import { Avatar, AvatarGroup, Box, Button, CircularProgress, Container, Dialog, Divider, FormControl, FormHelperText, IconButton, InputLabel, MenuItem, Select, Stack, Switch, Tooltip, Typography, } from '@mui/material'; import { FiChevronsLeft, FiChevronsRight, FiCircle, FiRss, FiSettings, FiSun, FiVideo, FiVideoOff, FiX, FiZap, FiZapOff, } from 'react-icons/fi'; import { MasterConversation, RoomMap } from '../util/types'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { ConversationUserMember } from '@nirvana/core/models/conversation.model'; import { SUPPORT_DISPLAY_NAME } from '../util/support'; import { blueGrey } from '@mui/material/colors'; import useAuth from '../providers/AuthProvider'; import useConversations from '../providers/ConversationProvider'; import useDevices from '../hooks/useDevices'; import useElectron from '../providers/ElectronProvider'; import useSearch from '../providers/SearchProvider'; import useZen from '../providers/ZenProvider'; export default function FooterControls() { const { handleFlowState } = useZen(); const { selectedConversation, priorityConversations, userLocalStream, handleToggleVideo } = useConversations(); const { user, handleLogout } = useAuth(); const { handleToggleDesktopMode, desktopMode } = useElectron(); const [openUserSettings, setOpenUserSettings] = useState(false); const handleTurnOnFlowState = useCallback(() => { // when in overlay mode, we need to toggle main app and then go into flow state if (desktopMode === 'overlayOnly') { handleToggleDesktopMode(); } handleFlowState(); }, [handleFlowState, desktopMode, handleToggleDesktopMode]); const handleClickProfile = useCallback( (event: React.MouseEvent) => { if (desktopMode === 'overlayOnly') { handleToggleDesktopMode(); } setOpenUserSettings(true); }, [setOpenUserSettings, handleToggleDesktopMode, desktopMode], ); const handleCloseUserSettings = useCallback(() => { 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]); const localVideoRef = useRef(null); useEffect(() => { if (localVideoRef?.current && userLocalStream) { localVideoRef.current.srcObject = userLocalStream; } }, [localVideoRef, userLocalStream]); return ( {priorityConversations.map((masterPriorityConversation) => ( ))} {selectedConversation && !isSelectedConversationPriority && ( <> )} {userLocalStream ? : } {userLocalStream ? ( ) : ( )} {desktopMode === 'overlayOnly' ? : } ); } function OverlayConversation({ masterConversation, isSelected = false, }: { masterConversation: MasterConversation; isSelected?: boolean; }) { const { user } = useAuth(); const { selectConversation, handleEscape, updateConversationPriority, userLocalStream } = useConversations(); const handleSelectConversation = useCallback(() => { if (!isSelected) { selectConversation(masterConversation._id.toString(), false); } }, [masterConversation, selectConversation, isSelected]); const isPriority = useMemo(() => { const personalConvoMember = masterConversation.members.find( (mem) => mem._id.toString() === user._id.toString(), ); if (personalConvoMember && personalConvoMember.memberState === 'priority') { return true; } return false; }, [masterConversation, user]); const handleToggleConversationZap = useCallback(() => { if (isPriority) { updateConversationPriority(masterConversation._id.toString(), 'inbox'); return; } updateConversationPriority(masterConversation._id.toString(), 'priority'); }, [updateConversationPriority, isPriority, masterConversation._id]); const userVideoRef = useRef(null); useEffect(() => { // }, []); return ( theme.transitions.create(['background-color', 'transform'], { duration: theme.transitions.duration.standard, }), cursor: 'pointer', '&:hover': { bgcolor: blueGrey[300], }, }} onClick={handleSelectConversation} alignItems={'center'} > {/* status */} theme.palette.secondary.main, height: 5, width: 5, borderRadius: 100, }} /> {isSelected && ( <> {isPriority ? : } {isPriority ? : } )} ); } function OverlayConversationAvatars({ conversationUserMembers, tunedInUserIds, isConversationSelected, roomPeers, localStreamToPeers, }: { isConversationSelected: boolean; tunedInUserIds: string[]; conversationUserMembers: ConversationUserMember[]; roomPeers: RoomMap; localStreamToPeers: MediaStream; }) { const { user } = useAuth(); const sortedMembers = useMemo(() => { const sortedUserMembers = [...conversationUserMembers]; sortedUserMembers.sort((convoUserA, convoUserB) => { if (convoUserA._id.toString() === user?._id.toString()) return 2; if (tunedInUserIds?.includes(convoUserA._id.toString())) return 1; if (tunedInUserIds?.includes(convoUserB._id.toString())) return -1; return -2; }); return sortedUserMembers; }, [conversationUserMembers, user, tunedInUserIds]); console.log(roomPeers); return ( :first-child': { marginTop: 0, }, '& > *': { marginLeft: '0 !important' as any, marginTop: -2, }, }} max={3} > {sortedMembers?.map((conversationUserMember, index) => ( ))} ); } function OverlayConversationAvatar({ conversationUserMember, isTunedIn, isConversationSelected, isConnecting, localStreamToPeers, }: { conversationUserMember: ConversationUserMember; isTunedIn: boolean; isConversationSelected: boolean; // if user is connecting or just have this conversation selected isConnecting: boolean; // if we are calling or receiving call from this person and still connecting localStreamToPeers: MediaStream; // the local stream that is casted to each peer }) { const { user } = useAuth(); const localVideoRef = useRef(null); useEffect(() => { if (localVideoRef?.current && localStreamToPeers) { localVideoRef.current.srcObject = localStreamToPeers; } }, [localVideoRef, localStreamToPeers]); console.log(isConnecting); if (isConnecting) { return ; } if (conversationUserMember._id.toString() === user._id.toString() && localStreamToPeers) { return ( ); } return ( ); return <>; } const NO_DEVICE_SELECTION = 'NA'; function UserSettingsDialog({ open, handleClose }: { handleClose: () => void; open: boolean }) { const { user, handleLogout } = useAuth(); const devices = useDevices(); const { omniSearch } = useSearch(); const handleQuickDialSupport = useCallback(() => { omniSearch(SUPPORT_DISPLAY_NAME); handleClose(); }, [omniSearch, handleClose]); return ( Media Settings Microphone Please select distinct speaker and microphone to avoid distortion when you have a bluetooth device connected. Video Questions? Help, feedback, and more? Account ); }