diff --git a/README.md b/README.md index 4ecd656..2d3359d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A powerful task management and focus timer plugin for [Obsidian](https://obsidia ![Immerse Banner](https://img.shields.io/badge/Obsidian-Plugin-7c3aed?style=for-the-badge&logo=obsidian&logoColor=white) ![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge) -![Version](https://img.shields.io/badge/Version-1.1.3-blue?style=for-the-badge) +![Version](https://img.shields.io/badge/Version-1.1.4-blue?style=for-the-badge) ## 🎯 Overview diff --git a/main.js b/main.js index 0874414..84a1aca 100644 --- a/main.js +++ b/main.js @@ -749,7 +749,12 @@ var ImmerseView = class extends import_obsidian2.ItemView { const breakLabel = this.plugin.currentTimerSeconds > 0 ? "\u2615 BREAK TIME" : "\u2728 BREAK COMPLETE"; activeCard.createEl("div", { cls: "immerse-active-label", text: breakLabel }); } else { - const workLabel = this.plugin.currentTimerSeconds > 0 ? "\u{1F3AF} FOCUSING ON" : "\u{1F345} POMODORO COMPLETE"; + let workLabel; + if (this.plugin.currentTimerSeconds > 0 || this.plugin.isStopwatchMode) { + workLabel = "\u{1F3AF} FOCUSING ON"; + } else { + workLabel = "\u{1F345} POMODORO COMPLETE"; + } activeCard.createEl("div", { cls: "immerse-active-label", text: workLabel }); } activeCard.createEl("div", { cls: "immerse-active-task-name", text: task.text }); @@ -809,7 +814,7 @@ var ImmerseView = class extends import_obsidian2.ItemView { }); } } else { - if (this.plugin.currentTimerSeconds > 0) { + if (this.plugin.currentTimerSeconds > 0 || this.plugin.isStopwatchMode) { this.pauseBtnEl = controls.createEl("button", { cls: "immerse-btn immerse-btn-secondary" }); this.pauseBtnEl.innerHTML = this.plugin.isTimerRunning ? "\u23F8 Pause" : "\u25B6 Resume"; this.pauseBtnEl.addEventListener("click", () => this.plugin.toggleTimer()); @@ -1250,6 +1255,7 @@ var ImmersePlugin = class extends import_obsidian4.Plugin { this.currentTimerSeconds = 0; this.isTimerRunning = false; this.isBreakMode = false; + this.isStopwatchMode = false; this.activeTaskId = null; this.pomodoroCount = 0; // Timestamp-based tracking for reliable background timing @@ -1652,6 +1658,7 @@ var ImmersePlugin = class extends import_obsidian4.Plugin { this.activeTaskId = taskId; task.isActive = true; this.isBreakMode = false; + this.isStopwatchMode = true; this.currentTimerSeconds = 0; this.isTimerRunning = true; this.secondsWorkedOnCurrentTask = task.actualMinutes * 60; @@ -1690,6 +1697,7 @@ var ImmersePlugin = class extends import_obsidian4.Plugin { this.activeTaskId = taskId; task.isActive = true; this.isBreakMode = false; + this.isStopwatchMode = false; this.currentTimerSeconds = this.settings.pomodoroWorkMinutes * 60; this.isTimerRunning = true; this.secondsWorkedOnCurrentTask = Math.floor(task.actualMinutes * 60); @@ -1788,7 +1796,11 @@ var ImmersePlugin = class extends import_obsidian4.Plugin { const now = Date.now(); const elapsedMs = now - this.timerStartTimestamp; const elapsedSeconds = Math.floor(elapsedMs / 1e3); - this.currentTimerSeconds = Math.max(0, this.pausedTimeRemaining - elapsedSeconds); + if (this.pausedTimeRemaining === 0 || this.isStopwatchMode) { + this.currentTimerSeconds = this.pausedTimeRemaining + elapsedSeconds; + } else { + this.currentTimerSeconds = Math.max(0, this.pausedTimeRemaining - elapsedSeconds); + } if (task && !this.isBreakMode) { this.secondsWorkedOnCurrentTask = initialSecondsWorked + elapsedSeconds; task.actualMinutes = Math.floor(this.secondsWorkedOnCurrentTask / 60); @@ -1797,7 +1809,7 @@ var ImmersePlugin = class extends import_obsidian4.Plugin { } this.updateStatusBar(); this.updateTimerDisplay(); - if (this.currentTimerSeconds <= 0) { + if (this.currentTimerSeconds <= 0 && !this.isStopwatchMode) { this.handlePomodoroEnd(); } }, 1e3); @@ -1822,6 +1834,7 @@ var ImmersePlugin = class extends import_obsidian4.Plugin { } } this.isTimerRunning = false; + this.isStopwatchMode = false; this.activeTaskId = null; this.secondsWorkedOnCurrentTask = 0; this.timerStartTimestamp = 0; diff --git a/manifest.json b/manifest.json index effe820..d65bae5 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "immerse", "name": "Immerse", - "version": "1.1.3", + "version": "1.1.4", "minAppVersion": "0.15.0", "description": "A Blitzit-inspired task management and focus timer plugin. Plan your day, track time with Pomodoro technique, and crush your tasks with satisfying checkoffs.", "author": "Crib", diff --git a/package.json b/package.json index 8993d8e..2c91927 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "immerse", - "version": "1.1.3", + "version": "1.1.4", "description": "A Blitzit-inspired task management and focus timer plugin for Obsidian", "main": "main.js", "scripts": { diff --git a/src/main.ts b/src/main.ts index 394666f..937f5c0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -35,6 +35,7 @@ export default class ImmersePlugin extends Plugin { currentTimerSeconds: number = 0; isTimerRunning: boolean = false; isBreakMode: boolean = false; + isStopwatchMode: boolean = false; activeTaskId: string | null = null; pomodoroCount: number = 0; @@ -551,6 +552,7 @@ export default class ImmersePlugin extends Plugin { this.activeTaskId = taskId; task.isActive = true; this.isBreakMode = false; + this.isStopwatchMode = true; this.currentTimerSeconds = 0; this.isTimerRunning = true; this.secondsWorkedOnCurrentTask = task.actualMinutes * 60; @@ -610,6 +612,7 @@ export default class ImmersePlugin extends Plugin { this.activeTaskId = taskId; task.isActive = true; this.isBreakMode = false; + this.isStopwatchMode = false; this.currentTimerSeconds = this.settings.pomodoroWorkMinutes * 60; this.isTimerRunning = true; @@ -766,8 +769,14 @@ export default class ImmersePlugin extends Plugin { const elapsedMs = now - this.timerStartTimestamp; const elapsedSeconds = Math.floor(elapsedMs / 1000); - // Update timer (countdown from paused position) - this.currentTimerSeconds = Math.max(0, this.pausedTimeRemaining - elapsedSeconds); + // Update timer based on mode + if (this.pausedTimeRemaining === 0 || this.isStopwatchMode) { + // Stopwatch mode - count up from paused position + this.currentTimerSeconds = this.pausedTimeRemaining + elapsedSeconds; + } else { + // Countdown mode (pomodoro/break) - count down from paused position + this.currentTimerSeconds = Math.max(0, this.pausedTimeRemaining - elapsedSeconds); + } if (task && !this.isBreakMode) { // Update actual time worked @@ -783,7 +792,7 @@ export default class ImmersePlugin extends Plugin { this.updateStatusBar(); this.updateTimerDisplay(); - if (this.currentTimerSeconds <= 0) { + if (this.currentTimerSeconds <= 0 && !this.isStopwatchMode) { this.handlePomodoroEnd(); } }, 1000); @@ -814,6 +823,7 @@ export default class ImmersePlugin extends Plugin { } this.isTimerRunning = false; + this.isStopwatchMode = false; this.activeTaskId = null; this.secondsWorkedOnCurrentTask = 0; this.timerStartTimestamp = 0; diff --git a/src/view.ts b/src/view.ts index fed6ada..f30e779 100644 --- a/src/view.ts +++ b/src/view.ts @@ -154,7 +154,13 @@ export class ImmerseView extends ItemView { const breakLabel = this.plugin.currentTimerSeconds > 0 ? '☕ BREAK TIME' : '✨ BREAK COMPLETE'; activeCard.createEl('div', { cls: 'immerse-active-label', text: breakLabel }); } else { - const workLabel = this.plugin.currentTimerSeconds > 0 ? '🎯 FOCUSING ON' : '🍅 POMODORO COMPLETE'; + // Determine label based on whether timer is active and mode (stopwatch vs pomodoro) + let workLabel: string; + if (this.plugin.currentTimerSeconds > 0 || this.plugin.isStopwatchMode) { + workLabel = '🎯 FOCUSING ON'; + } else { + workLabel = '🍅 POMODORO COMPLETE'; + } activeCard.createEl('div', { cls: 'immerse-active-label', text: workLabel }); } @@ -234,8 +240,8 @@ export class ImmerseView extends ItemView { } } else { // Work mode controls - if (this.plugin.currentTimerSeconds > 0) { - // Work session still running + if (this.plugin.currentTimerSeconds > 0 || this.plugin.isStopwatchMode) { + // Work session still running (or stopwatch mode active) this.pauseBtnEl = controls.createEl('button', { cls: 'immerse-btn immerse-btn-secondary' }); this.pauseBtnEl.innerHTML = this.plugin.isTimerRunning ? '⏸ Pause' : '▶ Resume'; this.pauseBtnEl.addEventListener('click', () => this.plugin.toggleTimer()); @@ -248,7 +254,7 @@ export class ImmerseView extends ItemView { stopBtn.innerHTML = '✕ Stop'; stopBtn.addEventListener('click', () => this.plugin.stopTimer()); } else { - // Work session finished - show break and completion options + // Pomodoro session finished - show break and completion options const startBreakBtn = controls.createEl('button', { cls: 'immerse-btn immerse-btn-secondary' }); startBreakBtn.innerHTML = '☕ Start Break'; startBreakBtn.addEventListener('click', () => this.plugin.startBreak()); diff --git a/versions.json b/versions.json index 913d869..1ccf7d0 100644 --- a/versions.json +++ b/versions.json @@ -5,5 +5,6 @@ "1.0.7": "0.15.0", "1.0.8": "0.15.0", "1.0.9": "0.15.0", - "1.1.3": "0.15.0" + "1.1.3": "0.15.0", + "1.1.4": "0.15.0" } \ No newline at end of file