Add theme toggle to login screen

This commit is contained in:
2026-09-19 00:04:04 +03:00
parent c8190b7eec
commit 393c333794
5 changed files with 190 additions and 13 deletions
+23 -11
View File
@@ -44,6 +44,12 @@ Install it with the same procedure above, copying `eternity-wasteland` instead o
$config['skin'] = 'eternity-wasteland';
```
### Login Theme Toggle
Wasteland opens in dark mode. Its login screen includes a **Dark mode** toggle that switches to the Eternity light palette without reloading the page. The choice is stored in the browser's `colorMode` cookie for one year and is applied on later visits to the login screen.
Clearing site cookies resets the Wasteland login screen to dark mode. This setting only changes the Wasteland login page; choose the desired Roundcube interface skin in **Settings > Preferences > User Interface > Interface skin** after signing in.
## Docker Install
### Docker Compose (persistent)
@@ -54,7 +60,7 @@ Place this repository alongside the Compose file, then bind-mount the skin into
services:
roundcube:
volumes:
- ./ep-roundcube-skin/eternity:/var/www/html/skins/eternity:ro
- ./ep-roundcube-skin/eternity-wasteland:/var/www/html/skins/eternity-wasteland:ro
- ./roundcube-config/config.inc.php:/var/roundcube/config/config.inc.php:ro
```
@@ -63,7 +69,7 @@ Create `./roundcube-config/config.inc.php` if it does not already exist and incl
```php
<?php
$config['skin'] = 'eternity';
$config['skin'] = 'eternity-wasteland';
```
The configuration mount location can vary for non-official images. Check the image documentation or run `docker compose exec roundcube sh -c 'find / -path "*/config.inc.php" 2>/dev/null'` to identify the active configuration file. Restart the service after changing either mount:
@@ -79,16 +85,16 @@ Use this method to test the skin on a container that is already running. Replace
1. Copy the skin from this repository into the container:
```sh
docker cp ./eternity roundcube:/var/www/html/skins/eternity
docker cp ./eternity-wasteland roundcube:/var/www/html/skins/eternity-wasteland
```
2. Confirm Roundcube can see the skin files:
```sh
docker exec roundcube sh -c 'test -f /var/www/html/skins/eternity/meta.json && test -f /var/www/html/skins/eternity/styles/styles.css'
docker exec roundcube sh -c 'test -f /var/www/html/skins/eternity-wasteland/meta.json && test -f /var/www/html/skins/eternity-wasteland/styles/styles.css'
```
3. Add `$config['skin'] = 'eternity';` to the active `config.inc.php` in the container, then restart it:
3. Add `$config['skin'] = 'eternity-wasteland';` to the active `config.inc.php` in the container, then restart it:
```sh
docker restart roundcube
@@ -96,7 +102,7 @@ Use this method to test the skin on a container that is already running. Replace
This live-container approach is not persistent: `docker compose up --force-recreate`, `docker rm`, or an image update removes the copied skin and in-container configuration change. Once the skin is confirmed, add the two bind mounts from the Compose example so both survive container recreation.
After either deployment method, hard-refresh the browser or clear its cache. If the old appearance remains, inspect the browser network panel to confirm that `/skins/eternity/styles/styles.css` returns HTTP 200.
After either deployment method, hard-refresh the browser or clear its cache. If the old appearance remains, inspect the browser network panel to confirm that `/skins/eternity-wasteland/styles/styles.css` returns HTTP 200.
If instead the page looks entirely unstyled — login credential fields stacked in the wrong place, an oversized logo, or mailbox toolbars/tabs scattered and hard to read — `styles/styles.css` is loading but its `@import` of `../../elastic/styles/styles.css` is not, so none of Elastic's layout rules apply. Confirm that file exists and is readable:
@@ -111,15 +117,15 @@ If it is `MISSING`, the Elastic skin was installed from source without its LESS
Run these commands on the Docker host, replacing `roundcube` with the container name or ID from `docker ps`. They distinguish an installation issue from an activation issue:
```sh
docker exec roundcube sh -c 'for file in /var/www/html/skins/eternity/meta.json /var/www/html/skins/eternity/styles/styles.css /var/www/html/skins/elastic/styles/styles.css; do test -f "$file" && echo "FOUND $file" || echo "MISSING $file"; done'
docker exec roundcube sh -c 'for file in /var/www/html/skins/eternity-wasteland/meta.json /var/www/html/skins/eternity-wasteland/styles/styles.css /var/www/html/skins/elastic/styles/styles.css; do test -f "$file" && echo "FOUND $file" || echo "MISSING $file"; done'
docker exec roundcube sh -c 'grep -RIn "\$config\[.skin.\]" /var/roundcube/config /var/www/html/config 2>/dev/null || true'
```
The first command must report all three paths as `FOUND`. The second must show `eternity` as the configured skin. On the official image, the equivalent persistent environment setting is:
The first command must report all three paths as `FOUND`. The second must show `eternity-wasteland` as the configured skin. On the official image, the equivalent persistent environment setting is:
```yaml
environment:
ROUNDCUBEMAIL_SKIN: eternity
ROUNDCUBEMAIL_SKIN: eternity-wasteland
```
Roundcube can store a skin preference for each user. A user who previously selected another appearance may continue to receive that preference instead of the newly configured default. Sign out and test in a private browser window or select **Eternity** from Roundcube's **Settings > Preferences > User Interface > Interface skin**, when the preference is available.
@@ -127,10 +133,10 @@ Roundcube can store a skin preference for each user. A user who previously selec
For a browser-level check, open this URL directly, replacing the hostname with the Roundcube site:
```text
https://webmail.example.com/skins/eternity/styles/styles.css
https://webmail.example.com/skins/eternity-wasteland/styles/styles.css
```
It must return CSS beginning with `@import url("../../elastic/styles/styles.css");`. A `404` means the skin is not mounted at the path served by the container. If it returns `200` but Roundcube still looks unchanged, inspect the mailbox page source: it must include a stylesheet URL containing `/skins/eternity/styles/styles.css`. If it instead contains `/skins/elastic/`, the active configuration or the user's stored preference still selects Elastic.
It must return CSS beginning with `@import url("../../elastic/styles/styles.css");`. A `404` means the skin is not mounted at the path served by the container. If it returns `200` but Roundcube still looks unchanged, inspect the mailbox page source: it must include a stylesheet URL containing `/skins/eternity-wasteland/styles/styles.css`. If it instead contains `/skins/elastic/`, the active configuration or the user's stored preference still selects Elastic.
## Structure
@@ -138,6 +144,12 @@ It must return CSS beginning with `@import url("../../elastic/styles/styles.css"
eternity/
meta.json Skin registration and Elastic inheritance
styles/styles.css Visual overrides for Elastic
eternity-wasteland/
images/logo.svg High-contrast Wasteland login mark
meta.json Skin registration and Elastic inheritance
styles/styles.css Dark and light Wasteland visual overrides
templates/login.html Login form with the theme toggle
watermark.html Wasteland login background
```
`styles/styles.css` imports Elastic before applying Eternity's overrides. Do not remove the import: the base skin provides the complete component layout and image assets.