feat: Add database migrations and auth system
- Add Alembic for database migrations - Implement user authentication system - Update frontend styles and components - Add new test audio functionality - Update stream management and UI
This commit is contained in:
125
static/upload.js
125
static/upload.js
@ -78,6 +78,22 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
dropzone.classList.remove("uploading");
|
||||
showToast("✅ Upload successful.");
|
||||
|
||||
// Refresh the audio player and file list
|
||||
const uid = localStorage.getItem("uid");
|
||||
if (uid) {
|
||||
try {
|
||||
if (window.loadProfileStream) {
|
||||
await window.loadProfileStream(uid);
|
||||
}
|
||||
// Refresh the file list
|
||||
if (window.fetchAndDisplayFiles) {
|
||||
await window.fetchAndDisplayFiles(uid);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to refresh:', e);
|
||||
}
|
||||
}
|
||||
|
||||
playBeep(432, 0.25, "sine");
|
||||
} else {
|
||||
streamInfo.hidden = true;
|
||||
@ -95,8 +111,115 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
};
|
||||
|
||||
// Export the upload function for use in other modules
|
||||
// Function to fetch and display uploaded files
|
||||
async function fetchAndDisplayFiles(uid) {
|
||||
console.log('[DEBUG] fetchAndDisplayFiles called with uid:', uid);
|
||||
const fileList = document.getElementById('file-list');
|
||||
if (!fileList) {
|
||||
const errorMsg = 'File list element not found in DOM';
|
||||
console.error(errorMsg);
|
||||
return showErrorInUI(errorMsg);
|
||||
}
|
||||
|
||||
// Show loading state
|
||||
fileList.innerHTML = '<div style="padding: 10px; color: #888; font-style: italic;">Loading files...</div>';
|
||||
|
||||
try {
|
||||
console.log(`[DEBUG] Fetching files for user: ${uid}`);
|
||||
const response = await fetch(`/me/${uid}`);
|
||||
console.log('[DEBUG] Response status:', response.status, response.statusText);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
const errorMsg = `Failed to fetch files: ${response.status} ${response.statusText} - ${errorText}`;
|
||||
console.error(`[ERROR] ${errorMsg}`);
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('[DEBUG] Received files data:', data);
|
||||
|
||||
if (!data.files) {
|
||||
throw new Error('Invalid response format: missing files array');
|
||||
}
|
||||
|
||||
if (data.files.length > 0) {
|
||||
// Sort files by name
|
||||
const sortedFiles = [...data.files].sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
fileList.innerHTML = sortedFiles.map(file => {
|
||||
const sizeMB = (file.size / (1024 * 1024)).toFixed(2);
|
||||
const displayName = file.original_name || file.name;
|
||||
const isRenamed = file.original_name && file.original_name !== file.name;
|
||||
return `
|
||||
<div style="display: flex; justify-content: space-between; padding: 3px 0; border-bottom: 1px solid #2a2a2a;">
|
||||
<div style="flex: 1; min-width: 0;">
|
||||
<div style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;" title="${displayName}">
|
||||
${displayName}
|
||||
${isRenamed ? `<div style="font-size: 0.8em; color: #888; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;" title="Stored as: ${file.name}">${file.name}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
<span style="color: #888; white-space: nowrap; margin-left: 10px;">${sizeMB} MB</span>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
} else {
|
||||
fileList.innerHTML = '<div style="padding: 5px 0; color: #888; font-style: italic;">No files uploaded yet</div>';
|
||||
}
|
||||
|
||||
// Update quota display if available
|
||||
if (data.quota !== undefined) {
|
||||
const bar = document.getElementById('quota-bar');
|
||||
const text = document.getElementById('quota-text');
|
||||
const quotaSec = document.getElementById('quota-meter');
|
||||
if (bar && text && quotaSec) {
|
||||
quotaSec.hidden = false;
|
||||
bar.value = data.quota;
|
||||
bar.max = 100;
|
||||
text.textContent = `${data.quota.toFixed(1)} MB used`;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = `Error loading file list: ${error.message || 'Unknown error'}`;
|
||||
console.error('[ERROR]', errorMessage, error);
|
||||
showErrorInUI(errorMessage, fileList);
|
||||
}
|
||||
|
||||
// Helper function to show error messages in the UI
|
||||
function showErrorInUI(message, targetElement = null) {
|
||||
const errorHtml = `
|
||||
<div style="
|
||||
padding: 10px;
|
||||
margin: 5px 0;
|
||||
background: #2a0f0f;
|
||||
border-left: 3px solid #f55;
|
||||
color: #ff9999;
|
||||
font-family: monospace;
|
||||
font-size: 0.9em;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
">
|
||||
<div style="font-weight: bold; color: #f55;">Error loading files</div>
|
||||
<div style="margin-top: 5px;">${message}</div>
|
||||
<div style="margin-top: 10px; font-size: 0.8em; color: #888;">
|
||||
Check browser console for details
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
if (targetElement) {
|
||||
targetElement.innerHTML = errorHtml;
|
||||
} else {
|
||||
// If no target element, try to find it
|
||||
const fileList = document.getElementById('file-list');
|
||||
if (fileList) fileList.innerHTML = errorHtml;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export functions for use in other modules
|
||||
window.upload = upload;
|
||||
window.fetchAndDisplayFiles = fetchAndDisplayFiles;
|
||||
|
||||
if (dropzone && fileInput) {
|
||||
dropzone.addEventListener("click", () => {
|
||||
|
Reference in New Issue
Block a user