Skip to content

Commit 974221d

Browse files
committed
Implement status detail drawer
1 parent a6a7e9d commit 974221d

File tree

6 files changed

+93
-2
lines changed

6 files changed

+93
-2
lines changed

renderer/components/detail/Detail.tsx

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { useRouter } from 'next/router'
2+
import { useEffect, useState } from 'react'
3+
import { FaChevronLeft, FaX } from 'react-icons/fa6'
4+
import Thread from './Thread'
5+
import { MegalodonInterface } from 'megalodon'
6+
7+
type Props = {
8+
client: MegalodonInterface
9+
}
10+
11+
export default function Detail(props: Props) {
12+
const [target, setTarget] = useState<'status' | null>(null)
13+
const router = useRouter()
14+
15+
useEffect(() => {
16+
if (router.query.status_id) {
17+
setTarget('status')
18+
} else {
19+
setTarget(null)
20+
}
21+
}, [router.query])
22+
23+
const back = () => {
24+
router.back()
25+
}
26+
27+
const close = () => {
28+
router.push({ query: { id: router.query.id, timeline: router.query.timeline } })
29+
}
30+
31+
return (
32+
<>
33+
{target && (
34+
<div className="w-96 h-full fixed top-0 right-0 bg-white shadow-md">
35+
<div className="bg-blue-900 text-gray-200 flex justify-between p-2 items-center" style={{ height: '50px' }}>
36+
<FaChevronLeft onClick={back} className="cursor-pointer text-lg" />
37+
<FaX onClick={close} className="cursor-pointer text-lg" />
38+
</div>
39+
{target === 'status' && <Thread client={props.client} status_id={router.query.status_id as string} />}
40+
</div>
41+
)}
42+
</>
43+
)
44+
}

renderer/components/detail/Thread.tsx

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Entity, MegalodonInterface } from 'megalodon'
2+
import { useEffect, useState } from 'react'
3+
import { Virtuoso } from 'react-virtuoso'
4+
import Status from '../timelines/status/Status'
5+
6+
type Props = {
7+
client: MegalodonInterface
8+
status_id: string
9+
}
10+
11+
export default function Thread(props: Props) {
12+
const [ancestors, setAncestors] = useState<Array<Entity.Status>>([])
13+
const [descendants, setDescendants] = useState<Array<Entity.Status>>([])
14+
const [status, setStatus] = useState<Entity.Status | null>(null)
15+
16+
useEffect(() => {
17+
if (props.status_id) {
18+
const f = async () => {
19+
const s = await props.client.getStatus(props.status_id)
20+
setStatus(s.data)
21+
const res = await props.client.getStatusContext(props.status_id)
22+
setAncestors(res.data.ancestors)
23+
setDescendants(res.data.descendants)
24+
}
25+
f()
26+
}
27+
}, [props.status_id])
28+
29+
return (
30+
<>
31+
<Virtuoso
32+
style={{ height: '100%' }}
33+
data={[...ancestors, status, ...descendants].filter(s => s !== null)}
34+
itemContent={(_, status) => <Status client={props.client} status={status} key={status.id} onRefresh={() => {}} />}
35+
/>
36+
</>
37+
)
38+
}

renderer/components/layouts/timelines.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default function Layout({ children }: LayoutProps) {
7070
<Sidebar.Items>
7171
<Sidebar.ItemGroup>
7272
{pages.map(page => (
73-
<Sidebar.Item key={page.id} active={`${page.path}/` === router.asPath} onClick={() => router.push(page.path)}>
73+
<Sidebar.Item key={page.id} active={router.asPath.includes(page.path)} onClick={() => router.push(page.path)}>
7474
{page.title}
7575
</Sidebar.Item>
7676
))}

renderer/components/timelines/Timeline.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useEffect, useState, useCallback, useRef } from 'react'
55
import { Virtuoso } from 'react-virtuoso'
66
import Status from './status/Status'
77
import { FormattedMessage, useIntl } from 'react-intl'
8+
import Detail from '../detail/Detail'
89

910
const TIMELINE_STATUSES_COUNT = 30
1011
const TIMELINE_MAX_STATUSES = 2147483647
@@ -159,6 +160,7 @@ export default function Timeline(props: Props) {
159160
)}
160161
/>
161162
</div>
163+
<Detail client={props.client} />
162164
</section>
163165
)
164166
}

renderer/components/timelines/status/Status.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Card from './Card'
88
import Poll from './Poll'
99
import { FormattedMessage } from 'react-intl'
1010
import Actions from './Actions'
11+
import { useRouter } from 'next/router'
1112

1213
type Props = {
1314
status: Entity.Status
@@ -17,12 +18,17 @@ type Props = {
1718

1819
export default function Status(props: Props) {
1920
const status = originalStatus(props.status)
21+
const router = useRouter()
2022

2123
const onRefresh = async () => {
2224
const res = await props.client.getStatus(status.id)
2325
props.onRefresh(res.data)
2426
}
2527

28+
const openStatus = () => {
29+
router.push({ query: { id: router.query.id, timeline: router.query.timeline, status_id: status.id } })
30+
}
31+
2632
return (
2733
<div className="border-b mr-2 py-1">
2834
{rebloggedHeader(props.status)}
@@ -39,7 +45,7 @@ export default function Status(props: Props) {
3945
></span>
4046
<span className="text-gray-600 text-ellipsis break-all overflow-hidden">@{status.account.acct}</span>
4147
</div>
42-
<div className="text-gray-600 text-right">
48+
<div className="text-gray-600 text-right cursor-pointer" onClick={openStatus}>
4349
<time dateTime={status.created_at}>{dayjs(status.created_at).format('YYYY-MM-DD HH:mm:ss')}</time>
4450
</div>
4551
</div>

renderer/pages/accounts/[id]/[timeline].tsx

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export default function Page() {
1616

1717
useEffect(() => {
1818
if (router.query.id) {
19+
console.log(router)
1920
const f = async () => {
2021
const a = await db.accounts.get(parseInt(router.query.id as string))
2122
if (a) {

0 commit comments

Comments
 (0)