feat(prefs): drop redundant unit-override; distances auto m/ft under a km/mi, else km/mi
All checks were successful
CI / test-and-build (push) Successful in 41s
All checks were successful
CI / test-and-build (push) Successful in 41s
This commit is contained in:
parent
149d7942dd
commit
f46d604546
15
README.md
15
README.md
@ -224,9 +224,12 @@ The matcher:
|
||||
|
||||
## Preferences & Units
|
||||
|
||||
Click **⚙ Preferences** in the top bar to choose **Metric** or **Imperial** units.
|
||||
Your choice (and the granular unit override) is saved to `localStorage`, so it
|
||||
persists across reloads and is shared by the Directions panel.
|
||||
Click **⚙ Preferences** in the top bar to choose the **unit system** — **Metric**
|
||||
or **Imperial**. The choice is saved to `localStorage`, so it persists across
|
||||
reloads and is shared by the Directions panel.
|
||||
|
||||
Units are auto-selected within the chosen system: **m/ft under a kilometer/mile,
|
||||
otherwise km/mi** (e.g. `820 m`, `1.9 km`; `900 ft`, `1.2 mi`).
|
||||
|
||||
## Directions & Routing
|
||||
|
||||
@ -237,9 +240,9 @@ button appears in the top bar. Opening it lets you:
|
||||
- **Avoid certain POI categories** along the route (schools, fire stations,
|
||||
fuel stations, parking, restaurants, …).
|
||||
- **Compute** a route and **draw it** on the map.
|
||||
- Choose a **unit system** (Metric or Imperial) and **units** (`m`/`km` or
|
||||
`ft`/`mi`, or `Auto` — which uses the small unit for short routes and the
|
||||
large one for long routes), plus a **travel mode** (Drive or Walk).
|
||||
- Choose a **unit system** (Metric or Imperial; distances auto-switch between
|
||||
m/ft and km/mi at the km/mile boundary), plus a **travel mode** (Drive or
|
||||
Walk).
|
||||
- See the route's **distance** and an **estimated travel time** (computed from
|
||||
the mode's average speed).
|
||||
- **Turn-by-turn directions** (*Head north*, *Turn right*, *Arrive at destination*,
|
||||
|
||||
@ -42,45 +42,28 @@
|
||||
];
|
||||
const selected = $state<Record<string, boolean>>({});
|
||||
|
||||
// Format a metric distance (meters) into the chosen unit system.
|
||||
function formatDistance(m: number): string {
|
||||
if ($prefs.system === 'imperial') {
|
||||
// Format a metric distance (meters) for a given unit system, auto-selecting
|
||||
// the small/large unit: use ft/m under a mile/km, otherwise mi/km.
|
||||
function fmtFor(m: number, sys: 'metric' | 'imperial'): string {
|
||||
if (sys === 'imperial') {
|
||||
const ft = m * 3.28084;
|
||||
if (ft < 5280) return `${ft < 10 ? ft.toFixed(1) : Math.round(ft)} ft`;
|
||||
const mi = m / 1609.344;
|
||||
const useFt = $prefs.unit === 'ft' || ($prefs.unit === 'auto' && ft < 528);
|
||||
if (useFt) {
|
||||
const v = ft < 10 ? ft.toFixed(1) : Math.round(ft).toString();
|
||||
return `${v} ft`;
|
||||
}
|
||||
return mi < 10 ? `${mi.toFixed(2)} mi` : `${mi.toFixed(1)} mi`;
|
||||
}
|
||||
const useM = $prefs.unit === 'm' || ($prefs.unit === 'auto' && m < 1000);
|
||||
if (useM) {
|
||||
const v = m < 10 ? m.toFixed(1) : Math.round(m).toString();
|
||||
return `${v} m`;
|
||||
}
|
||||
if (m < 1000) return `${m < 10 ? m.toFixed(1) : Math.round(m)} m`;
|
||||
const km = m / 1000;
|
||||
return km < 10 ? `${km.toFixed(2)} km` : `${km.toFixed(1)} km`;
|
||||
}
|
||||
|
||||
function formatAlt(m: number): string | null {
|
||||
if ($prefs.unit !== 'auto') {
|
||||
if ($prefs.system === 'metric') {
|
||||
if ($prefs.unit === 'm') return `${(m / 1000).toFixed(2)} km`;
|
||||
if ($prefs.unit === 'km') return m < 1000 ? `${Math.round(m)} m` : null;
|
||||
return null;
|
||||
} else {
|
||||
if ($prefs.unit === 'ft') return `${(m / 1609.344).toFixed(2)} mi`;
|
||||
if ($prefs.unit === 'mi') return ftAlt(m);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if ($prefs.system === 'metric') return m >= 1000 ? `${Math.round(m)} m` : null;
|
||||
return m >= 160.934 ? `${Math.round(m * 3.28084)} ft` : null;
|
||||
function formatDistance(m: number): string {
|
||||
return fmtFor(m, $prefs.system);
|
||||
}
|
||||
function ftAlt(m: number): string | null {
|
||||
const ft = m * 3.28084;
|
||||
return ft >= 528 ? null : `${Math.round(ft)} ft`;
|
||||
|
||||
// Show the same distance in the OTHER unit system (e.g. "3.31 mi (5.33 km)").
|
||||
function formatAlt(m: number): string | null {
|
||||
const other: 'metric' | 'imperial' = $prefs.system === 'metric' ? 'imperial' : 'metric';
|
||||
return fmtFor(m, other);
|
||||
}
|
||||
|
||||
function formatTime(m: number): string {
|
||||
@ -227,19 +210,6 @@
|
||||
<option value="imperial">Imperial</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="dir-unit">Units</label>
|
||||
<select id="dir-unit" bind:value={$prefs.unit}>
|
||||
<option value="auto">Auto</option>
|
||||
{#if $prefs.system === 'metric'}
|
||||
<option value="m">m</option>
|
||||
<option value="km">km</option>
|
||||
{:else}
|
||||
<option value="ft">ft</option>
|
||||
<option value="mi">mi</option>
|
||||
{/if}
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="dir-mode">Mode</label>
|
||||
<select id="dir-mode" bind:value={mode}>
|
||||
|
||||
@ -394,20 +394,7 @@
|
||||
<option value="imperial">Imperial (ft / mi)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="pref-row">
|
||||
<span class="pref-label">Default units</span>
|
||||
<select bind:value={$prefs.unit}>
|
||||
<option value="auto">Auto</option>
|
||||
{#if $prefs.system === 'metric'}
|
||||
<option value="m">m</option>
|
||||
<option value="km">km</option>
|
||||
{:else}
|
||||
<option value="ft">ft</option>
|
||||
<option value="mi">mi</option>
|
||||
{/if}
|
||||
</select>
|
||||
</div>
|
||||
<div class="pref-hint">Saved to this browser (localStorage).</div>
|
||||
<div class="pref-hint">Distances use m/ft under a km/mile, otherwise km/mi. Saved to this browser (localStorage).</div>
|
||||
<button class="pref-close" onclick={() => (showPrefs = false)}>Done</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,35 +1,29 @@
|
||||
/**
|
||||
* prefs.ts — shared, persisted user preferences (Svelte writable store).
|
||||
* ----------------------------------------------------------------------
|
||||
* Currently stores the unit system (Metric/Imperial) and the granular unit
|
||||
* override used by the Directions panel. Values are persisted to localStorage
|
||||
* so they survive reloads.
|
||||
* Currently stores the unit system (Metric/Imperial) for distance display.
|
||||
* Values are persisted to localStorage so they survive reloads.
|
||||
*
|
||||
* Usage in runes mode:
|
||||
* import { prefs } from '$lib/prefs';
|
||||
* $prefs.system // read
|
||||
* $prefs.system = 'imperial' // write (auto-persists)
|
||||
* $prefs.system // read
|
||||
* $prefs.system = 'imperial' // write (auto-persists)
|
||||
*/
|
||||
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
export type UnitSystem = 'metric' | 'imperial';
|
||||
export type UnitOverride = 'auto' | 'm' | 'km' | 'ft' | 'mi';
|
||||
|
||||
export interface Prefs {
|
||||
system: UnitSystem;
|
||||
unit: UnitOverride;
|
||||
}
|
||||
|
||||
const KEY = 'navigator.prefs.v1';
|
||||
const DEFAULTS: Prefs = { system: 'metric', unit: 'auto' };
|
||||
const DEFAULTS: Prefs = { system: 'metric' };
|
||||
|
||||
function isValidSystem(v: unknown): v is UnitSystem {
|
||||
return v === 'metric' || v === 'imperial';
|
||||
}
|
||||
function isValidUnit(v: unknown): v is UnitOverride {
|
||||
return v === 'auto' || v === 'm' || v === 'km' || v === 'ft' || v === 'mi';
|
||||
}
|
||||
|
||||
function load(): Prefs {
|
||||
try {
|
||||
@ -37,8 +31,7 @@ function load(): Prefs {
|
||||
if (!raw) return { ...DEFAULTS };
|
||||
const parsed = JSON.parse(raw) as Partial<Prefs>;
|
||||
return {
|
||||
system: isValidSystem(parsed.system) ? parsed.system : DEFAULTS.system,
|
||||
unit: isValidUnit(parsed.unit) ? parsed.unit : DEFAULTS.unit
|
||||
system: isValidSystem(parsed.system) ? parsed.system : DEFAULTS.system
|
||||
};
|
||||
} catch {
|
||||
return { ...DEFAULTS };
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user