Fix ticket timer, to initialise on reload and after tab sleeping

When the tab was reloaded, the timer was not initialized again.
When the tab was in background and the tab was sleeping, the timer showed the wrong time
This commit is contained in:
Flos 2025-11-01 23:23:25 +01:00 committed by GitHub
parent 0d5bfdafdf
commit b09e4938b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 92 additions and 49 deletions

View File

@ -1,6 +1,5 @@
(function() { (function() {
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
// Initialize variables
var timerInterval = null; var timerInterval = null;
var ticketID = getCurrentTicketID(); var ticketID = getCurrentTicketID();
var elapsedSecs = getElapsedSeconds(); var elapsedSecs = getElapsedSeconds();
@ -22,6 +21,10 @@
return pausedTime + timeSinceStart; return pausedTime + timeSinceStart;
} }
function pad(val) {
return val < 10 ? "0" + val : val;
}
function displayTime() { function displayTime() {
let totalSeconds = elapsedSecs; let totalSeconds = elapsedSecs;
let hours = Math.floor(totalSeconds / 3600); let hours = Math.floor(totalSeconds / 3600);
@ -29,17 +32,21 @@
let minutes = Math.floor(totalSeconds / 60); let minutes = Math.floor(totalSeconds / 60);
let seconds = totalSeconds % 60; let seconds = totalSeconds % 60;
document.getElementById("hours").value = pad(hours); let hoursEl = document.getElementById("hours");
document.getElementById("minutes").value = pad(minutes); let minutesEl = document.getElementById("minutes");
document.getElementById("seconds").value = pad(seconds); let secondsEl = document.getElementById("seconds");
}
function pad(val) { if (hoursEl && minutesEl && secondsEl) {
return val < 10 ? "0" + val : val; hoursEl.value = pad(hours);
minutesEl.value = pad(minutes);
secondsEl.value = pad(seconds);
} else {
console.warn("Timer input elements not found");
}
} }
function countTime() { function countTime() {
elapsedSecs++; elapsedSecs = getElapsedSeconds();
displayTime(); displayTime();
} }
@ -48,7 +55,8 @@
localStorage.setItem(getLocalStorageKey("startTime"), Date.now().toString()); localStorage.setItem(getLocalStorageKey("startTime"), Date.now().toString());
} }
timerInterval = setInterval(countTime, 1000); timerInterval = setInterval(countTime, 1000);
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-pause'></i>"; let btn = document.getElementById("startStopTimer");
if (btn) btn.innerHTML = "<i class='fas fa-pause'></i>";
localStorage.setItem("ticket-timer-running-" + ticketID, "true"); localStorage.setItem("ticket-timer-running-" + ticketID, "true");
} }
@ -60,7 +68,8 @@
let currentElapsed = getElapsedSeconds(); let currentElapsed = getElapsedSeconds();
localStorage.setItem(getLocalStorageKey("pausedTime"), currentElapsed.toString()); localStorage.setItem(getLocalStorageKey("pausedTime"), currentElapsed.toString());
localStorage.removeItem(getLocalStorageKey("startTime")); localStorage.removeItem(getLocalStorageKey("startTime"));
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>"; let btn = document.getElementById("startStopTimer");
if (btn) btn.innerHTML = "<i class='fas fa-play'></i>";
localStorage.setItem("ticket-timer-running-" + ticketID, "false"); localStorage.setItem("ticket-timer-running-" + ticketID, "false");
} }
@ -77,7 +86,8 @@
elapsedSecs = 0; elapsedSecs = 0;
clearTimeStorage(); clearTimeStorage();
displayTime(); displayTime();
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>"; let btn = document.getElementById("startStopTimer");
if (btn) btn.innerHTML = "<i class='fas fa-play'></i>";
} }
localStorage.setItem("ticket-timer-running-" + ticketID, "false"); localStorage.setItem("ticket-timer-running-" + ticketID, "false");
} }
@ -88,7 +98,8 @@
elapsedSecs = 0; elapsedSecs = 0;
clearTimeStorage(); clearTimeStorage();
displayTime(); displayTime();
document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>"; let btn = document.getElementById("startStopTimer");
if (btn) btn.innerHTML = "<i class='fas fa-play'></i>";
} }
function handleInputFocus() { function handleInputFocus() {
@ -96,9 +107,9 @@
} }
function updateTimeFromInput() { function updateTimeFromInput() {
const hours = parseInt(document.getElementById("hours").value, 10) || 0; const hours = parseInt(document.getElementById("hours")?.value, 10) || 0;
const minutes = parseInt(document.getElementById("minutes").value, 10) || 0; const minutes = parseInt(document.getElementById("minutes")?.value, 10) || 0;
const seconds = parseInt(document.getElementById("seconds").value, 10) || 0; const seconds = parseInt(document.getElementById("seconds")?.value, 10) || 0;
elapsedSecs = (hours * 3600) + (minutes * 60) + seconds; elapsedSecs = (hours * 3600) + (minutes * 60) + seconds;
if (!timerInterval) { if (!timerInterval) {
@ -111,61 +122,93 @@
} }
function checkStatusAndPauseTimer() { function checkStatusAndPauseTimer() {
var status = document.querySelector('select[name="status"]').value; var statusEl = document.querySelector('select[name="status"]');
if (status.includes("Pending") || status.includes("Close")) { if (statusEl) {
pauseTimer(); var status = statusEl.value;
if (status.includes("Pending") || status.includes("Close")) {
pauseTimer();
}
} }
} }
// Attach input listeners // Update on tab visibility change to handle background sleep
document.getElementById("hours").addEventListener('change', updateTimeFromInput); document.addEventListener('visibilitychange', function() {
document.getElementById("minutes").addEventListener('change', updateTimeFromInput); if (!document.hidden) {
document.getElementById("seconds").addEventListener('change', updateTimeFromInput); elapsedSecs = getElapsedSeconds();
displayTime();
document.getElementById("hours").addEventListener('focus', handleInputFocus);
document.getElementById("minutes").addEventListener('focus', handleInputFocus);
document.getElementById("seconds").addEventListener('focus', handleInputFocus);
document.querySelector('select[name="status"]').addEventListener('change', checkStatusAndPauseTimer);
document.getElementById("startStopTimer").addEventListener('click', function() {
if (timerInterval === null) {
startTimer();
} else {
pauseTimer();
} }
}); });
document.getElementById("resetTimer").addEventListener('click', function() { // Attach input listeners with null checks
resetTimer(); const hoursEl = document.getElementById("hours");
}); if (hoursEl) {
hoursEl.addEventListener('change', updateTimeFromInput);
hoursEl.addEventListener('focus', handleInputFocus);
}
document.getElementById("ticket_add_reply").addEventListener('click', function() { const minutesEl = document.getElementById("minutes");
setTimeout(forceResetTimer, 100); if (minutesEl) {
}); minutesEl.addEventListener('change', updateTimeFromInput);
minutesEl.addEventListener('focus', handleInputFocus);
}
document.getElementById("ticket_close").addEventListener('click', function() { const secondsEl = document.getElementById("seconds");
setTimeout(clearTimeStorage, 100); if (secondsEl) {
}); secondsEl.addEventListener('change', updateTimeFromInput);
secondsEl.addEventListener('focus', handleInputFocus);
}
const statusEl = document.querySelector('select[name="status"]');
if (statusEl) {
statusEl.addEventListener('change', checkStatusAndPauseTimer);
}
const startStopBtn = document.getElementById("startStopTimer");
if (startStopBtn) {
startStopBtn.addEventListener('click', function() {
if (timerInterval === null) {
startTimer();
} else {
pauseTimer();
}
});
}
const resetBtn = document.getElementById("resetTimer");
if (resetBtn) {
resetBtn.addEventListener('click', function() {
resetTimer();
});
}
const addReplyBtn = document.getElementById("ticket_add_reply");
if (addReplyBtn) {
addReplyBtn.addEventListener('click', function() {
setTimeout(forceResetTimer, 100);
});
}
const closeBtn = document.getElementById("ticket_close");
if (closeBtn) {
closeBtn.addEventListener('click', function() {
setTimeout(clearTimeStorage, 100);
});
}
// Final initialization logic // Final initialization logic
try { try {
displayTime(); displayTime();
// If no timer state, respect ticketAutoStart
if (!localStorage.getItem(getLocalStorageKey("startTime")) && !localStorage.getItem(getLocalStorageKey("pausedTime"))) { if (!localStorage.getItem(getLocalStorageKey("startTime")) && !localStorage.getItem(getLocalStorageKey("pausedTime"))) {
if (ticketAutoStart === 1) { if (typeof ticketAutoStart !== "undefined" && ticketAutoStart === 1) {
startTimer(); startTimer();
} else { } else {
pauseTimer(); pauseTimer();
} }
} } else if (localStorage.getItem(getLocalStorageKey("startTime"))) {
// If timer already running, resume it
else if (localStorage.getItem(getLocalStorageKey("startTime"))) {
startTimer(); startTimer();
} }
// Check and pause timer if status is pending
checkStatusAndPauseTimer(); checkStatusAndPauseTimer();
} catch (error) { } catch (error) {