Add time zone preference (#25342)
This commit is contained in:
		| @@ -90,7 +90,7 @@ class Api::V1::AccountsController < Api::BaseController | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   def account_params |   def account_params | ||||||
|     params.permit(:username, :email, :password, :agreement, :locale, :reason) |     params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def check_enabled_registrations |   def check_enabled_registrations | ||||||
|   | |||||||
| @@ -19,6 +19,6 @@ class Settings::Preferences::BaseController < Settings::BaseController | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   def user_params |   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 | ||||||
| end | end | ||||||
|   | |||||||
| @@ -140,6 +140,7 @@ class Account < ApplicationRecord | |||||||
|            :locale, |            :locale, | ||||||
|            :shows_application?, |            :shows_application?, | ||||||
|            :prefers_noindex?, |            :prefers_noindex?, | ||||||
|  |            :time_zone, | ||||||
|            to: :user, |            to: :user, | ||||||
|            prefix: true, |            prefix: true, | ||||||
|            allow_nil: true |            allow_nil: true | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ | |||||||
| #  sign_up_ip                :inet | #  sign_up_ip                :inet | ||||||
| #  role_id                   :bigint(8) | #  role_id                   :bigint(8) | ||||||
| #  settings                  :text | #  settings                  :text | ||||||
|  | #  time_zone                 :string | ||||||
| # | # | ||||||
|  |  | ||||||
| class User < ApplicationRecord | 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 BlacklistedEmailValidator, if: -> { ENV['EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION'] == 'true' || !confirmed? } | ||||||
|   validates_with EmailMxValidator, if: :validate_email_dns? |   validates_with EmailMxValidator, if: :validate_email_dns? | ||||||
|   validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create |   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 |   # Honeypot/anti-spam fields | ||||||
|   attr_accessor :registration_form_time, :website, :confirm_password |   attr_accessor :registration_form_time, :website, :confirm_password | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ class AppSignUpService < BaseService | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   def user_params |   def user_params | ||||||
|     @params.slice(:email, :password, :agreement, :locale) |     @params.slice(:email, :password, :agreement, :locale, :time_zone) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def account_params |   def account_params | ||||||
|   | |||||||
| @@ -42,4 +42,4 @@ | |||||||
|                                         = link_to a.remote_url, a.remote_url |                                         = link_to a.remote_url, a.remote_url | ||||||
|  |  | ||||||
|                               %p.status-footer |                               %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}") | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ | |||||||
|                               %h1= t 'notification_mailer.favourite.title' |                               %h1= t 'notification_mailer.favourite.title' | ||||||
|                               %p.lead= t('notification_mailer.favourite.body', name: @account.pretty_acct) |                               %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 } | %table.email-table{ cellspacing: 0, cellpadding: 0 } | ||||||
|   %tbody |   %tbody | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ | |||||||
|                               %h1= t 'notification_mailer.mention.title' |                               %h1= t 'notification_mailer.mention.title' | ||||||
|                               %p.lead= t('notification_mailer.mention.body', name: @status.account.pretty_acct) |                               %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 } | %table.email-table{ cellspacing: 0, cellpadding: 0 } | ||||||
|   %tbody |   %tbody | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ | |||||||
|                               %h1= t 'notification_mailer.reblog.title' |                               %h1= t 'notification_mailer.reblog.title' | ||||||
|                               %p.lead= t('notification_mailer.reblog.body', name: @account.pretty_acct) |                               %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 } | %table.email-table{ cellspacing: 0, cellpadding: 0 } | ||||||
|   %tbody |   %tbody | ||||||
|   | |||||||
| @@ -9,8 +9,11 @@ | |||||||
|     .fields-group.fields-row__column.fields-row__column-6 |     .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 |       = 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 |     .fields-group.fields-row__column.fields-row__column-6 | ||||||
|       = f.simple_fields_for :settings, current_user.settings do |ff| |       = f.input :time_zone, wrapper: :with_label, collection: ActiveSupport::TimeZone.all.map { |tz| ["(GMT#{tz.formatted_offset}) #{tz.name}", tz.tzinfo.name] }, hint: false | ||||||
|         = 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 |  | ||||||
|  |   .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 |   - unless I18n.locale == :en | ||||||
|     .flash-message.translation-prompt |     .flash-message.translation-prompt | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ | |||||||
|                         %tbody |                         %tbody | ||||||
|                           %tr |                           %tr | ||||||
|                             %td.column-cell.text-center |                             %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 } | %table.email-table{ cellspacing: 0, cellpadding: 0 } | ||||||
|   %tbody |   %tbody | ||||||
|   | |||||||
| @@ -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 %> | => <%= root_url %> | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ | |||||||
|                         %tbody |                         %tbody | ||||||
|                           %tr |                           %tr | ||||||
|                             %td.column-cell.text-center |                             %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 } | %table.email-table{ cellspacing: 0, cellpadding: 0 } | ||||||
|   %tbody |   %tbody | ||||||
|   | |||||||
| @@ -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 %> | => <%= root_url %> | ||||||
|   | |||||||
| @@ -47,7 +47,7 @@ | |||||||
|                                 %strong= "#{t('sessions.browser')}:" |                                 %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) |                                 %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/ |                                 %br/ | ||||||
|                                 = l(@timestamp) |                                 = l(@timestamp.in_time_zone(@resource.time_zone)) | ||||||
|  |  | ||||||
| %table.email-table{ cellspacing: 0, cellpadding: 0 } | %table.email-table{ cellspacing: 0, cellpadding: 0 } | ||||||
|   %tbody |   %tbody | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|  |  | ||||||
| <%= t('sessions.ip') %>: <%= @remote_ip %> | <%= 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}")) %> | <%= 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') %> | <%= t 'user_mailer.suspicious_sign_in.further_actions_html', action: t('user_mailer.suspicious_sign_in.change_password') %> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -58,7 +58,7 @@ | |||||||
|  |  | ||||||
| - unless @statuses.empty? | - unless @statuses.empty? | ||||||
|   - @statuses.each_with_index do |status, i| |   - @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 } | %table.email-table{ cellspacing: 0, cellpadding: 0 } | ||||||
|   %tbody |   %tbody | ||||||
|   | |||||||
| @@ -297,6 +297,7 @@ en: | |||||||
|         usable: Allow posts to use this hashtag |         usable: Allow posts to use this hashtag | ||||||
|       user: |       user: | ||||||
|         role: Role |         role: Role | ||||||
|  |         time_zone: Time zone | ||||||
|       user_role: |       user_role: | ||||||
|         color: Badge color |         color: Badge color | ||||||
|         highlighted: Display role as badge on user profiles |         highlighted: Display role as badge on user profiles | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								db/migrate/20230605085711_add_time_zone_to_users.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								db/migrate/20230605085711_add_time_zone_to_users.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | # frozen_string_literal: true | ||||||
|  |  | ||||||
|  | class AddTimeZoneToUsers < ActiveRecord::Migration[6.1] | ||||||
|  |   def change | ||||||
|  |     add_column :users, :time_zone, :string | ||||||
|  |   end | ||||||
|  | end | ||||||
| @@ -10,7 +10,7 @@ | |||||||
| # | # | ||||||
| # It's strongly recommended that you check this file into your version control system. | # 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 |   # These are extensions that must be enabled in order to support this database | ||||||
|   enable_extension "plpgsql" |   enable_extension "plpgsql" | ||||||
| @@ -1088,6 +1088,7 @@ ActiveRecord::Schema.define(version: 2023_06_05_085710) do | |||||||
|     t.boolean "skip_sign_in_token" |     t.boolean "skip_sign_in_token" | ||||||
|     t.bigint "role_id" |     t.bigint "role_id" | ||||||
|     t.text "settings" |     t.text "settings" | ||||||
|  |     t.string "time_zone" | ||||||
|     t.index ["account_id"], name: "index_users_on_account_id" |     t.index ["account_id"], name: "index_users_on_account_id" | ||||||
|     t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true |     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)" |     t.index ["created_by_application_id"], name: "index_users_on_created_by_application_id", where: "(created_by_application_id IS NOT NULL)" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user