Signed-off-by: mbrucedogs <mbrucedogs@gmail.com>

This commit is contained in:
mbrucedogs 2025-07-21 19:15:10 -05:00
parent ca5082e5d3
commit 0f43c8a3d2

View File

@ -80,38 +80,51 @@ export const queueService = {
return { key: nextKey.toString() }; return { key: nextKey.toString() };
}, },
// Remove song from queue // Remove a song from the queue
removeFromQueue: async (controllerName: string, queueItemKey: string) => { removeFromQueue: async (controllerName: string, queueItemKey: string) => {
const queueRef = ref(database, `controllers/${controllerName}/player/queue`); const queueRef = ref(database, `controllers/${controllerName}/player/queue`);
const snapshot = await get(queueRef); const queueSnapshot = await get(queueRef);
if (!snapshot.exists()) return { updates: {} }; if (!queueSnapshot.exists()) {
throw new Error('Queue not found');
}
const queue = snapshot.val(); const queue = queueSnapshot.val();
debugLog('removeFromQueue - original queue:', queue); debugLog('removeFromQueue - original queue:', queue);
// Get all remaining items sorted by order // Find the item to remove and get its key
const remainingItems = Object.entries(queue) const itemToRemove = Object.entries(queue).find(([key, item]) =>
.filter(([key]) => key !== queueItemKey) key === queueItemKey && item
.map(([key, item]) => ({ key, item: item as QueueItem })) );
.sort((a, b) => a.item.order - b.item.order);
debugLog('removeFromQueue - remaining items:', remainingItems); if (!itemToRemove) {
throw new Error('Queue item not found');
}
// Create a completely new queue with sequential keys const [removedKey, removedItem] = itemToRemove;
const removedKeyNum = parseInt(removedKey, 10);
debugLog('removeFromQueue - removing item:', removedItem, 'with key:', removedKeyNum);
// Create updates object
const updates: Record<string, QueueItem | null> = {}; const updates: Record<string, QueueItem | null> = {};
// First, remove all existing items // Remove the target item
Object.keys(queue).forEach(key => { updates[removedKey] = null;
updates[key] = null;
});
// Then, add back the remaining items with sequential keys and order // Shift down all items that come after the removed one
remainingItems.forEach(({ item }, index) => { Object.entries(queue).forEach(([key, item]) => {
const newKey = index.toString(); if (item && key !== queueItemKey) {
const newOrder = index + 1; const keyNum = parseInt(key, 10);
debugLog(`removeFromQueue - reindexing: old key ${item.key} -> new key ${newKey}, order ${item.order} -> ${newOrder}`); if (keyNum > removedKeyNum) {
updates[newKey] = { ...item, order: newOrder }; // This item comes after the removed one, shift it down
const newKey = (keyNum - 1).toString();
const shiftedItem = { ...item as QueueItem, order: keyNum - 1 };
debugLog(`removeFromQueue - shifting: ${key} -> ${newKey}, order: ${keyNum} -> ${keyNum - 1}`);
updates[newKey] = shiftedItem;
updates[key] = null; // Remove from old position
}
}
}); });
debugLog('removeFromQueue - updates to apply:', updates); debugLog('removeFromQueue - updates to apply:', updates);
@ -128,18 +141,20 @@ export const queueService = {
await update(queueItemRef, updates); await update(queueItemRef, updates);
}, },
// Reorder queue with zero-bound sequential ordering // Reorder the queue
reorderQueue: async (controllerName: string, newOrder: QueueItem[]) => { reorderQueue: async (controllerName: string, reorderedItems: QueueItem[]) => {
const queueRef = ref(database, `controllers/${controllerName}/player/queue`); const queueRef = ref(database, `controllers/${controllerName}/player/queue`);
const snapshot = await get(queueRef); const queueSnapshot = await get(queueRef);
if (!snapshot.exists()) return { updates: {} }; if (!queueSnapshot.exists()) {
throw new Error('Queue not found');
}
const queue = snapshot.val(); const queue = queueSnapshot.val();
debugLog('reorderQueue - original queue:', queue); debugLog('reorderQueue - original queue:', queue);
debugLog('reorderQueue - new order:', newOrder); debugLog('reorderQueue - reordered items:', reorderedItems);
// Create a completely new queue with sequential keys // Create updates object
const updates: Record<string, QueueItem | null> = {}; const updates: Record<string, QueueItem | null> = {};
// First, remove all existing items // First, remove all existing items
@ -147,20 +162,18 @@ export const queueService = {
updates[key] = null; updates[key] = null;
}); });
// Then, add back the items in the new order with sequential keys // Then, add back the reordered items with sequential keys and order
newOrder.forEach((item, index) => { reorderedItems.forEach((item, index) => {
const newKey = index.toString(); const newKey = index.toString();
const newOrder = index + 1; const newOrder = index + 1;
debugLog(`reorderQueue - reindexing: old key ${item.key} -> new key ${newKey}, order ${item.order} -> ${newOrder}`); debugLog(`reorderQueue - setting: key ${newKey}, order ${newOrder}, song: ${item.song.title}`);
updates[newKey] = { ...item, order: newOrder }; updates[newKey] = { ...item, order: newOrder };
}); });
debugLog('reorderQueue - updates to apply:', updates); debugLog('reorderQueue - updates to apply:', updates);
// Apply all updates atomically // Apply all updates atomically
if (Object.keys(updates).length > 0) {
await update(queueRef, updates); await update(queueRef, updates);
}
return { updates }; return { updates };
}, },
@ -382,7 +395,7 @@ export const singerService = {
} }
} }
// Then, remove the singer from the singers list and reindex // Then, remove the singer from the singers list and shift down
const singersRef = ref(database, `controllers/${controllerName}/player/singers`); const singersRef = ref(database, `controllers/${controllerName}/player/singers`);
const singersSnapshot = await get(singersRef); const singersSnapshot = await get(singersRef);
@ -390,27 +403,39 @@ export const singerService = {
const singers = singersSnapshot.val(); const singers = singersSnapshot.val();
debugLog('removeSinger - original singers:', singers); debugLog('removeSinger - original singers:', singers);
// Get all remaining singers (excluding the one to be removed) // Find the singer to remove and get their key
const remainingSingers = Object.entries(singers) const singerToRemove = Object.entries(singers).find(([, singer]) =>
.filter(([, singer]) => singer && (singer as Singer).name !== singerName) singer && (singer as Singer).name === singerName
.map(([key, singer]) => ({ key, singer: singer as Singer })) );
.sort((a, b) => a.singer.name.localeCompare(b.singer.name)); // Keep alphabetical order
debugLog('removeSinger - remaining singers:', remainingSingers); if (!singerToRemove) {
debugLog('removeSinger - singer not found:', singerName);
return;
}
// Create a completely new singers list with sequential keys const [removedKey, removedSinger] = singerToRemove;
const removedKeyNum = parseInt(removedKey, 10);
debugLog('removeSinger - removing singer:', removedSinger, 'with key:', removedKeyNum);
// Create updates object
const updates: Record<string, Singer | null> = {}; const updates: Record<string, Singer | null> = {};
// First, remove all existing singers // Remove the target singer
Object.keys(singers).forEach(key => { updates[removedKey] = null;
updates[key] = null;
});
// Then, add back the remaining singers with sequential keys // Shift down all singers that come after the removed one
remainingSingers.forEach(({ singer }, index) => { Object.entries(singers).forEach(([key, singer]) => {
const newKey = index.toString(); if (singer && (singer as Singer).name !== singerName) {
debugLog(`removeSinger - reindexing: old key ${singer.key} -> new key ${newKey}, singer: ${singer.name}`); const keyNum = parseInt(key, 10);
updates[newKey] = singer; if (keyNum > removedKeyNum) {
// This singer comes after the removed one, shift them down
const newKey = (keyNum - 1).toString();
debugLog(`removeSinger - shifting: ${key} -> ${newKey}, singer: ${(singer as Singer).name}`);
updates[newKey] = singer as Singer;
updates[key] = null; // Remove from old position
}
}
}); });
debugLog('removeSinger - updates to apply:', updates); debugLog('removeSinger - updates to apply:', updates);