# frozen_string_literal: true module Playbook module PbTimestamp class Timestamp < Playbook::KitBase include ActionView::Helpers::DateHelper prop :text prop :timestamp prop :dark, type: Playbook::Props::Boolean, default: false prop :align, type: Playbook::Props::Enum, values: %w[left center right], default: "left" prop :hide_updated, type: Playbook::Props::Boolean, default: false prop :show_date, type: Playbook::Props::Boolean, default: true prop :show_timezone, type: Playbook::Props::Boolean, default: false prop :show_user, type: Playbook::Props::Boolean, default: false prop :timezone, default: "America/New_York" prop :unstyled, type: Playbook::Props::Boolean, default: false prop :variant, type: Playbook::Props::Enum, values: %w[default elapsed updated], default: "default" # Variables to use with pb_time_ago method SECS_FORTY_FIVE = 45 SECS_PER_MIN = 60 SECS_PER_HOUR = 60 * SECS_PER_MIN # 3,600 seconds SECS_PER_DAY = 24 * SECS_PER_HOUR # 86,400 seconds SECS_PER_WEEK = 7 * SECS_PER_DAY # 604,800 seconds SECS_PER_26 = 26 * SECS_PER_DAY # 26 days = 2,246,400 seconds SECS_PER_MONTH = 4 * SECS_PER_WEEK # 2,419,200 seconds SECS_PER_YEAR = 12 * SECS_PER_MONTH # 29,030,400 seconds SECS_PER_320 = 320 * SECS_PER_DAY # 320 days = 27,648,000 seconds SECS_PER_CENT = 100 * SECS_PER_YEAR # 3,153,600,000 seconds def classname generate_classname("pb_timestamp_kit", variant_class, align) end def timestamp_text case variant when "updated" format_updated_string when "elapsed" format_elapsed_string else show_date ? datetime_or_text : format_time_string end end private def format_year_string pb_date_time.to_year != DateTime.now.year.to_s ? ", #{pb_date_time.to_year}" : "" end def format_time_string "#{pb_date_time.to_hour}:#{pb_date_time.to_minutes}#{pb_date_time.to_meridian} #{format_timezone_string}".strip end def format_timezone_string timezone && show_timezone ? pb_date_time.to_timezone.to_s : "" end def format_date_string "#{pb_date_time.to_month_downcase} #{pb_date_time.to_unpadded_day}#{format_year_string}" end def format_datetime_string "#{format_date_string} · #{format_time_string}".html_safe end def format_updated_string user_string = show_user ? " by #{text}" : "" datetime_string = " on #{format_date_string} at #{format_time_string}" "Last updated#{user_string}#{datetime_string}" end def format_elapsed_string user_string = show_user ? " by #{text}" : "" datetime_string = " #{pb_time_ago(pb_date_time.convert_to_timestamp)} ago" datetime_string[1] = hide_updated ? datetime_string[1].upcase : datetime_string[1] updated_string = hide_updated ? "" : "Last updated" "#{updated_string}#{user_string}#{datetime_string}" end def pb_time_ago(value) time_ago = DateTime.now.to_i - value.to_i case time_ago when (0...SECS_FORTY_FIVE) "a few seconds" when (SECS_FORTY_FIVE...SECS_PER_MIN) "a minute" when (SECS_PER_MIN...SECS_PER_HOUR) time = time_ago / SECS_PER_MIN time == 1 ? "a minute" : "#{time_ago / SECS_PER_MIN} minutes" when (SECS_PER_HOUR...SECS_PER_DAY) time = time_ago / SECS_PER_HOUR time == 1 ? "an hour" : "#{time_ago / SECS_PER_HOUR} hours" when (SECS_PER_DAY...SECS_PER_WEEK) time = time_ago / SECS_PER_DAY time == 1 ? "a day" : "#{time_ago / SECS_PER_DAY} days" when (SECS_PER_WEEK...SECS_PER_26) time = time_ago / SECS_PER_WEEK time == 1 ? "a week" : "#{time_ago / SECS_PER_WEEK} weeks" when (SECS_PER_26...SECS_PER_MONTH) "a month" when (SECS_PER_MONTH...SECS_PER_320) time = time_ago / SECS_PER_MONTH time == 1 ? "a month" : "#{time_ago / SECS_PER_MONTH} months" when (SECS_PER_320...SECS_PER_YEAR) "a year" when (SECS_PER_YEAR...SECS_PER_CENT) time = time_ago / SECS_PER_YEAR time == 1 ? "a year" : "#{time_ago / SECS_PER_YEAR} years" end end def datetime_or_text timestamp ? format_datetime_string : text end def pb_date_time Playbook::PbKit::PbDateTime.new(timestamp, timezone) end def variant_class case variant when "updated" "updated" when "elapsed" "elapsed" end end end end end