ensure all users are linked in MFM content
This commit is contained in:
parent
5ad256f170
commit
19738c6144
4 changed files with 67 additions and 28 deletions
|
@ -32,26 +32,29 @@ def escape_mention_handler("@" <> nickname = mention, buffer, _, _) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mention_tag(%User{id: id} = user, nickname, opts \\ []) do
|
||||||
|
user_url = user.uri || user.ap_id
|
||||||
|
nickname_text = get_nickname_text(nickname, opts)
|
||||||
|
|
||||||
|
:span
|
||||||
|
|> Phoenix.HTML.Tag.content_tag(
|
||||||
|
Phoenix.HTML.Tag.content_tag(
|
||||||
|
:a,
|
||||||
|
["@", Phoenix.HTML.Tag.content_tag(:span, nickname_text)],
|
||||||
|
"data-user": id,
|
||||||
|
class: "u-url mention",
|
||||||
|
href: user_url,
|
||||||
|
rel: "ugc"
|
||||||
|
),
|
||||||
|
class: "h-card"
|
||||||
|
)
|
||||||
|
|> Phoenix.HTML.safe_to_string()
|
||||||
|
end
|
||||||
|
|
||||||
def mention_handler("@" <> nickname, buffer, opts, acc) do
|
def mention_handler("@" <> nickname, buffer, opts, acc) do
|
||||||
case User.get_cached_by_nickname(nickname) do
|
case User.get_cached_by_nickname(nickname) do
|
||||||
%User{id: id} = user ->
|
%User{id: _id} = user ->
|
||||||
user_url = user.uri || user.ap_id
|
link = mention_tag(user, nickname, opts)
|
||||||
nickname_text = get_nickname_text(nickname, opts)
|
|
||||||
|
|
||||||
link =
|
|
||||||
Phoenix.HTML.Tag.content_tag(
|
|
||||||
:span,
|
|
||||||
Phoenix.HTML.Tag.content_tag(
|
|
||||||
:a,
|
|
||||||
["@", Phoenix.HTML.Tag.content_tag(:span, nickname_text)],
|
|
||||||
"data-user": id,
|
|
||||||
class: "u-url mention",
|
|
||||||
href: user_url,
|
|
||||||
rel: "ugc"
|
|
||||||
),
|
|
||||||
class: "h-card"
|
|
||||||
)
|
|
||||||
|> Phoenix.HTML.safe_to_string()
|
|
||||||
|
|
||||||
{link, %{acc | mentions: MapSet.put(acc.mentions, {"@" <> nickname, user})}}
|
{link, %{acc | mentions: MapSet.put(acc.mentions, {"@" <> nickname, user})}}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
|
defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||||
alias Pleroma.Object.Fetcher
|
alias Pleroma.Object.Fetcher
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
|
@ -81,11 +81,29 @@ defp fix_replies(%{"replies" => %{"first" => first}} = data) do
|
||||||
|
|
||||||
defp fix_replies(data), do: data
|
defp fix_replies(data), do: data
|
||||||
|
|
||||||
|
defp remote_mention_resolver(%{"tag" => tags}, "@" <> nickname = mention, buffer, opts, acc) do
|
||||||
|
with mention_tag <-
|
||||||
|
Enum.find(tags, fn t -> t["type"] == "Mention" && t["name"] == mention end),
|
||||||
|
false <- is_nil(mention_tag),
|
||||||
|
{:ok, %User{} = user} <- User.get_or_fetch_by_ap_id(mention_tag["href"]) do
|
||||||
|
link = Pleroma.Formatter.mention_tag(user, nickname, opts)
|
||||||
|
{link, %{acc | mentions: MapSet.put(acc.mentions, {"@" <> nickname, user})}}
|
||||||
|
else
|
||||||
|
_ -> {buffer, acc}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# https://github.com/misskey-dev/misskey/pull/8787
|
# https://github.com/misskey-dev/misskey/pull/8787
|
||||||
defp fix_misskey_content(
|
defp fix_misskey_content(
|
||||||
%{"source" => %{"mediaType" => "text/x.misskeymarkdown", "content" => content}} = object
|
%{"source" => %{"mediaType" => "text/x.misskeymarkdown", "content" => content}} = object
|
||||||
) do
|
) do
|
||||||
{linked, _, _} = Utils.format_input(content, "text/x.misskeymarkdown")
|
mention_handler = fn nick, buffer, opts, acc ->
|
||||||
|
remote_mention_resolver(object, nick, buffer, opts, acc)
|
||||||
|
end
|
||||||
|
|
||||||
|
{linked, _, _} =
|
||||||
|
Utils.format_input(content, "text/x.misskeymarkdown", mention_handler: mention_handler)
|
||||||
|
|
||||||
Map.put(object, "content", linked)
|
Map.put(object, "content", linked)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
9
test/fixtures/misskey/mfm_x_format.json
vendored
9
test/fixtures/misskey/mfm_x_format.json
vendored
|
@ -3,9 +3,9 @@
|
||||||
"type": "Note",
|
"type": "Note",
|
||||||
"attributedTo": "https://misskey.local.live/users/92hzkskwgy",
|
"attributedTo": "https://misskey.local.live/users/92hzkskwgy",
|
||||||
"summary": null,
|
"summary": null,
|
||||||
"content": "<p><a href=\"https://akkoma.local.live/users/akkoma_user\" class=\"u-url mention\">@akkoma_user@akkoma.local.live</a><span> linkifylink </span><a href=\"https://misskey.local.live/tags/dancedance\" rel=\"tag\">#dancedance</a><span> </span><i><span> mfm goes here</span></i><span> <br><br>## aaa</span></p>",
|
"content": "this gets replaced",
|
||||||
"source": {
|
"source": {
|
||||||
"content": "@akkoma_user linkifylink #dancedance $[jelly mfm goes here] \n\n## aaa",
|
"content": "@akkoma_user @remote_user linkifylink #dancedance $[jelly mfm goes here] \n\n## aaa",
|
||||||
"mediaType": "text/x.misskeymarkdown"
|
"mediaType": "text/x.misskeymarkdown"
|
||||||
},
|
},
|
||||||
"published": "2022-07-10T15:37:36.368Z",
|
"published": "2022-07-10T15:37:36.368Z",
|
||||||
|
@ -29,6 +29,11 @@
|
||||||
"type": "Mention",
|
"type": "Mention",
|
||||||
"href": "http://localhost:4001/users/akkoma_user",
|
"href": "http://localhost:4001/users/akkoma_user",
|
||||||
"name": "@akkoma_user"
|
"name": "@akkoma_user"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Mention",
|
||||||
|
"href": "http://misskey.local.live/users/remote_user",
|
||||||
|
"name": "@remote_user"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,14 @@ test "a note with an attachment should work", _ do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "a misskey MFM status with a content field should work and be linked", _ do
|
test "a misskey MFM status with a content field should work and be linked", _ do
|
||||||
local_user = insert(:user, %{nickname: "akkoma_user"})
|
local_user =
|
||||||
|
insert(:user, %{nickname: "akkoma_user", ap_id: "http://localhost:4001/users/akkoma_user"})
|
||||||
|
|
||||||
|
remote_user =
|
||||||
|
insert(:user, %{
|
||||||
|
nickname: "remote_user",
|
||||||
|
ap_id: "http://misskey.local.live/users/remote_user"
|
||||||
|
})
|
||||||
|
|
||||||
insert(:user, %{ap_id: "https://misskey.local.live/users/92hzkskwgy"})
|
insert(:user, %{ap_id: "https://misskey.local.live/users/92hzkskwgy"})
|
||||||
|
|
||||||
|
@ -80,19 +87,25 @@ test "a misskey MFM status with a content field should work and be linked", _ do
|
||||||
|> File.read!()
|
|> File.read!()
|
||||||
|> Jason.decode!()
|
|> Jason.decode!()
|
||||||
|
|
||||||
expected_content =
|
|
||||||
"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{local_user.id}\" href=\"#{local_user.ap_id}\" rel=\"ugc\">@<span>akkoma_user</span></a></span> linkifylink <a class=\"hashtag\" data-tag=\"dancedance\" href=\"http://localhost:4001/tag/dancedance\" rel=\"tag ugc\">#dancedance</a> $[jelly mfm goes here] <br><br>## aaa"
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
valid?: true,
|
valid?: true,
|
||||||
changes: %{
|
changes: %{
|
||||||
content: ^expected_content,
|
content: content,
|
||||||
source: %{
|
source: %{
|
||||||
"content" => "@akkoma_user linkifylink #dancedance $[jelly mfm goes here] \n\n## aaa",
|
"content" =>
|
||||||
|
"@akkoma_user @remote_user linkifylink #dancedance $[jelly mfm goes here] \n\n## aaa",
|
||||||
"mediaType" => "text/x.misskeymarkdown"
|
"mediaType" => "text/x.misskeymarkdown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} = ArticleNotePageValidator.cast_and_validate(note)
|
} = ArticleNotePageValidator.cast_and_validate(note)
|
||||||
|
|
||||||
|
assert content =~
|
||||||
|
"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{local_user.id}\" href=\"#{local_user.ap_id}\" rel=\"ugc\">@<span>akkoma_user</span></a></span>"
|
||||||
|
|
||||||
|
assert content =~
|
||||||
|
"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{remote_user.id}\" href=\"#{remote_user.ap_id}\" rel=\"ugc\">@<span>remote_user</span></a></span>"
|
||||||
|
|
||||||
|
assert content =~ "$[jelly mfm goes here] <br><br>## aaa"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "a misskey MFM status with a _misskey_content field should work and be linked", _ do
|
test "a misskey MFM status with a _misskey_content field should work and be linked", _ do
|
||||||
|
|
Loading…
Reference in a new issue