quick dial and creating conversations
This commit is contained in:
@@ -75,8 +75,8 @@ const getOneOnOneConversationIfExists = async (req: Request, res: Response, next
|
||||
resultConversation?._id ?? undefined,
|
||||
undefined,
|
||||
resultConversation
|
||||
? 'no such conversation exists!'
|
||||
: 'there is a conversation...quick dial them now!',
|
||||
? 'there is a conversation...quick dial them now!'
|
||||
: 'no such conversation exists!',
|
||||
),
|
||||
);
|
||||
} catch (error) {
|
||||
|
||||
@@ -85,3 +85,7 @@ export async function createConversation(
|
||||
export async function getConversations(): Promise<NirvanaResponse<Conversation[]>> {
|
||||
return await NirvanaApi.fetch(`/conversations`, 'GET', true);
|
||||
}
|
||||
|
||||
export async function checkIfOnOnOneExists(otherUserId: string): Promise<NirvanaResponse<string>> {
|
||||
return await NirvanaApi.fetch(`/conversations/check/${otherUserId}`, 'GET', true);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { checkIfOnOnOneExists, createConversation, getConversations } from '../api/NirvanaApi';
|
||||
|
||||
import Conversation from '@nirvana/core/models/conversation.model';
|
||||
import { ConversationMap } from '../util/types';
|
||||
import CreateConversationRequest from '@nirvana/core/requests/CreateConversationRequest.request';
|
||||
import { Typography } from '@mui/material';
|
||||
import { getConversations } from '../api/NirvanaApi';
|
||||
import User from '@nirvana/core/models/user.model';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useAsyncFn } from 'react-use';
|
||||
import { useImmer } from 'use-immer';
|
||||
|
||||
interface IConversationContext {
|
||||
conversations: ConversationMap;
|
||||
|
||||
selectedConversation?: Conversation;
|
||||
// handleSetConversation?: (conversationId: string) => void;
|
||||
|
||||
handleStartConversation?: (otherUsers: User[]) => void;
|
||||
}
|
||||
|
||||
const ConversationContext = React.createContext<IConversationContext>({
|
||||
@@ -22,6 +30,8 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
||||
// the map that we manage throughout the app
|
||||
const [conversationMap, setConversationMap] = useImmer<ConversationMap>({});
|
||||
|
||||
const [selectedConversation, setSelectedConversation] = useState<Conversation>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
doFetch();
|
||||
}, [doFetch]);
|
||||
@@ -42,6 +52,76 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
||||
}
|
||||
}, [fetchState.value, setConversationMap]);
|
||||
|
||||
/**
|
||||
* temporaryOverrideSort: tell me if you want to temporarily prioritize this conversation above all others
|
||||
*/
|
||||
const selectConversation = useCallback(
|
||||
(conversationId: string, temporaryOverrideSort = false) => {
|
||||
/**
|
||||
* see if there is such a conversation in our map
|
||||
* if not, then go and fetch it from backend
|
||||
* set the temporary sort accordingly
|
||||
*/
|
||||
|
||||
const allConversationIds = Object.keys(conversationMap);
|
||||
|
||||
if (allConversationIds.includes(conversationId)) {
|
||||
toast.success('we have that conversation!!!');
|
||||
|
||||
setSelectedConversation(conversationMap[conversationId]);
|
||||
}
|
||||
},
|
||||
[conversationMap, setSelectedConversation],
|
||||
);
|
||||
|
||||
const handleStartConversation = useCallback(
|
||||
async (otherUsers: User[]) => {
|
||||
try {
|
||||
/** group conversation
|
||||
* 1. create it
|
||||
* 2. select the conversation based on the id
|
||||
*
|
||||
* one on one:
|
||||
* 1. hit backend to see if we already have a conversation with them
|
||||
* 2. if so, then go and select it with priority sort flag
|
||||
* 3. if not, then go ahead and create
|
||||
* 4. use the conversation id to select it
|
||||
*/
|
||||
|
||||
if (!otherUsers || otherUsers.length === 0) {
|
||||
toast.error('Must provider users');
|
||||
return;
|
||||
}
|
||||
|
||||
// todo: check to make sure that the other user is not the user himself, although backend should error out
|
||||
|
||||
if (otherUsers.length === 1) {
|
||||
const conversationDmCheck = await checkIfOnOnOneExists(otherUsers[0]._id.toString());
|
||||
|
||||
// if we found a conversation
|
||||
if (conversationDmCheck.data) {
|
||||
toast.success('already have this user...quick dialing');
|
||||
|
||||
selectConversation(conversationDmCheck.data, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const createdConversationResult = await createConversation(
|
||||
new CreateConversationRequest(otherUsers),
|
||||
);
|
||||
|
||||
selectConversation(createdConversationResult.data.conversationId.toString());
|
||||
|
||||
toast.success('started conversation');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error(error.message);
|
||||
}
|
||||
},
|
||||
[conversationMap, selectConversation],
|
||||
);
|
||||
|
||||
// todo: open up a handler for children
|
||||
// to refetch or search for a particular conversation and add it to the list of conversations
|
||||
|
||||
@@ -56,7 +136,9 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
||||
}
|
||||
|
||||
return (
|
||||
<ConversationContext.Provider value={{ conversations: conversationMap }}>
|
||||
<ConversationContext.Provider
|
||||
value={{ conversations: conversationMap, handleStartConversation, selectedConversation }}
|
||||
>
|
||||
{children}
|
||||
</ConversationContext.Provider>
|
||||
);
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// make do router given absense of react router in desktop apps
|
||||
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import useConversations from './ConversationProvider';
|
||||
|
||||
type TPage =
|
||||
| 'START_NEW_CONVERSATION'
|
||||
| 'FULL_PAGE_OMNI_SEARCH'
|
||||
| 'CONVERSATION_DETAILS'
|
||||
| 'SELECTED_CONVERSATION'
|
||||
| 'PROFILE'
|
||||
| 'WELCOME';
|
||||
|
||||
@@ -21,6 +23,14 @@ const RouterContext = React.createContext<IRouterContext>({
|
||||
export function RouterProvider({ children }: { children: React.ReactNode }) {
|
||||
const [page, setPage] = useState<TPage>('WELCOME');
|
||||
|
||||
const { selectedConversation } = useConversations();
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedConversation) {
|
||||
setPage('SELECTED_CONVERSATION');
|
||||
}
|
||||
}, [setPage, selectedConversation]);
|
||||
|
||||
const handleSetPage = useCallback((newPage: TPage) => () => setPage(newPage), [setPage]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -29,6 +29,7 @@ import { blueGrey } from '@mui/material/colors';
|
||||
import { createConversation } from '../api/NirvanaApi';
|
||||
import toast from 'react-hot-toast';
|
||||
import useAuth from '../providers/AuthProvider';
|
||||
import useConversations from '../providers/ConversationProvider';
|
||||
import useRouter from '../providers/RouterProvider';
|
||||
import useSearch from '../providers/SearchProvider';
|
||||
|
||||
@@ -81,6 +82,8 @@ export default function NewConversationDialog() {
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
|
||||
|
||||
const { handleStartConversation } = useConversations();
|
||||
|
||||
const handleSubmit = useCallback(async () => {
|
||||
if (selectedUsers.length === 0) {
|
||||
toast.error('Must select a person!');
|
||||
@@ -94,24 +97,11 @@ export default function NewConversationDialog() {
|
||||
|
||||
setIsSubmitting(true);
|
||||
|
||||
try {
|
||||
// if it's just one other person, then call quick dial master function which would do all of the checking
|
||||
handleStartConversation(selectedUsers);
|
||||
|
||||
// if more than one person, then just create conversation
|
||||
|
||||
const createResult = await createConversation(
|
||||
new CreateConversationRequest(selectedUsers, conversationName),
|
||||
);
|
||||
|
||||
// clear form for next time
|
||||
setSelectedUsers([]);
|
||||
setConversationName('');
|
||||
|
||||
// todo: select conversation Id that was created
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error(error.message);
|
||||
}
|
||||
// clear form for next time
|
||||
setSelectedUsers([]);
|
||||
setConversationName('');
|
||||
|
||||
setIsSubmitting(false);
|
||||
}, [selectedUsers, setConversationName, conversationName, setSelectedUsers, setIsSubmitting]);
|
||||
|
||||
@@ -9,7 +9,7 @@ export type ConversationMap = {
|
||||
|
||||
// allows client side to have this pushed up in the list and can uncheck it once user is done with this
|
||||
// if action is take, normal ordering should take place with database upserts
|
||||
temporaryInboxTop?: boolean;
|
||||
temporaryOverrideSort?: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user