rails-diff-time 0.1.5 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9748702954e4f33f487e7ad5a8c657b89bbcc9966cfe384f0791fb2c60428b6e
4
- data.tar.gz: dcd1fee4443c63efeab7d4acc4742a2e3dd9e042ec0ce4fae7a8c6fd68809e51
3
+ metadata.gz: f500ef502d22be1eb93fe920650122bdd370b5799788e00180235a48afa17ce1
4
+ data.tar.gz: 0b954d61dcfbc5c431a8ea9a85ea996bac0a71470dc6db8dafb69e77d4c88813
5
5
  SHA512:
6
- metadata.gz: 3690429964d2704bf55479a1fae0083f46924a7098d3e24aa81899f3a0cebfe3f83feca3ae8ccf854e16928fae4799ce88e559561a49dc67d178d0aabb5c4aaf
7
- data.tar.gz: ca7e1e72f9d52fa0da0fcceaa28921f73b90453098beea0ae7723c1bf6287cc94826a588a7bd182790871477ce6905e7a8bc20aef35fe83e39b32d663212d575
6
+ metadata.gz: b515308f6f0ace59434dd0ee7be048696fbdddfe196d02198fb7cfd8d8ca7625195d5867dd3b3e287bf1bdc40f01bd92d6667b1295ff9e0c06edba1cdfc9b0e4
7
+ data.tar.gz: ee2d795c5307826898c38ca91421d106db62e4d0592a9c4ceebbf9ef34a1edb06970e2ab246b5c8e15ea1df60c5303d442f213766bfc8b28f9b4464eee1d3910
data/.rubocop.yml CHANGED
@@ -7,6 +7,7 @@ Style/StringLiterals:
7
7
 
8
8
  Style/StringLiteralsInInterpolation:
9
9
  EnforcedStyle: double_quotes
10
+ AutoCorrect: false
10
11
 
11
12
  # メトリクス系のルールをオプトアウト
12
13
  Metrics/ModuleLength:
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Rails::Diff::Time
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).
@@ -17,7 +17,7 @@ module RailsDiffTime
17
17
  # If auto_update is enabled and the script has not been included yet
18
18
  if auto_update && !@_diff_time_script_included
19
19
  @_diff_time_script_included = true
20
- result = result + diff_time_script_tag
20
+ result += diff_time_script_tag
21
21
  end
22
22
 
23
23
  result
@@ -30,36 +30,36 @@ module RailsDiffTime
30
30
  <<~JAVASCRIPT.html_safe
31
31
  (function() {
32
32
  'use strict';
33
-
33
+
34
34
  class DiffTimeUpdater {
35
35
  constructor() {
36
36
  this.updateInterval = 60000;
37
37
  this.elements = [];
38
38
  this.timerId = null;
39
39
  }
40
-
40
+
41
41
  init() {
42
42
  this.findElements();
43
43
  if (this.elements.length > 0) {
44
44
  this.startAutoUpdate();
45
45
  }
46
46
  }
47
-
47
+
48
48
  findElements() {
49
49
  this.elements = Array.from(
50
50
  document.querySelectorAll('[data-diff-time-target="display"]')
51
51
  );
52
52
  }
53
-
53
+
54
54
  startAutoUpdate() {
55
55
  if (this.timerId) clearInterval(this.timerId);
56
56
  this.timerId = setInterval(() => this.updateAll(), this.updateInterval);
57
57
  }
58
-
58
+
59
59
  updateAll() {
60
60
  this.elements.forEach(element => this.updateElement(element));
61
61
  }
62
-
62
+
63
63
  updateElement(element) {
64
64
  const certainTimeStr = element.dataset.certainTime;
65
65
  if (!certainTimeStr) return;
@@ -67,16 +67,16 @@ module RailsDiffTime
67
67
  const diffTimeStr = this.calculateDiffTime(certainTime);
68
68
  element.textContent = diffTimeStr;
69
69
  }
70
-
70
+
71
71
  calculateDiffTime(certainTime) {
72
72
  const now = new Date();
73
73
  const diff = certainTime - now;
74
74
  const differenceInSeconds = Math.abs(diff) / 1000;
75
-
75
+
76
76
  if (differenceInSeconds <= 5) return "now";
77
-
77
+
78
78
  const isLater = diff > 0;
79
-
79
+
80
80
  if (differenceInSeconds >= this.yearInSeconds()) {
81
81
  return this.formatYears(differenceInSeconds, isLater);
82
82
  } else if (differenceInSeconds >= this.monthInSeconds()) {
@@ -93,17 +93,17 @@ module RailsDiffTime
93
93
  return this.formatSeconds(differenceInSeconds, isLater);
94
94
  }
95
95
  }
96
-
96
+
97
97
  formatYears(seconds, isLater) {
98
98
  const years = Math.floor(seconds / this.yearInSeconds());
99
99
  let remaining = seconds - (years * this.yearInSeconds());
100
100
  let result = this.timeStr(years, "year");
101
-
101
+
102
102
  if (remaining >= this.monthInSeconds()) {
103
103
  const months = Math.floor(remaining / this.monthInSeconds());
104
104
  remaining -= months * this.monthInSeconds();
105
105
  result += ` ${this.timeStr(months, "month")}`;
106
-
106
+
107
107
  if (remaining >= this.dayInSeconds()) {
108
108
  const days = Math.floor(remaining / this.dayInSeconds());
109
109
  result += ` ${this.timeStr(days, "day")}`;
@@ -111,72 +111,72 @@ module RailsDiffTime
111
111
  }
112
112
  return `${result} ${this.agoOrLater(isLater)}`;
113
113
  }
114
-
114
+
115
115
  formatMonths(seconds, isLater) {
116
116
  const months = Math.floor(seconds / this.monthInSeconds());
117
117
  const remaining = seconds - (months * this.monthInSeconds());
118
118
  let result = this.timeStr(months, "month");
119
-
119
+
120
120
  if (remaining >= this.dayInSeconds()) {
121
121
  const days = Math.floor(remaining / this.dayInSeconds());
122
122
  result += ` ${this.timeStr(days, "day")}`;
123
123
  }
124
124
  return `${result} ${this.agoOrLater(isLater)}`;
125
125
  }
126
-
126
+
127
127
  formatWeeks(seconds, isLater) {
128
128
  const weeks = Math.floor(seconds / this.weekInSeconds());
129
129
  return `${this.timeStr(weeks, "week")} ${this.agoOrLater(isLater)}`;
130
130
  }
131
-
131
+
132
132
  formatDays(seconds, isLater) {
133
133
  const days = Math.floor(seconds / this.dayInSeconds());
134
134
  return `${this.timeStr(days, "day")} ${this.agoOrLater(isLater)}`;
135
135
  }
136
-
136
+
137
137
  formatHours(seconds, isLater) {
138
138
  const hours = Math.floor(seconds / this.hourInSeconds());
139
139
  const remaining = seconds - (hours * this.hourInSeconds());
140
140
  let result = this.timeStr(hours, "hour");
141
-
141
+
142
142
  if (remaining >= this.minuteInSeconds()) {
143
143
  const minutes = Math.floor(remaining / this.minuteInSeconds());
144
144
  result += ` ${this.timeStr(minutes, "minute")}`;
145
145
  }
146
146
  return `${result} ${this.agoOrLater(isLater)}`;
147
147
  }
148
-
148
+
149
149
  formatMinutes(seconds, isLater) {
150
150
  const minutes = Math.floor(seconds / this.minuteInSeconds());
151
151
  const remaining = seconds - (minutes * this.minuteInSeconds());
152
152
  let result = this.timeStr(minutes, "minute");
153
-
153
+
154
154
  if (remaining > 0) {
155
155
  const secs = Math.floor(remaining);
156
156
  result += ` ${this.timeStr(secs, "second")}`;
157
157
  }
158
158
  return `${result} ${this.agoOrLater(isLater)}`;
159
159
  }
160
-
160
+
161
161
  formatSeconds(seconds, isLater) {
162
162
  const secs = Math.floor(seconds);
163
163
  return `${this.timeStr(secs, "second")} ${this.agoOrLater(isLater)}`;
164
164
  }
165
-
165
+
166
166
  yearInSeconds() { return 365.25 * 24 * 3600; }
167
167
  monthInSeconds() { return 30 * 24 * 3600; }
168
168
  weekInSeconds() { return 7 * 24 * 3600; }
169
169
  dayInSeconds() { return 24 * 3600; }
170
170
  hourInSeconds() { return 3600; }
171
171
  minuteInSeconds() { return 60; }
172
-
172
+
173
173
  agoOrLater(isLater) { return isLater ? "later" : "ago"; }
174
-
174
+
175
175
  timeStr(count, singular) {
176
176
  const plural = singular + "s";
177
177
  return `${count} ${count === 1 ? singular : plural}`;
178
178
  }
179
-
179
+
180
180
  destroy() {
181
181
  if (this.timerId) {
182
182
  clearInterval(this.timerId);
@@ -185,32 +185,32 @@ module RailsDiffTime
185
185
  this.elements = [];
186
186
  }
187
187
  }
188
-
188
+
189
189
  let updater = null;
190
-
190
+
191
191
  function initUpdater() {
192
192
  if (updater) updater.destroy();
193
193
  updater = new DiffTimeUpdater();
194
194
  updater.init();
195
195
  }
196
-
196
+
197
197
  if (document.readyState === 'loading') {
198
198
  document.addEventListener('DOMContentLoaded', initUpdater);
199
199
  } else {
200
200
  initUpdater();
201
201
  }
202
-
202
+
203
203
  document.addEventListener('turbolinks:load', initUpdater);
204
204
  document.addEventListener('turbo:load', initUpdater);
205
-
205
+
206
206
  document.addEventListener('turbolinks:before-cache', function() {
207
207
  if (updater) updater.destroy();
208
208
  });
209
-
209
+
210
210
  document.addEventListener('turbo:before-cache', function() {
211
211
  if (updater) updater.destroy();
212
212
  });
213
-
213
+
214
214
  window.RailsDiffTime = {
215
215
  updater: updater,
216
216
  DiffTimeUpdater: DiffTimeUpdater
@@ -372,4 +372,3 @@ module RailsDiffTime
372
372
  end
373
373
  end
374
374
  end
375
-
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsDiffTime
4
- VERSION = "0.1.5"
4
+ VERSION = "0.2.0"
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.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dhq_boiler
@@ -46,7 +46,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
- version: 3.4.5
49
+ version: 3.4.7
50
50
  required_rubygems_version: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="