feat: add global keyboard shortcuts for navigation and panels
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect, useCallback } from "react";
|
||||||
import { Outlet, Link, useLocation } from "react-router-dom";
|
import { Outlet, Link, useLocation, useNavigate } from "react-router-dom";
|
||||||
import { Terminal } from "../components/terminal/Terminal";
|
import { Terminal } from "../components/terminal/Terminal";
|
||||||
import { useWebSocket } from "../hooks/useWebSocket";
|
import { useWebSocket } from "../hooks/useWebSocket";
|
||||||
import { useTheme } from "../hooks/useTheme";
|
import { useTheme } from "../hooks/useTheme";
|
||||||
@@ -18,6 +18,7 @@ export function IDELayout({ sidebar }: { sidebar?: React.ReactNode }) {
|
|||||||
const [upstreamBehind, setUpstreamBehind] = useState(0);
|
const [upstreamBehind, setUpstreamBehind] = useState(0);
|
||||||
const [pendingToolset, setPendingToolset] = useState(0);
|
const [pendingToolset, setPendingToolset] = useState(0);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
const { subscribe } = useWebSocket();
|
const { subscribe } = useWebSocket();
|
||||||
const { theme, toggleTheme } = useTheme();
|
const { theme, toggleTheme } = useTheme();
|
||||||
|
|
||||||
@@ -45,6 +46,38 @@ export function IDELayout({ sidebar }: { sidebar?: React.ReactNode }) {
|
|||||||
if (location.pathname === "/toolset") setPendingToolset(0);
|
if (location.pathname === "/toolset") setPendingToolset(0);
|
||||||
}, [location.pathname]);
|
}, [location.pathname]);
|
||||||
|
|
||||||
|
const handleKeyDown = useCallback(
|
||||||
|
(e: KeyboardEvent) => {
|
||||||
|
const tag = (e.target as HTMLElement)?.tagName;
|
||||||
|
if (tag === "INPUT" || tag === "TEXTAREA" || (e.target as HTMLElement)?.closest?.(".monaco-editor")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.ctrlKey && e.shiftKey && e.key === "B") {
|
||||||
|
e.preventDefault();
|
||||||
|
navigate("/build");
|
||||||
|
} else if (e.ctrlKey && e.key === "`") {
|
||||||
|
e.preventDefault();
|
||||||
|
setTerminalOpen((v) => !v);
|
||||||
|
} else if (e.ctrlKey && e.shiftKey && e.key === "F") {
|
||||||
|
e.preventDefault();
|
||||||
|
navigate("/editor");
|
||||||
|
} else if (e.ctrlKey && e.shiftKey && e.key === "G") {
|
||||||
|
e.preventDefault();
|
||||||
|
navigate("/repos");
|
||||||
|
} else if (e.ctrlKey && e.key === ",") {
|
||||||
|
e.preventDefault();
|
||||||
|
navigate("/settings");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[navigate],
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("keydown", handleKeyDown);
|
||||||
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||||
|
}, [handleKeyDown]);
|
||||||
|
|
||||||
const getBadge = (path: string): number => {
|
const getBadge = (path: string): number => {
|
||||||
if (path === "/repos") return upstreamBehind;
|
if (path === "/repos") return upstreamBehind;
|
||||||
if (path === "/toolset") return pendingToolset;
|
if (path === "/toolset") return pendingToolset;
|
||||||
|
|||||||
Reference in New Issue
Block a user