From 8a5ee2caeeaa87202d687ea7c022e26a144f0ecb Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Thu, 7 Jul 2022 14:36:47 +0100 Subject: [PATCH] feat: add emoji support --- package.json | 10 ++-- src/Client.ts | 11 +++++ src/index.ts | 1 + src/maps/Emojis.ts | 88 ++++++++++++++++++++++++++++++++++ src/websocket/client.ts | 15 ++++++ src/websocket/notifications.ts | 6 ++- yarn.lock | 8 ++-- 7 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 src/maps/Emojis.ts diff --git a/package.json b/package.json index 516b2e32..add520f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "revolt.js", - "version": "6.0.3", + "version": "6.0.4", "main": "dist/index.js", "typings": "dist/index.d.ts", "module": "esm/index.js", @@ -17,7 +17,7 @@ "lodash.isequal": "^4.5.0", "long": "^5.2.0", "mobx": "^6.3.2", - "revolt-api": "0.5.3-7", + "revolt-api": "0.5.4", "ulid": "^2.3.0", "ws": "^8.2.2" }, @@ -44,8 +44,12 @@ }, "eslintConfig": { "parser": "@typescript-eslint/parser", + "plugins": [ + "mobx" + ], "extends": [ - "plugin:@typescript-eslint/recommended" + "plugin:@typescript-eslint/recommended", + "plugin:mobx/recommended" ], "ignorePatterns": [ "build/" diff --git a/src/Client.ts b/src/Client.ts index d83790d2..b2ccba5e 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -16,6 +16,7 @@ import Members, { Member } from "./maps/Members"; import Messages, { Message } from "./maps/Messages"; import Servers, { Server } from "./maps/Servers"; import Users, { User } from "./maps/Users"; +import Emojis, { Emoji } from "./maps/Emojis"; import { WebSocketClient } from "./websocket/client"; import { ClientboundNotification } from "./websocket/notifications"; @@ -99,6 +100,12 @@ export declare interface Client { on(event: "member/leave", listener: (id: MemberCompositeKey) => void): this; on(event: "user/relationship", listener: (user: User) => void): this; + + on(event: "emoji/create", listener: (emoji: Emoji) => void): this; + on( + event: "emoji/delete", + listener: (id: string, emoji?: Emoji) => void, + ): this; } /** @@ -139,6 +146,7 @@ export class Client extends EventEmitter { members: Members; messages: Messages; bots: Bots; + emojis: Emojis; unreads?: Unreads; @@ -151,6 +159,7 @@ export class Client extends EventEmitter { this.members = new Members(this); this.messages = new Messages(this); this.bots = new Bots(this); + this.emojis = new Emojis(this); makeObservable( this, @@ -161,6 +170,7 @@ export class Client extends EventEmitter { servers: observable, members: observable, messages: observable, + emojis: observable, reset: action, }, { @@ -429,6 +439,7 @@ export class Client extends EventEmitter { this.servers = new Servers(this); this.members = new Members(this); this.messages = new Messages(this); + this.emojis = new Emojis(this); } /** diff --git a/src/index.ts b/src/index.ts index b034d9fd..4ec85780 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ export { Member } from "./maps/Members"; export { Message } from "./maps/Messages"; export { Server } from "./maps/Servers"; export { User } from "./maps/Users"; +export { Emoji } from "./maps/Emojis"; export * from "./Client"; export * from "./config"; diff --git a/src/maps/Emojis.ts b/src/maps/Emojis.ts new file mode 100644 index 00000000..63510bca --- /dev/null +++ b/src/maps/Emojis.ts @@ -0,0 +1,88 @@ +import type { Emoji as EmojiI, EmojiParent } from "revolt-api"; + +import { makeAutoObservable, runInAction } from "mobx"; + +import Collection from "./Collection"; +import { Client } from ".."; +import { decodeTime } from "ulid"; + +export class Emoji { + client: Client; + + _id: string; + name: string; + creator_id: string; + parent: EmojiParent; + animated: boolean; + + /** + * Get timestamp when this message was created. + */ + get createdAt() { + return decodeTime(this._id); + } + + /** + * Get creator of this emoji. + */ + get creator() { + return this.client.users.get(this.creator_id); + } + + constructor(client: Client, data: EmojiI) { + this.client = client; + this._id = data._id; + + this.name = data.name; + this.creator_id = data.creator_id; + this.parent = data.parent; + this.animated = data.animated; + + makeAutoObservable(this, { + _id: false, + client: false, + }); + } + + /** + * Delete a message + */ + async delete() { + return await this.client.api.delete(`/custom/emoji/${this._id as ""}`); + } + + /** + * Generate emoji URL + */ + get imageURL() { + return `${this.client.configuration?.features.autumn.url}/emojis/${ + this._id + }${this.animated ? "" : "?max_side=128"}`; + } +} + +export default class Emojis extends Collection { + constructor(client: Client) { + super(client); + this.createObj = this.createObj.bind(this); + } + + /** + * Create an emoji object. + * This is meant for internal use only. + * @param data Emoji Data + * @param emit Whether to emit creation event + * @returns Emoji + */ + createObj(data: EmojiI, emit?: boolean | number) { + if (this.has(data._id)) return this.get(data._id)!; + const emoji = new Emoji(this.client, data); + + runInAction(() => { + this.set(data._id, emoji); + }); + + if (emit === true) this.client.emit("emoji/create", emoji); + return emoji; + } +} diff --git a/src/websocket/client.ts b/src/websocket/client.ts index d0c70d22..42d5ecab 100644 --- a/src/websocket/client.ts +++ b/src/websocket/client.ts @@ -147,6 +147,10 @@ export class WebSocketClient { for (const member of packet.members) { this.client.members.createObj(member); } + + for (const emoji of packet.emojis!) { + this.client.emojis.createObj(emoji); + } }); this.client.user = this.client.users.get( @@ -575,6 +579,17 @@ export class WebSocketClient { break; } + case "EmojiCreate": { + this.client.emojis.createObj(packet, true); + break; + } + + case "EmojiDelete": { + const emoji = this.client.emojis.get(packet.id); + this.client.emit("emoji/delete", packet.id, emoji); + break; + } + case "Pong": { this.ping = +new Date() - packet.data; break; diff --git a/src/websocket/notifications.ts b/src/websocket/notifications.ts index 43acd1f0..75f5fd02 100644 --- a/src/websocket/notifications.ts +++ b/src/websocket/notifications.ts @@ -1,4 +1,5 @@ import type { + Emoji, FieldsChannel, FieldsMember, FieldsServer, @@ -30,6 +31,7 @@ export type ReadyPacket = { servers: Server[]; channels: Channel[]; members: Member[]; + emojis?: Emoji[]; }; export type ClientboundNotification = @@ -107,4 +109,6 @@ export type ClientboundNotification = type: "UserSettingsUpdate"; id: string; update: { [key: string]: [number, string] }; - }; + } + | ({ type: "EmojiCreate" } & Emoji) + | { type: "EmojiDelete"; id: string }; diff --git a/yarn.lock b/yarn.lock index 8272371e..01393114 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1015,10 +1015,10 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -revolt-api@0.5.3-7: - version "0.5.3-7" - resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.3-7.tgz#d6123654ed39321b1d745fdcec9f1c0bd4018bce" - integrity sha512-mBpM30OufJCS+6u1H/k0t8hbtFTur4eX6MtlEpCwBw/69FwMnO//isSwMMGnhGtwYiSM8o7xOlhF9Pb4OlKA0A== +revolt-api@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.4.tgz#cefbb05cbeeb7deb437aca9efb80ce277b8c04e4" + integrity sha512-JBoEzakPn11lq43BN2VMwyfeU8pC11Q6O07BuWjagMqBrjY8GdMdQIdmtmvudSiTogux6VsbGkV+0eVUUZ44xw== dependencies: "@insertish/oapi" "0.1.16" axios "^0.26.1"