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.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.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'