Class: ColorScheme
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- ColorScheme
- Defined in:
- app/models/color_scheme.rb
Constant Summary collapse
- CUSTOM_SCHEMES =
{ Dark: { "primary" => "dddddd", "secondary" => "222222", "tertiary" => "099dd7", "quaternary" => "c14924", "header_background" => "111111", "header_primary" => "dddddd", "highlight" => "a87137", "selected" => "052e3d", "hover" => "313131", "danger" => "e45735", "success" => "1ca551", "love" => "fa6c8d", }, # By @itsbhanusharma Neutral: { "primary" => "000000", "secondary" => "ffffff", "tertiary" => "51839b", "quaternary" => "b85e48", "header_background" => "333333", "header_primary" => "f3f3f3", "highlight" => "ecec70", "selected" => "e6e6e6", "hover" => "f0f0f0", "danger" => "b85e48", "success" => "518751", "love" => "fa6c8d", }, # By @Flower_Child "Grey Amber": { "primary" => "d9d9d9", "secondary" => "3d4147", "tertiary" => "fdd459", "quaternary" => "fdd459", "header_background" => "36393e", "header_primary" => "d9d9d9", "highlight" => "fdd459", "selected" => "272727", "hover" => "2F2F30", "danger" => "e45735", "success" => "fdd459", "love" => "fdd459", }, # By @rafafotes "Shades of Blue": { "primary" => "203243", "secondary" => "eef4f7", "tertiary" => "416376", "quaternary" => "5e99b9", "header_background" => "86bddb", "header_primary" => "203243", "highlight" => "86bddb", "selected" => "bee0f2", "hover" => "d2efff", "danger" => "bf3c3c", "success" => "70db82", "love" => "fc94cb", }, # By @mikechristopher Latte: { "primary" => "f2e5d7", "secondary" => "262322", "tertiary" => "f7f2ed", "quaternary" => "d7c9aa", "header_background" => "d7c9aa", "header_primary" => "262322", "highlight" => "d7c9aa", "selected" => "3e2a14", "hover" => "4c3319", "danger" => "db9584", "success" => "78be78", "love" => "8f6201", }, # By @Flower_Child Summer: { "primary" => "874342", "secondary" => "fffff4", "tertiary" => "fe9896", "quaternary" => "fcc9d0", "header_background" => "96ccbf", "header_primary" => "fff1e7", "highlight" => "f3c07f", "selected" => "f5eaea", "hover" => "f9f3f3", "danger" => "cfebdc", "success" => "fcb4b5", "love" => "f3c07f", }, # By @Flower_Child "Dark Rose": { "primary" => "ca9cb2", "secondary" => "3a2a37", "tertiary" => "fdd459", "quaternary" => "7e566a", "header_background" => "a97189", "header_primary" => "d9b2bb", "highlight" => "bd36a3", "selected" => "2a1620", "hover" => "331b27", "danger" => "6c3e63", "success" => "d9b2bb", "love" => "d9b2bb", }, WCAG: { "primary" => "000000", "primary-medium" => "696969", "primary-low-mid" => "909090", "secondary" => "ffffff", "tertiary" => "0033CC", "quaternary" => "3369FF", "header_background" => "ffffff", "header_primary" => "000000", "highlight" => "ffff00", "highlight-high" => "0036E6", "highlight-medium" => "e0e9ff", "highlight-low" => "e0e9ff", "selected" => "E2E9FE", "hover" => "F0F4FE", "danger" => "BB1122", "success" => "3d854d", "love" => "9D256B", }, "WCAG Dark": { "primary" => "ffffff", "primary-medium" => "999999", "primary-low-mid" => "888888", "secondary" => "0c0c0c", "tertiary" => "759AFF", "quaternary" => "759AFF", "header_background" => "000000", "header_primary" => "ffffff", "highlight" => "3369FF", "selected" => "0d2569", "hover" => "002382", "danger" => "FF697A", "success" => "70B880", "love" => "9D256B", }, # By @zenorocha Dracula: { "primary_very_low" => "373A47", "primary_low" => "414350", "primary_low_mid" => "8C8D94", "primary_medium" => "A3A4AA", "primary_high" => "CCCCCF", "primary" => "f2f2f2", "primary-50" => "3F414E", "primary-100" => "535460", "primary-200" => "666972", "primary-300" => "7A7C84", "primary-400" => "8D8F96", "primary-500" => "A2A3A9", "primary-600" => "B6B7BC", "primary-700" => "C7C7C7", "primary-800" => "DEDFE0", "primary-900" => "F5F5F5", "secondary_low" => "CCCCCF", "secondary_medium" => "91939A", "secondary_high" => "6A6C76", "secondary_very_high" => "3D404C", "secondary" => "2d303e", "tertiary_low" => "4A4463", "tertiary_medium" => "6E5D92", "tertiary" => "bd93f9", "tertiary_high" => "9275C1", "quaternary_low" => "6AA8BA", "quaternary" => "8be9fd", "header_background" => "373A47", "header_primary" => "f2f2f2", "highlight_low" => "686D55", "highlight_medium" => "52592B", "highlight_high" => "C0C879", "selected" => "4A4463", "hover" => "61597f", "danger_low" => "957279", "danger" => "ff5555", "success_low" => "386D50", "success_medium" => "44B366", "success" => "50fa7b", "love_low" => "6C4667", "love" => "ff79c6", }, # By @altercation "Solarized Light": { "primary_very_low" => "F0ECD7", "primary_low" => "D6D8C7", "primary_low_mid" => "A4AFA5", "primary_medium" => "7E918C", "primary_high" => "4C6869", "primary" => "002B36", "primary-50" => "F0EBDA", "primary-100" => "DAD8CA", "primary-200" => "B2B9B3", "primary-300" => "839496", "primary-400" => "76898C", "primary-500" => "697F83", "primary-600" => "627A7E", "primary-700" => "556F74", "primary-800" => "415F66", "primary-900" => "21454E", "secondary_low" => "325458", "secondary_medium" => "6C8280", "secondary_high" => "97A59D", "secondary_very_high" => "E8E6D3", "secondary" => "FCF6E1", "tertiary_low" => "D6E6DE", "tertiary_medium" => "7EBFD7", "tertiary" => "0088cc", "tertiary_high" => "329ED0", "quaternary" => "e45735", "header_background" => "FCF6E1", "header_primary" => "002B36", "highlight_low" => "FDF9AD", "highlight_medium" => "E3D0A3", "highlight" => "F2F481", "highlight_high" => "BCAA7F", "selected" => "E8E6D3", "hover" => "F0EBDA", "danger_low" => "F8D9C2", "danger" => "e45735", "success_low" => "CFE5B9", "success_medium" => "4CB544", "success" => "009900", "love_low" => "FCDDD2", "love" => "fa6c8d", }, # By @altercation "Solarized Dark": { "primary_very_low" => "0D353F", "primary_low" => "193F47", "primary_low_mid" => "798C88", "primary_medium" => "97A59D", "primary_high" => "B5BDB1", "primary" => "FCF6E1", "primary-50" => "21454E", "primary-100" => "415F66", "primary-200" => "556F74", "primary-300" => "627A7E", "primary-400" => "697F83", "primary-500" => "76898C", "primary-600" => "839496", "primary-700" => "B2B9B3", "primary-800" => "DAD8CA", "primary-900" => "F0EBDA", "secondary_low" => "B5BDB1", "secondary_medium" => "81938D", "secondary_high" => "4E6A6B", "secondary_very_high" => "143B44", "secondary" => "002B36", "tertiary_low" => "003E54", "tertiary_medium" => "00557A", "tertiary" => "1a97d5", "tertiary_high" => "006C9F", "quaternary_low" => "944835", "quaternary" => "e45735", "header_background" => "002B36", "header_primary" => "FCF6E1", "highlight_low" => "4D6B3D", "highlight_medium" => "464C33", "highlight" => "F2F481", "highlight_high" => "BFCA47", "selected" => "143B44", "hover" => "21454E", "danger_low" => "443836", "danger_medium" => "944835", "danger" => "e45735", "success_low" => "004C26", "success_medium" => "007313", "success" => "009900", "love_low" => "4B3F50", "love" => "fa6c8d", }, }
- LIGHT_THEME_ID =
"Light"
- BASE_COLORS_FILE =
"#{Rails.root}/app/assets/stylesheets/common/foundation/colors.scss"
- COLOR_TRANSFORMATION_FILE =
"#{Rails.root}/app/assets/stylesheets/common/foundation/color_transformations.scss"
Instance Attribute Summary collapse
-
#is_base ⇒ Object
Returns the value of attribute is_base.
-
#skip_publish ⇒ Object
Returns the value of attribute skip_publish.
Class Method Summary collapse
- .base ⇒ Object
- .base_color_scheme_colors ⇒ Object
- .base_color_schemes ⇒ Object
- .base_colors ⇒ Object
- .color_transformation_variables ⇒ Object
-
.create_from_base(params) ⇒ Object
create_from_base will create a new ColorScheme that overrides Discourse’s base color scheme with the given colors.
- .hex_cache ⇒ Object
- .hex_for_name(name, scheme_id = nil) ⇒ Object
- .is_base?(scheme_name) ⇒ Boolean
- .lookup_hex_for_name(name, scheme_id = nil) ⇒ Object
- .publish_discourse_stylesheets!(id = nil) ⇒ Object
Instance Method Summary collapse
- #base_colors ⇒ Object
- #bump_version ⇒ Object
- #clear_colors_cache ⇒ Object
- #colors=(arr) ⇒ Object
- #colors_by_name ⇒ Object
- #colors_hashes ⇒ Object
- #dump_caches ⇒ Object
- #is_dark? ⇒ Boolean
- #is_wcag? ⇒ Boolean
- #publish_discourse_stylesheet ⇒ Object
- #resolved_colors ⇒ Object
Instance Attribute Details
#is_base ⇒ Object
Returns the value of attribute is_base.
302 303 304 |
# File 'app/models/color_scheme.rb', line 302 def is_base @is_base end |
#skip_publish ⇒ Object
Returns the value of attribute skip_publish.
303 304 305 |
# File 'app/models/color_scheme.rb', line 303 def skip_publish @skip_publish end |
Class Method Details
.base ⇒ Object
368 369 370 371 372 373 374 |
# File 'app/models/color_scheme.rb', line 368 def self.base return @base_color_scheme if @base_color_scheme @base_color_scheme = new(name: I18n.t("color_schemes.base_theme_name")) @base_color_scheme.colors = base_colors.map { |name, hex| { name: name, hex: hex } } @base_color_scheme.is_base = true @base_color_scheme end |
.base_color_scheme_colors ⇒ Object
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'app/models/color_scheme.rb', line 282 def self.base_color_scheme_colors base_with_hash = [] base_colors.each { |name, color| base_with_hash << { name: name, hex: "#{color}" } } list = [{ id: LIGHT_THEME_ID, colors: base_with_hash }] CUSTOM_SCHEMES.each do |k, v| colors = [] v.each { |name, color| colors << { name: name, hex: "#{color}" } } list.push(id: k.to_s, colors: colors) end list end |
.base_color_schemes ⇒ Object
355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'app/models/color_scheme.rb', line 355 def self.base_color_schemes base_color_scheme_colors.map do |hash| scheme = new( name: I18n.t("color_schemes.#{hash[:id].downcase.gsub(" ", "_")}"), base_scheme_id: hash[:id], ) scheme.colors = hash[:colors].map { |k| { name: k[:name], hex: k[:hex] } } scheme.is_base = true scheme end end |
.base_colors ⇒ Object
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'app/models/color_scheme.rb', line 323 def self.base_colors return @base_colors if @base_colors @mutex.synchronize do return @base_colors if @base_colors base_colors = {} File .readlines(BASE_COLORS_FILE) .each do |line| matches = /\$([\w]+):\s*#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})(?:[;]|\s)/.match(line.strip) base_colors[matches[1]] = matches[2] if matches end @base_colors = base_colors end @base_colors end |
.color_transformation_variables ⇒ Object
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
# File 'app/models/color_scheme.rb', line 339 def self.color_transformation_variables return @transformation_variables if @transformation_variables @mutex.synchronize do return @transformation_variables if @transformation_variables transformation_variables = [] File .readlines(COLOR_TRANSFORMATION_FILE) .each do |line| matches = /\$([\w\-_]+):.*/.match(line.strip) transformation_variables.append(matches[1]) if matches end @transformation_variables = transformation_variables end @transformation_variables end |
.create_from_base(params) ⇒ Object
create_from_base will create a new ColorScheme that overrides Discourse’s base color scheme with the given colors.
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 |
# File 'app/models/color_scheme.rb', line 381 def self.create_from_base(params) new_color_scheme = new(name: params[:name]) new_color_scheme.via_wizard = true if params[:via_wizard] new_color_scheme.base_scheme_id = params[:base_scheme_id] new_color_scheme.user_selectable = true colors = CUSTOM_SCHEMES[params[:base_scheme_id].to_sym]&.map do |name, hex| { name: name, hex: hex } end if params[:base_scheme_id] colors ||= base.colors_hashes # Override base values params[:colors].each do |name, hex| c = colors.find { |x| x[:name].to_s == name.to_s } c[:hex] = hex end if params[:colors] new_color_scheme.colors = colors new_color_scheme.skip_publish if params[:skip_publish] new_color_scheme.save new_color_scheme end |
.hex_cache ⇒ Object
298 299 300 |
# File 'app/models/color_scheme.rb', line 298 def self.hex_cache @hex_cache ||= DistributedCache.new("scheme_hex_for_name") end |
.hex_for_name(name, scheme_id = nil) ⇒ Object
411 412 413 414 415 |
# File 'app/models/color_scheme.rb', line 411 def self.hex_for_name(name, scheme_id = nil) hex_cache.defer_get_set(scheme_id ? name + "_#{scheme_id}" : name) do lookup_hex_for_name(name, scheme_id) end end |
.is_base?(scheme_name) ⇒ Boolean
376 377 378 |
# File 'app/models/color_scheme.rb', line 376 def self.is_base?(scheme_name) base_color_scheme_colors.map { |c| c[:id] }.include?(scheme_name) end |
.lookup_hex_for_name(name, scheme_id = nil) ⇒ Object
405 406 407 408 409 |
# File 'app/models/color_scheme.rb', line 405 def self.lookup_hex_for_name(name, scheme_id = nil) enabled_color_scheme = find_by(id: scheme_id) if scheme_id enabled_color_scheme ||= Theme.where(id: SiteSetting.default_theme_id).first&.color_scheme (enabled_color_scheme || base).colors.find { |c| c.name == name }.try(:hex) end |
.publish_discourse_stylesheets!(id = nil) ⇒ Object
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
# File 'app/models/color_scheme.rb', line 476 def self.publish_discourse_stylesheets!(id = nil) Stylesheet::Manager.clear_color_scheme_cache! theme_ids = [] if id theme_ids = Theme.where(color_scheme_id: id).pluck(:id) else theme_ids = Theme.all.pluck(:id) end if theme_ids.present? Stylesheet::Manager.cache.clear Theme.notify_theme_change( theme_ids, with_scheme: true, clear_manager_cache: false, all_themes: true, ) end end |
Instance Method Details
#base_colors ⇒ Object
440 441 442 443 444 |
# File 'app/models/color_scheme.rb', line 440 def base_colors colors = nil colors = CUSTOM_SCHEMES[base_scheme_id.to_sym] if base_scheme_id && base_scheme_id != "Light" colors || ColorScheme.base_colors end |
#bump_version ⇒ Object
502 503 504 |
# File 'app/models/color_scheme.rb', line 502 def bump_version self.version += 1 if self.id end |
#clear_colors_cache ⇒ Object
432 433 434 |
# File 'app/models/color_scheme.rb', line 432 def clear_colors_cache @colors_by_name = nil end |
#colors=(arr) ⇒ Object
417 418 419 420 |
# File 'app/models/color_scheme.rb', line 417 def colors=(arr) @colors_by_name = nil arr.each { |c| self.color_scheme_colors << ColorSchemeColor.new(name: c[:name], hex: c[:hex]) } end |
#colors_by_name ⇒ Object
422 423 424 425 426 427 428 429 430 |
# File 'app/models/color_scheme.rb', line 422 def colors_by_name @colors_by_name ||= self .colors .inject({}) do |sum, c| sum[c.name] = c sum end end |
#colors_hashes ⇒ Object
436 437 438 |
# File 'app/models/color_scheme.rb', line 436 def colors_hashes color_scheme_colors.map { |c| { name: c.name, hex: c.hex } } end |
#dump_caches ⇒ Object
497 498 499 500 |
# File 'app/models/color_scheme.rb', line 497 def dump_caches self.class.hex_cache.clear ApplicationSerializer.expire_cache_fragment!("user_color_schemes") end |
#is_dark? ⇒ Boolean
506 507 508 509 510 511 512 513 |
# File 'app/models/color_scheme.rb', line 506 def is_dark? return if colors.to_a.empty? primary_b = ColorMath.brightness(resolved_colors["primary"]) secondary_b = ColorMath.brightness(resolved_colors["secondary"]) primary_b > secondary_b end |
#is_wcag? ⇒ Boolean
515 516 517 |
# File 'app/models/color_scheme.rb', line 515 def is_wcag? base_scheme_id&.start_with?("WCAG") end |
#publish_discourse_stylesheet ⇒ Object
472 473 474 |
# File 'app/models/color_scheme.rb', line 472 def publish_discourse_stylesheet self.class.publish_discourse_stylesheets!(self.id) if self.id end |
#resolved_colors ⇒ Object
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'app/models/color_scheme.rb', line 446 def resolved_colors from_base = ColorScheme.base_colors from_custom_scheme = base_colors from_db = colors.map { |c| [c.name, c.hex] }.to_h resolved = from_base.merge(from_custom_scheme).except("hover", "selected").merge(from_db) # Equivalent to primary-100 in light mode, or primary-low in dark mode resolved["hover"] ||= ColorMath.dark_light_diff( resolved["primary"], resolved["secondary"], 0.94, -0.78, ) # Equivalent to primary-low in light mode, or primary-100 in dark mode resolved["selected"] ||= ColorMath.dark_light_diff( resolved["primary"], resolved["secondary"], 0.9, -0.8, ) resolved end |