module ThemeHelper ATTRIBUTE_MAP = { 'primary_color' => 'primary', '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' => 'raised-bg', 'raised_accent' => 'raised-accent', 'background_color' => 'background', 'body_text' => 'body-text', 'input_color' => 'input-bg', 'input_text' => 'input-text', '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) if k.include? 'text' hex = get_hex_color_from_theme_value(v) body += "\t--#{ATTRIBUTE_MAP[k]}: #{get_decimal_triplet_from_hex(hex)};\n" else body += "\t--#{ATTRIBUTE_MAP[k]}: ##{get_hex_color_from_theme_value(v)};\n" end end body += "\t--turbolinks-progress-color: ##{lighten(theme.primary_color)}\n" body += '}' content_tag(:style, body) 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 { |c| c.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