wp_back/wp-content/plugins/wp-smushit/_src/js/modules/background-process.js
2024-05-20 15:37:46 +03:00

395 lines
16 KiB
JavaScript

/* global WP_Smush */
/**
* Bulk Smush Background Optimization.
*
* @since 3.12.0
*/
import Fetcher from '../utils/fetcher';
import MixPanel from "../mixpanel";
import SmushProgress from '../common/progressbar';
import {GlobalStats, UpsellManger} from "../common/globalStats";
(function () {
'use strict';
if (!window.wp_smush_msgs) {
return;
}
const $ = document.querySelector.bind(document);
const NO_FREE_LIMITED = 50;
/**
* Handle Background Process.
* @returns
*/
const BackgroundProcess = () => {
return {
handle(action) {
return Fetcher.background[action]();
},
initState() {
return Fetcher.background.initState();
},
}
}
/**
* Background Optimization.
*/
const BackgroundSmush = (() => {
const startBtn = window.wp_smushit_data && window.wp_smushit_data.bo_stats && $('.wp-smush-bo-start');
if (!startBtn) {
return;
}
const mixPanel = MixPanel.getInstance();
const BO = new BackgroundProcess();
const bulkWrapper = $('.bulk-smush-wrapper');
const reScanImagesButton = $('.wp-smush-scan');
let intervalHandle = 0;
let cancellationInProgress = false;
return {
hookStatusChecks() {
if (intervalHandle) {
// Already done
return;
}
let count = 0;
let statusSyncInProgress = false;
let statSyncInProgress = false;
intervalHandle = setInterval(() => {
if (statusSyncInProgress) {
return;
}
statusSyncInProgress = true;
count++;
const statusSynced = this.syncBackgroundStatus();
if (count % 3 === 0) {
// Do a full update every nth time
statusSynced.then(() => {
if (!statSyncInProgress) {
this.syncStats().then(() => {
statSyncInProgress = false;
});
statSyncInProgress = true;
}
});
}
statusSynced.finally(() => {
statusSyncInProgress = false;
});
}, 3 * 1000);
},
resetBOStatsOnStart() {
GlobalStats.setBoStats( {
is_cancelled: false,
is_completed: false,
processed_items: 0,
failed_items: 0,
} );
},
start() {
// Reset boStats.
this.resetBOStatsOnStart();
// Disable UI.
this.onStart();
// Start BO.
BO.handle('start').then((res) => {
if (res.success) {
// Update stats.
const updatedStats = this.updateStats(res.data, false);
// Show progress bar.
this.showProgressBar();
this.hookStatusChecks();
if ( updatedStats ) {
// Render stats.
GlobalStats.renderStats();
}
} else {
WP_Smush.helpers.showNotice( res, {
'showdismiss': true,
'autoclose' : false,
} );
this.cancelBulk();
}
});
},
/**
* Initial state when load the Bulk Smush page while BO is running.
*/
initState() {
if (!GlobalStats.getBoStats().in_processing) {
return;
}
// Disable UI.
this.onStart();
// Start BO.
BO.initState().then((res) => {
if (res.success) {
// Update stats.
this.updateStats(res.data, false);
// Show progress bar.
this.showProgressBar();
this.hookStatusChecks();
// Maybe update errors.
if ( res.data.errors && ! Object.keys( GlobalStats.getErrors() ).length ) {
GlobalStats.setErrors( res.data.errors );
}
// Render stats.
GlobalStats.renderStats();
} else {
WP_Smush.helpers.showNotice( res );
}
});
},
/**
* Cancel.
*/
cancel() {
cancellationInProgress = true;
this.setCancelButtonStateToStarted();
BO.handle('cancel').then((res) => {
if (res.success) {
this.cancelBulk();
} else {
WP_Smush.helpers.showNotice( res );
}
});
},
hideProgressBar() {
// Hide progress bar.
SmushProgress.close().update(0, GlobalStats.getBoStats().total_items);
},
showProgressBar() {
// Reset progress bar.
SmushProgress.update(GlobalStats.getBoStats().processed_items, GlobalStats.getBoStats().total_items);
// Show progress bar.
SmushProgress.show();
},
/**
* Update stats.
* @param {Object} newStats Included increment stats and new BO stats.
* @param updateGlobal
*/
updateStats(newStats, updateGlobal) {
// Make sure we have processed_stats/errors property (not added by default when start).
newStats.global_stats = newStats.global_stats || {};
newStats.errors = newStats.errors || {};
const {
global_stats,
errors,
...newBoStats
} = newStats;
if ( ! GlobalStats.isChangedStats( newBoStats ) ) {
return false;
}
// Update BO stats.
GlobalStats.setBoStats(newBoStats);
if (updateGlobal) {
// Update global stats.
GlobalStats.setGlobalStats(global_stats);
}
// Update Errors.
GlobalStats.setErrors( errors );
return true;
},
cancelBulk() {
// Sync Stats.
this.syncStats(() => {
if (100 === GlobalStats.getGlobalStats().percent_optimized) {
// If the last item was getting processed when the user cancelled then the process might have completed
GlobalStats.setBoStats( {
is_completed: true
} );
this.onCompletedBulk();
} else {
// Update status of boStats.
GlobalStats.setBoStats( {
is_cancelled: true
} );
// Reset and hide progress bar.
this.onFinish();
// Bulk is cancelled, show bulk desc.
SmushProgress.showBulkSmushDescription();
}
mixPanel.trackBulkSmushCancel();
cancellationInProgress = false;
});
},
showCompletedMessage() {
// Render completed message.
// Show completed message.
const processedWrapper = bulkWrapper.querySelector('.wp-smush-all-done');
if ( GlobalStats.getBoStats().failed_items ) {
let completeMessage = wp_smush_msgs.all_failed;
if ( ! this.isFailedAllItems() ) {
completeMessage = wp_smush_msgs.error_in_bulk.replace( '{{smushed}}', GlobalStats.getBoStats().total_items - GlobalStats.getBoStats().failed_items )
.replace('{{total}}', GlobalStats.getBoStats().total_items )
.replace('{{errors}}', GlobalStats.getBoStats().failed_items );
}
processedWrapper.querySelector('p').innerHTML = completeMessage;
processedWrapper.classList.remove('sui-notice-success', 'sui-notice-warning');
const noticeType = this.getNoticeType();
const noticeIcon = 'warning' === noticeType ? 'info' : 'check-tick';
const iconElement = processedWrapper.querySelector('.sui-notice-icon');
processedWrapper.classList.add( 'sui-notice-' + noticeType );
iconElement.classList.remove('sui-icon-check-tick', 'sui-icon-info');
iconElement.classList.add( 'sui-icon-' + noticeIcon );
} else {
processedWrapper.querySelector('p').innerHTML = wp_smush_msgs.all_smushed;
}
processedWrapper.classList.remove('sui-hidden');
},
isFailedAllItems() {
return GlobalStats.getBoStats().failed_items === GlobalStats.getBoStats().total_items;
},
getNoticeType() {
return this.isFailedAllItems() ? 'warning' : 'success';
},
onCompletedBulk() {
// Reset and hide progress bar.
this.onFinish();
// Bulk is completed, hide bulk desc.
SmushProgress.hideBulkSmushDescription();
// Show completed message.
this.showCompletedMessage();
// Reset the progress when we finish so the next smushing starts from zero.
SmushProgress.update(0, GlobalStats.getBoStats().total_items);
},
completeBulk() {
// Sync Stats.
this.syncStats(() => this.onCompletedBulk());
},
syncStats(onComplete = () => false) {
return BO.handle('getStats').then((res) => {
if ( res.success ) {
const responseErrors = res.data.errors || {};
this.updateStats( { global_stats: res.data, errors: responseErrors }, true );
GlobalStats.renderStats();
if ( res.data.content ) {
$('#wp-smush-bulk-content').innerHTML = res.data.content;
}
onComplete();
} else {
WP_Smush.helpers.showNotice( res );
}
}).catch( (error) => console.log('error', error));
},
syncBackgroundStatus() {
return BO.handle('getStatus').then((res) => {
if ((res.data || {}).in_process_notice) {
SmushProgress.setNotice( res.data.in_process_notice );
}
if (res.success) {
// Update stats.
if ( this.updateStats(res.data, false) ) {
// Update progress bar.
SmushProgress.update(GlobalStats.getBoStats().processed_items, GlobalStats.getBoStats().total_items);
if (! GlobalStats.getBoStats().is_cancelled && ! GlobalStats.getBoStats().is_completed) {
// Render stats.
GlobalStats.renderStats();
}
}
if (GlobalStats.getBoStats().is_cancelled && !cancellationInProgress) {
// Cancelled on server side
this.cancelBulk();
} else if (GlobalStats.getBoStats().is_completed) {
this.completeBulk();
}
} else {
WP_Smush.helpers.showNotice( res );
}
});
},
onStart() {
// Disable btn.
startBtn.setAttribute('disabled', '');
// Disable re-check images.
reScanImagesButton && reScanImagesButton.setAttribute('disabled', '');
$('.wp-smush-restore').setAttribute('disabled', '');
// Show upsell cdn.
UpsellManger.maybeShowCDNUpsellForPreSiteOnStart();
this.setCancelButtonStateToInitial();
},
onFinish() {
// Clear interval.
if (intervalHandle) {
clearInterval(intervalHandle);
intervalHandle = 0;
}
// Disable btn.
startBtn.removeAttribute('disabled');
// Reset and hide Progress Bar.
this.hideProgressBar();
// Disable re-check images.
reScanImagesButton && reScanImagesButton.removeAttribute('disabled', '');
$('.wp-smush-restore').removeAttribute('disabled', '');
// Show upsell cdn.
UpsellManger.maybeShowCDNUpsellForPreSiteOnCompleted();
},
init() {
if (!startBtn) {
return;
}
// Start BO.
startBtn.onclick = () => {
const requiredScanMedia = startBtn.classList.contains('wp-smush-scan-and-bulk-smush');
if ( requiredScanMedia ) {
return;
}
this.start();
}
// If BO is running, initial new state.
this.initState();
},
setCancelButtonStateToInitial() {
SmushProgress.setCancelButtonLabel( wp_smush_msgs.cancel );
SmushProgress.setOnCancelCallback( this.cancel.bind(this) );
},
setCancelButtonStateToStarted() {
SmushProgress.setCancelButtonLabel( wp_smush_msgs.cancelling );
SmushProgress.setOnCancelCallback( () => false );
},
}
})();
// Run.
BackgroundSmush && BackgroundSmush.init();
/**
* For globalStats, we will need to update it on reload and after re-checking images,
* and on finish the BO.
* 1. On finish, we handled via BackgroundSmush.syncStats -> BackgroundSmush.updateStats
* 2. On reload or after re-checking images, we need to update globalStats from global variable:
* window.wp_smushit_data
*/
// Update global stats after re-checking images.
document.addEventListener('wpSmushAfterRecheckImages', function(){
GlobalStats.updateGlobalStatsFromSmushScriptData();
});
document.addEventListener('backgroundBulkSmushOnScanCompleted', function(){
if ( ! BackgroundSmush ) {
return;
}
GlobalStats.setBoStats({
in_processing: true,
});
BackgroundSmush.initState();
});
})();