|
|
@@ -591,8 +591,8 @@ export default function ReviewPage() {
|
|
|
{/* ── Side-by-side compare layout ───────────────────────── */}
|
|
|
{compareMode ? (
|
|
|
<div className="flex gap-2 w-full">
|
|
|
- {/* Main video */}
|
|
|
- <div className="flex-1 min-w-0">
|
|
|
+ {/* Main video + its comments */}
|
|
|
+ <div className="flex-1 min-w-0 flex flex-col gap-0">
|
|
|
<div className="text-xs mb-1 px-1 truncate" style={{ color: 'rgba(255,255,255,0.5)' }}>
|
|
|
{asset.title}
|
|
|
</div>
|
|
|
@@ -617,11 +617,47 @@ export default function ReviewPage() {
|
|
|
externalCurrentTime={currentTime}
|
|
|
externalPlaying={playing}
|
|
|
/>
|
|
|
+ {/* Comments below main video */}
|
|
|
+ <div className="mt-2 rounded-xl overflow-hidden" style={{ background: 'rgba(10,11,20,0.80)', border: '1px solid rgba(255,255,255,0.06)' }}>
|
|
|
+ <div className="px-3 py-2 flex items-center gap-2" style={{ borderBottom: '1px solid rgba(255,255,255,0.06)' }}>
|
|
|
+ <span className="text-xs font-medium" style={{ color: 'var(--text)' }}>
|
|
|
+ Comments
|
|
|
+ </span>
|
|
|
+ <span className="text-xs px-1.5 py-0.5 rounded-full" style={{ background: 'rgba(255,255,255,0.06)', color: 'var(--text-muted)' }}>
|
|
|
+ {visibleComments.length}
|
|
|
+ </span>
|
|
|
+ <span className="font-mono text-[11px] ml-auto" style={{ color: '#818CF8' }}>
|
|
|
+ {formatTimecode(currentTime, fps, asset?.duration ?? 0)}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div className="max-h-32 overflow-y-auto">
|
|
|
+ {visibleComments.length === 0 ? (
|
|
|
+ <p className="text-xs text-center py-4" style={{ color: 'var(--text-muted)' }}>No comments</p>
|
|
|
+ ) : (
|
|
|
+ visibleComments.slice(0, 5).map(comment => (
|
|
|
+ <div key={comment.id} className="px-3 py-2 flex items-start gap-2" style={{ borderBottom: '1px solid rgba(255,255,255,0.04)' }}>
|
|
|
+ <Avatar name={comment.user?.name ?? 'U'} size="xs" />
|
|
|
+ <div className="flex-1 min-w-0">
|
|
|
+ <div className="flex items-center gap-1.5 mb-0.5">
|
|
|
+ <span className="text-[11px] font-medium" style={{ color: 'var(--text)' }}>{comment.user?.name ?? 'Unknown'}</span>
|
|
|
+ {comment.timestamp != null && (
|
|
|
+ <span className="text-[10px] font-mono px-1 rounded" style={{ background: 'rgba(99,102,241,0.10)', color: '#818CF8' }}>
|
|
|
+ {formatTimecode(comment.timestamp, fps, asset?.duration ?? 0)}
|
|
|
+ </span>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ <p className="text-[11px] truncate" style={{ color: 'var(--text-muted)' }}>{comment.content}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
- {/* Compare video — only show when durations match */}
|
|
|
+ {/* Compare video + its comments — only show when durations match */}
|
|
|
{compareAsset && !compareMismatch && (
|
|
|
- <div className="flex-1 min-w-0">
|
|
|
+ <div className="flex-1 min-w-0 flex flex-col gap-0">
|
|
|
<div className="text-xs mb-1 px-1 truncate" style={{ color: 'rgba(255,255,255,0.5)' }}>
|
|
|
{compareAsset.title}
|
|
|
</div>
|
|
|
@@ -645,6 +681,39 @@ export default function ReviewPage() {
|
|
|
externalCurrentTime={currentTime}
|
|
|
externalPlaying={playing}
|
|
|
/>
|
|
|
+ {/* Comments below compare video */}
|
|
|
+ <div className="mt-2 rounded-xl overflow-hidden" style={{ background: 'rgba(10,11,20,0.80)', border: '1px solid rgba(255,255,255,0.06)' }}>
|
|
|
+ <div className="px-3 py-2 flex items-center gap-2" style={{ borderBottom: '1px solid rgba(255,255,255,0.06)' }}>
|
|
|
+ <span className="text-xs font-medium" style={{ color: 'var(--text)' }}>
|
|
|
+ Comments
|
|
|
+ </span>
|
|
|
+ <span className="text-xs px-1.5 py-0.5 rounded-full" style={{ background: 'rgba(255,255,255,0.06)', color: 'var(--text-muted)' }}>
|
|
|
+ {compareVisibleComments.length}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div className="max-h-32 overflow-y-auto">
|
|
|
+ {compareVisibleComments.length === 0 ? (
|
|
|
+ <p className="text-xs text-center py-4" style={{ color: 'var(--text-muted)' }}>No comments</p>
|
|
|
+ ) : (
|
|
|
+ compareVisibleComments.slice(0, 5).map(comment => (
|
|
|
+ <div key={comment.id} className="px-3 py-2 flex items-start gap-2" style={{ borderBottom: '1px solid rgba(255,255,255,0.04)' }}>
|
|
|
+ <Avatar name={comment.user?.name ?? 'U'} size="xs" />
|
|
|
+ <div className="flex-1 min-w-0">
|
|
|
+ <div className="flex items-center gap-1.5 mb-0.5">
|
|
|
+ <span className="text-[11px] font-medium" style={{ color: 'var(--text)' }}>{comment.user?.name ?? 'Unknown'}</span>
|
|
|
+ {comment.timestamp != null && (
|
|
|
+ <span className="text-[10px] font-mono px-1 rounded" style={{ background: 'rgba(99,102,241,0.10)', color: '#818CF8' }}>
|
|
|
+ {formatTimecode(comment.timestamp, fps, asset?.duration ?? 0)}
|
|
|
+ </span>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ <p className="text-[11px] truncate" style={{ color: 'var(--text-muted)' }}>{comment.content}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
)}
|
|
|
</div>
|
|
|
@@ -758,8 +827,7 @@ export default function ReviewPage() {
|
|
|
{!compareMode && (
|
|
|
<div className="flex flex-wrap gap-3 text-xs shrink-0 hidden sm:flex" style={{ color: 'var(--text-subtle)' }}>
|
|
|
<span><kbd className="px-1.5 py-0.5 rounded text-[10px]" style={{ background: 'rgba(255,255,255,0.06)' }}>Space</kbd> play/pause</span>
|
|
|
- <span><kbd className="px-1.5 py-0.5 rounded text-[10px]" style={{ background: 'rgba(255,255,255,0.06)' }}>←</kbd><kbd className="px-1.5 py-0.5 rounded text-[10px] ml-0.5" style={{ background: 'rgba(255,255,255,0.06)' }}>→</kbd> seek ±5s</span>
|
|
|
- <span><kbd className="px-1.5 py-0.5 rounded text-[10px]" style={{ background: 'rgba(255,255,255,0.06)' }}>U</kbd><kbd className="px-1.5 py-0.5 rounded text-[10px] ml-0.5" style={{ background: 'rgba(255,255,255,0.06)' }}>I</kbd> frame</span>
|
|
|
+ <span><kbd className="px-1.5 py-0.5 rounded text-[10px]" style={{ background: 'rgba(255,255,255,0.06)' }}>←</kbd><kbd className="px-1.5 py-0.5 rounded text-[10px] ml-0.5" style={{ background: 'rgba(255,255,255,0.06)' }}>→</kbd> ±1 frame <kbd className="px-1.5 py-0.5 rounded text-[10px]" style={{ background: 'rgba(255,255,255,0.06)' }}>⇧←</kbd><kbd className="px-1.5 py-0.5 rounded text-[10px] ml-0.5" style={{ background: 'rgba(255,255,255,0.06)' }}>⇧→</kbd> ±1s</span>
|
|
|
<span><kbd className="px-1.5 py-0.5 rounded text-[10px]" style={{ background: 'rgba(255,255,255,0.06)' }}>C</kbd> draw mode</span>
|
|
|
<span><kbd className="px-1.5 py-0.5 rounded text-[10px]" style={{ background: 'rgba(255,255,255,0.06)' }}>Esc</kbd> exit draw</span>
|
|
|
<span className="font-mono text-[11px]">{formatTimecode(currentTime, fps, asset?.duration ?? 0)}</span>
|
|
|
@@ -767,12 +835,13 @@ export default function ReviewPage() {
|
|
|
)}
|
|
|
</div>
|
|
|
|
|
|
- {/* Resize handle — only shown in landscape */}
|
|
|
- {!isPortrait && (
|
|
|
+ {/* Resize handle — only shown in landscape, hidden in compare mode */}
|
|
|
+ {!isPortrait && !compareMode && (
|
|
|
<div className="resize-handle" onMouseDown={handleResizeStart} style={{ width: '4px' }} />
|
|
|
)}
|
|
|
|
|
|
- {/* ── Comment panel ─────────────────────────────────── */}
|
|
|
+ {/* ── Comment panel — hidden in compare mode (comments are below each video) ── */}
|
|
|
+ {!compareMode && (
|
|
|
<div
|
|
|
ref={panelRef}
|
|
|
className="flex flex-col overflow-hidden shrink-0"
|
|
|
@@ -969,6 +1038,7 @@ export default function ReviewPage() {
|
|
|
</form>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ )}
|
|
|
</div>
|
|
|
</div>
|
|
|
);
|