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.

customHooks.tsx 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright (c) 2019 - 2020 Arnaud Vergnet.
  3. *
  4. * This file is part of Campus INSAT.
  5. *
  6. * Campus INSAT is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Campus INSAT is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import { DependencyList, useEffect, useRef, useState } from 'react';
  20. import { REQUEST_STATUS } from './Requests';
  21. import { ApiRejectType } from './WebData';
  22. export function useMountEffect(func: () => void) {
  23. // eslint-disable-next-line react-hooks/exhaustive-deps
  24. useEffect(func, []);
  25. }
  26. /**
  27. * Effect that does not run on first render
  28. *
  29. * @param effect
  30. * @param deps
  31. */
  32. export function useSubsequentEffect(effect: () => void, deps?: DependencyList) {
  33. const didMountRef = useRef(false);
  34. useEffect(
  35. () => {
  36. if (didMountRef.current) {
  37. effect();
  38. } else {
  39. didMountRef.current = true;
  40. }
  41. },
  42. // eslint-disable-next-line react-hooks/exhaustive-deps
  43. deps ? deps : []
  44. );
  45. }
  46. export function useRequestLogic<T>(
  47. request: () => Promise<T>,
  48. cache?: T,
  49. onCacheUpdate?: (newCache: T) => void,
  50. startLoading?: boolean,
  51. minRefreshTime?: number
  52. ) {
  53. const [response, setResponse] = useState<{
  54. loading: boolean;
  55. lastRefreshDate?: Date;
  56. status: REQUEST_STATUS;
  57. code?: number;
  58. data: T | undefined;
  59. }>({
  60. loading: startLoading !== false && cache === undefined,
  61. lastRefreshDate: undefined,
  62. status: REQUEST_STATUS.SUCCESS,
  63. code: undefined,
  64. data: undefined,
  65. });
  66. const refreshData = (newRequest?: () => Promise<T>) => {
  67. let canRefresh;
  68. if (response.lastRefreshDate && minRefreshTime) {
  69. canRefresh =
  70. new Date().getTime() - response.lastRefreshDate.getTime() >
  71. minRefreshTime;
  72. } else {
  73. canRefresh = true;
  74. }
  75. if (canRefresh) {
  76. if (!response.loading) {
  77. setResponse((prevState) => ({
  78. ...prevState,
  79. loading: true,
  80. }));
  81. }
  82. const r = newRequest ? newRequest : request;
  83. r()
  84. .then((requestResponse: T) => {
  85. setResponse({
  86. loading: false,
  87. lastRefreshDate: new Date(),
  88. status: REQUEST_STATUS.SUCCESS,
  89. code: undefined,
  90. data: requestResponse,
  91. });
  92. if (onCacheUpdate) {
  93. onCacheUpdate(requestResponse);
  94. }
  95. })
  96. .catch((error: ApiRejectType | undefined) => {
  97. if (!error) {
  98. setResponse((prevState) => ({
  99. loading: false,
  100. lastRefreshDate: prevState.lastRefreshDate,
  101. status: REQUEST_STATUS.CONNECTION_ERROR,
  102. code: undefined,
  103. data: prevState.data,
  104. }));
  105. } else {
  106. setResponse((prevState) => ({
  107. loading: false,
  108. lastRefreshDate: prevState.lastRefreshDate,
  109. status: error.status,
  110. code: error.code,
  111. data: prevState.data,
  112. }));
  113. }
  114. });
  115. }
  116. };
  117. const value: [
  118. boolean,
  119. Date | undefined,
  120. REQUEST_STATUS,
  121. number | undefined,
  122. T | undefined,
  123. (newRequest?: () => Promise<T>) => void
  124. ] = [
  125. response.loading,
  126. response.lastRefreshDate,
  127. response.status,
  128. response.code,
  129. cache ? cache : response.data,
  130. refreshData,
  131. ];
  132. return value;
  133. }