From c8895f407c29ec7a479aea0cf2005e73480b90b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E5=AE=87=E5=AE=81?= Date: Mon, 26 Oct 2026 19:51:53 +0700 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E4=BD=93UI=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/collect.svg | 3 - public/images/comment.svg | 3 - public/images/footer_sw.svg | 3 - public/images/footer_x.svg | 3 - public/images/history.svg | 3 - public/images/home.svg | 3 - public/images/icon_collect.svg | 3 - public/images/icon_like.svg | 3 - public/images/icon_share.svg | 3 - public/images/more_arrow.svg | 3 - public/images/my_dz.png | Bin 23811 -> 0 bytes public/images/my_sc.png | Bin 31730 -> 0 bytes public/images/my_sz.png | Bin 26931 -> 0 bytes public/images/nav_x.svg | 3 - public/images/playing.svg | 5 - public/images/profile.svg | 3 - public/images/screen.svg | 5 - public/images/share_h5.svg | 3 - public/images/tag_mf.png | Bin 6873 -> 0 bytes public/images/unscreen.svg | 5 - public/logo.png | Bin 6390 -> 0 bytes src/app/favorites/page.tsx | 12 - src/app/history/page.tsx | 12 - src/app/likes/page.tsx | 12 - src/app/profile/page.tsx | 12 - src/app/settings/page.tsx | 12 - src/app/settings/profile/page.tsx | 12 - .../{profile => auth}/use-mock-user.ts | 0 src/components/collection/collection-page.tsx | 212 ------------ .../common/comments/comment-panel.tsx | 284 ---------------- .../common/comments/comment-reply-preview.tsx | 35 -- src/components/common/comments/data.ts | 82 ----- .../common/comments/h5-comment-sheet.tsx | 204 ------------ .../common/comments/h5-comments-tab.tsx | 209 ------------ src/components/common/comments/heart-icon.tsx | 12 - src/components/common/comments/index.ts | 25 -- .../common/comments/inline-reply-box.tsx | 102 ------ .../common/comments/use-comments.ts | 315 ------------------ src/components/drama-detail/episodes.tsx | 306 ----------------- src/components/drama-detail/related-aside.tsx | 48 --- .../drama-play/play-episode-panel.tsx | 169 ---------- .../drama-play/use-report-playlet-history.ts | 49 --- src/components/favorites/data.ts | 46 --- src/components/favorites/favorites-page.tsx | 221 ------------ src/components/history/data.ts | 58 ---- src/components/history/history-page.tsx | 310 ----------------- src/components/layout/header-user-chip.tsx | 21 -- src/components/likes/likes-page.tsx | 220 ------------ .../{nav-email-card.tsx => nav-tg-card.tsx} | 0 src/components/profile/profile-h5.tsx | 235 ------------- src/components/profile/profile-hero.tsx | 68 ---- src/components/profile/profile-page.tsx | 69 ---- .../settings/change-password-dialog.tsx | 193 ----------- src/components/settings/edit-profile-page.tsx | 174 ---------- src/components/settings/settings-page.tsx | 110 ------ src/components/settings/use-mock-profile.ts | 53 --- src/components/video-play/related-aside.tsx | 46 --- .../video-play/use-report-video-history.ts | 46 --- src/lib/api/comment.ts | 56 ---- 59 files changed, 4104 deletions(-) delete mode 100644 public/images/collect.svg delete mode 100644 public/images/comment.svg delete mode 100644 public/images/footer_sw.svg delete mode 100644 public/images/footer_x.svg delete mode 100644 public/images/history.svg delete mode 100644 public/images/home.svg delete mode 100644 public/images/icon_collect.svg delete mode 100644 public/images/icon_like.svg delete mode 100644 public/images/icon_share.svg delete mode 100644 public/images/more_arrow.svg delete mode 100644 public/images/my_dz.png delete mode 100644 public/images/my_sc.png delete mode 100644 public/images/my_sz.png delete mode 100644 public/images/nav_x.svg delete mode 100644 public/images/playing.svg delete mode 100644 public/images/profile.svg delete mode 100644 public/images/screen.svg delete mode 100644 public/images/share_h5.svg delete mode 100644 public/images/tag_mf.png delete mode 100644 public/images/unscreen.svg delete mode 100644 public/logo.png delete mode 100644 src/app/favorites/page.tsx delete mode 100644 src/app/history/page.tsx delete mode 100644 src/app/likes/page.tsx delete mode 100644 src/app/profile/page.tsx delete mode 100644 src/app/settings/page.tsx delete mode 100644 src/app/settings/profile/page.tsx rename src/components/{profile => auth}/use-mock-user.ts (100%) delete mode 100644 src/components/collection/collection-page.tsx delete mode 100644 src/components/common/comments/comment-panel.tsx delete mode 100644 src/components/common/comments/comment-reply-preview.tsx delete mode 100644 src/components/common/comments/data.ts delete mode 100644 src/components/common/comments/h5-comment-sheet.tsx delete mode 100644 src/components/common/comments/h5-comments-tab.tsx delete mode 100644 src/components/common/comments/heart-icon.tsx delete mode 100644 src/components/common/comments/index.ts delete mode 100644 src/components/common/comments/inline-reply-box.tsx delete mode 100644 src/components/common/comments/use-comments.ts delete mode 100644 src/components/drama-detail/episodes.tsx delete mode 100644 src/components/drama-detail/related-aside.tsx delete mode 100644 src/components/drama-play/play-episode-panel.tsx delete mode 100644 src/components/drama-play/use-report-playlet-history.ts delete mode 100644 src/components/favorites/data.ts delete mode 100644 src/components/favorites/favorites-page.tsx delete mode 100644 src/components/history/data.ts delete mode 100644 src/components/history/history-page.tsx delete mode 100644 src/components/layout/header-user-chip.tsx delete mode 100644 src/components/likes/likes-page.tsx rename src/components/nav/{nav-email-card.tsx => nav-tg-card.tsx} (100%) delete mode 100644 src/components/profile/profile-h5.tsx delete mode 100644 src/components/profile/profile-hero.tsx delete mode 100644 src/components/profile/profile-page.tsx delete mode 100644 src/components/settings/change-password-dialog.tsx delete mode 100644 src/components/settings/edit-profile-page.tsx delete mode 100644 src/components/settings/settings-page.tsx delete mode 100644 src/components/settings/use-mock-profile.ts delete mode 100644 src/components/video-play/related-aside.tsx delete mode 100644 src/components/video-play/use-report-video-history.ts delete mode 100644 src/lib/api/comment.ts diff --git a/public/images/collect.svg b/public/images/collect.svg deleted file mode 100644 index 7f029d5..0000000 --- a/public/images/collect.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/comment.svg b/public/images/comment.svg deleted file mode 100644 index 2540879..0000000 --- a/public/images/comment.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/footer_sw.svg b/public/images/footer_sw.svg deleted file mode 100644 index 98dab2f..0000000 --- a/public/images/footer_sw.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/footer_x.svg b/public/images/footer_x.svg deleted file mode 100644 index eb12cfe..0000000 --- a/public/images/footer_x.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/history.svg b/public/images/history.svg deleted file mode 100644 index dce15df..0000000 --- a/public/images/history.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/home.svg b/public/images/home.svg deleted file mode 100644 index 4cd9253..0000000 --- a/public/images/home.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/icon_collect.svg b/public/images/icon_collect.svg deleted file mode 100644 index ca9a097..0000000 --- a/public/images/icon_collect.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/icon_like.svg b/public/images/icon_like.svg deleted file mode 100644 index 94ddf6a..0000000 --- a/public/images/icon_like.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/icon_share.svg b/public/images/icon_share.svg deleted file mode 100644 index edfdbec..0000000 --- a/public/images/icon_share.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/more_arrow.svg b/public/images/more_arrow.svg deleted file mode 100644 index f86c8ac..0000000 --- a/public/images/more_arrow.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/my_dz.png b/public/images/my_dz.png deleted file mode 100644 index 5a6356bd6183aa0d9ccc7ce3c3912c2255b24b97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23811 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 D-DP?( diff --git a/public/images/my_sc.png b/public/images/my_sc.png deleted file mode 100644 index d520ee57f28fb9d1e1654b693df20fb9c3d30c85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31730 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 F{tuGG@ACiv diff --git a/public/images/my_sz.png b/public/images/my_sz.png deleted file mode 100644 index 4d89befd58bba163a23d1ea902fe377793726938..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26931 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 V3G2wl!Z-i`002ovPDHLkV1it@0(Sra diff --git a/public/images/nav_x.svg b/public/images/nav_x.svg deleted file mode 100644 index 2f16bac..0000000 --- a/public/images/nav_x.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/playing.svg b/public/images/playing.svg deleted file mode 100644 index 40a1cc9..0000000 --- a/public/images/playing.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/images/profile.svg b/public/images/profile.svg deleted file mode 100644 index 57b8d01..0000000 --- a/public/images/profile.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/screen.svg b/public/images/screen.svg deleted file mode 100644 index 9f435ad..0000000 --- a/public/images/screen.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/images/share_h5.svg b/public/images/share_h5.svg deleted file mode 100644 index c0c903d..0000000 --- a/public/images/share_h5.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/public/images/tag_mf.png b/public/images/tag_mf.png deleted file mode 100644 index 331a8fb02135c01a74cfd7cad89ea65ab5c7ba26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6873 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 TAyy>N00000NkvXXu0mjfat|_A diff --git a/public/images/unscreen.svg b/public/images/unscreen.svg deleted file mode 100644 index 405c041..0000000 --- a/public/images/unscreen.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/logo.png b/public/logo.png deleted file mode 100644 index cbba7543a74e701a82955445f2274ee0bcdabb1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6390 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 -} diff --git a/src/app/history/page.tsx b/src/app/history/page.tsx deleted file mode 100644 index 3d3cb6a..0000000 --- a/src/app/history/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import type { Metadata } from "next"; - -import { HistoryPage } from "@/components/history/history-page"; - -export const metadata: Metadata = { - title: "观看历史 - 海角社区", - robots: { index: false, follow: false }, -}; - -export default function Page() { - return ; -} diff --git a/src/app/likes/page.tsx b/src/app/likes/page.tsx deleted file mode 100644 index e8a7ff2..0000000 --- a/src/app/likes/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import type { Metadata } from "next"; - -import { LikesPage } from "@/components/likes/likes-page"; - -export const metadata: Metadata = { - title: "我的点赞 - 海角社区", - robots: { index: false, follow: false }, -}; - -export default function Page() { - return ; -} diff --git a/src/app/profile/page.tsx b/src/app/profile/page.tsx deleted file mode 100644 index 3d9a5e9..0000000 --- a/src/app/profile/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import type { Metadata } from "next"; - -import { ProfilePage } from "@/components/profile/profile-page"; - -export const metadata: Metadata = { - title: "个人中心 - 海角社区", - robots: { index: false, follow: false }, -}; - -export default function Page() { - return ; -} diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx deleted file mode 100644 index 1d3c33a..0000000 --- a/src/app/settings/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import type { Metadata } from "next"; - -import { SettingsPage } from "@/components/settings/settings-page"; - -export const metadata: Metadata = { - title: "账号设置 - 海角社区", - robots: { index: false, follow: false }, -}; - -export default function Page() { - return ; -} diff --git a/src/app/settings/profile/page.tsx b/src/app/settings/profile/page.tsx deleted file mode 100644 index fb64563..0000000 --- a/src/app/settings/profile/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import type { Metadata } from "next"; - -import { EditProfilePage } from "@/components/settings/edit-profile-page"; - -export const metadata: Metadata = { - title: "编辑个人资料 - 海角社区", - robots: { index: false, follow: false }, -}; - -export default function Page() { - return ; -} diff --git a/src/components/profile/use-mock-user.ts b/src/components/auth/use-mock-user.ts similarity index 100% rename from src/components/profile/use-mock-user.ts rename to src/components/auth/use-mock-user.ts diff --git a/src/components/collection/collection-page.tsx b/src/components/collection/collection-page.tsx deleted file mode 100644 index 6fc7c16..0000000 --- a/src/components/collection/collection-page.tsx +++ /dev/null @@ -1,212 +0,0 @@ -"use client"; - -import { useRouter } from "next/navigation"; -import { useRef, useState } from "react"; - -import { EmptyState } from "@/components/common/empty-state"; -import { Pagination } from "@/components/common/pagination"; -import { SeoBreadcrumb } from "@/components/seo/seo-breadcrumb"; -import type { ShortDramaItem } from "@/components/short-drama/data"; -import { H5ShortDramaCard, ShortDramaCard } from "@/components/short-drama/short-drama-card"; -import { H5VideoCard, VideoCard } from "@/components/video/video-card"; - -type CollectionPageProps = { - title: string; - subtitle: string; - breadcrumb: string; - types: readonly T[]; - mobileTypes?: readonly T[]; - scopes: readonly S[]; - defaultScope: S; - totalPages: number; - getItems: (type: T, scope: S, page: number) => ShortDramaItem[]; - clearable?: boolean; - showMobileScopes?: boolean; - showPcScopes?: boolean; - showVideoScopes?: boolean; - showMobileEpisodes?: boolean; - emptyText: string; -}; - -type FilterPillsProps = { - options: readonly T[]; - value: T; - onChange: (value: T) => void; - className?: string; - itemClassName: string; -}; - -function FilterPills({ options, value, onChange, className = "", itemClassName }: FilterPillsProps) { - return ( -
- {options.map((option) => ( - - ))} -
- ); -} - -export function CollectionPage({ - title, - subtitle, - breadcrumb, - types, - mobileTypes = types, - scopes, - defaultScope, - totalPages, - getItems, - clearable = false, - showMobileScopes = true, - showPcScopes = true, - showVideoScopes = true, - showMobileEpisodes = true, - emptyText, -}: CollectionPageProps) { - const router = useRouter(); - const [type, setType] = useState(types[0]); - const [scope, setScope] = useState(defaultScope); - const [page, setPage] = useState(1); - const [cleared, setCleared] = useState(false); - const topRef = useRef(null); - const items = cleared ? [] : getItems(type, scope, page); - const isVideo = type === "视频"; - const PcCard = isVideo ? VideoCard : ShortDramaCard; - const MobileCard = isVideo ? H5VideoCard : H5ShortDramaCard; - - const changeType = (next: T) => { - setType(next); - setPage(1); - }; - const changeScope = (next: S) => { - setScope(next); - setPage(1); - }; - const changePage = (next: number) => { - setPage(next); - topRef.current?.scrollIntoView({ behavior: "smooth" }); - }; - const goBack = () => { - if (window.history.length > 1) router.back(); - else router.push("/profile"); - }; - - return ( -
-
- -

{title}

- {clearable ? ( - - ) : null} -
- -
- - -
-
-

{title}

-

{subtitle}

-
- {clearable ? ( - - ) : null} -
- -
- - - {isVideo && !showVideoScopes ? null : ( - - )} -
- - {items.length === 0 ? ( - - ) : ( - <> -
- {items.map((item) => ( - - ))} -
- -
- {items.map((item) => ( - - ))} -
- - - - )} -
-
- ); -} diff --git a/src/components/common/comments/comment-panel.tsx b/src/components/common/comments/comment-panel.tsx deleted file mode 100644 index 7cb76f3..0000000 --- a/src/components/common/comments/comment-panel.tsx +++ /dev/null @@ -1,284 +0,0 @@ -"use client"; - -import { useState, type FormEvent } from "react"; - -import { DecryptedImage } from "@/components/common/decrypted-image"; -import { useMockUser } from "@/components/profile/use-mock-user"; -import type { CommentInfo } from "@/lib/api/types"; - -import { COMMENT_MAX_LENGTH, COMMENT_SELF_NAME, COMMENT_SORTS, formatCommentTime, type CommentTarget } from "./data"; -import { CommentReplyPreview } from "./comment-reply-preview"; -import { HeartIcon } from "./heart-icon"; -import { InlineReplyBox } from "./inline-reply-box"; -import { useComments } from "./use-comments"; - -const fallbackAvatar = "/images/default_avatar.svg"; - -const panelStyles = { - detail: { - section: "rounded-2xl bg-[rgba(24,23,46,0.88)] outline-[#383657]", - item: "py-4", - more: "mt-4 h-[43px] rounded-[7px]", - }, - play: { - section: "rounded-xl bg-[rgba(19,15,22,0.91)] outline-[rgba(199,145,89,0.7)]", - item: "py-3", - more: "mt-3 h-8 rounded-lg", - }, -}; - -type ReplyTarget = { - id: number; - userName: string; -}; - -function CommentComposer({ - onSubmit, - posting, - error, -}: { - onSubmit: (content: string) => Promise; - posting: boolean; - error: string | null; -}) { - const { user } = useMockUser(); - const avatar = user?.avatar || fallbackAvatar; - const displayName = user?.name || COMMENT_SELF_NAME; - const [text, setText] = useState(""); - - const submit = async (event: FormEvent) => { - event.preventDefault(); - const content = text.trim(); - if (!content || posting) return; - const ok = await onSubmit(content); - if (ok) setText(""); - }; - - return ( -
-
- - - - - {error && !posting ?

{error}

: null} -
- ); -} - -/** PC 评论面板(详情 / 播放页)— GET /api/app/comment/list */ -export function CommentPanel({ - variant = "detail", - target, -}: { - variant?: keyof typeof panelStyles; - target: CommentTarget | null; -}) { - const { - sort, - setSort, - comments, - total, - hasMore, - loading, - loadingMore, - error, - loadMore, - toggleLike, - post, - posting, - postError, - reload, - } = useComments({ target }); - const styles = panelStyles[variant]; - const [replyTo, setReplyTo] = useState(null); - const [expandedIds, setExpandedIds] = useState>(() => new Set()); - - const startReply = (comment: CommentInfo) => { - const id = Number(comment.id); - if (!Number.isInteger(id) || id < 1) return; - setReplyTo({ id, userName: (comment.userName || "").trim() || "用户" }); - }; - - const toggleExpanded = (commentId: number) => { - setExpandedIds((current) => { - const next = new Set(current); - if (next.has(commentId)) next.delete(commentId); - else next.add(commentId); - return next; - }); - }; - - const submitRoot = async (content: string) => post(content); - - const submitReply = async (content: string) => { - if (!replyTo) return false; - const ok = await post(content, { parentsId: replyTo.id }); - if (ok) setReplyTo(null); - return ok; - }; - - return ( -
-
-

评论 ({total})

-
- {COMMENT_SORTS.map((item) => ( - - ))} -
-
- - - - {loading ? ( -

评论加载中…

- ) : error ? ( -
-

{error}

- -
- ) : comments.length === 0 ? ( -

暂无评论

- ) : ( -
    - {comments.map((comment) => { - const liked = Boolean(comment.isLike); - const commentId = Number(comment.id) || 0; - const expanded = expandedIds.has(commentId); - const replies = comment.subComment ?? []; - const isReplying = replyTo?.id === commentId; - return ( -
  • - -
    -

    {comment.userName}

    -

    {comment.text}

    -
    - {formatCommentTime(comment.createdAt)} - - -
    - {isReplying && replyTo ? ( - setReplyTo(null)} - /> - ) : null} - {expanded && replies.length > 1 ? ( -
    - {replies.map((reply) => ( -

    - {reply.replyUserName - ? `${reply.userName || ""} 回复 ${reply.replyUserName}:${reply.text || ""}` - : `${reply.userName || ""}:${reply.text || ""}`} -

    - ))} - -
    - ) : ( - 1 ? () => toggleExpanded(commentId) : undefined} - /> - )} -
    -
  • - ); - })} -
- )} - - {!loading && !error && comments.length > 0 ? ( - - ) : null} -
- ); -} diff --git a/src/components/common/comments/comment-reply-preview.tsx b/src/components/common/comments/comment-reply-preview.tsx deleted file mode 100644 index 84934f5..0000000 --- a/src/components/common/comments/comment-reply-preview.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import type { CommentInfo } from "@/lib/api/types"; - -/** 直接展示接口 subComment / commentCount,不做字段改名 */ -export function CommentReplyPreview({ - comment, - className = "", - textClassName = "", - onMore, -}: { - comment: CommentInfo; - className?: string; - textClassName?: string; - onMore?: () => void; -}) { - const first = comment.subComment?.[0]; - const more = Number(comment.commentCount) || comment.subComment?.length || 0; - if (!first && more < 1) return null; - - const replyLabel = first - ? first.replyUserName - ? `${first.userName || ""} 回复 ${first.replyUserName}:${first.text || ""}` - : `${first.userName || ""}:${first.text || ""}` - : `共 ${more} 条回复`; - - return ( -
-

{replyLabel}

- {more > 0 && onMore ? ( - - ) : null} -
- ); -} diff --git a/src/components/common/comments/data.ts b/src/components/common/comments/data.ts deleted file mode 100644 index ce79ffd..0000000 --- a/src/components/common/comments/data.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { COMMENT_OBJECT_TYPE, type CommentInfo, type CommentObjectType } from "@/lib/api/types"; - -export type { CommentInfo }; - -export type CommentTarget = { - objectId: number; - objectType: CommentObjectType; -}; - -export const COMMENT_SORTS = ["热门", "最新"] as const; -export type CommentSort = (typeof COMMENT_SORTS)[number]; - -export const COMMENT_SELF_NAME = "剧迷1024"; -export const COMMENT_MAX_LENGTH = 200; -export const COMMENT_PAGE_SIZE = 6; -/** 列表请求超时,避免上游卡住拖住 UI */ -export const COMMENT_FETCH_TIMEOUT_MS = 8000; - -export function sortToOrder(sort: CommentSort): 1 | 2 { - return sort === "热门" ? 1 : 2; -} - -/** 过滤无效评论,保留接口原字段 */ -export function filterCommentList(list: CommentInfo[] | null | undefined): CommentInfo[] { - return (list ?? []).filter((item) => { - const id = Number(item?.id); - return Number.isInteger(id) && id > 0; - }); -} - -/** 本地乐观插入用,字段名与 CommentInfo 一致 */ -export function createSelfComment( - text: string, - options?: { userName?: string; avatar?: string }, -): CommentInfo { - return { - id: -Date.now(), - userName: (options?.userName || "").trim() || COMMENT_SELF_NAME, - avatar: (options?.avatar || "").trim() || "/images/default_avatar.svg", - text, - createdAt: new Date().toISOString(), - countLike: 0, - isLike: false, - commentCount: 0, - subComment: [], - }; -} - -export function formatCommentCount(value: number) { - return value >= 10000 ? `${(value / 10000).toFixed(1)}w` : String(value); -} - -/** 仅做展示格式化,不改字段名;空则回退原串 */ -export function formatCommentTime(value?: string | null) { - const raw = (value || "").trim(); - if (!raw) return ""; - const date = new Date(raw); - if (Number.isNaN(date.getTime())) return raw; - const pad = (n: number) => String(n).padStart(2, "0"); - return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()} ${pad(date.getHours())}:${pad(date.getMinutes())}`; -} - -export function commentTarget( - objectId: number | string | null | undefined, - objectType: CommentObjectType, -): CommentTarget | null { - const id = Number(objectId); - if (!Number.isInteger(id) || id < 1) return null; - return { objectId: id, objectType }; -} - -export function playletCommentTarget(playletId: number | string | null | undefined) { - return commentTarget(playletId, COMMENT_OBJECT_TYPE.playlet); -} - -export function playletChapterCommentTarget(chapterId: number | string | null | undefined) { - return commentTarget(chapterId, COMMENT_OBJECT_TYPE.playletChapter); -} - -export function videoCommentTarget(videoId: number | string | null | undefined) { - return commentTarget(videoId, COMMENT_OBJECT_TYPE.video); -} diff --git a/src/components/common/comments/h5-comment-sheet.tsx b/src/components/common/comments/h5-comment-sheet.tsx deleted file mode 100644 index a5379d8..0000000 --- a/src/components/common/comments/h5-comment-sheet.tsx +++ /dev/null @@ -1,204 +0,0 @@ -"use client"; - -import { useState, type FormEvent, type ReactNode } from "react"; - -import { DecryptedImage } from "@/components/common/decrypted-image"; - -import { COMMENT_MAX_LENGTH, COMMENT_SORTS, formatCommentTime, type CommentTarget } from "./data"; -import { CommentReplyPreview } from "./comment-reply-preview"; -import { HeartIcon } from "./heart-icon"; -import { InlineReplyBox } from "./inline-reply-box"; -import { useComments } from "./use-comments"; - -function SheetHead({ title, onClose, children }: { title: ReactNode; onClose: () => void; children?: ReactNode }) { - return ( -
- -

{title}

- {children ?? } -
- ); -} - -/** H5 短剧播放页评论底部弹层 */ -export function H5CommentSheet({ onClose, target }: { onClose: () => void; target: CommentTarget | null }) { - const { - sort, - setSort, - comments, - total, - hasMore, - loading, - loadingMore, - error, - loadMore, - toggleLike, - post, - posting, - postError, - reload, - } = useComments({ target }); - const [text, setText] = useState(""); - const [replyTo, setReplyTo] = useState<{ id: number; userName: string } | null>(null); - - const submit = async (event: FormEvent) => { - event.preventDefault(); - const content = text.trim(); - if (!content || posting || replyTo) return; - const ok = await post(content); - if (ok) setText(""); - }; - - const submitReply = async (content: string) => { - if (!replyTo) return false; - const ok = await post(content, { parentsId: replyTo.id }); - if (ok) setReplyTo(null); - return ok; - }; - - return ( -
-
- -
- {COMMENT_SORTS.map((item) => ( - - ))} -
-
-
-
- {loading ? ( -

评论加载中…

- ) : error ? ( -
-

{error}

- -
- ) : comments.length === 0 ? ( -

暂无评论

- ) : ( -
    - {comments.map((comment) => { - const liked = Boolean(comment.isLike); - const commentId = Number(comment.id) || 0; - const isReplying = replyTo?.id === commentId; - return ( -
  • - -
    -

    {comment.userName}

    -

    {comment.text}

    -
    - {formatCommentTime(comment.createdAt)} - - -
    - {isReplying && replyTo ? ( - setReplyTo(null)} - /> - ) : null} - -
    -
  • - ); - })} -
- )} - {!loading && !error && comments.length > 0 ? ( - - ) : null} -
-
- {!replyTo && postError ?

{postError}

: null} -
- setText(event.target.value)} - placeholder="发表评论…" - aria-label="评论内容" - className="h-9 min-w-0 flex-1 rounded-full bg-white/5 px-4 text-sm text-white outline-none placeholder:text-white/35 disabled:opacity-60" - /> - -
-
-
- ); -} diff --git a/src/components/common/comments/h5-comments-tab.tsx b/src/components/common/comments/h5-comments-tab.tsx deleted file mode 100644 index 374061e..0000000 --- a/src/components/common/comments/h5-comments-tab.tsx +++ /dev/null @@ -1,209 +0,0 @@ -"use client"; - -import { useState, type FormEvent, type ReactNode } from "react"; - -import { DecryptedImage } from "@/components/common/decrypted-image"; - -import { COMMENT_MAX_LENGTH, COMMENT_SORTS, formatCommentCount, formatCommentTime } from "./data"; -import { CommentReplyPreview } from "./comment-reply-preview"; -import { InlineReplyBox } from "./inline-reply-box"; -import type { UseCommentsResult } from "./use-comments"; - -type H5CommentsTabProps = { - /** 由页面 useComments 托管,便于 Tab 标题同步总数 */ - state: UseCommentsResult; - footerExtra?: ReactNode; -}; - -/** H5 视频播放页「评论」Tab */ -export function H5CommentsTab({ state, footerExtra }: H5CommentsTabProps) { - const { - sort, - setSort, - comments, - total, - hasMore, - loading, - loadingMore, - error, - loadMore, - toggleLike, - post, - posting, - postError, - reload, - } = state; - const [text, setText] = useState(""); - const [replyTo, setReplyTo] = useState<{ id: number; userName: string } | null>(null); - - const submit = async (event: FormEvent) => { - event.preventDefault(); - const content = text.trim(); - if (!content || posting || replyTo) return; - const ok = await post(content); - if (ok) setText(""); - }; - - const submitReply = async (content: string) => { - if (!replyTo) return false; - const ok = await post(content, { parentsId: replyTo.id }); - if (ok) setReplyTo(null); - return ok; - }; - - return ( -
-
-
-

{total}条评论

-
- {COMMENT_SORTS.map((item) => ( - - ))} -
-
- - {loading ? ( -

评论加载中…

- ) : error ? ( -
-

{error}

- -
- ) : comments.length === 0 ? ( -

暂无评论

- ) : ( -
    - {comments.map((comment) => { - const liked = Boolean(comment.isLike); - const commentId = Number(comment.id) || 0; - const isReplying = replyTo?.id === commentId; - return ( -
  • - -
    -

    {comment.userName}

    -

    {comment.text}

    -
    -
    - {formatCommentTime(comment.createdAt)} - -
    - -
    - {isReplying && replyTo ? ( - setReplyTo(null)} - /> - ) : null} - -
    -
  • - ); - })} -
- )} - - {!loading && !error && comments.length > 0 ? ( - - ) : null} -
-
- {!replyTo && postError ?

{postError}

: null} -
- -
-
- {footerExtra} -
- ); -} diff --git a/src/components/common/comments/heart-icon.tsx b/src/components/common/comments/heart-icon.tsx deleted file mode 100644 index ae77c6d..0000000 --- a/src/components/common/comments/heart-icon.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export function HeartIcon({ filled, className = "size-[18px]" }: { filled: boolean; className?: string }) { - return ( - - ); -} diff --git a/src/components/common/comments/index.ts b/src/components/common/comments/index.ts deleted file mode 100644 index 54c8887..0000000 --- a/src/components/common/comments/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -export { - COMMENT_FETCH_TIMEOUT_MS, - COMMENT_MAX_LENGTH, - COMMENT_PAGE_SIZE, - COMMENT_SELF_NAME, - COMMENT_SORTS, - commentTarget, - createSelfComment, - filterCommentList, - formatCommentCount, - formatCommentTime, - playletChapterCommentTarget, - playletCommentTarget, - sortToOrder, - videoCommentTarget, - type CommentSort, - type CommentTarget, -} from "./data"; -export { CommentPanel } from "./comment-panel"; -export { CommentReplyPreview } from "./comment-reply-preview"; -export { H5CommentSheet } from "./h5-comment-sheet"; -export { H5CommentsTab } from "./h5-comments-tab"; -export { HeartIcon } from "./heart-icon"; -export { useComments, type UseCommentsOptions, type UseCommentsResult } from "./use-comments"; -export type { CommentInfo } from "@/lib/api/types"; diff --git a/src/components/common/comments/inline-reply-box.tsx b/src/components/common/comments/inline-reply-box.tsx deleted file mode 100644 index 1771089..0000000 --- a/src/components/common/comments/inline-reply-box.tsx +++ /dev/null @@ -1,102 +0,0 @@ -"use client"; - -import { useEffect, useRef, useState, type FormEvent } from "react"; - -import { COMMENT_MAX_LENGTH } from "./data"; - -/** 挂在单条评论下方的回复输入框 */ -export function InlineReplyBox({ - userName, - posting, - error, - onSubmit, - onCancel, - compact = false, -}: { - userName: string; - posting: boolean; - error?: string | null; - onSubmit: (content: string) => Promise; - onCancel: () => void; - compact?: boolean; -}) { - const [text, setText] = useState(""); - const inputRef = useRef(null); - - useEffect(() => { - inputRef.current?.focus(); - }, []); - - const submit = async (event: FormEvent) => { - event.preventDefault(); - const content = text.trim(); - if (!content || posting) return; - const ok = await onSubmit(content); - if (ok) setText(""); - }; - - return ( -
-
- - 回复 @{userName} - - -
-
- - -
- {error ?

{error}

: null} -
- ); -} diff --git a/src/components/common/comments/use-comments.ts b/src/components/common/comments/use-comments.ts deleted file mode 100644 index f4c6fa9..0000000 --- a/src/components/common/comments/use-comments.ts +++ /dev/null @@ -1,315 +0,0 @@ -"use client"; - -import { useCallback, useEffect, useRef, useState } from "react"; -import { toast } from "@heroui/react"; - -import { openLoginDialog } from "@/components/auth/login-dialog"; -import { getCommentList, sendComment, setCommentLike } from "@/lib/api/comment"; -import type { CommentInfo } from "@/lib/api/types"; -import { handleUnauthorized } from "@/lib/auth/handle-unauthorized"; -import { ensureGuestSession, getAuthToken } from "@/lib/auth/session"; - -import { - COMMENT_FETCH_TIMEOUT_MS, - COMMENT_PAGE_SIZE, - filterCommentList, - sortToOrder, - type CommentSort, - type CommentTarget, -} from "./data"; - -export type UseCommentsOptions = { - target: CommentTarget | null; - initialSort?: CommentSort; - pageSize?: number; -}; - -export type UseCommentsResult = { - sort: CommentSort; - setSort: (sort: CommentSort) => void; - comments: CommentInfo[]; - total: number; - hasMore: boolean; - loading: boolean; - loadingMore: boolean; - posting: boolean; - error: string | null; - postError: string | null; - loadMore: () => void; - toggleLike: (comment: CommentInfo) => Promise; - post: (text: string, options?: { parentsId?: number }) => Promise; - reload: () => void; -}; - -function formatCommentError(err: unknown, fallback = "评论加载失败") { - if (err instanceof DOMException && err.name === "TimeoutError") return "加载超时,请重试"; - if (err instanceof Error) { - if (/aborted|timeout|超时/i.test(err.message) || err.name === "AbortError") return "加载超时,请重试"; - return err.message || fallback; - } - return fallback; -} - -function abortAfter(ms: number) { - if (typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function") { - return AbortSignal.timeout(ms); - } - const controller = new AbortController(); - setTimeout(() => controller.abort(), ms); - return controller.signal; -} - -function mergeSignals(a: AbortSignal, b: AbortSignal) { - if (typeof AbortSignal !== "undefined" && typeof AbortSignal.any === "function") { - return AbortSignal.any([a, b]); - } - const controller = new AbortController(); - const onAbort = () => controller.abort(); - if (a.aborted || b.aborted) { - controller.abort(); - return controller.signal; - } - a.addEventListener("abort", onAbort, { once: true }); - b.addEventListener("abort", onAbort, { once: true }); - return controller.signal; -} - -async function resolveAuthToken() { - let token = getAuthToken(); - if (!token) { - try { - await ensureGuestSession(); - } catch { - /* ignore */ - } - token = getAuthToken(); - } - return token; -} - -function patchComment(list: CommentInfo[], id: number, patch: Partial): CommentInfo[] { - return list.map((item) => (Number(item.id) === id ? { ...item, ...patch } : item)); -} - -export function useComments({ - target, - initialSort = "热门", - pageSize = COMMENT_PAGE_SIZE, -}: UseCommentsOptions): UseCommentsResult { - const [sort, setSort] = useState(initialSort); - const [comments, setComments] = useState([]); - const [total, setTotal] = useState(0); - const [pageNum, setPageNum] = useState(1); - const [loading, setLoading] = useState(Boolean(target)); - const [loadingMore, setLoadingMore] = useState(false); - const [posting, setPosting] = useState(false); - const [error, setError] = useState(null); - const [postError, setPostError] = useState(null); - const [reloadKey, setReloadKey] = useState(0); - const fetchSeq = useRef(0); - const likingIds = useRef(new Set()); - - const objectId = target?.objectId ?? 0; - const objectType = target?.objectType; - const enabled = Boolean(target && objectId > 0 && objectType != null); - - useEffect(() => { - const controller = new AbortController(); - let cancelled = false; - - void (async () => { - await Promise.resolve(); - if (cancelled) return; - - if (!enabled || objectType == null) { - setComments([]); - setTotal(0); - setLoading(false); - setError(null); - return; - } - - const seq = ++fetchSeq.current; - setLoading(true); - setError(null); - setPageNum(1); - likingIds.current.clear(); - - try { - const data = await getCommentList( - { - objectId, - objectType, - pageNum: 1, - pageSize, - sortOrder: sortToOrder(sort), - }, - { - token: getAuthToken(), - signal: mergeSignals(controller.signal, abortAfter(COMMENT_FETCH_TIMEOUT_MS)), - }, - ); - if (cancelled || seq !== fetchSeq.current) return; - setComments(filterCommentList(data?.list)); - setTotal(Number(data?.totalCount) || 0); - setPageNum(1); - } catch (err: unknown) { - if (cancelled || seq !== fetchSeq.current || controller.signal.aborted) return; - setComments([]); - setTotal(0); - setError(formatCommentError(err)); - } finally { - if (!cancelled && seq === fetchSeq.current) setLoading(false); - } - })(); - - return () => { - cancelled = true; - controller.abort(); - }; - }, [enabled, objectId, objectType, sort, pageSize, reloadKey]); - - const hasMore = comments.length < total; - - const loadMore = useCallback(() => { - if (!enabled || objectType == null || loading || loadingMore || !hasMore) return; - - const nextPage = pageNum + 1; - const controller = new AbortController(); - setLoadingMore(true); - - void getCommentList( - { - objectId, - objectType, - pageNum: nextPage, - pageSize, - sortOrder: sortToOrder(sort), - }, - { - token: getAuthToken(), - signal: mergeSignals(controller.signal, abortAfter(COMMENT_FETCH_TIMEOUT_MS)), - }, - ) - .then((data) => { - const mapped = filterCommentList(data?.list); - setComments((current) => { - const seen = new Set(current.map((item) => Number(item.id))); - return [...current, ...mapped.filter((item) => !seen.has(Number(item.id)))]; - }); - setTotal(Number(data?.totalCount) || total); - setPageNum(nextPage); - }) - .catch((err: unknown) => { - if (controller.signal.aborted) return; - setError(formatCommentError(err, "加载更多失败")); - }) - .finally(() => setLoadingMore(false)); - }, [enabled, objectId, objectType, loading, loadingMore, hasMore, pageNum, pageSize, sort, total]); - - const toggleLike = useCallback(async (comment: CommentInfo) => { - const commentId = Number(comment.id); - if (!Number.isInteger(commentId) || commentId < 1) return; - if (likingIds.current.has(commentId)) return; - - const token = await resolveAuthToken(); - if (!token) { - openLoginDialog(); - return; - } - - const nextIsLike = !Boolean(comment.isLike); - const nextCountLike = Math.max(0, (Number(comment.countLike) || 0) + (nextIsLike ? 1 : -1)); - const snapshot = { isLike: comment.isLike, countLike: comment.countLike }; - - likingIds.current.add(commentId); - setComments((current) => patchComment(current, commentId, { isLike: nextIsLike, countLike: nextCountLike })); - - try { - const result = await setCommentLike( - { commentId, isLike: nextIsLike }, - token, - abortAfter(COMMENT_FETCH_TIMEOUT_MS), - ); - setComments((current) => - patchComment(current, commentId, { - isLike: result?.isLike ?? nextIsLike, - countLike: typeof result?.countLike === "number" ? result.countLike : nextCountLike, - }), - ); - } catch (err: unknown) { - setComments((current) => patchComment(current, commentId, snapshot)); - handleUnauthorized(err); - } finally { - likingIds.current.delete(commentId); - } - }, []); - - const post = useCallback( - async (text: string, options?: { parentsId?: number }) => { - const trimmed = text.trim(); - if (!trimmed || posting) return false; - if (!enabled || objectType == null) { - setPostError("无法发布评论"); - return false; - } - - setPostError(null); - const token = await resolveAuthToken(); - if (!token) { - openLoginDialog(); - return false; - } - - setPosting(true); - - try { - await sendComment( - { - objectId, - objectType, - text: trimmed, - parentsId: options?.parentsId ?? 0, - }, - token, - abortAfter(COMMENT_FETCH_TIMEOUT_MS), - ); - - // 审核通过前不写入列表(对齐 1045) - toast.success("发布成功,评论审核后才会展示"); - return true; - } catch (err: unknown) { - if (handleUnauthorized(err)) { - setPostError("登录已过期或没有权限,请重新登录"); - return false; - } - const message = formatCommentError(err, "发表失败,请稍后重试"); - setPostError(message); - toast.danger(message); - return false; - } finally { - setPosting(false); - } - }, - [enabled, objectId, objectType, posting], - ); - - const reload = useCallback(() => setReloadKey((value) => value + 1), []); - - return { - sort, - setSort, - comments, - total, - hasMore, - loading, - loadingMore, - posting, - error, - postError, - loadMore, - toggleLike, - post, - reload, - }; -} diff --git a/src/components/drama-detail/episodes.tsx b/src/components/drama-detail/episodes.tsx deleted file mode 100644 index fb8000f..0000000 --- a/src/components/drama-detail/episodes.tsx +++ /dev/null @@ -1,306 +0,0 @@ -"use client"; - -import Link from "next/link"; -import { useState } from "react"; - -import { DecryptedImage } from "@/components/common/decrypted-image"; -import { CornerFlagBadge, resolveContentBadge } from "@/components/home/section-heading"; -import { dramaHref } from "@/components/short-drama/data"; - -import { - getEpisodeChunks, - getEpisodeRanges, - getEpisodeState, - totalEpisodeOf, - updateStatusLabel, - type DramaDetail, - type RelatedDrama, -} from "./data"; - -type EpisodeProps = { - detail: DramaDetail; - current: number; - onSelect: (episode: number) => void; -}; - -function LockIcon({ className = "" }: { className?: string }) { - return ( - - ); -} - -/** 免费/未解锁均进播放页;未解锁由播放页在播放器上盖下载遮罩 */ -function useEpisodeClick(_detail: DramaDetail, onSelect: (episode: number) => void) { - return (episode: number) => onSelect(episode); -} - -/** 与播放页「更多好剧」一致的三列推荐卡片 */ -export function MorePlayletsGrid({ items }: { items: RelatedDrama[] }) { - if (!items.length) { - return

暂无更多推荐

; - } - - return ( -
- {items.map((item) => { - const badge = resolveContentBadge(item); - return ( - -
- - -
- {item.title} - - {item.tagNames?.[0]} - {item.tagNames?.[0] && item.totalEpisode ? " · " : ""} - {item.totalEpisode ? `${item.totalEpisode}集` : ""} - - - ); - })} -
- ); -} - -export function EpisodePanel({ detail, current, onSelect }: EpisodeProps) { - const totalEpisode = totalEpisodeOf(detail); - const ranges = getEpisodeRanges(totalEpisode, 20); - const [rangeIndex, setRangeIndex] = useState(-1); - const range = ranges[rangeIndex]; - const start = range?.start ?? 1; - const end = range?.end ?? totalEpisode; - const handleClick = useEpisodeClick(detail, onSelect); - - return ( -
-
-

选集

-

共 {totalEpisode} 集

-
- {[{ label: "全部", index: -1 }, ...ranges.map((item, index) => ({ label: item.label, index }))].map( - (item) => ( - - ), - )} -
-
-
- {Array.from({ length: end - start + 1 }, (_, index) => start + index).map((episode) => { - const locked = getEpisodeState(episode, detail) === "locked"; - const playing = episode === current; - return ( - - ); - })} -
-
- ); -} - -export function H5EpisodeStrip({ detail, onSelect, current }: Omit & { current?: number }) { - const totalEpisode = totalEpisodeOf(detail); - const ranges = getEpisodeChunks(totalEpisode, 30); - const [rangeIndex, setRangeIndex] = useState(0); - const { start, end } = ranges[rangeIndex] ?? ranges[0]; - const handleClick = useEpisodeClick(detail, onSelect); - const hasPreview = Boolean(detail.preview?.trim()); - const previewChapter = detail.chapterList?.find( - (item) => item.title?.trim() === "预告" || Number(item.currentEpisode) === 0, - ); - const showPreview = hasPreview || Boolean(previewChapter); - - return ( -
-
-

剧集

-
- - {updateStatusLabel(detail.updateStatus)} 共{totalEpisode}集 - - -
-
- -
- {ranges.map((item, index) => ( - - ))} - - 更多好剧 - -
- -
- {showPreview && rangeIndex === 0 ? ( - - ) : null} - - {Array.from({ length: end - start + 1 }, (_, index) => start + index).map((episode) => { - const locked = getEpisodeState(episode, detail) === "locked"; - const playing = current != null && episode === current; - - if (playing) { - return ( - - ); - } - - if (locked) { - return ( - - ); - } - - return ( - - ); - })} -
-
- ); -} - -/** H5 详情:热门推荐 — 一行横向滚动 */ -export function H5MorePlaylets({ items }: { items: RelatedDrama[] }) { - if (!items.length) return null; - - return ( -
-

热门推荐

-
- {items.map((item) => { - const badge = resolveContentBadge(item); - return ( - -
- - -
- {item.title} - - {item.tagNames?.[0]} - {item.tagNames?.[0] && item.totalEpisode ? " · " : ""} - {item.totalEpisode ? `${item.totalEpisode}集` : ""} - - - ); - })} -
-
- ); -} diff --git a/src/components/drama-detail/related-aside.tsx b/src/components/drama-detail/related-aside.tsx deleted file mode 100644 index 2cb2e26..0000000 --- a/src/components/drama-detail/related-aside.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import Link from "next/link"; - -import { DecryptedImage } from "@/components/common/decrypted-image"; -import { formatHeat } from "@/components/ranking/data"; -import { dramaHref } from "@/components/short-drama/data"; -import { IMG_PLACEHOLDER } from "@/lib/image/decrypt"; - -import type { RelatedDrama } from "./data"; - -export function RelatedAside({ items }: { items: RelatedDrama[] }) { - if (!items.length) return null; - - return ( - - ); -} diff --git a/src/components/drama-play/play-episode-panel.tsx b/src/components/drama-play/play-episode-panel.tsx deleted file mode 100644 index f45001e..0000000 --- a/src/components/drama-play/play-episode-panel.tsx +++ /dev/null @@ -1,169 +0,0 @@ -"use client"; - -import Link from "next/link"; -import { useState } from "react"; - -import { - dramaDetailHref, - getEpisodeChunks, - getEpisodeState, - playHref, - totalEpisodeOf, - type DramaDetail, -} from "@/components/drama-detail/data"; - -import { ChevronIcon } from "./icons"; - -export const EPISODE_CHUNK = 30; - -function LockIcon({ className = "size-[18px]" }: { className?: string }) { - return ( - - ); -} - -function FreeBadge() { - return ( - - 免费 - - ); -} - -export function useEpisodeRange(detail: DramaDetail, current: number) { - const ranges = getEpisodeChunks(totalEpisodeOf(detail), EPISODE_CHUNK); - const [rangeIndex, setRangeIndex] = useState(() => Math.floor((current - 1) / EPISODE_CHUNK)); - const { start, end } = ranges[rangeIndex] ?? ranges[0]; - const episodes = Array.from({ length: end - start + 1 }, (_, index) => start + index); - return { ranges, rangeIndex, setRangeIndex, episodes }; -} - -export function PlayEpisodePanel({ - detail, - current, - wide = false, -}: { - detail: DramaDetail; - current: number; - wide?: boolean; -}) { - const { ranges, rangeIndex, setRangeIndex, episodes } = useEpisodeRange(detail, current); - - return ( - - ); -} diff --git a/src/components/drama-play/use-report-playlet-history.ts b/src/components/drama-play/use-report-playlet-history.ts deleted file mode 100644 index f8e1231..0000000 --- a/src/components/drama-play/use-report-playlet-history.ts +++ /dev/null @@ -1,49 +0,0 @@ -"use client"; - -import { useCallback, useRef } from "react"; - -import { reportPlayletHistory } from "@/lib/api/playlet-actions"; -import { ensureGuestSession, getAuthToken } from "@/lib/auth/session"; - -async function ensureToken() { - let token = getAuthToken(); - if (!token) { - try { - await ensureGuestSession(); - } catch { - /* ignore */ - } - token = getAuthToken(); - } - return token; -} - -/** 播放成功后上报观看历史;同一 playletId+chapterId 只报一次 */ -export function useReportPlayletHistory(playletId: number, chapterId?: number) { - const reportedKeyRef = useRef(null); - - return useCallback(async () => { - if (!Number.isInteger(playletId) || playletId < 1) return; - if (!Number.isInteger(chapterId) || !chapterId || chapterId < 1) return; - - const key = `${playletId}:${chapterId}`; - if (reportedKeyRef.current === key) return; - reportedKeyRef.current = key; - - const token = await ensureToken(); - if (!token) { - reportedKeyRef.current = null; - return; - } - - try { - await reportPlayletHistory({ playletId, chapterId }, token); - } catch (error) { - reportedKeyRef.current = null; - if (process.env.NODE_ENV === "development") { - const message = error instanceof Error ? error.message : String(error); - console.warn(`[playlet/history] report failed: ${message}`); - } - } - }, [playletId, chapterId]); -} diff --git a/src/components/favorites/data.ts b/src/components/favorites/data.ts deleted file mode 100644 index 579857a..0000000 --- a/src/components/favorites/data.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { pickPlayletCardTags, pickVideoCardTags } from "@/components/common/card-tags"; -import { resolveContentBadge } from "@/components/home/section-heading"; -import { formatHeat } from "@/components/ranking/data"; -import type { ShortDramaItem } from "@/components/short-drama/data"; -import type { FavoriteVideoListItem, PlayletData } from "@/lib/api/types"; - -export const favoriteTypes = ["短剧", "视频"] as const; - -export type FavoriteType = (typeof favoriteTypes)[number]; - -export const FAVORITES_PAGE_SIZE = 24; - -/** 短剧收藏列表项 → 卡片(接口 PlayletData) */ -export function mapFavoritePlayletItem(item: PlayletData): ShortDramaItem | null { - const id = Number(item.id); - if (!Number.isInteger(id) || id < 1) return null; - return { - kind: "drama", - id: String(id), - slug: item.slug, - title: (item.title || "").trim() || "未命名短剧", - subtitle: (item.desc || "").trim(), - tags: pickPlayletCardTags(item), - heat: formatHeat(item.heatValue ?? item.countBrowse), - episodes: item.totalEpisode ? `${item.totalEpisode}集` : "", - badge: resolveContentBadge(item), - cover: (item.cover || "").trim(), - }; -} - -/** 视频收藏列表项 → 卡片 */ -export function mapFavoriteVideoItem(item: FavoriteVideoListItem): ShortDramaItem | null { - const id = Number(item.id); - if (!Number.isInteger(id) || id < 1) return null; - return { - kind: "drama", - id: String(id), - slug: item.slug, - title: (item.title || "").trim() || "未命名视频", - subtitle: "", - tags: pickVideoCardTags(item), - heat: formatHeat(item.watchNum), - episodes: "", - cover: (item.coverImg || "").trim(), - }; -} diff --git a/src/components/favorites/favorites-page.tsx b/src/components/favorites/favorites-page.tsx deleted file mode 100644 index fd0ea91..0000000 --- a/src/components/favorites/favorites-page.tsx +++ /dev/null @@ -1,221 +0,0 @@ -"use client"; - -import { useRouter } from "next/navigation"; -import { useEffect, useRef, useState } from "react"; - -import { EmptyState } from "@/components/common/empty-state"; -import { Pagination } from "@/components/common/pagination"; -import { SeoBreadcrumb } from "@/components/seo/seo-breadcrumb"; -import type { ShortDramaItem } from "@/components/short-drama/data"; -import { H5ShortDramaCard, ShortDramaCard } from "@/components/short-drama/short-drama-card"; -import { H5VideoCard, VideoCard } from "@/components/video/video-card"; -import { ApiError } from "@/lib/api/client"; -import { getPlayletFavoriteList } from "@/lib/api/playlet-actions"; -import { getVideoFavoriteList } from "@/lib/api/video-actions"; -import { ensureGuestSession, getAuthToken } from "@/lib/auth/session"; - -import { - FAVORITES_PAGE_SIZE, - favoriteTypes, - mapFavoritePlayletItem, - mapFavoriteVideoItem, - type FavoriteType, -} from "./data"; - -async function resolveToken() { - let token = getAuthToken(); - if (!token) { - try { - await ensureGuestSession(); - } catch { - /* ignore */ - } - token = getAuthToken(); - } - return token; -} - -/** 我的收藏:短剧 GET /api/app/playlet/favorite/list · 视频 GET /api/app/video/favorite/list */ -export function FavoritesPage() { - const router = useRouter(); - const topRef = useRef(null); - const [type, setType] = useState("短剧"); - const [page, setPage] = useState(1); - const [items, setItems] = useState([]); - const [totalPages, setTotalPages] = useState(1); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [reloadKey, setReloadKey] = useState(0); - - useEffect(() => { - let cancelled = false; - void (async () => { - await Promise.resolve(); - if (cancelled) return; - setLoading(true); - setError(null); - try { - const token = await resolveToken(); - if (cancelled) return; - if (!token) { - setItems([]); - setTotalPages(1); - setError("请先登录后查看收藏"); - return; - } - - if (type === "短剧") { - const data = await getPlayletFavoriteList({ pageNum: page, pageSize: FAVORITES_PAGE_SIZE }, token); - if (cancelled) return; - const list = (data?.list ?? []) - .map(mapFavoritePlayletItem) - .filter((item): item is ShortDramaItem => Boolean(item)); - const total = Number(data?.totalCount) || 0; - setItems(list); - setTotalPages(Math.max(1, Math.ceil(total / FAVORITES_PAGE_SIZE) || 1)); - } else { - const data = await getVideoFavoriteList({ pageNum: page, pageSize: FAVORITES_PAGE_SIZE }, token); - if (cancelled) return; - const list = (data?.list ?? []) - .map(mapFavoriteVideoItem) - .filter((item): item is ShortDramaItem => Boolean(item)); - const total = Number(data?.totalCount) || 0; - setItems(list); - setTotalPages(Math.max(1, Math.ceil(total / FAVORITES_PAGE_SIZE) || 1)); - } - } catch (err) { - if (cancelled) return; - setItems([]); - setTotalPages(1); - setError(err instanceof ApiError ? err.message : "加载失败,请稍后重试"); - } finally { - if (!cancelled) setLoading(false); - } - })(); - return () => { - cancelled = true; - }; - }, [type, page, reloadKey]); - - const changeType = (next: FavoriteType) => { - setType(next); - setPage(1); - }; - - const changePage = (next: number) => { - setPage(next); - topRef.current?.scrollIntoView({ behavior: "smooth" }); - }; - - const goBack = () => { - if (window.history.length > 1) router.back(); - else router.push("/profile"); - }; - - const isVideo = type === "视频"; - const PcCard = isVideo ? VideoCard : ShortDramaCard; - const MobileCard = isVideo ? H5VideoCard : H5ShortDramaCard; - const empty = !loading && !error && items.length === 0; - - return ( -
-
- -

我的收藏

-
- -
- - -
-

我的收藏

-

继续关注喜欢的内容

-
- -
- {favoriteTypes.map((option) => ( - - ))} -
- -
- {favoriteTypes.map((option) => ( - - ))} -
- - {loading ? ( -

加载中…

- ) : error ? ( - setReloadKey((value) => value + 1)} - className="rounded-2xl px-4 py-12 lg:rounded-3xl lg:py-24" - /> - ) : empty ? ( - - ) : ( - <> -
- {items.map((item) => ( - - ))} -
- -
- {items.map((item) => ( - - ))} -
- - - - )} -
-
- ); -} diff --git a/src/components/history/data.ts b/src/components/history/data.ts deleted file mode 100644 index 519375b..0000000 --- a/src/components/history/data.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { pickPlayletCardTags, pickVideoCardTags } from "@/components/common/card-tags"; -import { playHref } from "@/components/drama-detail/data"; -import { formatHeat } from "@/components/ranking/data"; -import type { ShortDramaItem } from "@/components/short-drama/data"; -import { videoHref } from "@/components/video/video-card"; -import type { PlayletHistoryItem, VideoHistoryItem } from "@/lib/api/types"; - -export const historyTypes = ["短剧", "视频"] as const; -export type HistoryType = (typeof historyTypes)[number]; - -export const HISTORY_PAGE_SIZE = 24; - -export function formatWatchedAt(value?: string | null) { - const raw = (value || "").trim(); - if (!raw) return ""; - const date = new Date(raw); - if (Number.isNaN(date.getTime())) return raw; - const pad = (n: number) => String(n).padStart(2, "0"); - return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()} ${pad(date.getHours())}:${pad(date.getMinutes())}`; -} - -/** 短剧历史 → 卡片展示(保留接口字段语义,仅做展示文案) */ -export function mapPlayletHistoryItem(item: PlayletHistoryItem): ShortDramaItem | null { - const id = Number(item.id); - if (!Number.isInteger(id) || id < 1) return null; - const episode = Number(item.episode) || 0; - const href = episode > 0 ? playHref(id, episode, item.slug) : undefined; - return { - kind: "drama", - id: String(id), - slug: item.slug, - title: (item.title || "").trim() || "未命名短剧", - subtitle: (item.desc || "").trim(), - tags: pickPlayletCardTags(item), - heat: formatHeat(item.heatValue ?? item.countBrowse), - episodes: episode > 0 ? `看到第${episode}集` : item.totalEpisode ? `全${item.totalEpisode}集` : "", - cover: (item.cover || "").trim(), - href, - }; -} - -/** 视频历史 → 卡片展示 */ -export function mapVideoHistoryItem(item: VideoHistoryItem): ShortDramaItem | null { - const id = Number(item.id); - if (!Number.isInteger(id) || id < 1) return null; - return { - kind: "drama", - id: String(id), - slug: item.slug, - title: (item.title || "").trim() || "未命名视频", - subtitle: (item.desc || "").trim(), - tags: pickVideoCardTags(item), - heat: formatHeat(item.watchNum), - episodes: formatWatchedAt(item.watchedAt), - cover: (item.coverImg || "").trim(), - href: videoHref(String(id), item.slug), - }; -} diff --git a/src/components/history/history-page.tsx b/src/components/history/history-page.tsx deleted file mode 100644 index e6bce09..0000000 --- a/src/components/history/history-page.tsx +++ /dev/null @@ -1,310 +0,0 @@ -"use client"; - -import { AlertDialog, Button, toast } from "@heroui/react"; -import { useRouter } from "next/navigation"; -import { useEffect, useRef, useState } from "react"; - -import { EmptyState } from "@/components/common/empty-state"; -import { Pagination } from "@/components/common/pagination"; -import { SeoBreadcrumb } from "@/components/seo/seo-breadcrumb"; -import { H5ShortDramaCard, ShortDramaCard } from "@/components/short-drama/short-drama-card"; -import type { ShortDramaItem } from "@/components/short-drama/data"; -import { H5VideoCard, VideoCard } from "@/components/video/video-card"; -import { ApiError } from "@/lib/api/client"; -import { clearPlayletHistory, getPlayletHistoryList } from "@/lib/api/playlet-actions"; -import { clearVideoHistory, getVideoHistoryList } from "@/lib/api/video-actions"; -import { ensureGuestSession, getAuthToken } from "@/lib/auth/session"; - -import { - HISTORY_PAGE_SIZE, - historyTypes, - mapPlayletHistoryItem, - mapVideoHistoryItem, - type HistoryType, -} from "./data"; - -async function resolveToken() { - let token = getAuthToken(); - if (!token) { - try { - await ensureGuestSession(); - } catch { - /* ignore */ - } - token = getAuthToken(); - } - return token; -} - -/** 观看历史:短剧 GET /api/app/playlet/history/list · 视频 GET /api/app/video/history/list */ -export function HistoryPage() { - const router = useRouter(); - const topRef = useRef(null); - const [type, setType] = useState("短剧"); - const [page, setPage] = useState(1); - const [items, setItems] = useState([]); - const [totalPages, setTotalPages] = useState(1); - const [loading, setLoading] = useState(true); - const [clearing, setClearing] = useState(false); - const [confirmOpen, setConfirmOpen] = useState(false); - const [error, setError] = useState(null); - const [reloadKey, setReloadKey] = useState(0); - - useEffect(() => { - let cancelled = false; - void (async () => { - await Promise.resolve(); - if (cancelled) return; - setLoading(true); - setError(null); - try { - const token = await resolveToken(); - if (cancelled) return; - if (!token) { - setItems([]); - setTotalPages(1); - setError("请先登录后查看观看历史"); - return; - } - - if (type === "短剧") { - const data = await getPlayletHistoryList({ pageNum: page, pageSize: HISTORY_PAGE_SIZE }, token); - if (cancelled) return; - const list = (data?.list ?? []) - .map(mapPlayletHistoryItem) - .filter((item): item is ShortDramaItem => Boolean(item)); - const total = Number(data?.totalCount) || 0; - setItems(list); - setTotalPages(Math.max(1, Math.ceil(total / HISTORY_PAGE_SIZE) || 1)); - } else { - const data = await getVideoHistoryList({ pageNum: page, pageSize: HISTORY_PAGE_SIZE }, token); - if (cancelled) return; - const list = (data?.list ?? []) - .map(mapVideoHistoryItem) - .filter((item): item is ShortDramaItem => Boolean(item)); - const total = Number(data?.totalCount) || 0; - setItems(list); - setTotalPages(Math.max(1, Math.ceil(total / HISTORY_PAGE_SIZE) || 1)); - } - } catch (err) { - if (cancelled) return; - setItems([]); - setTotalPages(1); - setError(err instanceof ApiError ? err.message : "加载失败,请稍后重试"); - } finally { - if (!cancelled) setLoading(false); - } - })(); - return () => { - cancelled = true; - }; - }, [type, page, reloadKey]); - - const changeType = (next: HistoryType) => { - setType(next); - setPage(1); - }; - - const changePage = (next: number) => { - setPage(next); - topRef.current?.scrollIntoView({ behavior: "smooth" }); - }; - - const openClearConfirm = () => { - if (clearing || items.length === 0) return; - setConfirmOpen(true); - }; - - const clearHistory = async () => { - if (clearing || items.length === 0) return; - const label = type === "短剧" ? "短剧" : "视频"; - const token = await resolveToken(); - if (!token) { - setConfirmOpen(false); - toast.danger("请先登录后再清空"); - return; - } - - setClearing(true); - setError(null); - try { - // DELETE /api/app/playlet/history · DELETE /api/app/video/history - const result = type === "短剧" ? await clearPlayletHistory(token) : await clearVideoHistory(token); - const deleted = Number(result?.deletedCount) || 0; - setItems([]); - setTotalPages(1); - setPage(1); - setConfirmOpen(false); - setReloadKey((value) => value + 1); - toast.success(deleted > 0 ? `已清空${deleted}条${label}历史` : `${label}历史已清空`); - } catch (err) { - const message = err instanceof ApiError ? err.message : "清空失败,请稍后重试"; - setError(message); - toast.danger(message); - } finally { - setClearing(false); - } - }; - - const goBack = () => { - if (window.history.length > 1) router.back(); - else router.push("/profile"); - }; - - const isVideo = type === "视频"; - const PcCard = isVideo ? VideoCard : ShortDramaCard; - const MobileCard = isVideo ? H5VideoCard : H5ShortDramaCard; - const empty = !loading && !error && items.length === 0; - const canClear = !clearing && items.length > 0; - const clearLabel = type === "短剧" ? "短剧" : "视频"; - - return ( -
-
- -

观看历史

- -
- -
- - -
-
-

观看历史

-

找回最近观看的剧集

-
- -
- -
- {historyTypes.map((option) => ( - - ))} -
- - {loading ? ( -

加载中…

- ) : error ? ( - setReloadKey((value) => value + 1)} - className="rounded-2xl px-4 py-12 lg:rounded-3xl lg:py-24" - /> - ) : empty ? ( - - ) : ( - <> -
- {items.map((item) => ( - - ))} -
- -
- {items.map((item) => ( - - ))} -
- - - - )} -
- - { - if (clearing) return; - setConfirmOpen(open); - }} - > - - - - - - - 清空观看历史 - - - -

- 确定清空全部{clearLabel}观看历史?此操作不可恢复。 -

-
- - - - -
-
-
-
-
- ); -} diff --git a/src/components/layout/header-user-chip.tsx b/src/components/layout/header-user-chip.tsx deleted file mode 100644 index 96e0dac..0000000 --- a/src/components/layout/header-user-chip.tsx +++ /dev/null @@ -1,21 +0,0 @@ -"use client"; - -import Link from "next/link"; - -import { DecryptedImage } from "@/components/common/decrypted-image"; -import { useMockUser } from "@/components/profile/use-mock-user"; - -const fallbackAvatar = "/images/default_avatar.svg"; - -export function HeaderUserChip() { - const { user } = useMockUser(); - const avatar = user?.avatar || fallbackAvatar; - const displayName = user?.name || "游客"; - - return ( - - - {displayName} - - ); -} diff --git a/src/components/likes/likes-page.tsx b/src/components/likes/likes-page.tsx deleted file mode 100644 index 971fdb9..0000000 --- a/src/components/likes/likes-page.tsx +++ /dev/null @@ -1,220 +0,0 @@ -"use client"; - -import { useRouter } from "next/navigation"; -import { useEffect, useRef, useState } from "react"; - -import { EmptyState } from "@/components/common/empty-state"; -import { Pagination } from "@/components/common/pagination"; -import { - FAVORITES_PAGE_SIZE, - favoriteTypes, - mapFavoritePlayletItem, - mapFavoriteVideoItem, - type FavoriteType, -} from "@/components/favorites/data"; -import { SeoBreadcrumb } from "@/components/seo/seo-breadcrumb"; -import type { ShortDramaItem } from "@/components/short-drama/data"; -import { H5ShortDramaCard, ShortDramaCard } from "@/components/short-drama/short-drama-card"; -import { H5VideoCard, VideoCard } from "@/components/video/video-card"; -import { ApiError } from "@/lib/api/client"; -import { getPlayletLikeList } from "@/lib/api/playlet-actions"; -import { getVideoLikeList } from "@/lib/api/video-actions"; -import { ensureGuestSession, getAuthToken } from "@/lib/auth/session"; - -async function resolveToken() { - let token = getAuthToken(); - if (!token) { - try { - await ensureGuestSession(); - } catch { - /* ignore */ - } - token = getAuthToken(); - } - return token; -} - -/** 我的点赞:短剧 GET /api/app/playlet/like/list · 视频 GET /api/app/video/like/list */ -export function LikesPage() { - const router = useRouter(); - const topRef = useRef(null); - const [type, setType] = useState("短剧"); - const [page, setPage] = useState(1); - const [items, setItems] = useState([]); - const [totalPages, setTotalPages] = useState(1); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [reloadKey, setReloadKey] = useState(0); - - useEffect(() => { - let cancelled = false; - void (async () => { - await Promise.resolve(); - if (cancelled) return; - setLoading(true); - setError(null); - try { - const token = await resolveToken(); - if (cancelled) return; - if (!token) { - setItems([]); - setTotalPages(1); - setError("请先登录后查看点赞"); - return; - } - - if (type === "短剧") { - const data = await getPlayletLikeList({ pageNum: page, pageSize: FAVORITES_PAGE_SIZE }, token); - if (cancelled) return; - const list = (data?.list ?? []) - .map(mapFavoritePlayletItem) - .filter((item): item is ShortDramaItem => Boolean(item)); - const total = Number(data?.totalCount) || 0; - setItems(list); - setTotalPages(Math.max(1, Math.ceil(total / FAVORITES_PAGE_SIZE) || 1)); - } else { - const data = await getVideoLikeList({ pageNum: page, pageSize: FAVORITES_PAGE_SIZE }, token); - if (cancelled) return; - const list = (data?.list ?? []) - .map(mapFavoriteVideoItem) - .filter((item): item is ShortDramaItem => Boolean(item)); - const total = Number(data?.totalCount) || 0; - setItems(list); - setTotalPages(Math.max(1, Math.ceil(total / FAVORITES_PAGE_SIZE) || 1)); - } - } catch (err) { - if (cancelled) return; - setItems([]); - setTotalPages(1); - setError(err instanceof ApiError ? err.message : "加载失败,请稍后重试"); - } finally { - if (!cancelled) setLoading(false); - } - })(); - return () => { - cancelled = true; - }; - }, [type, page, reloadKey]); - - const changeType = (next: FavoriteType) => { - setType(next); - setPage(1); - }; - - const changePage = (next: number) => { - setPage(next); - topRef.current?.scrollIntoView({ behavior: "smooth" }); - }; - - const goBack = () => { - if (window.history.length > 1) router.back(); - else router.push("/profile"); - }; - - const isVideo = type === "视频"; - const PcCard = isVideo ? VideoCard : ShortDramaCard; - const MobileCard = isVideo ? H5VideoCard : H5ShortDramaCard; - const empty = !loading && !error && items.length === 0; - - return ( -
-
- -

我的点赞

-
- -
- - -
-

我的点赞

-

我喜欢的我都点赞

-
- -
- {favoriteTypes.map((option) => ( - - ))} -
- -
- {favoriteTypes.map((option) => ( - - ))} -
- - {loading ? ( -

加载中…

- ) : error ? ( - setReloadKey((value) => value + 1)} - className="rounded-2xl px-4 py-12 lg:rounded-3xl lg:py-24" - /> - ) : empty ? ( - - ) : ( - <> -
- {items.map((item) => ( - - ))} -
- -
- {items.map((item) => ( - - ))} -
- - - - )} -
-
- ); -} diff --git a/src/components/nav/nav-email-card.tsx b/src/components/nav/nav-tg-card.tsx similarity index 100% rename from src/components/nav/nav-email-card.tsx rename to src/components/nav/nav-tg-card.tsx diff --git a/src/components/profile/profile-h5.tsx b/src/components/profile/profile-h5.tsx deleted file mode 100644 index 3b5f0de..0000000 --- a/src/components/profile/profile-h5.tsx +++ /dev/null @@ -1,235 +0,0 @@ -"use client"; - -import Link from "next/link"; -import { useRouter } from "next/navigation"; -import { useEffect, useState } from "react"; - -import { DecryptedImage } from "@/components/common/decrypted-image"; -import { openLoginDialog } from "@/components/auth/login-dialog"; -import { getPlayletFavoriteList, getPlayletLikeList } from "@/lib/api/playlet-actions"; -import { getVideoFavoriteList, getVideoLikeList } from "@/lib/api/video-actions"; -import { ensureGuestSession, getAuthToken } from "@/lib/auth/session"; - -import { useMockUser } from "./use-mock-user"; - -const fallbackAvatar = "/images/default_avatar.svg"; - -type MenuItem = { - label: string; - icon: string; - href: string; - extra?: string; - small?: boolean; - highlight?: boolean; -}; - -const staticMenuItems: MenuItem[] = [ - { label: "我的点赞", icon: "/images/icon_like.svg", href: "/likes", small: true }, - { label: "我的收藏", icon: "/images/collect.svg", href: "/favorites" }, - { label: "观看历史", icon: "/images/history.svg", href: "/history", extra: "继续观看" }, - { label: "回家的路", icon: "/images/home.svg", href: "/way-home", highlight: true }, - { label: "账号设置", icon: "/images/profile.svg", href: "/settings" }, - { label: "问题反馈", icon: "/images/wtfk.svg", href: "/feedback" }, -]; - -function formatBuCount(count: number | null) { - if (count == null) return ""; - return `${count}部`; -} - -async function resolveToken() { - let token = getAuthToken(); - if (!token) { - try { - await ensureGuestSession(); - } catch { - /* ignore */ - } - token = getAuthToken(); - } - return token; -} - -async function readTotal( - loader: (query: { pageNum: number; pageSize: number }, token: string) => Promise<{ totalCount?: number } | null>, - token: string, -) { - try { - const data = await loader({ pageNum: 1, pageSize: 1 }, token); - return Number(data?.totalCount) || 0; - } catch (error) { - console.warn("[profile/counts]", error); - return 0; - } -} - -function Avatar({ src }: { src: string }) { - return ( - - ); -} - -const guestActionBtn = - "cursor-pointer flex h-7 shrink-0 items-center justify-center gap-1 rounded-full bg-white px-2 text-[#120F1C]"; - -function GuestCard({ name, avatar, id }: { name: string; avatar: string; id?: string }) { - return ( -
- -
-

{name}

-
- - {id ? `ID:${id}` : "游客登录中…"} - - - -
-

- 登录正式账号后可同步收藏、追剧、观看历史和金币余额。 -

-
-
- ); -} - -function UserCard({ name, avatar, id, onSwitch }: { name: string; avatar: string; id: string; onSwitch: () => void }) { - return ( -
-
- -
-

{name}

-
- ID:{id} - -
-
-
- -
- ); -} - -export function ProfileH5() { - const router = useRouter(); - const { user, logout } = useMockUser({ refreshOnMount: true }); - const [likeCount, setLikeCount] = useState(null); - const [favoriteCount, setFavoriteCount] = useState(null); - - useEffect(() => { - let cancelled = false; - - void (async () => { - const token = await resolveToken(); - if (!token || cancelled) { - if (!cancelled) { - setLikeCount(0); - setFavoriteCount(0); - } - return; - } - - const [playletLike, videoLike, playletFav, videoFav] = await Promise.all([ - readTotal(getPlayletLikeList, token), - readTotal(getVideoLikeList, token), - readTotal(getPlayletFavoriteList, token), - readTotal(getVideoFavoriteList, token), - ]); - - if (cancelled) return; - - setLikeCount(playletLike + videoLike); - setFavoriteCount(playletFav + videoFav); - })(); - - return () => { - cancelled = true; - }; - }, [user?.id]); - - const goBack = () => { - if (window.history.length > 1) router.back(); - else router.push("/"); - }; - - const switchAccount = () => { - logout(); - openLoginDialog(); - }; - - const menuItems = staticMenuItems.map((item) => { - if (item.label === "我的点赞") return { ...item, extra: formatBuCount(likeCount) }; - if (item.label === "我的收藏") return { ...item, extra: formatBuCount(favoriteCount) }; - return item; - }); - - return ( -
-
- -

我的

-
- -
- {user?.isRegister ? ( - - ) : ( - - )} - - -
-
- ); -} diff --git a/src/components/profile/profile-hero.tsx b/src/components/profile/profile-hero.tsx deleted file mode 100644 index 9bbbef1..0000000 --- a/src/components/profile/profile-hero.tsx +++ /dev/null @@ -1,68 +0,0 @@ -"use client"; - -import { DecryptedImage } from "@/components/common/decrypted-image"; -import { openLoginDialog } from "@/components/auth/login-dialog"; - -import { useMockUser } from "./use-mock-user"; - -const fallbackAvatar = "/images/default_avatar.svg"; - -const primaryBtn = - "cursor-pointer flex h-[42px] items-center justify-center gap-2 rounded-full bg-white px-4 text-[#120F1C]"; -const secondaryBtn = - "cursor-pointer flex h-[42px] items-center justify-center rounded-full bg-white/10 px-4 text-sm leading-5 font-semibold text-white outline outline-1 -outline-offset-1 outline-white/20 hover:bg-white/15"; - -export function ProfileHero() { - const { user, logout } = useMockUser({ refreshOnMount: true }); - const isGuest = !user || !user.isRegister; - - const switchAccount = () => { - logout(); - openLoginDialog(); - }; - - return ( -
- - {isGuest ? ( -
-

- {user?.name ?? "游客"} -

-
- {user ? `ID:${user.id}` : "游客登录中…"} - 登录正式账号后可同步收藏、追剧、观看历史和金币余额。 -
-
- - -
-
- ) : ( -
-
-

- {user.name} -

-

{user.accountNo || user.email}

-
- -
- )} -
- ); -} diff --git a/src/components/profile/profile-page.tsx b/src/components/profile/profile-page.tsx deleted file mode 100644 index f6e4a04..0000000 --- a/src/components/profile/profile-page.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import Link from "next/link"; - -import { SeoBreadcrumb } from "@/components/seo/seo-breadcrumb"; - -import { ProfileH5 } from "./profile-h5"; -import { ProfileHero } from "./profile-hero"; - -const entries = [ - { - title: "我的点赞", - description: "我喜欢的我都点赞", - href: "/likes", - image: "/images/my_dz.png", - imageClassName: "h-[93px] w-[98px]", - }, - { - title: "追剧与收藏", - description: "继续关注喜欢的内容", - href: "/favorites", - image: "/images/my_sc.png", - imageClassName: "h-[100px] w-[110px]", - }, - { - title: "账号设置", - description: "资料与安全设置", - href: "/settings", - image: "/images/my_sz.png", - imageClassName: "h-[100px] w-[98px]", - }, -]; - -export function ProfilePage() { - return ( -
- - -
-
-

ACCOUNT

-

个人中心

-

欢迎回来,继续你的追剧旅程

-
- - - -
- {entries.map((entry) => ( - -
-

{entry.title}

-

- {entry.description} -

-
-
- - -
- - ))} -
-
-
- ); -} diff --git a/src/components/settings/change-password-dialog.tsx b/src/components/settings/change-password-dialog.tsx deleted file mode 100644 index 08bc24a..0000000 --- a/src/components/settings/change-password-dialog.tsx +++ /dev/null @@ -1,193 +0,0 @@ -"use client"; - -import { useEffect, useState, type FormEvent } from "react"; - -import { - CREDENTIAL_MAX_LEN, - isValidCredential, - PASSWORD_RULE_HINT, -} from "@/lib/auth/credentials"; -import { updateUserProfile } from "@/lib/auth/session"; - -type Field = "oldPassword" | "newPassword" | "confirmPassword"; - -const fields: { key: Field; label: string; placeholder: string }[] = [ - { key: "oldPassword", label: "旧密码", placeholder: "请输入旧密码" }, - { key: "newPassword", label: "新密码", placeholder: "请输入新密码" }, - { key: "confirmPassword", label: "再次确认新密码", placeholder: "请再次输入新密码" }, -]; - -const emptyValues: Record = { oldPassword: "", newPassword: "", confirmPassword: "" }; - -function validate(values: Record) { - if (!values.oldPassword) return "请输入旧密码"; - if (!isValidCredential(values.newPassword)) return PASSWORD_RULE_HINT; - if (values.newPassword === values.oldPassword) return "新密码不能与旧密码相同"; - if (values.confirmPassword !== values.newPassword) return "两次输入的新密码不一致"; - return ""; -} - -export function ChangePasswordDialog({ open, onClose }: { open: boolean; onClose: () => void }) { - const [values, setValues] = useState(emptyValues); - const [error, setError] = useState(""); - const [saving, setSaving] = useState(false); - - useEffect(() => { - if (!open) return; - const onKeyDown = (event: KeyboardEvent) => event.key === "Escape" && !saving && onClose(); - const { overflow } = document.body.style; - document.body.style.overflow = "hidden"; - window.addEventListener("keydown", onKeyDown); - return () => { - document.body.style.overflow = overflow; - window.removeEventListener("keydown", onKeyDown); - }; - }, [open, onClose, saving]); - - if (!open) return null; - - const close = () => { - if (saving) return; - setValues(emptyValues); - setError(""); - onClose(); - }; - - const submit = async (event: FormEvent) => { - event.preventDefault(); - const message = validate(values); - if (message) { - setError(message); - return; - } - - setSaving(true); - setError(""); - try { - await updateUserProfile({ - oldPassword: values.oldPassword, - newPassword: values.newPassword, - }); - setValues(emptyValues); - onClose(); - } catch (err) { - setError(err instanceof Error ? err.message : "修改密码失败"); - } finally { - setSaving(false); - } - }; - - return ( -
event.target === event.currentTarget && close()} - > -
-
- 海角社区 -
-

- 修改密码 -

-

新密码需为 4-20 位,不能包含空格,且不同于旧密码

-
- {fields.map((field) => ( - { - setValues((current) => ({ ...current, [field.key]: value })); - setError(""); - }} - /> - ))} - {error ?

{error}

: null} -
- - -
- - -
-
- ); -} - -function PasswordField({ - label, - placeholder, - value, - onChange, -}: { - label: string; - placeholder: string; - value: string; - onChange: (value: string) => void; -}) { - const [visible, setVisible] = useState(false); - - return ( - - ); -} diff --git a/src/components/settings/edit-profile-page.tsx b/src/components/settings/edit-profile-page.tsx deleted file mode 100644 index db761ae..0000000 --- a/src/components/settings/edit-profile-page.tsx +++ /dev/null @@ -1,174 +0,0 @@ -"use client"; - -import { useRouter } from "next/navigation"; -import { useEffect, useState, type FormEvent, type ReactNode } from "react"; - -import { BackButton } from "@/components/common/back-button"; -import { DecryptedImage } from "@/components/common/decrypted-image"; -import { useMockUser } from "@/components/profile/use-mock-user"; -import { SeoBreadcrumb } from "@/components/seo/seo-breadcrumb"; -import { useMockProfile } from "@/components/settings/use-mock-profile"; -import { updateUserProfile } from "@/lib/auth/session"; - -const fallbackAvatar = "/images/default_avatar.svg"; - -type ProfileEditFormProps = { - onSaved?: () => void; - actions?: ReactNode; - className?: string; -}; - -export function ProfileEditForm({ onSaved, actions, className }: ProfileEditFormProps) { - const { user } = useMockUser({ refreshOnMount: true }); - const { profile, saveProfile } = useMockProfile(); - const [nicknameDraft, setNicknameDraft] = useState(null); - const [bioDraft, setBioDraft] = useState(null); - const [saving, setSaving] = useState(false); - const [message, setMessage] = useState<{ text: string; error: boolean } | null>(null); - - const nickname = nicknameDraft ?? user?.name ?? profile.nickname; - const bio = bioDraft ?? profile.bio; - const avatar = user?.avatar ?? profile.avatar ?? fallbackAvatar; - - const submit = async (event: FormEvent) => { - event.preventDefault(); - - const trimmed = nickname.trim(); - if (!trimmed) { - setMessage({ text: "请输入昵称", error: true }); - return; - } - - const nickChanged = trimmed !== (user?.name || ""); - const bioChanged = bio.trim() !== (profile.bio || "").trim(); - - if (nickChanged && !user?.accountNo) { - setMessage({ text: "请先注册账号后再修改资料", error: true }); - return; - } - - if (!nickChanged && !bioChanged) { - setMessage({ text: "暂无需要保存的修改", error: true }); - return; - } - - setSaving(true); - setMessage(null); - try { - if (nickChanged) { - await updateUserProfile({ nickName: trimmed }); - } - saveProfile({ - nickname: trimmed, - bio: bio.trim(), - avatar: null, - }); - setNicknameDraft(null); - setBioDraft(null); - setMessage({ text: "已保存", error: false }); - onSaved?.(); - } catch (error) { - setMessage({ - text: error instanceof Error ? error.message : "保存失败", - error: true, - }); - } finally { - setSaving(false); - } - }; - - return ( -
-
-
- 个人头像 - 当前头像 -
- -
- - - -