mirror of
https://github.com/GiriNeko/YesPlayMusic.git
synced 2025-12-16 13:17:46 +00:00
fix: bugs (#1579)
* fix: 让从本地缓存获取的音乐可以拖动进度条 * fix: 登陆二维码使用SVG & 二维码支持强调色 * fix: 搜索页面在没有取得结果不再白屏 * fix: 避免私人FM出现相同的歌曲连着出现 * fix: 给部分api添加时间戳参数 因为发现无法获取个性化推荐歌单,添加时间戳后成功获取 * 改用`Date.now()` * 将个性化推荐放在推荐歌单的前面
This commit is contained in:
parent
07d7564b1e
commit
4d59401549
7 changed files with 41 additions and 14 deletions
|
|
@ -275,7 +275,12 @@ class Cache {
|
||||||
fs.unlinkSync(path)
|
fs.unlinkSync(path)
|
||||||
return res.status(404).send({ error: 'Audio not found' })
|
return res.status(404).send({ error: 'Audio not found' })
|
||||||
}
|
}
|
||||||
res.send(audio)
|
res
|
||||||
|
.status(206)
|
||||||
|
.setHeader('Accept-Ranges', 'bytes')
|
||||||
|
.setHeader('Connection', 'keep-alive')
|
||||||
|
.setHeader('Content-Range', `bytes 0-${audio.byteLength - 1}/${audio.byteLength}`)
|
||||||
|
.send(audio)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).send({ error })
|
res.status(500).send({ error })
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,9 @@ export function fetchPersonalFM(): Promise<FetchPersonalFMResponse> {
|
||||||
return request({
|
return request({
|
||||||
url: '/personal/fm',
|
url: '/personal/fm',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,6 +113,7 @@ export function fmTrash(id: number): Promise<FMTrashResponse> {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
params: {
|
params: {
|
||||||
id,
|
id,
|
||||||
|
timestamp: Date.now(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,9 @@ export function fetchDailyRecommendPlaylists(): Promise<FetchDailyRecommendPlayl
|
||||||
return request({
|
return request({
|
||||||
url: '/recommend/resource',
|
url: '/recommend/resource',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ export default function Home() {
|
||||||
...(recommendedPlaylists?.result ?? []),
|
...(recommendedPlaylists?.result ?? []),
|
||||||
]
|
]
|
||||||
.slice(0, 10)
|
.slice(0, 10)
|
||||||
.reverse()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ enum Method {
|
||||||
Phone = 'phone',
|
Phone = 'phone',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const domParser = new DOMParser()
|
||||||
|
|
||||||
// Shared components and methods
|
// Shared components and methods
|
||||||
const EmailInput = ({
|
const EmailInput = ({
|
||||||
email,
|
email,
|
||||||
|
|
@ -367,23 +369,34 @@ const LoginWithQRCode = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const updateImage = async () => {
|
const updateImage = async () => {
|
||||||
const image = await QRCode.toDataURL(qrCodeUrl, {
|
const svg = await QRCode.toString(qrCodeUrl, {
|
||||||
width: 1024,
|
|
||||||
margin: 0,
|
margin: 0,
|
||||||
color: {
|
color: {
|
||||||
dark: '#335eea', // TODO: change brand color
|
|
||||||
light: '#ffffff00',
|
light: '#ffffff00',
|
||||||
},
|
},
|
||||||
|
type: 'svg',
|
||||||
})
|
})
|
||||||
setQrCodeImage(image)
|
const path = domParser
|
||||||
|
.parseFromString(svg, 'text/xml')
|
||||||
|
.getElementsByTagName('path')[0]
|
||||||
|
|
||||||
|
setQrCodeImage(path?.getAttribute('d') ?? '')
|
||||||
}
|
}
|
||||||
updateImage()
|
updateImage()
|
||||||
}, [qrCodeUrl])
|
}, [qrCodeUrl])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col items-center justify-center'>
|
<div className='flex flex-col items-center justify-center'>
|
||||||
<div className='rounded-3xl border p-6 dark:border-gray-700'>
|
<div className='rounded-3xl border p-6 text-brand-500 dark:border-gray-700'>
|
||||||
<img src={qrCodeImage} alt='QR Code' className='no-drag' />
|
<svg
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
width='270'
|
||||||
|
height='270'
|
||||||
|
viewBox='0 0 37 37'
|
||||||
|
shapeRendering='crispEdges'
|
||||||
|
>
|
||||||
|
<path stroke='currentColor' d={qrCodeImage} />
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-4 text-sm text-gray-500 dark:text-gray-200'>
|
<div className='mt-4 text-sm text-gray-500 dark:text-gray-200'>
|
||||||
{qrCodeMessage}
|
{qrCodeMessage}
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ const Search = () => {
|
||||||
|
|
||||||
const handlePlayTracks = useCallback(
|
const handlePlayTracks = useCallback(
|
||||||
(trackID: number | null = null) => {
|
(trackID: number | null = null) => {
|
||||||
const tracks = searchResult?.result.song.songs
|
const tracks = searchResult?.result?.song?.songs
|
||||||
if (!tracks?.length) {
|
if (!tracks?.length) {
|
||||||
toast('无法播放歌单')
|
toast('无法播放歌单')
|
||||||
return
|
return
|
||||||
|
|
@ -108,7 +108,7 @@ const Search = () => {
|
||||||
trackID
|
trackID
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
[searchResult?.result.song.songs]
|
[searchResult?.result?.song?.songs]
|
||||||
)
|
)
|
||||||
|
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
@ -163,21 +163,21 @@ const Search = () => {
|
||||||
|
|
||||||
{/* Search result */}
|
{/* Search result */}
|
||||||
<div className='grid grid-cols-2 gap-6'>
|
<div className='grid grid-cols-2 gap-6'>
|
||||||
{searchResult?.result.artist.artists && (
|
{searchResult?.result?.artist?.artists && (
|
||||||
<div>
|
<div>
|
||||||
<div className='mb-2 text-sm font-medium text-gray-400'>艺人</div>
|
<div className='mb-2 text-sm font-medium text-gray-400'>艺人</div>
|
||||||
<Artists artists={searchResult.result.artist.artists} />
|
<Artists artists={searchResult.result.artist.artists} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{searchResult?.result.album.albums && (
|
{searchResult?.result?.album?.albums && (
|
||||||
<div>
|
<div>
|
||||||
<div className='mb-2 text-sm font-medium text-gray-400'>专辑</div>
|
<div className='mb-2 text-sm font-medium text-gray-400'>专辑</div>
|
||||||
<Albums albums={searchResult.result.album.albums} />
|
<Albums albums={searchResult.result.album.albums} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{searchResult?.result.song.songs && (
|
{searchResult?.result?.song?.songs && (
|
||||||
<div className='col-span-2'>
|
<div className='col-span-2'>
|
||||||
<div className='mb-2 text-sm font-medium text-gray-400'>歌曲</div>
|
<div className='mb-2 text-sm font-medium text-gray-400'>歌曲</div>
|
||||||
<TrackGrid
|
<TrackGrid
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,10 @@ export class Player {
|
||||||
private async _loadMoreFMTracks() {
|
private async _loadMoreFMTracks() {
|
||||||
if (this.fmTrackList.length <= 5) {
|
if (this.fmTrackList.length <= 5) {
|
||||||
const response = await fetchPersonalFMWithReactQuery()
|
const response = await fetchPersonalFMWithReactQuery()
|
||||||
this.fmTrackList.push(...(response?.data?.map(r => r.id) ?? []))
|
const ids = (response?.data?.map(r => r.id) ?? []).filter(
|
||||||
|
r => !this.fmTrackList.includes(r)
|
||||||
|
)
|
||||||
|
this.fmTrackList.push(...ids)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue