defer loading of feeds until visible (#1271)

* defer loading of feeds until visible

* Fix: use existing hasLoaded

* Fix: dont query for latest during initial load

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
zio/stable
Eric Bailey 2023-08-24 18:26:29 -05:00 committed by GitHub
parent a5981e127f
commit 4654a9a45e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 37 deletions

View File

@ -272,7 +272,7 @@ export class PostsFeedModel {
* Check if new posts are available * Check if new posts are available
*/ */
async checkForLatest() { async checkForLatest() {
if (this.hasNewLatest || this.isLoading) { if (!this.hasLoaded || this.hasNewLatest || this.isLoading) {
return return
} }
const res = await this._getFeed({limit: 1}) const res = await this._getFeed({limit: 1})

View File

@ -69,14 +69,11 @@ export const Feed = observer(function Feed({
if (feed.loadMoreError) { if (feed.loadMoreError) {
feedItems = feedItems.concat([LOAD_MORE_ERROR_ITEM]) feedItems = feedItems.concat([LOAD_MORE_ERROR_ITEM])
} }
} else if (feed.isLoading) {
feedItems = feedItems.concat([LOADING_ITEM])
} }
return feedItems return feedItems
}, [ }, [
feed.hasError, feed.hasError,
feed.hasLoaded, feed.hasLoaded,
feed.isLoading,
feed.isEmpty, feed.isEmpty,
feed.slices, feed.slices,
feed.loadMoreError, feed.loadMoreError,
@ -97,6 +94,8 @@ export const Feed = observer(function Feed({
}, [feed, track, setIsRefreshing]) }, [feed, track, setIsRefreshing])
const onEndReached = React.useCallback(async () => { const onEndReached = React.useCallback(async () => {
if (!feed.hasLoaded) return
track('Feed:onEndReached') track('Feed:onEndReached')
try { try {
await feed.loadMore() await feed.loadMore()
@ -155,38 +154,36 @@ export const Feed = observer(function Feed({
return ( return (
<View testID={testID} style={style}> <View testID={testID} style={style}>
{data.length > 0 && ( <FlatList
<FlatList testID={testID ? `${testID}-flatlist` : undefined}
testID={testID ? `${testID}-flatlist` : undefined} ref={scrollElRef}
ref={scrollElRef} data={!feed.hasLoaded ? [LOADING_ITEM] : data}
data={data} keyExtractor={item => item._reactKey}
keyExtractor={item => item._reactKey} renderItem={renderItem}
renderItem={renderItem} ListFooterComponent={FeedFooter}
ListFooterComponent={FeedFooter} ListHeaderComponent={ListHeaderComponent}
ListHeaderComponent={ListHeaderComponent} refreshControl={
refreshControl={ <RefreshControl
<RefreshControl refreshing={isRefreshing}
refreshing={isRefreshing} onRefresh={onRefresh}
onRefresh={onRefresh} tintColor={pal.colors.text}
tintColor={pal.colors.text} titleColor={pal.colors.text}
titleColor={pal.colors.text} progressViewOffset={headerOffset}
progressViewOffset={headerOffset} />
/> }
} contentContainerStyle={s.contentContainer}
contentContainerStyle={s.contentContainer} style={{paddingTop: headerOffset}}
style={{paddingTop: headerOffset}} onScroll={onScroll}
onScroll={onScroll} scrollEventThrottle={scrollEventThrottle}
scrollEventThrottle={scrollEventThrottle} indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'}
indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'} onEndReached={onEndReached}
onEndReached={onEndReached} onEndReachedThreshold={0.6}
onEndReachedThreshold={0.6} removeClippedSubviews={true}
removeClippedSubviews={true} contentOffset={{x: 0, y: headerOffset * -1}}
contentOffset={{x: 0, y: headerOffset * -1}} extraData={extraData}
extraData={extraData} // @ts-ignore our .web version only -prf
// @ts-ignore our .web version only -prf desktopFixedHeight
desktopFixedHeight />
/>
)}
</View> </View>
) )
}) })

View File

@ -56,7 +56,6 @@ export const HomeScreen = withAuthRequired(
const feeds = [] const feeds = []
for (const feed of pinned) { for (const feed of pinned) {
const model = new PostsFeedModel(store, 'custom', {feed: feed.uri}) const model = new PostsFeedModel(store, 'custom', {feed: feed.uri})
model.setup()
feeds.push(model) feeds.push(model)
} }
pagerRef.current?.setPage(0) pagerRef.current?.setPage(0)
@ -169,6 +168,13 @@ const FeedPage = observer(
}) })
const isScreenFocused = useIsFocused() const isScreenFocused = useIsFocused()
React.useEffect(() => {
// called on first load
if (!feed.hasLoaded && isPageFocused) {
feed.setup()
}
}, [isPageFocused, feed])
const doPoll = React.useCallback( const doPoll = React.useCallback(
(knownActive = false) => { (knownActive = false) => {
if ( if (