about summary refs log tree commit diff
path: root/src/lib/strings
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/strings')
-rw-r--r--src/lib/strings/display-names.ts11
-rw-r--r--src/lib/strings/handles.ts2
-rw-r--r--src/lib/strings/rich-text-manip.ts34
-rw-r--r--src/lib/strings/url-helpers.ts15
4 files changed, 51 insertions, 11 deletions
diff --git a/src/lib/strings/display-names.ts b/src/lib/strings/display-names.ts
index b98153732..29b7c3b50 100644
--- a/src/lib/strings/display-names.ts
+++ b/src/lib/strings/display-names.ts
@@ -1,10 +1,19 @@
+import {ModerationUI} from '@atproto/api'
+import {describeModerationCause} from '../moderation'
+
 // \u2705 = ✅
 // \u2713 = ✓
 // \u2714 = ✔
 // \u2611 = ☑
 const CHECK_MARKS_RE = /[\u2705\u2713\u2714\u2611]/gu
 
-export function sanitizeDisplayName(str: string): string {
+export function sanitizeDisplayName(
+  str: string,
+  moderation?: ModerationUI,
+): string {
+  if (moderation?.blur) {
+    return `⚠${describeModerationCause(moderation.cause, 'account').name}`
+  }
   if (typeof str === 'string') {
     return str.replace(CHECK_MARKS_RE, '').trim()
   }
diff --git a/src/lib/strings/handles.ts b/src/lib/strings/handles.ts
index 3c01d9345..6ce462435 100644
--- a/src/lib/strings/handles.ts
+++ b/src/lib/strings/handles.ts
@@ -3,7 +3,7 @@ export function makeValidHandle(str: string): string {
     str = str.slice(0, 20)
   }
   str = str.toLowerCase()
-  return str.replace(/^[^a-z]+/g, '').replace(/[^a-z0-9-]/g, '')
+  return str.replace(/^[^a-z0-9]+/g, '').replace(/[^a-z0-9-]/g, '')
 }
 
 export function createFullHandle(name: string, domain: string): string {
diff --git a/src/lib/strings/rich-text-manip.ts b/src/lib/strings/rich-text-manip.ts
new file mode 100644
index 000000000..d9cd8c071
--- /dev/null
+++ b/src/lib/strings/rich-text-manip.ts
@@ -0,0 +1,34 @@
+import {RichText, UnicodeString} from '@atproto/api'
+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 => f.$type === 'app.bsky.richtext.facet#link',
+      )
+      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
+}
diff --git a/src/lib/strings/url-helpers.ts b/src/lib/strings/url-helpers.ts
index 105c631bf..b509aad01 100644
--- a/src/lib/strings/url-helpers.ts
+++ b/src/lib/strings/url-helpers.ts
@@ -30,7 +30,7 @@ export function toNiceDomain(url: string): string {
     if (`https://${urlp.host}` === PROD_SERVICE) {
       return 'Bluesky Social'
     }
-    return urlp.host
+    return urlp.host ? urlp.host : url
   } catch (e) {
     return url
   }
@@ -42,15 +42,12 @@ export function toShortUrl(url: string): string {
     if (urlp.protocol !== 'http:' && urlp.protocol !== 'https:') {
       return url
     }
-    const shortened =
-      urlp.host +
-      (urlp.pathname === '/' ? '' : urlp.pathname) +
-      urlp.search +
-      urlp.hash
-    if (shortened.length > 30) {
-      return shortened.slice(0, 27) + '...'
+    const path =
+      (urlp.pathname === '/' ? '' : urlp.pathname) + urlp.search + urlp.hash
+    if (path.length > 15) {
+      return urlp.host + path.slice(0, 13) + '...'
     }
-    return shortened ? shortened : url
+    return urlp.host + path
   } catch (e) {
     return url
   }