fix new installation styling, add blinking, fix version selection

This commit is contained in:
Vilsol 2022-06-05 07:07:19 +03:00
parent ac1dfb6148
commit a5e08cea62
6 changed files with 119 additions and 25 deletions

View file

@ -124,7 +124,6 @@ func (m modMenu) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
newModel, cmd := i.Activate(msg, m)
if newModel != nil || cmd != nil {
if newModel == nil {
newModel.Update(m.root.Size())
newModel = m
}
return newModel, cmd

View file

@ -38,7 +38,7 @@ func NewModSemver(root components.RootModel, parent tea.Model, mod utils.Mod) te
}
func (m modSemver) Init() tea.Cmd {
return nil
return textinput.Blink
}
func (m modSemver) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
@ -66,6 +66,10 @@ func (m modSemver) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.root.SetSize(msg)
case components.ErrorComponentTimeoutMsg:
m.error = nil
default:
var cmd tea.Cmd
m.input, cmd = m.input.Update(msg)
return m, cmd
}
return m, nil

View file

@ -21,7 +21,7 @@ type modVersionMenu struct {
}
func NewModVersion(root components.RootModel, parent tea.Model, mod utils.Mod) tea.Model {
model := modMenu{
model := modVersionMenu{
root: root,
parent: parent,
}
@ -108,7 +108,6 @@ func (m modVersionMenu) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
newModel, cmd := i.Activate(msg, m)
if newModel != nil || cmd != nil {
if newModel == nil {
newModel.Update(m.root.Size())
newModel = m
}
return newModel, cmd

View file

@ -1,18 +1,21 @@
package scenes
import (
"fmt"
"io"
"os"
"path/filepath"
"sort"
"time"
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/list"
"github.com/charmbracelet/bubbles/spinner"
"github.com/sahilm/fuzzy"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/muesli/reflow/truncate"
"github.com/sahilm/fuzzy"
"github.com/satisfactorymodding/ficsit-cli/tea/components"
"github.com/satisfactorymodding/ficsit-cli/tea/utils"
)
@ -29,7 +32,9 @@ type newInstallation struct {
}
func NewNewInstallation(root components.RootModel, parent tea.Model) tea.Model {
l := list.New([]list.Item{}, utils.NewItemDelegate(), root.Size().Width, root.Size().Height-root.Height())
listDelegate := CustomDelegate{ItemDelegate: utils.NewItemDelegate()}
l := list.New([]list.Item{}, listDelegate, root.Size().Width, root.Size().Height-root.Height())
l.SetShowStatusBar(true)
l.SetFilteringEnabled(false)
l.SetSpinner(spinner.MiniDot)
@ -58,7 +63,7 @@ func NewNewInstallation(root components.RootModel, parent tea.Model) tea.Model {
}
func (m newInstallation) Init() tea.Cmd {
return nil
return textinput.Blink
}
func (m newInstallation) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
@ -96,7 +101,7 @@ func (m newInstallation) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
break
}
newDir := newDirItem.(utils.SimpleItem[newInstallation]).ItemTitle
newDir := newDirItem.(utils.SimpleItemExtra[newInstallation, string]).ItemTitle
newPath := ""
_, err := os.ReadDir(m.input.Value())
@ -135,6 +140,10 @@ func (m newInstallation) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.root.SetSize(msg)
case components.ErrorComponentTimeoutMsg:
m.error = nil
default:
var cmd tea.Cmd
m.input, cmd = m.input.Update(msg)
return m, cmd
}
return m, nil
@ -151,13 +160,22 @@ func (m newInstallation) View() string {
if len(m.dirList.Items()) > 0 {
m.dirList.SetSize(m.dirList.Width(), m.root.Size().Height-lipgloss.Height(mandatory)-1)
return lipgloss.JoinVertical(lipgloss.Left, mandatory, m.dirList.View())
}
return mandatory
infoBox := lipgloss.NewStyle().
BorderStyle(lipgloss.ThickBorder()).
BorderForeground(lipgloss.Color("39")).
Padding(0, 1).
Margin(0, 0, 0, 2).
Render("Enter the path to the satisfactory installation")
return lipgloss.JoinVertical(lipgloss.Left, mandatory, infoBox)
}
// I know this is awful, but beats re-implementing the entire list model
var globalMatches []fuzzy.Match
func getDirItems(inputValue string) []list.Item {
filter := ""
dir, err := os.ReadDir(inputValue)
@ -170,22 +188,81 @@ func getDirItems(inputValue string) []list.Item {
newItems := make([]list.Item, 0)
if inputValue != "" {
for _, entry := range dir {
if entry.IsDir() {
if filter != "" {
matches := fuzzy.Find(filter, []string{entry.Name()})
if len(matches) == 0 {
continue
}
}
globalMatches = nil
newItems = append(newItems, utils.SimpleItem[newInstallation]{
ItemTitle: entry.Name(),
if inputValue != "" {
if filter != "" {
dirNames := make([]string, 0)
for _, entry := range dir {
if entry.IsDir() {
dirNames = append(dirNames, entry.Name())
}
}
matches := fuzzy.Find(filter, dirNames)
sort.Stable(matches)
for _, match := range matches {
newItems = append(newItems, utils.SimpleItemExtra[newInstallation, string]{
SimpleItem: utils.SimpleItem[newInstallation]{
ItemTitle: match.Str,
},
Extra: match.Str,
})
}
globalMatches = matches
} else {
for _, entry := range dir {
if entry.IsDir() {
newItems = append(newItems, utils.SimpleItemExtra[newInstallation, string]{
SimpleItem: utils.SimpleItem[newInstallation]{
ItemTitle: entry.Name(),
},
Extra: entry.Name(),
})
}
}
}
}
return newItems
}
type CustomDelegate struct {
list.ItemDelegate
}
func (c CustomDelegate) Render(w io.Writer, m list.Model, index int, item list.Item) {
realItem := item.(utils.SimpleItemExtra[newInstallation, string])
realDelegate := c.ItemDelegate.(list.DefaultDelegate)
title := realItem.Title()
s := &realDelegate.Styles
if m.Width() <= 0 {
return
}
textwidth := uint(m.Width() - s.NormalTitle.GetPaddingLeft() - s.NormalTitle.GetPaddingRight())
title = truncate.StringWithTail(title, textwidth, "…")
if index == m.Index() {
if globalMatches != nil {
unmatched := s.SelectedTitle.Inline(true)
matched := unmatched.Copy().Inherit(s.FilterMatch)
title = lipgloss.StyleRunes(title, globalMatches[index].MatchedIndexes, matched, unmatched)
}
title = s.SelectedTitle.Render(title)
} else {
if globalMatches != nil {
unmatched := s.NormalTitle.Inline(true)
matched := unmatched.Copy().Inherit(s.FilterMatch)
title = lipgloss.StyleRunes(title, globalMatches[index].MatchedIndexes, matched, unmatched)
}
title = s.NormalTitle.Render(title)
}
fmt.Fprintf(w, "%s", title)
}

View file

@ -35,7 +35,7 @@ func NewNewProfile(root components.RootModel, parent tea.Model) tea.Model {
}
func (m newProfile) Init() tea.Cmd {
return nil
return textinput.Blink
}
func (m newProfile) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
@ -63,6 +63,10 @@ func (m newProfile) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.root.SetSize(msg)
case components.ErrorComponentTimeoutMsg:
m.error = nil
default:
var cmd tea.Cmd
m.input, cmd = m.input.Update(msg)
return m, cmd
}
return m, nil
@ -75,5 +79,12 @@ func (m newProfile) View() string {
return lipgloss.JoinVertical(lipgloss.Left, m.root.View(), m.title, (*m.error).View(), inputView)
}
return lipgloss.JoinVertical(lipgloss.Left, m.root.View(), m.title, inputView)
infoBox := lipgloss.NewStyle().
BorderStyle(lipgloss.ThickBorder()).
BorderForeground(lipgloss.Color("39")).
Padding(0, 1).
Margin(0, 0, 0, 2).
Render("Enter the name of the profile")
return lipgloss.JoinVertical(lipgloss.Left, m.root.View(), m.title, inputView, infoBox)
}

View file

@ -40,7 +40,7 @@ func NewRenameProfile(root components.RootModel, parent tea.Model, profileData *
}
func (m renameProfile) Init() tea.Cmd {
return nil
return textinput.Blink
}
func (m renameProfile) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
@ -68,6 +68,10 @@ func (m renameProfile) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.root.SetSize(msg)
case components.ErrorComponentTimeoutMsg:
m.error = nil
default:
var cmd tea.Cmd
m.input, cmd = m.input.Update(msg)
return m, cmd
}
return m, nil