rails-diff-time 0.1.4 → 0.2.0
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 +4 -4
- data/.rubocop.yml +1 -0
- data/README.md +82 -6
- data/app/views/rails-diff-time/_diff_time.html.erb +12 -6
- data/lib/rails/diff/time/helpers.rb +210 -17
- data/lib/rails/diff/time/version.rb +1 -1
- metadata +7 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f500ef502d22be1eb93fe920650122bdd370b5799788e00180235a48afa17ce1
|
|
4
|
+
data.tar.gz: 0b954d61dcfbc5c431a8ea9a85ea996bac0a71470dc6db8dafb69e77d4c88813
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b515308f6f0ace59434dd0ee7be048696fbdddfe196d02198fb7cfd8d8ca7625195d5867dd3b3e287bf1bdc40f01bd92d6667b1295ff9e0c06edba1cdfc9b0e4
|
|
7
|
+
data.tar.gz: ee2d795c5307826898c38ca91421d106db62e4d0592a9c4ceebbf9ef34a1edb06970e2ab246b5c8e15ea1df60c5303d442f213766bfc8b28f9b4464eee1d3910
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# rails-diff-time
|
|
2
2
|
|
|
3
|
-
A Rails helper gem to display time differences in a human-readable format.
|
|
3
|
+
A Rails helper gem to display time differences in a human-readable format with automatic updates.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -18,6 +18,10 @@ Or install it yourself as:
|
|
|
18
18
|
|
|
19
19
|
$ gem install rails-diff-time
|
|
20
20
|
|
|
21
|
+
## Setup
|
|
22
|
+
|
|
23
|
+
No setup required! Just install the gem and start using it. The auto-update JavaScript will be automatically included when you use `auto_update: true` for the first time on a page.
|
|
24
|
+
|
|
21
25
|
## Usage
|
|
22
26
|
|
|
23
27
|
In your Rails views, you can use the `diff_time` helper to display time differences:
|
|
@@ -29,15 +33,34 @@ In your Rails views, you can use the `diff_time` helper to display time differen
|
|
|
29
33
|
<%= diff_time(Time.now - 2.hours) %>
|
|
30
34
|
# Output: <span>2 hours ago</span>
|
|
31
35
|
|
|
32
|
-
<%= diff_time(Time.now + 1.year + 2.months, "div", class: "time-diff") %>
|
|
36
|
+
<%= diff_time(Time.now + 1.year + 2.months, "div", { class: "time-diff" }) %>
|
|
33
37
|
# Output: <div class="time-diff">1 year 2 months later</div>
|
|
34
38
|
```
|
|
35
39
|
|
|
40
|
+
### Auto-update Feature
|
|
41
|
+
|
|
42
|
+
Enable automatic updates (every 1 minute) by passing the `auto_update: true` option:
|
|
43
|
+
|
|
44
|
+
```erb
|
|
45
|
+
<%= diff_time(user.created_at, auto_update: true) %>
|
|
46
|
+
# The display will automatically update every minute
|
|
47
|
+
|
|
48
|
+
<%= diff_time(post.published_at, "span", { class: "timestamp" }, auto_update: true) %>
|
|
49
|
+
# With custom element and attributes
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Note:** The necessary JavaScript code will be automatically included on the page the first time you call `diff_time` with `auto_update: true`. No manual setup required!
|
|
53
|
+
|
|
36
54
|
### Parameters
|
|
37
55
|
|
|
56
|
+
```ruby
|
|
57
|
+
diff_time(certain_time, element_name = "span", attributes = {}, auto_update: false)
|
|
58
|
+
```
|
|
59
|
+
|
|
38
60
|
- `certain_time` (required): The time to compare with the current time
|
|
39
61
|
- `element_name` (optional, default: "span"): The HTML element to wrap the output
|
|
40
62
|
- `attributes` (optional, default: {}): HTML attributes to add to the element
|
|
63
|
+
- `auto_update` (optional, default: false): Enable automatic updates every minute (JavaScript automatically included on first use)
|
|
41
64
|
|
|
42
65
|
## Examples
|
|
43
66
|
|
|
@@ -49,9 +72,63 @@ In your Rails views, you can use the `diff_time` helper to display time differen
|
|
|
49
72
|
<%= diff_time(event.starts_at, "p") %>
|
|
50
73
|
|
|
51
74
|
# With CSS classes
|
|
52
|
-
<%= diff_time(post.published_at, "span", class: "text-muted", id: "post-time") %>
|
|
75
|
+
<%= diff_time(post.published_at, "span", { class: "text-muted", id: "post-time" }) %>
|
|
76
|
+
|
|
77
|
+
# With auto-update enabled (JavaScript automatically included)
|
|
78
|
+
<%= diff_time(meeting.scheduled_at, "span", { class: "meeting-time" }, auto_update: true) %>
|
|
79
|
+
|
|
80
|
+
# Live timestamps for comments
|
|
81
|
+
<% @comments.each do |comment| %>
|
|
82
|
+
<div class="comment">
|
|
83
|
+
<p><%= comment.body %></p>
|
|
84
|
+
<small>Posted <%= diff_time(comment.created_at, auto_update: true) %></small>
|
|
85
|
+
</div>
|
|
86
|
+
<% end %>
|
|
53
87
|
```
|
|
54
88
|
|
|
89
|
+
### Complete Example
|
|
90
|
+
|
|
91
|
+
**app/views/posts/show.html.erb:**
|
|
92
|
+
```erb
|
|
93
|
+
<article>
|
|
94
|
+
<h1><%= @post.title %></h1>
|
|
95
|
+
<p class="meta">
|
|
96
|
+
Published <%= diff_time(@post.published_at, auto_update: true) %>
|
|
97
|
+
</p>
|
|
98
|
+
<div><%= @post.content %></div>
|
|
99
|
+
</article>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
That's it! No need to modify layout files or configure JavaScript imports.
|
|
103
|
+
|
|
104
|
+
## How It Works
|
|
105
|
+
|
|
106
|
+
The auto-update feature works by:
|
|
107
|
+
|
|
108
|
+
1. Storing the original timestamp in a `data-certain-time` attribute (ISO 8601 format)
|
|
109
|
+
2. Automatically including JavaScript code on first use of `auto_update: true`
|
|
110
|
+
3. Running a JavaScript timer that recalculates the time difference every 60 seconds
|
|
111
|
+
4. Updating the text content of elements client-side
|
|
112
|
+
|
|
113
|
+
This means:
|
|
114
|
+
- No additional server requests are made
|
|
115
|
+
- The display stays accurate without page reloads
|
|
116
|
+
- Works with Turbolinks/Turbo for SPA-like experiences
|
|
117
|
+
- **No JavaScript imports, asset pipeline configuration, or layout modifications needed** - everything is automatic!
|
|
118
|
+
|
|
119
|
+
## Browser Support
|
|
120
|
+
|
|
121
|
+
The JavaScript functionality requires:
|
|
122
|
+
- Modern browsers with ES6+ support
|
|
123
|
+
- Native `Date` object support
|
|
124
|
+
- `setInterval` support
|
|
125
|
+
|
|
126
|
+
Compatible with:
|
|
127
|
+
- Chrome/Edge (latest)
|
|
128
|
+
- Firefox (latest)
|
|
129
|
+
- Safari (latest)
|
|
130
|
+
- Mobile browsers (iOS Safari, Chrome Mobile)
|
|
131
|
+
|
|
55
132
|
## Development
|
|
56
133
|
|
|
57
134
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
@@ -64,5 +141,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/dhq_bo
|
|
|
64
141
|
|
|
65
142
|
## License
|
|
66
143
|
|
|
67
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
68
|
-
|
|
144
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
<%
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
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 += 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
|
|
319
|
+
365.25 * 24 * 3600
|
|
126
320
|
end
|
|
127
321
|
|
|
128
322
|
def month_in_seconds
|
|
129
|
-
30 * 24 * 3600
|
|
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
|
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.
|
|
4
|
+
version: 0.2.0
|
|
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').
|
|
14
|
-
|
|
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: []
|
|
@@ -44,7 +46,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
44
46
|
requirements:
|
|
45
47
|
- - ">="
|
|
46
48
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 3.4.
|
|
49
|
+
version: 3.4.7
|
|
48
50
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
51
|
requirements:
|
|
50
52
|
- - ">="
|
|
@@ -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: []
|