- 添加帮助信息栏 (bubbles help组件, Ctrl+H切换) - 翻译卡片样式优化 (Padding空隙、上方内边距) - 扩展build.sh支持跨平台编译 - release.yaml使用build.sh构建
This commit is contained in:
@@ -25,12 +25,13 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
chmod +x ./build.sh
|
||||
for p in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64; do
|
||||
os=${p%/*}
|
||||
arch=${p#*/}
|
||||
ext=""
|
||||
[ "$os" = "windows" ] && ext=".exe"
|
||||
GOOS=$os GOARCH=$arch go build -buildvcs=false -o "yoo-${os}-${arch}${ext}" ./cmd/yoyo
|
||||
./build.sh "$p" -o "yoo-${os}-${arch}${ext}"
|
||||
done
|
||||
|
||||
- name: Checksums
|
||||
|
||||
95
build.sh
95
build.sh
@@ -1,3 +1,94 @@
|
||||
#!/bin/bash
|
||||
VERSION=$(git describe --tags --always --dirty 2>/dev/null || echo "")
|
||||
go build -ldflags "-X github.com/titor/fanyi/internal/logo.version=${VERSION}" -o yoyo ./cmd/yoyo
|
||||
set -e
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
VERSION=$(git describe --tags --always --dirty 2>/dev/null || echo "dev")
|
||||
|
||||
show_help() {
|
||||
echo "YOYO 编译脚本"
|
||||
echo ""
|
||||
echo "用法:"
|
||||
echo " ./build.sh 构建当前平台,输出 yoyo"
|
||||
echo " ./build.sh <平台> 交叉编译指定平台"
|
||||
echo " ./build.sh -h 显示帮助"
|
||||
echo ""
|
||||
echo "参数:"
|
||||
echo " -h 显示帮助信息"
|
||||
echo " -o <文件名> 指定输出文件名"
|
||||
echo ""
|
||||
echo "支持的平台:"
|
||||
echo " linux/amd64, linux/arm64"
|
||||
echo " darwin/amd64, darwin/arm64"
|
||||
echo " windows/amd64"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " ./build.sh # 构建当前平台"
|
||||
echo " ./build.sh linux/amd64 # 编译 Linux x64"
|
||||
echo " ./build.sh darwin/arm64 # 编译 macOS ARM"
|
||||
echo " ./build.sh windows/amd64 -o app.exe # 编译 Windows x64,自定义输出名"
|
||||
echo ""
|
||||
echo "输出文件名格式: yoo-<os>-<arch>[.exe]"
|
||||
echo " yoo-linux-amd64"
|
||||
echo " yoo-darwin-arm64"
|
||||
echo " yoo-windows-amd64.exe"
|
||||
}
|
||||
|
||||
OUTPUT_NAME="yoyo"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
-o|--output)
|
||||
OUTPUT_NAME="$2"
|
||||
shift 2
|
||||
;;
|
||||
linux/amd64)
|
||||
GOOS=linux GOARCH=amd64
|
||||
PLATFORM="linux-amd64"
|
||||
shift
|
||||
;;
|
||||
linux/arm64)
|
||||
GOOS=linux GOARCH=arm64
|
||||
PLATFORM="linux-arm64"
|
||||
shift
|
||||
;;
|
||||
darwin/amd64)
|
||||
GOOS=darwin GOARCH=amd64
|
||||
PLATFORM="darwin-amd64"
|
||||
shift
|
||||
;;
|
||||
darwin/arm64)
|
||||
GOOS=darwin GOARCH=arm64
|
||||
PLATFORM="darwin-arm64"
|
||||
shift
|
||||
;;
|
||||
windows/amd64)
|
||||
GOOS=windows GOARCH=amd64
|
||||
PLATFORM="windows-amd64"
|
||||
if [[ "$OUTPUT_NAME" == "yoyo" ]]; then
|
||||
OUTPUT_NAME="yoo-windows-amd64.exe"
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "未知平台: $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "Building yoyo version: $VERSION"
|
||||
|
||||
if [ -n "$GOOS" ]; then
|
||||
echo "Target: $PLATFORM"
|
||||
go build -ldflags "-s -w -X github.com/titor/fanyi/internal/logo.version=${VERSION}" -o "$OUTPUT_NAME" ./cmd/yoyo
|
||||
else
|
||||
go build -ldflags "-s -w -X github.com/titor/fanyi/internal/logo.version=${VERSION}" -o "$OUTPUT_NAME" ./cmd/yoyo
|
||||
fi
|
||||
|
||||
echo "Build complete: ./$OUTPUT_NAME"
|
||||
25
changelog.md
25
changelog.md
@@ -70,6 +70,31 @@
|
||||
|
||||
## 版本历史
|
||||
|
||||
### 0.7.1 (2026-04-08) - TUI界面改进
|
||||
**类型**: 优化版本
|
||||
**状态**: 开发中
|
||||
|
||||
**改进内容**:
|
||||
- ✅ 添加帮助信息栏目 - 使用 bubbles help 组件,位于界面底部
|
||||
- ✅ 帮助按键绑定 - Ctrl+H 切换帮助显示
|
||||
- ✅ Logo 版本号注入 - 使用 build.sh + ldflags 自动注入 git 版本
|
||||
- ✅ 翻译卡片样式 - 翻译结果 Padding(1,3,1,3) 增加上方空隙
|
||||
- ✅ Viewport 上方内边距 - 第一个翻译卡片显示时增加上方空白
|
||||
|
||||
**构建脚本改进**:
|
||||
- ✅ 扩展 build.sh 支持跨平台编译
|
||||
- ✅ 添加 -h 帮助选项
|
||||
- ✅ 支持 -o 自定义输出文件名
|
||||
- ✅ 支持平台: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64
|
||||
|
||||
**讨论记录**:
|
||||
- [帮助功能和样式改进](taolun.md#2026-04-08-tui界面帮助功能与样式改进)
|
||||
|
||||
**下一步**:
|
||||
- 实现模块8: 弹出框组件
|
||||
|
||||
---
|
||||
|
||||
### 0.7.0 (2026-04-06) - TUI界面改进
|
||||
**类型**: 功能版本
|
||||
**状态**: 开发中
|
||||
|
||||
@@ -12,6 +12,7 @@ type KeyMap struct {
|
||||
ScrollDown key.Binding
|
||||
ScrollTop key.Binding
|
||||
ScrollBottom key.Binding
|
||||
Help key.Binding
|
||||
}
|
||||
|
||||
func NewKeyMap() KeyMap {
|
||||
@@ -44,5 +45,21 @@ func NewKeyMap() KeyMap {
|
||||
key.WithKeys("end"),
|
||||
key.WithHelp("End", "底部"),
|
||||
),
|
||||
Help: key.NewBinding(
|
||||
key.WithKeys("ctrl+h"),
|
||||
key.WithHelp("Ctrl+H", "帮助"),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (k KeyMap) ShortHelp() []key.Binding {
|
||||
return []key.Binding{k.Help, k.Quit}
|
||||
}
|
||||
|
||||
func (k KeyMap) FullHelp() [][]key.Binding {
|
||||
return [][]key.Binding{
|
||||
{k.Quit, k.Clear, k.SwitchLang},
|
||||
{k.ScrollUp, k.ScrollDown, k.ScrollTop, k.ScrollBottom},
|
||||
{k.Help},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"charm.land/bubbles/v2/help"
|
||||
"charm.land/bubbles/v2/key"
|
||||
"charm.land/bubbles/v2/spinner"
|
||||
"charm.land/bubbles/v2/textarea"
|
||||
"charm.land/bubbles/v2/viewport"
|
||||
@@ -33,6 +35,7 @@ type model struct {
|
||||
input textarea.Model
|
||||
viewport viewport.Model
|
||||
spinner spinner.Model
|
||||
help help.Model
|
||||
keys KeyMap
|
||||
|
||||
targetLang string
|
||||
@@ -67,16 +70,22 @@ func NewApp(cfg *config.Config, t *translator.Translator) *tea.Program {
|
||||
sp.Spinner = spinner.MiniDot
|
||||
sp.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("#8B5CF6"))
|
||||
|
||||
return tea.NewProgram(model{
|
||||
hp := help.New()
|
||||
|
||||
m := model{
|
||||
config: cfg,
|
||||
translator: t,
|
||||
messages: make([]ChatMessage, 0),
|
||||
input: ta,
|
||||
viewport: vp,
|
||||
spinner: sp,
|
||||
help: hp,
|
||||
keys: keys,
|
||||
targetLang: getDefaultLang(cfg),
|
||||
})
|
||||
}
|
||||
|
||||
p := tea.NewProgram(m)
|
||||
return p
|
||||
}
|
||||
|
||||
func getDefaultLang(cfg *config.Config) string {
|
||||
@@ -100,6 +109,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
case tea.WindowSizeMsg:
|
||||
m.width = msg.Width
|
||||
m.height = msg.Height
|
||||
m.help.SetWidth(msg.Width)
|
||||
m.updateLayout()
|
||||
|
||||
case translateMsg:
|
||||
@@ -137,6 +147,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
case "end":
|
||||
m.viewport.GotoBottom()
|
||||
}
|
||||
if key.Matches(msg, m.keys.Help) {
|
||||
m.help.ShowAll = !m.help.ShowAll
|
||||
}
|
||||
}
|
||||
|
||||
m.input, cmd = m.input.Update(msg)
|
||||
@@ -206,7 +219,12 @@ func (m *model) updateLayout() {
|
||||
|
||||
m.input.SetWidth(contentWidth)
|
||||
m.viewport.SetWidth(contentWidth)
|
||||
m.viewport.SetHeight(m.height - 12)
|
||||
|
||||
helpLines := 2
|
||||
if m.help.ShowAll {
|
||||
helpLines = 4
|
||||
}
|
||||
m.viewport.SetHeight(m.height - 12 - helpLines)
|
||||
if m.viewport.Height() < 5 {
|
||||
m.viewport.SetHeight(10)
|
||||
}
|
||||
@@ -217,6 +235,10 @@ func (m *model) updateLayout() {
|
||||
func (m *model) updateViewportContent() {
|
||||
var b strings.Builder
|
||||
|
||||
if len(m.messages) > 0 {
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
for _, msg := range m.messages {
|
||||
b.WriteString(m.renderTranslationCard(msg))
|
||||
}
|
||||
@@ -252,7 +274,7 @@ func (m *model) renderTranslationCard(msg ChatMessage) string {
|
||||
Render(msg.Error)
|
||||
outputBlock = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#F87171")).
|
||||
Padding(0, 3, 1, 3).
|
||||
Padding(1, 3, 1, 3).
|
||||
Width(m.viewport.Width()).
|
||||
Render(outputContent)
|
||||
} else {
|
||||
@@ -260,7 +282,7 @@ func (m *model) renderTranslationCard(msg ChatMessage) string {
|
||||
Width(m.viewport.Width() - 2).
|
||||
Render(msg.Output)
|
||||
outputBlock = lipgloss.NewStyle().
|
||||
Padding(0, 3, 1, 3).
|
||||
Padding(1, 3, 1, 3).
|
||||
Width(m.viewport.Width()).
|
||||
Render(outputContent)
|
||||
}
|
||||
@@ -299,9 +321,9 @@ func (m model) View() tea.View {
|
||||
messages := m.viewport.View()
|
||||
inputArea := m.renderInputArea()
|
||||
infoBar := m.renderInfoBar()
|
||||
spinnerView := m.renderSpinner()
|
||||
helpView := m.help.View(m.keys)
|
||||
|
||||
content := header + "\n" + messages + inputArea + infoBar + spinnerView
|
||||
content := header + "\n" + messages + inputArea + infoBar + helpView
|
||||
v := tea.NewView(content)
|
||||
v.AltScreen = true
|
||||
return v
|
||||
|
||||
44
taolun.md
44
taolun.md
@@ -878,4 +878,48 @@ go build -ldflags "-X github.com/titor/fanyi/internal/logo.version=${VERSION}" -
|
||||
(__)(_____(_____( v1.1.1-dirty )
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### [2026-04-08] TUI界面帮助功能与样式改进
|
||||
|
||||
**原因**:
|
||||
1. 用户需要在TUI底部添加帮助信息栏
|
||||
2. 优化翻译卡片的显示样式
|
||||
|
||||
**分析**:
|
||||
- 使用 bubbletea 的 help 组件实现帮助栏
|
||||
- 翻译卡片需要与输入区域保持间距
|
||||
|
||||
**解决方案**:
|
||||
|
||||
1. **帮助功能实现**:
|
||||
- 导入 `charm.land/bubbles/v2/help`
|
||||
- 在 `model` 结构体添加 `help help.Model` 字段
|
||||
- `KeyMap` 实现 `ShortHelp()` 和 `FullHelp()` 接口
|
||||
- 按键绑定: Help -> Ctrl+H (原 ? 和 ctrl+? 不兼容)
|
||||
- View 中添加 help.View(m.keys) 到底部
|
||||
|
||||
2. **翻译卡片样式**:
|
||||
- 翻译结果 outputBlock 的 Padding 从 `(0,3,1,3)` 改为 `(1,3,1,3)` 增加上方空隙
|
||||
- viewport 内容区域第一个卡片前添加 `"\n"` 作为上边距
|
||||
|
||||
3. **版本号注入**:
|
||||
- 扩展 build.sh 支持跨平台编译
|
||||
- 添加 -h 帮助选项
|
||||
- 添加 -o 自定义输出文件名
|
||||
- release.yaml 使用 build.sh 构建
|
||||
|
||||
**按键绑定历史**:
|
||||
- 初始: `?` → shift+? 切换,且会输入到文本框
|
||||
- 尝试: `ctrl+?` → 不兼容,无响应
|
||||
- 最终: `ctrl+h` → 正常工作
|
||||
|
||||
**相关文件**:
|
||||
- `internal/tui/keys.go` - KeyMap 定义和 ShortHelp/FullHelp
|
||||
- `internal/tui/model.go` - help 组件集成、样式调整
|
||||
- `build.sh` - 跨平台编译支持
|
||||
- `.gitea/workflows/release.yaml` - CI 构建脚本
|
||||
|
||||
**关联版本**: [changelog.md#0.7.1](changelog.md#071-2026-04-08---tui界面改进)
|
||||
|
||||
**关联版本**: [changelog.md#1.1.1](changelog.md#111-2026-04-08)
|
||||
Reference in New Issue
Block a user