GoSetup-bubble/setup/list.go

156 lines
4.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package setup
import (
"bubble/setup/ui"
"bubble/types"
"fmt"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/sirupsen/logrus"
)
type ListApplicationItem struct {
Application types.PackageApplication
}
func (i ListApplicationItem) Title() string {
return fmt.Sprintf("%s, v%s", i.Application.Name, i.Application.Version)
}
func (i ListApplicationItem) Description() string {
return fmt.Sprintf("%s", i.Application.Description)
}
func (i ListApplicationItem) FilterValue() string {
return i.Application.Name
}
type ListApplicationsModel struct {
List list.Model
width int
height int
}
func NewListApplicationsModel(applications []types.PackageApplication, width, height int) *ListApplicationsModel {
items := make([]list.Item, len(applications))
for i, app := range applications {
items[i] = ListApplicationItem{app}
}
delegate := list.NewDefaultDelegate()
delegate.Styles.SelectedTitle = ui.ListSelectedStyle
delegate.Styles.SelectedDesc = ui.ListSelectedStyle
delegate.ShowDescription = false
l := list.New(items, delegate, width, height)
l.Title = "Приложения"
l.Styles.Title = ui.ListTitleStyle
l.SetShowHelp(false)
return &ListApplicationsModel{
List: l,
width: width,
height: height,
}
}
func (m *ListApplicationsModel) Init() tea.Cmd {
return nil
}
func (m *ListApplicationsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.width = msg.Width
m.height = msg.Height
return m, nil
case tea.KeyMsg:
switch msg.String() {
case "enter":
selected := m.List.SelectedItem().(ListApplicationItem)
return m, func() tea.Msg {
return types.ShowModalMsg{
Type: types.ModalConfirm,
Title: "Начать установку",
Message: fmt.Sprintf("Вы хотите настроить приложение:\n\n%s\n\nПродолжить?", selected.Title()),
ModalButtons: []types.ModalButton{
{Text: "Да", Value: true},
{Text: "Нет", Value: false},
},
OnResult: func(result any) tea.Cmd {
if result == true {
return func() tea.Msg {
return types.SelectedAppMsg{App: selected.Application}
}
}
return nil
},
}
}
}
}
m.List, cmd = m.List.Update(msg)
return m, cmd
}
func (m *ListApplicationsModel) View() string {
gapStroke := " "
containerWidth, containerHeight, contentWidth, contentHeight := ui.ContentSizes(m.width, m.height)
listWidth := int(float64(contentWidth)*ui.ListWithRatio) - 2*1
//ширина листа = пропорция от ширины контента - границы для контейнера листа
listHeight := contentHeight - 2*1
//высота листа = высота контента - границы для контейнера листа
descWidth := int(float64(contentWidth)*(1-ui.ListWithRatio)) - 2*1 - len(gapStroke)
//ширина описания = обратная пропорция листа от ширины контента - границы для контейнера описания - отступ от контейнера листа
descHeight := contentHeight - 2*1
//высота листа = высота контента - границы для контейнера описания
m.List.SetSize(listWidth, listHeight)
//logs.go logrus.DebugLevel set
logrus.Debugf(
"window: width %d, height %d\ncontainer: width %d, height %d\ncontent: width %d, height %d\nlist: width %d, height %d\ndesc: width %d, height %d\n\n",
m.width, m.height,
containerWidth, containerHeight,
contentWidth, contentHeight,
listWidth, listHeight,
descWidth, descHeight,
)
listView := lipgloss.NewStyle().
Width(listWidth).
Height(listHeight).
Border(lipgloss.RoundedBorder()).
BorderForeground(ui.ColorPurple).
AlignVertical(lipgloss.Top).
Render(m.List.View())
var desc string
if sel := m.List.SelectedItem(); sel != nil {
desc = sel.(ListApplicationItem).Description()
}
descView := ui.ListDescriptionStyle.
Width(descWidth).
Height(descHeight).
Border(lipgloss.RoundedBorder()).
BorderForeground(ui.ColorError).
AlignVertical(lipgloss.Top).
Render(
desc,
)
body := lipgloss.JoinHorizontal(lipgloss.Center, listView, gapStroke, descView)
container := ui.AppContainer.
Width(containerWidth).
Height(containerHeight).
Render(body)
return lipgloss.Place(
m.width, m.height,
lipgloss.Center, lipgloss.Center,
container,
lipgloss.WithWhitespaceChars("░"),
lipgloss.WithWhitespaceForeground(ui.ColorWarning),
)
}