$(document).ready(function() { function createStopwatch(name, id, currentTime = 0, pausedAt = 0) { if (!id) { id = 'stopwatch' + ($('#stopWatches').children().length + 1); } var panelHtml = generatePanelHtml( name, id, 'glyphicon-time', 'stopwatch', 0, currentTime, pausedAt ); $('#stopWatches').append(panelHtml); setupStopwatch( id, currentTime, pausedAt ); } function createTimer( name, id, totalTime = 0, currentTime = 0, pausedAt = 0 ) { if (!id) { id = 'timer' + ($('#timers').children().length + 1); } var panelHtml = generatePanelHtml( name, id, 'glyphicon-hourglass', 'timer', totalTime, currentTime, pausedAt ); $('#timers').append(panelHtml); setupTimer( id, totalTime, currentTime, pausedAt ); } function generatePanelHtml(name, id, iconClass, type, totalSeconds, currentSeconds = 0, pausedAt = 0) { var panelColor, readout, defaultTime, resumeButtons; if (type === 'timer') { panelColor = 'primary'; defaultTime = `Default Time: ${formatTime(totalSeconds)}
`; readout = `

Time left: ${formatTime(currentSeconds)}

`; } else { panelColor = 'info'; defaultTime = ''; readout = `

Time elapsed: ${formatTime(currentSeconds)}

`; } if ( 0 != pausedAt ) { resumeButtons = ` `; } else { resumeButtons = ` `; } return ` `; } function generateButtons(id, type) { var duplicate = ''; if (type === 'timer') { duplicate = ``; } return ` ${duplicate} `; } function setupStopwatch(id, currentTime, pausedAt) { var interval; if ( 0 == pausedAt ) { interval = setInterval(() => updateDisplay(id, ++currentTime), 1000); } else { updateDisplay( id, currentTime ); } setData(id, interval, currentTime); setupControlButtons(id, 'stopwatch', () => updateDisplay(id, ++currentTime)); } function setupTimer( id, totalTime, currentTime, pausedAt = 0 ) { var interval; if ( 0 == pausedAt ) { interval = setInterval(() => { if (currentTime <= 0) { clearInterval(interval); $('#' + id).html("Time's up!"); } else { updateDisplay(id, --currentTime); } }, 1000); } else { updateDisplay( id, currentTime ); } setData( id, interval, currentTime, totalTime ); setupControlButtons(id, 'timer', () => { if (currentTime <= 0) { clearInterval(interval); $('#' + id).html("Time's up!"); } else { updateDisplay(id, --currentTime); } }); } function setData( id, interval, elapsed, original = 0 ) { $('#' + id).data({ 'interval': interval, 'elapsed': elapsed, 'original': original }); } function updateDisplay(id, time) { $('#' + id).html(`Time: ${formatTime(time)}`); $('#' + id).data({ 'elapsed': time }); } function setupControlButtons(id, type, updateFn) { var $pause = $(`#Pause${id}`); var $resume = $(`#Resume${id}`); var $remove = $(`#Remove${id}`); var $reset = $(`#Reset${id}`); var $duplicate = $(`#Duplicate${id}`); if (type === 'timer') { $duplicate.click(function() { var element = $( '#Panel' + id ); var name = element.find('.timer-name').text(); createTimer( name + ' Copy', 0, $('#' + id).data('original'), $('#' + id).data('original'), true ); }); } $pause.click(function() { clearInterval($('#' + id).data('interval')); $pause.hide(); $resume.show(); }); $resume.click(function() { var element = $( '#' + id ); var elapsedTime = element.data('elapsed') || 0; if ( type === 'timer') { var newInterval = setInterval( function() { elapsedTime--; updateDisplay( id, elapsedTime ); element.data('elapsed', elapsedTime ); }, 1000); } else { var newInterval = setInterval(function() { elapsedTime++; updateDisplay( id, elapsedTime ); element.data( 'elapsed', elapsedTime ); }, 1000); } element.data( 'interval', newInterval ); $resume.hide(); $pause.show(); }); $remove.click(function() { clearInterval($('#' + id).data('interval')); $.post('/timers/remove', { id: id, }).done(function(response) { $('#' + id).closest('.panel').remove(); alert('Timer removed successfully!'); }).fail(function() { alert('Error removing timer.'); }); }); $reset.click(function() { var element = $( '#' + id ); // get the element we are working with var originalTime = $( '#' + id ).data('original') || 0; // get the original time clearInterval( element.data('interval') ); //stop the countdown if ( type === 'timer') { element.data( 'elapsed', originalTime ); // set time remaining to original time updateDisplay( id, originalTime ); // let the display know things have changed // if its currently ticking, make it keep ticking if ( ! $resume.is(":visible") ) { var newInterval = setInterval( function() { if ( originalTime <= 0 ) { clearInterval( newInterval ); } else { originalTime--; element.data('elapsed', originalTime ); } updateDisplay( id, originalTime ); }, 1000); element.data( 'interval', newInterval ); } } else { var elapsedTime = 0; element.data( 'elapsed', elapsedTime ); updateDisplay( id, elapsedTime ); var newInterval = setInterval(function() { elapsedTime++; updateDisplay( id, elapsedTime ); element.data( 'elapsed', elapsedTime ); }, 1000); element.data( 'interval', newInterval ); } }); } function getFormattedDate() { var date = new Date(); var options = { year: 'numeric', month: 'long', day: 'numeric' }; return date.toLocaleDateString('en-US', options); } function changeId( currentID, newID ) { $(`#${currentID}`).attr('id', newID); $(`#Resume${currentID}`).attr('id', `Resume${newID}`); $(`#Pause${currentID}`).attr('id', `Pause${newID}`); $(`#Panel${currentID}`).attr('id', `Panel${newID}`); $(`#Collapse${currentID}`).attr('id', `Collapse${newID}`); $(`#Save${currentID}`).attr('id', `Save${newID}`).attr('onclick', `saveTimer('${newID}')`); $(`#Remove${currentID}`).attr('id', `Remove${newID}`); $(`#Reset${currentID}`).attr('id', `Reset${newID}`); $(`#Duplicate${currentID}`).attr('id', `Duplicate${newID}`); $(`button[data-target="#Collapse${currentID}"]`).attr('data-target', `#Collapse${newID}`); $(`button[aria-controls="#Collapse${currentID}"]`).attr('aria-controls', `#Collapse${newID}`) } function formatTime(seconds) { var hrs = Math.floor(seconds / 3600); var mins = Math.floor((seconds % 3600) / 60); var secs = seconds % 60; return `${hrs > 0 ? hrs + 'h ' : ''}${mins > 0 ? mins + 'm ' : ''}${secs}s`; } $('#addStopwatch').click(function() { createStopwatch($('#stopwatchName').val()); }); $('#addTimer').click(function() { var name = $('#name').val(); var hours = parseInt($('#hours').val()) || 0; var minutes = parseInt($('#minutes').val()) || 0; var seconds = parseInt($('#seconds').val()) || 0; var totalTime = hours * 3600 + minutes * 60 + seconds; if ( totalTime > 0 ) { createTimer( name, '', totalTime, totalTime ); // for new timers, it starts at max time } else { alert( 'Please enter a valid number of hours, minutes, or seconds.' ); } }); $('.timer-row').each( function() { var $row = $(this); var name = $row.find('.timer-name').text(); var currentSeconds = parseInt($row.find('.timer-current').text(), 10); var pausedAt = $row.find('.timer-paused').text(); var hours = parseInt($row.find('.timer-hours').text(), 10); var minutes = parseInt($row.find('.timer-minutes').text(), 10); var seconds = parseInt($row.find('.timer-seconds').text(), 10); var id = $row.find('.timer-id').text(); var totalTime = hours * 3600 + minutes * 60 + seconds; var createdAt = $row.find('.timer-created').text(); createTimer( name, id, totalTime, currentSeconds, pausedAt ); $row.remove(); }); $('.stopwatch-row').each( function() { var $row = $(this); var name = $row.find('.timer-name').text(); var currentSeconds = parseInt($row.find('.timer-current').text(), 10); var pausedAt = $row.find('.timer-paused').text(); var id = $row.find('.timer-id').text(); var createdAt = $row.find('.timer-created').text(); createStopwatch( name, id, currentSeconds, pausedAt ); $row.remove(); }); window.saveTimer = function( elementId ) { var type; if ( elementId.includes('timer') ) { type = 'timer'; } else if ( elementId.includes('stopwatch') ) { type = 'stopwatch'; } else { return updateTimer( elementId ); } var element = $( '#Panel' + elementId ); var name = element.find('.timer-name').text(); var originalTime = $('#' + elementId).data('original') || 0; var totalSeconds = $('#' + elementId).data('elapsed') || 0; var hours = Math.floor(originalTime / 3600); var minutes = Math.floor((originalTime % 3600) / 60); var seconds = originalTime % 60; $.post('/timers/save', { name: name.trim(), type: type, hours: hours, minutes: minutes, seconds: seconds, currentSeconds: totalSeconds, }).done(function(response) { var responseData = JSON.parse(response); var timerId = responseData.data.id; alert('Timer saved successfully! ID: ' + timerId); }).fail(function() { alert('Error saving timer.'); }); }; function updateTimer( elementId ) { var $resume = $(`#Resume${elementId}`); var totalSeconds = $('#' + elementId).data('elapsed') || 0; var fields = {}; if ( $resume.is(":visible") ) { fields.paused = true; } fields.currentSeconds = totalSeconds; $.post( '/timers/update/' + elementId, fields ).done(function(response) { alert('Timer updated successfully!'); }).fail(function() { alert('Error saving timer.'); }); } });