From 9d01f0f1691ec04a06bead7d9bf834c47c9a93d8 Mon Sep 17 00:00:00 2001 From: Terry Truong Date: Wed, 29 Jun 2022 17:32:14 +1000 Subject: Add saved-indicator to Settings Also, for range sliders, only save after user releases the slider --- src/App.vue | 11 +++++++---- src/components/SettingsModal.vue | 36 ++++++++++++++++++++++++++++++------ src/index.css | 13 +++++++++++++ 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 @@ + @input="onSettingChg('LYT', 'minTileSz', false)" @change="onSettingChg('LYT', 'minTileSz')" + name="minTileSizeInput" ref="minTileSzInput"/>
{{pxToDisplayStr(lytOpts.minTileSz)}}
+ @input="onSettingChg('LYT', 'maxTileSz', false)" @change="onSettingChg('LYT', 'maxTileSz')" + name="maxTileSizeInput" ref="maxTileSzInput"/>
{{pxToDisplayStr(lytOpts.maxTileSz)}}
+ @input="onSettingChg('LYT', 'tileSpacing', false)" @change="onSettingChg('LYT', 'tileSpacing')" + name="tileSpacingInput"/>
{{pxToDisplayStr(lytOpts.tileSpacing)}}
@@ -74,9 +77,14 @@ + @click="onReset"> Reset + +
+ Saved +
+
@@ -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; + } +} -- cgit v1.2.3