mirror of
https://github.com/GiriNeko/YesPlayMusic.git
synced 2025-12-16 05:08:04 +00:00
feat: updates
This commit is contained in:
parent
74dcb36e67
commit
b5f681631e
15 changed files with 320 additions and 99 deletions
|
|
@ -21,6 +21,8 @@
|
|||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sentry/node": "^6.19.2",
|
||||
"@sentry/tracing": "^6.19.2",
|
||||
"NeteaseCloudMusicApi": "^4.5.8",
|
||||
"change-case": "^4.1.2",
|
||||
"cookie-parser": "^1.4.6",
|
||||
|
|
@ -30,6 +32,7 @@
|
|||
"realm": "^10.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sentry/react": "^6.19.2",
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/express-fileupload": "^1.2.2",
|
||||
|
|
|
|||
|
|
@ -99,7 +99,6 @@ export function getCache(
|
|||
if (!isIDsValid) return
|
||||
|
||||
const idsQuery = ids.map(id => `id = ${id}`).join(' OR ')
|
||||
console.log(idsQuery)
|
||||
const tracksRaw = realm
|
||||
.objects(ModelNames.TRACK)
|
||||
.filtered(`(${idsQuery})`)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import './preload' // must be first
|
||||
import './sentry'
|
||||
import {
|
||||
BrowserWindow,
|
||||
BrowserWindowConstructorOptions,
|
||||
|
|
|
|||
14
packages/main/sentry.ts
Normal file
14
packages/main/sentry.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import * as Sentry from '@sentry/node'
|
||||
import * as Tracing from '@sentry/tracing'
|
||||
import pkg from '../../package.json'
|
||||
|
||||
Sentry.init({
|
||||
dsn: 'https://2aaaa67f1c3d4d6baefafa5d58fcf340@o436528.ingest.sentry.io/6274637',
|
||||
release: `yesplaymusic@${pkg.version}`,
|
||||
environment: import.meta.env.MODE,
|
||||
|
||||
// Set tracesSampleRate to 1.0 to capture 100%
|
||||
// of transactions for performance monitoring.
|
||||
// We recommend adjusting this value in production
|
||||
tracesSampleRate: 1.0,
|
||||
})
|
||||
|
|
@ -1,2 +1,4 @@
|
|||
<svg viewBox="0 0 576 512" xmlns="http://www.w3.org/2000/svg"><path d="M301.2 34.85c-11.5-5.19-25.02-3.122-34.44 5.253L131.8 160H48c-26.51 0-48 21.49-48 47.1v95.1c0 26.51 21.49 47.1 48 47.1h83.84l134.9 119.9c5.98 5.31 13.58 8.09 21.26 8.09 4.43 0 8.97-.94 13.17-2.85 11.5-5.16 18.82-16.56 18.82-29.16V63.99c-.89-12.59-7.29-24-18.79-29.15ZM513.9 255.1l47.03-47.03c9.375-9.375 9.375-24.56 0-33.94 -9.375-9.38-24.56-9.375-33.94 0L480 222.1 432.1 175c-9.375-9.375-24.56-9.375-33.94 0 -9.38 9.375-9.375 24.56 0 33.94l47.03 47.03L398.16 303c-9.375 9.375-9.375 24.56 0 33.94 9.37 9.37 24.56 9.38 33.94 0L480 289.9l47.03 47.03c9.37 9.37 24.56 9.38 33.94 0 9.375-9.375 9.375-24.56 0-33.94L513.9 255.1Z"/></svg>
|
||||
<svg viewBox="0 0 448 512" xmlns="http://www.w3.org/2000/svg"><path d="M412.6 181.9c-10.28-8.35-25.41-6.875-33.75 3.4 -8.41 10.25-6.91 25.37 3.375 33.78 11.27 9.31 17.77 22.714 17.77 36.91 0 14.19-6.5 27.62-17.81 36.87 -10.28 8.4-11.78 23.53-3.375 33.78 4.71 5.81 11.62 8.81 18.56 8.81 5.34 0 10.75-1.79 15.19-5.41 22.53-18.46 35.435-45.36 35.435-74.06 0-28.7-12.9-55.6-35.4-74.1ZM301.2 34.84c-11.5-5.19-25.01-3.12-34.43 5.25L131.8 159.99H48c-26.51 0-48 21.49-48 47.1v95.1c0 26.51 21.49 47.1 48 47.1h83.84l134.9 119.9c5.96 8 13.56 10.8 21.26 10.8 4.43 0 8.95-.94 13.16-2.84 11.54-5.17 18.84-16.57 18.84-29.17v-384c0-12.59-7.3-24.9-18.8-29.16Z"/></svg>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.4966 5.50774L10.4966 5.50774L6.61626 9H4.5C3.67157 9 3 9.67157 3 10.5V13.5C3 14.3284 3.67157 15 4.5 15H6.61626L10.4966 18.4923C11.4618 19.361 13 18.676 13 17.3773V6.62268C13 5.32402 11.4618 4.63899 10.4966 5.50774Z" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M16.5 9C16.5 9 17.5 10 17.5 12C17.5 14 16.5 15 16.5 15" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 525 B |
|
|
@ -1,4 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 10.5V13.5C3 14.3284 3.67157 15 4.5 15H6.61626L10.4966 18.4923C11.4618 19.361 13 18.676 13 17.3773V6.62268C13 5.32402 11.4618 4.63899 10.4966 5.50774L10.4966 5.50774L6.61626 9L4.5 9C3.67157 9 3 9.67157 3 10.5Z" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M16.5 9.5C16.5 9.5 17.5 10.5 17.5 12C17.5 13.5 16.5 14.5 16.5 14.5M19 7C19 7 21 9 21 12C21 15 19 17 19 17" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M10.4966 5.50774L10.4966 5.50774L6.61626 9H4.5C3.67157 9 3 9.67157 3 10.5V13.5C3 14.3284 3.67157 15 4.5 15H6.61626L10.4966 18.4923C11.4618 19.361 13 18.676 13 17.3773V6.62268C13 5.32402 11.4618 4.63899 10.4966 5.50774Z" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M16.5 9C16.5 9 17.5 10 17.5 12C17.5 14 16.5 15 16.5 15M19 6.5C19 6.5 21 9 21 12C21 15 19 17.5 19 17.5" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 569 B After Width: | Height: | Size: 572 B |
|
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 6L18 18M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 354 B After Width: | Height: | Size: 222 B |
|
|
@ -29,17 +29,38 @@ const NavigationButtons = () => {
|
|||
}
|
||||
|
||||
const SearchBox = () => {
|
||||
const [keyword, setKeyword] = useState('')
|
||||
const navigate = useNavigate()
|
||||
const toSearch = (e: React.KeyboardEvent) => {
|
||||
if (!keyword) return
|
||||
if (e.key === 'Enter') {
|
||||
navigate(`/search/${keyword}`)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='app-region-no-drag group flex w-[16rem] cursor-text items-center rounded-full bg-gray-500 bg-opacity-5 px-3 transition duration-300 hover:bg-opacity-10 dark:bg-gray-300 dark:bg-opacity-5'>
|
||||
<div className='app-region-no-drag group flex w-[16rem] cursor-text items-center rounded-full bg-gray-500 bg-opacity-5 pl-2.5 pr-2 transition duration-300 hover:bg-opacity-10 dark:bg-gray-300 dark:bg-opacity-5'>
|
||||
<SvgIcon
|
||||
className='mr-2 h-5 w-5 text-gray-500 transition duration-300 group-hover:text-gray-600 dark:text-gray-400 dark:group-hover:text-gray-200'
|
||||
className='mr-2 h-4 w-4 text-gray-500 transition duration-300 group-hover:text-gray-600 dark:text-gray-400 dark:group-hover:text-gray-200'
|
||||
name='search'
|
||||
/>
|
||||
<input
|
||||
value={keyword}
|
||||
onChange={e => setKeyword(e.target.value)}
|
||||
onKeyDown={toSearch}
|
||||
type='text'
|
||||
className='w-full bg-transparent placeholder:text-gray-500 dark:text-white dark:placeholder:text-gray-400'
|
||||
className='flex-grow bg-transparent placeholder:text-gray-500 dark:text-white dark:placeholder:text-gray-400'
|
||||
placeholder='搜索'
|
||||
/>
|
||||
<div
|
||||
onClick={() => setKeyword('')}
|
||||
className={classNames(
|
||||
'cursor-default rounded-full p-1 transition after:bg-gray-300 hover:bg-white/20 dark:text-white/50',
|
||||
!keyword && 'hidden'
|
||||
)}
|
||||
>
|
||||
<SvgIcon className='h-4 w-4' name='x' />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -55,9 +76,12 @@ const Settings = () => {
|
|||
const Avatar = () => {
|
||||
const navigate = useNavigate()
|
||||
const { data: user } = useUser()
|
||||
|
||||
const avatarUrl = resizeImage(user?.profile?.avatarUrl ?? '', 'sm')
|
||||
|
||||
return (
|
||||
<img
|
||||
src={user?.profile?.avatarUrl}
|
||||
src={avatarUrl}
|
||||
onClick={() => navigate('/login')}
|
||||
className='app-region-no-drag h-9 w-9 rounded-full bg-gray-100 dark:bg-gray-700'
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,24 @@
|
|||
import { StrictMode } from 'react'
|
||||
import { render } from 'react-dom'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import * as Sentry from '@sentry/react'
|
||||
import { BrowserTracing } from '@sentry/tracing'
|
||||
import 'virtual:svg-icons-register'
|
||||
import '@/styles/global.scss'
|
||||
import App from './App'
|
||||
import pkg from '../../../package.json'
|
||||
|
||||
Sentry.init({
|
||||
dsn: 'https://7cc7879b42ba4bed9f66fb6752558475@o436528.ingest.sentry.io/6274630',
|
||||
integrations: [new BrowserTracing()],
|
||||
release: `yesplaymusic@${pkg.version}`,
|
||||
environment: import.meta.env.MODE,
|
||||
|
||||
// Set tracesSampleRate to 1.0 to capture 100%
|
||||
// of transactions for performance monitoring.
|
||||
// We recommend adjusting this value in production
|
||||
tracesSampleRate: 1.0,
|
||||
})
|
||||
|
||||
render(
|
||||
<StrictMode>
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ const Header = ({
|
|||
/>
|
||||
</Fragment>
|
||||
)}
|
||||
<div className='absolute top-0 h-full w-full bg-gradient-to-b from-white/75 to-white dark:from-black/50 dark:to-[#1d1d1d]'></div>
|
||||
<div className='absolute top-0 h-full w-full bg-gradient-to-b from-white/80 to-white dark:from-black/50 dark:to-[#1d1d1d]'></div>
|
||||
</div>
|
||||
|
||||
<div className='grid grid-cols-[17rem_auto] items-center gap-9'>
|
||||
|
|
@ -145,7 +145,7 @@ const Header = ({
|
|||
<Skeleton className='mt-5 w-64 text-lg'>PLACEHOLDER</Skeleton>
|
||||
) : (
|
||||
<div className='mt-5 text-lg font-medium text-gray-800 dark:text-gray-300'>
|
||||
Album by{' '}
|
||||
Album ·{' '}
|
||||
<NavLink
|
||||
to={`/artist/${album?.artist.id}`}
|
||||
className='cursor-default font-semibold hover:underline'
|
||||
|
|
@ -161,8 +161,14 @@ const Header = ({
|
|||
PLACEHOLDER
|
||||
</Skeleton>
|
||||
) : (
|
||||
<div className='text-sm text-gray-500 dark:text-gray-400'>
|
||||
{dayjs(album?.publishTime || 0).year()} · {album?.size} 首歌,{' '}
|
||||
<div className='flex items-center text-sm text-gray-500 dark:text-gray-400'>
|
||||
{album?.mark === 1056768 && (
|
||||
<SvgIcon
|
||||
name='explicit'
|
||||
className='mt-px mr-1 h-4 w-4 text-gray-400 dark:text-gray-500'
|
||||
/>
|
||||
)}
|
||||
{dayjs(album?.publishTime || 0).year()} · {album?.size} 首歌 ·{' '}
|
||||
{albumDuration}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -11,22 +11,113 @@ import Skeleton from '@/components/Skeleton'
|
|||
import { Fragment } from 'react'
|
||||
import useTracks from '@/hooks/useTracks'
|
||||
|
||||
const Header = ({ artist }: { artist: Artist | undefined }) => {
|
||||
const coverImage = resizeImage(artist?.img1v1Url || '', 'md')
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div className='absolute top-0 left-0 z-0 h-[24rem] w-full overflow-hidden'>
|
||||
{coverImage && (
|
||||
<Fragment>
|
||||
<img
|
||||
src={coverImage}
|
||||
className='absolute -top-full w-full blur-[100px]'
|
||||
/>
|
||||
<img
|
||||
src={coverImage}
|
||||
className='absolute -top-full w-full blur-[100px]'
|
||||
/>
|
||||
</Fragment>
|
||||
)}
|
||||
<div className='absolute top-0 h-full w-full bg-gradient-to-b from-white/80 to-white dark:from-black/50 dark:to-[#1d1d1d]'></div>
|
||||
</div>
|
||||
|
||||
<div className='relative mt-6 overflow-hidden rounded-2xl bg-gray-500/10 dark:bg-gray-800/20'>
|
||||
<div className='flex h-[26rem] justify-center overflow-hidden'>
|
||||
<img src={coverImage} className='aspect-square brightness-[.5]' />
|
||||
<img src={coverImage} className='aspect-square brightness-[.5]' />
|
||||
<img src={coverImage} />
|
||||
<img src={coverImage} className='aspect-square brightness-[.5]' />
|
||||
<img src={coverImage} className='aspect-square brightness-[.5]' />
|
||||
</div>
|
||||
|
||||
<div className='absolute right-0 left-0 top-[18rem] h-32 bg-gradient-to-t from-[#222]/60 to-transparent'></div>
|
||||
|
||||
<div className='absolute top-0 right-0 left-0 flex h-[26rem] items-end justify-between p-8 pb-6'>
|
||||
<div className='text-7xl font-bold text-white'>{artist?.name}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
const LatestRelease = ({
|
||||
album,
|
||||
isLoading,
|
||||
}: {
|
||||
album: Album | undefined
|
||||
isLoading: boolean
|
||||
}) => {
|
||||
return (
|
||||
<div>
|
||||
<div className='mb-6 text-2xl font-semibold text-gray-800 dark:text-white'>
|
||||
最新发行
|
||||
</div>
|
||||
<div className='flex-grow rounded-xl '>
|
||||
{isLoading ? (
|
||||
<Skeleton className='aspect-square w-full rounded-xl'></Skeleton>
|
||||
) : (
|
||||
<Cover imageUrl={album?.picUrl ?? ''} />
|
||||
)}
|
||||
<div className='line-clamp-2 line-clamp-1 mt-2 font-semibold leading-tight decoration-gray-600 decoration-2 hover:underline dark:text-white dark:decoration-gray-200'>
|
||||
{album?.name}
|
||||
</div>
|
||||
<div className='text-[12px] text-gray-500 dark:text-gray-400'>
|
||||
{album?.type} · {dayjs(album?.publishTime || 0).year()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const PopularTracks = ({
|
||||
tracks,
|
||||
isLoadingArtist,
|
||||
}: {
|
||||
tracks: Track[] | undefined
|
||||
isLoadingArtist: boolean
|
||||
}) => {
|
||||
const { data: tracksWithExtraInfo } = useTracks({
|
||||
ids: tracks?.slice(0, 10)?.map(t => t.id) ?? [],
|
||||
})
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='mb-6 text-2xl font-semibold text-gray-800 dark:text-white'>
|
||||
热门歌曲
|
||||
</div>
|
||||
<div className='rounded-xl'>
|
||||
<TracksGrid
|
||||
tracks={tracksWithExtraInfo?.songs ?? tracks?.slice(0, 10) ?? []}
|
||||
isSkeleton={isLoadingArtist}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Artist = () => {
|
||||
const params = useParams()
|
||||
|
||||
const { data: artist, isLoading } = useArtist({
|
||||
const { data: artist, isLoading: isLoadingArtist } = useArtist({
|
||||
id: Number(params.id) || 0,
|
||||
})
|
||||
|
||||
const { data: albumsRaw, isLoading: isLoadingAlbum } = useArtistAlbums({
|
||||
const { data: albumsRaw, isLoading: isLoadingAlbums } = useArtistAlbums({
|
||||
id: Number(params.id) || 0,
|
||||
limit: 1000,
|
||||
})
|
||||
|
||||
const { data: tracks, isLoading: isLoadingTracks } = useTracks({
|
||||
ids: artist?.hotSongs?.slice(0, 10)?.map(t => t.id) ?? [],
|
||||
})
|
||||
|
||||
const albums = useMemo(() => {
|
||||
if (!albumsRaw?.hotAlbums) return []
|
||||
const albums: Album[] = []
|
||||
|
|
@ -66,84 +157,20 @@ const Artist = () => {
|
|||
)
|
||||
}, [albums, albumsRaw?.hotAlbums])
|
||||
|
||||
const latestAlbum = useMemo(() => {
|
||||
if (!albumsRaw || !albumsRaw.hotAlbums) return
|
||||
return albumsRaw.hotAlbums[0]
|
||||
}, [albumsRaw])
|
||||
|
||||
const coverImage = resizeImage(artist?.artist?.img1v1Url || '', 'md')
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='absolute top-0 left-0 z-0 h-[24rem] w-full overflow-hidden'>
|
||||
{coverImage && (
|
||||
<Fragment>
|
||||
<img
|
||||
src={coverImage}
|
||||
className='absolute -top-full w-full blur-[100px]'
|
||||
/>
|
||||
<img
|
||||
src={coverImage}
|
||||
className='absolute -top-full w-full blur-[100px]'
|
||||
/>
|
||||
</Fragment>
|
||||
)}
|
||||
<div className='absolute top-0 h-full w-full bg-gradient-to-b from-white/[.84] to-white dark:from-black/[.6] dark:to-[#1d1d1d]'></div>
|
||||
</div>
|
||||
|
||||
{/* Header */}
|
||||
<div className='relative mt-6 overflow-hidden rounded-2xl'>
|
||||
<div className='flex h-[26rem] justify-center overflow-hidden'>
|
||||
<img src={coverImage} className='aspect-square brightness-[.5]' />
|
||||
<img src={coverImage} className='aspect-square brightness-[.5]' />
|
||||
<img src={coverImage} />
|
||||
<img src={coverImage} className='aspect-square brightness-[.5]' />
|
||||
<img src={coverImage} className='aspect-square brightness-[.5]' />
|
||||
</div>
|
||||
|
||||
<div className='absolute right-0 left-0 top-[18rem] h-32 bg-gradient-to-t from-[#222]/60 to-transparent'></div>
|
||||
|
||||
<div className='absolute top-0 right-0 left-0 flex h-[26rem] items-end justify-between p-8 pb-6'>
|
||||
<div className='text-7xl font-bold text-white'>
|
||||
{artist?.artist.name}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Header artist={artist?.artist} />
|
||||
|
||||
<div className='mt-12 grid h-[20rem] grid-cols-[14rem,_auto] grid-rows-1 gap-16 px-2'>
|
||||
{/* Latest release */}
|
||||
<div>
|
||||
<div className='mb-6 text-2xl font-semibold text-gray-800 dark:text-white'>
|
||||
最新发行
|
||||
</div>
|
||||
<div className='flex-grow rounded-xl '>
|
||||
{isLoadingAlbum ? (
|
||||
<Skeleton className='aspect-square w-full rounded-xl'></Skeleton>
|
||||
) : (
|
||||
<Cover imageUrl={latestAlbum?.picUrl ?? ''} />
|
||||
)}
|
||||
<div className='line-clamp-2 line-clamp-1 mt-2 font-semibold leading-tight decoration-gray-600 decoration-2 hover:underline dark:text-white dark:decoration-gray-200'>
|
||||
{latestAlbum?.name}
|
||||
</div>
|
||||
<div className='text-[12px] text-gray-500 dark:text-gray-400'>
|
||||
{latestAlbum?.type} ·{' '}
|
||||
{dayjs(latestAlbum?.publishTime || 0).year()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<LatestRelease
|
||||
album={albumsRaw?.hotAlbums[0]}
|
||||
isLoading={isLoadingAlbums}
|
||||
/>
|
||||
|
||||
{/* Popular tracks */}
|
||||
<div>
|
||||
<div className='mb-6 text-2xl font-semibold text-gray-800 dark:text-white'>
|
||||
热门歌曲
|
||||
</div>
|
||||
<div className='rounded-xl'>
|
||||
<TracksGrid
|
||||
tracks={tracks?.songs ?? artist?.hotSongs.slice(0, 10) ?? []}
|
||||
isSkeleton={isLoading}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<PopularTracks
|
||||
tracks={artist?.hotSongs}
|
||||
isLoadingArtist={isLoadingArtist}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Albums */}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ const Header = memo(
|
|||
<div className='absolute top-0 left-0 z-0 h-[24rem] w-full overflow-hidden'>
|
||||
<img src={coverUrl} className='absolute top-0 w-full blur-[100px]' />
|
||||
<img src={coverUrl} className='absolute top-0 w-full blur-[100px]' />
|
||||
<div className='absolute top-0 h-full w-full bg-gradient-to-b from-white/[.84] to-white dark:from-black/[.5] dark:to-[#1d1d1d]'></div>
|
||||
<div className='absolute top-0 h-full w-full bg-gradient-to-b from-white/80 to-white dark:from-black/50 dark:to-[#1d1d1d]'></div>
|
||||
</div>
|
||||
|
||||
<div className='grid grid-cols-[17rem_auto] items-center gap-9'>
|
||||
|
|
@ -73,7 +73,7 @@ const Header = memo(
|
|||
{/* <!-- Playlist creator --> */}
|
||||
{!isLoading && (
|
||||
<div className='mt-5 text-lg font-medium text-gray-800 dark:text-gray-300'>
|
||||
Playlist by <span>{playlist?.creator?.nickname}</span>
|
||||
歌单 · <span>{playlist?.creator?.nickname}</span>
|
||||
</div>
|
||||
)}
|
||||
{isLoading && (
|
||||
|
|
|
|||
5
packages/renderer/src/pages/Search/Search.tsx
Normal file
5
packages/renderer/src/pages/Search/Search.tsx
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
const Search = () => {
|
||||
return <div></div>
|
||||
}
|
||||
|
||||
export default Search
|
||||
3
packages/renderer/src/pages/Search/index.ts
Normal file
3
packages/renderer/src/pages/Search/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import Search from './Search'
|
||||
|
||||
export default Search
|
||||
128
pnpm-lock.yaml
generated
128
pnpm-lock.yaml
generated
|
|
@ -1,6 +1,9 @@
|
|||
lockfileVersion: 5.3
|
||||
|
||||
specifiers:
|
||||
'@sentry/node': ^6.19.2
|
||||
'@sentry/react': ^6.19.2
|
||||
'@sentry/tracing': ^6.19.2
|
||||
'@types/cookie-parser': ^1.4.2
|
||||
'@types/express': ^4.17.13
|
||||
'@types/express-fileupload': ^1.2.2
|
||||
|
|
@ -19,7 +22,6 @@ specifiers:
|
|||
ansi-styles: ^6.1.0
|
||||
autoprefixer: ^10.4.4
|
||||
axios: ^0.26.1
|
||||
body-parser: ^1.19.2
|
||||
change-case: ^4.1.2
|
||||
classnames: ^2.3.1
|
||||
color.js: ^1.2.0
|
||||
|
|
@ -69,6 +71,9 @@ specifiers:
|
|||
vite-plugin-svg-icons: ^2.0.1
|
||||
|
||||
dependencies:
|
||||
'@sentry/node': 6.19.2
|
||||
'@sentry/react': 6.19.2_react@17.0.2
|
||||
'@sentry/tracing': 6.19.2
|
||||
NeteaseCloudMusicApi: 4.5.8
|
||||
change-case: 4.1.2
|
||||
cookie-parser: 1.4.6
|
||||
|
|
@ -95,7 +100,6 @@ devDependencies:
|
|||
ansi-styles: 6.1.0
|
||||
autoprefixer: 10.4.4_postcss@8.4.12
|
||||
axios: 0.26.1
|
||||
body-parser: 1.19.2
|
||||
classnames: 2.3.1
|
||||
color.js: 1.2.0
|
||||
colord: 2.9.2
|
||||
|
|
@ -562,6 +566,100 @@ packages:
|
|||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/@sentry/browser/6.19.2:
|
||||
resolution: {integrity: sha512-5VC44p5Vu2eJhVT39nLAJFgha5MjHDYCyZRR1ieeZt3a++otojPGBBAKNAtrEMGV+A2Z9AoneD6ZnDVlyb3GKg==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
'@sentry/core': 6.19.2
|
||||
'@sentry/types': 6.19.2
|
||||
'@sentry/utils': 6.19.2
|
||||
tslib: 1.14.1
|
||||
dev: false
|
||||
|
||||
/@sentry/core/6.19.2:
|
||||
resolution: {integrity: sha512-yu1R3ewBT4udmB4v7sc4biQZ0Z0rfB9+TzB5ZKoCftbe6kqXjFMMaFRYNUF9HicVldKAsBktgkWw3+yfqGkw/A==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
'@sentry/hub': 6.19.2
|
||||
'@sentry/minimal': 6.19.2
|
||||
'@sentry/types': 6.19.2
|
||||
'@sentry/utils': 6.19.2
|
||||
tslib: 1.14.1
|
||||
dev: false
|
||||
|
||||
/@sentry/hub/6.19.2:
|
||||
resolution: {integrity: sha512-W7KCgNBgdBIMagOxy5J5KQPe+maYxSqfE8a5ncQ3R8BcZDQEKnkW/1FplNbfRLZqA/tL/ndKb7pTPqVtzsbARw==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
'@sentry/types': 6.19.2
|
||||
'@sentry/utils': 6.19.2
|
||||
tslib: 1.14.1
|
||||
dev: false
|
||||
|
||||
/@sentry/minimal/6.19.2:
|
||||
resolution: {integrity: sha512-ClwxKm77iDHET7kpzv1JvzDx1er5DoNu+EUjst0kQzARIrXvu9xuZuE2/CnBWycQWqw8o3HoGoKz65uIhsUCzQ==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
'@sentry/hub': 6.19.2
|
||||
'@sentry/types': 6.19.2
|
||||
tslib: 1.14.1
|
||||
dev: false
|
||||
|
||||
/@sentry/node/6.19.2:
|
||||
resolution: {integrity: sha512-Z1qREpTpYHxaeWjc1zMUk8ZTAp1WbxMiI2TVNc+a14DVT19Z2xNXb06MiRfeLgNc9lVGdmzR62dPmMBjVgPJYg==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
'@sentry/core': 6.19.2
|
||||
'@sentry/hub': 6.19.2
|
||||
'@sentry/types': 6.19.2
|
||||
'@sentry/utils': 6.19.2
|
||||
cookie: 0.4.2
|
||||
https-proxy-agent: 5.0.0
|
||||
lru_map: 0.3.3
|
||||
tslib: 1.14.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@sentry/react/6.19.2_react@17.0.2:
|
||||
resolution: {integrity: sha512-6ffifcUWJegvC5iYJlXL3zBirR05F/i5nA7QaYSMERJqZpXuYhwNPySbuiNTajm64+HA1RbdQkiwrHE/Ur3f1w==}
|
||||
engines: {node: '>=6'}
|
||||
peerDependencies:
|
||||
react: 15.x || 16.x || 17.x
|
||||
dependencies:
|
||||
'@sentry/browser': 6.19.2
|
||||
'@sentry/minimal': 6.19.2
|
||||
'@sentry/types': 6.19.2
|
||||
'@sentry/utils': 6.19.2
|
||||
hoist-non-react-statics: 3.3.2
|
||||
react: 17.0.2
|
||||
tslib: 1.14.1
|
||||
dev: false
|
||||
|
||||
/@sentry/tracing/6.19.2:
|
||||
resolution: {integrity: sha512-rGoPpP1JIAxdq5bzrww0XuNVr6yn7RN6/wUcaxf6CAvklKvDx+q28WTGlZLGTZ/3un8Rv6i1FZFZOXizgnVnrg==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
'@sentry/hub': 6.19.2
|
||||
'@sentry/minimal': 6.19.2
|
||||
'@sentry/types': 6.19.2
|
||||
'@sentry/utils': 6.19.2
|
||||
tslib: 1.14.1
|
||||
dev: false
|
||||
|
||||
/@sentry/types/6.19.2:
|
||||
resolution: {integrity: sha512-XO5qmVBdTs+7PdCz7fAwn1afWxSnRE2KLBFg5/vOdKosPSSHsSHUURSkxiEZc2QsR+JpRB4AeQ26AkIRX38qTg==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/@sentry/utils/6.19.2:
|
||||
resolution: {integrity: sha512-2DQQ2OJaxjtyxGq5FmMlqb6hptsqMs2xoBiVRMkTS/rvyTrk1oQdKZ8ePwjtgX3nJ728ni3IXIyXV+vfGp4EBw==}
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
'@sentry/types': 6.19.2
|
||||
tslib: 1.14.1
|
||||
dev: false
|
||||
|
||||
/@sindresorhus/is/0.14.0:
|
||||
resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
@ -1433,6 +1531,7 @@ packages:
|
|||
qs: 6.9.7
|
||||
raw-body: 2.4.3
|
||||
type-is: 1.6.18
|
||||
dev: false
|
||||
|
||||
/boolbase/1.0.0:
|
||||
resolution: {integrity: sha1-aN/1++YMUes3cl6p4+0xDcwed24=}
|
||||
|
|
@ -1616,6 +1715,7 @@ packages:
|
|||
/bytes/3.1.2:
|
||||
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: false
|
||||
|
||||
/cache-base/1.0.1:
|
||||
resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==}
|
||||
|
|
@ -2293,6 +2393,7 @@ packages:
|
|||
/depd/1.1.2:
|
||||
resolution: {integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/destroy/1.0.4:
|
||||
resolution: {integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=}
|
||||
|
|
@ -2504,6 +2605,7 @@ packages:
|
|||
|
||||
/ee-first/1.1.1:
|
||||
resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
|
||||
dev: false
|
||||
|
||||
/ejs/3.1.6:
|
||||
resolution: {integrity: sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==}
|
||||
|
|
@ -3805,6 +3907,12 @@ packages:
|
|||
'@babel/runtime': 7.17.2
|
||||
dev: true
|
||||
|
||||
/hoist-non-react-statics/3.3.2:
|
||||
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
|
||||
dependencies:
|
||||
react-is: 16.13.1
|
||||
dev: false
|
||||
|
||||
/hosted-git-info/4.1.0:
|
||||
resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -3848,6 +3956,7 @@ packages:
|
|||
setprototypeof: 1.2.0
|
||||
statuses: 1.5.0
|
||||
toidentifier: 1.0.1
|
||||
dev: false
|
||||
|
||||
/http-proxy-agent/4.0.1:
|
||||
resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
|
||||
|
|
@ -3920,6 +4029,7 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
dev: false
|
||||
|
||||
/iconv-lite/0.6.3:
|
||||
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||
|
|
@ -4587,6 +4697,10 @@ packages:
|
|||
dependencies:
|
||||
yallist: 4.0.0
|
||||
|
||||
/lru_map/0.3.3:
|
||||
resolution: {integrity: sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=}
|
||||
dev: false
|
||||
|
||||
/magic-string/0.26.1:
|
||||
resolution: {integrity: sha512-ndThHmvgtieXe8J/VGPjG+Apu7v7ItcD5mhEIvOscWjPF/ccOiLxHaSuCAS2G+3x4GKsAbT8u7zdyamupui8Tg==}
|
||||
engines: {node: '>=12'}
|
||||
|
|
@ -4642,6 +4756,7 @@ packages:
|
|||
/media-typer/0.3.0:
|
||||
resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/media-typer/1.1.0:
|
||||
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
|
||||
|
|
@ -5068,6 +5183,7 @@ packages:
|
|||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
ee-first: 1.1.1
|
||||
dev: false
|
||||
|
||||
/once/1.4.0:
|
||||
resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=}
|
||||
|
|
@ -5555,6 +5671,7 @@ packages:
|
|||
/qs/6.9.7:
|
||||
resolution: {integrity: sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==}
|
||||
engines: {node: '>=0.6'}
|
||||
dev: false
|
||||
|
||||
/query-string/4.3.4:
|
||||
resolution: {integrity: sha1-u7aTucqRXCMlFbIosaArYJBD2+s=}
|
||||
|
|
@ -5590,6 +5707,7 @@ packages:
|
|||
http-errors: 1.8.1
|
||||
iconv-lite: 0.4.24
|
||||
unpipe: 1.0.0
|
||||
dev: false
|
||||
|
||||
/rc/1.2.8:
|
||||
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
|
||||
|
|
@ -6163,6 +6281,7 @@ packages:
|
|||
|
||||
/setprototypeof/1.2.0:
|
||||
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
||||
dev: false
|
||||
|
||||
/shebang-command/2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
|
|
@ -6397,6 +6516,7 @@ packages:
|
|||
/statuses/1.5.0:
|
||||
resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/stream-counter/1.0.0:
|
||||
resolution: {integrity: sha1-kc8lac5NxQYf6816yyY5SloRR1E=}
|
||||
|
|
@ -6730,6 +6850,7 @@ packages:
|
|||
/toidentifier/1.0.1:
|
||||
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
|
||||
engines: {node: '>=0.6'}
|
||||
dev: false
|
||||
|
||||
/token-types/4.2.0:
|
||||
resolution: {integrity: sha512-P0rrp4wUpefLncNamWIef62J0v0kQR/GfDVji9WKY7GDCWy5YbVSrKUTam07iWPZQGy0zWNOfstYTykMmPNR7w==}
|
||||
|
|
@ -6770,7 +6891,6 @@ packages:
|
|||
|
||||
/tslib/1.14.1:
|
||||
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
|
||||
dev: true
|
||||
|
||||
/tslib/2.3.1:
|
||||
resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
|
||||
|
|
@ -6835,6 +6955,7 @@ packages:
|
|||
dependencies:
|
||||
media-typer: 0.3.0
|
||||
mime-types: 2.1.34
|
||||
dev: false
|
||||
|
||||
/typedarray-to-buffer/3.1.5:
|
||||
resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==}
|
||||
|
|
@ -6901,6 +7022,7 @@ packages:
|
|||
/unpipe/1.0.0:
|
||||
resolution: {integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=}
|
||||
engines: {node: '>= 0.8'}
|
||||
dev: false
|
||||
|
||||
/unplugin-auto-import/0.6.6_rollup@2.70.1+vite@2.8.6:
|
||||
resolution: {integrity: sha512-x3YxAI9ePoumXOakuS5YJlFkSyAkl5vJlaFZSJhSp75nH5gg8LpqQ/0Gz1/CG/JRRv+xaE1CZpEV161AqFGjEg==}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue