feat(frontend): feed of deleted and edited messages above the chat list and per chat in the changes panel
This commit is contained in:
1 parent
010fa29ce0
commit
9f16e2aa56
23 files changed
+1915
-71
No files matched your search
@@ -8,14 +8,17 @@
|
||||
import Icon from "#lib/components/ui/Icon.svelte";
|
||||
import { peerName } from "#lib/format/peer.js";
|
||||
import { formatPresence, isOnline } from "#lib/format/presence.js";
|
||||
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 { withoutMessage } from "#lib/stores/feed.svelte.js";
|
||||
import { policyUi } from "#lib/stores/policy.svelte.js";
|
||||
import { presence } from "#lib/stores/presence.svelte.js";
|
||||
import { toasts } from "#lib/stores/toasts.svelte.js";
|
||||
import { ui } from "#lib/stores/ui.svelte.js";
|
||||
import { goto } from "$app/navigation";
|
||||
import { page } from "$app/state";
|
||||
|
||||
interface Props {
|
||||
chatId: number;
|
||||
@@ -36,14 +39,20 @@
|
||||
backfilling = true;
|
||||
try {
|
||||
await enqueueBackfill(chatId, true);
|
||||
toasts.success("Догружаем новые сообщения");
|
||||
toasts.success(t("chat.backfill.started"));
|
||||
} catch {
|
||||
toasts.error("Не удалось запустить бэкфилл");
|
||||
toasts.error(t("chat.backfill.failed"));
|
||||
} finally {
|
||||
backfilling = false;
|
||||
}
|
||||
}
|
||||
|
||||
function back() {
|
||||
const target = new URL(page.url.href);
|
||||
target.pathname = "/app";
|
||||
goto(withoutMessage(target));
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
if (accounts.selectedId === null) {
|
||||
return;
|
||||
@@ -82,7 +91,9 @@
|
||||
const fallbackTitle = $derived(
|
||||
chat?.title ??
|
||||
discovered?.title ??
|
||||
(isDm ? "Удалённый аккаунт" : `Chat ${chatId}`)
|
||||
(isDm
|
||||
? t("chat.deletedAccount")
|
||||
: t("chat.fallbackTitle", { id: chatId }))
|
||||
);
|
||||
const title = $derived(isDm && peer ? peerName(peer) : fallbackTitle);
|
||||
const subtitle = $derived.by(() => {
|
||||
@@ -97,9 +108,11 @@
|
||||
}
|
||||
const count = chat?.message_count ?? discovered?.message_count ?? 0;
|
||||
if (count > 0) {
|
||||
return `${count} messages`;
|
||||
return t("chat.messages", { count });
|
||||
}
|
||||
return discovered?.kind === "channel" ? "channel" : "group";
|
||||
return discovered?.kind === "channel"
|
||||
? t("chat.kind.channel")
|
||||
: t("chat.kind.group");
|
||||
});
|
||||
const avatarKind = $derived(isDm ? "peer" : "chat");
|
||||
const hasAvatar = $derived(
|
||||
@@ -114,8 +127,8 @@
|
||||
<header class="chat-header">
|
||||
<div class="back">
|
||||
<Button
|
||||
aria-label="Назад"
|
||||
onclick={() => goto("/app")}
|
||||
aria-label={t("common.back")}
|
||||
onclick={back}
|
||||
round
|
||||
smaller
|
||||
variant="translucent"
|
||||
@@ -129,7 +142,7 @@
|
||||
})}
|
||||
<button
|
||||
{...props}
|
||||
aria-label="Открыть профиль"
|
||||
aria-label={t("chat.openProfile")}
|
||||
class="peek"
|
||||
onclick={() => ui.openPanel("profile")}
|
||||
type="button"
|
||||
@@ -157,23 +170,26 @@
|
||||
{/snippet}
|
||||
{#snippet menu()}
|
||||
<ContextMenuItem icon="info" onselect={() => ui.openPanel("profile")}
|
||||
>Открыть профиль</ContextMenuItem
|
||||
>{t("chat.openProfile")}</ContextMenuItem
|
||||
>
|
||||
<ContextMenuItem icon="recent" onselect={() => ui.openPanel("changes")}
|
||||
>{t("feed.changes")}</ContextMenuItem
|
||||
>
|
||||
<ContextMenuItem
|
||||
icon="play-story"
|
||||
onselect={() => ui.openPanel("stories")}
|
||||
>Сторис</ContextMenuItem
|
||||
>{t("settings.stories")}</ContextMenuItem
|
||||
>
|
||||
<ContextMenuItem
|
||||
icon="settings"
|
||||
onselect={() => policyUi.edit({ chatId }, title)}
|
||||
>Политика захвата</ContextMenuItem
|
||||
>{t("settings.policy")}</ContextMenuItem
|
||||
>
|
||||
{/snippet}
|
||||
</ContextMenu>
|
||||
<div class="actions">
|
||||
<Button
|
||||
aria-label="Поиск в чате"
|
||||
aria-label={t("chat.search")}
|
||||
onclick={() => ui.openPanel("search")}
|
||||
round
|
||||
smaller
|
||||
@@ -182,7 +198,16 @@
|
||||
<Icon name="search" />
|
||||
</Button>
|
||||
<Button
|
||||
aria-label="Аналитика"
|
||||
aria-label={t("feed.changes")}
|
||||
onclick={() => ui.openPanel("changes")}
|
||||
round
|
||||
smaller
|
||||
variant="translucent"
|
||||
>
|
||||
<Icon name="recent" />
|
||||
</Button>
|
||||
<Button
|
||||
aria-label={t("chat.analytics")}
|
||||
onclick={() => ui.openPanel("presence")}
|
||||
round
|
||||
smaller
|
||||
@@ -191,7 +216,7 @@
|
||||
<Icon name="stats" />
|
||||
</Button>
|
||||
<Button
|
||||
aria-label="Догрузить новые сообщения"
|
||||
aria-label={t("chat.backfill")}
|
||||
loading={backfilling}
|
||||
onclick={backfill}
|
||||
round
|
||||
|
||||
Reference in new issue
Block a user