mirror of
https://github.com/ddworken/hishtory.git
synced 2025-04-01 11:58:38 +02: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 {
|
type bannerMsg struct {
|
||||||
banner string
|
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 {
|
func initialModel(ctx *context.Context, t table.Model, tableEntries []*data.HistoryEntry, initialQuery string) model {
|
||||||
s := spinner.New()
|
s := spinner.New()
|
||||||
@ -199,30 +205,27 @@ func (m model) Init() tea.Cmd {
|
|||||||
return m.spinner.Tick
|
return m.spinner.Tick
|
||||||
}
|
}
|
||||||
|
|
||||||
func runQueryAndUpdateTable(m model, updateTable bool) model {
|
func updateTable(m model, forceUpdateTable bool, rows []table.Row, entries []*data.HistoryEntry, searchErr error) model {
|
||||||
if (m.runQuery != nil && *m.runQuery != m.lastQuery) || updateTable || m.searchErr != nil {
|
if m.runQuery == nil {
|
||||||
if m.runQuery == nil {
|
m.runQuery = &m.lastQuery
|
||||||
m.runQuery = &m.lastQuery
|
}
|
||||||
}
|
m.searchErr = searchErr
|
||||||
rows, entries, err := getRows(m.ctx, hctx.GetConf(m.ctx).DisplayedColumns, *m.runQuery, PADDED_NUM_ENTRIES)
|
if searchErr != nil {
|
||||||
m.searchErr = err
|
return m
|
||||||
|
}
|
||||||
|
m.tableEntries = entries
|
||||||
|
if forceUpdateTable {
|
||||||
|
t, err := makeTable(m.ctx, rows)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
m.fatalErr = err
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
m.tableEntries = entries
|
m.table = t
|
||||||
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.SetRows(rows)
|
||||||
|
m.table.SetCursor(0)
|
||||||
|
m.lastQuery = *m.runQuery
|
||||||
|
m.runQuery = nil
|
||||||
if m.table.Cursor() >= len(m.tableEntries) {
|
if m.table.Cursor() >= len(m.tableEntries) {
|
||||||
// Ensure that we can't scroll past the end of the table
|
// Ensure that we can't scroll past the end of the table
|
||||||
m.table.SetCursor(len(m.tableEntries) - 1)
|
m.table.SetCursor(len(m.tableEntries) - 1)
|
||||||
@ -230,6 +233,27 @@ func runQueryAndUpdateTable(m model, updateTable bool) model {
|
|||||||
return m
|
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) {
|
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
@ -253,8 +277,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
m.fatalErr = err
|
m.fatalErr = err
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
m = runQueryAndUpdateTable(m, true)
|
cmd := runQueryAndUpdateTable(m, true)
|
||||||
return m, nil
|
preventTableOverscrolling(m)
|
||||||
|
return m, cmd
|
||||||
case key.Matches(msg, keys.Help):
|
case key.Matches(msg, keys.Help):
|
||||||
m.help.ShowAll = !m.help.ShowAll
|
m.help.ShowAll = !m.help.ShowAll
|
||||||
return m, nil
|
return m, nil
|
||||||
@ -268,13 +293,14 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
m.queryInput = i
|
m.queryInput = i
|
||||||
searchQuery := m.queryInput.Value()
|
searchQuery := m.queryInput.Value()
|
||||||
m.runQuery = &searchQuery
|
m.runQuery = &searchQuery
|
||||||
m = runQueryAndUpdateTable(m, false)
|
cmd3 := runQueryAndUpdateTable(m, false)
|
||||||
return m, tea.Batch(cmd1, cmd2)
|
preventTableOverscrolling(m)
|
||||||
|
return m, tea.Batch(cmd1, cmd2, cmd3)
|
||||||
}
|
}
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
m.help.Width = msg.Width
|
m.help.Width = msg.Width
|
||||||
m = runQueryAndUpdateTable(m, true)
|
cmd := runQueryAndUpdateTable(m, true)
|
||||||
return m, nil
|
return m, cmd
|
||||||
case offlineMsg:
|
case offlineMsg:
|
||||||
m.isOffline = true
|
m.isOffline = true
|
||||||
return m, nil
|
return m, nil
|
||||||
@ -284,6 +310,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
case doneDownloadingMsg:
|
case doneDownloadingMsg:
|
||||||
m.isLoading = false
|
m.isLoading = false
|
||||||
return m, nil
|
return m, nil
|
||||||
|
case asyncQueryFinishedMsg:
|
||||||
|
m = updateTable(m, msg.forceUpdateTable, msg.rows, msg.entries, msg.searchErr)
|
||||||
|
return m, nil
|
||||||
default:
|
default:
|
||||||
var cmd tea.Cmd
|
var cmd tea.Cmd
|
||||||
if m.isLoading {
|
if m.isLoading {
|
||||||
@ -592,3 +621,5 @@ func TuiQuery(ctx *context.Context, initialQuery string) error {
|
|||||||
|
|
||||||
// TODO: support custom key bindings
|
// TODO: support custom key bindings
|
||||||
// TODO: make the help page wrap
|
// 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 {
|
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 {
|
for _, hostname := range hostnames {
|
||||||
data = strings.ReplaceAll(data, hostname, "ghaction-runner-hostname")
|
data = strings.ReplaceAll(data, hostname, "ghaction-runner-hostname")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user