This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState, useRef } from 'react'
|
||||
import { useCallback, useEffect, useState, useRef } from 'react'
|
||||
import { Helmet } from 'react-helmet-async'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
@@ -21,9 +21,8 @@ import type { User } from '@/types'
|
||||
type Props = { user: User | null }
|
||||
|
||||
|
||||
export default (({ user }: Props) => {
|
||||
if (!(['admin', 'member'].some (r => user?.role === r)))
|
||||
return <Forbidden/>
|
||||
const PostNewPage: FC<Props> = ({ user }) => {
|
||||
const editable = ['admin', 'member'].some (r => user?.role === r)
|
||||
|
||||
const navigate = useNavigate ()
|
||||
|
||||
@@ -41,6 +40,7 @@ export default (({ user }: Props) => {
|
||||
const [url, setURL] = useState ('')
|
||||
|
||||
const previousURLRef = useRef ('')
|
||||
const thumbnailPreviewRef = useRef ('')
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const formData = new FormData
|
||||
@@ -67,16 +67,6 @@ export default (({ user }: Props) => {
|
||||
}
|
||||
}
|
||||
|
||||
useEffect (() => {
|
||||
if (titleAutoFlg && url)
|
||||
fetchTitle ()
|
||||
}, [titleAutoFlg])
|
||||
|
||||
useEffect (() => {
|
||||
if (thumbnailAutoFlg && url)
|
||||
fetchThumbnail ()
|
||||
}, [thumbnailAutoFlg])
|
||||
|
||||
const handleURLBlur = () => {
|
||||
if (!(url) || url === previousURLRef.current)
|
||||
return
|
||||
@@ -88,20 +78,20 @@ export default (({ user }: Props) => {
|
||||
previousURLRef.current = url
|
||||
}
|
||||
|
||||
const fetchTitle = async () => {
|
||||
const fetchTitle = useCallback (async () => {
|
||||
setTitle ('')
|
||||
setTitleLoading (true)
|
||||
const data = await apiGet<{ title: string }> ('/preview/title', { params: { url } })
|
||||
setTitle (data.title || '')
|
||||
setTitleLoading (false)
|
||||
}
|
||||
}, [url])
|
||||
|
||||
const fetchThumbnail = async () => {
|
||||
const fetchThumbnail = useCallback (async () => {
|
||||
setThumbnailPreview ('')
|
||||
setThumbnailFile (null)
|
||||
setThumbnailLoading (true)
|
||||
if (thumbnailPreview)
|
||||
URL.revokeObjectURL (thumbnailPreview)
|
||||
if (thumbnailPreviewRef.current)
|
||||
URL.revokeObjectURL (thumbnailPreviewRef.current)
|
||||
const data = await apiGet<Blob> ('/preview/thumbnail',
|
||||
{ params: { url }, responseType: 'blob' })
|
||||
const imageURL = URL.createObjectURL (data)
|
||||
@@ -110,7 +100,24 @@ export default (({ user }: Props) => {
|
||||
'thumbnail.png',
|
||||
{ type: data.type || 'image/png' }))
|
||||
setThumbnailLoading (false)
|
||||
}
|
||||
}, [url])
|
||||
|
||||
useEffect (() => {
|
||||
thumbnailPreviewRef.current = thumbnailPreview
|
||||
}, [thumbnailPreview])
|
||||
|
||||
useEffect (() => {
|
||||
if (titleAutoFlg && url)
|
||||
fetchTitle ()
|
||||
}, [fetchTitle, titleAutoFlg, url])
|
||||
|
||||
useEffect (() => {
|
||||
if (thumbnailAutoFlg && url)
|
||||
fetchThumbnail ()
|
||||
}, [fetchThumbnail, thumbnailAutoFlg, url])
|
||||
|
||||
if (!(editable))
|
||||
return <Forbidden/>
|
||||
|
||||
return (
|
||||
<MainArea>
|
||||
@@ -207,4 +214,6 @@ export default (({ user }: Props) => {
|
||||
</Button>
|
||||
</Form>
|
||||
</MainArea>)
|
||||
}) satisfies FC<Props>
|
||||
}
|
||||
|
||||
export default PostNewPage
|
||||
|
||||
Reference in New Issue
Block a user