Files
Oxicloud/frontend/src/routes/shared-with-me/+page.svelte
T

79 lines
2.2 KiB
Svelte
Raw Normal View History

2026-06-17 17:06:30 -06:00
<script lang="ts">
2026-06-17 22:07:18 -06:00
import { goto } from '$app/navigation';
2026-06-17 17:06:30 -06:00
import { onMount } from 'svelte';
import { fetchSharedWithMe, type IncomingGrantItem } from '$lib/api/endpoints/grants';
2026-06-17 22:07:18 -06:00
import type { FileItem } from '$lib/api/types';
import FileViewer from '$lib/components/FileViewer.svelte';
import ResourceList, { type ResourceEntry } from '$lib/components/ResourceList.svelte';
2026-06-17 17:06:30 -06:00
import { t } from '$lib/i18n/index.svelte';
2026-06-17 22:07:18 -06:00
let raw = $state<IncomingGrantItem[]>([]);
2026-06-17 17:06:30 -06:00
let cursor = $state<string | undefined>(undefined);
let loading = $state(false);
let error = $state<string | null>(null);
2026-06-17 22:07:18 -06:00
const byId = $derived(new Map(raw.map((it) => [it.resource.id, it])));
const entries = $derived(
raw.map(
(it): ResourceEntry => ({
id: it.resource.id,
name: it.resource.name,
kind: it.resource_type,
iconClass: it.resource.icon_class,
path: it.granted_by
? t('shared_with_me.from', { who: it.granted_by }, 'Shared by {{who}}')
: it.resource.path,
size: it.resource_type === 'file' ? (it.resource as FileItem).size : null,
date: it.granted_at
})
)
);
2026-06-17 17:06:30 -06:00
async function load(reset = false) {
loading = true;
error = null;
try {
const page = await fetchSharedWithMe({ cursor: reset ? undefined : cursor });
2026-06-17 22:07:18 -06:00
raw = reset ? page.items : [...raw, ...page.items];
2026-06-17 17:06:30 -06:00
cursor = page.next_cursor;
} catch (e) {
error = e instanceof Error ? e.message : String(e);
} finally {
loading = false;
}
}
2026-06-17 22:07:18 -06:00
let viewerOpen = $state(false);
let viewerFile = $state<FileItem | null>(null);
function open(entry: ResourceEntry) {
if (entry.kind === 'folder') {
goto(`/files/${entry.id}`);
return;
}
const item = byId.get(entry.id);
if (item) {
viewerFile = item.resource as FileItem;
viewerOpen = true;
}
}
2026-06-17 17:06:30 -06:00
onMount(() => load(true));
</script>
<svelte:head><title>{t('nav.shared_with_me', 'Shared with me')} · OxiCloud</title></svelte:head>
2026-06-17 22:07:18 -06:00
<ResourceList
title={t('nav.shared_with_me', 'Shared with me')}
items={entries}
2026-06-17 17:06:30 -06:00
{loading}
{error}
emptyText={t('shared_with_me.empty', 'Nothing has been shared with you yet.')}
hasMore={!!cursor}
onloadmore={() => load(false)}
2026-06-17 22:07:18 -06:00
onopen={open}
/>
<FileViewer bind:open={viewerOpen} file={viewerFile} />