Skip to content

Commit c888881

Browse files
committed
Refactor agent service
1 parent db6bb9b commit c888881

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

apps/array/src/main/services/ui/schemas.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { z } from "zod";
2+
13
// UI events emitted from main to renderer
24
export const UIServiceEvent = {
35
OpenSettings: "open-settings",
@@ -12,3 +14,6 @@ export interface UIServiceEvents {
1214
[UIServiceEvent.ResetLayout]: undefined;
1315
[UIServiceEvent.ClearStorage]: undefined;
1416
}
17+
18+
// No input needed for subscriptions - they're global events
19+
export const uiEventSubscriptionInput = z.object({}).optional();

apps/array/src/main/services/ui/service.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,30 @@ import { UIServiceEvent, type UIServiceEvents } from "./schemas.js";
88
*/
99
@injectable()
1010
export class UIService extends TypedEventEmitter<UIServiceEvents> {
11+
/**
12+
* Emit an event to open the settings panel
13+
*/
1114
openSettings(): void {
1215
this.emit(UIServiceEvent.OpenSettings, undefined);
1316
}
1417

18+
/**
19+
* Emit an event to create a new task
20+
*/
1521
newTask(): void {
1622
this.emit(UIServiceEvent.NewTask, undefined);
1723
}
1824

25+
/**
26+
* Emit an event to reset the layout
27+
*/
1928
resetLayout(): void {
2029
this.emit(UIServiceEvent.ResetLayout, undefined);
2130
}
2231

32+
/**
33+
* Emit an event to clear storage
34+
*/
2335
clearStorage(): void {
2436
this.emit(UIServiceEvent.ClearStorage, undefined);
2537
}

apps/array/src/renderer/components/MainLayout.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Box, Flex } from "@radix-ui/themes";
1212
import { useNavigationStore } from "@stores/navigationStore";
1313
import { useCallback, useState } from "react";
1414
import { Toaster } from "sonner";
15+
import { trpcReact } from "@/renderer/trpc";
1516
import { useTaskDeepLink } from "../hooks/useTaskDeepLink";
1617
import { GlobalEventHandlers } from "./GlobalEventHandlers";
1718

@@ -27,6 +28,58 @@ export function MainLayout() {
2728
setCommandMenuOpen((prev) => !prev);
2829
}, []);
2930

31+
useHotkeys("mod+k", () => setCommandMenuOpen((prev) => !prev), {
32+
enabled: !commandMenuOpen,
33+
});
34+
useHotkeys("mod+t", () => setCommandMenuOpen((prev) => !prev), {
35+
enabled: !commandMenuOpen,
36+
});
37+
useHotkeys("mod+p", () => setCommandMenuOpen((prev) => !prev), {
38+
enabled: !commandMenuOpen,
39+
});
40+
useHotkeys("mod+n", () => handleFocusTaskMode());
41+
useHotkeys("mod+,", () => handleOpenSettings());
42+
useHotkeys("mod+[", () => goBack());
43+
useHotkeys("mod+]", () => goForward());
44+
useHotkeys("mod+b", () => toggleLeftSidebar());
45+
useHotkeys("mod+shift+b", () => toggleRightSidebar());
46+
47+
// Subscribe to UI events from main process via tRPC
48+
trpcReact.ui.onOpenSettings.useSubscription(undefined, {
49+
onData: () => handleOpenSettings(),
50+
});
51+
52+
trpcReact.ui.onNewTask.useSubscription(undefined, {
53+
onData: () => handleFocusTaskMode(),
54+
});
55+
56+
trpcReact.ui.onResetLayout.useSubscription(undefined, {
57+
onData: () => handleResetLayout(),
58+
});
59+
60+
trpcReact.ui.onClearStorage.useSubscription(undefined, {
61+
onData: () => handleClearStorage(),
62+
});
63+
64+
useEffect(() => {
65+
const handleMouseButton = (event: MouseEvent) => {
66+
if (event.button === 3) {
67+
// Button 3 = back
68+
event.preventDefault();
69+
goBack();
70+
} else if (event.button === 4) {
71+
// Button 4 = forward
72+
event.preventDefault();
73+
goForward();
74+
}
75+
};
76+
77+
window.addEventListener("mouseup", handleMouseButton);
78+
return () => {
79+
window.removeEventListener("mouseup", handleMouseButton);
80+
};
81+
}, [goBack, goForward]);
82+
3083
return (
3184
<Flex direction="column" height="100vh">
3285
<HeaderRow />

0 commit comments

Comments
 (0)