mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-08-31 15:43:25 +00:00
load file shortcut
This commit is contained in:
16
website/src/lib/components/FileList.svelte
Normal file
16
website/src/lib/components/FileList.svelte
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { files } from '$lib/stores';
|
||||||
|
|
||||||
|
import { ScrollArea } from '$lib/components/ui/scroll-area/index.js';
|
||||||
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ScrollArea class="w-full h-full">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
{#each $files as file}
|
||||||
|
<Button variant="outline" class="w-full">
|
||||||
|
{file.metadata.name}
|
||||||
|
</Button>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</ScrollArea>
|
@@ -1,38 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { parseGPX } from 'gpx';
|
|
||||||
|
|
||||||
import * as Menubar from '$lib/components/ui/menubar/index.js';
|
import * as Menubar from '$lib/components/ui/menubar/index.js';
|
||||||
|
|
||||||
import { Upload } from 'lucide-svelte';
|
import { Upload } from 'lucide-svelte';
|
||||||
|
|
||||||
import { files } from '$lib/stores';
|
import { triggerFileInput } from '$lib/components/tools/tools';
|
||||||
|
|
||||||
let input: HTMLInputElement;
|
|
||||||
|
|
||||||
$: if (input) {
|
|
||||||
input.onchange = () => {
|
|
||||||
if (input.files) {
|
|
||||||
for (let i = 0; i < input.files.length; i++) {
|
|
||||||
const file = input.files[i];
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.onload = () => {
|
|
||||||
$files = [...$files, parseGPX(reader.result?.toString() ?? '')];
|
|
||||||
};
|
|
||||||
reader.readAsText(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Menubar.Item
|
<Menubar.Item on:click={triggerFileInput}>
|
||||||
on:click={() => {
|
|
||||||
if (input) {
|
|
||||||
input.click();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Upload size="16" class="mr-1" /> Load from desktop... <Menubar.Shortcut>⌘O</Menubar.Shortcut>
|
<Upload size="16" class="mr-1" /> Load from desktop... <Menubar.Shortcut>⌘O</Menubar.Shortcut>
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
|
|
||||||
<input bind:this={input} type="file" accept=".gpx" multiple class="hidden" />
|
|
||||||
|
38
website/src/lib/components/tools/tools.ts
Normal file
38
website/src/lib/components/tools/tools.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { files } from '$lib/stores';
|
||||||
|
|
||||||
|
import { parseGPX } from 'gpx';
|
||||||
|
|
||||||
|
export function triggerFileInput() {
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.type = 'file';
|
||||||
|
input.accept = '.gpx';
|
||||||
|
input.multiple = true;
|
||||||
|
input.className = 'hidden';
|
||||||
|
input.onchange = () => {
|
||||||
|
if (input.files) {
|
||||||
|
loadFiles(input.files);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
input.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadFiles(files: FileList) {
|
||||||
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
loadFile(files[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadFile(file: File) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = () => {
|
||||||
|
let data = reader.result?.toString() ?? null;
|
||||||
|
if (data) {
|
||||||
|
let gpx = parseGPX(data);
|
||||||
|
if (gpx.metadata.name === undefined) {
|
||||||
|
gpx.metadata['name'] = file.name.split('.').slice(0, -1).join('.');
|
||||||
|
}
|
||||||
|
files.update($files => [...$files, gpx]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.readAsText(file);
|
||||||
|
}
|
@@ -1,9 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Data from '$lib/components/Data.svelte';
|
import Data from '$lib/components/Data.svelte';
|
||||||
|
import FileList from '$lib/components/FileList.svelte';
|
||||||
import Map from '$lib/components/Map.svelte';
|
import Map from '$lib/components/Map.svelte';
|
||||||
import Menu from '$lib/components/Menu.svelte';
|
import Menu from '$lib/components/Menu.svelte';
|
||||||
import Toolbar from '$lib/components/Toolbar.svelte';
|
import Toolbar from '$lib/components/Toolbar.svelte';
|
||||||
import LayerControl from '$lib/components/layer-control/LayerControl.svelte';
|
import LayerControl from '$lib/components/layer-control/LayerControl.svelte';
|
||||||
|
|
||||||
|
import { triggerFileInput } from '$lib/components/tools/tools';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col w-screen h-screen">
|
<div class="flex flex-col w-screen h-screen">
|
||||||
@@ -14,5 +17,16 @@
|
|||||||
<LayerControl />
|
<LayerControl />
|
||||||
<Data />
|
<Data />
|
||||||
</div>
|
</div>
|
||||||
<div class="h-12">Test</div>
|
<div class="h-60 flex flex-row">
|
||||||
|
<FileList />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<svelte:window
|
||||||
|
on:keydown={(e) => {
|
||||||
|
if (e.key === 'o' && (e.metaKey || e.ctrlKey)) {
|
||||||
|
triggerFileInput();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
Reference in New Issue
Block a user