-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #27 from immccn123/snapshot-tl
feat: 用户名历史时间线
- Loading branch information
Showing
13 changed files
with
353 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
"use client"; | ||
|
||
import Spinner from "@/components/Spinner"; | ||
import UserInfo from "@/components/UserInfo"; | ||
import fetcher from "@/lib/fetcher"; | ||
import { UserSnapshot } from "@prisma/client"; | ||
import Timeline from "rsuite/Timeline"; | ||
import useSWRInfinite from "swr/infinite"; | ||
import "rsuite/Timeline/styles/index.css"; | ||
import { useState } from "react"; | ||
import { BsChevronDown, BsChevronUp, BsThreeDots } from "react-icons/bs"; | ||
|
||
const PER_PAGE = 15; | ||
|
||
interface PageData { | ||
snapshots: UserSnapshot[]; | ||
nextCursor: string; | ||
} | ||
|
||
export default function SnapshotTimeline({ uid }: { uid: number }) { | ||
const [open, setOpen] = useState(false); | ||
|
||
const { data, size, setSize, isValidating } = useSWRInfinite<PageData>( | ||
(_pageIndex, prev: PageData | null) => { | ||
if (prev && !prev.nextCursor) return null; | ||
let res = `/user/${uid}/snapshots?limit=${PER_PAGE}`; | ||
if (prev) res += `&offset=${prev.nextCursor}`; | ||
return res; | ||
}, | ||
fetcher, | ||
); | ||
|
||
const timeline = ( | ||
<> | ||
<Timeline endless isItemActive={Timeline.ACTIVE_FIRST}> | ||
{data?.map((dat) => | ||
dat.snapshots?.map((snapshot) => ( | ||
<Timeline.Item> | ||
<UserInfo | ||
user={{ | ||
id: uid, | ||
userSnapshots: [snapshot], | ||
}} | ||
noHref | ||
/> | ||
<br /> | ||
截至 {new Date(snapshot.until).toLocaleString()} | ||
</Timeline.Item> | ||
)), | ||
)} | ||
</Timeline> | ||
{isValidating && <Spinner className="mt-5" />} | ||
{!isValidating && | ||
data && | ||
data[data.length - 1].snapshots.length === PER_PAGE && ( | ||
<button | ||
className="btn btn-link w-100 rounded-4 py-2x py-md-3 text-center text-decoration-none" | ||
onClick={() => { | ||
// eslint-disable-next-line @typescript-eslint/no-floating-promises | ||
setSize(size + 1); | ||
}} | ||
type="button" | ||
> | ||
加载更多 | ||
<BsThreeDots | ||
className="ms-1" | ||
style={{ position: "relative", top: "-.09em" }} | ||
/> | ||
</button> | ||
)} | ||
</> | ||
); | ||
|
||
return ( | ||
<> | ||
<div className="d-md-none"> | ||
<button | ||
type="button" | ||
className="btn btn-link w-100 d-md-none" | ||
onMouseDown={() => setOpen(!open)} | ||
style={{ textDecoration: "none" }} | ||
> | ||
用户名历史 {open ? <BsChevronUp /> : <BsChevronDown />} | ||
</button> | ||
|
||
{open && ( | ||
<> | ||
{/* 对于缺失空白的一个并不优雅的解决方案 */} | ||
<div style={{ height: "10px" }} className="d-md-none" /> | ||
{timeline} | ||
</> | ||
)} | ||
</div> | ||
<div className="d-md-block d-none">{timeline}</div> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import prisma from "@/lib/prisma"; | ||
import { NextRequest, NextResponse } from "next/server"; | ||
|
||
export async function GET( | ||
request: NextRequest, | ||
{ params }: { params: { uid: string } }, | ||
) { | ||
const userId = +params.uid; | ||
const limit = request.nextUrl.searchParams.get("limit") ?? 10; | ||
const offset = request.nextUrl.searchParams.get("offset"); | ||
|
||
// 按照时间降序排序 跳过 offset 个 | ||
const snapshots = await prisma.userSnapshot.findMany({ | ||
where: { | ||
userId, | ||
time: { lt: offset ? new Date(offset) : undefined }, | ||
}, | ||
orderBy: { time: "desc" }, | ||
take: limit ? +limit : undefined, | ||
}); | ||
|
||
return NextResponse.json({ | ||
snapshots, | ||
nextCursor: snapshots[snapshots.length - 1]?.time ?? null, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.