|
@@ -36,6 +36,7 @@ export default function SharePage() {
|
|
|
const [commentText, setCommentText] = useState('');
|
|
const [commentText, setCommentText] = useState('');
|
|
|
const [commentSubmitting, setCommentSubmitting] = useState(false);
|
|
const [commentSubmitting, setCommentSubmitting] = useState(false);
|
|
|
const [commentError, setCommentError] = useState<string | null>(null);
|
|
const [commentError, setCommentError] = useState<string | null>(null);
|
|
|
|
|
+ const [currentTime, setCurrentTime] = useState(0);
|
|
|
|
|
|
|
|
// ── Load guest name from localStorage ───────────────────────────────────────
|
|
// ── Load guest name from localStorage ───────────────────────────────────────
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
@@ -151,6 +152,7 @@ export default function SharePage() {
|
|
|
const data = await shareLinksApi.postGuestComment(tokenParam, {
|
|
const data = await shareLinksApi.postGuestComment(tokenParam, {
|
|
|
guestName: guestName.trim(),
|
|
guestName: guestName.trim(),
|
|
|
content: commentText.trim(),
|
|
content: commentText.trim(),
|
|
|
|
|
+ timestamp: currentTime > 0 ? currentTime : undefined,
|
|
|
});
|
|
});
|
|
|
setComments(prev => [...prev, data.comment]);
|
|
setComments(prev => [...prev, data.comment]);
|
|
|
setCommentsTotal(prev => prev + 1);
|
|
setCommentsTotal(prev => prev + 1);
|
|
@@ -396,9 +398,11 @@ export default function SharePage() {
|
|
|
{streamUrl ? (
|
|
{streamUrl ? (
|
|
|
<div className="w-full max-w-6xl mx-auto" style={{ aspectRatio: '16/9', maxHeight: '85vh' }}>
|
|
<div className="w-full max-w-6xl mx-auto" style={{ aspectRatio: '16/9', maxHeight: '85vh' }}>
|
|
|
{isHls ? (
|
|
{isHls ? (
|
|
|
- <video ref={videoRef} className="w-full h-full" controls playsInline />
|
|
|
|
|
|
|
+ <video ref={videoRef} className="w-full h-full" controls playsInline
|
|
|
|
|
+ onTimeUpdate={e => setCurrentTime(e.currentTarget.currentTime)} />
|
|
|
) : (
|
|
) : (
|
|
|
- <video ref={videoRef} src={streamUrl} className="w-full h-full" controls playsInline />
|
|
|
|
|
|
|
+ <video ref={videoRef} src={streamUrl} className="w-full h-full" controls playsInline
|
|
|
|
|
+ onTimeUpdate={e => setCurrentTime(e.currentTarget.currentTime)} />
|
|
|
)}
|
|
)}
|
|
|
</div>
|
|
</div>
|
|
|
) : !linkInfo?.asset.videoReady ? (
|
|
) : !linkInfo?.asset.videoReady ? (
|
|
@@ -425,6 +429,14 @@ export default function SharePage() {
|
|
|
style={{ background: 'rgba(255,255,255,0.05)', color: 'var(--text)', border: '1px solid rgba(255,255,255,0.08)', outline: 'none' }}
|
|
style={{ background: 'rgba(255,255,255,0.05)', color: 'var(--text)', border: '1px solid rgba(255,255,255,0.08)', outline: 'none' }}
|
|
|
/>
|
|
/>
|
|
|
{commentError && <p className="text-xs mt-1" style={{ color: '#F87171' }}>{commentError}</p>}
|
|
{commentError && <p className="text-xs mt-1" style={{ color: '#F87171' }}>{commentError}</p>}
|
|
|
|
|
+ {currentTime > 0 && (
|
|
|
|
|
+ <div className="text-xs mb-2 flex items-center gap-1" style={{ color: '#A78BFA' }}>
|
|
|
|
|
+ <svg className="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
|
|
|
+ <path strokeLinecap="round" strokeLinejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ Comment at {formatTimecode(currentTime, 30, currentTime)}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
<div className="flex justify-end mt-2">
|
|
<div className="flex justify-end mt-2">
|
|
|
<button type="submit" disabled={commentSubmitting || !commentText.trim()}
|
|
<button type="submit" disabled={commentSubmitting || !commentText.trim()}
|
|
|
className="flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-lg transition-all"
|
|
className="flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-lg transition-all"
|