1import type { EnvironmentId, PullRequestLinkedThreadsResult } from "@t3tools/contracts";
2
3import { dispatchCommandPalette, isCommandPaletteMounted } from "./commandPaletteStore";
4
5export interface CommandPaletteLinkedThreads {
6 readonly environmentId: EnvironmentId;
7 readonly threads: PullRequestLinkedThreadsResult["threads"];
8}
9
10export interface CommandPaletteOpenDetail {
11 readonly open?: "add-project" | "new-thread-in";
12 readonly query?: string;
13 readonly linkedThreads?: CommandPaletteLinkedThreads;
14}
15
16export function openCommandPalette(detail: CommandPaletteOpenDetail = {}): void {
17 // With no palette on screen (e.g. /pair) the request is dropped; kept in the
18 // store, it would pop a stale palette once the app shell mounts.
19 if (!isCommandPaletteMounted()) return;
20 if (detail.open === "new-thread-in") {
21 dispatchCommandPalette({ _tag: "OpenNewThreadIn" });
22 } else if (detail.open === "add-project") {
23 dispatchCommandPalette({ _tag: "OpenAddProject" });
24 } else if (detail.query !== undefined) {
25 dispatchCommandPalette({
26 _tag: "OpenSearch",
27 query: detail.query,
28 ...(detail.linkedThreads ? { linkedThreads: detail.linkedThreads } : {}),
29 });
30 } else {
31 dispatchCommandPalette({ _tag: "SetOpen", open: true });
32 }
33}
34
35/** True while the palette popup is on screen, including its closing animation. */
36export function isCommandPaletteOpen(): boolean {
37 return (
38 typeof document !== "undefined" && document.querySelector("[data-command-palette]") !== null
39 );
40}