import axios from 'axios' import toCamel from 'camelcase-keys' import { useEffect, useState } from 'react' import { Helmet } from 'react-helmet-async' import { useParams } from 'react-router-dom' import TagDetailSidebar from '@/components/TagDetailSidebar' import NicoViewer from '@/components/NicoViewer' import PostEditForm from '@/components/PostEditForm' import TabGroup, { Tab } from '@/components/common/TabGroup' import MainArea from '@/components/layout/MainArea' import { Button } from '@/components/ui/button' import { toast } from '@/components/ui/use-toast' import { API_BASE_URL, SITE_TITLE } from '@/config' import { cn } from '@/lib/utils' import NotFound from '@/pages/NotFound' import ServiceUnavailable from '@/pages/ServiceUnavailable' import type { Post, User } from '@/types' type Props = { user: User | null } export default ({ user }: Props) => { const { id } = useParams () const [editing, setEditing] = useState (true) const [post, setPost] = useState (null) const [status, setStatus] = useState (200) const changeViewedFlg = async () => { const url = `${ API_BASE_URL }/posts/${ id }/viewed` const opt = { headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') || '' } } try { if (post!.viewed) await axios.delete (url, opt) else await axios.post (url, { }, opt) // 通信に成功したら “閲覧済” をトグル setPost (post => ({ ...post!, viewed: !(post!.viewed) })) } catch { toast ({ title: '失敗……', description: '通信に失敗しました……' }) } } useEffect (() => { if (!(id)) return void (async () => { try { const res = await axios.get (`${ API_BASE_URL }/posts/${ id }`, { headers: { 'X-Transfer-Code': localStorage.getItem ('user_code') ?? '' } }) setPost (toCamel (res.data as any, { deep: true }) as Post) } catch (err) { if (axios.isAxiosError (err)) setStatus (err.status ?? 200) } }) () }, [id]) useEffect (() => { setEditing (false) }, [post]) useEffect (() => { if (!(editing)) setEditing (true) }, [editing]) switch (status) { case 404: return case 503: return } const url = post ? new URL (post.url) : null const nicoFlg = url?.hostname.split ('.').slice (-2).join ('.') === 'nicovideo.jp' const match = nicoFlg ? url.pathname.match (/(?<=\/watch\/)[a-zA-Z0-9]+?(?=\/|$)/) : null const videoId = match?.[0] ?? '' const viewedClass = (post?.viewed ? 'bg-blue-600 hover:bg-blue-700' : 'bg-gray-500 hover:bg-gray-600') return (
{(post?.thumbnail || post?.thumbnailBase) && ( )} {post && {`${ post.title || post.url } | ${ SITE_TITLE }`}}
{post ? ( <> {nicoFlg ? ( ) : {post.url}} {(['admin', 'member'].some (r => user?.role === r) && editing) && ( { setPost (newPost) toast ({ description: '更新しました.' }) }} /> )} ) : 'Loading...'}
) }