From 67f7111f66af4d9d4c63f2abf4549137c5c57a62 Mon Sep 17 00:00:00 2001 From: Jiiks Date: Wed, 7 Feb 2018 18:02:27 +0200 Subject: [PATCH] Content manager error modal --- client/src/index.js | 1 + client/src/modules/contentmanager.js | 26 +++++-- client/src/modules/pluginmanager.js | 4 ++ client/src/structs/error.js | 9 +++ .../src/styles/partials/generic/modals.scss | 67 ++++++++++++++++++- client/src/ui/components/bd/BdModals.vue | 14 +++- .../src/ui/components/common/ErrorModal.vue | 30 +++++++++ 7 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 client/src/ui/components/common/ErrorModal.vue diff --git a/client/src/index.js b/client/src/index.js index 59015317..47d0519d 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -16,6 +16,7 @@ import { ClientLogger as Logger } from 'common'; class BetterDiscord { constructor() { + window.css = CssEditor; window.pm = PluginManager; window.events = Events; window.wpm = WebpackModules; diff --git a/client/src/modules/contentmanager.js b/client/src/modules/contentmanager.js index e631ad7e..d409e76e 100644 --- a/client/src/modules/contentmanager.js +++ b/client/src/modules/contentmanager.js @@ -16,6 +16,10 @@ import { Error } from 'structs'; export default class { + static get errors() { + return this._errors || (this._errors = []); + } + static get localContent() { return this._localContent ? this._localContent : (this._localContent = []); } @@ -33,16 +37,26 @@ export default class { try { await this.preloadContent(dir); } catch (err) { - //We don't want every plugin/theme to fail loading when one does - /*Events.emit('bd-error', { - header: `${this.moduleName} - Failed to load plugin: ${dir}`, - text: err.message, - type: 'err' - });*/ + this.errors.push(new Error({ + module: this.moduleName, + message: `Failed to load ${dir}`, + err + })); + Logger.err(this.moduleName, err); } } + if (this.errors.length) { + Events.emit('bd-error', { + header: `${this.moduleName} - one or more ${this.contentType}(s) failed to load`, + module: this.moduleName, + type: 'err', + content: this.errors + }); + } + this._errors = []; + return this.localContent; } catch (err) { throw err; diff --git a/client/src/modules/pluginmanager.js b/client/src/modules/pluginmanager.js index dfcd70a5..4e7a7cd9 100644 --- a/client/src/modules/pluginmanager.js +++ b/client/src/modules/pluginmanager.js @@ -19,6 +19,10 @@ export default class extends ContentManager { return this.localContent; } + static get contentType() { + return 'plugin'; + } + static get moduleName() { return 'PluginManager'; } diff --git a/client/src/structs/error.js b/client/src/structs/error.js index 21642a89..df6a8c16 100644 --- a/client/src/structs/error.js +++ b/client/src/structs/error.js @@ -12,6 +12,7 @@ export class Error { constructor(args) { this.args = args; + this.showStack = false; // For error modal } get module() { @@ -26,4 +27,12 @@ export class Error { return this.args.err; } + get stackTrace() { + return this.err.stack; + } + + get _type() { + return 'err'; + } + } diff --git a/client/src/styles/partials/generic/modals.scss b/client/src/styles/partials/generic/modals.scss index eac7f0dc..4fa762ca 100644 --- a/client/src/styles/partials/generic/modals.scss +++ b/client/src/styles/partials/generic/modals.scss @@ -197,4 +197,69 @@ } } } -} \ No newline at end of file +} + +.bd-modal-error .bd-modal-error-title { + padding: 5px; + background: rgba(0,0,0,.3); + border-radius: 3px 3px 0 0; +} + +.bd-modal-error { + margin-top: 5px; + + .bd-scroller-wrap { + background: rgba(0,0,0,.2); + + .bd-scroller { + overflow-x: auto; + padding: 0; + + &::-webkit-scrollbar-corner { + background: transparent; + } + } + } +} + +.bd-modal-error .bd-scroller-wrap { + opacity: 0; +} + +.bd-modal-error.bd-open { + .bd-modal-error-body { + transform: scaleY(1) translateY(0%); + margin-top: 0%; + opacity: 1; + + span { + font-weight: 700; + } + } + .bd-scroller-wrap { + opacity: 1; + } +} + +.bd-modal-error .bd-modal-error-body { + white-space: pre-wrap; + font-size: 12px; + font-family: 'Consolas'; + padding: 0 5px; + border-radius: 3px; + max-height: 100px; + width: auto; + transition: transform 0.2s ease, margin-top 0.2s ease, opacity 0.2s ease; + transform: scaleY(0) translateY(0%); + margin-top: -50%; + opacity: 0; +} + +.bd-modal-titlelink { + cursor: pointer; + color: $colbdblue; + &:hover { + text-decoration: underline; + color: lighten($colbdblue, 5%); + } +} diff --git a/client/src/ui/components/bd/BdModals.vue b/client/src/ui/components/bd/BdModals.vue index e31c4e71..61e7995f 100644 --- a/client/src/ui/components/bd/BdModals.vue +++ b/client/src/ui/components/bd/BdModals.vue @@ -19,7 +19,9 @@ :class="[{'bd-err': modal.type && modal.type === 'err'}, {'bd-modal-out': modal.closing}]">
- {{modal.text}} +
+ +
Ctrl+Shift+I for more details @@ -36,6 +38,7 @@ import { Events } from 'modules'; import { Modal } from '../common'; import { MiError } from '../common/MaterialIcon'; + import ErrorModal from '../common/ErrorModal.vue'; export default { data() { @@ -44,12 +47,13 @@ } }, components: { - Modal, MiError + Modal, MiError, ErrorModal }, beforeMount() { Events.on('bd-error', e => { e.closing = false; this.modals.push(e); + console.log(this.modals); }); }, methods: { @@ -58,6 +62,12 @@ setTimeout(() => { this.modals.splice(index, 1); }, 200); + }, + showStack(error) { + error.showStack = true; + }, + hideStack(error) { + error.showStack = false; } } } diff --git a/client/src/ui/components/common/ErrorModal.vue b/client/src/ui/components/common/ErrorModal.vue new file mode 100644 index 00000000..8c28581d --- /dev/null +++ b/client/src/ui/components/common/ErrorModal.vue @@ -0,0 +1,30 @@ +/** + * BetterDiscord Error Modal Component + * 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. +*/ + + +