mirror of
https://github.com/qier222/YesPlayMusic.git
synced 2025-02-22 07:49:38 +08:00
feat: 支持缓存歌词和一些小更新
This commit is contained in:
parent
abedbe7531
commit
1eb38937fc
@ -80,6 +80,15 @@ export async function setCache(api: string, data: any, query: any) {
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'lyric': {
|
||||
if (!data.lrc) return
|
||||
db.upsert(Tables.LYRIC, {
|
||||
id: query.id,
|
||||
json: JSON.stringify(data),
|
||||
updatedAt: Date.now(),
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,6 +169,12 @@ export function getCache(api: string, query: any): any {
|
||||
)
|
||||
return artistAlbums
|
||||
}
|
||||
case 'lyric': {
|
||||
if (isNaN(Number(query?.id))) return
|
||||
const data = db.find(Tables.LYRIC, query.id)
|
||||
if (data?.json) return JSON.parse(data.json)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,7 +183,7 @@ export async function getCacheForExpress(api: string, req: Request) {
|
||||
if (api === 'song/detail') {
|
||||
const cache = getCache(api, req.query)
|
||||
if (cache) {
|
||||
logger.info(`[cache] Cache hit for ${req.path}`)
|
||||
logger.debug(`[cache] Cache hit for ${req.path}`)
|
||||
return cache
|
||||
}
|
||||
}
|
||||
@ -185,7 +200,7 @@ export async function getCacheForExpress(api: string, req: Request) {
|
||||
)
|
||||
if (!isAudioFileExists) return
|
||||
|
||||
logger.info(`[cache] Audio cache hit for ${req.path}`)
|
||||
logger.debug(`[cache] Audio cache hit for ${req.path}`)
|
||||
|
||||
return {
|
||||
data: [
|
||||
|
@ -15,6 +15,7 @@ export enum Tables {
|
||||
ARTIST = 'artist',
|
||||
PLAYLIST = 'playlist',
|
||||
ARTIST_ALBUMS = 'artist_album',
|
||||
LYRIC = 'lyric',
|
||||
|
||||
// Special tables
|
||||
ACCOUNT_DATA = 'account_data',
|
||||
@ -123,6 +124,7 @@ if (process.env.NODE_ENV === 'development') {
|
||||
Tables.ARTIST,
|
||||
Tables.AUDIO,
|
||||
Tables.ACCOUNT_DATA,
|
||||
Tables.LYRIC,
|
||||
]
|
||||
tables.forEach(table => {
|
||||
const data = db.findAll(table)
|
||||
|
@ -1,12 +1,17 @@
|
||||
import { app } from 'electron'
|
||||
/** By default, it writes logs to the following locations:
|
||||
* on Linux: ~/.config/{app name}/logs/{process type}.log
|
||||
* on macOS: ~/Library/Logs/{app name}/{process type}.log
|
||||
* on Windows: %USERPROFILE%\AppData\Roaming\{app name}\logs\{process type}.log
|
||||
* @see https://www.npmjs.com/package/electron-log
|
||||
*/
|
||||
|
||||
import logger from 'electron-log'
|
||||
import pc from 'picocolors'
|
||||
|
||||
Object.assign(console, logger.functions)
|
||||
|
||||
logger.transports.console.format = `${pc.dim('{h}:{i}:{s}{scope}')} › {text}`
|
||||
logger.transports.file.level = 'info'
|
||||
|
||||
logger.transports.file.level = app.isPackaged ? 'info' : 'debug'
|
||||
logger.info(
|
||||
`\n\n██╗ ██╗███████╗███████╗██████╗ ██╗ █████╗ ██╗ ██╗███╗ ███╗██╗ ██╗███████╗██╗ ██████╗
|
||||
╚██╗ ██╔╝██╔════╝██╔════╝██╔══██╗██║ ██╔══██╗╚██╗ ██╔╝████╗ ████║██║ ██║██╔════╝██║██╔════╝
|
||||
|
@ -1,7 +1,8 @@
|
||||
CREATE TABLE "artist" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "account_data" ("id" text NOT NULL,"json" text NOT NULL,"updateAt" int NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "album" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "artist_album" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "artist" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "audio" ("id" integer NOT NULL,"br" int NOT NULL,"type" text NOT NULL,"srouce" text NOT NULL,"updateAt" int NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "lyric" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" integer NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "playlist" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "track" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "artist_album" ("id" integer NOT NULL,"json" text NOT NULL,"updatedAt" int NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "audio" ("id" integer NOT NULL,"br" int NOT NULL,"type" text NOT NULL,"srouce" text NOT NULL,"updateAt" int NOT NULL, PRIMARY KEY (id));
|
||||
CREATE TABLE "account_data" ("id" text NOT NULL,"json" text NOT NULL,"updateAt" int NOT NULL, PRIMARY KEY (id));
|
||||
|
@ -29,7 +29,7 @@ Object.entries(neteaseApi).forEach(([name, handler]) => {
|
||||
name = pathCase(name)
|
||||
|
||||
const wrappedHandler = async (req: Request, res: Response) => {
|
||||
logger.info(`[server] Handling request: ${req.path}`)
|
||||
logger.debug(`[server] Handling request: ${req.path}`)
|
||||
|
||||
// Get from cache
|
||||
const cache = await getCacheForExpress(name, req)
|
||||
|
@ -10,6 +10,7 @@ export default function useUserAlbums(params: FetchUserAlbumsParams = {}) {
|
||||
[UserApiNames.FETCH_USER_ALBUMS, user?.profile?.userId ?? 0],
|
||||
() => fetchUserAlbums(params),
|
||||
{
|
||||
refetchOnWindowFocus: true,
|
||||
placeholderData: (): FetchUserAlbumsResponse | undefined =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
api: 'album/sublist',
|
||||
|
@ -3,6 +3,7 @@ import { UserApiNames, fetchUserArtists } from '@/api/user'
|
||||
|
||||
export default function useUserArtists() {
|
||||
return useQuery([UserApiNames.FETCH_USER_ARTIST], fetchUserArtists, {
|
||||
refetchOnWindowFocus: true,
|
||||
placeholderData: (): FetchUserArtistsResponse =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
api: 'album/sublist',
|
||||
|
@ -29,6 +29,7 @@ export default function useUserPlaylists() {
|
||||
params.uid !== 0 &&
|
||||
params.offset !== undefined
|
||||
),
|
||||
refetchOnWindowFocus: true,
|
||||
placeholderData: (): FetchUserPlaylistsResponse =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
api: 'user/playlist',
|
||||
|
@ -64,7 +64,7 @@ const LatestRelease = ({
|
||||
<Skeleton className='aspect-square w-full rounded-xl'></Skeleton>
|
||||
) : (
|
||||
<Cover
|
||||
imageUrl={album?.picUrl ?? ''}
|
||||
imageUrl={resizeImage(album?.picUrl ?? '', 'md')}
|
||||
showPlayButton={true}
|
||||
onClick={toAlbum}
|
||||
/>
|
||||
|
@ -40,7 +40,7 @@ export default function Home() {
|
||||
)
|
||||
|
||||
const playlists = [
|
||||
...(dailyRecommendPlaylists?.recommend?.slice(1) ?? []),
|
||||
...(dailyRecommendPlaylists?.recommend?.slice(1).slice(0, 8) ?? []),
|
||||
...(recommendedPlaylists?.result ?? []),
|
||||
]
|
||||
.slice(0, 10)
|
||||
|
@ -73,7 +73,7 @@ const LikedTracksCard = ({ className }: { className?: string }) => {
|
||||
navigate(`/playlist/${likedSongsPlaylist.playlist.id}`)
|
||||
}
|
||||
className={classNames(
|
||||
'relative flex h-full w-full flex-col justify-between rounded-2xl bg-brand-50 py-5 px-6 text-brand-600 ',
|
||||
'relative flex h-full w-full flex-col justify-between rounded-2xl bg-brand-50 py-5 px-6 text-brand-600 dark:bg-brand-800 dark:text-brand-50',
|
||||
className
|
||||
)}
|
||||
>
|
||||
@ -91,7 +91,7 @@ const LikedTracksCard = ({ className }: { className?: string }) => {
|
||||
|
||||
<button
|
||||
onClick={handlePlay}
|
||||
className='btn-pressed-animation absolute bottom-6 right-6 grid h-11 w-11 cursor-default place-content-center rounded-full bg-brand-600 text-brand-50 shadow-lg'
|
||||
className='btn-pressed-animation absolute bottom-6 right-6 grid h-11 w-11 cursor-default place-content-center rounded-full bg-brand-600 text-brand-50 shadow-lg dark:bg-white dark:text-brand-600'
|
||||
>
|
||||
<SvgIcon name='play-fill' className='ml-0.5 h-6 w-6' />
|
||||
</button>
|
||||
@ -111,7 +111,7 @@ const OtherCard = ({
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'flex h-full w-full flex-col justify-between rounded-2xl bg-gray-100 text-lg font-bold',
|
||||
'flex h-full w-full flex-col justify-between rounded-2xl bg-gray-100 text-lg font-bold dark:bg-gray-800 dark:text-gray-200',
|
||||
className
|
||||
)}
|
||||
>
|
||||
@ -180,7 +180,7 @@ const TabHeader = ({
|
||||
setActiveTab: (tab: keyof TabsType) => void
|
||||
}) => {
|
||||
return (
|
||||
<div className='mt-10 flex text-lg'>
|
||||
<div className='mt-10 flex text-lg dark:text-white'>
|
||||
{Object.entries(tabs).map(([id, name]) => (
|
||||
<div
|
||||
key={id}
|
||||
@ -188,7 +188,7 @@ const TabHeader = ({
|
||||
className={classNames(
|
||||
'btn-pressed-animation mr-3 rounded-lg px-3.5 py-1.5 font-medium',
|
||||
activeTab === id
|
||||
? 'bg-black/[.04]'
|
||||
? 'bg-black/[.04] dark:bg-white/10'
|
||||
: 'btn-hover-animation after:bg-black/[.04] dark:after:bg-white/10'
|
||||
)}
|
||||
>
|
||||
@ -238,7 +238,7 @@ const Library = () => {
|
||||
|
||||
return (
|
||||
<div className='mt-8'>
|
||||
<div className='flex items-center text-[2.625rem] font-semibold'>
|
||||
<div className='flex items-center text-[2.625rem] font-semibold dark:text-white'>
|
||||
<img src={avatarUrl} className='mr-3 mt-1 h-12 w-12 rounded-full' />
|
||||
{user?.profile?.nickname}的音乐库
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user