about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2022-11-18 13:59:17 -0600
committerPaul Frazee <pfrazee@gmail.com>2022-11-18 13:59:17 -0600
commit6e2b7a0b90ae8140d81d2d66c87ec9e40d9f45ec (patch)
treef36f902da70006364e839ee53d55a468c7539e21 /src
parent9d13e05dbf0bb6430060ddf556006b1721444edc (diff)
downloadvoidsky-6e2b7a0b90ae8140d81d2d66c87ec9e40d9f45ec.tar.zst
Add support for web links
Diffstat (limited to 'src')
-rw-r--r--src/view/com/composer/ComposePost.tsx2
-rw-r--r--src/view/com/util/Link.tsx27
-rw-r--r--src/view/com/util/RichText.tsx27
-rw-r--r--src/view/lib/strings.ts41
4 files changed, 67 insertions, 30 deletions
diff --git a/src/view/com/composer/ComposePost.tsx b/src/view/com/composer/ComposePost.tsx
index b7abbed48..ab4834116 100644
--- a/src/view/com/composer/ComposePost.tsx
+++ b/src/view/com/composer/ComposePost.tsx
@@ -108,7 +108,7 @@ export const ComposePost = observer(function ComposePost({
       : undefined
 
   const textDecorated = useMemo(() => {
-    const re = /(@[a-z0-9\.]*)/gi
+    const re = /(@[a-z0-9\.]*)|(https?:\/\/[\S]+)/gi
     const segments = []
     let match
     let start = 0
diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx
index 4931438b8..ff3d25cb5 100644
--- a/src/view/com/util/Link.tsx
+++ b/src/view/com/util/Link.tsx
@@ -1,6 +1,7 @@
 import React from 'react'
 import {observer} from 'mobx-react-lite'
 import {
+  Linking,
   StyleProp,
   Text,
   TouchableOpacity,
@@ -8,6 +9,7 @@ import {
   ViewStyle,
 } from 'react-native'
 import {useStores} from '../../../state'
+import {RootStoreModel} from '../../../state'
 import {LinkActionsModel} from '../../../state/models/shell-ui'
 
 export const Link = observer(function Link({
@@ -23,13 +25,10 @@ export const Link = observer(function Link({
 }) {
   const store = useStores()
   const onPress = () => {
-    store.shell.closeModal() // close any active modals
-    store.nav.navigate(href)
+    handleLink(store, href, false)
   }
   const onLongPress = () => {
-    store.shell.closeModal() // close any active modals
-    store.nav.newTab(href, title)
-    // store.shell.openModal(new LinkActionsModel(href, title || href))
+    handleLink(store, href, true)
   }
   return (
     <TouchableOpacity
@@ -55,12 +54,10 @@ export const TextLink = observer(function Link({
 }) {
   const store = useStores()
   const onPress = () => {
-    store.shell.closeModal() // close any active modals
-    store.nav.navigate(href)
+    handleLink(store, href, false)
   }
   const onLongPress = () => {
-    store.shell.closeModal() // close any active modals
-    store.nav.newTab(href, title)
+    handleLink(store, href, true)
   }
   return (
     <Text style={style} onPress={onPress} onLongPress={onLongPress}>
@@ -68,3 +65,15 @@ export const TextLink = observer(function Link({
     </Text>
   )
 })
+
+function handleLink(store: RootStoreModel, href: string, longPress: boolean) {
+  if (href.startsWith('http')) {
+    Linking.openURL(href)
+  } else if (longPress) {
+    store.shell.closeModal() // close any active modals
+    store.nav.newTab(href)
+  } else {
+    store.shell.closeModal() // close any active modals
+    store.nav.navigate(href)
+  }
+}
diff --git a/src/view/com/util/RichText.tsx b/src/view/com/util/RichText.tsx
index 35948455a..f865c873a 100644
--- a/src/view/com/util/RichText.tsx
+++ b/src/view/com/util/RichText.tsx
@@ -32,14 +32,25 @@ export function RichText({
     if (typeof segment === 'string') {
       els.push(segment)
     } else {
-      els.push(
-        <TextLink
-          key={key}
-          text={segment.text}
-          href={`/profile/${segment.entity.value}`}
-          style={[style, s.blue3]}
-        />,
-      )
+      if (segment.entity.type === 'mention') {
+        els.push(
+          <TextLink
+            key={key}
+            text={segment.text}
+            href={`/profile/${segment.entity.value}`}
+            style={[style, s.blue3]}
+          />,
+        )
+      } else if (segment.entity.type === 'link') {
+        els.push(
+          <TextLink
+            key={key}
+            text={segment.text}
+            href={segment.entity.value}
+            style={[style, s.blue3]}
+          />,
+        )
+      }
     }
     key++
   }
diff --git a/src/view/lib/strings.ts b/src/view/lib/strings.ts
index 6d963b281..b12fbd398 100644
--- a/src/view/lib/strings.ts
+++ b/src/view/lib/strings.ts
@@ -63,19 +63,36 @@ export function extractEntities(
 ): Entity[] | undefined {
   let match
   let ents: Entity[] = []
-  const re = /(^|\s)(@)([a-zA-Z0-9\.-]+)(\b)/dg
-  while ((match = re.exec(text))) {
-    if (knownHandles && !knownHandles.has(match[3])) {
-      continue // not a known handle
+  {
+    // mentions
+    const re = /(^|\s)(@)([a-zA-Z0-9\.-]+)(\b)/dg
+    while ((match = re.exec(text))) {
+      if (knownHandles && !knownHandles.has(match[3])) {
+        continue // not a known handle
+      }
+      ents.push({
+        type: 'mention',
+        value: match[3],
+        index: {
+          start: match.indices[2][0], // skip the (^|\s) but include the '@'
+          end: match.indices[3][1],
+        },
+      })
+    }
+  }
+  {
+    // links
+    const re = /(^|\s)(https?:\/\/[\S]+)(\b)/dg
+    while ((match = re.exec(text))) {
+      ents.push({
+        type: 'link',
+        value: match[2],
+        index: {
+          start: match.indices[1][0], // skip the (^|\s) but include the '@'
+          end: match.indices[2][1],
+        },
+      })
     }
-    ents.push({
-      type: 'mention',
-      value: match[3],
-      index: {
-        start: match.indices[2][0], // skip the (^|\s) but include the '@'
-        end: match.indices[3][1],
-      },
-    })
   }
   return ents.length > 0 ? ents : undefined
 }