feat(theme): default to light and make following the device opt in
6 files changed, +12 −7
- README.md modified +1 −1
- forge/admin.go modified +1 −1
- forge/flow_test.go modified +5 −0
- forge/highlight.go modified +1 −1
- web/static/style.css modified +1 −1
- web/templates/appearance.tmpl modified +3 −3
README.md modified
| @@ -23,7 +23,7 @@ The web interface is then on `127.0.0.1:3200` and wants a reverse proxy with TLS | ||
| 23 | 23 | - Profiles with a pinned repository list, an activity graph and a README from your `~you/you` repository |
| 24 | 24 | - SSH and PGP commit verification, TOTP, access tokens and Atom feeds for commits, issues and pull requests |
| 25 | 25 | - Site search over repositories and people with language facets |
| 26 | -- Light and dark themes that follow the device or a choice saved under settings | |
| 26 | +- Light and dark themes, light by default, with an option to follow the device | |
| 27 | 27 | - A notification bell for activity on pull requests and issues you take part in |
| 28 | 28 | - Open, invite only or closed registration and an `/admin` page for accounts, invites, the front page and storage |
| 29 | 29 | |
forge/admin.go modified
| @@ -77,7 +77,7 @@ func (s *Store) IsAdmin(id int64) bool { | ||
| 77 | 77 | return admin |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | -var themes = []string{"", "light", "dark"} | |
| 80 | +var themes = []string{"", "light", "dark", "system"} | |
| 81 | 81 | |
| 82 | 82 | func (s *Store) Viewer(id int64) (admin bool, theme string, unread int) { |
| 83 | 83 | s.db.QueryRow(`select admin and not banned, theme, (select count(*) from notifications where user = ?1 and unread = 1) from users where id = ?1`, id).Scan(&admin, &theme, &unread) |
forge/flow_test.go modified
| @@ -385,6 +385,11 @@ func TestAppearance(t *testing.T) { | ||
| 385 | 385 | if !strings.Contains(get(h, "/", c).Body.String(), `data-theme="dark"`) { |
| 386 | 386 | t.Error("dark theme not applied") |
| 387 | 387 | } |
| 388 | + post(h, "/settings/appearance", url.Values{"theme": {"system"}}, c) | |
| 389 | + if !strings.Contains(get(h, "/", c).Body.String(), `data-theme="system"`) { | |
| 390 | + t.Error("system theme not applied") | |
| 391 | + } | |
| 392 | + post(h, "/settings/appearance", url.Values{"theme": {"dark"}}, c) | |
| 388 | 393 | post(h, "/settings/appearance", url.Values{"theme": {`x" onload="`}}, c) |
| 389 | 394 | if !strings.Contains(get(h, "/", c).Body.String(), `data-theme="dark"`) { |
| 390 | 395 | t.Error("unknown theme replaced the saved one") |
forge/highlight.go modified
| @@ -70,6 +70,6 @@ func highlightCSS() []byte { | ||
| 70 | 70 | } |
| 71 | 71 | rules = append(rules, strings.TrimSpace(rule)) |
| 72 | 72 | } |
| 73 | - fmt.Fprintf(&buf, "%s\n@media (prefers-color-scheme:dark){\n%s}\n", scoped(rules, ":root[data-theme=dark] "), scoped(rules, ":root:not([data-theme=light]) ")) | |
| 73 | + fmt.Fprintf(&buf, "%s\n@media (prefers-color-scheme:dark){\n%s}\n", scoped(rules, ":root[data-theme=dark] "), scoped(rules, ":root[data-theme=system] ")) | |
| 74 | 74 | return buf.Bytes() |
| 75 | 75 | } |
web/static/style.css modified
| @@ -477,7 +477,7 @@ nav.site .me form{margin:0} | ||
| 477 | 477 | label.radio input{width:auto;margin:0} |
| 478 | 478 | :root[data-theme=dark]{--accent:#5b5fa8;--accentdark:#4a4d91;--accentsoft:#2c2e48;--focus:#4a4d91;--link:#a3a7ee;--heat0:#2f3034;--heat1:#2f3262;--heat2:#454991;--heat3:#666bc4;--heat4:#9ca0f0;--fg:#f4f4f4;--muted:#a8a8a8;--line:#3e3f45;--soft:#28292d;--bar:#303136;--add:#42be65;--del:#fa4d56;--addbg:#0e2a17;--delbg:#3a1518;--code:#28292d;--bg:#212225;--raised:#2e2f34;--raisedhover:#393a40;--edge:#57585f;--hl:#3d3412;--warnbg:#2d2510;--warnedge:#5c4b10;--warnfg:#f1c21b;--merged:#a56eff;--dotedge:rgba(255,255,255,.15);--tip:#f4f4f4;--tipfg:#212225;--fg2:#c2c4c9;color-scheme:dark} |
| 479 | 479 | :root[data-theme=dark] nav.site .brand img{filter:brightness(2.2) saturate(.9)} |
| 480 | -@media (prefers-color-scheme:dark){:root:not([data-theme=light]){--accent:#5b5fa8;--accentdark:#4a4d91;--accentsoft:#2c2e48;--focus:#4a4d91;--link:#a3a7ee;--heat0:#2f3034;--heat1:#2f3262;--heat2:#454991;--heat3:#666bc4;--heat4:#9ca0f0;--fg:#f4f4f4;--muted:#a8a8a8;--line:#3e3f45;--soft:#28292d;--bar:#303136;--add:#42be65;--del:#fa4d56;--addbg:#0e2a17;--delbg:#3a1518;--code:#28292d;--bg:#212225;--raised:#2e2f34;--raisedhover:#393a40;--edge:#57585f;--hl:#3d3412;--warnbg:#2d2510;--warnedge:#5c4b10;--warnfg:#f1c21b;--merged:#a56eff;--dotedge:rgba(255,255,255,.15);--tip:#f4f4f4;--tipfg:#212225;--fg2:#c2c4c9;color-scheme:dark}:root:not([data-theme=light]) nav.site .brand img{filter:brightness(2.2) saturate(.9)}} | |
| 480 | +@media (prefers-color-scheme:dark){:root[data-theme=system]{--accent:#5b5fa8;--accentdark:#4a4d91;--accentsoft:#2c2e48;--focus:#4a4d91;--link:#a3a7ee;--heat0:#2f3034;--heat1:#2f3262;--heat2:#454991;--heat3:#666bc4;--heat4:#9ca0f0;--fg:#f4f4f4;--muted:#a8a8a8;--line:#3e3f45;--soft:#28292d;--bar:#303136;--add:#42be65;--del:#fa4d56;--addbg:#0e2a17;--delbg:#3a1518;--code:#28292d;--bg:#212225;--raised:#2e2f34;--raisedhover:#393a40;--edge:#57585f;--hl:#3d3412;--warnbg:#2d2510;--warnedge:#5c4b10;--warnfg:#f1c21b;--merged:#a56eff;--dotedge:rgba(255,255,255,.15);--tip:#f4f4f4;--tipfg:#212225;--fg2:#c2c4c9;color-scheme:dark}:root[data-theme=system] nav.site .brand img{filter:brightness(2.2) saturate(.9)}} | |
| 481 | 481 | .mdbar{display:flex;gap:.2rem;margin:.2rem 0 .3rem;font-size:.85rem} |
| 482 | 482 | .mdbar button{font:inherit;background:none;border:1px solid transparent;color:var(--muted);padding:.1rem .55rem;cursor:pointer} |
| 483 | 483 | .mdbar button:hover{color:var(--fg)} |
web/templates/appearance.tmpl modified
| @@ -2,11 +2,11 @@ | ||
| 2 | 2 | <div class="panel"><h3>Theme</h3> |
| 3 | 3 | <form method="post" action="/settings/appearance" class="stack"> |
| 4 | 4 | <label>Theme <select name="theme"> |
| 5 | -<option value=""{{if eq .Theme ""}} selected{{end}}>System</option> | |
| 6 | -<option value="light"{{if eq .Theme "light"}} selected{{end}}>Light</option> | |
| 5 | +<option value="light"{{if or (eq .Theme "") (eq .Theme "light")}} selected{{end}}>Light</option> | |
| 7 | 6 | <option value="dark"{{if eq .Theme "dark"}} selected{{end}}>Dark</option> |
| 7 | +<option value="system"{{if eq .Theme "system"}} selected{{end}}>System</option> | |
| 8 | 8 | </select></label> |
| 9 | -<small>System follows the light or dark setting of your device.</small> | |
| 9 | +<small>Light is the default. System follows the light or dark setting of your device.</small> | |
| 10 | 10 | <div class="actions left"><button class="btn primary">Save ▸</button></div> |
| 11 | 11 | </form></div> |
| 12 | 12 | {{end}} |