[🐴] send record via link in text (Record DMs - base PR) (#4227)
* send record via link in text * re-trim text after removing link
This commit is contained in:
parent
455937dd0f
commit
8eb3cebb36
7 changed files with 99 additions and 51 deletions
|
@ -63,7 +63,7 @@ export function MessageInput({
|
|||
return
|
||||
}
|
||||
clearDraft()
|
||||
onSendMessage(message.trimEnd())
|
||||
onSendMessage(message)
|
||||
playHaptic()
|
||||
setMessage('')
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ export function MessageInput({
|
|||
return
|
||||
}
|
||||
clearDraft()
|
||||
onSendMessage(message.trimEnd())
|
||||
onSendMessage(message)
|
||||
setMessage('')
|
||||
}, [message, onSendMessage, _, clearDraft])
|
||||
|
||||
|
|
|
@ -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,21 +269,72 @@ 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})
|
||||
|
||||
// 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 (mention && !mention.did) {
|
||||
// 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
|
||||
}
|
||||
return true
|
||||
})
|
||||
})
|
||||
|
||||
// if we found a post link, get the post and embed it
|
||||
if (postLinkFacet) {
|
||||
const postLink = postLinkFacet.features.find(
|
||||
AppBskyRichtextFacet.isLink,
|
||||
)
|
||||
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})
|
||||
}
|
||||
}
|
||||
|
||||
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.)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue