From acf38c7e2692298786e730d6a7a9cc7f93b54ef6 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Wed, 10 Jul 2024 16:49:26 +0300 Subject: [PATCH 01/36] CW-image-gallery-resize Fix wrong flag --- .../components/ImageGalleryModal/ImageGalleryModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/ui-kit/ImageGallery/components/ImageGalleryModal/ImageGalleryModal.tsx b/src/shared/ui-kit/ImageGallery/components/ImageGalleryModal/ImageGalleryModal.tsx index ae79bd260..a6b377232 100644 --- a/src/shared/ui-kit/ImageGallery/components/ImageGalleryModal/ImageGalleryModal.tsx +++ b/src/shared/ui-kit/ImageGallery/components/ImageGalleryModal/ImageGalleryModal.tsx @@ -75,7 +75,7 @@ const ImageGalleryModal: FC = (props) => { } > Date: Wed, 10 Jul 2024 17:47:41 +0300 Subject: [PATCH 02/36] CW-performance-monitoring Added firebase performance monitoring --- src/pages/OldCommon/hooks/useCommonMembers.ts | 6 ++++++ .../hooks/useCases/useDiscussionMessagesById.ts | 11 ++++++++++- src/shared/utils/firebase.tsx | 4 +++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/pages/OldCommon/hooks/useCommonMembers.ts b/src/pages/OldCommon/hooks/useCommonMembers.ts index 34aa60f0e..3f16ad080 100644 --- a/src/pages/OldCommon/hooks/useCommonMembers.ts +++ b/src/pages/OldCommon/hooks/useCommonMembers.ts @@ -1,5 +1,6 @@ import { useCallback, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; +import { trace } from "firebase/performance"; import { CommonService, Logger, UserService } from "@/services"; import { store } from "@/shared/appConfig"; import { LoadingState } from "@/shared/interfaces"; @@ -10,6 +11,7 @@ import { selectUserStates, } from "@/store/states"; import { useDeepCompareEffect } from "react-use"; +import { perf } from "@/shared/utils/firebase"; interface Options { commonId?: string; @@ -111,6 +113,9 @@ export const useCommonMembers = ({ commonId }: Options): Return => { (async () => { try { + const useCommonMembersTrace = trace(perf, 'useCommonMembers'); + useCommonMembersTrace.start(); + const cachedUserStates = selectUserStates()(store.getState()); const hasUsersFromCache = commonMembers.some( ({ userId }) => cachedUserStates[userId]?.data, @@ -183,6 +188,7 @@ export const useCommonMembers = ({ commonId }: Options): Return => { }; }); dispatch(cacheActions.updateUserStates(fetchedUsers)); + useCommonMembersTrace.stop(); } catch (err) { Logger.error(err); setState((prevState) => ({ diff --git a/src/shared/hooks/useCases/useDiscussionMessagesById.ts b/src/shared/hooks/useCases/useDiscussionMessagesById.ts index a2921fb4a..ca0348c33 100644 --- a/src/shared/hooks/useCases/useDiscussionMessagesById.ts +++ b/src/shared/hooks/useCases/useDiscussionMessagesById.ts @@ -1,6 +1,7 @@ import { useState, useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useDeepCompareEffect, useUpdateEffect } from "react-use"; +import { trace } from "firebase/performance"; import { DiscussionMessageService, MESSAGES_NUMBER_IN_BATCH, @@ -20,7 +21,7 @@ import { User, } from "@/shared/models"; import { InternalLinkData } from "@/shared/utils"; -import firebase from "@/shared/utils/firebase"; +import firebase, { perf } from "@/shared/utils/firebase"; import { cacheActions, selectDiscussionMessagesStateByDiscussionId, @@ -153,6 +154,9 @@ export const useDiscussionMessagesById = ({ const fetchRepliedMessages = useCallback( async (messageId: string, endDate: Date): Promise => { + const fetchRepliedMessagesTrace = trace(perf, 'fetchRepliedMessagesTrace'); + fetchRepliedMessagesTrace.start(); + if (state.data?.find((item) => item.id === messageId)) { return Promise.resolve(); } @@ -206,6 +210,7 @@ export const useDiscussionMessagesById = ({ updatedDiscussionMessages: discussionsWithText, }), ); + fetchRepliedMessagesTrace.stop(); }, [ state.data, @@ -239,6 +244,9 @@ export const useDiscussionMessagesById = ({ } try { + const fetchDiscussionMessagesTrace = trace(perf, 'fetchDiscussionMessages'); + fetchDiscussionMessagesTrace.start(); + DiscussionMessageService.subscribeToDiscussionMessagesByDiscussionId( discussionId, lastVisible && lastVisible[discussionId], @@ -308,6 +316,7 @@ export const useDiscussionMessagesById = ({ setIsBatchLoading(false); }, ); + fetchDiscussionMessagesTrace.stop(); } catch(err) { setIsBatchLoading(false); } diff --git a/src/shared/utils/firebase.tsx b/src/shared/utils/firebase.tsx index b652bbd95..5ab2f677a 100644 --- a/src/shared/utils/firebase.tsx +++ b/src/shared/utils/firebase.tsx @@ -3,6 +3,7 @@ import "firebase/compat/auth"; import "firebase/compat/firestore"; import "firebase/compat/performance"; import "firebase/compat/storage"; +import { getPerformance } from "firebase/performance"; import { local } from "@/config"; import { Environment, REACT_APP_ENV } from "@/shared/constants"; import config from "../../config"; @@ -11,7 +12,7 @@ interface FirebaseError extends Error { code: string; } -firebase.initializeApp(config.firebase); +const app = firebase.initializeApp(config.firebase); if (REACT_APP_ENV === Environment.Local) { firebase.auth().useEmulator(local.firebase.authDomain); @@ -33,6 +34,7 @@ if (REACT_APP_ENV === Environment.Local) { }); } +export const perf = getPerformance(app); // firebase.firestore.setLogLevel("debug"); export const isFirebaseError = (error: any): error is FirebaseError => From 454eb11b3c0c0b24701d88ed7d85d2a95997889b Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Wed, 10 Jul 2024 18:31:15 +0300 Subject: [PATCH 03/36] CW-performance-monitoring Fix tests --- package.json | 1 + src/shared/utils/firebase.tsx | 14 +++++++++++++- src/shared/utils/tests/mockFetch.ts | 3 +++ yarn.lock | 27 +++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/shared/utils/tests/mockFetch.ts diff --git a/package.json b/package.json index bd0a4db27..1553bfedc 100644 --- a/package.json +++ b/package.json @@ -175,6 +175,7 @@ "identity-obj-proxy": "^3.0.0", "jest": "^27.5.1", "jest-extended": "^2.0.0", + "jest-fetch-mock": "^3.0.3", "lint-staged": ">=10", "prettier": "^2.1.1", "prop-types": "^15.8.1", diff --git a/src/shared/utils/firebase.tsx b/src/shared/utils/firebase.tsx index 5ab2f677a..3db4544c9 100644 --- a/src/shared/utils/firebase.tsx +++ b/src/shared/utils/firebase.tsx @@ -34,7 +34,19 @@ if (REACT_APP_ENV === Environment.Local) { }); } -export const perf = getPerformance(app); +let perf; +if (typeof window !== "undefined" && typeof window.fetch !== "undefined") { + perf = getPerformance(app); +} else { + perf = { + trace: () => ({ + start: () => {}, + stop: () => {}, + }), + }; +} + +export { perf }; // firebase.firestore.setLogLevel("debug"); export const isFirebaseError = (error: any): error is FirebaseError => diff --git a/src/shared/utils/tests/mockFetch.ts b/src/shared/utils/tests/mockFetch.ts new file mode 100644 index 000000000..c68b24a4d --- /dev/null +++ b/src/shared/utils/tests/mockFetch.ts @@ -0,0 +1,3 @@ +import fetchMock from 'jest-fetch-mock'; + +fetchMock.enableMocks(); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 22f3f316e..14ceec5b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8608,6 +8608,13 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cross-fetch@^3.0.4: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== + dependencies: + node-fetch "^2.6.12" + cross-spawn@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" @@ -12782,6 +12789,14 @@ jest-extended@^2.0.0: jest-diff "^27.2.5" jest-get-type "^27.0.6" +jest-fetch-mock@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz#31749c456ae27b8919d69824f1c2bd85fe0a1f3b" + integrity sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw== + dependencies: + cross-fetch "^3.0.4" + promise-polyfill "^8.1.3" + jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" @@ -14718,6 +14733,13 @@ node-fetch@^2, node-fetch@^2.1.2, node-fetch@^2.6.1, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" +node-fetch@^2.6.12: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + node-forge@^1: version "1.3.1" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" @@ -16398,6 +16420,11 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== +promise-polyfill@^8.1.3: + version "8.3.0" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.3.0.tgz#9284810268138d103807b11f4e23d5e945a4db63" + integrity sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg== + promise.allsettled@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.5.tgz#2443f3d4b2aa8dfa560f6ac2aa6c4ea999d75f53" From 5ac183a3670656dc1f8579a587226d98527f0b75 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Thu, 11 Jul 2024 12:08:17 +0300 Subject: [PATCH 04/36] CW-performance-monitoring added try/catch --- .../useCases/useDiscussionMessagesById.ts | 106 +++++++++--------- 1 file changed, 55 insertions(+), 51 deletions(-) diff --git a/src/shared/hooks/useCases/useDiscussionMessagesById.ts b/src/shared/hooks/useCases/useDiscussionMessagesById.ts index ca0348c33..6d03f2126 100644 --- a/src/shared/hooks/useCases/useDiscussionMessagesById.ts +++ b/src/shared/hooks/useCases/useDiscussionMessagesById.ts @@ -155,62 +155,66 @@ export const useDiscussionMessagesById = ({ const fetchRepliedMessages = useCallback( async (messageId: string, endDate: Date): Promise => { const fetchRepliedMessagesTrace = trace(perf, 'fetchRepliedMessagesTrace'); - fetchRepliedMessagesTrace.start(); + try { + fetchRepliedMessagesTrace.start(); - if (state.data?.find((item) => item.id === messageId)) { - return Promise.resolve(); - } + if (state.data?.find((item) => item.id === messageId)) { + return Promise.resolve(); + } - const { - updatedDiscussionMessages, - removedDiscussionMessages, - lastVisibleSnapshot, - } = await DiscussionMessageService.getDiscussionMessagesByEndDate( - discussionId, - lastVisible && lastVisible[discussionId], - endDate, - ); + const { + updatedDiscussionMessages, + removedDiscussionMessages, + lastVisibleSnapshot, + } = await DiscussionMessageService.getDiscussionMessagesByEndDate( + discussionId, + lastVisible && lastVisible[discussionId], + endDate, + ); - setLastVisible((prevVisible) => ({ - ...prevVisible, - [discussionId]: lastVisibleSnapshot, - })); - const discussionsWithText = await Promise.all( - updatedDiscussionMessages.map(async (discussionMessage) => { - const isUserDiscussionMessage = - checkIsUserDiscussionMessage(discussionMessage); - const isSystemMessage = - checkIsSystemDiscussionMessage(discussionMessage); + setLastVisible((prevVisible) => ({ + ...prevVisible, + [discussionId]: lastVisibleSnapshot, + })); + const discussionsWithText = await Promise.all( + updatedDiscussionMessages.map(async (discussionMessage) => { + const isUserDiscussionMessage = + checkIsUserDiscussionMessage(discussionMessage); + const isSystemMessage = + checkIsSystemDiscussionMessage(discussionMessage); - const parsedText = await getTextFromTextEditorString({ - userId, - ownerId: isUserDiscussionMessage ? discussionMessage.ownerId : null, - textEditorString: discussionMessage.text, - users, - commonId: discussionMessage.commonId, - systemMessage: isSystemMessage ? discussionMessage : undefined, - getCommonPagePath, - getCommonPageAboutTabPath, - directParent, - onUserClick, - onFeedItemClick, - onInternalLinkClick, - }); + const parsedText = await getTextFromTextEditorString({ + userId, + ownerId: isUserDiscussionMessage ? discussionMessage.ownerId : null, + textEditorString: discussionMessage.text, + users, + commonId: discussionMessage.commonId, + systemMessage: isSystemMessage ? discussionMessage : undefined, + getCommonPagePath, + getCommonPageAboutTabPath, + directParent, + onUserClick, + onFeedItemClick, + onInternalLinkClick, + }); - return { - ...discussionMessage, - parsedText, - }; - }), - ); - dispatch( - cacheActions.updateDiscussionMessagesStateByDiscussionId({ - discussionId, - removedDiscussionMessages, - updatedDiscussionMessages: discussionsWithText, - }), - ); - fetchRepliedMessagesTrace.stop(); + return { + ...discussionMessage, + parsedText, + }; + }), + ); + dispatch( + cacheActions.updateDiscussionMessagesStateByDiscussionId({ + discussionId, + removedDiscussionMessages, + updatedDiscussionMessages: discussionsWithText, + }), + ); + fetchRepliedMessagesTrace.stop(); + } catch(err) { + fetchRepliedMessagesTrace.stop(); + } }, [ state.data, From 9db252102c80226527876d4600763f105ca5c451 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Tue, 16 Jul 2024 17:19:01 +0300 Subject: [PATCH 05/36] CW-crash-backpage Added condition for empty joinedAt --- .../MembersComponent/CommonMemberComponent.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx b/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx index 95d73d6fc..ef49ccc24 100644 --- a/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx +++ b/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx @@ -122,11 +122,13 @@ const CommonMember: FC = ({ -
- {joinedAt - .toDate() - .toLocaleDateString("en-US", { month: "short", day: "numeric" })} -
+ {joinedAt && ( +
+ {joinedAt + ?.toDate() + .toLocaleDateString("en-US", { month: "short", day: "numeric" })} +
+ )} Date: Tue, 30 Jul 2024 12:54:10 +0300 Subject: [PATCH 06/36] CW-long-breadcrumbs Added tooltip logic Added tooltip logic Updated tooltip component Optimized Breadcrumbs --- .../BreadcrumbsItem.module.scss | 13 +++ .../BreadcrumbsItem/BreadcrumbsItem.tsx | 48 ++++++++--- .../FeedItemBreadcrumbs.tsx | 41 ++++++---- .../FeedBreadcrumbsItem.tsx | 66 +++++++-------- .../TooltipContent/TooltipContent.module.scss | 5 ++ .../TooltipContent/TooltipContent.tsx | 82 +++++++++++++------ 6 files changed, 174 insertions(+), 81 deletions(-) diff --git a/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.module.scss b/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.module.scss index 76206a70e..428a4bf37 100644 --- a/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.module.scss +++ b/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.module.scss @@ -29,6 +29,19 @@ } } +.tooltipContent { + font-family: PoppinsSans, sans-serif; + font-size: $moderate-xsmall; + font-weight: normal; + color: var(--breadcrumbs-color); +} + +.li { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + @include tablet { .li { &:first-child { diff --git a/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.tsx b/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.tsx index 283926225..7b84a2908 100644 --- a/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.tsx +++ b/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.tsx @@ -1,7 +1,13 @@ -import React, { FC, useRef } from "react"; +import React, { FC, useRef, useMemo } from "react"; import { useHistory } from "react-router"; +import { useMeasure } from "react-use"; import { useRoutesContext } from "@/shared/contexts"; -import { ContextMenuRef } from "@/shared/ui-kit"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, + ContextMenuRef, +} from "@/shared/ui-kit"; import { ProjectsStateItem } from "@/store/states"; import { truncateBreadcrumbName } from "../../utils"; import { BreadcrumbsMenu } from "../BreadcrumbsMenu"; @@ -18,6 +24,9 @@ export interface BreadcrumbsItemProps { onClick?: () => void; } +const PADDING = 24; +const OVERLAY_THRESHOLD = 5; + const BreadcrumbsItem: FC = (props) => { const { activeItem, @@ -30,8 +39,18 @@ const BreadcrumbsItem: FC = (props) => { onClick, } = props; const history = useHistory(); + const [containerRef, { width: containerWidth }] = useMeasure(); + const [buttonRef, { width: buttonWidth }] = useMeasure(); + + const hasOverlay = useMemo(() => { + return ( + Math.abs( + Math.floor(containerWidth) - Math.floor(buttonWidth + PADDING), + ) >= OVERLAY_THRESHOLD + ); + }, [containerWidth, buttonWidth]); + const { getCommonPagePath } = useRoutesContext(); - const containerRef = useRef(null); const contextMenuRef = useRef(null); const handleButtonClick = () => { @@ -40,17 +59,26 @@ const BreadcrumbsItem: FC = (props) => { onClick?.(); return; } - if (containerRef.current) { - const { x, y, height } = containerRef.current.getBoundingClientRect(); - contextMenuRef.current?.open(x, y + height); - } }; return (
  • - + + + + + + {activeItem.name} + + {withMenu && ( = (props) => { - const { breadcrumbs, itemsWithMenus, truncate } = props; +const FeedItemBreadcrumbs: FC = ({ + breadcrumbs, + itemsWithMenus, + truncate, +}) => { const dispatch = useDispatch(); const goToCreateCommon = useGoToCreateCommon(); const isMobileView = useIsTabletView(); - const breadcrumbsItems = truncate - ? [breadcrumbs.items[0], breadcrumbs.items[breadcrumbs.items.length - 1]] - : breadcrumbs.items; - const handleItemClick = (item: ProjectsStateItem) => { - if (item.rootCommonId) { - dispatch( - commonLayoutActions.resetCurrentCommonIdAndProjects(item.rootCommonId), - ); - } - }; + const breadcrumbsItems = useMemo(() => { + return truncate + ? [breadcrumbs.items[0], breadcrumbs.items[breadcrumbs.items.length - 1]] + : breadcrumbs.items; + }, [breadcrumbs.items, truncate]); + + const handleItemClick = useCallback( + (item: ProjectsStateItem) => { + if (item.rootCommonId) { + dispatch( + commonLayoutActions.resetCurrentCommonIdAndProjects( + item.rootCommonId, + ), + ); + } + }, + [dispatch], + ); useEffect(() => { const commonIds = breadcrumbs.items.map((item) => item.commonId); @@ -55,7 +66,9 @@ const FeedItemBreadcrumbs: FC = (props) => { }); }); - return unsubscribe; + return () => { + unsubscribe(); + }; }, [breadcrumbs.activeItem?.id]); return ( diff --git a/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/FeedItemBreadcrumbs/components/FeedBreadcrumbsItem/FeedBreadcrumbsItem.tsx b/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/FeedItemBreadcrumbs/components/FeedBreadcrumbsItem/FeedBreadcrumbsItem.tsx index 6daa30221..95b005552 100644 --- a/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/FeedItemBreadcrumbs/components/FeedBreadcrumbsItem/FeedBreadcrumbsItem.tsx +++ b/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/FeedItemBreadcrumbs/components/FeedBreadcrumbsItem/FeedBreadcrumbsItem.tsx @@ -1,4 +1,4 @@ -import React, { FC, useMemo } from "react"; +import React, { FC, useMemo, useCallback } from "react"; import { useSelector } from "react-redux"; import { ProjectsStateItem, @@ -21,49 +21,49 @@ const getItemsByParentId = ( ): ProjectsStateItem[] => data.filter((item) => item.directParent?.commonId === parentId); -const FeedBreadcrumbsItem: FC = (props) => { - const { activeItem, ...restProps } = props; +const FeedBreadcrumbsItem: FC = ({ + activeItem, + ...restProps +}) => { const { commons, areCommonsFetched } = useSelector( selectCommonLayoutCommonsState, ); const { projects, areProjectsFetched } = useSelector( selectCommonLayoutProjectsState, ); + const parentCommonId = activeItem.directParent?.commonId; - const baseItems = useMemo( - () => - parentCommonId ? getItemsByParentId(parentCommonId, projects) : commons, - [parentCommonId, projects, commons], - ); + + const baseItems = useMemo(() => { + return parentCommonId + ? getItemsByParentId(parentCommonId, projects) + : commons; + }, [parentCommonId, projects, commons]); + const areItemsLoading = parentCommonId ? !areProjectsFetched : !areCommonsFetched; - const hasParentPermissionToAddProject = useMemo( - () => - (parentCommonId && - ( - commons.find((item) => item.commonId === parentCommonId) || - projects.find((item) => item.commonId === parentCommonId) - )?.hasPermissionToAddProject) ?? - false, - [commons, projects, parentCommonId], - ); - const items = useMemo( - () => - baseItems.length === 0 - ? [activeItem] - : [...baseItems].sort((prevItem, nextItem) => { - if (prevItem.commonId === activeItem.commonId) { - return -1; - } - if (nextItem.commonId === activeItem.commonId) { - return 1; - } - return 0; - }), - [baseItems, activeItem], - ); + const hasParentPermissionToAddProject = useMemo(() => { + if (!parentCommonId) return false; + + const parentItem = + commons.find((item) => item.commonId === parentCommonId) || + projects.find((item) => item.commonId === parentCommonId); + + return parentItem?.hasPermissionToAddProject ?? false; + }, [commons, projects, parentCommonId]); + + const items = useMemo(() => { + if (baseItems.length === 0) { + return [activeItem]; + } + return [...baseItems].sort((prevItem, nextItem) => { + if (prevItem.commonId === activeItem.commonId) return -1; + if (nextItem.commonId === activeItem.commonId) return 1; + return 0; + }); + }, [baseItems, activeItem]); return ( { + withOverlay?: boolean; +} + const TooltipContent: ForwardRefRenderFunction< HTMLDivElement, - HTMLProps + TooltipContentProps > = (props, propRef) => { + const { withOverlay } = props; const state = useTooltipContext(); const { children, ...containerProps } = state.getFloatingProps(props); const [side] = state.placement.split("-"); @@ -44,35 +49,64 @@ const TooltipContent: ForwardRefRenderFunction< [state.floating, propRef], ); + const divProps = useMemo( + () => ({ + ref, + style: { + position: state.strategy, + top: state.y ?? 0, + left: state.x ?? 0, + visibility: state.x === null ? "hidden" : "visible", + ...props.style, + } as CSSProperties, + ...containerProps, + className: containerClassName, + }), + [ + state.strategy, + state.x, + state.y, + props.style, + containerProps, + containerClassName, + ], + ); + return ( {state.open && ( -
    - {children} -
    - -
    -
    + <> + {withOverlay ? ( + +
    + {children} +
    + +
    +
    +
    + ) : ( +
    + {children} +
    + +
    +
    + )} + )}
    ); }; -export default forwardRef>( +export default forwardRef( TooltipContent, ); From cfff514c4fe897760bab4eb0f3b5bedb68c6d72c Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Wed, 31 Jul 2024 13:26:50 +0300 Subject: [PATCH 07/36] CW-crash-backpage added more conditions for joinedAt --- .../MembersComponent/CommonMemberComponent.tsx | 2 +- .../CommonDetailContainer/MembersComponent/MembersComponent.tsx | 2 +- .../components/MembersTab/components/Members/Members.tsx | 2 +- .../FeedLayout/components/ProfileContent/ProfileContent.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx b/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx index ef49ccc24..913a2b3e4 100644 --- a/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx +++ b/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx @@ -122,7 +122,7 @@ const CommonMember: FC = ({ - {joinedAt && ( + {joinedAt && joinedAt.toDate && (
    {joinedAt ?.toDate() diff --git a/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/MembersComponent.tsx b/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/MembersComponent.tsx index 5199bb858..acd0315bb 100644 --- a/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/MembersComponent.tsx +++ b/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/MembersComponent.tsx @@ -39,7 +39,7 @@ const MembersComponent: FC = ({ common }) => { () => [...commonMembers].sort( (commonMember, prevCommonMember) => - prevCommonMember.joinedAt.seconds - commonMember.joinedAt.seconds, + prevCommonMember.joinedAt?.seconds - commonMember.joinedAt?.seconds, ), [commonMembers], ); diff --git a/src/pages/common/components/CommonTabPanels/components/MembersTab/components/Members/Members.tsx b/src/pages/common/components/CommonTabPanels/components/MembersTab/components/Members/Members.tsx index 3adee34ff..2dd733f83 100644 --- a/src/pages/common/components/CommonTabPanels/components/MembersTab/components/Members/Members.tsx +++ b/src/pages/common/components/CommonTabPanels/components/MembersTab/components/Members/Members.tsx @@ -30,7 +30,7 @@ const MembersComponent: FC = (props) => { () => [...commonMembers].sort( (commonMember, prevCommonMember) => - prevCommonMember.joinedAt.seconds - commonMember.joinedAt.seconds, + prevCommonMember.joinedAt?.seconds - commonMember.joinedAt?.seconds, ), [commonMembers], ); diff --git a/src/pages/commonFeed/components/FeedLayout/components/ProfileContent/ProfileContent.tsx b/src/pages/commonFeed/components/FeedLayout/components/ProfileContent/ProfileContent.tsx index 75cdeaace..4f1ead753 100644 --- a/src/pages/commonFeed/components/FeedLayout/components/ProfileContent/ProfileContent.tsx +++ b/src/pages/commonFeed/components/FeedLayout/components/ProfileContent/ProfileContent.tsx @@ -169,7 +169,7 @@ const ProfileContent: FC = (props) => {

    Joined {common.name} at{" "} {formatDate( - new Date(commonMember.joinedAt.seconds * 1000), + new Date(commonMember.joinedAt?.seconds * 1000), DateFormat.SuperShortSecondary, )}

    From a6577d8f0f6a28c6fe9fac4ccdf39340ac02ba1a Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Thu, 1 Aug 2024 19:08:35 +0300 Subject: [PATCH 08/36] CW-some-stream-disappear Optimized FeedItem component. FIxed condition in FeedLayout --- .../common/components/FeedItem/FeedItem.tsx | 114 ++++++++++++------ .../components/FeedLayout/FeedLayout.tsx | 7 +- 2 files changed, 80 insertions(+), 41 deletions(-) diff --git a/src/pages/common/components/FeedItem/FeedItem.tsx b/src/pages/common/components/FeedItem/FeedItem.tsx index 366753b49..0c77addd8 100644 --- a/src/pages/common/components/FeedItem/FeedItem.tsx +++ b/src/pages/common/components/FeedItem/FeedItem.tsx @@ -6,10 +6,7 @@ import React, { useMemo, } from "react"; import { useFeedItemFollow } from "@/shared/hooks/useCases"; -import { - FeedLayoutItemChangeData, - SpaceListVisibility, -} from "@/shared/interfaces"; +import { FeedLayoutItemChangeData } from "@/shared/interfaces"; import { Circles, CirclesPermissions, @@ -20,7 +17,7 @@ import { CommonNotion, DirectParent, } from "@/shared/models"; -import { checkIsItemVisibleForUser, InternalLinkData } from "@/shared/utils"; +import { checkIsItemVisibleForUser } from "@/shared/utils"; import { useFeedItemSubscription } from "../../hooks"; import { DiscussionFeedCard } from "../DiscussionFeedCard"; import { ProposalFeedCard } from "../ProposalFeedCard"; @@ -113,14 +110,20 @@ const FeedItem = forwardRef((props, ref) => { const getNonAllowedItems = outerGetNonAllowedItems || contextGetNonAllowedItems; - const handleUserClick = useMemo( - () => onUserSelect && ((userId: string) => onUserSelect(userId, commonId)), + const handleUserClick = useCallback( + (userId: string) => { + if (onUserSelect) { + onUserSelect(userId, commonId); + } + }, [onUserSelect, commonId], ); const handleActiveItemDataChange = useCallback( (data: FeedLayoutItemChangeData) => { - onActiveItemDataChange?.(data, commonId); + if (onActiveItemDataChange) { + onActiveItemDataChange(data, commonId); + } }, [onActiveItemDataChange, commonId], ); @@ -130,11 +133,15 @@ const FeedItem = forwardRef((props, ref) => { feedItemFollow.isUserFeedItemFollowDataFetched && !feedItemFollow.userFeedItemFollowData ) { - onFeedItemUnfollowed?.(item.id); + if (onFeedItemUnfollowed) { + onFeedItemUnfollowed(item.id); + } } }, [ feedItemFollow.isUserFeedItemFollowDataFetched, feedItemFollow.userFeedItemFollowData, + item.id, + onFeedItemUnfollowed, ]); if ( @@ -150,35 +157,66 @@ const FeedItem = forwardRef((props, ref) => { return null; } - const generalProps = { - ref, - item, - commonId, - commonName, - commonImage, - commonNotion, - pinnedFeedItems, - isActive, - isExpanded, - isProject, - isPinned, - governanceCircles, - isPreviewMode, - getLastMessage, - commonMember, - getNonAllowedItems, - isMobileVersion, - onActiveItemDataChange: handleActiveItemDataChange, - directParent, - rootCommonId, - feedItemFollow, - onUserSelect, - shouldPreLoadMessages, - withoutMenu, - onUserClick: handleUserClick, - onFeedItemClick, - onInternalLinkClick, - }; + const generalProps = useMemo( + () => ({ + ref, + item, + commonId, + commonName, + commonImage, + commonNotion, + pinnedFeedItems, + isActive, + isExpanded, + isProject, + isPinned, + governanceCircles, + isPreviewMode, + getLastMessage, + commonMember, + getNonAllowedItems, + isMobileVersion, + onActiveItemDataChange: handleActiveItemDataChange, + directParent, + rootCommonId, + feedItemFollow, + onUserSelect, + shouldPreLoadMessages, + withoutMenu, + onUserClick: handleUserClick, + onFeedItemClick, + onInternalLinkClick, + }), + [ + ref, + item, + commonId, + commonName, + commonImage, + commonNotion, + pinnedFeedItems, + isActive, + isExpanded, + isProject, + isPinned, + governanceCircles, + isPreviewMode, + getLastMessage, + commonMember, + getNonAllowedItems, + isMobileVersion, + handleActiveItemDataChange, + directParent, + rootCommonId, + feedItemFollow, + onUserSelect, + shouldPreLoadMessages, + withoutMenu, + handleUserClick, + onFeedItemClick, + onInternalLinkClick, + ], + ); if (item.data.type === CommonFeedType.Discussion) { return ; diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx index 0f730acc8..c349b456a 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx @@ -1,14 +1,14 @@ import React, { CSSProperties, forwardRef, - ForwardRefRenderFunction, - ReactNode, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, + ReactNode, + ForwardRefRenderFunction, } from "react"; import { useSelector } from "react-redux"; import { useHistory } from "react-router-dom"; @@ -221,8 +221,9 @@ const FeedLayout: ForwardRefRenderFunction = ( fetchedCommonMember; const userForProfile = useUserForProfile(); const governance = chatItem?.nestedItemData - ? fetchedGovernance + ? fetchedGovernance || outerGovernance : outerGovernance || fetchedGovernance; + const [splitPaneRef, setSplitPaneRef] = useState(null); const maxContentSize = settings?.getSplitViewMaxSize?.(windowWidth) ?? From df78493ce9c7d3ececf4d230c8a04ad7c73bc769 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Sun, 4 Aug 2024 16:50:34 +0300 Subject: [PATCH 09/36] CW-long-breadcrumbs Fixed open menu --- .../BreadcrumbsItem/BreadcrumbsItem.tsx | 69 ++++++++++--------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.tsx b/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.tsx index 7b84a2908..37912d262 100644 --- a/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.tsx +++ b/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Breadcrumbs/components/BreadcrumbsItem/BreadcrumbsItem.tsx @@ -39,16 +39,17 @@ const BreadcrumbsItem: FC = (props) => { onClick, } = props; const history = useHistory(); - const [containerRef, { width: containerWidth }] = useMeasure(); + const containerRef = useRef(null); + const [listRef, { width: listWidth }] = useMeasure(); const [buttonRef, { width: buttonWidth }] = useMeasure(); const hasOverlay = useMemo(() => { return ( Math.abs( - Math.floor(containerWidth) - Math.floor(buttonWidth + PADDING), + Math.floor(listWidth) - Math.floor(buttonWidth + PADDING), ) >= OVERLAY_THRESHOLD ); - }, [containerWidth, buttonWidth]); + }, [listWidth, buttonWidth]); const { getCommonPagePath } = useRoutesContext(); const contextMenuRef = useRef(null); @@ -59,37 +60,43 @@ const BreadcrumbsItem: FC = (props) => { onClick?.(); return; } + if (containerRef.current) { + const { x, y, height } = containerRef.current.getBoundingClientRect(); + contextMenuRef.current?.open(x, y + height); + } }; return ( -
  • - - - - - - {activeItem.name} - - - {withMenu && ( - - )} -
  • +
    +
  • + + + + + + {activeItem.name} + + + {withMenu && ( + + )} +
  • +
    ); }; From 09e57233b5193f8eeb907f5f280d3c150f6a39b4 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Sun, 4 Aug 2024 18:39:18 +0300 Subject: [PATCH 10/36] CW-long-breadcrumbs Added margin-left to my spaces icon --- .../Header/components/Navigation/Navigation.module.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Navigation/Navigation.module.scss b/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Navigation/Navigation.module.scss index 1cd5199ec..87c25cb51 100644 --- a/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Navigation/Navigation.module.scss +++ b/src/shared/layouts/MultipleSpacesLayout/components/Header/components/Navigation/Navigation.module.scss @@ -10,6 +10,7 @@ color: inherit; width: 1.3rem; height: 1.3rem; + margin-left: 0.75rem; } .list { From 0e0bde068773e2693da6606b4e07e5e8c383bfdc Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 5 Aug 2024 15:37:52 +0300 Subject: [PATCH 11/36] CW-some-stream-disappear Fixed Render fewer hooks issue --- .../common/components/FeedItem/FeedItem.tsx | 26 ++++++++++--------- .../components/FeedLayout/FeedLayout.tsx | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/pages/common/components/FeedItem/FeedItem.tsx b/src/pages/common/components/FeedItem/FeedItem.tsx index 0c77addd8..56b8afca4 100644 --- a/src/pages/common/components/FeedItem/FeedItem.tsx +++ b/src/pages/common/components/FeedItem/FeedItem.tsx @@ -144,18 +144,6 @@ const FeedItem = forwardRef((props, ref) => { onFeedItemUnfollowed, ]); - if ( - shouldCheckItemVisibility && - !checkIsItemVisibleForUser({ - itemCircleVisibility: item.circleVisibility, - userCircleIds, - itemUserId: item.userId, - currentUserId, - itemDataType: item.data.type, - }) - ) { - return null; - } const generalProps = useMemo( () => ({ @@ -218,6 +206,20 @@ const FeedItem = forwardRef((props, ref) => { ], ); + + if ( + shouldCheckItemVisibility && + !checkIsItemVisibleForUser({ + itemCircleVisibility: item.circleVisibility, + userCircleIds, + itemUserId: item.userId, + currentUserId, + itemDataType: item.data.type, + }) + ) { + return null; + } + if (item.data.type === CommonFeedType.Discussion) { return ; } diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx index c349b456a..c57d97461 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx @@ -221,7 +221,7 @@ const FeedLayout: ForwardRefRenderFunction = ( fetchedCommonMember; const userForProfile = useUserForProfile(); const governance = chatItem?.nestedItemData - ? fetchedGovernance || outerGovernance + ? (fetchedGovernance || outerGovernance) : outerGovernance || fetchedGovernance; const [splitPaneRef, setSplitPaneRef] = useState(null); From c14a3be245e166ba5e18d3aae3f5ed629f77c442 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Tue, 6 Aug 2024 13:03:43 +0300 Subject: [PATCH 12/36] CW-some-stream-disappear Added names to components for better debugging --- .../DiscussionFeedCard/DiscussionFeedCard.tsx | 762 +++++++++--------- .../common/components/FeedCard/FeedCard.tsx | 6 +- src/pages/common/components/FeedCard/index.ts | 2 +- .../ProposalFeedCard/ProposalFeedCard.tsx | 740 +++++++++-------- 4 files changed, 754 insertions(+), 756 deletions(-) diff --git a/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx b/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx index 3da4b2a80..06a09cc7f 100644 --- a/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx +++ b/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx @@ -78,409 +78,407 @@ interface DiscussionFeedCardProps { onInternalLinkClick: (data: InternalLinkData) => void; } -const DiscussionFeedCard = forwardRef( - (props, ref) => { - const { - setChatItem, - feedItemIdForAutoChatOpen, - shouldAllowChatAutoOpen, - nestedItemData, - } = useChatContext(); - const { notify } = useNotification(); - const { - item, - governanceCircles, - isMobileVersion = false, +function DiscussionFeedCard(props, ref) { + const { + setChatItem, + feedItemIdForAutoChatOpen, + shouldAllowChatAutoOpen, + nestedItemData, + } = useChatContext(); + const { notify } = useNotification(); + const { + item, + governanceCircles, + isMobileVersion = false, + commonId, + commonName, + commonImage, + commonNotion: outerCommonNotion, + pinnedFeedItems, + commonMember, + isProject, + isPinned, + isPreviewMode, + isActive, + isExpanded, + getLastMessage, + getNonAllowedItems, + onActiveItemDataChange, + directParent, + rootCommonId, + feedItemFollow, + shouldPreLoadMessages, + withoutMenu, + onUserClick, + onFeedItemClick, + onInternalLinkClick, + } = props; + const { + isShowing: isReportModalOpen, + onOpen: onReportModalOpen, + onClose: onReportModalClose, + } = useModal(false); + const { + isShowing: isShareModalOpen, + onOpen: onShareModalOpen, + onClose: onShareModalClose, + } = useModal(false); + const { + isShowing: isDeleteModalOpen, + onOpen: onDeleteModalOpen, + onClose: onDeleteModalClose, + } = useModal(false); + const { + isShowing: isLinkStreamModalOpen, + onOpen: onLinkStreamModalOpen, + onClose: onLinkStreamModalClose, + } = useModal(false); + const { + isShowing: isUnlinkStreamModalOpen, + onOpen: onUnlinkStreamModalOpen, + onClose: onUnlinkStreamModalClose, + } = useModal(false); + const { + isShowing: isMoveStreamModalOpen, + onOpen: onMoveStreamModalOpen, + onClose: onMoveStreamModalClose, + } = useModal(false); + const [isDeletingInProgress, setDeletingInProgress] = useState(false); + const { + fetchUser: fetchDiscussionCreator, + data: discussionCreator, + fetched: isDiscussionCreatorFetched, + } = useUserById(); + const { + fetchDiscussion, + data: discussion, + fetched: isDiscussionFetched, + } = useDiscussionById(); + const isHome = discussion?.predefinedType === PredefinedTypes.General; + const discussionNotion = commonId + ? discussion?.notionByCommon?.[commonId] + : undefined; + const { + data: feedItemUserMetadata, + fetched: isFeedItemUserMetadataFetched, + fetchFeedItemUserMetadata, + } = useFeedItemUserMetadata(); + const shouldLoadCommonData = + isHome || (discussionNotion && !outerCommonNotion); + const { data: common } = useCommon(shouldLoadCommonData ? commonId : ""); + const preloadDiscussionMessagesData = usePreloadDiscussionMessagesById({ + commonId, + discussionId: discussion?.id, + onUserClick, + onFeedItemClick, + onInternalLinkClick, + }); + const { markFeedItemAsSeen, markFeedItemAsUnseen } = + useUpdateFeedItemSeenState(); + const menuItems = useMenuItems( + { commonId, - commonName, - commonImage, - commonNotion: outerCommonNotion, pinnedFeedItems, + feedItem: item, + discussion, + governanceCircles, commonMember, - isProject, - isPinned, - isPreviewMode, - isActive, - isExpanded, - getLastMessage, - getNonAllowedItems, - onActiveItemDataChange, - directParent, - rootCommonId, feedItemFollow, - shouldPreLoadMessages, + getNonAllowedItems, + feedItemUserMetadata, withoutMenu, - onUserClick, - onFeedItemClick, - onInternalLinkClick, - } = props; - const { - isShowing: isReportModalOpen, - onOpen: onReportModalOpen, - onClose: onReportModalClose, - } = useModal(false); - const { - isShowing: isShareModalOpen, - onOpen: onShareModalOpen, - onClose: onShareModalClose, - } = useModal(false); - const { - isShowing: isDeleteModalOpen, - onOpen: onDeleteModalOpen, - onClose: onDeleteModalClose, - } = useModal(false); - const { - isShowing: isLinkStreamModalOpen, - onOpen: onLinkStreamModalOpen, - onClose: onLinkStreamModalClose, - } = useModal(false); - const { - isShowing: isUnlinkStreamModalOpen, - onOpen: onUnlinkStreamModalOpen, - onClose: onUnlinkStreamModalClose, - } = useModal(false); - const { - isShowing: isMoveStreamModalOpen, - onOpen: onMoveStreamModalOpen, - onClose: onMoveStreamModalClose, - } = useModal(false); - const [isDeletingInProgress, setDeletingInProgress] = useState(false); - const { - fetchUser: fetchDiscussionCreator, - data: discussionCreator, - fetched: isDiscussionCreatorFetched, - } = useUserById(); - const { - fetchDiscussion, - data: discussion, - fetched: isDiscussionFetched, - } = useDiscussionById(); - const isHome = discussion?.predefinedType === PredefinedTypes.General; - const discussionNotion = commonId - ? discussion?.notionByCommon?.[commonId] - : undefined; - const { - data: feedItemUserMetadata, - fetched: isFeedItemUserMetadataFetched, - fetchFeedItemUserMetadata, - } = useFeedItemUserMetadata(); - const shouldLoadCommonData = - isHome || (discussionNotion && !outerCommonNotion); - const { data: common } = useCommon(shouldLoadCommonData ? commonId : ""); - const preloadDiscussionMessagesData = usePreloadDiscussionMessagesById({ - commonId, - discussionId: discussion?.id, - onUserClick, - onFeedItemClick, - onInternalLinkClick, - }); - const { markFeedItemAsSeen, markFeedItemAsUnseen } = - useUpdateFeedItemSeenState(); - const menuItems = useMenuItems( - { - commonId, - pinnedFeedItems, - feedItem: item, - discussion, - governanceCircles, - commonMember, - feedItemFollow, - getNonAllowedItems, - feedItemUserMetadata, - withoutMenu, - }, - { - report: onReportModalOpen, - share: () => onShareModalOpen(), - remove: onDeleteModalOpen, - linkStream: onLinkStreamModalOpen, - unlinkStream: onUnlinkStreamModalOpen, - moveStream: onMoveStreamModalOpen, - markFeedItemAsSeen, - markFeedItemAsUnseen, - }, - ); - const user = useSelector(selectUser()); - const [isHovering, setHovering] = useState(false); - const onHover = (isMouseEnter: boolean): void => { - setHovering(isMouseEnter); - }; - const userId = user?.uid; - const isLoading = - !isDiscussionCreatorFetched || - !isDiscussionFetched || - !isFeedItemUserMetadataFetched || - !commonId; - const cardTitle = discussion?.title; - const commonNotion = outerCommonNotion ?? common?.notion; + }, + { + report: onReportModalOpen, + share: () => onShareModalOpen(), + remove: onDeleteModalOpen, + linkStream: onLinkStreamModalOpen, + unlinkStream: onUnlinkStreamModalOpen, + moveStream: onMoveStreamModalOpen, + markFeedItemAsSeen, + markFeedItemAsUnseen, + }, + ); + const user = useSelector(selectUser()); + const [isHovering, setHovering] = useState(false); + const onHover = (isMouseEnter: boolean): void => { + setHovering(isMouseEnter); + }; + const userId = user?.uid; + const isLoading = + !isDiscussionCreatorFetched || + !isDiscussionFetched || + !isFeedItemUserMetadataFetched || + !commonId; + const cardTitle = discussion?.title; + const commonNotion = outerCommonNotion ?? common?.notion; - const handleOpenChat = useCallback(() => { - if (discussion && !isPreviewMode) { - setChatItem({ - feedItemId: item.id, - discussion, - circleVisibility: item.circleVisibility, - lastSeenItem: feedItemUserMetadata?.lastSeen, - lastSeenAt: feedItemUserMetadata?.lastSeenAt, - count: feedItemUserMetadata?.count, - seenOnce: feedItemUserMetadata?.seenOnce, - seen: feedItemUserMetadata?.seen, - hasUnseenMention: feedItemUserMetadata?.hasUnseenMention, - nestedItemData: nestedItemData && { - ...nestedItemData, - feedItem: { - type: InboxItemType.FeedItemFollow, - itemId: item.id, - feedItem: item, - }, + const handleOpenChat = useCallback(() => { + if (discussion && !isPreviewMode) { + setChatItem({ + feedItemId: item.id, + discussion, + circleVisibility: item.circleVisibility, + lastSeenItem: feedItemUserMetadata?.lastSeen, + lastSeenAt: feedItemUserMetadata?.lastSeenAt, + count: feedItemUserMetadata?.count, + seenOnce: feedItemUserMetadata?.seenOnce, + seen: feedItemUserMetadata?.seen, + hasUnseenMention: feedItemUserMetadata?.hasUnseenMention, + nestedItemData: nestedItemData && { + ...nestedItemData, + feedItem: { + type: InboxItemType.FeedItemFollow, + itemId: item.id, + feedItem: item, }, - }); - } - }, [ - discussion, - item.id, - item.circleVisibility, - feedItemUserMetadata?.lastSeen, - feedItemUserMetadata?.lastSeenAt, - feedItemUserMetadata?.count, - feedItemUserMetadata?.seenOnce, - feedItemUserMetadata?.seen, - feedItemUserMetadata?.hasUnseenMention, - nestedItemData, - isPreviewMode, - ]); + }, + }); + } + }, [ + discussion, + item.id, + item.circleVisibility, + feedItemUserMetadata?.lastSeen, + feedItemUserMetadata?.lastSeenAt, + feedItemUserMetadata?.count, + feedItemUserMetadata?.seenOnce, + feedItemUserMetadata?.seen, + feedItemUserMetadata?.hasUnseenMention, + nestedItemData, + isPreviewMode, + ]); - const onDiscussionDelete = useCallback(async () => { - try { - if (discussion) { - setDeletingInProgress(true); - await DiscussionService.deleteDiscussion(discussion.id); - onDeleteModalClose(); - } - } catch { - notify("Something went wrong"); - } finally { - setDeletingInProgress(false); + const onDiscussionDelete = useCallback(async () => { + try { + if (discussion) { + setDeletingInProgress(true); + await DiscussionService.deleteDiscussion(discussion.id); + onDeleteModalClose(); } - }, [discussion]); + } catch { + notify("Something went wrong"); + } finally { + setDeletingInProgress(false); + } + }, [discussion]); - const preloadDiscussionMessages = useMemo( - () => - debounce< - typeof preloadDiscussionMessagesData.preloadDiscussionMessages - >( - (...args) => - preloadDiscussionMessagesData.preloadDiscussionMessages(...args), - 6000, - ), - [preloadDiscussionMessagesData.preloadDiscussionMessages], - ); + const preloadDiscussionMessages = useMemo( + () => + debounce( + (...args) => + preloadDiscussionMessagesData.preloadDiscussionMessages(...args), + 6000, + ), + [preloadDiscussionMessagesData.preloadDiscussionMessages], + ); - useEffect(() => { - fetchDiscussionCreator(item.userId); - }, [item.userId]); + useEffect(() => { + fetchDiscussionCreator(item.userId); + }, [item.userId]); - useEffect(() => { - fetchDiscussion(item.data.id); - }, [item.data.id]); + useEffect(() => { + fetchDiscussion(item.data.id); + }, [item.data.id]); - useEffect(() => { - if (commonId) { - fetchFeedItemUserMetadata({ - userId: userId || "", - commonId, - feedObjectId: item.id, - }); - } - }, [userId, commonId, item.id]); + useEffect(() => { + if (commonId) { + fetchFeedItemUserMetadata({ + userId: userId || "", + commonId, + feedObjectId: item.id, + }); + } + }, [userId, commonId, item.id]); - useEffect(() => { - if ( - (!isActive || - shouldAllowChatAutoOpen === null || - shouldAllowChatAutoOpen) && - isDiscussionFetched && - isFeedItemUserMetadataFetched && - item.id === feedItemIdForAutoChatOpen && - !isMobileVersion - ) { - handleOpenChat(); - } - }, [ - isDiscussionFetched, - isFeedItemUserMetadataFetched, - shouldAllowChatAutoOpen, - ]); + useEffect(() => { + if ( + (!isActive || + shouldAllowChatAutoOpen === null || + shouldAllowChatAutoOpen) && + isDiscussionFetched && + isFeedItemUserMetadataFetched && + item.id === feedItemIdForAutoChatOpen && + !isMobileVersion + ) { + handleOpenChat(); + } + }, [ + isDiscussionFetched, + isFeedItemUserMetadataFetched, + shouldAllowChatAutoOpen, + ]); - useEffect(() => { - if (isActive && shouldAllowChatAutoOpen !== null) { - handleOpenChat(); - } - }, [isActive, shouldAllowChatAutoOpen, handleOpenChat]); + useEffect(() => { + if (isActive && shouldAllowChatAutoOpen !== null) { + handleOpenChat(); + } + }, [isActive, shouldAllowChatAutoOpen, handleOpenChat]); - useEffect(() => { - if (isActive && cardTitle) { - onActiveItemDataChange?.({ - itemId: item.id, - title: cardTitle, - }); - } - }, [isActive, cardTitle]); + useEffect(() => { + if (isActive && cardTitle) { + onActiveItemDataChange?.({ + itemId: item.id, + title: cardTitle, + }); + } + }, [isActive, cardTitle]); - useEffect(() => { - if ( - shouldPreLoadMessages && - !isActive && - commonId && - item.circleVisibility - ) { - preloadDiscussionMessages(item.circleVisibility); - } - }, [shouldPreLoadMessages, isActive]); + useEffect(() => { + if ( + shouldPreLoadMessages && + !isActive && + commonId && + item.circleVisibility + ) { + preloadDiscussionMessages(item.circleVisibility); + } + }, [shouldPreLoadMessages, isActive]); - useUpdateEffect(() => { - if ( - shouldPreLoadMessages && - !isActive && - commonId && - item.circleVisibility - ) { - preloadDiscussionMessages(item.circleVisibility, true); - } - }, [item.data.lastMessage?.content]); + useUpdateEffect(() => { + if ( + shouldPreLoadMessages && + !isActive && + commonId && + item.circleVisibility + ) { + preloadDiscussionMessages(item.circleVisibility, true); + } + }, [item.data.lastMessage?.content]); - return ( - <> - - {(isExpanded || isActive) && ( - onUserClick(item.userId))} - discussionCreator={discussionCreator} - isHome={isHome} - menuItems={menuItems} - discussion={discussion} - common={common} - discussionNotion={discussionNotion} - handleOpenChat={handleOpenChat} - onHover={onHover} - isLoading={isLoading} - /> - )} - - {userId && discussion && ( - + + {(isExpanded || isActive) && ( + onUserClick(item.userId))} + discussionCreator={discussionCreator} + isHome={isHome} + menuItems={menuItems} + discussion={discussion} + common={common} + discussionNotion={discussionNotion} + handleOpenChat={handleOpenChat} + onHover={onHover} + isLoading={isLoading} /> )} - {discussion && ( - + {userId && discussion && ( + + )} + {discussion && ( + + )} + {isDeleteModalOpen && ( + + + + )} + {commonId && ( + <> + - )} - {isDeleteModalOpen && ( - - - - )} - {commonId && ( - <> - - - - - )} - - ); - }, -); + + + + )} + + ); +} -export default DiscussionFeedCard; +export default forwardRef( + DiscussionFeedCard, +); diff --git a/src/pages/common/components/FeedCard/FeedCard.tsx b/src/pages/common/components/FeedCard/FeedCard.tsx index 65f87967a..353d5bd9e 100644 --- a/src/pages/common/components/FeedCard/FeedCard.tsx +++ b/src/pages/common/components/FeedCard/FeedCard.tsx @@ -60,7 +60,7 @@ type FeedCardProps = PropsWithChildren<{ linkedCommonIds?: string[]; }>; -export const FeedCard = forwardRef((props, ref) => { +const FeedCard = (props, ref) => { const { className, feedItemId, @@ -278,4 +278,6 @@ export const FeedCard = forwardRef((props, ref) => { ); -}); +}; + +export default forwardRef(FeedCard); diff --git a/src/pages/common/components/FeedCard/index.ts b/src/pages/common/components/FeedCard/index.ts index 71201cbdf..257e55820 100644 --- a/src/pages/common/components/FeedCard/index.ts +++ b/src/pages/common/components/FeedCard/index.ts @@ -1,4 +1,4 @@ -export * from "./FeedCard"; +export { default as FeedCard } from "./FeedCard"; export * from "./components"; export * from "./types"; export * from "./utils"; diff --git a/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx b/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx index 949dcea0c..591068e5e 100644 --- a/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx +++ b/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx @@ -72,400 +72,398 @@ interface ProposalFeedCardProps { onInternalLinkClick: (data: InternalLinkData) => void; } -const ProposalFeedCard = forwardRef( - (props, ref) => { - const { +function ProposalFeedCard(props: ProposalFeedCardProps, ref: React.Ref) { + const { + commonId, + commonName, + commonImage, + commonNotion: outerCommonNotion, + pinnedFeedItems, + isProject, + isPinned, + item, + governanceCircles, + isPreviewMode, + isActive, + isExpanded, + getLastMessage, + getNonAllowedItems, + isMobileVersion, + feedItemFollow, + onActiveItemDataChange, + shouldPreLoadMessages, + withoutMenu, + onUserClick, + onFeedItemClick, + onInternalLinkClick, + } = props; + const user = useSelector(selectUser()); + const userId = user?.uid; + const { + setChatItem, + feedItemIdForAutoChatOpen, + shouldAllowChatAutoOpen, + nestedItemData, + } = useChatContext(); + const { notify } = useNotification(); + const forceUpdate = useForceUpdate(); + const { getCommonPagePath } = useRoutesContext(); + const { + fetchUser: fetchFeedItemUser, + data: feedItemUser, + fetched: isFeedItemUserFetched, + } = useUserById(); + const { + fetchDiscussion, + data: discussion, + fetched: isDiscussionFetched, + } = useDiscussionById(); + const { + fetchProposal, + data: proposal, + fetched: isProposalFetched, + } = useProposalById(); + const { + fetched: isCommonMemberFetched, + data: commonMember, + fetchCommonMember, + } = useCommonMember(); + const { + data: userVote, + loading: isUserVoteLoading, + fetchProposalVote, + setVote, + } = useProposalUserVote(); + const { + data: proposalSpecificData, + fetched: isProposalSpecificDataFetched, + fetchData: fetchProposalSpecificData, + } = useProposalSpecificData(); + const { + data: feedItemUserMetadata, + fetched: isFeedItemUserMetadataFetched, + fetchFeedItemUserMetadata, + } = useFeedItemUserMetadata(); + const discussionNotion = commonId + ? discussion?.notionByCommon?.[commonId] + : undefined; + const shouldLoadCommonData = discussionNotion && !outerCommonNotion; + const { data: common } = useCommon(shouldLoadCommonData ? commonId : ""); + const { + isShowing: isProposalDeleteModalOpen, + onOpen: onProposalDeleteModalOpen, + onClose: onProposalDeleteModalClose, + } = useModal(false); + const [isProposalDeletingInProgress, setProposalDeletingInProgress] = + useState(false); + const isLoading = + !isFeedItemUserFetched || + !isDiscussionFetched || + !isProposalFetched || + !proposal || + isUserVoteLoading || + !isCommonMemberFetched || + !isProposalSpecificDataFetched || + !isFeedItemUserMetadataFetched || + !commonId || + !governanceCircles; + const [isHovering, setHovering] = useState(false); + const onHover = (isMouseEnter: boolean): void => { + setHovering(isMouseEnter); + }; + const proposalId = item.data.id; + const { + isShowing: isShareModalOpen, + onOpen: onShareModalOpen, + onClose: onShareModalClose, + } = useModal(false); + const preloadDiscussionMessagesData = usePreloadDiscussionMessagesById({ + commonId, + discussionId: discussion?.id, + onUserClick, + onFeedItemClick, + onInternalLinkClick, + }); + const { markFeedItemAsSeen, markFeedItemAsUnseen } = + useUpdateFeedItemSeenState(); + const menuItems = useMenuItems( + { commonId, - commonName, - commonImage, - commonNotion: outerCommonNotion, pinnedFeedItems, - isProject, - isPinned, - item, + feedItem: item, + discussion, governanceCircles, - isPreviewMode, - isActive, - isExpanded, - getLastMessage, - getNonAllowedItems, - isMobileVersion, + commonMember, feedItemFollow, - onActiveItemDataChange, - shouldPreLoadMessages, + getNonAllowedItems, + feedItemUserMetadata, withoutMenu, - onUserClick, - onFeedItemClick, - onInternalLinkClick, - } = props; - const user = useSelector(selectUser()); - const userId = user?.uid; - const { - setChatItem, - feedItemIdForAutoChatOpen, - shouldAllowChatAutoOpen, - nestedItemData, - } = useChatContext(); - const { notify } = useNotification(); - const forceUpdate = useForceUpdate(); - const { getCommonPagePath } = useRoutesContext(); - const { - fetchUser: fetchFeedItemUser, - data: feedItemUser, - fetched: isFeedItemUserFetched, - } = useUserById(); - const { - fetchDiscussion, - data: discussion, - fetched: isDiscussionFetched, - } = useDiscussionById(); - const { - fetchProposal, - data: proposal, - fetched: isProposalFetched, - } = useProposalById(); - const { - fetched: isCommonMemberFetched, - data: commonMember, - fetchCommonMember, - } = useCommonMember(); - const { - data: userVote, - loading: isUserVoteLoading, - fetchProposalVote, - setVote, - } = useProposalUserVote(); - const { - data: proposalSpecificData, - fetched: isProposalSpecificDataFetched, - fetchData: fetchProposalSpecificData, - } = useProposalSpecificData(); - const { - data: feedItemUserMetadata, - fetched: isFeedItemUserMetadataFetched, - fetchFeedItemUserMetadata, - } = useFeedItemUserMetadata(); - const discussionNotion = commonId - ? discussion?.notionByCommon?.[commonId] - : undefined; - const shouldLoadCommonData = discussionNotion && !outerCommonNotion; - const { data: common } = useCommon(shouldLoadCommonData ? commonId : ""); - const { - isShowing: isProposalDeleteModalOpen, - onOpen: onProposalDeleteModalOpen, - onClose: onProposalDeleteModalClose, - } = useModal(false); - const [isProposalDeletingInProgress, setProposalDeletingInProgress] = - useState(false); - const isLoading = - !isFeedItemUserFetched || - !isDiscussionFetched || - !isProposalFetched || - !proposal || - isUserVoteLoading || - !isCommonMemberFetched || - !isProposalSpecificDataFetched || - !isFeedItemUserMetadataFetched || - !commonId || - !governanceCircles; - const [isHovering, setHovering] = useState(false); - const onHover = (isMouseEnter: boolean): void => { - setHovering(isMouseEnter); - }; - const proposalId = item.data.id; - const { - isShowing: isShareModalOpen, - onOpen: onShareModalOpen, - onClose: onShareModalClose, - } = useModal(false); - const preloadDiscussionMessagesData = usePreloadDiscussionMessagesById({ - commonId, - discussionId: discussion?.id, - onUserClick, - onFeedItemClick, - onInternalLinkClick, - }); - const { markFeedItemAsSeen, markFeedItemAsUnseen } = - useUpdateFeedItemSeenState(); - const menuItems = useMenuItems( - { - commonId, - pinnedFeedItems, - feedItem: item, - discussion, - governanceCircles, - commonMember, - feedItemFollow, - getNonAllowedItems, - feedItemUserMetadata, - withoutMenu, - }, - { - report: () => {}, - share: () => onShareModalOpen(), - remove: onProposalDeleteModalOpen, - markFeedItemAsSeen, - markFeedItemAsUnseen, - }, - ); - const cardTitle = discussion?.title; - const commonNotion = outerCommonNotion ?? common?.notion; + }, + { + report: () => {}, + share: () => onShareModalOpen(), + remove: onProposalDeleteModalOpen, + markFeedItemAsSeen, + markFeedItemAsUnseen, + }, + ); + const cardTitle = discussion?.title; + const commonNotion = outerCommonNotion ?? common?.notion; - const onProposalDelete = useCallback(async () => { - try { - setProposalDeletingInProgress(true); - await ProposalService.deleteProposal(proposalId); - onProposalDeleteModalClose(); - } catch { - notify("Something went wrong"); - } finally { - setProposalDeletingInProgress(false); - } - }, [proposalId]); + const onProposalDelete = useCallback(async () => { + try { + setProposalDeletingInProgress(true); + await ProposalService.deleteProposal(proposalId); + onProposalDeleteModalClose(); + } catch { + notify("Something went wrong"); + } finally { + setProposalDeletingInProgress(false); + } + }, [proposalId]); - const preloadDiscussionMessages = useMemo( - () => - debounce< - typeof preloadDiscussionMessagesData.preloadDiscussionMessages - >( - (...args) => - preloadDiscussionMessagesData.preloadDiscussionMessages(...args), - 6000, - ), - [preloadDiscussionMessagesData.preloadDiscussionMessages], - ); + const preloadDiscussionMessages = useMemo( + () => + debounce< + typeof preloadDiscussionMessagesData.preloadDiscussionMessages + >( + (...args) => + preloadDiscussionMessagesData.preloadDiscussionMessages(...args), + 6000, + ), + [preloadDiscussionMessagesData.preloadDiscussionMessages], + ); - useEffect(() => { - fetchFeedItemUser(item.userId); - }, [item.userId]); + useEffect(() => { + fetchFeedItemUser(item.userId); + }, [item.userId]); - useEffect(() => { - if (item.data.discussionId) { - fetchDiscussion(item.data.discussionId); - } - }, [item.data.discussionId]); + useEffect(() => { + if (item.data.discussionId) { + fetchDiscussion(item.data.discussionId); + } + }, [item.data.discussionId]); - useEffect(() => { - fetchProposal(item.data.id); - }, [item.data.id]); + useEffect(() => { + fetchProposal(item.data.id); + }, [item.data.id]); - useEffect(() => { - fetchProposalVote(proposalId); - }, [fetchProposalVote, proposalId]); + useEffect(() => { + fetchProposalVote(proposalId); + }, [fetchProposalVote, proposalId]); - useEffect(() => { - if (commonId) { - fetchCommonMember(commonId, {}); - } - }, [fetchCommonMember, commonId]); + useEffect(() => { + if (commonId) { + fetchCommonMember(commonId, {}); + } + }, [fetchCommonMember, commonId]); - useEffect(() => { - if (commonId) { - fetchFeedItemUserMetadata({ - userId: userId || "", - commonId, - feedObjectId: item.id, - }); - } - }, [userId, commonId, item.id]); + useEffect(() => { + if (commonId) { + fetchFeedItemUserMetadata({ + userId: userId || "", + commonId, + feedObjectId: item.id, + }); + } + }, [userId, commonId, item.id]); - useEffect(() => { - if (proposal) { - fetchProposalSpecificData(proposal, true); - } - }, [proposal?.id]); + useEffect(() => { + if (proposal) { + fetchProposalSpecificData(proposal, true); + } + }, [proposal?.id]); - useEffect(() => { - if (isActive && cardTitle) { - onActiveItemDataChange?.({ - itemId: item.id, - title: cardTitle, - }); - } - }, [isActive, cardTitle]); + useEffect(() => { + if (isActive && cardTitle) { + onActiveItemDataChange?.({ + itemId: item.id, + title: cardTitle, + }); + } + }, [isActive, cardTitle]); - const handleOpenChat = useCallback(() => { - if (discussion && proposal && !isPreviewMode) { - setChatItem({ - feedItemId: item.id, - discussion, - proposal, - circleVisibility: item.circleVisibility, - lastSeenItem: feedItemUserMetadata?.lastSeen, - lastSeenAt: feedItemUserMetadata?.lastSeenAt, - seenOnce: feedItemUserMetadata?.seenOnce, - seen: feedItemUserMetadata?.seen, - hasUnseenMention: feedItemUserMetadata?.hasUnseenMention, - nestedItemData: nestedItemData && { - ...nestedItemData, - feedItem: { - type: InboxItemType.FeedItemFollow, - itemId: item.id, - feedItem: item, - }, + const handleOpenChat = useCallback(() => { + if (discussion && proposal && !isPreviewMode) { + setChatItem({ + feedItemId: item.id, + discussion, + proposal, + circleVisibility: item.circleVisibility, + lastSeenItem: feedItemUserMetadata?.lastSeen, + lastSeenAt: feedItemUserMetadata?.lastSeenAt, + seenOnce: feedItemUserMetadata?.seenOnce, + seen: feedItemUserMetadata?.seen, + hasUnseenMention: feedItemUserMetadata?.hasUnseenMention, + nestedItemData: nestedItemData && { + ...nestedItemData, + feedItem: { + type: InboxItemType.FeedItemFollow, + itemId: item.id, + feedItem: item, }, - }); - } - }, [ - item.id, - proposal, - discussion, - setChatItem, - item.circleVisibility, - feedItemUserMetadata?.lastSeen, - feedItemUserMetadata?.lastSeenAt, - feedItemUserMetadata?.seenOnce, - feedItemUserMetadata?.seen, - feedItemUserMetadata?.hasUnseenMention, - nestedItemData, - isPreviewMode, - ]); + }, + }); + } + }, [ + item.id, + proposal, + discussion, + setChatItem, + item.circleVisibility, + feedItemUserMetadata?.lastSeen, + feedItemUserMetadata?.lastSeenAt, + feedItemUserMetadata?.seenOnce, + feedItemUserMetadata?.seen, + feedItemUserMetadata?.hasUnseenMention, + nestedItemData, + isPreviewMode, + ]); - useEffect(() => { - if ( - (!isActive || - shouldAllowChatAutoOpen === null || - shouldAllowChatAutoOpen) && - isDiscussionFetched && - isProposalFetched && - isFeedItemUserMetadataFetched && - item.id === feedItemIdForAutoChatOpen && - !isMobileVersion - ) { - handleOpenChat(); - } - }, [ - isDiscussionFetched, - isProposalFetched, - isFeedItemUserMetadataFetched, - shouldAllowChatAutoOpen, - ]); + useEffect(() => { + if ( + (!isActive || + shouldAllowChatAutoOpen === null || + shouldAllowChatAutoOpen) && + isDiscussionFetched && + isProposalFetched && + isFeedItemUserMetadataFetched && + item.id === feedItemIdForAutoChatOpen && + !isMobileVersion + ) { + handleOpenChat(); + } + }, [ + isDiscussionFetched, + isProposalFetched, + isFeedItemUserMetadataFetched, + shouldAllowChatAutoOpen, + ]); - useEffect(() => { - if (isActive && shouldAllowChatAutoOpen !== null) { - handleOpenChat(); - } - }, [isActive, shouldAllowChatAutoOpen, handleOpenChat]); + useEffect(() => { + if (isActive && shouldAllowChatAutoOpen !== null) { + handleOpenChat(); + } + }, [isActive, shouldAllowChatAutoOpen, handleOpenChat]); - useEffect(() => { - if (isExpanded) { - forceUpdate(); - } - }, [isExpanded]); + useEffect(() => { + if (isExpanded) { + forceUpdate(); + } + }, [isExpanded]); - useEffect(() => { - if ( - shouldPreLoadMessages && - !isActive && - commonId && - item.circleVisibility - ) { - preloadDiscussionMessages(item.circleVisibility); - } - }, [shouldPreLoadMessages, isActive]); + useEffect(() => { + if ( + shouldPreLoadMessages && + !isActive && + commonId && + item.circleVisibility + ) { + preloadDiscussionMessages(item.circleVisibility); + } + }, [shouldPreLoadMessages, isActive]); - useUpdateEffect(() => { - if ( - shouldPreLoadMessages && - !isActive && - commonId && - item.circleVisibility - ) { - preloadDiscussionMessages(item.circleVisibility, true); - } - }, [item.data.lastMessage?.content]); + useUpdateEffect(() => { + if ( + shouldPreLoadMessages && + !isActive && + commonId && + item.circleVisibility + ) { + preloadDiscussionMessages(item.circleVisibility, true); + } + }, [item.data.lastMessage?.content]); - return ( - <> - - {(isActive || isExpanded) && ( - - )} - - {discussion && ( - + + {(isActive || isExpanded) && ( + )} - {isProposalDeleteModalOpen && ( - - - - )} - - ); - }, -); + + {discussion && ( + + )} + {isProposalDeleteModalOpen && ( + + + + )} + + ); +} -export default ProposalFeedCard; +export default forwardRef(ProposalFeedCard); From 9facea7c3ead495e7217e3eccd2606f66f324f46 Mon Sep 17 00:00:00 2001 From: elatif2020 <72435714+elatif2020@users.noreply.github.com> Date: Tue, 6 Aug 2024 10:54:23 +0000 Subject: [PATCH 13/36] chat dark mode colors fix --- src/shared/components/Chat/ChatMessage/ChatMessage.module.scss | 2 +- src/shared/components/Separator/index.scss | 2 +- src/shared/constants/theme.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shared/components/Chat/ChatMessage/ChatMessage.module.scss b/src/shared/components/Chat/ChatMessage/ChatMessage.module.scss index 149cfb7bc..83e9e16f6 100644 --- a/src/shared/components/Chat/ChatMessage/ChatMessage.module.scss +++ b/src/shared/components/Chat/ChatMessage/ChatMessage.module.scss @@ -62,7 +62,7 @@ .messageText { padding: 0.5rem 0rem; border-radius: 0.875rem; - background-color: var(--secondary-hover-fill); + background-color: var(--secondary-background); flex-direction: row; box-sizing: border-box; position: relative; diff --git a/src/shared/components/Separator/index.scss b/src/shared/components/Separator/index.scss index 98ee113f2..3f4445bea 100644 --- a/src/shared/components/Separator/index.scss +++ b/src/shared/components/Separator/index.scss @@ -3,5 +3,5 @@ .general-separator { width: 100%; height: 1px; - background-color: $light-gray-1; + background-color: var(--gentle-stroke); } diff --git a/src/shared/constants/theme.ts b/src/shared/constants/theme.ts index d8682c30b..03cdedbca 100644 --- a/src/shared/constants/theme.ts +++ b/src/shared/constants/theme.ts @@ -54,7 +54,7 @@ export const ThemeColorsValues = { [ThemeColors.secondaryBackground]: "#1f2124", [ThemeColors.hoverFill]: "#271d21", [ThemeColors.secondaryHoverFill]: "#432b33", - [ThemeColors.primaryText]: "#ffffff", + [ThemeColors.primaryText]: "#ddd", [ThemeColors.secondaryText]: "#a75a93", [ThemeColors.tertiaryText]: "#001a36", [ThemeColors.quaternaryText]: "#432B33", From 2e77e09bf3592573c36df721ab4fae83273b53e1 Mon Sep 17 00:00:00 2001 From: elatif2020 <72435714+elatif2020@users.noreply.github.com> Date: Tue, 6 Aug 2024 10:55:24 +0000 Subject: [PATCH 14/36] join project form dark mode colors fix --- .../components/JoinProjectForm/JoinProjectForm.module.scss | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/common/components/JoinProjectModal/components/JoinProjectForm/JoinProjectForm.module.scss b/src/pages/common/components/JoinProjectModal/components/JoinProjectForm/JoinProjectForm.module.scss index adf59dbb5..e3db9c86f 100644 --- a/src/pages/common/components/JoinProjectModal/components/JoinProjectForm/JoinProjectForm.module.scss +++ b/src/pages/common/components/JoinProjectModal/components/JoinProjectForm/JoinProjectForm.module.scss @@ -9,7 +9,7 @@ } .field { - border: 0.0625rem $light-gray-3 solid; + border: 0.0625rem var(--gentle-stroke) solid; &::placeholder { font-size: $xsmall; @@ -22,10 +22,12 @@ width: 100%; border-width: 0; outline: 0; - border: 0.0625rem $light-gray-3 solid; + border: 0.0625rem var(--gentle-stroke) solid; height: 100%; min-height: 6.4375rem; padding: 0.75rem; + background-color: var(--secondary-background); + color: var(--primary-text); @include tablet { max-height: 4.25rem; From b90ebbf6e50c626a4884444e0ab8b86ed5c0a087 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Wed, 7 Aug 2024 14:48:14 +0300 Subject: [PATCH 15/36] CW-some-stream-disappear Added commonId related logic for Feed --- src/pages/OldCommon/hooks/useCommonMember.ts | 3 +- src/pages/OldCommon/hooks/useCommonMembers.ts | 6 +-- .../components/FeedLayout/FeedLayout.tsx | 53 ++++++++++++++++--- src/shared/models/Common.tsx | 1 + 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/pages/OldCommon/hooks/useCommonMember.ts b/src/pages/OldCommon/hooks/useCommonMember.ts index f749b2b2e..8d01168e8 100644 --- a/src/pages/OldCommon/hooks/useCommonMember.ts +++ b/src/pages/OldCommon/hooks/useCommonMember.ts @@ -141,6 +141,7 @@ export const useCommonMember = (options: Options = {}): Return => { loading: false, fetched: true, data: { + commonId, ...commonMember, ...generateCirclesDataForCommonMember( governance.circles, @@ -189,7 +190,7 @@ export const useCommonMember = (options: Options = {}): Return => { } } }, - [state, userId], + [state, userId, commonId], ); const setCommonMember = useCallback( diff --git a/src/pages/OldCommon/hooks/useCommonMembers.ts b/src/pages/OldCommon/hooks/useCommonMembers.ts index 3f16ad080..f07c8221f 100644 --- a/src/pages/OldCommon/hooks/useCommonMembers.ts +++ b/src/pages/OldCommon/hooks/useCommonMembers.ts @@ -141,7 +141,7 @@ export const useCommonMembers = ({ commonId }: Options): Return => { const user = cachedUserStates[commonMember.userId]?.data; - return user ? [...acc, { ...commonMember, user }] : acc; + return user ? [...acc, { ...commonMember, user, commonId }] : acc; }, []); return { @@ -178,7 +178,7 @@ export const useCommonMembers = ({ commonId }: Options): Return => { ({ uid }) => uid === commonMember.userId, ); - return user ? [...acc, { ...commonMember, user }] : acc; + return user ? [...acc, { ...commonMember, user, commonId }] : acc; }, []); return { @@ -198,7 +198,7 @@ export const useCommonMembers = ({ commonId }: Options): Return => { })); } })(); - }, [commonMembersState.data]); + }, [commonMembersState.data, commonId]); return { ...state, diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx index c57d97461..7f2e19cd8 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx @@ -13,7 +13,7 @@ import React, { import { useSelector } from "react-redux"; import { useHistory } from "react-router-dom"; import PullToRefresh from "react-simple-pull-to-refresh"; -import { useWindowSize } from "react-use"; +import { useDeepCompareEffect, useWindowSize } from "react-use"; import classNames from "classnames"; import { selectUser } from "@/pages/Auth/store/selectors"; import { useCommonMember } from "@/pages/OldCommon/hooks"; @@ -219,9 +219,39 @@ const FeedLayout: ForwardRefRenderFunction = ( chatItem?.nestedItemData?.commonMember || outerCommonMember || fetchedCommonMember; + + const [ + commonMemberForSpecificCommonIds, + setCommonMemberForSpecificCommonIds, + ] = useState({}); + + useDeepCompareEffect(() => { + const chatItemCommonMember = { ...chatItem?.nestedItemData?.commonMember }; + + setCommonMemberForSpecificCommonIds((prevCommonMembers) => { + if (chatItemCommonMember?.commonId) { + prevCommonMembers[chatItemCommonMember.commonId] = chatItemCommonMember; + } + + if (outerCommonMember?.commonId) { + prevCommonMembers[outerCommonMember.commonId] = outerCommonMember; + } + + if (fetchedCommonMember?.commonId) { + prevCommonMembers[fetchedCommonMember.commonId] = fetchedCommonMember; + } + + return prevCommonMembers; + }); + }, [ + fetchedCommonMember, + chatItem?.nestedItemData?.commonMember, + outerCommonMember, + ]); + const userForProfile = useUserForProfile(); const governance = chatItem?.nestedItemData - ? (fetchedGovernance || outerGovernance) + ? fetchedGovernance || outerGovernance : outerGovernance || fetchedGovernance; const [splitPaneRef, setSplitPaneRef] = useState(null); @@ -312,9 +342,16 @@ const FeedLayout: ForwardRefRenderFunction = ( ]); const activeFeedItemId = chatItem?.feedItemId || feedItemIdForAutoChatOpen; const sizeKey = `${windowWidth}_${contentWidth}`; - const userCircleIds = useMemo( - () => Object.values(commonMember?.circles.map ?? {}), - [commonMember?.circles.map], + + const getUserCircleIds = useCallback( + (commonId) => { + return Object.values( + commonMemberForSpecificCommonIds[commonId]?.circles.map ?? + commonMember?.circles.map ?? + {}, + ) as string[]; + }, + [commonMemberForSpecificCommonIds, commonMember?.circles.map], ); const selectedFeedItem = useMemo( @@ -831,7 +868,7 @@ const FeedLayout: ForwardRefRenderFunction = ( item={item.feedItem} governanceCircles={governance?.circles} isMobileVersion={isTabletView} - userCircleIds={userCircleIds} + userCircleIds={getUserCircleIds(commonData?.id)} isActive={isActive} isExpanded={item.feedItem.id === expandedFeedItemId} sizeKey={isActive ? sizeKey : undefined} @@ -917,7 +954,9 @@ const FeedLayout: ForwardRefRenderFunction = ( isProject={selectedItemCommonData.isProject} governanceCircles={governance?.circles} selectedFeedItem={selectedFeedItem?.feedItem} - userCircleIds={userCircleIds} + userCircleIds={getUserCircleIds( + selectedItemCommonData.id, + )} isShowFeedItemDetailsModal={isShowFeedItemDetailsModal} sizeKey={sizeKey} isMainModalOpen={Boolean(chatItem)} diff --git a/src/shared/models/Common.tsx b/src/shared/models/Common.tsx index c5d79b1d1..ca92fefb3 100644 --- a/src/shared/models/Common.tsx +++ b/src/shared/models/Common.tsx @@ -172,6 +172,7 @@ export interface CommonMember { isFollowing: boolean; streamsUnreadCountByProjectStream?: Record; unreadCountByProjectStream?: Record; + commonId?: string; } export interface CirclesPermissions { From e0e046cd4b10fefea66c814d893a8adfa5ee682c Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Thu, 8 Aug 2024 12:52:43 +0300 Subject: [PATCH 16/36] CW-mobile-performance Added memoization for ProjectFeedItem --- .../ProjectFeedItem/ProjectFeedItem.tsx | 140 +++++++++++------- src/shared/hooks/ModalHook.tsx | 10 +- 2 files changed, 90 insertions(+), 60 deletions(-) diff --git a/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx b/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx index 76e3ad9d8..32b3eb141 100644 --- a/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx +++ b/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx @@ -2,10 +2,11 @@ import React, { CSSProperties, FC, MouseEventHandler, - ReactNode, useEffect, + useMemo, useRef, useState, + useCallback, } from "react"; import { useCollapse } from "react-collapsed"; import { useSelector } from "react-redux"; @@ -93,45 +94,56 @@ export const ProjectFeedItem: FC = (props) => { ); const commonPath = getCommonPagePath(commonId); const isProject = checkIsProject(common); - const titleEl = ( - <> - {common?.name} - - + const titleEl = useMemo( + () => ( + <> + {common?.name} + + + ), + [common?.name], ); - const handleClick = () => { + const handleClick = useCallback(() => { history.push(commonPath); - }; + }, [history, commonPath]); - const handleExpand: MouseEventHandler = (event) => { - event.stopPropagation(); - setIsExpanded((v) => !v); - }; + const handleExpand: MouseEventHandler = useCallback( + (event) => { + event.stopPropagation(); + setIsExpanded((v) => !v); + }, + [setIsExpanded], + ); - const renderLeftContent = (): ReactNode => ( -
    - - ( +
    + + + + - - -
    +
    + ), + [common?.image, common?.name, isExpanded, isProject, handleExpand], ); useEffect(() => { @@ -146,6 +158,45 @@ export const ProjectFeedItem: FC = (props) => { } }, [isExpanded]); + const feedItemProps = useMemo( + () => ({ + className: styles.container, + titleWrapperClassName: styles.titleWrapper, + lastActivity: item.updatedAt.seconds * 1000, + isMobileView: isMobileVersion, + title: titleEl, + onClick: handleClick, + onExpand: handleExpand, + seenOnce: true, + isLoading: !isCommonFetched, + unreadMessages, + lastMessage, + seen: !( + unreadStreamsCount && + unreadStreamsCount > 0 && + unreadMessages === 0 + ), + renderLeftContent, + shouldHideBottomContent: !lastMessage, + isFollowing: feedItemFollow.isFollowing, + notion: common?.notion, + }), + [ + item.updatedAt.seconds, + isMobileVersion, + titleEl, + handleClick, + handleExpand, + isCommonFetched, + unreadMessages, + lastMessage, + unreadStreamsCount, + renderLeftContent, + feedItemFollow.isFollowing, + common?.notion, + ], + ); + if ( !isCommonMemberFetched || (!commonMember && common?.listVisibility === SpaceListVisibility.Members) @@ -164,28 +215,7 @@ export const ProjectFeedItem: FC = (props) => { style={itemStyles} >
    - {renderFeedItemBaseContent?.({ - className: styles.container, - titleWrapperClassName: styles.titleWrapper, - lastActivity: item.updatedAt.seconds * 1000, - isMobileView: isMobileVersion, - title: titleEl, - onClick: handleClick, - onExpand: handleExpand, - seenOnce: true, - isLoading: !isCommonFetched, - unreadMessages, - lastMessage, - seen: !( - unreadStreamsCount && - unreadStreamsCount > 0 && - unreadMessages === 0 - ), - renderLeftContent, - shouldHideBottomContent: !lastMessage, - isFollowing: feedItemFollow.isFollowing, - notion: common?.notion, - })} + {renderFeedItemBaseContent?.(feedItemProps)}
    { const [isShowing, setIsShowing] = useState(show); - function onClose() { + const onClose = useCallback(() => { setIsShowing(false); - } + }, []); - function onOpen() { + const onOpen = useCallback(() => { setIsShowing(true); - } + }, []); return { isShowing, From 795445be654785fa1870abfbf4e4d46b65fda2d0 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Thu, 8 Aug 2024 13:05:35 +0300 Subject: [PATCH 17/36] CW-mobile-performance Added memoization for FeedCard --- .../common/components/FeedCard/FeedCard.tsx | 141 +++++++++++------- 1 file changed, 91 insertions(+), 50 deletions(-) diff --git a/src/pages/common/components/FeedCard/FeedCard.tsx b/src/pages/common/components/FeedCard/FeedCard.tsx index 65f87967a..62c018eaa 100644 --- a/src/pages/common/components/FeedCard/FeedCard.tsx +++ b/src/pages/common/components/FeedCard/FeedCard.tsx @@ -5,6 +5,8 @@ import React, { forwardRef, useImperativeHandle, PropsWithChildren, + useCallback, + useMemo, } from "react"; import { useCollapse } from "react-collapsed"; import classNames from "classnames"; @@ -106,11 +108,11 @@ export const FeedCard = forwardRef((props, ref) => { }); const containerRef = useRef(null); - const toggleExpanding = () => { + const toggleExpanding = useCallback(() => { if (setExpandedFeedItemId) { setExpandedFeedItemId(isExpanded ? null : feedItemId); } - }; + }, [setExpandedFeedItemId, isExpanded, feedItemId]); const scrollToTargetTop = ( headerOffset: number, @@ -140,7 +142,7 @@ export const FeedCard = forwardRef((props, ref) => { } }; - const scrollToTargetAdjusted = () => { + const scrollToTargetAdjusted = useCallback(() => { if (scrollTimeoutRef.current) { clearTimeout(scrollTimeoutRef.current); } @@ -192,7 +194,7 @@ export const FeedCard = forwardRef((props, ref) => { }); } }, COLLAPSE_DURATION + EXTRA_WAITING_TIME_FOR_TIMEOUT); - }; + }, [isTabletView]); useEffect(() => { if (isExpanded && containerRef?.current) { @@ -203,63 +205,102 @@ export const FeedCard = forwardRef((props, ref) => { clearTimeout(scrollTimeoutRef.current); scrollTimeoutRef.current = null; } - }, [isExpanded]); + }, [isExpanded, scrollToTargetAdjusted]); - const handleClick = () => { + const handleClick = useCallback(() => { onClick?.(); if (!isTabletView && isActive) { toggleExpanding(); } - }; + }, [onClick, isTabletView, isActive, toggleExpanding]); - const handleExpand: MouseEventHandler = (event) => { - event.stopPropagation(); - toggleExpanding(); - }; + const handleExpand: MouseEventHandler = useCallback( + (event) => { + event.stopPropagation(); + toggleExpanding(); + }, + [toggleExpanding], + ); + + useImperativeHandle( + ref, + () => ({ + itemId: feedItemId, + scrollToItem: scrollToTargetAdjusted, + }), + [feedItemId, scrollToTargetAdjusted], + ); - useImperativeHandle(ref, () => ({ - itemId: feedItemId, - scrollToItem: scrollToTargetAdjusted, - })); + const feedItemBaseContent = useMemo(() => { + return renderFeedItemBaseContent?.({ + lastActivity, + unreadMessages, + isMobileView: isTabletView, + isActive, + isExpanded, + canBeExpanded, + onClick: handleClick, + onExpand: handleExpand, + title, + lastMessage: !isLoading ? lastMessage : undefined, + menuItems, + commonName, + commonId, + image, + imageAlt, + isProject, + isPinned, + isFollowing, + type, + seenOnce, + seen, + ownerId, + discussionPredefinedType, + hasFiles, + hasImages, + hasUnseenMention, + notion, + originalCommonIdForLinking, + linkedCommonIds, + }); + }, [ + lastActivity, + unreadMessages, + isTabletView, + isActive, + isExpanded, + canBeExpanded, + handleClick, + handleExpand, + title, + lastMessage, + isLoading, + menuItems, + commonName, + commonId, + image, + imageAlt, + isProject, + isPinned, + isFollowing, + type, + seenOnce, + seen, + ownerId, + discussionPredefinedType, + hasFiles, + hasImages, + hasUnseenMention, + notion, + originalCommonIdForLinking, + linkedCommonIds, + renderFeedItemBaseContent, + ]); return (
    - {!isPreviewMode && ( -
    - {renderFeedItemBaseContent?.({ - lastActivity, - unreadMessages, - isMobileView: isTabletView, - isActive, - isExpanded, - canBeExpanded, - onClick: handleClick, - onExpand: handleExpand, - title, - lastMessage: !isLoading ? lastMessage : undefined, - menuItems, - commonName, - commonId, - image, - imageAlt, - isProject, - isPinned, - isFollowing, - type, - seenOnce, - seen, - ownerId, - discussionPredefinedType, - hasFiles, - hasImages, - hasUnseenMention, - notion, - originalCommonIdForLinking, - linkedCommonIds, - })} -
    - )} + {!isPreviewMode &&
    {feedItemBaseContent}
    }
    Date: Thu, 8 Aug 2024 14:18:52 +0300 Subject: [PATCH 18/36] CW-mobile-performance Added useMemo for lastMessages and menuItems --- .../DiscussionFeedCard/DiscussionFeedCard.tsx | 36 +++++++++----- .../ProjectFeedItem/ProjectFeedItem.tsx | 4 +- .../ProposalFeedCard/ProposalFeedCard.tsx | 36 +++++++++----- .../ChatChannelItem/ChatChannelItem.tsx | 4 +- .../ChatChannelItem/hooks/useMenuItems.tsx | 49 ++++++++++--------- 5 files changed, 81 insertions(+), 48 deletions(-) diff --git a/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx b/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx index 3da4b2a80..5ae93d503 100644 --- a/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx +++ b/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx @@ -349,6 +349,30 @@ const DiscussionFeedCard = forwardRef( } }, [item.data.lastMessage?.content]); + const lastMessage = useMemo(() => { + return getLastMessage({ + commonFeedType: item.data.type, + lastMessage: item.data.lastMessage, + discussion, + currentUserId: userId, + feedItemCreatorName: getUserName(discussionCreator), + commonName, + isProject, + hasFiles: item.data.hasFiles, + hasImages: item.data.hasImages, + }); + }, [ + item.data.type, + item.data.lastMessage, + discussion, + userId, + discussionCreator, + commonName, + isProject, + item.data.hasFiles, + item.data.hasImages, + ]); + return ( <> ( isExpanded={isExpanded} onClick={handleOpenChat} title={cardTitle} - lastMessage={getLastMessage({ - commonFeedType: item.data.type, - lastMessage: item.data.lastMessage, - discussion, - currentUserId: userId, - feedItemCreatorName: getUserName(discussionCreator), - commonName, - isProject, - hasFiles: item.data.hasFiles, - hasImages: item.data.hasImages, - })} + lastMessage={lastMessage} isPreviewMode={isPreviewMode} isPinned={isPinned} commonName={commonName} diff --git a/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx b/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx index 32b3eb141..d90904780 100644 --- a/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx +++ b/src/pages/common/components/FeedItem/components/ProjectFeedItem/ProjectFeedItem.tsx @@ -87,11 +87,11 @@ export const ProjectFeedItem: FC = (props) => { duration: COLLAPSE_DURATION, }); const isLoading = !fetched; - const lastMessage = parseStringToTextEditorValue( + const lastMessage = useMemo(() => parseStringToTextEditorValue( `${unreadStreamsCount ?? 0} unread stream${ unreadStreamsCount === 1 ? "" : "s" }`, - ); + ),[unreadStreamsCount]); const commonPath = getCommonPagePath(commonId); const isProject = checkIsProject(common); const titleEl = useMemo( diff --git a/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx b/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx index 949dcea0c..3396b0756 100644 --- a/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx +++ b/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx @@ -375,6 +375,30 @@ const ProposalFeedCard = forwardRef( } }, [item.data.lastMessage?.content]); + const lastMessage = useMemo(() => { + return getLastMessage({ + commonFeedType: item.data.type, + lastMessage: item.data.lastMessage, + discussion, + currentUserId: userId, + feedItemCreatorName: getUserName(feedItemUser), + commonName, + isProject, + hasFiles: item.data.hasFiles, + hasImages: item.data.hasImages, + }); + }, [ + item.data.type, + item.data.lastMessage, + discussion, + userId, + feedItemUser, + commonName, + isProject, + item.data.hasFiles, + item.data.hasImages, + ]); + return ( <> ( isExpanded={isExpanded} unreadMessages={feedItemUserMetadata?.count || 0} title={cardTitle} - lastMessage={getLastMessage({ - commonFeedType: item.data.type, - lastMessage: item.data.lastMessage, - discussion, - currentUserId: userId, - feedItemCreatorName: getUserName(feedItemUser), - commonName, - isProject, - hasFiles: item.data.hasFiles, - hasImages: item.data.hasImages, - })} + lastMessage={lastMessage} canBeExpanded={discussion?.predefinedType !== PredefinedTypes.General} isPreviewMode={isPreviewMode} commonName={commonName} diff --git a/src/pages/inbox/components/ChatChannelItem/ChatChannelItem.tsx b/src/pages/inbox/components/ChatChannelItem/ChatChannelItem.tsx index ccb85d5d8..cd9016cf7 100644 --- a/src/pages/inbox/components/ChatChannelItem/ChatChannelItem.tsx +++ b/src/pages/inbox/components/ChatChannelItem/ChatChannelItem.tsx @@ -149,6 +149,8 @@ export const ChatChannelItem: FC = (props) => { } }, [isActive, finalTitle, dmUsers?.[0]?.photoURL, dmUsersNames?.[0]]); + const lastMessage = useMemo(() => getLastMessage(chatChannel.lastMessage), [chatChannel.lastMessage]); + return ( = (props) => { isMobileView={isTabletView} isActive={isActive} title={finalTitle} - lastMessage={getLastMessage(chatChannel.lastMessage)} + lastMessage={lastMessage} canBeExpanded={false} onClick={handleOpenChat} menuItems={menuItems} diff --git a/src/pages/inbox/components/ChatChannelItem/hooks/useMenuItems.tsx b/src/pages/inbox/components/ChatChannelItem/hooks/useMenuItems.tsx index 05095fc9b..4970ee0c7 100644 --- a/src/pages/inbox/components/ChatChannelItem/hooks/useMenuItems.tsx +++ b/src/pages/inbox/components/ChatChannelItem/hooks/useMenuItems.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useMemo } from "react"; import { Message3Icon } from "@/shared/icons"; import { ContextMenuItem as Item } from "@/shared/interfaces"; import { ChatChannelMenuItem } from "../constants"; @@ -15,32 +15,35 @@ export const useMenuItems = ( ): Item[] => { const { chatChannelUserStatus } = options; const { markChatChannelAsSeen, markChatChannelAsUnseen } = actions; - const items: Item[] = [ - { - id: ChatChannelMenuItem.MarkUnread, - text: "Mark as unread", - onClick: async () => { - if (!chatChannelUserStatus) { - return; - } + const items: Item[] = useMemo( + () => [ + { + id: ChatChannelMenuItem.MarkUnread, + text: "Mark as unread", + onClick: async () => { + if (!chatChannelUserStatus) { + return; + } - markChatChannelAsUnseen(chatChannelUserStatus.chatChannelId); + markChatChannelAsUnseen(chatChannelUserStatus.chatChannelId); + }, + icon: , }, - icon: , - }, - { - id: ChatChannelMenuItem.MarkRead, - text: "Mark as read", - onClick: async () => { - if (!chatChannelUserStatus) { - return; - } + { + id: ChatChannelMenuItem.MarkRead, + text: "Mark as read", + onClick: async () => { + if (!chatChannelUserStatus) { + return; + } - markChatChannelAsSeen(chatChannelUserStatus.chatChannelId); + markChatChannelAsSeen(chatChannelUserStatus.chatChannelId); + }, + icon: , }, - icon: , - }, - ]; + ], + [chatChannelUserStatus?.chatChannelId], + ); return getAllowedItems(items, options); }; From 5c9a8601d6dd4d7e41be6fa01bbac5a55fa03969 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Thu, 8 Aug 2024 16:35:21 +0300 Subject: [PATCH 19/36] CW-mobile-performance Added memo for CommonFeed --- src/pages/commonFeed/CommonFeed.tsx | 65 +++++++++++++++++------------ 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/src/pages/commonFeed/CommonFeed.tsx b/src/pages/commonFeed/CommonFeed.tsx index 8d85ba7a8..0c1cb6b2c 100644 --- a/src/pages/commonFeed/CommonFeed.tsx +++ b/src/pages/commonFeed/CommonFeed.tsx @@ -237,11 +237,14 @@ const CommonFeedComponent: FC = (props) => { fetchUserRelatedData(); }; - const fetchMoreCommonFeedItems = (feedItemId?: string) => { - if (hasMoreCommonFeedItems && !isSearchingFeedItems) { - fetchCommonFeedItems(feedItemId); - } - }; + const fetchMoreCommonFeedItems = useCallback( + (feedItemId?: string) => { + if (hasMoreCommonFeedItems && !isSearchingFeedItems) { + fetchCommonFeedItems(feedItemId); + } + }, + [hasMoreCommonFeedItems, isSearchingFeedItems, fetchCommonFeedItems] + ); const renderFeedItemBaseContent = useCallback( (props: FeedItemBaseContentProps) => , @@ -281,7 +284,7 @@ const CommonFeedComponent: FC = (props) => { : onProjectJoinModalOpen : onCommonJoinModalOpen; - const renderChatInput = (): ReactNode => { + const renderChatInput = useCallback((): ReactNode => { if (commonMember) { return; } @@ -333,9 +336,19 @@ const CommonFeedComponent: FC = (props) => { )} ); - }; + }, [ + commonMember, + isJoinPending, + commonData, + isRootCommonMember, + canJoin, + onRootCommonJoinModalOpen, + getCommonPagePath, + parentCommonMember, + onJoinCommon + ]); - const renderLayoutTabs = (): ReactElement => { + const renderLayoutTabs = useCallback((): ReactElement => { return (
    onJoinCommon()}> @@ -343,7 +356,24 @@ const CommonFeedComponent: FC = (props) => {
    ); - }; + }, [onJoinCommon]); + + const renderContentWrapper = useCallback( + (children: ReactNode, wrapperStyles?: CSSProperties): ReactNode => + outerContentWrapperRenderer({ + children, + wrapperStyles, + commonData, + commonMember, + isGlobalDataFetched, + }), + [outerContentWrapperRenderer, commonData, commonMember, isGlobalDataFetched] + ); + + const onPullToRefresh = useCallback(() => { + dispatch(cacheActions.clearFeedStateByCommonId(commonId)); + dispatch(commonActions.resetFeedItems()); + }, [dispatch, commonId]); useEffect(() => { if ( @@ -538,23 +568,6 @@ const CommonFeedComponent: FC = (props) => { ); } - const onPullToRefresh = () => { - dispatch(cacheActions.clearFeedStateByCommonId(commonId)); - dispatch(commonActions.resetFeedItems()); - }; - - const renderContentWrapper = ( - children: ReactNode, - wrapperStyles?: CSSProperties, - ): ReactNode => - outerContentWrapperRenderer({ - children, - wrapperStyles, - commonData, - commonMember, - isGlobalDataFetched, - }); - return ( <> Date: Thu, 8 Aug 2024 16:43:44 +0300 Subject: [PATCH 20/36] CW-mobile-performance Fix type issue --- src/pages/commonFeed/CommonFeed.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/commonFeed/CommonFeed.tsx b/src/pages/commonFeed/CommonFeed.tsx index 0c1cb6b2c..6e85d1c37 100644 --- a/src/pages/commonFeed/CommonFeed.tsx +++ b/src/pages/commonFeed/CommonFeed.tsx @@ -363,7 +363,7 @@ const CommonFeedComponent: FC = (props) => { outerContentWrapperRenderer({ children, wrapperStyles, - commonData, + commonData: commonData!, commonMember, isGlobalDataFetched, }), From 5e0d1c565361c713ea62622e9135bee746e94aa9 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Thu, 8 Aug 2024 17:09:42 +0300 Subject: [PATCH 21/36] CW-mobile-performance Optimize FeedLayout --- src/pages/commonFeed/CommonFeed.tsx | 90 +++++++++++++--------- src/pages/inbox/BaseInbox.tsx | 4 +- src/shared/hooks/useCases/useInboxItems.ts | 6 +- 3 files changed, 59 insertions(+), 41 deletions(-) diff --git a/src/pages/commonFeed/CommonFeed.tsx b/src/pages/commonFeed/CommonFeed.tsx index 6e85d1c37..b9e341b8a 100644 --- a/src/pages/commonFeed/CommonFeed.tsx +++ b/src/pages/commonFeed/CommonFeed.tsx @@ -243,7 +243,7 @@ const CommonFeedComponent: FC = (props) => { fetchCommonFeedItems(feedItemId); } }, - [hasMoreCommonFeedItems, isSearchingFeedItems, fetchCommonFeedItems] + [hasMoreCommonFeedItems, isSearchingFeedItems, fetchCommonFeedItems], ); const renderFeedItemBaseContent = useCallback( @@ -345,7 +345,7 @@ const CommonFeedComponent: FC = (props) => { onRootCommonJoinModalOpen, getCommonPagePath, parentCommonMember, - onJoinCommon + onJoinCommon, ]); const renderLayoutTabs = useCallback((): ReactElement => { @@ -367,7 +367,12 @@ const CommonFeedComponent: FC = (props) => { commonMember, isGlobalDataFetched, }), - [outerContentWrapperRenderer, commonData, commonMember, isGlobalDataFetched] + [ + outerContentWrapperRenderer, + commonData, + commonMember, + isGlobalDataFetched, + ], ); const onPullToRefresh = useCallback(() => { @@ -526,6 +531,51 @@ const CommonFeedComponent: FC = (props) => { } }, [commonAction]); + const FeedLayoutTopContent = useCallback(() => { + if (!commonData) { + return null; + } + + return ( + { + dispatch(commonActions.setCommonAction(null)); + }} + > + {(commonAction === CommonAction.NewDiscussion || + commonAction === CommonAction.EditDiscussion) && ( + + )} + {commonAction === CommonAction.NewProposal && ( + + )} + + ); + }, [ + JSON.stringify(commonData), + JSON.stringify(commonMember), + commonAction, + scrollToItemsTop, + ]); + if (!isDataFetched) { const headerEl = renderLoadingHeader ? ( renderLoadingHeader() @@ -574,39 +624,7 @@ const CommonFeedComponent: FC = (props) => { ref={setFeedLayoutRef} className={styles.feedLayout} renderContentWrapper={renderContentWrapper} - topContent={ - { - dispatch(commonActions.setCommonAction(null)); - }} - > - {(commonAction === CommonAction.NewDiscussion || - commonAction === CommonAction.EditDiscussion) && ( - - )} - {commonAction === CommonAction.NewProposal && ( - - )} - - } + topContent={FeedLayoutTopContent} common={commonData.common} governance={commonData.governance} commonMember={commonMember} diff --git a/src/pages/inbox/BaseInbox.tsx b/src/pages/inbox/BaseInbox.tsx index 4a92ccae1..6b34a11d8 100644 --- a/src/pages/inbox/BaseInbox.tsx +++ b/src/pages/inbox/BaseInbox.tsx @@ -143,11 +143,11 @@ const InboxPage: FC = (props) => { }); }; - const fetchMoreInboxItems = () => { + const fetchMoreInboxItems = useCallback(() => { if (hasMoreInboxItems && !isSearchingInboxItems && !areInboxItemsLoading) { fetchInboxItems(); } - }; + },[hasMoreInboxItems, isSearchingInboxItems, areInboxItemsLoading]); const renderFeedItemBaseContent = useCallback( (props: FeedItemBaseContentProps) => , diff --git a/src/shared/hooks/useCases/useInboxItems.ts b/src/shared/hooks/useCases/useInboxItems.ts index 9e15e5508..19b5fde24 100644 --- a/src/shared/hooks/useCases/useInboxItems.ts +++ b/src/shared/hooks/useCases/useInboxItems.ts @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from "react"; +import { useEffect, useRef, useState, useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { selectUser } from "@/pages/Auth/store/selectors"; import { Logger, UserService } from "@/services"; @@ -87,10 +87,10 @@ export const useInboxItems = ( ); }; - const refetch = () => { + const refetch = useCallback(() => { setNewItemsBatches([]); dispatch(inboxActions.refetchInboxItems(Boolean(unread))); - }; + },[unread, setNewItemsBatches]); const addNewInboxItems = ( data: { From c38e29123b0a137f0d088407efa975919252ad82 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Fri, 9 Aug 2024 02:39:33 +0300 Subject: [PATCH 22/36] CW-mobile-performance Added memo for TreeItemTrigger and useMenuItems --- .../ChatChannelItem/hooks/useMenuItems.tsx | 4 +- .../DesktopCommonDropdown.tsx | 95 +++++++++++-------- .../components/TreeItem/TreeItem.tsx | 12 ++- 3 files changed, 64 insertions(+), 47 deletions(-) diff --git a/src/pages/inbox/components/ChatChannelItem/hooks/useMenuItems.tsx b/src/pages/inbox/components/ChatChannelItem/hooks/useMenuItems.tsx index 4970ee0c7..a1f2883cb 100644 --- a/src/pages/inbox/components/ChatChannelItem/hooks/useMenuItems.tsx +++ b/src/pages/inbox/components/ChatChannelItem/hooks/useMenuItems.tsx @@ -45,5 +45,7 @@ export const useMenuItems = ( [chatChannelUserStatus?.chatChannelId], ); - return getAllowedItems(items, options); + const menuItems = useMemo(() => getAllowedItems(items, options), [items, options]); + + return menuItems; }; diff --git a/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/CommonDropdown/components/DesktopCommonDropdown/DesktopCommonDropdown.tsx b/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/CommonDropdown/components/DesktopCommonDropdown/DesktopCommonDropdown.tsx index b74bbf19c..ba44d1735 100644 --- a/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/CommonDropdown/components/DesktopCommonDropdown/DesktopCommonDropdown.tsx +++ b/src/shared/layouts/CommonSidenavLayout/components/SidenavContent/components/CommonDropdown/components/DesktopCommonDropdown/DesktopCommonDropdown.tsx @@ -1,4 +1,10 @@ -import React, { FC, MouseEventHandler, useState } from "react"; +import React, { + FC, + MouseEventHandler, + useState, + useMemo, + useCallback, +} from "react"; import { useSelector } from "react-redux"; import classNames from "classnames"; import { ButtonIcon } from "@/shared/components"; @@ -27,51 +33,56 @@ const DesktopCommonDropdown: FC = (props) => { setMenuRerenderHack((value) => !value); }; - const finalItems = items.map((item) => ({ - ...item, - className: classNames(item.className, styles.menuItem, { - [styles.menuItemForCommonCreation]: item.id === CREATE_COMMON_ITEM_ID, - }), - activeClassName: classNames(item.activeClassName, styles.menuItemActive), - text: ( - <> - - {item.text} - - {item.id === activeItemId && ( - - )} - - ), - onClick: (event) => { - event.preventDefault(); - handleItemClick(); + const finalItems = useMemo(() => { + return items.map((item) => ({ + ...item, + className: classNames(item.className, styles.menuItem, { + [styles.menuItemForCommonCreation]: item.id === CREATE_COMMON_ITEM_ID, + }), + activeClassName: classNames(item.activeClassName, styles.menuItemActive), + text: ( + <> + + {item.text} + + {item.id === activeItemId && ( + + )} + + ), + onClick: (event) => { + event.preventDefault(); + handleItemClick(); - if (item.type !== MenuItemType.Link) { - item.onClick(event); - } - }, - })); + if (item.type !== MenuItemType.Link) { + item.onClick(event); + } + }, + })); + }, [items]); - const onClick: MouseEventHandler = (event) => { + const onClick: MouseEventHandler = useCallback((event) => { event.stopPropagation(); - }; + }, []); - const triggerEl = ( - - {isMobileView ? ( - Change - ) : ( - - )} - + const triggerEl = useMemo( + () => ( + + {isMobileView ? ( + Change + ) : ( + + )} + + ), + [onClick, isActive, isMobileView], ); return ( diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItem/TreeItem.tsx b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItem/TreeItem.tsx index 4436f04e6..714b2c429 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItem/TreeItem.tsx +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItem/TreeItem.tsx @@ -1,4 +1,4 @@ -import React, { FC, useEffect, useState } from "react"; +import React, { FC, useCallback, useEffect, useState, useMemo } from "react"; import classNames from "classnames"; import { Item } from "../../types"; import { TreeItemTrigger } from "../TreeItemTrigger"; @@ -40,10 +40,14 @@ const TreeItem: FC = (props) => { } }, [isActive, hasNestedContent, isOpenedManually, hasActiveChild]); - const handleTriggerToggle = () => { + const handleTriggerToggle = useCallback(() => { + if (!hasNestedContent) { + return; + } + setIsOpenedManually(!isOpen); setIsOpen((value) => !value); - }; + }, [hasNestedContent]); return (
  • = (props) => { level={level} isActive={isActive} isOpen={isOpen} - onToggle={hasNestedContent ? handleTriggerToggle : undefined} + onToggle={handleTriggerToggle} /> {isOpen ? children : null}
  • From a5d19af53ebdd41cb0a3de21ee631f95f211276a Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Fri, 9 Aug 2024 11:11:39 +0300 Subject: [PATCH 23/36] CW-mobile-performance Fix TreeItemTrigger component --- .../components/TreeItem/TreeItem.tsx | 2 +- .../TreeItemTrigger.module.scss | 60 ---------------- .../TreeItemTrigger/TreeItemTrigger.tsx | 69 +++++------------- .../TreeItemTriggerContent.module.scss | 57 +++++++++++++++ .../TreeItemTriggerContent.tsx | 70 +++++++++++++++++++ .../TreeItemTriggerContent/index.ts | 1 + 6 files changed, 148 insertions(+), 111 deletions(-) create mode 100644 src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.module.scss create mode 100644 src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.tsx create mode 100644 src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/index.ts diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItem/TreeItem.tsx b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItem/TreeItem.tsx index 714b2c429..ca5e9eb2d 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItem/TreeItem.tsx +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItem/TreeItem.tsx @@ -1,4 +1,4 @@ -import React, { FC, useCallback, useEffect, useState, useMemo } from "react"; +import React, { FC, useCallback, useEffect, useState } from "react"; import classNames from "classnames"; import { Item } from "../../types"; import { TreeItemTrigger } from "../TreeItemTrigger"; diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTrigger/TreeItemTrigger.module.scss b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTrigger/TreeItemTrigger.module.scss index 2ddcd7584..0bb9d1668 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTrigger/TreeItemTrigger.module.scss +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTrigger/TreeItemTrigger.module.scss @@ -36,63 +36,3 @@ .itemDisabled { cursor: not-allowed; } - -.arrowIconButton { - padding: 0.75rem 1.25rem 0.75rem var(--item-arrow-pl); -} -.arrowIconButtonHidden { - visibility: hidden; -} - -.arrowIcon { - width: 0.5rem; - height: 0.625rem; - color: $c-neutrals-600; - transition: transform 0.2s; -} - -.arrowIconOpen { - transform: rotate(90deg); -} - -.image { - flex-shrink: 0; - margin-right: var(--item-image-mr); - width: 1.5rem; - height: 1.5rem; - object-fit: cover; -} -.imageNonRounded { - border-radius: 0.1875rem; -} -.imageRounded { - border-radius: 50%; -} - -.name { - font-family: PoppinsSans, sans-serif; - font-weight: 600; - font-size: $small; - color: var(--item-text-color); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.nameActive { - color: $white; -} - -.notificationsAmount { - height: 1rem; - margin-left: auto; - padding: 0 0.25rem; - display: flex; - align-items: center; - justify-content: center; - font-weight: 600; - font-size: $xxsmall-2; - color: $c-shades-white; - background-color: $c-primary-400; - border-radius: 0.5rem; -} diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTrigger/TreeItemTrigger.tsx b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTrigger/TreeItemTrigger.tsx index acaddb127..3b62a1039 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTrigger/TreeItemTrigger.tsx +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTrigger/TreeItemTrigger.tsx @@ -1,11 +1,9 @@ import React, { FC, MouseEventHandler } from "react"; import { NavLink } from "react-router-dom"; import classNames from "classnames"; -import { ButtonIcon } from "@/shared/components/ButtonIcon"; -import { SmallArrowIcon } from "@/shared/icons"; -import { CommonAvatar } from "@/shared/ui-kit"; import { useTreeContext } from "../../context"; import { Item } from "../../types"; +import { TreeItemTriggerContent } from "../TreeItemTriggerContent"; import styles from "./TreeItemTrigger.module.scss"; interface TreeItemTriggerProps { @@ -50,51 +48,6 @@ const TreeItemTrigger: FC = (props) => { className, treeItemTriggerStyles?.container, ); - const contentEl = ( - <> - - - - - - - - {item.name} - - {item.nameRightContent} - {item.rightContent} - {!!item.notificationsAmount && ( - - {item.notificationsAmount} - - )} - - ); if (onItemClick || item.disabled) { return ( @@ -106,7 +59,15 @@ const TreeItemTrigger: FC = (props) => { tabIndex={0} onClick={handleItemClick} > - {contentEl} +
    ); } @@ -118,7 +79,15 @@ const TreeItemTrigger: FC = (props) => { title={item.name} aria-label={`Go to ${item.name}`} > - {contentEl} + ); }; diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.module.scss b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.module.scss new file mode 100644 index 000000000..9cb218cf6 --- /dev/null +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.module.scss @@ -0,0 +1,57 @@ +@import "../../../../../../../../../constants"; + +.arrowIconButton { + padding: 0.75rem 1.25rem 0.75rem var(--item-arrow-pl); +} +.arrowIconButtonHidden { + visibility: hidden; +} + +.arrowIcon { + width: 0.5rem; + height: 0.625rem; + color: $c-neutrals-600; + transition: transform 0.2s; +} + +.arrowIconOpen { + transform: rotate(90deg); +} + +.image { + flex-shrink: 0; + margin-right: var(--item-image-mr); + width: 1.5rem; + height: 1.5rem; + object-fit: cover; +} +.imageNonRounded { + border-radius: 0.1875rem; +} +.imageRounded { + border-radius: 50%; +} + +.name { + font-family: PoppinsSans, sans-serif; + font-weight: 600; + font-size: $small; + color: var(--item-text-color); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.notificationsAmount { + height: 1rem; + margin-left: auto; + padding: 0 0.25rem; + display: flex; + align-items: center; + justify-content: center; + font-weight: 600; + font-size: $xxsmall-2; + color: $c-shades-white; + background-color: $c-primary-400; + border-radius: 0.5rem; +} diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.tsx b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.tsx new file mode 100644 index 000000000..743c24f1c --- /dev/null +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.tsx @@ -0,0 +1,70 @@ +import React, { FC } from "react"; +import classNames from "classnames"; +import { ButtonIcon } from "@/shared/components/ButtonIcon"; +import { SmallArrowIcon } from "@/shared/icons"; +import { CommonAvatar } from "@/shared/ui-kit"; +import { TreeItemTriggerStyles } from "../../context"; +import { Item } from "../../types"; +import styles from "./TreeItemTriggerContent.module.scss"; + +interface TreeItemTriggerContentProps { + treeItemTriggerStyles?: TreeItemTriggerStyles; + item: Item; + level: number; + isActive: boolean; + isOpen: boolean; + onToggle?: () => void; + handleToggle: (event: React.MouseEvent) => void; +} + +const TreeItemTriggerContent: FC = (props) => { + const { treeItemTriggerStyles, item, level, isOpen, handleToggle, onToggle } = props; + + return ( + <> + + + + + + + + {item.name} + + {item.nameRightContent} + {item.rightContent} + {!!item.notificationsAmount && ( + + {item.notificationsAmount} + + )} + + ); +}; + +export default TreeItemTriggerContent; diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/index.ts b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/index.ts new file mode 100644 index 000000000..1c215a96e --- /dev/null +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/index.ts @@ -0,0 +1 @@ +export { default as TreeItemTriggerContent } from "./TreeItemTriggerContent"; \ No newline at end of file From fb6414dccc7339dc7a9ae7a7129b8673b00425a3 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Fri, 9 Aug 2024 17:04:18 +0300 Subject: [PATCH 24/36] CW-mobile-performance Optimize components --- .../components/ChatComponent/ChatComponent.tsx | 13 +++++++++---- .../components/FeedLayout/FeedLayout.tsx | 15 +++++++++++---- .../hooks/useCases/useDiscussionMessagesById.ts | 4 ++-- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/pages/common/components/ChatComponent/ChatComponent.tsx b/src/pages/common/components/ChatComponent/ChatComponent.tsx index 096516cea..de1e7796f 100644 --- a/src/pages/common/components/ChatComponent/ChatComponent.tsx +++ b/src/pages/common/components/ChatComponent/ChatComponent.tsx @@ -206,10 +206,15 @@ export default function ChatComponent({ chatChannelId: chatChannel?.id || "", participants: chatChannel?.participants, }); - const users = chatChannel ? chatUsers : discussionUsers; - const discussionMessages = chatChannel - ? chatMessagesData.data - : discussionMessagesData.data || []; + const users = useMemo( + () => (chatChannel ? chatUsers : discussionUsers), + [chatUsers, discussionUsers, chatChannel], + ); + const discussionMessages = useMemo( + () => + chatChannel ? chatMessagesData.data : discussionMessagesData.data || [], + [chatChannel, chatMessagesData.data, discussionMessagesData.data], + ); const isFetchedDiscussionMessages = discussionMessagesData.fetched || chatMessagesData.fetched; const areInitialMessagesLoading = isChatChannel diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx index 0f730acc8..205c35254 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx @@ -215,10 +215,17 @@ const FeedLayout: ForwardRefRenderFunction = ( } = useCommonMember({ shouldAutoReset: false, }); - const commonMember = - chatItem?.nestedItemData?.commonMember || - outerCommonMember || - fetchedCommonMember; + const commonMember = useMemo( + () => + chatItem?.nestedItemData?.commonMember || + outerCommonMember || + fetchedCommonMember, + [ + chatItem?.nestedItemData?.commonMember, + outerCommonMember, + fetchedCommonMember, + ], + ); const userForProfile = useUserForProfile(); const governance = chatItem?.nestedItemData ? fetchedGovernance diff --git a/src/shared/hooks/useCases/useDiscussionMessagesById.ts b/src/shared/hooks/useCases/useDiscussionMessagesById.ts index 6d03f2126..7e6fc36d3 100644 --- a/src/shared/hooks/useCases/useDiscussionMessagesById.ts +++ b/src/shared/hooks/useCases/useDiscussionMessagesById.ts @@ -231,7 +231,7 @@ export const useDiscussionMessagesById = ({ ], ); - const fetchDiscussionMessages = () => { + const fetchDiscussionMessages = useCallback(() => { if ( !discussionId || isEndOfList[discussionId] || @@ -324,7 +324,7 @@ export const useDiscussionMessagesById = ({ } catch(err) { setIsBatchLoading(false); } - }; + },[discussionId, isEndOfList, state.loading, state.data, isBatchLoading, lastVisible, userId, users, directParent, getCommonPagePath, getCommonPageAboutTabPath, onUserClick, onFeedItemClick, onInternalLinkClick, dispatch]); useDeepCompareEffect(() => { (async () => { From 51142e5d33cf3bd3a1f77d0c5d49aa159137d904 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 12 Aug 2024 12:39:55 +0300 Subject: [PATCH 25/36] CW-mobile-perfromance Remove unnecessary libraries --- package.json | 4 +-- .../AddDiscussionComponent.tsx | 2 +- .../components/WhitepaperMembers/helpers.ts | 2 +- .../EditRulesModal/EditSteps/Rules/Rules.tsx | 2 +- .../ChatComponent/ChatComponent.tsx | 2 +- .../utils/getLastNonUserMessage.ts | 2 +- .../DiscussionFormPersist.tsx | 2 +- .../ProposalFormPersist.tsx | 2 +- .../VotingSettings/VotingSettings.tsx | 2 +- .../DiscussionFeedCard/DiscussionFeedCard.tsx | 2 +- .../UnlinkStreamModal/UnlinkStreamModal.tsx | 8 +++-- .../ProposalFeedCard/ProposalFeedCard.tsx | 2 +- .../FeedLayout/utils/splitViewSize.ts | 2 +- .../HeaderContent/hooks/useSearchFeedItems.ts | 2 +- .../commonFeed/hooks/useCommonData/index.ts | 2 +- src/services/Common.ts | 2 +- .../Chat/ChatMessage/ChatMessage.tsx | 2 +- .../Chat/ChatMessage/DMChatMessage.tsx | 2 +- .../components/Reactions/Reactions.tsx | 2 +- src/shared/components/Dropdown/Dropdown.tsx | 2 +- .../AllFilesCarousel/AllFilesCarousel.tsx | 35 ++++++++++--------- .../AdvancedSettingsModal.tsx | 2 +- .../RadioButton/RadioButton.tsx | 2 +- .../useCases/useCommonPinnedFeedItems.ts | 2 +- .../hooks/useCases/useFullCommonData/index.ts | 2 +- .../Header/components/Breadcrumbs/utils.ts | 2 +- .../ui-kit/TextEditor/BaseTextEditor.tsx | 2 +- .../MentionDropdown/MentionDropdown.tsx | 2 +- src/shared/utils/circles.ts | 2 +- .../convertDatesToFirestoreTimestamps.ts | 2 +- src/shared/utils/proposals.ts | 2 +- src/shared/utils/shared.tsx | 2 +- src/store/states/cache/reducer.tsx | 2 +- src/store/states/common/reducer.ts | 2 +- src/store/states/common/saga/getFeedItems.ts | 2 +- src/store/states/inbox/reducer.ts | 2 +- .../states/multipleSpacesLayout/reducer.ts | 2 +- yarn.lock | 10 ------ 38 files changed, 59 insertions(+), 66 deletions(-) diff --git a/package.json b/package.json index 1553bfedc..80ff33fa4 100644 --- a/package.json +++ b/package.json @@ -24,13 +24,11 @@ "firebase": "^10.7.1", "formik": "^2.2.1", "google-libphonenumber": "^3.2.28", - "http-status-codes": "^2.2.0", "i18next": "^21.9.1", "immer": "^9.0.16", - "immutable": "^4.2.0", "is-hotkey": "^0.2.0", "jszip": "^3.7.1", - "lodash": "^4.17.20", + "lodash-es": "^4.17.21", "millify": "^3.5.2", "moment": "^2.29.1", "node-sass": "^4.14.1", diff --git a/src/pages/OldCommon/components/CommonDetailContainer/AddDiscussionComponent/AddDiscussionComponent.tsx b/src/pages/OldCommon/components/CommonDetailContainer/AddDiscussionComponent/AddDiscussionComponent.tsx index 7037f4c72..7ba21e358 100644 --- a/src/pages/OldCommon/components/CommonDetailContainer/AddDiscussionComponent/AddDiscussionComponent.tsx +++ b/src/pages/OldCommon/components/CommonDetailContainer/AddDiscussionComponent/AddDiscussionComponent.tsx @@ -3,7 +3,7 @@ import { useDispatch, useSelector } from "react-redux"; import { MultiValue, SingleValue } from "react-select"; import classNames from "classnames"; import { Formik } from "formik"; -import { omit } from "lodash"; +import { omit } from "lodash-es"; import * as Yup from "yup"; import { createDiscussion } from "@/pages/OldCommon/store/actions"; import { getCommonGovernanceCircles } from "@/pages/OldCommon/store/api"; diff --git a/src/pages/OldCommon/components/CommonDetailContainer/CommonWhitepaper/components/WhitepaperMembers/helpers.ts b/src/pages/OldCommon/components/CommonDetailContainer/CommonWhitepaper/components/WhitepaperMembers/helpers.ts index 0ebc73d35..a4a9d32cd 100644 --- a/src/pages/OldCommon/components/CommonDetailContainer/CommonWhitepaper/components/WhitepaperMembers/helpers.ts +++ b/src/pages/OldCommon/components/CommonDetailContainer/CommonWhitepaper/components/WhitepaperMembers/helpers.ts @@ -1,4 +1,4 @@ -import { lowerCase, startCase } from "lodash"; +import { lowerCase, startCase } from "lodash-es"; import { GovernanceActions } from "@/shared/constants"; import { AllowedActions } from "@/shared/models"; import { commonTypeText } from "@/shared/utils"; diff --git a/src/pages/OldCommon/components/CommonListContainer/EditRulesModal/EditSteps/Rules/Rules.tsx b/src/pages/OldCommon/components/CommonListContainer/EditRulesModal/EditSteps/Rules/Rules.tsx index 813a6cc3d..c89e57d31 100644 --- a/src/pages/OldCommon/components/CommonListContainer/EditRulesModal/EditSteps/Rules/Rules.tsx +++ b/src/pages/OldCommon/components/CommonListContainer/EditRulesModal/EditSteps/Rules/Rules.tsx @@ -8,7 +8,7 @@ import { intersectionBy, isEmpty, isEqual, -} from "lodash"; +} from "lodash-es"; import { Button, Separator } from "@/shared/components"; import { Form, RulesArray } from "@/shared/components/Form/Formik"; import { ModalFooter, ModalHeaderContent } from "@/shared/components/Modal"; diff --git a/src/pages/common/components/ChatComponent/ChatComponent.tsx b/src/pages/common/components/ChatComponent/ChatComponent.tsx index de1e7796f..17a20c141 100644 --- a/src/pages/common/components/ChatComponent/ChatComponent.tsx +++ b/src/pages/common/components/ChatComponent/ChatComponent.tsx @@ -11,7 +11,7 @@ import { useDispatch, useSelector } from "react-redux"; import { useDebounce, useMeasure, useScroll } from "react-use"; import classNames from "classnames"; import isHotkey from "is-hotkey"; -import { debounce, delay, omit } from "lodash"; +import { debounce, delay, omit } from "lodash-es"; import { v4 as uuidv4 } from "uuid"; import { selectUser } from "@/pages/Auth/store/selectors"; import { ChatService, DiscussionMessageService, FileService } from "@/services"; diff --git a/src/pages/common/components/ChatComponent/utils/getLastNonUserMessage.ts b/src/pages/common/components/ChatComponent/utils/getLastNonUserMessage.ts index 1653bea56..8b2f163a0 100644 --- a/src/pages/common/components/ChatComponent/utils/getLastNonUserMessage.ts +++ b/src/pages/common/components/ChatComponent/utils/getLastNonUserMessage.ts @@ -1,4 +1,4 @@ -import findLast from "lodash/findLast"; +import { findLast } from "lodash-es"; import { checkIsUserDiscussionMessage, DiscussionMessage, diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionFormPersist/DiscussionFormPersist.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionFormPersist/DiscussionFormPersist.tsx index b04e92185..757fda4bc 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionFormPersist/DiscussionFormPersist.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionFormPersist/DiscussionFormPersist.tsx @@ -1,7 +1,7 @@ import React, { FC, useEffect, useMemo } from "react"; import { useDispatch } from "react-redux"; import { useFormikContext } from "formik"; -import debounce from "lodash/debounce"; +import { debounce } from "lodash-es"; import { NewDiscussionCreationFormValues } from "@/shared/interfaces"; import { commonActions } from "@/store/states"; diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalFormPersist/ProposalFormPersist.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalFormPersist/ProposalFormPersist.tsx index 5b69531cd..d9eba8e16 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalFormPersist/ProposalFormPersist.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalFormPersist/ProposalFormPersist.tsx @@ -1,7 +1,7 @@ import React, { FC, useEffect, useMemo } from "react"; import { useDispatch } from "react-redux"; import { useFormikContext } from "formik"; -import debounce from "lodash/debounce"; +import { debounce } from "lodash-es"; import { NewProposalCreationFormValues } from "@/shared/interfaces"; import { commonActions } from "@/store/states"; diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/VotingSettings/VotingSettings.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/VotingSettings/VotingSettings.tsx index fb7d9dcd3..e7c798b50 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/VotingSettings/VotingSettings.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/VotingSettings/VotingSettings.tsx @@ -1,5 +1,5 @@ import React, { FC, useMemo } from "react"; -import { flattenDeep, uniq } from "lodash"; +import { flattenDeep, uniq } from "lodash-es"; import { ProposalsTypes } from "@/shared/constants"; import { Circles, Governance } from "@/shared/models"; import { diff --git a/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx b/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx index 5ae93d503..1fa0fd3c3 100644 --- a/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx +++ b/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx @@ -7,7 +7,7 @@ import React, { } from "react"; import { useSelector } from "react-redux"; import { useUpdateEffect } from "react-use"; -import { debounce } from "lodash"; +import { debounce } from "lodash-es"; import { selectUser } from "@/pages/Auth/store/selectors"; import { DiscussionService } from "@/services"; import { DeletePrompt, GlobalOverlay, ReportModal } from "@/shared/components"; diff --git a/src/pages/common/components/DiscussionFeedCard/components/UnlinkStreamModal/UnlinkStreamModal.tsx b/src/pages/common/components/DiscussionFeedCard/components/UnlinkStreamModal/UnlinkStreamModal.tsx index 76f088697..0cc50eec3 100644 --- a/src/pages/common/components/DiscussionFeedCard/components/UnlinkStreamModal/UnlinkStreamModal.tsx +++ b/src/pages/common/components/DiscussionFeedCard/components/UnlinkStreamModal/UnlinkStreamModal.tsx @@ -2,7 +2,7 @@ import React, { FC, useRef, useState } from "react"; import { useSelector } from "react-redux"; import { CancelTokenSource } from "axios"; import classNames from "classnames"; -import { isError } from "lodash"; +import { isError } from "lodash-es"; import { selectUser } from "@/pages/Auth/store/selectors"; import { CommonFeedService, @@ -71,7 +71,11 @@ const UnlinkStreamModal: FC = (props) => { cancelTokenRef.current = null; } setIsUnlinking(false); - setErrorText(isError(error) ? error.message : "Something went wrong..."); + setErrorText( + isError(error) + ? (error as Record)?.message + : "Something went wrong...", + ); } }; diff --git a/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx b/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx index 3396b0756..49f2262a7 100644 --- a/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx +++ b/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx @@ -7,7 +7,7 @@ import React, { } from "react"; import { useSelector } from "react-redux"; import { useUpdateEffect } from "react-use"; -import { debounce } from "lodash"; +import { debounce } from "lodash-es"; import { selectUser } from "@/pages/Auth/store/selectors"; import { useCommonMember, useProposalUserVote } from "@/pages/OldCommon/hooks"; import { ProposalService } from "@/services"; diff --git a/src/pages/commonFeed/components/FeedLayout/utils/splitViewSize.ts b/src/pages/commonFeed/components/FeedLayout/utils/splitViewSize.ts index f9f1c48ad..02ab48a81 100644 --- a/src/pages/commonFeed/components/FeedLayout/utils/splitViewSize.ts +++ b/src/pages/commonFeed/components/FeedLayout/utils/splitViewSize.ts @@ -1,4 +1,4 @@ -import { debounce } from "lodash"; +import { debounce } from "lodash-es"; import { StorageKey } from "@/shared/constants"; export const saveChatSize = debounce((size: number) => { diff --git a/src/pages/commonFeed/components/HeaderContent/hooks/useSearchFeedItems.ts b/src/pages/commonFeed/components/HeaderContent/hooks/useSearchFeedItems.ts index a75080246..f36438b64 100644 --- a/src/pages/commonFeed/components/HeaderContent/hooks/useSearchFeedItems.ts +++ b/src/pages/commonFeed/components/HeaderContent/hooks/useSearchFeedItems.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect, useState } from "react"; -import { debounce } from "lodash"; +import { debounce } from "lodash-es"; import { QueryParamKey } from "@/shared/constants"; import { ToggleState, useQueryParams, useToggle } from "@/shared/hooks"; import { addQueryParam, deleteQueryParam } from "@/shared/utils"; diff --git a/src/pages/commonFeed/hooks/useCommonData/index.ts b/src/pages/commonFeed/hooks/useCommonData/index.ts index 655be3d88..a93847385 100644 --- a/src/pages/commonFeed/hooks/useCommonData/index.ts +++ b/src/pages/commonFeed/hooks/useCommonData/index.ts @@ -1,5 +1,5 @@ import { RefObject, useCallback, useRef, useState } from "react"; -import { last } from "lodash"; +import { last } from "lodash-es"; import { CommonFeedService, CommonService, diff --git a/src/services/Common.ts b/src/services/Common.ts index 7429ff78d..a62be3d7e 100644 --- a/src/services/Common.ts +++ b/src/services/Common.ts @@ -1,4 +1,4 @@ -import { isEqual } from "lodash"; +import { isEqual } from "lodash-es"; import { getCommonState, updateCommonState, diff --git a/src/shared/components/Chat/ChatMessage/ChatMessage.tsx b/src/shared/components/Chat/ChatMessage/ChatMessage.tsx index 8b4b56a0b..832fe196c 100644 --- a/src/shared/components/Chat/ChatMessage/ChatMessage.tsx +++ b/src/shared/components/Chat/ChatMessage/ChatMessage.tsx @@ -8,7 +8,7 @@ import React, { } from "react"; import { useDispatch } from "react-redux"; import classNames from "classnames"; -import { isEmpty } from "lodash"; +import { isEmpty } from "lodash-es"; import { Element } from "slate"; import { useLongPress } from "use-long-press"; import * as oldCommonActions from "@/pages/OldCommon/store/actions"; diff --git a/src/shared/components/Chat/ChatMessage/DMChatMessage.tsx b/src/shared/components/Chat/ChatMessage/DMChatMessage.tsx index 99f8c2aff..8ae0a4547 100644 --- a/src/shared/components/Chat/ChatMessage/DMChatMessage.tsx +++ b/src/shared/components/Chat/ChatMessage/DMChatMessage.tsx @@ -9,7 +9,7 @@ import React, { import { useDispatch } from "react-redux"; import { usePrevious } from "react-use"; import classNames from "classnames"; -import { isEmpty, isEqual } from "lodash"; +import { isEmpty, isEqual } from "lodash-es"; import { Element } from "slate"; import { useLongPress } from "use-long-press"; import { ChatService, Logger } from "@/services"; diff --git a/src/shared/components/Chat/ChatMessage/components/Reactions/Reactions.tsx b/src/shared/components/Chat/ChatMessage/components/Reactions/Reactions.tsx index 2e9585e4b..4c8e4f284 100644 --- a/src/shared/components/Chat/ChatMessage/components/Reactions/Reactions.tsx +++ b/src/shared/components/Chat/ChatMessage/components/Reactions/Reactions.tsx @@ -7,7 +7,7 @@ import React, { useState, } from "react"; import { useSelector } from "react-redux"; -import { isEmpty } from "lodash"; +import { isEmpty } from "lodash-es"; import { selectUser } from "@/pages/Auth/store/selectors"; import { Logger } from "@/services"; import { UserAvatar } from "@/shared/components/UserAvatar"; diff --git a/src/shared/components/Dropdown/Dropdown.tsx b/src/shared/components/Dropdown/Dropdown.tsx index 8f7e34c68..83cec6cdc 100644 --- a/src/shared/components/Dropdown/Dropdown.tsx +++ b/src/shared/components/Dropdown/Dropdown.tsx @@ -19,7 +19,7 @@ import { closeMenu, } from "react-aria-menubutton"; import classNames from "classnames"; -import { isEqual } from "lodash"; +import { isEqual } from "lodash-es"; import { v4 as uuidv4 } from "uuid"; import { useChatContentContext } from "@/pages/common/components/CommonContent/context"; import { Loader } from "@/shared/components"; diff --git a/src/shared/components/FilesCarousel/AllFilesCarousel/AllFilesCarousel.tsx b/src/shared/components/FilesCarousel/AllFilesCarousel/AllFilesCarousel.tsx index 8b032dc89..848144770 100644 --- a/src/shared/components/FilesCarousel/AllFilesCarousel/AllFilesCarousel.tsx +++ b/src/shared/components/FilesCarousel/AllFilesCarousel/AllFilesCarousel.tsx @@ -9,14 +9,14 @@ import React, { ForwardRefRenderFunction, } from "react"; import classNames from "classnames"; +import throttle from "lodash-es/throttle"; import { Swiper, SwiperSlide } from "swiper/react"; import SwiperClass from "swiper/types/swiper-class"; -import throttle from "lodash/throttle"; import DownloadIcon from "../../../icons/download.icon"; import LeftArrowIcon from "../../../icons/leftArrow.icon"; import RightArrowIcon from "../../../icons/rightArrow.icon"; -import { saveZip } from "../../../utils"; import { DocInfo } from "../../../models"; +import { saveZip } from "../../../utils"; import { ButtonIcon } from "../../ButtonIcon"; import { InvoiceTile } from "../../InvoiceTile"; import { getSwiperConfig } from "./helpers"; @@ -45,10 +45,8 @@ const AllFilesCarousel: ForwardRefRenderFunction< initialDocIndex, onDocClick, } = props; - const [ - swiperWrapperRef, - setSwiperWrapperRef, - ] = useState(null); + const [swiperWrapperRef, setSwiperWrapperRef] = + useState(null); const [{ isBeginning, isEnd }, setSlideState] = useState<{ isBeginning: boolean; isEnd: boolean; @@ -59,7 +57,7 @@ const AllFilesCarousel: ForwardRefRenderFunction< const swiperClientWidth = swiperWrapperRef?.clientWidth || 0; const swiperConfig = useMemo( () => getSwiperConfig(payoutDocs.length, swiperClientWidth), - [payoutDocs.length, swiperClientWidth] + [payoutDocs.length, swiperClientWidth], ); const handleSlideChange = useCallback( @@ -70,17 +68,17 @@ const AllFilesCarousel: ForwardRefRenderFunction< : { isBeginning, isEnd, - } + }, ); }, - [] + [], ); const handleSwiper = useCallback( (swiper: SwiperClass) => { swiperRef.current = swiper; handleSlideChange(swiper); }, - [handleSlideChange] + [handleSlideChange], ); const handleLeftClick = () => { @@ -131,14 +129,14 @@ const AllFilesCarousel: ForwardRefRenderFunction< swiperRef.current?.slideTo(index); }, }), - [] + [], ); const contentWrapperClassName = classNames( "all-files-carousel-wrapper__content-wrapper", { "all-files-carousel-wrapper__content-wrapper--without-actions": false, - } + }, ); return ( @@ -159,7 +157,8 @@ const AllFilesCarousel: ForwardRefRenderFunction<
    Date: Mon, 12 Aug 2024 13:11:12 +0300 Subject: [PATCH 26/36] CW-mobile-performance Fix jest config --- jest.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/jest.config.js b/jest.config.js index 7dd0e821f..a36638aea 100644 --- a/jest.config.js +++ b/jest.config.js @@ -16,5 +16,6 @@ module.exports = { "^@/(.*)$": "/src/$1", }, testPathIgnorePatterns: ["/node_modules/", "/public/"], + transformIgnorePatterns: ["/node_modules/(?!lodash-es)"], testEnvironment: "jsdom", }; From d9aa6e865a18562f22e9c4c4a0fbf3ee63e31742 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 12 Aug 2024 13:22:29 +0300 Subject: [PATCH 27/36] CW-mobile-performance Fix words func call --- src/shared/utils/shared.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/utils/shared.tsx b/src/shared/utils/shared.tsx index 86213243f..40496a7d1 100644 --- a/src/shared/utils/shared.tsx +++ b/src/shared/utils/shared.tsx @@ -124,7 +124,7 @@ export const getRandomUserAvatarURL = ( name?: string | null, textColor = "ffffff", ): string => { - const isOneWord = words(name ?? "").length === 1; + const isOneWord = words(name ?? "", null, null).length === 1; return `https://eu.ui-avatars.com/api/?background=99999D&color=${textColor.substring( 1, )}&name=${name?.replace(/\s/gi, "+")}&rounded=true&${ From 9fecc76d4d3b7b7cb18e0a25fc3ecfda82eb4d1b Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 12 Aug 2024 13:32:00 +0300 Subject: [PATCH 28/36] CW-mobile-performance Fix eslint --- src/shared/utils/shared.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/utils/shared.tsx b/src/shared/utils/shared.tsx index 40496a7d1..c5efb3083 100644 --- a/src/shared/utils/shared.tsx +++ b/src/shared/utils/shared.tsx @@ -124,7 +124,7 @@ export const getRandomUserAvatarURL = ( name?: string | null, textColor = "ffffff", ): string => { - const isOneWord = words(name ?? "", null, null).length === 1; + const isOneWord = words(name ?? "", undefined, undefined).length === 1; return `https://eu.ui-avatars.com/api/?background=99999D&color=${textColor.substring( 1, )}&name=${name?.replace(/\s/gi, "+")}&rounded=true&${ From 8b4d4af07545d31ead46698149daa43519ee333c Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 12 Aug 2024 14:49:08 +0300 Subject: [PATCH 29/36] CW-mobile-performance Added lodash-es types --- package.json | 2 +- src/shared/utils/shared.tsx | 2 +- yarn.lock | 17 ++++++++++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 80ff33fa4..a8e6024b3 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "@types/google-libphonenumber": "^7.4.23", "@types/is-hotkey": "^0.1.7", "@types/jest": "^27.5.2", - "@types/lodash": "^4.14.163", + "@types/lodash-es": "^4.17.12", "@types/node": "^12.19.3", "@types/openpgp": "4.4.12", "@types/react": "^16.9.55", diff --git a/src/shared/utils/shared.tsx b/src/shared/utils/shared.tsx index c5efb3083..86213243f 100644 --- a/src/shared/utils/shared.tsx +++ b/src/shared/utils/shared.tsx @@ -124,7 +124,7 @@ export const getRandomUserAvatarURL = ( name?: string | null, textColor = "ffffff", ): string => { - const isOneWord = words(name ?? "", undefined, undefined).length === 1; + const isOneWord = words(name ?? "").length === 1; return `https://eu.ui-avatars.com/api/?background=99999D&color=${textColor.substring( 1, )}&name=${name?.replace(/\s/gi, "+")}&rounded=true&${ diff --git a/yarn.lock b/yarn.lock index f3a87f9ba..ac95f0b29 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5520,16 +5520,23 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/lodash-es@^4.17.12": + version "4.17.12" + resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.12.tgz#65f6d1e5f80539aa7cfbfc962de5def0cf4f341b" + integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.17.7" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.7.tgz#2f776bcb53adc9e13b2c0dfd493dfcbd7de43612" + integrity sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA== + "@types/lodash@^4.14.149": version "4.14.191" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa" integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== -"@types/lodash@^4.14.163": - version "4.14.182" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2" - integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q== - "@types/lodash@^4.14.167": version "4.14.187" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.187.tgz#122ff0a7192115b4c1a19444ab4482caa77e2c9d" From dbcf4b678f7e8a9127b196b52522870f25e37616 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 12 Aug 2024 14:55:17 +0300 Subject: [PATCH 30/36] Revert "CW-mobile-performance Added lodash-es types" This reverts commit 8b4d4af07545d31ead46698149daa43519ee333c. --- package.json | 2 +- src/shared/utils/shared.tsx | 2 +- yarn.lock | 17 +++++------------ 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index a8e6024b3..80ff33fa4 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "@types/google-libphonenumber": "^7.4.23", "@types/is-hotkey": "^0.1.7", "@types/jest": "^27.5.2", - "@types/lodash-es": "^4.17.12", + "@types/lodash": "^4.14.163", "@types/node": "^12.19.3", "@types/openpgp": "4.4.12", "@types/react": "^16.9.55", diff --git a/src/shared/utils/shared.tsx b/src/shared/utils/shared.tsx index 86213243f..c5efb3083 100644 --- a/src/shared/utils/shared.tsx +++ b/src/shared/utils/shared.tsx @@ -124,7 +124,7 @@ export const getRandomUserAvatarURL = ( name?: string | null, textColor = "ffffff", ): string => { - const isOneWord = words(name ?? "").length === 1; + const isOneWord = words(name ?? "", undefined, undefined).length === 1; return `https://eu.ui-avatars.com/api/?background=99999D&color=${textColor.substring( 1, )}&name=${name?.replace(/\s/gi, "+")}&rounded=true&${ diff --git a/yarn.lock b/yarn.lock index ac95f0b29..f3a87f9ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5520,23 +5520,16 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/lodash-es@^4.17.12": - version "4.17.12" - resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.12.tgz#65f6d1e5f80539aa7cfbfc962de5def0cf4f341b" - integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ== - dependencies: - "@types/lodash" "*" - -"@types/lodash@*": - version "4.17.7" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.7.tgz#2f776bcb53adc9e13b2c0dfd493dfcbd7de43612" - integrity sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA== - "@types/lodash@^4.14.149": version "4.14.191" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa" integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== +"@types/lodash@^4.14.163": + version "4.14.182" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2" + integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q== + "@types/lodash@^4.14.167": version "4.14.187" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.187.tgz#122ff0a7192115b4c1a19444ab4482caa77e2c9d" From 218e3628f401e795d7699bd613fd7b746ad77b33 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 12 Aug 2024 14:55:24 +0300 Subject: [PATCH 31/36] Revert "CW-mobile-performance Fix eslint" This reverts commit 9fecc76d4d3b7b7cb18e0a25fc3ecfda82eb4d1b. --- src/shared/utils/shared.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/utils/shared.tsx b/src/shared/utils/shared.tsx index c5efb3083..40496a7d1 100644 --- a/src/shared/utils/shared.tsx +++ b/src/shared/utils/shared.tsx @@ -124,7 +124,7 @@ export const getRandomUserAvatarURL = ( name?: string | null, textColor = "ffffff", ): string => { - const isOneWord = words(name ?? "", undefined, undefined).length === 1; + const isOneWord = words(name ?? "", null, null).length === 1; return `https://eu.ui-avatars.com/api/?background=99999D&color=${textColor.substring( 1, )}&name=${name?.replace(/\s/gi, "+")}&rounded=true&${ From 5813f1bfb9ca5cf0da296314a19652437dce8226 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 12 Aug 2024 14:55:28 +0300 Subject: [PATCH 32/36] Revert "CW-mobile-performance Fix words func call" This reverts commit d9aa6e865a18562f22e9c4c4a0fbf3ee63e31742. --- src/shared/utils/shared.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/utils/shared.tsx b/src/shared/utils/shared.tsx index 40496a7d1..86213243f 100644 --- a/src/shared/utils/shared.tsx +++ b/src/shared/utils/shared.tsx @@ -124,7 +124,7 @@ export const getRandomUserAvatarURL = ( name?: string | null, textColor = "ffffff", ): string => { - const isOneWord = words(name ?? "", null, null).length === 1; + const isOneWord = words(name ?? "").length === 1; return `https://eu.ui-avatars.com/api/?background=99999D&color=${textColor.substring( 1, )}&name=${name?.replace(/\s/gi, "+")}&rounded=true&${ From 9d245d0f9ffb0b765541819ce73571ff643de3d4 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 12 Aug 2024 14:55:33 +0300 Subject: [PATCH 33/36] Revert "CW-mobile-performance Fix jest config" This reverts commit d7792d49f1c722cd95e32c9e424444dc16795074. --- jest.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index a36638aea..7dd0e821f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -16,6 +16,5 @@ module.exports = { "^@/(.*)$": "/src/$1", }, testPathIgnorePatterns: ["/node_modules/", "/public/"], - transformIgnorePatterns: ["/node_modules/(?!lodash-es)"], testEnvironment: "jsdom", }; From 2be85e81df08f830db607529f70a26ac573fff27 Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Mon, 12 Aug 2024 14:55:39 +0300 Subject: [PATCH 34/36] Revert "CW-mobile-perfromance Remove unnecessary libraries" This reverts commit 51142e5d33cf3bd3a1f77d0c5d49aa159137d904. --- package.json | 4 ++- .../AddDiscussionComponent.tsx | 2 +- .../components/WhitepaperMembers/helpers.ts | 2 +- .../EditRulesModal/EditSteps/Rules/Rules.tsx | 2 +- .../ChatComponent/ChatComponent.tsx | 2 +- .../utils/getLastNonUserMessage.ts | 2 +- .../DiscussionFormPersist.tsx | 2 +- .../ProposalFormPersist.tsx | 2 +- .../VotingSettings/VotingSettings.tsx | 2 +- .../DiscussionFeedCard/DiscussionFeedCard.tsx | 2 +- .../UnlinkStreamModal/UnlinkStreamModal.tsx | 8 ++--- .../ProposalFeedCard/ProposalFeedCard.tsx | 2 +- .../FeedLayout/utils/splitViewSize.ts | 2 +- .../HeaderContent/hooks/useSearchFeedItems.ts | 2 +- .../commonFeed/hooks/useCommonData/index.ts | 2 +- src/services/Common.ts | 2 +- .../Chat/ChatMessage/ChatMessage.tsx | 2 +- .../Chat/ChatMessage/DMChatMessage.tsx | 2 +- .../components/Reactions/Reactions.tsx | 2 +- src/shared/components/Dropdown/Dropdown.tsx | 2 +- .../AllFilesCarousel/AllFilesCarousel.tsx | 35 +++++++++---------- .../AdvancedSettingsModal.tsx | 2 +- .../RadioButton/RadioButton.tsx | 2 +- .../useCases/useCommonPinnedFeedItems.ts | 2 +- .../hooks/useCases/useFullCommonData/index.ts | 2 +- .../Header/components/Breadcrumbs/utils.ts | 2 +- .../ui-kit/TextEditor/BaseTextEditor.tsx | 2 +- .../MentionDropdown/MentionDropdown.tsx | 2 +- src/shared/utils/circles.ts | 2 +- .../convertDatesToFirestoreTimestamps.ts | 2 +- src/shared/utils/proposals.ts | 2 +- src/shared/utils/shared.tsx | 2 +- src/store/states/cache/reducer.tsx | 2 +- src/store/states/common/reducer.ts | 2 +- src/store/states/common/saga/getFeedItems.ts | 2 +- src/store/states/inbox/reducer.ts | 2 +- .../states/multipleSpacesLayout/reducer.ts | 2 +- yarn.lock | 10 ++++++ 38 files changed, 66 insertions(+), 59 deletions(-) diff --git a/package.json b/package.json index 80ff33fa4..1553bfedc 100644 --- a/package.json +++ b/package.json @@ -24,11 +24,13 @@ "firebase": "^10.7.1", "formik": "^2.2.1", "google-libphonenumber": "^3.2.28", + "http-status-codes": "^2.2.0", "i18next": "^21.9.1", "immer": "^9.0.16", + "immutable": "^4.2.0", "is-hotkey": "^0.2.0", "jszip": "^3.7.1", - "lodash-es": "^4.17.21", + "lodash": "^4.17.20", "millify": "^3.5.2", "moment": "^2.29.1", "node-sass": "^4.14.1", diff --git a/src/pages/OldCommon/components/CommonDetailContainer/AddDiscussionComponent/AddDiscussionComponent.tsx b/src/pages/OldCommon/components/CommonDetailContainer/AddDiscussionComponent/AddDiscussionComponent.tsx index 7ba21e358..7037f4c72 100644 --- a/src/pages/OldCommon/components/CommonDetailContainer/AddDiscussionComponent/AddDiscussionComponent.tsx +++ b/src/pages/OldCommon/components/CommonDetailContainer/AddDiscussionComponent/AddDiscussionComponent.tsx @@ -3,7 +3,7 @@ import { useDispatch, useSelector } from "react-redux"; import { MultiValue, SingleValue } from "react-select"; import classNames from "classnames"; import { Formik } from "formik"; -import { omit } from "lodash-es"; +import { omit } from "lodash"; import * as Yup from "yup"; import { createDiscussion } from "@/pages/OldCommon/store/actions"; import { getCommonGovernanceCircles } from "@/pages/OldCommon/store/api"; diff --git a/src/pages/OldCommon/components/CommonDetailContainer/CommonWhitepaper/components/WhitepaperMembers/helpers.ts b/src/pages/OldCommon/components/CommonDetailContainer/CommonWhitepaper/components/WhitepaperMembers/helpers.ts index a4a9d32cd..0ebc73d35 100644 --- a/src/pages/OldCommon/components/CommonDetailContainer/CommonWhitepaper/components/WhitepaperMembers/helpers.ts +++ b/src/pages/OldCommon/components/CommonDetailContainer/CommonWhitepaper/components/WhitepaperMembers/helpers.ts @@ -1,4 +1,4 @@ -import { lowerCase, startCase } from "lodash-es"; +import { lowerCase, startCase } from "lodash"; import { GovernanceActions } from "@/shared/constants"; import { AllowedActions } from "@/shared/models"; import { commonTypeText } from "@/shared/utils"; diff --git a/src/pages/OldCommon/components/CommonListContainer/EditRulesModal/EditSteps/Rules/Rules.tsx b/src/pages/OldCommon/components/CommonListContainer/EditRulesModal/EditSteps/Rules/Rules.tsx index c89e57d31..813a6cc3d 100644 --- a/src/pages/OldCommon/components/CommonListContainer/EditRulesModal/EditSteps/Rules/Rules.tsx +++ b/src/pages/OldCommon/components/CommonListContainer/EditRulesModal/EditSteps/Rules/Rules.tsx @@ -8,7 +8,7 @@ import { intersectionBy, isEmpty, isEqual, -} from "lodash-es"; +} from "lodash"; import { Button, Separator } from "@/shared/components"; import { Form, RulesArray } from "@/shared/components/Form/Formik"; import { ModalFooter, ModalHeaderContent } from "@/shared/components/Modal"; diff --git a/src/pages/common/components/ChatComponent/ChatComponent.tsx b/src/pages/common/components/ChatComponent/ChatComponent.tsx index 17a20c141..de1e7796f 100644 --- a/src/pages/common/components/ChatComponent/ChatComponent.tsx +++ b/src/pages/common/components/ChatComponent/ChatComponent.tsx @@ -11,7 +11,7 @@ import { useDispatch, useSelector } from "react-redux"; import { useDebounce, useMeasure, useScroll } from "react-use"; import classNames from "classnames"; import isHotkey from "is-hotkey"; -import { debounce, delay, omit } from "lodash-es"; +import { debounce, delay, omit } from "lodash"; import { v4 as uuidv4 } from "uuid"; import { selectUser } from "@/pages/Auth/store/selectors"; import { ChatService, DiscussionMessageService, FileService } from "@/services"; diff --git a/src/pages/common/components/ChatComponent/utils/getLastNonUserMessage.ts b/src/pages/common/components/ChatComponent/utils/getLastNonUserMessage.ts index 8b2f163a0..1653bea56 100644 --- a/src/pages/common/components/ChatComponent/utils/getLastNonUserMessage.ts +++ b/src/pages/common/components/ChatComponent/utils/getLastNonUserMessage.ts @@ -1,4 +1,4 @@ -import { findLast } from "lodash-es"; +import findLast from "lodash/findLast"; import { checkIsUserDiscussionMessage, DiscussionMessage, diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionFormPersist/DiscussionFormPersist.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionFormPersist/DiscussionFormPersist.tsx index 757fda4bc..b04e92185 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionFormPersist/DiscussionFormPersist.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionFormPersist/DiscussionFormPersist.tsx @@ -1,7 +1,7 @@ import React, { FC, useEffect, useMemo } from "react"; import { useDispatch } from "react-redux"; import { useFormikContext } from "formik"; -import { debounce } from "lodash-es"; +import debounce from "lodash/debounce"; import { NewDiscussionCreationFormValues } from "@/shared/interfaces"; import { commonActions } from "@/store/states"; diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalFormPersist/ProposalFormPersist.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalFormPersist/ProposalFormPersist.tsx index d9eba8e16..5b69531cd 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalFormPersist/ProposalFormPersist.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalFormPersist/ProposalFormPersist.tsx @@ -1,7 +1,7 @@ import React, { FC, useEffect, useMemo } from "react"; import { useDispatch } from "react-redux"; import { useFormikContext } from "formik"; -import { debounce } from "lodash-es"; +import debounce from "lodash/debounce"; import { NewProposalCreationFormValues } from "@/shared/interfaces"; import { commonActions } from "@/store/states"; diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/VotingSettings/VotingSettings.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/VotingSettings/VotingSettings.tsx index e7c798b50..fb7d9dcd3 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/VotingSettings/VotingSettings.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/VotingSettings/VotingSettings.tsx @@ -1,5 +1,5 @@ import React, { FC, useMemo } from "react"; -import { flattenDeep, uniq } from "lodash-es"; +import { flattenDeep, uniq } from "lodash"; import { ProposalsTypes } from "@/shared/constants"; import { Circles, Governance } from "@/shared/models"; import { diff --git a/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx b/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx index 1fa0fd3c3..5ae93d503 100644 --- a/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx +++ b/src/pages/common/components/DiscussionFeedCard/DiscussionFeedCard.tsx @@ -7,7 +7,7 @@ import React, { } from "react"; import { useSelector } from "react-redux"; import { useUpdateEffect } from "react-use"; -import { debounce } from "lodash-es"; +import { debounce } from "lodash"; import { selectUser } from "@/pages/Auth/store/selectors"; import { DiscussionService } from "@/services"; import { DeletePrompt, GlobalOverlay, ReportModal } from "@/shared/components"; diff --git a/src/pages/common/components/DiscussionFeedCard/components/UnlinkStreamModal/UnlinkStreamModal.tsx b/src/pages/common/components/DiscussionFeedCard/components/UnlinkStreamModal/UnlinkStreamModal.tsx index 0cc50eec3..76f088697 100644 --- a/src/pages/common/components/DiscussionFeedCard/components/UnlinkStreamModal/UnlinkStreamModal.tsx +++ b/src/pages/common/components/DiscussionFeedCard/components/UnlinkStreamModal/UnlinkStreamModal.tsx @@ -2,7 +2,7 @@ import React, { FC, useRef, useState } from "react"; import { useSelector } from "react-redux"; import { CancelTokenSource } from "axios"; import classNames from "classnames"; -import { isError } from "lodash-es"; +import { isError } from "lodash"; import { selectUser } from "@/pages/Auth/store/selectors"; import { CommonFeedService, @@ -71,11 +71,7 @@ const UnlinkStreamModal: FC = (props) => { cancelTokenRef.current = null; } setIsUnlinking(false); - setErrorText( - isError(error) - ? (error as Record)?.message - : "Something went wrong...", - ); + setErrorText(isError(error) ? error.message : "Something went wrong..."); } }; diff --git a/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx b/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx index 49f2262a7..3396b0756 100644 --- a/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx +++ b/src/pages/common/components/ProposalFeedCard/ProposalFeedCard.tsx @@ -7,7 +7,7 @@ import React, { } from "react"; import { useSelector } from "react-redux"; import { useUpdateEffect } from "react-use"; -import { debounce } from "lodash-es"; +import { debounce } from "lodash"; import { selectUser } from "@/pages/Auth/store/selectors"; import { useCommonMember, useProposalUserVote } from "@/pages/OldCommon/hooks"; import { ProposalService } from "@/services"; diff --git a/src/pages/commonFeed/components/FeedLayout/utils/splitViewSize.ts b/src/pages/commonFeed/components/FeedLayout/utils/splitViewSize.ts index 02ab48a81..f9f1c48ad 100644 --- a/src/pages/commonFeed/components/FeedLayout/utils/splitViewSize.ts +++ b/src/pages/commonFeed/components/FeedLayout/utils/splitViewSize.ts @@ -1,4 +1,4 @@ -import { debounce } from "lodash-es"; +import { debounce } from "lodash"; import { StorageKey } from "@/shared/constants"; export const saveChatSize = debounce((size: number) => { diff --git a/src/pages/commonFeed/components/HeaderContent/hooks/useSearchFeedItems.ts b/src/pages/commonFeed/components/HeaderContent/hooks/useSearchFeedItems.ts index f36438b64..a75080246 100644 --- a/src/pages/commonFeed/components/HeaderContent/hooks/useSearchFeedItems.ts +++ b/src/pages/commonFeed/components/HeaderContent/hooks/useSearchFeedItems.ts @@ -1,5 +1,5 @@ import { useCallback, useEffect, useState } from "react"; -import { debounce } from "lodash-es"; +import { debounce } from "lodash"; import { QueryParamKey } from "@/shared/constants"; import { ToggleState, useQueryParams, useToggle } from "@/shared/hooks"; import { addQueryParam, deleteQueryParam } from "@/shared/utils"; diff --git a/src/pages/commonFeed/hooks/useCommonData/index.ts b/src/pages/commonFeed/hooks/useCommonData/index.ts index a93847385..655be3d88 100644 --- a/src/pages/commonFeed/hooks/useCommonData/index.ts +++ b/src/pages/commonFeed/hooks/useCommonData/index.ts @@ -1,5 +1,5 @@ import { RefObject, useCallback, useRef, useState } from "react"; -import { last } from "lodash-es"; +import { last } from "lodash"; import { CommonFeedService, CommonService, diff --git a/src/services/Common.ts b/src/services/Common.ts index a62be3d7e..7429ff78d 100644 --- a/src/services/Common.ts +++ b/src/services/Common.ts @@ -1,4 +1,4 @@ -import { isEqual } from "lodash-es"; +import { isEqual } from "lodash"; import { getCommonState, updateCommonState, diff --git a/src/shared/components/Chat/ChatMessage/ChatMessage.tsx b/src/shared/components/Chat/ChatMessage/ChatMessage.tsx index 832fe196c..8b4b56a0b 100644 --- a/src/shared/components/Chat/ChatMessage/ChatMessage.tsx +++ b/src/shared/components/Chat/ChatMessage/ChatMessage.tsx @@ -8,7 +8,7 @@ import React, { } from "react"; import { useDispatch } from "react-redux"; import classNames from "classnames"; -import { isEmpty } from "lodash-es"; +import { isEmpty } from "lodash"; import { Element } from "slate"; import { useLongPress } from "use-long-press"; import * as oldCommonActions from "@/pages/OldCommon/store/actions"; diff --git a/src/shared/components/Chat/ChatMessage/DMChatMessage.tsx b/src/shared/components/Chat/ChatMessage/DMChatMessage.tsx index 8ae0a4547..99f8c2aff 100644 --- a/src/shared/components/Chat/ChatMessage/DMChatMessage.tsx +++ b/src/shared/components/Chat/ChatMessage/DMChatMessage.tsx @@ -9,7 +9,7 @@ import React, { import { useDispatch } from "react-redux"; import { usePrevious } from "react-use"; import classNames from "classnames"; -import { isEmpty, isEqual } from "lodash-es"; +import { isEmpty, isEqual } from "lodash"; import { Element } from "slate"; import { useLongPress } from "use-long-press"; import { ChatService, Logger } from "@/services"; diff --git a/src/shared/components/Chat/ChatMessage/components/Reactions/Reactions.tsx b/src/shared/components/Chat/ChatMessage/components/Reactions/Reactions.tsx index 4c8e4f284..2e9585e4b 100644 --- a/src/shared/components/Chat/ChatMessage/components/Reactions/Reactions.tsx +++ b/src/shared/components/Chat/ChatMessage/components/Reactions/Reactions.tsx @@ -7,7 +7,7 @@ import React, { useState, } from "react"; import { useSelector } from "react-redux"; -import { isEmpty } from "lodash-es"; +import { isEmpty } from "lodash"; import { selectUser } from "@/pages/Auth/store/selectors"; import { Logger } from "@/services"; import { UserAvatar } from "@/shared/components/UserAvatar"; diff --git a/src/shared/components/Dropdown/Dropdown.tsx b/src/shared/components/Dropdown/Dropdown.tsx index 83cec6cdc..8f7e34c68 100644 --- a/src/shared/components/Dropdown/Dropdown.tsx +++ b/src/shared/components/Dropdown/Dropdown.tsx @@ -19,7 +19,7 @@ import { closeMenu, } from "react-aria-menubutton"; import classNames from "classnames"; -import { isEqual } from "lodash-es"; +import { isEqual } from "lodash"; import { v4 as uuidv4 } from "uuid"; import { useChatContentContext } from "@/pages/common/components/CommonContent/context"; import { Loader } from "@/shared/components"; diff --git a/src/shared/components/FilesCarousel/AllFilesCarousel/AllFilesCarousel.tsx b/src/shared/components/FilesCarousel/AllFilesCarousel/AllFilesCarousel.tsx index 848144770..8b032dc89 100644 --- a/src/shared/components/FilesCarousel/AllFilesCarousel/AllFilesCarousel.tsx +++ b/src/shared/components/FilesCarousel/AllFilesCarousel/AllFilesCarousel.tsx @@ -9,14 +9,14 @@ import React, { ForwardRefRenderFunction, } from "react"; import classNames from "classnames"; -import throttle from "lodash-es/throttle"; import { Swiper, SwiperSlide } from "swiper/react"; import SwiperClass from "swiper/types/swiper-class"; +import throttle from "lodash/throttle"; import DownloadIcon from "../../../icons/download.icon"; import LeftArrowIcon from "../../../icons/leftArrow.icon"; import RightArrowIcon from "../../../icons/rightArrow.icon"; -import { DocInfo } from "../../../models"; import { saveZip } from "../../../utils"; +import { DocInfo } from "../../../models"; import { ButtonIcon } from "../../ButtonIcon"; import { InvoiceTile } from "../../InvoiceTile"; import { getSwiperConfig } from "./helpers"; @@ -45,8 +45,10 @@ const AllFilesCarousel: ForwardRefRenderFunction< initialDocIndex, onDocClick, } = props; - const [swiperWrapperRef, setSwiperWrapperRef] = - useState(null); + const [ + swiperWrapperRef, + setSwiperWrapperRef, + ] = useState(null); const [{ isBeginning, isEnd }, setSlideState] = useState<{ isBeginning: boolean; isEnd: boolean; @@ -57,7 +59,7 @@ const AllFilesCarousel: ForwardRefRenderFunction< const swiperClientWidth = swiperWrapperRef?.clientWidth || 0; const swiperConfig = useMemo( () => getSwiperConfig(payoutDocs.length, swiperClientWidth), - [payoutDocs.length, swiperClientWidth], + [payoutDocs.length, swiperClientWidth] ); const handleSlideChange = useCallback( @@ -68,17 +70,17 @@ const AllFilesCarousel: ForwardRefRenderFunction< : { isBeginning, isEnd, - }, + } ); }, - [], + [] ); const handleSwiper = useCallback( (swiper: SwiperClass) => { swiperRef.current = swiper; handleSlideChange(swiper); }, - [handleSlideChange], + [handleSlideChange] ); const handleLeftClick = () => { @@ -129,14 +131,14 @@ const AllFilesCarousel: ForwardRefRenderFunction< swiperRef.current?.slideTo(index); }, }), - [], + [] ); const contentWrapperClassName = classNames( "all-files-carousel-wrapper__content-wrapper", { "all-files-carousel-wrapper__content-wrapper--without-actions": false, - }, + } ); return ( @@ -157,8 +159,7 @@ const AllFilesCarousel: ForwardRefRenderFunction<
    Date: Mon, 19 Aug 2024 11:15:17 +0300 Subject: [PATCH 35/36] CW-mobile-performance fixed new stream issue --- src/pages/commonFeed/CommonFeed.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/commonFeed/CommonFeed.tsx b/src/pages/commonFeed/CommonFeed.tsx index b9e341b8a..f578d5d96 100644 --- a/src/pages/commonFeed/CommonFeed.tsx +++ b/src/pages/commonFeed/CommonFeed.tsx @@ -531,7 +531,7 @@ const CommonFeedComponent: FC = (props) => { } }, [commonAction]); - const FeedLayoutTopContent = useCallback(() => { + const FeedLayoutTopContent = useMemo(() => { if (!commonData) { return null; } From 14132c41f49db90e8f60c3dffdbec41aa77a23df Mon Sep 17 00:00:00 2001 From: Pavel Meyer Date: Wed, 28 Aug 2024 16:44:29 +0300 Subject: [PATCH 36/36] CW-fix-tree-icons Added condition for empty Tree spaces icons --- .../TreeItemTriggerContent.module.scss | 1 + .../TreeItemTriggerContent.tsx | 85 ++++++++++--------- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.module.scss b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.module.scss index 9cb218cf6..c25d08ebb 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.module.scss +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.module.scss @@ -2,6 +2,7 @@ .arrowIconButton { padding: 0.75rem 1.25rem 0.75rem var(--item-arrow-pl); + width: 2.25rem; } .arrowIconButtonHidden { visibility: hidden; diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.tsx b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.tsx index 743c24f1c..e1ee61b4c 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.tsx +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/ProjectsTree/components/TreeItemTriggerContent/TreeItemTriggerContent.tsx @@ -14,56 +14,61 @@ interface TreeItemTriggerContentProps { isActive: boolean; isOpen: boolean; onToggle?: () => void; - handleToggle: (event: React.MouseEvent) => void; + handleToggle: ( + event: React.MouseEvent, + ) => void; } const TreeItemTriggerContent: FC = (props) => { - const { treeItemTriggerStyles, item, level, isOpen, handleToggle, onToggle } = props; + const { treeItemTriggerStyles, item, level, isOpen, handleToggle, onToggle } = + props; return ( <> - - - + onClick={handleToggle} + aria-label={`${isOpen ? "Hide" : "Show"} ${item.name}'s spaces`} + aria-hidden={!onToggle} + > + {item.items && item.items?.length > 0 && ( + + )} + - + - - {item.name} - - {item.nameRightContent} - {item.rightContent} - {!!item.notificationsAmount && ( - - {item.notificationsAmount} + + {item.name} - )} - + {item.nameRightContent} + {item.rightContent} + {!!item.notificationsAmount && ( + + {item.notificationsAmount} + + )} + ); };