mirror of
https://github.com/GiriNeko/YesPlayMusic.git
synced 2025-12-16 13:17:46 +00:00
feat: updates
This commit is contained in:
parent
884f3df41a
commit
c6c59b2cd9
84 changed files with 3531 additions and 2616 deletions
|
|
@ -2,7 +2,7 @@ import Header from './Header'
|
|||
import Popular from './Popular'
|
||||
import ArtistAlbum from './ArtistAlbums'
|
||||
import FansAlsoLike from './FansAlsoLike'
|
||||
import ArtistMVs from './ArtistMVs'
|
||||
import ArtistVideos from './ArtistVideos'
|
||||
|
||||
const Artist = () => {
|
||||
return (
|
||||
|
|
@ -12,7 +12,7 @@ const Artist = () => {
|
|||
<div className='mt-10 mb-7.5 h-px w-full bg-white/20'></div>
|
||||
<Popular />
|
||||
<ArtistAlbum />
|
||||
<ArtistMVs />
|
||||
<ArtistVideos />
|
||||
<FansAlsoLike />
|
||||
|
||||
{/* Page padding */}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import useArtistMV from '@/web/api/hooks/useArtistMV'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import uiStates from '@/web/states/uiStates'
|
||||
|
||||
const ArtistMVs = () => {
|
||||
const ArtistVideos = () => {
|
||||
const { t } = useTranslation()
|
||||
const params = useParams()
|
||||
const navigate = useNavigate()
|
||||
const { data: videos } = useArtistMV({ id: Number(params.id) || 0 })
|
||||
|
||||
return (
|
||||
|
|
@ -16,10 +16,13 @@ const ArtistMVs = () => {
|
|||
|
||||
<div className='grid grid-cols-3 gap-6'>
|
||||
{videos?.mvs?.slice(0, 6)?.map(video => (
|
||||
<div key={video.id} onClick={() => navigate(`/mv/${video.id}`)}>
|
||||
<div
|
||||
key={video.id}
|
||||
onClick={() => (uiStates.playingVideoID = video.id)}
|
||||
>
|
||||
<img
|
||||
src={video.imgurl16v9}
|
||||
className='aspect-video w-full rounded-24 object-contain'
|
||||
className='aspect-video w-full rounded-24 border border-white/5 object-contain'
|
||||
/>
|
||||
<div className='mt-2 text-12 font-medium text-neutral-600'>
|
||||
{video.name}
|
||||
|
|
@ -31,4 +34,4 @@ const ArtistMVs = () => {
|
|||
)
|
||||
}
|
||||
|
||||
export default ArtistMVs
|
||||
export default ArtistVideos
|
||||
|
|
@ -8,6 +8,7 @@ import { useMemo } from 'react'
|
|||
import useArtistMV from '@/web/api/hooks/useArtistMV'
|
||||
import { motion } from 'framer-motion'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import uiStates from '@/web/states/uiStates'
|
||||
|
||||
const Album = ({ album }: { album?: Album }) => {
|
||||
const navigate = useNavigate()
|
||||
|
|
@ -49,14 +50,12 @@ const Album = ({ album }: { album?: Album }) => {
|
|||
}
|
||||
|
||||
const Video = ({ video }: { video?: any }) => {
|
||||
const navigate = useNavigate()
|
||||
|
||||
return (
|
||||
<>
|
||||
{video && (
|
||||
<div
|
||||
className='group mt-4 flex rounded-24 bg-white/10 p-2.5 transition-colors duration-400 hover:bg-white/20'
|
||||
onClick={() => navigate(`/mv/${video.id}`)}
|
||||
onClick={() => (uiStates.playingVideoID = video.id)}
|
||||
>
|
||||
<img
|
||||
src={video.imgurl16v9}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import {
|
|||
fetchFromCache,
|
||||
} from '@/web/api/hooks/usePlaylist'
|
||||
import { fetchTracksWithReactQuery } from '@/web/api/hooks/useTracks'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { sampleSize } from 'lodash-es'
|
||||
import { FetchPlaylistResponse } from '@/shared/api/Playlists'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
|
|
@ -31,27 +30,19 @@ const getAlbumsFromAPI = async () => {
|
|||
7463185187, // 开发者夹带私货
|
||||
]
|
||||
|
||||
const playlists = (await Promise.all(
|
||||
sampleSize(playlistsIds, 5).map(
|
||||
id =>
|
||||
new Promise(resolve => {
|
||||
const cache = fetchFromCache(id)
|
||||
if (cache) {
|
||||
resolve(cache)
|
||||
return
|
||||
}
|
||||
resolve(fetchPlaylistWithReactQuery({ id }))
|
||||
})
|
||||
)
|
||||
)) as FetchPlaylistResponse[]
|
||||
const playlists: FetchPlaylistResponse[] = await Promise.all(
|
||||
sampleSize(playlistsIds, 5).map(async id => {
|
||||
const cache = await fetchFromCache({ id })
|
||||
if (cache) return cache
|
||||
return fetchPlaylistWithReactQuery({ id })
|
||||
})
|
||||
)
|
||||
|
||||
let ids: number[] = []
|
||||
playlists.forEach(playlist =>
|
||||
playlist?.playlist?.trackIds?.forEach(t => ids.push(t.id))
|
||||
)
|
||||
if (!ids.length) {
|
||||
return []
|
||||
}
|
||||
if (!ids.length) return []
|
||||
ids = sampleSize(ids, 100)
|
||||
|
||||
const tracks = await fetchTracksWithReactQuery({ ids })
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
import PageTransition from '@/web/components/PageTransition'
|
||||
import useMV, { useMVUrl } from '@/web/api/hooks/useMV'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import Plyr, { PlyrOptions, PlyrSource } from 'plyr-react'
|
||||
import 'plyr-react/plyr.css'
|
||||
import { useMemo } from 'react'
|
||||
import { css, cx } from '@emotion/css'
|
||||
|
||||
const plyrStyle = css`
|
||||
--plyr-color-main: rgb(152 208 11);
|
||||
--plyr-video-control-background-hover: rgba(255, 255, 255, 0.3);
|
||||
--plyr-control-radius: 8px;
|
||||
--plyr-range-fill-background: white;
|
||||
button[data-plyr='play']:not(.plyr__controls__item) {
|
||||
--plyr-video-control-background-hover: var(--plyr-color-main);
|
||||
}
|
||||
`
|
||||
|
||||
const plyrOptions: PlyrOptions = {
|
||||
settings: [],
|
||||
controls: [
|
||||
'play-large',
|
||||
'play',
|
||||
'progress',
|
||||
'current-time',
|
||||
'mute',
|
||||
'volume',
|
||||
'fullscreen',
|
||||
],
|
||||
resetOnEnd: true,
|
||||
ratio: '16:9',
|
||||
}
|
||||
|
||||
const MV = () => {
|
||||
const params = useParams()
|
||||
const { data: mv } = useMV({ mvid: Number(params.id) || 0 })
|
||||
const { data: mvUrl } = useMVUrl({ id: Number(params.id) || 0 })
|
||||
const source: PlyrSource = useMemo(
|
||||
() => ({
|
||||
type: 'video',
|
||||
sources: [
|
||||
{
|
||||
src: mvUrl?.data?.url || '',
|
||||
},
|
||||
],
|
||||
poster: mv?.data.cover,
|
||||
title: mv?.data.name,
|
||||
}),
|
||||
[mv?.data.cover, mv?.data.name, mvUrl?.data?.url]
|
||||
)
|
||||
|
||||
return (
|
||||
<PageTransition>
|
||||
<div className='text-white'>{mv?.data.name}</div>
|
||||
<div className={cx('aspect-video overflow-hidden rounded-24', plyrStyle)}>
|
||||
{mvUrl && <Plyr options={plyrOptions} source={source} />}
|
||||
</div>
|
||||
</PageTransition>
|
||||
)
|
||||
}
|
||||
|
||||
export default MV
|
||||
|
|
@ -15,6 +15,8 @@ import { AnimatePresence, motion } from 'framer-motion'
|
|||
import { scrollToBottom } from '@/web/utils/common'
|
||||
import { throttle } from 'lodash-es'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import VideoRow from '@/web/components/VideoRow'
|
||||
import useUserVideos from '@/web/api/hooks/useUserVideos'
|
||||
|
||||
const Albums = () => {
|
||||
const { data: albums } = useUserAlbums()
|
||||
|
|
@ -35,6 +37,11 @@ const Artists = () => {
|
|||
return <ArtistRow artists={artists?.data || []} />
|
||||
}
|
||||
|
||||
const Videos = () => {
|
||||
const { data: videos } = useUserVideos()
|
||||
return <VideoRow videos={videos?.data || []} />
|
||||
}
|
||||
|
||||
const CollectionTabs = ({ showBg }: { showBg: boolean }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
|
|
@ -130,6 +137,7 @@ const Collections = () => {
|
|||
{selectedTab === 'albums' && <Albums />}
|
||||
{selectedTab === 'playlists' && <Playlists />}
|
||||
{selectedTab === 'artists' && <Artists />}
|
||||
{selectedTab === 'videos' && <Videos />}
|
||||
</div>
|
||||
<div ref={observePoint}></div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue