0) {
this.$nextTick(() => {
if (typeof $wire !== 'undefined' && $wire && typeof $wire.call === 'function') {
$wire.call('logUploadedFiles', uploadedFiles);
} else if (typeof window.livewire !== 'undefined' && typeof window.livewire.call === 'function') {
window.livewire.call('logUploadedFiles', uploadedFiles);
} else if (typeof Livewire !== 'undefined' && typeof Livewire.call === 'function') {
Livewire.call('logUploadedFiles', uploadedFiles);
} else {
console.warn('Could not call Livewire method logUploadedFiles; Livewire not found.');
}
});
}
if (this.autoCloseTimer) clearTimeout(this.autoCloseTimer);
this.autoCloseTimer = setTimeout(() => {
this.isUploading = false;
this.uploadQueue = [];
}, 1000);
} catch (error) {
console.error('Upload error:', error);
new window.FilamentNotification()
.title('{{ preg_replace("/'/", "\\'", trans('server/file.actions.upload.error')) }}')
.danger()
.send();
this.isUploading = false;
}
},
async uploadFile(index) {
const fileData = this.uploadQueue[index];
fileData.status = 'uploading';
try {
const uploadUrl = await this.fetchUploadUrl();
const url = new URL(uploadUrl);
let basePath = @js($this->path);
if (fileData.path && fileData.path.trim() !== '') {
basePath = basePath.replace(/\/+$/, '') + '/' + fileData.path.replace(/^\/+/, '');
}
url.searchParams.append('directory', basePath);
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
const formData = new FormData();
formData.append('files', fileData.file);
let lastLoaded = 0;
let lastTime = Date.now();
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
fileData.uploadedBytes = e.loaded;
fileData.progress = Math.round((e.loaded / e.total) * 100);
const now = Date.now();
const timeDiff = (now - lastTime) / 1000;
if (timeDiff > 0.1) {
const bytesDiff = e.loaded - lastLoaded;
fileData.speed = bytesDiff / timeDiff;
lastTime = now;
lastLoaded = e.loaded;
}
}
});
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
fileData.status = 'complete';
fileData.progress = 100;
resolve();
} else {
fileData.status = 'error';
fileData.error = `Upload failed (${xhr.status})`;
reject(new Error(fileData.error));
}
};
xhr.onerror = () => {
fileData.status = 'error';
fileData.error = 'Network error';
reject(new Error('Network error'));
};
xhr.open('POST', url.toString());
xhr.send(formData);
});
} catch (err) {
fileData.status = 'error';
fileData.error = 'Failed to get upload token';
throw err;
}
},
formatBytes(bytes) {
if (bytes === 0) return '0.00 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];
},
formatSpeed(bytesPerSecond) {
return this.formatBytes(bytesPerSecond) + '/s';
},
handleEscapeKey(e) {
if (e.key === 'Escape' && this.isUploading) {
this.isUploading = false;
this.uploadQueue = [];
}
},
}"
@dragenter.window="handleDragEnter($event)"
@dragleave.window="handleDragLeave($event)"
@dragover.window="handleDragOver($event)"
@drop.window="handleDrop($event)"
@keydown.window="handleEscapeKey($event)"
class="relative"
>
{{ trans('server/file.actions.upload.drop_files') }}
{{ trans('server/file.actions.upload.header') }} -
of
{{ $this->table }}