full flow of zapping or pinning and unpinning cold full run
This commit is contained in:
@@ -9,9 +9,10 @@ import express, { NextFunction, Request, Response, response } from 'express';
|
|||||||
import ConversationService from '../services/conversation.service';
|
import ConversationService from '../services/conversation.service';
|
||||||
import CreateConversationRequest from '@nirvana/core/requests/CreateConversationRequest.request';
|
import CreateConversationRequest from '@nirvana/core/requests/CreateConversationRequest.request';
|
||||||
import CreateConversationResponse from '@nirvana/core/responses/CreateConversationResponse.response';
|
import CreateConversationResponse from '@nirvana/core/responses/CreateConversationResponse.response';
|
||||||
import { MemberState } from '../../core/models/conversation.model';
|
import { MemberState } from '@nirvana/core/models/conversation.model';
|
||||||
import NirvanaResponse from '@nirvana/core/responses/nirvanaResponse';
|
import NirvanaResponse from '@nirvana/core/responses/nirvanaResponse';
|
||||||
import { ObjectId } from 'mongodb';
|
import { ObjectId } from 'mongodb';
|
||||||
|
import UpdateConversationPriorityRequest from '@nirvana/core/requests/UpdateConversationPriority.request';
|
||||||
import { UserService } from '../services/user.service';
|
import { UserService } from '../services/user.service';
|
||||||
|
|
||||||
export default function getConversationRoutes() {
|
export default function getConversationRoutes() {
|
||||||
@@ -35,6 +36,9 @@ export default function getConversationRoutes() {
|
|||||||
// create a conversation
|
// create a conversation
|
||||||
router.post('/', authCheck, createConversation);
|
router.post('/', authCheck, createConversation);
|
||||||
|
|
||||||
|
// change user's categorization of conversation
|
||||||
|
router.post('/:conversationId/priority', authCheck, updatePriorityOfConversation);
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +134,7 @@ const createConversation = async (req: Request, res: Response, next: NextFunctio
|
|||||||
const conversationUserMembers: ConversationUserMember[] = [];
|
const conversationUserMembers: ConversationUserMember[] = [];
|
||||||
|
|
||||||
createRequest.otherUsers.forEach((userObject) => {
|
createRequest.otherUsers.forEach((userObject) => {
|
||||||
const newConversationMember = new ConversationMember(MemberRole.regular, MemberState.inbox);
|
const newConversationMember = new ConversationMember(MemberRole.regular, 'inbox');
|
||||||
|
|
||||||
// ! hack as json over the wire converts to string for some reason
|
// ! hack as json over the wire converts to string for some reason
|
||||||
userObject._id = new ObjectId(userObject._id);
|
userObject._id = new ObjectId(userObject._id);
|
||||||
@@ -142,7 +146,7 @@ const createConversation = async (req: Request, res: Response, next: NextFunctio
|
|||||||
});
|
});
|
||||||
|
|
||||||
// adding in the admin user which is the user who started the conversation
|
// adding in the admin user which is the user who started the conversation
|
||||||
const adminMember = new ConversationMember(MemberRole.admin, MemberState.inbox);
|
const adminMember = new ConversationMember(MemberRole.admin, 'inbox');
|
||||||
const currentUser = await UserService.getUserById(userInfo.userId);
|
const currentUser = await UserService.getUserById(userInfo.userId);
|
||||||
if (!currentUser) {
|
if (!currentUser) {
|
||||||
return next(new Error('unable to find your user object for caching'));
|
return next(new Error('unable to find your user object for caching'));
|
||||||
@@ -172,3 +176,27 @@ const createConversation = async (req: Request, res: Response, next: NextFunctio
|
|||||||
);
|
);
|
||||||
return res.json(responseObj);
|
return res.json(responseObj);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updatePriorityOfConversation = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
const { conversationId } = req.params;
|
||||||
|
const userInfo = res.locals.userInfo as JwtClaims;
|
||||||
|
const reqObj = req.body as UpdateConversationPriorityRequest;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const updateRes = await ConversationService.updateUserConversationPriority(
|
||||||
|
new ObjectId(conversationId),
|
||||||
|
new ObjectId(userInfo.userId),
|
||||||
|
reqObj.newState,
|
||||||
|
);
|
||||||
|
|
||||||
|
return res.json(
|
||||||
|
new NirvanaResponse(
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
updateRes?.ok ? 'updated' : 'failed to update conversation priority',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
next(Error('unable to set conversation as priority'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import Conversation from '@nirvana/core/models/conversation.model';
|
import Conversation, { MemberState } from '@nirvana/core/models/conversation.model';
|
||||||
|
|
||||||
import { ObjectId } from 'mongodb';
|
import { ObjectId } from 'mongodb';
|
||||||
import { collections } from './database.service';
|
import { collections } from './database.service';
|
||||||
|
|
||||||
@@ -65,4 +66,16 @@ export default class ConversationService {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async updateUserConversationPriority(
|
||||||
|
conversationId: ObjectId,
|
||||||
|
memberId: ObjectId,
|
||||||
|
newState: MemberState,
|
||||||
|
) {
|
||||||
|
const query = { _id: conversationId, 'members._id': memberId };
|
||||||
|
|
||||||
|
return await collections.conversations?.findOneAndUpdate(query, {
|
||||||
|
$set: { 'members.$.memberState': newState },
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,16 +39,18 @@ export enum MemberRole {
|
|||||||
regular = 'regular',
|
regular = 'regular',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MemberState {
|
//! for some reason using this breaks frontend to need node modules
|
||||||
priority = 'priority',
|
// export enum MemberState {
|
||||||
inbox = 'inbox',
|
// priority = 'priority',
|
||||||
// deleted = "deleted"
|
// inbox = 'inbox',
|
||||||
}
|
// // deleted = "deleted"
|
||||||
|
// }
|
||||||
|
|
||||||
|
export type MemberState = 'priority' | 'inbox';
|
||||||
export class ConversationMember {
|
export class ConversationMember {
|
||||||
constructor(
|
constructor(
|
||||||
public role: MemberRole,
|
public role: MemberRole,
|
||||||
public memberState: 'priority' | 'inbox',
|
public memberState: MemberState,
|
||||||
|
|
||||||
public joinedDate = new Date(),
|
public joinedDate = new Date(),
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { MemberState } from '../models/conversation.model';
|
||||||
|
|
||||||
|
export default class UpdateConversationPriorityRequest {
|
||||||
|
constructor(public newState: MemberState) {}
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
|
import Conversation, { MemberState } from '@nirvana/core/models/conversation.model';
|
||||||
import NirvanaResponse, { INirvanaResponse } from '@nirvana/core/responses/nirvanaResponse';
|
import NirvanaResponse, { INirvanaResponse } from '@nirvana/core/responses/nirvanaResponse';
|
||||||
import axios, { AxiosRequestConfig, AxiosResponse, Method } from 'axios';
|
import axios, { AxiosRequestConfig, AxiosResponse, Method } from 'axios';
|
||||||
|
|
||||||
import Conversation from '@nirvana/core/models/conversation.model';
|
|
||||||
import CreateConversationRequest from '@nirvana/core/requests/CreateConversationRequest.request';
|
import CreateConversationRequest from '@nirvana/core/requests/CreateConversationRequest.request';
|
||||||
import CreateConversationResponse from '@nirvana/core/responses/CreateConversationResponse.response';
|
import CreateConversationResponse from '@nirvana/core/responses/CreateConversationResponse.response';
|
||||||
import LoginResponse from '@nirvana/core/responses/login.response';
|
import LoginResponse from '@nirvana/core/responses/login.response';
|
||||||
|
import UpdateConversationPriorityRequest from '@nirvana/core/requests/UpdateConversationPriority.request';
|
||||||
import UserDetailsResponse from '@nirvana/core/responses/userDetails.response';
|
import UserDetailsResponse from '@nirvana/core/responses/userDetails.response';
|
||||||
import UserSearchResponse from '@nirvana/core/responses/userSearch.response';
|
import UserSearchResponse from '@nirvana/core/responses/userSearch.response';
|
||||||
|
|
||||||
@@ -95,3 +96,15 @@ export async function getConversationById(
|
|||||||
): Promise<NirvanaResponse<Conversation>> {
|
): Promise<NirvanaResponse<Conversation>> {
|
||||||
return await NirvanaApi.fetch(`/conversations/${conversationId}`, 'GET', true);
|
return await NirvanaApi.fetch(`/conversations/${conversationId}`, 'GET', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateConversationPriority(
|
||||||
|
conversationId: string,
|
||||||
|
newState: MemberState,
|
||||||
|
): Promise<NirvanaResponse<string>> {
|
||||||
|
return await NirvanaApi.fetch(
|
||||||
|
`/conversations/${conversationId}/priority`,
|
||||||
|
'POST',
|
||||||
|
true,
|
||||||
|
new UpdateConversationPriorityRequest(newState),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
createConversation,
|
createConversation,
|
||||||
getConversationById,
|
getConversationById,
|
||||||
getConversations,
|
getConversations,
|
||||||
|
updateConversationPriority,
|
||||||
} from '../api/NirvanaApi';
|
} from '../api/NirvanaApi';
|
||||||
import { useAsyncFn, useEffectOnce, useKeyPressEvent, useUnmount } from 'react-use';
|
import { useAsyncFn, useEffectOnce, useKeyPressEvent, useUnmount } from 'react-use';
|
||||||
|
|
||||||
@@ -75,6 +76,8 @@ interface IConversationContext {
|
|||||||
handleStartConversation?: (otherUsers: User[], conversationName?: string) => Promise<boolean>;
|
handleStartConversation?: (otherUsers: User[], conversationName?: string) => Promise<boolean>;
|
||||||
|
|
||||||
handleEscape?: () => void;
|
handleEscape?: () => void;
|
||||||
|
|
||||||
|
updateConversationPriority?: (conversationId: string, newState: MemberState) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConversationContext = React.createContext<IConversationContext>({
|
const ConversationContext = React.createContext<IConversationContext>({
|
||||||
@@ -397,6 +400,29 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
|||||||
return [priorityConversations, inboxConversations];
|
return [priorityConversations, inboxConversations];
|
||||||
}, [conversationMap, user]);
|
}, [conversationMap, user]);
|
||||||
|
|
||||||
|
const updateConversationPriority = useCallback(
|
||||||
|
async (conversationId: string, newState: MemberState) => {
|
||||||
|
try {
|
||||||
|
await updateConversationPriority(conversationId, newState);
|
||||||
|
|
||||||
|
setConversationMap((draft) => {
|
||||||
|
if (draft[conversationId]) {
|
||||||
|
const currUserMember = draft[conversationId].members.find(
|
||||||
|
(mem) => mem._id.toString() === user._id.toString(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (currUserMember) {
|
||||||
|
currUserMember.memberState = newState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
toast.error('problem in pinning conversation');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[setConversationMap, user],
|
||||||
|
);
|
||||||
|
|
||||||
const handleEscape = useCallback(() => {
|
const handleEscape = useCallback(() => {
|
||||||
selectConversation(undefined);
|
selectConversation(undefined);
|
||||||
}, [selectConversation]);
|
}, [selectConversation]);
|
||||||
@@ -434,6 +460,7 @@ export function ConversationProvider({ children }: { children: React.ReactNode }
|
|||||||
priorityConversations: masterConversations[0],
|
priorityConversations: masterConversations[0],
|
||||||
inboxConversations: masterConversations[1],
|
inboxConversations: masterConversations[1],
|
||||||
handleEscape,
|
handleEscape,
|
||||||
|
updateConversationPriority,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ function OverlayConversation({
|
|||||||
}) {
|
}) {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
|
||||||
const { selectConversation, handleEscape } = useConversations();
|
const { selectConversation, handleEscape, updateConversationPriority } = useConversations();
|
||||||
|
|
||||||
const handleSelectConversation = useCallback(() => {
|
const handleSelectConversation = useCallback(() => {
|
||||||
if (!isSelected) {
|
if (!isSelected) {
|
||||||
@@ -205,6 +205,14 @@ function OverlayConversation({
|
|||||||
return false;
|
return false;
|
||||||
}, [masterConversation, user]);
|
}, [masterConversation, user]);
|
||||||
|
|
||||||
|
const handleToggleConversationZap = useCallback(() => {
|
||||||
|
if (isPriority) {
|
||||||
|
updateConversationPriority(masterConversation._id.toString(), 'inbox');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateConversationPriority(masterConversation._id.toString(), 'priority');
|
||||||
|
}, [updateConversationPriority, isPriority, masterConversation._id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack
|
<Stack
|
||||||
direction={'column'}
|
direction={'column'}
|
||||||
@@ -279,6 +287,7 @@ function OverlayConversation({
|
|||||||
}}
|
}}
|
||||||
size="small"
|
size="small"
|
||||||
aria-selected={isPriority ? true : false}
|
aria-selected={isPriority ? true : false}
|
||||||
|
onClick={handleToggleConversationZap}
|
||||||
>
|
>
|
||||||
{isPriority ? <FiZap /> : <FiZapOff />}
|
{isPriority ? <FiZap /> : <FiZapOff />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|||||||
Reference in New Issue
Block a user