Skip to content

Commit

Permalink
feat(blog): Add loading indicator
Browse files Browse the repository at this point in the history
Fix #32
  • Loading branch information
thien-do committed May 14, 2022
1 parent 3791d9b commit b66216f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 23 deletions.
82 changes: 63 additions & 19 deletions lib/blog/nav/item.tsx
@@ -1,4 +1,6 @@
import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";

export interface BlogNavItem {
href: string;
Expand All @@ -10,27 +12,69 @@ interface Props {
item: BlogNavItem;
}

export const BlogNavItemLink = (props: Props): JSX.Element => {
const { children, href, image } = props.item;
export const BlogNavItemLink = (props: Props): JSX.Element => (
<Link href={props.item.href}>
<a className="font-normal no-underline not-prose flex items-center">
<Img {...props} />
<span>{props.item.children}</span>
</a>
</Link>
);

const size = 32;
const border = 2;

const Img = (props: Props): JSX.Element | null => {
const router = useRouter();
const [busy, setBusy] = useState<boolean>(false);

useEffect(() => {
const start = () => void setBusy(true);
const stop = () => void setBusy(false);

router.events.on("routeChangeStart", start);
router.events.on("routeChangeComplete", stop);
router.events.on("routeChangeError", stop);

return () => {
router.events.off("routeChangeStart", start);
router.events.off("routeChangeComplete", stop);
router.events.off("routeChangeError", stop);
};
}, [router]);

const image = props.item.image;
if (image === null) return null;
const radius = (size - border) / 2;
const circumference = Math.round(radius * 2 * Math.PI);

return (
<Link href={href}>
<a
<span className="mr-3 relative block ">
{busy ? (
<svg className="animate-spin absolute inset-0" width={size} height={size}>
<circle
className="stroke-gray-900 dark:stroke-white"
strokeWidth={border}
fill="transparent"
stroke="red"
strokeDashoffset={Math.round(circumference * 0.75)}
strokeDasharray={circumference}
r={radius}
cx={size / 2}
cy={size / 2}
/>
</svg>
) : null}
<img
className={[
"font-normal no-underline not-prose",
"flex items-center",
"rounded-full transition-transform relative duration-300 ease-out",
busy ? "scale-50 delay-300" : "",
].join(" ")}
>
{image !== null && (
<img
src={image}
alt=""
width="32"
height="32"
className="rounded-full mr-3"
/>
)}
<span>{children}</span>
</a>
</Link>
src={image}
alt=""
width={size}
height={size}
/>
</span>
);
};
5 changes: 1 addition & 4 deletions lib/blog/page/props.ts
Expand Up @@ -3,10 +3,7 @@ import { fetchBlogContent } from "../content/fetch";
import { parseBlogRequest } from "../request/parse";
import type { BlogPageProps, BlogPageParams } from "./type";

export const getBlogPageProps: GetStaticProps<
BlogPageProps,
BlogPageParams
> = async (context) => {
export const getBlogPageProps: GetStaticProps<BlogPageProps, BlogPageParams> = async (context) => {
const request = parseBlogRequest(context.params);
const { content, config } = await fetchBlogContent(request);
return {
Expand Down

1 comment on commit b66216f

@vercel
Copy link

@vercel vercel bot commented on b66216f May 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.