Clean up multiworld preset handling
This commit is contained in:
@@ -1,16 +1,25 @@
|
||||
<script>
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent } from "vue";
|
||||
import { mapState, mapActions } from "pinia";
|
||||
|
||||
import localforage from "localforage";
|
||||
import settingsData from "@/data/settings.yaml";
|
||||
import generatorSettings from "@/data/generator-settings.yaml";
|
||||
import presets from "@/data/presets.yaml";
|
||||
import usePresetStore from "@/stores/preset.js";
|
||||
|
||||
function settingsMatch(settings, preset) {
|
||||
for (const settingName of Object.keys(settings)) {
|
||||
if (settingName == "player_name") {
|
||||
continue;
|
||||
}
|
||||
if (preset[settingName] != settings[settingName]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
selected: "custom",
|
||||
localPresets: [],
|
||||
};
|
||||
},
|
||||
emits: [
|
||||
@@ -19,79 +28,45 @@ export default defineComponent({
|
||||
],
|
||||
props: {
|
||||
generator: null,
|
||||
},
|
||||
async mounted() {
|
||||
this.localPresets = await localforage.getItem(`local_presets_${this.generator}`) ?? [];
|
||||
for (const preset of this.localPresets) {
|
||||
this.fillPreset(preset);
|
||||
}
|
||||
await this.updateLocalPresets();
|
||||
prefix: null,
|
||||
},
|
||||
computed: {
|
||||
settings() {
|
||||
const settings = {};
|
||||
for (const name of Object.keys(generatorSettings[this.generator])) {
|
||||
var generatorValue = generatorSettings[this.generator][name]
|
||||
if (generatorValue == "all") {
|
||||
settings[name] = settingsData[name];
|
||||
} else if (Array.isArray(generatorValue)) {
|
||||
const { values, ...newObj } = settingsData[this.name];
|
||||
newObj.values = {};
|
||||
for (const value of generatorValue) {
|
||||
newObj.values[value] = values[value];
|
||||
}
|
||||
settings[name] = newObj;
|
||||
} else {
|
||||
settings[name] = generatorValue;
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
...mapState(usePresetStore, {
|
||||
allGlobalPresets: "globalPresets",
|
||||
allLocalPresets: "localPresets",
|
||||
}),
|
||||
globalPresets() {
|
||||
return this.allGlobalPresets[this.generator];
|
||||
},
|
||||
presets() {
|
||||
const filledPresets = {};
|
||||
if (presets[this.generator]) {
|
||||
for (const presetName of Object.keys(presets[this.generator])) {
|
||||
const preset = JSON.parse(JSON.stringify(presets[this.generator][presetName]));
|
||||
this.fillPreset(preset);
|
||||
filledPresets[presetName] = preset;
|
||||
}
|
||||
}
|
||||
return filledPresets;
|
||||
localPresets() {
|
||||
return this.allLocalPresets[this.generator];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(usePresetStore, ["deleteLocalPreset", "saveLocalPreset"]),
|
||||
change() {
|
||||
if (this.selected && this.selected != "custom") {
|
||||
if (this.selected.startsWith("local_")) {
|
||||
this.$emit("selected", this.localPresets[this.selected.substring(6)]);
|
||||
} else {
|
||||
this.$emit("selected", this.presets[this.selected]);
|
||||
this.$emit("selected", this.globalPresets[this.selected]);
|
||||
}
|
||||
}
|
||||
},
|
||||
settingsMatch(newSettings, preset) {
|
||||
for (const settingName of Object.keys(newSettings)) {
|
||||
if (settingName == "player_name") {
|
||||
continue;
|
||||
}
|
||||
if (preset[settingName] != newSettings[settingName]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
settingChanged(newSettings) {
|
||||
for (const presetName of Object.keys(this.presets)) {
|
||||
const preset = this.presets[presetName];
|
||||
if (this.settingsMatch(newSettings, preset)) {
|
||||
for (const presetName of Object.keys(this.globalPresets)) {
|
||||
const preset = this.globalPresets[presetName];
|
||||
if (settingsMatch(newSettings, preset)) {
|
||||
this.selected = presetName;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const [idx, preset] of this.localPresets.entries()) {
|
||||
if (this.settingsMatch(newSettings, preset)) {
|
||||
this.selected = `local_${idx}`;
|
||||
return;
|
||||
if (this.localPresets) {
|
||||
for (const [idx, preset] of this.localPresets.entries()) {
|
||||
if (settingsMatch(newSettings, preset)) {
|
||||
this.selected = `local_${idx}`;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.selected = "custom";
|
||||
@@ -101,31 +76,12 @@ export default defineComponent({
|
||||
},
|
||||
async deleteClicked() {
|
||||
const idx = this.selected.substring(6);
|
||||
this.localPresets.splice(idx, 1);
|
||||
this.selected = "custom";
|
||||
await this.updateLocalPresets();
|
||||
await this.deleteLocalPreset(this.generator, idk);
|
||||
},
|
||||
async savePreset(idx, settings) {
|
||||
if (idx == null) {
|
||||
idx = this.localPresets.length;
|
||||
this.localPresets.push(settings);
|
||||
} else {
|
||||
this.localPresets[idx] = settings;
|
||||
}
|
||||
async savePreset(idx, preset) {
|
||||
idx = await this.saveLocalPreset(this.generator, idx, preset);
|
||||
this.selected = `local_${idx}`;
|
||||
await this.updateLocalPresets();
|
||||
},
|
||||
async updateLocalPresets() {
|
||||
const copy = JSON.parse(JSON.stringify(this.localPresets));
|
||||
await localforage.setItem(`local_presets_${this.generator}`, copy);
|
||||
},
|
||||
fillPreset(preset) {
|
||||
for (const settingName of Object.keys(this.settings)) {
|
||||
if (preset[settingName] == undefined) {
|
||||
preset[settingName] = this.settings[settingName].default;
|
||||
}
|
||||
}
|
||||
return preset;
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -139,13 +95,13 @@ export default defineComponent({
|
||||
<select v-model="selected" class="form-select" id="presetSelector" @change="change">
|
||||
<option disabled="true" value="custom">Custom</option>
|
||||
<optgroup label="Global Presets">
|
||||
<template v-for="name of Object.keys(presets)">
|
||||
<template v-for="name of Object.keys(globalPresets)">
|
||||
<option :value="name">
|
||||
{{ presets[name].display }}
|
||||
{{ globalPresets[name].display }}
|
||||
</option>
|
||||
</template>
|
||||
</optgroup>
|
||||
<optgroup v-if="localPresets.length" label="Local Presets">
|
||||
<optgroup v-if="localPresets && localPresets.length" label="Local Presets">
|
||||
<template v-for="(preset, idx) of localPresets">
|
||||
<option :value="`local_${idx}`">
|
||||
{{ preset.display }}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import { mapActions } from "pinia";
|
||||
|
||||
import axios from "axios";
|
||||
import { Modal } from "bootstrap";
|
||||
@@ -10,6 +11,8 @@ import AccordionItem from "@/components/AccordionItem.vue";
|
||||
import PresetPicker from "@/components/PresetPicker.vue";
|
||||
import SettingPicker from "@/components/SettingPicker.vue";
|
||||
|
||||
import usePresetStore from "@/stores/preset.js";
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
AccordionItem,
|
||||
@@ -38,8 +41,10 @@ export default defineComponent({
|
||||
return generatorSettings[this.generator];
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.modal = new Modal(document.getElementById("savePresetModal"), {});
|
||||
async mounted() {
|
||||
this.modal = new Modal(this.$refs.savePresetModal, {});
|
||||
await this.fetchLocalPresets();
|
||||
this.$refs.preset.settingChanged(this.set);
|
||||
},
|
||||
watch: {
|
||||
set: {
|
||||
@@ -51,6 +56,7 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(usePresetStore, ["fetchLocalPresets"]),
|
||||
async generate(race) {
|
||||
const settings = {
|
||||
randomizer: this.generator,
|
||||
@@ -94,7 +100,7 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="modal" tabindex="-1" id="savePresetModal">
|
||||
<div class="modal" tabindex="-1" ref="savePresetModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@@ -137,7 +143,7 @@ export default defineComponent({
|
||||
<div id="settings" class="accordion accordion-flush">
|
||||
<AccordionItem>
|
||||
<PresetPicker ref="preset" :generator="generator" @selected="presetSelected"
|
||||
@save="savePreset" />
|
||||
@save="savePreset" :prefix="prefix" />
|
||||
</AccordionItem>
|
||||
<AccordionItem :expanded="true">
|
||||
<template #header>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createApp } from "vue";
|
||||
import { createPinia } from "pinia";
|
||||
import App from "./App.vue";
|
||||
import router from "./router";
|
||||
|
||||
@@ -14,8 +15,10 @@ import "./assets/main.css";
|
||||
import axios from "axios";
|
||||
axios.defaults.baseURL = import.meta.env.VITE_BACKEND_URL;
|
||||
|
||||
const app = createApp(App)
|
||||
const pinia = createPinia();
|
||||
const app = createApp(App);
|
||||
|
||||
app.use(router)
|
||||
app.use(router);
|
||||
app.use(pinia);
|
||||
|
||||
app.mount('#app')
|
||||
app.mount('#app');
|
||||
|
||||
104
src/stores/preset.js
Normal file
104
src/stores/preset.js
Normal file
@@ -0,0 +1,104 @@
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
import localforage from "localforage";
|
||||
import settingsData from "@/data/settings.yaml";
|
||||
import generatorSettings from "@/data/generator-settings.yaml";
|
||||
import presets from "@/data/presets.yaml";
|
||||
|
||||
function fillPreset(preset, settings) {
|
||||
for (const settingName of Object.keys(settings)) {
|
||||
if (preset[settingName] == undefined) {
|
||||
preset[settingName] = settings[settingName].default;
|
||||
}
|
||||
}
|
||||
return preset;
|
||||
}
|
||||
|
||||
export default defineStore("preset", {
|
||||
state() {
|
||||
return {
|
||||
localPresets: {},
|
||||
};
|
||||
},
|
||||
getters: {
|
||||
settings() {
|
||||
const settings = {};
|
||||
for (const generator of Object.keys(generatorSettings)) {
|
||||
settings[generator] = {};
|
||||
|
||||
for (const name of Object.keys(generatorSettings[generator])) {
|
||||
var generatorValue = generatorSettings[generator][name];
|
||||
if (generatorValue == "all") {
|
||||
settings[generator][name] = settingsData[name];
|
||||
} else if (Array.isArray(generatorValue)) {
|
||||
const { values, ...newObj } = settingsData[name];
|
||||
newObj.values = {};
|
||||
for (const value of generatorValue) {
|
||||
newObj.values[value] = values[value];
|
||||
}
|
||||
settings[generator][name] = newObj;
|
||||
} else {
|
||||
settings[generator][name] = generatorValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
},
|
||||
globalPresets() {
|
||||
const filledPresets = {};
|
||||
for (const generator of Object.keys(generatorSettings)) {
|
||||
filledPresets[generator] = {};
|
||||
if (presets[generator]) {
|
||||
for (const presetName of Object.keys(presets[generator])) {
|
||||
const preset = { ...presets[generator][presetName] };
|
||||
fillPreset(preset, this.settings[generator]);
|
||||
filledPresets[generator][presetName] = preset;
|
||||
}
|
||||
}
|
||||
}
|
||||
return filledPresets;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async fetchLocalPresets() {
|
||||
for (const generator of Object.keys(generatorSettings)) {
|
||||
if (this.localPresets[generator]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.cacheLocalPresets(generator);
|
||||
}
|
||||
},
|
||||
async cacheLocalPresets(generator) {
|
||||
var generatorPresets = await localforage.getItem(`local_presets_${generator}`);
|
||||
|
||||
if (!Array.isArray(generatorPresets)) {
|
||||
generatorPresets = [];
|
||||
}
|
||||
|
||||
for (const preset of generatorPresets) {
|
||||
fillPreset(preset, this.settings[generator]);
|
||||
}
|
||||
this.localPresets[generator] = generatorPresets;
|
||||
await this.saveLocalPresets(generator);
|
||||
},
|
||||
async deleteLocalPreset(generator, index) {
|
||||
this.localPresets[generator].splice(index, 1);
|
||||
await this.saveLocalPresets(generator);
|
||||
},
|
||||
async saveLocalPreset(generator, index, preset) {
|
||||
if (index == null) {
|
||||
index = this.localPresets[generator].length;
|
||||
this.localPresets[generator].push(preset);
|
||||
} else {
|
||||
this.localPresets[generator][index] = preset;
|
||||
}
|
||||
await this.saveLocalPresets(generator);
|
||||
return index;
|
||||
},
|
||||
async saveLocalPresets(generator) {
|
||||
const copy = JSON.parse(JSON.stringify(this.localPresets[generator]));
|
||||
await localforage.setItem(`local_presets_${generator}`, copy);
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -3,7 +3,7 @@ import { defineComponent } from "vue";
|
||||
|
||||
import axios from "axios";
|
||||
import localforage from "localforage";
|
||||
import { Modal } from "bootstrap";
|
||||
import { Tab } from "bootstrap";
|
||||
|
||||
import SettingsPage from "@/components/SettingsPage.vue";
|
||||
|
||||
@@ -28,6 +28,7 @@ export default defineComponent({
|
||||
|
||||
for (var i = 0; i < this.worldCount; i++) {
|
||||
this.worlds[i].player_name = await localforage.getItem(`${this.prefix}world_${i + 1}_setting_player_name`);
|
||||
new Tab(this.$refs.tabs[i]);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -36,12 +37,17 @@ export default defineComponent({
|
||||
this.worlds.push({player_name: newname});
|
||||
this.worldCount++;
|
||||
|
||||
await this.$nextTick();
|
||||
Tab.getOrCreateInstance(this.$refs.tabs[this.worldCount - 1]).show();
|
||||
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
this.worlds[this.worldCount - 1].player_name = newname;
|
||||
},
|
||||
async removeWorld() {
|
||||
this.worldCount--;
|
||||
this.worlds.pop();
|
||||
await this.$nextTick();
|
||||
Tab.getOrCreateInstance(this.$refs.tabs[this.worldCount - 1]).show();
|
||||
},
|
||||
async playerNameUpdated(num) {
|
||||
await localforage.setItem(`${this.prefix}world_${num + 1}_setting_player_name`, this.worlds[num].player_name);
|
||||
@@ -83,17 +89,18 @@ export default defineComponent({
|
||||
<ul class="nav nav-tabs ps-3 pt-3 pe-3">
|
||||
<li v-for="(n, idx) in worldCount" class="nav-item" role="presentation">
|
||||
<button class="nav-link" :class="{active: idx == 0}" data-bs-toggle="tab"
|
||||
:data-bs-target="`#world_page_${n}`" type="button" role="tab">
|
||||
:data-bs-target="`#world_page_${n}`" type="button" role="tab" ref="tabs">
|
||||
<template v-if="worlds[idx] && worlds[idx].player_name && worlds[idx].player_name.length">
|
||||
{{ worlds[idx].player_name }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ n }}
|
||||
</template>
|
||||
<button v-if="n == worldCount && n > 2" @click="removeWorld"
|
||||
class="badge btn rounded-pill text-bg-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
<div v-if="n == worldCount && n > 2" class="delete-player-button">
|
||||
<button @click="removeWorld" class="badge btn rounded-pill text-bg-danger">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</button>
|
||||
</li>
|
||||
<button class="nav-link" type="button" role="tab" @click="addWorld">
|
||||
@@ -132,3 +139,10 @@ export default defineComponent({
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.delete-player-button {
|
||||
display: inline;
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user