feat: add playing status on sidebar playlists (#1517)

* udpate playing status on sidebar playlists

* update player mode logic & delete unused codes

* change sidebar svg to volume-half

* format code and relevant optimizations

* justify-between

* change object visit mode to dot.

* delete duplited `flex` class

* add playlist id check
in case playlist id conflicts with album.
This commit is contained in:
L.Ryland 2022-04-12 22:18:37 +08:00 committed by GitHub
parent 1591586735
commit 3626095d97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 16 deletions

View File

@ -30,7 +30,8 @@ const PlayingTrack = () => {
[playerSnapshot.trackListSource] [playerSnapshot.trackListSource]
) )
const hasListSource = playerSnapshot.mode !== PlayerMode.FM && trackListSource?.type const hasListSource =
playerSnapshot.mode !== PlayerMode.FM && trackListSource?.type
const toTrackListSource = () => { const toTrackListSource = () => {
if (!hasListSource) return if (!hasListSource) return

View File

@ -3,17 +3,10 @@ import SvgIcon from './SvgIcon'
import useUserPlaylists from '@/renderer/hooks/useUserPlaylists' import useUserPlaylists from '@/renderer/hooks/useUserPlaylists'
import { scrollToTop } from '@/renderer/utils/common' import { scrollToTop } from '@/renderer/utils/common'
import { prefetchPlaylist } from '@/renderer/hooks/usePlaylist' import { prefetchPlaylist } from '@/renderer/hooks/usePlaylist'
import { player } from '@/renderer/store'
import { Mode, TrackListSourceType } from '@/renderer/utils/player'
interface Tab { const primaryTabs = [
name: string
icon: string
route: string
}
interface PrimaryTab extends Tab {
icon: string
}
const primaryTabs: PrimaryTab[] = [
{ {
name: '主页', name: '主页',
icon: 'home', icon: 'home',
@ -29,7 +22,7 @@ const primaryTabs: PrimaryTab[] = [
icon: 'music-library', icon: 'music-library',
route: '/library', route: '/library',
}, },
] ] as const
const PrimaryTabs = () => { const PrimaryTabs = () => {
return ( return (
@ -62,6 +55,16 @@ const PrimaryTabs = () => {
const Playlists = () => { const Playlists = () => {
const { data: playlists } = useUserPlaylists() const { data: playlists } = useUserPlaylists()
const playerSnapshot = useSnapshot(player)
const currentPlaylistID = useMemo(
() => playerSnapshot.trackListSource?.id,
[playerSnapshot.trackListSource]
)
const playlistMode = useMemo(
() => playerSnapshot.trackListSource?.type,
[playerSnapshot.trackListSource]
)
const mode = useMemo(() => playerSnapshot.mode, [playerSnapshot.mode])
return ( return (
<div className='mb-16 overflow-auto pb-2'> <div className='mb-16 overflow-auto pb-2'>
@ -73,12 +76,17 @@ const Playlists = () => {
to={`/playlist/${playlist.id}`} to={`/playlist/${playlist.id}`}
className={({ isActive }: { isActive: boolean }) => className={({ isActive }: { isActive: boolean }) =>
classNames( classNames(
'btn-hover-animation line-clamp-1 my-px mx-3 flex cursor-default items-center rounded-lg px-3 py-[0.38rem] text-sm text-black opacity-70 transition-colors duration-200 after:scale-[0.97] after:bg-black/[.06] dark:text-white dark:after:bg-white/20', 'btn-hover-animation line-clamp-1 my-px mx-3 flex cursor-default items-center justify-between rounded-lg px-3 py-[0.38rem] text-sm text-black opacity-70 transition-colors duration-200 after:scale-[0.97] after:bg-black/[.06] dark:text-white dark:after:bg-white/20',
isActive && 'after:scale-100 after:opacity-100' isActive && 'after:scale-100 after:opacity-100'
) )
} }
> >
<span className='line-clamp-1'>{playlist.name}</span> <span className='line-clamp-1'>{playlist.name}</span>
{playlistMode === TrackListSourceType.PLAYLIST &&
mode === Mode.PLAYLIST &&
currentPlaylistID === playlist.id && (
<SvgIcon className='h-5 w-5' name='volume-half' />
)}
</NavLink> </NavLink>
))} ))}
</div> </div>

View File

@ -1,4 +1,50 @@
const SvgIcon = ({ name, className }: { name: string; className?: string }) => { type SvgName =
| 'back'
| 'dislike'
| 'dj'
| 'email'
| 'explicit'
| 'eye-off'
| 'eye'
| 'fm'
| 'forward'
| 'heart-outline'
| 'heart'
| 'home'
| 'lock'
| 'lyrics'
| 'more'
| 'music-library'
| 'music-note'
| 'next'
| 'pause'
| 'phone'
| 'play-fill'
| 'play'
| 'playlist'
| 'podcast'
| 'previous'
| 'qrcode'
| 'repeat'
| 'repeat-1'
| 'search'
| 'settings'
| 'shuffle'
| 'user'
| 'volume-half'
| 'volume-mute'
| 'volume'
| 'windows-close'
| 'windows-maximize'
| 'windows-un-maximize'
| 'x'
const SvgIcon = ({
name,
className,
}: {
name: SvgName
className?: string
}) => {
const symbolId = `#icon-${name}` const symbolId = `#icon-${name}`
return ( return (
<svg aria-hidden='true' className={className}> <svg aria-hidden='true' className={className}>

View File

@ -13,7 +13,7 @@ import { fetchPlaylistWithReactQuery } from '@/renderer/hooks/usePlaylist'
import { fetchAlbumWithReactQuery } from '@/renderer/hooks/useAlbum' import { fetchAlbumWithReactQuery } from '@/renderer/hooks/useAlbum'
type TrackID = number type TrackID = number
enum TrackListSourceType { export enum TrackListSourceType {
ALBUM = 'album', ALBUM = 'album',
PLAYLIST = 'playlist', PLAYLIST = 'playlist',
} }
@ -269,7 +269,9 @@ export class Player {
if (this.fmTrackList.length === 0) await this._loadMoreFMTracks() if (this.fmTrackList.length === 0) await this._loadMoreFMTracks()
this._playTrack() this._playTrack()
this.fmTrackList.length <= 1 ? await this._loadMoreFMTracks() : this._loadMoreFMTracks() this.fmTrackList.length <= 1
? await this._loadMoreFMTracks()
: this._loadMoreFMTracks()
prefetchNextTrack() prefetchNextTrack()
} }