feat(userbot,api,frontend): file links, media downloads, story hold-pause, drop scheduled dupes
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { visible } from "$lib/actions/visible";
|
||||
import { downloadMedia } from "$lib/api/download";
|
||||
import { fetchMedia } from "$lib/api/endpoints";
|
||||
import {
|
||||
type InlineMedia,
|
||||
@@ -15,7 +16,9 @@
|
||||
import ContextMenuItem from "$lib/components/ui/ContextMenuItem.svelte";
|
||||
import Icon from "$lib/components/ui/Icon.svelte";
|
||||
import Spinner from "$lib/components/ui/Spinner.svelte";
|
||||
import { mediaKindLabel } from "$lib/format/media";
|
||||
import { poster } from "$lib/media/poster";
|
||||
import { shareUi } from "$lib/stores/shares.svelte";
|
||||
import { toasts } from "$lib/stores/toasts.svelte";
|
||||
import { ui } from "$lib/stores/ui.svelte";
|
||||
|
||||
@@ -33,6 +36,7 @@
|
||||
let loaded = $state(false);
|
||||
let media = $state<InlineMedia | null>(null);
|
||||
let queuing = $state(false);
|
||||
let saving = $state(false);
|
||||
|
||||
const ready = $derived(media?.state === "ready" ? media : null);
|
||||
const kind = $derived(ready?.kind ?? "");
|
||||
@@ -56,6 +60,7 @@
|
||||
const label = $derived(
|
||||
media && media.state !== "missing" ? media.kind : "media"
|
||||
);
|
||||
const storedId = $derived(ready?.mediaId ?? null);
|
||||
|
||||
function delay(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
@@ -86,14 +91,37 @@
|
||||
queuing = true;
|
||||
try {
|
||||
await fetchMedia(message.chat_id, message.message_id);
|
||||
toasts.success("Download queued");
|
||||
toasts.success("Скачивание поставлено в очередь");
|
||||
poll();
|
||||
} catch {
|
||||
toasts.error("Failed to queue download");
|
||||
toasts.error("Не удалось поставить в очередь");
|
||||
} finally {
|
||||
queuing = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function save() {
|
||||
if (storedId === null || saving) {
|
||||
return;
|
||||
}
|
||||
saving = true;
|
||||
try {
|
||||
await downloadMedia(storedId);
|
||||
} catch {
|
||||
toasts.error("Не удалось скачать файл");
|
||||
} finally {
|
||||
saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
function share() {
|
||||
if (storedId !== null) {
|
||||
shareUi.share(
|
||||
{ kind: "media", mediaId: storedId },
|
||||
mediaKindLabel(kind) ?? "Файл"
|
||||
);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<ContextMenu>
|
||||
@@ -102,7 +130,7 @@
|
||||
{#if message.is_self_destruct}
|
||||
<button class="media-chip self-destruct" onclick={onopen} type="button">
|
||||
<Icon name="timer" size="1.25rem" />
|
||||
<span>Self-destruct media</span>
|
||||
<span>Самоуничтожающееся медиа</span>
|
||||
</button>
|
||||
{:else if !loaded}
|
||||
<div class="media-skeleton"><Spinner /></div>
|
||||
@@ -161,18 +189,18 @@
|
||||
{:else if media?.state === "not-downloaded" && vk !== "other"}
|
||||
<button class="media-placeholder" onclick={queue} type="button">
|
||||
<Icon name={queuing ? "timer" : "download"} size="1.5rem" />
|
||||
<span>{vk === "video" ? "Video" : "Photo"}</span>
|
||||
<small>{queuing ? "Queued" : "Tap to download"}</small>
|
||||
<span>{vk === "video" ? "Видео" : "Фото"}</span>
|
||||
<small>{queuing ? "В очереди" : "Нажмите, чтобы скачать"}</small>
|
||||
</button>
|
||||
{:else if media?.state === "not-downloaded"}
|
||||
<button class="media-chip" onclick={queue} type="button">
|
||||
<Icon name={queuing ? "timer" : "download"} size="1.25rem" />
|
||||
<span>{queuing ? "Queued" : `Download ${label}`}</span>
|
||||
<span>{queuing ? "В очереди" : `Скачать ${label}`}</span>
|
||||
</button>
|
||||
{:else}
|
||||
<button class="media-chip" onclick={onopen} type="button">
|
||||
<Icon name="photo" size="1.25rem" />
|
||||
<span>Media</span>
|
||||
<span>Медиа</span>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -186,7 +214,18 @@
|
||||
onselect={() => ui.openMessagePanel("versions", message.message_id)}
|
||||
>Версии медиа</ContextMenuItem
|
||||
>
|
||||
<ContextMenuItem icon="download" onselect={queue}>Скачать</ContextMenuItem>
|
||||
{#if storedId === null}
|
||||
<ContextMenuItem icon="cloud-download" onselect={queue}>
|
||||
Скачать в архив
|
||||
</ContextMenuItem>
|
||||
{:else}
|
||||
<ContextMenuItem icon="download" onselect={save}>
|
||||
Скачать файл
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem icon="allow-share" onselect={share}>
|
||||
Доступ по ссылке
|
||||
</ContextMenuItem>
|
||||
{/if}
|
||||
{/snippet}
|
||||
</ContextMenu>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user