このコミットが含まれているのは:
2026-06-23 00:24:04 +09:00
コミット 53d1cadefb
19個のファイルの変更316行の追加38行の削除
+36 -3
ファイルの表示
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'
import { useEffect, useMemo, useState } from 'react'
import PostFormTagsArea from '@/components/PostFormTagsArea'
import PostOriginalCreatedTimeField from '@/components/PostOriginalCreatedTimeField'
@@ -17,7 +17,10 @@ import type { FC, FormEvent } from 'react'
import type { Post, TagWithSections } from '@/types'
type PostFormField =
'parentPostIds' | 'tags' | 'originalCreatedAt'
'parentPostIds' | 'tags' | 'videoMs' | 'originalCreatedAt'
const videoMsToDurationValue = (videoMs: number | null): string =>
videoMs == null ? '' : String (videoMs / 1_000)
const tagsToStr = (tags: TagWithSections[]): string => {
@@ -44,6 +47,7 @@ type Props = { post: Post
const PostEditForm: FC<Props> = ({ post, onSave }) => {
const [disabled, setDisabled] = useState (false)
const [duration, setDuration] = useState<string> (videoMsToDurationValue (post.videoMs))
const { baseErrors, fieldErrors, clearValidationErrors, applyValidationError } =
useValidationErrors<PostFormField> ()
const [originalCreatedBefore, setOriginalCreatedBefore] =
@@ -55,6 +59,10 @@ const PostEditForm: FC<Props> = ({ post, onSave }) => {
const [tags, setTags] = useState<string> ('')
const [title, setTitle] = useState (post.title)
const videoFlg =
useMemo (() => tags.split (/\s+/).some (tag => tag.replace (/\[.*\]$/, '') === '動画'),
[tags])
const dialogue = useDialogue ()
const update = async (...args: Parameters<typeof updatePost>) => {
@@ -66,6 +74,7 @@ const PostEditForm: FC<Props> = ({ post, onSave }) => {
onSave ({ ...post,
versionNo: data.versionNo,
title: data.title,
videoMs: data.videoMs,
tags: data.tags,
parentPosts: data.parentPosts,
childPosts: data.childPosts,
@@ -105,6 +114,7 @@ const PostEditForm: FC<Props> = ({ post, onSave }) => {
{
// TODO: 差分 UI
await update ({ id: post.id, title, tags, parentPostIds,
duration: videoFlg ? duration : null,
originalCreatedFrom, originalCreatedBefore },
{ baseVersionNo: post.versionNo, merge: true })
return
@@ -113,6 +123,7 @@ const PostEditForm: FC<Props> = ({ post, onSave }) => {
if (action === 'overwrite')
{
await update ({ id: post.id, title, tags, parentPostIds,
duration: videoFlg ? duration : null,
originalCreatedFrom, originalCreatedBefore },
{ baseVersionNo: post.versionNo, force: true })
return
@@ -127,6 +138,7 @@ const PostEditForm: FC<Props> = ({ post, onSave }) => {
try
{
await update ({ id: post.id, title, tags, parentPostIds,
duration: videoFlg ? duration : null,
originalCreatedFrom, originalCreatedBefore },
{ baseVersionNo: post.versionNo })
}
@@ -138,8 +150,14 @@ const PostEditForm: FC<Props> = ({ post, onSave }) => {
useEffect (() => {
setTags (tagsToStr (post.tags))
setDuration (videoMsToDurationValue (post.videoMs))
}, [post])
useEffect (() => {
if (!(videoFlg))
setDuration ('')
}, [videoFlg])
return (
<form onSubmit={handleSubmit} className="max-w-xl pt-2 space-y-4">
<FieldError messages={baseErrors}/>
@@ -152,7 +170,7 @@ const PostEditForm: FC<Props> = ({ post, onSave }) => {
disabled={disabled}
className={inputClass (invalid)}
value={title ?? ''}
onChange={ev => setTitle (ev.target.value)}/>)}
onChange={e => setTitle (e.target.value)}/>)}
</FormField>
{/* 親投稿 */}
@@ -184,6 +202,20 @@ const PostEditForm: FC<Props> = ({ post, onSave }) => {
setOriginalCreatedBefore={setOriginalCreatedBefore}
errors={fieldErrors.originalCreatedAt}/>
{/* 動画時間 */}
{videoFlg && (
<FormField label="動画時間" messages={fieldErrors.videoMs}>
{({ invalid }) => (
<input
type="number"
min="0.001"
step="0.001"
disabled={disabled}
className={inputClass (invalid)}
value={duration}
onChange={e => setDuration (e.target.value)}/>)}
</FormField>)}
{/* 送信 */}
<Button type="submit" disabled={disabled}>
@@ -191,4 +223,5 @@ const PostEditForm: FC<Props> = ({ post, onSave }) => {
</form>)
}
export default PostEditForm