adding conversation list
This commit is contained in:
@@ -16,16 +16,16 @@ import { useAsyncFn } from 'react-use';
|
||||
import { useImmer } from 'use-immer';
|
||||
|
||||
interface IConversationContext {
|
||||
conversations: ConversationMap;
|
||||
conversationMap: ConversationMap;
|
||||
|
||||
selectedConversation?: MasterConversation;
|
||||
// handleSetConversation?: (conversationId: string) => void;
|
||||
selectConversation?: (conversationId: string, temporaryOverrideSort?: boolean) => Promise<void>;
|
||||
|
||||
handleStartConversation?: (otherUsers: User[]) => void;
|
||||
handleStartConversation?: (otherUsers: User[], conversationName?: string) => Promise<void>;
|
||||
}
|
||||
|
||||
const ConversationContext = React.createContext<IConversationContext>({
|
||||
conversations: {},
|
||||
conversationMap: {},
|
||||
});
|
||||
|
||||
export function ConversationProvider({ children }: { children: React.ReactNode }) {
|
||||
@@ -100,7 +100,7 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
||||
);
|
||||
|
||||
const handleStartConversation = useCallback(
|
||||
async (otherUsers: User[]) => {
|
||||
async (otherUsers: User[], conversationName?: string) => {
|
||||
try {
|
||||
/** group conversation
|
||||
* 1. create it
|
||||
@@ -133,7 +133,7 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
||||
}
|
||||
|
||||
const createdConversationResult = await createConversation(
|
||||
new CreateConversationRequest(otherUsers),
|
||||
new CreateConversationRequest(otherUsers, conversationName),
|
||||
);
|
||||
|
||||
selectConversation(createdConversationResult.data.conversationId.toString());
|
||||
@@ -144,7 +144,7 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
||||
toast.error(error.message);
|
||||
}
|
||||
},
|
||||
[conversationMap, selectConversation],
|
||||
[selectConversation],
|
||||
);
|
||||
|
||||
// todo: open up a handler for children
|
||||
@@ -162,7 +162,12 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
||||
|
||||
return (
|
||||
<ConversationContext.Provider
|
||||
value={{ conversations: conversationMap, handleStartConversation, selectedConversation }}
|
||||
value={{
|
||||
conversationMap,
|
||||
handleStartConversation,
|
||||
selectedConversation,
|
||||
selectConversation,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ConversationContext.Provider>
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
import {
|
||||
Avatar,
|
||||
AvatarGroup,
|
||||
Box,
|
||||
Button,
|
||||
CircularProgress,
|
||||
Divider,
|
||||
IconButton,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemButton,
|
||||
ListSubheader,
|
||||
Stack,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { FiActivity, FiCircle, FiSun } from 'react-icons/fi';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { useKeyPressEvent, useRendersCount } from 'react-use';
|
||||
|
||||
import Conversation from '@nirvana/core/models/conversation.model';
|
||||
import ConversationLabel from '../subcomponents/ConversationLabel';
|
||||
import KeyboardShortcutLabel from '../subcomponents/KeyboardShortcutLabel';
|
||||
import { MasterConversation } from '../util/types';
|
||||
import { NirvanaRules } from '../util/rules';
|
||||
import { SUPPORT_DISPLAY_NAME } from '../util/support';
|
||||
import useAuth from '../providers/AuthProvider';
|
||||
import useConversations from '../providers/ConversationProvider';
|
||||
import useTerminal from './Terminal';
|
||||
|
||||
// sort conversations based on the different data sources: type, conversations, audio clips, etc.
|
||||
|
||||
/**
|
||||
*
|
||||
* @param lookingForSomeone: if a conversation id has been selected and we are looking for it
|
||||
* @returns
|
||||
*/
|
||||
export function ConversationList() {
|
||||
// const { handleOmniSearch } = useTerminal();
|
||||
|
||||
const { conversationMap } = useConversations();
|
||||
|
||||
const rendersCount = useRendersCount();
|
||||
console.warn('RENDER COUNT | CONVERSATION LIST | ', rendersCount);
|
||||
|
||||
// don't actually dial, just show nirvana support there
|
||||
// const handleQuickDialSupport = useCallback(() => {
|
||||
// handleOmniSearch(SUPPORT_DISPLAY_NAME);
|
||||
// }, [handleOmniSearch]);
|
||||
|
||||
if (Object.keys(conversationMap).length === 0) {
|
||||
return (
|
||||
<Stack direction={'column'} alignItems="center">
|
||||
<Typography align="center" variant="caption">
|
||||
Look for someone by name or email to start a conversation!
|
||||
</Typography>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Button variant={'text'}>Click here to say hi to our team!</Button>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<List
|
||||
subheader={
|
||||
<ListSubheader>
|
||||
<FiActivity />
|
||||
<Typography variant="subtitle2"> Priority</Typography>
|
||||
</ListSubheader>
|
||||
}
|
||||
>
|
||||
{Object.values(conversationMap).map((currentConversation, index) => (
|
||||
<ConversationRow
|
||||
key={`${currentConversation._id.toString()}-priorityConvoList`}
|
||||
conversation={currentConversation}
|
||||
index={index}
|
||||
/>
|
||||
))}
|
||||
</List>
|
||||
|
||||
{/* <Divider /> */}
|
||||
|
||||
{/* <List
|
||||
sx={{
|
||||
pt: 2,
|
||||
}}
|
||||
subheader={
|
||||
<ListSubheader>
|
||||
<FiInbox />
|
||||
<Typography variant="subtitle2"> Inbox</Typography>
|
||||
</ListSubheader>
|
||||
}
|
||||
></List> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param index is used for keyboard shortcut if this convo row is in a list
|
||||
* @returns
|
||||
*/
|
||||
export function ConversationRow({
|
||||
conversation,
|
||||
index,
|
||||
}: {
|
||||
conversation: MasterConversation;
|
||||
index?: number;
|
||||
}) {
|
||||
const { user } = useAuth();
|
||||
|
||||
const { selectedConversation, selectConversation } = useConversations();
|
||||
|
||||
const rendersCount = useRendersCount();
|
||||
console.warn('RENDER COUNT | CONVERSATION LIST ROW | ', rendersCount);
|
||||
|
||||
const keyboardShortcut = useMemo(() => {
|
||||
if (index < NirvanaRules.topXConversationsWithShortcuts) {
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}, [index]);
|
||||
|
||||
const handleSelectConversation = useCallback(() => {
|
||||
selectConversation(conversation._id.toString(), false);
|
||||
}, [conversation, selectConversation]);
|
||||
|
||||
useKeyPressEvent(`${keyboardShortcut?.toString()}`, handleSelectConversation);
|
||||
|
||||
return (
|
||||
<ListItem>
|
||||
<ListItemButton
|
||||
selected={selectedConversation?._id.toString() === conversation._id.toString()}
|
||||
onClick={handleSelectConversation}
|
||||
>
|
||||
{conversation.tunedInUsers?.length > 0 ? (
|
||||
<Box sx={{ color: 'primary.main', fontSize: 15, ml: 0 }}>
|
||||
<FiSun />
|
||||
</Box>
|
||||
) : (
|
||||
<Box sx={{ color: 'GrayText', fontSize: 10, ml: 0 }}>
|
||||
<FiCircle />
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Stack
|
||||
direction={'row'}
|
||||
spacing={1}
|
||||
sx={{ ml: 2, mr: 'auto', color: 'GrayText', overflow: 'auto' }}
|
||||
>
|
||||
{keyboardShortcut && <KeyboardShortcutLabel label={keyboardShortcut.toString()} />}
|
||||
|
||||
<ConversationLabel
|
||||
users={conversation.members ?? []}
|
||||
conversationName={conversation.name}
|
||||
isSelected={selectedConversation?._id.toString() === conversation._id.toString()}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
<ListItemAvatar>
|
||||
<AvatarGroup variant={'rounded'}>
|
||||
{conversation.members?.map((conversationUser, index) => (
|
||||
<Avatar
|
||||
key={`${conversation._id.toString()}-${conversationUser._id.toString()}-convoIcon`}
|
||||
alt={conversationUser?.givenName}
|
||||
src={conversationUser?.picture}
|
||||
sx={{
|
||||
width: 30,
|
||||
height: 30,
|
||||
opacity: conversation.tunedInUsers?.includes(conversationUser._id.toString())
|
||||
? '100%'
|
||||
: '20%',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</AvatarGroup>
|
||||
</ListItemAvatar>
|
||||
|
||||
{/* <Typography variant={'caption'}>20 sec</Typography> */}
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
@@ -97,14 +97,21 @@ export default function NewConversationDialog() {
|
||||
|
||||
setIsSubmitting(true);
|
||||
|
||||
handleStartConversation(selectedUsers);
|
||||
await handleStartConversation(selectedUsers, conversationName);
|
||||
|
||||
// clear form for next time
|
||||
setSelectedUsers([]);
|
||||
setConversationName('');
|
||||
|
||||
setIsSubmitting(false);
|
||||
}, [selectedUsers, setConversationName, conversationName, setSelectedUsers, setIsSubmitting]);
|
||||
}, [
|
||||
selectedUsers,
|
||||
setConversationName,
|
||||
conversationName,
|
||||
setSelectedUsers,
|
||||
setIsSubmitting,
|
||||
handleStartConversation,
|
||||
]);
|
||||
|
||||
return (
|
||||
<Dialog fullScreen open={page === 'START_NEW_CONVERSATION'} onClose={handleSetPage('WELCOME')}>
|
||||
|
||||
Reference in New Issue
Block a user