From 418f1c36fbf75583ba491bdcd0e7a05246e418c3 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 26 Sep 2023 12:34:53 +0300 Subject: [PATCH 1/3] add delay prop to Loader component --- src/shared/ui-kit/Loader/Loader.tsx | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/shared/ui-kit/Loader/Loader.tsx b/src/shared/ui-kit/Loader/Loader.tsx index ce1270c7eb..173d165a19 100644 --- a/src/shared/ui-kit/Loader/Loader.tsx +++ b/src/shared/ui-kit/Loader/Loader.tsx @@ -1,4 +1,4 @@ -import React, { FC } from "react"; +import React, { FC, useEffect, useRef, useState } from "react"; import classNames from "classnames"; import loaderDefault from "@/shared/assets/icons/loader-pink.svg"; import loaderWhite from "@/shared/assets/icons/loader-white.svg"; @@ -20,6 +20,7 @@ interface LoaderProps { overlayClassName?: string; variant?: LoaderVariant; color?: LoaderColor; + delay?: number; } const Loader: FC = (props) => { @@ -28,7 +29,10 @@ const Loader: FC = (props) => { overlayClassName, variant = LoaderVariant.Default, color = LoaderColor.Default, + delay, } = props; + const timeoutRef = useRef(null); + const [isShowing, setIsShowing] = useState(!delay); const loaderEl = ( = (props) => { /> ); + useEffect(() => { + if (!delay) { + return; + } + + timeoutRef.current = setTimeout(() => { + setIsShowing(true); + }, delay); + + return () => { + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + } + }; + }, [delay]); + if (variant === LoaderVariant.Global) { return ( @@ -49,7 +69,7 @@ const Loader: FC = (props) => { ); } - return loaderEl; + return isShowing ? loaderEl : null; }; export default Loader; From 487e5cfb7c6523acb910ce31d0f7528bc9d5fc45 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 26 Sep 2023 12:45:28 +0300 Subject: [PATCH 2/3] add delay to used loaders --- .../ChatContent/ChatContent.module.scss | 1 + .../components/ChatContent/ChatContent.tsx | 10 +++++++--- src/pages/commonFeed/CommonFeed.tsx | 8 ++++++-- .../components/FeedLayout/FeedLayout.tsx | 18 ++++++++++++------ .../DesktopChatPlaceholder.tsx | 5 ++++- src/pages/inbox/BaseInbox.tsx | 4 ++-- src/shared/constants/shared.tsx | 2 ++ .../components/Projects/Projects.tsx | 3 ++- .../components/ProjectsTree/ProjectsTree.tsx | 5 ++++- .../ui-kit/InfiniteScroll/InfiniteScroll.tsx | 5 +++-- 10 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.module.scss b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.module.scss index 44eb2df881..fd9cd3d746 100644 --- a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.module.scss +++ b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.module.scss @@ -54,5 +54,6 @@ .loaderContainer { display: flex; height: 100%; + justify-content: center; align-items: center; } diff --git a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx index a05f405fcd..141992de99 100644 --- a/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx +++ b/src/pages/common/components/ChatComponent/components/ChatContent/ChatContent.tsx @@ -12,9 +12,12 @@ import { scroller, animateScroll } from "react-scroll"; import { v4 as uuidv4 } from "uuid"; import { selectUser } from "@/pages/Auth/store/selectors"; import { EmptyTabComponent } from "@/pages/OldCommon/components/CommonDetailContainer"; -import { Loader } from "@/shared/components"; import { ChatMessage, InternalLinkData } from "@/shared/components"; -import { ChatType, QueryParamKey } from "@/shared/constants"; +import { + ChatType, + LOADER_APPEARANCE_DELAY, + QueryParamKey, +} from "@/shared/constants"; import { useQueryParams } from "@/shared/hooks"; import { checkIsUserDiscussionMessage, @@ -25,6 +28,7 @@ import { User, Circles, } from "@/shared/models"; +import { Loader } from "@/shared/ui-kit"; import { formatDate } from "@/shared/utils"; import { Separator } from "./components"; import { checkIsLastSeenInPreviousDay } from "./utils"; @@ -209,7 +213,7 @@ const ChatContent: ForwardRefRenderFunction< if (isLoading) { return (
- +
); } diff --git a/src/pages/commonFeed/CommonFeed.tsx b/src/pages/commonFeed/CommonFeed.tsx index d0b28b21c5..191e704a33 100644 --- a/src/pages/commonFeed/CommonFeed.tsx +++ b/src/pages/commonFeed/CommonFeed.tsx @@ -20,7 +20,11 @@ import { MembershipRequestModal } from "@/pages/OldCommon/components"; import { FeedItemBaseContent, FeedItemBaseContentProps } from "@/pages/common"; import { JoinProjectModal } from "@/pages/common/components/JoinProjectModal"; import { useJoinProjectAutomatically } from "@/pages/common/hooks"; -import { CommonAction, QueryParamKey } from "@/shared/constants"; +import { + CommonAction, + LOADER_APPEARANCE_DELAY, + QueryParamKey, +} from "@/shared/constants"; import { useRoutesContext } from "@/shared/contexts"; import { useAuthorizedModal, useQueryParams } from "@/shared/hooks"; import { useCommonFeedItems, useUserCommonIds } from "@/shared/hooks/useCases"; @@ -396,7 +400,7 @@ const CommonFeedComponent: FC = (props) => { if (!isDataFetched) { return (
- +
); } diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx index 63909afdf4..b320084497 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx @@ -15,7 +15,6 @@ import { useHistory } from "react-router-dom"; import { useWindowSize } from "react-use"; import classNames from "classnames"; import { selectUser } from "@/pages/Auth/store/selectors"; -import { MembershipRequestModal } from "@/pages/OldCommon/components"; import { useCommonMember } from "@/pages/OldCommon/hooks"; import { FeedItem, @@ -31,12 +30,15 @@ import { ChatItem, } from "@/pages/common/components/ChatComponent"; import { ChatContext } from "@/pages/common/components/ChatComponent/context"; -import { JoinProjectModal } from "@/pages/common/components/JoinProjectModal"; -import { useJoinProjectAutomatically } from "@/pages/common/hooks"; import { InternalLinkData } from "@/shared/components"; -import { InboxItemType, QueryParamKey, ROUTE_PATHS } from "@/shared/constants"; +import { + InboxItemType, + LOADER_APPEARANCE_DELAY, + QueryParamKey, + ROUTE_PATHS, +} from "@/shared/constants"; import { useRoutesContext } from "@/shared/contexts"; -import { useAuthorizedModal, useQueryParams } from "@/shared/hooks"; +import { useQueryParams } from "@/shared/hooks"; import { useGovernanceByCommonId } from "@/shared/hooks/useCases"; import { useIsTabletView } from "@/shared/hooks/viewport"; import { @@ -637,7 +639,11 @@ const FeedLayout: ForwardRefRenderFunction = ( > {topContent} {isContentEmpty &&

{emptyText}

} - + {allFeedItems?.map((item) => { const isActive = item.itemId === activeFeedItemId; diff --git a/src/pages/commonFeed/components/FeedLayout/components/DesktopChatPlaceholder/DesktopChatPlaceholder.tsx b/src/pages/commonFeed/components/FeedLayout/components/DesktopChatPlaceholder/DesktopChatPlaceholder.tsx index d0992b6674..8d2f0ac46e 100644 --- a/src/pages/commonFeed/components/FeedLayout/components/DesktopChatPlaceholder/DesktopChatPlaceholder.tsx +++ b/src/pages/commonFeed/components/FeedLayout/components/DesktopChatPlaceholder/DesktopChatPlaceholder.tsx @@ -1,5 +1,6 @@ import React, { FC } from "react"; import classNames from "classnames"; +import { LOADER_APPEARANCE_DELAY } from "@/shared/constants"; import { Loader } from "@/shared/ui-kit"; import { DesktopRightPane } from "../DesktopRightPane"; import desktopChatStyles from "../DesktopChat/DesktopChat.module.scss"; @@ -17,7 +18,9 @@ const DesktopChatPlaceholder: FC = (props) => { return ( {withTitle &&
} -
{isItemSelected && }
+
+ {isItemSelected && } +
); }; diff --git a/src/pages/inbox/BaseInbox.tsx b/src/pages/inbox/BaseInbox.tsx index a0f97b8667..2f8ad3a3c4 100644 --- a/src/pages/inbox/BaseInbox.tsx +++ b/src/pages/inbox/BaseInbox.tsx @@ -16,7 +16,7 @@ import { FeedLayoutOuterStyles, FeedLayoutSettings, } from "@/pages/commonFeed"; -import { QueryParamKey } from "@/shared/constants"; +import { LOADER_APPEARANCE_DELAY, QueryParamKey } from "@/shared/constants"; import { useRoutesContext } from "@/shared/contexts"; import { ChatChannelToDiscussionConverter } from "@/shared/converters"; import { useQueryParams } from "@/shared/hooks"; @@ -225,7 +225,7 @@ const InboxPage: FC = (props) => { if (!isDataFetched) { return (
- +
); } diff --git a/src/shared/constants/shared.tsx b/src/shared/constants/shared.tsx index eb489d9bff..2355c543ae 100644 --- a/src/shared/constants/shared.tsx +++ b/src/shared/constants/shared.tsx @@ -109,3 +109,5 @@ export const ANONYMOUS_USER_FIRST_NAME = "Anonymous"; export const ANONYMOUS_USER_LAST_NAME = "User"; export const GA_MEASUREMENT_ID = "G-1W2BNV5QZ9"; + +export const LOADER_APPEARANCE_DELAY = 2000; diff --git a/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/Projects/Projects.tsx b/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/Projects/Projects.tsx index f44974e259..2e930514c5 100644 --- a/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/Projects/Projects.tsx +++ b/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/Projects/Projects.tsx @@ -1,6 +1,7 @@ import React, { FC, ReactNode, useCallback, useMemo } from "react"; import { useHistory } from "react-router"; import { CreateCommonModal } from "@/pages/OldCommon/components"; +import { LOADER_APPEARANCE_DELAY } from "@/shared/constants"; import { useRoutesContext } from "@/shared/contexts"; import { useAuthorizedModal } from "@/shared/hooks"; import { Common } from "@/shared/models"; @@ -75,7 +76,7 @@ const Projects: FC = (props) => { if (!parentItem) { return areCommonsLoading ? ( - + ) : ( <> {renderNoItemsInfo?.() || null} diff --git a/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/ProjectsTree/ProjectsTree.tsx b/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/ProjectsTree/ProjectsTree.tsx index ae1d0c51f0..6ec3faf28a 100644 --- a/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/ProjectsTree/ProjectsTree.tsx +++ b/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/ProjectsTree/ProjectsTree.tsx @@ -1,4 +1,5 @@ import React, { FC, useMemo } from "react"; +import { LOADER_APPEARANCE_DELAY } from "@/shared/constants"; import { Loader } from "@/shared/ui-kit"; import { ProjectsStateItem } from "@/store/states"; import { Scrollbar } from "../../../../../SidenavLayout/components/SidenavContent"; @@ -96,7 +97,9 @@ const ProjectsTree: FC = (props) => { } level={INITIAL_TREE_ITEMS_LEVEL} /> - {isLoading && } + {isLoading && ( + + )} ); diff --git a/src/shared/ui-kit/InfiniteScroll/InfiniteScroll.tsx b/src/shared/ui-kit/InfiniteScroll/InfiniteScroll.tsx index 96bd8780c4..340946f68e 100644 --- a/src/shared/ui-kit/InfiniteScroll/InfiniteScroll.tsx +++ b/src/shared/ui-kit/InfiniteScroll/InfiniteScroll.tsx @@ -5,11 +5,12 @@ import styles from "./InfiniteScroll.module.scss"; interface InfiniteScrollProps { isLoading: boolean; + loaderDelay?: number; onFetchNext: () => void; } const InfiniteScroll: FC = (props) => { - const { isLoading, onFetchNext, children } = props; + const { isLoading, loaderDelay, onFetchNext, children } = props; const [isInnerLoading, setIsInnerLoading] = useState(isLoading); const markerRef = useRef(null); const isMarkerOnScreen = useIntersectionObserver(markerRef.current); @@ -41,7 +42,7 @@ const InfiniteScroll: FC = (props) => {
{isLoading && (
- +
)} From dece8a035a7f853926046459785ac04bdafb3811 Mon Sep 17 00:00:00 2001 From: Andrey Mikhadyuk Date: Tue, 26 Sep 2023 14:22:48 +0300 Subject: [PATCH 3/3] fix timeout ref type --- src/pages/common/components/FeedCard/FeedCard.tsx | 2 +- src/shared/ui-kit/Loader/Loader.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/common/components/FeedCard/FeedCard.tsx b/src/pages/common/components/FeedCard/FeedCard.tsx index d1ea7ab55a..84011cb894 100644 --- a/src/pages/common/components/FeedCard/FeedCard.tsx +++ b/src/pages/common/components/FeedCard/FeedCard.tsx @@ -84,7 +84,7 @@ export const FeedCard = forwardRef((props, ref) => { hasImages, hasFiles, } = props; - const scrollTimeoutRef = useRef(null); + const scrollTimeoutRef = useRef | null>(null); const isTabletView = useIsTabletView(); const { setExpandedFeedItemId, renderFeedItemBaseContent, feedCardSettings } = useFeedItemContext(); diff --git a/src/shared/ui-kit/Loader/Loader.tsx b/src/shared/ui-kit/Loader/Loader.tsx index 173d165a19..4575d3db6e 100644 --- a/src/shared/ui-kit/Loader/Loader.tsx +++ b/src/shared/ui-kit/Loader/Loader.tsx @@ -31,7 +31,7 @@ const Loader: FC = (props) => { color = LoaderColor.Default, delay, } = props; - const timeoutRef = useRef(null); + const timeoutRef = useRef | null>(null); const [isShowing, setIsShowing] = useState(!delay); const loaderEl = (