Add time zone preference (#25342)

This commit is contained in:
Eugen Rochko 2023-06-10 03:29:37 +02:00 committed by GitHub
parent 16dd3f08c1
commit 4c9406bdb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 32 additions and 17 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 %>

View File

@ -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

View File

@ -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 %>

View File

@ -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

View File

@ -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') %>

View File

@ -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

View File

@ -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

View 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

View File

@ -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)"