mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
fix: update Aurora colors reactively without recreating WebGL context
Split the monolithic useEffect into two: one for WebGL init (depends only on isEnabled) and one for updating color uniforms (depends on theme colors). Previously the entire WebGL context was torn down and rebuilt on every color change, causing updates to not apply until page refresh or navigation.
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Renderer, Program, Mesh, Color, Triangle } from 'ogl';
|
||||
import { brandingApi } from '@/api/branding';
|
||||
import { themeColorsApi } from '@/api/themeColors';
|
||||
import { useTheme } from '@/hooks/useTheme';
|
||||
import { ThemeSettings, DEFAULT_THEME_COLORS } from '@/types/theme';
|
||||
import { DEFAULT_THEME_COLORS } from '@/types/theme';
|
||||
|
||||
const VERT = /* glsl */ `#version 300 es
|
||||
in vec2 position;
|
||||
@@ -132,8 +133,6 @@ export function Aurora() {
|
||||
const rendererRef = useRef<Renderer | null>(null);
|
||||
const programRef = useRef<Program | null>(null);
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// Fetch animation setting
|
||||
const { data: animationSetting } = useQuery({
|
||||
queryKey: ['animation-enabled'],
|
||||
@@ -143,15 +142,19 @@ export function Aurora() {
|
||||
|
||||
const isEnabled = animationSetting?.enabled ?? false;
|
||||
|
||||
// Get theme colors from cache (already fetched by ThemeColorsProvider)
|
||||
const themeColors =
|
||||
queryClient.getQueryData<ThemeSettings>(['theme-colors']) || DEFAULT_THEME_COLORS;
|
||||
// Subscribe reactively to theme-colors cache so Aurora re-renders on setQueryData
|
||||
const { data: themeColors = DEFAULT_THEME_COLORS } = useQuery({
|
||||
queryKey: ['theme-colors'],
|
||||
queryFn: themeColorsApi.getColors,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
});
|
||||
|
||||
// Pick background and surface based on current theme
|
||||
const { isDark } = useTheme();
|
||||
const background = isDark ? themeColors.darkBackground : themeColors.lightBackground;
|
||||
const surface = isDark ? themeColors.darkSurface : themeColors.lightSurface;
|
||||
|
||||
// Initialize WebGL context once (only depends on isEnabled)
|
||||
useEffect(() => {
|
||||
if (!isEnabled || !containerRef.current) return;
|
||||
|
||||
@@ -235,7 +238,20 @@ export function Aurora() {
|
||||
rendererRef.current = null;
|
||||
programRef.current = null;
|
||||
};
|
||||
}, [isEnabled, themeColors.accent, background, surface]);
|
||||
}, [isEnabled]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
// Update color uniforms reactively without recreating WebGL context
|
||||
useEffect(() => {
|
||||
if (!programRef.current) return;
|
||||
const colorStops = generateColorStops(background, surface, themeColors.accent);
|
||||
const colorStopsArray = colorStops
|
||||
.map((hex) => {
|
||||
const c = new Color(hex);
|
||||
return [c.r, c.g, c.b];
|
||||
})
|
||||
.flat();
|
||||
programRef.current.uniforms.uColorStops.value = colorStopsArray;
|
||||
}, [themeColors.accent, background, surface]);
|
||||
|
||||
if (!isEnabled) {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user