Insert local links for remote actors in FE

This commit is contained in:
Shadowfacts 2020-05-24 22:50:40 -04:00
parent cf115c3f7c
commit dcd2cb04c9
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
4 changed files with 59 additions and 2 deletions

View File

@ -157,6 +157,10 @@ ul.notifications-list {
a { a {
text-decoration: underline; text-decoration: underline;
&.local-actor-link {
text-decoration: none;
}
} }
} }
} }

View File

@ -31,7 +31,7 @@
</p> </p>
</div> </div>
<div class="status-content"> <div class="status-content">
<%= raw(@original_note["content"]) %> <%= render_status_content(@original_activity) %>
</div> </div>
<div class="status-actions"> <div class="status-actions">
<a href="<%= Routes.frontend_path(@conn, :reply, @original_activity.id) %>">Reply</a> <a href="<%= Routes.frontend_path(@conn, :reply, @original_activity.id) %>">Reply</a>

View File

@ -16,7 +16,11 @@
</p> </p>
</div> </div>
<div class="status-content e-content"> <div class="status-content e-content">
<%= raw(@note["content"]) %> <%= unless is_nil(@conn.assigns[:user]) do %>
<%= render_status_content(@status) %>
<% else %>
<%= raw(@note["content"]) %>
<% end %>
</div> </div>
<%= unless is_nil(@conn.assigns[:user]) do %> <%= unless is_nil(@conn.assigns[:user]) do %>
<div class="status-actions"> <div class="status-actions">

View File

@ -3,6 +3,7 @@ defmodule ClacksWeb.FrontendView do
alias Clacks.{Actor, Activity, Repo, Notification} alias Clacks.{Actor, Activity, Repo, Notification}
alias ClacksWeb.Router.Helpers, as: Routes alias ClacksWeb.Router.Helpers, as: Routes
alias ClacksWeb.Endpoint alias ClacksWeb.Endpoint
require Logger
@spec display_username(actor :: Actor.t()) :: String.t() @spec display_username(actor :: Actor.t()) :: String.t()
@ -126,4 +127,52 @@ defmodule ClacksWeb.FrontendView do
end end
defp mentions_for_replying_to(_), do: "" defp mentions_for_replying_to(_), do: ""
@spec render_status_content(activity :: Activity.t()) :: String.t()
defp render_status_content(%Activity{
data: %{
"type" => "Create",
"object" => %{"type" => "Note", "content" => content} = note
}
}) do
with %{"tag" => tags} <- note,
{:ok, tree} <- Floki.parse_fragment(content) do
tree
|> Floki.traverse_and_update(fn
{"a", attrs, _children} = orig_tree ->
{"href", href} = Enum.find(attrs, fn {name, _} -> name == "href" end)
has_matching_tag =
Enum.any?(tags, fn
%{"type" => "Mention", "href" => ^href} -> true
_ -> false
end)
with true <- has_matching_tag,
%Actor{local: false} = actor <- Actor.get_cached_by_ap_id(href) do
{
"span",
[],
[
orig_tree,
{"a", [{"href", local_actor_link(actor)}, {"class", "local-actor-link"}], ["🔗"]}
]
}
else
_ ->
orig_tree
end
tree ->
tree
end)
|> Floki.raw_html()
# remove the <html> and </html> from the floki rendered output
|> String.slice(6..-8)
|> raw()
else
_ ->
content
end
end
end end