Skip to content

Commit edccf48

Browse files
committed
rebuild folder toolbar
1 parent 620aec8 commit edccf48

File tree

7 files changed

+155
-28
lines changed

7 files changed

+155
-28
lines changed

src/blossom-drive-client/Upload.ts

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type Drive from "./Drive";
33

44
export type UploadableItem = FileList | File | FileSystemDirectoryEntry;
55

6+
// NOTE: make sure to support webkitRelativePath on File if its defined
7+
68
export default class Upload {
79
drive: Drive;
810
servers: string[];

src/components/DriveEditModal.svelte

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
let description = drive.description;
1010
1111
const submit = async (e: SubmitEvent) => {
12-
e.preventDefault();
1312
drive.name = name;
1413
drive.description = description;
1514
await drive.save();
@@ -18,7 +17,7 @@
1817
</script>
1918

2019
<Modal bind:open size="xs" class="w-full" title="Edit Drive" outsideclose>
21-
<form id="update-form" class="flex flex-col gap-2 py-0" on:submit={submit}>
20+
<form id="update-form" class="flex flex-col gap-2 py-0" on:submit|preventDefault={submit}>
2221
<Input placeholder="Drive name" required bind:value={name} />
2322
<Textarea name="about" rows={4} placeholder="A short description" bind:value={description} />
2423
<div class="flex justify-end gap-2">

src/components/FileCard.svelte

+2-3
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@
3535

3636
<!-- svelte-ignore a11y-click-events-have-key-events -->
3737
<div
38-
class={"relative flex aspect-square min-w-40 flex-col divide-gray-200 rounded-md border-4 bg-white text-gray-700 hover:bg-gray-100 dark:divide-gray-700 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700" +
38+
class={"relative flex h-40 w-48 flex-col divide-gray-200 rounded-md border-2 bg-white text-gray-700 hover:bg-gray-100 dark:divide-gray-700 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700" +
3939
borderClass}
4040
on:dragstart={dragStart}
41-
on:click={toggleSelect}
41+
on:click|stopPropagation={toggleSelect}
4242
on:dblclick={() => window.open(link, "_blank")}
4343
role="row"
4444
tabindex={0}
@@ -101,7 +101,6 @@
101101

102102
<style>
103103
.preview-image {
104-
image-rendering: pixelated;
105104
background-position: center;
106105
background-size: contain;
107106
background-repeat: no-repeat;

src/components/FolderCard.svelte

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@
7575

7676
<!-- svelte-ignore a11y-click-events-have-key-events -->
7777
<div
78-
class={"relative flex aspect-square min-w-40 flex-col divide-gray-200 rounded-md border-4 bg-white text-gray-700 hover:bg-gray-100 dark:divide-gray-700 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700" +
78+
class={"relative flex h-40 w-48 flex-col divide-gray-200 rounded-md border-2 bg-white text-gray-700 hover:bg-gray-100 dark:divide-gray-700 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700" +
7979
borderClass}
80-
on:click={toggleSelect}
80+
on:click|stopPropagation={toggleSelect}
8181
on:dblclick={() => push(createDirLink(folder.name, $querystring))}
8282
on:drop={drop}
8383
on:dragover={dragover}

src/components/NewDriveModal.svelte

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script lang="ts">
22
import { NDKEvent } from "@nostr-dev-kit/ndk";
3-
import { Button, Modal, Input, Textarea } from "flowbite-svelte";
3+
import { Button, Modal, Input, Textarea, Spinner } from "flowbite-svelte";
44
import { createEventDispatcher } from "svelte";
55
import { ndk } from "../services/ndk";
66
import { nanoid } from "nanoid";
@@ -9,6 +9,8 @@
99
let name = "";
1010
let description = "";
1111
12+
let loading = false;
13+
1214
const dispatch = createEventDispatcher();
1315
1416
const submit = async (e: SubmitEvent) => {
@@ -27,12 +29,16 @@
2729
</script>
2830

2931
<Modal bind:open size="xs" class="w-full" title="New Drive" outsideclose>
30-
<form id="new-folder-form" class="flex flex-col gap-2 py-0" on:submit={submit}>
31-
<Input placeholder="Drive name" required bind:value={name} />
32-
<Textarea name="about" rows={4} placeholder="A short description" bind:value={description} />
33-
<div class="flex justify-end gap-2">
34-
<Button color="alternative" on:click={() => (open = false)}>Cancel</Button>
35-
<Button type="submit">Create</Button>
36-
</div>
37-
</form>
32+
{#if loading}
33+
<Spinner />
34+
{:else}
35+
<form id="new-folder-form" class="flex flex-col gap-2 py-0" on:submit={submit}>
36+
<Input placeholder="Drive name" required bind:value={name} />
37+
<Textarea name="about" rows={4} placeholder="A short description" bind:value={description} />
38+
<div class="flex justify-end gap-2">
39+
<Button color="alternative" on:click={() => (open = false)}>Cancel</Button>
40+
<Button type="submit">Create</Button>
41+
</div>
42+
</form>
43+
{/if}
3844
</Modal>

src/components/PathBreadcrumbs.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
$: path = parsePath(parsed.get("path") ?? "");
1010
</script>
1111

12-
<Breadcrumb>
12+
<Breadcrumb class={$$props.class}>
1313
<BreadcrumbItem href={"#" + $location} home>{root}</BreadcrumbItem>
1414
{#each path as name, i}
1515
<BreadcrumbItem href={"#" + $location + "?path=/" + [...path.slice(0, i), name].join("/")}>{name}</BreadcrumbItem>

src/pages/Drive/DriveFiles.svelte

+132-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
<script lang="ts">
2-
import SpeedDialMenu from "../../components/SpeedDialMenu.svelte";
3-
import { Button, CloseButton, Select, Spinner } from "flowbite-svelte";
4-
import { TrashBinSolid } from "flowbite-svelte-icons";
2+
import { Button, CloseButton, Select, Spinner, Tooltip } from "flowbite-svelte";
3+
import {
4+
ArrowLeftToBracketOutline,
5+
CogOutline,
6+
DownloadOutline,
7+
EditOutline,
8+
FileImportOutline,
9+
FolderArrowRightOutline,
10+
FolderPlusOutline,
11+
InfoCircleOutline,
12+
LinkOutline,
13+
ListSolid,
14+
TrashBinOutline,
15+
TrashBinSolid,
16+
} from "flowbite-svelte-icons";
517
618
import FileCard from "../../components/FileCard.svelte";
719
import FolderCard from "../../components/FolderCard.svelte";
@@ -15,16 +27,32 @@
1527
import TreeFile from "../../blossom-drive-client/FileTree/TreeFile";
1628
import { joinPath } from "../../blossom-drive-client/FileTree/methods";
1729
import DriveEditModal from "../../components/DriveEditModal.svelte";
30+
import NewFolderModal from "../../components/NewFolderModal.svelte";
31+
import UploadFileModal from "../../components/UploadFileModal.svelte";
32+
import { servers } from "../../services/servers";
33+
import { getBlobURL } from "../../helpers/blob";
1834
1935
export let currentPath: string;
2036
export let drive: Drive;
2137
$: readableDrive = getReadableDrive(drive);
2238
$: subTree = $readableDrive.getFolder(currentPath);
2339
2440
let editModal = false;
41+
let newFolderModal = false;
42+
let uploadFilesModal = false;
2543
2644
let detailsModal = false;
2745
let detailsFile: TreeFile | null = null;
46+
function showDetailsModal() {
47+
if (selected[0]) {
48+
const file = subTree.get(selected[0]);
49+
if (file instanceof TreeFile) {
50+
detailsFile = file;
51+
detailsModal = true;
52+
}
53+
}
54+
}
55+
2856
let confirmDelete = false;
2957
let selected: string[] = [];
3058
function toggleSelect(e: CustomEvent<string>) {
@@ -54,6 +82,16 @@
5482
await drive.save();
5583
}
5684
85+
function copySelectedLink() {
86+
if (selected[0]) {
87+
const file = subTree.get(selected[0]);
88+
if (file instanceof TreeFile) {
89+
const url = getBlobURL(file, $servers[0]);
90+
if (url) window.navigator.clipboard.writeText(url);
91+
}
92+
}
93+
}
94+
5795
async function deleteSelected() {
5896
for (const name of selected) drive.remove(joinPath(currentPath, name));
5997
selected = [];
@@ -152,19 +190,91 @@
152190
// handleEvent(draft);
153191
// await draft.publish();
154192
// }
193+
194+
let folderInput: HTMLInputElement;
195+
let filesInput: HTMLInputElement;
155196
</script>
156197

157198
{#if !drive}
158199
<Spinner />
159200
{:else}
160-
<main class="flex flex-grow flex-col gap-4 p-4" on:drop={drop} on:dragover={dragover}>
161-
<div class="flex gap-2">
162-
<PathBreadcrumbs root={drive.name ?? "Drive"} />
163-
<div class="flex-1" />
164-
<Button on:click={() => (editModal = true)} color="alternative" size="xs">Edit</Button>
201+
<main class="flex flex-grow flex-col" on:drop={drop} on:dragover={dragover}>
202+
<div class="flex items-center gap-2 border-b border-gray-200 p-2 dark:border-gray-800">
203+
<PathBreadcrumbs root={drive.name ?? "Drive"} class="mx-2" />
165204
<Button href="#/history/{drive.address}" color="alternative" size="xs">History</Button>
205+
206+
<div class="flex-1" />
207+
208+
{#if selected.length === 0}
209+
<Button size="sm" class="!p-2" color="alternative" on:click={() => (newFolderModal = true)}>
210+
<FolderPlusOutline />
211+
</Button>
212+
<Tooltip placement="bottom">Create Folder</Tooltip>
213+
214+
<div class="h-8 border border-gray-200 dark:border-gray-800" />
215+
216+
<input class="hidden" type="file" webkitdirectory multiple bind:this={folderInput} />
217+
<Button size="sm" class="!p-2" color="alternative" on:click={() => folderInput.click()}>
218+
<FolderArrowRightOutline />
219+
</Button>
220+
<Tooltip placement="bottom">Upload Folder</Tooltip>
221+
222+
<input class="hidden" type="file" multiple bind:this={filesInput} />
223+
<Button size="sm" class="!p-2" color="alternative" on:click={() => filesInput.click()}>
224+
<FileImportOutline />
225+
</Button>
226+
<Tooltip placement="bottom">Upload Files</Tooltip>
227+
{:else}
228+
{#if selected.length === 1}
229+
<Button size="sm" class="!p-2" color="alternative" disabled>
230+
<DownloadOutline />
231+
</Button>
232+
<Tooltip placement="bottom">Download</Tooltip>
233+
234+
<Button size="sm" class="!p-2" color="alternative" on:click={copySelectedLink}>
235+
<LinkOutline />
236+
</Button>
237+
<Tooltip placement="bottom">Copy Link</Tooltip>
238+
239+
<div class="h-8 border border-gray-200 dark:border-gray-800" />
240+
241+
<Button size="sm" class="!p-2" color="alternative" disabled>
242+
<ArrowLeftToBracketOutline />
243+
</Button>
244+
<Tooltip placement="bottom">Move</Tooltip>
245+
246+
<Button size="sm" class="!p-2" color="alternative" on:click={() => (renameModal = true)}>
247+
<EditOutline />
248+
</Button>
249+
<Tooltip placement="bottom">Rename</Tooltip>
250+
251+
<Button size="sm" class="!p-2" color="alternative" on:click={showDetailsModal}>
252+
<InfoCircleOutline />
253+
</Button>
254+
<Tooltip placement="bottom">Details</Tooltip>
255+
{/if}
256+
257+
<div class="h-8 border border-gray-200 dark:border-gray-800" />
258+
259+
<Button size="sm" class="!p-2" color="alternative" on:click={() => (confirmDelete = true)}>
260+
<TrashBinOutline />
261+
</Button>
262+
<Tooltip placement="bottom">Delete</Tooltip>
263+
{/if}
264+
265+
<div class="h-8 border border-gray-200 dark:border-gray-800" />
266+
267+
<Button size="sm" class="!p-2" color="alternative" disabled>
268+
<ListSolid />
269+
</Button>
270+
<Tooltip placement="bottom">Change Layout</Tooltip>
271+
272+
<Button size="sm" class="!p-2" color="alternative" on:click={() => (editModal = true)}>
273+
<CogOutline />
274+
</Button>
275+
<Tooltip placement="bottom">Drive Settings</Tooltip>
166276
</div>
167-
<div class="flex items-center gap-2 rounded-lg border border-gray-200 p-1 dark:border-gray-800">
277+
<div class="flex items-center gap-2 rounded-lg px-4 pt-2">
168278
{#if selected.length > 0}
169279
<p class="ml-2">{selected.length} selected</p>
170280
<Button size="sm" color="none" class="!p-2" on:click={() => (confirmDelete = true)}><TrashBinSolid /></Button>
@@ -180,8 +290,12 @@
180290
<Button size="sm" on:click={() => (filterType = "")} color="alternative">Clear Filter</Button>
181291
{/if}
182292
{/if}
293+
294+
<div class="mx-auto"></div>
183295
</div>
184-
<div class="flex flex-wrap items-start gap-4">
296+
<!-- svelte-ignore a11y-click-events-have-key-events -->
297+
<!-- svelte-ignore a11y-no-static-element-interactions -->
298+
<div class="flex flex-1 flex-wrap items-start gap-4 p-4" on:click={() => (selected = [])}>
185299
{#each folders as folder}
186300
<FolderCard
187301
{folder}
@@ -225,7 +339,6 @@
225339
</div>
226340
</main>
227341
{/if}
228-
<SpeedDialMenu drive={drive ?? undefined} path={currentPath} />
229342

230343
{#if confirmDelete}
231344
<DeleteModal bind:open={confirmDelete} on:yes={deleteSelected} />
@@ -242,3 +355,11 @@
242355
{#if editModal}
243356
<DriveEditModal bind:open={editModal} drive={$readableDrive} />
244357
{/if}
358+
359+
{#if newFolderModal && drive}
360+
<NewFolderModal bind:open={newFolderModal} {drive} path={currentPath} />
361+
{/if}
362+
363+
{#if uploadFilesModal}
364+
<UploadFileModal bind:open={uploadFilesModal} {drive} path={currentPath} />
365+
{/if}

0 commit comments

Comments
 (0)