1import type { EnvironmentThreadShell } from "@t3tools/client-runtime/state/shell";
2import { THREAD_JUMP_KEYBINDING_COMMANDS } from "@t3tools/contracts";
3import { useCallback } from "react";
4
5import type { ThreadListV2ListItem } from "../threads/threadListV2";
6import {
7 useHardwareKeyboardCommand,
8 type HardwareKeyboardCommand,
9} from "./hardwareKeyboardCommands";
10
11type ThreadShortcutListItem = ThreadListV2ListItem | { readonly type: "v2-show-more" };
12
13export function threadJumpIndex(command: HardwareKeyboardCommand) {
14 return THREAD_JUMP_KEYBINDING_COMMANDS.findIndex((candidate) => candidate === command);
15}
16
17/** Uses the rendered list so filters and shelves keep their order. */
18export function threadJumpTarget(
19 items: ReadonlyArray<ThreadShortcutListItem>,
20 command: HardwareKeyboardCommand,
21) {
22 let index = threadJumpIndex(command);
23 if (index < 0) return null;
24 for (const item of items) {
25 const thread = item.type === "v2-thread" ? item.item.thread : null;
26 if (thread !== null && index-- === 0) return thread;
27 }
28 return null;
29}
30
31export function useThreadJumpShortcuts(
32 items: ReadonlyArray<ThreadShortcutListItem>,
33 onSelectThread: (thread: EnvironmentThreadShell) => void,
34) {
35 const jumpToThread = useCallback(
36 (command: HardwareKeyboardCommand) => {
37 const thread = threadJumpTarget(items, command);
38 if (thread !== null) onSelectThread(thread);
39 return true;
40 },
41 [items, onSelectThread],
42 );
43 useHardwareKeyboardCommand(THREAD_JUMP_KEYBINDING_COMMANDS, jumpToThread);
44}