diff --git a/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx b/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx index 913a2b3e48..ded2585fa8 100644 --- a/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx +++ b/src/pages/OldCommon/components/CommonDetailContainer/MembersComponent/CommonMemberComponent.tsx @@ -45,7 +45,7 @@ const CommonMember: FC = ({ const { isShowing, onClose, onOpen } = useModal(false); const contextMenuRef = useRef(null); const recentAssignedCircle: Circle | undefined = useSelector( - selectRecentAssignedCircle(member.userId), + selectRecentAssignedCircle(commonId, member.userId), ); const handleContextMenu: MouseEventHandler = (event) => { diff --git a/src/pages/common/BaseCommon.tsx b/src/pages/common/BaseCommon.tsx index f49bdce588..dcef1e18c1 100644 --- a/src/pages/common/BaseCommon.tsx +++ b/src/pages/common/BaseCommon.tsx @@ -79,12 +79,17 @@ const BaseCommon: FC = (props) => { }, [userId]); useEffect(() => { - dispatch(setCommonMember(commonMember || null)); + dispatch(setCommonMember({ commonId, member: commonMember || null })); onCommonMemberChange?.(commonMember || null); }, [dispatch, commonMember]); useEffect(() => { - dispatch(setCommonGovernance(commonData?.governance || null)); + dispatch( + setCommonGovernance({ + commonId, + governance: commonData?.governance || null, + }), + ); }, [dispatch, commonData?.governance]); useEffect(() => { diff --git a/src/pages/common/components/ChatComponent/ChatComponent.tsx b/src/pages/common/components/ChatComponent/ChatComponent.tsx index c7350bd0b1..8fd09ccdd1 100644 --- a/src/pages/common/components/ChatComponent/ChatComponent.tsx +++ b/src/pages/common/components/ChatComponent/ChatComponent.tsx @@ -54,6 +54,7 @@ import { removeTextEditorEmptyEndLinesValues, countTextEditorEmojiElements, } from "@/shared/ui-kit"; +import { BaseTextEditorHandles } from "@/shared/ui-kit/TextEditor/BaseTextEditor"; import { checkUncheckedItemsInTextEditorValue } from "@/shared/ui-kit/TextEditor/utils"; import { InternalLinkData, notEmpty } from "@/shared/utils"; import { getUserName, hasPermission, isMobile } from "@/shared/utils"; @@ -70,6 +71,7 @@ import { selectInstantDiscussionMessagesOrder, } from "@/store/states"; import { ChatContentContext, ChatContentData } from "../CommonContent/context"; +import { useFeedItemContext } from "../FeedItem"; import { ChatContent, ChatContentRef, @@ -87,8 +89,6 @@ import { uploadFilesAndImages, } from "./utils"; import styles from "./ChatComponent.module.scss"; -import { BaseTextEditorHandles } from "@/shared/ui-kit/TextEditor/BaseTextEditor"; -import { useFeedItemContext } from "../FeedItem"; const BASE_CHAT_INPUT_HEIGHT = 48; const BASE_ORDER_INTERVAL = 1000; @@ -259,19 +259,16 @@ export default function ChatComponent({ parseStringToTextEditorValue(), ); - const { - setIsInputFocused - } = useFeedItemContext(); + const { setIsInputFocused } = useFeedItemContext(); useEffect(() => { const isEmpty = checkIsTextEditorValueEmpty(message); - if(!isEmpty || message.length > 1) { + if (!isEmpty || message.length > 1) { setIsInputFocused?.(true); } else { setIsInputFocused?.(false); } - - },[message, setIsInputFocused]) + }, [message, setIsInputFocused]); const emojiCount = useMemo( () => countTextEditorEmojiElements(message), @@ -294,9 +291,12 @@ export default function ChatComponent({ const optimisticDiscussionMessages = useSelector( selectOptimisticDiscussionMessages, ); - const instantDiscussionMessagesOrder = useSelector(selectInstantDiscussionMessagesOrder); + const instantDiscussionMessagesOrder = useSelector( + selectInstantDiscussionMessagesOrder, + ); - const currentChatOrder = instantDiscussionMessagesOrder.get(discussionId)?.order || 1; + const currentChatOrder = + instantDiscussionMessagesOrder.get(discussionId)?.order || 1; const isOptimisticChat = optimisticFeedItems.has(discussionId); @@ -604,7 +604,11 @@ export default function ChatComponent({ return [...prev, ...filePreviewPayload, payload]; }); - dispatch(optimisticActions.setInstantDiscussionMessagesOrder({discussionId})); + dispatch( + optimisticActions.setInstantDiscussionMessagesOrder({ + discussionId, + }), + ); } if (isChatChannel) { @@ -638,10 +642,15 @@ export default function ChatComponent({ userName: getUserName(user), ownerType: DiscussionMessageOwnerType.User, content: JSON.stringify(message), - } + }, }; - dispatch(commonActions.setFeedItemUpdatedAt(payloadUpdateFeedItem)); + dispatch( + commonActions.setFeedItemUpdatedAt({ + ...payloadUpdateFeedItem, + commonId, + }), + ); dispatch(inboxActions.setInboxItemUpdatedAt(payloadUpdateFeedItem)); document .getElementById("feedLayoutWrapper") @@ -765,7 +774,7 @@ export default function ChatComponent({ useLayoutEffect(() => { textInputRef?.current?.clear?.(); textInputRef?.current?.focus?.(); - },[discussionId]); + }, [discussionId]); useEffect(() => { if (isFetchedDiscussionMessages) { diff --git a/src/pages/common/components/CommonContent/CommonContent.tsx b/src/pages/common/components/CommonContent/CommonContent.tsx index 7d43469123..b641e697ca 100644 --- a/src/pages/common/components/CommonContent/CommonContent.tsx +++ b/src/pages/common/components/CommonContent/CommonContent.tsx @@ -1,5 +1,5 @@ import React, { FC, useEffect, useMemo, useState } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useSelector } from "react-redux"; import { useHistory } from "react-router-dom"; import { CommonPageSettings } from "@/pages/common/types"; import { useRoutesContext } from "@/shared/contexts"; @@ -16,7 +16,7 @@ import { } from "@/shared/models"; import { Container } from "@/shared/ui-kit"; import { getInboxPagePath } from "@/shared/utils"; -import { commonActions, selectIsNewProjectCreated } from "@/store/states"; +import { selectIsNewProjectCreated } from "@/store/states"; import { CommonDataProvider } from "../../providers"; import { CommonHeader } from "../CommonHeader"; import { CommonManagement } from "../CommonManagement"; @@ -67,7 +67,6 @@ const CommonContent: FC = (props) => { setIsJoinPending, } = props; const isTabletView = useIsTabletView(); - const dispatch = useDispatch(); const history = useHistory(); const { canGoBack, goBack } = useGoBack(); const { getCommonPagePath } = useRoutesContext(); @@ -86,7 +85,9 @@ const CommonContent: FC = (props) => { allowedTabs, }), ); - const isNewProjectCreated = useSelector(selectIsNewProjectCreated); + + const commonId = common.id; + const isNewProjectCreated = useSelector(selectIsNewProjectCreated(commonId)); const parentCommonId = common.directParent?.commonId; const isSubCommon = common.directParent !== null; @@ -108,12 +109,6 @@ const CommonContent: FC = (props) => { } }, [isCommonMember, common.listVisibility, history.push, goBack, canGoBack]); - useEffect(() => { - return () => { - dispatch(commonActions.resetCommon()); - }; - }, []); - return ( = (props) => { commonMember={commonMember} circles={governance.circles} isSubCommon={isSubCommon} - commonId={common.id} + commonId={commonId} /> = (props) => { settings.renderHeaderContent() ) : !isTabletView ? ( ) : null @@ -168,7 +163,7 @@ const CommonContent: FC = (props) => { {!isTabletView && ( = (props) => { {isGlobalDataFetched && isNewProjectCreated && parentCommonId && ( - + )} ); diff --git a/src/pages/common/components/CommonContent/components/SuccessfulProjectCreationModal/SuccessfulProjectCreationModal.tsx b/src/pages/common/components/CommonContent/components/SuccessfulProjectCreationModal/SuccessfulProjectCreationModal.tsx index 478c5613ba..6decb75bf7 100644 --- a/src/pages/common/components/CommonContent/components/SuccessfulProjectCreationModal/SuccessfulProjectCreationModal.tsx +++ b/src/pages/common/components/CommonContent/components/SuccessfulProjectCreationModal/SuccessfulProjectCreationModal.tsx @@ -9,22 +9,27 @@ import styles from "./SuccessfulProjectCreationModal.module.scss"; interface SuccessfulProjectCreationModalProps { parentCommonId: string; + commonId: string; } const SuccessfulProjectCreationModal: FC< SuccessfulProjectCreationModalProps > = (props) => { - const { parentCommonId } = props; + const { parentCommonId, commonId } = props; const dispatch = useDispatch(); const history = useHistory(); const handleClose = () => { - dispatch(commonActions.setIsNewProjectCreated(false)); + dispatch( + commonActions.setIsNewProjectCreated({ isCreated: false, commonId }), + ); history.push(getCommonPageAboutTabPath(parentCommonId)); }; const handleJumpToProject = () => { - dispatch(commonActions.setIsNewProjectCreated(false)); + dispatch( + commonActions.setIsNewProjectCreated({ isCreated: false, commonId }), + ); }; return ( diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/FeedTab.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/FeedTab.tsx index ddc2b5404a..12fbea531a 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/FeedTab.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/FeedTab.tsx @@ -179,14 +179,10 @@ export const FeedTab: FC = (props) => { useEffect(() => { return () => { - dispatch( - commonActions.getFeedItems.cancel( - "Cancel feed items fetch on feed umount", - ), - ); - dispatch(commonActions.resetFeedItems()); + dispatch(commonActions.getFeedItems.cancel({ commonId: common.id })); + dispatch(commonActions.resetFeedItems({ commonId: common.id })); }; - }, []); + }, [common.id]); const contextValue = useMemo( () => ({ diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/NewDiscussionCreation.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/NewDiscussionCreation.tsx index d70e1ee08b..ab71548ccf 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/NewDiscussionCreation.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/NewDiscussionCreation.tsx @@ -2,6 +2,7 @@ import React, { FC, useCallback, useEffect, useMemo } from "react"; import { useDispatch, useSelector } from "react-redux"; import { v4 as uuidv4 } from "uuid"; import { selectUser } from "@/pages/Auth/store/selectors"; +import { DiscussionMessageOwnerType } from "@/shared/constants"; import { NewDiscussionCreationFormValues, UploadFile, @@ -18,7 +19,11 @@ import { TextEditorValue, parseStringToTextEditorValue, } from "@/shared/ui-kit/TextEditor"; -import { generateFirstMessage, generateOptimisticFeedItem, getUserName } from "@/shared/utils"; +import { + generateFirstMessage, + generateOptimisticFeedItem, + getUserName, +} from "@/shared/utils"; import { optimisticActions, selectDiscussionCreationData, @@ -26,7 +31,6 @@ import { } from "@/store/states"; import { commonActions } from "@/store/states"; import { DiscussionCreationCard, DiscussionCreationModal } from "./components"; -import { DiscussionMessageOwnerType } from "@/shared/constants"; interface NewDiscussionCreationProps { common: Common; @@ -60,8 +64,12 @@ const NewDiscussionCreation: FC = (props) => { onDiscussionIdChange, } = props; const dispatch = useDispatch(); - const discussionCreationData = useSelector(selectDiscussionCreationData); - const isLoading = useSelector(selectIsDiscussionCreationLoading); + + const commonId = common.id; + const discussionCreationData = useSelector( + selectDiscussionCreationData(commonId), + ); + const isLoading = useSelector(selectIsDiscussionCreationLoading(commonId)); const user = useSelector(selectUser()); const userId = user?.uid; const userCircleIds = useMemo( @@ -71,7 +79,7 @@ const NewDiscussionCreation: FC = (props) => { const handleCancel = () => { dispatch(commonActions.setCommonAction(null)); - dispatch(commonActions.setDiscussionCreationData(null)); + dispatch(commonActions.setDiscussionCreationData({ data: null, commonId })); }; const initialValues: NewDiscussionCreationFormValues = useMemo(() => { @@ -118,6 +126,7 @@ const NewDiscussionCreation: FC = (props) => { message: JSON.stringify(values.content), images: values.images, }, + commonId, }), ); } else { @@ -136,13 +145,15 @@ const NewDiscussionCreation: FC = (props) => { ownerId: userId, userName, ownerType: DiscussionMessageOwnerType.System, - content: generateFirstMessage({userName, userId}), - } + content: generateFirstMessage({ userName, userId }), + }, }); - dispatch(optimisticActions.setOptimisticFeedItem({ - data: optimisticFeedItem, - common - })); + dispatch( + optimisticActions.setOptimisticFeedItem({ + data: optimisticFeedItem, + common, + }), + ); dispatch(commonActions.setRecentStreamId(optimisticFeedItem.data.id)); dispatch( commonActions.createDiscussion.request({ @@ -155,13 +166,14 @@ const NewDiscussionCreation: FC = (props) => { images: values.images, circleVisibility, }, + commonId, }), ); } handleCancel(); }, - [governanceCircles, userCircleIds, userId, common.id, edit], + [governanceCircles, userCircleIds, userId, commonId, edit], ); useEffect(() => { @@ -185,6 +197,7 @@ const NewDiscussionCreation: FC = (props) => { isLoading={isLoading} commonImage={commonImage} commonName={commonName} + commonId={commonId} edit={edit} /> ); @@ -199,6 +212,7 @@ const NewDiscussionCreation: FC = (props) => { onCancel={handleCancel} isLoading={isLoading} edit={edit} + commonId={commonId} /> ); }; diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationCard/DiscussionCreationCard.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationCard/DiscussionCreationCard.tsx index 1eb3b46319..39a4dbd657 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationCard/DiscussionCreationCard.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationCard/DiscussionCreationCard.tsx @@ -14,6 +14,7 @@ interface DiscussionCreationCardProps { onCancel?: () => void; isLoading?: boolean; edit?: boolean; + commonId: string; } const DiscussionCreationCard: FC = (props) => { @@ -25,6 +26,7 @@ const DiscussionCreationCard: FC = (props) => { onCancel, isLoading = false, edit, + commonId, } = props; return ( @@ -37,6 +39,7 @@ const DiscussionCreationCard: FC = (props) => { onCancel={onCancel} isLoading={isLoading} edit={edit} + commonId={commonId} /> ); diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationForm/DiscussionCreationForm.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationForm/DiscussionCreationForm.tsx index 217628a9ed..adc4533a10 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationForm/DiscussionCreationForm.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationForm/DiscussionCreationForm.tsx @@ -28,6 +28,7 @@ interface DiscussionCreationFormProps { isLoading?: boolean; styles?: Styles; edit?: boolean; + commonId: string; } const DiscussionCreationForm: FC = (props) => { @@ -41,6 +42,7 @@ const DiscussionCreationForm: FC = (props) => { isLoading = false, styles: outerStyles, edit, + commonId, } = props; const disabled = isLoading; @@ -94,7 +96,7 @@ const DiscussionCreationForm: FC = (props) => { - + )} diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationModal/DiscussionCreationModal.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationModal/DiscussionCreationModal.tsx index ee1e99f66b..2bc2ce86dd 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationModal/DiscussionCreationModal.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewDiscussionCreation/components/DiscussionCreationModal/DiscussionCreationModal.tsx @@ -16,6 +16,7 @@ interface DiscussionCreationModalProps { isLoading?: boolean; commonImage: string; commonName: string; + commonId: string; edit?: boolean; } @@ -30,6 +31,7 @@ const DiscussionCreationModal: FC = (props) => { commonImage, commonName, edit, + commonId, } = props; return ( @@ -53,6 +55,7 @@ const DiscussionCreationModal: FC = (props) => { buttonsWrapper: styles.buttonsWrapper, }} edit={edit} + commonId={commonId} /> ); 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 b04e921852..ce39afb8db 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 @@ -5,14 +5,22 @@ import debounce from "lodash/debounce"; import { NewDiscussionCreationFormValues } from "@/shared/interfaces"; import { commonActions } from "@/store/states"; -const DiscussionFormPersist: FC = () => { +interface DiscussionFormPersistProps { + commonId: string; +} + +const DiscussionFormPersist: FC = ({ + commonId, +}) => { const dispatch = useDispatch(); const { values } = useFormikContext(); const handleUpdate = useMemo( () => debounce((values: NewDiscussionCreationFormValues) => { - dispatch(commonActions.setDiscussionCreationData(values)); + dispatch( + commonActions.setDiscussionCreationData({ data: values, commonId }), + ); }, 400), [], ); diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/NewProposalCreation.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/NewProposalCreation.tsx index 06ba04f3a6..1d2fd00e3d 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/NewProposalCreation.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/NewProposalCreation.tsx @@ -16,7 +16,11 @@ import { Governance, } from "@/shared/models"; import { parseStringToTextEditorValue } from "@/shared/ui-kit/TextEditor"; -import { generateFirstMessage, generateOptimisticFeedItem, getUserName } from "@/shared/utils"; +import { + generateFirstMessage, + generateOptimisticFeedItem, + getUserName, +} from "@/shared/utils"; import { optimisticActions, selectIsProposalCreationLoading, @@ -61,11 +65,14 @@ const NewProposalCreation: FC = (props) => { isModalVariant = false, } = props; const dispatch = useDispatch(); - const proposalCreationData = useSelector(selectProposalCreationData); - const isLoading = useSelector(selectIsProposalCreationLoading); + + const commonId = common.id; + const proposalCreationData = useSelector( + selectProposalCreationData(commonId), + ); + const isLoading = useSelector(selectIsProposalCreationLoading(commonId)); const user = useSelector(selectUser()); const userId = user?.uid; - const commonId = common.id; const initialValues = useMemo( () => proposalCreationData || INITIAL_VALUES, [], @@ -78,7 +85,7 @@ const NewProposalCreation: FC = (props) => { const handleCancel = () => { dispatch(commonActions.setCommonAction(null)); - dispatch(commonActions.setProposalCreationData(null)); + dispatch(commonActions.setProposalCreationData({ data: null, commonId })); }; const handleSubmit = useCallback( @@ -103,14 +110,16 @@ const NewProposalCreation: FC = (props) => { ownerId: userId, userName, ownerType: DiscussionMessageOwnerType.System, - content: generateFirstMessage({userName, userId}), - } + content: generateFirstMessage({ userName, userId }), + }, }); - dispatch(optimisticActions.setOptimisticFeedItem({ - data: optimisticFeedItem, - common - })); + dispatch( + optimisticActions.setOptimisticFeedItem({ + data: optimisticFeedItem, + common, + }), + ); dispatch(commonActions.setRecentStreamId(optimisticFeedItem.data.id)); switch (values.proposalType.value) { case ProposalsTypes.FUNDS_ALLOCATION: { @@ -128,6 +137,7 @@ const NewProposalCreation: FC = (props) => { dispatch( commonActions.createFundingProposal.request({ payload: fundingProposalPayload, + commonId, }), ); break; @@ -141,6 +151,7 @@ const NewProposalCreation: FC = (props) => { proposalId, discussionId, ), + commonId, }), ); break; diff --git a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalCreationForm/ProposalCreationForm.tsx b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalCreationForm/ProposalCreationForm.tsx index 9484b7bd6b..d1ab57c2b5 100644 --- a/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalCreationForm/ProposalCreationForm.tsx +++ b/src/pages/common/components/CommonTabPanels/components/FeedTab/components/NewProposalCreation/components/ProposalCreationForm/ProposalCreationForm.tsx @@ -46,7 +46,9 @@ const ProposalCreationForm: FC = (props) => { commonBalance, } = props; const disabled = isLoading; - const creationData = useSelector(selectProposalCreationData); + const creationData = useSelector( + selectProposalCreationData(governance.commonId), + ); return ( = (props) => { - + )} 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 5b69531cd2..656a6ef58d 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 @@ -5,14 +5,20 @@ import debounce from "lodash/debounce"; import { NewProposalCreationFormValues } from "@/shared/interfaces"; import { commonActions } from "@/store/states"; -const ProposalFormPersist: FC = () => { +interface ProposalFormPersistProps { + commonId: string; +} + +const ProposalFormPersist: FC = ({ commonId }) => { const dispatch = useDispatch(); const { values } = useFormikContext(); const handleUpdate = useMemo( () => debounce((values: NewProposalCreationFormValues) => { - dispatch(commonActions.setProposalCreationData(values)); + dispatch( + commonActions.setProposalCreationData({ data: values, commonId }), + ); }, 400), [], ); diff --git a/src/pages/common/components/CommonTabPanels/components/MembersTab/components/MemberDropdown/AssignCircleModal.tsx b/src/pages/common/components/CommonTabPanels/components/MembersTab/components/MemberDropdown/AssignCircleModal.tsx index 245fd434db..3edc5127c7 100644 --- a/src/pages/common/components/CommonTabPanels/components/MembersTab/components/MemberDropdown/AssignCircleModal.tsx +++ b/src/pages/common/components/CommonTabPanels/components/MembersTab/components/MemberDropdown/AssignCircleModal.tsx @@ -43,6 +43,7 @@ export default function AssignCircleModal({ commonActions.setRecentAssignedCircleByMember({ memberId, circle: selectedCircle, + commonId, }), ); diff --git a/src/pages/common/components/CommonTabPanels/components/MembersTab/components/MembersList/MembersList.tsx b/src/pages/common/components/CommonTabPanels/components/MembersTab/components/MembersList/MembersList.tsx index 7842187785..58f8ee2f89 100644 --- a/src/pages/common/components/CommonTabPanels/components/MembersTab/components/MembersList/MembersList.tsx +++ b/src/pages/common/components/CommonTabPanels/components/MembersTab/components/MembersList/MembersList.tsx @@ -38,7 +38,7 @@ const MembersList: FC = ({ useEffect(() => { return () => { - dispatch(commonActions.resetRecentAssignedCircleByMember()); + dispatch(commonActions.resetRecentAssignedCircleByMember({ commonId })); }; }, []); diff --git a/src/pages/common/components/DiscussionFeedCard/hooks/useMenuItems.tsx b/src/pages/common/components/DiscussionFeedCard/hooks/useMenuItems.tsx index 3fe3c6ef21..b9142ecaba 100644 --- a/src/pages/common/components/DiscussionFeedCard/hooks/useMenuItems.tsx +++ b/src/pages/common/components/DiscussionFeedCard/hooks/useMenuItems.tsx @@ -59,7 +59,7 @@ export const useMenuItems = ( feedItem, feedItemFollow, feedItemUserMetadata, - shareText + shareText, } = options; const { report, @@ -160,11 +160,14 @@ export const useMenuItems = ( dispatch( commonActions.setDiscussionCreationData({ - circle: circles[0] || null, - title: discussion.title, - content: parseStringToTextEditorValue(discussion.message), - images: files, - id: discussion.id, + commonId: commonId ?? "", + data: { + circle: circles[0] || null, + title: discussion.title, + content: parseStringToTextEditorValue(discussion.message), + images: files, + id: discussion.id, + }, }), ); dispatch(commonActions.setCommonAction(CommonAction.EditDiscussion)); diff --git a/src/pages/commonCreation/components/ProjectCreation/ProjectCreation.tsx b/src/pages/commonCreation/components/ProjectCreation/ProjectCreation.tsx index e1879af730..450b7f7298 100644 --- a/src/pages/commonCreation/components/ProjectCreation/ProjectCreation.tsx +++ b/src/pages/commonCreation/components/ProjectCreation/ProjectCreation.tsx @@ -95,7 +95,12 @@ const ProjectCreation: FC = (props) => { notificationsAmount: 0, }; - dispatch(commonActions.setIsNewProjectCreated(true)); + dispatch( + commonActions.setIsNewProjectCreated({ + isCreated: true, + commonId: createdProject.id, + }), + ); CommonEventEmitter.emit( CommonEvent.ProjectCreatedOrUpdated, projectsStateItem, diff --git a/src/pages/commonFeed/CommonFeed.tsx b/src/pages/commonFeed/CommonFeed.tsx index de5643757b..282a4b60ad 100644 --- a/src/pages/commonFeed/CommonFeed.tsx +++ b/src/pages/commonFeed/CommonFeed.tsx @@ -104,8 +104,10 @@ const CommonFeedComponent: FC = (props) => { const user = useSelector(selectUser()); const userId = user?.uid; const recentStreamId = useSelector(selectRecentStreamId); - const isSearchingFeedItems = useSelector(selectIsSearchingFeedItems); - const searchValue = useSelector(selectFeedSearchValue); + const isSearchingFeedItems = useSelector( + selectIsSearchingFeedItems(commonId), + ); + const searchValue = useSelector(selectFeedSearchValue(commonId)); const [feedLayoutRef, setFeedLayoutRef] = useState( null, ); @@ -116,7 +118,9 @@ const CommonFeedComponent: FC = (props) => { sharedFeedItemIdQueryParam) || null; const commonAction = useSelector(selectCommonAction); - const createdOptimisticFeedItems = useSelector(selectCreatedOptimisticFeedItems); + const createdOptimisticFeedItems = useSelector( + selectCreatedOptimisticFeedItems, + ); const optimisticFeedItems = useSelector(selectOptimisticFeedItems); const { data: commonData, @@ -207,7 +211,7 @@ const CommonFeedComponent: FC = (props) => { commonData?.governance, ); - const sharedFeedItem = useSelector(selectSharedFeedItem); + const sharedFeedItem = useSelector(selectSharedFeedItem(commonId)); const topFeedItemsWithoutOptimistic = useMemo(() => { const items: FeedLayoutItem[] = []; const filteredPinnedItems = @@ -273,6 +277,7 @@ const CommonFeedComponent: FC = (props) => { commonActions.updateFeedItem({ item, isRemoved, + commonId, }), ); @@ -282,7 +287,7 @@ const CommonFeedComponent: FC = (props) => { ?.scrollIntoView({ behavior: "smooth" }); } }, - [dispatch], + [dispatch, commonId], ); const scrollToItemsTop = () => { @@ -393,7 +398,7 @@ const CommonFeedComponent: FC = (props) => { const onPullToRefresh = useCallback(() => { dispatch(cacheActions.clearFeedStateByCommonId(commonId)); - dispatch(commonActions.resetFeedItems()); + dispatch(commonActions.resetFeedItems({ commonId })); }, [dispatch, commonId]); useEffect(() => { @@ -418,7 +423,7 @@ const CommonFeedComponent: FC = (props) => { ]); useEffect(() => { - dispatch(commonActions.setSharedFeedItemId(sharedFeedItemId)); + dispatch(commonActions.setSharedFeedItemId({ sharedFeedItemId, commonId })); if (sharedFeedItemId) { feedLayoutRef?.setExpandedFeedItemId(sharedFeedItemId); @@ -427,7 +432,12 @@ const CommonFeedComponent: FC = (props) => { useEffect(() => { if (commonData?.sharedFeedItem) { - dispatch(commonActions.setSharedFeedItem(commonData.sharedFeedItem)); + dispatch( + commonActions.setSharedFeedItem({ + feedItem: commonData.sharedFeedItem, + commonId, + }), + ); } }, [commonData?.sharedFeedItem]); @@ -441,7 +451,6 @@ const CommonFeedComponent: FC = (props) => { return () => { clearInterval(interval); dispatch(cacheActions.copyFeedStateByCommonId(commonId)); - dispatch(commonActions.resetCommon()); }; }, [commonId]); @@ -468,7 +477,9 @@ const CommonFeedComponent: FC = (props) => { ) { feedLayoutRef?.setActiveItem({ feedItemId: firstItem.feedItem.id, - discussion: createdOptimisticFeedItems.get(recentStreamId)?.feedItem.optimisticData + discussion: + createdOptimisticFeedItems.get(recentStreamId)?.feedItem + .optimisticData, }); dispatch(commonActions.setRecentStreamId("")); } else if ( @@ -477,10 +488,11 @@ const CommonFeedComponent: FC = (props) => { ) { feedLayoutRef?.setActiveItem({ feedItemId: optimisticFeedItems.get(recentStreamId)!.feedItem.id, - discussion: optimisticFeedItems.get(recentStreamId)?.feedItem.optimisticData, + discussion: + optimisticFeedItems.get(recentStreamId)?.feedItem.optimisticData, }); } - }, [feedLayoutRef, recentStreamId, firstItem, optimisticFeedItems]); + }, [feedLayoutRef, recentStreamId, firstItem, optimisticFeedItems, commonId]); useEffect(() => { const handler: CommonEventToListener[CommonEvent.CommonDeleted] = ( diff --git a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx index 91f55aafef..0ce7b452eb 100644 --- a/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx +++ b/src/pages/commonFeed/components/FeedLayout/FeedLayout.tsx @@ -44,7 +44,11 @@ import { ROUTE_PATHS, } from "@/shared/constants"; import { useRoutesContext } from "@/shared/contexts"; -import { useElementPresence, useMemoizedFunction, useQueryParams } from "@/shared/hooks"; +import { + useElementPresence, + useMemoizedFunction, + useQueryParams, +} from "@/shared/hooks"; import { useGovernanceByCommonId } from "@/shared/hooks/useCases"; import { useDisableOverscroll } from "@/shared/hooks/useDisableOverscroll"; import { useIsTabletView } from "@/shared/hooks/viewport"; @@ -75,7 +79,10 @@ import { getParamsFromOneOfRoutes, getUserName, } from "@/shared/utils"; -import { selectCreatedOptimisticFeedItems, selectRecentStreamId } from "@/store/states"; +import { + selectCreatedOptimisticFeedItems, + selectRecentStreamId, +} from "@/store/states"; import { MIN_CONTENT_WIDTH } from "../../constants"; import { DesktopChat, @@ -200,7 +207,9 @@ const FeedLayout: ForwardRefRenderFunction = ( const queryParams = useQueryParams(); const isTabletView = useIsTabletView(); const user = useSelector(selectUser()); - const createdOptimisticFeedItems = useSelector(selectCreatedOptimisticFeedItems); + const createdOptimisticFeedItems = useSelector( + selectCreatedOptimisticFeedItems, + ); const recentStreamId = useSelector(selectRecentStreamId); const userId = user?.uid; const [chatItem, setChatItem] = useState(); @@ -282,6 +291,7 @@ const FeedLayout: ForwardRefRenderFunction = ( if (topFeedItems) { items.push(...topFeedItems); } + if (feedItems) { items.push(...feedItems); } @@ -354,7 +364,10 @@ const FeedLayout: ForwardRefRenderFunction = ( const activeFeedItemId = chatItem?.feedItemId || feedItemIdForAutoChatOpen; const sizeKey = `${windowWidth}_${contentWidth}`; - const activeFeedItemIndex = useMemo(() => allFeedItems.findIndex((item) => item.itemId === activeFeedItemId), [activeFeedItemId, allFeedItems]); + const activeFeedItemIndex = useMemo( + () => allFeedItems.findIndex((item) => item.itemId === activeFeedItemId), + [activeFeedItemId, allFeedItems], + ); const getUserCircleIds = useCallback( (commonId) => { @@ -408,48 +421,77 @@ const FeedLayout: ForwardRefRenderFunction = ( setChatItem(nextChatItem); }, []); - const isMentionOpen = useElementPresence(MENTION_TAG_ELEMENT.key, MENTION_TAG_ELEMENT.value); + const isMentionOpen = useElementPresence( + MENTION_TAG_ELEMENT.key, + MENTION_TAG_ELEMENT.value, + ); const [isInputFocused, setIsInputFocused] = useState(false); - const handleArrowUp = (event, activeFeedItemIndex, allFeedItems, isMentionOpen, setChatItem) => { + const handleArrowUp = ( + event, + activeFeedItemIndex, + allFeedItems, + isMentionOpen, + setChatItem, + ) => { if (!isMentionOpen && !isInputFocused) { event.preventDefault(); event.stopPropagation(); - + if (activeFeedItemIndex > 0) { const nextFeedItemId = allFeedItems[activeFeedItemIndex - 1]?.itemId; - + setChatItem({ feedItemId: nextFeedItemId }); } } }; - - const handleArrowDown = (event, activeFeedItemIndex, allFeedItems, isMentionOpen, setChatItem) => { + + const handleArrowDown = ( + event, + activeFeedItemIndex, + allFeedItems, + isMentionOpen, + setChatItem, + ) => { if (!isMentionOpen && !isInputFocused) { event.preventDefault(); event.stopPropagation(); - + if (activeFeedItemIndex < allFeedItems.length - 1) { const nextFeedItemId = allFeedItems[activeFeedItemIndex + 1]?.itemId; - + setChatItem({ feedItemId: nextFeedItemId }); } } }; - + // Inside your component useKey( "ArrowUp", - (event) => handleArrowUp(event, activeFeedItemIndex, allFeedItems, isMentionOpen, setChatItem), + (event) => + handleArrowUp( + event, + activeFeedItemIndex, + allFeedItems, + isMentionOpen, + setChatItem, + ), {}, - [activeFeedItemIndex, allFeedItems, isMentionOpen, isInputFocused] + [activeFeedItemIndex, allFeedItems, isMentionOpen, isInputFocused], ); - + useKey( "ArrowDown", - (event) => handleArrowDown(event, activeFeedItemIndex, allFeedItems, isMentionOpen, setChatItem), + (event) => + handleArrowDown( + event, + activeFeedItemIndex, + allFeedItems, + isMentionOpen, + setChatItem, + ), {}, - [activeFeedItemIndex, allFeedItems, isMentionOpen, isInputFocused] + [activeFeedItemIndex, allFeedItems, isMentionOpen, isInputFocused], ); const chatContextValue = useMemo( @@ -763,7 +805,7 @@ const FeedLayout: ForwardRefRenderFunction = ( return; } - if(!recentStreamId) { + if (!recentStreamId) { setActiveChatItem(null); } @@ -913,7 +955,9 @@ const FeedLayout: ForwardRefRenderFunction = ( = ( ); }; -export default forwardRef(FeedLayout); \ No newline at end of file +export default forwardRef(FeedLayout); diff --git a/src/pages/commonFeed/components/HeaderContent/HeaderContent.tsx b/src/pages/commonFeed/components/HeaderContent/HeaderContent.tsx index 6982fa8eea..0141f20c09 100644 --- a/src/pages/commonFeed/components/HeaderContent/HeaderContent.tsx +++ b/src/pages/commonFeed/components/HeaderContent/HeaderContent.tsx @@ -33,10 +33,15 @@ const HeaderContent: FC = (props) => { const isMobileVersion = useIsTabletView(); const searchInputRef = useRef(null); const commonFollow = useCommonFollow(common.id, commonMember); + const commonId = common.id; const { searchValue, searchInputToggle, onChangeSearchValue, onCloseSearch } = useSearchFeedItems({ - onSearch: (value) => dispatch(commonActions.searchFeedItems(value)), - onResetSearchState: () => dispatch(commonActions.resetSearchState()), + onSearch: (value) => + dispatch( + commonActions.searchFeedItems({ searchValue: value, commonId }), + ), + onResetSearchState: () => + dispatch(commonActions.resetSearchState({ commonId })), }); const showFollowIcon = !isMobileVersion && @@ -64,7 +69,7 @@ const HeaderContent: FC = (props) => { <> = (props) => { )} = (props) => { return null; } - if (items.length === 2 || (items.length === 1 && items[0].id === CommonAction.NewDiscussion)) { + if ( + items.length === 2 || + (items.length === 1 && items[0].id === CommonAction.NewDiscussion) + ) { return ( - ) + ); } const triggerEl = ( diff --git a/src/shared/hooks/useCases/useCommonFeedItems.ts b/src/shared/hooks/useCases/useCommonFeedItems.ts index f4f27922eb..8a478af252 100644 --- a/src/shared/hooks/useCases/useCommonFeedItems.ts +++ b/src/shared/hooks/useCases/useCommonFeedItems.ts @@ -21,8 +21,8 @@ export const useCommonFeedItems = ( sharedFeedItemId?: string | null, ): Return => { const dispatch = useDispatch(); - const feedItems = useSelector(selectFeedItems); - const filteredFeedItems = useSelector(selectFilteredFeedItems); + const feedItems = useSelector(selectFeedItems(commonId)); + const filteredFeedItems = useSelector(selectFilteredFeedItems(commonId)); const optimisticFeedItems = useSelector(selectOptimisticFeedItems); const idsForNotListeningRef = useRef(idsForNotListening || []); const isSubscriptionAllowed = feedItems.data !== null; @@ -56,19 +56,25 @@ export const useCommonFeedItems = ( return; } - // TODO: HERE I can get optFeedItem by discussionId - const optItemIds = Array.from(optimisticFeedItems.values()).map((item) => { - return item.feedItem.data.id; - } ); + const optItemIds = Array.from(optimisticFeedItems.values()).map( + (item) => { + return item.feedItem.data.id; + }, + ); data.forEach((item) => { - const discussionId = item.commonFeedItem.data.discussionId ?? item.commonFeedItem.data.id; - if(optItemIds.includes(discussionId)) { - - dispatch(optimisticActions.removeOptimisticFeedItemState({id: discussionId})) + const discussionId = + item.commonFeedItem.data.discussionId ?? + item.commonFeedItem.data.id; + if (optItemIds.includes(discussionId)) { + dispatch( + optimisticActions.removeOptimisticFeedItemState({ + id: discussionId, + }), + ); } - }) + }); const finalData = idsForNotListeningRef.current.length > 0 @@ -80,20 +86,23 @@ export const useCommonFeedItems = ( ) : data; - dispatch(commonActions.addNewFeedItems(finalData)); + dispatch(commonActions.addNewFeedItems({ items: finalData, commonId })); }, ); return unsubscribe; - }, [isSubscriptionAllowed, feedItems.firstDocTimestamp, commonId, optimisticFeedItems]); + }, [ + isSubscriptionAllowed, + feedItems.firstDocTimestamp, + commonId, + optimisticFeedItems, + ]); useEffect(() => { return () => { - dispatch( - commonActions.getFeedItems.cancel("Cancel feed items fetch on unmount"), - ); + dispatch(commonActions.getFeedItems.cancel({ commonId })); }; - }, []); + }, [commonId]); return { ...feedItems, diff --git a/src/shared/hooks/useCases/useCommonPinnedFeedItems.ts b/src/shared/hooks/useCases/useCommonPinnedFeedItems.ts index 5e24c83e4f..eb57214c38 100644 --- a/src/shared/hooks/useCases/useCommonPinnedFeedItems.ts +++ b/src/shared/hooks/useCases/useCommonPinnedFeedItems.ts @@ -19,8 +19,10 @@ export const useCommonPinnedFeedItems = ( idsForListening?: string[], ): Return => { const dispatch = useDispatch(); - const pinnedFeedItems = useSelector(selectPinnedFeedItems); - const filteredPinnedFeedItems = useSelector(selectFilteredPinnedFeedItems); + const pinnedFeedItems = useSelector(selectPinnedFeedItems(commonId)); + const filteredPinnedFeedItems = useSelector( + selectFilteredPinnedFeedItems(commonId), + ); const previousIdsForListening = usePreviousDistinct(idsForListening); const fetch = () => { @@ -42,14 +44,18 @@ export const useCommonPinnedFeedItems = ( []; if (unpinnedIds.length > 0) { - dispatch(commonActions.unpinFeedItems(unpinnedIds)); + dispatch( + commonActions.unpinFeedItems({ itemIds: unpinnedIds, commonId }), + ); } const unsubscribe = CommonFeedService.subscribeToNewUpdatedCommonFeedItems( { commonId, idsForListening }, (data) => { if (data.length > 0) { - dispatch(commonActions.addNewPinnedFeedItems(data)); + dispatch( + commonActions.addNewPinnedFeedItems({ items: data, commonId }), + ); } }, ); @@ -59,17 +65,14 @@ export const useCommonPinnedFeedItems = ( useEffect(() => { return () => { - dispatch( - commonActions.getPinnedFeedItems.cancel( - "Cancel pinned feed items fetch on unmount", - ), - ); + dispatch(commonActions.getPinnedFeedItems.cancel({ commonId })); }; }, []); return { - ...pinnedFeedItems, + // ...pinnedFeedItems, data: filteredPinnedFeedItems || pinnedFeedItems.data, + loading: false, fetch, }; }; diff --git a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.tsx b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.tsx index 01c4bf85e0..b920d7b4b3 100644 --- a/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.tsx +++ b/src/shared/layouts/SidenavLayout/components/SidenavContent/components/UserInfo/components/MenuItems/MenuItems.tsx @@ -59,7 +59,6 @@ const MenuItems: FC = (props) => { key: "my-profile", text: "My profile", icon: , - type: ItemType.Button, to: getProfilePagePath(), }, { diff --git a/src/shared/utils/sortFeedItemFollowLayoutItems.ts b/src/shared/utils/sortFeedItemFollowLayoutItems.ts index e86f5c13d0..f418c19fad 100644 --- a/src/shared/utils/sortFeedItemFollowLayoutItems.ts +++ b/src/shared/utils/sortFeedItemFollowLayoutItems.ts @@ -5,6 +5,7 @@ export const sortFeedItemFollowLayoutItems = ( ): void => { data.sort( (prevItem, nextItem) => - nextItem.feedItem.updatedAt.seconds - prevItem.feedItem.updatedAt.seconds, + nextItem?.feedItem?.updatedAt.seconds - + prevItem?.feedItem?.updatedAt.seconds, ); }; diff --git a/src/store/states/cache/actions.ts b/src/store/states/cache/actions.ts index b030fc384b..3bfe98dc77 100644 --- a/src/store/states/cache/actions.ts +++ b/src/store/states/cache/actions.ts @@ -4,7 +4,6 @@ import { ChatChannelUserStatus, CirclesPermissions, CommonFeedObjectUserUnique, - CommonMemberWithUserInfo, CommonMember, Discussion, DiscussionMessage, diff --git a/src/store/states/cache/saga/copyFeedStateByCommonId.ts b/src/store/states/cache/saga/copyFeedStateByCommonId.ts index ab3405ba70..506777cf93 100644 --- a/src/store/states/cache/saga/copyFeedStateByCommonId.ts +++ b/src/store/states/cache/saga/copyFeedStateByCommonId.ts @@ -7,10 +7,11 @@ export function* copyFeedStateByCommonId({ payload: commonId, }: ReturnType) { const commonState = (yield select(selectCommonState)) as CommonState; + const specificCommonFeedItems = commonState.feedItems[commonId]; const data = - commonState.feedItems.data && commonState.feedItems.data.slice(0, 30); + specificCommonFeedItems.data && specificCommonFeedItems.data.slice(0, 30); const feedItems = { - ...commonState.feedItems, + ...specificCommonFeedItems, data, loading: false, hasMore: true, @@ -27,8 +28,8 @@ export function* copyFeedStateByCommonId({ commonId, state: { feedItems, - pinnedFeedItems: commonState.pinnedFeedItems, - sharedFeedItem: commonState.sharedFeedItem, + pinnedFeedItems: commonState.pinnedFeedItems[commonId], + sharedFeedItem: commonState.sharedFeedItem[commonId], }, }), ); diff --git a/src/store/states/cache/types.ts b/src/store/states/cache/types.ts index c5faa4fcf2..8b0ee33e65 100644 --- a/src/store/states/cache/types.ts +++ b/src/store/states/cache/types.ts @@ -1,4 +1,4 @@ -import { LoadingState } from "@/shared/interfaces"; +import { FeedItemFollowLayoutItem, LoadingState } from "@/shared/interfaces"; import { ChatChannelUserStatus, ChatMessage, @@ -11,12 +11,13 @@ import { Proposal, User, } from "@/shared/models"; -import { CommonState } from "../common"; +import { FeedItems, PinnedFeedItems } from "../common"; -export type FeedState = Pick< - CommonState, - "feedItems" | "pinnedFeedItems" | "sharedFeedItem" ->; +export type FeedState = { + feedItems: FeedItems; + pinnedFeedItems: PinnedFeedItems; + sharedFeedItem: FeedItemFollowLayoutItem | null; +}; export interface CacheState { userStates: Record>; diff --git a/src/store/states/common/actions.ts b/src/store/states/common/actions.ts index ef1848fec1..6c6fcb2adf 100644 --- a/src/store/states/common/actions.ts +++ b/src/store/states/common/actions.ts @@ -6,6 +6,7 @@ import { } from "@/pages/OldCommon/interfaces"; import { CommonAction, ProposalsTypes } from "@/shared/constants"; import { + FeedItemFollowLayoutItem, NewDiscussionCreationFormValues, NewProposalCreationFormValues, PayloadWithOptionalCallback, @@ -23,7 +24,6 @@ import { import { CommonActionType } from "./constants"; import { CommonSearchState, - CommonState, FeedItems, FeedItemsPayload, PinnedFeedItems, @@ -39,19 +39,31 @@ export const setCommonAction = createStandardAction( export const setCommonMember = createStandardAction( CommonActionType.SET_COMMON_MEMBER, -)(); +)<{ + commonId: string; + member: CommonMember | null; +}>(); export const setCommonGovernance = createStandardAction( CommonActionType.SET_COMMON_GOVERNANCE, -)(); +)<{ + commonId: string; + governance: Governance | null; +}>(); export const setDiscussionCreationData = createStandardAction( CommonActionType.SET_DISCUSSION_CREATION_DATA, -)(); +)<{ + commonId: string; + data: NewDiscussionCreationFormValues | null; +}>(); export const setProposalCreationData = createStandardAction( CommonActionType.SET_PROPOSAL_CREATION_DATA, -)(); +)<{ + commonId: string; + data: NewProposalCreationFormValues | null; +}>(); export const createDiscussion = createAsyncAction( CommonActionType.CREATE_DISCUSSION, @@ -65,9 +77,9 @@ export const createDiscussion = createAsyncAction( }, Discussion, Error - >, - Discussion, - Error + > & { commonId: string }, + { commonId: string; discussion: Discussion }, + { commonId: string; error: Error } >(); export const editDiscussion = createAsyncAction( @@ -82,9 +94,9 @@ export const editDiscussion = createAsyncAction( }, Discussion, Error - >, - Discussion, - Error + > & { commonId: string }, + { commonId: string; discussion: Discussion }, + { commonId: string; error: Error } >(); export const createSurveyProposal = createAsyncAction( @@ -96,9 +108,9 @@ export const createSurveyProposal = createAsyncAction( CreateProposalWithFiles, Proposal, Error - >, - Proposal, - Error + > & { commonId: string }, + { commonId: string; proposal: Proposal }, + { commonId: string; error: Error } >(); export const createFundingProposal = createAsyncAction( @@ -110,9 +122,9 @@ export const createFundingProposal = createAsyncAction( CreateProposalWithFiles, Proposal, Error - >, - Proposal, - Error + > & { commonId: string }, + { commonId: string; proposal: Proposal }, + { commonId: string; error: Error } >(); export const getFeedItems = createAsyncAction( @@ -121,10 +133,10 @@ export const getFeedItems = createAsyncAction( CommonActionType.GET_FEED_ITEMS_FAILURE, CommonActionType.GET_FEED_ITEMS_CANCEL, )< - FeedItemsPayload, - Omit, - Error, - string + { commonId: string } & FeedItemsPayload, + { commonId: string } & Omit, + { commonId: string; error: Error }, + { commonId: string } >(); export const getPinnedFeedItems = createAsyncAction( @@ -133,91 +145,125 @@ export const getPinnedFeedItems = createAsyncAction( CommonActionType.GET_PINNED_FEED_ITEMS_FAILURE, CommonActionType.GET_PINNED_FEED_ITEMS_CANCEL, )< - { - commonId: string; - }, - Omit, - Error, - string + { commonId: string }, + { commonId: string } & Omit, + { commonId: string; error: Error }, + { commonId: string } >(); export const setFeedState = createStandardAction( CommonActionType.SET_FEED_STATE, )<{ - data: Pick; + commonId: string; + data: { + feedItems: FeedItems; + pinnedFeedItems: PinnedFeedItems; + sharedFeedItem: FeedItemFollowLayoutItem; + }; sharedFeedItemId?: string | null; }>(); export const addNewFeedItems = createStandardAction( CommonActionType.ADD_NEW_FEED_ITEMS, -)< - { +)<{ + commonId: string; + items: { commonFeedItem: CommonFeed; statuses: { isAdded: boolean; isRemoved: boolean; }; - }[] ->(); + }[]; +}>(); export const addNewPinnedFeedItems = createStandardAction( CommonActionType.ADD_NEW_PINNED_FEED_ITEMS, -)< - { +)<{ + commonId: string; + items: { commonFeedItem: CommonFeed; statuses: { isAdded: boolean; isRemoved: boolean; }; - }[] ->(); + }[]; +}>(); export const unpinFeedItems = createStandardAction( CommonActionType.UNPIN_FEED_ITEMS, -)(); +)<{ + commonId: string; + itemIds: string[]; +}>(); export const updateFeedItem = createStandardAction( CommonActionType.UPDATE_FEED_ITEM, )<{ + commonId: string; item: Partial & { id: string }; isRemoved?: boolean; }>(); export const resetFeedItems = createStandardAction( CommonActionType.RESET_FEED_ITEMS, -)(); +)<{ + commonId: string; +}>(); export const searchFeedItems = createStandardAction( CommonActionType.SEARCH_FEED_ITEMS, -)(); +)<{ + commonId: string; + searchValue: string; +}>(); export const setSearchState = createStandardAction( CommonActionType.SET_SEARCH_STATE, -)(); +)<{ + commonId: string; + state: CommonSearchState; +}>(); export const resetSearchState = createStandardAction( CommonActionType.RESET_SEARCH_STATE, -)(); +)<{ + commonId: string; +}>(); export const updateSearchFeedItems = createStandardAction( CommonActionType.UPDATE_SEARCH_FEED_ITEMS, -)(); +)<{ + commonId: string; + itemIds: string[]; +}>(); export const setIsSearchingFeedItems = createStandardAction( CommonActionType.SET_IS_SEARCHING_FEED_ITEMS, -)(); +)<{ + commonId: string; + isSearching: boolean; +}>(); export const setIsNewProjectCreated = createStandardAction( CommonActionType.SET_IS_NEW_PROJECT_CREATED, -)(); +)<{ + commonId: string; + isCreated: boolean; +}>(); export const setSharedFeedItemId = createStandardAction( CommonActionType.SET_SHARED_FEED_ITEM_ID, -)(); +)<{ + commonId: string; + sharedFeedItemId: string | null; +}>(); export const setSharedFeedItem = createStandardAction( CommonActionType.SET_SHARED_FEED_ITEM, -)(); +)<{ + commonId: string; + feedItem: CommonFeed | null; +}>(); export const setRecentStreamId = createStandardAction( CommonActionType.SET_RECENT_STREAM_ID, @@ -226,17 +272,21 @@ export const setRecentStreamId = createStandardAction( export const setRecentAssignedCircleByMember = createStandardAction( CommonActionType.SET_RECENT_ASSIGNED_CIRCLE_BY_MEMBER, )<{ + commonId: string; memberId: string; circle: Circle; }>(); export const resetRecentAssignedCircleByMember = createStandardAction( CommonActionType.RESET_RECENT_ASSIGNED_CIRCLE_BY_MEMBER, -)(); +)<{ + commonId: string; +}>(); export const setFeedItemUpdatedAt = createStandardAction( CommonActionType.SET_FEED_ITEM_UPDATED_AT, )<{ + commonId: string; feedItemId: string; lastMessage: LastMessageContentWithMessageId; }>(); diff --git a/src/store/states/common/constants.ts b/src/store/states/common/constants.ts index 94a9e725f6..cc9839c909 100644 --- a/src/store/states/common/constants.ts +++ b/src/store/states/common/constants.ts @@ -60,6 +60,6 @@ export enum CommonActionType { SET_RECENT_ASSIGNED_CIRCLE_BY_MEMBER = "@COMMON/SET_RECENT_ASSIGNED_CIRCLE_BY_MEMBER", RESET_RECENT_ASSIGNED_CIRCLE_BY_MEMBER = "@COMMON/RESET_RECENT_ASSIGNED_CIRCLE_BY_MEMBER", - + SET_FEED_ITEM_UPDATED_AT = "@COMMON/SET_FEED_ITEM_UPDATED_AT", } diff --git a/src/store/states/common/reducer.ts b/src/store/states/common/reducer.ts index 578d6d0f66..249aa11d8b 100644 --- a/src/store/states/common/reducer.ts +++ b/src/store/states/common/reducer.ts @@ -9,7 +9,6 @@ import { } from "@/shared/interfaces"; import { CommonFeed, Timestamp } from "@/shared/models"; import { - areTimestampsEqual, convertToTimestamp, sortFeedItemFollowLayoutItems as sortFeedItems, } from "@/shared/utils"; @@ -37,7 +36,7 @@ const initialPinnedFeedItems: PinnedFeedItems = { loading: false, }; -const initialSearchState: CommonSearchState = { +export const initialSearchState: CommonSearchState = { isSearching: false, feedItems: null, pinnedFeedItems: null, @@ -45,41 +44,37 @@ const initialSearchState: CommonSearchState = { }; const initialState: CommonState = { - feedItems: { ...initialFeedItems }, - pinnedFeedItems: { ...initialPinnedFeedItems }, - searchState: { ...initialSearchState }, - sharedFeedItemId: null, - sharedFeedItem: null, + feedItems: {}, + pinnedFeedItems: {}, + searchState: {}, + sharedFeedItem: {}, commonAction: null, - discussionCreation: { - data: null, - loading: false, - }, - isNewProjectCreated: false, - proposalCreation: { - data: null, - loading: false, - }, - commonMember: null, - governance: null, + discussionCreations: {}, + proposalCreations: {}, + isNewProjectCreated: {}, + sharedFeedItemId: {}, + commonMembers: {}, + governance: {}, recentStreamId: "", recentAssignedCircleByMember: {}, }; const updateFeedItemInList = ( state: WritableDraft, + commonId: string, payload: { item: Partial & { id: string }; isRemoved?: boolean; }, ): void => { - if (!state.feedItems.data) { + const feedItems = state.feedItems[commonId]; + if (!feedItems || !feedItems.data) { return; } const { item: updatedItem } = payload; const isRemoved = payload.isRemoved || updatedItem.isDeleted; - const feedItemIndex = state.feedItems.data?.findIndex( + const feedItemIndex = feedItems.data.findIndex( (item) => item.feedItem.id === updatedItem.id, ); @@ -87,8 +82,7 @@ const updateFeedItemInList = ( return; } - const nextData = [...state.feedItems.data]; - + const nextData = [...feedItems.data]; if (isRemoved) { nextData.splice(feedItemIndex, 1); } else { @@ -106,24 +100,17 @@ const updateFeedItemInList = ( const lastDocTimestamp = nextData[nextData.length - 1]?.feedItem.updatedAt || null; - state.feedItems = { - ...state.feedItems, + state.feedItems[commonId] = { + ...feedItems, data: nextData, + firstDocTimestamp, + lastDocTimestamp, }; - - if ( - !areTimestampsEqual(state.feedItems.firstDocTimestamp, firstDocTimestamp) - ) { - state.feedItems.firstDocTimestamp = firstDocTimestamp; - } - - if (!areTimestampsEqual(state.feedItems.lastDocTimestamp, lastDocTimestamp)) { - state.feedItems.lastDocTimestamp = lastDocTimestamp; - } }; const addNewFeedItems = ( state: WritableDraft, + commonId: string, payload: { commonFeedItem: CommonFeed; statuses: { @@ -133,24 +120,25 @@ const addNewFeedItems = ( }[], shouldSortNewItems = false, ) => { + const feedItems = state.feedItems[commonId] || initialFeedItems; + const data = payload.reduceRight((acc, { commonFeedItem, statuses }) => { const nextData = [...acc]; - const itemIndex = nextData.findIndex( - (item) => item.feedItem.id === commonFeedItem.id, - ); - const isRemoved = statuses.isRemoved || commonFeedItem.isDeleted; + const itemIndex = nextData.findIndex((item) => { + return item?.feedItem?.id === commonFeedItem?.id; + }); + const isRemoved = statuses.isRemoved || commonFeedItem?.isDeleted; if (isRemoved) { if (itemIndex >= 0) { nextData.splice(itemIndex, 1); } - return nextData; } const finalItem: FeedItemFollowLayoutItem = { type: InboxItemType.FeedItemFollow, - itemId: commonFeedItem.id, + itemId: commonFeedItem?.id, feedItem: commonFeedItem, }; @@ -171,32 +159,24 @@ const addNewFeedItems = ( } nextData.splice(indexForItemPlacement, 0, finalItem); - return nextData; - }, state.feedItems.data || []); + }, feedItems.data || []); sortFeedItems(data); - const firstDocTimestamp = data[0]?.feedItem.updatedAt || null; - const lastDocTimestamp = data[data.length - 1]?.feedItem.updatedAt || null; + const firstDocTimestamp = data[0]?.feedItem?.updatedAt || null; + const lastDocTimestamp = data[data.length - 1]?.feedItem?.updatedAt || null; - state.feedItems = { - ...state.feedItems, + state.feedItems[commonId] = { + ...feedItems, data, + firstDocTimestamp, + lastDocTimestamp, }; - - if ( - !areTimestampsEqual(state.feedItems.firstDocTimestamp, firstDocTimestamp) - ) { - state.feedItems.firstDocTimestamp = firstDocTimestamp; - } - - if (!areTimestampsEqual(state.feedItems.lastDocTimestamp, lastDocTimestamp)) { - state.feedItems.lastDocTimestamp = lastDocTimestamp; - } }; const addNewPinnedFeedItems = ( state: WritableDraft, + commonId: string, payload: { commonFeedItem: CommonFeed; statuses: { @@ -205,10 +185,16 @@ const addNewPinnedFeedItems = ( }; }[], ) => { + const pinnedFeedItems = state.pinnedFeedItems[commonId] || { + data: null, + loading: false, + }; + const data = payload.reduceRight((acc, { commonFeedItem, statuses }) => { const nextData = [...acc]; + const itemIndex = nextData.findIndex( - (item) => item.feedItem.id === commonFeedItem.id, + (item) => item?.feedItem?.id === commonFeedItem.id, ); const isRemoved = statuses.isRemoved || commonFeedItem.isDeleted; @@ -216,7 +202,6 @@ const addNewPinnedFeedItems = ( if (itemIndex >= 0) { nextData.splice(itemIndex, 1); } - return nextData; } @@ -231,30 +216,34 @@ const addNewPinnedFeedItems = ( } nextData[itemIndex] = finalItem; - return nextData; - }, state.pinnedFeedItems.data || []); + }, pinnedFeedItems.data || []); - state.pinnedFeedItems = { - ...state.pinnedFeedItems, + state.pinnedFeedItems[commonId] = { + ...pinnedFeedItems, data, }; }; const updatePinnedFeedItemInList = ( state: WritableDraft, + commonId: string, payload: { item: Partial & { id: string }; isRemoved?: boolean; }, ): FeedItemFollowLayoutItem | null => { - if (!state.pinnedFeedItems.data) { + const pinnedFeedItems = state.pinnedFeedItems[commonId] || { + data: null, + loading: false, + }; + if (!pinnedFeedItems.data) { return null; } const { item: updatedItem } = payload; const isRemoved = payload.isRemoved || updatedItem.isDeleted; - const feedItemIndex = state.pinnedFeedItems.data?.findIndex( + const feedItemIndex = pinnedFeedItems.data.findIndex( (item) => item.feedItem.id === updatedItem.id, ); @@ -262,7 +251,7 @@ const updatePinnedFeedItemInList = ( return null; } - const nextData = [...state.pinnedFeedItems.data]; + const nextData = [...pinnedFeedItems.data]; let itemToReturn: FeedItemFollowLayoutItem; if (isRemoved) { @@ -279,8 +268,8 @@ const updatePinnedFeedItemInList = ( itemToReturn = nextData[feedItemIndex]; } - state.pinnedFeedItems = { - ...state.pinnedFeedItems, + state.pinnedFeedItems[commonId] = { + ...pinnedFeedItems, data: nextData, }; @@ -289,26 +278,27 @@ const updatePinnedFeedItemInList = ( const updateSharedFeedItem = ( state: WritableDraft, + commonId: string, payload: { item: Partial & { id: string }; isRemoved?: boolean; }, ): void => { + const sharedFeedItem = state.sharedFeedItem[commonId]; const { item: updatedItem } = payload; const isRemoved = payload.isRemoved || updatedItem.isDeleted; - if (state.sharedFeedItem?.feedItem.id !== updatedItem.id) { + if (!sharedFeedItem || sharedFeedItem.feedItem.id !== updatedItem.id) { return; } if (isRemoved) { - state.sharedFeedItem = null; - state.sharedFeedItemId = null; + state.sharedFeedItem[commonId] = null; } else { - state.sharedFeedItem = { - ...state.sharedFeedItem, + state.sharedFeedItem[commonId] = { + ...sharedFeedItem, feedItem: { - ...state.sharedFeedItem.feedItem, + ...sharedFeedItem.feedItem, ...updatedItem, }, }; @@ -316,7 +306,10 @@ const updateSharedFeedItem = ( }; export const reducer = createReducer(initialState) + // Reset state .handleAction(actions.resetCommon, () => ({ ...initialState })) + + // Common Actions .handleAction(actions.setCommonAction, (state, { payload }) => produce(state, (nextState) => { nextState.commonAction = payload; @@ -324,74 +317,104 @@ export const reducer = createReducer(initialState) ) .handleAction(actions.setCommonMember, (state, { payload }) => produce(state, (nextState) => { - nextState.commonMember = payload; + const { commonId, member } = payload; + nextState.commonMembers[commonId] = member; }), ) .handleAction(actions.setCommonGovernance, (state, { payload }) => produce(state, (nextState) => { - nextState.governance = payload; + const { commonId, governance } = payload; + nextState.governance[commonId] = governance; }), ) + + // Discussion Creation .handleAction(actions.setDiscussionCreationData, (state, { payload }) => produce(state, (nextState) => { - nextState.discussionCreation = { - data: payload, + const { commonId, data } = payload; + nextState.discussionCreations[commonId] = { + data, loading: false, }; }), ) - .handleAction(actions.setProposalCreationData, (state, { payload }) => + .handleAction(actions.createDiscussion.request, (state, { payload }) => produce(state, (nextState) => { - nextState.proposalCreation = { - data: payload, + const { commonId } = payload; + const discussionCreation = nextState.discussionCreations[commonId] || { + data: null, loading: false, }; - }), - ) - .handleAction(actions.createDiscussion.request, (state) => - produce(state, (nextState) => { - nextState.discussionCreation = { - ...nextState.discussionCreation, + nextState.discussionCreations[commonId] = { + ...discussionCreation, loading: true, }; }), ) - .handleAction(actions.createDiscussion.success, (state) => + .handleAction(actions.createDiscussion.success, (state, { payload }) => produce(state, (nextState) => { - nextState.discussionCreation = { + const { commonId } = payload; + nextState.discussionCreations[commonId] = { loading: false, data: null, }; }), ) - .handleAction(actions.createDiscussion.failure, (state) => + .handleAction(actions.createDiscussion.failure, (state, { payload }) => produce(state, (nextState) => { - nextState.discussionCreation = { - ...nextState.discussionCreation, + const { commonId } = payload; + const discussionCreation = nextState.discussionCreations[commonId] || { + data: null, + loading: false, + }; + nextState.discussionCreations[commonId] = { + ...discussionCreation, loading: false, }; }), ) - .handleAction(actions.editDiscussion.request, (state) => + .handleAction(actions.editDiscussion.request, (state, { payload }) => produce(state, (nextState) => { - nextState.discussionCreation = { - ...nextState.discussionCreation, + const { commonId } = payload; + const discussionCreation = nextState.discussionCreations[commonId] || { + data: null, + loading: false, + }; + nextState.discussionCreations[commonId] = { + ...discussionCreation, loading: true, }; }), ) - .handleAction(actions.editDiscussion.success, (state) => + .handleAction(actions.editDiscussion.success, (state, { payload }) => produce(state, (nextState) => { - nextState.discussionCreation = { + const { commonId } = payload; + nextState.discussionCreations[commonId] = { loading: false, data: null, }; }), ) - .handleAction(actions.editDiscussion.failure, (state) => + .handleAction(actions.editDiscussion.failure, (state, { payload }) => + produce(state, (nextState) => { + const { commonId } = payload; + const discussionCreation = nextState.discussionCreations[commonId] || { + data: null, + loading: false, + }; + nextState.discussionCreations[commonId] = { + ...discussionCreation, + loading: false, + }; + }), + ) + + // Proposal Creation + .handleAction(actions.setProposalCreationData, (state, { payload }) => produce(state, (nextState) => { - nextState.discussionCreation = { - ...nextState.discussionCreation, + const { commonId, data } = payload; + nextState.proposalCreations[commonId] = { + data, loading: false, }; }), @@ -401,10 +424,15 @@ export const reducer = createReducer(initialState) actions.createSurveyProposal.request, actions.createFundingProposal.request, ], - (state) => + (state, { payload }) => produce(state, (nextState) => { - nextState.proposalCreation = { - ...nextState.proposalCreation, + const { commonId } = payload; + const proposalCreation = nextState.proposalCreations[commonId] || { + data: null, + loading: false, + }; + nextState.proposalCreations[commonId] = { + ...proposalCreation, loading: true, }; }), @@ -414,9 +442,10 @@ export const reducer = createReducer(initialState) actions.createSurveyProposal.success, actions.createFundingProposal.success, ], - (state) => + (state, { payload }) => produce(state, (nextState) => { - nextState.proposalCreation = { + const { commonId } = payload; + nextState.proposalCreations[commonId] = { loading: false, data: null, }; @@ -427,119 +456,288 @@ export const reducer = createReducer(initialState) actions.createSurveyProposal.failure, actions.createFundingProposal.failure, ], - (state) => + (state, { payload }) => produce(state, (nextState) => { - nextState.proposalCreation = { - ...nextState.proposalCreation, + const { commonId } = payload; + const proposalCreation = nextState.proposalCreations[commonId] || { + data: null, + loading: false, + }; + nextState.proposalCreations[commonId] = { + ...proposalCreation, loading: false, }; }), ) - .handleAction(actions.getFeedItems.request, (state) => + + // Feed Items + .handleAction(actions.getFeedItems.request, (state, { payload }) => produce(state, (nextState) => { - nextState.feedItems = { - ...nextState.feedItems, - loading: true, - }; + const { commonId } = payload; + const feedItems = nextState.feedItems[commonId] || initialFeedItems; + nextState.feedItems[commonId] = { ...feedItems, loading: true }; }), ) .handleAction(actions.getFeedItems.success, (state, { payload }) => produce(state, (nextState) => { - const payloadData = nextState.sharedFeedItemId - ? payload.data && - payload.data.filter( - (item) => item.feedItem.id !== nextState.sharedFeedItemId, - ) - : payload.data; - const nextData = nextState.feedItems.data || []; - const filteredPayloadData = - payloadData && differenceBy(payloadData, nextData, "feedItem.id"); - - nextState.feedItems = { - ...payload, - data: filteredPayloadData && nextData.concat(filteredPayloadData), + const { commonId, data, hasMore, firstDocTimestamp, lastDocTimestamp } = + payload; + const feedItems = nextState.feedItems[commonId] || initialFeedItems; + + const existingData = feedItems.data || []; + const filteredData = differenceBy(data, existingData, "feedItem.id"); + + nextState.feedItems[commonId] = { + ...feedItems, + data: [...existingData, ...filteredData], loading: false, - batchNumber: nextState.feedItems.batchNumber + 1, + hasMore, + firstDocTimestamp, + lastDocTimestamp, }; }), ) - .handleAction(actions.getFeedItems.failure, (state) => + .handleAction(actions.getFeedItems.failure, (state, { payload }) => produce(state, (nextState) => { - nextState.feedItems = { - ...nextState.feedItems, - data: nextState.feedItems.data || [], + const { commonId } = payload; + const feedItems = nextState.feedItems[commonId] || initialFeedItems; + nextState.feedItems[commonId] = { + ...feedItems, loading: false, hasMore: false, - lastDocTimestamp: null, }; }), ) - .handleAction(actions.getPinnedFeedItems.request, (state) => + .handleAction(actions.addNewFeedItems, (state, { payload }) => + produce(state, (nextState) => { + const { commonId, items: newItems } = payload; + const feedItems = nextState.feedItems[commonId] || initialFeedItems; + const existingData = feedItems.data || []; + + const mappedNewItems = newItems.map(({ commonFeedItem }) => ({ + type: InboxItemType.FeedItemFollow as const, + feedItem: commonFeedItem, + itemId: commonFeedItem.id, + })); + + const newData = differenceBy(mappedNewItems, existingData, "feedItem.id"); + nextState.feedItems[commonId] = { + ...feedItems, + data: [...existingData, ...newData], + }; + }), + ) + .handleAction(actions.updateFeedItem, (state, { payload }) => + produce(state, (nextState) => { + const { commonId, item, isRemoved } = payload; + + // Ensure the feedItems, pinnedFeedItems, and sharedFeedItems for the commonId exist + if (!nextState.feedItems[commonId]) { + nextState.feedItems[commonId] = { ...initialFeedItems }; + } + if (!nextState.pinnedFeedItems[commonId]) { + nextState.pinnedFeedItems[commonId] = { ...initialPinnedFeedItems }; + } + if (!nextState.sharedFeedItem[commonId]) { + nextState.sharedFeedItem[commonId] = null; + } + + // Update lists for the specified commonId + updateFeedItemInList(nextState, commonId, { item, isRemoved }); + updatePinnedFeedItemInList(nextState, commonId, { item, isRemoved }); + updateSharedFeedItem(nextState, commonId, { item, isRemoved }); + }), + ) + + // Pinned Feed Items + .handleAction(actions.getPinnedFeedItems.request, (state, { payload }) => produce(state, (nextState) => { - nextState.pinnedFeedItems = { - ...nextState.pinnedFeedItems, + const { commonId } = payload; + const pinnedFeedItems = + nextState.pinnedFeedItems[commonId] || initialPinnedFeedItems; + nextState.pinnedFeedItems[commonId] = { + ...pinnedFeedItems, loading: true, }; }), ) .handleAction(actions.getPinnedFeedItems.success, (state, { payload }) => produce(state, (nextState) => { - nextState.pinnedFeedItems = { - data: payload.data, + const { commonId, data } = payload; + nextState.pinnedFeedItems[commonId] = { + data, loading: false, }; }), ) - .handleAction(actions.getPinnedFeedItems.failure, (state) => + .handleAction(actions.getPinnedFeedItems.failure, (state, { payload }) => produce(state, (nextState) => { - nextState.pinnedFeedItems = { - ...nextState.pinnedFeedItems, - data: nextState.pinnedFeedItems.data || [], + const { commonId } = payload; + const pinnedFeedItems = + nextState.pinnedFeedItems[commonId] || initialPinnedFeedItems; + nextState.pinnedFeedItems[commonId] = { + ...pinnedFeedItems, loading: false, }; }), ) + .handleAction(actions.addNewPinnedFeedItems, (state, { payload }) => + produce(state, (nextState) => { + const { commonId, items } = payload; + + // Ensure pinnedFeedItems and feedItems are initialized for the commonId + if (!nextState.pinnedFeedItems[commonId]) { + nextState.pinnedFeedItems[commonId] = { ...initialPinnedFeedItems }; + } + if (!nextState.feedItems[commonId]) { + nextState.feedItems[commonId] = { ...initialFeedItems }; + } + + // Add new pinned feed items + addNewPinnedFeedItems(nextState, commonId, items); + + // Add items to feed items as "removed" + addNewFeedItems( + nextState, + commonId, + items.map((item) => ({ + ...item, + statuses: { + isAdded: false, + isRemoved: true, + }, + })), + true, // Ensure sorting is applied if required + ); + }), + ) + + // Shared Feed Item + .handleAction(actions.setSharedFeedItem, (state, { payload }) => + produce(state, (nextState) => { + const { commonId, feedItem } = payload; + nextState.sharedFeedItem[commonId] = feedItem + ? { + type: InboxItemType.FeedItemFollow, + itemId: feedItem.id, + feedItem, + } + : null; + }), + ) + .handleAction(actions.setFeedItemUpdatedAt, (state, { payload }) => + produce(state, (nextState) => { + const { commonId, feedItemId, lastMessage } = payload; + + const feedItems = nextState.feedItems[commonId]?.data || []; + + const updatedFeedItemIndex = feedItems.findIndex((feedItem) => { + return feedItem?.feedItem?.id === feedItemId; + }); + + if (updatedFeedItemIndex !== -1) { + const item = feedItems[updatedFeedItemIndex]; + item.feedItem = { + ...item.feedItem, + updatedAt: Timestamp.fromDate(new Date()), + data: { + ...item.feedItem.data, + lastMessage, + }, + }; + + // Sort feedItems by updatedAt in descending order + feedItems.sort((a, b) => { + const dateA = a?.feedItem?.updatedAt.toDate().getTime(); + const dateB = b?.feedItem?.updatedAt.toDate().getTime(); + return dateB - dateA; // Sort in descending order + }); + + const firstDocTimestamp = feedItems[0]?.feedItem?.updatedAt || null; + const lastDocTimestamp = + feedItems[feedItems.length - 1]?.feedItem?.updatedAt || null; + + nextState.feedItems[commonId] = { + ...nextState.feedItems[commonId], + data: feedItems, + firstDocTimestamp, + lastDocTimestamp, + }; + } + }), + ) .handleAction(actions.setSearchState, (state, { payload }) => produce(state, (nextState) => { - nextState.searchState = payload; + const { commonId, state: searchState } = payload; + nextState.searchState[commonId] = searchState; }), ) - .handleAction(actions.resetSearchState, (state) => + .handleAction(actions.resetSearchState, (state, { payload }) => produce(state, (nextState) => { - nextState.searchState = { ...initialSearchState }; + const { commonId } = payload; + nextState.searchState[commonId] = { ...initialSearchState }; }), ) .handleAction(actions.updateSearchFeedItems, (state, { payload }) => produce(state, (nextState) => { - if (!nextState.searchState.feedItems) { - nextState.searchState.feedItems = []; + const { commonId, itemIds } = payload; + + // Ensure the searchState for the given commonId is initialized + if (!nextState.searchState[commonId]) { + nextState.searchState[commonId] = { ...initialSearchState }; } - payload.forEach((feedItemEntityId) => { - const feedItem = nextState.feedItems.data?.find( + if (!nextState.searchState[commonId].feedItems) { + nextState.searchState[commonId].feedItems = []; + } + + // Get the feedItems for the given commonId + const feedItems = nextState.feedItems[commonId]?.data || []; + + itemIds.forEach((feedItemEntityId) => { + const feedItem = feedItems.find( (item) => item.feedItem.data.id === feedItemEntityId || item.feedItem.data.discussionId === feedItemEntityId, ); if (feedItem) { - nextState.searchState.feedItems!.push(feedItem); + nextState.searchState[commonId].feedItems!.push(feedItem); } }); }), ) .handleAction(actions.setIsSearchingFeedItems, (state, { payload }) => produce(state, (nextState) => { - nextState.searchState.isSearching = payload; + const { commonId, isSearching } = payload; + + // Ensure searchState exists for the commonId + if (!nextState.searchState[commonId]) { + nextState.searchState[commonId] = { ...initialSearchState }; + } + + nextState.searchState[commonId].isSearching = isSearching; }), ) .handleAction(actions.setFeedState, (state, { payload }) => produce(state, (nextState) => { const { + commonId, data: { feedItems, pinnedFeedItems, sharedFeedItem }, sharedFeedItemId, } = payload; - nextState.feedItems = { + + // Initialize feedItems and pinnedFeedItems for the commonId if not already present + if (!nextState.feedItems[commonId]) { + nextState.feedItems[commonId] = { ...initialFeedItems }; + } + + if (!nextState.pinnedFeedItems[commonId]) { + nextState.pinnedFeedItems[commonId] = { ...initialPinnedFeedItems }; + } + + // Update feedItems + nextState.feedItems[commonId] = { ...feedItems, data: feedItems.data && @@ -553,17 +751,24 @@ export const reducer = createReducer(initialState) convertToTimestamp(feedItems.lastDocTimestamp)) || null, hasMore: true, + loading: false, // Ensure required field + batchNumber: nextState.feedItems[commonId].batchNumber || 0, // Preserve or initialize }; - nextState.pinnedFeedItems = { + + // Update pinnedFeedItems + nextState.pinnedFeedItems[commonId] = { ...pinnedFeedItems, data: pinnedFeedItems.data && pinnedFeedItems.data.map(deserializeFeedItemFollowLayoutItem), + loading: false, // Ensure required field }; + // Handle sharedFeedItem logic if (sharedFeedItem && sharedFeedItem.itemId === sharedFeedItemId) { return; } + if ( sharedFeedItem && !pinnedFeedItems.data?.some( @@ -573,47 +778,45 @@ export const reducer = createReducer(initialState) ) { const data = [sharedFeedItem, ...(feedItems.data || [])]; sortFeedItems(data); - nextState.feedItems.data = data; + nextState.feedItems[commonId].data = data; } + + // Remove sharedFeedItemId from feedItems and pinnedFeedItems if (sharedFeedItemId) { - nextState.feedItems.data = - nextState.feedItems.data && - nextState.feedItems.data.filter( - (item) => item.itemId !== sharedFeedItemId, + if (!nextState.feedItems[commonId].data) { + nextState.feedItems[commonId].data = initialFeedItems.data; // Ensure it exists + } + + nextState.feedItems[commonId].data = + nextState.feedItems?.[commonId]?.data && + (nextState.feedItems[commonId]?.data ?? []).filter( + (item) => item?.itemId !== sharedFeedItemId, ); - nextState.pinnedFeedItems.data = - nextState.pinnedFeedItems.data && - nextState.pinnedFeedItems.data.filter( - (item) => item.itemId !== sharedFeedItemId, + nextState.pinnedFeedItems[commonId].data = + nextState.pinnedFeedItems?.[commonId]?.data && + (nextState.pinnedFeedItems[commonId]?.data ?? []).filter( + (item) => item?.itemId !== sharedFeedItemId, ); } }), ) - .handleAction(actions.addNewFeedItems, (state, { payload }) => - produce(state, (nextState) => { - addNewFeedItems(nextState, payload); - }), - ) - .handleAction(actions.addNewPinnedFeedItems, (state, { payload }) => - produce(state, (nextState) => { - addNewPinnedFeedItems(nextState, payload); - addNewFeedItems( - nextState, - payload.map((item) => ({ - ...item, - statuses: { - isAdded: false, - isRemoved: true, - }, - })), - ); - }), - ) + .handleAction(actions.unpinFeedItems, (state, { payload }) => produce(state, (nextState) => { + const { commonId, itemIds } = payload; + + // Ensure the pinnedFeedItems and feedItems for the commonId are initialized + if (!nextState.pinnedFeedItems[commonId]) { + nextState.pinnedFeedItems[commonId] = { ...initialPinnedFeedItems }; + } + if (!nextState.feedItems[commonId]) { + nextState.feedItems[commonId] = { ...initialFeedItems }; + } + const removedItems: FeedItemFollowLayoutItem[] = []; - payload.forEach((itemId) => { - const removedItem = updatePinnedFeedItemInList(nextState, { + + itemIds.forEach((itemId) => { + const removedItem = updatePinnedFeedItemInList(nextState, commonId, { item: { id: itemId }, isRemoved: true, }); @@ -629,6 +832,7 @@ export const reducer = createReducer(initialState) addNewFeedItems( nextState, + commonId, removedItems.map((item) => ({ commonFeedItem: item.feedItem, statuses: { @@ -640,29 +844,50 @@ export const reducer = createReducer(initialState) ); }), ) - .handleAction(actions.updateFeedItem, (state, { payload }) => + .handleAction(actions.resetFeedItems, (state, { payload }) => produce(state, (nextState) => { - updateFeedItemInList(nextState, payload); - updatePinnedFeedItemInList(nextState, payload); - updateSharedFeedItem(nextState, payload); - }), - ) - .handleAction(actions.resetFeedItems, (state) => - produce(state, (nextState) => { - nextState.feedItems = { ...initialFeedItems }; - nextState.pinnedFeedItems = { ...initialPinnedFeedItems }; - nextState.sharedFeedItemId = null; - nextState.sharedFeedItem = null; + const { commonId } = payload; + + // Reset the feed items for the given commonId + if (nextState.feedItems[commonId]) { + nextState.feedItems[commonId] = { ...initialFeedItems }; + } + + // Reset the pinned feed items for the given commonId + if (nextState.pinnedFeedItems[commonId]) { + nextState.pinnedFeedItems[commonId] = { ...initialPinnedFeedItems }; + } + + // Reset the shared feed item for the given commonId + if (nextState.sharedFeedItem[commonId]) { + nextState.sharedFeedItem[commonId] = null; + } }), ) .handleAction(actions.setIsNewProjectCreated, (state, { payload }) => produce(state, (nextState) => { - nextState.isNewProjectCreated = payload; + const { commonId, isCreated } = payload; + + // Ensure the isNewProjectCreated map is initialized + if (!nextState.isNewProjectCreated) { + nextState.isNewProjectCreated = {}; + } + + // Set the value for the specific commonId + nextState.isNewProjectCreated[commonId] = isCreated; }), ) .handleAction(actions.setSharedFeedItemId, (state, { payload }) => produce(state, (nextState) => { - nextState.sharedFeedItemId = payload; + const { commonId, sharedFeedItemId } = payload; + + // Ensure sharedFeedItemIds map is initialized + if (!nextState.sharedFeedItem) { + nextState.sharedFeedItemId = {}; + } + + // Set the sharedFeedItemId for the given commonId + nextState.sharedFeedItemId[commonId] = sharedFeedItemId; }), ) .handleAction(actions.setRecentStreamId, (state, { payload }) => @@ -672,52 +897,26 @@ export const reducer = createReducer(initialState) ) .handleAction(actions.setRecentAssignedCircleByMember, (state, { payload }) => produce(state, (nextState) => { - const { memberId, circle } = payload; + const { commonId, memberId, circle } = payload; - nextState.recentAssignedCircleByMember[memberId] = circle; - }), - ) - .handleAction(actions.resetRecentAssignedCircleByMember, (state) => - produce(state, (nextState) => { - nextState.recentAssignedCircleByMember = {}; - }), - ) - .handleAction(actions.setSharedFeedItem, (state, { payload }) => - produce(state, (nextState) => { - nextState.sharedFeedItem = payload - ? { - type: InboxItemType.FeedItemFollow, - itemId: payload.id, - feedItem: payload, - } - : null; + // Ensure the recentAssignedCircleByMember map for the commonId exists + if (!nextState.recentAssignedCircleByMember[commonId]) { + nextState.recentAssignedCircleByMember[commonId] = {}; + } + + // Update the circle for the given memberId within the commonId + nextState.recentAssignedCircleByMember[commonId][memberId] = circle; }), ) - .handleAction(actions.setFeedItemUpdatedAt, (state, { payload }) => - produce(state, (nextState) => { - const feedItemId = payload.feedItemId; - - const updatedFeedItemIndex = nextState.feedItems.data?.findIndex( - feedItem => feedItem.itemId === feedItemId - ) ?? -1; - - if (updatedFeedItemIndex !== -1 && nextState.feedItems.data) { - const item = nextState.feedItems.data[updatedFeedItemIndex]; - item.feedItem = { - ...item.feedItem, - updatedAt: Timestamp.fromDate(new Date()), - data: { - ...item.feedItem.data, - lastMessage: payload.lastMessage, - } - }; + .handleAction( + actions.resetRecentAssignedCircleByMember, + (state, { payload }) => + produce(state, (nextState) => { + const { commonId } = payload; - // Sort `nextState.items.data` by `updatedAt` in descending order - nextState.feedItems.data.sort((a, b) => { - const dateA = a.feedItem.updatedAt.toDate().getTime(); - const dateB = b.feedItem.updatedAt.toDate().getTime(); - return dateB - dateA; // Sort in descending order - }); - } - }), - ); \ No newline at end of file + // Reset the recentAssignedCircleByMember for the specific commonId + if (nextState.recentAssignedCircleByMember[commonId]) { + nextState.recentAssignedCircleByMember[commonId] = {}; + } + }), + ); diff --git a/src/store/states/common/saga/createDiscussion.ts b/src/store/states/common/saga/createDiscussion.ts index 50d86da08b..d12a0da5ab 100644 --- a/src/store/states/common/saga/createDiscussion.ts +++ b/src/store/states/common/saga/createDiscussion.ts @@ -33,14 +33,21 @@ export function* createDiscussion( ); yield put(actions.setCommonAction(null)); - yield put(actions.createDiscussion.success(discussion)); + yield put( + actions.createDiscussion.success({ + discussion, + commonId: payload.commonId, + }), + ); if (payload.callback) { payload.callback(null, discussion); } } catch (error) { if (isError(error)) { - yield put(actions.createDiscussion.failure(error)); + yield put( + actions.createDiscussion.failure({ error, commonId: payload.commonId }), + ); if (payload.callback) { payload.callback(error); diff --git a/src/store/states/common/saga/createProposal.ts b/src/store/states/common/saga/createProposal.ts index e6789f76fa..68a19f1eec 100644 --- a/src/store/states/common/saga/createProposal.ts +++ b/src/store/states/common/saga/createProposal.ts @@ -28,14 +28,24 @@ export function* createSurveyProposal( ); yield put(actions.setCommonAction(null)); - yield put(actions.createSurveyProposal.success(proposal)); + yield put( + actions.createSurveyProposal.success({ + proposal, + commonId: payload.commonId, + }), + ); if (payload.callback) { payload.callback(null, proposal); } } catch (error) { if (isError(error)) { - yield put(actions.createSurveyProposal.failure(error)); + yield put( + actions.createSurveyProposal.failure({ + error, + commonId: payload.commonId, + }), + ); if (payload.callback) { payload.callback(error); @@ -67,14 +77,24 @@ export function* createFundingProposal( ); yield put(actions.setCommonAction(null)); - yield put(actions.createFundingProposal.success(proposal)); + yield put( + actions.createFundingProposal.success({ + proposal, + commonId: payload.commonId, + }), + ); if (payload.callback) { payload.callback(null, proposal); } } catch (error) { if (isError(error)) { - yield put(actions.createFundingProposal.failure(error)); + yield put( + actions.createFundingProposal.failure({ + error, + commonId: payload.commonId, + }), + ); if (payload.callback) { payload.callback(error); diff --git a/src/store/states/common/saga/editDiscussion.ts b/src/store/states/common/saga/editDiscussion.ts index c4fd5f2dab..ce42805aa9 100644 --- a/src/store/states/common/saga/editDiscussion.ts +++ b/src/store/states/common/saga/editDiscussion.ts @@ -10,6 +10,7 @@ export function* editDiscussion( ) { const { payload } = action; + const commonId = payload.commonId; try { const files = yield FileService.uploadFiles(payload.payload.files || []); const images = yield FileService.uploadFiles(payload.payload.images || []); @@ -32,14 +33,14 @@ export function* editDiscussion( ); yield put(actions.setCommonAction(null)); - yield put(actions.editDiscussion.success(discussion)); + yield put(actions.editDiscussion.success({ discussion, commonId })); if (payload.callback) { payload.callback(null, discussion); } } catch (error) { if (isError(error)) { - yield put(actions.editDiscussion.failure(error)); + yield put(actions.editDiscussion.failure({ error, commonId })); if (payload.callback) { payload.callback(error); diff --git a/src/store/states/common/saga/getFeedItems.ts b/src/store/states/common/saga/getFeedItems.ts index 40342f7bd0..687cc55fdd 100644 --- a/src/store/states/common/saga/getFeedItems.ts +++ b/src/store/states/common/saga/getFeedItems.ts @@ -22,7 +22,9 @@ export function* getFeedItems( } = action; try { - const currentFeedItems = (yield select(selectFeedItems)) as FeedItems; + const currentFeedItems = (yield select( + selectFeedItems(commonId), + )) as FeedItems; const cachedFeedState = yield select(selectFeedStateByCommonId(commonId)); const user = (yield select(selectUser())) as User | null; const userId = user?.uid; @@ -48,6 +50,7 @@ export function* getFeedItems( }, }, sharedFeedItemId, + commonId, }), ); return; @@ -80,15 +83,16 @@ export function* getFeedItems( firstDocTimestamp: isFirstRequest ? firstDocTimestamp : currentFeedItems.firstDocTimestamp, + commonId, }), ); if (!isFirstRequest) { - yield searchFetchedFeedItems(convertedData); + yield searchFetchedFeedItems({ data: convertedData, commonId }); } } catch (error) { if (isError(error)) { - yield put(actions.getFeedItems.failure(error)); + yield put(actions.getFeedItems.failure({ error, commonId })); } } } diff --git a/src/store/states/common/saga/getPinnedFeedItems.ts b/src/store/states/common/saga/getPinnedFeedItems.ts index ea3ce2591f..f3f1569324 100644 --- a/src/store/states/common/saga/getPinnedFeedItems.ts +++ b/src/store/states/common/saga/getPinnedFeedItems.ts @@ -29,11 +29,12 @@ export function* getPinnedFeedItems( yield put( actions.getPinnedFeedItems.success({ data: convertedData, + commonId, }), ); } catch (error) { if (isError(error)) { - yield put(actions.getPinnedFeedItems.failure(error)); + yield put(actions.getPinnedFeedItems.failure({ error, commonId })); } } } diff --git a/src/store/states/common/saga/searchFeedItems.ts b/src/store/states/common/saga/searchFeedItems.ts index 34609ddc58..dd6f9dbfc2 100644 --- a/src/store/states/common/saga/searchFeedItems.ts +++ b/src/store/states/common/saga/searchFeedItems.ts @@ -10,15 +10,18 @@ import { FeedItems } from "../types"; export function* searchFeedItems( action: ReturnType, ) { - const searchValue = action.payload.toLowerCase(); + const searchValue = action.payload.searchValue.toLowerCase(); + const commonId = action.payload.commonId; if (!searchValue) { - yield put(actions.resetSearchState()); + yield put(actions.resetSearchState({ commonId })); return; } const feedItems = (yield select(selectFeedItems)) as FeedItems; - const pinnedFeedItems = (yield select(selectPinnedFeedItems)) as FeedItems; + const pinnedFeedItems = (yield select( + selectPinnedFeedItems(commonId), + )) as FeedItems; const discussionStates = yield select(selectDiscussionStates()); const proposalStates = yield select(selectProposalStates()); const projectStates = yield select(selectCommonStates()); @@ -57,10 +60,13 @@ export function* searchFeedItems( yield put( actions.setSearchState({ - searchValue, - isSearching: false, - feedItems: filteredFeedItems, - pinnedFeedItems: filteredPinnedFeedItems, + state: { + searchValue, + isSearching: false, + feedItems: filteredFeedItems, + pinnedFeedItems: filteredPinnedFeedItems, + }, + commonId, }), ); } diff --git a/src/store/states/common/saga/searchFetchedFeedItems.ts b/src/store/states/common/saga/searchFetchedFeedItems.ts index 236dfce8ab..3fc0ac432a 100644 --- a/src/store/states/common/saga/searchFetchedFeedItems.ts +++ b/src/store/states/common/saga/searchFetchedFeedItems.ts @@ -46,14 +46,22 @@ function* doesProjectMatchSearchValue(searchValue: string, projectId: string) { return Boolean(projectState?.data?.name.toLowerCase().includes(searchValue)); } -export function* searchFetchedFeedItems(feedItems: FeedItemFollowLayoutItem[]) { - const searchValue = (yield select(selectFeedSearchValue)).toLowerCase(); +export function* searchFetchedFeedItems({ + data: feedItems, + commonId, +}: { + data: FeedItemFollowLayoutItem[]; + commonId: string; +}) { + const searchValue = (yield select( + selectFeedSearchValue(commonId), + )).toLowerCase(); if (!searchValue) { return; } - yield put(actions.setIsSearchingFeedItems(true)); + yield put(actions.setIsSearchingFeedItems({ isSearching: true, commonId })); const resultFeedItemIds: string[] = []; const discussionIdsToFetch: string[] = []; @@ -114,14 +122,16 @@ export function* searchFetchedFeedItems(feedItems: FeedItemFollowLayoutItem[]) { .map((discussion) => discussion!.id); yield put( - actions.updateSearchFeedItems([ - ...resultFeedItemIds, - ...resultFeedDiscussionIds, - ]), + actions.updateSearchFeedItems({ + itemIds: [...resultFeedItemIds, ...resultFeedDiscussionIds], + commonId, + }), ); } catch (error) { Logger.error(error); } finally { - yield put(actions.setIsSearchingFeedItems(false)); + yield put( + actions.setIsSearchingFeedItems({ isSearching: false, commonId }), + ); } } diff --git a/src/store/states/common/selectors.ts b/src/store/states/common/selectors.ts index 025cf24e45..6b983302d7 100644 --- a/src/store/states/common/selectors.ts +++ b/src/store/states/common/selectors.ts @@ -3,51 +3,74 @@ import { AppState } from "@/shared/interfaces"; export const selectCommonState = (state: AppState) => state.common; export const selectCommonAction = (state: AppState) => - state.common.commonAction; - -export const selectCommonMember = (state: AppState) => - state.common.commonMember; - -export const selectGovernance = (state: AppState) => state.common.governance; - -export const selectDiscussionCreationData = (state: AppState) => - state.common.discussionCreation.data; - -export const selectIsDiscussionCreationLoading = (state: AppState) => - state.common.discussionCreation.loading; - -export const selectProposalCreationData = (state: AppState) => - state.common.proposalCreation.data; - -export const selectIsProposalCreationLoading = (state: AppState) => - state.common.proposalCreation.loading; - -export const selectFeedItems = (state: AppState) => state.common.feedItems; - -export const selectPinnedFeedItems = (state: AppState) => - state.common.pinnedFeedItems; - -export const selectFilteredFeedItems = (state: AppState) => - state.common.searchState.feedItems; - -export const selectFilteredPinnedFeedItems = (state: AppState) => - state.common.searchState.pinnedFeedItems; - -export const selectFeedSearchValue = (state: AppState) => - state.common.searchState.searchValue; - -export const selectIsSearchingFeedItems = (state: AppState) => - state.common.searchState.isSearching; - -export const selectIsNewProjectCreated = (state: AppState) => - state.common.isNewProjectCreated; - -export const selectSharedFeedItem = (state: AppState) => - state.common.sharedFeedItem; + state.common.commonAction || null; + +export const selectCommonMember = (commonId: string) => (state: AppState) => + state.common.commonMembers[commonId] || {}; + +export const selectGovernance = (commonId: string) => (state: AppState) => + state.common.governance[commonId] || {}; + +export const selectDiscussionCreationData = + (commonId: string) => (state: AppState) => + state.common.discussionCreations[commonId]?.data || null; + +export const selectIsDiscussionCreationLoading = + (commonId: string) => (state: AppState) => + state.common.discussionCreations[commonId]?.loading || false; + +export const selectProposalCreationData = + (commonId: string) => (state: AppState) => + state.common.proposalCreations[commonId]?.data || null; + +export const selectIsProposalCreationLoading = + (commonId: string) => (state: AppState) => + state.common.proposalCreations[commonId]?.loading || false; + +export const selectFeedItems = (commonId: string) => (state: AppState) => + state.common.feedItems[commonId] || { + data: null, + loading: false, + hasMore: false, + firstDocTimestamp: null, + lastDocTimestamp: null, + batchNumber: 0, + }; + +export const selectPinnedFeedItems = + (commonId: string) => (state: AppState) => { + const pinnedFeedItems = state.common.pinnedFeedItems[commonId]; + return { + data: pinnedFeedItems?.data || [], + loading: pinnedFeedItems?.loading || false, + }; + }; + +export const selectFilteredFeedItems = + (commonId: string) => (state: AppState) => + state.common.searchState[commonId]?.feedItems || null; + +export const selectFilteredPinnedFeedItems = + (commonId: string) => (state: AppState) => + state.common.searchState?.[commonId]?.pinnedFeedItems ?? null; + +export const selectFeedSearchValue = (commonId: string) => (state: AppState) => + state.common.searchState[commonId]?.searchValue || ""; + +export const selectIsSearchingFeedItems = + (commonId: string) => (state: AppState) => + state.common.searchState[commonId]?.isSearching || false; + +export const selectIsNewProjectCreated = + (commonId: string) => (state: AppState) => + state.common.isNewProjectCreated[commonId] || {}; + +export const selectSharedFeedItem = (commonId: string) => (state: AppState) => + state.common.sharedFeedItem[commonId] || null; export const selectRecentStreamId = (state: AppState) => - state.common.recentStreamId; + state.common.recentStreamId || ""; export const selectRecentAssignedCircle = - (memberId: string) => (state: AppState) => - state.common.recentAssignedCircleByMember[memberId]; + (commonId: string, memberId: string) => (state: AppState) => + state.common.recentAssignedCircleByMember[commonId]?.[memberId] || {}; diff --git a/src/store/states/common/types.ts b/src/store/states/common/types.ts index 0d9eee745d..8d32f682bc 100644 --- a/src/store/states/common/types.ts +++ b/src/store/states/common/types.ts @@ -40,17 +40,23 @@ export interface CommonSearchState { } export interface CommonState { - feedItems: FeedItems; - pinnedFeedItems: PinnedFeedItems; - sharedFeedItemId: string | null; - sharedFeedItem: FeedItemFollowLayoutItem | null; + feedItems: Record; + pinnedFeedItems: Record; + sharedFeedItem: Record; commonAction: CommonAction | null; - discussionCreation: EntityCreation; - proposalCreation: EntityCreation; - isNewProjectCreated: boolean; - commonMember: CommonMember | null; - governance: Governance | null; + discussionCreations: Record< + string, + EntityCreation + >; + proposalCreations: Record< + string, + EntityCreation + >; + isNewProjectCreated: Record; + sharedFeedItemId: Record; + commonMembers: Record; + recentAssignedCircleByMember: Record>; + governance: Record; recentStreamId: string; - recentAssignedCircleByMember: Record; - searchState: CommonSearchState; + searchState: Record; }