diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py index 118bd5f55..ab82cedc2 100644 --- a/web/pgadmin/browser/__init__.py +++ b/web/pgadmin/browser/__init__.py @@ -400,12 +400,6 @@ def index(): 'pass_enc_key' in session: session['allow_save_password'] = False - response = Response(render_template( - MODULE_NAME + "/index.html", - username=current_user.username, - _=gettext - )) - # Set the language cookie after login, so next time the user will have that # same option at the login time. misc_preference = Preferences.module('misc') @@ -416,11 +410,22 @@ def index(): if user_languages: language = user_languages.get() or 'en' + # Get the theme preference + user_theme = misc_preference.preference('theme') + theme = user_theme.get() or 'light' if user_theme else 'light' + domain = dict() if config.COOKIE_DEFAULT_DOMAIN and\ config.COOKIE_DEFAULT_DOMAIN != 'localhost': domain['domain'] = config.COOKIE_DEFAULT_DOMAIN + response = Response(render_template( + MODULE_NAME + "/index.html", + username=current_user.username, + theme=theme, + _=gettext + )) + response.set_cookie("PGADMIN_LANGUAGE", value=language, path=config.SESSION_COOKIE_PATH, secure=config.SESSION_COOKIE_SECURE, diff --git a/web/pgadmin/browser/templates/browser/index.html b/web/pgadmin/browser/templates/browser/index.html index 4a9c589e9..f72b72754 100644 --- a/web/pgadmin/browser/templates/browser/index.html +++ b/web/pgadmin/browser/templates/browser/index.html @@ -3,6 +3,9 @@ {% block title %}{{ config.APP_NAME }}{% endblock %} {% block init_script %} +// Set theme on the global window object +window.theme = "{{ theme }}"; + function parseConsoleArgs(args) { const retData = Array.from(args).map(arg => { try { diff --git a/web/pgadmin/static/js/Theme/index.jsx b/web/pgadmin/static/js/Theme/index.jsx index fd7709d91..29323fba3 100644 --- a/web/pgadmin/static/js/Theme/index.jsx +++ b/web/pgadmin/static/js/Theme/index.jsx @@ -882,12 +882,34 @@ function getFinalTheme(baseTheme) { }, baseTheme); } +/* Get the actual system theme is user selected system theme in preferences */ +function parseSystemTheme(selectedTheme) { + if (selectedTheme === 'system') { + const systemMatchMedia = matchMedia('(prefers-color-scheme: dark)'); + return { + 'theme': systemMatchMedia.matches ? 'dark' : 'light', + 'systemMatchMedia': systemMatchMedia, + }; + } + return { + 'theme': selectedTheme, + 'systemMatchMedia': null, + }; +} + /* Theme wrapper used by DOM containers to apply theme */ /* In future, this will be moved to App container */ export default function Theme({children}) { const prefStore = usePreferences(); - const [theme, setTheme] = useState(); + const selectedTheme = + prefStore?.getPreferencesForModule('misc')?.theme || + window.theme || + 'light'; + // Initialize theme state + const [theme, setTheme] = useState(parseSystemTheme(selectedTheme).theme); + + // Memoize the theme object const themeObj = useMemo(()=>{ let baseTheme = getLightTheme(basicSettings); switch(theme) { @@ -901,31 +923,26 @@ export default function Theme({children}) { return getFinalTheme(baseTheme); }, [theme]); + // Handle theme updates useEffect(() => { - const selectedTheme = prefStore.getPreferencesForModule('misc').theme; - if(theme && theme === selectedTheme) { - return; - }else{ - if (selectedTheme !== 'system') { - setTheme(selectedTheme); - return; - } - const isSystemInDarkMode = matchMedia('(prefers-color-scheme: dark)'); - setTheme(isSystemInDarkMode.matches ? 'dark' : 'light'); - const listener = (event) => { - setTheme(event.matches ? 'dark' : 'light'); - }; - isSystemInDarkMode.addEventListener('change',listener); - return () => { - isSystemInDarkMode.removeEventListener('change',listener); - }; - } - },[prefStore]); + let {theme, systemMatchMedia} = parseSystemTheme(selectedTheme); + setTheme(theme); + + const updateTheme = (event) => { + const newTheme = event.matches ? 'dark' : 'light'; + setTheme(newTheme); + }; + systemMatchMedia?.addEventListener('change', updateTheme); + + return () => { + systemMatchMedia?.removeEventListener('change', updateTheme); + }; + },[selectedTheme]); return ( - + {children}