diff --git a/make_post_sell/static/js/auction.js b/make_post_sell/static/js/auction.js index f81c6ae..578b989 100644 --- a/make_post_sell/static/js/auction.js +++ b/make_post_sell/static/js/auction.js @@ -22,17 +22,25 @@ const bidForm = document.getElementById("auction-bid-form"); const buyNowForm = document.getElementById("auction-buy-now-form"); + /* fmtRemaining — prose human delta, matches ago.human() server-side. + * Top two non-zero units, so the line stays short on small viewports. + */ function fmtRemaining(ms) { if (ms <= 0) return "ended"; const totalSeconds = Math.floor(ms / 1000); - const days = Math.floor(totalSeconds / 86400); - const hours = Math.floor((totalSeconds % 86400) / 3600); - const minutes = Math.floor((totalSeconds % 3600) / 60); - const seconds = totalSeconds % 60; - if (days > 0) return `${days}d ${hours}h ${minutes}m`; - if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`; - if (minutes > 0) return `${minutes}m ${seconds}s`; - return `${seconds}s`; + const units = [ + { name: "day", value: Math.floor(totalSeconds / 86400) }, + { name: "hour", value: Math.floor((totalSeconds % 86400) / 3600) }, + { name: "minute", value: Math.floor((totalSeconds % 3600) / 60) }, + { name: "second", value: totalSeconds % 60 }, + ]; + const parts = []; + for (let i = 0; i < units.length && parts.length < 2; i++) { + const u = units[i]; + if (u.value === 0 && parts.length === 0 && i < units.length - 1) continue; + parts.push(u.value + " " + u.name + (u.value === 1 ? "" : "s")); + } + return "in " + parts.join(", "); } function tickCountdown() { @@ -114,29 +122,19 @@ }); } - // Pay-by countdown (post-end): same fmtRemaining; written into - // #auction-pay-countdown if present. The human deadline string is - // also resolved locally from the same data attribute so the user - // sees a consistent wall-clock + countdown in their own timezone. - const payCountdownEl = document.getElementById("auction-pay-countdown"); - const payDeadlineHumanEl = document.getElementById( - "auction-pay-deadline-human" - ); - + /* Pay-by countdown (post-end). Rewrites any [data-pay-deadline] + * element on the page in place — the server pre-fills the same + * element with ago.human(), and we refine to second precision. */ function tickPayCountdown() { - if (!payCountdownEl) return; - const raw = payCountdownEl.getAttribute("data-pay-deadline"); - if (!raw) return; - const deadline = parseInt(raw, 10); - if (isNaN(deadline)) return; - payCountdownEl.textContent = fmtRemaining(deadline - Date.now()); - if (payDeadlineHumanEl && payDeadlineHumanEl.textContent === "computing…") { - try { - payDeadlineHumanEl.textContent = new Date(deadline).toLocaleString(); - } catch (e) { - /* leave the placeholder */ - } - } + const nodes = document.querySelectorAll("[data-pay-deadline]"); + if (!nodes.length) return; + const now = Date.now(); + nodes.forEach(function (node) { + const raw = node.getAttribute("data-pay-deadline"); + const deadline = parseInt(raw, 10); + if (isNaN(deadline)) return; + node.textContent = fmtRemaining(deadline - now); + }); } // Countdown ticks locally every second. diff --git a/make_post_sell/static/js/offer.js b/make_post_sell/static/js/offer.js index 69bcbb9..0ab9678 100644 --- a/make_post_sell/static/js/offer.js +++ b/make_post_sell/static/js/offer.js @@ -126,19 +126,31 @@ * elapses the offer auto-expires server-side; we reflect that * locally as "expired — refresh to update." */ + /* fmtRemaining — prose human delta, matches ago.human() server-side. + * The top two non-zero units make the cut so the line stays short + * even on small phones (`in 1 day, 5 hours`, not `in 1d 5h 30m 2s`). + */ function fmtRemaining(ms) { if (ms <= 0) return "expired"; var totalSeconds = Math.floor(ms / 1000); - var days = Math.floor(totalSeconds / 86400); - var hours = Math.floor((totalSeconds % 86400) / 3600); - var minutes = Math.floor((totalSeconds % 3600) / 60); - var seconds = totalSeconds % 60; - if (days > 0) return days + "d " + hours + "h " + minutes + "m"; - if (hours > 0) return hours + "h " + minutes + "m " + seconds + "s"; - if (minutes > 0) return minutes + "m " + seconds + "s"; - return seconds + "s"; + var units = [ + { name: "day", value: Math.floor(totalSeconds / 86400) }, + { name: "hour", value: Math.floor((totalSeconds % 86400) / 3600) }, + { name: "minute", value: Math.floor((totalSeconds % 3600) / 60) }, + { name: "second", value: totalSeconds % 60 }, + ]; + var parts = []; + for (var i = 0; i < units.length && parts.length < 2; i++) { + var u = units[i]; + if (u.value === 0 && parts.length === 0 && i < units.length - 1) continue; + parts.push(u.value + " " + u.name + (u.value === 1 ? "" : "s")); + } + return "in " + parts.join(", "); } + /* Tick each [data-pay-deadline] element directly — JS rewrites the + * same the server pre-filled with ago.human(). The two + * disagree by at most one second after each tick. */ function tickPayCountdown() { var nodes = document.querySelectorAll("[data-pay-deadline]"); if (!nodes.length) return; @@ -147,9 +159,7 @@ var raw = node.getAttribute("data-pay-deadline"); var deadline = parseInt(raw, 10); if (isNaN(deadline)) return; - var value = node.querySelector(".offer-pay-countdown-value"); - if (!value) return; - value.textContent = fmtRemaining(deadline - now); + node.textContent = fmtRemaining(deadline - now); }); } diff --git a/make_post_sell/templates/auction.j2 b/make_post_sell/templates/auction.j2 index 6d975a0..7126402 100644 --- a/make_post_sell/templates/auction.j2 +++ b/make_post_sell/templates/auction.j2 @@ -44,9 +44,7 @@

You won this auction!

- Complete payment by computing… - · computing… remaining, - or the auction will be released to the next-highest bidder. + Complete payment {{ payment_deadline_human }}, or the auction will be released to the next-highest bidder.

diff --git a/make_post_sell/templates/offer.j2 b/make_post_sell/templates/offer.j2 index 37c4eb7..e0e977b 100644 --- a/make_post_sell/templates/offer.j2 +++ b/make_post_sell/templates/offer.j2 @@ -107,11 +107,7 @@
{% if pay_deadline_human %} -

You have until {{ pay_deadline_human }} to complete payment, after which this offer auto-expires. - {% if pay_deadline_timestamp_ms %} - · computing… remaining - {% endif %} -

+

Payment due {{ pay_deadline_human }}, after which this offer auto-expires.

{% endif %}
@@ -122,11 +118,7 @@

Awaiting payment

You accepted {{ buyer_name }}’s offer at ${{ "%.2f"|format(current_amount) }}. We emailed them a one-time checkout link — this offer can be redeemed only once.

{% if pay_deadline_human %} -

Buyer must pay by {{ pay_deadline_human }}; the offer auto-expires after that. - {% if pay_deadline_timestamp_ms %} - · computing… remaining - {% endif %} -

+

Buyer must pay {{ pay_deadline_human }}; the offer auto-expires after that.

{% endif %}

If they need it again, share this same page: