diff --git a/src/pages/commonFeed/components/HeaderContent/components/ActionsButton/ActionsButton.tsx b/src/pages/commonFeed/components/HeaderContent/components/ActionsButton/ActionsButton.tsx index 5047ad139e..fce9e0ac3a 100644 --- a/src/pages/commonFeed/components/HeaderContent/components/ActionsButton/ActionsButton.tsx +++ b/src/pages/commonFeed/components/HeaderContent/components/ActionsButton/ActionsButton.tsx @@ -6,6 +6,7 @@ import { CirclesPermissions, Common, CommonMember } from "@/shared/models"; import { DesktopMenu, MenuButton } from "@/shared/ui-kit"; import { StaticLinkType, generateStaticShareLink } from "@/shared/utils"; import { useMenuItems } from "./hooks"; +import { useUpdateCommonSeenState } from "@/shared/hooks/useCases"; interface ActionsButtonProps { common: Common; @@ -22,6 +23,7 @@ const ActionsButton: FC = (props) => { onOpen: onShareModalOpen, onClose: onShareModalClose, } = useModal(false); + const { markCommonAsSeen } = useUpdateCommonSeenState(); const items = useMenuItems( { common, @@ -33,6 +35,7 @@ const ActionsButton: FC = (props) => { share: onShareModalOpen, onFollowToggle: commonFollow.onFollowToggle, onSearchClick, + markCommonAsSeen }, ); const shareLink = generateStaticShareLink(StaticLinkType.Common, common); diff --git a/src/pages/commonFeed/components/HeaderContent/components/ActionsButton/hooks/useMenuItems.tsx b/src/pages/commonFeed/components/HeaderContent/components/ActionsButton/hooks/useMenuItems.tsx index 0eb66064cd..e36c7305e7 100644 --- a/src/pages/commonFeed/components/HeaderContent/components/ActionsButton/hooks/useMenuItems.tsx +++ b/src/pages/commonFeed/components/HeaderContent/components/ActionsButton/hooks/useMenuItems.tsx @@ -2,6 +2,7 @@ import React from "react"; import { CommonFollowState } from "@/shared/hooks/useCases"; import { FollowIcon, + Message3Icon, SearchIcon, Share3Icon, UnfollowIcon, @@ -17,6 +18,7 @@ interface Actions { share: () => void; onSearchClick?: () => void; onFollowToggle: CommonFollowState["onFollowToggle"]; + markCommonAsSeen: (commonId: string) => void; } export const useMenuItems = ( @@ -24,7 +26,7 @@ export const useMenuItems = ( actions: Actions, ): Item[] => { const { common } = options; - const { share, onFollowToggle, onSearchClick } = actions; + const { share, onFollowToggle, onSearchClick, markCommonAsSeen } = actions; const items: Item[] = [ { @@ -51,6 +53,18 @@ export const useMenuItems = ( onClick: () => onFollowToggle(), icon: , }, + { + id: CommonFeedMenuItem.MarkRead, + text: "Mark all as read", + onClick: () => { + if (!common.id) { + return; + } + + markCommonAsSeen(common.id); + }, + icon: , + }, ]; return getAllowedItems(items, options); diff --git a/src/pages/commonFeed/constants/commonFeedMenuItem.ts b/src/pages/commonFeed/constants/commonFeedMenuItem.ts index 6aea242f55..3dde29d002 100644 --- a/src/pages/commonFeed/constants/commonFeedMenuItem.ts +++ b/src/pages/commonFeed/constants/commonFeedMenuItem.ts @@ -3,4 +3,5 @@ export enum CommonFeedMenuItem { Share = "share", Follow = "follow", Mute = "mute", + MarkRead = "markRead", } diff --git a/src/pages/commonFeed/utils/getAllowedItems.ts b/src/pages/commonFeed/utils/getAllowedItems.ts index 0e02ecc1e2..8be993be32 100644 --- a/src/pages/commonFeed/utils/getAllowedItems.ts +++ b/src/pages/commonFeed/utils/getAllowedItems.ts @@ -20,6 +20,7 @@ const MENU_ITEM_TO_CHECK_FUNCTION_MAP: Record< !isFollowInProgress && Boolean(commonMember && !commonMember.isFollowing), [CommonFeedMenuItem.Mute]: ({ commonMember, isFollowInProgress }) => !isFollowInProgress && Boolean(commonMember?.isFollowing), + [CommonFeedMenuItem.MarkRead]: () => true, }; export const getAllowedItems = (items: Item[], options: Options): Item[] => diff --git a/src/services/Common.ts b/src/services/Common.ts index 2c053e6a87..7429ff78d6 100644 --- a/src/services/Common.ts +++ b/src/services/Common.ts @@ -609,6 +609,19 @@ class CommonService { return snapshot.data() || null; }; + + public markCommonAsSeen = async ( + commonId: string, + userId: string, + ): Promise => { + await Api.post( + ApiEndpoint.MarkCommonSeenForUser, + { + commonId, + userId + }, + ); + }; } export default new CommonService(); diff --git a/src/shared/constants/endpoint.ts b/src/shared/constants/endpoint.ts index 45ac8aab6c..cf5c27a9af 100644 --- a/src/shared/constants/endpoint.ts +++ b/src/shared/constants/endpoint.ts @@ -8,6 +8,7 @@ export const ApiEndpoint = { CreateCommon: "/commons/create", UpdateCommon: "/commons/update", CreateSubCommon: "/commons/subcommon/create", + MarkCommonSeenForUser: "/commons/mark-seen-for-user", MarkFeedObjectSeenForUser: "/commons/mark-feed-object-seen-for-user", MarkFeedObjectUnseenForUser: "/commons/mark-feed-object-unseen-for-user", LinkStream: "/commons/link-stream", diff --git a/src/shared/hooks/useCases/index.ts b/src/shared/hooks/useCases/index.ts index 3b63789e06..683dbce471 100644 --- a/src/shared/hooks/useCases/index.ts +++ b/src/shared/hooks/useCases/index.ts @@ -47,5 +47,6 @@ export { useEligibleVoters } from "./useEligibleVoters"; export { useDiscussionMessageReaction } from "./useDiscussionMessageReaction"; export { useChatMessageReaction } from "./useChatMessageReaction"; export { useUserReaction } from "./useUserReaction"; +export { useUpdateCommonSeenState } from "./useUpdateCommonSeenState"; export * from "./useCommonFollow"; export * from "./usePreloadDiscussionMessagesById"; diff --git a/src/shared/hooks/useCases/useUpdateCommonSeenState.ts b/src/shared/hooks/useCases/useUpdateCommonSeenState.ts new file mode 100644 index 0000000000..fc7b1f91e5 --- /dev/null +++ b/src/shared/hooks/useCases/useUpdateCommonSeenState.ts @@ -0,0 +1,43 @@ +import { useCallback } from "react"; +import { useSelector } from "react-redux"; +import { selectUser } from "@/pages/Auth/store/selectors"; +import { CommonService } from "@/services"; +import useNotification from "../useNotification"; + +interface Return { + markCommonAsSeen: ( + commonId: string, + delay?: number, + ) => ReturnType; +} + +export const useUpdateCommonSeenState = (): Return => { + const user = useSelector(selectUser()); + const userId = user?.uid; + const { notify } = useNotification(); + + const updateSeenState = async ( + commonId: string, + ) => { + if (!userId) { + return; + } + + try { + await CommonService.markCommonAsSeen(commonId, userId); + } catch (error) { + notify("Something went wrong"); + } + }; + + const markCommonAsSeen = useCallback( + (commonId: string, delay = 0) => { + return setTimeout(() => { + updateSeenState(commonId); + }, delay); + }, + [userId], + ); + + return { markCommonAsSeen }; +};