Compare commits

...

4 commits

Author SHA1 Message Date
Arnaud Vergnet
50c62dd676 fix state update 2021-05-13 10:32:44 +02:00
Arnaud Vergnet
6516cf918d remove log 2021-05-13 10:27:25 +02:00
Arnaud Vergnet
e7cffde198 Remove annoying snackbar 2021-05-13 10:27:01 +02:00
Arnaud Vergnet
c1dd69d0ed move last refresh date in request screen 2021-05-13 09:59:38 +02:00
5 changed files with 60 additions and 80 deletions

View file

@ -132,7 +132,11 @@ function getMessage(props: Props) {
} }
} }
fullMessage.message += `\n\nCode {${props.status}:${props.code}}`; if (props.code !== undefined) {
fullMessage.message += `\n\nCode {${props.status}:${props.code}}`;
} else {
fullMessage.message += `\n\nCode {${props.status}}`;
}
if (props.message != null) { if (props.message != null) {
fullMessage.message = props.message; fullMessage.message = props.message;
} }

View file

@ -11,6 +11,7 @@ export type RequestScreenProps<T> = {
render: ( render: (
data: T | undefined, data: T | undefined,
loading: boolean, loading: boolean,
lastRefreshDate: Date | undefined,
refreshData: (newRequest?: () => Promise<T>) => void, refreshData: (newRequest?: () => Promise<T>) => void,
status: REQUEST_STATUS, status: REQUEST_STATUS,
code?: REQUEST_CODES code?: REQUEST_CODES
@ -37,8 +38,15 @@ const MIN_REFRESH_TIME = 5 * 1000;
export default function RequestScreen<T>(props: Props<T>) { export default function RequestScreen<T>(props: Props<T>) {
const refreshInterval = useRef<number>(); const refreshInterval = useRef<number>();
const [loading, status, code, data, refreshData] = useRequestLogic<T>( const [
() => props.request(), loading,
lastRefreshDate,
status,
code,
data,
refreshData,
] = useRequestLogic<T>(
props.request,
props.cache, props.cache,
props.onCacheUpdate, props.onCacheUpdate,
props.refreshOnFocus, props.refreshOnFocus,
@ -81,16 +89,6 @@ export default function RequestScreen<T>(props: Props<T>) {
}, [props.cache, props.refreshOnFocus]) }, [props.cache, props.refreshOnFocus])
); );
// useEffect(() => {
// if (status === REQUEST_STATUS.BAD_TOKEN && props.onMajorError) {
// props.onMajorError(status, code);
// }
// // eslint-disable-next-line react-hooks/exhaustive-deps
// }, [status, code]);
// if (status === REQUEST_STATUS.BAD_TOKEN && props.onMajorError) {
// return <View />;
// } else
if (data === undefined && loading && props.showLoading !== false) { if (data === undefined && loading && props.showLoading !== false) {
return <BasicLoadingScreen />; return <BasicLoadingScreen />;
} else if ( } else if (
@ -110,6 +108,13 @@ export default function RequestScreen<T>(props: Props<T>) {
/> />
); );
} else { } else {
return props.render(data, loading, refreshData, status, code); return props.render(
data,
loading,
lastRefreshDate,
refreshData,
status,
code
);
} }
} }

View file

@ -17,20 +17,16 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/ */
import React, { useState } from 'react'; import React from 'react';
import i18n from 'i18n-js'; import i18n from 'i18n-js';
import { Snackbar } from 'react-native-paper';
import { import {
RefreshControl, RefreshControl,
SectionListData, SectionListData,
SectionListProps, SectionListProps,
StyleSheet, StyleSheet,
View,
} from 'react-native'; } from 'react-native';
import ErrorView from './ErrorView'; import ErrorView from './ErrorView';
import { TAB_BAR_HEIGHT } from '../Tabbar/CustomTabBar';
import CollapsibleSectionList from '../Collapsible/CollapsibleSectionList'; import CollapsibleSectionList from '../Collapsible/CollapsibleSectionList';
import GENERAL_STYLES from '../../constants/Styles';
import RequestScreen, { RequestScreenProps } from './RequestScreen'; import RequestScreen, { RequestScreenProps } from './RequestScreen';
import { CollapsibleComponentPropsType } from '../Collapsible/CollapsibleComponent'; import { CollapsibleComponentPropsType } from '../Collapsible/CollapsibleComponent';
import { REQUEST_CODES, REQUEST_STATUS } from '../../utils/Requests'; import { REQUEST_CODES, REQUEST_STATUS } from '../../utils/Requests';
@ -62,6 +58,7 @@ type Props<ItemT, RawData> = Omit<
createDataset: ( createDataset: (
data: RawData | undefined, data: RawData | undefined,
loading: boolean, loading: boolean,
lastRefreshDate: Date | undefined,
refreshData: (newRequest?: () => Promise<RawData>) => void, refreshData: (newRequest?: () => Promise<RawData>) => void,
status: REQUEST_STATUS, status: REQUEST_STATUS,
code?: REQUEST_CODES code?: REQUEST_CODES
@ -69,6 +66,7 @@ type Props<ItemT, RawData> = Omit<
renderListHeaderComponent?: ( renderListHeaderComponent?: (
data: RawData | undefined, data: RawData | undefined,
loading: boolean, loading: boolean,
lastRefreshDate: Date | undefined,
refreshData: (newRequest?: () => Promise<RawData>) => void, refreshData: (newRequest?: () => Promise<RawData>) => void,
status: REQUEST_STATUS, status: REQUEST_STATUS,
code?: REQUEST_CODES code?: REQUEST_CODES
@ -87,12 +85,6 @@ const styles = StyleSheet.create({
* To force the component to update, change the value of updateData. * To force the component to update, change the value of updateData.
*/ */
function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) { function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
const [snackbarVisible, setSnackbarVisible] = useState(false);
const showSnackBar = () => setSnackbarVisible(true);
const hideSnackBar = () => setSnackbarVisible(false);
const getItemLayout = ( const getItemLayout = (
height: number, height: number,
_data: Array<SectionListData<ItemT>> | null, _data: Array<SectionListData<ItemT>> | null,
@ -108,6 +100,7 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
const render = ( const render = (
data: RawData | undefined, data: RawData | undefined,
loading: boolean, loading: boolean,
lastRefreshDate: Date | undefined,
refreshData: (newRequest?: () => Promise<RawData>) => void, refreshData: (newRequest?: () => Promise<RawData>) => void,
status: REQUEST_STATUS, status: REQUEST_STATUS,
code?: REQUEST_CODES code?: REQUEST_CODES
@ -116,13 +109,11 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
const dataset = props.createDataset( const dataset = props.createDataset(
data, data,
loading, loading,
lastRefreshDate,
refreshData, refreshData,
status, status,
code code
); );
if (!data && !loading) {
showSnackBar();
}
return ( return (
<CollapsibleSectionList <CollapsibleSectionList
{...props} {...props}
@ -143,6 +134,7 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
? props.renderListHeaderComponent( ? props.renderListHeaderComponent(
data, data,
loading, loading,
lastRefreshDate,
refreshData, refreshData,
status, status,
code code
@ -157,7 +149,7 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
button={{ button={{
icon: 'refresh', icon: 'refresh',
text: i18n.t('general.retry'), text: i18n.t('general.retry'),
onPress: refreshData, onPress: () => refreshData(),
}} }}
/> />
) )
@ -170,32 +162,16 @@ function WebSectionList<ItemT, RawData>(props: Props<ItemT, RawData>) {
}; };
return ( return (
<View style={GENERAL_STYLES.flex}> <RequestScreen<RawData>
<RequestScreen<RawData> request={props.request}
request={props.request} render={render}
render={render} showError={false}
showError={false} showLoading={false}
showLoading={false} autoRefreshTime={props.autoRefreshTime}
autoRefreshTime={props.autoRefreshTime} refreshOnFocus={props.refreshOnFocus}
refreshOnFocus={props.refreshOnFocus} cache={props.cache}
cache={props.cache} onCacheUpdate={props.onCacheUpdate}
onCacheUpdate={props.onCacheUpdate} />
/>
<Snackbar
visible={snackbarVisible}
onDismiss={hideSnackBar}
action={{
label: 'OK',
onPress: hideSnackBar,
}}
duration={4000}
style={{
bottom: TAB_BAR_HEIGHT,
}}
>
{i18n.t('general.listUpdateFail')}
</Snackbar>
</View>
); );
} }

View file

@ -52,7 +52,6 @@ import GENERAL_STYLES from '../../constants/Styles';
import { readData } from '../../utils/WebData'; import { readData } from '../../utils/WebData';
import { useFocusEffect, useNavigation } from '@react-navigation/core'; import { useFocusEffect, useNavigation } from '@react-navigation/core';
import { setupMachineNotification } from '../../utils/Notifications'; import { setupMachineNotification } from '../../utils/Notifications';
import { REQUEST_STATUS } from '../../utils/Requests';
import ProximoListHeader from '../../components/Lists/Proximo/ProximoListHeader'; import ProximoListHeader from '../../components/Lists/Proximo/ProximoListHeader';
const REFRESH_TIME = 1000 * 10; // Refresh every 10 seconds const REFRESH_TIME = 1000 * 10; // Refresh every 10 seconds
@ -110,8 +109,6 @@ function ProxiwashScreen() {
) as 'tripodeB' | 'washinsa' ) as 'tripodeB' | 'washinsa'
); );
const lastrefreshDate = useRef<Date | undefined>(undefined);
const modalStateStrings: { [key in MachineStates]: string } = { const modalStateStrings: { [key in MachineStates]: string } = {
[MachineStates.AVAILABLE]: i18n.t('screens.proxiwash.modal.ready'), [MachineStates.AVAILABLE]: i18n.t('screens.proxiwash.modal.ready'),
[MachineStates.RUNNING]: i18n.t('screens.proxiwash.modal.running'), [MachineStates.RUNNING]: i18n.t('screens.proxiwash.modal.running'),
@ -418,21 +415,17 @@ function ProxiwashScreen() {
}; };
const renderListHeaderComponent = ( const renderListHeaderComponent = (
_data: FetchedDataType | undefined, data: FetchedDataType | undefined,
loading: boolean, _loading: boolean,
_refreshData: (newRequest?: () => Promise<FetchedDataType>) => void, lastRefreshDate: Date | undefined
status: REQUEST_STATUS
) => { ) => {
const success = status === REQUEST_STATUS.SUCCESS; if (data) {
if (success && !loading) { return (
lastrefreshDate.current = new Date(); <ProximoListHeader date={lastRefreshDate} selectedWash={selectedWash} />
);
} else {
return null;
} }
return (
<ProximoListHeader
date={lastrefreshDate.current}
selectedWash={selectedWash}
/>
);
}; };
let data: LaundromatType; let data: LaundromatType;

View file

@ -55,24 +55,24 @@ export function useRequestLogic<T>(
) { ) {
const [response, setResponse] = useState<{ const [response, setResponse] = useState<{
loading: boolean; loading: boolean;
lastRefreshDate?: Date;
status: REQUEST_STATUS; status: REQUEST_STATUS;
code?: number; code?: number;
data: T | undefined; data: T | undefined;
}>({ }>({
loading: startLoading !== false && cache === undefined, loading: startLoading !== false && cache === undefined,
lastRefreshDate: undefined,
status: REQUEST_STATUS.SUCCESS, status: REQUEST_STATUS.SUCCESS,
code: undefined, code: undefined,
data: undefined, data: undefined,
}); });
const [lastRefreshDate, setLastRefreshDate] = useState<Date | undefined>(
undefined
);
const refreshData = (newRequest?: () => Promise<T>) => { const refreshData = (newRequest?: () => Promise<T>) => {
let canRefresh; let canRefresh;
if (lastRefreshDate && minRefreshTime) { if (response.lastRefreshDate && minRefreshTime) {
const last = lastRefreshDate; canRefresh =
canRefresh = new Date().getTime() - last.getTime() > minRefreshTime; new Date().getTime() - response.lastRefreshDate.getTime() >
minRefreshTime;
} else { } else {
canRefresh = true; canRefresh = true;
} }
@ -83,12 +83,12 @@ export function useRequestLogic<T>(
loading: true, loading: true,
})); }));
} }
setLastRefreshDate(new Date());
const r = newRequest ? newRequest : request; const r = newRequest ? newRequest : request;
r() r()
.then((requestResponse: T) => { .then((requestResponse: T) => {
setResponse({ setResponse({
loading: false, loading: false,
lastRefreshDate: new Date(),
status: REQUEST_STATUS.SUCCESS, status: REQUEST_STATUS.SUCCESS,
code: undefined, code: undefined,
data: requestResponse, data: requestResponse,
@ -100,23 +100,25 @@ export function useRequestLogic<T>(
.catch(() => { .catch(() => {
setResponse((prevState) => ({ setResponse((prevState) => ({
loading: false, loading: false,
lastRefreshDate: prevState.lastRefreshDate,
status: REQUEST_STATUS.CONNECTION_ERROR, status: REQUEST_STATUS.CONNECTION_ERROR,
code: 0, code: undefined,
data: prevState.data, data: prevState.data,
})); }));
setLastRefreshDate(undefined);
}); });
} }
}; };
const value: [ const value: [
boolean, boolean,
Date | undefined,
REQUEST_STATUS, REQUEST_STATUS,
number | undefined, number | undefined,
T | undefined, T | undefined,
(newRequest?: () => Promise<T>) => void (newRequest?: () => Promise<T>) => void
] = [ ] = [
response.loading, response.loading,
response.lastRefreshDate,
response.status, response.status,
response.code, response.code,
cache ? cache : response.data, cache ? cache : response.data,