Signed-off-by: mbrucedogs <mbrucedogs@gmail.com>
This commit is contained in:
parent
debabcc9e7
commit
551b180f54
@ -8,7 +8,7 @@ import {
|
||||
} from 'ionicons/icons';
|
||||
import { useAppSelector } from '../../redux';
|
||||
import { selectIsAdmin, selectFavorites, selectSongs, selectQueue } from '../../redux';
|
||||
import { useActionHandlers } from '../../hooks/useActionHandlers';
|
||||
import { useActions } from '../../hooks/useActions';
|
||||
import { useModal } from '../../hooks/useModalContext';
|
||||
|
||||
import { ModalHeader } from './ModalHeader';
|
||||
@ -26,7 +26,7 @@ const SongInfo: React.FC<SongInfoProps> = ({ isOpen, onClose, song }) => {
|
||||
const favorites = useAppSelector(selectFavorites);
|
||||
const allSongs = useAppSelector(selectSongs);
|
||||
const queue = useAppSelector(selectQueue);
|
||||
const { handleToggleFavorite, handleToggleDisabled, isSongDisabled } = useActionHandlers();
|
||||
const { handleToggleFavorite, handleToggleDisabled, isSongDisabled } = useActions();
|
||||
|
||||
const { openSelectSinger } = useModal();
|
||||
const [showArtistSongs, setShowArtistSongs] = useState(false);
|
||||
|
||||
@ -3,8 +3,7 @@ import { IonItem, IonLabel } from '@ionic/react';
|
||||
import ActionButton from './ActionButton';
|
||||
import { useAppSelector } from '../../redux';
|
||||
import { selectQueue, selectFavorites } from '../../redux';
|
||||
import { useSongOperations } from '../../hooks/useSongOperations';
|
||||
import { useToast } from '../../hooks/useToast';
|
||||
import { useActions } from '../../hooks/useActions';
|
||||
import { useModal } from '../../hooks/useModalContext';
|
||||
import { debugLog } from '../../utils/logger';
|
||||
import type { SongItemProps, QueueItem, Song } from '../../types';
|
||||
@ -214,9 +213,8 @@ const SongItem: React.FC<SongItemProps> = ({
|
||||
const queue = useAppSelector(selectQueue);
|
||||
const favorites = useAppSelector(selectFavorites);
|
||||
|
||||
// Get song operations and hooks
|
||||
const { addToQueue, removeFromQueue, toggleFavorite } = useSongOperations();
|
||||
const { showSuccess, showError } = useToast();
|
||||
// Get unified action handlers
|
||||
const { handleAddToQueue, handleToggleFavorite, handleRemoveFromQueue } = useActions();
|
||||
const { openSongInfo } = useModal();
|
||||
|
||||
// Check if song is in queue or favorites based on path
|
||||
@ -248,33 +246,21 @@ const SongItem: React.FC<SongItemProps> = ({
|
||||
const shouldShowDeleteButton = showDeleteButton !== undefined ? showDeleteButton : context === 'history' && isAdmin;
|
||||
const shouldShowFavoriteButton = showFavoriteButton !== undefined ? showFavoriteButton : false; // Disabled for all contexts
|
||||
|
||||
// Handle song operations internally
|
||||
const handleAddToQueue = async () => {
|
||||
try {
|
||||
await addToQueue(song);
|
||||
showSuccess('Song added to queue');
|
||||
} catch {
|
||||
showError('Failed to add song to queue');
|
||||
}
|
||||
// Create wrapper functions for the unified handlers
|
||||
const handleAddToQueueClick = async () => {
|
||||
await handleAddToQueue(song);
|
||||
};
|
||||
|
||||
const handleRemoveFromQueue = async () => {
|
||||
const handleToggleFavoriteClick = async () => {
|
||||
await handleToggleFavorite(song);
|
||||
};
|
||||
|
||||
const handleRemoveFromQueueClick = async () => {
|
||||
if (!queueItemKey) return;
|
||||
|
||||
try {
|
||||
await removeFromQueue(queueItemKey);
|
||||
showSuccess('Song removed from queue');
|
||||
} catch {
|
||||
showError('Failed to remove song from queue');
|
||||
}
|
||||
};
|
||||
|
||||
const handleToggleFavorite = async () => {
|
||||
try {
|
||||
await toggleFavorite(song);
|
||||
showSuccess(isInFavorites ? 'Removed from favorites' : 'Added to favorites');
|
||||
} catch {
|
||||
showError('Failed to update favorites');
|
||||
// Find the queue item by key
|
||||
const queueItem = (Object.values(queue) as QueueItem[]).find(item => item.key === queueItemKey);
|
||||
if (queueItem) {
|
||||
await handleRemoveFromQueue(queueItem);
|
||||
}
|
||||
};
|
||||
|
||||
@ -302,9 +288,9 @@ const SongItem: React.FC<SongItemProps> = ({
|
||||
showDeleteButton={shouldShowDeleteButton}
|
||||
showFavoriteButton={shouldShowFavoriteButton}
|
||||
onDeleteItem={onDeleteItem}
|
||||
onAddToQueue={context === 'queue' ? handleRemoveFromQueue : handleAddToQueue}
|
||||
onRemoveFromQueue={context === 'queue' ? handleRemoveFromQueue : onDeleteItem}
|
||||
onToggleFavorite={context === 'favorites' ? onDeleteItem : handleToggleFavorite}
|
||||
onAddToQueue={context === 'queue' ? handleRemoveFromQueueClick : handleAddToQueueClick}
|
||||
onRemoveFromQueue={context === 'queue' ? handleRemoveFromQueueClick : onDeleteItem}
|
||||
onToggleFavorite={context === 'favorites' ? onDeleteItem : handleToggleFavoriteClick}
|
||||
onShowSongInfo={handleSelectSinger}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -1,48 +1,43 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { IonItem, IonLabel, IonItemSliding, IonItemOptions, IonItemOption, IonIcon, IonReorderGroup, IonReorder } from '@ionic/react';
|
||||
import { reorderThreeOutline, reorderTwoOutline, list } from 'ionicons/icons';
|
||||
import { useQueue } from '../../hooks';
|
||||
import { useQueue, useActions } from '../../hooks';
|
||||
import { useAppSelector } from '../../redux';
|
||||
import { selectQueueLength, selectPlayerStateMemoized, selectIsAdmin, selectControllerName } from '../../redux';
|
||||
import { selectQueueLength } from '../../redux';
|
||||
import { ActionButton, NumberDisplay, EmptyState } from '../../components/common';
|
||||
import { ActionButtonVariant, ActionButtonSize, ActionButtonIconSlot } from '../../types';
|
||||
import { Icons } from '../../constants';
|
||||
import { SongInfoDisplay } from '../../components/common/SongItem';
|
||||
import { queueService } from '../../firebase/services';
|
||||
import { debugLog } from '../../utils/logger';
|
||||
import { PlayerState } from '../../types';
|
||||
import type { QueueItem } from '../../types';
|
||||
|
||||
type QueueMode = 'delete' | 'reorder';
|
||||
|
||||
const Queue: React.FC = () => {
|
||||
const [queueMode, setQueueMode] = useState<QueueMode>('delete');
|
||||
const [listItems, setListItems] = useState<QueueItem[]>([]);
|
||||
|
||||
const {
|
||||
queueItems,
|
||||
canReorder,
|
||||
handleRemoveFromQueue,
|
||||
} = useQueue();
|
||||
|
||||
const {
|
||||
queueMode,
|
||||
canDeleteItems,
|
||||
canDeleteFirstItem,
|
||||
toggleQueueMode,
|
||||
handleReorder,
|
||||
} = useActions();
|
||||
|
||||
// Check if reordering is allowed
|
||||
const canReorder = canDeleteItems && queueItems.length > 1;
|
||||
|
||||
const queueCount = useAppSelector(selectQueueLength);
|
||||
const playerState = useAppSelector(selectPlayerStateMemoized);
|
||||
const isAdmin = useAppSelector(selectIsAdmin);
|
||||
const controllerName = useAppSelector(selectControllerName);
|
||||
|
||||
// Debug logging
|
||||
debugLog('Queue component - queue count:', queueCount);
|
||||
debugLog('Queue component - queue items:', queueItems);
|
||||
debugLog('Queue component - player state:', playerState);
|
||||
debugLog('Queue component - isAdmin:', isAdmin);
|
||||
debugLog('Queue component - canReorder:', canReorder);
|
||||
debugLog('Queue component - queueMode:', queueMode);
|
||||
|
||||
// Check if items can be deleted (admin can delete any item when not playing)
|
||||
const canDeleteItems = isAdmin && (playerState?.state === PlayerState.stopped || playerState?.state === PlayerState.paused);
|
||||
|
||||
debugLog('Queue component - canDeleteItems:', canDeleteItems);
|
||||
debugLog('Queue component - canReorder:', canReorder);
|
||||
|
||||
|
||||
// Update list items when queue changes
|
||||
@ -55,52 +50,15 @@ const Queue: React.FC = () => {
|
||||
}
|
||||
}, [queueItems]);
|
||||
|
||||
// Toggle between modes
|
||||
const toggleQueueMode = () => {
|
||||
setQueueMode(prevMode => prevMode === 'delete' ? 'reorder' : 'delete');
|
||||
};
|
||||
|
||||
// Handle reorder event from IonReorderGroup
|
||||
const doReorder = async (event: CustomEvent) => {
|
||||
debugLog('Reorder event:', event.detail);
|
||||
const { from, to, complete } = event.detail;
|
||||
|
||||
if (listItems && controllerName) {
|
||||
const copy = [...listItems];
|
||||
const draggedItem = copy.splice(from, 1)[0];
|
||||
copy.splice(to, 0, draggedItem);
|
||||
|
||||
// Complete the reorder animation
|
||||
complete();
|
||||
|
||||
// Create the new queue order (first item + reordered items)
|
||||
const newQueueItems = [queueItems[0], ...copy];
|
||||
debugLog('New queue order:', newQueueItems);
|
||||
|
||||
try {
|
||||
// Update all items with their new order values
|
||||
const updatePromises = newQueueItems.map((item, index) => {
|
||||
const newOrder = index + 1;
|
||||
if (item.key && item.order !== newOrder) {
|
||||
debugLog(`Updating item ${item.key} from order ${item.order} to ${newOrder}`);
|
||||
return queueService.updateQueueItem(controllerName, item.key, { order: newOrder });
|
||||
}
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
await Promise.all(updatePromises);
|
||||
debugLog('Queue reorder completed successfully');
|
||||
} catch (error) {
|
||||
console.error('Failed to reorder queue:', error);
|
||||
// You might want to show an error toast here
|
||||
}
|
||||
}
|
||||
await handleReorder(event, queueItems);
|
||||
};
|
||||
|
||||
// Render queue item
|
||||
const renderQueueItem = (queueItem: QueueItem, index: number) => {
|
||||
debugLog(`Queue item ${index}: order=${queueItem.order}, key=${queueItem.key}`);
|
||||
const canDelete = isAdmin && queueMode === 'delete'; // Only allow delete in delete mode
|
||||
const canDelete = canDeleteItems && queueMode === 'delete'; // Only allow delete in delete mode
|
||||
|
||||
return (
|
||||
<IonItemSliding key={queueItem.key}>
|
||||
@ -167,7 +125,6 @@ const Queue: React.FC = () => {
|
||||
if (queueItems.length === 0) return null;
|
||||
|
||||
const firstItem = queueItems[0];
|
||||
const canDeleteFirstItem = isAdmin && (playerState?.state === PlayerState.stopped || playerState?.state === PlayerState.paused);
|
||||
|
||||
return (
|
||||
<IonItemSliding key={firstItem.key}>
|
||||
@ -236,7 +193,7 @@ const Queue: React.FC = () => {
|
||||
<>
|
||||
<div className="ion-padding">
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: '1rem' }}>
|
||||
{isAdmin && (
|
||||
{canDeleteItems && (
|
||||
<ActionButton
|
||||
onClick={toggleQueueMode}
|
||||
variant={ActionButtonVariant.SECONDARY}
|
||||
|
||||
@ -11,6 +11,6 @@ export { useArtists } from './useArtists';
|
||||
export { useSingers } from './useSingers';
|
||||
export { useSongLists } from './useSongLists';
|
||||
export { useDisabledSongs } from './useDisabledSongs';
|
||||
export { useActionHandlers } from './useActionHandlers';
|
||||
export { useActions } from './useActions';
|
||||
|
||||
export { useSongInfo } from './useSongInfo';
|
||||
@ -1,69 +0,0 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useSongOperations } from './useSongOperations';
|
||||
import { useToast } from './useToast';
|
||||
import { useDisabledSongs } from './useDisabledSongs';
|
||||
import { historyService } from '../firebase/services';
|
||||
import { useAppSelector } from '../redux';
|
||||
import { selectControllerName } from '../redux';
|
||||
import type { Song } from '../types';
|
||||
|
||||
export const useActionHandlers = () => {
|
||||
const { addToQueue, toggleFavorite } = useSongOperations();
|
||||
const { showSuccess, showError } = useToast();
|
||||
const { isSongDisabled, addDisabledSong, removeDisabledSong } = useDisabledSongs();
|
||||
const controllerName = useAppSelector(selectControllerName);
|
||||
|
||||
const handleAddToQueue = useCallback(async (song: Song) => {
|
||||
try {
|
||||
await addToQueue(song);
|
||||
showSuccess('Song added to queue');
|
||||
} catch {
|
||||
showError('Failed to add song to queue');
|
||||
}
|
||||
}, [addToQueue, showSuccess, showError]);
|
||||
|
||||
const handleToggleFavorite = useCallback(async (song: Song) => {
|
||||
try {
|
||||
await toggleFavorite(song);
|
||||
showSuccess(song.favorite ? 'Removed from favorites' : 'Added to favorites');
|
||||
} catch {
|
||||
showError('Failed to update favorites');
|
||||
}
|
||||
}, [toggleFavorite, showSuccess, showError]);
|
||||
|
||||
const handleToggleDisabled = useCallback(async (song: Song) => {
|
||||
try {
|
||||
if (isSongDisabled(song)) {
|
||||
await removeDisabledSong(song);
|
||||
showSuccess('Song enabled');
|
||||
} else {
|
||||
await addDisabledSong(song);
|
||||
showSuccess('Song disabled');
|
||||
}
|
||||
} catch {
|
||||
showError('Failed to update song disabled status');
|
||||
}
|
||||
}, [isSongDisabled, addDisabledSong, removeDisabledSong, showSuccess, showError]);
|
||||
|
||||
const handleDeleteFromHistory = useCallback(async (song: Song) => {
|
||||
if (!controllerName || !song.key) {
|
||||
showError('Cannot delete history item - missing data');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await historyService.removeFromHistory(controllerName, song.key);
|
||||
showSuccess('Removed from history');
|
||||
} catch {
|
||||
showError('Failed to remove from history');
|
||||
}
|
||||
}, [controllerName, showSuccess, showError]);
|
||||
|
||||
return {
|
||||
handleAddToQueue,
|
||||
handleToggleFavorite,
|
||||
handleToggleDisabled,
|
||||
handleDeleteFromHistory,
|
||||
isSongDisabled,
|
||||
};
|
||||
};
|
||||
153
src/hooks/useActions.ts
Normal file
153
src/hooks/useActions.ts
Normal file
@ -0,0 +1,153 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useAppSelector } from '../redux';
|
||||
import { selectControllerName, selectPlayerStateMemoized, selectIsAdmin } from '../redux';
|
||||
import { useSongOperations } from './useSongOperations';
|
||||
import { useToast } from './useToast';
|
||||
import { useDisabledSongs } from './useDisabledSongs';
|
||||
import { queueService, historyService } from '../firebase/services';
|
||||
import { debugLog } from '../utils/logger';
|
||||
import { PlayerState } from '../types';
|
||||
import type { Song, QueueItem } from '../types';
|
||||
|
||||
export type QueueMode = 'delete' | 'reorder';
|
||||
|
||||
export const useActions = () => {
|
||||
const [queueMode, setQueueMode] = useState<QueueMode>('delete');
|
||||
|
||||
const controllerName = useAppSelector(selectControllerName);
|
||||
const playerState = useAppSelector(selectPlayerStateMemoized);
|
||||
const isAdmin = useAppSelector(selectIsAdmin);
|
||||
const { addToQueue, removeFromQueue, toggleFavorite } = useSongOperations();
|
||||
const { showSuccess, showError } = useToast();
|
||||
const { isSongDisabled, addDisabledSong, removeDisabledSong } = useDisabledSongs();
|
||||
|
||||
// Queue permissions
|
||||
const canDeleteItems = isAdmin && (playerState?.state === PlayerState.stopped || playerState?.state === PlayerState.paused);
|
||||
const canDeleteFirstItem = isAdmin && (playerState?.state === PlayerState.stopped || playerState?.state === PlayerState.paused);
|
||||
|
||||
// Song operations
|
||||
const handleAddToQueue = useCallback(async (song: Song) => {
|
||||
try {
|
||||
await addToQueue(song);
|
||||
showSuccess('Song added to queue');
|
||||
} catch {
|
||||
showError('Failed to add song to queue');
|
||||
}
|
||||
}, [addToQueue, showSuccess, showError]);
|
||||
|
||||
const handleRemoveFromQueue = useCallback(async (queueItem: QueueItem) => {
|
||||
if (!queueItem.key) return;
|
||||
|
||||
try {
|
||||
await removeFromQueue(queueItem.key);
|
||||
showSuccess('Song removed from queue');
|
||||
} catch {
|
||||
showError('Failed to remove song from queue');
|
||||
}
|
||||
}, [removeFromQueue, showSuccess, showError]);
|
||||
|
||||
const handleToggleFavorite = useCallback(async (song: Song) => {
|
||||
try {
|
||||
await toggleFavorite(song);
|
||||
showSuccess(song.favorite ? 'Removed from favorites' : 'Added to favorites');
|
||||
} catch {
|
||||
showError('Failed to update favorites');
|
||||
}
|
||||
}, [toggleFavorite, showSuccess, showError]);
|
||||
|
||||
const handleToggleDisabled = useCallback(async (song: Song) => {
|
||||
try {
|
||||
if (isSongDisabled(song)) {
|
||||
await removeDisabledSong(song);
|
||||
showSuccess('Song enabled');
|
||||
} else {
|
||||
await addDisabledSong(song);
|
||||
showSuccess('Song disabled');
|
||||
}
|
||||
} catch {
|
||||
showError('Failed to update song disabled status');
|
||||
}
|
||||
}, [isSongDisabled, addDisabledSong, removeDisabledSong, showSuccess, showError]);
|
||||
|
||||
const handleDeleteFromHistory = useCallback(async (song: Song) => {
|
||||
if (!controllerName || !song.key) {
|
||||
showError('Cannot delete history item - missing data');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await historyService.removeFromHistory(controllerName, song.key);
|
||||
showSuccess('Removed from history');
|
||||
} catch {
|
||||
showError('Failed to remove from history');
|
||||
}
|
||||
}, [controllerName, showSuccess, showError]);
|
||||
|
||||
// Queue UI operations
|
||||
const toggleQueueMode = useCallback(() => {
|
||||
setQueueMode(prevMode => prevMode === 'delete' ? 'reorder' : 'delete');
|
||||
}, []);
|
||||
|
||||
// Queue operations
|
||||
const handleReorder = useCallback(async (event: CustomEvent, queueItems: QueueItem[]) => {
|
||||
debugLog('Reorder event:', event.detail);
|
||||
const { from, to, complete } = event.detail;
|
||||
|
||||
if (!controllerName) {
|
||||
showError('Cannot reorder - controller not available');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Create the new queue order (first item + reordered items)
|
||||
const listItems = queueItems.slice(1); // Skip first item for reordering
|
||||
const copy = [...listItems];
|
||||
const draggedItem = copy.splice(from, 1)[0];
|
||||
copy.splice(to, 0, draggedItem);
|
||||
|
||||
// Complete the reorder animation
|
||||
complete();
|
||||
|
||||
const newQueueItems = [queueItems[0], ...copy];
|
||||
debugLog('New queue order:', newQueueItems);
|
||||
|
||||
// Update all items with their new order values
|
||||
const updatePromises = newQueueItems.map((item, index) => {
|
||||
const newOrder = index + 1;
|
||||
if (item.key && item.order !== newOrder) {
|
||||
debugLog(`Updating item ${item.key} from order ${item.order} to ${newOrder}`);
|
||||
return queueService.updateQueueItem(controllerName, item.key, { order: newOrder });
|
||||
}
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
await Promise.all(updatePromises);
|
||||
debugLog('Queue reorder completed successfully');
|
||||
showSuccess('Queue reordered successfully');
|
||||
} catch (error) {
|
||||
console.error('Failed to reorder queue:', error);
|
||||
showError('Failed to reorder queue');
|
||||
}
|
||||
}, [controllerName, showSuccess, showError]);
|
||||
|
||||
return {
|
||||
// Song operations
|
||||
handleAddToQueue,
|
||||
handleRemoveFromQueue,
|
||||
handleToggleFavorite,
|
||||
handleToggleDisabled,
|
||||
handleDeleteFromHistory,
|
||||
|
||||
// Queue UI state
|
||||
queueMode,
|
||||
toggleQueueMode,
|
||||
|
||||
// Queue operations
|
||||
handleReorder,
|
||||
|
||||
// Permissions
|
||||
canDeleteItems,
|
||||
canDeleteFirstItem,
|
||||
isSongDisabled,
|
||||
};
|
||||
};
|
||||
@ -1,14 +1,14 @@
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useAppSelector, selectFavoritesArray } from '../redux';
|
||||
import { debugLog } from '../utils/logger';
|
||||
import { useActionHandlers } from './useActionHandlers';
|
||||
import { useActions } from './useActions';
|
||||
import { useDisabledSongs } from './useDisabledSongs';
|
||||
|
||||
const ITEMS_PER_PAGE = 20;
|
||||
|
||||
export const useFavorites = () => {
|
||||
const allFavoritesItems = useAppSelector(selectFavoritesArray);
|
||||
const { handleAddToQueue, handleToggleFavorite, handleToggleDisabled, isSongDisabled } = useActionHandlers();
|
||||
const { handleAddToQueue, handleToggleFavorite, handleToggleDisabled, isSongDisabled } = useActions();
|
||||
const { disabledSongPaths, loading: disabledSongsLoading } = useDisabledSongs();
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useAppSelector, selectHistoryArray } from '../redux';
|
||||
import { debugLog } from '../utils/logger';
|
||||
import { useActionHandlers } from './useActionHandlers';
|
||||
import { useActions } from './useActions';
|
||||
import { useDisabledSongs } from './useDisabledSongs';
|
||||
|
||||
const ITEMS_PER_PAGE = 20;
|
||||
|
||||
export const useHistory = () => {
|
||||
const allHistoryItems = useAppSelector(selectHistoryArray);
|
||||
const { handleAddToQueue, handleToggleFavorite, handleToggleDisabled, handleDeleteFromHistory, isSongDisabled } = useActionHandlers();
|
||||
const { handleAddToQueue, handleToggleFavorite, handleToggleDisabled, handleDeleteFromHistory, isSongDisabled } = useActions();
|
||||
const { disabledSongPaths, loading: disabledSongsLoading } = useDisabledSongs();
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useState, useCallback, useMemo } from 'react';
|
||||
import { useAppSelector, selectSongsArray } from '../redux';
|
||||
import { useActionHandlers } from './useActionHandlers';
|
||||
import { useActions } from './useActions';
|
||||
import { useDisabledSongs } from './useDisabledSongs';
|
||||
import { UI_CONSTANTS } from '../constants';
|
||||
import { filterSongs } from '../utils/dataProcessing';
|
||||
@ -11,7 +11,7 @@ const ITEMS_PER_PAGE = 20;
|
||||
export const useSearch = () => {
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const { handleAddToQueue, handleToggleFavorite, handleToggleDisabled, isSongDisabled } = useActionHandlers();
|
||||
const { handleAddToQueue, handleToggleFavorite, handleToggleDisabled, isSongDisabled } = useActions();
|
||||
const { disabledSongPaths, loading: disabledSongsLoading } = useDisabledSongs();
|
||||
|
||||
// Get all songs from Redux (this is memoized)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user