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 - +![Demo](https://github.com/wth461694678/text-block-timer/blob/main/demo.gif) -- 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 - +![Command Shortcut](https://github.com/wth461694678/text-block-timer/blob/main/command_shortcut.gif) -### (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 +![Right Click](https://github.com/wth461694678/text-block-timer/blob/main/right_click.gif) -- 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",