feat(web): add player name, freeform input, and unified settings modal

- Player name: stored in localStorage, injected into Architect/Writer/InsertBeat
  prompts so NPCs address the player by name, displayed in dialogue UI
- Freeform input: compact button at choice nodes expands to text input, LLM
  classifier routes to insert-beat (interactive NPC response) or change-scene
- SettingsModal: unified panel merging player name, voice toggle (with
  collapsible TTS key section), replacing the old TtsKeyModal
- Insert-beat upgrade: prompt now requires NPC reaction when characters are
  present, shared by both freeform and Vision paths
- IME guard: isComposing check on freeform input to prevent CJK mid-composition
  submission

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
yuanzonghao
2026-06-07 12:03:13 +08:00
parent b0b5630a25
commit ae3dd17e6b
11 changed files with 897 additions and 77 deletions
+5 -1
View File
@@ -16,11 +16,15 @@ export function DialogueHistoryModal({
items,
portrait,
onClose,
playerName,
}: {
items: DialogueHistoryItem[];
portrait: boolean;
onClose: () => void;
playerName?: string;
}) {
const displaySpeaker = (s: string | undefined) =>
s === "你" && playerName ? playerName : s;
const listRef = useRef<HTMLDivElement>(null);
useEffect(() => {
@@ -97,7 +101,7 @@ export function DialogueHistoryModal({
</span>
{item.speaker && (
<span className="font-serif text-[12px] text-[rgba(205,165,90,0.92)]">
{item.speaker}
{displaySpeaker(item.speaker)}
</span>
)}
</div>