Skip to content
This repository has been archived by the owner on Oct 25, 2022. It is now read-only.

Commit

Permalink
feat: Ability to reset settings to default
Browse files Browse the repository at this point in the history
Settings sections now have a reset button to reset the section to the defaults currently set in the code.
This currently only applies to top-level sections. The actions on nested lists are no longer functional. These will be restored as nested panels are broken out into discrete components.
  • Loading branch information
oliversalzburg committed Oct 10, 2022
1 parent cb1a2db commit b697a71
Show file tree
Hide file tree
Showing 28 changed files with 366 additions and 79 deletions.
2 changes: 2 additions & 0 deletions packages/userscript/source/i18n/i18nData.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
"ui.maximum": "Maximum",
"ui.min": "Min: {0}",
"ui.options": "Options",
"ui.reset": "reset to defaults",
"ui.resources": "Resource Control",
"ui.space": "Space",
"ui.time": "Time",
Expand Down Expand Up @@ -340,6 +341,7 @@
"ui.maximum": "上限",
"ui.min": "Min: {0}",
"ui.options": "选项",
"ui.reset": "reset to defaults",
"ui.resources": "Resource Control",
"ui.space": "太空",
"ui.time": "时间",
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/userscript/source/options/Options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class Options {
const subject = {} as KittenStorageType;

subject.toggles = {
engine: settings.engine.enabled,
build: settings.bonfire.enabled,
space: settings.space.enabled,
craft: settings.workshop.enabled,
Expand Down
5 changes: 5 additions & 0 deletions packages/userscript/source/tools/Array.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ConstructorOf, is } from "./Maybe";

export const shuffleArray = <T>(array: Array<T>) => {
for (let index = array.length - 1; index > 0; index--) {
const targetIndex = Math.floor(Math.random() * (index + 1));
Expand All @@ -15,3 +17,6 @@ export const intersect = <T>(a: Array<T>, b: Array<T>) => {
export const difference = <T>(a: Array<T>, b: Array<T>) => {
return a.filter(x => !b.includes(x));
};

export const filterType = <T>(array: Array<unknown>, InstanceType: ConstructorOf<T>) =>
array.filter(element => is(element, InstanceType)) as Array<T>;
16 changes: 16 additions & 0 deletions packages/userscript/source/tools/Maybe.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
export type Nil = null | undefined;
export type Maybe<T> = T | Nil;

/**
* Describes a function that is a constructor for T.
*/
export type ConstructorOf<T = Record<string, unknown>> = new (...args: any[]) => T;

/**
* Check if something is a concrete value of the given type.
* Can be used as a typeguard.
*
* @param nilable The subject that could be nil.
* @param InstanceType The type to check against.
*/
export function is<T>(nilable: Maybe<T>, InstanceType: ConstructorOf<T>): nilable is T {
return !isNil(nilable) && nilable instanceof InstanceType;
}

/**
* Check if something is Nil.
* Can be used as a typeguard.
Expand Down
20 changes: 18 additions & 2 deletions packages/userscript/source/ui/BonfireSettingsUi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BonfireSettings } from "../options/BonfireSettings";
import { filterType } from "../tools/Array";
import { objectEntries } from "../tools/Entries";
import { ucfirst } from "../tools/Format";
import { mustExist } from "../tools/Maybe";
Expand All @@ -10,6 +11,7 @@ import { TriggerButton } from "./components/TriggerButton";
import { SettingsSectionUi } from "./SettingsSectionUi";

export class BonfireSettingsUi extends SettingsSectionUi {
protected readonly _items: Array<SettingListItem>;
private readonly _trigger: TriggerButton;
private readonly _settings: BonfireSettings;

Expand All @@ -24,7 +26,20 @@ export class BonfireSettingsUi extends SettingsSectionUi {
this._trigger = new TriggerButton(host, label, settings);
this._trigger.element.insertBefore(panel.list);

const optionButtons = [
this.panel._list.addEventListener("enableAll", () => {
this._items.forEach(item => (item.setting.enabled = true));
this.refreshUi();
});
this.panel._list.addEventListener("disableAll", () => {
this._items.forEach(item => (item.setting.enabled = false));
this.refreshUi();
});
this.panel._list.addEventListener("reset", () => {
this._settings.load(new BonfireSettings());
this.refreshUi();
});

const uiElements = [
new HeaderListItem(this._host, this._host.engine.i18n("$buildings.group.food")),
this._getBuildOption(
this._settings.items.field,
Expand Down Expand Up @@ -226,8 +241,9 @@ export class BonfireSettingsUi extends SettingsSectionUi {
true
),
];
this._items = filterType(uiElements, SettingListItem);

for (const item of optionButtons) {
for (const item of uiElements) {
panel.list.append(item.element);
}

Expand Down
23 changes: 20 additions & 3 deletions packages/userscript/source/ui/FilterSettingsUi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { SettingsPanel } from "./components/SettingsPanel";
import { SettingsSectionUi } from "./SettingsSectionUi";

export class FiltersSettingsUi extends SettingsSectionUi {
protected readonly _items: Array<SettingListItem>;
private readonly _settings: FilterSettings;

constructor(host: UserScript, settings: FilterSettings) {
Expand All @@ -18,6 +19,19 @@ export class FiltersSettingsUi extends SettingsSectionUi {

this._settings = settings;

this.panel._list.addEventListener("enableAll", () => {
this._items.forEach(item => (item.setting.enabled = true));
this.refreshUi();
});
this.panel._list.addEventListener("disableAll", () => {
this._items.forEach(item => (item.setting.enabled = false));
this.refreshUi();
});
this.panel._list.addEventListener("reset", () => {
this._settings.load(new FilterSettings());
this.refreshUi();
});

const buttons = [
{
name: "buildFilter" as const,
Expand Down Expand Up @@ -118,13 +132,16 @@ export class FiltersSettingsUi extends SettingsSectionUi {
false,
false,
[]
).element;
);

const optionButtons = buttons
this._items = buttons
.sort((a, b) => a.label.localeCompare(b.label))
.map(button => makeButton(button.option, button.label));

panel.list.append(optionButtons);
for (const item of this._items) {
panel.list.append(item.element);
}

panel.list.append(
new ExplainerListItem(this._host, "Disabled items are hidden from the log.").element
);
Expand Down
26 changes: 21 additions & 5 deletions packages/userscript/source/ui/OptionsSettingsUi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { SettingTriggerListItem } from "./components/SettingTriggerListItem";
import { SettingsSectionUi } from "./SettingsSectionUi";

export class OptionsSettingsUi extends SettingsSectionUi {
protected readonly _items: Array<SettingListItem>;
private readonly _settings: OptionsSettings;

constructor(host: UserScript, settings: OptionsSettings) {
Expand All @@ -19,7 +20,20 @@ export class OptionsSettingsUi extends SettingsSectionUi {

this._settings = settings;

const optionButtons = [
this.panel._list.addEventListener("enableAll", () => {
this._items.forEach(item => (item.setting.enabled = true));
this.refreshUi();
});
this.panel._list.addEventListener("disableAll", () => {
this._items.forEach(item => (item.setting.enabled = false));
this.refreshUi();
});
this.panel._list.addEventListener("reset", () => {
this._settings.load(new OptionsSettings());
this.refreshUi();
});

this._items = [
this._getOptionsOption(
this._settings.items.observe,
this._host.engine.i18n("option.observe")
Expand All @@ -32,17 +46,19 @@ export class OptionsSettingsUi extends SettingsSectionUi {
this._getOptionsOption(this._settings.items.fixCry, this._host.engine.i18n("option.fix.cry")),
];

panel.list.append(...optionButtons);
for (const item of this._items) {
panel.list.append(item.element);
}
}

private _getOptionsOption(option: OptionsSettingsItem, iname: string): JQuery<HTMLElement> {
private _getOptionsOption(option: OptionsSettingsItem, iname: string) {
const handler = {
onCheck: () => this._host.engine.imessage("status.sub.enable", [iname]),
onUnCheck: () => this._host.engine.imessage("status.sub.disable", [iname]),
};
return option.trigger
? new SettingTriggerListItem(this._host, iname, option as SettingTrigger, handler).element
: new SettingListItem(this._host, iname, option, handler).element;
? new SettingTriggerListItem(this._host, iname, option as SettingTrigger, handler)
: new SettingListItem(this._host, iname, option, handler);
}

setState(state: OptionsSettings): void {
Expand Down
20 changes: 18 additions & 2 deletions packages/userscript/source/ui/ReligionSettingsUi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ReligionSettings } from "../options/ReligionSettings";
import { filterType } from "../tools/Array";
import { objectEntries } from "../tools/Entries";
import { ucfirst } from "../tools/Format";
import { mustExist } from "../tools/Maybe";
Expand All @@ -12,6 +13,7 @@ import { TriggerButton } from "./components/TriggerButton";
import { SettingsSectionUi } from "./SettingsSectionUi";

export class ReligionSettingsUi extends SettingsSectionUi {
protected readonly _items: Array<SettingListItem>;
private readonly _trigger: TriggerButton;
private readonly _settings: ReligionSettings;

Expand All @@ -26,7 +28,20 @@ export class ReligionSettingsUi extends SettingsSectionUi {
this._trigger = new TriggerButton(host, label, settings);
this._trigger.element.insertBefore(panel.list);

const optionButtons = [
this.panel._list.addEventListener("enableAll", () => {
this._items.forEach(item => (item.setting.enabled = true));
this.refreshUi();
});
this.panel._list.addEventListener("disableAll", () => {
this._items.forEach(item => (item.setting.enabled = false));
this.refreshUi();
});
this.panel._list.addEventListener("reset", () => {
this._settings.load(new ReligionSettings());
this.refreshUi();
});

const uiElements = [
new HeaderListItem(this._host, this._host.engine.i18n("$religion.panel.ziggurat.label")),
this._getBuildOption(
this._settings.items.unicornPasture,
Expand Down Expand Up @@ -161,8 +176,9 @@ export class ReligionSettingsUi extends SettingsSectionUi {
true
),
];
this._items = filterType(uiElements, SettingListItem);

for (const item of optionButtons) {
for (const item of uiElements) {
panel.list.append(item.element);
}

Expand Down
33 changes: 19 additions & 14 deletions packages/userscript/source/ui/ResourcesSettingsUi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { ResourcesSettings, ResourcesSettingsItem } from "../options/ResourcesSe
import { objectEntries } from "../tools/Entries";
import { ucfirst } from "../tools/Format";
import { mustExist } from "../tools/Maybe";
import { Resource } from "../types";
import { UserScript } from "../UserScript";
import { SettingListItem } from "./components/SettingListItem";
import { SettingsPanel } from "./components/SettingsPanel";
import { SettingsSectionUi } from "./SettingsSectionUi";

export class ResourcesSettingsUi extends SettingsSectionUi {
protected readonly _items: Array<SettingListItem>;
private readonly _settings: ResourcesSettings;

constructor(host: UserScript, settings: ResourcesSettings) {
Expand All @@ -19,14 +19,24 @@ export class ResourcesSettingsUi extends SettingsSectionUi {
this._settings = settings;
$("input", panel.element).prop("disabled", true);

this.panel._list.addEventListener("enableAll", () => {
this._items.forEach(item => (item.setting.enabled = true));
this.refreshUi();
});
this.panel._list.addEventListener("disableAll", () => {
this._items.forEach(item => (item.setting.enabled = false));
this.refreshUi();
});
this.panel._list.addEventListener("reset", () => {
this._settings.load(new ResourcesSettings());
this.refreshUi();
});

// Add all the current resources
this._items = [];
for (const [name, item] of objectEntries(this._settings.items)) {
panel.list.append(
this._makeResourceSetting(
name,
ucfirst(this._host.engine.i18n(`$resources.${name}.title`)),
item
)
this._items.push(
this._makeResourceSetting(ucfirst(this._host.engine.i18n(`$resources.${name}.title`)), item)
);
}
}
Expand All @@ -35,16 +45,11 @@ export class ResourcesSettingsUi extends SettingsSectionUi {
* Creates a UI element that reflects stock and consume values for a given resource.
* This is currently only used for the craft section.
*
* @param name The resource.
* @param title The title to apply to the option.
* @param setting The option that is being controlled.
* @returns A new option with stock and consume values.
*/
private _makeResourceSetting(
name: Resource,
title: string,
setting: ResourcesSettingsItem
): JQuery<HTMLElement> {
private _makeResourceSetting(title: string, setting: ResourcesSettingsItem) {
const stock = setting.stock;

// The overall container for this resource item.
Expand Down Expand Up @@ -96,7 +101,7 @@ export class ResourcesSettingsUi extends SettingsSectionUi {
setting.$consume = consumeElement;
setting.$stock = stockElement;

return container.element;
return container;
}

setState(state: ResourcesSettings): void {
Expand Down
17 changes: 17 additions & 0 deletions packages/userscript/source/ui/ScienceSettingsUi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { SettingsPanel } from "./components/SettingsPanel";
import { SettingsSectionUi } from "./SettingsSectionUi";

export class ScienceSettingsUi extends SettingsSectionUi {
protected readonly _items: Array<SettingListItem>;
private readonly _settings: ScienceSettings;

constructor(host: UserScript, settings: ScienceSettings) {
Expand All @@ -17,12 +18,26 @@ export class ScienceSettingsUi extends SettingsSectionUi {

this._settings = settings;

this.panel._list.addEventListener("enableAll", () => {
this._items.forEach(item => (item.setting.enabled = true));
this.refreshUi();
});
this.panel._list.addEventListener("disableAll", () => {
this._items.forEach(item => (item.setting.enabled = false));
this.refreshUi();
});
this.panel._list.addEventListener("reset", () => {
this._settings.load(new ScienceSettings());
this.refreshUi();
});

// Technologies
const techsElement = new SettingsPanel(
this._host,
this._host.engine.i18n("ui.upgrade.techs"),
this._settings.techs
);
techsElement._list.resetButton.element.hide();

const techButtons = [];
for (const [techName, tech] of objectEntries(this._settings.techs.items)) {
Expand Down Expand Up @@ -61,6 +76,8 @@ export class ScienceSettingsUi extends SettingsSectionUi {
policyButtons.sort((a, b) => a.label.localeCompare(b.label));
policyButtons.forEach(button => policiesElement.list.append(button.button.element));

this._items = [policiesElement, techsElement];

panel.list.append(techsElement.element, policiesElement.element);
}

Expand Down
2 changes: 2 additions & 0 deletions packages/userscript/source/ui/SettingsSectionUi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ReligionSettingsItem } from "../options/ReligionSettings";
import { SettingMax } from "../options/Settings";
import { UserScript } from "../UserScript";
import { WorkshopManager } from "../WorkshopManager";
import { SettingListItem } from "./components/SettingListItem";
import { SettingMaxListItem } from "./components/SettingMaxListItem";
import { SettingsPanel } from "./components/SettingsPanel";

Expand All @@ -16,6 +17,7 @@ export type Toggleable = {
* This provides common functionality to help build the automation sections themselves.
*/
export abstract class SettingsSectionUi {
protected abstract readonly _items: Array<SettingListItem>;
protected _host: UserScript;
readonly element: JQuery<HTMLElement>;
readonly panel: SettingsPanel;
Expand Down

0 comments on commit b697a71

Please sign in to comment.