diff --git a/public/index.html b/public/index.html index a11216879f..df420d1a82 100644 --- a/public/index.html +++ b/public/index.html @@ -46,9 +46,10 @@ } .loader-wrapper { - position: relative; + position: absolute; left: 50%; - transform: translateX(-50%); + top: 50%; + transform: translate(-50%, -50%); height: 75px; width: 75px; background-image: url(/icons/loader-pink.svg); diff --git a/src/pages/App/router/Router.tsx b/src/pages/App/router/Router.tsx index 26a09228a8..4a6dfb8f42 100644 --- a/src/pages/App/router/Router.tsx +++ b/src/pages/App/router/Router.tsx @@ -6,7 +6,7 @@ import { ROUTES } from "./configuration"; const Router: FC = () => ( {ROUTES.map((layoutConfiguration, index) => ( - + ))} diff --git a/src/pages/App/router/components/Layout/Layout.tsx b/src/pages/App/router/components/Layout/Layout.tsx index a59cc1c887..eddff8016a 100644 --- a/src/pages/App/router/components/Layout/Layout.tsx +++ b/src/pages/App/router/components/Layout/Layout.tsx @@ -1,7 +1,8 @@ -import React, { FC } from "react"; +import React, { FC, Suspense } from "react"; import { Route, Switch } from "react-router-dom"; import { LayoutConfigurationWithRouteProps } from "../../types"; import { LayoutRoute } from "../LayoutRoute"; +import { SuspenseLoader } from "@/shared/ui-kit"; const Layout: FC = (props) => { const { component: LayoutComponent, routes, ...restProps } = props; @@ -9,11 +10,11 @@ const Layout: FC = (props) => { return ( + - {routes.map((route) => ( - - ))} + {routes.map((route) => )} + ); diff --git a/src/pages/App/router/components/LayoutRoute/LayoutRoute.tsx b/src/pages/App/router/components/LayoutRoute/LayoutRoute.tsx index 3edb7b6c83..9d1238817b 100644 --- a/src/pages/App/router/components/LayoutRoute/LayoutRoute.tsx +++ b/src/pages/App/router/components/LayoutRoute/LayoutRoute.tsx @@ -1,4 +1,4 @@ -import React, { FC, useMemo } from "react"; +import React, { FC, Suspense, useMemo } from "react"; import { useSelector } from "react-redux"; import { Route, RouteProps } from "react-router-dom"; import { Route as RouteConfiguration } from "@/pages/App/router/types"; @@ -9,6 +9,7 @@ import { import { matchRoute } from "@/shared/utils"; import { LayoutRouteContext, LayoutRouteContextValue } from "./context"; import { renderRouteContent } from "./helpers"; +import { SuspenseLoader } from "@/shared/ui-kit"; interface PrivateRouteProps extends RouteProps { routeConfigurations: RouteConfiguration[]; @@ -36,19 +37,21 @@ const LayoutRoute: FC = (props) => { return ( - - renderRouteContent({ - ...routeProps, - component, - children, - configuration: routeConfiguration, - userRoles: userRoles || [], - authenticated, - }) - } - /> + + + renderRouteContent({ + ...routeProps, + component, + children, + configuration: routeConfiguration, + userRoles: userRoles || [], + authenticated, + }) + } + /> + ); }; diff --git a/src/pages/App/router/configuration/commonSidenavLayout.tsx b/src/pages/App/router/configuration/commonSidenavLayout.tsx index 4535543fda..acc9e932cb 100644 --- a/src/pages/App/router/configuration/commonSidenavLayout.tsx +++ b/src/pages/App/router/configuration/commonSidenavLayout.tsx @@ -1,76 +1,75 @@ -import { BillingPage_v04 } from "@/pages/billing"; -import { ALL_COMMON_PAGE_TABS, CommonPage_v04 } from "@/pages/common"; -import { - CommonCreationPage, - ProjectCreationPage_v04, -} from "@/pages/commonCreation"; -import { CommonEditingPage_v04 } from "@/pages/commonEditing"; -import { CommonFeedPage_v04 } from "@/pages/commonFeed"; -import { InboxPage_v04 } from "@/pages/inbox"; -import { ProfilePage_v04 } from "@/pages/profile"; -import { SettingsPage_v04 } from "@/pages/settings"; +import React, { lazy } from "react"; import { ROUTE_PATHS } from "@/shared/constants"; import { CommonSidenavLayout } from "@/shared/layouts"; import { LayoutConfiguration, RouteType } from "../types"; +import { ALL_COMMON_PAGE_TABS } from "@/pages/common"; + +const InboxPage_v04 = lazy(() => import("@/pages/inbox").then(module => ({ default: module.InboxPage_v04 }))); +const CommonCreationPage = lazy(() => import("@/pages/commonCreation").then(module => ({ default: module.CommonCreationPage }))); +const CommonFeedPage_v04 = lazy(() => import("@/pages/commonFeed").then(module => ({ default: module.CommonFeedPage_v04 }))); +const ProjectCreationPage_v04 = lazy(() => import("@/pages/commonCreation").then(module => ({ default: module.ProjectCreationPage_v04 }))); +const CommonEditingPage_v04 = lazy(() => import("@/pages/commonEditing").then(module => ({ default: module.CommonEditingPage_v04 }))); +const ProfilePage_v04 = lazy(() => import("@/pages/profile").then(module => ({ default: module.ProfilePage_v04 }))); +const BillingPage_v04 = lazy(() => import("@/pages/billing").then(module => ({ default: module.BillingPage_v04 }))); +const SettingsPage_v04 = lazy(() => import("@/pages/settings").then(module => ({ default: module.SettingsPage_v04 }))); +const CommonPage_v04 = lazy(() => import("@/pages/common").then(module => ({ default: module.CommonPage_v04 }))); export interface CommonSidenavLayoutRouteOptions { sidenav?: boolean; } -const getCommonPageConfiguration = - (): LayoutConfiguration["routes"] => - ALL_COMMON_PAGE_TABS.map((tab) => ({ - path: `${ROUTE_PATHS.V04_COMMON}/${tab}` as ROUTE_PATHS, - exact: true, - component: CommonPage_v04, - })); +const getCommonPageConfiguration = (): LayoutConfiguration["routes"] => + ALL_COMMON_PAGE_TABS.map((tab) => ({ + path: `${ROUTE_PATHS.V04_COMMON}/${tab}` as ROUTE_PATHS, + exact: true, + component: CommonPage_v04, + })); -export const COMMON_SIDENAV_LAYOUT_CONFIGURATION: LayoutConfiguration = - { - component: CommonSidenavLayout, - routes: [ - { - path: ROUTE_PATHS.V04_INBOX, - exact: true, - component: InboxPage_v04, - type: RouteType.Private, - unauthenticatedRedirectPath: ROUTE_PATHS.HOME, - }, - { - path: ROUTE_PATHS.V04_COMMON_CREATION, - exact: true, - component: CommonCreationPage, - }, - { - path: ROUTE_PATHS.V04_COMMON, - exact: true, - component: CommonFeedPage_v04, - }, - ...getCommonPageConfiguration(), - { - path: ROUTE_PATHS.V04_PROJECT_CREATION, - exact: true, - component: ProjectCreationPage_v04, - }, - { - path: ROUTE_PATHS.V04_COMMON_EDITING, - exact: true, - component: CommonEditingPage_v04, - }, - { - path: ROUTE_PATHS.V04_PROFILE, - exact: true, - component: ProfilePage_v04, - }, - { - path: ROUTE_PATHS.V04_BILLING, - exact: true, - component: BillingPage_v04, - }, - { - path: ROUTE_PATHS.V04_SETTINGS, - exact: true, - component: SettingsPage_v04, - }, - ], - }; +export const COMMON_SIDENAV_LAYOUT_CONFIGURATION: LayoutConfiguration = { + component: CommonSidenavLayout, + routes: [ + { + path: ROUTE_PATHS.V04_INBOX, + exact: true, + component: InboxPage_v04, + type: RouteType.Private, + unauthenticatedRedirectPath: ROUTE_PATHS.HOME, + }, + { + path: ROUTE_PATHS.V04_COMMON_CREATION, + exact: true, + component: CommonCreationPage, + }, + { + path: ROUTE_PATHS.V04_COMMON, + exact: true, + component: CommonFeedPage_v04, + }, + ...getCommonPageConfiguration(), + { + path: ROUTE_PATHS.V04_PROJECT_CREATION, + exact: true, + component: ProjectCreationPage_v04, + }, + { + path: ROUTE_PATHS.V04_COMMON_EDITING, + exact: true, + component: CommonEditingPage_v04, + }, + { + path: ROUTE_PATHS.V04_PROFILE, + exact: true, + component: ProfilePage_v04, + }, + { + path: ROUTE_PATHS.V04_BILLING, + exact: true, + component: BillingPage_v04, + }, + { + path: ROUTE_PATHS.V04_SETTINGS, + exact: true, + component: SettingsPage_v04, + }, + ], +}; diff --git a/src/pages/App/router/configuration/emptyLayout.tsx b/src/pages/App/router/configuration/emptyLayout.tsx index a794de5928..b2695d24f1 100644 --- a/src/pages/App/router/configuration/emptyLayout.tsx +++ b/src/pages/App/router/configuration/emptyLayout.tsx @@ -1,9 +1,12 @@ -import { PrivacyPolicy } from "@/pages/PrivacyPolicy"; -import { EmptyPage } from "@/pages/empty"; +import React, { lazy } from "react"; import { ROUTE_PATHS } from "@/shared/constants"; import { EmptyLayout } from "@/shared/layouts"; import { LayoutConfiguration } from "../types"; +// Wrapping non-default exports for lazy loading +const EmptyPage = lazy(() => import("@/pages/empty").then(module => ({ default: module.EmptyPage }))); +const PrivacyPolicy = lazy(() => import("@/pages/PrivacyPolicy").then(module => ({ default: module.PrivacyPolicy }))); + export const EMPTY_LAYOUT_CONFIGURATION: LayoutConfiguration = { component: EmptyLayout, routes: [ diff --git a/src/pages/App/router/configuration/multipleSpacesLayout.tsx b/src/pages/App/router/configuration/multipleSpacesLayout.tsx index 7c7cd751d4..9cec83fc37 100644 --- a/src/pages/App/router/configuration/multipleSpacesLayout.tsx +++ b/src/pages/App/router/configuration/multipleSpacesLayout.tsx @@ -1,17 +1,18 @@ -import { BillingPage } from "@/pages/billing"; -import { ALL_COMMON_PAGE_TABS, CommonPage } from "@/pages/common"; -import { - CommonCreationPage, - ProjectCreationPage, -} from "@/pages/commonCreation"; -import { CommonEditingPage } from "@/pages/commonEditing"; -import { CommonFeedPage } from "@/pages/commonFeed"; -import { InboxPage } from "@/pages/inbox"; -import { ProfilePage } from "@/pages/profile"; -import { SettingsPage } from "@/pages/settings"; +import React, { lazy } from "react"; import { ROUTE_PATHS } from "@/shared/constants"; import { MultipleSpacesLayout } from "@/shared/layouts"; import { LayoutConfiguration, RouteType } from "../types"; +import { ALL_COMMON_PAGE_TABS } from "@/pages/common"; + +const InboxPage = lazy(() => import("@/pages/inbox").then(module => ({ default: module.InboxPage }))); +const CommonCreationPage = lazy(() => import("@/pages/commonCreation").then(module => ({ default: module.CommonCreationPage }))); +const CommonFeedPage = lazy(() => import("@/pages/commonFeed").then(module => ({ default: module.CommonFeedPage }))); +const ProjectCreationPage = lazy(() => import("@/pages/commonCreation").then(module => ({ default: module.ProjectCreationPage }))); +const CommonEditingPage = lazy(() => import("@/pages/commonEditing").then(module => ({ default: module.CommonEditingPage }))); +const ProfilePage = lazy(() => import("@/pages/profile").then(module => ({ default: module.ProfilePage }))); +const BillingPage = lazy(() => import("@/pages/billing").then(module => ({ default: module.BillingPage }))); +const SettingsPage = lazy(() => import("@/pages/settings").then(module => ({ default: module.SettingsPage }))); +const CommonPage = lazy(() => import("@/pages/common").then(module => ({ default: module.CommonPage }))); export interface MultipleSpacesLayoutRouteOptions { withSidenav?: boolean; @@ -20,81 +21,79 @@ export interface MultipleSpacesLayoutRouteOptions { breadcrumbsItemsWithMenus?: boolean; } -const getCommonPageConfiguration = - (): LayoutConfiguration["routes"] => - ALL_COMMON_PAGE_TABS.map((tab) => ({ - path: `${ROUTE_PATHS.COMMON}/${tab}` as ROUTE_PATHS, +const getCommonPageConfiguration = (): LayoutConfiguration["routes"] => + ALL_COMMON_PAGE_TABS.map((tab) => ({ + path: `${ROUTE_PATHS.COMMON}/${tab}` as ROUTE_PATHS, + exact: true, + component: CommonPage, + routeOptions: { + withGoBack: true, + }, + })); + +export const MULTIPLE_SPACES_LAYOUT_CONFIGURATION: LayoutConfiguration = { + component: MultipleSpacesLayout, + routes: [ + { + path: ROUTE_PATHS.INBOX, exact: true, - component: CommonPage, + component: InboxPage, + type: RouteType.Private, + unauthenticatedRedirectPath: ROUTE_PATHS.HOME, routeOptions: { - withGoBack: true, - }, - })); - -export const MULTIPLE_SPACES_LAYOUT_CONFIGURATION: LayoutConfiguration = - { - component: MultipleSpacesLayout, - routes: [ - { - path: ROUTE_PATHS.INBOX, - exact: true, - component: InboxPage, - type: RouteType.Private, - unauthenticatedRedirectPath: ROUTE_PATHS.HOME, - routeOptions: { - breadcrumbsItemsWithMenus: false, - }, - }, - { - path: ROUTE_PATHS.COMMON_CREATION, - exact: true, - component: CommonCreationPage, + breadcrumbsItemsWithMenus: false, }, - { - path: ROUTE_PATHS.COMMON, - exact: true, - component: CommonFeedPage, - }, - ...getCommonPageConfiguration(), - { - path: ROUTE_PATHS.PROJECT_CREATION, - exact: true, - component: ProjectCreationPage, - }, - { - path: ROUTE_PATHS.COMMON_EDITING, - exact: true, - component: CommonEditingPage, - }, - { - path: ROUTE_PATHS.PROFILE, - exact: true, - component: ProfilePage, - routeOptions: { - withSidenav: false, - withBreadcrumbs: false, - withGoBack: true, - }, + }, + { + path: ROUTE_PATHS.COMMON_CREATION, + exact: true, + component: CommonCreationPage, + }, + { + path: ROUTE_PATHS.COMMON, + exact: true, + component: CommonFeedPage, + }, + ...getCommonPageConfiguration(), + { + path: ROUTE_PATHS.PROJECT_CREATION, + exact: true, + component: ProjectCreationPage, + }, + { + path: ROUTE_PATHS.COMMON_EDITING, + exact: true, + component: CommonEditingPage, + }, + { + path: ROUTE_PATHS.PROFILE, + exact: true, + component: ProfilePage, + routeOptions: { + withSidenav: false, + withBreadcrumbs: false, + withGoBack: true, }, - { - path: ROUTE_PATHS.BILLING, - exact: true, - component: BillingPage, - routeOptions: { - withSidenav: false, - withBreadcrumbs: false, - withGoBack: true, - }, + }, + { + path: ROUTE_PATHS.BILLING, + exact: true, + component: BillingPage, + routeOptions: { + withSidenav: false, + withBreadcrumbs: false, + withGoBack: true, }, - { - path: ROUTE_PATHS.SETTINGS, - exact: true, - component: SettingsPage, - routeOptions: { - withSidenav: false, - withBreadcrumbs: false, - withGoBack: true, - }, + }, + { + path: ROUTE_PATHS.SETTINGS, + exact: true, + component: SettingsPage, + routeOptions: { + withSidenav: false, + withBreadcrumbs: false, + withGoBack: true, }, - ], - }; + }, + ], +}; diff --git a/src/pages/App/router/configuration/oldLayout.tsx b/src/pages/App/router/configuration/oldLayout.tsx index bfb3bbaed6..6e4681d3e1 100644 --- a/src/pages/App/router/configuration/oldLayout.tsx +++ b/src/pages/App/router/configuration/oldLayout.tsx @@ -1,20 +1,21 @@ -import { SubmitInvoicesContainer } from "@/pages/Invoices"; -import { ContactUsContainer, LandingContainer } from "@/pages/Landing"; -import { MyAccountContainer } from "@/pages/MyAccount"; -import { - CommonDetailContainer, - DiscussionContainer, - DiscussionMessageContainer, - ProposalCommentContainer, - ProposalContainer, - SupportersContainer, -} from "@/pages/OldCommon"; -import { MyCommonsContainer } from "@/pages/OldCommon/containers/MyCommonsContainer"; -import { TrusteeContainer } from "@/pages/Trustee"; +import React, { lazy } from "react"; import { ROUTE_PATHS, ScreenSize } from "@/shared/constants"; import { OldLayout } from "@/shared/layouts"; import { LayoutConfiguration, RouteType } from "../types"; +const LandingContainer = lazy(() => import("@/pages/Landing").then(module => ({ default: module.LandingContainer }))); +const ContactUsContainer = lazy(() => import("@/pages/Landing").then(module => ({ default: module.ContactUsContainer }))); +const CommonDetailContainer = lazy(() => import("@/pages/OldCommon").then(module => ({ default: module.CommonDetailContainer }))); +const SupportersContainer = lazy(() => import("@/pages/OldCommon").then(module => ({ default: module.SupportersContainer }))); +const ProposalContainer = lazy(() => import("@/pages/OldCommon").then(module => ({ default: module.ProposalContainer }))); +const ProposalCommentContainer = lazy(() => import("@/pages/OldCommon").then(module => ({ default: module.ProposalCommentContainer }))); +const DiscussionContainer = lazy(() => import("@/pages/OldCommon").then(module => ({ default: module.DiscussionContainer }))); +const DiscussionMessageContainer = lazy(() => import("@/pages/OldCommon").then(module => ({ default: module.DiscussionMessageContainer }))); +const MyAccountContainer = lazy(() => import("@/pages/MyAccount").then(module => ({ default: module.MyAccountContainer }))); +const MyCommonsContainer = lazy(() => import("@/pages/OldCommon/containers/MyCommonsContainer").then(module => ({ default: module.MyCommonsContainer }))); +const SubmitInvoicesContainer = lazy(() => import("@/pages/Invoices").then(module => ({ default: module.SubmitInvoicesContainer }))); +const TrusteeContainer = lazy(() => import("@/pages/Trustee").then(module => ({ default: module.TrusteeContainer }))); + export interface OldLayoutRouteOptions { footer?: | boolean @@ -23,90 +24,89 @@ export interface OldLayoutRouteOptions { }; } -export const OLD_LAYOUT_CONFIGURATION: LayoutConfiguration = - { - component: OldLayout, - routes: [ - { - path: ROUTE_PATHS.HOME, - exact: true, - component: LandingContainer, - }, - { - path: ROUTE_PATHS.CONTACT_US, - exact: true, - component: ContactUsContainer, - }, - { - path: ROUTE_PATHS.V02_COMMON, - exact: true, - component: CommonDetailContainer, - routeOptions: { - footer: { - screenSizeWhenDisplay: ScreenSize.Desktop, - }, - }, - }, - { - path: ROUTE_PATHS.COMMON_SUPPORT, - exact: true, - component: SupportersContainer, - routeOptions: { - footer: false, +export const OLD_LAYOUT_CONFIGURATION: LayoutConfiguration = { + component: OldLayout, + routes: [ + { + path: ROUTE_PATHS.HOME, + exact: true, + component: LandingContainer, + }, + { + path: ROUTE_PATHS.CONTACT_US, + exact: true, + component: ContactUsContainer, + }, + { + path: ROUTE_PATHS.V02_COMMON, + exact: true, + component: CommonDetailContainer, + routeOptions: { + footer: { + screenSizeWhenDisplay: ScreenSize.Desktop, }, }, - { - path: ROUTE_PATHS.PROPOSAL_DETAIL, - component: ProposalContainer, - type: RouteType.Private, + }, + { + path: ROUTE_PATHS.COMMON_SUPPORT, + exact: true, + component: SupportersContainer, + routeOptions: { + footer: false, }, - { - path: ROUTE_PATHS.PROPOSAL_COMMENT, - component: ProposalCommentContainer, - type: RouteType.Private, - routeOptions: { - footer: { - screenSizeWhenDisplay: ScreenSize.Desktop, - }, + }, + { + path: ROUTE_PATHS.PROPOSAL_DETAIL, + component: ProposalContainer, + type: RouteType.Private, + }, + { + path: ROUTE_PATHS.PROPOSAL_COMMENT, + component: ProposalCommentContainer, + type: RouteType.Private, + routeOptions: { + footer: { + screenSizeWhenDisplay: ScreenSize.Desktop, }, }, - { - path: ROUTE_PATHS.DISCUSSION_DETAIL, - component: DiscussionContainer, - type: RouteType.Private, - routeOptions: { - footer: { - screenSizeWhenDisplay: ScreenSize.Desktop, - }, + }, + { + path: ROUTE_PATHS.DISCUSSION_DETAIL, + component: DiscussionContainer, + type: RouteType.Private, + routeOptions: { + footer: { + screenSizeWhenDisplay: ScreenSize.Desktop, }, }, - { - path: ROUTE_PATHS.DISCUSSION_MESSAGE, - component: DiscussionMessageContainer, - type: RouteType.Private, - routeOptions: { - footer: { - screenSizeWhenDisplay: ScreenSize.Desktop, - }, + }, + { + path: ROUTE_PATHS.DISCUSSION_MESSAGE, + component: DiscussionMessageContainer, + type: RouteType.Private, + routeOptions: { + footer: { + screenSizeWhenDisplay: ScreenSize.Desktop, }, }, - { - path: ROUTE_PATHS.MY_ACCOUNT, - component: MyAccountContainer, - type: RouteType.Private, - }, - { - path: ROUTE_PATHS.MY_COMMONS, - component: MyCommonsContainer, - type: RouteType.Private, - }, - { - path: ROUTE_PATHS.SUBMIT_INVOICES, - component: SubmitInvoicesContainer, - }, - { - path: ROUTE_PATHS.TRUSTEE, - component: TrusteeContainer, - }, - ], - }; + }, + { + path: ROUTE_PATHS.MY_ACCOUNT, + component: MyAccountContainer, + type: RouteType.Private, + }, + { + path: ROUTE_PATHS.MY_COMMONS, + component: MyCommonsContainer, + type: RouteType.Private, + }, + { + path: ROUTE_PATHS.SUBMIT_INVOICES, + component: SubmitInvoicesContainer, + }, + { + path: ROUTE_PATHS.TRUSTEE, + component: TrusteeContainer, + }, + ], +}; diff --git a/src/pages/App/router/configuration/sidenavLayout.tsx b/src/pages/App/router/configuration/sidenavLayout.tsx index 8dd4a8b732..f351e56336 100644 --- a/src/pages/App/router/configuration/sidenavLayout.tsx +++ b/src/pages/App/router/configuration/sidenavLayout.tsx @@ -1,20 +1,21 @@ -import { CommonPage_v03 } from "@/pages/common-v03"; +import React, { lazy } from "react"; import { ROUTE_PATHS } from "@/shared/constants"; import { SidenavLayout } from "@/shared/layouts"; import { LayoutConfiguration } from "../types"; +const CommonPage_v03 = lazy(() => import("@/pages/common-v03").then(module => ({ default: module.CommonPage_v03 }))); + export interface SidenavLayoutRouteOptions { sidenav?: boolean; } -export const SIDENAV_LAYOUT_CONFIGURATION: LayoutConfiguration = - { - component: SidenavLayout, - routes: [ - { - path: ROUTE_PATHS.V03_COMMON, - exact: true, - component: CommonPage_v03, - }, - ], - }; +export const SIDENAV_LAYOUT_CONFIGURATION: LayoutConfiguration = { + component: SidenavLayout, + routes: [ + { + path: ROUTE_PATHS.V03_COMMON, + exact: true, + component: CommonPage_v03, + }, + ], +}; diff --git a/src/shared/hooks/useCases/useDiscussionMessagesById.ts b/src/shared/hooks/useCases/useDiscussionMessagesById.ts index 7e6fc36d32..2dd45e70d8 100644 --- a/src/shared/hooks/useCases/useDiscussionMessagesById.ts +++ b/src/shared/hooks/useCases/useDiscussionMessagesById.ts @@ -1,4 +1,4 @@ -import { useState, useCallback } from "react"; +import { useState, useCallback, useEffect, useRef } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useDeepCompareEffect, useUpdateEffect } from "react-use"; import { trace } from "firebase/performance"; @@ -100,6 +100,8 @@ export const useDiscussionMessagesById = ({ const [discussionMessagesWithOwners, setDiscussionMessagesWithOwners] = useState(); + const unsubscribeRef = useRef(null); + useUpdateEffect(() => { if (discussionId) { setDiscussionMessagesWithOwners([]); @@ -251,7 +253,7 @@ export const useDiscussionMessagesById = ({ const fetchDiscussionMessagesTrace = trace(perf, 'fetchDiscussionMessages'); fetchDiscussionMessagesTrace.start(); - DiscussionMessageService.subscribeToDiscussionMessagesByDiscussionId( + unsubscribeRef.current = DiscussionMessageService.subscribeToDiscussionMessagesByDiscussionId( discussionId, lastVisible && lastVisible[discussionId], async ( @@ -268,16 +270,16 @@ export const useDiscussionMessagesById = ({ ...prevVisible, [discussionId]: lastVisibleDocument, })); - + const hasLastVisibleDocument = !!lastVisibleDocument?.data(); - + const discussionsWithText = await Promise.all( updatedDiscussionMessages.map(async (discussionMessage) => { const isUserDiscussionMessage = checkIsUserDiscussionMessage(discussionMessage); const isSystemMessage = checkIsSystemDiscussionMessage(discussionMessage); - + const parsedText = await getTextFromTextEditorString({ userId, ownerId: isUserDiscussionMessage @@ -294,7 +296,7 @@ export const useDiscussionMessagesById = ({ onFeedItemClick, onInternalLinkClick, }); - + return { ...discussionMessage, parsedText, @@ -321,10 +323,35 @@ export const useDiscussionMessagesById = ({ }, ); fetchDiscussionMessagesTrace.stop(); - } catch(err) { + } catch (err) { setIsBatchLoading(false); } - },[discussionId, isEndOfList, state.loading, state.data, isBatchLoading, lastVisible, userId, users, directParent, getCommonPagePath, getCommonPageAboutTabPath, onUserClick, onFeedItemClick, onInternalLinkClick, dispatch]); + }, [ + discussionId, + isEndOfList, + state.loading, + state.data, + isBatchLoading, + lastVisible, + userId, + users, + directParent, + getCommonPagePath, + getCommonPageAboutTabPath, + onUserClick, + onFeedItemClick, + onInternalLinkClick, + dispatch, + ]); + + useEffect(() => { + // Cleanup subscription on unmount or when discussionId changes + return () => { + if (unsubscribeRef.current) { + unsubscribeRef.current(); + } + }; + }, [discussionId]); useDeepCompareEffect(() => { (async () => { diff --git a/src/shared/ui-kit/Loader/Loader.module.scss b/src/shared/ui-kit/Loader/Loader.module.scss index 2129d49978..8153df74fe 100644 --- a/src/shared/ui-kit/Loader/Loader.module.scss +++ b/src/shared/ui-kit/Loader/Loader.module.scss @@ -6,6 +6,11 @@ height: 3.125rem; } +.bigLoader { + height: 4.6875rem; + width: 4.6875rem; +} + .globalLoaderOverlay { position: fixed; top: 0; diff --git a/src/shared/ui-kit/Loader/Loader.tsx b/src/shared/ui-kit/Loader/Loader.tsx index 4575d3db6e..f7b3bd4f5d 100644 --- a/src/shared/ui-kit/Loader/Loader.tsx +++ b/src/shared/ui-kit/Loader/Loader.tsx @@ -8,6 +8,7 @@ import styles from "./Loader.module.scss"; export enum LoaderVariant { Default, Global, + Big, } export enum LoaderColor { @@ -35,7 +36,9 @@ const Loader: FC = (props) => { const [isShowing, setIsShowing] = useState(!delay); const loaderEl = ( Loader diff --git a/src/shared/ui-kit/SuspenseLoader/SuspenseLoader.module.scss b/src/shared/ui-kit/SuspenseLoader/SuspenseLoader.module.scss new file mode 100644 index 0000000000..52522947d8 --- /dev/null +++ b/src/shared/ui-kit/SuspenseLoader/SuspenseLoader.module.scss @@ -0,0 +1,16 @@ +.container { + width: 100vw; + height: 100vh; + display: flex; + background-color: white; + flex: 4; + justify-content: center; + align-items: center; +} + +.loader { + display: flex; + flex-direction:column; + justify-content: center; + align-items: center; +} \ No newline at end of file diff --git a/src/shared/ui-kit/SuspenseLoader/SuspenseLoader.tsx b/src/shared/ui-kit/SuspenseLoader/SuspenseLoader.tsx new file mode 100644 index 0000000000..426d822941 --- /dev/null +++ b/src/shared/ui-kit/SuspenseLoader/SuspenseLoader.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Loader, LoaderVariant } from "../Loader"; +import styles from "./SuspenseLoader.module.scss"; + + +export default ( +
+
+ +
+
+); \ No newline at end of file diff --git a/src/shared/ui-kit/SuspenseLoader/index.ts b/src/shared/ui-kit/SuspenseLoader/index.ts new file mode 100644 index 0000000000..fa71f15443 --- /dev/null +++ b/src/shared/ui-kit/SuspenseLoader/index.ts @@ -0,0 +1 @@ +export { default as SuspenseLoader } from "./SuspenseLoader"; \ No newline at end of file diff --git a/src/shared/ui-kit/index.ts b/src/shared/ui-kit/index.ts index 1e56588102..faf1e88e6b 100644 --- a/src/shared/ui-kit/index.ts +++ b/src/shared/ui-kit/index.ts @@ -27,3 +27,4 @@ export * from "./TopNavigation"; export * from "./UploadFiles"; export * from "./FilePreview"; export * from "./MenuButton"; +export * from "./SuspenseLoader";