Skip to content

Commit 46d3687

Browse files
charlesvienjonathanlab
authored andcommitted
Implement the ability to quickly switch between tasks with CMD+0-9 keyboard shortcut
1 parent 5d4a514 commit 46d3687

2 files changed

Lines changed: 62 additions & 3 deletions

File tree

apps/twig/src/renderer/components/GlobalEventHandlers.tsx

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { usePanelLayoutStore } from "@features/panels/store/panelLayoutStore";
22
import { useRightSidebarStore } from "@features/right-sidebar";
3+
import { usePinnedTasksStore } from "@features/sidebar/stores/pinnedTasksStore";
34
import { useSidebarStore } from "@features/sidebar/stores/sidebarStore";
5+
import { useTasks } from "@features/tasks/hooks/useTasks";
46
import { useWorkspaceStore } from "@features/workspace/stores/workspaceStore";
57
import { SHORTCUTS } from "@renderer/constants/keyboard-shortcuts";
68
import { clearApplicationStorage } from "@renderer/lib/clearStorage";
79
import { useRegisteredFoldersStore } from "@renderer/stores/registeredFoldersStore";
10+
import type { Task } from "@shared/types";
811
import { useNavigationStore } from "@stores/navigationStore";
9-
import { useCallback, useEffect } from "react";
12+
import { useCallback, useEffect, useMemo } from "react";
1013
import { useHotkeys } from "react-hotkeys-hook";
1114
import { trpcReact } from "@/renderer/trpc";
1215

@@ -25,6 +28,7 @@ export function GlobalEventHandlers({
2528
const navigateToTaskInput = useNavigationStore(
2629
(state) => state.navigateToTaskInput,
2730
);
31+
const navigateToTask = useNavigationStore((state) => state.navigateToTask);
2832
const navigateToFolderSettings = useNavigationStore(
2933
(state) => state.navigateToFolderSettings,
3034
);
@@ -37,6 +41,40 @@ export function GlobalEventHandlers({
3741
const toggleLeftSidebar = useSidebarStore((state) => state.toggle);
3842
const toggleRightSidebar = useRightSidebarStore((state) => state.toggle);
3943

44+
const { data: allTasks = [] } = useTasks();
45+
const pinnedTaskIds = usePinnedTasksStore((state) => state.pinnedTaskIds);
46+
47+
// Build ordered task list for CMD+0-9 switching (pinned → active → recent)
48+
const orderedTasks = useMemo((): Task[] => {
49+
if (allTasks.length === 0) return [];
50+
51+
const sortedByActivity = [...allTasks].sort(
52+
(a, b) =>
53+
new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime(),
54+
);
55+
56+
const pinned = sortedByActivity.filter((t) => pinnedTaskIds.has(t.id));
57+
const unpinned = sortedByActivity.filter((t) => !pinnedTaskIds.has(t.id));
58+
59+
return [...pinned, ...unpinned];
60+
}, [allTasks, pinnedTaskIds]);
61+
62+
const handleSwitchTask = useCallback(
63+
(index: number) => {
64+
if (index === 0) {
65+
// mod+0 goes to home/task input
66+
navigateToTaskInput();
67+
} else {
68+
// mod+1-9 switches to task at that index (1-based)
69+
const task = orderedTasks[index - 1];
70+
if (task) {
71+
navigateToTask(task);
72+
}
73+
}
74+
},
75+
[orderedTasks, navigateToTask, navigateToTaskInput],
76+
);
77+
4078
const handleOpenSettings = useCallback(() => {
4179
toggleSettings();
4280
}, [toggleSettings]);
@@ -91,6 +129,19 @@ export function GlobalEventHandlers({
91129
useHotkeys(SHORTCUTS.TOGGLE_RIGHT_SIDEBAR, toggleRightSidebar, globalOptions);
92130
useHotkeys(SHORTCUTS.SHORTCUTS_SHEET, onToggleShortcutsSheet, globalOptions);
93131

132+
// Task switching with mod+0-9
133+
useHotkeys(
134+
SHORTCUTS.SWITCH_TASK,
135+
(_event, handler) => {
136+
const keyPressed = handler.keys?.[0];
137+
if (!keyPressed) return;
138+
const index = parseInt(keyPressed, 10);
139+
handleSwitchTask(index);
140+
},
141+
globalOptions,
142+
[handleSwitchTask],
143+
);
144+
94145
// Mouse back/forward buttons
95146
useEffect(() => {
96147
const handleMouseButton = (event: MouseEvent) => {

apps/twig/src/renderer/constants/keyboard-shortcuts.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ export const SHORTCUTS = {
88
TOGGLE_LEFT_SIDEBAR: "mod+b",
99
TOGGLE_RIGHT_SIDEBAR: "mod+shift+b",
1010
CLOSE_TAB: "mod+w",
11-
SWITCH_TAB: "mod+1,mod+2,mod+3,mod+4,mod+5,mod+6,mod+7,mod+8,mod+9",
11+
SWITCH_TAB:
12+
"mod+shift+1,mod+shift+2,mod+shift+3,mod+shift+4,mod+shift+5,mod+shift+6,mod+shift+7,mod+shift+8,mod+shift+9",
13+
SWITCH_TASK: "mod+0,mod+1,mod+2,mod+3,mod+4,mod+5,mod+6,mod+7,mod+8,mod+9",
1214
OPEN_IN_EDITOR: "mod+o",
1315
COPY_PATH: "mod+shift+c",
1416
TASK_REFRESH: "mod+r",
@@ -57,6 +59,12 @@ export const KEYBOARD_SHORTCUTS: KeyboardShortcut[] = [
5759
description: "Show keyboard shortcuts",
5860
category: "general",
5961
},
62+
{
63+
id: "switch-task",
64+
keys: "mod+0-9",
65+
description: "Switch to task 1-9 (0 = home)",
66+
category: "navigation",
67+
},
6068
{
6169
id: "go-back",
6270
keys: SHORTCUTS.GO_BACK,
@@ -83,7 +91,7 @@ export const KEYBOARD_SHORTCUTS: KeyboardShortcut[] = [
8391
},
8492
{
8593
id: "switch-tab",
86-
keys: "mod+1-9",
94+
keys: "mod+shift+1-9",
8795
description: "Switch to tab 1-9",
8896
category: "panels",
8997
context: "Task detail",

0 commit comments

Comments
 (0)