diff --git a/assets/css/paywall-styles.css b/assets/css/paywall-styles.css index 41c53a0..4943366 100644 --- a/assets/css/paywall-styles.css +++ b/assets/css/paywall-styles.css @@ -38,4 +38,55 @@ font-family: inherit; font-size: 1.2em; font-style: italic; +} + +/* Verification Overlay Styles */ + +.paybutton_overlay { + left: 0; + top: 0; + width: 100%; + height: 100%; + position: fixed; + background: rgba(34, 34, 34, 0.8); + text-align: center; + z-index: 999999; +} + +.paybutton_overlay_inner { + left: 0; + top: 0; + width: 100%; + height: 100%; + position: absolute; + z-index: 999999; +} + +.paybutton_overlay_content { + left: 50%; + top: 50%; + position: absolute; + transform: translate(-50%, -50%); +} + +.paybutton_overlay_spinner { + width: 75px; + height: 75px; + display: inline-block; + border-width: 4px; + border-color: rgba(255, 255, 255, 0.05); + border-top-color: #0074C2; + animation: paybutton_spin 1s infinite linear; + border-radius: 100%; + border-style: solid; +} + +@keyframes paybutton_spin { + 100% { transform: rotate(360deg); } +} + +#paybutton_overlay_text { + padding-top: 7px; + color: white; + font-weight: bold; } \ No newline at end of file diff --git a/assets/js/paybutton-paywall-cashtab-login.js b/assets/js/paybutton-paywall-cashtab-login.js index f18c8a3..cdb4993 100644 --- a/assets/js/paybutton-paywall-cashtab-login.js +++ b/assets/js/paybutton-paywall-cashtab-login.js @@ -1,6 +1,20 @@ /* File: assets/js/paybutton-paywall-cashtab-login.js */ let isLoggedIn = false; +/* Show/Hide Verification Overlay*/ +function showPBVerificationOverlay(msg = "Processing, please wait!") { + const el = document.getElementById('paybutton_overlay'); + if (!el) return; + document.getElementById('paybutton_overlay_text').innerText = msg; + el.style.display = 'block'; +} + +function hidePBVerificationOverlay() { + const el = document.getElementById('paybutton_overlay'); + if (!el) return; + el.style.display = 'none'; +} + /** * Handle user login: * Called when the PayButton login flow completes successfully. @@ -64,6 +78,8 @@ function renderLoginPaybutton() { // Shared state: login address captured in onSuccess, consumed in onClose. let loginAddr = null; let loginTx = null; + // Track if a payment was actually initiated + let paymentInitiated = false; PayButton.render(document.getElementById('loginPaybutton'), { to: PaywallAjax.defaultAddress, @@ -75,6 +91,7 @@ function renderLoginPaybutton() { autoClose: true, opReturn: 'login', onSuccess: function (tx) { + paymentInitiated = true; loginAddr = tx?.inputAddresses?.[0] ?? null; loginTx = { hash: tx?.hash ?? '', @@ -82,6 +99,11 @@ function renderLoginPaybutton() { }; }, onClose: function () { + // Show verification overlay immediately + if (paymentInitiated) { + showPBVerificationOverlay("Verifying login..."); + } + if (loginAddr && loginTx && loginTx.hash) { // Make stable copies for the whole retry flow const addrCopy = loginAddr; @@ -105,6 +127,8 @@ function renderLoginPaybutton() { // Retry once again after 3 seconds setTimeout(() => tryValidateLogin(2), 3000); } else { + hidePBVerificationOverlay(); + paymentInitiated = false; alert('⚠️ Login failed: Invalid or expired transaction.'); } } diff --git a/assets/js/paywalled-content.js b/assets/js/paywalled-content.js index cb0e8ac..73ac8df 100644 --- a/assets/js/paywalled-content.js +++ b/assets/js/paywalled-content.js @@ -20,6 +20,21 @@ * the now unlocked content is displayed. * 3. Finally, the render() method is called on the container to display the button. */ + +/* Show/Hide Verification Overlay*/ +function showPBVerificationOverlay(msg = "Verifying Payment...") { + const el = document.getElementById('paybutton_overlay'); + if (!el) return; + document.getElementById('paybutton_overlay_text').innerText = msg; + el.style.display = 'block'; +} + +function hidePBVerificationOverlay() { + const el = document.getElementById('paybutton_overlay'); + if (!el) return; + el.style.display = 'none'; +} + jQuery(document).ready(function($) { $('.paybutton-container').each(function() { var $container = $(this); @@ -37,6 +52,10 @@ jQuery(document).ready(function($) { // Shared state: user wallet address + unlock tx captured in onSuccess. let unlockAddr = null; let unlockTx = null; + // Check if the unlock flow has completed to avoid showing the verification overlay. + let unlockFlowCompleted = false; + // Track if a payment was actually initiated + let paymentInitiated = false; // Helper to fetch and inject unlocked content function fetchUnlocked() { @@ -108,6 +127,7 @@ jQuery(document).ready(function($) { autoClose: configData.autoClose, onSuccess: function (tx) { + paymentInitiated = true; unlockAddr = (tx.inputAddresses && tx.inputAddresses.length > 0) ? tx.inputAddresses[0] : ''; @@ -157,6 +177,8 @@ jQuery(document).ready(function($) { success: function () { // Finally, fetch and render the unlocked content fetchUnlocked(); + unlockFlowCompleted = true; + hidePBVerificationOverlay(); } }); } else { @@ -171,6 +193,9 @@ jQuery(document).ready(function($) { }, nextDelay); } else { alert('⚠️ Payment could not be verified on-chain. Please try again.'); + hidePBVerificationOverlay(); + paymentInitiated = false; + unlockFlowCompleted = false; } } } @@ -187,6 +212,11 @@ jQuery(document).ready(function($) { unlockAddr = null; unlockTx = null; }, + onClose: function() { + if (paymentInitiated && !unlockFlowCompleted) { + showPBVerificationOverlay(); + } + }, }); }); }); diff --git a/templates/public/sticky-header.php b/templates/public/sticky-header.php index 528861f..aaa5449 100644 --- a/templates/public/sticky-header.php +++ b/templates/public/sticky-header.php @@ -69,4 +69,13 @@ + + +
\ No newline at end of file