import { IconButton } from "./button"; import { ErrorBoundary } from "./error"; import styles from "./mask.module.scss"; import DownloadIcon from "../icons/download.svg"; import EditIcon from "../icons/edit.svg"; import AddIcon from "../icons/add.svg"; import CloseIcon from "../icons/close.svg"; import DeleteIcon from "../icons/delete.svg"; import CopyIcon from "../icons/copy.svg"; import { DEFAULT_MASK_AVATAR, DEFAULT_MASK_ID, Mask } from "../store/mask"; import { Message, ModelConfig, ROLES, useAppConfig, useChatStore, } from "../store"; import { Input, List, ListItem, Modal, Popover } from "./ui-lib"; import { Avatar, AvatarPicker, EmojiAvatar } from "./emoji"; import Locale from "../locales"; import { useNavigate } from "react-router-dom"; import chatStyle from "./chat.module.scss"; import { useState } from "react"; import { copyToClipboard } from "../utils"; import { Updater } from "../api/openai/typing"; import { ModelConfigList } from "./model-config"; export function MaskConfig(props: { mask: Mask; updateMask: Updater; extraListItems?: JSX.Element; }) { const [showPicker, setShowPicker] = useState(false); const updateConfig = (updater: (config: ModelConfig) => void) => { const config = { ...props.mask.modelConfig }; updater(config); props.updateMask((mask) => (mask.modelConfig = config)); }; return ( <> { const context = props.mask.context.slice(); updater(context); props.updateMask((mask) => (mask.context = context)); }} /> { props.updateMask((mask) => (mask.avatar = emoji)); setShowPicker(false); }} > } open={showPicker} onClose={() => setShowPicker(false)} >
setShowPicker(true)} style={{ cursor: "pointer" }} > {props.mask.avatar !== DEFAULT_MASK_AVATAR ? ( ) : ( )}
props.updateMask((mask) => (mask.name = e.currentTarget.value)) } >
{props.extraListItems} ); } export function ContextPrompts(props: { context: Message[]; updateContext: (updater: (context: Message[]) => void) => void; }) { const context = props.context; const addContextPrompt = (prompt: Message) => { props.updateContext((context) => context.push(prompt)); }; const removeContextPrompt = (i: number) => { props.updateContext((context) => context.splice(i, 1)); }; const updateContextPrompt = (i: number, prompt: Message) => { props.updateContext((context) => (context[i] = prompt)); }; return ( <>
{context.map((c, i) => (
updateContextPrompt(i, { ...c, content: e.currentTarget.value as any, }) } /> } className={chatStyle["context-delete-button"]} onClick={() => removeContextPrompt(i)} bordered />
))}
} text={Locale.Context.Add} bordered className={chatStyle["context-prompt-button"]} onClick={() => addContextPrompt({ role: "system", content: "", date: "", }) } />
); } export function MaskPage() { const config = useAppConfig(); const navigate = useNavigate(); const masks: Mask[] = new Array(10).fill(0).map((m, i) => ({ id: i, avatar: "1f606", name: "预设角色 " + i.toString(), context: [ { role: "assistant", content: "你好,有什么可以帮忙的吗", date: "" }, ], modelConfig: config.modelConfig, lang: "cn", })); return (
预设角色面具
编辑预设角色定义
} bordered />
} bordered />
} bordered onClick={() => navigate(-1)} />
{masks.map((m) => (
} className={styles["mask-item"]} >
} text="对话" /> } text="编辑" /> } text="删除" />
))}
); }