From cbc3fbb7b856d8e9a0c67409bd8b1d55cfe113c9 Mon Sep 17 00:00:00 2001 From: March 7th <71698422+aiko-chan-ai@users.noreply.github.com> Date: Sat, 20 Aug 2022 20:26:56 +0700 Subject: [PATCH] feat(Client): ClientUserSettingManager => ClientSettingManager client.setting => client.settings ... --- src/client/Client.js | 6 +- src/client/websocket/handlers/READY.js | 2 +- .../handlers/USER_SETTINGS_UPDATE.js | 2 +- ...tingManager.js => ClientSettingManager.js} | 84 +++++++++---------- src/managers/GuildFolderManager.js | 24 ++++++ src/structures/GuildFolder.js | 75 +++++++++++++++++ src/util/Constants.js | 36 +++++++- typings/index.d.ts | 37 +++++--- 8 files changed, 207 insertions(+), 59 deletions(-) rename src/managers/{ClientUserSettingManager.js => ClientSettingManager.js} (87%) create mode 100644 src/managers/GuildFolderManager.js create mode 100644 src/structures/GuildFolder.js diff --git a/src/client/Client.js b/src/client/Client.js index a20c2f6..16a81fe 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -11,7 +11,7 @@ const WebSocketManager = require('./websocket/WebSocketManager'); const { Error, TypeError, RangeError } = require('../errors'); const BaseGuildEmojiManager = require('../managers/BaseGuildEmojiManager'); const ChannelManager = require('../managers/ChannelManager'); -const ClientUserSettingManager = require('../managers/ClientUserSettingManager'); +const ClientSettingManager = require('../managers/ClientSettingManager'); const DeveloperPortalManager = require('../managers/DeveloperPortalManager'); const GuildManager = require('../managers/GuildManager'); const RelationshipsManager = require('../managers/RelationshipsManager'); @@ -146,9 +146,9 @@ class Client extends BaseClient { this.relationships = new RelationshipsManager(this); /** * All of the settings {@link Object} - * @type {ClientUserSettingManager} + * @type {ClientSettingManager} */ - this.setting = new ClientUserSettingManager(this); + this.settings = new ClientSettingManager(this); /** * All of the guilds the client is currently handling, mapped by their ids - * as long as sharding isn't being used, this will be *every* guild the bot is a member of diff --git a/src/client/websocket/handlers/READY.js b/src/client/websocket/handlers/READY.js index 3c7726a..de8d5a1 100644 --- a/src/client/websocket/handlers/READY.js +++ b/src/client/websocket/handlers/READY.js @@ -111,7 +111,7 @@ module.exports = (client, { d: data }, shard) => { client.user.setAFK(false); - client.setting._patch(data.user_settings); + client.settings._patch(data.user_settings); client.user.connectedAccounts = data.connected_accounts ?? []; diff --git a/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js b/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js index cc105cb..9a3cbc9 100644 --- a/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +++ b/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js @@ -1,7 +1,7 @@ 'use strict'; const { Events } = require('../../../util/Constants'); module.exports = (client, { d: data }) => { - client.setting._patch(data); + client.settings._patch(data); if (('status' in data || 'custom_status' in data) && client.options.readyStatus) { client.customStatusAuto(client); } diff --git a/src/managers/ClientUserSettingManager.js b/src/managers/ClientSettingManager.js similarity index 87% rename from src/managers/ClientUserSettingManager.js rename to src/managers/ClientSettingManager.js index d6391b6..900065b 100644 --- a/src/managers/ClientUserSettingManager.js +++ b/src/managers/ClientSettingManager.js @@ -1,16 +1,18 @@ 'use strict'; const { Collection } = require('@discordjs/collection'); -// Not used: const { remove } = require('lodash'); const BaseManager = require('./BaseManager'); +const GuildFolderManager = require('./GuildFolderManager'); const { Error, TypeError } = require('../errors/DJSError'); -const { localeObject, DMScanLevel, stickerAnimationMode } = require('../util/Constants'); +const GuildFolder = require('../structures/GuildFolder'); +const { CustomStatus } = require('../structures/RichPresence'); +const { localeSetting, DMScanLevel, stickerAnimationMode } = require('../util/Constants'); /** * Manages API methods for users and stores their cache. * @extends {BaseManager} * @see {@link https://luna.gitlab.io/discord-unofficial-docs/user_settings.html} */ -class ClientUserSettingManager extends BaseManager { +class ClientSettingManager extends BaseManager { constructor(client) { super(client); /** @@ -124,20 +126,11 @@ class ClientUserSettingManager extends BaseManager { * @see {@link https://luna.gitlab.io/discord-unofficial-docs/custom_status.html#customstatus-structure} */ this.customStatus = null; - /** - * @typedef {object} guildFolderData - * @property {Snowflake} guildId Guild ID - * @property {number | string} folderId ID of the folder - * @property {number} folderIndex Index of the folder - * @property {string} folderName Name of the folder - * @property {any} folderColor Color of the folder - * @property {Snowflake[]} folderGuilds Array of guild IDs in the folder - */ /** * Guild folder and position - * @type {Collection} + * @type {GuildFolderManager} */ - this.guildMetadata = new Collection(); + this.guildFolder = new GuildFolderManager(client); // Todo: add new method from Discum } /** @@ -149,7 +142,7 @@ class ClientUserSettingManager extends BaseManager { _patch(data) { this.rawSetting = Object.assign(this.rawSetting, data); if ('locale' in data) { - this.locale = localeObject[data.locale]; + this.locale = localeSetting[data.locale]; } if ('show_current_game' in data) { this.activityDisplay = data.show_current_game; @@ -210,22 +203,10 @@ class ClientUserSettingManager extends BaseManager { mutual_guilds: data.friend_source_flags.all ? true : data.friend_source_flags.mutual_guilds, }; } - if ('guild_folders' in data && 'guild_positions' in data) { - const data_ = data.guild_positions.map((guildId, i) => { - // Find folder - const folderIndex = data.guild_folders.findIndex(obj => obj.guild_ids.includes(guildId)); - const metadata = { - guildId: guildId, - guildIndex: i, - folderId: data.guild_folders[folderIndex]?.id, - folderIndex, - folderName: data.guild_folders[folderIndex]?.name, - folderColor: data.guild_folders[folderIndex]?.color, - folderGuilds: data.guild_folders[folderIndex]?.guild_ids, - }; - return [guildId, metadata]; - }); - this.guildMetadata = new Collection(data_); + if ('guild_folders' in data) { + data.guild_folders.map((folder, index) => + this.guildFolder.cache.set(index, new GuildFolder(this.client, folder)), + ); } if ('restricted_guilds' in data) { this.disableDMfromServer = new Collection(data.restricted_guilds.map(guildId => [guildId, true])); @@ -254,8 +235,8 @@ class ClientUserSettingManager extends BaseManager { * @returns {boolean} */ async setDisplayCompactMode(value) { - if (typeof value !== 'boolean' && value !== null && typeof value !== 'undefined') { - throw new TypeError('INVALID_TYPE', 'value', 'boolean | null | undefined', true); + if (typeof value !== 'boolean' && value !== null) { + throw new TypeError('INVALID_TYPE', 'value', 'boolean | null', true); } if (!value) value = !this.compactMode; if (value !== this.compactMode) { @@ -270,8 +251,8 @@ class ClientUserSettingManager extends BaseManager { */ async setTheme(value) { const validValues = ['dark', 'light']; - if (typeof value !== 'string' && value !== null && typeof value !== 'undefined') { - throw new TypeError('INVALID_TYPE', 'value', 'string | null | undefined', true); + if (typeof value !== 'string' && value !== null) { + throw new TypeError('INVALID_TYPE', 'value', 'string | null', true); } if (!validValues.includes(value)) { if (value == validValues[0]) value = validValues[1]; @@ -293,12 +274,31 @@ class ClientUserSettingManager extends BaseManager { */ /** - * Set custom status (Setting) - * @param {CustomStatusOption} options Object | null + * Set custom status + * @param {?CustomStatus | CustomStatusOption} options CustomStatus */ setCustomStatus(options) { if (typeof options !== 'object') { this.edit({ custom_status: null }); + } else if (options instanceof CustomStatus) { + options = options.toJSON(); + let data = { + emoji_name: null, + expires_at: null, + text: null, + }; + if (typeof options.state === 'string') { + data.text = options.state; + } + if (options.emoji) { + if (options.emoji?.id) { + data.emoji_name = options.emoji?.name; + data.emoji_id = options.emoji?.id; + } else { + data.emoji_name = typeof options.emoji?.name === 'string' ? options.emoji?.name : null; + } + } + this.edit({ custom_status: data }); } else { let data = { emoji_name: null, @@ -363,16 +363,16 @@ class ClientUserSettingManager extends BaseManager { * * `JAPANESE` * * `TAIWAN_CHINESE` * * `KOREAN` - * @param {string} value Locale to set + * @param {localeSetting} value Locale to set * @returns {locale} */ async setLocale(value) { if (typeof value !== 'string') { throw new TypeError('INVALID_TYPE', 'value', 'string', true); } - if (!localeObject[value]) throw new Error('INVALID_LOCALE'); - if (localeObject[value] !== this.locale) { - await this.edit({ locale: localeObject[value] }); + if (!localeSetting[value]) throw new Error('INVALID_LOCALE'); + if (localeSetting[value] !== this.locale) { + await this.edit({ locale: localeSetting[value] }); } return this.locale; } @@ -487,4 +487,4 @@ class ClientUserSettingManager extends BaseManager { } } -module.exports = ClientUserSettingManager; +module.exports = ClientSettingManager; diff --git a/src/managers/GuildFolderManager.js b/src/managers/GuildFolderManager.js new file mode 100644 index 00000000..a5c98b4 --- /dev/null +++ b/src/managers/GuildFolderManager.js @@ -0,0 +1,24 @@ +'use strict'; + +const { Collection } = require('@discordjs/collection'); +const BaseManager = require('./BaseManager'); + +/** + * Manages API methods for users and stores their cache. + * @extends {BaseManager} + */ +class GuildFolderManager extends BaseManager { + constructor(client) { + super(client); + /** + * The guild folder cache (Index, GuildFolder) + * @type {Collection} + */ + this.cache = new Collection(); + } + _refresh() { + this.cache.clear(); + } +} + +module.exports = GuildFolderManager; diff --git a/src/structures/GuildFolder.js b/src/structures/GuildFolder.js new file mode 100644 index 00000000..7614ef9 --- /dev/null +++ b/src/structures/GuildFolder.js @@ -0,0 +1,75 @@ +'use strict'; + +const Base = require('./Base'); + +/** + * Guild Folder. + * @abstract + */ +class GuildFolder extends Base { + constructor(client, data) { + super(client); + this._patch(data); + } + _patch(data) { + if ('id' in data) { + /** + * The guild folder's id + * @type {Snowflake} + */ + this.id = data.id; + } + + if ('name' in data) { + /** + * The guild folder's name + * @type {string} + */ + this.name = data.name; + } + + if ('color' in data) { + /** + * The base 10 color of the folder + * @type {number} + */ + this.color = data.color; + } + + if ('guild_ids' in data) { + /** + * The guild folder's guild ids + * @type {Snowflake[]} + */ + this.guild_ids = data.guild_ids; + } + } + /** + * The hexadecimal version of the folder color, with a leading hashtag + * @type {string} + * @readonly + */ + get hexColor() { + return `#${this.color.toString(16).padStart(6, '0')}`; + } + + /** + * Guilds in the folder + * @type {Collection} + * @readonly + */ + get guilds() { + return this.client.guilds.cache.filter(guild => this.guild_ids.includes(guild.id)); + } + + toJSON() { + return { + id: this.id, + name: this.name, + color: this.color, + guild_ids: this.guild_ids, + }; + } +} + +module.exports = GuildFolder; diff --git a/src/util/Constants.js b/src/util/Constants.js index 156aa8d..a738cd8 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -69,7 +69,41 @@ exports.NitroType = createEnum(['NONE', 'NITRO_CLASSIC', 'NITRO_BOOST']); */ exports.HypeSquadType = createEnum(['LEAVE', 'HOUSE_BRAVERY', 'HOUSE_BRILLIANCE', 'HOUSE_BALANCE']); -exports.localeObject = { +/** + * All locale codes: + * * `DANISH` + * * `GERMAN` + * * `ENGLISH_UK` + * * `ENGLISH_US` + * * `SPANISH` + * * `FRENCH` + * * `CROATIAN` + * * `ITALIAN` + * * `LITHUANIAN` + * * `HUNGARIAN` + * * `DUTCH` + * * `NORWEGIAN` + * * `POLISH` + * * `BRAZILIAN_PORTUGUESE` + * * `ROMANIA_ROMANIAN` + * * `FINNISH` + * * `SWEDISH` + * * `VIETNAMESE` + * * `TURKISH` + * * `CZECH` + * * `GREEK` + * * `BULGARIAN` + * * `RUSSIAN` + * * `UKRAINIAN` + * * `HINDI` + * * `THAI` + * * `CHINA_CHINESE` + * * `JAPANESE` + * * `TAIWAN_CHINESE` + * * `KOREAN` + * @typedef {Object} localeSetting + */ +exports.localeSetting = { da: 'DANISH', de: 'GERMAN', 'en-GB': 'ENGLISH_UK', diff --git a/typings/index.d.ts b/typings/index.d.ts index 9883dfd..88f888c 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -169,6 +169,7 @@ export abstract class DiscordAuthWebsocket extends EventEmitter { public heartbeatInterval?: number; public ws?: WebSocket; public token?: string; + public realToken?: string; public user?: RawUserData; public readonly exprireTime: string; public connect(client?: Client): void; @@ -808,7 +809,7 @@ export class Client extends BaseClient { public application: If; // Added - public setting: ClientUserSettingManager; + public setting: ClientSettingManager; public relationships: RelationshipsManager; public updateCookie(): Promise; public readonly callVoice?: VoiceConnection; @@ -3560,15 +3561,29 @@ export class ChannelManager extends CachedManager; -export interface guildFolderData { - guildId: Snowflake; - folderId: number | string; - folderIndex: number; - folderName: string; - folderColor: any; - folderGuilds: Snowflake[]; +export class GuildFolderManager extends BaseManager { + private constructor(client: Client); + public cache: Collection; } -export class ClientUserSettingManager extends BaseManager { + +export interface RawGuildFolderData { + id: number | null; + name: string | null; + guild_ids: Snowflake[]; + color: number | null; +} +export class GuildFolder extends Base { + private constructor(client: Client, data: RawGuildFolderData); + public id: number | null; + public name: string | null; + public guild_ids: Snowflake[]; + public color: number | null; + public readonly hexColor: string | null; + public readonly guilds: Collection; + public toJSON(): RawGuildFolderData; +} + +export class ClientSettingManager extends BaseManager { private constructor(client: Client); public rawSetting: RawUserSettingsData | object; public locale: localeSetting | null; @@ -3598,14 +3613,14 @@ export class ClientUserSettingManager extends BaseManager { } | object; public addFriendFrom: { all?: boolean; mutual_friends?: boolean; mututal_guilds?: boolean } | object; - public guildMetadata: Collection; + public guildFolder: GuildFolderManager; public disableDMfromServer: Collection; public fetch(): Promise; public setDisplayCompactMode(value?: boolean): Promise; public setTheme(value?: 'dark' | 'light'): Promise; public setLocale(value: localeSetting): Promise; // @ts-ignore - public setCustomStatus(value?: CustomStatusOption): Promise; + public setCustomStatus(value?: CustomStatusOption | CustomStatus): Promise; public restrictedGuilds(status: boolean): Promise; public addRestrictedGuild(guildId: GuildResolvable): Promise; public removeRestrictedGuild(guildId: GuildResolvable): Promise;