feat(api,userbot,frontend): search peers without chats and start tracking them

This commit is contained in:
hh
2026-08-05 23:46:54 +02:00
parent dcf95bd9d4
commit 92fd20137e
21 changed files with 936 additions and 65 deletions
@@ -0,0 +1,118 @@
<script lang="ts">
import { enqueueBackfill, trackChat } from "$lib/api/endpoints";
import Button from "$lib/components/ui/Button.svelte";
import Icon from "$lib/components/ui/Icon.svelte";
import { accounts } from "$lib/stores/accounts.svelte";
import { chats } from "$lib/stores/chats.svelte";
import { discover } from "$lib/stores/discover.svelte";
import { toasts } from "$lib/stores/toasts.svelte";
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 ?? "Этот чат");
$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("Отслеживание включено, история загружается");
chats.refresh();
} catch {
toasts.error("Не удалось включить отслеживание");
} finally {
busy = false;
}
}
async function backfill() {
if (busy) {
return;
}
busy = true;
try {
await enqueueBackfill(chatId, true);
toasts.success("Бэкфилл запущен");
} catch {
toasts.error("Не удалось запустить бэкфилл");
} finally {
busy = false;
}
}
</script>
<div class="track">
<div class="title">Здесь пока нет сообщений</div>
<p class="description">
{#if tracked}
{title}
отслеживается — новые сообщения и статистика собираются автоматически.
{:else}
Включите отслеживание, чтобы собирать сообщения, медиа и статистику по
этому чату.
{/if}
</p>
<div class="actions">
{#if tracked}
<Button variant="secondary" pill loading={busy} onclick={backfill}>
<Icon name="cloud-download" />
<span>Загрузить историю</span>
</Button>
{:else}
<Button variant="primary" pill loading={busy} onclick={track}>
<Icon name="stats" />
<span>Начать отслеживать</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>