fix: make tag indicators immediately update colors on theme switch

Tag indicators next to guest names now properly update their colors when switching between dark and light modes. Previously they would only update on the next data refresh cycle.

- Added reactive DarkModeContext for theme state management
- Updated TagBadges component to use reactive dark mode signal
- Made color calculations reactive to respond to theme changes
This commit is contained in:
Pulse Monitor
2025-09-03 12:39:49 +00:00
parent 7595fbd644
commit 0603a6506f
2 changed files with 24 additions and 10 deletions
+15 -3
View File
@@ -35,6 +35,16 @@ export const useWebSocket = () => {
return context;
};
// Dark mode context for reactive theme switching
export const DarkModeContext = createContext<() => boolean>(() => false);
export const useDarkMode = () => {
const context = useContext(DarkModeContext);
if (!context) {
throw new Error('useDarkMode must be used within DarkModeContext.Provider');
}
return context;
};
function App() {
// Simple auth state
const [isLoading, setIsLoading] = createSignal(true);
@@ -392,9 +402,10 @@ function App() {
<ErrorBoundary>
<Show when={enhancedStore()} fallback={<div>Initializing...</div>}>
<WebSocketContext.Provider value={enhancedStore()!}>
<SecurityWarning />
<UpdateBanner />
<div class="min-h-screen bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-200 p-2 font-sans">
<DarkModeContext.Provider value={darkMode}>
<SecurityWarning />
<UpdateBanner />
<div class="min-h-screen bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-200 p-2 font-sans">
<div class="container w-[95%] max-w-screen-xl mx-auto">
{/* Header */}
<div class="header flex flex-row justify-between items-center mb-2">
@@ -606,6 +617,7 @@ function App() {
</div>
<ToastContainer />
<NotificationContainer />
</DarkModeContext.Provider>
</WebSocketContext.Provider>
</Show>
</ErrorBoundary>
@@ -1,6 +1,7 @@
import { Component, For, Show, createSignal } from 'solid-js';
import { Portal } from 'solid-js/web';
import { getTagColorWithSpecial } from '@/utils/tagColors';
import { useDarkMode } from '@/App';
interface TagBadgesProps {
tags: string[];
@@ -12,7 +13,8 @@ interface TagBadgesProps {
export const TagBadges: Component<TagBadgesProps> = (props) => {
const maxVisible = () => props.maxVisible ?? 3;
const isDark = () => props.isDarkMode ?? document.documentElement.classList.contains('dark');
const darkModeSignal = useDarkMode();
const isDark = () => props.isDarkMode ?? darkModeSignal();
const visibleTags = () => props.tags?.slice(0, maxVisible()) || [];
const hiddenTags = () => props.tags?.slice(maxVisible()) || [];
@@ -26,7 +28,7 @@ export const TagBadges: Component<TagBadgesProps> = (props) => {
<div class="inline-flex items-center gap-1 ml-2">
<For each={visibleTags()}>
{(tag) => {
const colors = getTagColorWithSpecial(tag, isDark());
const colors = () => getTagColorWithSpecial(tag, isDark());
const isActive = () => props.activeSearch?.includes(`tags:${tag}`) || false;
return (
@@ -50,7 +52,7 @@ export const TagBadges: Component<TagBadgesProps> = (props) => {
<div
class="w-2 h-2 rounded-full hover:scale-150 transition-transform duration-200 ease-out cursor-pointer"
style={{
'background-color': colors.bg,
'background-color': colors().bg,
'box-shadow': isActive()
? isDark()
? `0 0 0 2.5px rgba(255, 255, 255, 0.9)` // White ring in dark mode when active
@@ -108,7 +110,7 @@ export const TagBadges: Component<TagBadgesProps> = (props) => {
// Tooltip for individual tag
(() => {
const tag = hoveredTag()!;
const colors = getTagColorWithSpecial(tag, isDark());
const colors = () => getTagColorWithSpecial(tag, isDark());
return (
<div
class="fixed px-2 py-1 text-xs rounded shadow-lg pointer-events-none"
@@ -116,9 +118,9 @@ export const TagBadges: Component<TagBadgesProps> = (props) => {
left: `${tooltipPos()!.x}px`,
top: `${tooltipPos()!.y - 35}px`,
transform: 'translateX(-50%)',
'background-color': colors.bg,
'color': colors.text,
'border': `1px solid ${colors.border}`,
'background-color': colors().bg,
'color': colors().text,
'border': `1px solid ${colors().border}`,
'z-index': '999999',
}}
>