Compare commits
57 Commits
v2.0.0-bet
...
v2.0.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad2422d826 | ||
|
|
6b9ba74c35 | ||
|
|
22e2653e20 | ||
|
|
4cac54c84a | ||
|
|
e5f9ecd7b5 | ||
|
|
d64cfb40ec | ||
|
|
53c30caf00 | ||
|
|
6fcce91b2b | ||
|
|
5a53dfcdf7 | ||
|
|
bbe71bd62d | ||
|
|
ecedf0b7b9 | ||
|
|
f2935f3c1c | ||
|
|
d3e677d494 | ||
|
|
e49f90b0da | ||
|
|
0359b0e470 | ||
|
|
aa2373695b | ||
|
|
cf940ff405 | ||
|
|
e7c17cf531 | ||
|
|
c6a1ca4f42 | ||
|
|
8f5008df69 | ||
|
|
428ce4be86 | ||
|
|
d46c4c4285 | ||
|
|
0b871175b2 | ||
|
|
c34c4fd880 | ||
|
|
ff00f0c283 | ||
|
|
847c2e5810 | ||
|
|
e62c81bb33 | ||
|
|
984fdb3459 | ||
|
|
019b78bf38 | ||
|
|
cf88c7669f | ||
|
|
f4383ba848 | ||
|
|
adbda459ba | ||
|
|
984d747179 | ||
|
|
c012f84064 | ||
|
|
a57a18b9f5 | ||
|
|
309c323a14 | ||
|
|
6a1e606d6d | ||
|
|
af3931847e | ||
|
|
41eadb5843 | ||
|
|
8963d719d9 | ||
|
|
0a7761ffff | ||
|
|
1a63771f2d | ||
|
|
1f9141ba33 | ||
|
|
a341a69d48 | ||
|
|
0cedfe0af3 | ||
|
|
59f492ed8f | ||
|
|
8f416ff841 | ||
|
|
99ab194e4b | ||
|
|
43fb9b48dc | ||
|
|
c61e54d6a3 | ||
|
|
c8d195053f | ||
|
|
8cfe5d0481 | ||
|
|
fcc2f5015f | ||
|
|
9b98a45264 | ||
|
|
3c4e836fb8 | ||
|
|
a8111b9d3f | ||
|
|
8eaeffeda3 |
@@ -1,9 +1,18 @@
|
||||
# 根配置文件
|
||||
## 编辑器在查找配置时会停止查找更高层次的配置文件
|
||||
root = true
|
||||
|
||||
# 通配符,匹配所有文件
|
||||
[*]
|
||||
# 设置字符集为 UTF-8,确保文件中的文本使用 UTF-8 编码
|
||||
charset = utf-8
|
||||
# 使用空格作为缩进风格
|
||||
indent_style = space
|
||||
# 设置每个缩进级别的空格数量为 2
|
||||
indent_size = 2
|
||||
# 设置行尾换行符为LF(Line Feed)
|
||||
end_of_line = lf
|
||||
# 在文件的末尾插入一个新行
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
# 删除每一行末尾的尾随空格
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
@@ -2,3 +2,5 @@ node_modules
|
||||
dist
|
||||
out
|
||||
.gitignore
|
||||
auto-imports.d.ts
|
||||
components.d.ts
|
||||
|
||||
@@ -49,7 +49,8 @@ module.exports = {
|
||||
$notification: true,
|
||||
$changeThemeColor: true,
|
||||
$canNotConnect: true,
|
||||
$refreshCloudList: true,
|
||||
$refreshCloudCatch: true,
|
||||
$cleanAll: true,
|
||||
$player: true,
|
||||
},
|
||||
};
|
||||
|
||||
17
.github/ISSUE_TEMPLATE/add.yml
vendored
@@ -1,17 +0,0 @@
|
||||
name: 添加功能
|
||||
description: 请填写希望添加的功能的具体信息
|
||||
title: "添加功能"
|
||||
labels: [add]
|
||||
body:
|
||||
- type: input
|
||||
id: name
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "希望添加什么功能?"
|
||||
placeholder: "请填写功能名称"
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
label: "具体信息"
|
||||
description: "请详细描述希望添加的功能的具体信息"
|
||||
4
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -1,5 +1,6 @@
|
||||
name: 遇到问题
|
||||
description: 关于使用过程中遇到的问题
|
||||
title: 请填写标题
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: input
|
||||
@@ -30,4 +31,5 @@ body:
|
||||
id: other
|
||||
attributes:
|
||||
label: "具体信息"
|
||||
description: "有需要补充的信息吗?比如控制台的报错什么的"
|
||||
description: "请填写完整的复现步骤和遇到的问题,包括但不限于报错信息、控制台输出、网络请求等"
|
||||
placeholder: "请填写具体的复现步骤和遇到的问题"
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 添加功能
|
||||
url: https://github.com/imsyy/SPlayer/discussions/new?category=%E6%83%B3%E6%B3%95-ideas
|
||||
about: 新的功能建议和提问答疑请到讨论区发起
|
||||
- name: 转到讨论区
|
||||
url: https://github.com/imsyy/SPlayer/discussions
|
||||
about: Issues 用于反馈 Bug, 新的功能建议和提问答疑请到讨论区发起
|
||||
|
||||
21
.github/workflows/build.yml
vendored
@@ -15,12 +15,12 @@ jobs:
|
||||
steps:
|
||||
# 检出 Git 仓库
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v4.1.1
|
||||
uses: actions/checkout@v4
|
||||
# 安装 Node.js
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4.0.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18.x"
|
||||
node-version: "20.x"
|
||||
# 复制环境变量文件
|
||||
- name: Copy .env.example
|
||||
run: |
|
||||
@@ -43,7 +43,20 @@ jobs:
|
||||
npx rimraf "dist/!(*.exe)"
|
||||
# 上传构建产物
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3.1.3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: SPlayer-dev
|
||||
path: dist
|
||||
# 创建 GitHub Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
name: ${{ github.ref }}-rc
|
||||
body: This version is still under development, currently only provides windows version, non-developers please do not use!
|
||||
draft: false
|
||||
prerelease: true
|
||||
files: dist/*.exe
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
|
||||
46
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Publish Docker image
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
push_to_registry:
|
||||
name: Push Docker image to multiple registries
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
imsyy/splayer
|
||||
ghcr.io/${{ github.repository }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
30
.github/workflows/release.yml
vendored
@@ -16,12 +16,12 @@ jobs:
|
||||
steps:
|
||||
# 检出 Git 仓库
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v4.1.1
|
||||
uses: actions/checkout@v4
|
||||
# 安装 Node.js
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4.0.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18.x"
|
||||
node-version: "20.x"
|
||||
# 复制环境变量文件
|
||||
- name: Copy .env.example
|
||||
run: |
|
||||
@@ -41,14 +41,14 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
# 上传构建产物
|
||||
- name: Upload Windows artifact
|
||||
uses: actions/upload-artifact@v3.1.3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: SPlarer-Win
|
||||
if-no-files-found: ignore
|
||||
path: dist/*.*
|
||||
# 创建 GitHub Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v0.1.15
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
with:
|
||||
draft: true
|
||||
@@ -63,12 +63,12 @@ jobs:
|
||||
steps:
|
||||
# 检出 Git 仓库
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v4.1.1
|
||||
uses: actions/checkout@v4
|
||||
# 安装 Node.js
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4.0.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18.x"
|
||||
node-version: "20.x"
|
||||
# 复制环境变量文件
|
||||
- name: Copy .env.example
|
||||
run: |
|
||||
@@ -88,14 +88,14 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
# 上传构建产物
|
||||
- name: Upload macOS artifact
|
||||
uses: actions/upload-artifact@v3.1.3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: SPlarer-Macos
|
||||
if-no-files-found: ignore
|
||||
path: dist/*.*
|
||||
# 创建 GitHub Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v0.1.15
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
with:
|
||||
draft: true
|
||||
@@ -110,12 +110,12 @@ jobs:
|
||||
steps:
|
||||
# 检出 Git 仓库
|
||||
- name: Check out git repository
|
||||
uses: actions/checkout@v4.1.1
|
||||
uses: actions/checkout@v4
|
||||
# 安装 Node.js
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4.0.0
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18.x"
|
||||
node-version: "20.x"
|
||||
# 更新 Ubuntu 软件源
|
||||
- name: Ubuntu Update with sudo
|
||||
run: sudo apt-get update
|
||||
@@ -138,14 +138,14 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
# 上传构建产物
|
||||
- name: Upload Linux artifact
|
||||
uses: actions/upload-artifact@v3.1.3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: SPlarer-Linux
|
||||
if-no-files-found: ignore
|
||||
path: dist/*.*
|
||||
# 创建 GitHub Release
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v0.1.15
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
with:
|
||||
draft: true
|
||||
|
||||
3
.gitignore
vendored
@@ -16,9 +16,6 @@ coverage
|
||||
out
|
||||
.env
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
.vscode
|
||||
|
||||
@@ -4,3 +4,5 @@ pnpm-lock.yaml
|
||||
LICENSE.md
|
||||
tsconfig.json
|
||||
tsconfig.*.json
|
||||
auto-imports.d.ts
|
||||
components.d.ts
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
# 是否使用单引号而不是双引号
|
||||
singleQuote: false
|
||||
# 是否在语句末尾使用分号
|
||||
semi: true
|
||||
# 每行的最大打印宽度
|
||||
printWidth: 100
|
||||
# 是否在对象和数组的末尾加上逗号
|
||||
trailingComma: all
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN [ ! -e ".env" ] && cp .env.example .env || true
|
||||
RUN npm run build
|
||||
|
||||
# nginx
|
||||
FROM nginx:1.20.2-alpine as app
|
||||
FROM nginx:1.25.3-alpine-slim as app
|
||||
|
||||
COPY --from=builder /app/out/renderer /usr/share/nginx/html
|
||||
|
||||
|
||||
99
README.md
@@ -1,10 +1,8 @@
|
||||
<div align="center">
|
||||
<img alt="logo" height="80" src="./public/images/icons/favicon.png" />
|
||||
<h2>SPlayer</h2>
|
||||
<p>一个简约的音乐播放器</p>
|
||||
<img alt="main" src="./screenshots/main.png" />
|
||||
</div>
|
||||
<br />
|
||||
# SPlayer
|
||||
|
||||
> 一个简约的音乐播放器
|
||||
|
||||

|
||||
|
||||
## 说明
|
||||
|
||||
@@ -19,9 +17,12 @@
|
||||
> - 感谢您的尊重与理解
|
||||
|
||||
- 本项目采用 [Vue 3](https://cn.vuejs.org/) 全家桶和 [Naïve UI](https://www.naiveui.com/) 组件库及 [Electron](https://www.electronjs.org/zh/docs/latest/) 开发
|
||||
- 支持网页端与客户端,由于设备有限,目前仅适配 `Win`,其他平台可自行构建
|
||||
- ~~仅对移动端做了基础适配,**不保证功能全部可用**~~
|
||||
- 欢迎各位大佬指点和 `Star` 哦 😍
|
||||
- 支持网页端与客户端,由于设备有限,目前仅适配 `Win`,其他平台可自行解决兼容性后进行构建
|
||||
- 仅对移动端做了基础适配,**不保证功能全部可用**
|
||||
|
||||
> 请注意,本程序不打算开发移动端,也不会对移动端进行完美适配,仅保证基础可用性
|
||||
|
||||
- 欢迎各位大佬 `Star` 😍
|
||||
|
||||
## 👀 Demo
|
||||
|
||||
@@ -29,40 +30,34 @@
|
||||
|
||||
## 🎉 功能
|
||||
|
||||
- 支持扫码登录
|
||||
- 支持手机号登录
|
||||
- 自动进行每日签到及云贝签到
|
||||
- 封面主题色自适应
|
||||
- 本地歌曲管理及分类 ~~以及音乐标签编辑~~
|
||||
- **支持播放部分无版权歌曲(可能会与原曲不匹配,客户端独占功能)**
|
||||
- 下载歌曲(最高支持 Hi-Res)
|
||||
- 新建歌单及歌单编辑
|
||||
- 收藏 / 取消收藏歌单或歌手
|
||||
- 每日推荐歌曲
|
||||
- 私人 FM
|
||||
- 云盘音乐上传
|
||||
- 云盘内歌曲播放
|
||||
- 云盘内歌曲纠正
|
||||
- 云盘歌曲删除
|
||||
- 支持逐字歌词
|
||||
- 歌词滚动以及歌词翻译
|
||||
- MV 与视频播放
|
||||
- 音乐频谱显示( 暂时去除,还待完善 )
|
||||
- 音乐渐入渐出
|
||||
- 支持 PWA
|
||||
- 支持评论区及评论点赞
|
||||
- 明暗模式自动 / 手动切换
|
||||
- ~~移动端基础适配~~
|
||||
- ~~`i18n` 支持~~
|
||||
- ✨ 支持扫码登录
|
||||
- 📱 支持手机号登录
|
||||
- 📅 自动进行每日签到及云贝签到
|
||||
- 🎨 封面主题色自适应
|
||||
- 🌚 Light / Dark 模式自动切换
|
||||
- 📁 本地歌曲管理及分类(建议先使用 [音乐标签](https://www.cnblogs.com/vinlxc/p/11347744.html) 进行匹配后再使用)
|
||||
- 🎵 **支持播放部分无版权歌曲(可能会与原曲不匹配,客户端独占功能)**
|
||||
- ⬇️ 下载歌曲(最高支持 Hi-Res)
|
||||
- ➕ 新建歌单及歌单编辑
|
||||
- ❤️ 收藏 / 取消收藏歌单或歌手
|
||||
- 🎶 每日推荐歌曲
|
||||
- 📻 私人 FM
|
||||
- ☁️ 云盘音乐上传
|
||||
- 📂 云盘内歌曲播放
|
||||
- 🔄 云盘内歌曲纠正
|
||||
- 🗑️ 云盘歌曲删除
|
||||
- 📝 支持逐字歌词
|
||||
- 🔄 歌词滚动以及歌词翻译
|
||||
- 📹 MV 与视频播放
|
||||
- 🎶 音乐频谱显示
|
||||
- ⏭️ 音乐渐入渐出
|
||||
- 🔄 支持 PWA
|
||||
- 💬 支持评论区及评论点赞
|
||||
- 🌓 明暗模式自动 / 手动切换
|
||||
- 📱 移动端基础适配
|
||||
- ~~🌐 `i18n` 支持~~
|
||||
|
||||
#### 待办
|
||||
|
||||
- [ ] 完善音乐频谱
|
||||
- [ ] 添加桌面歌词
|
||||
- [ ] 多种布局方式
|
||||
- [ ] 发表评论
|
||||
|
||||
## 🖼️ Screenshots
|
||||
## 🖼️ screenshots
|
||||
|
||||
> 开发中,仅供参考
|
||||
|
||||
@@ -141,10 +136,13 @@ docker-compose up -d
|
||||
### 在线部署
|
||||
|
||||
```bash
|
||||
# 拉取
|
||||
docker pull imsyy/splayer:2.0.0-beta.5
|
||||
# 从 Docker Hub 拉取
|
||||
docker pull imsyy/splayer:latest
|
||||
# 从 GitHub ghcr 拉取
|
||||
docker pull ghcr.io/imsyy/splayer:latest
|
||||
|
||||
# 运行
|
||||
docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:2.0.0-beta.5
|
||||
docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:latest
|
||||
```
|
||||
|
||||
以上步骤成功后,将会在本地 [localhost:7899](http://localhost:7899/) 启动,如需更换端口,请自行修改命令行中的端口号
|
||||
@@ -164,7 +162,7 @@ docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:2.0.0-beta.5
|
||||
|
||||
5. 将 `Build and Output Settings` 中的 `Output Directory` 改为 `out/renderer`
|
||||
|
||||

|
||||

|
||||
|
||||
6. 点击 `Deploy`,即可成功部署
|
||||
|
||||
@@ -228,7 +226,6 @@ docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:2.0.0-beta.5
|
||||
- [NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi)
|
||||
- [YesPlayMusic](https://github.com/qier222/YesPlayMusic)
|
||||
- [UnblockNeteaseMusic](https://github.com/UnblockNeteaseMusic/server)
|
||||
- [BlurLyric](https://github.com/Project-And-Factory/BlurLyric)
|
||||
- [Vue-mmPlayer](https://github.com/maomao1996/Vue-mmPlayer)
|
||||
|
||||
## 📢 免责声明
|
||||
@@ -257,7 +254,6 @@ docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:2.0.0-beta.5
|
||||
<details>
|
||||
<summary>查看目录结构详情</summary>
|
||||
|
||||
|
||||
> ChatGPT 写的,如有错误,请见谅
|
||||
|
||||
```dir
|
||||
@@ -423,4 +419,9 @@ docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:2.0.0-beta.5
|
||||
│ └── Test.vue
|
||||
└── vercel.json # Vercel 部署配置
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## ⭐ Star History
|
||||
|
||||
[](https://star-history.com/#imsyy/SPlayer&Date)
|
||||
|
||||
3
auto-imports.d.ts
vendored
@@ -65,5 +65,6 @@ declare global {
|
||||
// for type re-export
|
||||
declare global {
|
||||
// @ts-ignore
|
||||
export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
|
||||
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
|
||||
import('vue')
|
||||
}
|
||||
|
||||
6
components.d.ts
vendored
@@ -12,6 +12,7 @@ declare module 'vue' {
|
||||
CommentList: typeof import('./src/components/List/CommentList.vue')['default']
|
||||
CountDown: typeof import('./src/components/Player/CountDown.vue')['default']
|
||||
CoverDropdown: typeof import('./src/components/Cover/CoverDropdown.vue')['default']
|
||||
CoverPlayBtn: typeof import('./src/components/Cover/CoverPlayBtn.vue')['default']
|
||||
CreatePlaylist: typeof import('./src/components/Modal/CreatePlaylist.vue')['default']
|
||||
DownloadSong: typeof import('./src/components/Modal/DownloadSong.vue')['default']
|
||||
FullPlayer: typeof import('./src/components/Player/FullPlayer.vue')['default']
|
||||
@@ -39,12 +40,12 @@ declare module 'vue' {
|
||||
NDropdown: typeof import('naive-ui')['NDropdown']
|
||||
NEllipsis: typeof import('naive-ui')['NEllipsis']
|
||||
NEmpty: typeof import('naive-ui')['NEmpty']
|
||||
NFlex: typeof import('naive-ui')['NFlex']
|
||||
NForm: typeof import('naive-ui')['NForm']
|
||||
NFormItem: typeof import('naive-ui')['NFormItem']
|
||||
NGi: typeof import('naive-ui')['NGi']
|
||||
NGlobalStyle: typeof import('naive-ui')['NGlobalStyle']
|
||||
NGrid: typeof import('naive-ui')['NGrid']
|
||||
NGridItem: typeof import('naive-ui')['NGridItem']
|
||||
NH1: typeof import('naive-ui')['NH1']
|
||||
NH3: typeof import('naive-ui')['NH3']
|
||||
NH4: typeof import('naive-ui')['NH4']
|
||||
@@ -76,7 +77,6 @@ declare module 'vue' {
|
||||
NSelect: typeof import('naive-ui')['NSelect']
|
||||
NSkeleton: typeof import('naive-ui')['NSkeleton']
|
||||
NSlider: typeof import('naive-ui')['NSlider']
|
||||
NSpace: typeof import('naive-ui')['NSpace']
|
||||
NSpin: typeof import('naive-ui')['NSpin']
|
||||
NSwitch: typeof import('naive-ui')['NSwitch']
|
||||
NTab: typeof import('naive-ui')['NTab']
|
||||
@@ -99,9 +99,11 @@ declare module 'vue' {
|
||||
SearchInp: typeof import('./src/components/Search/SearchInp.vue')['default']
|
||||
SearchSuggestions: typeof import('./src/components/Search/SearchSuggestions.vue')['default']
|
||||
SongList: typeof import('./src/components/List/SongList.vue')['default']
|
||||
SongListDrawer: typeof import('./src/components/List/SongListDrawer.vue')['default']
|
||||
SongListDropdown: typeof import('./src/components/List/SongListDropdown.vue')['default']
|
||||
SpecialCover: typeof import('./src/components/Cover/SpecialCover.vue')['default']
|
||||
SpecialCoverCard: typeof import('./src/components/Cover/SpecialCoverCard.vue')['default']
|
||||
Spectrum: typeof import('./src/components/Player/Spectrum.vue')['default']
|
||||
SvgIcon: typeof import('./src/components/Global/SvgIcon.vue')['default']
|
||||
TitleBar: typeof import('./src/components/WinDom/TitleBar.vue')['default']
|
||||
UpCloudSong: typeof import('./src/components/Modal/UpCloudSong.vue')['default']
|
||||
|
||||
@@ -21,7 +21,7 @@ win:
|
||||
# 可执行文件名
|
||||
executableName: SPlayer
|
||||
# 应用程序的图标文件路径
|
||||
icon: public/images/icons/favicon-512x512.png
|
||||
icon: public/imgs/icons/favicon-512x512.png
|
||||
# 构建类型
|
||||
target: nsis
|
||||
# NSIS 安装器配置
|
||||
@@ -41,15 +41,15 @@ nsis:
|
||||
# 是否允许用户更改安装目录
|
||||
allowToChangeInstallationDirectory: true
|
||||
# 安装包图标
|
||||
installerIcon: public/images/icons/favicon.ico
|
||||
installerIcon: public/imgs/icons/favicon.ico
|
||||
# 卸载命令图标
|
||||
uninstallerIcon: public/images/icons/favicon.ico
|
||||
uninstallerIcon: public/imgs/icons/favicon.ico
|
||||
# macOS 平台配置
|
||||
mac:
|
||||
# 可执行文件名
|
||||
executableName: SPlayer
|
||||
# 应用程序的图标文件路径
|
||||
icon: public/images/icons/favicon-512x512.png
|
||||
icon: public/imgs/icons/favicon-512x512.png
|
||||
# 权限继承的文件路径
|
||||
entitlementsInherit: build/entitlements.mac.plist
|
||||
# 扩展信息,如权限描述
|
||||
@@ -71,7 +71,7 @@ linux:
|
||||
# 可执行文件名
|
||||
executableName: SPlayer
|
||||
# 应用程序的图标文件路径
|
||||
icon: public/images/icons/favicon-512x512.png
|
||||
icon: public/imgs/icons/favicon-512x512.png
|
||||
# 构建类型
|
||||
target:
|
||||
- AppImage
|
||||
|
||||
@@ -42,7 +42,7 @@ export default defineConfig(({ mode }) => {
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
index: resolve(__dirname, "electron/preload/index.js"),
|
||||
index: resolve(__dirname, "electron/preload/index.mjs"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -97,31 +97,31 @@ export default defineConfig(({ mode }) => {
|
||||
],
|
||||
},
|
||||
manifest: {
|
||||
name: loadEnv(mode, process.cwd()).RENDERER_VITE_SITE_TITLE,
|
||||
short_name: loadEnv(mode, process.cwd()).RENDERER_VITE_SITE_TITLE,
|
||||
description: loadEnv(mode, process.cwd()).RENDERER_VITE_SITE_DES,
|
||||
name: getEnv("RENDERER_VITE_SITE_TITLE"),
|
||||
short_name: getEnv("RENDERER_VITE_SITE_TITLE"),
|
||||
description: getEnv("RENDERER_VITE_SITE_DES"),
|
||||
display: "standalone",
|
||||
start_url: "/",
|
||||
theme_color: "#fff",
|
||||
background_color: "#efefef",
|
||||
icons: [
|
||||
{
|
||||
src: "/images/icons/favicon-32x32.png",
|
||||
src: "/imgs/icons/favicon-32x32.png",
|
||||
sizes: "32x32",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: "/images/icons/favicon-96x96.png",
|
||||
src: "/imgs/icons/favicon-96x96.png",
|
||||
sizes: "96x96",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: "/images/icons/favicon-256x256.png",
|
||||
src: "/imgs/icons/favicon-256x256.png",
|
||||
sizes: "256x256",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: "/images/icons/favicon-512x512.png",
|
||||
src: "/imgs/icons/favicon-512x512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
},
|
||||
@@ -3,7 +3,6 @@ import { app, protocol, shell, BrowserWindow, globalShortcut, nativeImage } from
|
||||
import { platform, optimizer, is } from "@electron-toolkit/utils";
|
||||
import { startNcmServer } from "@main/startNcmServer";
|
||||
import { startMainServer } from "@main/startMainServer";
|
||||
import { configureAutoUpdater } from "@main/utils/checkUpdates";
|
||||
import createSystemTray from "@main/utils/createSystemTray";
|
||||
import createGlobalShortcut from "@main/utils/createGlobalShortcut";
|
||||
import mainIpcMain from "@main/mainIpcMain";
|
||||
@@ -115,18 +114,18 @@ class MainProcess {
|
||||
center: true, // 是否出现在屏幕居中的位置
|
||||
show: false, // 初始时不显示窗口
|
||||
frame: false, // 无边框
|
||||
// transparent: true, // 透明窗口
|
||||
titleBarStyle: "customButtonsOnHover", // Macos 隐藏菜单栏
|
||||
autoHideMenuBar: true, // 失去焦点后自动隐藏菜单栏
|
||||
// 图标配置
|
||||
icon: nativeImage.createFromPath(join(__dirname, "../../public/images/icons/favicon.png")),
|
||||
icon: nativeImage.createFromPath(join(__dirname, "../../public/imgs/icons/favicon.png")),
|
||||
// 预加载
|
||||
webPreferences: {
|
||||
// devTools: is.dev, //是否开启 DevTools
|
||||
preload: join(__dirname, "../preload/index.js"),
|
||||
// devTools: is.dev,
|
||||
preload: join(__dirname, "../preload/index.mjs"),
|
||||
sandbox: false,
|
||||
webSecurity: false,
|
||||
hardwareAcceleration: true,
|
||||
nodeIntegration: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -155,6 +154,14 @@ class MainProcess {
|
||||
else {
|
||||
this.mainWindow.loadURL(`http://127.0.0.1:${import.meta.env.MAIN_VITE_MAIN_PORT ?? 7899}`);
|
||||
}
|
||||
|
||||
// 配置网络代理
|
||||
const proxyRules = this.store.get("proxy");
|
||||
if (proxyRules) {
|
||||
this.mainWindow.webContents.session.setProxy({ proxyRules }, (result) => {
|
||||
console.info("网络代理配置:", result);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 主应用程序事件
|
||||
@@ -162,10 +169,8 @@ class MainProcess {
|
||||
app.whenReady().then(async () => {
|
||||
// 创建主窗口
|
||||
this.createWindow();
|
||||
// 检测更新
|
||||
configureAutoUpdater();
|
||||
// 引入主 Ipc
|
||||
mainIpcMain(this.mainWindow);
|
||||
mainIpcMain(this.mainWindow, this.store);
|
||||
// 系统托盘
|
||||
createSystemTray(this.mainWindow);
|
||||
// 注册快捷键
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { ipcMain, dialog, app, clipboard, shell } from "electron";
|
||||
import { File, Picture, Id3v2Settings } from "node-taglib-sharp";
|
||||
import { configureAutoUpdater } from "@main/utils/checkUpdates";
|
||||
import { readDirAsync } from "@main/utils/readDirAsync";
|
||||
import { parseFile } from "music-metadata";
|
||||
import { write } from "node-id3";
|
||||
import { download } from "electron-dl";
|
||||
import { getFonts } from "font-list";
|
||||
import getNeteaseMusicUrl from "@main/utils/getNeteaseMusicUrl";
|
||||
import axios from "axios";
|
||||
import fs from "fs/promises";
|
||||
@@ -10,9 +12,10 @@ import fs from "fs/promises";
|
||||
/**
|
||||
* 监听主进程的 IPC 事件
|
||||
* @param {BrowserWindow} win - 要监听 IPC 事件的程序窗口
|
||||
* @param {Store} store - 存储对象
|
||||
*/
|
||||
|
||||
const mainIpcMain = (win) => {
|
||||
const mainIpcMain = (win, store) => {
|
||||
// 窗口操作部分
|
||||
ipcMain.on("window-min", (ev) => {
|
||||
// 阻止最小化
|
||||
@@ -41,6 +44,10 @@ const mainIpcMain = (win) => {
|
||||
app.relaunch();
|
||||
app.quit();
|
||||
});
|
||||
ipcMain.on("check-updates", () => {
|
||||
console.info("开始检查更新");
|
||||
configureAutoUpdater();
|
||||
});
|
||||
|
||||
// 显示进度
|
||||
ipcMain.on("setProgressBar", (_, val) => {
|
||||
@@ -193,32 +200,39 @@ const mainIpcMain = (win) => {
|
||||
});
|
||||
|
||||
// 下载文件至指定目录
|
||||
ipcMain.handle("downloadFile", async (_, data, song, songName, songType, path) => {
|
||||
ipcMain.handle("downloadFile", async (_, songData, options) => {
|
||||
try {
|
||||
const { url, data, lyric, name, type } = JSON.parse(songData);
|
||||
const { path, downloadMeta, downloadCover, downloadLyrics } = JSON.parse(options);
|
||||
if (fs.access(path)) {
|
||||
const songData = JSON.parse(song);
|
||||
console.info("开始下载:", songData, data);
|
||||
console.info("开始下载:", name, url);
|
||||
// 下载歌曲
|
||||
const songDownload = await download(win, data.url, {
|
||||
const songDownload = await download(win, url, {
|
||||
directory: path,
|
||||
filename: `${songName}.${songType}`,
|
||||
filename: `${name}.${type}`,
|
||||
});
|
||||
// 若关闭,则不进行元信息写入
|
||||
if (!downloadMeta) return true;
|
||||
// 下载封面
|
||||
const coverDownload = await download(win, songData.cover, {
|
||||
const coverDownload = await download(win, data.cover, {
|
||||
directory: path,
|
||||
filename: `${songName}.jpg`,
|
||||
filename: `${name}.jpg`,
|
||||
});
|
||||
// 生成歌曲文件的元数据
|
||||
const songTag = {
|
||||
title: songData.name,
|
||||
artist: Array.isArray(songData.artists)
|
||||
? songData.artists.map((ar) => ar.name).join(" / ")
|
||||
: songData.artists || "未知歌手",
|
||||
album: songData.album?.name || songData.album,
|
||||
image: coverDownload.getSavePath(),
|
||||
};
|
||||
// 读取歌曲文件
|
||||
const songFile = File.createFromPath(songDownload.getSavePath());
|
||||
// 生成图片信息
|
||||
const songCover = Picture.fromPath(coverDownload.getSavePath());
|
||||
// 保存修改后的元数据
|
||||
write(songTag, songDownload.getSavePath());
|
||||
Id3v2Settings.forceDefaultVersion = true;
|
||||
Id3v2Settings.defaultVersion = 3;
|
||||
songFile.tag.title = data.name || "未知曲目";
|
||||
songFile.tag.album = data.album?.name || "未知专辑";
|
||||
songFile.tag.performers = data?.artists?.map((ar) => ar.name) || ["未知艺术家"];
|
||||
if (downloadLyrics) songFile.tag.lyrics = lyric;
|
||||
if (downloadCover) songFile.tag.pictures = [songCover];
|
||||
// 保存元信息
|
||||
songFile.save();
|
||||
songFile.dispose();
|
||||
// 删除封面
|
||||
await fs.unlink(coverDownload.getSavePath());
|
||||
return true;
|
||||
@@ -231,6 +245,35 @@ const mainIpcMain = (win) => {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// 读取系统全部字体
|
||||
ipcMain.handle("getAllFonts", async () => {
|
||||
try {
|
||||
const fonts = await getFonts();
|
||||
return fonts;
|
||||
} catch (error) {
|
||||
console.error("获取系统字体时出错:", error);
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
// 配置网络代理
|
||||
ipcMain.on("set-proxy", (_, config) => {
|
||||
console.log(config);
|
||||
const proxyRules = `${config.protocol}://${config.server}:${config.port}`;
|
||||
store.set("proxy", proxyRules);
|
||||
win.webContents.session.setProxy({ proxyRules }, () => {
|
||||
console.info("网络代理配置完成");
|
||||
});
|
||||
});
|
||||
|
||||
// 取消代理
|
||||
ipcMain.on("remove-proxy", () => {
|
||||
store.set("proxy", "");
|
||||
win.webContents.session.setProxy({ proxyRules: "" }, () => {
|
||||
console.info("取消网络代理配置");
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const netEaseApi = require("NeteaseCloudMusicApi");
|
||||
import netEaseApi from "NeteaseCloudMusicApi";
|
||||
|
||||
/**
|
||||
* 启动网易云音乐 API 服务器
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { dialog, shell } from "electron";
|
||||
import { dialog } from "electron";
|
||||
import { is } from "@electron-toolkit/utils";
|
||||
import { autoUpdater } from "electron-updater";
|
||||
import pkg from "electron-updater";
|
||||
|
||||
const { autoUpdater } = pkg;
|
||||
|
||||
// 更新弹窗
|
||||
const hasNewVersion = (info) => {
|
||||
@@ -8,23 +10,56 @@ const hasNewVersion = (info) => {
|
||||
.showMessageBox({
|
||||
title: "发现新版本 v" + info.version,
|
||||
message: "发现新版本 v" + info.version,
|
||||
detail: "是否前往 GitHub 下载新版本安装包?",
|
||||
buttons: ["前往", "取消"],
|
||||
detail: "是否立即下载并安装新版本?",
|
||||
buttons: ["立即下载", "取消"],
|
||||
type: "question",
|
||||
noLink: true,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.response === 0) {
|
||||
shell.openExternal("https://github.com/imsyy/SPlayer/releases");
|
||||
// 触发手动下载
|
||||
autoUpdater.downloadUpdate();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const configureAutoUpdater = () => {
|
||||
if (is.dev) return false;
|
||||
autoUpdater.checkForUpdatesAndNotify();
|
||||
|
||||
// 监听下载进度事件
|
||||
autoUpdater.on("download-progress", (progressObj) => {
|
||||
console.log(`更新下载进度: ${progressObj.percent}%`);
|
||||
});
|
||||
|
||||
// 下载完成
|
||||
autoUpdater.on("update-downloaded", () => {
|
||||
// 显示安装弹窗
|
||||
dialog
|
||||
.showMessageBox({
|
||||
title: "下载完成",
|
||||
message: "新版本已下载完成,是否现在安装?",
|
||||
buttons: ["是", "稍后"],
|
||||
type: "question",
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.response === 0) {
|
||||
// 安装更新
|
||||
autoUpdater.quitAndInstall();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 下载失败
|
||||
autoUpdater.on("error", (err) => {
|
||||
console.error("下载更新失败:", err);
|
||||
dialog.showErrorBox("下载更新失败", "请检查网络连接并稍后重试!");
|
||||
});
|
||||
|
||||
// 若有更新
|
||||
autoUpdater.on("update-available", (info) => {
|
||||
hasNewVersion(info);
|
||||
});
|
||||
|
||||
// 检查更新
|
||||
autoUpdater.checkForUpdatesAndNotify();
|
||||
};
|
||||
|
||||
@@ -17,8 +17,8 @@ const createSystemTray = (win) => {
|
||||
join(
|
||||
__dirname,
|
||||
process.platform === "win32"
|
||||
? "../../public/images/icons/favicon.ico"
|
||||
: "../../public/images/icons/favicon-32x32.png",
|
||||
? "../../public/imgs/icons/favicon.ico"
|
||||
: "../../public/imgs/icons/favicon-32x32.png",
|
||||
),
|
||||
)
|
||||
.resize({
|
||||
@@ -63,8 +63,8 @@ const createIcon = (name) => {
|
||||
return nativeImage
|
||||
.createFromPath(
|
||||
isDarkMode
|
||||
? join(__dirname, `../../public/images/icons/${name}-dark.png`)
|
||||
: join(__dirname, `../../public/images/icons/${name}-light.png`),
|
||||
? join(__dirname, `../../public/imgs/icons/${name}-dark.png`)
|
||||
: join(__dirname, `../../public/imgs/icons/${name}-light.png`),
|
||||
)
|
||||
.resize({ width: 16, height: 16 });
|
||||
};
|
||||
|
||||
@@ -121,7 +121,7 @@ const getKuwoSongUrl = async (keyword) => {
|
||||
const url = encryptQuery
|
||||
? "http://mobi.kuwo.cn/mobi.s?f=kuwo&q=" +
|
||||
encryptQuery(
|
||||
"corp=kuwo&source=kwplayer_ar_8.5.5.0_apk_keluze.apk&p2p=1&type=convert_url2&sig=0&format=mp3" +
|
||||
"corp=kuwo&source=kwplayer_ar_1.1.9_oppo_118980_320.apk&p2p=1&type=convert_url2&sig=0&format=mp3" +
|
||||
"&rid=" +
|
||||
songId,
|
||||
)
|
||||
|
||||
40
index.html
@@ -1,25 +1,23 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/imgs/icons/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/imgs/icons/favicon-16x16.png" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/imgs/icons/apple-touch-icon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>%RENDERER_VITE_SITE_TITLE%</title>
|
||||
<meta name="apple-mobile-web-app-title" content="%RENDERER_VITE_SITE_TITLE%" />
|
||||
<meta name="author" content="%RENDERER_VITE_SITE_ANTHOR%" />
|
||||
<meta name="keywords" content="%RENDERER_VITE_SITE_KEYWORDS%" />
|
||||
<meta name="description" content="%RENDERER_VITE_SITE_DES%" />
|
||||
<link rel="mask-icon" href="/imgs/icons/safari-pinned-tab.svg" color="#5bbad5" />
|
||||
<meta name="msapplication-TileColor" content="#da532c" />
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/images/icons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/images/icons/favicon-16x16.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/images/icons/apple-touch-icon.png">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>%RENDERER_VITE_SITE_TITLE%</title>
|
||||
<meta name="apple-mobile-web-app-title" content="%RENDERER_VITE_SITE_TITLE%" />
|
||||
<meta name="author" content="%RENDERER_VITE_SITE_ANTHOR%" />
|
||||
<meta name="keywords" content="%RENDERER_VITE_SITE_KEYWORDS%" />
|
||||
<meta name="description" content="%RENDERER_VITE_SITE_DES%" />
|
||||
<link rel="mask-icon" href="/images/icons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="theme-color" content="#ffffff" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
81
package.json
@@ -1,16 +1,20 @@
|
||||
{
|
||||
"name": "splayer",
|
||||
"version": "2.0.0-beta.5",
|
||||
"version": "2.0.8",
|
||||
"description": "A minimalist music player",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "imsyy",
|
||||
"home": "https://imsyy.top",
|
||||
"github": "https://github.com/imsyy/SPlayer",
|
||||
"repository": "github:imsyy/SPlayer",
|
||||
"license": "AGPL-3.0",
|
||||
"license-file": "LICENSE",
|
||||
"engines": {
|
||||
"node": ">=16.16.0"
|
||||
"node": ">=18.16.0",
|
||||
"npm": ">=9.6.7",
|
||||
"pnpm": ">=8.14.0"
|
||||
},
|
||||
"packageManager": "pnpm@8.12.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"format": "prettier --write .",
|
||||
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.vue --fix",
|
||||
@@ -23,50 +27,51 @@
|
||||
"build:linux": "npm run build && electron-builder --linux --config"
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron-toolkit/preload": "^2.0.0",
|
||||
"@electron-toolkit/utils": "^2.0.0",
|
||||
"@electron-toolkit/preload": "^3.0.1",
|
||||
"@electron-toolkit/utils": "^3.0.0",
|
||||
"@material/material-color-utilities": "^0.2.7",
|
||||
"NeteaseCloudMusicApi": "^4.14.0",
|
||||
"axios": "^1.4.0",
|
||||
"NeteaseCloudMusicApi": "^4.19.8",
|
||||
"axios": "^1.7.2",
|
||||
"colorthief": "^2.4.0",
|
||||
"electron-dl": "^3.5.1",
|
||||
"electron-store": "^8.1.0",
|
||||
"electron-updater": "^6.1.7",
|
||||
"express": "^4.18.2",
|
||||
"express-http-proxy": "^1.6.3",
|
||||
"howler": "^2.2.3",
|
||||
"electron-dl": "^3.5.2",
|
||||
"electron-store": "^8.2.0",
|
||||
"electron-updater": "^6.1.8",
|
||||
"express": "^4.19.2",
|
||||
"express-http-proxy": "^2.0.0",
|
||||
"font-list": "^1.5.1",
|
||||
"howler": "^2.2.4",
|
||||
"js-cookie": "^3.0.5",
|
||||
"localforage": "^1.10.0",
|
||||
"music-metadata": "7.13.4",
|
||||
"node-id3": "^0.2.6",
|
||||
"pinia": "^2.1.6",
|
||||
"pinia-plugin-persistedstate": "^3.2.0",
|
||||
"music-metadata": "7.14.0",
|
||||
"node-taglib-sharp": "^5.2.3",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"plyr": "^3.7.8",
|
||||
"screenfull": "^6.0.2",
|
||||
"vue-router": "^4.2.4",
|
||||
"vue-router": "^4.3.2",
|
||||
"vue-slider-component": "4.1.0-beta.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-toolkit/eslint-config": "^1.0.1",
|
||||
"@rushstack/eslint-patch": "^1.3.3",
|
||||
"@vitejs/plugin-vue": "^4.3.1",
|
||||
"@vue/eslint-config-prettier": "^8.0.0",
|
||||
"ajv": "^8.12.0",
|
||||
"electron": "^27.0.0",
|
||||
"electron-builder": "^24.9.1",
|
||||
"electron-log": "^5.0.1",
|
||||
"electron-vite": "^1.0.29",
|
||||
"eslint": "^8.47.0",
|
||||
"eslint-plugin-vue": "^9.17.0",
|
||||
"naive-ui": "^2.36.0",
|
||||
"prettier": "^3.0.2",
|
||||
"sass": "^1.66.1",
|
||||
"terser": "^5.19.2",
|
||||
"unplugin-auto-import": "^0.16.6",
|
||||
"unplugin-vue-components": "^0.25.1",
|
||||
"vite": "^4.4.9",
|
||||
"@electron-toolkit/eslint-config": "^1.0.2",
|
||||
"@rushstack/eslint-patch": "^1.10.3",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"ajv": "^8.13.0",
|
||||
"electron": "^28.3.2",
|
||||
"electron-builder": "^24.13.3",
|
||||
"electron-log": "^5.1.4",
|
||||
"electron-vite": "^2.2.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-vue": "^9.26.0",
|
||||
"naive-ui": "^2.38.2",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "^1.77.2",
|
||||
"terser": "^5.31.0",
|
||||
"unplugin-auto-import": "^0.17.6",
|
||||
"unplugin-vue-components": "^0.26.0",
|
||||
"vite": "^5.2.11",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-pwa": "^0.17.4",
|
||||
"vue": "^3.3.4"
|
||||
"vite-plugin-pwa": "^0.17.5",
|
||||
"vue": "3.4.8"
|
||||
}
|
||||
}
|
||||
|
||||
11472
pnpm-lock.yaml
generated
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
BIN
public/font/HarmonyOS_Sans_SC.woff2
Normal file
BIN
public/font/HarmonyOS_Sans_SC_Bold.woff2
Normal file
13
public/font/font.css
Normal file
@@ -0,0 +1,13 @@
|
||||
@font-face {
|
||||
font-family: "HarmonyOS Sans";
|
||||
src: url("./HarmonyOS_Sans_SC.woff2") format("woff2");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "HarmonyOS Sans";
|
||||
src: url("./HarmonyOS_Sans_SC_Bold.woff2") format("woff2");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
1
public/font/font.min.css
vendored
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |