diff --git a/frontend/js/views/playlists.js b/frontend/js/views/playlists.js
index 7295dbf..cf001a3 100644
--- a/frontend/js/views/playlists.js
+++ b/frontend/js/views/playlists.js
@@ -294,7 +294,7 @@ function renderItems(items) {
}
itemsEl.innerHTML = items.map((item, i) => `
-
+
${i + 1}
${item.thumbnail_path
@@ -311,9 +311,17 @@ function renderItems(items) {
sec
-
+
`).join('');
@@ -348,6 +356,28 @@ function renderItems(items) {
});
});
+ // Up/down reorder (touch-friendly alternative to drag)
+ itemsEl.querySelectorAll('.item-move').forEach(btn => {
+ btn.addEventListener('click', async (e) => {
+ if (btn.disabled) return;
+ const itemId = parseInt(e.currentTarget.dataset.itemId, 10);
+ const dir = e.currentTarget.dataset.dir;
+ const order = Array.from(itemsEl.querySelectorAll('.playlist-item'))
+ .map(el => parseInt(el.dataset.itemId, 10));
+ const idx = order.indexOf(itemId);
+ const swap = dir === 'up' ? idx - 1 : idx + 1;
+ if (swap < 0 || swap >= order.length) return;
+ [order[idx], order[swap]] = [order[swap], order[idx]];
+ try {
+ const updated = await api.reorderPlaylistItems(currentPlaylistId, order);
+ renderItems(updated);
+ refreshAfterMutation();
+ } catch (err) {
+ showToast(err.message, 'error');
+ }
+ });
+ });
+
// Drag-to-reorder
setupDragReorder(itemsEl);
}