fix: remove Appwrite sync effects that caused mount-loop
PrefsInitializer calls setTheme + updateConfig on mount. ThemeCustomizer was watching these with skip-first-mount effects — but after PrefsInitializer changed the values, the effects fired and called saveThemePrefsAction (server action). Next.js server actions revalidate the router cache, triggering a soft remount, resetting applied.current in PrefsInitializer, causing another save → infinite loop / flicker. Fix: dark/light and sidebar config no longer call saveThemePrefsAction from reactive effects. Sidebar saves localStorage only. Color theme / tweakcn / radius still call saveThemePrefsAction from explicit click handlers (no mount trigger, no loop).
This commit is contained in:
@@ -45,14 +45,9 @@ export function ThemeCustomizer({ open, onOpenChange, initialPrefs }: ThemeCusto
|
|||||||
const [importModalOpen, setImportModalOpen] = React.useState(false)
|
const [importModalOpen, setImportModalOpen] = React.useState(false)
|
||||||
const [importedTheme, setImportedTheme] = React.useState<ImportedTheme | null>(null)
|
const [importedTheme, setImportedTheme] = React.useState<ImportedTheme | null>(null)
|
||||||
|
|
||||||
// Save dark/light mode to Appwrite when it changes (skip first mount)
|
// Sidebar config → sadece localStorage (Appwrite tetiklemesi döngüye yol açıyordu:
|
||||||
const themeMountRef = React.useRef(false)
|
// PrefsInitializer mount'ta updateConfig çağırıyor → bu effect server action tetikliyor
|
||||||
React.useEffect(() => {
|
// → Next.js router cache revalidation → remount → döngü)
|
||||||
if (!themeMountRef.current) { themeMountRef.current = true; return }
|
|
||||||
void saveThemePrefsAction({ theme })
|
|
||||||
}, [theme])
|
|
||||||
|
|
||||||
// Save sidebar config to localStorage + Appwrite when it changes (skip first mount)
|
|
||||||
const sidebarMountRef = React.useRef(false)
|
const sidebarMountRef = React.useRef(false)
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!sidebarMountRef.current) { sidebarMountRef.current = true; return }
|
if (!sidebarMountRef.current) { sidebarMountRef.current = true; return }
|
||||||
@@ -61,11 +56,6 @@ export function ThemeCustomizer({ open, onOpenChange, initialPrefs }: ThemeCusto
|
|||||||
sidebarCollapsible: sidebarConfig.collapsible,
|
sidebarCollapsible: sidebarConfig.collapsible,
|
||||||
sidebarSide: sidebarConfig.side,
|
sidebarSide: sidebarConfig.side,
|
||||||
})
|
})
|
||||||
void saveThemePrefsAction({
|
|
||||||
sidebarVariant: sidebarConfig.variant,
|
|
||||||
sidebarCollapsible: sidebarConfig.collapsible,
|
|
||||||
sidebarSide: sidebarConfig.side,
|
|
||||||
})
|
|
||||||
}, [sidebarConfig.variant, sidebarConfig.collapsible, sidebarConfig.side])
|
}, [sidebarConfig.variant, sidebarConfig.collapsible, sidebarConfig.side])
|
||||||
|
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
@@ -78,7 +68,7 @@ export function ThemeCustomizer({ open, onOpenChange, initialPrefs }: ThemeCusto
|
|||||||
applyRadius("0.5rem")
|
applyRadius("0.5rem")
|
||||||
updateSidebarConfig({ variant: "inset", collapsible: "offcanvas", side: "left" })
|
updateSidebarConfig({ variant: "inset", collapsible: "offcanvas", side: "left" })
|
||||||
saveLocalThemePrefs({ colorTheme: "default", tweakcnTheme: "", radius: "0.5rem", sidebarVariant: "inset", sidebarCollapsible: "offcanvas", sidebarSide: "left" })
|
saveLocalThemePrefs({ colorTheme: "default", tweakcnTheme: "", radius: "0.5rem", sidebarVariant: "inset", sidebarCollapsible: "offcanvas", sidebarSide: "left" })
|
||||||
void saveThemePrefsAction({ colorTheme: "default", tweakcnTheme: "", radius: "0.5rem" })
|
void saveThemePrefsAction({ colorTheme: "default", tweakcnTheme: "", radius: "0.5rem", sidebarVariant: "inset", sidebarCollapsible: "offcanvas", sidebarSide: "left" })
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleImport = (themeData: ImportedTheme) => {
|
const handleImport = (themeData: ImportedTheme) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user