Compare commits

..

59 Commits

Author SHA1 Message Date
imsyy
e66ba52889 🐞 fix: 修复酷我音源失效 2024-06-06 09:34:52 +08:00
imsyy
b146dc011e feat: 自动切换可用端口 2024-06-04 15:03:02 +08:00
imsyy
ad2422d826 🐞 fix: 修复酷我解灰失效 2024-05-28 09:47:33 +08:00
imsyy
6b9ba74c35 🦄 refactor: 图片大小优化 2024-05-24 11:36:18 +08:00
imsyy
22e2653e20 🐞 fix: 修复图片 2024-05-24 11:19:20 +08:00
imsyy
4cac54c84a feat: 电台模式完善 2024-05-24 11:01:42 +08:00
imsyy
e5f9ecd7b5 ↩ revert: 回退部分修改 2024-05-24 10:47:14 +08:00
imsyy
d64cfb40ec Revert "🐎 ci: 修复工作流"
This reverts commit f2935f3c1c.
2024-05-24 10:40:36 +08:00
imsyy
53c30caf00 Merge branch 'dev' of github.com:imsyy/SPlayer into dev 2024-05-24 10:27:04 +08:00
imsyy
6fcce91b2b ↩ revert: 回退 2024-05-24 10:26:53 +08:00
imsyy
5a53dfcdf7 🐞 fix: 修正图片 2024-05-24 10:09:43 +08:00
imsyy
bbe71bd62d feat: 支持查看电台节目评论 2024-05-23 18:01:16 +08:00
imsyy
ecedf0b7b9 🦄 refactor: add .gitattributes 2024-05-23 15:21:08 +08:00
imsyy
f2935f3c1c 🐎 ci: 修复工作流 2024-05-10 16:55:15 +08:00
imsyy
d3e677d494 🐎 ci: 修复构建工作流 2024-05-10 16:24:51 +08:00
imsyy
e49f90b0da feat: 电台模式下可展开播放器 2024-05-10 16:11:31 +08:00
imsyy
0359b0e470 🔧 build: 更新依赖 2024-05-06 11:24:15 +08:00
imsyy
aa2373695b 🔧 build: 去除无关文件 2024-04-29 17:47:29 +08:00
imsyy
cf940ff405 🌈 style: 优化部分样式 2024-04-29 17:43:56 +08:00
imsyy
e7c17cf531 🐞 fix: 修复偶发性客户端状态栏异常 2024-04-26 10:02:25 +08:00
imsyy
c6a1ca4f42 feat: 新增自定义字体 #156 & 网络代理 #159 2024-04-25 18:17:50 +08:00
imsyy
8f5008df69 🐞 fix: 修复大部分历史遗留错误 #144
- 修复客户端导航栏显示异常的问题
- 优化频谱动画的显示效果
- 修复Tab栏移动效果 #144
- 优化字体粗体时的显示效果 #156
2024-04-16 17:51:15 +08:00
imsyy
428ce4be86 feat: 支持配置自动更新开关 #148 2024-03-21 14:11:49 +08:00
imsyy
d46c4c4285 🐞 fix: 修复标题栏异常消失 #142 2024-03-14 13:41:31 +08:00
imsyy
0b871175b2 🐞 fix: 修复标题栏异常消失 #142 2024-03-14 11:57:29 +08:00
imsyy
c34c4fd880 📃 docs: update Docs 2024-03-05 18:00:26 +08:00
imsyy
ff00f0c283 🐞 fix: 修复标题栏无法正常显示 #142 2024-02-22 15:18:26 +08:00
imsyy
847c2e5810 📃 docs: 更新说明 2024-01-25 09:22:11 +08:00
imsyy
e62c81bb33 🐞 fix: 修复电台未加载全部节目 2024-01-18 16:25:03 +08:00
imsyy
984fdb3459 📃 docs: 更新说明 2024-01-18 11:45:46 +08:00
imsyy
019b78bf38 🐞 fix: 修复歌单无法删除歌曲 2024-01-13 10:23:40 +08:00
imsyy
cf88c7669f 📃 docs: 更新说明 2024-01-12 11:14:09 +08:00
imsyy
f4383ba848 feat: 播放页面支持调节音量 #124 2024-01-12 11:08:35 +08:00
imsyy
adbda459ba 🐞 fix: 修复下载歌曲元信息不正确导致无法正常播放 #113 2024-01-11 16:09:09 +08:00
imsyy
984d747179 🐞 fix: 修复本地歌词翻译显示异常 #121 2024-01-11 11:39:29 +08:00
imsyy
c012f84064 🐳 chore: Docker 自动部署 2024-01-10 16:00:02 +08:00
imsyy
a57a18b9f5 feat: 播放模式支持点击切换 2024-01-10 14:47:59 +08:00
imsyy
309c323a14 🔧 build: support ESM and upgrade to Vite 5
- 临时解决下载歌曲无法正常播放 #113
2024-01-09 18:13:01 +08:00
imsyy
6a1e606d6d feat: 移动端基础适配
- 修复未登录时无法使用本地歌曲
- 修复部分样式异常
2024-01-08 18:20:47 +08:00
imsyy
af3931847e 🐞 fix: 修复音乐缓存导致播放异常 2024-01-05 11:32:40 +08:00
imsyy
41eadb5843 🌈 style: 优化部分样式 2024-01-05 11:15:24 +08:00
imsyy
8963d719d9 feat: 侧边栏支持显示歌单封面 #111 2024-01-03 16:36:54 +08:00
imsyy
0a7761ffff 🐞 fix: 解决音频资源过期问题 2024-01-03 11:33:59 +08:00
imsyy
1a63771f2d feat: 新增雷达歌单 2024-01-03 10:54:27 +08:00
imsyy
1f9141ba33 🔧 build: 更新部分依赖版本 2024-01-02 18:13:01 +08:00
imsyy
a341a69d48 feat: 卡片播放按钮可直接播放 #111 2023-12-29 14:32:10 +08:00
imsyy
0cedfe0af3 feat: 支持播放超大歌单
- 支持大于 2000 首歌曲的歌单播放
2023-12-28 17:46:57 +08:00
imsyy
59f492ed8f feat: 新增音乐频谱显示 2023-12-27 16:47:10 +08:00
imsyy
8f416ff841 🐞 fix: 修复当电台模式时播放列表出现错误 2023-12-27 10:26:42 +08:00
imsyy
99ab194e4b 🐳 chore: Change Dockerfile 2023-12-26 13:55:31 +08:00
底层用户
43fb9b48dc 🔧 Merge pull request #109 from imsyy/dependabot/npm_and_yarn/postcss-8.4.32
build(deps): bump postcss from 8.4.28 to 8.4.32
2023-12-26 09:42:46 +08:00
底层用户
c61e54d6a3 🔧 Merge pull request #108 from imsyy/dependabot/npm_and_yarn/babel/traverse-7.23.6
build(deps-dev): bump @babel/traverse from 7.22.11 to 7.23.6
2023-12-26 09:42:38 +08:00
底层用户
c8d195053f 🔧 Merge pull request #107 from imsyy/dependabot/npm_and_yarn/vite-4.4.12
build(deps-dev): bump vite from 4.4.9 to 4.4.12
2023-12-26 09:41:50 +08:00
底层用户
8cfe5d0481 🔧 Merge pull request #106 from imsyy/dependabot/npm_and_yarn/axios-1.6.0
build(deps): bump axios from 1.4.0 to 1.6.0
2023-12-26 09:41:27 +08:00
dependabot[bot]
fcc2f5015f build(deps): bump postcss from 8.4.28 to 8.4.32
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.28 to 8.4.32.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.4.28...8.4.32)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-26 01:33:27 +00:00
dependabot[bot]
9b98a45264 build(deps-dev): bump @babel/traverse from 7.22.11 to 7.23.6
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.22.11 to 7.23.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.6/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-26 01:22:34 +00:00
dependabot[bot]
3c4e836fb8 build(deps-dev): bump vite from 4.4.9 to 4.4.12
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.9 to 4.4.12.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.4.12/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.4.12/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-26 01:22:23 +00:00
dependabot[bot]
a8111b9d3f build(deps): bump axios from 1.4.0 to 1.6.0
Bumps [axios](https://github.com/axios/axios) from 1.4.0 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.4.0...v1.6.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-26 01:22:18 +00:00
imsyy
8eaeffeda3 🎈 perf: 优化云盘缓存 2023-12-25 18:30:38 +08:00
270 changed files with 11380 additions and 6924 deletions

View File

@@ -1,9 +1,18 @@
# 根配置文件
## 编辑器在查找配置时会停止查找更高层次的配置文件
root = true
# 通配符,匹配所有文件
[*]
# 设置字符集为 UTF-8确保文件中的文本使用 UTF-8 编码
charset = utf-8
# 使用空格作为缩进风格
indent_style = space
# 设置每个缩进级别的空格数量为 2
indent_size = 2
# 设置行尾换行符为LFLine Feed
end_of_line = lf
# 在文件的末尾插入一个新行
insert_final_newline = true
trim_trailing_whitespace = true
# 删除每一行末尾的尾随空格
trim_trailing_whitespace = true

View File

@@ -2,3 +2,5 @@ node_modules
dist
out
.gitignore
auto-imports.d.ts
components.d.ts

View File

@@ -49,7 +49,8 @@ module.exports = {
$notification: true,
$changeThemeColor: true,
$canNotConnect: true,
$refreshCloudList: true,
$refreshCloudCatch: true,
$cleanAll: true,
$player: true,
},
};

View File

@@ -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: "请详细描述希望添加的功能的具体信息"

View File

@@ -1,5 +1,6 @@
name: 遇到问题
description: 关于使用过程中遇到的问题
title: 请填写标题
labels: [bug]
body:
- type: input
@@ -30,4 +31,5 @@ body:
id: other
attributes:
label: "具体信息"
description: "有需要补充的信息吗?比如控制台的报错什么的"
description: "请填写完整的复现步骤和遇到的问题,包括但不限于报错信息、控制台输出、网络请求等"
placeholder: "请填写具体的复现步骤和遇到的问题"

View File

@@ -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, 新的功能建议和提问答疑请到讨论区发起

View File

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

View File

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

@@ -16,9 +16,6 @@ coverage
out
.env
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
.vscode

View File

@@ -4,3 +4,5 @@ pnpm-lock.yaml
LICENSE.md
tsconfig.json
tsconfig.*.json
auto-imports.d.ts
components.d.ts

View File

@@ -1,4 +1,8 @@
# 是否使用单引号而不是双引号
singleQuote: false
# 是否在语句末尾使用分号
semi: true
# 每行的最大打印宽度
printWidth: 100
# 是否在对象和数组的末尾加上逗号
trailingComma: all

View File

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

View File

@@ -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
> 一个简约的音乐播放器
![main](/screenshots/SPlayer.jpg)
## 说明
@@ -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`
![build](/screenshots/build.png)
![build](/screenshots/build.jpg)
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
[![Star History Chart](https://api.star-history.com/svg?repos=imsyy/SPlayer&type=Date)](https://star-history.com/#imsyy/SPlayer&Date)

3
auto-imports.d.ts vendored
View File

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

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

View File

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

View File

@@ -1,22 +1,21 @@
import { resolve } from "path";
import {
defineConfig,
externalizeDepsPlugin,
loadEnv,
splitVendorChunkPlugin,
} from "electron-vite";
import { defineConfig, externalizeDepsPlugin, loadEnv } from "electron-vite";
import { NaiveUiResolver } from "unplugin-vue-components/resolvers";
import { VitePWA } from "vite-plugin-pwa";
import vue from "@vitejs/plugin-vue";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import viteCompression from "vite-plugin-compression";
import checkPort from "./electron/main/utils/checkPort";
export default defineConfig(({ mode }) => {
export default defineConfig(async ({ mode }) => {
// 读取环境变量
const getEnv = (name) => {
return loadEnv(mode, process.cwd())[name];
};
// 获取端口
const devPort = await checkPort(getEnv("MAIN_VITE_DEV_PORT"));
const serverPort = await checkPort(getEnv("MAIN_VITE_SERVER_PORT"));
// 返回配置
return {
// 主进程
@@ -42,7 +41,7 @@ export default defineConfig(({ mode }) => {
build: {
rollupOptions: {
input: {
index: resolve(__dirname, "electron/preload/index.js"),
index: resolve(__dirname, "electron/preload/index.mjs"),
},
},
},
@@ -70,8 +69,6 @@ export default defineConfig(({ mode }) => {
}),
// viteCompression
viteCompression(),
// splitVendorChunkPlugin
splitVendorChunkPlugin(),
// PWA
VitePWA({
registerType: "autoUpdate",
@@ -97,31 +94,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",
},
@@ -131,11 +128,11 @@ export default defineConfig(({ mode }) => {
],
// 服务器配置
server: {
port: getEnv("MAIN_VITE_DEV_PORT"),
port: devPort,
// 代理
proxy: {
"/api": {
target: `http://${getEnv("MAIN_VITE_SERVER_HOST")}:${getEnv("MAIN_VITE_SERVER_PORT")}`,
target: `http://${getEnv("MAIN_VITE_SERVER_HOST")}:${serverPort}`,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},

View File

@@ -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);
// 注册快捷键

View File

@@ -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("取消网络代理配置");
});
});
};
/**

View File

@@ -1,4 +1,5 @@
const netEaseApi = require("NeteaseCloudMusicApi");
import netEaseApi from "NeteaseCloudMusicApi";
import checkPort from "@main/utils/checkPort";
/**
* 启动网易云音乐 API 服务器
@@ -15,6 +16,7 @@ export const startNcmServer = async (
host: "127.0.0.1",
},
) => {
console.log(options);
const serverPort = await checkPort(options.port);
options.port = serverPort;
return await netEaseApi.serveNcmApi(options);
};

View File

@@ -0,0 +1,37 @@
import net from "net";
/**
* 检查端口是否可用, 如果被占用或不可访问,则尝试下一个端口
* @param {number} port 端口号
* @param {number} [maxPort=65535] 端口号上限
* @returns {Promise<number>} 返回可用的端口号
*/
const checkPort = (port, maxPort = 65535) => {
return new Promise((resolve, reject) => {
if (port > maxPort) {
reject(new Error(`${port} 超出端口范围,无法找到可用端口`));
return;
}
port = Number(port);
const server = net.createServer();
server.listen(port, "0.0.0.0", () => {
server.once("close", () => {
resolve(port);
});
server.close();
});
server.on("error", (err) => {
if (err.code === "EADDRINUSE" || err.code === "EACCES") {
resolve(checkPort(port + 1, maxPort));
} else {
reject(err);
}
});
});
};
export default checkPort;

View File

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

View File

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

View File

@@ -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_5.1.0.0_B_jiakong_vh.apk&p2p=1&type=convert_url2&sig=0&format=mp3" +
"&rid=" +
songId,
)

View File

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

View File

@@ -1,16 +1,20 @@
{
"name": "splayer",
"version": "2.0.0-beta.5",
"version": "2.0.9",
"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.9",
"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.5",
"@vue/eslint-config-prettier": "^9.0.0",
"ajv": "^8.15.0",
"electron": "^28.3.3",
"electron-builder": "^24.13.3",
"electron-log": "^5.1.5",
"electron-vite": "^2.2.0",
"eslint": "^8.57.0",
"eslint-plugin-vue": "^9.26.0",
"naive-ui": "^2.38.2",
"prettier": "^3.3.0",
"sass": "^1.77.4",
"terser": "^5.31.0",
"unplugin-auto-import": "^0.17.6",
"unplugin-vue-components": "^0.26.0",
"vite": "^5.2.12",
"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"
}
}

11439
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Binary file not shown.

13
public/font/font.css Normal file
View 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;
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Some files were not shown because too many files have changed in this diff Show More