From 6fe6a43cf0210bf0eb5144eaaa8a8f7104656bfa Mon Sep 17 00:00:00 2001 From: tigeren Date: Wed, 27 Aug 2025 14:53:30 +0000 Subject: [PATCH] feat: add average rating and star count to media retrieval and display - Updated media retrieval query to include average ratings and star counts for media files. - Enhanced FolderViewer and VideosPage components to display star ratings, improving user feedback on media quality. - Integrated StarRating component for visual representation of ratings in the UI. --- media.db | Bin 258048 -> 258048 bytes src/app/api/files/route.ts | 6 ++- src/app/folder-viewer/page.tsx | 18 ++++++++- src/app/videos/page.tsx | 16 +++++++- src/components/star-rating.tsx | 66 +++++++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 src/components/star-rating.tsx diff --git a/media.db b/media.db index fbd3112827d990f018f4bf8fdfc5bcab4e012180..6e59859274007741c31e665d456586b2f822e782 100644 GIT binary patch delta 175 zcmZp8z~AtIe}Xil&qNt#MxTudlkFMVH-E7gP~c$Xzr?_QiGRsvL4g_klb7V{>$0;l zFd7@H85tOv>Ka(+8ks8?npl|{Ss55%5!zJ1A^x!G;Km^UNmWdHyG delta 169 zcmZp8z~AtIe}Xil*F+g-Mz4(tlkFMVHh-}fP~cz?U|`_C#J^;-pui0N$xHI}b=g=M z7>$h;j0}uSbqy?Zjm#7bEv$?!txQd@2yH505rCNSi~rYV!3j_JCkC+aurf0;GO>b4 z1-4BSf(17FZ+OYLapDU0%};jLvu;ja|I=&ogukNGnYkG~ns@$c-}#Gi`_5lX?q2~u Cl{9z& diff --git a/src/app/api/files/route.ts b/src/app/api/files/route.ts index fd15f9b..9092650 100644 --- a/src/app/api/files/route.ts +++ b/src/app/api/files/route.ts @@ -20,10 +20,10 @@ export async function GET(request: Request) { // Get media files from database for this path const mediaFiles = db.prepare(` - SELECT id, path, type, thumbnail + SELECT id, path, type, thumbnail, avg_rating, star_count FROM media WHERE path LIKE ? - `).all(`${dirPath}%`) as Array<{id: number, path: string, type: string, thumbnail: string | null}>; + `).all(`${dirPath}%`) as Array<{id: number, path: string, type: string, thumbnail: string | null, avg_rating: number, star_count: number}>; const result = files.map((file) => { const filePath = path.join(dirPath, file); @@ -48,6 +48,8 @@ export async function GET(request: Request) { type: mediaFile?.type || type, thumbnail: mediaFile?.thumbnail, id: mediaFile?.id, + avg_rating: mediaFile?.avg_rating || 0, + star_count: mediaFile?.star_count || 0, }; }); diff --git a/src/app/folder-viewer/page.tsx b/src/app/folder-viewer/page.tsx index d3f9204..5b6fce2 100644 --- a/src/app/folder-viewer/page.tsx +++ b/src/app/folder-viewer/page.tsx @@ -3,7 +3,8 @@ import { useState, useEffect, Suspense } from "react"; import { useSearchParams, useRouter } from "next/navigation"; -import { Folder, File, Image, Film, Play, ChevronLeft, Home } from "lucide-react"; +import { Folder, File, Image, Film, Play, ChevronLeft, Home, Star } from "lucide-react"; +import { StarRating } from "@/components/star-rating"; import Link from "next/link"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import PhotoViewer from "@/components/photo-viewer"; @@ -18,6 +19,8 @@ interface FileSystemItem { thumbnail?: string; type?: string; id?: number; + avg_rating?: number; + star_count?: number; } interface BreadcrumbItem { @@ -364,6 +367,19 @@ const FolderViewerPage = () => {

{item.name}

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

{formatFileSize(item.size)}

{!item.isDirectory && ( diff --git a/src/app/videos/page.tsx b/src/app/videos/page.tsx index fa8e0bd..96f2d9f 100644 --- a/src/app/videos/page.tsx +++ b/src/app/videos/page.tsx @@ -2,11 +2,12 @@ import { useState, useEffect } from "react"; import Link from "next/link"; -import { Film, Play, Clock, HardDrive, Search, Filter } from "lucide-react"; +import { Film, Play, Clock, HardDrive, Search, Filter, Star } from "lucide-react"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import VideoViewer from "@/components/video-viewer"; +import { StarRating } from "@/components/star-rating"; interface Video { id: number; @@ -225,6 +226,19 @@ const VideosPage = () => {

{video.title}

+ + {/* Star Rating */} + {(video.avg_rating > 0 || video.star_count > 0) && ( +
+ +
+ )} +
diff --git a/src/components/star-rating.tsx b/src/components/star-rating.tsx new file mode 100644 index 0000000..39a0e1c --- /dev/null +++ b/src/components/star-rating.tsx @@ -0,0 +1,66 @@ +'use client'; + +import { Star } from 'lucide-react'; +import { cn } from '@/lib/utils'; + +interface StarRatingProps { + rating: number; + count?: number; + size?: 'sm' | 'md' | 'lg'; + showCount?: boolean; + interactive?: boolean; + onRate?: (rating: number) => void; + className?: string; +} + +export function StarRating({ + rating, + count = 0, + size = 'md', + showCount = false, + interactive = false, + onRate, + className +}: StarRatingProps) { + const sizeClasses = { + sm: 'h-3 w-3', + md: 'h-4 w-4', + lg: 'h-5 w-5' + }; + + const handleRate = (newRating: number) => { + if (interactive && onRate) { + onRate(newRating); + } + }; + + return ( +
+ {[1, 2, 3, 4, 5].map((star) => ( + + ))} + {showCount && count > 0 && ( + + ({count}) + + )} +
+ ); +} \ No newline at end of file