package setup import ( "bubble/setup/ui" "bubble/types" "fmt" "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss/table" ) type FinalModel struct { variables []types.Variable table *table.Table viewport viewport.Model ready bool width int height int } func NewFinalModel(variables []types.Variable, width, height int) *FinalModel { m := &FinalModel{ variables: variables, width: width, height: height, ready: false, } if width > 0 && height > 0 { m.initViewport(width, height) } return m } func (m *FinalModel) Init() tea.Cmd { return nil } func (m *FinalModel) initViewport(width, height int) { m.viewport = viewport.New(width, height-8) m.viewport.Width = width m.viewport.Height = height - 10 m.ready = true m.rebuildTable(m.viewport.Width) m.viewport.SetContent(m.table.Render()) } func (m *FinalModel) rebuildTable(width int) { if len(m.variables) == 0 { m.table = table.New().Headers("Нет переменных") return } availableWidth := width - 12 // примерно: 2 (отступы) + 4 (бордер) + запас if availableWidth < 70 { availableWidth = 70 } t := table.New(). Border(lipgloss.RoundedBorder()). BorderStyle(ui.TableBorder). StyleFunc(func(row, col int) lipgloss.Style { var style lipgloss.Style switch { case row == table.HeaderRow: return ui.TableHeader case row%2 == 0: style = ui.TableRowEven.Padding(0, 2) default: style = ui.TableRowOdd.Padding(0, 2) } switch col { case 0, 1: style = style.Width(25) case 2: style = style.Width(availableWidth - 50 - 10) } return style }). Headers("Variable name", "Default value", "Used value") for _, v := range m.variables { used := fmt.Sprintf("%v", v.Value) if used == "" { used = "<пусто>" } t.Row(v.Name, v.Default, used) } m.table = t } func (m *FinalModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { case "ctrl+c", "q": return m, tea.Quit case "up": m.viewport.ScrollUp(1) case "down": m.viewport.ScrollDown(1) case "pageup": m.viewport.HalfPageUp() case "pagedown": m.viewport.HalfPageDown() case "home": m.viewport.GotoTop() case "end": m.viewport.GotoBottom() } case tea.WindowSizeMsg: if !m.ready { m.initViewport(msg.Width, msg.Height) } else { m.viewport.Width = msg.Width - 4 m.viewport.Height = msg.Height - 6 } m.rebuildTable(m.viewport.Width) rendered := m.table.Render() m.viewport.SetContent(rendered) } m.viewport, cmd = m.viewport.Update(msg) return m, cmd } func (m *FinalModel) View() string { if !m.ready { return "Загрузка таблицы" } contentWidth := ui.ContentWidth(m.width) m.rebuildTable(contentWidth) header := ui.HeaderStyle.Width(contentWidth).Render("Итоговые значения переменных") footer := ui.FooterStyle.Width(contentWidth).Render(fmt.Sprintf("Строк: %d • q — выход • ↑↓ / jk — скролл", len(m.variables))) m.viewport.Width = contentWidth - 8 m.viewport.Height = m.height - 12 m.viewport.SetContent(m.table.Render()) body := m.viewport.View() content := lipgloss.JoinVertical(lipgloss.Left, header, body, footer) container := ui.AppContainer.Width(contentWidth).Render(content) return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, container, lipgloss.WithWhitespaceChars("░"), lipgloss.WithWhitespaceForeground(ui.ColorGrey), ) //contentWidth := ui.AppContentWidth(m.width) //m.viewport.Width = contentWidth - 6 //m.viewport.Height = m.height - 12 //m.rebuildTable(contentWidth) // //header := ui.AppHeaderStyle. // Width(contentWidth). // Render("Итоговые значения переменных") // //footer := ui.AppFooterStyle. // Width(contentWidth). // Render(fmt.Sprintf("Строк: %d • q — выход • ↑↓ / jk — скролл", len(m.variables))) // //body := m.viewport.View() //content := lipgloss.JoinVertical(lipgloss.Left, header, body, footer) // //container := ui.AppContainerStyle. // Width(contentWidth). // Render(content) // //return lipgloss.Place(m.width, m.height, // lipgloss.Center, lipgloss.Center, // container, // lipgloss.WithWhitespaceChars("░"), // lipgloss.WithWhitespaceForeground(ui.ColorGrey), //) //header := lipgloss.NewStyle(). // Width(m.viewport.Width). // Align(lipgloss.Center). // Bold(true). // Background(ui.ColorPurple). // Foreground(ui.ColorWhite). // Padding(1). // Render("Итоговые значения переменных") // //footer := lipgloss.NewStyle(). // Width(m.viewport.Width). // Align(lipgloss.Center). // Foreground(ui.ColorGrey). // Padding(0, 1). // Render(fmt.Sprintf("Строк: %d • q — выход • ↑↓ / jk — скролл", len(m.variables))) // //body := m.viewport.View() //return lipgloss.JoinVertical(lipgloss.Center, // header, // body, // footer, //) }