PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / trunk
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF vtrunk
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / assets / js / pricing-modal.js

pricing-modal.js in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF trunk, at assets/js/pricing-modal.js

602 lines 18.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 // Imagify tabs ====================================================================================
2 (function ($, d, w, undefined) { // eslint-disable-line no-unused-vars, no-shadow, no-shadow-restricted-names
3 $('.imagify-badge').addClass('imagify-badge-checked');
4 $('.imagify-toggle-label').eq(0).css('color', '#c8ced5');
5 $('.imagify-toggle-label').eq(1).css('color', '#3b3f4a');
6 // Plan switcher.
7 $('#imagify-toggle-plan').on('change', function() {
8 var isChecked = $(this).is(':checked');
9 $('.imagify-toggle-label').eq(0).css('color', isChecked ? '#c8ced5' : '#3b3f4a');
10 $('.imagify-toggle-label').eq(1).css('color', isChecked ? '#3b3f4a' : '#c8ced5');
11 $('.imagify-badge').toggleClass('imagify-badge-checked', isChecked);
12 $('#imagify_all_plan_view').toggleClass('imagify-year-selected', isChecked).toggleClass('imagify-month-selected', ! isChecked);
13 $('.imagify-arrow-container img').eq(0).toggle(! isChecked);
14 $('.imagify-arrow-container img').eq(1).toggle(isChecked);
15 });
16
17 })(jQuery, document, window);
18
19
20 // Imagify payment modal ===========================================================================
21 (function ($, d, w, undefined) { // eslint-disable-line no-unused-vars, no-shadow, no-shadow-restricted-names
22
23 var imagifyModal = {};
24
25 if (! $('#imagify-pricing-modal').length) {
26 return;
27 }
28
29 imagifyModal = {
30 $modal: $('#imagify-pricing-modal'),
31 // Plans selection view & payment process view hidden by default.
32 $plansView: $('#imagify-plans-selection-view'),
33 $paymentView: $('#imagify-payment-process-view').hide(),
34 $successView: $('#imagify-success-view').hide(),
35 speedFadeIn: 300,
36
37 getHtmlPrice: function (content, period) {
38 var monthly, yearly, m, y, output;
39
40 if (! period) {
41 period = null;
42 }
43
44 if (typeof content !== 'object') {
45 content = w.imagify.splitPrice(content);
46
47 output = '<span class="imagify-price-big">' + content[0] + '</span> ';
48 output += '<span class="imagify-price-mini">.' + content[1] + '</span>';
49
50 return output;
51 }
52
53 monthly = content.monthly + '';
54 yearly = content.yearly + '';
55 m = w.imagify.splitPrice(monthly);
56 y = w.imagify.splitPrice(yearly);
57 output = '<span class="imagify-switch-my">';
58 /* eslint-disable indent */
59 output += '<span aria-hidden="' + (period === 'monthly' ? 'false' : 'true') + '" class="imagify-monthly">';
60 output += '<span class="imagify-price-big">' + m[0] + '</span> ';
61 output += '<span class="imagify-price-mini">.' + m[1] + '</span>';
62 output += '</span> ';
63 output += '<span aria-hidden="' + (period === 'yearly' ? 'false' : 'true') + '" class="imagify-yearly">';
64 output += '<span class="imagify-price-big">' + y[0] + '</span> ';
65 output += '<span class="imagify-price-mini">.' + y[1] + '</span>';
66 output += '</span>';
67 /* eslint-enable indent */
68 output += '</span>';
69
70 return output;
71 },
72
73 getHtmlDiscountPrice: function (content, period) {
74 var monthly, yearly,
75 output = '';
76
77 if (! period) {
78 period = null;
79 }
80
81 if (typeof content === 'object') {
82 monthly = content.monthly + '';
83 yearly = content.yearly + '';
84
85 output += '<span class="imagify-price-discount">';
86 /* eslint-disable indent */
87 output += '<span class="imagify-price-discount-dollar">$</span>';
88 output += '<span class="imagify-switch-my">';
89 output += '<span aria-hidden="' + (period === 'monthly' ? 'false' : 'true') + '" class="imagify-monthly">';
90 output += '<span class="imagify-price-discount-number">' + monthly + '</span>';
91 output += '</span>';
92 output += '<span aria-hidden="' + (period === 'yearly' ? 'false' : 'true') + '" class="imagify-yearly">';
93 output += '<span class="imagify-price-discount-number">' + yearly + '</span>';
94 output += '</span>';
95 output += '</span>';
96 /* eslint-enable indent */
97 output += '</span>';
98 } else {
99 content += ''; // Be sure content is a string.
100 output += '<span class="imagify-price-discount">';
101 /* eslint-disable indent */
102 output += '<span class="imagify-price-discount-dollar">$</span>';
103 output += '<span class="imagify-price-discount-number">' + content + '</span>';
104 /* eslint-enable indent */
105 output += '</span>';
106 }
107
108 return output;
109 },
110
111 /**
112 * @uses imagifyModal.getHtmlPrice()
113 * @uses imagifyModal.getHtmlDiscountPrice()
114 */
115 populateOffer: function ($offer, datas, type, classes) {
116 var promo = w.imagify_discount_datas,
117 add = datas.additional_gb, // 4 (monthly)
118 ann = datas.annual_cost, // 49.9 (monthly)
119 id = datas.id, // 3 (monthly/onetime)
120 lab = datas.label, // 'lite' (monthly/onetime)
121 mon = datas.monthly_cost, // 4.99 (monthly)
122 quo = datas.quota, // 1000 (MB) - 5000 images (monthly/onetime)
123 cos = datas.cost, // 3.49 (onetime)
124 label = datas.label.replace(/_.*$/, ''),
125 name = w.imagify.formatQuota(quo),
126 pcs = 'monthly' === type ? {monthly: mon, yearly: w.imagify.monthlyFromAnnual(ann)} : cos,
127 pcsd = pcs, // Used if discount is active.
128 percent, $datas_c, datas_content, applies_to = [],
129 offer_by = '',
130 additional_data = '';
131
132 applies_to = imagifyModal.getPromoAppliesTo(promo);
133
134
135 // Change pricing value only if discount in percentage is active and if offer is a monthly and not a onetime.
136 if (
137 promo.is_active
138 && 'percentage' === promo.coupon_type
139 && 'monthly' === type
140 && (0 < mon)
141 && (applies_to.includes(lab) || 'all' === applies_to[0])
142 ) {
143 percent = (100 - promo.coupon_value) / 100;
144 pcs = 'monthly' === type
145 ? w.imagify.applyDiscount(mon, ann, promo.coupon_value)
146 : cos * percent;
147 }
148
149 if (typeof classes !== 'undefined') {
150 $offer.addClass('imagify-' + type + '-' + lab + classes);
151 $offer.addClass('imagify-' + type + '-' + lab + classes);
152 }
153
154 // Label.
155 $offer.find('.imagify-label-plans').text(label);
156
157 // Name.
158 $offer.find('.imagify-offer-size').text(name);
159
160 // Main prices (pcs can be an object or a string).
161 $offer.find('.imagify-number-block').html(imagifyModal.getHtmlPrice(pcs, 'monthly'));
162
163 if ('Unlimited' === name) {
164 offer_by = 'quota';
165 $offer.addClass('imagify-best-value');
166 additional_data = 'No additional cost';
167 } else {
168 offer_by = '/month';
169 additional_data = '$' + add + ' per additional Gb';
170 }
171
172 $offer.find('.imagify-offer-by').text(offer_by);
173
174 // discount prices
175 $offer.find('.imagify-price-block').prev('.imagify-price-discount').remove();
176 if (
177 promo.is_active
178 && 'percentage' === promo.coupon_type
179 && 'monthly' === type
180 && (0 < mon)
181 && (applies_to.includes(lab) || 'all' === applies_to[0])
182 ) {
183 $offer.find('.imagify-price-block').before(imagifyModal.getHtmlDiscountPrice(pcsd, 'monthly'));
184 }
185 // Nb images.
186 $offer.find('.imagify-approx-nb').text(quo * 5);
187
188 if ('monthly' === type) {
189 // Additional price.
190 $offer.find('.imagify-price-add-data').text(additional_data);
191 }
192
193 // Button data-offer attr.
194 $datas_c = $offer.find('.imagify-payment-btn-select-plan').length ? $offer.find('.imagify-payment-btn-select-plan') : $offer;
195
196 if ('monthly' === type) {
197 datas_content = '{"' + lab + '":{"id":' + id + ',"name":"' + name + '","label":"' + lab + '","data":' + quo + ',"dataf":"' + name + '","imgs":' + (quo * 5) + ',"prices":{"monthly":' + pcs.monthly + ',"yearly":' + pcs.yearly + ',"add":' + add + '}}}';
198 } else {
199 datas_content = '{"ot' + lab + '":{"id":' + id + ',"name":"' + name + '","label":"' + lab + '","data":' + quo + ',"dataf":"' + name + '","imgs":' + (quo * 5) + ',"price":' + pcs + '}}';
200 }
201
202 $datas_c.attr('data-offer', datas_content);
203
204 return $offer;
205 },
206
207 /**
208 * @uses imagifyModal.populateOffer()
209 */
210 getPricing: function ($button) {
211 var nonce = $button.data('nonce'),
212 prices_rq_datas = {
213 action: 'imagify_get_prices',
214 imagifynonce: nonce
215 },
216 prices_rq_discount = {
217 action: 'imagify_get_discount',
218 imagifynonce: nonce
219 };
220
221 imagifyModal.$modal.find('.imagify-modal-loader').hide().show();
222 imagifyModal.$modal.addClass('imagify-modal-loading');
223
224 /**
225 * TODO: change the way to waterfall requests.
226 * Use setInterval + counter instead.
227 */
228
229 // Get the true prices.
230 $.post(ajaxurl, prices_rq_datas, function (prices_response) {
231
232 if (! prices_response.success) {
233 // TODO: replace modal content by any information.
234 // An error occurred.
235
236 return;
237 }
238
239 // Get the discount informations.
240 $.post(ajaxurl, prices_rq_discount, function (discount_response) {
241 var prices_datas, promo_datas,
242 offers,
243 mo_html = '',
244 $mo_tpl,
245 mo_clone,
246 $estim_block, $offers_block,
247 $banners, date_end, plan_names, promo, discount;
248
249 if (! discount_response.success) {
250 // TODO: replace modal content by any information.
251 // An error occurred.
252 return;
253 }
254
255 prices_datas = prices_response.data;
256 promo_datas = discount_response.data;
257 offers = {
258 mo: []
259 };
260 $mo_tpl = $('#imagify-offer-monthly-template');
261 mo_clone = $mo_tpl.html();
262 $estim_block = $('.imagify-estimation-block');
263
264 // Remove inactive offers.
265 $.each(prices_datas.monthlies, function (index, value) {
266 if ('undefined' === typeof value.active
267 ||
268 ('undefined' !== typeof value.active && true === value.active)
269 ) {
270 if ('starter' === value.label) {
271 return;
272 }
273 offers.mo.push(value);
274 }
275 });
276
277 // Refresh Analyzing block.
278 $estim_block.removeClass('imagify-analyzing');
279
280 // Reset offer selection.
281 $('.imagify-offer-selected').removeClass('imagify-offer-selected').find('.imagify-checkbox').prop('checked', false);
282
283 // Don't create prices table if something went wrong during request.
284 if (null === offers.mo) {
285 $offers_block = $('.imagify-pre-checkout-offers');
286
287 // Hide main content.
288 $offers_block.hide().attr('aria-hidden', true);
289
290 // Show error message.
291 $offers_block.closest('.imagify-modal-views').find('.imagify-popin-message').remove();
292 $offers_block.after('<div class="imagify-popin-message imagify-error"><p>' + imagifyPricingModal.labels.errorPriceAPI + '</p></div>');
293
294 // Show the modal content.
295 imagifyModal.$modal.find('.imagify-modal-loader').fadeOut(300);
296 imagifyModal.$modal.removeClass('imagify-modal-loading');
297 return;
298 }
299
300 // Autofill coupon code & Show banner if discount is active.
301 w.imagify_discount_datas = promo_datas;
302
303 if (promo_datas.is_active) {
304 if (promo_datas.applies_to instanceof Array) {
305 plan_names = [];
306 var plan_list = [];
307
308 for (var plan_infos = 0; plan_infos < promo_datas.applies_to.length; plan_infos++) {
309 plan_list.push(promo_datas.applies_to[plan_infos].plan_name);
310 }
311
312 plan_list.forEach(function (item) {
313 if (! plan_names.includes(item)) {
314 plan_names.push(item);
315 }
316 });
317
318 plan_names = plan_names.join(', ');
319 } else {
320 plan_names = promo_datas.applies_to;
321 }
322
323 $banners = $('.imagify-modal-promotion');
324 date_end = promo_datas.date_end.split('T')[0];
325 promo = promo_datas.coupon_value;
326 discount = 'percentage' === promo_datas.coupon_type ? promo + '%' : '$' + promo;
327
328
329 // Show banners.
330 $banners.addClass('active').attr('aria-hidden', 'false');
331
332 // Populate banners.
333 $banners.find('.imagify-promotion-number').text(discount);
334 $banners.find('.imagify-promotion-plan-name').text(plan_names);
335 $banners.find('.imagify-promotion-date').text(date_end);
336
337 }
338
339 /**
340 * Below lines will build Plan and Onetime offers lists.
341 * It will also pre-select a Plan and/or Onetime in both of views: pre-checkout and pricing tables.
342 */
343 if (0 === offers.mo.length) {
344 $('.imagify-pre-checkout-offers .imagify-offer-monthly').remove();
345 $('.imagify-tabs').remove();
346 $('.imagify-pricing-tab-monthly').remove();
347 } else {
348 // Now, do the MONTHLIES Markup.
349 offers.mo = offers.mo.reverse();
350 $.each(offers.mo, function (index, value) {
351 var $tpl,
352 classes = '';
353
354 // Populate each offer.
355 $tpl = $(mo_clone).clone();
356 $tpl = imagifyModal.populateOffer($tpl, value, 'monthly', classes);
357
358 // Complete Monthlies HTML.
359 mo_html += $tpl[0].outerHTML;
360 });
361
362 // Wait for element to be ready after ajax callback before adding ribbon.
363 setTimeout(function() {
364 // Add best value ribbon to unlimited plan.
365 $('.imagify-best-value').prepend('<div class="imagify-ribbon"><span>Best Value!</span></div>');
366 }, 100);
367 }
368
369 // Fill pricing tables.
370 if ($mo_tpl.parent().find('.imagify-offer-line')) {
371 $mo_tpl.parent().find('.imagify-offer-line').remove();
372 }
373
374 $mo_tpl.before(mo_html);
375
376
377 // Show the content.
378 imagifyModal.$modal.find('.imagify-modal-loader').fadeOut(300);
379 imagifyModal.$modal.removeClass('imagify-modal-loading');
380
381 }); // Third AJAX request to get discount information.
382
383 }); // End $.post.
384 },
385
386 /**
387 * 1) Modal Payment change/select plan
388 * 2) Checkout selection(s)
389 * 3) Payment process
390 */
391
392 getPeriod: function () {
393 return $('#imagify_all_plan_view').hasClass('imagify-month-selected') ? 'monthly' : 'yearly';
394 },
395
396 switchToView: function ($view, data) {
397
398 var viewId = $view.attr('id'),
399 $modalContent = imagifyModal.$modal.children('.imagify-modal-content');
400
401 $view.siblings('.imagify-modal-views').hide().attr('aria-hidden', 'true');
402
403 // Plans view has tabs: display the right one.
404 if (data && data.tab) {
405 $view.find('a[href="#' + data.tab + '"]').trigger('click.imagify');
406 }
407
408 // Payment view: it's an iframe.
409 if ('imagify-payment-process-view' === viewId) {
410 $modalContent.addClass('imagify-iframe-viewing');
411 } else {
412 $modalContent.removeClass('imagify-iframe-viewing');
413 }
414
415 // Success view: some tweaks.
416 if ('imagify-success-view' === viewId) {
417 $modalContent.addClass('imagify-success-viewing');
418 imagifyModal.$modal.attr('aria-labelledby', 'imagify-success-view');
419 } else {
420 $modalContent.removeClass('imagify-success-viewing');
421 imagifyModal.$modal.removeAttr('aria-labelledby');
422 }
423
424 $view.fadeIn(imagifyModal.speedFadeIn).attr('aria-hidden', 'false');
425 },
426
427 iframeSetSrc: function (params) {
428 /**
429 * params = {
430 * 'plan_id': 0,
431 * 'period': 'monthly'|'yearly'
432 * }
433 */
434
435 var $iframe = $('#imagify-payment-iframe'),
436 iframe_src = $iframe.attr('src'),
437 pay_src = $iframe.data('src'),
438 // Stop it ESLint, you're drunk.
439 key, amount, // eslint-disable-line no-unused-vars
440 rt_yearly, rt_monthly, $iframeClone, tofind;
441
442 // If we only change monthly/yearly payment mode.
443 if (typeof params === 'string' && '' !== iframe_src) {
444 tofind = 'monthly' === params ? 'yearly' : 'monthly';
445 iframe_src = iframe_src.replace(tofind, params);
446 $iframe.attr('src', iframe_src);
447 return;
448 }
449
450 // If we get new informations about products.
451 if (typeof params !== 'object') {
452 return;
453 }
454
455 if (! params.period) {
456 w.imagify.info('No period defined');
457 return;
458 }
459
460 rt_yearly = 'yearly' === params.period ? params.plan_id : 0;
461 rt_monthly = 'monthly' === params.period ? params.plan_id : 0;
462
463 // Compose route.
464 // pay_src + /:monthlyplan(0)/:yearlyplan(0)/
465 pay_src = pay_src + 0 + '/' + rt_monthly + '/' + rt_yearly + '/none/';
466
467 console.log(pay_src);
468 // iFrame sort of cache fix.
469 $iframeClone = $iframe.remove().attr('src', pay_src);
470
471 imagifyModal.$paymentView.html($iframeClone);
472 },
473
474 /**
475 * Public function triggered by payement iframe.
476 */
477 paymentClose: function () {
478 $('.imagify-iframe-viewing .close-btn').trigger('click.imagify');
479 $('.imagify-iframe-viewing').removeClass('imagify-iframe-viewing');
480 },
481
482 /**
483 * @uses imagifyModal.switchToView()
484 */
485 paymentBack: function () {
486 imagifyModal.switchToView(imagifyModal.$plansView);
487 },
488
489 /**
490 * @uses imagifyModal.switchToView()
491 */
492 paymentSuccess: function () {
493 imagifyModal.switchToView(imagifyModal.$successView);
494 },
495
496 /**
497 * @uses imagifyModal.paymentClose()
498 * @uses imagifyModal.paymentBack()
499 * @uses imagifyModal.paymentSuccess()
500 */
501 checkPluginMessage: function (e) {
502 var origin = e.origin || e.originalEvent.origin; // eslint-disable-line no-shadow
503
504 if ( imagifyPricingModal.imagify_app_domain !== origin ) {
505 return;
506 }
507
508 switch (e.data) {
509 case 'cancel':
510 imagifyModal.paymentClose();
511 break;
512 case 'back':
513 imagifyModal.paymentBack();
514 break;
515 case 'success':
516 imagifyModal.paymentSuccess();
517 break;
518 }
519 },
520 getPromoAppliesTo: function(promo){
521 return w.imagify.getPromoAppliesTo(promo);
522 }
523 };
524
525 /**
526 * INIT.
527 */
528
529 /**
530 * Get pricings on modal opening.
531 * Build the pricing tables inside modal.
532 */
533 $('.imagify-get-pricing-modal').on('click.imagify-ajax', function () {
534 imagifyModal.getPricing($(this));
535 });
536
537 /**
538 * Get pricing on modal opening for admin bar menu, the button is added dynamically
539 * Build the pricing tables inside modal.
540 */
541 $(document).on('click', '.imagify-admin-bar-upgrade-plan', function () {
542 imagifyModal.getPricing($(this));
543 });
544
545 /**
546 * Reset the modal on close.
547 */
548 $(d).on('modalClosed.imagify', '.imagify-payment-modal', function () {
549 $(this).find('.imagify-modal-content').removeClass('imagify-success-viewing imagify-iframe-viewing');
550
551 // Reset first view after fadeout ~= 300 ms.
552 setTimeout(function () {
553 $('.imagify-modal-views').hide();
554 $('#imagify-plans-selection-view').show();
555 }, 300);
556
557 //delay scrolltop top to avoid flickering
558 setTimeout(function () {
559 $('.imagify-payment-modal').find('.imagify-modal-content').scrollTop(0);
560 }, 400);
561 });
562
563 /**
564 * View game, step by step.
565 */
566
567 /**
568 * 2) when you checkout.
569 *
570 * @uses imagifyModal.switchToView()
571 * @uses imagifyModal.getPeriod()
572 * @uses imagifyModal.iframeSetSrc()
573 */
574 imagifyModal.$modal.on('click.imagify', '.imagify-payment-btn-select-plan', function (e) {
575 var checkout_datas;
576
577 e.preventDefault();
578
579 checkout_datas = {};
580
581 // Clear user account cache.
582 if (imagifyPricingModal.userDataCache) {
583 $.post(ajaxurl, {
584 action: imagifyPricingModal.userDataCache.deleteAction,
585 _wpnonce: imagifyPricingModal.userDataCache.deleteNonce
586 });
587 }
588
589 // Change views to go to checkout/payment view.
590 imagifyModal.switchToView(imagifyModal.$paymentView);
591
592 checkout_datas.plan_id = Object.values(JSON.parse($(this).attr('data-offer')))[0].id;
593 checkout_datas.period = imagifyModal.getPeriod();
594
595 imagifyModal.iframeSetSrc(checkout_datas);
596 });
597
598 // Message/communication API.
599 w.addEventListener('message', imagifyModal.checkPluginMessage, true);
600
601 })(jQuery, document, window);
602