layerman 0.2.0
layerman: ^0.2.0 copied to clipboard
Headless overlay queue orchestrator: serial one-at-a-time queueing with priority, replace, overlap, conditions, cooldown and two-phase close; renders through any UI backend (showDialog / GetX / bot_to [...]
0.2.0 #
Breaking — the manager is now headless (UI-agnostic). The self-rendering
builder: path is gone; present: is the sole rendering hook. The core no
longer owns an Overlay, imports no package:flutter/widgets.dart, and mirrors
the headless TS sister package.
Why: the whole point is an orchestrator that doesn't care what renders. As long
as builder: existed, the manager had to own an Overlay layer and be attached
to an OverlayState — that is a UI responsibility, and it contradicted the
goal. The present:/PresentedOverlay handle model is a strict superset: a
backend that owns its own OverlayEntry covers everything builder: did, so
nothing is lost. See the README's "Why there is no builder:" section for the
migration recipe.
Renamed (to match the package name)
OverlayManager→Layerman;OverlayNavigatorObserver→LayermanNavigatorObserver.- Everything else keeps its
Overlay*name on purpose —OverlayPredicate,OverlayCooldown,OverlayCooldownStorage,OverlayRecord,PresentedOverlaydescribe the overlay being managed, not the manager itself, so renaming those toLayerman*would misdescribe what they are (e.g.PresentedOverlayis "the overlay that got presented", not "a presented orchestrator").
Removed
open(builder: ...)and theOverlayContentBuildertypedef — useopen(present: ...).OverlayManagerScope,Layerman.attach/detach/isAttached— the manager attaches to nothing now.OverlayHandle,OverlayPhase, and the handle'sphase/phaseListenable/isClosing—open()returns itsFuture<T?>directly; a backend drives its own exit animation and reports completion viaPresentedOverlay.dismissed.barrierColor/barrierDismissibleonopen()— the backend renders its own barrier.Layerman(exitDuration:)constructor default —exitDurationis now a per-open()grace only (null ⇒ advance immediately).
Behavior
replacenow always closes the preempted overlay (resultnull); it is never sent back to the queue to re-show. A dismissed backend can't be faithfully re-presented (that would re-run its side effects), so the old self-rendered "displace + resume" semantics no longer applied and were dropped along with theirwasDisplaced/replaceBandmachinery.
Unchanged: slots, priority, affix, overlap, conditions (when / route
/ requiresAuth / setContext / dismissWhenUnmet), cooldown (+ pluggable
storage), resolve, beforeClose, duration, delay, gap, pauseAll /
resumeAll / pause / resume, update, clearWhere, LayermanNavigatorObserver,
currentRoute, pauseOnRoutes.
0.1.1 #
Docs only — no code changes.
- README now links the live interactive demo.
0.1.0 #
OverlayNavigatorObserver— aNavigatorObserverthat feeds real navigation intosetContext'sroutekey automatically (deferred to a post-frame callback, safe even if navigation happens mid-build). Works under vanillaNavigator, GetX and go_router alike; purely observational, never touches navigation itself. Removes the need to callsetContext({'route': ...})by hand in every page's lifecycle.OverlayManager.currentRoute— reads the trackedroutecontext value back, so hosts don't need to maintain their own route mirror.OverlayManager({pauseOnRoutes: [...]})— declares "no-overlay zone" route patterns: entering a match freezes the whole queue (likepauseAll), leaving resumes it (likeresumeAll). Composes correctly with manualpauseAll/resumeAll— neither one overrides the other; the queue only actually thaws once both are clear.- README: new "Auto route awareness" section and a "navigated page as a queue
entry" recipe (wrapping
Navigator.pushinpresent:— a page route is just another external presenter, nobuilder:needed).
0.0.1 #
Initial public release.
A Flutter-native overlay queue manager that renders real OverlayEntrys and
can also orchestrate overlays rendered by other libraries (showDialog, GetX,
bot_toast, fluttertoast, …).
Core
OverlayManager— serial one-at-a-time queueing per namedslot, with an optionalgap;open<T>()returns aFuture<T?>(likeshowDialog).- Ordering:
priority(desc, FIFO ties),replace(preempt the current overlay — which is sent back to the queue and re-shows after the replacer closes; front-bands ahead of queued entries; skips a pending gap),affix(protect the current overlay fromreplace),overlap(bypass the queue and stack immediately, now-or-never). - Two-phase close (
OverlayPhase.open→closing→ removed) for exit animations, driven byOverlayHandle.phaseListenable. - Per-overlay
delay/duration(auto-close) and an optional modal barrier (barrierColor/barrierDismissible).
Conditions & cooldown
- Conditions:
when(ctx)predicate (sole authority),route(String/List/RegExp) +requiresAuthsugar,setContext({...})push-model re-evaluation, anddismissWhenUnmet(default true) auto-dismissal. - Cooldown:
OverlayCooldown(session/total/day/hour/minute/minGap)— AND semantics, counts on real open, local calendar buckets, rollingminGap; persisted via a pluggableOverlayCooldownStorage(defaultMemoryCooldownStorage);ready()awaits hydration; injectablenow. A time-based cap (minGap/ bucket rollover) auto-shows the queued entry the moment it expires.
Lifecycle & data
- Backend-driven
resolve(fetch payload only when granted;nullskips without counting cooldown; slot committed while resolving). beforeCloseguard (sync/async;falseor throw vetoesclose;remove/clearbypass it).pauseAll/resumeAllfull freeze and per-idpause/resume.update(id, patch)(shallow-merge + rebuild) andclearWhere(test)(selective mass removal overOverlayRecords).- Introspection:
activeIds,queuedIds,isShowing,isPaused,isAttached;OverlayManageris aChangeNotifier.
Rendering & orchestration
OverlayManagerScope— a dedicatedOverlaylayer above your app (independent of theNavigator), withof/maybeOfand automatic re-attach when the manager is swapped. Orattach/detachan ambientOverlayyourself.- External presenter:
open(present: ...)withPresent/PresentContext/PresentedOverlay— one queue overshowDialog/ GetX (dialog + snackbar) /bot_toast/fluttertoast. README has copy-paste recipes and the orchestration rules of engagement.
Zero third-party runtime dependencies.