peak search, denser catalog, profiles, filename parsing, themed map controls

This commit is contained in:
Vincent van der Wal
2026-07-22 12:07:01 +02:00
parent b288daf251
commit b89de57967
17 changed files with 767 additions and 64 deletions
+28 -4
View File
@@ -3,6 +3,25 @@ import { db, peaksNearBounds, recordAscent } from '$lib/server/db';
import { matchPeaks, parseGpx } from '$lib/server/gpx';
import type { Actions } from './$types';
/**
* Parse export-style filenames like
* "2018-01-11 141322 - Run - Afternoon Run.gpx" (Date - Type - Name).
*/
function parseFilename(
filename: string
): { date: string; type: string; name: string } | null {
const base = filename.replace(/\.gpx$/i, '');
const parts = base.split(' - ');
if (parts.length < 3) return null;
const dateMatch = parts[0].match(/^(\d{4}-\d{2}-\d{2})(\s+\d{4,6})?$/);
if (!dateMatch) return null;
return {
date: dateMatch[1],
type: parts[1].trim().toLowerCase(),
name: parts.slice(2).join(' - ').trim()
};
}
export const actions: Actions = {
default: async ({ request, locals }) => {
const userId = locals.user!.id;
@@ -25,11 +44,12 @@ export const actions: Actions = {
for (const file of files) {
try {
const gpx = parseGpx(await file.text());
const parsed = parseFilename(file.name);
const result = insert.run({
user_id: userId,
name: gpx.name ?? file.name.replace(/\.gpx$/i, ''),
type: gpx.type ?? 'outdoor',
date: gpx.date,
name: parsed?.name ?? gpx.name ?? file.name.replace(/\.gpx$/i, ''),
type: parsed?.type ?? gpx.type ?? 'outdoor',
date: gpx.date ?? parsed?.date ?? null,
distance_m: gpx.distance_m,
duration_s: gpx.duration_s,
moving_s: gpx.moving_s,
@@ -49,7 +69,11 @@ export const actions: Actions = {
if (recordAscent(userId, peak.id, activityId, gpx.date)) newPeaks.push(peak.name);
}
uploaded.push({ id: activityId, name: gpx.name ?? file.name, newPeaks });
uploaded.push({
id: activityId,
name: parsed?.name ?? gpx.name ?? file.name,
newPeaks
});
} catch (err) {
errors.push(`${file.name}: ${err instanceof Error ? err.message : 'could not parse'}`);
}