Files
gpx.studio/website/src/lib/logic/statistics.ts

88 lines
2.8 KiB
TypeScript
Raw Normal View History

2025-10-18 00:31:14 +02:00
import { selection } from '$lib/logic/selection';
import { GPXGlobalStatistics, GPXStatisticsGroup } from 'gpx';
2025-10-18 00:31:14 +02:00
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';
2025-10-18 16:10:08 +02:00
import { settings } from '$lib/logic/settings';
const { fileOrder } = settings;
2025-10-18 00:31:14 +02:00
export class SelectedGPXStatistics {
private _statistics: Writable<GPXStatisticsGroup>;
2025-10-18 00:31:14 +02:00
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 GPXStatisticsGroup());
2025-10-18 00:31:14 +02:00
this._files = new Map();
selection.subscribe(() => this.update());
2025-10-18 16:10:08 +02:00
fileOrder.subscribe(() => this.update());
2025-10-05 19:34:05 +02:00
}
subscribe(
run: (value: GPXStatisticsGroup) => void,
invalidate?: (value?: GPXStatisticsGroup) => void
) {
2025-10-18 00:31:14 +02:00
return this._statistics.subscribe(run, invalidate);
}
update() {
let statistics = new GPXStatisticsGroup();
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.add(stats.getStatisticsFor(item));
2025-10-18 00:31:14 +02:00
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<[GPXGlobalStatistics, number, number] | undefined> =
2025-10-18 00:31:14 +02:00
writable(undefined);
gpxStatistics.subscribe(() => {
slicedGPXStatistics.set(undefined);
});