fix reordering

This commit is contained in:
2025-12-12 22:26:14 -08:00
parent 6ff150cfef
commit 706f277fd3
8 changed files with 473 additions and 58 deletions

View File

@@ -102,6 +102,40 @@ router.post('/skip', async (req, res) => {
}
});
// Go to previous track
router.post('/previous', async (req, res) => {
try {
const response = await fetch(`${req.app.locals.botUrl}/previous`, { method: 'POST' });
const result = await response.json();
// Get updated state immediately and broadcast
try {
const stateResponse = await fetch(`${req.app.locals.botUrl}/state`);
const state = await stateResponse.json();
if (state.currentTrack) {
req.app.locals.broadcast('trackChange', {
track: state.currentTrack,
queueLength: state.queueLength
});
}
req.app.locals.broadcast('playbackUpdate', {
state: state.state,
position: state.position,
volume: state.volume
});
} catch (broadcastError) {
// Polling will catch it
}
res.json(result);
} catch (error) {
req.app.locals.logger.error(`Error going to previous track: ${error.message}`);
res.status(500).json({ error: 'Failed to go to previous track' });
}
});
// Set volume
router.post('/volume', async (req, res) => {
try {

View File

@@ -2,13 +2,13 @@ import express from 'express';
const router = express.Router();
// Get current queue
// Get current queue (full library in playback order)
router.get('/', async (req, res) => {
try {
const response = await fetch(`${req.app.locals.botUrl}/state`);
const state = await response.json();
res.json({
tracks: state.queue || [],
tracks: state.fullQueue || [],
currentTrack: state.currentTrack,
shuffled: state.shuffled || false
});
@@ -33,4 +33,41 @@ router.post('/shuffle', async (req, res) => {
}
});
// Reorder queue
router.post('/reorder', async (req, res) => {
try {
const { from, to } = req.body;
const response = await fetch(`${req.app.locals.botUrl}/queue/reorder`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ from, to })
});
const result = await response.json();
req.app.locals.broadcast('queueUpdate', { queue: result.queue });
res.json(result);
} catch (error) {
req.app.locals.logger.error(`Error reordering queue: ${error.message}`);
res.status(500).json({ error: 'Failed to reorder queue' });
}
});
// Add track to queue
router.post('/add', async (req, res) => {
try {
const { trackId } = req.body;
const response = await fetch(`${req.app.locals.botUrl}/queue/add`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ trackId })
});
const result = await response.json();
req.app.locals.broadcast('queueUpdate', { queue: result.queue });
res.json(result);
} catch (error) {
req.app.locals.logger.error(`Error adding to queue: ${error.message}`);
res.status(500).json({ error: 'Failed to add to queue' });
}
});
export default router;

View File

@@ -74,7 +74,8 @@ router.get('/', async (req, res) => {
title: file.replace('.mp3', ''),
artist: 'Unknown',
album: '',
duration: 0
duration: 0,
hasArt: false
};
try {
@@ -83,7 +84,8 @@ router.get('/', async (req, res) => {
title: parsed.common.title || metadata.title,
artist: parsed.common.artist || metadata.artist,
album: parsed.common.album || '',
duration: Math.floor(parsed.format.duration || 0)
duration: Math.floor(parsed.format.duration || 0),
hasArt: parsed.common.picture && parsed.common.picture.length > 0
};
} catch (error) {
// Use defaults if metadata parsing fails
@@ -94,7 +96,6 @@ router.get('/', async (req, res) => {
filename: file,
filepath: file,
...metadata,
hasArt: false,
size: stats.size
});
}
@@ -106,6 +107,31 @@ router.get('/', async (req, res) => {
}
});
// Get album art for a track
router.get('/:id/art', async (req, res) => {
try {
const filepath = path.join(MUSIC_DIRECTORY, req.params.id);
if (!fs.existsSync(filepath)) {
return res.status(404).json({ error: 'Track not found' });
}
const parsed = await parseFile(filepath);
if (!parsed.common.picture || parsed.common.picture.length === 0) {
return res.status(404).json({ error: 'No album art found' });
}
const picture = parsed.common.picture[0];
res.set('Content-Type', picture.format || 'image/jpeg');
res.set('Cache-Control', 'public, max-age=86400'); // Cache for 24 hours
res.send(picture.data);
} catch (error) {
req.app.locals.logger.error(`Error getting album art: ${error.message}`);
res.status(500).json({ error: 'Failed to get album art' });
}
});
// Upload tracks
router.post('/upload', upload.array('files', MAX_BATCH_SIZE), async (req, res) => {
const uploaded = [];