/* chapter write page: 大纲编辑 + 上下文面板 + SSE 流式生成 + 暂停/继续/重写. */
import { escapeHtml, fetchJson, postJson, showError } from "../utils.js";
import { createSSEStream } from "../components/sse-client.js";
const NOVEL_ID = window.NOVEL_ID;
const CHAPTER_ID = window.CHAPTER_ID;
const alertsEl = document.getElementById("cwAlerts");
const outlineEl = document.getElementById("cwOutline");
const outputEl = document.getElementById("cwOutput");
const wordCountEl = document.getElementById("cwWordCount");
const ctxSummaryEl = document.getElementById("cwContextSummary");
const btn = {
generate: document.getElementById("cwGenerate"),
pause: document.getElementById("cwPause"),
resume: document.getElementById("cwResume"),
regen: document.getElementById("cwRegen"),
edit: document.getElementById("cwEdit"),
save: document.getElementById("cwSave"),
approve: document.getElementById("cwApprove"),
saveOutline: document.getElementById("cwSaveOutline"),
};
let stream = null;
let accumulated = ""; // 已生成文本 (暂停断点)
let editing = false;
/* ---------------- 状态管理 ---------------- */
function setStreaming(on) {
btn.generate.disabled = on;
btn.pause.disabled = !on;
btn.regen.disabled = on || !accumulated;
btn.resume.disabled = on || !accumulated;
btn.saveOutline.disabled = on;
if (on) {
btn.edit.disabled = true;
btn.save.disabled = true;
btn.approve.disabled = true;
}
}
function setIdleWithContent() {
btn.generate.disabled = false;
btn.pause.disabled = true;
btn.resume.disabled = true;
btn.regen.disabled = false;
btn.edit.disabled = false;
btn.save.disabled = false;
btn.approve.disabled = false;
}
function renderOutput() {
outputEl.innerHTML = accumulated
? escapeHtml(accumulated)
: '点击"生成"开始写作…';
outputEl.scrollTop = outputEl.scrollHeight;
wordCountEl.textContent = accumulated ? "当前字数: " + accumulated.length : "";
}
/* ---------------- 加载章节 + 上下文 ---------------- */
async function loadChapter() {
try {
const ch = await fetchJson("/api/chapters/" + CHAPTER_ID);
document.getElementById("cwTitle").textContent =
"第" + (ch.volume || 1) + "卷 第" + (ch.chapter_number || 1) + "章 " + (ch.title || "");
outlineEl.value = ch.outline || "";
if (ch.content) {
accumulated = ch.content;
renderOutput();
setIdleWithContent();
}
} catch (err) {
showError(alertsEl, "加载章节失败: " + err.message);
}
}
async function loadContext() {
const el = document.getElementById("cwContext");
try {
const ctx = await fetchJson("/api/chapters/" + CHAPTER_ID + "/context");
let html = "";
html += " 第" + s.volume + "卷 第" + s.chapter_number + "章 "
+ escapeHtml(s.title || "") + ": " + escapeHtml(s.summary) + " 无 无 (这是第一章) " + escapeHtml(c.name) + " ("
+ escapeHtml(c.role || "") + "): "
+ escapeHtml((c.description || "").slice(0, 200)) + " 无 " + escapeHtml(f.description) + " 无前文摘要 ("
+ ctx.earlier_summaries.length + ")
";
html += ctx.earlier_summaries.length
? ctx.earlier_summaries.map((s) =>
"前章正文 ("
+ ctx.prev_chapters.length + ")
";
html += ctx.prev_chapters.length
? ctx.prev_chapters.map((c) =>
"第" + c.volume + "卷 第"
+ c.chapter_number + "章 " + escapeHtml(c.title || "") + "
"
+ ""
+ escapeHtml(c.content) + "相关角色 ("
+ ctx.characters.length + ")
";
html += ctx.characters.length
? ctx.characters.map((c) =>
"未回收伏笔 ("
+ ctx.open_foreshadowing.length + ")
";
html += ctx.open_foreshadowing.length
? ctx.open_foreshadowing.map((f) =>
"
上下文总大小: ' + ctx.total_chars + " 字符
"; el.innerHTML = html; } catch (err) { el.innerHTML = '