Static generate gists code

This commit is contained in:
Defectink
2022-04-29 09:44:59 +08:00
parent cedc921035
commit 32e0f1c953
5 changed files with 65 additions and 56 deletions

View File

@ -0,0 +1,21 @@
import React from 'react';
import classNames from 'classnames';
import loadingImage from 'public/images/img/mona-loading-default.gif';
import Image from 'next/image';
const RUALoading = () => {
return (
<div
className={classNames(
'h-[300px] flex loading',
'flex-col items-center justify-center'
)}
>
<Image width={50} height={50} src={loadingImage} alt="Loading" />
<span className="my-4">rua rua rua...</span>
</div>
);
};
export default RUALoading;

View File

@ -1,39 +1,17 @@
import { Gist } from 'types'; import { GistsFile } from 'types';
import { unified } from 'unified'; import { unified } from 'unified';
import remarkParse from 'remark-parse'; import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype'; import remarkRehype from 'remark-rehype';
import rehypePrism from '@mapbox/rehype-prism'; import rehypePrism from '@mapbox/rehype-prism';
import remarkGfm from 'remark-gfm'; import remarkGfm from 'remark-gfm';
import { createElement, Fragment, useEffect, useState } from 'react'; import { createElement, Fragment } from 'react';
import rehypeReact from 'rehype-react'; import rehypeReact from 'rehype-react';
import classNames from 'classnames';
import useInView from 'lib/hooks/useInView';
import loadingImage from 'public/images/img/mona-loading-default.gif';
import Image from 'next/image';
interface Props { interface Props {
gist: Gist; file: GistsFile;
f: string;
} }
const GistsCode = ({ gist, f }: Props) => { const GistsCode = ({ file }: Props) => {
const file = gist.files;
const url = file[f].raw_url;
const format = file[f].language;
const { ref, inView } = useInView();
const [rawCode, setRawCode] = useState('');
useEffect(() => {
inView && getRawCode();
async function getRawCode() {
const res = await fetch(url);
const raw = await res.text();
setRawCode(`\`\`\`${format ?? ''}\n${raw}`);
}
}, [format, inView, url]);
const code = unified() const code = unified()
.use(remarkParse) .use(remarkParse)
.use(remarkRehype) .use(remarkRehype)
@ -43,26 +21,11 @@ const GistsCode = ({ gist, f }: Props) => {
createElement, createElement,
Fragment, Fragment,
}) })
.processSync(rawCode).result; .processSync(`\`\`\`${file.language ?? ''}\n${file.content}`).result;
return ( return (
<> <>
<div ref={ref}> <div>{code}</div>
{rawCode ? (
<div className={classNames(!rawCode && 'min-h-[300px]')}>{code}</div>
) : (
<div
className={classNames(
'h-[300px] flex loading',
'flex-col items-center justify-center'
)}
>
<Image width={50} height={50} src={loadingImage} alt="Loading" />
<span className="my-4">rua rua rua...</span>
</div>
)}
</div>
</> </>
); );
}; };

View File

@ -71,7 +71,7 @@ const Gist = ({ gist }: InferGetStaticPropsType<typeof getStaticProps>) => {
</div> </div>
</div> </div>
<GistsCode gist={gist} f={f} /> <GistsCode file={gist.files[f]} />
</div> </div>
))} ))}
</div> </div>
@ -92,14 +92,24 @@ export const getStaticProps: GetStaticProps<{
id: string | undefined; id: string | undefined;
gist: SignalGist; gist: SignalGist;
}> = async ({ params }) => { }> = async ({ params }) => {
const gist = (await fetch(`https://api.github.com/gists/${params?.id}`).then(
(res) => res.json()
)) as SignalGist;
await Promise.all(
Object.keys(gist.files).map(async (f) => {
gist.files[f].content = await fetch(gist.files[f].raw_url).then((res) =>
res.text()
);
})
);
return { return {
props: { props: {
id: params?.id?.toString(), id: params?.id?.toString(),
gist: await fetch(`https://api.github.com/gists/${params?.id}`).then( gist,
(res) => res.json()
),
}, },
revalidate: 3600, revalidate: 600,
}; };
}; };

View File

@ -15,7 +15,6 @@ const Gists = ({
gists, gists,
user, user,
}: InferGetStaticPropsType<typeof getStaticProps>) => { }: InferGetStaticPropsType<typeof getStaticProps>) => {
console.log(gists);
return ( return (
<> <>
<main className="max-w-5xl px-4 mx-auto lg:px-0"> <main className="max-w-5xl px-4 mx-auto lg:px-0">
@ -66,7 +65,7 @@ const Gists = ({
<p className="text-gray-400">Update at: {g.updated_at}</p> <p className="text-gray-400">Update at: {g.updated_at}</p>
<p className="text-gray-500">{g.description}</p> <p className="text-gray-500">{g.description}</p>
<GistsCode gist={g} f={f} /> <GistsCode file={g.files[f]} />
</div> </div>
))} ))}
</div> </div>
@ -82,14 +81,29 @@ export const getStaticProps: GetStaticProps<{
gists: Gist[]; gists: Gist[];
user: GithubUser; user: GithubUser;
}> = async () => { }> = async () => {
const gists = (await fetch(
'https://api.github.com/users/DefectingCat/gists'
).then((res) => res.json())) as Gist[];
const user = await fetch('https://api.github.com/users/DefectingCat').then(
(res) => res.json()
);
await Promise.all(
gists.map(async (g) => {
await Promise.all(
Object.keys(g.files).map(async (f) => {
g.files[f].content = await fetch(g.files[f].raw_url).then((res) =>
res.text()
);
})
);
})
);
return { return {
props: { props: {
gists: await fetch( gists,
'https://api.github.com/users/DefectingCat/gists' user,
).then((res) => res.json()),
user: await fetch('https://api.github.com/users/DefectingCat').then(
(res) => res.json()
),
}, },
revalidate: 600, revalidate: 600,
}; };

View File

@ -47,6 +47,7 @@ export interface GistsFile {
language: GistsLanguage | null; language: GistsLanguage | null;
raw_url: string; raw_url: string;
size: number; size: number;
content: string;
} }
export enum GistsLanguage { export enum GistsLanguage {
JavaScript = 'JavaScript', JavaScript = 'JavaScript',