From 47bb420c81bb34616cb3c3ad44b03eef222cde6e Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 23 May 2020 11:53:27 -0400 Subject: [PATCH] Show announces in timelines --- assets/css/clacks.scss | 5 +++ lib/clacks/timeline.ex | 37 +++++++++++++++++-- .../controllers/frontend_controller.ex | 20 ++++++++-- .../templates/frontend/_status.html.eex | 5 +++ .../templates/frontend/_timeline.html.eex | 9 ++++- .../templates/frontend/profile.html.eex | 2 +- lib/clacks_web/views/frontend_view.ex | 1 + 7 files changed, 68 insertions(+), 11 deletions(-) diff --git a/assets/css/clacks.scss b/assets/css/clacks.scss index 3b71145..92a630b 100644 --- a/assets/css/clacks.scss +++ b/assets/css/clacks.scss @@ -116,6 +116,11 @@ ul.status-list { border: 1px solid #ddd; background-color: #f2f2f2; + .status-announcer { + margin-top: 0; + margin-bottom: 0.5rem; + } + .status-meta { display: flex; flex-direction: row; diff --git a/lib/clacks/timeline.ex b/lib/clacks/timeline.ex index 84575e6..2bf3236 100644 --- a/lib/clacks/timeline.ex +++ b/lib/clacks/timeline.ex @@ -11,7 +11,7 @@ defmodule Clacks.Timeline do params :: map(), only_public :: boolean() ) :: [ - Activity.t() + {Activity.t(), Actor.t(), {Activity.t() | nil, Actor.t() | nil}} ] def actor_timeline(actor, params, only_public \\ true) do Activity @@ -20,11 +20,16 @@ defmodule Clacks.Timeline do |> restrict_to_public(only_public) |> paginate(params) |> limit(^Map.get(params, "limit", 20)) + |> join_with_announces() + |> select( + [activity, announced, announced_actor], + {activity, {announced, announced_actor}} + ) |> Repo.all() end @spec home_timeline(user :: User.t(), params :: map()) :: [ - {Activity.t(), Actor.t()} + {Activity.t(), Actor.t(), {Activity.t() | nil, Actor.t() | nil}} ] def home_timeline(user, params) do user = @@ -46,10 +51,17 @@ defmodule Clacks.Timeline do |> restrict_to_types(@timeline_types) |> paginate(params) |> limit(^Map.get(params, "limit", 20)) + |> join_with_announces() + |> select( + [activity, actor, announced, announced_actor], + {activity, actor, {announced, announced_actor}} + ) |> Repo.all() end - @spec local_timeline(params :: map()) :: [{Activity.t(), Actor.t()}] + @spec local_timeline(params :: map()) :: [ + {Activity.t(), Actor.t(), {Activity.t() | nil, Actor.t() | nil}} + ] def local_timeline(params) do Activity |> where([a], a.local) @@ -58,6 +70,11 @@ defmodule Clacks.Timeline do |> paginate(params) |> limit(^Map.get(params, "limit", 20)) |> join_with_actors() + |> join_with_announces() + |> select( + [activity, actor, announced, announced_actor], + {activity, actor, {announced, announced_actor}} + ) |> Repo.all() end @@ -82,6 +99,18 @@ defmodule Clacks.Timeline do defp join_with_actors(query) do query |> join(:left, [o], a in Actor, on: a.ap_id == fragment("?->>'actor'", o.data)) - |> select([o, a], {o, a}) + end + + defp join_with_announces(query) do + query + |> join(:left, [a], other in Activity, + on: + fragment("?->>'type'", a.data) == "Announce" and + fragment("?->>'type'", other.data) == "Create" and + fragment("?->>'object'", a.data) == fragment("?->'object'->>'id'", other.data) + ) + |> join(:left, [a, ..., announced], actor in Actor, + on: actor.ap_id == fragment("?->>'actor'", announced.data) + ) end end diff --git a/lib/clacks_web/controllers/frontend_controller.ex b/lib/clacks_web/controllers/frontend_controller.ex index 6e2887c..30cbdb6 100644 --- a/lib/clacks_web/controllers/frontend_controller.ex +++ b/lib/clacks_web/controllers/frontend_controller.ex @@ -31,11 +31,15 @@ defmodule ClacksWeb.FrontendController do defp index({:profile, nickname}, conn, params) do case Actor.get_by_nickname(nickname) do + # only local profiles are shown %Actor{local: true} = actor -> - # only local profiles are shown + statuses_with_actor = + actor_statuses(actor, params, only_public: true) + |> Enum.map(fn {activity, announce} -> {activity, actor, announce} end) + render(conn, "profile.html", %{ actor: actor, - statuses: actor_statuses(actor, params, only_public: true) + statuses_with_actor: statuses_with_actor }) _ -> @@ -127,10 +131,14 @@ defmodule ClacksWeb.FrontendController do user -> user = Repo.preload(user, :actor) + statuses_with_actor = + actor_statuses(user.actor, params, only_public: true) + |> Enum.map(fn {activity, announce} -> {activity, user.actor, announce} end) + render(conn, "profile.html", %{ current_user: current_user, actor: user.actor, - statuses: actor_statuses(user.actor, params, only_public: true), + statuses_with_actor: statuses_with_actor, following_state: following_state(current_user.actor, user.actor) }) end @@ -144,10 +152,14 @@ defmodule ClacksWeb.FrontendController do resp(conn, 404, "Not Found") actor -> + statuses_with_actor = + actor_statuses(actor, params, only_public: true) + |> Enum.map(fn {activity, announce} -> {activity, actor, announce} end) + render(conn, "profile.html", %{ current_user: current_user, actor: actor, - statuses: actor_statuses(actor, params, only_public: true), + statuses_with_actor: statuses_with_actor, following_state: following_state(current_user.actor, actor) }) end diff --git a/lib/clacks_web/templates/frontend/_status.html.eex b/lib/clacks_web/templates/frontend/_status.html.eex index f1284dc..a90cb65 100644 --- a/lib/clacks_web/templates/frontend/_status.html.eex +++ b/lib/clacks_web/templates/frontend/_status.html.eex @@ -1,4 +1,9 @@
+ <%= if assigns[:announcer] do %> +

+ Announced by <%= @announcer.data["preferredUsername"] %> +

+ <% end %> -<%= render "_timeline.html", conn: @conn, statuses_with_authors: Enum.map(@statuses, &({&1, @actor})) %> +<%= render "_timeline.html", conn: @conn, statuses_with_authors: @statuses_with_actor %> diff --git a/lib/clacks_web/views/frontend_view.ex b/lib/clacks_web/views/frontend_view.ex index 0a846dc..20a7bbe 100644 --- a/lib/clacks_web/views/frontend_view.ex +++ b/lib/clacks_web/views/frontend_view.ex @@ -88,6 +88,7 @@ defmodule ClacksWeb.FrontendView do defp activity_id(%Activity{id: id}), do: id defp activity_id({%Activity{id: id}, _}), do: id + defp activity_id({%Activity{id: id}, _, _}), do: id @spec mentions_for_replying_to(Activity.t()) :: String.t() defp mentions_for_replying_to(conn, %Activity{