-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstreakCounter.js
More file actions
132 lines (113 loc) · 3.88 KB
/
streakCounter.js
File metadata and controls
132 lines (113 loc) · 3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
* Moduł Streak Counter
* Odpowiedzialny za obliczanie i zarządzanie streak'ami (dniami z rzędu z osiągnięciami)
*/
// Check if a date is a workday (Monday-Friday)
function isWorkday(date) {
const day = date.getDay();
return day >= 1 && day <= 5; // 1 = Monday, 5 = Friday
}
// Get date string in YYYY-MM-DD format
function getDateString(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
// Load streak data from localStorage
function loadStreakData() {
const data = localStorage.getItem('streakData');
if (data) {
return JSON.parse(data);
}
return {
current: 0,
longest: 0,
lastAchievementDate: null,
skippedDays: 0,
lastCalculated: null
};
}
// Save streak data to localStorage
function saveStreakData(streakData) {
localStorage.setItem('streakData', JSON.stringify(streakData));
}
// Calculate current streak based on achievement history
function calculateStreak() {
const today = new Date();
const todayStr = getDateString(today);
// Get all achievement dates from localStorage
const achievementDates = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key && key.startsWith('achievements_')) {
const dateStr = key.replace('achievements_', '');
const achievements = JSON.parse(localStorage.getItem(key) || '[]');
if (achievements.length > 0) {
achievementDates.push(dateStr);
}
}
}
// Sort dates in descending order (newest first)
achievementDates.sort((a, b) => new Date(b) - new Date(a));
// Load previous streak data
const streakData = loadStreakData();
let currentStreak = 0;
let consecutiveSkips = 0;
let usedTolerance = false;
// Iterate backwards from today to calculate streak
let checkDate = new Date(today);
let foundToday = achievementDates.includes(todayStr);
// If today has achievement, start counting from today
if (foundToday) {
currentStreak = 1;
checkDate.setDate(checkDate.getDate() - 1);
}
// Go back through workdays to count streak
for (let i = 0; i < 60; i++) { // Check last 60 days max
// Skip weekends
while (!isWorkday(checkDate)) {
checkDate.setDate(checkDate.getDate() - 1);
}
const checkDateStr = getDateString(checkDate);
const hasAchievement = achievementDates.includes(checkDateStr);
if (hasAchievement) {
currentStreak++;
consecutiveSkips = 0; // Reset skip counter
} else {
consecutiveSkips++;
if (consecutiveSkips === 1) {
// First skip - use tolerance
usedTolerance = true;
} else if (consecutiveSkips >= 2) {
// Second consecutive skip - break streak
break;
}
}
checkDate.setDate(checkDate.getDate() - 1);
}
// Update longest streak
const longestStreak = Math.max(streakData.longest, currentStreak);
// Save updated streak data
const updatedStreakData = {
current: currentStreak,
longest: longestStreak,
lastAchievementDate: foundToday ? todayStr : streakData.lastAchievementDate,
skippedDays: consecutiveSkips,
lastCalculated: todayStr,
showMotivation: usedTolerance && currentStreak > 0
};
saveStreakData(updatedStreakData);
return updatedStreakData;
}
// Export functions for use in other modules
if (typeof module !== 'undefined' && module.exports) {
// Node.js environment (for tests)
module.exports = {
isWorkday,
getDateString,
loadStreakData,
saveStreakData,
calculateStreak
};
}