diff --git a/client/src/modules/content.js b/client/src/modules/content.js index 2200c30a..fdc6c463 100644 --- a/client/src/modules/content.js +++ b/client/src/modules/content.js @@ -91,9 +91,9 @@ export default class Content { config: this.settings.strip().settings, data: this.data }); - this.settings.setSaved(); + this.settings.setSaved(); } catch (err) { - Logger.err(this.name, ['Failed to save configuration', err]); + Logger.err(this.name, ['Failed to save configuration', err]); throw err; } } diff --git a/client/src/modules/database.js b/client/src/modules/database.js index 9b6e475d..1405b4aa 100644 --- a/client/src/modules/database.js +++ b/client/src/modules/database.js @@ -16,6 +16,12 @@ export default class { return true; } + /** + * Inserts or updates data in the database. + * @param {Object} args The record to find + * @param {Object} data The new record + * @return {Promise} + */ static async insertOrUpdate(args, data) { try { return ClientIPC.send('bd-dba', { action: 'update', args, data }); @@ -24,6 +30,11 @@ export default class { } } + /** + * Finds data in the database. + * @param {Object} args The record to find + * @return {Promise} + */ static async find(args) { try { return ClientIPC.send('bd-dba', { action: 'find', args }); diff --git a/client/src/modules/discordapi.js b/client/src/modules/discordapi.js index 661976e9..948a73da 100644 --- a/client/src/modules/discordapi.js +++ b/client/src/modules/discordapi.js @@ -402,7 +402,7 @@ export default class DiscordApi { static get currentChannel() { const channel = Modules.ChannelStore.getChannel(Modules.SelectedChannelStore.getChannelId()); - return channel.isPrivate ? new PrivateChannel(channel) : new GuildChannel(channel); + if (channel) return channel.isPrivate() ? new PrivateChannel(channel) : new GuildChannel(channel); } static get currentUser() { @@ -415,5 +415,5 @@ export default class DiscordApi { for (const id of friends) returnUsers.push(User.fromId(id)); return returnUsers; } - + } diff --git a/client/src/modules/eventhook.js b/client/src/modules/eventhook.js index 9ae647f4..d6ba83b4 100644 --- a/client/src/modules/eventhook.js +++ b/client/src/modules/eventhook.js @@ -1,5 +1,5 @@ /** - * BetterDiscord WebpackModules Module + * BetterDiscord Event Hook * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks * All rights reserved. * https://betterdiscord.net @@ -8,14 +8,13 @@ * LICENSE file in the root directory of this source tree. */ -import EventListener from './eventlistener'; -import { Utils } from 'common'; -import Events from './events'; +import { Utils, ClientLogger as Logger } from 'common'; import { WebpackModules } from './webpackmodules'; +import Events from './events'; +import EventListener from './eventlistener'; import * as SocketStructs from '../structs/socketstructs'; - /** * Discord socket event hook * @extends {EventListener} @@ -23,7 +22,7 @@ import * as SocketStructs from '../structs/socketstructs'; export default class extends EventListener { init() { - console.log(SocketStructs); + Logger.log('EventHook', SocketStructs); this.hook(); } @@ -44,11 +43,11 @@ export default class extends EventListener { orig.call(this, ...args); self.wsc = this; self.emit(...args); - } + }; } get eventsModule() { - return WebpackModules.getModuleByPrototypes(['setMaxListeners', 'emit']); + return WebpackModules.getModuleByName('Events'); } /** @@ -66,8 +65,8 @@ export default class extends EventListener { /** * Emit callback - * @param {any} e Event Action - * @param {any} d Event Args + * @param {any} event Event + * @param {any} data Event data */ dispatch(e, d) { Events.emit('raw-event', { type: e, data: d }); @@ -143,7 +142,7 @@ export default class extends EventListener { LFG_LISTING_CREATE: 'LFG_LISTING_CREATE', // No groups here LFG_LISTING_DELETE: 'LFG_LISTING_DELETE', // Thank you BRAINTREE_POPUP_BRIDGE_CALLBACK: 'BRAINTREE_POPUP_BRIDGE_CALLBACK' // What - } + }; } } diff --git a/client/src/modules/events.js b/client/src/modules/events.js index c60f8ee3..7021d33e 100644 --- a/client/src/modules/events.js +++ b/client/src/modules/events.js @@ -12,14 +12,39 @@ import { EventEmitter } from 'events'; const emitter = new EventEmitter(); export default class { - static on(eventName, callBack) { - emitter.on(eventName, callBack); + + /** + * Adds an event listener. + * @param {String} event The event to listen for + * @param {Function} callback The function to call when the event is emitted + */ + static on(event, callback) { + emitter.on(event, callback); } - static off(eventName, callBack) { - emitter.removeListener(eventName, callBack); + /** + * Adds an event listener that is only called once. + * @param {String} event The event to listen for + * @param {Function} callback The function to call when the event is emitted + */ + static once(event, callback) { + emitter.once(event, callback); } + /** + * Removes an event listener. + * @param {String} event The event to remove + * @param {Function} callback The listener to remove + */ + static off(event, callback) { + emitter.removeListener(event, callback); + } + + /** + * Emits an event + * @param {String} event The event to emit + * @param {Any} ...data Data to pass to the event listeners + */ static emit(...args) { emitter.emit(...args); } diff --git a/client/src/modules/eventswrapper.js b/client/src/modules/eventswrapper.js index 49a654cd..8196e561 100644 --- a/client/src/modules/eventswrapper.js +++ b/client/src/modules/eventswrapper.js @@ -11,7 +11,8 @@ const eventemitters = new WeakMap(); export default class EventsWrapper { - constructor(eventemitter) { + + constructor(eventemitter, bind) { eventemitters.set(this, eventemitter); } @@ -19,26 +20,33 @@ export default class EventsWrapper { return this._eventSubs || (this._eventSubs = []); } + get on() { return this.subscribe } subscribe(event, callback) { if (this.eventSubs.find(e => e.event === event && e.callback === callback)) return; - this.eventSubs.push({ - event, - callback - }); - eventemitters.get(this).on(event, callback); + const boundCallback = () => callback.apply(this.bind, arguments); + this.eventSubs.push({ event, callback, boundCallback }); + eventemitters.get(this).on(event, boundCallback); } + once(event, callback) { + if (this.eventSubs.find(e => e.event === event && e.callback === callback)) return; + const boundCallback = () => this.off(event, callback) && callback.apply(this.bind, arguments); + this.eventSubs.push({ event, callback, boundCallback }); + eventemitters.get(this).on(event, boundCallback); + } + + get off() { return this.unsubscribe } unsubscribe(event, callback) { for (let index of this.eventSubs) { - if (this.eventSubs[index].event !== event || (callback && this.eventSubs[index].callback === callback)) return; - eventemitters.get(this).off(event, this.eventSubs[index].callback); + if (this.eventSubs[index].event !== event || (callback && this.eventSubs[index].callback === callback)) continue; + eventemitters.get(this).off(event, this.eventSubs[index].boundCallback); this.eventSubs.splice(index, 1); } } unsubscribeAll() { for (let event of this.eventSubs) { - eventemitters.get(this).off(event.event, event.callback); + eventemitters.get(this).off(event.event, event.boundCallback); } this.eventSubs.splice(0, this.eventSubs.length); } diff --git a/client/src/modules/module.js b/client/src/modules/module.js index c786e366..c358662d 100644 --- a/client/src/modules/module.js +++ b/client/src/modules/module.js @@ -5,20 +5,19 @@ * https://github.com/JsSucks - https://betterdiscord.net * * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. -*/ - -/* -Base Module that every non-static module should extend + * LICENSE file in the root directory of this source tree. */ +/** + * Base Module that every non-static module should extend + */ export default class Module { constructor(args) { this.__ = { state: args || {}, args - } + }; this.setState = this.setState.bind(this); this.initialize(); } @@ -38,7 +37,6 @@ export default class Module { set args(t) { } get args() { return this.__.args; } - set state(state) { return this.__.state = state; } get state() { return this.__.state; } diff --git a/client/src/modules/modulemanager.js b/client/src/modules/modulemanager.js index c1f69d51..99d9324c 100644 --- a/client/src/modules/modulemanager.js +++ b/client/src/modules/modulemanager.js @@ -18,6 +18,9 @@ import Updater from './updater'; */ export default class { + /** + * An array of modules. + */ static get modules() { return this._modules ? this._modules : (this._modules = [ new ProfileBadges(), @@ -28,6 +31,10 @@ export default class { ]); } + /** + * Initializes all modules. + * @return {Promise} + */ static async initModules() { for (let module of this.modules) { try { diff --git a/client/src/modules/plugin.js b/client/src/modules/plugin.js index 7b786eff..dcf26bef 100644 --- a/client/src/modules/plugin.js +++ b/client/src/modules/plugin.js @@ -15,12 +15,8 @@ export default class Plugin extends Content { get type() { return 'plugin' } - // Don't use - these will eventually be removed! - get pluginPath() { return this.contentPath } - get pluginConfig() { return this.config } - get start() { return this.enable } - get stop() { return this.disable } + get stop() { return this.disable } unload() { PluginManager.unloadPlugin(this); diff --git a/client/src/modules/pluginapi.js b/client/src/modules/pluginapi.js index 3bb93be8..670a407c 100644 --- a/client/src/modules/pluginapi.js +++ b/client/src/modules/pluginapi.js @@ -1,5 +1,5 @@ /** - * BetterDiscord Plugin Api + * BetterDiscord Plugin API * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks * All rights reserved. * https://betterdiscord.net @@ -8,7 +8,7 @@ * LICENSE file in the root directory of this source tree. */ -import { Utils, ClientLogger as Logger, ClientIPC } from 'common'; +import { Utils, ClientLogger as Logger, ClientIPC, AsyncEventEmitter } from 'common'; import Settings from './settings'; import ExtModuleManager from './extmodulemanager'; import PluginManager from './pluginmanager'; @@ -24,27 +24,20 @@ import { MonkeyPatch } from './patcher'; export default class PluginApi { - constructor(pluginInfo) { + constructor(pluginInfo, pluginPath) { this.pluginInfo = pluginInfo; + this.pluginPath = pluginPath; + this.Events = new EventsWrapper(Events); + Utils.defineSoftGetter(this.Events, 'bind', () => this.plugin); + this._menuItems = undefined; this._injectedStyles = undefined; this._modalStack = undefined; } - get Discord() { - return DiscordApi; - } - get ReactComponents() { - return ReactComponents; - } - get Reflection() { - return Reflection; - } - get MonkeyPatch() { - return module => MonkeyPatch(this.pluginInfo.id, module); - } + get plugin() { - return PluginManager.getPluginById(this.pluginInfo.id || this.pluginInfo.name.toLowerCase().replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-')); + return PluginManager.getPluginByPath(this.pluginPath); } async bridge(plugin_id) { @@ -61,15 +54,18 @@ export default class PluginApi { get Api() { return this } + get AsyncEventEmitter() { return AsyncEventEmitter } + get EventsWrapper() { return EventsWrapper } + /** * Logger */ - loggerLog(...message) { Logger.log(this.pluginInfo.name, message) } - loggerErr(...message) { Logger.err(this.pluginInfo.name, message) } - loggerWarn(...message) { Logger.warn(this.pluginInfo.name, message) } - loggerInfo(...message) { Logger.info(this.pluginInfo.name, message) } - loggerDbg(...message) { Logger.dbg(this.pluginInfo.name, message) } + loggerLog(...message) { Logger.log(this.plugin.name, message) } + loggerErr(...message) { Logger.err(this.plugin.name, message) } + loggerWarn(...message) { Logger.warn(this.plugin.name, message) } + loggerInfo(...message) { Logger.info(this.plugin.name, message) } + loggerDbg(...message) { Logger.dbg(this.plugin.name, message) } get Logger() { return { log: this.loggerLog.bind(this), @@ -381,6 +377,24 @@ export default class PluginApi { }); } + /** + * DiscordApi + */ + + get Discord() { + return DiscordApi; + } + + get ReactComponents() { + return ReactComponents; + } + get Reflection() { + return Reflection; + } + get MonkeyPatch() { + return module => MonkeyPatch(this.plugin.id, module); + } + } // Stop plugins from modifying the plugin API for all plugins diff --git a/client/src/modules/pluginmanager.js b/client/src/modules/pluginmanager.js index 198d06e1..9275eda2 100644 --- a/client/src/modules/pluginmanager.js +++ b/client/src/modules/pluginmanager.js @@ -76,12 +76,12 @@ export default class extends ContentManager { static async loadPlugin(paths, configs, info, main, dependencies, permissions) { if (permissions && permissions.length > 0) { for (let perm of permissions) { - console.log(`Permission: ${Permissions.permissionText(perm).HEADER} - ${Permissions.permissionText(perm).BODY}`); + Logger.log(this.moduleName, `Permission: ${Permissions.permissionText(perm).HEADER} - ${Permissions.permissionText(perm).BODY}`); } try { const allowed = await Modals.permissions(`${info.name} wants to:`, info.name, permissions).promise; } catch (err) { - return null; + return; } } @@ -98,7 +98,7 @@ export default class extends ContentManager { } } - const plugin = window.require(paths.mainPath)(Plugin, new PluginApi(info), Vendor, deps); + const plugin = window.require(paths.mainPath)(Plugin, new PluginApi(info, paths.contentPath), Vendor, deps); if (!(plugin.prototype instanceof Plugin)) throw {message: `Plugin ${info.name} did not return a class that extends Plugin.`}; diff --git a/client/src/modules/settings.js b/client/src/modules/settings.js index de4f4a0b..f382ec0d 100644 --- a/client/src/modules/settings.js +++ b/client/src/modules/settings.js @@ -8,22 +8,23 @@ * LICENSE file in the root directory of this source tree. */ -import defaultSettings from '../data/user.settings.default'; -import Globals from './globals'; -import CssEditor from './csseditor'; -import Events from './events'; import { Utils, FileUtils, ClientLogger as Logger } from 'common'; import { SettingsSet, SettingUpdatedEvent } from 'structs'; import path from 'path'; +import Globals from './globals'; +import CssEditor from './csseditor'; +import Events from './events'; +import defaultSettings from '../data/user.settings.default'; export default new class Settings { + constructor() { this.settings = defaultSettings.map(_set => { const set = new SettingsSet(_set); set.on('setting-updated', event => { const { category, setting, value, old_value } = event; - Logger.log('Settings', `${set.id}/${category.id}/${setting.id} was changed from ${old_value} to ${value}`); + Logger.log('Settings', [`${set.id}/${category.id}/${setting.id} was changed from`, old_value, 'to', value]); Events.emit('setting-updated', event); Events.emit(`setting-updated-${set.id}_${category.id}_${setting.id}`, event); }); @@ -37,6 +38,9 @@ export default new class Settings { }); } + /** + * Loads BetterDiscord's settings. + */ async loadSettings() { try { await FileUtils.ensureDirectory(this.dataPath); @@ -48,7 +52,7 @@ export default new class Settings { for (let set of this.settings) { const newSet = settings.find(s => s.id === set.id); if (!newSet) continue; - set.merge(newSet); + await set.merge(newSet); set.setSaved(); } @@ -61,6 +65,9 @@ export default new class Settings { } } + /** + * Saves BetterDiscord's settings including CSS editor data. + */ async saveSettings() { try { await FileUtils.ensureDirectory(this.dataPath); @@ -72,15 +79,10 @@ export default new class Settings { css: CssEditor.css, css_editor_files: CssEditor.files, scss_error: CssEditor.error, - css_editor_bounds: { - width: CssEditor.editor_bounds.width, - height: CssEditor.editor_bounds.height, - x: CssEditor.editor_bounds.x, - y: CssEditor.editor_bounds.y - } + css_editor_bounds: CssEditor.editor_bounds }); - for (let set of this.getSettings) { + for (let set of this.settings) { set.setSaved(); } } catch (err) { @@ -90,8 +92,13 @@ export default new class Settings { } } + /** + * Finds one of BetterDiscord's settings sets. + * @param {String} set_id The ID of the set to find + * @return {SettingsSet} + */ getSet(set_id) { - return this.getSettings.find(s => s.id === set_id); + return this.settings.find(s => s.id === set_id); } get core() { return this.getSet('core') } @@ -100,39 +107,46 @@ export default new class Settings { get css() { return this.getSet('css') } get security() { return this.getSet('security') } + /** + * Finds a category in one of BetterDiscord's settings sets. + * @param {String} set_id The ID of the set to look in + * @param {String} category_id The ID of the category to find + * @return {SettingsCategory} + */ getCategory(set_id, category_id) { const set = this.getSet(set_id); return set ? set.getCategory(category_id) : undefined; } + /** + * Finds a setting in one of BetterDiscord's settings sets. + * @param {String} set_id The ID of the set to look in + * @param {String} category_id The ID of the category to look in + * @param {String} setting_id The ID of the setting to find + * @return {Setting} + */ getSetting(set_id, category_id, setting_id) { const set = this.getSet(set_id); return set ? set.getSetting(category_id, setting_id) : undefined; } + /** + * Returns a setting's value in one of BetterDiscord's settings sets. + * @param {String} set_id The ID of the set to look in + * @param {String} category_id The ID of the category to look in + * @param {String} setting_id The ID of the setting to find + * @return {Any} + */ get(set_id, category_id, setting_id) { const set = this.getSet(set_id); return set ? set.get(category_id, setting_id) : undefined; } - async mergeSettings(set_id, newSettings) { - const set = this.getSet(set_id); - if (!set) return; - - return await set.merge(newSettings); - } - - setSetting(set_id, category_id, setting_id, value) { - const setting = this.getSetting(set_id, category_id, setting_id); - if (!setting) throw {message: `Tried to set ${set_id}/${category_id}/${setting_id}, which doesn't exist`}; - setting.value = value; - } - - get getSettings() { - return this.settings; - } - + /** + * The path to store user data in. + */ get dataPath() { return Globals.getPath('data'); } + } diff --git a/client/src/modules/socketproxy.js b/client/src/modules/socketproxy.js index 745d32a8..e3657343 100644 --- a/client/src/modules/socketproxy.js +++ b/client/src/modules/socketproxy.js @@ -8,6 +8,7 @@ * LICENSE file in the root directory of this source tree. */ +import { ClientLogger as Logger } from 'common'; import EventListener from './eventlistener'; export default class SocketProxy extends EventListener { @@ -19,7 +20,7 @@ export default class SocketProxy extends EventListener { get eventBindings() { return [ - { id: 'socket-created', 'callback': this.socketCreated } + { id: 'socket-created', callback: this.socketCreated } ]; } @@ -29,11 +30,11 @@ export default class SocketProxy extends EventListener { socketCreated(socket) { this.activeSocket = socket; - // socket.addEventListener('message', this.onMessage); + // socket.addEventListener('message', this.onMessage); } onMessage(e) { - console.info(e); + Logger.info('SocketProxy', e); } } diff --git a/client/src/modules/theme.js b/client/src/modules/theme.js index b02ba3ed..bbabc810 100644 --- a/client/src/modules/theme.js +++ b/client/src/modules/theme.js @@ -31,10 +31,6 @@ export default class Theme extends Content { get type() { return 'theme' } get css() { return this.data.css } - // Don't use - these will eventually be removed! - get themePath() { return this.contentPath } - get themeConfig() { return this.config } - /** * Called when settings are updated. * This can be overridden by other content types. @@ -63,7 +59,7 @@ export default class Theme extends Content { * @return {Promise} */ async compile() { - console.log('Compiling CSS'); + Logger.log(this.name, 'Compiling CSS'); if (this.info.type === 'sass') { const config = await ThemeManager.getConfigAsSCSS(this.settings); @@ -76,7 +72,7 @@ export default class Theme extends Content { Logger.log(this.name, ['Finished compiling theme', new class Info { get SCSS_variables() { console.log(config); } get Compiled_SCSS() { console.log(result.css.toString()); } - get Result() { console.log(result); } + get Result() { console.log(result); } }]); return { @@ -121,6 +117,7 @@ export default class Theme extends Content { */ set files(files) { this.data.files = files; + if (Settings.get('css', 'default', 'watch-files')) this.watchfiles = files; } diff --git a/client/src/modules/thememanager.js b/client/src/modules/thememanager.js index 81276c5d..dfaf7a37 100644 --- a/client/src/modules/thememanager.js +++ b/client/src/modules/thememanager.js @@ -74,6 +74,11 @@ export default class ThemeManager extends ContentManager { return theme instanceof Theme; } + /** + * Returns a representation of a settings set's values in SCSS. + * @param {SettingsSet} settingsset The set to convert to SCSS + * @return {Promise} + */ static async getConfigAsSCSS(settingsset) { const variables = []; @@ -87,6 +92,11 @@ export default class ThemeManager extends ContentManager { return variables.join('\n'); } + /** + * Returns a representation of a settings set's values as an SCSS map. + * @param {SettingsSet} settingsset The set to convert to an SCSS map + * @return {Promise} + */ static async getConfigAsSCSSMap(settingsset) { const variables = []; @@ -100,6 +110,11 @@ export default class ThemeManager extends ContentManager { return '(' + variables.join(', ') + ')'; } + /** + * Returns a setting's name and value as a string that can be included in SCSS. + * @param {Setting} setting The setting to convert to SCSS + * @return {Promise} + */ static async parseSetting(setting) { const { type, id, value } = setting; const name = id.replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-'); @@ -108,6 +123,11 @@ export default class ThemeManager extends ContentManager { if (scss) return [name, scss]; } + /** + * Escapes a string so it can be included in SCSS. + * @param {String} value The string to escape + * @return {String} + */ static toSCSSString(value) { if (typeof value !== 'string' && value.toString) value = value.toString(); return `'${typeof value === 'string' ? value.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') : ''}'`; diff --git a/client/src/modules/updater.js b/client/src/modules/updater.js index 08efbc8c..36ec548d 100644 --- a/client/src/modules/updater.js +++ b/client/src/modules/updater.js @@ -22,6 +22,9 @@ export default class { this.checkForUpdates = this.checkForUpdates.bind(this); } + /** + * The interval to wait before checking for updates. + */ get interval() { return 60 * 1000 * 30; } @@ -30,34 +33,51 @@ export default class { this.updateInterval = setInterval(this.checkForUpdates, this.interval); } + /** + * Installs an update. + * TODO + */ update() { - // TODO this.updatesAvailable = false; Events.emit('update-check-end'); } + /** + * Checks for updates. + * @return {Promise} + */ checkForUpdates() { - if (this.updatesAvailable) return; - Events.emit('update-check-start'); - Logger.info('Updater', 'Checking for updates'); - $.ajax({ - type: 'GET', - url: 'https://rawgit.com/JsSucks/BetterDiscordApp/master/package.json', - cache: false, - success: e => { - try { - Events.emit('update-check-end'); - Logger.info('Updater', - `Latest Version: ${e.version} - Current Version: ${Globals.version}`); - if (e.version !== Globals.version) { - this.updatesAvailable = true; - Events.emit('updates-available'); + return new Promise((resolve, reject) => { + if (this.updatesAvailable) return resolve(true); + Events.emit('update-check-start'); + Logger.info('Updater', 'Checking for updates'); + + $.ajax({ + type: 'GET', + url: 'https://rawgit.com/JsSucks/BetterDiscordApp/master/package.json', + cache: false, + success: e => { + try { + Events.emit('update-check-end'); + Logger.info('Updater', `Latest Version: ${e.version} - Current Version: ${Globals.getObject('version')}`); + + if (e.version !== Globals.getObject('version')) { + this.updatesAvailable = true; + Events.emit('updates-available'); + resolve(true); + } + + resolve(false); + } catch (err) { + Events.emit('update-check-fail', err); + reject(err); } - } catch (err) { + }, + fail: err => { Events.emit('update-check-fail', err); + reject(err); } - }, - fail: e => Events.emit('update-check-fail', e) + }); }); } diff --git a/client/src/modules/vendor.js b/client/src/modules/vendor.js index 7ce84fa1..29d5a804 100644 --- a/client/src/modules/vendor.js +++ b/client/src/modules/vendor.js @@ -16,22 +16,21 @@ export { jQuery as $ }; export default class { - static get jQuery() { - return jQuery; - } + /** + * jQuery + */ + static get jQuery() { return jQuery } + static get $() { return this.jQuery } - static get $() { - return this.jQuery; - } - - static get lodash() { - return lodash; - } - - static get _() { - return this.lodash; - } + /** + * Lodash + */ + static get lodash() { return lodash } + static get _() { return this.lodash } + /** + * Moment + */ static get moment() { return WebpackModules.getModuleByName('Moment'); } diff --git a/client/src/modules/webpackmodules.js b/client/src/modules/webpackmodules.js index 82906d67..71b03ecd 100644 --- a/client/src/modules/webpackmodules.js +++ b/client/src/modules/webpackmodules.js @@ -51,6 +51,8 @@ const KnownModules = { React: Filters.byProperties(['createElement', 'cloneElement']), ReactDOM: Filters.byProperties(['render', 'findDOMNode']), + Events: Filters.byPrototypeFields(['setMaxListeners', 'emit']), + /* Guild Info, Stores, and Utilities */ GuildStore: Filters.byProperties(['getGuild']), SortedGuildStore: Filters.byProperties(['getSortedGuilds']), @@ -207,37 +209,37 @@ const KnownModules = { export class WebpackModules { - /** - * Finds a module using a filter function. - * @param {Function} filter A function to use to filter modules - * @param {Boolean} first Whether to return only the first matching module - * @return {Any} - */ - static getModule(filter, first = true) { - const modules = this.getAllModules(); - const rm = []; - for (let index in modules) { - if (!modules.hasOwnProperty(index)) continue; - const module = modules[index]; - const { exports } = module; - let foundModule = null; + /** + * Finds a module using a filter function. + * @param {Function} filter A function to use to filter modules + * @param {Boolean} first Whether to return only the first matching module + * @return {Any} + */ + static getModule(filter, first = true) { + const modules = this.getAllModules(); + const rm = []; + for (let index in modules) { + if (!modules.hasOwnProperty(index)) continue; + const module = modules[index]; + const { exports } = module; + let foundModule = null; - if (!exports) continue; - if (exports.__esModule && exports.default && filter(exports.default)) foundModule = exports.default; - if (filter(exports)) foundModule = exports; - if (!foundModule) continue; - if (first) return foundModule; - rm.push(foundModule); - } - return first || rm.length == 0 ? undefined : rm; - } + if (!exports) continue; + if (exports.__esModule && exports.default && filter(exports.default)) foundModule = exports.default; + if (filter(exports)) foundModule = exports; + if (!foundModule) continue; + if (first) return foundModule; + rm.push(foundModule); + } + return first || rm.length == 0 ? undefined : rm; + } - /** - * Finds a module by it's name. - * @param {String} name The name of the module - * @param {Function} fallback A function to use to filter modules if not finding a known module - * @return {Any} - */ + /** + * Finds a module by it's name. + * @param {String} name The name of the module + * @param {Function} fallback A function to use to filter modules if not finding a known module + * @return {Any} + */ static getModuleByName(name, fallback) { if (Cache.hasOwnProperty(name)) return Cache[name]; if (KnownModules.hasOwnProperty(name)) fallback = KnownModules[name]; @@ -246,48 +248,48 @@ export class WebpackModules { return module ? Cache[name] = module : undefined; } - /** - * Finds a module by it's display name. - * @param {String} name The display name of the module - * @return {Any} - */ + /** + * Finds a module by it's display name. + * @param {String} name The display name of the module + * @return {Any} + */ static getModuleByDisplayName(name) { return this.getModule(Filters.byDisplayName(name), true); } - /** - * Finds a module using it's code. - * @param {RegEx} regex A regular expression to use to filter modules - * @param {Boolean} first Whether to return the only the first matching module - * @return {Any} - */ + /** + * Finds a module using it's code. + * @param {RegEx} regex A regular expression to use to filter modules + * @param {Boolean} first Whether to return the only the first matching module + * @return {Any} + */ static getModuleByRegex(regex, first = true) { return this.getModule(Filters.byCode(regex), first); } - /** - * Finds a module using properties on it's prototype. - * @param {Array} props Properties to use to filter modules - * @param {Boolean} first Whether to return only the first matching module - * @return {Any} - */ + /** + * Finds a module using properties on it's prototype. + * @param {Array} props Properties to use to filter modules + * @param {Boolean} first Whether to return only the first matching module + * @return {Any} + */ static getModuleByPrototypes(prototypes, first = true) { return this.getModule(Filters.byPrototypeFields(prototypes), first); } - /** - * Finds a module using it's own properties. - * @param {Array} props Properties to use to filter modules - * @param {Boolean} first Whether to return only the first matching module - * @return {Any} - */ + /** + * Finds a module using it's own properties. + * @param {Array} props Properties to use to filter modules + * @param {Boolean} first Whether to return only the first matching module + * @return {Any} + */ static getModuleByProps(props, first = true) { return this.getModule(Filters.byProperties(props), first); } - /** - * Discord's __webpack_require__ function. - */ + /** + * Discord's __webpack_require__ function. + */ static get require() { if (this._require) return this._require; const id = 'bd-webpackmodules'; diff --git a/client/src/structs/events/error.js b/client/src/structs/events/error.js index 04f8bf8f..4268c753 100644 --- a/client/src/structs/events/error.js +++ b/client/src/structs/events/error.js @@ -17,22 +17,37 @@ export default class ErrorEvent extends Event { this.showStack = false; // For error modal } + /** + * The module the error occured in. + */ get module() { return this.args.module; } + /** + * A message describing the error. + */ get message() { return this.args.message; } + /** + * The original error object. + */ get err() { return this.args.err; } + /** + * A trace showing which functions were called when the error occured. + */ get stackTrace() { return this.err.stack; } + /** + * The type of event. + */ get __eventType() { return 'error'; } diff --git a/client/src/structs/events/event.js b/client/src/structs/events/event.js index 1159910e..cb26edf6 100644 --- a/client/src/structs/events/event.js +++ b/client/src/structs/events/event.js @@ -17,14 +17,23 @@ export default class Event { }; } + /** + * An object containing information about the event. + */ get event() { return this.__eventInfo; } + /** + * The first argument that was passed to the constructor, which contains information about the event. + */ get args() { return this.event.args[0]; } - get __eventType() { return null; } + /** + * The type of event. + */ + get __eventType() { return undefined; } } diff --git a/client/src/structs/events/settingsupdated.js b/client/src/structs/events/settingsupdated.js index 99470ea7..8c8965ad 100644 --- a/client/src/structs/events/settingsupdated.js +++ b/client/src/structs/events/settingsupdated.js @@ -12,10 +12,16 @@ import Event from './event'; export default class SettingsUpdatedEvent extends Event { + /** + * An array of SettingUpdated events. + */ get updatedSettings() { return this.args.updatedSettings; } + /** + * The type of event. + */ get __eventType() { return 'settings-updated'; } diff --git a/client/src/structs/events/settingupdated.js b/client/src/structs/events/settingupdated.js index 9edbb19f..c69e81db 100644 --- a/client/src/structs/events/settingupdated.js +++ b/client/src/structs/events/settingupdated.js @@ -12,38 +12,65 @@ import Event from './event'; export default class SettingUpdatedEvent extends Event { + /** + * The set containing the setting that was updated. + */ get set() { return this.args.set; } + /** + * The ID of the set containing the setting that was updated. + */ get set_id() { - return this.args.set.id; + return this.set.id; } + /** + * The category containing the setting that was updated. + */ get category() { return this.args.category; } + /** + * The ID of the category containing the setting that was updated. + */ get category_id() { - return this.args.category.id; + return this.category.id; } + /** + * The setting that was updated. + */ get setting() { return this.args.setting; } + /** + * The ID of the setting that was updated. + */ get setting_id() { - return this.args.setting.id; + return this.setting.id; } + /** + * The setting's new value. + */ get value() { return this.args.value; } + /** + * The setting's old value. + */ get old_value() { return this.args.old_value; } + /** + * The type of event. + */ get __eventType() { return 'setting-updated'; } diff --git a/client/src/structs/settings/multiplechoiceoption.js b/client/src/structs/settings/multiplechoiceoption.js index 70f8abbe..3e583c91 100644 --- a/client/src/structs/settings/multiplechoiceoption.js +++ b/client/src/structs/settings/multiplechoiceoption.js @@ -14,22 +14,29 @@ export default class MultipleChoiceOption { constructor(args) { this.args = args.args || args; + + Object.freeze(this); } + /** + * This option's ID. + */ get id() { return this.args.id || this.value; } + /** + * A string describing this option. + */ get text() { return this.args.text; } + /** + * The value to return when this option is active. + */ get value() { return this.args.value; } - clone() { - return new MultipleChoiceOption(Utils.deepclone(this.args)); - } - } diff --git a/client/src/structs/settings/settingsscheme.js b/client/src/structs/settings/settingsscheme.js index 8f3d945a..2d4a14f6 100644 --- a/client/src/structs/settings/settingsscheme.js +++ b/client/src/structs/settings/settingsscheme.js @@ -24,26 +24,46 @@ export default class SettingsScheme { Object.freeze(this); } + /** + * The scheme's ID. + */ get id() { return this.args.id; } + /** + * The URL of the scheme's icon. This should be a base64 encoded data URI. + */ get icon_url() { return this.args.icon_url; } + /** + * The scheme's name. + */ get name() { return this.args.name; } + /** + * A string to be displayed under the scheme. + */ get hint() { return this.args.hint; } + /** + * An array of stripped settings categories this scheme manages. + */ get settings() { return this.args.settings || []; } + /** + * Checks if this scheme's values are currently applied to a set. + * @param {SettingsSet} set The set to check + * @return {Boolean} + */ isActive(set) { for (let schemeCategory of this.settings) { const category = set.categories.find(c => c.category === schemeCategory.category); @@ -66,12 +86,13 @@ export default class SettingsScheme { return true; } + /** + * Applies this scheme's values to a set. + * @param {SettingsSet} set The set to merge this scheme's values into + * @return {Promise} + */ applyTo(set) { - return set.merge({ settings: this.settings }); - } - - clone() { - return new SettingsScheme(Utils.deepclone(this.args)); + return set.merge(this); } } diff --git a/client/src/structs/settings/settingsset.js b/client/src/structs/settings/settingsset.js index 5b324a69..bb87fac9 100644 --- a/client/src/structs/settings/settingsset.js +++ b/client/src/structs/settings/settingsset.js @@ -446,7 +446,7 @@ export default class SettingsSet { text: this.text, headertext: this.headertext, settings: this.categories.map(category => category.clone()), - schemes: this.schemes.map(scheme => scheme.clone()) + schemes: this.schemes }, ...merge); } diff --git a/client/src/styles/partials/badges.scss b/client/src/styles/partials/badges.scss index fee77077..fb5656df 100644 --- a/client/src/styles/partials/badges.scss +++ b/client/src/styles/partials/badges.scss @@ -25,16 +25,21 @@ width: 16px; filter: brightness(10); cursor: pointer; - .theme-light [class*="topSectionNormal-"] & { - background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FscXVlXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjAwMCAyMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyMDAwIDIwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwYXRoIGZpbGw9IiMzRTgyRTUiIGQ9Ik0xNDAyLjIsNjMxLjdjLTkuNy0zNTMuNC0yODYuMi00OTYtNjQyLjYtNDk2SDY4LjR2NzE0LjFsNDQyLDM5OFY0OTAuN2gyNTdjMjc0LjUsMCwyNzQuNSwzNDQuOSwwLDM0NC45SDU5Ny42djMyOS41aDE2OS44YzI3NC41LDAsMjc0LjUsMzQ0LjgsMCwzNDQuOGgtNjk5djM1NC45aDY5MS4yYzM1Ni4zLDAsNjMyLjgtMTQyLjYsNjQyLjYtNDk2YzAtMTYyLjYtNDQuNS0yODQuMS0xMjIuOS0zNjguNkMxMzU3LjcsOTE1LjgsMTQwMi4yLDc5NC4zLDE0MDIuMiw2MzEuN3oiLz48cGF0aCBmaWxsPSIjYmJiYmJiIiBkPSJNMTI2Mi41LDEzNS4yTDEyNjIuNSwxMzUuMmwtNzYuOCwwYzI2LjYsMTMuMyw1MS43LDI4LjEsNzUsNDQuM2M3MC43LDQ5LjEsMTI2LjEsMTExLjUsMTY0LjYsMTg1LjNjMzkuOSw3Ni42LDYxLjUsMTY1LjYsNjQuMywyNjQuNmwwLDEuMnYxLjJjMCwxNDEuMSwwLDU5Ni4xLDAsNzM3LjF2MS4ybDAsMS4yYy0yLjcsOTktMjQuMywxODgtNjQuMywyNjQuNmMtMzguNSw3My44LTkzLjgsMTM2LjItMTY0LjYsMTg1LjNjLTIyLjYsMTUuNy00Ni45LDMwLjEtNzIuNiw0My4xaDcyLjVjMzQ2LjIsMS45LDY3MS0xNzEuMiw2NzEtNTY3LjlWNzE2LjdDMTkzMy41LDMxMi4yLDE2MDguNywxMzUuMiwxMjYyLjUsMTM1LjJ6Ii8+PC9nPjwvc3ZnPg=='); - filter: none; - } +} + +.theme-light [class*="topSectionNormal-"] .bd-profile-badge-developer, +.theme-light [class*="topSectionNormal-"] .bd-profile-badge-contributor, +.theme-light .bd-message-badge-developer, +.theme-light .bd-message-badge-contributor { + background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iQ2FscXVlXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjAwMCAyMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyMDAwIDIwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwYXRoIGZpbGw9IiMzRTgyRTUiIGQ9Ik0xNDAyLjIsNjMxLjdjLTkuNy0zNTMuNC0yODYuMi00OTYtNjQyLjYtNDk2SDY4LjR2NzE0LjFsNDQyLDM5OFY0OTAuN2gyNTdjMjc0LjUsMCwyNzQuNSwzNDQuOSwwLDM0NC45SDU5Ny42djMyOS41aDE2OS44YzI3NC41LDAsMjc0LjUsMzQ0LjgsMCwzNDQuOGgtNjk5djM1NC45aDY5MS4yYzM1Ni4zLDAsNjMyLjgtMTQyLjYsNjQyLjYtNDk2YzAtMTYyLjYtNDQuNS0yODQuMS0xMjIuOS0zNjguNkMxMzU3LjcsOTE1LjgsMTQwMi4yLDc5NC4zLDE0MDIuMiw2MzEuN3oiLz48cGF0aCBmaWxsPSIjYmJiYmJiIiBkPSJNMTI2Mi41LDEzNS4yTDEyNjIuNSwxMzUuMmwtNzYuOCwwYzI2LjYsMTMuMyw1MS43LDI4LjEsNzUsNDQuM2M3MC43LDQ5LjEsMTI2LjEsMTExLjUsMTY0LjYsMTg1LjNjMzkuOSw3Ni42LDYxLjUsMTY1LjYsNjQuMywyNjQuNmwwLDEuMnYxLjJjMCwxNDEuMSwwLDU5Ni4xLDAsNzM3LjF2MS4ybDAsMS4yYy0yLjcsOTktMjQuMywxODgtNjQuMywyNjQuNmMtMzguNSw3My44LTkzLjgsMTM2LjItMTY0LjYsMTg1LjNjLTIyLjYsMTUuNy00Ni45LDMwLjEtNzIuNiw0My4xaDcyLjVjMzQ2LjIsMS45LDY3MS0xNzEuMiw2NzEtNTY3LjlWNzE2LjdDMTkzMy41LDMxMi4yLDE2MDguNywxMzUuMiwxMjYyLjUsMTM1LjJ6Ii8+PC9nPjwvc3ZnPg=='); + filter: none; } .bd-message-badges-wrap { display: inline-block; margin-left: 6px; height: 11px; + .bd-message-badge-developer, .bd-message-badge-contributor { width: 12px; diff --git a/client/src/styles/partials/bdsettings/tooltips.scss b/client/src/styles/partials/bdsettings/tooltips.scss index 0ec5e69f..3eaa12d4 100644 --- a/client/src/styles/partials/bdsettings/tooltips.scss +++ b/client/src/styles/partials/bdsettings/tooltips.scss @@ -20,17 +20,17 @@ bd-tooltips { word-wrap: break-word; z-index: 9001; margin-bottom: 10px; -} -.bd-tooltip:after { - border: 5px solid transparent; - content: " "; - height: 0; - pointer-events: none; - width: 0; - border-top-color: #000; - left: 50%; - margin-left: -5px; - position: absolute; - top: 100%; + .bd-tooltip-arrow { + border: 5px solid transparent; + content: " "; + height: 0; + pointer-events: none; + width: 0; + border-top-color: #000; + left: 50%; + margin-left: -5px; + position: absolute; + top: 100%; + } } diff --git a/client/src/ui/automanip.js b/client/src/ui/automanip.js index 7331f66c..88f19651 100644 --- a/client/src/ui/automanip.js +++ b/client/src/ui/automanip.js @@ -8,37 +8,14 @@ * LICENSE file in the root directory of this source tree. */ -import { Events, WebpackModules, EventListener, ReactComponents, Renderer } from 'modules'; +import { Events, WebpackModules, EventListener, DiscordApi, ReactComponents, Renderer } from 'modules'; +import { ClientLogger as Logger } from 'common'; import Reflection from './reflection'; import DOM from './dom'; import VueInjector from './vueinjector'; import EditedTimeStamp from './components/common/EditedTimestamp.vue'; import Autocomplete from './components/common/Autocomplete.vue'; -class TempApi { - static get currentGuildId() { - try { - return WebpackModules.getModuleByName('SelectedGuildStore').getGuildId(); - } catch (err) { - return 0; - } - } - static get currentChannelId() { - try { - return WebpackModules.getModuleByName('SelectedChannelStore').getChannelId(); - } catch (err) { - return 0; - } - } - static get currentUserId() { - try { - return WebpackModules.getModuleByName('UserStore').getCurrentUser().id; - } catch (err) { - return 0; - } - } -} - export default class extends EventListener { constructor(args) { @@ -54,22 +31,19 @@ export default class extends EventListener { } get eventBindings() { - return [{ id: 'gkh:keyup', callback: this.injectAutocomplete }]; - /* return [ - { id: 'server-switch', callback: this.manipAll }, - { id: 'channel-switch', callback: this.manipAll }, - { id: 'discord:MESSAGE_CREATE', callback: this.markupInjector }, - { id: 'discord:MESSAGE_UPDATE', callback: this.markupInjector }, + // { id: 'server-switch', callback: this.manipAll }, + // { id: 'channel-switch', callback: this.manipAll }, + // { id: 'discord:MESSAGE_CREATE', callback: this.markupInjector }, + // { id: 'discord:MESSAGE_UPDATE', callback: this.markupInjector }, { id: 'gkh:keyup', callback: this.injectAutocomplete } ]; - */ } manipAll() { try { - this.appMount.setAttribute('guild-id', TempApi.currentGuildId); - this.appMount.setAttribute('channel-id', TempApi.currentChannelId); + this.appMount.setAttribute('guild-id', DiscordApi.currentGuild.id); + this.appMount.setAttribute('channel-id', DiscordApi.currentChannel.id); this.setIds(); this.makeMutable(); } catch (err) { @@ -172,14 +146,14 @@ export default class extends EventListener { const userTest = Reflection(msgGroup).prop('user'); if (!userTest) return; msgGroup.setAttribute('data-author-id', userTest.id); - if (userTest.id === TempApi.currentUserId) msgGroup.setAttribute('data-currentuser', true); + if (userTest.id === DiscordApi.currentUserId) msgGroup.setAttribute('data-currentuser', true); return; } msg.setAttribute('data-message-id', messageid); const msgGroup = msg.closest('.message-group'); if (!msgGroup) return; msgGroup.setAttribute('data-author-id', authorid); - if (authorid === TempApi.currentUserId) msgGroup.setAttribute('data-currentuser', true); + if (authorid === DiscordApi.currentUser.id) msgGroup.setAttribute('data-currentuser', true); } setUserId(user) { @@ -187,7 +161,7 @@ export default class extends EventListener { const userid = Reflection(user).prop('user.id'); if (!userid) return; user.setAttribute('data-user-id', userid); - const currentUser = userid === TempApi.currentUserId; + const currentUser = userid === DiscordApi.currentUser.id; if (currentUser) user.setAttribute('data-currentuser', true); Events.emit('ui:useridset', user); } @@ -218,4 +192,5 @@ export default class extends EventListener { template: '' }); } + } diff --git a/client/src/ui/bdmenu.js b/client/src/ui/bdmenu.js index c8f6cd60..0eb3a019 100644 --- a/client/src/ui/bdmenu.js +++ b/client/src/ui/bdmenu.js @@ -28,7 +28,14 @@ const BdMenuItems = new class { this.add({category: 'External', contentid: 'themes', text: 'Themes'}); } + /** + * Adds an item to the menu. + * @param {Object} item The item to add to the menu + * @return {Object} + */ add(item) { + if (this.items.includes(item)) return item; + item.id = items++; item.contentid = item.contentid || (items++ + ''); item.active = false; @@ -39,6 +46,13 @@ const BdMenuItems = new class { return item; } + /** + * Adds a settings set to the menu. + * @param {String} category The category to display this item under + * @param {SettingsSet} set The settings set to display when this item is active + * @param {String} text The text to display in the menu (optional) + * @return {Object} The item that was added + */ addSettingsSet(category, set, text) { return this.add({ category, set, @@ -46,12 +60,23 @@ const BdMenuItems = new class { }); } + /** + * Adds a Vue component to the menu. + * @param {String} category The category to display this item under + * @param {String} text The text to display in the menu + * @param {Object} component The Vue component to display when this item is active + * @return {Object} The item that was added + */ addVueComponent(category, text, component) { return this.add({ category, text, component }); } + /** + * Removes an item from the menu. + * @param {Object} item The item to remove from the menu + */ remove(item) { Utils.removeFromArray(this.items, item); } diff --git a/client/src/ui/bdui.js b/client/src/ui/bdui.js index 009a2905..458fcf12 100644 --- a/client/src/ui/bdui.js +++ b/client/src/ui/bdui.js @@ -8,48 +8,21 @@ * LICENSE file in the root directory of this source tree. */ +import { Events, WebpackModules, DiscordApi } from 'modules'; +import { Utils } from 'common'; +import { remote } from 'electron'; import DOM from './dom'; import Vue from './vue'; -import { BdSettingsWrapper } from './components'; -import BdModals from './components/bd/BdModals.vue'; -import { Events, WebpackModules } from 'modules'; -import { Utils } from 'common'; import AutoManip from './automanip'; -import { remote } from 'electron'; - -class TempApi { - static get currentGuild() { - try { - const currentGuildId = WebpackModules.getModuleByName('SelectedGuildStore').getGuildId(); - return WebpackModules.getModuleByName('GuildStore').getGuild(currentGuildId); - } catch (err) { - return null; - } - } - static get currentChannel() { - try { - const currentChannelId = WebpackModules.getModuleByName('SelectedChannelStore').getChannelId(); - return WebpackModules.getModuleByName('ChannelStore').getChannel(currentChannelId); - } catch (err) { - return 0; - } - } - static get currentUserId() { - try { - return WebpackModules.getModuleByName('UserStore').getCurrentUser().id; - } catch (err) { - return 0; - } - } -} +import { BdSettingsWrapper, BdModals } from './components'; export default class { static initUiEvents() { this.pathCache = { isDm: null, - server: TempApi.currentGuild, - channel: TempApi.currentChannel + server: DiscordApi.currentGuild, + channel: DiscordApi.currentChannel }; window.addEventListener('keyup', e => Events.emit('gkh:keyup', e)); this.autoManip = new AutoManip(); @@ -67,9 +40,9 @@ export default class { if (!remote.BrowserWindow.getFocusedWindow()) return; clearInterval(ehookInterval); remote.BrowserWindow.getFocusedWindow().webContents.on('did-navigate-in-page', (e, url, isMainFrame) => { - const { currentGuild, currentChannel } = TempApi; + const { currentGuild, currentChannel } = DiscordApi; if (!this.pathCache.server) { - Events.emit('server-switch', { 'server': currentGuild, 'channel': currentChannel }); + Events.emit('server-switch', { server: currentGuild, channel: currentChannel }); this.pathCache.server = currentGuild; this.pathCache.channel = currentChannel; return; @@ -84,7 +57,7 @@ export default class { currentGuild.id && this.pathCache.server && this.pathCache.server.id !== currentGuild.id) { - Events.emit('server-switch', { 'server': currentGuild, 'channel': currentChannel }); + Events.emit('server-switch', { server: currentGuild, channel: currentChannel }); this.pathCache.server = currentGuild; this.pathCache.channel = currentChannel; return; @@ -110,19 +83,19 @@ export default class { DOM.createElement('div', null, 'bd-modals').appendTo(DOM.bdModals); DOM.createElement('bd-tooltips').appendTo(DOM.bdBody); - const modals = new Vue({ + this.modals = new Vue({ el: '#bd-modals', components: { BdModals }, - template: '' + template: '' }); - const vueInstance = new Vue({ + this.vueInstance = new Vue({ el: '#bd-settings', components: { BdSettingsWrapper }, - template: '' + template: '' }); - return vueInstance; + return this.vueInstance; } } diff --git a/client/src/ui/components/bd/BdModals.vue b/client/src/ui/components/BdModals.vue similarity index 92% rename from client/src/ui/components/bd/BdModals.vue rename to client/src/ui/components/BdModals.vue index 60a85d32..78e04f3b 100644 --- a/client/src/ui/components/bd/BdModals.vue +++ b/client/src/ui/components/BdModals.vue @@ -19,13 +19,14 @@ +