diff --git a/core/template/cdown/control/control.js b/core/template/cdown/control/control.js
index 2ad652f..7f23421 100644
--- a/core/template/cdown/control/control.js
+++ b/core/template/cdown/control/control.js
@@ -86,7 +86,7 @@ socket.addEventListener('message', (event) => {
resetButton.textContent = translateElements.timer.buttons.reset
if (elementVariables && typeof elementVariables === 'object') {
- checkTextTime = MsToText(elementVariables.textmilliseconds)
+ checkTextTime = MsToText(elementVariables.textMilliseconds)
checkHexColor = elementVariables.colorText
// Format selector options
@@ -101,10 +101,10 @@ socket.addEventListener('message', (event) => {
// Perform necessary actions with the variables here
textMsg.textContent = elementVariables.msgEnd
if (elementVariables.msgEnd === '') {
- textMsg.textContent = translateElements.timer.ph_msgend
+ textMsg.textContent = translateElements.timer.phMsgEnd
textMsg.style.color = '#555'
} else { textMsg.style.color = '#000' }
- timeText.value = MsToText(elementVariables.textmilliseconds)
+ timeText.value = MsToText(elementVariables.textMilliseconds)
formatSelector.value = elementVariables.formatTime
fontSelect.value = elementVariables.font
fontSize.value = elementVariables.size
@@ -122,10 +122,10 @@ socket.addEventListener('message', (event) => {
if (message[classElement].status !== 'started') {
textMsg.textContent = message[classElement].msgEnd
if (message[classElement].msgEnd === '') {
- textMsg.textContent = translateElements.timer.ph_msgend
+ textMsg.textContent = translateElements.timer.phMsgEnd
textMsg.style.color = '#555'
} else { textMsg.style.color = '#000' }
- timeText.value = MsToText(message[classElement].textmilliseconds)
+ timeText.value = MsToText(message[classElement].textMilliseconds)
formatSelector.value = message[classElement].formatTime
fontSelect.value = message[classElement].font
fontSize.value = message[classElement].size
@@ -172,7 +172,7 @@ timeText.addEventListener('change', () => {
const textTime = timeText.value.trim()
// Regular expression to check the correct time format
- const timeRegex = /^([0-9]+):([0-5]?[0-9]):([0-5]?[0-9])$/
+ const timeRegex = /^(\d+):([0-5]?\d):([0-5]?\d)$/
if (timeRegex.test(textTime)) {
checkTextTime = textTime
@@ -218,7 +218,7 @@ subContainer.addEventListener('click', (event) => {
})
textMsg.addEventListener('focus', () => {
- if (textMsg.textContent === translateElements.timer.ph_msgend) {
+ if (textMsg.textContent === translateElements.timer.phMsgEnd) {
textMsg.textContent = ''
textMsg.style.color = '#000'
}
@@ -227,17 +227,17 @@ textMsg.addEventListener('focus', () => {
textMsg.addEventListener('blur', () => {
socket.send(JSON.stringify({ action: 'editMsgCdown', msg: textMsg.textContent, classElement }))
if (textMsg.textContent === '') {
- textMsg.textContent = translateElements.timer.ph_msgend
+ textMsg.textContent = translateElements.timer.phMsgEnd
textMsg.style.color = '#555'
} else { textMsg.style.color = '#000' }
})
formatSelector.addEventListener('change', () => {
- socket.send(JSON.stringify({ action: 'changeFormatCdown', format: formatSelector.value, classElement }))
+ socket.send(JSON.stringify({ action: 'changeFormat', format: formatSelector.value, classElement }))
})
fontSelect.addEventListener('change', () => {
- socket.send(JSON.stringify({ action: 'changeFontCdown', font: fontSelect.value, classElement }))
+ socket.send(JSON.stringify({ action: 'changeFont', font: fontSelect.value, classElement }))
})
fontSize.addEventListener('change', () => {
@@ -255,37 +255,37 @@ fontSize.addEventListener('change', () => {
}
// Send the new size to the server
- socket.send(JSON.stringify({ action: 'changeSizeCdown', size: newSize, classElement }))
+ socket.send(JSON.stringify({ action: 'changeSize', size: newSize, classElement }))
})
boldButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatCdown', format: 'bold', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'bold', classElement }))
})
italicButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatCdown', format: 'italic', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'italic', classElement }))
})
underlineButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatCdown', format: 'underline', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'underline', classElement }))
})
alignLeftButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignCdown', align: 'left', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'left', classElement }))
})
alignCenterButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignCdown', align: 'center', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'center', classElement }))
})
alignRightButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignCdown', align: 'right', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'right', classElement }))
})
colorPicker.addEventListener('change', () => {
checkHexColor = colorPicker.value.toUpperCase()
// If the hexadecimal code is valid, send the color to the server
- socket.send(JSON.stringify({ action: 'changeColorCdown', color: colorPicker.value.toUpperCase(), classElement }))
+ socket.send(JSON.stringify({ action: 'changeColor', color: colorPicker.value.toUpperCase(), classElement }))
colorHex.value = checkHexColor
})
@@ -298,7 +298,7 @@ colorHex.addEventListener('change', () => {
if (hexRegex.test(hexColor)) {
checkHexColor = hexColor.toUpperCase()
// If the hexadecimal code is valid, send the color to the server
- socket.send(JSON.stringify({ action: 'changeColorCdown', color: checkHexColor, classElement }))
+ socket.send(JSON.stringify({ action: 'changeColor', color: checkHexColor, classElement }))
colorPicker.value = checkHexColor
colorHex.value = checkHexColor
} else {
diff --git a/core/template/cdown/view/client.js b/core/template/cdown/view/client.js
index 492550e..a57883c 100644
--- a/core/template/cdown/view/client.js
+++ b/core/template/cdown/view/client.js
@@ -39,7 +39,7 @@ socket.addEventListener('message', (event) => {
}
formatTimeVar = message[classElement].formatTime
- if (message[classElement].status === 'stopped') {
+ if (message[classElement].status === 'ended') {
if (message[classElement].milliseconds !== 0) {
updateTimeDisplay(formatTimeVar, message[classElement].milliseconds)
} else if (message[classElement].msgEnd !== '') {
diff --git a/core/template/cdowntime/control/control.js b/core/template/cdowntime/control/control.js
index db161c9..1943afb 100644
--- a/core/template/cdowntime/control/control.js
+++ b/core/template/cdowntime/control/control.js
@@ -107,7 +107,7 @@ socket.addEventListener('message', (event) => {
// Perform necessary actions with the variables here
textMsg.textContent = elementVariables.msgEnd
if (elementVariables.msgEnd === '') {
- textMsg.textContent = translateElements.timer.ph_msgend
+ textMsg.textContent = translateElements.timer.phMsgEnd
textMsg.style.color = '#555'
} else { textMsg.style.color = '#000' }
timeData.value = new Date(elementVariables.endDatetime).toLocaleString('en-CA', { timeZone: elementVariables.timezone, hour12: false }).replace(/,\s/, 'T')
@@ -189,7 +189,7 @@ subContainer.addEventListener('click', (event) => {
})
textMsg.addEventListener('focus', () => {
- if (textMsg.textContent === translateElements.timer.ph_msgend) {
+ if (textMsg.textContent === translateElements.timer.phMsgEnd) {
textMsg.textContent = ''
textMsg.style.color = '#000'
}
@@ -198,17 +198,17 @@ textMsg.addEventListener('focus', () => {
textMsg.addEventListener('blur', () => {
socket.send(JSON.stringify({ action: 'editMsgCdownTime', msg: textMsg.textContent, classElement }))
if (textMsg.textContent === '') {
- textMsg.textContent = translateElements.timer.ph_msgend
+ textMsg.textContent = translateElements.timer.phMsgEnd
textMsg.style.color = '#555'
} else { textMsg.style.color = '#000' }
})
formatSelector.addEventListener('change', () => {
- socket.send(JSON.stringify({ action: 'changeFormatCdownTime', format: formatSelector.value, classElement }))
+ socket.send(JSON.stringify({ action: 'changeFormat', format: formatSelector.value, classElement }))
})
fontSelect.addEventListener('change', () => {
- socket.send(JSON.stringify({ action: 'changeFontCdownTime', font: fontSelect.value, classElement }))
+ socket.send(JSON.stringify({ action: 'changeFont', font: fontSelect.value, classElement }))
})
fontSize.addEventListener('change', () => {
@@ -226,37 +226,37 @@ fontSize.addEventListener('change', () => {
}
// Send the new size to the server
- socket.send(JSON.stringify({ action: 'changeSizeCdownTime', size: newSize, classElement }))
+ socket.send(JSON.stringify({ action: 'changeSize', size: newSize, classElement }))
})
boldButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatCdownTime', format: 'bold', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'bold', classElement }))
})
italicButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatCdownTime', format: 'italic', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'italic', classElement }))
})
underlineButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatCdownTime', format: 'underline', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'underline', classElement }))
})
alignLeftButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignCdownTime', align: 'left', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'left', classElement }))
})
alignCenterButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignCdownTime', align: 'center', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'center', classElement }))
})
alignRightButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignCdownTime', align: 'right', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'right', classElement }))
})
colorPicker.addEventListener('change', () => {
checkHexColor = colorPicker.value.toUpperCase()
// If the hexadecimal code is valid, send the color to the server
- socket.send(JSON.stringify({ action: 'changeColorCdownTime', color: colorPicker.value.toUpperCase(), classElement }))
+ socket.send(JSON.stringify({ action: 'changeColor', color: colorPicker.value.toUpperCase(), classElement }))
colorHex.value = checkHexColor
})
@@ -269,7 +269,7 @@ colorHex.addEventListener('change', () => {
if (hexRegex.test(hexColor)) {
checkHexColor = hexColor.toUpperCase()
// If the hexadecimal code is valid, send the color to the server
- socket.send(JSON.stringify({ action: 'changeColorCdownTime', color: checkHexColor, classElement }))
+ socket.send(JSON.stringify({ action: 'changeColor', color: checkHexColor, classElement }))
colorPicker.value = checkHexColor
colorHex.value = checkHexColor
} else {
diff --git a/core/template/crono/control/control.js b/core/template/crono/control/control.js
index e5606c1..bd8270c 100644
--- a/core/template/crono/control/control.js
+++ b/core/template/crono/control/control.js
@@ -184,11 +184,11 @@ subContainer.addEventListener('click', (event) => {
})
formatSelector.addEventListener('change', () => {
- socket.send(JSON.stringify({ action: 'changeFormatCrono', format: formatSelector.value, classElement }))
+ socket.send(JSON.stringify({ action: 'changeFormat', format: formatSelector.value, classElement }))
})
fontSelect.addEventListener('change', () => {
- socket.send(JSON.stringify({ action: 'changeFontCrono', font: fontSelect.value, classElement }))
+ socket.send(JSON.stringify({ action: 'changeFont', font: fontSelect.value, classElement }))
})
fontSize.addEventListener('change', () => {
@@ -200,36 +200,36 @@ fontSize.addEventListener('change', () => {
fontSize.value = maxSize
}
- socket.send(JSON.stringify({ action: 'changeSizeCrono', size: newSize, classElement }))
+ socket.send(JSON.stringify({ action: 'changeSize', size: newSize, classElement }))
})
boldButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatCrono', format: 'bold', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'bold', classElement }))
})
italicButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatCrono', format: 'italic', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'italic', classElement }))
})
underlineButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatCrono', format: 'underline', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'underline', classElement }))
})
alignLeftButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignCrono', align: 'left', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'left', classElement }))
})
alignCenterButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignCrono', align: 'center', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'center', classElement }))
})
alignRightButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignCrono', align: 'right', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'right', classElement }))
})
colorPicker.addEventListener('change', () => {
checkHexColor = colorPicker.value.toUpperCase()
- socket.send(JSON.stringify({ action: 'changeColorCrono', color: checkHexColor, classElement }))
+ socket.send(JSON.stringify({ action: 'changeColor', color: checkHexColor, classElement }))
colorHex.value = checkHexColor
})
@@ -239,7 +239,7 @@ colorHex.addEventListener('change', () => {
if (hexRegex.test(hexColor)) {
checkHexColor = hexColor.toUpperCase()
- socket.send(JSON.stringify({ action: 'changeColorCrono', color: checkHexColor, classElement }))
+ socket.send(JSON.stringify({ action: 'changeColor', color: checkHexColor, classElement }))
colorPicker.value = checkHexColor
colorHex.value = checkHexColor
} else {
diff --git a/core/template/extensible/control/blank.html b/core/template/extensible/control/blank.html
new file mode 100644
index 0000000..1e32f96
--- /dev/null
+++ b/core/template/extensible/control/blank.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
URL Action
+
+
+
+
+
+
diff --git a/core/template/extensible/control/control.js b/core/template/extensible/control/control.js
new file mode 100644
index 0000000..5ee63fd
--- /dev/null
+++ b/core/template/extensible/control/control.js
@@ -0,0 +1,456 @@
+const controlButton = document.getElementById('controlButton')
+const resetButton = document.getElementById('resetButton')
+const timeText = document.getElementById('timeText')
+const addContainer = document.getElementById('buttonsaddtime')
+const subContainer = document.getElementById('buttonssubtime')
+const checkboxStopAdd = document.getElementById('checkboxStopAdd')
+const checkboxLabelStopAdd = document.getElementById('checkboxLabelStopAdd')
+const checkboxPauseAdd = document.getElementById('checkboxPauseAdd')
+const checkboxLabelPauseAdd = document.getElementById('checkboxLabelPauseAdd')
+const textMsg = document.getElementById('text-endmsg')
+const formatSelectorCrono = document.getElementById('formatSelectorCrono')
+const formatSelectorCdown = document.getElementById('formatSelectorCdown')
+const fontSelect = document.getElementById('fontSelect') // Font selector
+const fontSize = document.getElementById('fontSize')
+const boldButton = document.getElementById('boldButton')
+const italicButton = document.getElementById('italicButton')
+const underlineButton = document.getElementById('underlineButton')
+const alignLeftButton = document.getElementById('alignLeft')
+const alignCenterButton = document.getElementById('alignCenter')
+const alignRightButton = document.getElementById('alignRight')
+const colorPicker = document.getElementById('colorPicker')
+const colorHex = document.getElementById('colorHex')
+const titlePage = document.getElementById('titlePage')
+const selectorLang = document.getElementById('language-selector')
+const switchTheme = document.getElementById('switch-theme')
+// const test = document.getElementById('test');
+const socket = new WebSocket('ws://localhost:3000')
+
+const classElement = window.location.href.split('/')[3]
+titlePage.textContent = classElement + ' - Control'
+let translateElements
+
+let checkTextTime
+let checkHexColor
+
+socket.addEventListener('open', (event) => {
+ console.log('WebSocket Connection Opened')
+
+ // Ask the WebSocket server to send variable data
+ socket.send(JSON.stringify({ action: 'getVariables', classElement }))
+})
+
+socket.addEventListener('message', (event) => {
+ const message = JSON.parse(event.data)
+
+ if (message.action === 'reload') {
+ window.location.reload()
+ }
+
+ if (message.fonts) {
+ // If the message contains a list of fonts
+ updateFontSelector(message.fonts)
+ }
+ if (fontSelect.innerHTML !== '') {
+ // Call the function to get the maximum font size width
+ const maxWidth = getMaxSizeWidth()
+
+ // Set the calculated width as the CSS style for the font size selector
+ fontSize.style.width = maxWidth
+
+ if (message.action === 'sendVariables' && message.classElement === classElement) {
+ // If the message contains variable data
+ const elementVariables = message.variables
+ translateElements = message.translateElements
+
+ // Config and translates
+ switchTheme.checked = message.config.themedark
+ if (message.config.themedark) {
+ document.body.classList.remove('light-theme')
+ document.body.classList.add('dark-theme')
+ } else {
+ document.body.classList.remove('dark-theme')
+ document.body.classList.add('light-theme')
+ }
+
+ selectorLang.innerHTML = ''
+ Object.keys(message.formats.langs).forEach((format) => {
+ const option = document.createElement('option')
+ option.value = format
+ option.textContent = message.formats.langs[format]
+ selectorLang.appendChild(option)
+ })
+ selectorLang.value = Object.keys(message.formats.langs).includes(message.config.lang)
+ ? message.config.lang
+ : 'en'
+ document.documentElement.lang = Object.keys(message.formats.langs).includes(message.config.lang)
+ ? message.config.lang
+ : 'en'
+
+ controlButton.textContent = translateElements.timer.buttons.start
+ resetButton.textContent = translateElements.timer.buttons.reset
+ checkboxLabelStopAdd.textContent = translateElements.timer.enableStopAdd
+ checkboxLabelPauseAdd.textContent = translateElements.timer.enablePauseAdd
+
+ if (elementVariables && typeof elementVariables === 'object') {
+ checkTextTime = MsToText(elementVariables.textMilliseconds)
+ checkHexColor = elementVariables.colorText
+
+ // Format selector options
+ formatSelectorCrono.innerHTML = ''
+ message.formats[classElement.replace(/\d/g, '')].forEach((format) => {
+ const option = document.createElement('option')
+ option.value = format
+ option.textContent = format
+ formatSelectorCrono.appendChild(option)
+ })
+
+ formatSelectorCdown.innerHTML = ''
+ message.formats[classElement.replace(/\d/g, '')].forEach((format) => {
+ const option = document.createElement('option')
+ option.value = format
+ option.textContent = format
+ formatSelectorCdown.appendChild(option)
+ })
+
+ // Perform necessary actions with the variables here
+ textMsg.textContent = elementVariables.msgEnd
+ if (elementVariables.msgEnd === '') {
+ textMsg.textContent = translateElements.timer.phMsgEnd
+ textMsg.style.color = '#555'
+ } else { textMsg.style.color = '#000' }
+ timeText.value = MsToText(elementVariables.textMilliseconds)
+ // checkboxStopAdd.checked = elementVariables.enableStopAdd
+ // checkboxPauseAdd.checked = elementVariables.enablePauseAdd
+ formatSelectorCrono.value = elementVariables.formatTimeCrono
+ formatSelectorCdown.value = elementVariables.formatTimeCdown
+ fontSelect.value = elementVariables.font
+ fontSize.value = elementVariables.size
+ textFormat(elementVariables)
+ formatAlign(elementVariables.align)
+ colorPicker.value = elementVariables.colorText
+ colorHex.value = elementVariables.colorText
+ if (translateElements) {
+ updateControlButton(elementVariables.status)
+ }
+ } else {
+ console.log('The server did not return valid data.')
+ }
+ } else {
+ if (message[classElement].status !== 'started') {
+ textMsg.textContent = message[classElement].msgEnd
+ if (message[classElement].msgEnd === '') {
+ textMsg.textContent = translateElements.timer.phMsgEnd
+ textMsg.style.color = '#555'
+ } else { textMsg.style.color = '#000' }
+ timeText.value = MsToText(message[classElement].textMilliseconds)
+ checkboxStopAdd.checked = message[classElement].enableStopAdd
+ checkboxPauseAdd.checked = message[classElement].enablePauseAdd
+ formatSelectorCrono.value = message[classElement].formatTimeCrono
+ formatSelectorCdown.value = message[classElement].formatTimeCdown
+ fontSelect.value = message[classElement].font
+ fontSize.value = message[classElement].size
+ colorPicker.value = message[classElement].colorText
+ colorHex.value = message[classElement].colorText
+ }
+ formatAlign(message[classElement].align)
+ textFormat(message[classElement])
+ // Update the control button and other elements based on the received message
+ updateControlButton(message[classElement].status)
+ formatSelectorCrono.value = message[classElement].formatTimeCrono
+ formatSelectorCdown.value = message[classElement].formatTimeCdown
+ }
+ } else {
+ window.location.reload()
+ }
+ twemoji.parse(document.body)
+})
+
+socket.addEventListener('close', (event) => {
+ console.log('WebSocket Connection Closed')
+})
+
+switchTheme.addEventListener('change', () => {
+ socket.send(JSON.stringify({ action: 'themeChange', themedark: switchTheme.checked }))
+})
+
+selectorLang.addEventListener('change', () => {
+ socket.send(JSON.stringify({ action: 'langChange', lang: selectorLang.value }))
+})
+
+controlButton.addEventListener('click', () => {
+ if (controlButton.textContent === translateElements.timer.buttons.start) {
+ socket.send(JSON.stringify({ action: 'startExtensible', classElement }))
+ } else {
+ socket.send(JSON.stringify({ action: 'pauseExtensible', classElement }))
+ }
+})
+
+resetButton.addEventListener('click', () => {
+ socket.send(JSON.stringify({ action: 'resetExtensible', classElement }))
+})
+
+timeText.addEventListener('change', () => {
+ const textTime = timeText.value.trim()
+
+ // Regular expression to check the correct time format
+ const timeRegex = /^(\d+):([0-5]?\d):([0-5]?\d)$/
+
+ if (timeRegex.test(textTime)) {
+ checkTextTime = textTime
+ // If the time format is valid, send the time to the server
+ socket.send(JSON.stringify({ action: 'changeTimeExtensible', time: TextToMs(checkTextTime), classElement }))
+ timeText.value = MsToText(TextToMs(checkTextTime))
+ } else {
+ timeText.value = checkTextTime
+ }
+})
+
+// Add an event listener to the main container
+addContainer.addEventListener('click', (event) => {
+ const target = event.target
+
+ // Find the nearest button to the clicked element (including icons and text)
+ const button = target.closest('button')
+
+ if (button) {
+ // A button was clicked
+ const data = button.id.split('-')
+
+ if (button.id.startsWith('addtime-')) {
+ socket.send(JSON.stringify({ action: 'editTimeExtensible', time: `+${data[1]}`, classElement }))
+ }
+ }
+})
+
+subContainer.addEventListener('click', (event) => {
+ const target = event.target
+
+ // Find the nearest button to the clicked element (including icons and text)
+ const button = target.closest('button')
+
+ if (button) {
+ // A button was clicked
+ const data = button.id.split('-')
+
+ if (button.id.startsWith('subtime-')) {
+ socket.send(JSON.stringify({ action: 'editTimeExtensible', time: `-${data[1]}`, classElement }))
+ }
+ }
+})
+
+checkboxStopAdd.addEventListener('change', () => {
+ socket.send(JSON.stringify({ action: 'checkboxStopAdd', value: checkboxStopAdd.checked, classElement }))
+})
+
+checkboxPauseAdd.addEventListener('change', () => {
+ socket.send(JSON.stringify({ action: 'checkboxPauseAdd', value: checkboxPauseAdd.checked, classElement }))
+})
+
+textMsg.addEventListener('focus', () => {
+ if (textMsg.textContent === translateElements.timer.phMsgEnd) {
+ textMsg.textContent = ''
+ textMsg.style.color = '#000'
+ }
+})
+
+textMsg.addEventListener('blur', () => {
+ socket.send(JSON.stringify({ action: 'editMsgExtensible', msg: textMsg.textContent, classElement }))
+ if (textMsg.textContent === '') {
+ textMsg.textContent = translateElements.timer.phMsgEnd
+ textMsg.style.color = '#555'
+ } else { textMsg.style.color = '#000' }
+})
+
+formatSelectorCrono.addEventListener('change', () => {
+ socket.send(JSON.stringify({ action: 'changeFormatExtCrono', format: formatSelectorCrono.value, classElement }))
+})
+
+formatSelectorCdown.addEventListener('change', () => {
+ socket.send(JSON.stringify({ action: 'changeFormatExtCdown', format: formatSelectorCdown.value, classElement }))
+})
+
+fontSelect.addEventListener('change', () => {
+ socket.send(JSON.stringify({ action: 'changeFont', font: fontSelect.value, classElement }))
+})
+
+fontSize.addEventListener('change', () => {
+ // Get the maximum allowed value from the 'max' attribute
+ const maxSize = parseFloat(fontSize.getAttribute('max'))
+
+ // Get the manually entered value as a number
+ let newSize = parseFloat(fontSize.value)
+
+ // Check if the entered value is greater than the maximum value
+ if (newSize > maxSize) {
+ // If it's greater, set the value to the maximum allowed
+ newSize = maxSize
+ fontSize.value = maxSize
+ }
+
+ // Send the new size to the server
+ socket.send(JSON.stringify({ action: 'changeSize', size: newSize, classElement }))
+})
+
+boldButton.addEventListener('click', () => {
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'bold', classElement }))
+})
+
+italicButton.addEventListener('click', () => {
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'italic', classElement }))
+})
+
+underlineButton.addEventListener('click', () => {
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'underline', classElement }))
+})
+
+alignLeftButton.addEventListener('click', () => {
+ socket.send(JSON.stringify({ action: 'align', align: 'left', classElement }))
+})
+
+alignCenterButton.addEventListener('click', () => {
+ socket.send(JSON.stringify({ action: 'align', align: 'center', classElement }))
+})
+
+alignRightButton.addEventListener('click', () => {
+ socket.send(JSON.stringify({ action: 'align', align: 'right', classElement }))
+})
+
+colorPicker.addEventListener('change', () => {
+ checkHexColor = colorPicker.value.toUpperCase()
+ // If the hexadecimal code is valid, send the color to the server
+ socket.send(JSON.stringify({ action: 'changeColor', color: colorPicker.value.toUpperCase(), classElement }))
+ colorHex.value = checkHexColor
+})
+
+colorHex.addEventListener('change', () => {
+ const hexColor = colorHex.value.trim()
+
+ // Regular expression to check the correct hexadecimal color code format
+ const hexRegex = /^#([0-9A-Fa-f]{6})$/
+
+ if (hexRegex.test(hexColor)) {
+ checkHexColor = hexColor.toUpperCase()
+ // If the hexadecimal code is valid, send the color to the server
+ socket.send(JSON.stringify({ action: 'changeColorExtensible', color: checkHexColor, classElement }))
+ colorPicker.value = checkHexColor
+ colorHex.value = checkHexColor
+ } else {
+ colorHex.value = checkHexColor
+ }
+})
+
+// Function to update the font selector
+function updateFontSelector (fonts) {
+ // Clear the font selector
+ fontSelect.innerHTML = ''
+
+ // Add font options to the selector without quotes
+ fonts.forEach((font) => {
+ // Remove double quotes at the beginning and end of the font name
+ font = font.replace(/^"(.*)"$/, '$1')
+
+ const option = document.createElement('option')
+ option.value = font
+ option.textContent = font
+ fontSelect.appendChild(option)
+ })
+}
+
+function updateControlButton (status) {
+ const maxWidth = getMaxButtonWidth()
+ controlButton.style.width = maxWidth
+
+ if (status === 'started') {
+ controlButton.textContent = translateElements.timer.buttons.pause
+ } else {
+ controlButton.textContent = translateElements.timer.buttons.start
+ }
+}
+
+function getMaxButtonWidth () {
+ const widths = []
+
+ Object.keys(translateElements.timer.buttons).forEach((value) => {
+ controlButton.textContent = translateElements.timer.buttons[value]
+ widths.push(parseFloat(window.getComputedStyle(controlButton).getPropertyValue('width')))
+ })
+ // Get the maximum of the two widths
+ return Math.max(...widths) + 'px'
+}
+
+function getMaxSizeWidth () {
+ const maxvalue = fontSize.getAttribute('max') // Get the maximum value from the 'max' attribute
+
+ // Get the maximum of the two widths
+ return maxvalue.length * 20 + 'px'
+}
+
+function formatAlign (align) {
+ // List of buttons and their corresponding alignments
+ const buttons = [
+ { button: alignLeftButton, align: 'left' },
+ { button: alignCenterButton, align: 'center' },
+ { button: alignRightButton, align: 'right' }
+ ]
+
+ // Reset the format of all buttons
+ buttons.forEach((btn) => {
+ btn.button.style.backgroundColor = '#ccc'
+ btn.button.style.color = '#333'
+ btn.button.style.border = '2px solid #ccc'
+ })
+
+ // Find and highlight the selected button
+ const selectedButton = buttons.find((btn) => btn.align === align)
+ if (selectedButton) {
+ selectedButton.button.style.backgroundColor = '#777'
+ selectedButton.button.style.color = 'white'
+ selectedButton.button.style.border = '2px solid #777'
+ }
+}
+
+function textFormat (message) {
+ // List of buttons and their corresponding formats
+ const buttons = [
+ { button: boldButton, format: message.bold },
+ { button: italicButton, format: message.italic },
+ { button: underlineButton, format: message.underline }
+ ]
+
+ // Set the format for all buttons
+ buttons.forEach((btn) => {
+ if (btn.format) {
+ btn.button.style.backgroundColor = '#777'
+ btn.button.style.color = 'white'
+ btn.button.style.border = '2px solid #777'
+ } else {
+ btn.button.style.backgroundColor = '#ccc'
+ btn.button.style.color = '#333'
+ btn.button.style.border = '2px solid #ccc'
+ }
+ })
+}
+
+function TextToMs (text) {
+ const timeComponents = text.split(':')
+
+ const hours = parseInt(timeComponents[0], 10)
+ const minutes = parseInt(timeComponents[1], 10)
+ const seconds = parseInt(timeComponents[2], 10)
+
+ return (hours * 3600 + minutes * 60 + seconds) * 1000
+}
+
+function MsToText (ms) {
+ const total = ms / 1000
+ const hours = Math.floor(total / 3600)
+ const minutes = Math.floor((total % 3600) / 60)
+ const seconds = total % 60
+
+ const formattedHours = String(hours).padStart(2, '0')
+ const formattedMinutes = String(minutes).padStart(2, '0')
+ const formattedSeconds = String(seconds).padStart(2, '0')
+
+ return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`
+}
diff --git a/core/template/extensible/control/index.html b/core/template/extensible/control/index.html
new file mode 100644
index 0000000..e244809
--- /dev/null
+++ b/core/template/extensible/control/index.html
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/template/extensible/control/styles.css b/core/template/extensible/control/styles.css
new file mode 100644
index 0000000..ded1b60
--- /dev/null
+++ b/core/template/extensible/control/styles.css
@@ -0,0 +1,236 @@
+/* Estilos para crono01/control */
+
+body {
+ margin: 0;
+ padding: 0;
+ font-family: Arial, sans-serif;
+ justify-content: center;
+ align-items: center;
+}
+
+.light-theme {
+ background-color: #fff;
+}
+
+/* Estilos para el tema oscuro */
+.dark-theme {
+ background-color: #555;
+}
+
+#icon-fa-clock,
+#icon-fa-stopwatch {
+ margin-right: 10px;
+ color: #000;
+ font-size: 30px;
+}
+
+.container {
+ text-align: center;
+ margin-top: 50px;
+}
+
+.start-button {
+ background-color: #4caf50;
+ color: white;
+ font-size: 24px;
+ padding: 10px 20px;
+ border: 2px solid #4caf50; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ cursor: pointer;
+ margin-right: 10px;
+ margin-left: 10px;
+}
+
+.start-button:hover {
+ background-color: #388e3c; /* Fondo gris más oscuro al pasar el ratón */
+ border: 2px solid #388e3c;
+}
+
+.reset-button {
+ background-color: #f44336;
+ color: white;
+ font-size: 24px;
+ padding: 10px 20px;
+ border: 2px solid #f44336; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ cursor: pointer;
+ margin-right: 10px;
+ margin-left: 10px;
+}
+
+.reset-button:hover {
+ background-color: #d9362e; /* Fondo gris más oscuro al pasar el ratón */
+ border: 2px solid #d9362e;
+}
+
+.space-between {
+ margin-top: 5px; /* La mitad de 20px (espacio entre divs) */
+}
+
+#timeText {
+ background-color: #cccccc88;
+ font-size: 24px; /* Tamaño de fuente */
+ padding: 10px 20px; /* Espaciado interno */
+ text-align: right;
+ border: 2px solid #cccccc88; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ width: 150px;
+}
+
+.addtime-button {
+ background-color: #4caf50aa;
+ color: white;
+ font-size: 18px;
+ padding: 5px 10px;
+ border: 2px solid #4caf50aa; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ cursor: pointer;
+ margin-right: 2.5px;
+ margin-left: 2.5px;
+ width: 70px;
+}
+
+.addtime-button:hover {
+ background-color: #388e3caa; /* Fondo gris más oscuro al pasar el ratón */
+ border: 2px solid #388e3caa;
+}
+
+.subtime-button {
+ background-color: #f44336aa;
+ color: white;
+ font-size: 18px;
+ padding: 5px 10px;
+ border: 2px solid #f44336aa; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ cursor: pointer;
+ margin-right: 2.5px;
+ margin-left: 2.5px;
+ width: 70px;
+}
+
+.subtime-button:hover {
+ background-color: #d9362eaa; /* Fondo gris más oscuro al pasar el ratón */
+ border: 2px solid #d9362eaa;
+}
+
+.checkboxBox {
+ background-color: #cccccc88;
+ border: 2px solid #cccccc88; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ cursor: pointer;
+ width: 18px; /* Ancho personalizado */
+ height: 18px; /* Alto personalizado */
+}
+
+.checkboxText {
+ font-size: 18px; /* Tamaño de fuente */
+}
+
+.text-input-container {
+ display: flex;
+ justify-content: center; /* Centra horizontalmente */
+ align-items: flex-start;
+}
+
+.paragraph {
+ background-color: #cccccc88;
+ font-size: 24px; /* Tamaño de fuente */
+ padding: 10px 20px; /* Espaciado interno */
+ border: 2px solid #cccccc88; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ margin-right: 10px;
+ margin-left: 10px;
+ width: 500px;
+ height: auto;
+ min-height: 28px; /* Altura mínima para que sea visible */
+}
+
+/* Estilos para el selector */
+#formatSelectorCrono,
+#formatSelectorCdown,
+#fontSelect {
+ background-color: #cccccc88;
+ font-size: 24px; /* Tamaño de fuente */
+ padding: 10px 20px; /* Espaciado interno */
+ border: 2px solid #cccccc88; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ margin-right: 10px;
+ margin-left: 10px;
+ cursor: pointer;
+ width: auto;
+}
+
+#fontSize {
+ background-color: #cccccc88;
+ font-size: 24px; /* Tamaño de fuente */
+ padding: 10px 20px; /* Espaciado interno */
+ border: 2px solid #cccccc88; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ margin-right: 10px;
+ margin-left: 10px;
+ width: auto;
+}
+
+/* Estilos para los botones de alineación */
+#boldButton,
+#italicButton,
+#underlineButton,
+#alignLeft,
+#alignCenter,
+#alignRight {
+ background-color: #ccc; /* Fondo gris claro */
+ color: #333; /* Texto gris oscuro */
+ font-size: 24px; /* Tamaño de fuente */
+ padding: 10px 20px; /* Espaciado interno */
+ border: 2px solid #ccc; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ cursor: pointer;
+ width: 65px;
+}
+
+#boldButton:hover,
+#italicButton:hover,
+#underlineButton:hover,
+#alignLeft:hover,
+#alignCenter:hover,
+#alignRight:hover {
+ background-color: #999; /* Fondo gris más oscuro al pasar el ratón */
+ border: 2px solid #999;
+}
+
+#colorPicker {
+ background-color: #cccccc88;
+ border: 2px solid #cccccc88;
+ border-radius: 5px;
+ cursor: pointer;
+ height: 52px;
+ vertical-align: bottom;
+}
+
+#colorPicker:hover {
+ border: 2px solid #999; /* Cambia el borde al pasar el ratón */
+ cursor: pointer;
+}
+
+#colorHex {
+ background-color: #cccccc88;
+ font-size: 24px; /* Tamaño de fuente */
+ padding: 10px 20px; /* Espaciado interno */
+ border: 2px solid #cccccc88; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ width: 120px;
+}
+
+#textFormatBlock,
+#alingblock,
+#colorblock {
+ margin-right: 10px;
+ margin-left: 10px;
+}
+
+img.emoji {
+ height: 1em;
+ width: 1em;
+ margin: 0 0.05em 0 0.1em;
+ vertical-align: -0.1em;
+}
diff --git a/core/template/extensible/control/topbar.css b/core/template/extensible/control/topbar.css
new file mode 100644
index 0000000..ffc660c
--- /dev/null
+++ b/core/template/extensible/control/topbar.css
@@ -0,0 +1,94 @@
+.top-bar {
+ background-color: #e5e5e5;
+ display: flex;
+ justify-content: right;
+ align-items: right;
+ padding: 10px 20px;
+}
+
+.language-span {
+ font-size: 30px; /* Tamaño de fuente */
+ margin-right: 10px;
+ margin-left: 10px;
+}
+
+.language-selector {
+ font-family: Arial, sans-serif;
+ font-size: 17px; /* Tamaño de fuente */
+ border: 2px solid #ccc; /* Borde */
+ border-radius: 5px; /* Borde redondeado */
+ vertical-align: top;
+ margin-top: 3.5px;
+ width: auto;
+}
+
+.theme-span {
+ font-size: 22px; /* Tamaño de fuente */
+ margin-right: 10px;
+ margin-left: 10px;
+ margin-top: 3.5px;
+}
+
+/* The switch - the box around the slider */
+.switch {
+ position: relative;
+ display: inline-block;
+ width: 40px;
+ height: 25px;
+}
+
+/* Hide default HTML checkbox */
+.switch input {
+ opacity: 0;
+ width: 0;
+ height: 0;
+}
+
+/* The slider */
+.slider {
+ position: absolute;
+ cursor: pointer;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: #ccc;
+ -webkit-transition: 0.4s;
+ transition: 0.4s;
+}
+
+.slider:before {
+ position: absolute;
+ content: "";
+ height: 20px;
+ width: 20px;
+ top: 2px;
+ left: 2px;
+ bottom: 4px;
+ background-color: white;
+ -webkit-transition: 0.4s;
+ transition: 0.4s;
+}
+
+input:checked + .slider {
+ background-color: #ccc;
+}
+
+input:focus + .slider {
+ box-shadow: 0 0 1px #ccc;
+}
+
+input:checked + .slider:before {
+ -webkit-transform: translateX(16px);
+ -ms-transform: translateX(16px);
+ transform: translateX(16px);
+}
+
+/* Rounded sliders */
+.slider.round {
+ border-radius: 20px;
+}
+
+.slider.round:before {
+ border-radius: 50%;
+}
diff --git a/core/template/extensible/viewCdown/client.js b/core/template/extensible/viewCdown/client.js
new file mode 100644
index 0000000..c315ad0
--- /dev/null
+++ b/core/template/extensible/viewCdown/client.js
@@ -0,0 +1,165 @@
+// Elements
+const timeElement = document.getElementById('time')
+const containers = document.querySelectorAll('.container')
+const titlePage = document.getElementById('titlePage')
+// const test = document.getElementById('test'); // Commented out unused variable
+const socket = new WebSocket('ws://localhost:3000')
+
+// Extract class element from URL
+const classElement = window.location.href.split('/')[3]
+titlePage.textContent = classElement + ' - View - Countdown'
+
+let intervalId = null
+let formatTimeVar
+
+socket.addEventListener('open', (event) => {
+ console.log('WebSocket Connection Opened')
+
+ // Request the WebSocket server to send variable data
+ socket.send(JSON.stringify({ action: 'getVariables', classElement }))
+})
+
+socket.addEventListener('message', (event) => {
+ const message = JSON.parse(event.data)
+
+ if (message.action === 'reload') {
+ window.location.reload()
+ }
+
+ if (message.action === 'sendVariables' && message.classElement === classElement && message.config) {
+ document.documentElement.lang = Object.keys(message.formats.langs).includes(message.config.lang)
+ ? message.config.lang
+ : 'en'
+ }
+
+ if (message[classElement].milliseconds !== undefined) {
+ if (formatTimeVar !== message[classElement].formatTimeCdown && intervalId) {
+ clearInterval(intervalId)
+ intervalId = null
+ }
+
+ formatTimeVar = message[classElement].formatTimeCdown
+ if (message[classElement].status === 'ended') {
+ if (message[classElement].milliseconds !== 0) {
+ updateTimeDisplay(formatTimeVar, message[classElement].milliseconds)
+ } else if (message[classElement].msgEnd !== '') {
+ timeElement.textContent = message[classElement].msgEnd
+ twemoji.parse(document.body)
+ } else {
+ updateTimeDisplay(formatTimeVar, 0)
+ }
+ } else {
+ updateTimeDisplay(formatTimeVar, message[classElement].milliseconds)
+ }
+
+ // Update the timer based on the received message
+ timeElement.style.fontFamily = `"${message[classElement].font}"`
+ timeElement.style.fontSize = message[classElement].size + 'px'
+ timeElement.style.color = message[classElement].colorText
+
+ if (message[classElement].bold) {
+ timeElement.style.fontWeight = 'bold'
+ } else {
+ timeElement.style.fontWeight = 'normal'
+ }
+ if (message[classElement].italic) {
+ timeElement.style.fontStyle = 'italic'
+ } else {
+ timeElement.style.fontStyle = 'normal'
+ }
+ if (message[classElement].underline) {
+ timeElement.style.textDecoration = 'underline'
+ } else {
+ timeElement.style.textDecoration = 'none'
+ }
+ containers.forEach((container) => {
+ container.style.textAlign = message[classElement].align
+ })
+
+ // If the timer is in "started" state, start the interval
+ if (message[classElement].status === 'started') {
+ if (!intervalId) {
+ intervalId = setInterval(() => {
+ if (message[classElement].startTime + message[classElement].milliseconds > Date.now()) {
+ updateTimeDisplay(formatTimeVar, message[classElement].startTime + message[classElement].milliseconds - Date.now())
+ } else {
+ socket.send(JSON.stringify({ action: 'stopExtensible', classElement }))
+ }
+ }, 1) // Update every 1 millisecond
+ }
+ } else {
+ // If the timer is not in "started" state, stop the interval
+ clearInterval(intervalId)
+ intervalId = null
+ }
+ }
+})
+
+socket.addEventListener('close', (event) => {
+ console.log('WebSocket Connection Closed')
+})
+
+// Update the time display based on format and milliseconds
+function updateTimeDisplay (format, milliseconds) {
+ if (isNaN(milliseconds)) {
+ milliseconds = 0
+ }
+
+ const totalMilliseconds = Math.floor(milliseconds)
+ const totalSeconds = Math.floor(totalMilliseconds / 1000)
+ const hours = Math.floor(totalSeconds / 3600)
+ const minutes = Math.floor((totalSeconds % 3600) / 60)
+ const remainingSeconds = totalSeconds % 60
+ const remainingMilliseconds = totalMilliseconds % 1000
+
+ const formattedTime = formatTime(format, hours, minutes, remainingSeconds, remainingMilliseconds)
+ timeElement.textContent = formattedTime
+}
+
+// Format time based on the provided format
+function formatTime (format, hours, minutes, seconds, milliseconds) {
+ switch (format) {
+ case 'HH:mm:ss.000':
+ return `${formatTimeComponent(hours)}:${formatTimeComponent(minutes)}:${formatTimeComponent(seconds)}.${formatMilliseconds(milliseconds)}`
+ case 'HH:mm:ss':
+ return `${formatTimeComponent(hours)}:${formatTimeComponent(minutes)}:${formatTimeComponent(seconds)}`
+ case '(HH:)(mm:)ss.000':
+ return `${hours !== 0 ? formatTimeComponent(hours) + ':' : ''}${(hours !== 0 || minutes !== 0) ? formatTimeComponent(minutes) + ':' : ''}${formatTimeComponent(seconds)}.${formatMilliseconds(milliseconds)}`
+ case '(HH:)(mm:)ss':
+ return `${hours !== 0 ? formatTimeComponent(hours) + ':' : ''}${(hours !== 0 || minutes !== 0) ? formatTimeComponent(minutes) + ':' : ''}${formatTimeComponent(seconds)}`
+ case '(HH:)mm:ss.000':
+ return `${hours !== 0 ? formatTimeComponent(hours) + ':' : ''}${formatTimeComponent(minutes)}:${formatTimeComponent(seconds)}.${formatMilliseconds(milliseconds)}`
+ case '(HH:)mm:ss':
+ return `${hours !== 0 ? formatTimeComponent(hours) + ':' : ''}${formatTimeComponent(minutes)}:${formatTimeComponent(seconds)}`
+ case 'MM:ss.000':
+ return `${formatTimeComponent(minutes + hours * 60)}:${formatTimeComponent(seconds)}.${formatMilliseconds(milliseconds)}`
+ case 'MM:ss':
+ return `${formatTimeComponent(minutes + hours * 60)}:${formatTimeComponent(seconds)}`
+ case 'SS.000':
+ return `${formatTimeComponent(seconds + minutes * 60 + hours * 3600)}.${formatMilliseconds(milliseconds)}`
+ case 'SS':
+ return `${formatTimeComponent(seconds + minutes * 60 + hours * 3600)}`
+ default:
+ return '' // Return an empty string if the format does not match
+ }
+}
+
+// Format time component with leading zero if less than 10
+function formatTimeComponent (component) {
+ return component < 10 ? `0${component}` : component
+}
+
+// Format milliseconds to 3 digits
+function formatMilliseconds (milliseconds) {
+ let result
+
+ if (milliseconds < 10) {
+ result = `00${milliseconds}`
+ } else if (milliseconds < 100) {
+ result = `0${milliseconds}`
+ } else {
+ result = milliseconds
+ }
+
+ return result
+}
diff --git a/core/template/extensible/viewCdown/index.html b/core/template/extensible/viewCdown/index.html
new file mode 100644
index 0000000..240ceab
--- /dev/null
+++ b/core/template/extensible/viewCdown/index.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/template/extensible/viewCdown/styles.css b/core/template/extensible/viewCdown/styles.css
new file mode 100644
index 0000000..1d44a0d
--- /dev/null
+++ b/core/template/extensible/viewCdown/styles.css
@@ -0,0 +1,10 @@
+/* Estilos para crono/view */
+
+img.emoji {
+ height: 1em;
+ width: 1em;
+ margin: 0 0.05em 0 0.1em;
+ vertical-align: -0.1em;
+}
+
+/* Puedes agregar más estilos según tus necesidades */
diff --git a/core/template/extensible/viewCrono/client.js b/core/template/extensible/viewCrono/client.js
new file mode 100644
index 0000000..240d2e9
--- /dev/null
+++ b/core/template/extensible/viewCrono/client.js
@@ -0,0 +1,147 @@
+const timeElement = document.getElementById('time')
+const containers = document.querySelectorAll('.container')
+const titlePage = document.getElementById('titlePage')
+// const test = document.getElementById('test')
+const socket = new WebSocket('ws://localhost:3000')
+
+const classElement = window.location.href.split('/')[3]
+titlePage.textContent = classElement + ' - View - Crono'
+
+let intervalId = null
+let formatTimeVar
+
+socket.addEventListener('open', (event) => {
+ console.log('WebSocket Connection Opened')
+
+ // Request the WebSocket server to send variable data
+ socket.send(JSON.stringify({ action: 'getVariables', classElement }))
+})
+
+socket.addEventListener('message', (event) => {
+ const message = JSON.parse(event.data)
+
+ if (message.action === 'reload') {
+ window.location.reload()
+ }
+
+ if (message.action === 'sendVariables' && message.classElement === classElement && message.config) {
+ document.documentElement.lang = Object.keys(message.formats.langs).includes(message.config.lang)
+ ? message.config.lang
+ : 'en'
+ }
+
+ if (message[classElement].millisecondsTotal !== undefined) {
+ if (formatTimeVar !== message[classElement].formatTimeCrono && intervalId) {
+ clearInterval(intervalId)
+ intervalId = null
+ }
+
+ formatTimeVar = message[classElement].formatTimeCrono
+ updateTimeDisplay(formatTimeVar, message[classElement].millisecondsTotal)
+
+ // Update the timer based on the received message
+ timeElement.style.fontFamily = `"${message[classElement].font}"`
+ timeElement.style.fontSize = message[classElement].size + 'px'
+ timeElement.style.color = message[classElement].colorText
+
+ if (message[classElement].bold) {
+ timeElement.style.fontWeight = 'bold'
+ } else {
+ timeElement.style.fontWeight = 'normal'
+ }
+ if (message[classElement].italic) {
+ timeElement.style.fontStyle = 'italic'
+ } else {
+ timeElement.style.fontStyle = 'normal'
+ }
+ if (message[classElement].underline) {
+ timeElement.style.textDecoration = 'underline'
+ } else {
+ timeElement.style.textDecoration = 'none'
+ }
+ containers.forEach((container) => {
+ container.style.textAlign = message[classElement].align
+ })
+
+ // If the timer is in "started" state, start the interval
+ if (message[classElement].status === 'started') {
+ if (!intervalId) {
+ intervalId = setInterval(() => {
+ updateTimeDisplay(formatTimeVar, Date.now() - message[classElement].startTime + message[classElement].millisecondsTotal)
+ }, 1) // Update every 1 millisecond
+ }
+ } else {
+ // If the timer is not in "started" state, stop the interval
+ clearInterval(intervalId)
+ intervalId = null
+ if (message[classElement].status === 'ended') {
+ updateTimeDisplay(formatTimeVar, message[classElement].millisecondsTotal)
+ }
+ }
+ }
+})
+
+socket.addEventListener('close', (event) => {
+ console.log('WebSocket Connection Closed')
+})
+
+function updateTimeDisplay (format, millisecondsTotal) {
+ if (isNaN(millisecondsTotal)) {
+ millisecondsTotal = 0
+ }
+
+ const totalmillisecondsTotal = Math.floor(millisecondsTotal)
+ const totalSeconds = Math.floor(totalmillisecondsTotal / 1000)
+ const hours = Math.floor(totalSeconds / 3600)
+ const minutes = Math.floor((totalSeconds % 3600) / 60)
+ const remainingSeconds = totalSeconds % 60
+ const remainingmillisecondsTotal = totalmillisecondsTotal % 1000
+
+ const formattedTime = formatTime(format, hours, minutes, remainingSeconds, remainingmillisecondsTotal)
+ timeElement.textContent = formattedTime
+}
+
+function formatTime (format, hours, minutes, seconds, millisecondsTotal) {
+ switch (format) {
+ case 'HH:mm:ss.000':
+ return `${formatTimeComponent(hours)}:${formatTimeComponent(minutes)}:${formatTimeComponent(seconds)}.${formatmillisecondsTotal(millisecondsTotal)}`
+ case 'HH:mm:ss':
+ return `${formatTimeComponent(hours)}:${formatTimeComponent(minutes)}:${formatTimeComponent(seconds)}`
+ case '(HH:)(mm:)ss.000':
+ return `${hours !== 0 ? formatTimeComponent(hours) + ':' : ''}${(hours !== 0 || minutes !== 0) ? formatTimeComponent(minutes) + ':' : ''}${formatTimeComponent(seconds)}.${formatmillisecondsTotal(millisecondsTotal)}`
+ case '(HH:)(mm:)ss':
+ return `${hours !== 0 ? formatTimeComponent(hours) + ':' : ''}${(hours !== 0 || minutes !== 0) ? formatTimeComponent(minutes) + ':' : ''}${formatTimeComponent(seconds)}`
+ case '(HH:)mm:ss.000':
+ return `${hours !== 0 ? formatTimeComponent(hours) + ':' : ''}${formatTimeComponent(minutes)}:${formatTimeComponent(seconds)}.${formatmillisecondsTotal(millisecondsTotal)}`
+ case '(HH:)mm:ss':
+ return `${hours !== 0 ? formatTimeComponent(hours) + ':' : ''}${formatTimeComponent(minutes)}:${formatTimeComponent(seconds)}`
+ case 'MM:ss.000':
+ return `${formatTimeComponent(minutes + hours * 60)}:${formatTimeComponent(seconds)}.${formatmillisecondsTotal(millisecondsTotal)}`
+ case 'MM:ss':
+ return `${formatTimeComponent(minutes + hours * 60)}:${formatTimeComponent(seconds)}`
+ case 'SS.000':
+ return `${formatTimeComponent(seconds + minutes * 60 + hours * 3600)}.${formatmillisecondsTotal(millisecondsTotal)}`
+ case 'SS':
+ return `${formatTimeComponent(seconds + minutes * 60 + hours * 3600)}`
+ default:
+ return '' // Return an empty string if the format doesn't match
+ }
+}
+
+function formatTimeComponent (component) {
+ return component < 10 ? `0${component}` : component
+}
+
+function formatmillisecondsTotal (millisecondsTotal) {
+ let result
+
+ if (millisecondsTotal < 10) {
+ result = `00${millisecondsTotal}`
+ } else if (millisecondsTotal < 100) {
+ result = `0${millisecondsTotal}`
+ } else {
+ result = millisecondsTotal
+ }
+
+ return result
+}
diff --git a/core/template/extensible/viewCrono/index.html b/core/template/extensible/viewCrono/index.html
new file mode 100644
index 0000000..6009ce0
--- /dev/null
+++ b/core/template/extensible/viewCrono/index.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/template/extensible/viewCrono/styles.css b/core/template/extensible/viewCrono/styles.css
new file mode 100644
index 0000000..05dd7b4
--- /dev/null
+++ b/core/template/extensible/viewCrono/styles.css
@@ -0,0 +1,3 @@
+/* Estilos para crono/view */
+
+/* Puedes agregar más estilos según tus necesidades */
diff --git a/core/template/time/control/control.js b/core/template/time/control/control.js
index 4c8f059..31b4d47 100644
--- a/core/template/time/control/control.js
+++ b/core/template/time/control/control.js
@@ -141,11 +141,11 @@ timezoneSelector.addEventListener('change', () => {
})
formatSelector.addEventListener('change', () => {
- socket.send(JSON.stringify({ action: 'changeFormatTime', format: formatSelector.value, classElement }))
+ socket.send(JSON.stringify({ action: 'changeFormat', format: formatSelector.value, classElement }))
})
fontSelect.addEventListener('change', () => {
- socket.send(JSON.stringify({ action: 'changeFontTime', font: fontSelect.value, classElement }))
+ socket.send(JSON.stringify({ action: 'changeFont', font: fontSelect.value, classElement }))
})
fontSize.addEventListener('change', () => {
@@ -163,37 +163,37 @@ fontSize.addEventListener('change', () => {
}
// Send the new size to the server
- socket.send(JSON.stringify({ action: 'changeSizeTime', size: newSize, classElement }))
+ socket.send(JSON.stringify({ action: 'changeSize', size: newSize, classElement }))
})
boldButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatTime', format: 'bold', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'bold', classElement }))
})
italicButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatTime', format: 'italic', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'italic', classElement }))
})
underlineButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'textFormatTime', format: 'underline', classElement }))
+ socket.send(JSON.stringify({ action: 'textFormat', format: 'underline', classElement }))
})
alignLeftButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignTime', align: 'left', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'left', classElement }))
})
alignCenterButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignTime', align: 'center', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'center', classElement }))
})
alignRightButton.addEventListener('click', () => {
- socket.send(JSON.stringify({ action: 'alignTime', align: 'right', classElement }))
+ socket.send(JSON.stringify({ action: 'align', align: 'right', classElement }))
})
colorPicker.addEventListener('change', () => {
checkHexColor = colorPicker.value.toUpperCase()
// If the hexadecimal code is valid, send the color to the server
- socket.send(JSON.stringify({ action: 'changeColorTime', color: colorPicker.value.toUpperCase(), classElement }))
+ socket.send(JSON.stringify({ action: 'changeColor', color: colorPicker.value.toUpperCase(), classElement }))
colorHex.value = checkHexColor
})
@@ -206,7 +206,7 @@ colorHex.addEventListener('change', () => {
if (hexRegex.test(hexColor)) {
checkHexColor = hexColor.toUpperCase()
// If the hexadecimal code is valid, send the color to the server
- socket.send(JSON.stringify({ action: 'changeColorTime', color: checkHexColor, classElement }))
+ socket.send(JSON.stringify({ action: 'changeColor', color: checkHexColor, classElement }))
colorPicker.value = checkHexColor
colorHex.value = checkHexColor
} else {
diff --git a/core/topbar.css b/core/topbar.css
index e938070..1dc1897 100644
--- a/core/topbar.css
+++ b/core/topbar.css
@@ -37,6 +37,8 @@
margin-top: 3.5px;
cursor: pointer;
flex-grow: 1;
+ margin-right: 2.5px;
+ margin-left: 2.5px;
}
.link-button:hover {
diff --git a/core/translates/en.yaml b/core/translates/en.yaml
index 879cb42..fdfc1d9 100644
--- a/core/translates/en.yaml
+++ b/core/translates/en.yaml
@@ -1,15 +1,17 @@
home:
close: Close the window and stop the code
wiki: Documentation
- cronoTitle: CLOCKS
- cdownTitle: TIMERS
+ cronoTitle: CHRONOMETERS
+ cdownTitle: COUNTDOWNS
cdowntimeTitle: TIME UNTIL...
- twitchextTitle: EXTENSIBLE TWITCH
+ extensibleTitle: STREAM EXTENSIBLE
timeTitle: CURRENT TIME
- notycopycrono: URL copied to clipboard
+ notycopy: URL copied to clipboard
timer:
buttons:
start: Start
pause: Pause
reset: Reset
- ph_msgend: Message to display when time expires
\ No newline at end of file
+ phMsgEnd: Message to display when time expires
+ enablePauseAdd: Enabled permission to add time when time is paused
+ enableStopAdd: Enabled permission to add time when time has not yet started
\ No newline at end of file
diff --git a/core/translates/es.yaml b/core/translates/es.yaml
index a759cd5..b6c2536 100644
--- a/core/translates/es.yaml
+++ b/core/translates/es.yaml
@@ -4,12 +4,14 @@ home:
cronoTitle: CRONÓMETROS
cdownTitle: TEMPORIZADORES
cdowntimeTitle: TIEMPO HASTA...
- twitchextTitle: EXTENSIBLE TWITCH
+ extensibleTitle: STREAM EXTENSIBLE
timeTitle: HORA ACTUAL
- notycopycrono: URL copiada al portapapeles
+ notycopy: URL copiada al portapapeles
timer:
buttons:
start: Iniciar
pause: Pausar
reset: Reiniciar
- ph_msgend: Mensaje a mostrar cuando finalice el tiempo
\ No newline at end of file
+ phMsgEnd: Mensaje a mostrar cuando finalice el tiempo
+ enablePauseAdd: Habilitado el permiso para añadir tiempo cuando el tiempo está pausado
+ enableStopAdd: Habilitado el permiso para añadir tiempo cuando el tiempo aún no se ha iniciado
diff --git a/functions.js b/functions.js
index 2281d0b..ca9a408 100644
--- a/functions.js
+++ b/functions.js
@@ -223,7 +223,7 @@ exports.createDataYAML = (GlobalVariables, classType) => {
GlobalVariables[newKey].status = 'stopped'
GlobalVariables[newKey].startTime = 0
GlobalVariables[newKey].milliseconds = 60000
- GlobalVariables[newKey].textmilliseconds = 60000
+ GlobalVariables[newKey].textMilliseconds = 60000
GlobalVariables[newKey].formatTime = 'MM:ss'
GlobalVariables[newKey].font = 'Arial'
GlobalVariables[newKey].size = 50
@@ -245,6 +245,24 @@ exports.createDataYAML = (GlobalVariables, classType) => {
GlobalVariables[newKey].align = 'center'
GlobalVariables[newKey].colorText = '#000000'
GlobalVariables[newKey].msgEnd = ''
+ } else if (classType === 'extensible') {
+ GlobalVariables[newKey].status = 'stopped'
+ GlobalVariables[newKey].startTime = 0
+ GlobalVariables[newKey].millisecondsTotal = 0
+ GlobalVariables[newKey].milliseconds = 60000
+ GlobalVariables[newKey].textMilliseconds = 60000
+ GlobalVariables[newKey].formatTimeCrono = 'HH:mm:ss'
+ GlobalVariables[newKey].formatTimeCdown = 'HH:mm:ss'
+ GlobalVariables[newKey].font = 'Arial'
+ GlobalVariables[newKey].size = 50
+ GlobalVariables[newKey].bold = false
+ GlobalVariables[newKey].italic = false
+ GlobalVariables[newKey].underline = false
+ GlobalVariables[newKey].align = 'center'
+ GlobalVariables[newKey].colorText = '#000000'
+ GlobalVariables[newKey].msgEnd = ''
+ GlobalVariables[newKey].enablePauseAdd = false
+ GlobalVariables[newKey].enableStopAdd = false
} else if (classType === 'time') {
GlobalVariables[newKey].timezone = Intl.DateTimeFormat().resolvedOptions().timeZone
GlobalVariables[newKey].formatTime = 'hh:mm:ss'
@@ -329,6 +347,24 @@ exports.pauseCdown = (wss, GlobalVariables, classElement) => {
}
}
+// Pause the extensible
+exports.pauseExtensible = (wss, GlobalVariables, classElement) => {
+ if (GlobalVariables[classElement].status === 'started') {
+ GlobalVariables[classElement].status = 'paused'
+ GlobalVariables[classElement].millisecondsTotal += Date.now() - GlobalVariables[classElement].startTime
+ GlobalVariables[classElement].milliseconds -= Date.now() - GlobalVariables[classElement].startTime
+
+ // Update all WebSocket clients with countdown status
+ wss.clients.forEach((client) => {
+ if (client.readyState === WebSocket.OPEN) {
+ client.send(JSON.stringify(GlobalVariables))
+ }
+ })
+
+ this.saveVariablesToYAML(GlobalVariables)
+ }
+}
+
// Reset the stopwatch
exports.resetCrono = (wss, GlobalVariables, classElement) => {
GlobalVariables[classElement].status = 'stopped'
@@ -348,7 +384,24 @@ exports.resetCrono = (wss, GlobalVariables, classElement) => {
// Reset the countdown
exports.resetCdown = (wss, GlobalVariables, classElement) => {
GlobalVariables[classElement].status = 'stopped'
- GlobalVariables[classElement].milliseconds = GlobalVariables[classElement].textmilliseconds
+ GlobalVariables[classElement].milliseconds = GlobalVariables[classElement].textMilliseconds
+ GlobalVariables[classElement].startTime = 0
+
+ // Update all WebSocket clients with countdown status
+ wss.clients.forEach((client) => {
+ if (client.readyState === WebSocket.OPEN) {
+ client.send(JSON.stringify(GlobalVariables))
+ }
+ })
+
+ this.saveVariablesToYAML(GlobalVariables)
+}
+
+// Reset the extensible
+exports.resetExtensible = (wss, GlobalVariables, classElement) => {
+ GlobalVariables[classElement].status = 'stopped'
+ GlobalVariables[classElement].millisecondsTotal = 0
+ GlobalVariables[classElement].milliseconds = GlobalVariables[classElement].textMilliseconds
GlobalVariables[classElement].startTime = 0
// Update all WebSocket clients with countdown status
@@ -363,8 +416,25 @@ exports.resetCdown = (wss, GlobalVariables, classElement) => {
// Stop the countdown
exports.stopCdown = (wss, GlobalVariables, classElement) => {
- GlobalVariables[classElement].status = 'stopped'
+ GlobalVariables[classElement].status = 'ended'
+ GlobalVariables[classElement].milliseconds = 0
+
+ // Update all WebSocket clients with countdown status
+ wss.clients.forEach((client) => {
+ if (client.readyState === WebSocket.OPEN) {
+ client.send(JSON.stringify(GlobalVariables))
+ }
+ })
+
+ this.saveVariablesToYAML(GlobalVariables)
+}
+
+// Stop the countdown
+exports.stopExtensible = (wss, GlobalVariables, classElement) => {
+ GlobalVariables[classElement].status = 'ended'
GlobalVariables[classElement].milliseconds = 0
+ GlobalVariables[classElement].millisecondsTotal += Date.now() - GlobalVariables[classElement].startTime
+ GlobalVariables[classElement].millisecondsTotal = Math.round(GlobalVariables[classElement].millisecondsTotal / 1000) * 1000
// Update all WebSocket clients with countdown status
wss.clients.forEach((client) => {
diff --git a/package.json b/package.json
index 99a895a..81b0416 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "obs-timer-controller",
- "version": "1.0.2",
+ "version": "1.0.3",
"description": "Handling browser fonts for OBS related to timers and countdowns.",
"main": "server.js",
"repository": {
@@ -22,7 +22,7 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"node": "node . test",
- "pkg-win": "electron-packager . OBS-Timer-Controller --platform=win32 --arch=x64 --out=dist --overwrite --icon=icon.ico --app-version=1.0.2 --author=\"XtoManuel\" --description=\"Handling browser fonts for OBS related to timers and countdowns.\""
+ "pkg-win": "electron-packager . OBS-Timer-Controller --platform=win32 --arch=x64 --app-version=1.0.3 --out=dist --overwrite --icon=icon.ico --author=\"XtoManuel\" --description=\"Handling browser fonts for OBS related to timers and countdowns.\""
},
"author": "XtoManuel",
"license": "ISC",
diff --git a/server.js b/server.js
index 9e92bde..55986ef 100644
--- a/server.js
+++ b/server.js
@@ -25,9 +25,12 @@ const {
startTimer,
pauseCrono,
pauseCdown,
+ pauseExtensible,
resetCrono,
resetCdown,
stopCdown,
+ stopExtensible,
+ resetExtensible,
sendVariableData,
initConfig,
saveConfig,
@@ -95,7 +98,7 @@ wss.on('connection', (ws) => {
client.send(JSON.stringify({ action: 'reload' }))
}
})
- } else if (data.action === 'startCrono' || data.action === 'startCdown') {
+ } else if (data.action === 'startCrono' || data.action === 'startCdown' || data.action === 'startExtensible') {
// Start the timer when receiving the "start" action
startTimer(wss, GlobalVariables, data.classElement)
} else if (data.action === 'pauseCrono') {
@@ -104,15 +107,24 @@ wss.on('connection', (ws) => {
} else if (data.action === 'pauseCdown') {
// Pause the countdown when receiving the "pause" action
pauseCdown(wss, GlobalVariables, data.classElement)
+ } else if (data.action === 'pauseExtensible') {
+ // Pause the countdown when receiving the "pause" action
+ pauseExtensible(wss, GlobalVariables, data.classElement)
} else if (data.action === 'resetCrono') {
// Reset the timer when receiving the "reset" action
resetCrono(wss, GlobalVariables, data.classElement)
} else if (data.action === 'resetCdown') {
// Reset the countdown when receiving the "reset" action
resetCdown(wss, GlobalVariables, data.classElement)
+ } else if (data.action === 'resetExtensible') {
+ // Reset the countdown when receiving the "reset" action
+ resetExtensible(wss, GlobalVariables, data.classElement)
} else if (data.action === 'stopCdown') {
// Stop the countdown when receiving the "stop" action
stopCdown(wss, GlobalVariables, data.classElement)
+ } else if (data.action === 'stopExtensible') {
+ // Stop the countdown when receiving the "stop" action
+ stopExtensible(wss, GlobalVariables, data.classElement)
} else if (data.action === 'changeTimeCdown' && data.time) {
// Change the time format when receiving the "changeFormat" action
GlobalVariables[data.classElement].textMilliseconds = data.time
@@ -123,7 +135,7 @@ wss.on('connection', (ws) => {
}
})
saveVariablesToYAML(GlobalVariables)
- if (GlobalVariables[data.classElement].status === 'stopped') {
+ if (GlobalVariables[data.classElement].status === 'ended') {
resetCdown(wss, GlobalVariables, data.classElement)
}
} else if (data.action === 'changeTimeCdownTime' && data.time) {
@@ -136,6 +148,19 @@ wss.on('connection', (ws) => {
}
})
saveVariablesToYAML(GlobalVariables)
+ } else if (data.action === 'changeTimeExtensible' && data.time) {
+ // Change the time format when receiving the "changeFormat" action
+ GlobalVariables[data.classElement].textMilliseconds = data.time
+ // Transmit the updated format to all WebSocket clients
+ wss.clients.forEach((client) => {
+ if (client.readyState === WebSocket.OPEN) {
+ client.send(JSON.stringify(GlobalVariables))
+ }
+ })
+ saveVariablesToYAML(GlobalVariables)
+ if (GlobalVariables[data.classElement].status === 'ended') {
+ resetExtensible(wss, GlobalVariables, data.classElement)
+ }
} else if (
data.action === 'changeTimezoneCdownTime' ||
data.action === 'changeTimezoneTime'
@@ -149,7 +174,9 @@ wss.on('connection', (ws) => {
client.send(JSON.stringify({ action: 'reload' }))
}
})
- } else if (data.action === 'editMsgCdown' || data.action === 'editMsgCdownTime') {
+ } else if (data.action === 'editMsgCdown' ||
+ data.action === 'editMsgCdownTime' ||
+ data.action === 'editMsgExtensible') {
GlobalVariables[data.classElement].msgEnd = data.msg
// Transmit the updated format to all WebSocket clients
wss.clients.forEach((client) => {
@@ -158,15 +185,38 @@ wss.on('connection', (ws) => {
}
})
saveVariablesToYAML(GlobalVariables)
- } else if (
- (data.action === 'changeFormatCrono' ||
- data.action === 'changeFormatCdown' ||
- data.action === 'changeFormatCdownTime' ||
- data.action === 'changeFormatTime') &&
- data.format
- ) {
+ } else if (data.action === 'checkboxStopAdd') {
+ // Change the text format when receiving the "changeFormat"
+ GlobalVariables[data.classElement].enableStopAdd = data.value
+ // Transmit the updated format to all WebSocket clients
+ wss.clients.forEach((client) => {
+ if (client.readyState === WebSocket.OPEN) {
+ client.send(JSON.stringify(GlobalVariables))
+ }
+ })
+ saveVariablesToYAML(GlobalVariables)
+ } else if (data.action === 'checkboxPauseAdd') {
+ // Change the text format when receiving the "changeFormat"
+ GlobalVariables[data.classElement].enablePauseAdd = data.value
+ // Transmit the updated format to all WebSocket clients
+ wss.clients.forEach((client) => {
+ if (client.readyState === WebSocket.OPEN) {
+ client.send(JSON.stringify(GlobalVariables))
+ }
+ })
+ saveVariablesToYAML(GlobalVariables)
+ } else if ((data.action === 'changeFormat' ||
+ data.action === 'changeFormatExtCrono' ||
+ data.action === 'changeFormatExtCdown'
+ ) && data.format) {
const classElement = data.classElement
- GlobalVariables[classElement].formatTime = data.format
+ if (data.action === 'changeFormatExtCrono') {
+ GlobalVariables[classElement].formatTimeCrono = data.format
+ } else if (data.action === 'changeFormatExtCdown') {
+ GlobalVariables[classElement].formatTimeCdown = data.format
+ } else {
+ GlobalVariables[classElement].formatTime = data.format
+ }
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
@@ -177,19 +227,19 @@ wss.on('connection', (ws) => {
saveVariablesToYAML(GlobalVariables)
} else if (
data.action === 'editTimeCrono' ||
- data.action === 'editTimeCdown'
+ (data.action === 'editTimeCdown' && GlobalVariables[data.classElement].status === 'ended')
) {
editTimeTimer(wss, GlobalVariables, data.time, data.classElement)
} else if (data.action === 'editTimeCdownTime') {
editTimeCdowntime(wss, GlobalVariables, data.time, data.classElement)
- } else if (
- (data.action === 'changeFontCrono' ||
- data.action === 'changeFontCdown' ||
- data.action === 'changeFontCdownTime' ||
- data.action === 'changeFontTime') &&
- data.font
+ } else if (data.action === 'editTimeExtensible' && (
+ GlobalVariables[data.classElement].status === 'started' ||
+ (GlobalVariables[data.classElement].status === 'paused' && GlobalVariables[data.classElement].enablePauseAdd) ||
+ (GlobalVariables[data.classElement].status === 'stopped' && GlobalVariables[data.classElement].enableStopAdd))
) {
- // Change the font format when receiving the "changeFormatTimer"
+ editTimeTimer(wss, GlobalVariables, data.time, data.classElement)
+ } else if (data.action === 'changeFont' && data.font) {
+ // Change the font format when receiving the "changeFormatr"
GlobalVariables[data.classElement].font = data.font
// Transmit the updated format to all WebSocket clients
@@ -199,13 +249,7 @@ wss.on('connection', (ws) => {
}
})
saveVariablesToYAML(GlobalVariables)
- } else if (
- (data.action === 'changeSizeCrono' ||
- data.action === 'changeSizeCdown' ||
- data.action === 'changeSizeCdownTime' ||
- data.action === 'changeSizeTime') &&
- data.size
- ) {
+ } else if (data.action === 'changeSize' && data.size) {
// Change the font size when receiving the "changeFormat"
GlobalVariables[data.classElement].size = data.size
@@ -216,12 +260,7 @@ wss.on('connection', (ws) => {
}
})
saveVariablesToYAML(GlobalVariables)
- } else if (
- data.action === 'textFormatCrono' ||
- data.action === 'textFormatCdown' ||
- data.action === 'textFormatCdownTime' ||
- data.action === 'textFormatTime'
- ) {
+ } else if (data.action === 'textFormat') {
// Change the text format when receiving the "changeFormat"
switch (data.format) {
case 'bold':
@@ -241,12 +280,7 @@ wss.on('connection', (ws) => {
}
})
saveVariablesToYAML(GlobalVariables)
- } else if (
- data.action === 'alignCrono' ||
- data.action === 'alignCdown' ||
- data.action === 'alignCdownTime' ||
- data.action === 'alignTime'
- ) {
+ } else if (data.action === 'align') {
// Change the text alignment when receiving the "changeFormat"
GlobalVariables[data.classElement].align = data.align
@@ -257,12 +291,7 @@ wss.on('connection', (ws) => {
}
})
saveVariablesToYAML(GlobalVariables)
- } else if (
- data.action === 'changeColorCrono' ||
- data.action === 'changeColorCdown' ||
- data.action === 'changeColorCdownTime' ||
- data.action === 'changeColorTime'
- ) {
+ } else if (data.action === 'changeColor') {
// Change the text color when receiving the "changeFormat"
GlobalVariables[data.classElement].colorText = data.color