diff --git a/src/app/folder-viewer/page.tsx b/src/app/folder-viewer/page.tsx index d1272d5..1767e6e 100644 --- a/src/app/folder-viewer/page.tsx +++ b/src/app/folder-viewer/page.tsx @@ -108,12 +108,12 @@ const FolderViewerPage = () => { const filename = path.substring(lastSeparatorIndex + 1); // If directory is short enough, show it all - if (directory.length <= 30) { + if (directory.length <= 80) { return `${directory}/${filename}`; } // Truncate directory with ellipsis in the middle - const maxDirLength = 25; + const maxDirLength = 75; const startLength = Math.floor(maxDirLength / 2); const endLength = maxDirLength - startLength - 3; // -3 for "..." @@ -124,6 +124,18 @@ const FolderViewerPage = () => { return `${truncatedDir}/${filename}`; }; + const formatTitle = (title: string) => { + if (!title) return ''; + + // If title is short enough, return as is + if (title.length <= 40) { + return title; + } + + // For longer titles, truncate to prevent awkward third-line display + return title.length > 60 ? title.substring(0, 60) + '...' : title; + }; + const getLibraryRoot = (currentPath: string): string | null => { if (!currentPath || libraries.length === 0) return null; @@ -351,7 +363,7 @@ const FolderViewerPage = () => { -
+
{error && (
@@ -374,7 +386,7 @@ const FolderViewerPage = () => { {!error && Array.isArray(items) && items.map((item) => (
+ className={`group relative bg-white dark:bg-slate-800 rounded-xl shadow-sm hover:shadow-lg transition-all duration-300 hover:-translate-y-1 overflow-hidden min-h-[280px] ${(item.type === 'video' || item.type === 'photo') ? 'cursor-pointer' : ''}`}> { @@ -396,44 +408,29 @@ const FolderViewerPage = () => {
) : isMediaFile(item) ? ( -
+
{item.name} -
-
- {item.type === 'video' ? ( -
- -
- ) : ( -
- -
- )} -
{item.type === 'video' && ( <> - {/* Always visible small play icon */} -
- +
+
- {/* Large play button on hover */} -
-
- -
-
- {/* Loading overlay when video is being opened */} {isVideoLoading && selectedVideo?.id === item.id && ( -
-
+
+
)} )} + {item.type === 'photo' && ( +
+ +
+ )}
) : (
{
)}
-
-

{item.name}

+
+

{formatTitle(item.name)}

- {/* Star Rating for media files */} - {isMediaFile(item) && (item.avg_rating || 0) > 0 && ( -
+
+ {formatFileSize(item.size)} + {isMediaFile(item) && (item.avg_rating || 0) > 0 && ( -
- )} - -
-

{formatFileSize(item.size)}

- {!item.isDirectory && ( -

- {formatFilePath(item.path)} -

)}
+ +

+ {formatFilePath(item.path)} +

diff --git a/src/components/infinite-virtual-grid.tsx b/src/components/infinite-virtual-grid.tsx index 8ae71f1..ef74891 100644 --- a/src/components/infinite-virtual-grid.tsx +++ b/src/components/infinite-virtual-grid.tsx @@ -27,7 +27,7 @@ interface InfiniteVirtualGridProps { onRate: (id: number, rating: number) => Promise; } -const ITEM_HEIGHT = 300; +const ITEM_HEIGHT = 220; const ITEMS_PER_BATCH = 50; const BUFFER_SIZE = 200; @@ -354,7 +354,7 @@ export default function InfiniteVirtualGrid({ className="group hover:shadow-lg transition-all duration-300 hover:-translate-y-1 cursor-pointer border-border overflow-hidden h-full" onClick={() => onItemClick(item)} > -
+
{item.title}
- -

- {item.title || item.path.split('/').pop()} -

- - {(item.avg_rating > 0 || item.star_count > 0) && ( -
- + +
+
+

+ {item.title || item.path.split('/').pop()} +

+ + {(item.avg_rating > 0 || item.star_count > 0) && ( +
+ +
+ )}
- )} - -
-
- - {formatFileSize(item.size)} + +
+ {type === 'video' && item.bookmark_count > 0 && ( +
+ +
+ )}
-

- {formatFilePath(item.path)} -

+ +
+
+
+ + {formatFileSize(item.size)} +
+ {type === 'video' && item.bookmark_count > 0 && ( + + {item.bookmark_count} + + )} +
+ +

+ {formatFilePath(item.path)} +

+
diff --git a/src/components/star-rating.tsx b/src/components/star-rating.tsx index 39a0e1c..6129c72 100644 --- a/src/components/star-rating.tsx +++ b/src/components/star-rating.tsx @@ -6,7 +6,7 @@ import { cn } from '@/lib/utils'; interface StarRatingProps { rating: number; count?: number; - size?: 'sm' | 'md' | 'lg'; + size?: 'xs' | 'sm' | 'md' | 'lg'; showCount?: boolean; interactive?: boolean; onRate?: (rating: number) => void; @@ -23,6 +23,7 @@ export function StarRating({ className }: StarRatingProps) { const sizeClasses = { + xs: 'h-2.5 w-2.5', sm: 'h-3 w-3', md: 'h-4 w-4', lg: 'h-5 w-5'