diff --git a/changelog.md b/changelog.md index 831d94e..69d05cc 100644 --- a/changelog.md +++ b/changelog.md @@ -26,12 +26,13 @@ ## 当前正实现 - [x] TUI界面模块拆分计划 ✅ 已制定 - [x] 模块1: TUI框架搭建 ✅ 已完成 +- [x] 模块2: 输入组件 ✅ 已完成 ## TUI界面实现计划 (v0.6.0) | 步骤 | 模块 | 内容 | 状态 | |------|------|------|------| | 1 | TUI框架搭建 | bubbletea基础App结构、运行循环 | ✅ 已完成 | -| 2 | 输入组件 | 文本输入框、光标、基础编辑 | ⏳ 待实现 | +| 2 | 输入组件 | 文本输入框、光标、基础编辑 | ✅ 已完成 | | 3 | 翻译显示区 | 结果展示、格式化、滚动 | ⏳ 待实现 | | 4 | 状态栏/主题 | 底部状态栏、语言选择、主题配色 | ⏳ 待实现 | | 5 | 快捷键系统 | 退出、清空、切换语言等 | ⏳ 待实现 | @@ -48,7 +49,7 @@ **变更内容**: - ✅ 模块1: TUI框架搭建 - 添加bubbletea依赖,实现基础App结构 -- ⏳ 模块2: 输入组件 - 待实现 +- ✅ 模块2: 输入组件 - textinput组件、基础输入处理 - ⏳ 模块3: 翻译显示区 - 待实现 - ⏳ 模块4: 状态栏/主题 - 待实现 - ⏳ 模块5: 快捷键系统 - 待实现 @@ -64,7 +65,7 @@ - [TUI界面模块拆分计划](taolun.md#2026-04-06-1000-版本-060---tui界面模块拆分计划) **下一步**: -- 实现模块2: 输入组件 +- 实现模块3: 翻译显示区 --- diff --git a/internal/tui/app.go b/internal/tui/app.go index cbd94ec..a6feeb6 100644 --- a/internal/tui/app.go +++ b/internal/tui/app.go @@ -1,7 +1,9 @@ package tui import ( + "github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" "github.com/titor/fanyi/internal/config" "github.com/titor/fanyi/internal/translator" ) @@ -9,12 +11,29 @@ import ( type model struct { config *config.Config translator *translator.Translator + textInput textinput.Model } +var ( + inputStyle = lipgloss.NewStyle(). + Foreground(lipgloss.Color("#FAFAFA")). + Background(lipgloss.Color("#1A1A2E")) + focusedStyle = lipgloss.NewStyle(). + Foreground(lipgloss.Color("#FAFAFA")). + Background(lipgloss.Color("#16213E")) +) + func NewApp(cfg *config.Config, t *translator.Translator) *tea.Program { + ti := textinput.New() + ti.Placeholder = "输入要翻译的文本..." + ti.Focus() + ti.Prompt = "> " + ti.TextStyle = inputStyle + return tea.NewProgram(model{ config: cfg, translator: t, + textInput: ti, }) } @@ -23,9 +42,26 @@ func (m model) Init() tea.Cmd { } func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - return m, nil + var cmd tea.Cmd + + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.Type { + case tea.KeyEnter: + // 回车键处理,后续模块会添加翻译逻辑 + case tea.KeyCtrlC, tea.KeyEsc: + return m, tea.Quit + } + } + + m.textInput, cmd = m.textInput.Update(msg) + return m, cmd } func (m model) View() string { - return "YOYO翻译 TUI\n\n(基础框架搭建中...)\n" + return "\n" + + " YOYO翻译\n" + + " ─────────────────────\n\n" + + " " + m.textInput.View() + "\n\n" + + " 按 Ctrl+C 退出\n" } diff --git a/memory.md b/memory.md index 3721772..795b761 100644 --- a/memory.md +++ b/memory.md @@ -586,4 +586,35 @@ func NewApp(cfg, translator) *tea.Program { ### main.go集成注意 - 版本检查(--version)需要在interactive模式检查之前 - 避免interactive模式在非TTY环境启动 -- Run()需要两个返回值: `_, err := app.Run()` \ No newline at end of file +- Run()需要两个返回值: `_, err := app.Run()` + +### TextInput组件使用 +```go +import "github.com/charmbracelet/bubbles/textinput" + +// model中添加字段 +type model struct { + textInput textinput.Model +} + +// 初始化 +ti := textinput.New() +ti.Placeholder = "输入文本..." +ti.Focus() // 获取焦点 +ti.Prompt = "> " // 提示符 + +// Update中处理 +m.textInput, cmd = m.textInput.Update(msg) + +// View中显示 +m.textInput.View() +``` + +### Lipgloss样式定义 +```go +var style = lipgloss.NewStyle(). + Foreground(lipgloss.Color("#FAFAFA")). + Background(lipgloss.Color("#1A1A2E")) + +ti.TextStyle = style // 应用到textinput +``` \ No newline at end of file diff --git a/taolun.md b/taolun.md index 39c821f..4dfe52c 100644 --- a/taolun.md +++ b/taolun.md @@ -441,5 +441,43 @@ func NewApp(cfg *config.Config, t *translator.Translator) *tea.Program { **下一步**: 实现模块2: 输入组件 +**关联文档**: +- [changelog.md#0.6.0](changelog.md#060) + +--- + +### [2026-04-06 11:00] 版本 0.6.0 - 模块2: 输入组件 (已完成) +**原因**: 实现TUI输入功能 +**分析**: +- 使用bubbletea的textinput组件 +- 需要焦点管理和键盘事件处理 + +**解决方案**: +1. 添加textinput字段到model +2. 初始化时设置placeholder和prompt +3. Update中处理KeyMsg +4. View中渲染输入框 +5. 支持Ctrl+C和Esc退出 + +**技术实现**: +```go +type model struct { + textInput textinput.Model +} + +func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + if msg.Type == tea.KeyCtrlC || msg.Type == tea.KeyEsc { + return m, tea.Quit + } + } + m.textInput, cmd = m.textInput.Update(msg) + return m, cmd +} +``` + +**下一步**: 实现模块3: 翻译显示区 + **关联文档**: - [changelog.md#0.6.0](changelog.md#060) \ No newline at end of file