forked from varia/go-sh-manymanuals
feat: datasheet loading spinner
This commit is contained in:
parent
48cb580a49
commit
cdfe068cd2
98
gshmm.go
98
gshmm.go
@ -8,6 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/bubbles/spinner"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
"github.com/charmbracelet/bubbles/viewport"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
@ -68,9 +69,11 @@ func readPDF(name string) (string, error) {
|
||||
type model struct {
|
||||
input textinput.Model // Fuzzy search interface
|
||||
|
||||
datasheets []datasheet // All datasheets under cwd
|
||||
datasheetNames []string // All datasheet names (caching)
|
||||
filteredDatasheets []string // Filtered view on all datasheets
|
||||
datasheets []datasheet // All datasheets under cwd
|
||||
datasheetNames []string // All datasheet names (caching)
|
||||
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
|
||||
|
||||
@ -108,6 +111,35 @@ func initialModel() model {
|
||||
input := textinput.New()
|
||||
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 datasheetNames []string
|
||||
|
||||
@ -138,28 +170,19 @@ func initialModel() model {
|
||||
return nil
|
||||
})
|
||||
|
||||
// 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)
|
||||
selectedDatasheet := datasheets[len(datasheets)-1].contents
|
||||
viewp.SetContent(selectedDatasheet)
|
||||
|
||||
m := model{
|
||||
input: input,
|
||||
datasheets: datasheets,
|
||||
datasheetNames: datasheetNames,
|
||||
filteredDatasheets: datasheetNames,
|
||||
datasheetViewport: viewp,
|
||||
filterMode: filenameFilterMode,
|
||||
return loadedDatasheetsMsg{
|
||||
datasheets: datasheets,
|
||||
datasheetNames: datasheetNames,
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// Init initialises the program.
|
||||
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.
|
||||
@ -189,7 +212,16 @@ func (m model) Update(msg tea.Msg) (tea.Model, 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)
|
||||
|
||||
// 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
|
||||
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:
|
||||
switch msg.String() {
|
||||
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...)
|
||||
}
|
||||
|
||||
@ -224,8 +259,13 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
func (m model) View() string {
|
||||
body := strings.Builder{}
|
||||
|
||||
// TODO: paginate / trim view to last 10 or something?
|
||||
sheets := strings.Join(m.filteredDatasheets, "\n")
|
||||
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?
|
||||
sheets = strings.Join(m.filteredDatasheets, "\n")
|
||||
}
|
||||
|
||||
// TODO: style further with lipgloss, e.g. borders, margins, etc.
|
||||
panes := lipgloss.JoinHorizontal(lipgloss.Left, sheets, m.datasheetViewport.View())
|
||||
|
Loading…
Reference in New Issue
Block a user