feat: updates

This commit is contained in:
qier222 2023-01-07 14:39:03 +08:00
parent 884f3df41a
commit c6c59b2cd9
No known key found for this signature in database
84 changed files with 3531 additions and 2616 deletions

View file

@ -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 */}

View file

@ -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

View file

@ -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}

View file

@ -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 })

View file

@ -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

View file

@ -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>