feat: default to display featured activities
This commit is contained in:
parent
943cae7396
commit
b88daee3d9
|
|
@ -0,0 +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() {
|
||||
const queryClient = getQueryClient()
|
||||
await prefetchGetFeed(
|
||||
{
|
||||
type: "latest",
|
||||
},
|
||||
queryClient,
|
||||
)
|
||||
|
||||
const dehydratedState = dehydrate(queryClient)
|
||||
|
||||
return (
|
||||
<Hydrate state={dehydratedState}>
|
||||
<HomeFeed type="latest" />
|
||||
</Hydrate>
|
||||
)
|
||||
}
|
||||
|
|
@ -3,19 +3,19 @@ import { Metadata } from "next"
|
|||
import { Hydrate, dehydrate } from "@tanstack/react-query"
|
||||
|
||||
import { HomeFeed } from "~/components/home/HomeFeed"
|
||||
import { APP_NAME } from "~/lib/env"
|
||||
import { APP_NAME, APP_SLOGAN } from "~/lib/env"
|
||||
import getQueryClient from "~/lib/query-client"
|
||||
import { prefetchGetFeed } from "~/queries/home.server"
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `Latest Activities - ${APP_NAME}`,
|
||||
title: `${APP_NAME} - ${APP_SLOGAN}`,
|
||||
}
|
||||
|
||||
export default async function LatestActivities() {
|
||||
export default async function HomeActivities() {
|
||||
const queryClient = getQueryClient()
|
||||
await prefetchGetFeed(
|
||||
{
|
||||
type: "latest",
|
||||
type: "featured",
|
||||
},
|
||||
queryClient,
|
||||
)
|
||||
|
|
@ -24,7 +24,7 @@ export default async function LatestActivities() {
|
|||
|
||||
return (
|
||||
<Hydrate state={dehydratedState}>
|
||||
<HomeFeed type="latest" />
|
||||
<HomeFeed type="featured" />
|
||||
</Hydrate>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,15 @@ export const HomeActivitiesTabs = () => {
|
|||
|
||||
const tabs = [
|
||||
{
|
||||
text: "Latest",
|
||||
text: "Featured",
|
||||
href: "/",
|
||||
active: pathname === "/",
|
||||
},
|
||||
{
|
||||
text: "Latest",
|
||||
href: "/latest",
|
||||
active: pathname === "/latest",
|
||||
},
|
||||
{
|
||||
text: "Hottest",
|
||||
href: "/hottest",
|
||||
|
|
|
|||
|
|
@ -181,6 +181,7 @@
|
|||
"Subdomain Available.": "子域名可用。",
|
||||
"Subdomain Unavailable.": "子域名不可用。",
|
||||
"Recheck": "重新检查",
|
||||
"Featured": "精选",
|
||||
"Hottest": "最热",
|
||||
"Latest": "最新",
|
||||
"Following": "关注",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { ExpandedNote } from "~/lib/types"
|
|||
import { client } from "~/queries/graphql"
|
||||
|
||||
import filter from "../../data/filter.json"
|
||||
import titles from "../../data/titles.json"
|
||||
import topics from "../../data/topics.json"
|
||||
|
||||
export type FeedType =
|
||||
|
|
@ -18,12 +19,14 @@ export type FeedType =
|
|||
| "search"
|
||||
| "tag"
|
||||
| "comments"
|
||||
| "featured"
|
||||
|
||||
export type SearchType = "latest" | "hottest"
|
||||
|
||||
export async function getFeed({
|
||||
type,
|
||||
cursor,
|
||||
limit = 30,
|
||||
limit = 12,
|
||||
characterId,
|
||||
daysInterval,
|
||||
searchKeyword,
|
||||
|
|
@ -480,9 +483,9 @@ export async function getFeed({
|
|||
},
|
||||
},
|
||||
take: 40,
|
||||
orderBy: {
|
||||
stat: {
|
||||
viewDetailCount: desc
|
||||
orderBy: {
|
||||
stat: {
|
||||
viewDetailCount: desc
|
||||
}
|
||||
},
|
||||
) {
|
||||
|
|
@ -534,6 +537,102 @@ export async function getFeed({
|
|||
count: list?.length || 0,
|
||||
}
|
||||
}
|
||||
case "featured": {
|
||||
const result = await client
|
||||
.query(
|
||||
gql`
|
||||
query getNotes($filter: [Int!], $limit: Int, $whitelist: [Int!]) {
|
||||
notes(
|
||||
where: {
|
||||
characterId: {
|
||||
notIn: $filter
|
||||
},
|
||||
deleted: {
|
||||
equals: false,
|
||||
},
|
||||
metadata: {
|
||||
content: {
|
||||
path: "sources",
|
||||
array_contains: "xlog"
|
||||
},
|
||||
NOT: [{
|
||||
content: {
|
||||
path: "tags",
|
||||
array_starts_with: "comment"
|
||||
}
|
||||
}]
|
||||
},
|
||||
OR: [
|
||||
{
|
||||
stat: {
|
||||
viewDetailCount: {
|
||||
gt: 30
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
characterId: {
|
||||
in: $whitelist
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
orderBy: [{ createdAt: desc }],
|
||||
take: $limit,
|
||||
${cursorQuery}
|
||||
) {
|
||||
stat {
|
||||
viewDetailCount
|
||||
}
|
||||
${resultFields}
|
||||
}
|
||||
}
|
||||
`,
|
||||
{
|
||||
filter: filter.latest,
|
||||
limit,
|
||||
whitelist: titles.reduce((acc, cur) => {
|
||||
acc = acc.concat(cur.list)
|
||||
return acc
|
||||
}, [] as number[]),
|
||||
},
|
||||
)
|
||||
.toPromise()
|
||||
|
||||
let list = await Promise.all(
|
||||
result?.data?.notes.map(async (page: any) => {
|
||||
const secondAgo = dayjs().diff(dayjs(page.createdAt), "second")
|
||||
page.stat.hotScore =
|
||||
page.stat.viewDetailCount / Math.max(Math.log10(secondAgo), 1)
|
||||
|
||||
const expand = await expandCrossbellNote({
|
||||
note: page,
|
||||
useHTML,
|
||||
})
|
||||
delete expand.metadata?.content.content
|
||||
return expand
|
||||
}),
|
||||
)
|
||||
|
||||
const cursor = list?.length
|
||||
? `${list[list.length - 1]?.characterId}_${list[list.length - 1]
|
||||
?.noteId}`
|
||||
: undefined
|
||||
|
||||
list = list.sort((a, b) => {
|
||||
if (a.stat?.hotScore && b.stat?.hotScore) {
|
||||
return b.stat.hotScore - a.stat.hotScore
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
list,
|
||||
cursor,
|
||||
count: list?.length || 0,
|
||||
}
|
||||
}
|
||||
case "search": {
|
||||
const result = await indexer.search.notes(searchKeyword!, {
|
||||
sources: ["xlog"],
|
||||
|
|
|
|||
Loading…
Reference in New Issue