Add ability to restore default settings
This commit is contained in:
parent
853c554d4d
commit
97b486657f
|
@ -257,6 +257,8 @@
|
|||
"updateButton": "Update!"
|
||||
},
|
||||
"Settings": {
|
||||
"customColor": "Custom Color"
|
||||
"customColor": "Custom Color",
|
||||
"resetSettings": "Reset Settings",
|
||||
"resetSettingsWarning": "Resetting your settings returns them all to the original state, this cannot be undone."
|
||||
}
|
||||
}
|
|
@ -73,12 +73,16 @@ export default new class SettingsManager {
|
|||
if (!this.state[collection.id]) this.state[collection.id] = {};
|
||||
for (let cc = 0; cc < categories.length; cc++) {
|
||||
const category = categories[cc];
|
||||
if (category.type != "category") {if (!this.state[collection.id].hasOwnProperty(category.id)) this.state[collection.id][category.id] = category.value;}
|
||||
if (category.type != "category") {
|
||||
if (!this.state[collection.id].hasOwnProperty(category.id)) this.state[collection.id][category.id] = category.value;
|
||||
category.defaultValue = category.value;
|
||||
}
|
||||
else {
|
||||
if (!this.state[collection.id].hasOwnProperty(category.id)) this.state[collection.id][category.id] = {};
|
||||
for (let s = 0; s < category.settings.length; s++) {
|
||||
const setting = category.settings[s];
|
||||
if (!this.state[collection.id][category.id].hasOwnProperty(setting.id)) this.state[collection.id][category.id][setting.id] = setting.value;
|
||||
setting.defaultValue = setting.value;
|
||||
if (setting.hasOwnProperty("disabled")) continue;
|
||||
if (!setting.enableWith && !setting.disableWith) continue;
|
||||
const pathString = setting.enableWith || setting.disableWith;
|
||||
|
@ -131,6 +135,28 @@ export default new class SettingsManager {
|
|||
this.saveCollection(id); // in case new things were added
|
||||
}
|
||||
|
||||
resetCollection(id) {
|
||||
const collection = this.collections.find(c => c.id == id);
|
||||
if (!collection) return;
|
||||
const categories = collection.settings;
|
||||
for (let cc = 0; cc < categories.length; cc++) {
|
||||
const category = categories[cc];
|
||||
if (category.type != "category") {
|
||||
// console.log("cat", collection.id, category.id, this.get(collection.id, category.id), category.value);
|
||||
if (this.get(collection.id, category.id) == category.defaultValue) continue;
|
||||
this.set(collection.id, category.id, category.defaultValue);
|
||||
}
|
||||
else {
|
||||
for (let s = 0; s < category.settings.length; s++) {
|
||||
const setting = category.settings[s];
|
||||
// console.log("setting", collection.id, category.id, setting.id, this.get(collection.id, category.id, setting.id), setting.defaultValue);
|
||||
if (this.get(collection.id, category.id, setting.id) == setting.defaultValue) continue;
|
||||
this.set(collection.id, category.id, setting.id, setting.defaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onSettingChange(collection, category, id, value) {
|
||||
this.state[collection][category][id] = value;
|
||||
Events.dispatch("setting-updated", collection, category, id, value);
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import React from "@modules/react";
|
||||
|
||||
export default function Restore(props) {
|
||||
const size = props.size || "24px";
|
||||
return <svg className={props.className || ""} fill="#FFFFFF" viewBox="0 0 24 24" style={{width: size, height: size}} onClick={props.onClick}>
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M14 12c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm-2-9c-4.97 0-9 4.03-9 9H0l4 4 4-4H5c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.51 0-2.91-.49-4.06-1.3l-1.42 1.44C8.04 20.3 9.94 21 12 21c4.97 0 9-4.03 9-9s-4.03-9-9-9z"/>
|
||||
</svg>;
|
||||
}
|
|
@ -1,15 +1,55 @@
|
|||
import React from "@modules/react";
|
||||
import Strings from "@modules/strings";
|
||||
import Utilities from "@modules/utilities";
|
||||
import Events from "@modules/emitter";
|
||||
import Settings from "@modules/settingsmanager";
|
||||
import DataStore from "@modules/datastore";
|
||||
import WebpackModules, {Filters} from "@modules/webpackmodules";
|
||||
import Patcher from "@modules/patcher";
|
||||
import DiscordModules from "@modules/discordmodules";
|
||||
|
||||
import AddonList from "./settings/addonlist";
|
||||
import SettingsGroup from "./settings/group";
|
||||
import SettingsTitle from "./settings/title";
|
||||
import Header from "./settings/sidebarheader";
|
||||
import ReactUtils from "@modules/api/reactutils";
|
||||
|
||||
import Button from "@ui/base/button";
|
||||
import Modals from "@ui/modals";
|
||||
|
||||
import AddonList from "@ui/settings/addonlist";
|
||||
import SettingsGroup from "@ui/settings/group";
|
||||
import SettingsTitle from "@ui/settings/title";
|
||||
import Header from "@ui/settings/sidebarheader";
|
||||
|
||||
import Restore from "./icons/restore";
|
||||
// import SettingsPanel from "./settings/panel";
|
||||
|
||||
|
||||
function makeResetButton(collectionId, refresh) {
|
||||
const action = confirmReset(() => {
|
||||
Settings.resetCollection(collectionId);
|
||||
refresh?.();
|
||||
});
|
||||
return <DiscordModules.Tooltip color="primary" position="top" text={Strings.Settings.resetSettings}>
|
||||
{(props) =>
|
||||
<Button {...props} size={Button.Sizes.ICON} look={Button.Looks.BLANK} color={Button.Colors.TRANSPARENT} onClick={action}>
|
||||
<Restore />
|
||||
</Button>
|
||||
}
|
||||
</DiscordModules.Tooltip>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function} action
|
||||
* @returns
|
||||
*/
|
||||
function confirmReset(action) {
|
||||
return () => {
|
||||
Modals.showConfirmationModal(Strings.Modals.confirmAction, Strings.Settings.resetSettingsWarning, {
|
||||
confirmText: Strings.Modals.okay,
|
||||
cancelText: Strings.Modals.cancel,
|
||||
danger: true,
|
||||
onConfirm: action,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default new class SettingsRenderer {
|
||||
|
||||
|
@ -34,22 +74,32 @@ export default new class SettingsRenderer {
|
|||
|
||||
onChange(onChange) {
|
||||
return (collection, category, id) => {
|
||||
const before = Settings.collections.length + Settings.panels.length;
|
||||
onChange(collection, category, id);
|
||||
const after = Settings.collections.length + Settings.panels.length;
|
||||
if (before != after) setTimeout(this.forceUpdate.bind(this), 50);
|
||||
|
||||
// Delay until after switch animation
|
||||
// TODO: lift settings state to SettingsPanel
|
||||
// to prevent the need for this.
|
||||
setTimeout(this.forceUpdate.bind(this), 250);
|
||||
};
|
||||
}
|
||||
|
||||
buildSettingsPanel(id, title, config, state, onChange, button = null) {
|
||||
buildSettingsPanel(id, title, config, state, onChange) {
|
||||
config.forEach(section => {
|
||||
section.settings.forEach(item => item.value = state[section.id][item.id]);
|
||||
});
|
||||
return this.getSettingsPanel(id, title, config, this.onChange(onChange), button);
|
||||
return this.getSettingsPanel(id, title, config, this.onChange(onChange));
|
||||
}
|
||||
|
||||
getSettingsPanel(id, title, groups, onChange, button = null) {
|
||||
return [React.createElement(SettingsTitle, {text: title, button: button}), groups.map(section => {
|
||||
getSettingsPanel(id, title, groups, onChange) {
|
||||
// return <SettingsPanel
|
||||
// id={id}
|
||||
// title={title}
|
||||
// groups={groups}
|
||||
// onChange={onChange}
|
||||
// onDrawerToggle={(...args) => this.onDrawerToggle(...args)}
|
||||
// getDrawerState={(...args) => this.getDrawerState(...args)}
|
||||
// />;
|
||||
return [React.createElement(SettingsTitle, {text: title}, makeResetButton(id, this.forceUpdate.bind(this))), groups.map(section => {
|
||||
return React.createElement(SettingsGroup, Object.assign({}, section, {
|
||||
onChange: onChange,
|
||||
onDrawerToggle: state => this.onDrawerToggle(id, section.id, state),
|
||||
|
@ -85,7 +135,7 @@ export default new class SettingsRenderer {
|
|||
section: collection.name,
|
||||
label: collection.name.toString(),
|
||||
className: `bd-${collection.id}-tab`,
|
||||
element: () => this.buildSettingsPanel(collection.id, collection.name, collection.settings, Settings.state[collection.id], Settings.onSettingChange.bind(Settings, collection.id), collection.button ? collection.button : null)
|
||||
element: () => this.buildSettingsPanel(collection.id, collection.name, collection.settings, Settings.state[collection.id], Settings.onSettingChange.bind(Settings, collection.id))
|
||||
});
|
||||
}
|
||||
for (const panel of Settings.panels.sort((a,b) => a.order > b.order ? 1 : -1)) {
|
||||
|
@ -101,7 +151,7 @@ export default new class SettingsRenderer {
|
|||
const viewClass = WebpackModules.getByProps("standardSidebarView")?.standardSidebarView.split(" ")[0];
|
||||
const node = document.querySelector(`.${viewClass}`);
|
||||
if (!node) return;
|
||||
const stateNode = Utilities.findInTree(node?.__reactFiber$, m => m && m.getPredicateSections, {walkable: ["return", "stateNode"]});
|
||||
const stateNode = Utilities.findInTree(ReactUtils.getInternalInstance(node), m => m && m.getPredicateSections, {walkable: ["return", "stateNode"]});
|
||||
if (stateNode) stateNode.forceUpdate();
|
||||
}
|
||||
};
|
|
@ -0,0 +1,68 @@
|
|||
import React from "@modules/react";
|
||||
import Strings from "@modules/strings";
|
||||
import Utilities from "@modules/utilities";
|
||||
import Events from "@modules/emitter";
|
||||
import Settings from "@modules/settingsmanager";
|
||||
import DataStore from "@modules/datastore";
|
||||
import WebpackModules, {Filters} from "@modules/webpackmodules";
|
||||
import Patcher from "@modules/patcher";
|
||||
import DiscordModules from "@modules/discordmodules";
|
||||
|
||||
import Button from "@ui/base/button";
|
||||
import Modals from "@ui/modals";
|
||||
|
||||
import AddonList from "@ui/settings/addonlist";
|
||||
import SettingsGroup from "@ui/settings/group";
|
||||
import SettingsTitle from "@ui/settings/title";
|
||||
import Header from "@ui/settings/sidebarheader";
|
||||
|
||||
import Restore from "@ui/icons/restore";
|
||||
|
||||
|
||||
const {useCallback, useEffect, useReducer} = React;
|
||||
|
||||
function makeResetButton(collectionId) {
|
||||
const action = confirmReset(() => Settings.resetCollection(collectionId));
|
||||
return <DiscordModules.Tooltip color="primary" position="top" text={Strings.Settings.resetSettings}>
|
||||
{(props) =>
|
||||
<Button {...props} size={Button.Sizes.ICON} look={Button.Looks.BLANK} color={Button.Colors.TRANSPARENT} onClick={action}>
|
||||
<Restore />
|
||||
</Button>
|
||||
}
|
||||
</DiscordModules.Tooltip>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function} action
|
||||
* @returns
|
||||
*/
|
||||
function confirmReset(action) {
|
||||
return () => {
|
||||
Modals.showConfirmationModal(Strings.Modals.confirmAction, Strings.Settings.resetSettingsWarning, {
|
||||
confirmText: Strings.Modals.okay,
|
||||
cancelText: Strings.Modals.cancel,
|
||||
danger: true,
|
||||
onConfirm: action,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default function SettingsPanel({id, title, groups, onChange, onDrawerToggle, getDrawerState}) {
|
||||
|
||||
// TODO: add onChange here to lift and manage state here
|
||||
|
||||
return <>
|
||||
<SettingsTitle text={title}>
|
||||
{makeResetButton(id)}
|
||||
</SettingsTitle>,
|
||||
{groups.map(section => {
|
||||
const props = Object.assign({}, section, {
|
||||
onChange,
|
||||
onDrawerToggle: state => onDrawerToggle(id, section.id, state),
|
||||
shown: getDrawerState(id, section.id, section.hasOwnProperty("shown") ? section.shown : true)
|
||||
});
|
||||
return <SettingsGroup {...props} />;
|
||||
})}
|
||||
</>;
|
||||
|
||||
}
|
Loading…
Reference in New Issue