feat(frontend): analytics shows minutes online by hour of week and by day, sessions with start and end, says when last seen is hidden, chat status is live and in russian

This commit is contained in:
hh committed 2026-10-19 02:41:39 +00:00
1 parent f44597b2dc
commit 73b8903de1
11 files changed
+1275 -373

No files matched your search

+13 -40
View File
@@ -1,10 +1,6 @@
<script lang="ts">
import {
enqueueBackfill,
getCurrentPresence,
getPeer,
} from "#lib/api/endpoints.js";
import type { PeerView, PresenceSample } from "#lib/api/types.js";
import { enqueueBackfill, getPeer } from "#lib/api/endpoints.js";
import type { PeerView } from "#lib/api/types.js";
import Avatar from "#lib/components/ui/Avatar.svelte";
import Button from "#lib/components/ui/Button.svelte";
import ContextMenu from "#lib/components/ui/ContextMenu.svelte";
@@ -16,6 +12,7 @@
import { chats } from "#lib/stores/chats.svelte.js";
import { discover } from "#lib/stores/discover.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";
@@ -26,13 +23,10 @@
let { chatId }: Props = $props();
const PRESENCE_INTERVAL = 30_000;
const isDm = $derived(chatId > 0);
const chat = $derived(chats.byId(chatId));
const discovered = $derived(discover.get(chatId));
let peer = $state<PeerView | null>(null);
let presence = $state<PresenceSample | null>(null);
let backfilling = $state(false);
async function backfill() {
@@ -81,34 +75,8 @@
});
$effect(() => {
if (accounts.selectedId === null || !isDm) {
presence = null;
return;
}
let active = true;
presence = null;
const refresh = () => {
if (document.visibilityState !== "visible") {
return;
}
getCurrentPresence(chatId)
.then((result) => {
if (active) {
presence = result;
}
})
.catch(() => {
if (active) {
presence = null;
}
});
};
refresh();
const timer = setInterval(refresh, PRESENCE_INTERVAL);
return () => {
active = false;
clearInterval(timer);
};
presence.follow(accounts.selectedId, isDm ? chatId : null);
return () => presence.follow(null, null);
});
const fallbackTitle = $derived(
@@ -119,8 +87,8 @@
const title = $derived(isDm && peer ? peerName(peer) : fallbackTitle);
const subtitle = $derived.by(() => {
if (isDm) {
if (presence) {
return formatPresence(presence);
if (presence.sample) {
return formatPresence(presence.sample, presence.now);
}
if (peer?.username) {
return `@${peer.username}`;
@@ -176,7 +144,12 @@
/>
<div class="info">
<h2 class="title">{title}</h2>
<span class="subtitle" class:online={isDm && isOnline(presence)}>
<span
class={[
"subtitle",
{ online: isDm && isOnline(presence.sample, presence.now) },
]}
>
{subtitle}
</span>
</div>