Signed-off-by: mbrucedogs <mbrucedogs@gmail.com>
This commit is contained in:
parent
fb2a06129d
commit
923968ca57
@ -18,7 +18,6 @@ interface GenericListItemProps {
|
|||||||
button?: boolean;
|
button?: boolean;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
endContent?: React.ReactNode;
|
endContent?: React.ReactNode;
|
||||||
showSeparator?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic ListItem component for different types of data
|
// Generic ListItem component for different types of data
|
||||||
@ -36,7 +35,6 @@ export const ListItem = React.memo(forwardRef<HTMLIonItemElement, GenericListIte
|
|||||||
button = false,
|
button = false,
|
||||||
style,
|
style,
|
||||||
endContent,
|
endContent,
|
||||||
showSeparator, // keep for API compatibility, but not used
|
|
||||||
}, ref) => {
|
}, ref) => {
|
||||||
return (
|
return (
|
||||||
<IonItem
|
<IonItem
|
||||||
|
|||||||
@ -21,7 +21,9 @@ const PlayerControls: React.FC<PlayerControlsProps> = ({ className = '', variant
|
|||||||
const playerState = useAppSelector(selectPlayerState);
|
const playerState = useAppSelector(selectPlayerState);
|
||||||
const queueLength = useAppSelector(selectQueueLength);
|
const queueLength = useAppSelector(selectQueueLength);
|
||||||
const controllerName = useAppSelector(selectControllerName);
|
const controllerName = useAppSelector(selectControllerName);
|
||||||
const { showSuccess, showError } = useToast();
|
const toast = useToast();
|
||||||
|
const showSuccess = toast?.showSuccess;
|
||||||
|
const showError = toast?.showError;
|
||||||
|
|
||||||
// Debug logging
|
// Debug logging
|
||||||
debugLog('PlayerControls - playerState:', playerState);
|
debugLog('PlayerControls - playerState:', playerState);
|
||||||
@ -33,10 +35,10 @@ const PlayerControls: React.FC<PlayerControlsProps> = ({ className = '', variant
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await playerService.updatePlayerStateValue(controllerName, PlayerState.playing);
|
await playerService.updatePlayerStateValue(controllerName, PlayerState.playing);
|
||||||
showSuccess('Playback started');
|
if (showSuccess) showSuccess('Playback started');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to start playback:', error);
|
console.error('Failed to start playback:', error);
|
||||||
showError('Failed to start playback');
|
if (showError) showError('Failed to start playback');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,10 +47,10 @@ const PlayerControls: React.FC<PlayerControlsProps> = ({ className = '', variant
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await playerService.updatePlayerStateValue(controllerName, PlayerState.paused);
|
await playerService.updatePlayerStateValue(controllerName, PlayerState.paused);
|
||||||
showSuccess('Playback paused');
|
if (showSuccess) showSuccess('Playback paused');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to pause playback:', error);
|
console.error('Failed to pause playback:', error);
|
||||||
showError('Failed to pause playback');
|
if (showError) showError('Failed to pause playback');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,10 +59,10 @@ const PlayerControls: React.FC<PlayerControlsProps> = ({ className = '', variant
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await playerService.updatePlayerStateValue(controllerName, PlayerState.stopped);
|
await playerService.updatePlayerStateValue(controllerName, PlayerState.stopped);
|
||||||
showSuccess('Playback stopped');
|
if (showSuccess) showSuccess('Playback stopped');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to stop playback:', error);
|
console.error('Failed to stop playback:', error);
|
||||||
showError('Failed to stop playback');
|
if (showError) showError('Failed to stop playback');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -25,12 +25,14 @@ const SelectSinger: React.FC<SelectSingerProps> = ({ isOpen, onClose, song }) =>
|
|||||||
const singers = useAppSelector(selectSingersArray);
|
const singers = useAppSelector(selectSingersArray);
|
||||||
const controllerName = useAppSelector(selectControllerName);
|
const controllerName = useAppSelector(selectControllerName);
|
||||||
const currentQueue = useAppSelector(selectQueueObject);
|
const currentQueue = useAppSelector(selectQueueObject);
|
||||||
const { showSuccess, showError } = useToast();
|
const toast = useToast();
|
||||||
|
const showSuccess = toast?.showSuccess;
|
||||||
|
const showError = toast?.showError;
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const handleSelectSinger = async (singer: Singer) => {
|
const handleSelectSinger = async (singer: Singer) => {
|
||||||
if (!controllerName) {
|
if (!controllerName) {
|
||||||
showError('Controller not found');
|
if (showError) showError('Controller not found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,11 +55,11 @@ const SelectSinger: React.FC<SelectSingerProps> = ({ isOpen, onClose, song }) =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
await queueService.addToQueue(controllerName, queueItem);
|
await queueService.addToQueue(controllerName, queueItem);
|
||||||
showSuccess(`${song.title} added to queue for ${singer.name}`);
|
if (showSuccess) showSuccess(`${song.title} added to queue for ${singer.name}`);
|
||||||
onClose();
|
onClose();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to add song to queue:', error);
|
console.error('Failed to add song to queue:', error);
|
||||||
showError('Failed to add song to queue');
|
if (showError) showError('Failed to add song to queue');
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { useArtists } from '../../hooks';
|
|||||||
import { useAppSelector } from '../../redux';
|
import { useAppSelector } from '../../redux';
|
||||||
import { selectSongs } from '../../redux';
|
import { selectSongs } from '../../redux';
|
||||||
import { debugLog } from '../../utils/logger';
|
import { debugLog } from '../../utils/logger';
|
||||||
|
import { SongItemContext } from '../../types';
|
||||||
|
|
||||||
|
|
||||||
const Artists: React.FC = () => {
|
const Artists: React.FC = () => {
|
||||||
@ -90,7 +91,7 @@ const Artists: React.FC = () => {
|
|||||||
renderItem={(song) => (
|
renderItem={(song) => (
|
||||||
<SongItem
|
<SongItem
|
||||||
song={song}
|
song={song}
|
||||||
context="search"
|
context={SongItemContext.SEARCH}
|
||||||
showAddButton={true}
|
showAddButton={true}
|
||||||
showInfoButton={true}
|
showInfoButton={true}
|
||||||
showFavoriteButton={false}
|
showFavoriteButton={false}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import { ban } from 'ionicons/icons';
|
|||||||
import { useAppSelector } from '../../redux';
|
import { useAppSelector } from '../../redux';
|
||||||
import { selectIsAdmin, selectSettings, updateController, selectControllerName } from '../../redux';
|
import { selectIsAdmin, selectSettings, updateController, selectControllerName } from '../../redux';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { settingsService } from '../../firebase/services';
|
|
||||||
import { useDisabledSongs } from '../../hooks';
|
import { useDisabledSongs } from '../../hooks';
|
||||||
import { InfiniteScrollList, ActionButton, SongItem } from '../../components/common';
|
import { InfiniteScrollList, ActionButton, SongItem } from '../../components/common';
|
||||||
import { ActionButtonVariant, ActionButtonSize, ActionButtonIconSlot } from '../../types';
|
import { ActionButtonVariant, ActionButtonSize, ActionButtonIconSlot } from '../../types';
|
||||||
@ -12,6 +11,9 @@ import { Icons } from '../../constants';
|
|||||||
import { filterSongs } from '../../utils/dataProcessing';
|
import { filterSongs } from '../../utils/dataProcessing';
|
||||||
import { setDebugEnabled, isDebugEnabled, debugLog } from '../../utils/logger';
|
import { setDebugEnabled, isDebugEnabled, debugLog } from '../../utils/logger';
|
||||||
import type { Song, DisabledSong } from '../../types';
|
import type { Song, DisabledSong } from '../../types';
|
||||||
|
import { SongItemContext } from '../../types';
|
||||||
|
import type { Controller } from '../../types';
|
||||||
|
import { PlayerState } from '../../types';
|
||||||
|
|
||||||
const Settings: React.FC = () => {
|
const Settings: React.FC = () => {
|
||||||
const isAdmin = useAppSelector(selectIsAdmin);
|
const isAdmin = useAppSelector(selectIsAdmin);
|
||||||
@ -26,7 +28,15 @@ const Settings: React.FC = () => {
|
|||||||
const [showDisabledSongsModal, setShowDisabledSongsModal] = useState(false);
|
const [showDisabledSongsModal, setShowDisabledSongsModal] = useState(false);
|
||||||
const [searchTerm, setSearchTerm] = useState('');
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
const controllerNameRedux = useAppSelector(selectControllerName);
|
const controllerNameRedux = useAppSelector(selectControllerName);
|
||||||
const existingPlayer = useAppSelector(state => state.controller.data?.player) || {};
|
const existingPlayer = (useAppSelector(state => state.controller.data?.player) || {}) as Partial<Controller['player']>;
|
||||||
|
|
||||||
|
// Provide default values for required properties
|
||||||
|
const updatedPlayer = {
|
||||||
|
queue: existingPlayer.queue || {},
|
||||||
|
settings: existingPlayer.settings || { autoadvance: false, userpick: false },
|
||||||
|
singers: existingPlayer.singers || {},
|
||||||
|
state: existingPlayer.state || { state: PlayerState.stopped },
|
||||||
|
};
|
||||||
|
|
||||||
// Convert disabled songs object to array for display
|
// Convert disabled songs object to array for display
|
||||||
const disabledSongsArray: DisabledSong[] = Object.entries(disabledSongs).map(([key, disabledSong]) => ({
|
const disabledSongsArray: DisabledSong[] = Object.entries(disabledSongs).map(([key, disabledSong]) => ({
|
||||||
@ -46,16 +56,15 @@ const Settings: React.FC = () => {
|
|||||||
debugLog(`Toggle ${setting} to ${value}`);
|
debugLog(`Toggle ${setting} to ${value}`);
|
||||||
const controllerName = controllerNameRedux;
|
const controllerName = controllerNameRedux;
|
||||||
if (controllerName) {
|
if (controllerName) {
|
||||||
await settingsService.updateSetting(controllerName, setting, value);
|
// @ts-expect-error: Redux Thunk type mismatch workaround
|
||||||
dispatch(updateController({
|
dispatch(updateController({
|
||||||
controllerName,
|
controllerName,
|
||||||
updates: {
|
updates: {
|
||||||
player: {
|
player: {
|
||||||
...existingPlayer,
|
queue: updatedPlayer.queue,
|
||||||
settings: {
|
settings: { ...updatedPlayer.settings, [setting]: value },
|
||||||
...existingPlayer.settings,
|
singers: updatedPlayer.singers,
|
||||||
[setting]: value
|
state: updatedPlayer.state,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@ -198,7 +207,7 @@ const Settings: React.FC = () => {
|
|||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<SongItem
|
<SongItem
|
||||||
song={song}
|
song={song}
|
||||||
context="history"
|
context={SongItemContext.HISTORY}
|
||||||
showDeleteButton={true}
|
showDeleteButton={true}
|
||||||
showInfoButton={false}
|
showInfoButton={false}
|
||||||
showAddButton={false}
|
showAddButton={false}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { debugLog } from '../../utils/logger';
|
|||||||
|
|
||||||
|
|
||||||
import type { TopPlayed } from '../../types';
|
import type { TopPlayed } from '../../types';
|
||||||
|
import { SongItemContext } from '../../types';
|
||||||
|
|
||||||
const Top100: React.FC = () => {
|
const Top100: React.FC = () => {
|
||||||
debugLog('Top100 component - RENDERING START');
|
debugLog('Top100 component - RENDERING START');
|
||||||
@ -124,7 +125,7 @@ const Top100: React.FC = () => {
|
|||||||
<SongItem
|
<SongItem
|
||||||
key={song.key || `${song.title}-${song.artist}`}
|
key={song.key || `${song.title}-${song.artist}`}
|
||||||
song={song}
|
song={song}
|
||||||
context="search"
|
context={SongItemContext.SEARCH}
|
||||||
showAddButton={true}
|
showAddButton={true}
|
||||||
showInfoButton={true}
|
showInfoButton={true}
|
||||||
showFavoriteButton={false}
|
showFavoriteButton={false}
|
||||||
|
|||||||
@ -18,7 +18,9 @@ export const useActions = () => {
|
|||||||
const playerState = useAppSelector(selectPlayerStateMemoized);
|
const playerState = useAppSelector(selectPlayerStateMemoized);
|
||||||
const isAdmin = useAppSelector(selectIsAdmin);
|
const isAdmin = useAppSelector(selectIsAdmin);
|
||||||
const { addToQueue, removeFromQueue, toggleFavorite } = useSongOperations();
|
const { addToQueue, removeFromQueue, toggleFavorite } = useSongOperations();
|
||||||
const { showSuccess, showError } = useToast();
|
const toast = useToast();
|
||||||
|
const showSuccess = toast?.showSuccess;
|
||||||
|
const showError = toast?.showError;
|
||||||
const { isSongDisabled, addDisabledSong, removeDisabledSong } = useDisabledSongs();
|
const { isSongDisabled, addDisabledSong, removeDisabledSong } = useDisabledSongs();
|
||||||
|
|
||||||
// Queue permissions
|
// Queue permissions
|
||||||
@ -29,9 +31,9 @@ export const useActions = () => {
|
|||||||
const handleAddToQueue = useCallback(async (song: Song) => {
|
const handleAddToQueue = useCallback(async (song: Song) => {
|
||||||
try {
|
try {
|
||||||
await addToQueue(song);
|
await addToQueue(song);
|
||||||
showSuccess('Song added to queue');
|
if (showSuccess) showSuccess('Song added to queue');
|
||||||
} catch {
|
} catch {
|
||||||
showError('Failed to add song to queue');
|
if (showError) showError('Failed to add song to queue');
|
||||||
}
|
}
|
||||||
}, [addToQueue, showSuccess, showError]);
|
}, [addToQueue, showSuccess, showError]);
|
||||||
|
|
||||||
@ -40,18 +42,18 @@ export const useActions = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await removeFromQueue(queueItem.key);
|
await removeFromQueue(queueItem.key);
|
||||||
showSuccess('Song removed from queue');
|
if (showSuccess) showSuccess('Song removed from queue');
|
||||||
} catch {
|
} catch {
|
||||||
showError('Failed to remove song from queue');
|
if (showError) showError('Failed to remove song from queue');
|
||||||
}
|
}
|
||||||
}, [removeFromQueue, showSuccess, showError]);
|
}, [removeFromQueue, showSuccess, showError]);
|
||||||
|
|
||||||
const handleToggleFavorite = useCallback(async (song: Song) => {
|
const handleToggleFavorite = useCallback(async (song: Song) => {
|
||||||
try {
|
try {
|
||||||
await toggleFavorite(song);
|
await toggleFavorite(song);
|
||||||
showSuccess(song.favorite ? 'Removed from favorites' : 'Added to favorites');
|
if (showSuccess) showSuccess(song.favorite ? 'Removed from favorites' : 'Added to favorites');
|
||||||
} catch {
|
} catch {
|
||||||
showError('Failed to update favorites');
|
if (showError) showError('Failed to update favorites');
|
||||||
}
|
}
|
||||||
}, [toggleFavorite, showSuccess, showError]);
|
}, [toggleFavorite, showSuccess, showError]);
|
||||||
|
|
||||||
@ -59,27 +61,27 @@ export const useActions = () => {
|
|||||||
try {
|
try {
|
||||||
if (isSongDisabled(song)) {
|
if (isSongDisabled(song)) {
|
||||||
await removeDisabledSong(song);
|
await removeDisabledSong(song);
|
||||||
showSuccess('Song enabled');
|
if (showSuccess) showSuccess('Song enabled');
|
||||||
} else {
|
} else {
|
||||||
await addDisabledSong(song);
|
await addDisabledSong(song);
|
||||||
showSuccess('Song disabled');
|
if (showSuccess) showSuccess('Song disabled');
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
showError('Failed to update song disabled status');
|
if (showError) showError('Failed to update song disabled status');
|
||||||
}
|
}
|
||||||
}, [isSongDisabled, addDisabledSong, removeDisabledSong, showSuccess, showError]);
|
}, [isSongDisabled, addDisabledSong, removeDisabledSong, showSuccess, showError]);
|
||||||
|
|
||||||
const handleDeleteFromHistory = useCallback(async (song: Song) => {
|
const handleDeleteFromHistory = useCallback(async (song: Song) => {
|
||||||
if (!controllerName || !song.key) {
|
if (!controllerName || !song.key) {
|
||||||
showError('Cannot delete history item - missing data');
|
if (showError) showError('Cannot delete history item - missing data');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await historyService.removeFromHistory(controllerName, song.key);
|
await historyService.removeFromHistory(controllerName, song.key);
|
||||||
showSuccess('Removed from history');
|
if (showSuccess) showSuccess('Removed from history');
|
||||||
} catch {
|
} catch {
|
||||||
showError('Failed to remove from history');
|
if (showError) showError('Failed to remove from history');
|
||||||
}
|
}
|
||||||
}, [controllerName, showSuccess, showError]);
|
}, [controllerName, showSuccess, showError]);
|
||||||
|
|
||||||
@ -94,7 +96,7 @@ export const useActions = () => {
|
|||||||
const { from, to, complete } = event.detail;
|
const { from, to, complete } = event.detail;
|
||||||
|
|
||||||
if (!controllerName) {
|
if (!controllerName) {
|
||||||
showError('Cannot reorder - controller not available');
|
if (showError) showError('Cannot reorder - controller not available');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,10 +125,10 @@ export const useActions = () => {
|
|||||||
|
|
||||||
await Promise.all(updatePromises);
|
await Promise.all(updatePromises);
|
||||||
debugLog('Queue reorder completed successfully');
|
debugLog('Queue reorder completed successfully');
|
||||||
showSuccess('Queue reordered successfully');
|
if (showSuccess) showSuccess('Queue reordered successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to reorder queue:', error);
|
console.error('Failed to reorder queue:', error);
|
||||||
showError('Failed to reorder queue');
|
if (showError) showError('Failed to reorder queue');
|
||||||
}
|
}
|
||||||
}, [controllerName, showSuccess, showError]);
|
}, [controllerName, showSuccess, showError]);
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,9 @@ export const useDisabledSongs = () => {
|
|||||||
const [disabledSongs, setDisabledSongs] = useState<Record<string, DisabledSong>>({});
|
const [disabledSongs, setDisabledSongs] = useState<Record<string, DisabledSong>>({});
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const controllerName = useAppSelector(selectControllerName);
|
const controllerName = useAppSelector(selectControllerName);
|
||||||
const { showSuccess, showError } = useToast();
|
const toast = useToast();
|
||||||
|
const showSuccess = toast?.showSuccess;
|
||||||
|
const showError = toast?.showError;
|
||||||
|
|
||||||
// Load disabled songs on mount and subscribe to changes
|
// Load disabled songs on mount and subscribe to changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -35,7 +37,7 @@ export const useDisabledSongs = () => {
|
|||||||
setDisabledSongPaths(paths);
|
setDisabledSongPaths(paths);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading disabled songs:', error);
|
console.error('Error loading disabled songs:', error);
|
||||||
showError('Failed to load disabled songs');
|
if (showError) showError('Failed to load disabled songs');
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@ -81,22 +83,22 @@ export const useDisabledSongs = () => {
|
|||||||
const addDisabledSong = useCallback(async (song: Song) => {
|
const addDisabledSong = useCallback(async (song: Song) => {
|
||||||
if (!controllerName) {
|
if (!controllerName) {
|
||||||
console.error('No controller name available');
|
console.error('No controller name available');
|
||||||
showError('No controller name available');
|
if (showError) showError('No controller name available');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!song.path) {
|
if (!song.path) {
|
||||||
console.error('Song has no path:', song);
|
console.error('Song has no path:', song);
|
||||||
showError('Song has no path');
|
if (showError) showError('Song has no path');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await disabledSongsService.addDisabledSong(controllerName, song);
|
await disabledSongsService.addDisabledSong(controllerName, song);
|
||||||
showSuccess('Song marked as disabled');
|
if (showSuccess) showSuccess('Song marked as disabled');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error adding disabled song:', error);
|
console.error('Error adding disabled song:', error);
|
||||||
showError(`Failed to mark song as disabled: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
if (showError) showError(`Failed to mark song as disabled: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||||
}
|
}
|
||||||
}, [controllerName, showSuccess, showError]);
|
}, [controllerName, showSuccess, showError]);
|
||||||
|
|
||||||
@ -106,10 +108,10 @@ export const useDisabledSongs = () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await disabledSongsService.removeDisabledSong(controllerName, song.path);
|
await disabledSongsService.removeDisabledSong(controllerName, song.path);
|
||||||
showSuccess('Song re-enabled');
|
if (showSuccess) showSuccess('Song re-enabled');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error removing disabled song:', error);
|
console.error('Error removing disabled song:', error);
|
||||||
showError('Failed to re-enable song');
|
if (showError) showError('Failed to re-enable song');
|
||||||
}
|
}
|
||||||
}, [controllerName, showSuccess, showError]);
|
}, [controllerName, showSuccess, showError]);
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,8 @@ interface ErrorHandlerResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const useErrorHandler = (defaultOptions: ErrorHandlerOptions = {}): ErrorHandlerResult => {
|
export const useErrorHandler = (defaultOptions: ErrorHandlerOptions = {}): ErrorHandlerResult => {
|
||||||
const { showError } = useToast();
|
const toast = useToast();
|
||||||
|
const showError = toast?.showError;
|
||||||
|
|
||||||
const defaultErrorOptions: Required<ErrorHandlerOptions> = {
|
const defaultErrorOptions: Required<ErrorHandlerOptions> = {
|
||||||
showToast: true,
|
showToast: true,
|
||||||
@ -45,9 +46,7 @@ export const useErrorHandler = (defaultOptions: ErrorHandlerOptions = {}): Error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show toast if enabled
|
// Show toast if enabled
|
||||||
if (opts.showToast) {
|
if (opts.showToast && showError) showError(displayMessage);
|
||||||
showError(displayMessage);
|
|
||||||
}
|
|
||||||
}, [defaultErrorOptions, showError]);
|
}, [defaultErrorOptions, showError]);
|
||||||
|
|
||||||
const handleAsyncError = useCallback(async <T>(
|
const handleAsyncError = useCallback(async <T>(
|
||||||
|
|||||||
@ -8,53 +8,55 @@ export const useSingers = () => {
|
|||||||
const singers = useAppSelector(selectSingersArray);
|
const singers = useAppSelector(selectSingersArray);
|
||||||
const isAdmin = useAppSelector(selectIsAdmin);
|
const isAdmin = useAppSelector(selectIsAdmin);
|
||||||
const controllerName = useAppSelector(selectControllerName);
|
const controllerName = useAppSelector(selectControllerName);
|
||||||
const { showSuccess, showError } = useToast();
|
const toast = useToast();
|
||||||
|
const showSuccess = toast?.showSuccess;
|
||||||
|
const showError = toast?.showError;
|
||||||
|
|
||||||
const handleRemoveSinger = useCallback(async (singer: Singer) => {
|
const handleRemoveSinger = useCallback(async (singer: Singer) => {
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
showError('Only admins can remove singers');
|
showError && showError('Only admins can remove singers');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controllerName) {
|
if (!controllerName) {
|
||||||
showError('Controller not found');
|
showError && showError('Controller not found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await singerService.removeSinger(controllerName, singer.name);
|
await singerService.removeSinger(controllerName, singer.name);
|
||||||
showSuccess(`${singer.name} removed from singers list and queue`);
|
showSuccess && showSuccess(`${singer.name} removed from singers list and queue`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to remove singer:', error);
|
console.error('Failed to remove singer:', error);
|
||||||
showError('Failed to remove singer');
|
showError && showError('Failed to remove singer');
|
||||||
}
|
}
|
||||||
}, [isAdmin, controllerName, showSuccess, showError]);
|
}, [isAdmin, controllerName, showSuccess, showError]);
|
||||||
|
|
||||||
const handleAddSinger = useCallback(async (singerName: string) => {
|
const handleAddSinger = useCallback(async (singerName: string) => {
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
showError('Only admins can add singers');
|
showError && showError('Only admins can add singers');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controllerName) {
|
if (!controllerName) {
|
||||||
showError('Controller not found');
|
showError && showError('Controller not found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!singerName.trim()) {
|
if (!singerName.trim()) {
|
||||||
showError('Singer name cannot be empty');
|
showError && showError('Singer name cannot be empty');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await singerService.addSinger(controllerName, singerName.trim());
|
await singerService.addSinger(controllerName, singerName.trim());
|
||||||
showSuccess(`${singerName} added to singers list`);
|
showSuccess && showSuccess(`${singerName} added to singers list`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to add singer:', error);
|
console.error('Failed to add singer:', error);
|
||||||
if (error instanceof Error && error.message === 'Singer already exists') {
|
if (error instanceof Error && error.message === 'Singer already exists') {
|
||||||
showError('Singer already exists');
|
showError && showError('Singer already exists');
|
||||||
} else {
|
} else {
|
||||||
showError('Failed to add singer');
|
showError && showError('Failed to add singer');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [isAdmin, controllerName, showSuccess, showError]);
|
}, [isAdmin, controllerName, showSuccess, showError]);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user