From 38dcf8e986c9d9605ee4bf9abbf21be004b44232 Mon Sep 17 00:00:00 2001 From: xecdev Date: Sun, 16 Mar 2025 17:27:23 +0430 Subject: [PATCH 1/3] Implement Native PayButton Generator --- assets/css/paybutton-admin.css | 112 ++++++++++++++++++++ assets/js/paybutton-generator.js | 118 +++++++++++++++++++++ includes/class-paybutton-admin.php | 38 ++++++- includes/class-paybutton-public.php | 31 ++++++ templates/admin/dashboard.php | 6 +- templates/admin/paybutton-generator.php | 134 ++++++++++++++++++++++++ 6 files changed, 435 insertions(+), 4 deletions(-) create mode 100644 assets/js/paybutton-generator.js create mode 100644 templates/admin/paybutton-generator.php diff --git a/assets/css/paybutton-admin.css b/assets/css/paybutton-admin.css index 9211426..e2380e5 100644 --- a/assets/css/paybutton-admin.css +++ b/assets/css/paybutton-admin.css @@ -59,6 +59,118 @@ border: none; } +/* ------------------------------ + Button Generator Page Styles +------------------------------ */ +.pb-generator-container { + display: flex; + gap: 2rem; + } + +.pb-generator-form { + flex: 1; + max-width: 400px; +} + +.pb-generator-form label { + font-weight: bold; + display: block; + margin-bottom: 0.5rem; +} + +.pb-generator-input { + width: 100%; + box-sizing: border-box; + padding: 0.5rem; + margin-bottom: 1rem; +} + +.pb-generator-preview { + flex: 1; +} + +#pbGenPreview { + border: 1px solid #ccc; + padding: 1rem; + text-align: center; + display: flex; + justify-content: center; + align-items: center; + min-height: 80px; +} + +#pbGenShortcode { + width: 100%; + box-sizing: border-box; +} + +/* Grouped Colors */ +.pb-generator-colors { + display: flex; + gap: 1rem; + align-items: center; + margin-top: 1rem; +} + +.pb-generator-colors .pb-generator-color { + display: flex; + flex-direction: column; + align-items: center; +} + +.pb-generator-widget { + display: inline-flex; + align-items: center; + gap: 0.5rem; + margin-top: 1rem; +} + +.pb-generator-widget input[type="checkbox"] { + margin-left: 0.7rem; +} + +/* Simple custom tooltip styling */ +.pbTooltip { + position: absolute; + cursor: help; + margin-left: 0.3rem; +} + +.pbTooltip::before { + padding: 5px 3px; +} + +.pbTooltip::after { + content: ''; + left: 100%; + top: 50%; + transform: translateY(-50%); + opacity: 0; + transition: opacity 0.2s ease-in-out; + pointer-events: none; + z-index: 999999; /* ensure it stays above WP admin menu */ + max-width: 300px; + background: #0074C2; + color: #fff; + padding: 5px 2px; + border-radius: 3px; + white-space: normal; + overflow-wrap: break-word; + text-align: center; +} + +.pbTooltip:hover::after { + content: attr(data-tooltip); + opacity: 1; + padding: 5px 10px; +} + +.shortcode-note { + font-size: 0.9em; + color: #555; + margin-top: 0.5rem; + font-style: italic; +} /* ------------------------------ Paywall Settings page styles ------------------------------ */ diff --git a/assets/js/paybutton-generator.js b/assets/js/paybutton-generator.js new file mode 100644 index 0000000..14ade34 --- /dev/null +++ b/assets/js/paybutton-generator.js @@ -0,0 +1,118 @@ +/* File: assets/js/paybutton-generator.js +*/ +(function($) { + "use strict"; + + /* ========================================================================== + BUTTON GENERATOR LOGIC + ========================================================================== */ + if ($('#pbGenTo').length) { + function updateGenerator() { + // Define default values for required options + const defaults = { + to:"", + text: "🧋 Buy me a coffee", + currency: "XEC", + animation: "slide", + successText: "Thank You", + primary: "#0074C2", + secondary: "#ffffff", + tertiary: "#231F20" + }; + + const toVal = $('#pbGenTo').val().trim() || defaults.to; + const amountVal = $('#pbGenAmount').val().trim(); + const currencyVal = $('#pbGenCurrency').val().trim() || defaults.currency; + const textVal = $('#pbGenText').val().trim() || defaults.text; + const hoverVal = $('#pbGenHover').val().trim(); + const successVal = $('#pbGenSuccessText').val().trim() || defaults.successText; + const animationVal = $('#pbGenAnimation').val().trim() || defaults.animation; + const goalVal = $('#pbGenGoal').val().trim(); + const primaryVal = $('#pbGenPrimary').val().trim() || defaults.primary; + const secondaryVal = $('#pbGenSecondary').val().trim() || defaults.secondary; + const tertiaryVal = $('#pbGenTertiary').val().trim() || defaults.tertiary; + const widgetChecked = $('#pbGenWidget').is(':checked'); + + // Build PB's config object + let config = {}; + if(toVal !== '') { config.to = toVal; } + if(amountVal !== '') { config.amount = parseFloat(amountVal); } + config.currency = currencyVal; + if(textVal !== '') { config.text = textVal; } + if(hoverVal !== '') { config.hoverText = hoverVal; } + config.successText = successVal; + config.animation = animationVal; + if(goalVal !== '') { config.goalAmount = parseFloat(goalVal); } + config.theme = { + palette: { + primary: primaryVal, + secondary: secondaryVal, + tertiary: tertiaryVal + } + }; + config.widget = widgetChecked; + + // Get the preview container + const previewContainer = document.getElementById('pbGenPreview'); + if (previewContainer) { + // Remove all child nodes + while (previewContainer.firstChild) { + previewContainer.removeChild(previewContainer.firstChild); + } + // Create a new inner container for rendering the button + const innerContainer = document.createElement('div'); + previewContainer.appendChild(innerContainer); + + // Render the button using the local paybutton.js + if (typeof PayButton !== 'undefined') { + if (widgetChecked) { + PayButton.renderWidget(innerContainer, config); + } else { + PayButton.render(innerContainer, config); + } + } else { + previewContainer.innerHTML = '

Error: paybutton.js not loaded.

'; + } + } + + // Generate shortcode with config attribute + const shortcode = `[paybutton config='${JSON.stringify(config)}'][/paybutton]`; + $('#pbGenShortcode').val(shortcode); + } + + // Bind updates on input and change events + $('#pbGenTo, #pbGenAmount, #pbGenCurrency, #pbGenText, #pbGenAnimation, #pbGenGoal, #pbGenHover, #pbGenPrimary, #pbGenSecondary, #pbGenTertiary, #pbGenSuccessText, #pbGenWidget') + .on('input change', updateGenerator); + + // Initialize the generator on page load + updateGenerator(); + } + + /* ========================================================================== + SHORTCODE RENDERING LOGIC ON THE FRONT-END + ========================================================================== */ + function renderPayButtonShortcodes() { + const containers = document.querySelectorAll('.paybutton-shortcode-container'); + containers.forEach(container => { + const configStr = container.getAttribute('data-config'); + try { + const config = JSON.parse(configStr); + if (typeof PayButton !== 'undefined') { + if (config.widget) { + PayButton.renderWidget(container, config); + } else { + PayButton.render(container, config); + } + } else { + container.innerHTML = '

Error: paybutton.js not loaded.

'; + } + } catch (err) { + console.error('Invalid PayButton config JSON:', err); + } + }); + } + + // Run shortcode rendering on DOMContentLoaded + document.addEventListener('DOMContentLoaded', renderPayButtonShortcodes); + +})(jQuery); \ No newline at end of file diff --git a/includes/class-paybutton-admin.php b/includes/class-paybutton-admin.php index 5025627..b1cdb33 100644 --- a/includes/class-paybutton-admin.php +++ b/includes/class-paybutton-admin.php @@ -33,6 +33,15 @@ public function add_admin_menus() { 100 ); + add_submenu_page( + 'paybutton', + 'Button Generator', + 'Button Generator', + 'manage_options', + 'paybutton-generator', + array( $this, 'button_generator_page' ) + ); + add_submenu_page( 'paybutton', 'Paywall Settings', @@ -110,6 +119,26 @@ public function enqueue_admin_scripts( $hook_suffix ) { true ); } + + // Only load the generator JS on the PayButton Generator page + if ( $hook_suffix === 'paybutton_page_paybutton-generator' ) { + + wp_enqueue_script( + 'paybutton-core', + PAYBUTTON_PLUGIN_URL . 'assets/js/paybutton.js', + array(), + '1.0', + false + ); + + wp_enqueue_script( + 'paybutton-generator', + PAYBUTTON_PLUGIN_URL . 'assets/js/paybutton-generator.js', + array('jquery'), + '1.0', + true + ); + } } /** @@ -134,12 +163,19 @@ private function load_admin_template( $template_name, $args = array() ) { */ public function dashboard_page() { $args = array( - 'generate_button_url' => 'https://paybutton.org/#button-generator', + 'generate_button_url' => esc_url( admin_url( 'admin.php?page=paybutton-generator' ) ), 'paywall_settings_url' => esc_url( admin_url( 'admin.php?page=paybutton-paywall' ) ) ); $this->load_admin_template( 'dashboard', $args ); } + public function button_generator_page() { + if ( ! current_user_can( 'manage_options' ) ) { + return; + } + $this->load_admin_template( 'paybutton-generator' ); + } + /** * Output the Paywall Settings page. */ diff --git a/includes/class-paybutton-public.php b/includes/class-paybutton-public.php index b7212da..8b8f4ed 100644 --- a/includes/class-paybutton-public.php +++ b/includes/class-paybutton-public.php @@ -30,6 +30,7 @@ public function __construct() { add_shortcode( 'paybutton_profile', array( $this, 'profile_shortcode' ) ); add_filter( 'comments_open', array( $this, 'filter_comments_open' ), 999, 2 ); add_action( 'pre_get_comments', array( $this, 'filter_comments_query' ), 999 ); + add_shortcode( 'paybutton', [ $this, 'paybutton_generator_shortcode' ] ); } /** @@ -85,6 +86,15 @@ public function enqueue_public_assets() { true ); + // Load a new JS file to render the [paybutton] shortcodes + wp_enqueue_script( + 'paybutton-generator', + PAYBUTTON_PLUGIN_URL . 'assets/js/paybutton-generator.js', + array('paybutton-core'), + '1.0', + true + ); + /** * Localizes the 'paybutton-cashtab-login' script with variables needed for AJAX interactions. * @@ -108,6 +118,27 @@ public function enqueue_public_assets() { ) ); } + /** + * Renders the [paybutton][/paybutton] shortcode + */ + public function paybutton_generator_shortcode( $atts, $content = null ) { + // Provide a default empty JSON if not supplied + $atts = shortcode_atts( [ 'config' => '{}' ], $atts ); + $decoded = json_decode( $atts['config'], true ); + if ( ! is_array( $decoded ) ) { + $decoded = []; + } + + // Safely encode the config for a data attribute + $encodedConfig = esc_attr( wp_json_encode( $decoded ) ); + + ob_start(); + ?> +
+
- - Add Simple PayButton + + PayButton Generator
- + Paywall Settings
diff --git a/templates/admin/paybutton-generator.php b/templates/admin/paybutton-generator.php new file mode 100644 index 0000000..a6fb38f --- /dev/null +++ b/templates/admin/paybutton-generator.php @@ -0,0 +1,134 @@ + + + +
+

Button Generator

+

Build your custom PayButton and begin accepting payments!

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ +
+

PREVIEW

+
+ Enter an address +
+

SHORTCODE

+

Copy and paste the shortcode generated below wherever you want the PayButton to appear on your site.

+ +
+
+
\ No newline at end of file From 61f55e2a1bdbc2dddc2df33f3e4e787203548bcb Mon Sep 17 00:00:00 2001 From: xecdev Date: Mon, 17 Mar 2025 15:33:07 +0430 Subject: [PATCH 2/3] added support for BCH, improved address validation and shortcode to clipboard feature --- assets/css/paybutton-admin.css | 77 +++++++++++- assets/js/addressValidator.bundle.js | 8 +- assets/js/paybutton-generator.js | 156 +++++++++++++++++++++--- includes/class-paybutton-admin.php | 15 ++- templates/admin/paybutton-generator.php | 14 ++- 5 files changed, 241 insertions(+), 29 deletions(-) diff --git a/assets/css/paybutton-admin.css b/assets/css/paybutton-admin.css index e2380e5..d5deeac 100644 --- a/assets/css/paybutton-admin.css +++ b/assets/css/paybutton-admin.css @@ -89,19 +89,43 @@ flex: 1; } -#pbGenPreview { - border: 1px solid #ccc; +.pb-generator-preview #pbGenPreview { + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; padding: 1rem; - text-align: center; + min-height: 80px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); display: flex; justify-content: center; align-items: center; - min-height: 80px; + font-size: 1rem; + color: #333; + transition: box-shadow 0.3s ease, border-color 0.3s ease; +} + +.pb-generator-preview #pbGenPreview:hover { + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); + border-color: #0074C2; } #pbGenShortcode { + font-family: monospace; + font-size: 0.8rem; + line-height: 1.5; + color: #333; + background-color: #f9f9f9; + border: 1px solid #ddd; + border-radius: 4px; + padding: 1rem; + box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); width: 100%; - box-sizing: border-box; + resize: vertical; + word-break: break-all; +} + +#pbGenToValidationResult{ + margin-top: 0px; } /* Grouped Colors */ @@ -197,4 +221,47 @@ table.widefat.fixed.striped td { ------------------------------ */ .pb-paragraph-margin-top { margin-top: 1rem; +} + +/* ------------------------------ + Utility - Clipboard +------------------------------ */ +.shortcode-container { + position: relative; + margin-bottom: 1rem; +} + +.shortcode-container textarea { + width: 100%; + box-sizing: border-box; +} + +/* The overlay covers the textarea but is hidden by default */ +.copy-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(66, 123, 236, 0.7); + display: flex; + align-items: center; + justify-content: center; + font-size: 1rem; + color: #f6f7f7; + cursor: pointer; + transition: opacity 0.3s ease; + opacity: 0; + pointer-events: none; +} + +/* Show the overlay when hovering over the container */ +.shortcode-container:hover .copy-overlay { + opacity: 1; + pointer-events: auto; +} + +.copy-overlay .overlay-text { + text-align: center; + font-weight:bold; } \ No newline at end of file diff --git a/assets/js/addressValidator.bundle.js b/assets/js/addressValidator.bundle.js index 69ad8d4..3e67f71 100644 --- a/assets/js/addressValidator.bundle.js +++ b/assets/js/addressValidator.bundle.js @@ -749,7 +749,7 @@ var cashaddrExports = requireCashaddr(); - // src/addressValidator.js + window.cashaddrExports = cashaddrExports; document.addEventListener('DOMContentLoaded', () => { // Find the wallet address input field by its ID. @@ -771,8 +771,8 @@ addressInput.addEventListener('input', () => { const address = addressInput.value.trim(); if (address === "") { - resultSpan.textContent = '❌ Invalid address'; - resultSpan.style.color = 'red'; + resultSpan.textContent = ''; + resultSpan.style.color = ''; if (saveButton) saveButton.disabled = true; return; } @@ -793,4 +793,4 @@ addressInput.dispatchEvent(new Event('input')); }); -})(); +})(); \ No newline at end of file diff --git a/assets/js/paybutton-generator.js b/assets/js/paybutton-generator.js index 14ade34..0f8ce2b 100644 --- a/assets/js/paybutton-generator.js +++ b/assets/js/paybutton-generator.js @@ -3,9 +3,48 @@ (function($) { "use strict"; + /* ========================================================================== + ADMIN WALLET ADDRESS VALIDATION + ========================================================================== + */ + if ($('#pbGenTo').length) { + + const $toField = $('#pbGenTo'); + let $validationMsg; + + if (!$('#pbGenToValidationResult').length) { + $toField.after('

'); + } + $validationMsg = $('#pbGenToValidationResult'); + + $toField.on('input', function() { + const address = $toField.val().trim(); + + if (!address) { + $validationMsg.text('').css('color', ''); + return; + } + + const valid = window.cashaddrExports && window.cashaddrExports.isValidCashAddress(address); + if (typeof window.cashaddrExports === 'undefined') { + console.error('[PayButton] addressValidator is missing or not loaded!'); + } + + if (valid) { + $validationMsg.text('✅ Valid address').css('color', 'green'); + } else { + $validationMsg.text('❌ Invalid address').css('color', 'red'); + } + }); + + // Trigger input event on page load to validate pre-set value (from Paywall Settings). + $toField.trigger('input'); + } + /* ========================================================================== BUTTON GENERATOR LOGIC - ========================================================================== */ + ========================================================================== + */ if ($('#pbGenTo').length) { function updateGenerator() { // Define default values for required options @@ -20,17 +59,72 @@ tertiary: "#231F20" }; - const toVal = $('#pbGenTo').val().trim() || defaults.to; - const amountVal = $('#pbGenAmount').val().trim(); - const currencyVal = $('#pbGenCurrency').val().trim() || defaults.currency; - const textVal = $('#pbGenText').val().trim() || defaults.text; - const hoverVal = $('#pbGenHover').val().trim(); - const successVal = $('#pbGenSuccessText').val().trim() || defaults.successText; - const animationVal = $('#pbGenAnimation').val().trim() || defaults.animation; - const goalVal = $('#pbGenGoal').val().trim(); - const primaryVal = $('#pbGenPrimary').val().trim() || defaults.primary; - const secondaryVal = $('#pbGenSecondary').val().trim() || defaults.secondary; - const tertiaryVal = $('#pbGenTertiary').val().trim() || defaults.tertiary; + const toVal = ($('#pbGenTo').val() || "").trim() || defaults.to; + + // If the TO field is empty, reset the currency dropdown to show all options. + if (!toVal) { + $('#pbGenCurrency').html(''); + } + + // If the wallet address is invalid, clear preview and shortcode and exit. + if (!toVal || !window.cashaddrExports.isValidCashAddress(toVal)) { + const previewContainer = document.getElementById('pbGenPreview'); + if (previewContainer) { + previewContainer.innerHTML = 'Please enter a valid wallet address to preview'; + } + $('#pbGenShortcode').val(''); + $('.pb-generator-preview').find('h3:contains("SHORTCODE"), p.shortcode-note, #pbGenShortcode').hide(); + $('.shortcode-container .copy-btn').hide(); + return; + } else { + $('.pb-generator-preview').find('h3:contains("SHORTCODE"), p.shortcode-note, #pbGenShortcode').show(); + $('.shortcode-container .copy-btn').show(); + } + + // Use the validator lib to determine the address type and adjust primary color and currency accordingly. + try { + const decoded = window.cashaddrExports.decodeCashAddress(toVal); + const $currency = $('#pbGenCurrency'); + const currentCurrency = $currency.val(); + const prefix = decoded.prefix ? decoded.prefix.toLowerCase() : ""; + if (prefix === 'bitcoincash') { + $('#pbGenPrimary').val("#4BC846"); + // Remove XEC option from crypto choices. + $currency.find('option[value="XEC"]').remove(); + if ($currency.find('option[value="BCH"]').length === 0) { + $currency.append(''); + } + + } else if (prefix === 'ecash') { + $('#pbGenPrimary').val("#0074C2"); + // Remove BCH option from crypto choices. + $currency.find('option[value="BCH"]').remove(); + if ($currency.find('option[value="XEC"]').length === 0) { + $currency.append(''); + } + if (!currentCurrency || currentCurrency === "BCH") { + $currency.val("XEC"); + } + } else { + $('#pbGenPrimary').val(defaults.primary); + $currency.val(defaults.currency); + } + } catch (e) { + // In case decoding fails, revert to default values. + $('#pbGenPrimary').val(defaults.primary); + $('#pbGenCurrency').val(defaults.currency); + } + + const amountVal = ($('#pbGenAmount').val() || "").trim(); + const currencyVal = ($('#pbGenCurrency').val() || "").trim() || defaults.currency; + const textVal = ($('#pbGenText').val() || "").trim() || defaults.text; + const hoverVal = ($('#pbGenHover').val() || "").trim(); + const successVal = ($('#pbGenSuccessText').val() || "").trim() || defaults.successText; + const animationVal = ($('#pbGenAnimation').val() || "").trim() || defaults.animation; + const goalVal = ($('#pbGenGoal').val() || "").trim(); + const primaryVal = ($('#pbGenPrimary').val() || "").trim() || defaults.primary; + const secondaryVal = ($('#pbGenSecondary').val() || "").trim() || defaults.secondary; + const tertiaryVal = ($('#pbGenTertiary').val() || "").trim() || defaults.tertiary; const widgetChecked = $('#pbGenWidget').is(':checked'); // Build PB's config object @@ -90,7 +184,8 @@ /* ========================================================================== SHORTCODE RENDERING LOGIC ON THE FRONT-END - ========================================================================== */ + ========================================================================== + */ function renderPayButtonShortcodes() { const containers = document.querySelectorAll('.paybutton-shortcode-container'); containers.forEach(container => { @@ -115,4 +210,37 @@ // Run shortcode rendering on DOMContentLoaded document.addEventListener('DOMContentLoaded', renderPayButtonShortcodes); -})(jQuery); \ No newline at end of file +})(jQuery); + +/* ========================================================================== + CLIPBOARD FUNCTIONALITY + ========================================================================== +*/ +document.addEventListener('DOMContentLoaded', function() { + const copyOverlay = document.querySelector('.copy-overlay'); + if (copyOverlay) { + copyOverlay.addEventListener('click', function() { + const targetSelector = copyOverlay.getAttribute('data-target'); + const targetElement = document.getElementById(targetSelector.replace('#', '')); + if (targetElement && navigator.clipboard) { + navigator.clipboard.writeText(targetElement.value) + .then(function() { + const overlayText = copyOverlay.querySelector('.overlay-text'); + if (overlayText) { + overlayText.textContent = 'Copied to clipboard!'; + } + copyOverlay.classList.add('copied'); + setTimeout(function() { + if (overlayText) { + overlayText.textContent = 'Click to copy!'; + } + copyOverlay.classList.remove('copied'); + }, 2000); + }) + .catch(function(err) { + console.error('Failed to copy text: ', err); + }); + } + }); + } +}); \ No newline at end of file diff --git a/includes/class-paybutton-admin.php b/includes/class-paybutton-admin.php index b1cdb33..174e111 100644 --- a/includes/class-paybutton-admin.php +++ b/includes/class-paybutton-admin.php @@ -123,18 +123,27 @@ public function enqueue_admin_scripts( $hook_suffix ) { // Only load the generator JS on the PayButton Generator page if ( $hook_suffix === 'paybutton_page_paybutton-generator' ) { + // Enqueue the bundled address validator script + wp_enqueue_script( + 'address-validator', + PAYBUTTON_PLUGIN_URL . 'assets/js/addressValidator.bundle.js', + array(), + '2.0.0', + true + ); + wp_enqueue_script( 'paybutton-core', PAYBUTTON_PLUGIN_URL . 'assets/js/paybutton.js', - array(), + array('address-validator'), '1.0', - false + true ); wp_enqueue_script( 'paybutton-generator', PAYBUTTON_PLUGIN_URL . 'assets/js/paybutton-generator.js', - array('jquery'), + array('jquery','paybutton-core','address-validator'), '1.0', true ); diff --git a/templates/admin/paybutton-generator.php b/templates/admin/paybutton-generator.php index a6fb38f..033c267 100644 --- a/templates/admin/paybutton-generator.php +++ b/templates/admin/paybutton-generator.php @@ -18,7 +18,7 @@ @@ -38,6 +38,7 @@ class="pb-generator-input" @@ -127,8 +128,15 @@ class="pb-generator-input" Enter an address

SHORTCODE

-

Copy and paste the shortcode generated below wherever you want the PayButton to appear on your site.

- +

+ Click the shortcode below to copy it, then paste it anywhere you'd like the PayButton to appear on your site. +

+
+ +
+ Click to copy! +
+
\ No newline at end of file From 22604a7e54301f3d3d6ca2dac9a0264e9d59c51d Mon Sep 17 00:00:00 2001 From: xecdev Date: Tue, 18 Mar 2025 13:13:23 +0430 Subject: [PATCH 3/3] Fixed primary color value not changing --- assets/js/paybutton-generator.js | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/assets/js/paybutton-generator.js b/assets/js/paybutton-generator.js index 0f8ce2b..3e78009 100644 --- a/assets/js/paybutton-generator.js +++ b/assets/js/paybutton-generator.js @@ -45,6 +45,9 @@ BUTTON GENERATOR LOGIC ========================================================================== */ + + let previousAddress = ''; + if ($('#pbGenTo').length) { function updateGenerator() { // Define default values for required options @@ -81,22 +84,33 @@ $('.shortcode-container .copy-btn').show(); } - // Use the validator lib to determine the address type and adjust primary color and currency accordingly. + const addressChanged = toVal !== previousAddress; + if (addressChanged) { + previousAddress = toVal; + } + + // Set primary color based on address type only if the address has changed, to preserve user modifications try { const decoded = window.cashaddrExports.decodeCashAddress(toVal); const $currency = $('#pbGenCurrency'); const currentCurrency = $currency.val(); const prefix = decoded.prefix ? decoded.prefix.toLowerCase() : ""; + if (addressChanged) { + if (prefix === 'bitcoincash') { + $('#pbGenPrimary').val("#4BC846"); + } else if (prefix === 'ecash') { + $('#pbGenPrimary').val("#0074C2"); + } else { + $('#pbGenPrimary').val(defaults.primary); + } + } if (prefix === 'bitcoincash') { - $('#pbGenPrimary').val("#4BC846"); // Remove XEC option from crypto choices. $currency.find('option[value="XEC"]').remove(); if ($currency.find('option[value="BCH"]').length === 0) { $currency.append(''); } - } else if (prefix === 'ecash') { - $('#pbGenPrimary').val("#0074C2"); // Remove BCH option from crypto choices. $currency.find('option[value="BCH"]').remove(); if ($currency.find('option[value="XEC"]').length === 0) { @@ -106,12 +120,13 @@ $currency.val("XEC"); } } else { - $('#pbGenPrimary').val(defaults.primary); $currency.val(defaults.currency); } } catch (e) { // In case decoding fails, revert to default values. - $('#pbGenPrimary').val(defaults.primary); + if (addressChanged) { + $('#pbGenPrimary').val(defaults.primary); + } $('#pbGenCurrency').val(defaults.currency); } @@ -235,7 +250,7 @@ document.addEventListener('DOMContentLoaded', function() { overlayText.textContent = 'Click to copy!'; } copyOverlay.classList.remove('copied'); - }, 2000); + }, 1000); }) .catch(function(err) { console.error('Failed to copy text: ', err);