feat(app): add keyboard shortcut to cycle themes
This commit is contained in:
@@ -14,7 +14,7 @@ import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
|
|||||||
import { PortalProvider } from "@gorhom/portal";
|
import { PortalProvider } from "@gorhom/portal";
|
||||||
import { VoiceProvider } from "@/contexts/voice-context";
|
import { VoiceProvider } from "@/contexts/voice-context";
|
||||||
import { useAppSettings } from "@/hooks/use-settings";
|
import { useAppSettings } from "@/hooks/use-settings";
|
||||||
import { THEME_TO_UNISTYLES } from "@/styles/theme";
|
import { THEME_TO_UNISTYLES, type ThemeName } from "@/styles/theme";
|
||||||
import { useFaviconStatus } from "@/hooks/use-favicon-status";
|
import { useFaviconStatus } from "@/hooks/use-favicon-status";
|
||||||
import { View, Text } from "react-native";
|
import { View, Text } from "react-native";
|
||||||
import { UnistylesRuntime, useUnistyles } from "react-native-unistyles";
|
import { UnistylesRuntime, useUnistyles } from "react-native-unistyles";
|
||||||
@@ -358,6 +358,8 @@ interface AppContainerProps {
|
|||||||
chromeEnabled?: boolean;
|
chromeEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const THEME_CYCLE_ORDER: ThemeName[] = ["dark", "zinc", "midnight", "claude", "ghostty", "light"];
|
||||||
|
|
||||||
function AppContainer({
|
function AppContainer({
|
||||||
children,
|
children,
|
||||||
selectedAgentId,
|
selectedAgentId,
|
||||||
@@ -365,6 +367,7 @@ function AppContainer({
|
|||||||
}: AppContainerProps) {
|
}: AppContainerProps) {
|
||||||
const { theme } = useUnistyles();
|
const { theme } = useUnistyles();
|
||||||
const daemons = useHosts();
|
const daemons = useHosts();
|
||||||
|
const { settings, updateSettings } = useAppSettings();
|
||||||
const toggleAgentList = usePanelStore((state) => state.toggleAgentList);
|
const toggleAgentList = usePanelStore((state) => state.toggleAgentList);
|
||||||
const toggleFileExplorer = usePanelStore((state) => state.toggleFileExplorer);
|
const toggleFileExplorer = usePanelStore((state) => state.toggleFileExplorer);
|
||||||
const toggleBothSidebars = usePanelStore((state) => state.toggleBothSidebars);
|
const toggleBothSidebars = usePanelStore((state) => state.toggleBothSidebars);
|
||||||
@@ -373,6 +376,12 @@ function AppContainer({
|
|||||||
const agentListOpen = usePanelStore((state) => state.desktop.agentListOpen);
|
const agentListOpen = usePanelStore((state) => state.desktop.agentListOpen);
|
||||||
const sidebarWidth = usePanelStore((state) => state.sidebarWidth);
|
const sidebarWidth = usePanelStore((state) => state.sidebarWidth);
|
||||||
|
|
||||||
|
const cycleTheme = useCallback(() => {
|
||||||
|
const currentIndex = THEME_CYCLE_ORDER.indexOf(settings.theme as ThemeName);
|
||||||
|
const nextIndex = (currentIndex + 1) % THEME_CYCLE_ORDER.length;
|
||||||
|
void updateSettings({ theme: THEME_CYCLE_ORDER[nextIndex]! });
|
||||||
|
}, [settings.theme, updateSettings]);
|
||||||
|
|
||||||
const isCompactLayout = useIsCompactFormFactor();
|
const isCompactLayout = useIsCompactFormFactor();
|
||||||
const chromeEnabled = chromeEnabledOverride ?? daemons.length > 0;
|
const chromeEnabled = chromeEnabledOverride ?? daemons.length > 0;
|
||||||
|
|
||||||
@@ -413,6 +422,7 @@ function AppContainer({
|
|||||||
toggleFileExplorer,
|
toggleFileExplorer,
|
||||||
toggleBothSidebars,
|
toggleBothSidebars,
|
||||||
toggleFocusMode,
|
toggleFocusMode,
|
||||||
|
cycleTheme,
|
||||||
});
|
});
|
||||||
|
|
||||||
const containerStyle = useMemo(
|
const containerStyle = useMemo(
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export function useKeyboardShortcuts({
|
|||||||
toggleFileExplorer,
|
toggleFileExplorer,
|
||||||
toggleBothSidebars,
|
toggleBothSidebars,
|
||||||
toggleFocusMode,
|
toggleFocusMode,
|
||||||
|
cycleTheme,
|
||||||
}: {
|
}: {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
isMobile: boolean;
|
isMobile: boolean;
|
||||||
@@ -43,6 +44,7 @@ export function useKeyboardShortcuts({
|
|||||||
toggleFileExplorer?: () => void;
|
toggleFileExplorer?: () => void;
|
||||||
toggleBothSidebars?: () => void;
|
toggleBothSidebars?: () => void;
|
||||||
toggleFocusMode?: () => void;
|
toggleFocusMode?: () => void;
|
||||||
|
cycleTheme?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const hosts = useHosts();
|
const hosts = useHosts();
|
||||||
@@ -267,6 +269,11 @@ export function useKeyboardShortcuts({
|
|||||||
toggleFocusMode();
|
toggleFocusMode();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
case "theme.cycle":
|
||||||
|
if (cycleTheme) {
|
||||||
|
cycleTheme();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
case "command-center.toggle": {
|
case "command-center.toggle": {
|
||||||
const store = useKeyboardShortcutsStore.getState();
|
const store = useKeyboardShortcutsStore.getState();
|
||||||
if (!store.commandCenterOpen) {
|
if (!store.commandCenterOpen) {
|
||||||
@@ -413,6 +420,7 @@ export function useKeyboardShortcuts({
|
|||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
bindings,
|
bindings,
|
||||||
|
cycleTheme,
|
||||||
enabled,
|
enabled,
|
||||||
isMobile,
|
isMobile,
|
||||||
openProjectPickerAction,
|
openProjectPickerAction,
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ export type KeyboardActionId =
|
|||||||
| "worktree.new"
|
| "worktree.new"
|
||||||
| "worktree.archive"
|
| "worktree.archive"
|
||||||
| "view.toggle.focus"
|
| "view.toggle.focus"
|
||||||
|
| "theme.cycle"
|
||||||
| "message-input.action";
|
| "message-input.action";
|
||||||
|
|
||||||
export type KeyboardShortcutPayload =
|
export type KeyboardShortcutPayload =
|
||||||
|
|||||||
@@ -744,6 +744,32 @@ const SHORTCUT_BINDINGS: readonly ShortcutBinding[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// --- Theme cycling ---
|
||||||
|
{
|
||||||
|
id: "theme-cycle-cmd-shift-t-mac",
|
||||||
|
action: "theme.cycle",
|
||||||
|
combo: "Cmd+Alt+T",
|
||||||
|
when: { mac: true, commandCenter: false },
|
||||||
|
help: {
|
||||||
|
id: "cycle-theme",
|
||||||
|
section: "panels",
|
||||||
|
label: "Cycle theme",
|
||||||
|
keys: ["mod", "alt", "T"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "theme-cycle-ctrl-alt-t-non-mac",
|
||||||
|
action: "theme.cycle",
|
||||||
|
combo: "Ctrl+Alt+T",
|
||||||
|
when: { mac: false, commandCenter: false, terminal: false },
|
||||||
|
help: {
|
||||||
|
id: "cycle-theme",
|
||||||
|
section: "panels",
|
||||||
|
label: "Cycle theme",
|
||||||
|
keys: ["mod", "alt", "T"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
// --- Message input ---
|
// --- Message input ---
|
||||||
{
|
{
|
||||||
id: "message-input-voice-toggle-cmd-shift-d-mac",
|
id: "message-input-voice-toggle-cmd-shift-d-mac",
|
||||||
|
|||||||
Reference in New Issue
Block a user