about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEric Bailey <git@esb.lol>2024-12-06 16:43:49 -0600
committerGitHub <noreply@github.com>2024-12-06 22:43:49 +0000
commitd05217e56006499a107b772a8a09c79b383e2e3f (patch)
tree640d79b7ab45d5ffb5911f32448cd6d738802d86 /src
parent8c68093d24ded438b2b8eab475efd4bed4a8a1d1 (diff)
downloadvoidsky-d05217e56006499a107b772a8a09c79b383e2e3f.tar.zst
Immediately parse pre-filled links in composer state (#6974)
* Immediately parse pre-filled links in composer state

* Add hack to fix PasteInput height bug

* Parse out ext links separately from post links
Diffstat (limited to 'src')
-rw-r--r--src/view/com/composer/state/composer.ts70
-rw-r--r--src/view/com/composer/text-input/TextInput.tsx4
-rw-r--r--src/view/com/composer/text-input/text-input-util.ts6
3 files changed, 75 insertions, 5 deletions
diff --git a/src/view/com/composer/state/composer.ts b/src/view/com/composer/state/composer.ts
index a0f286419..6d4f10297 100644
--- a/src/view/com/composer/state/composer.ts
+++ b/src/view/com/composer/state/composer.ts
@@ -1,5 +1,5 @@
 import {ImagePickerAsset} from 'expo-image-picker'
-import {AppBskyFeedPostgate, RichText} from '@atproto/api'
+import {AppBskyFeedPostgate, AppBskyRichtextFacet, RichText} from '@atproto/api'
 import {nanoid} from 'nanoid/non-secure'
 
 import {SelfLabel} from '#/lib/moderation'
@@ -16,6 +16,10 @@ import {Gif} from '#/state/queries/tenor'
 import {threadgateViewToAllowUISetting} from '#/state/queries/threadgate'
 import {ThreadgateAllowUISetting} from '#/state/queries/threadgate'
 import {ComposerOpts} from '#/state/shell/composer'
+import {
+  LinkFacetMatch,
+  suggestLinkCardUri,
+} from '#/view/com/composer/text-input/text-input-util'
 import {createVideoState, VideoAction, videoReducer, VideoState} from './video'
 
 type ImagesMedia = {
@@ -508,6 +512,68 @@ export function createComposerState({
         )
       : '',
   })
+
+  let link: Link | undefined
+
+  /**
+   * `initText` atm is only used for compose intents, meaning share links from
+   * external sources. If `initText` is defined, we want to extract links/posts
+   * from `initText` and suggest them as embeds.
+   *
+   * This checks for posts separately from other types of links so that posts
+   * can become quotes. The util `suggestLinkCardUri` is then applied to ensure
+   * we suggest at most 1 of each.
+   */
+  if (initText) {
+    initRichText.detectFacetsWithoutResolution()
+    const detectedExtUris = new Map<string, LinkFacetMatch>()
+    const detectedPostUris = new Map<string, LinkFacetMatch>()
+    if (initRichText.facets) {
+      for (const facet of initRichText.facets) {
+        for (const feature of facet.features) {
+          if (AppBskyRichtextFacet.isLink(feature)) {
+            if (isBskyPostUrl(feature.uri)) {
+              detectedPostUris.set(feature.uri, {facet, rt: initRichText})
+            } else {
+              detectedExtUris.set(feature.uri, {facet, rt: initRichText})
+            }
+          }
+        }
+      }
+    }
+    const pastSuggestedUris = new Set<string>()
+    const suggestedExtUri = suggestLinkCardUri(
+      true,
+      detectedExtUris,
+      new Map(),
+      pastSuggestedUris,
+    )
+    if (suggestedExtUri) {
+      link = {
+        type: 'link',
+        uri: suggestedExtUri,
+      }
+    }
+    const suggestedPostUri = suggestLinkCardUri(
+      true,
+      detectedPostUris,
+      new Map(),
+      pastSuggestedUris,
+    )
+    if (suggestedPostUri) {
+      /*
+       * `initQuote` is only populated via in-app user action, but we're being
+       * future-defensive here.
+       */
+      if (!quote) {
+        quote = {
+          type: 'link',
+          uri: suggestedPostUri,
+        }
+      }
+    }
+  }
+
   return {
     activePostIndex: 0,
     mutableNeedsFocusActive: false,
@@ -521,7 +587,7 @@ export function createComposerState({
           embed: {
             quote,
             media,
-            link: undefined,
+            link,
           },
         },
       ],
diff --git a/src/view/com/composer/text-input/TextInput.tsx b/src/view/com/composer/text-input/TextInput.tsx
index 96cecb37c..55fd3650f 100644
--- a/src/view/com/composer/text-input/TextInput.tsx
+++ b/src/view/com/composer/text-input/TextInput.tsx
@@ -257,6 +257,10 @@ export const TextInput = forwardRef(function TextInputImpl(
             minHeight: 60,
             includeFontPadding: false,
           },
+          {
+            borderWidth: 1,
+            borderColor: 'transparent',
+          },
         ]}
         {...props}>
         {textDecorated}
diff --git a/src/view/com/composer/text-input/text-input-util.ts b/src/view/com/composer/text-input/text-input-util.ts
index cbe8ef6af..7268e10f0 100644
--- a/src/view/com/composer/text-input/text-input-util.ts
+++ b/src/view/com/composer/text-input/text-input-util.ts
@@ -6,7 +6,7 @@ export type LinkFacetMatch = {
 }
 
 export function suggestLinkCardUri(
-  mayBePaste: boolean,
+  suggestLinkImmediately: boolean,
   nextDetectedUris: Map<string, LinkFacetMatch>,
   prevDetectedUris: Map<string, LinkFacetMatch>,
   pastSuggestedUris: Set<string>,
@@ -20,8 +20,8 @@ export function suggestLinkCardUri(
       // Don't suggest already added or already dismissed link cards.
       continue
     }
-    if (mayBePaste) {
-      // Immediately add the pasted link without waiting to type more.
+    if (suggestLinkImmediately) {
+      // Immediately add the pasted or intent-prefilled link without waiting to type more.
       suggestedUris.add(uri)
       continue
     }