From 3be90245558cfe71c6bb17d2bbb78c6a4c8e7048 Mon Sep 17 00:00:00 2001 From: Aleksandr Lushkin Date: Thu, 8 Aug 2024 15:11:17 +0200 Subject: [PATCH] Client: Groups: Fix loaders --- .../CreateEditGroupDialog/EditGroupDialog.tsx | 92 +++++++++++---- .../Home/InfoPanel/Body/views/Groups/index.js | 110 +++++++++++------- 2 files changed, 137 insertions(+), 65 deletions(-) diff --git a/packages/client/src/components/dialogs/CreateEditGroupDialog/EditGroupDialog.tsx b/packages/client/src/components/dialogs/CreateEditGroupDialog/EditGroupDialog.tsx index a79cb2d6d5..bfc3b0084d 100644 --- a/packages/client/src/components/dialogs/CreateEditGroupDialog/EditGroupDialog.tsx +++ b/packages/client/src/components/dialogs/CreateEditGroupDialog/EditGroupDialog.tsx @@ -24,7 +24,7 @@ // content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode -import { ChangeEvent, useEffect, useState } from "react"; +import { ChangeEvent, useEffect, useRef, useState } from "react"; import { inject, observer } from "mobx-react"; import { useTranslation } from "react-i18next"; @@ -34,6 +34,10 @@ import { ModalDialogType, } from "@docspace/shared/components/modal-dialog"; import { TGroup } from "@docspace/shared/api/groups/types"; +import { + MIN_LOADER_TIMER, + SHOW_LOADER_TIMER, +} from "@docspace/shared/selectors/Files/FilesSelector.constants"; import EditGroupStore from "SRC_DIR/store/EditGroupStore"; import { StyledModal } from "./CreateEditGroupDialog.styled"; @@ -101,6 +105,10 @@ const EditGroupDialog = ({ useState(false); const [selectMembersPanelIsVisible, setSelectMembersPanelIsVisible] = useState(false); + const [showLoader, setShowLoader] = useState(false); + + const loaderTimeout = useRef(null); + const startLoaderTime = useRef(null); const onChangeGroupName = (e: ChangeEvent) => { setTitle(e.target.value); @@ -136,6 +144,38 @@ const EditGroupDialog = ({ }; }, []); + useEffect(() => { + if (!isInit) { + loaderTimeout.current = setTimeout(() => { + startLoaderTime.current = new Date(); + setShowLoader(true); + }, SHOW_LOADER_TIMER); + } else if (startLoaderTime.current) { + const currentDate = new Date(); + + const ms = Math.abs( + startLoaderTime.current.getTime() - currentDate.getTime(), + ); + + if (ms >= MIN_LOADER_TIMER) { + startLoaderTime.current = null; + return setShowLoader(false); + } + + setTimeout(() => { + if (isInit) { + startLoaderTime.current = null; + setShowLoader(false); + } + }, MIN_LOADER_TIMER - ms); + + loaderTimeout.current = null; + } else if (loaderTimeout.current) { + clearTimeout(loaderTimeout.current); + loaderTimeout.current = null; + } + }, [isInit]); + const notEnoughParamsToEdit = !title || (!manager && !members?.length); return ( @@ -152,31 +192,33 @@ const EditGroupDialog = ({ - {isInit ? ( - <> - - - - - - ) : ( + {showLoader ? ( + ) : ( + isInit && ( + <> + + + + + + ) )} diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/index.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/index.js index f250e63b2b..ce23ad8fb3 100644 --- a/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/index.js +++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/index.js @@ -27,13 +27,16 @@ import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; import { useParams } from "react-router-dom"; -import { useState, useEffect } from "react"; +import { useState, useEffect, useRef } from "react"; import withLoader from "@docspace/client/src/HOCs/withLoader"; import InfoPanelViewLoader from "@docspace/shared/skeletons/info-panel/body"; import api from "@docspace/shared/api"; import AccountsFilter from "@docspace/shared/api/people/filter"; -import { MIN_LOADER_TIMER } from "@docspace/shared/selectors/Files/FilesSelector.constants"; +import { + MIN_LOADER_TIMER, + SHOW_LOADER_TIMER, +} from "@docspace/shared/selectors/Files/FilesSelector.constants"; import GroupMember from "./GroupMember"; import * as Styled from "../../styles/groups.styled"; @@ -47,11 +50,14 @@ const Groups = ({ infoPanelSelectedGroup, setInfoPanelSelectedGroup, }) => { - const [isShowLoader, setIsShowLoader] = useState(false); - const [areMembersLoading, setAreMembersLoading] = useState(false); + const [isFirstLoad, setIsFirstLoad] = useState(true); + const [showLoader, setShowLoader] = useState(false); const [groupMembers, setGroupMembers] = useState(null); const [total, setTotal] = useState(0); + const startLoader = useRef(null); + const loaderTimeout = useRef(null); + const { groupId: paramsGroupId } = useParams(); const isInsideGroup = !!paramsGroupId; @@ -63,13 +69,7 @@ const Groups = ({ const groupManager = group?.manager; const loadNextPage = async (startIndex) => { - const startLoadingTime = new Date(); - try { - if (startIndex === 0) { - setAreMembersLoading(true); - } - const pageCount = 100; const filter = AccountsFilter.getDefault(); filter.group = groupId; @@ -91,21 +91,48 @@ const Groups = ({ } catch (e) { console.log(e); } finally { - const nowDate = new Date(); - const diff = Math.abs(nowDate.getTime() - startLoadingTime.getTime()); - - if (diff < MIN_LOADER_TIMER) { - setTimeout(() => { - setAreMembersLoading(false); - }, MIN_LOADER_TIMER - diff); - } else { - setAreMembersLoading(false); + if (startIndex === 0) { + setIsFirstLoad(false); } } }; + const calculateLoader = () => { + if (isFirstLoad) { + loaderTimeout.current = setTimeout(() => { + startLoader.current = new Date(); + setShowLoader(true); + }, SHOW_LOADER_TIMER); + } else if (startLoader.current) { + const currentDate = new Date(); + + const ms = Math.abs( + startLoader.current.getTime() - currentDate.getTime(), + ); + + if (ms >= MIN_LOADER_TIMER) { + startLoader.current = null; + return setShowLoader(false); + } + + setTimeout(() => { + startLoader.current = null; + setShowLoader(false); + }, MIN_LOADER_TIMER - ms); + + loaderTimeout.current = null; + } else if (loaderTimeout.current) { + clearTimeout(loaderTimeout.current); + loaderTimeout.current = null; + } + }; + useFetchGroup(groupId, group?.id, setGroup); + useEffect(() => { + setIsFirstLoad(true); + }, [infoPanelSelection.id]); + useEffect(() => { if (group) { loadNextPage(0); @@ -113,35 +140,38 @@ const Groups = ({ }, [group]); useEffect(() => { - const showLoaderTimer = setTimeout(() => setIsShowLoader(true), 500); - return () => clearTimeout(showLoaderTimer); + calculateLoader(); + }, [isFirstLoad]); + + useEffect(() => { + return () => { + loaderTimeout.current = null; + }; }, []); - if (!group) { - if (isShowLoader) - return ( - - - - ); - return null; + if (showLoader) { + return ( + + + + ); } const totalWithoutManager = groupManager ? total - 1 : total; return ( - {groupManager && } - {!groupMembers || areMembersLoading ? ( - - ) : ( - + {isFirstLoad || !groupMembers ? null : ( + <> + {groupManager && } + + )} );