Action Manager
The action classes are an opt-in scaffold for routing product intents such as
display, play, and content focus through one application service. Hosanna does
not register a default actionManager, and the base handler methods contain no
navigation, playback, or analytics behavior.
Use this layer only when your app supplies and registers a concrete manager.
Register a manager
export class AppActionManager extends ActionManager<BaseActionType> {
override handleDisplayAction() {
const item = this.action?.payload?.item as CatalogueItem | undefined;
const origin = this.action?.payload?.origin as BaseView | undefined;
const nav = origin?.getNavController();
if (!item || !nav) {
this.action?.setState(ActionState.Failed);
this.action?.setFinishState(ActionState.Failed);
return;
}
nav.push(DetailsScreen({ item }));
this.action?.setState(ActionState.Completed);
}
}
export class App extends BaseApp {
protected override getCustomIOCServices(): IOCServiceMap {
return [
{ key: 'actionManager', clazz: AppActionManager },
];
}
}
BaseView.dispatchAction() requires that registration. It creates an
HsAction, adds the dispatching view as payload.origin when a payload exists,
and passes the action to the manager:
const action = this.dispatchAction({
actionType: BaseActionType.Display,
payload: { item },
});
If payload is omitted, no origin object is created automatically. Include a
payload whenever the manager needs the source view.
Built-in action types
BaseActionType contains:
NoneDisplayDisplayAndPlayPlayPlayLiveContentFocusInContentBlurContentClick
The base manager routes these to overridable handler methods.
DisplayAndPlay currently calls handleDisplayAction(); implement any
follow-on play behavior in your subclass.
For a custom action-type union or enum, override manageAction() so the manager
can route those values. The base switch marks unknown types as Error.
Action lifecycle
HsAction extends HsObservable and publishes two fields:
| Field | Purpose |
|---|---|
state | Immediate handling result. |
finishState | Optional later outcome, such as playback completion. |
Both start at ActionState.Pending. Other values are Completed, Failed,
and Error.
action.setState(ActionState.Completed);
// Later, when the launched experience ends:
action.setFinishState(ActionState.Completed);
setState() and setFinishState() only change a field while that field is
still Pending. Repeated terminal updates are ignored.
ActionManager.cancelPendingAction() currently logs a pending action but does
not change its state or cancel underlying work. Override it if a new action
must supersede or cancel an older one.
Likewise, base handler methods are empty. A true result from
handleAction() means the base routing path ran; it does not prove that a
screen opened, playback started, analytics fired, or a pending action reached a
terminal state. Your subclass owns those guarantees.