diff options
Diffstat (limited to 'src/view/com/post-thread/PostThread.tsx')
-rw-r--r-- | src/view/com/post-thread/PostThread.tsx | 63 |
1 files changed, 53 insertions, 10 deletions
diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx index 51f63dbb3..e7282cf83 100644 --- a/src/view/com/post-thread/PostThread.tsx +++ b/src/view/com/post-thread/PostThread.tsx @@ -20,25 +20,37 @@ import {ComposePrompt} from '../composer/Prompt' import {ErrorMessage} from '../util/error/ErrorMessage' import {Text} from '../util/text/Text' import {s} from 'lib/styles' -import {isDesktopWeb, isMobileWeb} from 'platform/detection' +import {isIOS, isDesktopWeb, isMobileWeb} from 'platform/detection' import {usePalette} from 'lib/hooks/usePalette' import {useSetTitle} from 'lib/hooks/useSetTitle' import {useNavigation} from '@react-navigation/native' import {NavigationProp} from 'lib/routes/types' import {sanitizeDisplayName} from 'lib/strings/display-names' +const MAINTAIN_VISIBLE_CONTENT_POSITION = {minIndexForVisible: 0} + +const PARENT_SPINNER = { + _reactKey: '__parent_spinner__', + _isHighlightedPost: false, +} const REPLY_PROMPT = {_reactKey: '__reply__', _isHighlightedPost: false} const DELETED = {_reactKey: '__deleted__', _isHighlightedPost: false} const BLOCKED = {_reactKey: '__blocked__', _isHighlightedPost: false} +const CHILD_SPINNER = { + _reactKey: '__child_spinner__', + _isHighlightedPost: false, +} const BOTTOM_COMPONENT = { _reactKey: '__bottom_component__', _isHighlightedPost: false, } type YieldedItem = | PostThreadItemModel + | typeof PARENT_SPINNER | typeof REPLY_PROMPT | typeof DELETED | typeof BLOCKED + | typeof PARENT_SPINNER export const PostThread = observer(function PostThread({ uri, @@ -55,10 +67,19 @@ export const PostThread = observer(function PostThread({ const navigation = useNavigation<NavigationProp>() const posts = React.useMemo(() => { if (view.thread) { - return Array.from(flattenThread(view.thread)).concat([BOTTOM_COMPONENT]) + const arr = Array.from(flattenThread(view.thread)) + if (view.isLoadingFromCache) { + if (view.thread?.postRecord?.reply) { + arr.unshift(PARENT_SPINNER) + } + arr.push(CHILD_SPINNER) + } else { + arr.push(BOTTOM_COMPONENT) + } + return arr } return [] - }, [view.thread]) + }, [view.isLoadingFromCache, view.thread]) useSetTitle( view.thread?.postRecord && `${sanitizeDisplayName( @@ -80,17 +101,15 @@ export const PostThread = observer(function PostThread({ setIsRefreshing(false) }, [view, setIsRefreshing]) - const onLayout = React.useCallback(() => { + const onContentSizeChange = React.useCallback(() => { const index = posts.findIndex(post => post._isHighlightedPost) if (index !== -1) { ref.current?.scrollToIndex({ index, animated: false, - viewOffset: 40, }) } }, [posts, ref]) - const onScrollToIndexFailed = React.useCallback( (info: { index: number @@ -115,7 +134,13 @@ export const PostThread = observer(function PostThread({ const renderItem = React.useCallback( ({item}: {item: YieldedItem}) => { - if (item === REPLY_PROMPT) { + if (item === PARENT_SPINNER) { + return ( + <View style={styles.parentSpinner}> + <ActivityIndicator /> + </View> + ) + } else if (item === REPLY_PROMPT) { return <ComposePrompt onPressCompose={onPressReply} /> } else if (item === DELETED) { return ( @@ -150,6 +175,12 @@ export const PostThread = observer(function PostThread({ ]} /> ) + } else if (item === CHILD_SPINNER) { + return ( + <View style={styles.childSpinner}> + <ActivityIndicator /> + </View> + ) } else if (item instanceof PostThreadItemModel) { return <PostThreadItem item={item} onPostReply={onRefresh} /> } @@ -247,6 +278,9 @@ export const PostThread = observer(function PostThread({ ref={ref} data={posts} initialNumToRender={posts.length} + maintainVisibleContentPosition={ + view.isFromCache ? MAINTAIN_VISIBLE_CONTENT_POSITION : undefined + } keyExtractor={item => item._reactKey} renderItem={renderItem} refreshControl={ @@ -257,10 +291,12 @@ export const PostThread = observer(function PostThread({ titleColor={pal.colors.text} /> } - onLayout={onLayout} + onContentSizeChange={ + !isIOS || !view.isFromCache ? onContentSizeChange : undefined + } onScrollToIndexFailed={onScrollToIndexFailed} style={s.hContentRegion} - contentContainerStyle={s.contentContainerExtra} + contentContainerStyle={styles.contentContainerExtra} /> ) }) @@ -307,10 +343,17 @@ const styles = StyleSheet.create({ paddingHorizontal: 18, paddingVertical: 18, }, + parentSpinner: { + paddingVertical: 10, + }, + childSpinner: {}, bottomBorder: { borderBottomWidth: 1, }, bottomSpacer: { - height: 200, + height: 400, + }, + contentContainerExtra: { + paddingBottom: 500, }, }) |