mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-10-13 15:28:05 +01:00
Updated the Theme changes based on portal theme changes
This commit is contained in:
parent
26b9816214
commit
066bef5fc8
@ -1,48 +1,5 @@
|
|||||||
import { useFluent } from "@fluentui/react-components";
|
|
||||||
import React, { createContext, FC, ReactNode, useEffect, useState } from "react";
|
|
||||||
import create from "zustand";
|
import create from "zustand";
|
||||||
|
|
||||||
interface ThemeSettings {
|
|
||||||
mode: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FxsTheme {
|
|
||||||
(): ThemeSettings;
|
|
||||||
subscribe: (context: null, callback: (update: ThemeSettings) => void) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface MsPortalFxSettings {
|
|
||||||
"fxs-theme"?: FxsTheme;
|
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
MsPortalFx?: {
|
|
||||||
Services: {
|
|
||||||
getSettings: () => Promise<MsPortalFxSettings>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ThemeContextType {
|
|
||||||
theme: "Light" | "Dark";
|
|
||||||
isDarkMode: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
|
|
||||||
|
|
||||||
interface ThemeProviderProps {
|
|
||||||
children: ReactNode;
|
|
||||||
theme: "Light" | "Dark";
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CustomThemeProvider: FC<ThemeProviderProps> = ({ children, theme }) => {
|
|
||||||
const isDarkMode = theme === "Dark";
|
|
||||||
return <ThemeContext.Provider value={{ theme, isDarkMode }}>{children}</ThemeContext.Provider>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface ThemeStore {
|
export interface ThemeStore {
|
||||||
isDarkMode: boolean;
|
isDarkMode: boolean;
|
||||||
themeMode: number;
|
themeMode: number;
|
||||||
@ -63,10 +20,6 @@ export const useThemeStore = create<ThemeStore>((set) => ({
|
|||||||
document.body.classList.remove("isDarkMode");
|
document.body.classList.remove("isDarkMode");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save to localStorage for persistence
|
|
||||||
localStorage.setItem("cosmos-explorer-theme", newIsDarkMode ? "dark" : "light");
|
|
||||||
localStorage.setItem("cosmos-explorer-theme-mode", String(newThemeMode));
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isDarkMode: newIsDarkMode,
|
isDarkMode: newIsDarkMode,
|
||||||
themeMode: newThemeMode,
|
themeMode: newThemeMode,
|
||||||
@ -74,124 +27,47 @@ export const useThemeStore = create<ThemeStore>((set) => ({
|
|||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Initialize the theme from localStorage or MsPortalFx if available
|
// Portal theme communication
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
// Try to initialize from MsPortalFx.Services if available
|
window.addEventListener("message", (event) => {
|
||||||
try {
|
// Only process portal messages
|
||||||
if (window.MsPortalFx && window.MsPortalFx.Services) {
|
if (
|
||||||
window.MsPortalFx.Services.getSettings()
|
event.data &&
|
||||||
.then((settings: MsPortalFxSettings) => {
|
typeof event.data === "object" &&
|
||||||
if (settings["fxs-theme"]) {
|
event.data.signature === "pcIframe" &&
|
||||||
const theme = settings["fxs-theme"];
|
event.data.data &&
|
||||||
|
event.data.data.type === "UpdateTheme" &&
|
||||||
|
event.data.data.theme &&
|
||||||
|
event.data.data.theme.mode !== undefined
|
||||||
|
) {
|
||||||
|
const themeMode = event.data.data.theme.mode;
|
||||||
|
const isDark = themeMode === 1;
|
||||||
|
|
||||||
// Initial theme value
|
useThemeStore.setState({
|
||||||
const initialTheme = theme();
|
isDarkMode: isDark,
|
||||||
if (initialTheme && typeof initialTheme.mode === "number") {
|
themeMode: themeMode,
|
||||||
const isDark = initialTheme.mode === 1;
|
});
|
||||||
useThemeStore.setState({
|
|
||||||
isDarkMode: isDark,
|
|
||||||
themeMode: initialTheme.mode,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isDark) {
|
if (isDark) {
|
||||||
document.body.classList.add("isDarkMode");
|
document.body.classList.add("isDarkMode");
|
||||||
} else {
|
} else {
|
||||||
document.body.classList.remove("isDarkMode");
|
document.body.classList.remove("isDarkMode");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
theme.subscribe(null, (themeUpdate: ThemeSettings) => {
|
|
||||||
if (themeUpdate && typeof themeUpdate.mode === "number") {
|
|
||||||
const isDark = themeUpdate.mode === 1;
|
|
||||||
useThemeStore.setState({
|
|
||||||
isDarkMode: isDark,
|
|
||||||
themeMode: themeUpdate.mode,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isDark) {
|
|
||||||
document.body.classList.add("isDarkMode");
|
|
||||||
} else {
|
|
||||||
document.body.classList.remove("isDarkMode");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
fallbackToLocalStorage();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
fallbackToLocalStorage();
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
});
|
||||||
fallbackToLocalStorage();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fallbackToLocalStorage() {
|
// Exports
|
||||||
const savedTheme = localStorage.getItem("cosmos-explorer-theme");
|
|
||||||
const savedThemeMode = localStorage.getItem("cosmos-explorer-theme-mode");
|
|
||||||
|
|
||||||
if (savedTheme || savedThemeMode) {
|
|
||||||
const isDark = savedTheme === "dark" || savedThemeMode === "1";
|
|
||||||
const themeMode = isDark ? 1 : 0;
|
|
||||||
|
|
||||||
useThemeStore.setState({
|
|
||||||
isDarkMode: isDark,
|
|
||||||
themeMode: themeMode,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isDark) {
|
|
||||||
document.body.classList.add("isDarkMode");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dynamic exports that use the theme store
|
|
||||||
export const isDarkMode = () => useThemeStore.getState().isDarkMode;
|
export const isDarkMode = () => useThemeStore.getState().isDarkMode;
|
||||||
|
|
||||||
|
export const useTheme = () => {
|
||||||
|
const { isDarkMode } = useThemeStore();
|
||||||
|
return { isDarkMode };
|
||||||
|
};
|
||||||
|
|
||||||
export const useMonacoTheme = () => {
|
export const useMonacoTheme = () => {
|
||||||
const { isDarkMode } = useThemeStore();
|
const { isDarkMode } = useThemeStore();
|
||||||
return isDarkMode ? "vs-dark" : "vs";
|
return isDarkMode ? "vs-dark" : "vs";
|
||||||
};
|
};
|
||||||
|
|
||||||
export const monacoTheme = () => (useThemeStore.getState().isDarkMode ? "vs-dark" : "vs");
|
export const monacoTheme = () => (useThemeStore.getState().isDarkMode ? "vs-dark" : "vs");
|
||||||
|
|
||||||
export const useTheme = () => {
|
|
||||||
const { targetDocument } = useFluent();
|
|
||||||
const context = React.useContext(ThemeContext);
|
|
||||||
|
|
||||||
const [isDarkMode, setIsDarkMode] = useState(() => {
|
|
||||||
if (context) {
|
|
||||||
return context.isDarkMode;
|
|
||||||
}
|
|
||||||
return targetDocument?.body.classList.contains("isDarkMode") ?? true;
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!targetDocument) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const checkTheme = () => {
|
|
||||||
if (context) {
|
|
||||||
setIsDarkMode(context.isDarkMode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const hasDarkMode = targetDocument.body.classList.contains("isDarkMode");
|
|
||||||
setIsDarkMode(hasDarkMode);
|
|
||||||
};
|
|
||||||
|
|
||||||
checkTheme();
|
|
||||||
|
|
||||||
const observer = new MutationObserver(() => {
|
|
||||||
checkTheme();
|
|
||||||
});
|
|
||||||
observer.observe(targetDocument.body, { attributes: true, attributeFilter: ["class"] });
|
|
||||||
|
|
||||||
return () => observer.disconnect();
|
|
||||||
}, [targetDocument, context]);
|
|
||||||
|
|
||||||
return {
|
|
||||||
isDarkMode,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user