feat: more page sorting

This commit is contained in:
DIYgod 2023-09-22 17:34:20 +08:00
parent aea6743f55
commit 3838e2e532
No known key found for this signature in database
6 changed files with 86 additions and 28 deletions

View File

@ -1,5 +1,5 @@
import { NextServerResponse, getQuery } from "~/lib/server-helper"
import { PageVisibilityEnum } from "~/lib/types"
import { PageVisibilityEnum, PagesSortTypes } from "~/lib/types"
import { getPagesBySite } from "~/models/page.model"
export async function GET(req: Request) {
@ -13,6 +13,7 @@ export async function GET(req: Request) {
cursor: query.cursor as string,
useStat: true,
skipExpansion: query.skipExpansion === "true",
sortType: query.sortType as PagesSortTypes,
...(query.tags && {
tags: Array.isArray(query.tags)
? (query.tags as string[])

View File

@ -27,6 +27,7 @@ async function SiteIndexPage({
visibility: PageVisibilityEnum.Published,
useStat: true,
limit: 18,
sortType: "latest",
},
queryClient,
)

View File

@ -1,7 +1,10 @@
"use client"
import { useState } from "react"
import PostList from "~/components/site/PostList"
import { NoteType, PageVisibilityEnum } from "~/lib/types"
import { type TabItem, Tabs } from "~/components/ui/Tabs"
import { NoteType, PageVisibilityEnum, PagesSortTypes } from "~/lib/types"
import { useGetPagesBySiteLite, usePinnedPage } from "~/queries/page"
import { useGetSite } from "~/queries/site"
@ -13,19 +16,61 @@ export default function SiteHome({
type?: NoteType
}) {
const site = useGetSite(handle)
const [sortType, setSortType] = useState<PagesSortTypes>("latest")
const posts = useGetPagesBySiteLite({
characterId: site.data?.characterId,
type: type || ["post", "portfolio"],
visibility: PageVisibilityEnum.Published,
useStat: true,
limit: type === "short" ? 20 : 18,
sortType: sortType,
})
const pinnedPage = usePinnedPage({ characterId: site.data?.characterId })
if (!posts.data?.pages?.length) return null
let tabs: TabItem[]
switch (type) {
case "portfolio":
tabs = []
break
case "short":
tabs = [
{
text: "Latest",
onClick: () => setSortType("latest"),
active: sortType === "latest",
},
{
text: "Most Commented",
onClick: () => setSortType("commented"),
active: sortType === "commented",
},
]
break
default:
tabs = [
{
text: "Latest",
onClick: () => setSortType("latest"),
active: sortType === "latest",
},
{
text: "Hottest",
onClick: () => setSortType("hottest"),
active: sortType === "hottest",
},
{
text: "Most Commented",
onClick: () => setSortType("commented"),
active: sortType === "commented",
},
]
break
}
return (
<>
<Tabs items={tabs} className="border-none mb-4 -mt-3" />
{!posts.data?.pages?.length && posts.isLoading && <>Loading...</>}
<PostList
posts={posts}
pinnedNoteId={pinnedPage.noteId}

View File

@ -194,6 +194,7 @@
"Hottest": "最热",
"Latest": "最新",
"Following": "关注",
"Most Commented": "最多评论",
"Create a Post": "创建文章",
"Change Site Icon or domain": "更改站点图标或域名",
"Join xLog's Discord channel": "加入 xLog 的 Discord 频道",

View File

@ -27,6 +27,8 @@ export enum PageVisibilityEnum {
Modified = "published and local modified",
}
export type PagesSortTypes = "latest" | "hottest" | "commented"
export type PostOnSiteHome = {
id: string
title: string

View File

@ -20,7 +20,12 @@ import { filterCommentCharacter } from "~/lib/filter-character"
import { getNoteSlug } from "~/lib/helpers"
import { checkSlugReservedWords } from "~/lib/slug-reserved-words"
import { getKeys, getStorage } from "~/lib/storage"
import { ExpandedNote, NoteType, PageVisibilityEnum } from "~/lib/types"
import {
ExpandedNote,
NoteType,
PageVisibilityEnum,
PagesSortTypes,
} from "~/lib/types"
import { client } from "~/queries/graphql"
export const PINNED_PAGE_KEY = "xlog_pinned_page"
@ -120,6 +125,7 @@ export async function getPagesBySite(input: {
keepBody?: boolean
handle?: string // In order to be compatible with old drafts
skipExpansion?: boolean
sortType?: PagesSortTypes
}) {
if (!input.characterId) {
return {
@ -210,6 +216,31 @@ export async function getPagesBySite(input: {
`
const limit = (input.limit || 12) - (pinnedNote ? 1 : 0)
let orderBy
switch (input.sortType) {
case "hottest":
orderBy = `{
stat: {
viewDetailCount:desc
}
}`
break
case "commented":
orderBy = `{
fromNotes: {
_count: desc
}
}`
break
default:
orderBy = `{
publishedAt: {
sort: desc
}
}`
break
}
const { data } = await client
.query(
gql`
@ -217,11 +248,7 @@ export async function getPagesBySite(input: {
noteCount(where: ${whereQuery}),
notes(
where: ${whereQuery},
orderBy: [{
publishedAt: {
sort: desc
}
}],
orderBy: [${orderBy}],
take: $limit,
${cursorQuery}
) {
@ -351,25 +378,6 @@ export async function getPagesBySite(input: {
break
}
expandedNotes.list.sort((a, b) => {
if (
!a.metadata?.content?.date_published ||
a.noteId === expandedNotes.pinnedNoteId
) {
return -1
} else if (
!b.metadata?.content?.date_published ||
b.noteId === expandedNotes.pinnedNoteId
) {
return 1
} else {
return (
+new Date(b.metadata?.content?.date_published) -
+new Date(a.metadata?.content?.date_published)
)
}
})
return expandedNotes
}