sage-mem 1.5.2 → 1.5.3
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/lib/client.js +108 -82
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -3741,6 +3741,97 @@ h("span", { key: "sep", className: "smem-actions-sep", "aria-hidden": "true" }),
|
|
|
3741
3741
|
notice ? h("div", { className: "smem-ok", key: "ok" }, "✓ " + notice) : null,
|
|
3742
3742
|
]);
|
|
3743
3743
|
}
|
|
3744
|
+
// ── 文件列表这一屏(1.5.3 从 Section 里抽出;D23 计划的 72 片)──────────
|
|
3745
|
+
// 只负责「按状态/筛选把卡片摆出来 + 四种空态」;状态、筛选语义、动作回调全部由 Section 传。
|
|
3746
|
+
// 抽出的判据:它是 Section 里最大的一块纯渲染,而卡片组件(Card / ArchivedCard)本来就在 50 共享层。
|
|
3747
|
+
function FilesView(props) {
|
|
3748
|
+
const { loading, totalCount, openAdd, statusFilter, setStatusFilter, items, archiveItems, filtered, setTypeFilter, setTagFilter, setQuery, busy, restoring, archDelete, archEdit, archLoad, archSaving, archText, setArchText, openArchEdit, saveArchEdit, cancelArchEdit, restoreFile, setArchDelete, setArchEdit, deleteArchivedFile, expanded, deleting, archiving, archiveReason, setArchiveReason, setArchiving, setDeleting, confirmArchive, toggleLock, openEdit, confirmDelete } = props;
|
|
3749
|
+
let filesView;
|
|
3750
|
+
if (loading && totalCount === 0) {
|
|
3751
|
+
filesView = h("div", { className: "smem-skeleton", key: "loading", "data-loading": "1" }, [0, 1, 2].map(function (i) {
|
|
3752
|
+
return h("div", { className: "smem-skeleton-row", key: i });
|
|
3753
|
+
}));
|
|
3754
|
+
} else if (totalCount === 0) {
|
|
3755
|
+
filesView = h("div", { className: "smem-empty", key: "empty" }, [
|
|
3756
|
+
h("div", { key: "t" }, "还没有记忆文件。对话中值得记住的事会写到这里,也可以手动写入。"),
|
|
3757
|
+
h("button", { type: "button", className: "smem-btn smem-btn-primary", key: "add", onClick: openAdd }, "+ 添加记忆"),
|
|
3758
|
+
]);
|
|
3759
|
+
} else if (statusFilter === "archived" && archiveItems.length === 0) {
|
|
3760
|
+
filesView = h("div", { className: "smem-empty", key: "empty" }, [
|
|
3761
|
+
h("div", { key: "t" }, "档案馆是空的 —— 在活动记忆那张卡上点「归档」,它就会收到这里。"),
|
|
3762
|
+
h("button", { type: "button", className: "smem-btn", key: "back", onClick: function () { setStatusFilter("active"); } }, "回文件列表"),
|
|
3763
|
+
]);
|
|
3764
|
+
} else if (statusFilter === "active" && items.length === 0) {
|
|
3765
|
+
filesView = h("div", { className: "smem-empty", key: "empty" }, [
|
|
3766
|
+
h("div", { key: "t" }, "活动记忆是空的 —— 状态筛到「已归档」还能捞出 " + archiveItems.length + " 条。"),
|
|
3767
|
+
h("button", { type: "button", className: "smem-btn", key: "go", onClick: function () { setStatusFilter("archived"); } }, "切到已归档"),
|
|
3768
|
+
]);
|
|
3769
|
+
} else if (filtered.length === 0) {
|
|
3770
|
+
filesView = h("div", { className: "smem-empty", key: "empty" }, [
|
|
3771
|
+
h("div", { key: "t" }, "没有符合搜索或筛选条件的文件。"),
|
|
3772
|
+
h("button", { type: "button", className: "smem-btn", key: "clear", onClick: function () { setStatusFilter("all"); setTypeFilter([]); setTagFilter([]); setQuery(""); } }, "清除筛选"),
|
|
3773
|
+
]);
|
|
3774
|
+
} else {
|
|
3775
|
+
const list = h("div", { className: "smem-list", key: "list" }, filtered.map(function (it) {
|
|
3776
|
+
if (it.archived === true) {
|
|
3777
|
+
return h(ArchivedCard, {
|
|
3778
|
+
key: it.file,
|
|
3779
|
+
item: it,
|
|
3780
|
+
busy: busy,
|
|
3781
|
+
restoring: restoring === it.file,
|
|
3782
|
+
deleting: archDelete === it.file,
|
|
3783
|
+
editing: archEdit === it.file,
|
|
3784
|
+
loading: archLoad && archEdit === it.file,
|
|
3785
|
+
saving: archSaving && archEdit === it.file,
|
|
3786
|
+
text: archText,
|
|
3787
|
+
onText: setArchText,
|
|
3788
|
+
onEdit: openArchEdit,
|
|
3789
|
+
onSave: saveArchEdit,
|
|
3790
|
+
onCancel: cancelArchEdit,
|
|
3791
|
+
onRestore: restoreFile,
|
|
3792
|
+
// 两个「危险动作的确认」互斥:问到一半又去改文本,界面就会同时摆两个确认条。
|
|
3793
|
+
onAskDelete: function (file) { setArchDelete(file); setArchEdit(null); },
|
|
3794
|
+
onCancelDelete: function () { setArchDelete(null); },
|
|
3795
|
+
onConfirmDelete: deleteArchivedFile,
|
|
3796
|
+
});
|
|
3797
|
+
}
|
|
3798
|
+
return h(Card, {
|
|
3799
|
+
key: it.file,
|
|
3800
|
+
item: it,
|
|
3801
|
+
expanded: !!expanded[it.file],
|
|
3802
|
+
deleting: deleting === it.file,
|
|
3803
|
+
archiving: archiving === it.file,
|
|
3804
|
+
archiveReason: archiveReason,
|
|
3805
|
+
busy: busy,
|
|
3806
|
+
onArchiveReason: setArchiveReason,
|
|
3807
|
+
onAskArchive: function (file) { setArchiving(file); setArchiveReason(""); setDeleting(null); },
|
|
3808
|
+
onCancelArchive: function () { setArchiving(null); setArchiveReason(""); },
|
|
3809
|
+
onConfirmArchive: confirmArchive,
|
|
3810
|
+
onToggleLock: toggleLock,
|
|
3811
|
+
onToggle: function (file) {
|
|
3812
|
+
const nx = {};
|
|
3813
|
+
nx[file] = !expanded[file];
|
|
3814
|
+
setExpanded(Object.assign({}, expanded, nx));
|
|
3815
|
+
},
|
|
3816
|
+
onEdit: openEdit,
|
|
3817
|
+
onAskDelete: function (file) { setDeleting(file); setArchiving(null); },
|
|
3818
|
+
onCancelDelete: function () { setDeleting(null); },
|
|
3819
|
+
onConfirmDelete: confirmDelete,
|
|
3820
|
+
});
|
|
3821
|
+
}));
|
|
3822
|
+
filesView = statusFilter === "archived"
|
|
3823
|
+
? [
|
|
3824
|
+
h("div", { className: "smem-ar-banner", key: "banner" },
|
|
3825
|
+
"档案馆里的记忆不参与检索与星图,原文仍在记忆目录的 archive/ 下 —— 恢复后它就回到活动列表;" +
|
|
3826
|
+
"「编辑」是原样文本编辑,改完存回同一份文件;「彻底删除」会真的从 archive/ 里删掉它(不可恢复,删除前还要再确认一次)。"),
|
|
3827
|
+
list,
|
|
3828
|
+
]
|
|
3829
|
+
: list;
|
|
3830
|
+
}
|
|
3831
|
+
|
|
3832
|
+
return filesView;
|
|
3833
|
+
}
|
|
3834
|
+
|
|
3744
3835
|
// ── 筛选条(1.5.2 从 Section 里抽出)────────────────────────────────
|
|
3745
3836
|
// 只接收 props、只渲染;筛选语义(哪些项互斥、怎么 AND/OR)仍在 Section 里算好再传进来。
|
|
3746
3837
|
// 抽出来的收益是 Section 少了 60 行 UI 细节,而筛选条可以单独看、单独改(比如以后再加
|
|
@@ -4481,88 +4572,23 @@ h("span", { key: "sep", className: "smem-actions-sep", "aria-hidden": "true" }),
|
|
|
4481
4572
|
|
|
4482
4573
|
// 「文件列表」这一屏:状态筛选决定看哪一批,灰色卡片与留痕块自带「退役」语义。
|
|
4483
4574
|
// banner 只在**专门看归档**时出现,切到全部时不重复说一遍。
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
}
|
|
4500
|
-
|
|
4501
|
-
h("div", { key: "t" }, "活动记忆是空的 —— 状态筛到「已归档」还能捞出 " + archiveItems.length + " 条。"),
|
|
4502
|
-
h("button", { type: "button", className: "smem-btn", key: "go", onClick: function () { setStatusFilter("archived"); } }, "切到已归档"),
|
|
4503
|
-
]);
|
|
4504
|
-
} else if (filtered.length === 0) {
|
|
4505
|
-
filesView = h("div", { className: "smem-empty", key: "empty" }, [
|
|
4506
|
-
h("div", { key: "t" }, "没有符合搜索或筛选条件的文件。"),
|
|
4507
|
-
h("button", { type: "button", className: "smem-btn", key: "clear", onClick: function () { setStatusFilter("all"); setTypeFilter([]); setTagFilter([]); setQuery(""); } }, "清除筛选"),
|
|
4508
|
-
]);
|
|
4509
|
-
} else {
|
|
4510
|
-
const list = h("div", { className: "smem-list", key: "list" }, filtered.map(function (it) {
|
|
4511
|
-
if (it.archived === true) {
|
|
4512
|
-
return h(ArchivedCard, {
|
|
4513
|
-
key: it.file,
|
|
4514
|
-
item: it,
|
|
4515
|
-
busy: busy,
|
|
4516
|
-
restoring: restoring === it.file,
|
|
4517
|
-
deleting: archDelete === it.file,
|
|
4518
|
-
editing: archEdit === it.file,
|
|
4519
|
-
loading: archLoad && archEdit === it.file,
|
|
4520
|
-
saving: archSaving && archEdit === it.file,
|
|
4521
|
-
text: archText,
|
|
4522
|
-
onText: setArchText,
|
|
4523
|
-
onEdit: openArchEdit,
|
|
4524
|
-
onSave: saveArchEdit,
|
|
4525
|
-
onCancel: cancelArchEdit,
|
|
4526
|
-
onRestore: restoreFile,
|
|
4527
|
-
// 两个「危险动作的确认」互斥:问到一半又去改文本,界面就会同时摆两个确认条。
|
|
4528
|
-
onAskDelete: function (file) { setArchDelete(file); setArchEdit(null); },
|
|
4529
|
-
onCancelDelete: function () { setArchDelete(null); },
|
|
4530
|
-
onConfirmDelete: deleteArchivedFile,
|
|
4531
|
-
});
|
|
4532
|
-
}
|
|
4533
|
-
return h(Card, {
|
|
4534
|
-
key: it.file,
|
|
4535
|
-
item: it,
|
|
4536
|
-
expanded: !!expanded[it.file],
|
|
4537
|
-
deleting: deleting === it.file,
|
|
4538
|
-
archiving: archiving === it.file,
|
|
4539
|
-
archiveReason: archiveReason,
|
|
4540
|
-
busy: busy,
|
|
4541
|
-
onArchiveReason: setArchiveReason,
|
|
4542
|
-
onAskArchive: function (file) { setArchiving(file); setArchiveReason(""); setDeleting(null); },
|
|
4543
|
-
onCancelArchive: function () { setArchiving(null); setArchiveReason(""); },
|
|
4544
|
-
onConfirmArchive: confirmArchive,
|
|
4545
|
-
onToggleLock: toggleLock,
|
|
4546
|
-
onToggle: function (file) {
|
|
4547
|
-
const nx = {};
|
|
4548
|
-
nx[file] = !expanded[file];
|
|
4549
|
-
setExpanded(Object.assign({}, expanded, nx));
|
|
4550
|
-
},
|
|
4551
|
-
onEdit: openEdit,
|
|
4552
|
-
onAskDelete: function (file) { setDeleting(file); setArchiving(null); },
|
|
4553
|
-
onCancelDelete: function () { setDeleting(null); },
|
|
4554
|
-
onConfirmDelete: confirmDelete,
|
|
4555
|
-
});
|
|
4556
|
-
}));
|
|
4557
|
-
filesView = statusFilter === "archived"
|
|
4558
|
-
? [
|
|
4559
|
-
h("div", { className: "smem-ar-banner", key: "banner" },
|
|
4560
|
-
"档案馆里的记忆不参与检索与星图,原文仍在记忆目录的 archive/ 下 —— 恢复后它就回到活动列表;" +
|
|
4561
|
-
"「编辑」是原样文本编辑,改完存回同一份文件;「彻底删除」会真的从 archive/ 里删掉它(不可恢复,删除前还要再确认一次)。"),
|
|
4562
|
-
list,
|
|
4563
|
-
]
|
|
4564
|
-
: list;
|
|
4565
|
-
}
|
|
4575
|
+
const filesView = h(FilesView, {
|
|
4576
|
+
loading: loading, totalCount: totalCount, openAdd: openAdd,
|
|
4577
|
+
statusFilter: statusFilter, setStatusFilter: setStatusFilter,
|
|
4578
|
+
items: items, archiveItems: archiveItems, filtered: filtered,
|
|
4579
|
+
setTypeFilter: setTypeFilter, setTagFilter: setTagFilter, setQuery: setQuery,
|
|
4580
|
+
busy: busy, restoring: restoring,
|
|
4581
|
+
archDelete: archDelete, archEdit: archEdit, archLoad: archLoad, archSaving: archSaving,
|
|
4582
|
+
archText: archText, setArchText: setArchText,
|
|
4583
|
+
openArchEdit: openArchEdit, saveArchEdit: saveArchEdit, cancelArchEdit: cancelArchEdit,
|
|
4584
|
+
restoreFile: restoreFile, setArchDelete: setArchDelete, setArchEdit: setArchEdit, deleteArchivedFile: deleteArchivedFile,
|
|
4585
|
+
expanded: expanded, deleting: deleting, archiving: archiving,
|
|
4586
|
+
archiveReason: archiveReason, setArchiveReason: setArchiveReason,
|
|
4587
|
+
setArchiving: setArchiving, setDeleting: setDeleting,
|
|
4588
|
+
confirmArchive: confirmArchive, toggleLock: toggleLock,
|
|
4589
|
+
openEdit: openEdit, confirmDelete: confirmDelete,
|
|
4590
|
+
});
|
|
4591
|
+
|
|
4566
4592
|
|
|
4567
4593
|
return h("div", { className: "smem-root" }, [
|
|
4568
4594
|
h("div", { className: "smem-tabs", key: "tabs", role: "tablist" }, [
|
package/package.json
CHANGED