{{-- Detail Manager — clique em item, rotação, recorte, confirmação --}} let detailCropperInstance = null; /* Clique em um item da galeria: abre o painel de detalhes */ $(document).on('click', '.gallery-item-' + pickerId, function(e) { $('.gallery-item-' + pickerId).removeClass('selected'); $(this).addClass('selected'); var id = $(this).data('id'); var url = $(this).data('url'); var isImg = $(this).data('is-img') == '1'; /* Fecha cropper inline se estiver aberto */ cancelDetailCrop(); $.get(urls.index, { owner_module: ownerModule, allow_shared: allowShared, allowed_mime_types: filterMimeTypes, archived: viewArchived }, function(data) { var found = null; for (var i = 0; i < data.length; i++) { if (data[i].id == id) { found = data[i]; break; } } if (found) { var isAudio = $(this).data('is-audio') == '1'; var isExcel = found.file_path && (found.file_path.endsWith('.xlsx') || found.file_path.endsWith('.xls') || found.file_path.endsWith('.csv') || found.file_path.endsWith('.ods')); $('#detail-media-id-' + pickerId).val(found.id); $('#detail-media-url-' + pickerId).val(url); $('#detail-media-mime-' + pickerId).val(found.mime_type || ''); $('#detail-media-alt-' + pickerId).val(found.alt_text || ''); $('#detail-media-desc-' + pickerId).val(found.description || ''); /* Oculta todos os previews */ $('#detail-preview-img-' + pickerId).addClass('d-none'); $('#detail-preview-pdf-' + pickerId).addClass('d-none'); $('#detail-preview-audio-' + pickerId).addClass('d-none'); $('#detail-preview-spreadsheet-' + pickerId).addClass('d-none'); $('#detail-image-actions-' + pickerId).addClass('d-none'); /* Link de download */ var downloadUrl = urls.index + '/' + found.id + '/download?owner_module=' + ownerModule; $('#btn-download-detail-' + pickerId).attr('href', downloadUrl); if (isImg) { var cacheBuster = '?t=' + new Date().getTime(); $('#detail-preview-img-' + pickerId).attr('src', url + cacheBuster).removeClass('d-none'); $('#detail-group-alt-' + pickerId).show(); $('#detail-image-actions-' + pickerId).removeClass('d-none'); } else { $('#detail-group-alt-' + pickerId).hide(); $('#detail-image-actions-' + pickerId).addClass('d-none'); if (isAudio) { $('#detail-preview-audio-' + pickerId).removeClass('d-none'); } else if (isExcel) { $('#detail-preview-spreadsheet-' + pickerId).removeClass('d-none'); } else { $('#detail-preview-pdf-' + pickerId).removeClass('d-none'); } } /* Texto do botão arquivar/desarquivar */ if (viewArchived == 1) { $('#btn-archive-detail-' + pickerId).html(' Desarquivar'); } else { $('#btn-archive-detail-' + pickerId).html(' Arquivar'); } $('#gallery-detail-segment-' + pickerId).fadeIn(); } }); }); /* =========== ROTAÇÃO =========== */ $('#btn-detail-rotate-' + pickerId).on('click', function() { var id = $('#detail-media-id-' + pickerId).val(); if (!id) return; showDetailFeedback('Rotacionando imagem...'); $.ajax({ url: urls.index + '/' + id + '/rotate', type: 'POST', data: { owner_module: ownerModule }, success: function() { hideDetailFeedback(); /* Atualiza o preview com cache buster */ var url = $('#detail-media-url-' + pickerId).val(); $('#detail-preview-img-' + pickerId).attr('src', url + '?t=' + new Date().getTime()); if (typeof toastr !== 'undefined') toastr.success('Imagem rotacionada!'); }, error: function() { hideDetailFeedback(); if (typeof toastr !== 'undefined') toastr.error('Erro ao rotacionar imagem.'); } }); }); /* =========== RECORTE =========== */ $('#btn-detail-crop-' + pickerId).on('click', function() { var id = $('#detail-media-id-' + pickerId).val(); if (!id) return; var imgUrl = $('#detail-media-url-' + pickerId).val(); if (!imgUrl) return; /* Destroi cropper anterior se existir */ if (detailCropperInstance) { detailCropperInstance.destroy(); detailCropperInstance = null; } var $cropImage = $('#detail-cropper-image-' + pickerId); $cropImage.attr('src', imgUrl + '?t=' + new Date().getTime()); $('#detail-cropper-wrapper-' + pickerId).slideDown(200, function() { detailCropperInstance = new Cropper($cropImage[0], { viewMode: 1, autoCropArea: 1, responsive: true }); }); }); /* Rotacionar dentro do cropper de recorte */ $('#btn-detail-crop-rotate-' + pickerId).on('click', function() { if (detailCropperInstance) { detailCropperInstance.rotate(90); } }); /* Cancelar recorte */ var cancelDetailCrop = function() { if (detailCropperInstance) { detailCropperInstance.destroy(); detailCropperInstance = null; } $('#detail-cropper-wrapper-' + pickerId).slideUp(200); }; $('#btn-detail-crop-cancel-' + pickerId).on('click', cancelDetailCrop); /* Aplicar Recorte: faz upload do crop como nova mídia e arquiva a antiga */ $('#btn-detail-crop-apply-' + pickerId).on('click', function() { var oldId = $('#detail-media-id-' + pickerId).val(); if (!oldId) return; if (!detailCropperInstance) return; showDetailFeedback('Aplicando recorte...'); detailCropperInstance.getCroppedCanvas().toBlob(function(blob) { /* Cria um File a partir do blob */ var croppedFile = new File([blob], 'cropped_' + new Date().getTime() + '.jpg', { type: 'image/jpeg', lastModified: Date.now() }); var altText = $('#detail-media-alt-' + pickerId).val(); var desc = $('#detail-media-desc-' + pickerId).val(); var formData = new FormData(); formData.append('file', croppedFile); formData.append('owner_module', ownerModule); formData.append('is_shared', '0'); formData.append('file_alt', altText); formData.append('description', desc); formData.append('allowed_mime_types', filterMimeTypes); formData.append('_token', csrfToken); /* 1. Upload do recorte como nova mídia */ $.ajax({ url: urls.store, type: 'POST', data: formData, processData: false, contentType: false, headers: { 'X-CSRF-TOKEN': csrfToken }, success: function(newMedia) { /* 2. Arquiva a mídia antiga */ $.ajax({ url: urls.index + '/' + oldId + '/archive', type: 'POST', data: { owner_module: ownerModule, action: 'archive' }, complete: function() { /* 3. Atualiza o painel com a nova mídia */ var newUrl = '/storage/' + newMedia.file_path; $('#detail-media-id-' + pickerId).val(newMedia.id); $('#detail-media-url-' + pickerId).val(newUrl); $('#detail-media-mime-' + pickerId).val(newMedia.mime_type || ''); $('#detail-preview-img-' + pickerId).attr('src', newUrl + '?t=' + new Date().getTime()); /* Atualiza link de download */ var downloadUrl = urls.index + '/' + newMedia.id + '/download?owner_module=' + ownerModule; $('#btn-download-detail-' + pickerId).attr('href', downloadUrl); /* Recarrega a galeria */ loadGallery(); cancelDetailCrop(); hideDetailFeedback(); if (typeof toastr !== 'undefined') toastr.success('Recorte aplicado!'); } }); }, error: function() { hideDetailFeedback(); if (typeof toastr !== 'undefined') toastr.error('Erro ao aplicar recorte.'); } }); }, 'image/jpeg'); }); /* =========== CONFIRMAR ESCOLHA (salva metadados + callback) =========== */ $('#btn-confirm-selection-' + pickerId).on('click', function() { var id = $('#detail-media-id-' + pickerId).val(); var altText = $('#detail-media-alt-' + pickerId).val(); var desc = $('#detail-media-desc-' + pickerId).val(); var url = $('#detail-media-url-' + pickerId).val(); var mimeType = $('#detail-media-mime-' + pickerId).val(); /* Fecha cropper se estiver aberto */ cancelDetailCrop(); /* Salva metadados e retorna a mídia */ $.ajax({ url: urls.index + '/' + id, type: 'PUT', data: { owner_module: ownerModule, alt_text: altText, description: desc }, complete: function() { selectMedia(id, url, altText, mimeType, desc); } }); }); /* =========== CANCELAR =========== */ $('#btn-cancel-detail-' + pickerId).on('click', function() { cancelDetailCrop(); $('#gallery-detail-segment-' + pickerId).fadeOut(); $('.gallery-item-' + pickerId).removeClass('selected'); }); /* =========== ARQUIVAR / DESARQUIVAR =========== */ $('#btn-archive-detail-' + pickerId).on('click', function() { var id = $('#detail-media-id-' + pickerId).val(); var action = viewArchived == 1 ? 'restore' : 'archive'; if (!confirm('Deseja realmente ' + (action === 'restore' ? 'desarquivar' : 'arquivar') + ' esta mídia?')) return; $.ajax({ url: urls.index + '/' + id + '/archive', type: 'POST', data: { owner_module: ownerModule, action: action }, success: function() { if (typeof toastr !== 'undefined') toastr.success('Mídia ' + (action === 'restore' ? 'desarquivada' : 'arquivada') + ' com sucesso!'); cancelDetailCrop(); $('#gallery-detail-segment-' + pickerId).hide(); loadGallery(); }, error: function() { if (typeof toastr !== 'undefined') toastr.error('Erro ao processar arquivamento.'); } }); }); /* =========== HELPERS =========== */ var showDetailFeedback = function(text) { $('#detail-operating-text-' + pickerId).text(text); $('#detail-operating-feedback-' + pickerId).removeClass('d-none'); }; var hideDetailFeedback = function() { $('#detail-operating-feedback-' + pickerId).addClass('d-none'); };