| @@ -45,9 +45,12 @@ | ||
| 45 | 45 | } ).then( function() { |
| 46 | 46 | location.reload(); |
| 47 | 47 | } ); |
| 48 | 48 | } |
| 49 | - | |
| 49 | + } ) | |
| 50 | + .always( function() { | |
| 51 | + // Always release the lock, even when the request was aborted or failed, | |
| 52 | + // so a following blur can trigger a fresh check instead of staying stuck. | |
| 50 | 53 | busy = false; |
| 51 | 54 | } ); |
| 52 | 55 | } ); |
| 53 | 56 | |
| @@ -515,9 +518,9 @@ | ||
| 515 | 518 | /* |
| 516 | 519 | * Init. |
| 517 | 520 | */ |
| 518 | 521 | init: function () { |
| 519 | - var processed, progress; | |
| 522 | + var progress; | |
| 520 | 523 | this.$missingWebpElement = $('.generate-missing-webp'); |
| 521 | 524 | this.$missingWebpMessage = $('.generate-missing-webp p'); |
| 522 | 525 | |
| 523 | 526 | this.$button = $( '#imagify-generate-webp-versions' ); |
| @@ -555,12 +558,11 @@ | ||
| 555 | 558 | w.imagify.beat.disableSuspend(); |
| 556 | 559 | |
| 557 | 560 | this.$missingWebpMessage.hide().attr('aria-hidden', 'true'); |
| 558 | 561 | |
| 559 | - processed = imagifyOptions.bulk.progress_next_gen.total - imagifyOptions.bulk.progress_next_gen.remaining; | |
| 560 | - progress = Math.floor( processed / imagifyOptions.bulk.progress_next_gen.total * 100 ); | |
| 561 | - this.$progressBar.css( 'width', progress + '%' ); | |
| 562 | - this.$progressText.text( processed + '/' + imagifyOptions.bulk.progress_next_gen.total ); | |
| 562 | + progress = this.getProgress( imagifyOptions.bulk.progress_next_gen.total, imagifyOptions.bulk.progress_next_gen.remaining ); | |
| 563 | + this.$progressBar.css( 'width', progress.percent + '%' ); | |
| 564 | + this.$progressText.text( progress.processed + '/' + progress.total ); | |
| 563 | 565 | |
| 564 | 566 | this.$progressWrap.slideDown().attr( 'aria-hidden', 'false' ).removeClass( 'hidden' ); |
| 565 | 567 | } |
| 566 | 568 | }, |
| @@ -622,8 +624,28 @@ | ||
| 622 | 624 | data[ imagifyOptions.bulk.imagifybeatIDs.progress ] = imagifyOptions.bulk.contexts; |
| 623 | 625 | }, |
| 624 | 626 | |
| 625 | 627 | /** |
| 628 | + * Compute a display-safe progress state. | |
| 629 | + * | |
| 630 | + * `total` is a snapshot taken when the run started, while `remaining` is recounted on | |
| 631 | + * every Imagifybeat tick. Anything that grows the workload mid-run pushes `remaining` | |
| 632 | + * above `total`: uploading new media while the run is in progress, or switching the | |
| 633 | + * Next-Gen format so that every media is suddenly missing one. `total - remaining` then | |
| 634 | + * rendered as a negative count, and a snapshot of 0 divided by zero on top of that. | |
| 635 | + * | |
| 636 | + * Track the largest workload seen instead, so the count never goes negative and the | |
| 637 | + * denominator reflects what is actually left to do. | |
| 638 | + * | |
| 639 | + * @param {number} total Number of media to process when the run started. | |
| 640 | + * @param {number} remaining Number of media still waiting to be processed. | |
| 641 | + * @return {object} Object with `processed`, `total` and `percent` keys. | |
| 642 | + */ | |
| 643 | + getProgress: function ( total, remaining ) { | |
| 644 | + return w.imagify.getProgress( total, remaining ); | |
| 645 | + }, | |
| 646 | + | |
| 647 | + /** | |
| 626 | 648 | * Listen for the custom event "imagifybeat-tick" on $(document). |
| 627 | 649 | * It allows to update various data periodically. |
| 628 | 650 | * |
| 629 | 651 | * @param {object} e Event object. |
| @@ -629,9 +651,9 @@ | ||
| 629 | 651 | * @param {object} e Event object. |
| 630 | 652 | * @param {object} data Object containing all Imagifybeat IDs. |
| 631 | 653 | */ |
| 632 | 654 | processQueueImagifybeat: function ( e, data ) { |
| 633 | - var images_status, processed, progress; | |
| 655 | + var images_status, progress; | |
| 634 | 656 | |
| 635 | 657 | if ( e.data.imagifyOptionsBulk && typeof data[ imagifyOptions.bulk.imagifybeatIDs.progress ] === 'undefined' ) { |
| 636 | 658 | return; |
| 637 | 659 | } |
| @@ -647,12 +669,11 @@ | ||
| 647 | 669 | e.data.imagifyOptionsBulk.processFinished(); |
| 648 | 670 | return; |
| 649 | 671 | } |
| 650 | 672 | |
| 651 | - processed = images_status.total - images_status.remaining; | |
| 652 | - progress = Math.floor( processed / images_status.total * 100 ); | |
| 653 | - e.data.imagifyOptionsBulk.$progressBar.css( 'width', progress + '%' ); | |
| 654 | - e.data.imagifyOptionsBulk.$progressText.text( processed + '/' + images_status.total ); | |
| 673 | + progress = e.data.imagifyOptionsBulk.getProgress( images_status.total, images_status.remaining ); | |
| 674 | + e.data.imagifyOptionsBulk.$progressBar.css( 'width', progress.percent + '%' ); | |
| 675 | + e.data.imagifyOptionsBulk.$progressText.text( progress.processed + '/' + progress.total ); | |
| 655 | 676 | }, |
| 656 | 677 | |
| 657 | 678 | /** |
| 658 | 679 | * Add a Imagifybeat ID for requirements on "imagifybeat-send" event. |