整体UI调整

This commit is contained in:
谢宇宁
2026-10-26 19:51:59 +07:00
parent c8895f407c
commit eeb9986923
112 changed files with 1507 additions and 4255 deletions
+1 -11
View File
@@ -2,7 +2,7 @@ import { DecryptedImage } from "@/components/common/decrypted-image";
import type { AdvertiseInfo, AdvitiseData } from "@/lib/api/types";
import { IMG_PLACEHOLDER } from "@/lib/image/decrypt";
import { adHref, adTrackProps, pickBannerAds } from "./pick";
import { adHref, pickBannerAds } from "./pick";
type AdBannersProps = {
variant?: "pc" | "h5";
@@ -39,11 +39,6 @@ export function AdBanners({
target={external ? "_blank" : undefined}
rel={external ? "sponsored nofollow noopener noreferrer" : undefined}
className="block h-10 overflow-hidden rounded-xl"
{...adTrackProps(ad, {
slotKey: `content_banner_${index + 1}`,
slotName: `内容横幅第${index + 1}位`,
adType: "banner",
})}
>
<DecryptedImage
src={ad.images || null}
@@ -74,11 +69,6 @@ export function AdBanners({
target={external ? "_blank" : undefined}
rel={external ? "sponsored nofollow noopener noreferrer" : undefined}
className="block h-[97px] overflow-hidden rounded-xl"
{...adTrackProps(ad, {
slotKey: `content_banner_${index + 1}`,
slotName: `内容横幅第${index + 1}位`,
adType: "banner",
})}
>
<DecryptedImage
src={ad.images || null}
+1 -6
View File
@@ -3,7 +3,7 @@ import { AdIconMarquee } from "@/components/common/ad-icon-marquee";
import type { AdvertiseInfo, AdvitiseData } from "@/lib/api/types";
import { IMG_PLACEHOLDER } from "@/lib/image/decrypt";
import { adContentKey, adHref, adTrackProps, pickIconAds } from "./pick";
import { adContentKey, adHref, pickIconAds } from "./pick";
type AdIconsProps = {
variant?: "pc" | "h5";
@@ -54,11 +54,6 @@ export function AdIcons({
target={external ? "_blank" : undefined}
rel={external ? "sponsored nofollow noopener noreferrer" : undefined}
className={iconClass}
{...adTrackProps(ad, {
slotKey: `icon_grid_${index + 1}`,
slotName: `九宫格第${index + 1}位`,
adType: "icon",
})}
>
<DecryptedImage
src={ad.images || null}
-18
View File
@@ -36,21 +36,3 @@ export function adHref(link?: string, fallback = "#download") {
export function adContentKey(list: AdvertiseInfo[]) {
return list.map((item) => item.id || item.title || item.images || "").join("|") || "mock";
}
/** 外链广告埋点属性(对齐 hkdj / jha-1043 data-track-ad) */
export function adTrackProps(
ad: AdvertiseInfo,
options?: { slotKey?: string; slotName?: string; adType?: string },
) {
const adId = String(ad.advertiseCode || ad.id || "").trim();
if (!adId) return {};
return {
"data-track-ad": "external" as const,
"data-ad-id": adId,
"data-ad-clickable": "1",
"data-ad-type": options?.adType || "banner",
"data-ad-slot-key": options?.slotKey || ad.advertiseLocationCode || undefined,
"data-ad-slot-name": options?.slotName || ad.advertiseLocationName || ad.title || undefined,
"data-creative-id": String(ad.id || ""),
};
}
+73
View File
@@ -0,0 +1,73 @@
import type { BadgeTone } from "@/components/home/data";
/**
* 黄果黑料卡片 / 详情页公用视觉:琥珀色强调(区别于其它导航站的品红主题)。
* 卡片不做整块底色,封面 + 正文排版;hover 只给封面描边、标题变色。
*/
export const HL_ACCENT = "#FFB020";
export const HL_COVER =
"relative block overflow-hidden rounded-md bg-[#17161D] outline outline-1 -outline-offset-1 outline-white/5 transition-[outline-color] duration-300 group-hover:outline-[#FFB020]/80";
export const HL_COVER_IMG =
"absolute inset-0 h-full w-full object-cover transition-transform duration-500 ease-out group-hover:scale-[1.04]";
export const HL_TITLE_LINK = "transition-colors duration-200 hover:text-[#FFB020] group-hover:text-[#FFB020]";
const badgeText: Record<BadgeTone, string> = {
hot: "热播",
fresh: "新上架",
original: "独家",
};
/** 封面左上角琥珀角标(文字,不用图片角标) */
export function HlBadge({ tone, small = false }: { tone?: BadgeTone | null; small?: boolean }) {
if (!tone) return null;
return (
<span
className={`absolute top-0 left-0 z-[1] rounded-br-md bg-[#FFB020] font-semibold text-[#1A1206] ${
small ? "px-1.5 py-0.5 text-[10px] leading-[14px]" : "px-2 py-0.5 text-xs leading-[18px]"
}`}
>
{badgeText[tone]}
</span>
);
}
/** 接口时间 → YYYY-MM-DD;无效返回空串。优先直接截取,避免服务端 / 浏览器时区不同导致水合不一致 */
export function formatDay(raw?: string | null) {
const text = raw?.trim();
if (!text) return "";
const head = /^\d{4}-\d{2}-\d{2}/.exec(text);
if (head) return head[0];
const date = new Date(/^\d+$/.test(text) ? Number(text) : text);
if (Number.isNaN(date.getTime())) return "";
const pad = (value: number) => String(value).padStart(2, "0");
return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())}`;
}
/** 秒 → m:ss / h:mm:ss;无效返回空串 */
export function formatDuration(seconds?: number | null) {
const total = Math.floor(Number(seconds) || 0);
if (total <= 0) return "";
const h = Math.floor(total / 3600);
const m = Math.floor((total % 3600) / 60);
const s = total % 60;
const pad = (value: number) => String(value).padStart(2, "0");
return h ? `${h}:${pad(m)}:${pad(s)}` : `${m}:${pad(s)}`;
}
/** 卡片元信息里的小眼睛图标 */
export function EyeIcon({ className = "size-3.5" }: { className?: string }) {
return (
<svg viewBox="0 0 16 16" fill="none" className={className} aria-hidden="true">
<path
d="M1.5 8S4 3.5 8 3.5 14.5 8 14.5 8 12 12.5 8 12.5 1.5 8 1.5 8Z"
stroke="currentColor"
strokeWidth="1.3"
strokeLinejoin="round"
/>
<circle cx="8" cy="8" r="2" stroke="currentColor" strokeWidth="1.3" />
</svg>
);
}