Documentation
¶
Overview ¶
Package notification owns the notification feature: the scoped SQLite history store (with level migration and retention pruning) and the UI component — the popup, the history/detail overlays, the log-notification queue, and rendering. The UI half has no dependency on the root workbench package; the root shell supplies screen geometry, the store, and the connection scope through the component's methods and events.
Index ¶
- Constants
- Variables
- func AttachLogProgram(program *tea.Program)
- func DrainLogEntries() []log.Entry
- func EnqueueLogEntry(entry log.Entry)
- func NewHistory(entries []Entry, selectedID int64, width, height int) *history
- func SetNerdFont(enabled bool)
- func StoredLogLevel(level log.Level) int
- type DismissMsg
- type Entry
- type LogWakeupMsg
- type Model
- func (m *Model) ApplyPersisted(token uint64, id int64)
- func (m Model) Consumes(msg tea.Msg, layout uikit.Layout) bool
- func (m Model) DetailOpen() bool
- func (m Model) Draw(canvas uv.ScreenBuffer, layout uikit.Layout)
- func (m Model) HistoryOpen() bool
- func (m *Model) OpenHistory(selectedID int64, width, height int)
- func (m Model) PopupBounds(layout uikit.Layout) (image.Rectangle, bool)
- func (m Model) PopupOpen() bool
- func (m *Model) Reset()
- func (m *Model) ResizeHistory(width, height int)
- func (m *Model) SetEntries(entries []Entry)
- func (m Model) Show(entry Entry, persist bool, duration time.Duration) (Model, tea.Cmd, uint64)
- func (m Model) Update(msg tea.Msg, layout uikit.Layout, keys uikit.KeyMatcher) (Model, uikit.Event, tea.Cmd)
- func (m Model) View(layout uikit.Layout) string
- type Store
Constants ¶
const Limit = 100
Limit bounds the number of live or loaded notifications retained by the UI.
Variables ¶
var DismissTick = func(generation uint64, duration time.Duration) tea.Cmd { return tea.Tick(duration, func(time.Time) tea.Msg { return DismissMsg{Generation: generation} }) }
DismissTick builds the command that closes the popup after the given duration. It is a variable so tests can replace it with an immediate dismiss and avoid wall-clock waits.
Functions ¶
func AttachLogProgram ¶
AttachLogProgram wires the running program into the log notification pipeline so entries logged by async commands surface as popups even when the UI is idle. Call once with the program returned by tea.NewProgram, before program.Run. Attaching nil detaches.
func DrainLogEntries ¶
DrainLogEntries returns and clears the queued log entries.
func EnqueueLogEntry ¶
EnqueueLogEntry is the log package notifier: it queues entries for the next Update drain and wakes the attached program so an entry from an async command surfaces even when the UI is idle. Safe for concurrent callers (async Bubble Tea commands). The wakeup is sent on its own goroutine: the program's message channel is unbuffered, so sending from inside an Update handler (where every current log call happens) would deadlock on the loop waiting for that same Update to return.
func NewHistory ¶
NewHistory builds the modal. selectedID selects the entry with that SQLite row ID, falling back to the newest entry when 0 or absent.
func SetNerdFont ¶
func SetNerdFont(enabled bool)
SetNerdFont records the resolved nerd-font preference for log icons.
func StoredLogLevel ¶
StoredLogLevel converts a log level to the persisted notification level.
Types ¶
type DismissMsg ¶
type DismissMsg struct {
Generation uint64
}
DismissMsg closes the visible popup when its generation still matches the model's current one.
type Entry ¶
type Entry struct {
ID int64
CreatedAt time.Time
Title string
Description string
Level int
// contains filtered or unexported fields
}
Entry is one captured status or log notification. ID is the SQLite row ID when the entry was persisted for a connection scope, 0 otherwise. Level is notificationLevelNone (0) for status messages, or log.Level + 1 for entries captured from the event log.
func LogEntry ¶
LogEntry builds the captured entry for one logged event, carrying the level's icon, title, and severity.
func StatusEntry ¶
StatusEntry builds the captured-status entry for one status transition. The entry always carries a real severity: routine query lifecycle transitions capture at Debug, every other status captures at Info, so history never stores the neutral level 0 again. (Rows persisted before leveled captures keep level 0 and render neutrally via logLevelOf.)
type LogWakeupMsg ¶
type LogWakeupMsg struct{}
LogWakeupMsg wakes the idle program loop when a log entry arrives from an async command; the outer Update wrapper drains the queue into a popup.
type Model ¶
type Model struct {
Entries []Entry
Popup *Entry
Detail *Entry
History *history
Generation uint64
PopupSwallowRelease bool
// contains filtered or unexported fields
}
Model is the notification feature component: the captured entries, the visible popup, the history/detail overlays, the popup click/release swallow state, and the dismiss generation counter. Root owns the persistence store, the connection scope, and screen geometry; the component owns every interaction and renders its own overlays.
func (*Model) ApplyPersisted ¶ added in v1.0.0
ApplyPersisted attaches a persisted row ID to entries that still carry the matching Show token. Stale completions are deliberately ignored.
func (Model) Consumes ¶
Consumes reports whether msg belongs to the notification overlays: the popup dismiss timer, the popup click and its trailing release, or an open history/detail modal (which swallows every input while open). Root routes the message into Update only when this returns true, so an idle notification state never intercepts messages meant for the panes.
func (Model) DetailOpen ¶
DetailOpen reports whether the single-entry detail overlay is open.
func (Model) Draw ¶
func (m Model) Draw(canvas uv.ScreenBuffer, layout uikit.Layout)
Draw renders the component's open overlays onto the canvas: the history modal, then the single-entry detail, then the popup last so it stays readable above everything. Root calls Draw from each overlay precedence slot and draws whatever is open.
func (Model) HistoryOpen ¶
HistoryOpen reports whether the history modal is open.
func (*Model) OpenHistory ¶
OpenHistory opens the history modal, selecting the entry with the given SQLite row ID (0 or absent falls back to the newest entry).
func (Model) PopupBounds ¶
PopupBounds returns the screen rectangle of the visible popup. The popup is a bordered card anchored to the top-right corner.
func (*Model) Reset ¶
func (m *Model) Reset()
Reset clears the captured entries and every overlay in place.
func (*Model) ResizeHistory ¶
ResizeHistory refits an open history modal to a new window size.
func (*Model) SetEntries ¶
SetEntries replaces the captured entry list (the scoped history load).
func (Model) Show ¶
Show surfaces one entry as the visible popup. Persistence itself is owned by the root app's asynchronous command; this component only records a token so the eventual row ID can be attached to the still-live entry.
func (Model) Update ¶
func (m Model) Update(msg tea.Msg, layout uikit.Layout, keys uikit.KeyMatcher) (Model, uikit.Event, tea.Cmd)
Update handles the notification messages in the root's precedence order: the popup dismiss timer, the release trailing a popup click, the popup click itself (which opens the history or detail overlay), and the open overlays, which swallow every input while visible. Messages the component does not own pass through unchanged; root routes them only when Consumes reports them.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is a scoped notification-history database. It owns the SQLite connection and applies the configured retention window when reading or appending entries.
func Open ¶
Open opens (creating and migrating if needed) the notification database at path. retentionDays is the resolved history window applied on each prune.