Browse Source

Add play next buttons on all pages

- Decrease button sizes to account for added button: lg -> md
- Use dynamic button sizing on card depending on card size
master
jeffvli 3 years ago
committed by Jeff
parent
commit
42e8b7d569
  1. 22
      src/components/card/Card.tsx
  2. 7
      src/components/card/styled.tsx
  3. 26
      src/components/library/AlbumView.tsx
  4. 28
      src/components/library/ArtistView.tsx
  5. 3
      src/components/library/GenreList.tsx
  6. 28
      src/components/player/NowPlayingView.tsx
  7. 27
      src/components/playlist/PlaylistView.tsx

22
src/components/card/Card.tsx

@ -22,6 +22,7 @@ import {
FavoriteOverlayButton, FavoriteOverlayButton,
AppendOverlayButton, AppendOverlayButton,
ModalViewOverlayButton, ModalViewOverlayButton,
AppendNextOverlayButton,
} from './styled'; } from './styled';
import { setStatus } from '../../redux/playerSlice'; import { setStatus } from '../../redux/playerSlice';
import { addModalPage } from '../../redux/miscSlice'; import { addModalPage } from '../../redux/miscSlice';
@ -75,22 +76,22 @@ const Card = ({
dispatch(fixPlayer2Index()); dispatch(fixPlayer2Index());
}; };
const handlePlayAppend = async () => { const handlePlayAppend = async (type: 'next' | 'later') => {
if (playClick.type === 'playlist') { if (playClick.type === 'playlist') {
const res = await getPlaylist(playClick.id); const res = await getPlaylist(playClick.id);
dispatch(appendPlayQueue({ entries: res.song })); dispatch(appendPlayQueue({ entries: res.song, type }));
notifyToast('info', `Added ${res.song.length} song(s)`); notifyToast('info', `Added ${res.song.length} song(s)`);
} }
if (playClick.type === 'album') { if (playClick.type === 'album') {
const res = await getAlbum(playClick.id); const res = await getAlbum(playClick.id);
dispatch(appendPlayQueue({ entries: res.song })); dispatch(appendPlayQueue({ entries: res.song, type }));
notifyToast('info', `Added ${res.song.length} song(s)`); notifyToast('info', `Added ${res.song.length} song(s)`);
} }
if (playClick.type === 'artist') { if (playClick.type === 'artist') {
const songs = await getAllArtistSongs(playClick.id); const songs = await getAllArtistSongs(playClick.id);
dispatch(appendPlayQueue({ entries: songs })); dispatch(appendPlayQueue({ entries: songs, type }));
notifyToast('info', `Added ${songs.length} song(s)`); notifyToast('info', `Added ${songs.length} song(s)`);
} }
@ -171,20 +172,25 @@ const Card = ({
onClick={handlePlayClick} onClick={handlePlayClick}
/> />
<AppendOverlayButton <AppendOverlayButton
onClick={handlePlayAppend} onClick={() => handlePlayAppend('later')}
size="xs" size={size <= 160 ? 'xs' : 'sm'}
icon={<Icon icon="plus" />} icon={<Icon icon="plus" />}
/> />
<AppendNextOverlayButton
onClick={() => handlePlayAppend('next')}
size={size <= 160 ? 'xs' : 'sm'}
icon={<Icon icon="plus-circle" />}
/>
{playClick.type !== 'playlist' && ( {playClick.type !== 'playlist' && (
<FavoriteOverlayButton <FavoriteOverlayButton
onClick={handleFavorite} onClick={handleFavorite}
size="xs" size={size <= 160 ? 'xs' : 'sm'}
icon={<Icon icon={rest.details.starred ? 'heart' : 'heart-o'} />} icon={<Icon icon={rest.details.starred ? 'heart' : 'heart-o'} />}
/> />
)} )}
{!rest.isModal && ( {!rest.isModal && (
<ModalViewOverlayButton <ModalViewOverlayButton
size="xs" size={size <= 160 ? 'xs' : 'sm'}
icon={<Icon icon="external-link" />} icon={<Icon icon="external-link" />}
onClick={handleOpenModal} onClick={handleOpenModal}
/> />

7
src/components/card/styled.tsx

@ -118,11 +118,16 @@ export const AppendOverlayButton = styled(OverlayButton)`
left: 90%; left: 90%;
`; `;
export const FavoriteOverlayButton = styled(OverlayButton)` export const AppendNextOverlayButton = styled(OverlayButton)`
top: 90%; top: 90%;
left: 70%; left: 70%;
`; `;
export const FavoriteOverlayButton = styled(OverlayButton)`
top: 90%;
left: 50%;
`;
export const ModalViewOverlayButton = styled(OverlayButton)` export const ModalViewOverlayButton = styled(OverlayButton)`
top: 10%; top: 10%;
left: 90%; left: 90%;

26
src/components/library/AlbumView.tsx

@ -4,7 +4,12 @@ import settings from 'electron-settings';
import { ButtonToolbar, Tag } from 'rsuite'; import { ButtonToolbar, Tag } from 'rsuite';
import { useQuery, useQueryClient } from 'react-query'; import { useQuery, useQueryClient } from 'react-query';
import { useParams, useHistory } from 'react-router-dom'; import { useParams, useHistory } from 'react-router-dom';
import { FavoriteButton, PlayAppendButton, PlayButton } from '../shared/ToolbarButtons'; import {
FavoriteButton,
PlayAppendButton,
PlayAppendNextButton,
PlayButton,
} from '../shared/ToolbarButtons';
import { getAlbum, star, unstar } from '../../api/api'; import { getAlbum, star, unstar } from '../../api/api';
import { useAppDispatch, useAppSelector } from '../../redux/hooks'; import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import { import {
@ -98,8 +103,8 @@ const AlbumView = ({ ...rest }: any) => {
notifyToast('info', `Playing ${data.song.length} song(s)`); notifyToast('info', `Playing ${data.song.length} song(s)`);
}; };
const handlePlayAppend = () => { const handlePlayAppend = (type: 'next' | 'later') => {
dispatch(appendPlayQueue({ entries: data.song })); dispatch(appendPlayQueue({ entries: data.song, type }));
if (playQueue.entry.length < 1) { if (playQueue.entry.length < 1) {
dispatch(setStatus('PLAYING')); dispatch(setStatus('PLAYING'));
} }
@ -198,9 +203,18 @@ const AlbumView = ({ ...rest }: any) => {
</div> </div>
<div style={{ marginTop: '10px' }}> <div style={{ marginTop: '10px' }}>
<ButtonToolbar> <ButtonToolbar>
<PlayButton appearance="primary" size="lg" onClick={handlePlay} /> <PlayButton appearance="primary" size="md" onClick={handlePlay} />
<PlayAppendButton appearance="primary" size="lg" onClick={handlePlayAppend} /> <PlayAppendButton
<FavoriteButton size="lg" isFavorite={data.starred} onClick={handleFavorite} /> appearance="primary"
size="md"
onClick={() => handlePlayAppend('later')}
/>
<PlayAppendNextButton
appearance="primary"
size="md"
onClick={() => handlePlayAppend('next')}
/>
<FavoriteButton size="md" isFavorite={data.starred} onClick={handleFavorite} />
</ButtonToolbar> </ButtonToolbar>
</div> </div>
</div> </div>

28
src/components/library/ArtistView.tsx

@ -5,7 +5,12 @@ import settings from 'electron-settings';
import { ButtonToolbar, Tag, Whisper, Button, Popover, TagGroup } from 'rsuite'; import { ButtonToolbar, Tag, Whisper, Button, Popover, TagGroup } from 'rsuite';
import { useQuery, useQueryClient } from 'react-query'; import { useQuery, useQueryClient } from 'react-query';
import { useParams, useHistory } from 'react-router-dom'; import { useParams, useHistory } from 'react-router-dom';
import { FavoriteButton, PlayAppendButton, PlayButton } from '../shared/ToolbarButtons'; import {
FavoriteButton,
PlayAppendButton,
PlayAppendNextButton,
PlayButton,
} from '../shared/ToolbarButtons';
import { getAllArtistSongs, getArtist, getArtistInfo, star, unstar } from '../../api/api'; import { getAllArtistSongs, getArtist, getArtistInfo, star, unstar } from '../../api/api';
import { useAppDispatch } from '../../redux/hooks'; import { useAppDispatch } from '../../redux/hooks';
import { import {
@ -94,9 +99,9 @@ const ArtistView = ({ ...rest }: any) => {
notifyToast('info', `Playing ${songs.length} song(s)`); notifyToast('info', `Playing ${songs.length} song(s)`);
}; };
const handlePlayAppend = async () => { const handlePlayAppend = async (type: 'next' | 'later') => {
const songs = await getAllArtistSongs(data.id); const songs = await getAllArtistSongs(data.id);
dispatch(appendPlayQueue({ entries: songs })); dispatch(appendPlayQueue({ entries: songs, type }));
notifyToast('info', `Added ${songs.length} song(s)`); notifyToast('info', `Added ${songs.length} song(s)`);
}; };
@ -165,9 +170,18 @@ const ArtistView = ({ ...rest }: any) => {
</CustomTooltip> </CustomTooltip>
<div style={{ marginTop: '10px' }}> <div style={{ marginTop: '10px' }}>
<ButtonToolbar> <ButtonToolbar>
<PlayButton appearance="primary" size="lg" onClick={handlePlay} /> <PlayButton appearance="primary" size="md" onClick={handlePlay} />
<PlayAppendButton appearance="primary" size="lg" onClick={handlePlayAppend} /> <PlayAppendButton
<FavoriteButton size="lg" isFavorite={data.starred} onClick={handleFavorite} /> appearance="primary"
size="md"
onClick={() => handlePlayAppend('later')}
/>
<PlayAppendNextButton
appearance="primary"
size="md"
onClick={() => handlePlayAppend('later')}
/>
<FavoriteButton size="md" isFavorite={data.starred} onClick={handleFavorite} />
<Whisper <Whisper
placement="bottomStart" placement="bottomStart"
trigger="hover" trigger="hover"
@ -199,7 +213,7 @@ const ArtistView = ({ ...rest }: any) => {
</Popover> </Popover>
} }
> >
<Button size="lg">Related Artists</Button> <Button size="md">Related Artists</Button>
</Whisper> </Whisper>
</ButtonToolbar> </ButtonToolbar>
</div> </div>

3
src/components/library/GenreList.tsx

@ -78,7 +78,8 @@ const GenreList = () => {
virtualized virtualized
disabledContextMenuOptions={[ disabledContextMenuOptions={[
'play', 'play',
'addToQueue', 'addToQueueNext',
'addToQueueLast',
'moveSelectedTo', 'moveSelectedTo',
'removeFromCurrent', 'removeFromCurrent',
'addToPlaylist', 'addToPlaylist',

28
src/components/player/NowPlayingView.tsx

@ -168,7 +168,7 @@ const NowPlayingView = () => {
} }
}; };
const handlePlayRandom = async (action: 'play' | 'add') => { const handlePlayRandom = async (action: 'play' | 'addNext' | 'addLater') => {
setIsLoadingRandom(true); setIsLoadingRandom(true);
const res = await getRandomSongs({ const res = await getRandomSongs({
size: randomPlaylistTrackCount, size: randomPlaylistTrackCount,
@ -198,8 +198,17 @@ const NowPlayingView = () => {
difference !== 0 ? `(-${difference} invalid)` : '' difference !== 0 ? `(-${difference} invalid)` : ''
} song(s)` } 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 { } else {
dispatch(appendPlayQueue({ entries: cleanedSongs })); dispatch(appendPlayQueue({ entries: cleanedSongs, type: 'next' }));
if (playQueue.entry.length < 1) { if (playQueue.entry.length < 1) {
dispatch(setStatus('PLAYING')); dispatch(setStatus('PLAYING'));
} }
@ -329,6 +338,8 @@ const NowPlayingView = () => {
<br /> <br />
<ButtonToolbar> <ButtonToolbar>
<StyledButton <StyledButton
block
appearance="primary"
onClick={() => handlePlayRandom('play')} onClick={() => handlePlayRandom('play')}
loading={isLoadingRandom} loading={isLoadingRandom}
disabled={!(typeof randomPlaylistTrackCount === 'number')} disabled={!(typeof randomPlaylistTrackCount === 'number')}
@ -336,12 +347,21 @@ const NowPlayingView = () => {
<Icon icon="play" style={{ marginRight: '10px' }} /> <Icon icon="play" style={{ marginRight: '10px' }} />
Play Play
</StyledButton> </StyledButton>
</ButtonToolbar>
<ButtonToolbar>
<StyledButton
onClick={() => handlePlayRandom('addNext')}
loading={isLoadingRandom}
disabled={!(typeof randomPlaylistTrackCount === 'number')}
>
<Icon icon="plus" style={{ marginRight: '10px' }} /> Add (next)
</StyledButton>
<StyledButton <StyledButton
onClick={() => handlePlayRandom('add')} onClick={() => handlePlayRandom('addLater')}
loading={isLoadingRandom} loading={isLoadingRandom}
disabled={!(typeof randomPlaylistTrackCount === 'number')} disabled={!(typeof randomPlaylistTrackCount === 'number')}
> >
<Icon icon="plus" style={{ marginRight: '10px' }} /> Add to queue <Icon icon="plus" style={{ marginRight: '10px' }} /> Add (later)
</StyledButton> </StyledButton>
</ButtonToolbar> </ButtonToolbar>
</StyledPopover> </StyledPopover>

27
src/components/playlist/PlaylistView.tsx

@ -11,6 +11,7 @@ import {
DeleteButton, DeleteButton,
EditButton, EditButton,
PlayAppendButton, PlayAppendButton,
PlayAppendNextButton,
PlayButton, PlayButton,
SaveButton, SaveButton,
UndoButton, UndoButton,
@ -175,8 +176,8 @@ const PlaylistView = ({ ...rest }) => {
notifyToast('info', `Playing ${playlist.entry.length} song(s)`); notifyToast('info', `Playing ${playlist.entry.length} song(s)`);
}; };
const handlePlayAppend = () => { const handlePlayAppend = (type: 'next' | 'later') => {
dispatch(appendPlayQueue({ entries: playlist.entry })); dispatch(appendPlayQueue({ entries: playlist.entry, type }));
if (playQueue.entry.length < 1) { if (playQueue.entry.length < 1) {
dispatch(setStatus('PLAYING')); dispatch(setStatus('PLAYING'));
} }
@ -363,18 +364,24 @@ const PlaylistView = ({ ...rest }) => {
<ButtonToolbar> <ButtonToolbar>
<PlayButton <PlayButton
appearance="primary" appearance="primary"
size="lg" size="md"
onClick={handlePlay} onClick={handlePlay}
disabled={playlist.entry?.length < 1} disabled={playlist.entry?.length < 1}
/> />
<PlayAppendButton <PlayAppendButton
appearance="primary" appearance="primary"
size="lg" size="md"
onClick={handlePlayAppend} onClick={() => handlePlayAppend('later')}
disabled={playlist.entry?.length < 1}
/>
<PlayAppendNextButton
appearance="primary"
size="md"
onClick={() => handlePlayAppend('next')}
disabled={playlist.entry?.length < 1} disabled={playlist.entry?.length < 1}
/> />
<SaveButton <SaveButton
size="lg" size="md"
text={ text={
needsRecovery needsRecovery
? 'Recover playlist' ? 'Recover playlist'
@ -389,7 +396,7 @@ const PlaylistView = ({ ...rest }) => {
onClick={() => handleSave(needsRecovery)} onClick={() => handleSave(needsRecovery)}
/> />
<UndoButton <UndoButton
size="lg" size="md"
color={needsRecovery ? 'red' : undefined} color={needsRecovery ? 'red' : undefined}
disabled={ disabled={
needsRecovery || !isModified || misc.isProcessingPlaylist.includes(data?.id) needsRecovery || !isModified || misc.isProcessingPlaylist.includes(data?.id)
@ -427,7 +434,7 @@ const PlaylistView = ({ ...rest }) => {
</StyledCheckbox> </StyledCheckbox>
<br /> <br />
<StyledButton <StyledButton
size="sm" size="md"
type="submit" type="submit"
block block
loading={isSubmittingEdit} loading={isSubmittingEdit}
@ -441,7 +448,7 @@ const PlaylistView = ({ ...rest }) => {
</Popover> </Popover>
} }
> >
<EditButton size="lg" disabled={misc.isProcessingPlaylist.includes(data?.id)} /> <EditButton size="md" disabled={misc.isProcessingPlaylist.includes(data?.id)} />
</Whisper> </Whisper>
<Whisper <Whisper
@ -458,7 +465,7 @@ const PlaylistView = ({ ...rest }) => {
} }
> >
<DeleteButton <DeleteButton
size="lg" size="md"
disabled={misc.isProcessingPlaylist.includes(data?.id)} disabled={misc.isProcessingPlaylist.includes(data?.id)}
/> />
</Whisper> </Whisper>

Loading…
Cancel
Save