mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-30 15:59:09 +08:00
refactor(selection): improve type safety and model handling for actions
- Replace FC type with direct props typing in ActionTranslate - Add zod schema and type guards for builtin action items - Enhance model selection logic in SelectionActionApp
This commit is contained in:
parent
63cde7c8ab
commit
c2dde99947
@ -1,3 +1,5 @@
|
||||
import * as z from 'zod'
|
||||
|
||||
import type { PreferenceSchemas } from './preferenceSchemas'
|
||||
|
||||
export type PreferenceDefaultScopeType = PreferenceSchemas['default']
|
||||
@ -38,14 +40,38 @@ export type SelectionActionItem = {
|
||||
searchEngine?: string
|
||||
}
|
||||
|
||||
export type BuiltinActionItemId = 'translate' | 'explain' | 'summary' | 'search' | 'copy' | 'refine' | 'quote'
|
||||
const SelectionBuiltinActionItemIdSchema = z.enum([
|
||||
'translate',
|
||||
'explain',
|
||||
'summary',
|
||||
'search',
|
||||
'copy',
|
||||
'refine',
|
||||
'quote'
|
||||
])
|
||||
|
||||
export type SelectionBuiltinActionItemId = z.infer<typeof SelectionBuiltinActionItemIdSchema>
|
||||
|
||||
export function isBuiltinActionItemId(id: string): id is SelectionBuiltinActionItemId {
|
||||
return SelectionBuiltinActionItemIdSchema.safeParse(id).success
|
||||
}
|
||||
|
||||
export interface SelectionBuiltinActionItem extends SelectionActionItem {
|
||||
id: BuiltinActionItemId
|
||||
id: SelectionBuiltinActionItemId
|
||||
isBuiltIn: true
|
||||
assistantId?: never
|
||||
}
|
||||
|
||||
export function isSelectionBuiltinActionItem(
|
||||
item: SelectionActionItem | null | undefined
|
||||
): item is SelectionBuiltinActionItem {
|
||||
if (!item) {
|
||||
return false
|
||||
}
|
||||
|
||||
return isBuiltinActionItemId(item.id)
|
||||
}
|
||||
|
||||
export enum ThemeMode {
|
||||
light = 'light',
|
||||
dark = 'dark',
|
||||
|
||||
@ -2,9 +2,11 @@ import { Button, Tooltip } from '@cherrystudio/ui'
|
||||
import { usePreference } from '@data/hooks/usePreference'
|
||||
import { isMac } from '@renderer/config/constant'
|
||||
import i18n from '@renderer/i18n'
|
||||
import { getAssistantById } from '@renderer/services/AssistantService'
|
||||
import { getAssistantById, getDefaultModel, getTranslateModel } from '@renderer/services/AssistantService'
|
||||
import { getProviderNameById } from '@renderer/services/ProviderService'
|
||||
import type { Model } from '@renderer/types'
|
||||
import { defaultLanguage } from '@shared/config/constant'
|
||||
import type { SelectionActionItem } from '@shared/data/preference/preferenceTypes'
|
||||
import { isSelectionBuiltinActionItem, type SelectionActionItem } from '@shared/data/preference/preferenceTypes'
|
||||
import { IpcChannel } from '@shared/IpcChannel'
|
||||
import { Slider } from 'antd'
|
||||
import { Droplet, Minus, Pin, X } from 'lucide-react'
|
||||
@ -23,13 +25,25 @@ const SelectionActionApp: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [action, setAction] = useState<SelectionActionItem | null>(null)
|
||||
const assistant = useMemo(() => {
|
||||
if (action?.assistantId) {
|
||||
return getAssistantById(action.assistantId)
|
||||
} else {
|
||||
return null
|
||||
const model: Model | undefined = useMemo(() => {
|
||||
if (isSelectionBuiltinActionItem(action)) {
|
||||
switch (action.id) {
|
||||
case 'translate':
|
||||
return getTranslateModel()
|
||||
case 'explain':
|
||||
case 'summary':
|
||||
case 'refine':
|
||||
return getDefaultModel()
|
||||
default:
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}, [action?.assistantId])
|
||||
if (action?.assistantId) {
|
||||
const assistant = getAssistantById(action.assistantId)
|
||||
return assistant?.model
|
||||
}
|
||||
return undefined
|
||||
}, [action])
|
||||
|
||||
const isActionLoaded = useRef(false)
|
||||
|
||||
@ -214,7 +228,11 @@ const SelectionActionApp: FC = () => {
|
||||
</TitleBarIcon>
|
||||
)}
|
||||
<TitleBarCaption>{action.isBuiltIn ? t(action.name) : action.name}</TitleBarCaption>
|
||||
{assistant?.model !== undefined && <span className="text-muted-foreground">{assistant.model.name}</span>}
|
||||
{model !== undefined && (
|
||||
<span className="text-muted-foreground">
|
||||
{getProviderNameById(model.provider)} | {model.name}
|
||||
</span>
|
||||
)}
|
||||
<TitleBarButtons>
|
||||
<Tooltip
|
||||
content={isPinned ? t('selection.action.window.pinned') : t('selection.action.window.pin')}
|
||||
|
||||
@ -17,7 +17,6 @@ import { detectLanguage } from '@renderer/utils/translate'
|
||||
import { defaultLanguage } from '@shared/config/constant'
|
||||
import type { SelectionActionItem } from '@shared/data/preference/preferenceTypes'
|
||||
import { ArrowRightFromLine, ArrowRightToLine, ChevronDown, CircleHelp, Globe } from 'lucide-react'
|
||||
import type { FC } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
@ -31,7 +30,7 @@ interface Props {
|
||||
|
||||
const logger = loggerService.withContext('ActionTranslate')
|
||||
|
||||
const ActionTranslate: FC<Props> = ({ action, scrollToBottom }) => {
|
||||
const ActionTranslate = ({ action, scrollToBottom }: Props) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [language] = usePreference('app.language')
|
||||
|
||||
Loading…
Reference in New Issue
Block a user