Skip to content

Commit

Permalink
Implement useStorage composable
Browse files Browse the repository at this point in the history
  • Loading branch information
ashermorgan committed May 27, 2024
1 parent b490ff7 commit baf7d08
Show file tree
Hide file tree
Showing 12 changed files with 142 additions and 398 deletions.
3 changes: 1 addition & 2 deletions src/components/TargetSetSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@
</template>

<script setup>
import { nextTick, onActivated, ref, watch } from 'vue';
import { nextTick, ref, watch } from 'vue';
import VueFeather from 'vue-feather';
import storage from '@/utils/localStorage';
import targetUtils from '@/utils/targets';
import TargetEditor from '@/components/TargetEditor.vue';
Expand Down
36 changes: 36 additions & 0 deletions src/composables/useStorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ref, onActivated, watchEffect } from 'vue';

// The global localStorage prefix
const prefix = 'running-tools';

/*
* Create a reactive value that is synced with a localStorage item
* @param {String} key The localStorage item's key
* @defaultValue {Object} defaultValue The default value
*/
export default function useStorage(key, defaultValue) {
const clonedDefault = JSON.parse(JSON.stringify(defaultValue));
const value = ref(clonedDefault);

// (Re)load value from localStorage
function updateValue() {
let parsedValue;
try {
parsedValue = JSON.parse(localStorage.getItem(`${prefix}.${key}`));
} catch {
parsedValue = null;
}
if (parsedValue !== null) value.value = parsedValue;
}
updateValue();
onActivated(updateValue);

// Save value to localStorage when modified
watchEffect(() => {
if (typeof localStorage !== 'undefined') {
localStorage.setItem(`${prefix}.${key}`, JSON.stringify(value.value));
}
})

return value
}
40 changes: 0 additions & 40 deletions src/utils/localStorage.js

This file was deleted.

78 changes: 9 additions & 69 deletions src/views/PaceCalculator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,9 @@
</template>

<script setup>
import { computed, onActivated, ref, watch } from 'vue';
import { computed } from 'vue';
import paceUtils from '@/utils/paces';
import storage from '@/utils/localStorage';
import targetUtils from '@/utils/targets';
import unitUtils from '@/utils/units';
Expand All @@ -55,81 +54,37 @@ import SimpleTargetTable from '@/components/SimpleTargetTable.vue';
import TargetSetSelector from '@/components/TargetSetSelector.vue';
import TimeInput from '@/components/TimeInput.vue';
import useStorage from '@/composables/useStorage';
/**
* The input distance value
*/
const inputDistance = ref(storage.get('pace-calculator-input-distance', 5));
const inputDistance = useStorage('pace-calculator-input-distance', 5);
/**
* The input distance unit
*/
const inputUnit = ref(storage.get('pace-calculator-input-unit', 'kilometers'));
const inputUnit = useStorage('pace-calculator-input-unit', 'kilometers');
/**
* The input time value
*/
const inputTime = ref(storage.get('pace-calculator-input-time', 20 * 60));
const inputTime = useStorage('pace-calculator-input-time', 20 * 60);
/**
* The default unit system
*
* Loaded in onActivated() hook
*/
const defaultUnitSystem = ref(null);
const defaultUnitSystem = useStorage('default-unit-system', unitUtils.detectDefaultUnitSystem());
/**
* The current selected target set
*/
const selectedTargetSet = ref(storage.get('pace-calculator-target-set', '_pace_targets'));
const selectedTargetSet = useStorage('pace-calculator-target-set', '_pace_targets');
/**
* The target sets
*
* Loaded in onActivated() hook
*/
const targetSets = ref({});
/**
* Save input distance value
*/
watch(inputDistance, (newValue) => {
storage.set('pace-calculator-input-distance', newValue);
});
/**
* Save input distance unit
*/
watch(inputUnit, (newValue) => {
storage.set('pace-calculator-input-unit', newValue);
});
/**
* Save input time value
*/
watch(inputTime, (newValue) => {
storage.set('pace-calculator-input-time', newValue);
});
/**
* Save default unit system
*/
watch(defaultUnitSystem, (newValue) => {
storage.set('default-unit-system', newValue);
});
/**
* Save the current selected target set
*/
watch(selectedTargetSet, (newValue) => {
storage.set('pace-calculator-target-set', newValue);
});
/**
* Save target sets
*/
watch(targetSets, (newValue) => {
storage.set('target-sets', newValue);
}, { deep: true });
const targetSets = useStorage('target-sets', targetUtils.defaultTargetSets);
/**
* The input pace (in seconds per meter)
Expand All @@ -139,13 +94,6 @@ const pace = computed(() => {
return paceUtils.getPace(distance, inputTime.value);
});
/**
* Reload the target sets
*/
function reloadTargets() {
targetSets.value = storage.get('target-sets', targetUtils.defaultTargetSets);
}
/**
* Calculate paces from a target
* @param {Object} target The target
Expand Down Expand Up @@ -186,14 +134,6 @@ function calculatePace(target) {
// Return result
return result;
}
/**
* (Re)load settings used in multiple calculators
*/
onActivated(() => {
reloadTargets();
defaultUnitSystem.value = storage.get('default-unit-system', unitUtils.detectDefaultUnitSystem());
});
</script>

<style scoped>
Expand Down
96 changes: 11 additions & 85 deletions src/views/RaceCalculator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,10 @@
</template>

<script setup>
import { computed, onActivated, ref, watch } from 'vue';
import { computed } from 'vue';
import formatUtils from '@/utils/format';
import raceUtils from '@/utils/races';
import storage from '@/utils/localStorage';
import targetUtils from '@/utils/targets';
import unitUtils from '@/utils/units';
Expand All @@ -87,56 +86,47 @@ import SimpleTargetTable from '@/components/SimpleTargetTable.vue';
import TargetSetSelector from '@/components/TargetSetSelector.vue';
import TimeInput from '@/components/TimeInput.vue';
import useStorage from '@/composables/useStorage';
/**
* The input distance value
*/
const inputDistance = ref(storage.get('race-calculator-input-distance', 5));
const inputDistance = useStorage('race-calculator-input-distance', 5);
/**
* The input distance unit
*/
const inputUnit = ref(storage.get('race-calculator-input-unit', 'kilometers'));
const inputUnit = useStorage('race-calculator-input-unit', 'kilometers');
/**
* The input time value
*/
const inputTime = ref(storage.get('race-calculator-input-time', 20 * 60));
const inputTime = useStorage('race-calculator-input-time', 20 * 60);
/**
* The default unit system
*
* Loaded in onActivated() hook
*/
const defaultUnitSystem = ref(null);
const defaultUnitSystem = useStorage('default-unit-system', unitUtils.detectDefaultUnitSystem());
/**
* The race prediction model
*/
const model = ref(storage.get('race-calculator-model', 'AverageModel'));
const model = useStorage('race-calculator-model', 'AverageModel');
/**
* The value of the exponent in Riegel's Model
*/
const riegelExponent = ref(storage.get('race-calculator-riegel-exponent', 1.06));
const riegelExponent = useStorage('race-calculator-riegel-exponent', 1.06);
/**
* The current selected target set
*/
const selectedTargetSet = ref(storage.get('race-calculator-target-set', '_race_targets'));
const selectedTargetSet = useStorage('race-calculator-target-set', '_race_targets');
/**
* The target sets
*
* Loaded in onActivated() hook
*/
let targetSets = ref({});
/**
* Reload the target sets
*/
function reloadTargets() {
targetSets.value = storage.get('target-sets', targetUtils.defaultTargetSets);
}
let targetSets = useStorage('target-sets', targetUtils.defaultTargetSets);
/**
* Predict race results from a target
Expand Down Expand Up @@ -258,70 +248,6 @@ const vo2Percentage = computed(() => {
const result = raceUtils.VO2MaxModel.getVO2Percentage(inputTime.value) * 100;
return result;
});
/**
* Save input distance value
*/
watch(inputDistance, (newValue) => {
storage.set('race-calculator-input-distance', newValue);
});
/**
* Save input distance unit
*/
watch(inputUnit, (newValue) => {
storage.set('race-calculator-input-unit', newValue);
});
/**
* Save input time value
*/
watch(inputTime, (newValue) => {
storage.set('race-calculator-input-time', newValue);
});
/**
* Save default unit system
*/
watch(defaultUnitSystem, (newValue) => {
storage.set('default-unit-system', newValue);
});
/**
* Save prediction model
*/
watch(model, (newValue) => {
storage.set('race-calculator-model', newValue);
});
/**
* Save Riegel Model exponent
*/
watch(riegelExponent, (newValue) => {
storage.set('race-calculator-riegel-exponent', newValue);
});
/**
* Save the current selected target set
*/
watch(selectedTargetSet, (newValue) => {
storage.set('race-calculator-target-set', newValue);
});
/**
* Save target sets
*/
watch(targetSets, (newValue) => {
storage.set('target-sets', newValue);
}, { deep: true });
/**
* (Re)load settings used in multiple calculators
*/
onActivated(() => {
reloadTargets();
defaultUnitSystem.value = storage.get('default-unit-system', unitUtils.detectDefaultUnitSystem());
});
</script>

<style scoped>
Expand Down
Loading

0 comments on commit baf7d08

Please sign in to comment.