fix: bugs

fix: bugs
This commit is contained in:
qier222 2022-04-09 00:28:37 +08:00
parent 1444bbefa2
commit 70d1de0e0f
No known key found for this signature in database
GPG key ID: 9C85007ED905F14D
62 changed files with 368 additions and 284 deletions

View file

@ -10,7 +10,7 @@
"repository": "github:qier222/YesPlayMusic", "repository": "github:qier222/YesPlayMusic",
"main": "dist/main/index.js", "main": "dist/main/index.js",
"scripts": { "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": "concurrently -n=vite,main -c=#646cff,#74b1be \"npm run dev:renderer\" \"node scripts/build.main.mjs --watch\"",
"dev:renderer": "vite dev", "dev:renderer": "vite dev",
"build:main": "node scripts/build.main.mjs", "build:main": "node scripts/build.main.mjs",

View file

@ -6,6 +6,9 @@ import pc from 'picocolors'
const pkg = JSON.parse(await fs.readFileSync('./package.json', 'utf8')) const pkg = JSON.parse(await fs.readFileSync('./package.json', 'utf8'))
const electronVersion = pkg.devDependencies.electron.replaceAll('^', '') const electronVersion = pkg.devDependencies.electron.replaceAll('^', '')
const argv = minimist(process.argv.slice(2)) 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 => { const build = async arch => {
console.log(pc.blue(`Building for ${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', './node_modules/better-sqlite3/build/Release/better_sqlite3.node',
`./dist/main/better_sqlite3_${arch}.node` `./dist/main/better_sqlite3_${arch}.node`
) )
if (process.platform === 'win32') { if (isWin) {
fs.copyFileSync( fs.copyFileSync(
'./node_modules/better-sqlite3/build/Release/sqlite3.dll', './node_modules/better-sqlite3/build/Release/sqlite3.dll',
'./dist/main/sqlite3.dll' './dist/main/sqlite3.dll'
@ -37,9 +40,20 @@ const build = async arch => {
} }
const main = async () => { const main = async () => {
if (argv.x64) await build('x64') if (argv.x64 || argv.arm64 || argv.arm) {
if (argv.arm64) await build('arm64') if (argv.x64) await build('x64')
if (argv.arm) await build('arm') 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() main()

View 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',
}

View file

@ -1,6 +1,6 @@
import { db, Tables } from './db' import { db, Tables } from './db'
import type { FetchTracksResponse } from '../renderer/api/track' import type { FetchTracksResponse } from '../renderer/api/track'
import { app, ipcMain } from 'electron' import { app } from 'electron'
import { Request, Response } from 'express' import { Request, Response } from 'express'
import logger from './logger' import logger from './logger'
import fs from 'fs' import fs from 'fs'
@ -302,9 +302,3 @@ export async function cacheAudio(
logger.info(`[cache] cacheAudio ${id}-${br}.${type}`) logger.info(`[cache] cacheAudio ${id}-${br}.${type}`)
}) })
} }
ipcMain.on('getApiCacheSync', (event, args) => {
const { api, query } = args
const data = getCache(api, query)
event.returnValue = data
})

View file

@ -1,5 +1,5 @@
import path from 'path' import path from 'path'
import { app, ipcMain } from 'electron' import { app } from 'electron'
import fs from 'fs' import fs from 'fs'
import SQLite3 from 'better-sqlite3' import SQLite3 from 'better-sqlite3'
import logger from './logger' 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') logger.info('[db] Database initialized')

View file

@ -1,14 +1,33 @@
import { BrowserWindow, ipcMain, app } from 'electron' import { BrowserWindow, ipcMain, app } from 'electron'
import { db, Tables } from './db' 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', * win对象的事件
Minimize = 'minimize', * @param {BrowserWindow} win
MaximizeOrUnmaximize = 'maximize-or-unmaximize', */
Close = 'close', 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.TRACK)
db.truncate(Tables.ALBUM) db.truncate(Tables.ALBUM)
db.truncate(Tables.ARTIST) db.truncate(Tables.ARTIST)
@ -19,17 +38,39 @@ ipcMain.on(Events.ClearAPICache, () => {
db.vacuum() db.vacuum()
}) })
export function initIpcMain(win: BrowserWindow | null) { /**
ipcMain.on(Events.Minimize, () => { * Get API cache
win?.minimize() */
}) 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 * tables到json文件便table大小dev环境
win.isMaximized() ? win.unmaximize() : win.maximize() */
}) 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, () => { fs.writeFile(`./tmp/${table}.json`, JSON.stringify(data), function (err) {
app.exit() if (err) {
return console.log(err)
}
console.log('The file was saved!')
})
})
}) })
} }

View file

@ -1,11 +1,17 @@
import { IpcChannels } from '@/main/IpcChannelsName'
const { contextBridge, ipcRenderer } = require('electron') const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('ipcRenderer', { contextBridge.exposeInMainWorld('ipcRenderer', {
sendSync: ipcRenderer.sendSync, sendSync: ipcRenderer.sendSync,
send: ipcRenderer.send, send: ipcRenderer.send,
on: (channel, listener) => { on: (
channel: IpcChannels,
listener: (event: Electron.IpcRendererEvent, ...args: any[]) => void
) => {
ipcRenderer.on(channel, listener) ipcRenderer.on(channel, listener)
return () => ipcRenderer.removeListener(channel, listener) return () => {
ipcRenderer.removeListener(channel, listener)
}
}, },
}) })
contextBridge.exposeInMainWorld('env', { contextBridge.exposeInMainWorld('env', {

View file

@ -1,12 +1,12 @@
import { Toaster } from 'react-hot-toast' import { Toaster } from 'react-hot-toast'
import { QueryClientProvider } from 'react-query' import { QueryClientProvider } from 'react-query'
import { ReactQueryDevtools } from 'react-query/devtools' import { ReactQueryDevtools } from 'react-query/devtools'
import Player from '@/components/Player' import Player from '@/renderer/components/Player'
import Sidebar from '@/components/Sidebar' import Sidebar from '@/renderer/components/Sidebar'
import reactQueryClient from '@/utils/reactQueryClient' import reactQueryClient from '@/renderer/utils/reactQueryClient'
import Main from '@/components/Main' import Main from '@/renderer/components/Main'
import TitleBar from '@/components/TitleBar' import TitleBar from '@/renderer/components/TitleBar'
import Lyric from '@/components/Lyric' import Lyric from '@/renderer/components/Lyric'
const App = () => { const App = () => {
return ( return (

View file

@ -1,4 +1,4 @@
import request from '@/utils/request' import request from '@/renderer/utils/request'
export enum AlbumApiNames { export enum AlbumApiNames {
FETCH_ALBUM = 'fetchAlbum', FETCH_ALBUM = 'fetchAlbum',

View file

@ -1,4 +1,4 @@
import request from '@/utils/request' import request from '@/renderer/utils/request'
export enum ArtistApiNames { export enum ArtistApiNames {
FETCH_ARTIST = 'fetchArtist', FETCH_ARTIST = 'fetchArtist',

View file

@ -1,5 +1,5 @@
import type { fetchUserAccountResponse } from '@/api/user' import type { fetchUserAccountResponse } from '@/renderer/api/user'
import request from '@/utils/request' import request from '@/renderer/utils/request'
// 手机号登录 // 手机号登录
interface LoginWithPhoneParams { interface LoginWithPhoneParams {

View file

@ -1,4 +1,4 @@
import request from '@/utils/request' import request from '@/renderer/utils/request'
export enum PersonalFMApiNames { export enum PersonalFMApiNames {
FETCH_PERSONAL_FM = 'fetchPersonalFM', FETCH_PERSONAL_FM = 'fetchPersonalFM',

View file

@ -1,4 +1,4 @@
import request from '@/utils/request' import request from '@/renderer/utils/request'
export enum PlaylistApiNames { export enum PlaylistApiNames {
FETCH_PLAYLIST = 'fetchPlaylist', FETCH_PLAYLIST = 'fetchPlaylist',

View file

@ -1,4 +1,4 @@
import request from '@/utils/request' import request from '@/renderer/utils/request'
export enum SearchApiNames { export enum SearchApiNames {
SEARCH = 'search', SEARCH = 'search',

View file

@ -1,4 +1,4 @@
import request from '@/utils/request' import request from '@/renderer/utils/request'
export enum TrackApiNames { export enum TrackApiNames {
FETCH_TRACKS = 'fetchTracks', FETCH_TRACKS = 'fetchTracks',

View file

@ -1,4 +1,4 @@
import request from '@/utils/request' import request from '@/renderer/utils/request'
export enum UserApiNames { export enum UserApiNames {
FETCH_USER_ACCOUNT = 'fetchUserAccount', FETCH_USER_ACCOUNT = 'fetchUserAccount',

View file

@ -1,4 +1,4 @@
import SvgIcon from '@/components/SvgIcon' import SvgIcon from '@/renderer/components/SvgIcon'
const Cover = ({ const Cover = ({
imageUrl, imageUrl,

View file

@ -1,9 +1,9 @@
import Cover from '@/components/Cover' import Cover from '@/renderer/components/Cover'
import Skeleton from '@/components/Skeleton' import Skeleton from '@/renderer/components/Skeleton'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from '@/renderer/components/SvgIcon'
import { prefetchAlbum } from '@/hooks/useAlbum' import { prefetchAlbum } from '@/renderer/hooks/useAlbum'
import { prefetchPlaylist } from '@/hooks/usePlaylist' import { prefetchPlaylist } from '@/renderer/hooks/usePlaylist'
import { formatDate, resizeImage, scrollToTop } from '@/utils/common' import { formatDate, resizeImage, scrollToTop } from '@/renderer/utils/common'
export enum Subtitle { export enum Subtitle {
COPYWRITER = 'copywriter', COPYWRITER = 'copywriter',

View file

@ -1,4 +1,4 @@
import SvgIcon from '@/components/SvgIcon' import SvgIcon from './SvgIcon'
import style from './DailyTracksCard.module.scss' import style from './DailyTracksCard.module.scss'
const DailyTracksCard = () => { const DailyTracksCard = () => {

View file

@ -1,10 +1,13 @@
import { average } from 'color.js' import { average } from 'color.js'
import { colord } from 'colord' import { colord } from 'colord'
import { player } from '@/store' import { player } from '@/renderer/store'
import { resizeImage } from '@/utils/common' import { resizeImage } from '@/renderer/utils/common'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from './SvgIcon'
import ArtistInline from '@/components/ArtistsInline' import ArtistInline from './ArtistsInline'
import { State as PlayerState, Mode as PlayerMode } from '@/utils/player' import {
State as PlayerState,
Mode as PlayerMode,
} from '@/renderer/utils/player'
const MediaControls = () => { const MediaControls = () => {
const classes = const classes =

View file

@ -1,5 +1,5 @@
import useLyric from '@/hooks/useLyric' import useLyric from '@/renderer/hooks/useLyric'
import { player } from '@/store' import { player } from '@/renderer/store'
import { import {
motion, motion,
useMotionValue, useMotionValue,
@ -8,7 +8,7 @@ import {
useAnimation, useAnimation,
LayoutGroup, LayoutGroup,
} from 'framer-motion' } from 'framer-motion'
import { lyricParser } from '@/utils/lyric' import { lyricParser } from '@/renderer/utils/lyric'
const Lyric = ({ className }: { className?: string }) => { const Lyric = ({ className }: { className?: string }) => {
// const ease = [0.5, 0.2, 0.2, 0.8] // const ease = [0.5, 0.2, 0.2, 0.8]

View file

@ -1,8 +1,9 @@
import useLyric from '@/hooks/useLyric' import useLyric from '@/renderer/hooks/useLyric'
import { player } from '@/store' import { player } from '@/renderer/store'
import { motion, useMotionValue } from 'framer-motion' import { motion, useMotionValue } from 'framer-motion'
import { lyricParser } from '@/utils/lyric' import { lyricParser } from '@/renderer/utils/lyric'
import { useWindowSize } from 'react-use' import { useWindowSize } from 'react-use'
import { useLayoutEffect } from 'react'
const Lyric = ({ className }: { className?: string }) => { const Lyric = ({ className }: { className?: string }) => {
// const ease = [0.5, 0.2, 0.2, 0.8] // const ease = [0.5, 0.2, 0.2, 0.8]
@ -29,7 +30,7 @@ const Lyric = ({ className }: { className?: string }) => {
const y = useMotionValue(1000) const y = useMotionValue(1000)
const { height: windowHight } = useWindowSize() const { height: windowHight } = useWindowSize()
useEffect(() => { useLayoutEffect(() => {
const top = ( const top = (
document.getElementById('lyrics')?.children?.[currentIndex] as any document.getElementById('lyrics')?.children?.[currentIndex] as any
)?.offsetTop )?.offsetTop

View file

@ -1,6 +1,6 @@
import Player from './Player' import Player from './Player'
import { player, state } from '@/store' import { player, state } from '@/renderer/store'
import { resizeImage } from '@/utils/common' import { resizeImage } from '@/renderer/utils/common'
import { average } from 'color.js' import { average } from 'color.js'
import { colord } from 'colord' import { colord } from 'colord'
import IconButton from '../IconButton' import IconButton from '../IconButton'

View file

@ -1,14 +1,17 @@
import useUserLikedTracksIDs, { import useUserLikedTracksIDs, {
useMutationLikeATrack, useMutationLikeATrack,
} from '@/hooks/useUserLikedTracksIDs' } from '@/renderer/hooks/useUserLikedTracksIDs'
import { player, state } from '@/store' import { player, state } from '@/renderer/store'
import { resizeImage } from '@/utils/common' import { resizeImage } from '@/renderer/utils/common'
import ArtistInline from '../ArtistsInline' import ArtistInline from '../ArtistsInline'
import Cover from '../Cover' import Cover from '../Cover'
import IconButton from '../IconButton' import IconButton from '../IconButton'
import SvgIcon from '../SvgIcon' 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 PlayingTrack = () => {
const playerSnapshot = useSnapshot(player) const playerSnapshot = useSnapshot(player)

View file

@ -1,5 +1,5 @@
import Router from '@/components/Router' import Router from './Router'
import Topbar from '@/components/Topbar' import Topbar from './Topbar'
const Main = () => { const Main = () => {
return ( return (

View file

@ -1,13 +1,16 @@
import ArtistInline from '@/components/ArtistsInline' import ArtistInline from './ArtistsInline'
import IconButton from '@/components/IconButton' import IconButton from './IconButton'
import Slider from '@/components/Slider' import Slider from './Slider'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from './SvgIcon'
import useUserLikedTracksIDs, { import useUserLikedTracksIDs, {
useMutationLikeATrack, useMutationLikeATrack,
} from '@/hooks/useUserLikedTracksIDs' } from '@/renderer/hooks/useUserLikedTracksIDs'
import { player, state } from '@/store' import { player, state } from '@/renderer/store'
import { resizeImage } from '@/utils/common' import { resizeImage } from '@/renderer/utils/common'
import { State as PlayerState, Mode as PlayerMode } from '@/utils/player' import {
State as PlayerState,
Mode as PlayerMode,
} from '@/renderer/utils/player'
const PlayingTrack = () => { const PlayingTrack = () => {
const navigate = useNavigate() const navigate = useNavigate()

View file

@ -1,14 +1,14 @@
import type { RouteObject } from 'react-router-dom' import type { RouteObject } from 'react-router-dom'
import { useRoutes } from 'react-router-dom' import { useRoutes } from 'react-router-dom'
import Album from '@/pages/Album' import Album from '@/renderer/pages/Album'
import Home from '@/pages/Home' import Home from '@/renderer/pages/Home'
import Login from '@/pages/Login' import Login from '@/renderer/pages/Login'
import Playlist from '@/pages/Playlist' import Playlist from '@/renderer/pages/Playlist'
import Artist from '@/pages/Artist' import Artist from '@/renderer/pages/Artist'
import Search from '@/pages/Search' import Search from '@/renderer/pages/Search'
import Library from '@/pages/Library' import Library from '@/renderer/pages/Library'
import Podcast from '@/pages/Podcast' import Podcast from '@/renderer/pages/Podcast'
import Settings from '@/pages/Settings' import Settings from '@/renderer/pages/Settings'
const routes: RouteObject[] = [ const routes: RouteObject[] = [
{ {

View file

@ -1,9 +1,8 @@
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from './SvgIcon'
import useUser from '@/hooks/useUser' import useUserPlaylists from '@/renderer/hooks/useUserPlaylists'
import useUserPlaylists from '@/hooks/useUserPlaylists' import { scrollToTop } from '@/renderer/utils/common'
import { scrollToTop } from '@/utils/common' import { prefetchPlaylist } from '@/renderer/hooks/usePlaylist'
import { prefetchPlaylist } from '@/hooks/usePlaylist'
interface Tab { interface Tab {
name: string name: string

View file

@ -1,25 +1,26 @@
import { player } from '@/store' import { player } from '@/renderer/store'
import SvgIcon from './SvgIcon' import SvgIcon from './SvgIcon'
import { IpcChannels } from '@/main/IpcChannelsName'
const Controls = () => { const Controls = () => {
const [isMaximized, setIsMaximized] = useState(false) const [isMaximized, setIsMaximized] = useState(false)
useEffectOnce(() => { useEffectOnce(() => {
return window.ipcRenderer?.on('is-maximized', (e, value) => { return window.ipcRenderer?.on(IpcChannels.IsMaximized, (e, value) => {
setIsMaximized(value) setIsMaximized(value)
}) })
}) })
const minimize = () => { const minimize = () => {
window.ipcRenderer?.send('minimize') window.ipcRenderer?.send(IpcChannels.Minimize)
} }
const maxRestore = () => { const maxRestore = () => {
window.ipcRenderer?.send('maximize-or-unmaximize') window.ipcRenderer?.send(IpcChannels.MaximizeOrUnmaximize)
} }
const close = () => { const close = () => {
window.ipcRenderer?.send('close') window.ipcRenderer?.send(IpcChannels.Close)
} }
return ( return (

View file

@ -1,7 +1,7 @@
import SvgIcon from '@/components/SvgIcon' import SvgIcon from '@/renderer/components/SvgIcon'
import useScroll from '@/hooks/useScroll' import useScroll from '@/renderer/hooks/useScroll'
import useUser from '@/hooks/useUser' import useUser from '@/renderer/hooks/useUser'
import { resizeImage } from '@/utils/common' import { resizeImage } from '@/renderer/utils/common'
const NavigationButtons = () => { const NavigationButtons = () => {
const navigate = useNavigate() const navigate = useNavigate()

View file

@ -1,13 +1,13 @@
import { memo } from 'react' import { memo } from 'react'
import ArtistInline from '@/components/ArtistsInline' import ArtistInline from '@/renderer/components/ArtistsInline'
import Skeleton from '@/components/Skeleton' import Skeleton from '@/renderer/components/Skeleton'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from '@/renderer/components/SvgIcon'
import useUserLikedTracksIDs, { import useUserLikedTracksIDs, {
useMutationLikeATrack, useMutationLikeATrack,
} from '@/hooks/useUserLikedTracksIDs' } from '@/renderer/hooks/useUserLikedTracksIDs'
import { player } from '@/store' import { player } from '@/renderer/store'
import { formatDuration } from '@/utils/common' import { formatDuration } from '@/renderer/utils/common'
import { State as PlayerState } from '@/utils/player' import { State as PlayerState } from '@/renderer/utils/player'
const enableRenderLog = true const enableRenderLog = true

View file

@ -1,7 +1,7 @@
import ArtistInline from '@/components/ArtistsInline' import ArtistInline from '@/renderer/components/ArtistsInline'
import Skeleton from '@/components/Skeleton' import Skeleton from '@/renderer/components/Skeleton'
import { player } from '@/store' import { player } from '@/renderer/store'
import { resizeImage } from '@/utils/common' import { resizeImage } from '@/renderer/utils/common'
import SvgIcon from './SvgIcon' import SvgIcon from './SvgIcon'
const Track = ({ const Track = ({

View file

@ -1,14 +1,14 @@
import { memo } from 'react' import { memo } from 'react'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import ArtistInline from '@/components/ArtistsInline' import ArtistInline from '@/renderer/components/ArtistsInline'
import Skeleton from '@/components/Skeleton' import Skeleton from '@/renderer/components/Skeleton'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from '@/renderer/components/SvgIcon'
import useUser from '@/hooks/useUser' import useUser from '@/renderer/hooks/useUser'
import useUserLikedTracksIDs, { import useUserLikedTracksIDs, {
useMutationLikeATrack, useMutationLikeATrack,
} from '@/hooks/useUserLikedTracksIDs' } from '@/renderer/hooks/useUserLikedTracksIDs'
import { formatDuration, resizeImage } from '@/utils/common' import { formatDuration, resizeImage } from '@/renderer/utils/common'
import { player } from '@/store' import { player } from '@/renderer/store'
const Track = memo( const Track = memo(
({ ({

View file

@ -1,9 +1,18 @@
import { IpcChannels } from '@/main/IpcChannelsName'
export {} export {}
declare global { declare global {
interface Window { interface Window {
// Expose some Api through preload script // 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?: { env?: {
isElectron: boolean isElectron: boolean
isEnableTitlebar: boolean isEnableTitlebar: boolean

View file

@ -1,7 +1,8 @@
import { fetchAlbum } from '@/api/album' import { fetchAlbum } from '@/renderer/api/album'
import { AlbumApiNames } from '@/api/album' import { AlbumApiNames } from '@/renderer/api/album'
import type { FetchAlbumParams, FetchAlbumResponse } from '@/api/album' import type { FetchAlbumParams, FetchAlbumResponse } from '@/renderer/api/album'
import reactQueryClient from '@/utils/reactQueryClient' import reactQueryClient from '@/renderer/utils/reactQueryClient'
import { IpcChannels } from '@/main/IpcChannelsName'
const fetch = async (params: FetchAlbumParams, noCache?: boolean) => { const fetch = async (params: FetchAlbumParams, noCache?: boolean) => {
const album = await fetchAlbum(params, !!noCache) const album = await fetchAlbum(params, !!noCache)
@ -19,7 +20,7 @@ export default function useAlbum(params: FetchAlbumParams, noCache?: boolean) {
enabled: !!params.id, enabled: !!params.id,
staleTime: 24 * 60 * 60 * 1000, // 24 hours staleTime: 24 * 60 * 60 * 1000, // 24 hours
placeholderData: (): FetchAlbumResponse => placeholderData: (): FetchAlbumResponse =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'album', api: 'album',
query: { query: {
id: params.id, id: params.id,

View file

@ -1,6 +1,10 @@
import { fetchArtist } from '@/api/artist' import { fetchArtist } from '@/renderer/api/artist'
import { ArtistApiNames } from '@/api/artist' import { ArtistApiNames } from '@/renderer/api/artist'
import type { FetchArtistParams, FetchArtistResponse } from '@/api/artist' import type {
FetchArtistParams,
FetchArtistResponse,
} from '@/renderer/api/artist'
import { IpcChannels } from '@/main/IpcChannelsName'
export default function useArtist( export default function useArtist(
params: FetchArtistParams, params: FetchArtistParams,
@ -13,7 +17,7 @@ export default function useArtist(
enabled: !!params.id && params.id > 0 && !isNaN(Number(params.id)), enabled: !!params.id && params.id > 0 && !isNaN(Number(params.id)),
staleTime: 5 * 60 * 1000, // 5 mins staleTime: 5 * 60 * 1000, // 5 mins
placeholderData: (): FetchArtistResponse => placeholderData: (): FetchArtistResponse =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'artists', api: 'artists',
query: { query: {
id: params.id, id: params.id,

View file

@ -1,9 +1,10 @@
import { fetchArtistAlbums } from '@/api/artist' import { fetchArtistAlbums } from '@/renderer/api/artist'
import { ArtistApiNames } from '@/api/artist' import { ArtistApiNames } from '@/renderer/api/artist'
import type { import type {
FetchArtistAlbumsParams, FetchArtistAlbumsParams,
FetchArtistAlbumsResponse, FetchArtistAlbumsResponse,
} from '@/api/artist' } from '@/renderer/api/artist'
import { IpcChannels } from '@/main/IpcChannelsName'
export default function useUserAlbums(params: FetchArtistAlbumsParams) { export default function useUserAlbums(params: FetchArtistAlbumsParams) {
return useQuery( return useQuery(
@ -16,7 +17,7 @@ export default function useUserAlbums(params: FetchArtistAlbumsParams) {
enabled: !!params.id && params.id !== 0, enabled: !!params.id && params.id !== 0,
staleTime: 3600000, staleTime: 3600000,
placeholderData: (): FetchArtistAlbumsResponse => placeholderData: (): FetchArtistAlbumsResponse =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'artist/album', api: 'artist/album',
query: { query: {
id: params.id, id: params.id,

View file

@ -1,6 +1,7 @@
import { TrackApiNames, fetchLyric } from '@/api/track' import { TrackApiNames, fetchLyric } from '@/renderer/api/track'
import type { FetchLyricParams, FetchLyricResponse } from '@/api/track' import type { FetchLyricParams, FetchLyricResponse } from '@/renderer/api/track'
import reactQueryClient from '@/utils/reactQueryClient' import reactQueryClient from '@/renderer/utils/reactQueryClient'
import { IpcChannels } from '@/main/IpcChannelsName'
export default function useLyric(params: FetchLyricParams) { export default function useLyric(params: FetchLyricParams) {
return useQuery( return useQuery(
@ -13,7 +14,7 @@ export default function useLyric(params: FetchLyricParams) {
refetchInterval: false, refetchInterval: false,
staleTime: Infinity, staleTime: Infinity,
initialData: (): FetchLyricResponse | undefined => initialData: (): FetchLyricResponse | undefined =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'lyric', api: 'lyric',
query: { query: {
id: params.id, id: params.id,

View file

@ -1,5 +1,5 @@
import { fetchPersonalFM, PersonalFMApiNames } from '@/api/personalFM' import { fetchPersonalFM, PersonalFMApiNames } from '@/renderer/api/personalFM'
import reactQueryClient from '@/utils/reactQueryClient' import reactQueryClient from '@/renderer/utils/reactQueryClient'
export function fetchPersonalFMWithReactQuery() { export function fetchPersonalFMWithReactQuery() {
return reactQueryClient.fetchQuery( return reactQueryClient.fetchQuery(

View file

@ -1,7 +1,11 @@
import { fetchPlaylist } from '@/api/playlist' import { fetchPlaylist } from '@/renderer/api/playlist'
import { PlaylistApiNames } from '@/api/playlist' import { PlaylistApiNames } from '@/renderer/api/playlist'
import type { FetchPlaylistParams, FetchPlaylistResponse } from '@/api/playlist' import type {
import reactQueryClient from '@/utils/reactQueryClient' FetchPlaylistParams,
FetchPlaylistResponse,
} from '@/renderer/api/playlist'
import reactQueryClient from '@/renderer/utils/reactQueryClient'
import { IpcChannels } from '@/main/IpcChannelsName'
const fetch = (params: FetchPlaylistParams, noCache?: boolean) => { const fetch = (params: FetchPlaylistParams, noCache?: boolean) => {
return fetchPlaylist(params, !!noCache) return fetchPlaylist(params, !!noCache)
@ -18,7 +22,7 @@ export default function usePlaylist(
enabled: !!(params.id && params.id > 0 && !isNaN(Number(params.id))), enabled: !!(params.id && params.id > 0 && !isNaN(Number(params.id))),
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
placeholderData: (): FetchPlaylistResponse | undefined => placeholderData: (): FetchPlaylistResponse | undefined =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'playlist/detail', api: 'playlist/detail',
query: { query: {
id: params.id, id: params.id,

View file

@ -1,10 +1,15 @@
import { TrackApiNames, fetchAudioSource, fetchTracks } from '@/api/track' import {
TrackApiNames,
fetchAudioSource,
fetchTracks,
} from '@/renderer/api/track'
import type { import type {
FetchAudioSourceParams, FetchAudioSourceParams,
FetchTracksParams, FetchTracksParams,
FetchTracksResponse, FetchTracksResponse,
} from '@/api/track' } from '@/renderer/api/track'
import reactQueryClient from '@/utils/reactQueryClient' import reactQueryClient from '@/renderer/utils/reactQueryClient'
import { IpcChannels } from '@/main/IpcChannelsName'
export default function useTracks(params: FetchTracksParams) { export default function useTracks(params: FetchTracksParams) {
return useQuery( return useQuery(
@ -17,7 +22,7 @@ export default function useTracks(params: FetchTracksParams) {
refetchInterval: false, refetchInterval: false,
staleTime: Infinity, staleTime: Infinity,
initialData: (): FetchTracksResponse | undefined => initialData: (): FetchTracksResponse | undefined =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'song/detail', api: 'song/detail',
query: { query: {
ids: params.ids.join(','), ids: params.ids.join(','),

View file

@ -1,5 +1,5 @@
import { TrackApiNames, fetchTracks } from '@/api/track' import { TrackApiNames, fetchTracks } from '@/renderer/api/track'
import type { FetchTracksParams } from '@/api/track' import type { FetchTracksParams } from '@/renderer/api/track'
// 100 tracks each page // 100 tracks each page
const offset = 100 const offset = 100

View file

@ -1,11 +1,12 @@
import { fetchUserAccount, fetchUserAccountResponse } from '@/api/user' import { fetchUserAccount, fetchUserAccountResponse } from '@/renderer/api/user'
import { UserApiNames } from '@/api/user' import { UserApiNames } from '@/renderer/api/user'
import { IpcChannels } from '@/main/IpcChannelsName'
export default function useUser() { export default function useUser() {
return useQuery(UserApiNames.FETCH_USER_ACCOUNT, fetchUserAccount, { return useQuery(UserApiNames.FETCH_USER_ACCOUNT, fetchUserAccount, {
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
placeholderData: (): fetchUserAccountResponse | undefined => placeholderData: (): fetchUserAccountResponse | undefined =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'user/account', api: 'user/account',
}), }),
}) })

View file

@ -1,8 +1,12 @@
import { likeAAlbum } from '@/api/album' import { likeAAlbum } from '@/renderer/api/album'
import type { FetchUserAlbumsParams, FetchUserAlbumsResponse } from '@/api/user' import type {
import { UserApiNames, fetchUserAlbums } from '@/api/user' FetchUserAlbumsParams,
FetchUserAlbumsResponse,
} from '@/renderer/api/user'
import { UserApiNames, fetchUserAlbums } from '@/renderer/api/user'
import { useQueryClient } from 'react-query' import { useQueryClient } from 'react-query'
import useUser from './useUser' import useUser from './useUser'
import { IpcChannels } from '@/main/IpcChannelsName'
export default function useUserAlbums(params: FetchUserAlbumsParams = {}) { export default function useUserAlbums(params: FetchUserAlbumsParams = {}) {
const { data: user } = useUser() const { data: user } = useUser()
@ -12,7 +16,7 @@ export default function useUserAlbums(params: FetchUserAlbumsParams = {}) {
{ {
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
placeholderData: (): FetchUserAlbumsResponse | undefined => placeholderData: (): FetchUserAlbumsResponse | undefined =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'album/sublist', api: 'album/sublist',
query: params, query: params,
}), }),

View file

@ -1,11 +1,12 @@
import type { FetchUserArtistsResponse } from '@/api/user' import type { FetchUserArtistsResponse } from '@/renderer/api/user'
import { UserApiNames, fetchUserArtists } from '@/api/user' import { UserApiNames, fetchUserArtists } from '@/renderer/api/user'
import { IpcChannels } from '@/main/IpcChannelsName'
export default function useUserArtists() { export default function useUserArtists() {
return useQuery([UserApiNames.FETCH_USER_ARTIST], fetchUserArtists, { return useQuery([UserApiNames.FETCH_USER_ARTIST], fetchUserArtists, {
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
placeholderData: (): FetchUserArtistsResponse => placeholderData: (): FetchUserArtistsResponse =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'album/sublist', api: 'album/sublist',
}), }),
}) })

View file

@ -1,8 +1,9 @@
import type { FetchUserLikedTracksIDsResponse } from '@/api/user' import type { FetchUserLikedTracksIDsResponse } from '@/renderer/api/user'
import { UserApiNames, fetchUserLikedTracksIDs } from '@/api/user' import { UserApiNames, fetchUserLikedTracksIDs } from '@/renderer/api/user'
import { likeATrack } from '@/api/track' import { likeATrack } from '@/renderer/api/track'
import useUser from './useUser' import useUser from './useUser'
import { useQueryClient } from 'react-query' import { useQueryClient } from 'react-query'
import { IpcChannels } from '@/main/IpcChannelsName'
export default function useUserLikedTracksIDs() { export default function useUserLikedTracksIDs() {
const { data: user } = useUser() const { data: user } = useUser()
@ -15,7 +16,7 @@ export default function useUserLikedTracksIDs() {
enabled: !!(uid && uid !== 0), enabled: !!(uid && uid !== 0),
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
placeholderData: (): FetchUserLikedTracksIDsResponse | undefined => placeholderData: (): FetchUserLikedTracksIDsResponse | undefined =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'likelist', api: 'likelist',
query: { query: {
uid, uid,

View file

@ -1,8 +1,9 @@
import { likeAPlaylist } from '@/api/playlist' import { likeAPlaylist } from '@/renderer/api/playlist'
import type { FetchUserPlaylistsResponse } from '@/api/user' import type { FetchUserPlaylistsResponse } from '@/renderer/api/user'
import { UserApiNames, fetchUserPlaylists } from '@/api/user' import { UserApiNames, fetchUserPlaylists } from '@/renderer/api/user'
import { useQueryClient } from 'react-query' import { useQueryClient } from 'react-query'
import useUser from './useUser' import useUser from './useUser'
import { IpcChannels } from '@/main/IpcChannelsName'
export default function useUserPlaylists() { export default function useUserPlaylists() {
const { data: user } = useUser() const { data: user } = useUser()
@ -31,7 +32,7 @@ export default function useUserPlaylists() {
), ),
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
placeholderData: (): FetchUserPlaylistsResponse => placeholderData: (): FetchUserPlaylistsResponse =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'user/playlist', api: 'user/playlist',
query: { query: {
uid: params.uid, uid: params.uid,

View file

@ -4,7 +4,7 @@ import { BrowserRouter } from 'react-router-dom'
import * as Sentry from '@sentry/react' import * as Sentry from '@sentry/react'
import { BrowserTracing } from '@sentry/tracing' import { BrowserTracing } from '@sentry/tracing'
import 'virtual:svg-icons-register' import 'virtual:svg-icons-register'
import '@/styles/global.scss' import './styles/global.scss'
import App from './App' import App from './App'
import pkg from '../../package.json' import pkg from '../../package.json'

View file

@ -1,23 +1,25 @@
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import Button, { Color as ButtonColor } from '@/components/Button' import Button, { Color as ButtonColor } from '@/renderer/components/Button'
import CoverRow, { Subtitle } from '@/components/CoverRow' import CoverRow, { Subtitle } from '@/renderer/components/CoverRow'
import Skeleton from '@/components/Skeleton' import Skeleton from '@/renderer/components/Skeleton'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from '@/renderer/components/SvgIcon'
import TracksAlbum from '@/components/TracksAlbum' import TracksAlbum from '@/renderer/components/TracksAlbum'
import useAlbum from '@/hooks/useAlbum' import useAlbum from '@/renderer/hooks/useAlbum'
import useArtistAlbums from '@/hooks/useArtistAlbums' import useArtistAlbums from '@/renderer/hooks/useArtistAlbums'
import { player } from '@/store' import { player } from '@/renderer/store'
import { State as PlayerState } from '@/utils/player' import { State as PlayerState } from '@/renderer/utils/player'
import { import {
formatDate, formatDate,
formatDuration, formatDuration,
resizeImage, resizeImage,
scrollToTop, scrollToTop,
} from '@/utils/common' } from '@/renderer/utils/common'
import useTracks from '@/hooks/useTracks' import useTracks from '@/renderer/hooks/useTracks'
import useUserAlbums, { useMutationLikeAAlbum } from '@/hooks/useUserAlbums' import useUserAlbums, {
import useUser from '@/hooks/useUser' useMutationLikeAAlbum,
} from '@/renderer/hooks/useUserAlbums'
import useUser from '@/renderer/hooks/useUser'
const PlayButton = ({ const PlayButton = ({
album, album,

View file

@ -1,15 +1,15 @@
import Button, { Color as ButtonColor } from '@/components/Button' import Button, { Color as ButtonColor } from '@/renderer/components/Button'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from '@/renderer/components/SvgIcon'
import Cover from '@/components/Cover' import Cover from '@/renderer/components/Cover'
import useArtist from '@/hooks/useArtist' import useArtist from '@/renderer/hooks/useArtist'
import useArtistAlbums from '@/hooks/useArtistAlbums' import useArtistAlbums from '@/renderer/hooks/useArtistAlbums'
import { resizeImage } from '@/utils/common' import { resizeImage } from '@/renderer/utils/common'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import TracksGrid from '@/components/TracksGrid' import TracksGrid from '@/renderer/components/TracksGrid'
import CoverRow, { Subtitle } from '@/components/CoverRow' import CoverRow, { Subtitle } from '@/renderer/components/CoverRow'
import Skeleton from '@/components/Skeleton' import Skeleton from '@/renderer/components/Skeleton'
import useTracks from '@/hooks/useTracks' import useTracks from '@/renderer/hooks/useTracks'
import { player } from '@/store' import { player } from '@/renderer/store'
const Header = ({ artist }: { artist: Artist | undefined }) => { const Header = ({ artist }: { artist: Artist | undefined }) => {
const coverImage = resizeImage(artist?.img1v1Url || '', 'md') const coverImage = resizeImage(artist?.img1v1Url || '', 'md')

View file

@ -2,10 +2,11 @@ import {
PlaylistApiNames, PlaylistApiNames,
fetchRecommendedPlaylists, fetchRecommendedPlaylists,
fetchDailyRecommendPlaylists, fetchDailyRecommendPlaylists,
} from '@/api/playlist' } from '@/renderer/api/playlist'
import CoverRow from '@/components/CoverRow' import CoverRow from '@/renderer/components/CoverRow'
import DailyTracksCard from '@/components/DailyTracksCard' import DailyTracksCard from '@/renderer/components/DailyTracksCard'
import FMCard from '@/components/FMCard' import FMCard from '@/renderer/components/FMCard'
import { IpcChannels } from '@/main/IpcChannelsName'
export default function Home() { export default function Home() {
const { const {
@ -17,7 +18,7 @@ export default function Home() {
{ {
retry: false, retry: false,
placeholderData: () => placeholderData: () =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'recommend/resource', api: 'recommend/resource',
}), }),
} }
@ -33,7 +34,7 @@ export default function Home() {
}, },
{ {
placeholderData: () => placeholderData: () =>
window.ipcRenderer?.sendSync('getApiCacheSync', { window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
api: 'personalized', api: 'personalized',
}), }),
} }

View file

@ -1,14 +1,14 @@
import CoverRow, { Subtitle } from '@/components/CoverRow' import CoverRow, { Subtitle } from '@/renderer/components/CoverRow'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from '@/renderer/components/SvgIcon'
import useUserAlbums from '@/hooks/useUserAlbums' import useUserAlbums from '@/renderer/hooks/useUserAlbums'
import useLyric from '@/hooks/useLyric' import useLyric from '@/renderer/hooks/useLyric'
import usePlaylist from '@/hooks/usePlaylist' import usePlaylist from '@/renderer/hooks/usePlaylist'
import useUser from '@/hooks/useUser' import useUser from '@/renderer/hooks/useUser'
import useUserPlaylists from '@/hooks/useUserPlaylists' import useUserPlaylists from '@/renderer/hooks/useUserPlaylists'
import { player } from '@/store' import { player } from '@/renderer/store'
import { resizeImage } from '@/utils/common' import { resizeImage } from '@/renderer/utils/common'
import { sample, chunk } from 'lodash-es' import { sample, chunk } from 'lodash-es'
import useUserArtists from '@/hooks/useUserArtists' import useUserArtists from '@/renderer/hooks/useUserArtists'
const LikedTracksCard = ({ className }: { className?: string }) => { const LikedTracksCard = ({ className }: { className?: string }) => {
const navigate = useNavigate() const navigate = useNavigate()

View file

@ -5,10 +5,10 @@ import {
fetchLoginQrCodeKey, fetchLoginQrCodeKey,
loginWithEmail, loginWithEmail,
loginWithPhone, loginWithPhone,
} from '@/api/auth' } from '@/renderer/api/auth'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from '@/renderer/components/SvgIcon'
import { state } from '@/store' import { state } from '@/renderer/store'
import { setCookies } from '@/utils/cookie' import { setCookies } from '@/renderer/utils/cookie'
import { useInterval } from 'react-use' import { useInterval } from 'react-use'
enum Method { enum Method {

View file

@ -1,17 +1,17 @@
import { memo } from 'react' import { memo } from 'react'
import Button, { Color as ButtonColor } from '@/components/Button' import Button, { Color as ButtonColor } from '@/renderer/components/Button'
import Skeleton from '@/components/Skeleton' import Skeleton from '@/renderer/components/Skeleton'
import SvgIcon from '@/components/SvgIcon' import SvgIcon from '@/renderer/components/SvgIcon'
import TracksList from '@/components/TracksList' import TracksList from '@/renderer/components/TracksList'
import usePlaylist from '@/hooks/usePlaylist' import usePlaylist from '@/renderer/hooks/usePlaylist'
import useScroll from '@/hooks/useScroll' import useScroll from '@/renderer/hooks/useScroll'
import useTracksInfinite from '@/hooks/useTracksInfinite' import useTracksInfinite from '@/renderer/hooks/useTracksInfinite'
import { player } from '@/store' import { player } from '@/renderer/store'
import { formatDate, resizeImage } from '@/utils/common' import { formatDate, resizeImage } from '@/renderer/utils/common'
import useUserPlaylists, { import useUserPlaylists, {
useMutationLikeAPlaylist, useMutationLikeAPlaylist,
} from '@/hooks/useUserPlaylists' } from '@/renderer/hooks/useUserPlaylists'
import useUser from '@/hooks/useUser' import useUser from '@/renderer/hooks/useUser'
const enableRenderLog = true const enableRenderLog = true

View file

@ -3,11 +3,11 @@ import {
search, search,
SearchApiNames, SearchApiNames,
SearchTypes, SearchTypes,
} from '@/api/search' } from '@/renderer/api/search'
import Cover from '@/components/Cover' import Cover from '@/renderer/components/Cover'
import TrackGrid from '@/components/TracksGrid' import TrackGrid from '@/renderer/components/TracksGrid'
import { player } from '@/store' import { player } from '@/renderer/store'
import { resizeImage } from '@/utils/common' import { resizeImage } from '@/renderer/utils/common'
const Artists = ({ artists }: { artists: Artist[] }) => { const Artists = ({ artists }: { artists: Artist[] }) => {
const navigate = useNavigate() const navigate = useNavigate()

View file

@ -1,6 +1,6 @@
import { proxy, subscribe } from 'valtio' import { proxy, subscribe } from 'valtio'
import { devtools } from 'valtio/utils' import { devtools } from 'valtio/utils'
import { Player } from '@/utils/player' import { Player } from '@/renderer/utils/player'
interface Store { interface Store {
uiStates: { uiStates: {

View file

@ -54,38 +54,38 @@
@font-face { @font-face {
font-family: Barlow; font-family: Barlow;
font-weight: normal; font-weight: normal;
src: url('@/assets/fonts/Barlow-Regular.woff2') format('woff2'), src: url('@/renderer/assets/fonts/Barlow-Regular.woff2') format('woff2'),
url('@/assets/fonts/Barlow-Regular.ttf') format('truetype'); url('@/renderer/assets/fonts/Barlow-Regular.ttf') format('truetype');
} }
@font-face { @font-face {
font-family: Barlow; font-family: Barlow;
font-weight: medium; font-weight: medium;
src: url('@/assets/fonts/Barlow-Medium.woff2') format('woff2'), src: url('@/renderer/assets/fonts/Barlow-Medium.woff2') format('woff2'),
url('@/assets/fonts/Barlow-Medium.ttf') format('truetype'); url('@/renderer/assets/fonts/Barlow-Medium.ttf') format('truetype');
} }
@font-face { @font-face {
font-family: Barlow; font-family: Barlow;
font-weight: 600; font-weight: 600;
src: url('@/assets/fonts/Barlow-SemiBold.woff2') format('woff2'), src: url('@/renderer/assets/fonts/Barlow-SemiBold.woff2') format('woff2'),
url('@/assets/fonts/Barlow-SemiBold.ttf') format('truetype'); url('@/renderer/assets/fonts/Barlow-SemiBold.ttf') format('truetype');
} }
@font-face { @font-face {
font-family: Barlow; font-family: Barlow;
font-weight: bold; font-weight: bold;
src: url('@/assets/fonts/Barlow-Bold.woff2') format('woff2'), src: url('@/renderer/assets/fonts/Barlow-Bold.woff2') format('woff2'),
url('@/assets/fonts/Barlow-Bold.ttf') format('truetype'); url('@/renderer/assets/fonts/Barlow-Bold.ttf') format('truetype');
} }
@font-face { @font-face {
font-family: Barlow; font-family: Barlow;
font-weight: 800; font-weight: 800;
src: url('@/assets/fonts/Barlow-ExtraBold.woff2') format('woff2'), src: url('@/renderer/assets/fonts/Barlow-ExtraBold.woff2') format('woff2'),
url('@/assets/fonts/Barlow-ExtraBold.ttf') format('truetype'); url('@/renderer/assets/fonts/Barlow-ExtraBold.ttf') format('truetype');
} }
@font-face { @font-face {
font-family: Barlow; font-family: Barlow;
font-weight: 900; font-weight: 900;
src: url('@/assets/fonts/Barlow-Black.woff2') format('woff2'), src: url('@/renderer/assets/fonts/Barlow-Black.woff2') format('woff2'),
url('@/assets/fonts/Barlow-Black.ttf') format('truetype'); url('@/renderer/assets/fonts/Barlow-Black.ttf') format('truetype');
} }
body, body,

View file

@ -17,7 +17,7 @@
"jsx": "react-jsx", "jsx": "react-jsx",
"baseUrl": "./", "baseUrl": "./",
"paths": { "paths": {
"@/*": ["*"] "@/*": ["../*"]
} }
}, },
"include": ["./**/*.ts", "./**/*.tsx"] "include": ["./**/*.ts", "./**/*.tsx"]

View file

@ -1,4 +1,4 @@
import { FetchLyricResponse } from '@/api/track' import { FetchLyricResponse } from '@/renderer/api/track'
export function lyricParser(lrc: FetchLyricResponse) { export function lyricParser(lrc: FetchLyricResponse) {
return { return {
@ -58,7 +58,7 @@ function parseLyric(lrc: string): ParsedLyric[] {
if ( if (
content.match( content.match(
/((\s|\S)*)(作曲|作词|编曲|制作|Producers|Producer|Produced|贝斯|工程师|吉他|合成器|助理|编程|制作|和声|母带|人声|鼓|混音|中提琴|编写|Talkbox|钢琴|出版|录音|发行|出品)((\s|\S)*)(:|)/ /((\s|\S)*)(作曲|作词|编曲|制作|Producers|Producer|Produced|贝斯|工程师|吉他|合成器|助理|编程|制作|和声|母带|人声|鼓|混音|中提琴|编写|Talkbox|钢琴|出版|录音|发行|出品|键盘|弦乐|设计|监制|原曲|演唱|声明|版权|封面|插画|统筹|企划|填词|原唱|后期|和音|琵琶)((\s|\S)*)(:|)/
) )
) { ) {
continue continue

View file

@ -2,15 +2,15 @@ import { Howl, Howler } from 'howler'
import { import {
fetchAudioSourceWithReactQuery, fetchAudioSourceWithReactQuery,
fetchTracksWithReactQuery, fetchTracksWithReactQuery,
} from '@/hooks/useTracks' } from '@/renderer/hooks/useTracks'
import { fetchPersonalFMWithReactQuery } from '@/hooks/usePersonalFM' import { fetchPersonalFMWithReactQuery } from '@/renderer/hooks/usePersonalFM'
import { fmTrash } from '@/api/personalFM' import { fmTrash } from '@/renderer/api/personalFM'
import { cacheAudio } from '@/api/yesplaymusic' import { cacheAudio } from '@/renderer/api/yesplaymusic'
import { clamp } from 'lodash-es' import { clamp } from 'lodash-es'
import axios from 'axios' import axios from 'axios'
import { resizeImage } from './common' import { resizeImage } from './common'
import { fetchPlaylistWithReactQuery } from '@/hooks/usePlaylist' import { fetchPlaylistWithReactQuery } from '@/renderer/hooks/usePlaylist'
import { fetchAlbumWithReactQuery } from '@/hooks/useAlbum' import { fetchAlbumWithReactQuery } from '@/renderer/hooks/useAlbum'
type TrackID = number type TrackID = number
enum TrackListSourceType { enum TrackListSourceType {

View file

@ -12,7 +12,7 @@
"jsx": "react-jsx", "jsx": "react-jsx",
"baseUrl": "./", "baseUrl": "./",
"paths": { "paths": {
"@/*": ["src/renderer/*"] "@/*": ["src/*"]
} }
}, },
"exclude": ["node_modules", "./dist"] "exclude": ["node_modules", "./dist"]

View file

@ -36,7 +36,7 @@ export default defineConfig({
{ 'react-query': ['useQuery', 'useMutation', 'useInfiniteQuery'] }, { 'react-query': ['useQuery', 'useMutation', 'useInfiniteQuery'] },
{ 'react-router-dom': ['useNavigate', 'useParams'] }, { 'react-router-dom': ['useNavigate', 'useParams'] },
{ 'react-hot-toast': ['toast'] }, { 'react-hot-toast': ['toast'] },
{ 'react-use': ['useEffectOnce']}, { 'react-use': ['useEffectOnce'] },
{ valtio: ['useSnapshot'] }, { valtio: ['useSnapshot'] },
], ],
}), }),
@ -60,7 +60,7 @@ export default defineConfig({
}, },
resolve: { resolve: {
alias: { alias: {
'@': join(__dirname, './src/renderer'), '@': join(__dirname, './src'),
}, },
}, },
clearScreen: false, clearScreen: false,