Fix list view alignment, modal sizing, folder icons, and add bitrate metadata
Some checks failed
Automated Container Build / build-and-push (push) Failing after 8s

This commit is contained in:
Elijah 2026-05-23 09:21:41 -07:00
parent 807775a176
commit 42864ebcb7
3 changed files with 27 additions and 11 deletions

View file

@ -1,15 +1,25 @@
'use client'; 'use client';
import { useState, useEffect, useCallback, useRef, useMemo } from 'react'; import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
import { formatDistanceToNow } from 'date-fns';
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
import { import {
Folder, File, Search, Pin, Trash2, HardDrive, Settings, Folder as LucideFolder, File, Search, Pin, Trash2, HardDrive, Settings,
ChevronRight, Grid3X3, List, Plus, Upload, LogOut, ChevronRight, Grid3X3, List, Plus, Upload, LogOut,
MoreVertical, Star, Download, Pencil, Copy, Move, MoreVertical, Star, Download, Pencil, Copy, Move,
FolderPlus, ArrowUp, X, Check, RefreshCw, Info, Link as LinkIcon, Image as ImageIcon, Film as FilmIcon, FolderPlus, ArrowUp, X, Check, RefreshCw, Info, Link as LinkIcon, Image as ImageIcon, Film as FilmIcon,
Sun, Moon, Music as MusicIcon, Code as CodeIcon, Archive as ArchiveIcon, CornerDownRight Sun, Moon, Music as MusicIcon, Code as CodeIcon, Archive as ArchiveIcon, CornerDownRight
} from 'lucide-react'; } from 'lucide-react';
import api from '@/lib/api'; import api from '@/lib/api';
const Folder = ({ className, style }: { className?: string, style?: React.CSSProperties }) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className={className} style={style}>
<path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z" />
</svg>
);
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080';
import api from '@/lib/api';
import FilePreview from './FilePreview'; import FilePreview from './FilePreview';
import SettingsPage from './SettingsPage'; import SettingsPage from './SettingsPage';
import StorageDashboard from './StorageDashboard'; import StorageDashboard from './StorageDashboard';
@ -128,7 +138,7 @@ function Tooltip({ children, text }: { children: React.ReactNode; text: string }
return ( return (
<div <div
className="relative flex items-center justify-center w-full min-w-0" className="relative flex items-center justify-start w-full min-w-0"
onMouseEnter={() => setHovered(true)} onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)} onMouseLeave={() => setHovered(false)}
> >
@ -733,15 +743,13 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) {
function getFileIcon(file: FileItem, large = false) { function getFileIcon(file: FileItem, large = false) {
if (file.is_dir) { if (file.is_dir) {
if (large) {
return ( return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="var(--color-accent)" className="w-28 h-28 opacity-90 drop-shadow-sm"> <Folder
<path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z" /> className={`${large ? 'w-28 h-28 opacity-90 drop-shadow-sm' : 'w-5 h-5 flex-shrink-0 aspect-square'}`}
</svg> style={{ color: 'var(--color-accent)' }}
/>
); );
} }
return <Folder className="w-5 h-5" style={{ color: 'var(--color-accent)' }} />;
}
const sizeClass = large ? "w-20 h-20" : "w-5 h-5"; const sizeClass = large ? "w-20 h-20" : "w-5 h-5";
const ext = file.name.split('.').pop()?.toLowerCase() || ''; const ext = file.name.split('.').pop()?.toLowerCase() || '';

View file

@ -158,6 +158,14 @@ export default function FileInfoModal({ filePath, onClose }: FileInfoModalProps)
<span style={{ color: 'var(--color-text-primary)' }}>{data.info.metadata.VideoFrameRate} fps</span> <span style={{ color: 'var(--color-text-primary)' }}>{data.info.metadata.VideoFrameRate} fps</span>
</div> </div>
)} )}
{(data.info.metadata.AvgBitrate || data.info.metadata.AudioBitrate || data.info.metadata.VideoBitrate || data.info.metadata.Bitrate) && (
<div className="flex items-center justify-between text-sm">
<span style={{ color: 'var(--color-text-secondary)' }}>Bitrate</span>
<span style={{ color: 'var(--color-text-primary)' }}>
{data.info.metadata.AvgBitrate || data.info.metadata.AudioBitrate || data.info.metadata.VideoBitrate || data.info.metadata.Bitrate}
</span>
</div>
)}
{data.info.metadata.CompressorID && ( {data.info.metadata.CompressorID && (
<div className="flex items-center justify-between text-sm"> <div className="flex items-center justify-between text-sm">
<span style={{ color: 'var(--color-text-secondary)' }}>Codec</span> <span style={{ color: 'var(--color-text-secondary)' }}>Codec</span>

View file

@ -145,7 +145,7 @@ export default function FilePreview({ file, onClose }: FilePreviewProps) {
)} )}
{previewType === 'audio' && ( {previewType === 'audio' && (
<div className="w-full max-w-md p-6 rounded-xl text-center" style={{ backgroundColor: 'var(--color-bg-elevated)', border: '1px solid var(--color-border)' }}> <div className="w-[400px] sm:w-[500px] max-w-full p-6 rounded-xl text-center" style={{ backgroundColor: 'var(--color-bg-elevated)', border: '1px solid var(--color-border)' }}>
<Music className="w-16 h-16 mx-auto mb-6" style={{ color: 'var(--color-accent)' }} /> <Music className="w-16 h-16 mx-auto mb-6" style={{ color: 'var(--color-accent)' }} />
<h3 className="text-lg font-medium mb-4 truncate" style={{ color: 'var(--color-text-primary)' }}>{getFileDisplayName(file.name)}</h3> <h3 className="text-lg font-medium mb-4 truncate" style={{ color: 'var(--color-text-primary)' }}>{getFileDisplayName(file.name)}</h3>
<audio src={downloadUrl} controls autoPlay className="w-full outline-none" /> <audio src={downloadUrl} controls autoPlay className="w-full outline-none" />