1/**
2 * How a composer submission is delivered when the thread already has a turn in
3 * flight. Shared by web (where the alternate is Mod+Enter) and mobile (where it
4 * is a long-press on the send button), so both clients agree on what the user's
5 * configured follow-up behavior means.
6 */
7export type ComposerDispatchMode = "auto" | "queue" | "steer" | "restart";
8export type ActiveTurnComposerAction = Exclude<ComposerDispatchMode, "auto">;
9
10/** The alternate switches between queue and steer relative to the configured action. */
11export function resolveComposerDispatchMode(input: {
12 /** A turn is in flight, so the follow-up has to queue behind it or steer it. */
13 readonly running: boolean;
14 readonly alternateModifier: boolean;
15 readonly activeTurnDefault?: ActiveTurnComposerAction;
16}): ComposerDispatchMode {
17 if (!input.running) return "auto";
18 const defaultAction = input.activeTurnDefault ?? "steer";
19 if (input.alternateModifier) return defaultAction === "queue" ? "steer" : "queue";
20 return defaultAction;
21}
22
23/** What the alternate would do, for labelling the affordance that triggers it. */
24export function alternateComposerDispatchAction(
25 activeTurnDefault?: ActiveTurnComposerAction,
26): ActiveTurnComposerAction {
27 return resolveComposerDispatchMode({
28 running: true,
29 alternateModifier: true,
30 ...(activeTurnDefault === undefined ? {} : { activeTurnDefault }),
31 }) as ActiveTurnComposerAction;
32}