feat(messages): E2EE real-time messaging UI + system welcome
A Messages tab in the notification center (hidden for demo): set up secure messaging with a passphrase (key generated + wrapped in-browser via WebCrypto, stored non-extractable per device), unlock on other devices, then chat with end-to-end encrypted, live-delivered messages. The server-authored Siftlode welcome is readable before any key setup. - lib/e2ee.ts: ECDH P-256 + HKDF + AES-GCM, PBKDF2-wrapped key, IndexedDB. - lib/messagesSocket.ts: WebSocket client with backoff reconnect. - Messages.tsx: key gate, conversation list with decrypted previews, directory, thread with client-side decrypt + encrypt-on-send. Unread feeds the nav badge. EN/HU/DE strings.
This commit is contained in:
parent
002a79949b
commit
2f0ca68e8a
13 changed files with 943 additions and 6 deletions
|
|
@ -126,7 +126,15 @@ export default function NavSidebar({
|
|||
// One indicator for both layers: durable server notifications + the client-side transient
|
||||
// events (the former separate bell is now folded into the inbox page).
|
||||
const clientUnread = useSyncExternalStore(subscribe, getUnreadCount, getUnreadCount);
|
||||
const unread = (unreadQuery.data?.count ?? 0) + clientUnread;
|
||||
// Unread direct messages also live in the notification module, so they add to the same badge.
|
||||
// The demo account can't use messaging, so don't poll it there.
|
||||
const msgUnreadQuery = useLiveQuery(
|
||||
["message-unread"],
|
||||
api.messageUnreadCount,
|
||||
{ intervalMs: 30000, enabled: !me.is_demo }
|
||||
);
|
||||
const unread =
|
||||
(unreadQuery.data?.count ?? 0) + clientUnread + (msgUnreadQuery.data?.count ?? 0);
|
||||
|
||||
type NavItem = { page: Page; icon: typeof Home; label: string; badge?: number };
|
||||
// User-facing content modules vs. admin/system modules, separated by a divider in the rail.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue