Separate message rendering, fix some message rendering issues

This commit is contained in:
Alex P 2023-09-11 10:57:23 +03:00
parent dbe4e82707
commit e5513d51de
No known key found for this signature in database
GPG key ID: 54487A734A204D71
6 changed files with 128 additions and 74 deletions

View file

@ -19,6 +19,7 @@ import FreeTrialHandler from "./modules/ActionHandler/FreeTrialHandler";
import FormSaver from './modules/Helper/FormSaver'; import FormSaver from './modules/Helper/FormSaver';
import FormValidator from "./modules/Helper/FormValidator"; import FormValidator from "./modules/Helper/FormValidator";
import {loadPaypalScript} from "./modules/Helper/ScriptLoading"; import {loadPaypalScript} from "./modules/Helper/ScriptLoading";
import MessagesBootstrap from "./modules/ContextBootstrap/MessagesBootstap";
// TODO: could be a good idea to have a separate spinner for each gateway, // TODO: could be a good idea to have a separate spinner for each gateway,
// but I think we care mainly about the script loading, so one spinner should be enough. // but I think we care mainly about the script loading, so one spinner should be enough.
@ -158,7 +159,6 @@ const bootstrap = () => {
const singleProductBootstrap = new SingleProductBootstap( const singleProductBootstrap = new SingleProductBootstap(
PayPalCommerceGateway, PayPalCommerceGateway,
renderer, renderer,
messageRenderer,
errorHandler, errorHandler,
); );
@ -169,7 +169,6 @@ const bootstrap = () => {
const cartBootstrap = new CartBootstrap( const cartBootstrap = new CartBootstrap(
PayPalCommerceGateway, PayPalCommerceGateway,
renderer, renderer,
messageRenderer,
errorHandler, errorHandler,
); );
@ -180,7 +179,6 @@ const bootstrap = () => {
const checkoutBootstap = new CheckoutBootstap( const checkoutBootstap = new CheckoutBootstap(
PayPalCommerceGateway, PayPalCommerceGateway,
renderer, renderer,
messageRenderer,
spinner, spinner,
errorHandler, errorHandler,
); );
@ -199,6 +197,11 @@ const bootstrap = () => {
payNowBootstrap.init(); payNowBootstrap.init();
} }
const messagesBootstrap = new MessagesBootstrap(
PayPalCommerceGateway,
messageRenderer,
);
messagesBootstrap.init();
}; };
const hasMessages = () => { const hasMessages = () => {

View file

@ -2,12 +2,10 @@ import CartActionHandler from '../ActionHandler/CartActionHandler';
import BootstrapHelper from "../Helper/BootstrapHelper"; import BootstrapHelper from "../Helper/BootstrapHelper";
class CartBootstrap { class CartBootstrap {
constructor(gateway, renderer, messages, errorHandler) { constructor(gateway, renderer, errorHandler) {
this.gateway = gateway; this.gateway = gateway;
this.renderer = renderer; this.renderer = renderer;
this.messages = messages;
this.errorHandler = errorHandler; this.errorHandler = errorHandler;
this.lastAmount = this.gateway.messages.amount;
this.renderer.onButtonsInit(this.gateway.button.wrapper, () => { this.renderer.onButtonsInit(this.gateway.button.wrapper, () => {
this.handleButtonStatus(); this.handleButtonStatus();
@ -15,16 +13,16 @@ class CartBootstrap {
} }
init() { init() {
if (!this.shouldRender()) { if (this.shouldRender()) {
return;
}
this.render();
this.handleButtonStatus();
jQuery(document.body).on('updated_cart_totals updated_checkout', () => {
this.render(); this.render();
this.handleButtonStatus(); this.handleButtonStatus();
}
jQuery(document.body).on('updated_cart_totals updated_checkout', () => {
if (this.shouldRender()) {
this.render();
this.handleButtonStatus();
}
fetch( fetch(
this.gateway.ajax.cart_script_params.endpoint, this.gateway.ajax.cart_script_params.endpoint,
@ -49,16 +47,19 @@ class CartBootstrap {
} }
// handle button status // handle button status
if (result.data.button || result.data.messages) { const newData = {};
this.gateway.button = result.data.button; if (result.data.button) {
this.gateway.messages = result.data.messages; newData.button = result.data.button;
}
if (result.data.messages) {
newData.messages = result.data.messages;
}
if (newData) {
BootstrapHelper.updateScriptData(this, newData);
this.handleButtonStatus(); this.handleButtonStatus();
} }
if (this.lastAmount !== result.data.amount) { jQuery(document.body).trigger('ppcp_cart_total_updated', [result.data.amount]);
this.lastAmount = result.data.amount;
this.messages.renderWithAmount(this.lastAmount);
}
}); });
}); });
} }
@ -76,6 +77,10 @@ class CartBootstrap {
} }
render() { render() {
if (!this.shouldRender()) {
return;
}
const actionHandler = new CartActionHandler( const actionHandler = new CartActionHandler(
PayPalCommerceGateway, PayPalCommerceGateway,
this.errorHandler, this.errorHandler,
@ -99,7 +104,7 @@ class CartBootstrap {
actionHandler.configuration() actionHandler.configuration()
); );
this.messages.renderWithAmount(this.lastAmount); jQuery(document.body).trigger('ppcp_cart_rendered');
} }
} }

View file

@ -8,13 +8,11 @@ import {
import BootstrapHelper from "../Helper/BootstrapHelper"; import BootstrapHelper from "../Helper/BootstrapHelper";
class CheckoutBootstap { class CheckoutBootstap {
constructor(gateway, renderer, messages, spinner, errorHandler) { constructor(gateway, renderer, spinner, errorHandler) {
this.gateway = gateway; this.gateway = gateway;
this.renderer = renderer; this.renderer = renderer;
this.messages = messages;
this.spinner = spinner; this.spinner = spinner;
this.errorHandler = errorHandler; this.errorHandler = errorHandler;
this.lastAmount = this.gateway.messages.amount;
this.standardOrderButtonSelector = ORDER_BUTTON_SELECTOR; this.standardOrderButtonSelector = ORDER_BUTTON_SELECTOR;
@ -37,7 +35,7 @@ class CheckoutBootstap {
this.render() this.render()
this.handleButtonStatus(); this.handleButtonStatus();
if (this.shouldRenderMessages()) { // currently we need amount only for Pay Later if (this.shouldShowMessages() && document.querySelector(this.gateway.messages.wrapper)) { // currently we need amount only for Pay Later
fetch( fetch(
this.gateway.ajax.cart_script_params.endpoint, this.gateway.ajax.cart_script_params.endpoint,
{ {
@ -51,10 +49,7 @@ class CheckoutBootstap {
return; return;
} }
if (this.lastAmount !== result.data.amount) { jQuery(document.body).trigger('ppcp_checkout_total_updated', [result.data.amount]);
this.lastAmount = result.data.amount;
this.updateUi();
}
}); });
} }
}); });
@ -69,6 +64,12 @@ class CheckoutBootstap {
}) })
}); });
jQuery(document).on('ppcp_should_show_messages', (e, data) => {
if (!this.shouldShowMessages()) {
data.result = false;
}
});
this.updateUi(); this.updateUi();
} }
@ -138,16 +139,11 @@ class CheckoutBootstap {
setVisibleByClass(this.standardOrderButtonSelector, (isPaypal && isFreeTrial && hasVaultedPaypal) || isNotOurGateway || isSavedCard, 'ppcp-hidden'); setVisibleByClass(this.standardOrderButtonSelector, (isPaypal && isFreeTrial && hasVaultedPaypal) || isNotOurGateway || isSavedCard, 'ppcp-hidden');
setVisible('.ppcp-vaulted-paypal-details', isPaypal); setVisible('.ppcp-vaulted-paypal-details', isPaypal);
setVisible(this.gateway.button.wrapper, isPaypal && !(isFreeTrial && hasVaultedPaypal)); setVisible(this.gateway.button.wrapper, isPaypal && !(isFreeTrial && hasVaultedPaypal));
setVisible(this.gateway.messages.wrapper, isPaypal && !isFreeTrial);
setVisible(this.gateway.hosted_fields.wrapper, isCard && !isSavedCard); setVisible(this.gateway.hosted_fields.wrapper, isCard && !isSavedCard);
for (const [gatewayId, wrapper] of Object.entries(paypalButtonWrappers)) { for (const [gatewayId, wrapper] of Object.entries(paypalButtonWrappers)) {
setVisible(wrapper, gatewayId === currentPaymentMethod); setVisible(wrapper, gatewayId === currentPaymentMethod);
} }
if (this.shouldRenderMessages()) {
this.messages.renderWithAmount(this.lastAmount);
}
if (isCard) { if (isCard) {
if (isSavedCard) { if (isSavedCard) {
this.disableCreditCardFields(); this.disableCreditCardFields();
@ -155,12 +151,13 @@ class CheckoutBootstap {
this.enableCreditCardFields(); this.enableCreditCardFields();
} }
} }
jQuery(document.body).trigger('ppcp_checkout_rendered');
} }
shouldRenderMessages() { shouldShowMessages() {
return getCurrentPaymentMethod() === PaymentMethods.PAYPAL return getCurrentPaymentMethod() === PaymentMethods.PAYPAL
&& !PayPalCommerceGateway.is_free_trial_cart && !PayPalCommerceGateway.is_free_trial_cart;
&& this.messages.shouldRender();
} }
disableCreditCardFields() { disableCreditCardFields() {

View file

@ -0,0 +1,55 @@
import {setVisible} from "../Helper/Hiding";
class MessagesBootstrap {
constructor(gateway, messageRenderer) {
this.gateway = gateway;
this.renderer = messageRenderer;
this.lastAmount = this.gateway.messages.amount;
}
init() {
jQuery(document.body).on('ppcp_cart_rendered ppcp_checkout_rendered', () => {
this.render();
});
jQuery(document.body).on('ppcp_script_data_changed', (e, data) => {
this.gateway = data;
this.render();
});
jQuery(document.body).on('ppcp_cart_total_updated ppcp_checkout_total_updated ppcp_product_total_updated', (e, amount) => {
if (this.lastAmount !== amount) {
this.lastAmount = amount;
this.render();
}
});
this.render();
}
shouldShow() {
if (this.gateway.messages.is_hidden === true) {
return false;
}
const eventData = {result: true}
jQuery(document.body).trigger('ppcp_should_show_messages', [eventData]);
return eventData.result;
}
shouldRender() {
return this.shouldShow() && this.renderer.shouldRender();
}
render() {
setVisible(this.gateway.messages.wrapper, this.shouldShow());
if (!this.shouldRender()) {
return;
}
this.renderer.renderWithAmount(this.lastAmount);
}
}
export default MessagesBootstrap;

View file

@ -6,12 +6,12 @@ import {loadPaypalJsScript} from "../Helper/ScriptLoading";
import {getPlanIdFromVariation} from "../Helper/Subscriptions" import {getPlanIdFromVariation} from "../Helper/Subscriptions"
import SimulateCart from "../Helper/SimulateCart"; import SimulateCart from "../Helper/SimulateCart";
import {strRemoveWord, strAddWord, throttle} from "../Helper/Utils"; import {strRemoveWord, strAddWord, throttle} from "../Helper/Utils";
import merge from "deepmerge";
class SingleProductBootstap { class SingleProductBootstap {
constructor(gateway, renderer, messages, errorHandler) { constructor(gateway, renderer, errorHandler) {
this.gateway = gateway; this.gateway = gateway;
this.renderer = renderer; this.renderer = renderer;
this.messages = messages;
this.errorHandler = errorHandler; this.errorHandler = errorHandler;
this.mutationObserver = new MutationObserver(this.handleChange.bind(this)); this.mutationObserver = new MutationObserver(this.handleChange.bind(this));
this.formSelector = 'form.cart'; this.formSelector = 'form.cart';
@ -36,7 +36,6 @@ class SingleProductBootstap {
if (!this.shouldRender()) { if (!this.shouldRender()) {
this.renderer.disableSmartButtons(this.gateway.button.wrapper); this.renderer.disableSmartButtons(this.gateway.button.wrapper);
hide(this.gateway.button.wrapper, this.formSelector); hide(this.gateway.button.wrapper, this.formSelector);
hide(this.gateway.messages.wrapper);
return; return;
} }
@ -44,7 +43,6 @@ class SingleProductBootstap {
this.renderer.enableSmartButtons(this.gateway.button.wrapper); this.renderer.enableSmartButtons(this.gateway.button.wrapper);
show(this.gateway.button.wrapper); show(this.gateway.button.wrapper);
show(this.gateway.messages.wrapper);
this.handleButtonStatus(); this.handleButtonStatus();
} }
@ -78,6 +76,12 @@ class SingleProductBootstap {
.observe(addToCartButton, { attributes : true }); .observe(addToCartButton, { attributes : true });
} }
jQuery(document).on('ppcp_should_show_messages', (e, data) => {
if (!this.shouldRender()) {
data.result = false;
}
});
if (!this.shouldRender()) { if (!this.shouldRender()) {
return; return;
} }
@ -232,7 +236,18 @@ class SingleProductBootstap {
this.gateway.ajax.simulate_cart.nonce, this.gateway.ajax.simulate_cart.nonce,
)).simulate((data) => { )).simulate((data) => {
this.messages.renderWithAmount(data.total); jQuery(document.body).trigger('ppcp_product_total_updated', [data.total]);
let newData = {};
if (typeof data.button.is_disabled === 'boolean') {
newData = merge(newData, {button: {is_disabled: data.button.is_disabled}});
}
if (typeof data.messages.is_hidden === 'boolean') {
newData = merge(newData, {messages: {is_hidden: data.messages.is_hidden}});
}
if (newData) {
BootstrapHelper.updateScriptData(this, newData);
}
if ( this.gateway.single_product_buttons_enabled !== '1' ) { if ( this.gateway.single_product_buttons_enabled !== '1' ) {
return; return;
@ -260,13 +275,6 @@ class SingleProductBootstap {
jQuery(this.gateway.button.wrapper).trigger('ppcp-reload-buttons'); jQuery(this.gateway.button.wrapper).trigger('ppcp-reload-buttons');
} }
if (typeof data.button.is_disabled === 'boolean') {
this.gateway.button.is_disabled = data.button.is_disabled;
}
if (typeof data.messages.is_hidden === 'boolean') {
this.gateway.messages.is_hidden = data.messages.is_hidden;
}
this.handleButtonStatus(false); this.handleButtonStatus(false);
}, products); }, products);

View file

@ -1,5 +1,5 @@
import {disable, enable, isDisabled} from "./ButtonDisabler"; import {disable, enable, isDisabled} from "./ButtonDisabler";
import {hide, show} from "./Hiding"; import merge from "deepmerge";
/** /**
* Common Bootstrap methods to avoid code repetition. * Common Bootstrap methods to avoid code repetition.
@ -9,15 +9,6 @@ export default class BootstrapHelper {
static handleButtonStatus(bs, options) { static handleButtonStatus(bs, options) {
options = options || {}; options = options || {};
options.wrapper = options.wrapper || bs.gateway.button.wrapper; options.wrapper = options.wrapper || bs.gateway.button.wrapper;
options.messagesWrapper = options.messagesWrapper || bs.gateway.messages.wrapper;
options.skipMessages = options.skipMessages || false;
// Handle messages hide / show
if (this.shouldShowMessages(bs, options)) {
show(options.messagesWrapper);
} else {
hide(options.messagesWrapper);
}
const wasDisabled = isDisabled(options.wrapper); const wasDisabled = isDisabled(options.wrapper);
const shouldEnable = bs.shouldEnable(); const shouldEnable = bs.shouldEnable();
@ -26,17 +17,9 @@ export default class BootstrapHelper {
if (shouldEnable && wasDisabled) { if (shouldEnable && wasDisabled) {
bs.renderer.enableSmartButtons(options.wrapper); bs.renderer.enableSmartButtons(options.wrapper);
enable(options.wrapper); enable(options.wrapper);
if (!options.skipMessages) {
enable(options.messagesWrapper);
}
} else if (!shouldEnable && !wasDisabled) { } else if (!shouldEnable && !wasDisabled) {
bs.renderer.disableSmartButtons(options.wrapper); bs.renderer.disableSmartButtons(options.wrapper);
disable(options.wrapper, options.formSelector || null); disable(options.wrapper, options.formSelector || null);
if (!options.skipMessages) {
disable(options.messagesWrapper);
}
} }
if (wasDisabled !== !shouldEnable) { if (wasDisabled !== !shouldEnable) {
@ -54,12 +37,15 @@ export default class BootstrapHelper {
&& options.isDisabled !== true; && options.isDisabled !== true;
} }
static shouldShowMessages(bs, options) { static updateScriptData(bs, newData) {
options = options || {}; const newObj = merge(bs.gateway, newData);
if (typeof options.isMessagesHidden === 'undefined') {
options.isMessagesHidden = bs.gateway.messages.is_hidden;
}
return options.isMessagesHidden !== true; const isChanged = JSON.stringify(bs.gateway) !== JSON.stringify(newObj);
bs.gateway = newObj;
if (isChanged) {
jQuery(document.body).trigger('ppcp_script_data_changed', [newObj]);
}
} }
} }