(wip) add message input embed component

This commit is contained in:
Samuel Newman
2024-05-08 22:37:36 +01:00
parent f62b0458a7
commit 5b5edaf69f
3 changed files with 159 additions and 66 deletions
@@ -16,6 +16,7 @@ import {HITSLOP_10} from '#/lib/constants'
import {useHaptics} from 'lib/haptics' import {useHaptics} from 'lib/haptics'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane' import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane'
import {MessageInputEmbed} from './MessageInputEmbed'
export function MessageInput({ export function MessageInput({
onSendMessage, onSendMessage,
@@ -68,43 +69,48 @@ export function MessageInput({
<View <View
style={[ style={[
a.w_full, a.w_full,
a.flex_row,
a.py_sm, a.py_sm,
a.px_sm, a.px_sm,
a.pl_md, a.pl_md,
t.atoms.bg_contrast_25, t.atoms.bg_contrast_25,
{borderRadius: 23}, {borderRadius: 23},
]}> ]}>
<TextInput <MessageInputEmbed message={message} setMessage={setMessage} />
accessibilityLabel={_(msg`Message input field`)} <View style={a.flex_row}>
accessibilityHint={_(msg`Type your message here`)} <TextInput
placeholder={_(msg`Write a message`)} accessibilityLabel={_(msg`Message input field`)}
placeholderTextColor={t.palette.contrast_500} accessibilityHint={_(msg`Type your message here`)}
value={message} placeholder={_(msg`Write a message`)}
multiline={true} placeholderTextColor={t.palette.contrast_500}
onChangeText={setMessage} value={message}
style={[a.flex_1, a.text_md, a.px_sm, t.atoms.text, {maxHeight}]} multiline={true}
keyboardAppearance={t.name === 'light' ? 'light' : 'dark'} onChangeText={setMessage}
scrollEnabled={isInputScrollable} style={[a.flex_1, a.text_md, a.px_sm, t.atoms.text, {maxHeight}]}
blurOnSubmit={false} keyboardAppearance={t.name === 'light' ? 'light' : 'dark'}
onFocus={scrollToEnd} scrollEnabled={isInputScrollable}
onContentSizeChange={onInputLayout} blurOnSubmit={false}
ref={inputRef} onFocus={scrollToEnd}
/> onContentSizeChange={onInputLayout}
<Pressable ref={inputRef}
accessibilityRole="button" />
accessibilityLabel={_(msg`Send message`)} <Pressable
accessibilityHint="" accessibilityRole="button"
hitSlop={HITSLOP_10} accessibilityLabel={_(msg`Send message`)}
style={[ accessibilityHint=""
a.rounded_full, hitSlop={HITSLOP_10}
a.align_center, style={[
a.justify_center, a.rounded_full,
{height: 30, width: 30, backgroundColor: t.palette.primary_500}, a.align_center,
]} a.justify_center,
onPress={onSubmit}> {height: 30, width: 30, backgroundColor: t.palette.primary_500},
<PaperPlane fill={t.palette.white} style={[a.relative, {left: 1}]} /> ]}
</Pressable> onPress={onSubmit}>
<PaperPlane
fill={t.palette.white}
style={[a.relative, {left: 1}]}
/>
</Pressable>
</View>
</View> </View>
</View> </View>
) )
@@ -6,6 +6,7 @@ import TextareaAutosize from 'react-textarea-autosize'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane' import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane'
import {MessageInputEmbed} from './MessageInputEmbed'
export function MessageInput({ export function MessageInput({
onSendMessage, onSendMessage,
@@ -47,47 +48,52 @@ export function MessageInput({
<View style={a.p_sm}> <View style={a.p_sm}>
<View <View
style={[ style={[
a.flex_row,
a.py_sm, a.py_sm,
a.px_sm, a.px_sm,
a.pl_md, a.pl_md,
t.atoms.bg_contrast_25, t.atoms.bg_contrast_25,
{borderRadius: 23}, {borderRadius: 23},
]}> ]}>
<TextareaAutosize <MessageInputEmbed message={message} setMessage={setMessage} />
style={StyleSheet.flatten([ <View style={a.flex_row}>
a.flex_1, <TextareaAutosize
a.px_sm, style={StyleSheet.flatten([
a.border_0, a.flex_1,
t.atoms.text, a.px_sm,
{ a.border_0,
backgroundColor: 'transparent', t.atoms.text,
resize: 'none', {
paddingTop: 4, backgroundColor: 'transparent',
}, resize: 'none',
])} paddingTop: 4,
maxRows={12} },
placeholder={_(msg`Write a message`)} ])}
defaultValue="" maxRows={12}
value={message} placeholder={_(msg`Write a message`)}
dirName="ltr" defaultValue=""
autoFocus={true} value={message}
onChange={onChange} dirName="ltr"
onKeyDown={onKeyDown} autoFocus={true}
/> onChange={onChange}
<Pressable onKeyDown={onKeyDown}
accessibilityRole="button" />
accessibilityLabel={_(msg`Send message`)} <Pressable
accessibilityHint="" accessibilityRole="button"
style={[ accessibilityLabel={_(msg`Send message`)}
a.rounded_full, accessibilityHint=""
a.align_center, style={[
a.justify_center, a.rounded_full,
{height: 30, width: 30, backgroundColor: t.palette.primary_500}, a.align_center,
]} a.justify_center,
onPress={onSubmit}> {height: 30, width: 30, backgroundColor: t.palette.primary_500},
<PaperPlane fill={t.palette.white} style={[a.relative, {left: 1}]} /> ]}
</Pressable> onPress={onSubmit}>
<PaperPlane
fill={t.palette.white}
style={[a.relative, {left: 1}]}
/>
</Pressable>
</View>
</View> </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
}