From 6aca61b69c1bb66c9e95db8e8ac4e55681aaef4e Mon Sep 17 00:00:00 2001 From: xecdev Date: Wed, 26 Nov 2025 18:51:31 +0430 Subject: [PATCH 1/4] improve sticky header button UI/UX --- assets/css/sticky-header.css | 133 ++++++++++++++++++- assets/icons/logout.svg | 2 + assets/icons/profile.svg | 1 + assets/js/paybutton-paywall-cashtab-login.js | 25 +++- templates/public/sticky-header.php | 24 +++- 5 files changed, 172 insertions(+), 13 deletions(-) create mode 100644 assets/icons/logout.svg create mode 100644 assets/icons/profile.svg diff --git a/assets/css/sticky-header.css b/assets/css/sticky-header.css index 464694d..a8c635e 100644 --- a/assets/css/sticky-header.css +++ b/assets/css/sticky-header.css @@ -57,6 +57,7 @@ display: flex; /* added for vertical centering */ align-items: center; /* centers content vertically */ justify-content: center; /* centers content horizontally */ + opacity: 1 !important; } /* Profile button colors */ @@ -64,17 +65,55 @@ background-color: var(--profile-button-bg-color, #ffc107); color: var(--profile-button-text-color, #000); } -.profile-button:hover { - background-color: #e0a800; -} /* Logout button colors */ .logout-button { background-color: var(--logout-button-bg-color, #d9534f); color: var(--logout-button-text-color, #fff); } -.logout-button:hover { - background-color: #c9302c; + +/* Logout button "logging out" state */ +.logout-button.is-logging-out { + position: relative; + opacity: 0.8; + cursor: wait; + padding-right: 26px; /* space for spinner */ +} + +/* Default: show "Logout", hide "Logging out..." */ +.logout-button .btn-text-logging-out { + display: none; +} + +/* When logging out: swap labels */ +.logout-button.is-logging-out .btn-text-default { + display: none; +} + +.logout-button.is-logging-out .btn-text-logging-out { + display: inline; +} + +/* Simple spinner on the right side of the logout button */ +.logout-button.is-logging-out::after { + content: ""; + position: absolute; + right: 8px; + top: 50%; + width: 14px; + height: 14px; + margin-top: -7px; + border-radius: 50%; + border: 2px solid currentColor; + border-top-color: transparent; + animation: cashtab-spin 0.8s linear infinite; +} + +/* Spinner animation */ +@keyframes cashtab-spin { + to { + transform: rotate(360deg); + } } /* Prevent header from overlapping content */ @@ -95,4 +134,88 @@ body { .profile-button, .logout-button { margin: 4px 0; } +} + +/* --- Animated Slide Effect for Profile + Logout Buttons --- */ + +/* Base animation wrapper */ +.paybutton-animated { + position: relative; + overflow: hidden; + z-index: 0; + transition: color 0.25s ease; + font-weight: bold; /*make text bold for better visibility*/ +} + +/* Text wrapper stays above the animated layer */ +.paybutton-animated span { + position: relative; + z-index: 1; +} + +/* Animated overlay grows left to right */ +.paybutton-animated::before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 0; + height: 100%; + z-index: 0; + transition: width 0.25s ease-out; +} + +/* On hover, fill the whole button */ +.paybutton-animated:hover::before { + width: 100%; +} + +/* --- Profile button animated variant --- */ +.profile-button.paybutton-animated { + border: 2px solid var(--profile-button-bg-color); + color: var(--profile-button-text-color); +} + +.profile-button.paybutton-animated::before { + background-color: #808080; + opacity: 0.3; +} + +/* --- Logout button animated variant --- */ +.logout-button.paybutton-animated { + border: 2px solid var(--logout-button-bg-color); + color: var(--logout-button-text-color, #fff); +} + +.logout-button.paybutton-animated::before { + background-color: #808080; + opacity: 0.3; +} + +/* --- Profile and Logout Button SVG Icon Style --- */ +.paybutton-animated .btn-icon { + display: inline-flex; + align-items: center; + justify-content: center; + margin-right: 6px; + width: 16px; + height: 16px; +} + +.paybutton-animated .btn-icon svg { + width: 100%; + height: 100%; + fill: currentColor; /* inherits text color */ +} + +/* Ensure text stays above animation layer */ +.paybutton-animated .btn-text { + position: relative; + z-index: 1; +} + +/* Icon also stays above animation layer */ +.paybutton-animated .btn-icon { + position: relative; + z-index: 1; } \ No newline at end of file diff --git a/assets/icons/logout.svg b/assets/icons/logout.svg new file mode 100644 index 0000000..6acb19d --- /dev/null +++ b/assets/icons/logout.svg @@ -0,0 +1,2 @@ + + diff --git a/assets/icons/profile.svg b/assets/icons/profile.svg new file mode 100644 index 0000000..03626d9 --- /dev/null +++ b/assets/icons/profile.svg @@ -0,0 +1 @@ + \ 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 7779ba1..55c9782 100644 --- a/assets/js/paybutton-paywall-cashtab-login.js +++ b/assets/js/paybutton-paywall-cashtab-login.js @@ -29,18 +29,31 @@ function handleLogin(address, txHash, loginToken) { /** * Handle user logout. */ -function handleLogout() { +function handleLogout(logoutButton) { + if (logoutButton) { + // Disable the button and mark as logging out + logoutButton.disabled = true; + logoutButton.classList.add('is-logging-out'); + } + jQuery.post( PaywallAjax.ajaxUrl, { action: 'paybutton_logout', security: PaywallAjax.nonce - }, - function() { - isLoggedIn = false; - location.reload(); } - ); + ) + .done(function () { + isLoggedIn = false; + location.reload(); + }) + .fail(function () { + if (logoutButton) { + logoutButton.disabled = false; + logoutButton.classList.remove('is-logging-out'); + } + alert('Logout failed. Please try again.'); + }); } /** diff --git a/templates/public/sticky-header.php b/templates/public/sticky-header.php index c6f2c52..1eaa57c 100644 --- a/templates/public/sticky-header.php +++ b/templates/public/sticky-header.php @@ -15,8 +15,28 @@
- - + +
\ No newline at end of file From 29095dba701533a06c16e34fdd43d79a34207cdf Mon Sep 17 00:00:00 2001 From: xecdev Date: Thu, 27 Nov 2025 13:20:01 +0430 Subject: [PATCH 2/4] Consolidate redundant CSS rule --- assets/css/sticky-header.css | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/assets/css/sticky-header.css b/assets/css/sticky-header.css index a8c635e..c010792 100644 --- a/assets/css/sticky-header.css +++ b/assets/css/sticky-header.css @@ -200,6 +200,8 @@ body { margin-right: 6px; width: 16px; height: 16px; + position: relative; + z-index: 1; } .paybutton-animated .btn-icon svg { @@ -212,10 +214,4 @@ body { .paybutton-animated .btn-text { position: relative; z-index: 1; -} - -/* Icon also stays above animation layer */ -.paybutton-animated .btn-icon { - position: relative; - z-index: 1; } \ No newline at end of file From df10d92fb73cd9dae9d98bd35c0d9142c3ceb05a Mon Sep 17 00:00:00 2001 From: xecdev Date: Thu, 27 Nov 2025 13:56:51 +0430 Subject: [PATCH 3/4] Safely inline an SVG icon using wp_kses --- paybutton.php | 63 ++++++++++++++++++++++++++++++ templates/public/sticky-header.php | 12 +----- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/paybutton.php b/paybutton.php index 0c8b619..2bed7b8 100644 --- a/paybutton.php +++ b/paybutton.php @@ -71,3 +71,66 @@ } } }); + +//Helper Functions + +/** + * Safely inline an SVG icon from the plugin's assets/icons directory. + * + * @param string $filename SVG filename without extension. + * @return string Sanitized inline SVG or empty string. +*/ +function paybutton_inline_svg( $filename ) { + + $file = PAYBUTTON_PLUGIN_DIR . "assets/icons/{$filename}.svg"; + + if ( ! file_exists( $file ) ) { + return ''; + } + + $svg = file_get_contents( $file ); + + // Whitelist for SVG elements used in plugin icons/logos +$allowed_svg = [ + 'svg' => [ + 'xmlns' => true, + 'xmlns:xlink' => true, + 'viewbox' => true, + 'width' => true, + 'height' => true, + 'id' => true, + 'data-name' => true, + 'enable-background' => true, + 'class' => true, + 'fill' => true, + 'stroke' => true, + 'stroke-width' => true, + ], + 'g' => [ + 'id' => true, + 'class' => true, + 'fill' => true, + 'stroke' => true, + 'stroke-width' => true, + 'stroke-linecap' => true, + 'stroke-linejoin' => true, + ], + 'path' => [ + 'id' => true, + 'class' => true, + 'd' => true, + 'fill' => true, + 'stroke' => true, + 'stroke-width' => true, + 'stroke-linecap' => true, + 'stroke-linejoin' => true, + 'opacity' => true, + 'transform' => true, + ], + 'title' => [ + 'id' => true, + ], + ]; + + return wp_kses( $svg, $allowed_svg ); +} \ No newline at end of file diff --git a/templates/public/sticky-header.php b/templates/public/sticky-header.php index 1eaa57c..b4fdfb1 100644 --- a/templates/public/sticky-header.php +++ b/templates/public/sticky-header.php @@ -17,20 +17,12 @@
+ Profile