nice sort of display of priority convos and such

This commit is contained in:
talksik
2022-06-20 11:24:12 -05:00
parent 76f7446f46
commit 1953687805
3 changed files with 174 additions and 156 deletions
@@ -64,6 +64,10 @@ function useSocketFire() {
interface IConversationContext {
conversationMap: ConversationMap;
// sorted conversation lists
priorityConversations: MasterConversation[];
inboxConversations: MasterConversation[];
selectedConversation?: MasterConversation;
selectConversation?: (conversationId: string, temporaryOverrideSort?: boolean) => Promise<void>;
@@ -72,6 +76,8 @@ interface IConversationContext {
const ConversationContext = React.createContext<IConversationContext>({
conversationMap: {},
priorityConversations: [],
inboxConversations: [],
});
export function ConversationProvider({ children }: { children: React.ReactNode }) {
@@ -339,6 +345,43 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
return tunedConversations;
}, [conversationMap, user]);
const masterConversations = useMemo(() => {
const priorityConversations: MasterConversation[] = [];
const inboxConversations: MasterConversation[] = [];
Object.values(conversationMap).forEach((currentMasterConversation) => {
const personalConvoMember = currentMasterConversation.members.find(
(mem) => mem._id.toString() === user._id.toString(),
);
if (personalConvoMember && personalConvoMember.memberState === 'priority') {
priorityConversations.push(currentMasterConversation);
return;
}
inboxConversations.push(currentMasterConversation);
});
// sort each list
inboxConversations.sort((a, b) => {
if (a.temporaryOverrideSort) {
return 1;
}
if (b.temporaryOverrideSort) {
return -1;
}
// sort by which ones have new activity for me
// then sort by last activity date
});
priorityConversations.sort((a, b) => {
return b.createdDate.getTime() - a.createdDate.getTime();
});
return [priorityConversations, inboxConversations];
}, [conversationMap, user]);
if (fetchState.error) {
return (
<Typography variant={'h6'} color={'danger'}>
@@ -354,6 +397,8 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
handleStartConversation,
selectedConversation,
selectConversation,
priorityConversations: masterConversations[0],
inboxConversations: masterConversations[1],
}}
>
{children}
+2 -70
View File
@@ -41,7 +41,7 @@ export function ConversationList() {
const { omniSearch } = useSearch();
const { conversationMap } = useConversations();
const { conversationMap, inboxConversations } = useConversations();
const rendersCount = useRendersCount();
// console.warn('RENDER COUNT | CONVERSATION LIST | ', rendersCount);
@@ -51,43 +51,6 @@ export function ConversationList() {
omniSearch(SUPPORT_DISPLAY_NAME);
}, [omniSearch]);
const masterConversations = useMemo(() => {
const priorityConversations: MasterConversation[] = [];
const inboxConversations: MasterConversation[] = [];
Object.values(conversationMap).forEach((currentMasterConversation) => {
const personalConvoMember = currentMasterConversation.members.find(
(mem) => mem._id.toString() === user._id.toString(),
);
if (personalConvoMember && personalConvoMember.memberState === 'priority') {
priorityConversations.push(currentMasterConversation);
return;
}
inboxConversations.push(currentMasterConversation);
});
// sort each list
inboxConversations.sort((a, b) => {
if (a.temporaryOverrideSort) {
return 1;
}
if (b.temporaryOverrideSort) {
return -1;
}
// sort by which ones have new activity for me
// then sort by last activity date
});
priorityConversations.sort((a, b) => {
return b.createdDate.getTime() - a.createdDate.getTime();
});
return [priorityConversations, inboxConversations];
}, [conversationMap, user]);
if (Object.keys(conversationMap).length === 0) {
return (
<Stack direction={'column'} alignItems="center">
@@ -123,37 +86,6 @@ export function ConversationList() {
<Divider />
<List
sx={{
pt: 2,
}}
subheader={
<ListSubheader>
<FiActivity />
<Typography variant="subtitle2"> Priority</Typography>
</ListSubheader>
}
>
{masterConversations[0].length === 0 && (
<Stack direction={'column'} alignItems="center">
<Typography align="center" variant="caption">
Mark conversations as priority to hear them across the hall.
</Typography>
</Stack>
)}
{masterConversations[0].map((currentConversation, index) => (
<ConversationRow
key={`${currentConversation._id.toString()}-priorityConvoList`}
conversation={currentConversation}
index={index}
isPriority={true}
/>
))}
</List>
<Divider />
<List
sx={{
pt: 2,
@@ -165,7 +97,7 @@ export function ConversationList() {
</ListSubheader>
}
>
{masterConversations[1].map((currentConversation, index) => (
{inboxConversations.map((currentConversation, index) => (
<ConversationRow
key={`${currentConversation._id.toString()}-inboxConvoList`}
conversation={currentConversation}
+127 -86
View File
@@ -39,9 +39,10 @@ import {
FiVideoOff,
FiX,
} from 'react-icons/fi';
import React, { useCallback, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import ConversationLabel from '../subcomponents/ConversationLabel';
import { MasterConversation } from '../util/types';
import { SUPPORT_DISPLAY_NAME } from '../util/support';
import { blueGrey } from '@mui/material/colors';
import useAuth from '../providers/AuthProvider';
@@ -53,7 +54,7 @@ import useZen from '../providers/ZenProvider';
export default function FooterControls() {
const { handleFlowState } = useZen();
const { selectedConversation } = useConversations();
const { selectedConversation, priorityConversations } = useConversations();
const { user, handleLogout } = useAuth();
const [openUserSettings, setOpenUserSettings] = useState<boolean>(false);
@@ -69,6 +70,18 @@ export default function FooterControls() {
setOpenUserSettings(false);
}, [setOpenUserSettings]);
// is there a selected conversation and if so, is it a priority one?
const isSelectedConversationPriority = useMemo(() => {
const priorityIds =
priorityConversations.map((priorityConvo) => priorityConvo._id.toString()) ?? [];
if (selectedConversation && priorityIds.includes(selectedConversation._id.toString())) {
return true;
}
return false;
}, [selectedConversation, priorityConversations]);
return (
<Box
sx={{
@@ -90,93 +103,23 @@ export default function FooterControls() {
p: 1,
flex: 1,
}}
spacing={2}
>
{selectedConversation && (
<Stack
direction={'column'}
spacing={1}
sx={{
p: 1,
borderRadius: 2,
bgcolor: blueGrey[300],
}}
alignItems={'center'}
>
{/* status */}
<Box
component={'span'}
sx={{
bgcolor: (theme) => theme.palette.secondary.main,
height: 5,
width: 5,
borderRadius: 100,
}}
/>
<AvatarGroup
variant={'rounded'}
sx={{
display: 'flex',
flexDirection: 'column',
'& >:first-child': {
marginTop: 0,
},
'& > *': {
marginLeft: '0 !important' as any,
marginTop: -2,
},
}}
>
{selectedConversation.members?.map((conversationUser, index) => (
<Avatar
key={`${selectedConversation._id.toString()}-${conversationUser._id.toString()}-convoIcon`}
alt={conversationUser?.givenName}
src={conversationUser?.picture}
sx={{
opacity: selectedConversation.tunedInUsers?.includes(
conversationUser._id.toString(),
)
? '100%'
: '20%',
}}
/>
))}
</AvatarGroup>
{priorityConversations.map((masterPriorityConversation) => (
<OverlayConversation
key={`priorityConversationOverlay-${masterPriorityConversation._id.toString()}`}
masterConversation={masterPriorityConversation}
isSelected={
masterPriorityConversation._id.toString() === selectedConversation?._id.toString()
}
/>
))}
{selectedConversation && !isSelectedConversationPriority && (
<>
<Divider orientation="horizontal" flexItem />
<Tooltip title="Show video!">
<IconButton
sx={{
color: 'white',
}}
size="small"
>
<FiVideoOff />
</IconButton>
</Tooltip>
{/* todo: not speaking mode, speaking mode, locked in mode */}
<Tooltip title="Speak or toggle by clicking here!">
<IconButton
sx={{
color: 'white',
}}
size="small"
>
<FiSun />
</IconButton>
</Tooltip>
<IconButton
sx={{
color: 'GrayText',
}}
size="small"
>
<FiX />
</IconButton>
</Stack>
<OverlayConversation masterConversation={selectedConversation} isSelected={true} />
</>
)}
<Stack sx={{ mt: 'auto' }} spacing={1} direction={'column'} alignItems={'center'}>
@@ -222,6 +165,104 @@ export default function FooterControls() {
);
}
function OverlayConversation({
masterConversation,
isSelected = false,
}: {
masterConversation: MasterConversation;
isSelected?: boolean;
}) {
return (
<Stack
direction={'column'}
spacing={1}
sx={{
p: 1,
borderRadius: 2,
bgcolor: isSelected ? blueGrey[300] : '',
}}
alignItems={'center'}
>
{/* status */}
<Box
component={'span'}
sx={{
bgcolor: (theme) => theme.palette.secondary.main,
height: 5,
width: 5,
borderRadius: 100,
}}
/>
<AvatarGroup
variant={'rounded'}
sx={{
display: 'flex',
flexDirection: 'column',
'& >:first-child': {
marginTop: 0,
},
'& > *': {
marginLeft: '0 !important' as any,
marginTop: -2,
},
}}
>
{masterConversation.members?.map((conversationUser, index) => (
<Avatar
key={`${masterConversation._id.toString()}-${conversationUser._id.toString()}-convoIcon`}
alt={conversationUser?.givenName}
src={conversationUser?.picture}
sx={{
opacity: masterConversation.tunedInUsers?.includes(conversationUser._id.toString())
? '100%'
: '20%',
}}
/>
))}
</AvatarGroup>
{isSelected && (
<>
<Divider orientation="horizontal" flexItem />
<Tooltip title="Show video!">
<IconButton
sx={{
color: 'white',
}}
size="small"
>
<FiVideoOff />
</IconButton>
</Tooltip>
{/* todo: not speaking mode, speaking mode, locked in mode */}
<Tooltip title="Speak or toggle by clicking here!">
<IconButton
sx={{
color: 'white',
}}
size="small"
>
<FiSun />
</IconButton>
</Tooltip>
<IconButton
sx={{
color: 'GrayText',
}}
size="small"
>
<FiX />
</IconButton>
</>
)}
</Stack>
);
}
const NO_DEVICE_SELECTION = 'NA';
function UserSettingsDialog({ open, handleClose }: { handleClose: () => void; open: boolean }) {