Add message nonces.

This commit is contained in:
Paul Makles
2020-02-18 15:49:47 +00:00
parent d5ec4965f8
commit 8a80b20471
7 changed files with 82 additions and 14 deletions
+1
View File
@@ -11,6 +11,7 @@
"isomorphic-ws": "^4.0.1",
"lodash": "^4.17.15",
"tsc-watch": "^4.1.0",
"ulid": "^2.3.0",
"ws": "^7.2.1"
},
"devDependencies": {
+4
View File
@@ -91,6 +91,10 @@ export class Client extends EventEmitter {
let m = packet.data as RawMessage & { channel: string };
let channel = await this.findChannel(m.channel);
if (m.nonce) {
channel.messages.delete(m.nonce);
}
this.emit('message', await Message.from(m.id, channel, m));
}
break;
+2
View File
@@ -27,6 +27,7 @@ export type RawChannel = {
export type RawMessage = {
id: string,
nonce?: string,
author: string,
content: string,
edited: number | null,
@@ -42,6 +43,7 @@ export namespace Channels {
// POST /:id/messages
export interface SendMessageRequest extends Request {
content: string,
nonce: string,
}
export interface SendMessageResponse extends Response {
+35 -14
View File
@@ -2,6 +2,7 @@ import { Channels, ChannelType } from '../api';
import { Client } from '../Client';
import { User } from './User';
import { Message } from './Message';
import { ulid } from 'ulid';
export class Channel {
client: Client;
@@ -69,21 +70,41 @@ export class Channel {
return messages;
}
async sendMessage(content: string) {
let res = await this.client.$req<Channels.SendMessageRequest, Channels.SendMessageResponse>('POST', '/channels/' + this.id + '/messages', { content });
sendMessage(content: string): [ Message, Promise<Message> ] {
if (content.length > 2000)
throw new Error("Message too long! > 2000 characters.");
if (res.success) {
let message = new Message(this, {
id: res.id,
author: this.client.userId as string,
content,
edited: null
});
let nonce = ulid();
let message = new Message(this, {
id: nonce,
nonce,
author: this.client.userId as string,
content,
edited: null
});
this.messages.set(this.id, message);
return message;
} else {
throw new Error(res.error);
}
this.messages.set(nonce, message);
return [
message,
(async () => {
let res = await this.client.$req<Channels.SendMessageRequest, Channels.SendMessageResponse>('POST', '/channels/' + this.id + '/messages', { content, nonce });
if (res.success) {
this.messages.delete(nonce);
Message.from(res.id, this,
{
id: this.id,
author: this.client.userId as string,
content,
edited: null,
}
);
return message;
} else {
throw new Error(res.error);
}
})()
]
}
}
+28
View File
@@ -8,10 +8,19 @@ export interface MessageSnapshot {
content: string,
}
export enum Sent {
UNSENT,
SENT,
FAILED,
}
export class Message {
channel: Channel;
id: string;
nonce: string;
sent: Sent;
user: User;
content: string;
edited: Date | null;
@@ -20,6 +29,7 @@ export class Message {
constructor(channel: Channel, data: RawMessage) {
this.channel = channel;
this.sent = Sent.UNSENT;
this.update(data);
}
@@ -57,12 +67,21 @@ export class Message {
message = new Message(channel, await channel.client.$req<Request, RawMessage>('GET', '/channels/' + channel.id + '/messages/' + id));
}
message.sent = Sent.SENT;
await message.$init();
channel.messages.set(id, message);
return message;
}
async edit(content: string) {
if (this.sent === Sent.FAILED) {
throw new Error("Cannot edit failed message!");
}
if (this.sent === Sent.UNSENT) {
throw new Error("Cannot delete unsent message!");
}
let res = await this.channel.client.$req<Channels.EditMessageRequest, Channels.EditMessageResponse>('PATCH', '/channels/' + this.channel.id + '/messages/' + this.id, { content });
if (res.success) {
@@ -73,6 +92,15 @@ export class Message {
}
async delete() {
if (this.sent === Sent.FAILED) {
this.channel.messages.delete(this.id);
return;
}
if (this.sent === Sent.UNSENT) {
throw new Error("Cannot delete unsent message!");
}
let res = await this.channel.client.$req<Request, Channels.DeleteMessageResponse>('DELETE', '/channels/' + this.channel.id + '/messages/' + this.id);
if (res.success) {
+7
View File
@@ -7,6 +7,13 @@ let client = new Client();
client.on('ready', () => {
console.log(`Logged in as ${client.user?.username}!`);
/*client.findChannel('01E1CDFQ4QWT93Q2Z6YWVTW2ND')
.then(async x => {
let [ temp, next ] = x.sendMessage('bruh');
await next;
console.log(Array.from(x.messages.values()).map(x => x.id));
})*/
});
client.on('message', msg => {
+5
View File
@@ -503,6 +503,11 @@ typescript@^3.8.0-dev.20200208:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.0-dev.20200208.tgz#3cd1ee025932c88ff78831f3629e99b1995e1de5"
integrity sha512-/n4f+RIfoHvEmXprHjE7dHzGlDzD0wpqpvHBXBtwaCi1wp8zsGqA07v1UPijR1xBqumO5FFDMEPIuu7fEDJemA==
ulid@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/ulid/-/ulid-2.3.0.tgz#93063522771a9774121a84d126ecd3eb9804071f"
integrity sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==
validate-npm-package-license@^3.0.1:
version "3.0.4"
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"