diff --git a/src/components/journal/ComposePanel.tsx b/src/components/journal/ComposePanel.tsx index 5584052..00b4ad3 100644 --- a/src/components/journal/ComposePanel.tsx +++ b/src/components/journal/ComposePanel.tsx @@ -68,7 +68,7 @@ export const ComposePanel: Component = () => { disabled={sending()} class="ml-auto bg-blue-600 text-white rounded px-3 py-1 text-xs hover:bg-blue-700 disabled:opacity-50" > - {sending() ? "..." : "Send"} + {sending() ? "..." : "发送"} diff --git a/src/components/journal/ConnectionBar.tsx b/src/components/journal/ConnectionBar.tsx index b2cef64..7d780c3 100644 --- a/src/components/journal/ConnectionBar.tsx +++ b/src/components/journal/ConnectionBar.tsx @@ -31,7 +31,7 @@ export const ConnectionBar: Component = () => { }; const handleDeleteSession = (id: string) => { - if (confirm(`Delete session "${id}"? This cannot be undone.`)) { + if (confirm(`确定要删除会话 "${id}"?此操作不可撤销。`)) { deleteSession(id); } }; @@ -41,7 +41,7 @@ export const ConnectionBar: Component = () => { await hydrateFromServer(id); setSessionId(id); } catch (e) { - setError("Failed to load session"); + setError("无法加载会话"); } }; @@ -54,7 +54,7 @@ export const ConnectionBar: Component = () => { {/* Status row */}
- connected + 已连接 {stream.sessionName || stream.sessionId} @@ -62,12 +62,12 @@ export const ConnectionBar: Component = () => {
- Playing as {stream.myName} + 扮演 {stream.myName} @@ -77,12 +77,12 @@ export const ConnectionBar: Component = () => {
- Sessions: + 会话列表:
@@ -92,7 +92,7 @@ export const ConnectionBar: Component = () => { type="text" value={newSessionName()} onInput={(e) => setNewSessionName(e.currentTarget.value)} - placeholder="Session name" + placeholder="会话名称" class="flex-1 border border-gray-300 rounded px-2 py-0.5 text-xs" onKeyDown={(e) => e.key === "Enter" && handleCreateSession()} /> @@ -100,7 +100,7 @@ export const ConnectionBar: Component = () => { onClick={handleCreateSession} class="bg-green-600 text-white rounded px-2 py-0.5 text-xs hover:bg-green-700" > - Create + Create Create
@@ -126,7 +126,7 @@ export const ConnectionBar: Component = () => { handleDeleteSession(id); }} class="text-gray-400 hover:text-red-500 text-xs" - title="Delete session" + title="删除会话" > ✕ diff --git a/src/components/journal/DynamicForm.tsx b/src/components/journal/DynamicForm.tsx index 5ece0c5..6d36ecb 100644 --- a/src/components/journal/DynamicForm.tsx +++ b/src/components/journal/DynamicForm.tsx @@ -53,7 +53,7 @@ const SchemaFields: Component<{ const shape = unwrapShape(props.schema); if (!shape) { - return

No fields

; + return

无字段

; } return ( @@ -98,7 +98,7 @@ const SchemaFields: Component<{ checked={isSet()} onChange={toggleOptional} class="mt-1.5" - title={`Include ${key}`} + title={`包含 ${key}`} />
@@ -204,7 +204,7 @@ const FieldInput: Component<{ }} disabled={props.disabled} class={inputClass} - placeholder="comma-separated" + placeholder="逗号分隔" />
diff --git a/src/components/journal/JournalInput.tsx b/src/components/journal/JournalInput.tsx index 4e558c8..8c44da8 100644 --- a/src/components/journal/JournalInput.tsx +++ b/src/components/journal/JournalInput.tsx @@ -44,20 +44,19 @@ function parseInput(raw: string): ParsedInput { if (raw.startsWith("/roll ")) { const notation = raw.slice("/roll ".length).trim(); if (!notation) - return { type: "roll", payload: {}, error: "Dice notation required" }; + return { type: "roll", payload: {}, error: "需要骰子表达式" }; return { type: "roll", payload: { notation, label: notation } }; } if (raw.startsWith("/spark ")) { const key = raw.slice("/spark ".length).trim(); - if (!key) - return { type: "spark", payload: {}, error: "Spark table key required" }; + if (!key) return { type: "spark", payload: {}, error: "需要种子表键名" }; return { type: "spark", payload: { key } }; } if (raw.startsWith("/link ")) { const arg = raw.slice("/link ".length).trim(); - if (!arg) return { type: "link", payload: {}, error: "Path required" }; + if (!arg) return { type: "link", payload: {}, error: "需要路径" }; const hashIdx = arg.indexOf("#"); const path = hashIdx === -1 ? arg : arg.slice(0, hashIdx); const section = @@ -67,7 +66,7 @@ function parseInput(raw: string): ParsedInput { // /roll, /spark, or /link with no space — need to complete, don't send if (raw === "/roll" || raw === "/spark" || raw === "/link") { - return { type: "chat", payload: {}, error: "Complete the command" }; + return { type: "chat", payload: {}, error: "请补全命令" }; } return { type: "chat", payload: { text: raw } }; @@ -168,7 +167,7 @@ export const JournalInput: Component = () => { textareaRef?.focus(); return; } catch (e) { - setError(e instanceof Error ? e.message : "Failed to roll spark table"); + setError(e instanceof Error ? e.message : "种子表掷骰失败"); setSending(false); return; } @@ -216,7 +215,7 @@ export const JournalInput: Component = () => { ); return matches.length > 0 ? matches - : [{ label: "Unknown command", kind: "no-results", insertText: "" }]; + : [{ label: "未知命令", kind: "no-results", insertText: "" }]; } // After /roll — show dice suggestions @@ -230,7 +229,7 @@ export const JournalInput: Component = () => { ) .slice(0, 8); if (matches.length === 0) { - return [{ label: "No dice found", kind: "no-results", insertText: "" }]; + return [{ label: "未找到骰子", kind: "no-results", insertText: "" }]; } return matches.map((d) => ({ label: d.notation, @@ -252,7 +251,7 @@ export const JournalInput: Component = () => { if (matches.length === 0) { return [ { - label: "No spark tables found", + label: "未找到种子表", kind: "no-results", insertText: "", }, @@ -276,9 +275,7 @@ export const JournalInput: Component = () => { ) .slice(0, 8); if (matches.length === 0) { - return [ - { label: "No links found", kind: "no-results", insertText: "" }, - ]; + return [{ label: "未找到链接", kind: "no-results", insertText: "" }]; } return matches.map((l) => { const insert = l.section @@ -459,7 +456,7 @@ export const JournalInput: Component = () => { ref={completionsRef} class="absolute bottom-full left-0 right-0 bg-white border border-gray-200 rounded-t shadow-lg mb-0.5 z-50 px-3 py-2 text-xs text-gray-400 italic" > - Loading completions… + 正在加载补全数据…
@@ -467,7 +464,7 @@ export const JournalInput: Component = () => { ref={completionsRef} class="absolute bottom-full left-0 right-0 bg-white border border-red-200 rounded-t shadow-lg mb-0.5 z-50 px-3 py-2 text-xs text-red-500" > - {(comp.state as any).message || "Failed to load completions"} + {(comp.state as any).message || "无法加载补全数据"}
{ when={!isObserver()} fallback={
- You are observing. Open this panel on another device to join as GM - or player. + 你正在观察模式。在另一台设备上打开此面板以主持人或玩家身份加入。
} > @@ -498,8 +494,8 @@ export const JournalInput: Component = () => { onKeyDown={handleKeyDown} placeholder={ isGm() - ? "Type a message, or /roll, /spark, or /link..." - : "Type a message..." + ? "输入消息,或使用 /roll、/spark、/link 命令..." + : "输入消息..." } rows={2} class="w-full resize-none border-0 px-3 pt-2.5 pb-1 text-sm @@ -520,7 +516,7 @@ export const JournalInput: Component = () => { hover:bg-blue-700 disabled:opacity-40 disabled:cursor-not-allowed transition-colors" > - Send + 发送 diff --git a/src/components/journal/JournalPanel.tsx b/src/components/journal/JournalPanel.tsx index 524fae4..7b34163 100644 --- a/src/components/journal/JournalPanel.tsx +++ b/src/components/journal/JournalPanel.tsx @@ -68,9 +68,9 @@ export const JournalPanel: Component = (props) => { @@ -161,9 +161,7 @@ const JournalHeader: Component = (props) => { - Disconnected - +

未连接

} >
@@ -221,7 +219,7 @@ const JournalHeader: Component = (props) => { onInput={(e) => setNewSessionName(e.currentTarget.value) } - placeholder="Session name" + placeholder="会话名称" class="flex-1 border border-gray-300 rounded px-1.5 py-0.5 text-xs" autofocus onKeyDown={(e) => { @@ -242,7 +240,7 @@ const JournalHeader: Component = (props) => { onClick={() => setShowNewInput(true)} class="w-full text-left px-3 py-1 text-xs text-blue-600 hover:bg-gray-100" > - + New session + + 新建会话
@@ -257,7 +255,7 @@ const JournalHeader: Component = (props) => { @@ -265,7 +263,7 @@ const JournalHeader: Component = (props) => { @@ -332,16 +330,16 @@ const ConnectDialog: Component = () => { when={!autoJoined() || error()} fallback={

- {connecting() ? "Joining session…" : "Joined!"} + {connecting() ? "正在加入会话…" : "已加入!"}

} >

- Enter your name and role to join the session. + 请输入你的名字和角色来加入会话。
- Connecting to {window.location.host} + 连接到 {window.location.host}

{ value={playerName()} onInput={(e) => setPlayerName(e.currentTarget.value)} onKeyDown={(e) => e.key === "Enter" && handleConnect()} - placeholder="Your name" + placeholder="你的名字" class="w-full border border-gray-300 rounded px-3 py-1.5 text-sm" autofocus /> @@ -364,7 +362,7 @@ const ConnectDialog: Component = () => { : "bg-white text-gray-600 border-gray-300 hover:border-gray-400" }`} > - {r === "gm" ? "GM" : r === "player" ? "Player" : "Observer"} + {r === "gm" ? "主持人" : r === "player" ? "玩家" : "观察者"} ))}
@@ -374,7 +372,7 @@ const ConnectDialog: Component = () => { class="w-full bg-blue-600 text-white rounded px-3 py-2 text-sm font-medium hover:bg-blue-700 disabled:opacity-50" > - {connecting() ? "Connecting..." : "Join"} + {connecting() ? "连接中..." : "加入"}

{error()}

@@ -424,7 +422,7 @@ const InviteDialog: Component = (props) => {
-

Invite Player

+

邀请玩家

- Enter a player name and share the link. They will join as a player. + 输入玩家名字并分享链接,对方将以玩家身份加入。

setPlayerName(e.currentTarget.value)} - placeholder="Player name" + placeholder="玩家名字" class="w-full border border-gray-300 rounded px-2 py-1 text-xs" autofocus /> @@ -459,7 +457,7 @@ const InviteDialog: Component = (props) => { : "bg-blue-600 text-white hover:bg-blue-700" }`} > - {copied() ? "Copied!" : "Copy"} + {copied() ? "已复制!" : "复制"}
diff --git a/src/components/journal/StreamMessage.tsx b/src/components/journal/StreamMessage.tsx index d1253ef..f6919af 100644 --- a/src/components/journal/StreamMessage.tsx +++ b/src/components/journal/StreamMessage.tsx @@ -45,7 +45,7 @@ export const StreamMessageCard: Component<{ @@ -87,7 +87,7 @@ const RevealedCard: Component<{ msg: StreamMessageType }> = (props) => { return (
- {props.msg.sender} — reverted + {props.msg.sender} — 已撤回
); diff --git a/src/components/journal/StreamView.tsx b/src/components/journal/StreamView.tsx index 37866ac..ef0d015 100644 --- a/src/components/journal/StreamView.tsx +++ b/src/components/journal/StreamView.tsx @@ -30,8 +30,8 @@ export const StreamView: Component = () => {

{stream.connected - ? "No messages yet. Start by posting something." - : "Connect to a session to see messages."} + ? "暂无消息,发送点什么开始吧。" + : "连接会话以查看消息。"}

diff --git a/src/components/journal/types/chat.tsx b/src/components/journal/types/chat.tsx index dfd1f58..7c5ed6c 100644 --- a/src/components/journal/types/chat.tsx +++ b/src/components/journal/types/chat.tsx @@ -19,7 +19,7 @@ export type ChatPayload = z.infer; registerMessageType({ type: "chat", - label: "Chat", + label: "聊天", emitters: ["gm", "player"], schema, defaultPayload: () => ({ text: "" }), diff --git a/src/components/journal/types/intent.tsx b/src/components/journal/types/intent.tsx index 23f636a..496ca2b 100644 --- a/src/components/journal/types/intent.tsx +++ b/src/components/journal/types/intent.tsx @@ -18,7 +18,7 @@ export type IntentPayload = z.infer; registerMessageType({ type: "intent", - label: "Declare Intent", + label: "声明意图", emitters: ["player"], schema: intentSchema, defaultPayload: () => ({ description: "" }), @@ -26,7 +26,7 @@ registerMessageType({
🙋 - Intent + 意图

{p.description}

{p.context && Object.keys(p.context).length > 0 && ( @@ -52,14 +52,14 @@ export type ResolutionPayload = z.infer; registerMessageType({ type: "resolution", - label: "Resolve Intent", + label: "裁决意图", emitters: ["gm"], schema: resolutionSchema, render: (p) => (
- Resolution + 裁决 re: {p.intentId}

{p.outcome}

diff --git a/src/components/journal/types/link.tsx b/src/components/journal/types/link.tsx index a2c5f5a..18ac991 100644 --- a/src/components/journal/types/link.tsx +++ b/src/components/journal/types/link.tsx @@ -84,7 +84,7 @@ const RevealLink: Component = (p) => { registerMessageType({ type: "link", - label: "Link Article", + label: "链接文章", emitters: ["gm"], schema, defaultPayload: () => ({ path: "/" }), diff --git a/src/components/journal/types/roll.tsx b/src/components/journal/types/roll.tsx index 568d6b1..70b100c 100644 --- a/src/components/journal/types/roll.tsx +++ b/src/components/journal/types/roll.tsx @@ -43,7 +43,7 @@ export function resolveRollPayload(raw: { registerMessageType({ type: "roll", - label: "Roll Dice", + label: "掷骰", emitters: ["gm"], schema, defaultPayload: () => ({ diff --git a/src/components/journal/types/spark.tsx b/src/components/journal/types/spark.tsx index 47c65e8..ced0121 100644 --- a/src/components/journal/types/spark.tsx +++ b/src/components/journal/types/spark.tsx @@ -117,7 +117,7 @@ export async function resolveSparkPayload(raw: { registerMessageType({ type: "spark", - label: "Spark Table", + label: "种子表", emitters: ["gm"], schema, defaultPayload: () => ({