Merge pull request #141 from samuelthomas2774/tabs-and-settings-arrays
Tabs and settings arrays
This commit is contained in:
commit
99e9ce3852
|
@ -135,7 +135,7 @@ export default class Theme {
|
|||
let css = '';
|
||||
if (this.info.type === 'sass') {
|
||||
css = await ClientIPC.send('bd-compileSass', {
|
||||
data: ThemeManager.getConfigAsSCSS(this.config),
|
||||
data: await ThemeManager.getConfigAsSCSS(this.config),
|
||||
path: this.paths.mainPath.replace(/\\/g, '/')
|
||||
});
|
||||
console.log(css);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
import ContentManager from './contentmanager';
|
||||
import Theme from './theme';
|
||||
import { FileUtils } from 'common';
|
||||
|
||||
export default class ThemeManager extends ContentManager {
|
||||
|
||||
|
@ -64,36 +65,97 @@ export default class ThemeManager extends ContentManager {
|
|||
theme.recompile();
|
||||
}
|
||||
|
||||
static getConfigAsSCSS(config) {
|
||||
static async getConfigAsSCSS(config) {
|
||||
const variables = [];
|
||||
|
||||
for (let category of config) {
|
||||
for (let setting of category.settings) {
|
||||
variables.push(this.parseSetting(setting));
|
||||
const setting_scss = await this.parseSetting(setting);
|
||||
if (setting_scss) variables.push(`$${setting_scss[0]}: ${setting_scss[1]};`);
|
||||
}
|
||||
}
|
||||
|
||||
return variables.join('\n');
|
||||
}
|
||||
|
||||
static parseSetting(setting) {
|
||||
static async getConfigAsSCSSMap(config) {
|
||||
const variables = [];
|
||||
|
||||
for (let category of config) {
|
||||
for (let setting of category.settings) {
|
||||
const setting_scss = await this.parseSetting(setting);
|
||||
if (setting_scss) variables.push(`${setting_scss[0]}: (${setting_scss[1]})`);
|
||||
}
|
||||
}
|
||||
|
||||
return '(' + variables.join(', ') + ')';
|
||||
}
|
||||
|
||||
static async parseSetting(setting) {
|
||||
const { type, id, value } = setting;
|
||||
const name = id.replace(/[^a-zA-Z0-9-]/g, '-').replace(/--/g, '-');
|
||||
|
||||
if (type === 'array') {
|
||||
const items = JSON.parse(JSON.stringify(value)) || [];
|
||||
const settings_json = JSON.stringify(setting.settings);
|
||||
|
||||
for (let item of items) {
|
||||
const settings = JSON.parse(settings_json);
|
||||
|
||||
for (let category of settings) {
|
||||
const newCategory = item.settings.find(c => c.category === category.category);
|
||||
for (let setting of category.settings) {
|
||||
const newSetting = newCategory.settings.find(s => s.id === setting.id);
|
||||
setting.value = setting.old_value = newSetting.value;
|
||||
setting.changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
item.settings = settings;
|
||||
}
|
||||
|
||||
console.log('items', items);
|
||||
|
||||
// Final comma ensures the variable is a list
|
||||
const maps = [];
|
||||
for (let item of items)
|
||||
maps.push(await this.getConfigAsSCSSMap(item.settings));
|
||||
return [name, maps.length ? maps.join(', ') + ',' : '()'];
|
||||
}
|
||||
|
||||
if (type === 'file' && Array.isArray(value)) {
|
||||
if (!value || !value.length) return [name, '(),'];
|
||||
|
||||
const files = [];
|
||||
for (let filepath of value) {
|
||||
const buffer = await FileUtils.readFileBuffer(filepath);
|
||||
const type = await FileUtils.getFileType(buffer);
|
||||
files.push(`(data: ${this.toSCSSString(buffer.toString('base64'))}, type: ${this.toSCSSString(type.mime)}, url: ${this.toSCSSString(await FileUtils.toDataURI(buffer, type.mime))})`);
|
||||
}
|
||||
|
||||
return [name, files.length ? files.join(', ') : '()'];
|
||||
}
|
||||
|
||||
if (type === 'slider') {
|
||||
return `$${name}: ${value * setting.multi || 1};`;
|
||||
return [name, value * setting.multi || 1];
|
||||
}
|
||||
|
||||
if (type === 'dropdown' || type === 'radio') {
|
||||
return `$${name}: ${setting.options.find(opt => opt.id === value).value};`;
|
||||
return [name, setting.options.find(opt => opt.id === value).value];
|
||||
}
|
||||
|
||||
if (typeof value === 'boolean' || typeof value === 'number') {
|
||||
return `$${name}: ${value};`;
|
||||
return [name, value];
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return `$${name}: ${setting.scss_raw ? value : `'${setting.value.replace(/\\/g, '\\\\').replace(/'/g, '\\\'')}'`};`;
|
||||
return [name, this.toSCSSString(value)];
|
||||
}
|
||||
}
|
||||
|
||||
static toSCSSString(value) {
|
||||
if (typeof value !== 'string' && value.toString) value = value.toString();
|
||||
return `'${typeof value === 'string' ? value.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') : ''}'`;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,6 +46,12 @@
|
|||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.bd-settings-scheme-icon {
|
||||
border-color: lighten($coldimwhite, 20%);
|
||||
}
|
||||
}
|
||||
|
||||
&.bd-active {
|
||||
cursor: default;
|
||||
|
||||
|
|
|
@ -111,8 +111,7 @@
|
|||
.platform-darwin & {
|
||||
top: 0px;
|
||||
|
||||
.bd-sidebar-view .bd-sidebar-region,
|
||||
.bd-sidebar-view .bd-content-region {
|
||||
.bd-sidebar-view .bd-sidebar-region {
|
||||
padding-top: 22px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,50 +79,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bd-tabheader {
|
||||
.bd-button {
|
||||
background: transparent;
|
||||
border-bottom: 2px solid rgba(114, 118, 126, 0.3);
|
||||
|
||||
h3 {
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
display: block;
|
||||
font-size: 1.17em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
font-weight: bold;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.bd-material-button {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
|
||||
.material-design-icon,
|
||||
.bd-material-design-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
fill: #FFF;
|
||||
|
||||
svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #2d2f34;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.bd-active {
|
||||
background: transparent;
|
||||
border-bottom: 2px solid $colbdblue;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,14 +43,17 @@
|
|||
font-size: 12px;
|
||||
}
|
||||
|
||||
.bd-form-item-changed .bd-form-divider {
|
||||
background: $colok;
|
||||
}
|
||||
|
||||
|
||||
.bd-form-divider {
|
||||
height: 1px;
|
||||
margin: 15px 0;
|
||||
background: hsla(218,5%,47%,.3);
|
||||
transition: background-color 0.2s ease;
|
||||
|
||||
.bd-form-item-changed > & {
|
||||
background: $colok;
|
||||
}
|
||||
}
|
||||
|
||||
.bd-form-warning {
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
.bd-form-settingsarray {
|
||||
.bd-button.bd-button-primary {
|
||||
padding: 3px 8px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.bd-settingsarray-items {
|
||||
margin-top: 15px;
|
||||
|
||||
.bd-settingsarray-item {
|
||||
display: flex;
|
||||
margin-top: 10px;
|
||||
|
||||
.bd-settingsarray-item-marker {
|
||||
flex: 0 0 auto;
|
||||
min-width: 15px;
|
||||
margin-right: 5px;
|
||||
color: #aaa;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.bd-settingsarray-item-contents {
|
||||
flex: 1 1;
|
||||
}
|
||||
|
||||
.bd-settings-panel {
|
||||
.bd-settings-categories:last-child .bd-form-item:last-child .bd-form-divider {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.bd-settings-category:only-child > div > .bd-form-item.bd-form-item-noheader:only-child {
|
||||
.bd-form-textinput,
|
||||
.bd-form-numberinput {
|
||||
+ .bd-form-divider {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bd-settingsarray-item-hint {
|
||||
color: #aaa;
|
||||
font-size: 15px;
|
||||
font-style: italic;
|
||||
word-wrap: break-word;
|
||||
|
||||
max-width: 385px;
|
||||
}
|
||||
|
||||
.bd-settingsarray-item-controls {
|
||||
flex: 0 0 auto;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.bd-settingsarray-open,
|
||||
.bd-settingsarray-remove {
|
||||
margin-left: 5px;
|
||||
|
||||
svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
fill: #ccc;
|
||||
|
||||
&:hover {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child .bd-settings-categories:last-child .bd-form-item:last-child .bd-form-divider {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.bd-form-settingsarray-inline .bd-settingsarray-item {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,10 @@
|
|||
.bd-dropdown {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
h3 + & {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.bd-dropdown-current {
|
||||
color: #f6f6f7;
|
||||
|
@ -10,7 +15,6 @@
|
|||
cursor: default;
|
||||
outline: none;
|
||||
transition: border .15s ease;
|
||||
width: 180px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
@import './radios.scss';
|
||||
@import './sliders.scss';
|
||||
@import './switches.scss';
|
||||
@import './arrays.scss';
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
.bd-form-radio,
|
||||
.bd-form-numberinput,
|
||||
.bd-form-slider,
|
||||
.bd-setting-switch {
|
||||
.bd-setting-switch,
|
||||
.bd-form-settingsarray {
|
||||
.bd-title {
|
||||
display: flex;
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
.bd-radio-text {
|
||||
flex: 1 1 auto;
|
||||
color: white;
|
||||
word-wrap: break-word;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
.bd-form-textinput,
|
||||
.bd-form-numberinput {
|
||||
h3 {
|
||||
+ .bd-textinput-wrapper,
|
||||
+ .bd-textinput-wrapper input[type="text"],
|
||||
+ .bd-textinput-wrapper input[type="number"] {
|
||||
width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="number"] {
|
||||
background: transparent;
|
||||
|
@ -10,7 +18,7 @@
|
|||
line-height: 24px;
|
||||
font-size: 100%;
|
||||
font-weight: 500;
|
||||
width: 180px;
|
||||
width: 100%;
|
||||
|
||||
&:focus {
|
||||
color: #fff;
|
||||
|
@ -19,6 +27,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.bd-textinput-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bd-form-textarea {
|
||||
.bd-form-textarea-wrap {
|
||||
margin-top: 15px;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@import './spinners/index.scss';
|
||||
@import './scrollable.scss';
|
||||
@import './buttons.scss';
|
||||
@import './tabs.scss';
|
||||
@import './forms.scss';
|
||||
@import './forms/index.scss';
|
||||
@import './material-buttons.scss';
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding: 10px 10px 10px 0;
|
||||
margin: 10px 0;
|
||||
|
||||
@include scrollbar;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
.bd-tabbar {
|
||||
flex: 0 0 auto;
|
||||
margin-right: -15px;
|
||||
display: flex;
|
||||
|
||||
.bd-button {
|
||||
background: transparent;
|
||||
border-bottom: 2px solid rgba(114, 118, 126, 0.3);
|
||||
cursor: pointer;
|
||||
margin-right: 15px;
|
||||
padding: 15px 0;
|
||||
color: #87909c;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: color 0.2s ease, border-bottom-color 0.2s ease;
|
||||
flex: 0 0;
|
||||
display: flex;
|
||||
|
||||
h3 {
|
||||
flex: 0 0;
|
||||
}
|
||||
|
||||
.bd-material-button {
|
||||
margin: -1px 0 -1px 4px;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.bd-active {
|
||||
background: transparent;
|
||||
border-bottom-color: $colbdblue;
|
||||
color: #fff;
|
||||
|
||||
.bd-material-design-icon {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&.bd-active {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.bd-material-button-wrap {
|
||||
margin-right: 15px;
|
||||
flex: 0 0;
|
||||
padding: 17px 0 18px;
|
||||
|
||||
.bd-material-button {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.bd-button,
|
||||
.bd-material-button-wrap {
|
||||
.bd-material-button {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex: 0 0;
|
||||
cursor: pointer;
|
||||
|
||||
.material-design-icon,
|
||||
.bd-material-design-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
fill: #87909c;
|
||||
transition: fill 0.2s ease;
|
||||
|
||||
svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
|
||||
.bd-material-design-icon {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bd-settingswrap-header & {
|
||||
margin-top: -17px;
|
||||
margin-bottom: -20px;
|
||||
|
||||
.bd-button {
|
||||
font-size: 16px;
|
||||
padding: 18px 0 17px;
|
||||
}
|
||||
|
||||
.bd-material-button {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -85,12 +85,16 @@
|
|||
.bd-modal-tip {
|
||||
flex-grow: 1;
|
||||
line-height: 26px;
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.bd-button {
|
||||
padding: 5px 10px;
|
||||
border-radius: 3px;
|
||||
|
||||
+ .bd-button {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,28 +11,6 @@
|
|||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.bd-settingsWrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
|
||||
.bd-scroller-wrap {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.bd-settingsWrap-header {
|
||||
color: $colbdblue;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 100%;
|
||||
outline: 0;
|
||||
padding: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
||||
|
||||
> div:not(.active) {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
|
@ -50,8 +28,4 @@
|
|||
.animating {
|
||||
animation: bd-fade-out .4s forwards;
|
||||
}
|
||||
|
||||
.bd-settingsWrap {
|
||||
padding: 20px 15px 15px 15px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@import './main.scss';
|
||||
@import './sidebar.scss';
|
||||
@import './content.scss';
|
||||
@import './settingswrap.scss';
|
||||
|
|
|
@ -20,14 +20,8 @@
|
|||
max-width: 310px;
|
||||
min-width: 310px;
|
||||
|
||||
.bd-settingsWrap {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
-webkit-box-flex: 1;
|
||||
flex: 1;
|
||||
min-height: 1px;
|
||||
box-sizing: border-box;
|
||||
padding: 80px 15px 15px 15px;
|
||||
.bd-scroller {
|
||||
padding: 10px 10px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
.bd-sidebar-region {
|
||||
.bd-settingswrap {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
-webkit-box-flex: 1;
|
||||
flex: 1;
|
||||
min-height: 1px;
|
||||
box-sizing: border-box;
|
||||
padding: 90px 15px 0 15px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.bd-content-region {
|
||||
.bd-settingswrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
|
||||
> .bd-scroller-wrap {
|
||||
flex-grow: 1;
|
||||
|
||||
> .bd-scroller {
|
||||
overflow-y: scroll;
|
||||
|
||||
.platform-darwin .bd-settings & {
|
||||
padding-top: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bd-settingswrap-header {
|
||||
outline: 0;
|
||||
padding: 0;
|
||||
margin: 30px 20px 20px;
|
||||
vertical-align: baseline;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
|
||||
.bd-settingswrap-header-text {
|
||||
color: $colbdblue;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.bd-settingswrap-contents {
|
||||
padding: 0 20px;
|
||||
margin-bottom: 84px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,7 +44,7 @@
|
|||
}
|
||||
|
||||
&.active {
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
|
||||
<template>
|
||||
<div class="bd-modals-container">
|
||||
<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 v-for="(modal, index) in modals.stack" :key="`bd-modal-${modal.id}`">
|
||||
<div class="bd-backdrop" :class="{'bd-backdrop-out': closing}" :style="{opacity: index === 0 ? undefined : 0}"></div>
|
||||
<div class="bd-modal-wrap" :style="{transform: `scale(${downscale(index + 1, 0.2)})`, opacity: downscale(index + 1, 1)}">
|
||||
<div class="bd-modal-close-area" @click="closeModal(modal)"></div>
|
||||
<component :is="modal.component" />
|
||||
<keep-alive><component :is="modal.component" /></keep-alive>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -37,6 +37,11 @@
|
|||
eventListener: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
closing() {
|
||||
return !this.modals.stack.find(m => !m.closing);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
Events.on('bd-refresh-modals', this.eventListener = () => {
|
||||
this.$forceUpdate();
|
||||
|
|
|
@ -10,20 +10,12 @@
|
|||
|
||||
<template>
|
||||
<Card :item="plugin">
|
||||
<SettingSwitch v-if="plugin.type === 'plugin'" slot="toggle" :checked="plugin.enabled" :change="() => plugin.enabled ? plugin.stop() : plugin.start()" />
|
||||
<SettingSwitch v-if="plugin.type === 'plugin'" slot="toggle" :checked="plugin.enabled" :change="togglePlugin" />
|
||||
<ButtonGroup slot="controls">
|
||||
<Button v-tooltip="'Settings'" v-if="plugin.hasSettings" :onClick="() => showSettings(plugin)">
|
||||
<MiSettings size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Reload'" :onClick="() => reloadPlugin(plugin)">
|
||||
<MiRefresh size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Edit'" :onClick="editPlugin">
|
||||
<MiPencil size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Uninstall'" type="err">
|
||||
<MiDelete size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Settings'" v-if="plugin.hasSettings" :onClick="() => showSettings(plugin)"><MiSettings size="18" /></Button>
|
||||
<Button v-tooltip="'Reload'" :onClick="reloadPlugin"><MiRefresh size="18" /></Button>
|
||||
<Button v-tooltip="'Edit'" :onClick="editPlugin"><MiPencil size="18" /></Button>
|
||||
<Button v-tooltip="'Uninstall'" type="err"><MiDelete size="18" /></Button>
|
||||
</ButtonGroup>
|
||||
</Card>
|
||||
</template>
|
||||
|
@ -52,6 +44,5 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -10,23 +10,20 @@
|
|||
|
||||
<template>
|
||||
<SettingsWrapper headertext="Plugins">
|
||||
<div class="bd-flex bd-flex-col bd-pluginsView">
|
||||
<div class="bd-flex bd-tabheader">
|
||||
<div class="bd-flex-grow bd-button" :class="{'bd-active': local}" @click="showLocal">
|
||||
<h3>Local</h3>
|
||||
<div class="bd-material-button" @click="refreshLocal">
|
||||
<MiRefresh />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bd-flex-grow bd-button" :class="{'bd-active': !local}" @click="showOnline">
|
||||
<h3>Online</h3>
|
||||
<div class="bd-material-button">
|
||||
<MiRefresh />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bd-tabbar" slot="header">
|
||||
<div class="bd-button" :class="{'bd-active': local}" @click="showLocal">
|
||||
<h3>Local</h3>
|
||||
<div class="bd-material-button" v-if="local" @click="refreshLocal"><MiRefresh /></div>
|
||||
</div>
|
||||
<div class="bd-button" :class="{'bd-active': !local}" @click="showOnline">
|
||||
<h3>Online</h3>
|
||||
<div class="bd-material-button" v-if="!local" @click="refreshOnline"><MiRefresh /></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bd-flex bd-flex-col bd-pluginsView">
|
||||
<div v-if="local" class="bd-flex bd-flex-grow bd-flex-col bd-plugins-container bd-local-plugins">
|
||||
<PluginCard v-for="plugin in localPlugins" :plugin="plugin" :key="plugin.id" :togglePlugin="togglePlugin" :reloadPlugin="reloadPlugin" :showSettings="showSettings" />
|
||||
<PluginCard v-for="plugin in localPlugins" :plugin="plugin" :key="plugin.id" :togglePlugin="() => togglePlugin(plugin)" :reloadPlugin="() => reloadPlugin(plugin)" :showSettings="() => showSettings(plugin)" />
|
||||
</div>
|
||||
<div v-if="!local" class="bd-spinner-container">
|
||||
<div class="bd-spinner-2"></div>
|
||||
|
@ -61,32 +58,31 @@
|
|||
showOnline() {
|
||||
this.local = false;
|
||||
},
|
||||
refreshLocal() {
|
||||
(async () => {
|
||||
await PluginManager.refreshPlugins();
|
||||
})();
|
||||
async refreshLocal() {
|
||||
await PluginManager.refreshPlugins();
|
||||
},
|
||||
togglePlugin(plugin) {
|
||||
async refreshOnline() {
|
||||
|
||||
},
|
||||
async togglePlugin(plugin) {
|
||||
// TODO Display error if plugin fails to start/stop
|
||||
try {
|
||||
if (plugin.enabled) {
|
||||
PluginManager.stopPlugin(plugin);
|
||||
await PluginManager.stopPlugin(plugin);
|
||||
} else {
|
||||
PluginManager.startPlugin(plugin);
|
||||
await PluginManager.startPlugin(plugin);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
reloadPlugin(plugin) {
|
||||
(async () => {
|
||||
try {
|
||||
await PluginManager.reloadPlugin(plugin);
|
||||
this.$forceUpdate();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
})();
|
||||
async reloadPlugin(plugin) {
|
||||
try {
|
||||
await PluginManager.reloadPlugin(plugin);
|
||||
this.$forceUpdate();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
showSettings(plugin) {
|
||||
return Modals.contentSettings(plugin);
|
||||
|
|
|
@ -58,11 +58,6 @@
|
|||
Setting,
|
||||
Drawer
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active_scheme: 'scheme-1'
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
checkSchemeActive(scheme) {
|
||||
for (let schemeCategory of scheme.settings) {
|
||||
|
|
|
@ -9,10 +9,15 @@
|
|||
*/
|
||||
|
||||
<template>
|
||||
<div class="bd-settingsWrap">
|
||||
<div class="bd-settingsWrap-header">{{headertext}}</div>
|
||||
<div class="bd-settingswrap">
|
||||
<ScrollerWrap>
|
||||
<slot />
|
||||
<div class="bd-settingswrap-header">
|
||||
<span class="bd-settingswrap-header-text">{{ headertext }}</span>
|
||||
<slot name="header" />
|
||||
</div>
|
||||
<div class="bd-settingswrap-contents">
|
||||
<slot />
|
||||
</div>
|
||||
</ScrollerWrap>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -10,20 +10,12 @@
|
|||
|
||||
<template>
|
||||
<Card :item="theme">
|
||||
<SettingSwitch slot="toggle" :checked="theme.enabled" :change="() => theme.enabled ? theme.disable() : theme.enable()" />
|
||||
<SettingSwitch slot="toggle" :checked="theme.enabled" :change="toggleTheme" />
|
||||
<ButtonGroup slot="controls">
|
||||
<Button v-tooltip="'Settings'" v-if="theme.hasSettings" :onClick="() => showSettings(theme)">
|
||||
<MiSettings size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Reload'" :onClick="() => reloadTheme(theme)">
|
||||
<MiRefresh size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Edit'" :onClick="editTheme">
|
||||
<MiPencil size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Uninstall'" type="err">
|
||||
<MiDelete size="18" />
|
||||
</Button>
|
||||
<Button v-tooltip="'Settings'" v-if="theme.hasSettings" :onClick="showSettings"><MiSettings size="18" /></Button>
|
||||
<Button v-tooltip="'Reload'" :onClick="reloadTheme"><MiRefresh size="18" /></Button>
|
||||
<Button v-tooltip="'Edit'" :onClick="editTheme"><MiPencil size="18" /></Button>
|
||||
<Button v-tooltip="'Uninstall'" type="err"><MiDelete size="18" /></Button>
|
||||
</ButtonGroup>
|
||||
</Card>
|
||||
</template>
|
||||
|
@ -52,6 +44,5 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -10,23 +10,20 @@
|
|||
|
||||
<template>
|
||||
<SettingsWrapper headertext="Themes">
|
||||
<div class="bd-flex bd-flex-col bd-themesView">
|
||||
<div class="bd-flex bd-tabheader">
|
||||
<div class="bd-flex-grow bd-button" :class="{'bd-active': local}" @click="showLocal">
|
||||
<h3>Local</h3>
|
||||
<div class="bd-material-button" @click="refreshLocal">
|
||||
<MiRefresh />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bd-flex-grow bd-button" :class="{'bd-active': !local}" @click="showOnline">
|
||||
<h3>Online</h3>
|
||||
<div class="bd-material-button">
|
||||
<MiRefresh />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bd-tabbar" slot="header">
|
||||
<div class="bd-button" :class="{'bd-active': local}" @click="showLocal">
|
||||
<h3>Local</h3>
|
||||
<div class="bd-material-button" v-if="local" @click="refreshLocal"><MiRefresh /></div>
|
||||
</div>
|
||||
<div class="bd-button" :class="{'bd-active': !local}" @click="showOnline">
|
||||
<h3>Online</h3>
|
||||
<div class="bd-material-button" v-if="!local" @click="refreshOnline"><MiRefresh /></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bd-flex bd-flex-col bd-themesView">
|
||||
<div v-if="local" class="bd-flex bd-flex-grow bd-flex-col bd-themes-container bd-local-themes">
|
||||
<ThemeCard v-for="theme in localThemes" :theme="theme" :key="theme.id" :toggleTheme="toggleTheme" :reloadTheme="reloadTheme" :showSettings="showSettings" />
|
||||
<ThemeCard v-for="theme in localThemes" :theme="theme" :key="theme.id" :toggleTheme="() => toggleTheme(theme)" :reloadTheme="() => reloadTheme(theme)" :showSettings="() => showSettings(theme)" />
|
||||
</div>
|
||||
<div v-if="!local" class="bd-spinner-container">
|
||||
<div class="bd-spinner-2"></div>
|
||||
|
@ -61,10 +58,11 @@
|
|||
showOnline() {
|
||||
this.local = false;
|
||||
},
|
||||
refreshLocal() {
|
||||
(async () => {
|
||||
await ThemeManager.refreshTheme();
|
||||
})();
|
||||
async refreshLocal() {
|
||||
await ThemeManager.refreshTheme();
|
||||
},
|
||||
async refreshOnline() {
|
||||
|
||||
},
|
||||
toggleTheme(theme) {
|
||||
// TODO Display error if theme fails to enable/disable
|
||||
|
@ -78,15 +76,13 @@
|
|||
console.log(err);
|
||||
}
|
||||
},
|
||||
reloadTheme(theme) {
|
||||
(async () => {
|
||||
try {
|
||||
await ThemeManager.reloadTheme(theme);
|
||||
this.$forceUpdate();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
})();
|
||||
async reloadTheme(theme) {
|
||||
try {
|
||||
await ThemeManager.reloadTheme(theme);
|
||||
this.$forceUpdate();
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
},
|
||||
showSettings(theme) {
|
||||
return Modals.contentSettings(theme);
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* BetterDiscord Confirm 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" @click="modal.close">Cancel</div>
|
||||
<div class="bd-button bd-ok" @click="() => { modal.confirm(); modal.close(); }">OK</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Imports
|
||||
import { Modal } from '../../common';
|
||||
|
||||
export default {
|
||||
props: ['modal'],
|
||||
components: {
|
||||
Modal
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,129 @@
|
|||
/**
|
||||
* BetterDiscord Setting File 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>
|
||||
<div class="bd-form-settingsarray" :class="{'bd-form-settingsarray-inline': setting.inline}">
|
||||
<div class="bd-title">
|
||||
<h3>{{ setting.text }}</h3>
|
||||
<button class="bd-button bd-button-primary" :class="{'bd-disabled': setting.disabled || setting.max && items.length >= setting.max}" @click="() => addItem(!setting.inline)">Add</button>
|
||||
</div>
|
||||
<div class="bd-hint">{{ setting.hint }}</div>
|
||||
<div class="bd-settingsarray-items">
|
||||
<div class="bd-settingsarray-item" v-for="(item, index) in items">
|
||||
<div class="bd-settingsarray-item-marker">{{ index + 1 }}</div>
|
||||
|
||||
<SettingsPanel class="bd-settingsarray-item-contents" v-if="setting.inline" :settings="item.settings" :change="(c, s, v) => changeInItem(item, c, s, v)" />
|
||||
<div class="bd-settingsarray-item-contents" v-else>
|
||||
<div class="bd-settingsarray-item-hint">
|
||||
<span v-if="item.settings[0] && item.settings[0].settings[0]">{{ item.settings[0].settings[0].text }}: {{ item.settings[0].settings[0].value }}</span><span v-if="item.settings[0] && item.settings[0].settings[1]">, {{ item.settings[0].settings[1].text }}: {{ item.settings[0].settings[1].value }}</span><span v-if="item.settings[0] && item.settings[0].settings[2] || item.settings[1] && item.settings[1].settings[0]">, ...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bd-settingsarray-item-controls">
|
||||
<span class="bd-settingsarray-open" v-if="typeof setting.allow_external !== 'undefined' ? setting.allow_external || !setting.inline : true" @click="() => showModal(item, index)"><MiOpenInNew v-if="setting.inline" /><MiSettings v-else /></span>
|
||||
<span class="bd-settingsarray-remove" :class="{'bd-disabled': setting.disabled || setting.min && items.length <= setting.min}" @click="() => removeItem(item)"><MiMinus /></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { shell } from 'electron';
|
||||
import { Utils, ClientIPC } from 'common';
|
||||
import { MiSettings, MiOpenInNew, MiMinus } from '../../common';
|
||||
import { Modals } from 'ui';
|
||||
import SettingsPanel from '../SettingsPanel.vue';
|
||||
|
||||
export default {
|
||||
props: ['setting', 'change'],
|
||||
components: {
|
||||
MiSettings, MiOpenInNew, MiMinus
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
items: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
setting(value) {
|
||||
// this.setting was changed
|
||||
this.reloadSettings();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addItem(openModal) {
|
||||
if (this.setting.disabled || this.setting.max && this.items.length >= this.setting.max) return;
|
||||
const item = { settings: this.getItemSettings({}) };
|
||||
if (openModal) this.showModal(item, this.items.length);
|
||||
this.items.push(item);
|
||||
this.update();
|
||||
},
|
||||
removeItem(item) {
|
||||
if (this.setting.disabled || this.setting.min && this.items.length <= this.setting.min) return;
|
||||
this.items = this.items.filter(i => i !== item);
|
||||
this.update();
|
||||
},
|
||||
changeInItem(item, category_id, setting_id, value) {
|
||||
console.log('Setting', item, category_id, setting_id, 'to', value);
|
||||
|
||||
const category = item.settings.find(c => c.category === category_id);
|
||||
if (!category) return;
|
||||
|
||||
const setting = category.settings.find(s => s.id === setting_id);
|
||||
if (!setting || Utils.compare(setting.value, value)) return;
|
||||
|
||||
setting.value = value;
|
||||
setting.changed = !Utils.compare(setting.value, setting.old_value);
|
||||
this.update();
|
||||
},
|
||||
update() {
|
||||
this.change(this.items.map(item => ({
|
||||
settings: item.settings ? item.settings.map(category => ({
|
||||
category: category.category,
|
||||
settings: category.settings.map(setting => ({
|
||||
id: setting.id,
|
||||
value: setting.value
|
||||
}))
|
||||
})) : []
|
||||
})));
|
||||
},
|
||||
showModal(item, index) {
|
||||
Modals.settings(this.setting.headertext ? this.setting.headertext.replace(/%n/, index + 1) : this.setting.text + ` #${index + 1}`, item.settings, this.setting.schemes, () => this.update());
|
||||
},
|
||||
getItemSettings(item) {
|
||||
const settings = JSON.parse(JSON.stringify(this.setting.settings));
|
||||
const newSettings = item.settings || [];
|
||||
|
||||
for (let newCategory of newSettings) {
|
||||
const category = settings.find(c => c.category === newCategory.category);
|
||||
for (let newSetting of newCategory.settings) {
|
||||
const setting = category.settings.find(s => s.id === newSetting.id);
|
||||
setting.value = setting.old_value = newSetting.value;
|
||||
setting.changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return settings;
|
||||
},
|
||||
reloadSettings() {
|
||||
this.items = JSON.parse(JSON.stringify(this.setting.value)) || [];
|
||||
this.items = this.items.map(item => ({ settings: this.getItemSettings(item) }));
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
// https://vuejs.org/v2/guide/components.html#Circular-References-Between-Components
|
||||
this.$options.components.SettingsPanel = SettingsPanel;
|
||||
},
|
||||
beforeMount() {
|
||||
this.reloadSettings();
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -11,7 +11,7 @@
|
|||
<template>
|
||||
<div class="bd-form-dropdown">
|
||||
<div class="bd-title">
|
||||
<h3>{{setting.text}}</h3>
|
||||
<h3 v-if="setting.text">{{setting.text}}</h3>
|
||||
<div class="bd-dropdown" :class="{'bd-active': active}">
|
||||
<div class="bd-dropdown-current" @click="() => active = !active && !setting.disabled">
|
||||
<span class="bd-dropdown-text">{{getOptionText(setting.value)}}</span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<template>
|
||||
<div class="bd-form-numberinput">
|
||||
<div class="bd-title">
|
||||
<h3>{{setting.text}}</h3>
|
||||
<h3 v-if="setting.text">{{setting.text}}</h3>
|
||||
<div class="bd-number">
|
||||
<input type="number" :value="setting.value" :min="setting.min" :max="setting.max" :step="setting.step" @keyup.stop @input="input"/>
|
||||
<div class="bd-number-spinner bd-flex bd-flex-col">
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
|
||||
<template>
|
||||
<div class="bd-form-item" :class="{'bd-form-item-changed': changed, 'bd-disabled': disabled}">
|
||||
<div class="bd-form-item" :class="{'bd-form-item-changed': changed, 'bd-disabled': disabled, 'bd-form-item-noheader': !setting.text}">
|
||||
<BoolSetting v-if="setting.type === 'bool'" :setting="setting" :change="change"/>
|
||||
<DropdownSetting v-if="setting.type === 'dropdown'" :setting="setting" :change="change"/>
|
||||
<NumberSetting v-if="setting.type === 'number'" :setting="setting" :change="change"/>
|
||||
|
@ -18,6 +18,7 @@
|
|||
<MultilineTextSetting v-if="setting.type === 'text' && setting.multiline" :setting="setting" :change="change"/>
|
||||
<SliderSetting v-if="setting.type === 'slider'" :setting="setting" :change="change"/>
|
||||
<FileSetting v-if="setting.type === 'file'" :setting="setting" :change="change"/>
|
||||
<ArraySetting v-if="setting.type === 'array'" :setting="setting" :change="change" />
|
||||
<div class="bd-form-divider"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -31,6 +32,7 @@
|
|||
import MultilineTextSetting from './Multiline.vue';
|
||||
import SliderSetting from './Slider.vue';
|
||||
import FileSetting from './File.vue';
|
||||
import ArraySetting from './Array.vue';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
|
@ -45,7 +47,8 @@
|
|||
StringSetting,
|
||||
MultilineTextSetting,
|
||||
SliderSetting,
|
||||
FileSetting
|
||||
FileSetting,
|
||||
ArraySetting
|
||||
},
|
||||
computed: {
|
||||
changed() {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<template>
|
||||
<div class="bd-form-textinput">
|
||||
<div class="bd-title">
|
||||
<h3>{{setting.text}}</h3>
|
||||
<h3 v-if="setting.text">{{setting.text}}</h3>
|
||||
<div class="bd-textinput-wrapper">
|
||||
<input type="text" :value="setting.value" @keyup.stop @input="input"/>
|
||||
</div>
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default as BdSettingsWrapper } from './BdSettingsWrapper.vue';
|
||||
export { default as BdSettings } from './BdSettings.vue';
|
||||
export { default as BdSettings } from './BdSettings.vue';
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<template>
|
||||
<div class="bd-sidebar-view" :class="{active: contentVisible, animating: animating}">
|
||||
<div class="bd-sidebar-region bd-flex-col">
|
||||
<div class="bd-settingsWrap">
|
||||
<div class="bd-settingswrap">
|
||||
<ScrollerWrap dark="true">
|
||||
<slot name="sidebar" />
|
||||
</ScrollerWrap>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
import { Utils, FileUtils } from 'common';
|
||||
import { Settings, Events, PluginManager, ThemeManager } from 'modules';
|
||||
import BasicModal from './components/bd/modals/BasicModal.vue';
|
||||
import ConfirmModal from './components/bd/modals/ConfirmModal.vue';
|
||||
import ErrorModal from './components/bd/modals/ErrorModal.vue';
|
||||
import SettingsModal from './components/bd/modals/SettingsModal.vue';
|
||||
|
||||
|
@ -25,6 +26,7 @@ export default class {
|
|||
};
|
||||
modal.closing = false;
|
||||
modal.close = force => this.close(modal, force);
|
||||
modal.id = Date.now();
|
||||
|
||||
this.stack.push(modal);
|
||||
Events.emit('bd-refresh-modals');
|
||||
|
@ -68,6 +70,17 @@ export default class {
|
|||
return this.add({ title, text }, BasicModal);
|
||||
}
|
||||
|
||||
static confirm(title, text) {
|
||||
const modal = { title, text };
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
modal.confirm = () => resolve(true);
|
||||
modal.beforeClose = () => reject();
|
||||
this.add(modal, ConfirmModal);
|
||||
});
|
||||
modal.promise = promise;
|
||||
return modal;
|
||||
}
|
||||
|
||||
static error(event) {
|
||||
return this.add({ event }, ErrorModal);
|
||||
}
|
||||
|
|
|
@ -59,4 +59,4 @@ module.exports = {
|
|||
path.resolve(__dirname, '..', 'node_modules')
|
||||
]
|
||||
}*/
|
||||
};
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@ const
|
|||
_ = require('lodash');
|
||||
|
||||
import { Vendor } from 'modules';
|
||||
import filetype from 'file-type';
|
||||
|
||||
export class Utils {
|
||||
static overload(fn, cb) {
|
||||
|
@ -150,6 +151,15 @@ export class FileUtils {
|
|||
});
|
||||
}
|
||||
|
||||
static async readFileBuffer(path, options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.readFile(path, options || {}, (err, data) => {
|
||||
if (err) return reject(err);
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static async writeFile(path, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.writeFile(path, data, err => {
|
||||
|
@ -196,4 +206,16 @@ export class FileUtils {
|
|||
static async readDir(path) {
|
||||
return this.listDirectory(path);
|
||||
}
|
||||
|
||||
static async getFileType(buffer) {
|
||||
if (typeof buffer === 'string') buffer = await this.readFileBuffer(buffer);
|
||||
|
||||
return filetype(buffer);
|
||||
}
|
||||
|
||||
static async toDataURI(buffer, type) {
|
||||
if (typeof buffer === 'string') buffer = await this.readFileBuffer(buffer);
|
||||
if (!type) type = this.getFileType(buffer).mime;
|
||||
return `data:${type};base64,${buffer.toString('base64')}`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"electron-rebuild": "^1.7.3",
|
||||
"eslint": "^4.16.0",
|
||||
"eslint-plugin-vue": "^4.2.0",
|
||||
"file-type": "^7.6.0",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-babel": "^7.0.0",
|
||||
"gulp-plumber": "^1.2.0",
|
||||
|
@ -49,7 +50,7 @@
|
|||
"build": "npm run build --prefix client && npm run build --prefix core && npm run build --prefix csseditor",
|
||||
"build_client": "npm run build --prefix client",
|
||||
"watch_client": "npm run watch --prefix client",
|
||||
"build_core": "npm run build --prefix core",
|
||||
"build_core": "npm run build --prefix core",
|
||||
"watch_core": "npm run watch --prefix core",
|
||||
"watch_csseditor": "npm run watch --prefix csseditor",
|
||||
"lint": "eslint -f unix client/src core/src csseditor/src",
|
||||
|
|
|
@ -17,6 +17,77 @@
|
|||
"category_default_comment": "default category has no header and is always displayed first",
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "array-1",
|
||||
"type": "array",
|
||||
"value": null,
|
||||
"text": "Test settings array",
|
||||
"hint": "Just a test. Inline should be left as false here in most cases. (Only set it to true if there's only one setting otherwise it takes up too much space. Or you could put it in a drawer.)",
|
||||
"inline": false,
|
||||
"min": 1,
|
||||
"max": 5,
|
||||
"settings": [
|
||||
{
|
||||
"category_default_comment": "default category has no header and is always displayed first",
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "default-0",
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"text": "Bool Test Setting 3",
|
||||
"hint": "Bool Test Setting Hint 3"
|
||||
},
|
||||
{
|
||||
"id": "default-1",
|
||||
"type": "text",
|
||||
"value": "defaultValue",
|
||||
"text": "Text Test Setting",
|
||||
"hint": "Text Test Setting Hint"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"schemes": [
|
||||
{
|
||||
"id": "scheme-1",
|
||||
"name": "Test scheme",
|
||||
"hint": "Can even use schemes here.",
|
||||
"icon_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Cow_female_black_white.jpg/220px-Cow_female_black_white.jpg",
|
||||
"settings": [
|
||||
{
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "default-0",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "scheme-2",
|
||||
"name": "Another test scheme",
|
||||
"icon_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Cow_female_black_white.jpg/220px-Cow_female_black_white.jpg",
|
||||
"settings": [
|
||||
{
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "default-0",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"id": "default-1",
|
||||
"value": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Cow_female_black_white.jpg/220px-Cow_female_black_white.jpg"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "default-0",
|
||||
"type": "bool",
|
||||
|
|
|
@ -17,8 +17,106 @@
|
|||
"type": "text",
|
||||
"value": "#00ff00",
|
||||
"text": "Primary colour",
|
||||
"hint": "A colour setting type would be nice here",
|
||||
"scss_raw": true
|
||||
"hint": "A colour setting type would be nice here"
|
||||
},
|
||||
{
|
||||
"id": "additional-colours",
|
||||
"type": "array",
|
||||
"text": "Additional colours",
|
||||
"inline": true,
|
||||
"allow_external": false,
|
||||
"value": [
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "colour",
|
||||
"value": "#ff0000"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "colour",
|
||||
"value": "#ffff00"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "colour",
|
||||
"value": "#ffffff"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "colour",
|
||||
"value": "#00ffff"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "colour",
|
||||
"value": "#0000ff"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"settings": [
|
||||
{
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "colour",
|
||||
"value": "#000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "colour",
|
||||
"type": "text",
|
||||
"value": "#ff0000"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "spanOpacity",
|
||||
|
@ -34,8 +132,7 @@
|
|||
},
|
||||
{
|
||||
"id": "avatar",
|
||||
"type": "text",
|
||||
"value": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Cow_female_black_white.jpg/220px-Cow_female_black_white.jpg",
|
||||
"type": "file",
|
||||
"text": "Avatar replace",
|
||||
"hint": "Replace all avatars"
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@import 'vars.scss';
|
||||
@import 'vars';
|
||||
|
||||
div {
|
||||
background: $divBg;
|
||||
background: unquote($divBg);
|
||||
}
|
||||
|
||||
span {
|
||||
|
@ -11,6 +11,18 @@ span {
|
|||
}
|
||||
|
||||
.avatar-large {
|
||||
background-image: url($avatar) !important;
|
||||
background-image: url(map-get($avatar, url)) !important;
|
||||
border-radius: $avatarRadius !important;
|
||||
}
|
||||
|
||||
// Can't use a for loop as then we don't get the index
|
||||
$index: 0;
|
||||
@while $index < length($additional-colours) {
|
||||
$additional-colour: nth($additional-colours, $index + 1);
|
||||
|
||||
div:nth-child(#{length($additional-colours)}n + #{$index}) {
|
||||
color: unquote(map-get($additional-colour, colour)) !important;
|
||||
}
|
||||
|
||||
$index: $index + 1;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
$divBg: green !default;
|
||||
$spanOpacity: 0.5 !default;
|
||||
$avatar: "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Cow_female_black_white.jpg/220px-Cow_female_black_white.jpg" !default;
|
||||
$avatar: (url: "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0c/Cow_female_black_white.jpg/220px-Cow_female_black_white.jpg") !default;
|
||||
$avatarRadius: 8px !default;
|
||||
$radioTest: red !default;
|
||||
$spanOpacity2: 1 !default;
|
||||
$spanOpacity2: 1 !default;
|
||||
|
|
Loading…
Reference in New Issue