add session cache for proximo data

This commit is contained in:
Arnaud Vergnet 2021-05-10 15:14:55 +02:00
parent a94006d18a
commit 2f1c64e6f9
6 changed files with 120 additions and 31 deletions

45
App.tsx
View file

@ -38,6 +38,7 @@ import initLocales from './src/utils/Locales';
import { NavigationContainerRef } from '@react-navigation/core'; import { NavigationContainerRef } from '@react-navigation/core';
import GENERAL_STYLES from './src/constants/Styles'; import GENERAL_STYLES from './src/constants/Styles';
import CollapsibleProvider from './src/components/providers/CollapsibleProvider'; import CollapsibleProvider from './src/components/providers/CollapsibleProvider';
import CacheProvider from './src/components/providers/CacheProvider';
// Native optimizations https://reactnavigation.org/docs/react-native-screens // Native optimizations https://reactnavigation.org/docs/react-native-screens
// Crashes app when navigating away from webview on android 9+ // Crashes app when navigating away from webview on android 9+
@ -212,27 +213,29 @@ export default class App extends React.Component<{}, StateType> {
return ( return (
<PaperProvider theme={state.currentTheme}> <PaperProvider theme={state.currentTheme}>
<CollapsibleProvider> <CollapsibleProvider>
<OverflowMenuProvider> <CacheProvider>
<View <OverflowMenuProvider>
style={{ <View
backgroundColor: ThemeManager.getCurrentTheme().colors style={{
.background, backgroundColor: ThemeManager.getCurrentTheme().colors
...GENERAL_STYLES.flex, .background,
}} ...GENERAL_STYLES.flex,
> }}
<SafeAreaView style={GENERAL_STYLES.flex}> >
<NavigationContainer <SafeAreaView style={GENERAL_STYLES.flex}>
theme={state.currentTheme} <NavigationContainer
ref={this.navigatorRef} theme={state.currentTheme}
> ref={this.navigatorRef}
<MainNavigator >
defaultHomeRoute={this.defaultHomeRoute} <MainNavigator
defaultHomeData={this.defaultHomeData} defaultHomeRoute={this.defaultHomeRoute}
/> defaultHomeData={this.defaultHomeData}
</NavigationContainer> />
</SafeAreaView> </NavigationContainer>
</View> </SafeAreaView>
</OverflowMenuProvider> </View>
</OverflowMenuProvider>
</CacheProvider>
</CollapsibleProvider> </CollapsibleProvider>
</PaperProvider> </PaperProvider>
); );

View file

@ -67,6 +67,8 @@ type Props<ItemT, RawData> = {
isLoading: boolean isLoading: boolean
) => React.ReactElement | null; ) => React.ReactElement | null;
stickyHeader?: boolean; stickyHeader?: boolean;
cache?: RawData;
onCacheUpdate?: (newCache: RawData) => void;
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -200,6 +202,8 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
showLoading={false} showLoading={false}
autoRefreshTime={props.autoRefreshTime} autoRefreshTime={props.autoRefreshTime}
refreshOnFocus={props.refreshOnFocus} refreshOnFocus={props.refreshOnFocus}
cache={props.cache}
onCacheUpdate={props.onCacheUpdate}
/> />
<Snackbar <Snackbar
visible={snackbarVisible} visible={snackbarVisible}

View file

@ -0,0 +1,41 @@
import React, { useState } from 'react';
import {
CacheContext,
CacheContextType,
CacheType,
} from '../../utils/cacheContext';
type Props = {
children: React.ReactChild;
};
export default function CacheProvider(props: Props) {
const setCache = (newCache: CacheType) => {
setCacheState((prevState) => ({
...prevState,
cache: {
...prevState.cache,
...newCache,
},
}));
};
const resetCache = () => {
setCacheState((prevState) => ({
...prevState,
cache: undefined,
}));
};
const [cacheState, setCacheState] = useState<CacheContextType>({
cache: undefined,
setCache: setCache,
resetCache: resetCache,
});
return (
<CacheContext.Provider value={cacheState}>
{props.children}
</CacheContext.Provider>
);
}

View file

@ -48,6 +48,7 @@ import {
MainRoutes, MainRoutes,
MainStackParamsList, MainStackParamsList,
} from '../../../navigation/MainNavigator'; } from '../../../navigation/MainNavigator';
import { useCachedProximoArticles } from '../../../utils/cacheContext';
function sortPrice(a: ProximoArticleType, b: ProximoArticleType): number { function sortPrice(a: ProximoArticleType, b: ProximoArticleType): number {
return a.price - b.price; return a.price - b.price;
@ -110,13 +111,14 @@ const styles = StyleSheet.create({
}, },
}); });
type ArticlesType = Array<ProximoArticleType>; export type ArticlesType = Array<ProximoArticleType>;
type Props = StackScreenProps<MainStackParamsList, MainRoutes.ProximoList>; type Props = StackScreenProps<MainStackParamsList, MainRoutes.ProximoList>;
function ProximoListScreen(props: Props) { function ProximoListScreen(props: Props) {
const navigation = useNavigation(); const navigation = useNavigation();
const theme = useTheme(); const theme = useTheme();
const { articles, setArticles } = useCachedProximoArticles();
const modalRef = useRef<Modalize>(); const modalRef = useRef<Modalize>();
const [currentSearchString, setCurrentSearchString] = useState(''); const [currentSearchString, setCurrentSearchString] = useState('');
@ -367,6 +369,8 @@ function ProximoListScreen(props: Props) {
renderItem={getRenderItem} renderItem={getRenderItem}
updateData={currentSearchString + currentSortMode} updateData={currentSearchString + currentSortMode}
itemHeight={LIST_ITEM_HEIGHT} itemHeight={LIST_ITEM_HEIGHT}
cache={articles}
onCacheUpdate={setArticles}
/> />
</View> </View>
); );

View file

@ -30,6 +30,7 @@ import Urls from '../../../constants/Urls';
import { readData } from '../../../utils/WebData'; import { readData } from '../../../utils/WebData';
import { useNavigation } from '@react-navigation/core'; import { useNavigation } from '@react-navigation/core';
import { useLayoutEffect } from 'react'; import { useLayoutEffect } from 'react';
import { useCachedProximoCategories } from '../../../utils/cacheContext';
const LIST_ITEM_HEIGHT = 84; const LIST_ITEM_HEIGHT = 84;
@ -55,7 +56,7 @@ export type ProximoArticleType = {
category: ProximoCategoryType; category: ProximoCategoryType;
}; };
type CategoriesType = Array<ProximoCategoryType>; export type CategoriesType = Array<ProximoCategoryType>;
const styles = StyleSheet.create({ const styles = StyleSheet.create({
item: { item: {
@ -92,6 +93,7 @@ function sortFinalData(a: ProximoCategoryType, b: ProximoCategoryType): number {
function ProximoMainScreen() { function ProximoMainScreen() {
const navigation = useNavigation(); const navigation = useNavigation();
const theme = useTheme(); const theme = useTheme();
const { categories, setCategories } = useCachedProximoCategories();
useLayoutEffect(() => { useLayoutEffect(() => {
navigation.setOptions({ navigation.setOptions({
@ -233,6 +235,8 @@ function ProximoMainScreen() {
createDataset={createDataset} createDataset={createDataset}
refreshOnFocus={true} refreshOnFocus={true}
renderItem={getRenderItem} renderItem={getRenderItem}
cache={categories}
onCacheUpdate={setCategories}
/> />
); );
} }

View file

@ -1,21 +1,54 @@
import React, { useContext } from 'react'; import React, { useContext } from 'react';
import { ArticlesType } from '../screens/Services/Proximo/ProximoListScreen';
import { CategoriesType } from '../screens/Services/Proximo/ProximoMainScreen';
export type CacheContextType<T> = { export type CacheType = {
cache: T | undefined; proximo?: {
setCache: (newCache: T) => void; articles?: ArticlesType;
categories?: CategoriesType;
};
};
export type CacheContextType = {
cache: CacheType | undefined;
setCache: (newCache: CacheType) => void;
resetCache: () => void; resetCache: () => void;
}; };
export const CacheContext = React.createContext<CacheContextType<any>>({ export const CacheContext = React.createContext<CacheContextType>({
cache: undefined, cache: undefined,
setCache: () => undefined, setCache: () => undefined,
resetCache: () => undefined, resetCache: () => undefined,
}); });
function getCacheContext<T>() { export function useCache() {
return CacheContext as React.Context<CacheContextType<T>>; return useContext(CacheContext);
} }
export function useCache<T>() { export function useCachedProximoCategories() {
return useContext(getCacheContext<T>()); const { cache, setCache } = useCache();
const categories = cache?.proximo?.categories;
const setCategories = (newCategories: CategoriesType) => {
setCache({
proximo: {
categories: newCategories,
articles: cache?.proximo?.articles,
},
});
};
return { categories, setCategories };
}
export function useCachedProximoArticles() {
const { cache, setCache } = useCache();
const articles = cache?.proximo?.articles;
const setArticles = (newArticles: ArticlesType) => {
setCache({
proximo: {
categories: cache?.proximo?.categories,
articles: newArticles,
},
});
};
return { articles, setArticles };
} }