Add settings arrays
This commit is contained in:
parent
847d88a628
commit
fae6fc8511
|
@ -0,0 +1,77 @@
|
|||
.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-settingsarray-item-controls {
|
||||
flex-basis: 0%;
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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" @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>
|
|
@ -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() {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -20,6 +20,25 @@
|
|||
"hint": "A colour setting type would be nice here",
|
||||
"scss_raw": true
|
||||
},
|
||||
{
|
||||
"id": "additional-colours",
|
||||
"type": "array",
|
||||
"text": "Additional colours",
|
||||
"inline": true,
|
||||
"settings": [
|
||||
{
|
||||
"category": "default",
|
||||
"settings": [
|
||||
{
|
||||
"id": "colour",
|
||||
"type": "text",
|
||||
"value": "#ff0000",
|
||||
"scss_raw": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "spanOpacity",
|
||||
"type": "slider",
|
||||
|
|
Loading…
Reference in New Issue