diff --git a/package.json b/package.json
index 5bfdbdd..43fc654 100644
--- a/package.json
+++ b/package.json
@@ -14,8 +14,9 @@
"packageManager": "pnpm@7.0.0",
"scripts": {
"install": "turbo run post-install --parallel --no-cache",
- "build": "ross-env-shell IS_ELECTRON=yes turbo run build",
+ "build": "cross-env-shell IS_ELECTRON=yes turbo run build",
"build:web": "turbo run build:web",
+ "pack": "turbo run build pack",
"dev": "cross-env-shell IS_ELECTRON=yes turbo run dev --parallel",
"lint": "turbo run lint",
"format": "prettier --write \"**/*.{ts,tsx,js,jsx,md}\"",
@@ -24,9 +25,9 @@
},
"devDependencies": {
"cross-env": "^7.0.3",
- "eslint": "^8.16.0",
+ "eslint": "^8.17.0",
"prettier": "^2.6.2",
- "turbo": "^1.2.14",
- "typescript": "^4.7.2"
+ "turbo": "^1.2.16",
+ "typescript": "^4.7.3"
}
}
diff --git a/packages/electron/.electron-builder.config.js b/packages/electron/.electron-builder.config.js
index 8f935e9..d86f4ff 100644
--- a/packages/electron/.electron-builder.config.js
+++ b/packages/electron/.electron-builder.config.js
@@ -6,15 +6,15 @@
module.exports = {
appId: 'com.qier222.yesplaymusic',
productName: 'YesPlayMusic',
- copyright: 'Copyright © 2022 ${author}',
- asar: true,
+ copyright: 'Copyright © 2022 qier222',
+ asar: false,
directories: {
output: 'release',
buildResources: 'build',
},
npmRebuild: false,
buildDependenciesFromSource: true,
- files: ['./dist'],
+ electronVersion: '19.0.3',
publish: [
{
provider: 'github',
@@ -98,16 +98,8 @@ module.exports = {
icon: './build/icon.icns',
},
files: [
- 'dist/main/**/*',
- 'dist/renderer/**/*',
- {
- from: 'packages/electron/migrations',
- to: 'dist/main/migrations',
- },
- {
- from: 'src/main/assets',
- to: 'dist/main/assets',
- },
+ '!**/*.ts',
+ '!**/node_modules/better-sqlite3/{bin,build,deps}/**',
'!**/node_modules/*/{*.MD,*.md,README,readme}',
'!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}',
'!**/node_modules/*.d.ts',
@@ -120,5 +112,24 @@ module.exports = {
'!**/{appveyor.yml,.travis.yml,circle.yml}',
'!**/{npm-debug.log,yarn.lock,.yarn-integrity,.yarn-metadata.json,pnpm-lock.yaml}',
'!**/*.{map,debug.min.js}',
+
+ '!**/dist/binary',
+ {
+ from: './dist',
+ to: './main',
+ },
+ {
+ from: '../web/dist',
+ to: './web',
+ },
+ {
+ from: './migrations',
+ to: 'main/migrations',
+ },
+ {
+ from: './assets',
+ to: 'main/assets',
+ },
+ './main',
],
}
diff --git a/build/icons/1024x1024.png b/packages/electron/build/icons/1024x1024.png
similarity index 100%
rename from build/icons/1024x1024.png
rename to packages/electron/build/icons/1024x1024.png
diff --git a/build/icons/128x128.png b/packages/electron/build/icons/128x128.png
similarity index 100%
rename from build/icons/128x128.png
rename to packages/electron/build/icons/128x128.png
diff --git a/build/icons/16x16.png b/packages/electron/build/icons/16x16.png
similarity index 100%
rename from build/icons/16x16.png
rename to packages/electron/build/icons/16x16.png
diff --git a/build/icons/24x24.png b/packages/electron/build/icons/24x24.png
similarity index 100%
rename from build/icons/24x24.png
rename to packages/electron/build/icons/24x24.png
diff --git a/build/icons/256x256.png b/packages/electron/build/icons/256x256.png
similarity index 100%
rename from build/icons/256x256.png
rename to packages/electron/build/icons/256x256.png
diff --git a/build/icons/32x32.png b/packages/electron/build/icons/32x32.png
similarity index 100%
rename from build/icons/32x32.png
rename to packages/electron/build/icons/32x32.png
diff --git a/build/icons/48x48.png b/packages/electron/build/icons/48x48.png
similarity index 100%
rename from build/icons/48x48.png
rename to packages/electron/build/icons/48x48.png
diff --git a/build/icons/512x512.png b/packages/electron/build/icons/512x512.png
similarity index 100%
rename from build/icons/512x512.png
rename to packages/electron/build/icons/512x512.png
diff --git a/build/icons/64x64.png b/packages/electron/build/icons/64x64.png
similarity index 100%
rename from build/icons/64x64.png
rename to packages/electron/build/icons/64x64.png
diff --git a/build/icons/icon.icns b/packages/electron/build/icons/icon.icns
similarity index 100%
rename from build/icons/icon.icns
rename to packages/electron/build/icons/icon.icns
diff --git a/build/icons/icon.ico b/packages/electron/build/icons/icon.ico
similarity index 100%
rename from build/icons/icon.ico
rename to packages/electron/build/icons/icon.ico
diff --git a/build/icons/icon.png b/packages/electron/build/icons/icon.png
similarity index 100%
rename from build/icons/icon.png
rename to packages/electron/build/icons/icon.png
diff --git a/build/icons/menu@88.png b/packages/electron/build/icons/menu@88.png
similarity index 100%
rename from build/icons/menu@88.png
rename to packages/electron/build/icons/menu@88.png
diff --git a/packages/electron/package.json b/packages/electron/package.json
index 59d83ec..65e6b51 100644
--- a/packages/electron/package.json
+++ b/packages/electron/package.json
@@ -2,11 +2,13 @@
"name": "electron",
"private": true,
"version": "2.0.0",
- "main": "./index.js",
+ "main": "./main/index.js",
+ "author": "*",
"scripts": {
"post-install": "node scripts/build.sqlite3.js",
"dev": "node scripts/build.main.mjs --watch",
"build": "node scripts/build.main.mjs",
+ "pack": "electron-builder build -c .electron-builder.config.js",
"test:types": "tsc --noEmit --project src/main/tsconfig.json",
"lint": "eslint --ext .ts,.js ./",
"format": "prettier --write './**/*.{ts,js,tsx,jsx}'"
@@ -18,7 +20,7 @@
"@sentry/node": "^6.19.7",
"@sentry/tracing": "^6.19.7",
"@unblockneteasemusic/rust-napi": "^0.3.0",
- "NeteaseCloudMusicApi": "^4.6.0",
+ "NeteaseCloudMusicApi": "^4.6.2",
"better-sqlite3": "7.5.1",
"change-case": "^4.1.2",
"compare-versions": "^4.1.3",
@@ -26,7 +28,7 @@
"electron-log": "^4.4.6",
"electron-store": "^8.0.1",
"express": "^4.18.1",
- "fast-folder-size": "^1.6.1",
+ "fast-folder-size": "^1.7.0",
"pretty-bytes": "^6.0.0"
},
"devDependencies": {
@@ -35,18 +37,18 @@
"@types/cookie-parser": "^1.4.3",
"@types/express": "^4.17.13",
"@types/express-fileupload": "^1.2.2",
- "@typescript-eslint/eslint-plugin": "^5.26.0",
- "@typescript-eslint/parser": "^5.26.0",
+ "@typescript-eslint/eslint-plugin": "^5.27.0",
+ "@typescript-eslint/parser": "^5.27.0",
"@vitejs/plugin-react": "^1.3.1",
"axios": "^0.27.2",
"cross-env": "^7.0.3",
"dotenv": "^16.0.0",
- "electron": "^19.0.1",
+ "electron": "^19.0.3",
"electron-builder": "^23.0.3",
"electron-devtools-installer": "^3.2.0",
"electron-rebuild": "^3.2.7",
- "electron-releases": "^3.1021.0",
- "esbuild": "^0.14.41",
+ "electron-releases": "^3.1026.0",
+ "esbuild": "^0.14.42",
"eslint": "*",
"express-fileupload": "^1.4.0",
"minimist": "^1.2.6",
@@ -59,6 +61,6 @@
"wait-on": "^6.0.1"
},
"resolutions": {
- "@electron/universal": "1.2.1"
+ "@electron/universal": "1.3.0"
}
}
diff --git a/packages/shared/api/User.ts b/packages/shared/api/User.ts
index 7b8316b..ef996e0 100644
--- a/packages/shared/api/User.ts
+++ b/packages/shared/api/User.ts
@@ -4,6 +4,7 @@ export enum UserApiNames {
FetchUserPlaylists = 'fetchUserPlaylists',
FetchUserAlbums = 'fetchUserAlbums',
FetchUserArtist = 'fetchUserArtists',
+ FetchListenedRecords = 'fetchListenedRecords',
}
// 获取账号详情
diff --git a/packages/web/AppNew.tsx b/packages/web/AppNew.tsx
index b3f22f5..fe118aa 100644
--- a/packages/web/AppNew.tsx
+++ b/packages/web/AppNew.tsx
@@ -3,16 +3,19 @@ import TitleBar from '@/web/components/TitleBar'
import IpcRendererReact from '@/web/IpcRendererReact'
import Layout from '@/web/components/New/Layout'
import Devtool from '@/web/components/New/Devtool'
+import ErrorBoundary from '@/web/components/New/ErrorBoundary'
const App = () => {
return (
-
- {window.env?.isEnableTitlebar && }
-
-
-
-
-
+
+
+ {window.env?.isEnableTitlebar && }
+
+
+
+
+
+
)
}
diff --git a/packages/web/api/hooks/useAlbum.ts b/packages/web/api/hooks/useAlbum.ts
index 0cc0a3d..cfddf59 100644
--- a/packages/web/api/hooks/useAlbum.ts
+++ b/packages/web/api/hooks/useAlbum.ts
@@ -17,6 +17,12 @@ const fetch = async (params: FetchAlbumParams, noCache?: boolean) => {
return album
}
+const fetchFromCache = (id: number): FetchAlbumResponse =>
+ window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
+ api: APIs.Album,
+ query: { id },
+ })
+
export default function useAlbum(params: FetchAlbumParams, noCache?: boolean) {
return useQuery(
[AlbumApiNames.FetchAlbum, params.id],
@@ -24,13 +30,7 @@ export default function useAlbum(params: FetchAlbumParams, noCache?: boolean) {
{
enabled: !!params.id,
staleTime: 24 * 60 * 60 * 1000, // 24 hours
- placeholderData: (): FetchAlbumResponse =>
- window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
- api: APIs.Album,
- query: {
- id: params.id,
- },
- }),
+ placeholderData: () => fetchFromCache(params.id),
}
)
}
@@ -46,6 +46,7 @@ export function fetchAlbumWithReactQuery(params: FetchAlbumParams) {
}
export async function prefetchAlbum(params: FetchAlbumParams) {
+ if (fetchFromCache(params.id)) return
await reactQueryClient.prefetchQuery(
[AlbumApiNames.FetchAlbum, params.id],
() => fetch(params),
diff --git a/packages/web/api/hooks/useArtists.ts b/packages/web/api/hooks/useArtists.ts
new file mode 100644
index 0000000..d66268c
--- /dev/null
+++ b/packages/web/api/hooks/useArtists.ts
@@ -0,0 +1,27 @@
+import { fetchArtist } from '@/web/api/artist'
+import { IpcChannels } from '@/shared/IpcChannels'
+import { APIs } from '@/shared/CacheAPIs'
+import {
+ FetchArtistParams,
+ ArtistApiNames,
+ FetchArtistResponse,
+} from '@/shared/api/Artist'
+import { useQuery } from 'react-query'
+
+export default function useArtists(ids: number[]) {
+ return useQuery(
+ ['fetchArtists', ids],
+ () => Promise.all(ids.map(id => fetchArtist({ id }, false))),
+ {
+ enabled: !!ids && ids.length > 0,
+ staleTime: 5 * 60 * 1000, // 5 mins
+ // placeholderData: (): FetchArtistResponse[] =>
+ // window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
+ // api: APIs.Artist,
+ // query: {
+ // ids,
+ // },
+ // }),
+ }
+ )
+}
diff --git a/packages/web/api/hooks/usePlaylist.ts b/packages/web/api/hooks/usePlaylist.ts
index 96ce4fa..91cf025 100644
--- a/packages/web/api/hooks/usePlaylist.ts
+++ b/packages/web/api/hooks/usePlaylist.ts
@@ -13,6 +13,12 @@ const fetch = (params: FetchPlaylistParams, noCache?: boolean) => {
return fetchPlaylist(params, !!noCache)
}
+export const fetchFromCache = (id: number): FetchPlaylistResponse | undefined =>
+ window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
+ api: APIs.Playlist,
+ query: { id },
+ })
+
export default function usePlaylist(
params: FetchPlaylistParams,
noCache?: boolean
@@ -23,13 +29,7 @@ export default function usePlaylist(
{
enabled: !!(params.id && params.id > 0 && !isNaN(Number(params.id))),
refetchOnWindowFocus: true,
- placeholderData: (): FetchPlaylistResponse | undefined =>
- window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
- api: APIs.Playlist,
- query: {
- id: params.id,
- },
- }),
+ placeholderData: () => fetchFromCache(params.id),
}
)
}
@@ -45,6 +45,7 @@ export function fetchPlaylistWithReactQuery(params: FetchPlaylistParams) {
}
export async function prefetchPlaylist(params: FetchPlaylistParams) {
+ if (fetchFromCache(params.id)) return
await reactQueryClient.prefetchQuery(
[PlaylistApiNames.FetchPlaylist, params],
() => fetch(params),
diff --git a/packages/web/api/hooks/useUserListenedRecords.ts b/packages/web/api/hooks/useUserListenedRecords.ts
new file mode 100644
index 0000000..d2a93eb
--- /dev/null
+++ b/packages/web/api/hooks/useUserListenedRecords.ts
@@ -0,0 +1,33 @@
+import {
+ fetchListenedRecords,
+ FetchListenedRecordsParams,
+} from '@/web/api/user'
+import { UserApiNames } from '@/shared/api/User'
+import { APIs } from '@/shared/CacheAPIs'
+import { IpcChannels } from '@/shared/IpcChannels'
+import { useQuery } from 'react-query'
+import useUser from './useUser'
+
+export default function useUserListenedRecords(params: {
+ type: 'week' | 'all'
+}) {
+ const { data: user } = useUser()
+ const uid = user?.account?.id || 0
+
+ return useQuery(
+ [UserApiNames.FetchListenedRecords],
+ () =>
+ fetchListenedRecords({
+ uid,
+ type: params.type === 'week' ? 1 : 0,
+ }),
+ {
+ refetchOnWindowFocus: false,
+ enabled: !!uid,
+ // placeholderData: (): FetchUserArtistsResponse =>
+ // window.ipcRenderer?.sendSync(IpcChannels.GetApiCacheSync, {
+ // api: APIs.UserArtists,
+ // }),
+ }
+ )
+}
diff --git a/packages/web/api/user.ts b/packages/web/api/user.ts
index 6c74658..6092bd6 100644
--- a/packages/web/api/user.ts
+++ b/packages/web/api/user.ts
@@ -62,6 +62,47 @@ export function fetchUserLikedTracksIDs(
})
}
+// 听歌打卡
+export function scrobble(params: {
+ id: number // track id
+ sourceid: number // 歌单或专辑id
+ time?: number // 已听秒数
+}): Promise {
+ return request({
+ url: '/scrobble',
+ method: 'post',
+ params: {
+ ...params,
+ timestamp: new Date().getTime(),
+ },
+ })
+}
+
+export interface FetchListenedRecordsParams {
+ uid: number // 用户id
+ type: number // type=1 时只返回 weekData, type=0 时返回 allData
+}
+export interface FetchListenedRecordsResponse {
+ code: number
+ weekData: {
+ playCount: number
+ score: number
+ song: Track
+ }[]
+}
+export function fetchListenedRecords(
+ params: FetchListenedRecordsParams
+): Promise {
+ return request({
+ url: '/user/record',
+ method: 'get',
+ params: {
+ ...params,
+ timestamp: new Date().getTime(),
+ },
+ })
+}
+
/**
* 每日签到
* 说明 : 调用此接口可签到获取积分
diff --git a/packages/web/assets/icons/heart.svg b/packages/web/assets/icons/heart.svg
index 50426fd..ac6c718 100644
--- a/packages/web/assets/icons/heart.svg
+++ b/packages/web/assets/icons/heart.svg
@@ -1,3 +1,3 @@
-