Files
gpx.studio/website/src/lib/components/Menu.svelte

579 lines
18 KiB
Svelte
Raw Normal View History

2024-04-08 17:12:39 +02:00
<script lang="ts">
import * as Menubar from '$lib/components/ui/menubar/index.js';
import { Button } from '$lib/components/ui/button';
2024-06-28 15:43:57 +02:00
import Logo from '$lib/components/Logo.svelte';
import Shortcut from '$lib/components/Shortcut.svelte';
2024-05-08 12:00:04 +02:00
import {
Plus,
Copy,
Download,
Undo2,
Redo2,
Trash2,
Heart,
Map,
Layers2,
2024-05-08 12:35:31 +02:00
Box,
Milestone,
Coins,
Ruler,
Zap,
Thermometer,
Sun,
2024-05-22 16:05:31 +02:00
Moon,
2024-06-09 17:22:41 +02:00
Layers3,
2024-06-10 12:06:32 +02:00
MountainSnow,
2024-06-19 19:42:36 +02:00
GalleryVertical,
2024-06-20 11:59:21 +02:00
Languages,
Settings,
Info,
File,
View,
FilePen,
2024-06-24 19:41:44 +02:00
HeartHandshake,
2024-06-27 18:23:11 +02:00
PersonStanding,
Eye,
EyeOff,
ClipboardCopy,
Scissors,
ClipboardPaste,
2024-07-01 11:08:28 +02:00
PaintBucket,
FolderOpen,
FileStack,
2024-07-13 12:02:04 +02:00
FileX,
BookOpenText
2024-05-08 12:00:04 +02:00
} from 'lucide-svelte';
2024-04-18 10:55:55 +02:00
2024-04-18 15:30:19 +02:00
import {
2024-05-08 12:00:04 +02:00
map,
2024-04-22 11:45:57 +02:00
triggerFileInput,
2024-06-11 19:27:10 +02:00
createFile,
2024-06-19 18:11:05 +02:00
loadFiles,
2024-06-27 18:23:11 +02:00
updateSelectionFromKey,
2024-07-02 20:04:17 +02:00
allHidden,
2024-06-27 18:23:11 +02:00
editMetadata,
2024-06-28 15:43:57 +02:00
editStyle,
exportState,
ExportState
2024-04-18 15:30:19 +02:00
} from '$lib/stores';
2024-06-20 15:18:21 +02:00
import {
2024-06-27 18:23:11 +02:00
copied,
2024-06-20 15:18:21 +02:00
copySelection,
cutSelection,
pasteSelection,
selectAll,
selection
} from '$lib/components/file-list/Selection';
import { derived } from 'svelte/store';
2024-05-04 15:10:30 +02:00
import { canUndo, canRedo, dbUtils, fileObservers, settings } from '$lib/db';
2024-05-23 11:21:57 +02:00
import { anySelectedLayer } from '$lib/components/layer-control/utils';
import { defaultOverlays } from '$lib/assets/layers';
import LayerControlSettings from '$lib/components/layer-control/LayerControlSettings.svelte';
2024-06-28 15:43:57 +02:00
import { allowedPastes, ListFileItem, ListTrackItem } from '$lib/components/file-list/FileList';
import Export from '$lib/components/Export.svelte';
2024-07-05 18:47:37 +02:00
import { mode, setMode, systemPrefersMode } from 'mode-watcher';
2024-06-19 19:42:36 +02:00
import { _, locale } from 'svelte-i18n';
2024-07-08 19:13:31 +02:00
import { languages } from '$lib/languages';
import { getURLForLanguage } from '$lib/utils';
2024-04-24 16:12:50 +02:00
2024-05-04 23:50:27 +02:00
const {
distanceUnits,
velocityUnits,
temperatureUnits,
2024-06-09 17:22:41 +02:00
elevationProfile,
2024-05-22 16:05:31 +02:00
verticalFileView,
2024-05-04 23:50:27 +02:00
currentBasemap,
previousBasemap,
currentOverlays,
2024-05-08 12:35:31 +02:00
previousOverlays,
distanceMarkers,
2024-06-24 19:41:44 +02:00
directionMarkers,
2024-07-16 15:48:01 +02:00
streetViewSource,
routing
2024-05-04 23:50:27 +02:00
} = settings;
2024-05-08 12:35:31 +02:00
2024-05-02 19:51:08 +02:00
let undoDisabled = derived(canUndo, ($canUndo) => !$canUndo);
2024-05-03 15:59:34 +02:00
let redoDisabled = derived(canRedo, ($canRedo) => !$canRedo);
2024-05-06 15:52:11 +02:00
function switchBasemaps() {
[$currentBasemap, $previousBasemap] = [$previousBasemap, $currentBasemap];
}
function toggleOverlays() {
if (anySelectedLayer($currentOverlays)) {
[$currentOverlays, $previousOverlays] = [defaultOverlays, $currentOverlays];
} else {
[$currentOverlays, $previousOverlays] = [$previousOverlays, defaultOverlays];
}
}
2024-05-08 12:00:04 +02:00
function toggle3D() {
if ($map) {
if ($map.getPitch() === 0) {
$map.easeTo({ pitch: 70 });
} else {
$map.easeTo({ pitch: 0 });
}
}
}
2024-05-23 11:21:57 +02:00
let layerSettingsOpen = false;
2024-07-05 18:47:37 +02:00
$: selectedMode = $mode ?? $systemPrefersMode ?? 'light';
2024-04-08 17:12:39 +02:00
</script>
2024-06-20 11:59:21 +02:00
<div class="absolute md:top-2 left-0 right-0 z-20 flex flex-row justify-center pointer-events-none">
2024-04-10 14:54:35 +02:00
<div
2024-06-20 11:59:21 +02:00
class="w-fit flex flex-row items-center justify-center p-1 bg-background rounded-b-md md:rounded-md pointer-events-auto shadow-md"
2024-04-10 14:54:35 +02:00
>
2024-07-12 15:22:36 +02:00
<a href="./" target="_blank">
2024-07-08 15:46:00 +02:00
<Logo class="h-5 mt-0.5 mx-2 md:hidden" iconOnly={true} />
<Logo class="h-5 mt-0.5 mx-2 hidden md:block" />
</a>
2024-04-09 18:46:01 +02:00
<Menubar.Root class="border-none h-fit p-0">
2024-04-09 17:21:26 +02:00
<Menubar.Menu>
2024-06-20 11:59:21 +02:00
<Menubar.Trigger>
<File size="18" class="md:hidden" />
<span class="hidden md:block">{$_('gpx.file')}</span>
</Menubar.Trigger>
2024-04-26 12:30:39 +02:00
<Menubar.Content class="border-none">
2024-04-27 12:18:40 +02:00
<Menubar.Item on:click={createFile}>
2024-04-24 16:12:50 +02:00
<Plus size="16" class="mr-1" />
2024-06-12 15:29:54 +02:00
{$_('menu.new')}
<Shortcut key="+" ctrl={true} />
2024-04-09 17:21:26 +02:00
</Menubar.Item>
2024-04-18 15:49:20 +02:00
<Menubar.Separator />
2024-04-18 10:55:55 +02:00
<Menubar.Item on:click={triggerFileInput}>
2024-07-01 11:08:28 +02:00
<FolderOpen size="16" class="mr-1" />
{$_('menu.open')}
2024-04-29 17:03:23 +02:00
<Shortcut key="O" ctrl={true} />
2024-04-18 10:55:55 +02:00
</Menubar.Item>
2024-04-15 10:33:47 +02:00
<Menubar.Separator />
2024-05-22 16:05:31 +02:00
<Menubar.Item on:click={dbUtils.duplicateSelection} disabled={$selection.size == 0}>
2024-04-24 17:39:56 +02:00
<Copy size="16" class="mr-1" />
{$_('menu.duplicate')}
2024-04-29 17:03:23 +02:00
<Shortcut key="D" ctrl={true} />
2024-04-09 17:21:26 +02:00
</Menubar.Item>
<Menubar.Separator />
2024-07-01 11:08:28 +02:00
<Menubar.Item on:click={dbUtils.deleteSelectedFiles} disabled={$selection.size == 0}>
<FileX size="16" class="mr-1" />
{$_('menu.close')}
<Shortcut key="⌫" ctrl={true} />
</Menubar.Item>
<Menubar.Item on:click={dbUtils.deleteAllFiles} disabled={$fileObservers.size == 0}>
<FileX size="16" class="mr-1" />
{$_('menu.close_all')}
<Shortcut key="⌫" ctrl={true} shift={true} />
</Menubar.Item>
<Menubar.Separator />
2024-06-28 15:43:57 +02:00
<Menubar.Item
on:click={() => ($exportState = ExportState.SELECTION)}
disabled={$selection.size == 0}
>
2024-04-24 17:39:56 +02:00
<Download size="16" class="mr-1" />
{$_('menu.export')}
2024-04-29 17:03:23 +02:00
<Shortcut key="S" ctrl={true} />
2024-04-09 17:21:26 +02:00
</Menubar.Item>
2024-06-28 15:43:57 +02:00
<Menubar.Item
on:click={() => ($exportState = ExportState.ALL)}
disabled={$fileObservers.size == 0}
>
2024-04-24 17:39:56 +02:00
<Download size="16" class="mr-1" />
{$_('menu.export_all')}
2024-04-29 17:03:23 +02:00
<Shortcut key="S" ctrl={true} shift={true} />
2024-04-09 17:21:26 +02:00
</Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
2024-06-20 11:59:21 +02:00
<Menubar.Trigger>
<FilePen size="18" class="md:hidden" />
<span class="hidden md:block">{$_('menu.edit')}</span>
</Menubar.Trigger>
2024-04-26 12:30:39 +02:00
<Menubar.Content class="border-none">
2024-05-04 14:27:12 +02:00
<Menubar.Item on:click={dbUtils.undo} disabled={$undoDisabled}>
2024-04-24 17:39:56 +02:00
<Undo2 size="16" class="mr-1" />
{$_('menu.undo')}
2024-04-29 17:03:23 +02:00
<Shortcut key="Z" ctrl={true} />
2024-04-09 17:21:26 +02:00
</Menubar.Item>
2024-05-04 14:27:12 +02:00
<Menubar.Item on:click={dbUtils.redo} disabled={$redoDisabled}>
2024-04-24 17:39:56 +02:00
<Redo2 size="16" class="mr-1" />
{$_('menu.redo')}
2024-04-29 17:03:23 +02:00
<Shortcut key="Z" ctrl={true} shift={true} />
</Menubar.Item>
<Menubar.Separator />
2024-06-27 18:23:11 +02:00
<Menubar.Item
disabled={$selection.size !== 1 ||
!$selection
.getSelected()
.every((item) => item instanceof ListFileItem || item instanceof ListTrackItem)}
on:click={() => ($editMetadata = true)}
>
<Info size="16" class="mr-1" />
{$_('menu.metadata.button')}
2024-07-02 10:21:04 +02:00
<Shortcut key="I" ctrl={true} />
2024-06-27 18:23:11 +02:00
</Menubar.Item>
<Menubar.Item
disabled={$selection.size === 0 ||
!$selection
.getSelected()
.every((item) => item instanceof ListFileItem || item instanceof ListTrackItem)}
on:click={() => ($editStyle = true)}
>
<PaintBucket size="16" class="mr-1" />
{$_('menu.style.button')}
</Menubar.Item>
<Menubar.Item
on:click={() => {
2024-07-02 20:04:17 +02:00
if ($allHidden) {
dbUtils.setHiddenToSelection(false);
2024-06-27 18:23:11 +02:00
} else {
2024-07-02 20:04:17 +02:00
dbUtils.setHiddenToSelection(true);
2024-06-27 18:23:11 +02:00
}
}}
disabled={$selection.size == 0}
>
2024-07-02 20:04:17 +02:00
{#if $allHidden}
2024-06-27 18:23:11 +02:00
<Eye size="16" class="mr-1" />
{$_('menu.unhide')}
{:else}
<EyeOff size="16" class="mr-1" />
{$_('menu.hide')}
{/if}
<Shortcut key="H" ctrl={true} />
</Menubar.Item>
<Menubar.Separator />
2024-07-02 20:04:17 +02:00
<Menubar.Item on:click={selectAll} disabled={$fileObservers.size == 0}>
2024-07-01 11:08:28 +02:00
<FileStack size="16" class="mr-1" />
2024-04-29 17:03:23 +02:00
{$_('menu.select_all')}
<Shortcut key="A" ctrl={true} />
2024-04-09 17:21:26 +02:00
</Menubar.Item>
2024-06-27 18:23:11 +02:00
{#if $verticalFileView}
<Menubar.Separator />
<Menubar.Item on:click={copySelection} disabled={$selection.size === 0}>
<ClipboardCopy size="16" class="mr-1" />
{$_('menu.copy')}
<Shortcut key="C" ctrl={true} />
</Menubar.Item>
<Menubar.Item on:click={cutSelection} disabled={$selection.size === 0}>
<Scissors size="16" class="mr-1" />
{$_('menu.cut')}
<Shortcut key="X" ctrl={true} />
</Menubar.Item>
<Menubar.Item
disabled={$copied === undefined ||
$copied.length === 0 ||
($selection.size > 0 &&
!allowedPastes[$copied[0].level].includes($selection.getSelected().pop()?.level))}
on:click={pasteSelection}
>
<ClipboardPaste size="16" class="mr-1" />
{$_('menu.paste')}
<Shortcut key="V" ctrl={true} />
</Menubar.Item>
{/if}
2024-04-09 17:21:26 +02:00
<Menubar.Separator />
2024-05-22 16:05:31 +02:00
<Menubar.Item on:click={dbUtils.deleteSelection} disabled={$selection.size == 0}>
2024-04-24 17:39:56 +02:00
<Trash2 size="16" class="mr-1" />
{$_('menu.delete')}
2024-04-29 17:03:23 +02:00
<Shortcut key="⌫" ctrl={true} />
</Menubar.Item>
2024-04-09 17:21:26 +02:00
</Menubar.Content>
</Menubar.Menu>
2024-05-06 15:52:11 +02:00
<Menubar.Menu>
2024-06-20 11:59:21 +02:00
<Menubar.Trigger>
<View size="18" class="md:hidden" />
<span class="hidden md:block">{$_('menu.view')}</span>
</Menubar.Trigger>
2024-05-06 15:52:11 +02:00
<Menubar.Content class="border-none">
2024-06-09 17:22:41 +02:00
<Menubar.CheckboxItem bind:checked={$elevationProfile}>
2024-06-19 17:34:07 +02:00
<MountainSnow size="16" class="mr-1" />
{$_('menu.elevation_profile')}
<Shortcut key="P" ctrl={true} />
2024-06-09 17:22:41 +02:00
</Menubar.CheckboxItem>
2024-05-22 16:05:31 +02:00
<Menubar.CheckboxItem bind:checked={$verticalFileView}>
2024-06-19 17:34:07 +02:00
<GalleryVertical size="16" class="mr-1" />
{$_('menu.vertical_file_view')}
<Shortcut key="L" ctrl={true} />
2024-05-22 16:05:31 +02:00
</Menubar.CheckboxItem>
<Menubar.Separator />
2024-06-19 17:34:07 +02:00
<Menubar.Item inset on:click={switchBasemaps}>
<Map size="16" class="mr-1" />{$_('menu.switch_basemap')}<Shortcut key="F1" />
</Menubar.Item>
<Menubar.Item inset on:click={toggleOverlays}>
<Layers2 size="16" class="mr-1" />{$_('menu.toggle_overlays')}<Shortcut key="F2" />
</Menubar.Item>
2024-05-08 12:00:04 +02:00
<Menubar.Separator />
2024-05-08 12:35:31 +02:00
<Menubar.CheckboxItem bind:checked={$distanceMarkers}>
2024-06-19 17:34:07 +02:00
<Coins size="16" class="mr-1" />{$_('menu.distance_markers')}<Shortcut key="F3" />
2024-05-08 12:35:31 +02:00
</Menubar.CheckboxItem>
<Menubar.CheckboxItem bind:checked={$directionMarkers}>
2024-06-19 17:34:07 +02:00
<Milestone size="16" class="mr-1" />{$_('menu.direction_markers')}<Shortcut key="F4" />
2024-05-08 12:35:31 +02:00
</Menubar.CheckboxItem>
2024-05-08 12:37:06 +02:00
<Menubar.Separator />
2024-06-19 17:34:07 +02:00
<Menubar.Item inset on:click={toggle3D}>
<Box size="16" class="mr-1" />
{$_('menu.toggle_3d')}
<Shortcut key="{$_('menu.ctrl')}+{$_('menu.drag')}" />
</Menubar.Item>
2024-05-06 15:52:11 +02:00
</Menubar.Content>
</Menubar.Menu>
2024-04-09 17:21:26 +02:00
<Menubar.Menu>
2024-06-20 11:59:21 +02:00
<Menubar.Trigger>
<Settings size="18" class="md:hidden" />
<span class="hidden md:block">
{$_('menu.settings')}
</span>
</Menubar.Trigger>
2024-04-26 12:30:39 +02:00
<Menubar.Content class="border-none"
2024-04-09 17:21:26 +02:00
><Menubar.Sub>
2024-06-19 17:34:07 +02:00
<Menubar.SubTrigger>
<Ruler size="16" class="mr-1" />{$_('menu.distance_units')}
</Menubar.SubTrigger>
2024-04-09 17:21:26 +02:00
<Menubar.SubContent>
2024-05-04 15:10:30 +02:00
<Menubar.RadioGroup bind:value={$distanceUnits}>
2024-04-24 17:39:56 +02:00
<Menubar.RadioItem value="metric">{$_('menu.metric')}</Menubar.RadioItem>
<Menubar.RadioItem value="imperial">{$_('menu.imperial')}</Menubar.RadioItem>
2024-04-09 17:21:26 +02:00
</Menubar.RadioGroup>
</Menubar.SubContent>
</Menubar.Sub>
<Menubar.Sub>
2024-05-08 12:35:31 +02:00
<Menubar.SubTrigger
><Zap size="16" class="mr-1" />{$_('menu.velocity_units')}</Menubar.SubTrigger
>
2024-04-09 17:21:26 +02:00
<Menubar.SubContent>
2024-05-04 15:10:30 +02:00
<Menubar.RadioGroup bind:value={$velocityUnits}>
2024-04-24 17:39:56 +02:00
<Menubar.RadioItem value="speed">{$_('quantities.speed')}</Menubar.RadioItem>
<Menubar.RadioItem value="pace">{$_('quantities.pace')}</Menubar.RadioItem>
2024-04-09 17:21:26 +02:00
</Menubar.RadioGroup>
</Menubar.SubContent>
</Menubar.Sub>
2024-04-24 16:12:50 +02:00
<Menubar.Sub>
2024-06-19 17:34:07 +02:00
<Menubar.SubTrigger>
<Thermometer size="16" class="mr-1" />{$_('menu.temperature_units')}
</Menubar.SubTrigger>
2024-04-24 16:12:50 +02:00
<Menubar.SubContent>
2024-05-04 15:10:30 +02:00
<Menubar.RadioGroup bind:value={$temperatureUnits}>
2024-04-24 17:39:56 +02:00
<Menubar.RadioItem value="celsius">{$_('menu.celsius')}</Menubar.RadioItem>
<Menubar.RadioItem value="fahrenheit">{$_('menu.fahrenheit')}</Menubar.RadioItem>
2024-04-24 16:12:50 +02:00
</Menubar.RadioGroup>
</Menubar.SubContent>
</Menubar.Sub>
2024-04-09 17:21:26 +02:00
<Menubar.Separator />
2024-06-19 19:42:36 +02:00
<Menubar.Sub>
<Menubar.SubTrigger>
<Languages size="16" class="mr-1" />
{$_('menu.language')}
</Menubar.SubTrigger>
<Menubar.SubContent>
2024-07-08 15:46:00 +02:00
<Menubar.RadioGroup bind:value={$locale}>
2024-07-08 18:54:16 +02:00
{#each Object.entries(languages) as [lang, label]}
2024-07-08 23:22:37 +02:00
<a href={getURLForLanguage(lang)}>
2024-07-08 18:54:16 +02:00
<Menubar.RadioItem value={lang}>{label}</Menubar.RadioItem>
2024-07-08 15:46:00 +02:00
</a>
2024-06-19 19:42:36 +02:00
{/each}
</Menubar.RadioGroup>
</Menubar.SubContent>
</Menubar.Sub>
2024-04-27 11:16:59 +02:00
<Menubar.Sub>
2024-05-08 12:35:31 +02:00
<Menubar.SubTrigger>
2024-07-05 18:47:37 +02:00
{#if selectedMode === 'light'}
2024-05-08 12:35:31 +02:00
<Sun size="16" class="mr-1" />
2024-07-05 18:47:37 +02:00
{:else}
2024-05-08 12:35:31 +02:00
<Moon size="16" class="mr-1" />
{/if}
{$_('menu.mode')}
</Menubar.SubTrigger>
2024-04-27 11:16:59 +02:00
<Menubar.SubContent>
2024-07-05 18:47:37 +02:00
<Menubar.RadioGroup
bind:value={selectedMode}
onValueChange={(value) => {
setMode(value);
}}
>
2024-04-27 11:16:59 +02:00
<Menubar.RadioItem value="light">{$_('menu.light')}</Menubar.RadioItem>
<Menubar.RadioItem value="dark">{$_('menu.dark')}</Menubar.RadioItem>
</Menubar.RadioGroup>
</Menubar.SubContent>
</Menubar.Sub>
2024-05-23 11:21:57 +02:00
<Menubar.Separator />
2024-06-24 19:41:44 +02:00
<Menubar.Sub>
<Menubar.SubTrigger>
<PersonStanding size="16" class="mr-1" />
{$_('menu.street_view_source')}
</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.RadioGroup bind:value={$streetViewSource}>
<Menubar.RadioItem value="mapillary">{$_('menu.mapillary')}</Menubar.RadioItem>
<Menubar.RadioItem value="google">{$_('menu.google')}</Menubar.RadioItem>
</Menubar.RadioGroup>
</Menubar.SubContent>
</Menubar.Sub>
2024-05-23 11:21:57 +02:00
<Menubar.Item on:click={() => (layerSettingsOpen = true)}>
<Layers3 size="16" class="mr-1" />
{$_('menu.layers')}
</Menubar.Item>
2024-04-09 17:21:26 +02:00
</Menubar.Content>
</Menubar.Menu>
</Menubar.Root>
2024-04-12 15:12:27 +02:00
<div class="h-fit flex flex-row items-center ml-1 gap-1">
2024-06-20 11:59:21 +02:00
<Button
variant="ghost"
2024-07-12 15:22:36 +02:00
href="./help"
2024-06-20 11:59:21 +02:00
target="_blank"
2024-07-08 15:46:00 +02:00
class="cursor-default h-fit rounded-sm px-3 py-0.5"
2024-04-09 17:21:26 +02:00
>
2024-07-13 12:02:04 +02:00
<BookOpenText size="18" class="md:hidden" />
2024-06-20 11:59:21 +02:00
<span class="hidden md:block">
2024-07-08 15:46:00 +02:00
{$_('menu.help')}
2024-06-20 11:59:21 +02:00
</span>
</Button>
2024-04-09 17:21:26 +02:00
<Button
variant="ghost"
href="https://ko-fi.com/gpxstudio"
target="_blank"
2024-07-08 15:46:00 +02:00
class="cursor-default h-fit rounded-sm font-bold text-support hover:text-support px-3 py-0.5"
2024-04-09 17:21:26 +02:00
>
2024-06-20 11:59:21 +02:00
<HeartHandshake size="18" class="md:hidden" />
<span class="hidden md:flex flex-row items-center">
{$_('menu.donate')}
<Heart size="16" class="ml-1" fill="rgb(var(--support))" />
</span>
</Button>
2024-04-09 17:21:26 +02:00
</div>
2024-04-08 17:12:39 +02:00
</div>
</div>
2024-04-09 18:46:01 +02:00
2024-06-28 15:43:57 +02:00
<Export />
2024-05-23 11:21:57 +02:00
<LayerControlSettings bind:open={layerSettingsOpen} />
2024-04-18 15:30:19 +02:00
<svelte:window
on:keydown={(e) => {
let targetInput =
e.target.tagName === 'INPUT' ||
e.target.tagName === 'TEXTAREA' ||
e.target.tagName === 'SELECT' ||
e.target.role === 'combobox' ||
e.target.role === 'radio' ||
e.target.role === 'menu' ||
e.target.role === 'menuitem' ||
e.target.role === 'menuitemradio' ||
e.target.role === 'menuitemcheckbox';
2024-06-12 15:29:54 +02:00
if (e.key === '+' && (e.metaKey || e.ctrlKey)) {
2024-04-27 12:18:40 +02:00
createFile();
e.preventDefault();
} else if (e.key === 'o' && (e.metaKey || e.ctrlKey)) {
2024-04-18 15:30:19 +02:00
triggerFileInput();
e.preventDefault();
} else if (e.key === 'd' && (e.metaKey || e.ctrlKey)) {
2024-05-22 16:05:31 +02:00
dbUtils.duplicateSelection();
2024-04-18 15:30:19 +02:00
e.preventDefault();
2024-06-20 15:18:21 +02:00
} else if (e.key === 'c' && (e.metaKey || e.ctrlKey)) {
if (!targetInput) {
copySelection();
e.preventDefault();
}
2024-06-20 15:18:21 +02:00
} else if (e.key === 'x' && (e.metaKey || e.ctrlKey)) {
if (!targetInput) {
cutSelection();
e.preventDefault();
}
2024-06-20 15:18:21 +02:00
} else if (e.key === 'v' && (e.metaKey || e.ctrlKey)) {
if (!targetInput) {
2024-06-26 17:19:41 +02:00
pasteSelection();
e.preventDefault();
}
2024-04-18 15:48:07 +02:00
} else if ((e.key === 's' || e.key == 'S') && (e.metaKey || e.ctrlKey)) {
2024-04-18 15:30:19 +02:00
if (e.shiftKey) {
2024-06-28 15:43:57 +02:00
if ($fileObservers.size > 0) {
$exportState = ExportState.ALL;
}
} else if ($selection.size > 0) {
$exportState = ExportState.SELECTION;
2024-04-18 15:30:19 +02:00
}
e.preventDefault();
2024-04-30 22:35:54 +02:00
} else if ((e.key === 'z' || e.key == 'Z') && (e.metaKey || e.ctrlKey)) {
if (e.shiftKey) {
2024-05-04 14:27:12 +02:00
dbUtils.redo();
2024-04-30 22:35:54 +02:00
} else {
2024-05-04 14:27:12 +02:00
dbUtils.undo();
2024-04-30 22:35:54 +02:00
}
2024-04-18 15:30:19 +02:00
} else if ((e.key === 'Backspace' || e.key === 'Delete') && (e.metaKey || e.ctrlKey)) {
if (e.shiftKey) {
2024-05-02 19:51:08 +02:00
dbUtils.deleteAllFiles();
2024-04-18 15:30:19 +02:00
} else {
2024-05-22 16:05:31 +02:00
dbUtils.deleteSelection();
2024-04-18 15:30:19 +02:00
}
e.preventDefault();
2024-04-22 11:45:57 +02:00
} else if (e.key === 'a' && (e.metaKey || e.ctrlKey)) {
if (!targetInput) {
selectAll();
e.preventDefault();
}
2024-07-02 10:21:04 +02:00
} else if (e.key === 'i' && (e.metaKey || e.ctrlKey)) {
if (
$selection.size === 1 &&
$selection
.getSelected()
.every((item) => item instanceof ListFileItem || item instanceof ListTrackItem)
) {
$editMetadata = true;
}
e.preventDefault();
2024-06-19 17:34:07 +02:00
} else if (e.key === 'p' && (e.metaKey || e.ctrlKey)) {
$elevationProfile = !$elevationProfile;
e.preventDefault();
} else if (e.key === 'l' && (e.metaKey || e.ctrlKey)) {
$verticalFileView = !$verticalFileView;
e.preventDefault();
2024-06-19 18:11:05 +02:00
} else if (e.key === 'h' && (e.metaKey || e.ctrlKey)) {
2024-07-02 20:04:17 +02:00
if ($allHidden) {
dbUtils.setHiddenToSelection(false);
} else {
dbUtils.setHiddenToSelection(true);
}
2024-06-19 18:11:05 +02:00
e.preventDefault();
2024-05-04 23:50:27 +02:00
} else if (e.key === 'F1') {
2024-05-06 15:52:11 +02:00
switchBasemaps();
2024-05-04 23:50:27 +02:00
e.preventDefault();
} else if (e.key === 'F2') {
2024-05-06 15:52:11 +02:00
toggleOverlays();
2024-05-04 23:50:27 +02:00
e.preventDefault();
2024-06-19 17:34:07 +02:00
} else if (e.key === 'F3') {
$distanceMarkers = !$distanceMarkers;
e.preventDefault();
} else if (e.key === 'F4') {
$directionMarkers = !$directionMarkers;
e.preventDefault();
2024-07-16 15:48:01 +02:00
} else if (e.key === 'F5') {
$routing = !$routing;
e.preventDefault();
2024-06-19 18:51:26 +02:00
} else if (
e.key === 'ArrowRight' ||
e.key === 'ArrowDown' ||
e.key === 'ArrowLeft' ||
e.key === 'ArrowUp'
) {
if (!targetInput) {
updateSelectionFromKey(e.key === 'ArrowRight' || e.key === 'ArrowDown', e.shiftKey);
e.preventDefault();
}
2024-04-18 15:30:19 +02:00
}
}}
2024-06-11 19:27:10 +02:00
on:dragover={(e) => e.preventDefault()}
on:drop={(e) => {
e.preventDefault();
if (e.dataTransfer.files.length > 0) {
loadFiles(e.dataTransfer.files);
}
}}
2024-04-18 15:30:19 +02:00
/>
2024-04-09 18:46:01 +02:00
<style lang="postcss">
div :global(button) {
@apply hover:bg-accent;
@apply px-3;
@apply py-0.5;
}
</style>