From 4c9406bdb0938367615a12083199705304d29e27 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 10 Jun 2023 03:29:37 +0200 Subject: [PATCH] Add time zone preference (#25342) --- app/controllers/api/v1/accounts_controller.rb | 2 +- app/controllers/settings/preferences/base_controller.rb | 2 +- app/models/account.rb | 1 + app/models/user.rb | 2 ++ app/services/app_sign_up_service.rb | 2 +- app/views/notification_mailer/_status.html.haml | 2 +- app/views/notification_mailer/favourite.html.haml | 2 +- app/views/notification_mailer/mention.html.haml | 2 +- app/views/notification_mailer/reblog.html.haml | 2 +- app/views/settings/preferences/appearance/show.html.haml | 7 +++++-- app/views/user_mailer/appeal_approved.html.haml | 2 +- app/views/user_mailer/appeal_approved.text.erb | 2 +- app/views/user_mailer/appeal_rejected.html.haml | 2 +- app/views/user_mailer/appeal_rejected.text.erb | 2 +- app/views/user_mailer/suspicious_sign_in.html.haml | 2 +- app/views/user_mailer/suspicious_sign_in.text.erb | 2 +- app/views/user_mailer/warning.html.haml | 2 +- config/locales/simple_form.en.yml | 1 + db/migrate/20230605085711_add_time_zone_to_users.rb | 7 +++++++ db/schema.rb | 3 ++- 20 files changed, 32 insertions(+), 17 deletions(-) create mode 100644 db/migrate/20230605085711_add_time_zone_to_users.rb diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index 8af4242ba30e232021120bd0ff1f858e08e26886..ddb94d5ca48691dcf36ea0ee541f9d33c17a8079 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -90,7 +90,7 @@ class Api::V1::AccountsController < Api::BaseController end def account_params - params.permit(:username, :email, :password, :agreement, :locale, :reason) + params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone) end def check_enabled_registrations diff --git a/app/controllers/settings/preferences/base_controller.rb b/app/controllers/settings/preferences/base_controller.rb index faf778a7e525327b7837120ae123addff33d1263..c1f8b49898e0593ff91e0ab9464cdca81090ed0e 100644 --- a/app/controllers/settings/preferences/base_controller.rb +++ b/app/controllers/settings/preferences/base_controller.rb @@ -19,6 +19,6 @@ class Settings::Preferences::BaseController < Settings::BaseController end def user_params - params.require(:user).permit(:locale, chosen_languages: [], settings_attributes: UserSettings.keys) + params.require(:user).permit(:locale, :time_zone, chosen_languages: [], settings_attributes: UserSettings.keys) end end diff --git a/app/models/account.rb b/app/models/account.rb index 1d24a7ec81207f614788022fc9c4d8432384d794..8a606fd2a24f9dde935c3b4032c4ef6cfe48cdf9 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -140,6 +140,7 @@ class Account < ApplicationRecord :locale, :shows_application?, :prefers_noindex?, + :time_zone, to: :user, prefix: true, allow_nil: true diff --git a/app/models/user.rb b/app/models/user.rb index b903344be9bb52f6ed0be11b4c2466417995c967..5ee14bbdaf262b9873e494ccf816fa8a892b2853 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -40,6 +40,7 @@ # sign_up_ip :inet # role_id :bigint(8) # settings :text +# time_zone :string # class User < ApplicationRecord @@ -99,6 +100,7 @@ class User < ApplicationRecord validates_with BlacklistedEmailValidator, if: -> { ENV['EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION'] == 'true' || !confirmed? } validates_with EmailMxValidator, if: :validate_email_dns? validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create + validates :time_zone, inclusion: { in: ActiveSupport::TimeZone.all.map { |tz| tz.tzinfo.name } }, allow_blank: true # Honeypot/anti-spam fields attr_accessor :registration_form_time, :website, :confirm_password diff --git a/app/services/app_sign_up_service.rb b/app/services/app_sign_up_service.rb index 3833327bbceab5abcca2cfa682e7177f0c2aec8d..94547b61b214c5b420c60770a0dfd588947fc87b 100644 --- a/app/services/app_sign_up_service.rb +++ b/app/services/app_sign_up_service.rb @@ -35,7 +35,7 @@ class AppSignUpService < BaseService end def user_params - @params.slice(:email, :password, :agreement, :locale) + @params.slice(:email, :password, :agreement, :locale, :time_zone) end def account_params diff --git a/app/views/notification_mailer/_status.html.haml b/app/views/notification_mailer/_status.html.haml index fd65039ae989a6f6b51ab3645e4d5addf6d2d8bf..d8aa38b1128473f0995e2e283fe0eb0b9f51fc28 100644 --- a/app/views/notification_mailer/_status.html.haml +++ b/app/views/notification_mailer/_status.html.haml @@ -42,4 +42,4 @@ = link_to a.remote_url, a.remote_url %p.status-footer - = link_to l(status.created_at), web_url("@#{status.account.pretty_acct}/#{status.id}") + = link_to l(status.created_at.in_time_zone(time_zone)), web_url("@#{status.account.pretty_acct}/#{status.id}") diff --git a/app/views/notification_mailer/favourite.html.haml b/app/views/notification_mailer/favourite.html.haml index 4ec89172d96a3e47bd786adc7cd309d33f96c064..325f0aff5f7d5843e633faea6f0afddf420a9738 100644 --- a/app/views/notification_mailer/favourite.html.haml +++ b/app/views/notification_mailer/favourite.html.haml @@ -22,7 +22,7 @@ %h1= t 'notification_mailer.favourite.title' %p.lead= t('notification_mailer.favourite.body', name: @account.pretty_acct) -= render 'status', status: @status += render 'status', status: @status, time_zone: @me.user_time_zone %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/notification_mailer/mention.html.haml b/app/views/notification_mailer/mention.html.haml index 4ae9bb7b0bdf346ea1d05c76a11aa7a03719ade4..e830644c3f4bce6b2f5ebc7dcae8842f7d7ed350 100644 --- a/app/views/notification_mailer/mention.html.haml +++ b/app/views/notification_mailer/mention.html.haml @@ -22,7 +22,7 @@ %h1= t 'notification_mailer.mention.title' %p.lead= t('notification_mailer.mention.body', name: @status.account.pretty_acct) -= render 'status', status: @status += render 'status', status: @status, time_zone: @me.user_time_zone %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/notification_mailer/reblog.html.haml b/app/views/notification_mailer/reblog.html.haml index f805c79f0d19b673f4d4c0411e0b6a5012b19f51..e4f9441236b4f03f882d16d6dc3e31e44e53a639 100644 --- a/app/views/notification_mailer/reblog.html.haml +++ b/app/views/notification_mailer/reblog.html.haml @@ -22,7 +22,7 @@ %h1= t 'notification_mailer.reblog.title' %p.lead= t('notification_mailer.reblog.body', name: @account.pretty_acct) -= render 'status', status: @status += render 'status', status: @status, time_zone: @me.user_time_zone %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index af61df71b81fec3b43c010cb7d8941f9b2e5a2cd..ce3a30c5eed6a72367ef3662e10dbda0c17853b2 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -9,8 +9,11 @@ .fields-group.fields-row__column.fields-row__column-6 = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| native_locale_name(locale) }, selected: I18n.locale, hint: false .fields-group.fields-row__column.fields-row__column-6 - = f.simple_fields_for :settings, current_user.settings do |ff| - = ff.input :theme, collection: Themes.instance.names, label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_theme'), include_blank: false, hint: false + = f.input :time_zone, wrapper: :with_label, collection: ActiveSupport::TimeZone.all.map { |tz| ["(GMT#{tz.formatted_offset}) #{tz.name}", tz.tzinfo.name] }, hint: false + + .fields-group + = f.simple_fields_for :settings, current_user.settings do |ff| + = ff.input :theme, collection: Themes.instance.names, label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, label: I18n.t('simple_form.labels.defaults.setting_theme'), include_blank: false, hint: false - unless I18n.locale == :en .flash-message.translation-prompt diff --git a/app/views/user_mailer/appeal_approved.html.haml b/app/views/user_mailer/appeal_approved.html.haml index 962cab2e2cf5a2329f13108ff68018fc1a63f22a..d62789a067b59d203de45a75864a2ba89d1c3b5b 100644 --- a/app/views/user_mailer/appeal_approved.html.haml +++ b/app/views/user_mailer/appeal_approved.html.haml @@ -36,7 +36,7 @@ %tbody %tr %td.column-cell.text-center - %p= t 'user_mailer.appeal_approved.explanation', appeal_date: l(@appeal.created_at), strike_date: l(@appeal.strike.created_at) + %p= t 'user_mailer.appeal_approved.explanation', appeal_date: l(@appeal.created_at.in_time_zone(@resource.time_zone)), strike_date: l(@appeal.strike.created_at.in_time_zone(@resource.time_zone)) %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/user_mailer/appeal_approved.text.erb b/app/views/user_mailer/appeal_approved.text.erb index 290fa24c3653b829da17a3a429b5960c484f943f..99596605aa27951ae53e725fe6a5bdd570141e61 100644 --- a/app/views/user_mailer/appeal_approved.text.erb +++ b/app/views/user_mailer/appeal_approved.text.erb @@ -2,6 +2,6 @@ === -<%= t 'user_mailer.appeal_approved.explanation', appeal_date: l(@appeal.created_at), strike_date: l(@appeal.strike.created_at) %> +<%= t 'user_mailer.appeal_approved.explanation', appeal_date: l(@appeal.created_at.in_time_zone(@resource.time_zone)), strike_date: l(@appeal.strike.created_at.in_time_zone(@resource.time_zone)) %> => <%= root_url %> diff --git a/app/views/user_mailer/appeal_rejected.html.haml b/app/views/user_mailer/appeal_rejected.html.haml index c316a73fb5be4539f0cc8fd57e6f3f39fd3344f1..ae60775b01cd288e567835e1a372c4078680c1f7 100644 --- a/app/views/user_mailer/appeal_rejected.html.haml +++ b/app/views/user_mailer/appeal_rejected.html.haml @@ -36,7 +36,7 @@ %tbody %tr %td.column-cell.text-center - %p= t 'user_mailer.appeal_rejected.explanation', appeal_date: l(@appeal.created_at), strike_date: l(@appeal.strike.created_at) + %p= t 'user_mailer.appeal_rejected.explanation', appeal_date: l(@appeal.created_at.in_time_zone(@resource.time_zone)), strike_date: l(@appeal.strike.created_at.in_time_zone(@resource.time_zone)) %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/user_mailer/appeal_rejected.text.erb b/app/views/user_mailer/appeal_rejected.text.erb index f47a768181bb62ff47f4667feab423d41984bb6c..3c937771807b1f7a8ed0a1e5712589d607ec63c0 100644 --- a/app/views/user_mailer/appeal_rejected.text.erb +++ b/app/views/user_mailer/appeal_rejected.text.erb @@ -2,6 +2,6 @@ === -<%= t 'user_mailer.appeal_rejected.explanation', appeal_date: l(@appeal.created_at), strike_date: l(@appeal.strike.created_at) %> +<%= t 'user_mailer.appeal_rejected.explanation', appeal_date: l(@appeal.created_at.in_time_zone(@resource.time_zone)), strike_date: l(@appeal.strike.created_at.in_time_zone(@resource.time_zone)) %> => <%= root_url %> diff --git a/app/views/user_mailer/suspicious_sign_in.html.haml b/app/views/user_mailer/suspicious_sign_in.html.haml index e4ad500c3df64d9dcd295b269ad55c9e66587a24..6ebba3fa55bfd6504445ac89fe2f04ac0e3ab408 100644 --- a/app/views/user_mailer/suspicious_sign_in.html.haml +++ b/app/views/user_mailer/suspicious_sign_in.html.haml @@ -47,7 +47,7 @@ %strong= "#{t('sessions.browser')}:" %span{ title: @user_agent }= t 'sessions.description', browser: t("sessions.browsers.#{@detection.id}", default: @detection.id.to_s), platform: t("sessions.platforms.#{@detection.platform.id}", default: @detection.platform.id.to_s) %br/ - = l(@timestamp) + = l(@timestamp.in_time_zone(@resource.time_zone)) %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/app/views/user_mailer/suspicious_sign_in.text.erb b/app/views/user_mailer/suspicious_sign_in.text.erb index 7d2ca28e84e77ec653f02a4f21e06547ad95f237..956071e774bcb102dec0348784818f4bf5cd5792 100644 --- a/app/views/user_mailer/suspicious_sign_in.text.erb +++ b/app/views/user_mailer/suspicious_sign_in.text.erb @@ -8,7 +8,7 @@ <%= t('sessions.ip') %>: <%= @remote_ip %> <%= t('sessions.browser') %>: <%= t('sessions.description', browser: t("sessions.browsers.#{@detection.id}", default: "#{@detection.id}"), platform: t("sessions.platforms.#{@detection.platform.id}", default: "#{@detection.platform.id}")) %> -<%= l(@timestamp) %> +<%= l(@timestamp.in_time_zone(@resource.time_zone)) %> <%= t 'user_mailer.suspicious_sign_in.further_actions_html', action: t('user_mailer.suspicious_sign_in.change_password') %> diff --git a/app/views/user_mailer/warning.html.haml b/app/views/user_mailer/warning.html.haml index b9422e95028745ed5df3bcbe78966b0ceead6f04..9cb73b0feeb1dba0f861eec035181f44759ab422 100644 --- a/app/views/user_mailer/warning.html.haml +++ b/app/views/user_mailer/warning.html.haml @@ -58,7 +58,7 @@ - unless @statuses.empty? - @statuses.each_with_index do |status, i| - = render 'notification_mailer/status', status: status, i: i + 1, highlighted: true + = render 'notification_mailer/status', status: status, i: i + 1, highlighted: true, time_zone: @resource.time_zone %table.email-table{ cellspacing: 0, cellpadding: 0 } %tbody diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index f92e66e55a421b843ff35fefc4a104a71ff7c524..330c8732ffcf87730e21c85496052b693d763d12 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -297,6 +297,7 @@ en: usable: Allow posts to use this hashtag user: role: Role + time_zone: Time zone user_role: color: Badge color highlighted: Display role as badge on user profiles diff --git a/db/migrate/20230605085711_add_time_zone_to_users.rb b/db/migrate/20230605085711_add_time_zone_to_users.rb new file mode 100644 index 0000000000000000000000000000000000000000..fc6c0b091cf66e1e2fb02a4dede3e7347d3052f3 --- /dev/null +++ b/db/migrate/20230605085711_add_time_zone_to_users.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddTimeZoneToUsers < ActiveRecord::Migration[6.1] + def change + add_column :users, :time_zone, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 28d8d839023d87daf9e00d961be2ec309d6f2a7f..9866b1014957c122ed4c2b396105c978373355d4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_06_05_085710) do +ActiveRecord::Schema.define(version: 2023_06_05_085711) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1088,6 +1088,7 @@ ActiveRecord::Schema.define(version: 2023_06_05_085710) do t.boolean "skip_sign_in_token" t.bigint "role_id" t.text "settings" + t.string "time_zone" t.index ["account_id"], name: "index_users_on_account_id" t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["created_by_application_id"], name: "index_users_on_created_by_application_id", where: "(created_by_application_id IS NOT NULL)"