Fix onchange listeners for individual items
This commit is contained in:
parent
23aa6876d1
commit
c3951cba25
|
@ -69,6 +69,22 @@ export default class BdApi {
|
||||||
get UI() {return UI;}
|
get UI() {return UI;}
|
||||||
get ReactUtils() {return ReactUtils;}
|
get ReactUtils() {return ReactUtils;}
|
||||||
get ContextMenu() {return ContextMenuAPI;}
|
get ContextMenu() {return ContextMenuAPI;}
|
||||||
|
Components = {
|
||||||
|
get Tooltip() {return DiscordModules.Tooltip;},
|
||||||
|
get ColorInput() {return ColorInput;},
|
||||||
|
get DropdownInput() {return DropdownInput;},
|
||||||
|
get SettingItem() {return SettingItem;},
|
||||||
|
get KeybindInput() {return KeybindInput;},
|
||||||
|
get NumberInput() {return NumberInput;},
|
||||||
|
get RadioInput() {return RadioInput;},
|
||||||
|
get SearchInput() {return SearchInput;},
|
||||||
|
get SliderInput() {return SliderInput;},
|
||||||
|
get SwitchInput() {return SwitchInput;},
|
||||||
|
get TextInput() {return TextInput;},
|
||||||
|
get SettingGroup() {return SettingGroup;},
|
||||||
|
get ErrorBoundary() {return ErrorBoundary;},
|
||||||
|
};
|
||||||
|
Net = {fetch};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add legacy functions
|
// Add legacy functions
|
||||||
|
|
|
@ -6,6 +6,7 @@ import Notices from "@ui/notices";
|
||||||
import Tooltip from "@ui/tooltip";
|
import Tooltip from "@ui/tooltip";
|
||||||
import Group, {buildSetting} from "@ui/settings/group";
|
import Group, {buildSetting} from "@ui/settings/group";
|
||||||
import React from "@modules/react";
|
import React from "@modules/react";
|
||||||
|
import ErrorBoundary from "@ui/errorboundary";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +81,7 @@ const UI = {
|
||||||
* @param {string} [options.video] Youtube link or url of a video file to use as the banner
|
* @param {string} [options.video] Youtube link or url of a video file to use as the banner
|
||||||
* @param {string} [options.poster] URL to use for the video freeze-frame poster
|
* @param {string} [options.poster] URL to use for the video freeze-frame poster
|
||||||
* @param {string|ReactElement|Array<string|ReactElement>} [options.footer] What to show in the modal footer
|
* @param {string|ReactElement|Array<string|ReactElement>} [options.footer] What to show in the modal footer
|
||||||
* @param {Array<object>} [options.changes] List of changes to show (see description for details)
|
* @param {Array<Changes>} [options.changes] List of changes to show (see description for details)
|
||||||
* @returns {string} The key used for this modal.
|
* @returns {string} The key used for this modal.
|
||||||
*/
|
*/
|
||||||
showChangelogModal(options) {
|
showChangelogModal(options) {
|
||||||
|
@ -169,7 +170,8 @@ const UI = {
|
||||||
* as the Group React Component found under the `Components` API.
|
* as the Group React Component found under the `Components` API.
|
||||||
*
|
*
|
||||||
* `onChange` will always be given 3 arguments: category id, setting id, and setting value. In the case
|
* `onChange` will always be given 3 arguments: category id, setting id, and setting value. In the case
|
||||||
* that you have settings on the "root" of the panel, the category id is `null`.
|
* that you have settings on the "root" of the panel, the category id is `null`. Any `onChange`
|
||||||
|
* listeners attached to individual settings will fire before the panel-level change listener.
|
||||||
*
|
*
|
||||||
* `onDrawerToggle` is given 2 arguments: category id, and the current shown state. You can use this to
|
* `onDrawerToggle` is given 2 arguments: category id, and the current shown state. You can use this to
|
||||||
* save drawer states.
|
* save drawer states.
|
||||||
|
@ -186,18 +188,28 @@ const UI = {
|
||||||
*/
|
*/
|
||||||
buildSettingsPanel({settings, onChange, onDrawerToggle, getDrawerState}) {
|
buildSettingsPanel({settings, onChange, onDrawerToggle, getDrawerState}) {
|
||||||
if (!settings?.length) throw new Error("No settings provided!");
|
if (!settings?.length) throw new Error("No settings provided!");
|
||||||
if (typeof(onChange) !== "function") throw new Error("No change listener provided!");
|
|
||||||
return React.createElement(React.Fragment, null, settings.map(setting => {
|
return React.createElement(ErrorBoundary, null, settings.map(setting => {
|
||||||
|
if (!setting.id || !setting.type) throw new Error(`Setting item missing id or type`);
|
||||||
|
|
||||||
if (setting.type === "category") {
|
if (setting.type === "category") {
|
||||||
const shownByDefault = setting.hasOwnProperty("shown") ? setting.shown : true;
|
const shownByDefault = setting.hasOwnProperty("shown") ? setting.shown : true;
|
||||||
const categoryProps = Object.assign({}, setting, {
|
|
||||||
onChange,
|
return React.createElement(Group, {
|
||||||
|
...setting,
|
||||||
|
onChange: onChange,
|
||||||
onDrawerToggle: state => onDrawerToggle?.(setting.id, state),
|
onDrawerToggle: state => onDrawerToggle?.(setting.id, state),
|
||||||
shown: getDrawerState?.(setting.id, shownByDefault) ?? shownByDefault
|
shown: getDrawerState?.(setting.id, shownByDefault) ?? shownByDefault
|
||||||
});
|
});
|
||||||
return React.createElement(Group, categoryProps);
|
|
||||||
}
|
}
|
||||||
return buildSetting(Object.assign({}, setting, {onChange: value => onChange(null, setting.id, value)}));
|
|
||||||
|
return buildSetting({
|
||||||
|
...setting,
|
||||||
|
onChange: value => {
|
||||||
|
setting?.onChange?.(value);
|
||||||
|
onChange(null, setting.id, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,11 @@ export default function Group({onChange, id, name, button, shown, onDrawerToggle
|
||||||
}, [id, onChange]);
|
}, [id, onChange]);
|
||||||
|
|
||||||
return <Drawer collapsible={collapsible} name={name} button={button} shown={shown} onDrawerToggle={onDrawerToggle} showDivider={showDivider}>
|
return <Drawer collapsible={collapsible} name={name} button={button} shown={shown} onDrawerToggle={onDrawerToggle} showDivider={showDivider}>
|
||||||
{settings.length && settings.filter(s => !s.hidden).map((setting) => {
|
{settings?.length > 0 && settings.filter(s => !s.hidden).map((setting) => {
|
||||||
const callback = value => change(setting.id, value);
|
const callback = value => {
|
||||||
|
setting?.onChange?.(value);
|
||||||
|
change(setting.id, value);
|
||||||
|
};
|
||||||
return buildSetting({...setting, onChange: callback});
|
return buildSetting({...setting, onChange: callback});
|
||||||
})}
|
})}
|
||||||
{children}
|
{children}
|
||||||
|
@ -42,5 +45,5 @@ export function buildSetting(setting) {
|
||||||
if (setting.type == "color") children = <Color disabled={setting.disabled} id={setting.id} value={setting.value} defaultValue={setting.defaultValue} colors={setting.colors} onChange={setting.onChange} />;
|
if (setting.type == "color") children = <Color disabled={setting.disabled} id={setting.id} value={setting.value} defaultValue={setting.defaultValue} colors={setting.colors} onChange={setting.onChange} />;
|
||||||
if (setting.type == "custom") children = setting.children;
|
if (setting.type == "custom") children = setting.children;
|
||||||
if (!children) return null;
|
if (!children) return null;
|
||||||
return <Item id={setting.id} inline={setting.hasOwnProperty("inline") ? setting.inline : setting.type !== "radio"} key={setting.id} name={setting.name} note={setting.note}>{children}</Item>;
|
return <Item id={setting.id} inline={setting.hasOwnProperty("inline") ? setting.inline : setting.type !== "radio" && setting.type !== "color"} key={setting.id} name={setting.name} note={setting.note}>{children}</Item>;
|
||||||
}
|
}
|
Loading…
Reference in New Issue