From 6a0b291acd7abfaecc024ffb816bf05797d90a02 Mon Sep 17 00:00:00 2001 From: Andrew Malsbury Date: Wed, 25 Oct 2023 18:26:33 +0000 Subject: [PATCH 1/4] Save timer to local Storage --- js/ticket_time_tracking.js | 88 +++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/js/ticket_time_tracking.js b/js/ticket_time_tracking.js index 3a8ac886..f574561f 100644 --- a/js/ticket_time_tracking.js +++ b/js/ticket_time_tracking.js @@ -1,19 +1,50 @@ document.addEventListener("DOMContentLoaded", function() { - // Default values var hours = 0; var minutes = 0; var seconds = 0; - var timerInterval = null; // variable to hold interval id - var isPaused = false; // variable to track if the timer is paused + var timerInterval = null; + var isPaused = false; + + var ticketID = getCurrentTicketID(); + + // Load stored time if available + loadTimeFromStorage(); + + function getCurrentTicketID() { + const urlParams = new URLSearchParams(window.location.search); + return urlParams.get('ticket_id'); + } + + function getLocalStorageKey() { + return 'time-' + ticketID; + } + + function loadTimeFromStorage() { + var storedTime = localStorage.getItem(getLocalStorageKey()); + if (storedTime) { + var parsed = JSON.parse(storedTime); + hours = parsed.hours || 0; + minutes = parsed.minutes || 0; + seconds = parsed.seconds || 0; + } + } + + function storeTimeToStorage() { + var timeData = { + hours: hours, + minutes: minutes, + seconds: seconds + }; + localStorage.setItem(getLocalStorageKey(), JSON.stringify(timeData)); + } function startTimer() { - if(timerInterval === null) { + if (timerInterval === null) { timerInterval = setInterval(countTime, 1000); } } - // Counter function countTime() { ++seconds; if (seconds == 60) { @@ -25,24 +56,11 @@ document.addEventListener("DOMContentLoaded", function() { hours++; } - // Total time worked var time_worked = pad(hours) + ":" + pad(minutes) + ":" + pad(seconds); document.getElementById("time_worked").value = time_worked; + storeTimeToStorage(); } - // Allows manually adjusting the timer - function setTime() { - var time_as_text = document.getElementById("time_worked").value; - const time_text_array = time_as_text.split(":"); - hours = parseInt(time_text_array[0]); - minutes = parseInt(time_text_array[1]); - seconds = parseInt(time_text_array[2]); - if (!isPaused) { - startTimer(); // start the timer when time is manually adjusted - } - } - - // This function "pads" out the values, adding zeros if they are required function pad(val) { var valString = val + ""; if (valString.length < 2) { @@ -52,56 +70,56 @@ document.addEventListener("DOMContentLoaded", function() { } } - // Function to pause the timer function pauseTimer() { - if(timerInterval !== null) { + if (timerInterval !== null) { clearInterval(timerInterval); timerInterval = null; } } - // Function to toggle the timer function toggleTimer() { var button = document.getElementById("toggleTimer"); - if(isPaused) { - // If timer is paused, then start the timer and change the button icon to pause + if (isPaused) { startTimer(); button.innerHTML = ''; isPaused = false; } else { - // If timer is running, then pause the timer and change the button icon to play pauseTimer(); button.innerHTML = ''; isPaused = true; } } + function setTime() { + var time_as_text = document.getElementById("time_worked").value; + const time_text_array = time_as_text.split(":"); + hours = parseInt(time_text_array[0]); + minutes = parseInt(time_text_array[1]); + seconds = parseInt(time_text_array[2]); + if (!isPaused) { + startTimer(); + } + } function pauseForEdit() { - wasRunningBeforeEdit = !isPaused; // check if timer was running + var wasRunningBeforeEdit = !isPaused; pauseTimer(); } function restartAfterEdit() { + var wasRunningBeforeEdit = !isPaused; if (wasRunningBeforeEdit) { startTimer(); } } - // Start timer when page is loaded startTimer(); - // Set setTime as the onchange event handler for the time input + // Event listeners document.getElementById("time_worked").addEventListener('change', setTime); - - // Toggle timer when button is clicked document.getElementById("toggleTimer").addEventListener('click', toggleTimer); - - // Function to pause the timer when the time input is clicked document.getElementById("time_worked").addEventListener('focus', pauseForEdit); - - // Function to restart the timer when the time input is clicked away from document.getElementById("time_worked").addEventListener('blur', restartAfterEdit); -}); \ No newline at end of file +}); From ea3e1df78449b0b067b29dcf9078d3dc1d9b572c Mon Sep 17 00:00:00 2001 From: Andrew Malsbury Date: Wed, 25 Oct 2023 19:02:23 +0000 Subject: [PATCH 2/4] clear local storage when responding --- js/ticket_time_tracking.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/js/ticket_time_tracking.js b/js/ticket_time_tracking.js index f574561f..691ad6de 100644 --- a/js/ticket_time_tracking.js +++ b/js/ticket_time_tracking.js @@ -39,6 +39,10 @@ document.addEventListener("DOMContentLoaded", function() { localStorage.setItem(getLocalStorageKey(), JSON.stringify(timeData)); } + function clearTimeStorage() { + localStorage.removeItem(getLocalStorageKey()); + } + function startTimer() { if (timerInterval === null) { timerInterval = setInterval(countTime, 1000); @@ -121,5 +125,8 @@ document.addEventListener("DOMContentLoaded", function() { document.getElementById("toggleTimer").addEventListener('click', toggleTimer); document.getElementById("time_worked").addEventListener('focus', pauseForEdit); document.getElementById("time_worked").addEventListener('blur', restartAfterEdit); + document.getElementById("ticket_add_reply").addEventListener('click', function() { + clearTimeStorage(); + }); }); From a29a97214ab2a9bda4498fc282bfec04826fa1c2 Mon Sep 17 00:00:00 2001 From: Andrew Malsbury Date: Wed, 25 Oct 2023 19:16:07 +0000 Subject: [PATCH 3/4] Update to keep incrementing while tab is closed --- js/ticket_time_tracking.js | 135 +++++++++++++------------------------ 1 file changed, 46 insertions(+), 89 deletions(-) diff --git a/js/ticket_time_tracking.js b/js/ticket_time_tracking.js index 691ad6de..8c293852 100644 --- a/js/ticket_time_tracking.js +++ b/js/ticket_time_tracking.js @@ -1,132 +1,89 @@ document.addEventListener("DOMContentLoaded", function() { - var hours = 0; - var minutes = 0; - var seconds = 0; var timerInterval = null; var isPaused = false; - var ticketID = getCurrentTicketID(); - - // Load stored time if available - loadTimeFromStorage(); + var elapsedSecs = getElapsedSeconds(); function getCurrentTicketID() { const urlParams = new URLSearchParams(window.location.search); return urlParams.get('ticket_id'); } - function getLocalStorageKey() { - return 'time-' + ticketID; + function getLocalStorageKey(suffix) { + return ticketID + "-" + suffix; } - function loadTimeFromStorage() { - var storedTime = localStorage.getItem(getLocalStorageKey()); - if (storedTime) { - var parsed = JSON.parse(storedTime); - hours = parsed.hours || 0; - minutes = parsed.minutes || 0; - seconds = parsed.seconds || 0; - } + function getElapsedSeconds() { + let storedStartTime = localStorage.getItem(getLocalStorageKey("startTime")); + let pausedTime = parseInt(localStorage.getItem(getLocalStorageKey("pausedTime")) || "0"); + + if (!storedStartTime) return pausedTime; + + let timeSinceStart = Math.floor((Date.now() - parseInt(storedStartTime)) / 1000); + return pausedTime + timeSinceStart; } - function storeTimeToStorage() { - var timeData = { - hours: hours, - minutes: minutes, - seconds: seconds - }; - localStorage.setItem(getLocalStorageKey(), JSON.stringify(timeData)); + function displayTime() { + let totalSeconds = elapsedSecs; + let hours = Math.floor(totalSeconds / 3600); + totalSeconds %= 3600; + let minutes = Math.floor(totalSeconds / 60); + let seconds = totalSeconds % 60; + + document.getElementById("time_worked").value = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`; } - function clearTimeStorage() { - localStorage.removeItem(getLocalStorageKey()); + function pad(val) { + return val < 10 ? "0" + val : val; + } + + function countTime() { + elapsedSecs++; + displayTime(); } function startTimer() { - if (timerInterval === null) { + if (!localStorage.getItem(getLocalStorageKey("startTime"))) { + localStorage.setItem(getLocalStorageKey("startTime"), Date.now().toString()); + } + if (!isPaused && timerInterval === null) { timerInterval = setInterval(countTime, 1000); } } - function countTime() { - ++seconds; - if (seconds == 60) { - seconds = 0; - minutes++; - } - if (minutes == 60) { - minutes = 0; - hours++; - } - - var time_worked = pad(hours) + ":" + pad(minutes) + ":" + pad(seconds); - document.getElementById("time_worked").value = time_worked; - storeTimeToStorage(); - } - - function pad(val) { - var valString = val + ""; - if (valString.length < 2) { - return "0" + valString; - } else { - return valString; - } - } - function pauseTimer() { - if (timerInterval !== null) { + if (timerInterval) { clearInterval(timerInterval); timerInterval = null; } + let currentElapsed = getElapsedSeconds(); + localStorage.setItem(getLocalStorageKey("pausedTime"), currentElapsed.toString()); + localStorage.removeItem(getLocalStorageKey("startTime")); } - function toggleTimer() { - var button = document.getElementById("toggleTimer"); + function clearTimeStorage() { + localStorage.removeItem(getLocalStorageKey("startTime")); + localStorage.removeItem(getLocalStorageKey("pausedTime")); + } + + document.getElementById("toggleTimer").addEventListener('click', function() { if (isPaused) { startTimer(); - button.innerHTML = ''; isPaused = false; } else { pauseTimer(); - button.innerHTML = ''; isPaused = true; } - } + }); - function setTime() { - var time_as_text = document.getElementById("time_worked").value; - const time_text_array = time_as_text.split(":"); - hours = parseInt(time_text_array[0]); - minutes = parseInt(time_text_array[1]); - seconds = parseInt(time_text_array[2]); - if (!isPaused) { - startTimer(); - } - } - - function pauseForEdit() { - var wasRunningBeforeEdit = !isPaused; - pauseTimer(); - } - - function restartAfterEdit() { - var wasRunningBeforeEdit = !isPaused; - if (wasRunningBeforeEdit) { - startTimer(); - } - } - - // Start timer when page is loaded - startTimer(); - - // Event listeners - document.getElementById("time_worked").addEventListener('change', setTime); - document.getElementById("toggleTimer").addEventListener('click', toggleTimer); - document.getElementById("time_worked").addEventListener('focus', pauseForEdit); - document.getElementById("time_worked").addEventListener('blur', restartAfterEdit); document.getElementById("ticket_add_reply").addEventListener('click', function() { + pauseTimer(); clearTimeStorage(); }); + // Initialize on page load + displayTime(); + startTimer(); + }); From f6cdf5ac51373bbec28011d5892340126aaffa73 Mon Sep 17 00:00:00 2001 From: Andrew Malsbury Date: Wed, 25 Oct 2023 19:37:17 +0000 Subject: [PATCH 4/4] Added comments because I dont know JavaScript --- js/ticket_time_tracking.js | 67 +++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/js/ticket_time_tracking.js b/js/ticket_time_tracking.js index 8c293852..ee682a08 100644 --- a/js/ticket_time_tracking.js +++ b/js/ticket_time_tracking.js @@ -1,48 +1,88 @@ -document.addEventListener("DOMContentLoaded", function() { +// Description: This file contains the javascript for the ticket time tracking feature +document.addEventListener("DOMContentLoaded", function() { + // Initialize variables var timerInterval = null; var isPaused = false; var ticketID = getCurrentTicketID(); var elapsedSecs = getElapsedSeconds(); + + // Get the ticket ID from the URL + // Inputs: None + // Outputs: The ticket ID from the URL + // Document Interactions: None function getCurrentTicketID() { const urlParams = new URLSearchParams(window.location.search); return urlParams.get('ticket_id'); } + + // Get the local storage key for the ticket + // Inputs: The suffix to append to the key + // Outputs: The local storage key for the ticket + // Document Interactions: None + function getLocalStorageKey(suffix) { return ticketID + "-" + suffix; } + + // Get the elapsed seconds from local storage + // Inputs: None + // Outputs: The elapsed seconds from local storage + // Document Interactions: None + function getElapsedSeconds() { let storedStartTime = localStorage.getItem(getLocalStorageKey("startTime")); let pausedTime = parseInt(localStorage.getItem(getLocalStorageKey("pausedTime")) || "0"); - + // If there is no start time, return the paused time if (!storedStartTime) return pausedTime; - + // Otherwise, return the paused time plus the time since the start time let timeSinceStart = Math.floor((Date.now() - parseInt(storedStartTime)) / 1000); return pausedTime + timeSinceStart; } + // Display the elapsed time + // Inputs: None + // Outputs: None + // Document Interactions: Updates the time worked input + function displayTime() { let totalSeconds = elapsedSecs; let hours = Math.floor(totalSeconds / 3600); totalSeconds %= 3600; let minutes = Math.floor(totalSeconds / 60); let seconds = totalSeconds % 60; - + // Update the time worked input document.getElementById("time_worked").value = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`; } - + + // Pad a number with a leading zero if it is less than 10 + // Inputs: The number to pad + // Outputs: The padded number + // Document Interactions: None + function pad(val) { return val < 10 ? "0" + val : val; } + // Count the time + // Inputs: None + // Outputs: None + // Document Interactions: Updates the elapsed time + function countTime() { elapsedSecs++; displayTime(); } + + // Start the timer + // Inputs: None + // Outputs: None + // Document Interactions: None + function startTimer() { if (!localStorage.getItem(getLocalStorageKey("startTime"))) { localStorage.setItem(getLocalStorageKey("startTime"), Date.now().toString()); @@ -52,6 +92,11 @@ document.addEventListener("DOMContentLoaded", function() { } } + // Pause the timer + // Inputs: None + // Outputs: None + // Document Interactions: None + function pauseTimer() { if (timerInterval) { clearInterval(timerInterval); @@ -62,27 +107,39 @@ document.addEventListener("DOMContentLoaded", function() { localStorage.removeItem(getLocalStorageKey("startTime")); } + // Clear the time storage + // Inputs: None + // Outputs: None + // Document Interactions: None + function clearTimeStorage() { localStorage.removeItem(getLocalStorageKey("startTime")); localStorage.removeItem(getLocalStorageKey("pausedTime")); } + // Add event listeners + + // When toggleTimer is clicked, toggle the timer document.getElementById("toggleTimer").addEventListener('click', function() { if (isPaused) { + // If the timer is paused, start it startTimer(); isPaused = false; } else { + // If the timer is running, pause it pauseTimer(); isPaused = true; } }); + // When the ticket is submitted, clear the time storage document.getElementById("ticket_add_reply").addEventListener('click', function() { pauseTimer(); clearTimeStorage(); }); // Initialize on page load + // If the timer is paused, start it displayTime(); startTimer();