From 72c40309ce32843a1f29f169b4974e5088576916 Mon Sep 17 00:00:00 2001 From: choidabom <48302257+choidabom@users.noreply.github.com> Date: Wed, 7 Aug 2024 00:16:59 +0900 Subject: [PATCH] Fix 'Additional Users' Popover Display Logic for Profile Clicks (#270) * Modify profile click functionality to only show 'Additional Users' popover when more than 4 users are present * Separate UserPresence component from DocumentHeader component * Fix code format --- .../src/components/headers/DocumentHeader.tsx | 87 ++---------------- .../src/components/headers/UserPresence.tsx | 92 +++++++++++++++++++ 2 files changed, 101 insertions(+), 78 deletions(-) create mode 100644 frontend/src/components/headers/UserPresence.tsx diff --git a/frontend/src/components/headers/DocumentHeader.tsx b/frontend/src/components/headers/DocumentHeader.tsx index 35adc01f..e10bcaad 100644 --- a/frontend/src/components/headers/DocumentHeader.tsx +++ b/frontend/src/components/headers/DocumentHeader.tsx @@ -4,8 +4,6 @@ import VerticalSplitIcon from "@mui/icons-material/VerticalSplit"; import VisibilityIcon from "@mui/icons-material/Visibility"; import { AppBar, - Avatar, - AvatarGroup, IconButton, Paper, Stack, @@ -13,14 +11,8 @@ import { ToggleButtonGroup, Toolbar, Tooltip, - Popover, - Typography, - List, - ListItem, - ListItemAvatar, - ListItemText, } from "@mui/material"; -import { useEffect, useState } from "react"; +import { useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useNavigate } from "react-router-dom"; import { useList } from "react-use"; @@ -31,6 +23,12 @@ import { YorkieCodeMirrorPresenceType } from "../../utils/yorkie/yorkieSync"; import DownloadMenu from "../common/DownloadMenu"; import ShareButton from "../common/ShareButton"; import ThemeButton from "../common/ThemeButton"; +import UserPresence from "./UserPresence"; + +export type Presence = { + clientID: ActorID; + presence: YorkieCodeMirrorPresenceType; +}; function DocumentHeader() { const dispatch = useDispatch(); @@ -46,12 +44,7 @@ function DocumentHeader() { clear: clearPresenceList, filter: filterPresenceList, }, - ] = useList<{ - clientID: ActorID; - presence: YorkieCodeMirrorPresenceType; - }>([]); - - const [anchorEl, setAnchorEl] = useState(null); + ] = useList([]); useEffect(() => { if (editorState.shareRole === "READ") { @@ -96,20 +89,6 @@ function DocumentHeader() { navigate(`/${workspaceState.data?.slug}`); }; - // Display additional users in a popover when there are more than 4 users - const handleOpenPopover = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - - // Display None additional users in a popover when there are more than 4 users - const handleClosePopover = () => { - setAnchorEl(null); - }; - - const popoverOpen = Boolean(anchorEl); - - const hiddenAvatars = presenceList.slice(3); - return ( @@ -151,55 +130,7 @@ function DocumentHeader() { - - {presenceList?.map((presence) => ( - - - {presence.presence.name[0]} - - - ))} - - - - Additional Users - - {hiddenAvatars.map((presence) => ( - - - - {presence.presence.name[0]} - - - - - ))} - - - + {!editorState.shareRole && } diff --git a/frontend/src/components/headers/UserPresence.tsx b/frontend/src/components/headers/UserPresence.tsx new file mode 100644 index 00000000..503ed430 --- /dev/null +++ b/frontend/src/components/headers/UserPresence.tsx @@ -0,0 +1,92 @@ +import { + Avatar, + AvatarGroup, + ListItem, + ListItemAvatar, + ListItemText, + Paper, + Popover, + Tooltip, + Typography, +} from "@mui/material"; +import { useState } from "react"; +import { Presence } from "./DocumentHeader"; + +interface UserPresenceProps { + presenceList: Presence[]; +} + +function UserPresence(props: UserPresenceProps) { + const { presenceList } = props; + const [anchorEl, setAnchorEl] = useState(null); + const popoverOpen = Boolean(anchorEl); + + const handleOpenPopover = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const handleClosePopover = () => { + setAnchorEl(null); + }; + + const MAX_VISIBLE_AVATARS = 4; + const hiddenAvatars = presenceList.slice(MAX_VISIBLE_AVATARS); + + const renderAvatar = (presence: Presence) => ( + + + {presence.presence.name[0]} + + + ); + + return ( + <> + + {presenceList.slice(0, MAX_VISIBLE_AVATARS).map(renderAvatar)} + {presenceList.length > MAX_VISIBLE_AVATARS && ( + + +{presenceList.length - MAX_VISIBLE_AVATARS} + + )} + + + + Additional Users + {hiddenAvatars.map((presence) => ( + + + + {presence.presence.name[0]} + + + + + ))} + + + + ); +} + +export default UserPresence;