|
@@ -14,7 +14,20 @@
|
|
|
var uploadedAttachmentId = null;
|
|
var uploadedAttachmentId = null;
|
|
|
var uploadedFileRecordId = null;
|
|
var uploadedFileRecordId = null;
|
|
|
var isUploading = false;
|
|
var isUploading = false;
|
|
|
- var originalGalleryImages = {}; // Store original src/srcset to restore on remove
|
|
|
|
|
|
|
+ var originalGalleryImages = {};
|
|
|
|
|
+
|
|
|
|
|
+ // Broad selectors for add-to-cart elements
|
|
|
|
|
+ var addToCartSelectors = [
|
|
|
|
|
+ '.single_add_to_cart_button',
|
|
|
|
|
+ '.add_to_cart_button',
|
|
|
|
|
+ 'button[name="add-to-cart"]',
|
|
|
|
|
+ 'input[name="add-to-cart"]',
|
|
|
|
|
+ 'a[data-product_id]',
|
|
|
|
|
+ 'button[data-product_id]',
|
|
|
|
|
+ 'a[href*="add-to-cart"]',
|
|
|
|
|
+ '.product form.cart button[type="submit"]',
|
|
|
|
|
+ '.product form.cart input[type="submit"]'
|
|
|
|
|
+ ].join(', ');
|
|
|
|
|
|
|
|
// Upload area elements
|
|
// Upload area elements
|
|
|
var $dropzone = $uploadWrap.find('#studiou-fpp-dropzone');
|
|
var $dropzone = $uploadWrap.find('#studiou-fpp-dropzone');
|
|
@@ -28,51 +41,80 @@
|
|
|
var $removeBtn = $uploadWrap.find('.studiou-fpp-remove-file');
|
|
var $removeBtn = $uploadWrap.find('.studiou-fpp-remove-file');
|
|
|
var $messages = $uploadWrap.find('.studiou-fpp-messages');
|
|
var $messages = $uploadWrap.find('.studiou-fpp-messages');
|
|
|
|
|
|
|
|
- // Block all add-to-cart actions until photo is uploaded
|
|
|
|
|
- // Intercept form submissions
|
|
|
|
|
- $(document).on('submit', 'form.cart, form.variations_form', function (e) {
|
|
|
|
|
- if (!uploadedAttachmentId) {
|
|
|
|
|
- e.preventDefault();
|
|
|
|
|
- showMessage(studiouWcfppFront.i18n.uploadFile, 'error');
|
|
|
|
|
- scrollToUpload();
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ // ==========================================
|
|
|
|
|
+ // Disable/enable add-to-cart buttons
|
|
|
|
|
+ // ==========================================
|
|
|
|
|
+ function disableAddToCart() {
|
|
|
|
|
+ $(addToCartSelectors).each(function () {
|
|
|
|
|
+ var $el = $(this);
|
|
|
|
|
+ $el.addClass('studiou-fpp-disabled');
|
|
|
|
|
+ if ($el.is('a')) {
|
|
|
|
|
+ if (!$el.data('studiou-fpp-href')) {
|
|
|
|
|
+ $el.data('studiou-fpp-href', $el.attr('href'));
|
|
|
|
|
+ }
|
|
|
|
|
+ $el.attr('href', '#');
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $el.prop('disabled', true);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function enableAddToCart() {
|
|
|
|
|
+ $(addToCartSelectors).each(function () {
|
|
|
|
|
+ var $el = $(this);
|
|
|
|
|
+ $el.removeClass('studiou-fpp-disabled');
|
|
|
|
|
+ if ($el.is('a')) {
|
|
|
|
|
+ var origHref = $el.data('studiou-fpp-href');
|
|
|
|
|
+ if (origHref) {
|
|
|
|
|
+ $el.attr('href', origHref);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $el.prop('disabled', false);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // Intercept add-to-cart button clicks (covers AJAX and non-AJAX buttons)
|
|
|
|
|
- $(document).on('click', '.single_add_to_cart_button, .add_to_cart_button, button[name="add-to-cart"], input[name="add-to-cart"]', function (e) {
|
|
|
|
|
|
|
+ // Fallback: intercept clicks on disabled elements (capture phase)
|
|
|
|
|
+ document.addEventListener('click', function (e) {
|
|
|
if (!uploadedAttachmentId) {
|
|
if (!uploadedAttachmentId) {
|
|
|
- e.preventDefault();
|
|
|
|
|
- e.stopImmediatePropagation();
|
|
|
|
|
- showMessage(studiouWcfppFront.i18n.uploadFile, 'error');
|
|
|
|
|
- scrollToUpload();
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+ var el = e.target.closest(addToCartSelectors.replace(/,\s*/g, ', '));
|
|
|
|
|
+ if (el) {
|
|
|
|
|
+ e.preventDefault();
|
|
|
|
|
+ e.stopImmediatePropagation();
|
|
|
|
|
+ showMessage(studiouWcfppFront.i18n.uploadFile, 'error');
|
|
|
|
|
+ $('html, body').animate({ scrollTop: $uploadWrap.offset().top - 100 }, 400);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- });
|
|
|
|
|
|
|
+ }, true); // capture phase - fires before bubble
|
|
|
|
|
|
|
|
- // Intercept add-to-cart links (e.g. ?add-to-cart=ID)
|
|
|
|
|
- $(document).on('click', 'a[href*="add-to-cart"]', function (e) {
|
|
|
|
|
|
|
+ // Disable buttons on page load
|
|
|
|
|
+ disableAddToCart();
|
|
|
|
|
+
|
|
|
|
|
+ // Also watch for dynamically added buttons (e.g. AJAX-loaded variations)
|
|
|
|
|
+ var observer = new MutationObserver(function () {
|
|
|
if (!uploadedAttachmentId) {
|
|
if (!uploadedAttachmentId) {
|
|
|
- e.preventDefault();
|
|
|
|
|
- e.stopImmediatePropagation();
|
|
|
|
|
- showMessage(studiouWcfppFront.i18n.uploadFile, 'error');
|
|
|
|
|
- scrollToUpload();
|
|
|
|
|
- return false;
|
|
|
|
|
|
|
+ disableAddToCart();
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
+ observer.observe(document.querySelector('.product') || document.body, {
|
|
|
|
|
+ childList: true, subtree: true
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
- function scrollToUpload() {
|
|
|
|
|
- $('html, body').animate({
|
|
|
|
|
- scrollTop: $uploadWrap.offset().top - 100
|
|
|
|
|
- }, 400);
|
|
|
|
|
|
|
+ // ==========================================
|
|
|
|
|
+ // Restore session state on page load
|
|
|
|
|
+ // ==========================================
|
|
|
|
|
+ if (typeof studiouWcfppSession !== 'undefined' && studiouWcfppSession.attachment_id) {
|
|
|
|
|
+ uploadedAttachmentId = studiouWcfppSession.attachment_id;
|
|
|
|
|
+ uploadedFileRecordId = studiouWcfppSession.file_record_id;
|
|
|
|
|
+ showPreview(studiouWcfppSession.thumbnail_url, studiouWcfppSession.file_name);
|
|
|
|
|
+ updateProductGallery(studiouWcfppSession.preview_url || studiouWcfppSession.thumbnail_url);
|
|
|
|
|
+ enableAddToCart();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Reset upload after successful WC add-to-cart
|
|
|
|
|
- $(document.body).on('added_to_cart', function () {
|
|
|
|
|
- resetUpload();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
|
|
+ // ==========================================
|
|
|
// Drag and drop
|
|
// Drag and drop
|
|
|
|
|
+ // ==========================================
|
|
|
$dropzone.on('dragover dragenter', function (e) {
|
|
$dropzone.on('dragover dragenter', function (e) {
|
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
|
e.stopPropagation();
|
|
e.stopPropagation();
|
|
@@ -109,10 +151,11 @@
|
|
|
removeUploadedFile();
|
|
removeUploadedFile();
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+ // ==========================================
|
|
|
|
|
+ // Upload logic
|
|
|
|
|
+ // ==========================================
|
|
|
function handleFile(file) {
|
|
function handleFile(file) {
|
|
|
- if (isUploading) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (isUploading) return;
|
|
|
|
|
|
|
|
var maxBytes = maxFileSize * 1024 * 1024;
|
|
var maxBytes = maxFileSize * 1024 * 1024;
|
|
|
if (file.size > maxBytes) {
|
|
if (file.size > maxBytes) {
|
|
@@ -149,7 +192,6 @@
|
|
|
formData.append('file_size', file.size);
|
|
formData.append('file_size', file.size);
|
|
|
formData.append('chunk', blob, 'chunk');
|
|
formData.append('chunk', blob, 'chunk');
|
|
|
|
|
|
|
|
- // Last chunk triggers server-side assembly - needs longer timeout
|
|
|
|
|
var isLastChunk = (currentChunk === totalChunks - 1);
|
|
var isLastChunk = (currentChunk === totalChunks - 1);
|
|
|
if (isLastChunk) {
|
|
if (isLastChunk) {
|
|
|
$progressFill.css('width', '100%');
|
|
$progressFill.css('width', '100%');
|
|
@@ -176,7 +218,6 @@
|
|
|
uploadedAttachmentId = response.data.attachment_id;
|
|
uploadedAttachmentId = response.data.attachment_id;
|
|
|
uploadedFileRecordId = response.data.file_record_id;
|
|
uploadedFileRecordId = response.data.file_record_id;
|
|
|
|
|
|
|
|
- // Store in WC session so any add-to-cart button picks it up
|
|
|
|
|
storeInSession(
|
|
storeInSession(
|
|
|
response.data.attachment_id,
|
|
response.data.attachment_id,
|
|
|
response.data.file_record_id,
|
|
response.data.file_record_id,
|
|
@@ -185,6 +226,7 @@
|
|
|
|
|
|
|
|
showPreview(response.data.thumbnail_url, response.data.file_name);
|
|
showPreview(response.data.thumbnail_url, response.data.file_name);
|
|
|
updateProductGallery(response.data.preview_url || response.data.thumbnail_url);
|
|
updateProductGallery(response.data.preview_url || response.data.thumbnail_url);
|
|
|
|
|
+ enableAddToCart();
|
|
|
$progress.hide();
|
|
$progress.hide();
|
|
|
isUploading = false;
|
|
isUploading = false;
|
|
|
} else {
|
|
} else {
|
|
@@ -203,6 +245,9 @@
|
|
|
uploadNextChunk();
|
|
uploadNextChunk();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // ==========================================
|
|
|
|
|
+ // Session management
|
|
|
|
|
+ // ==========================================
|
|
|
function storeInSession(attachmentId, fileRecordId, fileName) {
|
|
function storeInSession(attachmentId, fileRecordId, fileName) {
|
|
|
$.ajax({
|
|
$.ajax({
|
|
|
url: studiouWcfppFront.ajaxUrl,
|
|
url: studiouWcfppFront.ajaxUrl,
|
|
@@ -228,18 +273,12 @@
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function uploadFailed(message) {
|
|
|
|
|
- isUploading = false;
|
|
|
|
|
- $progress.hide();
|
|
|
|
|
- $dropzone.show();
|
|
|
|
|
- showMessage(message, 'error');
|
|
|
|
|
- $fileInput.val('');
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ // ==========================================
|
|
|
|
|
+ // Product gallery image replacement
|
|
|
|
|
+ // ==========================================
|
|
|
function updateProductGallery(imageUrl) {
|
|
function updateProductGallery(imageUrl) {
|
|
|
if (!imageUrl) return;
|
|
if (!imageUrl) return;
|
|
|
|
|
|
|
|
- // Find the main product image (try common WC / theme selectors)
|
|
|
|
|
var selectors = [
|
|
var selectors = [
|
|
|
'.woocommerce-product-gallery__image img',
|
|
'.woocommerce-product-gallery__image img',
|
|
|
'.product .wp-post-image',
|
|
'.product .wp-post-image',
|
|
@@ -257,19 +296,16 @@
|
|
|
|
|
|
|
|
if (!$img || !$img.length) return;
|
|
if (!$img || !$img.length) return;
|
|
|
|
|
|
|
|
- // Save original attributes for restoration
|
|
|
|
|
if (!originalGalleryImages.src) {
|
|
if (!originalGalleryImages.src) {
|
|
|
originalGalleryImages.src = $img.attr('src');
|
|
originalGalleryImages.src = $img.attr('src');
|
|
|
originalGalleryImages.srcset = $img.attr('srcset') || '';
|
|
originalGalleryImages.srcset = $img.attr('srcset') || '';
|
|
|
originalGalleryImages.sizes = $img.attr('sizes') || '';
|
|
originalGalleryImages.sizes = $img.attr('sizes') || '';
|
|
|
- // Also save the parent link href if it's a gallery link
|
|
|
|
|
var $parentLink = $img.closest('a');
|
|
var $parentLink = $img.closest('a');
|
|
|
if ($parentLink.length) {
|
|
if ($parentLink.length) {
|
|
|
originalGalleryImages.href = $parentLink.attr('href');
|
|
originalGalleryImages.href = $parentLink.attr('href');
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Replace with uploaded image
|
|
|
|
|
$img.attr('src', imageUrl);
|
|
$img.attr('src', imageUrl);
|
|
|
$img.removeAttr('srcset');
|
|
$img.removeAttr('srcset');
|
|
|
$img.removeAttr('sizes');
|
|
$img.removeAttr('sizes');
|
|
@@ -301,23 +337,27 @@
|
|
|
if (!$img || !$img.length) return;
|
|
if (!$img || !$img.length) return;
|
|
|
|
|
|
|
|
$img.attr('src', originalGalleryImages.src);
|
|
$img.attr('src', originalGalleryImages.src);
|
|
|
- if (originalGalleryImages.srcset) {
|
|
|
|
|
- $img.attr('srcset', originalGalleryImages.srcset);
|
|
|
|
|
- }
|
|
|
|
|
- if (originalGalleryImages.sizes) {
|
|
|
|
|
- $img.attr('sizes', originalGalleryImages.sizes);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (originalGalleryImages.srcset) $img.attr('srcset', originalGalleryImages.srcset);
|
|
|
|
|
+ if (originalGalleryImages.sizes) $img.attr('sizes', originalGalleryImages.sizes);
|
|
|
|
|
|
|
|
if (originalGalleryImages.href) {
|
|
if (originalGalleryImages.href) {
|
|
|
- var $parentLink = $img.closest('a');
|
|
|
|
|
- if ($parentLink.length) {
|
|
|
|
|
- $parentLink.attr('href', originalGalleryImages.href);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ $img.closest('a').attr('href', originalGalleryImages.href);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
originalGalleryImages = {};
|
|
originalGalleryImages = {};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // ==========================================
|
|
|
|
|
+ // UI helpers
|
|
|
|
|
+ // ==========================================
|
|
|
|
|
+ function uploadFailed(message) {
|
|
|
|
|
+ isUploading = false;
|
|
|
|
|
+ $progress.hide();
|
|
|
|
|
+ $dropzone.show();
|
|
|
|
|
+ showMessage(message, 'error');
|
|
|
|
|
+ $fileInput.val('');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
function showPreview(thumbnailUrl, fileName) {
|
|
function showPreview(thumbnailUrl, fileName) {
|
|
|
if (thumbnailUrl) {
|
|
if (thumbnailUrl) {
|
|
|
$previewImg.attr('src', thumbnailUrl).show();
|
|
$previewImg.attr('src', thumbnailUrl).show();
|
|
@@ -326,12 +366,11 @@
|
|
|
}
|
|
}
|
|
|
$previewName.text(fileName);
|
|
$previewName.text(fileName);
|
|
|
$preview.show();
|
|
$preview.show();
|
|
|
|
|
+ $dropzone.hide();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function removeUploadedFile() {
|
|
function removeUploadedFile() {
|
|
|
- if (!uploadedFileRecordId) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!uploadedFileRecordId) return;
|
|
|
|
|
|
|
|
$.ajax({
|
|
$.ajax({
|
|
|
url: studiouWcfppFront.ajaxUrl,
|
|
url: studiouWcfppFront.ajaxUrl,
|
|
@@ -352,6 +391,7 @@
|
|
|
uploadedFileRecordId = null;
|
|
uploadedFileRecordId = null;
|
|
|
clearSession();
|
|
clearSession();
|
|
|
restoreProductGallery();
|
|
restoreProductGallery();
|
|
|
|
|
+ disableAddToCart();
|
|
|
$preview.hide();
|
|
$preview.hide();
|
|
|
$previewImg.attr('src', '');
|
|
$previewImg.attr('src', '');
|
|
|
$previewName.text('');
|
|
$previewName.text('');
|