summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--assets/js/themes.js37
-rw-r--r--locales/ar.json4
-rw-r--r--locales/de.json4
-rw-r--r--locales/el.json4
-rw-r--r--locales/en-US.json4
-rw-r--r--locales/eo.json4
-rw-r--r--locales/es.json4
-rw-r--r--locales/eu.json4
-rw-r--r--locales/fr.json4
-rw-r--r--locales/is.json4
-rw-r--r--locales/it.json4
-rw-r--r--locales/nb_NO.json4
-rw-r--r--locales/nl.json4
-rw-r--r--locales/pl.json4
-rw-r--r--locales/ru.json4
-rw-r--r--locales/uk.json4
-rw-r--r--locales/zh-CN.json4
-rw-r--r--src/invidious.cr30
-rw-r--r--src/invidious/helpers/helpers.cr74
-rw-r--r--src/invidious/helpers/patch_mapping.cr2
-rw-r--r--src/invidious/helpers/utils.cr13
-rw-r--r--src/invidious/users.cr62
-rw-r--r--src/invidious/views/preferences.ecr8
-rw-r--r--src/invidious/views/template.ecr9
24 files changed, 215 insertions, 84 deletions
diff --git a/assets/js/themes.js b/assets/js/themes.js
index 683aea39..90a05c36 100644
--- a/assets/js/themes.js
+++ b/assets/js/themes.js
@@ -1,8 +1,8 @@
-var toggle_theme = document.getElementById('toggle_theme')
+var toggle_theme = document.getElementById('toggle_theme');
toggle_theme.href = 'javascript:void(0);';
toggle_theme.addEventListener('click', function () {
- var dark_mode = document.getElementById('dark_theme').media == 'none';
+ var dark_mode = document.getElementById('dark_theme').media === 'none';
var url = '/toggle_theme?redirect=false';
var xhr = new XMLHttpRequest();
@@ -11,19 +11,24 @@ toggle_theme.addEventListener('click', function () {
xhr.open('GET', url, true);
set_mode(dark_mode);
- localStorage.setItem('dark_mode', dark_mode);
+ window.localStorage.setItem('dark_mode', dark_mode ? 'dark' : 'light');
xhr.send();
});
window.addEventListener('storage', function (e) {
- if (e.key == 'dark_mode') {
- var dark_mode = e.newValue === 'true';
- set_mode(dark_mode);
+ if (e.key === 'dark_mode') {
+ update_mode(e.newValue);
}
});
-function set_mode(bool) {
+window.addEventListener('load', function () {
+ window.localStorage.setItem('dark_mode', document.getElementById('dark_mode_pref').textContent);
+ // Update localStorage if dark mode preference changed on preferences page
+ update_mode(window.localStorage.dark_mode);
+});
+
+function set_mode (bool) {
document.getElementById('dark_theme').media = !bool ? 'none' : '';
document.getElementById('light_theme').media = bool ? 'none' : '';
@@ -33,3 +38,21 @@ function set_mode(bool) {
toggle_theme.children[0].setAttribute('class', 'icon ion-ios-moon');
}
}
+
+function update_mode (mode) {
+ if (mode === 'true' /* for backwards compatibility */ || mode === 'dark') {
+ // If preference for dark mode indicated
+ set_mode(true);
+ }
+ else if (mode === 'false' /* for backwards compaibility */ || mode === 'light') {
+ // If preference for light mode indicated
+ set_mode(false);
+ }
+ else if (document.getElementById('dark_mode_pref').textContent === '' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
+ // If no preference indicated here and no preference indicated on the preferences page (backend), but the browser tells us that the operating system has a dark theme
+ set_mode(true);
+ }
+ // else do nothing, falling back to the mode defined by the `dark_mode` preference on the preferences page (backend)
+}
+
+
diff --git a/locales/ar.json b/locales/ar.json
index e3716008..f2ed450c 100644
--- a/locales/ar.json
+++ b/locales/ar.json
@@ -68,7 +68,11 @@
"Show related videos: ": "عرض مقاطع الفيديو ذات الصلة؟",
"Show annotations by default: ": "عرض الملاحظات فى الفيديو تلقائيا ؟",
"Visual preferences": "التفضيلات المرئية",
+ "Player style: ": "",
"Dark mode: ": "الوضع الليلى: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "الوضع الخفيف: ",
"Subscription preferences": "تفضيلات الإشتراك",
"Show annotations by default for subscribed channels: ": "عرض الملاحظات فى الفيديوهات تلقائيا فى القنوات المشترك بها فقط ؟",
diff --git a/locales/de.json b/locales/de.json
index 33edb706..e0ef9d67 100644
--- a/locales/de.json
+++ b/locales/de.json
@@ -68,7 +68,11 @@
"Show related videos: ": "Ähnliche Videos anzeigen? ",
"Show annotations by default: ": "Standardmäßig Anmerkungen anzeigen? ",
"Visual preferences": "Anzeigeeinstellungen",
+ "Player style: ": "",
"Dark mode: ": "Nachtmodus: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Schlanker Modus: ",
"Subscription preferences": "Abonnementeinstellungen",
"Show annotations by default for subscribed channels: ": "Anmerkungen für abonnierte Kanäle standardmäßig anzeigen? ",
diff --git a/locales/el.json b/locales/el.json
index 03d25533..32f154a1 100644
--- a/locales/el.json
+++ b/locales/el.json
@@ -74,7 +74,11 @@
"Show related videos: ": "Προβολή σχετικών βίντεο; ",
"Show annotations by default: ": "Αυτόματη προβολή σημειώσεων; :",
"Visual preferences": "Προτιμήσεις εμφάνισης",
+ "Player style: ": "",
"Dark mode: ": "Σκοτεινή λειτουργία: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Ελαφριά λειτουργία: ",
"Subscription preferences": "Προτιμήσεις συνδρομών",
"Show annotations by default for subscribed channels: ": "Προβολή σημειώσεων μόνο για κανάλια στα οποία είστε συνδρομητής; ",
diff --git a/locales/en-US.json b/locales/en-US.json
index 16301b1d..580d9ead 100644
--- a/locales/en-US.json
+++ b/locales/en-US.json
@@ -74,7 +74,11 @@
"Show related videos: ": "Show related videos: ",
"Show annotations by default: ": "Show annotations by default: ",
"Visual preferences": "Visual preferences",
+ "Player style: ": "",
"Dark mode: ": "Dark mode: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Thin mode: ",
"Subscription preferences": "Subscription preferences",
"Show annotations by default for subscribed channels: ": "Show annotations by default for subscribed channels? ",
diff --git a/locales/eo.json b/locales/eo.json
index fe85edf2..2c22af59 100644
--- a/locales/eo.json
+++ b/locales/eo.json
@@ -68,7 +68,11 @@
"Show related videos: ": "Ĉu montri rilatajn videojn? ",
"Show annotations by default: ": "Ĉu montri prinotojn defaŭlte? ",
"Visual preferences": "Vidaj preferoj",
+ "Player style: ": "",
"Dark mode: ": "Malhela reĝimo: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Maldika reĝimo: ",
"Subscription preferences": "Abonaj agordoj",
"Show annotations by default for subscribed channels: ": "Ĉu montri prinotojn defaŭlte por abonitaj kanaloj? ",
diff --git a/locales/es.json b/locales/es.json
index fdbf2fb2..5860b882 100644
--- a/locales/es.json
+++ b/locales/es.json
@@ -68,7 +68,11 @@
"Show related videos: ": "¿Mostrar vídeos relacionados? ",
"Show annotations by default: ": "¿Mostrar anotaciones por defecto? ",
"Visual preferences": "Preferencias visuales",
+ "Player style: ": "",
"Dark mode: ": "Modo oscuro: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Modo compacto: ",
"Subscription preferences": "Preferencias de la suscripción",
"Show annotations by default for subscribed channels: ": "¿Mostrar anotaciones por defecto para los canales suscritos? ",
diff --git a/locales/eu.json b/locales/eu.json
index 5a756154..cbdbbefc 100644
--- a/locales/eu.json
+++ b/locales/eu.json
@@ -68,7 +68,11 @@
"Show related videos: ": "",
"Show annotations by default: ": "",
"Visual preferences": "",
+ "Player style: ": "",
"Dark mode: ": "",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "",
"Subscription preferences": "",
"Show annotations by default for subscribed channels: ": "",
diff --git a/locales/fr.json b/locales/fr.json
index 37a773f1..af561a0c 100644
--- a/locales/fr.json
+++ b/locales/fr.json
@@ -68,7 +68,11 @@
"Show related videos: ": "Voir les vidéos liées : ",
"Show annotations by default: ": "Voir les annotations par défaut : ",
"Visual preferences": "Préférences du site",
+ "Player style: ": "",
"Dark mode: ": "Mode Sombre : ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Mode Simplifié : ",
"Subscription preferences": "Préférences de la page d'abonnements",
"Show annotations by default for subscribed channels: ": "Voir les annotations par défaut sur les chaînes suivies : ",
diff --git a/locales/is.json b/locales/is.json
index 43ba26e9..808063c4 100644
--- a/locales/is.json
+++ b/locales/is.json
@@ -68,7 +68,11 @@
"Show related videos: ": "Sýna tengd myndbönd? ",
"Show annotations by default: ": "Á að sýna glósur sjálfgefið? ",
"Visual preferences": "Sjónrænar stillingar",
+ "Player style: ": "",
"Dark mode: ": "Myrkur ham: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Þunnt ham: ",
"Subscription preferences": "Áskriftarstillingar",
"Show annotations by default for subscribed channels: ": "Á að sýna glósur sjálfgefið fyrir áskriftarrásir? ",
diff --git a/locales/it.json b/locales/it.json
index bf028c91..7f532d0d 100644
--- a/locales/it.json
+++ b/locales/it.json
@@ -68,7 +68,11 @@
"Show related videos: ": "Mostra video correlati? ",
"Show annotations by default: ": "Mostra le annotazioni per impostazione predefinita? ",
"Visual preferences": "Preferenze grafiche",
+ "Player style: ": "",
"Dark mode: ": "Tema scuro: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Modalità per connessioni lente: ",
"Subscription preferences": "Preferenze iscrizioni",
"Show annotations by default for subscribed channels: ": "",
diff --git a/locales/nb_NO.json b/locales/nb_NO.json
index 589512d4..f50e2290 100644
--- a/locales/nb_NO.json
+++ b/locales/nb_NO.json
@@ -68,7 +68,11 @@
"Show related videos: ": "Vis relaterte videoer? ",
"Show annotations by default: ": "Vis merknader som forvalg? ",
"Visual preferences": "Visuelle innstillinger",
+ "Player style: ": "",
"Dark mode: ": "Mørk drakt: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Tynt modus: ",
"Subscription preferences": "Abonnementsinnstillinger",
"Show annotations by default for subscribed channels: ": "Vis merknader som forvalg for kanaler det abonneres på? ",
diff --git a/locales/nl.json b/locales/nl.json
index b24b13b8..3e2c6c64 100644
--- a/locales/nl.json
+++ b/locales/nl.json
@@ -68,7 +68,11 @@
"Show related videos: ": "Gerelateerde video's tonen? ",
"Show annotations by default: ": "Standaard annotaties tonen? ",
"Visual preferences": "Visuele instellingen",
+ "Player style: ": "",
"Dark mode: ": "Donkere modus: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Smalle modus: ",
"Subscription preferences": "Abonnementsinstellingen",
"Show annotations by default for subscribed channels: ": "Standaard annotaties tonen voor geabonneerde kanalen? ",
diff --git a/locales/pl.json b/locales/pl.json
index 550e664b..1e3a2068 100644
--- a/locales/pl.json
+++ b/locales/pl.json
@@ -68,7 +68,11 @@
"Show related videos: ": "Pokaż powiązane filmy? ",
"Show annotations by default: ": "",
"Visual preferences": "Preferencje Wizualne",
+ "Player style: ": "",
"Dark mode: ": "Ciemny motyw: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Tryb minimalny: ",
"Subscription preferences": "Preferencje subskrybcji",
"Show annotations by default for subscribed channels: ": "",
diff --git a/locales/ru.json b/locales/ru.json
index f9cc1e2d..90aa4a3b 100644
--- a/locales/ru.json
+++ b/locales/ru.json
@@ -68,7 +68,11 @@
"Show related videos: ": "Показывать похожие видео? ",
"Show annotations by default: ": "Всегда показывать аннотации? ",
"Visual preferences": "Настройки сайта",
+ "Player style: ": "",
"Dark mode: ": "Тёмное оформление: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Облегчённое оформление: ",
"Subscription preferences": "Настройки подписок",
"Show annotations by default for subscribed channels: ": "Всегда показывать аннотации в видео каналов, на которые вы подписаны? ",
diff --git a/locales/uk.json b/locales/uk.json
index 95e5798d..e537008c 100644
--- a/locales/uk.json
+++ b/locales/uk.json
@@ -68,7 +68,11 @@
"Show related videos: ": "Показувати схожі відео? ",
"Show annotations by default: ": "Завжди показувати анотації? ",
"Visual preferences": "Налаштування сайту",
+ "Player style: ": "",
"Dark mode: ": "Темне оформлення: ",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "Полегшене оформлення: ",
"Subscription preferences": "Налаштування підписок",
"Show annotations by default for subscribed channels: ": "Завжди показувати анотації у відео каналів, на які ви підписані? ",
diff --git a/locales/zh-CN.json b/locales/zh-CN.json
index 0a3f53d9..23617d04 100644
--- a/locales/zh-CN.json
+++ b/locales/zh-CN.json
@@ -68,7 +68,11 @@
"Show related videos: ": "显示相关视频?",
"Show annotations by default: ": "默认显示视频注释?",
"Visual preferences": "视觉选项",
+ "Player style: ": "",
"Dark mode: ": "暗色模式:",
+ "Theme: ": "",
+ "dark": "",
+ "light": "",
"Thin mode: ": "窄页模式:",
"Subscription preferences": "订阅设置",
"Show annotations by default for subscribed channels: ": "在订阅频道的视频默认显示注释?",
diff --git a/src/invidious.cr b/src/invidious.cr
index 16695c5f..712a408f 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -267,8 +267,7 @@ before_all do |env|
end
end
- dark_mode = env.params.query["dark_mode"]? || preferences.dark_mode.to_s
- dark_mode = dark_mode == "true"
+ dark_mode = convert_theme(env.params.query["dark_mode"]?) || preferences.dark_mode.to_s
thin_mode = env.params.query["thin_mode"]? || preferences.thin_mode.to_s
thin_mode = thin_mode == "true"
@@ -1528,8 +1527,7 @@ post "/preferences" do |env|
locale ||= CONFIG.default_user_preferences.locale
dark_mode = env.params.body["dark_mode"]?.try &.as(String)
- dark_mode ||= "off"
- dark_mode = dark_mode == "on"
+ dark_mode ||= CONFIG.default_user_preferences.dark_mode
thin_mode = env.params.body["thin_mode"]?.try &.as(String)
thin_mode ||= "off"
@@ -1553,6 +1551,7 @@ post "/preferences" do |env|
notifications_only ||= "off"
notifications_only = notifications_only == "on"
+ # Convert to JSON and back again to take advantage of converters used for compatability
preferences = Preferences.from_json({
annotations: annotations,
annotations_subscribed: annotations_subscribed,
@@ -1648,12 +1647,27 @@ get "/toggle_theme" do |env|
if user = env.get? "user"
user = user.as(User)
preferences = user.preferences
- preferences.dark_mode = !preferences.dark_mode
- PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", preferences.to_json, user.email)
+ case preferences.dark_mode
+ when "dark"
+ preferences.dark_mode = "light"
+ else
+ preferences.dark_mode = "dark"
+ end
+
+ preferences = preferences.to_json
+
+ PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", preferences, user.email)
else
preferences = env.get("preferences").as(Preferences)
- preferences.dark_mode = !preferences.dark_mode
+
+ case preferences.dark_mode
+ when "dark"
+ preferences.dark_mode = "light"
+ else
+ preferences.dark_mode = "dark"
+ end
+
preferences = preferences.to_json
if Kemal.config.ssl || config.https_only
@@ -2026,7 +2040,7 @@ post "/data_control" do |env|
env.response.puts %(<meta http-equiv="refresh" content="0; url=#{referer}">)
env.response.puts %(<link rel="stylesheet" href="/css/ionicons.min.css?v=#{ASSET_COMMIT}">)
env.response.puts %(<link rel="stylesheet" href="/css/default.css?v=#{ASSET_COMMIT}">)
- if env.get("preferences").as(Preferences).dark_mode
+ if env.get("preferences").as(Preferences).dark_mode == "dark"
env.response.puts %(<link rel="stylesheet" href="/css/darktheme.css?v=#{ASSET_COMMIT}">)
else
env.response.puts %(<link rel="stylesheet" href="/css/lighttheme.css?v=#{ASSET_COMMIT}">)
diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index ce0ded32..03c1654c 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -24,6 +24,27 @@ end
struct ConfigPreferences
module StringToArray
+ def self.to_json(value : Array(String), json : JSON::Builder)
+ json.array do
+ value.each do |element|
+ json.string element
+ end
+ end
+ end
+
+ def self.from_json(value : JSON::PullParser) : Array(String)
+ begin
+ result = [] of String
+ value.read_array do
+ result << HTML.escape(value.read_string[0, 100])
+ end
+ rescue ex
+ result = [HTML.escape(value.read_string[0, 100]), ""]
+ end
+
+ result
+ end
+
def self.to_yaml(value : Array(String), yaml : YAML::Nodes::Builder)
yaml.sequence do
value.each do |element|
@@ -44,11 +65,11 @@ struct ConfigPreferences
node.raise "Expected scalar, not #{item.class}"
end
- result << item.value
+ result << HTML.escape(item.value[0, 100])
end
rescue ex
if node.is_a?(YAML::Nodes::Scalar)
- result = [node.value, ""]
+ result = [HTML.escape(node.value[0, 100]), ""]
else
result = ["", ""]
end
@@ -58,6 +79,53 @@ struct ConfigPreferences
end
end
+ module BoolToString
+ def self.to_json(value : String, json : JSON::Builder)
+ json.string value
+ end
+
+ def self.from_json(value : JSON::PullParser) : String
+ begin
+ result = value.read_string
+
+ if result.empty?
+ CONFIG.default_user_preferences.dark_mode
+ else
+ result
+ end
+ rescue ex
+ result = value.read_bool
+
+ if result
+ "dark"
+ else
+ "light"
+ end
+ end
+ end
+
+ def self.to_yaml(value : String, yaml : YAML::Nodes::Builder)
+ yaml.scalar value
+ end
+
+ def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : String
+ unless node.is_a?(YAML::Nodes::Scalar)
+ node.raise "Expected sequence, not #{node.class}"
+ end
+
+ case node.value
+ when "true"
+ "dark"
+ when "false"
+ "light"
+ when ""
+ CONFIG.default_user_preferences.dark_mode
+ else
+ node.value
+ end
+ end
+ end
+
yaml_mapping({
annotations: {type: Bool, default: false},
annotations_subscribed: {type: Bool, default: false},
@@ -66,7 +134,7 @@ struct ConfigPreferences
comments: {type: Array(String), default: ["youtube", ""], converter: StringToArray},
continue: {type: Bool, default: false},
continue_autoplay: {type: Bool, default: true},
- dark_mode: {type: Bool, default: false},
+ dark_mode: {type: String, default: "", converter: BoolToString},
latest_only: {type: Bool, default: false},
listen: {type: Bool, default: false},
local: {type: Bool, default: false},
diff --git a/src/invidious/helpers/patch_mapping.cr b/src/invidious/helpers/patch_mapping.cr
index 8360caa6..e138aa1c 100644
--- a/src/invidious/helpers/patch_mapping.cr
+++ b/src/invidious/helpers/patch_mapping.cr
@@ -4,7 +4,7 @@ def Object.from_json(string_or_io, default) : self
new parser, default
end
-# Adds configurable 'default' to
+# Adds configurable 'default'
macro patched_json_mapping(_properties_, strict = false)
{% for key, value in _properties_ %}
{% _properties_[key] = {type: value} unless value.is_a?(HashLiteral) || value.is_a?(NamedTupleLiteral) %}
diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr
index 69aae839..b39f65c5 100644
--- a/src/invidious/helpers/utils.cr
+++ b/src/invidious/helpers/utils.cr
@@ -356,3 +356,16 @@ def parse_range(range)
return 0_i64, nil
end
+
+def convert_theme(theme)
+ case theme
+ when "true"
+ "dark"
+ when "false"
+ "light"
+ when "", nil
+ nil
+ else
+ theme
+ end
+end
diff --git a/src/invidious/users.cr b/src/invidious/users.cr
index 35d8a49e..8bd82bf1 100644
--- a/src/invidious/users.cr
+++ b/src/invidious/users.cr
@@ -31,62 +31,6 @@ struct User
end
struct Preferences
- module StringToArray
- def self.to_json(value : Array(String), json : JSON::Builder)
- json.array do
- value.each do |element|
- json.string element
- end
- end
- end
-
- def self.from_json(value : JSON::PullParser) : Array(String)
- begin
- result = [] of String
- value.read_array do
- result << HTML.escape(value.read_string[0, 100])
- end
- rescue ex
- result = [HTML.escape(value.read_string[0, 100]), ""]
- end
-
- result
- end
-
- def self.to_yaml(value : Array(String), yaml : YAML::Nodes::Builder)
- yaml.sequence do
- value.each do |element|
- yaml.scalar element
- end
- end
- end
-
- def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Array(String)
- begin
- unless node.is_a?(YAML::Nodes::Sequence)
- node.raise "Expected sequence, not #{node.class}"
- end
-
- result = [] of String
- node.nodes.each do |item|
- unless item.is_a?(YAML::Nodes::Scalar)
- node.raise "Expected scalar, not #{item.class}"
- end
-
- result << HTML.escape(item.value[0, 100])
- end
- rescue ex
- if node.is_a?(YAML::Nodes::Scalar)
- result = [HTML.escape(node.value[0, 100]), ""]
- else
- result = ["", ""]
- end
- end
-
- result
- end
- end
-
module ProcessString
def self.to_json(value : String, json : JSON::Builder)
json.string value
@@ -127,11 +71,11 @@ struct Preferences
annotations: {type: Bool, default: CONFIG.default_user_preferences.annotations},
annotations_subscribed: {type: Bool, default: CONFIG.default_user_preferences.annotations_subscribed},
autoplay: {type: Bool, default: CONFIG.default_user_preferences.autoplay},
- captions: {type: Array(String), default: CONFIG.default_user_preferences.captions, converter: StringToArray},
- comments: {type: Array(String), default: CONFIG.default_user_preferences.comments, converter: StringToArray},
+ captions: {type: Array(String), default: CONFIG.default_user_preferences.captions, converter: ConfigPreferences::StringToArray},
+ comments: {type: Array(String), default: CONFIG.default_user_preferences.comments, converter: ConfigPreferences::StringToArray},
continue: {type: Bool, default: CONFIG.default_user_preferences.continue},
continue_autoplay: {type: Bool, default: CONFIG.default_user_preferences.continue_autoplay},
- dark_mode: {type: Bool, default: CONFIG.default_user_preferences.dark_mode},
+ dark_mode: {type: String, default: CONFIG.default_user_preferences.dark_mode, converter: ConfigPreferences::BoolToString},
latest_only: {type: Bool, default: CONFIG.default_user_preferences.latest_only},
listen: {type: Bool, default: CONFIG.default_user_preferences.listen},
local: {type: Bool, default: CONFIG.default_user_preferences.local},
diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr
index b04bcd4d..6ea01fba 100644
--- a/src/invidious/views/preferences.ecr
+++ b/src/invidious/views/preferences.ecr
@@ -122,8 +122,12 @@ function update_value(element) {
</div>
<div class="pure-control-group">
- <label for="dark_mode"><%= translate(locale, "Dark mode: ") %></label>
- <input name="dark_mode" id="dark_mode" type="checkbox" <% if preferences.dark_mode %>checked<% end %>>
+ <label for="dark_mode"><%= translate(locale, "Theme: ") %></label>
+ <select name="dark_mode" id="dark_mode">
+ <% {"", "light", "dark"}.each do |option| %>
+ <option value="<%= option %>" <% if preferences.dark_mode == option %> selected <% end %>><%= translate(locale, option) %></option>
+ <% end %>
+ </select>
</div>
<div class="pure-control-group">
diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr
index 6272d2be..8d8cec88 100644
--- a/src/invidious/views/template.ecr
+++ b/src/invidious/views/template.ecr
@@ -18,13 +18,14 @@
<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/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 %>media="none"<% end %>>
- <link rel="stylesheet" href="/css/lighttheme.css?v=<%= ASSET_COMMIT %>" id="light_theme" <% if env.get("preferences").as(Preferences).dark_mode %>media="none"<% end %>>
+ <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/lighttheme.css?v=<%= ASSET_COMMIT %>" id="light_theme" <% if env.get("preferences").as(Preferences).dark_mode == "dark" %>media="none"<% end %>>
</head>
<% locale = LOCALES[env.get("preferences").as(Preferences).locale]? %>
<body>
+ <span style="display:none" id="dark_mode_pref"><%= env.get("preferences").as(Preferences).dark_mode %></span>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-2-24"></div>
<div class="pure-u-1 pure-u-md-20-24">
@@ -43,7 +44,7 @@
<% if env.get? "user" %>
<div class="pure-u-1-4">
<a id="toggle_theme" href="/toggle_theme?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
- <% if env.get("preferences").as(Preferences).dark_mode %>
+ <% if env.get("preferences").as(Preferences).dark_mode == "dark" %>
<i class="icon ion-ios-sunny"></i>
<% else %>
<i class="icon ion-ios-moon"></i>
@@ -76,7 +77,7 @@
<% else %>
<div class="pure-u-1-3">
<a id="toggle_theme" href="/toggle_theme?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
- <% if env.get("preferences").as(Preferences).dark_mode %>
+ <% if env.get("preferences").as(Preferences).dark_mode == "dark" %>
<i class="icon ion-ios-sunny"></i>
<% else %>
<i class="icon ion-ios-moon"></i>