diff --git a/assets/css/clacks.scss b/assets/css/clacks.scss index ca59608..34095b8 100644 --- a/assets/css/clacks.scss +++ b/assets/css/clacks.scss @@ -157,6 +157,10 @@ ul.notifications-list { a { text-decoration: underline; + + &.local-actor-link { + text-decoration: none; + } } } } diff --git a/lib/clacks_web/templates/frontend/_action_status.html.eex b/lib/clacks_web/templates/frontend/_action_status.html.eex index 4c79cc5..a6dc4f4 100644 --- a/lib/clacks_web/templates/frontend/_action_status.html.eex +++ b/lib/clacks_web/templates/frontend/_action_status.html.eex @@ -31,7 +31,11 @@

- <%= raw(@original_note["content"]) %> + <%= unless is_nil(@conn.assigns[:user]) do %> + <%= render_status_content(@original_activity) %> + <% else %> + <%= raw(@original_note["content"]) %> + <% end %>
Reply diff --git a/lib/clacks_web/templates/frontend/_status.html.eex b/lib/clacks_web/templates/frontend/_status.html.eex index 53467ac..da8a049 100644 --- a/lib/clacks_web/templates/frontend/_status.html.eex +++ b/lib/clacks_web/templates/frontend/_status.html.eex @@ -16,7 +16,11 @@

- <%= raw(@note["content"]) %> + <%= unless is_nil(@conn.assigns[:user]) do %> + <%= render_status_content(@status) %> + <% else %> + <%= raw(@note["content"]) %> + <% end %>
<%= unless is_nil(@conn.assigns[:user]) do %>
diff --git a/lib/clacks_web/views/frontend_view.ex b/lib/clacks_web/views/frontend_view.ex index 34a7179..220878d 100644 --- a/lib/clacks_web/views/frontend_view.ex +++ b/lib/clacks_web/views/frontend_view.ex @@ -3,6 +3,7 @@ defmodule ClacksWeb.FrontendView do alias Clacks.{Actor, Activity, Repo, Notification} alias ClacksWeb.Router.Helpers, as: Routes alias ClacksWeb.Endpoint + require Logger @spec display_username(actor :: Actor.t()) :: String.t() @@ -126,4 +127,52 @@ defmodule ClacksWeb.FrontendView do end 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 and from the floki rendered output + |> String.slice(6..-8) + |> raw() + else + _ -> + content + end + end end