Add modal manager
This commit is contained in:
parent
cbc727f951
commit
64ac3677b1
|
@ -13,6 +13,7 @@ import { FileUtils, ClientLogger as Logger } from 'common';
|
|||
import path from 'path';
|
||||
import { Events } from 'modules';
|
||||
import { Error } from 'structs';
|
||||
import { Modals } from 'ui';
|
||||
|
||||
export default class {
|
||||
|
||||
|
@ -48,8 +49,8 @@ export default class {
|
|||
}
|
||||
|
||||
if (this.errors.length) {
|
||||
Events.emit('bd-error', {
|
||||
header: `${this.moduleName} - one or more ${this.contentType}(s) failed to load`,
|
||||
Modals.error({
|
||||
header: `${this.moduleName} - ${this.errors.length} ${this.contentType}${this.errors.length !== 1 ? 's' : ''} failed to load`,
|
||||
module: this.moduleName,
|
||||
type: 'err',
|
||||
content: this.errors
|
||||
|
|
|
@ -16,6 +16,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
|
|
|
@ -8,66 +8,50 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
|
||||
<template>
|
||||
<div class="bd-modals-container">
|
||||
<div v-for="(modal, index) in modals" :key="`bd-modal-${index}`">
|
||||
<div v-if="index === 0" class="bd-backdrop" @click="closeModal(index)"></div>
|
||||
<div v-else :style="{opacity: 0}" class="bd-backdrop" @click="closeModal(index)"></div>
|
||||
<Modal :headerText="modal.header"
|
||||
:close="() => closeModal(index)"
|
||||
:class="[{'bd-err': modal.type && modal.type === 'err'}, {'bd-modal-out': modal.closing}]">
|
||||
<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 v-for="(modal, index) in modals.stack" :key="`bd-modal-${index}`">
|
||||
<div class="bd-backdrop" :class="{'bd-backdrop-out': modal.closing}" :style="{opacity: index === 0 ? undefined : 0}"></div>
|
||||
<div class="bd-modal-wrap" :style="{transform: `scale(${downscale(index + 1)})`, opacity: downscale(index + 1)}">
|
||||
<div class="bd-modal-close-area" @click="closeModal(modal)"></div>
|
||||
<component :is="modal.component" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
// Imports
|
||||
import { Events } from 'modules';
|
||||
import { Modals } from 'ui';
|
||||
import { Modal } from '../common';
|
||||
import { MiError } from '../common/MaterialIcon';
|
||||
import ErrorModal from '../common/ErrorModal.vue';
|
||||
import ErrorModal from './modals/ErrorModal.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Modal, MiError
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
modals: []
|
||||
}
|
||||
modals: Modals,
|
||||
eventListener: null
|
||||
};
|
||||
},
|
||||
components: {
|
||||
Modal, MiError, ErrorModal
|
||||
},
|
||||
beforeMount() {
|
||||
Events.on('bd-error', e => {
|
||||
e.closing = false;
|
||||
this.modals.push(e);
|
||||
console.log(this.modals);
|
||||
created() {
|
||||
console.log(this);
|
||||
Events.on('bd-refresh-modals', this.eventListener = () => {
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
destroyed() {
|
||||
if (this.eventListener) Events.off('bd-refresh-modals', this.eventListener);
|
||||
},
|
||||
methods: {
|
||||
closeModal(index) {
|
||||
this.modals[index].closing = true;
|
||||
setTimeout(() => {
|
||||
this.modals.splice(index, 1);
|
||||
}, 200);
|
||||
closeModal(modal) {
|
||||
modal.close();
|
||||
},
|
||||
showStack(error) {
|
||||
error.showStack = true;
|
||||
},
|
||||
hideStack(error) {
|
||||
error.showStack = false;
|
||||
downscale(index) {
|
||||
return 1 - ((this.modals.stack.filter(m => !m.closing).length - index) * 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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-out': modal.closing}" :headerText="modal.title" :close="modal.close">
|
||||
<div slot="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>
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* 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 } from 'modules';
|
||||
import BasicModal from './components/bd/modals/BasicModal.vue';
|
||||
import ErrorModal from './components/bd/modals/ErrorModal.vue';
|
||||
|
||||
export default class Modals {
|
||||
|
||||
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 get stack() {
|
||||
return this._stack ? this._stack : (this._stack = []);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
export { default as DOM } from './dom';
|
||||
export { default as BdUI } from './bdui';
|
||||
export { default as VueInjector } from './vueinjector';
|
||||
export { default as Modals } from './modals';
|
||||
export { default as ProfileBadges } from './profilebadges';
|
||||
|
|
Loading…
Reference in New Issue