Skip to content

Commit 88955e0

Browse files
authored
feat: ai assistant supports shortcuts (#414)
1 parent aee7df6 commit 88955e0

7 files changed

Lines changed: 57 additions & 9 deletions

File tree

src/components/Assistant/AssistantList.tsx

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { useClickAway } from "@/hooks/useClickAway";
99
import VisibleKey from "@/components/Common/VisibleKey";
1010
import { useConnectStore } from "@/stores/connectStore";
1111
import FontIcon from "@/components/Common/Icons/FontIcon";
12+
import { AI_ASSISTANT_PANEL_ID } from "@/constants";
13+
import { useShortcutsStore } from "@/stores/shortcutsStore";
1214

1315
interface AssistantListProps {
1416
showChatHistory?: boolean;
@@ -19,17 +21,20 @@ export function AssistantList({ showChatHistory = true }: AssistantListProps) {
1921
const isTauri = useAppStore((state) => state.isTauri);
2022
const currentService = useConnectStore((state) => state.currentService);
2123
const currentAssistant = useConnectStore((state) => state.currentAssistant);
22-
const setCurrentAssistant = useConnectStore((state) => state.setCurrentAssistant);
24+
const setCurrentAssistant = useConnectStore(
25+
(state) => state.setCurrentAssistant
26+
);
2327

2428
const [isOpen, setIsOpen] = useState(false);
2529
const [isRefreshing, setIsRefreshing] = useState(false);
26-
30+
const aiAssistant = useShortcutsStore((state) => {
31+
return state.aiAssistant;
32+
});
2733
const menuRef = useRef<HTMLDivElement>(null);
2834

2935
useClickAway(menuRef, () => setIsOpen(false));
3036
const [assistants, setAssistants] = useState<any[]>([]);
3137

32-
3338
const fetchAssistant = useCallback(async () => {
3439
if (!isTauri) return;
3540
if (!currentService?.id) return;
@@ -82,16 +87,27 @@ export function AssistantList({ showChatHistory = true }: AssistantListProps) {
8287
{currentAssistant?._source?.name || "Coco AI"}
8388
</div>
8489
{showChatHistory && isTauri && (
85-
<ChevronDownIcon
86-
className={`size-4 text-gray-500 dark:text-gray-400 transition-transform ${
87-
isOpen ? "rotate-180" : ""
88-
}`}
89-
/>
90+
<VisibleKey
91+
aria-controls={isOpen ? AI_ASSISTANT_PANEL_ID : ""}
92+
shortcut={aiAssistant}
93+
onKeyPress={() => {
94+
setIsOpen(!isOpen);
95+
}}
96+
>
97+
<ChevronDownIcon
98+
className={`size-4 text-gray-500 dark:text-gray-400 transition-transform ${
99+
isOpen ? "rotate-180" : ""
100+
}`}
101+
/>
102+
</VisibleKey>
90103
)}
91104
</button>
92105

93106
{showChatHistory && isTauri && isOpen && (
94-
<div className="absolute z-50 top-full mt-1 left-0 w-64 rounded-xl bg-white dark:bg-[#202126] p-2 text-sm/6 text-gray-800 dark:text-white shadow-lg border border-gray-200 dark:border-gray-700 focus:outline-none max-h-[calc(100vh-80px)] overflow-y-auto">
107+
<div
108+
id={isOpen ? AI_ASSISTANT_PANEL_ID : ""}
109+
className="absolute z-50 top-full mt-1 left-0 w-64 rounded-xl bg-white dark:bg-[#202126] p-2 text-sm/6 text-gray-800 dark:text-white shadow-lg border border-gray-200 dark:border-gray-700 focus:outline-none max-h-[calc(100vh-80px)] overflow-y-auto"
110+
>
95111
<div className="sticky top-0 mb-2 px-2 py-1 text-sm font-medium text-gray-900 dark:text-white bg-white dark:bg-[#202126] flex justify-between">
96112
<div>AI Assistant</div>
97113
<button

src/components/Settings/Advanced/components/Shortcuts/index.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ const Shortcuts = () => {
4343
const setHistoricalRecords = useShortcutsStore((state) => {
4444
return state.setHistoricalRecords;
4545
});
46+
const aiAssistant = useShortcutsStore((state) => {
47+
return state.aiAssistant;
48+
});
49+
const setAiAssistant = useShortcutsStore((state) => {
50+
return state.setAiAssistant;
51+
});
4652
const newSession = useShortcutsStore((state) => state.newSession);
4753
const setNewSession = useShortcutsStore((state) => state.setNewSession);
4854
const fixedWindow = useShortcutsStore((state) => state.fixedWindow);
@@ -110,6 +116,12 @@ const Shortcuts = () => {
110116
value: historicalRecords,
111117
setValue: setHistoricalRecords,
112118
},
119+
{
120+
title: "settings.advanced.shortcuts.aiAssistant.title",
121+
description: "settings.advanced.shortcuts.aiAssistant.description",
122+
value: aiAssistant,
123+
setValue: setAiAssistant,
124+
},
113125
{
114126
title: "settings.advanced.shortcuts.newSession.title",
115127
description: "settings.advanced.shortcuts.newSession.description",

src/constants/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ export const POPOVER_PANEL_SELECTOR = '[id^="headlessui-popover-panel"]';
33
export const HISTORY_PANEL_ID = "headlessui-popover-panel:history-panel";
44

55
export const CONTEXT_MENU_PANEL_ID = "headlessui-popover-panel:context-menu";
6+
7+
export const AI_ASSISTANT_PANEL_ID = "headlessui-popover-panel:ai-assistant";

src/hooks/useSyncStore.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ export const useSyncStore = () => {
4141
const setHistoricalRecords = useShortcutsStore((state) => {
4242
return state.setHistoricalRecords;
4343
});
44+
const setAiAssistant = useShortcutsStore((state) => {
45+
return state.setAiAssistant;
46+
});
4447
const setNewSession = useShortcutsStore((state) => {
4548
return state.setNewSession;
4649
});
@@ -90,6 +93,7 @@ export const useSyncStore = () => {
9093
internetSearch,
9194
internetSearchScope,
9295
historicalRecords,
96+
aiAssistant,
9397
newSession,
9498
fixedWindow,
9599
serviceList,
@@ -104,6 +108,7 @@ export const useSyncStore = () => {
104108
setInternetSearch(internetSearch);
105109
setInternetSearchScope(internetSearchScope);
106110
setHistoricalRecords(historicalRecords);
111+
setAiAssistant(aiAssistant);
107112
setNewSession(newSession);
108113
setFixedWindow(fixedWindow);
109114
setServiceList(serviceList);

src/locales/en/translation.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@
119119
"title": "Conversation History",
120120
"description": "Shortcut to view past conversation history in chat mode."
121121
},
122+
"aiAssistant": {
123+
"title": "AI Assistant",
124+
"description": "Shortcut to view AI assistant list in chat mode."
125+
},
122126
"newSession": {
123127
"title": "New Conversation",
124128
"description": "Shortcut to start a new conversation in chat mode."

src/locales/zh/translation.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@
119119
"title": "历史记录",
120120
"description": "在聊天模式下查看历史对话记录的快捷键。"
121121
},
122+
"aiAssistant": {
123+
"title": "AI 助手",
124+
"description": "在聊天模式下查看 AI 助手列表快捷键。"
125+
},
122126
"newSession": {
123127
"title": "新建会话",
124128
"description": "在聊天模式下创建新对话的快捷按键。"

src/stores/shortcutsStore.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ export type IShortcutsStore = {
2727
setInternetSearchScope: (internetSearchScope: string) => void;
2828
historicalRecords: string;
2929
setHistoricalRecords: (historicalRecords: string) => void;
30+
aiAssistant: string;
31+
setAiAssistant: (aiAssistant: string) => void;
3032
newSession: string;
3133
setNewSession: (newSession: string) => void;
3234
fixedWindow: string;
@@ -72,6 +74,8 @@ export const useShortcutsStore = create<IShortcutsStore>()(
7274
setHistoricalRecords: (historicalRecords) => {
7375
return set({ historicalRecords });
7476
},
77+
aiAssistant: "U",
78+
setAiAssistant: (aiAssistant) => set({ aiAssistant }),
7579
newSession: "N",
7680
setNewSession: (newSession) => set({ newSession }),
7781
fixedWindow: "P",
@@ -96,6 +100,7 @@ export const useShortcutsStore = create<IShortcutsStore>()(
96100
deepThinking: state.deepThinking,
97101
internetSearch: state.internetSearch,
98102
historicalRecords: state.historicalRecords,
103+
aiAssistant: state.aiAssistant,
99104
newSession: state.newSession,
100105
fixedWindow: state.fixedWindow,
101106
serviceList: state.serviceList,

0 commit comments

Comments
 (0)