Skip to content

Commit

Permalink
Merge pull request JsSucks#326 from samuelthomas2774/ui
Browse files Browse the repository at this point in the history
  • Loading branch information
Maks-s committed Jul 17, 2019
2 parents 0b67f1b + 4be9c8b commit 4f935f4
Show file tree
Hide file tree
Showing 44 changed files with 352 additions and 263 deletions.
2 changes: 0 additions & 2 deletions client/src/builtin/Emotes/EmoteModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,6 @@ export default new class EmoteModule extends BuiltinModule {
const { content } = args[1];
if (!content) return orig(...args);

Logger.log('EmoteModule', ['Sending message', MessageActions, args, orig]);

const emoteAsImage = Settings.getSetting('emotes', 'default', 'emoteasimage').value &&
(DiscordApi.currentChannel.type === 'DM' || DiscordApi.currentChannel.type === 'GROUP_DM' || DiscordApi.currentChannel.checkPermissions(DiscordApi.modules.DiscordPermissions.ATTACH_FILES));

Expand Down
2 changes: 1 addition & 1 deletion client/src/data/user.settings.default.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"id": "developer-mode",
"type": "bool",
"text": "Developer mode",
"hint": "Adds some of BetterDiscord's internal modules to `global._bd`.",
"hint": "Adds some of BetterDiscord's internal modules to `global._bd` and enable additional options in plugin and theme settings.",
"value": false
},
{
Expand Down
2 changes: 1 addition & 1 deletion client/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const ignoreExternal = tests && true;
class BetterDiscord {

constructor() {
Logger.file = tests ? path.resolve(__dirname, '..', '..', 'tests', 'log.txt') : path.join(__dirname, 'log.txt');
Logger.file = tests ? path.resolve(__dirname, '..', '..', 'tests', 'log.txt') : `${__dirname}-log.txt`;
Logger.trimLogFile();
Logger.log('main', 'BetterDiscord starting');

Expand Down
2 changes: 1 addition & 1 deletion client/src/modules/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export default class Content extends AsyncEventEmitter {
* @return {Promise}
*/
async enable(save = true) {
if (this.enabled) return;
if (this.enabled || this.unloaded) return;
await this.emit('enable');
await this.emit('start');

Expand Down
76 changes: 41 additions & 35 deletions client/src/modules/contentmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { remote } from 'electron';
import Content from './content';
import Globals from './globals';
import Database from './database';
import { Utils, FileUtils, ClientLogger as Logger } from 'common';
import { Utils, FileUtils, ClientLogger as Logger, ClientIPC } from 'common';
import { SettingsSet, ErrorEvent } from 'structs';
import { Modals } from 'ui';
import Combokeys from 'combokeys';
Expand Down Expand Up @@ -73,23 +73,23 @@ export default class {
}

static async packContent(path, contentPath) {
return new Promise((resolve, reject) => {
remote.dialog.showSaveDialog({
title: 'Save Package',
defaultPath: path,
filters: [
{
name: 'BetterDiscord Package',
extensions: ['bd']
}
]
}, filepath => {
if (!filepath) return;
const filepath = await ClientIPC.send('bd-native-save', {
title: 'Save Package',
defaultPath: path,
filters: [
{
name: 'BetterDiscord Package',
extensions: ['bd']
}
]
});

asar.uncache(filepath);
asar.createPackage(contentPath, filepath, () => {
resolve(filepath);
});
if (!filepath) return;

return new Promise((resolve, reject) => {
asar.uncache(filepath);
asar.createPackage(contentPath, filepath, () => {
resolve(filepath);
});
});
}
Expand All @@ -104,13 +104,8 @@ export default class {
const directories = await FileUtils.listDirectory(this.contentPath);

for (const dir of directories) {
const packed = dir.endsWith('.bd');

if (!packed) {
try {
await FileUtils.directoryExists(path.join(this.contentPath, dir));
} catch (err) { continue; }
}
const stat = await FileUtils.stat(path.join(this.contentPath, dir));
const packed = stat.isFile();

try {
if (packed) {
Expand Down Expand Up @@ -148,25 +143,27 @@ export default class {
* @param {bool} suppressErrors Suppress any errors that occur during loading of content
*/
static async refreshContent(suppressErrors = false) {
this.loaded = true;

if (!this.localContent.length) return this.loadAllContent();

try {
await FileUtils.ensureDirectory(this.contentPath);
const directories = await FileUtils.listDirectory(this.contentPath);

for (const dir of directories) {
const packed = dir.endsWith('.bd');

// If content is already loaded this should resolve
if (this.getContentByDirName(dir)) continue;

try {
await FileUtils.directoryExists(path.join(this.contentPath, dir));
} catch (err) { continue; }
const stat = await FileUtils.stat(path.join(this.contentPath, dir));
const packed = stat.isFile();

try {
// Load if not
await this.preloadContent(dir);
if (packed) {
await this.preloadPackedContent(dir);
} else {
await this.preloadContent(dir);
}
} catch (err) {
// We don't want every plugin/theme to fail loading when one does
this.errors.push(new ErrorEvent({
Expand Down Expand Up @@ -217,7 +214,8 @@ export default class {
await FileUtils.fileExists(packagePath);

const config = JSON.parse(asar.extractFile(packagePath, 'config.json').toString());
const unpackedPath = path.join(Globals.getPath('tmp'), packageName);
const id = config.info.id || config.info.name.toLowerCase().replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-');
const unpackedPath = path.join(Globals.getPath('tmp'), this.pathId, id);

asar.extractAll(packagePath, unpackedPath);

Expand Down Expand Up @@ -348,7 +346,7 @@ export default class {
await unload;

await FileUtils.recursiveDeleteDirectory(content.paths.contentPath);
if (content.packed) await FileUtils.recursiveDeleteDirectory(content.packagePath);
if (content.packed) await FileUtils.deleteFile(content.packagePath);
return true;
} catch (err) {
Logger.err(this.moduleName, err);
Expand All @@ -368,6 +366,8 @@ export default class {
if (!content) throw {message: `Could not find a ${this.contentType} from ${content}.`};

try {
Object.defineProperty(content, 'unloaded', {configurable: true, value: true});

const disablePromise = content.disable(false);
const unloadPromise = content.emit('unload', reload);

Expand All @@ -380,8 +380,14 @@ export default class {

if (this.unloadContentHook) this.unloadContentHook(content);

if (reload) return content.packed ? this.preloadPackedContent(content.packagePath, true, index) : this.preloadContent(content.dirName, true, index);
if (reload) {
const newcontent = content.packed ? this.preloadPackedContent(content.dirName.pkg, true, index) :
this.preloadContent(content.dirName, true, index);
Object.defineProperty(content, 'unloaded', {value: newcontent});
return newcontent;
}

Object.defineProperty(content, 'unloaded', {value: true});
this.localContent.splice(index, 1);
} catch (err) {
Logger.err(this.moduleName, err);
Expand Down Expand Up @@ -433,7 +439,7 @@ export default class {

static getContentIndex(content) { return this.localContent.findIndex(c => c === content) }
static getContentById(id) { return this.localContent.find(c => c.id === id) }
static getContentByDirName(dirName) { return this.localContent.find(c => c.dirName === dirName) }
static getContentByDirName(dirName) { return this.localContent.find(c => !c.packed ? c.dirName === dirName : c.dirName.pkg === dirName) }
static getContentByPath(path) { return this.localContent.find(c => c.contentPath === path) }
static getContentByName(name) { return this.localContent.find(c => c.name === name) }

Expand Down
51 changes: 39 additions & 12 deletions client/src/modules/reactcomponents.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,34 @@ class ReactComponent {
}
}

ReactComponent.important = Symbol('BD.ReactComponent.important');

export class ReactComponents {
/** @type {ReactComponent[]} */
static get components() { return this._components || (this._components = []) }

/** @type {Reflection.modules.React.Component[]} */
static get unknownComponents() { return this._unknownComponents || (this._unknownComponents = []) }

/** @type {{id: string, listeners: function[]}[]} */
static get listeners() { return this._listeners || (this._listeners = []) }

/** @type {<{name: string, filter: function}[]>} */
static get nameSetters() { return this._nameSetters || (this._nameSetters = []) }
static get componentAliases() { return this._componentAliases || (this._componentAliases = []) }

/** @type {Object.<string, string>} */
static get componentAliases() { return this._componentAliases || (this._componentAliases = {}) }

static get ReactComponent() { return ReactComponent }

/**
* Processes a React component.
* @param {Reflection.modules.React.Component} component The React component class
* @param {object} retVal
* @param {object} important
* @param {string} important.selector A query selector the component will render elements matching (used to select all component instances to force them to rerender)
* @return {ReactComponent}
*/
static push(component, retVal, important) {
if (!(component instanceof Function)) return null;
const { displayName } = component;
Expand All @@ -212,6 +231,8 @@ export class ReactComponents {
return component;
}

if (!important) important = component[ReactComponent.important];

const c = new ReactComponent(displayName, component, retVal, important);
this.components.push(c);

Expand All @@ -226,16 +247,19 @@ export class ReactComponents {

/**
* Finds a component from the components array or by waiting for it to be mounted.
* @param {String} name The component's name
* @param {Object} important An object containing a selector to look for
* @param {Function} filter A function to filter components if a single element is rendered by multiple components
* @return {Promise => ReactComponent}
* @param {string} name The component's name
* @param {object} important An object containing a selector to look for
* @param {function} filter A function to filter components if a single element is rendered by multiple components
* @return {Promise<ReactComponent>}
*/
static async getComponent(name, important, filter) {
name = this.getComponentName(name);

const have = this.components.find(c => c.id === name);
if (have) return have;
if (have) {
if (!have.important) have.important = important;
return have;
}

if (important) {
const callback = () => {
Expand All @@ -262,7 +286,7 @@ export class ReactComponents {
}

if (!component && filter) {
Logger.log('ReactComponents', ['Found elements matching the query selector but no components passed the filter']);
Logger.log('ReactComponents', ['Found elements matching the query selector but no components passed the filter', name, important, filter]);
return;
}

Expand Down Expand Up @@ -321,8 +345,12 @@ export class ReactComponents {
return this.nameSetters.push({ name, filter });
}

/**
* Processes a React component that isn't known.
* @param {Reflection.modules.React.Component} component
* @param {} retVal
*/
static processUnknown(component, retVal) {
const have = this.unknownComponents.find(c => c.component === component);
for (const [fi, filter] of this.nameSetters.entries()) {
if (filter.filter.filter(component)) {
Logger.log('ReactComponents', 'Filter match!');
Expand All @@ -331,9 +359,8 @@ export class ReactComponents {
return this.push(component, retVal);
}
}
if (have) return have;
this.unknownComponents.push(component);
return component;

if (!this.unknownComponents.includes(component)) this.unknownComponents.push(component);
}
}

Expand Down Expand Up @@ -441,7 +468,7 @@ export class ReactAutoPatcher {
}

static async patchNameTag() {
const { selector } = Reflection.resolve('nameTag', 'username', 'discriminator', 'ownerIcon');
const { selector } = Reflection.resolve('nameTag', 'username', 'discriminator', 'discriminatorWithMobileIndicator');
this.NameTag = await ReactComponents.getComponent('NameTag', {selector});
}

Expand Down
16 changes: 13 additions & 3 deletions client/src/modules/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,20 @@ export default class Theme extends Content {

const watchfiles = Settings.getSetting('css', 'default', 'watch-files');
if (watchfiles.value) this.watchfiles = this.files;
watchfiles.on('setting-updated', event => {

watchfiles.on('setting-updated', this.__watchFilesSettingUpdated = event => {
if (event.value) this.watchfiles = this.files;
else this.watchfiles = [];
});

this.on('unload', () => {
watchfiles.off('setting-updated', this.__watchFilesSettingUpdated);

if (this._filewatcher) {
this._filewatcher.removeAll();
delete this._filewatcher;
}
});
}

get type() { return 'theme' }
Expand Down Expand Up @@ -61,7 +71,7 @@ export default class Theme extends Content {
async compile() {
Logger.log(this.name, 'Compiling CSS');

if (this.info.type === 'sass') {
if (this.info.type === 'sass' || this.info.type === 'scss') {
const config = await ThemeManager.getConfigAsSCSS(this.settings);

const result = await ClientIPC.send('bd-compileSass', {
Expand Down Expand Up @@ -147,7 +157,7 @@ export default class Theme extends Content {
* @param {Array} files Files to watch
*/
set watchfiles(files) {
if (this.packed) {
if (this.unloaded || this.packed) {
// Don't watch files for packed themes
return;
}
Expand Down
2 changes: 1 addition & 1 deletion client/src/modules/thememanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default class ThemeManager extends ContentManager {
});
if (instance.enabled) {
instance.userConfig.enabled = false;
instance.enable();
instance.enable(false);
}
return instance;
} catch (err) {
Expand Down
1 change: 0 additions & 1 deletion client/src/styles/partials/bdsettings/card.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
.bd-card {
display: flex;
flex-direction: column;
flex-grow: 1;
background: transparent;
border-bottom: 1px solid rgba(114, 118, 126, .3);
min-height: 150px;
Expand Down
Loading

0 comments on commit 4f935f4

Please sign in to comment.