このコミットが含まれているのは:
2026-06-07 02:01:16 +09:00
コミット be2df723fe
8個のファイルの変更222行の追加47行の削除
+29 -14
ファイルの表示
@@ -21,9 +21,7 @@ import { useValidationErrors } from '@/lib/useValidationErrors'
import type { FC, FormEvent, ReactNode } from 'react'
import type { NiconicoMetadata,
NiconicoVideoInfo,
NiconicoViewerHandle,
import type { NiconicoViewerHandle,
Post,
Category,
Tag,
@@ -88,7 +86,9 @@ const commentBox = (
{dateString (comment.createdAt)}
</div>),
(
<div key={`${ comment.no }-post`} className="mt-1 w-full text-xs text-zinc-500 dark:text-zinc-400">
<div
key={`${ comment.no }-post`}
className="mt-1 w-full text-xs text-zinc-500 dark:text-zinc-400">
{programme && (
<>
<PrefetchLink to={`/posts/${ programme.post.id }`} className="font-bold hover:underline">
@@ -439,7 +439,7 @@ const TheatreDetailPage: FC<Props> = ({ user }: Props) => {
void refreshProgrammes ()
}, [refreshProgrammes, theatreInfo.postId])
const syncPlayback = (meta: NiconicoMetadata) => {
const syncPlaybackTime = (currentTimeMs: number): number | void => {
if (!(theatreInfo.postStartedAt))
return
@@ -447,24 +447,38 @@ const TheatreDetailPage: FC<Props> = ({ user }: Props) => {
currentPostElapsedMs (theatreInfo),
videoLength)
const drift = Math.abs (meta.currentTime - targetTime)
const drift = Math.abs (currentTimeMs - targetTime)
if (drift > 5_000)
embedRef.current?.seek (targetTime)
return targetTime
}
const handlePlaybackError = async () => {
if (!(theatreInfoRef.current.hostFlg) || loadingRef.current)
return
await advancePost ()
loadingRef.current = true
try
{
await advancePost ()
}
finally
{
loadingRef.current = false
}
}
const handleNiconicoLoadComplete = (info: NiconicoVideoInfo) => {
const lengthMs = info.lengthInSeconds * 1_000
setVideoLength (lengthMs)
const handleVideoReady = (durationMs: number) => {
const playableDurationMs =
Number.isFinite (durationMs)
? durationMs
: 0
if (lengthMs <= 0)
setVideoLength (playableDurationMs)
if (playableDurationMs <= 0)
{
void handlePlaybackError ()
return
@@ -738,7 +752,8 @@ const TheatreDetailPage: FC<Props> = ({ user }: Props) => {
<motion.div
layout="position"
transition={{ layout: { duration: .2, ease: 'easeOut' } }}
className="min-h-0 flex-1 overflow-y-auto bg-zinc-50 text-zinc-950 md:overflow-hidden dark:bg-zinc-950 dark:text-zinc-50">
className="min-h-0 flex-1 overflow-y-auto bg-zinc-50 text-zinc-950
md:overflow-hidden dark:bg-zinc-950 dark:text-zinc-50">
<Helmet>
<meta name="robots" content="noindex"/>
{theatre && <title>{`${ theatreTitle } | ${ SITE_TITLE }`}</title>}
@@ -811,8 +826,8 @@ const TheatreDetailPage: FC<Props> = ({ user }: Props) => {
key={post.id}
ref={embedRef}
post={post}
onLoadComplete={handleNiconicoLoadComplete}
onMetadataChange={syncPlayback}
onVideoReady={handleVideoReady}
onPlaybackChange={syncPlaybackTime}
onError={handlePlaybackError}/>) : (
<div className="grid min-h-72 place-items-center text-zinc-400">
{loading ? '次の投稿を選んでゐます……' : '上映待機中'}