# frozen_string_literal: true module ThemeHelper ATTRIBUTE_MAP = { "primary_color" => %w[primary primary-rgb], "primary_text" => "primary-text", "danger_color" => "danger", "danger_text" => "danger-text", "warning_color" => "warning", "warning_text" => "warning-text", "info_color" => "info", "info_text" => "info-text", "success_color" => "success", "success_text" => "success-text", "dark_color" => "dark", "dark_text" => "dark-text", "light_color" => "light", "light_text" => "light-text", "raised_background" => %w[raised-bg raised-bg-rgb], "raised_accent" => %w[raised-accent raised-accent-rgb], "background_color" => "background", "body_text" => "body-text", "input_color" => "input-bg", "input_text" => "input-text", "input_placeholder" => "input-placeholder", "muted_text" => "muted-text" }.freeze def render_theme theme = get_active_theme return unless theme body = ":root {\n" theme.attributes.each do |k, v| next unless ATTRIBUTE_MAP.key?(k) Array(ATTRIBUTE_MAP[k]).each do |var| body += "\t--#{var}: #{get_color_for_key(var, v)};\n" end end body += "\t--turbolinks-progress-color: ##{lighten(theme.primary_color)}\n}" content_tag(:style, body) end def get_color_for_key(key, color) hex = get_hex_color_from_theme_value(color) if key.include?("text") || key.include?("placeholder") || key.include?("rgb") get_decimal_triplet_from_hex(hex) else "##{hex}" end end def theme_color theme = get_active_theme if theme theme.theme_color else "#5e35b1" end end def mobile_theme_color theme = get_active_theme if theme theme.mobile_theme_color else "#f0edf4" end end def get_active_theme if @user&.theme if user_signed_in? if current_user&.show_foreign_themes? @user.theme else current_user&.theme end else @user.theme end elsif @answer&.user&.theme if user_signed_in? if current_user&.show_foreign_themes? @answer.user.theme else current_user&.theme end else @answer.user.theme end elsif current_user&.theme current_user.theme end end def get_hex_color_from_theme_value(value) "0000000#{value.to_s(16)}"[-6, 6] end def get_decimal_triplet_from_hex(value) hexes = value.split(/(.{2})/).reject(&:empty?) hexes.map(&:hex).join(", ") end def rgb_values_from_hex(value) [ (value & 0xFF0000) >> 16, # R (value & 0x00FF00) >> 8, # G value & 0x0000FF # B ] end def rgb_to_hex(rgb_values) rgb_values.map.with_index { |v, i| v << ((2 - i) * 8) }.reduce(&:+).to_s(16) end def lighten(value, amount = 0.25) rgb_to_hex(rgb_values_from_hex(value).map { |v| [(v + (255 * amount)).round, 255].min }) end end