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