From 44ef66fae78eeb573acea10501cafdb3b3f7a4ed Mon Sep 17 00:00:00 2001 From: Mayel de Borniol Date: Fri, 17 Jan 2025 16:10:05 +0000 Subject: [PATCH] https://github.com/bonfire-networks/bonfire-app/issues/900 --- lib/activities.ex | 13 +++++++-- lib/feed_loader.ex | 44 ++++++++++++++++++++++-------- test/social/feeds_preload_test.exs | 2 +- test/social/feeds_presets_test.exs | 2 +- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/lib/activities.ex b/lib/activities.ex index b005df2..1e7887f 100644 --- a/lib/activities.ex +++ b/lib/activities.ex @@ -429,16 +429,20 @@ defmodule Bonfire.Social.Activities do debug(preloads, "preloads inputted") opts = to_options(debug(opts)) + already_preloaded = + is_tuple(opts[:activity_preloads]) && + elem(opts[:activity_preloads], 0) |> debug("already_preloaded") + if not is_nil(query_or_object_or_objects) and Ecto.Queryable.impl_for(query_or_object_or_objects) do preloads - |> Bonfire.Social.FeedLoader.map_activity_preloads(opts[:activity_loaded_preloads]) + |> Bonfire.Social.FeedLoader.map_activity_preloads(already_preloaded) |> debug("accumulated preloads to proload") |> Enum.reduce(query_or_object_or_objects, &prepare_activity_preloads(&2, &1, opts)) |> debug("query with accumulated proloads") else preloads - |> Bonfire.Social.FeedLoader.map_activity_preloads(opts[:activity_loaded_preloads]) + |> Bonfire.Social.FeedLoader.map_activity_preloads(already_preloaded) |> Enum.flat_map(&prepare_activity_preloads(nil, &1, opts)) |> Enum.uniq() |> debug("accumulated postloads to try") @@ -1170,7 +1174,10 @@ defmodule Bonfire.Social.Activities do def maybe_filter(query, {:exclude_object_types, types}, _opts) do debug(types, "filter by exclude_object_types") - case Objects.prepare_exclude_object_types(types, FeedLoader.skip_types_default()) do + case Objects.prepare_exclude_object_types( + types, + Bonfire.Social.FeedLoader.skip_types_default() + ) do exclude_table_ids when is_list(exclude_table_ids) and exclude_table_ids != [] -> maybe_filter(query, {:exclude_table_ids, exclude_table_ids}, []) diff --git a/lib/feed_loader.ex b/lib/feed_loader.ex index d602ecb..1a97141 100644 --- a/lib/feed_loader.ex +++ b/lib/feed_loader.ex @@ -97,7 +97,10 @@ defmodule Bonfire.Social.FeedLoader do merge_feed_filters(preset_filters, custom_filters, opts) |> parameterize_filters(parameters, opts) |> FeedFilters.validate() - |> dump("parameterized feed_filters") do + |> dump("parameterized feed_filters"), + {filters, opts} <- + prepare_filters_and_opts(filters, opts) + |> debug("prepared feed_filters and opts") do feed_filtered(filters[:feed_name], filters, opts) end @@ -105,7 +108,10 @@ defmodule Bonfire.Social.FeedLoader do with {:ok, filters} <- merge_feed_filters(preset_filters, custom_filters, opts) |> FeedFilters.validate() - |> debug("merged feed_filters") do + |> debug("merged feed_filters"), + {filters, opts} <- + prepare_filters_and_opts(filters, opts) + |> debug("prepared feed_filters and opts") do feed_filtered(filters[:feed_name], filters, opts) end @@ -403,7 +409,7 @@ defmodule Bonfire.Social.FeedLoader do default_or_filtered_query(FeedActivities.base_query(opts), opts) |> join(:inner, [fp], ^initial_query, on: [id: fp.id]) |> Activities.activity_preloads( - opts[:preload] || contextual_preloads_from_filters(filters, :query), + opts[:preload], opts ) |> Activities.as_permitted_for(opts) @@ -415,7 +421,7 @@ defmodule Bonfire.Social.FeedLoader do defp paginate_and_boundarise_feed_non_deferred_query(query, filters, opts) do query |> Activities.activity_preloads( - opts[:preload] || contextual_preloads_from_filters(filters, :query), + opts[:preload], opts ) |> Activities.as_permitted_for(opts) @@ -511,6 +517,7 @@ defmodule Bonfire.Social.FeedLoader do @doc """ Gets feed ids and options for the given feed or list of feeds. + # TODO: this should be replaced by feed presets ## Examples > feed_ids_and_opts(feed_name, opts) @@ -753,7 +760,7 @@ defmodule Bonfire.Social.FeedLoader do query_extras(query, filters, opts) |> Activities.as_permitted_for(opts) |> Activities.activity_preloads( - opts[:preload] || contextual_preloads_from_filters(filters, :query), + opts[:preload], opts ) end @@ -768,14 +775,12 @@ defmodule Bonfire.Social.FeedLoader do |> query_optional_extras(filters, opts) |> Objects.as_permitted_for(opts) |> Activities.activity_preloads( - opts[:preload] || contextual_preloads_from_filters(filters, :query), + opts[:preload], opts ) end defp query_extras(query \\ nil, filters, opts) do - {filters, opts} = prepare_filters_and_opts(filters, opts) - # exclude_feed_ids = e(opts, :exclude_feed_ids, []) |> List.wrap() # WIP - to exclude activities that also appear in another feed (query || default_or_filtered_query(filters, FeedActivities.base_query(opts), opts)) @@ -805,6 +810,9 @@ defmodule Bonfire.Social.FeedLoader do def prepare_filters_and_opts(filters, opts) do opts = to_options(opts) + preload = opts[:preload] || contextual_preloads_from_filters(filters, :query) + # postload = opts[:postload] || contextual_preloads_from_filters(filters, :post) + include_flags = filters[:include_flags] || opts[:include_flags] include_all_objects = @@ -888,7 +896,8 @@ defmodule Bonfire.Social.FeedLoader do |> Map.drop([:exclude_object_types, :exclude_activity_types]), opts |> Keyword.merge( - preload: opts[:activity_preloads] |> Enums.filter_empty(nil) || opts[:preload] + preload: preload + # postload: postload )} |> debug("feed query filters & opts") end @@ -1597,12 +1606,11 @@ defmodule Bonfire.Social.FeedLoader do Enums.fun(preload_presets, :keys) else preloads - |> Enums.filter_empty([]) - |> Enum.reject(&MapSet.member?(already_preloaded, &1)) + |> do_filter_already_preloaded(already_preloaded) end |> do_map_preloads(preload_presets, MapSet.new()) # TODO: optimise - |> Enum.reject(&MapSet.member?(already_preloaded, &1)) + |> do_filter_already_preloaded(already_preloaded) end defp do_map_preloads(preloads, mappings, seen) when is_list(preloads) do @@ -1627,4 +1635,16 @@ defmodule Bonfire.Social.FeedLoader do end) |> Enum.uniq() end + + def filter_already_preloaded(preloads, already_preloaded) do + already_preloaded = MapSet.new(already_preloaded || []) + + (preloads || []) + |> Enum.reject(&(is_nil(&1) or MapSet.member?(already_preloaded, &1))) + end + + defp do_filter_already_preloaded(preloads, already_preloaded) do + (preloads || []) + |> Enum.reject(&(is_nil(&1) or MapSet.member?(already_preloaded, &1))) + end end diff --git a/test/social/feeds_preload_test.exs b/test/social/feeds_preload_test.exs index 9210fed..4e332ef 100644 --- a/test/social/feeds_preload_test.exs +++ b/test/social/feeds_preload_test.exs @@ -95,7 +95,7 @@ defmodule Bonfire.Social.FeedsPreloadTest do FeedLoader.feed_contains?(feed, reply, current_user: user) |> Bonfire.Social.Activities.activity_preloads(:all, current_user: user, - activity_loaded_preloads: postloads1 + activity_preloads: {postloads1, nil} ) # NOTE: by running postloads instead of preloading in original query, we are loading unecessary data sonce diff --git a/test/social/feeds_presets_test.exs b/test/social/feeds_presets_test.exs index 0f86137..766d97b 100644 --- a/test/social/feeds_presets_test.exs +++ b/test/social/feeds_presets_test.exs @@ -177,7 +177,7 @@ defmodule Bonfire.Social.FeedsPresetTest do loaded_activity = Bonfire.Social.Activities.activity_preloads(loaded_activity, postloads, current_user: user, - activity_loaded_preloads: preloads + activity_preloads: {preloads, nil} ) verify_data(preset, loaded_activity, activity, object, user, other_user)