114 lines
2.5 KiB
Svelte
114 lines
2.5 KiB
Svelte
<script lang="ts">
|
|
import { enqueueBackfill, trackChat } from "#lib/api/endpoints.js";
|
|
import Button from "#lib/components/ui/Button.svelte";
|
|
import Icon from "#lib/components/ui/Icon.svelte";
|
|
import { t } from "#lib/i18n/locale.svelte.js";
|
|
import { accounts } from "#lib/stores/accounts.svelte.js";
|
|
import { chats } from "#lib/stores/chats.svelte.js";
|
|
import { discover } from "#lib/stores/discover.svelte.js";
|
|
import { toasts } from "#lib/stores/toasts.svelte.js";
|
|
|
|
interface Props {
|
|
chatId: number;
|
|
}
|
|
|
|
let { chatId }: Props = $props();
|
|
|
|
let busy = $state(false);
|
|
|
|
const item = $derived(discover.get(chatId));
|
|
const tracked = $derived(item?.tracked ?? false);
|
|
const title = $derived(item?.title ?? t("track.thisChat"));
|
|
|
|
$effect(() => {
|
|
if (accounts.selectedId === null) {
|
|
return;
|
|
}
|
|
discover.ensure(chatId).catch(() => undefined);
|
|
});
|
|
|
|
async function track() {
|
|
if (busy) {
|
|
return;
|
|
}
|
|
busy = true;
|
|
try {
|
|
discover.set(await trackChat(chatId, true));
|
|
toasts.success(t("track.started"));
|
|
chats.refresh();
|
|
} catch {
|
|
toasts.error(t("track.failed"));
|
|
} finally {
|
|
busy = false;
|
|
}
|
|
}
|
|
|
|
async function backfill() {
|
|
if (busy) {
|
|
return;
|
|
}
|
|
busy = true;
|
|
try {
|
|
await enqueueBackfill(chatId, true, true);
|
|
toasts.success(t("jobs.backfillStarted"));
|
|
} catch {
|
|
toasts.error(t("jobs.backfillFailed"));
|
|
} finally {
|
|
busy = false;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div class="track">
|
|
<div class="title">{t("track.empty")}</div>
|
|
<p class="description">
|
|
{tracked ? t("track.tracked", { title }) : t("track.hint")}
|
|
</p>
|
|
<div class="actions">
|
|
{#if tracked}
|
|
<Button loading={busy} onclick={backfill} pill variant="secondary">
|
|
<Icon name="cloud-download" />
|
|
<span>{t("track.loadHistory")}</span>
|
|
</Button>
|
|
{:else}
|
|
<Button loading={busy} onclick={track} pill variant="primary">
|
|
<Icon name="stats" />
|
|
<span>{t("track.start")}</span>
|
|
</Button>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
|
|
<style lang="scss">
|
|
.track {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
width: 100%;
|
|
height: 80%;
|
|
padding: 0 1.5rem;
|
|
}
|
|
|
|
.title {
|
|
margin-bottom: 0.25rem;
|
|
font-size: 1.25rem;
|
|
text-align: center;
|
|
}
|
|
|
|
.description {
|
|
max-width: 22rem;
|
|
margin: 0 0 1rem;
|
|
|
|
font-size: 0.875rem;
|
|
color: var(--color-text-secondary);
|
|
text-align: center;
|
|
}
|
|
|
|
.actions {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
}
|
|
</style>
|