Skip to content

Commit 4e8f29f

Browse files
authored
Fixed an issue where light theme briefly appears when pgAdmin loads or tools open, even when a dark or system UI theme is preferred. #8711
1 parent 126e1fb commit 4e8f29f

3 files changed

Lines changed: 52 additions & 27 deletions

File tree

web/pgadmin/browser/__init__.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -400,12 +400,6 @@ def index():
400400
'pass_enc_key' in session:
401401
session['allow_save_password'] = False
402402

403-
response = Response(render_template(
404-
MODULE_NAME + "/index.html",
405-
username=current_user.username,
406-
_=gettext
407-
))
408-
409403
# Set the language cookie after login, so next time the user will have that
410404
# same option at the login time.
411405
misc_preference = Preferences.module('misc')
@@ -416,11 +410,22 @@ def index():
416410
if user_languages:
417411
language = user_languages.get() or 'en'
418412

413+
# Get the theme preference
414+
user_theme = misc_preference.preference('theme')
415+
theme = user_theme.get() or 'light' if user_theme else 'light'
416+
419417
domain = dict()
420418
if config.COOKIE_DEFAULT_DOMAIN and\
421419
config.COOKIE_DEFAULT_DOMAIN != 'localhost':
422420
domain['domain'] = config.COOKIE_DEFAULT_DOMAIN
423421

422+
response = Response(render_template(
423+
MODULE_NAME + "/index.html",
424+
username=current_user.username,
425+
theme=theme,
426+
_=gettext
427+
))
428+
424429
response.set_cookie("PGADMIN_LANGUAGE", value=language,
425430
path=config.SESSION_COOKIE_PATH,
426431
secure=config.SESSION_COOKIE_SECURE,

web/pgadmin/browser/templates/browser/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
{% block title %}{{ config.APP_NAME }}{% endblock %}
44

55
{% block init_script %}
6+
// Set theme on the global window object
7+
window.theme = "{{ theme }}";
8+
69
function parseConsoleArgs(args) {
710
const retData = Array.from(args).map(arg => {
811
try {

web/pgadmin/static/js/Theme/index.jsx

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -882,12 +882,34 @@ function getFinalTheme(baseTheme) {
882882
}, baseTheme);
883883
}
884884

885+
/* Get the actual system theme is user selected system theme in preferences */
886+
function parseSystemTheme(selectedTheme) {
887+
if (selectedTheme === 'system') {
888+
const systemMatchMedia = matchMedia('(prefers-color-scheme: dark)');
889+
return {
890+
'theme': systemMatchMedia.matches ? 'dark' : 'light',
891+
'systemMatchMedia': systemMatchMedia,
892+
};
893+
}
894+
return {
895+
'theme': selectedTheme,
896+
'systemMatchMedia': null,
897+
};
898+
}
899+
885900
/* Theme wrapper used by DOM containers to apply theme */
886901
/* In future, this will be moved to App container */
887902
export default function Theme({children}) {
888903
const prefStore = usePreferences();
889-
const [theme, setTheme] = useState();
904+
const selectedTheme =
905+
prefStore?.getPreferencesForModule('misc')?.theme ||
906+
window.theme ||
907+
'light';
908+
909+
// Initialize theme state
910+
const [theme, setTheme] = useState(parseSystemTheme(selectedTheme).theme);
890911

912+
// Memoize the theme object
891913
const themeObj = useMemo(()=>{
892914
let baseTheme = getLightTheme(basicSettings);
893915
switch(theme) {
@@ -901,31 +923,26 @@ export default function Theme({children}) {
901923
return getFinalTheme(baseTheme);
902924
}, [theme]);
903925

926+
// Handle theme updates
904927
useEffect(() => {
905-
const selectedTheme = prefStore.getPreferencesForModule('misc').theme;
906-
if(theme && theme === selectedTheme) {
907-
return;
908-
}else{
909-
if (selectedTheme !== 'system') {
910-
setTheme(selectedTheme);
911-
return;
912-
}
913-
const isSystemInDarkMode = matchMedia('(prefers-color-scheme: dark)');
914-
setTheme(isSystemInDarkMode.matches ? 'dark' : 'light');
915-
const listener = (event) => {
916-
setTheme(event.matches ? 'dark' : 'light');
917-
};
918-
isSystemInDarkMode.addEventListener('change',listener);
919-
return () => {
920-
isSystemInDarkMode.removeEventListener('change',listener);
921-
};
922-
}
923-
},[prefStore]);
928+
let {theme, systemMatchMedia} = parseSystemTheme(selectedTheme);
929+
setTheme(theme);
930+
931+
const updateTheme = (event) => {
932+
const newTheme = event.matches ? 'dark' : 'light';
933+
setTheme(newTheme);
934+
};
935+
systemMatchMedia?.addEventListener('change', updateTheme);
936+
937+
return () => {
938+
systemMatchMedia?.removeEventListener('change', updateTheme);
939+
};
940+
},[selectedTheme]);
924941

925942
return (
926943
<ThemeProvider theme={themeObj}>
927944
<CssBaseline />
928-
<LocalizationProvider dateAdapter={AdapterDateFns} >
945+
<LocalizationProvider dateAdapter={AdapterDateFns}>
929946
{children}
930947
</LocalizationProvider>
931948
</ThemeProvider>

0 commit comments

Comments
 (0)