visual-novel-web/src/app/(main)/character/[id]/chat/Right/index.tsx

158 lines
4.8 KiB
TypeScript
Raw Normal View History

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';
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-04 10:42:16 +00:00
<FormItem<SettingFormValues>
name="model"
2025-10-28 07:59:26 +00:00
render={({ value, onChange }) => (
<ModelSelectDialog value={value} onChange={onChange} />
)}
/>
2025-11-04 10:42:16 +00:00
<FormItem<SettingFormValues>
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-04 10:42:16 +00:00
<FormItem<SettingFormValues>
name="voiceActor"
render={({ value, onChange }) => (
<VoiceActorSelectDialog value={value} onChange={onChange} />
)}
2025-10-28 07:59:26 +00:00
/>
2025-11-04 10:42:16 +00:00
<FormItem<SettingFormValues>
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-04 10:42:16 +00:00
<FormItem<SettingFormValues>
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-04 10:42:16 +00:00
<FormItem<SettingFormValues>
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-04 10:42:16 +00:00
<FormItem<SettingFormValues>
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-04 10:42:16 +00:00
<FormItem<SettingFormValues>
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;