Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,30 @@ jobs:
}
EOF

# 使用临时配置进行版本分析
OUTPUT=$(pnpm semantic-release --dry-run -c .releaserc.temp.js 2>&1)
echo "$OUTPUT"
# 使用临时配置进行版本分析,输出到临时文件
pnpm semantic-release --dry-run -c .releaserc.temp.js > semantic_output.txt 2>&1

# 显示输出内容以便调试
echo "=== Semantic Release Output ==="
cat semantic_output.txt
echo "=== End of Output ==="

# 清理临时文件
rm -f .releaserc.temp.js

# 检查是否有新版本需要发布
if echo "$OUTPUT" | grep -q "The next release version is"; then
NEXT_VERSION=$(echo "$OUTPUT" | grep "The next release version is" | sed 's/.*The next release version is \([0-9.a-z-]*\).*/\1/')
# 检查是否有新版本需要发布(从文件中搜索,避免变量长度限制)
if grep -q "next release version is" semantic_output.txt; then
NEXT_VERSION=$(grep "next release version is" semantic_output.txt | sed 's/.*next release version is \([0-9.a-z-]*\).*/\1/' | head -1)
echo "✅ Next version: $NEXT_VERSION"
echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT
echo "should_release=true" >> $GITHUB_OUTPUT
else
echo "ℹ️ No new version to release"
echo "should_release=false" >> $GITHUB_OUTPUT
fi

# 清理临时输出文件
rm -f semantic_output.txt
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand Down
38 changes: 38 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,44 @@
- 在布局实现上,后续优先使用 flex 布局(尽量避免使用 grid 作为默认方案)。
- 项目优先使用 antd 组件库,如果组件可以被 antd 复用则优先使用 antd 而不是自定义开发

## 主题变量使用最佳实践

项目启用了 Ant Design 的 CSS 变量模式 (`cssVar: true`),在 styled-components 中应采用分类使用策略:

### 使用 CSS 变量的场景(主题相关属性):

- 颜色系统:`var(--ant-color-bg-elevated, fallback)`
- 阴影效果:`var(--ant-box-shadow-secondary, fallback)`
- 主题切换时会发生变化的属性

### 使用 JS 变量的场景(设计系统常量):

- 尺寸间距:`${SPACING.XS}px`、`${BORDER_RADIUS.SM}px`
- 动画配置:`${ANIMATION_DURATION.SLOW}`、`${EASING.APPLE}`
- 层级关系:`${Z_INDEX.MODAL}`
- 字体配置:`${FONT_SIZES.SM}px`、`${FONT_WEIGHTS.MEDIUM}`
- 毛玻璃效果:`${GLASS_EFFECT.BACKGROUND_ALPHA.LIGHT}`

### 推荐模式:

```typescript
const StyledComponent = styled.div`
/* 主题相关:使用 CSS 变量 */
background: var(--ant-color-bg-elevated, rgba(0, 0, 0, ${GLASS_EFFECT.BACKGROUND_ALPHA.LIGHT}));
color: var(--ant-color-white, #ffffff);
box-shadow: var(--ant-box-shadow-secondary, ${SHADOWS.SM});

/* 设计系统常量:使用 JS 变量 */
padding: ${SPACING.XS}px ${SPACING.MD}px;
border-radius: ${BORDER_RADIUS.SM}px;
font-size: ${FONT_SIZES.SM}px;
transition: opacity ${ANIMATION_DURATION.SLOW} ${EASING.APPLE};
z-index: ${Z_INDEX.MODAL};
`
```

这种混合模式既保持了类型安全和构建时优化,又支持主题的运行时切换,是当前架构下的最佳实践。

# State Management

- 项目使用 Zustand 作为状态管理库,配合 Immer 中间件支持不可变状态更新,使用自定义的中间件栈包含持久化、DevTools 和订阅选择器功能
Expand Down
862 changes: 661 additions & 201 deletions LICENSE

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,10 @@ pnpm test:ui

## 🙏 致谢

| 项目名 | 简介 |
| --- | --- |
| [Cherry Studio](https://github.com/CherryHQ/cherry-studio) | 一款为创造而生的 AI 助手 |
| [DashPlayer](https://github.com/solidSpoon/DashPlayer) | 为英语学习者量身打造的视频播放器 |
| 项目名 | 简介 |
| ------------------------------------------------------ | -------------------------------- |
| [EchoPlayer](https://github.com/CherryHQ/EchoPlayer) | 一款为创造而生的 AI 助手 |
| [DashPlayer](https://github.com/solidSpoon/DashPlayer) | 为英语学习者量身打造的视频播放器 |

---

Expand Down
53 changes: 41 additions & 12 deletions electron.vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,49 @@ function ffmpegDownloadPlugin() {
// 只在生产构建时下载 FFmpeg
if (!isProd) return

console.log('Downloading FFmpeg...')
// 根据构建目标决定下载哪个平台
const targetPlatform = process.env.BUILD_TARGET_PLATFORM || process.platform
const targetArch = process.env.BUILD_TARGET_ARCH || process.arch

// 检查是否已存在,避免重复下载
const ffmpegPath = path.resolve(
'resources/ffmpeg',
`${targetPlatform}-${targetArch}`,
targetPlatform === 'win32' ? 'ffmpeg.exe' : 'ffmpeg'
)

if (fs.existsSync(ffmpegPath)) {
console.log(`FFmpeg already exists for ${targetPlatform}-${targetArch}`)
return
}

try {
// 根据构建目标决定下载哪个平台
const targetPlatform = process.env.BUILD_TARGET_PLATFORM || process.platform
const targetArch = process.env.BUILD_TARGET_ARCH || process.arch
console.log(`Downloading FFmpeg for ${targetPlatform}-${targetArch}...`)

try {
await new Promise<void>((resolve, reject) => {
const downloadScript = spawn(
'tsx',
['scripts/download-ffmpeg.ts', 'platform', targetPlatform, targetArch],
{
stdio: 'inherit'
// 在不同环境中使用不同的命令来确保兼容性
let command: string
let args: string[]

if (process.platform === 'win32') {
// Windows 环境:使用 npm run 调用脚本,更可靠
command = 'npm'
args = ['run', 'ffmpeg:download']
} else {
// Unix 环境:直接使用 tsx
command = 'tsx'
args = ['scripts/download-ffmpeg.ts', 'platform', targetPlatform, targetArch]
}

const downloadScript = spawn(command, args, {
stdio: 'inherit',
shell: process.platform === 'win32',
env: {
...process.env,
BUILD_TARGET_PLATFORM: targetPlatform,
BUILD_TARGET_ARCH: targetArch
}
)
})

downloadScript.on('close', (code) => {
if (code === 0) {
Expand All @@ -48,7 +76,8 @@ function ffmpegDownloadPlugin() {
})
})
} catch (error) {
console.warn('FFmpeg Download failed', error)
console.error('FFmpeg Download failed:', error)
throw new Error(`Failed to download FFmpeg for ${targetPlatform}-${targetArch}: ${error}`)
}
}
}
Expand Down
19 changes: 11 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@
"start": "electron-vite preview",
"dev": "electron-vite dev",
"build": "npm run typecheck && electron-vite build",
"build:release": "npm run typecheck && electron-vite build",
"postinstall": "electron-builder install-app-deps",
"build:unpack": "npm run build && electron-builder --dir --publish never",
"build:win": "npm run build && electron-builder --win --publish never",
"build:win:x64": "npm run build && electron-builder --win --x64 --publish never",
"build:win:arm64": "npm run build && electron-builder --win --arm64 --publish never",
"build:win": "cross-env BUILD_TARGET_PLATFORM=win32 npm run build && electron-builder --win --publish never",
"build:win:x64": "cross-env BUILD_TARGET_PLATFORM=win32 BUILD_TARGET_ARCH=x64 npm run build && electron-builder --win --x64 --publish never",
"build:win:arm64": "cross-env BUILD_TARGET_PLATFORM=win32 BUILD_TARGET_ARCH=arm64 npm run build && electron-builder --win --arm64 --publish never",
"build:mac": "electron-vite build && electron-builder --mac --publish never",
"build:mac:x64": "npm run build && electron-builder --mac --x64 --publish never",
"build:mac:arm64": "npm run build && electron-builder --mac --arm64 --publish never",
Expand All @@ -47,10 +48,10 @@
"version:prerelease": "tsx scripts/version-manager.ts prerelease",
"version:beta": "tsx scripts/version-manager.ts minor beta",
"version:beta-patch": "tsx scripts/version-manager.ts patch beta",
"release": "npm run build && electron-builder --publish onTagOrDraft",
"release:all": "npm run build && electron-builder --publish always",
"release:never": "npm run build && electron-builder --publish never",
"release:draft": "npm run build && electron-builder --publish onTagOrDraft",
"release": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish onTagOrDraft",
"release:all": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish always",
"release:never": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish never",
"release:draft": "npm run ffmpeg:download-all && npm run build:release && electron-builder --publish onTagOrDraft",
"migrate": "tsx src/main/db/migration-cli.ts",
"migrate:up": "npm run migrate up",
"migrate:down": "npm run migrate down",
Expand All @@ -71,7 +72,8 @@
"ffmpeg:download-all": "tsx scripts/download-ffmpeg.ts all",
"ffmpeg:clean": "tsx scripts/download-ffmpeg.ts clean",
"ffmpeg:test": "tsx scripts/test-ffmpeg-integration.ts",
"prebuild": "npm run ffmpeg:download"
"prebuild": "npm run ffmpeg:download",
"prebuild:release": "echo 'FFmpeg already downloaded by release script'"
},
"dependencies": {
"@ant-design/icons": "^6.0.1",
Expand Down Expand Up @@ -128,6 +130,7 @@
"@welldone-software/why-did-you-render": "^10.0.1",
"cli-progress": "^3.12.0",
"code-inspector-plugin": "^1.2.7",
"cross-env": "^10.0.0",
"electron": "37.2.4",
"electron-builder": "26.0.19",
"electron-devtools-installer": "^4.0.0",
Expand Down
18 changes: 18 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 22 additions & 1 deletion scripts/download-ffmpeg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,11 +376,28 @@ class FFmpegDownloader {
// CLI 入口
async function main() {
const args = process.argv.slice(2)
const command = args[0] || 'current'
let command = args[0]

const downloader = new FFmpegDownloader()

try {
// 优先检查环境变量,如果设置了构建目标则使用目标平台
if (process.env.BUILD_TARGET_PLATFORM) {
console.log(
`检测到构建目标平台: ${process.env.BUILD_TARGET_PLATFORM}-${process.env.BUILD_TARGET_ARCH || process.arch}`
)
await downloader.downloadFFmpeg(
process.env.BUILD_TARGET_PLATFORM,
process.env.BUILD_TARGET_ARCH || process.arch
)
return
}

// 如果没有环境变量,按原逻辑处理命令参数
if (!command) {
command = 'current'
}

switch (command) {
case 'all':
await downloader.downloadAllPlatforms()
Expand Down Expand Up @@ -416,6 +433,10 @@ async function main() {
win32: x64, arm64
darwin: x64, arm64
linux: x64, arm64

环境变量:
BUILD_TARGET_PLATFORM - 构建目标平台 (win32, darwin, linux)
BUILD_TARGET_ARCH - 构建目标架构 (x64, arm64)
`)
}
} catch (error) {
Expand Down
Loading
Loading