2021-10-06 12:52:41 +11:00
|
|
|
import { idToContentTopic } from "./contentTopic";
|
2021-09-23 15:42:15 +10:00
|
|
|
import { createSymKeyFromPassword } from "./encryption";
|
2021-10-06 10:43:53 +11:00
|
|
|
import { ChatMessage, Content } from "./wire/chat_message";
|
2021-09-14 12:50:33 +10:00
|
|
|
|
2021-09-23 15:42:15 +10:00
|
|
|
/**
|
|
|
|
* Represent a chat room. Only public chats are currently supported.
|
|
|
|
*/
|
2021-09-14 12:50:33 +10:00
|
|
|
export class Chat {
|
2021-09-14 13:49:42 +10:00
|
|
|
private lastClockValue?: number;
|
|
|
|
private lastMessage?: ChatMessage;
|
2021-09-14 12:50:33 +10:00
|
|
|
|
2021-09-23 15:42:15 +10:00
|
|
|
private constructor(public id: string, public symKey: Uint8Array) {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a public chat room.
|
|
|
|
*/
|
2021-10-05 14:04:12 +11:00
|
|
|
public static async create(id: string): Promise<Chat> {
|
2021-09-23 15:42:15 +10:00
|
|
|
const symKey = await createSymKeyFromPassword(id);
|
|
|
|
|
|
|
|
return new Chat(id, symKey);
|
2021-09-14 13:49:42 +10:00
|
|
|
}
|
2021-09-14 12:50:33 +10:00
|
|
|
|
2021-09-14 15:16:40 +10:00
|
|
|
public get contentTopic(): string {
|
2021-10-06 12:52:41 +11:00
|
|
|
return idToContentTopic(this.id);
|
2021-09-14 15:16:40 +10:00
|
|
|
}
|
|
|
|
|
2021-10-08 11:29:15 +11:00
|
|
|
public createMessage(content: Content): ChatMessage {
|
2021-09-22 15:05:36 +10:00
|
|
|
const { timestamp, clock } = this._nextClockAndTimestamp();
|
2021-09-14 12:50:33 +10:00
|
|
|
|
2021-10-07 14:21:49 +11:00
|
|
|
const message = ChatMessage.createMessage(
|
|
|
|
clock,
|
|
|
|
timestamp,
|
|
|
|
this.id,
|
2021-10-08 11:29:15 +11:00
|
|
|
content
|
2021-10-07 14:21:49 +11:00
|
|
|
);
|
2021-09-22 15:05:36 +10:00
|
|
|
|
2021-09-23 14:33:09 +10:00
|
|
|
this._updateClockFromMessage(message);
|
2021-09-22 15:05:36 +10:00
|
|
|
|
|
|
|
return message;
|
2021-09-14 13:49:42 +10:00
|
|
|
}
|
2021-09-14 12:50:33 +10:00
|
|
|
|
2021-10-05 14:04:12 +11:00
|
|
|
public handleNewMessage(message: ChatMessage): void {
|
2021-09-23 14:33:09 +10:00
|
|
|
this._updateClockFromMessage(message);
|
2021-09-14 15:16:40 +10:00
|
|
|
}
|
|
|
|
|
2021-09-22 15:05:36 +10:00
|
|
|
private _nextClockAndTimestamp(): { clock: number; timestamp: number } {
|
2021-09-14 13:49:42 +10:00
|
|
|
let clock = this.lastClockValue;
|
|
|
|
const timestamp = Date.now();
|
2021-09-14 12:50:33 +10:00
|
|
|
|
2021-09-14 13:49:42 +10:00
|
|
|
if (!clock || clock < timestamp) {
|
|
|
|
clock = timestamp;
|
|
|
|
} else {
|
|
|
|
clock += 1;
|
|
|
|
}
|
2021-09-14 12:50:33 +10:00
|
|
|
|
2021-09-14 13:49:42 +10:00
|
|
|
return { clock, timestamp };
|
|
|
|
}
|
2021-09-14 12:50:33 +10:00
|
|
|
|
2021-09-23 14:33:09 +10:00
|
|
|
private _updateClockFromMessage(message: ChatMessage): void {
|
2021-10-05 14:04:12 +11:00
|
|
|
if (
|
|
|
|
!this.lastMessage ||
|
|
|
|
!this.lastMessage.clock ||
|
|
|
|
(message.clock && this.lastMessage.clock <= message.clock)
|
|
|
|
) {
|
2021-09-14 13:49:42 +10:00
|
|
|
this.lastMessage = message;
|
2021-09-14 12:50:33 +10:00
|
|
|
}
|
|
|
|
|
2021-10-05 14:04:12 +11:00
|
|
|
if (
|
|
|
|
!this.lastClockValue ||
|
|
|
|
(message.clock && this.lastClockValue < message.clock)
|
|
|
|
) {
|
2021-09-14 13:49:42 +10:00
|
|
|
this.lastClockValue = message.clock;
|
2021-09-14 12:50:33 +10:00
|
|
|
}
|
2021-09-14 13:49:42 +10:00
|
|
|
}
|
2021-09-14 12:50:33 +10:00
|
|
|
}
|