@@ -27,6 +27,7 @@ export class PomodoroTimer {
2727
2828 // Session time tracking
2929 this . sessionStartTime = null ; // When the current session was started
30+ this . lastSessionStartTime = null ; // Preserved start time for the last completed session
3031 this . currentSessionElapsedTime = 0 ; // Actual elapsed time for current session (in seconds)
3132 this . lastCompletedSessionTime = 0 ; // Time of the last completed session for undo functionality
3233 this . sessionCompletedButNotSaved = false ; // Flag to track if session completed but not saved yet
@@ -109,7 +110,7 @@ export class PomodoroTimer {
109110 // Generate initial progress dots
110111 this . generateProgressDots ( ) ;
111112 this . updateDisplay ( ) ;
112- this . updateProgressDots ( ) ;
113+ await this . updateProgressDots ( ) ;
113114 this . updateStopUndoButton ( ) ; // Initialize stop/undo button state
114115 this . updateSkipIcon ( ) ; // Initialize skip button icon
115116 this . updateSmartIndicator ( ) ; // Initialize smart pause indicator
@@ -189,6 +190,42 @@ export class PomodoroTimer {
189190
190191 // Start midnight monitoring for daily reset
191192 this . startMidnightMonitoring ( ) ;
193+
194+ // Setup event listeners for session synchronization
195+ this . setupSessionEventListeners ( ) ;
196+ }
197+
198+ setupSessionEventListeners ( ) {
199+ // Listen for session changes from SessionManager to keep dots synchronized
200+ window . addEventListener ( 'sessionAdded' , async ( event ) => {
201+ const { date } = event . detail ;
202+ const today = new Date ( ) . toDateString ( ) ;
203+
204+ // Only update dots if the session was added for today
205+ if ( date === today ) {
206+ await this . updateProgressDots ( ) ;
207+ }
208+ } ) ;
209+
210+ window . addEventListener ( 'sessionDeleted' , async ( event ) => {
211+ const { date } = event . detail ;
212+ const today = new Date ( ) . toDateString ( ) ;
213+
214+ // Only update dots if the session was deleted from today
215+ if ( date === today ) {
216+ await this . updateProgressDots ( ) ;
217+ }
218+ } ) ;
219+
220+ window . addEventListener ( 'sessionUpdated' , async ( event ) => {
221+ const { date } = event . detail ;
222+ const today = new Date ( ) . toDateString ( ) ;
223+
224+ // Only update dots if the session was updated for today
225+ if ( date === today ) {
226+ await this . updateProgressDots ( ) ;
227+ }
228+ } ) ;
192229 }
193230
194231 setupEventListeners ( ) {
@@ -612,8 +649,19 @@ export class PomodoroTimer {
612649 // Track session start time if not already set
613650 if ( ! this . sessionStartTime ) {
614651 this . sessionStartTime = Date . now ( ) ;
652+ console . log ( '🟢 NEW SESSION STARTED - sessionStartTime set to:' , {
653+ timestamp : this . sessionStartTime ,
654+ dateISO : new Date ( this . sessionStartTime ) . toISOString ( ) ,
655+ dateLocal : new Date ( this . sessionStartTime ) . toString ( )
656+ } ) ;
615657 this . currentSessionElapsedTime = 0 ;
616658 this . sessionCompletedButNotSaved = false ; // Reset flag for new session
659+ } else {
660+ console . log ( '⚠️ Session already started - not updating sessionStartTime:' , {
661+ existingTimestamp : this . sessionStartTime ,
662+ existingDateISO : new Date ( this . sessionStartTime ) . toISOString ( ) ,
663+ existingDateLocal : new Date ( this . sessionStartTime ) . toString ( )
664+ } ) ;
617665 }
618666
619667 // Initialize timer accuracy tracking
@@ -981,6 +1029,14 @@ export class PomodoroTimer {
9811029 if ( shouldSaveSession ) {
9821030 this . saveSessionData ( ) ;
9831031 }
1032+
1033+ // Reset session start time for next session (after saving)
1034+ console . log ( '🔄 Resetting sessionStartTime after overtime skip:' , {
1035+ beforeReset : this . sessionStartTime ,
1036+ beforeResetISO : this . sessionStartTime ? new Date ( this . sessionStartTime ) . toISOString ( ) : null
1037+ } ) ;
1038+ this . sessionStartTime = null ;
1039+
9841040 const messages = {
9851041 focus : 'Focus session skipped. Time for a break! 😌' ,
9861042 break : 'Break skipped. Ready to focus? 🍅' ,
@@ -1000,10 +1056,18 @@ export class PomodoroTimer {
10001056 if ( this . currentMode === 'focus' ) {
10011057 if ( ! this . sessionCompletedButNotSaved ) {
10021058 this . completedPomodoros ++ ;
1003- this . updateProgressDots ( ) ;
1059+ await this . updateProgressDots ( ) ;
10041060 const actualElapsedTime = this . currentSessionElapsedTime || ( this . durations . focus - this . timeRemaining ) ;
10051061 this . totalFocusTime += actualElapsedTime ;
10061062 this . lastCompletedSessionTime = actualElapsedTime ;
1063+
1064+ // Preserve session start time for saving
1065+ console . log ( 'Preserving session start time:' , {
1066+ before : this . lastSessionStartTime ,
1067+ sessionStartTime : this . sessionStartTime ,
1068+ preservedValue : this . sessionStartTime
1069+ } ) ;
1070+ this . lastSessionStartTime = this . sessionStartTime ;
10071071
10081072 // Save skipped focus session to SessionManager as individual session
10091073 // Only save if session lasted at least 1 minute
@@ -1046,6 +1110,14 @@ export class PomodoroTimer {
10461110 if ( shouldSaveSession ) {
10471111 this . saveSessionData ( ) ;
10481112 }
1113+
1114+ // Reset session start time for next session (after saving)
1115+ console . log ( '🔄 Resetting sessionStartTime after normal skip:' , {
1116+ beforeReset : this . sessionStartTime ,
1117+ beforeResetISO : this . sessionStartTime ? new Date ( this . sessionStartTime ) . toISOString ( ) : null
1118+ } ) ;
1119+ this . sessionStartTime = null ;
1120+
10491121 const messages = {
10501122 focus : 'Focus session skipped. Time for a break! 😌' ,
10511123 break : 'Break skipped. Ready to focus? 🍅' ,
@@ -1077,14 +1149,22 @@ export class PomodoroTimer {
10771149
10781150 if ( this . currentMode === 'focus' ) {
10791151 this . completedPomodoros ++ ;
1080- this . updateProgressDots ( ) ;
1152+ await this . updateProgressDots ( ) ;
10811153
10821154 // Calculate actual elapsed time for focus sessions
10831155 const actualElapsedTime = this . currentSessionElapsedTime || ( this . durations . focus - this . timeRemaining ) ;
10841156 this . totalFocusTime += actualElapsedTime ;
10851157
10861158 // Store the actual elapsed time for undo functionality
10871159 this . lastCompletedSessionTime = actualElapsedTime ;
1160+
1161+ // Preserve session start time for saving
1162+ console . log ( 'Preserving session start time (timer completion):' , {
1163+ before : this . lastSessionStartTime ,
1164+ sessionStartTime : this . sessionStartTime ,
1165+ preservedValue : this . sessionStartTime
1166+ } ) ;
1167+ this . lastSessionStartTime = this . sessionStartTime ;
10881168
10891169 // Mark current task as completed if exists
10901170 if ( this . currentTask . trim ( ) ) {
@@ -1136,7 +1216,13 @@ export class PomodoroTimer {
11361216 }
11371217 }
11381218
1219+ // Save completed focus session to SessionManager as individual session BEFORE resetting sessionStartTime
1220+ if ( this . lastCompletedSessionTime > 0 && this . completedPomodoros > 0 ) {
1221+ await this . saveCompletedFocusSession ( ) ;
1222+ }
1223+
11391224 // Reset session tracking for next session
1225+ console . log ( 'Resetting sessionStartTime for next session (from completeSession)' ) ;
11401226 this . sessionStartTime = null ;
11411227 this . currentSessionElapsedTime = 0 ;
11421228 this . sessionCompletedButNotSaved = false ; // Reset flag
@@ -1151,11 +1237,6 @@ export class PomodoroTimer {
11511237 this . updateDisplay ( ) ;
11521238 this . updateButtons ( ) ;
11531239
1154- // Save completed focus session to SessionManager as individual session
1155- if ( this . lastCompletedSessionTime > 0 && this . completedPomodoros > 0 ) {
1156- await this . saveCompletedFocusSession ( ) ;
1157- }
1158-
11591240 // Only save aggregated session data, individual sessions are handled by saveCompletedFocusSession
11601241 await this . saveSessionData ( ) ;
11611242 this . showNotification ( ) ;
@@ -1228,14 +1309,22 @@ export class PomodoroTimer {
12281309 // Update completed sessions count for focus sessions
12291310 if ( this . currentMode === 'focus' ) {
12301311 this . completedPomodoros ++ ;
1231- this . updateProgressDots ( ) ;
1312+ await this . updateProgressDots ( ) ;
12321313
12331314 // Calculate actual elapsed time for focus sessions
12341315 const actualElapsedTime = this . currentSessionElapsedTime || this . durations . focus ;
12351316 this . totalFocusTime += actualElapsedTime ;
12361317
12371318 // Store the actual elapsed time for undo functionality
12381319 this . lastCompletedSessionTime = actualElapsedTime ;
1320+
1321+ // Preserve session start time for saving
1322+ console . log ( 'Preserving session start time (overtime):' , {
1323+ before : this . lastSessionStartTime ,
1324+ sessionStartTime : this . sessionStartTime ,
1325+ preservedValue : this . sessionStartTime
1326+ } ) ;
1327+ this . lastSessionStartTime = this . sessionStartTime ;
12391328
12401329 // Mark current task as completed if exists
12411330 if ( this . currentTask . trim ( ) ) {
@@ -1745,7 +1834,7 @@ export class PomodoroTimer {
17451834
17461835 // Update all displays
17471836 this . updateDisplay ( ) ;
1748- this . updateProgressDots ( ) ;
1837+ await this . updateProgressDots ( ) ;
17491838 this . updateButtons ( ) ;
17501839 await this . saveSessionData ( ) ;
17511840 this . updateTrayIcon ( ) ;
@@ -1773,7 +1862,7 @@ export class PomodoroTimer {
17731862 }
17741863
17751864 // Progress dots update
1776- updateProgressDots ( ) {
1865+ async updateProgressDots ( ) {
17771866 const dots = this . progressDots . querySelectorAll ( '.dot' ) ;
17781867
17791868 // Remove any existing overflow indicator
@@ -1782,20 +1871,23 @@ export class PomodoroTimer {
17821871 existingOverflow . remove ( ) ;
17831872 }
17841873
1785- // Update each dot based on completed pomodoros and current session
1874+ // Get actual completed sessions count from SessionManager
1875+ const actualCompletedSessions = await this . getCompletedSessionsToday ( ) ;
1876+
1877+ // Update each dot based on actual completed sessions and current session
17861878 dots . forEach ( ( dot , index ) => {
17871879 // Remove all classes first
17881880 dot . classList . remove ( 'completed' , 'current' ) ;
17891881
1790- if ( index < this . completedPomodoros ) {
1882+ if ( index < actualCompletedSessions ) {
17911883 dot . classList . add ( 'completed' ) ;
1792- } else if ( index === this . completedPomodoros && this . currentMode === 'focus' ) {
1884+ } else if ( index === actualCompletedSessions && this . currentMode === 'focus' ) {
17931885 dot . classList . add ( 'current' ) ;
17941886 }
17951887 } ) ;
17961888
1797- if ( this . completedPomodoros > this . totalSessions ) {
1798- const overflowCount = this . completedPomodoros - this . totalSessions ;
1889+ if ( actualCompletedSessions > this . totalSessions ) {
1890+ const overflowCount = actualCompletedSessions - this . totalSessions ;
17991891 const overflowIndicator = document . createElement ( 'div' ) ;
18001892 overflowIndicator . className = 'overflow-indicator' ;
18011893 overflowIndicator . textContent = `+${ overflowCount } ` ;
@@ -2050,6 +2142,21 @@ export class PomodoroTimer {
20502142 }
20512143 }
20522144
2145+ async getCompletedSessionsToday ( ) {
2146+ if ( ! window . sessionManager ) {
2147+ return this . completedPomodoros ; // Fallback to internal counter
2148+ }
2149+
2150+ try {
2151+ const today = new Date ( ) ; // Pass Date object instead of string
2152+ const todaySessions = await window . sessionManager . getSessionsForDate ( today ) ;
2153+ return todaySessions ? todaySessions . length : 0 ;
2154+ } catch ( error ) {
2155+ console . error ( 'Failed to get completed sessions from SessionManager:' , error ) ;
2156+ return this . completedPomodoros ; // Fallback to internal counter
2157+ }
2158+ }
2159+
20532160 async saveCompletedFocusSession ( ) {
20542161 if ( ! window . sessionManager ) {
20552162 console . log ( 'SessionManager not available, skipping individual session save' ) ;
@@ -2059,12 +2166,50 @@ export class PomodoroTimer {
20592166 const now = new Date ( ) ;
20602167 const durationMinutes = Math . round ( this . lastCompletedSessionTime / 60 ) ;
20612168
2062- // Calculate session end time (now) and start time (backwards from duration)
2169+ // Use preserved session start time if available, otherwise fall back to calculating backwards
2170+ let startHour , startMinute ;
2171+ const actualSessionStartTime = this . lastSessionStartTime ;
2172+
2173+ console . log ( 'Session saving debug:' , {
2174+ lastSessionStartTime : this . lastSessionStartTime ,
2175+ sessionStartTime : this . sessionStartTime ,
2176+ actualSessionStartTime : actualSessionStartTime ,
2177+ durationMinutes : durationMinutes ,
2178+ nowISO : now . toISOString ( ) ,
2179+ nowLocal : now . toString ( )
2180+ } ) ;
2181+
2182+ if ( actualSessionStartTime ) {
2183+ const sessionStart = new Date ( actualSessionStartTime ) ;
2184+ startHour = sessionStart . getHours ( ) ;
2185+ startMinute = sessionStart . getMinutes ( ) ;
2186+ console . log ( 'Using preserved session start time:' , {
2187+ timestampUTC : sessionStart . toISOString ( ) ,
2188+ timestampLocal : sessionStart . toString ( ) ,
2189+ extractedHour : startHour ,
2190+ extractedMinute : startMinute
2191+ } ) ;
2192+ } else {
2193+ // Fallback to calculating backwards from duration
2194+ const endHour = now . getHours ( ) ;
2195+ const endMinute = now . getMinutes ( ) ;
2196+ const startTotalMinutes = endHour * 60 + endMinute - durationMinutes ;
2197+ startHour = Math . max ( 0 , Math . floor ( startTotalMinutes / 60 ) ) ;
2198+ startMinute = Math . max ( 0 , startTotalMinutes % 60 ) ;
2199+ console . log ( 'Using fallback calculation for session start time (no preserved time available)' ) ;
2200+ }
2201+
20632202 const endHour = now . getHours ( ) ;
20642203 const endMinute = now . getMinutes ( ) ;
2065- const startTotalMinutes = endHour * 60 + endMinute - durationMinutes ;
2066- const startHour = Math . max ( 0 , Math . floor ( startTotalMinutes / 60 ) ) ;
2067- const startMinute = Math . max ( 0 , startTotalMinutes % 60 ) ;
2204+
2205+ console . log ( 'Final time values:' , {
2206+ startHour : startHour ,
2207+ startMinute : startMinute ,
2208+ endHour : endHour ,
2209+ endMinute : endMinute ,
2210+ startTimeString : `${ startHour . toString ( ) . padStart ( 2 , '0' ) } :${ startMinute . toString ( ) . padStart ( 2 , '0' ) } ` ,
2211+ endTimeString : `${ endHour . toString ( ) . padStart ( 2 , '0' ) } :${ endMinute . toString ( ) . padStart ( 2 , '0' ) } `
2212+ } ) ;
20682213
20692214 // Get current tags from TagManager
20702215 const currentTags = window . tagManager ? window . tagManager . getCurrentTags ( ) : [ ] ;
@@ -2083,6 +2228,10 @@ export class PomodoroTimer {
20832228 try {
20842229 await window . sessionManager . addSession ( sessionData ) ;
20852230 console . log ( 'Timer session saved to SessionManager:' , sessionData ) ;
2231+
2232+ // Clear the preserved session start time after successful save
2233+ this . lastSessionStartTime = null ;
2234+ console . log ( 'Cleared lastSessionStartTime after successful save' ) ;
20862235 } catch ( error ) {
20872236 console . error ( 'Failed to save timer session to SessionManager:' , error ) ;
20882237 }
@@ -2101,14 +2250,14 @@ export class PomodoroTimer {
21012250 this . completedPomodoros = data . completed_pomodoros || 0 ;
21022251 this . totalFocusTime = data . total_focus_time || 0 ;
21032252 this . currentSession = data . current_session || 1 ;
2104- this . updateProgressDots ( ) ;
2253+ await this . updateProgressDots ( ) ;
21052254 console . log ( '📊 Loaded existing session data for today' ) ;
21062255 } else {
21072256 // Reset to default values for new day, no data, or forced reset
21082257 this . completedPomodoros = 0 ;
21092258 this . totalFocusTime = 0 ;
21102259 this . currentSession = 1 ;
2111- this . updateProgressDots ( ) ;
2260+ await this . updateProgressDots ( ) ;
21122261 console . log ( '🌅 Reset session data for new day or forced reset' ) ;
21132262 }
21142263 } catch ( error ) {
@@ -2122,22 +2271,22 @@ export class PomodoroTimer {
21222271 this . completedPomodoros = data . completedPomodoros || 0 ;
21232272 this . totalFocusTime = data . totalFocusTime || 0 ;
21242273 this . currentSession = data . currentSession || 1 ;
2125- this . updateProgressDots ( ) ;
2274+ await this . updateProgressDots ( ) ;
21262275 console . log ( '📊 Loaded existing session data from localStorage' ) ;
21272276 } else {
21282277 // Reset to default values for new day, no data, or forced reset
21292278 this . completedPomodoros = 0 ;
21302279 this . totalFocusTime = 0 ;
21312280 this . currentSession = 1 ;
2132- this . updateProgressDots ( ) ;
2281+ await this . updateProgressDots ( ) ;
21332282 console . log ( '🌅 Reset session data from localStorage for new day or forced reset' ) ;
21342283 }
21352284 } else {
21362285 // No saved data at all, reset to defaults
21372286 this . completedPomodoros = 0 ;
21382287 this . totalFocusTime = 0 ;
21392288 this . currentSession = 1 ;
2140- this . updateProgressDots ( ) ;
2289+ await this . updateProgressDots ( ) ;
21412290 console . log ( '🌅 No saved data found, using defaults' ) ;
21422291 }
21432292 }
@@ -2288,7 +2437,7 @@ export class PomodoroTimer {
22882437
22892438 // Regenerate progress dots when total sessions change
22902439 this . generateProgressDots ( ) ;
2291- this . updateProgressDots ( ) ;
2440+ await this . updateProgressDots ( ) ;
22922441
22932442 // Update notification preferences
22942443 this . enableDesktopNotifications = settings . notifications . desktop_notifications ;
0 commit comments