Skip to content

Commit b432e9b

Browse files
committed
🔖 v5.1.0 / 20260128 优化插件性能,比之前丝滑太多
- 🎨 优化插件数据读取和保存性能 - 任务数据 - 项目数据 - 习惯数据 - 任务和项目分类数据 - 番茄钟数据 - 订阅日历数据 - 节假日数据 - 🎨 项目看板支持拖动到任务管理侧栏今日任务设置为今日任务,拖动到明日任务设置为明日任务 - 🎨 粘贴列表新建子任务 - 🎨 设置绑定块属性性能 - 🎨 优化绑定块按钮添加稳定性 - 🎨 优化添加大纲前缀性能 - 🐛 项目看板拖动分组没有自动更新排序 - 🎨 优化番茄钟统计:统计视图也需要计算未完成完整时长的番茄数
1 parent df4d05c commit b432e9b

File tree

8 files changed

+92
-52
lines changed

8 files changed

+92
-52
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
- 番茄钟数据
88
- 订阅日历数据
99
- 节假日数据
10+
- 🎨 项目看板支持拖动到任务管理侧栏今日任务设置为今日任务,拖动到明日任务设置为明日任务
11+
- 🎨 粘贴列表新建子任务
1012
- 🎨 设置绑定块属性性能
1113
- 🎨 优化绑定块按钮添加稳定性
12-
- 🎨 优化添加大纲前缀:修改块属性会更新标题大纲前缀
14+
- 🎨 优化添加大纲前缀性能
1315
- 🐛 项目看板拖动分组没有自动更新排序
14-
- 🎨 优化番茄钟统计
16+
- 🎨 优化番茄钟统计:统计视图也需要计算未完成完整时长的番茄数
1517

1618
## v5.0.2 / 20260126
1719

i18n/en_US.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,8 @@
524524
"spanningDaysLeftSingle": "1 day remaining",
525525
"autoDetectDateTime": "Auto Detect Date Time",
526526
"autoDetectDateTimeDesc": "Automatically detect date and time information in block content when creating reminders, supports natural language expressions like 'tomorrow 3pm', 'next Friday', etc.",
527+
"removeDateAfterDetection": "Remove date from title after detection",
528+
"removeDateAfterDetectionDesc": "Automatically remove recognized date and time description text from the task title",
527529
"bindUrl": "Bind URL",
528530
"enterUrl": "Enter URL (http:// or https://)",
529531
"openUrl": "Open Link",

i18n/zh_CN.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,8 @@
532532
"spanningDaysLeftSingle": "还剩1天",
533533
"autoDetectDateTime": "添加提醒时自动时间识别",
534534
"autoDetectDateTimeDesc": "在创建提醒时自动识别块内容中的日期时间信息,支持自然语言表达如'明天下午3点'、'下周五'等",
535+
"removeDateAfterDetection": "识别日期后标题移除日期",
536+
"removeDateAfterDetectionDesc": "自动从任务标题中移除已识别出的日期和时间描述文本",
535537
"createQuickReminder": "创建快速提醒",
536538
"bindToBlock": "绑定到块",
537539
"unboundReminder": "未绑定提醒",

src/SettingPanel.svelte

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,13 @@
253253
title: t('autoDetectDateTime'),
254254
description: t('autoDetectDateTimeDesc'),
255255
},
256+
{
257+
key: 'removeDateAfterDetection',
258+
value: settings.removeDateAfterDetection,
259+
type: 'checkbox',
260+
title: t('removeDateAfterDetection'),
261+
description: t('removeDateAfterDetectionDesc'),
262+
},
256263
{
257264
key: 'newDocNotebook',
258265
value: settings.newDocNotebook,

src/components/BatchReminderDialog.ts

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Dialog, showMessage } from "siyuan";
22
import { t } from "../utils/i18n";
33
import { updateBindBlockAtrrs, getBlockByID } from "../api";
44
import { getRepeatDescription } from "../utils/repeatUtils";
5-
import { getLogicalDateString, parseNaturalDateTime } from "../utils/dateUtils";
5+
import { getLogicalDateString, parseNaturalDateTime, autoDetectDateTimeFromTitle } from "../utils/dateUtils";
66
import { RepeatConfig, RepeatSettingsDialog } from "./RepeatSettingsDialog";
77
import { QuickReminderDialog } from "./QuickReminderDialog";
88
import { CategoryManager } from "../utils/categoryManager";
@@ -147,19 +147,22 @@ export class BatchReminderDialog {
147147
}
148148

149149

150+
const removeEnabled = await this.plugin.getRemoveDateAfterDetectionEnabled();
150151
// 从标题中识别日期
151-
const titleAuto = this.autoDetectDateTimeFromTitle(content);
152+
const titleAuto = autoDetectDateTimeFromTitle(content);
152153
// 从备注中识别日期,如果标题没有
153154
let date = titleAuto.date;
154155
let time = titleAuto.time;
155156
let hasTime = titleAuto.hasTime;
156157
if (!date) {
157-
const contentAuto = this.autoDetectDateTimeFromTitle(note);
158+
const contentAuto = autoDetectDateTimeFromTitle(note);
158159
date = contentAuto.date;
159160
time = contentAuto.time;
160161
hasTime = contentAuto.hasTime;
161162
}
162163

164+
const cleanTitle = removeEnabled ? (titleAuto.cleanTitle || content) : content;
165+
163166
results.push({
164167
blockId,
165168
content: content,
@@ -170,7 +173,7 @@ export class BatchReminderDialog {
170173
endDate: titleAuto.endDate,
171174
endTime: titleAuto.endTime,
172175
hasEndTime: titleAuto.hasEndTime,
173-
cleanTitle: titleAuto.cleanTitle
176+
cleanTitle: cleanTitle
174177
});
175178
}
176179
} catch (error) {
@@ -187,36 +190,6 @@ export class BatchReminderDialog {
187190
}
188191

189192

190-
private autoDetectDateTimeFromTitle(title: string): { date?: string; time?: string; hasTime?: boolean; cleanTitle?: string; endDate?: string; endTime?: string; hasEndTime?: boolean } {
191-
const parseResult = parseNaturalDateTime(title);
192-
193-
if (!parseResult.date) {
194-
return { cleanTitle: title };
195-
}
196-
197-
let cleanTitle = title;
198-
const timeExpressions = [
199-
/|/gi,
200-
/|/gi,
201-
//gi,
202-
//gi,
203-
/?[]/gi,
204-
/?[]/gi,
205-
/\d+[]/gi,
206-
/\d+[]/gi,
207-
];
208-
209-
timeExpressions.forEach(pattern => {
210-
cleanTitle = cleanTitle.replace(pattern, '').trim();
211-
});
212-
213-
cleanTitle = cleanTitle.replace(/\s+/g, ' ').replace(/^[\s]+|[\s]+$/g, '');
214-
215-
return {
216-
...parseResult,
217-
cleanTitle: cleanTitle || title
218-
};
219-
}
220193

221194

222195
}

src/components/PasteTaskDialog.ts

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ export class PasteTaskDialog {
5353
<textarea id="taskList" class="b3-text-field"
5454
placeholder=""
5555
style="width: 100%; height: 250px; resize: vertical;"></textarea>
56+
<div style="display: flex; flex-direction: column; gap: 8px; margin-top: 12px;">
57+
<label style="display: flex; align-items: center; cursor: pointer;">
58+
<input id="autoDetectDate" type="checkbox" style="margin-right: 8px;">
59+
<span>${t("autoDetectDateTime")}</span>
60+
</label>
61+
<label id="removeDateLabel" style="display: flex; align-items: center; cursor: pointer; margin-left: 20px;">
62+
<input id="removeDate" type="checkbox" style="margin-right: 8px;">
63+
<span>${t("removeDateAfterDetection")}</span>
64+
</label>
65+
</div>
5666
</div>
5767
<div class="b3-dialog__action">
5868
<button class="b3-button b3-button--cancel" id="cancelBtn">${t("cancel") || "取消"}</button>
@@ -65,6 +75,34 @@ export class PasteTaskDialog {
6575
const textArea = dialog.element.querySelector('#taskList') as HTMLTextAreaElement;
6676
const cancelBtn = dialog.element.querySelector('#cancelBtn') as HTMLButtonElement;
6777
const createBtn = dialog.element.querySelector('#createBtn') as HTMLButtonElement;
78+
const autoDetectCheckbox = dialog.element.querySelector('#autoDetectDate') as HTMLInputElement;
79+
const removeDateCheckbox = dialog.element.querySelector('#removeDate') as HTMLInputElement;
80+
const removeDateLabel = dialog.element.querySelector('#removeDateLabel') as HTMLElement;
81+
82+
// 初始化选中状态
83+
this.config.plugin.getAutoDetectDateTimeEnabled().then((enabled: boolean) => {
84+
autoDetectCheckbox.checked = enabled;
85+
updateRemoveDateVisibility();
86+
});
87+
this.config.plugin.getRemoveDateAfterDetectionEnabled().then((enabled: boolean) => {
88+
removeDateCheckbox.checked = enabled;
89+
});
90+
91+
function updateRemoveDateVisibility() {
92+
if (autoDetectCheckbox.checked) {
93+
removeDateLabel.style.opacity = "1";
94+
removeDateLabel.style.pointerEvents = "auto";
95+
removeDateCheckbox.disabled = false;
96+
} else {
97+
removeDateLabel.style.opacity = "0.5";
98+
removeDateLabel.style.pointerEvents = "none";
99+
removeDateCheckbox.disabled = true;
100+
}
101+
}
102+
103+
autoDetectCheckbox.addEventListener('change', () => {
104+
updateRemoveDateVisibility();
105+
});
68106

69107
cancelBtn.addEventListener('click', () => dialog.destroy());
70108

@@ -75,8 +113,9 @@ export class PasteTaskDialog {
75113
return;
76114
}
77115

78-
const autoDetect = await this.config.plugin.getAutoDetectDateTimeEnabled();
79-
const hierarchicalTasks = this.parseHierarchicalTaskList(text, autoDetect);
116+
const autoDetect = autoDetectCheckbox.checked;
117+
const removeDate = removeDateCheckbox.checked;
118+
const hierarchicalTasks = this.parseHierarchicalTaskList(text, autoDetect, removeDate);
80119

81120
if (hierarchicalTasks.length > 0) {
82121
try {
@@ -100,7 +139,7 @@ export class PasteTaskDialog {
100139
});
101140
}
102141

103-
private parseHierarchicalTaskList(text: string, autoDetect: boolean = false): HierarchicalTask[] {
142+
private parseHierarchicalTaskList(text: string, autoDetect: boolean = false, removeDate: boolean = true): HierarchicalTask[] {
104143
const lines = text.split('\n');
105144
const tasks: HierarchicalTask[] = [];
106145
const stack: Array<{ task: HierarchicalTask; level: number }> = [];
@@ -113,7 +152,7 @@ export class PasteTaskDialog {
113152

114153
if (!cleanLine || (!cleanLine.startsWith('-') && level === 0 && !cleanLine.match(/^\s*-/))) {
115154
if (cleanLine && level === 0) {
116-
const taskData = this.parseTaskLine(cleanLine, autoDetect);
155+
const taskData = this.parseTaskLine(cleanLine, autoDetect, removeDate);
117156
const task: HierarchicalTask = {
118157
...taskData,
119158
level: 0,
@@ -136,7 +175,7 @@ export class PasteTaskDialog {
136175
const taskContent = cleanLine.replace(/^[-*+]+\s*/, '');
137176
if (!taskContent) continue;
138177

139-
const taskData = this.parseTaskLine(taskContent, autoDetect);
178+
const taskData = this.parseTaskLine(taskContent, autoDetect, removeDate);
140179
const task: HierarchicalTask = {
141180
...taskData,
142181
level: combinedLevel,
@@ -168,7 +207,7 @@ export class PasteTaskDialog {
168207
return Math.floor(spaces / 2);
169208
}
170209

171-
private parseTaskLine(line: string, autoDetect: boolean = false): Omit<HierarchicalTask, 'level' | 'children'> {
210+
private parseTaskLine(line: string, autoDetect: boolean = false, removeDate: boolean = true): Omit<HierarchicalTask, 'level' | 'children'> {
172211
const paramMatch = line.match(/@(.*)$/);
173212
let title = line;
174213
let priority: string | undefined;
@@ -204,7 +243,9 @@ export class PasteTaskDialog {
204243
if (autoDetect) {
205244
const detected = autoDetectDateTimeFromTitle(title);
206245
if (detected.date || detected.endDate) {
207-
title = detected.cleanTitle || title;
246+
if (removeDate) {
247+
title = detected.cleanTitle || title;
248+
}
208249
startDate = detected.date;
209250
time = detected.time;
210251
endDate = detected.endDate;

src/components/QuickReminderDialog.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,9 +1236,12 @@ export class QuickReminderDialog {
12361236
if (noTimeCheckbox) noTimeCheckbox.checked = true;
12371237
}
12381238

1239-
// if (detected.cleanTitle && detected.cleanTitle.trim()) {
1240-
// titleInput.value = detected.cleanTitle;
1241-
// }
1239+
// 如果启用了识别后移除日期设置,更新标题
1240+
this.plugin.getRemoveDateAfterDetectionEnabled().then((removeEnabled: boolean) => {
1241+
if (removeEnabled && detected.cleanTitle !== undefined) {
1242+
titleInput.value = detected.cleanTitle || titleInput.value;
1243+
}
1244+
});
12421245
}
12431246
} catch (err) {
12441247
console.warn('自动识别标题日期失败:', err);
@@ -1825,12 +1828,15 @@ export class QuickReminderDialog {
18251828
if (detected && (detected.date || detected.endDate)) {
18261829
this.applyNaturalLanguageResult(detected);
18271830

1828-
// 这里的逻辑已移除:用户希望保留原始标题内容,不自动移除日期时间文本
1829-
// if (detected.cleanTitle !== undefined && detected.cleanTitle !== joined) {
1830-
// // 重新计算 titleInput 的值,将粘贴的那部分替换为清理后的文本
1831-
// titleInput.value = before + detected.cleanTitle + after;
1832-
// titleInput.selectionStart = titleInput.selectionEnd = start + detected.cleanTitle.length;
1833-
// }
1831+
// 识别后移除日期
1832+
this.plugin.getRemoveDateAfterDetectionEnabled().then((removeEnabled: boolean) => {
1833+
if (removeEnabled && detected.cleanTitle !== undefined) {
1834+
// 重新计算 titleInput 的值,将粘贴的那部分替换为清理后的文本
1835+
const cleanPart = detected.cleanTitle || '';
1836+
titleInput.value = before + cleanPart + after;
1837+
titleInput.selectionStart = titleInput.selectionEnd = start + cleanPart.length;
1838+
}
1839+
});
18341840
}
18351841
}
18361842
}

src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export const DEFAULT_SETTINGS = {
8282
randomNotificationPopupWindow: false, // 新增:随机微休息弹窗提醒,默认关闭
8383
dailyFocusGoal: 6,
8484
autoDetectDateTime: false, // 新增:是否自动识别日期时间
85+
removeDateAfterDetection: true, // 新增:识别日期后是否移除标题中的日期
8586
newDocNotebook: '', // 新增:新建文档的笔记本ID
8687
newDocPath: '/{{now | date "2006-01-02"}}/', // 新增:新建文档的路径模板,支持sprig语法
8788
defaultHeadingLevel: 3, // 新增:新建标题的默认层级(1-6),默认为3级标题
@@ -3906,6 +3907,12 @@ export default class ReminderPlugin extends Plugin {
39063907
return settings.autoDetectDateTime !== false;
39073908
}
39083909

3910+
// 获取识别后移除日期设置
3911+
async getRemoveDateAfterDetectionEnabled(): Promise<boolean> {
3912+
const settings = await this.loadSettings();
3913+
return settings.removeDateAfterDetection !== false;
3914+
}
3915+
39093916
/**
39103917
* 打开番茄钟独立窗口
39113918
* @param reminder 提醒对象

0 commit comments

Comments
 (0)