11import { Md } from '@m2d/react-markdown/client' ;
22import { capitalize } from 'es-toolkit' ;
3- import { useEffect , useState } from 'react' ;
43import { View } from 'react-native' ;
54import { type Theme } from 'react-shiki' ;
65import rehypeRaw from 'rehype-raw' ;
76import rehypeSanitize from 'rehype-sanitize' ;
87import remarkEmoji from 'remark-emoji' ;
98import remarkGfm from 'remark-gfm' ;
9+ import useSWR from 'swr' ;
1010
1111import { A , P } from '~/common/styleguide' ;
1212import { ReadmeFile } from '~/components/Icons' ;
@@ -26,62 +26,30 @@ type Props = {
2626} ;
2727
2828export default function ReadmeBox ( { packageName, githubUrl, isTemplate, loader = false } : Props ) {
29- const [ readmeContent , setReadmeContent ] = useState < string | null | undefined > ( undefined ) ;
30-
31- useEffect ( ( ) => {
32- if ( loader ) {
33- return ;
34- }
35-
36- let cancelled = false ;
37-
38- void ( async ( ) => {
39- if ( isTemplate ) {
40- const templateRawUrl = githubUrl ?. replace ( 'github.com/' , 'raw.githubusercontent.com/' ) ;
41- let readmeResponse = await fetch ( `${ templateRawUrl } /main/README.md` ) ;
42-
43- if ( readmeResponse . status === 404 ) {
44- readmeResponse = await fetch ( `${ templateRawUrl } /master/README.md` ) ;
29+ const { data, error, isLoading } = useSWR (
30+ isTemplate
31+ ? `${ githubUrl ?. replace ( 'github.com/' , 'raw.githubusercontent.com/' ) } /HEAD/README.md`
32+ : `https://unpkg.com/${ packageName } /README.md` ,
33+ ( url : string ) =>
34+ fetch ( url ) . then ( res => {
35+ if ( res . status === 404 ) {
36+ return '' ;
37+ } else if ( res . status === 200 ) {
38+ return res . text ( ) ;
4539 }
46-
47- if ( readmeResponse . status === 200 ) {
48- const readmeContent = await readmeResponse . text ( ) ;
49- if ( ! cancelled ) {
50- setReadmeContent ( readmeContent ) ;
51- }
52- } else {
53- setReadmeContent ( '' ) ;
54- }
55- } else {
56- try {
57- const readmeResponse = await fetch ( `https://unpkg.com/${ packageName } /README.md` ) ;
58- const readmeContent = await readmeResponse . text ( ) ;
59- if ( ! cancelled ) {
60- setReadmeContent ( readmeContent ) ;
61- }
62- } catch ( error : any ) {
63- if ( error instanceof Error ) {
64- if ( error . message === 'Failed to fetch' ) {
65- setReadmeContent ( '' ) ;
66- return ;
67- }
68- }
69- if ( ! cancelled ) {
70- setReadmeContent ( null ) ;
71- }
72- }
73- }
74- } ) ( ) ;
75- return ( ) => {
76- cancelled = true ;
77- } ;
78- } , [ ] ) ;
40+ return null ;
41+ } ) ,
42+ {
43+ dedupingInterval : 60_000 * 10 ,
44+ revalidateOnFocus : false ,
45+ }
46+ ) ;
7947
8048 if ( ! githubUrl || ! packageName ) {
8149 return null ;
8250 }
8351
84- const readmeFallbackContent = getReadmeFallbackContent ( readmeContent ) ;
52+ const readmeFallbackContent = getReadmeFallbackContent ( data , isLoading , error ) ;
8553
8654 return (
8755 < View
@@ -92,9 +60,9 @@ export default function ReadmeBox({ packageName, githubUrl, isTemplate, loader =
9260 < P > Readme</ P >
9361 </ View >
9462 < View style = { tw `p-4 pt-3 font-light` } >
95- { ! readmeContent && readmeFallbackContent ? (
63+ { ! data && readmeFallbackContent ? (
9664 < View style = { tw `gap-4 py-6` } >
97- { readmeContent === undefined && < ThreeDotsLoader /> }
65+ { isLoading && < ThreeDotsLoader /> }
9866 < P style = { tw `text-center` } > { readmeFallbackContent } </ P >
9967 </ View >
10068 ) : (
@@ -201,21 +169,25 @@ export default function ReadmeBox({ packageName, githubUrl, isTemplate, loader =
201169 } }
202170 rehypePlugins = { [ rehypeRaw , rehypeSanitize ] }
203171 remarkPlugins = { [ remarkGfm , remarkEmoji ] } >
204- { readmeContent ?? undefined }
172+ { data ?? undefined }
205173 </ Md >
206174 ) }
207175 </ View >
208176 </ View >
209177 ) ;
210178}
211179
212- function getReadmeFallbackContent ( readmeContent ?: string | null ) : string | null {
213- if ( readmeContent === undefined ) {
180+ function getReadmeFallbackContent (
181+ readmeContent ?: string | null ,
182+ isLoading ?: boolean ,
183+ error ?: string
184+ ) : string | null {
185+ if ( isLoading ) {
214186 return 'Loading README…' ;
215- } else if ( readmeContent === null ) {
216- return 'Cannot fetch README file content.' ;
217187 } else if ( readmeContent === '' ) {
218188 return 'This package does not have a README file.' ;
189+ } else if ( readmeContent === null || error ) {
190+ return `Cannot fetch README file content.` ;
219191 }
220192 return null ;
221193}
0 commit comments