Show announces in timelines

This commit is contained in:
Shadowfacts 2020-05-23 11:53:27 -04:00
parent a2ddde09f7
commit 47bb420c81
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
7 changed files with 68 additions and 11 deletions

View File

@ -116,6 +116,11 @@ ul.status-list {
border: 1px solid #ddd; border: 1px solid #ddd;
background-color: #f2f2f2; background-color: #f2f2f2;
.status-announcer {
margin-top: 0;
margin-bottom: 0.5rem;
}
.status-meta { .status-meta {
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View File

@ -11,7 +11,7 @@ defmodule Clacks.Timeline do
params :: map(), params :: map(),
only_public :: boolean() only_public :: boolean()
) :: [ ) :: [
Activity.t() {Activity.t(), Actor.t(), {Activity.t() | nil, Actor.t() | nil}}
] ]
def actor_timeline(actor, params, only_public \\ true) do def actor_timeline(actor, params, only_public \\ true) do
Activity Activity
@ -20,11 +20,16 @@ defmodule Clacks.Timeline do
|> restrict_to_public(only_public) |> restrict_to_public(only_public)
|> paginate(params) |> paginate(params)
|> limit(^Map.get(params, "limit", 20)) |> limit(^Map.get(params, "limit", 20))
|> join_with_announces()
|> select(
[activity, announced, announced_actor],
{activity, {announced, announced_actor}}
)
|> Repo.all() |> Repo.all()
end end
@spec home_timeline(user :: User.t(), params :: map()) :: [ @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 def home_timeline(user, params) do
user = user =
@ -46,10 +51,17 @@ defmodule Clacks.Timeline do
|> restrict_to_types(@timeline_types) |> restrict_to_types(@timeline_types)
|> paginate(params) |> paginate(params)
|> limit(^Map.get(params, "limit", 20)) |> limit(^Map.get(params, "limit", 20))
|> join_with_announces()
|> select(
[activity, actor, announced, announced_actor],
{activity, actor, {announced, announced_actor}}
)
|> Repo.all() |> Repo.all()
end 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 def local_timeline(params) do
Activity Activity
|> where([a], a.local) |> where([a], a.local)
@ -58,6 +70,11 @@ defmodule Clacks.Timeline do
|> paginate(params) |> paginate(params)
|> limit(^Map.get(params, "limit", 20)) |> limit(^Map.get(params, "limit", 20))
|> join_with_actors() |> join_with_actors()
|> join_with_announces()
|> select(
[activity, actor, announced, announced_actor],
{activity, actor, {announced, announced_actor}}
)
|> Repo.all() |> Repo.all()
end end
@ -82,6 +99,18 @@ defmodule Clacks.Timeline do
defp join_with_actors(query) do defp join_with_actors(query) do
query query
|> join(:left, [o], a in Actor, on: a.ap_id == fragment("?->>'actor'", o.data)) |> 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
end end

View File

@ -31,11 +31,15 @@ defmodule ClacksWeb.FrontendController do
defp index({:profile, nickname}, conn, params) do defp index({:profile, nickname}, conn, params) do
case Actor.get_by_nickname(nickname) do case Actor.get_by_nickname(nickname) do
%Actor{local: true} = actor ->
# only local profiles are shown # only local profiles are shown
%Actor{local: true} = actor ->
statuses_with_actor =
actor_statuses(actor, params, only_public: true)
|> Enum.map(fn {activity, announce} -> {activity, actor, announce} end)
render(conn, "profile.html", %{ render(conn, "profile.html", %{
actor: actor, 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 ->
user = Repo.preload(user, :actor) 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", %{ render(conn, "profile.html", %{
current_user: current_user, current_user: current_user,
actor: user.actor, 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) following_state: following_state(current_user.actor, user.actor)
}) })
end end
@ -144,10 +152,14 @@ defmodule ClacksWeb.FrontendController do
resp(conn, 404, "Not Found") resp(conn, 404, "Not Found")
actor -> actor ->
statuses_with_actor =
actor_statuses(actor, params, only_public: true)
|> Enum.map(fn {activity, announce} -> {activity, actor, announce} end)
render(conn, "profile.html", %{ render(conn, "profile.html", %{
current_user: current_user, current_user: current_user,
actor: actor, actor: actor,
statuses: actor_statuses(actor, params, only_public: true), statuses_with_actor: statuses_with_actor,
following_state: following_state(current_user.actor, actor) following_state: following_state(current_user.actor, actor)
}) })
end end

View File

@ -1,4 +1,9 @@
<div class="status h-entry"> <div class="status h-entry">
<%= if assigns[:announcer] do %>
<p class="status-announcer">
Announced by <a href="<%= local_actor_link(@announcer) %>"><%= @announcer.data["preferredUsername"] %></a>
</p>
<% end %>
<div class="status-meta"> <div class="status-meta">
<h2 class="status-author-nickname"> <h2 class="status-author-nickname">
<a href="<%= local_actor_link(@author) %>" class="p-author"> <a href="<%= local_actor_link(@author) %>" class="p-author">

View File

@ -6,9 +6,14 @@
<% end %> <% end %>
<ul class="status-list"> <ul class="status-list">
<%= for {status, author} <- @statuses_with_authors do %> <%= for {status, author, announced} <- @statuses_with_authors do %>
<li> <li>
<%= if status.data["type"] == "Announce" do %>
<% {announced_status, announced_actor} = announced %>
<%= render "_status.html", conn: @conn, announcer: author, status: announced_status, note: announced_status.data["object"], author: announced_actor %>
<% else %>
<%= render "_status.html", conn: @conn, author: author, status: status, note: status.data["object"] %> <%= render "_status.html", conn: @conn, author: author, status: status, note: status.data["object"] %>
<% end %>
</li> </li>
<% end %> <% end %>
</ul> </ul>

View File

@ -30,4 +30,4 @@
<% end %> <% end %>
</div> </div>
<%= render "_timeline.html", conn: @conn, statuses_with_authors: Enum.map(@statuses, &({&1, @actor})) %> <%= render "_timeline.html", conn: @conn, statuses_with_authors: @statuses_with_actor %>

View File

@ -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 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() @spec mentions_for_replying_to(Activity.t()) :: String.t()
defp mentions_for_replying_to(conn, %Activity{ defp mentions_for_replying_to(conn, %Activity{