Application Android et IOS pour l'amicale des élèves https://play.google.com/store/apps/details?id=fr.amicaleinsat.application
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RequestScreen.tsx 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import React, { useEffect, useRef } from 'react';
  2. import ErrorView from './ErrorView';
  3. import { useRequestLogic } from '../../utils/customHooks';
  4. import { useFocusEffect } from '@react-navigation/native';
  5. import BasicLoadingScreen from './BasicLoadingScreen';
  6. import i18n from 'i18n-js';
  7. import { REQUEST_STATUS } from '../../utils/Requests';
  8. export type RequestScreenProps<T> = {
  9. request: () => Promise<T>;
  10. render: (
  11. data: T | undefined,
  12. loading: boolean,
  13. refreshData: (newRequest?: () => Promise<T>) => void,
  14. status: REQUEST_STATUS,
  15. code: number | undefined
  16. ) => React.ReactElement;
  17. cache?: T;
  18. onCacheUpdate?: (newCache: T) => void;
  19. onMajorError?: (status: number, code?: number) => void;
  20. showLoading?: boolean;
  21. showError?: boolean;
  22. refreshOnFocus?: boolean;
  23. autoRefreshTime?: number;
  24. refresh?: boolean;
  25. onFinish?: () => void;
  26. };
  27. export type RequestProps = {
  28. refreshData: () => void;
  29. loading: boolean;
  30. };
  31. type Props<T> = RequestScreenProps<T>;
  32. const MIN_REFRESH_TIME = 5 * 1000;
  33. export default function RequestScreen<T>(props: Props<T>) {
  34. const refreshInterval = useRef<number>();
  35. const [loading, status, code, data, refreshData] = useRequestLogic<T>(
  36. () => props.request(),
  37. props.cache,
  38. props.onCacheUpdate,
  39. props.refreshOnFocus,
  40. MIN_REFRESH_TIME
  41. );
  42. // Store last refresh prop value
  43. const lastRefresh = useRef<boolean>(false);
  44. useEffect(() => {
  45. // Refresh data if refresh prop changed and we are not loading
  46. if (props.refresh && !lastRefresh.current && !loading) {
  47. refreshData();
  48. // Call finish callback if refresh prop was set and we finished loading
  49. } else if (lastRefresh.current && !loading && props.onFinish) {
  50. props.onFinish();
  51. }
  52. // Update stored refresh prop value
  53. if (props.refresh !== lastRefresh.current) {
  54. lastRefresh.current = props.refresh === true;
  55. }
  56. }, [props, loading, refreshData]);
  57. useFocusEffect(
  58. React.useCallback(() => {
  59. if (!props.cache && props.refreshOnFocus !== false) {
  60. refreshData();
  61. }
  62. if (props.autoRefreshTime && props.autoRefreshTime > 0) {
  63. refreshInterval.current = setInterval(
  64. refreshData,
  65. props.autoRefreshTime
  66. );
  67. }
  68. return () => {
  69. if (refreshInterval.current) {
  70. clearInterval(refreshInterval.current);
  71. }
  72. };
  73. // eslint-disable-next-line react-hooks/exhaustive-deps
  74. }, [props.cache, props.refreshOnFocus])
  75. );
  76. // useEffect(() => {
  77. // if (status === REQUEST_STATUS.BAD_TOKEN && props.onMajorError) {
  78. // props.onMajorError(status, code);
  79. // }
  80. // // eslint-disable-next-line react-hooks/exhaustive-deps
  81. // }, [status, code]);
  82. // if (status === REQUEST_STATUS.BAD_TOKEN && props.onMajorError) {
  83. // return <View />;
  84. // } else
  85. if (data === undefined && loading && props.showLoading !== false) {
  86. return <BasicLoadingScreen />;
  87. } else if (
  88. data === undefined &&
  89. status !== REQUEST_STATUS.SUCCESS &&
  90. props.showError !== false
  91. ) {
  92. return (
  93. <ErrorView
  94. status={status}
  95. loading={loading}
  96. button={{
  97. icon: 'refresh',
  98. text: i18n.t('general.retry'),
  99. onPress: () => refreshData(),
  100. }}
  101. />
  102. );
  103. } else {
  104. return props.render(data, loading, refreshData, status, code);
  105. }
  106. }