Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/controllers/settings/appearance_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def update_theme
private

def page_props
{ user: { theme: @user.theme }, options: base_options(keys: %i[themes]) }
{ user: { theme: @user.theme }, options: { themes: User.theme_options } }
end

def theme_params = params.require(:user).permit(:theme)
Expand Down
15 changes: 0 additions & 15 deletions app/controllers/settings/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,13 @@ def common_props(active_section:)
# Subclasses override this to provide page-specific props
def page_props = {}

BASE_OPTION_BUILDERS = {
countries: -> { ISO3166::Country.all.map { |c| { label: c.common_name, value: c.alpha2 } }.sort_by { |c| c[:label] } },
# see .timezone_options below; a user's current zone, if outside the list,
# is pinned in ProfileController#page_props so it never disappears.
timezones: -> { Settings::BaseController.timezone_options },
extension_text_types: -> { User.hackatime_extension_text_types.keys.map { |k| { label: k.humanize, value: k } } },
themes: -> { User.theme_options }
}.freeze

def self.timezone_options
@timezone_options ||= ActiveSupport::TimeZone.all
.group_by { |z| z.tzinfo.identifier } # London & Edinburgh both map to Europe/London
.map { |identifier, zones| { label: "(GMT#{zones.first.formatted_offset}) #{zones.map(&:name).join(", ")}", value: identifier } }
.freeze
end

# Build a base options hash containing only the requested keys.
def base_options(keys: nil)
(keys.present? ? BASE_OPTION_BUILDERS.slice(*keys) : BASE_OPTION_BUILDERS)
.transform_values { |builder| builder.call }
end

def set_user
@user = current_user
redirect_to root_path, alert: "You need to log in!" if @user.nil?
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/settings/editors_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ def page_props
hackatime_extension_text_type: @user.hackatime_extension_text_type,
show_goals_in_statusbar: @user.show_goals_in_statusbar
},
options: base_options(keys: %i[extension_text_types]) }
options: {
extension_text_types: User.hackatime_extension_text_types.keys.map { |key|
{ label: key.humanize, value: key }
}
} }
end

def editor_params = params.require(:user).permit(:hackatime_extension_text_type, :show_goals_in_statusbar)
Expand Down
9 changes: 6 additions & 3 deletions app/controllers/settings/profile_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ def update_username = update_section(username_params)
private

def page_props
options = base_options(keys: %i[countries timezones])
options[:timezones] = pin_current_timezone(options[:timezones])
{
username_max_length: User::USERNAME_MAX_LENGTH,
display_name_max_length: User::DISPLAY_NAME_MAX_LENGTH,
Expand All @@ -18,7 +16,12 @@ def page_props
display_name_override: @user.display_name_override,
username: @user.username
},
options: options,
options: {
countries: ISO3166::Country.all
.map { |country| { label: country.common_name, value: country.alpha2 } }
.sort_by { |country| country[:label] },
timezones: pin_current_timezone(Settings::BaseController.timezone_options)
},
profile_url: (@user.username.present? ? "https://hackati.me/#{@user.username}" : nil),
emails: email_props
}
Expand Down
12 changes: 12 additions & 0 deletions test/controllers/settings_appearance_controller_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
require "test_helper"

class SettingsAppearanceControllerTest < ActionDispatch::IntegrationTest
test "show provides theme options" do
user = create(:user)
sign_in_as(user)

get my_settings_appearance_path

assert_response :success
assert_inertia_component "Users/Settings/Appearance"
assert_equal [ "themes" ], inertia.props.fetch("options").keys
assert_equal User.theme_options.as_json, inertia.props.dig("options", "themes")
end

test "theme update persists selected theme and clears Inertia history" do
user = create(:user)
sign_in_as(user)
Expand Down
19 changes: 19 additions & 0 deletions test/controllers/settings_editors_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require "test_helper"

class SettingsEditorsControllerTest < ActionDispatch::IntegrationTest
test "show provides extension text type options" do
user = create(:user)
sign_in_as(user)

get my_settings_editors_path

assert_response :success
assert_inertia_component "Users/Settings/Editors"
assert_equal [ "extension_text_types" ], inertia.props.fetch("options").keys
assert_equal [
{ "label" => "Simple text", "value" => "simple_text" },
{ "label" => "Clock emoji", "value" => "clock_emoji" },
{ "label" => "Compliment text", "value" => "compliment_text" }
], inertia.props.dig("options", "extension_text_types")
end
end
25 changes: 25 additions & 0 deletions test/controllers/settings_profile_controller_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,31 @@
require "test_helper"

class SettingsProfileControllerTest < ActionDispatch::IntegrationTest
test "show provides profile options and pins a legacy timezone" do
travel_to Time.utc(2026, 1, 15) do
user = create(:user)
user.update_column(:timezone, "Eastern Time (US & Canada)")
sign_in_as(user)

get my_settings_profile_path

assert_response :success
assert_inertia_component "Users/Settings/Profile"

options = inertia.props.fetch("options")
countries = options.fetch("countries")
timezones = options.fetch("timezones")

assert_equal %w[countries timezones], options.keys
assert_equal countries.sort_by { |country| country.fetch("label") }, countries
assert_equal({ "label" => "Afghanistan", "value" => "AF" }, countries.first)
assert_equal({
"label" => "Eastern Time (US & Canada) (UTC-05:00)",
"value" => "Eastern Time (US & Canada)"
}, timezones.first)
end
end

test "region update normalizes blank country code to nil" do
user = create(:user)
user.update!(country_code: "US")
Expand Down