feat(chat): add presence metadata and improve web chat core
Some checks failed
CI / test (push) Failing after 22s
Some checks failed
CI / test (push) Failing after 22s
- add user last_seen_at with alembic migration and persist on realtime disconnect - extend chat serialization with private online/last_seen, group members/online, channel subscribers - add Redis batch presence lookup helper - update web chat list/header to display status counters and last-seen labels - improve delivery receipt handling using last_delivered/last_read boundaries - include chat info panel and related API/type updates
This commit is contained in:
@@ -145,7 +145,7 @@ export function ChatList() {
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<p className="truncate text-xs text-slate-400">{chat.type}</p>
|
||||
<p className="truncate text-xs text-slate-400">{chatMetaLabel(chat)}</p>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
@@ -283,3 +283,46 @@ function chatLabel(chat: { display_title?: string | null; title: string | null;
|
||||
if (chat.type === "group") return "Group";
|
||||
return "Channel";
|
||||
}
|
||||
|
||||
function chatMetaLabel(chat: {
|
||||
type: "private" | "group" | "channel";
|
||||
is_saved?: boolean;
|
||||
counterpart_is_online?: boolean | null;
|
||||
counterpart_last_seen_at?: string | null;
|
||||
members_count?: number | null;
|
||||
online_count?: number | null;
|
||||
subscribers_count?: number | null;
|
||||
}): string {
|
||||
if (chat.is_saved) {
|
||||
return "Personal cloud chat";
|
||||
}
|
||||
if (chat.type === "private") {
|
||||
if (chat.counterpart_is_online) {
|
||||
return "online";
|
||||
}
|
||||
if (chat.counterpart_last_seen_at) {
|
||||
return `last seen ${formatLastSeen(chat.counterpart_last_seen_at)}`;
|
||||
}
|
||||
return "offline";
|
||||
}
|
||||
if (chat.type === "group") {
|
||||
const members = chat.members_count ?? 0;
|
||||
const online = chat.online_count ?? 0;
|
||||
return `${members} members, ${online} online`;
|
||||
}
|
||||
const subscribers = chat.subscribers_count ?? chat.members_count ?? 0;
|
||||
return `${subscribers} subscribers`;
|
||||
}
|
||||
|
||||
function formatLastSeen(value: string): string {
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) {
|
||||
return "recently";
|
||||
}
|
||||
return date.toLocaleString(undefined, {
|
||||
day: "2-digit",
|
||||
month: "short",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit"
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user