From e4831ee3d9b2393fa313699f2a008dc2b44b30ce Mon Sep 17 00:00:00 2001 From: recanman <29310982+recanman@users.noreply.github.com> Date: Fri, 13 Sep 2024 15:09:58 -0700 Subject: [PATCH 1/7] refactor: redo frontend js --- src/js/main.js | 116 +++++++++++++++++++++---------------------------- 1 file changed, 49 insertions(+), 67 deletions(-) diff --git a/src/js/main.js b/src/js/main.js index 7390237..788e95a 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,22 +1,22 @@ import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/js/bootstrap.bundle.min'; - import '../css/custom.css'; -import Tooltip from "bootstrap/js/dist/tooltip"; -var tooltipTriggerList = [].slice.call( - document.querySelectorAll('[data-toggle="tooltip"]') -); -var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { - return new Tooltip(tooltipTriggerEl, { placement: "top" }); -}); +import Tooltip from 'bootstrap/js/dist/tooltip'; + +const tooltipTriggerList = Array.from(document.querySelectorAll('[data-toggle="tooltip"]')); +const tooltipList = tooltipTriggerList.map(tooltipTriggerEl => new Tooltip(tooltipTriggerEl, { placement: 'top' })); console.log(tooltipList); let lastModifiedField = 'xmr'; +const exchangeRates = {}; -var exchangeRates = {}; +const runConvert = () => + lastModifiedField === 'xmr' ? xmrConvert() : fiatConvert(); -document.addEventListener('DOMContentLoaded', function () { + + +document.addEventListener('DOMContentLoaded', () => { const copyXMRBtn = document.getElementById('copyXMRBtn'); const copyFiatBtn = document.getElementById('copyFiatBtn'); const xmrInput = document.getElementById('xmrInput'); @@ -31,66 +31,50 @@ document.addEventListener('DOMContentLoaded', function () { button.addEventListener('click', (e) => { e.preventDefault(); selectBox.value = button.textContent; - if (lastModifiedField === 'xmr') { - xmrConvert(); - } else { - fiatConvert(); - } + runConvert(); history.pushState(null, '', `?in=${button.textContent}`); }); }); // Add event listeners for the copy buttons - copyXMRBtn.addEventListener('click', copyToClipBoardXMR); - copyFiatBtn.addEventListener('click', copyToClipBoardFiat); + copyXMRBtn.addEventListener('click', copyToClipboardXMR); + copyFiatBtn.addEventListener('click', copyToClipboardFiat); // Add event listeners for the XMR input field - xmrInput.addEventListener('change', () => xmrConvert(xmrInput.value)); + xmrInput.addEventListener('change', xmrConvert); xmrInput.addEventListener('keyup', () => { - xmrInput.value = xmrInput.value.replace(/[^\.^,\d]/g, ''); - xmrInput.value = xmrInput.value.replace(/\,/, '.'); + xmrInput.value = xmrInput.value.replace(/[^\.^,\d]/g, '').replace(/\,/, '.'); if (xmrInput.value.split('.').length > 2) { xmrInput.value = xmrInput.value.slice(0, -1); } - xmrConvert(xmrInput.value); - }); - xmrInput.addEventListener('input', () => { - lastModifiedField = 'xmr'; + xmrConvert(); }); + xmrInput.addEventListener('input', () => lastModifiedField = 'xmr'); // Add event listeners for the fiat input field - fiatInput.addEventListener('change', () => fiatConvert(fiatInput.value)); + fiatInput.addEventListener('change', fiatConvert); fiatInput.addEventListener('keyup', () => { - fiatInput.value = fiatInput.value.replace(/[^\.^,\d]/g, ''); - fiatInput.value = fiatInput.value.replace(/\,/, '.'); + fiatInput.value = fiatInput.value.replace(/[^\.^,\d]/g, '').replace(/\,/, '.'); if (fiatInput.value.split('.').length > 2) { fiatInput.value = fiatInput.value.slice(0, -1); } - fiatConvert(fiatInput.value); - }); - fiatInput.addEventListener('input', () => { - lastModifiedField = 'fiat'; + fiatConvert(); }); + fiatInput.addEventListener('input', () => lastModifiedField = 'fiat'); // Add event listener for the select box to change the conversion - selectBox.addEventListener('change', () => { - if (lastModifiedField === 'xmr') { - xmrConvert(selectBox.value) - } else { - fiatConvert(selectBox.value) - } - }); + selectBox.addEventListener('change', runConvert); // Hide the conversion buttons if JavaScript is enabled convertXMRToFiatBtn.style.display = 'none'; convertFiatToXMRBtn.style.display = 'none'; // Fetch updated exchange rates immediately, then every 5 seconds - fetchUpdatedExchangeRates(); + fetchUpdatedExchangeRates(true) setInterval(fetchUpdatedExchangeRates, 5000); }); -function fetchUpdatedExchangeRates() { +function fetchUpdatedExchangeRates(showAlert = false) { fetch('/coingecko.php') .then(response => response.json()) .then(data => { @@ -102,13 +86,12 @@ function fetchUpdatedExchangeRates() { updateTimeElement(data.time); // Re-execute the appropriate conversion function - if (lastModifiedField === 'xmr') { - xmrConvert(); - } else { - fiatConvert(); - } + runConvert(); }) - .catch(error => console.error('Error fetching exchange rates:', error)); + .catch(e => { + const msg = `Error fetching exchange rates: ${e}`; + showAlert ? alert(msg) : console.error(msg); + }); } function updateTimeElement(unixTimestamp) { @@ -123,41 +106,40 @@ function updateTimeElement(unixTimestamp) { u.parentElement.innerHTML = u.parentElement.innerHTML.replace('Europe/Berlin', Intl.DateTimeFormat().resolvedOptions().timeZone); } -function copyToClipBoardXMR() { - var content = document.getElementById('xmrInput'); +function copyToClipboardXMR() { + const content = document.getElementById('xmrInput'); content.select(); + + // Using deprecated execCommand for compatibility with older browsers document.execCommand('copy'); } -function copyToClipBoardFiat() { - var content = document.getElementById('fiatInput'); +function copyToClipboardFiat() { + const content = document.getElementById('fiatInput'); content.select(); + + // Using deprecated execCommand for compatibility with older browsers document.execCommand('copy'); } -function fiatConvert(value) { - let fiatAmount = document.getElementById("fiatInput").value; - let xmrValue = document.getElementById("xmrInput"); - let selectBox = document.getElementById("selectBox").value; +function fiatConvert() { + const fiatAmount = document.getElementById('fiatInput').value; + const xmrValue = document.getElementById('xmrInput'); + const selectBox = document.getElementById('selectBox').value; if (exchangeRates[selectBox]) { - let value = fiatAmount / exchangeRates[selectBox]; + const value = fiatAmount / exchangeRates[selectBox]; xmrValue.value = value.toFixed(12); } } -function xmrConvert(value) { - let xmrAmount = document.getElementById("xmrInput").value; - let fiatValue = document.getElementById("fiatInput"); - let selectBox = document.getElementById("selectBox").value; +function xmrConvert() { + const xmrAmount = document.getElementById('xmrInput').value; + const fiatValue = document.getElementById('fiatInput'); + const selectBox = document.getElementById('selectBox').value; if (exchangeRates[selectBox]) { - let value = xmrAmount * exchangeRates[selectBox]; - fiatValue.value = value.toFixed(selectBox == 'BTC' || selectBox == 'LTC' || selectBox == 'ETH' || selectBox == 'XAG' || selectBox == 'XAU' ? 8 : 2); + const value = xmrAmount * exchangeRates[selectBox]; + fiatValue.value = value.toFixed(['BTC', 'LTC', 'ETH', 'XAG', 'XAU'].includes(selectBox) ? 8 : 2); } -} - -window.copyToClipBoardXMR = copyToClipBoardXMR; -window.copyToClipBoardFiat = copyToClipBoardFiat; -window.fiatConvert = fiatConvert; -window.xmrConvert = xmrConvert; \ No newline at end of file +} \ No newline at end of file From d514cd94cb1c8f07cf0ea5269af991d47aad718d Mon Sep 17 00:00:00 2001 From: recanman <29310982+recanman@users.noreply.github.com> Date: Fri, 13 Sep 2024 15:11:44 -0700 Subject: [PATCH 2/7] style: use consistent indent spacing --- src/js/main.js | 204 ++++++++++++++++++++++++------------------------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/src/js/main.js b/src/js/main.js index 788e95a..aca7c6b 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -12,134 +12,134 @@ let lastModifiedField = 'xmr'; const exchangeRates = {}; const runConvert = () => - lastModifiedField === 'xmr' ? xmrConvert() : fiatConvert(); + lastModifiedField === 'xmr' ? xmrConvert() : fiatConvert(); document.addEventListener('DOMContentLoaded', () => { - const copyXMRBtn = document.getElementById('copyXMRBtn'); - const copyFiatBtn = document.getElementById('copyFiatBtn'); - const xmrInput = document.getElementById('xmrInput'); - const fiatInput = document.getElementById('fiatInput'); - const selectBox = document.getElementById('selectBox'); - const convertXMRToFiatBtn = document.getElementById('convertXMRToFiat'); - const convertFiatToXMRBtn = document.getElementById('convertFiatToXMR'); - const fiatButtons = document.querySelectorAll('.fiat-btn'); - - // Add event listeners for the currency buttons - fiatButtons.forEach(button => { - button.addEventListener('click', (e) => { - e.preventDefault(); - selectBox.value = button.textContent; - runConvert(); - history.pushState(null, '', `?in=${button.textContent}`); + const copyXMRBtn = document.getElementById('copyXMRBtn'); + const copyFiatBtn = document.getElementById('copyFiatBtn'); + const xmrInput = document.getElementById('xmrInput'); + const fiatInput = document.getElementById('fiatInput'); + const selectBox = document.getElementById('selectBox'); + const convertXMRToFiatBtn = document.getElementById('convertXMRToFiat'); + const convertFiatToXMRBtn = document.getElementById('convertFiatToXMR'); + const fiatButtons = document.querySelectorAll('.fiat-btn'); + + // Add event listeners for the currency buttons + fiatButtons.forEach(button => { + button.addEventListener('click', (e) => { + e.preventDefault(); + selectBox.value = button.textContent; + runConvert(); + history.pushState(null, '', `?in=${button.textContent}`); + }); }); - }); - - // Add event listeners for the copy buttons - copyXMRBtn.addEventListener('click', copyToClipboardXMR); - copyFiatBtn.addEventListener('click', copyToClipboardFiat); - - // Add event listeners for the XMR input field - xmrInput.addEventListener('change', xmrConvert); - xmrInput.addEventListener('keyup', () => { - xmrInput.value = xmrInput.value.replace(/[^\.^,\d]/g, '').replace(/\,/, '.'); - if (xmrInput.value.split('.').length > 2) { - xmrInput.value = xmrInput.value.slice(0, -1); - } - xmrConvert(); - }); - xmrInput.addEventListener('input', () => lastModifiedField = 'xmr'); - - // Add event listeners for the fiat input field - fiatInput.addEventListener('change', fiatConvert); - fiatInput.addEventListener('keyup', () => { - fiatInput.value = fiatInput.value.replace(/[^\.^,\d]/g, '').replace(/\,/, '.'); - if (fiatInput.value.split('.').length > 2) { - fiatInput.value = fiatInput.value.slice(0, -1); - } - fiatConvert(); - }); - fiatInput.addEventListener('input', () => lastModifiedField = 'fiat'); - - // Add event listener for the select box to change the conversion - selectBox.addEventListener('change', runConvert); - - // Hide the conversion buttons if JavaScript is enabled - convertXMRToFiatBtn.style.display = 'none'; - convertFiatToXMRBtn.style.display = 'none'; - - // Fetch updated exchange rates immediately, then every 5 seconds - fetchUpdatedExchangeRates(true) - setInterval(fetchUpdatedExchangeRates, 5000); + + // Add event listeners for the copy buttons + copyXMRBtn.addEventListener('click', copyToClipboardXMR); + copyFiatBtn.addEventListener('click', copyToClipboardFiat); + + // Add event listeners for the XMR input field + xmrInput.addEventListener('change', xmrConvert); + xmrInput.addEventListener('keyup', () => { + xmrInput.value = xmrInput.value.replace(/[^\.^,\d]/g, '').replace(/\,/, '.'); + if (xmrInput.value.split('.').length > 2) { + xmrInput.value = xmrInput.value.slice(0, -1); + } + xmrConvert(); + }); + xmrInput.addEventListener('input', () => lastModifiedField = 'xmr'); + + // Add event listeners for the fiat input field + fiatInput.addEventListener('change', fiatConvert); + fiatInput.addEventListener('keyup', () => { + fiatInput.value = fiatInput.value.replace(/[^\.^,\d]/g, '').replace(/\,/, '.'); + if (fiatInput.value.split('.').length > 2) { + fiatInput.value = fiatInput.value.slice(0, -1); + } + fiatConvert(); + }); + fiatInput.addEventListener('input', () => lastModifiedField = 'fiat'); + + // Add event listener for the select box to change the conversion + selectBox.addEventListener('change', runConvert); + + // Hide the conversion buttons if JavaScript is enabled + convertXMRToFiatBtn.style.display = 'none'; + convertFiatToXMRBtn.style.display = 'none'; + + // Fetch updated exchange rates immediately, then every 5 seconds + fetchUpdatedExchangeRates(true) + setInterval(fetchUpdatedExchangeRates, 5000); }); function fetchUpdatedExchangeRates(showAlert = false) { - fetch('/coingecko.php') + fetch('/coingecko.php') .then(response => response.json()) .then(data => { - // Update the exchangeRates object with the new values - for (const [currency, value] of Object.entries(data)) { - exchangeRates[currency.toUpperCase()] = value.lastValue; - } - - updateTimeElement(data.time); - - // Re-execute the appropriate conversion function - runConvert(); + // Update the exchangeRates object with the new values + for (const [currency, value] of Object.entries(data)) { + exchangeRates[currency.toUpperCase()] = value.lastValue; + } + + updateTimeElement(data.time); + + // Re-execute the appropriate conversion function + runConvert(); }) .catch(e => { - const msg = `Error fetching exchange rates: ${e}`; - showAlert ? alert(msg) : console.error(msg); + const msg = `Error fetching exchange rates: ${e}`; + showAlert ? alert(msg) : console.error(msg); }); } function updateTimeElement(unixTimestamp) { - const date = new Date(unixTimestamp * 1000); - const hours = String(date.getHours()).padStart(2, '0'); - const minutes = String(date.getMinutes()).padStart(2, '0'); - const seconds = String(date.getSeconds()).padStart(2, '0'); - const formattedTime = `${hours}:${minutes}:${seconds}`; - - const u = document.querySelector('u'); - u.textContent = formattedTime; - u.parentElement.innerHTML = u.parentElement.innerHTML.replace('Europe/Berlin', Intl.DateTimeFormat().resolvedOptions().timeZone); + const date = new Date(unixTimestamp * 1000); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + const seconds = String(date.getSeconds()).padStart(2, '0'); + const formattedTime = `${hours}:${minutes}:${seconds}`; + + const u = document.querySelector('u'); + u.textContent = formattedTime; + u.parentElement.innerHTML = u.parentElement.innerHTML.replace('Europe/Berlin', Intl.DateTimeFormat().resolvedOptions().timeZone); } function copyToClipboardXMR() { - const content = document.getElementById('xmrInput'); - content.select(); - - // Using deprecated execCommand for compatibility with older browsers - document.execCommand('copy'); + const content = document.getElementById('xmrInput'); + content.select(); + + // Using deprecated execCommand for compatibility with older browsers + document.execCommand('copy'); } function copyToClipboardFiat() { - const content = document.getElementById('fiatInput'); - content.select(); - - // Using deprecated execCommand for compatibility with older browsers - document.execCommand('copy'); + const content = document.getElementById('fiatInput'); + content.select(); + + // Using deprecated execCommand for compatibility with older browsers + document.execCommand('copy'); } function fiatConvert() { - const fiatAmount = document.getElementById('fiatInput').value; - const xmrValue = document.getElementById('xmrInput'); - const selectBox = document.getElementById('selectBox').value; - - if (exchangeRates[selectBox]) { - const value = fiatAmount / exchangeRates[selectBox]; - xmrValue.value = value.toFixed(12); - } + const fiatAmount = document.getElementById('fiatInput').value; + const xmrValue = document.getElementById('xmrInput'); + const selectBox = document.getElementById('selectBox').value; + + if (exchangeRates[selectBox]) { + const value = fiatAmount / exchangeRates[selectBox]; + xmrValue.value = value.toFixed(12); + } } function xmrConvert() { - const xmrAmount = document.getElementById('xmrInput').value; - const fiatValue = document.getElementById('fiatInput'); - const selectBox = document.getElementById('selectBox').value; - - if (exchangeRates[selectBox]) { - const value = xmrAmount * exchangeRates[selectBox]; - fiatValue.value = value.toFixed(['BTC', 'LTC', 'ETH', 'XAG', 'XAU'].includes(selectBox) ? 8 : 2); - } + const xmrAmount = document.getElementById('xmrInput').value; + const fiatValue = document.getElementById('fiatInput'); + const selectBox = document.getElementById('selectBox').value; + + if (exchangeRates[selectBox]) { + const value = xmrAmount * exchangeRates[selectBox]; + fiatValue.value = value.toFixed(['BTC', 'LTC', 'ETH', 'XAG', 'XAU'].includes(selectBox) ? 8 : 2); + } } \ No newline at end of file From 7ebf97b3b706c6d1a321d3477b6fb2e45b27ff25 Mon Sep 17 00:00:00 2001 From: recanman <29310982+recanman@users.noreply.github.com> Date: Fri, 13 Sep 2024 23:06:44 -0700 Subject: [PATCH 3/7] feat: stop fetching exchange rates after inactivity --- src/js/main.js | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/js/main.js b/src/js/main.js index aca7c6b..ae739b8 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -14,7 +14,45 @@ const exchangeRates = {}; const runConvert = () => lastModifiedField === 'xmr' ? xmrConvert() : fiatConvert(); +let updateInterval +const startFetching = () => updateInterval = setInterval(fetchUpdatedExchangeRates, 5000); +const stopFetching = () => { + clearInterval(updateInterval) + updateInterval = null; +}; +const inactivityTimeout = 30 * 1000; // 30 seconds +let lastActivity = Date.now() + +const resetActivity = () => lastActivity = Date.now() +const checkInactivity = () => { + if (Date.now() - lastActivity > inactivityTimeout) { + console.log('Inactivity detected, stopping exchange rate updates'); + stopFetching(); + } else { + requestAnimationFrame(checkInactivity); + } +} + +document.addEventListener('focus', () => { + const focused = document.hasFocus(); + console.log(`Page is ${focused ? 'visible' : 'hidden'}`); + + if (focused && !updateInterval) { + console.log('Restarting exchange rate updates'); + startFetching(); + + resetActivity(); + requestAnimationFrame(checkInactivity); + } else { + stopFetching(); + } +}); +window.addEventListener('mousemove', resetActivity); +window.addEventListener('keydown', resetActivity); +window.addEventListener('touchstart', resetActivity); + +requestAnimationFrame(checkInactivity); document.addEventListener('DOMContentLoaded', () => { const copyXMRBtn = document.getElementById('copyXMRBtn'); @@ -71,7 +109,7 @@ document.addEventListener('DOMContentLoaded', () => { // Fetch updated exchange rates immediately, then every 5 seconds fetchUpdatedExchangeRates(true) - setInterval(fetchUpdatedExchangeRates, 5000); + startFetching(); }); function fetchUpdatedExchangeRates(showAlert = false) { From 72eb7bc3bc0569036613c8ca8504ae06d5200cd3 Mon Sep 17 00:00:00 2001 From: recanman <29310982+recanman@users.noreply.github.com> Date: Fri, 13 Sep 2024 23:28:52 -0700 Subject: [PATCH 4/7] chore: update dependencies to fix vulnerability --- package-lock.json | 73 +++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index e4bb07c..70ae82f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -124,30 +124,10 @@ "url": "https://opencollective.com/popperjs" } }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "license": "MIT" }, "node_modules/@types/json-schema": { @@ -379,10 +359,10 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "license": "MIT", "peerDependencies": { "acorn": "^8" @@ -833,9 +813,9 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", - "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -1587,9 +1567,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "license": "ISC" }, "node_modules/pkg-dir": { @@ -1605,9 +1585,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "dev": true, "funding": [ { @@ -1626,8 +1606,8 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -1965,9 +1945,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -2248,21 +2228,20 @@ } }, "node_modules/webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", + "version": "5.95.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", + "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", "license": "MIT", "dependencies": { - "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", From e79b7a8de59b6e7a1c1c3e6bcdeacd861c32d2ba Mon Sep 17 00:00:00 2001 From: recanman <29310982+recanman@users.noreply.github.com> Date: Fri, 13 Sep 2024 23:29:24 -0700 Subject: [PATCH 5/7] build: fix webpack config for purgecss --- webpack.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/webpack.config.js b/webpack.config.js index d1a8d91..ea9d9cd 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -29,7 +29,9 @@ module.exports = { }), new PurgeCSSPlugin({ paths: glob.sync([ - path.join(__dirname, 'index.php') + path.join(__dirname, 'index.php'), + path.join(__dirname, 'src/js/*.js'), + path.join(__dirname, 'templates/*.php'), ]), safelist: ['tooltip', 'fade', 'show', 'bs-tooltip-top', 'tooltip-inner', 'tooltip-arrow', 'btn-equals', 'btn-arrow', 'alert', 'alert-warning'] }) From 2227ebe6cd485e969884f1c233c8984698b7a195 Mon Sep 17 00:00:00 2001 From: recanman <29310982+recanman@users.noreply.github.com> Date: Fri, 13 Sep 2024 23:29:39 -0700 Subject: [PATCH 6/7] chore: remove unneeded import --- src/js/main.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/js/main.js b/src/js/main.js index ae739b8..9f99bd2 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,5 +1,4 @@ import 'bootstrap/dist/css/bootstrap.min.css'; -import 'bootstrap/dist/js/bootstrap.bundle.min'; import '../css/custom.css'; import Tooltip from 'bootstrap/js/dist/tooltip'; From bffbd46ce0a0d4827fb55c169bcd728f5af58609 Mon Sep 17 00:00:00 2001 From: recanman <29310982+recanman@users.noreply.github.com> Date: Fri, 13 Sep 2024 23:37:01 -0700 Subject: [PATCH 7/7] feat: add footer, qr code img --- img/qr.jpg | Bin 0 -> 32451 bytes index.php | 1 + templates/index.php | 1 + 3 files changed, 2 insertions(+) create mode 100644 img/qr.jpg diff --git a/img/qr.jpg b/img/qr.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a8f6e3434edd8aa6500ca043e784b17135e5445d GIT binary patch literal 32451 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 literal 0 HcmV?d00001 diff --git a/index.php b/index.php index 9fa90c4..27dc946 100644 --- a/index.php +++ b/index.php @@ -27,6 +27,7 @@ $display_servers_guru = isset($config['servers_guru']) && $config['servers_guru' $attribution = isset($config['attribution']) ? $config['attribution'] : ''; $preferred_currencies = isset($config['preferred_currencies']) ? $config['preferred_currencies'] : []; $github_url = isset($config['github_url']) ? $config['github_url'] : 'https://github.com/rottenwheel/moner.ooo/'; +$footer_html = isset($config['footer_html']) ? $config['footer_html'] : ''; // Extract the keys $currencies = array_map('strtoupper', array_keys($api_cg)); diff --git a/templates/index.php b/templates/index.php index 997cc41..c7c8575 100644 --- a/templates/index.php +++ b/templates/index.php @@ -138,6 +138,7 @@ <small class="cursor-default text-white" lang="<?php echo $lang_meta; ?>"> <?php echo $footer_links . $getmonero . $countrymonero; ?> + <?php echo $footer_html; ?> </small> </div>