FEATURE: out-of-the-box dark/light user selectable themes

This commit is contained in:
Sam 2017-05-03 11:31:16 -04:00
parent 81190f5d66
commit 342ef5f81a
13 changed files with 68 additions and 35 deletions

View File

@ -92,13 +92,19 @@ class ColorScheme < ActiveRecord::Base
# create_from_base will create a new ColorScheme that overrides Discourse's base color scheme with the given colors.
def self.create_from_base(params)
new_color_scheme = new(name: params[:name])
colors = base.colors_hashes
new_color_scheme.via_wizard = true if params[:via_wizard]
new_color_scheme.base_scheme_id = params[:base_scheme_id]
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
end if params[:colors]
new_color_scheme.colors = colors
new_color_scheme.save

View File

@ -83,6 +83,10 @@ class Theme < ActiveRecord::Base
Theme.expire_site_cache!
end
def default?
SiteSetting.default_theme_key == key
end
def self.lookup_field(key, target, field)
return if key.blank?

View File

@ -2772,6 +2772,9 @@ en:
base_theme_name: "Base"
default: "Light Scheme"
dark: "Dark Scheme"
default_theme_name: "Default"
dark_theme_name: "Dark"
light_theme_name: "Light"
about: "About"
guidelines: "Guidelines"

19
db/fixtures/600_themes.rb Normal file
View File

@ -0,0 +1,19 @@
# we can not guess what to do if customization already started, so skip it
if !Theme.exists?
STDERR.puts "> Seeding dark and light themes"
name = I18n.t("wizard.step.colors.fields.theme_id.choices.dark.label")
dark_scheme = ColorScheme.where.find_by(base_scheme_id: "dark")
dark_scheme ||= ColorScheme.create_from_base(name: name, via_wizard: true, base_scheme_id: "dark")
name = I18n.t('color_schemes.dark_theme_name')
_dark_theme = Theme.create(name: name, user_id: -1,
color_scheme_id: dark_scheme.id,
user_selectable: true)
name = I18n.t('color_schemes.default_theme_name')
default_theme = Theme.create(name: name, user_id: -1,
user_selectable: true)
default_theme.set_default!
end

View File

@ -114,8 +114,8 @@ class Wizard
end
@wizard.append_step('colors') do |step|
scheme_id = ColorScheme.where(via_wizard: true).pluck(:base_scheme_id)&.first
scheme_id ||= 'default'
default_theme = Theme.find_by(key: SiteSetting.default_theme_key)
scheme_id = default_theme&.color_scheme&.base_scheme_id || 'default'
themes = step.add_field(id: 'base_scheme_id', type: 'dropdown', required: true, value: scheme_id)
ColorScheme.base_color_scheme_colors.each do |t|
@ -128,37 +128,28 @@ class Wizard
step.on_update do |updater|
scheme_name = updater.fields[:base_scheme_id]
theme = ColorScheme.base_color_schemes.find{|s| s.base_scheme_id == scheme_name}
theme = nil
colors = []
theme.colors.each do |color|
colors << {name: color.name, hex: color.hex }
end
if scheme_name == "dark"
scheme = ColorScheme.find_by(base_scheme_id: 'dark', via_wizard: true)
attrs = {
name: I18n.t("wizard.step.colors.fields.theme_id.choices.#{scheme_name}.label"),
colors: colors,
base_scheme_id: scheme_name
}
name = I18n.t("wizard.step.colors.fields.theme_id.choices.dark.label")
scheme ||= ColorScheme.create_from_base(name: name, via_wizard: true, base_scheme_id: "dark")
scheme = ColorScheme.where(via_wizard: true).first
if scheme.present?
attrs[:colors] = colors
revisor = ColorSchemeRevisor.new(scheme, attrs)
revisor.revise
theme = Theme.find_by(color_scheme_id: scheme.id)
name = I18n.t('color_schemes.dark_theme_name')
theme ||= Theme.create(name: name, color_scheme_id: scheme.id)
else
attrs[:via_wizard] = true
scheme = ColorScheme.new(attrs)
scheme.save!
themes = Theme.where(color_scheme_id: nil).order(:id).to_a
theme = themes.find(&:default?)
theme ||= themes.first
name = I18n.t('color_schemes.light_theme_name')
theme ||= Theme.create(name: name)
end
default_theme = Theme.find_by(key: SiteSetting.default_theme_key)
unless default_theme
default_theme = Theme.new(name: "Default Theme", user_id: -1)
end
default_theme.color_scheme_id = scheme.id
default_theme.save!
SiteSetting.default_theme_key = default_theme.key
theme.set_default!
end
end

View File

@ -4,6 +4,7 @@ require 'stylesheet/compiler'
describe Stylesheet::Manager do
it 'does not crash for missing theme' do
Theme.clear_default!
link = Stylesheet::Manager.stylesheet_link_tag(:embedded_theme)
expect(link).to eq("")

View File

@ -155,17 +155,14 @@ describe Wizard::StepUpdater do
updater.update
expect(updater.success?).to eq(true)
expect(wizard.completed_steps?('colors')).to eq(true)
theme = Theme.find_by(key: SiteSetting.default_theme_key)
expect(theme.color_scheme_id).to eq(color_scheme.id)
expect(theme.color_scheme.base_scheme_id).to eq('dark')
end
end
context "without an existing scheme" do
it "creates the scheme" do
updater = wizard.create_updater('colors', base_scheme_id: 'dark')
updater = wizard.create_updater('colors', base_scheme_id: 'dark', allow_dark_light_selection: true)
updater.update
expect(updater.success?).to eq(true)
expect(wizard.completed_steps?('colors')).to eq(true)
@ -176,6 +173,8 @@ describe Wizard::StepUpdater do
theme = Theme.find_by(key: SiteSetting.default_theme_key)
expect(theme.color_scheme_id).to eq(color_scheme.id)
expect(Theme.where(user_selectable: true).count).to eq(2)
end
end
end

View File

@ -12,7 +12,11 @@ describe Admin::ThemesController do
end
context ' .index' do
it 'returns success' do
it 'correctly returns themes' do
ColorScheme.destroy_all
Theme.destroy_all
theme = Theme.new(name: 'my name', user_id: -1)
theme.set_field(target: :common, name: :scss, value: '.body{color: black;}')
theme.set_field(target: :desktop, name: :after_header, value: '<b>test</b>')

View File

@ -4,6 +4,8 @@ describe StylesheetCache do
describe "add" do
it "correctly cycles once MAX_TO_KEEP is hit" do
StylesheetCache.destroy_all
(StylesheetCache::MAX_TO_KEEP + 1).times do |i|
StylesheetCache.add("a", "d" + i.to_s, "c" + i.to_s, "map")
end
@ -13,6 +15,8 @@ describe StylesheetCache do
end
it "does nothing if digest is set and already exists" do
StylesheetCache.destroy_all
StylesheetCache.add("a", "b", "c", "map")
StylesheetCache.add("a", "b", "cc", "map")

View File

@ -152,6 +152,8 @@ HTML
end
it 'correctly caches theme keys' do
Theme.destroy_all
theme = Theme.create!(name: "bob", user_id: -1)
expect(Theme.theme_keys).to eq(Set.new([theme.key]))