store settings

This commit is contained in:
vcoppe
2024-05-04 15:10:30 +02:00
parent b85dc81c14
commit 71d68a3b5c
10 changed files with 114 additions and 75 deletions

View File

@@ -6,7 +6,8 @@
import Chart from 'chart.js/auto';
import mapboxgl from 'mapbox-gl';
import { map, settings, gpxStatistics } from '$lib/stores';
import { map, gpxStatistics } from '$lib/stores';
import { settings } from '$lib/db';
import { onDestroy, onMount } from 'svelte';
import {
@@ -53,6 +54,8 @@
let marker: mapboxgl.Marker | null = null;
let { distanceUnits, velocityUnits, temperatureUnits } = settings;
let options = {
animation: false,
parsing: false,
@@ -111,7 +114,7 @@
}
return `${$_('quantities.elevation')}: ${getElevationWithUnits(point.y, false)}`;
} else if (context.datasetIndex === 1) {
return `${$settings.velocityUnits === 'speed' ? $_('quantities.speed') : $_('quantities.pace')}: ${getVelocityWithUnits(point.y, false)}`;
return `${$velocityUnits === 'speed' ? $_('quantities.speed') : $_('quantities.pace')}: ${getVelocityWithUnits(point.y, false)}`;
} else if (context.datasetIndex === 2) {
return `${$_('quantities.heartrate')}: ${getHeartRateWithUnits(point.y)}`;
} else if (context.datasetIndex === 3) {
@@ -150,8 +153,7 @@
} = {
speed: {
id: 'speed',
getLabel: () =>
$settings.velocityUnits === 'speed' ? $_('quantities.speed') : $_('quantities.pace'),
getLabel: () => ($velocityUnits === 'speed' ? $_('quantities.speed') : $_('quantities.pace')),
getUnits: () => getVelocityUnits()
},
hr: {
@@ -196,7 +198,7 @@
}
options.scales.yspeed['ticks'] = {
callback: function (value: number) {
if ($settings.velocityUnits === 'speed') {
if ($velocityUnits === 'speed') {
return value;
} else {
return secondsToHHMMSS(value);
@@ -232,7 +234,7 @@
});
});
$: if (chart && $settings) {
$: if (chart && $distanceUnits && $velocityUnits && $temperatureUnits) {
let data = $gpxStatistics;
// update data
@@ -432,9 +434,7 @@
<Tooltip side="left">
<Zap slot="data" size="16" />
<span slot="tooltip"
>{$settings.velocityUnits === 'speed'
? $_('chart.show_speed')
: $_('chart.show_pace')}</span
>{$velocityUnits === 'speed' ? $_('chart.show_speed') : $_('chart.show_pace')}</span
>
</Tooltip>
</ToggleGroup.Item>

View File

@@ -3,11 +3,14 @@
import Tooltip from '$lib/components/Tooltip.svelte';
import WithUnits from '$lib/components/WithUnits.svelte';
import { gpxStatistics, settings } from '$lib/stores';
import { gpxStatistics } from '$lib/stores';
import { settings } from '$lib/db';
import { MoveDownRight, MoveUpRight, Ruler, Timer, Zap } from 'lucide-svelte';
import { _ } from 'svelte-i18n';
const { velocityUnits } = settings;
</script>
<Card.Root class="h-full overflow-hidden border-none shadow-none min-w-48 pl-4">
@@ -36,7 +39,7 @@
<WithUnits value={$gpxStatistics.global.speed.moving} type="speed" />
</span>
<span slot="tooltip"
>{$settings.velocityUnits === 'speed' ? $_('quantities.speed') : $_('quantities.pace')} ({$_(
>{$velocityUnits === 'speed' ? $_('quantities.speed') : $_('quantities.pace')} ({$_(
'quantities.total'
)} / {$_('quantities.moving')})</span
>

View File

@@ -7,7 +7,8 @@
import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css';
import { map, settings } from '$lib/stores';
import { map } from '$lib/stores';
import { settings } from '$lib/db';
import { locale } from 'svelte-i18n';
import { get } from 'svelte/store';
@@ -20,8 +21,9 @@
easing: () => 1
};
const { distanceUnits } = settings;
let scaleControl = new mapboxgl.ScaleControl({
unit: $settings.distanceUnits
unit: $distanceUnits
});
function toggleTerrain() {
@@ -98,7 +100,7 @@
});
$: if ($map) {
scaleControl.setUnit($settings.distanceUnits);
scaleControl.setUnit($distanceUnits);
}
</script>

View File

@@ -11,33 +11,23 @@
exportSelectedFiles,
triggerFileInput,
selectFiles,
settings,
createFile
} from '$lib/stores';
import { derived } from 'svelte/store';
import { canUndo, canRedo, dbUtils, fileObservers, settings } from '$lib/db';
import { mode, resetMode, setMode } from 'mode-watcher';
import { resetMode, setMode } from 'mode-watcher';
import { _ } from 'svelte-i18n';
import { derived, get } from 'svelte/store';
import { canUndo, canRedo, dbUtils, fileObservers } from '$lib/db';
let showDistanceMarkers = false;
let showDirectionMarkers = false;
let currentMode = derived(mode, ($mode) => {
if (!$mode) {
return 'system';
} else {
return $mode;
}
});
$: if ($settings.mode !== get(currentMode)) {
if ($settings.mode === 'system') {
resetMode();
} else {
setMode($settings.mode);
}
const { distanceUnits, velocityUnits, temperatureUnits, mode } = settings;
$: if ($mode === 'system') {
resetMode();
} else {
setMode($mode);
}
let undoDisabled = derived(canUndo, ($canUndo) => !$canUndo);
@@ -132,7 +122,7 @@
><Menubar.Sub>
<Menubar.SubTrigger inset>{$_('menu.distance_units')}</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.RadioGroup bind:value={$settings.distanceUnits}>
<Menubar.RadioGroup bind:value={$distanceUnits}>
<Menubar.RadioItem value="metric">{$_('menu.metric')}</Menubar.RadioItem>
<Menubar.RadioItem value="imperial">{$_('menu.imperial')}</Menubar.RadioItem>
</Menubar.RadioGroup>
@@ -141,7 +131,7 @@
<Menubar.Sub>
<Menubar.SubTrigger inset>{$_('menu.velocity_units')}</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.RadioGroup bind:value={$settings.velocityUnits}>
<Menubar.RadioGroup bind:value={$velocityUnits}>
<Menubar.RadioItem value="speed">{$_('quantities.speed')}</Menubar.RadioItem>
<Menubar.RadioItem value="pace">{$_('quantities.pace')}</Menubar.RadioItem>
</Menubar.RadioGroup>
@@ -150,7 +140,7 @@
<Menubar.Sub>
<Menubar.SubTrigger inset>{$_('menu.temperature_units')}</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.RadioGroup bind:value={$settings.temperatureUnits}>
<Menubar.RadioGroup bind:value={$temperatureUnits}>
<Menubar.RadioItem value="celsius">{$_('menu.celsius')}</Menubar.RadioItem>
<Menubar.RadioItem value="fahrenheit">{$_('menu.fahrenheit')}</Menubar.RadioItem>
</Menubar.RadioGroup>
@@ -160,7 +150,7 @@
<Menubar.Sub>
<Menubar.SubTrigger inset>{$_('menu.mode')}</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.RadioGroup bind:value={$settings.mode}>
<Menubar.RadioGroup bind:value={$mode}>
<Menubar.RadioItem value="light">{$_('menu.light')}</Menubar.RadioItem>
<Menubar.RadioItem value="dark">{$_('menu.dark')}</Menubar.RadioItem>
<Menubar.RadioItem value="system">{$_('menu.system')}</Menubar.RadioItem>

View File

@@ -1,5 +1,5 @@
<script lang="ts">
import { settings } from '$lib/stores';
import { settings } from '$lib/db';
import {
celsiusToFahrenheit,
distancePerHourToSecondsPerDistance,
@@ -13,36 +13,38 @@
export let value: number;
export let type: 'distance' | 'elevation' | 'speed' | 'temperature' | 'time';
export let showUnits: boolean = true;
const { distanceUnits, velocityUnits, temperatureUnits } = settings;
</script>
{#if type === 'distance'}
{#if $settings.distanceUnits === 'metric'}
{#if $distanceUnits === 'metric'}
{value.toFixed(2)} {showUnits ? $_('units.kilometers') : ''}
{:else}
{kilometersToMiles(value).toFixed(2)} {showUnits ? $_('units.miles') : ''}
{/if}
{:else if type === 'elevation'}
{#if $settings.distanceUnits === 'metric'}
{#if $distanceUnits === 'metric'}
{value.toFixed(0)} {showUnits ? $_('units.meters') : ''}
{:else}
{metersToFeet(value).toFixed(0)} {showUnits ? $_('units.feet') : ''}
{/if}
{:else if type === 'speed'}
{#if $settings.distanceUnits === 'metric'}
{#if $settings.velocityUnits === 'speed'}
{#if $distanceUnits === 'metric'}
{#if $velocityUnits === 'speed'}
{value.toFixed(2)} {showUnits ? $_('units.kilometers_per_hour') : ''}
{:else}
{secondsToHHMMSS(distancePerHourToSecondsPerDistance(value))}
{showUnits ? $_('units.minutes_per_kilometer') : ''}
{/if}
{:else if $settings.velocityUnits === 'speed'}
{:else if $velocityUnits === 'speed'}
{kilometersToMiles(value).toFixed(2)} {showUnits ? $_('units.miles_per_hour') : ''}
{:else}
{secondsToHHMMSS(distancePerHourToSecondsPerDistance(kilometersToMiles(value)))}
{showUnits ? $_('units.minutes_per_mile') : ''}
{/if}
{:else if type === 'temperature'}
{#if $settings.temperatureUnits === 'celsius'}
{#if $temperatureUnits === 'celsius'}
{value} {showUnits ? $_('units.celsius') : ''}
{:else}
{celsiusToFahrenheit(value)} {showUnits ? $_('units.fahrenheit') : ''}

View File

@@ -7,7 +7,8 @@
import { CircleHelp } from 'lucide-svelte';
import { map, selectedFiles, Tool } from '$lib/stores';
import { brouterProfiles, privateRoads, routing, routingProfile } from './Routing';
import { settings } from '$lib/db';
import { brouterProfiles, routingProfileSelectItem } from './Routing';
import { _ } from 'svelte-i18n';
import { get } from 'svelte/store';
@@ -23,6 +24,8 @@
let selectedId: string | null = null;
let active = false;
const { privateRoads, routing } = settings;
$: if ($map) {
// remove controls for deleted files
routingControls.forEach((controls, fileId) => {
@@ -82,7 +85,7 @@
<ToolbarItemMenu tool={Tool.ROUTING} bind:active>
<div class="w-full flex flex-row justify-between items-center gap-2">
<Label>{$_('toolbar.routing.activity')}</Label>
<Select.Root bind:selected={$routingProfile}>
<Select.Root bind:selected={$routingProfileSelectItem}>
<Select.Trigger class="h-8 w-40">
<Select.Value />
</Select.Trigger>

View File

@@ -1,8 +1,11 @@
import type { Coordinates } from "gpx";
import { TrackPoint } from "gpx";
import { get, writable } from "svelte/store";
import { settings } from "$lib/db";
import { _ } from "svelte-i18n";
const { routing, routingProfile, privateRoads } = settings;
export const brouterProfiles: { [key: string]: string } = {
bike: 'Trekking-dry',
racing_bike: 'fastbike',
@@ -12,12 +15,24 @@ export const brouterProfiles: { [key: string]: string } = {
water: 'river',
railway: 'rail'
};
export const routingProfile = writable({
export const routingProfileSelectItem = writable({
value: 'bike',
label: get(_)('toolbar.routing.activities.bike')
});
export const routing = writable(true);
export const privateRoads = writable(false);
routingProfile.subscribe((value) => {
if (value !== get(routingProfileSelectItem).value) {
routingProfileSelectItem.update((item) => {
item.value = value;
item.label = get(_)(`toolbar.routing.activities.${value}`);
return item;
});
}
});
routingProfileSelectItem.subscribe((item) => {
if (item.value !== get(routingProfile)) {
routingProfile.set(item.value);
}
});
export function route(points: Coordinates[]): Promise<TrackPoint[]> {
if (get(routing)) {

View File

@@ -3,6 +3,7 @@ import { GPXFile } from 'gpx';
import { type FreezedObject, type Patch, produceWithPatches, applyPatches } from 'structurajs';
import { writable, get, derived, type Readable, type Writable } from 'svelte/store';
import { fileOrder, selectedFiles } from './stores';
import { mode } from 'mode-watcher';
class Database extends Dexie {
@@ -259,4 +260,37 @@ export const dbUtils = {
});
}
}
}
}
function dexieSettingStore(setting: string, initial: any): Writable<any> {
let store = writable(initial);
liveQuery(() => db.settings.get(setting)).subscribe(value => {
if (value !== undefined) {
store.set(value);
}
});
return {
subscribe: store.subscribe,
set: (value: any) => db.settings.put(value, setting),
update: (callback: (value: any) => any) => {
let newValue = callback(get(store));
db.settings.put(newValue, setting);
}
};
}
export const settings = {
distanceUnits: dexieSettingStore('distanceUnits', 'metric'),
velocityUnits: dexieSettingStore('velocityUnits', 'speed'),
temperatureUnits: dexieSettingStore('temperatureUnits', 'celsius'),
mode: dexieSettingStore('mode', (() => {
let currentMode: string | undefined = get(mode);
if (currentMode === undefined) {
currentMode = 'system';
}
return currentMode;
})()),
routing: dexieSettingStore('routing', true),
routingProfile: dexieSettingStore('routingProfile', 'bike'),
privateRoads: dexieSettingStore('privateRoads', false),
};

View File

@@ -57,12 +57,6 @@ selectedFiles.subscribe((selectedFiles) => {
updateGPXData();
});
export const settings = writable<{ [key: string]: any }>({
distanceUnits: 'metric',
velocityUnits: 'speed',
temperatureUnits: 'celsius',
mode: 'system'
});
export const gpxLayers: Writable<Map<string, GPXLayer>> = writable(new Map());
export enum Tool {

View File

@@ -1,7 +1,9 @@
import { get } from 'svelte/store';
import { settings } from './stores';
import { settings } from '$lib/db';
import { _ } from 'svelte-i18n';
const { distanceUnits, velocityUnits, temperatureUnits } = settings;
export function kilometersToMiles(value: number) {
return value * 0.621371;
}
@@ -39,9 +41,7 @@ export function getDistanceWithUnits(value: number, convert: boolean = true) {
}
export function getVelocityWithUnits(value: number, convert: boolean = true) {
const velocityUnits = get(settings).velocityUnits;
const distanceUnits = get(settings).distanceUnits;
if (velocityUnits === 'speed') {
if (get(velocityUnits) === 'speed') {
if (convert) {
return getConvertedVelocity(value).toFixed(2) + ' ' + getVelocityUnits();
} else {
@@ -86,22 +86,20 @@ export function getTemperatureWithUnits(value: number, convert: boolean = true)
// Get the units
export function getDistanceUnits() {
return get(settings).distanceUnits === 'metric' ? get(_)('units.kilometers') : get(_)('units.miles');
return get(distanceUnits) === 'metric' ? get(_)('units.kilometers') : get(_)('units.miles');
}
export function getVelocityUnits() {
const velocityUnits = get(settings).velocityUnits;
const distanceUnits = get(settings).distanceUnits;
if (velocityUnits === 'speed') {
return distanceUnits === 'metric' ? get(_)('units.kilometers_per_hour') : get(_)('units.miles_per_hour');
if (get(velocityUnits) === 'speed') {
return get(distanceUnits) === 'metric' ? get(_)('units.kilometers_per_hour') : get(_)('units.miles_per_hour');
} else {
return distanceUnits === 'metric' ? get(_)('units.minutes_per_kilometer') : get(_)('units.minutes_per_mile');
return get(distanceUnits) === 'metric' ? get(_)('units.minutes_per_kilometer') : get(_)('units.minutes_per_mile');
}
}
export function getElevationUnits() {
return get(settings).distanceUnits === 'metric' ? get(_)('units.meters') : get(_)('units.feet');
return get(distanceUnits) === 'metric' ? get(_)('units.meters') : get(_)('units.feet');
}
export function getHeartRateUnits() {
@@ -117,28 +115,26 @@ export function getPowerUnits() {
}
export function getTemperatureUnits() {
return get(settings).temperatureUnits === 'celsius' ? get(_)('units.celsius') : get(_)('units.fahrenheit');
return get(temperatureUnits) === 'celsius' ? get(_)('units.celsius') : get(_)('units.fahrenheit');
}
// Convert only the value
export function getConvertedDistance(value: number) {
return get(settings).distanceUnits === 'metric' ? value : kilometersToMiles(value);
return get(distanceUnits) === 'metric' ? value : kilometersToMiles(value);
}
export function getConvertedElevation(value: number) {
return get(settings).distanceUnits === 'metric' ? value : metersToFeet(value);
return get(distanceUnits) === 'metric' ? value : metersToFeet(value);
}
export function getConvertedVelocity(value: number) {
const velocityUnits = get(settings).velocityUnits;
const distanceUnits = get(settings).distanceUnits;
if (velocityUnits === 'speed') {
return distanceUnits === 'metric' ? value : kilometersToMiles(value);
if (get(velocityUnits) === 'speed') {
return get(distanceUnits) === 'metric' ? value : kilometersToMiles(value);
} else {
return distanceUnits === 'metric' ? distancePerHourToSecondsPerDistance(value) : distancePerHourToSecondsPerDistance(kilometersToMiles(value));
return get(distanceUnits) === 'metric' ? distancePerHourToSecondsPerDistance(value) : distancePerHourToSecondsPerDistance(kilometersToMiles(value));
}
}
export function getConvertedTemperature(value: number) {
return get(settings).temperatureUnits === 'celsius' ? value : celsiusToFahrenheit(value);
return get(temperatureUnits) === 'celsius' ? value : celsiusToFahrenheit(value);
}