@@ -65,94 +65,69 @@ class TaskTimerWidget extends WidgetType {
6565 return this . dom ;
6666 }
6767
68- this . dom = createDiv ( { cls : `task-timer-widget ${ this . timerState ?. status || 'idle' } ` } ) ;
69- this . createTimeDisplay ( this . dom ) ;
70- this . createButtons ( this . dom ) ;
71- return this . dom ;
72- }
73-
74- /**
75- * Create time display area
76- */
77- private createTimeDisplay ( container : HTMLElement ) : void {
78- const timeSpan = container . createSpan ( { cls : "task-timer-display" } ) ;
68+ // Create a simple text-based widget
69+ this . dom = createDiv ( { cls : 'task-timer-widget' } ) ;
70+ this . dom . style . cssText = 'margin: 2px 0; font-size: 0.9em; color: var(--text-muted);' ;
7971 this . updateTimerState ( ) ;
80- this . refreshTimeDisplay ( ) ;
72+ this . createContent ( ) ;
73+ return this . dom ;
8174 }
8275
8376 /**
84- * Create action buttons
77+ * Create content based on timer state
8578 */
86- private createButtons ( container : HTMLElement ) : void {
87- const buttonContainer = container . createDiv ( { cls : "task-timer-buttons" } ) ;
79+ private createContent ( ) : void {
80+ if ( ! this . dom ) return ;
8881
89- this . updateTimerState ( ) ;
82+ this . dom . empty ( ) ;
9083
9184 if ( ! this . timerState || this . timerState . status === 'idle' ) {
92- const startButton = buttonContainer . createEl ( "button" , {
93- cls : "task-timer-button start" ,
94- text : "Start Task"
95- } ) ;
96- startButton . addEventListener ( " click" , ( e ) => {
85+ // Create text-style start button
86+ const startSpan = this . dom . createSpan ( ) ;
87+ startSpan . style . cssText = 'cursor: pointer; text-decoration: underline; color: var(--text-accent);' ;
88+ startSpan . setText ( 'Start Task' ) ;
89+ startSpan . addEventListener ( ' click' , ( e ) => {
9790 e . preventDefault ( ) ;
91+ e . stopPropagation ( ) ;
9892 this . startTimer ( ) ;
9993 } ) ;
100- } else if ( this . timerState . status === 'running' ) {
101- const pauseButton = buttonContainer . createEl ( "button" , {
102- cls : "task-timer-button pause" ,
103- text : "Pause"
104- } ) ;
105- pauseButton . addEventListener ( "click" , ( e ) => {
106- e . preventDefault ( ) ;
107- this . pauseTimer ( ) ;
108- } ) ;
109-
110- const resetButton = buttonContainer . createEl ( "button" , {
111- cls : "task-timer-button reset" ,
112- text : "Reset"
113- } ) ;
114- resetButton . addEventListener ( "click" , ( e ) => {
115- e . preventDefault ( ) ;
116- this . resetTimer ( ) ;
117- } ) ;
118-
119- const completeButton = buttonContainer . createEl ( "button" , {
120- cls : "task-timer-button complete" ,
121- text : "Complete"
122- } ) ;
123- completeButton . addEventListener ( "click" , ( e ) => {
124- e . preventDefault ( ) ;
125- this . completeTimer ( ) ;
126- } ) ;
127- } else if ( this . timerState . status === 'paused' ) {
128- const resumeButton = buttonContainer . createEl ( "button" , {
129- cls : "task-timer-button resume" ,
130- text : "Resume"
131- } ) ;
132- resumeButton . addEventListener ( "click" , ( e ) => {
133- e . preventDefault ( ) ;
134- this . resumeTimer ( ) ;
135- } ) ;
136-
137- const resetButton = buttonContainer . createEl ( "button" , {
138- cls : "task-timer-button reset" ,
139- text : "Reset"
140- } ) ;
141- resetButton . addEventListener ( "click" , ( e ) => {
142- e . preventDefault ( ) ;
143- this . resetTimer ( ) ;
144- } ) ;
145-
146- const completeButton = buttonContainer . createEl ( "button" , {
147- cls : "task-timer-button complete" ,
148- text : "Complete"
149- } ) ;
150- completeButton . addEventListener ( "click" , ( e ) => {
151- e . preventDefault ( ) ;
152- this . completeTimer ( ) ;
153- } ) ;
94+ } else {
95+ // Show elapsed time
96+ const elapsedMs = Date . now ( ) - this . timerState . startTime + ( this . timerState . elapsed || 0 ) ;
97+ const formattedTime = TaskTimerFormatter . formatDuration ( elapsedMs , this . settings . timeFormat ) ;
98+ const timeSpan = this . dom . createSpan ( ) ;
99+ timeSpan . setText ( `⏱ ${ formattedTime } ` ) ;
100+
101+ // Add action links
102+ if ( this . timerState . status === 'running' ) {
103+ this . addActionLink ( 'Pause' , ( ) => this . pauseTimer ( ) ) ;
104+ this . dom . appendText ( ' | ' ) ;
105+ this . addActionLink ( 'Complete' , ( ) => this . completeTimer ( ) ) ;
106+ } else if ( this . timerState . status === 'paused' ) {
107+ this . addActionLink ( 'Resume' , ( ) => this . resumeTimer ( ) ) ;
108+ this . dom . appendText ( ' | ' ) ;
109+ this . addActionLink ( 'Complete' , ( ) => this . completeTimer ( ) ) ;
110+ }
111+ this . dom . appendText ( ' | ' ) ;
112+ this . addActionLink ( 'Reset' , ( ) => this . resetTimer ( ) ) ;
154113 }
155114 }
115+
116+ /**
117+ * Add clickable action link
118+ */
119+ private addActionLink ( text : string , action : ( ) => void ) : void {
120+ if ( ! this . dom ) return ;
121+
122+ const link = this . dom . createSpan ( ) ;
123+ link . style . cssText = 'cursor: pointer; text-decoration: underline; color: var(--text-accent);' ;
124+ link . setText ( text ) ;
125+ link . addEventListener ( 'click' , ( e ) => {
126+ e . preventDefault ( ) ;
127+ e . stopPropagation ( ) ;
128+ action ( ) ;
129+ } ) ;
130+ }
156131
157132 /**
158133 * Start timer
@@ -340,8 +315,8 @@ class TaskTimerWidget extends WidgetType {
340315 }
341316
342317 this . updateInterval = window . setInterval ( ( ) => {
343- this . refreshTimeDisplay ( ) ;
344- } , 5000 ) ; // Update every 5 seconds for performance
318+ this . createContent ( ) ; // Update the entire content
319+ } , 1000 ) ; // Update every second
345320 }
346321
347322 /**
@@ -354,51 +329,14 @@ class TaskTimerWidget extends WidgetType {
354329 }
355330 }
356331
357- /**
358- * Refresh only the time display (performance optimization)
359- */
360- private refreshTimeDisplay ( ) : void {
361- if ( ! this . dom ) return ;
362-
363- const timeDisplay = this . dom . querySelector ( '.task-timer-display' ) as HTMLElement ;
364- if ( ! timeDisplay ) return ;
365-
366- this . updateTimerState ( ) ;
367-
368- if ( this . timerState ) {
369- const elapsedMs = Date . now ( ) - this . timerState . startTime ;
370- const formattedTime = TaskTimerFormatter . formatDuration ( elapsedMs , this . settings . timeFormat ) ;
371-
372- // Only update if the text has changed
373- if ( timeDisplay . textContent !== formattedTime ) {
374- timeDisplay . textContent = formattedTime ;
375- }
376-
377- // Update animation class
378- if ( this . timerState . status === 'running' ) {
379- timeDisplay . addClass ( 'running' ) ;
380- } else {
381- timeDisplay . removeClass ( 'running' ) ;
382- }
383- } else {
384- timeDisplay . textContent = "00:00" ;
385- timeDisplay . removeClass ( 'running' ) ;
386- }
387- }
388-
389332 /**
390333 * Refresh the entire UI (used when state changes significantly)
391334 */
392335 private refreshUI ( ) : void {
393336 if ( ! this . dom ) return ;
394337
395- // Update widget class
396- this . dom . className = `task-timer-widget ${ this . timerState ?. status || 'idle' } ` ;
397-
398- // Clear and recreate content
399- this . dom . empty ( ) ;
400- this . createTimeDisplay ( this . dom ) ;
401- this . createButtons ( this . dom ) ;
338+ this . updateTimerState ( ) ;
339+ this . createContent ( ) ;
402340 }
403341
404342 destroy ( ) {
@@ -536,18 +474,33 @@ function hasSubTasks(rangeText: string, parentLineText: string): boolean {
536474 const parentMatch = parentLineText . match ( / ^ ( \s * ) / ) ;
537475 const parentIndent = parentMatch ? parentMatch [ 1 ] . length : 0 ;
538476
477+ console . log ( `[TaskTimer] Checking subtasks for parent with indent ${ parentIndent } ` ) ;
478+
539479 // Check subsequent lines for subtasks
480+ let foundSubtask = false ;
540481 for ( let i = 1 ; i < lines . length ; i ++ ) {
541482 const line = lines [ i ] ;
542- if ( isTaskLine ( line ) ) {
543- const lineMatch = line . match ( / ^ ( \s * ) / ) ;
544- const lineIndent = lineMatch ? lineMatch [ 1 ] . length : 0 ;
545- if ( lineIndent > parentIndent ) {
546- return true ; // Found a subtask with greater indentation
547- }
483+
484+ // Skip empty lines
485+ if ( ! line . trim ( ) ) continue ;
486+
487+ const lineMatch = line . match ( / ^ ( \s * ) / ) ;
488+ const lineIndent = lineMatch ? lineMatch [ 1 ] . length : 0 ;
489+
490+ // If we find a line with same or less indentation that's not empty, stop checking
491+ if ( lineIndent <= parentIndent ) {
492+ break ;
493+ }
494+
495+ // Check if this indented line is a task
496+ if ( isTaskLine ( line ) && lineIndent > parentIndent ) {
497+ console . log ( `[TaskTimer] Found subtask: ${ line . trim ( ) } ` ) ;
498+ foundSubtask = true ;
499+ break ;
548500 }
549501 }
550- return false ;
502+
503+ return foundSubtask ;
551504}
552505
553506function extractBlockRef ( lineText : string ) : string | undefined {
0 commit comments