diff --git a/client/src/modules/plugin.js b/client/src/modules/plugin.js index 9ce047fd..1ebcffaa 100644 --- a/client/src/modules/plugin.js +++ b/client/src/modules/plugin.js @@ -8,7 +8,7 @@ * LICENSE file in the root directory of this source tree. */ -import { FileUtils } from 'common'; +import { Utils, FileUtils } from 'common'; import { Modals } from 'ui'; export default class Plugin { @@ -54,13 +54,18 @@ export default class Plugin { } async saveSettings(newSettings) { - for (let category of newSettings) { - const oldCategory = this.pluginConfig.find(c => c.category === category.category); - for (let setting of category.settings) { - const oldSetting = oldCategory.settings.find(s => s.id === setting.id); - if (oldSetting.value === setting.value) continue; - oldSetting.value = setting.value; - if (this.settingChanged) this.settingChanged(category.category, setting.id, setting.value); + const updatedSettings = []; + + for (let newCategory of newSettings) { + const category = this.pluginConfig.find(c => c.category === newCategory.category); + for (let newSetting of newCategory.settings) { + const setting = category.settings.find(s => s.id === newSetting.id); + if (Utils.compare(setting.value, newSetting.value)) continue; + + let old_value = setting.value; + setting.value = newSetting.value; + updatedSettings.push({ category_id: category.category, setting_id: setting.id, value: setting.value, old_value }); + this.settingUpdated(category.category, setting.id, setting.value, old_value); } } diff --git a/client/src/styles/partials/modals/index.scss b/client/src/styles/partials/modals/index.scss index e36ebd94..db8ff474 100644 --- a/client/src/styles/partials/modals/index.scss +++ b/client/src/styles/partials/modals/index.scss @@ -5,3 +5,4 @@ @import './basic-modal.scss'; @import './error-modal.scss'; +@import './settings-modal.scss'; diff --git a/client/src/styles/partials/modals/settings-modal.scss b/client/src/styles/partials/modals/settings-modal.scss new file mode 100644 index 00000000..fd3513a8 --- /dev/null +++ b/client/src/styles/partials/modals/settings-modal.scss @@ -0,0 +1,32 @@ +.bd-settings-modal { + .bd-modal .bd-modal-body { + padding: 0; + } + + .bd-modal .bd-modal-footer { + .bd-ok { + width: 100px; + } + } + + .bd-settings-modal-body { + padding: 0 15px; + margin: 0 0 74px; + + .bd-switch-wrapper { + width: 40px; + height: 20px; + + .bd-switch::before { + width: 14px; + height: 14px; + } + } + } + + &.bd-edited { + .bd-scroller::-webkit-scrollbar-track { + margin-bottom: 74px; + } + } +} diff --git a/client/src/ui/components/bd/BdModals.vue b/client/src/ui/components/bd/BdModals.vue index 34a4bed8..f6216014 100644 --- a/client/src/ui/components/bd/BdModals.vue +++ b/client/src/ui/components/bd/BdModals.vue @@ -38,7 +38,6 @@ }; }, created() { - console.log(this); Events.on('bd-refresh-modals', this.eventListener = () => { this.$forceUpdate(); }); diff --git a/client/src/ui/components/bd/modals/SettingsModal.vue b/client/src/ui/components/bd/modals/SettingsModal.vue new file mode 100644 index 00000000..bdb69688 --- /dev/null +++ b/client/src/ui/components/bd/modals/SettingsModal.vue @@ -0,0 +1,114 @@ +/** + * BetterDiscord Settings 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. +*/ + + + diff --git a/client/src/ui/modals.js b/client/src/ui/modals.js index fffab1d1..655571b1 100644 --- a/client/src/ui/modals.js +++ b/client/src/ui/modals.js @@ -8,12 +8,13 @@ * LICENSE file in the root directory of this source tree. */ -import { FileUtils } from 'common'; +import { Utils, 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'; +import SettingsModal from './components/bd/modals/SettingsModal.vue'; export default class { @@ -78,6 +79,31 @@ export default class { }); } + static settings(headertext, settings, settingsUpdated, settingUpdated, saveSettings) { + return this.add({ + headertext, settings, + saveSettings: saveSettings ? saveSettings : newSettings => { + const updatedSettings = []; + + for (let newCategory of newSettings) { + let category = settings.find(c => c.category === newCategory.category); + + for (let newSetting of newCategory.settings) { + let setting = category.settings.find(s => s.id === newSetting.id); + if (Utils.compare(setting.value, newSetting.value)) continue; + + let old_value = setting.value; + setting.value = newSetting.value; + updatedSettings.push({ category_id: category.category, setting_id: setting.id, value: setting.value, old_value }); + if (settingUpdated) settingUpdated(category.category, setting.id, setting.value, old_value); + } + } + + return settingsUpdated ? settingsUpdated(updatedSettings) : updatedSettings; + } + }, SettingsModal); + } + static pluginSettings(plugin) { return this.add({ plugin }, PluginSettingsModal); } diff --git a/common/modules/utils.js b/common/modules/utils.js index 84380086..13f2c7f7 100644 --- a/common/modules/utils.js +++ b/common/modules/utils.js @@ -45,6 +45,27 @@ export class Utils { }); return camelCased; } + + static compare(value1, value2) { + // Check to see if value1 and value2 contain the same data + if (typeof value1 !== typeof value2) return false; + if (value1 === null && value2 === null) return true; + if (value1 === null || value2 === null) return false; + + if (typeof value1 === 'object' || typeof value1 === 'array') { + // Loop through the object and check if everything's the same + let value1array = typeof value1 === 'array' ? value1 : Object.keys(value1); + let value2array = typeof value2 === 'array' ? value2 : Object.keys(value2); + if (value1array.length !== value2array.length) return false; + + for (let key in value1) { + if (!this.compare(value1[key], value2[key])) return false; + } + } else if (value1 !== value2) return false; + + // value1 and value2 contain the same data + return true; + } } export class FileUtils {