about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/moderation/create-sanitized-display-name.ts6
-rw-r--r--src/lib/strings/bidi.ts10
-rw-r--r--src/lib/strings/handles.ts6
-rw-r--r--src/view/com/util/PostMeta.tsx4
4 files changed, 19 insertions, 7 deletions
diff --git a/src/lib/moderation/create-sanitized-display-name.ts b/src/lib/moderation/create-sanitized-display-name.ts
index 16135b274..5863503f5 100644
--- a/src/lib/moderation/create-sanitized-display-name.ts
+++ b/src/lib/moderation/create-sanitized-display-name.ts
@@ -12,10 +12,6 @@ export function createSanitizedDisplayName(
   if (profile.displayName != null && profile.displayName !== '') {
     return sanitizeDisplayName(profile.displayName)
   } else {
-    let sanitizedHandle = sanitizeHandle(profile.handle)
-    if (!noAt) {
-      sanitizedHandle = `@${sanitizedHandle}`
-    }
-    return sanitizedHandle
+    return sanitizeHandle(profile.handle, noAt ? '' : '@')
   }
 }
diff --git a/src/lib/strings/bidi.ts b/src/lib/strings/bidi.ts
new file mode 100644
index 000000000..790c2b6ac
--- /dev/null
+++ b/src/lib/strings/bidi.ts
@@ -0,0 +1,10 @@
+const LEFT_TO_RIGHT_EMBEDDING = '\u202A'
+const POP_DIRECTIONAL_FORMATTING = '\u202C'
+
+/*
+ * Force LTR directionality in a string.
+ * https://www.unicode.org/reports/tr9/#Directional_Formatting_Characters
+ */
+export function forceLTR(str: string) {
+  return LEFT_TO_RIGHT_EMBEDDING + str + POP_DIRECTIONAL_FORMATTING
+}
diff --git a/src/lib/strings/handles.ts b/src/lib/strings/handles.ts
index bc07b32ec..7955e1b2e 100644
--- a/src/lib/strings/handles.ts
+++ b/src/lib/strings/handles.ts
@@ -1,5 +1,7 @@
 // Regex from the go implementation
 // https://github.com/bluesky-social/indigo/blob/main/atproto/syntax/handle.go#L10
+import {forceLTR} from 'lib/strings/bidi'
+
 const VALIDATE_REGEX =
   /^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/
 
@@ -22,7 +24,9 @@ export function isInvalidHandle(handle: string): boolean {
 }
 
 export function sanitizeHandle(handle: string, prefix = ''): string {
-  return isInvalidHandle(handle) ? '⚠Invalid Handle' : `${prefix}${handle}`
+  return isInvalidHandle(handle)
+    ? '⚠Invalid Handle'
+    : forceLTR(`${prefix}${handle}`)
 }
 
 export interface IsValidHandle {
diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx
index 3f855c336..aec787e4e 100644
--- a/src/view/com/util/PostMeta.tsx
+++ b/src/view/com/util/PostMeta.tsx
@@ -32,6 +32,8 @@ interface PostMetaOpts {
   style?: StyleProp<ViewStyle>
 }
 
+const NON_BREAKING_SPACE = '\u00A0'
+
 let PostMeta = (opts: PostMetaOpts): React.ReactNode => {
   const pal = usePalette('default')
   const displayName = opts.author.displayName || opts.author.handle
@@ -83,7 +85,7 @@ let PostMeta = (opts: PostMetaOpts): React.ReactNode => {
             type="md"
             disableMismatchWarning
             style={[pal.textLight, {flexShrink: 4}]}
-            text={'\xa0' + sanitizeHandle(handle, '@')}
+            text={NON_BREAKING_SPACE + sanitizeHandle(handle, '@')}
             href={profileLink}
             onBeforePress={onBeforePressAuthor}
             anchorNoUnderline