Compare commits
102 Commits
http
...
b6c325198d
| Author | SHA1 | Date | |
|---|---|---|---|
| b6c325198d | |||
| 532d30aa93 | |||
| aae86d8b4e | |||
| 4b1fb765b0 | |||
| 533f732c53 | |||
| 009274e4ad | |||
| 76f6c30b9d | |||
| 9ec22add55 | |||
| 272227e4e3 | |||
| ec8f8c1e2d | |||
| 1c14092068 | |||
| 00bdafc621 | |||
| 78422899e4 | |||
| c47f7de5b8 | |||
| 37aae9e03c | |||
| fa134d31d6 | |||
| d035dcd531 | |||
| c50bf452ca | |||
| dace5ce2b0 | |||
| ef145169aa | |||
| 7b746155f7 | |||
|
|
b289f4054d | ||
|
|
bdee1fdf84 | ||
| 541e4e96cf | |||
| 401eb3ab39 | |||
| d3eba96a29 | |||
| 81c02db00d | |||
|
|
9cb2ccbb4e | ||
| 8a10b8fe0f | |||
| 8fce8bdca4 | |||
| 1ab934cee9 | |||
| 6659ac6fad | |||
| 3a5ab1c614 | |||
| 1e07e1f833 | |||
| e1e91a3683 | |||
| c30d95a3e0 | |||
| 97f6fa843c | |||
| f43fc47539 | |||
|
|
c330de52fa | ||
| 67d35626cb | |||
| cc4c2189dc | |||
| d16905c0a3 | |||
| 4e611db349 | |||
| 7e9fc0ac3f | |||
| ff072d1a93 | |||
| a9c81c878e | |||
| 3660d13d7d | |||
| 281f53c049 | |||
| 71ca541f78 | |||
| 91f4f4afac | |||
| fc5639d7bd | |||
|
|
6668c11846 | ||
| 17f3351cea | |||
| dd3dd4ddb2 | |||
| 60d1494d45 | |||
| 1ef5350b3f | |||
| 3521e5787b | |||
| 8d9bcdad7e | |||
| ac086db1ed | |||
| 6dff0181d2 | |||
| ad24d3a140 | |||
| 4b0f39d747 | |||
| 096cc1da94 | |||
| 2d3200ad97 | |||
| 4e82e2f6f7 | |||
| 339ed53c2e | |||
| fc7c162e2f | |||
|
|
24f1549730 | ||
| 5584a46ca2 | |||
| 4471441d6f | |||
| 991a89147e | |||
| a08c0d8448 | |||
| 59db8dd177 | |||
| 29693f1baf | |||
| 5d6f157ae1 | |||
| afda3d5301 | |||
| 5d4ba757aa | |||
| d12d58b15a | |||
| 627c3dc71f | |||
| 26c7a3241c | |||
| 46c5e3dd1a | |||
|
|
92a6c6bfdb | ||
| 031aa49f9f | |||
| 1d7aee4cea | |||
| dec3ef5ef4 | |||
| d42f913250 | |||
| bae4e663fb | |||
| a17e060d16 | |||
| 71946965eb | |||
| d4cd22d234 | |||
| 05f2f7d46d | |||
| 9deb2744a9 | |||
| 6fac7c42d6 | |||
| 3393bc84e3 | |||
| 286b0159d7 | |||
| cc98e556c6 | |||
| 5902f482d9 | |||
| 551e7e2cfd | |||
| e0179b5838 | |||
| df79267e16 | |||
| 1f0254822f | |||
| e9b6fef3cd |
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. iOS]
|
||||||
|
- Browser [e.g. chrome, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Smartphone (please complete the following information):**
|
||||||
|
- Device: [e.g. iPhone6]
|
||||||
|
- OS: [e.g. iOS8.1]
|
||||||
|
- Browser [e.g. stock browser, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
328
.github/workflows/build-release.yml
vendored
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
name: Build and Release Voidraft
|
||||||
|
|
||||||
|
on:
|
||||||
|
# 推送标签时触发(用于正式发布)
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*' # 触发条件:推送 v 开头的标签,如 v1.0.0
|
||||||
|
branches:
|
||||||
|
- main # 仅当标签在 main 分支时触发
|
||||||
|
|
||||||
|
# 手动触发(用于测试)
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
release:
|
||||||
|
description: '是否创建 Release(测试时选 false)'
|
||||||
|
required: true
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
platforms:
|
||||||
|
description: '要构建的平台(用逗号分隔:windows,linux,macos-intel,macos-arm)'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: 'windows,linux'
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_OPTIONS: "--max-old-space-size=4096" # 防止 Node.js 内存溢出
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# 准备构建配置
|
||||||
|
prepare:
|
||||||
|
permissions: {}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||||
|
should_release: ${{ steps.check-release.outputs.should_release }}
|
||||||
|
steps:
|
||||||
|
- name: 确定构建平台
|
||||||
|
id: set-matrix
|
||||||
|
run: |
|
||||||
|
# 如果是手动触发,根据输入决定平台
|
||||||
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||||
|
PLATFORMS="${{ github.event.inputs.platforms }}"
|
||||||
|
else
|
||||||
|
# 标签触发,构建所有平台
|
||||||
|
PLATFORMS="windows,linux,macos-intel,macos-arm"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "构建平台: $PLATFORMS"
|
||||||
|
|
||||||
|
# 构建矩阵 JSON
|
||||||
|
MATRIX='{"include":[]}'
|
||||||
|
|
||||||
|
if [[ "$PLATFORMS" == *"windows"* ]]; then
|
||||||
|
MATRIX=$(echo "$MATRIX" | jq -c '.include += [{"platform":"windows-latest","os":"windows","arch":"amd64","platform_dir":"windows","id":"windows"}]')
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$PLATFORMS" == *"linux"* ]]; then
|
||||||
|
MATRIX=$(echo "$MATRIX" | jq -c '.include += [{"platform":"ubuntu-22.04","os":"linux","arch":"amd64","platform_dir":"linux","id":"linux"}]')
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$PLATFORMS" == *"macos-intel"* ]]; then
|
||||||
|
MATRIX=$(echo "$MATRIX" | jq -c '.include += [{"platform":"macos-latest","os":"darwin","arch":"amd64","platform_dir":"darwin","id":"macos-intel"}]')
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$PLATFORMS" == *"macos-arm"* ]]; then
|
||||||
|
MATRIX=$(echo "$MATRIX" | jq -c '.include += [{"platform":"macos-latest","os":"darwin","arch":"arm64","platform_dir":"darwin","id":"macos-arm"}]')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 使用 -c 确保输出紧凑的单行 JSON,符合 GitHub Actions 输出格式
|
||||||
|
echo "matrix=$(echo "$MATRIX" | jq -c .)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
# 输出美化的 JSON 用于日志查看
|
||||||
|
echo "生成的矩阵:"
|
||||||
|
echo "$MATRIX" | jq .
|
||||||
|
|
||||||
|
- name: 检查是否创建 Release
|
||||||
|
id: check-release
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||||
|
# 手动触发,根据输入决定
|
||||||
|
echo "should_release=${{ github.event.inputs.release }}" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
# 标签触发,自动创建 Release
|
||||||
|
echo "should_release=true" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
build:
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
needs: prepare
|
||||||
|
if: ${{ fromJson(needs.prepare.outputs.matrix).include[0] != null }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix: ${{ fromJson(needs.prepare.outputs.matrix) }}
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: 设置 Go 环境
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.21'
|
||||||
|
cache: true
|
||||||
|
|
||||||
|
- name: 设置 Node.js 环境
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: frontend/package-lock.json
|
||||||
|
|
||||||
|
# Linux 平台依赖
|
||||||
|
- name: 安装 Linux 依赖
|
||||||
|
if: matrix.os == 'linux'
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
# Wails 3 + 项目特定依赖
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
pkg-config \
|
||||||
|
libgtk-3-dev \
|
||||||
|
libwebkit2gtk-4.1-dev \
|
||||||
|
libayatana-appindicator3-dev \
|
||||||
|
librsvg2-dev \
|
||||||
|
patchelf \
|
||||||
|
libx11-dev \
|
||||||
|
rpm \
|
||||||
|
fuse \
|
||||||
|
file
|
||||||
|
|
||||||
|
# 依赖说明:
|
||||||
|
# - build-essential: C/C++ 编译工具链
|
||||||
|
# - pkg-config: 包配置工具
|
||||||
|
# - libgtk-3-dev: GTK3 GUI 框架
|
||||||
|
# - libwebkit2gtk-4.1-dev: WebKit2GTK 4.1 (Wails 3 要求)
|
||||||
|
# - libayatana-appindicator3-dev: 系统托盘支持
|
||||||
|
# - librsvg2-dev: SVG 图标支持
|
||||||
|
# - patchelf: 修改 ELF 二进制文件
|
||||||
|
# - libx11-dev: X11 库 (热键服务依赖)
|
||||||
|
# - rpm: RPM 打包工具
|
||||||
|
# - fuse: AppImage 运行依赖
|
||||||
|
# - file: 文件类型检测工具
|
||||||
|
|
||||||
|
# Windows 平台依赖
|
||||||
|
- name: 设置 Windows 构建环境
|
||||||
|
if: matrix.os == 'windows'
|
||||||
|
run: |
|
||||||
|
# 安装 NSIS (用于创建安装程序)
|
||||||
|
choco install nsis -y
|
||||||
|
# 将 NSIS 添加到 PATH
|
||||||
|
echo "C:\Program Files (x86)\NSIS" >> $GITHUB_PATH
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
# macOS 平台依赖
|
||||||
|
- name: 设置 macOS 构建环境
|
||||||
|
if: matrix.os == 'darwin'
|
||||||
|
run: |
|
||||||
|
# Xcode 命令行工具通常已安装
|
||||||
|
xcode-select --install 2>/dev/null || true
|
||||||
|
|
||||||
|
# 安装 Wails CLI
|
||||||
|
- name: 安装 Wails CLI
|
||||||
|
run: go install github.com/wailsapp/wails/v3/cmd/wails3@latest
|
||||||
|
|
||||||
|
# 安装前端依赖
|
||||||
|
- name: 安装前端依赖
|
||||||
|
working-directory: frontend
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
# 构建前端
|
||||||
|
- name: 构建前端
|
||||||
|
working-directory: frontend
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
# 使用 Wails Task 构建和打包应用
|
||||||
|
- name: 构建和打包 Wails 应用
|
||||||
|
run: wails3 task ${{ matrix.id }}:package PRODUCTION=true ARCH=${{ matrix.arch }}
|
||||||
|
env:
|
||||||
|
CGO_ENABLED: 1
|
||||||
|
APP_NAME: voidraft
|
||||||
|
BIN_DIR: bin
|
||||||
|
ROOT_DIR: .
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
# 整理构建产物
|
||||||
|
- name: 整理构建产物
|
||||||
|
id: organize_artifacts
|
||||||
|
run: |
|
||||||
|
echo "=== 构建产物列表 ==="
|
||||||
|
ls -lhR bin/ || echo "bin 目录不存在"
|
||||||
|
|
||||||
|
# 创建输出目录
|
||||||
|
mkdir -p artifacts
|
||||||
|
|
||||||
|
# 根据平台复制产物
|
||||||
|
if [ "${{ matrix.os }}" = "windows" ]; then
|
||||||
|
echo "Windows 平台:查找 NSIS 安装程序"
|
||||||
|
find . -name "*.exe" -type f
|
||||||
|
cp bin/*.exe artifacts/ 2>/dev/null || echo "未找到 .exe 文件"
|
||||||
|
|
||||||
|
elif [ "${{ matrix.os }}" = "linux" ]; then
|
||||||
|
echo "Linux 平台:查找 AppImage, deb, rpm, archlinux 包"
|
||||||
|
find bin -type f
|
||||||
|
cp bin/*.AppImage artifacts/ 2>/dev/null || echo "未找到 AppImage"
|
||||||
|
cp bin/*.deb artifacts/ 2>/dev/null || echo "未找到 deb"
|
||||||
|
cp bin/*.rpm artifacts/ 2>/dev/null || echo "未找到 rpm"
|
||||||
|
cp bin/*.pkg.tar.zst artifacts/ 2>/dev/null || echo "未找到 archlinux 包"
|
||||||
|
|
||||||
|
elif [ "${{ matrix.os }}" = "darwin" ]; then
|
||||||
|
echo "macOS 平台:查找 .app bundle"
|
||||||
|
find bin -name "*.app" -type d
|
||||||
|
# macOS: .app bundle,打包成 zip
|
||||||
|
if [ -d "bin/voidraft.app" ]; then
|
||||||
|
cd bin
|
||||||
|
zip -r ../artifacts/voidraft-darwin-${{ matrix.arch }}.app.zip voidraft.app
|
||||||
|
cd ..
|
||||||
|
else
|
||||||
|
echo "未找到 .app bundle"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== 最终产物 ==="
|
||||||
|
ls -lh artifacts/ || echo "artifacts 目录为空"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
# 上传构建产物到 Artifacts
|
||||||
|
- name: 上传构建产物
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: voidraft-${{ matrix.id }}
|
||||||
|
path: artifacts/*
|
||||||
|
if-no-files-found: warn
|
||||||
|
|
||||||
|
# 创建 GitHub Release 并上传所有构建产物
|
||||||
|
release:
|
||||||
|
needs: [prepare, build]
|
||||||
|
if: ${{ needs.prepare.outputs.should_release == 'true' }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: 检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 下载所有构建产物
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: artifacts
|
||||||
|
|
||||||
|
- name: 显示下载的文件
|
||||||
|
run: |
|
||||||
|
echo "下载的构建产物:"
|
||||||
|
ls -R artifacts/
|
||||||
|
|
||||||
|
- name: 准备 Release 文件
|
||||||
|
run: |
|
||||||
|
mkdir -p release
|
||||||
|
find artifacts -type f -exec cp {} release/ \;
|
||||||
|
ls -lh release/
|
||||||
|
|
||||||
|
- name: 生成 Release 说明
|
||||||
|
id: release_notes
|
||||||
|
run: |
|
||||||
|
# 获取版本号
|
||||||
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||||
|
VERSION="${{ github.sha }}"
|
||||||
|
VERSION_NAME="测试构建 ${VERSION:0:7}"
|
||||||
|
else
|
||||||
|
VERSION="${{ github.ref_name }}"
|
||||||
|
VERSION_NAME="${VERSION}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > release_notes.md << EOF
|
||||||
|
## Voidraft ${VERSION_NAME}
|
||||||
|
|
||||||
|
### 📦 下载
|
||||||
|
|
||||||
|
根据你的操作系统选择对应的版本:
|
||||||
|
|
||||||
|
- **Windows (64位)**: \`voidraft-windows-amd64.exe\`
|
||||||
|
- **Linux (64位)**: \`voidraft-linux-amd64\`
|
||||||
|
- **macOS (Intel)**: \`voidraft-darwin-amd64.zip\`
|
||||||
|
- **macOS (Apple Silicon)**: \`voidraft-darwin-arm64.zip\`
|
||||||
|
|
||||||
|
### 📝 更新内容
|
||||||
|
|
||||||
|
请查看 [提交历史](../../commits/${{ github.ref_name }}) 了解本次更新的详细内容。
|
||||||
|
|
||||||
|
### 💡 使用说明
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
1. 下载 `voidraft-windows-amd64.exe`
|
||||||
|
2. 直接运行即可
|
||||||
|
|
||||||
|
#### Linux
|
||||||
|
1. 下载 `voidraft-linux-amd64`
|
||||||
|
2. 添加执行权限:`chmod +x voidraft-linux-amd64`
|
||||||
|
3. 运行:`./voidraft-linux-amd64`
|
||||||
|
|
||||||
|
#### macOS
|
||||||
|
1. 下载对应架构的 zip 文件
|
||||||
|
2. 解压后运行
|
||||||
|
3. 如果提示无法打开,请在 系统偏好设置 > 安全性与隐私 中允许运行
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
构建时间: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: 创建 GitHub Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
files: release/*
|
||||||
|
body_path: release_notes.md
|
||||||
|
draft: false
|
||||||
|
prerelease: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
|
tag_name: ${{ github.event_name == 'workflow_dispatch' && format('test-{0}', github.sha) || github.ref_name }}
|
||||||
|
name: ${{ github.event_name == 'workflow_dispatch' && format('测试构建 {0}', github.sha) || github.ref_name }}
|
||||||
|
generate_release_notes: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
109
.github/workflows/codeql.yml
vendored
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL Advanced"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "master" ]
|
||||||
|
schedule:
|
||||||
|
- cron: '29 8 * * 3'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze (${{ matrix.language }})
|
||||||
|
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||||
|
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||||
|
# - https://gh.io/supported-runners-and-hardware-resources
|
||||||
|
# - https://gh.io/using-larger-runners (GitHub.com only)
|
||||||
|
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
||||||
|
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||||
|
permissions:
|
||||||
|
# required for all workflows
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
# required to fetch internal or private CodeQL packs
|
||||||
|
packages: read
|
||||||
|
|
||||||
|
# only required for workflows in private repositories
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- language: actions
|
||||||
|
build-mode: none
|
||||||
|
- language: c-cpp
|
||||||
|
build-mode: none
|
||||||
|
- language: go
|
||||||
|
build-mode: autobuild
|
||||||
|
- language: javascript-typescript
|
||||||
|
build-mode: none
|
||||||
|
- language: python
|
||||||
|
build-mode: none
|
||||||
|
- language: rust
|
||||||
|
build-mode: none
|
||||||
|
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
|
||||||
|
# Use `c-cpp` to analyze code written in C, C++ or both
|
||||||
|
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||||
|
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||||
|
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
|
||||||
|
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
|
||||||
|
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
|
||||||
|
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Add any setup steps before running the `github/codeql-action/init` action.
|
||||||
|
# This includes steps like installing compilers or runtimes (`actions/setup-node`
|
||||||
|
# or others). This is typically only required for manual builds.
|
||||||
|
# - name: Setup runtime (example)
|
||||||
|
# uses: actions/setup-example@v1
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v4
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
build-mode: ${{ matrix.build-mode }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
|
||||||
|
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||||
|
# queries: security-extended,security-and-quality
|
||||||
|
|
||||||
|
# If the analyze step fails for one of the languages you are analyzing with
|
||||||
|
# "We were unable to automatically build your code", modify the matrix above
|
||||||
|
# to set the build mode to "manual" for that language. Then modify this step
|
||||||
|
# to build your code.
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
|
- name: Run manual build steps
|
||||||
|
if: matrix.build-mode == 'manual'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo 'If you are using a "manual" build mode for one or more of the' \
|
||||||
|
'languages you are analyzing, replace this with the commands to build' \
|
||||||
|
'your code, for example:'
|
||||||
|
echo ' make bootstrap'
|
||||||
|
echo ' make release'
|
||||||
|
exit 1
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v4
|
||||||
|
with:
|
||||||
|
category: "/language:${{matrix.language}}"
|
||||||
12
Taskfile.yml
@@ -12,25 +12,13 @@ vars:
|
|||||||
VITE_PORT: '{{.WAILS_VITE_PORT | default 9245}}'
|
VITE_PORT: '{{.WAILS_VITE_PORT | default 9245}}'
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
version:
|
|
||||||
summary: Generate version information
|
|
||||||
cmds:
|
|
||||||
- '{{if eq OS "windows"}}cmd /c ".\scripts\version.bat"{{else}}bash ./scripts/version.sh{{end}}'
|
|
||||||
sources:
|
|
||||||
- scripts/version.bat
|
|
||||||
- scripts/version.sh
|
|
||||||
generates:
|
|
||||||
- version.txt
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
summary: Builds the application
|
summary: Builds the application
|
||||||
deps: [version]
|
|
||||||
cmds:
|
cmds:
|
||||||
- task: "{{OS}}:build"
|
- task: "{{OS}}:build"
|
||||||
|
|
||||||
package:
|
package:
|
||||||
summary: Packages a production build of the application
|
summary: Packages a production build of the application
|
||||||
deps: [version]
|
|
||||||
cmds:
|
cmds:
|
||||||
- task: "{{OS}}:package"
|
- task: "{{OS}}:package"
|
||||||
|
|
||||||
|
|||||||
293
build/COMMANDS.md
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
# Wails 3 命令参考表
|
||||||
|
|
||||||
|
本文档列出了 Voidraft 项目中使用的所有 Wails 3 命令和参数。
|
||||||
|
|
||||||
|
## 📋 命令总览
|
||||||
|
|
||||||
|
| 类别 | 命令 | 用途 |
|
||||||
|
|------|------|------|
|
||||||
|
| 生成工具 | `wails3 generate` | 生成项目所需的各种资源文件 |
|
||||||
|
| 打包工具 | `wails3 tool package` | 使用 nfpm 打包应用程序 |
|
||||||
|
| 任务执行 | `wails3 task` | 执行 Taskfile.yml 中定义的任务 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 详细命令参数
|
||||||
|
|
||||||
|
### 1. `wails3 generate bindings`
|
||||||
|
**生成 TypeScript 绑定文件**
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-f` | 构建标志 | `''` (空字符串) |
|
||||||
|
| `-clean` | 清理旧绑定 | `true` |
|
||||||
|
| `-ts` | 生成 TypeScript | 无需值 |
|
||||||
|
|
||||||
|
**使用位置:** `build/Taskfile.yml:53`
|
||||||
|
|
||||||
|
**完整命令:**
|
||||||
|
```bash
|
||||||
|
wails3 generate bindings -f '' -clean=true -ts
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. `wails3 generate icons`
|
||||||
|
**从单个图片生成多平台图标**
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-input` | 输入图片路径 | `appicon.png` |
|
||||||
|
| `-macfilename` | macOS 图标输出路径 | `darwin/icons.icns` |
|
||||||
|
| `-windowsfilename` | Windows 图标输出路径 | `windows/icons.ico` |
|
||||||
|
|
||||||
|
**使用位置:** `build/Taskfile.yml:64`
|
||||||
|
|
||||||
|
**完整命令:**
|
||||||
|
```bash
|
||||||
|
wails3 generate icons \
|
||||||
|
-input appicon.png \
|
||||||
|
-macfilename darwin/icons.icns \
|
||||||
|
-windowsfilename windows/icons.ico
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. `wails3 generate syso`
|
||||||
|
**生成 Windows .syso 资源文件**
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-arch` | 目标架构 | `amd64` / `arm64` |
|
||||||
|
| `-icon` | 图标文件 | `windows/icon.ico` |
|
||||||
|
| `-manifest` | 清单文件 | `windows/wails.exe.manifest` |
|
||||||
|
| `-info` | 应用信息 JSON | `windows/info.json` |
|
||||||
|
| `-out` | 输出文件路径 | `../wails_windows_amd64.syso` |
|
||||||
|
|
||||||
|
**使用位置:** `build/windows/Taskfile.yml:42`
|
||||||
|
|
||||||
|
**完整命令:**
|
||||||
|
```bash
|
||||||
|
wails3 generate syso \
|
||||||
|
-arch amd64 \
|
||||||
|
-icon windows/icon.ico \
|
||||||
|
-manifest windows/wails.exe.manifest \
|
||||||
|
-info windows/info.json \
|
||||||
|
-out ../wails_windows_amd64.syso
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. `wails3 generate webview2bootstrapper`
|
||||||
|
**生成 Windows WebView2 引导程序**
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-dir` | 输出目录 | `build/windows/nsis` |
|
||||||
|
|
||||||
|
**使用位置:** `build/windows/Taskfile.yml:55`
|
||||||
|
|
||||||
|
**完整命令:**
|
||||||
|
```bash
|
||||||
|
wails3 generate webview2bootstrapper -dir "build/windows/nsis"
|
||||||
|
```
|
||||||
|
|
||||||
|
**说明:** 下载 Microsoft Edge WebView2 运行时安装程序,用于 NSIS 打包。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5. `wails3 generate .desktop`
|
||||||
|
**生成 Linux .desktop 桌面文件**
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-name` | 应用名称 | `voidraft` |
|
||||||
|
| `-exec` | 可执行文件名 | `voidraft` |
|
||||||
|
| `-icon` | 图标名称 | `appicon` |
|
||||||
|
| `-outputfile` | 输出文件路径 | `build/linux/voidraft.desktop` |
|
||||||
|
| `-categories` | 应用分类 | `Development;` |
|
||||||
|
|
||||||
|
**使用位置:** `build/linux/Taskfile.yml:107`
|
||||||
|
|
||||||
|
**完整命令:**
|
||||||
|
```bash
|
||||||
|
wails3 generate .desktop \
|
||||||
|
-name "voidraft" \
|
||||||
|
-exec "voidraft" \
|
||||||
|
-icon "appicon" \
|
||||||
|
-outputfile build/linux/voidraft.desktop \
|
||||||
|
-categories "Development;"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6. `wails3 generate appimage`
|
||||||
|
**生成 Linux AppImage 包**
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-binary` | 二进制文件名 | `voidraft` |
|
||||||
|
| `-icon` | 图标文件路径 | `../../appicon.png` |
|
||||||
|
| `-desktopfile` | .desktop 文件路径 | `../voidraft.desktop` |
|
||||||
|
| `-outputdir` | 输出目录 | `../../../bin` |
|
||||||
|
| `-builddir` | 构建临时目录 | `build/linux/appimage/build` |
|
||||||
|
|
||||||
|
**使用位置:** `build/linux/Taskfile.yml:49`
|
||||||
|
|
||||||
|
**完整命令:**
|
||||||
|
```bash
|
||||||
|
wails3 generate appimage \
|
||||||
|
-binary voidraft \
|
||||||
|
-icon ../../appicon.png \
|
||||||
|
-desktopfile ../voidraft.desktop \
|
||||||
|
-outputdir ../../../bin \
|
||||||
|
-builddir build/linux/appimage/build
|
||||||
|
```
|
||||||
|
|
||||||
|
**说明:** 自动下载 linuxdeploy 工具并创建 AppImage。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7. `wails3 tool package` (deb)
|
||||||
|
**创建 Debian/Ubuntu .deb 包**
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-name` | 包名称 | `voidraft` |
|
||||||
|
| `-format` | 包格式 | `deb` |
|
||||||
|
| `-config` | nfpm 配置文件 | `./build/linux/nfpm/nfpm.yaml` |
|
||||||
|
| `-out` | 输出目录 | `./bin` |
|
||||||
|
|
||||||
|
**使用位置:** `build/linux/Taskfile.yml:90`
|
||||||
|
|
||||||
|
**完整命令:**
|
||||||
|
```bash
|
||||||
|
wails3 tool package \
|
||||||
|
-name voidraft \
|
||||||
|
-format deb \
|
||||||
|
-config ./build/linux/nfpm/nfpm.yaml \
|
||||||
|
-out ./bin
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 8. `wails3 tool package` (rpm)
|
||||||
|
**创建 RedHat/CentOS/Fedora .rpm 包**
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-name` | 包名称 | `voidraft` |
|
||||||
|
| `-format` | 包格式 | `rpm` |
|
||||||
|
| `-config` | nfpm 配置文件 | `./build/linux/nfpm/nfpm.yaml` |
|
||||||
|
| `-out` | 输出目录 | `./bin` |
|
||||||
|
|
||||||
|
**使用位置:** `build/linux/Taskfile.yml:95`
|
||||||
|
|
||||||
|
**完整命令:**
|
||||||
|
```bash
|
||||||
|
wails3 tool package \
|
||||||
|
-name voidraft \
|
||||||
|
-format rpm \
|
||||||
|
-config ./build/linux/nfpm/nfpm.yaml \
|
||||||
|
-out ./bin
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 9. `wails3 tool package` (archlinux)
|
||||||
|
**创建 Arch Linux .pkg.tar.zst 包**
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `-name` | 包名称 | `voidraft` |
|
||||||
|
| `-format` | 包格式 | `archlinux` |
|
||||||
|
| `-config` | nfpm 配置文件 | `./build/linux/nfpm/nfpm.yaml` |
|
||||||
|
| `-out` | 输出目录 | `./bin` |
|
||||||
|
|
||||||
|
**使用位置:** `build/linux/Taskfile.yml:100`
|
||||||
|
|
||||||
|
**完整命令:**
|
||||||
|
```bash
|
||||||
|
wails3 tool package \
|
||||||
|
-name voidraft \
|
||||||
|
-format archlinux \
|
||||||
|
-config ./build/linux/nfpm/nfpm.yaml \
|
||||||
|
-out ./bin
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 10. `wails3 task`
|
||||||
|
**执行 Taskfile.yml 中定义的任务**
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `[taskname]` | 任务名称 | `build`, `package`, `run` |
|
||||||
|
| `[VAR=value]` | 变量赋值 | `PRODUCTION=true`, `ARCH=amd64` |
|
||||||
|
|
||||||
|
**常用任务:**
|
||||||
|
|
||||||
|
| 任务 | 说明 | 命令 |
|
||||||
|
|------|------|------|
|
||||||
|
| `build` | 构建应用 | `wails3 task build PRODUCTION=true` |
|
||||||
|
| `package` | 打包应用 | `wails3 task package` |
|
||||||
|
| `run` | 运行应用 | `wails3 task run` |
|
||||||
|
|
||||||
|
**使用位置:** `build/config.yml`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 平台对应命令表
|
||||||
|
|
||||||
|
| 平台 | 主要命令 | 产物 |
|
||||||
|
|------|----------|------|
|
||||||
|
| **Windows** | `generate syso`<br>`generate webview2bootstrapper` | `.syso` 资源文件<br>NSIS 安装程序 |
|
||||||
|
| **Linux** | `generate .desktop`<br>`generate appimage`<br>`tool package -format deb/rpm/archlinux` | `.desktop` 文件<br>`.AppImage`<br>`.deb` / `.rpm` / `.pkg.tar.zst` |
|
||||||
|
| **macOS** | `generate icons` | `.icns` 图标<br>`.app` 应用包 |
|
||||||
|
| **通用** | `generate bindings`<br>`generate icons` | TypeScript 绑定<br>多平台图标 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 快速参考
|
||||||
|
|
||||||
|
### 完整构建流程
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 生成绑定和图标
|
||||||
|
wails3 task common:generate:bindings
|
||||||
|
wails3 task common:generate:icons
|
||||||
|
|
||||||
|
# 2. 构建前端
|
||||||
|
cd frontend
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# 3. 构建应用(各平台)
|
||||||
|
cd build/windows && wails3 task build PRODUCTION=true # Windows
|
||||||
|
cd build/linux && wails3 task build PRODUCTION=true # Linux
|
||||||
|
cd build/darwin && wails3 task build PRODUCTION=true # macOS
|
||||||
|
|
||||||
|
# 4. 打包应用(各平台)
|
||||||
|
cd build/windows && wails3 task package # NSIS 安装程序
|
||||||
|
cd build/linux && wails3 task package # AppImage + deb + rpm + archlinux
|
||||||
|
cd build/darwin && wails3 task package # .app bundle
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 注意事项
|
||||||
|
|
||||||
|
1. **变量传递:** Task 命令支持通过 `VAR=value` 格式传递变量
|
||||||
|
2. **路径问题:** 相对路径基于 Taskfile.yml 所在目录
|
||||||
|
3. **依赖顺序:** 某些任务有依赖关系(通过 `deps:` 定义)
|
||||||
|
4. **环境变量:** 使用 `env:` 定义的环境变量会自动设置
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 相关文档
|
||||||
|
|
||||||
|
- [Wails 3 官方文档](https://v3alpha.wails.io/)
|
||||||
|
- [Taskfile 语法](https://taskfile.dev/)
|
||||||
|
- [nfpm 打包工具](https://nfpm.goreleaser.com/)
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 6.9 KiB |
@@ -39,7 +39,7 @@ tasks:
|
|||||||
summary: Generates Windows `.syso` file
|
summary: Generates Windows `.syso` file
|
||||||
dir: build
|
dir: build
|
||||||
cmds:
|
cmds:
|
||||||
- wails3 generate syso -arch {{.ARCH}} -icon windows/favicon_256x256.ico -manifest windows/wails.exe.manifest -info windows/info.json -out ../wails_windows_{{.ARCH}}.syso
|
- wails3 generate syso -arch {{.ARCH}} -icon windows/icon.ico -manifest windows/wails.exe.manifest -info windows/info.json -out ../wails_windows_{{.ARCH}}.syso
|
||||||
vars:
|
vars:
|
||||||
ARCH: '{{.ARCH | default ARCH}}'
|
ARCH: '{{.ARCH | default ARCH}}'
|
||||||
|
|
||||||
|
|||||||
@@ -61,20 +61,3 @@ export class ServiceOptions {
|
|||||||
return new ServiceOptions($$parsedSource as Partial<ServiceOptions>);
|
return new ServiceOptions($$parsedSource as Partial<ServiceOptions>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WebviewWindow {
|
|
||||||
|
|
||||||
/** Creates a new WebviewWindow instance. */
|
|
||||||
constructor($$source: Partial<WebviewWindow> = {}) {
|
|
||||||
|
|
||||||
Object.assign(this, $$source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new WebviewWindow instance from a string or object.
|
|
||||||
*/
|
|
||||||
static createFrom($$source: any = {}): WebviewWindow {
|
|
||||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
|
||||||
return new WebviewWindow($$parsedSource as Partial<WebviewWindow>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
export * from "./models.js";
|
||||||
17
frontend/bindings/voidraft/internal/common/helper/models.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CancelFunc 取消订阅函数
|
||||||
|
* 调用此函数可以取消对配置的监听
|
||||||
|
*/
|
||||||
|
export type CancelFunc = any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ObserverCallback 观察者回调函数
|
||||||
|
*/
|
||||||
|
export type ObserverCallback = any;
|
||||||
4
frontend/bindings/voidraft/internal/models/ent/index.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
export * from "./models.js";
|
||||||
370
frontend/bindings/voidraft/internal/models/ent/models.ts
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as theme$0 from "./theme/models.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Document is the model entity for the Document schema.
|
||||||
|
*/
|
||||||
|
export class Document {
|
||||||
|
/**
|
||||||
|
* ID of the ent.
|
||||||
|
*/
|
||||||
|
"id"?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UUID for cross-device sync (UUIDv7)
|
||||||
|
*/
|
||||||
|
"uuid": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creation time
|
||||||
|
*/
|
||||||
|
"created_at": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update time
|
||||||
|
*/
|
||||||
|
"updated_at": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deleted at
|
||||||
|
*/
|
||||||
|
"deleted_at"?: string | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* document title
|
||||||
|
*/
|
||||||
|
"title": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* document content
|
||||||
|
*/
|
||||||
|
"content": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* document locked status
|
||||||
|
*/
|
||||||
|
"locked": boolean;
|
||||||
|
|
||||||
|
/** Creates a new Document instance. */
|
||||||
|
constructor($$source: Partial<Document> = {}) {
|
||||||
|
if (!("uuid" in $$source)) {
|
||||||
|
this["uuid"] = "";
|
||||||
|
}
|
||||||
|
if (!("created_at" in $$source)) {
|
||||||
|
this["created_at"] = "";
|
||||||
|
}
|
||||||
|
if (!("updated_at" in $$source)) {
|
||||||
|
this["updated_at"] = "";
|
||||||
|
}
|
||||||
|
if (!("title" in $$source)) {
|
||||||
|
this["title"] = "";
|
||||||
|
}
|
||||||
|
if (!("content" in $$source)) {
|
||||||
|
this["content"] = "";
|
||||||
|
}
|
||||||
|
if (!("locked" in $$source)) {
|
||||||
|
this["locked"] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Document instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): Document {
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
return new Document($$parsedSource as Partial<Document>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension is the model entity for the Extension schema.
|
||||||
|
*/
|
||||||
|
export class Extension {
|
||||||
|
/**
|
||||||
|
* ID of the ent.
|
||||||
|
*/
|
||||||
|
"id"?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UUID for cross-device sync (UUIDv7)
|
||||||
|
*/
|
||||||
|
"uuid": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creation time
|
||||||
|
*/
|
||||||
|
"created_at": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update time
|
||||||
|
*/
|
||||||
|
"updated_at": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deleted at
|
||||||
|
*/
|
||||||
|
"deleted_at"?: string | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extension name
|
||||||
|
*/
|
||||||
|
"name": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extension enabled or not
|
||||||
|
*/
|
||||||
|
"enabled": boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extension config
|
||||||
|
*/
|
||||||
|
"config": { [_: string]: any };
|
||||||
|
|
||||||
|
/** Creates a new Extension instance. */
|
||||||
|
constructor($$source: Partial<Extension> = {}) {
|
||||||
|
if (!("uuid" in $$source)) {
|
||||||
|
this["uuid"] = "";
|
||||||
|
}
|
||||||
|
if (!("created_at" in $$source)) {
|
||||||
|
this["created_at"] = "";
|
||||||
|
}
|
||||||
|
if (!("updated_at" in $$source)) {
|
||||||
|
this["updated_at"] = "";
|
||||||
|
}
|
||||||
|
if (!("name" in $$source)) {
|
||||||
|
this["name"] = "";
|
||||||
|
}
|
||||||
|
if (!("enabled" in $$source)) {
|
||||||
|
this["enabled"] = false;
|
||||||
|
}
|
||||||
|
if (!("config" in $$source)) {
|
||||||
|
this["config"] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Extension instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): Extension {
|
||||||
|
const $$createField7_0 = $$createType0;
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
if ("config" in $$parsedSource) {
|
||||||
|
$$parsedSource["config"] = $$createField7_0($$parsedSource["config"]);
|
||||||
|
}
|
||||||
|
return new Extension($$parsedSource as Partial<Extension>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KeyBinding is the model entity for the KeyBinding schema.
|
||||||
|
*/
|
||||||
|
export class KeyBinding {
|
||||||
|
/**
|
||||||
|
* ID of the ent.
|
||||||
|
*/
|
||||||
|
"id"?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UUID for cross-device sync (UUIDv7)
|
||||||
|
*/
|
||||||
|
"uuid": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creation time
|
||||||
|
*/
|
||||||
|
"created_at": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update time
|
||||||
|
*/
|
||||||
|
"updated_at": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deleted at
|
||||||
|
*/
|
||||||
|
"deleted_at"?: string | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* command identifier
|
||||||
|
*/
|
||||||
|
"name": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keybinding type: standard or emacs
|
||||||
|
*/
|
||||||
|
"type": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* universal keybinding (cross-platform)
|
||||||
|
*/
|
||||||
|
"key"?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* macOS specific keybinding
|
||||||
|
*/
|
||||||
|
"macos"?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows specific keybinding
|
||||||
|
*/
|
||||||
|
"windows"?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linux specific keybinding
|
||||||
|
*/
|
||||||
|
"linux"?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extension name (functional category)
|
||||||
|
*/
|
||||||
|
"extension": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whether this keybinding is enabled
|
||||||
|
*/
|
||||||
|
"enabled": boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* prevent browser default behavior
|
||||||
|
*/
|
||||||
|
"preventDefault": boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keybinding scope (default: editor)
|
||||||
|
*/
|
||||||
|
"scope"?: string;
|
||||||
|
|
||||||
|
/** Creates a new KeyBinding instance. */
|
||||||
|
constructor($$source: Partial<KeyBinding> = {}) {
|
||||||
|
if (!("uuid" in $$source)) {
|
||||||
|
this["uuid"] = "";
|
||||||
|
}
|
||||||
|
if (!("created_at" in $$source)) {
|
||||||
|
this["created_at"] = "";
|
||||||
|
}
|
||||||
|
if (!("updated_at" in $$source)) {
|
||||||
|
this["updated_at"] = "";
|
||||||
|
}
|
||||||
|
if (!("name" in $$source)) {
|
||||||
|
this["name"] = "";
|
||||||
|
}
|
||||||
|
if (!("type" in $$source)) {
|
||||||
|
this["type"] = "";
|
||||||
|
}
|
||||||
|
if (!("extension" in $$source)) {
|
||||||
|
this["extension"] = "";
|
||||||
|
}
|
||||||
|
if (!("enabled" in $$source)) {
|
||||||
|
this["enabled"] = false;
|
||||||
|
}
|
||||||
|
if (!("preventDefault" in $$source)) {
|
||||||
|
this["preventDefault"] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new KeyBinding instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): KeyBinding {
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
return new KeyBinding($$parsedSource as Partial<KeyBinding>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme is the model entity for the Theme schema.
|
||||||
|
*/
|
||||||
|
export class Theme {
|
||||||
|
/**
|
||||||
|
* ID of the ent.
|
||||||
|
*/
|
||||||
|
"id"?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UUID for cross-device sync (UUIDv7)
|
||||||
|
*/
|
||||||
|
"uuid": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creation time
|
||||||
|
*/
|
||||||
|
"created_at": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update time
|
||||||
|
*/
|
||||||
|
"updated_at": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deleted at
|
||||||
|
*/
|
||||||
|
"deleted_at"?: string | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* theme name
|
||||||
|
*/
|
||||||
|
"name": string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* theme type
|
||||||
|
*/
|
||||||
|
"type": theme$0.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* theme colors
|
||||||
|
*/
|
||||||
|
"colors": { [_: string]: any };
|
||||||
|
|
||||||
|
/** Creates a new Theme instance. */
|
||||||
|
constructor($$source: Partial<Theme> = {}) {
|
||||||
|
if (!("uuid" in $$source)) {
|
||||||
|
this["uuid"] = "";
|
||||||
|
}
|
||||||
|
if (!("created_at" in $$source)) {
|
||||||
|
this["created_at"] = "";
|
||||||
|
}
|
||||||
|
if (!("updated_at" in $$source)) {
|
||||||
|
this["updated_at"] = "";
|
||||||
|
}
|
||||||
|
if (!("name" in $$source)) {
|
||||||
|
this["name"] = "";
|
||||||
|
}
|
||||||
|
if (!("type" in $$source)) {
|
||||||
|
this["type"] = ("" as theme$0.Type);
|
||||||
|
}
|
||||||
|
if (!("colors" in $$source)) {
|
||||||
|
this["colors"] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(this, $$source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Theme instance from a string or object.
|
||||||
|
*/
|
||||||
|
static createFrom($$source: any = {}): Theme {
|
||||||
|
const $$createField7_0 = $$createType0;
|
||||||
|
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||||
|
if ("colors" in $$parsedSource) {
|
||||||
|
$$parsedSource["colors"] = $$createField7_0($$parsedSource["colors"]);
|
||||||
|
}
|
||||||
|
return new Theme($$parsedSource as Partial<Theme>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private type creation functions
|
||||||
|
const $$createType0 = $Create.Map($Create.Any, $Create.Any);
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
export * from "./models.js";
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import {Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type defines the type for the "type" enum field.
|
||||||
|
*/
|
||||||
|
export enum Type {
|
||||||
|
/**
|
||||||
|
* The Go zero value for the underlying type of the enum.
|
||||||
|
*/
|
||||||
|
$zero = "",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type values.
|
||||||
|
*/
|
||||||
|
TypeDark = "dark",
|
||||||
|
TypeLight = "light",
|
||||||
|
};
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BackupService 提供基于Git的备份功能
|
* BackupService 提供基于Git的备份同步功能
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/applic
|
|||||||
import * as models$0 from "../models/models.js";
|
import * as models$0 from "../models/models.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HandleConfigChange 处理备份配置变更
|
* HandleConfigChange 处理配置变更
|
||||||
*/
|
*/
|
||||||
export function HandleConfigChange(config: models$0.GitBackupConfig | null): Promise<void> & { cancel(): void } {
|
export function HandleConfigChange(config: models$0.GitBackupConfig | null): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(395287784, config) as any;
|
let $resultPromise = $Call.ByID(395287784, config) as any;
|
||||||
@@ -34,15 +34,7 @@ export function Initialize(): Promise<void> & { cancel(): void } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PushToRemote 推送本地更改到远程仓库
|
* Reinitialize 重新初始化
|
||||||
*/
|
|
||||||
export function PushToRemote(): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(262644139) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reinitialize 重新初始化备份服务,用于响应配置变更
|
|
||||||
*/
|
*/
|
||||||
export function Reinitialize(): Promise<void> & { cancel(): void } {
|
export function Reinitialize(): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(301562543) as any;
|
let $resultPromise = $Call.ByID(301562543) as any;
|
||||||
@@ -50,7 +42,7 @@ export function Reinitialize(): Promise<void> & { cancel(): void } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServiceShutdown 服务关闭时的清理工作
|
* ServiceShutdown 服务关闭
|
||||||
*/
|
*/
|
||||||
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(422131801) as any;
|
let $resultPromise = $Call.ByID(422131801) as any;
|
||||||
@@ -63,7 +55,7 @@ export function ServiceStartup(options: application$0.ServiceOptions): Promise<v
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StartAutoBackup 启动自动备份定时器
|
* StartAutoBackup 启动自动备份
|
||||||
*/
|
*/
|
||||||
export function StartAutoBackup(): Promise<void> & { cancel(): void } {
|
export function StartAutoBackup(): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3035755449) as any;
|
let $resultPromise = $Call.ByID(3035755449) as any;
|
||||||
@@ -77,3 +69,11 @@ export function StopAutoBackup(): Promise<void> & { cancel(): void } {
|
|||||||
let $resultPromise = $Call.ByID(2641894021) as any;
|
let $resultPromise = $Call.ByID(2641894021) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync 执行完整的同步流程:导出 -> commit -> pull -> 解决冲突 -> push -> 导入
|
||||||
|
*/
|
||||||
|
export function Sync(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3420383211) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,12 @@
|
|||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as helper$0 from "../common/helper/models.js";
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import * as models$0 from "../models/models.js";
|
import * as models$0 from "../models/models.js";
|
||||||
@@ -34,22 +40,6 @@ export function GetConfig(): Promise<models$0.AppConfig | null> & { cancel(): vo
|
|||||||
return $typingPromise;
|
return $typingPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* GetConfigDir 获取配置目录
|
|
||||||
*/
|
|
||||||
export function GetConfigDir(): Promise<string> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(2275626561) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GetSettingsPath 获取设置文件路径
|
|
||||||
*/
|
|
||||||
export function GetSettingsPath(): Promise<string> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(2175583370) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MigrateConfig 执行配置迁移
|
* MigrateConfig 执行配置迁移
|
||||||
*/
|
*/
|
||||||
@@ -59,7 +49,7 @@ export function MigrateConfig(): Promise<void> & { cancel(): void } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ResetConfig 强制重置所有配置为默认值
|
* ResetConfig 重置所有配置为默认值
|
||||||
*/
|
*/
|
||||||
export function ResetConfig(): Promise<void> & { cancel(): void } {
|
export function ResetConfig(): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3593047389) as any;
|
let $resultPromise = $Call.ByID(3593047389) as any;
|
||||||
@@ -74,6 +64,14 @@ export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
|||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceStartup 服务启动时初始化
|
||||||
|
*/
|
||||||
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3311949428, options) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set 设置配置项
|
* Set 设置配置项
|
||||||
*/
|
*/
|
||||||
@@ -83,34 +81,18 @@ export function Set(key: string, value: any): Promise<void> & { cancel(): void }
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SetBackupConfigChangeCallback 设置备份配置变更回调
|
* Watch 注册配置变更监听器
|
||||||
*/
|
*/
|
||||||
export function SetBackupConfigChangeCallback(callback: any): Promise<void> & { cancel(): void } {
|
export function Watch(path: string, callback: helper$0.ObserverCallback): Promise<helper$0.CancelFunc> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3264871659, callback) as any;
|
let $resultPromise = $Call.ByID(1143583035, path, callback) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SetDataPathChangeCallback 设置数据路径配置变更回调
|
* WatchWithContext 使用 Context 注册监听器
|
||||||
*/
|
*/
|
||||||
export function SetDataPathChangeCallback(callback: any): Promise<void> & { cancel(): void } {
|
export function WatchWithContext(path: string, callback: helper$0.ObserverCallback): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(393017412, callback) as any;
|
let $resultPromise = $Call.ByID(1454973098, path, callback) as any;
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SetHotkeyChangeCallback 设置热键配置变更回调
|
|
||||||
*/
|
|
||||||
export function SetHotkeyChangeCallback(callback: any): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(283872321, callback) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SetWindowSnapConfigChangeCallback 设置窗口吸附配置变更回调
|
|
||||||
*/
|
|
||||||
export function SetWindowSnapConfigChangeCallback(callback: any): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(2324961653, callback) as any;
|
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DatabaseService provides shared database functionality
|
* DatabaseService 数据库服务
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -15,23 +15,7 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
|||||||
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OnDataPathChanged handles data path changes
|
* ServiceShutdown 服务关闭
|
||||||
*/
|
|
||||||
export function OnDataPathChanged(): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(3652863491) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RegisterModel 注册模型与表的映射关系
|
|
||||||
*/
|
|
||||||
export function RegisterModel(tableName: string, model: any): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(175397515, tableName, model) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ServiceShutdown shuts down the service when the application closes
|
|
||||||
*/
|
*/
|
||||||
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3907893632) as any;
|
let $resultPromise = $Call.ByID(3907893632) as any;
|
||||||
@@ -39,7 +23,7 @@ export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServiceStartup initializes the service when the application starts
|
* ServiceStartup 服务启动
|
||||||
*/
|
*/
|
||||||
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(2067840771, options) as any;
|
let $resultPromise = $Call.ByID(2067840771, options) as any;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DocumentService provides document management functionality
|
* DocumentService 文档服务
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -15,12 +15,12 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
|||||||
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import * as models$0 from "../models/models.js";
|
import * as ent$0 from "../models/ent/models.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CreateDocument creates a new document and returns the created document with ID
|
* CreateDocument 创建文档
|
||||||
*/
|
*/
|
||||||
export function CreateDocument(title: string): Promise<models$0.Document | null> & { cancel(): void } {
|
export function CreateDocument(title: string): Promise<ent$0.Document | null> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3360680842, title) as any;
|
let $resultPromise = $Call.ByID(3360680842, title) as any;
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
return $$createType1($result);
|
return $$createType1($result);
|
||||||
@@ -30,7 +30,7 @@ export function CreateDocument(title: string): Promise<models$0.Document | null>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DeleteDocument marks a document as deleted (default document with ID=1 cannot be deleted)
|
* DeleteDocument 删除文档
|
||||||
*/
|
*/
|
||||||
export function DeleteDocument(id: number): Promise<void> & { cancel(): void } {
|
export function DeleteDocument(id: number): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(412287269, id) as any;
|
let $resultPromise = $Call.ByID(412287269, id) as any;
|
||||||
@@ -38,9 +38,9 @@ export function DeleteDocument(id: number): Promise<void> & { cancel(): void } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GetDocumentByID gets a document by ID
|
* GetDocumentByID 根据ID获取文档
|
||||||
*/
|
*/
|
||||||
export function GetDocumentByID(id: number): Promise<models$0.Document | null> & { cancel(): void } {
|
export function GetDocumentByID(id: number): Promise<ent$0.Document | null> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3468193232, id) as any;
|
let $resultPromise = $Call.ByID(3468193232, id) as any;
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
return $$createType1($result);
|
return $$createType1($result);
|
||||||
@@ -50,9 +50,9 @@ export function GetDocumentByID(id: number): Promise<models$0.Document | null> &
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ListAllDocumentsMeta lists all active (non-deleted) document metadata
|
* ListAllDocumentsMeta 列出所有文档
|
||||||
*/
|
*/
|
||||||
export function ListAllDocumentsMeta(): Promise<(models$0.Document | null)[]> & { cancel(): void } {
|
export function ListAllDocumentsMeta(): Promise<(ent$0.Document | null)[]> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3073950297) as any;
|
let $resultPromise = $Call.ByID(3073950297) as any;
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
return $$createType2($result);
|
return $$createType2($result);
|
||||||
@@ -62,19 +62,7 @@ export function ListAllDocumentsMeta(): Promise<(models$0.Document | null)[]> &
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ListDeletedDocumentsMeta lists all deleted document metadata
|
* LockDocument 锁定文档
|
||||||
*/
|
|
||||||
export function ListDeletedDocumentsMeta(): Promise<(models$0.Document | null)[]> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(490143787) as any;
|
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
|
||||||
return $$createType2($result);
|
|
||||||
}) as any;
|
|
||||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
|
||||||
return $typingPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* LockDocument 锁定文档,防止删除
|
|
||||||
*/
|
*/
|
||||||
export function LockDocument(id: number): Promise<void> & { cancel(): void } {
|
export function LockDocument(id: number): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(1889494473, id) as any;
|
let $resultPromise = $Call.ByID(1889494473, id) as any;
|
||||||
@@ -82,15 +70,7 @@ export function LockDocument(id: number): Promise<void> & { cancel(): void } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RestoreDocument restores a deleted document
|
* ServiceStartup 服务启动
|
||||||
*/
|
|
||||||
export function RestoreDocument(id: number): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(784200778, id) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ServiceStartup initializes the service when the application starts
|
|
||||||
*/
|
*/
|
||||||
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(1474135487, options) as any;
|
let $resultPromise = $Call.ByID(1474135487, options) as any;
|
||||||
@@ -106,7 +86,7 @@ export function UnlockDocument(id: number): Promise<void> & { cancel(): void } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateDocumentContent updates the content of a document
|
* UpdateDocumentContent 更新文档内容
|
||||||
*/
|
*/
|
||||||
export function UpdateDocumentContent(id: number, content: string): Promise<void> & { cancel(): void } {
|
export function UpdateDocumentContent(id: number, content: string): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3251897116, id, content) as any;
|
let $resultPromise = $Call.ByID(3251897116, id, content) as any;
|
||||||
@@ -114,7 +94,7 @@ export function UpdateDocumentContent(id: number, content: string): Promise<void
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateDocumentTitle updates the title of a document
|
* UpdateDocumentTitle 更新文档标题
|
||||||
*/
|
*/
|
||||||
export function UpdateDocumentTitle(id: number, title: string): Promise<void> & { cancel(): void } {
|
export function UpdateDocumentTitle(id: number, title: string): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(2045530459, id, title) as any;
|
let $resultPromise = $Call.ByID(2045530459, id, title) as any;
|
||||||
@@ -122,6 +102,6 @@ export function UpdateDocumentTitle(id: number, title: string): Promise<void> &
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = models$0.Document.createFrom;
|
const $$createType0 = ent$0.Document.createFrom;
|
||||||
const $$createType1 = $Create.Nullable($$createType0);
|
const $$createType1 = $Create.Nullable($$createType0);
|
||||||
const $$createType2 = $Create.Array($$createType1);
|
const $$createType2 = $Create.Array($$createType1);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ExtensionService 扩展管理服务
|
* ExtensionService 扩展服务
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -16,12 +16,15 @@ import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/applic
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import * as models$0 from "../models/models.js";
|
import * as models$0 from "../models/models.js";
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as ent$0 from "../models/ent/models.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GetAllExtensions 获取所有扩展配置
|
* GetDefaultExtensions 获取默认扩展配置(用于前端绑定生成)
|
||||||
*/
|
*/
|
||||||
export function GetAllExtensions(): Promise<models$0.Extension[]> & { cancel(): void } {
|
export function GetDefaultExtensions(): Promise<models$0.Extension[]> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3094292124) as any;
|
let $resultPromise = $Call.ByID(4036328166) as any;
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
return $$createType1($result);
|
return $$createType1($result);
|
||||||
}) as any;
|
}) as any;
|
||||||
@@ -30,23 +33,51 @@ export function GetAllExtensions(): Promise<models$0.Extension[]> & { cancel():
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ResetAllExtensionsToDefault 重置所有扩展到默认状态
|
* GetExtensionByID 根据ID获取扩展
|
||||||
*/
|
*/
|
||||||
export function ResetAllExtensionsToDefault(): Promise<void> & { cancel(): void } {
|
export function GetExtensionByID(id: number): Promise<ent$0.Extension | null> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(270611949) as any;
|
let $resultPromise = $Call.ByID(1521424252, id) as any;
|
||||||
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
|
return $$createType3($result);
|
||||||
|
}) as any;
|
||||||
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
|
return $typingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetExtensionConfig 获取扩展配置
|
||||||
|
*/
|
||||||
|
export function GetExtensionConfig(id: number): Promise<{ [_: string]: any }> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1629559882, id) as any;
|
||||||
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
|
return $$createType4($result);
|
||||||
|
}) as any;
|
||||||
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
|
return $typingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetExtensions 获取所有扩展
|
||||||
|
*/
|
||||||
|
export function GetExtensions(): Promise<(ent$0.Extension | null)[]> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3179289021) as any;
|
||||||
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
|
return $$createType5($result);
|
||||||
|
}) as any;
|
||||||
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
|
return $typingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ResetExtensionConfig 重置单个扩展到默认状态
|
||||||
|
*/
|
||||||
|
export function ResetExtensionConfig(id: number): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3990780299, id) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ResetExtensionToDefault 重置扩展到默认状态
|
* ServiceStartup 服务启动
|
||||||
*/
|
|
||||||
export function ResetExtensionToDefault(id: models$0.ExtensionID): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(868308101, id) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ServiceStartup 启动时调用
|
|
||||||
*/
|
*/
|
||||||
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(40324057, options) as any;
|
let $resultPromise = $Call.ByID(40324057, options) as any;
|
||||||
@@ -54,21 +85,33 @@ export function ServiceStartup(options: application$0.ServiceOptions): Promise<v
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateExtensionEnabled 更新扩展启用状态
|
* SyncExtensions 同步扩展配置
|
||||||
*/
|
*/
|
||||||
export function UpdateExtensionEnabled(id: models$0.ExtensionID, enabled: boolean): Promise<void> & { cancel(): void } {
|
export function SyncExtensions(): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(1067300094, id, enabled) as any;
|
let $resultPromise = $Call.ByID(167560004) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateExtensionState 更新扩展状态
|
* UpdateExtensionConfig 更新扩展配置
|
||||||
*/
|
*/
|
||||||
export function UpdateExtensionState(id: models$0.ExtensionID, enabled: boolean, config: models$0.ExtensionConfig): Promise<void> & { cancel(): void } {
|
export function UpdateExtensionConfig(id: number, config: { [_: string]: any }): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(2917946454, id, enabled, config) as any;
|
let $resultPromise = $Call.ByID(3184142503, id, config) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateExtensionEnabled 更新扩展启用状态
|
||||||
|
*/
|
||||||
|
export function UpdateExtensionEnabled(id: number, enabled: boolean): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1067300094, id, enabled) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = models$0.Extension.createFrom;
|
const $$createType0 = models$0.Extension.createFrom;
|
||||||
const $$createType1 = $Create.Array($$createType0);
|
const $$createType1 = $Create.Array($$createType0);
|
||||||
|
const $$createType2 = ent$0.Extension.createFrom;
|
||||||
|
const $$createType3 = $Create.Nullable($$createType2);
|
||||||
|
const $$createType4 = $Create.Map($Create.Any, $Create.Any);
|
||||||
|
const $$createType5 = $Create.Array($$createType3);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HotkeyService Windows全局热键服务
|
* HotkeyService 全局热键服务
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -18,12 +18,12 @@ import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/applic
|
|||||||
import * as models$0 from "../models/models.js";
|
import * as models$0 from "../models/models.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GetCurrentHotkey 获取当前热键
|
* GetSupportedKeys 返回系统支持的快捷键列表
|
||||||
*/
|
*/
|
||||||
export function GetCurrentHotkey(): Promise<models$0.HotkeyCombo | null> & { cancel(): void } {
|
export function GetSupportedKeys(): Promise<string[]> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(2572811187) as any;
|
let $resultPromise = $Call.ByID(1511528650) as any;
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
return $$createType1($result);
|
return $$createType0($result);
|
||||||
}) as any;
|
}) as any;
|
||||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
return $typingPromise;
|
return $typingPromise;
|
||||||
@@ -48,8 +48,8 @@ export function IsRegistered(): Promise<boolean> & { cancel(): void } {
|
|||||||
/**
|
/**
|
||||||
* RegisterHotkey 注册全局热键
|
* RegisterHotkey 注册全局热键
|
||||||
*/
|
*/
|
||||||
export function RegisterHotkey(hotkey: models$0.HotkeyCombo | null): Promise<void> & { cancel(): void } {
|
export function RegisterHotkey(combo: models$0.HotkeyCombo | null): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(1103945691, hotkey) as any;
|
let $resultPromise = $Call.ByID(1103945691, combo) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServiceStartup initializes the service when the application starts
|
* ServiceStartup 服务启动时初始化
|
||||||
*/
|
*/
|
||||||
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(3079990808, options) as any;
|
let $resultPromise = $Call.ByID(3079990808, options) as any;
|
||||||
@@ -80,11 +80,10 @@ export function UnregisterHotkey(): Promise<void> & { cancel(): void } {
|
|||||||
/**
|
/**
|
||||||
* UpdateHotkey 更新热键配置
|
* UpdateHotkey 更新热键配置
|
||||||
*/
|
*/
|
||||||
export function UpdateHotkey(enable: boolean, hotkey: models$0.HotkeyCombo | null): Promise<void> & { cancel(): void } {
|
export function UpdateHotkey(enable: boolean, combo: models$0.HotkeyCombo | null): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(823285555, enable, hotkey) as any;
|
let $resultPromise = $Call.ByID(823285555, enable, combo) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = models$0.HotkeyCombo.createFrom;
|
const $$createType0 = $Create.Array($Create.Any);
|
||||||
const $$createType1 = $Create.Nullable($$createType0);
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import * as SystemService from "./systemservice.js";
|
|||||||
import * as TestService from "./testservice.js";
|
import * as TestService from "./testservice.js";
|
||||||
import * as ThemeService from "./themeservice.js";
|
import * as ThemeService from "./themeservice.js";
|
||||||
import * as TranslationService from "./translationservice.js";
|
import * as TranslationService from "./translationservice.js";
|
||||||
import * as TrayService from "./trayservice.js";
|
|
||||||
import * as WindowService from "./windowservice.js";
|
import * as WindowService from "./windowservice.js";
|
||||||
export {
|
export {
|
||||||
BackupService,
|
BackupService,
|
||||||
@@ -36,7 +35,6 @@ export {
|
|||||||
TestService,
|
TestService,
|
||||||
ThemeService,
|
ThemeService,
|
||||||
TranslationService,
|
TranslationService,
|
||||||
TrayService,
|
|
||||||
WindowService
|
WindowService
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KeyBindingService 快捷键管理服务
|
* KeyBindingService 快捷键服务
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -16,12 +16,15 @@ import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/applic
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import * as models$0 from "../models/models.js";
|
import * as models$0 from "../models/models.js";
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore: Unused imports
|
||||||
|
import * as ent$0 from "../models/ent/models.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GetAllKeyBindings 获取所有快捷键配置
|
* GetDefaultKeyBindings 获取默认快捷键配置
|
||||||
*/
|
*/
|
||||||
export function GetAllKeyBindings(): Promise<models$0.KeyBinding[]> & { cancel(): void } {
|
export function GetDefaultKeyBindings(): Promise<models$0.KeyBinding[]> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(1633502882) as any;
|
let $resultPromise = $Call.ByID(3843471588) as any;
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
return $$createType1($result);
|
return $$createType1($result);
|
||||||
}) as any;
|
}) as any;
|
||||||
@@ -30,13 +33,80 @@ export function GetAllKeyBindings(): Promise<models$0.KeyBinding[]> & { cancel()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServiceStartup 启动时调用
|
* GetKeyBindingByID 根据ID获取快捷键
|
||||||
|
*/
|
||||||
|
export function GetKeyBindingByID(id: number): Promise<ent$0.KeyBinding | null> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1578192526, id) as any;
|
||||||
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
|
return $$createType3($result);
|
||||||
|
}) as any;
|
||||||
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
|
return $typingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GetKeyBindings 根据类型获取快捷键
|
||||||
|
*/
|
||||||
|
export function GetKeyBindings(kbType: models$0.KeyBindingType): Promise<(ent$0.KeyBinding | null)[]> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(4253885163, kbType) as any;
|
||||||
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
|
return $$createType4($result);
|
||||||
|
}) as any;
|
||||||
|
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
||||||
|
return $typingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ResetKeyBindings 重置所有快捷键到默认值
|
||||||
|
*/
|
||||||
|
export function ResetKeyBindings(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(4251626010) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ServiceStartup 服务启动
|
||||||
*/
|
*/
|
||||||
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(2057121990, options) as any;
|
let $resultPromise = $Call.ByID(2057121990, options) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SyncKeyBindings 同步快捷键配置
|
||||||
|
*/
|
||||||
|
export function SyncKeyBindings(): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(1522202638) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateKeyBindingEnabled 更新快捷键启用状态
|
||||||
|
*/
|
||||||
|
export function UpdateKeyBindingEnabled(id: number, enabled: boolean): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(843626124, id, enabled) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateKeyBindingKeys 更新快捷键绑定
|
||||||
|
*/
|
||||||
|
export function UpdateKeyBindingKeys(id: number, key: string): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(3432755175, id, key) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UpdateKeyBindingPreventDefault 更新快捷键 PreventDefault 状态
|
||||||
|
*/
|
||||||
|
export function UpdateKeyBindingPreventDefault(id: number, preventDefault: boolean): Promise<void> & { cancel(): void } {
|
||||||
|
let $resultPromise = $Call.ByID(202386744, id, preventDefault) as any;
|
||||||
|
return $resultPromise;
|
||||||
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = models$0.KeyBinding.createFrom;
|
const $$createType0 = models$0.KeyBinding.createFrom;
|
||||||
const $$createType1 = $Create.Array($$createType0);
|
const $$createType1 = $Create.Array($$createType0);
|
||||||
|
const $$createType2 = ent$0.KeyBinding.createFrom;
|
||||||
|
const $$createType3 = $Create.Nullable($$createType2);
|
||||||
|
const $$createType4 = $Create.Array($$createType3);
|
||||||
|
|||||||
@@ -5,9 +5,6 @@
|
|||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import {Create as $Create} from "@wailsio/runtime";
|
import {Create as $Create} from "@wailsio/runtime";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore: Unused imports
|
|
||||||
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import * as http$0 from "../../../net/http/models.js";
|
import * as http$0 from "../../../net/http/models.js";
|
||||||
@@ -188,15 +185,14 @@ export class MemoryStats {
|
|||||||
* MigrationProgress 迁移进度信息
|
* MigrationProgress 迁移进度信息
|
||||||
*/
|
*/
|
||||||
export class MigrationProgress {
|
export class MigrationProgress {
|
||||||
"status": MigrationStatus;
|
/**
|
||||||
|
* 0-100
|
||||||
|
*/
|
||||||
"progress": number;
|
"progress": number;
|
||||||
"error"?: string;
|
"error"?: string;
|
||||||
|
|
||||||
/** Creates a new MigrationProgress instance. */
|
/** Creates a new MigrationProgress instance. */
|
||||||
constructor($$source: Partial<MigrationProgress> = {}) {
|
constructor($$source: Partial<MigrationProgress> = {}) {
|
||||||
if (!("status" in $$source)) {
|
|
||||||
this["status"] = ("" as MigrationStatus);
|
|
||||||
}
|
|
||||||
if (!("progress" in $$source)) {
|
if (!("progress" in $$source)) {
|
||||||
this["progress"] = 0;
|
this["progress"] = 0;
|
||||||
}
|
}
|
||||||
@@ -213,20 +209,6 @@ export class MigrationProgress {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* MigrationStatus 迁移状态
|
|
||||||
*/
|
|
||||||
export enum MigrationStatus {
|
|
||||||
/**
|
|
||||||
* The Go zero value for the underlying type of the enum.
|
|
||||||
*/
|
|
||||||
$zero = "",
|
|
||||||
|
|
||||||
MigrationStatusMigrating = "migrating",
|
|
||||||
MigrationStatusCompleted = "completed",
|
|
||||||
MigrationStatusFailed = "failed",
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OSInfo 操作系统信息
|
* OSInfo 操作系统信息
|
||||||
*/
|
*/
|
||||||
@@ -303,7 +285,7 @@ export class SelfUpdateResult {
|
|||||||
"error": string;
|
"error": string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新源(github/gitea)
|
* 更新源(github)
|
||||||
*/
|
*/
|
||||||
"source": string;
|
"source": string;
|
||||||
|
|
||||||
@@ -394,62 +376,6 @@ export class SystemInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* WindowInfo 窗口信息
|
|
||||||
*/
|
|
||||||
export class WindowInfo {
|
|
||||||
"Window": application$0.WebviewWindow | null;
|
|
||||||
"DocumentID": number;
|
|
||||||
"Title": string;
|
|
||||||
|
|
||||||
/** Creates a new WindowInfo instance. */
|
|
||||||
constructor($$source: Partial<WindowInfo> = {}) {
|
|
||||||
if (!("Window" in $$source)) {
|
|
||||||
this["Window"] = null;
|
|
||||||
}
|
|
||||||
if (!("DocumentID" in $$source)) {
|
|
||||||
this["DocumentID"] = 0;
|
|
||||||
}
|
|
||||||
if (!("Title" in $$source)) {
|
|
||||||
this["Title"] = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(this, $$source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new WindowInfo instance from a string or object.
|
|
||||||
*/
|
|
||||||
static createFrom($$source: any = {}): WindowInfo {
|
|
||||||
const $$createField0_0 = $$createType8;
|
|
||||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
|
||||||
if ("Window" in $$parsedSource) {
|
|
||||||
$$parsedSource["Window"] = $$createField0_0($$parsedSource["Window"]);
|
|
||||||
}
|
|
||||||
return new WindowInfo($$parsedSource as Partial<WindowInfo>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* WindowSnapService 窗口吸附服务
|
|
||||||
*/
|
|
||||||
export class WindowSnapService {
|
|
||||||
|
|
||||||
/** Creates a new WindowSnapService instance. */
|
|
||||||
constructor($$source: Partial<WindowSnapService> = {}) {
|
|
||||||
|
|
||||||
Object.assign(this, $$source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new WindowSnapService instance from a string or object.
|
|
||||||
*/
|
|
||||||
static createFrom($$source: any = {}): WindowSnapService {
|
|
||||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
|
||||||
return new WindowSnapService($$parsedSource as Partial<WindowSnapService>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = $Create.Map($Create.Any, $Create.Any);
|
const $$createType0 = $Create.Map($Create.Any, $Create.Any);
|
||||||
var $$createType1 = (function $$initCreateType1(...args): any {
|
var $$createType1 = (function $$initCreateType1(...args): any {
|
||||||
@@ -463,5 +389,3 @@ const $$createType3 = $Create.Map($Create.Any, $$createType2);
|
|||||||
const $$createType4 = OSInfo.createFrom;
|
const $$createType4 = OSInfo.createFrom;
|
||||||
const $$createType5 = $Create.Nullable($$createType4);
|
const $$createType5 = $Create.Nullable($$createType4);
|
||||||
const $$createType6 = $Create.Map($Create.Any, $Create.Any);
|
const $$createType6 = $Create.Map($Create.Any, $Create.Any);
|
||||||
const $$createType7 = application$0.WebviewWindow.createFrom;
|
|
||||||
const $$createType8 = $Create.Nullable($$createType7);
|
|
||||||
|
|||||||
@@ -15,26 +15,13 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
|||||||
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import * as models$0 from "../models/models.js";
|
import * as ent$0 from "../models/ent/models.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GetAllThemes 获取所有主题
|
* GetThemeByName 根据Key获取主题
|
||||||
*/
|
*/
|
||||||
export function GetAllThemes(): Promise<(models$0.Theme | null)[]> & { cancel(): void } {
|
export function GetThemeByName(name: string): Promise<ent$0.Theme | null> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(2425053076) as any;
|
let $resultPromise = $Call.ByID(1938954770, name) as any;
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
|
||||||
return $$createType2($result);
|
|
||||||
}) as any;
|
|
||||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
|
||||||
return $typingPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GetThemeByID 根据ID或名称获取主题
|
|
||||||
* 如果 id > 0,按ID查询;如果 id = 0,按名称查询
|
|
||||||
*/
|
|
||||||
export function GetThemeByIdOrName(id: number, ...name: string[]): Promise<models$0.Theme | null> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(127385338, id, name) as any;
|
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||||
return $$createType1($result);
|
return $$createType1($result);
|
||||||
}) as any;
|
}) as any;
|
||||||
@@ -43,23 +30,15 @@ export function GetThemeByIdOrName(id: number, ...name: string[]): Promise<model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ResetTheme 重置主题为预设配置
|
* ResetTheme 删除主题
|
||||||
*/
|
*/
|
||||||
export function ResetTheme(id: number, ...name: string[]): Promise<void> & { cancel(): void } {
|
export function ResetTheme(key: string): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(1806334457, id, name) as any;
|
let $resultPromise = $Call.ByID(1806334457, key) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServiceShutdown 服务关闭
|
* ServiceStartup 服务启动
|
||||||
*/
|
|
||||||
export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(1676749034) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ServiceStartup 服务启动时初始化
|
|
||||||
*/
|
*/
|
||||||
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(2915959937, options) as any;
|
let $resultPromise = $Call.ByID(2915959937, options) as any;
|
||||||
@@ -67,14 +46,13 @@ export function ServiceStartup(options: application$0.ServiceOptions): Promise<v
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UpdateTheme 更新主题
|
* UpdateTheme 保存或更新主题
|
||||||
*/
|
*/
|
||||||
export function UpdateTheme(id: number, colors: models$0.ThemeColorConfig): Promise<void> & { cancel(): void } {
|
export function UpdateTheme(key: string, colors: { [_: string]: any }): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(70189749, id, colors) as any;
|
let $resultPromise = $Call.ByID(70189749, key, colors) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
// Private type creation functions
|
||||||
const $$createType0 = models$0.Theme.createFrom;
|
const $$createType0 = ent$0.Theme.createFrom;
|
||||||
const $$createType1 = $Create.Nullable($$createType0);
|
const $$createType1 = $Create.Nullable($$createType0);
|
||||||
const $$createType2 = $Create.Array($$createType1);
|
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
|
||||||
// This file is automatically generated. DO NOT EDIT
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TrayService 系统托盘服务
|
|
||||||
* @module
|
|
||||||
*/
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore: Unused imports
|
|
||||||
import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HandleWindowClose 处理窗口关闭事件
|
|
||||||
*/
|
|
||||||
export function HandleWindowClose(): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(1824247204) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HandleWindowMinimize 处理窗口最小化事件
|
|
||||||
*/
|
|
||||||
export function HandleWindowMinimize(): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(178686624) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MinimizeButtonClicked 处理标题栏最小化按钮点击
|
|
||||||
*/
|
|
||||||
export function MinimizeButtonClicked(): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(2477618539) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ShouldMinimizeToTray 检查是否应该最小化到托盘
|
|
||||||
*/
|
|
||||||
export function ShouldMinimizeToTray(): Promise<boolean> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(3403884012) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ShowWindow 显示主窗口
|
|
||||||
*/
|
|
||||||
export function ShowWindow(): Promise<void> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(1315913255) as any;
|
|
||||||
return $resultPromise;
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WindowService 窗口管理服务(专注于窗口生命周期管理)
|
* WindowService 窗口管理服务
|
||||||
* @module
|
* @module
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -12,19 +12,7 @@ import {Call as $Call, Create as $Create} from "@wailsio/runtime";
|
|||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore: Unused imports
|
// @ts-ignore: Unused imports
|
||||||
import * as $models from "./models.js";
|
import * as application$0 from "../../../github.com/wailsapp/wails/v3/pkg/application/models.js";
|
||||||
|
|
||||||
/**
|
|
||||||
* GetOpenWindows 获取所有打开的窗口信息
|
|
||||||
*/
|
|
||||||
export function GetOpenWindows(): Promise<$models.WindowInfo[]> & { cancel(): void } {
|
|
||||||
let $resultPromise = $Call.ByID(1464997251) as any;
|
|
||||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
|
||||||
return $$createType1($result);
|
|
||||||
}) as any;
|
|
||||||
$typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
|
|
||||||
return $typingPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IsDocumentWindowOpen 检查指定文档的窗口是否已打开
|
* IsDocumentWindowOpen 检查指定文档的窗口是否已打开
|
||||||
@@ -51,13 +39,9 @@ export function ServiceShutdown(): Promise<void> & { cancel(): void } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SetWindowSnapService 设置窗口吸附服务引用
|
* ServiceStartup 服务启动时初始化
|
||||||
*/
|
*/
|
||||||
export function SetWindowSnapService(snapService: $models.WindowSnapService | null): Promise<void> & { cancel(): void } {
|
export function ServiceStartup(options: application$0.ServiceOptions): Promise<void> & { cancel(): void } {
|
||||||
let $resultPromise = $Call.ByID(1105193745, snapService) as any;
|
let $resultPromise = $Call.ByID(2432987694, options) as any;
|
||||||
return $resultPromise;
|
return $resultPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private type creation functions
|
|
||||||
const $$createType0 = $models.WindowInfo.createFrom;
|
|
||||||
const $$createType1 = $Create.Array($$createType0);
|
|
||||||
|
|||||||
4
frontend/components.d.ts
vendored
@@ -11,6 +11,8 @@ export {}
|
|||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
AccordionContainer: typeof import('./src/components/accordion/AccordionContainer.vue')['default']
|
||||||
|
AccordionItem: typeof import('./src/components/accordion/AccordionItem.vue')['default']
|
||||||
BlockLanguageSelector: typeof import('./src/components/toolbar/BlockLanguageSelector.vue')['default']
|
BlockLanguageSelector: typeof import('./src/components/toolbar/BlockLanguageSelector.vue')['default']
|
||||||
DocumentSelector: typeof import('./src/components/toolbar/DocumentSelector.vue')['default']
|
DocumentSelector: typeof import('./src/components/toolbar/DocumentSelector.vue')['default']
|
||||||
LinuxTitleBar: typeof import('./src/components/titlebar/LinuxTitleBar.vue')['default']
|
LinuxTitleBar: typeof import('./src/components/titlebar/LinuxTitleBar.vue')['default']
|
||||||
@@ -22,6 +24,8 @@ declare module 'vue' {
|
|||||||
TabContainer: typeof import('./src/components/tabs/TabContainer.vue')['default']
|
TabContainer: typeof import('./src/components/tabs/TabContainer.vue')['default']
|
||||||
TabContextMenu: typeof import('./src/components/tabs/TabContextMenu.vue')['default']
|
TabContextMenu: typeof import('./src/components/tabs/TabContextMenu.vue')['default']
|
||||||
TabItem: typeof import('./src/components/tabs/TabItem.vue')['default']
|
TabItem: typeof import('./src/components/tabs/TabItem.vue')['default']
|
||||||
|
Toast: typeof import('./src/components/toast/Toast.vue')['default']
|
||||||
|
ToastContainer: typeof import('./src/components/toast/ToastContainer.vue')['default']
|
||||||
Toolbar: typeof import('./src/components/toolbar/Toolbar.vue')['default']
|
Toolbar: typeof import('./src/components/toolbar/Toolbar.vue')['default']
|
||||||
WindowsTitleBar: typeof import('./src/components/titlebar/WindowsTitleBar.vue')['default']
|
WindowsTitleBar: typeof import('./src/components/titlebar/WindowsTitleBar.vue')['default']
|
||||||
WindowTitleBar: typeof import('./src/components/titlebar/WindowTitleBar.vue')['default']
|
WindowTitleBar: typeof import('./src/components/titlebar/WindowTitleBar.vue')['default']
|
||||||
|
|||||||
2756
frontend/package-lock.json
generated
@@ -11,14 +11,19 @@
|
|||||||
"lint": "eslint",
|
"lint": "eslint",
|
||||||
"lint:fix": "eslint --fix",
|
"lint:fix": "eslint --fix",
|
||||||
"build:lang-parser": "node src/views/editor/extensions/codeblock/lang-parser/build-parser.js",
|
"build:lang-parser": "node src/views/editor/extensions/codeblock/lang-parser/build-parser.js",
|
||||||
|
"build:mermaid-parser": "node src/views/editor/language/mermaid/build-parsers.js",
|
||||||
"test": "vitest",
|
"test": "vitest",
|
||||||
"docs:dev": "vitepress dev docs",
|
"docs:dev": "vitepress dev docs",
|
||||||
"docs:build": "vitepress build docs",
|
"docs:build": "vitepress build docs",
|
||||||
"docs:preview": "vitepress preview docs"
|
"docs:preview": "vitepress preview docs",
|
||||||
|
"app:dev": "cd .. &&wails3 dev",
|
||||||
|
"app:build": "cd .. && wails3 task build",
|
||||||
|
"app:package": "cd .. && wails3 package",
|
||||||
|
"app:generate": "cd .. && wails3 generate bindings -ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.19.1",
|
"@codemirror/autocomplete": "^6.20.0",
|
||||||
"@codemirror/commands": "^6.10.0",
|
"@codemirror/commands": "^6.10.1",
|
||||||
"@codemirror/lang-angular": "^0.1.4",
|
"@codemirror/lang-angular": "^0.1.4",
|
||||||
"@codemirror/lang-cpp": "^6.0.3",
|
"@codemirror/lang-cpp": "^6.0.3",
|
||||||
"@codemirror/lang-css": "^6.3.1",
|
"@codemirror/lang-css": "^6.3.1",
|
||||||
@@ -29,7 +34,7 @@
|
|||||||
"@codemirror/lang-json": "^6.0.2",
|
"@codemirror/lang-json": "^6.0.2",
|
||||||
"@codemirror/lang-less": "^6.0.2",
|
"@codemirror/lang-less": "^6.0.2",
|
||||||
"@codemirror/lang-lezer": "^6.0.2",
|
"@codemirror/lang-lezer": "^6.0.2",
|
||||||
"@codemirror/lang-liquid": "^6.3.0",
|
"@codemirror/lang-liquid": "^6.3.1",
|
||||||
"@codemirror/lang-markdown": "^6.5.0",
|
"@codemirror/lang-markdown": "^6.5.0",
|
||||||
"@codemirror/lang-php": "^6.0.2",
|
"@codemirror/lang-php": "^6.0.2",
|
||||||
"@codemirror/lang-python": "^6.2.1",
|
"@codemirror/lang-python": "^6.2.1",
|
||||||
@@ -39,59 +44,64 @@
|
|||||||
"@codemirror/lang-vue": "^0.1.3",
|
"@codemirror/lang-vue": "^0.1.3",
|
||||||
"@codemirror/lang-wast": "^6.0.2",
|
"@codemirror/lang-wast": "^6.0.2",
|
||||||
"@codemirror/lang-yaml": "^6.1.2",
|
"@codemirror/lang-yaml": "^6.1.2",
|
||||||
"@codemirror/language": "^6.11.3",
|
"@codemirror/language": "^6.12.1",
|
||||||
"@codemirror/language-data": "^6.5.2",
|
"@codemirror/language-data": "^6.5.2",
|
||||||
"@codemirror/legacy-modes": "^6.5.2",
|
"@codemirror/legacy-modes": "^6.5.2",
|
||||||
"@codemirror/lint": "^6.9.1",
|
"@codemirror/lint": "^6.9.2",
|
||||||
"@codemirror/search": "^6.5.11",
|
"@codemirror/search": "^6.5.11",
|
||||||
"@codemirror/state": "^6.5.2",
|
"@codemirror/state": "^6.5.3",
|
||||||
"@codemirror/view": "^6.38.6",
|
"@codemirror/view": "^6.39.8",
|
||||||
"@cospaia/prettier-plugin-clojure": "^0.0.2",
|
"@cospaia/prettier-plugin-clojure": "^0.0.2",
|
||||||
"@lezer/highlight": "^1.2.3",
|
"@lezer/highlight": "^1.2.3",
|
||||||
"@lezer/lr": "^1.4.2",
|
"@lezer/lr": "^1.4.5",
|
||||||
"@prettier/plugin-xml": "^3.4.2",
|
"@prettier/plugin-xml": "^3.4.2",
|
||||||
"@replit/codemirror-lang-svelte": "^6.0.0",
|
"@replit/codemirror-lang-svelte": "^6.0.0",
|
||||||
"@toml-tools/lexer": "^1.0.0",
|
"@toml-tools/lexer": "^1.0.1",
|
||||||
"@toml-tools/parser": "^1.0.0",
|
"@toml-tools/parser": "^1.0.1",
|
||||||
|
"@types/katex": "^0.16.7",
|
||||||
|
"@zumer/snapdom": "^2.0.1",
|
||||||
"codemirror": "^6.0.2",
|
"codemirror": "^6.0.2",
|
||||||
"codemirror-lang-elixir": "^4.0.0",
|
"codemirror-lang-elixir": "^4.0.0",
|
||||||
"colors-named": "^1.0.2",
|
"colors-named": "^1.0.4",
|
||||||
"colors-named-hex": "^1.0.2",
|
"colors-named-hex": "^1.0.3",
|
||||||
"groovy-beautify": "^0.0.17",
|
"groovy-beautify": "^0.0.17",
|
||||||
"hsl-matcher": "^1.2.4",
|
"hsl-matcher": "^1.2.4",
|
||||||
"java-parser": "^3.0.1",
|
"java-parser": "^3.0.1",
|
||||||
"jsox": "^1.2.123",
|
"katex": "^0.16.27",
|
||||||
"linguist-languages": "^9.1.0",
|
"linguist-languages": "^9.1.11",
|
||||||
|
"marked": "^17.0.1",
|
||||||
|
"mermaid": "^11.12.2",
|
||||||
"php-parser": "^3.2.5",
|
"php-parser": "^3.2.5",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.4",
|
||||||
"pinia-plugin-persistedstate": "^4.7.1",
|
"pinia-plugin-persistedstate": "^4.7.1",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.7.4",
|
||||||
"remarkable": "^2.0.1",
|
"sass": "^1.97.1",
|
||||||
"sass": "^1.93.3",
|
"vue": "^3.5.26",
|
||||||
"vue": "^3.5.22",
|
"vue-i18n": "^11.2.8",
|
||||||
"vue-i18n": "^11.1.12",
|
|
||||||
"vue-pick-colors": "^1.8.0",
|
"vue-pick-colors": "^1.8.0",
|
||||||
"vue-router": "^4.6.3"
|
"vue-router": "^4.6.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.39.0",
|
"@eslint/js": "^9.39.2",
|
||||||
"@lezer/generator": "^1.8.0",
|
"@lezer/generator": "^1.8.0",
|
||||||
"@types/node": "^24.9.2",
|
"@types/node": "^25.0.3",
|
||||||
"@types/remarkable": "^2.0.8",
|
"@vitejs/plugin-vue": "^6.0.3",
|
||||||
"@vitejs/plugin-vue": "^6.0.1",
|
"@wailsio/runtime": "^3.0.0-alpha.77",
|
||||||
"@wailsio/runtime": "latest",
|
|
||||||
"cross-env": "^10.1.0",
|
"cross-env": "^10.1.0",
|
||||||
"eslint": "^9.39.0",
|
"eslint": "^9.39.2",
|
||||||
"eslint-plugin-vue": "^10.5.1",
|
"eslint-plugin-vue": "^10.6.2",
|
||||||
"globals": "^16.5.0",
|
"globals": "^16.5.0",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.46.2",
|
"typescript-eslint": "^8.51.0",
|
||||||
"unplugin-vue-components": "^30.0.0",
|
"unplugin-vue-components": "^30.0.0",
|
||||||
"vite": "^7.1.12",
|
"vite": "npm:rolldown-vite@latest",
|
||||||
"vite-plugin-node-polyfills": "^0.24.0",
|
"vite-plugin-node-polyfills": "^0.24.0",
|
||||||
"vitepress": "^2.0.0-alpha.12",
|
"vitepress": "^2.0.0-alpha.12",
|
||||||
"vitest": "^4.0.6",
|
"vitest": "^4.0.16",
|
||||||
"vue-eslint-parser": "^10.2.0",
|
"vue-eslint-parser": "^10.2.0",
|
||||||
"vue-tsc": "^3.1.2"
|
"vue-tsc": "^3.2.1"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"vite": "npm:rolldown-vite@latest"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1
frontend/public/images/blockImage.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1767366893329" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="106998" width="200" height="200"><path d="M344.064 36.571429v95.085714H155.428571a23.771429 23.771429 0 0 0-23.259428 19.017143l-0.512 4.754285-0.073143 509.952L306.176 505.417143a95.085714 95.085714 0 0 1 121.270857-5.997714l4.827429 3.876571 152.137143 130.413714 102.546285-102.4a95.085714 95.085714 0 0 1 119.003429-12.507428l5.266286 3.657143 81.042285 60.781714 0.073143-118.784 0.512-7.021714a47.542857 47.542857 0 0 1 94.061714 0l0.512 7.021714v404.114286c0 62.171429-47.762286 113.225143-108.617142 118.418285l-10.24 0.438857h-713.142858l-10.24-0.438857a118.857143 118.857143 0 0 1-108.105142-107.52L36.571429 868.498286v-713.142857l0.438857-10.24A118.857143 118.857143 0 0 1 155.428571 36.571429h188.708572z m26.331429 538.916571L131.657143 794.404571l0.073143 74.166858c0 11.483429 8.118857 21.065143 19.017143 23.259428l4.754285 0.512h713.142857a23.771429 23.771429 0 0 0 23.259429-19.017143l0.512-4.754285-0.073143-166.473143-138.093714-103.570286-97.353143 97.28 76.288 65.316571a47.542857 47.542857 0 0 1-58.002286 75.190858l-3.876571-2.925715-300.836572-257.901714zM649.069714 60.269714a47.542857 47.542857 0 0 1 3.291429 63.634286l-3.291429 3.657143-61.44 61.44 61.44 61.44a47.542857 47.542857 0 0 1 3.291429 63.634286l-3.291429 3.657142a47.542857 47.542857 0 0 1-63.634285 3.218286l-3.584-3.291428-95.085715-95.085715a47.542857 47.542857 0 0 1-3.291428-63.634285l3.291428-3.584 95.085715-95.085715a47.542857 47.542857 0 0 1 67.291428 0zM855.259429 57.051429l3.584 3.218285 95.085714 95.085715a47.542857 47.542857 0 0 1 3.291428 63.634285l-3.291428 3.657143-95.085714 95.085714a47.542857 47.542857 0 0 1-70.509715-63.634285l3.291429-3.657143 61.44-61.44-61.44-61.44a47.542857 47.542857 0 0 1-3.291429-63.634286l3.291429-3.657143a47.542857 47.542857 0 0 1 63.634286-3.218285zM344.210286 36.571429a47.542857 47.542857 0 0 1 7.021714 94.573714l-7.021714 0.512V36.571429z" p-id="106999" fill="#e0620d"></path></svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
1
frontend/public/images/colorSelector.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1767367606621" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15611" width="200" height="200"><path d="M511.966509 0.066982c96.036384 0 185.886507 26.451603 262.724147 72.443261L767.949763 68.670494l-127.948963 221.638835A254.788666 254.788666 0 0 0 511.966509 256.050237V0.066982z" fill="#E70212" p-id="15612"></path><path d="M767.949763 68.670494a509.577332 509.577332 0 0 1 191.304819 194.120635L955.329506 256.050237l-221.638835 127.991627a257.263171 257.263171 0 0 0-93.689871-93.689871L767.949763 68.670494z" fill="#EA6101" p-id="15613"></path><path d="M955.329506 256.050237A509.577332 509.577332 0 0 1 1023.933018 519.798317V512.033491h-255.983255a254.788666 254.788666 0 0 0-34.259092-127.991627l221.638835-127.991627z" fill="#F39801" p-id="15614"></path><path d="M1023.933018 512.033491c0 90.020778-23.251812 174.665907-64.038478 248.175765l-4.565034 7.80749-221.638835-127.948964c21.758577-37.672202 34.259092-81.402675 34.259092-128.034291v-0.042664L1023.933018 512.033491z" fill="#FCC902" p-id="15615"></path><path d="M733.690671 640.025118l221.638835 127.991628a509.66266 509.66266 0 0 1-179.52959 182.900035l-7.850153 4.479707-127.991627-221.638835A257.263171 257.263171 0 0 0 733.690671 640.025118z" fill="#FEF200" p-id="15616"></path><path d="M640.0008 733.757653L767.949763 955.396488A509.66266 509.66266 0 0 1 521.011251 1024H511.966509v-255.983254a254.788666 254.788666 0 0 0 128.034291-34.259093z" fill="#90C320" p-id="15617"></path><path d="M511.966509 768.016746v255.983254c-90.020778 0-174.665907-23.251812-248.175765-64.038477L255.983254 955.396488l127.991628-221.638835c37.672202 21.758577 81.402675 34.259092 128.034291 34.259093z" fill="#019A44" p-id="15618"></path><path d="M383.974882 733.757653l-127.991628 221.638835a509.66266 509.66266 0 0 1-182.900035-179.529589L68.603512 768.016746l221.638835-127.991628A257.263171 257.263171 0 0 0 383.974882 733.757653z" fill="#019E97" p-id="15619"></path><path d="M255.983254 512.033491c0 46.631616 12.457852 90.362089 34.259093 128.034291L68.603512 768.016746A509.66266 509.66266 0 0 1 0 521.078233V512.033491h255.983254z" fill="#0169B8" p-id="15620"></path><path d="M68.603512 256.050237l221.638835 127.991627A254.788666 254.788666 0 0 0 255.983254 512.033491H0c0-90.020778 23.251812-174.665907 64.038477-248.175765L68.603512 256.050237z" fill="#1C2089" p-id="15621"></path><path d="M262.681483 64.745418L255.983254 68.670494l127.991628 221.638835A257.263171 257.263171 0 0 0 290.242347 384.041864L68.603512 256.050237a509.577332 509.577332 0 0 1 194.120635-191.304819z" fill="#621988" p-id="15622"></path><path d="M519.731334 0.066982H511.966509v255.983255a254.788666 254.788666 0 0 0-128.034291 34.259092L255.983254 68.670494A509.577332 509.577332 0 0 1 519.731334 0.066982z" fill="#910783" p-id="15623"></path></svg>
|
||||||
|
After Width: | Height: | Size: 2.8 KiB |
1
frontend/public/images/contextMenu.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1767366808037" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="103196" width="200" height="200"><path d="M878.921143 96c27.099429 0 49.078857 21.942857 49.078857 49.078857v349.842286c0 27.099429-21.942857 49.078857-49.078857 49.078857h-221.842286c-27.099429 0-49.078857-21.942857-49.078857-49.078857V145.078857c0-27.099429 21.942857-49.078857 49.078857-49.078857z m-14.921143 320h-192v64h192v-64z m0-128h-192v64h192v-64z m0-128h-192v64h192v-64zM384 309.321143A202.678857 202.678857 0 0 1 586.678857 512v213.321143a202.678857 202.678857 0 0 1-202.678857 202.678857H298.678857a202.678857 202.678857 0 0 1-202.678857-202.678857V512a202.678857 202.678857 0 0 1 202.678857-202.678857z m138.642286 298.642286H160v117.394285a138.678857 138.678857 0 0 0 131.547429 138.459429l7.131428 0.182857H384a138.678857 138.678857 0 0 0 138.678857-138.678857l-0.036571-117.357714z m-213.321143-234.642286h-10.642286A138.678857 138.678857 0 0 0 160 512v31.963429h149.321143v-170.642286z" p-id="103197" fill="#8992c8"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
1
frontend/public/images/fold.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1767366707029" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="100833" width="200" height="200"><path d="M533.333 54c16.138 0 29.75 12.016 31.753 28.03l17.828 142.569L896 224.6c17.496 0 31.713 14.042 31.996 31.47l0.004 0.53V939c0 17.673-14.327 32-32 32H469.735a31.94 31.94 0 0 1-3.051-0.102l-0.09-0.009c-10.834-0.868-19.434-6.86-24.45-14.999a31.766 31.766 0 0 1-3.374-7.39 32.348 32.348 0 0 1-1.405-7.246L419.752 800.4H128c-17.496 0-31.713-14.042-31.996-31.47L96 768.4V86c0-17.673 14.327-32 32-32zM864 288.599H590.917l13.33 106.6L704 395.2c17.673 0 32 14.327 32 32 0 17.496-14.042 31.713-31.47 31.996l-0.53 0.004-91.75-0.001 13.331 106.6L704 565.8c17.673 0 32 14.327 32 32 0 17.496-14.042 31.713-31.47 31.996l-0.53 0.004-70.416-0.001 16.548 132.332 0.287 2.298c0.024 0.188 0.046 0.376 0.066 0.565 0.986 9.171-2.002 17.793-7.523 24.232l-0.217 0.25L539.872 907H864v-618.4zM548.127 800.4H484.25l7.985 63.851 55.892-63.851zM505.085 118H160v618.4h287.598c0.302-0.004 0.603-0.004 0.904 0h133.913l-0.001-0.004L569.01 629.21l-3.386-27.076c-0.03-0.225-0.058-0.45-0.084-0.676l-21.256-169.977c-0.03-0.219-0.056-0.438-0.081-0.659L505.085 118zM448 565.8c17.673 0 32 14.327 32 32 0 17.496-14.042 31.713-31.47 31.996l-0.53 0.004H256c-17.673 0-32-14.327-32-32 0-17.496 14.042-31.713 31.47-31.996l0.53-0.004h192z m-21.333-170.6c17.673 0 32 14.327 32 32 0 17.496-14.042 31.713-31.471 31.996l-0.53 0.004H256c-17.673 0-32-14.327-32-32 0-17.496 14.042-31.713 31.47-31.996l0.53-0.004h170.667z m-21.334-170.6c17.673 0 32 14.327 32 32 0 17.496-14.041 31.713-31.47 31.996l-0.53 0.004H256c-17.673 0-32-14.327-32-32 0-17.496 14.042-31.713 31.47-31.996l0.53-0.004h149.333z" p-id="100834" fill="#1aaba8"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
1
frontend/public/images/highlightTrailingWhitespace.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1767367226608" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5585" width="200" height="200"><path d="M416 64H768v64h-64v704h64v64H448v-64h64V512H416a224 224 0 1 1 0-448zM576 832h64V128H576v704zM416 128H512v320H416a160 160 0 0 1 0-320z" fill="#a4579d" p-id="5586"></path></svg>
|
||||||
|
After Width: | Height: | Size: 330 B |
1
frontend/public/images/highlightWhitespace.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1767366207284" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="95138" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M753.5 130.4v763.3h70.1v66.4H477v-66.4h70.1V547.1H443.9c-44.2 0-84.8-11.1-121.7-33.2-36.9-22.1-66.4-51.6-88.5-88.5s-33.2-76.8-33.2-119.8 11.1-83.6 33.2-121.7c22.1-38.1 51.6-67.6 88.5-88.5s77.4-31.3 121.7-31.3h379.8v66.4h-70.1z m-206.5 0H443.8c-49.2 0-90.3 17.2-123.5 51.6-33.2 34.4-49.8 75.6-49.8 123.5s16.6 88.5 49.8 121.7c33.2 33.2 74.4 49.8 123.5 49.8H547V130.4z m140.1 0H617v763.3h70.1V130.4z" p-id="95139"></path></svg>
|
||||||
|
After Width: | Height: | Size: 758 B |
1
frontend/public/images/httpClient.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1767365935803" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="81379" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M896 64a64 64 0 0 1 64 64v613.952l-121.28-95.68a83.2 83.2 0 0 0-110.848 7.04l-6.016 6.784-5.312 7.616a83.2 83.2 0 0 0-12.032 34.56l-0.064 1.728H595.2A83.2 83.2 0 0 0 512 787.2v44.8H128a64 64 0 0 1-64-64V128a64 64 0 0 1 64-64h768z" fill="#B5E3CC" p-id="81380"></path><path d="M640 256a32 32 0 1 1 0 64h-32v224a32 32 0 0 1-64 0V320h-64v224a32 32 0 0 1-64 0V320H384a32 32 0 0 1 0-64h256z m160 0a96 96 0 0 1 0 192H768v96a32 32 0 0 1-26.24 31.488L736 576a32 32 0 0 1-32-32v-256a32 32 0 0 1 32-32h64zM768 384h32a32 32 0 1 0 0-64H768v64zM288 256a32 32 0 0 1 32 32v256a32 32 0 0 1-64 0V448H192v96a32 32 0 0 1-64 0v-256a32 32 0 0 1 64 0V384h64V288a32 32 0 0 1 32-32zM772.096 699.712a19.2 19.2 0 0 0-4.096 11.904v56.32L595.2 768a19.2 19.2 0 0 0-19.2 19.2v89.6a19.2 19.2 0 0 0 19.2 19.2H768v56.384a19.2 19.2 0 0 0 31.104 15.104l152.576-120.384a19.2 19.2 0 0 0 0-30.208l-152.576-120.32a19.2 19.2 0 0 0-27.008 3.136z" fill="#129250" p-id="81381"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
1
frontend/public/images/hyperlink.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1767365120766" class="icon" viewBox="0 0 1160 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12589" xmlns:xlink="http://www.w3.org/1999/xlink" width="226.5625" height="200"><path d="M398.5408 736.142222l435.768889-384.568889a44.009244 44.009244 0 0 0 0-67.675022 59.483022 59.483022 0 0 0-76.731733 0l-435.768889 384.568889a43.872711 43.872711 0 0 0 0 67.675022 59.164444 59.164444 0 0 0 76.731733 0z m143.7696-66.582755a39.867733 39.867733 0 0 1 9.102222 25.031111 38.866489 38.866489 0 0 1-13.653333 30.128355L308.929422 926.151111a52.8384 52.8384 0 0 1-68.266666 0L111.047111 811.781689a39.139556 39.139556 0 0 1 0-60.302222l228.192711-201.9328a50.335289 50.335289 0 0 1 34.178845-11.969423 53.748622 53.748622 0 0 1 22.755555 4.551112l69.632-60.848356c-57.617067-41.824711-141.7216-38.365867-194.696533 7.964444L42.052267 690.631111c-56.069689 50.3808-56.069689 131.117511 0 181.4528l130.207289 114.323911a158.651733 158.651733 0 0 0 204.8 0L605.297778 785.066667c54.613333-48.196267 57.025422-125.474133 5.779911-176.355556zM1117.980444 151.916089L988.410311 37.546667c-56.797867-50.062222-148.821333-50.062222-205.664711 0L554.552889 238.933333c-52.519822 46.739911-56.388267 120.968533-9.102222 171.804445L614.4 349.889422a41.688178 41.688178 0 0 1-5.142756-20.48 38.866489 38.866489 0 0 1 13.653334-30.128355l228.875378-201.386667a50.335289 50.335289 0 0 1 34.178844-12.515556 52.383289 52.383289 0 0 1 34.178844 12.515556l129.570134 114.323911a39.139556 39.139556 0 0 1 0 60.302222l-228.192711 201.9328a50.335289 50.335289 0 0 1-34.178845 11.969423 57.7536 57.7536 0 0 1-28.353422-7.418312l-68.266667 60.302223c57.389511 45.101511 144.543289 43.099022 199.202134-4.551111l228.192711-201.9328a117.418667 117.418667 0 0 0 0-180.906667z" fill="#1A97F0" p-id="12590"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.9 KiB |
1
frontend/public/images/lineNumbers.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1767366749042" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="102155" width="200" height="200"><path d="M426.7008 256c0-23.552 19.0976-42.6496 42.6496-42.6496h384a42.6496 42.6496 0 1 1 0 85.2992h-384A42.6496 42.6496 0 0 1 426.7008 256zM426.7008 512c0-23.552 19.0976-42.6496 42.6496-42.6496h384a42.6496 42.6496 0 1 1 0 85.2992h-384A42.6496 42.6496 0 0 1 426.7008 512zM469.2992 768c0-23.552 19.1488-42.6496 42.7008-42.6496h341.2992a42.6496 42.6496 0 0 1 0 85.2992H512A42.6496 42.6496 0 0 1 469.2992 768zM256 640a42.6496 42.6496 0 0 0-42.6496 42.6496 42.6496 42.6496 0 0 1-85.3504 0 128 128 0 1 1 256 0c0 25.856-11.264 45.6192-22.4256 59.8528-8.0384 10.1888-18.5856 20.48-26.8288 28.5184l-5.888 5.8368a42.4448 42.4448 0 0 1-2.8672 2.56l-37.4784 31.232h52.8384a42.6496 42.6496 0 1 1 0 85.3504H170.6496a42.6496 42.6496 0 0 1-27.2896-75.4688l126.5152-105.472 6.5024-6.3488 0.4096-0.4096 7.2704-7.168c4.608-4.608 7.936-8.192 10.3936-11.3664a28.672 28.672 0 0 0 3.9424-6.0928c0.3072-0.7168 0.256-0.9728 0.256-1.024A42.6496 42.6496 0 0 0 256 640zM272.3328 131.2256a42.6496 42.6496 0 0 1 26.3168 39.424v256a42.6496 42.6496 0 0 1-85.2992 0V273.664l-12.4928 12.4928a42.6496 42.6496 0 1 1-60.3648-60.3136l85.3504-85.3504a42.6496 42.6496 0 0 1 46.4896-9.216z" p-id="102156" fill="#87c38f"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
1
frontend/public/images/markdown.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1767365625477" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="51837" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M98.649225 16.619164h734.636904v990.162784h-734.636904z" fill="#FF8A90" p-id="51838"></path><path d="M881.197231 128.411736h-31.940735V32.589531c0-17.642265-14.29847-31.940735-31.940735-31.940735H114.619592c-17.642265 0-31.940735 14.29847-31.940735 31.940735v958.222049c0 17.642265 14.29847 31.940735 31.940735 31.940735h702.696169c17.642265 0 31.940735-14.29847 31.940735-31.940735V415.878351h31.940735c17.642265 0 31.940735-14.29847 31.940735-31.940735V160.352471c0-17.642265-14.29847-31.940735-31.940735-31.940735z m-63.88147 0h-383.288819c-17.642265 0-31.940735 14.29847-31.940735 31.940735V383.937616c0 17.642265 14.29847 31.940735 31.940735 31.940735h383.288819v574.933229H114.619592v-958.222049h702.696169v95.822205z" fill="#2B3139" p-id="51839"></path><path d="M434.026942 160.352471h447.170289V383.937616h-447.170289z" fill="#FFFFFF" p-id="51840"></path><path d="M544.808889 215.175748h49.969783l16.294765 67.025636h0.311922l16.294765-67.025636h49.957306v113.963544h-33.18842v-73.101861h-0.336875l-19.80076 73.101861h-26.176431l-19.788283-73.101861h-0.336875v73.101861h-33.200897zM698.947889 215.175748h57.618092c37.992007 0 51.392143 28.097865 51.392143 56.819573 0 34.947656-18.490691 57.143971-58.241934 57.143971h-50.768301v-113.963544z" fill="#2B3139" p-id="51841"></path><path d="M726.584111 299.918511h13.712058c21.85944 0 25.065991-17.717126 25.065991-28.409787 0-7.174189-2.233356-27.112194-27.611269-27.112194h-11.154303v55.521981z" fill="#FFFFFF" p-id="51842"></path><path d="M630.512369 785.841895l-94.998733-129.709328h57.318647V544.888976h76.445658v111.243591h57.30617L630.487415 785.841895z" fill="#1EB9B0" p-id="51843"></path><path d="M508.139428 785.754557l-76.445657 0.087338v-120.439029l-57.331124 77.194268-57.343601-77.194268v120.439029H240.573389V544.976313h76.445657l57.343601 80.288528 57.331124-80.288528 76.445657-0.087337z" fill="#1EB9B0" p-id="51844"></path></svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
1
frontend/public/images/minimap.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1767367796950" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="18541" width="200" height="200"><path d="M880.489336 512H993.882278v455.107765A56.786824 56.786824 0 0 1 937.185807 1024h-56.681412V512z" fill="#4AC3BB" fill-opacity=".603" p-id="18542"></path><path d="M143.510513 1024a113.182118 113.182118 0 0 1-80.188235-33.325176A113.980235 113.980235 0 0 1 30.117572 910.215529V113.784471C30.117572 83.606588 42.059219 54.663529 63.322278 33.325176A113.182118 113.182118 0 0 1 143.510513 0h510.238118C778.977807 0 880.489336 101.872941 880.489336 227.553882v739.553883A56.786824 56.786824 0 0 0 937.185807 1024H143.510513z" fill="#4AC3BB" p-id="18543"></path><path d="M575.653572 335.329882c64.331294 65.024 66.529882 169.758118 4.954353 237.477647l-4.954353 5.240471-98.063059 122.473412a28.175059 28.175059 0 0 1-21.985882 10.586353 28.175059 28.175059 0 0 1-21.985883-10.586353l-98.078117-122.473412-4.412236-4.638118c-63.503059-68.487529-60.777412-175.841882 6.098824-240.941176a168.478118 168.478118 0 0 1 238.426353 2.861176z m-120.048941 64.150589a56.470588 56.470588 0 0 0-49.016471 28.611764 57.735529 57.735529 0 0 0 0 57.193412 56.470588 56.470588 0 0 0 49.016471 28.611765c31.247059-0.015059 56.576-25.630118 56.576-57.22353 0-31.578353-25.328941-57.193412-56.576-57.193411z" fill="#FFFFFF" fill-opacity=".95" p-id="18544"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
1
frontend/public/images/rainbowBrackets.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1767364585914" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8006" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M960 128c0-35.36-28.704-64.224-63.936-61.728A896.48 896.48 0 0 0 326.4 326.4a896.48 896.48 0 0 0-260.128 569.664C63.776 931.296 92.64 960 128 960c0 0 19.52 0.576 32 0 64-272 84.48-383.68 234.24-533.76C544.32 276.16 752 192 960 160V128z" fill="#F8312F" p-id="8007"></path><path d="M960 256V160a800 800 0 0 0-565.76 234.24A801.344 801.344 0 0 0 160 960h96c32-128 106.24-333.76 238.08-465.92C625.92 362.24 752 304 960 256z" fill="#FFB02E" p-id="8008"></path><path d="M960 256v96c-160 16-284.16 96-398.08 209.92C448 676.16 384 800 352 960H256c0-186.56 74.24-365.76 206.08-497.92A704.32 704.32 0 0 1 960 256z" fill="#FFF478" p-id="8009"></path><path d="M630.08 630.08C534.08 726.08 480 832 448 960h-96c0-161.28 64-315.84 177.92-430.08C643.84 416 798.72 352 960 352v96c-144 32-233.92 86.08-329.92 182.08z" fill="#00D26A" p-id="8010"></path><path d="M960 544v-96c-135.68 0-265.92 54.08-361.92 150.08-96 96-150.08 226.24-150.08 361.92h96c0-110.4 43.84-216.32 121.92-294.08C744 587.84 849.92 544 960 544z" fill="#3F5FFF" p-id="8011"></path><path d="M960 576c0 35.36-28.928 63.36-63.584 70.336a320.384 320.384 0 0 0-250.112 250.08C639.36 931.04 611.392 960 576 960h-32c0-110.4 43.84-216.32 121.92-294.08C744 587.84 849.92 544 960 544v32z" fill="#8D65C5" p-id="8012"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
1
frontend/public/images/search.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg t="1767366992790" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="111373" width="200" height="200"><path d="M581.973333 846.933333a380.8 380.8 0 1 1 380.8-380.8A381.226667 381.226667 0 0 1 581.973333 846.933333z m0-688a307.2 307.2 0 1 0 307.2 307.2 307.413333 307.413333 0 0 0-307.2-307.2z" fill="#FA6302" p-id="111374"></path><path d="M146.56 938.666667a36.906667 36.906667 0 0 1-26.026667-64l192-190.933334a36.906667 36.906667 0 0 1 52.053334 52.266667l-192 192a37.333333 37.333333 0 0 1-26.026667 10.666667z" fill="#43D7B4" p-id="111375"></path><path d="M470.826667 274.773333m-49.066667 0a49.066667 49.066667 0 1 0 98.133333 0 49.066667 49.066667 0 1 0-98.133333 0Z" fill="#43D7B4" p-id="111376"></path><path d="M312.106667 684.8l-23.68 23.466667A388.693333 388.693333 0 0 0 341.333333 760.32l23.466667-23.253333a36.906667 36.906667 0 0 0-52.053333-52.266667z" fill="#425300" p-id="111377"></path></svg>
|
||||||
|
After Width: | Height: | Size: 956 B |
1
frontend/public/images/translator.svg
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
@@ -6,7 +6,10 @@ import {useKeybindingStore} from '@/stores/keybindingStore';
|
|||||||
import {useThemeStore} from '@/stores/themeStore';
|
import {useThemeStore} from '@/stores/themeStore';
|
||||||
import {useUpdateStore} from '@/stores/updateStore';
|
import {useUpdateStore} from '@/stores/updateStore';
|
||||||
import WindowTitleBar from '@/components/titlebar/WindowTitleBar.vue';
|
import WindowTitleBar from '@/components/titlebar/WindowTitleBar.vue';
|
||||||
|
import ToastContainer from '@/components/toast/ToastContainer.vue';
|
||||||
import {useTranslationStore} from "@/stores/translationStore";
|
import {useTranslationStore} from "@/stores/translationStore";
|
||||||
|
import {useI18n} from "vue-i18n";
|
||||||
|
import {LanguageType} from "../bindings/voidraft/internal/models";
|
||||||
|
|
||||||
const configStore = useConfigStore();
|
const configStore = useConfigStore();
|
||||||
const systemStore = useSystemStore();
|
const systemStore = useSystemStore();
|
||||||
@@ -14,18 +17,18 @@ const keybindingStore = useKeybindingStore();
|
|||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
const updateStore = useUpdateStore();
|
const updateStore = useUpdateStore();
|
||||||
const translationStore = useTranslationStore();
|
const translationStore = useTranslationStore();
|
||||||
|
const {locale} = useI18n();
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
// 并行初始化配置、系统信息和快捷键配置
|
// 并行初始化配置、系统信息和快捷键配置
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
configStore.initConfig(),
|
configStore.initConfig(),
|
||||||
systemStore.initializeSystemInfo(),
|
systemStore.initSystemInfo(),
|
||||||
keybindingStore.loadKeyBindings(),
|
keybindingStore.loadKeyBindings(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 初始化语言和主题
|
locale.value = configStore.config.appearance.language || LanguageType.LangEnUS;
|
||||||
await configStore.initializeLanguage();
|
await themeStore.initTheme();
|
||||||
await themeStore.initializeTheme();
|
|
||||||
await translationStore.loadTranslators();
|
await translationStore.loadTranslators();
|
||||||
|
|
||||||
// 启动时检查更新
|
// 启动时检查更新
|
||||||
@@ -39,6 +42,7 @@ onBeforeMount(async () => {
|
|||||||
<div class="app-content">
|
<div class="app-content">
|
||||||
<router-view/>
|
<router-view/>
|
||||||
</div>
|
</div>
|
||||||
|
<ToastContainer/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,254 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
鸿蒙字体压缩工具
|
|
||||||
使用 fonttools 库压缩 TTF 字体文件,减小文件大小
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
import shutil
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import List, Tuple
|
|
||||||
|
|
||||||
def check_dependencies():
|
|
||||||
"""检查必要的依赖是否已安装"""
|
|
||||||
missing_packages = []
|
|
||||||
|
|
||||||
# 检查 fonttools
|
|
||||||
try:
|
|
||||||
import fontTools
|
|
||||||
except ImportError:
|
|
||||||
missing_packages.append('fonttools')
|
|
||||||
|
|
||||||
# 检查 brotli
|
|
||||||
try:
|
|
||||||
import brotli
|
|
||||||
except ImportError:
|
|
||||||
missing_packages.append('brotli')
|
|
||||||
|
|
||||||
# 检查 pyftsubset 命令是否可用
|
|
||||||
try:
|
|
||||||
result = subprocess.run(['pyftsubset', '--help'], capture_output=True, text=True)
|
|
||||||
if result.returncode != 0:
|
|
||||||
missing_packages.append('fonttools[subset]')
|
|
||||||
except FileNotFoundError:
|
|
||||||
if 'fonttools' not in missing_packages:
|
|
||||||
missing_packages.append('fonttools[subset]')
|
|
||||||
|
|
||||||
if missing_packages:
|
|
||||||
print(f"缺少必要的依赖包: {', '.join(missing_packages)}")
|
|
||||||
print("请运行以下命令安装:")
|
|
||||||
print(f"pip install {' '.join(missing_packages)}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_file_size(file_path: str) -> int:
|
|
||||||
"""获取文件大小(字节)"""
|
|
||||||
return os.path.getsize(file_path)
|
|
||||||
|
|
||||||
def format_file_size(size_bytes: int) -> str:
|
|
||||||
"""格式化文件大小显示"""
|
|
||||||
if size_bytes < 1024:
|
|
||||||
return f"{size_bytes} B"
|
|
||||||
elif size_bytes < 1024 * 1024:
|
|
||||||
return f"{size_bytes / 1024:.2f} KB"
|
|
||||||
else:
|
|
||||||
return f"{size_bytes / (1024 * 1024):.2f} MB"
|
|
||||||
|
|
||||||
def compress_font(input_path: str, output_path: str, compression_level: str = "basic") -> bool:
|
|
||||||
"""
|
|
||||||
压缩单个字体文件
|
|
||||||
|
|
||||||
Args:
|
|
||||||
input_path: 输入字体文件路径
|
|
||||||
output_path: 输出字体文件路径
|
|
||||||
compression_level: 压缩级别 ("basic", "medium", "aggressive")
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: 压缩是否成功
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# 基础压缩参数
|
|
||||||
base_args = [
|
|
||||||
"pyftsubset", input_path,
|
|
||||||
"--output-file=" + output_path,
|
|
||||||
"--flavor=woff2", # 输出为 WOFF2 格式,压缩率更高
|
|
||||||
"--with-zopfli", # 使用 Zopfli 算法进一步压缩
|
|
||||||
]
|
|
||||||
|
|
||||||
# 根据压缩级别设置不同的参数
|
|
||||||
if compression_level == "basic":
|
|
||||||
# 基础压缩:保留常用字符和功能
|
|
||||||
args = base_args + [
|
|
||||||
"--unicodes=U+0020-007F,U+00A0-00FF,U+2000-206F,U+2070-209F,U+20A0-20CF", # 基本拉丁字符、标点符号等
|
|
||||||
"--layout-features=*", # 保留所有布局特性
|
|
||||||
"--glyph-names", # 保留字形名称
|
|
||||||
"--symbol-cmap", # 保留符号映射
|
|
||||||
"--legacy-cmap", # 保留传统字符映射
|
|
||||||
"--notdef-glyph", # 保留 .notdef 字形
|
|
||||||
"--recommended-glyphs", # 保留推荐字形
|
|
||||||
"--name-IDs=*", # 保留所有名称ID
|
|
||||||
"--name-legacy", # 保留传统名称
|
|
||||||
]
|
|
||||||
elif compression_level == "medium":
|
|
||||||
# 中等压缩:移除一些不常用的功能
|
|
||||||
args = base_args + [
|
|
||||||
"--unicodes=U+0020-007F,U+00A0-00FF,U+2000-206F", # 减少字符范围
|
|
||||||
"--layout-features=kern,liga,clig", # 只保留关键布局特性
|
|
||||||
"--no-glyph-names", # 移除字形名称
|
|
||||||
"--notdef-glyph",
|
|
||||||
"--name-IDs=1,2,3,4,5,6", # 只保留基本名称ID
|
|
||||||
]
|
|
||||||
else: # aggressive
|
|
||||||
# 激进压缩:最大程度减小文件大小
|
|
||||||
args = base_args + [
|
|
||||||
"--unicodes=U+0020-007F", # 只保留基本ASCII字符
|
|
||||||
"--no-layout-features", # 移除所有布局特性
|
|
||||||
"--no-glyph-names", # 移除字形名称
|
|
||||||
"--no-symbol-cmap", # 移除符号映射
|
|
||||||
"--no-legacy-cmap", # 移除传统映射
|
|
||||||
"--notdef-glyph",
|
|
||||||
"--name-IDs=1,2", # 只保留最基本的名称
|
|
||||||
"--desubroutinize", # 去子程序化(可能减小CFF字体大小)
|
|
||||||
]
|
|
||||||
|
|
||||||
# 执行压缩命令
|
|
||||||
result = subprocess.run(args, capture_output=True, text=True)
|
|
||||||
|
|
||||||
if result.returncode == 0:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"压缩失败: {result.stderr}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"压缩过程中出现错误: {str(e)}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
def find_font_files(directory: str) -> List[str]:
|
|
||||||
"""查找目录中的所有字体文件"""
|
|
||||||
font_extensions = ['.ttf', '.otf', '.woff', '.woff2']
|
|
||||||
font_files = []
|
|
||||||
|
|
||||||
for root, dirs, files in os.walk(directory):
|
|
||||||
for file in files:
|
|
||||||
if any(file.lower().endswith(ext) for ext in font_extensions):
|
|
||||||
font_files.append(os.path.join(root, file))
|
|
||||||
|
|
||||||
return font_files
|
|
||||||
|
|
||||||
def compress_fonts_batch(font_directory: str, compression_level: str = "basic"):
|
|
||||||
"""
|
|
||||||
批量压缩字体文件
|
|
||||||
|
|
||||||
Args:
|
|
||||||
font_directory: 字体文件目录
|
|
||||||
compression_level: 压缩级别
|
|
||||||
"""
|
|
||||||
if not os.path.exists(font_directory):
|
|
||||||
print(f"错误: 目录 {font_directory} 不存在")
|
|
||||||
return
|
|
||||||
|
|
||||||
# 查找所有字体文件
|
|
||||||
font_files = find_font_files(font_directory)
|
|
||||||
|
|
||||||
if not font_files:
|
|
||||||
print("未找到字体文件")
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"找到 {len(font_files)} 个字体文件")
|
|
||||||
print(f"压缩级别: {compression_level}")
|
|
||||||
print(f"压缩后的文件将与源文件放在同一目录,扩展名为 .woff2")
|
|
||||||
print("-" * 60)
|
|
||||||
|
|
||||||
total_original_size = 0
|
|
||||||
total_compressed_size = 0
|
|
||||||
successful_compressions = 0
|
|
||||||
|
|
||||||
for i, font_file in enumerate(font_files, 1):
|
|
||||||
print(f"[{i}/{len(font_files)}] 处理: {os.path.basename(font_file)}")
|
|
||||||
|
|
||||||
# 获取原始文件大小
|
|
||||||
original_size = get_file_size(font_file)
|
|
||||||
total_original_size += original_size
|
|
||||||
|
|
||||||
# 生成输出文件名(保持原文件名,只改变扩展名)
|
|
||||||
file_dir = os.path.dirname(font_file)
|
|
||||||
base_name = os.path.splitext(os.path.basename(font_file))[0]
|
|
||||||
output_file = os.path.join(file_dir, f"{base_name}.woff2")
|
|
||||||
|
|
||||||
# 压缩字体
|
|
||||||
if compress_font(font_file, output_file, compression_level):
|
|
||||||
if os.path.exists(output_file):
|
|
||||||
compressed_size = get_file_size(output_file)
|
|
||||||
total_compressed_size += compressed_size
|
|
||||||
successful_compressions += 1
|
|
||||||
|
|
||||||
# 计算压缩率
|
|
||||||
compression_ratio = (1 - compressed_size / original_size) * 100
|
|
||||||
|
|
||||||
print(f" ✓ 成功: {format_file_size(original_size)} → {format_file_size(compressed_size)} "
|
|
||||||
f"(压缩 {compression_ratio:.1f}%)")
|
|
||||||
else:
|
|
||||||
print(f" ✗ 失败: 输出文件未生成")
|
|
||||||
else:
|
|
||||||
print(f" ✗ 失败: 压缩过程出错")
|
|
||||||
|
|
||||||
print()
|
|
||||||
|
|
||||||
# 显示总结
|
|
||||||
print("=" * 60)
|
|
||||||
print("压缩完成!")
|
|
||||||
print(f"成功压缩: {successful_compressions}/{len(font_files)} 个文件")
|
|
||||||
|
|
||||||
if successful_compressions > 0:
|
|
||||||
total_compression_ratio = (1 - total_compressed_size / total_original_size) * 100
|
|
||||||
print(f"总大小: {format_file_size(total_original_size)} → {format_file_size(total_compressed_size)}")
|
|
||||||
print(f"总压缩率: {total_compression_ratio:.1f}%")
|
|
||||||
print(f"节省空间: {format_file_size(total_original_size - total_compressed_size)}")
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""主函数"""
|
|
||||||
print("鸿蒙字体压缩工具")
|
|
||||||
print("=" * 60)
|
|
||||||
|
|
||||||
# 检查依赖
|
|
||||||
if not check_dependencies():
|
|
||||||
return
|
|
||||||
|
|
||||||
# 获取当前脚本所在目录
|
|
||||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
|
|
||||||
# 设置默认字体目录
|
|
||||||
font_directory = current_dir
|
|
||||||
|
|
||||||
print(f"字体目录: {font_directory}")
|
|
||||||
|
|
||||||
# 让用户选择压缩级别
|
|
||||||
print("\n请选择压缩级别:")
|
|
||||||
print("1. 基础压缩 (保留大部分功能,适合网页使用)")
|
|
||||||
print("2. 中等压缩 (平衡文件大小和功能)")
|
|
||||||
print("3. 激进压缩 (最小文件大小,可能影响显示效果)")
|
|
||||||
|
|
||||||
while True:
|
|
||||||
choice = input("\n请输入选择 (1-3): ").strip()
|
|
||||||
if choice == "1":
|
|
||||||
compression_level = "basic"
|
|
||||||
break
|
|
||||||
elif choice == "2":
|
|
||||||
compression_level = "medium"
|
|
||||||
break
|
|
||||||
elif choice == "3":
|
|
||||||
compression_level = "aggressive"
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
print("无效选择,请输入 1、2 或 3")
|
|
||||||
|
|
||||||
# 开始批量压缩
|
|
||||||
compress_fonts_batch(font_directory, compression_level=compression_level)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-Black.otf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-Black.woff2
Normal file
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-Bold.otf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-Bold.woff2
Normal file
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-ExtraLight.otf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-Italic.otf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-Italic.woff2
Normal file
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-Light.otf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-Light.woff2
Normal file
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-SemiBold.otf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/otf/Monocraft-SemiBold.woff2
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-Black.ttf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-Black.woff2
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-Bold.ttf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-Bold.woff2
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-ExtraLight.ttf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-Italic.ttf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-Italic.woff2
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-Light.ttf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-Light.woff2
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-SemiBold.ttf
Normal file
BIN
frontend/src/assets/fonts/Monocraft/ttf/Monocraft-SemiBold.woff2
Normal file
179
frontend/src/assets/fonts/README.md
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
# 字体压缩工具使用指南
|
||||||
|
|
||||||
|
## 📖 简介
|
||||||
|
|
||||||
|
`font_compressor.py` 是一个通用的字体压缩工具,可以:
|
||||||
|
- ✅ 将 TTF、OTF、WOFF 字体文件转换为 WOFF2 格式
|
||||||
|
- ✅ 支持相对路径和绝对路径
|
||||||
|
- ✅ 自动生成 CSS 字体定义文件
|
||||||
|
- ✅ 智能识别字体字重和样式
|
||||||
|
- ✅ 批量处理整个目录(包括子目录)
|
||||||
|
|
||||||
|
## 🚀 前置要求
|
||||||
|
|
||||||
|
安装 Python 依赖包:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install fonttools brotli
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 使用方法
|
||||||
|
|
||||||
|
### 基础用法
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 进入 fonts 目录
|
||||||
|
cd frontend/src/assets/fonts
|
||||||
|
|
||||||
|
# 交互式模式处理当前目录
|
||||||
|
python font_compressor.py
|
||||||
|
|
||||||
|
# 处理相对路径的 Monocraft 目录
|
||||||
|
python font_compressor.py Monocraft
|
||||||
|
|
||||||
|
# 处理相对路径并指定压缩级别
|
||||||
|
python font_compressor.py Monocraft -l basic
|
||||||
|
```
|
||||||
|
|
||||||
|
### 生成 CSS 文件
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 压缩 Monocraft 字体并生成 CSS 文件
|
||||||
|
python font_compressor.py Monocraft -l basic -c ../styles/monocraft_fonts.css
|
||||||
|
|
||||||
|
# 压缩 Hack 字体并生成 CSS
|
||||||
|
python font_compressor.py Hack -l basic -c ../styles/hack_fonts_new.css
|
||||||
|
|
||||||
|
# 压缩 OpenSans 字体并生成 CSS
|
||||||
|
python font_compressor.py OpenSans -l medium -c ../styles/opensans_fonts.css
|
||||||
|
```
|
||||||
|
|
||||||
|
### 高级用法
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 使用绝对路径
|
||||||
|
python font_compressor.py E:\Go_WorkSpace\voidraft\frontend\src\assets\fonts\Monocraft -l basic -c monocraft.css
|
||||||
|
|
||||||
|
# 不同压缩级别
|
||||||
|
python font_compressor.py Monocraft -l basic # 基础压缩,保留所有功能
|
||||||
|
python font_compressor.py Monocraft -l medium # 中等压缩,平衡大小和功能
|
||||||
|
python font_compressor.py Monocraft -l aggressive # 激进压缩,最小文件
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚙️ 命令行参数
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| `directory` | 字体目录(相对/绝对路径) | `Monocraft` 或 `/path/to/fonts` |
|
||||||
|
| `-l, --level` | 压缩级别 (basic/medium/aggressive) | `-l basic` |
|
||||||
|
| `-c, --css` | CSS 输出文件路径 | `-c monocraft.css` |
|
||||||
|
| `--version` | 显示版本信息 | `--version` |
|
||||||
|
| `-h, --help` | 显示帮助信息 | `-h` |
|
||||||
|
|
||||||
|
## 📊 压缩级别说明
|
||||||
|
|
||||||
|
### basic(基础) - 推荐
|
||||||
|
- 保留大部分字体功能
|
||||||
|
- 适合网页使用
|
||||||
|
- 压缩率约 30-40%
|
||||||
|
|
||||||
|
### medium(中等)
|
||||||
|
- 移除一些不常用的功能
|
||||||
|
- 平衡文件大小和功能
|
||||||
|
- 压缩率约 40-50%
|
||||||
|
|
||||||
|
### aggressive(激进)
|
||||||
|
- 最大程度减小文件大小
|
||||||
|
- 可能影响高级排版功能
|
||||||
|
- 压缩率约 50-60%
|
||||||
|
|
||||||
|
## 📁 输出结果
|
||||||
|
|
||||||
|
### 字体文件
|
||||||
|
压缩后的 `.woff2` 文件会保存在原文件相同的目录下,例如:
|
||||||
|
- `Monocraft/ttf/Monocraft-Bold.ttf` → `Monocraft/ttf/Monocraft-Bold.woff2`
|
||||||
|
- `Hack/hack-regular.ttf` → `Hack/hack-regular.woff2`
|
||||||
|
|
||||||
|
### CSS 文件
|
||||||
|
生成的 CSS 文件会包含:
|
||||||
|
- 自动识别的字体家族名称
|
||||||
|
- 正确的字重和样式设置
|
||||||
|
- 使用相对路径的字体引用
|
||||||
|
- 按字重排序的 `@font-face` 定义
|
||||||
|
|
||||||
|
生成的 CSS 示例:
|
||||||
|
|
||||||
|
```css
|
||||||
|
/* 自动生成的字体文件 */
|
||||||
|
/* 由 font_compressor.py 生成 */
|
||||||
|
|
||||||
|
/* Monocraft 字体家族 */
|
||||||
|
|
||||||
|
/* Monocraft Light */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-Light.woff2') format('woff2');
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Bold */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-Bold.woff2') format('woff2');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 实际使用示例
|
||||||
|
|
||||||
|
### 示例 1: 压缩 Monocraft 字体
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend/src/assets/fonts
|
||||||
|
python font_compressor.py Monocraft -l basic -c ../styles/monocraft_fonts.css
|
||||||
|
```
|
||||||
|
|
||||||
|
这将:
|
||||||
|
1. 扫描 `Monocraft/ttf` 和 `Monocraft/otf` 目录
|
||||||
|
2. 将所有字体文件转换为 WOFF2
|
||||||
|
3. 在 `frontend/src/assets/styles/monocraft_fonts.css` 生成 CSS 文件
|
||||||
|
|
||||||
|
### 示例 2: 批量处理多个字体目录
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend/src/assets/fonts
|
||||||
|
|
||||||
|
# 压缩 Monocraft
|
||||||
|
python font_compressor.py Monocraft -l basic -c ../styles/monocraft_fonts.css
|
||||||
|
|
||||||
|
# 压缩 OpenSans
|
||||||
|
python font_compressor.py OpenSans -l basic -c ../styles/opensans_fonts.css
|
||||||
|
|
||||||
|
# 压缩 Hack(已有 CSS,只需生成新版本对比)
|
||||||
|
python font_compressor.py Hack -l basic -c ../styles/hack_fonts_new.css
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 字体信息自动识别
|
||||||
|
|
||||||
|
工具会自动从文件名识别:
|
||||||
|
- **字重**:Thin(100), Light(300), Regular(400), Medium(500), SemiBold(600), Bold(700), Black(900)
|
||||||
|
- **样式**:normal, italic
|
||||||
|
- **字体家族**:自动去除字重和样式后缀
|
||||||
|
|
||||||
|
支持的命名格式:
|
||||||
|
- `FontName-Bold.ttf`
|
||||||
|
- `FontName_Bold.otf`
|
||||||
|
- `FontName-BoldItalic.ttf`
|
||||||
|
- `FontName_SemiBold_Italic.woff`
|
||||||
|
|
||||||
|
|
||||||
|
## 📞 获取帮助
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python font_compressor.py --help
|
||||||
|
```
|
||||||
|
|
||||||
494
frontend/src/assets/fonts/font_compressor.py
Normal file
@@ -0,0 +1,494 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
通用字体压缩工具
|
||||||
|
使用 fonttools 库将字体文件转换为 WOFF2 格式,减小文件大小
|
||||||
|
支持 TTF、OTF、WOFF 等格式的字体文件
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
import argparse
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List, Tuple, Dict, Optional
|
||||||
|
|
||||||
|
def check_dependencies():
|
||||||
|
"""检查必要的依赖是否已安装"""
|
||||||
|
missing_packages = []
|
||||||
|
|
||||||
|
# 检查 fonttools
|
||||||
|
try:
|
||||||
|
import fontTools
|
||||||
|
except ImportError:
|
||||||
|
missing_packages.append('fonttools')
|
||||||
|
|
||||||
|
# 检查 brotli
|
||||||
|
try:
|
||||||
|
import brotli
|
||||||
|
except ImportError:
|
||||||
|
missing_packages.append('brotli')
|
||||||
|
|
||||||
|
# 检查 pyftsubset 命令是否可用
|
||||||
|
try:
|
||||||
|
result = subprocess.run(['pyftsubset', '--help'], capture_output=True, text=True)
|
||||||
|
if result.returncode != 0:
|
||||||
|
missing_packages.append('fonttools[subset]')
|
||||||
|
except FileNotFoundError:
|
||||||
|
if 'fonttools' not in missing_packages:
|
||||||
|
missing_packages.append('fonttools[subset]')
|
||||||
|
|
||||||
|
if missing_packages:
|
||||||
|
print(f"缺少必要的依赖包: {', '.join(missing_packages)}")
|
||||||
|
print("请运行以下命令安装:")
|
||||||
|
print(f"pip install {' '.join(missing_packages)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_file_size(file_path: str) -> int:
|
||||||
|
"""获取文件大小(字节)"""
|
||||||
|
return os.path.getsize(file_path)
|
||||||
|
|
||||||
|
def format_file_size(size_bytes: int) -> str:
|
||||||
|
"""格式化文件大小显示"""
|
||||||
|
if size_bytes < 1024:
|
||||||
|
return f"{size_bytes} B"
|
||||||
|
elif size_bytes < 1024 * 1024:
|
||||||
|
return f"{size_bytes / 1024:.2f} KB"
|
||||||
|
else:
|
||||||
|
return f"{size_bytes / (1024 * 1024):.2f} MB"
|
||||||
|
|
||||||
|
def compress_font(input_path: str, output_path: str, compression_level: str = "basic") -> bool:
|
||||||
|
"""
|
||||||
|
压缩单个字体文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
input_path: 输入字体文件路径
|
||||||
|
output_path: 输出字体文件路径
|
||||||
|
compression_level: 压缩级别 ("basic", "medium", "aggressive")
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 压缩是否成功
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 基础压缩参数
|
||||||
|
base_args = [
|
||||||
|
"pyftsubset", input_path,
|
||||||
|
"--output-file=" + output_path,
|
||||||
|
"--flavor=woff2", # 输出为 WOFF2 格式,压缩率更高
|
||||||
|
"--with-zopfli", # 使用 Zopfli 算法进一步压缩
|
||||||
|
]
|
||||||
|
|
||||||
|
# 根据压缩级别设置不同的参数
|
||||||
|
if compression_level == "basic":
|
||||||
|
# 基础压缩:保留常用字符和功能
|
||||||
|
args = base_args + [
|
||||||
|
"--unicodes=U+0020-007F,U+00A0-00FF,U+2000-206F,U+2070-209F,U+20A0-20CF", # 基本拉丁字符、标点符号等
|
||||||
|
"--layout-features=*", # 保留所有布局特性
|
||||||
|
"--glyph-names", # 保留字形名称
|
||||||
|
"--symbol-cmap", # 保留符号映射
|
||||||
|
"--legacy-cmap", # 保留传统字符映射
|
||||||
|
"--notdef-glyph", # 保留 .notdef 字形
|
||||||
|
"--recommended-glyphs", # 保留推荐字形
|
||||||
|
"--name-IDs=*", # 保留所有名称ID
|
||||||
|
"--name-legacy", # 保留传统名称
|
||||||
|
]
|
||||||
|
elif compression_level == "medium":
|
||||||
|
# 中等压缩:移除一些不常用的功能
|
||||||
|
args = base_args + [
|
||||||
|
"--unicodes=U+0020-007F,U+00A0-00FF,U+2000-206F", # 减少字符范围
|
||||||
|
"--layout-features=kern,liga,clig", # 只保留关键布局特性
|
||||||
|
"--no-glyph-names", # 移除字形名称
|
||||||
|
"--notdef-glyph",
|
||||||
|
"--name-IDs=1,2,3,4,5,6", # 只保留基本名称ID
|
||||||
|
]
|
||||||
|
else: # aggressive
|
||||||
|
# 激进压缩:最大程度减小文件大小
|
||||||
|
args = base_args + [
|
||||||
|
"--unicodes=U+0020-007F", # 只保留基本ASCII字符
|
||||||
|
"--no-layout-features", # 移除所有布局特性
|
||||||
|
"--no-glyph-names", # 移除字形名称
|
||||||
|
"--no-symbol-cmap", # 移除符号映射
|
||||||
|
"--no-legacy-cmap", # 移除传统映射
|
||||||
|
"--notdef-glyph",
|
||||||
|
"--name-IDs=1,2", # 只保留最基本的名称
|
||||||
|
"--desubroutinize", # 去子程序化(可能减小CFF字体大小)
|
||||||
|
]
|
||||||
|
|
||||||
|
# 执行压缩命令
|
||||||
|
result = subprocess.run(args, capture_output=True, text=True)
|
||||||
|
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"压缩失败: {result.stderr}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"压缩过程中出现错误: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def find_font_files(directory: str, exclude_woff2: bool = False) -> List[str]:
|
||||||
|
"""查找目录中的所有字体文件"""
|
||||||
|
if exclude_woff2:
|
||||||
|
font_extensions = ['.ttf', '.otf', '.woff']
|
||||||
|
else:
|
||||||
|
font_extensions = ['.ttf', '.otf', '.woff', '.woff2']
|
||||||
|
font_files = []
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(directory):
|
||||||
|
for file in files:
|
||||||
|
if any(file.lower().endswith(ext) for ext in font_extensions):
|
||||||
|
font_files.append(os.path.join(root, file))
|
||||||
|
|
||||||
|
return font_files
|
||||||
|
|
||||||
|
def parse_font_info(filename: str) -> Dict[str, any]:
|
||||||
|
"""
|
||||||
|
从字体文件名解析字体信息(字重、样式等)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filename: 字体文件名(不含路径)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
包含字体信息的字典
|
||||||
|
"""
|
||||||
|
# 移除扩展名
|
||||||
|
name_without_ext = os.path.splitext(filename)[0]
|
||||||
|
|
||||||
|
# 字重映射
|
||||||
|
weight_mapping = {
|
||||||
|
'thin': (100, 'Thin'),
|
||||||
|
'extralight': (200, 'ExtraLight'),
|
||||||
|
'light': (300, 'Light'),
|
||||||
|
'regular': (400, 'Regular'),
|
||||||
|
'normal': (400, 'Regular'),
|
||||||
|
'medium': (500, 'Medium'),
|
||||||
|
'semibold': (600, 'SemiBold'),
|
||||||
|
'bold': (700, 'Bold'),
|
||||||
|
'extrabold': (800, 'ExtraBold'),
|
||||||
|
'black': (900, 'Black'),
|
||||||
|
'heavy': (900, 'Heavy'),
|
||||||
|
}
|
||||||
|
|
||||||
|
# 默认值
|
||||||
|
font_weight = 400
|
||||||
|
font_style = 'normal'
|
||||||
|
weight_name = 'Regular'
|
||||||
|
|
||||||
|
# 检查是否为斜体
|
||||||
|
if re.search(r'italic', name_without_ext, re.IGNORECASE):
|
||||||
|
font_style = 'italic'
|
||||||
|
|
||||||
|
# 检查字重
|
||||||
|
name_lower = name_without_ext.lower()
|
||||||
|
for weight_key, (weight_value, weight_label) in weight_mapping.items():
|
||||||
|
if weight_key in name_lower:
|
||||||
|
font_weight = weight_value
|
||||||
|
weight_name = weight_label
|
||||||
|
break
|
||||||
|
|
||||||
|
# 提取字体家族名称(移除字重和样式后缀)
|
||||||
|
family_name = name_without_ext
|
||||||
|
for weight_key, (_, weight_label) in weight_mapping.items():
|
||||||
|
family_name = re.sub(r'[-_]?' + weight_label, '', family_name, flags=re.IGNORECASE)
|
||||||
|
family_name = re.sub(r'[-_]?italic', '', family_name, flags=re.IGNORECASE)
|
||||||
|
family_name = family_name.strip('-_')
|
||||||
|
|
||||||
|
return {
|
||||||
|
'family': family_name,
|
||||||
|
'weight': font_weight,
|
||||||
|
'style': font_style,
|
||||||
|
'weight_name': weight_name,
|
||||||
|
'full_name': name_without_ext
|
||||||
|
}
|
||||||
|
|
||||||
|
def generate_css(font_files: List[str], output_css_path: str, css_base_path: str):
|
||||||
|
"""
|
||||||
|
生成CSS字体文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
font_files: 字体文件路径列表(woff2文件)
|
||||||
|
output_css_path: 输出CSS文件路径
|
||||||
|
css_base_path: CSS文件相对于字体文件的基础路径
|
||||||
|
"""
|
||||||
|
# 按字体家族分组
|
||||||
|
font_groups: Dict[str, List[Dict]] = {}
|
||||||
|
|
||||||
|
for font_file in font_files:
|
||||||
|
if not font_file.endswith('.woff2'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
filename = os.path.basename(font_file)
|
||||||
|
font_info = parse_font_info(filename)
|
||||||
|
|
||||||
|
# 计算相对路径
|
||||||
|
font_dir = os.path.dirname(font_file)
|
||||||
|
css_dir = os.path.dirname(output_css_path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 计算从CSS文件到字体文件的相对路径
|
||||||
|
rel_path = os.path.relpath(font_file, css_dir)
|
||||||
|
# 统一使用正斜杠(适用于Web)
|
||||||
|
rel_path = rel_path.replace('\\', '/')
|
||||||
|
except ValueError:
|
||||||
|
# 如果在不同驱动器上,使用绝对路径
|
||||||
|
rel_path = font_file.replace('\\', '/')
|
||||||
|
|
||||||
|
font_info['path'] = rel_path
|
||||||
|
|
||||||
|
family = font_info['family']
|
||||||
|
if family not in font_groups:
|
||||||
|
font_groups[family] = []
|
||||||
|
font_groups[family].append(font_info)
|
||||||
|
|
||||||
|
# 生成CSS内容
|
||||||
|
css_lines = ['/* 自动生成的字体文件 */', '/* 由 font_compressor.py 生成 */', '']
|
||||||
|
|
||||||
|
for family, fonts in sorted(font_groups.items()):
|
||||||
|
css_lines.append(f'/* {family} 字体家族 */')
|
||||||
|
css_lines.append('')
|
||||||
|
|
||||||
|
# 按字重排序
|
||||||
|
fonts.sort(key=lambda x: (x['weight'], x['style']))
|
||||||
|
|
||||||
|
for font in fonts:
|
||||||
|
css_lines.append(f"/* {family} {font['weight_name']}{' Italic' if font['style'] == 'italic' else ''} */")
|
||||||
|
css_lines.append('@font-face {')
|
||||||
|
css_lines.append(f" font-family: '{family}';")
|
||||||
|
css_lines.append(f" src: url('{font['path']}') format('woff2');")
|
||||||
|
css_lines.append(f" font-weight: {font['weight']};")
|
||||||
|
css_lines.append(f" font-style: {font['style']};")
|
||||||
|
css_lines.append(' font-display: swap;')
|
||||||
|
css_lines.append('}')
|
||||||
|
css_lines.append('')
|
||||||
|
|
||||||
|
# 写入CSS文件
|
||||||
|
with open(output_css_path, 'w', encoding='utf-8') as f:
|
||||||
|
f.write('\n'.join(css_lines))
|
||||||
|
|
||||||
|
print(f"[OK] CSS文件已生成: {output_css_path}")
|
||||||
|
print(f" 包含 {sum(len(fonts) for fonts in font_groups.values())} 个字体定义")
|
||||||
|
print(f" 字体家族: {', '.join(sorted(font_groups.keys()))}")
|
||||||
|
|
||||||
|
def compress_fonts_batch(font_directory: str, compression_level: str = "basic") -> List[str]:
|
||||||
|
"""
|
||||||
|
批量压缩字体文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
font_directory: 字体文件目录
|
||||||
|
compression_level: 压缩级别
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
生成的woff2文件路径列表
|
||||||
|
"""
|
||||||
|
if not os.path.exists(font_directory):
|
||||||
|
print(f"错误: 目录 {font_directory} 不存在")
|
||||||
|
return []
|
||||||
|
|
||||||
|
# 查找所有字体文件(排除已经是woff2的)
|
||||||
|
font_files = find_font_files(font_directory, exclude_woff2=True)
|
||||||
|
|
||||||
|
if not font_files:
|
||||||
|
print("未找到字体文件")
|
||||||
|
return []
|
||||||
|
|
||||||
|
print(f"找到 {len(font_files)} 个字体文件")
|
||||||
|
print(f"压缩级别: {compression_level}")
|
||||||
|
print(f"压缩后的文件将与源文件放在同一目录,扩展名为 .woff2")
|
||||||
|
print("-" * 60)
|
||||||
|
|
||||||
|
total_original_size = 0
|
||||||
|
total_compressed_size = 0
|
||||||
|
successful_compressions = 0
|
||||||
|
generated_woff2_files = []
|
||||||
|
|
||||||
|
for i, font_file in enumerate(font_files, 1):
|
||||||
|
print(f"[{i}/{len(font_files)}] 处理: {os.path.basename(font_file)}")
|
||||||
|
|
||||||
|
# 获取原始文件大小
|
||||||
|
original_size = get_file_size(font_file)
|
||||||
|
total_original_size += original_size
|
||||||
|
|
||||||
|
# 生成输出文件名(保持原文件名,只改变扩展名)
|
||||||
|
file_dir = os.path.dirname(font_file)
|
||||||
|
base_name = os.path.splitext(os.path.basename(font_file))[0]
|
||||||
|
output_file = os.path.join(file_dir, f"{base_name}.woff2")
|
||||||
|
|
||||||
|
# 压缩字体
|
||||||
|
if compress_font(font_file, output_file, compression_level):
|
||||||
|
if os.path.exists(output_file):
|
||||||
|
compressed_size = get_file_size(output_file)
|
||||||
|
total_compressed_size += compressed_size
|
||||||
|
successful_compressions += 1
|
||||||
|
generated_woff2_files.append(output_file)
|
||||||
|
|
||||||
|
# 计算压缩率
|
||||||
|
compression_ratio = (1 - compressed_size / original_size) * 100
|
||||||
|
|
||||||
|
print(f" [OK] 成功: {format_file_size(original_size)} -> {format_file_size(compressed_size)} "
|
||||||
|
f"(压缩 {compression_ratio:.1f}%)")
|
||||||
|
else:
|
||||||
|
print(f" [失败] 输出文件未生成")
|
||||||
|
else:
|
||||||
|
print(f" [失败] 压缩过程出错")
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 显示总结
|
||||||
|
print("=" * 60)
|
||||||
|
print("压缩完成!")
|
||||||
|
print(f"成功压缩: {successful_compressions}/{len(font_files)} 个文件")
|
||||||
|
|
||||||
|
if successful_compressions > 0:
|
||||||
|
total_compression_ratio = (1 - total_compressed_size / total_original_size) * 100
|
||||||
|
print(f"总大小: {format_file_size(total_original_size)} → {format_file_size(total_compressed_size)}")
|
||||||
|
print(f"总压缩率: {total_compression_ratio:.1f}%")
|
||||||
|
print(f"节省空间: {format_file_size(total_original_size - total_compressed_size)}")
|
||||||
|
|
||||||
|
return generated_woff2_files
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
# 解析命令行参数
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='通用字体压缩工具 - 将字体文件转换为 WOFF2 格式并生成CSS',
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
epilog='''
|
||||||
|
使用示例:
|
||||||
|
%(prog)s # 交互式模式,处理当前目录
|
||||||
|
%(prog)s Monocraft # 处理相对路径目录
|
||||||
|
%(prog)s Monocraft -l basic # 使用基础压缩级别
|
||||||
|
%(prog)s Monocraft -l basic -c monocraft.css # 压缩并生成CSS文件
|
||||||
|
%(prog)s /path/to/fonts -l medium -c fonts.css # 使用绝对路径
|
||||||
|
|
||||||
|
压缩级别说明:
|
||||||
|
basic - 基础压缩:保留大部分功能,适合网页使用
|
||||||
|
medium - 中等压缩:平衡文件大小和功能
|
||||||
|
aggressive - 激进压缩:最小文件大小,可能影响显示效果
|
||||||
|
|
||||||
|
CSS生成说明:
|
||||||
|
使用 -c/--css 选项生成CSS文件,自动使用相对路径引用字体文件
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'directory',
|
||||||
|
nargs='?',
|
||||||
|
default=None,
|
||||||
|
help='字体文件目录路径(支持相对/绝对路径,默认为当前脚本所在目录)'
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-l', '--level',
|
||||||
|
choices=['basic', 'medium', 'aggressive'],
|
||||||
|
default=None,
|
||||||
|
help='压缩级别:basic(基础)、medium(中等)、aggressive(激进)'
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'-c', '--css',
|
||||||
|
default=None,
|
||||||
|
help='生成CSS文件路径(相对于脚本位置或绝对路径)'
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'--version',
|
||||||
|
action='version',
|
||||||
|
version='%(prog)s 2.0'
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
print("=" * 60)
|
||||||
|
print("通用字体压缩工具 v2.0")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# 检查依赖
|
||||||
|
if not check_dependencies():
|
||||||
|
return
|
||||||
|
|
||||||
|
# 获取脚本所在目录
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
# 确定字体目录
|
||||||
|
if args.directory:
|
||||||
|
# 支持相对路径和绝对路径
|
||||||
|
if os.path.isabs(args.directory):
|
||||||
|
font_directory = args.directory
|
||||||
|
else:
|
||||||
|
font_directory = os.path.join(script_dir, args.directory)
|
||||||
|
font_directory = os.path.abspath(font_directory)
|
||||||
|
else:
|
||||||
|
# 默认使用当前脚本所在目录
|
||||||
|
font_directory = script_dir
|
||||||
|
|
||||||
|
# 检查目录是否存在
|
||||||
|
if not os.path.exists(font_directory):
|
||||||
|
print(f"\n错误: 目录不存在: {font_directory}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"\n字体目录: {font_directory}")
|
||||||
|
|
||||||
|
# 确定压缩级别
|
||||||
|
compression_level = args.level
|
||||||
|
|
||||||
|
if compression_level is None:
|
||||||
|
# 交互式选择压缩级别
|
||||||
|
print("\n请选择压缩级别:")
|
||||||
|
print("1. 基础压缩 (保留大部分功能,适合网页使用)")
|
||||||
|
print("2. 中等压缩 (平衡文件大小和功能)")
|
||||||
|
print("3. 激进压缩 (最小文件大小,可能影响显示效果)")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
choice = input("\n请输入选择 (1-3): ").strip()
|
||||||
|
if choice == "1":
|
||||||
|
compression_level = "basic"
|
||||||
|
break
|
||||||
|
elif choice == "2":
|
||||||
|
compression_level = "medium"
|
||||||
|
break
|
||||||
|
elif choice == "3":
|
||||||
|
compression_level = "aggressive"
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("无效选择,请输入 1、2 或 3")
|
||||||
|
|
||||||
|
# 开始批量压缩
|
||||||
|
print()
|
||||||
|
generated_files = compress_fonts_batch(font_directory, compression_level=compression_level)
|
||||||
|
|
||||||
|
# 生成CSS文件
|
||||||
|
if args.css and generated_files:
|
||||||
|
print()
|
||||||
|
print("=" * 60)
|
||||||
|
print("生成CSS文件...")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# 确定CSS输出路径
|
||||||
|
if os.path.isabs(args.css):
|
||||||
|
css_path = args.css
|
||||||
|
else:
|
||||||
|
css_path = os.path.join(script_dir, args.css)
|
||||||
|
css_path = os.path.abspath(css_path)
|
||||||
|
|
||||||
|
# 确保输出目录存在
|
||||||
|
css_dir = os.path.dirname(css_path)
|
||||||
|
if css_dir and not os.path.exists(css_dir):
|
||||||
|
os.makedirs(css_dir)
|
||||||
|
|
||||||
|
# 生成CSS
|
||||||
|
generate_css(generated_files, css_path, script_dir)
|
||||||
|
elif args.css and not generated_files:
|
||||||
|
print("\n警告: 没有成功生成WOFF2文件,跳过CSS生成")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("=" * 60)
|
||||||
|
print("全部完成!")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
1
frontend/src/assets/images/translator.svg
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
@@ -1,7 +1,9 @@
|
|||||||
/* 导入所有CSS文件 */
|
/* 导入所有CSS文件 */
|
||||||
@import 'normalize.css';
|
@import 'normalize.css';
|
||||||
@import 'variables.css';
|
|
||||||
@import "harmony_fonts.css";
|
@import "harmony_fonts.css";
|
||||||
@import 'scrollbar.css';
|
|
||||||
@import 'hack_fonts.css';
|
@import 'hack_fonts.css';
|
||||||
@import 'opensans_fonts.css';
|
@import 'opensans_fonts.css';
|
||||||
|
@import "monocraft_fonts.css";
|
||||||
|
@import 'variables.css';
|
||||||
|
@import 'scrollbar.css';
|
||||||
|
@import 'styles.css';
|
||||||
202
frontend/src/assets/styles/monocraft_fonts.css
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
/* 自动生成的字体文件 */
|
||||||
|
/* 由 font_compressor.py 生成 */
|
||||||
|
|
||||||
|
/* Monocraft 字体家族 */
|
||||||
|
|
||||||
|
/* Monocraft ExtraLight Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-ExtraLight-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 200;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft ExtraLight Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-ExtraLight-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 200;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft ExtraLight */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-ExtraLight.woff2') format('woff2');
|
||||||
|
font-weight: 200;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft ExtraLight */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-ExtraLight.woff2') format('woff2');
|
||||||
|
font-weight: 200;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Light Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-Light-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Light Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-Light-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Light */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-Light.woff2') format('woff2');
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Light */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-Light.woff2') format('woff2');
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Regular Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Regular Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft SemiBold Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-SemiBold-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 600;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft SemiBold Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-SemiBold-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 600;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft SemiBold */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-SemiBold.woff2') format('woff2');
|
||||||
|
font-weight: 600;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft SemiBold */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-SemiBold.woff2') format('woff2');
|
||||||
|
font-weight: 600;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Bold Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-Bold-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Bold Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-Bold-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Bold */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-Bold.woff2') format('woff2');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Bold */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-Bold.woff2') format('woff2');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Black Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-Black-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Black Italic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-Black-Italic.woff2') format('woff2');
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Black */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/otf/Monocraft-Black.woff2') format('woff2');
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monocraft Black */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Monocraft';
|
||||||
|
src: url('../fonts/Monocraft/ttf/Monocraft-Black.woff2') format('woff2');
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
3
frontend/src/assets/styles/styles.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
body {
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
}
|
||||||
@@ -1,255 +1,266 @@
|
|||||||
:root {
|
:root {
|
||||||
/* 编辑器区域 */
|
--voidraft-font-mono: "HarmonyOS", SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace;
|
||||||
--text-primary: #9BB586; /* 内容区域字体颜色 */
|
|
||||||
|
|
||||||
/* 深色主题颜色变量 */
|
|
||||||
--dark-toolbar-bg: #2d2d2d;
|
|
||||||
--dark-toolbar-border: #404040;
|
|
||||||
--dark-toolbar-text: #ffffff;
|
|
||||||
--dark-toolbar-text-secondary: #cccccc;
|
|
||||||
--dark-toolbar-button-hover: #404040;
|
|
||||||
--dark-tab-active-line: linear-gradient(90deg, #007acc 0%, #0099ff 100%);
|
|
||||||
--dark-bg-secondary: #0E1217;
|
|
||||||
--dark-text-secondary: #a0aec0;
|
|
||||||
--dark-text-muted: #666;
|
|
||||||
--dark-border-color: #2d3748;
|
|
||||||
--dark-settings-bg: #2a2a2a;
|
|
||||||
--dark-settings-card-bg: #333333;
|
|
||||||
--dark-settings-text: #ffffff;
|
|
||||||
--dark-settings-text-secondary: #cccccc;
|
|
||||||
--dark-settings-border: #444444;
|
|
||||||
--dark-settings-input-bg: #3a3a3a;
|
|
||||||
--dark-settings-input-border: #555555;
|
|
||||||
--dark-settings-hover: #404040;
|
|
||||||
--dark-scrollbar-track: #2a2a2a;
|
|
||||||
--dark-scrollbar-thumb: #555555;
|
|
||||||
--dark-scrollbar-thumb-hover: #666666;
|
|
||||||
--dark-selection-bg: rgba(181, 206, 168, 0.1);
|
|
||||||
--dark-selection-text: #b5cea8;
|
|
||||||
--dark-danger-color: #ff6b6b;
|
|
||||||
--dark-bg-primary: #1a1a1a;
|
|
||||||
--dark-bg-hover: #2a2a2a;
|
|
||||||
--dark-loading-bg-gradient: radial-gradient(#222922, #000500);
|
|
||||||
--dark-loading-color: #fff;
|
|
||||||
--dark-loading-glow: 0 0 10px rgba(50, 255, 50, 0.5), 0 0 5px rgba(100, 255, 100, 0.5);
|
|
||||||
--dark-loading-done-color: #6f6;
|
|
||||||
--dark-loading-overlay: linear-gradient(transparent 0%, rgba(10, 16, 10, 0.5) 50%);
|
|
||||||
|
|
||||||
/* 浅色主题颜色变量 */
|
|
||||||
--light-toolbar-bg: #f8f9fa;
|
|
||||||
--light-toolbar-border: #e9ecef;
|
|
||||||
--light-toolbar-text: #212529;
|
|
||||||
--light-toolbar-text-secondary: #495057;
|
|
||||||
--light-toolbar-button-hover: #e9ecef;
|
|
||||||
--light-tab-active-line: linear-gradient(90deg, #0066cc 0%, #0088ff 100%);
|
|
||||||
--light-bg-secondary: #f7fef7;
|
|
||||||
--light-text-secondary: #374151;
|
|
||||||
--light-text-muted: #6b7280;
|
|
||||||
--light-border-color: #e5e7eb;
|
|
||||||
--light-settings-bg: #ffffff;
|
|
||||||
--light-settings-card-bg: #f8f9fa;
|
|
||||||
--light-settings-text: #212529;
|
|
||||||
--light-settings-text-secondary: #6c757d;
|
|
||||||
--light-settings-border: #dee2e6;
|
|
||||||
--light-settings-input-bg: #ffffff;
|
|
||||||
--light-settings-input-border: #ced4da;
|
|
||||||
--light-settings-hover: #e9ecef;
|
|
||||||
--light-scrollbar-track: #f1f3f4;
|
|
||||||
--light-scrollbar-thumb: #c1c1c1;
|
|
||||||
--light-scrollbar-thumb-hover: #a8a8a8;
|
|
||||||
--light-selection-bg: rgba(59, 130, 246, 0.15);
|
|
||||||
--light-selection-text: #2563eb;
|
|
||||||
--light-danger-color: #dc3545;
|
|
||||||
--light-bg-primary: #ffffff;
|
|
||||||
--light-bg-hover: #f1f3f4;
|
|
||||||
--light-loading-bg-gradient: radial-gradient(#f0f6f0, #e5efe5);
|
|
||||||
--light-loading-color: #1a3c1a;
|
|
||||||
--light-loading-glow: 0 0 10px rgba(0, 160, 0, 0.3), 0 0 5px rgba(0, 120, 0, 0.2);
|
|
||||||
--light-loading-done-color: #008800;
|
|
||||||
--light-loading-overlay: linear-gradient(transparent 0%, rgba(220, 240, 220, 0.5) 50%);
|
|
||||||
|
|
||||||
/* 默认使用深色主题 */
|
|
||||||
--toolbar-bg: var(--dark-toolbar-bg);
|
|
||||||
--toolbar-border: var(--dark-toolbar-border);
|
|
||||||
--toolbar-text: var(--dark-toolbar-text);
|
|
||||||
--toolbar-text-secondary: var(--dark-toolbar-text-secondary);
|
|
||||||
--toolbar-button-hover: var(--dark-toolbar-button-hover);
|
|
||||||
--toolbar-separator: var(--dark-toolbar-button-hover);
|
|
||||||
--tab-active-line: var(--dark-tab-active-line);
|
|
||||||
--bg-secondary: var(--dark-bg-secondary);
|
|
||||||
--text-secondary: var(--dark-text-secondary);
|
|
||||||
--text-muted: var(--dark-text-muted);
|
|
||||||
--border-color: var(--dark-border-color);
|
|
||||||
--settings-bg: var(--dark-settings-bg);
|
|
||||||
--settings-card-bg: var(--dark-settings-card-bg);
|
|
||||||
--settings-text: var(--dark-settings-text);
|
|
||||||
--settings-text-secondary: var(--dark-settings-text-secondary);
|
|
||||||
--settings-border: var(--dark-settings-border);
|
|
||||||
--settings-input-bg: var(--dark-settings-input-bg);
|
|
||||||
--settings-input-border: var(--dark-settings-input-border);
|
|
||||||
--settings-hover: var(--dark-settings-hover);
|
|
||||||
--scrollbar-track: var(--dark-scrollbar-track);
|
|
||||||
--scrollbar-thumb: var(--dark-scrollbar-thumb);
|
|
||||||
--scrollbar-thumb-hover: var(--dark-scrollbar-thumb-hover);
|
|
||||||
--selection-bg: var(--dark-selection-bg);
|
|
||||||
--selection-text: var(--dark-selection-text);
|
|
||||||
--text-danger: var(--dark-danger-color);
|
|
||||||
--bg-primary: var(--dark-bg-primary);
|
|
||||||
--bg-hover: var(--dark-bg-hover);
|
|
||||||
--voidraft-bg-gradient: var(--dark-loading-bg-gradient);
|
|
||||||
--voidraft-loading-color: var(--dark-loading-color);
|
|
||||||
--voidraft-loading-glow: var(--dark-loading-glow);
|
|
||||||
--voidraft-loading-done-color: var(--dark-loading-done-color);
|
|
||||||
--voidraft-loading-overlay: var(--dark-loading-overlay);
|
|
||||||
--voidraft-mono-font: "HarmonyOS Sans Mono", monospace;
|
|
||||||
|
|
||||||
color-scheme: light dark;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 监听系统深色主题 */
|
/* 默认/暗色主题 */
|
||||||
@media (prefers-color-scheme: dark) {
|
:root,
|
||||||
|
:root[data-theme="dark"],
|
||||||
:root[data-theme="auto"] {
|
:root[data-theme="auto"] {
|
||||||
--toolbar-bg: var(--dark-toolbar-bg);
|
color-scheme: dark;
|
||||||
--toolbar-border: var(--dark-toolbar-border);
|
|
||||||
--toolbar-text: var(--dark-toolbar-text);
|
--text-primary: #ffffff;
|
||||||
--toolbar-text-secondary: var(--dark-toolbar-text-secondary);
|
|
||||||
--toolbar-button-hover: var(--dark-toolbar-button-hover);
|
--toolbar-bg: #2d2d2d;
|
||||||
--toolbar-separator: var(--dark-toolbar-button-hover);
|
--toolbar-border: #404040;
|
||||||
--tab-active-line: var(--dark-tab-active-line);
|
--toolbar-text: #ffffff;
|
||||||
--bg-secondary: var(--dark-bg-secondary);
|
--toolbar-text-secondary: #cccccc;
|
||||||
--text-secondary: var(--dark-text-secondary);
|
--toolbar-button-hover: #404040;
|
||||||
--text-muted: var(--dark-text-muted);
|
--toolbar-separator: #404040;
|
||||||
--border-color: var(--dark-border-color);
|
|
||||||
--settings-bg: var(--dark-settings-bg);
|
--tab-active-line: linear-gradient(90deg, #007acc 0%, #0099ff 100%);
|
||||||
--settings-card-bg: var(--dark-settings-card-bg);
|
--bg-secondary: #0e1217;
|
||||||
--settings-text: var(--dark-settings-text);
|
--bg-primary: #1a1a1a;
|
||||||
--settings-text-secondary: var(--dark-settings-text-secondary);
|
--bg-hover: #2a2a2a;
|
||||||
--settings-border: var(--dark-settings-border);
|
|
||||||
--settings-input-bg: var(--dark-settings-input-bg);
|
--text-secondary: #a0aec0;
|
||||||
--settings-input-border: var(--dark-settings-input-border);
|
--text-muted: #666666;
|
||||||
--settings-hover: var(--dark-settings-hover);
|
--text-danger: #ff6b6b;
|
||||||
--scrollbar-track: var(--dark-scrollbar-track);
|
|
||||||
--scrollbar-thumb: var(--dark-scrollbar-thumb);
|
--border-color: #2d3748;
|
||||||
--scrollbar-thumb-hover: var(--dark-scrollbar-thumb-hover);
|
|
||||||
--selection-bg: var(--dark-selection-bg);
|
--settings-bg: #2a2a2a;
|
||||||
--selection-text: var(--dark-selection-text);
|
--settings-card-bg: #333333;
|
||||||
--text-danger: var(--dark-danger-color);
|
--settings-text: #ffffff;
|
||||||
--bg-primary: var(--dark-bg-primary);
|
--settings-text-secondary: #cccccc;
|
||||||
--bg-hover: var(--dark-bg-hover);
|
--settings-border: #444444;
|
||||||
--voidraft-bg-gradient: var(--dark-loading-bg-gradient);
|
--settings-input-bg: #3a3a3a;
|
||||||
--voidraft-loading-color: var(--dark-loading-color);
|
--settings-input-border: #555555;
|
||||||
--voidraft-loading-glow: var(--dark-loading-glow);
|
--settings-hover: #404040;
|
||||||
--voidraft-loading-done-color: var(--dark-loading-done-color);
|
|
||||||
--voidraft-loading-overlay: var(--dark-loading-overlay);
|
--scrollbar-track: #2a2a2a;
|
||||||
}
|
--scrollbar-thumb: #555555;
|
||||||
|
--scrollbar-thumb-hover: #666666;
|
||||||
|
|
||||||
|
--selection-bg: rgba(181, 206, 168, 0.1);
|
||||||
|
--selection-text: #b5cea8;
|
||||||
|
|
||||||
|
--voidraft-bg-gradient: radial-gradient(#222922, #000500);
|
||||||
|
--voidraft-loading-color: #ffffff;
|
||||||
|
--voidraft-loading-glow: 0 0 10px rgba(50, 255, 50, 0.5), 0 0 5px rgba(100, 255, 100, 0.5);
|
||||||
|
--voidraft-loading-done-color: #66ff66;
|
||||||
|
--voidraft-loading-overlay: linear-gradient(transparent 0%, rgba(10, 16, 10, 0.5) 50%);
|
||||||
|
|
||||||
|
/* Markdown 代码块样式 - 暗色主题 */
|
||||||
|
--cm-codeblock-bg: rgba(46, 51, 69, 0.8);
|
||||||
|
--cm-codeblock-radius: 0.4rem;
|
||||||
|
|
||||||
|
|
||||||
|
/* Markdown 内联代码样式 */
|
||||||
|
--cm-inline-code-bg: oklch(28% 0.02 255);
|
||||||
|
|
||||||
|
/* Markdown 上标/下标样式 */
|
||||||
|
--cm-superscript-color: inherit;
|
||||||
|
--cm-subscript-color: inherit;
|
||||||
|
|
||||||
|
/* Markdown 高亮样式 */
|
||||||
|
--cm-highlight-background: rgba(250, 204, 21, 0.35);
|
||||||
|
|
||||||
|
/* Markdown 表格样式 - 暗色主题 */
|
||||||
|
--cm-table-bg: rgba(35, 40, 52, 0.5);
|
||||||
|
--cm-table-header-bg: rgba(46, 51, 69, 0.7);
|
||||||
|
--cm-table-border: rgba(75, 85, 99, 0.35);
|
||||||
|
--cm-table-row-hover: rgba(55, 62, 78, 0.5);
|
||||||
|
|
||||||
|
/* Search Panel - Dark Theme */
|
||||||
|
--search-panel-bg: #252526;
|
||||||
|
--search-panel-text: #cccccc;
|
||||||
|
--search-panel-border: #454545;
|
||||||
|
--search-input-bg: #3c3c3c;
|
||||||
|
--search-input-text: #cccccc;
|
||||||
|
--search-input-border: #3c3c3c;
|
||||||
|
--search-focus-border: #0078d4;
|
||||||
|
--search-btn-hover: rgba(255, 255, 255, 0.1);
|
||||||
|
--search-btn-active-bg: rgba(0, 120, 212, 0.4);
|
||||||
|
--search-btn-active-text: #ffffff;
|
||||||
|
--search-error-border: #f14c4c;
|
||||||
|
--search-error-bg: #5a1d1d;
|
||||||
|
|
||||||
|
/* Search Match Highlight - Dark Theme (VSCode style) */
|
||||||
|
--search-match-bg: rgba(250, 220, 81, 0.85);
|
||||||
|
--search-match-selected-bg: rgba(81, 175, 255, 0.5);
|
||||||
|
--search-match-selected-border: #74b0f4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 监听系统浅色主题 */
|
/* 亮色主题 */
|
||||||
|
:root[data-theme="light"] {
|
||||||
|
color-scheme: light;
|
||||||
|
|
||||||
|
--text-primary: #000000;
|
||||||
|
|
||||||
|
--toolbar-bg: #f8f9fa;
|
||||||
|
--toolbar-border: #e9ecef;
|
||||||
|
--toolbar-text: #212529;
|
||||||
|
--toolbar-text-secondary: #495057;
|
||||||
|
--toolbar-button-hover: #e9ecef;
|
||||||
|
--toolbar-separator: #e9ecef;
|
||||||
|
|
||||||
|
--tab-active-line: linear-gradient(90deg, #0066cc 0%, #0088ff 100%);
|
||||||
|
--bg-secondary: #f7fef7;
|
||||||
|
--bg-primary: #ffffff;
|
||||||
|
--bg-hover: #f1f3f4;
|
||||||
|
|
||||||
|
--text-secondary: #374151;
|
||||||
|
--text-muted: #6b7280;
|
||||||
|
--text-danger: #dc3545;
|
||||||
|
|
||||||
|
--border-color: #e5e7eb;
|
||||||
|
|
||||||
|
--settings-bg: #ffffff;
|
||||||
|
--settings-card-bg: #f8f9fa;
|
||||||
|
--settings-text: #212529;
|
||||||
|
--settings-text-secondary: #6c757d;
|
||||||
|
--settings-border: #dee2e6;
|
||||||
|
--settings-input-bg: #ffffff;
|
||||||
|
--settings-input-border: #ced4da;
|
||||||
|
--settings-hover: #e9ecef;
|
||||||
|
|
||||||
|
--scrollbar-track: #f1f3f4;
|
||||||
|
--scrollbar-thumb: #c1c1c1;
|
||||||
|
--scrollbar-thumb-hover: #a8a8a8;
|
||||||
|
|
||||||
|
--selection-bg: rgba(59, 130, 246, 0.15);
|
||||||
|
--selection-text: #2563eb;
|
||||||
|
|
||||||
|
--voidraft-bg-gradient: radial-gradient(#f0f6f0, #e5efe5);
|
||||||
|
--voidraft-loading-color: #1a3c1a;
|
||||||
|
--voidraft-loading-glow: 0 0 10px rgba(0, 160, 0, 0.3), 0 0 5px rgba(0, 120, 0, 0.2);
|
||||||
|
--voidraft-loading-done-color: #008800;
|
||||||
|
--voidraft-loading-overlay: linear-gradient(transparent 0%, rgba(220, 240, 220, 0.5) 50%);
|
||||||
|
|
||||||
|
/* Markdown 代码块样式 - 亮色主题 */
|
||||||
|
--cm-codeblock-bg: #f3f3f3;
|
||||||
|
--cm-codeblock-radius: 0.4rem;
|
||||||
|
|
||||||
|
/* Markdown 内联代码样式 */
|
||||||
|
--cm-inline-code-bg: oklch(92.9% 0.013 255.508);
|
||||||
|
|
||||||
|
/* Markdown 上标/下标样式 */
|
||||||
|
--cm-superscript-color: inherit;
|
||||||
|
--cm-subscript-color: inherit;
|
||||||
|
|
||||||
|
/* Markdown 高亮样式 */
|
||||||
|
--cm-highlight-background: rgba(253, 224, 71, 0.45);
|
||||||
|
|
||||||
|
/* Markdown 表格样式 - 亮色主题 */
|
||||||
|
--cm-table-bg: oklch(97.5% 0.006 255);
|
||||||
|
--cm-table-header-bg: oklch(94% 0.01 255);
|
||||||
|
--cm-table-border: oklch(88% 0.008 255);
|
||||||
|
--cm-table-row-hover: oklch(95% 0.008 255);
|
||||||
|
|
||||||
|
/* Search Panel - Light Theme */
|
||||||
|
--search-panel-bg: #f3f3f3;
|
||||||
|
--search-panel-text: #616161;
|
||||||
|
--search-panel-border: #c8c8c8;
|
||||||
|
--search-input-bg: #ffffff;
|
||||||
|
--search-input-text: #616161;
|
||||||
|
--search-input-border: #cecece;
|
||||||
|
--search-focus-border: #0078d4;
|
||||||
|
--search-btn-hover: rgba(0, 0, 0, 0.1);
|
||||||
|
--search-btn-active-bg: rgba(0, 120, 212, 0.2);
|
||||||
|
--search-btn-active-text: #0078d4;
|
||||||
|
--search-error-border: #e51400;
|
||||||
|
--search-error-bg: #fdeceb;
|
||||||
|
|
||||||
|
/* Search Match Highlight - Light Theme (VSCode style) */
|
||||||
|
--search-match-bg: rgba(250, 220, 81, 0.85);
|
||||||
|
--search-match-selected-bg: rgba(38, 143, 255, 0.3);
|
||||||
|
--search-match-selected-border: #268fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 跟随系统的浅色偏好 */
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
:root[data-theme="auto"] {
|
:root[data-theme="auto"] {
|
||||||
--toolbar-bg: var(--light-toolbar-bg);
|
color-scheme: light;
|
||||||
--toolbar-border: var(--light-toolbar-border);
|
|
||||||
--toolbar-text: var(--light-toolbar-text);
|
|
||||||
--toolbar-text-secondary: var(--light-toolbar-text-secondary);
|
|
||||||
--toolbar-button-hover: var(--light-toolbar-button-hover);
|
|
||||||
--toolbar-separator: var(--light-toolbar-button-hover);
|
|
||||||
--tab-active-line: var(--light-tab-active-line);
|
|
||||||
--bg-secondary: var(--light-bg-secondary);
|
|
||||||
--text-secondary: var(--light-text-secondary);
|
|
||||||
--text-muted: var(--light-text-muted);
|
|
||||||
--border-color: var(--light-border-color);
|
|
||||||
--settings-bg: var(--light-settings-bg);
|
|
||||||
--settings-card-bg: var(--light-settings-card-bg);
|
|
||||||
--settings-text: var(--light-settings-text);
|
|
||||||
--settings-text-secondary: var(--light-settings-text-secondary);
|
|
||||||
--settings-border: var(--light-settings-border);
|
|
||||||
--settings-input-bg: var(--light-settings-input-bg);
|
|
||||||
--settings-input-border: var(--light-settings-input-border);
|
|
||||||
--settings-hover: var(--light-settings-hover);
|
|
||||||
--scrollbar-track: var(--light-scrollbar-track);
|
|
||||||
--scrollbar-thumb: var(--light-scrollbar-thumb);
|
|
||||||
--scrollbar-thumb-hover: var(--light-scrollbar-thumb-hover);
|
|
||||||
--selection-bg: var(--light-selection-bg);
|
|
||||||
--selection-text: var(--light-selection-text);
|
|
||||||
--text-danger: var(--light-danger-color);
|
|
||||||
--bg-primary: var(--light-bg-primary);
|
|
||||||
--bg-hover: var(--light-bg-hover);
|
|
||||||
--voidraft-bg-gradient: var(--light-loading-bg-gradient);
|
|
||||||
--voidraft-loading-color: var(--light-loading-color);
|
|
||||||
--voidraft-loading-glow: var(--light-loading-glow);
|
|
||||||
--voidraft-loading-done-color: var(--light-loading-done-color);
|
|
||||||
--voidraft-loading-overlay: var(--light-loading-overlay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 手动选择浅色主题 */
|
--text-primary: #000000;
|
||||||
:root[data-theme="light"] {
|
|
||||||
--toolbar-bg: var(--light-toolbar-bg);
|
|
||||||
--toolbar-border: var(--light-toolbar-border);
|
|
||||||
--toolbar-text: var(--light-toolbar-text);
|
|
||||||
--toolbar-text-secondary: var(--light-toolbar-text-secondary);
|
|
||||||
--toolbar-button-hover: var(--light-toolbar-button-hover);
|
|
||||||
--toolbar-separator: var(--light-toolbar-button-hover);
|
|
||||||
--tab-active-line: var(--light-tab-active-line);
|
|
||||||
--bg-secondary: var(--light-bg-secondary);
|
|
||||||
--text-secondary: var(--light-text-secondary);
|
|
||||||
--text-muted: var(--light-text-muted);
|
|
||||||
--border-color: var(--light-border-color);
|
|
||||||
--settings-bg: var(--light-settings-bg);
|
|
||||||
--settings-card-bg: var(--light-settings-card-bg);
|
|
||||||
--settings-text: var(--light-settings-text);
|
|
||||||
--settings-text-secondary: var(--light-settings-text-secondary);
|
|
||||||
--settings-border: var(--light-settings-border);
|
|
||||||
--settings-input-bg: var(--light-settings-input-bg);
|
|
||||||
--settings-input-border: var(--light-settings-input-border);
|
|
||||||
--settings-hover: var(--light-settings-hover);
|
|
||||||
--scrollbar-track: var(--light-scrollbar-track);
|
|
||||||
--scrollbar-thumb: var(--light-scrollbar-thumb);
|
|
||||||
--scrollbar-thumb-hover: var(--light-scrollbar-thumb-hover);
|
|
||||||
--selection-bg: var(--light-selection-bg);
|
|
||||||
--selection-text: var(--light-selection-text);
|
|
||||||
--text-danger: var(--light-danger-color);
|
|
||||||
--bg-primary: var(--light-bg-primary);
|
|
||||||
--bg-hover: var(--light-bg-hover);
|
|
||||||
--voidraft-bg-gradient: var(--light-loading-bg-gradient);
|
|
||||||
--voidraft-loading-color: var(--light-loading-color);
|
|
||||||
--voidraft-loading-glow: var(--light-loading-glow);
|
|
||||||
--voidraft-loading-done-color: var(--light-loading-done-color);
|
|
||||||
--voidraft-loading-overlay: var(--light-loading-overlay);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 手动选择深色主题 */
|
--toolbar-bg: #f8f9fa;
|
||||||
:root[data-theme="dark"] {
|
--toolbar-border: #e9ecef;
|
||||||
--toolbar-bg: var(--dark-toolbar-bg);
|
--toolbar-text: #212529;
|
||||||
--toolbar-border: var(--dark-toolbar-border);
|
--toolbar-text-secondary: #495057;
|
||||||
--toolbar-text: var(--dark-toolbar-text);
|
--toolbar-button-hover: #e9ecef;
|
||||||
--toolbar-text-secondary: var(--dark-toolbar-text-secondary);
|
--toolbar-separator: #e9ecef;
|
||||||
--toolbar-button-hover: var(--dark-toolbar-button-hover);
|
|
||||||
--toolbar-separator: var(--dark-toolbar-button-hover);
|
--tab-active-line: linear-gradient(90deg, #0066cc 0%, #0088ff 100%);
|
||||||
--tab-active-line: var(--dark-tab-active-line);
|
--bg-secondary: #f7fef7;
|
||||||
--bg-secondary: var(--dark-bg-secondary);
|
--bg-primary: #ffffff;
|
||||||
--text-secondary: var(--dark-text-secondary);
|
--bg-hover: #f1f3f4;
|
||||||
--text-muted: var(--dark-text-muted);
|
|
||||||
--border-color: var(--dark-border-color);
|
--text-secondary: #374151;
|
||||||
--settings-bg: var(--dark-settings-bg);
|
--text-muted: #6b7280;
|
||||||
--settings-card-bg: var(--dark-settings-card-bg);
|
--text-danger: #dc3545;
|
||||||
--settings-text: var(--dark-settings-text);
|
|
||||||
--settings-text-secondary: var(--dark-settings-text-secondary);
|
--border-color: #e5e7eb;
|
||||||
--settings-border: var(--dark-settings-border);
|
|
||||||
--settings-input-bg: var(--dark-settings-input-bg);
|
--settings-bg: #ffffff;
|
||||||
--settings-input-border: var(--dark-settings-input-border);
|
--settings-card-bg: #f8f9fa;
|
||||||
--settings-hover: var(--dark-settings-hover);
|
--settings-text: #212529;
|
||||||
--scrollbar-track: var(--dark-scrollbar-track);
|
--settings-text-secondary: #6c757d;
|
||||||
--scrollbar-thumb: var(--dark-scrollbar-thumb);
|
--settings-border: #dee2e6;
|
||||||
--scrollbar-thumb-hover: var(--dark-scrollbar-thumb-hover);
|
--settings-input-bg: #ffffff;
|
||||||
--selection-bg: var(--dark-selection-bg);
|
--settings-input-border: #ced4da;
|
||||||
--selection-text: var(--dark-selection-text);
|
--settings-hover: #e9ecef;
|
||||||
--text-danger: var(--dark-danger-color);
|
|
||||||
--bg-primary: var(--dark-bg-primary);
|
--scrollbar-track: #f1f3f4;
|
||||||
--bg-hover: var(--dark-bg-hover);
|
--scrollbar-thumb: #c1c1c1;
|
||||||
--voidraft-bg-gradient: var(--dark-loading-bg-gradient);
|
--scrollbar-thumb-hover: #a8a8a8;
|
||||||
--voidraft-loading-color: var(--dark-loading-color);
|
|
||||||
--voidraft-loading-glow: var(--dark-loading-glow);
|
--selection-bg: rgba(59, 130, 246, 0.15);
|
||||||
--voidraft-loading-done-color: var(--dark-loading-done-color);
|
--selection-text: #2563eb;
|
||||||
--voidraft-loading-overlay: var(--dark-loading-overlay);
|
|
||||||
|
--voidraft-bg-gradient: radial-gradient(#f0f6f0, #e5efe5);
|
||||||
|
--voidraft-loading-color: #1a3c1a;
|
||||||
|
--voidraft-loading-glow: 0 0 10px rgba(0, 160, 0, 0.3), 0 0 5px rgba(0, 120, 0, 0.2);
|
||||||
|
--voidraft-loading-done-color: #008800;
|
||||||
|
--voidraft-loading-overlay: linear-gradient(transparent 0%, rgba(220, 240, 220, 0.5) 50%);
|
||||||
|
|
||||||
|
/* Markdown 代码块样式 - 亮色主题 */
|
||||||
|
--cm-codeblock-bg: oklch(92.9% 0.013 255.508);
|
||||||
|
--cm-codeblock-radius: 0.4rem;
|
||||||
|
|
||||||
|
/* Markdown 内联代码样式 */
|
||||||
|
--cm-inline-code-bg: oklch(92.9% 0.013 255.508);
|
||||||
|
|
||||||
|
/* Markdown 上标/下标样式 */
|
||||||
|
--cm-superscript-color: inherit;
|
||||||
|
--cm-subscript-color: inherit;
|
||||||
|
|
||||||
|
/* Markdown 高亮样式 */
|
||||||
|
--cm-highlight-background: rgba(253, 224, 71, 0.45);
|
||||||
|
|
||||||
|
/* Markdown 表格样式 - 亮色主题 */
|
||||||
|
--cm-table-bg: oklch(97.5% 0.006 255);
|
||||||
|
--cm-table-header-bg: oklch(94% 0.01 255);
|
||||||
|
--cm-table-border: oklch(88% 0.008 255);
|
||||||
|
--cm-table-row-hover: oklch(95% 0.008 255);
|
||||||
|
|
||||||
|
/* Search Panel - Light Theme (auto) */
|
||||||
|
--search-panel-bg: #f3f3f3;
|
||||||
|
--search-panel-text: #616161;
|
||||||
|
--search-panel-border: #c8c8c8;
|
||||||
|
--search-input-bg: #ffffff;
|
||||||
|
--search-input-text: #616161;
|
||||||
|
--search-input-border: #cecece;
|
||||||
|
--search-focus-border: #0078d4;
|
||||||
|
--search-btn-hover: rgba(0, 0, 0, 0.1);
|
||||||
|
--search-btn-active-bg: rgba(0, 120, 212, 0.2);
|
||||||
|
--search-btn-active-text: #0078d4;
|
||||||
|
--search-error-border: #e51400;
|
||||||
|
--search-error-bg: #fdeceb;
|
||||||
|
|
||||||
|
/* Search Match Highlight - Light Theme auto (VSCode style) */
|
||||||
|
--search-match-bg: rgba(250, 220, 81, 0.85);
|
||||||
|
--search-match-selected-bg: rgba(38, 143, 255, 0.3);
|
||||||
|
--search-match-selected-border: #268fff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,43 +1,19 @@
|
|||||||
import {
|
import {
|
||||||
AppConfig,
|
AppConfig,
|
||||||
AppearanceConfig,
|
AuthMethod,
|
||||||
EditingConfig,
|
KeyBindingType,
|
||||||
GeneralConfig,
|
|
||||||
LanguageType,
|
LanguageType,
|
||||||
SystemThemeType,
|
SystemThemeType,
|
||||||
TabType,
|
TabType,
|
||||||
UpdatesConfig,
|
|
||||||
UpdateSourceType,
|
|
||||||
GitBackupConfig,
|
|
||||||
AuthMethod
|
|
||||||
} from '@/../bindings/voidraft/internal/models/models';
|
} from '@/../bindings/voidraft/internal/models/models';
|
||||||
import {FONT_OPTIONS} from './fonts';
|
import {FONT_OPTIONS} from './fonts';
|
||||||
|
|
||||||
// 配置键映射和限制的类型定义
|
|
||||||
export type GeneralConfigKeyMap = {
|
|
||||||
readonly [K in keyof GeneralConfig]: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type EditingConfigKeyMap = {
|
|
||||||
readonly [K in keyof EditingConfig]: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type AppearanceConfigKeyMap = {
|
|
||||||
readonly [K in keyof AppearanceConfig]: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type UpdatesConfigKeyMap = {
|
|
||||||
readonly [K in keyof UpdatesConfig]: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BackupConfigKeyMap = {
|
|
||||||
readonly [K in keyof GitBackupConfig]: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type NumberConfigKey = 'fontSize' | 'tabSize' | 'lineHeight';
|
export type NumberConfigKey = 'fontSize' | 'tabSize' | 'lineHeight';
|
||||||
|
export type ConfigSection = 'general' | 'editing' | 'appearance' | 'updates' | 'backup';
|
||||||
|
|
||||||
// 配置键映射
|
// 统一配置键映射(平级展开)
|
||||||
export const GENERAL_CONFIG_KEY_MAP: GeneralConfigKeyMap = {
|
export const CONFIG_KEY_MAP = {
|
||||||
|
// general
|
||||||
alwaysOnTop: 'general.alwaysOnTop',
|
alwaysOnTop: 'general.alwaysOnTop',
|
||||||
dataPath: 'general.dataPath',
|
dataPath: 'general.dataPath',
|
||||||
enableSystemTray: 'general.enableSystemTray',
|
enableSystemTray: 'general.enableSystemTray',
|
||||||
@@ -47,9 +23,8 @@ export const GENERAL_CONFIG_KEY_MAP: GeneralConfigKeyMap = {
|
|||||||
enableWindowSnap: 'general.enableWindowSnap',
|
enableWindowSnap: 'general.enableWindowSnap',
|
||||||
enableLoadingAnimation: 'general.enableLoadingAnimation',
|
enableLoadingAnimation: 'general.enableLoadingAnimation',
|
||||||
enableTabs: 'general.enableTabs',
|
enableTabs: 'general.enableTabs',
|
||||||
} as const;
|
enableMemoryMonitor: 'general.enableMemoryMonitor',
|
||||||
|
// editing
|
||||||
export const EDITING_CONFIG_KEY_MAP: EditingConfigKeyMap = {
|
|
||||||
fontSize: 'editing.fontSize',
|
fontSize: 'editing.fontSize',
|
||||||
fontFamily: 'editing.fontFamily',
|
fontFamily: 'editing.fontFamily',
|
||||||
fontWeight: 'editing.fontWeight',
|
fontWeight: 'editing.fontWeight',
|
||||||
@@ -57,16 +32,13 @@ export const EDITING_CONFIG_KEY_MAP: EditingConfigKeyMap = {
|
|||||||
enableTabIndent: 'editing.enableTabIndent',
|
enableTabIndent: 'editing.enableTabIndent',
|
||||||
tabSize: 'editing.tabSize',
|
tabSize: 'editing.tabSize',
|
||||||
tabType: 'editing.tabType',
|
tabType: 'editing.tabType',
|
||||||
autoSaveDelay: 'editing.autoSaveDelay'
|
keymapMode: 'editing.keymapMode',
|
||||||
} as const;
|
autoSaveDelay: 'editing.autoSaveDelay',
|
||||||
|
// appearance
|
||||||
export const APPEARANCE_CONFIG_KEY_MAP: AppearanceConfigKeyMap = {
|
|
||||||
language: 'appearance.language',
|
language: 'appearance.language',
|
||||||
systemTheme: 'appearance.systemTheme',
|
systemTheme: 'appearance.systemTheme',
|
||||||
currentTheme: 'appearance.currentTheme'
|
currentTheme: 'appearance.currentTheme',
|
||||||
} as const;
|
// updates
|
||||||
|
|
||||||
export const UPDATES_CONFIG_KEY_MAP: UpdatesConfigKeyMap = {
|
|
||||||
version: 'updates.version',
|
version: 'updates.version',
|
||||||
autoUpdate: 'updates.autoUpdate',
|
autoUpdate: 'updates.autoUpdate',
|
||||||
primarySource: 'updates.primarySource',
|
primarySource: 'updates.primarySource',
|
||||||
@@ -74,10 +46,8 @@ export const UPDATES_CONFIG_KEY_MAP: UpdatesConfigKeyMap = {
|
|||||||
backupBeforeUpdate: 'updates.backupBeforeUpdate',
|
backupBeforeUpdate: 'updates.backupBeforeUpdate',
|
||||||
updateTimeout: 'updates.updateTimeout',
|
updateTimeout: 'updates.updateTimeout',
|
||||||
github: 'updates.github',
|
github: 'updates.github',
|
||||||
gitea: 'updates.gitea'
|
gitea: 'updates.gitea',
|
||||||
} as const;
|
// backup
|
||||||
|
|
||||||
export const BACKUP_CONFIG_KEY_MAP: BackupConfigKeyMap = {
|
|
||||||
enabled: 'backup.enabled',
|
enabled: 'backup.enabled',
|
||||||
repo_url: 'backup.repo_url',
|
repo_url: 'backup.repo_url',
|
||||||
auth_method: 'backup.auth_method',
|
auth_method: 'backup.auth_method',
|
||||||
@@ -90,6 +60,8 @@ export const BACKUP_CONFIG_KEY_MAP: BackupConfigKeyMap = {
|
|||||||
auto_backup: 'backup.auto_backup',
|
auto_backup: 'backup.auto_backup',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export type ConfigKey = keyof typeof CONFIG_KEY_MAP;
|
||||||
|
|
||||||
// 配置限制
|
// 配置限制
|
||||||
export const CONFIG_LIMITS = {
|
export const CONFIG_LIMITS = {
|
||||||
fontSize: {min: 12, max: 28, default: 13},
|
fontSize: {min: 12, max: 28, default: 13},
|
||||||
@@ -116,6 +88,7 @@ export const DEFAULT_CONFIG: AppConfig = {
|
|||||||
enableWindowSnap: true,
|
enableWindowSnap: true,
|
||||||
enableLoadingAnimation: true,
|
enableLoadingAnimation: true,
|
||||||
enableTabs: false,
|
enableTabs: false,
|
||||||
|
enableMemoryMonitor: true,
|
||||||
},
|
},
|
||||||
editing: {
|
editing: {
|
||||||
fontSize: CONFIG_LIMITS.fontSize.default,
|
fontSize: CONFIG_LIMITS.fontSize.default,
|
||||||
@@ -125,29 +98,23 @@ export const DEFAULT_CONFIG: AppConfig = {
|
|||||||
enableTabIndent: true,
|
enableTabIndent: true,
|
||||||
tabSize: CONFIG_LIMITS.tabSize.default,
|
tabSize: CONFIG_LIMITS.tabSize.default,
|
||||||
tabType: CONFIG_LIMITS.tabType.default,
|
tabType: CONFIG_LIMITS.tabType.default,
|
||||||
|
keymapMode: KeyBindingType.Standard,
|
||||||
autoSaveDelay: 5000
|
autoSaveDelay: 5000
|
||||||
},
|
},
|
||||||
appearance: {
|
appearance: {
|
||||||
language: LanguageType.LangZhCN,
|
language: LanguageType.LangZhCN,
|
||||||
systemTheme: SystemThemeType.SystemThemeAuto,
|
systemTheme: SystemThemeType.SystemThemeDark,
|
||||||
currentTheme: 'default-dark'
|
currentTheme: 'default-dark'
|
||||||
},
|
},
|
||||||
updates: {
|
updates: {
|
||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
autoUpdate: true,
|
autoUpdate: true,
|
||||||
primarySource: UpdateSourceType.UpdateSourceGithub,
|
|
||||||
backupSource: UpdateSourceType.UpdateSourceGitea,
|
|
||||||
backupBeforeUpdate: true,
|
backupBeforeUpdate: true,
|
||||||
updateTimeout: 30,
|
updateTimeout: 120,
|
||||||
github: {
|
github: {
|
||||||
owner: "landaiqing",
|
owner: "landaiqing",
|
||||||
repo: "voidraft",
|
repo: "voidraft",
|
||||||
},
|
},
|
||||||
gitea: {
|
|
||||||
baseURL: "https://git.landaiqing.cn",
|
|
||||||
owner: "landaiqing",
|
|
||||||
repo: "voidraft",
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
backup: {
|
backup: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|||||||