diff --git a/src/renderer/src/windows/mini/home/components/FeatureMenus.tsx b/src/renderer/src/windows/mini/home/components/FeatureMenus.tsx index 511310b8..b7746e23 100644 --- a/src/renderer/src/windows/mini/home/components/FeatureMenus.tsx +++ b/src/renderer/src/windows/mini/home/components/FeatureMenus.tsx @@ -1,7 +1,7 @@ import { BulbOutlined, FileTextOutlined, MessageOutlined, TranslationOutlined } from '@ant-design/icons' import Scrollbar from '@renderer/components/Scrollbar' import { Col } from 'antd' -import { Dispatch, FC, SetStateAction } from 'react' +import { Dispatch, FC, SetStateAction, useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' @@ -13,52 +13,78 @@ interface FeatureMenusProps { const FeatureMenus: FC = ({ text, setRoute, onSendMessage }) => { const { t } = useTranslation() + const [selectedIndex, setSelectedIndex] = useState(0) - const features = [ - { - icon: , - title: t('miniwindow.feature.chat'), - active: true, - onClick: () => { - if (text) { - setRoute('chat') - onSendMessage() + const features = useMemo( + () => [ + { + icon: , + title: t('miniwindow.feature.chat'), + active: true, + onClick: () => { + if (text) { + setRoute('chat') + onSendMessage() + } + } + }, + { + icon: , + title: t('miniwindow.feature.translate'), + onClick: () => text && setRoute('translate') + }, + { + icon: , + title: t('miniwindow.feature.summary'), + onClick: () => { + if (text) { + setRoute('summary') + onSendMessage(t('prompts.summarize')) + } + } + }, + { + icon: , + title: t('miniwindow.feature.explanation'), + onClick: () => { + if (text) { + setRoute('explanation') + onSendMessage(t('prompts.explanation')) + } } } - }, - { - icon: , - title: t('miniwindow.feature.translate'), - onClick: () => text && setRoute('translate') - }, - { - icon: , - title: t('miniwindow.feature.summary'), - onClick: () => { - if (text) { - setRoute('summary') - onSendMessage(t('prompts.summarize')) - } - } - }, - { - icon: , - title: t('miniwindow.feature.explanation'), - onClick: () => { - if (text) { - setRoute('explanation') - onSendMessage(t('prompts.explanation')) - } + ], + [onSendMessage, setRoute, t, text] + ) + + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + switch (e.key) { + case 'ArrowUp': + e.preventDefault() + setSelectedIndex((prev) => (prev > 0 ? prev - 1 : features.length - 1)) + break + case 'ArrowDown': + e.preventDefault() + setSelectedIndex((prev) => (prev < features.length - 1 ? prev + 1 : 0)) + break + case 'Enter': + e.preventDefault() + features[selectedIndex].onClick?.() + break } } - ] + + window.addEventListener('keydown', handleKeyDown) + return () => window.removeEventListener('keydown', handleKeyDown) + }, [features, selectedIndex]) return ( {features.map((feature, index) => ( - + {feature.icon} {feature.title}