refactor manageParticipants

This commit is contained in:
Abhinav 2023-07-12 14:28:35 +05:30
parent c55dc07913
commit 061d0a6d61
14 changed files with 376 additions and 500 deletions

View file

@ -357,7 +357,9 @@
"MODIFY_SHARING": "Modify sharing",
"ADD_COLLABORATORS": "Add collaborators",
"ADD_NEW_EMAIL": "Add a new email",
"SHARE_WITH_PEOPLE":"Share with specific people",
"shared_with_people_zero" :"Share with specific people",
"shared_with_people_one": "Shared with 1 person",
"shared_with_people_other": "Shared with {{count, number}} people",
"ADD_VIEWERS":"Add viewers",
"PARTICIPANTS": " Participants",
"CHANGE_PERMISSIONS_TO_VIEWER": "<p>{{selectedEmail}} will not be able to add more photos to the album</p> <p>They will still be able to remove photos added by them</p>",
@ -373,6 +375,7 @@
"REMOVE_PARTICIPANT_HEAD": "Remove participant",
"OWNER": "Owner",
"COLLABORATORS": "Collaborators",
"ADD_MORE": "Add more",
"VIEWERS": "Viewers",
"OR_ADD_EXISTING": "or an add existing one",
"REMOVE_PARTICIPANT_MESSAGE": "<p>{{selectedEmail}} will be removed from the album</p> <p>Any photos added by them will also be removed from the album</p>",

View file

@ -141,56 +141,64 @@ export default function AddParticipantForm(props: AddParticipantFormProps) {
autoComplete={props.autoComplete}
/>
</Stack>
<Stack>
<MenuSectionTitle title={t('OR_ADD_EXISTING')} />
<MenuItemGroup>
{updatedOptionsList.map((item, index) => (
<>
<EnteMenuItem
fontWeight="normal"
key={item}
onClick={() => {
if (
{updatedOptionsList.length > 0 && (
<Stack>
<MenuSectionTitle
title={t('OR_ADD_EXISTING')}
/>
<MenuItemGroup>
{updatedOptionsList.map((item, index) => (
<>
<EnteMenuItem
fontWeight="normal"
key={item}
onClick={() => {
if (
values.selectedOptions.includes(
item
)
) {
setFieldValue(
'selectedOptions',
values.selectedOptions.filter(
(
selectedOption
) =>
selectedOption !==
item
)
);
} else {
setFieldValue(
'selectedOptions',
[
...values.selectedOptions,
item,
]
);
}
}}
label={item}
startIcon={
<Avatar email={item} />
}
endIcon={
values.selectedOptions.includes(
item
)
) {
setFieldValue(
'selectedOptions',
values.selectedOptions.filter(
(selectedOption) =>
selectedOption !==
item
)
);
} else {
setFieldValue(
'selectedOptions',
[
...values.selectedOptions,
item,
]
);
) ? (
<DoneIcon />
) : null
}
}}
label={item}
startIcon={<Avatar email={item} />}
endIcon={
values.selectedOptions.includes(
item
) ? (
<DoneIcon />
) : null
}
/>
{index !==
props.optionsList.length - 1 && (
<MenuItemDivider />
)}
</>
))}
</MenuItemGroup>
</Stack>
/>
{index !==
props.optionsList.length -
1 && <MenuItemDivider />}
</>
))}
</MenuItemGroup>
</Stack>
)}
<FormHelperText
sx={{

View file

@ -1,90 +0,0 @@
import { Box, Typography } from '@mui/material';
import React, { useEffect, useState } from 'react';
import { t } from 'i18next';
import { Collection } from 'types/collection';
import { MenuItemGroup } from 'components/Menu/MenuItemGroup';
import { EnteMenuItem } from 'components/Menu/EnteMenuItem';
import Avatar from 'components/pages/gallery/Avatar';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import MenuItemDivider from 'components/Menu/MenuItemDivider';
import AddCollab from './AddCollab';
import ModeEditIcon from '@mui/icons-material/ModeEdit';
import ManageParticipantsRole from './ManageParticipantsRole';
interface Iprops {
collection: Collection;
onRootClose: () => void;
collectionUnshare: (email: string) => Promise<void>;
}
export function CollaboratorParticipants({
collection,
onRootClose,
collectionUnshare,
}: Iprops) {
if (!collection.sharees?.length) {
return <></>;
}
const [collaborators, setCollaborators] = useState([]);
const [participantRoleView, setParticipantRoleView] = useState(false);
const [selectedEmail, setSelectedEmail] = useState('');
const openParticipantRoleView = (email) => {
setParticipantRoleView(true);
setSelectedEmail(email);
};
const closeParticipantRoleView = () => {
setParticipantRoleView(false);
};
useEffect(() => {
const collaboratorEmails =
collection.sharees
?.filter((sharee) => sharee.role === 'COLLABORATOR')
.map((sharee) => sharee.email) || [];
setCollaborators(collaboratorEmails);
}, [collection.sharees]);
return (
<Box mb={3}>
<Typography color="text.muted" variant="small" padding={1}>
<ModeEditIcon style={{ fontSize: 20, marginRight: 8 }} />
{t('Collaborators')}
</Typography>
<MenuItemGroup>
{collaborators.map((item, index) => (
<>
<EnteMenuItem
fontWeight="normal"
key={item}
onClick={() => openParticipantRoleView(item)}
label={item}
startIcon={<Avatar email={item} />}
endIcon={<ChevronRightIcon />}
/>
{index !== collaborators.length - 1 && (
<MenuItemDivider />
)}
</>
))}
<AddCollab
open
onClose={() => {}}
collection={collection}
onRootClose={onRootClose}
/>
</MenuItemGroup>
<ManageParticipantsRole
collectionUnshare={collectionUnshare}
open={participantRoleView}
collection={collection}
onRootClose={onRootClose}
onClose={closeParticipantRoleView}
selectedEmail={selectedEmail} // Pass the selected email to ManageParticipantsRole
/>
</Box>
);
}

View file

@ -1,100 +1,222 @@
import { Stack, Typography, styled } from '@mui/material';
import { Stack } from '@mui/material';
import { COLLECTION_ROLE, Collection } from 'types/collection';
import { EnteDrawer } from 'components/EnteDrawer';
import { t } from 'i18next';
import { DialogProps } from '@mui/material';
import Titlebar from 'components/Titlebar';
import { useContext, useState } from 'react';
import { AppContext } from 'pages/_app';
import { GalleryContext } from 'pages/gallery';
import { unshareCollection } from 'services/collectionService';
import { EnteMenuItem } from 'components/Menu/EnteMenuItem';
import { MenuItemGroup } from 'components/Menu/MenuItemGroup';
import { Collection } from 'types/collection';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import { useState } from 'react';
import { t } from 'i18next';
import Avatar from 'components/pages/gallery/Avatar';
import MenuSectionTitle from 'components/Menu/MenuSectionTitle';
import AdminPanelSettingsIcon from '@mui/icons-material/AdminPanelSettings';
import ModeEditIcon from '@mui/icons-material/ModeEdit';
import MenuItemDivider from 'components/Menu/MenuItemDivider';
import NumberAvatar from '@mui/material/Avatar';
import ManageParticipantsOptions from './ManageParticipantsOptions';
import Workspaces from '@mui/icons-material/Workspaces';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import ModifyParticipant from './ModifyParticipant';
import AddParticipant from './AddParticipant';
import { useRef } from 'react';
import Add from '@mui/icons-material/Add';
interface Iprops {
collection: Collection;
open: boolean;
onClose: () => void;
onRootClose: () => void;
peopleCount: number;
}
const AvatarContainer = styled('div')({
position: 'relative',
display: 'flex',
alignItems: 'center',
marginLeft: -5,
});
const AvatarContainerOuter = styled('div')({
position: 'relative',
display: 'flex',
alignItems: 'center',
marginLeft: 8,
});
const AvatarCounter = styled(NumberAvatar)({
height: 20,
width: 20,
fontSize: 10,
color: '#fff',
});
export default function ManageParticipants({
open,
collection,
onClose,
onRootClose,
peopleCount,
}: Iprops) {
const [manageAddViewer, setManageAddViewer] = useState(false);
const closeManageAddViewer = () => setManageAddViewer(false);
const openManageAddViewer = () => setManageAddViewer(true);
const peopleCount = collection.sharees.length;
const appContext = useContext(AppContext);
const galleryContext = useContext(GalleryContext);
const [addParticipantView, setAddParticipantView] = useState(false);
const [participantRoleView, setParticipantRoleView] = useState(false);
const [selectedEmail, setSelectedEmail] = useState('');
const closeAddParticipant = () => setAddParticipantView(false);
const openAddParticipant = () => setAddParticipantView(true);
const participantType = useRef<
COLLECTION_ROLE.COLLABORATOR | COLLECTION_ROLE.VIEWER
>();
const openAddCollab = () => {
participantType.current = COLLECTION_ROLE.COLLABORATOR;
openAddParticipant();
};
const openAddViewer = () => {
participantType.current = COLLECTION_ROLE.VIEWER;
openAddParticipant();
};
const handleRootClose = () => {
onClose();
onRootClose();
};
const handleDrawerClose: DialogProps['onClose'] = (_, reason) => {
if (reason === 'backdropClick') {
handleRootClose();
} else {
onClose();
}
};
const collectionUnshare = async (email: string) => {
try {
appContext.startLoading();
await unshareCollection(collection, email);
await galleryContext.syncWithRemote(false, true);
} finally {
appContext.finishLoading();
}
};
const ownerEmail =
galleryContext.user.id === collection.owner?.id
? galleryContext.user.email
: collection.owner?.email;
const isOwner = galleryContext.user.id === collection.owner?.id;
const collaborators = collection.sharees
?.filter((sharee) => sharee.role === COLLECTION_ROLE.COLLABORATOR)
.map((sharee) => sharee.email);
const viewers =
collection.sharees
?.filter((sharee) => sharee.role === COLLECTION_ROLE.VIEWER)
.map((sharee) => sharee.email) || [];
const openParticipantRoleView = (email) => {
setParticipantRoleView(true);
setSelectedEmail(email);
};
const closeParticipantRoleView = () => {
setParticipantRoleView(false);
};
const shareeCount = collection.sharees?.length || 0;
const extraShareeCount = Math.max(0, shareeCount - 6);
return (
<>
<Stack>
<Typography color="text.muted" variant="small" padding={1}>
<Workspaces style={{ fontSize: 17, marginRight: 8 }} />
{t(`Shared with ${peopleCount} people`)}
</Typography>
<MenuItemGroup>
<EnteMenuItem
startIcon={
<AvatarContainerOuter>
{collection.sharees
?.slice(0, 6)
.map((sharee) => (
<AvatarContainer key={sharee.email}>
<Avatar
key={sharee.email}
email={sharee.email}
/>
</AvatarContainer>
))}
{extraShareeCount > 0 && (
<AvatarContainer key="extra-count">
<AvatarCounter>
+{extraShareeCount}
</AvatarCounter>
</AvatarContainer>
)}
</AvatarContainerOuter>
}
onClick={openManageAddViewer}
label={
collection.sharees.length === 1
? t(collection.sharees[0]?.email)
: null
}
endIcon={<ChevronRightIcon />}
<EnteDrawer anchor="right" open={open} onClose={handleDrawerClose}>
<Stack spacing={'4px'} py={'12px'}>
<Titlebar
onClose={onClose}
title={collection.name}
onRootClose={handleRootClose}
caption={`${peopleCount}${t('PARTICIPANTS')} `}
/>
<MenuItemDivider hasIcon={true} />
</MenuItemGroup>
</Stack>
<Stack py={'20px'} px={'12px'} spacing={'24px'}>
<Stack>
<MenuSectionTitle
title={t('OWNER')}
icon={<AdminPanelSettingsIcon />}
/>
<MenuItemGroup>
<EnteMenuItem
fontWeight="normal"
onClick={() => {}}
label={isOwner ? t('YOU') : ownerEmail}
startIcon={<Avatar email={ownerEmail} />}
/>
</MenuItemGroup>
</Stack>
<Stack>
<MenuSectionTitle
title={t('COLLABORATORS')}
icon={<ModeEditIcon />}
/>
<MenuItemGroup>
{collaborators.map((item, index) => (
<>
<EnteMenuItem
key={item}
onClick={() =>
openParticipantRoleView(item)
}
label={item}
startIcon={<Avatar email={item} />}
endIcon={<ChevronRightIcon />}
/>
{index !== collaborators.length - 1 && (
<MenuItemDivider />
)}
</>
))}
<ManageParticipantsOptions
peopleCount={peopleCount}
open={manageAddViewer}
onClose={closeManageAddViewer}
<EnteMenuItem
startIcon={<Add />}
fontWeight={'bold'}
onClick={openAddCollab}
label={
collaborators?.length
? t('ADD_MORE')
: t('ADD_COLLABORATORS')
}
/>
</MenuItemGroup>
</Stack>
<Stack>
<MenuSectionTitle
title={t('VIEWERS')}
icon={<ModeEditIcon />}
/>
<MenuItemGroup>
{viewers.map((item, index) => (
<>
<EnteMenuItem
key={item}
onClick={() =>
openParticipantRoleView(item)
}
label={item}
startIcon={<Avatar email={item} />}
endIcon={<ChevronRightIcon />}
/>
{index !== collaborators.length - 1 && (
<MenuItemDivider />
)}
</>
))}
<EnteMenuItem
startIcon={<Add />}
fontWeight={'bold'}
onClick={openAddViewer}
label={
viewers?.length
? t('ADD_MORE')
: t('ADD_VIEWERS')
}
/>
</MenuItemGroup>
</Stack>
</Stack>
</Stack>
</EnteDrawer>
<ModifyParticipant
collectionUnshare={collectionUnshare}
open={participantRoleView}
collection={collection}
onRootClose={onRootClose}
onClose={closeParticipantRoleView}
selectedEmail={selectedEmail} // Pass the selected email to ManageParticipantsRole
/>
<AddParticipant
open={addParticipantView}
onClose={closeAddParticipant}
onRootClose={onRootClose}
collection={collection}
type={participantType.current}
/>
</>
);

View file

@ -1,48 +0,0 @@
import { Box } from '@mui/material';
import React, { useContext } from 'react';
import { Collection } from 'types/collection';
import { OwnerParticipant } from './OwnerParticipant';
import { ViewerParticipants } from './ViewerParticipants';
import { CollaboratorParticipants } from './CollaboratorParticipants';
import { unshareCollection } from 'services/collectionService';
import { AppContext } from 'pages/_app';
import { GalleryContext } from 'pages/gallery';
interface Iprops {
collection: Collection;
onRootClose: () => void;
}
export function ManageParticipantsList({ collection, onRootClose }: Iprops) {
if (!collection.sharees?.length) {
return <></>;
}
const appContext = useContext(AppContext);
const galleryContext = useContext(GalleryContext);
const collectionUnshare = async (email: string) => {
try {
appContext.startLoading();
await unshareCollection(collection, email);
await galleryContext.syncWithRemote(false, true);
} finally {
appContext.finishLoading();
}
};
return (
<Box mb={3}>
<OwnerParticipant collection={collection}></OwnerParticipant>
<CollaboratorParticipants
collection={collection}
onRootClose={onRootClose}
collectionUnshare={
collectionUnshare
}></CollaboratorParticipants>
<ViewerParticipants
collection={collection}
onRootClose={onRootClose}
collectionUnshare={collectionUnshare}></ViewerParticipants>
</Box>
);
}

View file

@ -1,54 +0,0 @@
import { Stack } from '@mui/material';
import { Collection } from 'types/collection';
import { EnteDrawer } from 'components/EnteDrawer';
import { t } from 'i18next';
import { DialogProps } from '@mui/material';
import Titlebar from 'components/Titlebar';
import { ManageParticipantsList } from './ManageParticipantsList';
interface Iprops {
collection: Collection;
open: boolean;
onClose: () => void;
onRootClose: () => void;
peopleCount: number;
}
export default function ManageParticipantsOptions({
open,
collection,
onClose,
onRootClose,
peopleCount,
}: Iprops) {
const handleDrawerClose: DialogProps['onClose'] = (_, reason) => {
if (reason === 'backdropClick') {
onRootClose();
} else {
onClose();
}
};
return (
<>
<EnteDrawer anchor="right" open={open} onClose={handleDrawerClose}>
<Stack spacing={'4px'} py={'12px'}>
<Titlebar
onClose={onClose}
title={collection.name}
onRootClose={onRootClose}
caption={`${peopleCount}${t('PARTICIPANTS')} `}
/>
<Stack py={'20px'} px={'8px'} spacing={'8px'}>
<ManageParticipantsList
collection={collection}
onRootClose={onRootClose}
/>
</Stack>
</Stack>
</EnteDrawer>
</>
);
}

View file

@ -28,7 +28,7 @@ interface Iprops {
collectionUnshare: (email: string) => Promise<void>;
}
export default function ManageParticipantsRole({
export default function ModifyParticipant({
collection,
open,
onClose,

View file

@ -1,55 +0,0 @@
import { Box, Typography } from '@mui/material';
import React from 'react';
import { t } from 'i18next';
import { Collection } from 'types/collection';
import { MenuItemGroup } from 'components/Menu/MenuItemGroup';
import { EnteMenuItem } from 'components/Menu/EnteMenuItem';
import Avatar from 'components/pages/gallery/Avatar';
import { User } from 'types/user';
import { LS_KEYS, getData } from 'utils/storage/localStorage';
import AdminPanelSettingsIcon from '@mui/icons-material/AdminPanelSettings';
interface Iprops {
collection: Collection;
}
export function OwnerParticipant({ collection }: Iprops) {
if (!collection.sharees?.length) {
return <></>;
}
const user: User = getData(LS_KEYS.USER);
const ownerEmail =
user.id === collection.owner?.id ? t('YOU') : collection.owner?.email;
return (
<Box mb={3}>
<Typography color="text.muted" variant="small" padding={1}>
<AdminPanelSettingsIcon
style={{ fontSize: 20, marginRight: 8 }}
/>
{t('OWNER')}
</Typography>
<MenuItemGroup>
<>
<EnteMenuItem
//
fontWeight="normal"
onClick={() => console.log('clicked', ownerEmail)}
label={ownerEmail}
startIcon={
<Avatar
email={
user.id === collection.owner?.id
? user.email
: collection.owner?.email
}
/>
}
/>
</>
</MenuItemGroup>
</Box>
);
}

View file

@ -1,96 +0,0 @@
import { Box, Stack, Typography } from '@mui/material';
import React, { useEffect, useState } from 'react';
import { t } from 'i18next';
import { Collection } from 'types/collection';
import { MenuItemGroup } from 'components/Menu/MenuItemGroup';
import { EnteMenuItem } from 'components/Menu/EnteMenuItem';
import MenuItemDivider from 'components/Menu/MenuItemDivider';
import Avatar from 'components/pages/gallery/Avatar';
import AddViewer from './AddViewer';
import PhotoIcon from '@mui/icons-material/Photo';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import ManageParticipantsRole from './ManageParticipantsRole';
interface Iprops {
collection: Collection;
onRootClose: () => void;
collectionUnshare: (email: string) => Promise<void>;
}
export function ViewerParticipants({
collection,
onRootClose,
collectionUnshare,
}: Iprops) {
if (!collection.sharees?.length) {
return <></>;
}
const [Viewers, setViewers] = useState([]);
const [participantRoleView, setParticipantRoleView] = useState(false);
const [selectedEmail, setSelectedEmail] = useState('');
const openParticipantRoleView = (email) => {
setParticipantRoleView(true);
setSelectedEmail(email);
};
const closeParticipantRoleView = () => {
setParticipantRoleView(false);
};
useEffect(() => {
const viewersEmails =
collection.sharees
?.filter((sharee) => sharee.role === 'VIEWER')
.map((sharee) => sharee.email) || [];
setViewers(viewersEmails);
}, [collection.sharees]);
return (
<>
<Stack>
<Box mb={3}>
<Typography color="text.muted" variant="small" padding={1}>
<PhotoIcon style={{ fontSize: 20, marginRight: 8 }} />
{t('VIEWERS')}
</Typography>
<MenuItemGroup>
<>
{Viewers.map((item, index) => (
<>
<EnteMenuItem
fontWeight="normal"
key={item}
onClick={() =>
openParticipantRoleView(item)
}
label={item}
startIcon={<Avatar email={item} />}
endIcon={<ChevronRightIcon />}
/>
{index !== Viewers.length - 1 && (
<MenuItemDivider />
)}
</>
))}
<AddViewer
open
onClose={() => {}}
collection={collection}
onRootClose={onRootClose}
/>
</>
</MenuItemGroup>
</Box>
</Stack>
<ManageParticipantsRole
collectionUnshare={collectionUnshare}
open={participantRoleView}
collection={collection}
onRootClose={onRootClose}
onClose={closeParticipantRoleView}
selectedEmail={selectedEmail} // Pass the selected email to ManageParticipantsRole
/>
</>
);
}

View file

@ -1,7 +1,6 @@
import React, { useState } from 'react';
import { Collection } from 'types/collection';
import React, { useRef, useState } from 'react';
import { COLLECTION_ROLE, Collection } from 'types/collection';
import ManageParticipants from './ManageParticipants';
import { Stack } from '@mui/material';
import MenuSectionTitle from 'components/Menu/MenuSectionTitle';
import { t } from 'i18next';
@ -10,8 +9,10 @@ import { MenuItemGroup } from 'components/Menu/MenuItemGroup';
import { EnteMenuItem } from 'components/Menu/EnteMenuItem';
import MenuItemDivider from 'components/Menu/MenuItemDivider';
import AddIcon from '@mui/icons-material/Add';
import AddViewer from './AddViewer';
import AddCollab from './AddCollab';
import AddParticipant from './AddParticipant';
import ManageParticipants from './ManageParticipants';
import AvatarGroup from 'components/pages/gallery/AvatarGroup';
import ChevronRight from '@mui/icons-material/ChevronRight';
export default function EmailShare({
collection,
@ -20,28 +21,55 @@ export default function EmailShare({
collection: Collection;
onRootClose: () => void;
}) {
const [addViewerView, setAddViewerView] = useState(false);
const [addCollabView, setAddCollabView] = useState(false);
const [addParticipantView, setAddParticipantView] = useState(false);
const [manageParticipantView, setManageParticipantView] = useState(false);
const closeAddViewer = () => setAddViewerView(false);
const openAddViewer = () => setAddViewerView(true);
const closeAddParticipant = () => setAddParticipantView(false);
const openAddParticipant = () => setAddParticipantView(true);
const closeAddCollab = () => setAddCollabView(false);
const openAddCollab = () => setAddCollabView(true);
const closeManageParticipant = () => setManageParticipantView(false);
const openManageParticipant = () => setManageParticipantView(true);
const participantType = useRef<
COLLECTION_ROLE.COLLABORATOR | COLLECTION_ROLE.VIEWER
>();
const openAddCollab = () => {
participantType.current = COLLECTION_ROLE.COLLABORATOR;
openAddParticipant();
};
const openAddViewer = () => {
participantType.current = COLLECTION_ROLE.VIEWER;
openAddParticipant();
};
return (
<>
<Stack>
<MenuSectionTitle
title={t('SHARE_WITH_PEOPLE')}
title={t('shared_with_people', {
count: collection.sharees?.length ?? 0,
})}
icon={<Workspaces />}
/>
<MenuItemGroup>
{collection.sharees.length > 0 ? (
<ManageParticipants
collection={collection}
onRootClose={onRootClose}
/>
<>
<EnteMenuItem
startIcon={
<AvatarGroup sharees={collection.sharees} />
}
onClick={openManageParticipant}
label={
collection.sharees.length === 1
? t(collection.sharees[0]?.email)
: null
}
endIcon={<ChevronRight />}
/>
<MenuItemDivider hasIcon />
</>
) : null}
<EnteMenuItem
startIcon={<AddIcon />}
@ -56,15 +84,17 @@ export default function EmailShare({
/>
</MenuItemGroup>
</Stack>
<AddViewer
open={addViewerView}
onClose={closeAddViewer}
<AddParticipant
open={addParticipantView}
onClose={closeAddParticipant}
onRootClose={onRootClose}
collection={collection}
type={participantType.current}
/>
<AddCollab
open={addCollabView}
onClose={closeAddCollab}
<ManageParticipants
peopleCount={collection.sharees.length}
open={manageParticipantView}
onClose={closeManageParticipant}
onRootClose={onRootClose}
collection={collection}
/>

View file

@ -44,7 +44,13 @@ function CollectionShare({ collectionSummary, ...props }: Props) {
<Stack spacing={'4px'} py={'12px'}>
<Titlebar
onClose={props.onClose}
title={t('SHARE_COLLECTION')}
title={
type ===
CollectionSummaryType.incomingShareCollaborator ||
type === CollectionSummaryType.incomingShareViewer
? t('SHARING_DETAILS')
: t('SHARE_COLLECTION')
}
onRootClose={handleRootClose}
caption={props.collection.name}
/>

View file

@ -58,7 +58,6 @@ const MapBox: React.FC<MapBoxProps> = ({
} else {
if (mapContainer && mapContainer.hasChildNodes()) {
if (mapContainer.firstChild) {
console.log('removing child');
mapContainer.removeChild(mapContainer.firstChild);
}
}

View file

@ -34,6 +34,9 @@ const Avatar: React.FC<AvatarProps> = ({ file, email }) => {
useLayoutEffect(() => {
try {
if (!file) {
return;
}
if (file.ownerID !== user.id) {
// getting email from in-memory id-email map
const email = userIDToEmailMap.get(file.ownerID);
@ -66,21 +69,21 @@ const Avatar: React.FC<AvatarProps> = ({ file, email }) => {
useLayoutEffect(() => {
try {
if (!email) {
logError(Error(), 'email not found in userIDToEmailMap');
return;
}
const id = Array.from(userIDToEmailMap.keys()).find(
(key) => userIDToEmailMap.get(key) === email
);
if (!id && user.email !== email) {
logError(Error(), `ID not found for email: ${email}`);
return;
} else if (!id && user.email === email) {
if (user.email === email) {
setUserLetter(email[0].toUpperCase());
setColorCode(PUBLIC_COLLECTED_FILES_AVATAR_COLOR_CODE);
return;
}
const id = Array.from(userIDToEmailMap.keys()).find(
(key) => userIDToEmailMap.get(key) === email
);
if (!id) {
logError(Error(), `ID not found for email: ${email}`);
return;
}
const colorIndex = id % theme.colors.avatarColors.length;
const colorCode = theme.colors.avatarColors[colorIndex];
setUserLetter(email[0].toUpperCase());

View file

@ -0,0 +1,48 @@
import { styled } from '@mui/material';
import NumberAvatar from '@mui/material/Avatar';
import Avatar from './Avatar';
import { Collection } from 'types/collection';
const AvatarContainer = styled('div')({
position: 'relative',
display: 'flex',
alignItems: 'center',
marginLeft: -5,
});
const AvatarContainerOuter = styled('div')({
position: 'relative',
display: 'flex',
alignItems: 'center',
marginLeft: 8,
});
const AvatarCounter = styled(NumberAvatar)({
height: 20,
width: 20,
fontSize: 10,
color: '#fff',
});
const SHAREE_AVATAR_LIMIT = 6;
const AvatarGroup = ({ sharees }: { sharees: Collection['sharees'] }) => {
const hasShareesOverLimit = sharees?.length > SHAREE_AVATAR_LIMIT;
const countOfShareesOverLimit = sharees?.length - SHAREE_AVATAR_LIMIT;
return (
<AvatarContainerOuter>
{sharees?.slice(0, 6).map((sharee) => (
<AvatarContainer key={sharee.email}>
<Avatar key={sharee.email} email={sharee.email} />
</AvatarContainer>
))}
{hasShareesOverLimit && (
<AvatarContainer key="extra-count">
<AvatarCounter>+{countOfShareesOverLimit}</AvatarCounter>
</AvatarContainer>
)}
</AvatarContainerOuter>
);
};
export default AvatarGroup;