diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index d680b9d4d65..779ac6ea54c 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -115,7 +115,7 @@ class Admin::UsersController < Admin::StaffController "user.already_suspended", staff: suspend_record.acting_user.username, time_ago: - FreedomPatches::Rails4.time_ago_in_words( + AgeWords.time_ago_in_words( suspend_record.created_at, true, scope: :"datetime.distance_in_words_verbose", @@ -368,7 +368,7 @@ class Admin::UsersController < Admin::StaffController "user.already_silenced", staff: silenced_record.acting_user.username, time_ago: - FreedomPatches::Rails4.time_ago_in_words( + AgeWords.time_ago_in_words( silenced_record.created_at, true, scope: :"datetime.distance_in_words_verbose", diff --git a/app/controllers/composer_messages_controller.rb b/app/controllers/composer_messages_controller.rb index 893a30dec5e..f3fffc7fd8e 100644 --- a/app/controllers/composer_messages_controller.rb +++ b/app/controllers/composer_messages_controller.rb @@ -36,7 +36,7 @@ class ComposerMessagesController < ApplicationController user_count: user_count, usernames: users, time_ago: - FreedomPatches::Rails4.time_ago_in_words( + AgeWords.time_ago_in_words( SiteSetting.pm_warn_user_last_seen_months_ago.month.ago, true, scope: :"datetime.distance_in_words_verbose", diff --git a/lib/age_words.rb b/lib/age_words.rb index c9bfbfec281..0f6504bcc12 100644 --- a/lib/age_words.rb +++ b/lib/age_words.rb @@ -6,7 +6,91 @@ module AgeWords "—" else now = Time.now - FreedomPatches::Rails4.distance_of_time_in_words(now, now + secs) + distance_of_time_in_words(now, now + secs) end end + + # Sam: This has now forked of rails. Trouble is we would never like to use "about 1 month" ever, we only want months for 2 or more months. + # Backporting a fix to rails itself may get too complex + def self.distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {}) + options = { scope: :"datetime.distance_in_words" }.merge!(options) + + from_time = from_time.to_time if from_time.respond_to?(:to_time) + to_time = to_time.to_time if to_time.respond_to?(:to_time) + distance = (to_time.to_f - from_time.to_f).abs + distance_in_minutes = (distance / 60.0).round + distance_in_seconds = distance.round + + I18n.with_options locale: options[:locale], scope: options[:scope] do |locale| + case distance_in_minutes + when 0..1 + unless include_seconds + return( + ( + if distance_in_minutes == 0 + locale.t(:less_than_x_minutes, count: 1) + else + locale.t(:x_minutes, count: distance_in_minutes) + end + ) + ) + end + + case distance_in_seconds + when 0..4 + locale.t :less_than_x_seconds, count: 5 + when 5..9 + locale.t :less_than_x_seconds, count: 10 + when 10..19 + locale.t :less_than_x_seconds, count: 20 + when 20..39 + locale.t :half_a_minute + when 40..59 + locale.t :less_than_x_minutes, count: 1 + else + locale.t :x_minutes, count: 1 + end + when 2..44 + locale.t :x_minutes, count: distance_in_minutes + when 45..89 + locale.t :about_x_hours, count: 1 + when 90..1439 + locale.t :about_x_hours, count: (distance_in_minutes.to_f / 60.0).round + when 1440..2519 + locale.t :x_days, count: 1 + + # this is were we diverge from Rails + when 2520..129_599 + locale.t :x_days, count: (distance_in_minutes.to_f / 1440.0).round + when 129_600..525_599 + locale.t :x_months, count: (distance_in_minutes.to_f / 43200.0).round + else + fyear = from_time.year + fyear += 1 if from_time.month >= 3 + tyear = to_time.year + tyear -= 1 if to_time.month < 3 + leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count { |x| Date.leap?(x) } + minute_offset_for_leap_year = leap_years * 1440 + # Discount the leap year days when calculating year distance. + # e.g. if there are 20 leap year days between 2 dates having the same day + # and month then the based on 365 days calculation + # the distance in years will come out to over 80 years when in written + # english it would read better as about 80 years. + minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year + remainder = (minutes_with_offset % 525_600) + distance_in_years = (minutes_with_offset / 525_600) + if remainder < 131_400 + locale.t(:about_x_years, count: distance_in_years) + elsif remainder < 394_200 + locale.t(:over_x_years, count: distance_in_years) + else + locale.t(:almost_x_years, count: distance_in_years + 1) + end + end + end + end + + def self.time_ago_in_words(from_time, include_seconds = false, options = {}) + distance_of_time_in_words(from_time, Time.now, include_seconds, options) + end end diff --git a/lib/composer_messages_finder.rb b/lib/composer_messages_finder.rb index 4bba013a5c0..01b94cf896a 100644 --- a/lib/composer_messages_finder.rb +++ b/lib/composer_messages_finder.rb @@ -270,7 +270,7 @@ class ComposerMessagesFinder I18n.t( "education.reviving_old_topic", time_ago: - FreedomPatches::Rails4.time_ago_in_words( + AgeWords.time_ago_in_words( @topic.last_posted_at, false, scope: :"datetime.distance_in_words_verbose", diff --git a/lib/freedom_patches/rails4.rb b/lib/freedom_patches/rails4.rb index 806813b7c87..e5751d63130 100644 --- a/lib/freedom_patches/rails4.rb +++ b/lib/freedom_patches/rails4.rb @@ -1,95 +1,27 @@ # frozen_string_literal: true -# Sam: This has now forked of rails. Trouble is we would never like to use "about 1 month" ever, we only want months for 2 or more months. -# -# Backporting a fix to rails itself may get too complex module FreedomPatches module Rails4 - def self.distance_of_time_in_words( - from_time, - to_time = 0, - include_seconds = false, - options = {} - ) - options = { scope: :"datetime.distance_in_words" }.merge!(options) + def self.distance_of_time_in_words(*args) + Discourse.deprecate( + "FreedomPatches::Rails4.distance_of_time_in_words has moved to AgeWords.distance_of_time_in_words", + output_in_test: true, + since: "3.1.0.beta5", + drop_from: "3.2.0.beta1", + ) - from_time = from_time.to_time if from_time.respond_to?(:to_time) - to_time = to_time.to_time if to_time.respond_to?(:to_time) - distance = (to_time.to_f - from_time.to_f).abs - distance_in_minutes = (distance / 60.0).round - distance_in_seconds = distance.round - - I18n.with_options locale: options[:locale], scope: options[:scope] do |locale| - case distance_in_minutes - when 0..1 - unless include_seconds - return( - ( - if distance_in_minutes == 0 - locale.t(:less_than_x_minutes, count: 1) - else - locale.t(:x_minutes, count: distance_in_minutes) - end - ) - ) - end - - case distance_in_seconds - when 0..4 - locale.t :less_than_x_seconds, count: 5 - when 5..9 - locale.t :less_than_x_seconds, count: 10 - when 10..19 - locale.t :less_than_x_seconds, count: 20 - when 20..39 - locale.t :half_a_minute - when 40..59 - locale.t :less_than_x_minutes, count: 1 - else - locale.t :x_minutes, count: 1 - end - when 2..44 - locale.t :x_minutes, count: distance_in_minutes - when 45..89 - locale.t :about_x_hours, count: 1 - when 90..1439 - locale.t :about_x_hours, count: (distance_in_minutes.to_f / 60.0).round - when 1440..2519 - locale.t :x_days, count: 1 - - # this is were we diverge from Rails - when 2520..129_599 - locale.t :x_days, count: (distance_in_minutes.to_f / 1440.0).round - when 129_600..525_599 - locale.t :x_months, count: (distance_in_minutes.to_f / 43200.0).round - else - fyear = from_time.year - fyear += 1 if from_time.month >= 3 - tyear = to_time.year - tyear -= 1 if to_time.month < 3 - leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count { |x| Date.leap?(x) } - minute_offset_for_leap_year = leap_years * 1440 - # Discount the leap year days when calculating year distance. - # e.g. if there are 20 leap year days between 2 dates having the same day - # and month then the based on 365 days calculation - # the distance in years will come out to over 80 years when in written - # english it would read better as about 80 years. - minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year - remainder = (minutes_with_offset % 525_600) - distance_in_years = (minutes_with_offset / 525_600) - if remainder < 131_400 - locale.t(:about_x_years, count: distance_in_years) - elsif remainder < 394_200 - locale.t(:over_x_years, count: distance_in_years) - else - locale.t(:almost_x_years, count: distance_in_years + 1) - end - end - end + AgeWords.distance_of_time_in_words(*args) end - def self.time_ago_in_words(from_time, include_seconds = false, options = {}) - distance_of_time_in_words(from_time, Time.now, include_seconds, options) + def self.time_ago_in_words(*args) + Discourse.deprecate( + "FreedomPatches::Rails4.time_ago_in_words has moved to AgeWords.time_ago_in_words", + output_in_test: true, + since: "3.1.0.beta5", + drop_from: "3.2.0.beta1", + ) + + AgeWords.time_ago_in_words(*args) end end end diff --git a/spec/requests/admin/users_controller_spec.rb b/spec/requests/admin/users_controller_spec.rb index c975ae5ee12..bdb6593e017 100644 --- a/spec/requests/admin/users_controller_spec.rb +++ b/spec/requests/admin/users_controller_spec.rb @@ -302,7 +302,7 @@ RSpec.describe Admin::UsersController do "user.already_suspended", staff: admin.username, time_ago: - FreedomPatches::Rails4.time_ago_in_words( + AgeWords.time_ago_in_words( user.suspend_record.created_at, true, scope: :"datetime.distance_in_words_verbose", @@ -1539,7 +1539,7 @@ RSpec.describe Admin::UsersController do "user.already_silenced", staff: admin.username, time_ago: - FreedomPatches::Rails4.time_ago_in_words( + AgeWords.time_ago_in_words( user.silenced_record.created_at, true, scope: :"datetime.distance_in_words_verbose",