Добавление и исправление комментариев, начало добавление валидации, сообщение прокрути viewport на форме

This commit is contained in:
XeRo 2026-01-20 17:40:21 +05:00
parent c7ff7662ba
commit e37cabadcc
14 changed files with 371 additions and 297 deletions

View file

@ -2,6 +2,7 @@ package fields
import (
"bubble/setup/ui"
"bubble/setup/utils"
"fmt"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
@ -28,8 +29,9 @@ type FileSelectModel struct {
}
// NewFileSelectModel создаем новую модель поля выбора файла
func NewFileSelectModel(label, file, description string, extensions []string) *FileSelectModel {
func NewFileSelectModel(label, file, description string, extensions []string, validator textinput.ValidateFunc) *FileSelectModel {
inputModel := textinput.New()
inputModel.Validate = validator
inputModel.SetValue(file)
return &FileSelectModel{
input: inputModel,
@ -78,7 +80,7 @@ func (m *FileSelectModel) Update(msg tea.Msg) (FieldModel, tea.Cmd) {
//Если имя файла ".." возвращаемся в родительскую папку.
//Если файл является директорией, то переходим в эту директорию.
//Если у файла совпадают расширения, то записываем его и закрываем список.
if len(m.options) == 0 || m.focus == len(m.options) {
if len(m.options) == 0 || m.focus >= len(m.options) {
return m, nil
}
file := m.options[m.focus]
@ -112,7 +114,7 @@ func (m *FileSelectModel) Update(msg tea.Msg) (FieldModel, tea.Cmd) {
}
}
} else {
//Если список не открыт и был нажат enter открываем его и рисуем опции списка.
//Если список не открыт и был нажат enter, открываем его и рисуем опции списка.
//Иначе просто передаем сообщение нажатия клавиш в input.
switch msg.String() {
case "enter":
@ -142,27 +144,13 @@ func (m *FileSelectModel) Update(msg tea.Msg) (FieldModel, tea.Cmd) {
func (m *FileSelectModel) View() string {
res := fmt.Sprintf("%s: %s", m.label, m.input.View())
if m.description != "" {
if m.input.Err != nil && !m.open {
res += fmt.Sprintf("\nОшибка валидации: %s", m.input.Err)
} else if m.description != "" {
res += fmt.Sprintf("\n%s", m.description)
}
if m.open && len(m.options) > 0 {
visibleCount := m.optionsCount //количество отображаемых
if visibleCount > len(m.options) { //если количество отображаемых больше, чем есть опций на самом деле
visibleCount = len(m.options) //то меняем количество видимых на количество опций
}
half := visibleCount / 2 //количество объектов сверху и снизу
start := m.focus - half //стартовая позиция
if start < 0 { //если стартовая позиция меньше 0, то меняем на 0
start = 0
}
end := start + visibleCount //последний элемент
if end > len(m.options) { //если последний элемент вне опций
end = len(m.options) //меняем на количество опций
start = end - visibleCount //перерасчет стартовой позиции
if start < 0 {
start = 0
}
}
start, end := utils.CalculateSelectOptionsIndex(m.focus, m.optionsCount, len(m.options))
for i := start; i < end; i++ {
file := m.options[i]
name := file.Name()