commit
91a658db44
|
@ -8,7 +8,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { DOM, BdUI } from 'ui';
|
import { DOM, BdUI, Modals } from 'ui';
|
||||||
import BdCss from './styles/index.scss';
|
import BdCss from './styles/index.scss';
|
||||||
import { Events, CssEditor, Globals, PluginManager, ThemeManager, ModuleManager, WebpackModules, Settings } from 'modules';
|
import { Events, CssEditor, Globals, PluginManager, ThemeManager, ModuleManager, WebpackModules, Settings } from 'modules';
|
||||||
import { ClientLogger as Logger, ClientIPC } from 'common';
|
import { ClientLogger as Logger, ClientIPC } from 'common';
|
||||||
|
@ -22,6 +22,7 @@ class BetterDiscord {
|
||||||
window.events = Events;
|
window.events = Events;
|
||||||
window.wpm = WebpackModules;
|
window.wpm = WebpackModules;
|
||||||
window.bdsettings = Settings;
|
window.bdsettings = Settings;
|
||||||
|
window.bdmodals = Modals;
|
||||||
DOM.injectStyle(BdCss, 'bdmain');
|
DOM.injectStyle(BdCss, 'bdmain');
|
||||||
Events.on('global-ready', this.globalReady.bind(this));
|
Events.on('global-ready', this.globalReady.bind(this));
|
||||||
}
|
}
|
||||||
|
@ -29,8 +30,9 @@ class BetterDiscord {
|
||||||
async init() {
|
async init() {
|
||||||
await Settings.loadSettings();
|
await Settings.loadSettings();
|
||||||
await ModuleManager.initModules();
|
await ModuleManager.initModules();
|
||||||
await PluginManager.loadAllPlugins();
|
await PluginManager.loadAllPlugins(true);
|
||||||
await ThemeManager.loadAllThemes();
|
await ThemeManager.loadAllThemes(true);
|
||||||
|
Modals.showContentManagerErrors();
|
||||||
Events.emit('ready');
|
Events.emit('ready');
|
||||||
Events.emit('discord-ready');
|
Events.emit('discord-ready');
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { FileUtils, ClientLogger as Logger } from 'common';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { Events } from 'modules';
|
import { Events } from 'modules';
|
||||||
import { Error } from 'structs';
|
import { Error } from 'structs';
|
||||||
|
import { Modals } from 'ui';
|
||||||
|
|
||||||
export default class {
|
export default class {
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ export default class {
|
||||||
return this._contentPath ? this._contentPath : (this._contentPath = Globals.getObject('paths').find(path => path.id === this.pathId).path);
|
return this._contentPath ? this._contentPath : (this._contentPath = Globals.getObject('paths').find(path => path.id === this.pathId).path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async loadAllContent() {
|
static async loadAllContent(supressErrors) {
|
||||||
try {
|
try {
|
||||||
await FileUtils.ensureDirectory(this.contentPath);
|
await FileUtils.ensureDirectory(this.contentPath);
|
||||||
const directories = await FileUtils.listDirectory(this.contentPath);
|
const directories = await FileUtils.listDirectory(this.contentPath);
|
||||||
|
@ -47,15 +48,15 @@ export default class {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.errors.length) {
|
if (this.errors.length && !supressErrors) {
|
||||||
Events.emit('bd-error', {
|
Modals.error({
|
||||||
header: `${this.moduleName} - one or more ${this.contentType}(s) failed to load`,
|
header: `${this.moduleName} - ${this.errors.length} ${this.contentType}${this.errors.length !== 1 ? 's' : ''} failed to load`,
|
||||||
module: this.moduleName,
|
module: this.moduleName,
|
||||||
type: 'err',
|
type: 'err',
|
||||||
content: this.errors
|
content: this.errors
|
||||||
});
|
});
|
||||||
|
this._errors = [];
|
||||||
}
|
}
|
||||||
this._errors = [];
|
|
||||||
|
|
||||||
return this.localContent;
|
return this.localContent;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { FileUtils } from 'common';
|
import { FileUtils } from 'common';
|
||||||
|
import { Modals } from 'ui';
|
||||||
|
|
||||||
export default class {
|
export default class {
|
||||||
|
|
||||||
|
@ -48,6 +49,10 @@ export default class {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showSettingsModal() {
|
||||||
|
return Modals.pluginSettings(this);
|
||||||
|
}
|
||||||
|
|
||||||
async saveSettings(newSettings) {
|
async saveSettings(newSettings) {
|
||||||
for (let category of newSettings) {
|
for (let category of newSettings) {
|
||||||
const oldCategory = this.pluginConfig.find(c => c.category === category.category);
|
const oldCategory = this.pluginConfig.find(c => c.category === category.category);
|
||||||
|
|
|
@ -52,15 +52,15 @@ export default class extends ContentManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
static get moduleName() {
|
static get moduleName() {
|
||||||
return 'PluginManager';
|
return 'Plugin Manager';
|
||||||
}
|
}
|
||||||
|
|
||||||
static get pathId() {
|
static get pathId() {
|
||||||
return 'plugins';
|
return 'plugins';
|
||||||
}
|
}
|
||||||
|
|
||||||
static async loadAllPlugins() {
|
static async loadAllPlugins(supressErrors) {
|
||||||
const loadAll = await this.loadAllContent();
|
const loadAll = await this.loadAllContent(supressErrors);
|
||||||
this.localPlugins.forEach(plugin => {
|
this.localPlugins.forEach(plugin => {
|
||||||
if (plugin.type === 'module') return;
|
if (plugin.type === 'module') return;
|
||||||
if (plugin.enabled) plugin.start();
|
if (plugin.enabled) plugin.start();
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ContentManager from './contentmanager';
|
import ContentManager from './contentmanager';
|
||||||
import { DOM } from 'ui';
|
import { DOM, Modals } from 'ui';
|
||||||
import { FileUtils, ClientIPC } from 'common';
|
import { FileUtils, ClientIPC } from 'common';
|
||||||
|
|
||||||
class Theme {
|
class Theme {
|
||||||
|
@ -39,6 +39,10 @@ class Theme {
|
||||||
get css() { return this.userConfig.css }
|
get css() { return this.userConfig.css }
|
||||||
get id() { return this.name.toLowerCase().replace(/\s+/g, '-') }
|
get id() { return this.name.toLowerCase().replace(/\s+/g, '-') }
|
||||||
|
|
||||||
|
showSettingsModal() {
|
||||||
|
return Modals.themeSettings(this);
|
||||||
|
}
|
||||||
|
|
||||||
async saveSettings(newSettings) {
|
async saveSettings(newSettings) {
|
||||||
for (let category of newSettings) {
|
for (let category of newSettings) {
|
||||||
const oldCategory = this.themeConfig.find(c => c.category === category.category);
|
const oldCategory = this.themeConfig.find(c => c.category === category.category);
|
||||||
|
@ -132,6 +136,14 @@ export default class ThemeManager extends ContentManager {
|
||||||
return this.localContent;
|
return this.localContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get contentType() {
|
||||||
|
return 'theme';
|
||||||
|
}
|
||||||
|
|
||||||
|
static get moduleName() {
|
||||||
|
return 'Theme Manager';
|
||||||
|
}
|
||||||
|
|
||||||
static get pathId() {
|
static get pathId() {
|
||||||
return 'themes';
|
return 'themes';
|
||||||
}
|
}
|
||||||
|
@ -195,11 +207,11 @@ export default class ThemeManager extends ContentManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === 'boolean' || typeof value === 'number') {
|
if (typeof value === 'boolean' || typeof value === 'number') {
|
||||||
return `$${name}: ${value};`;
|
return `$${name}: ${value};`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
return `$${name}: ${setting.scss_raw ? value : `'${setting.value.replace(/\\/g, '\\\\').replace(/'/g, '\\\'')}'`};`;
|
return `$${name}: ${setting.scss_raw ? value : `'${setting.value.replace(/\\/g, '\\\\').replace(/'/g, '\\\'')}'`};`;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
background-position: center;
|
background-position: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: 3000;
|
z-index: 3001;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
filter: grayscale(100%);
|
filter: grayscale(100%);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
background: transparent;
|
background: transparent;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
z-index: 90000;
|
z-index: 3001;
|
||||||
|
|
||||||
.bd-settings-button-btn {
|
.bd-settings-button-btn {
|
||||||
background-image: $logoBigBw;
|
background-image: $logoBigBw;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
.bd-plugin-settings-body {
|
.bd-plugin-settings-body {
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
|
margin: 0 0 74px;
|
||||||
|
|
||||||
.bd-switch-wrapper {
|
.bd-switch-wrapper {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
|
@ -22,4 +23,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.bd-edited {
|
||||||
|
.bd-scroller::-webkit-scrollbar-track {
|
||||||
|
margin-bottom: 74px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
bdtooltips {
|
bd-tooltips {
|
||||||
left: 0;
|
left: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 9000;
|
z-index: 9001;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bd-tooltip {
|
.bd-tooltip {
|
||||||
|
|
|
@ -4,5 +4,4 @@
|
||||||
@import './forms.scss';
|
@import './forms.scss';
|
||||||
@import './forms/index.scss';
|
@import './forms/index.scss';
|
||||||
@import './material-buttons.scss';
|
@import './material-buttons.scss';
|
||||||
@import './modals.scss';
|
|
||||||
@import './drawers.scss';
|
@import './drawers.scss';
|
||||||
|
|
|
@ -1,265 +0,0 @@
|
||||||
.bd-backdrop {
|
|
||||||
position: fixed;
|
|
||||||
right: 0px;
|
|
||||||
left: 0px;
|
|
||||||
top: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
background: #000;
|
|
||||||
opacity: .85;
|
|
||||||
padding: 20px;
|
|
||||||
z-index: 9000;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
animation: bd-backdrop-in 0.22s ease;
|
|
||||||
&.bd-backdrop-out {
|
|
||||||
animation: bd-backdrop-out 0.22s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-modal {
|
|
||||||
position: fixed;
|
|
||||||
align-content: space-around;
|
|
||||||
display: flex;
|
|
||||||
border-radius: 8px;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
user-select: none;
|
|
||||||
padding: 60px;
|
|
||||||
transform: scale(1) translateZ(0px);
|
|
||||||
-webkit-box-direction: normal;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 9001;
|
|
||||||
justify-content: center;
|
|
||||||
animation: bd-modal-in 0.22s ease;
|
|
||||||
|
|
||||||
&.bd-modal-out {
|
|
||||||
animation: bd-modal-out 0.22s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-modal-header .bd-modal-icon .bd-material-design-icon {
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bd-err {
|
|
||||||
.bd-modal-header .bd-modal-icon svg {
|
|
||||||
fill: $colerr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-modal-body .bd-scroller-wrap .bd-scroller {
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-modal-controls {
|
|
||||||
display: flex;
|
|
||||||
padding: 15px;
|
|
||||||
border-top: 1px solid #4a4a4a;
|
|
||||||
|
|
||||||
.bd-modal-tip {
|
|
||||||
flex-grow: 1;
|
|
||||||
line-height: 26px;
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-button {
|
|
||||||
padding: 5px 10px;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-modal .bd-modal-inner {
|
|
||||||
background: #36393e;
|
|
||||||
contain: layout;
|
|
||||||
flex-direction: column;
|
|
||||||
pointer-events: auto;
|
|
||||||
-webkit-box-direction: normal;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
display: -webkit-box;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
flex-grow: 1;
|
|
||||||
border-radius: 4px;
|
|
||||||
max-height: 100%;
|
|
||||||
max-width: 500px;
|
|
||||||
width: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-modal .bd-modal-body {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-modal {
|
|
||||||
.bd-modal-header {
|
|
||||||
display: flex;
|
|
||||||
padding: 15px;
|
|
||||||
flex: 0 0;
|
|
||||||
-webkit-transition: -webkit-box-shadow .1s ease-out;
|
|
||||||
transition: -webkit-box-shadow .1s ease-out;
|
|
||||||
transition: box-shadow .1s ease-out;
|
|
||||||
|
|
||||||
.bd-modal-headertext {
|
|
||||||
color: #FFF;
|
|
||||||
font-weight: 700;
|
|
||||||
flex-grow: 1;
|
|
||||||
line-height: 18px;
|
|
||||||
padding: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-modal-x {
|
|
||||||
display: flex;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border-radius: 3px;
|
|
||||||
cursor: pointer;
|
|
||||||
align-content: center;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
margin-left: -2px -2px -2px 10px;
|
|
||||||
padding: 2px;
|
|
||||||
|
|
||||||
.bd-material-design-icon {
|
|
||||||
fill: #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: #2d2f34;
|
|
||||||
|
|
||||||
.bd-material-design-icon {
|
|
||||||
fill: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bd-modal-scrolled .bd-modal-header {
|
|
||||||
-webkit-box-shadow: 0 1px 0 0 rgba(24,25,28,.3), 0 1px 2px 0 rgba(24,25,28,.3);
|
|
||||||
box-shadow: 0 1px 0 0 rgba(24,25,28,.3), 0 1px 2px 0 rgba(24,25,28,.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-modal-body {
|
|
||||||
padding: 0 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-modal-footer {
|
|
||||||
.bd-footer-alert {
|
|
||||||
margin: 10px;
|
|
||||||
height: 0;
|
|
||||||
display: flex;
|
|
||||||
background-color: rgba(32, 34, 37, 0.9);
|
|
||||||
box-shadow: 0 2px 10px 0 rgba(0,0,0,.2);
|
|
||||||
padding: 10px 10px 10px 16px;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 5px;
|
|
||||||
transform: translateY(100%);
|
|
||||||
opacity: 0;
|
|
||||||
transition: all .2s ease-in-out;
|
|
||||||
|
|
||||||
&.bd-warn {
|
|
||||||
background-color: $colerr;
|
|
||||||
animation: bd-warn-shake 0.4s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bd-active {
|
|
||||||
height: auto;
|
|
||||||
opacity: 1;
|
|
||||||
transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-footer-alert-text {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
color: #FFF;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 34px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bd-button {
|
|
||||||
height: 30px;
|
|
||||||
border-radius: 3px;
|
|
||||||
padding: 2px 16px;
|
|
||||||
|
|
||||||
&.bd-tp {
|
|
||||||
background: transparent;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
user-select: all;
|
|
||||||
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%);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,6 +6,7 @@
|
||||||
@import './sidebarview/index.scss';
|
@import './sidebarview/index.scss';
|
||||||
@import './bdsettings/index.scss';
|
@import './bdsettings/index.scss';
|
||||||
@import './generic/index.scss';
|
@import './generic/index.scss';
|
||||||
|
@import './modals/index.scss';
|
||||||
@import './profilebadges.scss';
|
@import './profilebadges.scss';
|
||||||
|
|
||||||
@import './discordoverrides.scss';
|
@import './discordoverrides.scss';
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
.bd-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
right: 0px;
|
||||||
|
left: 0px;
|
||||||
|
top: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
background: #000;
|
||||||
|
opacity: .85;
|
||||||
|
padding: 20px;
|
||||||
|
z-index: 9000;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
animation: bd-backdrop-in 0.22s ease;
|
||||||
|
&.bd-backdrop-out {
|
||||||
|
animation: bd-backdrop-out 0.22s ease;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
.bd-modal-basic {
|
||||||
|
.bd-modal-basic-body {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
.bd-modal.bd-err {
|
||||||
|
.bd-modal-header .bd-modal-icon svg {
|
||||||
|
fill: $colerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-modal-body {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
min-height: 70px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
user-select: all;
|
||||||
|
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;
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
.bd-modal-footer {
|
||||||
|
.bd-footer-alert {
|
||||||
|
margin: -64px 10px 10px;
|
||||||
|
height: 0;
|
||||||
|
display: flex;
|
||||||
|
background-color: rgba(32, 34, 37, 0.9);
|
||||||
|
box-shadow: 0 2px 10px 0 rgba(0,0,0,.2);
|
||||||
|
padding: 10px 10px 10px 16px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 5px;
|
||||||
|
transform: translateY(100%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: all .2s ease-in-out;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&.bd-warn {
|
||||||
|
background-color: $colerr;
|
||||||
|
animation: bd-warn-shake 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bd-active {
|
||||||
|
height: auto;
|
||||||
|
opacity: 1;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-footer-alert-text {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-button {
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 2px 16px;
|
||||||
|
|
||||||
|
&.bd-tp {
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
.bd-modal-header {
|
||||||
|
display: flex;
|
||||||
|
padding: 15px;
|
||||||
|
flex: 0 0;
|
||||||
|
-webkit-transition: -webkit-box-shadow .1s ease-out;
|
||||||
|
transition: -webkit-box-shadow .1s ease-out;
|
||||||
|
transition: box-shadow .1s ease-out;
|
||||||
|
|
||||||
|
.bd-modal-headertext {
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 700;
|
||||||
|
flex-grow: 1;
|
||||||
|
line-height: 18px;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-modal-icon .bd-material-design-icon {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-modal-x {
|
||||||
|
display: flex;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: -2px -2px -2px 10px;
|
||||||
|
padding: 2px;
|
||||||
|
|
||||||
|
.bd-material-design-icon {
|
||||||
|
fill: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #2d2f34;
|
||||||
|
|
||||||
|
.bd-material-design-icon {
|
||||||
|
fill: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-modal-scrolled .bd-modal-header {
|
||||||
|
-webkit-box-shadow: 0 1px 0 0 rgba(24,25,28,.3), 0 1px 2px 0 rgba(24,25,28,.3);
|
||||||
|
box-shadow: 0 1px 0 0 rgba(24,25,28,.3), 0 1px 2px 0 rgba(24,25,28,.3);
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
@import './backdrop.scss';
|
||||||
|
@import './modals.scss';
|
||||||
|
@import './header.scss';
|
||||||
|
@import './footer-alert.scss';
|
||||||
|
|
||||||
|
@import './basic-modal.scss';
|
||||||
|
@import './error-modal.scss';
|
|
@ -0,0 +1,96 @@
|
||||||
|
.bd-modal-wrap {
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 9000;
|
||||||
|
|
||||||
|
.bd-modal-close-area {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-modal {
|
||||||
|
position: fixed;
|
||||||
|
align-content: space-around;
|
||||||
|
display: flex;
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
user-select: none;
|
||||||
|
padding: 60px;
|
||||||
|
transform: scale(1) translateZ(0px);
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 9001;
|
||||||
|
justify-content: center;
|
||||||
|
animation: bd-modal-in 0.22s ease;
|
||||||
|
|
||||||
|
&.bd-modal-out {
|
||||||
|
animation: bd-modal-out 0.22s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-modal-inner {
|
||||||
|
background: #36393e;
|
||||||
|
contain: layout;
|
||||||
|
flex-direction: column;
|
||||||
|
pointer-events: auto;
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
border-radius: 4px;
|
||||||
|
max-height: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-modal-body {
|
||||||
|
padding: 0 15px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.bd-scroller-wrap .bd-scroller {
|
||||||
|
color: #fff;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-modal-titlelink {
|
||||||
|
cursor: pointer;
|
||||||
|
color: $colbdblue;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: lighten($colbdblue, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-modal-controls {
|
||||||
|
display: flex;
|
||||||
|
padding: 15px;
|
||||||
|
border-top: 1px solid #4a4a4a;
|
||||||
|
|
||||||
|
.bd-modal-tip {
|
||||||
|
flex-grow: 1;
|
||||||
|
line-height: 26px;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-button {
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,9 +35,9 @@ export default class {
|
||||||
}
|
}
|
||||||
|
|
||||||
static injectUi() {
|
static injectUi() {
|
||||||
DOM.createElement('bdtooltips').appendTo(DOM.bdBody);
|
|
||||||
DOM.createElement('div', null, 'bd-settings').appendTo(DOM.bdBody);
|
DOM.createElement('div', null, 'bd-settings').appendTo(DOM.bdBody);
|
||||||
DOM.createElement('div', null, 'bd-modals').appendTo(DOM.bdModals);
|
DOM.createElement('div', null, 'bd-modals').appendTo(DOM.bdModals);
|
||||||
|
DOM.createElement('bd-tooltips').appendTo(DOM.bdBody);
|
||||||
|
|
||||||
const modals = new Vue({
|
const modals = new Vue({
|
||||||
el: '#bd-modals',
|
el: '#bd-modals',
|
||||||
|
|
|
@ -12,9 +12,6 @@
|
||||||
<div class="bd-settings" :class="{active: active}" @keyup="close">
|
<div class="bd-settings" :class="{active: active}" @keyup="close">
|
||||||
<SidebarView :contentVisible="this.activeIndex >= 0" :animating="this.animating" :class="{'bd-stop': !first}">
|
<SidebarView :contentVisible="this.activeIndex >= 0" :animating="this.animating" :class="{'bd-stop': !first}">
|
||||||
<Sidebar slot="sidebar">
|
<Sidebar slot="sidebar">
|
||||||
<div class="bd-settings-button bd-active">
|
|
||||||
<div class="bd-settings-button-btn"></div>
|
|
||||||
</div>
|
|
||||||
<div class="bd-settings-x" @click="close">
|
<div class="bd-settings-x" @click="close">
|
||||||
<MiClose size="17"/>
|
<MiClose size="17"/>
|
||||||
<span class="bd-x-text">ESC</span>
|
<span class="bd-x-text">ESC</span>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="bd-settings-wrapper" :class="[{active: active}, 'platform-' + this.platform]">
|
<div class="bd-settings-wrapper" :class="[{active: active}, 'platform-' + this.platform]">
|
||||||
<div class="bd-settings-button" @click="showSettings">
|
<div class="bd-settings-button" :class="{'bd-active': active}" @click="showSettings">
|
||||||
<div class="bd-settings-button-btn" :class="[{'bd-loading': !loaded}]"></div>
|
<div class="bd-settings-button-btn" :class="[{'bd-loading': !loaded}]"></div>
|
||||||
</div>
|
</div>
|
||||||
<BdSettings :active="active" :close="hideSettings" />
|
<BdSettings :active="active" :close="hideSettings" />
|
||||||
|
|
|
@ -8,66 +8,50 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="bd-modals-container">
|
<div class="bd-modals-container">
|
||||||
<div v-for="(modal, index) in modals" :key="`bd-modal-${index}`">
|
<div v-for="(modal, index) in modals.stack" :key="`bd-modal-${index}`">
|
||||||
<div v-if="index === 0" class="bd-backdrop" @click="closeModal(index)"></div>
|
<div class="bd-backdrop" :class="{'bd-backdrop-out': modal.closing}" :style="{opacity: index === 0 ? undefined : 0}"></div>
|
||||||
<div v-else :style="{opacity: 0}" class="bd-backdrop" @click="closeModal(index)"></div>
|
<div class="bd-modal-wrap" :style="{transform: `scale(${downscale(index + 1, 0.2)})`, opacity: downscale(index + 1, 1)}">
|
||||||
<Modal :headerText="modal.header"
|
<div class="bd-modal-close-area" @click="closeModal(modal)"></div>
|
||||||
:close="() => closeModal(index)"
|
<component :is="modal.component" />
|
||||||
:class="[{'bd-err': modal.type && modal.type === 'err'}, {'bd-modal-out': modal.closing}]">
|
</div>
|
||||||
<MiError v-if="modal.type === 'err'" slot="icon" size="20"/>
|
|
||||||
<div slot="body">
|
|
||||||
<div v-for="(content, index) in modal.content">
|
|
||||||
<ErrorModal v-if="content._type === 'err'" :content="content" :hideStack="hideStack" :showStack="showStack"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div slot="footer" class="bd-modal-controls">
|
|
||||||
<span class="bd-modal-tip">Ctrl+Shift+I for more details</span>
|
|
||||||
<div class="bd-button bd-ok" @click="closeModal(index)">
|
|
||||||
OK
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
// Imports
|
// Imports
|
||||||
import { Events } from 'modules';
|
import { Events } from 'modules';
|
||||||
|
import { Modals } from 'ui';
|
||||||
import { Modal } from '../common';
|
import { Modal } from '../common';
|
||||||
import { MiError } from '../common/MaterialIcon';
|
import { MiError } from '../common/MaterialIcon';
|
||||||
import ErrorModal from '../common/ErrorModal.vue';
|
import ErrorModal from './modals/ErrorModal.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
Modal, MiError
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
modals: []
|
modals: Modals,
|
||||||
}
|
eventListener: null
|
||||||
|
};
|
||||||
},
|
},
|
||||||
components: {
|
created() {
|
||||||
Modal, MiError, ErrorModal
|
console.log(this);
|
||||||
},
|
Events.on('bd-refresh-modals', this.eventListener = () => {
|
||||||
beforeMount() {
|
this.$forceUpdate();
|
||||||
Events.on('bd-error', e => {
|
|
||||||
e.closing = false;
|
|
||||||
this.modals.push(e);
|
|
||||||
console.log(this.modals);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
destroyed() {
|
||||||
|
if (this.eventListener) Events.off('bd-refresh-modals', this.eventListener);
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeModal(index) {
|
closeModal(modal) {
|
||||||
this.modals[index].closing = true;
|
modal.close();
|
||||||
setTimeout(() => {
|
|
||||||
this.modals.splice(index, 1);
|
|
||||||
}, 200);
|
|
||||||
},
|
},
|
||||||
showStack(error) {
|
downscale(index, times) {
|
||||||
error.showStack = true;
|
return 1 - ((this.modals.stack.filter(m => !m.closing).length - index) * times);
|
||||||
},
|
|
||||||
hideStack(error) {
|
|
||||||
error.showStack = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,28 +32,26 @@
|
||||||
<div class="bd-spinner-2"></div>
|
<div class="bd-spinner-2"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<PluginSettingsModal v-if="settingsOpen !== null" :plugin="settingsOpen" :close="closeSettings" />
|
|
||||||
</SettingsWrapper>
|
</SettingsWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Imports
|
// Imports
|
||||||
import { PluginManager } from 'modules';
|
import { PluginManager } from 'modules';
|
||||||
|
import { Modals } from 'ui';
|
||||||
import { SettingsWrapper } from './';
|
import { SettingsWrapper } from './';
|
||||||
import PluginCard from './PluginCard.vue';
|
import PluginCard from './PluginCard.vue';
|
||||||
import PluginSettingsModal from './PluginSettingsModal.vue';
|
|
||||||
import { MiRefresh } from '../common';
|
import { MiRefresh } from '../common';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
local: true,
|
local: true,
|
||||||
settingsOpen: null,
|
|
||||||
localPlugins: PluginManager.localPlugins
|
localPlugins: PluginManager.localPlugins
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
SettingsWrapper, PluginCard, PluginSettingsModal,
|
SettingsWrapper, PluginCard,
|
||||||
MiRefresh
|
MiRefresh
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -91,12 +89,8 @@
|
||||||
})();
|
})();
|
||||||
},
|
},
|
||||||
showSettings(plugin) {
|
showSettings(plugin) {
|
||||||
this.settingsOpen = plugin;
|
return Modals.pluginSettings(plugin);
|
||||||
},
|
|
||||||
closeSettings() {
|
|
||||||
this.settingsOpen = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -32,29 +32,26 @@
|
||||||
<div class="bd-spinner-2"></div>
|
<div class="bd-spinner-2"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ThemeSettingsModal v-if="settingsOpen !== null" :theme="settingsOpen" :close="closeSettings" />
|
|
||||||
</SettingsWrapper>
|
</SettingsWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Imports
|
// Imports
|
||||||
import { ThemeManager } from 'modules';
|
import { ThemeManager } from 'modules';
|
||||||
|
import { Modals } from 'ui';
|
||||||
import { SettingsWrapper } from './';
|
import { SettingsWrapper } from './';
|
||||||
import { MiRefresh } from '../common';
|
import { MiRefresh } from '../common';
|
||||||
import ThemeSettingsModal from './ThemeSettingsModal.vue';
|
|
||||||
import ThemeCard from './ThemeCard.vue';
|
import ThemeCard from './ThemeCard.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
local: true,
|
local: true,
|
||||||
settingsOpen: null,
|
|
||||||
localThemes: ThemeManager.localThemes
|
localThemes: ThemeManager.localThemes
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
SettingsWrapper, ThemeCard,
|
SettingsWrapper, ThemeCard,
|
||||||
ThemeSettingsModal,
|
|
||||||
MiRefresh
|
MiRefresh
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -92,12 +89,8 @@
|
||||||
})();
|
})();
|
||||||
},
|
},
|
||||||
showSettings(theme) {
|
showSettings(theme) {
|
||||||
this.settingsOpen = theme;
|
return Modals.themeSettings(theme);
|
||||||
},
|
|
||||||
closeSettings() {
|
|
||||||
this.settingsOpen = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* BetterDiscord Basic 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal :class="['bd-modal-basic', {'bd-modal-out': modal.closing}]" :headerText="modal.title" :close="modal.close">
|
||||||
|
<div slot="body" class="bd-modal-basic-body">{{ modal.text }}</div>
|
||||||
|
<div slot="footer" class="bd-modal-controls">
|
||||||
|
<div class="bd-flex-grow"></div>
|
||||||
|
<div class="bd-button bd-ok" @click="modal.close">OK</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Imports
|
||||||
|
import { Modal } from '../../common';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ['modal'],
|
||||||
|
components: {
|
||||||
|
Modal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<template>
|
||||||
|
<Modal :headerText="modal.event.header" :close="modal.close"
|
||||||
|
:class="[{'bd-err': modal.event.type && modal.event.type === 'err'}, {'bd-modal-out': modal.closing}]">
|
||||||
|
<MiError v-if="modal.event.type === 'err'" slot="icon" size="20"/>
|
||||||
|
<div slot="body">
|
||||||
|
<div v-for="(content, index) in modal.event.content">
|
||||||
|
<div v-if="content._type === 'err'" class="bd-modal-error" :class="{'bd-open': content.showStack}">
|
||||||
|
<div class="bd-modal-error-title bd-flex">
|
||||||
|
<span class="bd-modal-title-text bd-flex-grow">{{content.message}}</span>
|
||||||
|
<span class="bd-modal-titlelink" v-if="content.showStack" @click="() => { content.showStack = false; $forceUpdate(); }">Hide Stacktrace</span>
|
||||||
|
<span class="bd-modal-titlelink" v-else @click="() => { content.showStack = true; $forceUpdate(); }">Show Stacktrace</span>
|
||||||
|
</div>
|
||||||
|
<div class="bd-scroller-wrap">
|
||||||
|
<div class="bd-scroller">
|
||||||
|
<div class="bd-modal-error-body"><span>{{content.err.message}}</span>
|
||||||
|
{{content.stackTrace}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="bd-modal-controls">
|
||||||
|
<span class="bd-modal-tip">Press {{ platformInspectorKey }} for more details</span>
|
||||||
|
<div class="bd-button bd-ok" @click="modal.close">OK</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Imports
|
||||||
|
import { Modal } from '../../common';
|
||||||
|
import { MiError } from '../../common/MaterialIcon';
|
||||||
|
|
||||||
|
const process = window.require('process');
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ['modal'],
|
||||||
|
components: {
|
||||||
|
Modal, MiError
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
platformInspectorKey() {
|
||||||
|
return process.platform === 'darwin' ? 'Cmd+Option+I' : 'Ctrl+Shift+I';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -10,8 +10,7 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="bd-plugin-settings-modal" :class="{'bd-edited': changed}">
|
<div class="bd-plugin-settings-modal" :class="{'bd-edited': changed}">
|
||||||
<div class="bd-backdrop" @click="attemptToClose" :class="{'bd-backdrop-out': closing}"></div>
|
<Modal :headerText="plugin.name + ' Settings'" :close="attemptToClose" :class="{'bd-modal-out': modal.closing}">
|
||||||
<Modal :headerText="plugin.name + ' Settings'" :close="attemptToClose" :class="{'bd-modal-out': closing}">
|
|
||||||
<SettingsPanel :settings="configCache" :change="settingChange" slot="body" class="bd-plugin-settings-body" />
|
<SettingsPanel :settings="configCache" :change="settingChange" slot="body" class="bd-plugin-settings-body" />
|
||||||
<div slot="footer" class="bd-footer-alert" :class ="{'bd-active': changed, 'bd-warn': warnclose}">
|
<div slot="footer" class="bd-footer-alert" :class ="{'bd-active': changed, 'bd-warn': warnclose}">
|
||||||
<div class="bd-footer-alert-text">Unsaved changes</div>
|
<div class="bd-footer-alert-text">Unsaved changes</div>
|
||||||
|
@ -27,11 +26,11 @@
|
||||||
<script>
|
<script>
|
||||||
// Imports
|
// Imports
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { Modal } from '../common';
|
import { Modal } from '../../common';
|
||||||
import SettingsPanel from './SettingsPanel.vue';
|
import SettingsPanel from '../SettingsPanel.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['plugin','close'],
|
props: ['modal'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
changed: false,
|
changed: false,
|
||||||
|
@ -43,7 +42,10 @@
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Modal,
|
Modal,
|
||||||
SettingsPanel,
|
SettingsPanel
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
plugin() { return this.modal.plugin; }
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkForChanges() {
|
checkForChanges() {
|
||||||
|
@ -96,7 +98,7 @@
|
||||||
if (!this.changed) {
|
if (!this.changed) {
|
||||||
this.closing = true;
|
this.closing = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.close();
|
this.modal.close();
|
||||||
}, 200);
|
}, 200);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
|
@ -10,8 +10,7 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="bd-plugin-settings-modal" :class="{'bd-edited': changed}">
|
<div class="bd-plugin-settings-modal" :class="{'bd-edited': changed}">
|
||||||
<div class="bd-backdrop" @click="attemptToClose" :class="{'bd-backdrop-out': closing}"></div>
|
<Modal :headerText="theme.name + ' Settings'" :close="attemptToClose" :class="{'bd-modal-out': modal.closing}">
|
||||||
<Modal :headerText="theme.name + ' Settings'" :close="attemptToClose" :class="{'bd-modal-out': closing}">
|
|
||||||
<SettingsPanel :settings="configCache" :change="settingChange" slot="body" class="bd-plugin-settings-body" />
|
<SettingsPanel :settings="configCache" :change="settingChange" slot="body" class="bd-plugin-settings-body" />
|
||||||
<div slot="footer" class="bd-footer-alert" :class ="{'bd-active': changed, 'bd-warn': warnclose}">
|
<div slot="footer" class="bd-footer-alert" :class ="{'bd-active': changed, 'bd-warn': warnclose}">
|
||||||
<div class="bd-footer-alert-text">Unsaved changes</div>
|
<div class="bd-footer-alert-text">Unsaved changes</div>
|
||||||
|
@ -27,11 +26,11 @@
|
||||||
<script>
|
<script>
|
||||||
// Imports
|
// Imports
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { Modal } from '../common';
|
import { Modal } from '../../common';
|
||||||
import SettingsPanel from './SettingsPanel.vue';
|
import SettingsPanel from '../SettingsPanel.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ['theme', 'close'],
|
props: ['modal'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
changed: false,
|
changed: false,
|
||||||
|
@ -45,6 +44,9 @@
|
||||||
Modal,
|
Modal,
|
||||||
SettingsPanel
|
SettingsPanel
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
theme() { return this.modal.theme; }
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkForChanges() {
|
checkForChanges() {
|
||||||
let changed = false;
|
let changed = false;
|
||||||
|
@ -96,7 +98,7 @@
|
||||||
if (!this.changed) {
|
if (!this.changed) {
|
||||||
this.closing = true;
|
this.closing = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.close();
|
this.modal.close();
|
||||||
}, 200);
|
}, 200);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/**
|
||||||
|
* BetterDiscord Modals
|
||||||
|
* 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 } from 'common';
|
||||||
|
import { Events, PluginManager, ThemeManager } from 'modules';
|
||||||
|
import BasicModal from './components/bd/modals/BasicModal.vue';
|
||||||
|
import ErrorModal from './components/bd/modals/ErrorModal.vue';
|
||||||
|
import PluginSettingsModal from './components/bd/modals/PluginSettingsModal.vue';
|
||||||
|
import ThemeSettingsModal from './components/bd/modals/ThemeSettingsModal.vue';
|
||||||
|
|
||||||
|
export default class {
|
||||||
|
|
||||||
|
static add(modal, component) {
|
||||||
|
modal.component = modal.component || {
|
||||||
|
template: '<custom-modal :modal="modal" />',
|
||||||
|
components: { 'custom-modal': component },
|
||||||
|
data() { return { modal }; },
|
||||||
|
created() { modal.vue = this; }
|
||||||
|
};
|
||||||
|
modal.closing = false;
|
||||||
|
modal.close = () => this.close(modal);
|
||||||
|
|
||||||
|
this.stack.push(modal);
|
||||||
|
Events.emit('bd-refresh-modals');
|
||||||
|
return modal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static close(modal) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
modal.closing = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
this._stack = this.stack.filter(m => m !== modal);
|
||||||
|
Events.emit('bd-refresh-modals');
|
||||||
|
resolve();
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static closeAll() {
|
||||||
|
for (let modal of this.stack)
|
||||||
|
modal.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static closeLast() {
|
||||||
|
if (!this.stack.length) return;
|
||||||
|
this.stack[this.stack.length - 1].close();
|
||||||
|
}
|
||||||
|
|
||||||
|
static basic(title, text) {
|
||||||
|
return this.add({ title, text }, BasicModal);
|
||||||
|
}
|
||||||
|
|
||||||
|
static error(event) {
|
||||||
|
return this.add({ event }, ErrorModal);
|
||||||
|
}
|
||||||
|
|
||||||
|
static showContentManagerErrors() {
|
||||||
|
// Get any errors from PluginManager and ThemeManager
|
||||||
|
this.error({
|
||||||
|
header:
|
||||||
|
(PluginManager.errors.length && ThemeManager.errors.length ? '' :
|
||||||
|
(PluginManager.errors.length ? PluginManager.moduleName : ThemeManager.moduleName) + ' - ') +
|
||||||
|
(PluginManager.errors.length ? `${PluginManager.errors.length} ${PluginManager.contentType}${PluginManager.errors.length !== 1 ? 's' : ''}` : '') +
|
||||||
|
(PluginManager.errors.length && ThemeManager.errors.length ? ' and ' : '') +
|
||||||
|
(ThemeManager.errors.length ? `${ThemeManager.errors.length} ${ThemeManager.contentType}${ThemeManager.errors.length !== 1 ? 's' : ''}` : '') +
|
||||||
|
' failed to load',
|
||||||
|
module: (PluginManager.errors.length && ThemeManager.errors.length ? 'Content Manager' :
|
||||||
|
(PluginManager.errors.length ? PluginManager.moduleName : ThemeManager.moduleName)),
|
||||||
|
type: 'err',
|
||||||
|
content: ([]).concat(PluginManager.errors).concat(ThemeManager.errors)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static pluginSettings(plugin) {
|
||||||
|
return this.add({ plugin }, PluginSettingsModal);
|
||||||
|
}
|
||||||
|
|
||||||
|
static themeSettings(theme) {
|
||||||
|
return this.add({ theme }, ThemeSettingsModal);
|
||||||
|
}
|
||||||
|
|
||||||
|
static get stack() {
|
||||||
|
return this._stack ? this._stack : (this._stack = []);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
export { default as DOM } from './dom';
|
export { default as DOM } from './dom';
|
||||||
export { default as BdUI } from './bdui';
|
export { default as BdUI } from './bdui';
|
||||||
export { default as VueInjector } from './vueinjector';
|
export { default as VueInjector } from './vueinjector';
|
||||||
|
export { default as Modals } from './modals';
|
||||||
export { default as ProfileBadges } from './profilebadges';
|
export { default as ProfileBadges } from './profilebadges';
|
||||||
|
|
|
@ -13,7 +13,7 @@ import Vue from 'vue';
|
||||||
import VTooltip from 'v-tooltip';
|
import VTooltip from 'v-tooltip';
|
||||||
|
|
||||||
Vue.use(VTooltip, {
|
Vue.use(VTooltip, {
|
||||||
defaultContainer: 'bdtooltips',
|
defaultContainer: 'bd-tooltips',
|
||||||
defaultClass: 'bd-tooltip',
|
defaultClass: 'bd-tooltip',
|
||||||
defaultTargetClass: 'bd-has-tooltip',
|
defaultTargetClass: 'bd-has-tooltip',
|
||||||
defaultInnerSelector: '.bd-tooltip-inner',
|
defaultInnerSelector: '.bd-tooltip-inner',
|
||||||
|
|
|
@ -17,6 +17,7 @@ module.exports = (Plugin, Api, Vendor) => {
|
||||||
onStop() {
|
onStop() {
|
||||||
Events.unsubscribeAll();
|
Events.unsubscribeAll();
|
||||||
Logger.log('onStop');
|
Logger.log('onStop');
|
||||||
|
console.log(this.showSettingsModal());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue