mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
at session-alignment 110 lines 3.6 kB view raw
1import React from 'react' 2import {StyleSheet, View} from 'react-native' 3import Animated from 'react-native-reanimated' 4import {useFocusEffect} from '@react-navigation/native' 5import {useQueryClient} from '@tanstack/react-query' 6import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types' 7import {makeRecordUri} from 'lib/strings/url-helpers' 8import {PostThread as PostThreadComponent} from '../com/post-thread/PostThread' 9import {ComposePrompt} from 'view/com/composer/Prompt' 10import {s} from 'lib/styles' 11import {useSafeAreaInsets} from 'react-native-safe-area-context' 12import { 13 RQKEY as POST_THREAD_RQKEY, 14 ThreadNode, 15} from '#/state/queries/post-thread' 16import {clamp} from 'lodash' 17import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' 18import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode' 19import {useSetMinimalShellMode} from '#/state/shell' 20import {useResolveUriQuery} from '#/state/queries/resolve-uri' 21import {ErrorMessage} from '../com/util/error/ErrorMessage' 22import {CenteredView} from '../com/util/Views' 23import {useComposerControls} from '#/state/shell/composer' 24import {useSession} from '#/state/session' 25import {isWeb} from '#/platform/detection' 26 27type Props = NativeStackScreenProps<CommonNavigatorParams, 'PostThread'> 28export function PostThreadScreen({route}: Props) { 29 const queryClient = useQueryClient() 30 const {hasSession} = useSession() 31 const {fabMinimalShellTransform} = useMinimalShellMode() 32 const setMinimalShellMode = useSetMinimalShellMode() 33 const {openComposer} = useComposerControls() 34 const safeAreaInsets = useSafeAreaInsets() 35 const {name, rkey} = route.params 36 const {isMobile} = useWebMediaQueries() 37 const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey) 38 const {data: resolvedUri, error: uriError} = useResolveUriQuery(uri) 39 const [canReply, setCanReply] = React.useState(false) 40 41 useFocusEffect( 42 React.useCallback(() => { 43 setMinimalShellMode(false) 44 }, [setMinimalShellMode]), 45 ) 46 47 const onPressReply = React.useCallback(() => { 48 if (!resolvedUri) { 49 return 50 } 51 const thread = queryClient.getQueryData<ThreadNode>( 52 POST_THREAD_RQKEY(resolvedUri.uri), 53 ) 54 if (thread?.type !== 'post') { 55 return 56 } 57 openComposer({ 58 replyTo: { 59 uri: thread.post.uri, 60 cid: thread.post.cid, 61 text: thread.record.text, 62 author: thread.post.author, 63 embed: thread.post.embed, 64 }, 65 onPost: () => 66 queryClient.invalidateQueries({ 67 queryKey: POST_THREAD_RQKEY(resolvedUri.uri || ''), 68 }), 69 }) 70 }, [openComposer, queryClient, resolvedUri]) 71 72 return ( 73 <View style={s.hContentRegion}> 74 <View style={s.flex1}> 75 {uriError ? ( 76 <CenteredView> 77 <ErrorMessage message={String(uriError)} /> 78 </CenteredView> 79 ) : ( 80 <PostThreadComponent 81 uri={resolvedUri?.uri} 82 onPressReply={onPressReply} 83 onCanReply={setCanReply} 84 /> 85 )} 86 </View> 87 {isMobile && canReply && hasSession && ( 88 <Animated.View 89 style={[ 90 styles.prompt, 91 fabMinimalShellTransform, 92 { 93 bottom: clamp(safeAreaInsets.bottom, 15, 30), 94 }, 95 ]}> 96 <ComposePrompt onPressCompose={onPressReply} /> 97 </Animated.View> 98 )} 99 </View> 100 ) 101} 102 103const styles = StyleSheet.create({ 104 prompt: { 105 // @ts-ignore web-only 106 position: isWeb ? 'fixed' : 'absolute', 107 left: 0, 108 right: 0, 109 }, 110})