From cfa2c240f8ab1091da889cbfcda42ef724f86861 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Sat, 8 Jul 2023 23:09:43 +0100 Subject: [PATCH] feat: ssr for activities pages --- src/app/(home)/(activities)/hottest/page.tsx | 21 +++++- src/app/(home)/(activities)/page.tsx | 20 +++++- src/app/(home)/(activities)/search/page.tsx | 52 ++++++++++++++ .../(home)/(activities)/tag/[tag]/page.tsx | 48 +++++++++++++ .../(activities)/topic/[topic]/page.tsx | 23 +++++- src/app/(home)/search/page.tsx | 34 --------- src/app/(home)/tag/[tag]/page.tsx | 37 ---------- src/components/common/Titles.tsx | 11 ++- src/components/home/HomeFeed.tsx | 71 ++++++++++++------- src/queries/home.server.ts | 9 +-- 10 files changed, 216 insertions(+), 110 deletions(-) create mode 100644 src/app/(home)/(activities)/search/page.tsx create mode 100644 src/app/(home)/(activities)/tag/[tag]/page.tsx delete mode 100644 src/app/(home)/search/page.tsx delete mode 100644 src/app/(home)/tag/[tag]/page.tsx diff --git a/src/app/(home)/(activities)/hottest/page.tsx b/src/app/(home)/(activities)/hottest/page.tsx index 16418ef4..a27c11fa 100644 --- a/src/app/(home)/(activities)/hottest/page.tsx +++ b/src/app/(home)/(activities)/hottest/page.tsx @@ -1,12 +1,31 @@ import { Metadata } from "next" +import { Hydrate, dehydrate } from "@tanstack/react-query" + import { HomeFeed } from "~/components/home/HomeFeed" import { APP_NAME } from "~/lib/env" +import getQueryClient from "~/lib/query-client" +import { prefetchGetFeed } from "~/queries/home.server" export const metadata: Metadata = { title: `Hottest Activities - ${APP_NAME}`, } export default async function HottestActivities() { - return + const queryClient = getQueryClient() + await prefetchGetFeed( + { + type: "hottest", + daysInterval: 7, + }, + queryClient, + ) + + const dehydratedState = dehydrate(queryClient) + + return ( + + + + ) } diff --git a/src/app/(home)/(activities)/page.tsx b/src/app/(home)/(activities)/page.tsx index cb82eb04..b03a4036 100644 --- a/src/app/(home)/(activities)/page.tsx +++ b/src/app/(home)/(activities)/page.tsx @@ -1,12 +1,30 @@ import { Metadata } from "next" +import { Hydrate, dehydrate } from "@tanstack/react-query" + import { HomeFeed } from "~/components/home/HomeFeed" import { APP_NAME } from "~/lib/env" +import getQueryClient from "~/lib/query-client" +import { prefetchGetFeed } from "~/queries/home.server" export const metadata: Metadata = { title: `Latest Activities - ${APP_NAME}`, } export default async function LatestActivities() { - return + const queryClient = getQueryClient() + await prefetchGetFeed( + { + type: "latest", + }, + queryClient, + ) + + const dehydratedState = dehydrate(queryClient) + + return ( + + + + ) } diff --git a/src/app/(home)/(activities)/search/page.tsx b/src/app/(home)/(activities)/search/page.tsx new file mode 100644 index 00000000..3b8e561a --- /dev/null +++ b/src/app/(home)/(activities)/search/page.tsx @@ -0,0 +1,52 @@ +import { Metadata } from "next" + +import { Hydrate, dehydrate } from "@tanstack/react-query" + +import { SearchInput } from "~/components/common/SearchInput" +import { HomeFeed } from "~/components/home/HomeFeed" +import { APP_NAME } from "~/lib/env" +import getQueryClient from "~/lib/query-client" +import { prefetchGetFeed } from "~/queries/home.server" + +export function generateMetadata({ + searchParams, +}: { + searchParams: { + [key: string]: string | string[] | undefined + } +}): Metadata { + return { + title: `Search: ${searchParams.q} - ${APP_NAME}`, + } +} + +async function Search({ + searchParams, +}: { + searchParams: { + [key: string]: string | undefined + } +}) { + const queryClient = getQueryClient() + await prefetchGetFeed( + { + type: "search", + searchKeyword: searchParams.q || undefined, + searchType: "latest", + }, + queryClient, + ) + + const dehydratedState = dehydrate(queryClient) + + return ( + + +
+ +
+
+ ) +} + +export default Search diff --git a/src/app/(home)/(activities)/tag/[tag]/page.tsx b/src/app/(home)/(activities)/tag/[tag]/page.tsx new file mode 100644 index 00000000..60da187a --- /dev/null +++ b/src/app/(home)/(activities)/tag/[tag]/page.tsx @@ -0,0 +1,48 @@ +import { Metadata } from "next" + +import { Hydrate, dehydrate } from "@tanstack/react-query" + +import { HomeFeed } from "~/components/home/HomeFeed" +import { APP_NAME } from "~/lib/env" +import getQueryClient from "~/lib/query-client" +import { prefetchGetFeed } from "~/queries/home.server" + +export function generateMetadata({ + params, +}: { + params: { + tag: string + } +}): Metadata { + return { + title: `Tag: ${params.tag} - ${APP_NAME}`, + } +} + +export default async function Tag({ + params, +}: { + params: { + tag: string + } +}) { + params.tag = decodeURIComponent(params.tag) + + const queryClient = getQueryClient() + await prefetchGetFeed( + { + type: "tag", + tag: params.tag, + }, + queryClient, + ) + + const dehydratedState = dehydrate(queryClient) + + return ( + +

Tag: {params.tag}

+ +
+ ) +} diff --git a/src/app/(home)/(activities)/topic/[topic]/page.tsx b/src/app/(home)/(activities)/topic/[topic]/page.tsx index 1dae7595..e8b4aa97 100644 --- a/src/app/(home)/(activities)/topic/[topic]/page.tsx +++ b/src/app/(home)/(activities)/topic/[topic]/page.tsx @@ -1,8 +1,12 @@ import { Metadata } from "next" +import { Hydrate, dehydrate } from "@tanstack/react-query" + import { HomeFeed } from "~/components/home/HomeFeed" import { APP_NAME } from "~/lib/env" import { getTranslation } from "~/lib/i18n" +import getQueryClient from "~/lib/query-client" +import { prefetchGetFeed } from "~/queries/home.server" import topics from "../../../../../../data/topics.json" @@ -30,8 +34,21 @@ export default async function Topic({ params.topic = decodeURIComponent(params.topic) const info = topics.find((t) => t.name === params.topic) + const queryClient = getQueryClient() + await prefetchGetFeed( + { + type: "topic", + topicIncludeKeywords: info?.includeKeywords, + topicIncludeTags: info?.includeTags, + noteIds: info?.notes, + }, + queryClient, + ) + + const dehydratedState = dehydrate(queryClient) + return ( - <> +
@@ -47,7 +64,7 @@ export default async function Topic({ {t("Participate in Topic")} */}
- - + + ) } diff --git a/src/app/(home)/search/page.tsx b/src/app/(home)/search/page.tsx deleted file mode 100644 index d5ba6bcd..00000000 --- a/src/app/(home)/search/page.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Metadata } from "next" - -import { SearchInput } from "~/components/common/SearchInput" -import { HomeFeed } from "~/components/home/HomeFeed" -import { HomeSidebar } from "~/components/home/HomeSidebar" -import { APP_NAME } from "~/lib/env" - -export function generateMetadata({ - searchParams, -}: { - searchParams: { - [key: string]: string | string[] | undefined - } -}): Metadata { - return { - title: `Search: ${searchParams.q} - ${APP_NAME}`, - } -} - -async function Search() { - return ( - <> -
- -
- -
-
- - - ) -} - -export default Search diff --git a/src/app/(home)/tag/[tag]/page.tsx b/src/app/(home)/tag/[tag]/page.tsx deleted file mode 100644 index e6e6fe83..00000000 --- a/src/app/(home)/tag/[tag]/page.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Metadata } from "next" - -import { HomeFeed } from "~/components/home/HomeFeed" -import { HomeSidebar } from "~/components/home/HomeSidebar" -import { APP_NAME } from "~/lib/env" - -export function generateMetadata({ - params, -}: { - params: { - tag: string - } -}): Metadata { - return { - title: `Tag: ${params.tag} - ${APP_NAME}`, - } -} - -export default function Tag({ - params, -}: { - params: { - tag: string - } -}) { - params.tag = decodeURIComponent(params.tag) - - return ( - <> -
-

Tag: {params.tag}

- -
- - - ) -} diff --git a/src/components/common/Titles.tsx b/src/components/common/Titles.tsx index db1cd3b2..e72e8e49 100644 --- a/src/components/common/Titles.tsx +++ b/src/components/common/Titles.tsx @@ -2,7 +2,6 @@ import { cn } from "~/lib/utils" import data from "../../../data/titles.json" import { Tooltip } from "../ui/Tooltip" -import { UniLink } from "../ui/UniLink" const icons: { [key: string]: { @@ -38,11 +37,17 @@ export const Titles = ({ characterId }: { characterId?: number }) => { "inline-flex p-[1px] rounded-sm", )} > - + { + e.preventDefault() + window.open(title.link) + }} + className="inline-flex" + > - + ))} diff --git a/src/components/home/HomeFeed.tsx b/src/components/home/HomeFeed.tsx index 8562bdb8..f19598b3 100644 --- a/src/components/home/HomeFeed.tsx +++ b/src/components/home/HomeFeed.tsx @@ -200,13 +200,7 @@ const Post = ({ post, keyword }: { post: ExpandedNote; keyword?: string }) => { const MemoedPost = memo(Post) -export const HomeFeed = ({ - noteIds, - type, -}: { - noteIds?: string[] - type?: FeedType -}) => { +export const HomeFeed = ({ type }: { type?: FeedType }) => { const { t } = useTranslation("common") const searchParams = useSearchParams() @@ -227,21 +221,47 @@ export const HomeFeed = ({ params.topic = decodeURIComponent(params.topic) } - const feed = useGetFeed({ + let feedConfig: Parameters[0] = { type, - characterId: currentCharacterId, - noteIds: noteIds, - daysInterval: hotInterval, - searchKeyword: searchParams?.get("q") || undefined, - searchType, - tag: decodeURIComponent(params?.tag), - topicIncludeKeywords: params.topic - ? topics.find((t) => t.name === params.topic)?.includeKeywords - : undefined, - topicIncludeTags: params.topic - ? topics.find((t) => t.name === params.topic)?.includeTags - : undefined, - }) + } + switch (type) { + case "following": + feedConfig = { + type, + characterId: currentCharacterId, + } + break + case "topic": + const info = topics.find((t) => t.name === params.topic) + feedConfig = { + type, + topicIncludeKeywords: info?.includeKeywords, + topicIncludeTags: info?.includeTags, + noteIds: info?.notes, + } + break + case "hottest": + feedConfig = { + type, + daysInterval: hotInterval, + } + break + case "search": + feedConfig = { + type, + searchKeyword: searchParams?.get("q") || undefined, + searchType, + } + break + case "tag": + feedConfig = { + type, + tag: decodeURIComponent(params?.tag), + } + break + } + + const feed = useGetFeed(feedConfig) const hasFiltering = type === "latest" @@ -287,7 +307,9 @@ export const HomeFeed = ({ }, ] - const [feedInOne, setFeedInOne] = useState([]) + const [feedInOne, setFeedInOne] = useState( + feed.data?.pages?.[0]?.list || [], + ) useEffect(() => { if (feed.data?.pages?.length) { setFeedInOne( @@ -368,8 +390,9 @@ export const HomeFeed = ({ ) : !feed.data?.pages[0]?.count ? ( ) : ( -
+
feed.hasNextPage && feed.fetchNextPage()} useWindowScroll @@ -413,7 +436,7 @@ const FeedSkeleton = () => { return (
diff --git a/src/queries/home.server.ts b/src/queries/home.server.ts index 2b6ad5aa..4c56493c 100644 --- a/src/queries/home.server.ts +++ b/src/queries/home.server.ts @@ -4,17 +4,12 @@ import { cacheGet } from "~/lib/redis.server" import * as homeModel from "~/models/home.model" export const prefetchGetFeed = async ( - data: { - type?: homeModel.FeedType - characterId?: number - limit?: number - noteIds?: string[] - }, + data: Parameters[0], queryClient: QueryClient, ) => { const key = ["getFeed", data] await queryClient.prefetchInfiniteQuery({ - queryKey: ["getFeed", data], + queryKey: key, queryFn: async ({ pageParam }) => { return cacheGet({ key,