Skip to content

Commit b3a7dcd

Browse files
committed
update: handle calculating effective month
1 parent 6ec5f18 commit b3a7dcd

1 file changed

Lines changed: 117 additions & 8 deletions

File tree

src/core/contributions.ts

Lines changed: 117 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { githubGraphQL } from "../api/api.js";
2-
import { GitHubContribution } from "../types/types.js";
2+
import { GitHubContribution, MonthlyContribution } from "../types/types.js";
33

44
export const getGitHubContributions = async (
55
username: string,
@@ -140,23 +140,124 @@ const CONTRIBUTIONS_QUERY = `
140140
}
141141
`;
142142

143+
interface ContributionDay {
144+
contributionCount: number;
145+
date: string;
146+
color: string;
147+
}
148+
143149
interface ContributionResponse {
144150
user: {
145151
contributionsCollection: {
146152
contributionCalendar: {
147153
totalContributions: number;
148154
weeks: Array<{
149-
contributionDays: Array<{
150-
contributionCount: number;
151-
date: string;
152-
color: string;
153-
}>;
155+
contributionDays: Array<ContributionDay>;
154156
}>;
155157
};
156158
};
157159
};
158160
}
159161

162+
interface StreakData {
163+
count: number;
164+
startDate: string;
165+
endDate: string;
166+
}
167+
168+
const calcStreakStats = (
169+
days: ContributionDay[]
170+
): { longestStreak: StreakData; activeDays: number } => {
171+
let longestStreak: StreakData = { count: 0, startDate: "", endDate: "" };
172+
173+
let tempStreak: StreakData = { count: 0, startDate: "", endDate: "" };
174+
175+
// ensure chronological order
176+
const sortedDays = [...days].sort(
177+
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
178+
);
179+
const activeDays = sortedDays.filter(
180+
(day) => day.contributionCount > 0
181+
).length;
182+
183+
sortedDays.forEach((day) => {
184+
if (day.contributionCount > 0) {
185+
if (tempStreak.count === 0) {
186+
tempStreak.startDate = day.date;
187+
}
188+
tempStreak.count++;
189+
tempStreak.endDate = day.date;
190+
191+
if (tempStreak.count > longestStreak.count) {
192+
longestStreak = { ...tempStreak };
193+
}
194+
} else {
195+
tempStreak = { count: 0, startDate: "", endDate: "" };
196+
}
197+
});
198+
199+
return { longestStreak, activeDays };
200+
};
201+
202+
const monthNames = [
203+
"January",
204+
"February",
205+
"March",
206+
"April",
207+
"May",
208+
"June",
209+
"July",
210+
"August",
211+
"September",
212+
"October",
213+
"November",
214+
"December"
215+
];
216+
217+
const getEffectiveMonth = (days: ContributionDay[], totalCommit: number) => {
218+
const monthlyCounts = new Array(12).fill(0);
219+
days.forEach((day) => {
220+
const monthlyIndex = new Date(day.date).getUTCMonth();
221+
monthlyCounts[monthlyIndex] += day.contributionCount;
222+
});
223+
224+
let maxCount = -1;
225+
let maxIndex = 0;
226+
227+
monthlyCounts.forEach((count, index) => {
228+
if (count > maxCount) {
229+
maxCount = count;
230+
maxIndex = index;
231+
}
232+
});
233+
234+
return {
235+
index: maxIndex,
236+
name: monthNames[maxIndex],
237+
contributionCounts: maxCount,
238+
percent:
239+
totalCommit > 0 ? Math.round((maxCount / totalCommit) * 1000) / 10 : 0
240+
};
241+
};
242+
243+
export const getMonthlyContributions = (
244+
days: ContributionDay[],
245+
totalCommit: number
246+
): MonthlyContribution[] => {
247+
const monthlyCounts = new Array(12).fill(0);
248+
days.forEach((day) => {
249+
const monthlyIndex = new Date(day.date).getUTCMonth();
250+
monthlyCounts[monthlyIndex] += day.contributionCount;
251+
});
252+
253+
return monthlyCounts.map((count, index) => ({
254+
index,
255+
name: monthNames[index],
256+
contributionCounts: count,
257+
percent: totalCommit > 0 ? Math.round((count / totalCommit) * 1000) / 10 : 0
258+
}));
259+
};
260+
160261
export const getGitHubYearlyContributions = async (
161262
username: string,
162263
year: number,
@@ -175,9 +276,17 @@ export const getGitHubYearlyContributions = async (
175276

176277
const dailyData = calendar.weeks.flatMap((week) => week.contributionDays);
177278

279+
const streakStats = calcStreakStats(dailyData);
280+
const effectiveMonth = getEffectiveMonth(
281+
dailyData,
282+
calendar.totalContributions
283+
);
284+
178285
return {
179286
year,
180287
totalContributions: calendar.totalContributions,
181-
days: dailyData
288+
days: dailyData,
289+
streakStats,
290+
effectiveMonth
182291
};
183-
};
292+
};

0 commit comments

Comments
 (0)