mirror of
https://github.com/DefectingCat/DefectingCat.github.io
synced 2025-07-16 01:01:38 +00:00
Add gists skeleton animation
This commit is contained in:
66
components/gists/gists-skeleton.tsx
Normal file
66
components/gists/gists-skeleton.tsx
Normal 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;
|
@ -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}
|
||||||
|
@ -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';
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
|
@ -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(),
|
||||||
|
@ -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';
|
||||||
|
@ -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';
|
||||||
|
@ -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';
|
||||||
|
@ -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';
|
||||||
|
@ -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,
|
||||||
|
Reference in New Issue
Block a user