101 lines
2.9 KiB
Go
101 lines
2.9 KiB
Go
|
|
package setup
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"bubble/setup/ui"
|
|||
|
|
"bubble/types"
|
|||
|
|
"github.com/charmbracelet/bubbles/viewport"
|
|||
|
|
tea "github.com/charmbracelet/bubbletea"
|
|||
|
|
"github.com/charmbracelet/lipgloss"
|
|||
|
|
"github.com/muesli/reflow/wordwrap"
|
|||
|
|
"strings"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// LogModel структура описывающая модель отрисовки окна логирования
|
|||
|
|
type LogModel struct {
|
|||
|
|
logs []string //Массив строк логирования
|
|||
|
|
viewport viewport.Model //Видимая область логов
|
|||
|
|
width int //Ширина
|
|||
|
|
height int //Высота
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewLogModel создает новую модель логирования
|
|||
|
|
func NewLogModel(width, height int) *LogModel {
|
|||
|
|
l := &LogModel{
|
|||
|
|
logs: make([]string, 0),
|
|||
|
|
width: width,
|
|||
|
|
height: height,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if width > 0 && height > 0 {
|
|||
|
|
l.initViewport(width, height)
|
|||
|
|
}
|
|||
|
|
return l
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (m *LogModel) Init() tea.Cmd {
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Update отслеживает действия логов
|
|||
|
|
func (m *LogModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
|
|
var cmd tea.Cmd
|
|||
|
|
switch msg := msg.(type) {
|
|||
|
|
case tea.WindowSizeMsg:
|
|||
|
|
//Отслеживает и записывает новый размеры окна, обновляет область действий
|
|||
|
|
m.height = msg.Height
|
|||
|
|
m.width = msg.Width
|
|||
|
|
m.initViewport(m.width, m.height)
|
|||
|
|
return m, nil
|
|||
|
|
case types.ActionClearLogsMsg:
|
|||
|
|
//Отслеживаем сообщение об очистке сообщений
|
|||
|
|
m.logs = make([]string, 0)
|
|||
|
|
m.rebuildContent(m.width)
|
|||
|
|
case tea.KeyMsg:
|
|||
|
|
//Передаем нажатия клавиш для обновления области действий
|
|||
|
|
m.viewport, cmd = m.viewport.Update(msg)
|
|||
|
|
return m, cmd
|
|||
|
|
}
|
|||
|
|
return m, cmd
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (m *LogModel) View() string {
|
|||
|
|
containerWidth, containerHeight, contentWidth, _ := ui.ContentSizes(m.width, m.height)
|
|||
|
|
m.rebuildContent(contentWidth)
|
|||
|
|
container := ui.AppContainer.
|
|||
|
|
Width(containerWidth).
|
|||
|
|
Height(containerHeight).
|
|||
|
|
Render(m.viewport.View())
|
|||
|
|
|
|||
|
|
return lipgloss.Place(
|
|||
|
|
m.width, m.height,
|
|||
|
|
lipgloss.Center, lipgloss.Center,
|
|||
|
|
container,
|
|||
|
|
lipgloss.WithWhitespaceChars("&"),
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func (m *LogModel) initViewport(width, height int) {
|
|||
|
|
_, _, contentWidth, contentHeight := ui.ContentSizes(width, height)
|
|||
|
|
m.viewport = viewport.New(contentWidth, contentHeight)
|
|||
|
|
m.viewport.SetHorizontalStep(1)
|
|||
|
|
m.rebuildContent(contentWidth)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// rebuildContent обновляем содержимое логов
|
|||
|
|
func (m *LogModel) rebuildContent(width int) {
|
|||
|
|
var sb strings.Builder
|
|||
|
|
for i, log := range m.logs {
|
|||
|
|
//Строка логирования с переносом слов
|
|||
|
|
logString := wordwrap.String(log, width)
|
|||
|
|
//Рендер строки логов
|
|||
|
|
logString = lipgloss.NewStyle().Foreground(lipgloss.Color("#fff")).Render(logString)
|
|||
|
|
if i != len(m.logs)-1 {
|
|||
|
|
logString += "\n\n"
|
|||
|
|
} else {
|
|||
|
|
logString += "\n"
|
|||
|
|
}
|
|||
|
|
sb.WriteString(logString)
|
|||
|
|
}
|
|||
|
|
m.viewport.SetContent(sb.String())
|
|||
|
|
}
|