mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 10:27:49 +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 { 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 { Renderer, Program, Mesh, Color, Triangle } from 'ogl';
|
||||||
import { brandingApi } from '@/api/branding';
|
import { brandingApi } from '@/api/branding';
|
||||||
|
import { themeColorsApi } from '@/api/themeColors';
|
||||||
import { useTheme } from '@/hooks/useTheme';
|
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
|
const VERT = /* glsl */ `#version 300 es
|
||||||
in vec2 position;
|
in vec2 position;
|
||||||
@@ -132,8 +133,6 @@ export function Aurora() {
|
|||||||
const rendererRef = useRef<Renderer | null>(null);
|
const rendererRef = useRef<Renderer | null>(null);
|
||||||
const programRef = useRef<Program | null>(null);
|
const programRef = useRef<Program | null>(null);
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
|
|
||||||
// Fetch animation setting
|
// Fetch animation setting
|
||||||
const { data: animationSetting } = useQuery({
|
const { data: animationSetting } = useQuery({
|
||||||
queryKey: ['animation-enabled'],
|
queryKey: ['animation-enabled'],
|
||||||
@@ -143,15 +142,19 @@ export function Aurora() {
|
|||||||
|
|
||||||
const isEnabled = animationSetting?.enabled ?? false;
|
const isEnabled = animationSetting?.enabled ?? false;
|
||||||
|
|
||||||
// Get theme colors from cache (already fetched by ThemeColorsProvider)
|
// Subscribe reactively to theme-colors cache so Aurora re-renders on setQueryData
|
||||||
const themeColors =
|
const { data: themeColors = DEFAULT_THEME_COLORS } = useQuery({
|
||||||
queryClient.getQueryData<ThemeSettings>(['theme-colors']) || DEFAULT_THEME_COLORS;
|
queryKey: ['theme-colors'],
|
||||||
|
queryFn: themeColorsApi.getColors,
|
||||||
|
staleTime: 5 * 60 * 1000,
|
||||||
|
});
|
||||||
|
|
||||||
// Pick background and surface based on current theme
|
// Pick background and surface based on current theme
|
||||||
const { isDark } = useTheme();
|
const { isDark } = useTheme();
|
||||||
const background = isDark ? themeColors.darkBackground : themeColors.lightBackground;
|
const background = isDark ? themeColors.darkBackground : themeColors.lightBackground;
|
||||||
const surface = isDark ? themeColors.darkSurface : themeColors.lightSurface;
|
const surface = isDark ? themeColors.darkSurface : themeColors.lightSurface;
|
||||||
|
|
||||||
|
// Initialize WebGL context once (only depends on isEnabled)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isEnabled || !containerRef.current) return;
|
if (!isEnabled || !containerRef.current) return;
|
||||||
|
|
||||||
@@ -235,7 +238,20 @@ export function Aurora() {
|
|||||||
rendererRef.current = null;
|
rendererRef.current = null;
|
||||||
programRef.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) {
|
if (!isEnabled) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user