aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/App.vue11
-rw-r--r--src/components/SettingsModal.vue36
-rw-r--r--src/index.css13
3 files changed, 50 insertions, 10 deletions
diff --git a/src/App.vue b/src/App.vue
index 1937997..fa8ddcd 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -720,20 +720,23 @@ export default defineComponent({
this.resetMode();
this.settingsOpen = true;
},
- async onSettingChg(optionType: OptionType, option: string){
+ async onSettingChg(optionType: OptionType, option: string, save = true){
// Save in localStorage
if (optionType == 'LYT'){
- localStorage.setItem(`${optionType} ${option}`, String(this.lytOpts[option as keyof LayoutOptions]));
+ if (save){
+ localStorage.setItem(`${optionType} ${option}`, String(this.lytOpts[option as keyof LayoutOptions]));
+ }
this.relayoutWithCollapse();
} else if (optionType == 'UI') {
- localStorage.setItem(`${optionType} ${option}`, String(this.uiOpts[option as keyof UiOptions]));
+ if (save){
+ localStorage.setItem(`${optionType} ${option}`, String(this.uiOpts[option as keyof UiOptions]));
+ }
if (option == 'useReducedTree'){
this.onTreeChange();
}
} else {
throw new Error(`Unexpected setting: ${optionType}, ${option}`);
}
- console.log(`Saved setting: ${optionType}, ${option}`);
},
async onTreeChange(){
if (this.activeRoot != this.layoutTree){
diff --git a/src/components/SettingsModal.vue b/src/components/SettingsModal.vue
index cbbe084..58da129 100644
--- a/src/components/SettingsModal.vue
+++ b/src/components/SettingsModal.vue
@@ -33,17 +33,20 @@
<!-- Row 1 -->
<label for="minTileSizeInput">Min Tile Size</label>
<input type="range" min="0" max="400" v-model.number="lytOpts.minTileSz"
- @input="onSettingChg('LYT', 'minTileSz')" name="minTileSizeInput" ref="minTileSzInput"/>
+ @input="onSettingChg('LYT', 'minTileSz', false)" @change="onSettingChg('LYT', 'minTileSz')"
+ name="minTileSizeInput" ref="minTileSzInput"/>
<div class="my-auto text-right">{{pxToDisplayStr(lytOpts.minTileSz)}}</div>
<!-- Row 2 -->
<label for="maxTileSizeInput">Max Tile Size</label>
<input type="range" min="0" max="400" v-model.number="lytOpts.maxTileSz"
- @input="onSettingChg('LYT', 'maxTileSz')" name="maxTileSizeInput" ref="maxTileSzInput"/>
+ @input="onSettingChg('LYT', 'maxTileSz', false)" @change="onSettingChg('LYT', 'maxTileSz')"
+ name="maxTileSizeInput" ref="maxTileSzInput"/>
<div class="my-auto text-right">{{pxToDisplayStr(lytOpts.maxTileSz)}}</div>
<!-- Row 3 -->
<label for="tileSpacingInput">Tile Spacing</label>
<input type="range" min="0" max="20" v-model.number="lytOpts.tileSpacing"
- @input="onSettingChg('LYT', 'tileSpacing')" name="tileSpacingInput"/>
+ @input="onSettingChg('LYT', 'tileSpacing', false)" @change="onSettingChg('LYT', 'tileSpacing')"
+ name="tileSpacingInput"/>
<div class="my-auto text-right">{{pxToDisplayStr(lytOpts.tileSpacing)}}</div>
</div>
</div>
@@ -74,9 +77,14 @@
</div>
</div>
<s-button class="mx-auto mt-2" :style="{color: uiOpts.textColor, backgroundColor: uiOpts.bgColor}"
- @click="$emit('reset')">
+ @click="onReset">
Reset
</s-button>
+ <transition name="fade">
+ <div v-if="saved" class="absolute right-1 bottom-1" ref="saveIndicator">
+ Saved
+ </div>
+ </transition>
</div>
</div>
</template>
@@ -97,6 +105,7 @@ export default defineComponent({
return {
sweepLeaves: this.lytOpts.layoutType == 'sweep',
// For making only two of 'layoutType's values available for user selection
+ saved: false, // Set to true after a setting is saved
};
},
computed: {
@@ -119,7 +128,7 @@ export default defineComponent({
this.$emit('close');
}
},
- onSettingChg(optionType: OptionType, option: string){
+ onSettingChg(optionType: OptionType, option: string, save = true){
// Maintain min/max-tile-size consistency
if (optionType == 'LYT' && (option == 'minTileSz' || option == 'maxTileSz')){
let minInput = this.$refs.minTileSzInput as HTMLInputElement;
@@ -131,7 +140,22 @@ export default defineComponent({
}
}
//
- this.$emit('setting-chg', optionType, option);
+ this.$emit('setting-chg', optionType, option, save);
+ if (save){
+ // Make saved-indicator appear/animate
+ if (!this.saved){
+ this.saved = true;
+ } else {
+ let el = this.$refs.saveIndicator as HTMLDivElement;
+ el.classList.remove('animate-flash-green');
+ el.offsetWidth; // Triggers reflow
+ el.classList.add('animate-flash-green');
+ }
+ }
+ },
+ onReset(){
+ this.$emit('reset');
+ this.saved = false;
},
pxToDisplayStr(px: number): string {
return (px / 3.78).toFixed() + ' mm';
diff --git a/src/index.css b/src/index.css
index c3e9ac7..ffd7dda 100644
--- a/src/index.css
+++ b/src/index.css
@@ -75,3 +75,16 @@ body {
background-color: transparent;
}
}
+.animate-flash-green {
+ animation-name: flash-green;
+ animation-duration: 700ms;
+ animation-timing-function: ease-in;
+}
+@keyframes flash-green {
+ from {
+ color: lawngreen;
+ }
+ to {
+ color: inherit;
+ }
+}