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

+19 -10
View File
@@ -28,8 +28,9 @@ import type {
PolicyRecord,
PolicyRule,
PolicyScope,
PresenceHourly,
PresenceSample,
PresenceSession,
PresenceStats,
ReactionView,
ReadInfo,
ResponseStats,
@@ -206,30 +207,38 @@ export function getCurrentPresence(
});
}
export function getPresenceHistory(
export function getPresenceStats(
peerId: number,
days: number,
tz: string,
page: Page = {}
): Promise<PresenceSample[]> {
return request<PresenceSample[]>("/presence", {
): Promise<PresenceStats> {
return request<PresenceStats>("/presence/stats", {
account: true,
query: { peer_id: peerId, ...page },
query: { days, peer_id: peerId, tz, ...page },
});
}
export function getPresenceHourly(peerId: number): Promise<PresenceHourly[]> {
return request<PresenceHourly[]>("/presence/hourly", {
export function getPresenceSessions(
peerId: number,
days: number,
tz: string,
page: Page = {}
): Promise<PresenceSession[]> {
return request<PresenceSession[]>("/presence/sessions", {
account: true,
query: { peer_id: peerId },
query: { days, peer_id: peerId, tz, ...page },
});
}
export function getMessageVolume(
chatId: number,
days = 90
days: number,
tz: string
): Promise<VolumeBucket[]> {
return request<VolumeBucket[]>("/analytics/volume", {
account: true,
query: { chat_id: chatId, days },
query: { chat_id: chatId, days, tz },
});
}
+49 -4
View File
@@ -336,12 +336,57 @@ export interface PresenceSample {
ts: string;
}
export interface PresenceHourly {
bucket: string;
export interface PresenceSession {
ended: string;
ongoing: boolean;
online_seconds: number;
seconds: number;
started: string;
}
export interface PresenceHour {
covered_hours: number;
hour: number;
hours: number;
online_minutes: number | null;
weekday: number;
}
export interface PresenceDay {
covered_seconds: number;
day: string;
online_seconds: number;
}
export interface CoverageGap {
ended: string;
started: string;
}
export interface PresenceSummary {
covered_seconds: number;
daily_seconds: number | null;
first_online: number | null;
last_offline: number | null;
last_seen: string | null;
online_samples: number;
median_session_seconds: number | null;
online_seconds: number;
session_count: number;
}
export interface PresenceStats {
current: PresenceSample | null;
days: PresenceDay[];
gaps: CoverageGap[];
hidden: boolean;
online: boolean;
peer_id: number;
samples: number;
sessions: PresenceSession[];
since: string;
summary: PresenceSummary;
tz: string;
until: string;
week: PresenceHour[];
}
export interface VolumeBucket {