mirror of
https://github.com/ddworken/hishtory.git
synced 2025-03-27 16:17:11 +01:00
Make queries async for better TUI performance when sqlite is slow
This commit is contained in:
parent
e9adb44f6b
commit
a79d401058
@ -179,6 +179,12 @@ type offlineMsg struct{}
|
||||
type bannerMsg struct {
|
||||
banner string
|
||||
}
|
||||
type asyncQueryFinishedMsg struct {
|
||||
rows []table.Row
|
||||
entries []*data.HistoryEntry
|
||||
searchErr error
|
||||
forceUpdateTable bool
|
||||
}
|
||||
|
||||
func initialModel(ctx *context.Context, t table.Model, tableEntries []*data.HistoryEntry, initialQuery string) model {
|
||||
s := spinner.New()
|
||||
@ -199,30 +205,27 @@ func (m model) Init() tea.Cmd {
|
||||
return m.spinner.Tick
|
||||
}
|
||||
|
||||
func runQueryAndUpdateTable(m model, updateTable bool) model {
|
||||
if (m.runQuery != nil && *m.runQuery != m.lastQuery) || updateTable || m.searchErr != nil {
|
||||
if m.runQuery == nil {
|
||||
m.runQuery = &m.lastQuery
|
||||
}
|
||||
rows, entries, err := getRows(m.ctx, hctx.GetConf(m.ctx).DisplayedColumns, *m.runQuery, PADDED_NUM_ENTRIES)
|
||||
m.searchErr = err
|
||||
func updateTable(m model, forceUpdateTable bool, rows []table.Row, entries []*data.HistoryEntry, searchErr error) model {
|
||||
if m.runQuery == nil {
|
||||
m.runQuery = &m.lastQuery
|
||||
}
|
||||
m.searchErr = searchErr
|
||||
if searchErr != nil {
|
||||
return m
|
||||
}
|
||||
m.tableEntries = entries
|
||||
if forceUpdateTable {
|
||||
t, err := makeTable(m.ctx, rows)
|
||||
if err != nil {
|
||||
m.fatalErr = err
|
||||
return m
|
||||
}
|
||||
m.tableEntries = entries
|
||||
if updateTable {
|
||||
t, err := makeTable(m.ctx, rows)
|
||||
if err != nil {
|
||||
m.fatalErr = err
|
||||
return m
|
||||
}
|
||||
m.table = t
|
||||
}
|
||||
m.table.SetRows(rows)
|
||||
m.table.SetCursor(0)
|
||||
m.lastQuery = *m.runQuery
|
||||
m.runQuery = nil
|
||||
m.table = t
|
||||
}
|
||||
m.table.SetRows(rows)
|
||||
m.table.SetCursor(0)
|
||||
m.lastQuery = *m.runQuery
|
||||
m.runQuery = nil
|
||||
if m.table.Cursor() >= len(m.tableEntries) {
|
||||
// Ensure that we can't scroll past the end of the table
|
||||
m.table.SetCursor(len(m.tableEntries) - 1)
|
||||
@ -230,6 +233,27 @@ func runQueryAndUpdateTable(m model, updateTable bool) model {
|
||||
return m
|
||||
}
|
||||
|
||||
func preventTableOverscrolling(m model) {
|
||||
if m.table.Cursor() >= len(m.tableEntries) {
|
||||
// Ensure that we can't scroll past the end of the table
|
||||
m.table.SetCursor(len(m.tableEntries) - 1)
|
||||
}
|
||||
}
|
||||
|
||||
func runQueryAndUpdateTable(m model, forceUpdateTable bool) tea.Cmd {
|
||||
if (m.runQuery != nil && *m.runQuery != m.lastQuery) || forceUpdateTable || m.searchErr != nil {
|
||||
query := m.lastQuery
|
||||
if m.runQuery != nil {
|
||||
query = *m.runQuery
|
||||
}
|
||||
return func() tea.Msg {
|
||||
rows, entries, searchErr := getRows(m.ctx, hctx.GetConf(m.ctx).DisplayedColumns, query, PADDED_NUM_ENTRIES)
|
||||
return asyncQueryFinishedMsg{rows, entries, searchErr, forceUpdateTable}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
@ -253,8 +277,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.fatalErr = err
|
||||
return m, nil
|
||||
}
|
||||
m = runQueryAndUpdateTable(m, true)
|
||||
return m, nil
|
||||
cmd := runQueryAndUpdateTable(m, true)
|
||||
preventTableOverscrolling(m)
|
||||
return m, cmd
|
||||
case key.Matches(msg, keys.Help):
|
||||
m.help.ShowAll = !m.help.ShowAll
|
||||
return m, nil
|
||||
@ -268,13 +293,14 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.queryInput = i
|
||||
searchQuery := m.queryInput.Value()
|
||||
m.runQuery = &searchQuery
|
||||
m = runQueryAndUpdateTable(m, false)
|
||||
return m, tea.Batch(cmd1, cmd2)
|
||||
cmd3 := runQueryAndUpdateTable(m, false)
|
||||
preventTableOverscrolling(m)
|
||||
return m, tea.Batch(cmd1, cmd2, cmd3)
|
||||
}
|
||||
case tea.WindowSizeMsg:
|
||||
m.help.Width = msg.Width
|
||||
m = runQueryAndUpdateTable(m, true)
|
||||
return m, nil
|
||||
cmd := runQueryAndUpdateTable(m, true)
|
||||
return m, cmd
|
||||
case offlineMsg:
|
||||
m.isOffline = true
|
||||
return m, nil
|
||||
@ -284,6 +310,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
case doneDownloadingMsg:
|
||||
m.isLoading = false
|
||||
return m, nil
|
||||
case asyncQueryFinishedMsg:
|
||||
m = updateTable(m, msg.forceUpdateTable, msg.rows, msg.entries, msg.searchErr)
|
||||
return m, nil
|
||||
default:
|
||||
var cmd tea.Cmd
|
||||
if m.isLoading {
|
||||
@ -592,3 +621,5 @@ func TuiQuery(ctx *context.Context, initialQuery string) error {
|
||||
|
||||
// TODO: support custom key bindings
|
||||
// TODO: make the help page wrap
|
||||
// TODO: FR: when updating the search query, try to maintain position in the table
|
||||
// TODO: FR: when deleting an entry, try to maintain position in the table
|
||||
|
@ -360,7 +360,7 @@ func CompareGoldens(t *testing.T, out, goldenName string) {
|
||||
}
|
||||
|
||||
func normalizeHostnames(data string) string {
|
||||
hostnames := []string{"Davids-MacBook-Air.local", "ghaction-runner-hostname"}
|
||||
hostnames := []string{"Davids-MacBook-Air.local", "ghaction-runner-hostname", "Davids-Air"}
|
||||
for _, hostname := range hostnames {
|
||||
data = strings.ReplaceAll(data, hostname, "ghaction-runner-hostname")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user