mirror of
https://github.com/GiriNeko/YesPlayMusic.git
synced 2025-12-16 13:17:46 +00:00
fix: bugs
fix: bugs
This commit is contained in:
parent
1444bbefa2
commit
70d1de0e0f
62 changed files with 368 additions and 284 deletions
|
|
@ -10,7 +10,7 @@
|
|||
"repository": "github:qier222/YesPlayMusic",
|
||||
"main": "dist/main/index.js",
|
||||
"scripts": {
|
||||
"install": "node scripts/build.sqlite3.mjs --x64",
|
||||
"install:sqlite3": "node scripts/build.sqlite3.mjs",
|
||||
"dev": "concurrently -n=vite,main -c=#646cff,#74b1be \"npm run dev:renderer\" \"node scripts/build.main.mjs --watch\"",
|
||||
"dev:renderer": "vite dev",
|
||||
"build:main": "node scripts/build.main.mjs",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ import pc from 'picocolors'
|
|||
const pkg = JSON.parse(await fs.readFileSync('./package.json', 'utf8'))
|
||||
const electronVersion = pkg.devDependencies.electron.replaceAll('^', '')
|
||||
const argv = minimist(process.argv.slice(2))
|
||||
const isWin = process.platform === 'win32'
|
||||
const isMac = process.platform === 'darwin'
|
||||
const isLinux = process.platform === 'linux'
|
||||
|
||||
const build = async arch => {
|
||||
console.log(pc.blue(`Building for ${arch}...`))
|
||||
|
|
@ -23,7 +26,7 @@ const build = async arch => {
|
|||
'./node_modules/better-sqlite3/build/Release/better_sqlite3.node',
|
||||
`./dist/main/better_sqlite3_${arch}.node`
|
||||
)
|
||||
if (process.platform === 'win32') {
|
||||
if (isWin) {
|
||||
fs.copyFileSync(
|
||||
'./node_modules/better-sqlite3/build/Release/sqlite3.dll',
|
||||
'./dist/main/sqlite3.dll'
|
||||
|
|
@ -37,9 +40,20 @@ const build = async arch => {
|
|||
}
|
||||
|
||||
const main = async () => {
|
||||
if (argv.x64 || argv.arm64 || argv.arm) {
|
||||
if (argv.x64) await build('x64')
|
||||
if (argv.arm64) await build('arm64')
|
||||
if (argv.arm) await build('arm')
|
||||
} else {
|
||||
if (isWin || isMac) {
|
||||
await build('x64')
|
||||
await build('arm64')
|
||||
} else if (isLinux) {
|
||||
await build('x64')
|
||||
await build('arm64')
|
||||
await build('arm')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
|
|
|
|||
9
src/main/IpcChannelsName.ts
Normal file
9
src/main/IpcChannelsName.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export enum IpcChannels {
|
||||
ClearAPICache = 'clear-api-cache',
|
||||
Minimize = 'minimize',
|
||||
MaximizeOrUnmaximize = 'maximize-or-unmaximize',
|
||||
Close = 'close',
|
||||
IsMaximized = 'is-maximized',
|
||||
GetApiCacheSync = 'get-api-cache-sync',
|
||||
DevDbExportJson = 'dev-db-export-json',
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { db, Tables } from './db'
|
||||
import type { FetchTracksResponse } from '../renderer/api/track'
|
||||
import { app, ipcMain } from 'electron'
|
||||
import { app } from 'electron'
|
||||
import { Request, Response } from 'express'
|
||||
import logger from './logger'
|
||||
import fs from 'fs'
|
||||
|
|
@ -302,9 +302,3 @@ export async function cacheAudio(
|
|||
logger.info(`[cache] cacheAudio ${id}-${br}.${type}`)
|
||||
})
|
||||
}
|
||||
|
||||
ipcMain.on('getApiCacheSync', (event, args) => {
|
||||
const { api, query } = args
|
||||
const data = getCache(api, query)
|
||||
event.returnValue = data
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import path from 'path'
|
||||
import { app, ipcMain } from 'electron'
|
||||
import { app } from 'electron'
|
||||
import fs from 'fs'
|
||||
import SQLite3 from 'better-sqlite3'
|
||||
import logger from './logger'
|
||||
|
|
@ -113,30 +113,4 @@ export const db = {
|
|||
},
|
||||
}
|
||||
|
||||
// 导出tables到json文件,方便查看table大小
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
ipcMain.on('db-export-json', () => {
|
||||
const tables = [
|
||||
Tables.ARTIST_ALBUMS,
|
||||
Tables.PLAYLIST,
|
||||
Tables.ALBUM,
|
||||
Tables.TRACK,
|
||||
Tables.ARTIST,
|
||||
Tables.AUDIO,
|
||||
Tables.ACCOUNT_DATA,
|
||||
Tables.LYRIC,
|
||||
]
|
||||
tables.forEach(table => {
|
||||
const data = db.findAll(table)
|
||||
|
||||
fs.writeFile(`./tmp/${table}.json`, JSON.stringify(data), function (err) {
|
||||
if (err) {
|
||||
return console.log(err)
|
||||
}
|
||||
console.log('The file was saved!')
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
logger.info('[db] Database initialized')
|
||||
|
|
|
|||
|
|
@ -1,14 +1,33 @@
|
|||
import { BrowserWindow, ipcMain, app } from 'electron'
|
||||
import { db, Tables } from './db'
|
||||
import { IpcChannels } from './IpcChannelsName'
|
||||
import { getCache } from './cache'
|
||||
import logger from './logger'
|
||||
import fs from 'fs'
|
||||
|
||||
export enum Events {
|
||||
ClearAPICache = 'clear-api-cache',
|
||||
Minimize = 'minimize',
|
||||
MaximizeOrUnmaximize = 'maximize-or-unmaximize',
|
||||
Close = 'close',
|
||||
/**
|
||||
* 处理需要win对象的事件
|
||||
* @param {BrowserWindow} win
|
||||
*/
|
||||
export function initIpcMain(win: BrowserWindow | null) {
|
||||
ipcMain.on(IpcChannels.Minimize, () => {
|
||||
win?.minimize()
|
||||
})
|
||||
|
||||
ipcMain.on(IpcChannels.MaximizeOrUnmaximize, () => {
|
||||
if (!win) return
|
||||
win.isMaximized() ? win.unmaximize() : win.maximize()
|
||||
})
|
||||
|
||||
ipcMain.on(IpcChannels.Close, () => {
|
||||
app.exit()
|
||||
})
|
||||
}
|
||||
|
||||
ipcMain.on(Events.ClearAPICache, () => {
|
||||
/**
|
||||
* 清除API缓存
|
||||
*/
|
||||
ipcMain.on(IpcChannels.ClearAPICache, () => {
|
||||
db.truncate(Tables.TRACK)
|
||||
db.truncate(Tables.ALBUM)
|
||||
db.truncate(Tables.ARTIST)
|
||||
|
|
@ -19,17 +38,39 @@ ipcMain.on(Events.ClearAPICache, () => {
|
|||
db.vacuum()
|
||||
})
|
||||
|
||||
export function initIpcMain(win: BrowserWindow | null) {
|
||||
ipcMain.on(Events.Minimize, () => {
|
||||
win?.minimize()
|
||||
})
|
||||
/**
|
||||
* Get API cache
|
||||
*/
|
||||
ipcMain.on(IpcChannels.GetApiCacheSync, (event, args) => {
|
||||
const { api, query } = args
|
||||
const data = getCache(api, query)
|
||||
event.returnValue = data
|
||||
})
|
||||
|
||||
ipcMain.on(Events.MaximizeOrUnmaximize, () => {
|
||||
if (!win) return
|
||||
win.isMaximized() ? win.unmaximize() : win.maximize()
|
||||
})
|
||||
/**
|
||||
* 导出tables到json文件,方便查看table大小(dev环境)
|
||||
*/
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
ipcMain.on(IpcChannels.DevDbExportJson, () => {
|
||||
const tables = [
|
||||
Tables.ARTIST_ALBUMS,
|
||||
Tables.PLAYLIST,
|
||||
Tables.ALBUM,
|
||||
Tables.TRACK,
|
||||
Tables.ARTIST,
|
||||
Tables.AUDIO,
|
||||
Tables.ACCOUNT_DATA,
|
||||
Tables.LYRIC,
|
||||
]
|
||||
tables.forEach(table => {
|
||||
const data = db.findAll(table)
|
||||
|
||||
ipcMain.on(Events.Close, () => {
|
||||
app.exit()
|
||||
fs.writeFile(`./tmp/${table}.json`, JSON.stringify(data), function (err) {
|
||||
if (err) {
|
||||
return console.log(err)
|
||||
}
|
||||
console.log('The file was saved!')
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
|
||||
contextBridge.exposeInMainWorld('ipcRenderer', {
|
||||
sendSync: ipcRenderer.sendSync,
|
||||
send: ipcRenderer.send,
|
||||
on: (channel, listener) => {
|
||||
on: (
|
||||
channel: IpcChannels,
|
||||
listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void
|
||||
) => {
|
||||
ipcRenderer.on(channel, listener)
|
||||
return () => ipcRenderer.removeListener(channel, listener)
|
||||
return () => {
|
||||
ipcRenderer.removeListener(channel, listener)
|
||||
}
|
||||
},
|
||||
})
|
||||
contextBridge.exposeInMainWorld('env', {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { Toaster } from 'react-hot-toast'
|
||||
import { QueryClientProvider } from 'react-query'
|
||||
import { ReactQueryDevtools } from 'react-query/devtools'
|
||||
import Player from '@/components/Player'
|
||||
import Sidebar from '@/components/Sidebar'
|
||||
import reactQueryClient from '@/utils/reactQueryClient'
|
||||
import Main from '@/components/Main'
|
||||
import TitleBar from '@/components/TitleBar'
|
||||
import Lyric from '@/components/Lyric'
|
||||
import Player from '@/renderer/components/Player'
|
||||
import Sidebar from '@/renderer/components/Sidebar'
|
||||
import reactQueryClient from '@/renderer/utils/reactQueryClient'
|
||||
import Main from '@/renderer/components/Main'
|
||||
import TitleBar from '@/renderer/components/TitleBar'
|
||||
import Lyric from '@/renderer/components/Lyric'
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import request from '@/utils/request'
|
||||
import request from '@/renderer/utils/request'
|
||||
|
||||
export enum AlbumApiNames {
|
||||
FETCH_ALBUM = 'fetchAlbum',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import request from '@/utils/request'
|
||||
import request from '@/renderer/utils/request'
|
||||
|
||||
export enum ArtistApiNames {
|
||||
FETCH_ARTIST = 'fetchArtist',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { fetchUserAccountResponse } from '@/api/user'
|
||||
import request from '@/utils/request'
|
||||
import type { fetchUserAccountResponse } from '@/renderer/api/user'
|
||||
import request from '@/renderer/utils/request'
|
||||
|
||||
// 手机号登录
|
||||
interface LoginWithPhoneParams {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import request from '@/utils/request'
|
||||
import request from '@/renderer/utils/request'
|
||||
|
||||
export enum PersonalFMApiNames {
|
||||
FETCH_PERSONAL_FM = 'fetchPersonalFM',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import request from '@/utils/request'
|
||||
import request from '@/renderer/utils/request'
|
||||
|
||||
export enum PlaylistApiNames {
|
||||
FETCH_PLAYLIST = 'fetchPlaylist',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import request from '@/utils/request'
|
||||
import request from '@/renderer/utils/request'
|
||||
|
||||
export enum SearchApiNames {
|
||||
SEARCH = 'search',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import request from '@/utils/request'
|
||||
import request from '@/renderer/utils/request'
|
||||
|
||||
export enum TrackApiNames {
|
||||
FETCH_TRACKS = 'fetchTracks',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import request from '@/utils/request'
|
||||
import request from '@/renderer/utils/request'
|
||||
|
||||
export enum UserApiNames {
|
||||
FETCH_USER_ACCOUNT = 'fetchUserAccount',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import SvgIcon from '@/components/SvgIcon'
|
||||
import SvgIcon from '@/renderer/components/SvgIcon'
|
||||
|
||||
const Cover = ({
|
||||
imageUrl,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import Cover from '@/components/Cover'
|
||||
import Skeleton from '@/components/Skeleton'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import { prefetchAlbum } from '@/hooks/useAlbum'
|
||||
import { prefetchPlaylist } from '@/hooks/usePlaylist'
|
||||
import { formatDate, resizeImage, scrollToTop } from '@/utils/common'
|
||||
import Cover from '@/renderer/components/Cover'
|
||||
import Skeleton from '@/renderer/components/Skeleton'
|
||||
import SvgIcon from '@/renderer/components/SvgIcon'
|
||||
import { prefetchAlbum } from '@/renderer/hooks/useAlbum'
|
||||
import { prefetchPlaylist } from '@/renderer/hooks/usePlaylist'
|
||||
import { formatDate, resizeImage, scrollToTop } from '@/renderer/utils/common'
|
||||
|
||||
export enum Subtitle {
|
||||
COPYWRITER = 'copywriter',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import SvgIcon from '@/components/SvgIcon'
|
||||
import SvgIcon from './SvgIcon'
|
||||
import style from './DailyTracksCard.module.scss'
|
||||
|
||||
const DailyTracksCard = () => {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
import { average } from 'color.js'
|
||||
import { colord } from 'colord'
|
||||
import { player } from '@/store'
|
||||
import { resizeImage } from '@/utils/common'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import ArtistInline from '@/components/ArtistsInline'
|
||||
import { State as PlayerState, Mode as PlayerMode } from '@/utils/player'
|
||||
import { player } from '@/renderer/store'
|
||||
import { resizeImage } from '@/renderer/utils/common'
|
||||
import SvgIcon from './SvgIcon'
|
||||
import ArtistInline from './ArtistsInline'
|
||||
import {
|
||||
State as PlayerState,
|
||||
Mode as PlayerMode,
|
||||
} from '@/renderer/utils/player'
|
||||
|
||||
const MediaControls = () => {
|
||||
const classes =
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import useLyric from '@/hooks/useLyric'
|
||||
import { player } from '@/store'
|
||||
import useLyric from '@/renderer/hooks/useLyric'
|
||||
import { player } from '@/renderer/store'
|
||||
import {
|
||||
motion,
|
||||
useMotionValue,
|
||||
|
|
@ -8,7 +8,7 @@ import {
|
|||
useAnimation,
|
||||
LayoutGroup,
|
||||
} from 'framer-motion'
|
||||
import { lyricParser } from '@/utils/lyric'
|
||||
import { lyricParser } from '@/renderer/utils/lyric'
|
||||
|
||||
const Lyric = ({ className }: { className?: string }) => {
|
||||
// const ease = [0.5, 0.2, 0.2, 0.8]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import useLyric from '@/hooks/useLyric'
|
||||
import { player } from '@/store'
|
||||
import useLyric from '@/renderer/hooks/useLyric'
|
||||
import { player } from '@/renderer/store'
|
||||
import { motion, useMotionValue } from 'framer-motion'
|
||||
import { lyricParser } from '@/utils/lyric'
|
||||
import { lyricParser } from '@/renderer/utils/lyric'
|
||||
import { useWindowSize } from 'react-use'
|
||||
import { useLayoutEffect } from 'react'
|
||||
|
||||
const Lyric = ({ className }: { className?: string }) => {
|
||||
// const ease = [0.5, 0.2, 0.2, 0.8]
|
||||
|
|
@ -29,7 +30,7 @@ const Lyric = ({ className }: { className?: string }) => {
|
|||
const y = useMotionValue(1000)
|
||||
const { height: windowHight } = useWindowSize()
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
const top = (
|
||||
document.getElementById('lyrics')?.children?.[currentIndex] as any
|
||||
)?.offsetTop
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import Player from './Player'
|
||||
import { player, state } from '@/store'
|
||||
import { resizeImage } from '@/utils/common'
|
||||
import { player, state } from '@/renderer/store'
|
||||
import { resizeImage } from '@/renderer/utils/common'
|
||||
import { average } from 'color.js'
|
||||
import { colord } from 'colord'
|
||||
import IconButton from '../IconButton'
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
import useUserLikedTracksIDs, {
|
||||
useMutationLikeATrack,
|
||||
} from '@/hooks/useUserLikedTracksIDs'
|
||||
import { player, state } from '@/store'
|
||||
import { resizeImage } from '@/utils/common'
|
||||
} from '@/renderer/hooks/useUserLikedTracksIDs'
|
||||
import { player, state } from '@/renderer/store'
|
||||
import { resizeImage } from '@/renderer/utils/common'
|
||||
|
||||
import ArtistInline from '../ArtistsInline'
|
||||
import Cover from '../Cover'
|
||||
import IconButton from '../IconButton'
|
||||
import SvgIcon from '../SvgIcon'
|
||||
import { State as PlayerState, Mode as PlayerMode } from '@/utils/player'
|
||||
import {
|
||||
State as PlayerState,
|
||||
Mode as PlayerMode,
|
||||
} from '@/renderer/utils/player'
|
||||
|
||||
const PlayingTrack = () => {
|
||||
const playerSnapshot = useSnapshot(player)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import Router from '@/components/Router'
|
||||
import Topbar from '@/components/Topbar'
|
||||
import Router from './Router'
|
||||
import Topbar from './Topbar'
|
||||
|
||||
const Main = () => {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
import ArtistInline from '@/components/ArtistsInline'
|
||||
import IconButton from '@/components/IconButton'
|
||||
import Slider from '@/components/Slider'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import ArtistInline from './ArtistsInline'
|
||||
import IconButton from './IconButton'
|
||||
import Slider from './Slider'
|
||||
import SvgIcon from './SvgIcon'
|
||||
import useUserLikedTracksIDs, {
|
||||
useMutationLikeATrack,
|
||||
} from '@/hooks/useUserLikedTracksIDs'
|
||||
import { player, state } from '@/store'
|
||||
import { resizeImage } from '@/utils/common'
|
||||
import { State as PlayerState, Mode as PlayerMode } from '@/utils/player'
|
||||
} from '@/renderer/hooks/useUserLikedTracksIDs'
|
||||
import { player, state } from '@/renderer/store'
|
||||
import { resizeImage } from '@/renderer/utils/common'
|
||||
import {
|
||||
State as PlayerState,
|
||||
Mode as PlayerMode,
|
||||
} from '@/renderer/utils/player'
|
||||
|
||||
const PlayingTrack = () => {
|
||||
const navigate = useNavigate()
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import type { RouteObject } from 'react-router-dom'
|
||||
import { useRoutes } from 'react-router-dom'
|
||||
import Album from '@/pages/Album'
|
||||
import Home from '@/pages/Home'
|
||||
import Login from '@/pages/Login'
|
||||
import Playlist from '@/pages/Playlist'
|
||||
import Artist from '@/pages/Artist'
|
||||
import Search from '@/pages/Search'
|
||||
import Library from '@/pages/Library'
|
||||
import Podcast from '@/pages/Podcast'
|
||||
import Settings from '@/pages/Settings'
|
||||
import Album from '@/renderer/pages/Album'
|
||||
import Home from '@/renderer/pages/Home'
|
||||
import Login from '@/renderer/pages/Login'
|
||||
import Playlist from '@/renderer/pages/Playlist'
|
||||
import Artist from '@/renderer/pages/Artist'
|
||||
import Search from '@/renderer/pages/Search'
|
||||
import Library from '@/renderer/pages/Library'
|
||||
import Podcast from '@/renderer/pages/Podcast'
|
||||
import Settings from '@/renderer/pages/Settings'
|
||||
|
||||
const routes: RouteObject[] = [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import { NavLink } from 'react-router-dom'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import useUser from '@/hooks/useUser'
|
||||
import useUserPlaylists from '@/hooks/useUserPlaylists'
|
||||
import { scrollToTop } from '@/utils/common'
|
||||
import { prefetchPlaylist } from '@/hooks/usePlaylist'
|
||||
import SvgIcon from './SvgIcon'
|
||||
import useUserPlaylists from '@/renderer/hooks/useUserPlaylists'
|
||||
import { scrollToTop } from '@/renderer/utils/common'
|
||||
import { prefetchPlaylist } from '@/renderer/hooks/usePlaylist'
|
||||
|
||||
interface Tab {
|
||||
name: string
|
||||
|
|
|
|||
|
|
@ -1,25 +1,26 @@
|
|||
import { player } from '@/store'
|
||||
import { player } from '@/renderer/store'
|
||||
import SvgIcon from './SvgIcon'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
const Controls = () => {
|
||||
const [isMaximized, setIsMaximized] = useState(false)
|
||||
|
||||
useEffectOnce(() => {
|
||||
return window.ipcRenderer?.on('is-maximized', (e, value) => {
|
||||
return window.ipcRenderer?.on(IpcChannels.IsMaximized, (e, value) => {
|
||||
setIsMaximized(value)
|
||||
})
|
||||
})
|
||||
|
||||
const minimize = () => {
|
||||
window.ipcRenderer?.send('minimize')
|
||||
window.ipcRenderer?.send(IpcChannels.Minimize)
|
||||
}
|
||||
|
||||
const maxRestore = () => {
|
||||
window.ipcRenderer?.send('maximize-or-unmaximize')
|
||||
window.ipcRenderer?.send(IpcChannels.MaximizeOrUnmaximize)
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
window.ipcRenderer?.send('close')
|
||||
window.ipcRenderer?.send(IpcChannels.Close)
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import SvgIcon from '@/components/SvgIcon'
|
||||
import useScroll from '@/hooks/useScroll'
|
||||
import useUser from '@/hooks/useUser'
|
||||
import { resizeImage } from '@/utils/common'
|
||||
import SvgIcon from '@/renderer/components/SvgIcon'
|
||||
import useScroll from '@/renderer/hooks/useScroll'
|
||||
import useUser from '@/renderer/hooks/useUser'
|
||||
import { resizeImage } from '@/renderer/utils/common'
|
||||
|
||||
const NavigationButtons = () => {
|
||||
const navigate = useNavigate()
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { memo } from 'react'
|
||||
import ArtistInline from '@/components/ArtistsInline'
|
||||
import Skeleton from '@/components/Skeleton'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import ArtistInline from '@/renderer/components/ArtistsInline'
|
||||
import Skeleton from '@/renderer/components/Skeleton'
|
||||
import SvgIcon from '@/renderer/components/SvgIcon'
|
||||
import useUserLikedTracksIDs, {
|
||||
useMutationLikeATrack,
|
||||
} from '@/hooks/useUserLikedTracksIDs'
|
||||
import { player } from '@/store'
|
||||
import { formatDuration } from '@/utils/common'
|
||||
import { State as PlayerState } from '@/utils/player'
|
||||
} from '@/renderer/hooks/useUserLikedTracksIDs'
|
||||
import { player } from '@/renderer/store'
|
||||
import { formatDuration } from '@/renderer/utils/common'
|
||||
import { State as PlayerState } from '@/renderer/utils/player'
|
||||
|
||||
const enableRenderLog = true
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import ArtistInline from '@/components/ArtistsInline'
|
||||
import Skeleton from '@/components/Skeleton'
|
||||
import { player } from '@/store'
|
||||
import { resizeImage } from '@/utils/common'
|
||||
import ArtistInline from '@/renderer/components/ArtistsInline'
|
||||
import Skeleton from '@/renderer/components/Skeleton'
|
||||
import { player } from '@/renderer/store'
|
||||
import { resizeImage } from '@/renderer/utils/common'
|
||||
import SvgIcon from './SvgIcon'
|
||||
|
||||
const Track = ({
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import { memo } from 'react'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import ArtistInline from '@/components/ArtistsInline'
|
||||
import Skeleton from '@/components/Skeleton'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import useUser from '@/hooks/useUser'
|
||||
import ArtistInline from '@/renderer/components/ArtistsInline'
|
||||
import Skeleton from '@/renderer/components/Skeleton'
|
||||
import SvgIcon from '@/renderer/components/SvgIcon'
|
||||
import useUser from '@/renderer/hooks/useUser'
|
||||
import useUserLikedTracksIDs, {
|
||||
useMutationLikeATrack,
|
||||
} from '@/hooks/useUserLikedTracksIDs'
|
||||
import { formatDuration, resizeImage } from '@/utils/common'
|
||||
import { player } from '@/store'
|
||||
} from '@/renderer/hooks/useUserLikedTracksIDs'
|
||||
import { formatDuration, resizeImage } from '@/renderer/utils/common'
|
||||
import { player } from '@/renderer/store'
|
||||
|
||||
const Track = memo(
|
||||
({
|
||||
|
|
|
|||
11
src/renderer/global.d.ts
vendored
11
src/renderer/global.d.ts
vendored
|
|
@ -1,9 +1,18 @@
|
|||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export {}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
// Expose some Api through preload script
|
||||
ipcRenderer?: import('electron').IpcRenderer
|
||||
ipcRenderer?: {
|
||||
sendSync: (channel: IpcChannels, ...args: any[]) => any
|
||||
send: (channel: IpcChannels, ...args: any[]) => void
|
||||
on: (
|
||||
channel: IpcChannels,
|
||||
listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void
|
||||
) => void
|
||||
}
|
||||
env?: {
|
||||
isElectron: boolean
|
||||
isEnableTitlebar: boolean
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { fetchAlbum } from '@/api/album'
|
||||
import { AlbumApiNames } from '@/api/album'
|
||||
import type { FetchAlbumParams, FetchAlbumResponse } from '@/api/album'
|
||||
import reactQueryClient from '@/utils/reactQueryClient'
|
||||
import { fetchAlbum } from '@/renderer/api/album'
|
||||
import { AlbumApiNames } from '@/renderer/api/album'
|
||||
import type { FetchAlbumParams, FetchAlbumResponse } from '@/renderer/api/album'
|
||||
import reactQueryClient from '@/renderer/utils/reactQueryClient'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
const fetch = async (params: FetchAlbumParams, noCache?: boolean) => {
|
||||
const album = await fetchAlbum(params, !!noCache)
|
||||
|
|
@ -19,7 +20,7 @@ export default function useAlbum(params: FetchAlbumParams, noCache?: boolean) {
|
|||
enabled: !!params.id,
|
||||
staleTime: 24 * 60 * 60 * 1000, // 24 hours
|
||||
placeholderData: (): FetchAlbumResponse =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'album',
|
||||
query: {
|
||||
id: params.id,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { fetchArtist } from '@/api/artist'
|
||||
import { ArtistApiNames } from '@/api/artist'
|
||||
import type { FetchArtistParams, FetchArtistResponse } from '@/api/artist'
|
||||
import { fetchArtist } from '@/renderer/api/artist'
|
||||
import { ArtistApiNames } from '@/renderer/api/artist'
|
||||
import type {
|
||||
FetchArtistParams,
|
||||
FetchArtistResponse,
|
||||
} from '@/renderer/api/artist'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export default function useArtist(
|
||||
params: FetchArtistParams,
|
||||
|
|
@ -13,7 +17,7 @@ export default function useArtist(
|
|||
enabled: !!params.id && params.id > 0 && !isNaN(Number(params.id)),
|
||||
staleTime: 5 * 60 * 1000, // 5 mins
|
||||
placeholderData: (): FetchArtistResponse =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'artists',
|
||||
query: {
|
||||
id: params.id,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { fetchArtistAlbums } from '@/api/artist'
|
||||
import { ArtistApiNames } from '@/api/artist'
|
||||
import { fetchArtistAlbums } from '@/renderer/api/artist'
|
||||
import { ArtistApiNames } from '@/renderer/api/artist'
|
||||
import type {
|
||||
FetchArtistAlbumsParams,
|
||||
FetchArtistAlbumsResponse,
|
||||
} from '@/api/artist'
|
||||
} from '@/renderer/api/artist'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export default function useUserAlbums(params: FetchArtistAlbumsParams) {
|
||||
return useQuery(
|
||||
|
|
@ -16,7 +17,7 @@ export default function useUserAlbums(params: FetchArtistAlbumsParams) {
|
|||
enabled: !!params.id && params.id !== 0,
|
||||
staleTime: 3600000,
|
||||
placeholderData: (): FetchArtistAlbumsResponse =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'artist/album',
|
||||
query: {
|
||||
id: params.id,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { TrackApiNames, fetchLyric } from '@/api/track'
|
||||
import type { FetchLyricParams, FetchLyricResponse } from '@/api/track'
|
||||
import reactQueryClient from '@/utils/reactQueryClient'
|
||||
import { TrackApiNames, fetchLyric } from '@/renderer/api/track'
|
||||
import type { FetchLyricParams, FetchLyricResponse } from '@/renderer/api/track'
|
||||
import reactQueryClient from '@/renderer/utils/reactQueryClient'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export default function useLyric(params: FetchLyricParams) {
|
||||
return useQuery(
|
||||
|
|
@ -13,7 +14,7 @@ export default function useLyric(params: FetchLyricParams) {
|
|||
refetchInterval: false,
|
||||
staleTime: Infinity,
|
||||
initialData: (): FetchLyricResponse | undefined =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'lyric',
|
||||
query: {
|
||||
id: params.id,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { fetchPersonalFM, PersonalFMApiNames } from '@/api/personalFM'
|
||||
import reactQueryClient from '@/utils/reactQueryClient'
|
||||
import { fetchPersonalFM, PersonalFMApiNames } from '@/renderer/api/personalFM'
|
||||
import reactQueryClient from '@/renderer/utils/reactQueryClient'
|
||||
|
||||
export function fetchPersonalFMWithReactQuery() {
|
||||
return reactQueryClient.fetchQuery(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
import { fetchPlaylist } from '@/api/playlist'
|
||||
import { PlaylistApiNames } from '@/api/playlist'
|
||||
import type { FetchPlaylistParams, FetchPlaylistResponse } from '@/api/playlist'
|
||||
import reactQueryClient from '@/utils/reactQueryClient'
|
||||
import { fetchPlaylist } from '@/renderer/api/playlist'
|
||||
import { PlaylistApiNames } from '@/renderer/api/playlist'
|
||||
import type {
|
||||
FetchPlaylistParams,
|
||||
FetchPlaylistResponse,
|
||||
} from '@/renderer/api/playlist'
|
||||
import reactQueryClient from '@/renderer/utils/reactQueryClient'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
const fetch = (params: FetchPlaylistParams, noCache?: boolean) => {
|
||||
return fetchPlaylist(params, !!noCache)
|
||||
|
|
@ -18,7 +22,7 @@ export default function usePlaylist(
|
|||
enabled: !!(params.id && params.id > 0 && !isNaN(Number(params.id))),
|
||||
refetchOnWindowFocus: true,
|
||||
placeholderData: (): FetchPlaylistResponse | undefined =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'playlist/detail',
|
||||
query: {
|
||||
id: params.id,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
import { TrackApiNames, fetchAudioSource, fetchTracks } from '@/api/track'
|
||||
import {
|
||||
TrackApiNames,
|
||||
fetchAudioSource,
|
||||
fetchTracks,
|
||||
} from '@/renderer/api/track'
|
||||
import type {
|
||||
FetchAudioSourceParams,
|
||||
FetchTracksParams,
|
||||
FetchTracksResponse,
|
||||
} from '@/api/track'
|
||||
import reactQueryClient from '@/utils/reactQueryClient'
|
||||
} from '@/renderer/api/track'
|
||||
import reactQueryClient from '@/renderer/utils/reactQueryClient'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export default function useTracks(params: FetchTracksParams) {
|
||||
return useQuery(
|
||||
|
|
@ -17,7 +22,7 @@ export default function useTracks(params: FetchTracksParams) {
|
|||
refetchInterval: false,
|
||||
staleTime: Infinity,
|
||||
initialData: (): FetchTracksResponse | undefined =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'song/detail',
|
||||
query: {
|
||||
ids: params.ids.join(','),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { TrackApiNames, fetchTracks } from '@/api/track'
|
||||
import type { FetchTracksParams } from '@/api/track'
|
||||
import { TrackApiNames, fetchTracks } from '@/renderer/api/track'
|
||||
import type { FetchTracksParams } from '@/renderer/api/track'
|
||||
|
||||
// 100 tracks each page
|
||||
const offset = 100
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { fetchUserAccount, fetchUserAccountResponse } from '@/api/user'
|
||||
import { UserApiNames } from '@/api/user'
|
||||
import { fetchUserAccount, fetchUserAccountResponse } from '@/renderer/api/user'
|
||||
import { UserApiNames } from '@/renderer/api/user'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export default function useUser() {
|
||||
return useQuery(UserApiNames.FETCH_USER_ACCOUNT, fetchUserAccount, {
|
||||
refetchOnWindowFocus: true,
|
||||
placeholderData: (): fetchUserAccountResponse | undefined =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'user/account',
|
||||
}),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
import { likeAAlbum } from '@/api/album'
|
||||
import type { FetchUserAlbumsParams, FetchUserAlbumsResponse } from '@/api/user'
|
||||
import { UserApiNames, fetchUserAlbums } from '@/api/user'
|
||||
import { likeAAlbum } from '@/renderer/api/album'
|
||||
import type {
|
||||
FetchUserAlbumsParams,
|
||||
FetchUserAlbumsResponse,
|
||||
} from '@/renderer/api/user'
|
||||
import { UserApiNames, fetchUserAlbums } from '@/renderer/api/user'
|
||||
import { useQueryClient } from 'react-query'
|
||||
import useUser from './useUser'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export default function useUserAlbums(params: FetchUserAlbumsParams = {}) {
|
||||
const { data: user } = useUser()
|
||||
|
|
@ -12,7 +16,7 @@ export default function useUserAlbums(params: FetchUserAlbumsParams = {}) {
|
|||
{
|
||||
refetchOnWindowFocus: true,
|
||||
placeholderData: (): FetchUserAlbumsResponse | undefined =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'album/sublist',
|
||||
query: params,
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import type { FetchUserArtistsResponse } from '@/api/user'
|
||||
import { UserApiNames, fetchUserArtists } from '@/api/user'
|
||||
import type { FetchUserArtistsResponse } from '@/renderer/api/user'
|
||||
import { UserApiNames, fetchUserArtists } from '@/renderer/api/user'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export default function useUserArtists() {
|
||||
return useQuery([UserApiNames.FETCH_USER_ARTIST], fetchUserArtists, {
|
||||
refetchOnWindowFocus: true,
|
||||
placeholderData: (): FetchUserArtistsResponse =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'album/sublist',
|
||||
}),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import type { FetchUserLikedTracksIDsResponse } from '@/api/user'
|
||||
import { UserApiNames, fetchUserLikedTracksIDs } from '@/api/user'
|
||||
import { likeATrack } from '@/api/track'
|
||||
import type { FetchUserLikedTracksIDsResponse } from '@/renderer/api/user'
|
||||
import { UserApiNames, fetchUserLikedTracksIDs } from '@/renderer/api/user'
|
||||
import { likeATrack } from '@/renderer/api/track'
|
||||
import useUser from './useUser'
|
||||
import { useQueryClient } from 'react-query'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export default function useUserLikedTracksIDs() {
|
||||
const { data: user } = useUser()
|
||||
|
|
@ -15,7 +16,7 @@ export default function useUserLikedTracksIDs() {
|
|||
enabled: !!(uid && uid !== 0),
|
||||
refetchOnWindowFocus: true,
|
||||
placeholderData: (): FetchUserLikedTracksIDsResponse | undefined =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'likelist',
|
||||
query: {
|
||||
uid,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { likeAPlaylist } from '@/api/playlist'
|
||||
import type { FetchUserPlaylistsResponse } from '@/api/user'
|
||||
import { UserApiNames, fetchUserPlaylists } from '@/api/user'
|
||||
import { likeAPlaylist } from '@/renderer/api/playlist'
|
||||
import type { FetchUserPlaylistsResponse } from '@/renderer/api/user'
|
||||
import { UserApiNames, fetchUserPlaylists } from '@/renderer/api/user'
|
||||
import { useQueryClient } from 'react-query'
|
||||
import useUser from './useUser'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export default function useUserPlaylists() {
|
||||
const { data: user } = useUser()
|
||||
|
|
@ -31,7 +32,7 @@ export default function useUserPlaylists() {
|
|||
),
|
||||
refetchOnWindowFocus: true,
|
||||
placeholderData: (): FetchUserPlaylistsResponse =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'user/playlist',
|
||||
query: {
|
||||
uid: params.uid,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ 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 './styles/global.scss'
|
||||
import App from './App'
|
||||
import pkg from '../../package.json'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,25 @@
|
|||
import dayjs from 'dayjs'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import Button, { Color as ButtonColor } from '@/components/Button'
|
||||
import CoverRow, { Subtitle } from '@/components/CoverRow'
|
||||
import Skeleton from '@/components/Skeleton'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import TracksAlbum from '@/components/TracksAlbum'
|
||||
import useAlbum from '@/hooks/useAlbum'
|
||||
import useArtistAlbums from '@/hooks/useArtistAlbums'
|
||||
import { player } from '@/store'
|
||||
import { State as PlayerState } from '@/utils/player'
|
||||
import Button, { Color as ButtonColor } from '@/renderer/components/Button'
|
||||
import CoverRow, { Subtitle } from '@/renderer/components/CoverRow'
|
||||
import Skeleton from '@/renderer/components/Skeleton'
|
||||
import SvgIcon from '@/renderer/components/SvgIcon'
|
||||
import TracksAlbum from '@/renderer/components/TracksAlbum'
|
||||
import useAlbum from '@/renderer/hooks/useAlbum'
|
||||
import useArtistAlbums from '@/renderer/hooks/useArtistAlbums'
|
||||
import { player } from '@/renderer/store'
|
||||
import { State as PlayerState } from '@/renderer/utils/player'
|
||||
import {
|
||||
formatDate,
|
||||
formatDuration,
|
||||
resizeImage,
|
||||
scrollToTop,
|
||||
} from '@/utils/common'
|
||||
import useTracks from '@/hooks/useTracks'
|
||||
import useUserAlbums, { useMutationLikeAAlbum } from '@/hooks/useUserAlbums'
|
||||
import useUser from '@/hooks/useUser'
|
||||
} from '@/renderer/utils/common'
|
||||
import useTracks from '@/renderer/hooks/useTracks'
|
||||
import useUserAlbums, {
|
||||
useMutationLikeAAlbum,
|
||||
} from '@/renderer/hooks/useUserAlbums'
|
||||
import useUser from '@/renderer/hooks/useUser'
|
||||
|
||||
const PlayButton = ({
|
||||
album,
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
import Button, { Color as ButtonColor } from '@/components/Button'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import Cover from '@/components/Cover'
|
||||
import useArtist from '@/hooks/useArtist'
|
||||
import useArtistAlbums from '@/hooks/useArtistAlbums'
|
||||
import { resizeImage } from '@/utils/common'
|
||||
import Button, { Color as ButtonColor } from '@/renderer/components/Button'
|
||||
import SvgIcon from '@/renderer/components/SvgIcon'
|
||||
import Cover from '@/renderer/components/Cover'
|
||||
import useArtist from '@/renderer/hooks/useArtist'
|
||||
import useArtistAlbums from '@/renderer/hooks/useArtistAlbums'
|
||||
import { resizeImage } from '@/renderer/utils/common'
|
||||
import dayjs from 'dayjs'
|
||||
import TracksGrid from '@/components/TracksGrid'
|
||||
import CoverRow, { Subtitle } from '@/components/CoverRow'
|
||||
import Skeleton from '@/components/Skeleton'
|
||||
import useTracks from '@/hooks/useTracks'
|
||||
import { player } from '@/store'
|
||||
import TracksGrid from '@/renderer/components/TracksGrid'
|
||||
import CoverRow, { Subtitle } from '@/renderer/components/CoverRow'
|
||||
import Skeleton from '@/renderer/components/Skeleton'
|
||||
import useTracks from '@/renderer/hooks/useTracks'
|
||||
import { player } from '@/renderer/store'
|
||||
|
||||
const Header = ({ artist }: { artist: Artist | undefined }) => {
|
||||
const coverImage = resizeImage(artist?.img1v1Url || '', 'md')
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ import {
|
|||
PlaylistApiNames,
|
||||
fetchRecommendedPlaylists,
|
||||
fetchDailyRecommendPlaylists,
|
||||
} from '@/api/playlist'
|
||||
import CoverRow from '@/components/CoverRow'
|
||||
import DailyTracksCard from '@/components/DailyTracksCard'
|
||||
import FMCard from '@/components/FMCard'
|
||||
} from '@/renderer/api/playlist'
|
||||
import CoverRow from '@/renderer/components/CoverRow'
|
||||
import DailyTracksCard from '@/renderer/components/DailyTracksCard'
|
||||
import FMCard from '@/renderer/components/FMCard'
|
||||
import { IpcChannels } from '@/main/IpcChannelsName'
|
||||
|
||||
export default function Home() {
|
||||
const {
|
||||
|
|
@ -17,7 +18,7 @@ export default function Home() {
|
|||
{
|
||||
retry: false,
|
||||
placeholderData: () =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'recommend/resource',
|
||||
}),
|
||||
}
|
||||
|
|
@ -33,7 +34,7 @@ export default function Home() {
|
|||
},
|
||||
{
|
||||
placeholderData: () =>
|
||||
window.ipcRenderer?.sendSync('getApiCacheSync', {
|
||||
window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
|
||||
api: 'personalized',
|
||||
}),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import CoverRow, { Subtitle } from '@/components/CoverRow'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import useUserAlbums from '@/hooks/useUserAlbums'
|
||||
import useLyric from '@/hooks/useLyric'
|
||||
import usePlaylist from '@/hooks/usePlaylist'
|
||||
import useUser from '@/hooks/useUser'
|
||||
import useUserPlaylists from '@/hooks/useUserPlaylists'
|
||||
import { player } from '@/store'
|
||||
import { resizeImage } from '@/utils/common'
|
||||
import CoverRow, { Subtitle } from '@/renderer/components/CoverRow'
|
||||
import SvgIcon from '@/renderer/components/SvgIcon'
|
||||
import useUserAlbums from '@/renderer/hooks/useUserAlbums'
|
||||
import useLyric from '@/renderer/hooks/useLyric'
|
||||
import usePlaylist from '@/renderer/hooks/usePlaylist'
|
||||
import useUser from '@/renderer/hooks/useUser'
|
||||
import useUserPlaylists from '@/renderer/hooks/useUserPlaylists'
|
||||
import { player } from '@/renderer/store'
|
||||
import { resizeImage } from '@/renderer/utils/common'
|
||||
import { sample, chunk } from 'lodash-es'
|
||||
import useUserArtists from '@/hooks/useUserArtists'
|
||||
import useUserArtists from '@/renderer/hooks/useUserArtists'
|
||||
|
||||
const LikedTracksCard = ({ className }: { className?: string }) => {
|
||||
const navigate = useNavigate()
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ import {
|
|||
fetchLoginQrCodeKey,
|
||||
loginWithEmail,
|
||||
loginWithPhone,
|
||||
} from '@/api/auth'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import { state } from '@/store'
|
||||
import { setCookies } from '@/utils/cookie'
|
||||
} from '@/renderer/api/auth'
|
||||
import SvgIcon from '@/renderer/components/SvgIcon'
|
||||
import { state } from '@/renderer/store'
|
||||
import { setCookies } from '@/renderer/utils/cookie'
|
||||
import { useInterval } from 'react-use'
|
||||
|
||||
enum Method {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
import { memo } from 'react'
|
||||
import Button, { Color as ButtonColor } from '@/components/Button'
|
||||
import Skeleton from '@/components/Skeleton'
|
||||
import SvgIcon from '@/components/SvgIcon'
|
||||
import TracksList from '@/components/TracksList'
|
||||
import usePlaylist from '@/hooks/usePlaylist'
|
||||
import useScroll from '@/hooks/useScroll'
|
||||
import useTracksInfinite from '@/hooks/useTracksInfinite'
|
||||
import { player } from '@/store'
|
||||
import { formatDate, resizeImage } from '@/utils/common'
|
||||
import Button, { Color as ButtonColor } from '@/renderer/components/Button'
|
||||
import Skeleton from '@/renderer/components/Skeleton'
|
||||
import SvgIcon from '@/renderer/components/SvgIcon'
|
||||
import TracksList from '@/renderer/components/TracksList'
|
||||
import usePlaylist from '@/renderer/hooks/usePlaylist'
|
||||
import useScroll from '@/renderer/hooks/useScroll'
|
||||
import useTracksInfinite from '@/renderer/hooks/useTracksInfinite'
|
||||
import { player } from '@/renderer/store'
|
||||
import { formatDate, resizeImage } from '@/renderer/utils/common'
|
||||
import useUserPlaylists, {
|
||||
useMutationLikeAPlaylist,
|
||||
} from '@/hooks/useUserPlaylists'
|
||||
import useUser from '@/hooks/useUser'
|
||||
} from '@/renderer/hooks/useUserPlaylists'
|
||||
import useUser from '@/renderer/hooks/useUser'
|
||||
|
||||
const enableRenderLog = true
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ import {
|
|||
search,
|
||||
SearchApiNames,
|
||||
SearchTypes,
|
||||
} from '@/api/search'
|
||||
import Cover from '@/components/Cover'
|
||||
import TrackGrid from '@/components/TracksGrid'
|
||||
import { player } from '@/store'
|
||||
import { resizeImage } from '@/utils/common'
|
||||
} from '@/renderer/api/search'
|
||||
import Cover from '@/renderer/components/Cover'
|
||||
import TrackGrid from '@/renderer/components/TracksGrid'
|
||||
import { player } from '@/renderer/store'
|
||||
import { resizeImage } from '@/renderer/utils/common'
|
||||
|
||||
const Artists = ({ artists }: { artists: Artist[] }) => {
|
||||
const navigate = useNavigate()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { proxy, subscribe } from 'valtio'
|
||||
import { devtools } from 'valtio/utils'
|
||||
import { Player } from '@/utils/player'
|
||||
import { Player } from '@/renderer/utils/player'
|
||||
|
||||
interface Store {
|
||||
uiStates: {
|
||||
|
|
|
|||
|
|
@ -54,38 +54,38 @@
|
|||
@font-face {
|
||||
font-family: Barlow;
|
||||
font-weight: normal;
|
||||
src: url('@/assets/fonts/Barlow-Regular.woff2') format('woff2'),
|
||||
url('@/assets/fonts/Barlow-Regular.ttf') format('truetype');
|
||||
src: url('@/renderer/assets/fonts/Barlow-Regular.woff2') format('woff2'),
|
||||
url('@/renderer/assets/fonts/Barlow-Regular.ttf') format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: Barlow;
|
||||
font-weight: medium;
|
||||
src: url('@/assets/fonts/Barlow-Medium.woff2') format('woff2'),
|
||||
url('@/assets/fonts/Barlow-Medium.ttf') format('truetype');
|
||||
src: url('@/renderer/assets/fonts/Barlow-Medium.woff2') format('woff2'),
|
||||
url('@/renderer/assets/fonts/Barlow-Medium.ttf') format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: Barlow;
|
||||
font-weight: 600;
|
||||
src: url('@/assets/fonts/Barlow-SemiBold.woff2') format('woff2'),
|
||||
url('@/assets/fonts/Barlow-SemiBold.ttf') format('truetype');
|
||||
src: url('@/renderer/assets/fonts/Barlow-SemiBold.woff2') format('woff2'),
|
||||
url('@/renderer/assets/fonts/Barlow-SemiBold.ttf') format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: Barlow;
|
||||
font-weight: bold;
|
||||
src: url('@/assets/fonts/Barlow-Bold.woff2') format('woff2'),
|
||||
url('@/assets/fonts/Barlow-Bold.ttf') format('truetype');
|
||||
src: url('@/renderer/assets/fonts/Barlow-Bold.woff2') format('woff2'),
|
||||
url('@/renderer/assets/fonts/Barlow-Bold.ttf') format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: Barlow;
|
||||
font-weight: 800;
|
||||
src: url('@/assets/fonts/Barlow-ExtraBold.woff2') format('woff2'),
|
||||
url('@/assets/fonts/Barlow-ExtraBold.ttf') format('truetype');
|
||||
src: url('@/renderer/assets/fonts/Barlow-ExtraBold.woff2') format('woff2'),
|
||||
url('@/renderer/assets/fonts/Barlow-ExtraBold.ttf') format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: Barlow;
|
||||
font-weight: 900;
|
||||
src: url('@/assets/fonts/Barlow-Black.woff2') format('woff2'),
|
||||
url('@/assets/fonts/Barlow-Black.ttf') format('truetype');
|
||||
src: url('@/renderer/assets/fonts/Barlow-Black.woff2') format('woff2'),
|
||||
url('@/renderer/assets/fonts/Barlow-Black.ttf') format('truetype');
|
||||
}
|
||||
|
||||
body,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
"jsx": "react-jsx",
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["*"]
|
||||
"@/*": ["../*"]
|
||||
}
|
||||
},
|
||||
"include": ["./**/*.ts", "./**/*.tsx"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { FetchLyricResponse } from '@/api/track'
|
||||
import { FetchLyricResponse } from '@/renderer/api/track'
|
||||
|
||||
export function lyricParser(lrc: FetchLyricResponse) {
|
||||
return {
|
||||
|
|
@ -58,7 +58,7 @@ function parseLyric(lrc: string): ParsedLyric[] {
|
|||
|
||||
if (
|
||||
content.match(
|
||||
/((\s|\S)*)(作曲|作词|编曲|制作|Producers|Producer|Produced|贝斯|工程师|吉他|合成器|助理|编程|制作|和声|母带|人声|鼓|混音|中提琴|编写|Talkbox|钢琴|出版|录音|发行|出品)((\s|\S)*)(:|:)/
|
||||
/((\s|\S)*)(作曲|作词|编曲|制作|Producers|Producer|Produced|贝斯|工程师|吉他|合成器|助理|编程|制作|和声|母带|人声|鼓|混音|中提琴|编写|Talkbox|钢琴|出版|录音|发行|出品|键盘|弦乐|设计|监制|原曲|演唱|声明|版权|封面|插画|统筹|企划|填词|原唱|后期|和音|琵琶)((\s|\S)*)(:|:)/
|
||||
)
|
||||
) {
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@ import { Howl, Howler } from 'howler'
|
|||
import {
|
||||
fetchAudioSourceWithReactQuery,
|
||||
fetchTracksWithReactQuery,
|
||||
} from '@/hooks/useTracks'
|
||||
import { fetchPersonalFMWithReactQuery } from '@/hooks/usePersonalFM'
|
||||
import { fmTrash } from '@/api/personalFM'
|
||||
import { cacheAudio } from '@/api/yesplaymusic'
|
||||
} from '@/renderer/hooks/useTracks'
|
||||
import { fetchPersonalFMWithReactQuery } from '@/renderer/hooks/usePersonalFM'
|
||||
import { fmTrash } from '@/renderer/api/personalFM'
|
||||
import { cacheAudio } from '@/renderer/api/yesplaymusic'
|
||||
import { clamp } from 'lodash-es'
|
||||
import axios from 'axios'
|
||||
import { resizeImage } from './common'
|
||||
import { fetchPlaylistWithReactQuery } from '@/hooks/usePlaylist'
|
||||
import { fetchAlbumWithReactQuery } from '@/hooks/useAlbum'
|
||||
import { fetchPlaylistWithReactQuery } from '@/renderer/hooks/usePlaylist'
|
||||
import { fetchAlbumWithReactQuery } from '@/renderer/hooks/useAlbum'
|
||||
|
||||
type TrackID = number
|
||||
enum TrackListSourceType {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
"jsx": "react-jsx",
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["src/renderer/*"]
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "./dist"]
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export default defineConfig({
|
|||
{ 'react-query': ['useQuery', 'useMutation', 'useInfiniteQuery'] },
|
||||
{ 'react-router-dom': ['useNavigate', 'useParams'] },
|
||||
{ 'react-hot-toast': ['toast'] },
|
||||
{ 'react-use': ['useEffectOnce']},
|
||||
{ 'react-use': ['useEffectOnce'] },
|
||||
{ valtio: ['useSnapshot'] },
|
||||
],
|
||||
}),
|
||||
|
|
@ -60,7 +60,7 @@ export default defineConfig({
|
|||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': join(__dirname, './src/renderer'),
|
||||
'@': join(__dirname, './src'),
|
||||
},
|
||||
},
|
||||
clearScreen: false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue