feat: 实现模块6 - TUI集成翻译 (Enter翻译/异步执行/加载状态)
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package tui
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
"github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
@@ -13,8 +15,15 @@ type model struct {
|
||||
translator *translator.Translator
|
||||
textInput textinput.Model
|
||||
result string
|
||||
errMsg string
|
||||
targetLang string
|
||||
langIndex int
|
||||
loading bool
|
||||
}
|
||||
|
||||
type translateMsg struct {
|
||||
result string
|
||||
err error
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -29,6 +38,9 @@ var (
|
||||
resultStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#98FB98")).
|
||||
Background(lipgloss.Color("#0D1B2A"))
|
||||
errorStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#FF6B6B")).
|
||||
Background(lipgloss.Color("#1A1A2E"))
|
||||
helpStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#888888"))
|
||||
statusBarStyle = lipgloss.NewStyle().
|
||||
@@ -40,6 +52,8 @@ var (
|
||||
Bold(true)
|
||||
keyStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#60A5FA"))
|
||||
loadingStyle = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#60A5FA"))
|
||||
)
|
||||
|
||||
var supportedLangs = []string{"zh-CN", "en-US", "ja", "ko", "zh-TW", "es", "fr", "de"}
|
||||
@@ -72,22 +86,45 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
var cmd tea.Cmd
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case translateMsg:
|
||||
m.loading = false
|
||||
if msg.err != nil {
|
||||
m.errMsg = msg.err.Error()
|
||||
m.result = ""
|
||||
} else {
|
||||
m.result = msg.result
|
||||
m.errMsg = ""
|
||||
}
|
||||
return m, nil
|
||||
|
||||
case tea.KeyMsg:
|
||||
switch msg.Type {
|
||||
case tea.KeyEnter:
|
||||
// 回车键处理,后续模块会添加翻译逻辑
|
||||
if m.loading {
|
||||
return m, nil
|
||||
}
|
||||
text := m.textInput.Value()
|
||||
if text == "" {
|
||||
return m, nil
|
||||
}
|
||||
m.loading = true
|
||||
m.errMsg = ""
|
||||
return m, m.doTranslate(text, m.targetLang)
|
||||
|
||||
case tea.KeyCtrlC:
|
||||
return m, tea.Quit
|
||||
|
||||
case tea.KeyCtrlL:
|
||||
// Ctrl+L: 清空输入和结果
|
||||
m.textInput.SetValue("")
|
||||
m.result = ""
|
||||
m.errMsg = ""
|
||||
return m, nil
|
||||
|
||||
case tea.KeyCtrlT:
|
||||
// Ctrl+T: 切换语言
|
||||
m.langIndex = (m.langIndex + 1) % len(supportedLangs)
|
||||
m.targetLang = supportedLangs[m.langIndex]
|
||||
return m, nil
|
||||
|
||||
case tea.KeyEsc:
|
||||
return m, tea.Quit
|
||||
}
|
||||
@@ -97,6 +134,23 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
func (m model) doTranslate(text, toLang string) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
result, err := m.translator.Translate(
|
||||
context.Background(),
|
||||
text,
|
||||
&translator.TranslateOptions{
|
||||
ToLang: toLang,
|
||||
PromptName: "simple",
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return translateMsg{err: err}
|
||||
}
|
||||
return translateMsg{result: result.Translated}
|
||||
}
|
||||
}
|
||||
|
||||
func (m model) View() string {
|
||||
resultBox := m.renderResult()
|
||||
helpText := helpStyle.Render("\n " +
|
||||
@@ -116,6 +170,12 @@ func (m model) View() string {
|
||||
}
|
||||
|
||||
func (m model) renderResult() string {
|
||||
if m.loading {
|
||||
return " " + loadingStyle.Render("正在翻译...") + "\n"
|
||||
}
|
||||
if m.errMsg != "" {
|
||||
return " " + errorStyle.Render("错误: "+m.errMsg) + "\n"
|
||||
}
|
||||
if m.result == "" {
|
||||
return " " + helpStyle.Render("翻译结果将显示在这里...") + "\n"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user