2026-10-08 09:24:15 +02:00
|
|
|
import { engine, type ExportOptions } from '$lib/engine';
|
2025-06-21 21:07:36 +02:00
|
|
|
import FileSaver from 'file-saver';
|
|
|
|
|
import JSZip from 'jszip';
|
2025-10-17 23:54:45 +02:00
|
|
|
import { get } from 'svelte/store';
|
2026-10-09 08:58:00 +02:00
|
|
|
import { sanitizeFileName, uniqueFileNames } from './file-names';
|
2025-06-21 21:07:36 +02:00
|
|
|
|
|
|
|
|
export enum ExportState {
|
|
|
|
|
NONE,
|
|
|
|
|
SELECTION,
|
|
|
|
|
ALL,
|
|
|
|
|
}
|
|
|
|
|
export const exportState = $state({
|
|
|
|
|
current: ExportState.NONE,
|
|
|
|
|
});
|
|
|
|
|
|
2026-10-08 09:24:15 +02:00
|
|
|
/** The files that contain the selection, in the order of the selection. */
|
|
|
|
|
export function selectedFileIds(): string[] {
|
|
|
|
|
const selection = get(engine.selection);
|
|
|
|
|
switch (selection.type) {
|
|
|
|
|
case 'file':
|
|
|
|
|
return selection.fileIds;
|
|
|
|
|
case 'empty':
|
|
|
|
|
return [];
|
|
|
|
|
default:
|
|
|
|
|
return [selection.fileId];
|
2025-06-21 21:07:36 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-08 09:24:15 +02:00
|
|
|
export function allFileIds(): string[] {
|
|
|
|
|
return get(engine.order);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function exportFiles(fileIds: string[], options: ExportOptions) {
|
2026-10-16 18:14:59 +02:00
|
|
|
if (get(engine.workspace)) {
|
|
|
|
|
// the desktop app: the user chooses where the files go
|
|
|
|
|
await engine.exportFiles(fileIds, options);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-10-14 08:51:38 +02:00
|
|
|
const files = (
|
|
|
|
|
await Promise.all(
|
|
|
|
|
fileIds.map(async (fileId) => {
|
|
|
|
|
const gpx = await engine.exportFile(fileId, options);
|
|
|
|
|
const name = get(engine.files).get(fileId);
|
|
|
|
|
return gpx === undefined || !name ? [] : [{ name: get(name).structure.name, gpx }];
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
).flat();
|
2025-06-21 21:07:36 +02:00
|
|
|
|
2026-10-08 09:24:15 +02:00
|
|
|
if (files.length === 1) {
|
|
|
|
|
const blob = new Blob([files[0].gpx], { type: 'application/gpx+xml' });
|
2026-10-09 08:58:00 +02:00
|
|
|
FileSaver.saveAs(blob, `${sanitizeFileName(files[0].name)}.gpx`);
|
2026-10-08 09:24:15 +02:00
|
|
|
} else if (files.length > 1) {
|
|
|
|
|
const zip = new JSZip();
|
2026-10-09 08:58:00 +02:00
|
|
|
const names = uniqueFileNames(files.map((file) => file.name));
|
|
|
|
|
files.forEach(({ gpx }, i) => zip.file(`${names[i]}.gpx`, gpx));
|
2025-06-21 21:07:36 +02:00
|
|
|
const blob = await zip.generateAsync({ type: 'blob' });
|
|
|
|
|
FileSaver.saveAs(blob, 'gpx-files.zip');
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-10-08 09:24:15 +02:00
|
|
|
|
|
|
|
|
export async function exportSelectedFiles(options: ExportOptions) {
|
|
|
|
|
await exportFiles(selectedFileIds(), options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function exportAllFiles(options: ExportOptions) {
|
|
|
|
|
await exportFiles(allFileIds(), options);
|
|
|
|
|
}
|