Skip to content

Commit

Permalink
feat: add timeline support
Browse files Browse the repository at this point in the history
  • Loading branch information
OXeu committed Jun 7, 2024
1 parent 9593222 commit 6592e4d
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 2 deletions.
5 changes: 5 additions & 0 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { FriendsPage } from './page/friends'
import { WritingPage } from './page/writing'
import { Profile, ProfileContext } from './state/profile'
import { headersWithAuth } from './utils/auth'
import { TimelinePage } from './page/timeline'
function App() {
const ref = useRef(false)
const [profile, setProfile] = useState<Profile | undefined>()
Expand Down Expand Up @@ -38,6 +39,10 @@ function App() {
<FeedsPage />
</RouteMe>

<RouteMe path="/timeline">
<TimelinePage />
</RouteMe>

<RouteMe path="/feed/:id">
{params => <FeedPage id={params.id} />}
</RouteMe>
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function Header() {
</div>
</div>
<NavItem title="文章" selected={location === "/" || location.startsWith('/feed')} href="/" />
{/* <NavItem title="标签" selected={false} onClick={() => { }} /> */}
<NavItem title="时间轴" selected={location === "/timeline"} href="/timeline" />
{profile?.permission && <NavItem title="写作" selected={location.startsWith("/writing")} href="/writing" />}
<NavItem title="朋友们" selected={location === "/friends"} href="/friends" />
<NavItem title="关于" selected={location === "/about"} href="/about" />
Expand Down
2 changes: 1 addition & 1 deletion client/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ ul {
}

.t-secondary {
@apply text-neutral-800 dark:text-neutral-200;
@apply text-neutral-500 dark:text-neutral-200;
}

.wauto {
Expand Down
79 changes: 79 additions & 0 deletions client/src/page/timeline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { useEffect, useRef, useState } from "react"
import { Link } from "wouter"
import { Waiting } from "../components/loading"
import { client } from "../main"
import { headersWithAuth } from "../utils/auth"

export function TimelinePage() {
const [feeds, setFeeds] = useState<Partial<Record<number, { id: number; title: string | null; createdAt: Date; }[]>>>()
const [length, setLength] = useState(0)
const ref = useRef(false)
function fetchFeeds() {
client.feed.timeline.get({
headers: headersWithAuth()
}).then(({ data }) => {
if (data && typeof data != 'string') {
setLength(data.length)
const groups = Object.groupBy(data, ({ createdAt }) => new Date(createdAt).getFullYear())
setFeeds(groups)
}
})
}
useEffect(() => {
if (ref.current) return
fetchFeeds()
ref.current = true
}, [])
return (
<>
<Waiting wait={feeds}>
<div className="w-full flex flex-col justify-center items-center mb-8 px-4">
<div className="wauto text-start text-black dark:text-white py-4 text-4xl font-bold">
<p>
时间轴
</p>
<div className="flex flex-row justify-between">
<p className="text-sm mt-4 text-neutral-500 font-normal">
共有 {length} 篇文章
</p>
</div>
</div>
{feeds && Object.keys(feeds).sort((a, b) => parseInt(b) - parseInt(a)).map(year => (
<div key={year} className="wauto flex flex-col justify-center items-start">
<h1 className="flex flex-row items-center space-x-2">
<span className="text-2xl font-bold t-primary ">
{year}
</span>
<span className="text-sm t-secondary">{feeds[+year]?.length}</span>
</h1>
<div className="w-full flex flex-col justify-center items-start my-4">
{feeds[+year]?.map(({ id, title, createdAt }) => (
<FeedItem key={id} id={id.toString()} title={title || "无标题"} createdAt={new Date(createdAt)} />
))}
</div>
</div>
))}
</div>
</Waiting>
</>
)
}

export function FeedItem({ id, title, createdAt }: { id: string, title: string, createdAt: Date }) {
const formatter = new Intl.DateTimeFormat('en-US', { day: '2-digit', month: '2-digit' });
return (
<div className="flex flex-row pl-8">
<div className="flex flex-row items-center">
<div className="w-2 h-2 bg-theme rounded-full"></div>
</div>
<div className="flex-1 rounded-2xl m-2 duration-300 flex flex-row items-center space-x-4 ">
<span className="t-secondary text-sm" title={new Date(createdAt).toLocaleString()}>
{formatter.format(new Date(createdAt))}
</span>
<Link href={`/feed/${id}`} target="_blank" className="text-base t-primary hover:text-theme text-pretty overflow-hidden">
{title}
</Link>
</div>
</div>
)
}
13 changes: 13 additions & 0 deletions server/src/services/feed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ export const FeedService = (db: DB, env: Env) => new Elysia({ aot: false })
type: t.Optional(t.String())
})
})
.get('/timeline', async () => {
const where = and(eq(feeds.draft, 0), eq(feeds.listed, 1));
const feed_list = (await db.query.feeds.findMany({
where: where,
columns: {
id: true,
title: true,
createdAt: true,
},
orderBy: [desc(feeds.createdAt), desc(feeds.updatedAt)],
}))
return feed_list
})
.post('/', async ({ admin, set, uid, body: { title, alias, listed, content, summary, draft, tags } }) => {
if (!admin) {
set.status = 403;
Expand Down

0 comments on commit 6592e4d

Please sign in to comment.