|
1 | 1 | (function() { |
2 | 2 | document.addEventListener("DOMContentLoaded", function() { |
3 | | - // Initialize variables |
4 | 3 | var timerInterval = null; |
5 | 4 | var ticketID = getCurrentTicketID(); |
6 | 5 | var elapsedSecs = getElapsedSeconds(); |
|
22 | 21 | return pausedTime + timeSinceStart; |
23 | 22 | } |
24 | 23 |
|
| 24 | + function pad(val) { |
| 25 | + return val < 10 ? "0" + val : val; |
| 26 | + } |
| 27 | + |
25 | 28 | function displayTime() { |
26 | 29 | let totalSeconds = elapsedSecs; |
27 | 30 | let hours = Math.floor(totalSeconds / 3600); |
28 | 31 | totalSeconds %= 3600; |
29 | 32 | let minutes = Math.floor(totalSeconds / 60); |
30 | 33 | let seconds = totalSeconds % 60; |
31 | 34 |
|
32 | | - document.getElementById("hours").value = pad(hours); |
33 | | - document.getElementById("minutes").value = pad(minutes); |
34 | | - document.getElementById("seconds").value = pad(seconds); |
35 | | - } |
| 35 | + let hoursEl = document.getElementById("hours"); |
| 36 | + let minutesEl = document.getElementById("minutes"); |
| 37 | + let secondsEl = document.getElementById("seconds"); |
36 | 38 |
|
37 | | - function pad(val) { |
38 | | - return val < 10 ? "0" + val : val; |
| 39 | + if (hoursEl && minutesEl && secondsEl) { |
| 40 | + hoursEl.value = pad(hours); |
| 41 | + minutesEl.value = pad(minutes); |
| 42 | + secondsEl.value = pad(seconds); |
| 43 | + } else { |
| 44 | + console.warn("Timer input elements not found"); |
| 45 | + } |
39 | 46 | } |
40 | 47 |
|
41 | 48 | function countTime() { |
42 | | - elapsedSecs++; |
| 49 | + elapsedSecs = getElapsedSeconds(); |
43 | 50 | displayTime(); |
44 | 51 | } |
45 | 52 |
|
|
48 | 55 | localStorage.setItem(getLocalStorageKey("startTime"), Date.now().toString()); |
49 | 56 | } |
50 | 57 | timerInterval = setInterval(countTime, 1000); |
51 | | - document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-pause'></i>"; |
| 58 | + let btn = document.getElementById("startStopTimer"); |
| 59 | + if (btn) btn.innerHTML = "<i class='fas fa-pause'></i>"; |
52 | 60 | localStorage.setItem("ticket-timer-running-" + ticketID, "true"); |
53 | 61 | } |
54 | 62 |
|
|
60 | 68 | let currentElapsed = getElapsedSeconds(); |
61 | 69 | localStorage.setItem(getLocalStorageKey("pausedTime"), currentElapsed.toString()); |
62 | 70 | localStorage.removeItem(getLocalStorageKey("startTime")); |
63 | | - document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>"; |
| 71 | + let btn = document.getElementById("startStopTimer"); |
| 72 | + if (btn) btn.innerHTML = "<i class='fas fa-play'></i>"; |
64 | 73 | localStorage.setItem("ticket-timer-running-" + ticketID, "false"); |
65 | 74 | } |
66 | 75 |
|
|
77 | 86 | elapsedSecs = 0; |
78 | 87 | clearTimeStorage(); |
79 | 88 | displayTime(); |
80 | | - document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>"; |
| 89 | + let btn = document.getElementById("startStopTimer"); |
| 90 | + if (btn) btn.innerHTML = "<i class='fas fa-play'></i>"; |
81 | 91 | } |
82 | 92 | localStorage.setItem("ticket-timer-running-" + ticketID, "false"); |
83 | 93 | } |
|
88 | 98 | elapsedSecs = 0; |
89 | 99 | clearTimeStorage(); |
90 | 100 | displayTime(); |
91 | | - document.getElementById("startStopTimer").innerHTML = "<i class='fas fa-play'></i>"; |
| 101 | + let btn = document.getElementById("startStopTimer"); |
| 102 | + if (btn) btn.innerHTML = "<i class='fas fa-play'></i>"; |
92 | 103 | } |
93 | 104 |
|
94 | 105 | function handleInputFocus() { |
95 | 106 | pauseTimer(); |
96 | 107 | } |
97 | 108 |
|
98 | 109 | function updateTimeFromInput() { |
99 | | - const hours = parseInt(document.getElementById("hours").value, 10) || 0; |
100 | | - const minutes = parseInt(document.getElementById("minutes").value, 10) || 0; |
101 | | - const seconds = parseInt(document.getElementById("seconds").value, 10) || 0; |
| 110 | + const hours = parseInt(document.getElementById("hours")?.value, 10) || 0; |
| 111 | + const minutes = parseInt(document.getElementById("minutes")?.value, 10) || 0; |
| 112 | + const seconds = parseInt(document.getElementById("seconds")?.value, 10) || 0; |
102 | 113 | elapsedSecs = (hours * 3600) + (minutes * 60) + seconds; |
103 | 114 |
|
104 | 115 | if (!timerInterval) { |
|
111 | 122 | } |
112 | 123 |
|
113 | 124 | function checkStatusAndPauseTimer() { |
114 | | - var status = document.querySelector('select[name="status"]').value; |
115 | | - if (status.includes("Pending") || status.includes("Close")) { |
116 | | - pauseTimer(); |
| 125 | + var statusEl = document.querySelector('select[name="status"]'); |
| 126 | + if (statusEl) { |
| 127 | + var status = statusEl.value; |
| 128 | + if (status.includes("Pending") || status.includes("Close")) { |
| 129 | + pauseTimer(); |
| 130 | + } |
117 | 131 | } |
118 | 132 | } |
119 | 133 |
|
120 | | - // Attach input listeners |
121 | | - document.getElementById("hours").addEventListener('change', updateTimeFromInput); |
122 | | - document.getElementById("minutes").addEventListener('change', updateTimeFromInput); |
123 | | - document.getElementById("seconds").addEventListener('change', updateTimeFromInput); |
| 134 | + // Update on tab visibility change to handle background sleep |
| 135 | + document.addEventListener('visibilitychange', function() { |
| 136 | + if (!document.hidden) { |
| 137 | + elapsedSecs = getElapsedSeconds(); |
| 138 | + displayTime(); |
| 139 | + } |
| 140 | + }); |
124 | 141 |
|
125 | | - document.getElementById("hours").addEventListener('focus', handleInputFocus); |
126 | | - document.getElementById("minutes").addEventListener('focus', handleInputFocus); |
127 | | - document.getElementById("seconds").addEventListener('focus', handleInputFocus); |
| 142 | + // Attach input listeners with null checks |
| 143 | + const hoursEl = document.getElementById("hours"); |
| 144 | + if (hoursEl) { |
| 145 | + hoursEl.addEventListener('change', updateTimeFromInput); |
| 146 | + hoursEl.addEventListener('focus', handleInputFocus); |
| 147 | + } |
128 | 148 |
|
129 | | - document.querySelector('select[name="status"]').addEventListener('change', checkStatusAndPauseTimer); |
| 149 | + const minutesEl = document.getElementById("minutes"); |
| 150 | + if (minutesEl) { |
| 151 | + minutesEl.addEventListener('change', updateTimeFromInput); |
| 152 | + minutesEl.addEventListener('focus', handleInputFocus); |
| 153 | + } |
130 | 154 |
|
131 | | - document.getElementById("startStopTimer").addEventListener('click', function() { |
132 | | - if (timerInterval === null) { |
133 | | - startTimer(); |
134 | | - } else { |
135 | | - pauseTimer(); |
136 | | - } |
137 | | - }); |
| 155 | + const secondsEl = document.getElementById("seconds"); |
| 156 | + if (secondsEl) { |
| 157 | + secondsEl.addEventListener('change', updateTimeFromInput); |
| 158 | + secondsEl.addEventListener('focus', handleInputFocus); |
| 159 | + } |
138 | 160 |
|
139 | | - document.getElementById("resetTimer").addEventListener('click', function() { |
140 | | - resetTimer(); |
141 | | - }); |
| 161 | + const statusEl = document.querySelector('select[name="status"]'); |
| 162 | + if (statusEl) { |
| 163 | + statusEl.addEventListener('change', checkStatusAndPauseTimer); |
| 164 | + } |
142 | 165 |
|
143 | | - document.getElementById("ticket_add_reply").addEventListener('click', function() { |
144 | | - setTimeout(forceResetTimer, 100); |
145 | | - }); |
| 166 | + const startStopBtn = document.getElementById("startStopTimer"); |
| 167 | + if (startStopBtn) { |
| 168 | + startStopBtn.addEventListener('click', function() { |
| 169 | + if (timerInterval === null) { |
| 170 | + startTimer(); |
| 171 | + } else { |
| 172 | + pauseTimer(); |
| 173 | + } |
| 174 | + }); |
| 175 | + } |
146 | 176 |
|
147 | | - document.getElementById("ticket_close").addEventListener('click', function() { |
148 | | - setTimeout(clearTimeStorage, 100); |
149 | | - }); |
| 177 | + const resetBtn = document.getElementById("resetTimer"); |
| 178 | + if (resetBtn) { |
| 179 | + resetBtn.addEventListener('click', function() { |
| 180 | + resetTimer(); |
| 181 | + }); |
| 182 | + } |
| 183 | + |
| 184 | + const addReplyBtn = document.getElementById("ticket_add_reply"); |
| 185 | + if (addReplyBtn) { |
| 186 | + addReplyBtn.addEventListener('click', function() { |
| 187 | + setTimeout(forceResetTimer, 100); |
| 188 | + }); |
| 189 | + } |
| 190 | + |
| 191 | + const closeBtn = document.getElementById("ticket_close"); |
| 192 | + if (closeBtn) { |
| 193 | + closeBtn.addEventListener('click', function() { |
| 194 | + setTimeout(clearTimeStorage, 100); |
| 195 | + }); |
| 196 | + } |
150 | 197 |
|
151 | 198 | // Final initialization logic |
152 | 199 | try { |
153 | 200 | displayTime(); |
154 | 201 |
|
155 | | - // If no timer state, respect ticketAutoStart |
156 | 202 | if (!localStorage.getItem(getLocalStorageKey("startTime")) && !localStorage.getItem(getLocalStorageKey("pausedTime"))) { |
157 | | - if (ticketAutoStart === 1) { |
| 203 | + if (typeof ticketAutoStart !== "undefined" && ticketAutoStart === 1) { |
158 | 204 | startTimer(); |
159 | 205 | } else { |
160 | 206 | pauseTimer(); |
161 | 207 | } |
162 | | - } |
163 | | - // If timer already running, resume it |
164 | | - else if (localStorage.getItem(getLocalStorageKey("startTime"))) { |
| 208 | + } else if (localStorage.getItem(getLocalStorageKey("startTime"))) { |
165 | 209 | startTimer(); |
166 | 210 | } |
167 | 211 |
|
168 | | - // Check and pause timer if status is pending |
169 | 212 | checkStatusAndPauseTimer(); |
170 | 213 |
|
171 | 214 | } catch (error) { |
|
0 commit comments