Files
Instagram-Gallery-Sync-Pro/admin/js/ajax-sync.js

183 lines
5.7 KiB
JavaScript

/**
* Instagram Gallery Sync Pro - AJAX Sync Handler
*
* Handles manual sync with progress feedback
*
* @package Instagram_Gallery_Sync_Pro
*/
(function ($) {
'use strict';
/**
* Sync Controller
*/
const IGSPSync = {
isRunning: false,
/**
* Start sync process
*/
start: function () {
if (this.isRunning) {
return;
}
this.isRunning = true;
const $button = $('#igsp-sync-now');
const $progress = $('#igsp-sync-progress');
const $progressFill = $progress.find('.igsp-progress-fill');
const $progressText = $progress.find('.igsp-progress-text');
const $result = $('#igsp-sync-result');
// Reset UI
$button.prop('disabled', true);
$progress.show();
$result.hide().removeClass('success error');
$progressFill.css('width', '0%');
// Start progress animation
this.animateProgress($progressFill, $progressText);
// Execute sync
this.executeSync($button, $progress, $progressFill, $result);
},
/**
* Animate progress bar
*/
animateProgress: function ($fill, $text) {
const stages = [
{ progress: 20, text: 'Connecting to Instagram...' },
{ progress: 40, text: 'Fetching profile data...' },
{ progress: 60, text: 'Downloading images...' },
{ progress: 80, text: 'Saving to database...' },
{ progress: 90, text: 'Finalizing...' }
];
let stageIndex = 0;
this.progressInterval = setInterval(function () {
if (stageIndex < stages.length && IGSPSync.isRunning) {
$fill.css('width', stages[stageIndex].progress + '%');
$text.text(stages[stageIndex].text);
stageIndex++;
}
}, 1500);
},
/**
* Execute sync via AJAX
*/
executeSync: function ($button, $progress, $fill, $result) {
const self = this;
$.ajax({
url: igspAdmin.ajaxUrl,
type: 'POST',
data: {
action: 'igsp_manual_sync',
nonce: igspAdmin.nonce
},
timeout: 120000, // 2 minute timeout
success: function (response) {
self.complete($button, $progress, $fill, $result, response);
},
error: function (xhr, status, error) {
let message = igspAdmin.strings.syncError;
if (status === 'timeout') {
message = 'Sync timed out. The process may still be running in the background.';
} else if (xhr.responseJSON && xhr.responseJSON.data) {
message = xhr.responseJSON.data.message;
}
self.complete($button, $progress, $fill, $result, {
success: false,
data: { message: message }
});
}
});
},
/**
* Complete sync process
*/
complete: function ($button, $progress, $fill, $result, response) {
clearInterval(this.progressInterval);
this.isRunning = false;
// Complete progress bar
$fill.css('width', '100%');
setTimeout(function () {
$progress.hide();
if (response.success) {
$result
.addClass('success')
.html(IGSPSync.formatSuccessMessage(response.data))
.show();
// Update sidebar status
IGSPSync.updateStatus();
} else {
$result
.addClass('error')
.html(response.data.message || igspAdmin.strings.syncError)
.show();
}
$button.prop('disabled', false);
}, 500);
},
/**
* Format success message
*/
formatSuccessMessage: function (data) {
let html = '<strong>✓ ' + igspAdmin.strings.syncComplete + '</strong><br>';
if (data.posts_added > 0) {
html += '<span>Added: ' + data.posts_added + ' new posts</span><br>';
}
if (data.posts_updated > 0) {
html += '<span>Updated: ' + data.posts_updated + ' existing posts</span><br>';
}
if (data.posts_skipped > 0) {
html += '<span>Skipped: ' + data.posts_skipped + ' posts</span>';
}
if (data.errors && data.errors.length > 0) {
html += '<br><small style="color: #dc3545;">Warnings: ' + data.errors.length + '</small>';
}
return html;
},
/**
* Update sync status in sidebar
*/
updateStatus: function () {
$.post(igspAdmin.ajaxUrl, {
action: 'igsp_get_sync_status',
nonce: igspAdmin.nonce
}, function (response) {
if (response.success) {
$('#igsp-total-posts').text(response.data.total_posts);
$('#igsp-last-sync').text(response.data.last_sync);
$('#igsp-next-sync').text(response.data.next_sync);
}
});
}
};
// Make it available globally
window.IGSPSync = IGSPSync;
})(jQuery);