mirror of
https://github.com/ddworken/hishtory.git
synced 2025-01-23 06:38:52 +01:00
Replace e50f4d164
with query IDs so that we properly handle deletions. See e50f4d164
for full details on the bug that this fixes.
This commit is contained in:
parent
e50f4d164b
commit
93cffd98b4
@ -31,6 +31,13 @@ const PADDED_NUM_ENTRIES = TABLE_HEIGHT * 5
|
|||||||
var CURRENT_QUERY_FOR_HIGHLIGHTING string = ""
|
var CURRENT_QUERY_FOR_HIGHLIGHTING string = ""
|
||||||
var SELECTED_COMMAND string = ""
|
var SELECTED_COMMAND string = ""
|
||||||
|
|
||||||
|
// Globally shared monotonically increasing IDs used to prevent race conditions in handling async queries.
|
||||||
|
// If the user types 'l' and then 's', two queries will be dispatched: One for 'l' and one for 'ls'. These
|
||||||
|
// counters are used to ensure that we don't process the query results for 'ls' and then promptly overwrite
|
||||||
|
// them with the results for 'l'.
|
||||||
|
var LAST_DISPATCHED_QUERY_ID = 0
|
||||||
|
var LAST_PROCESSED_QUERY_ID = -1
|
||||||
|
|
||||||
var baseStyle = lipgloss.NewStyle().
|
var baseStyle = lipgloss.NewStyle().
|
||||||
BorderStyle(lipgloss.NormalBorder()).
|
BorderStyle(lipgloss.NormalBorder()).
|
||||||
BorderForeground(lipgloss.Color("240"))
|
BorderForeground(lipgloss.Color("240"))
|
||||||
@ -183,8 +190,8 @@ type bannerMsg struct {
|
|||||||
banner string
|
banner string
|
||||||
}
|
}
|
||||||
type asyncQueryFinishedMsg struct {
|
type asyncQueryFinishedMsg struct {
|
||||||
// The query that finished running. Used to ensure that we only process this message if it matches the current query.
|
// The query ID finished running. Used to ensure that we only process this message if it is the latest query to finish.
|
||||||
searchedQuery string
|
queryId int
|
||||||
// The table rows and entries
|
// The table rows and entries
|
||||||
rows []table.Row
|
rows []table.Row
|
||||||
entries []*data.HistoryEntry
|
entries []*data.HistoryEntry
|
||||||
@ -275,9 +282,11 @@ func runQueryAndUpdateTable(m model, forceUpdateTable, maintainCursor bool) tea.
|
|||||||
if m.runQuery != nil {
|
if m.runQuery != nil {
|
||||||
query = *m.runQuery
|
query = *m.runQuery
|
||||||
}
|
}
|
||||||
|
queryId := LAST_DISPATCHED_QUERY_ID
|
||||||
|
LAST_DISPATCHED_QUERY_ID += 1
|
||||||
return func() tea.Msg {
|
return func() tea.Msg {
|
||||||
rows, entries, searchErr := getRows(m.ctx, hctx.GetConf(m.ctx).DisplayedColumns, query, PADDED_NUM_ENTRIES)
|
rows, entries, searchErr := getRows(m.ctx, hctx.GetConf(m.ctx).DisplayedColumns, query, PADDED_NUM_ENTRIES)
|
||||||
return asyncQueryFinishedMsg{query, rows, entries, searchErr, forceUpdateTable, maintainCursor, nil}
|
return asyncQueryFinishedMsg{queryId, rows, entries, searchErr, forceUpdateTable, maintainCursor, nil}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -349,7 +358,8 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
m.isLoading = false
|
m.isLoading = false
|
||||||
return m, nil
|
return m, nil
|
||||||
case asyncQueryFinishedMsg:
|
case asyncQueryFinishedMsg:
|
||||||
if m.runQuery != nil && *m.runQuery == msg.searchedQuery {
|
if msg.queryId > LAST_PROCESSED_QUERY_ID {
|
||||||
|
LAST_PROCESSED_QUERY_ID = msg.queryId
|
||||||
m = updateTable(m, msg.rows, msg.entries, msg.searchErr, msg.forceUpdateTable, msg.maintainCursor)
|
m = updateTable(m, msg.rows, msg.entries, msg.searchErr, msg.forceUpdateTable, msg.maintainCursor)
|
||||||
if msg.overriddenSearchQuery != nil {
|
if msg.overriddenSearchQuery != nil {
|
||||||
m.queryInput.SetValue(*msg.overriddenSearchQuery)
|
m.queryInput.SetValue(*msg.overriddenSearchQuery)
|
||||||
@ -391,6 +401,7 @@ func (m model) View() string {
|
|||||||
if m.isLoading {
|
if m.isLoading {
|
||||||
loadingMessage = fmt.Sprintf("%s Loading hishtory entries from other devices...", m.spinner.View())
|
loadingMessage = fmt.Sprintf("%s Loading hishtory entries from other devices...", m.spinner.View())
|
||||||
}
|
}
|
||||||
|
// TODO: There is a bug where it is needed to add a new line between warnings
|
||||||
warning := ""
|
warning := ""
|
||||||
if m.isOffline {
|
if m.isOffline {
|
||||||
warning += "Warning: failed to contact the hishtory backend (are you offline?), so some results may be stale"
|
warning += "Warning: failed to contact the hishtory backend (are you offline?), so some results may be stale"
|
||||||
@ -693,14 +704,16 @@ func TuiQuery(ctx context.Context, initialQuery string) error {
|
|||||||
p := tea.NewProgram(initialModel(ctx, initialQuery), tea.WithOutput(os.Stderr))
|
p := tea.NewProgram(initialModel(ctx, initialQuery), tea.WithOutput(os.Stderr))
|
||||||
// Async: Get the initial set of rows
|
// Async: Get the initial set of rows
|
||||||
go func() {
|
go func() {
|
||||||
|
queryId := LAST_DISPATCHED_QUERY_ID
|
||||||
|
LAST_DISPATCHED_QUERY_ID++
|
||||||
rows, entries, err := getRows(ctx, hctx.GetConf(ctx).DisplayedColumns, initialQuery, PADDED_NUM_ENTRIES)
|
rows, entries, err := getRows(ctx, hctx.GetConf(ctx).DisplayedColumns, initialQuery, PADDED_NUM_ENTRIES)
|
||||||
if err == nil || initialQuery == "" {
|
if err == nil || initialQuery == "" {
|
||||||
p.Send(asyncQueryFinishedMsg{searchedQuery: initialQuery, rows: rows, entries: entries, searchErr: err, forceUpdateTable: true, maintainCursor: false, overriddenSearchQuery: nil})
|
p.Send(asyncQueryFinishedMsg{queryId: queryId, rows: rows, entries: entries, searchErr: err, forceUpdateTable: true, maintainCursor: false, overriddenSearchQuery: nil})
|
||||||
} else {
|
} else {
|
||||||
// initialQuery is likely invalid in some way, let's just drop it
|
// initialQuery is likely invalid in some way, let's just drop it
|
||||||
emptyQuery := ""
|
emptyQuery := ""
|
||||||
rows, entries, err := getRows(ctx, hctx.GetConf(ctx).DisplayedColumns, emptyQuery, PADDED_NUM_ENTRIES)
|
rows, entries, err := getRows(ctx, hctx.GetConf(ctx).DisplayedColumns, emptyQuery, PADDED_NUM_ENTRIES)
|
||||||
p.Send(asyncQueryFinishedMsg{searchedQuery: emptyQuery, rows: rows, entries: entries, searchErr: err, forceUpdateTable: true, maintainCursor: false, overriddenSearchQuery: &emptyQuery})
|
p.Send(asyncQueryFinishedMsg{queryId: queryId, rows: rows, entries: entries, searchErr: err, forceUpdateTable: true, maintainCursor: false, overriddenSearchQuery: &emptyQuery})
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// Async: Retrieve additional entries from the backend
|
// Async: Retrieve additional entries from the backend
|
||||||
|
Loading…
Reference in New Issue
Block a user