Progress bar and song reference/cover metadata

This commit is contained in:
riversedge
2026-02-04 20:40:38 -05:00
parent 16f5af6435
commit b75bea3860
8 changed files with 167 additions and 24 deletions
+6 -6
View File
@@ -107,7 +107,7 @@ router.get('/', authMiddleware, async (req: AuthenticatedRequest, res: Response)
const result = await pool.query(
`SELECT s.id, s.title, s.lyrics, s.style, s.caption, s.cover_url, s.audio_url,
s.duration, s.bpm, s.key_scale, s.time_signature, s.tags, s.is_public,
s.like_count, s.view_count, s.user_id, s.created_at,
s.like_count, s.view_count, s.user_id, s.created_at, s.generation_params,
COALESCE(u.username, 'Anonymous') as creator
FROM songs s
LEFT JOIN users u ON s.user_id = u.id
@@ -137,7 +137,7 @@ router.get('/public/featured', optionalAuthMiddleware, async (_req: Authenticate
const result = await pool.query(
`SELECT s.id, s.title, s.lyrics, s.style, s.caption, s.cover_url, s.audio_url,
s.duration, s.bpm, s.key_scale, s.time_signature, s.tags, s.like_count, s.view_count, s.created_at, s.user_id,
COALESCE(u.username, 'Anonymous') as creator, u.avatar_url as creator_avatar
COALESCE(u.username, 'Anonymous') as creator, u.avatar_url as creator_avatar, s.generation_params
FROM songs s
LEFT JOIN users u ON s.user_id = u.id
ORDER BY RANDOM()
@@ -184,7 +184,7 @@ router.get('/public', optionalAuthMiddleware, async (req: AuthenticatedRequest,
const result = await pool.query(
`SELECT s.id, s.title, s.lyrics, s.style, s.caption, s.cover_url, s.audio_url,
s.duration, s.bpm, s.key_scale, s.time_signature, s.tags, s.like_count, s.created_at,
COALESCE(u.username, 'Anonymous') as creator
COALESCE(u.username, 'Anonymous') as creator, s.generation_params
FROM songs s
LEFT JOIN users u ON s.user_id = u.id
WHERE s.is_public = true
@@ -213,7 +213,7 @@ router.get('/:id', optionalAuthMiddleware, async (req: AuthenticatedRequest, res
const result = await pool.query(
`SELECT s.id, s.user_id, s.title, s.lyrics, s.style, s.caption, s.cover_url, s.audio_url,
s.duration, s.bpm, s.key_scale, s.time_signature, s.tags, s.is_public, s.like_count, s.view_count, s.created_at,
COALESCE(u.username, 'Anonymous') as creator, u.avatar_url as creator_avatar
COALESCE(u.username, 'Anonymous') as creator, u.avatar_url as creator_avatar, s.generation_params
FROM songs s
LEFT JOIN users u ON s.user_id = u.id
WHERE s.id = $1`,
@@ -252,7 +252,7 @@ router.get('/:id/full', optionalAuthMiddleware, async (req: AuthenticatedRequest
pool.query(
`SELECT s.id, s.user_id, s.title, s.lyrics, s.style, s.caption, s.cover_url, s.audio_url,
s.duration, s.bpm, s.key_scale, s.time_signature, s.tags, s.is_public,
s.like_count, s.view_count, s.created_at,
s.like_count, s.view_count, s.created_at, s.generation_params,
COALESCE(u.username, 'Anonymous') as creator, u.avatar_url as creator_avatar
FROM songs s
LEFT JOIN users u ON s.user_id = u.id
@@ -496,7 +496,7 @@ router.get('/liked/list', authMiddleware, async (req: AuthenticatedRequest, res:
const result = await pool.query(
`SELECT s.id, s.title, s.lyrics, s.style, s.cover_url, s.audio_url,
s.duration, s.tags, s.like_count, s.created_at, s.is_public,
COALESCE(u.username, 'Anonymous') as creator
COALESCE(u.username, 'Anonymous') as creator, s.generation_params
FROM liked_songs ls
JOIN songs s ON ls.song_id = s.id
LEFT JOIN users u ON s.user_id = u.id
+48 -1
View File
@@ -255,7 +255,12 @@ async function pollApiResult(taskId: string, maxWaitMs = 600000): Promise<ApiTas
return { status: 1, audioPaths, metas };
} else if (taskData.status === 2) {
throw new Error('Generation failed on API side');
const details = taskData.error
|| taskData.message
|| taskData.status_message
|| taskData.result
|| JSON.stringify(taskData);
throw new Error(`Generation failed on API side: ${details}`);
}
// Still processing
@@ -382,6 +387,8 @@ interface JobStatus {
status: 'queued' | 'running' | 'succeeded' | 'failed';
queuePosition?: number;
etaSeconds?: number;
progress?: number;
stage?: string;
result?: GenerationResult;
error?: string;
}
@@ -502,6 +509,7 @@ async function processGeneration(
try {
// Submit to API
const { taskId } = await submitToApi(params);
job.taskId = taskId;
console.log(`Job ${jobId}: Submitted to API as task ${taskId}`);
// Poll for result
@@ -832,6 +840,45 @@ export async function getJobStatus(jobId: string): Promise<JobStatus> {
};
}
if (job.status === 'running' && job.taskId) {
try {
const response = await fetch(`${ACESTEP_API}/query_result`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ task_id_list: [job.taskId] }),
});
if (response.ok) {
const result = await response.json();
const taskData = result.data?.[0];
if (taskData?.result) {
let resultData: unknown = taskData.result;
if (typeof resultData === 'string') {
try {
resultData = JSON.parse(resultData);
} catch {
resultData = null;
}
}
const item = Array.isArray(resultData) ? resultData[0] : resultData;
if (item && typeof item === 'object') {
const progress = typeof (item as any).progress === 'number' ? (item as any).progress : undefined;
const stage = typeof (item as any).stage === 'string' ? (item as any).stage : undefined;
return {
status: job.status,
etaSeconds: Math.max(0, 180 - elapsed),
progress,
stage,
};
}
}
}
} catch {
// ignore progress fetch failures, fall back to ETA only
}
}
return {
status: job.status,
etaSeconds: Math.max(0, 180 - elapsed), // 3 min estimate