このコミットが含まれているのは:
@@ -9,7 +9,6 @@ import Form from '@/components/common/Form'
|
||||
import FormField from '@/components/common/FormField'
|
||||
import PageTitle from '@/components/common/PageTitle'
|
||||
import MainArea from '@/components/layout/MainArea'
|
||||
import { useUserSettings } from '@/components/users/UserSettingsProvider'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { toast } from '@/components/ui/use-toast'
|
||||
import { SITE_TITLE } from '@/config'
|
||||
@@ -31,7 +30,6 @@ type PostFormField =
|
||||
|
||||
const PostNewPage: FC<Props> = ({ user }) => {
|
||||
const editable = canEditContent (user)
|
||||
const { settings } = useUserSettings ()
|
||||
|
||||
const navigate = useNavigate ()
|
||||
|
||||
@@ -49,16 +47,8 @@ const PostNewPage: FC<Props> = ({ user }) => {
|
||||
const [title, setTitle] = useState ('')
|
||||
const [titleLoading, setTitleLoading] = useState (false)
|
||||
const [url, setURL] = useState ('')
|
||||
const [titleAutoFlg, setTitleAutoFlg] = useState (settings.autoFetchTitle === 'auto')
|
||||
const [thumbnailAutoFlg, setThumbnailAutoFlg] =
|
||||
useState (settings.autoFetchThumbnail === 'auto')
|
||||
|
||||
const previousURLRef = useRef ('')
|
||||
const thumbnailPreviewRef = useRef ('')
|
||||
const titleFetchMode = settings.autoFetchTitle
|
||||
const thumbnailFetchMode = settings.autoFetchThumbnail
|
||||
const titleFetchVisible = titleFetchMode !== 'off'
|
||||
const thumbnailFetchVisible = thumbnailFetchMode !== 'off'
|
||||
const videoFlg =
|
||||
useMemo (() => tags.split (/\s+/).some (tag => tag.replace (/\[.*\]$/, '') === '動画'),
|
||||
[tags])
|
||||
@@ -93,19 +83,7 @@ const PostNewPage: FC<Props> = ({ user }) => {
|
||||
}
|
||||
}
|
||||
|
||||
const handleURLBlur = () => {
|
||||
if (!(url) || url === previousURLRef.current)
|
||||
return
|
||||
|
||||
if (titleAutoFlg)
|
||||
fetchTitle ()
|
||||
if (thumbnailAutoFlg)
|
||||
fetchThumbnail ()
|
||||
previousURLRef.current = url
|
||||
}
|
||||
|
||||
const fetchTitle = useCallback (async () => {
|
||||
setTitle ('')
|
||||
setTitleLoading (true)
|
||||
try
|
||||
{
|
||||
@@ -144,24 +122,6 @@ const PostNewPage: FC<Props> = ({ user }) => {
|
||||
thumbnailPreviewRef.current = thumbnailPreview
|
||||
}, [thumbnailPreview])
|
||||
|
||||
useEffect (() => {
|
||||
setTitleAutoFlg (settings.autoFetchTitle === 'auto')
|
||||
}, [settings.autoFetchTitle])
|
||||
|
||||
useEffect (() => {
|
||||
setThumbnailAutoFlg (settings.autoFetchThumbnail === 'auto')
|
||||
}, [settings.autoFetchThumbnail])
|
||||
|
||||
useEffect (() => {
|
||||
if (titleAutoFlg && url)
|
||||
fetchTitle ()
|
||||
}, [fetchTitle, titleAutoFlg, url])
|
||||
|
||||
useEffect (() => {
|
||||
if (thumbnailAutoFlg && url)
|
||||
fetchThumbnail ()
|
||||
}, [fetchThumbnail, thumbnailAutoFlg, url])
|
||||
|
||||
if (!(editable))
|
||||
return <Forbidden/>
|
||||
|
||||
@@ -183,8 +143,7 @@ const PostNewPage: FC<Props> = ({ user }) => {
|
||||
onChange={e => setURL (e.target.value)}
|
||||
aria-describedby={describedBy}
|
||||
aria-invalid={invalid}
|
||||
className={inputClass (invalid)}
|
||||
onBlur={handleURLBlur}/>)}
|
||||
className={inputClass (invalid)}/>)}
|
||||
</FormField>
|
||||
|
||||
{/* タイトル */}
|
||||
@@ -200,31 +159,14 @@ const PostNewPage: FC<Props> = ({ user }) => {
|
||||
onChange={ev => setTitle (ev.target.value)}
|
||||
disabled={titleLoading}/>
|
||||
<div className="flex flex-wrap items-center gap-2 text-sm">
|
||||
<span>
|
||||
{titleAutoFlg
|
||||
? 'URL 入力時に自動取得します.'
|
||||
: titleFetchMode === 'manual'
|
||||
? '自動取得しません.必要なら手動で取得できます.'
|
||||
: '取得機能は無効です.'}
|
||||
</span>
|
||||
{titleFetchVisible && (
|
||||
<>
|
||||
<label className="flex items-center gap-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={titleAutoFlg}
|
||||
onChange={ev => setTitleAutoFlg (ev.target.checked)}/>
|
||||
<span>自動</span>
|
||||
</label>
|
||||
{!(titleAutoFlg) && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() => void fetchTitle ()}
|
||||
disabled={!(url) || titleLoading}>
|
||||
取得
|
||||
</Button>)}
|
||||
</>)}
|
||||
<span>必要なタイミングで URL から取得できます.</span>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() => void fetchTitle ()}
|
||||
disabled={!(url) || titleLoading}>
|
||||
取得
|
||||
</Button>
|
||||
</div>
|
||||
</div>)}
|
||||
</FormField>
|
||||
@@ -234,52 +176,29 @@ const PostNewPage: FC<Props> = ({ user }) => {
|
||||
{({ describedBy, invalid }) => (
|
||||
<>
|
||||
<div className="mb-2 flex flex-wrap items-center gap-2 text-sm">
|
||||
<span>
|
||||
{thumbnailAutoFlg
|
||||
? 'URL 入力時に自動取得します.'
|
||||
: thumbnailFetchMode === 'manual'
|
||||
? '自動取得しません.必要なら手動で取得できます.'
|
||||
: '取得機能は無効です.'}
|
||||
</span>
|
||||
{thumbnailFetchVisible && (
|
||||
<>
|
||||
<label className="flex items-center gap-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={thumbnailAutoFlg}
|
||||
onChange={ev => setThumbnailAutoFlg (ev.target.checked)}/>
|
||||
<span>自動</span>
|
||||
</label>
|
||||
{!(thumbnailAutoFlg) && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() => void fetchThumbnail ()}
|
||||
disabled={!(url) || thumbnailLoading}>
|
||||
取得
|
||||
</Button>)}
|
||||
</>)}
|
||||
<span>必要なタイミングで URL から取得できます.</span>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={() => void fetchThumbnail ()}
|
||||
disabled={!(url) || thumbnailLoading}>
|
||||
取得
|
||||
</Button>
|
||||
</div>
|
||||
{thumbnailAutoFlg
|
||||
? (thumbnailLoading
|
||||
? <p className="text-gray-500 text-sm">Loading...</p>
|
||||
: !(thumbnailPreview) && (
|
||||
<p className="text-gray-500 text-sm">
|
||||
URL から自動取得されます。
|
||||
</p>))
|
||||
: (
|
||||
<input type="file"
|
||||
accept="image/*"
|
||||
aria-describedby={describedBy}
|
||||
aria-invalid={invalid}
|
||||
onChange={e => {
|
||||
const file = e.target.files?.[0]
|
||||
if (file)
|
||||
{
|
||||
setThumbnailFile (file)
|
||||
setThumbnailPreview (URL.createObjectURL (file))
|
||||
}
|
||||
}}/>)}
|
||||
{thumbnailLoading && (
|
||||
<p className="text-gray-500 text-sm">Loading...</p>)}
|
||||
<input type="file"
|
||||
accept="image/*"
|
||||
aria-describedby={describedBy}
|
||||
aria-invalid={invalid}
|
||||
onChange={e => {
|
||||
const file = e.target.files?.[0]
|
||||
if (file)
|
||||
{
|
||||
setThumbnailFile (file)
|
||||
setThumbnailPreview (URL.createObjectURL (file))
|
||||
}
|
||||
}}/>
|
||||
{thumbnailPreview && (
|
||||
<img src={thumbnailPreview}
|
||||
alt="preview"
|
||||
|
||||
新しい課題から参照
ユーザをブロックする