diff --git a/src/class-tiny-plugin.php b/src/class-tiny-plugin.php index 735d8328..a6b7d067 100644 --- a/src/class-tiny-plugin.php +++ b/src/class-tiny-plugin.php @@ -210,7 +210,6 @@ public function admin_init() { $this->tiny_compatibility(); - add_thickbox(); Tiny_Logger::init(); } @@ -984,6 +983,7 @@ public static function uninstall() { public function restore_backup_image() { $response = $this->validate_ajax_attachment_request(); if ( isset( $response['error'] ) ) { + status_header( 400 ); echo esc_html( $response['error'] ); exit(); } @@ -992,6 +992,7 @@ public function restore_backup_image() { $tiny_image = new Tiny_Image( $this->settings, $id, $metadata ); if ( ! $tiny_image->restore_backup() ) { + status_header( 500 ); echo esc_html__( 'Could not restore backup. The backup file may not exist or could not be written.', 'tiny-compress-images' diff --git a/src/css/admin.css b/src/css/admin.css index bad18a87..cfaa00ba 100644 --- a/src/css/admin.css +++ b/src/css/admin.css @@ -444,10 +444,6 @@ input[type=number][name*="tinypng_resize_original"] { padding: 8px 10px; } -.tiny-compress-images .modal { - display: none; -} - .tiny-compress-images h4 { margin: 5px 0; } @@ -490,6 +486,36 @@ fieldset.tinypng_convert_fields[disabled] { box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3); } +.tiny-dialog::backdrop { + background: rgba(0, 0, 0, 0.7); +} + +.tiny-details-dialog { + box-sizing: border-box; + width: min(700px, calc(100vw - 32px)); + max-height: calc(100vh - 64px); + overflow: auto; + text-align: left; + white-space: normal; +} + +.tiny-dialog-header { + display: flex; + justify-content: space-between; + align-items: center; + gap: 10px; +} + +.tiny-dialog-close { + color: #646970; + cursor: pointer; +} + +.tiny-dialog-close:hover, +.tiny-dialog-close:focus { + color: #135e96; +} + .tiny-dialog-error { color: #dc3232; } @@ -500,6 +526,11 @@ fieldset.tinypng_convert_fields[disabled] { justify-content: flex-end; } +/* Overrides .tiny-compress-images span.spinner; admin.js shows it while busy. */ +.tiny-dialog-actions span.spinner { + visibility: hidden; +} + .tiny-dialog-title { font-size: 1.3rem; } diff --git a/src/js/admin.js b/src/js/admin.js index 9f4ccdbe..9430368e 100644 --- a/src/js/admin.js +++ b/src/js/admin.js @@ -13,69 +13,57 @@ jQuery(document).on('click', 'a[data-dialog-id]', function (e) { e.preventDefault(); - const trigger = jQuery(e.currentTarget); - const dialogID = trigger.data('dialog-id'); - if (!dialogID) { - return; + const dialog = document.getElementById(jQuery(e.currentTarget).data('dialog-id')); + if (dialog) { + dialog.showModal(); } + }); + + jQuery(document).on('click', '[data-dialog-close]', function (e) { + e.currentTarget.closest('dialog').close(); + }); - const dialog = document.getElementById(dialogID); - if (!dialog) { + jQuery(document).on('click', 'dialog.tiny-dialog', function (e) { + const dialog = e.currentTarget; + if (e.target !== dialog) { return; } + const rect = dialog.getBoundingClientRect(); + const inside = e.clientX >= rect.left && e.clientX <= rect.right && + e.clientY >= rect.top && e.clientY <= rect.bottom; + if (!inside) { + dialog.close(); + } + }); - const attachmentId = trigger.data('id'); - const container = document.querySelector(`[data-tiny-media-id="${attachmentId}"]`); - const confirmButton = dialog.querySelector('button[value="submit"]'); - - dialog.showModal(); - - if (confirmButton) { - let restoring = false; - confirmButton.onclick = async () => { - if (restoring) { - return; - } - restoring = true; - confirmButton.disabled = true; - - const spinner = dialog.querySelector('.spinner'); - let allowRetry = false; - try { - if (spinner) { - spinner.style.visibility = 'visible'; - } - const result = await restoreBackup(attachmentId); - dialog.close(); - - // refresh thickbox - const modal = container.querySelector('.modal'); - const ajaxContent = document.getElementById('TB_ajaxContent'); - if (modal && ajaxContent) { - modal.append(...ajaxContent.children); - } + jQuery(document).on('click', '.tiny-restore-dialog button[value="submit"]', async function (e) { + const confirmButton = e.currentTarget; + const dialog = confirmButton.closest('dialog'); + const detailsDialog = dialog.parentElement.closest('dialog'); + const container = dialog.closest('.tiny-ajax-container'); + const spinner = dialog.querySelector('.spinner'); - container.innerHTML = result; - if (typeof tb_remove === 'function') { - tb_remove(); - } - } catch (err) { - allowRetry = true; - const errorEl = dialog.querySelector('.tiny-dialog-error'); - if (errorEl) { - errorEl.textContent = err.responseText || 'Failed to restore backup.'; - errorEl.hidden = false; - } - } finally { - restoring = false; - if (allowRetry) { - confirmButton.disabled = false; - } - if (spinner) { - spinner.style.visibility = 'hidden'; - } - } - }; + confirmButton.disabled = true; + if (spinner) { + spinner.style.visibility = 'visible'; + } + try { + const result = await restoreBackup(container.dataset.tinyMediaId); + dialog.close(); + if (detailsDialog) { + detailsDialog.close(); + } + container.innerHTML = result; + } catch (err) { + const errorEl = dialog.querySelector('.tiny-dialog-error'); + if (errorEl) { + errorEl.textContent = err.responseText || 'Failed to restore backup.'; + errorEl.hidden = false; + } + confirmButton.disabled = false; + if (spinner) { + spinner.style.visibility = 'hidden'; + } } }); diff --git a/src/views/compress-details-backup.php b/src/views/compress-details-backup.php index f589eab0..4c5beb8a 100644 --- a/src/views/compress-details-backup.php +++ b/src/views/compress-details-backup.php @@ -22,18 +22,18 @@
- + -