mirror of
https://github.com/GiriNeko/YesPlayMusic.git
synced 2025-12-16 21:28:06 +00:00
feat: 支持缓存歌词和一些小更新
This commit is contained in:
parent
abedbe7531
commit
1eb38937fc
11 changed files with 44 additions and 18 deletions
|
|
@ -80,6 +80,15 @@ export async function setCache(api: string, data: any, query: any) {
|
||||||
})
|
})
|
||||||
break
|
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
|
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') {
|
if (api === 'song/detail') {
|
||||||
const cache = getCache(api, req.query)
|
const cache = getCache(api, req.query)
|
||||||
if (cache) {
|
if (cache) {
|
||||||
logger.info(`[cache] Cache hit for ${req.path}`)
|
logger.debug(`[cache] Cache hit for ${req.path}`)
|
||||||
return cache
|
return cache
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +200,7 @@ export async function getCacheForExpress(api: string, req: Request) {
|
||||||
)
|
)
|
||||||
if (!isAudioFileExists) return
|
if (!isAudioFileExists) return
|
||||||
|
|
||||||
logger.info(`[cache] Audio cache hit for ${req.path}`)
|
logger.debug(`[cache] Audio cache hit for ${req.path}`)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: [
|
data: [
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ export enum Tables {
|
||||||
ARTIST = 'artist',
|
ARTIST = 'artist',
|
||||||
PLAYLIST = 'playlist',
|
PLAYLIST = 'playlist',
|
||||||
ARTIST_ALBUMS = 'artist_album',
|
ARTIST_ALBUMS = 'artist_album',
|
||||||
|
LYRIC = 'lyric',
|
||||||
|
|
||||||
// Special tables
|
// Special tables
|
||||||
ACCOUNT_DATA = 'account_data',
|
ACCOUNT_DATA = 'account_data',
|
||||||
|
|
@ -123,6 +124,7 @@ if (process.env.NODE_ENV === 'development') {
|
||||||
Tables.ARTIST,
|
Tables.ARTIST,
|
||||||
Tables.AUDIO,
|
Tables.AUDIO,
|
||||||
Tables.ACCOUNT_DATA,
|
Tables.ACCOUNT_DATA,
|
||||||
|
Tables.LYRIC,
|
||||||
]
|
]
|
||||||
tables.forEach(table => {
|
tables.forEach(table => {
|
||||||
const data = db.findAll(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 logger from 'electron-log'
|
||||||
import pc from 'picocolors'
|
import pc from 'picocolors'
|
||||||
|
|
||||||
Object.assign(console, logger.functions)
|
Object.assign(console, logger.functions)
|
||||||
|
|
||||||
logger.transports.console.format = `${pc.dim('{h}:{i}:{s}{scope}')} › {text}`
|
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(
|
logger.info(
|
||||||
`\n\n██╗ ██╗███████╗███████╗██████╗ ██╗ █████╗ ██╗ ██╗███╗ ███╗██╗ ██╗███████╗██╗ ██████╗
|
`\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 "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 "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 "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)
|
name = pathCase(name)
|
||||||
|
|
||||||
const wrappedHandler = async (req: Request, res: Response) => {
|
const wrappedHandler = async (req: Request, res: Response) => {
|
||||||
logger.info(`[server] Handling request: ${req.path}`)
|
logger.debug(`[server] Handling request: ${req.path}`)
|
||||||
|
|
||||||
// Get from cache
|
// Get from cache
|
||||||
const cache = await getCacheForExpress(name, req)
|
const cache = await getCacheForExpress(name, req)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ export default function useUserAlbums(params: FetchUserAlbumsParams = {}) {
|
||||||
[UserApiNames.FETCH_USER_ALBUMS, user?.profile?.userId ?? 0],
|
[UserApiNames.FETCH_USER_ALBUMS, user?.profile?.userId ?? 0],
|
||||||
() => fetchUserAlbums(params),
|
() => fetchUserAlbums(params),
|
||||||
{
|
{
|
||||||
|
refetchOnWindowFocus: true,
|
||||||
placeholderData: (): FetchUserAlbumsResponse | undefined =>
|
placeholderData: (): FetchUserAlbumsResponse | undefined =>
|
||||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||||
api: 'album/sublist',
|
api: 'album/sublist',
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { UserApiNames, fetchUserArtists } from '@/api/user'
|
||||||
|
|
||||||
export default function useUserArtists() {
|
export default function useUserArtists() {
|
||||||
return useQuery([UserApiNames.FETCH_USER_ARTIST], fetchUserArtists, {
|
return useQuery([UserApiNames.FETCH_USER_ARTIST], fetchUserArtists, {
|
||||||
|
refetchOnWindowFocus: true,
|
||||||
placeholderData: (): FetchUserArtistsResponse =>
|
placeholderData: (): FetchUserArtistsResponse =>
|
||||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||||
api: 'album/sublist',
|
api: 'album/sublist',
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ export default function useUserPlaylists() {
|
||||||
params.uid !== 0 &&
|
params.uid !== 0 &&
|
||||||
params.offset !== undefined
|
params.offset !== undefined
|
||||||
),
|
),
|
||||||
|
refetchOnWindowFocus: true,
|
||||||
placeholderData: (): FetchUserPlaylistsResponse =>
|
placeholderData: (): FetchUserPlaylistsResponse =>
|
||||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||||
api: 'user/playlist',
|
api: 'user/playlist',
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ const LatestRelease = ({
|
||||||
<Skeleton className='aspect-square w-full rounded-xl'></Skeleton>
|
<Skeleton className='aspect-square w-full rounded-xl'></Skeleton>
|
||||||
) : (
|
) : (
|
||||||
<Cover
|
<Cover
|
||||||
imageUrl={album?.picUrl ?? ''}
|
imageUrl={resizeImage(album?.picUrl ?? '', 'md')}
|
||||||
showPlayButton={true}
|
showPlayButton={true}
|
||||||
onClick={toAlbum}
|
onClick={toAlbum}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ export default function Home() {
|
||||||
)
|
)
|
||||||
|
|
||||||
const playlists = [
|
const playlists = [
|
||||||
...(dailyRecommendPlaylists?.recommend?.slice(1) ?? []),
|
...(dailyRecommendPlaylists?.recommend?.slice(1).slice(0, 8) ?? []),
|
||||||
...(recommendedPlaylists?.result ?? []),
|
...(recommendedPlaylists?.result ?? []),
|
||||||
]
|
]
|
||||||
.slice(0, 10)
|
.slice(0, 10)
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ const LikedTracksCard = ({ className }: { className?: string }) => {
|
||||||
navigate(`/playlist/${likedSongsPlaylist.playlist.id}`)
|
navigate(`/playlist/${likedSongsPlaylist.playlist.id}`)
|
||||||
}
|
}
|
||||||
className={classNames(
|
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
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
@ -91,7 +91,7 @@ const LikedTracksCard = ({ className }: { className?: string }) => {
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={handlePlay}
|
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' />
|
<SvgIcon name='play-fill' className='ml-0.5 h-6 w-6' />
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -111,7 +111,7 @@ const OtherCard = ({
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
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
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
@ -180,7 +180,7 @@ const TabHeader = ({
|
||||||
setActiveTab: (tab: keyof TabsType) => void
|
setActiveTab: (tab: keyof TabsType) => void
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className='mt-10 flex text-lg'>
|
<div className='mt-10 flex text-lg dark:text-white'>
|
||||||
{Object.entries(tabs).map(([id, name]) => (
|
{Object.entries(tabs).map(([id, name]) => (
|
||||||
<div
|
<div
|
||||||
key={id}
|
key={id}
|
||||||
|
|
@ -188,7 +188,7 @@ const TabHeader = ({
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'btn-pressed-animation mr-3 rounded-lg px-3.5 py-1.5 font-medium',
|
'btn-pressed-animation mr-3 rounded-lg px-3.5 py-1.5 font-medium',
|
||||||
activeTab === id
|
activeTab === id
|
||||||
? 'bg-black/[.04]'
|
? 'bg-black/[.04] dark:bg-white/10'
|
||||||
: 'btn-hover-animation after:bg-black/[.04] dark:after:bg-white/10'
|
: 'btn-hover-animation after:bg-black/[.04] dark:after:bg-white/10'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
@ -238,7 +238,7 @@ const Library = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='mt-8'>
|
<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' />
|
<img src={avatarUrl} className='mr-3 mt-1 h-12 w-12 rounded-full' />
|
||||||
{user?.profile?.nickname}的音乐库
|
{user?.profile?.nickname}的音乐库
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue