feat: Extract and display video quality from titles on video cards and update package version.

This commit is contained in:
kuekhaoyang
2025-12-28 17:52:53 +08:00
parent 1e67ad9240
commit e961e9e195
4 changed files with 60 additions and 13 deletions
+30 -10
View File
@@ -10,6 +10,7 @@ import { LatencyBadge } from '@/components/ui/LatencyBadge';
import { FavoriteButton } from '@/components/favorites/FavoriteButton';
import { Video } from '@/lib/types';
import { parseVideoTitle } from '@/lib/utils/video';
interface VideoCardProps {
video: Video;
@@ -139,17 +140,36 @@ export const VideoCard = memo<VideoCardProps>(({
</div>
{/* Info */}
<div className="pt-3">
<h4 className="font-semibold text-sm text-[var(--text-color)] line-clamp-2">
{video.vod_remarks && (
<span className="text-xs text-[var(--accent-color)] mr-1">[{video.vod_remarks}]</span>
)}
{video.vod_name}
</h4>
<div className="p-3 flex-1 flex flex-col">
{(() => {
const { cleanTitle, quality } = parseVideoTitle(video.vod_name);
// Visual priority: Quality from title tag, then vod_remarks
const displayQuality = quality || video.vod_remarks;
return (
<>
<h4 className="font-semibold text-sm text-[var(--text-color)] line-clamp-2 min-h-[2.5rem] mb-1">
{cleanTitle}
</h4>
{displayQuality && (
<p className="text-xs text-[var(--accent-color)] font-medium">
{displayQuality}
</p>
)}
{/* Hide remarks if it was used as quality to avoid duplication */}
{video.vod_remarks && video.vod_remarks !== displayQuality && (
<p className="text-xs text-[var(--text-color-secondary)] mt-1 line-clamp-1">
{video.vod_remarks}
</p>
)}
</>
);
})()}
</div>
</Card>
</Link>
</div>
</div>
</Card>
</Link>
</div >
);
});
+27
View File
@@ -0,0 +1,27 @@
/**
* Parses a video title to extract quality tags (e.g., [HD], [TS])
* and return a cleaned title.
*/
export function parseVideoTitle(title: string): { cleanTitle: string, quality?: string } {
// Regex to match tags in brackets at the start of the title
// Example: "[HD] 利刃出鞘3" -> quality: "HD", cleanTitle: "利刃出鞘3"
// Example: "利刃出鞘3 [HD]" -> quality: "HD", cleanTitle: "利刃出鞘3"
const bracketRegex = /\[([^\]]+)\]/g;
let quality: string | undefined;
let cleanTitle = title;
const matches = [...title.matchAll(bracketRegex)];
if (matches.length > 0) {
// Take the first bracket content as quality (usually what we want)
quality = matches[0][1];
// Remove all brackets and their content from the title
cleanTitle = title.replace(bracketRegex, '').trim();
}
return {
cleanTitle: cleanTitle || title,
quality
};
}
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "kvideo",
"version": "3.6.0",
"version": "3.7.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "kvideo",
"version": "3.6.0",
"version": "3.7.0",
"dependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "kvideo",
"version": "3.6.0",
"version": "3.7.0",
"private": true,
"scripts": {
"dev": "next dev",