feat: datasheet loading spinner

This commit is contained in:
decentral1se 2023-05-10 19:24:10 +02:00
parent 48cb580a49
commit cdfe068cd2
No known key found for this signature in database
GPG Key ID: 03789458B3D0C410

View File

@ -8,6 +8,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/charmbracelet/bubbles/spinner"
"github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/bubbles/textinput"
"github.com/charmbracelet/bubbles/viewport" "github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
@ -71,6 +72,8 @@ type model struct {
datasheets []datasheet // All datasheets under cwd datasheets []datasheet // All datasheets under cwd
datasheetNames []string // All datasheet names (caching) datasheetNames []string // All datasheet names (caching)
filteredDatasheets []string // Filtered view on all datasheets filteredDatasheets []string // Filtered view on all datasheets
loadDatasheetSpinner spinner.Model // Spinner to show while loading datasheets
datasheetsLoaded bool // Whether or not the datasheets are loaded or not
datasheetViewport viewport.Model // Viewport for the PDF content datasheetViewport viewport.Model // Viewport for the PDF content
@ -108,6 +111,35 @@ func initialModel() model {
input := textinput.New() input := textinput.New()
input.Focus() input.Focus()
// TODO: set width/heigh to match terminal. this should also
// be set in relation to the list of filenames also. they
// should have some visually pleasing ratio set i imagine
viewp := viewport.New(60, 30)
loadDatasheetSpinner := spinner.New()
loadDatasheetSpinner.Spinner = spinner.Dot
loadDatasheetSpinner.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
m := model{
input: input,
datasheetsLoaded: false,
loadDatasheetSpinner: loadDatasheetSpinner,
datasheetViewport: viewp,
filterMode: filenameFilterMode,
}
return m
}
// loadedDatasheetsMsg signals to the UI that the datasheets have been loaded.
type loadedDatasheetsMsg struct {
datasheets []datasheet
datasheetNames []string
}
// loadDatasheets loads the datasheets from disk. The UI shows a spinner while
// this is happening so that nobody gets bored.
func loadDatasheets(m model) loadedDatasheetsMsg {
var datasheets []datasheet var datasheets []datasheet
var datasheetNames []string var datasheetNames []string
@ -138,28 +170,19 @@ func initialModel() model {
return nil return nil
}) })
// TODO: set width/heigh to match terminal. this should also return loadedDatasheetsMsg{
// be set in relation to the list of filenames also. they
// should have some visually pleasing ratio set i imagine
viewp := viewport.New(60, 30)
selectedDatasheet := datasheets[len(datasheets)-1].contents
viewp.SetContent(selectedDatasheet)
m := model{
input: input,
datasheets: datasheets, datasheets: datasheets,
datasheetNames: datasheetNames, datasheetNames: datasheetNames,
filteredDatasheets: datasheetNames,
datasheetViewport: viewp,
filterMode: filenameFilterMode,
} }
return m
} }
// Init initialises the program. // Init initialises the program.
func (m model) Init() tea.Cmd { func (m model) Init() tea.Cmd {
return textinput.Blink return tea.Batch(
func() tea.Msg { return loadDatasheets(m) },
textinput.Blink,
m.loadDatasheetSpinner.Tick,
)
} }
// filterDatasheetNames filters datasheet names based on user input. // filterDatasheetNames filters datasheet names based on user input.
@ -189,7 +212,16 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds []tea.Cmd cmds []tea.Cmd
) )
if m.input.Focused() { m.input, cmd = m.input.Update(msg)
cmds = append(cmds, cmd)
m.datasheetViewport, cmd = m.datasheetViewport.Update(msg)
cmds = append(cmds, cmd)
m.loadDatasheetSpinner, cmd = m.loadDatasheetSpinner.Update(msg)
cmds = append(cmds, cmd)
if m.input.Focused() && m.datasheetsLoaded {
m.filteredDatasheets = filterDatasheetNames(m) m.filteredDatasheets = filterDatasheetNames(m)
// TODO: implement cursor for scrolling up/down filtered // TODO: implement cursor for scrolling up/down filtered
@ -202,6 +234,15 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// TODO: handle terminal resizing // TODO: handle terminal resizing
switch msg := msg.(type) { switch msg := msg.(type) {
case loadedDatasheetsMsg:
m.datasheets = msg.datasheets
m.datasheetNames = msg.datasheetNames
m.filteredDatasheets = msg.datasheetNames
selectedDatasheet := msg.datasheets[len(msg.datasheets)-1].contents
m.datasheetViewport.SetContent(selectedDatasheet)
m.datasheetsLoaded = true
case tea.KeyMsg: case tea.KeyMsg:
switch msg.String() { switch msg.String() {
case "ctrl+c": case "ctrl+c":
@ -211,12 +252,6 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} }
} }
m.input, cmd = m.input.Update(msg)
cmds = append(cmds, cmd)
m.datasheetViewport, cmd = m.datasheetViewport.Update(msg)
cmds = append(cmds, cmd)
return m, tea.Batch(cmds...) return m, tea.Batch(cmds...)
} }
@ -224,8 +259,13 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m model) View() string { func (m model) View() string {
body := strings.Builder{} body := strings.Builder{}
var sheets string
if !m.datasheetsLoaded {
sheets = fmt.Sprintf("%s gathering datasheets...", m.loadDatasheetSpinner.View())
} else {
// TODO: paginate / trim view to last 10 or something? // TODO: paginate / trim view to last 10 or something?
sheets := strings.Join(m.filteredDatasheets, "\n") sheets = strings.Join(m.filteredDatasheets, "\n")
}
// TODO: style further with lipgloss, e.g. borders, margins, etc. // TODO: style further with lipgloss, e.g. borders, margins, etc.
panes := lipgloss.JoinHorizontal(lipgloss.Left, sheets, m.datasheetViewport.View()) panes := lipgloss.JoinHorizontal(lipgloss.Left, sheets, m.datasheetViewport.View())