package ui import ( "strings" "github.com/charmbracelet/lipgloss" ) func (m model) View() string { // Title title := titleStyle.Render(" ByteSock v1.0.0 ") // Status header content status := lipgloss.JoinHorizontal(lipgloss.Top, modeStyle.Render(" [OutMode: "+m.omode.ToString()+"]"), modeStyle.Render("[InMode: "+m.imode.ToString()+"]"), modeStyle.Render("[Type: "+m.conn.ToString()+"]"), rulesetStyle.Render(""), addressStyle.Render(m.address), ) // Padding spacer := m.width - lipgloss.Width(title) - lipgloss.Width(status) - 4 if spacer < 0 { spacer = 0 } usableWidth := m.width - 2 if usableWidth < 0 { usableWidth = 0 } // Status header layout headerLine := lipgloss.JoinHorizontal(lipgloss.Top, title, strings.Repeat("─", spacer), status, ) headerBox := headerBoxStyle.Width(usableWidth).Render(headerLine) // Input field box inputBox := inputStyle.Width(usableWidth).Render("> " + m.input) // Calculate message log height logHeight := m.height - lipgloss.Height(headerBox) - lipgloss.Height(inputBox) - 2 if logHeight < 3 { logHeight = 3 } renderedHeight := logHeight - 2 if renderedHeight < 0 { renderedHeight = 0 } // Extract lines to render var renderedLines []string lineCount := 0 for i := len(m.logs) - 1; i >= 0; i-- { localLines := strings.Split(m.logs[i], "\n") localLineCount := len(localLines) if lineCount+localLineCount > renderedHeight { startIndex := localLineCount - (renderedHeight - lineCount) localLines = localLines[startIndex:] renderedLines = append(localLines, renderedLines...) break } lineCount += localLineCount renderedLines = append(localLines, renderedLines...) } // Message log box logContent := strings.Join(renderedLines, "\n") logBox := boxStyle. Height(logHeight). Width(usableWidth). Render(logStyle.Render(logContent)) // Final layout return lipgloss.JoinVertical(lipgloss.Left, headerBox, logBox, inputBox, ) }