···1010 "net/http"
1111 "os"
1212 "os/signal"
1313+ "slices"
1314 "strings"
1415 "syscall"
1516 "time"
···351352 data["imgThumbUrls"] = thumbUrls
352353 }
353354 }
355355+356356+ data["postText"] = expandPostLinks(postView)
357357+354358 return c.Render(http.StatusOK, "post.html", data)
359359+}
360360+361361+// function to expand shortened links in rich text back to full urls, replacing shortened urls in
362362+// social card meta tags and the noscript output. this essentially reverses the effect
363363+// of shortenLinks() in src/lib/strings/rich-text-manip.ts
364364+func expandPostLinks(postView *appbsky.FeedDefs_PostView) string {
365365+ if postView.Record != nil {
366366+ rec := postView.Record.Val.(*appbsky.FeedPost)
367367+ postText := rec.Text
368368+ var charsAdded int64 = 0
369369+ // iterate over facets, check if they're link facets, and if found, grab the uri
370370+ for _, facet := range rec.Facets {
371371+ linkUri := ""
372372+ if slices.ContainsFunc(facet.Features, func(feat *appbsky.RichtextFacet_Features_Elem) bool {
373373+ if feat.RichtextFacet_Link != nil && feat.RichtextFacet_Link.LexiconTypeID == "app.bsky.richtext.facet#link" {
374374+ linkUri = feat.RichtextFacet_Link.Uri
375375+ // only expand uris that have been shortened (as opposed to those with non-uri anchor text)
376376+ if int64(len(postText)) >= facet.Index.ByteEnd+charsAdded &&
377377+ strings.HasSuffix(postText[facet.Index.ByteStart+charsAdded:facet.Index.ByteEnd+charsAdded], "...") &&
378378+ strings.Contains(linkUri, postText[facet.Index.ByteStart+charsAdded:(facet.Index.ByteEnd+charsAdded)-3]) {
379379+ return true
380380+ }
381381+ }
382382+ return false
383383+ }) {
384384+ // replace the shortened uri with the full length one from the facet using utf8 byte offsets
385385+ if int64(len(postText)) >= facet.Index.ByteEnd+charsAdded {
386386+ postText = postText[0:facet.Index.ByteStart+charsAdded] + linkUri + postText[facet.Index.ByteEnd+charsAdded:]
387387+ charsAdded += int64(len(linkUri)) - (facet.Index.ByteEnd - facet.Index.ByteStart)
388388+ }
389389+ }
390390+ }
391391+ // if the post has an embeded link and its url doesn't already appear in postText, append it to
392392+ // the end to avoid social cards with missing links
393393+ if postView.Embed != nil &&
394394+ postView.Embed.EmbedExternal_View != nil &&
395395+ !strings.Contains(postText, postView.Embed.EmbedExternal_View.External.Uri) {
396396+ postText = fmt.Sprintf("%s\n%s", postText, postView.Embed.EmbedExternal_View.External.Uri)
397397+ }
398398+ return postText
399399+ }
400400+ return ""
355401}
356402357403func (srv *Server) WebProfile(c echo.Context) error {