diff --git a/website/package-lock.json b/website/package-lock.json
index 1d92a0ba..608424e4 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -15,8 +15,10 @@
"gpx": "file:../gpx",
"lucide-svelte": "^0.365.0",
"mapbox-gl": "^3.2.0",
+ "mode-watcher": "^0.3.0",
"sortablejs": "^1.15.2",
"svelte-i18n": "^4.0.0",
+ "svelte-sonner": "^0.3.22",
"tailwind-merge": "^2.2.2",
"tailwind-variants": "^0.2.1"
},
@@ -3939,6 +3941,14 @@
"mkdirp": "bin/cmd.js"
}
},
+ "node_modules/mode-watcher": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/mode-watcher/-/mode-watcher-0.3.0.tgz",
+ "integrity": "sha512-k8jjuTx94HaaRKWO6JDf8wL761hFatrTIHJKl+E+3JWcnv+GnMBH062zcLsy0lbCI3n7RZxxHaWi66auFnUO4g==",
+ "peerDependencies": {
+ "svelte": "^4.0.0"
+ }
+ },
"node_modules/mri": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
@@ -5745,6 +5755,14 @@
}
}
},
+ "node_modules/svelte-sonner": {
+ "version": "0.3.22",
+ "resolved": "https://registry.npmjs.org/svelte-sonner/-/svelte-sonner-0.3.22.tgz",
+ "integrity": "sha512-1AEBl7rTP4oeMAmBmkcvoHNOwB8gPzz73RYApcY8pyDwbjBewU8ATnXV8N42omV1sQvtSX/X0o5A1nfkN3T6cg==",
+ "peerDependencies": {
+ "svelte": ">=3 <5"
+ }
+ },
"node_modules/tabbable": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
diff --git a/website/package.json b/website/package.json
index 202ca240..875e210e 100644
--- a/website/package.json
+++ b/website/package.json
@@ -48,8 +48,10 @@
"gpx": "file:../gpx",
"lucide-svelte": "^0.365.0",
"mapbox-gl": "^3.2.0",
+ "mode-watcher": "^0.3.0",
"sortablejs": "^1.15.2",
"svelte-i18n": "^4.0.0",
+ "svelte-sonner": "^0.3.22",
"tailwind-merge": "^2.2.2",
"tailwind-variants": "^0.2.1"
}
diff --git a/website/src/lib/components/App.svelte b/website/src/lib/components/App.svelte
index 21e87c5a..239b3936 100644
--- a/website/src/lib/components/App.svelte
+++ b/website/src/lib/components/App.svelte
@@ -7,6 +7,7 @@
import Menu from '$lib/components/Menu.svelte';
import Toolbar from '$lib/components/toolbar/Toolbar.svelte';
import LayerControl from '$lib/components/layer-control/LayerControl.svelte';
+ import { Toaster } from '$lib/components/ui/sonner';
@@ -17,9 +18,18 @@
+
+
+
diff --git a/website/src/lib/components/FileList.svelte b/website/src/lib/components/FileList.svelte
index 5257f2cc..5ad3d855 100644
--- a/website/src/lib/components/FileList.svelte
+++ b/website/src/lib/components/FileList.svelte
@@ -1,6 +1,7 @@
@@ -126,6 +145,17 @@
+
+ {$_('menu.mode')}
+
+
+ {$_('menu.light')}
+ {$_('menu.dark')}
+ {$_('menu.system')}
+
+
+
+
{$_('menu.distance_markers')}
diff --git a/website/src/lib/components/routing/Routing.ts b/website/src/lib/components/routing/Routing.ts
index 28ee6ffb..9477af57 100644
--- a/website/src/lib/components/routing/Routing.ts
+++ b/website/src/lib/components/routing/Routing.ts
@@ -38,6 +38,12 @@ async function getRoute(points: Coordinates[], brouterProfile: string, privateRo
let url = `https://routing.gpx.studio?lonlats=${points.map(point => `${point.lon.toFixed(8)},${point.lat.toFixed(8)}`).join('|')}&profile=${brouterProfile + (privateRoads ? '-private' : '')}&format=geojson&alternativeidx=0`;
let response = await fetch(url);
+
+ // Check if the response is ok
+ if (!response.ok) {
+ throw new Error(`${await response.text()}`);
+ }
+
let geojson = await response.json();
let route: TrackPoint[] = [];
@@ -66,7 +72,7 @@ async function getRoute(points: Coordinates[], brouterProfile: string, privateRo
coordinates[i][1] == Number(messages[messageIdx][latIdx]) / 1000000) {
messageIdx++;
- if (messageIdx == messages.length) surface = "missing";
+ if (messageIdx == messages.length) surface = "unknown";
else surface = getSurface(messages[messageIdx][tagIdx]);
}
}
diff --git a/website/src/lib/components/routing/RoutingControls.ts b/website/src/lib/components/routing/RoutingControls.ts
index c607a2dc..c3bb86ac 100644
--- a/website/src/lib/components/routing/RoutingControls.ts
+++ b/website/src/lib/components/routing/RoutingControls.ts
@@ -3,7 +3,11 @@ import { get, type Writable } from "svelte/store";
import { computeAnchorPoints, type SimplifiedTrackPoint } from "./Simplify";
import mapboxgl from "mapbox-gl";
import { route } from "./Routing";
-import { applyToFileElement, applyToFileStore } from "$lib/stores";
+import { applyToFileElement } from "$lib/stores";
+
+import { toast } from "svelte-sonner";
+
+import { _ } from "svelte-i18n";
export class RoutingControls {
map: mapboxgl.Map;
@@ -100,7 +104,7 @@ export class RoutingControls {
createMarker(anchor: SimplifiedTrackPoint) {
let element = document.createElement('div');
- element.className = `h-3 w-3 rounded-full bg-background border-2 border-black cursor-pointer`;
+ element.className = `h-3 w-3 rounded-full bg-white border-2 border-black cursor-pointer`;
let marker = new mapboxgl.Marker({
draggable: true,
@@ -380,7 +384,14 @@ export class RoutingControls {
try {
response = await route(targetCoordinates);
} catch (e) {
- console.error(e);
+ console.log(e);
+ if (e.message.includes('from-position not mapped in existing datafile')) {
+ toast.error(get(_)("toolbar.routing.error.from"));
+ } else if (e.message.includes('to-position not mapped in existing datafile')) {
+ toast.error(get(_)("toolbar.routing.error.to"));
+ } else {
+ toast.error(e.message);
+ }
return false;
}
diff --git a/website/src/lib/components/ui/sonner/index.ts b/website/src/lib/components/ui/sonner/index.ts
new file mode 100644
index 00000000..1ad9f4a2
--- /dev/null
+++ b/website/src/lib/components/ui/sonner/index.ts
@@ -0,0 +1 @@
+export { default as Toaster } from "./sonner.svelte";
diff --git a/website/src/lib/components/ui/sonner/sonner.svelte b/website/src/lib/components/ui/sonner/sonner.svelte
new file mode 100644
index 00000000..7d5b2f14
--- /dev/null
+++ b/website/src/lib/components/ui/sonner/sonner.svelte
@@ -0,0 +1,20 @@
+
+
+
diff --git a/website/src/lib/stores.ts b/website/src/lib/stores.ts
index 680ae338..a98e675c 100644
--- a/website/src/lib/stores.ts
+++ b/website/src/lib/stores.ts
@@ -12,6 +12,7 @@ export const settings = writable<{ [key: string]: any }>({
distanceUnits: 'metric',
velocityUnits: 'speed',
temperatureUnits: 'celsius',
+ mode: 'system'
});
export enum Tool {
ROUTING
diff --git a/website/src/locales/en.json b/website/src/locales/en.json
index 435c1268..0d4b76d2 100644
--- a/website/src/locales/en.json
+++ b/website/src/locales/en.json
@@ -20,6 +20,10 @@
"temperature_units": "Temperature units",
"celsius": "Celsius",
"fahrenheit": "Fahrenheit",
+ "mode": "Mode",
+ "light": "Light",
+ "dark": "Dark",
+ "system": "System",
"distance_markers": "Show distance markers",
"direction_markers": "Show direction markers",
"about": "About",
@@ -42,6 +46,10 @@
"motorcycle": "Motorcycle",
"water": "Water",
"railway": "Railway"
+ },
+ "error": {
+ "from": "The start point is too far from the nearest road",
+ "to": "The end point is too far from the nearest road"
}
},
"time_tooltip": "Change the time and speed data",
diff --git a/website/src/routes/+layout.svelte b/website/src/routes/+layout.svelte
index 17abf18a..f69fc18f 100644
--- a/website/src/routes/+layout.svelte
+++ b/website/src/routes/+layout.svelte
@@ -1,5 +1,9 @@
+
+