fix(frontend): shared mark on its own line in trash rows, undo ignores the trailing click, trash segment has a key

This commit is contained in:
hh committed 2026-10-14 03:23:22 +02:00
1 parent 580927da0a
commit c9c088ed73
3 files changed
+29 -5

No files matched your search

@@ -37,6 +37,7 @@
const PAGE = 30; const PAGE = 30;
const UNDO_MS = 12_000; const UNDO_MS = 12_000;
const UNDO_GUARD_MS = 600;
let summary = $state<StorageSummary | null>(null); let summary = $state<StorageSummary | null>(null);
let files = $state<StorageFile[]>([]); let files = $state<StorageFile[]>([]);
@@ -54,6 +55,7 @@
const selected = new SvelteSet<number>(); const selected = new SvelteSet<number>();
let token = 0; let token = 0;
let undoTimer: ReturnType<typeof setTimeout> | undefined; let undoTimer: ReturnType<typeof setTimeout> | undefined;
let undoShownAt = 0;
const heaviest = $derived(files[0]?.file_size ?? 0); const heaviest = $derived(files[0]?.file_size ?? 0);
const chosen = $derived(files.filter((file) => selected.has(file.media_id))); const chosen = $derived(files.filter((file) => selected.has(file.media_id)));
@@ -151,6 +153,7 @@
hideUndo(); hideUndo();
if (outcome.files > 0) { if (outcome.files > 0) {
undo = { files: trashed, outcome }; undo = { files: trashed, outcome };
undoShownAt = Date.now();
undoTimer = setTimeout(hideUndo, UNDO_MS); undoTimer = setTimeout(hideUndo, UNDO_MS);
} }
} }
@@ -185,7 +188,7 @@
} }
async function restoreLast() { async function restoreLast() {
if (undo === null) { if (undo === null || Date.now() - undoShownAt < UNDO_GUARD_MS) {
return; return;
} }
const restored = undo; const restored = undo;
@@ -290,9 +293,13 @@
<Icon name="delete" size="1.375rem" /> <Icon name="delete" size="1.375rem" />
<span class="label">Корзина</span> <span class="label">Корзина</span>
<span class="value"> <span class="value">
{summary.trash_files > 0 {#if summary.trash_files > 0}
? `${filesLabel(summary.trash_files)} · ${formatBytes(summary.trash_bytes)}` <span class="swatch"></span>
: "пусто"} {filesLabel(summary.trash_files)}
· {formatBytes(summary.trash_bytes)}
{:else}
пусто
{/if}
</span> </span>
<Icon name="next" size="1.125rem" /> <Icon name="next" size="1.125rem" />
</button> </button>
@@ -581,10 +588,21 @@
} }
.value { .value {
display: flex;
gap: 0.375rem;
align-items: center;
font-size: 0.8125rem; font-size: 0.8125rem;
font-variant-numeric: tabular-nums; font-variant-numeric: tabular-nums;
} }
.swatch {
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
background-color: rgba(var(--color-text-secondary-rgb), 0.35);
}
&:focus-visible { &:focus-visible {
outline: 2px solid var(--color-primary); outline: 2px solid var(--color-primary);
outline-offset: -2px; outline-offset: -2px;
@@ -12,6 +12,7 @@
lead?: string; lead?: string;
menu: Snippet; menu: Snippet;
mime: string | null; mime: string | null;
note?: string;
onopen: () => void; onopen: () => void;
ontoggle: () => void; ontoggle: () => void;
refetchable: boolean; refetchable: boolean;
@@ -31,6 +32,7 @@
lead, lead,
sub, sub,
tail, tail,
note,
size, size,
weight, weight,
refetchable, refetchable,
@@ -76,6 +78,9 @@
<span class="rigid">{` · ${tail}`}</span> <span class="rigid">{` · ${tail}`}</span>
{/if} {/if}
</span> </span>
{#if note}
<span class="note">{note}</span>
{/if}
{#if !refetchable} {#if !refetchable}
<span class="gone">Не скачать заново</span> <span class="gone">Не скачать заново</span>
{/if} {/if}
@@ -211,6 +216,7 @@
} }
.sub, .sub,
.note,
.gone { .gone {
margin-top: 0.125rem; margin-top: 0.125rem;
font-size: 0.8125rem; font-size: 0.8125rem;
@@ -178,6 +178,7 @@
kind={item.kind} kind={item.kind}
lead={purgeLabel(item.purge_at)} lead={purgeLabel(item.purge_at)}
mime={item.mime} mime={item.mime}
note={item.refs > 1 ? messagesLabel(item.refs) : undefined}
onopen={() => open(index)} onopen={() => open(index)}
ontoggle={() => toggle(item.storage_key)} ontoggle={() => toggle(item.storage_key)}
refetchable={item.refetchable} refetchable={item.refetchable}
@@ -185,7 +186,6 @@
size={item.file_size} size={item.file_size}
src={trashedUrl(item.storage_key)} src={trashedUrl(item.storage_key)}
sub={chatTitle(item.chat_id)} sub={chatTitle(item.chat_id)}
tail={item.refs > 1 ? messagesLabel(item.refs) : undefined}
weight={heaviest > 0 ? (item.file_size ?? 0) / heaviest : 0} weight={heaviest > 0 ? (item.file_size ?? 0) / heaviest : 0}
> >
{#snippet menu()} {#snippet menu()}