45 lines
1.2 KiB
Go
45 lines
1.2 KiB
Go
package browser
|
|
|
|
import "strings"
|
|
|
|
// HandleSearch filters entries by the given query string.
|
|
// It performs case-insensitive substring matching across all loaded pages.
|
|
// When query is empty, search results are cleared.
|
|
// When results are found, ScrollOffset is set to jump to the first match.
|
|
func HandleSearch(s *BrowserState, query string) {
|
|
s.Query = query
|
|
|
|
// Empty query clears search results; leave ScrollOffset unchanged.
|
|
if query == "" {
|
|
s.SearchResults = nil
|
|
return
|
|
}
|
|
|
|
var results []int
|
|
queryLower := strings.ToLower(query)
|
|
|
|
// Iterate over all loaded pages in order (map iteration is non-deterministic).
|
|
totalPages := (s.TotalEntries + PageSize - 1) / PageSize
|
|
for pageIdx := 0; pageIdx < totalPages; pageIdx++ {
|
|
page, ok := s.Pages[pageIdx]
|
|
if !ok || !page.Loaded {
|
|
continue
|
|
}
|
|
// Compute the global start index for this page.
|
|
startIdx := pageIdx * PageSize
|
|
for i, entry := range page.Entries {
|
|
globalIdx := startIdx + i
|
|
if strings.Contains(strings.ToLower(entry.Name), queryLower) {
|
|
results = append(results, globalIdx)
|
|
}
|
|
}
|
|
}
|
|
|
|
s.SearchResults = results
|
|
|
|
// Jump to first result if any matches found.
|
|
if len(results) > 0 {
|
|
s.ScrollOffset = float64(results[0]) * s.EntryHeight
|
|
}
|
|
}
|