feat: redesign + avatars + theme + call presence fixes (v0.6.0)
Visual:
- Light/dark theme via ThemeContext + CSS vars
- New design tokens (surface/fg/accent/line/etc.) across all pages
- Reusable Avatar component (img + letter fallback) wired into UserBar,
ConversationHeader, ChatsPage, FriendsPage, GroupInfoPanel, IncomingCallPanel
Calls:
- Split call UI: IncomingCallPanel, InCallPanel, CallControls,
CallParticipantTile, ScreenShareViewer
- Active speaker hook (useActiveSpeakers)
- Fix: ActiveCallBanner stayed hidden after hangup while peers in room.
- useCallPresence: bind presence callbacks only when we own subscribe
(Supabase forbids .on() after .subscribe() on shared dedup'd channels)
- useCallPresence: never removeChannel — channel is shared with CallContext
so tearing it down on ConversationHeader unmount killed live tracking
- ActiveCallBanner: lastCallConversationId fallback so banner shows
instantly after hangup, auto-dismiss when room confirmed empty
- Drop unused useAnyActiveCall
Bump tauri version 0.5.0 -> 0.6.0
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
// Clean-Rail theme: persisted `.dark` class on <html>. Default follows the
|
||||
// system preference; user-toggle persists to localStorage and wins over it.
|
||||
|
||||
export type Theme = 'light' | 'dark';
|
||||
|
||||
const STORAGE_KEY = 'netralax.theme';
|
||||
|
||||
function readStoredTheme(): Theme | null {
|
||||
try {
|
||||
const raw = window.localStorage.getItem(STORAGE_KEY);
|
||||
if (raw === 'light' || raw === 'dark') return raw;
|
||||
} catch {
|
||||
/* localStorage unavailable (private mode / sandbox) */
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function writeStoredTheme(theme: Theme): void {
|
||||
try {
|
||||
window.localStorage.setItem(STORAGE_KEY, theme);
|
||||
} catch {
|
||||
/* localStorage unavailable */
|
||||
}
|
||||
}
|
||||
|
||||
function systemPrefersDark(): boolean {
|
||||
return typeof window !== 'undefined'
|
||||
&& typeof window.matchMedia === 'function'
|
||||
&& window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
|
||||
export function getInitialTheme(): Theme {
|
||||
return readStoredTheme() ?? (systemPrefersDark() ? 'dark' : 'light');
|
||||
}
|
||||
|
||||
export function applyTheme(theme: Theme): void {
|
||||
const root = document.documentElement;
|
||||
root.classList.toggle('dark', theme === 'dark');
|
||||
}
|
||||
|
||||
export function setThemePersisted(theme: Theme): void {
|
||||
writeStoredTheme(theme);
|
||||
applyTheme(theme);
|
||||
}
|
||||
Reference in New Issue
Block a user