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-layout after 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 โ†’ a App::Moneymoor::View::HintBar context 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 v0.4.2

YNAB-style envelope budgeting: a derivation engine

Authors

  • Matt Doughty

License

Artistic-2.0

Dependencies

DBIish:ver<0.6.7>:auth<zef:raku-community-modules>Notcurses::Native:ver<0.6.5+>:auth<zef:apogee>Selkie:ver<0.16.0+>:auth<zef:apogee>JSON::Fast:ver<0.19>:auth<cpan:TIMOTIMO>MacOS::NativeLib:ver<0.0.6>:auth<zef:lizmat>

Test Dependencies

Provides

  • App::Moneymoor
  • App::Moneymoor::Config
  • App::Moneymoor::DB
  • App::Moneymoor::Gateway::Account
  • App::Moneymoor::Gateway::Assignment
  • App::Moneymoor::Gateway::Category
  • App::Moneymoor::Gateway::Payee
  • App::Moneymoor::Gateway::Transaction
  • App::Moneymoor::Handlers::Boot
  • App::Moneymoor::Model::Account
  • App::Moneymoor::Model::Assignment
  • App::Moneymoor::Model::Category
  • App::Moneymoor::Model::CategoryGroup
  • App::Moneymoor::Model::Payee
  • App::Moneymoor::Model::Split
  • App::Moneymoor::Model::Transaction
  • App::Moneymoor::Screen::Accounts
  • App::Moneymoor::Screen::Budget
  • App::Moneymoor::Screen::Login
  • App::Moneymoor::Screen::Main
  • App::Moneymoor::Screen::Main::Keybinds
  • App::Moneymoor::Screen::Main::Modals
  • App::Moneymoor::Screen::Main::Subscriptions
  • App::Moneymoor::Screen::Reports
  • App::Moneymoor::Service::Budget
  • App::Moneymoor::Service::Icons
  • App::Moneymoor::Service::Target
  • App::Moneymoor::Service::Workspace
  • App::Moneymoor::StoreHandlers
  • App::Moneymoor::Theme
  • App::Moneymoor::Theme::Catppuccin
  • App::Moneymoor::Theme::Dracula
  • App::Moneymoor::Theme::Everforest
  • App::Moneymoor::Theme::Gruvbox
  • App::Moneymoor::Theme::Kanagawa
  • App::Moneymoor::Theme::Monokai
  • App::Moneymoor::Theme::Nord
  • App::Moneymoor::Theme::OneDark
  • App::Moneymoor::Theme::RosePine
  • App::Moneymoor::Theme::Solarized
  • App::Moneymoor::Theme::TokyoNight
  • App::Moneymoor::Themes
  • App::Moneymoor::UI
  • App::Moneymoor::Util::Money
  • App::Moneymoor::Util::Period
  • App::Moneymoor::View::BudgetRow
  • App::Moneymoor::View::EmptyState
  • App::Moneymoor::View::HintBar
  • App::Moneymoor::View::InspectorPane
  • App::Moneymoor::View::ModalChrome
  • App::Moneymoor::View::RegisterRow
  • App::Moneymoor::View::ReportRow
  • App::Moneymoor::Widget::BannerBar
  • App::Moneymoor::Widget::BootProgressModal

The Camelia image is copyright 2009 by Larry Wall. "Raku" is a trademark of the Yet Another Society. All rights reserved.

Built with Podlite โ€” the markup and publishing tools behind this site.