Handle embeds in backwards compat way
This commit is contained in:
@@ -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 {
|
export function toShareUrl(url: string): string {
|
||||||
if (!url.startsWith('https')) {
|
if (!url.startsWith('https')) {
|
||||||
const urlp = new URL('https://bsky.app')
|
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.
|
* Checks if the label in the post text matches the host of the link facet.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import Graphemer from 'graphemer'
|
|||||||
|
|
||||||
import {HITSLOP_10, MAX_DM_GRAPHEME_LENGTH} from '#/lib/constants'
|
import {HITSLOP_10, MAX_DM_GRAPHEME_LENGTH} from '#/lib/constants'
|
||||||
import {useHaptics} from '#/lib/haptics'
|
import {useHaptics} from '#/lib/haptics'
|
||||||
|
import {postUriToHref} from '#/lib/strings/url-helpers'
|
||||||
import {
|
import {
|
||||||
useMessageDraft,
|
useMessageDraft,
|
||||||
useSaveMessageDraft,
|
useSaveMessageDraft,
|
||||||
@@ -33,12 +34,12 @@ const AnimatedTextInput = Animated.createAnimatedComponent(TextInput)
|
|||||||
|
|
||||||
export function MessageInput({
|
export function MessageInput({
|
||||||
onSendMessage,
|
onSendMessage,
|
||||||
hasEmbed,
|
embedUri,
|
||||||
setEmbed,
|
setEmbed,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
onSendMessage: (message: string) => void
|
onSendMessage: (message: string) => void
|
||||||
hasEmbed: boolean
|
embedUri?: string
|
||||||
setEmbed: (embedUrl: string | undefined) => void
|
setEmbed: (embedUrl: string | undefined) => void
|
||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
@@ -56,14 +57,16 @@ export function MessageInput({
|
|||||||
|
|
||||||
const inputStyles = useSharedInputStyles()
|
const inputStyles = useSharedInputStyles()
|
||||||
const [isFocused, setIsFocused] = React.useState(false)
|
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<TextInput>()
|
const inputRef = useAnimatedRef<TextInput>()
|
||||||
|
|
||||||
useSaveMessageDraft(message)
|
useSaveMessageDraft(message)
|
||||||
useExtractEmbedFromFacets(message, setEmbed)
|
useExtractEmbedFromFacets(message, setEmbed)
|
||||||
|
|
||||||
const onSubmit = React.useCallback(() => {
|
const onSubmit = React.useCallback(() => {
|
||||||
if (!hasEmbed && message.trim() === '') {
|
if (!embedUri && message.trim() === '') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (new Graphemer().countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) {
|
if (new Graphemer().countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) {
|
||||||
@@ -82,7 +85,7 @@ export function MessageInput({
|
|||||||
inputRef.current?.focus()
|
inputRef.current?.focus()
|
||||||
}, 100)
|
}, 100)
|
||||||
}, [
|
}, [
|
||||||
hasEmbed,
|
embedUri,
|
||||||
message,
|
message,
|
||||||
clearDraft,
|
clearDraft,
|
||||||
onSendMessage,
|
onSendMessage,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import Graphemer from 'graphemer'
|
|||||||
import TextareaAutosize from 'react-textarea-autosize'
|
import TextareaAutosize from 'react-textarea-autosize'
|
||||||
|
|
||||||
import {MAX_DM_GRAPHEME_LENGTH} from '#/lib/constants'
|
import {MAX_DM_GRAPHEME_LENGTH} from '#/lib/constants'
|
||||||
|
import {postUriToHref} from '#/lib/strings/url-helpers'
|
||||||
import {
|
import {
|
||||||
useMessageDraft,
|
useMessageDraft,
|
||||||
useSaveMessageDraft,
|
useSaveMessageDraft,
|
||||||
@@ -20,12 +21,12 @@ import {useExtractEmbedFromFacets} from './MessageInputEmbed'
|
|||||||
|
|
||||||
export function MessageInput({
|
export function MessageInput({
|
||||||
onSendMessage,
|
onSendMessage,
|
||||||
hasEmbed,
|
embedUri,
|
||||||
setEmbed,
|
setEmbed,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
onSendMessage: (message: string) => void
|
onSendMessage: (message: string) => void
|
||||||
hasEmbed: boolean
|
embedUri?: string
|
||||||
setEmbed: (embedUrl: string | undefined) => void
|
setEmbed: (embedUrl: string | undefined) => void
|
||||||
children?: React.ReactNode
|
children?: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
@@ -33,7 +34,9 @@ export function MessageInput({
|
|||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {getDraft, clearDraft} = useMessageDraft()
|
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 inputStyles = useSharedInputStyles()
|
||||||
const isComposing = React.useRef(false)
|
const isComposing = React.useRef(false)
|
||||||
@@ -42,7 +45,7 @@ export function MessageInput({
|
|||||||
const [textAreaHeight, setTextAreaHeight] = React.useState(38)
|
const [textAreaHeight, setTextAreaHeight] = React.useState(38)
|
||||||
|
|
||||||
const onSubmit = React.useCallback(() => {
|
const onSubmit = React.useCallback(() => {
|
||||||
if (!hasEmbed && message.trim() === '') {
|
if (!embedUri && message.trim() === '') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (new Graphemer().countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) {
|
if (new Graphemer().countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) {
|
||||||
@@ -53,7 +56,7 @@ export function MessageInput({
|
|||||||
onSendMessage(message)
|
onSendMessage(message)
|
||||||
setMessage('')
|
setMessage('')
|
||||||
setEmbed(undefined)
|
setEmbed(undefined)
|
||||||
}, [message, onSendMessage, _, clearDraft, hasEmbed, setEmbed])
|
}, [message, onSendMessage, _, clearDraft, embedUri, setEmbed])
|
||||||
|
|
||||||
const onKeyDown = React.useCallback(
|
const onKeyDown = React.useCallback(
|
||||||
(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ export function useExtractEmbedFromFacets(
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (uriFromFacet) {
|
if (uriFromFacet) {
|
||||||
setEmbed(uriFromFacet)
|
setEmbed(uriFromFacet)
|
||||||
|
} else {
|
||||||
|
setEmbed(undefined)
|
||||||
}
|
}
|
||||||
}, [uriFromFacet, setEmbed])
|
}, [uriFromFacet, setEmbed])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ export function MessagesList({
|
|||||||
convoState.items.length === 0 && <ChatEmptyPill />}
|
convoState.items.length === 0 && <ChatEmptyPill />}
|
||||||
<MessageInput
|
<MessageInput
|
||||||
onSendMessage={onSendMessage}
|
onSendMessage={onSendMessage}
|
||||||
hasEmbed={!!embedUri}
|
embedUri={embedUri}
|
||||||
setEmbed={setEmbed}>
|
setEmbed={setEmbed}>
|
||||||
<MessageInputEmbed embedUri={embedUri} setEmbed={setEmbed} />
|
<MessageInputEmbed embedUri={embedUri} setEmbed={setEmbed} />
|
||||||
</MessageInput>
|
</MessageInput>
|
||||||
|
|||||||
Reference in New Issue
Block a user