/** * app/js/main.js * * This file is for 'access anywhere' javascript. * * @version 5.0.1 * @author Joey Kimsey * @link https://TheTempusProject.com * @license https://opensource.org/licenses/MIT [MIT LICENSE] */ /** * Progressive Web-App **/ let deferredPrompt; const installPrompt = document.getElementById("install-prompt"); const chromeMessage = document.getElementById("chrome-install-message"); const iosMessage = document.getElementById("ios-install-message"); const installButton = document.getElementById("install-button"); const dismissButton = document.querySelector("#install-prompt .btn-close"); // Check if the user previously dismissed the prompt if ( ! localStorage.getItem("pwaInstallDismissed") ) { window.addEventListener("beforeinstallprompt", (event) => { event.preventDefault(); deferredPrompt = event; installPrompt.classList.remove("d-none"); installPrompt.classList.add("d-block"); // Show the alert if ( chromeMessage ) { chromeMessage.classList.remove("d-none"); chromeMessage.classList.add("d-block"); // Show the prompt } }); if ( isIos() && ! isInStandaloneMode() ) { installPrompt.classList.remove("d-none"); installPrompt.classList.add("d-block"); // Show the alert if ( iosMessage ) { iosMessage.classList.remove("d-none"); iosMessage.classList.add("d-block"); // Show the prompt } } } // ios REQUIRES a service worker if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(() => console.log('Service Worker Registered')); } // Handle Install Button Click if ( installButton ) { installButton.addEventListener("click", async () => { if ( deferredPrompt ) { deferredPrompt.prompt(); const { outcome } = await deferredPrompt.userChoice; if (outcome === "dismissed") { setInstallDismissed(); // Store that the user dismissed the prompt } deferredPrompt = null; // Reset prompt installPrompt.classList.remove("d-block"); installPrompt.classList.add("d-none"); } }); } // Handle Close Button Click if ( dismissButton ) { dismissButton.addEventListener("click", () => { setInstallDismissed(); // Store that the user dismissed the prompt }); } // Function to remember user choice for 7 days function setInstallDismissed() { localStorage.setItem("pwaInstallDismissed", Date.now() + 7 * 24 * 60 * 60 * 1000); installPrompt.classList.remove("d-block"); // Hide the prompt installPrompt.classList.add("d-none"); } // Check if the 7-day period has passed if (localStorage.getItem("pwaInstallDismissed")) { const dismissUntil = parseInt(localStorage.getItem("pwaInstallDismissed"), 10); if (Date.now() < dismissUntil) { // } else { localStorage.removeItem("pwaInstallDismissed"); // Reset after 7 days } } function isIos() { return /iphone|ipad|ipod/i.test(navigator.userAgent); } function isInStandaloneMode() { return window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone; } /** * Automatically selects/de-selects all check boxes associated with that field **/ function checkAll(ele) { var checkboxes = document.getElementsByTagName( 'input' ); if (ele.checked) { test = true; } else { test = false; } for ( var i = 0; i < checkboxes.length; i++ ) { if ( checkboxes[i].type == 'checkbox' ) { if ( checkboxes[i].name == ele.value ) { checkboxes[i].checked = test; } } } } function insertTag( box, tag ) { var Field = document.getElementById( box ); var currentPos = cursorPos( Field ); var val = Field.value; var before = val.substring( 0, currentPos ); var after = val.substring( currentPos, val.length ); Field.value = before + '(' + tag + ')' + after; } function cursorPos( el ) { if ( el.selectionStart ) { return el.selectionStart; } else if ( document.selection ) { el.focus(); var r = document.selection.createRange(); if ( r == null ) { return 0; } var re = el.createTextRange(), rc = re.duplicate(); re.moveToBookmark( r.getBookmark() ); rc.setEndPoint( 'EndToStart', re ); return rc.text.length; } return 0; } function getRandomInt(min, max) { const minCeiled = Math.ceil(min); const maxFloored = Math.floor(max); return Math.floor(Math.random() * (maxFloored - minCeiled) + minCeiled); } function copyElementText( id ) { const inputElement = document.getElementById( id ); const textToCopy = inputElement.value; if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(textToCopy) .then(() => alert('Copied to clipboard!')) .catch((err) => console.error('Failed to copy: ', err)); } else { // Fallback for older browsers inputElement.select(); try { document.execCommand('copy'); alert('Copied to clipboard!'); } catch (err) { console.error('Failed to copy: ', err); } } } document.addEventListener("DOMContentLoaded", function () { document.querySelectorAll("select").forEach(function (select) { var selectedValue = select.getAttribute("value"); if (selectedValue) { select.removeAttribute("value"); select.querySelectorAll("option").forEach(function (option) { if (option.getAttribute("value") === selectedValue) { option.selected = true; } }); } }); }); document.addEventListener('DOMContentLoaded', function () { const ttpDarkmode = document.getElementById('dark-mode-pref'); const toggleButton = document.getElementById('dark-mode-toggle'); const enableButton = document.getElementById('dark-mode-toggle-button'); const darkModeStylesheet = document.getElementById('dark-mode-stylesheet'); let currentState = ''; // Check if dark mode is set by ttp if ( ttpDarkmode ) { if ( 'true' == ttpDarkmode.value ) { currentState = 'enabled'; } if ( 'false' == ttpDarkmode.value ) { currentState = 'disabled'; } } // Check if dark mode is set in localStorage if ( '' == currentState ) { if ( localStorage.getItem('darkMode') === 'enabled' ) { currentState = 'enabled'; } } // Update current button states if ( 'enabled' == currentState ) { darkModeStylesheet.disabled = false; if ( toggleButton ) { toggleButton.checked = true; } if ( enableButton ) { enableButton.innerText = 'Disable Now'; } } // Style striped table elements document.querySelectorAll('.table-striped').forEach((table) => { if ( 'enabled' == currentState ) { table.classList.add('table-dark'); } else { table.classList.add('table-light') } }); if ( enableButton ) { enableButton.addEventListener('click', function () { if ( darkModeStylesheet.disabled ) { darkModeStylesheet.disabled = false; localStorage.setItem('darkMode', 'enabled'); enableButton.innerText = 'Disable Now'; } else { darkModeStylesheet.disabled = true; localStorage.setItem('darkMode', 'disabled'); enableButton.innerText = 'Enable Now'; } }); } if ( toggleButton ) { toggleButton.addEventListener('click', function () { if (darkModeStylesheet.disabled) { toggleDarkModePref( true ); darkModeStylesheet.disabled = false; localStorage.setItem('darkMode', 'enabled'); } else { toggleDarkModePref( false ); darkModeStylesheet.disabled = true; localStorage.setItem('darkMode', 'disabled'); } document.querySelectorAll('.table-striped').forEach((table) => { if (localStorage.getItem('darkMode') === 'enabled') { table.classList.add('table-dark'); table.classList.remove('table-light'); } else { table.classList.add('table-light'); table.classList.remove('table-dark'); } }); }); } function toggleDarkModePref(value) { var fields = new URLSearchParams(); fields.append("prefName", "darkMode"); fields.append("prefValue", value); fetch("/usercp/updatePref", { method: "POST", body: fields, headers: { "Content-Type": "application/x-www-form-urlencoded", }, }) // .then(response => response.text()) // Handle response if needed .catch(error => console.error("Error:", error)); } }); // this reverses the carets for the folderSelect document.querySelectorAll('[data-bs-toggle="collapse"]').forEach(button => { button.addEventListener('click', () => { setTimeout(() => { const icon = button.querySelector('i'); // Only proceed if the icon already has one of the relevant classes if (icon && (icon.classList.contains('fa-caret-down') || icon.classList.contains('fa-caret-up'))) { icon.classList.toggle('fa-caret-down', button.classList.contains('collapsed')); icon.classList.toggle('fa-caret-up', !button.classList.contains('collapsed')); } }, 150); }); }); // this should load all popovers document.addEventListener("DOMContentLoaded", function () { var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')); var popoverList = popoverTriggerList.map(function (popoverTriggerEl) { return new bootstrap.Popover(popoverTriggerEl, { customClass: 'context-popover', }); }); });