diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-05-31 18:41:06 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-31 10:41:06 -0500 |
commit | 8eb3cebb362cc438e368a9fbb78e2f85403ffeed (patch) | |
tree | 3c82cd4701c830a43e7f13825fc912304069625c /src/screens/Messages/Conversation/MessagesList.tsx | |
parent | 455937dd0f7248033f412f53f7d2be89978aa4f2 (diff) | |
download | voidsky-8eb3cebb362cc438e368a9fbb78e2f85403ffeed.tar.zst |
[🐴] send record via link in text (Record DMs - base PR) (#4227)
* send record via link in text * re-trim text after removing link
Diffstat (limited to 'src/screens/Messages/Conversation/MessagesList.tsx')
-rw-r--r-- | src/screens/Messages/Conversation/MessagesList.tsx | 85 |
1 files changed, 71 insertions, 14 deletions
diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx index 583c40852..d6aa06a1c 100644 --- a/src/screens/Messages/Conversation/MessagesList.tsx +++ b/src/screens/Messages/Conversation/MessagesList.tsx @@ -13,12 +13,16 @@ import { } from 'react-native-reanimated' import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/reanimated2/hook/commonTypes' import {useSafeAreaInsets} from 'react-native-safe-area-context' -import {AppBskyRichtextFacet, RichText} from '@atproto/api' +import {AppBskyEmbedRecord, AppBskyRichtextFacet, RichText} from '@atproto/api' -import {shortenLinks} from '#/lib/strings/rich-text-manip' +import {getPostAsQuote} from '#/lib/link-meta/bsky' +import {shortenLinks, stripInvalidMentions} from '#/lib/strings/rich-text-manip' +import {isBskyPostUrl} from '#/lib/strings/url-helpers' +import {logger} from '#/logger' import {isNative} from '#/platform/detection' import {isConvoActive, useConvoActive} from '#/state/messages/convo' import {ConvoItem, ConvoStatus} from '#/state/messages/convo/types' +import {useGetPost} from '#/state/queries/post' import {useAgent} from '#/state/session' import {clamp} from 'lib/numbers' import {ScrollProvider} from 'lib/ScrollContext' @@ -80,6 +84,7 @@ export function MessagesList({ }) { const convoState = useConvoActive() const agent = useAgent() + const getPost = useGetPost() const flatListRef = useAnimatedRef<FlatList>() @@ -264,20 +269,71 @@ export function MessagesList({ // -- Message sending const onSendMessage = useCallback( async (text: string) => { - let rt = new RichText({text}, {cleanNewlines: true}) - await rt.detectFacets(agent) - rt = shortenLinks(rt) + let rt = new RichText({text: text.trimEnd()}, {cleanNewlines: true}) + + // detect facets without resolution first - this is used to see if there's + // any post links in the text that we can embed. We do this first because + // we want to remove the post link from the text, re-trim, then detect facets + rt.detectFacetsWithoutResolution() + + let embed: AppBskyEmbedRecord.Main | undefined + // find the first link facet that is a link to a post + const postLinkFacet = rt.facets?.find(facet => { + return facet.features.find(feature => { + if (AppBskyRichtextFacet.isLink(feature)) { + return isBskyPostUrl(feature.uri) + } + return false + }) + }) - // filter out any mention facets that didn't map to a user - rt.facets = rt.facets?.filter(facet => { - const mention = facet.features.find(feature => - AppBskyRichtextFacet.isMention(feature), + // if we found a post link, get the post and embed it + if (postLinkFacet) { + const postLink = postLinkFacet.features.find( + AppBskyRichtextFacet.isLink, ) - if (mention && !mention.did) { - return false + if (!postLink) return + + try { + const post = await getPostAsQuote(getPost, postLink.uri) + if (post) { + embed = { + $type: 'app.bsky.embed.record', + record: { + uri: post.uri, + cid: post.cid, + }, + } + + // remove the post link from the text + rt.delete( + postLinkFacet.index.byteStart, + postLinkFacet.index.byteEnd, + ) + + // re-trim the text, now that we've removed the post link + // + // if the post link is at the start of the text, we don't want to leave a leading space + // so trim on both sides + if (postLinkFacet.index.byteStart === 0) { + rt = new RichText({text: rt.text.trim()}, {cleanNewlines: true}) + } else { + // otherwise just trim the end + rt = new RichText( + {text: rt.text.trimEnd()}, + {cleanNewlines: true}, + ) + } + } + } catch (error) { + logger.error('Failed to get post as quote for DM', {error}) } - return true - }) + } + + await rt.detectFacets(agent) + + rt = shortenLinks(rt) + rt = stripInvalidMentions(rt) if (!hasScrolled) { setHasScrolled(true) @@ -286,9 +342,10 @@ export function MessagesList({ convoState.sendMessage({ text: rt.text, facets: rt.facets, + embed, }) }, - [convoState, agent, hasScrolled, setHasScrolled], + [agent, convoState, getPost, hasScrolled, setHasScrolled], ) // -- List layout changes (opening emoji keyboard, etc.) |