Skip to content

Commit 260d2bf

Browse files
authored
Merge pull request #31 from murdercode/stats-fix
Stats fix
2 parents fade1dc + b1cde51 commit 260d2bf

File tree

5 files changed

+238
-49
lines changed

5 files changed

+238
-49
lines changed

src/core/pomodoro-timer.js

Lines changed: 175 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)