Skip to content

Commit

Permalink
minor: allow dragging and dropping files to open them
Browse files Browse the repository at this point in the history
  • Loading branch information
acheronfail committed Sep 28, 2024
1 parent da203ee commit fae19be
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 8 deletions.
45 changes: 43 additions & 2 deletions src/components/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
import Header from './Header.svelte';
import { demoFile, demoRows } from '../lib/parse/float-control';
import Picker from './Picker.svelte';
import type { EventHandler } from 'svelte/elements';
import type { DragEventHandler, EventHandler } from 'svelte/elements';
import { DataSource, State, Units, type RowWithIndex } from '../lib/parse/types';
import Modal from './Modal.svelte';
import { riderSvg } from '../lib/map-helpers';
import settings from '../lib/settings.svelte';
import SettingsModal from './SettingsModal.svelte';
import Button from './Button.svelte';
import { ChartColours } from '../lib/chart-helpers';
import { parse } from '../lib/parse';
import { parse, supportedMimeTypes } from '../lib/parse';
import { speedMapper } from '../lib/misc';
/** source of data*/
Expand Down Expand Up @@ -205,6 +205,35 @@
}
});
/**
* Allow dragging and dropping files to open them.
*/
let draggingFile = $state(false);
const filterSupported = (item: { type: string }) => supportedMimeTypes.includes(item.type);
const ondragenter: DragEventHandler<HTMLElement> = (e) => {
if (!e.dataTransfer) return;
draggingFile = Array.from(e.dataTransfer.items).some(filterSupported);
};
const ondragleave: DragEventHandler<HTMLElement> = (_) => (draggingFile = false);
const ondragover: DragEventHandler<HTMLElement> = (e) => {
e.preventDefault();
if (draggingFile && e.dataTransfer) {
e.dataTransfer.dropEffect = 'copy';
}
};
const ondrop: DragEventHandler<HTMLElement> = (e) => {
e.preventDefault();
if (!e.dataTransfer) return;
const droppedFile = Array.from(e.dataTransfer.files).find(filterSupported);
if (droppedFile) {
file = droppedFile;
}
draggingFile = false;
};
const chartClass = 'bg-slate-950 flex overflow-hidden h-[--grid-width] wide:h-[unset]';
</script>

Expand All @@ -231,7 +260,19 @@
grid-cols-[repeat(auto-fit,minmax(var(--grid-width),1fr))]
wide:h-[calc(100vh-var(--header-height))]
wide:grid-cols-[repeat(3,1fr)]"
{ondragenter}
{ondragover}
{ondrop}
>
{#if draggingFile}
<Modal title="File drag detected!" open closable={false} {ondragleave}>
<div class="h-full w-full flex flex-row justify-center items-center border border-dashed border-4 rounded-2xl">
<div>{@html riderSvg}</div>
<p>Drop your file to open it!</p>
<div>{@html riderSvg}</div>
</div>
</Modal>
{/if}
<div
class="sticky top-[--header-height] h-[--grid-width] z-50 border-b
wide:relative wide:top-[unset] wide:h-[unset] wide:border-b-0"
Expand Down
8 changes: 5 additions & 3 deletions src/components/Modal.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script lang="ts" module>
import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
export interface Props {
export interface Props extends HTMLAttributes<HTMLDivElement> {
open?: boolean;
title: string;
closable?: boolean;
Expand All @@ -21,18 +22,19 @@
closable = true,
title,
children,
...rest
}: Props = $props();
</script>

{#if open}
<div class="fixed top-0 left-0 right-0 bottom-0 z-[10000] bg-slate-950 opacity-50"></div>
<div class="fixed top-0 left-0 right-0 bottom-0 z-[10010] flex justify-center items-center">
<div class="fixed top-0 left-0 right-0 bottom-0 z-[10010] flex justify-center items-center" {...rest}>
<div
class="flex flex-col justify-between items-center text-center overflow-y-auto bg-slate-800
h-screen w-screen border-0 p-4 rounded-none wide:w-[60vw] wide:h-[80vh] wide:rounded wide:border"
>
<h2 class="font-bold text-xl mb-2 underline">{title}</h2>
<div class="grow flex flex-col">
<div class="w-full h-full grow flex flex-col">
{@render children()}
</div>
{#if closable}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Picker.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Modal from './Modal.svelte';
import { demoFile } from '../lib/parse/float-control';
import Link from './Link.svelte';
import { supportedMimeTypes } from '../lib/parse';
import { supportedMimeTypeString } from '../lib/parse';
let { file = $bindable() }: Props = $props();
Expand All @@ -34,7 +34,7 @@
file:text-sm file:font-bold file:bg-slate-700 active:file:bg-slate-800"
type="file"
{onchange}
accept={supportedMimeTypes}
accept={supportedMimeTypeString}
/>
</div>
<div class="grow flex flex-col justify-end items-center text-left text-xs">
Expand Down
3 changes: 2 additions & 1 deletion src/lib/parse/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export enum SupportedMimeTypes {
Json = 'application/json',
}

export const supportedMimeTypes = Object.values(SupportedMimeTypes).join(',');
export const supportedMimeTypes = Object.values<string>(SupportedMimeTypes);
export const supportedMimeTypeString = supportedMimeTypes.join(',');

export async function parse(file: File): Promise<ParseResult> {
const lowerName = file.name.toLowerCase();
Expand Down

0 comments on commit fae19be

Please sign in to comment.