running-tools

A collection of tools for runners and their coaches
git clone https://git.ashermorgan.net/running-tools/
Log | Files | Refs | README

commit 7d5ebf4311c6dea52d92a78ce9abebaacfc740db
parent 28cbf3073facad24b591ae40c02f30ec8fb0618c
Author: ashermorgan <59518073+ashermorgan@users.noreply.github.com>
Date:   Mon, 13 Sep 2021 20:50:26 -0700

Implement default units

Default units determined by the user's BCP 47 language code

Diffstat:
Msrc/components/TargetTable.vue | 11++++++++---
Msrc/utils/units.js | 41+++++++++++++++++++++++++++++++++++++++++
Msrc/views/PaceCalculator.vue | 17++++++++---------
Msrc/views/RaceCalculator.vue | 10+++++-----
Msrc/views/UnitCalculator.vue | 10+++++-----
Mtests/unit/views/UnitCalculator.spec.js | 11+++++++----
6 files changed, 74 insertions(+), 26 deletions(-)

diff --git a/src/components/TargetTable.vue b/src/components/TargetTable.vue @@ -30,7 +30,7 @@ <td v-if="showPace" colspan="2"> {{ formatDuration(getPace(item), 0, 0) }} - / mi + / {{ distanceUnits[getDefaultDistanceUnit()].symbol }} </td> </tr> @@ -95,7 +95,7 @@ <tr> <td colspan="2"> <button title="Add Distance Target" @click="targets.push({ result: 'time', - distanceValue: 1, distanceUnit: 'miles' })" v-blur> + distanceValue: 1, distanceUnit: getDefaultDistanceUnit() })" v-blur> Add distance target </button> <button title="Add Time Target" @click="targets.push({ result: 'distance', @@ -189,6 +189,11 @@ export default { formatDuration: unitUtils.formatDuration, /** + * The getDefaultDistanceUnit method + */ + getDefaultDistanceUnit: unitUtils.getDefaultDistanceUnit, + + /** * Whether the table is in edit mode */ inEditMode: false, @@ -273,7 +278,7 @@ export default { */ getPace(result) { return result.time / unitUtils.convertDistance(result.distanceValue, result.distanceUnit, - 'miles'); + unitUtils.getDefaultDistanceUnit()); }, }, diff --git a/src/utils/units.js b/src/utils/units.js @@ -215,6 +215,42 @@ function formatDuration(value, padding = 6, digits = 2) { return result; } +/** + * Get the default unit system + * @returns {String} The default unit system + */ +function getDefaultUnitSystem() { + const language = navigator.language || navigator.userLanguage; + if (language.endsWith('-US') || language.endsWith('-MM')) { + return 'imperial'; + } + return 'metric'; +} + +/** + * Get the default distance unit + * @returns {String} The default distance unit + */ +function getDefaultDistanceUnit() { + return getDefaultUnitSystem() === 'metric' ? 'kilometers' : 'miles'; +} + +/** + * Get the default speed unit + * @returns {String} The default speed unit + */ +function getDefaultSpeedUnit() { + return getDefaultUnitSystem() === 'metric' ? 'kilometers_per_hour' : 'miles_per_hour'; +} + +/** + * Get the default pace unit + * @returns {String} The default pace unit + */ +function getDefaultPaceUnit() { + return getDefaultUnitSystem() === 'metric' ? 'seconds_per_kilometer' : 'seconds_per_mile'; +} + export default { TIME_UNITS, DISTANCE_UNITS, @@ -228,4 +264,9 @@ export default { convertSpeedPace, formatDuration, + + getDefaultUnitSystem, + getDefaultDistanceUnit, + getDefaultSpeedUnit, + getDefaultPaceUnit, }; diff --git a/src/views/PaceCalculator.vue b/src/views/PaceCalculator.vue @@ -47,17 +47,17 @@ export default { /** * The input distance value */ - inputDistance: 1, + inputDistance: 5, /** * The input distance unit */ - inputUnit: 'miles', + inputUnit: 'kilometers', /** * The input time value */ - inputTime: 8 * 60, + inputTime: 20 * 60, /** * The names of the distance units @@ -100,9 +100,8 @@ export default { { result: 'time', distanceValue: 0.5, distanceUnit: 'marathons' }, { result: 'time', distanceValue: 1, distanceUnit: 'marathons' }, - { result: 'distance', distanceUnit: 'miles', time: 600 }, - { result: 'distance', distanceUnit: 'miles', time: 1800 }, - { result: 'distance', distanceUnit: 'miles', time: 3600 }, + { result: 'distance', time: 600 }, + { result: 'distance', time: 1800 }, ], }; }, @@ -146,12 +145,12 @@ export default { // Calculate distance traveled in time at input pace let distance = paceUtils.getDistance(this.pace, target.time); - // Convert output distance into miles - distance = unitUtils.convertDistance(distance, 'meters', 'miles'); + // Convert output distance into default distance unit + distance = unitUtils.convertDistance(distance, 'meters', unitUtils.getDefaultDistanceUnit()); // Update result result.distanceValue = distance; - result.distanceUnit = 'miles'; + result.distanceUnit = unitUtils.getDefaultDistanceUnit(); } // Return result diff --git a/src/views/RaceCalculator.vue b/src/views/RaceCalculator.vue @@ -141,8 +141,8 @@ export default { { result: 'time', distanceValue: 0.5, distanceUnit: 'marathons' }, { result: 'time', distanceValue: 1, distanceUnit: 'marathons' }, - { result: 'distance', distanceUnit: 'miles', time: 600 }, - { result: 'distance', distanceUnit: 'miles', time: 3600 }, + { result: 'distance', time: 600 }, + { result: 'distance', time: 3600 }, ], }; }, @@ -217,12 +217,12 @@ export default { break; } - // Convert output distance into miles - distance = unitUtils.convertDistance(distance, 'meters', 'miles'); + // Convert output distance into default distance unit + distance = unitUtils.convertDistance(distance, 'meters', unitUtils.getDefaultDistanceUnit()); // Update result result.distanceValue = distance; - result.distanceUnit = 'miles'; + result.distanceUnit = unitUtils.getDefaultDistanceUnit(); } // Return result diff --git a/src/views/UnitCalculator.vue b/src/views/UnitCalculator.vue @@ -63,7 +63,7 @@ export default { /** * The unit of the output */ - outputUnit: 'meters', + outputUnit: 'kilometers', /** * The unit category @@ -140,7 +140,7 @@ export default { case 'distance': { this.inputValue = 1; this.inputUnit = 'miles'; - this.outputUnit = 'meters'; + this.outputUnit = 'kilometers'; break; } case 'time': { @@ -150,9 +150,9 @@ export default { break; } case 'speed_and_pace': { - this.inputValue = 1; - this.inputUnit = 'miles_per_hour'; - this.outputUnit = 'seconds_per_mile'; + this.inputValue = unitUtils.getDefaultPaceUnit() === 'seconds_per_mile' ? 600 : 300; + this.inputUnit = unitUtils.getDefaultPaceUnit(); + this.outputUnit = unitUtils.getDefaultSpeedUnit(); break; } default: { diff --git a/tests/unit/views/UnitCalculator.spec.js b/tests/unit/views/UnitCalculator.spec.js @@ -2,6 +2,7 @@ import { expect } from 'chai'; import { shallowMount } from '@vue/test-utils'; +import unitUtils from '@/utils/units'; import UnitCalculator from '@/views/UnitCalculator.vue'; describe('views/UnitCalculator.vue', () => { @@ -21,9 +22,11 @@ describe('views/UnitCalculator.vue', () => { await wrapper.setData({ category: 'speed_and_pace' }); // Assert controls are correct - expect(wrapper.vm._data.inputValue).to.equal(1); - expect(wrapper.vm._data.inputUnit).to.equal('miles_per_hour'); - expect(wrapper.vm._data.outputUnit).to.equal('seconds_per_mile'); + expect(wrapper.vm._data.inputValue).to.equal( + unitUtils.getDefaultPaceUnit() === 'seconds_per_mile' ? 600 : 300, + ); + expect(wrapper.vm._data.inputUnit).to.equal(unitUtils.getDefaultPaceUnit()); + expect(wrapper.vm._data.outputUnit).to.equal(unitUtils.getDefaultSpeedUnit()); // Change category await wrapper.setData({ category: 'distance' }); @@ -31,7 +34,7 @@ describe('views/UnitCalculator.vue', () => { // Assert controls are correct expect(wrapper.vm._data.inputValue).to.equal(1); expect(wrapper.vm._data.inputUnit).to.equal('miles'); - expect(wrapper.vm._data.outputUnit).to.equal('meters'); + expect(wrapper.vm._data.outputUnit).to.equal('kilometers'); }); it('outputValue should be correct', async () => {