Scroll to highlighted post in threads

zio/stable
Paul Frazee 2022-11-22 12:56:56 -06:00
parent 8f883d00bc
commit d7b1a2e0ee
2 changed files with 32 additions and 3 deletions

View File

@ -1,4 +1,4 @@
import React, {useState, useEffect} from 'react' import React, {useRef} from 'react'
import {observer} from 'mobx-react-lite' import {observer} from 'mobx-react-lite'
import {ActivityIndicator, FlatList, Text, View} from 'react-native' import {ActivityIndicator, FlatList, Text, View} from 'react-native'
import { import {
@ -16,9 +16,31 @@ export const PostThread = observer(function PostThread({
uri: string uri: string
view: PostThreadViewModel view: PostThreadViewModel
}) { }) {
const ref = useRef<FlatList>(null)
const posts = view.thread ? Array.from(flattenThread(view.thread)) : []
const onRefresh = () => { const onRefresh = () => {
view?.refresh().catch(err => console.error('Failed to refresh', err)) view?.refresh().catch(err => console.error('Failed to refresh', err))
} }
const onLayout = () => {
const index = posts.findIndex(post => post._isHighlightedPost)
if (index !== -1) {
ref.current?.scrollToIndex({
index,
animated: false,
viewOffset: 40,
})
}
}
const onScrollToIndexFailed = (info: {
index: number
highestMeasuredFrameIndex: number
averageItemLength: number
}) => {
ref.current?.scrollToOffset({
animated: false,
offset: info.averageItemLength * info.index,
})
}
// loading // loading
// = // =
@ -47,17 +69,19 @@ export const PostThread = observer(function PostThread({
// loaded // loaded
// = // =
const posts = view.thread ? Array.from(flattenThread(view.thread)) : []
const renderItem = ({item}: {item: PostThreadViewPostModel}) => ( const renderItem = ({item}: {item: PostThreadViewPostModel}) => (
<PostThreadItem item={item} onPostReply={onRefresh} /> <PostThreadItem item={item} onPostReply={onRefresh} />
) )
return ( return (
<FlatList <FlatList
ref={ref}
data={posts} data={posts}
keyExtractor={item => item._reactKey} keyExtractor={item => item._reactKey}
renderItem={renderItem} renderItem={renderItem}
refreshing={view.isRefreshing} refreshing={view.isRefreshing}
onRefresh={onRefresh} onRefresh={onRefresh}
onLayout={onLayout}
onScrollToIndexFailed={onScrollToIndexFailed}
style={{flex: 1}} style={{flex: 1}}
/> />
) )

View File

@ -134,7 +134,12 @@ export const MobileShell: React.FC = observer(() => {
if (store.nav.tab.current.url === '/') { if (store.nav.tab.current.url === '/') {
scrollElRef.current?.scrollToOffset({offset: 0}) scrollElRef.current?.scrollToOffset({offset: 0})
} else { } else {
if (store.nav.tab.canGoBack) {
// sanity check
store.nav.tab.goBackToZero() store.nav.tab.goBackToZero()
} else {
store.nav.navigate('/')
}
} }
} }
const onPressMenu = () => setMainMenuActive(true) const onPressMenu = () => setMainMenuActive(true)