Files
bsky-social-app/src/lib/strings/rich-text-manip.ts
T
2026-08-13 12:26:23 -07:00

58 lines
1.5 KiB
TypeScript

import {type RichText, UnicodeString} from '@bsky/sdk/richtext'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
import {toShortUrl} from './url-helpers'
export function shortenLinks(rt: RichText): RichText {
if (!rt.facets?.length) {
return rt
}
rt = rt.clone()
// enumerate the link facets
if (rt.facets) {
for (const facet of rt.facets) {
const isLink = !!facet.features.find(f =>
bsky.isType(app.bsky.richtext.facet.link, f),
)
if (!isLink) {
continue
}
// extract and shorten the URL
const {byteStart, byteEnd} = facet.index
const url = rt.unicodeText.slice(byteStart, byteEnd)
const shortened = new UnicodeString(toShortUrl(url))
// insert the shorten URL
rt.insert(byteStart, shortened.utf16)
// update the facet to cover the new shortened URL
facet.index.byteStart = byteStart
facet.index.byteEnd = byteStart + shortened.length
// remove the old URL
rt.delete(byteStart + shortened.length, byteEnd + shortened.length)
}
}
return rt
}
// filter out any mention facets that didn't map to a user
export function stripInvalidMentions(rt: RichText): RichText {
if (!rt.facets?.length) {
return rt
}
rt = rt.clone()
if (rt.facets) {
rt.facets = rt.facets?.filter(facet => {
const mention = facet.features.find(f =>
bsky.isType(app.bsky.richtext.facet.mention, f),
)
if (mention && !mention.did) {
return false
}
return true
})
}
return rt
}