Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2023-10-17 16:41:31 +02:00
parent 0613f7f736
commit b5672cee7e
108 changed files with 5221 additions and 1318 deletions

View File

@@ -44,7 +44,7 @@ defmodule Mobilizon.Web.Auth.Context do
context = if is_nil(user_agent), do: context, else: Map.put(context, :user_agent, user_agent)
put_private(conn, :absinthe, %{context: context})
Absinthe.Plug.put_options(conn, context: context)
end
defp set_user_context({conn, context}, %User{id: user_id, email: user_email} = user) do

View File

@@ -3,9 +3,10 @@ defmodule Mobilizon.Web.Cache.ActivityPub do
ActivityPub related cache.
"""
alias Mobilizon.{Actors, Discussions, Events, Posts, Resources, Todos, Tombstone}
alias Mobilizon.{Actors, Conversations, Discussions, Events, Posts, Resources, Todos, Tombstone}
alias Mobilizon.Actors.Actor, as: ActorModel
alias Mobilizon.Actors.Member
alias Mobilizon.Conversations.Conversation
alias Mobilizon.Discussions.{Comment, Discussion}
alias Mobilizon.Events.Event
alias Mobilizon.Federation.ActivityPub.{Actor, Relay}
@@ -184,6 +185,23 @@ defmodule Mobilizon.Web.Cache.ActivityPub do
end)
end
@doc """
Gets a conversation participant by it's ID, with all associations loaded.
"""
@spec get_conversation_by_id_with_preload(String.t()) ::
{:commit, Todo.t()} | {:ignore, nil}
def get_conversation_by_id_with_preload(id) do
Cachex.fetch(@cache, "conversation_participant_" <> id, fn "conversation_participant_" <> id ->
case Conversations.get_conversation_participant(id) do
%Conversation{} = conversation ->
{:commit, conversation}
nil ->
{:ignore, nil}
end
end)
end
@doc """
Gets a member by its UUID, with all associations loaded.
"""

View File

@@ -4,6 +4,7 @@ defmodule Mobilizon.Web.Cache do
"""
alias Mobilizon.Actors.{Actor, Member}
alias Mobilizon.Conversations.Conversation
alias Mobilizon.Discussions.{Comment, Discussion}
alias Mobilizon.Events.Event
alias Mobilizon.Posts.Post
@@ -27,6 +28,10 @@ defmodule Mobilizon.Web.Cache do
defdelegate get_todo_list_by_uuid_with_preload(uuid), to: ActivityPub
@spec get_todo_by_uuid_with_preload(binary) :: {:commit, Todo.t()} | {:ignore, nil}
defdelegate get_todo_by_uuid_with_preload(uuid), to: ActivityPub
@spec get_conversation_by_id_with_preload(binary) ::
{:commit, Conversation.t()} | {:ignore, nil}
defdelegate get_conversation_by_id_with_preload(uuid), to: ActivityPub
@spec get_member_by_uuid_with_preload(binary) :: {:commit, Member.t()} | {:ignore, nil}
defdelegate get_member_by_uuid_with_preload(uuid), to: ActivityPub
@spec get_post_by_slug_with_preload(binary) :: {:commit, Post.t()} | {:ignore, nil}

View File

@@ -13,9 +13,7 @@ defmodule Mobilizon.Web.GraphQLSocket do
with {:ok, authed_socket} <-
Guardian.Phoenix.Socket.authenticate(socket, Mobilizon.Web.Auth.Guardian, token),
resource <- Guardian.Phoenix.Socket.current_resource(authed_socket) do
set_context(authed_socket, resource)
{:ok, authed_socket}
{:ok, set_context(authed_socket, resource)}
else
{:error, _} ->
:error
@@ -24,8 +22,17 @@ defmodule Mobilizon.Web.GraphQLSocket do
def connect(_args, _socket), do: :error
@spec id(any) :: nil
def id(_socket), do: nil
@spec id(Phoenix.Socket.t()) :: String.t() | nil
def id(%Phoenix.Socket{assigns: assigns}) do
context = Keyword.get(assigns.absinthe.opts, :context)
current_user = Map.get(context, :current_user)
if current_user do
"user_socket:#{current_user.id}"
else
nil
end
end
@spec set_context(Phoenix.Socket.t(), User.t() | ApplicationToken.t()) :: Phoenix.Socket.t()
defp set_context(socket, %User{} = user) do

View File

@@ -85,6 +85,12 @@ defmodule Mobilizon.Web.PageController do
render_or_error(conn, &checks?/3, status, :todo, todo)
end
@spec conversation(Plug.Conn.t(), map()) :: Plug.Conn.t() | {:error, :not_found}
def conversation(conn, %{"id" => slug}) do
{status, conversation} = Cache.get_conversation_by_id_with_preload(slug)
render_or_error(conn, &checks?/3, status, :conversation, conversation)
end
@typep collections :: :resources | :posts | :discussions | :events | :todos
@spec resources(Plug.Conn.t(), map()) :: Plug.Conn.t()

View File

@@ -132,6 +132,7 @@ defmodule Mobilizon.Web.Router do
get("/@:name/discussions", PageController, :discussions)
get("/@:name/events", PageController, :events)
get("/p/:slug", PageController, :post)
get("/conversations/:id", PageController, :conversation)
get("/@:name/c/:slug", PageController, :discussion)
end
@@ -176,6 +177,7 @@ defmodule Mobilizon.Web.Router do
forward("/", Absinthe.Plug.GraphiQL,
schema: Mobilizon.GraphQL.Schema,
socket: Mobilizon.Web.GraphQLSocket,
interface: :playground
)
end

View File

@@ -0,0 +1,20 @@
<%= case @activity.subject do %>
<% :conversation_created -> %>
<%= dgettext("activity", "%{profile} mentionned you in a %{conversation}.", %{
profile: "<b>#{escaped_display_name_and_username(@activity.author)}</b>",
conversation:
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
:conversation,
@activity.subject_params["conversation_participant_id"]) |> URI.decode()}\">conversation</a>"
})
|> raw %>
<% :conversation_replied -> %>
<%= dgettext("activity", "%{profile} replied you in a %{conversation}.", %{
profile: "<b>#{escaped_display_name_and_username(@activity.author)}</b>",
conversation:
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
:conversation,
@activity.subject_params["conversation_participant_id"]) |> URI.decode()}\">conversation</a>"
})
|> raw %>
<% end %>

View File

@@ -0,0 +1,11 @@
<%= case @activity.subject do %><% :conversation_created -> %><%= dgettext("activity", "%{profile} mentionned you in a conversation.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
}
) %>
<%= Routes.page_url(Mobilizon.Web.Endpoint, :conversation, @activity.subject_params["conversation_participant_id"]) |> URI.decode() %><% :conversation_replied -> %><%= dgettext("activity", "%{profile} replied you in a conversation.",
%{
profile: Mobilizon.Actors.Actor.display_name_and_username(@activity.author),
}
) %>
<%= Routes.page_url(Mobilizon.Web.Endpoint, :conversation, @activity.subject_params["conversation_participant_id"]) |> URI.decode() %><% end %>

View File

@@ -167,6 +167,10 @@
<%= render("activity/_discussion_activity_item.html",
activity: activity
) %>
<% :conversation -> %>
<%= render("activity/_conversation_activity_item.html",
activity: activity
) %>
<% :event -> %>
<%= render("activity/_event_activity_item.html",
activity: activity

View File

@@ -15,7 +15,7 @@
<% end %>
<%= for activity <- Enum.take(group_activities, 5) do %>
* <%= case activity.type do %><% :discussion -> %><%= render("activity/_discussion_activity_item.text", activity: activity) %><% :event -> %><%= render("activity/_event_activity_item.text", activity: activity) %><% :group -> %><%= render("activity/_group_activity_item.text", activity: activity) %>
* <%= case activity.type do %><% :discussion -> %><%= render("activity/_discussion_activity_item.text", activity: activity) %><% :conversation -> %><%= render("activity/_conversation_activity_item.text", activity: activity) %><% :event -> %><%= render("activity/_event_activity_item.text", activity: activity) %><% :group -> %><%= render("activity/_group_activity_item.text", activity: activity) %>
<% :member -> %><%= render("activity/_member_activity_item.text", activity: activity) %><% :post -> %><%= render("activity/_post_activity_item.text", activity: activity) %><% :resource -> %><%= render("activity/_resource_activity_item.text", activity: activity) %><% :comment -> %><%= render("activity/_comment_activity_item.text", activity: activity) %><% end %>
<%= unless @single_activity do %><%= datetime_to_string(activity.inserted_at, @locale, :short) %><% end %>
<% end %>