Skip to content

Commit

Permalink
feat: @vercel/kv
Browse files Browse the repository at this point in the history
  • Loading branch information
powerfulyang committed Nov 2, 2023
1 parent 0514f0e commit eb1ae50
Show file tree
Hide file tree
Showing 15 changed files with 230 additions and 44 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ public/worker-*.js
.vercel/
cache/
.wrangler/
.vercel
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"@trpc/react-query": "10.43.0",
"@trpc/server": "10.43.0",
"@vercel/analytics": "^1.1.1",
"@vercel/kv": "^0.2.4",
"@volar/monaco": "1.10.9",
"@vue/language-service": "1.8.22",
"canvas-confetti": "1.9.0",
Expand Down Expand Up @@ -184,7 +185,8 @@
"rimraf": "5.0.5",
"swagger-typescript-api": "13.0.3",
"tailwindcss": "3.3.5",
"typescript": "5.2.2"
"typescript": "5.2.2",
"vercel": "32.5.0"
},
"bundledDependencies": [
"katex",
Expand Down
25 changes: 24 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 51 additions & 14 deletions src/components/NavBar/User/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import { loginUrl } from '@/constant/Constant';
import React, { useMemo } from 'react';
import classNames from 'classnames';
import { LazyImage } from '@/components/LazyImage';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { loginUrl } from '@/constant/Constant';
import { useUser } from '@/hooks/useUser';
import { clientApi } from '@/request/requestTool';
import classNames from 'classnames';
import { LogOut, User } from 'lucide-react';
import React, { useMemo } from 'react';
import styles from './index.module.scss';

export const login = () => {
Expand All @@ -12,24 +24,49 @@ export const login = () => {
};

export const NavBarUser = () => {
const { isFetching, user } = useUser(true);
const { isFetching, user, refetch } = useUser(true);

const Component = useMemo(() => {
return user ? (
<div className={classNames(styles.user, 'pointer')}>
<span className={styles.nickname}>{user.nickname}</span>
<LazyImage
className="aspect-square"
src={user.avatar}
containerClassName={styles.avatar}
alt="avatar"
/>
</div>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<div className={classNames(styles.user, 'pointer')}>
<span className={styles.nickname}>{user.nickname}</span>
<LazyImage
className="aspect-square"
src={user.avatar}
containerClassName={styles.avatar}
alt="avatar"
/>
</div>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<User className="mr-2 h-4 w-4" />
<span>Profile</span>
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem
onClick={async () => {
await clientApi.logout();
return refetch();
}}
>
<LogOut className="mr-2 h-4 w-4" />
<span>Logout</span>
<DropdownMenuShortcut>⇧⌘L</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
) : (
<button type="button" className="pointer mr-4 block text-pink-400" onClick={login}>
Login
</button>
);
}, [user]);
}, [refetch, user]);
return isFetching && !user ? <span className="pr-4 text-pink-400">Loading...</span> : Component;
};
6 changes: 5 additions & 1 deletion src/components/Timeline/TimelineForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
removeFromFileList,
sourceUrlToFile,
} from '@/utils/copy';
import { trpc } from '@/utils/trpc';
import { zodResolver } from '@hookform/resolvers/zod';
import { useImmer, useIsomorphicLayoutEffect } from '@powerfulyang/hooks';
import { useMutation } from '@tanstack/react-query';
Expand Down Expand Up @@ -73,6 +74,8 @@ export const TimeLineForm = memo<Props>(({ onSubmitSuccess }) => {
}
}, [editItem, setValue]);

const cacheClean = trpc.cacheClean.useMutation();

const mutation = useMutation({
onMutate() {
confetti();
Expand All @@ -85,14 +88,15 @@ export const TimeLineForm = memo<Props>(({ onSubmitSuccess }) => {
const res_1 = await clientApi.createFeed(variables);
return res_1.data;
},
onSuccess(data) {
async onSuccess(data) {
reset();
if (editItem) {
onSubmitSuccess('modify', data);
setEditItem(undefined);
} else {
onSubmitSuccess('create', data);
}
await cacheClean.mutateAsync();
},
});

Expand Down
29 changes: 26 additions & 3 deletions src/pages/gallery/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import Masonry from '@/components/Masonry';
import { UserLayout } from '@/layout/UserLayout';
import { clientApi, serverApi } from '@/request/requestTool';
import type { LayoutFC } from '@/types/GlobalContext';
import { extractRequestHeaders } from '@/utils/extractRequestHeaders';
import { checkAuthInfo, extractRequestHeaders } from '@/utils/extractRequestHeaders';
import { firstItem, lastItem } from '@powerfulyang/utils';
import { useInfiniteQuery } from '@tanstack/react-query';
import { kv } from '@vercel/kv';
import { flatten } from 'lodash-es';
import type { GetServerSideProps } from 'next';
import React, { useCallback } from 'react';
Expand Down Expand Up @@ -103,17 +104,31 @@ export const Gallery: LayoutFC<GalleryProps> = ({ assets, nextCursor, prevCursor
};

export const getServerSideProps: GetServerSideProps = async (ctx) => {
const requestHeaders = extractRequestHeaders(ctx.req.headers);
const hasAuthInfo = checkAuthInfo(requestHeaders);

if (!hasAuthInfo) {
try {
const _ = await kv.get<any>('props:gallery:index');
if (_) {
return _;
}
} catch (e) {
// ignore
}
}

const res = await serverApi.infiniteQueryPublicAsset(
{
take: 20,
},
{
headers: extractRequestHeaders(ctx.req.headers),
headers: requestHeaders,
},
);
const pathViewCount = res.headers.get('x-path-view-count');
const { data } = res;
return {
const props = {
props: {
assets: data.resources,
nextCursor: data.nextCursor,
Expand All @@ -130,6 +145,14 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
},
},
};
if (!hasAuthInfo) {
try {
await kv.set('props:gallery:index', props);
} catch {
// ignore
}
}
return props;
};

Gallery.getLayout = (page) => {
Expand Down
47 changes: 36 additions & 11 deletions src/pages/post/[id]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { cn } from '@/lib/utils';
import type { GetServerSideProps } from 'next';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/navigation';
import React from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import type { HttpResponse, Post } from '@/__generated__/api';
import { origin } from '@/components/Head';
import type { TOCItem } from '@/components/MarkdownContainer/TOC';
import { MarkdownTOC } from '@/components/MarkdownContainer/TOC';
import { Skeleton } from '@/components/Skeleton';
import { UserLayout } from '@/layout/UserLayout';
import { cn } from '@/lib/utils';
import { serverApi } from '@/request/requestTool';
import { helpers } from '@/server';
import type { LayoutFC } from '@/types/GlobalContext';
import { extractRequestHeaders } from '@/utils/extractRequestHeaders';
import { generateTOC } from '@/utils/toc';
import { checkAuthInfo, extractRequestHeaders } from '@/utils/extractRequestHeaders';
import { kv } from '@vercel/kv';
import type { GetServerSideProps } from 'next';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/navigation';
import React from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import styles from './index.module.scss';

const LazyMarkdownContainer = dynamic(() => import('@/components/MarkdownContainer'), {
Expand Down Expand Up @@ -56,30 +57,46 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
query: { id },
} = ctx;
const postId = id as string;

const requestHeaders = extractRequestHeaders(ctx.req.headers);
const hasAuthInfo = checkAuthInfo(requestHeaders);
if (!hasAuthInfo) {
try {
const _ = await kv.get<any>(`props:post:${postId}`);
if (_) {
return _;
}
} catch (e) {
// ignore
}
}

const res = await serverApi
.queryPublicPostById(
Number(postId),
{
versions: [],
},
{
headers: extractRequestHeaders(ctx.req.headers),
headers: requestHeaders,
},
)
.catch((r: HttpResponse<Post>) => {
return r;
});

if (!res.ok) {
return {
notFound: true,
};
}

const pathViewCount = res.headers.get('x-path-view-count');
const { data } = res;

const toc = await generateTOC(data.content);
const toc = await helpers.generateTOC.fetch(data.content);

return {
const props = {
props: {
post: data,
toc,
Expand All @@ -95,6 +112,14 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
},
},
};
if (!hasAuthInfo) {
try {
await kv.set(`props:post:${postId}`, props);
} catch {
// ignore
}
}
return props;
};

export default PostDetail;
Expand Down
3 changes: 3 additions & 0 deletions src/pages/post/diff/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,16 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
},
)
.catch((r: HttpResponse<Post>) => r);

if (!res.ok) {
return {
notFound: true,
};
}

const post = res.data;
const { logs } = post;

if (logs.length !== 2) {
return {
notFound: true,
Expand Down
2 changes: 1 addition & 1 deletion src/pages/post/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,6 @@
}

.footer {
@apply pt-6 text-center text-base text-pink-400;
@apply pt-6 text-center sm:pt-4;
}
}
Loading

0 comments on commit eb1ae50

Please sign in to comment.