Skip to content

Commit

Permalink
fix image previews in encrypted drives
Browse files Browse the repository at this point in the history
  • Loading branch information
hzrd149 committed Mar 18, 2024
1 parent 486bb81 commit 2c65396
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 31 deletions.
4 changes: 0 additions & 4 deletions src/components/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
Button,
SidebarBrand,
DropdownItem,
DropdownDivider,
Dropdown,
} from "flowbite-svelte";
import {
Expand All @@ -18,11 +17,8 @@
PlusSolid,
TagSolid,
DatabaseOutline,
FolderArrowRightOutline,
FileImportOutline,
InfoCircleOutline,
} from "flowbite-svelte-icons";
import type { NDKEvent } from "@nostr-dev-kit/ndk";
import { drives } from "../services/drives";
import { servers } from "../services/servers";
Expand Down
32 changes: 16 additions & 16 deletions src/pages/Drive/DrivePage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@
import { EncryptedDrive } from "../../blossom-drive-client/EncryptedDrive";
import UnlockDrive from "../../components/UnlockDrive.svelte";
import ReadmePreview from "./Readme.svelte";
import { basename } from "path-browserify";
import { MultiDownload } from "../../helpers/multi-download";
import { clearCache, getLocalFileURL } from "../../services/downloads";
import { onDestroy } from "svelte";
export let currentPath: string;
export let drive: Drive;
Expand Down Expand Up @@ -128,14 +129,8 @@
}
async function openFile(file: TreeFile) {
if (drive instanceof EncryptedDrive) {
const download = await drive.downloadFile(file.path, $servers);
if (!download) return;
const url = URL.createObjectURL(download);
window.open(url, "_blank");
} else {
window.open(drive.getFileURL(file.path, $servers), "_blank");
}
const url = await getLocalFileURL(drive, file.path, $servers);
window.open(url, "_blank");
}
async function openSelected() {
for (const file of subTree) {
Expand Down Expand Up @@ -163,6 +158,11 @@
else await download.start([subTree]);
}
onDestroy(() => {
// remove all cached files
clearCache();
});
let renameModal = false;
async function renameEntry(e: CustomEvent<string>) {
const name = selected[0];
Expand Down Expand Up @@ -222,7 +222,7 @@
let folderInput: HTMLInputElement;
let filesInput: HTMLInputElement;
let showInfo = false;
let showInfoHeader = false;
</script>

<main
Expand All @@ -235,22 +235,22 @@
<div class="flex flex-1 flex-col overflow-hidden">
{#if encrypted}
<div class="relative flex w-full flex-row items-center bg-green-500">
{#if showInfo}
{#if showInfoHeader}
<LockSolid class="m-2 h-6 w-6" />
<p>This drive is encrypted, only users who know the password can view it and download files</p>
<Button color="none" class="ml-auto" on:click={() => (showInfo = false)}><CloseOutline /></Button>
<Button color="none" class="ml-auto" on:click={() => (showInfoHeader = false)}><CloseOutline /></Button>
{:else}
<button class="h-3 w-full border-none bg-none" on:click={() => (showInfo = true)} />
<button class="h-3 w-full border-none bg-none" on:click={() => (showInfoHeader = true)} />
{/if}
</div>
{:else}
<div class="relative flex w-full flex-row items-center bg-purple-500">
{#if showInfo}
{#if showInfoHeader}
<EyeSolid class="m-2 h-6 w-6" />
<p>This drive is public, anyone can view it and download files</p>
<Button color="none" class="ml-auto" on:click={() => (showInfo = false)}><CloseOutline /></Button>
<Button color="none" class="ml-auto" on:click={() => (showInfoHeader = false)}><CloseOutline /></Button>
{:else}
<button class="h-3 w-full border-none bg-none" on:click={() => (showInfo = true)} />
<button class="h-3 w-full border-none bg-none" on:click={() => (showInfoHeader = true)} />
{/if}
</div>
{/if}
Expand Down
28 changes: 17 additions & 11 deletions src/pages/Drive/markdown/plugins/components/Img.svelte
Original file line number Diff line number Diff line change
@@ -1,34 +1,40 @@
<script lang="ts">
import { Img } from "flowbite-svelte";
import { getContext } from "svelte";
import { Img, Spinner } from "flowbite-svelte";
import { joinPath } from "../../../../../blossom-drive-client/FileTree/methods";
import { servers } from "../../../../../services/servers";
import { getContext } from "svelte";
import { EncryptedDrive } from "../../../../../blossom-drive-client/EncryptedDrive";
import type Drive from "../../../../../blossom-drive-client/Drive";
import { getLocalFileURL } from "../../../../../services/downloads";
export let src: string;
export let alt: string;
let loading = false;
let resolved = src;
$: {
const drive = getContext<Drive | EncryptedDrive>("drive");
const drive = getContext<Drive>("drive");
if (drive) {
if (src.startsWith("./") || src.startsWith("/")) {
loading = true;
try {
const subPath = getContext<string>("path");
if (drive instanceof EncryptedDrive) {
resolved = "";
} else {
const fullPath = src.startsWith("/") ? src : joinPath(subPath, src.replace(/^\.\//, ""));
resolved = drive.getFileURL(fullPath, $servers);
}
const fullPath = src.startsWith("/") ? src : joinPath(subPath, src.replace(/^\.\//, ""));
getLocalFileURL(drive, fullPath, $servers)
.then((url) => (resolved = url))
.finally(() => (loading = false));
} catch (e) {
resolved = "";
loading = false;
}
}
}
}
</script>

<Img src={resolved || undefined} {alt} class="max-h-96" />
{#if loading}
<Spinner />
{:else}
<Img src={resolved || undefined} {alt} class="max-h-96" />
{/if}
43 changes: 43 additions & 0 deletions src/services/downloads.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,52 @@
import { writable } from "svelte/store";
import type { MultiDownload } from "../helpers/multi-download";
import type Drive from "../blossom-drive-client/Drive";
import { EncryptedDrive } from "../blossom-drive-client/EncryptedDrive";
import type { Path } from "../blossom-drive-client/FileTree/methods";

export const drawerOpen = writable(false);
export const downloads = writable<MultiDownload[]>([]);

export function addDownload(download: MultiDownload) {
downloads.update((arr) => [...arr, download]);
}

const cache = new Map<string, File>();
export async function getOrDownloadFile(drive: Drive, path: Path, additionalServers: string[]) {
const file = drive.getFile(path);

let download = cache.get(file.sha256);
if (!download) {
const d = await drive.downloadFile(file.path, additionalServers);
if (!d) throw new Error("Failed to download file");
cache.set(file.sha256, d);
download = d;
}

return download;
}

const URLCache = new Map<string, string>();
export async function getLocalFileURL(drive: Drive, path: Path, additionalServers: string[]) {
const file = drive.getFile(path);

if (drive instanceof EncryptedDrive) {
let url = URLCache.get(file.sha256);
if (!url) {
let download = await getOrDownloadFile(drive, path, additionalServers);
url = URL.createObjectURL(download);
URLCache.set(file.sha256, url);
}
return url;
} else {
return drive.getFileURL(file.path, additionalServers);
}
}

export function clearCache() {
for (const [_, url] of URLCache) {
URL.revokeObjectURL(url);
}
URLCache.clear();
cache.clear();
}

0 comments on commit 2c65396

Please sign in to comment.