Add gists skeleton animation

This commit is contained in:
DefectingCat
2023-01-30 11:37:15 +08:00
parent 3c001e0028
commit 35d1aeec9e
13 changed files with 120 additions and 33 deletions

View File

@ -0,0 +1,66 @@
import LinkAnchor from 'components/mdx/link-anchor';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import MainLayout from 'layouts/common/main-layout';
import { getSignalGist, SingalGist } from 'lib/fetcher';
import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next';
import dynamic from 'next/dynamic';
import Image from 'next/image';
import Link from 'next/link';
import avatar from 'public/images/img/avatar.svg';
import { Fragment, ReactElement, Suspense } from 'react';
import { useRouter } from 'next/router';
import clsx from 'clsx';
const GistsCode = dynamic(() => import('components/gists/gists-code'), {
suspense: true,
});
dayjs.extend(relativeTime);
const GistSkeleton = () => {
return (
<>
<main className="max-w-5xl px-4 mx-auto lg:px-0">
<div className="pb-4 text-sm">
<div className="flex items-center py-1 ">
<div
className={clsx(
'w-8 h-8 rounded-full',
'animate-pulse bg-gray-300'
)}
></div>
<h1
className={clsx(
'ml-2 overflow-hidden text-xl',
'whitespace-nowrap overflow-ellipsis',
'w-[234px] animate-pulse bg-gray-300',
'h-6 rounded-lg'
)}
></h1>
</div>
<p
className={clsx(
'ml-10 text-gray-400',
'w-48 h-4 animate-pulse bg-gray-300',
'rounded-lg'
)}
></p>
<div className="py-4">
<p className="pb-2 text-lg text-gray-500">
<span className={'w-16 animate-pulse'}></span>
</p>
<Suspense fallback>
{/*<GistsCode file={gist.files[f]} showFileName />*/}
</Suspense>
</div>
</div>
</main>
</>
);
};
export default GistSkeleton;

View File

@ -3,11 +3,12 @@ import { memo, ReactNode } from 'react';
import { FiExternalLink } from 'react-icons/fi'; import { FiExternalLink } from 'react-icons/fi';
interface Props { interface Props {
children: ReactNode; children?: ReactNode;
external?: boolean; external?: boolean;
className?: string;
} }
const Anchor = ({ children, external = true }: Props) => { const Anchor = ({ children, external = true, className }: Props) => {
return ( return (
<> <>
<span <span
@ -16,7 +17,8 @@ const Anchor = ({ children, external = true }: Props) => {
'before:left-0 before:top-[1px] before:block before:absolute', 'before:left-0 before:top-[1px] before:block before:absolute',
'before:w-full before:h-full before:transition-all before:shadow-underline', 'before:w-full before:h-full before:transition-all before:shadow-underline',
'hover:before:shadow-throughline', 'hover:before:shadow-throughline',
'dark:text-teal-600' 'dark:text-teal-600',
className
)} )}
> >
{children} {children}

View File

@ -1,6 +1,6 @@
import TWEEN from '@tweenjs/tween.js'; import TWEEN from '@tweenjs/tween.js';
import clsx from 'clsx'; import clsx from 'clsx';
import MainLayout from 'layouts/main-layout'; import MainLayout from 'layouts/common/main-layout';
import { gltfLoader, manager } from 'lib/gltf-loader'; import { gltfLoader, manager } from 'lib/gltf-loader';
import { getMousePosition } from 'lib/utils'; import { getMousePosition } from 'lib/utils';
import { useTheme } from 'next-themes'; import { useTheme } from 'next-themes';

View File

@ -1,5 +1,5 @@
import PostCardLoading from 'components/rua/loading/post-card-loading'; import PostCardLoading from 'components/rua/loading/post-card-loading';
import MainLayout from 'layouts/main-layout'; import MainLayout from 'layouts/common/main-layout';
import { getPostListPath, postLists, PostPerPage } from 'lib/posts'; import { getPostListPath, postLists, PostPerPage } from 'lib/posts';
import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next'; import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
@ -9,7 +9,9 @@ import { Post } from 'types';
const PostCard = dynamic(() => import('components/post-card'), { const PostCard = dynamic(() => import('components/post-card'), {
suspense: true, suspense: true,
}); });
const BlogList = dynamic(() => import('layouts/blog-list'), { suspense: true }); const BlogList = dynamic(() => import('layouts/common/blog-list'), {
suspense: true,
});
const Pagination = dynamic(() => import('components/rua/rua-pagination'), { const Pagination = dynamic(() => import('components/rua/rua-pagination'), {
suspense: true, suspense: true,
}); });

View File

@ -1,5 +1,5 @@
import PostCardLoading from 'components/rua/loading/post-card-loading'; import PostCardLoading from 'components/rua/loading/post-card-loading';
import MainLayout from 'layouts/main-layout'; import MainLayout from 'layouts/common/main-layout';
import { postLists, PostPerPage } from 'lib/posts'; import { postLists, PostPerPage } from 'lib/posts';
import { GetStaticProps, InferGetStaticPropsType } from 'next'; import { GetStaticProps, InferGetStaticPropsType } from 'next';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
@ -9,7 +9,9 @@ import { Post } from 'types';
const PostCard = dynamic(() => import('components/post-card'), { const PostCard = dynamic(() => import('components/post-card'), {
suspense: true, suspense: true,
}); });
const BlogList = dynamic(() => import('layouts/blog-list'), { suspense: true }); const BlogList = dynamic(() => import('layouts/common/blog-list'), {
suspense: true,
});
const Pagination = dynamic(() => import('components/rua/rua-pagination'), { const Pagination = dynamic(() => import('components/rua/rua-pagination'), {
suspense: true, suspense: true,
}); });

View File

@ -1,23 +1,36 @@
import LinkAnchor from 'components/mdx/link-anchor'; import LinkAnchor from 'components/mdx/link-anchor';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime'; import relativeTime from 'dayjs/plugin/relativeTime';
import MainLayout from 'layouts/main-layout'; import MainLayout from 'layouts/common/main-layout';
import { getGists, getSignalGist, SingalGist } from 'lib/fetcher'; import { getSignalGist, SingalGist } from 'lib/fetcher';
import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next'; import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import Image from 'next/image'; import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import avatar from 'public/images/img/avatar.svg'; import avatar from 'public/images/img/avatar.svg';
import { ParsedUrlQuery } from 'querystring';
import { Fragment, ReactElement, Suspense } from 'react'; import { Fragment, ReactElement, Suspense } from 'react';
import { useRouter } from 'next/router';
const GistsCode = dynamic(() => import('components/gists/gists-code'), { const GistsCode = dynamic(() => import('components/gists/gists-code'), {
suspense: true, suspense: true,
}); });
const GistsSkeleton = dynamic(() => import('components/gists/gists-skeleton'), {
suspense: true,
});
dayjs.extend(relativeTime); dayjs.extend(relativeTime);
const Gist = ({ gist }: InferGetStaticPropsType<typeof getStaticProps>) => { const Gist = ({ gist }: InferGetStaticPropsType<typeof getStaticProps>) => {
const router = useRouter();
// if (router.isFallback) {
return (
<Suspense fallback>
<GistsSkeleton />
</Suspense>
);
// }
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">
@ -61,23 +74,23 @@ const Gist = ({ gist }: InferGetStaticPropsType<typeof getStaticProps>) => {
}; };
export const getStaticPaths: GetStaticPaths = async () => { export const getStaticPaths: GetStaticPaths = async () => {
const result = await getGists(); // const result = await getGists();
const last = Number(result?.pageSize.last); // const last = Number(result?.pageSize.last);
const paths: ( // const paths: (
| string // | string
| { // | {
params: ParsedUrlQuery; // params: ParsedUrlQuery;
locale?: string | undefined; // locale?: string | undefined;
} // }
)[] = []; // )[] = [];
for (let i = 1; i <= last; i++) { // for (let i = 1; i <= last; i++) {
const result = await getGists(i); // const result = await getGists(i);
paths.push(...(result?.gists.map((g) => ({ params: { id: g.id } })) ?? [])); // paths.push(...(result?.gists.map((g) => ({ params: { id: g.id } })) ?? []));
} // }
return { return {
paths, paths: [],
fallback: 'blocking', fallback: true,
}; };
}; };
@ -85,17 +98,19 @@ export const getStaticProps: GetStaticProps<{
id: string | undefined; id: string | undefined;
gist: SingalGist; gist: SingalGist;
}> = async ({ params }) => { }> = async ({ params }) => {
if (typeof params?.id !== 'string') if (typeof params?.id !== 'string') {
return { return {
notFound: true, notFound: true,
}; };
}
try { try {
const gist = await getSignalGist(params.id); const gist = await getSignalGist(params.id);
if (!gist || !gist.files) if (!gist || !gist.files) {
return { return {
notFound: true, notFound: true,
}; };
}
return { return {
props: { props: {
id: params?.id?.toString(), id: params?.id?.toString(),

View File

@ -1,6 +1,6 @@
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime'; import relativeTime from 'dayjs/plugin/relativeTime';
import MainLayout from 'layouts/main-layout'; import MainLayout from 'layouts/common/main-layout';
import { GetGists, getGists, GetUser, getUser } from 'lib/fetcher'; import { GetGists, getGists, GetUser, getUser } from 'lib/fetcher';
import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next'; import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';

View File

@ -1,6 +1,6 @@
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime'; import relativeTime from 'dayjs/plugin/relativeTime';
import MainLayout from 'layouts/main-layout'; import MainLayout from 'layouts/common/main-layout';
import { GetGists, getGists, GetUser, getUser } from 'lib/fetcher'; import { GetGists, getGists, GetUser, getUser } from 'lib/fetcher';
import { GetStaticProps, InferGetStaticPropsType } from 'next'; import { GetStaticProps, InferGetStaticPropsType } from 'next';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';

View File

@ -1,5 +1,5 @@
import clsx from 'clsx'; import clsx from 'clsx';
import MainLayout from 'layouts/main-layout'; import MainLayout from 'layouts/common/main-layout';
import { gltfLoader, manager } from 'lib/gltf-loader'; import { gltfLoader, manager } from 'lib/gltf-loader';
import { getMousePosition } from 'lib/utils'; import { getMousePosition } from 'lib/utils';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';

View File

@ -3,7 +3,7 @@ import components from 'components/mdx/components';
import PostCommnetLine from 'components/post/post-commnet-line'; import PostCommnetLine from 'components/post/post-commnet-line';
import PostToc from 'components/post/post-toc'; import PostToc from 'components/post/post-toc';
import data from 'content/mdx-data'; import data from 'content/mdx-data';
import MainLayout from 'layouts/main-layout'; import MainLayout from 'layouts/common/main-layout';
import useInView from 'lib/hooks/use-in-view'; import useInView from 'lib/hooks/use-in-view';
import { allPostsPath, readSinglePost } from 'lib/posts'; import { allPostsPath, readSinglePost } from 'lib/posts';
import { generateToc, SingleToc } from 'lib/utils'; import { generateToc, SingleToc } from 'lib/utils';

View File

@ -12,7 +12,7 @@ import {
} from 'react-icons/si'; } from 'react-icons/si';
import { VscGithubInverted } from 'react-icons/vsc'; import { VscGithubInverted } from 'react-icons/vsc';
import { HiPhoto } from 'react-icons/hi2'; import { HiPhoto } from 'react-icons/hi2';
import MainLayout from 'layouts/main-layout'; import MainLayout from 'layouts/common/main-layout';
const ProjectCard = dynamic(() => import('components/pages/project-card'), { const ProjectCard = dynamic(() => import('components/pages/project-card'), {
suspense: true, suspense: true,