Merge branch 'better-suggested-events' into 'main'

better suggested events

See merge request framasoft/mobilizon!1273
This commit is contained in:
Thomas Citharel 2022-10-04 09:25:16 +00:00
commit 0cbe0b8fad
3 changed files with 76 additions and 28 deletions

View File

@ -59,16 +59,16 @@ export const eventMetaDataList: IEventMetadataDescription[] = [
{ {
icon: "smoking-off", icon: "smoking-off",
key: "mz:accessibility:smokeFree", key: "mz:accessibility:smokeFree",
label: i18n.t("Smoke free") as string, label: t("Smoke free") as string,
description: i18n.t( description: t(
"Whether smoking is prohibited during the event" "Whether smoking is prohibited during the event"
) as string, ) as string,
value: "false", value: "false",
type: EventMetadataType.BOOLEAN, type: EventMetadataType.BOOLEAN,
keyType: EventMetadataKeyType.PLAIN, keyType: EventMetadataKeyType.PLAIN,
choices: { choices: {
true: i18n.t("Smoke free") as string, true: t("Smoke free") as string,
false: i18n.t("Smoking allowed") as string, false: t("Smoking allowed") as string,
}, },
category: EventMetadataCategories.ACCESSIBILITY, category: EventMetadataCategories.ACCESSIBILITY,
}, },

View File

@ -211,10 +211,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
# We get the organizer's next public event # We get the organizer's next public event
events = events =
event event
|> organizer_next_public_event() |> Events.related_events()
# We find similar events with the same tags
|> similar_events_common_tags(event)
# TODO: We should use tag_relations to find more appropriate events
# We've considered all recommended events, so we fetch the latest events # We've considered all recommended events, so we fetch the latest events
|> add_latest_events() |> add_latest_events()
# We remove the same event from the results # We remove the same event from the results
@ -225,26 +222,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
{:ok, events} {:ok, events}
end end
@spec organizer_next_public_event(Event.t()) :: list(Event.t())
defp organizer_next_public_event(%Event{attributed_to: %Actor{} = group, uuid: uuid}) do
[Events.get_upcoming_public_event_for_actor(group, uuid)]
|> Enum.filter(&is_map/1)
end
defp organizer_next_public_event(%Event{organizer_actor: %Actor{} = profile, uuid: uuid}) do
[Events.get_upcoming_public_event_for_actor(profile, uuid)]
|> Enum.filter(&is_map/1)
end
@spec similar_events_common_tags(list(Event.t()), Event.t()) :: list(Event.t())
defp similar_events_common_tags(events, %Event{tags: tags, uuid: uuid}) do
events
|> Enum.concat(Events.list_events_by_tags(tags, @number_of_related_events))
|> Enum.filter(fn event -> event.uuid != uuid end)
# uniq_by : It's possible event_from_same_actor is inside events_from_tags
|> uniq_events()
end
@spec add_latest_events(list(Event.t())) :: list(Event.t()) @spec add_latest_events(list(Event.t())) :: list(Event.t())
defp add_latest_events(events) do defp add_latest_events(events) do
if @number_of_related_events - length(events) > 0 do if @number_of_related_events - length(events) > 0 do

View File

@ -1686,6 +1686,77 @@ defmodule Mobilizon.Events do
|> Repo.all() |> Repo.all()
end end
@threshold_related_value 7
@spec related_events(Event.t()) :: list(Event.t())
def related_events(%Event{
id: event_id,
tags: tags,
physical_address: physical_address,
organizer_actor: %Actor{id: organizer_actor_id},
attributed_to: attributed_to,
category: category,
language: language
}) do
event_tags_ids = Enum.map(tags, & &1.id)
geom = if is_nil(physical_address), do: nil, else: physical_address.geom
group_id = if is_nil(attributed_to), do: nil, else: attributed_to.id
Event
|> distinct([e], e.id)
|> join(:left, [e], et in "events_tags", on: e.id == et.event_id)
|> join(:left, [e], a in Address, on: e.physical_address_id == a.id)
|> events_for_begins_on(%{})
|> filter_draft()
|> filter_local_or_from_followed_instances_events()
|> filter_public_visibility()
|> where(
[e, et, a],
fragment(
"(? = ?)::int * 5 + (? = ALL(?))::int * 2 + (? = ?)::int + (? = ?)::int * 2 + (?::int is null or ? = ?)::int * 2 + (?::geography is null or ST_DWithin(?::geography, ?::geography, ?::float))::int * 2 > ?",
e.language,
^language,
et.tag_id,
^event_tags_ids,
e.category,
^category,
e.organizer_actor_id,
^organizer_actor_id,
^group_id,
e.attributed_to_id,
^group_id,
^geom,
^geom,
a.geom,
5000,
@threshold_related_value
)
)
|> where([e], e.id != ^event_id)
|> order_by(
[e, et, a],
fragment(
"(? = ?)::int * 5 + (? = ALL(?))::int * 2 + (? = ?)::int + (? = ?)::int * 2 + (?::int is null or ? = ?)::int * 2 + (?::geography is null or ST_DWithin(?::geography, ?::geography, ?::float))::int * 2 DESC",
e.language,
^language,
et.tag_id,
^event_tags_ids,
e.category,
^category,
e.organizer_actor_id,
^organizer_actor_id,
^group_id,
e.attributed_to_id,
^group_id,
^geom,
^geom,
a.geom,
5000
)
)
|> Repo.all()
end
@spec list_participations_for_user_query(integer()) :: Ecto.Query.t() @spec list_participations_for_user_query(integer()) :: Ecto.Query.t()
defp list_participations_for_user_query(user_id) do defp list_participations_for_user_query(user_id) do
from( from(