Subscriptions
NAME
App::Moneymoor::Screen::Main::Subscriptions - the store-subscription wiring for the Main shell, extracted so the screen class stays a shell rather than a wiring loom.
SYNOPSIS
use App::Moneymoor::Screen::Main::Subscriptions;
App::Moneymoor::Screen::Main::Subscriptions::install-banner($main);
App::Moneymoor::Screen::Main::Subscriptions::install-footer($main);
App::Moneymoor::Screen::Main::Subscriptions::install-content($main);
# Pure, and so directly testable:
hint-for-focus($main, $some-widget); # 'register'
DESCRIPTION
Three install subs, each owning one subscription channel, plus the pure function they resolve the footer's value with.
install-bannerโ the banner line and the terminal title. Registered once; the banner outlives every tab change.install-footerโ the hint footer's context, driven by focus and by the active tab. Registered once.install-contentโ whatever the current tab's panes need. Re-run by!refresh-content-layoutafter the panes are rebuilt, because the widgets the subscriptions are anchored to are new objects each time.refresh-footerโ re-resolve the footer's context right now, for the moment after a tab swap when the widget the context was describing has just been destroyed.
The selector rule
Every selector here returns a plain scalar โ a Str, an Int.
Selkie::Store compares subscription values by content digest and
keys objects by identity, so a selector that built a Style, a
Span or a model object would read as changed on every tick and
re-push its widget every frame. Widgets and styles are built in the
callback; the selector's job is to answer "has anything I care
about moved?" in a form that digests stably.
The banner is the clearest case: the selector composes the whole string, and the callback does nothing but hand it to two setters.
Why the clock is not here
App::Moneymoor::Widget::BannerBar carries a right-aligned HH:MM
that never touches the store. It is widget-local state nothing else
reads, and a store dispatch on a fixed period is exactly the
metronomic pattern the idle render ladder exists to avoid. The frame
callback caches the formatted minute and marks the banner dirty only
when the string moves, so 59 seconds out of 60 cost a string compare.
EXPORTS
hint-for-focus($main, $focused --Str)> โ a focused widget โ aApp::Moneymoor::View::HintBarcontext key.
The three install-* subs and refresh-footer are our subs
called by fully-qualified name from Screen::Main; the module name is
the namespace boundary.
SEE ALSO
App::Moneymoor::Screen::Main โ the accessors these read.
App::Moneymoor::Util::Period โ
label, which turns theapp/periodkey into the caption the banner shows.App::Moneymoor::View::HintBar โ the context table.