@musnows/scriverse 0.4.9 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +112 -22
- package/dist/app.js.map +1 -1
- package/dist/collaboration-presence.js +77 -2
- package/dist/collaboration-presence.js.map +1 -1
- package/dist/public/app.js +68 -9
- package/dist/public/display-labels.d.ts +1 -0
- package/dist/public/display-labels.js +8 -0
- package/dist/public/index.html +35 -33
- package/dist/public/markdown.js +16 -0
- package/dist/public/styles.css +20 -9
- package/dist/store.js +3 -3
- package/dist/store.js.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collaboration-presence.js","sourceRoot":"","sources":["../src/collaboration-presence.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,eAAe;IACf,UAAU;CACF,CAAC;
|
|
1
|
+
{"version":3,"file":"collaboration-presence.js","sourceRoot":"","sources":["../src/collaboration-presence.ts"],"names":[],"mappings":"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"}
|
package/dist/public/app.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { buildRelationshipGraph, createGalaxyRenderer, renderRelationshipMindMap } from "/relationship-graph.js?v=20260725-galaxy-ripple";
|
|
2
2
|
import { collapseExcessBlankLines, formatDateTime, normalizeParagraphSpacing } from "/text-formatting.js?v=20260713-saved-at-seconds";
|
|
3
|
-
import { renderMarkdown } from "/markdown.js?v=
|
|
3
|
+
import { renderMarkdown } from "/markdown.js?v=20260725-ordered-list";
|
|
4
4
|
import { buildAiReferenceScope, findAiMention, listAiMentionOptions } from "/ai-mentions.js?v=20260716-chapter-references";
|
|
5
5
|
import { shouldShowAiQuickActions } from "/ai-conversation.js?v=20260713-quick-actions";
|
|
6
6
|
import { calculateLineNumberRowHeight, calculateLineNumberRowTop, calculateLineNumberTextOffset, calculateLineNumberTop } from "/line-number-layout.js?v=20260713-row-box-alignment";
|
|
@@ -29,8 +29,9 @@ import {
|
|
|
29
29
|
searchResultTypeLabel,
|
|
30
30
|
settingStatusLabel,
|
|
31
31
|
taskScopeLabel,
|
|
32
|
-
timelineStatusLabel
|
|
33
|
-
|
|
32
|
+
timelineStatusLabel,
|
|
33
|
+
characterStateFieldLabel
|
|
34
|
+
} from "/display-labels.js?v=20260725-state-field-zh";
|
|
34
35
|
import { parsePageRoute, serializePageRoute } from "/page-route.js?v=20260723-knowledge-editor-page";
|
|
35
36
|
import { splitRelationshipKeywordInput, splitRelationshipKeywords, uniqueRelationshipKeywords } from "/relationship-keywords.js?v=20260720-relationship-keyword-chips";
|
|
36
37
|
import { tokenizeVisibleSpaces } from "/whitespace-visualization.js?v=20260718-visible-whitespace";
|
|
@@ -97,6 +98,9 @@ let presenceParticipants = [];
|
|
|
97
98
|
let presenceHeartbeatTimer = null;
|
|
98
99
|
let presenceHeartbeatQueued = null;
|
|
99
100
|
let presenceHeartbeatRequest = 0;
|
|
101
|
+
const acknowledgedCollaborativeChangeIds = new Set();
|
|
102
|
+
let collaborativeChangePromptOpen = false;
|
|
103
|
+
let peerPageStale = false;
|
|
100
104
|
let collaborationAutoSaveDisabled = false;
|
|
101
105
|
|
|
102
106
|
let timelineMultiSelectEnabled = false;
|
|
@@ -547,14 +551,16 @@ async function refreshPresence() {
|
|
|
547
551
|
return [];
|
|
548
552
|
}
|
|
549
553
|
try {
|
|
550
|
-
const
|
|
554
|
+
const payload = await api(`/api/works/${encodeURIComponent(workId)}/presence`, {
|
|
551
555
|
method: "POST",
|
|
552
556
|
body: { clientId: presenceClientId, page },
|
|
553
557
|
skipOptimisticVersion: true
|
|
554
558
|
});
|
|
555
559
|
if (state.work?.id === workId && presenceHeartbeatRequest === requestId) {
|
|
556
|
-
presenceParticipants = participants;
|
|
560
|
+
presenceParticipants = Array.isArray(payload) ? payload : (payload?.participants ?? []);
|
|
557
561
|
renderPresence();
|
|
562
|
+
const recentChanges = Array.isArray(payload) ? [] : (payload?.recentChanges ?? []);
|
|
563
|
+
void handleCollaborativeChanges(recentChanges);
|
|
558
564
|
}
|
|
559
565
|
} catch {
|
|
560
566
|
if (state.work?.id === workId) renderPresence();
|
|
@@ -564,6 +570,58 @@ async function refreshPresence() {
|
|
|
564
570
|
return presenceParticipants;
|
|
565
571
|
}
|
|
566
572
|
|
|
573
|
+
function localEditingDirty() {
|
|
574
|
+
return Boolean(state.dirty || entityEditorDirty || characterSectionEditorDirty || knowledgeSectionEditorDirty);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
async function handleCollaborativeChanges(recentChanges) {
|
|
578
|
+
if (!Array.isArray(recentChanges) || !recentChanges.length || collaborativeChangePromptOpen) return;
|
|
579
|
+
const localKey = presencePageKey(presencePageForRoute());
|
|
580
|
+
if (!localKey) return;
|
|
581
|
+
const selfId = state.user?.userId;
|
|
582
|
+
const incoming = recentChanges.filter((change) => (
|
|
583
|
+
change
|
|
584
|
+
&& change.pageKey === localKey
|
|
585
|
+
&& change.actorUserId
|
|
586
|
+
&& change.actorUserId !== selfId
|
|
587
|
+
&& change.id
|
|
588
|
+
&& !acknowledgedCollaborativeChangeIds.has(change.id)
|
|
589
|
+
));
|
|
590
|
+
if (!incoming.length) return;
|
|
591
|
+
const latest = incoming[0];
|
|
592
|
+
for (const change of incoming) acknowledgedCollaborativeChangeIds.add(change.id);
|
|
593
|
+
while (acknowledgedCollaborativeChangeIds.size > 200) {
|
|
594
|
+
const oldest = acknowledgedCollaborativeChangeIds.values().next().value;
|
|
595
|
+
acknowledgedCollaborativeChangeIds.delete(oldest);
|
|
596
|
+
}
|
|
597
|
+
peerPageStale = true;
|
|
598
|
+
collaborativeChangePromptOpen = true;
|
|
599
|
+
const dirtyHint = localEditingDirty()
|
|
600
|
+
? "你当前页面还有未保存修改。请先把正在编辑的内容复制保存到别处(本页无法代为另存),再刷新页面后重新提交。"
|
|
601
|
+
: "请先确认本地没有需要保留的草稿;如有,请复制保存到别处(本页无法代为另存),再刷新页面后继续编辑。";
|
|
602
|
+
try {
|
|
603
|
+
const shouldReload = await confirmToast(`${latest.actorDisplayName || "协作者"}已更新「${latest.label || "当前页面"}」。${dirtyHint}`, {
|
|
604
|
+
title: "协作者已更新",
|
|
605
|
+
confirmLabel: "刷新页面",
|
|
606
|
+
cancelLabel: "稍后处理"
|
|
607
|
+
});
|
|
608
|
+
if (shouldReload) window.location.reload();
|
|
609
|
+
} finally {
|
|
610
|
+
collaborativeChangePromptOpen = false;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
async function confirmPeerStaleSave() {
|
|
615
|
+
if (!peerPageStale) return true;
|
|
616
|
+
const confirmed = await confirmToast("协作者已更新当前页面。请先把正在编辑的内容复制保存到别处(本页无法代为另存),再刷新页面后重新提交。继续保存可能覆盖对方修改或触发冲突。", {
|
|
617
|
+
title: "页面内容已过期",
|
|
618
|
+
confirmLabel: "仍然保存",
|
|
619
|
+
cancelLabel: "暂不保存"
|
|
620
|
+
});
|
|
621
|
+
if (confirmed) peerPageStale = false;
|
|
622
|
+
return confirmed;
|
|
623
|
+
}
|
|
624
|
+
|
|
567
625
|
function schedulePresenceHeartbeat() {
|
|
568
626
|
if (presenceHeartbeatQueued !== null) clearTimeout(presenceHeartbeatQueued);
|
|
569
627
|
presenceHeartbeatQueued = setTimeout(() => {
|
|
@@ -574,6 +632,7 @@ function schedulePresenceHeartbeat() {
|
|
|
574
632
|
|
|
575
633
|
async function confirmConcurrentSave() {
|
|
576
634
|
await refreshPresence();
|
|
635
|
+
if (!(await confirmPeerStaleSave())) return false;
|
|
577
636
|
const localKey = presencePageKey(presencePageForRoute());
|
|
578
637
|
const peers = presenceParticipants.filter((participant) => participant.clientId !== presenceClientId && participant.page.key === localKey);
|
|
579
638
|
if (!peers.length) return true;
|
|
@@ -2735,7 +2794,7 @@ function resetWorkScopedUiCaches() {
|
|
|
2735
2794
|
async function selectWork(workId, preferredChapterId = null) {
|
|
2736
2795
|
const discarding = state.work?.id !== workId && state.dirty;
|
|
2737
2796
|
if (discarding && !(await confirmDiscardChanges())) return false;
|
|
2738
|
-
const nextWork = await api(`/api/works/${workId}
|
|
2797
|
+
const nextWork = await api(`/api/works/${workId}`);
|
|
2739
2798
|
if (state.work?.id !== nextWork.id) resetWorkScopedUiCaches();
|
|
2740
2799
|
if (discarding) setSaveState("就绪");
|
|
2741
2800
|
$("#app").classList.remove("shelf-mode");
|
|
@@ -3403,14 +3462,14 @@ async function renderCharacters(page = characterListPage) {
|
|
|
3403
3462
|
${item.aliases.length ? `<div class="character-aliases"><b>别名</b>${item.aliases.map((alias) => `<span class="pill">${esc(alias)}</span>`).join("")}</div>` : ""}
|
|
3404
3463
|
${item.code ? `<div class="character-code"><b>编号</b><span class="pill">${esc(item.code)}</span></div>` : ""}
|
|
3405
3464
|
${item.species ? `<div class="character-species"><b>种族</b><span class="pill">${esc(racePathLabel(item.race) || item.species)}</span></div>` : ""}
|
|
3406
|
-
${details.length ? `<dl class="character-detail-list">${details.slice(0, 4).map((detail) => `<div><dt>${esc(detail.label)}</dt><dd>${esc(detail.value)}</dd></div>`).join("")}</dl>` : ""}
|
|
3465
|
+
${details.length ? `<dl class="character-detail-list">${details.slice(0, 4).map((detail) => `<div><dt>${esc(characterStateFieldLabel(detail.label))}</dt><dd>${esc(detail.value)}</dd></div>`).join("")}</dl>` : ""}
|
|
3407
3466
|
<div class="organization-links"><b>所属组织</b>${(item.organizations ?? []).length ? item.organizations.map((organization) => `<span class="pill organization-pill">${esc(organization.name)}</span>`).join("") : '<span class="organization-empty">未加入组织</span>'}</div>
|
|
3408
|
-
${item.profile?.summary ? `<p class="character-summary">${esc(item.profile.summary)}</p>` : `<p>${esc(Object.entries(item.currentState).map(([key, value]) => `${key}:${value}`).join("\n") || "尚未记录当前状态")}</p>`}
|
|
3467
|
+
${item.profile?.summary ? `<p class="character-summary">${esc(item.profile.summary)}</p>` : `<p>${esc(Object.entries(item.currentState).map(([key, value]) => `${characterStateFieldLabel(key)}:${value}`).join("\n") || "尚未记录当前状态")}</p>`}
|
|
3409
3468
|
${item.profileSectionCount ? `<small class="character-section-count">${item.profileSectionCount} 个设定章节</small>` : ""}
|
|
3410
3469
|
</article>`;
|
|
3411
3470
|
}).join("")}</div>`;
|
|
3412
3471
|
const characterRows = () => `<div class="module-row-list">${state.characters.map((item) => {
|
|
3413
|
-
const preview = moduleRowPreview(item.profile?.summary || item.attributes?.identity || Object.entries(item.currentState).map(([key, value]) => `${key}:${value}`).join(" ") || "尚未记录当前状态");
|
|
3472
|
+
const preview = moduleRowPreview(item.profile?.summary || item.attributes?.identity || Object.entries(item.currentState).map(([key, value]) => `${characterStateFieldLabel(key)}:${value}`).join(" ") || "尚未记录当前状态");
|
|
3414
3473
|
const meta = [
|
|
3415
3474
|
item.code ? `编号 ${item.code}` : "",
|
|
3416
3475
|
item.species ? (racePathLabel(item.race) || item.species) : "",
|
|
@@ -13,3 +13,4 @@ export function providerConnectionLabel(value: unknown): string;
|
|
|
13
13
|
export function chapterVersionSourceLabel(value: unknown): string;
|
|
14
14
|
export function occurrenceRoleLabel(value: unknown): string;
|
|
15
15
|
export function searchResultTypeLabel(value: unknown): string;
|
|
16
|
+
export function characterStateFieldLabel(value: unknown): string;
|
|
@@ -75,3 +75,11 @@ export function occurrenceRoleLabel(value) {
|
|
|
75
75
|
export function searchResultTypeLabel(value) {
|
|
76
76
|
return enumLabel({ chapter: "章节", setting: "设定", character: "角色", race: "种族", organization: "组织" }, value, "其他资料");
|
|
77
77
|
}
|
|
78
|
+
|
|
79
|
+
export function characterStateFieldLabel(value) {
|
|
80
|
+
const normalized = String(value ?? "").trim();
|
|
81
|
+
return enumLabel({
|
|
82
|
+
location: "位置",
|
|
83
|
+
condition: "状况"
|
|
84
|
+
}, normalized, normalized || "未命名字段");
|
|
85
|
+
}
|
package/dist/public/index.html
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<link rel="icon" href="/icon.svg?v=20260712" type="image/svg+xml">
|
|
11
11
|
<link rel="manifest" href="/site.webmanifest">
|
|
12
12
|
<link rel="stylesheet" href="/vendor/vditor/dist/index.css?v=3.11.2">
|
|
13
|
-
<link rel="stylesheet" href="/styles.css?v=20260725-module-
|
|
13
|
+
<link rel="stylesheet" href="/styles.css?v=20260725-module-count-vditor-left-panel">
|
|
14
14
|
</head>
|
|
15
15
|
<body class="auth-pending">
|
|
16
16
|
<section id="auth-view" class="auth-view hidden" aria-labelledby="auth-title">
|
|
@@ -105,40 +105,42 @@
|
|
|
105
105
|
|
|
106
106
|
<aside class="left-panel">
|
|
107
107
|
<div id="left-panel-resize" class="panel-resize-handle" role="separator" aria-label="调整作品侧栏宽度" aria-orientation="vertical" tabindex="0"></div>
|
|
108
|
-
<div class="left-
|
|
109
|
-
<div class="left-
|
|
110
|
-
<
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
108
|
+
<div class="left-panel-body">
|
|
109
|
+
<div class="left-actions">
|
|
110
|
+
<div class="left-primary-actions">
|
|
111
|
+
<label id="import-file-button" class="file-button" aria-label="导入 TXT / DOCX">
|
|
112
|
+
<span class="import-file-label import-file-label-full" aria-hidden="true">导入 TXT / DOCX</span>
|
|
113
|
+
<span class="import-file-label import-file-label-compact" aria-hidden="true">导入TXT/DOCX</span>
|
|
114
|
+
<span class="import-file-label import-file-label-short" aria-hidden="true">导入</span>
|
|
115
|
+
<input id="import-file" type="file" accept=".txt,.docx">
|
|
116
|
+
</label>
|
|
117
|
+
<button id="left-panel-toggle" class="panel-collapse-button" type="button" aria-label="收起作品侧栏" aria-expanded="true">‹</button>
|
|
118
|
+
</div>
|
|
117
119
|
</div>
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
120
|
+
<nav id="module-nav" class="module-nav" aria-label="作品模块">
|
|
121
|
+
<button type="button" data-module="editor" class="active"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>正文</button>
|
|
122
|
+
<button type="button" data-module="settings"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m16 6 4 14"/><path d="M12 6v14"/><path d="M8 8v12"/><path d="M4 4v16"/></svg>设定库</button>
|
|
123
|
+
<button type="button" data-module="characters"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>角色</button>
|
|
124
|
+
<button type="button" data-module="organizations"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>组织</button>
|
|
125
|
+
<button type="button" data-module="timeline"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>时间轴</button>
|
|
126
|
+
<button type="button" data-module="relationships"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="m8.59 13.51 6.83 3.98"/><path d="m15.41 6.51-6.82 3.98"/></svg>关系</button>
|
|
127
|
+
<button type="button" data-module="races"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="4" r="2"/><circle cx="18" cy="8" r="2"/><circle cx="20" cy="16" r="2"/><path d="M9 10a5 5 0 0 1 5 5v3.5a3.5 3.5 0 0 1-6.84 1.045Q6.52 17.48 4.46 16.84A3.5 3.5 0 0 1 5.5 10Z"/></svg>种族</button>
|
|
128
|
+
<button class="ai-analysis-entry" type="button" data-module="tasks"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/><path d="M20 3v4"/><path d="M22 5h-4"/><path d="M4 17v2"/><path d="M5 18H3"/></svg>AI 分析</button>
|
|
129
|
+
<button id="module-more-button" type="button" aria-expanded="false"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg><span class="nav-label">更多</span></button>
|
|
130
|
+
<button class="module-nav-secondary hidden" type="button" data-module="outlines"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/></svg><span class="nav-label">大纲/伏笔</span></button>
|
|
131
|
+
<button class="module-nav-secondary hidden" type="button" data-module="reviews"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="m9 14 2 2 4-4"/></svg>审核</button>
|
|
132
|
+
<button class="module-nav-secondary hidden" type="button" data-module="ai-settings"><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><rect width="16" height="16" x="4" y="4" rx="2"/><rect width="6" height="6" x="9" y="9" rx="1"/><path d="M15 2v2"/><path d="M15 20v2"/><path d="M2 15h2"/><path d="M2 9h2"/><path d="M20 15h2"/><path d="M20 9h2"/><path d="M9 2v2"/><path d="M9 20v2"/></svg>AI 设置</button>
|
|
133
|
+
<button class="module-nav-secondary hidden" type="button" data-work-settings><svg class="nav-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.09a2 2 0 0 1 1 1.74v.5a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.38a2 2 0 0 0-.73-2.73l-.15-.09a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2Z"/><circle cx="12" cy="12" r="3"/></svg>作品设置</button>
|
|
134
|
+
</nav>
|
|
135
|
+
<div class="panel-heading">
|
|
136
|
+
<span>作品目录</span>
|
|
137
|
+
<div class="panel-heading-actions">
|
|
138
|
+
<span id="chapter-count">0 章</span>
|
|
139
|
+
<button id="new-volume-button" class="add-button" type="button" aria-label="新建分卷" title="新建分卷">+</button>
|
|
140
|
+
</div>
|
|
139
141
|
</div>
|
|
142
|
+
<div id="novel-tree" class="novel-tree empty-copy">创建或选择作品后开始写作</div>
|
|
140
143
|
</div>
|
|
141
|
-
<div id="novel-tree" class="novel-tree empty-copy">创建或选择作品后开始写作</div>
|
|
142
144
|
</aside>
|
|
143
145
|
|
|
144
146
|
<main id="main-panel" class="main-panel">
|
|
@@ -731,6 +733,6 @@
|
|
|
731
733
|
<div id="auth-loading" class="auth-loading" role="status" aria-label="正在载入工作台"></div>
|
|
732
734
|
<script id="vditorIconScript" src="/vendor/vditor/dist/js/icons/ant.js?v=3.11.2"></script>
|
|
733
735
|
<script src="/vendor/vditor/dist/index.min.js?v=3.11.2"></script>
|
|
734
|
-
<script type="module" src="/app.js?v=20260725-
|
|
736
|
+
<script type="module" src="/app.js?v=20260725-collab-refresh-left-panel-resize"></script>
|
|
735
737
|
</body>
|
|
736
738
|
</html>
|
package/dist/public/markdown.js
CHANGED
|
@@ -199,6 +199,22 @@ export function renderMarkdown(value) {
|
|
|
199
199
|
}
|
|
200
200
|
flushQuote();
|
|
201
201
|
if (!line.trim()) {
|
|
202
|
+
// CommonMark 松散列表:同类型列表项之间的空行不结束列表,
|
|
203
|
+
// 否则每个条目会各自生成 <ol>/<ul>,有序序号会全部显示为 1。
|
|
204
|
+
if (list) {
|
|
205
|
+
let nextIndex = lineIndex + 1;
|
|
206
|
+
while (nextIndex < lines.length && !lines[nextIndex].trim()) nextIndex += 1;
|
|
207
|
+
if (nextIndex < lines.length) {
|
|
208
|
+
const nextListItem = lines[nextIndex].match(/^(\s*)([-+*]|\d+\.)\s+(.+)$/u);
|
|
209
|
+
if (nextListItem) {
|
|
210
|
+
const nextTag = /\d+\./u.test(nextListItem[2]) ? "ol" : "ul";
|
|
211
|
+
if (nextTag === list.tag) {
|
|
212
|
+
flushParagraph();
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
202
218
|
flushBlocks();
|
|
203
219
|
continue;
|
|
204
220
|
}
|
package/dist/public/styles.css
CHANGED
|
@@ -485,7 +485,8 @@ input[type="checkbox"][hidden] { display: none; }
|
|
|
485
485
|
@keyframes onboarding-popover-in { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } }
|
|
486
486
|
|
|
487
487
|
.left-panel, .ai-panel { position: relative; min-height: 0; background: var(--panel); }
|
|
488
|
-
.left-panel { border-right: 1px solid var(--line); padding:
|
|
488
|
+
.left-panel { display: flex; flex-direction: column; border-right: 1px solid var(--line); padding: 0; overflow: hidden; }
|
|
489
|
+
.left-panel-body { flex: 1 1 auto; min-height: 0; padding: 18px 14px 16px; overflow-y: auto; }
|
|
489
490
|
.ai-panel { border-left: 1px solid var(--line); display: flex; flex-direction: column; padding: 18px; min-width: 0; }
|
|
490
491
|
.panel-collapse-button { z-index: 8; flex: 0 0 auto; width: 24px; height: 24px; padding: 0; border: 1px solid var(--line); border-radius: 4px; background: var(--panel); color: var(--muted); font-size: 18px; line-height: 1; }
|
|
491
492
|
.ai-heading #ai-panel-toggle { flex-basis: 30px; width: 30px; height: 30px; }
|
|
@@ -496,7 +497,10 @@ input[type="checkbox"][hidden] { display: none; }
|
|
|
496
497
|
body.is-panel-resizing { cursor: col-resize; user-select: none; }
|
|
497
498
|
.app-shell.left-panel-collapsed { --left-panel-width: 42px !important; }.app-shell.ai-panel-collapsed { --ai-panel-width: 42px !important; }
|
|
498
499
|
.app-shell.left-panel-collapsed .left-panel, .app-shell.ai-panel-collapsed .ai-panel { padding: 0; overflow: hidden; }
|
|
499
|
-
.app-shell.left-panel-collapsed .left-panel >
|
|
500
|
+
.app-shell.left-panel-collapsed .left-panel > .panel-resize-handle,
|
|
501
|
+
.app-shell.left-panel-collapsed .left-panel-body > :not(.left-actions),
|
|
502
|
+
.app-shell.ai-panel-collapsed .ai-panel > :not(.ai-heading) { display: none; }
|
|
503
|
+
.app-shell.left-panel-collapsed .left-panel-body { padding: 0; overflow: hidden; }
|
|
500
504
|
.app-shell.left-panel-collapsed .left-actions, .app-shell.ai-panel-collapsed .ai-heading { display: flex; justify-content: center; padding: 8px 0; border: 0; }
|
|
501
505
|
.app-shell.left-panel-collapsed .left-actions > :not(.left-primary-actions), .app-shell.left-panel-collapsed .left-primary-actions > :not(.panel-collapse-button), .app-shell.ai-panel-collapsed .ai-heading > :not(.panel-collapse-button) { display: none; }
|
|
502
506
|
.app-shell.left-panel-collapsed .left-primary-actions { display: flex; justify-content: center; }
|
|
@@ -1018,6 +1022,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1018
1022
|
.module-header { display: flex; justify-content: space-between; align-items: flex-end; gap: 18px; padding-bottom: 24px; border-bottom: 1px solid var(--line); }
|
|
1019
1023
|
.module-header-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
|
|
1020
1024
|
.module-header-actions > [data-module-header-action] { order: 1; }
|
|
1025
|
+
.module-header-actions > .module-count-badge { order: 0; }
|
|
1021
1026
|
.module-header-actions > #module-create-button { order: 2; min-height: 36px; }
|
|
1022
1027
|
.module-count-badge { display: inline-grid; min-width: 28px; height: 28px; padding: 0 7px; place-items: center; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); color: var(--accent-dark); font-family: var(--font-latin), monospace; font-size: 11px; font-weight: 650; }
|
|
1023
1028
|
.module-header h1 { margin: 0 0 6px; font-weight: 500; font-size: 24px; line-height: 1.25; }
|
|
@@ -1859,6 +1864,10 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1859
1864
|
.vditor-editor-host .vditor-reset { color: var(--ink); font-family: var(--font-cjk), var(--font-latin), sans-serif; }
|
|
1860
1865
|
.vditor-editor-host .vditor-ir, .vditor-editor-host .vditor-sv, .vditor-editor-host .vditor-wysiwyg { background: var(--surface); color: var(--ink); }
|
|
1861
1866
|
.vditor-editor-host .vditor-sv textarea { color: var(--ink); }
|
|
1867
|
+
.vditor-editor-host.vditor--dark .vditor-reset table { background: var(--surface); color: var(--ink); }
|
|
1868
|
+
.vditor-editor-host.vditor--dark .vditor-reset table tr { background: var(--surface); border-top-color: var(--line); }
|
|
1869
|
+
.vditor-editor-host.vditor--dark .vditor-reset table td, .vditor-editor-host.vditor--dark .vditor-reset table th { border-color: var(--line); color: var(--ink); }
|
|
1870
|
+
.vditor-editor-host.vditor--dark .vditor-reset table tbody tr:nth-child(2n) { background: var(--surface-soft); }
|
|
1862
1871
|
.record-markdown-preview { display: -webkit-box; margin: 12px 0 8px; overflow: hidden; overflow-wrap: anywhere; color: var(--ink); font-size: 12px; line-height: 1.7; -webkit-box-orient: vertical; -webkit-line-clamp: 12; }
|
|
1863
1872
|
.record-markdown-preview > :first-child, .knowledge-markdown-block .message-body > :first-child { margin-top: 0; }
|
|
1864
1873
|
.record-markdown-preview > :last-child, .knowledge-markdown-block .message-body > :last-child { margin-bottom: 0; }
|
|
@@ -2058,7 +2067,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2058
2067
|
}
|
|
2059
2068
|
|
|
2060
2069
|
@media (max-width: 1100px) {
|
|
2061
|
-
.left-panel { padding-inline: 10px; }
|
|
2070
|
+
.left-panel-body { padding-inline: 10px; }
|
|
2062
2071
|
.ai-panel { padding-inline: 14px; }
|
|
2063
2072
|
.editor-toolbar { grid-template-areas: "path" "title" "actions"; grid-template-columns: minmax(0, 1fr); gap: 12px; padding-inline: 6%; }
|
|
2064
2073
|
.editor-actions { justify-content: flex-end; flex-wrap: wrap; }
|
|
@@ -2197,17 +2206,19 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2197
2206
|
grid-column: auto;
|
|
2198
2207
|
grid-row: auto;
|
|
2199
2208
|
min-width: 0;
|
|
2200
|
-
padding:
|
|
2209
|
+
padding: 0;
|
|
2201
2210
|
border-left: 1px solid var(--line);
|
|
2202
2211
|
border-bottom: 1px solid var(--line);
|
|
2203
2212
|
box-shadow: -12px 0 36px rgba(36, 30, 24, .2);
|
|
2204
|
-
overflow
|
|
2213
|
+
overflow: hidden;
|
|
2205
2214
|
transform: translateX(0);
|
|
2206
2215
|
transition: transform .2s ease;
|
|
2207
2216
|
}
|
|
2208
|
-
.
|
|
2209
|
-
.app-shell.left-panel-collapsed .left-panel
|
|
2210
|
-
.app-shell.left-panel-collapsed .left-panel > .
|
|
2217
|
+
.left-panel-body { padding: 76px var(--mobile-gutter) 18px; }
|
|
2218
|
+
.app-shell.left-panel-collapsed .left-panel { transform: translateX(100%); }
|
|
2219
|
+
.app-shell.left-panel-collapsed .left-panel > .panel-resize-handle { display: none; }
|
|
2220
|
+
.app-shell.left-panel-collapsed .left-panel-body > :not(.left-actions) { display: block; }
|
|
2221
|
+
.app-shell.left-panel-collapsed .left-panel-body > .module-nav { display: grid; }
|
|
2211
2222
|
.left-panel > .panel-resize-handle { display: none; }
|
|
2212
2223
|
.left-actions { margin: 0 0 8px; }
|
|
2213
2224
|
.left-primary-actions { gap: 6px; }
|
|
@@ -2223,7 +2234,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2223
2234
|
.module-nav .nav-icon { width: 16px; height: 16px; }
|
|
2224
2235
|
.module-nav .module-nav-secondary.hidden { display: none !important; }
|
|
2225
2236
|
.panel-heading, #novel-tree { display: none; }
|
|
2226
|
-
.app-shell.left-panel-collapsed .left-panel { padding: 8px var(--mobile-gutter) 0; }
|
|
2237
|
+
.app-shell.left-panel-collapsed .left-panel-body { padding: 8px var(--mobile-gutter) 0; }
|
|
2227
2238
|
.app-shell.left-panel-collapsed .left-actions { display: block; padding: 0; }
|
|
2228
2239
|
|
|
2229
2240
|
.main-panel {
|
package/dist/store.js
CHANGED
|
@@ -764,9 +764,9 @@ export class Store {
|
|
|
764
764
|
const chapterRows = this.db.all(`SELECT id, work_id, volume_id, title, chapter_type, sort_order, word_count, version_no,
|
|
765
765
|
analysis_status, excluded_from_analysis, created_at, updated_at
|
|
766
766
|
FROM chapters WHERE work_id = ? ORDER BY sort_order, created_at${page.sql}`, workId, ...page.params);
|
|
767
|
-
const
|
|
767
|
+
const pageResult = paginated(chapterRows.map((row) => this.mapChapterDirectoryEntry(row)), pagination);
|
|
768
768
|
const chaptersByVolume = new Map();
|
|
769
|
-
for (const chapter of
|
|
769
|
+
for (const chapter of pageResult.items) {
|
|
770
770
|
const volumeId = String(chapter.volumeId);
|
|
771
771
|
const list = chaptersByVolume.get(volumeId) ?? [];
|
|
772
772
|
list.push(chapter);
|
|
@@ -776,7 +776,7 @@ export class Store {
|
|
|
776
776
|
...this.mapVolume(row),
|
|
777
777
|
chapters: chaptersByVolume.get(requiredString(row, "id")) ?? []
|
|
778
778
|
}));
|
|
779
|
-
return { ...work, volumes, directoryPage:
|
|
779
|
+
return { ...work, volumes, directoryPage: pageResult };
|
|
780
780
|
}
|
|
781
781
|
listFileVersions(workId) {
|
|
782
782
|
this.getWork(workId);
|