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",
"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",

View file

@ -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()

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 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
})

View file

@ -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')

View file

@ -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!')
})
})
})
}

View file

@ -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', {

View file

@ -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 (

View file

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

View file

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

View file

@ -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 {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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',

View file

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

View file

@ -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 =

View file

@ -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]

View file

@ -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

View file

@ -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'

View file

@ -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)

View file

@ -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 (

View file

@ -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()

View file

@ -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[] = [
{

View file

@ -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

View file

@ -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 (

View file

@ -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()

View file

@ -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

View file

@ -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 = ({

View file

@ -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(
({

View file

@ -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

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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(

View file

@ -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,

View file

@ -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(','),

View file

@ -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

View file

@ -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',
}),
})

View file

@ -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,
}),

View file

@ -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',
}),
})

View file

@ -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,

View file

@ -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,

View file

@ -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'

View file

@ -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,

View file

@ -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')

View file

@ -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',
}),
}

View file

@ -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()

View file

@ -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 {

View file

@ -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

View file

@ -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()

View file

@ -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: {

View file

@ -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,

View file

@ -17,7 +17,7 @@
"jsx": "react-jsx",
"baseUrl": "./",
"paths": {
"@/*": ["*"]
"@/*": ["../*"]
}
},
"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) {
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

View file

@ -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 {

View file

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

View file

@ -60,7 +60,7 @@ export default defineConfig({
},
resolve: {
alias: {
'@': join(__dirname, './src/renderer'),
'@': join(__dirname, './src'),
},
},
clearScreen: false,