From dcf6531eba0e0372bbe4f8306aea1c96bf0f44db Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Mon, 15 Aug 2022 11:13:41 +0100 Subject: [PATCH 1/8] add compatibility with fedibird stuff --- lib/pleroma/web/mastodon_api/views/status_view.ex | 1 + .../controllers/emoji_reaction_controller.ex | 1 + lib/pleroma/web/router.ex | 5 +++++ lib/pleroma/web/templates/masto_fe/index.html.eex | 15 +++++++-------- lib/pleroma/web/views/masto_fe_view.ex | 6 +++++- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index f0fe9a4ba..cd3c04598 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -375,6 +375,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do emojis: build_emojis(object.data["emoji"]), quote_id: if(quote, do: quote.id, else: nil), quote: maybe_render_quote(quote, opts), + emoji_reactions: emoji_reactions, pleroma: %{ local: activity.local, conversation_id: get_context_id(activity), diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex index 1de02faf8..325f86ef0 100644 --- a/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex @@ -74,6 +74,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionController do defp filter(reactions, _), do: reactions def create(%{assigns: %{user: user}} = conn, %{id: activity_id, emoji: emoji}) do + emoji = Pleroma.Emoji.maybe_quote(emoji) with {:ok, _activity} <- CommonAPI.react_with_emoji(activity_id, user, emoji) do activity = Activity.get_by_id(activity_id) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index a0310bbb5..647d99278 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -457,6 +457,11 @@ defmodule Pleroma.Web.Router do get("/federation_status", InstancesController, :show) end + scope "/api/v1", Pleroma.Web.PleromaAPI do + pipe_through(:authenticated_api) + put("/statuses/:id/emoji_reactions/:emoji", EmojiReactionController, :create) + end + scope "/api/v1", Pleroma.Web.MastodonAPI do pipe_through(:authenticated_api) diff --git a/lib/pleroma/web/templates/masto_fe/index.html.eex b/lib/pleroma/web/templates/masto_fe/index.html.eex index dadf8f413..02c421831 100644 --- a/lib/pleroma/web/templates/masto_fe/index.html.eex +++ b/lib/pleroma/web/templates/masto_fe/index.html.eex @@ -11,22 +11,21 @@ - - + + + + - + - - - - + + -
diff --git a/lib/pleroma/web/views/masto_fe_view.ex b/lib/pleroma/web/views/masto_fe_view.ex index 63a9c8179..fbc9fc565 100644 --- a/lib/pleroma/web/views/masto_fe_view.ex +++ b/lib/pleroma/web/views/masto_fe_view.ex @@ -27,7 +27,10 @@ defmodule Pleroma.Web.MastoFEView do display_sensitive_media: false, reduce_motion: false, max_toot_chars: limit, - mascot: User.get_mascot(user)["url"] + mascot: User.get_mascot(user)["url"], + show_quote_button: true, + enable_reaction: true, + compact_reaction: false }, poll_limits: Config.get([:instance, :poll_limits]), rights: %{ @@ -56,6 +59,7 @@ defmodule Pleroma.Web.MastoFEView do "video\/mp4" ] }, + lists: [], settings: user.mastofe_settings || %{}, push_subscription: nil, accounts: %{user.id => render(AccountView, "show.json", user: user, for: user)}, -- 2.50.1 From 1b75aeead64c6e29b2becc8666f9a9a05c20eade Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 16 Aug 2022 12:05:24 +0100 Subject: [PATCH 2/8] add multi-stream sockets --- config/config.exs | 8 +++ lib/pleroma/web/masto_fe_controller.ex | 14 ++++- .../web/mastodon_api/websocket_handler.ex | 44 ++++++++++++-- .../controllers/emoji_reaction_controller.ex | 1 + lib/pleroma/web/streamer.ex | 15 +++-- ...index.html.eex => fedibird.index.html.eex} | 0 .../masto_fe/glitchsoc.index.html.eex | 35 +++++++++++ lib/pleroma/web/views/masto_fe_view.ex | 3 +- lib/pleroma/web/views/streamer_view.ex | 15 +++-- .../integration/mastodon_websocket_test.exs | 4 +- test/pleroma/notification_test.exs | 4 +- .../mastodon_api/views/status_view_test.exs | 1 + test/pleroma/web/streamer_test.exs | 60 ++++++++++++------- 13 files changed, 161 insertions(+), 43 deletions(-) rename lib/pleroma/web/templates/masto_fe/{index.html.eex => fedibird.index.html.eex} (100%) create mode 100644 lib/pleroma/web/templates/masto_fe/glitchsoc.index.html.eex diff --git a/config/config.exs b/config/config.exs index f49ec861c..83977da19 100644 --- a/config/config.exs +++ b/config/config.exs @@ -734,6 +734,14 @@ config :pleroma, :frontends, "build_dir" => "distribution", "ref" => "akkoma" }, + "fedibird-fe" => %{ + "name" => "fedibird-fe", + "git" => "https://akkoma.dev/AkkomaGang/fedibird-fe", + "build_url" => + "https://akkoma-updates.s3-website.fr-par.scw.cloud/frontend/${ref}/fedibird-fe.zip", + "build_dir" => "distribution", + "ref" => "akkoma" + }, "admin-fe" => %{ "name" => "admin-fe", "git" => "https://akkoma.dev/AkkomaGang/admin-fe", diff --git a/lib/pleroma/web/masto_fe_controller.ex b/lib/pleroma/web/masto_fe_controller.ex index d2460f51d..7b6e01aad 100644 --- a/lib/pleroma/web/masto_fe_controller.ex +++ b/lib/pleroma/web/masto_fe_controller.ex @@ -27,9 +27,21 @@ defmodule Pleroma.Web.MastoFEController do def index(conn, _params) do with %{assigns: %{user: %User{} = user, token: %Token{app_id: token_app_id} = token}} <- conn, {:ok, %{id: ^token_app_id}} <- AuthController.local_mastofe_app() do + flavour = + [:frontends, :mastodon] + |> Pleroma.Config.get() + |> Map.get("name", "mastodon-fe") + + index = + if flavour == "fedibird-fe" do + "fedibird.index.html" + else + "glitchsoc.index.html" + end + conn |> put_layout(false) - |> render("index.html", + |> render(index, token: token.token, user: user, custom_emojis: Pleroma.Emoji.get_all() diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex index 861a7ce3e..b8fe3ad78 100644 --- a/lib/pleroma/web/mastodon_api/websocket_handler.ex +++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex @@ -32,8 +32,15 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do req end - {:cowboy_websocket, req, %{user: user, topic: topic, count: 0, timer: nil}, - %{idle_timeout: @timeout}} + {:cowboy_websocket, req, + %{ + user: user, + topic: topic, + count: 0, + timer: nil, + subscriptions: [], + oauth_token: oauth_token + }, %{idle_timeout: @timeout}} else {:error, :bad_topic} -> Logger.debug("#{__MODULE__} bad topic #{inspect(req)}") @@ -70,16 +77,45 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do {:reply, {:text, "pong"}, %{state | timer: timer()}} end + def websocket_handle({:text, text}, state) do + with {:ok, json} <- Jason.decode(text) do + websocket_handle({:json, json}, state) + else + _ -> + Logger.error("#{__MODULE__} received text frame: #{text}") + {:ok, state} + end + end + + def websocket_handle( + {:json, %{"type" => "subscribe", "stream" => stream_name}}, + %{user: user, oauth_token: token} = state + ) do + with {:ok, topic} <- Streamer.get_topic(stream_name, user, token, %{}) do + new_subscriptions = + [topic | Map.get(state, :subscriptions, [])] + |> Enum.uniq() + + {:ok, _topic} = Streamer.add_socket(topic, user) + + {:ok, Map.put(state, :subscriptions, new_subscriptions)} + else + _ -> + Logger.error("#{__MODULE__} received invalid topic: #{stream_name}") + {:ok, state} + end + end + def websocket_handle(frame, state) do Logger.error("#{__MODULE__} received frame: #{inspect(frame)}") {:ok, state} end - def websocket_info({:render_with_user, view, template, item}, state) do + def websocket_info({:render_with_user, view, template, item, topic}, state) do user = %User{} = User.get_cached_by_ap_id(state.user.ap_id) unless Streamer.filtered_by_user?(user, item) do - websocket_info({:text, view.render(template, item, user)}, %{state | user: user}) + websocket_info({:text, view.render(template, item, user, topic)}, %{state | user: user}) else {:ok, state} end diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex index 325f86ef0..91658587a 100644 --- a/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex @@ -75,6 +75,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionController do def create(%{assigns: %{user: user}} = conn, %{id: activity_id, emoji: emoji}) do emoji = Pleroma.Emoji.maybe_quote(emoji) + with {:ok, _activity} <- CommonAPI.react_with_emoji(activity_id, user, emoji) do activity = Activity.get_by_id(activity_id) diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index 9a4ac1317..d5b1d0678 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -114,6 +114,11 @@ defmodule Pleroma.Web.Streamer do {:error, :unauthorized} end + # mastodon multi-topic WS + def get_topic(nil, _user, _oauth_token, _params) do + {:ok, :multi} + end + def get_topic(_stream, _user, _oauth_token, _params) do {:error, :bad_topic} end @@ -186,8 +191,8 @@ defmodule Pleroma.Web.Streamer do end defp do_stream("follow_relationship", item) do - text = StreamerView.render("follow_relationships_update.json", item) user_topic = "user:#{item.follower.id}" + text = StreamerView.render("follow_relationships_update.json", item, user_topic) Logger.debug("Trying to push follow relationship update to #{user_topic}\n\n") @@ -235,7 +240,7 @@ defmodule Pleroma.Web.Streamer do when topic in ["user", "user:notification"] do Registry.dispatch(@registry, "#{topic}:#{item.user_id}", fn list -> Enum.each(list, fn {pid, _auth} -> - send(pid, {:render_with_user, StreamerView, "notification.json", item}) + send(pid, {:render_with_user, StreamerView, "notification.json", item, topic}) end) end) end @@ -259,7 +264,7 @@ defmodule Pleroma.Web.Streamer do end defp push_to_socket(topic, %Participation{} = participation) do - rendered = StreamerView.render("conversation.json", participation) + rendered = StreamerView.render("conversation.json", participation, topic) Registry.dispatch(@registry, topic, fn list -> Enum.each(list, fn {pid, _} -> @@ -283,12 +288,12 @@ defmodule Pleroma.Web.Streamer do defp push_to_socket(_topic, %Activity{data: %{"type" => "Delete"}}), do: :noop defp push_to_socket(topic, item) do - anon_render = StreamerView.render("update.json", item) + anon_render = StreamerView.render("update.json", item, topic) Registry.dispatch(@registry, topic, fn list -> Enum.each(list, fn {pid, auth?} -> if auth? do - send(pid, {:render_with_user, StreamerView, "update.json", item}) + send(pid, {:render_with_user, StreamerView, "update.json", item, topic}) else send(pid, {:text, anon_render}) end diff --git a/lib/pleroma/web/templates/masto_fe/index.html.eex b/lib/pleroma/web/templates/masto_fe/fedibird.index.html.eex similarity index 100% rename from lib/pleroma/web/templates/masto_fe/index.html.eex rename to lib/pleroma/web/templates/masto_fe/fedibird.index.html.eex diff --git a/lib/pleroma/web/templates/masto_fe/glitchsoc.index.html.eex b/lib/pleroma/web/templates/masto_fe/glitchsoc.index.html.eex new file mode 100644 index 000000000..dadf8f413 --- /dev/null +++ b/lib/pleroma/web/templates/masto_fe/glitchsoc.index.html.eex @@ -0,0 +1,35 @@ + + + + + + +<%= Config.get([:instance, :name]) %> + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + diff --git a/lib/pleroma/web/views/masto_fe_view.ex b/lib/pleroma/web/views/masto_fe_view.ex index fbc9fc565..35ee3d630 100644 --- a/lib/pleroma/web/views/masto_fe_view.ex +++ b/lib/pleroma/web/views/masto_fe_view.ex @@ -30,7 +30,8 @@ defmodule Pleroma.Web.MastoFEView do mascot: User.get_mascot(user)["url"], show_quote_button: true, enable_reaction: true, - compact_reaction: false + compact_reaction: false, + advanced_layout: true }, poll_limits: Config.get([:instance, :poll_limits]), rights: %{ diff --git a/lib/pleroma/web/views/streamer_view.ex b/lib/pleroma/web/views/streamer_view.ex index de2e4d1e9..f455f941e 100644 --- a/lib/pleroma/web/views/streamer_view.ex +++ b/lib/pleroma/web/views/streamer_view.ex @@ -11,8 +11,9 @@ defmodule Pleroma.Web.StreamerView do alias Pleroma.User alias Pleroma.Web.MastodonAPI.NotificationView - def render("update.json", %Activity{} = activity, %User{} = user) do + def render("update.json", %Activity{} = activity, %User{} = user, topic) do %{ + stream: [topic], event: "update", payload: Pleroma.Web.MastodonAPI.StatusView.render( @@ -25,8 +26,9 @@ defmodule Pleroma.Web.StreamerView do |> Jason.encode!() end - def render("notification.json", %Notification{} = notify, %User{} = user) do + def render("notification.json", %Notification{} = notify, %User{} = user, topic) do %{ + stream: [topic], event: "notification", payload: NotificationView.render( @@ -38,8 +40,9 @@ defmodule Pleroma.Web.StreamerView do |> Jason.encode!() end - def render("update.json", %Activity{} = activity) do + def render("update.json", %Activity{} = activity, topic) do %{ + stream: [topic], event: "update", payload: Pleroma.Web.MastodonAPI.StatusView.render( @@ -51,8 +54,9 @@ defmodule Pleroma.Web.StreamerView do |> Jason.encode!() end - def render("follow_relationships_update.json", item) do + def render("follow_relationships_update.json", item, topic) do %{ + stream: [topic], event: "pleroma:follow_relationships_update", payload: %{ @@ -73,8 +77,9 @@ defmodule Pleroma.Web.StreamerView do |> Jason.encode!() end - def render("conversation.json", %Participation{} = participation) do + def render("conversation.json", %Participation{} = participation, topic) do %{ + stream: [topic], event: "conversation", payload: Pleroma.Web.MastodonAPI.ConversationView.render("participation.json", %{ diff --git a/test/pleroma/integration/mastodon_websocket_test.exs b/test/pleroma/integration/mastodon_websocket_test.exs index 43ec57893..356bfa48d 100644 --- a/test/pleroma/integration/mastodon_websocket_test.exs +++ b/test/pleroma/integration/mastodon_websocket_test.exs @@ -31,9 +31,9 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do WebsocketClient.start_link(self(), path, headers) end - test "refuses invalid requests" do + test "allows multi-streams" do capture_log(fn -> - assert {:error, {404, _}} = start_socket() + assert {:ok, _} = start_socket() assert {:error, {404, _}} = start_socket("?stream=ncjdk") Process.sleep(30) end) diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs index b47edd0a3..4354dd2b6 100644 --- a/test/pleroma/notification_test.exs +++ b/test/pleroma/notification_test.exs @@ -224,7 +224,7 @@ defmodule Pleroma.NotificationTest do task = Task.async(fn -> {:ok, _topic} = Streamer.get_topic_and_add_socket("user", user, oauth_token) - assert_receive {:render_with_user, _, _, _}, 4_000 + assert_receive {:render_with_user, _, _, _, "user"}, 4_000 end) task_user_notification = @@ -232,7 +232,7 @@ defmodule Pleroma.NotificationTest do {:ok, _topic} = Streamer.get_topic_and_add_socket("user:notification", user, oauth_token) - assert_receive {:render_with_user, _, _, _}, 4_000 + assert_receive {:render_with_user, _, _, _, "user:notification"}, 4_000 end) activity = insert(:note_activity) diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs index fb3255927..4987093d0 100644 --- a/test/pleroma/web/mastodon_api/views/status_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs @@ -272,6 +272,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do spoiler_text: HTML.filter_tags(object_data["summary"]), visibility: "public", media_attachments: [], + emoji_reactions: [], mentions: [], tags: [ %{ diff --git a/test/pleroma/web/streamer_test.exs b/test/pleroma/web/streamer_test.exs index 841db0e91..07129ff11 100644 --- a/test/pleroma/web/streamer_test.exs +++ b/test/pleroma/web/streamer_test.exs @@ -157,7 +157,8 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("user", user, oauth_token) {:ok, activity} = CommonAPI.post(user, %{status: "hey"}) - assert_receive {:render_with_user, _, _, ^activity} + stream_name = "user:#{user.id}" + assert_receive {:render_with_user, _, _, ^activity, ^stream_name} refute Streamer.filtered_by_user?(user, activity) end @@ -168,7 +169,11 @@ defmodule Pleroma.Web.StreamerTest do {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"}) {:ok, announce} = CommonAPI.repeat(activity.id, user) - assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce} + stream_name = "user:#{user.id}" + + assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce, + ^stream_name} + refute Streamer.filtered_by_user?(user, announce) end @@ -221,7 +226,11 @@ defmodule Pleroma.Web.StreamerTest do {:ok, %Pleroma.Activity{data: _data, local: false} = announce} = Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming(data) - assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce} + stream_name = "user:#{user.id}" + + assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce, + ^stream_name} + refute Streamer.filtered_by_user?(user, announce) end @@ -233,7 +242,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("user", user, oauth_token) Streamer.stream("user", notify) - assert_receive {:render_with_user, _, _, ^notify} + assert_receive {:render_with_user, _, _, ^notify, "user"} refute Streamer.filtered_by_user?(user, notify) end @@ -245,7 +254,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("user:notification", user, oauth_token) Streamer.stream("user:notification", notify) - assert_receive {:render_with_user, _, _, ^notify} + assert_receive {:render_with_user, _, _, ^notify, "user:notification"} refute Streamer.filtered_by_user?(user, notify) end @@ -291,7 +300,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("user:notification", user, oauth_token) {:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id) - assert_receive {:render_with_user, _, "notification.json", notif} + assert_receive {:render_with_user, _, "notification.json", notif, "user:notification"} assert notif.activity.id == favorite_activity.id refute Streamer.filtered_by_user?(user, notif) end @@ -320,7 +329,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("user:notification", user, oauth_token) {:ok, _follower, _followed, follow_activity} = CommonAPI.follow(user2, user) - assert_receive {:render_with_user, _, "notification.json", notif} + assert_receive {:render_with_user, _, "notification.json", notif, "user:notification"} assert notif.activity.id == follow_activity.id refute Streamer.filtered_by_user?(user, notif) end @@ -384,7 +393,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("public", user, oauth_token) {:ok, activity} = CommonAPI.post(other_user, %{status: "Test"}) - assert_receive {:render_with_user, _, _, ^activity} + assert_receive {:render_with_user, _, _, ^activity, "public"} refute Streamer.filtered_by_user?(other_user, activity) end @@ -436,7 +445,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("public", user, oauth_token) Streamer.stream("public", activity) - assert_receive {:render_with_user, _, _, ^activity} + assert_receive {:render_with_user, _, _, ^activity, "public"} assert Streamer.filtered_by_user?(user, activity) end @@ -458,7 +467,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("public", user, oauth_token) Streamer.stream("public", activity) - assert_receive {:render_with_user, _, _, ^activity} + assert_receive {:render_with_user, _, _, ^activity, "public"} refute Streamer.filtered_by_user?(user, activity) end @@ -481,7 +490,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("public", user, oauth_token) Streamer.stream("public", activity) - assert_receive {:render_with_user, _, _, ^activity} + assert_receive {:render_with_user, _, _, ^activity, "public"} refute Streamer.filtered_by_user?(user, activity) end end @@ -495,7 +504,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("public", user, oauth_token) {:ok, activity} = CommonAPI.post(blocked_user, %{status: "Test"}) - assert_receive {:render_with_user, _, _, ^activity} + assert_receive {:render_with_user, _, _, ^activity, "public"} assert Streamer.filtered_by_user?(user, activity) end @@ -512,17 +521,17 @@ defmodule Pleroma.Web.StreamerTest do {:ok, activity_one} = CommonAPI.post(friend, %{status: "hey! @#{blockee.nickname}"}) - assert_receive {:render_with_user, _, _, ^activity_one} + assert_receive {:render_with_user, _, _, ^activity_one, "public"} assert Streamer.filtered_by_user?(blocker, activity_one) {:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"}) - assert_receive {:render_with_user, _, _, ^activity_two} + assert_receive {:render_with_user, _, _, ^activity_two, "public"} assert Streamer.filtered_by_user?(blocker, activity_two) {:ok, activity_three} = CommonAPI.post(blockee, %{status: "hey! @#{blocker.nickname}"}) - assert_receive {:render_with_user, _, _, ^activity_three} + assert_receive {:render_with_user, _, _, ^activity_three, "public"} assert Streamer.filtered_by_user?(blocker, activity_three) end end @@ -583,7 +592,8 @@ defmodule Pleroma.Web.StreamerTest do visibility: "private" }) - assert_receive {:render_with_user, _, _, ^activity} + stream_name = "list:#{list.id}" + assert_receive {:render_with_user, _, _, ^activity, ^stream_name} refute Streamer.filtered_by_user?(user_a, activity) end end @@ -601,7 +611,8 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("user", user1, user1_token) {:ok, announce_activity} = CommonAPI.repeat(create_activity.id, user2) - assert_receive {:render_with_user, _, _, ^announce_activity} + stream_name = "user:#{user1.id}" + assert_receive {:render_with_user, _, _, ^announce_activity, ^stream_name} assert Streamer.filtered_by_user?(user1, announce_activity) end @@ -617,7 +628,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("user", user1, user1_token) {:ok, _announce_activity} = CommonAPI.repeat(create_activity.id, user2) - assert_receive {:render_with_user, _, "notification.json", notif} + assert_receive {:render_with_user, _, "notification.json", notif, "user"} assert Streamer.filtered_by_user?(user1, notif) end @@ -633,7 +644,7 @@ defmodule Pleroma.Web.StreamerTest do Streamer.get_topic_and_add_socket("user", user1, user1_token) {:ok, _favorite_activity} = CommonAPI.favorite(user2, create_activity.id) - assert_receive {:render_with_user, _, "notification.json", notif} + assert_receive {:render_with_user, _, "notification.json", notif, "user"} refute Streamer.filtered_by_user?(user1, notif) end end @@ -648,7 +659,8 @@ defmodule Pleroma.Web.StreamerTest do {:ok, activity} = CommonAPI.post(user, %{status: "super hot take"}) {:ok, _} = CommonAPI.add_mute(user2, activity) - assert_receive {:render_with_user, _, _, ^activity} + stream_name = "user:#{user2.id}" + assert_receive {:render_with_user, _, _, ^activity, ^stream_name} assert Streamer.filtered_by_user?(user2, activity) end end @@ -690,7 +702,8 @@ defmodule Pleroma.Web.StreamerTest do }) create_activity_id = create_activity.id - assert_receive {:render_with_user, _, _, ^create_activity} + stream_name = "direct:#{user.id}" + assert_receive {:render_with_user, _, _, ^create_activity, ^stream_name} assert_receive {:text, received_conversation1} assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1) @@ -725,8 +738,9 @@ defmodule Pleroma.Web.StreamerTest do visibility: "direct" }) - assert_receive {:render_with_user, _, _, ^create_activity} - assert_receive {:render_with_user, _, _, ^create_activity2} + stream_name = "direct:#{user.id}" + assert_receive {:render_with_user, _, _, ^create_activity, ^stream_name} + assert_receive {:render_with_user, _, _, ^create_activity2, ^stream_name} assert_receive {:text, received_conversation1} assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1) assert_receive {:text, received_conversation1} -- 2.50.1 From 03af49798d1c52c0afdf133d2dd309e04443e182 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 16 Aug 2022 13:10:41 +0100 Subject: [PATCH 3/8] add instance name to meta --- lib/pleroma/web/views/masto_fe_view.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pleroma/web/views/masto_fe_view.ex b/lib/pleroma/web/views/masto_fe_view.ex index 35ee3d630..305368c9d 100644 --- a/lib/pleroma/web/views/masto_fe_view.ex +++ b/lib/pleroma/web/views/masto_fe_view.ex @@ -14,6 +14,7 @@ defmodule Pleroma.Web.MastoFEView do %{ meta: %{ + title: Config.get([:instance, :name]), streaming_api_base_url: Pleroma.Web.Endpoint.websocket_url(), access_token: token, locale: "en", -- 2.50.1 From 41a3d7cb8e07b2819ca47d3d581b900117e9db13 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 16 Aug 2022 16:41:22 +0100 Subject: [PATCH 4/8] add reaction IDs in model --- .../web/mastodon_api/controllers/notification_controller.ex | 1 - lib/pleroma/web/mastodon_api/views/status_view.ex | 3 ++- lib/pleroma/web/mastodon_api/websocket_handler.ex | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex index ae4432e85..e02519bd4 100644 --- a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex @@ -56,7 +56,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do params = Map.new(params, fn {k, v} -> {to_string(k), v} end) |> Map.put_new("include_types", @default_notification_types) - notifications = MastodonAPI.get_notifications(user, params) conn diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index cd3c04598..d099c4901 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -590,7 +590,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do name: emoji, count: length(users), url: MediaProxy.url(url), - me: !!(current_user && current_user.ap_id in users) + me: !!(current_user && current_user.ap_id in users), + account_ids: Enum.map(users, fn user -> User.get_cached_by_ap_id(user).id end) } end diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex index b8fe3ad78..582e65d70 100644 --- a/lib/pleroma/web/mastodon_api/websocket_handler.ex +++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex @@ -72,7 +72,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do # We only receive pings for now def websocket_handle(:ping, state), do: {:ok, state} - def websocket_handle({:text, "ping"}, state) do + def websocket_handle({:text, ping}, state) when ping in ~w[ping PING] do if state.timer, do: Process.cancel_timer(state.timer) {:reply, {:text, "pong"}, %{state | timer: timer()}} end -- 2.50.1 From e2b1f269997e470588778b21d05a2f2ff3541f02 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 16 Aug 2022 16:56:38 +0100 Subject: [PATCH 5/8] fix tests --- .../controllers/notification_controller.ex | 1 + .../mastodon_api/views/status_view_test.exs | 30 ++++++++++++------- .../emoji_reaction_controller_test.exs | 11 +++++-- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex index e02519bd4..ae4432e85 100644 --- a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex @@ -56,6 +56,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do params = Map.new(params, fn {k, v} -> {to_string(k), v} end) |> Map.put_new("include_types", @default_notification_types) + notifications = MastodonAPI.get_notifications(user, params) conn diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs index 4987093d0..a6f8f3fc8 100644 --- a/test/pleroma/web/mastodon_api/views/status_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs @@ -44,14 +44,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) assert status[:pleroma][:emoji_reactions] == [ - %{name: "☕", count: 2, me: false, url: nil}, + %{name: "☕", count: 2, me: false, url: nil, account_ids: [other_user.id, user.id]}, %{ count: 2, me: false, name: "dinosaur", - url: "http://localhost:4001/emoji/dino walking.gif" + url: "http://localhost:4001/emoji/dino walking.gif", + account_ids: [other_user.id, user.id] }, - %{name: "🍵", count: 1, me: false, url: nil} + %{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]} ] status = StatusView.render("show.json", activity: activity, for: user) @@ -59,14 +60,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) assert status[:pleroma][:emoji_reactions] == [ - %{name: "☕", count: 2, me: true, url: nil}, + %{name: "☕", count: 2, me: true, url: nil, account_ids: [other_user.id, user.id]}, %{ count: 2, me: true, name: "dinosaur", - url: "http://localhost:4001/emoji/dino walking.gif" + url: "http://localhost:4001/emoji/dino walking.gif", + account_ids: [other_user.id, user.id] }, - %{name: "🍵", count: 1, me: false, url: nil} + %{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]} ] end @@ -82,7 +84,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do status = StatusView.render("show.json", activity: activity, for: user) assert status[:pleroma][:emoji_reactions] == [ - %{name: "☕", count: 1, me: true, url: nil} + %{name: "☕", count: 1, me: true, url: nil, account_ids: [user.id]} ] end @@ -102,7 +104,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do status = StatusView.render("show.json", activity: activity) assert status[:pleroma][:emoji_reactions] == [ - %{name: "☕", count: 1, me: false, url: nil} + %{name: "☕", count: 1, me: false, url: nil, account_ids: [other_user.id]} ] status = StatusView.render("show.json", activity: activity, for: user) @@ -114,19 +116,25 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do status = StatusView.render("show.json", activity: activity) assert status[:pleroma][:emoji_reactions] == [ - %{name: "☕", count: 2, me: false, url: nil} + %{ + name: "☕", + count: 2, + me: false, + url: nil, + account_ids: [third_user.id, other_user.id] + } ] status = StatusView.render("show.json", activity: activity, for: user) assert status[:pleroma][:emoji_reactions] == [ - %{name: "☕", count: 1, me: false, url: nil} + %{name: "☕", count: 1, me: false, url: nil, account_ids: [third_user.id]} ] status = StatusView.render("show.json", activity: activity, for: other_user) assert status[:pleroma][:emoji_reactions] == [ - %{name: "☕", count: 1, me: true, url: nil} + %{name: "☕", count: 1, me: true, url: nil, account_ids: [other_user.id]} ] end diff --git a/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs index 65bb22e27..4898179e6 100644 --- a/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs +++ b/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs @@ -31,7 +31,13 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do assert to_string(activity.id) == id assert result["pleroma"]["emoji_reactions"] == [ - %{"name" => "☕", "count" => 1, "me" => true, "url" => nil} + %{ + "name" => "☕", + "count" => 1, + "me" => true, + "url" => nil, + "account_ids" => [other_user.id] + } ] {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"}) @@ -54,7 +60,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do "name" => "dinosaur", "count" => 1, "me" => true, - "url" => "http://localhost:4001/emoji/dino walking.gif" + "url" => "http://localhost:4001/emoji/dino walking.gif", + "account_ids" => [other_user.id] } ] -- 2.50.1 From 0487500390f1ea05777c43c84577ee5445bb6761 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 16 Aug 2022 23:24:09 +0100 Subject: [PATCH 6/8] add mastofe docs --- docs/docs/configuration/frontend_management.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/docs/configuration/frontend_management.md b/docs/docs/configuration/frontend_management.md index a25120589..5e4b9b051 100644 --- a/docs/docs/configuration/frontend_management.md +++ b/docs/docs/configuration/frontend_management.md @@ -19,6 +19,10 @@ config :pleroma, :frontends, admin: %{ "name" => "admin-fe", "ref" => "stable" + }, + mastodon: %{ + "name" => "mastodon-fe", + "ref" => "akkoma" } ``` @@ -26,12 +30,18 @@ This would serve the frontend from the the folder at `$instance_static/frontends Refer to [the frontend CLI task](../../administration/CLI_tasks/frontend) for how to install the frontend's files -If you wish masto-fe to also be enabled, you will also need to run the install task for `mastodon-fe`. Not doing this will lead to the frontend not working. - If you choose not to install a frontend for whatever reason, it is recommended that you enable [`:static_fe`](#static_fe) to allow remote users to click "view remote source". Don't bother with this if you've got no unauthenticated access though. You can also replace the default "no frontend" page by placing an `index.html` file under your `instance/static/` directory. +## Mastodon-FE + +Akkoma supports both [glitchsoc](https://github.com/glitch-soc/mastodon)'s more "vanilla" mastodon frontend, +as well as [fedibird](https://github.com/fedibird/mastodon)'s extended frontend which has near-feature-parity with akkoma (with quoting and reactions). + +To enable either one, you must run the `frontend.install` task for either `mastodon-fe` or `fedibird-fe` (both `--ref akkoma`), then make sure +`:pleroma, :frontends, :mastodon` references the one you want. + ## Swagger (openAPI) documentation viewer If you're a developer and you'd like a human-readable rendering of the -- 2.50.1 From 729d830ef72c7e9b16fe80eaa9c930047318ee69 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 16 Aug 2022 23:26:28 +0100 Subject: [PATCH 7/8] add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c7cd8601..6124c9b02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Added +- support for fedibird-fe, and API parity for it to function + ### Removed - Non-finch HTTP adapters. `:tesla, :adapter` is now highly recommended to be set to the default. -- 2.50.1 From 3171285985cea8dcf489a14b6c011f269d1bb464 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Wed, 17 Aug 2022 01:22:39 +0100 Subject: [PATCH 8/8] add test for frontends --- test/pleroma/web/masto_fe_controller_test.exs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 test/pleroma/web/masto_fe_controller_test.exs diff --git a/test/pleroma/web/masto_fe_controller_test.exs b/test/pleroma/web/masto_fe_controller_test.exs new file mode 100644 index 000000000..924b45352 --- /dev/null +++ b/test/pleroma/web/masto_fe_controller_test.exs @@ -0,0 +1,38 @@ +defmodule Pleroma.Web.MastoFEControllerTest do + use Pleroma.Web.ConnCase, async: true + alias Pleroma.Web.MastodonAPI.AuthController + + describe "index/2 (main page)" do + test "GET /web/ (glitch-soc)" do + clear_config([:frontends, :mastodon], %{"name" => "mastodon-fe"}) + + {:ok, masto_app} = AuthController.local_mastofe_app() + user = Pleroma.Factory.insert(:user) + token = Pleroma.Factory.insert(:oauth_token, app: masto_app, user: user) + %{conn: conn} = oauth_access(["read", "write"], oauth_token: token, user: user) + + resp = + conn + |> get("/web/getting-started") + |> html_response(200) + + assert resp =~ "glitch" + end + + test "GET /web/ (fedibird)" do + clear_config([:frontends, :mastodon], %{"name" => "fedibird-fe"}) + + {:ok, masto_app} = AuthController.local_mastofe_app() + user = Pleroma.Factory.insert(:user) + token = Pleroma.Factory.insert(:oauth_token, app: masto_app, user: user) + %{conn: conn} = oauth_access(["read", "write"], oauth_token: token, user: user) + + resp = + conn + |> get("/web/getting-started") + |> html_response(200) + + refute resp =~ "glitch" + end + end +end -- 2.50.1