(dailyActivity: DailyActivity[])
| 851 | } |
| 852 | |
| 853 | function calculateStreaks(dailyActivity: DailyActivity[]): StreakInfo { |
| 854 | if (dailyActivity.length === 0) { |
| 855 | return { |
| 856 | currentStreak: 0, |
| 857 | longestStreak: 0, |
| 858 | currentStreakStart: null, |
| 859 | longestStreakStart: null, |
| 860 | longestStreakEnd: null, |
| 861 | } |
| 862 | } |
| 863 | |
| 864 | const today = new Date() |
| 865 | today.setHours(0, 0, 0, 0) |
| 866 | |
| 867 | // Calculate current streak (working backwards from today) |
| 868 | let currentStreak = 0 |
| 869 | let currentStreakStart: string | null = null |
| 870 | const checkDate = new Date(today) |
| 871 | |
| 872 | // Build a set of active dates for quick lookup |
| 873 | const activeDates = new Set(dailyActivity.map(d => d.date)) |
| 874 | |
| 875 | while (true) { |
| 876 | const dateStr = toDateString(checkDate) |
| 877 | if (!activeDates.has(dateStr)) { |
| 878 | break |
| 879 | } |
| 880 | currentStreak++ |
| 881 | currentStreakStart = dateStr |
| 882 | checkDate.setDate(checkDate.getDate() - 1) |
| 883 | } |
| 884 | |
| 885 | // Calculate longest streak |
| 886 | let longestStreak = 0 |
| 887 | let longestStreakStart: string | null = null |
| 888 | let longestStreakEnd: string | null = null |
| 889 | |
| 890 | if (dailyActivity.length > 0) { |
| 891 | const sortedDates = Array.from(activeDates).sort() |
| 892 | let tempStreak = 1 |
| 893 | let tempStart = sortedDates[0]! |
| 894 | |
| 895 | for (let i = 1; i < sortedDates.length; i++) { |
| 896 | const prevDate = new Date(sortedDates[i - 1]!) |
| 897 | const currDate = new Date(sortedDates[i]!) |
| 898 | |
| 899 | const dayDiff = Math.round( |
| 900 | (currDate.getTime() - prevDate.getTime()) / (1000 * 60 * 60 * 24), |
| 901 | ) |
| 902 | |
| 903 | if (dayDiff === 1) { |
| 904 | tempStreak++ |
| 905 | } else { |
| 906 | if (tempStreak > longestStreak) { |
| 907 | longestStreak = tempStreak |
| 908 | longestStreakStart = tempStart |
| 909 | longestStreakEnd = sortedDates[i - 1]! |
| 910 | } |
no test coverage detected