Add file rename functionality and improve preview handling
- Implement file/folder rename feature with dialog and API endpoint - Add rename button to file browser with keyboard shortcuts - Switch PDF preview from object to embed tag for better compatibility - Fix CORS issues by fetching preview files as blobs with object URLs - Add proper cleanup for object URLs to prevent memory leaks - Add renameObject utility function for MinIO operations
This commit is contained in:
@@ -50,16 +50,12 @@
|
||||
|
||||
<!-- PDF Preview -->
|
||||
<div v-else-if="isPdf" class="pdf-preview-container">
|
||||
<object
|
||||
:data="previewUrl"
|
||||
<embed
|
||||
:src="previewUrl"
|
||||
type="application/pdf"
|
||||
width="100%"
|
||||
height="100%"
|
||||
@load="loading = false"
|
||||
@error="handlePreviewError"
|
||||
>
|
||||
<p>PDF preview is not available. <a :href="previewUrl" target="_blank">Click here to view the PDF</a>.</p>
|
||||
</object>
|
||||
/>
|
||||
</div>
|
||||
</v-card-text>
|
||||
|
||||
@@ -86,7 +82,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { ref, computed, watch, onUnmounted } from 'vue';
|
||||
|
||||
interface FileItem {
|
||||
name: string;
|
||||
@@ -114,6 +110,7 @@ const emit = defineEmits<Emits>();
|
||||
const loading = ref(false);
|
||||
const error = ref('');
|
||||
const previewUrl = ref('');
|
||||
const objectUrl = ref('');
|
||||
|
||||
// Computed property for v-model binding
|
||||
const isOpen = computed({
|
||||
@@ -156,19 +153,39 @@ const loadPreview = async () => {
|
||||
error.value = '';
|
||||
previewUrl.value = '';
|
||||
|
||||
// Clean up previous object URL if exists
|
||||
if (objectUrl.value) {
|
||||
URL.revokeObjectURL(objectUrl.value);
|
||||
objectUrl.value = '';
|
||||
}
|
||||
|
||||
try {
|
||||
// For images and PDFs, use the proxy endpoint to avoid CORS issues
|
||||
// For images and PDFs, fetch as blob and create object URL
|
||||
if (isImage.value || isPdf.value) {
|
||||
// Use the proxy endpoint that serves the file directly
|
||||
const proxyUrl = `/api/files/proxy-preview?fileName=${encodeURIComponent(props.file.name)}`;
|
||||
console.log('Setting preview URL to:', proxyUrl);
|
||||
previewUrl.value = proxyUrl;
|
||||
// The loading state will be handled by the image/iframe onload event
|
||||
// Fetch the file as a blob
|
||||
const response = await fetch(`/api/files/proxy-preview?fileName=${encodeURIComponent(props.file.name)}`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch file');
|
||||
}
|
||||
|
||||
const blob = await response.blob();
|
||||
|
||||
// Create object URL from blob
|
||||
objectUrl.value = URL.createObjectURL(blob);
|
||||
previewUrl.value = objectUrl.value;
|
||||
|
||||
console.log('Created object URL for preview:', objectUrl.value);
|
||||
|
||||
// Set loading to false after a short delay to allow the component to render
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
}, 100);
|
||||
} else {
|
||||
throw new Error('File type does not support preview');
|
||||
}
|
||||
} catch (err: any) {
|
||||
error.value = err.data?.statusMessage || err.message || 'Failed to load preview';
|
||||
error.value = err.message || 'Failed to load preview';
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
@@ -201,7 +218,20 @@ const closeModal = () => {
|
||||
isOpen.value = false;
|
||||
previewUrl.value = '';
|
||||
error.value = '';
|
||||
|
||||
// Clean up object URL
|
||||
if (objectUrl.value) {
|
||||
URL.revokeObjectURL(objectUrl.value);
|
||||
objectUrl.value = '';
|
||||
}
|
||||
};
|
||||
|
||||
// Clean up on unmount
|
||||
onUnmounted(() => {
|
||||
if (objectUrl.value) {
|
||||
URL.revokeObjectURL(objectUrl.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user