// GigLez - Upload Functionality
let selectedFiles = [];
// Initialize upload functionality
document.addEventListener('DOMContentLoaded', () => {
setupDropZone();
setupFileInput();
});
function setupDropZone() {
const dropZone = document.getElementById('drop-zone');
dropZone.addEventListener('click', () => {
document.getElementById('file-input').click();
});
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('drag-over');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('drag-over');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('drag-over');
const files = Array.from(e.dataTransfer.files).filter(f => f.name.endsWith('.sub'));
addFiles(files);
});
}
function setupFileInput() {
const fileInput = document.getElementById('file-input');
fileInput.addEventListener('change', (e) => {
const files = Array.from(e.target.files);
addFiles(files);
});
}
function addFiles(files) {
if (files.length === 0) {
alert('Please select .sub files');
return;
}
// Add new files
selectedFiles.push(...files);
// Show file list
document.getElementById('file-list').style.display = 'block';
// Render file list
renderFileList();
}
function renderFileList() {
const container = document.getElementById('files-container');
container.innerHTML = selectedFiles.map((file, index) => `
${file.name}
${formatFileSize(file.size)}
`).join('');
}
function removeFile(index) {
selectedFiles.splice(index, 1);
if (selectedFiles.length === 0) {
document.getElementById('file-list').style.display = 'none';
} else {
renderFileList();
}
}
function clearFiles() {
selectedFiles = [];
document.getElementById('file-list').style.display = 'none';
document.getElementById('file-input').value = '';
}
async function uploadFiles() {
if (selectedFiles.length === 0) {
alert('Please select files to upload');
return;
}
// Validate GPS coordinates
const lat = parseFloat(document.getElementById('default-lat').value);
const lon = parseFloat(document.getElementById('default-lon').value);
if (isNaN(lat) || isNaN(lon)) {
alert('Please provide valid GPS coordinates');
return;
}
if (lat < -90 || lat > 90 || lon < -180 || lon > 180) {
alert('GPS coordinates out of range');
return;
}
// Hide file list, show progress
document.getElementById('file-list').style.display = 'none';
document.getElementById('upload-progress').style.display = 'block';
try {
// Build manifest
const sessionUuid = document.getElementById('session-uuid').value || generateUUID();
const accuracy = parseFloat(document.getElementById('default-accuracy').value) || 5.0;
const altitude = parseFloat(document.getElementById('default-altitude').value) || null;
const manifest = {
session_uuid: sessionUuid,
captures: selectedFiles.map(file => ({
filename: file.name,
latitude: lat,
longitude: lon,
accuracy: accuracy,
altitude: altitude,
timestamp: new Date().toISOString()
}))
};
// Build FormData
const formData = new FormData();
formData.append('manifest', JSON.stringify(manifest));
selectedFiles.forEach(file => {
formData.append('files', file);
});
// Upload
updateProgress(0, 'Uploading files...');
const response = await fetch('/api/v1/captures/upload', {
method: 'POST',
body: formData
});
updateProgress(100, 'Processing...');
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Upload failed');
}
const result = await response.json();
// Show results
showUploadResults(result);
} catch (error) {
console.error('Upload error:', error);
alert(`Upload failed: ${error.message}`);
// Reset
document.getElementById('upload-progress').style.display = 'none';
document.getElementById('file-list').style.display = 'block';
}
}
function updateProgress(percent, text) {
document.getElementById('progress-fill').style.width = `${percent}%`;
document.getElementById('progress-text').textContent = text;
}
function showUploadResults(result) {
// Hide progress
document.getElementById('upload-progress').style.display = 'none';
// Show results
const resultsDiv = document.getElementById('upload-results');
const container = document.getElementById('results-container');
resultsDiv.style.display = 'block';
const successCount = result.successful?.length || 0;
const errorCount = result.failed?.length || 0;
let html = `
Successfully uploaded: ${successCount} files
${errorCount > 0 ? `
Failed: ${errorCount} files
` : ''}
`;
if (result.successful && result.successful.length > 0) {
html += 'Successful Uploads:
';
result.successful.forEach(item => {
html += `
${item.filename}
Frequency: ${(item.frequency / 1e6).toFixed(2)} MHz |
Protocol: ${item.protocol || 'RAW'}
`;
});
}
if (result.failed && result.failed.length > 0) {
html += 'Failed Uploads:
';
result.failed.forEach(item => {
html += `
${item.filename}
Error: ${item.error}
`;
});
}
container.innerHTML = html;
}
function resetUpload() {
// Hide results
document.getElementById('upload-results').style.display = 'none';
// Clear files
clearFiles();
// Reset form
document.getElementById('default-lat').value = '';
document.getElementById('default-lon').value = '';
document.getElementById('session-uuid').value = '';
}
function useCurrentLocation() {
if (!navigator.geolocation) {
alert('Geolocation is not supported by your browser');
return;
}
navigator.geolocation.getCurrentPosition(
(position) => {
document.getElementById('default-lat').value = position.coords.latitude.toFixed(6);
document.getElementById('default-lon').value = position.coords.longitude.toFixed(6);
document.getElementById('default-accuracy').value = position.coords.accuracy.toFixed(1);
if (position.coords.altitude) {
document.getElementById('default-altitude').value = position.coords.altitude.toFixed(1);
}
},
(error) => {
alert(`Geolocation error: ${error.message}`);
}
);
}
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function formatFileSize(bytes) {
if (bytes < 1024) return bytes + ' B';
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
}