@@ -2,9 +2,13 @@ import { join } from "path"
2
2
3
3
import { useEffect , useState } from "react"
4
4
5
- import type { Author , FileContributorsState } from "@/lib/types"
5
+ import type { Author , Commit , FileContributorsState } from "@/lib/types"
6
6
7
- import { CONTENT_DIR , GITHUB_COMMITS_URL } from "@/lib/constants"
7
+ import {
8
+ CONTENT_DIR ,
9
+ GITHUB_COMMITS_URL ,
10
+ OLD_CONTENT_DIR ,
11
+ } from "@/lib/constants"
8
12
9
13
export const gitHubAuthHeaders = {
10
14
headers : new Headers ( {
@@ -13,42 +17,19 @@ export const gitHubAuthHeaders = {
13
17
} ) ,
14
18
}
15
19
16
- const fetchGitHubContributors = async (
17
- relativePath : string
18
- ) : Promise < FileContributorsState > => {
20
+ const fetchGitHubCommits = async ( filePath : string ) : Promise < Commit [ ] > => {
19
21
const url = new URL ( GITHUB_COMMITS_URL )
20
- const filePath = join ( CONTENT_DIR , relativePath , "index.md" )
21
22
url . searchParams . set ( "path" , filePath )
22
23
23
24
try {
24
25
const response = await fetch ( url , gitHubAuthHeaders )
25
26
if ( ! response . ok ) throw new Error ( response . statusText )
26
- const commits = await response . json ( )
27
- const authorSet = new Set < string > ( )
28
- commits
29
- . filter ( ( { author } ) => author )
30
- . forEach ( ( { author, commit } ) => {
31
- const entry : Author = {
32
- name : commit . author . name ,
33
- email : commit . author . email ,
34
- avatarUrl : author . avatar_url ,
35
- user : {
36
- login : author . login ,
37
- url : author . html_url ,
38
- } ,
39
- }
40
- // Unique authors only
41
- authorSet . add ( JSON . stringify ( entry ) )
42
- } )
43
- const authors = Array . from ( authorSet ) . map (
44
- JSON . parse as ( entry : string ) => Author
45
- )
46
- return { loading : false , data : authors }
27
+ return ( await response . json ( ) ) as Commit [ ]
47
28
} catch ( error : unknown ) {
48
29
if ( error instanceof Error ) {
49
30
console . error ( filePath , error . message )
50
31
}
51
- return { loading : false , error }
32
+ throw error
52
33
}
53
34
}
54
35
/**
@@ -63,7 +44,41 @@ export const useClientSideGitHubContributors = (
63
44
const [ state , setState ] = useState < FileContributorsState > ( { loading : true } )
64
45
useEffect ( ( ) => {
65
46
; ( async ( ) => {
66
- setState ( await fetchGitHubContributors ( relativePath ) )
47
+ const oldFilePath = join ( OLD_CONTENT_DIR , relativePath , "index.md" )
48
+ const filePath = join ( CONTENT_DIR , relativePath , "index.md" )
49
+
50
+ try {
51
+ const oldCommits = await fetchGitHubCommits ( oldFilePath )
52
+ const newCommits = await fetchGitHubCommits ( filePath )
53
+
54
+ const authorSet = new Set < string > ( )
55
+
56
+ ; [ ...oldCommits , ...newCommits ]
57
+ . filter ( ( { author } ) => author )
58
+ . forEach ( ( { author, commit } ) => {
59
+ const entry : Author = {
60
+ name : commit . author . name ,
61
+ email : commit . author . email ,
62
+ avatarUrl : author . avatar_url ,
63
+ user : {
64
+ login : author . login ,
65
+ url : author . html_url ,
66
+ } ,
67
+ }
68
+ // Unique authors only
69
+ authorSet . add ( JSON . stringify ( entry ) )
70
+ } )
71
+ const authors = Array . from ( authorSet ) . map (
72
+ JSON . parse as ( entry : string ) => Author
73
+ )
74
+
75
+ setState ( {
76
+ loading : false ,
77
+ data : authors ,
78
+ } )
79
+ } catch ( error : unknown ) {
80
+ setState ( { loading : false , error } )
81
+ }
67
82
} ) ( )
68
83
} , [ relativePath ] )
69
84
return state
0 commit comments