Skip to content

Commit b08c7bc

Browse files
committed
feat(incremental-share): improve document handling and UI robustness
- Add "neverShared" translation key in en_US and zh_CN locales - Refactor IncrementalShareUI to safely handle undefined or null values - Introduce virtual scroll with fixed height for document list container - Adjust mock data generation counts for new and updated documents - Fix date parsing logic for modifiedTime in getDocuments function - Correct SQL time filtering to handle zero timestamp as "fetch all" - Display "neverShared" label for documents with no share time - Add safe checks for array lengths and selectedDocs existence in UI - Remove unused hasMoreDocuments variable and related assignments - Update pagination logic to handle potentially undefined totalPages and currentPage
1 parent f69f073 commit b08c7bc

File tree

4 files changed

+47
-29
lines changed

4 files changed

+47
-29
lines changed

src/composables/useSiyuanApi.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
*/
99

1010
import { simpleLogger } from "zhi-lib-base"
11-
import { isDev } from "../Constants"
1211
import { SiYuanApiAdaptor, SiyuanConfig, SiyuanKernelApi } from "zhi-siyuan-api"
12+
import { isDev } from "../Constants"
1313
import { ShareProConfig } from "../models/ShareProConfig"
1414

1515
/**
@@ -70,8 +70,9 @@ export const getDocumentsPaged = async (
7070

7171
// SQL 查询:获取所有文档,按更新时间排序,支持分页
7272
// 如果有 lastShareTime,则只获取自该时间以来修改的文档
73-
// 注意:SiYuan 使用的是 Unix 时间戳格式,需要转换
74-
const timeCondition = lastShareTime ? `AND b.updated > ${lastShareTime}` : ""
73+
// 注意:SiYuan 使用的是 Unix 时间戳格式(毫秒),需要直接比较
74+
// 当 lastShareTime 为 0 时,表示获取所有文档
75+
const timeCondition = lastShareTime && lastShareTime > 0 ? `AND b.updated > ${lastShareTime}` : ""
7576

7677
const sql = `
7778
SELECT DISTINCT
@@ -96,7 +97,18 @@ export const getDocumentsPaged = async (
9697
return result.data.map((row: any) => ({
9798
docId: row.docId,
9899
docTitle: row.docTitle || "未命名文档",
99-
modifiedTime: new Date(row.modifiedTime).getTime() || 0,
100+
// modifiedTime 看起来是形如 "20251208000004" 的字符串,需要转换为 Unix 时间戳
101+
modifiedTime:
102+
row.modifiedTime && typeof row.modifiedTime === "string"
103+
? new Date(
104+
parseInt(row.modifiedTime.substring(0, 4)), // 年
105+
parseInt(row.modifiedTime.substring(4, 6)) - 1, // 月(需要减1,因为月份从0开始)
106+
parseInt(row.modifiedTime.substring(6, 8)), // 日
107+
parseInt(row.modifiedTime.substring(8, 10)), // 时
108+
parseInt(row.modifiedTime.substring(10, 12)), // 分
109+
parseInt(row.modifiedTime.substring(12, 14)) // 秒
110+
).getTime()
111+
: parseInt(row.modifiedTime) || 0,
100112
notebookId: row.notebookId,
101113
notebookName: row.notebookId, // 这里可以后续优化获取笔记本名称
102114
}))
@@ -109,8 +121,9 @@ export const getDocumentsPaged = async (
109121
*/
110122
export const getDocumentsCount = async (kernelApi: SiyuanKernelApi, lastShareTime?: number): Promise<number> => {
111123
// 如果有 lastShareTime,则只计算自该时间以来修改的文档数量
112-
// 注意:SiYuan 使用的是 Unix 时间戳格式,需要转换
113-
const timeCondition = lastShareTime ? `AND b.updated > ${lastShareTime}` : ""
124+
// 注意:SiYuan 使用的是 Unix 时间戳格式(毫秒),需要直接比较
125+
// 当 lastShareTime 为 0 时,表示获取所有文档
126+
const timeCondition = lastShareTime && lastShareTime > 0 ? `AND b.updated > ${lastShareTime}` : ""
114127

115128
const sql = `
116129
SELECT COUNT(DISTINCT b.root_id) as total

src/i18n/en_US.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@
251251
"shareFailed": "Share failed",
252252
"loadError": "Failed to load documents",
253253
"noData": "No data",
254+
"neverShared": "Never shared",
254255
"blacklist": {
255256
"title": "Blacklist Management",
256257
"add": "Add",

src/i18n/zh_CN.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@
256256
"shareFailed": "分享失败",
257257
"loadError": "加载文档失败",
258258
"noData": "暂无数据",
259+
"neverShared": "从未分享",
259260
"blacklist": {
260261
"title": "黑名单管理",
261262
"add": "添加",

src/libs/pages/IncrementalShareUI.svelte

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@
3838
let pageSize = 5 // 每页显示5条记录
3939
let totalDocuments = 0
4040
let totalPages = 0
41-
let hasMoreDocuments = true
42-
41+
4342
// 虚拟滚动配置
4443
const ITEM_HEIGHT = 45 // 每个文档项的高度(像素)
4544
const MAX_VISIBLE_ITEMS = 5 // 每页显示的最大项数
@@ -79,7 +78,6 @@
7978
8079
// 重置分页状态
8180
currentPage = 0
82-
hasMoreDocuments = true
8381
changeDetectionResult = {
8482
newDocuments: [],
8583
updatedDocuments: [],
@@ -108,7 +106,7 @@
108106
logger.info("使用mock数据进行测试")
109107
110108
// 生成mock的新文档数据
111-
const mockNewDocuments: any = Array.from({ length: 25 }, (_, i) => ({
109+
const mockNewDocuments: any = Array.from({ length: 5 }, (_, i) => ({
112110
docId: `new-doc-${i + 1}`,
113111
docTitle: `Mock 新增文档 ${i + 1} - 测试数据`,
114112
modifiedTime: Date.now() - Math.floor(Math.random() * 1000 * 60 * 60 * 24), // 随机在过去24小时内
@@ -119,7 +117,7 @@
119117
}))
120118
121119
// 生成mock的更新文档数据
122-
const mockUpdatedDocuments: any = Array.from({ length: 15 }, (_, i) => ({
120+
const mockUpdatedDocuments: any = Array.from({ length: 3 }, (_, i) => ({
123121
docId: `updated-doc-${i + 1}`,
124122
docTitle: `Mock 更新文档 ${i + 1} - 内容已修改`,
125123
modifiedTime: Date.now() - Math.floor(Math.random() * 1000 * 60 * 60 * 24), // 随机在过去24小时内
@@ -134,7 +132,7 @@
134132
newDocuments: mockNewDocuments,
135133
updatedDocuments: mockUpdatedDocuments,
136134
unchangedDocuments: [],
137-
blacklistedCount: 3,
135+
blacklistedCount: 0,
138136
}
139137
140138
// 更新分页信息
@@ -323,17 +321,18 @@
323321
<span>{pluginInstance.i18n.incrementalShare.loading}</span>
324322
</div>
325323
{:else if changeDetectionResult}
324+
{JSON.stringify(changeDetectionResult)}
326325
<div class="share-stats">
327326
<div class="stat-item">
328-
<span class="stat-number">{changeDetectionResult.newDocuments.length}</span>
327+
<span class="stat-number">{changeDetectionResult.newDocuments?.length || 0}</span>
329328
<span class="stat-label">{pluginInstance.i18n.incrementalShare.newDocuments}</span>
330329
</div>
331330
<div class="stat-item">
332-
<span class="stat-number">{changeDetectionResult.updatedDocuments.length}</span>
331+
<span class="stat-number">{changeDetectionResult.updatedDocuments?.length || 0}</span>
333332
<span class="stat-label">{pluginInstance.i18n.incrementalShare.updatedDocuments}</span>
334333
</div>
335334
<div class="stat-item">
336-
<span class="stat-number">{changeDetectionResult.unchangedDocuments.length}</span>
335+
<span class="stat-number">{changeDetectionResult.unchangedDocuments?.length || 0}</span>
337336
<span class="stat-label">{pluginInstance.i18n.incrementalShare.unchangedDocuments}</span>
338337
</div>
339338
<div class="stat-item blacklisted">
@@ -348,42 +347,46 @@
348347
<div class="group-header">
349348
<span class="group-title">
350349
{pluginInstance.i18n.incrementalShare.documentsToShare}
351-
<span class="group-count">({filteredDocs.length})</span>
350+
<span class="group-count">({filteredDocs?.length || 0})</span>
352351
</span>
353-
{#if filteredDocs.length > 0}
352+
{#if (filteredDocs?.length || 0) > 0}
354353
<label class="select-all">
355354
<input type="checkbox" bind:checked={selectAll} on:change={handleSelectAll} />
356355
{pluginInstance.i18n.incrementalShare.selectAll}
357356
</label>
358357
{/if}
359358
</div>
360359
<div class="group-content">
361-
{#if filteredDocs.length === 0}
360+
{#if (filteredDocs?.length || 0) === 0}
362361
<div class="empty-message">
363362
{pluginInstance.i18n.incrementalShare.noDocumentsToShare}
364363
</div>
365364
{:else}
366365
<!-- 使用虚拟滚动 -->
367-
<div class="virtual-list-container"
368-
style="height: {Math.min(filteredDocs.length, MAX_VISIBLE_ITEMS) * ITEM_HEIGHT}px;">
369-
<VirtualList items={filteredDocs} let:item height="{Math.min(filteredDocs.length, MAX_VISIBLE_ITEMS) * ITEM_HEIGHT}px">
366+
<div class="virtual-list-container"
367+
style="height: {Math.min(filteredDocs?.length || 0, MAX_VISIBLE_ITEMS) * ITEM_HEIGHT}px;">
368+
<VirtualList items={filteredDocs || []} let:item height="{Math.min(filteredDocs?.length || 0, MAX_VISIBLE_ITEMS) * ITEM_HEIGHT}px">
370369
<div class="document-item">
371370
<label class="document-checkbox">
372371
<input
373372
type="checkbox"
374-
checked={selectedDocs.has(item.docId)}
373+
checked={selectedDocs?.has(item.docId) || false}
375374
on:change={() => toggleDocSelection(item.docId)}
376375
/>
377-
<span class="document-title">{item.docTitle}</span>
376+
<span class="document-title">{item.docTitle || "未命名文档"}</span>
378377
</label>
379378
<div class="document-meta">
380-
<span class={`document-type document-type--${item.type}`}>
381-
{item.type === 'new' ? pluginInstance.i18n.incrementalShare.new : pluginInstance.i18n.incrementalShare.updated}
379+
<span class={`document-type document-type--${item.type || 'new'}`}>
380+
{item.type === 'updated' ? pluginInstance.i18n.incrementalShare.updated : pluginInstance.i18n.incrementalShare.new}
382381
</span>
383-
{#if item.shareTime}
382+
{#if item.shareTime && item.shareTime > 0}
384383
<span class="document-time">
385384
{pluginInstance.i18n.incrementalShare.lastShared}: {formatTime(item.shareTime)}
386385
</span>
386+
{:else}
387+
<span class="document-time">
388+
{pluginInstance.i18n.incrementalShare.lastShared}: {pluginInstance.i18n.incrementalShare.neverShared}
389+
</span>
387390
{/if}
388391
</div>
389392
</div>
@@ -394,7 +397,7 @@
394397
</div>
395398

396399
<!-- 分页控件 -->
397-
{#if totalPages > 1}
400+
{#if (totalPages || 0) > 1}
398401
<div class="pagination-controls">
399402
<button
400403
class="pagination-btn"
@@ -406,13 +409,13 @@
406409
</button>
407410

408411
<div class="pagination-info">
409-
{pluginInstance.i18n.incrementalShare.page} {currentPage + 1} / {totalPages}
412+
{pluginInstance.i18n.incrementalShare.page} {(currentPage || 0) + 1} / {totalPages || 1}
410413
</div>
411414

412415
<button
413416
class="pagination-btn"
414417
on:click={loadNextPage}
415-
disabled={currentPage === totalPages - 1 || isLoading}
418+
disabled={currentPage === (totalPages || 1) - 1 || isLoading}
416419
>
417420
{pluginInstance.i18n.incrementalShare.nextPage}
418421
{@html icons.iconChevronRight}

0 commit comments

Comments
 (0)