添加详情页的点赞计数,添加网站图标

This commit is contained in:
feie9456 2025-10-23 14:22:12 +08:00
parent 5a5eba19e4
commit f94ef73518
10 changed files with 65 additions and 19 deletions

View File

@ -87,11 +87,16 @@ async function readPostMem(context: BrowserContext, page: Page) {
// return {aweme: { detail: {} } }; // return {aweme: { detail: {} } };
}).catch(() => null); }).catch(() => null);
// await new Promise((res) => setTimeout(res, 1000000));
let aweme_mem = md?.aweme?.detail as DouyinImageAweme; let aweme_mem = md?.aweme?.detail as DouyinImageAweme;
if (!aweme_mem) throw new Error('页面内存数据中未找到作品详情'); if (!aweme_mem) throw new Error('页面内存数据中未找到作品详情');
// @ts-ignore // @ts-ignore
aweme_mem.author = aweme_mem.authorInfo aweme_mem.author = aweme_mem.authorInfo
// @ts-ignore
aweme_mem.statistics = aweme_mem.stats
const comments = md.comment ? createCamelCompatibleProxy<DouyinCommentResponse>(md.comment) : null; const comments = md.comment ? createCamelCompatibleProxy<DouyinCommentResponse>(md.comment) : null;
const aweme = createCamelCompatibleProxy(aweme_mem); const aweme = createCamelCompatibleProxy(aweme_mem);

View File

@ -300,6 +300,7 @@ export default function AwemeDetailClient({ data, neighbors }: AwemeDetailClient
<NavigationButtons <NavigationButtons
neighbors={neighbors} neighbors={neighbors}
commentsCount={data.commentsCount} commentsCount={data.commentsCount}
likesCount={data.likesCount}
onNavigatePrev={() => neighbors.prev && router.push(`/aweme/${neighbors.prev.aweme_id}`)} onNavigatePrev={() => neighbors.prev && router.push(`/aweme/${neighbors.prev.aweme_id}`)}
onNavigateNext={() => neighbors.next && router.push(`/aweme/${neighbors.next.aweme_id}`)} onNavigateNext={() => neighbors.next && router.push(`/aweme/${neighbors.next.aweme_id}`)}
onToggleComments={() => commentState.setOpen((v) => !v)} onToggleComments={() => commentState.setOpen((v) => !v)}

View File

@ -21,7 +21,7 @@ export function ImageNavigationButtons({
{/* 左侧按钮 */} {/* 左侧按钮 */}
<button <button
className={` className={`
absolute left-4 top-7/16 -translate-y-1/2 z-20 absolute left-4 top-6/17 -translate-y-1/2 z-20
w-12 h-12 rounded-full w-12 h-12 rounded-full
bg-black/40 backdrop-blur-sm border border-white/20 bg-black/40 backdrop-blur-sm border border-white/20
flex items-center justify-center flex items-center justify-center
@ -38,7 +38,7 @@ export function ImageNavigationButtons({
{/* 右侧按钮 */} {/* 右侧按钮 */}
<button <button
className={` className={`
absolute right-4 top-7/16 -translate-y-1/2 z-20 absolute right-4 top-6/17 -translate-y-1/2 z-20
w-12 h-12 rounded-full w-12 h-12 rounded-full
bg-black/40 backdrop-blur-sm border border-white/20 bg-black/40 backdrop-blur-sm border border-white/20
flex items-center justify-center flex items-center justify-center

View File

@ -1,9 +1,10 @@
import { ChevronDown, ChevronUp, MessageSquareText } from "lucide-react"; import { ChevronDown, ChevronUp, MessageSquareText, ThumbsUp } from "lucide-react";
import type { Neighbors } from "../types"; import type { Neighbors } from "../types";
interface NavigationButtonsProps { interface NavigationButtonsProps {
neighbors: Neighbors; neighbors: Neighbors;
commentsCount: number; commentsCount: number;
likesCount: number;
onNavigatePrev: () => void; onNavigatePrev: () => void;
onNavigateNext: () => void; onNavigateNext: () => void;
onToggleComments: () => void; onToggleComments: () => void;
@ -12,30 +13,44 @@ interface NavigationButtonsProps {
export function NavigationButtons({ export function NavigationButtons({
neighbors, neighbors,
commentsCount, commentsCount,
likesCount,
onNavigatePrev, onNavigatePrev,
onNavigateNext, onNavigateNext,
onToggleComments, onToggleComments,
}: NavigationButtonsProps) { }: NavigationButtonsProps) {
return ( return (
<> <>
{/* 评论开关(右侧中部) */} <div className="absolute right-4 top-8/14 flex flex-col items-center gap-8 z-10">
<button <button
className="z-10 grid place-items-center w-[54px] h-[54px] rounded-full absolute right-4 top-2/3 -translate-y-1/2 cursor-pointer" className="grid place-items-center w-[54px] h-[54px] rounded-full -translate-y-1/2"
onClick={onToggleComments} >
aria-label="切换评论" <div className="grid place-items-center gap-1 drop-shadow-lg">
> <ThumbsUp size={40} className="" />
<div className="grid place-items-center gap-1 drop-shadow-lg">
<MessageSquareText size={40} className="" />
{commentsCount > 0 ? <span className="text-[18px] font-semibold text-white/90 drop-shadow">{commentsCount}</span> : <span className="text-[16px] font-semibold text-white/90 drop-shadow">{likesCount}</span>
<span className="text-[12px] font-semibold text-white/90 drop-shadow"></span>
}
</div> </div>
</button> </button>
{/* 评论开关(右侧中部) */}
<button
className="grid place-items-center w-[54px] h-[54px] rounded-full -translate-y-1/2 cursor-pointer"
onClick={onToggleComments}
aria-label="切换评论"
>
<div className="grid place-items-center gap-1 drop-shadow-lg">
<MessageSquareText size={40} className="" />
{commentsCount > 0 ? <span className="text-[16px] font-semibold text-white/90 drop-shadow">{commentsCount}</span> :
<span className="text-[12px] font-semibold text-white/90 drop-shadow"></span>
}
</div>
</button>
</div>
{/* 上下切换按钮(右侧胶囊形状) */} {/* 上下切换按钮(右侧胶囊形状) */}
<div className="absolute right-4 top-6/11 -translate-y-1/2 z-10"> <div className="absolute right-4 top-5/11 -translate-y-1/2 z-10">
<div className="flex flex-col rounded-full bg-black/40 backdrop-blur-sm border border-white/20 overflow-hidden"> <div className="flex flex-col rounded-full bg-black/40 backdrop-blur-sm border border-white/20 overflow-hidden">
<button <button
className="w-[44px] h-[44px] inline-flex items-center justify-center text-white disabled:opacity-40 cursor-pointer disabled:cursor-not-allowed hover:bg-white/10 transition-colors" className="w-[44px] h-[44px] inline-flex items-center justify-center text-white disabled:opacity-40 cursor-pointer disabled:cursor-not-allowed hover:bg-white/10 transition-colors"

View File

@ -77,6 +77,7 @@ export default async function AwemeDetail({ params }: { params: Promise<{ awemeI
height: video!.height ?? null, height: video!.height ?? null,
author: { nickname: video!.author.nickname, avatar_url: video!.author.avatar_url }, author: { nickname: video!.author.nickname, avatar_url: video!.author.avatar_url },
commentsCount, commentsCount,
likesCount: Number(video!.digg_count),
} }
: { : {
type: "image" as const, type: "image" as const,
@ -87,6 +88,7 @@ export default async function AwemeDetail({ params }: { params: Promise<{ awemeI
music_url: post!.music_url, music_url: post!.music_url,
author: { nickname: post!.author.nickname, avatar_url: post!.author.avatar_url }, author: { nickname: post!.author.nickname, avatar_url: post!.author.avatar_url },
commentsCount, commentsCount,
likesCount: Number(post!.digg_count),
}; };
// Compute prev/next neighbors by created_at across videos and image posts // Compute prev/next neighbors by created_at across videos and image posts

View File

@ -20,6 +20,7 @@ export type VideoData = {
height?: number | null; height?: number | null;
author: User; author: User;
commentsCount: number; commentsCount: number;
likesCount: number;
}; };
export type ImageData = { export type ImageData = {
@ -31,6 +32,7 @@ export type ImageData = {
music_url?: string | null; music_url?: string | null;
author: User; author: User;
commentsCount: number; commentsCount: number;
likesCount: number;
}; };
export type AwemeData = VideoData | ImageData; export type AwemeData = VideoData | ImageData;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -18,6 +18,9 @@ export const metadata: Metadata = {
template: "%s - 抖歪", template: "%s - 抖歪",
}, },
description: "记录当下时代的精彩瞬间", description: "记录当下时代的精彩瞬间",
icons: {
icon: "/favicon.png",
},
}; };
export default function RootLayout({ export default function RootLayout({

View File

@ -1,7 +1,7 @@
"use client"; "use client";
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { AlertTriangle, CheckCircle2, Clock, ExternalLink, Link2, Loader2, PlayCircle, Plus, Square, Trash2, X } from "lucide-react"; import { AlertTriangle, CheckCircle2, Clipboard, Clock, ExternalLink, Link2, Loader2, PlayCircle, Plus, Square, Trash2, X } from "lucide-react";
type TaskStatus = "pending" | "running" | "success" | "error"; type TaskStatus = "pending" | "running" | "success" | "error";
@ -74,6 +74,21 @@ export default function TasksPage() {
setInput(""); setInput("");
}, [input, addTasks]); }, [input, addTasks]);
const handlePasteAndAdd = useCallback(async () => {
try {
const text = await navigator.clipboard.readText();
const urls = extractDouyinLinks(text);
if (!urls.length) {
alert("剪贴板中未检测到 Douyin 短链,请复制包含 https://v.douyin.com/... 的文本");
return;
}
addTasks(urls);
} catch (err) {
alert("无法读取剪贴板内容,请检查浏览器权限设置");
console.error("Clipboard read error:", err);
}
}, [addTasks]);
const startTask = useCallback(async (task: Task) => { const startTask = useCallback(async (task: Task) => {
// 若已存在控制器,避免重复启动 // 若已存在控制器,避免重复启动
if (controllers.current.has(task.id)) return; if (controllers.current.has(task.id)) return;
@ -199,10 +214,13 @@ export default function TasksPage() {
</div> </div>
</div> </div>
</div> </div>
<div className="mt-4 flex items-center gap-3"> <div className="mt-4 flex flex-wrap items-center gap-3">
<button type="submit" className="inline-flex items-center gap-2 rounded-md bg-indigo-600/90 px-3 py-2 text-sm font-medium text-white transition-colors hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-indigo-400/40"> <button type="submit" className="inline-flex items-center gap-2 rounded-md bg-indigo-600/90 px-3 py-2 text-sm font-medium text-white transition-colors hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-indigo-400/40">
<Plus className="h-4 w-4" /> <Plus className="h-4 w-4" />
</button> </button>
<button type="button" onClick={handlePasteAndAdd} className="inline-flex items-center gap-2 rounded-md bg-emerald-600/90 px-3 py-2 text-sm font-medium text-white transition-colors hover:bg-emerald-600 focus:outline-none focus:ring-2 focus:ring-emerald-400/40">
<Clipboard className="h-4 w-4" />
</button>
<button type="button" onClick={clearFinished} className="inline-flex items-center gap-2 rounded-md bg-neutral-800 px-3 py-2 text-sm text-neutral-200 transition-colors hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-white/10"> <button type="button" onClick={clearFinished} className="inline-flex items-center gap-2 rounded-md bg-neutral-800 px-3 py-2 text-sm text-neutral-200 transition-colors hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-white/10">
<Trash2 className="h-4 w-4" /> <Trash2 className="h-4 w-4" />
</button> </button>

BIN
public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB