Apply dark theme immediately

Themes are now controlled with a class on the body element.

If a preference is set the body element will have either "dark-theme"
or "light-theme" class. If no preference is set or the preference is
empty the class will be "no-theme".

"dark-theme" and "light-theme" are handled by darktheme.css and
lighttheme.css respectively.

"no-theme" is handled by default.css where depending on the value of
"prefers-color-scheme" the styles corresponding to "dark-theme" or
"light-theme" are applied.

Unfortunately this means that both themes are duplicated, once in the
theme .css and once in default.css.
This commit is contained in:
saltycrys 2020-11-16 04:19:41 +01:00
parent aeed7deb2d
commit de777907f2
5 changed files with 108 additions and 25 deletions

View file

@ -1,37 +1,43 @@
a:hover, /*
a:active { * Dark theme
* Same as (prefers-color-scheme: dark) in default.css
*/
.dark-theme a:hover,
.dark-theme a:active {
color: rgb(0, 182, 240); color: rgb(0, 182, 240);
} }
a { .dark-theme a {
color: #a0a0a0; color: #a0a0a0;
text-decoration: none; text-decoration: none;
} }
body { body.dark-theme {
background-color: rgba(35, 35, 35, 1); background-color: rgba(35, 35, 35, 1);
color: #f0f0f0; color: #f0f0f0;
} }
.pure-form legend { .dark-theme .pure-form legend {
color: #f0f0f0; color: #f0f0f0;
} }
.pure-menu-heading { .dark-theme .pure-menu-heading {
color: #f0f0f0; color: #f0f0f0;
} }
input, .dark-theme input,
select, .dark-theme select,
textarea { .dark-theme textarea {
color: rgba(35, 35, 35, 1); color: rgba(35, 35, 35, 1);
} }
.pure-form input[type="file"] { .dark-theme .pure-form input[type="file"] {
color: #f0f0f0; color: #f0f0f0;
} }
.navbar > .searchbar input { .dark-theme .navbar > .searchbar input {
background-color: inherit; background-color: inherit;
color: inherit; color: inherit;
} }

View file

@ -485,3 +485,68 @@ video.video-js {
margin-top: -0.81666em; margin-top: -0.81666em;
margin-left: -1.5em; margin-left: -1.5em;
} }
/*
* Automatic theme support
* Same as lighttheme.css and darktheme.css
*/
@media (prefers-color-scheme: light) {
.no-theme a:hover,
.no-theme a:active {
color: #167ac6 !important;
}
.no-theme a {
color: #61809b;
text-decoration: none;
}
/* All links that do not fit with the default color goes here */
.no-theme a:not([data-id]) > .icon,
.no-theme .pure-u-lg-1-5 > .h-box > a[href^="/watch?"],
.no-theme .playlist-restricted > ol > li > a {
color: #303030;
}
}
@media (prefers-color-scheme: dark) {
.no-theme a:hover,
.no-theme a:active {
color: rgb(0, 182, 240);
}
.no-theme a {
color: #a0a0a0;
text-decoration: none;
}
body.no-theme {
background-color: rgba(35, 35, 35, 1);
color: #f0f0f0;
}
.no-theme .pure-form legend {
color: #f0f0f0;
}
.no-theme .pure-menu-heading {
color: #f0f0f0;
}
.no-theme input,
.no-theme select,
.no-theme textarea {
color: rgba(35, 35, 35, 1);
}
.no-theme .pure-form input[type="file"] {
color: #f0f0f0;
}
.no-theme .navbar > .searchbar input {
background-color: inherit;
color: inherit;
}
}

View file

@ -1,16 +1,22 @@
a:hover, /*
a:active { * Light theme
* Same as (prefers-color-scheme: light) in default.css
*/
.light-theme a:hover,
.light-theme a:active {
color: #167ac6 !important; color: #167ac6 !important;
} }
a { .light-theme a {
color: #61809b; color: #61809b;
text-decoration: none; text-decoration: none;
} }
/* All links that do not fit with the default color goes here */ /* All links that do not fit with the default color goes here */
a:not([data-id]) > .icon, .light-theme a:not([data-id]) > .icon,
.pure-u-lg-1-5 > .h-box > a[href^="/watch?"], .light-theme .pure-u-lg-1-5 > .h-box > a[href^="/watch?"],
.playlist-restricted > ol > li > a { .light-theme .playlist-restricted > ol > li > a {
color: #303030; color: #303030;
} }

View file

@ -2,7 +2,7 @@ var toggle_theme = document.getElementById('toggle_theme');
toggle_theme.href = 'javascript:void(0);'; toggle_theme.href = 'javascript:void(0);';
toggle_theme.addEventListener('click', function () { toggle_theme.addEventListener('click', function () {
var dark_mode = document.getElementById('dark_theme').media === 'none'; var dark_mode = document.body.classList.contains("light-theme");
var url = '/toggle_theme?redirect=false'; var url = '/toggle_theme?redirect=false';
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
@ -22,7 +22,7 @@ window.addEventListener('storage', function (e) {
} }
}); });
window.addEventListener('load', function () { window.addEventListener('DOMContentLoaded', function () {
window.localStorage.setItem('dark_mode', document.getElementById('dark_mode_pref').textContent); window.localStorage.setItem('dark_mode', document.getElementById('dark_mode_pref').textContent);
// Update localStorage if dark mode preference changed on preferences page // Update localStorage if dark mode preference changed on preferences page
update_mode(window.localStorage.dark_mode); update_mode(window.localStorage.dark_mode);
@ -50,13 +50,18 @@ function scheme_switch (e) {
} }
function set_mode (bool) { function set_mode (bool) {
document.getElementById('dark_theme').media = !bool ? 'none' : '';
document.getElementById('light_theme').media = bool ? 'none' : '';
if (bool) { if (bool) {
// dark
toggle_theme.children[0].setAttribute('class', 'icon ion-ios-sunny'); toggle_theme.children[0].setAttribute('class', 'icon ion-ios-sunny');
document.body.classList.remove('no-theme');
document.body.classList.remove('light-theme');
document.body.classList.add('dark-theme');
} else { } else {
// light
toggle_theme.children[0].setAttribute('class', 'icon ion-ios-moon'); toggle_theme.children[0].setAttribute('class', 'icon ion-ios-moon');
document.body.classList.remove('no-theme');
document.body.classList.remove('dark-theme');
document.body.classList.add('light-theme');
} }
} }

View file

@ -18,13 +18,14 @@
<link rel="stylesheet" href="/css/grids-responsive-min.css?v=<%= ASSET_COMMIT %>"> <link rel="stylesheet" href="/css/grids-responsive-min.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/ionicons.min.css?v=<%= ASSET_COMMIT %>"> <link rel="stylesheet" href="/css/ionicons.min.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/default.css?v=<%= ASSET_COMMIT %>"> <link rel="stylesheet" href="/css/default.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/darktheme.css?v=<%= ASSET_COMMIT %>" id="dark_theme" <% if env.get("preferences").as(Preferences).dark_mode != "dark" %>media="none"<% end %>> <link rel="stylesheet" href="/css/darktheme.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/lighttheme.css?v=<%= ASSET_COMMIT %>" id="light_theme" <% if env.get("preferences").as(Preferences).dark_mode == "dark" %>media="none"<% end %>> <link rel="stylesheet" href="/css/lighttheme.css?v=<%= ASSET_COMMIT %>">
</head> </head>
<% locale = LOCALES[env.get("preferences").as(Preferences).locale]? %> <% locale = LOCALES[env.get("preferences").as(Preferences).locale]? %>
<% dark_mode = env.get("preferences").as(Preferences).dark_mode %>
<body> <body class="<%= dark_mode.blank? ? "no" : dark_mode %>-theme">
<span style="display:none" id="dark_mode_pref"><%= env.get("preferences").as(Preferences).dark_mode %></span> <span style="display:none" id="dark_mode_pref"><%= env.get("preferences").as(Preferences).dark_mode %></span>
<div class="pure-g"> <div class="pure-g">
<div class="pure-u-1 pure-u-md-2-24"></div> <div class="pure-u-1 pure-u-md-2-24"></div>