feat(遊戲化): 新增大廳、附身、時間流、後日談進度等遊戲化系統功能

新增角色大廳(lobby)邀約與通話、附身(possession)、時鐘(clock)抽象、
時間流與睡眠負債、後日談進度、行為選擇與旁觀反應等模組,並補齊對應冒煙
測試(R~V)與單元測試;同步調整 web/mobile 對應頁面與元件。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 09:10:26 +08:00
co-authored by Claude Sonnet 5
parent 127a59dafd
commit 1bea06e3cd
195 changed files with 17219 additions and 738 deletions
+26 -20
View File
@@ -1,6 +1,10 @@
import { VoicePlaybackButton } from "./VoicePlaybackButton";
interface ChatBubbleProps {
role: "user" | "character";
text: string;
characterId?: string;
userId?: string;
}
// H-3 動作描寫標記渲染:把 *…* 標記以暮空紫小字呈現,與台詞區分。
@@ -19,28 +23,30 @@ function renderContent(text: string) {
});
}
export function ChatBubble({ role, text }: ChatBubbleProps) {
export function ChatBubble({ role, text, characterId, userId }: ChatBubbleProps) {
const isUser = role === "user";
return (
<div
className="max-w-[78%] rounded-2xl px-3.5 py-2 text-sm leading-relaxed"
style={
isUser
? {
alignSelf: "flex-end",
background: "var(--accent-bright)",
color: "#fff",
borderBottomRightRadius: 4,
}
: {
alignSelf: "flex-start",
background: "var(--bg-soft)",
border: "1px solid var(--line)",
borderBottomLeftRadius: 4,
}
}
>
{renderContent(text)}
<div className="flex max-w-[78%] flex-col" style={{ alignSelf: isUser ? "flex-end" : "flex-start", alignItems: isUser ? "flex-end" : "flex-start" }}>
<div
className="rounded-2xl px-3.5 py-2 text-sm leading-relaxed"
style={
isUser
? {
background: "var(--accent-bright)",
color: "#fff",
borderBottomRightRadius: 4,
}
: {
background: "var(--bg-soft)",
border: "1px solid var(--line)",
borderBottomLeftRadius: 4,
}
}
>
{renderContent(text)}
</div>
{/* P-6:語音播放介面只在角色訊息旁提供,使用者自己的訊息不需要播放。 */}
{!isUser && characterId && userId && <VoicePlaybackButton characterId={characterId} userId={userId} text={text} />}
</div>
);
}