diff --git a/src/ProChat/components/ProInputArea/AudioLines.tsx b/src/ProChat/components/ProInputArea/AudioLines.tsx new file mode 100644 index 0000000..41ba933 --- /dev/null +++ b/src/ProChat/components/ProInputArea/AudioLines.tsx @@ -0,0 +1,26 @@ +import { memo } from 'react'; + +const AudioIcon = memo(() => { + return ( + + + + + + + + + ); +}); +export default AudioIcon; diff --git a/src/ProChat/components/ProInputArea/ControlPanel.tsx b/src/ProChat/components/ProInputArea/ControlPanel.tsx index cf5f896..9863b7e 100644 --- a/src/ProChat/components/ProInputArea/ControlPanel.tsx +++ b/src/ProChat/components/ProInputArea/ControlPanel.tsx @@ -37,7 +37,7 @@ export const ActionBar = ({ className }: { className?: string }) => { > , - , + , , ]; diff --git a/src/ProChat/components/ProInputArea/ExtraModel.tsx b/src/ProChat/components/ProInputArea/ExtraModel.tsx index cf5f896..7bf5f9e 100644 --- a/src/ProChat/components/ProInputArea/ExtraModel.tsx +++ b/src/ProChat/components/ProInputArea/ExtraModel.tsx @@ -1,12 +1,11 @@ -import { createStyles, cx } from 'antd-style'; -import { Flexbox } from 'react-layout-kit'; - import ActionIcon from '@/ActionIcon'; -import { ConfigProvider, Popconfirm } from 'antd'; -import { Globe, RotateCw, Trash2 } from 'lucide-react'; - import useProChatLocale from '@/ProChat/hooks/useProChatLocale'; -import { useStore } from '../../store'; +import { ConfigProvider } from 'antd'; +import { createStyles, cx } from 'antd-style'; +import { isObject, isString } from 'lodash-es'; +import { FileVideo, Image } from 'lucide-react'; +import { Flexbox } from 'react-layout-kit'; +import AudioIcon from './AudioLines'; const useStyles = createStyles(({ css, token }) => ({ extra: css` @@ -14,33 +13,60 @@ const useStyles = createStyles(({ css, token }) => ({ `, })); -export const ActionBar = ({ className }: { className?: string }) => { - const [clearMessage, actionsRender, flexConfig] = useStore((s) => [ - s.clearMessage, - s.actions?.render, - s.actions?.flexConfig, - ]); +export type ExtraType = 'image' | 'audio' | 'video'; +export interface ExtraItem { + type: ExtraType; + onChange?: () => void; + onFinish?: () => void; + render: () => JSX.Element; +} +export type ExtraModelProps = { + className?: string; + extra?: Array; +}; + +export const ExtraModel = (props: ExtraModelProps) => { + const { className, extra } = props; const { localeObject } = useProChatLocale(); - const { styles, theme } = useStyles(); const defaultDoms = [ - { - clearMessage(); - }} - > - - , - , - , + { + type: 'video', + render: , + }, + { + type: 'audio', + render: , + }, + { + type: 'image', + render: , + }, ]; + const { styles, theme } = useStyles(); + + const renderContent = () => { + if (!extra || extra.length === 0) { + return null; + } + + const getDefaultRender = (type: ExtraType) => { + const defaultComponent = defaultDoms.find((dom) => dom.type === type); + return defaultComponent ? defaultComponent.render : null; + }; + + return extra.reverse().map((item) => { + if (isString(item)) { + return getDefaultRender(item as ExtraType); + } else if (isObject(item) && 'type' in item && 'render' in item) { + return item.render(); + } else { + return null; + } + }); + }; return ( { paddingInline={12} className={cx(styles.extra, className)} gap={8} - {...flexConfig} > - {actionsRender?.(defaultDoms) ?? defaultDoms} + {renderContent()} ); }; -export default ActionBar; +export default ExtraModel; diff --git a/src/ProChat/components/ProInputArea/index.tsx b/src/ProChat/components/ProInputArea/index.tsx index e749cf2..83a1380 100644 --- a/src/ProChat/components/ProInputArea/index.tsx +++ b/src/ProChat/components/ProInputArea/index.tsx @@ -7,6 +7,7 @@ import { ReactNode, useContext, useEffect, useMemo, useRef, useState } from 'rea import { Flexbox } from 'react-layout-kit'; import { useStore } from '../../store'; import ControlPanel from './ControlPanel'; +import ExtraModel, { ExtraItem, ExtraType } from './ExtraModel'; import { ProTextArea } from './ProTextArea'; import StopLoadingIcon from './StopLoading'; const ENTER = 'enter'; @@ -52,17 +53,7 @@ const useStyles = createStyles(({ css, responsive, token }) => ({ color: ${token.colorTextTertiary}; `, })); -export enum ExtraType { - Image = 'image', - Voice = 'voice', - Video = 'video', -} -export interface ExtraItem { - type: ExtraType; - onChange?: () => void; - onFinish?: () => void; - render: () => JSX.Element; -} + export type ProInputAreaProps = { className?: string; extra?: Array; @@ -83,8 +74,15 @@ export type ProInputAreaProps = { export const ProInputArea = (props: ProInputAreaProps) => { // 拿到 Props 中的 需求 - const { className, onSend, inputAreaRender, inputRender, sendButtonRender, sendShortcutKey } = - props || {}; + const { + className, + onSend, + inputAreaRender, + inputRender, + sendButtonRender, + sendShortcutKey, + extra, + } = props || {}; // 拿到 本地仓库 透出的 方法 const [sendMessage, isLoading, placeholder, inputAreaProps, clearMessage, stopGenerateMessage] = useStore((s) => [ @@ -243,7 +241,10 @@ export const ProInputArea = (props: ProInputAreaProps) => { }} > - + + + + ( inputAreaRender={inputAreaRender || renderInputArea} inputRender={inputRender} sendShortcutKey="enter" + extra={[ + 'image', + 'audio', + { + type: 'video', + render: () => { + return ; + }, + }, + ]} /> }