diff --git a/.gitignore b/.gitignore index f3f7b10f..2cd26cb8 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ v2/lib/static.js Installers/**/*/bin Installers/**/*/obj Installers/**/*/packages +.vs diff --git a/core/.babelrc b/core/.babelrc new file mode 100644 index 00000000..562ff7c9 --- /dev/null +++ b/core/.babelrc @@ -0,0 +1,10 @@ +{ + "presets": [ + ["env", { + "targets": { + "node": "6.7.0" + }, + "debug": true + }] + ] +} \ No newline at end of file diff --git a/core/dist/main.js b/core/dist/main.js new file mode 100644 index 00000000..0f6670e3 --- /dev/null +++ b/core/dist/main.js @@ -0,0 +1,58 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const { Utils, FileUtils, BDIpc, Config } = require('./modules'); + +const Common = {}; + +const dummyArgs = { + 'version': '0.3.1', + 'paths': [{ 'base': 'basePath' }, { 'plugins': 'pluginsPath' }, { 'themes': 'themesPath' }] +}; + +class Comms { + + constructor() { + this.initListeners(); + } + + initListeners() { + BDIpc.on('bd-getConfig', o => { + o.reply(Common.Config.config); + }); + + BDIpc.on('bd-readFile', this.readFile); + BDIpc.on('bd-readJson', o => this.readFile(o, true)); + } + + readFile(o, json) { + return _asyncToGenerator(function* () { + const { path } = o.args; + try { + const readFile = json ? yield FileUtils.readJsonFromFile(path) : yield FileUtils.readFile(path); + o.reply(readFile); + } catch (err) { + o.reply(err); + } + })(); + } + +} + +class BetterDiscord { + + constructor(args) { + Common.Config = new Config(args || dummyArgs); + this.comms = new Comms(); + } + + get fileUtils() { + return FileUtils; + } + +} + +module.exports = { + BetterDiscord +}; \ No newline at end of file diff --git a/core/dist/modules/bdipc.js b/core/dist/modules/bdipc.js new file mode 100644 index 00000000..38dbd30c --- /dev/null +++ b/core/dist/modules/bdipc.js @@ -0,0 +1,38 @@ +'use strict'; + +const { ipcMain } = require('electron'); + +class BDIpcEvent { + + constructor(event, args) { + this.bindings(); + this.ipcEvent = event; + this.args = args; + this.__eid = args.__eid; + delete this.args.__eid; + } + + bindings() { + this.send = this.send.bind(this); + this.reply = this.reply.bind(this); + } + + send(message) { + console.log(this.__eid); + this.ipcEvent.sender.send(this.__eid, message); + } + + reply(message) { + this.send(message); + } + +} + +class BDIpc { + + static on(channel, cb) { + ipcMain.on(channel, (event, args) => cb(new BDIpcEvent(event, args))); + } +} + +module.exports = { BDIpc }; \ No newline at end of file diff --git a/core/dist/modules/config.js b/core/dist/modules/config.js new file mode 100644 index 00000000..20776dfe --- /dev/null +++ b/core/dist/modules/config.js @@ -0,0 +1,26 @@ +'use strict'; + +class Config { + + constructor(args) { + this.args = args; + } + + get version() { + return this.args.version; + } + + get paths() { + return this.args.paths; + } + + get config() { + return { + 'version': this.version, + 'paths': this.paths + }; + } + +} + +module.exports = { Config }; \ No newline at end of file diff --git a/core/dist/modules/index.js b/core/dist/modules/index.js new file mode 100644 index 00000000..e9f233bc --- /dev/null +++ b/core/dist/modules/index.js @@ -0,0 +1,38 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _bdipc = require('./bdipc'); + +Object.defineProperty(exports, 'BDIpc', { + enumerable: true, + get: function () { + return _bdipc.BDIpc; + } +}); + +var _utils = require('./utils'); + +Object.defineProperty(exports, 'Utils', { + enumerable: true, + get: function () { + return _utils.Utils; + } +}); +Object.defineProperty(exports, 'FileUtils', { + enumerable: true, + get: function () { + return _utils.FileUtils; + } +}); + +var _config = require('./config'); + +Object.defineProperty(exports, 'Config', { + enumerable: true, + get: function () { + return _config.Config; + } +}); \ No newline at end of file diff --git a/core/dist/modules/utils.js b/core/dist/modules/utils.js new file mode 100644 index 00000000..cc6993f2 --- /dev/null +++ b/core/dist/modules/utils.js @@ -0,0 +1,118 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const path = require('path'), + fs = require('fs'); + +class Utils { + + static tryParseJson(jsonString) { + return _asyncToGenerator(function* () { + try { + return JSON.parse(jsonString); + } catch (err) { + throw { + 'message': 'Failed to parse json', + err + }; + } + })(); + } + + static get timestamp() { + return 'Timestamp'; + } + +} + +class FileUtils { + + static fileExists(path) { + return _asyncToGenerator(function* () { + return new Promise(function (resolve, reject) { + fs.stat(path, function (err, stats) { + if (err) return reject({ + 'message': `No such file or directory: ${err.path}`, + err + }); + + if (!stats.isFile()) return reject({ + 'message': `Not a file: ${path}`, + stats + }); + + resolve(); + }); + }); + })(); + } + + static directoryExists(path) { + return _asyncToGenerator(function* () { + return new Promise(function (resolve) { + fs.stat(path, function (err, stats) { + if (err) return reject({ + 'message': `Directory does not exist: ${path}`, + err + }); + + if (!stats.isDirectory()) return reject({ + 'message': `Not a directory: ${path}`, + stats + }); + + resolve(); + }); + }); + })(); + } + + static readFile(path) { + var _this = this; + + return _asyncToGenerator(function* () { + try { + yield _this.fileExists(path); + } catch (err) { + throw err; + } + + return new Promise(function (resolve) { + fs.readFile(path, 'utf-8', function (err, data) { + if (err) reject({ + 'message': `Could not read file: ${path}`, + err + }); + + resolve(data); + }); + }); + })(); + } + + static readJsonFromFile(path) { + var _this2 = this; + + return _asyncToGenerator(function* () { + let readFile; + try { + readFile = yield _this2.readFile(path); + } catch (err) { + throw err; + } + + try { + const parsed = yield Utils.tryParseJson(readFile); + return parsed; + } catch (err) { + throw Object.assign(err, { path }); + } + })(); + } +} + +module.exports = { + Utils, + FileUtils +}; \ No newline at end of file diff --git a/core/dist/test.js b/core/dist/test.js new file mode 100644 index 00000000..b9803bd1 --- /dev/null +++ b/core/dist/test.js @@ -0,0 +1,48 @@ +const { BetterDiscord } = require('./main.js'); + +const _bd = new BetterDiscord(); + +const fileUtils = _bd.fileUtils; + +//console.log(fileUtils.readJsonFromFile); + +function dirExistsTest() { + fileUtils.readJsonFromFile('test.json').then(data => { + if(data.err) { + console.log("ERR"); + console.log(data); + } else { + console.log(data); + } + }).catch(err => { console.log(err) }); +} + + +String.prototype.padLeft = Number.prototype.padLeft = function(prefix, len) { + let str = this.toString(); + while(str.length < len) str = prefix + str; + return str; +} + +String.prototype.padRight = Number.prototype.padLeft = function(suffix, len) { + let str = this.toString(); + while(str.length < len) str = str + suffix; + return str; +} + +//console.log("".padStart); +// +//let date = new Date(); +//let dateString = `[${date.getDate().padLeft("0", 2)}/${date.getMonth()+1}/${date.getYear()}]`; +//console.log(dateString); +//dirExistsTest(); + + +const original = String.prototype.toString; +String.prototype.toString = function() { + let str = original.apply(this); + if(str === "foo") return "bar"; + return str; +} + +String.prototype.toString = proxy; \ No newline at end of file diff --git a/core/dist/test.json b/core/dist/test.json new file mode 100644 index 00000000..ca507327 --- /dev/null +++ b/core/dist/test.json @@ -0,0 +1,3 @@ +{ + "foo": "bar +} \ No newline at end of file diff --git a/core/dist/utils.js b/core/dist/utils.js new file mode 100644 index 00000000..9fb42a7e --- /dev/null +++ b/core/dist/utils.js @@ -0,0 +1,97 @@ +'use strict'; + +function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + +const path = require('path'), + fs = require('fs'); + +class Utils { + + static tryParseJson(jsonString) { + return _asyncToGenerator(function* () { + try { + return JSON.parse(jsonString); + } catch (err) { + throw { "message": "Failed to parse json", err }; + } + })(); + } + + static get timestamp() { + return "lol".padStart(10, "g"); + } + +} + +class FileUtils { + + static fileExists(path) { + return _asyncToGenerator(function* () { + return new Promise(function (resolve, reject) { + fs.stat(path, function (err, stats) { + if (err) return reject({ "message": `No such file or directory: ${err.path}`, err }); + if (!stats.isFile()) return reject({ "message": `Not a file: ${path}`, stats }); + resolve(); + }); + }); + })(); + } + + static directoryExists(path) { + return _asyncToGenerator(function* () { + return new Promise(function (resolve) { + fs.stat(path, function (err, stats) { + if (err) return reject({ "message": `Directory does not exist: ${path}`, err }); + if (!stats.isDirectory()) return reject({ "message": `Not a directory: ${path}`, stats }); + resolve(); + }); + }); + })(); + } + + static readFile(path) { + var _this = this; + + return _asyncToGenerator(function* () { + let fileExists; + try { + fileExists = yield _this.fileExists(path); + } catch (err) { + throw err; + } + + return new Promise(function (resolve) { + fs.readFile(path, function (err, data) { + if (err) reject({ "message": `Could not read file: ${path}`, err }); + resolve(data); + }); + }); + })(); + } + + static readJsonFromFile(path) { + var _this2 = this; + + return _asyncToGenerator(function* () { + let readFile; + try { + readFile = yield _this2.readFile(path); + } catch (err) { + throw err; + } + + let parsed; + try { + const parsed = yield Utils.tryParseJson(readFile); + return parsed; + } catch (err) { + throw Object.assign(err, { path }); + } + })(); + } +} + +module.exports = { + Utils, + FileUtils +}; \ No newline at end of file diff --git a/core/gulpfile.js b/core/gulpfile.js new file mode 100644 index 00000000..93bae3cd --- /dev/null +++ b/core/gulpfile.js @@ -0,0 +1,14 @@ +const + gulp = require('gulp'), + pump = require('pump'), + babel = require('gulp-babel'); + +const task_babel = function () { + return pump([ + gulp.src('src/**/*js'), + babel(), + gulp.dest('dist') + ]); +} + +gulp.task('babel', task_babel); \ No newline at end of file diff --git a/core/index.js b/core/index.js new file mode 100644 index 00000000..1a3833cd --- /dev/null +++ b/core/index.js @@ -0,0 +1,23 @@ +class BetterDiscord { + + constructor() {} + + async asyncTest() { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve("asyncTest!"); + }, 3000); + }); + } + + async asyncTest2() { + const at = await this.asyncTest(); + console.log(at); + console.log("Finished!"); + } + +} + +module.exports = { + BetterDiscord +}; \ No newline at end of file diff --git a/core/package.json b/core/package.json new file mode 100644 index 00000000..146f6375 --- /dev/null +++ b/core/package.json @@ -0,0 +1,26 @@ +{ + "name": "bdcore", + "description": "BetterDiscord core package", + "author": "Jiiks", + "version": "0.4.0", + "homepage": "https://betterdiscord.net", + "license": "MIT", + "main": "index.js", + "contributors": [ + "Jiiks", + "Pohky" + ], + "repository": { + "type": "git", + "url": "https://github.com/Jiiks/BetterDiscordApp.git" + }, + "private": false, + "devDependencies": { + "babel-core": "^6.26.0", + "babel-preset-env": "^1.6.1", + "electron": "^1.7.10", + "gulp": "^3.9.1", + "gulp-babel": "^7.0.0", + "pump": "^2.0.0" + } +} diff --git a/core/src/main.js b/core/src/main.js new file mode 100644 index 00000000..9c0e7401 --- /dev/null +++ b/core/src/main.js @@ -0,0 +1,54 @@ +const { Utils, FileUtils, BDIpc, Config } = require('./modules'); + +const Common = {}; + +const dummyArgs = { + 'version': '0.3.1', + 'paths': [ + { 'base': 'basePath' }, + { 'plugins': 'pluginsPath' }, + { 'themes': 'themesPath' } + ] +}; + +class Comms { + + constructor() { + this.initListeners(); + } + + initListeners() { + BDIpc.on('bd-getConfig', o => { + o.reply(Common.Config.config); + }); + + BDIpc.on('bd-readFile', this.readFile); + BDIpc.on('bd-readJson', o => this.readFile(o, true)); + } + + async readFile(o, json) { + const { path } = o.args; + try { + const readFile = json ? await FileUtils.readJsonFromFile(path) : await FileUtils.readFile(path); + o.reply(readFile); + } catch (err) { + o.reply(err); + } + } + +} + +class BetterDiscord { + + constructor(args) { + Common.Config = new Config(args || dummyArgs); + this.comms = new Comms(); + } + + get fileUtils() { return FileUtils; } + +} + +module.exports = { + BetterDiscord +} \ No newline at end of file diff --git a/core/src/modules/bdipc.js b/core/src/modules/bdipc.js new file mode 100644 index 00000000..11909972 --- /dev/null +++ b/core/src/modules/bdipc.js @@ -0,0 +1,36 @@ +const { ipcMain } = require('electron'); + +class BDIpcEvent { + + constructor(event, args) { + this.bindings(); + this.ipcEvent = event; + this.args = args; + this.__eid = args.__eid; + delete this.args.__eid; + } + + bindings() { + this.send = this.send.bind(this); + this.reply = this.reply.bind(this); + } + + send(message) { + console.log(this.__eid); + this.ipcEvent.sender.send(this.__eid, message); + } + + reply(message) { + this.send(message); + } + +} + +class BDIpc { + + static on(channel, cb) { + ipcMain.on(channel, (event, args) => cb(new BDIpcEvent(event, args))); + } +} + +module.exports = { BDIpc }; \ No newline at end of file diff --git a/core/src/modules/config.js b/core/src/modules/config.js new file mode 100644 index 00000000..a8ae53f8 --- /dev/null +++ b/core/src/modules/config.js @@ -0,0 +1,24 @@ +class Config { + + constructor(args) { + this.args = args; + } + + get version() { + return this.args.version; + } + + get paths() { + return this.args.paths; + } + + get config() { + return { + 'version': this.version, + 'paths': this.paths + }; + } + +} + +module.exports = { Config }; \ No newline at end of file diff --git a/core/src/modules/index.js b/core/src/modules/index.js new file mode 100644 index 00000000..b5f7415a --- /dev/null +++ b/core/src/modules/index.js @@ -0,0 +1,3 @@ +export { BDIpc } from './bdipc'; +export { Utils, FileUtils } from './utils'; +export { Config } from './config'; \ No newline at end of file diff --git a/core/src/modules/utils.js b/core/src/modules/utils.js new file mode 100644 index 00000000..2e322e05 --- /dev/null +++ b/core/src/modules/utils.js @@ -0,0 +1,101 @@ +const + path = require('path'), + fs = require('fs'); + +class Utils { + + static async tryParseJson(jsonString) { + try { + return JSON.parse(jsonString); + }catch(err) { + throw ({ + 'message': 'Failed to parse json', + err + }); + } + } + + static get timestamp() { + return 'Timestamp'; + } + +} + +class FileUtils { + + static async fileExists(path) { + return new Promise((resolve, reject) => { + fs.stat(path, (err, stats) => { + if(err) return reject({ + 'message': `No such file or directory: ${err.path}`, + err + }); + + if(!stats.isFile()) return reject({ + 'message': `Not a file: ${path}`, + stats + }); + + resolve(); + }); + }); + } + + static async directoryExists(path) { + return new Promise(resolve => { + fs.stat(path, (err, stats) => { + if(err) return reject({ + 'message': `Directory does not exist: ${path}`, + err + }); + + if(!stats.isDirectory()) return reject({ + 'message': `Not a directory: ${path}`, + stats + }); + + resolve(); + }); + }); + } + + static async readFile(path) { + try { + await this.fileExists(path); + } catch(err) { + throw(err); + } + + return new Promise(resolve => { + fs.readFile(path, 'utf-8', (err, data) => { + if(err) reject({ + 'message': `Could not read file: ${path}`, + err + }); + + resolve(data); + }); + }); + } + + static async readJsonFromFile(path) { + let readFile; + try { + readFile = await this.readFile(path); + } catch(err) { + throw(err); + } + + try { + const parsed = await Utils.tryParseJson(readFile); + return parsed; + } catch(err) { + throw(Object.assign(err, { path })); + } + } +} + +module.exports = { + Utils, + FileUtils +} \ No newline at end of file diff --git a/core/tests/config.json b/core/tests/config.json new file mode 100644 index 00000000..fa1a8e7e --- /dev/null +++ b/core/tests/config.json @@ -0,0 +1,4 @@ +{ + "version": "0.3.2", + "paths": [] +} \ No newline at end of file diff --git a/core/tests/frontend/index.html b/core/tests/frontend/index.html new file mode 100644 index 00000000..a99e496b --- /dev/null +++ b/core/tests/frontend/index.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/core/tests/frontend/main.js b/core/tests/frontend/main.js new file mode 100644 index 00000000..3bec0671 --- /dev/null +++ b/core/tests/frontend/main.js @@ -0,0 +1,20 @@ +const { ipcRenderer } = require('electron'); + +class BDIpc { + + static async send(channel, message) { + const __eid = Date.now().toString(); + ipcRenderer.send( + channel.startsWith('bd-') ? channel: `bd-${channel}`, + message === undefined ? { __eid } : Object.assign(message, { __eid }) + ); + + return new Promise((resolve, reject) => { + ipcRenderer.once(__eid, (event, arg) => { + if (arg.err) return reject(arg); + resolve(arg); + }); + }); + } + +} \ No newline at end of file diff --git a/core/tests/index.js b/core/tests/index.js new file mode 100644 index 00000000..f895eb98 --- /dev/null +++ b/core/tests/index.js @@ -0,0 +1,21 @@ +const { app, BrowserWindow } = require('electron'); +const { BetterDiscord } = require('../dist/main'); +const path = require('path'); +const url = require('url'); + +const config = require('./config.json'); + +let bw; + +const bd = new BetterDiscord(config); + +app.on('ready', () => { + bw = new BrowserWindow({ width: 1920, height: 1080 }); + bw.webContents.openDevTools(); + bw.loadURL(url.format({ + pathname: path.join(__dirname, 'frontend', 'index.html'), + protocol: 'file', + slashes: true + })); + bw.on('closed', () => app.quit()); +}); \ No newline at end of file diff --git a/core/tests/run.bat b/core/tests/run.bat new file mode 100644 index 00000000..ebae3e02 --- /dev/null +++ b/core/tests/run.bat @@ -0,0 +1 @@ +..\node_modules\.bin\electron.cmd .\ \ No newline at end of file