149 lines
2.9 KiB
Go
149 lines
2.9 KiB
Go
package tui
|
|
|
|
import (
|
|
"learning-assistant/internal/ai"
|
|
"learning-assistant/internal/ai/generators"
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/charmbracelet/lipgloss"
|
|
)
|
|
|
|
// State TUI状态
|
|
type State string
|
|
|
|
const (
|
|
StateInput State = "input"
|
|
StateLoading State = "loading"
|
|
StateResult State = "result"
|
|
StateError State = "error"
|
|
)
|
|
|
|
// TabType Tab类型
|
|
type TabType string
|
|
|
|
const (
|
|
TabGuodegang TabType = "guodegang"
|
|
TabQuiz TabType = "quiz"
|
|
TabCard TabType = "card"
|
|
TabScenario TabType = "scenario"
|
|
)
|
|
|
|
// TabItem Tab项
|
|
type TabItem struct {
|
|
Type TabType
|
|
Label string
|
|
Icon string
|
|
}
|
|
|
|
// Model TUI模型
|
|
type Model struct {
|
|
state State
|
|
|
|
// AI组件
|
|
client *ai.SiliconFlowClient
|
|
promptManager *ai.PromptManager
|
|
generator *generators.BaseGenerator
|
|
|
|
// 用户输入
|
|
inputText string
|
|
|
|
// 生成结果
|
|
results map[TabType]string
|
|
|
|
// 加载状态
|
|
loadingStatus map[generators.GeneratorType]bool
|
|
|
|
// Tab管理
|
|
tabs []TabItem
|
|
activeTab int
|
|
|
|
// 错误信息
|
|
errorMsg string
|
|
}
|
|
|
|
// NewModel 创建模型
|
|
func NewModel(client *ai.SiliconFlowClient, promptManager *ai.PromptManager) Model {
|
|
return Model{
|
|
state: StateResult,
|
|
client: client,
|
|
promptManager: promptManager,
|
|
generator: generators.NewBaseGenerator(client, promptManager),
|
|
inputText: "",
|
|
results: make(map[TabType]string),
|
|
loadingStatus: make(map[generators.GeneratorType]bool),
|
|
tabs: []TabItem{
|
|
{Type: TabGuodegang, Label: "讲解", Icon: "🎭"},
|
|
{Type: TabQuiz, Label: "考核", Icon: "✍️"},
|
|
{Type: TabCard, Label: "卡片", Icon: "📝"},
|
|
{Type: TabScenario, Label: "场景", Icon: "🏗️"},
|
|
},
|
|
activeTab: 0,
|
|
}
|
|
}
|
|
|
|
// SetInput 设置输入
|
|
func (m *Model) SetInput(input string) {
|
|
m.inputText = input
|
|
m.state = StateLoading
|
|
}
|
|
|
|
// Init 初始化
|
|
func (m Model) Init() tea.Cmd {
|
|
return nil
|
|
}
|
|
|
|
// Update 更新
|
|
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
switch msg := msg.(type) {
|
|
case tea.KeyMsg:
|
|
return m.handleKeyPress(msg)
|
|
case contentMsg:
|
|
return m.handleContentResult(msg)
|
|
case errorMessage:
|
|
return m.handleError(msg)
|
|
}
|
|
|
|
return m, nil
|
|
}
|
|
|
|
// View 视图
|
|
func (m Model) View() string {
|
|
switch m.state {
|
|
case StateInput:
|
|
return m.inputView()
|
|
case StateLoading:
|
|
return m.loadingView()
|
|
case StateResult:
|
|
return m.resultView()
|
|
case StateError:
|
|
return m.errorView()
|
|
default:
|
|
return "Unknown state"
|
|
}
|
|
}
|
|
|
|
// contentMsg 内容生成完成消息
|
|
type contentMsg struct {
|
|
Type generators.GeneratorType
|
|
Content string
|
|
}
|
|
|
|
// errorMessage 错误消息
|
|
type errorMessage struct {
|
|
Type generators.GeneratorType
|
|
Error error
|
|
}
|
|
|
|
// 样式定义
|
|
var (
|
|
baseStyle = lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("#FAFAFA"))
|
|
|
|
headerStyle = lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("#7D56F4")).
|
|
Bold(true)
|
|
|
|
errorStyle = lipgloss.NewStyle().
|
|
Foreground(lipgloss.Color("#FF5555"))
|
|
)
|