diff options
author | 2025-01-31 02:40:39 -0800 | |
---|---|---|
committer | 2025-01-31 11:40:39 +0100 | |
commit | ab758cc2336e88d9cd967238310b433e75d500dc (patch) | |
tree | 4e30baebb21a4d06b31273e81f1317d1a6d0d939 | |
parent | [bugfix] fix boost of account ID check (#3709) (diff) | |
download | gotosocial-ab758cc2336e88d9cd967238310b433e75d500dc.tar.xz |
[feature] Add system message wrappers for pending replies and placeholder attachments (#3713)
Fixes #3712
-rw-r--r-- | internal/typeutils/internaltofrontend_test.go | 4 | ||||
-rw-r--r-- | internal/typeutils/util.go | 38 |
2 files changed, 32 insertions, 10 deletions
diff --git a/internal/typeutils/internaltofrontend_test.go b/internal/typeutils/internaltofrontend_test.go index df6edd553..27b6df139 100644 --- a/internal/typeutils/internaltofrontend_test.go +++ b/internal/typeutils/internaltofrontend_test.go @@ -1278,7 +1278,7 @@ func (suite *InternalToFrontendTestSuite) TestStatusToFrontendUnknownAttachments "muted": false, "bookmarked": false, "pinned": false, - "content": "\u003cp\u003ehi \u003cspan class=\"h-card\"\u003e\u003ca href=\"http://localhost:8080/@admin\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e@\u003cspan\u003eadmin\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e here's some media for ya\u003c/p\u003e\u003chr\u003e\u003cp\u003e\u003ci lang=\"en\"\u003eℹ️ Note from localhost:8080: 2 attachments in this status were not downloaded. Treat the following external links with care:\u003c/i\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"http://example.org/fileserver/01HE7Y659ZWZ02JM4AWYJZ176Q/attachment/original/01HE7ZGJYTSYMXF927GF9353KR.svg\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e01HE7ZGJYTSYMXF927GF9353KR.svg\u003c/a\u003e [SVG line art of a sloth, public domain]\u003c/li\u003e\u003cli\u003e\u003ca href=\"http://example.org/fileserver/01HE7Y659ZWZ02JM4AWYJZ176Q/attachment/original/01HE892Y8ZS68TQCNPX7J888P3.mp3\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e01HE892Y8ZS68TQCNPX7J888P3.mp3\u003c/a\u003e [Jolly salsa song, public domain.]\u003c/li\u003e\u003c/ul\u003e", + "content": "\u003cp\u003ehi \u003cspan class=\"h-card\"\u003e\u003ca href=\"http://localhost:8080/@admin\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e@\u003cspan\u003eadmin\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e here's some media for ya\u003c/p\u003e\u003cdiv class=\"gts-system-message gts-placeholder-attachments\"\u003e\u003chr\u003e\u003cp\u003e\u003ci lang=\"en\"\u003eℹ️ Note from localhost:8080: 2 attachments in this status were not downloaded. Treat the following external links with care:\u003c/i\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"http://example.org/fileserver/01HE7Y659ZWZ02JM4AWYJZ176Q/attachment/original/01HE7ZGJYTSYMXF927GF9353KR.svg\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e01HE7ZGJYTSYMXF927GF9353KR.svg\u003c/a\u003e [SVG line art of a sloth, public domain]\u003c/li\u003e\u003cli\u003e\u003ca href=\"http://example.org/fileserver/01HE7Y659ZWZ02JM4AWYJZ176Q/attachment/original/01HE892Y8ZS68TQCNPX7J888P3.mp3\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e01HE892Y8ZS68TQCNPX7J888P3.mp3\u003c/a\u003e [Jolly salsa song, public domain.]\u003c/li\u003e\u003c/ul\u003e\u003c/div\u003e", "reblog": null, "account": { "id": "01FHMQX3GAABWSM0S2VZEC2SWC", @@ -1828,7 +1828,7 @@ func (suite *InternalToFrontendTestSuite) TestStatusToAPIStatusPendingApproval() "muted": false, "bookmarked": false, "pinned": false, - "content": "<p>Hi <span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span>, can I reply?</p><hr><p><i lang=\"en\">ℹ️ Note from localhost:8080: This reply is pending your approval. You can quickly accept it by liking, boosting or replying to it. You can also accept or reject it at the following link: <a href=\"http://localhost:8080/settings/user/interaction_requests/01J5QVXCCEATJYSXM9H6MZT4JR\" rel=\"noreferrer noopener nofollow\" target=\"_blank\">http://localhost:8080/settings/user/interaction_requests/01J5QVXCCEATJYSXM9H6MZT4JR</a>.</i></p>", + "content": "<p>Hi <span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span>, can I reply?</p><div class=\"gts-system-message gts-pending-reply\"><hr><p><i lang=\"en\">ℹ️ Note from localhost:8080: This reply is pending your approval. You can quickly accept it by liking, boosting or replying to it. You can also accept or reject it at the following link: <a href=\"http://localhost:8080/settings/user/interaction_requests/01J5QVXCCEATJYSXM9H6MZT4JR\" rel=\"noreferrer noopener nofollow\" target=\"_blank\">http://localhost:8080/settings/user/interaction_requests/01J5QVXCCEATJYSXM9H6MZT4JR</a>.</i></p></div>", "reblog": null, "application": { "name": "superseriousbusiness", diff --git a/internal/typeutils/util.go b/internal/typeutils/util.go index 1747dbdcd..b4f2e41aa 100644 --- a/internal/typeutils/util.go +++ b/internal/typeutils/util.go @@ -128,12 +128,14 @@ func misskeyReportInlineURLs(content string) []*url.URL { // // Example: // -// <hr> -// <p><i lang="en">ℹ️ Note from your.instance.com: 2 attachment(s) in this status were not downloaded. Treat the following external link(s) with care:</i></p> -// <ul> -// <li><a href="http://example.org/fileserver/01HE7Y659ZWZ02JM4AWYJZ176Q/attachment/original/01HE7ZGJYTSYMXF927GF9353KR.svg" rel="nofollow noreferrer noopener" target="_blank">01HE7ZGJYTSYMXF927GF9353KR.svg</a> [SVG line art of a sloth, public domain]</li> -// <li><a href="http://example.org/fileserver/01HE7Y659ZWZ02JM4AWYJZ176Q/attachment/original/01HE892Y8ZS68TQCNPX7J888P3.mp3" rel="nofollow noreferrer noopener" target="_blank">01HE892Y8ZS68TQCNPX7J888P3.mp3</a> [Jolly salsa song, public domain.]</li> -// </ul> +// <div class="gts-system-message gts-placeholder-attachments"> +// <hr> +// <p><i lang="en">ℹ️ Note from your.instance.com: 2 attachment(s) in this status were not downloaded. Treat the following external link(s) with care:</i></p> +// <ul> +// <li><a href="http://example.org/fileserver/01HE7Y659ZWZ02JM4AWYJZ176Q/attachment/original/01HE7ZGJYTSYMXF927GF9353KR.svg" rel="nofollow noreferrer noopener" target="_blank">01HE7ZGJYTSYMXF927GF9353KR.svg</a> [SVG line art of a sloth, public domain]</li> +// <li><a href="http://example.org/fileserver/01HE7Y659ZWZ02JM4AWYJZ176Q/attachment/original/01HE892Y8ZS68TQCNPX7J888P3.mp3" rel="nofollow noreferrer noopener" target="_blank">01HE892Y8ZS68TQCNPX7J888P3.mp3</a> [Jolly salsa song, public domain.]</li> +// </ul> +// </div> func placeholderAttachments(arr []*apimodel.Attachment) (string, []*apimodel.Attachment) { // Extract non-locally stored attachments into a @@ -187,7 +189,7 @@ func placeholderAttachments(arr []*apimodel.Attachment) (string, []*apimodel.Att } note.WriteString(`</ul>`) - return text.SanitizeToHTML(note.String()), arr + return systemMessage("gts-placeholder-attachments", note.String()), arr } func (c *Converter) pendingReplyNote( @@ -228,7 +230,27 @@ func (c *Converter) pendingReplyNote( note.WriteString(`</a>.`) note.WriteString(`</i></p>`) - return text.SanitizeToHTML(note.String()), nil + return systemMessage("gts-pending-reply", note.String()), nil +} + +// systemMessage wraps a note with a div with semantic classes that aren't allowed through the sanitizer, +// but may be emitted to the client as an addition to the status's actual content. +// Clients may want to display these specially or suppress them in favor of their own UI. +// +// messageClass must be valid inside an HTML attribute and should be one or more classes starting with `gts-`. +func systemMessage( + messageClass string, + unsanitizedNoteHTML string, +) string { + var wrappedNote strings.Builder + + wrappedNote.WriteString(`<div class="gts-system-message `) + wrappedNote.WriteString(messageClass) + wrappedNote.WriteString(`">`) + wrappedNote.WriteString(text.SanitizeToHTML(unsanitizedNoteHTML)) + wrappedNote.WriteString(`</div>`) + + return wrappedNote.String() } // ContentToContentLanguage tries to |