feat: improve usability with clickable keyboard hints
This allows people to use the app even if they aren't used to their keyboard. Closes #186
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { create } from "zustand";
|
||||
|
||||
/**
|
||||
* Fire-and-forget intents that drive the compose flow from outside the active
|
||||
* ComposeOverlay (e.g. clickable keyboard hints in the bottom controls or in
|
||||
* the recording overlay). The active overlay subscribes to `intent`, runs the
|
||||
* step-aware handler, then calls `clear()`.
|
||||
*
|
||||
* | intent | valid step | effect |
|
||||
* |--------|-----------------|--------------------------------------------|
|
||||
* | record | idle | start a media (camera/mic) recording |
|
||||
* | text | idle | open the text compose step |
|
||||
* | stop | recording | finish recording → review |
|
||||
* | cancel | recording, etc. | abort recording / discard review |
|
||||
* | send | reviewing | submit the recorded particle |
|
||||
*
|
||||
* Keyboard handlers stay local to ComposeOverlay (no round-trip), but they
|
||||
* ultimately invoke the same callbacks the intent dispatcher does, so the
|
||||
* guard logic stays in one place.
|
||||
*/
|
||||
export type ComposeIntent = "record" | "text" | "stop" | "cancel" | "send";
|
||||
|
||||
interface ComposeIntentState {
|
||||
intent: { kind: ComposeIntent } | null;
|
||||
request: (kind: ComposeIntent) => void;
|
||||
clear: () => void;
|
||||
}
|
||||
|
||||
export const useComposeIntentStore = create<ComposeIntentState>((set) => ({
|
||||
intent: null,
|
||||
// New object each call — ensures useEffect refires for repeated same kind.
|
||||
request: (kind) => set({ intent: { kind } }),
|
||||
clear: () => set({ intent: null }),
|
||||
}));
|
||||
Reference in New Issue
Block a user