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
This commit is contained in:
Eric Bailey
2024-12-06 16:43:49 -06:00
committed by Dan Abramov
parent b888fe1fcd
commit 12f9dacb06
3 changed files with 75 additions and 5 deletions
+68 -2
View File
@@ -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,
},
},
],
@@ -257,6 +257,10 @@ export const TextInput = forwardRef(function TextInputImpl(
minHeight: 60,
includeFontPadding: false,
},
{
borderWidth: 1,
borderColor: 'transparent',
},
]}
{...props}>
{textDecorated}
@@ -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
}