|
@@ -8,6 +8,7 @@ import PostList from '@/components/PostList' |
|
|
import TagDetailSidebar from '@/components/TagDetailSidebar' |
|
|
import TagDetailSidebar from '@/components/TagDetailSidebar' |
|
|
import NicoViewer from '@/components/NicoViewer' |
|
|
import NicoViewer from '@/components/NicoViewer' |
|
|
import PostEditForm from '@/components/PostEditForm' |
|
|
import PostEditForm from '@/components/PostEditForm' |
|
|
|
|
|
import TwitterEmbed from '@/components/TwitterEmbed' |
|
|
import TabGroup, { Tab } from '@/components/common/TabGroup' |
|
|
import TabGroup, { Tab } from '@/components/common/TabGroup' |
|
|
import MainArea from '@/components/layout/MainArea' |
|
|
import MainArea from '@/components/layout/MainArea' |
|
|
import { Button } from '@/components/ui/button' |
|
|
import { Button } from '@/components/ui/button' |
|
@@ -17,8 +18,27 @@ import { cn } from '@/lib/utils' |
|
|
import NotFound from '@/pages/NotFound' |
|
|
import NotFound from '@/pages/NotFound' |
|
|
import ServiceUnavailable from '@/pages/ServiceUnavailable' |
|
|
import ServiceUnavailable from '@/pages/ServiceUnavailable' |
|
|
|
|
|
|
|
|
|
|
|
import type { FC } from 'react' |
|
|
|
|
|
|
|
|
import type { Post, User } from '@/types' |
|
|
import type { Post, User } from '@/types' |
|
|
|
|
|
|
|
|
|
|
|
const PostEmbed: FC<{ post: Post }> = ({ post }: { post: Post }) => { |
|
|
|
|
|
const url = new URL (post.url) |
|
|
|
|
|
switch (url.hostname.split ('.').slice (-2).join ('.')) |
|
|
|
|
|
{ |
|
|
|
|
|
case 'nicovideo.jp': |
|
|
|
|
|
const [videoId] = url.pathname.match (/(?<=\/watch\/)[a-zA-Z0-9]+?(?=\/|$)/)! |
|
|
|
|
|
return <NicoViewer id={videoId} width={640} height={360}/> |
|
|
|
|
|
case 'twitter.com': |
|
|
|
|
|
case 'x.com': |
|
|
|
|
|
const [userId] = url.pathname.match (/(?<=\/)[^\/]+?(?=\/|$)/)! |
|
|
|
|
|
const [statusId] = url.pathname.match (/(?<=\/status\/)\d+?(?=\/|$)/)! |
|
|
|
|
|
return <TwitterEmbed userId={userId} statusId={statusId}/> |
|
|
|
|
|
default: |
|
|
|
|
|
return <img src={post.thumbnail} alt={post.url} className="mb-4 w-full"/> |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
type Props = { user: User | null } |
|
|
type Props = { user: User | null } |
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -77,10 +97,6 @@ export default ({ user }: Props) => { |
|
|
return <ServiceUnavailable/> |
|
|
return <ServiceUnavailable/> |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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 |
|
|
const viewedClass = (post?.viewed |
|
|
? 'bg-blue-600 hover:bg-blue-700' |
|
|
? 'bg-blue-600 hover:bg-blue-700' |
|
|
: 'bg-gray-500 hover:bg-gray-600') |
|
|
: 'bg-gray-500 hover:bg-gray-600') |
|
@@ -99,12 +115,7 @@ export default ({ user }: Props) => { |
|
|
{post |
|
|
{post |
|
|
? ( |
|
|
? ( |
|
|
<> |
|
|
<> |
|
|
{nicoFlg |
|
|
|
|
|
? ( |
|
|
|
|
|
<NicoViewer id={videoId} |
|
|
|
|
|
width={640} |
|
|
|
|
|
height={360}/>) |
|
|
|
|
|
: <img src={post.thumbnail} alt={post.url} className="mb-4 w-full"/>} |
|
|
|
|
|
|
|
|
<PostEmbed post={post}/> |
|
|
<Button onClick={changeViewedFlg} |
|
|
<Button onClick={changeViewedFlg} |
|
|
className={cn ('text-white', viewedClass)}> |
|
|
className={cn ('text-white', viewedClass)}> |
|
|
{post.viewed ? '閲覧済' : '未閲覧'} |
|
|
{post.viewed ? '閲覧済' : '未閲覧'} |
|
@@ -112,7 +123,7 @@ export default ({ user }: Props) => { |
|
|
<TabGroup> |
|
|
<TabGroup> |
|
|
<Tab name="関聯"> |
|
|
<Tab name="関聯"> |
|
|
{post.related.length > 0 |
|
|
{post.related.length > 0 |
|
|
? <PostList posts={post.related} /> |
|
|
|
|
|
|
|
|
? <PostList posts={post.related}/> |
|
|
: 'まだないよ(笑)'} |
|
|
: 'まだないよ(笑)'} |
|
|
</Tab> |
|
|
</Tab> |
|
|
{['admin', 'member'].some (r => user?.role === r) && ( |
|
|
{['admin', 'member'].some (r => user?.role === r) && ( |
|
|