From 99ef0d9f81b8d9c2fb02e43e3e36da6215515414 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sun, 24 Feb 2019 12:28:29 +0200 Subject: [PATCH 01/37] add bdedit --- editor/package.json | 23 +++++++++++++++++++++ editor/src/Editor.vue | 12 +++++++++++ editor/src/index.js | 22 ++++++++++++++++++++ editor/src/styles/index.scss | 0 editor/webpack.config.js | 39 ++++++++++++++++++++++++++++++++++++ package-lock.json | 16 ++++++++++++--- package.json | 3 +++ 7 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 editor/package.json create mode 100644 editor/src/Editor.vue create mode 100644 editor/src/index.js create mode 100644 editor/src/styles/index.scss create mode 100644 editor/webpack.config.js diff --git a/editor/package.json b/editor/package.json new file mode 100644 index 00000000..0e692209 --- /dev/null +++ b/editor/package.json @@ -0,0 +1,23 @@ +{ + "name": "bdeditorwindow", + "description": "BetterDiscord editor window", + "author": "JsSucks", + "version": "0.4.0", + "homepage": "https://betterdiscord.net", + "license": "MIT", + "main": "dist/csseditor.js", + "contributors": [ + "Jiiks", + "Pohky" + ], + "repository": { + "type": "git", + "url": "https://github.com/JsSucks/BetterDiscordApp.git" + }, + "private": false, + "scripts": { + "build": "webpack --progress --colors", + "watch": "webpack --progress --colors --watch", + "release": "webpack --progress --colors --config=webpack.production.config.js" + } +} diff --git a/editor/src/Editor.vue b/editor/src/Editor.vue new file mode 100644 index 00000000..1406c147 --- /dev/null +++ b/editor/src/Editor.vue @@ -0,0 +1,12 @@ + + + diff --git a/editor/src/index.js b/editor/src/index.js new file mode 100644 index 00000000..756464cc --- /dev/null +++ b/editor/src/index.js @@ -0,0 +1,22 @@ +// const styles = require('./styles/index.scss'); + +import Vue from 'vue'; + +import Editor from './Editor.vue'; +import styles from './styles/index.scss'; + +const mount = document.createElement('div'); +mount.classList.add('container'); +document.body.appendChild(mount); + +const vue = new Vue({ + el: mount, + components: { Editor }, + template: '' +}); + +const style = document.createElement('style'); +style.id = 'bd-main'; +style.type = 'text/css'; +style.appendChild(document.createTextNode(styles)); +document.head.appendChild(style); diff --git a/editor/src/styles/index.scss b/editor/src/styles/index.scss new file mode 100644 index 00000000..e69de29b diff --git a/editor/webpack.config.js b/editor/webpack.config.js new file mode 100644 index 00000000..5a36e052 --- /dev/null +++ b/editor/webpack.config.js @@ -0,0 +1,39 @@ +const path = require('path'); +const webpack = require('webpack'); + +const vueLoader = { + test: /\.(vue)$/, + exclude: /node_modules/, + loader: 'vue-loader' +}; + +const scssLoader = { + test: /\.(css|scss)$/, + loader: ['css-loader', 'sass-loader'] +}; + +module.exports = { + entry: './src/index.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'editor.js' + }, + module: { + loaders: [vueLoader, scssLoader] + }, + externals: { + electron: 'window.require("electron")', + fs: 'window.require("fs")', + util: 'window.require("util")', + process: 'require("process")' + }, + resolve: { + alias: { + vue$: path.resolve('..', 'node_modules', 'vue', 'dist', 'vue.esm.js') + }, + modules: [ + path.resolve('..', 'node_modules'), + path.resolve('..', 'common', 'modules') + ] + } +}; diff --git a/package-lock.json b/package-lock.json index 1a770741..81231f81 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,12 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=" }, + "ace-builds": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.4.3.tgz", + "integrity": "sha512-T+e4DQRQR8ReNPOUryXWdXRX1NBTb9rB1y42IhnH4mmFe0NIIpAQVu8BQ9tgU2K3EGaPFZeG7E87OOjaXDP8PQ==", + "dev": true + }, "acorn": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", @@ -1581,6 +1587,13 @@ "tweetnacl": "0.14.5" } }, + "bdedit": { + "version": "github:JsSucks/BDEdit#1ddc18aa4ae980cd0d50618ba4ffa73721a6819e", + "dev": true, + "requires": { + "ace-builds": "1.4.3" + } + }, "beeper": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", @@ -2828,9 +2841,6 @@ "randomfill": "1.0.4" } }, - "csp-parse": { - "version": "github:macropodhq/csp-parse#db7d5f954b420b527d7fb452a93bb6e2fa302c5a" - }, "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", diff --git a/package.json b/package.json index dc7329f9..32024844 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "babel-preset-env": "^1.7.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", + "bdedit": "github:JsSucks/BDEdit", "codemirror": "^5.39.2", "combokeys": "^3.0.0", "css-loader": "^0.28.11", @@ -82,6 +83,8 @@ "watch_core": "npm run watch --prefix core", "build_csseditor": "npm run build --prefix csseditor", "watch_csseditor": "npm run watch --prefix csseditor", + "build_editor": "npm run build --prefix editor", + "watch_editor": "npm run watch --prefix editor", "lint": "eslint -f unix client/src core/src csseditor/src common && npm run sasslint", "lint_fix": "eslint -f unix client/src core/src csseditor/src common --fix", "sasslint": "sass-lint client/src/styles/**/*.scss -v", From f1f23fa220c52c419722f760d0247d9f06801983 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sun, 24 Feb 2019 13:03:15 +0200 Subject: [PATCH 02/37] Initial BDEdit addition. No logic yet. --- core/src/main.js | 11 ++-- core/src/modules/editor.js | 93 +++++++++++++++++++++++++++++++++ core/src/modules/index.js | 1 + editor/src/Editor.vue | 22 +++++++- editor/src/styles/index.scss | 20 +++++++ editor/src/styles/titlebar.scss | 71 +++++++++++++++++++++++++ editor/src/styles/vars.scss | 2 + package-lock.json | 2 +- package.json | 2 +- 9 files changed, 216 insertions(+), 8 deletions(-) create mode 100644 core/src/modules/editor.js create mode 100644 editor/src/styles/titlebar.scss create mode 100644 editor/src/styles/vars.scss diff --git a/core/src/main.js b/core/src/main.js index 29494434..5b4caf58 100644 --- a/core/src/main.js +++ b/core/src/main.js @@ -21,7 +21,8 @@ const TEST_ARGS = () => { 'paths': { 'client': path.resolve(_basePath, 'client', 'dist'), 'core': path.resolve(_basePath, 'core', 'dist'), - 'data': path.resolve(_baseDataPath, 'data') + 'data': path.resolve(_baseDataPath, 'data'), + 'editor': path.resolve(_basePath, 'editor', 'dist') } } } @@ -33,7 +34,7 @@ import deepmerge from 'deepmerge'; import ContentSecurityPolicy from 'csp-parse'; import keytar from 'keytar'; -import { FileUtils, BDIpc, Config, WindowUtils, CSSEditor, Database } from './modules'; +import { FileUtils, BDIpc, Config, WindowUtils, CSSEditor, Editor, Database } from './modules'; const packageJson = require(path.resolve(__dirname, 'package.json')); const sparkplug = path.resolve(__dirname, 'sparkplug.js'); @@ -63,7 +64,8 @@ class Comms { BDIpc.on('bd-sendToDiscord', (event, m) => this.sendToDiscord(m.channel, m.message), true); // BDIpc.on('bd-openCssEditor', (event, options) => this.bd.csseditor.openEditor(options), true); - BDIpc.on('bd-sendToCssEditor', (event, m) => this.sendToCssEditor(m.channel, m.message), true); + // BDIpc.on('bd-sendToCssEditor', (event, m) => this.sendToCssEditor(m.channel, m.message), true); + BDIpc.on('bd-openCssEditor', (event, options) => this.bd.editor.openEditor(options), true); BDIpc.on('bd-native-open', (event, options) => { dialog.showOpenDialog(OriginalBrowserWindow.fromWebContents(event.ipcEvent.sender), options, filenames => { @@ -148,7 +150,8 @@ export class BetterDiscord { get comms() { return this._comms ? this._comms : (this._commas = new Comms(this)); } get database() { return this._db ? this._db : (this._db = new Database(this.config.getPath('data'))); } get config() { return this._config ? this._config : (this._config = new Config(this._args)); } - get window() { return this.windowUtils ? this.windowUtils.window : undefined; } + get window() { return this.windowUtils ? this.windowUtils.window : undefined; } + get editor() { return this._editor ? this._editor : (this._editor = new Editor(this, this.config.getPath('editor'))); } constructor(args) { if (TESTS) args = TEST_ARGS(); diff --git a/core/src/modules/editor.js b/core/src/modules/editor.js new file mode 100644 index 00000000..0f4b46e7 --- /dev/null +++ b/core/src/modules/editor.js @@ -0,0 +1,93 @@ +/** + * BetterDiscord Editor Module + * Copyright (c) 2015-present JsSucks - https://github.com/JsSucks + * All rights reserved. + * 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. +*/ + +import path from 'path'; +import { BrowserWindow } from 'electron'; + +import Module from './modulebase'; +import { WindowUtils } from './utils'; +import BDIpc from './bdipc'; + +export default class Editor extends Module { + + constructor(bd, path) { + super(); + this.editorPath = path; + this.bd = bd; + } + + /** + * Opens an editor. + * @return {Promise} + */ + openEditor(options) { + return new Promise((resolve, reject) => { + if (this.editor) { + if (this.editor.isFocused()) return; + + this.editor.focus(); + this.editor.flashFrame(true); + return resolve(true); + } + + options = Object.assign({}, this.options, options); + + this.editor = new BrowserWindow(options); + this.editor.loadURL('about:blank'); + this.editor.setSheetOffset(33); + this.editorUtils = new WindowUtils({ window: this.editor }); + + this.editor.on('close', () => { + this.bd.windowUtils.send('bd-save-csseditor-bounds', this.editor.getBounds()); + this.editor = null; + }); + + this.editor.once('ready-to-show', () => { + this.editor.show(); + }); + + this.editor.webContents.on('did-finish-load', () => { + this.editorUtils.injectScript(path.join(this.editorPath, 'editor.js')); + resolve(true); + }); + }) + } + + /** + * Sends data to the editor. + * @param {String} channel + * @param {Any} data + */ + send(channel, data) { + if (!this.editor) throw { message: 'The CSS editor is not open.' }; + return BDIpc.send(this.editor, channel, data); + } + + /** + * Sets the CSS editor's always on top flag. + */ + set alwaysOnTop(state) { + if (!this.editor) return; + this.editor.setAlwaysOnTop(state); + } + + /** + * Default options to pass to BrowserWindow. + */ + get options() { + return { + width: 800, + height: 600, + show: false, + frame: false + }; + } + +} diff --git a/core/src/modules/index.js b/core/src/modules/index.js index 5f922a23..4a56e948 100644 --- a/core/src/modules/index.js +++ b/core/src/modules/index.js @@ -2,4 +2,5 @@ export { default as BDIpc } from './bdipc'; export { Utils, FileUtils, WindowUtils } from './utils'; export { default as Config } from './config'; export { default as CSSEditor } from './csseditor'; +export { default as Editor } from './editor'; export { default as Database } from './database'; diff --git a/editor/src/Editor.vue b/editor/src/Editor.vue index 1406c147..e226b8e7 100644 --- a/editor/src/Editor.vue +++ b/editor/src/Editor.vue @@ -1,12 +1,30 @@ diff --git a/editor/src/styles/index.scss b/editor/src/styles/index.scss index e69de29b..8ec713ef 100644 --- a/editor/src/styles/index.scss +++ b/editor/src/styles/index.scss @@ -0,0 +1,20 @@ +@import './vars.scss'; +@import './titlebar.scss'; + +html, body { + margin: 0; + padding: 0; + display: flex; + max-height: 100%; + height: 100%; + width: 100%; + background: #2c383e; + min-width: 700px; + min-height: 400px; +} + +.container { + display: flex; + flex-grow: 1; + flex-direction: column; +} diff --git a/editor/src/styles/titlebar.scss b/editor/src/styles/titlebar.scss new file mode 100644 index 00000000..b837087a --- /dev/null +++ b/editor/src/styles/titlebar.scss @@ -0,0 +1,71 @@ +.titlebar { + display: flex; + height: 25px; + padding: 4px 5px; + background: #292b2f; + border-bottom: 1px solid hsla(218,5%,47%,.3); + user-select: none; + cursor: default; + + .icon { + width: 31px; + height: 25px; + + .inner { + width: 25px; + height: 25px; + background-image: $bdicon; + background-size: 22px 22px; + background-repeat: no-repeat; + background-position: center; + } + } + + .title { + color: #bac9d2; + font-family: Whitney,Helvetica Neue,Helvetica,Arial,sans-serif; + line-height: 25px; + font-size: 15px; + } + + .controls { + margin: 0 0 0 2px; + font-size: 0; + + button { + -webkit-app-region: no-drag; + border-radius: 3px; + width: 25px; + font-size: 12px; + font-weight: 600; + background: #36393f; + color: #bac9d2; + font-family: Whitney,Helvetica Neue,Helvetica,Arial,sans-serif; + transition: background-color .2s ease, color .2s ease; + cursor: default; + border: 0; + height: 25px; + z-index: 900062; + padding: 0; + margin: 0 0 0 4px; + + &:hover { + background: #44474e; + color: #FFF; + } + + &.active { + background: #3a71c1; + } + } + } + + .draggable { + top: 0; + left: 0; + right: 63px; + position: absolute; + height: 33px; + -webkit-app-region: drag; + } +} diff --git a/editor/src/styles/vars.scss b/editor/src/styles/vars.scss new file mode 100644 index 00000000..202ab708 --- /dev/null +++ b/editor/src/styles/vars.scss @@ -0,0 +1,2 @@ +$logoSmallGw: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkltYWdlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGUgdHlwZT0idGV4dC9jc3MiPi5zdDB7ZGlzcGxheTpub25lO30uc3Qxe2Rpc3BsYXk6aW5saW5lO2ZpbGw6IzAyMDAzNTtzdHJva2U6IzAwMDAwMDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9LnN0MntmaWxsOiMzRUNDOUU7fS5zdDN7ZmlsbDojRkZGRkZGO308L3N0eWxlPjxnIGlkPSJMYXllcl8yIiBjbGFzcz0ic3QwIj48cmVjdCB4PSItNjQiIHk9Ii0zMiIgY2xhc3M9InN0MSIgd2lkdGg9IjYxOCIgaGVpZ2h0PSI1NzIiLz48L2c+PGcgaWQ9IkxheWVyXzEiIHhtbG5zOnZlY3Rvcm5hdG9yPSJodHRwOi8vdmVjdG9ybmF0b3IuaW8iPjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik03MCwxOC44Yy0xMy43LDAtMjcuMywxMy43LTI3LjMsMjcuM3YyMzMuNkM0Mi43LDM5Ny43LDEzNy45LDQ5MywyNTYsNDkzYzI5LjcsMCw1OC02LjEsODMuNi0xN1YzNDEuNWMtMTksMjUuNi00OS4zLDQyLjItODMuNiw0Mi4yYy01Ny42LDAtMTA0LjEtNDYuNS0xMDQuMS0xMDQuMVY0Ni4xYzAtMTMuNy0xMy43LTI3LjMtMjcuMy0yNy4zSDcweiIvPjxwYXRoIGNsYXNzPSJzdDMiIGQ9Ik0zODcuNCwxOC44Yy0xMy43LDAtMjcuMywxMy43LTI3LjMsMjcuM3Y0Ny4zQzMyOS4zLDc2LjIsMjkzLjksNjYuMywyNTYsNjYuM2MtMjkuOCwwLTU3LjksNi4zLTgzLjYsMTcuM3YxMzQuMmMxOS0yNS42LDQ5LjMtNDIuMiw4My42LTQyLjJjNTcuNiwwLDEwNC4xLDQ2LjUsMTA0LjEsMTA0LjF2MTg2LjJjNjUuMi0zNi40LDEwOS4yLTEwNiwxMDkuMi0xODYuMlY0Ni4xYzAtMTguOC0xMy43LTI3LjMtMjcuMy0yNy4zSDM4Ny40eiIvPjwvZz48L3N2Zz4=); +$bdicon: $logoSmallGw; diff --git a/package-lock.json b/package-lock.json index 81231f81..3d4e2421 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1588,7 +1588,7 @@ } }, "bdedit": { - "version": "github:JsSucks/BDEdit#1ddc18aa4ae980cd0d50618ba4ffa73721a6819e", + "version": "github:JsSucks/bdedit#1ddc18aa4ae980cd0d50618ba4ffa73721a6819e", "dev": true, "requires": { "ace-builds": "1.4.3" diff --git a/package.json b/package.json index 32024844..b137bf70 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "dependencies": { "asar": "^0.14.6", "csp-parse": "github:macropodhq/csp-parse", + "bdedit": "github:JsSucks/bdedit", "deepmerge": "^2.2.1", "fs-extra": "^7.0.0", "keytar": "^4.3.0", @@ -33,7 +34,6 @@ "babel-preset-env": "^1.7.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", - "bdedit": "github:JsSucks/BDEdit", "codemirror": "^5.39.2", "combokeys": "^3.0.0", "css-loader": "^0.28.11", From a76938521965df08c26d2132e6328b31c10f9af1 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sun, 24 Feb 2019 16:04:25 +0200 Subject: [PATCH 03/37] Run scripts from editor in Discord window --- client/src/modules/csseditor.js | 8 ++++++ core/src/main.js | 10 ++++++++ editor/src/Editor.vue | 45 +++++++++++++++++++++++++++++++-- package-lock.json | 9 ++++--- package.json | 2 +- 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/client/src/modules/csseditor.js b/client/src/modules/csseditor.js index 6534532b..487c1516 100644 --- a/client/src/modules/csseditor.js +++ b/client/src/modules/csseditor.js @@ -38,6 +38,14 @@ export default new class { ClientIPC.on('bd-get-scss', () => this.scss, true); ClientIPC.on('bd-update-scss', (e, scss) => this.updateScss(scss)); ClientIPC.on('bd-save-csseditor-bounds', (e, bounds) => this.saveEditorBounds(bounds)); + ClientIPC.on('bd-runEditorScript', (e, script) => { + try { + new Function(script)(); + e.reply('ok'); + } catch (err) { + e.reply({ err: err.stack || err }); + } + }); ClientIPC.on('bd-save-scss', async (e, scss) => { await this.updateScss(scss); diff --git a/core/src/main.js b/core/src/main.js index 5b4caf58..aeae655d 100644 --- a/core/src/main.js +++ b/core/src/main.js @@ -53,10 +53,13 @@ const CSP = { class Comms { constructor(bd) { this.bd = bd; + this.editorListeners = this.editorListeners.bind(this); this.initListeners(); } initListeners() { + this.editorListeners(); + BDIpc.on('ping', () => 'pong', true); BDIpc.on('bd-getConfig', () => this.bd.config.config, true); @@ -93,6 +96,13 @@ class Comms { BDIpc.on('bd-keytar-find-credentials', (event, { service }) => keytar.findCredentials(service), true); } + editorListeners() { + BDIpc.on('bd-editor-runScript', async (event, script) => { + const result = await this.sendToDiscord('bd-runEditorScript', script); + event.reply(result); + }); + } + async send(channel, message) { BDIpc.send(channel, message); } diff --git a/editor/src/Editor.vue b/editor/src/Editor.vue index e226b8e7..ae0500db 100644 --- a/editor/src/Editor.vue +++ b/editor/src/Editor.vue @@ -12,19 +12,60 @@ - + diff --git a/package-lock.json b/package-lock.json index 3d4e2421..75f8c63f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,8 +18,7 @@ "ace-builds": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.4.3.tgz", - "integrity": "sha512-T+e4DQRQR8ReNPOUryXWdXRX1NBTb9rB1y42IhnH4mmFe0NIIpAQVu8BQ9tgU2K3EGaPFZeG7E87OOjaXDP8PQ==", - "dev": true + "integrity": "sha512-T+e4DQRQR8ReNPOUryXWdXRX1NBTb9rB1y42IhnH4mmFe0NIIpAQVu8BQ9tgU2K3EGaPFZeG7E87OOjaXDP8PQ==" }, "acorn": { "version": "5.7.1", @@ -1588,8 +1587,7 @@ } }, "bdedit": { - "version": "github:JsSucks/bdedit#1ddc18aa4ae980cd0d50618ba4ffa73721a6819e", - "dev": true, + "version": "github:JsSucks/bdedit#95cea7f8d55cf97a9e7dff9d0bf82c7af7c38312", "requires": { "ace-builds": "1.4.3" } @@ -2841,6 +2839,9 @@ "randomfill": "1.0.4" } }, + "csp-parse": { + "version": "github:macropodhq/csp-parse#db7d5f954b420b527d7fb452a93bb6e2fa302c5a" + }, "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", diff --git a/package.json b/package.json index b137bf70..de2c3eee 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ "private": false, "dependencies": { "asar": "^0.14.6", - "csp-parse": "github:macropodhq/csp-parse", "bdedit": "github:JsSucks/bdedit", + "csp-parse": "github:macropodhq/csp-parse", "deepmerge": "^2.2.1", "fs-extra": "^7.0.0", "keytar": "^4.3.0", From 691c9f378a235c8718145848136635c5c9bbc2a9 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sun, 24 Feb 2019 18:29:00 +0200 Subject: [PATCH 04/37] new file/snippet --- editor/src/Editor.vue | 61 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/editor/src/Editor.vue b/editor/src/Editor.vue index ae0500db..71430d37 100644 --- a/editor/src/Editor.vue +++ b/editor/src/Editor.vue @@ -17,6 +17,10 @@ :snippets="snippets" :updateContent="updateContent" :runScript="runScript" + :newFile="newFile" + :saveFile="saveFile" + :newSnippet="newSnippet" + :saveSnippet="saveSnippet" /> @@ -29,6 +33,21 @@ import { BDEdit } from 'bdedit'; ace.acequire = ace.require; + const modes = { + 'css': 'css', + 'scss': 'scss', + 'js': 'js', + 'txt': 'text', + 'json': 'json' + }; + + function resolveMode(fileName) { + if (!fileName.includes('.')) return 'text'; + const ext = fileName.substr(fileName.lastIndexOf('.') + 1); + if (modes.hasOwnProperty(ext)) return modes[ext]; + return 'text'; + } + export default { data() { return { @@ -59,6 +78,48 @@ return ClientIPC.send('editor-runScript', script); }, + newFile(fileName) { + const prefix = fileName; + const mode = resolveMode(fileName); + + let newName = prefix; + let iter = 0; + + while (this.files.find(file => file.name === newName)) { + newName = `${prefix}_${iter}`; + iter++; + } + + const newItem = { type: 'file', name: newName, content: '', mode, saved: false }; + this.files.push(newItem); + return newItem; + }, + + newSnippet(snippetName) { + const prefix = snippetName; + const mode = resolveMode(snippetName); + + let newName = prefix; + let iter = 0; + + while (this.snippets.find(snippet => snippet.name === newName)) { + newName = `${prefix}_${iter}`; + iter++; + } + + const newItem = { type: 'snippet', name: newName, content: '', mode, saved: false }; + this.snippets.push(newItem); + return newItem; + }, + + saveFile(file) { + + }, + + saveSnippet(snippet) { + + }, + toggleaot() { this.alwaysOnTop = !this.alwaysOnTop; remote.getCurrentWindow().setAlwaysOnTop(this.alwaysOnTop); From 3fc1adc503b6c6a352798afdc850b261a7f5ee4d Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sun, 24 Feb 2019 18:39:28 +0200 Subject: [PATCH 05/37] get files/snippets from core --- core/src/main.js | 12 ++++++++++++ editor/src/Editor.vue | 34 ++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/core/src/main.js b/core/src/main.js index aeae655d..3f2efbac 100644 --- a/core/src/main.js +++ b/core/src/main.js @@ -101,6 +101,18 @@ class Comms { const result = await this.sendToDiscord('bd-runEditorScript', script); event.reply(result); }); + + BDIpc.on('bd-editor-getFiles', async (event) => { + event.reply([ + { type: 'file', name: 'custom.scss', content: '', savedContent: '', mode: 'scss', saved: true } + ]); + }); + + BDIpc.on('bd-editor-getSnippets', async (event) => { + event.reply([ + { type: 'snippet', name: 'test.js', content: '', savedContent: '', mode: 'javascript', saved: true } + ]); + }); } async send(channel, message) { diff --git a/editor/src/Editor.vue b/editor/src/Editor.vue index 71430d37..140c18c9 100644 --- a/editor/src/Editor.vue +++ b/editor/src/Editor.vue @@ -12,16 +12,17 @@ - +
+
Loading Please Wait...
+
+ @@ -51,7 +52,7 @@ export default { data() { return { - files: [{ type: 'file', name: 'custom.scss', content: 'asd', savedContent: 'asd', mode: 'scss', saved: true }], + files: [], snippets: [], loading: true, alwaysOnTop: false, @@ -64,9 +65,17 @@ ClientIPC.on('bd-editor-addSnippet', (_, snippet) => this.addSnippet(snippet)); }, mounted() { + (async () => { + this.files = await ClientIPC.send('bd-editor-getFiles'); + this.snippets = await ClientIPC.send('bd-editor-getSnippets'); + + this.loading = false; + })(); }, methods: { - addFile(file) { this.files.push(file) }, + addFile(file) { + this.files.push(file); + }, addSnippet(snippet) { this.snippets.push(file) }, updateContent(item, content) { @@ -124,6 +133,7 @@ this.alwaysOnTop = !this.alwaysOnTop; remote.getCurrentWindow().setAlwaysOnTop(this.alwaysOnTop); }, + close() { window.close(); } From 8c04e7d2d35b8f1220e372c7cec8167d1fe463a2 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sun, 24 Feb 2019 18:43:58 +0200 Subject: [PATCH 06/37] File/snippet saving signals --- core/src/main.js | 10 ++++++++++ editor/src/Editor.vue | 10 ++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core/src/main.js b/core/src/main.js index 3f2efbac..18aa7bc0 100644 --- a/core/src/main.js +++ b/core/src/main.js @@ -113,6 +113,16 @@ class Comms { { type: 'snippet', name: 'test.js', content: '', savedContent: '', mode: 'javascript', saved: true } ]); }); + + BDIpc.on('bd-editor-saveFile', async (event, file) => { + console.log(file); + event.reply('ok'); + }); + + BDIpc.on('bd-editor-saveSnippet', async (event, snippet) => { + console.log(snippet); + event.reply('ok'); + }); } async send(channel, message) { diff --git a/editor/src/Editor.vue b/editor/src/Editor.vue index 140c18c9..b79261d2 100644 --- a/editor/src/Editor.vue +++ b/editor/src/Editor.vue @@ -121,12 +121,14 @@ return newItem; }, - saveFile(file) { - + async saveFile(file) { + const result = await ClientIPC.send('bd-editor-saveFile', file); + console.log(result); }, - saveSnippet(snippet) { - + async saveSnippet(snippet) { + const result = await ClientIPC.send('bd-editor-saveSnippet', snippet); + console.log(result); }, toggleaot() { From d1fd5ae881574d10af852fc8e7b8d64e4438cc15 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Sun, 24 Feb 2019 19:46:11 +0200 Subject: [PATCH 07/37] imodule and base for new editor module in client --- client/src/index.js | 4 +-- client/src/modules/csseditor.js | 2 +- client/src/modules/editor.js | 40 +++++++++++++++++++++ client/src/modules/imodule.js | 44 +++++++++++++++++++++++ client/src/modules/modules.js | 1 + client/src/ui/components/bd/CssEditor.vue | 18 +++++----- core/src/main.js | 7 ++-- 7 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 client/src/modules/editor.js create mode 100644 client/src/modules/imodule.js diff --git a/client/src/index.js b/client/src/index.js index c64134a0..5d2e315d 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -10,7 +10,7 @@ import { DOM, BdUI, BdMenu, Modals, Toasts, Notifications, BdContextMenu, DiscordContextMenu } from 'ui'; import BdCss from './styles/index.scss'; -import { Events, CssEditor, Globals, Settings, Database, Updater, ModuleManager, PluginManager, ThemeManager, ExtModuleManager, Vendor, Patcher, MonkeyPatch, ReactComponents, ReactHelpers, ReactAutoPatcher, DiscordApi, BdWebApi, Connectivity, Cache, Reflection, PackageInstaller } from 'modules'; +import { Events, Globals, Settings, Database, Updater, ModuleManager, PluginManager, ThemeManager, ExtModuleManager, Vendor, Patcher, MonkeyPatch, ReactComponents, ReactHelpers, ReactAutoPatcher, DiscordApi, BdWebApi, Connectivity, Cache, Reflection, PackageInstaller } from 'modules'; import { ClientLogger as Logger, ClientIPC, Utils } from 'common'; import { BuiltinManager, EmoteModule, ReactDevtoolsModule, VueDevtoolsModule, TrackingProtection, E2EE } from 'builtin'; import electron from 'electron'; @@ -30,7 +30,7 @@ class BetterDiscord { this._bd = { DOM, BdUI, BdMenu, Modals, Reflection, Toasts, Notifications, BdContextMenu, DiscordContextMenu, - Events, CssEditor, Globals, Settings, Database, Updater, + Events, Globals, Settings, Database, Updater, ModuleManager, PluginManager, ThemeManager, ExtModuleManager, PackageInstaller, Vendor, diff --git a/client/src/modules/csseditor.js b/client/src/modules/csseditor.js index 487c1516..873a4943 100644 --- a/client/src/modules/csseditor.js +++ b/client/src/modules/csseditor.js @@ -38,7 +38,7 @@ export default new class { ClientIPC.on('bd-get-scss', () => this.scss, true); ClientIPC.on('bd-update-scss', (e, scss) => this.updateScss(scss)); ClientIPC.on('bd-save-csseditor-bounds', (e, bounds) => this.saveEditorBounds(bounds)); - ClientIPC.on('bd-runEditorScript', (e, script) => { + ClientIPC.on('bd-editor-runScript', (e, script) => { try { new Function(script)(); e.reply('ok'); diff --git a/client/src/modules/editor.js b/client/src/modules/editor.js new file mode 100644 index 00000000..b4cea53e --- /dev/null +++ b/client/src/modules/editor.js @@ -0,0 +1,40 @@ +/** + * BetterDiscord Editor Module + * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks + * All rights reserved. + * 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. +*/ + +import { FileUtils, ClientLogger as Logger, ClientIPC } from 'common'; +import Module from './imodule'; + +export default new class extends Module { + + setInitialState(state) { + return { + editorBounds: undefined + }; + } + + events() { + ClientIPC.on('editor-runScript', (e, script) => { + try { + new Function(script)(); + e.reply('ok'); + } catch (err) { + e.reply({ err: err.stack || err }); + } + }); + } + + /** + * Show editor, flashes if already visible. + */ + async show() { + await ClientIPC.send('editor-open', this.state.editorBounds); + } + +} diff --git a/client/src/modules/imodule.js b/client/src/modules/imodule.js new file mode 100644 index 00000000..0afbad3c --- /dev/null +++ b/client/src/modules/imodule.js @@ -0,0 +1,44 @@ +/** + * BetterDiscord Module Base + * Copyright (c) 2015-present JsSucks - https://github.com/JsSucks + * All rights reserved. + * 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 + */ +export default class Module { + + constructor(args) { + this.__ = { + state: args || {}, + args + }; + this.setState = this.setState.bind(this); + this.initialize(); + } + + initialize() { + if (this.bindings) this.bindings(); + if (this.setInitialState) this.setState(this.setInitialState(this.state)); + if (this.events) this.events(); + if (this.init) this.init(); + } + + setState(newState) { + const oldState = this.state; + Object.assign(this.state, newState); + if (this.stateChanged) this.stateChanged(oldState, newState); + } + + 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/modules.js b/client/src/modules/modules.js index 239e89f8..437f54fc 100644 --- a/client/src/modules/modules.js +++ b/client/src/modules/modules.js @@ -1,5 +1,6 @@ export { default as Events } from './events'; export { default as CssEditor } from './csseditor'; +export { default as Editor } from './editor'; export { default as Globals } from './globals'; export { default as Settings } from './settings'; export { default as Database } from './database'; diff --git a/client/src/ui/components/bd/CssEditor.vue b/client/src/ui/components/bd/CssEditor.vue index 18a39f57..a5639641 100644 --- a/client/src/ui/components/bd/CssEditor.vue +++ b/client/src/ui/components/bd/CssEditor.vue @@ -8,6 +8,8 @@ * LICENSE file in the root directory of this source tree. */ +// TODO this should be remade as editor instead of css editor +