Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-03-23 15:18:03 +01:00
parent adaaef6914
commit 86c2512c62
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
87 changed files with 7816 additions and 1387 deletions

View File

@ -265,7 +265,7 @@ config :mobilizon, :anonymous,
config :mobilizon, Oban,
repo: Mobilizon.Storage.Repo,
log: false,
queues: [default: 10, search: 5, mailers: 10, background: 5, activity: 5],
queues: [default: 10, search: 5, mailers: 10, background: 5, activity: 5, notifications: 5],
plugins: [
{Oban.Plugins.Cron,
crontab: [
@ -298,6 +298,12 @@ config :mobilizon, :external_resource_providers, %{
"https://docs.google.com/spreadsheets/" => :google_spreadsheets
}
config :mobilizon, Mobilizon.Service.Notifier,
notifiers: [
Mobilizon.Service.Notifier.Email,
Mobilizon.Service.Notifier.Push
]
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{config_env()}.exs"

View File

@ -8,7 +8,9 @@
slot="group"
:to="{
name: RouteName.GROUP,
params: { preferredUsername: usernameWithDomain(activity.object) },
params: {
preferredUsername: subjectParams.group_federated_username,
},
}"
>{{ subjectParams.group_name }}</router-link
>

View File

@ -18,7 +18,7 @@
></popover-actor-card
>
<b slot="member" v-else>{{
subjectParams.member_preferred_username
subjectParams.member_actor_federated_username
}}</b>
<popover-actor-card
:actor="activity.author"

View File

@ -4,10 +4,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
"""
import Mobilizon.Users.Guards
alias Mobilizon.{Activities, Actors, Discussions, Events, Posts, Resources, Users}
alias Mobilizon.{Activities, Actors, Users}
alias Mobilizon.Activities.Activity
alias Mobilizon.Actors.Actor
alias Mobilizon.Events.Event
alias Mobilizon.Service.Activity, as: ActivityService
alias Mobilizon.Storage.Page
alias Mobilizon.Users.User
@ -31,7 +31,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
Enum.map(elements, fn %Activity{} = activity ->
activity
|> Map.update(:subject_params, %{}, &transform_params/1)
|> Map.put(:object, get_object(activity))
|> Map.put(:object, ActivityService.object(activity))
end)
{:ok, %Page{total: total, elements: elements}}
@ -45,43 +45,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
{:error, :unauthenticated}
end
defp get_object(%Activity{object_type: object_type, object_id: object_id}) do
get_object(object_type, object_id)
end
defp get_object(_, nil), do: nil
defp get_object(:event, event_id) do
case Events.get_event(event_id) do
{:ok, %Event{} = event} -> event
_ -> nil
end
end
defp get_object(:post, post_id) do
Posts.get_post(post_id)
end
defp get_object(:member, member_id) do
Actors.get_member(member_id)
end
defp get_object(:resource, resource_id) do
Resources.get_resource(resource_id)
end
defp get_object(:discussion, discussion_id) do
Discussions.get_discussion(discussion_id)
end
defp get_object(:group, group_id) do
Actors.get_actor(group_id)
end
defp get_object(:comment, comment_id) do
Discussions.get_comment(comment_id)
end
@spec transform_params(map()) :: list()
defp transform_params(params) do
Enum.map(params, fn {key, value} -> %{key: key, value: transform_value(value)} end)

View File

@ -59,6 +59,8 @@ defmodule Mobilizon.Activities do
defenum(Subject, @subjects)
defenum(ObjectType, @object_type)
@activity_preloads [:author, :group]
@doc """
Returns the list of activities.
@ -153,6 +155,11 @@ defmodule Mobilizon.Activities do
|> Repo.insert()
end
@spec preload_activity(Activity.t()) :: Activity.t()
def preload_activity(%Activity{} = activity) do
Repo.preload(activity, @activity_preloads)
end
def object_types, do: @object_type
def subjects, do: @subjects

View File

@ -3,5 +3,50 @@ defmodule Mobilizon.Service.Activity do
Behavior for Activity creators
"""
alias Mobilizon.Activities.Activity
alias Mobilizon.Service.Activity.{Comment, Discussion, Event, Group, Member, Post, Resource}
@callback insert_activity(entity :: struct(), options :: map()) :: {:ok, Oban.Job.t()}
@callback get_object(object_id :: String.t() | integer()) :: struct()
@spec object(Activity.t()) :: struct() | nil
def object(%Activity{object_type: object_type, object_id: object_id}) do
do_get_object(object_type, object_id)
end
@spec has_object?(Activity.t()) :: boolean()
def has_object?(%Activity{} = activity) do
!is_nil(object(activity))
end
defp do_get_object(_, nil), do: nil
defp do_get_object(:event, event_id) do
Event.get_object(event_id)
end
defp do_get_object(:post, post_id) do
Post.get_object(post_id)
end
defp do_get_object(:member, member_id) do
Member.get_object(member_id)
end
defp do_get_object(:resource, resource_id) do
Resource.get_object(resource_id)
end
defp do_get_object(:discussion, discussion_id) do
Discussion.get_object(discussion_id)
end
defp do_get_object(:group, group_id) do
Group.get_object(group_id)
end
defp do_get_object(:comment, comment_id) do
Comment.get_object(comment_id)
end
end

View File

@ -2,7 +2,7 @@ defmodule Mobilizon.Service.Activity.Comment do
@moduledoc """
Insert a comment activity
"""
alias Mobilizon.{Actors, Events}
alias Mobilizon.{Actors, Discussions, Events}
alias Mobilizon.Actors.Actor
alias Mobilizon.Discussions.Comment
alias Mobilizon.Events.Event
@ -48,4 +48,9 @@ defmodule Mobilizon.Service.Activity.Comment do
end
def insert_activity(_, _), do: {:ok, nil}
@impl Activity
def get_object(comment_id) do
Discussions.get_comment(comment_id)
end
end

View File

@ -2,7 +2,7 @@ defmodule Mobilizon.Service.Activity.Discussion do
@moduledoc """
Insert a discussion activity
"""
alias Mobilizon.Actors
alias Mobilizon.{Actors, Discussions}
alias Mobilizon.Discussions.Discussion
alias Mobilizon.Service.Activity
alias Mobilizon.Service.Workers.ActivityBuilder
@ -38,6 +38,11 @@ defmodule Mobilizon.Service.Activity.Discussion do
def insert_activity(_, _), do: {:ok, nil}
@impl Activity
def get_object(discussion_id) do
Discussions.get_discussion(discussion_id)
end
@spec subject_params(Discussion.t(), String.t() | nil, Discussion.t() | nil) :: map()
defp subject_params(%Discussion{} = discussion, "discussion_renamed", old_discussion) do
discussion

View File

@ -2,7 +2,7 @@ defmodule Mobilizon.Service.Activity.Event do
@moduledoc """
Insert an event activity
"""
alias Mobilizon.Actors
alias Mobilizon.{Actors, Events}
alias Mobilizon.Events.Event
alias Mobilizon.Service.Activity
alias Mobilizon.Service.Workers.ActivityBuilder
@ -36,4 +36,12 @@ defmodule Mobilizon.Service.Activity.Event do
@impl Activity
def insert_activity(_, _), do: {:ok, nil}
@impl Activity
def get_object(event_id) do
case Events.get_event(event_id) do
{:ok, %Event{} = event} -> event
_ -> nil
end
end
end

View File

@ -40,6 +40,11 @@ defmodule Mobilizon.Service.Activity.Group do
def insert_activity(_, _), do: {:ok, nil}
@impl Activity
def get_object(group_id) do
Actors.get_actor(group_id)
end
@spec subject_params(Actor.t(), String.t() | nil, Actor.t() | nil) :: map()
defp subject_params(%Actor{} = group, "group_updated", %Actor{} = old_group) do
group
@ -67,7 +72,7 @@ defmodule Mobilizon.Service.Activity.Group do
end
defp subject_params(
%Actor{preferred_username: preferred_username, domain: domain, name: name},
%Actor{preferred_username: preferred_username, domain: domain, name: name} = actor,
_,
_
) do
@ -75,6 +80,7 @@ defmodule Mobilizon.Service.Activity.Group do
group_preferred_username: preferred_username,
group_name: name,
group_domain: domain,
group_federated_username: Actor.preferred_username_and_domain(actor),
group_changes: []
}
end

View File

@ -35,6 +35,11 @@ defmodule Mobilizon.Service.Activity.Member do
def insert_activity(_, _), do: {:ok, nil}
@impl Activity
def get_object(member_id) do
Actors.get_member(member_id)
end
@spec get_author(Member.t(), Member.t() | nil) :: String.t() | integer()
defp get_author(%Member{actor_id: actor_id}, options) do
moderator = Keyword.get(options, :moderator)
@ -72,11 +77,12 @@ defmodule Mobilizon.Service.Activity.Member do
if(is_nil(actor),
do: subject_params,
else:
Map.put(
subject_params,
:member_preferred_username,
subject_params
|> Map.put(
:member_actor_federated_username,
Actor.preferred_username_and_domain(actor)
)
|> Map.put(:member_actor_name, actor.name)
)
subject_params =

View File

@ -2,7 +2,7 @@ defmodule Mobilizon.Service.Activity.Post do
@moduledoc """
Insert an post activity
"""
alias Mobilizon.Actors
alias Mobilizon.{Actors, Posts}
alias Mobilizon.Posts.Post
alias Mobilizon.Service.Activity
alias Mobilizon.Service.Workers.ActivityBuilder
@ -34,4 +34,9 @@ defmodule Mobilizon.Service.Activity.Post do
end
def insert_activity(_, _), do: {:ok, nil}
@impl Activity
def get_object(post_id) do
Posts.get_post(post_id)
end
end

View File

@ -2,7 +2,7 @@ defmodule Mobilizon.Service.Activity.Resource do
@moduledoc """
Insert an resource activity
"""
alias Mobilizon.Actors
alias Mobilizon.{Actors, Resources}
alias Mobilizon.Resources.Resource
alias Mobilizon.Service.Activity
alias Mobilizon.Service.Workers.ActivityBuilder
@ -37,6 +37,11 @@ defmodule Mobilizon.Service.Activity.Resource do
@impl Activity
def insert_activity(_, _), do: {:ok, nil}
@impl Activity
def get_object(resource_id) do
Resources.get_resource(resource_id)
end
@spec subject_params(Resource.t(), String.t() | nil, Resource.t() | nil) :: map()
defp subject_params(%Resource{} = resource, "resource_renamed", old_resource) do
resource
@ -44,7 +49,7 @@ defmodule Mobilizon.Service.Activity.Resource do
|> Map.put(:old_resource_title, old_resource.title)
end
defp subject_params(%Resource{path: path, title: title}, _, _) do
%{resource_path: path, resource_title: title}
defp subject_params(%Resource{path: path, title: title, type: type, id: id}, _, _) do
%{resource_path: path, resource_title: title, is_folder: type == :folder, resource_uuid: id}
end
end

View File

@ -0,0 +1,31 @@
defmodule Mobilizon.Service.Notifier.Email do
@moduledoc """
Email notifier
"""
alias Mobilizon.Activities.Activity
alias Mobilizon.Config
alias Mobilizon.Service.Notifier
alias Mobilizon.Service.Notifier.Email
alias Mobilizon.Users.User
alias Mobilizon.Web.Email.Activity, as: EmailActivity
alias Mobilizon.Web.Email.Mailer
@behaviour Notifier
@impl Notifier
def ready? do
Config.get(__MODULE__, :enabled)
end
@impl Notifier
def send(%User{} = user, %Activity{} = activity) do
Email.send(user, [activity])
end
@impl Notifier
def send(%User{email: email, locale: locale}, activities) when is_list(activities) do
email
|> EmailActivity.direct_activity(activities, locale)
|> Mailer.send_email()
end
end

View File

@ -0,0 +1,31 @@
defmodule Mobilizon.Service.Notifier do
@moduledoc """
Behaviour for notifiers
"""
alias Mobilizon.Activities.Activity
alias Mobilizon.Config
alias Mobilizon.Users.User
@doc """
Whether the notifier is enabled and configured
"""
@callback ready?() :: boolean()
@doc """
Sends one or multiple notifications from an activity
"""
@callback send(User.t(), Activity.t()) :: {:ok, any()} | {:error, String.t()}
@callback send(User.t(), list(Activity.t())) :: {:ok, any()} | {:error, String.t()}
def notify(%User{} = user, %Activity{} = activity, opts \\ []) do
Enum.each(providers(opts), & &1.send(user, activity))
end
@spec providers(Keyword.t()) :: list()
defp providers(opts) do
opts
|> Keyword.get(:notifiers, Config.get([__MODULE__, :notifiers]))
|> Enum.filter(& &1.ready?())
end
end

View File

@ -0,0 +1,38 @@
defmodule Mobilizon.Service.Notifier.Push do
@moduledoc """
WebPush notifier
"""
alias Mobilizon.Activities.Activity
alias Mobilizon.Config
alias Mobilizon.Service.Notifier
alias Mobilizon.Service.Notifier.Push
alias Mobilizon.Users.User
@behaviour Notifier
@impl Notifier
def ready? do
Config.get(__MODULE__, :enabled)
end
@impl Notifier
def send(%User{} = _user, %Activity{} = activity) do
# Get user's subscriptions
activity
|> payload()
# |> WebPushEncryption.send_web_push()
end
@impl Notifier
def send(%User{} = user, activities) when is_list(activities) do
Enum.each(activities, &Push.send(user, &1))
end
defp payload(%Activity{subject: subject}) do
%{
title: subject
}
|> Jason.encode!()
end
end

View File

@ -7,8 +7,12 @@ defmodule Mobilizon.Service.RichMedia.Parsers.Fallback do
@moduledoc """
Module to parse fallback data in HTML pages (plain old title and meta description)
"""
require Logger
@spec parse(String.t(), map()) :: {:ok, map()} | {:error, String.t()}
def parse(html, data) do
Logger.debug("Running Fallback parser")
data =
data
|> maybe_put(html, :title)

View File

@ -3,15 +3,20 @@ defmodule Mobilizon.Service.Workers.ActivityBuilder do
Worker to insert activity items in users feeds
"""
alias Mobilizon.Activities
alias Mobilizon.{Activities, Actors, Users}
alias Mobilizon.Activities.Activity
alias Mobilizon.Actors.Actor
alias Mobilizon.Service.Notifier
alias Mobilizon.Users.User
use Mobilizon.Service.Workers.Helper, queue: "activity"
@impl Oban.Worker
def perform(%Job{args: args}) do
with {"build_activity", args} <- Map.pop(args, "op") do
build_activity(args)
with {"build_activity", args} <- Map.pop(args, "op"),
{:ok, %Activity{} = activity} <- build_activity(args),
preloaded_activity <- Activities.preload_activity(activity) do
notify_activity(preloaded_activity)
end
end
@ -19,4 +24,27 @@ defmodule Mobilizon.Service.Workers.ActivityBuilder do
def build_activity(args) do
Activities.create_activity(args)
end
@spec notify_activity(Activity.t()) :: :ok
def notify_activity(%Activity{} = activity) do
activity
|> users_to_notify()
|> Enum.each(&Notifier.notify(&1, activity))
end
@spec users_to_notify(Activity.t()) :: list(User.t())
defp users_to_notify(%Activity{group: %Actor{} = group, author_id: author_id}) do
group
|> Actors.list_internal_actors_members_for_group([
:creator,
:administrator,
:moderator,
:member
])
|> Enum.filter(&(&1.id != author_id))
|> Enum.map(& &1.user_id)
|> Enum.filter(& &1)
|> Enum.uniq()
|> Enum.map(&Users.get_user!/1)
end
end

View File

@ -0,0 +1,14 @@
defmodule Mobilizon.Service.Workers.DigestNotifierWorker do
@moduledoc """
Worker to send notifications
"""
use Mobilizon.Service.Workers.Helper, queue: "notifications"
@impl Oban.Worker
def perform(%Job{}) do
# Get last time activities were send
# List activities to send
# Send activites
end
end

73
lib/web/email/activity.ex Normal file
View File

@ -0,0 +1,73 @@
defmodule Mobilizon.Web.Email.Activity do
@moduledoc """
Handles emails sent about activity notifications.
"""
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
import Bamboo.Phoenix
import Mobilizon.Web.Gettext
alias Mobilizon.Activities.Activity
alias Mobilizon.Actors.Actor
alias Mobilizon.Config
alias Mobilizon.Web.{Email, Gettext}
@spec direct_activity(String.t(), list(), String.t()) ::
Bamboo.Email.t()
def direct_activity(
email,
activities,
locale \\ "en"
) do
Gettext.put_locale(locale)
subject =
gettext(
"Activity notification for %{instance}",
instance: Config.instance_name()
)
chunked_activities = chunk_activities(activities)
Email.base_email(to: email, subject: subject)
|> assign(:locale, locale)
|> assign(:subject, subject)
|> assign(:activities, chunked_activities)
|> assign(:total_number_activities, length(activities))
|> render(:email_direct_activity)
end
@spec chunk_activities(list()) :: map()
defp chunk_activities(activities) do
activities
|> Enum.reduce(%{}, fn %Activity{group: %Actor{id: group_id}} = activity, acc ->
Map.update(acc, group_id, [activity], fn activities -> activities ++ [activity] end)
end)
|> Enum.map(fn {key, value} ->
{key, Enum.sort(value, &(&1.inserted_at <= &2.inserted_at))}
end)
|> Enum.map(fn {key, value} -> {key, filter_duplicates(value)} end)
|> Enum.into(%{})
end
# We filter duplicates when subject_params are being the same
# so it will probably not catch much things
@spec filter_duplicates(list()) :: list()
defp filter_duplicates(activities) do
Enum.uniq_by(activities, fn %Activity{
author: %Actor{id: author_id},
group: %Actor{id: group_id},
type: type,
subject: subject,
subject_params: subject_params
} ->
%{
author_id: author_id,
group_id: group_id,
type: type,
subject: subject,
subject_params: subject_params
}
end)
end
end

View File

@ -30,6 +30,7 @@ defmodule Mobilizon.Web do
quote do
use Phoenix.View,
root: "lib/web/templates",
pattern: "**/*",
namespace: Mobilizon.Web
# Import convenience functions from controllers

View File

@ -0,0 +1,70 @@
<%= case @activity.subject do %>
<% :discussion_created -> %>
<%=
dgettext("activity", "%{profile} created the discussion %{discussion}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
discussion: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:discussion,
Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]
) |> URI.decode()}\">
#{@activity.subject_params["discussion_title"]}
</a>"
}
) |> raw %>
<% :discussion_replied -> %>
<%=
dgettext("activity", "%{profile} replied to the discussion %{discussion}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
discussion: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:discussion,
Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]
) |> URI.decode()}\">
#{@activity.subject_params["discussion_title"]}
</a>"
}
) |> raw %>
<% :discussion_renamed -> %>
<%=
dgettext("activity", "%{profile} renamed the discussion %{discussion}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
discussion: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:discussion,
Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]
) |> URI.decode()}\">
#{@activity.subject_params["discussion_title"]}
</a>"
}
) |> raw %>
<% :discussion_archived -> %>
<%=
dgettext("activity", "%{profile} archived the discussion %{discussion}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
discussion: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:discussion,
Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]
) |> URI.decode()}\">
#{@activity.subject_params["discussion_title"]}
</a>"
}
) |> raw %>
<% :discussion_deleted -> %>
<%=
dgettext("activity", "%{profile} deleted the discussion %{discussion}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
discussion: "<b>#{@activity.subject_params["discussion_title"]}</b>"
}
) |> raw %>
<% end %>

View File

@ -0,0 +1,30 @@
<%= case @activity.subject do %><% :discussion_created -> %><%= dgettext("activity", "%{profile} created the discussion %{discussion}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
discussion: @activity.subject_params["discussion_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :discussion, Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]) |> URI.decode() %><% :discussion_replied -> %><%= dgettext("activity", "%{profile} replied to the discussion %{discussion}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
discussion: @activity.subject_params["discussion_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :discussion, Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]) |> URI.decode() %><% :discussion_renamed -> %><%= dgettext("activity", "%{profile} renamed the discussion %{discussion}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
discussion: @activity.subject_params["discussion_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :discussion, Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]) |> URI.decode() %><% :discussion_archived -> %><%= dgettext("activity", "%{profile} archived the discussion %{discussion}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
discussion: @activity.subject_params["discussion_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :discussion, Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]) |> URI.decode() %><% :discussion_deleted -> %><%= dgettext("activity", "%{profile} deleted the discussion %{discussion}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
discussion: @activity.subject_params["discussion_title"]
}
) %><% end %>

View File

@ -0,0 +1,66 @@
<%= case @activity.subject do %>
<% :discussion_created -> %>
<%=
dgettext("activity", "%{profile} created the discussion %{discussion}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
discussion: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:discussion,
Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]
) |> URI.decode()}\">
#{@activity.subject_params["discussion_title"]}</a>"
}
) |> raw %>
<% :discussion_replied -> %>
<%=
dgettext("activity", "%{profile} replied to the discussion %{discussion}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
discussion: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:discussion,
Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]
) |> URI.decode()}\">
#{@activity.subject_params["discussion_title"]}</a>"
}
) |> raw %>
<% :discussion_renamed -> %>
<%=
dgettext("activity", "%{profile} renamed the discussion %{discussion}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
discussion: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:discussion,
Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]
) |> URI.decode()}\">
#{@activity.subject_params["discussion_title"]}</a>"
}
) |> raw %>
<% :discussion_archived -> %>
<%=
dgettext("activity", "%{profile} archived the discussion %{discussion}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
discussion: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:discussion,
Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]
) |> URI.decode()}\">
#{@activity.subject_params["discussion_title"]}</a>"
}
) |> raw %>
<% :discussion_deleted -> %>
<%=
dgettext("activity", "%{profile} deleted the discussion %{discussion}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
discussion: "<b>#{@activity.subject_params["discussion_title"]}</b>"
}
) |> raw %>
<% end %>

View File

@ -0,0 +1,30 @@
<%= case @activity.subject do %><% :discussion_created -> %><%= dgettext("activity", "%{profile} created the discussion %{discussion}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
discussion: @activity.subject_params["discussion_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :discussion, Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]) |> URI.decode() %><% :discussion_replied -> %><%= dgettext("activity", "%{profile} replied to the discussion %{discussion}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
discussion: @activity.subject_params["discussion_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :discussion, Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]) |> URI.decode() %><% :discussion_renamed -> %><%= dgettext("activity", "%{profile} renamed the discussion %{discussion}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
discussion: @activity.subject_params["discussion_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :discussion, Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]) |> URI.decode() %><% :discussion_archived -> %><%= dgettext("activity", "%{profile} archived the discussion %{discussion}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
discussion: @activity.subject_params["discussion_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :discussion, Mobilizon.Actors.Actor.preferred_username_and_domain(@activity.group), @activity.subject_params["discussion_slug"]) |> URI.decode() %><% :discussion_deleted -> %><%= dgettext("activity", "%{profile} deleted the discussion %{discussion}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
discussion: @activity.subject_params["discussion_title"]
}
) %><% end %>

View File

@ -0,0 +1,72 @@
<%= case @activity.subject do %>
<% :event_created -> %>
<%=
dgettext("activity", "The event %{event} was created by %{profile}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
event: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:event,
@activity.subject_params["event_uuid"]
) |> URI.decode()}\">
#{@activity.subject_params["event_title"]}
</a>"
}
) |> raw %>
<% :event_updated -> %>
<%=
dgettext("activity", "The event %{event} was updated by %{profile}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
event: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:event,
@activity.subject_params["event_uuid"]
) |> URI.decode()}\">
#{@activity.subject_params["event_title"]}
</a>"
}
) |> raw %>
<% :event_deleted -> %>
<%=
dgettext("activity", "The event %{event} was deleted by %{profile}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
event: "<b>#{@activity.subject_params["event_title"]}</b>"
}
) |> raw %>
<% :comment_posted -> %>
<%= if @activity.subject_params["comment_reply_to"] do %>
<%=
dgettext("activity", "%{profile} replied to a comment on the event %{event}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
event: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:event,
@activity.subject_params["event_uuid"]
) |> URI.decode()}\">
#{@activity.subject_params["event_title"]}
</a>"
}
) |> raw %>
<% else %>
<%=
dgettext("activity", "%{profile} posted a comment on the event %{event}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
event: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:event,
@activity.subject_params["event_uuid"]
) |> URI.decode()}\">
#{@activity.subject_params["event_title"]}
</a>"
}
) |> raw %>
<% end %>
<% end %>

View File

@ -0,0 +1,31 @@
<%= 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),
event: @activity.subject_params["event_title"]
}
) %>
<%= 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),
event: @activity.subject_params["event_title"]
}
) %>
<%= 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),
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),
event: @activity.subject_params["event_title"]
}
) %>
<%= 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),
event: @activity.subject_params["event_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :event, @activity.subject_params["event_uuid"]) |> URI.decode() %><% end %><% end %>

View File

@ -0,0 +1,32 @@
<%= case @activity.subject do %>
<% :group_created -> %>
<%=
dgettext("activity", "%{profile} created the group %{group}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
group: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:actor,
@activity.subject_params["group_federated_username"]
) |> URI.decode()}\">
#{@activity.subject_params["group_name"]}
</a>"
}
) |> raw %>
<% :group_updated -> %>
<%=
dgettext("activity", "%{profile} updated the group %{group}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
group: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:actor,
@activity.subject_params["group_federated_username"]
) |> URI.decode()}\">
#{@activity.subject_params["group_name"]}
</a>"
}
) |> raw %>
<% end %>

View File

@ -0,0 +1,13 @@
<%= case @activity.subject do %><% :group_created -> %><%= dgettext("activity", "%{profile} created the group %{group}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
group: @activity.subject_params["group_name"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :actor, @activity.subject_params["group_federated_username"]) |> URI.decode() %><% :group_updated -> %><%= dgettext("activity", "%{profile} updated the group %{group}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
group: @activity.subject_params["group_name"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :actor, @activity.subject_params["group_federated_username"]) |> URI.decode() %><% end %>

View File

@ -0,0 +1,69 @@
<%= case @activity.subject do %>
<% :member_request -> %>
<%=
dgettext("activity", "%{member} requested to join the group.",
%{
member: "<b>#{@activity.subject_params["member_actor_name"]}</b>",
}
) |> raw %>
<% :member_invited -> %>
<%=
dgettext("activity", "%{member} was invited by %{profile}.",
%{
member: "<b>#{@activity.subject_params["member_actor_name"]}</b>",
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
}
) |> raw %>
<% :member_accepted_invitation -> %>
<%=
dgettext("activity", "%{member} accepted the invitation to join the group.",
%{
member: "<b>#{@activity.subject_params["member_actor_name"]}</b>",
}
) |> raw %>
<% :member_rejected_invitation -> %>
<%=
dgettext("activity", "%{member} rejected the invitation to join the group.",
%{
member: "<b>#{@activity.subject_params["member_actor_name"]}</b>",
}
) |> raw %>
<% :member_joined -> %>
<%=
dgettext("activity", "%{member} joined the group.",
%{
member: "<b title=\"#{@activity.subject_params["member_actor_federated_username"]}\">#{@activity.subject_params["member_actor_name"]}</b>",
}
) |> raw %>
<% :member_added -> %>
<%=
dgettext("activity", "%{profile} added the member %{member}.",
%{
member: "<b>#{@activity.subject_params["member_actor_name"]}</b>",
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
}
) |> raw %>
<% :member_updated -> %>
<%=
dgettext("activity", "%{profile} updated the member %{member}.",
%{
member: "<b>#{@activity.subject_params["member_actor_name"]}</b>",
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
}
) |> raw %>
<% :member_removed -> %>
<%=
dgettext("activity", "%{profile} excluded member %{member}.",
%{
member: "<b>#{@activity.subject_params["member_actor_name"]}</b>",
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
}
) |> raw %>
<% :member_quit -> %>
<%=
dgettext("activity", "%{profile} quit the group.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
}
) |> raw %>
<% end %>

View File

@ -0,0 +1,49 @@
<%= case @activity.subject do %><% :member_request -> %><%= dgettext("activity", "%{member} requested to join the group.",
%{
member: @activity.subject_params["member_actor_name"],
}
) %>
<% :member_invited -> %><%= dgettext("activity", "%{member} was invited by %{profile}.",
%{
member: @activity.subject_params["member_actor_name"],
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
}
) %>
<% :member_accepted_invitation -> %><%= dgettext("activity", "%{member} accepted the invitation to join the group.",
%{
member: @activity.subject_params["member_actor_name"],
}
) %>
<% :member_rejected_invitation -> %><%= dgettext("activity", "%{member} rejected the invitation to join the group.",
%{
member: @activity.subject_params["member_actor_name"],
}
) %>
<% :member_joined -> %><%= dgettext("activity", "%{member} joined the group.",
%{
member: @activity.subject_params["member_actor_name"],
}
) %>
<% :member_added -> %><%= dgettext("activity", "%{profile} added the member %{member}.",
%{
member: @activity.subject_params["member_actor_name"],
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
}
) %>
<% :member_updated -> %><%= dgettext("activity", "%{profile} updated the member %{member}.",
%{
member: @activity.subject_params["member_actor_name"],
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
}
) %>
<% :member_removed -> %><%= dgettext("activity", "%{profile} excluded member %{member}.",
%{
member: @activity.subject_params["member_actor_name"],
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
}
) %>
<% :member_quit -> %><%= dgettext("activity", "%{profile} quit the group.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
}
) %><% end %>

View File

@ -0,0 +1,40 @@
<%= case @activity.subject do %>
<% :post_created -> %>
<%=
dgettext("activity", "The post %{post} was created by %{profile}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
post: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:post,
@activity.subject_params["post_slug"]
) |> URI.decode()}\">
#{@activity.subject_params["post_title"]}
</a>"
}
) |> raw %>
<% :post_updated -> %>
<%=
dgettext("activity", "The post %{post} was updated by %{profile}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
post: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:post,
@activity.subject_params["post_slug"]
) |> URI.decode()}\">
#{@activity.subject_params["post_title"]}
</a>"
}
) |> raw %>
<% :post_deleted -> %>
<%=
dgettext("activity", "The post %{post} was deleted by %{profile}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
post: "<b>#{@activity.subject_params["post_title"]}</b>"
}
) |> raw %>
<% end %>

View File

@ -0,0 +1,18 @@
<%= case @activity.subject do %><% :post_created -> %><%= dgettext("activity", "The post %{post} was created by %{profile}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
post: @activity.subject_params["post_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :post, @activity.subject_params["post_slug"]) |> URI.decode() %><% :post_updated -> %><%= dgettext("activity", "The post %{post} was updated by %{profile}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
post: @activity.subject_params["post_title"]
}
) %>
<%= page_url(Mobilizon.Web.Endpoint, :post, @activity.subject_params["post_slug"]) |> URI.decode() %><% :post_deleted -> %><%= dgettext("activity", "The post %{post} was deleted by %{profile}.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
post: @activity.subject_params["post_title"]
}
) %><% end %>

View File

@ -0,0 +1,118 @@
<%= case @activity.subject do %>
<% :resource_created -> %>
<%= if @activity.subject_params["is_folder"] do %>
<%=
dgettext("activity", "%{profile} created the folder %{resource}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
resource: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:resource,
@activity.subject_params["resource_uuid"]
) |> URI.decode()}\">
#{@activity.subject_params["resource_title"]}
</a>"
}
) |> raw %>
<% else %>
<%=
dgettext("activity", "%{profile} created the resource %{resource}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
resource: "<a href=\"#{
page_url(
Mobilizon.Web.Endpoint,
:resource,
@activity.subject_params["resource_uuid"]
) |> URI.decode()}\">
#{@activity.subject_params["resource_title"]}
</a>"
}
) |> raw %>
<% end %>
<% :resource_renamed -> %>
<%= if @activity.subject_params["is_folder"] do %>
<%=
dgettext("activity", "%{profile} renamed the folder from %{old_resource_title} to %{resource}.",
%{
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
resource: "<a href=\"#{
page_