From 9d996844025f9d128305a54f8f169fb4b1ffac44 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 9 Feb 2024 10:54:00 +0100 Subject: [PATCH] feat: allow to filter events by local-only In addition to internal (self + federated) and global (global external search engine), introduce the self possibility Closes #1322 Signed-off-by: Thomas Citharel --- .tool-versions | 4 +-- lib/graphql/api/search.ex | 11 ++++-- lib/graphql/schema/search.ex | 2 ++ lib/mobilizon/actors/actors.ex | 8 +++++ lib/mobilizon/events/events.ex | 1 + src/types/enums.ts | 1 + src/views/SearchView.vue | 16 +++++++++ test/graphql/api/search_test.exs | 5 +-- test/graphql/resolvers/search_test.exs | 47 ++++++++++++++++++++++++-- 9 files changed, 87 insertions(+), 8 deletions(-) diff --git a/.tool-versions b/.tool-versions index 01d0166b6..1c43fd8c8 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -elixir 1.15.5-otp-26 -erlang 26.0.2 +erlang 26.2.2 +elixir 1.16.1-otp-26 diff --git a/lib/graphql/api/search.ex b/lib/graphql/api/search.ex index 79049c80d..eba18c20f 100644 --- a/lib/graphql/api/search.ex +++ b/lib/graphql/api/search.ex @@ -56,7 +56,8 @@ defmodule Mobilizon.GraphQL.API.Search do minimum_visibility: Map.get(args, :minimum_visibility, :public), current_actor_id: Map.get(args, :current_actor_id), exclude_my_groups: Map.get(args, :exclude_my_groups, false), - exclude_stale_actors: true + exclude_stale_actors: true, + local_only: Map.get(args, :search_target, :internal) == :self ], page, limit @@ -94,7 +95,13 @@ defmodule Mobilizon.GraphQL.API.Search do {:ok, service.search_events(Keyword.new(args, fn {k, v} -> {k, v} end))} else - {:ok, Events.build_events_for_search(Map.put(args, :term, term), page, limit)} + results = + args + |> Map.put(:term, term) + |> Map.put(:local_only, Map.get(args, :search_target, :internal) == :self) + |> Events.build_events_for_search(page, limit) + + {:ok, results} end end end diff --git a/lib/graphql/schema/search.ex b/lib/graphql/schema/search.ex index 8f75c5e91..626a693c0 100644 --- a/lib/graphql/schema/search.ex +++ b/lib/graphql/schema/search.ex @@ -160,6 +160,8 @@ defmodule Mobilizon.GraphQL.Schema.SearchType do end enum :search_target do + value(:self, description: "Search only on content from this instance") + value(:internal, description: "Search on content from this instance and from the followed instances" ) diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex index 3fd5d8de3..cc78c0807 100644 --- a/lib/mobilizon/actors/actors.ex +++ b/lib/mobilizon/actors/actors.ex @@ -525,6 +525,7 @@ defmodule Mobilizon.Actors do Keyword.get(options, :radius), Keyword.get(options, :bbox) ) + |> filter_by_local_only(Keyword.get(options, :local_only, false)) |> actors_for_location(Keyword.get(options, :location), Keyword.get(options, :radius)) |> events_for_bounding_box(Keyword.get(options, :bbox)) |> filter_by_type(Keyword.get(options, :actor_type, :Group)) @@ -1418,6 +1419,13 @@ defmodule Mobilizon.Actors do defp maybe_join_address(query, _location, _radius, _bbox), do: query + @spec filter_by_local_only(Ecto.Queryable.t(), boolean()) :: Ecto.Query.t() + defp filter_by_local_only(query, true) do + where(query, [q], is_nil(q.domain)) + end + + defp filter_by_local_only(query, false), do: query + @spec actors_for_location(Ecto.Queryable.t(), String.t(), integer()) :: Ecto.Query.t() defp actors_for_location(query, location, radius) when is_valid_string(location) and not is_nil(radius) do diff --git a/lib/mobilizon/events/events.ex b/lib/mobilizon/events/events.ex index 3472effed..bc97ab50d 100644 --- a/lib/mobilizon/events/events.ex +++ b/lib/mobilizon/events/events.ex @@ -581,6 +581,7 @@ defmodule Mobilizon.Events do |> events_for_bounding_box(args) |> filter_online(args) |> filter_draft() + |> filter_local(if Map.get(args, :local_only, nil) == true, do: true, else: nil) |> filter_local_or_from_followed_instances_events() |> filter_public_visibility() |> event_order(Map.get(args, :sort_by, :match_desc), search_string) diff --git a/src/types/enums.ts b/src/types/enums.ts index ed7e3ee0f..22f8366d0 100644 --- a/src/types/enums.ts +++ b/src/types/enums.ts @@ -293,6 +293,7 @@ export enum InstanceFollowStatus { } export enum SearchTargets { + SELF = "SELF", INTERNAL = "INTERNAL", GLOBAL = "GLOBAL", } diff --git a/src/views/SearchView.vue b/src/views/SearchView.vue index b156c7dde..bdf95345a 100644 --- a/src/views/SearchView.vue +++ b/src/views/SearchView.vue @@ -68,6 +68,22 @@
{{ t("Search target") }} +
+ + +
+