Skip to content

Commit 2414644

Browse files
committed
fix: make timers more generic
1 parent c3e5800 commit 2414644

2 files changed

Lines changed: 25 additions & 22 deletions

File tree

assets/style.css

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,16 +1037,9 @@ input:-webkit-autofill:active {
10371037
height: 16dvh;
10381038
}
10391039
.timer > svg > circle {
1040-
transform: rotate(-90deg);
1040+
transform: rotate(90deg) scale(-1, 1);
10411041
transform-origin: center center;
10421042
}
1043-
/* Applies to iOS Safari as stroke rotations are done differently */
1044-
@supports (-webkit-touch-callout: none) {
1045-
.timer > svg > circle {
1046-
transform: rotate(90deg) scale(-1, 1);
1047-
transform-origin: center center;
1048-
}
1049-
}
10501043
.timer > svg > circle.base {
10511044
fill: none;
10521045
stroke-opacity: 0.3;

scripts/bikes.js

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ async function openUnlockBikeCard(stationSerialNumber, bikeObjJSON, dockSerialNu
174174
alert("Ocorreu um erro ao reservar a bicicleta.");
175175
return;
176176
}
177+
const reserveTimerDurationMs = 30_000,
178+
endReserveTime = Date.now() + reserveTimerDurationMs;
177179

178180
// Populate card element
179181
card.innerHTML = `
@@ -200,19 +202,17 @@ async function openUnlockBikeCard(stationSerialNumber, bikeObjJSON, dockSerialNu
200202
`.trim();
201203

202204
// Run the timer (30 seconds)
203-
let timeLeft = 30;
204205
const timerElement = document.getElementById("reserveDuration");
205206
const timerText = timerElement.querySelector("#timeLeft");
206207
const timerCircle = timerElement.querySelector("svg > circle.progress");
207-
timerCircle.style.strokeDashoffset = 1;
208+
timerCircle.style.strokeDashoffset = getCurrentTimerProgress(endReserveTime, reserveTimerDurationMs);
208209

209210
let countdownHandler = async function () {
210211
if (!document.getElementById("unlockBikeCard")) clearInterval(countdownTimer);
211-
let isTimeLeft = timeLeft > -1;
212-
if (isTimeLeft) {
213-
const timeRemaining = timeLeft--;
214-
const normalizedTime = (timeRemaining - 30) / 30;
215-
timerCircle.style.strokeDashoffset = normalizedTime;
212+
const currentProgress = getCurrentTimerProgress(endReserveTime, reserveTimerDurationMs),
213+
timeRemaining = Math.round(((1 - Math.abs(currentProgress)) * reserveTimerDurationMs) / 1000);
214+
if (timeRemaining >= 0) {
215+
timerCircle.style.strokeDashoffset = currentProgress;
216216
timerText.innerHTML = timeRemaining;
217217
} else {
218218
clearInterval(countdownTimer);
@@ -575,7 +575,8 @@ async function payTrip(tripCode, tripCost) {
575575
* @param {number} lastTripEndDate Time at which the last trip ended
576576
*/
577577
function startCountdownBetweenTrips(lastTripEndDate) {
578-
const timeForStartingNextTrip = lastTripEndDate + 5 * 60_000;
578+
const timerDurationMs = 5 * 60_000; // 5 minutes in milliseconds
579+
const timeForStartingNextTrip = lastTripEndDate + timerDurationMs;
579580
if (timeForStartingNextTrip < Date.now()) return;
580581

581582
// Remove previous countdown if it exists
@@ -608,19 +609,17 @@ function startCountdownBetweenTrips(lastTripEndDate) {
608609
const timerElement = document.querySelector("#countdown");
609610
const timerCircle = timerElement.querySelector("svg > circle.progress");
610611

611-
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
612-
const isSafari = navigator.userAgent.includes("Safari") && !navigator.userAgent.includes("Chrome");
613612
// Initialize differently for iOS Safari
614-
timerCircle.style.strokeDashoffset = isIOS && isSafari ? 0 : 1;
613+
timerCircle.style.strokeDashoffset = getCurrentTimerProgress(timeForStartingNextTrip, timerDurationMs);
615614

616615
const countdownHandler = function () {
617616
// stop the countdown if the element is removed
618617
if (!document.body.contains(timerElement)) return;
619618

620-
const timeRemaining = Math.round((timeForStartingNextTrip - Date.now()) / 1000);
619+
const currentProgress = getCurrentTimerProgress(timeForStartingNextTrip, timerDurationMs);
620+
const timeRemaining = Math.round(((1 - Math.abs(currentProgress)) * timerDurationMs) / 1000);
621621
if (timeRemaining >= 0) {
622-
const normalizedTime = (timeRemaining - 300) / 300;
623-
timerCircle.style.strokeDashoffset = isIOS && isSafari ? -normalizedTime : normalizedTime;
622+
timerCircle.style.strokeDashoffset = currentProgress;
624623
timerText.innerHTML = formatTime(timeRemaining);
625624
setTimeout(countdownHandler, 1000);
626625
} else {
@@ -630,3 +629,14 @@ function startCountdownBetweenTrips(lastTripEndDate) {
630629

631630
countdownHandler();
632631
}
632+
633+
/**
634+
* Returns the current progress of a timer based on the end date, current and total time.
635+
* @param {number} endDate The timestamp, in ms, when this timer is supposed to end
636+
* @param {number} totalTimeMs The total length of the timer in ms
637+
*/
638+
function getCurrentTimerProgress(endDate, totalTimeMs) {
639+
const start = endDate - totalTimeMs;
640+
const normalizedTime = (Date.now() - start) / totalTimeMs;
641+
return normalizedTime;
642+
}

0 commit comments

Comments
 (0)