2025-10-28 07:59:26 +00:00
|
|
|
'use client';
|
|
|
|
|
|
2025-11-04 10:42:16 +00:00
|
|
|
import Form, { FormItem } from '@/components/ui/radix-form';
|
2025-10-28 07:59:26 +00:00
|
|
|
import React from 'react';
|
|
|
|
|
import { cn } from '@/lib';
|
|
|
|
|
import { Select, Switch, Number, FontSize } from '@/components/ui/inputs';
|
|
|
|
|
import Background from './Background';
|
2025-11-03 10:03:34 +00:00
|
|
|
import { AddIcon } from '@/assets/common';
|
2025-11-03 11:32:52 +00:00
|
|
|
import ModelSelectDialog from '@/components/feature/ModelSelectDialog';
|
|
|
|
|
import VoiceActorSelectDialog from '@/components/feature/VoiceActorSelectDialog';
|
|
|
|
|
import BubbleSelectDialog from '@/components/feature/BubbleSelectDialog';
|
2025-11-03 10:03:34 +00:00
|
|
|
import IconFont from '@/components/ui/iconFont';
|
2025-10-28 07:59:26 +00:00
|
|
|
|
2025-11-04 10:42:16 +00:00
|
|
|
// 表单数据类型定义
|
|
|
|
|
type SettingFormValues = {
|
|
|
|
|
model?: string;
|
|
|
|
|
short_text?: boolean;
|
|
|
|
|
voiceActor?: string;
|
|
|
|
|
dialogueOnly?: boolean;
|
|
|
|
|
max_tokens?: number;
|
|
|
|
|
fontSize?: number;
|
|
|
|
|
chat_mode?: string;
|
|
|
|
|
chat_bubble?: string;
|
|
|
|
|
background?: string;
|
|
|
|
|
};
|
|
|
|
|
|
2025-10-28 07:59:26 +00:00
|
|
|
const Title: React.FC<
|
|
|
|
|
{
|
|
|
|
|
text?: string;
|
|
|
|
|
children?: React.ReactNode;
|
|
|
|
|
} & React.HTMLAttributes<HTMLDivElement>
|
|
|
|
|
> = (props) => {
|
|
|
|
|
const { text, children, ...rest } = props;
|
|
|
|
|
return (
|
|
|
|
|
<div className="mt-10 flex flex-col gap-2.5">
|
|
|
|
|
<div {...rest} className={cn('font-bold', rest.className)}>
|
|
|
|
|
{text}
|
|
|
|
|
</div>
|
|
|
|
|
{children}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const SettingForm = React.memo(() => {
|
|
|
|
|
return (
|
|
|
|
|
<div className="flex h-full flex-col">
|
|
|
|
|
<div
|
|
|
|
|
className="flex items-center text-lg font-black"
|
|
|
|
|
style={{ height: 83 }}
|
|
|
|
|
>
|
|
|
|
|
Setting
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex-1 overflow-y-auto pr-10">
|
2025-11-04 10:42:16 +00:00
|
|
|
<Form<SettingFormValues>
|
|
|
|
|
onChange={(values) => {
|
|
|
|
|
console.log(values);
|
|
|
|
|
}}
|
|
|
|
|
>
|
2025-10-28 07:59:26 +00:00
|
|
|
<Title text="Switch Model">
|
2025-11-05 11:32:23 +00:00
|
|
|
<FormItem
|
2025-11-04 10:42:16 +00:00
|
|
|
name="model"
|
2025-10-28 07:59:26 +00:00
|
|
|
render={({ value, onChange }) => (
|
|
|
|
|
<ModelSelectDialog value={value} onChange={onChange} />
|
|
|
|
|
)}
|
|
|
|
|
/>
|
2025-11-05 11:32:23 +00:00
|
|
|
<FormItem
|
2025-11-04 10:42:16 +00:00
|
|
|
name="short_text"
|
2025-10-28 07:59:26 +00:00
|
|
|
render={({ value, onChange }) => (
|
|
|
|
|
<Switch
|
|
|
|
|
icon={'/character/model_long_text.svg'}
|
|
|
|
|
text="Short Text Mode"
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</Title>
|
|
|
|
|
|
|
|
|
|
<Title text="Sound">
|
2025-11-05 11:32:23 +00:00
|
|
|
<FormItem
|
2025-11-04 10:42:16 +00:00
|
|
|
name="voiceActor"
|
|
|
|
|
render={({ value, onChange }) => (
|
|
|
|
|
<VoiceActorSelectDialog value={value} onChange={onChange} />
|
|
|
|
|
)}
|
2025-10-28 07:59:26 +00:00
|
|
|
/>
|
2025-11-05 11:32:23 +00:00
|
|
|
<FormItem
|
2025-11-04 10:42:16 +00:00
|
|
|
name="dialogueOnly"
|
2025-10-28 07:59:26 +00:00
|
|
|
render={({ value, onChange }) => (
|
|
|
|
|
<Switch
|
|
|
|
|
icon={'/character/play_dialogue_only.svg'}
|
|
|
|
|
text="Play dialogue only"
|
|
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</Title>
|
|
|
|
|
|
|
|
|
|
<Title text="Maximum number of response tokens">
|
2025-11-05 11:32:23 +00:00
|
|
|
<FormItem
|
2025-11-04 10:42:16 +00:00
|
|
|
name="max_tokens"
|
2025-10-28 07:59:26 +00:00
|
|
|
render={({ value, onChange }) => (
|
|
|
|
|
<Number value={value} onChange={onChange} />
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</Title>
|
|
|
|
|
|
|
|
|
|
<Title text="Appearance">
|
2025-11-05 11:32:23 +00:00
|
|
|
<FormItem
|
2025-10-28 07:59:26 +00:00
|
|
|
name="fontSize"
|
2025-11-04 10:42:16 +00:00
|
|
|
render={({ value, onChange }) => {
|
|
|
|
|
return <FontSize value={value} onChange={onChange} />;
|
2025-10-28 07:59:26 +00:00
|
|
|
}}
|
|
|
|
|
/>
|
2025-11-05 11:32:23 +00:00
|
|
|
<FormItem
|
2025-11-04 10:42:16 +00:00
|
|
|
name="chat_mode"
|
2025-10-28 07:59:26 +00:00
|
|
|
render={({ value, onChange }) => (
|
|
|
|
|
<Select
|
2025-11-04 10:42:16 +00:00
|
|
|
value={value}
|
|
|
|
|
onChange={onChange}
|
2025-10-28 07:59:26 +00:00
|
|
|
placeholder="Chat Mode"
|
|
|
|
|
icon={'/character/chat_mode.svg'}
|
|
|
|
|
options={[
|
|
|
|
|
{ label: 'Chat Mode', value: 'chat_mode' },
|
|
|
|
|
{ label: 'Chat Bubble', value: 'chat_bubble' },
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
/>
|
2025-11-04 10:42:16 +00:00
|
|
|
{/* TODO: BubbleSelectDialog 需要支持受控模式 */}
|
|
|
|
|
<div>
|
|
|
|
|
<BubbleSelectDialog />
|
|
|
|
|
</div>
|
2025-10-28 07:59:26 +00:00
|
|
|
</Title>
|
|
|
|
|
|
|
|
|
|
<Title text="Background">
|
2025-11-05 11:32:23 +00:00
|
|
|
<FormItem
|
2025-10-28 07:59:26 +00:00
|
|
|
name="background"
|
|
|
|
|
render={({ value, onChange }) => (
|
|
|
|
|
<Background value={value} onChange={onChange} />
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
</Title>
|
|
|
|
|
</Form>
|
|
|
|
|
<div className="mt-12.5 mb-10 flex flex-col gap-5">
|
|
|
|
|
<div className="tk-button border-1 border-[#E2503D] text-[rgba(255,59,48,1)] hover:bg-[rgba(255,59,48,0.1)]">
|
2025-11-03 10:03:34 +00:00
|
|
|
<IconFont type="icon-delete" size={20} /> Delete
|
2025-10-28 07:59:26 +00:00
|
|
|
</div>
|
|
|
|
|
<div className="tk-button border-text-color/80 border-1 hover:bg-white hover:text-[rgba(0,102,255,1)]">
|
|
|
|
|
<AddIcon /> START NEW CHAT
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
export default SettingForm;
|