feat(miniwindow): add up and down key switch menu #792

This commit is contained in:
kangfenmao 2025-01-21 10:11:09 +08:00
parent f5c547cdb2
commit f7db1289e4

View File

@ -1,7 +1,7 @@
import { BulbOutlined, FileTextOutlined, MessageOutlined, TranslationOutlined } from '@ant-design/icons' import { BulbOutlined, FileTextOutlined, MessageOutlined, TranslationOutlined } from '@ant-design/icons'
import Scrollbar from '@renderer/components/Scrollbar' import Scrollbar from '@renderer/components/Scrollbar'
import { Col } from 'antd' 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 { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
@ -13,52 +13,78 @@ interface FeatureMenusProps {
const FeatureMenus: FC<FeatureMenusProps> = ({ text, setRoute, onSendMessage }) => { const FeatureMenus: FC<FeatureMenusProps> = ({ text, setRoute, onSendMessage }) => {
const { t } = useTranslation() const { t } = useTranslation()
const [selectedIndex, setSelectedIndex] = useState(0)
const features = [ const features = useMemo(
{ () => [
icon: <MessageOutlined style={{ fontSize: '16px', color: 'var(--color-text)' }} />, {
title: t('miniwindow.feature.chat'), icon: <MessageOutlined style={{ fontSize: '16px', color: 'var(--color-text)' }} />,
active: true, title: t('miniwindow.feature.chat'),
onClick: () => { active: true,
if (text) { onClick: () => {
setRoute('chat') if (text) {
onSendMessage() setRoute('chat')
onSendMessage()
}
}
},
{
icon: <TranslationOutlined style={{ fontSize: '16px', color: 'var(--color-text)' }} />,
title: t('miniwindow.feature.translate'),
onClick: () => text && setRoute('translate')
},
{
icon: <FileTextOutlined style={{ fontSize: '16px', color: 'var(--color-text)' }} />,
title: t('miniwindow.feature.summary'),
onClick: () => {
if (text) {
setRoute('summary')
onSendMessage(t('prompts.summarize'))
}
}
},
{
icon: <BulbOutlined style={{ fontSize: '16px', color: 'var(--color-text)' }} />,
title: t('miniwindow.feature.explanation'),
onClick: () => {
if (text) {
setRoute('explanation')
onSendMessage(t('prompts.explanation'))
}
} }
} }
}, ],
{ [onSendMessage, setRoute, t, text]
icon: <TranslationOutlined style={{ fontSize: '16px', color: 'var(--color-text)' }} />, )
title: t('miniwindow.feature.translate'),
onClick: () => text && setRoute('translate') useEffect(() => {
}, const handleKeyDown = (e: KeyboardEvent) => {
{ switch (e.key) {
icon: <FileTextOutlined style={{ fontSize: '16px', color: 'var(--color-text)' }} />, case 'ArrowUp':
title: t('miniwindow.feature.summary'), e.preventDefault()
onClick: () => { setSelectedIndex((prev) => (prev > 0 ? prev - 1 : features.length - 1))
if (text) { break
setRoute('summary') case 'ArrowDown':
onSendMessage(t('prompts.summarize')) e.preventDefault()
} setSelectedIndex((prev) => (prev < features.length - 1 ? prev + 1 : 0))
} break
}, case 'Enter':
{ e.preventDefault()
icon: <BulbOutlined style={{ fontSize: '16px', color: 'var(--color-text)' }} />, features[selectedIndex].onClick?.()
title: t('miniwindow.feature.explanation'), break
onClick: () => {
if (text) {
setRoute('explanation')
onSendMessage(t('prompts.explanation'))
}
} }
} }
]
window.addEventListener('keydown', handleKeyDown)
return () => window.removeEventListener('keydown', handleKeyDown)
}, [features, selectedIndex])
return ( return (
<FeatureList> <FeatureList>
<FeatureListWrapper> <FeatureListWrapper>
{features.map((feature, index) => ( {features.map((feature, index) => (
<Col span={24} key={index}> <Col span={24} key={index}>
<FeatureItem onClick={feature.onClick} className={feature.active ? 'active' : ''}> <FeatureItem onClick={feature.onClick} className={index === selectedIndex ? 'active' : ''}>
<FeatureIcon>{feature.icon}</FeatureIcon> <FeatureIcon>{feature.icon}</FeatureIcon>
<FeatureTitle>{feature.title}</FeatureTitle> <FeatureTitle>{feature.title}</FeatureTitle>
</FeatureItem> </FeatureItem>