2025-10-18 00:31:14 +02:00
|
|
|
import { selection } from '$lib/logic/selection';
|
|
|
|
|
import { GPXStatistics } from 'gpx';
|
|
|
|
|
import { fileStateCollection, GPXFileState } from '$lib/logic/file-state';
|
|
|
|
|
import {
|
|
|
|
|
ListFileItem,
|
|
|
|
|
ListWaypointItem,
|
|
|
|
|
ListWaypointsItem,
|
|
|
|
|
} from '$lib/components/file-list/file-list';
|
|
|
|
|
import { get, writable, type Writable } from 'svelte/store';
|
|
|
|
|
|
|
|
|
|
export class SelectedGPXStatistics {
|
|
|
|
|
private _statistics: Writable<GPXStatistics>;
|
|
|
|
|
private _files: Map<
|
|
|
|
|
string,
|
|
|
|
|
{
|
|
|
|
|
file: GPXFileState;
|
|
|
|
|
unsubscribe: () => void;
|
2025-10-05 19:34:05 +02:00
|
|
|
}
|
2025-10-18 00:31:14 +02:00
|
|
|
>;
|
|
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
|
this._statistics = writable(new GPXStatistics());
|
|
|
|
|
this._files = new Map();
|
|
|
|
|
selection.subscribe(() => this.update());
|
2025-10-05 19:34:05 +02:00
|
|
|
}
|
|
|
|
|
|
2025-10-18 00:31:14 +02:00
|
|
|
subscribe(run: (value: GPXStatistics) => void, invalidate?: (value?: GPXStatistics) => void) {
|
|
|
|
|
return this._statistics.subscribe(run, invalidate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update() {
|
2025-10-05 19:34:05 +02:00
|
|
|
let statistics = new GPXStatistics();
|
2025-10-18 00:31:14 +02:00
|
|
|
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
|
|
|
|
|
let stats = fileStateCollection.getStatistics(fileId);
|
|
|
|
|
if (stats) {
|
|
|
|
|
let first = true;
|
|
|
|
|
items.forEach((item) => {
|
|
|
|
|
if (
|
|
|
|
|
!(item instanceof ListWaypointItem || item instanceof ListWaypointsItem) ||
|
|
|
|
|
first
|
|
|
|
|
) {
|
|
|
|
|
statistics.mergeWith(stats.getStatisticsFor(item));
|
|
|
|
|
first = false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!this._files.has(fileId)) {
|
|
|
|
|
let file = fileStateCollection.getFileState(fileId);
|
|
|
|
|
if (file) {
|
|
|
|
|
let first = true;
|
|
|
|
|
let unsubscribe = file.subscribe(() => {
|
|
|
|
|
if (first) first = false;
|
|
|
|
|
else this.update();
|
|
|
|
|
});
|
|
|
|
|
this._files.set(fileId, { file, unsubscribe });
|
2025-10-05 19:34:05 +02:00
|
|
|
}
|
2025-10-18 00:31:14 +02:00
|
|
|
}
|
|
|
|
|
}, false);
|
|
|
|
|
this._statistics.set(statistics);
|
|
|
|
|
for (let [fileId, entry] of this._files) {
|
|
|
|
|
if (
|
|
|
|
|
!get(fileStateCollection).has(fileId) ||
|
|
|
|
|
!get(selection).hasAnyChildren(new ListFileItem(fileId))
|
|
|
|
|
) {
|
|
|
|
|
entry.unsubscribe();
|
|
|
|
|
this._files.delete(fileId);
|
2025-10-05 19:34:05 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-10-18 00:31:14 +02:00
|
|
|
|
|
|
|
|
export const gpxStatistics = new SelectedGPXStatistics();
|
|
|
|
|
|
|
|
|
|
export const slicedGPXStatistics: Writable<[GPXStatistics, number, number] | undefined> =
|
|
|
|
|
writable(undefined);
|
|
|
|
|
|
|
|
|
|
gpxStatistics.subscribe(() => {
|
|
|
|
|
slicedGPXStatistics.set(undefined);
|
|
|
|
|
});
|