import { useEffect, useRef, useState } from 'react'
import { getPosts, fileDownloadUrl, type ChannelKindKey, type FileRef, type Org, type PostView } from '../api/client'
const POLL_INTERVAL_MS = 3000
const timeFormatter = new Intl.DateTimeFormat('ko-KR', { hour: '2-digit', minute: '2-digit' })
function humanizeSize(bytes: number): string {
if (bytes < 1024) {
return `${bytes} B`
}
const kb = bytes / 1024
if (kb < 1024) {
return `${kb.toFixed(1)} KB`
}
return `${(kb / 1024).toFixed(1)} MB`
}
function AttachmentChip({ file }: { file: FileRef }) {
return (
{file.name}
({humanizeSize(file.size)})
)
}
function PostRow({ post }: { post: PostView }) {
if (post.system) {
return
{post.message}
}
return (
{post.user}
{timeFormatter.format(new Date(post.createAt))}
{post.message}
{post.files.length > 0 && (
{post.files.map((f) => (
))}
)}
)
}
/** 기관관리 상세의 게시물 탭. 선택한 채널의 최근 게시글을 3초 간격으로 폴링해서 보여준다. */
export default function ChannelPosts({ org }: { org: Org }) {
const bothMissing = !org.channelIdMj && !org.channelIdLaw
const [channel, setChannel] = useState(org.channelIdMj ? 'mj' : 'law')
const [posts, setPosts] = useState([])
const [error, setError] = useState(null)
const containerRef = useRef(null)
const prevCountRef = useRef(0)
useEffect(() => {
if (bothMissing) {
return
}
let cancelled = false
async function load() {
try {
const data = await getPosts(org.id, channel)
if (!cancelled) {
setPosts(data)
setError(null)
}
} catch {
if (!cancelled) {
setError('연결이 원활하지 않습니다. 재시도 중…')
}
}
}
void load()
const timer = setInterval(() => void load(), POLL_INTERVAL_MS)
return () => {
cancelled = true
clearInterval(timer)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [channel, org.id])
useEffect(() => {
if (posts.length > prevCountRef.current && containerRef.current) {
containerRef.current.scrollTop = containerRef.current.scrollHeight
}
prevCountRef.current = posts.length
}, [posts.length])
return (
{bothMissing ? (
채널이 아직 생성되지 않았습니다.
) : (
<>
{error && (
{error}
)}
{posts.length === 0 ? (
게시글이 없습니다.
) : (
posts.map((post) =>
)
)}
>
)}
)
}