export dialog progress

This commit is contained in:
vcoppe
2024-06-28 15:43:57 +02:00
parent d11ed1e5b0
commit ec8d3f8f87
6 changed files with 131 additions and 32 deletions

View File

@@ -10,7 +10,7 @@
"dependencies": { "dependencies": {
"@internationalized/date": "^3.5.4", "@internationalized/date": "^3.5.4",
"@mapbox/mapbox-gl-geocoder": "^5.0.2", "@mapbox/mapbox-gl-geocoder": "^5.0.2",
"bits-ui": "^0.21.10", "bits-ui": "^0.21.11",
"chart.js": "^4.4.3", "chart.js": "^4.4.3",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"dexie": "^4.0.7", "dexie": "^4.0.7",
@@ -1911,9 +1911,9 @@
} }
}, },
"node_modules/bits-ui": { "node_modules/bits-ui": {
"version": "0.21.10", "version": "0.21.11",
"resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-0.21.10.tgz", "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-0.21.11.tgz",
"integrity": "sha512-KuweEOKO0Rr8XX87dQh46G9mG0bZSmTqNxj5qBazz4OTQC+oPKui04/wP/ISsCOSGFomaRydTULqh4p+nsyc2g==", "integrity": "sha512-pFS/9z1qLaPZwb+9Tm0YS4iBp+ClsJBARMZWFOjv0lGCYpzAN7lx4eNk3SbSB5QMBUKwoVjr9Rai71ROq3RD1Q==",
"dependencies": { "dependencies": {
"@internationalized/date": "^3.5.1", "@internationalized/date": "^3.5.1",
"@melt-ui/svelte": "0.76.2", "@melt-ui/svelte": "0.76.2",

View File

@@ -45,7 +45,7 @@
"dependencies": { "dependencies": {
"@internationalized/date": "^3.5.4", "@internationalized/date": "^3.5.4",
"@mapbox/mapbox-gl-geocoder": "^5.0.2", "@mapbox/mapbox-gl-geocoder": "^5.0.2",
"bits-ui": "^0.21.10", "bits-ui": "^0.21.11",
"chart.js": "^4.4.3", "chart.js": "^4.4.3",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"dexie": "^4.0.7", "dexie": "^4.0.7",

View File

@@ -0,0 +1,77 @@
<script lang="ts">
import { Button } from '$lib/components/ui/button';
import { Dialog } from 'bits-ui';
import {
currentTool,
exportAllFiles,
exportSelectedFiles,
ExportState,
exportState
} from '$lib/stores';
import { fileObservers } from '$lib/db';
import { Cloud, Download } from 'lucide-svelte';
import { _ } from 'svelte-i18n';
import { selection } from './file-list/Selection';
let open = false;
$: if ($exportState !== ExportState.NONE) {
open = true;
$currentTool = null;
}
</script>
<Dialog.Root
bind:open
onOpenChange={(isOpen) => {
if (!isOpen) {
$exportState = ExportState.NONE;
}
}}
>
<Dialog.Trigger class="hidden" />
<Dialog.Portal>
<Dialog.Content
class="fixed left-[50%] top-[50%] z-50 w-fit max-w-full translate-x-[-50%] translate-y-[-50%] flex flex-col items-center gap-2 border bg-background p-3 shadow-lg rounded-md"
>
<div class="flex flex-col items-center gap-2 rounded border p-2">
<div class="flex flex-row items-center gap-2 text-sm">
<span>⚠️</span>
<span class="text-center max-w-96">
{$_('menu.support_message')}
</span>
<span>⚠️</span>
</div>
<Button class="bg-support w-fit" href="https://ko-fi.com/gpxstudio">
{$_('menu.support_button')}
<span class="ml-2">🙏</span>
</Button>
</div>
<div class="flex flex-row gap-2 justify-center">
<Button
variant="outline"
on:click={() => {
if ($exportState === ExportState.SELECTION) {
exportSelectedFiles();
} else if ($exportState === ExportState.ALL) {
exportAllFiles();
}
open = false;
$exportState = ExportState.NONE;
}}
>
<Download size="16" class="mr-1" />
{#if $fileObservers.size === 1 || ($exportState === ExportState.SELECTION && $selection.size === 1)}
{$_('menu.download_file')}
{:else}
{$_('menu.download_files')}
{/if}
</Button>
<Button variant="outline">
<Cloud size="16" class="mr-1" />
{$_('menu.save_drive')}
</Button>
</div>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>

View File

@@ -1,8 +1,8 @@
<script lang="ts"> <script lang="ts">
import * as Menubar from '$lib/components/ui/menubar/index.js'; import * as Menubar from '$lib/components/ui/menubar/index.js';
import { Button } from '$lib/components/ui/button'; import { Button } from '$lib/components/ui/button';
import Logo from './Logo.svelte'; import Logo from '$lib/components/Logo.svelte';
import Shortcut from './Shortcut.svelte'; import Shortcut from '$lib/components/Shortcut.svelte';
import { import {
Plus, Plus,
Copy, Copy,
@@ -44,8 +44,6 @@
import { import {
map, map,
exportAllFiles,
exportSelectedFiles,
triggerFileInput, triggerFileInput,
createFile, createFile,
loadFiles, loadFiles,
@@ -55,7 +53,9 @@
hideSelection, hideSelection,
anyHidden, anyHidden,
editMetadata, editMetadata,
editStyle editStyle,
exportState,
ExportState
} from '$lib/stores'; } from '$lib/stores';
import { import {
copied, copied,
@@ -70,6 +70,8 @@
import { anySelectedLayer } from '$lib/components/layer-control/utils'; import { anySelectedLayer } from '$lib/components/layer-control/utils';
import { defaultOverlays } from '$lib/assets/layers'; import { defaultOverlays } from '$lib/assets/layers';
import LayerControlSettings from '$lib/components/layer-control/LayerControlSettings.svelte'; import LayerControlSettings from '$lib/components/layer-control/LayerControlSettings.svelte';
import { allowedPastes, ListFileItem, ListTrackItem } from '$lib/components/file-list/FileList';
import Export from '$lib/components/Export.svelte';
import { resetMode, setMode, systemPrefersMode } from 'mode-watcher'; import { resetMode, setMode, systemPrefersMode } from 'mode-watcher';
@@ -77,7 +79,6 @@
import { languages } from '$lib/languages'; import { languages } from '$lib/languages';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { base } from '$app/paths'; import { base } from '$app/paths';
import { allowedPastes, ListFileItem, ListTrackItem } from './file-list/FileList';
const { const {
distanceUnits, distanceUnits,
@@ -164,12 +165,18 @@
<Shortcut key="D" ctrl={true} /> <Shortcut key="D" ctrl={true} />
</Menubar.Item> </Menubar.Item>
<Menubar.Separator /> <Menubar.Separator />
<Menubar.Item on:click={exportSelectedFiles} disabled={$selection.size == 0}> <Menubar.Item
on:click={() => ($exportState = ExportState.SELECTION)}
disabled={$selection.size == 0}
>
<Download size="16" class="mr-1" /> <Download size="16" class="mr-1" />
{$_('menu.export')} {$_('menu.export')}
<Shortcut key="S" ctrl={true} /> <Shortcut key="S" ctrl={true} />
</Menubar.Item> </Menubar.Item>
<Menubar.Item on:click={exportAllFiles} disabled={$fileObservers.size == 0}> <Menubar.Item
on:click={() => ($exportState = ExportState.ALL)}
disabled={$fileObservers.size == 0}
>
<Download size="16" class="mr-1" /> <Download size="16" class="mr-1" />
{$_('menu.export_all')} {$_('menu.export_all')}
<Shortcut key="S" ctrl={true} shift={true} /> <Shortcut key="S" ctrl={true} shift={true} />
@@ -452,6 +459,7 @@
</div> </div>
</div> </div>
<Export />
<LayerControlSettings bind:open={layerSettingsOpen} /> <LayerControlSettings bind:open={layerSettingsOpen} />
<svelte:window <svelte:window
@@ -478,9 +486,11 @@
} }
} else if ((e.key === 's' || e.key == 'S') && (e.metaKey || e.ctrlKey)) { } else if ((e.key === 's' || e.key == 'S') && (e.metaKey || e.ctrlKey)) {
if (e.shiftKey) { if (e.shiftKey) {
exportAllFiles(); if ($fileObservers.size > 0) {
} else { $exportState = ExportState.ALL;
exportSelectedFiles(); }
} else if ($selection.size > 0) {
$exportState = ExportState.SELECTION;
} }
e.preventDefault(); e.preventDefault();
} else if ((e.key === 'z' || e.key == 'Z') && (e.metaKey || e.ctrlKey)) { } else if ((e.key === 'z' || e.key == 'Z') && (e.metaKey || e.ctrlKey)) {

View File

@@ -312,26 +312,26 @@ export function updateSelectionFromKey(down: boolean, shift: boolean) {
} }
} }
export function exportSelectedFiles() { async function exportFiles(fileIds: string[]) {
get(selection).forEach(async (item) => { for (let fileId of fileIds) {
if (item instanceof ListFileItem) { let file = getFile(fileId);
let file = getFile(item.getFileId()); if (file) {
if (file) { exportFile(file);
exportFile(file); await new Promise(resolve => setTimeout(resolve, 200));
await new Promise(resolve => setTimeout(resolve, 200));
}
} }
}
}
export function exportSelectedFiles() {
let fileIds: string[] = [];
applyToOrderedSelectedItemsFromFile(async (fileId, level, items) => {
fileIds.push(fileId);
}); });
exportFiles(fileIds);
} }
export function exportAllFiles() { export function exportAllFiles() {
get(fileObservers).forEach(async (file) => { exportFiles(get(fileOrder));
let f = get(file);
if (f) {
exportFile(f.file);
await new Promise(resolve => setTimeout(resolve, 200));
}
});
} }
export function exportFile(file: GPXFile) { export function exportFile(file: GPXFile) {
@@ -398,6 +398,13 @@ export function showSelection() {
export const editMetadata = writable(false); export const editMetadata = writable(false);
export const editStyle = writable(false); export const editStyle = writable(false);
export enum ExportState {
NONE,
SELECTION,
ALL
}
export const exportState = writable<ExportState>(ExportState.NONE);
let stravaCookies: any = null; let stravaCookies: any = null;
function refreshStravaCookies() { function refreshStravaCookies() {
/* /*

View File

@@ -17,6 +17,11 @@
"cut": "Cut", "cut": "Cut",
"export": "Export...", "export": "Export...",
"export_all": "Export all...", "export_all": "Export all...",
"support_message": "The tool is free to use, but not free to run. Please consider supporting the website if you use it frequently.",
"support_button": "Help keep the website free",
"download_file": "Download file",
"download_files": "Download files",
"save_drive": "Save to Google Drive",
"edit": "Edit", "edit": "Edit",
"undo": "Undo", "undo": "Undo",
"redo": "Redo", "redo": "Redo",