package tui import ( "fmt" "github.com/charmbracelet/lipgloss" "learning-assistant/internal/ai/generators" ) // inputView 输入视图 func (m Model) inputView() string { title := headerStyle.Render("🎓 学习助手") subtitle := baseStyle.Render("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━") inputPrompt := baseStyle.Render("请输入您想学习的知识点,按 Enter 开始生成:\n") return fmt.Sprintf( "\n%s\n%s\n\n%s\n\n%s[按 Ctrl+C 退出]\n", title, subtitle, inputPrompt, baseStyle.Render("> "), ) } // loadingView 加载视图 func (m Model) loadingView() string { title := headerStyle.Render("⏳ 正在生成学习内容...") subtitle := baseStyle.Render("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━") knowledge := fmt.Sprintf("知识点:%s", m.inputText) knowledgeStyled := baseStyle.Render(knowledge) status := "生成状态:\n" // Mermaid if m.loadingStatus[generators.GeneratorMermaid] { status += fmt.Sprintf(" ✓ Mermaid 图表\n") } else { status += fmt.Sprintf(" ◯ Mermaid 图表\n") } // Guodegang if m.loadingStatus[generators.GeneratorGuodegang] { status += fmt.Sprintf(" ✓ 郭德纲式讲解\n") } else { status += fmt.Sprintf(" ◯ 郭德纲式讲解\n") } // Quiz if m.loadingStatus[generators.GeneratorQuiz] { status += fmt.Sprintf(" ✓ 十道考核题\n") } else { status += fmt.Sprintf(" ◯ 十道考核题\n") } // Card if m.loadingStatus[generators.GeneratorCard] { status += fmt.Sprintf(" ✓ 记忆卡片\n") } else { status += fmt.Sprintf(" ◯ 记忆卡片\n") } // Scenario if m.loadingStatus[generators.GeneratorScenario] { status += fmt.Sprintf(" ✓ 工程场景案例\n") } else { status += fmt.Sprintf(" ◯ 工程场景案例\n") } return fmt.Sprintf( "\n%s\n%s\n\n%s\n\n%s %s[按 Ctrl+C 退出]\n", title, subtitle, knowledgeStyled, baseStyle.Render(status), "", "", ) } // resultView 结果视图 func (m Model) resultView() string { title := headerStyle.Render("🎓 学习助手") // Tab栏 tabBar := m.renderTabs() // 分隔线 separator := lipgloss.NewStyle(). Foreground(lipgloss.Color("#586069")). Render("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━") // 当前Tab内容 currentTab := m.tabs[m.activeTab] content, ok := m.results[currentTab.Type] if !ok { content = "内容生成中..." } // 内容区域(简化渲染,实际应该用viewport) contentView := m.renderContent(content, currentTab) // Mermaid复制提示 clipboardHint := "" if currentTab.Type == TabGuodegang || currentTab.Type == TabQuiz || currentTab.Type == TabCard || currentTab.Type == TabScenario { clipboardHint = baseStyle.Render("\n✅ Mermaid 图表已自动复制到剪切板") } // 底部帮助 help := m.renderHelp() return fmt.Sprintf( "%s\n%s\n\n%s\n\n%s\n%s\n%s\n%s", title, tabBar, separator, contentView, "", clipboardHint, "", help, ) } // errorView 错误视图 func (m Model) errorView() string { title := errorStyle.Render("❌ 生成失败") content := errorStyle.Render(m.errorMsg) help := baseStyle.Render("[按 Ctrl+C 退出,或按 Enter 重新输入]") return fmt.Sprintf( "\n%s\n\n%s\n\n%s\n", title, content, help, ) } // renderTabs 渲染Tab栏 func (m Model) renderTabs() string { var tabs []string for i, tab := range m.tabs { var style lipgloss.Style if i == m.activeTab { style = lipgloss.NewStyle(). Foreground(lipgloss.Color("#7D56F4")). Bold(true) } else { style = lipgloss.NewStyle(). Foreground(lipgloss.Color("#586069")) } tabs = append(tabs, style.Render(fmt.Sprintf("[%s%s]", tab.Icon, tab.Label))) } exitHint := lipgloss.NewStyle(). Foreground(lipgloss.Color("#FAFAFA")). Render("q退出") tabs = append(tabs, exitHint) return lipgloss.JoinHorizontal(lipgloss.Top, tabs...) } // renderContent 渲染内容 func (m Model) renderContent(content string, tab TabItem) string { header := lipgloss.NewStyle(). Foreground(lipgloss.Color("#04B575")). Bold(true). Render(fmt.Sprintf("%s %s", tab.Icon, tab.Label)) return fmt.Sprintf("%s\n\n%s", header, baseStyle.Render(content)) } // renderHelp 渲染帮助信息 func (m Model) renderHelp() string { help := baseStyle.Render("←/→ 切换标签页 | ↑/↓ 滚动内容 | q 退出") var style lipgloss.Style style = lipgloss.NewStyle(). Foreground(lipgloss.Color("#586069")) return style.Render(help) }