rails-diff-time 0.1.4 → 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: 908929488b5de5bb6d8dcdfdf0f16b7081d02b3e2873e3969884a64c7400d674
4
- data.tar.gz: bbf8fc3135e4e1afcacd7299e6f43775337f5798dacb712505d5020b02a14a48
3
+ metadata.gz: 9748702954e4f33f487e7ad5a8c657b89bbcc9966cfe384f0791fb2c60428b6e
4
+ data.tar.gz: dcd1fee4443c63efeab7d4acc4742a2e3dd9e042ec0ce4fae7a8c6fd68809e51
5
5
  SHA512:
6
- metadata.gz: 40e116660189676a4a8636e9d7ec9375ba7f715ec9e72cdb4bd192d824b26b8a4eae5ffade00a493f232425c801e8ac8d405d0713ce318031cedaec794208464
7
- data.tar.gz: 82e04671eba7400273228f7ed916397da2a52fb6559160d10ac1eb5bdae1ca5d1c07944860be28405fa437eaf1ebc4c1ff563c0d19c31eee6f29ae7afb395ce6
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) %>
@@ -2,34 +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 = {})
6
+ def diff_time(certain_time, element_name = "span", attributes = {}, auto_update: false)
16
7
  return "" if certain_time.nil?
17
8
 
18
- render "rails-diff-time/diff_time", locals: {
9
+ result = render "rails-diff-time/diff_time", locals: {
19
10
  diff_time: diff_time_str(certain_time),
20
11
  element_name: element_name,
21
- attributes: attributes
12
+ attributes: attributes,
13
+ certain_time: certain_time,
14
+ auto_update: auto_update
22
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
23
24
  end
24
25
 
25
26
  private
26
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
+
27
223
  def diff_time_str(certain_time)
28
224
  now = ::Time.now
29
225
  diff = certain_time - now
30
226
  difference_in_seconds = diff.abs
31
227
 
32
- # Display "now" if within 5 seconds
33
228
  return "now" if difference_in_seconds <= 5
34
229
 
35
230
  case difference_in_seconds
@@ -120,13 +315,12 @@ module RailsDiffTime
120
315
  "#{time_str(seconds, "second")} #{ago_or_later(diff)}"
121
316
  end
122
317
 
123
- # Time unit constant methods
124
318
  def year_in_seconds
125
- 365.25 * 24 * 3600 # Considering leap years
319
+ 365.25 * 24 * 3600
126
320
  end
127
321
 
128
322
  def month_in_seconds
129
- 30 * 24 * 3600 # Average 30 days
323
+ 30 * 24 * 3600
130
324
  end
131
325
 
132
326
  def week_in_seconds
@@ -145,7 +339,6 @@ module RailsDiffTime
145
339
  60
146
340
  end
147
341
 
148
- # Threshold methods
149
342
  def year_threshold
150
343
  year_in_seconds
151
344
  end
@@ -179,3 +372,4 @@ module RailsDiffTime
179
372
  end
180
373
  end
181
374
  end
375
+
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsDiffTime
4
- VERSION = "0.1.4"
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.4
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: []