Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions web/pgadmin/browser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand All @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions web/pgadmin/browser/templates/browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
59 changes: 38 additions & 21 deletions web/pgadmin/static/js/Theme/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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 (
<ThemeProvider theme={themeObj}>
<CssBaseline />
<LocalizationProvider dateAdapter={AdapterDateFns} >
<LocalizationProvider dateAdapter={AdapterDateFns}>
{children}
</LocalizationProvider>
</ThemeProvider>
Expand Down