it's just a mess
This commit is contained in:
@@ -5,23 +5,36 @@ export default class Conversation {
|
||||
constructor(
|
||||
public createdByUserId: string,
|
||||
|
||||
public membersList: string[],
|
||||
|
||||
public name: string | null = null,
|
||||
|
||||
public lastUpdatedDate = Timestamp.now(),
|
||||
|
||||
public createdDate = Timestamp.now(),
|
||||
|
||||
public membersInRoom: string[] = [],
|
||||
|
||||
public lastActivityDate: Timestamp = Timestamp.now(),
|
||||
) {}
|
||||
}
|
||||
|
||||
// export class Member {
|
||||
// constructor(
|
||||
// public id: string,
|
||||
// public userId: string,
|
||||
// public role: 'admin' | 'regular',
|
||||
// public joinedDate = Timestamp.now(),
|
||||
// ) {}
|
||||
// }
|
||||
export class ConversationMember {
|
||||
constructor(
|
||||
public id: string, // NOTE: serves as the user ID
|
||||
public conversationId: string,
|
||||
|
||||
public role: MemberRole,
|
||||
|
||||
public memberState: MemberState,
|
||||
|
||||
public lastActiveDate: Timestamp | null = null,
|
||||
public joinedDate = Timestamp.now(),
|
||||
) {}
|
||||
}
|
||||
|
||||
export enum MemberRole {
|
||||
admin = 'admin',
|
||||
regular = 'regular',
|
||||
}
|
||||
export enum MemberState {
|
||||
priority = 'priority',
|
||||
inbox = 'inbox',
|
||||
// deleted = "deleted"
|
||||
}
|
||||
|
||||
@@ -48,25 +48,27 @@ import { useSnackbar } from 'notistack';
|
||||
|
||||
import NirvanaLogo from './NirvanaLogo';
|
||||
|
||||
import Conversation from '@nirvana/core/src/models/conversation.model';
|
||||
import Conversation, { ConversationMember } from '@nirvana/core/src/models/conversation.model';
|
||||
import useAuth from '../providers/AuthProvider';
|
||||
import {
|
||||
createOneOnOneConversation,
|
||||
getConversationsQueryLIVE,
|
||||
getUserById,
|
||||
getUserConversationMembersQueryLIVE,
|
||||
searchUsers,
|
||||
} from '../firebase/firestore';
|
||||
import { Link, AudioClip, Image } from '@nirvana/core/src/models/content.model';
|
||||
import { useImmer } from 'use-immer';
|
||||
import { User } from '@nirvana/core/src/models/user.model';
|
||||
import { onSnapshot } from 'firebase/firestore';
|
||||
import { onSnapshot, Unsubscribe } from 'firebase/firestore';
|
||||
|
||||
import NirvanaAvatar from './NirvanaAvatar';
|
||||
import { useDebounce, useKey, useKeyPressEvent } from 'react-use';
|
||||
|
||||
import KeyboardShortcutLabel from './KeyboardShortcutLabel';
|
||||
import { getConversationQueryLIVE } from '../firebase/firestore';
|
||||
|
||||
type ConversationMap = {
|
||||
[conversationId: string]: Conversation;
|
||||
[conversationId: string]: Partial<MasterConversation>;
|
||||
};
|
||||
|
||||
type UserMap = {
|
||||
@@ -88,6 +90,8 @@ interface ITerminalContext {
|
||||
getUser?: (userId: string) => Promise<User | undefined>;
|
||||
}
|
||||
|
||||
type MasterConversation = Conversation & { members: ConversationMember[] };
|
||||
|
||||
const TerminalContext = React.createContext<ITerminalContext>({
|
||||
conversationMap: {},
|
||||
});
|
||||
@@ -121,23 +125,52 @@ export function TerminalProvider({ children }: { children?: React.ReactNode }) {
|
||||
const [userMap, updateUserMap] = useImmer<UserMap>({});
|
||||
const [contentMap, updatecontentMap] = useImmer<ConversationContentMap>({});
|
||||
|
||||
// fetch conversations
|
||||
// fetch conversations that I am in
|
||||
useEffect(() => {
|
||||
const unsub = onSnapshot(getConversationsQueryLIVE(user.uid), (querySnapshot) => {
|
||||
const conversations = querySnapshot.docs.map((doc) => doc.data());
|
||||
const unsubs: Unsubscribe[] = [];
|
||||
|
||||
console.log('got new or updated conversations', conversations);
|
||||
const unsubMyConversationMembers = onSnapshot(
|
||||
getUserConversationMembersQueryLIVE(user.uid),
|
||||
(querySnapshot) => {
|
||||
querySnapshot.docChanges().forEach((docSnapChange) => {
|
||||
const conversationMember = docSnapChange.doc.data();
|
||||
const conversationId = conversationMember.conversationId;
|
||||
|
||||
updateConversationMap((draft) => {
|
||||
conversations.forEach((convo) => {
|
||||
draft[convo.id] = convo;
|
||||
// start listening to conversations
|
||||
// get all of the other members
|
||||
if (docSnapChange.type === 'added') {
|
||||
const conversationSub = onSnapshot(getConversationQueryLIVE, (conversationSnapshot) => {
|
||||
const conversation = conversationSnapshot
|
||||
})
|
||||
console.log('New city: ', docSnapChange.doc.data());
|
||||
}
|
||||
if (docSnapChange.type === 'modified') {
|
||||
console.log('Modified city: ', docSnapChange.doc.data());
|
||||
}
|
||||
if (docSnapChange.type === 'removed') {
|
||||
console.log('Removed city: ', docSnapChange.doc.data());
|
||||
}
|
||||
|
||||
updateConversationMap((draft) => {
|
||||
if (draft[conversationMember.conversationId]) {
|
||||
if (draft[conversationMember.conversationId].members) {
|
||||
draft[conversationMember.conversationId].members.push(conversationMember);
|
||||
} else {
|
||||
draft[conversationMember.conversationId].members = [conversationMember];
|
||||
}
|
||||
} else {
|
||||
draft[conversationMember.conversationId] = { members: [conversationMember] };
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
enqueueSnackbar('got conversations...logging', { variant: 'success' });
|
||||
});
|
||||
unsubs.push(unsubMyConversationMembers)
|
||||
|
||||
return () => unsub();
|
||||
return () => {
|
||||
unsubs.forEach((unsub) => unsub());
|
||||
};
|
||||
}, [user, enqueueSnackbar, updateConversationMap]);
|
||||
|
||||
// cache of selected conversation
|
||||
|
||||
@@ -17,13 +17,18 @@ import {
|
||||
startAt,
|
||||
endAt,
|
||||
addDoc,
|
||||
writeBatch,
|
||||
collectionGroup,
|
||||
} 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 from '@nirvana/core/src/models/conversation.model';
|
||||
import useAuth from '../providers/AuthProvider';
|
||||
import Conversation, {
|
||||
ConversationMember,
|
||||
MemberRole,
|
||||
MemberState,
|
||||
} from '@nirvana/core/src/models/conversation.model';
|
||||
|
||||
interface Document {
|
||||
id: string;
|
||||
@@ -50,11 +55,17 @@ const docPoint = <T extends Document>(collectionPath: string) =>
|
||||
const collectionPoint = <T extends Document>(collectionPath: string) =>
|
||||
firestoreDb && collection(getFirestore(), collectionPath).withConverter(converter<T>());
|
||||
|
||||
// const collectionGroupPoint = <T extends Document>(collectionPath: string) =>
|
||||
// firestoreDb && collectionGroup(getFirestore(), collectionPath).withConverter(converter<T>());
|
||||
|
||||
const db = {
|
||||
users: collectionPoint<User>(`users`),
|
||||
user: (userId: string) => docPoint<User>(`users/${userId}`),
|
||||
conversations: collectionPoint<Conversation>(`conversations`),
|
||||
conversation: (conversationId: string) => docPoint<User>(`conversations/${conversationId}`),
|
||||
conversation: (conversationId: string) =>
|
||||
docPoint<Conversation>(`conversations/${conversationId}`),
|
||||
conversationMembers: collectionPoint<ConversationMember>(`conversationMembers`),
|
||||
conversationMember: () => docPoint<ConversationMember>(`conversationMembers`),
|
||||
};
|
||||
|
||||
// enum COLLECTION {
|
||||
@@ -127,9 +138,20 @@ export const getUserById = async (userId: string): Promise<User | undefined> =>
|
||||
return undefined;
|
||||
};
|
||||
|
||||
// get the conversations for particular user
|
||||
export const getConversationsQueryLIVE = (userId: string) =>
|
||||
query(db.conversations, where('membersList', 'array-contains', userId));
|
||||
// get conversation members for all conversations that I am in
|
||||
export const getUserConversationMembersQueryLIVE = (userId: string) => {
|
||||
return query(db.conversationMembers, where('userId', '==', userId));
|
||||
};
|
||||
|
||||
// get all conversation members for a conversation
|
||||
export const getConversationMembersQueryLIVE = (conversationId: string) => {
|
||||
return query(db.conversationMembers, where('conversationId', '==', conversationId));
|
||||
};
|
||||
|
||||
// get document reference for specific conversation
|
||||
export const getConversationQueryLIVE = (conversationId: string) => {
|
||||
return db.conversation(conversationId);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -141,11 +163,34 @@ export const createOneOnOneConversation = async (
|
||||
otherUserId: string,
|
||||
myUserId: string,
|
||||
): Promise<string | undefined> => {
|
||||
const newConversation = new Conversation(myUserId, [myUserId, otherUserId], null);
|
||||
|
||||
try {
|
||||
const newDoc = await addDoc(db.conversations, newConversation);
|
||||
return newDoc.id;
|
||||
const newConversation = new Conversation(myUserId);
|
||||
const newDocConversationInserted = await addDoc(db.conversations, newConversation);
|
||||
|
||||
const batch = writeBatch(firestoreDb);
|
||||
|
||||
// create all members
|
||||
const adminMember = new ConversationMember(
|
||||
myUserId,
|
||||
newDocConversationInserted.id,
|
||||
MemberRole.admin,
|
||||
MemberState.priority,
|
||||
null,
|
||||
);
|
||||
const otherMember = new ConversationMember(
|
||||
otherUserId,
|
||||
newDocConversationInserted.id,
|
||||
MemberRole.regular,
|
||||
MemberState.inbox,
|
||||
null,
|
||||
);
|
||||
|
||||
batch.set(db.conversationMember(), adminMember);
|
||||
batch.set(db.conversationMember(), otherMember);
|
||||
|
||||
await batch.commit();
|
||||
|
||||
return newDocConversationInserted.id;
|
||||
} catch (e) {
|
||||
console.error('Error creating user: ', e);
|
||||
|
||||
@@ -156,11 +201,38 @@ export const createOneOnOneConversation = async (
|
||||
export const createGroupConversation = async (
|
||||
otherUserIds: string[],
|
||||
myUserId: string,
|
||||
): Promise<void> => {
|
||||
const newConversation = new Conversation(myUserId, [myUserId, ...otherUserIds]);
|
||||
|
||||
): Promise<string> => {
|
||||
try {
|
||||
await addDoc(db.conversations, newConversation);
|
||||
const newConversation = new Conversation(myUserId);
|
||||
const newDocConversationInserted = await addDoc(db.conversations, newConversation);
|
||||
|
||||
const batch = writeBatch(firestoreDb);
|
||||
|
||||
const adminMember = new ConversationMember(
|
||||
myUserId,
|
||||
newDocConversationInserted.id,
|
||||
MemberRole.admin,
|
||||
MemberState.priority,
|
||||
null,
|
||||
);
|
||||
batch.set(db.conversationMember(), adminMember);
|
||||
|
||||
// create all members
|
||||
otherUserIds.forEach((otherUserId) => {
|
||||
const otherMember = new ConversationMember(
|
||||
otherUserId,
|
||||
newDocConversationInserted.id,
|
||||
MemberRole.regular,
|
||||
MemberState.inbox,
|
||||
null,
|
||||
);
|
||||
|
||||
batch.set(db.conversationMember(), otherMember);
|
||||
});
|
||||
|
||||
await batch.commit();
|
||||
|
||||
return newDocConversationInserted.id;
|
||||
} catch (e) {
|
||||
console.error('Error creating user: ', e);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user