|
@ -52,17 +52,19 @@ import { |
|
|
StyledPopover, |
|
|
StyledPopover, |
|
|
} from '../shared/styled'; |
|
|
} from '../shared/styled'; |
|
|
import { errorMessages, getCurrentEntryList, isFailedResponse } from '../../shared/utils'; |
|
|
import { errorMessages, getCurrentEntryList, isFailedResponse } from '../../shared/utils'; |
|
|
import { getGenres, getRandomSongs, setRating, star, unstar } from '../../api/api'; |
|
|
import { getGenres, getMusicFolders, getRandomSongs, setRating, star, unstar } from '../../api/api'; |
|
|
import { notifyToast } from '../shared/toast'; |
|
|
import { notifyToast } from '../shared/toast'; |
|
|
|
|
|
|
|
|
const NowPlayingView = () => { |
|
|
const NowPlayingView = () => { |
|
|
const tableRef = useRef<any>(); |
|
|
const tableRef = useRef<any>(); |
|
|
const pickerContainerRef = useRef(null); |
|
|
const genrePickerContainerRef = useRef(null); |
|
|
|
|
|
const musicFolderPickerContainerRef = useRef(null); |
|
|
const autoPlaylistTriggerRef = useRef<any>(); |
|
|
const autoPlaylistTriggerRef = useRef<any>(); |
|
|
const dispatch = useAppDispatch(); |
|
|
const dispatch = useAppDispatch(); |
|
|
const playQueue = useAppSelector((state) => state.playQueue); |
|
|
const playQueue = useAppSelector((state) => state.playQueue); |
|
|
const multiSelect = useAppSelector((state) => state.multiSelect); |
|
|
const multiSelect = useAppSelector((state) => state.multiSelect); |
|
|
const config = useAppSelector((state) => state.config); |
|
|
const config = useAppSelector((state) => state.config); |
|
|
|
|
|
const folder = useAppSelector((state) => state.folder); |
|
|
const [autoPlaylistTrackCount, setRandomPlaylistTrackCount] = useState( |
|
|
const [autoPlaylistTrackCount, setRandomPlaylistTrackCount] = useState( |
|
|
Number(settings.getSync('randomPlaylistTrackCount')) |
|
|
Number(settings.getSync('randomPlaylistTrackCount')) |
|
|
); |
|
|
); |
|
@ -70,6 +72,9 @@ const NowPlayingView = () => { |
|
|
const [autoPlaylistToYear, setRandomPlaylistToYear] = useState(0); |
|
|
const [autoPlaylistToYear, setRandomPlaylistToYear] = useState(0); |
|
|
const [randomPlaylistGenre, setRandomPlaylistGenre] = useState(''); |
|
|
const [randomPlaylistGenre, setRandomPlaylistGenre] = useState(''); |
|
|
const [isLoadingRandom, setIsLoadingRandom] = useState(false); |
|
|
const [isLoadingRandom, setIsLoadingRandom] = useState(false); |
|
|
|
|
|
const [musicFolder, setMusicFolder] = useState(folder.musicFolder); |
|
|
|
|
|
|
|
|
|
|
|
const { data: musicFolders } = useQuery(['musicFolders'], getMusicFolders); |
|
|
|
|
|
|
|
|
const [searchQuery, setSearchQuery] = useState(''); |
|
|
const [searchQuery, setSearchQuery] = useState(''); |
|
|
const filteredData = useSearchQuery(searchQuery, playQueue.entry, [ |
|
|
const filteredData = useSearchQuery(searchQuery, playQueue.entry, [ |
|
@ -180,6 +185,7 @@ const NowPlayingView = () => { |
|
|
fromYear: autoPlaylistFromYear !== 0 ? autoPlaylistFromYear : undefined, |
|
|
fromYear: autoPlaylistFromYear !== 0 ? autoPlaylistFromYear : undefined, |
|
|
toYear: autoPlaylistToYear !== 0 ? autoPlaylistToYear : undefined, |
|
|
toYear: autoPlaylistToYear !== 0 ? autoPlaylistToYear : undefined, |
|
|
genre: randomPlaylistGenre, |
|
|
genre: randomPlaylistGenre, |
|
|
|
|
|
musicFolderId: musicFolder, |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
if (isFailedResponse(res)) { |
|
|
if (isFailedResponse(res)) { |
|
@ -194,37 +200,45 @@ const NowPlayingView = () => { |
|
|
|
|
|
|
|
|
const difference = res.song.length - cleanedSongs.length; |
|
|
const difference = res.song.length - cleanedSongs.length; |
|
|
|
|
|
|
|
|
if (action === 'play') { |
|
|
if (cleanedSongs.length > 0) { |
|
|
dispatch(setPlayQueue({ entries: cleanedSongs })); |
|
|
if (action === 'play') { |
|
|
dispatch(setStatus('PLAYING')); |
|
|
dispatch(setPlayQueue({ entries: cleanedSongs })); |
|
|
notifyToast( |
|
|
|
|
|
'info', |
|
|
|
|
|
`Playing ${cleanedSongs.length} ${ |
|
|
|
|
|
difference !== 0 ? `(-${difference} invalid)` : '' |
|
|
|
|
|
} song(s)` |
|
|
|
|
|
); |
|
|
|
|
|
} else if (action === 'addLater') { |
|
|
|
|
|
dispatch(appendPlayQueue({ entries: cleanedSongs, type: 'later' })); |
|
|
|
|
|
if (playQueue.entry.length < 1) { |
|
|
|
|
|
dispatch(setStatus('PLAYING')); |
|
|
|
|
|
} |
|
|
|
|
|
notifyToast( |
|
|
|
|
|
'info', |
|
|
|
|
|
`Added ${cleanedSongs.length} ${difference !== 0 ? `(-${difference} invalid)` : ''} song(s)` |
|
|
|
|
|
); |
|
|
|
|
|
} else { |
|
|
|
|
|
dispatch(appendPlayQueue({ entries: cleanedSongs, type: 'next' })); |
|
|
|
|
|
if (playQueue.entry.length < 1) { |
|
|
|
|
|
dispatch(setStatus('PLAYING')); |
|
|
dispatch(setStatus('PLAYING')); |
|
|
|
|
|
notifyToast( |
|
|
|
|
|
'info', |
|
|
|
|
|
`Playing ${cleanedSongs.length} ${ |
|
|
|
|
|
difference !== 0 ? `(-${difference} invalid)` : '' |
|
|
|
|
|
} song(s)` |
|
|
|
|
|
); |
|
|
|
|
|
} else if (action === 'addLater') { |
|
|
|
|
|
dispatch(appendPlayQueue({ entries: cleanedSongs, type: 'later' })); |
|
|
|
|
|
if (playQueue.entry.length < 1) { |
|
|
|
|
|
dispatch(setStatus('PLAYING')); |
|
|
|
|
|
} |
|
|
|
|
|
notifyToast( |
|
|
|
|
|
'info', |
|
|
|
|
|
`Added ${cleanedSongs.length} ${ |
|
|
|
|
|
difference !== 0 ? `(-${difference} invalid)` : '' |
|
|
|
|
|
} song(s)` |
|
|
|
|
|
); |
|
|
|
|
|
} else { |
|
|
|
|
|
dispatch(appendPlayQueue({ entries: cleanedSongs, type: 'next' })); |
|
|
|
|
|
if (playQueue.entry.length < 1) { |
|
|
|
|
|
dispatch(setStatus('PLAYING')); |
|
|
|
|
|
} |
|
|
|
|
|
notifyToast( |
|
|
|
|
|
'info', |
|
|
|
|
|
`Added ${cleanedSongs.length} ${ |
|
|
|
|
|
difference !== 0 ? `(-${difference} invalid)` : '' |
|
|
|
|
|
} song(s)` |
|
|
|
|
|
); |
|
|
} |
|
|
} |
|
|
notifyToast( |
|
|
dispatch(fixPlayer2Index()); |
|
|
'info', |
|
|
setIsLoadingRandom(false); |
|
|
`Added ${cleanedSongs.length} ${difference !== 0 ? `(-${difference} invalid)` : ''} song(s)` |
|
|
return autoPlaylistTriggerRef.current.close(); |
|
|
); |
|
|
|
|
|
} |
|
|
} |
|
|
dispatch(fixPlayer2Index()); |
|
|
|
|
|
setIsLoadingRandom(false); |
|
|
setIsLoadingRandom(false); |
|
|
return autoPlaylistTriggerRef.current.close(); |
|
|
return notifyToast('warning', `No songs found, adjust your filters`); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const handleRowFavorite = async (rowData: any) => { |
|
|
const handleRowFavorite = async (rowData: any) => { |
|
@ -323,11 +337,12 @@ const NowPlayingView = () => { |
|
|
</FlexboxGrid.Item> |
|
|
</FlexboxGrid.Item> |
|
|
</FlexboxGrid> |
|
|
</FlexboxGrid> |
|
|
<br /> |
|
|
<br /> |
|
|
<ControlLabel>Genre</ControlLabel> |
|
|
<StyledInputPickerContainer ref={genrePickerContainerRef}> |
|
|
<StyledInputPickerContainer ref={pickerContainerRef}> |
|
|
<ControlLabel>Genre</ControlLabel> |
|
|
|
|
|
<br /> |
|
|
<StyledInputPicker |
|
|
<StyledInputPicker |
|
|
style={{ width: '100%' }} |
|
|
style={{ width: '100%' }} |
|
|
container={() => pickerContainerRef.current} |
|
|
container={() => genrePickerContainerRef.current} |
|
|
data={genres} |
|
|
data={genres} |
|
|
value={randomPlaylistGenre} |
|
|
value={randomPlaylistGenre} |
|
|
virtualized |
|
|
virtualized |
|
@ -335,6 +350,22 @@ const NowPlayingView = () => { |
|
|
/> |
|
|
/> |
|
|
</StyledInputPickerContainer> |
|
|
</StyledInputPickerContainer> |
|
|
<br /> |
|
|
<br /> |
|
|
|
|
|
<StyledInputPickerContainer ref={musicFolderPickerContainerRef}> |
|
|
|
|
|
<ControlLabel>Music folder</ControlLabel> |
|
|
|
|
|
<br /> |
|
|
|
|
|
<StyledInputPicker |
|
|
|
|
|
style={{ width: '100%' }} |
|
|
|
|
|
container={() => musicFolderPickerContainerRef.current} |
|
|
|
|
|
data={musicFolders} |
|
|
|
|
|
defaultValue={musicFolder} |
|
|
|
|
|
valueKey="id" |
|
|
|
|
|
labelKey="name" |
|
|
|
|
|
onChange={(e: any) => { |
|
|
|
|
|
setMusicFolder(e); |
|
|
|
|
|
}} |
|
|
|
|
|
/> |
|
|
|
|
|
</StyledInputPickerContainer> |
|
|
|
|
|
<br /> |
|
|
<ButtonToolbar> |
|
|
<ButtonToolbar> |
|
|
<StyledButton |
|
|
<StyledButton |
|
|
appearance="subtle" |
|
|
appearance="subtle" |
|
|