race condition with search and firebase initializing

This commit is contained in:
talksik
2022-05-28 13:04:44 -05:00
parent 6b0d993e1e
commit e1584a6c0f
4 changed files with 105 additions and 11 deletions
-1
View File
@@ -9,7 +9,6 @@ import { NirvanaTheme } from './mui/NirvanaTheme';
import { ElectronProvider } from './providers/ElectronProvider';
import { AuthProvider } from './providers/AuthProvider';
import './firebase/connect';
import ErrorParent from './providers/ErrorBoundary';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
@@ -1,4 +1,4 @@
import React, { useCallback, useRef } from 'react';
import React, { useCallback, useRef, useState } from 'react';
import {
Avatar,
@@ -17,21 +17,37 @@ import {
import { blueGrey } from '@mui/material/colors';
import { FiActivity, FiInbox, FiSearch } from 'react-icons/fi';
import NirvanaAvatar from './NirvanaAvatar';
import { useKey } from 'react-use';
import { useDebounce, useKey } from 'react-use';
import { useSnackbar } from 'notistack';
import KeyboardShortcutLabel from './KeyboardShortcutLabel';
import { searchUsers, User } from '../firebase/firestore';
const Conversations = () => {
const { enqueueSnackbar } = useSnackbar();
const searchRef = useRef<HTMLInputElement>(null);
const [searchVal, setSearchVal] = useState<string>('');
const onSearch = useCallback(() => {
const onSearchFocus = useCallback(() => {
enqueueSnackbar('search focused');
if (searchRef?.current) searchRef.current.focus();
}, []);
}, [enqueueSnackbar, searchRef]);
useKey('Shift', onSearch);
const [searchUsersResults, setSearchUsersResults] = useState<User[]>([]);
useKey('Shift', onSearchFocus);
const [, cancel] = useDebounce(
async () => {
if (searchVal) {
enqueueSnackbar('searching...', { variant: 'info' });
setSearchUsersResults(await searchUsers(searchVal));
}
},
500,
[searchVal, enqueueSnackbar, setSearchUsersResults],
);
return (
<>
@@ -51,11 +67,18 @@ const Conversations = () => {
>
<FiSearch style={{ color: blueGrey[500] }} />
<Input placeholder={'Find or start a conversation'} inputRef={searchRef} />
<Input
onChange={(e) => setSearchVal(e.target.value)}
value={searchVal}
placeholder={'Find or start a conversation'}
inputRef={searchRef}
/>
<KeyboardShortcutLabel label="Shift" />
</Stack>
{searchVal && <ListPeople people={searchUsersResults} />}
<List
sx={{
pt: 2,
@@ -149,4 +172,39 @@ const Conversations = () => {
);
};
function ListPeople({ people }: { people: User[] }) {
return (
<List
sx={{
pt: 2,
}}
subheader={
<ListSubheader>
<FiActivity />
<Typography variant="subtitle2"> Priority</Typography>
</ListSubheader>
}
>
{people.length === 0 && (
<Typography variant="caption">
Sorry please try someone else or invite them to nirvana.
</Typography>
)}
{people.map((person) => (
<ListItem key={`${person.uid}-searchUsers`}>
<ListItemButton selected={true}>
<ListItemAvatar>
<Avatar alt={person.displayName} src={person.photoUrl} />
</ListItemAvatar>
<ListItemText primary={person.displayName} />
<Typography variant={'caption'}>20 sec</Typography>
</ListItemButton>
</ListItem>
))}
</List>
);
}
export default Conversations;
+1 -1
View File
@@ -12,4 +12,4 @@ export const firebaseApp = initializeApp(devConfig);
export const firebaseAuth = getAuth(firebaseApp);
// Initialize Cloud Firestore and get a reference to the service
export const firestore = getFirestore(firebaseApp);
export const firestoreDb = getFirestore(firebaseApp);
+40 -3
View File
@@ -8,9 +8,14 @@ import {
QueryDocumentSnapshot,
Timestamp,
FieldValue,
getDoc,
query,
where,
getDocs,
} from 'firebase/firestore';
import { User as FirebaseUser } from 'firebase/auth';
import { firestoreDb } from './connect';
/**
* UTILS
@@ -20,11 +25,15 @@ const converter = <T>() => ({
fromFirestore: (snap: QueryDocumentSnapshot) => snap.data() as T,
});
const dataPoint = <T>(collectionPath: string) =>
doc(getFirestore(), collectionPath).withConverter(converter<T>());
const docPoint = <T>(collectionPath: string) =>
firestoreDb && doc(getFirestore(), collectionPath).withConverter(converter<T>());
const collectionPoint = <T>(collectionPath: string) =>
firestoreDb && collection(getFirestore(), collectionPath).withConverter(converter<T>());
const db = {
user: (userId: string) => dataPoint<User>(`users/${userId}`),
users: collectionPoint<User>(`users`),
user: (userId: string) => docPoint<User>(`users/${userId}`),
};
export class User {
@@ -65,3 +74,31 @@ export const createUser = async (user: FirebaseUser) => {
throw new Error('Error creating user');
}
};
export const searchUsers = async (searchQuery: string): Promise<User[] | undefined> => {
try {
const emaildocSearchQuery = query(
db.users,
where('email', '>=', searchQuery.toUpperCase()),
where('email', '<=', searchQuery.toUpperCase() + '\uf8ff'),
);
const nameSearchQuery = query(
db.users,
where('displayName', '>=', searchQuery.toUpperCase()),
where('displayName', '<=', searchQuery.toUpperCase() + '\uf8ff'),
);
const emailquerySnap = await getDocs(emaildocSearchQuery);
const namequerySnap = await getDocs(nameSearchQuery);
return [
...emailquerySnap.docs.map((doc) => doc.data()),
...namequerySnap.docs.map((doc) => doc.data()),
];
} catch (e) {
console.error('Error: ', e);
throw new Error('Error');
}
};