1- import { useCallback , useMemo , useState } from 'react' ;
2- import {
3- RefreshControl ,
4- StyleSheet ,
5- useWindowDimensions ,
6- View ,
7- } from 'react-native' ;
1+ import { useCallback , useState } from 'react' ;
2+ import { RefreshControl , useWindowDimensions , View } from 'react-native' ;
83import { FlashList } from '@shopify/flash-list' ;
94import { type PostData } from '@/src/common/lib/polycentric-hooks' ;
105import { Post } from './Post' ;
11- import { usePostById } from './hooks/usePostById' ;
12- import { useThreadReplies } from './hooks/useThreadReplies' ;
6+ import { useThread } from './hooks/useThread' ;
137import { Atoms } from '@/src/common/theme' ;
148import { ComposerInput } from '../composer' ;
15- import { getKeyFingerprint } from '@/src/common/lib/polycentric-hooks/helpers' ;
169
1710interface ConversationViewProps {
1811 post : PostData ;
@@ -22,27 +15,10 @@ export function ConversationView({ post }: ConversationViewProps) {
2215 const [ refreshing , setRefreshing ] = useState ( false ) ;
2316 const { height : windowHeight } = useWindowDimensions ( ) ;
2417
25- const { post : rootPost } = usePostById (
26- post . reply ?. root ?. identity ,
27- getKeyFingerprint ( post . reply ?. root ?. signedBy ) ,
28- BigInt ( post . reply ?. root ?. sequence || '' ) ,
29- ) ;
30- const { post : parentPost } = usePostById (
31- post . reply ?. parent ?. identity ,
32- getKeyFingerprint ( post . reply ?. parent ?. signedBy ) ,
33- BigInt ( post . reply ?. parent ?. sequence || '' ) ,
34- ) ;
35- const { replies } = useThreadReplies ( post ) ;
18+ const { thread } = useThread ( post ) ;
3619
37- const items = useMemo ( ( ) => {
38- const list : PostData [ ] = [ ] ;
39- if ( rootPost ) list . push ( rootPost ) ;
40- // Skip parent if it's the same as root (thread of depth 1).
41- if ( parentPost && parentPost . id !== rootPost ?. id ) list . push ( parentPost ) ;
42- list . push ( post ) ;
43- list . push ( ...replies ) ;
44- return list ;
45- } , [ rootPost , parentPost , post , replies ] ) ;
20+ // Fall back to rendering just the subject until the server response lands.
21+ const items = thread . length > 0 ? thread : [ post ] ;
4622
4723 const handleRefresh = useCallback ( ( ) => {
4824 setRefreshing ( true ) ;
@@ -53,21 +29,27 @@ export function ConversationView({ post }: ConversationViewProps) {
5329 < FlashList
5430 data = { items }
5531 keyExtractor = { ( p ) => p . id }
56- renderItem = { ( { item, index } ) => (
57- < View style = { [ Atoms . w_full ] } >
58- < Post
59- post = { item }
60- hideReplyingTo = { false }
61- disablePress = { item . id === post . id }
62- showThreadLineAbove = { item . id === post . id && ! ! item . reply ?. parent }
63- showThreadLineBelow = {
64- index < items . length - 1 && ! ! post . reply ?. parent
65- }
66- hideBottomBorder = { index < items . length - 1 && ! ! post . reply ?. parent }
67- />
68- { item . id === post . id ? < ComposerInput replyTo = { post . id } /> : null }
69- </ View >
70- ) }
32+ renderItem = { ( { item, index } ) => {
33+ const above = index > 0 ? items [ index - 1 ] : null ;
34+ const below = index < items . length - 1 ? items [ index + 1 ] : null ;
35+ const lineAbove =
36+ ! ! above && item . reply ?. parentId === above . id && above . id !== post . id ;
37+ const lineBelow = ! ! below && below . reply ?. parentId === item . id ;
38+
39+ return (
40+ < View style = { [ Atoms . w_full ] } >
41+ < Post
42+ post = { item }
43+ hideReplyingTo = { false }
44+ disablePress = { item . id === post . id }
45+ showThreadLineAbove = { lineAbove }
46+ showThreadLineBelow = { lineBelow }
47+ hideBottomBorder = { lineBelow }
48+ />
49+ { item . id === post . id ? < ComposerInput replyTo = { post . id } /> : null }
50+ </ View >
51+ ) ;
52+ } }
7153 ListFooterComponent = { < View style = { { height : windowHeight } } /> }
7254 refreshControl = {
7355 < RefreshControl refreshing = { refreshing } onRefresh = { handleRefresh } />
0 commit comments