More comments

This commit is contained in:
Samuel Elliott 2018-03-22 02:13:32 +00:00
parent 33adb92902
commit 0f805d57e3
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
12 changed files with 134 additions and 145 deletions

View File

@ -8,27 +8,33 @@
* LICENSE file in the root directory of this source tree.
*/
import { FileUtils, ClientLogger as Logger } from 'common';
import { Events, Globals, WebpackModules, ReactComponents, MonkeyPatch } from 'modules';
import { DOM, VueInjector, Reflection } from 'ui';
import { FileUtils, ClientLogger as Logger } from 'common';
import path from 'path';
import EmoteComponent from './EmoteComponent.vue';
let emotes = null;
const emotesEnabled = true;
export default class {
static get searchCache() {
return this._searchCache || (this._searchCache = {});
}
static get emoteDb() {
return emotes;
}
static get React() {
return WebpackModules.getModuleByName('React');
}
static get ReactDOM() {
return WebpackModules.getModuleByName('ReactDOM');
}
static processMarkup(markup) {
if (!emotesEnabled) return markup; // TODO Get it from setttings
const newMarkup = [];
@ -94,13 +100,20 @@ export default class {
}
static async observe() {
const dataPath = Globals.getObject('paths').find(path => path.id === 'data').path;
const dataPath = Globals.getPath('data');
try {
emotes = await FileUtils.readJsonFromFile(path.join(dataPath, 'emotes.json'));
} catch (err) {
Logger.err('EmoteModule', [`Failed to load emote data. Make sure you've downloaded the emote data and placed it in ${dataPath}:`, err]);
return;
}
try {
emotes = await FileUtils.readJsonFromFile(dataPath + '/emotes.json');
const Message = await ReactComponents.getComponent('Message');
this.unpatchRender = MonkeyPatch('BD:EmoteModule', Message.component.prototype).after('render', (component, args, retVal) => {
try {
const markup = this.findByProp(retVal, 'className', 'markup'); // First child has all the actual text content, second is the edited timestamp
// First child has all the actual text content, second is the edited timestamp
const markup = this.findByProp(retVal, 'className', 'markup');
if (!markup) return;
markup.children[0] = this.processMarkup(markup.children[0]);
} catch (err) {
@ -180,4 +193,5 @@ export default class {
}
});
}
}

View File

@ -59,6 +59,7 @@ export default class Content {
/**
* Opens a settings modal for this content.
* @return {Modal}
*/
showSettingsModal() {
return Modals.contentSettings(this);
@ -73,16 +74,10 @@ export default class Content {
/**
* Saves the content's current configuration.
* @return {Promise}
*/
async saveConfiguration() {
try {
/*
await FileUtils.writeFile(`${this.contentPath}/user.config.json`, JSON.stringify({
enabled: this.enabled,
config: this.settings.strip().settings,
data: this.data
}));
*/
Database.insertOrUpdate({ type: 'contentconfig', $or: [{ id: this.id }, { name: this.name }] }, {
type: 'contentconfig',
id: this.id,
@ -143,15 +138,6 @@ export default class Content {
return this.events.on(...args);
}
/**
* Removes an event listener.
* @param {String} event The event to remove the listener from
* @param {Function} callback The bound callback (optional)
*/
off(...args) {
return this.events.removeListener(...args);
}
/**
* Adds an event listener that removes itself when called, therefore only being called once.
* @param {String} event The event to add the listener to
@ -162,6 +148,15 @@ export default class Content {
return this.events.once(...args);
}
/**
* Removes an event listener.
* @param {String} event The event to remove the listener from
* @param {Function} callback The bound callback (optional)
*/
off(...args) {
return this.events.removeListener(...args);
}
/**
* Emits an event.
* @param {String} event The event to emit

View File

@ -24,31 +24,31 @@ import Combokeys from 'combokeys';
export default class {
/**
* Any errors that happened
* returns {Array}
* Any errors that happened.
* @return {Array}
*/
static get errors() {
return this._errors || (this._errors = []);
}
/**
* Locallly stored content
* returns {Array}
* Locally stored content.
* @return {Array}
*/
static get localContent() {
return this._localContent ? this._localContent : (this._localContent = []);
}
/**
* Local path for content
* returns {String}
* Local path for content.
* @return {String}
*/
static get contentPath() {
return Globals.getPath(this.pathId);
}
/**
* Load all locally stored content
* Load all locally stored content.
* @param {bool} suppressErrors Suppress any errors that occur during loading of content
*/
static async loadAllContent(suppressErrors = false) {
@ -83,8 +83,6 @@ export default class {
});
this._errors = [];
}
return this.localContent;
} catch (err) {
throw err;
}
@ -150,8 +148,6 @@ export default class {
});
this._errors = [];
}
return this.localContent;
} catch (err) {
throw err;
}
@ -169,15 +165,12 @@ export default class {
await FileUtils.directoryExists(contentPath);
if (!reload) {
const loaded = this.localContent.find(content => content.contentPath === contentPath);
if (loaded) {
throw { 'message': `Attempted to load already loaded user content: ${path}` };
}
}
if (!reload && this.getContentByPath(contentPath))
throw { 'message': `Attempted to load already loaded user content: ${path}` };
const readConfig = await this.readConfig(contentPath);
const mainPath = path.join(contentPath, readConfig.main);
const configPath = path.resolve(contentPath, 'config.json');
const readConfig = await FileUtils.readJsonFromFile(configPath);
const mainPath = path.join(contentPath, readConfig.main || 'index.js');
const defaultConfig = new SettingsSet({
settings: readConfig.defaultConfig,
@ -191,17 +184,15 @@ export default class {
};
try {
//const readUserConfig = await this.readUserConfig(contentPath);
const readUserConfig = await Database.find({ type: 'contentconfig', name: readConfig.info.name });
const id = readConfig.info.id || readConfig.info.name.toLowerCase().replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-');
const readUserConfig = await Database.find({ type: 'contentconfig', id });
if (readUserConfig.length) {
userConfig.enabled = readUserConfig[0].enabled || false;
// await userConfig.config.merge({ settings: readUserConfig.config });
// userConfig.config.setSaved();
// userConfig.config = userConfig.config.clone({ settings: readUserConfig.config });
userConfig.config = readUserConfig[0].config;
userConfig.data = readUserConfig[0].data || {};
}
} catch (err) { /*We don't care if this fails it either means that user config doesn't exist or there's something wrong with it so we revert to default config*/
} catch (err) {
// We don't care if this fails it either means that user config doesn't exist or there's something wrong with it so we revert to default config
Logger.info(this.moduleName, `Failed reading config for ${this.contentType} ${readConfig.info.name} in ${dirName}`);
Logger.err(this.moduleName, err);
}
@ -244,9 +235,10 @@ export default class {
}
/**
* Unload content
* @param {any} content Content to unload
* @param {bool} reload Whether to reload the content after
* Unload content.
* @param {Content|String} content Content to unload
* @param {Boolean} reload Whether to reload the content after
* @return {Content}
*/
static async unloadContent(content, reload) {
content = this.findContent(content);
@ -275,34 +267,18 @@ export default class {
}
/**
* Reload content
* @param {any} content Content to reload
* Reload content.
* @param {Content|String} content Content to reload
* @return {Content}
*/
static reloadContent(content) {
return this.unloadContent(content, true);
}
/**
* Read content config file
* @param {any} configPath Config file path
*/
static async readConfig(configPath) {
configPath = path.resolve(configPath, 'config.json');
return FileUtils.readJsonFromFile(configPath);
}
/**
* Read content user config file
* @param {any} configPath User config file path
*/
static async readUserConfig(configPath) {
configPath = path.resolve(configPath, 'user.config.json');
return FileUtils.readJsonFromFile(configPath);
}
/**
* Checks if the passed object is an instance of this content type.
* @param {any} content Object to check
* @param {Any} content Object to check
* @return {Boolean}
*/
static isThisContent(content) {
return content instanceof Content;
@ -318,8 +294,9 @@ export default class {
/**
* Wildcard content finder
* @param {any} wild Content ID / directory name / path / name
* @param {bool} nonunique Allow searching attributes that may not be unique
* @param {String} wild Content ID / directory name / path / name
* @param {Boolean} nonunique Allow searching attributes that may not be unique
* @return {Content}
*/
static findContent(wild, nonunique) {
if (this.isThisContent(wild)) return wild;
@ -338,7 +315,8 @@ export default class {
/**
* Wait for content to load
* @param {any} content_id
* @param {String} content_id
* @return {Promise}
*/
static waitForContent(content_id) {
return new Promise((resolve, reject) => {

View File

@ -32,7 +32,7 @@ export default new class {
}
/**
* Init css editor
* Init css editor.
*/
init() {
ClientIPC.on('bd-get-scss', () => this.scss, true);
@ -60,16 +60,16 @@ export default new class {
}
/**
* Show css editor, flashes if already visible
* Show css editor, flashes if already visible.
*/
async show() {
await ClientIPC.send('openCssEditor', this.editor_bounds);
}
/**
* Update css in client
* @param {String} scss scss to compile
* @param {bool} sendSource send to css editor instance
* Update css in client.
* @param {String} scss SCSS to compile
* @param {bool} sendSource Whether to send to css editor instance
*/
async updateScss(scss, sendSource) {
if (sendSource)
@ -97,15 +97,15 @@ export default new class {
}
/**
* Save css to file
* Save css to file.
*/
async save() {
Settings.saveSettings();
}
/**
* Save current editor bounds
* @param {Rectangle} bounds editor bounds
* Save current editor bounds.
* @param {Rectangle} bounds Editor bounds
*/
saveEditorBounds(bounds) {
this.editor_bounds = bounds;
@ -113,8 +113,8 @@ export default new class {
}
/**
* Send scss to core for compilation
* @param {String} scss scss string
* Send SCSS to core for compilation.
* @param {String} scss SCSS string
*/
async compile(scss) {
return await ClientIPC.send('bd-compileSass', {
@ -124,7 +124,7 @@ export default new class {
}
/**
* Recompile the current SCSS
* Recompile the current SCSS.
* @return {Promise}
*/
async recompile() {
@ -132,16 +132,18 @@ export default new class {
}
/**
* Send data to open editor
* @param {any} channel
* @param {any} data
* Send data to open editor.
* @param {String} channel
* @param {Any} data
* @return {Promise}
*/
async sendToEditor(channel, data) {
return ClientIPC.sendToCssEditor(channel, data);
}
/**
* Opens an SCSS file in a system editor
* Opens an SCSS file in a system editor.
* @return {Promise}
*/
async openSystemEditor() {
try {
@ -160,7 +162,8 @@ export default new class {
throw {message: 'Failed to open system editor.'};
}
/** Set current state
/**
* Set current state
* @param {String} scss Current uncompiled SCSS
* @param {String} css Current compiled CSS
* @param {String} files Files imported in the SCSS
@ -175,29 +178,28 @@ export default new class {
}
/**
* Current uncompiled scss
* Current uncompiled scss.
*/
get scss() {
return this._scss || '';
}
/**
* Set current scss
* Set current scss.
*/
set scss(scss) {
this.updateScss(scss, true);
}
/**
* Current compiled css
* Current compiled css.
*/
get css() {
return this._css || '';
}
/**
* Inject compiled css to head
* {DOM}
* Inject compiled css to head.
*/
set css(css) {
this._css = css;
@ -205,15 +207,14 @@ export default new class {
}
/**
* Current error
* Current error.
*/
get error() {
return this._error || undefined;
}
/**
* Set current error
* {DOM}
* Set current error.
*/
set error(err) {
this._error = err;
@ -293,7 +294,7 @@ export default new class {
/**
* Checks if the system editor's file exists.
* @return {Boolean}
* @return {Promise}
*/
async fileExists() {
try {

View File

@ -52,7 +52,7 @@ export default class extends EventListener {
/**
* Discord emit overload
* @param {any} e
* @param {any} event
* @param {any} action
* @param {any} data
*/

View File

@ -29,26 +29,24 @@ export default new class extends Module {
this.getObject = this.getObject.bind(this);
}
first() {
(async() => {
const config = await ClientIPC.send('getConfig');
this.setState({ config });
async first() {
const config = await ClientIPC.send('getConfig');
this.setState({ config });
// This is for Discord to stop error reporting :3
window.BetterDiscord = {
version: config.version,
v: config.version
};
window.jQuery = {};
// This is for Discord to stop error reporting :3
window.BetterDiscord = {
version: config.version,
v: config.version
};
window.jQuery = {};
if (sparkplug.bd) {
this.setState({ bd: sparkplug.bd });
sparkplug.bd.setWS = this.setWS;
}
if (sparkplug.bd) {
this.setState({ bd: sparkplug.bd });
sparkplug.bd.setWS = this.setWS;
}
Events.emit('global-ready');
Events.emit('socket-created', this.state.wsHook);
})();
Events.emit('global-ready');
Events.emit('socket-created', this.state.wsHook);
}
setWS(wSocket) {

View File

@ -90,9 +90,7 @@ export default class extends ContentManager {
for (const [key, value] of Object.entries(dependencies)) {
const extModule = ExtModuleManager.findModule(key);
if (!extModule) {
throw {
'message': `Dependency: ${key}:${value} is not loaded`
};
throw {message: `Dependency ${key}:${value} is not loaded.`};
}
deps[key] = extModule.__require;
}
@ -121,24 +119,24 @@ export default class extends ContentManager {
static get unloadPlugin() { return this.unloadContent }
static get reloadPlugin() { return this.reloadContent }
static stopPlugin(name) {
const plugin = name instanceof Plugin ? name : this.getPluginByName(name);
try {
if (plugin) return plugin.stop();
} catch (err) {
// Logger.err('PluginManager', err);
}
return true; //Return true anyways since plugin doesn't exist
/**
* Stops a plugin.
* @param {Plugin|String} plugin
* @return {Promise}
*/
static stopPlugin(plugin) {
plugin = this.isPlugin(plugin) ? plugin : this.getPluginById(plugin);
return plugin.stop();
}
static startPlugin(name) {
const plugin = name instanceof Plugin ? name : this.getPluginByName(name);
try {
if (plugin) return plugin.start();
} catch (err) {
// Logger.err('PluginManager', err);
}
return true; //Return true anyways since plugin doesn't exist
/**
* Starts a plugin.
* @param {Plugin|String} plugin
* @return {Promise}
*/
static startPlugin(plugin) {
plugin = this.isPlugin(plugin) ? plugin : this.getPluginById(plugin);
return plugin.start();
}
static get isPlugin() { return this.isThisContent }

View File

@ -6,7 +6,7 @@
* 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.
* LICENSE file in the root directory of this source tree.
*/
import { MonkeyPatch, Patcher } from './patcher';
@ -19,6 +19,7 @@ class Helpers {
static get plannedActions() {
return this._plannedActions || (this._plannedActions = new Map());
}
static recursiveArray(parent, key, count = 1) {
let index = 0;
function* innerCall(parent, key) {
@ -34,13 +35,15 @@ class Helpers {
return innerCall(parent, key);
}
static recursiveArrayCount(parent, key) {
let count = 0;
// eslint-disable-next-line no-empty-pattern
for (let { } of this.recursiveArray(parent, key))
for (let {} of this.recursiveArray(parent, key))
++count;
return this.recursiveArray(parent, key, count);
}
static get recursiveChildren() {
return function* (parent, key, index = 0, count = 1) {
const item = parent[key];
@ -52,12 +55,14 @@ class Helpers {
}
}
}
static returnFirst(iterator, process) {
for (let child of iterator) {
const retVal = process(child);
if (retVal !== undefined) return retVal;
}
}
static getFirstChild(rootParent, rootKey, selector) {
const getDirectChild = (item, selector) => {
if (item && item.props && item.props.children) {
@ -116,11 +121,13 @@ class Helpers {
};
return this.returnFirst(this.recursiveChildren(rootParent, rootKey), checkFilter.bind(null, selector)) || {};
}
static parseSelector(selector) {
if (selector.startsWith('.')) return { className: selector.substr(1) }
if (selector.startsWith('#')) return { id: selector.substr(1) }
return {}
}
static findByProp(obj, what, value) {
if (obj.hasOwnProperty(what) && obj[what] === value) return obj;
if (obj.props && !obj.children) return this.findByProp(obj.props, what, value);
@ -132,6 +139,7 @@ class Helpers {
}
return null;
}
static findProp(obj, what) {
if (obj.hasOwnProperty(what)) return obj[what];
if (obj.props && !obj.children) return this.findProp(obj.props, what);
@ -144,6 +152,7 @@ class Helpers {
}
return null;
}
static get ReactDOM() {
return WebpackModules.getModuleByName('ReactDOM');
}
@ -155,12 +164,15 @@ class ReactComponent {
this._component = component;
this._retVal = retVal;
}
get id() {
return this._id;
}
get component() {
return this._component;
}
get retVal() {
return this._retVal;
}

View File

@ -62,11 +62,11 @@ export default class ThemeManager extends ContentManager {
}
static enableTheme(theme) {
theme.enable();
return theme.enable();
}
static disableTheme(theme) {
theme.disable();
return theme.disable();
}
static get isTheme() { return this.isThisContent }

View File

@ -91,7 +91,6 @@ const KnownModules = {
UserActivityStore: Filters.byProperties(['getActivity']),
UserNameResolver: Filters.byProperties(['getName']),
/* Emoji Store and Utils */
EmojiInfo: Filters.byProperties(['isEmojiDisabled']),
EmojiUtils: Filters.byProperties(['getGuildEmoji']),
@ -102,7 +101,6 @@ const KnownModules = {
InviteResolver: Filters.byProperties(['findInvite']),
InviteActions: Filters.byProperties(['acceptInvite']),
/* Discord Objects & Utils */
DiscordConstants: Filters.byProperties(["Permissions", "ActivityTypes", "StatusTypes"]),
Permissions: Filters.byProperties(['getHighestRole']),
@ -128,7 +126,6 @@ const KnownModules = {
ExperimentsManager: Filters.byProperties(['isDeveloper']),
CurrentExperiment: Filters.byProperties(['getExperimentId']),
/* Images, Avatars and Utils */
ImageResolver: Filters.byProperties(["getUserAvatarURL"]),
ImageUtils: Filters.byProperties(['getSizedImageSrc']),
@ -182,7 +179,6 @@ const KnownModules = {
URLParser: Filters.byProperties(['Url', 'parse']),
ExtraURLs: Filters.byProperties(['getArticleURL']),
/* DOM/React Components */
/* ==================== */
UserSettingsWindow: Filters.byProperties(['open', 'updateAccount']),

View File

@ -1,3 +0,0 @@
export default class {
}