Merge pull request #362 from basecamp/local-time-fixes

Local time fixes
This commit is contained in:
Jorge Manrubia
2025-04-07 10:47:21 +02:00
committed by GitHub
5 changed files with 37 additions and 38 deletions
+4
View File
@@ -86,6 +86,10 @@
inline-size: calc(100dvw - var(--actions-inline-inset) * 2 - var(--btn-size) * 2);
}
.local-time-value {
font-weight: bold;
}
@media (prefers-color-scheme: dark) {
--border-color: var(--color-subtle-dark);
--border-size: 1px;
@@ -1,7 +1,8 @@
import { Controller } from "@hotwired/stimulus"
import { differenceInDays } from "helpers/date_helpers"
export default class extends Controller {
static targets = [ "time", "date", "datetime", "shortdate", "ago", "indays" ]
static targets = [ "time", "date", "datetime", "shortdate", "ago", "indays", "daysago" ]
#timer
@@ -11,7 +12,7 @@ export default class extends Controller {
this.shortDateFormatter = new Intl.DateTimeFormat(undefined, { month: "short", day: "numeric" })
this.dateTimeFormatter = new Intl.DateTimeFormat(undefined, { timeStyle: "short", dateStyle: "short" })
this.agoFormatter = new AgoFormatter()
this.daysAgoFormatter = new DaysAgoFormatter()
this.daysagoFormatter = new DaysAgoFormatter()
this.indaysFormatter = new InDaysFormatter()
}
@@ -43,14 +44,14 @@ export default class extends Controller {
this.#formatTime(this.agoFormatter, target)
}
daysAgoTargetConnected(target) {
this.#formatTime(this.daysAgoFormatter, target)
}
indaysTargetConnected(target) {
this.#formatTime(this.indaysFormatter, target)
}
daysagoTargetConnected(target) {
this.#formatTime(this.daysagoFormatter, target)
}
#refreshRelativeTimes() {
this.agoTargets.forEach(target => {
this.#formatTime(this.agoFormatter, target)
@@ -59,7 +60,7 @@ export default class extends Controller {
#formatTime(formatter, target) {
const dt = new Date(target.getAttribute("datetime"))
target.textContent = formatter.format(dt)
target.innerHTML = formatter.format(dt)
target.title = this.dateTimeFormatter.format(dt)
}
}
@@ -93,38 +94,25 @@ class AgoFormatter {
}
class DaysAgoFormatter {
format(dt) {
const now = new Date()
format(date) {
const days = differenceInDays(date, new Date())
const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate())
const startOfGivenDay = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate())
const msPerDay = 1000 * 60 * 60 * 24
const dayDiff = Math.floor((startOfToday - startOfGivenDay) / msPerDay)
if (dayDiff === 0) return "Today"
if (dayDiff === 1) return "Yesterday"
return `${dayDiff} days ago`
if (days <= 0) return styleableValue("today")
if (days === 1) return styleableValue("yesterday")
return `${styleableValue(days)} days ago`
}
}
class InDaysFormatter {
format(dt) {
const target = this.#beginningOfDay(dt)
const today = this.#beginningOfDay(new Date())
const days = Math.round((target - today) / (1000 * 60 * 60 * 24))
format(date) {
const days = differenceInDays(new Date(), date)
if (days <= 0) {
return "today"
}
if (days === 1) {
return "tomorrow"
}
return `in ${Math.round(days)} days`
}
#beginningOfDay(dt) {
return new Date(dt.getFullYear(), dt.getMonth(), dt.getDate())
if (days <= 0) return styleableValue("today")
if (days === 1) return styleableValue("tomorrow")
return `in ${styleableValue(days)} days`
}
}
function styleableValue(value) {
return `<span class="local-time-value">${value}</span>`
}
+7
View File
@@ -0,0 +1,7 @@
export function differenceInDays(fromDate, toDate) {
return Math.round(Math.abs((beginningOfDay(toDate) - beginningOfDay(fromDate)) / (1000 * 60 * 60 * 24)))
}
export function beginningOfDay(date) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate())
}
+1 -1
View File
@@ -7,7 +7,7 @@
</h3>
<div class="txt-small overflow-ellipsis txt-uppercase"><%= "Added to #{bubble.bucket.name} by #{bubble.creator.name}" %>
<%= local_datetime_tag(bubble.created_at, style: :daysAgo) %>
<%= local_datetime_tag(bubble.created_at, style: :daysago) %>
</div>
<div class="card__stuff flex align-center gap">
@@ -1,18 +1,18 @@
<div class="card__meta flex txt-tight-lines txt-uppercase">
<div class="flex flex-column gap txt-align-end">
<span class="pad-inline overflow-ellipsis"><%= bubble.creating? ? "Added" : "Updated" %>
<%= local_datetime_tag(bubble.updated_at, style: :daysAgo) %>
<%= local_datetime_tag(bubble.updated_at, style: :daysago) %>
</span>
<hr class="full-width separator--horizontal unpad margin-none">
<% if bubble.creating? %>
<span class="pad-inline overflow-ellipsis">Expires
<%= local_datetime_tag(bubble.auto_pop_at, style: :daysAgo) %>
<%= local_datetime_tag(bubble.auto_pop_at, style: :indays) %>
</span>
<% else %>
<span class="pad-inline overflow-ellipsis">Added
<%= local_datetime_tag(bubble.created_at, style: :daysAgo) %>
<%= local_datetime_tag(bubble.created_at, style: :daysago) %>
</span>
<% end %>
</div>