Skip to content

Commit

Permalink
UiSession: fix theme initialization
Browse files Browse the repository at this point in the history
- URL param (?theme=xyz) always takes precedence over the current theme
- Otherwise, if the model already has a theme set, use that one.
- Otherwise, use the "current theme" from the request (session
  attribute, cookie or default value).

A warning is only logged when the requested theme or the model theme is
set but is not valid according to UiThemeHelper. When the model does not
specify a theme, a default theme is assigned automatically without log
message.

When the theme is determined, it is written back to the model, so the
logo URL and potentially other things can be adjusted.

In Scout JS, we have no UiSession or ClientSession. For a similar
functionality, the URL param is manually compared with the current
theme (called "active theme").

270127
  • Loading branch information
bschwarzent committed May 8, 2024
1 parent 1a09d0b commit 22a8c00
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 15 deletions.
2 changes: 1 addition & 1 deletion eclipse-scout-core/src/desktop/Desktop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1680,7 +1680,7 @@ export class Desktop extends Widget implements DesktopModel, DisplayParent {

protected _initTheme() {
let theme = this.theme;
if (this.url.hasParameter('theme')) {
if (!this.modelAdapter && this.url.hasParameter('theme')) { // only needed for Scout JS (in Scout classic, the theme URL parameter is handled in UiSession#initUiTheme)
theme = strings.nullIfEmpty(this.url.getParameter('theme') as string) || Desktop.DEFAULT_THEME;
} else if (theme === null) {
theme = this._activeTheme();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,18 @@ protected void updatePreferredLocaleCookie(Locale locale) {
}
}

protected boolean initUiTheme(HttpServletRequest req, HttpServletResponse resp, Map<String, String> sessionStartupParams) {
// Run in a model job, because the computed theme is written to the model ("theme" property on the desktop)
IFuture<Boolean> future = ModelJobs.schedule(
() -> initUiThemeInternal(req, resp, sessionStartupParams),
ModelJobs.newInput(
ClientRunContexts.copyCurrent()
.withSession(m_clientSession, true))
.withName("Initializing UI theme")
.withExceptionHandling(null, false /* propagate */)); // exception handling done by caller
return BEANS.get(UiJobs.class).awaitAndGet(future);
}

/**
* Info: instead of reload the current page in the browser, we could build a servlet-filter which determines what
* theme the user has _before_ the client-session is created. However, the 'reload' will only be performed in the case
Expand All @@ -412,32 +424,39 @@ protected void updatePreferredLocaleCookie(Locale locale) {
* @return Whether the page must be reloaded by the browser (required when theme changes after client-session has been
* initialized)
*/
protected boolean initUiTheme(HttpServletRequest req, HttpServletResponse resp, Map<String, String> sessionStartupParams) {
protected boolean initUiThemeInternal(HttpServletRequest req, HttpServletResponse resp, Map<String, String> sessionStartupParams) {
ModelJobs.assertModelThread(); // because we change the model ("theme" property on the desktop)
UiThemeHelper helper = UiThemeHelper.get();

String modelTheme = m_clientSession.getDesktop().getTheme();
String currentTheme = helper.getTheme(req);

// Ensure the model theme is valid, otherwise it could result in an endless reload loop
String validTheme = UiThemeHelper.get().validateTheme(modelTheme);
if (!ObjectUtility.equals(validTheme, modelTheme)) {
LOG.info("Model theme ({}) is not valid, switching to a valid one ({})", modelTheme, validTheme);
modelTheme = validTheme;
}

// If a theme is requested via URL this has priority before the theme from the session or the model
// If a theme is requested via URL, that has priority over the theme from the session or the model
String requestedTheme = sessionStartupParams.get(URL_PARAM_THEME);
if (requestedTheme != null) {
modelTheme = helper.validateTheme(requestedTheme);
modelTheme = requestedTheme;
}

if (modelTheme == null) {
modelTheme = ObjectUtility.nvl(currentTheme, helper.getConfiguredTheme());
m_clientSession.getDesktop().setTheme(currentTheme);
// "currentTheme" is valid by definition (see JavaDoc of UiThemeHelper#getTheme)
modelTheme = currentTheme;
}
else {
// Ensure the model theme is valid, otherwise it could result in an endless reload loop
String validTheme = helper.validateTheme(modelTheme);
if (!ObjectUtility.equals(validTheme, modelTheme)) {
LOG.warn("Model theme ({}) is not valid, switching to a valid one ({})", modelTheme, validTheme);
modelTheme = validTheme;
}
}

boolean reloadPage = !modelTheme.equals(currentTheme);
// Write the valid theme to the client session, so the desktop logo can be adjusted (but this is not stored in the user settings)
m_clientSession.getDesktop().setTheme(modelTheme);
// Set as current theme for subsequent requests with the same UI session
helper.storeTheme(resp, req.getSession(), modelTheme);
LOG.debug("UI theme model={} current={} reloadPage={}", modelTheme, currentTheme, reloadPage);

boolean reloadPage = !modelTheme.equals(currentTheme);
LOG.debug("UI theme requested={} current={} model={} reloadPage={}", requestedTheme, currentTheme, modelTheme, reloadPage);
return reloadPage;
}

Expand Down

0 comments on commit 22a8c00

Please sign in to comment.