blob: 3a7556706792ade192c7f1a81de3060e63846b0c [file] [log] [blame]
simon06527b02022-10-01 15:01:47 -04001import { Socket } from 'socket.io';
2
3import Contact from './Contact';
4import { PromiseExecutor, Session } from './util';
5
6export interface ConversationMember {
7 contact: Contact;
8 role?: 'admin' | 'member' | 'invited' | 'banned' | 'left';
9}
10
11type ConversationInfos = Record<string, unknown>;
12
13export type Message = Record<string, string>;
14type ConversationRequest = PromiseExecutor<Message[]>;
15
16type ConversationListeners = Record<
17 string,
18 {
19 socket: Socket;
20 session: Session;
21 }
22>;
23
24class Conversation {
25 private readonly id: string | undefined;
26 private readonly accountId: string;
27 private readonly members: ConversationMember[];
28 private messages: Message[] = [];
29 private _infos: ConversationInfos = {};
30 private _requests: Record<string, ConversationRequest> = {};
31 private _listeners: ConversationListeners = {};
32
33 constructor(id: string | undefined, accountId: string, members?: ConversationMember[]) {
34 this.id = id;
35 this.accountId = accountId;
36 this.members = members || [];
37 }
38
39 static from(accountId: string, object: Conversation) {
40 const conversation = new Conversation(
41 object.id,
42 accountId,
43 object.members.map((member) => {
44 member.contact = Contact.from(member.contact);
45 return member;
46 })
47 );
48 conversation.messages = object.messages;
49 return conversation;
50 }
51 static fromSingleContact(accountId: string, contact: Contact) {
52 return new Conversation(undefined, accountId, [{ contact }]);
53 }
54
55 getId() {
56 return this.id;
57 }
58
59 getAccountId() {
60 return this.accountId;
61 }
62
63 getDisplayName() {
64 if (this.members.length !== 0) {
65 return this.members[0].contact.getDisplayName();
66 }
67 return this.getDisplayUri();
68 }
69
70 getDisplayNameNoFallback() {
71 if (this.members.length !== 0) {
72 return this.members[0].contact.getDisplayNameNoFallback();
73 }
74 }
75
76 async getObject(params?: {
77 memberFilter: (value: ConversationMember, index: number, array: ConversationMember[]) => boolean;
78 }) {
79 const members = params?.memberFilter ? this.members.filter(params.memberFilter) : this.members;
80 return {
81 id: this.id,
82 messages: this.messages,
83 members: await Promise.all(
84 members.map(async (member) => {
85 //Object.assign({}, member);
86 return {
87 role: member.role,
88 contact: await member.contact.getObject(),
89 };
90 })
91 ),
92 };
93 }
94
95 getSummary() {
96 return this.getObject();
97 }
98
99 getDisplayUri() {
100 return this.getId() || this.getFirstMember().contact.getUri();
101 }
102
103 getFirstMember() {
104 return this.members[0];
105 }
106
107 getMembers() {
108 return this.members;
109 }
110
111 addMessage(message: Message) {
112 if (this.messages.length === 0) this.messages.push(message);
113 else if (message.id === this.messages[this.messages.length - 1].linearizedParent) {
114 this.messages.push(message);
115 } else if (message.linearizedParent === this.messages[0].id) {
116 this.messages.unshift(message);
117 } else {
118 console.log("Can't insert message " + message.id);
119 }
120 }
121
122 addLoadedMessages(messages: Message[]) {
123 messages.forEach((message) => this.addMessage(message));
124 }
125
126 getMessages() {
127 return this.messages;
128 }
129
130 set infos(infos: ConversationInfos) {
131 this._infos = infos;
132 }
133
134 get requests(): Record<string, ConversationRequest> {
135 return this._requests;
136 }
137
138 set requests(value: Record<string, ConversationRequest>) {
139 this._requests = value;
140 }
141
142 get listeners(): ConversationListeners {
143 return this._listeners;
144 }
145
146 set listeners(listeners: ConversationListeners) {
147 this._listeners = listeners;
148 }
149}
150
151export default Conversation;