2023-11-15 16:15:44 +01:00
|
|
|
import { useRouter } from 'next/router'
|
2023-11-17 15:01:54 +01:00
|
|
|
import { HTMLAttributes, useEffect, useState } from 'react'
|
2024-09-02 15:00:18 +02:00
|
|
|
import { FaChevronLeft, FaUserPlus, FaUserXmark, FaX } from 'react-icons/fa6'
|
2023-11-15 16:15:44 +01:00
|
|
|
import Thread from './Thread'
|
2023-12-02 11:26:45 +01:00
|
|
|
import { Entity, MegalodonInterface } from 'megalodon'
|
2023-11-28 16:37:21 +01:00
|
|
|
import Reply from './Reply'
|
2023-12-02 03:50:42 +01:00
|
|
|
import Profile from './Profile'
|
2024-01-02 05:24:18 +01:00
|
|
|
import Tag from './Tag'
|
2023-12-11 16:00:44 +01:00
|
|
|
import { Account } from '@/db'
|
2024-01-30 16:51:36 +01:00
|
|
|
import { useIntl } from 'react-intl'
|
2024-09-03 14:45:28 +02:00
|
|
|
import { useTimelines } from '../layouts/timelines'
|
2023-11-15 16:15:44 +01:00
|
|
|
|
|
|
|
type Props = {
|
|
|
|
client: MegalodonInterface
|
2023-12-11 16:00:44 +01:00
|
|
|
account: Account
|
2024-03-09 07:00:27 +01:00
|
|
|
openMedia: (media: Array<Entity.Attachment>, index: number) => void
|
2023-11-17 15:01:54 +01:00
|
|
|
} & HTMLAttributes<HTMLElement>
|
2023-11-15 16:15:44 +01:00
|
|
|
|
|
|
|
export default function Detail(props: Props) {
|
2024-01-02 05:24:18 +01:00
|
|
|
const [target, setTarget] = useState<'status' | 'reply' | 'profile' | 'tag' | null>(null)
|
2023-11-15 16:15:44 +01:00
|
|
|
const router = useRouter()
|
2024-01-30 16:51:36 +01:00
|
|
|
const { formatMessage } = useIntl()
|
2024-09-02 15:00:18 +02:00
|
|
|
const [tagFollowing, setTagFollowing] = useState(false)
|
2024-09-03 14:45:28 +02:00
|
|
|
const { reloadMenu } = useTimelines()
|
2023-11-15 16:15:44 +01:00
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (router.query.status_id) {
|
|
|
|
setTarget('status')
|
2023-11-28 16:37:21 +01:00
|
|
|
} else if (router.query.reply_target_id) {
|
|
|
|
setTarget('reply')
|
2023-12-02 03:50:42 +01:00
|
|
|
} else if (router.query.user_id) {
|
|
|
|
setTarget('profile')
|
2024-01-02 05:24:18 +01:00
|
|
|
} else if (router.query.tag) {
|
|
|
|
setTarget('tag')
|
2023-11-15 16:15:44 +01:00
|
|
|
} else {
|
|
|
|
setTarget(null)
|
|
|
|
}
|
|
|
|
}, [router.query])
|
|
|
|
|
2024-09-02 15:00:18 +02:00
|
|
|
useEffect(() => {
|
|
|
|
if (router.query.tag) {
|
|
|
|
refreshFollowing(router.query.tag as string)
|
|
|
|
} else {
|
|
|
|
setTagFollowing(false)
|
|
|
|
}
|
|
|
|
}, [router.query.tag])
|
|
|
|
|
|
|
|
const refreshFollowing = async (tag: string) => {
|
|
|
|
const res = await props.client.getTag(tag)
|
|
|
|
if (res.data.following) {
|
|
|
|
setTagFollowing(true)
|
|
|
|
} else {
|
|
|
|
setTagFollowing(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-15 16:15:44 +01:00
|
|
|
const back = () => {
|
|
|
|
router.back()
|
|
|
|
}
|
|
|
|
|
|
|
|
const close = () => {
|
|
|
|
router.push({ query: { id: router.query.id, timeline: router.query.timeline } })
|
|
|
|
}
|
|
|
|
|
2024-09-02 15:00:18 +02:00
|
|
|
const followTag = async (tag: string) => {
|
|
|
|
await props.client.followTag(tag)
|
|
|
|
await refreshFollowing(tag)
|
2024-09-03 14:45:28 +02:00
|
|
|
await reloadMenu()
|
2024-09-02 15:00:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const unfollowTag = async (tag: string) => {
|
|
|
|
await props.client.unfollowTag(tag)
|
|
|
|
await refreshFollowing(tag)
|
2024-09-03 14:45:28 +02:00
|
|
|
await reloadMenu()
|
2024-09-02 15:00:18 +02:00
|
|
|
}
|
|
|
|
|
2023-11-15 16:15:44 +01:00
|
|
|
return (
|
|
|
|
<>
|
|
|
|
{target && (
|
2024-03-14 17:12:19 +01:00
|
|
|
<div className={`${props.className}`} style={props.style}>
|
2024-03-09 10:26:43 +01:00
|
|
|
<div className="theme-bg-secondary text-gray-200 flex justify-between p-2 items-center" style={{ height: '44px' }}>
|
2024-01-02 05:24:18 +01:00
|
|
|
<div className="flex gap-4 items-center">
|
2024-01-30 16:51:36 +01:00
|
|
|
<button className="text-lg" title={formatMessage({ id: 'detail.back' })}>
|
|
|
|
<FaChevronLeft onClick={back} />
|
|
|
|
</button>
|
2024-01-02 05:24:18 +01:00
|
|
|
{target === 'tag' && `#${router.query.tag}`}
|
|
|
|
</div>
|
2024-01-30 16:51:36 +01:00
|
|
|
<div className="flex items-center">
|
2024-09-02 15:00:18 +02:00
|
|
|
{target === 'tag' && (
|
|
|
|
<>
|
|
|
|
{tagFollowing ? (
|
|
|
|
<button
|
|
|
|
className="text-lg mr-4"
|
|
|
|
title={formatMessage({ id: 'detail.unfollow_tag' })}
|
|
|
|
onClick={() => unfollowTag(router.query.tag as string)}
|
|
|
|
>
|
|
|
|
<FaUserXmark />
|
|
|
|
</button>
|
|
|
|
) : (
|
|
|
|
<button
|
|
|
|
className="text-lg mr-4"
|
|
|
|
title={formatMessage({ id: 'detail.follow_tag' })}
|
|
|
|
onClick={() => followTag(router.query.tag as string)}
|
|
|
|
>
|
|
|
|
<FaUserPlus />
|
|
|
|
</button>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
|
2024-01-30 16:51:36 +01:00
|
|
|
<button className="text-lg" title={formatMessage({ id: 'detail.close' })}>
|
|
|
|
<FaX onClick={close} />
|
|
|
|
</button>
|
2024-01-02 05:24:18 +01:00
|
|
|
</div>
|
2023-11-15 16:15:44 +01:00
|
|
|
</div>
|
2023-12-11 16:00:44 +01:00
|
|
|
{target === 'status' && (
|
|
|
|
<Thread
|
|
|
|
client={props.client}
|
|
|
|
account={props.account}
|
|
|
|
status_id={router.query.status_id as string}
|
|
|
|
openMedia={props.openMedia}
|
|
|
|
/>
|
|
|
|
)}
|
2023-12-02 11:26:45 +01:00
|
|
|
{target === 'reply' && (
|
2023-12-11 16:00:44 +01:00
|
|
|
<Reply
|
|
|
|
client={props.client}
|
|
|
|
account={props.account}
|
|
|
|
status_id={router.query.reply_target_id as string}
|
|
|
|
openMedia={props.openMedia}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
{target === 'profile' && (
|
|
|
|
<Profile client={props.client} account={props.account} user_id={router.query.user_id as string} openMedia={props.openMedia} />
|
2023-12-02 11:26:45 +01:00
|
|
|
)}
|
2024-01-02 05:24:18 +01:00
|
|
|
{target === 'tag' && (
|
|
|
|
<Tag client={props.client} account={props.account} tag={router.query.tag as string} openMedia={props.openMedia} />
|
|
|
|
)}
|
2023-11-15 16:15:44 +01:00
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|