diff options
author | Zach Lipton <zach@zachlipton.com> | 2024-01-23 13:04:22 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-23 13:04:22 -0800 |
commit | c58e65000d36cec3af46e6c07372260767b23481 (patch) | |
tree | fe6ac0a0383b9ec881b3866d060cab8717bd7c77 | |
parent | cdbdb37aac3d395dc5ccafb0bc1e901deacc8e0a (diff) | |
download | voidsky-c58e65000d36cec3af46e6c07372260767b23481.tar.zst |
Include expanded urls in social cards (#2427)
* include expanded urls in social cards (#2427) * break expandPostLinks into its own function, add bounds checking
-rw-r--r-- | bskyweb/cmd/bskyweb/server.go | 46 | ||||
-rw-r--r-- | bskyweb/templates/post.html | 8 |
2 files changed, 50 insertions, 4 deletions
diff --git a/bskyweb/cmd/bskyweb/server.go b/bskyweb/cmd/bskyweb/server.go index e391b8b03..7571e536e 100644 --- a/bskyweb/cmd/bskyweb/server.go +++ b/bskyweb/cmd/bskyweb/server.go @@ -10,6 +10,7 @@ import ( "net/http" "os" "os/signal" + "slices" "strings" "syscall" "time" @@ -351,9 +352,54 @@ func (srv *Server) WebPost(c echo.Context) error { data["imgThumbUrls"] = thumbUrls } } + + data["postText"] = expandPostLinks(postView) + return c.Render(http.StatusOK, "post.html", data) } +// function to expand shortened links in rich text back to full urls, replacing shortened urls in +// social card meta tags and the noscript output. this essentially reverses the effect +// of shortenLinks() in src/lib/strings/rich-text-manip.ts +func expandPostLinks(postView *appbsky.FeedDefs_PostView) string { + if postView.Record != nil { + rec := postView.Record.Val.(*appbsky.FeedPost) + postText := rec.Text + var charsAdded int64 = 0 + // iterate over facets, check if they're link facets, and if found, grab the uri + for _, facet := range rec.Facets { + linkUri := "" + if slices.ContainsFunc(facet.Features, func(feat *appbsky.RichtextFacet_Features_Elem) bool { + if feat.RichtextFacet_Link != nil && feat.RichtextFacet_Link.LexiconTypeID == "app.bsky.richtext.facet#link" { + linkUri = feat.RichtextFacet_Link.Uri + // only expand uris that have been shortened (as opposed to those with non-uri anchor text) + if int64(len(postText)) >= facet.Index.ByteEnd+charsAdded && + strings.HasSuffix(postText[facet.Index.ByteStart+charsAdded:facet.Index.ByteEnd+charsAdded], "...") && + strings.Contains(linkUri, postText[facet.Index.ByteStart+charsAdded:(facet.Index.ByteEnd+charsAdded)-3]) { + return true + } + } + return false + }) { + // replace the shortened uri with the full length one from the facet using utf8 byte offsets + if int64(len(postText)) >= facet.Index.ByteEnd+charsAdded { + postText = postText[0:facet.Index.ByteStart+charsAdded] + linkUri + postText[facet.Index.ByteEnd+charsAdded:] + charsAdded += int64(len(linkUri)) - (facet.Index.ByteEnd - facet.Index.ByteStart) + } + } + } + // if the post has an embeded link and its url doesn't already appear in postText, append it to + // the end to avoid social cards with missing links + if postView.Embed != nil && + postView.Embed.EmbedExternal_View != nil && + !strings.Contains(postText, postView.Embed.EmbedExternal_View.External.Uri) { + postText = fmt.Sprintf("%s\n%s", postText, postView.Embed.EmbedExternal_View.External.Uri) + } + return postText + } + return "" +} + func (srv *Server) WebProfile(c echo.Context) error { ctx := c.Request().Context() data := pongo2.Context{} diff --git a/bskyweb/templates/post.html b/bskyweb/templates/post.html index 307f80bbb..b6688e35b 100644 --- a/bskyweb/templates/post.html +++ b/bskyweb/templates/post.html @@ -21,9 +21,9 @@ {% else %} <meta property="og:title" content="@{{ postView.Author.Handle }}"> {% endif -%} - {%- if postView.Record.Val.Text %} - <meta name="description" content="{{ postView.Record.Val.Text }}"> - <meta property="og:description" content="{{ postView.Record.Val.Text }}"> + {%- if postText %} + <meta name="description" content="{{ postText }}"> + <meta property="og:description" content="{{ postText }}"> {% endif -%} {%- if imgThumbUrls %} {% for imgThumbUrl in imgThumbUrls %} @@ -47,7 +47,7 @@ <p id="bsky_display_name">{{ postView.Author.DisplayName }}</p> <p id="bsky_handle">{{ postView.Author.Handle }}</p> <p id="bsky_did">{{ postView.Author.Did }}</p> - <p id="bsky_post_text">{{ postView.Record.Val.Text }}</p> + <p id="bsky_post_text">{{ postText }}</p> <p id="bsky_post_indexedat">{{ postView.IndexedAt }}</p> </div> {% endif -%} |