nirvana support really awesome right there!

This commit is contained in:
talksik
2022-05-30 10:45:58 -05:00
parent 946334dd60
commit 522cf40cf7
6 changed files with 147 additions and 186 deletions
@@ -1,25 +1,33 @@
/* eslint-disable jsx-a11y/media-has-caption */
import { blueGrey } from '@mui/material/colors';
import React, { useState, useEffect, useMemo } from 'react';
import { joinConversation, leaveConversation } from '../firebase/firestore';
import useAuth from '../providers/AuthProvider';
import { useImmer } from 'use-immer';
import useTerminal from './Terminal';
import { User } from '@nirvana/core/src/models/user.model';
import {
Stack,
IconButton,
Typography,
AvatarGroup,
Avatar,
AvatarGroup,
Box,
Container,
Fab,
IconButton,
Paper,
Stack,
Typography,
} from '@mui/material';
import { FiSun, FiMoreVertical, FiPlay, FiCloudRain } from 'react-icons/fi';
import { FiCloudRain, FiMoreVertical, FiPlay, FiSun } from 'react-icons/fi';
import React, { useEffect, useMemo, useState } from 'react';
import { joinConversation, leaveConversation } from '../firebase/firestore';
import ConversationLabel from '../subcomponents/ConversationLabel';
import { User } from '@nirvana/core/src/models/user.model';
/* eslint-disable jsx-a11y/media-has-caption */
import { blueGrey } from '@mui/material/colors';
import useAuth from '../providers/AuthProvider';
import { useImmer } from 'use-immer';
import { useRendersCount } from 'react-use';
import useTerminal from './Terminal';
/**
* nice convo history
* - chunk has max of 1 minute
* - put current clip in next chunk if previous clip was more than 4 hours ago
* - put current clip in next chunk if it's after my last active date here
*/
export default function ConversationDetails() {
const { user } = useAuth();
@@ -1,38 +1,40 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
Avatar,
AvatarGroup,
Badge,
Box,
CircularProgress,
Divider,
IconButton,
Input,
List,
ListItem,
ListItemAvatar,
ListItemButton,
ListItemSecondaryAction,
ListItemText,
ListSubheader,
Stack,
Typography,
Input,
CircularProgress,
IconButton,
Box,
Tooltip,
ListItemSecondaryAction,
AvatarGroup,
Typography,
} from '@mui/material';
import { blueGrey } from '@mui/material/colors';
import { FiActivity, FiInbox, FiSearch, FiUsers, FiCoffee, FiCircle, FiSun } from 'react-icons/fi';
import NirvanaAvatar from './NirvanaAvatar';
import { FiActivity, FiCircle, FiCoffee, FiInbox, FiSearch, FiSun, FiUsers } from 'react-icons/fi';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useDebounce, useKey, useRendersCount } from 'react-use';
import { useSnackbar } from 'notistack';
import KeyboardShortcutLabel from './KeyboardShortcutLabel';
import { searchUsers } from '../firebase/firestore';
import { User } from '@nirvana/core/src/models/user.model';
import useTerminal from './Terminal';
import Conversation from '@nirvana/core/src/models/conversation.model';
import ConversationLabel from '../subcomponents/ConversationLabel';
import KeyboardShortcutLabel from './KeyboardShortcutLabel';
import NirvanaAvatar from './NirvanaAvatar';
import { User } from '@nirvana/core/src/models/user.model';
import { blueGrey } from '@mui/material/colors';
import { searchUsers } from '../firebase/firestore';
import useAuth from '../providers/AuthProvider';
import { useImmer } from 'use-immer';
import ConversationLabel from '../subcomponents/ConversationLabel';
import { useSnackbar } from 'notistack';
import useTerminal from './Terminal';
// sort conversations based on the different data sources: type, conversations, audio clips, etc.
/**
*
@@ -1,28 +1,29 @@
import {
Box,
Stack,
IconButton,
Avatar,
Tooltip,
Switch,
Button,
AvatarGroup,
Box,
Button,
Divider,
Fab,
IconButton,
ListItemIcon,
Typography,
Menu,
MenuItem,
Stack,
Switch,
Tooltip,
Typography,
} from '@mui/material';
import { blueGrey } from '@mui/material/colors';
import { FiHeadphones, FiHelpCircle, FiLogOut, FiSun } from 'react-icons/fi';
import React, { useCallback } from 'react';
import React from 'react';
import { FiHeadphones, FiSun, FiLogOut } from 'react-icons/fi';
import ConversationLabel from '../subcomponents/ConversationLabel';
import useTerminal from './Terminal';
import { blueGrey } from '@mui/material/colors';
import useAuth from '../providers/AuthProvider';
import useTerminal from './Terminal';
export default function FooterControls() {
const { selectedConversation } = useTerminal();
const { selectedConversation, handleOmniSearch } = useTerminal();
const { user, logout } = useAuth();
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
@@ -34,6 +35,10 @@ export default function FooterControls() {
setAnchorEl(null);
};
const handleQuickDialSupport = useCallback(() => {
handleOmniSearch('Nirvana Support');
}, [handleOmniSearch]);
return (
<Box
sx={{
@@ -158,36 +163,17 @@ export default function FooterControls() {
id="account-menu"
open={open}
onClose={handleCloseProfileMenu}
onClick={handleCloseProfileMenu}
PaperProps={{
elevation: 0,
sx: {
overflow: 'visible',
filter: 'drop-shadow(0px 2px 8px rgba(0,0,0,0.32))',
mt: 1.5,
'& .MuiAvatar-root': {
width: 32,
height: 32,
ml: -0.5,
mr: 1,
},
'&:before': {
content: '""',
display: 'block',
position: 'absolute',
top: 0,
right: 14,
width: 10,
height: 10,
bgcolor: 'background.paper',
transform: 'translateY(-50%) rotate(45deg)',
zIndex: 0,
},
},
}}
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
transformOrigin={{ horizontal: 'right', vertical: 'bottom' }}
anchorOrigin={{ horizontal: 'right', vertical: 'top' }}
>
<MenuItem onClick={handleQuickDialSupport}>
<ListItemIcon>
<FiHelpCircle />
</ListItemIcon>
<Typography>Help</Typography>
</MenuItem>
<Divider />
<MenuItem onClick={logout}>
<ListItemIcon>
<FiLogOut />
+43 -85
View File
@@ -1,36 +1,32 @@
import React, { useContext, useState, useCallback, useMemo, useEffect } from 'react';
import {
Avatar,
AvatarGroup,
Box,
Button,
Dialog,
Divider,
Fab,
Grid,
IconButton,
Tooltip,
Stack,
Divider,
List,
ListItem,
ListItemAvatar,
Button,
ListItemButton,
ListItemIcon,
ListItemSecondaryAction,
ListItemText,
ListSubheader,
Typography,
Menu,
MenuItem,
ListItemIcon,
Fab,
Stack,
Switch,
Dialog,
AvatarGroup,
Tooltip,
Typography,
} from '@mui/material';
import { blueGrey } from '@mui/material/colors';
import { FiZap, FiHeadphones, FiLogOut, FiMonitor, FiSun } from 'react-icons/fi';
import { useSnackbar } from 'notistack';
import Conversation from '@nirvana/core/src/models/conversation.model';
import useAuth from '../providers/AuthProvider';
import { ContentBlock, ContentType } from '@nirvana/core/src/models/content.model';
import { FiHeadphones, FiLogOut, FiMonitor, FiSun, FiZap } from 'react-icons/fi';
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { Unsubscribe, onSnapshot } from 'firebase/firestore';
import {
createOneOnOneConversation,
getConversationContentQueryLIVE,
@@ -39,21 +35,23 @@ import {
searchUsers,
sendContentBlockToConversation,
} from '../firebase/firestore';
import { useImmer } from 'use-immer';
import { User } from '@nirvana/core/src/models/user.model';
import { onSnapshot, Unsubscribe } from 'firebase/firestore';
import { useDebounce, useKeyPressEvent, useRendersCount, useUnmount } from 'react-use';
import { uploadAudioClip } from '../firebase/firebaseStorage';
import { ContentBlock, ContentType } from '@nirvana/core/src/models/content.model';
import Navbar from './Navbar';
import MainPanel from './MainPanel';
import { ConversationList } from './ConversationList';
import NewConversationDialog from './NewConversationDialog';
import { createGroupConversation } from '../firebase/firestore';
import Conversation from '@nirvana/core/src/models/conversation.model';
import ConversationLabel from '../subcomponents/ConversationLabel';
import { ConversationList } from './ConversationList';
import FooterControls from './FooterControls';
import MainPanel from './MainPanel';
import Navbar from './Navbar';
import NewConversationDialog from './NewConversationDialog';
import { User } from '@nirvana/core/src/models/user.model';
import { blueGrey } from '@mui/material/colors';
import { createGroupConversation } from '../firebase/firestore';
import { uploadAudioClip } from '../firebase/firebaseStorage';
import useAuth from '../providers/AuthProvider';
import { useImmer } from 'use-immer';
import { useSnackbar } from 'notistack';
type ConversationMap = {
[conversationId: string]: Conversation;
};
@@ -84,6 +82,8 @@ interface ITerminalContext {
handleShowCreateConvoForm?: () => void;
handleEscape?: () => void;
handleOmniSearch?: (searchQuery: string) => void; // handle searching for anything globally
}
const TerminalContext = React.createContext<ITerminalContext>({
@@ -106,60 +106,6 @@ const handleOnStartRecording = (e: BlobEvent) => {
audioChunks = [];
};
// TODOS
// fetch all conversations that I am part of
// create a convo
// 1. search
// 2. click on person
// 3. search database if there is already a convo for this
// - if yes: select this one
// - if no: create one
// 4. show the conversation details page show on right
// 5. connect live if other person there
// 6. send first clip
// 7. display all blocks/clips for convo simple and separate
// if no conversations, show stale state + create one with nirvana
// 1. create group conversation page
// you know what to do...simple row of selected users...dropdown options should show searched user list
// use material selects for this dropdown to avoid all the work...and hide select-like things
// 2. auto select that conversation and have it show up
// 3. allow adding name when creating convo
// 4.
// 5. convo settings: add people (simple add method with firestore), change name | max 8 people
/**
* Streaming stuff:
* - join a stream room if 2 or more in the list
* - leave on unmount
* - timer to unselect a conversation after 30 minutes...no fancy checking if user is there/active
* - show little control to see if
*/
/**
*
* media stuff:
* - paste image + view in history + with modal nice and big
* - paste a link + see in a content block
* - paste link of image and have it save as image
*/
/**
*
* tech debt: now go back and make convo line and side panel name and icons and all legit
*/
/**
* nice convo history
* - chunk has max of 1 minute
* - put current clip in next chunk if previous clip was more than 4 hours ago
* - put current clip in next chunk if it's after my last active date here
*/
// sort based on the different data sources: conversations, audio clips, etc.
// todo: extract each use effect to custom hook and will be clean
export function TerminalProvider({ children }: { children?: React.ReactNode }) {
const { enqueueSnackbar } = useSnackbar();
@@ -493,14 +439,25 @@ export function TerminalProvider({ children }: { children?: React.ReactNode }) {
[searchVal, enqueueSnackbar, setSearchUsersResults, user],
);
const handleChangeSearchInput = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const handleOmniSearch = useCallback(
(searchQuery: string) => {
if (!searchQuery) {
return;
}
setSearching(true);
setSearchVal(e.target.value.replace('/', ''));
setSearchVal(searchQuery.replace('/', ''));
},
[setSearching, setSearchVal],
);
const handleChangeSearchInput = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
handleOmniSearch(e.target.value);
},
[handleOmniSearch],
);
const selectConversation = useCallback(
(conversationId: string) => setSelectedConversationId(conversationId),
[setSelectedConversationId],
@@ -571,6 +528,7 @@ export function TerminalProvider({ children }: { children?: React.ReactNode }) {
createConversationMode,
handleShowCreateConvoForm,
handleEscape,
handleOmniSearch,
}}
>
<Stack direction={'column'} sx={{ flex: 1 }}>
+29 -29
View File
@@ -1,39 +1,40 @@
//TODO: move all of this to core or common and separate out files
import {
setDoc,
getFirestore,
doc,
collection,
QueryDocumentSnapshot,
Timestamp,
FieldValue,
getDoc,
query,
where,
getDocs,
orderBy,
limit,
startAt,
endAt,
addDoc,
arrayUnion,
updateDoc,
arrayRemove,
serverTimestamp,
} from 'firebase/firestore';
import { User as FirebaseUser } from 'firebase/auth';
import { firestoreDb } from './connect';
import { User } from '@nirvana/core/src/models/user.model';
import Conversation, {
ConversationMember,
MemberMap,
MemberRole,
MemberState,
} from '@nirvana/core/src/models/conversation.model';
import useAuth from '../providers/AuthProvider';
import {
FieldValue,
QueryDocumentSnapshot,
Timestamp,
addDoc,
arrayRemove,
arrayUnion,
collection,
doc,
endAt,
getDoc,
getDocs,
getFirestore,
limit,
orderBy,
query,
serverTimestamp,
setDoc,
startAt,
updateDoc,
where,
} from 'firebase/firestore';
import { ContentBlock } from '@nirvana/core/src/models/content.model';
import { User as FirebaseUser } from 'firebase/auth';
import { User } from '@nirvana/core/src/models/user.model';
import { firestoreDb } from './connect';
import { toTitleCase } from '../util/text';
import useAuth from '../providers/AuthProvider';
interface Document {
id: string;
@@ -108,8 +109,7 @@ export const searchUsers = async (searchQuery: string): Promise<User[] | undefin
limit(5),
);
const nameManipulatedQuery =
searchQuery[0].toUpperCase() + searchQuery.slice(1).toLocaleLowerCase();
const nameManipulatedQuery = toTitleCase(searchQuery);
const nameSearchQuery = query(
db.users,
orderBy('displayName'),
+7
View File
@@ -0,0 +1,7 @@
export const toTitleCase = (str: string) => {
return str
.toLowerCase()
.split(' ')
.map((s) => s.charAt(0).toUpperCase() + s.substring(1))
.join(' ');
};