From 4205664ea9b12b84a5d67bfa6ffe96081d04138a Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Mon, 3 Jun 2024 14:38:27 -0500 Subject: [PATCH] Handle embeds in backwards compat way --- src/lib/strings/url-helpers.ts | 18 ++++++++++++++++++ .../Messages/Conversation/MessageInput.tsx | 13 ++++++++----- .../Messages/Conversation/MessageInput.web.tsx | 13 ++++++++----- .../Conversation/MessageInputEmbed.tsx | 2 ++ .../Messages/Conversation/MessagesList.tsx | 2 +- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/lib/strings/url-helpers.ts b/src/lib/strings/url-helpers.ts index 2a20373a42..ed69a79a08 100644 --- a/src/lib/strings/url-helpers.ts +++ b/src/lib/strings/url-helpers.ts @@ -74,6 +74,10 @@ export function toShortUrl(url: string): string { } } +export function toBskyAppUrl(url: string): string { + return new URL(url, BSKY_APP_HOST).toString() +} + export function toShareUrl(url: string): string { if (!url.startsWith('https')) { const urlp = new URL('https://bsky.app') @@ -183,6 +187,20 @@ export function feedUriToHref(url: string): string { } } +export function postUriToRelativePath(uri: string): string | undefined { + try { + const {hostname, rkey} = new AtUri(uri) + return `/profile/${hostname}/post/${rkey}` + } catch { + return undefined + } +} + +export function postUriToHref(uri: string): string { + const path = postUriToRelativePath(uri) + return path ? toBskyAppUrl(path) : '' +} + /** * Checks if the label in the post text matches the host of the link facet. * diff --git a/src/screens/Messages/Conversation/MessageInput.tsx b/src/screens/Messages/Conversation/MessageInput.tsx index c8229f95dc..e02bae4d4d 100644 --- a/src/screens/Messages/Conversation/MessageInput.tsx +++ b/src/screens/Messages/Conversation/MessageInput.tsx @@ -18,6 +18,7 @@ import Graphemer from 'graphemer' import {HITSLOP_10, MAX_DM_GRAPHEME_LENGTH} from '#/lib/constants' import {useHaptics} from '#/lib/haptics' +import {postUriToHref} from '#/lib/strings/url-helpers' import { useMessageDraft, useSaveMessageDraft, @@ -33,12 +34,12 @@ const AnimatedTextInput = Animated.createAnimatedComponent(TextInput) export function MessageInput({ onSendMessage, - hasEmbed, + embedUri, setEmbed, children, }: { onSendMessage: (message: string) => void - hasEmbed: boolean + embedUri?: string setEmbed: (embedUrl: string | undefined) => void children?: React.ReactNode }) { @@ -56,14 +57,16 @@ export function MessageInput({ const inputStyles = useSharedInputStyles() const [isFocused, setIsFocused] = React.useState(false) - const [message, setMessage] = React.useState(getDraft) + const [maybeDraft] = React.useState(getDraft) + const [maybeEmbedUrl] = React.useState(postUriToHref(embedUri || '')) + const [message, setMessage] = React.useState(maybeEmbedUrl || maybeDraft) const inputRef = useAnimatedRef() useSaveMessageDraft(message) useExtractEmbedFromFacets(message, setEmbed) const onSubmit = React.useCallback(() => { - if (!hasEmbed && message.trim() === '') { + if (!embedUri && message.trim() === '') { return } if (new Graphemer().countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) { @@ -82,7 +85,7 @@ export function MessageInput({ inputRef.current?.focus() }, 100) }, [ - hasEmbed, + embedUri, message, clearDraft, onSendMessage, diff --git a/src/screens/Messages/Conversation/MessageInput.web.tsx b/src/screens/Messages/Conversation/MessageInput.web.tsx index b9181774e5..4f1053262d 100644 --- a/src/screens/Messages/Conversation/MessageInput.web.tsx +++ b/src/screens/Messages/Conversation/MessageInput.web.tsx @@ -6,6 +6,7 @@ import Graphemer from 'graphemer' import TextareaAutosize from 'react-textarea-autosize' import {MAX_DM_GRAPHEME_LENGTH} from '#/lib/constants' +import {postUriToHref} from '#/lib/strings/url-helpers' import { useMessageDraft, useSaveMessageDraft, @@ -20,12 +21,12 @@ import {useExtractEmbedFromFacets} from './MessageInputEmbed' export function MessageInput({ onSendMessage, - hasEmbed, + embedUri, setEmbed, children, }: { onSendMessage: (message: string) => void - hasEmbed: boolean + embedUri?: string setEmbed: (embedUrl: string | undefined) => void children?: React.ReactNode }) { @@ -33,7 +34,9 @@ export function MessageInput({ const {_} = useLingui() const t = useTheme() const {getDraft, clearDraft} = useMessageDraft() - const [message, setMessage] = React.useState(getDraft) + const [maybeDraft] = React.useState(getDraft) + const [maybeEmbedUrl] = React.useState(postUriToHref(embedUri || '')) + const [message, setMessage] = React.useState(maybeEmbedUrl || maybeDraft) const inputStyles = useSharedInputStyles() const isComposing = React.useRef(false) @@ -42,7 +45,7 @@ export function MessageInput({ const [textAreaHeight, setTextAreaHeight] = React.useState(38) const onSubmit = React.useCallback(() => { - if (!hasEmbed && message.trim() === '') { + if (!embedUri && message.trim() === '') { return } if (new Graphemer().countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) { @@ -53,7 +56,7 @@ export function MessageInput({ onSendMessage(message) setMessage('') setEmbed(undefined) - }, [message, onSendMessage, _, clearDraft, hasEmbed, setEmbed]) + }, [message, onSendMessage, _, clearDraft, embedUri, setEmbed]) const onKeyDown = React.useCallback( (e: React.KeyboardEvent) => { diff --git a/src/screens/Messages/Conversation/MessageInputEmbed.tsx b/src/screens/Messages/Conversation/MessageInputEmbed.tsx index 4fdd31bcf1..b2013a5730 100644 --- a/src/screens/Messages/Conversation/MessageInputEmbed.tsx +++ b/src/screens/Messages/Conversation/MessageInputEmbed.tsx @@ -89,6 +89,8 @@ export function useExtractEmbedFromFacets( useEffect(() => { if (uriFromFacet) { setEmbed(uriFromFacet) + } else { + setEmbed(undefined) } }, [uriFromFacet, setEmbed]) } diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx index de77997f1d..f3a33ff30a 100644 --- a/src/screens/Messages/Conversation/MessagesList.tsx +++ b/src/screens/Messages/Conversation/MessagesList.tsx @@ -387,7 +387,7 @@ export function MessagesList({ convoState.items.length === 0 && }