TUI Polish

This commit is contained in:
2026-03-27 19:27:38 -04:00
parent 16ea2e8683
commit c4e6c634d1
13 changed files with 462 additions and 86 deletions

View File

@@ -2,6 +2,7 @@ package api
import (
"net/http"
"sync/atomic"
"time"
)
@@ -10,6 +11,12 @@ type OpenF1Client struct {
apiKey string
httpClient *http.Client
cache *Cache
// staleFlag is set to 1 atomically whenever a request falls back to stale
// cached data (e.g. because the API is locked during a live session).
// The UI reads this via LastResponseWasStale() to decide whether to show
// a disclaimer banner. The flag is sticky until ClearStaleFlag() is called.
staleFlag int32
}
func NewOpenF1Client(url string, timeout time.Duration) *OpenF1Client {
@@ -31,6 +38,31 @@ func NewOpenF1ClientWithKey(url string, timeout time.Duration, apiKey string) *O
}
}
// Cache returns the underlying Cache so callers can access track outline
// storage and other persistent data directly.
func (c *OpenF1Client) Cache() *Cache {
return c.cache
}
// LastResponseWasStale reports whether the most recent API request (or any
// request since the last ClearStaleFlag call) fell back to expired cached
// data because the API was unavailable. The UI uses this to show a
// disclaimer banner informing the user that data may be stale.
func (c *OpenF1Client) LastResponseWasStale() bool {
return atomic.LoadInt32(&c.staleFlag) == 1
}
// ClearStaleFlag resets the stale indicator. Call this when navigating away
// from a tab or after the disclaimer has been acknowledged.
func (c *OpenF1Client) ClearStaleFlag() {
atomic.StoreInt32(&c.staleFlag, 0)
}
// setStale marks the client as having served stale data.
func (c *OpenF1Client) setStale() {
atomic.StoreInt32(&c.staleFlag, 1)
}
// CacheStats returns the cache hit/miss statistics.
func (c *OpenF1Client) CacheStats() CacheStats {
return c.cache.Stats()