(wip) add message input embed component
This commit is contained in:
@@ -16,6 +16,7 @@ import {HITSLOP_10} from '#/lib/constants'
|
||||
import {useHaptics} from 'lib/haptics'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane'
|
||||
import {MessageInputEmbed} from './MessageInputEmbed'
|
||||
|
||||
export function MessageInput({
|
||||
onSendMessage,
|
||||
@@ -68,43 +69,48 @@ export function MessageInput({
|
||||
<View
|
||||
style={[
|
||||
a.w_full,
|
||||
a.flex_row,
|
||||
a.py_sm,
|
||||
a.px_sm,
|
||||
a.pl_md,
|
||||
t.atoms.bg_contrast_25,
|
||||
{borderRadius: 23},
|
||||
]}>
|
||||
<TextInput
|
||||
accessibilityLabel={_(msg`Message input field`)}
|
||||
accessibilityHint={_(msg`Type your message here`)}
|
||||
placeholder={_(msg`Write a message`)}
|
||||
placeholderTextColor={t.palette.contrast_500}
|
||||
value={message}
|
||||
multiline={true}
|
||||
onChangeText={setMessage}
|
||||
style={[a.flex_1, a.text_md, a.px_sm, t.atoms.text, {maxHeight}]}
|
||||
keyboardAppearance={t.name === 'light' ? 'light' : 'dark'}
|
||||
scrollEnabled={isInputScrollable}
|
||||
blurOnSubmit={false}
|
||||
onFocus={scrollToEnd}
|
||||
onContentSizeChange={onInputLayout}
|
||||
ref={inputRef}
|
||||
/>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Send message`)}
|
||||
accessibilityHint=""
|
||||
hitSlop={HITSLOP_10}
|
||||
style={[
|
||||
a.rounded_full,
|
||||
a.align_center,
|
||||
a.justify_center,
|
||||
{height: 30, width: 30, backgroundColor: t.palette.primary_500},
|
||||
]}
|
||||
onPress={onSubmit}>
|
||||
<PaperPlane fill={t.palette.white} style={[a.relative, {left: 1}]} />
|
||||
</Pressable>
|
||||
<MessageInputEmbed message={message} setMessage={setMessage} />
|
||||
<View style={a.flex_row}>
|
||||
<TextInput
|
||||
accessibilityLabel={_(msg`Message input field`)}
|
||||
accessibilityHint={_(msg`Type your message here`)}
|
||||
placeholder={_(msg`Write a message`)}
|
||||
placeholderTextColor={t.palette.contrast_500}
|
||||
value={message}
|
||||
multiline={true}
|
||||
onChangeText={setMessage}
|
||||
style={[a.flex_1, a.text_md, a.px_sm, t.atoms.text, {maxHeight}]}
|
||||
keyboardAppearance={t.name === 'light' ? 'light' : 'dark'}
|
||||
scrollEnabled={isInputScrollable}
|
||||
blurOnSubmit={false}
|
||||
onFocus={scrollToEnd}
|
||||
onContentSizeChange={onInputLayout}
|
||||
ref={inputRef}
|
||||
/>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Send message`)}
|
||||
accessibilityHint=""
|
||||
hitSlop={HITSLOP_10}
|
||||
style={[
|
||||
a.rounded_full,
|
||||
a.align_center,
|
||||
a.justify_center,
|
||||
{height: 30, width: 30, backgroundColor: t.palette.primary_500},
|
||||
]}
|
||||
onPress={onSubmit}>
|
||||
<PaperPlane
|
||||
fill={t.palette.white}
|
||||
style={[a.relative, {left: 1}]}
|
||||
/>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -6,6 +6,7 @@ import TextareaAutosize from 'react-textarea-autosize'
|
||||
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane'
|
||||
import {MessageInputEmbed} from './MessageInputEmbed'
|
||||
|
||||
export function MessageInput({
|
||||
onSendMessage,
|
||||
@@ -47,47 +48,52 @@ export function MessageInput({
|
||||
<View style={a.p_sm}>
|
||||
<View
|
||||
style={[
|
||||
a.flex_row,
|
||||
a.py_sm,
|
||||
a.px_sm,
|
||||
a.pl_md,
|
||||
t.atoms.bg_contrast_25,
|
||||
{borderRadius: 23},
|
||||
]}>
|
||||
<TextareaAutosize
|
||||
style={StyleSheet.flatten([
|
||||
a.flex_1,
|
||||
a.px_sm,
|
||||
a.border_0,
|
||||
t.atoms.text,
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
resize: 'none',
|
||||
paddingTop: 4,
|
||||
},
|
||||
])}
|
||||
maxRows={12}
|
||||
placeholder={_(msg`Write a message`)}
|
||||
defaultValue=""
|
||||
value={message}
|
||||
dirName="ltr"
|
||||
autoFocus={true}
|
||||
onChange={onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Send message`)}
|
||||
accessibilityHint=""
|
||||
style={[
|
||||
a.rounded_full,
|
||||
a.align_center,
|
||||
a.justify_center,
|
||||
{height: 30, width: 30, backgroundColor: t.palette.primary_500},
|
||||
]}
|
||||
onPress={onSubmit}>
|
||||
<PaperPlane fill={t.palette.white} style={[a.relative, {left: 1}]} />
|
||||
</Pressable>
|
||||
<MessageInputEmbed message={message} setMessage={setMessage} />
|
||||
<View style={a.flex_row}>
|
||||
<TextareaAutosize
|
||||
style={StyleSheet.flatten([
|
||||
a.flex_1,
|
||||
a.px_sm,
|
||||
a.border_0,
|
||||
t.atoms.text,
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
resize: 'none',
|
||||
paddingTop: 4,
|
||||
},
|
||||
])}
|
||||
maxRows={12}
|
||||
placeholder={_(msg`Write a message`)}
|
||||
defaultValue=""
|
||||
value={message}
|
||||
dirName="ltr"
|
||||
autoFocus={true}
|
||||
onChange={onChange}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Send message`)}
|
||||
accessibilityHint=""
|
||||
style={[
|
||||
a.rounded_full,
|
||||
a.align_center,
|
||||
a.justify_center,
|
||||
{height: 30, width: 30, backgroundColor: t.palette.primary_500},
|
||||
]}
|
||||
onPress={onSubmit}>
|
||||
<PaperPlane
|
||||
fill={t.palette.white}
|
||||
style={[a.relative, {left: 1}]}
|
||||
/>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import React, {useEffect, useState} from 'react'
|
||||
import {ActivityIndicator, View} from 'react-native'
|
||||
import {AppBskyEmbedRecord, AppBskyFeedDefs} from '@atproto/api'
|
||||
import {useQuery} from '@tanstack/react-query'
|
||||
|
||||
import {useAgent} from '#/state/session'
|
||||
import {MaybeQuoteEmbed} from '#/view/com/util/post-embeds/QuoteEmbed'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {PostMeta} from '#/view/com/util/PostMeta'
|
||||
import {RichText} from '#/components/RichText'
|
||||
|
||||
export function MessageInputEmbed({
|
||||
message,
|
||||
}: {
|
||||
message: string
|
||||
setMessage: (message: string) => void
|
||||
}) {
|
||||
const {getAgent} = useAgent()
|
||||
const t = useTheme()
|
||||
const [url, setUrl] = useState<string | null>(
|
||||
'https://bsky.app/profile/retr0.id/post/3krylejlvke2j',
|
||||
)
|
||||
|
||||
useEffect(() => {}, [message])
|
||||
|
||||
const query = useQuery({
|
||||
queryKey: ['post-message-embed', url],
|
||||
queryFn: async () => {
|
||||
if (!url) return null
|
||||
const urlp = new URL(url)
|
||||
const [, , didOrHandle, _, rkey] = urlp.pathname.split('/')
|
||||
let did = didOrHandle
|
||||
if (!didOrHandle.startsWith('did:')) {
|
||||
did = (await getAgent().resolveHandle({handle: didOrHandle})).data.did
|
||||
}
|
||||
const uri = `at://${did}/app.bsky.feed.post/${rkey}`
|
||||
const {data} = await getAgent().api.app.bsky.feed.getPostThread({
|
||||
uri,
|
||||
depth: 1,
|
||||
parentHeight: 0,
|
||||
})
|
||||
return data
|
||||
},
|
||||
enabled: !!url,
|
||||
})
|
||||
|
||||
if (!url || query.isError) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (query.isPending) {
|
||||
//temp
|
||||
return <ActivityIndicator />
|
||||
}
|
||||
|
||||
if (query.data) {
|
||||
if (!AppBskyFeedDefs.isThreadViewPost(query.data.thread)) return null
|
||||
return (
|
||||
<View
|
||||
pointerEvents="none"
|
||||
style={(a.border, a.rounded_2xs, t.atoms.border_contrast_high)}>
|
||||
<PostMeta
|
||||
author={query.data.thread.post.author}
|
||||
showAvatar
|
||||
authorHasWarning={false}
|
||||
timestamp={query.data.thread.post.indexedAt}
|
||||
/>
|
||||
{richText ? (
|
||||
<RichText
|
||||
value={richText}
|
||||
style={[a.text_md]}
|
||||
numberOfLines={20}
|
||||
disableLinks
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
Reference in New Issue
Block a user