diff --git a/README.md b/README.md
index 1fb05bb..3880fdd 100644
--- a/README.md
+++ b/README.md
@@ -1,51 +1,49 @@
-[English](README.md) | [中文](README.zh.md)
-
# Text Block Timer Plugin
-A text block timing tool designed for Obsidian, allowing you to add **count-up** timing functionality to any text line in your notes.
+A text block timing tool designed for Obsidian, allowing you to add a **count-up stopwatch** function to any text line in your notes.
## Features
-
+
-- Add timers to any text line as many as you wsh (count-up timing)
-- ▶️/⏸️ Supports start, pause, and continue timing, with multi-segment timing accumulation for a single task
-- ⏳ Real-time display of accumulated time
-- [💾](https://www.emojiall.com/zh-hans/emoji/%F0%9F%92%BE) Timing data is persistently saved
+- Add timers to any text line, supporting multiple timers running simultaneously (stopwatch function).
+- ▶️/⏸️ Start, pause, and resume timing for tasks.
+- ⏳ Real-time display of cumulative time cost.
+- 💾 Persistent storage of timing data.
+- 🔄 Users can optionally choose whether to continue timing when files or Obsidian is closed (by default, closing a file will not cause failure of the real-time stopwatch).
-## Usage Method
+## Usage
-[Strongly Recommended] Write your task first before adding a timer!
+### (I) Command Palette + Shortcut (Recommended⭐️)
-### (1) Command Palette + Shortcuts (Recommended ⭐️)
+1. Configure a shortcut for the command "Text Block Timer: Toggle timer" for quick access.
+2. When the cursor is on a text block, press the shortcut key to start, pause, or resume.
+3. The timer will be displayed in the format `【⏳00:00:00 】` at the beginning of the text line.
-1. Assign a shortcut for the command "Text Block Timer: Toggle timer" for quick access
-2. Place your cursor on a text block, press the shortcut to start, pause, or continue
-
+
-### (2) Mouse Operations
+### (II) Mouse Operations
-1. Right-click on a text line
-2. Select "Start Timer", "Pause Timer", or "Continue Timer"
-3. The timer will display in the format `【⏳00:00:00 】` at the start of the text block
-
+1. Right-click on a text line.
+2. Select "Start Timer," "Pause Timer," or "Resume Timer."
-## Notes
+
-- It is recommended to keep the file (containing a running tiemr) open; otherwise, the real-time second updates of the timer may fail.
-- However, the file will record the timer state, which can be manually resumed.
-
-## Changelog:
+## Version Log:
+- V1.0.3
+ 1. ==Major Optimization==: Closing a file no longer causes the timer to fail. Users can freely choose whether to continue timing when the or Obsidian is closed (see custom settings).
+ 2. Added custom settings: Users can now choose the position to insert the timer (before or after texts).
+ 3. Improve compatibility with markdown, adding support for ordered checkboxes and headings.
- V1.0.2
- 1. Add language support for English, Chinese, Japanese and Korean.
+ 1. Added language support for Chinese, English, Japanese, and Korean.
- V1.0.1
- 1. A space is added before the time tag to better distinguish it from your content.
- 2. Fixed the issue where adding a timer disrupted the structure of checkboxes in Markdown.
+ 1. Improved display effects by adding a space before the time label.
+ 2. Fixed the issue where adding a timer to a task list caused the task checkbox to fail.
- V1.0.0
1. Plugin release
## Development Information
- Developer: frankthwang
-- Version: 1.0.2
+- Version: 1.0.3
\ No newline at end of file
diff --git a/README.zh.md b/README.zh.md
index 97adb30..0ad3a09 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -1,4 +1,4 @@
-[English](README.md) | [中文](README.zh.md)
+[English](https://github.com/wth461694678/text-block-timer/blob/main/README.md) | [中文](https://github.com/wth461694678/text-block-timer/blob/main/README.zh.md)
# 文本块计时器插件
@@ -6,36 +6,35 @@
## 功能特性
-
+
- 为任意文本行添加计时器,支持同时执行多个计时器(正计时)
-- ▶️/⏸️ 支持开始、暂停、继续计时,支持一个任务的多段计时累计
+- ▶️/⏸️ 支持开始、暂停、继续计时,支持任务分段耗时累计
- ⏳ 实时显示累计时间
- 💾 计时数据持久化保存
+- 🔄 可自由选择关闭文件、关闭Obsidian后是否持续计时 (默认设置下,关闭文件不会导致实时计时失效)
## 使用方法
-【强烈推荐】先撰写文本,再添加Timer为你的任务即计时!!
-
### (一)命令行+快捷键(推荐⭐️)
1. 为命令 "Text Block Timer: Toggle timer" 配置快捷键,方便快速使用
2. 当光标在某个文本块时,按下快捷键,即可实现timer的开始、暂停、继续操作
3. 计时器会以 `【⏳00:00:00 】`格式显示在文本块的行首
-
+
### (二)鼠标操作
1. 在文本行上右键点击
2. 选择"开始计时"、"暂停计时"或"继续计时"
-
-
-## 注意事项
-
-- 建议保持文本块所在文件打开,否则会导致计时器的实时跳秒失效。但文件会保留计时器状态,下次打开文件时可以手动恢复计时。
+
## 版本日志:
+- V1.0.3
+ 1. ==重大优化==:现在关闭文件不会导致计时器失效,用户可自由选择关闭文件或关闭Obsidian后是否持续计时(见自定义设置)
+ 2. 增加自定义设置:现在用户可自由选择插入文本块位置(文本前或文本后)
+ 3. 优化对Markdown的处理逻辑,增加对有序复选框、标题的支持
- V1.0.2
1. 增加了对中文、英文、日语、韩语的语言支持
- V1.0.1
@@ -47,4 +46,4 @@
## 开发信息
- 开发者: frankthwang
-- 版本: 1.0.2
+- 版本: 1.0.3
\ No newline at end of file
diff --git a/main.js b/main.js
index b3acc24..d6153e5 100644
--- a/main.js
+++ b/main.js
@@ -3,7 +3,6 @@
const obsidian = require('obsidian');
// Regex constants
-const TIMER_REGEX = /]*)>([^<]+)<\/span>/;
const UPDATE_INTERVAL = 1000;
// —— Utility: Format time and render span —— //
@@ -14,24 +13,41 @@ class TimerRenderer {
.substr(11, 8);
const colorStyle =
timerData.Status === 'Running' ? 'style="color: #10b981;"' : '';
- return `【⏳${formatted} 】 `;
+ return `【⏳${formatted} 】 `;
}
}
// —— Utility: Parse existing span data —— //
class TimerParser {
static parse(lineText) {
- const m = lineText.match(TIMER_REGEX);
- if (!m) return null;
+ // const spanMatch = lineText.match(/]*>/);
+ const spanMatch = lineText.match(/]*>.*?<\/span>/);
+ if (!spanMatch) return null;
+
+ const spanTag = spanMatch[0];
+ const attributesText = spanTag.substring(6, spanTag.length - 1); // 去掉 ""
+
+ const attributes = {};
+ const attributeList = attributesText.split(/\s+/); // 按空格分割成属性列表
+ for (const attribute of attributeList) {
+ if (attribute.includes('=')) {
+ const [key, value] = attribute.split('=', 2);
+ attributes[key] = value.replace(/"/g, '').replace(/'/g, '');
+ } else {
+ attributes[attribute] = true; // 处理没有值的属性(如 disabled)
+ }
+ }
+
return {
- raw: m[0],
- beforeIndex: m.index,
- afterIndex: m.index + m[0].length,
- timerId: m[1],
- Status: m[2],
- AccumulatedTime: parseInt(m[3], 10),
- currentStartTimeStamp: parseInt(m[4], 10),
- lineId: parseInt(m[5], 10),
+ raw: spanTag,
+ beforeIndex: spanMatch.index,
+ afterIndex: spanMatch.index + spanTag.length,
+ timerId: attributes.timerId || null,
+ Status: attributes.Status || null,
+ AccumulatedTime: parseInt(attributes.AccumulatedTime, 10) || 0,
+ currentStartTimeStamp: parseInt(attributes.currentStartTimeStamp, 10) || null,
+ lineId: parseInt(attributes.lineId, 10) || null,
+ PLT: parseInt(attributes.PLT, 10) || 0,
};
}
}
@@ -46,6 +62,7 @@ class TimerManager {
if (this.timers.has(timerId)) return;
const id = setInterval(() => tickCallback(timerId), UPDATE_INTERVAL);
this.timers.set(timerId, id);
+ console.log('start timerId:', timerId);
}
stop(timerId) {
@@ -53,6 +70,7 @@ class TimerManager {
if (id) {
clearInterval(id);
this.timers.delete(timerId);
+ console.log('stop timerId:', timerId);
}
}
@@ -67,43 +85,102 @@ class TimerManager {
// —— Main plugin class —— //
class TimerPlugin extends obsidian.Plugin {
async onload() {
+
this.manager = new TimerManager();
// Stores context for each timerId: { editor, lineNum }
this.timerContexts = new Map();
+ this.fileFirstOpen = true;
+ this.pluginLoadTime = Date.now();
+
+ this.default_settings = {
+ autoStopTimers: 'quit', // default value
+ timerInsertLocation: 'head' // default value
+ };
+
+ await this.loadSettings();
// 获取当前界面语言
const currentLanguage = window.localStorage.getItem('language');
- console.log('Current Obsidian Interface Language:', currentLanguage);
+ // console.log('Current Obsidian Interface Language:', currentLanguage);
if (currentLanguage === 'zh') {
+ this.plugin_name = '文本块计时器';
+ this.plugin_desc = '强烈建议配合快捷键使用';
this.command_name = '启动计时器/切换计时器状态';
this.action_paused = '暂停计时';
this.action_continue = '继续计时';
this.action_start = '开始计时';
+ this.setting_autostop_label = '自动停止计时器';
+ this.setting_autostop_desc = '哪些行为视作用户手动停止计时器';
+ this.setting_never = '从不停止,除非用户手动停止';
+ this.setting_quit = '仅退出Obsidian时停止,关闭文件依然后台计时';
+ this.setting_close = '关闭文件时立即停止';
+ this.setting_insertlocation_label = '计时器插入位置';
+ this.setting_insertlocation_head = '在文本前插入';
+ this.setting_insertlocation_tail = '在文本后插入';
} else if (currentLanguage === 'zh-TW') {
+ this.plugin_name = '文本塊計時器';
+ this.plugin_desc = '強烈建議配合快捷鍵使用';
this.command_name = '啟動計時器/切換計時器狀態';
this.action_paused = '暫停計時';
this.action_continue = '繼續計時';
this.action_start = '開始計時';
+ this.setting_autostop_label = '自動停止計時器';
+ this.setting_autostop_desc = '哪些行為視為用戶手動停止計時器';
+ this.setting_never = '從不停止,除非用戶手動停止';
+ this.setting_quit = '僅退出Obsidian時停止,關閉文件依後台計時';
+ this.setting_close = '關閉文件時立即停止';
+ this.setting_insertlocation_label = '計時器插入位置';
+ this.setting_insertlocation_head = '在文本前插入';
+ this.setting_insertlocation_tail = '在文本後插入';
} else if (currentLanguage === 'ja') {
+ this.plugin_name = 'テキストブロックタイマー';
+ this.plugin_desc = 'ショートカットキーと合わせて使うのがおすすめです';
this.command_name = 'タイマーを始める/切替タイマ';
this.action_paused = 'タイマーを止める';
this.action_continue = 'タイマーを続ける';
this.action_start = 'タイマーを始める';
+ this.setting_autostop_label = 'タイマー自動停止';
+ this.setting_autostop_desc = 'ユーザーが手働でタイマーを停止したものとみなします';
+ this.setting_never = 'ユーザーが手動で止めない限り停止しません';
+ this.setting_quit = 'Obsidianをログアウトしたときだけ停止し、ファイルを閉じたままバックグラウンドカウントします';
+ this.setting_close = 'ファイルを閉じたらすぐに停止します';
+ this.setting_insertlocation_label = 'タイマー挿入位置です';
+ this.setting_insertlocation_head = 'テキストの前に挿入します';
+ this.setting_insertlocation_tail = 'テキストの後に挿入します';
} else if (currentLanguage === 'ko') {
+ this.plugin_name = '텍스트 블록 타이머';
+ this.plugin_desc = '단축키에 맞춰 사용하는 것을 권장합니다';
this.command_name = '타이머 전환';
this.action_paused = '타이머 일시 정지';
this.action_continue = '타이머 계속';
this.action_start = '타이머 시작';
+ this.setting_autostop_label = '타이머 자동 정지';
+ this.setting_autostop_desc = '사용자가 타이머를 수동으로 종료한 것으로 간주할 행동입니다';
+ this.setting_never = '사용자가 수동으로 중지하지 않는 한 정지하지 않는다';
+ this.setting_quit = 'obsidian을 종료할 때만 종료되며, 닫기 파일은 여전히 백그라운드 타임을 유지한다';
+ this.setting_close = '파일을 닫을 때 즉시 중지합니다';
+ this.setting_insertlocation_label = '타이머 삽입 위치';
+ this.setting_insertlocation_head = '텍스트 앞에 삽입';
+ this.setting_insertlocation_tail = '텍스트 뒤에 삽입';
+
} else {
+ this.plugin_name = 'Text Block Timer';
+ this.plugin_desc = 'It is strongly recommened to control timer by shortcut key';
this.command_name = 'toggle-timer';
this.action_paused = 'Pause Timer';
this.action_continue = 'Continue Timer';
this.action_start = 'Start Timer';
+ this.setting_autostop_label = 'Auto Stop Timers';
+ this.setting_autostop_desc = 'Which actions should stop the timer automatically?';
+ this.setting_never = 'Never Stop unless user stop timer manually';
+ this.setting_quit = 'Auto stop when quit Obsidian, continue timing when file closed';
+ this.setting_close = 'Auto stop when file closed';
+ this.setting_insertlocation_label = 'Timer insert position';
+ this.setting_insertlocation_head = 'Insert before text';
+ this.setting_insertlocation_tail = 'Insert after text';
}
-
-
// Add to editor context menu
this.registerEvent(
this.app.workspace.on('editor-menu', this.onEditorMenu.bind(this))
@@ -132,6 +209,16 @@ class TimerPlugin extends obsidian.Plugin {
}
},
});
+
+ // 监听文件打开事件
+ this.registerEvent(
+ this.app.workspace.on('file-open', this.onFileOpen.bind(this))
+ );
+
+
+ // 注册设置
+ this.addSettingTab(new TimerSettingTab(this.app, this));
+
}
onunload() {
@@ -175,7 +262,7 @@ class TimerPlugin extends obsidian.Plugin {
this.timerContexts.set(timerId, { editor, lineNum });
this.manager.start(timerId, this.onTick.bind(this));
this.updateTimer('continue', editor, lineNum, timerId);
- this.timerContexts.set(timerId, { editor, lineNum });
+ // this.timerContexts.set(timerId, { editor, lineNum });
}
handleContinue(parsed, editor, lineNum) {
@@ -183,7 +270,7 @@ class TimerPlugin extends obsidian.Plugin {
this.timerContexts.set(timerId, { editor, lineNum });
this.manager.start(timerId, this.onTick.bind(this));
this.updateTimer('continue', editor, lineNum, timerId);
- this.timerContexts.set(timerId, { editor, lineNum });
+ // this.timerContexts.set(timerId, { editor, lineNum });
}
handlePause(parsed, editor, lineNum) {
@@ -191,9 +278,27 @@ class TimerPlugin extends obsidian.Plugin {
this.timerContexts.set(timerId, { editor, lineNum });
this.manager.stop(timerId);
this.updateTimer('pause', editor, lineNum, timerId);
- this.timerContexts.set(timerId, { editor, lineNum });
+ // this.timerContexts.set(timerId, { editor, lineNum });
}
+ handleRestore(parsed, editor, lineNum) {
+ const timerId = parsed.timerId;
+ // 在ontick之前,先把数据恢复
+ this.updateTimer('restore', editor, lineNum, timerId);
+ this.timerContexts.set(timerId, { editor, lineNum });
+ this.manager.start(timerId, this.onTick.bind(this));
+ // this.timerContexts.set(timerId, { editor, lineNum });
+ }
+
+ handleForcePause(parsed, editor, lineNum) {
+ const timerId = parsed.timerId;
+ // this.timerContexts.set(timerId, { editor, lineNum });
+ // this.manager.stop(timerId);
+ this.updateTimer('forcepause', editor, lineNum, timerId);
+ // this.timerContexts.set(timerId, { editor, lineNum });
+ }
+
+
onTick(timerId) {
const ctx = this.timerContexts.get(timerId);
if (ctx) {
@@ -201,7 +306,6 @@ class TimerPlugin extends obsidian.Plugin {
const lineText = editor.getLine(lineNum) || '';
if (lineText.includes(`timerId="${timerId}"`)) {
this.updateTimer('update', editor, lineNum, timerId);
- return;
}
}
@@ -234,28 +338,34 @@ class TimerPlugin extends obsidian.Plugin {
let data;
switch (action) {
- case 'init':
+ case 'init': // init:Timer初始化,TimerId为当前时间戳,初始化时为暂停状态,累计耗时=0,记录创建时的时间戳
data = {
timerId: Date.now().toString(),
lineId: lineNum,
Status: 'Paused',
AccumulatedTime: 0,
- currentStartTimeStamp: null,
+ currentStartTimeStamp: now,
+ PLT: this.pluginLoadTime,
};
break;
- case 'continue':
+ case 'continue': // continue:暂停状态下启动: 启动瞬间的timer状态应当和暂停时状态相同,只是把status改为Running
{
const old = parsed || {};
+ // const elapsed = old ?
+ // now - old.currentStartTimeStamp : 0;
+ const elapsed = 0;
data = {
timerId: timerId || old.timerId || Date.now().toString(),
lineId: lineNum,
Status: 'Running',
- AccumulatedTime: old.AccumulatedTime || 0,
+ AccumulatedTime:
+ (old.AccumulatedTime || 0) + elapsed,
currentStartTimeStamp: now,
+ PLT: this.pluginLoadTime,
};
break;
}
- case 'pause':
+ case 'pause': // 逻辑应当与update一致,只是把状态改为Paused
{
const old = parsed;
const elapsed = old ?
@@ -266,11 +376,12 @@ class TimerPlugin extends obsidian.Plugin {
Status: 'Paused',
AccumulatedTime:
(old.AccumulatedTime || 0) + elapsed,
- currentStartTimeStamp: null,
+ currentStartTimeStamp: now,
+ PLT: this.pluginLoadTime,
};
break;
}
- case 'update':
+ case 'update': // AccumulatedTime和currentStartTimeStamp应当更新为当前值
{
const old = parsed;
const elapsed = old ?
@@ -282,6 +393,37 @@ class TimerPlugin extends obsidian.Plugin {
AccumulatedTime:
(old.AccumulatedTime || 0) + elapsed,
currentStartTimeStamp: now,
+ PLT: this.pluginLoadTime,
+ };
+ break;
+ }
+ case 'restore': // 把一个有遗留数据,且状态为Running的Timer, 把ontick失效期间的时间累加到AccumulatedTime, 把currentStartTimeStamp更新为当前时间戳, 把状态改为Running
+ {
+ const old = parsed;
+ const elapsed = old ?
+ now - old.currentStartTimeStamp : 0;
+ data = {
+ timerId: old.timerId,
+ lineId: lineNum,
+ Status: 'Running',
+ AccumulatedTime:
+ (old.AccumulatedTime || 0) + elapsed,
+ currentStartTimeStamp: now,
+ PLT: this.pluginLoadTime,
+ };
+ break;
+ }
+ case 'forcepause': // forcepause: 强制暂停,一切保留原样,只是状态强制改写为暂停
+ {
+ const old = parsed;
+ data = {
+ timerId: old.timerId,
+ lineId: lineNum,
+ Status: 'Paused',
+ AccumulatedTime:
+ (old.AccumulatedTime || 0),
+ currentStartTimeStamp: now,
+ PLT: this.pluginLoadTime,
};
break;
}
@@ -299,24 +441,190 @@ class TimerPlugin extends obsidian.Plugin {
if (parsed) {
before = parsed.beforeIndex;
after = parsed.afterIndex;
- } else {
- // Calculate insertion position after indentation and checkboxes
- const indentMatch = /^(\s*)/.exec(lineText);
- const indentLen = indentMatch ? indentMatch[1].length : 0;
+ } else if (this.settings.timerInsertLocation === 'head') {
- // Check for markdown checkbox or list patterns after indentation
- const afterIndent = lineText.slice(indentLen);
- const checkboxMatch = /^([+\-*]\s\[[^\]]\]\s+|\s*[-+*]\s+)/.exec(afterIndent);
- const checkboxLen = checkboxMatch ? checkboxMatch[1].length : 0;
+ // ol+checkbox
+ const olcheckboxMatch = /(^\s*#*\d\.\s\[.?\]\s)/.exec(lineText);
+ const olcheckboxLen = olcheckboxMatch ? olcheckboxMatch[0].length : 0;
+ // ul+checkbox
+ const ulcheckboxMatch = /(^\s*#*[-/+/*]\s\[.?\]\s)/.exec(lineText);
+ const ulcheckboxLen = ulcheckboxMatch ? ulcheckboxMatch[0].length : 0;
+ // ol
+ const orderedListMatch = /(^\s*#*\d+\.\s)/.exec(lineText);
+ const orderedListLen = orderedListMatch ? orderedListMatch[0].length : 0;
+ // ul
+ const ulMatch = /(^\s*#*[-/+/*]\s)/.exec(lineText);
+ const ulLen = ulMatch ? ulMatch[0].length : 0;
+ // header
+ const headerMatch = /(^\s*#+\s)/.exec(lineText);
+ const headerLen = headerMatch ? headerMatch[0].length : 0;
- before = after = indentLen + checkboxLen;
+
+ if (olcheckboxLen > 0) {
+ var textleft
+ textleft = lineText.slice(olcheckboxLen);
+ console.log('textleft after olcheckbox:', textleft);
+ before = after = olcheckboxLen;
+ } else if (ulcheckboxLen > 0) {
+ var textleft
+ textleft = lineText.slice(ulcheckboxLen);
+ console.log('textleft after checkbox:', textleft);
+ before = after = ulcheckboxLen;
+ } else if (orderedListLen > 0) {
+ var textleft
+ textleft = lineText.slice(orderedListLen);
+ console.log('textleft after ol:', textleft);
+ before = after = orderedListLen;
+ } else if (ulLen > 0) {
+ var textleft
+ textleft = lineText.slice(ulLen);
+ console.log('textleft after ul:', textleft);
+ before = after = ulLen;
+ } else if (headerLen > 0) {
+ var textleft
+ textleft = lineText.slice(headerLen);
+ console.log('textleft after header:', textleft);
+ before = after = headerLen;
+ } else {
+ before = after = 0;
+ }
+ before = before ? before : 0;
+ after = after ? after : 0;
+ } else if (this.settings.timerInsertLocation === 'tail') {
+ before = after = lineText.length;
}
editor.replaceRange(
newSpan, { line: lineNum, ch: before }, { line: lineNum, ch: after }
);
+ console.log('lineNum:', lineNum, 'before:', before, 'after:', after);
return data.timerId;
}
+
+ // 用于标记是否是第一次监听到onFileOpen事件
+ onFileOpen(event) {
+ if (this.fileFirstOpen) {
+ // 如果是第一次监听到onFileOpen事件,则针对每个leaf都执行一次恢复计时器的操作
+ const leaves = this.app.workspace.getLeavesOfType('markdown');
+ for (const leaf of leaves) {
+ if (leaf.view && leaf.view.editor) {
+ const editor = leaf.view.editor;
+ this.restoreTimers(editor);
+ }
+ }
+ this.fileFirstOpen = false; // 标记为已处理过第一次监听
+ } else {
+ // 如果不是第一次监听,则按照原来的逻辑处理特定的文件
+ const leaves = this.app.workspace.getLeavesOfType('markdown');
+ for (const leaf of leaves) {
+ if (leaf.view && leaf.view.file === event) {
+ const editor = leaf.view.editor;
+ if (editor) {
+ // 精简逻辑,可能有问题
+ // this.restoreTimers(editor);
+
+ // 启动一个定时器,每隔1秒检查文件行数
+ const checkInterval = setInterval(() => {
+ const lineCount = editor.lineCount();
+ if (lineCount > 1) {
+ // 如果行数大于1,则执行Restore逻辑
+ this.restoreTimers(editor);
+ clearInterval(checkInterval); // 删除定时器
+ }
+ }, 100);
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // 新增Restore逻辑
+ restoreTimers(editor) {
+ const lineCount = editor.lineCount();
+ for (let i = 0; i < lineCount; i++) {
+ const lineText = editor.getLine(i);
+ const parsed = TimerParser.parse(lineText);
+ if (parsed && parsed.Status === 'Running' && !this.manager.timers.has(parsed.timerId)) {
+
+ if (this.settings.autoStopTimers === 'never') {
+ // 对于状态为Running且timerId不在this.manager中的计时器,执行暂停和继续操作(立即恢复)
+ this.handleRestore(parsed, editor, i);
+ } else if (this.settings.autoStopTimers === 'quit') {
+ // 对于状态为Running且timerId不在this.manager中的计时器,如果计时器的本次启动时间 等于 当前插件启动时间,则继续,否则强行暂停
+ console.log('PLT:', parsed.PLT, 'pluginLoadTime:', this.pluginLoadTime);
+ if (parsed.PLT === this.pluginLoadTime) {
+ this.handleRestore(parsed, editor, i);
+ } else {
+ this.handleForcePause(parsed, editor, i);
+ }
+ } else if (this.settings.autoStopTimers === 'close') {
+ // 对于状态为Running且timerId不在this.manager中的计时器,执行暂停操作
+ this.handleForcePause(parsed, editor, i);
+ }
+
+ }
+ }
+ }
+
+ // 设置项相关方法
+ async loadSettings() {
+ this.settings = Object.assign({}, this.default_settings, await this.loadData());
+ }
+
+
+ async saveSettings() {
+ await this.saveData(this.settings);
+ }
+}
+
+
+
+class TimerSettingTab extends obsidian.PluginSettingTab {
+ constructor(app, plugin) {
+ super(app, plugin);
+ this.plugin = plugin;
+ }
+
+ display() {
+ const { containerEl } = this;
+ containerEl.empty();
+ containerEl.createEl('h2', { text: this.plugin.plugin_name });
+ containerEl.createEl('h3', { text: this.plugin.plugin_desc });
+
+ new obsidian.Setting(containerEl)
+ .setName(this.plugin.setting_autostop_label)
+ .setDesc(this.plugin.setting_autostop_desc)
+ .addDropdown(dropdown => {
+ dropdown
+ .addOption('never', this.plugin.setting_never)
+ .addOption('quit', this.plugin.setting_quit)
+ .addOption('close', this.plugin.setting_close)
+ .setValue(this.plugin.settings.autoStopTimers)
+ .onChange(async(value) => {
+ this.plugin.settings.autoStopTimers = value;
+ await this.plugin.saveSettings();
+ });
+ });
+ new obsidian.Setting(containerEl)
+ .setName(this.plugin.setting_insertlocation_label)
+ .addDropdown(dropdown => {
+ dropdown
+ .addOption('head', this.plugin.setting_insertlocation_head)
+ .addOption('tail', this.plugin.setting_insertlocation_tail)
+ .setValue(this.plugin.settings.timerInsertLocation)
+ .onChange(async(value) => {
+ this.plugin.settings.timerInsertLocation = value;
+ await this.plugin.saveSettings();
+ });
+ });
+
+
+
+
+ ;
+ }
}
module.exports = TimerPlugin;
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
index f8b4996..a9b9051 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,6 +1,6 @@
{
"id": "text-block-timer",
- "version": "1.0.2",
+ "version": "1.0.3",
"minAppVersion": "1.8.9",
"name": "Text Block Timer",
"author": "frankthwang",