add tag selector to image and video viewers

This commit is contained in:
Garret Patti
2026-04-05 14:01:32 -04:00
parent 2ba887dba6
commit 427aade21a
4 changed files with 177 additions and 50 deletions

View File

@@ -1,15 +1,21 @@
'use client'
import { useEffect, useRef } from 'react'
import { useEffect, useRef, useState } from 'react'
import TagSelector from '@/components/tags/TagSelector'
interface Props {
url: string
name: string
onClose: () => void
mediaKey?: string
onTagsChanged?: () => void
}
export default function VideoPlayerModal({ url, name, onClose }: Props) {
export default function VideoPlayerModal({ url, name, onClose, mediaKey, onTagsChanged }: Props) {
const overlayRef = useRef<HTMLDivElement>(null)
const [showTags, setShowTags] = useState(
() => !!mediaKey && typeof window !== 'undefined' && window.innerWidth >= 1280
)
useEffect(() => {
const handleKey = (e: KeyboardEvent) => {
@@ -35,31 +41,79 @@ export default function VideoPlayerModal({ url, name, onClose }: Props) {
onClick={handleOverlayClick}
>
{/* Toolbar */}
<div className="flex items-center justify-between w-full max-w-4xl">
<div className={`flex items-center justify-between w-full ${showTags ? '' : 'max-w-4xl'}`}>
<span className="text-sm truncate max-w-[80%]" style={{ color: 'var(--text-secondary)' }}>
{name}
</span>
<button
onClick={onClose}
className="w-8 h-8 rounded-full flex items-center justify-center text-sm flex-shrink-0 transition-colors"
style={{ backgroundColor: 'var(--surface)', color: 'var(--text-primary)' }}
onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--surface-hover)')}
onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--surface)')}
aria-label="Close"
>
</button>
<div className="flex items-center gap-2 flex-shrink-0">
{mediaKey && (
<button
onClick={(e) => { e.stopPropagation(); setShowTags((v) => !v) }}
className="w-8 h-8 rounded-full flex items-center justify-center text-sm transition-colors"
style={{
backgroundColor: showTags ? 'var(--accent)' : 'var(--surface)',
color: showTags ? '#fff' : 'var(--text-primary)',
}}
onMouseEnter={(e) => {
if (!showTags) (e.currentTarget as HTMLElement).style.backgroundColor = 'var(--surface-hover)'
}}
onMouseLeave={(e) => {
if (!showTags) (e.currentTarget as HTMLElement).style.backgroundColor = 'var(--surface)'
}}
aria-label={showTags ? 'Hide tags' : 'Show tags'}
title="Tags"
>
🏷
</button>
)}
<button
onClick={onClose}
className="w-8 h-8 rounded-full flex items-center justify-center text-sm flex-shrink-0 transition-colors"
style={{ backgroundColor: 'var(--surface)', color: 'var(--text-primary)' }}
onMouseEnter={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--surface-hover)')}
onMouseLeave={(e) => ((e.currentTarget as HTMLElement).style.backgroundColor = 'var(--surface)')}
aria-label="Close"
>
</button>
</div>
</div>
{/* Video */}
<video
src={url}
controls
autoPlay
className="w-full max-w-4xl max-h-[80vh] rounded-lg"
style={{ backgroundColor: '#000' }}
onClick={(e) => e.stopPropagation()}
/>
{showTags ? (
<div className="flex gap-4 w-full flex-1 min-h-0 items-start">
{/* Video */}
<div className="flex-1 min-w-0 flex items-center justify-center">
<video
src={url}
controls
autoPlay
className="w-full max-h-full rounded-lg"
style={{ backgroundColor: '#000' }}
onClick={(e) => e.stopPropagation()}
/>
</div>
{/* Tag panel */}
<div
className="w-80 flex-shrink-0 rounded-xl overflow-y-auto max-h-[80vh] p-4"
style={{ backgroundColor: 'var(--surface)', border: '1px solid var(--border)' }}
onClick={(e) => e.stopPropagation()}
>
<p className="text-xs font-semibold uppercase tracking-wider mb-3" style={{ color: 'var(--text-secondary)' }}>
Tags
</p>
<TagSelector mediaKey={mediaKey!} onTagsChanged={onTagsChanged} />
</div>
</div>
) : (
<video
src={url}
controls
autoPlay
className="w-full max-w-4xl max-h-[80vh] rounded-lg"
style={{ backgroundColor: '#000' }}
onClick={(e) => e.stopPropagation()}
/>
)}
</div>
)
}