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 %() env.response.puts %() env.response.puts %() - if env.get("preferences").as(Preferences).dark_mode + if env.get("preferences").as(Preferences).dark_mode == "dark" env.response.puts %() else env.response.puts %() diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr index ce0ded32..296e02af 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: "light", 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) {
- - checked<% end %>> + +
diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr index 6272d2be..e658ace6 100644 --- a/src/invidious/views/template.ecr +++ b/src/invidious/views/template.ecr @@ -18,8 +18,8 @@ - media="none"<% end %>> - media="none"<% end %>> + media="none"<% end %>> + media="none"<% end %>> <% locale = LOCALES[env.get("preferences").as(Preferences).locale]? %> @@ -43,7 +43,7 @@ <% if env.get? "user" %>
" class="pure-menu-heading"> - <% if env.get("preferences").as(Preferences).dark_mode %> + <% if env.get("preferences").as(Preferences).dark_mode == "dark" %> <% else %> @@ -76,7 +76,7 @@ <% else %>