diff --git a/js/src/components/Activity/EventActivityItem.vue b/js/src/components/Activity/EventActivityItem.vue
index 4c9f1a359..cdb13264e 100644
--- a/js/src/components/Activity/EventActivityItem.vue
+++ b/js/src/components/Activity/EventActivityItem.vue
@@ -42,6 +42,7 @@ import { usernameWithDomain } from "@/types/actor";
import { formatTimeString } from "@/filters/datetime";
import {
ActivityEventCommentSubject,
+ ActivityEventParticipantSubject,
ActivityEventSubject,
} from "@/types/enums";
import { computed } from "vue";
@@ -90,6 +91,14 @@ const translation = computed((): string | undefined => {
return "You posted a comment on the event {event}.";
}
return "{profile} posted a comment on the event {event}.";
+ case ActivityEventParticipantSubject.EVENT_NEW_PARTICIPATION:
+ if (isAuthorCurrentActor.value) {
+ return "You joined the event {event}.";
+ }
+ if (props.activity.author.preferredUsername === "anonymous") {
+ return "An anonymous profile joined the event {event}.";
+ }
+ return "{profile} joined the the event {event}.";
default:
return undefined;
}
diff --git a/js/src/i18n/en_US.json b/js/src/i18n/en_US.json
index dc52d2ec0..58d487f1f 100644
--- a/js/src/i18n/en_US.json
+++ b/js/src/i18n/en_US.json
@@ -1579,5 +1579,8 @@
"Access drafts events": "Access drafts events",
"This application will be allowed to list and view your draft events": "This application will be allowed to list and view your draft events",
"Access group suggested events": "Access group suggested events",
- "This application will be allowed to list your suggested group events": "This application will be allowed to list your suggested group events"
+ "This application will be allowed to list your suggested group events": "This application will be allowed to list your suggested group events",
+ "{profile} joined the the event {event}.": "{profile} joined the the event {event}.",
+ "You joined the event {event}.": "You joined the event {event}.",
+ "An anonymous profile joined the event {event}.": "An anonymous profile joined the event {event}."
}
\ No newline at end of file
diff --git a/js/src/i18n/fr_FR.json b/js/src/i18n/fr_FR.json
index bc91b3b8e..dba74ff49 100644
--- a/js/src/i18n/fr_FR.json
+++ b/js/src/i18n/fr_FR.json
@@ -1575,5 +1575,8 @@
"Access drafts events": "Accéder aux événements brouillons",
"This application will be allowed to list and view your draft events": "Cetta application sera autorisée à lister et accéder à vos événements brouillons",
"Access group suggested events": "Accéder aux événements des groupes suggérés",
- "This application will be allowed to list your suggested group events": "Cetta application sera autorisée à lister les événements de vos groupes qui vous sont suggérés"
+ "This application will be allowed to list your suggested group events": "Cetta application sera autorisée à lister les événements de vos groupes qui vous sont suggérés",
+ "{profile} joined the the event {event}.": "{profile} a rejoint l'événement {event}.",
+ "You joined the event {event}.": "Vous avez rejoint l'événement {event}.",
+ "An anonymous profile joined the event {event}.": "Un profil anonyme a rejoint l'événement {event}."
}
diff --git a/js/src/types/activity.model.ts b/js/src/types/activity.model.ts
index c5c218757..f3ecb913e 100644
--- a/js/src/types/activity.model.ts
+++ b/js/src/types/activity.model.ts
@@ -3,6 +3,7 @@ import { IMember } from "./actor/member.model";
import {
ActivityDiscussionSubject,
ActivityEventCommentSubject,
+ ActivityEventParticipantSubject,
ActivityEventSubject,
ActivityGroupSubject,
ActivityMemberSubject,
@@ -21,7 +22,8 @@ export type ActivitySubject =
| ActivityResourceSubject
| ActivityDiscussionSubject
| ActivityGroupSubject
- | ActivityEventCommentSubject;
+ | ActivityEventCommentSubject
+ | ActivityEventParticipantSubject;
export interface IActivity {
id: string;
diff --git a/js/src/types/enums.ts b/js/src/types/enums.ts
index 0eb3841bb..dc551f3f9 100644
--- a/js/src/types/enums.ts
+++ b/js/src/types/enums.ts
@@ -200,6 +200,10 @@ export enum ActivityEventCommentSubject {
COMMENT_POSTED = "comment_posted",
}
+export enum ActivityEventParticipantSubject {
+ EVENT_NEW_PARTICIPATION = "event_new_participation",
+}
+
export enum ActivityPostSubject {
POST_CREATED = "post_created",
POST_UPDATED = "post_updated",
diff --git a/lib/federation/activity_pub/actions/accept.ex b/lib/federation/activity_pub/actions/accept.ex
index 87912de97..1480a262f 100644
--- a/lib/federation/activity_pub/actions/accept.ex
+++ b/lib/federation/activity_pub/actions/accept.ex
@@ -82,6 +82,11 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Accept do
)
Scheduler.trigger_notifications_for_participant(participant)
+
+ Mobilizon.Service.Activity.Participant.insert_activity(participant,
+ subject: "event_new_participation"
+ )
+
participant_as_data = Convertible.model_to_as(participant)
audience = Audience.get_audience(participant)
diff --git a/lib/federation/activity_pub/types/events.ex b/lib/federation/activity_pub/types/events.ex
index 13b3e2f12..94cd9d665 100644
--- a/lib/federation/activity_pub/types/events.ex
+++ b/lib/federation/activity_pub/types/events.ex
@@ -224,6 +224,10 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
cond do
Mobilizon.Events.get_default_participant_role(event) == :participant &&
role == :participant ->
+ Mobilizon.Service.Activity.Participant.insert_activity(participant,
+ subject: "event_new_participation"
+ )
+
{:accept,
Actions.Accept.accept(
:join,
diff --git a/lib/mobilizon/activities/activities.ex b/lib/mobilizon/activities/activities.ex
index 52b7683ed..d851f19fb 100644
--- a/lib/mobilizon/activities/activities.ex
+++ b/lib/mobilizon/activities/activities.ex
@@ -19,6 +19,7 @@ defmodule Mobilizon.Activities do
@activity_types ["event", "post", "discussion", "resource", "group", "member", "comment"]
@event_activity_subjects ["event_created", "event_updated", "event_deleted", "comment_posted"]
+ @participant_activity_subjects ["event_new_participation"]
@post_activity_subjects ["post_created", "post_updated", "post_deleted"]
@discussion_activity_subjects [
"discussion_created",
@@ -48,12 +49,23 @@ defmodule Mobilizon.Activities do
@settings_activity_subjects ["group_created", "group_updated"]
@subjects @event_activity_subjects ++
+ @participant_activity_subjects ++
@post_activity_subjects ++
@discussion_activity_subjects ++
@resource_activity_subjects ++
@member_activity_subjects ++ @settings_activity_subjects
- @object_type ["event", "actor", "post", "discussion", "resource", "member", "group", "comment"]
+ @object_type [
+ "event",
+ "participant",
+ "actor",
+ "post",
+ "discussion",
+ "resource",
+ "member",
+ "group",
+ "comment"
+ ]
defenum(Type, @activity_types)
defenum(Subject, @subjects)
diff --git a/lib/service/activity/activity.ex b/lib/service/activity/activity.ex
index 9c436fecf..1262102c6 100644
--- a/lib/service/activity/activity.ex
+++ b/lib/service/activity/activity.ex
@@ -4,7 +4,17 @@ defmodule Mobilizon.Service.Activity do
"""
alias Mobilizon.Activities.Activity
- alias Mobilizon.Service.Activity.{Comment, Discussion, Event, Group, Member, Post, Resource}
+
+ alias Mobilizon.Service.Activity.{
+ Comment,
+ Discussion,
+ Event,
+ Group,
+ Member,
+ Participant,
+ Post,
+ Resource
+ }
@callback insert_activity(entity :: struct(), options :: Keyword.t()) ::
{:ok, Oban.Job.t()} | {:ok, any()} | {:error, Ecto.Changeset.t()}
@@ -45,4 +55,8 @@ defmodule Mobilizon.Service.Activity do
defp do_get_object(:comment, comment_id) do
Comment.get_object(comment_id)
end
+
+ defp do_get_object(:participant, participant_id) do
+ Participant.get_object(participant_id)
+ end
end
diff --git a/lib/service/activity/participant.ex b/lib/service/activity/participant.ex
new file mode 100644
index 000000000..791e67fff
--- /dev/null
+++ b/lib/service/activity/participant.ex
@@ -0,0 +1,48 @@
+defmodule Mobilizon.Service.Activity.Participant do
+ @moduledoc """
+ Insert an event activity
+ """
+ alias Mobilizon.{Actors, Events}
+ alias Mobilizon.Actors.Actor
+ alias Mobilizon.Events.Participant
+ alias Mobilizon.Service.Activity
+ alias Mobilizon.Service.Workers.ActivityBuilder
+
+ @behaviour Activity
+
+ @impl Activity
+ def insert_activity(event, options \\ [])
+
+ def insert_activity(
+ %Participant{event_id: event_id, actor_id: actor_id, id: participant_id} =
+ _participant,
+ options
+ ) do
+ actor = Actors.get_actor(actor_id)
+ event = Events.get_event!(event_id)
+ subject = Keyword.fetch!(options, :subject)
+
+ ActivityBuilder.enqueue(:build_activity, %{
+ "type" => "event",
+ "subject" => subject,
+ "subject_params" => %{
+ actor_name: Actor.display_name(actor),
+ event_title: event.title,
+ event_uuid: event.uuid
+ },
+ "group_id" => event.attributed_to_id,
+ "author_id" => actor.id,
+ "object_type" => "participant",
+ "object_id" => participant_id,
+ "inserted_at" => DateTime.utc_now()
+ })
+ end
+
+ @impl Activity
+ def insert_activity(_, _), do: {:ok, nil}
+
+ @impl Activity
+ def get_object(participant_id) do
+ Events.get_participant(participant_id)
+ end
+end
diff --git a/lib/service/activity/renderer/event.ex b/lib/service/activity/renderer/event.ex
index 809583bb0..3bf07232f 100644
--- a/lib/service/activity/renderer/event.ex
+++ b/lib/service/activity/renderer/event.ex
@@ -1,6 +1,6 @@
defmodule Mobilizon.Service.Activity.Renderer.Event do
@moduledoc """
- Insert a comment activity
+ Insert an event activity
"""
alias Mobilizon.Activities.Activity
alias Mobilizon.Actors.Actor
@@ -67,6 +67,16 @@ defmodule Mobilizon.Service.Activity.Renderer.Event do
url: event_url(activity)
}
end
+
+ :event_new_participation ->
+ %{
+ body:
+ dgettext("activity", "%{profile} joined your event %{event}.", %{
+ profile: profile(activity),
+ event: title(activity)
+ }),
+ url: event_url(activity)
+ }
end
end
diff --git a/lib/service/notifier/email.ex b/lib/service/notifier/email.ex
index acd213d2e..750c70706 100644
--- a/lib/service/notifier/email.ex
+++ b/lib/service/notifier/email.ex
@@ -96,7 +96,7 @@ defmodule Mobilizon.Service.Notifier.Email do
defp can_send_activity?(activity, user, options) do
Logger.warning(
- "Can't check if user #{inspect(user)} can be sent an activity (#{inspect(activity)}) (#{inspect(options)})"
+ "Can't check if user #{inspect(user.email)} can be sent an activity (#{inspect(activity)}) (#{inspect(options)})"
)
false
diff --git a/lib/web/templates/email/activity/_event_activity_item.html.heex b/lib/web/templates/email/activity/_event_activity_item.html.heex
index 9af392741..0497d658d 100644
--- a/lib/web/templates/email/activity/_event_activity_item.html.heex
+++ b/lib/web/templates/email/activity/_event_activity_item.html.heex
@@ -51,4 +51,13 @@
})
|> raw %>
<% end %>
+ <% :event_new_participation -> %>
+ <%= dgettext("activity", "%{profile} joined your event %{event}.", %{
+ profile: "#{escaped_display_name_and_username(@activity.author)}",
+ event:
+ " URI.decode()}\">#{escape_html(@activity.subject_params["event_title"])}"
+ })
+ |> raw %>
<% end %>
diff --git a/lib/web/templates/email/activity/_event_activity_item.text.eex b/lib/web/templates/email/activity/_event_activity_item.text.eex
index 390bd2611..30b05abc0 100644
--- a/lib/web/templates/email/activity/_event_activity_item.text.eex
+++ b/lib/web/templates/email/activity/_event_activity_item.text.eex
@@ -1,31 +1,37 @@
<%= case @activity.subject do %><% :event_created -> %><%= dgettext("activity", "The event %{event} was created by %{profile}.",
%{
- profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
+ profile: display_name_and_username(@activity.author),
event: @activity.subject_params["event_title"]
}
) %>
<%= Routes.page_url(Mobilizon.Web.Endpoint, :event, @activity.subject_params["event_uuid"]) |> URI.decode() %><% :event_updated -> %><%= dgettext("activity", "The event %{event} was updated by %{profile}.",
%{
- profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
+ profile: display_name_and_username(@activity.author),
event: @activity.subject_params["event_title"]
}
) %>
<%= Routes.page_url(Mobilizon.Web.Endpoint, :event, @activity.subject_params["event_uuid"]) |> URI.decode() %><% :event_deleted -> %><%= dgettext("activity", "The event %{event} was deleted by %{profile}.",
%{
- profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
+ profile: display_name_and_username(@activity.author),
event: @activity.subject_params["event_title"]
}
) %>
<% :comment_posted -> %><%= if @activity.subject_params["comment_reply_to"] do %><%= dgettext("activity", "%{profile} replied to a comment on the event %{event}.",
%{
- profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
+ profile: display_name_and_username(@activity.author),
event: @activity.subject_params["event_title"]
}
) %>
<%= Routes.page_url(Mobilizon.Web.Endpoint, :event, @activity.subject_params["event_uuid"]) |> URI.decode() %><% else %><%= dgettext("activity", "%{profile} posted a comment on the event %{event}.",
%{
- profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
+ profile: display_name_and_username(@activity.author),
event: @activity.subject_params["event_title"]
}
) %>
-<%= Routes.page_url(Mobilizon.Web.Endpoint, :event, @activity.subject_params["event_uuid"]) |> URI.decode() %><% end %><% end %>
\ No newline at end of file
+<%= Routes.page_url(Mobilizon.Web.Endpoint, :event, @activity.subject_params["event_uuid"]) |> URI.decode() %><% end %><% :event_new_participation -> %><%= dgettext("activity", "%{profile} joined your event %{event}.",
+ %{
+ profile: display_name_and_username(@activity.author),
+ event: @activity.subject_params["event_title"]
+ }
+) %>
+<%= Routes.page_url(Mobilizon.Web.Endpoint, :event, @activity.subject_params["event_uuid"]) |> URI.decode() %><% end %>
\ No newline at end of file
diff --git a/lib/web/views/email_view.ex b/lib/web/views/email_view.ex
index c103e4fcf..82b0e74d9 100644
--- a/lib/web/views/email_view.ex
+++ b/lib/web/views/email_view.ex
@@ -25,7 +25,6 @@ defmodule Mobilizon.Web.EmailView do
defdelegate datetime_relative(datetime, locale \\ "en"), to: DateTimeRenderer
defdelegate render_address(address), to: Address
defdelegate is_same_day?(one, two), to: DateTimeRenderer
- defdelegate display_name_and_username(actor), to: Actor
defdelegate display_name(actor), to: Actor
defdelegate preferred_username_and_domain(actor), to: Actor
@@ -38,7 +37,13 @@ defmodule Mobilizon.Web.EmailView do
def escaped_display_name_and_username(actor) do
actor
- |> Actor.display_name_and_username()
+ |> display_name_and_username()
|> escape_html()
end
+
+ def display_name_and_username(%Actor{preferred_username: "anonymous"}) do
+ dgettext("activity", "An anonymous profile")
+ end
+
+ def display_name_and_username(actor), do: Actor.display_name_and_username(actor)
end