Search code examples
javathemesvaadin14

Persist dark theme setting and apply in vaadin 14


Hello I want to apply the dark theme at the login of the user in Vaadin 14. But it does not work when i call the toggle function programmatically. I was following this example:

https://vaadin.com/learn/tutorials/toggle-dark-theme

The setting is already persisted, but how can i apply the theme setting? It works only when the trigger comes from a request thread. Here is my code:

/**
 * Changes the theme from dark to light and vice versa
 */
private static void toogleTheme() {
    boolean darkThemeEnabled = ConfigManager.isLightThemeEnabled();
    ThemeList themeList = UI.getCurrent().getElement().getThemeList(); //
    if (themeList.contains(Lumo.DARK)) { //
        themeList.remove(Lumo.DARK);
        themeList.add(Lumo.LIGHT);
    } else {
        themeList.remove(Lumo.LIGHT);
        themeList.add(Lumo.DARK);
    }
    ConfigManager.setLightThemeEnabled(!darkThemeEnabled);
}

The method gets called from the change theme button.


Solution

  • You can read the value in the onAttach method. Here is a full example class which uses a cookie for storage:

    public class HelloWorldView extends HorizontalLayout {
        
        private static final String LIGHTMODE = "lightmode";
    
        private Button toggleTheme;
        
        public HelloWorldView() {
            setMargin(true);
            toggleTheme = new Button("Toggle theme between light and dark");
            add(toggleTheme);
            toggleTheme.addClickListener(e -> {
                toggleTheme();
            });
        }
    
        private void setThemeFromCookie() {
            ThemeList themeList = UI.getCurrent().getElement().getThemeList();
            if (isLightThemeOn()) {
                if (themeList.contains(Lumo.DARK)) {
                    themeList.remove(Lumo.DARK);
                }
                themeList.add(Lumo.LIGHT);
            } else {
                if (themeList.contains(Lumo.LIGHT)) {
                    themeList.remove(Lumo.LIGHT);
                }
                themeList.add(Lumo.DARK);
            }
        }
    
        private void toggleTheme() {
            boolean saveLightTheme = true;
            ThemeList themeList = UI.getCurrent().getElement().getThemeList();
            if (themeList.contains(Lumo.DARK)) {
                themeList.remove(Lumo.DARK);
                themeList.add(Lumo.LIGHT);
            } else {
                themeList.remove(Lumo.LIGHT);
                themeList.add(Lumo.DARK);
                saveLightTheme = false;
            }
            setLightThemeInCookie(saveLightTheme);
        }
    
    
        private void setLightThemeInCookie(boolean b) {
            Cookie myCookie = new Cookie(LIGHTMODE, b ? "true" : "false");
            // Make cookie expire in 2 minutes
            myCookie.setMaxAge(120);
            myCookie.setPath(VaadinService.getCurrentRequest().getContextPath());
            VaadinService.getCurrentResponse().addCookie(myCookie);
        }
    
        private String getLightModeCookieValue() {
            for (Cookie c : VaadinService.getCurrentRequest().getCookies()) {
                if ("lightmode".equals(c.getName())) {
                    String value = c.getValue();
                    return value;
                }
            }
            return null;
        }
    
        private boolean isLightThemeOn() {
            String value = getLightModeCookieValue();
            if (value == null) {
                setLightThemeInCookie(true);
                return true;
            }
            return "true".equals(value);
        }
    
        @Override
        protected void onAttach(AttachEvent attachEvent) {
            setThemeFromCookie();
            super.onAttach(attachEvent);
        }
    }