Skip to content

Commit e3a25b5

Browse files
committed
Ability to set color scheme in session
1 parent ae06897 commit e3a25b5

File tree

8 files changed

+137
-41
lines changed

8 files changed

+137
-41
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
11
class ApplicationController < ActionController::Base
22
include Erroring
33
include Authentication
4+
5+
before_action :set_color_theme
6+
7+
def set_color_theme
8+
@color_scale = find_color_theme
9+
end
10+
11+
def find_color_theme
12+
if session[:color_scale_id]
13+
begin
14+
return ColorScale.find(session[:color_scale_id])
15+
rescue ActiveRecord::RecordNotFound
16+
end
17+
end
18+
19+
ColorScale.cached_default
20+
end
421
end
Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,38 @@
11
class ColorThemesController < ApplicationController
22
def show
3-
show_params = params[:color_theme] ? params.require(:color_theme).permit(:color_scale_id) : {}
4-
color_scale_id = show_params[:color_scale_id]
5-
@color_scale = color_scale_id ? ColorScale.find(color_scale_id) : ColorScale.find_or_create_default
3+
@color_scale = selected_color_scale || session_color_scale || ColorScale.cached_default
64
@color_theme = ColorTheme.new(color_scale: @color_scale)
75

86
render ColorThemes::ShowView.new(
97
color_theme: @color_theme,
8+
fallback_color_scale: session_color_scale || ColorScale.cached_default,
109
curated_color_scales: ColorScale.cached_curated,
11-
selected: color_scale_id.present?
10+
selected: selected_color_scale_id.present?,
11+
saved: session[:color_scale_id].presence == @color_scale.id
1212
)
1313
end
14+
15+
def update
16+
update_params = params[:color_theme] ? params.require(:color_theme).permit(:color_scale_id) : {}
17+
color_scale_id = update_params[:color_scale_id]
18+
@color_scale = ColorScale.find(color_scale_id)
19+
20+
redirect_to color_theme_path unless @color_scale.present?
21+
22+
if @color_scale == ColorScale.cached_default
23+
session.delete(:color_scale_id)
24+
else
25+
session[:color_scale_id] = @color_scale.id
26+
end
27+
28+
redirect_to color_theme_path, status: :see_other
29+
end
30+
31+
private
32+
33+
def selected_color_scale_id = params.dig(:color_theme, :color_scale_id) || session[:color_scale_id]
34+
35+
def session_color_scale = session[:color_scale_id] && ColorScale.find(session[:color_scale_id])
36+
37+
def selected_color_scale = selected_color_scale_id && ColorScale.find(selected_color_scale_id)
1438
end

app/models/color_scale.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ def self.cached_default
5252

5353
return where(id: cached_id).first if cached_id
5454

55-
where(name: APP_DEFAULT[:name]).first.tap do |cs|
56-
Rails.cache.write("default_color_scale_id", cs.id)
55+
find_or_create_default.tap do |cs|
56+
Rails.cache.write(cache_key, cs.id)
5757
end
5858
end
5959

app/models/color_theme.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ class ColorTheme
66
def initialize(color_scale:)
77
@color_scale = color_scale
88
end
9+
10+
def color_scale_id = color_scale.id
911
end
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
<%
2-
color_scale = @color_scale || ColorScale.find_or_create_default
3-
%>
41
<style>
52
:root {
6-
<%= render ColorScales::Css.new(color_scale: color_scale) %>
3+
<%= render ColorScales::Css.new(color_scale: @color_scale || ColorScale.find_or_create_default) %>
74
}
85
</style>

app/views/color_themes/show_view.rb

Lines changed: 74 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,95 @@
33
class ColorThemes::ShowView < ApplicationView
44
include Phlex::Rails::Helpers::FormWith
55
include Phlex::Rails::Helpers::LinkTo
6+
include Phlex::Rails::Helpers::ButtonTo
7+
include Phlex::Rails::Helpers::ContentFor
68

7-
def initialize(color_theme:, curated_color_scales: [], selected: false)
9+
def initialize(color_theme:, fallback_color_scale: nil, curated_color_scales: [], selected: false, saved: false)
810
@color_theme = color_theme
911
@color_scale = color_theme.color_scale
12+
@fallback_color_scale = fallback_color_scale
1013
@curated_color_scales = curated_color_scales
1114
@selected = selected
15+
@saved = saved
1216
end
1317

1418
def view_template
15-
render Pages::Header.new(title: "Settings: Color Theme")
19+
content_for :head do
20+
render("application/theme/color")
21+
end
22+
render Pages::Header.new(title: "Theme")
1623
div(class: "section-content container py-gap") do
17-
h3 { "Want to try a different color theme?" }
18-
19-
p { "You can preview and save your desired color theme for this site. We have curated some options for you below." }
20-
21-
form_with(model: @color_theme, url: url_for, method: :get) do |f|
22-
fieldset(class: "flex items-center") do
23-
f.select(
24-
:color_scale_id,
25-
@curated_color_scales.map { |cs| [cs.display_name, cs.id] },
26-
{
27-
prompt: "Pick one!",
28-
selected: (@selected ? @color_scale.id : nil)
29-
},
30-
# requestSubmit and Turbo
31-
# https://stackoverflow.com/questions/68624668/how-can-i-submit-a-form-on-input-change-with-turbo-streams
32-
onchange: "this.form.requestSubmit()",
33-
class: "mr-2 bg-gray-50 border border-gray-300 text-small rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
34-
)
24+
if @saved || @selected
25+
h3 do
26+
plain "You are now #{@saved ? "using" : "previewing"} the"
27+
whitespace
28+
span(class: "emphasis") { @color_scale.display_name }
29+
whitespace
30+
plain "color scheme"
31+
end
32+
else
33+
h3 { "Want to try a different color scheme?" }
34+
end
3535

36-
span(class: "mr-2 text-small") { "OR" }
37-
link_to "I feel lucky!", url_for(color_theme: {color_scale_id: @curated_color_scales.sample.id}), class: "button primary mr-2"
38-
if @selected
39-
span(class: "mr-2 text-small") { unsafe_raw "&bull;" }
40-
link_to "Reset to default", url_for, class: "button secondary"
36+
p { "You can preview and save your desired color scheme for this site. We have curated some options for you below." }
37+
38+
div(class: "flex items-center") do
39+
span(class: "mr-2 text-small") { "Preview" }
40+
41+
form_with(model: @color_theme, url: url_for, method: :get) do |f|
42+
fieldset do
43+
f.select(
44+
:color_scale_id,
45+
@curated_color_scales.map { |cs| [cs.display_name, cs.id] },
46+
{
47+
prompt: "Pick one!",
48+
selected: @selected && @color_scale.id
49+
},
50+
# requestSubmit and Turbo
51+
# https://stackoverflow.com/questions/68624668/how-can-i-submit-a-form-on-input-change-with-turbo-streams
52+
onchange: "this.form.requestSubmit()",
53+
class: "mr-2"
54+
)
4155
end
4256
end
57+
58+
span(class: "mr-2 text-small") { "OR" }
59+
60+
link_to "I feel lucky!",
61+
color_theme_path(color_theme: {color_scale_id: @curated_color_scales.sample.id}),
62+
class: "button secondary mr-2"
63+
64+
if @selected && @color_scale != @fallback_color_scale
65+
span(class: "mr-2 text-small") { "OR" }
66+
67+
button_to "Reset preview",
68+
color_theme_path(color_theme: {color_scale_id: @fallback_color_scale.id}),
69+
method: :patch,
70+
class: "button tertiary mr-2"
71+
end
72+
end
73+
74+
if @selected
75+
div(class: "flex items-center") do
76+
span(class: "mr-2 text-small") { plain "Save" }
77+
78+
button_to "Save this color scheme",
79+
color_theme_path(color_theme: {color_scale_id: @color_scale.id}),
80+
method: :patch,
81+
class: "button primary mr-2"
82+
83+
span(class: "mr-2 text-small") { unsafe_raw "&bull;" }
84+
85+
button_to "Reset to default",
86+
color_theme_path(color_theme: {color_scale_id: ColorScale.cached_default.id}),
87+
method: :patch,
88+
class: "button tertiary mr-2"
89+
end
4390
end
4491

4592
h3 { display_name }
46-
div(class: "color-theme color-theme:#{@color_scale.name.parameterize}") do
93+
94+
div(class: "color-scheme color-scheme__#{@color_scale.name.parameterize}") do
4795
@color_scale.weights.each do |weight, color|
4896
div(class: "color-swatch color-swatch__weight:#{weight}", style: "background-color: #{color.hex}") do
4997
div(class: "color-swatch__weight") { weight }

spec/models/color_scale_spec.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
it "should return a hash of all weights" do
1818
color_scale = FactoryBot.build(:color_scale)
1919

20-
expect(color_scale.weights).to eq(
20+
# ColorConversion::Color objects don’t implement #==, so we convert to hex
21+
expect(color_scale.weights.transform_values { |color| color.hex }).to eq(
2122
"50" => color_scale.weight_50,
2223
"100" => color_scale.weight_100,
2324
"200" => color_scale.weight_200,

spec/system/color_themes/customize_spec.rb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,21 @@
44

55
RSpec.describe "Customize Color Themes", type: :system do
66
it "user can selected a curated color scale" do
7+
curated_color_names = YAML.load_file(Rails.root.join("config", "curated_colors.yml")).sample(3)
8+
9+
curated_colors = curated_color_names.map do |name|
10+
FactoryBot.create(:color_scale, name: name)
11+
end
12+
713
visit color_theme_path
814

9-
select "Thunderbird", from: "Choose a color scheme"
15+
chosen_color = curated_colors.second
16+
select chosen_color.display_name, from: "color_theme[color_scale_id]"
1017

11-
click_button "Use this color scheme"
18+
click_button "Save this color scheme"
1219

13-
expect(page).to have_content("You are now using the Cerulean Blue color scheme")
20+
expect(page).to have_content("You are now using the #{chosen_color.display_name} color scheme")
1421

15-
expect(page).to have_css("color-theme:custom-thunderbird")
22+
expect(page).to have_css(".color-scheme__#{chosen_color.name.parameterize}")
1623
end
1724
end

0 commit comments

Comments
 (0)