feat: use different URLs for different activity types
This commit is contained in:
parent
7aef7acd25
commit
d03f37abda
|
|
@ -0,0 +1,12 @@
|
|||
import { Metadata } from "next"
|
||||
|
||||
import { HomeFeed } from "~/components/home/HomeFeed"
|
||||
import { APP_NAME } from "~/lib/env"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `Following Activities - ${APP_NAME}`,
|
||||
}
|
||||
|
||||
export default async function FollowingActivities() {
|
||||
return <HomeFeed type="following" />
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { Metadata } from "next"
|
||||
|
||||
import { HomeFeed } from "~/components/home/HomeFeed"
|
||||
import { APP_NAME } from "~/lib/env"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `Hottest Activities - ${APP_NAME}`,
|
||||
}
|
||||
|
||||
export default async function HottestActivities() {
|
||||
return <HomeFeed type="hottest" />
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import { Metadata } from "next"
|
||||
|
||||
import { HomeActivitiesTabs } from "~/components/home/HomeActivitiesTabs"
|
||||
import { HomeSidebar } from "~/components/home/HomeSidebar"
|
||||
import { APP_NAME } from "~/lib/env"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `Activities - ${APP_NAME}`,
|
||||
}
|
||||
|
||||
export default async function ActivitiesLayout({
|
||||
children,
|
||||
}: {
|
||||
children?: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<section className="pt-24">
|
||||
<div className="max-w-screen-lg px-5 mx-auto flex">
|
||||
<div className="flex-1 min-w-[300px]">
|
||||
<HomeActivitiesTabs />
|
||||
{children}
|
||||
</div>
|
||||
<HomeSidebar />
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,39 +1,12 @@
|
|||
import { Metadata } from "next"
|
||||
|
||||
import { Hydrate, dehydrate } from "@tanstack/react-query"
|
||||
|
||||
import { HomeFeed } from "~/components/home/HomeFeed"
|
||||
import { HomeSidebar } from "~/components/home/HomeSidebar"
|
||||
import { APP_NAME } from "~/lib/env"
|
||||
import getQueryClient from "~/lib/query-client"
|
||||
import { prefetchGetFeed } from "~/queries/home.server"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `Activities - ${APP_NAME}`,
|
||||
title: `Latest Activities - ${APP_NAME}`,
|
||||
}
|
||||
|
||||
async function Activities() {
|
||||
const queryClient = getQueryClient()
|
||||
await prefetchGetFeed(
|
||||
{
|
||||
type: "latest",
|
||||
},
|
||||
queryClient,
|
||||
)
|
||||
const dehydratedState = dehydrate(queryClient)
|
||||
|
||||
return (
|
||||
<Hydrate state={dehydratedState}>
|
||||
<section className="pt-24">
|
||||
<div className="max-w-screen-lg px-5 mx-auto flex">
|
||||
<div className="flex-1 min-w-[300px]">
|
||||
<HomeFeed />
|
||||
</div>
|
||||
<HomeSidebar />
|
||||
</div>
|
||||
</section>
|
||||
</Hydrate>
|
||||
)
|
||||
export default async function LatestActivities() {
|
||||
return <HomeFeed type="latest" />
|
||||
}
|
||||
|
||||
export default Activities
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export async function GET(request: Request) {
|
|||
const searchParams = new URLSearchParams(request.url.split("?")[1])
|
||||
|
||||
const feed = await getFeed({
|
||||
type: "hot",
|
||||
type: "hottest",
|
||||
daysInterval: parseInt(searchParams.get("interval") || "0"),
|
||||
useHTML: true,
|
||||
limit: 10,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
"use client"
|
||||
|
||||
import { usePathname, useRouter } from "next/navigation"
|
||||
|
||||
import { useAccountState, useConnectModal } from "@crossbell/connect-kit"
|
||||
|
||||
import { Tabs } from "~/components/ui/Tabs"
|
||||
|
||||
export const HomeActivitiesTabs = () => {
|
||||
const pathname = usePathname()
|
||||
const connectModal = useConnectModal()
|
||||
const router = useRouter()
|
||||
|
||||
const currentCharacterId = useAccountState(
|
||||
(s) => s.computed.account?.characterId,
|
||||
)
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
text: "Latest",
|
||||
href: "/activities",
|
||||
active: pathname === "/activities",
|
||||
},
|
||||
{
|
||||
text: "Hottest",
|
||||
href: "/activities/hottest",
|
||||
active: pathname === "/activities/hottest",
|
||||
},
|
||||
{
|
||||
text: "Following",
|
||||
onClick: () => {
|
||||
if (!currentCharacterId) {
|
||||
connectModal.show()
|
||||
} else {
|
||||
router.push(`/activities/following`)
|
||||
}
|
||||
},
|
||||
active: pathname === "/activities/following",
|
||||
},
|
||||
]
|
||||
|
||||
return <Tabs items={tabs} className="border-none text-lg"></Tabs>
|
||||
}
|
||||
|
|
@ -174,25 +174,28 @@ const MemoedPost = memo(Post)
|
|||
|
||||
export const HomeFeed: React.FC<{
|
||||
noteIds?: string[]
|
||||
keyword?: string
|
||||
type?: FeedType
|
||||
}> = ({ noteIds, keyword, type }) => {
|
||||
}> = ({ noteIds, type }) => {
|
||||
const { t } = useTranslation("common")
|
||||
const searchParams = useSearchParams()
|
||||
|
||||
const [feedType, setFeedType] = useState<FeedType>(type || "latest")
|
||||
const router = useRouter()
|
||||
|
||||
const currentCharacterId = useAccountState(
|
||||
(s) => s.computed.account?.characterId,
|
||||
)
|
||||
|
||||
const connectModal = useConnectModal()
|
||||
if (type === "following" && !currentCharacterId) {
|
||||
connectModal.show()
|
||||
}
|
||||
|
||||
const [hotInterval, setHotInterval] = useState(7)
|
||||
const [searchType, setSearchType] = useState<SearchType>("latest")
|
||||
|
||||
const params = useParams()
|
||||
|
||||
const feed = useGetFeed({
|
||||
type: feedType,
|
||||
type,
|
||||
characterId: currentCharacterId,
|
||||
noteIds: noteIds,
|
||||
daysInterval: hotInterval,
|
||||
|
|
@ -201,7 +204,7 @@ export const HomeFeed: React.FC<{
|
|||
tag: decodeURIComponent(params?.tag),
|
||||
})
|
||||
|
||||
const hasFiltering = feedType === "latest"
|
||||
const hasFiltering = type === "latest"
|
||||
|
||||
const [aiFiltering, setAiFiltering] = useState(true)
|
||||
|
||||
|
|
@ -240,40 +243,13 @@ export const HomeFeed: React.FC<{
|
|||
},
|
||||
{
|
||||
text: "Hottest",
|
||||
onClick: () => setSearchType("hot"),
|
||||
active: searchType === "hot",
|
||||
},
|
||||
]
|
||||
|
||||
const connectModal = useConnectModal()
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
text: "Latest",
|
||||
onClick: () => setFeedType("latest"),
|
||||
active: feedType === "latest",
|
||||
},
|
||||
{
|
||||
text: "Hottest",
|
||||
onClick: () => setFeedType("hot"),
|
||||
active: feedType === "hot",
|
||||
},
|
||||
{
|
||||
text: "Following",
|
||||
onClick: () => {
|
||||
if (!currentCharacterId) {
|
||||
connectModal.show()
|
||||
} else {
|
||||
setFeedType("following")
|
||||
}
|
||||
},
|
||||
active: feedType === "following",
|
||||
onClick: () => setSearchType("hottest"),
|
||||
active: searchType === "hottest",
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<>
|
||||
{!type && <Tabs items={tabs} className="border-none text-lg"></Tabs>}
|
||||
<div className="space-y-10">
|
||||
{hasFiltering && (
|
||||
<div className="flex items-center text-zinc-500">
|
||||
|
|
@ -309,10 +285,10 @@ export const HomeFeed: React.FC<{
|
|||
</Switch>
|
||||
</div>
|
||||
)}
|
||||
{feedType === "hot" && (
|
||||
{type === "hottest" && (
|
||||
<Tabs items={hotTabs} className="border-none text-sm -my-4"></Tabs>
|
||||
)}
|
||||
{feedType === "search" && (
|
||||
{type === "search" && (
|
||||
<Tabs items={searchTabs} className="border-none text-sm -my-4"></Tabs>
|
||||
)}
|
||||
|
||||
|
|
@ -337,7 +313,7 @@ export const HomeFeed: React.FC<{
|
|||
key={`${post.characterId}-${post.noteId}`}
|
||||
post={post}
|
||||
previousPost={
|
||||
feedType === "latest" && index >= 1
|
||||
type === "latest" && index >= 1
|
||||
? array[index - 1]
|
||||
: undefined
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ export type FeedType =
|
|||
| "latest"
|
||||
| "following"
|
||||
| "topic"
|
||||
| "hot"
|
||||
| "hottest"
|
||||
| "search"
|
||||
| "tag"
|
||||
export type SearchType = "latest" | "hot"
|
||||
export type SearchType = "latest" | "hottest"
|
||||
|
||||
export async function getFeed({
|
||||
type,
|
||||
|
|
@ -183,7 +183,7 @@ export async function getFeed({
|
|||
count: list?.length || 0,
|
||||
}
|
||||
}
|
||||
case "hot": {
|
||||
case "hottest": {
|
||||
const client = createClient({
|
||||
url: "https://indexer.crossbell.io/v1/graphql",
|
||||
exchanges: [cacheExchange, fetchExchange],
|
||||
|
|
@ -269,7 +269,7 @@ export async function getFeed({
|
|||
limit: limit,
|
||||
cursor,
|
||||
includeCharacterMetadata: true,
|
||||
orderBy: searchType === "hot" ? "viewCount" : "createdAt",
|
||||
orderBy: searchType === "hottest" ? "viewCount" : "createdAt",
|
||||
})
|
||||
|
||||
const list = await Promise.all(
|
||||
|
|
|
|||
Loading…
Reference in New Issue