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

View file

@ -67,6 +67,8 @@ type Props<ItemT, RawData> = {
isLoading: boolean
) => React.ReactElement | null;
stickyHeader?: boolean;
cache?: RawData;
onCacheUpdate?: (newCache: RawData) => void;
};
const styles = StyleSheet.create({
@ -200,6 +202,8 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
showLoading={false}
autoRefreshTime={props.autoRefreshTime}
refreshOnFocus={props.refreshOnFocus}
cache={props.cache}
onCacheUpdate={props.onCacheUpdate}
/>
<Snackbar
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,
MainStackParamsList,
} from '../../../navigation/MainNavigator';
import { useCachedProximoArticles } from '../../../utils/cacheContext';
function sortPrice(a: ProximoArticleType, b: ProximoArticleType): number {
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>;
function ProximoListScreen(props: Props) {
const navigation = useNavigation();
const theme = useTheme();
const { articles, setArticles } = useCachedProximoArticles();
const modalRef = useRef<Modalize>();
const [currentSearchString, setCurrentSearchString] = useState('');
@ -367,6 +369,8 @@ function ProximoListScreen(props: Props) {
renderItem={getRenderItem}
updateData={currentSearchString + currentSortMode}
itemHeight={LIST_ITEM_HEIGHT}
cache={articles}
onCacheUpdate={setArticles}
/>
</View>
);

View file

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

View file

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