rails-diff-time 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0df096d6ed881a33af5f513b00298f22b6e689d95b0f473682941e8d6eadc8a5
4
- data.tar.gz: e325fa3d700ef58840ca6eaca3bd0c5148aaf4c809136ca4693b174966ed9829
3
+ metadata.gz: 9748702954e4f33f487e7ad5a8c657b89bbcc9966cfe384f0791fb2c60428b6e
4
+ data.tar.gz: dcd1fee4443c63efeab7d4acc4742a2e3dd9e042ec0ce4fae7a8c6fd68809e51
5
5
  SHA512:
6
- metadata.gz: 556b016fb84ba4f42836b2cbe46db4691e50b96665a125314791e8aff55e7df0abfb3f30a1fbeca6aeb972c890672a750a376b2473571b43527de64b9f080100
7
- data.tar.gz: a3c3921bf4231dcccd71a0979b7aff25bcefbf9f845906cb4b724e23f677ddec18496ca2c72250a1af62616a3104175fce2e0b847bfa965f41b88be299c6862c
6
+ metadata.gz: 3690429964d2704bf55479a1fae0083f46924a7098d3e24aa81899f3a0cebfe3f83feca3ae8ccf854e16928fae4799ce88e559561a49dc67d178d0aabb5c4aaf
7
+ data.tar.gz: ca7e1e72f9d52fa0da0fcceaa28921f73b90453098beea0ae7723c1bf6287cc94826a588a7bd182790871477ce6905e7a8bc20aef35fe83e39b32d663212d575
@@ -1,8 +1,14 @@
1
1
  <%
2
- _element_name ||= locals[:element_name] || "span"
3
- _diff_time = locals[:diff_time]
4
- _attributes ||= locals[:attributes] || {}
2
+ element_name ||= locals[:element_name] || "span"
3
+ diff_time = locals[:diff_time]
4
+ attributes ||= locals[:attributes] || {}
5
+ certain_time = locals[:certain_time]
6
+ auto_update = locals[:auto_update]
7
+
8
+ if auto_update
9
+ attributes[:data] ||= {}
10
+ attributes[:data][:diff_time_target] = "display"
11
+ attributes[:data][:certain_time] = certain_time.iso8601
12
+ end
5
13
  %>
6
- <% if _diff_time %>
7
- <%= content_tag(_element_name.to_sym, _diff_time, _attributes) %>
8
- <% end %>
14
+ <%= content_tag(element_name.to_sym, diff_time, attributes) %>
@@ -14,4 +14,4 @@ module RailsDiffTime
14
14
  end
15
15
  end
16
16
  end
17
- end
17
+ end
@@ -2,32 +2,229 @@
2
2
 
3
3
  module RailsDiffTime
4
4
  # Helper methods for displaying time differences in a human-readable format.
5
- #
6
- # This module provides methods to format time differences as relative strings
7
- # (e.g., "2 hours ago", "3 days later") and integrates with Rails views.
8
- # The helpers can be used directly in templates or through the provided
9
- # render helper method.
10
- #
11
- # @example Usage in a Rails view
12
- # <%= diff_time(user.created_at) %>
13
- # <%= diff_time(event.start_time, "div", class: "timestamp") %>
14
5
  module Helpers
15
- def diff_time(certain_time, element_name = "span", attributes = {})
16
- render "rails-diff-time/diff_time", locals: {
6
+ def diff_time(certain_time, element_name = "span", attributes = {}, auto_update: false)
7
+ return "" if certain_time.nil?
8
+
9
+ result = render "rails-diff-time/diff_time", locals: {
17
10
  diff_time: diff_time_str(certain_time),
18
11
  element_name: element_name,
19
- attributes: attributes
12
+ attributes: attributes,
13
+ certain_time: certain_time,
14
+ auto_update: auto_update
20
15
  }
16
+
17
+ # If auto_update is enabled and the script has not been included yet
18
+ if auto_update && !@_diff_time_script_included
19
+ @_diff_time_script_included = true
20
+ result = result + diff_time_script_tag
21
+ end
22
+
23
+ result
21
24
  end
22
25
 
23
26
  private
24
27
 
28
+ def diff_time_script_tag
29
+ javascript_tag do
30
+ <<~JAVASCRIPT.html_safe
31
+ (function() {
32
+ 'use strict';
33
+
34
+ class DiffTimeUpdater {
35
+ constructor() {
36
+ this.updateInterval = 60000;
37
+ this.elements = [];
38
+ this.timerId = null;
39
+ }
40
+
41
+ init() {
42
+ this.findElements();
43
+ if (this.elements.length > 0) {
44
+ this.startAutoUpdate();
45
+ }
46
+ }
47
+
48
+ findElements() {
49
+ this.elements = Array.from(
50
+ document.querySelectorAll('[data-diff-time-target="display"]')
51
+ );
52
+ }
53
+
54
+ startAutoUpdate() {
55
+ if (this.timerId) clearInterval(this.timerId);
56
+ this.timerId = setInterval(() => this.updateAll(), this.updateInterval);
57
+ }
58
+
59
+ updateAll() {
60
+ this.elements.forEach(element => this.updateElement(element));
61
+ }
62
+
63
+ updateElement(element) {
64
+ const certainTimeStr = element.dataset.certainTime;
65
+ if (!certainTimeStr) return;
66
+ const certainTime = new Date(certainTimeStr);
67
+ const diffTimeStr = this.calculateDiffTime(certainTime);
68
+ element.textContent = diffTimeStr;
69
+ }
70
+
71
+ calculateDiffTime(certainTime) {
72
+ const now = new Date();
73
+ const diff = certainTime - now;
74
+ const differenceInSeconds = Math.abs(diff) / 1000;
75
+
76
+ if (differenceInSeconds <= 5) return "now";
77
+
78
+ const isLater = diff > 0;
79
+
80
+ if (differenceInSeconds >= this.yearInSeconds()) {
81
+ return this.formatYears(differenceInSeconds, isLater);
82
+ } else if (differenceInSeconds >= this.monthInSeconds()) {
83
+ return this.formatMonths(differenceInSeconds, isLater);
84
+ } else if (differenceInSeconds >= this.weekInSeconds()) {
85
+ return this.formatWeeks(differenceInSeconds, isLater);
86
+ } else if (differenceInSeconds >= this.dayInSeconds()) {
87
+ return this.formatDays(differenceInSeconds, isLater);
88
+ } else if (differenceInSeconds >= this.hourInSeconds()) {
89
+ return this.formatHours(differenceInSeconds, isLater);
90
+ } else if (differenceInSeconds >= this.minuteInSeconds()) {
91
+ return this.formatMinutes(differenceInSeconds, isLater);
92
+ } else {
93
+ return this.formatSeconds(differenceInSeconds, isLater);
94
+ }
95
+ }
96
+
97
+ formatYears(seconds, isLater) {
98
+ const years = Math.floor(seconds / this.yearInSeconds());
99
+ let remaining = seconds - (years * this.yearInSeconds());
100
+ let result = this.timeStr(years, "year");
101
+
102
+ if (remaining >= this.monthInSeconds()) {
103
+ const months = Math.floor(remaining / this.monthInSeconds());
104
+ remaining -= months * this.monthInSeconds();
105
+ result += ` ${this.timeStr(months, "month")}`;
106
+
107
+ if (remaining >= this.dayInSeconds()) {
108
+ const days = Math.floor(remaining / this.dayInSeconds());
109
+ result += ` ${this.timeStr(days, "day")}`;
110
+ }
111
+ }
112
+ return `${result} ${this.agoOrLater(isLater)}`;
113
+ }
114
+
115
+ formatMonths(seconds, isLater) {
116
+ const months = Math.floor(seconds / this.monthInSeconds());
117
+ const remaining = seconds - (months * this.monthInSeconds());
118
+ let result = this.timeStr(months, "month");
119
+
120
+ if (remaining >= this.dayInSeconds()) {
121
+ const days = Math.floor(remaining / this.dayInSeconds());
122
+ result += ` ${this.timeStr(days, "day")}`;
123
+ }
124
+ return `${result} ${this.agoOrLater(isLater)}`;
125
+ }
126
+
127
+ formatWeeks(seconds, isLater) {
128
+ const weeks = Math.floor(seconds / this.weekInSeconds());
129
+ return `${this.timeStr(weeks, "week")} ${this.agoOrLater(isLater)}`;
130
+ }
131
+
132
+ formatDays(seconds, isLater) {
133
+ const days = Math.floor(seconds / this.dayInSeconds());
134
+ return `${this.timeStr(days, "day")} ${this.agoOrLater(isLater)}`;
135
+ }
136
+
137
+ formatHours(seconds, isLater) {
138
+ const hours = Math.floor(seconds / this.hourInSeconds());
139
+ const remaining = seconds - (hours * this.hourInSeconds());
140
+ let result = this.timeStr(hours, "hour");
141
+
142
+ if (remaining >= this.minuteInSeconds()) {
143
+ const minutes = Math.floor(remaining / this.minuteInSeconds());
144
+ result += ` ${this.timeStr(minutes, "minute")}`;
145
+ }
146
+ return `${result} ${this.agoOrLater(isLater)}`;
147
+ }
148
+
149
+ formatMinutes(seconds, isLater) {
150
+ const minutes = Math.floor(seconds / this.minuteInSeconds());
151
+ const remaining = seconds - (minutes * this.minuteInSeconds());
152
+ let result = this.timeStr(minutes, "minute");
153
+
154
+ if (remaining > 0) {
155
+ const secs = Math.floor(remaining);
156
+ result += ` ${this.timeStr(secs, "second")}`;
157
+ }
158
+ return `${result} ${this.agoOrLater(isLater)}`;
159
+ }
160
+
161
+ formatSeconds(seconds, isLater) {
162
+ const secs = Math.floor(seconds);
163
+ return `${this.timeStr(secs, "second")} ${this.agoOrLater(isLater)}`;
164
+ }
165
+
166
+ yearInSeconds() { return 365.25 * 24 * 3600; }
167
+ monthInSeconds() { return 30 * 24 * 3600; }
168
+ weekInSeconds() { return 7 * 24 * 3600; }
169
+ dayInSeconds() { return 24 * 3600; }
170
+ hourInSeconds() { return 3600; }
171
+ minuteInSeconds() { return 60; }
172
+
173
+ agoOrLater(isLater) { return isLater ? "later" : "ago"; }
174
+
175
+ timeStr(count, singular) {
176
+ const plural = singular + "s";
177
+ return `${count} ${count === 1 ? singular : plural}`;
178
+ }
179
+
180
+ destroy() {
181
+ if (this.timerId) {
182
+ clearInterval(this.timerId);
183
+ this.timerId = null;
184
+ }
185
+ this.elements = [];
186
+ }
187
+ }
188
+
189
+ let updater = null;
190
+
191
+ function initUpdater() {
192
+ if (updater) updater.destroy();
193
+ updater = new DiffTimeUpdater();
194
+ updater.init();
195
+ }
196
+
197
+ if (document.readyState === 'loading') {
198
+ document.addEventListener('DOMContentLoaded', initUpdater);
199
+ } else {
200
+ initUpdater();
201
+ }
202
+
203
+ document.addEventListener('turbolinks:load', initUpdater);
204
+ document.addEventListener('turbo:load', initUpdater);
205
+
206
+ document.addEventListener('turbolinks:before-cache', function() {
207
+ if (updater) updater.destroy();
208
+ });
209
+
210
+ document.addEventListener('turbo:before-cache', function() {
211
+ if (updater) updater.destroy();
212
+ });
213
+
214
+ window.RailsDiffTime = {
215
+ updater: updater,
216
+ DiffTimeUpdater: DiffTimeUpdater
217
+ };
218
+ })();
219
+ JAVASCRIPT
220
+ end
221
+ end
222
+
25
223
  def diff_time_str(certain_time)
26
224
  now = ::Time.now
27
225
  diff = certain_time - now
28
226
  difference_in_seconds = diff.abs
29
227
 
30
- # Display "now" if within 5 seconds
31
228
  return "now" if difference_in_seconds <= 5
32
229
 
33
230
  case difference_in_seconds
@@ -118,13 +315,12 @@ module RailsDiffTime
118
315
  "#{time_str(seconds, "second")} #{ago_or_later(diff)}"
119
316
  end
120
317
 
121
- # Time unit constant methods
122
318
  def year_in_seconds
123
- 365.25 * 24 * 3600 # Considering leap years
319
+ 365.25 * 24 * 3600
124
320
  end
125
321
 
126
322
  def month_in_seconds
127
- 30 * 24 * 3600 # Average 30 days
323
+ 30 * 24 * 3600
128
324
  end
129
325
 
130
326
  def week_in_seconds
@@ -143,7 +339,6 @@ module RailsDiffTime
143
339
  60
144
340
  end
145
341
 
146
- # Threshold methods
147
342
  def year_threshold
148
343
  year_in_seconds
149
344
  end
@@ -177,3 +372,4 @@ module RailsDiffTime
177
372
  end
178
373
  end
179
374
  end
375
+
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsDiffTime
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.5"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-diff-time
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - dhq_boiler
@@ -10,8 +10,10 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: A Rails gem that provides helper methods to display time differences
13
- in a human-readable format (e.g., '2 hours ago', '3 days later'). Integrates seamlessly
14
- with Rails views and supports various time units from seconds to years.
13
+ in a human-readable format (e.g., '2 hours ago', '3 days later'). Features include
14
+ auto-updating timestamps every minute without page reload, no JavaScript imports
15
+ required, and seamless integration with Rails views. Supports various time units
16
+ from seconds to years.
15
17
  email:
16
18
  - dhq_boiler@live.jp
17
19
  executables: []
@@ -53,5 +55,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
55
  requirements: []
54
56
  rubygems_version: 3.6.9
55
57
  specification_version: 4
56
- summary: Rails helper for displaying human-readable time differences
58
+ summary: Rails helper for displaying human-readable time differences with auto-update
57
59
  test_files: []