Files
gpx.studio/website/src/lib/components/toolbar/tools/Scissors.svelte

127 lines
3.4 KiB
Svelte
Raw Normal View History

2024-06-10 20:03:57 +02:00
<script lang="ts" context="module">
export enum SplitType {
FILES = 'files',
TRACKS = 'tracks',
SEGMENTS = 'segments'
}
</script>
<script lang="ts">
import Help from '$lib/components/Help.svelte';
import { ListRootItem } from '$lib/components/file-list/FileList';
import { selection } from '$lib/components/file-list/Selection';
import { Label } from '$lib/components/ui/label/index.js';
import { Button } from '$lib/components/ui/button';
import { Slider } from '$lib/components/ui/slider';
import * as Select from '$lib/components/ui/select';
import { Separator } from '$lib/components/ui/separator';
import { gpxStatistics, slicedGPXStatistics, splitAs } from '$lib/stores';
import { get } from 'svelte/store';
import { _ } from 'svelte-i18n';
2024-06-12 12:13:30 +02:00
import { onDestroy, tick } from 'svelte';
2024-06-10 20:03:57 +02:00
import { Crop } from 'lucide-svelte';
import { dbUtils } from '$lib/db';
2024-06-27 18:23:11 +02:00
$: validSelection =
$selection.hasAnyChildren(new ListRootItem(), true, ['waypoints']) &&
$gpxStatistics.local.points.length > 0;
2024-06-10 20:03:57 +02:00
let maxSliderValue = 100;
let sliderValues = [0, 100];
2024-06-12 14:53:43 +02:00
$: canCrop = sliderValues[0] != 0 || sliderValues[1] != maxSliderValue;
2024-06-10 20:03:57 +02:00
function updateSlicedGPXStatistics() {
2024-06-12 14:53:43 +02:00
if (validSelection && canCrop) {
2024-07-10 15:09:52 +02:00
$slicedGPXStatistics = [
get(gpxStatistics).slice(sliderValues[0], sliderValues[1]),
sliderValues[0],
sliderValues[1]
2024-07-10 15:09:52 +02:00
];
2024-06-10 20:03:57 +02:00
} else {
2024-07-10 15:09:52 +02:00
$slicedGPXStatistics = undefined;
}
}
function updateSliderValues() {
if ($slicedGPXStatistics !== undefined) {
sliderValues = [$slicedGPXStatistics[1], $slicedGPXStatistics[2]];
2024-06-10 20:03:57 +02:00
}
}
async function updateSliderLimits() {
2024-06-12 14:53:43 +02:00
if (validSelection && $gpxStatistics.local.points.length > 0) {
maxSliderValue = $gpxStatistics.local.points.length - 1;
2024-06-10 20:03:57 +02:00
} else {
maxSliderValue = 100;
}
await tick();
sliderValues = [0, maxSliderValue];
}
$: if ($gpxStatistics.local.points.length - 1 != maxSliderValue) {
2024-06-10 20:03:57 +02:00
updateSliderLimits();
}
$: if (sliderValues) {
updateSlicedGPXStatistics();
}
2024-07-10 15:09:52 +02:00
$: if (
$slicedGPXStatistics !== undefined &&
($slicedGPXStatistics[1] !== sliderValues[0] || $slicedGPXStatistics[2] !== sliderValues[1])
) {
updateSliderValues();
}
2024-06-10 20:03:57 +02:00
const splitTypes = [
{ value: SplitType.FILES, label: $_('gpx.files') },
{ value: SplitType.TRACKS, label: $_('gpx.tracks') },
{ value: SplitType.SEGMENTS, label: $_('gpx.segments') }
];
let splitType = splitTypes[0];
$: splitAs.set(splitType.value);
2024-06-12 12:13:30 +02:00
onDestroy(() => {
2024-07-10 15:09:52 +02:00
$slicedGPXStatistics = undefined;
2024-06-12 12:13:30 +02:00
});
2024-06-10 20:03:57 +02:00
</script>
2024-07-09 22:49:57 +02:00
<div class="flex flex-col gap-3 w-full max-w-80 {$$props.class ?? ''}">
2024-06-10 20:03:57 +02:00
<div class="p-2">
<Slider bind:value={sliderValues} max={maxSliderValue} step={1} disabled={!validSelection} />
</div>
<Button
variant="outline"
2024-06-12 14:53:43 +02:00
disabled={!validSelection || !canCrop}
2024-06-10 20:03:57 +02:00
on:click={() => dbUtils.cropSelection(sliderValues[0], sliderValues[1])}
>
2024-06-27 18:23:11 +02:00
<Crop size="16" class="mr-1" />{$_('toolbar.scissors.crop')}
</Button>
2024-06-10 20:03:57 +02:00
<Separator />
2024-07-10 15:09:52 +02:00
<Label class="flex flex-row flex-wrap gap-3 items-center">
2024-06-10 20:03:57 +02:00
<span class="shrink-0">
{$_('toolbar.scissors.split_as')}
</span>
<Select.Root bind:selected={splitType}>
2024-07-10 15:09:52 +02:00
<Select.Trigger class="h-8 w-fit grow">
2024-06-10 20:03:57 +02:00
<Select.Value />
</Select.Trigger>
<Select.Content>
{#each splitTypes as { value, label }}
<Select.Item {value}>{label}</Select.Item>
{/each}
</Select.Content>
</Select.Root>
</Label>
<Help>
{#if validSelection}
{$_('toolbar.scissors.help')}
{:else}
{$_('toolbar.scissors.help_invalid_selection')}
{/if}
</Help>
</div>