diff --git a/web/src/pages/DiscoverPage.tsx b/web/src/pages/DiscoverPage.tsx index 6500cfc..789b73a 100644 --- a/web/src/pages/DiscoverPage.tsx +++ b/web/src/pages/DiscoverPage.tsx @@ -1,9 +1,9 @@ import { useEffect, useMemo, useState } from 'react' -import { AlertTriangle, RefreshCw, Sparkles } from 'lucide-react' import { discoverAPI, type DiscoverItem, type DiscoverSection } from '../api/discover' -import { ContentRow, DiscoverSkeleton } from './DiscoverContentRow' +import { DiscoverSkeleton } from './DiscoverContentRow' import { DiscoverDetailModal } from './DiscoverDetailModal' +import { DiscoverEmptySelection, DiscoverHeader, DiscoverResults } from './DiscoverPageSections' import { defaultSections, discoverStorageKey, @@ -112,7 +112,7 @@ export function DiscoverPage() { [sections], ) const hasContent = selected.some((key) => (rows[key] ?? []).length > 0) - const hasRowErrors = Object.keys(rowErrors).length > 0 + const sectionLabel = (key: string) => sectionMap.get(key)?.label ?? key const toggleSection = (key: string) => { setSelected((current) => { @@ -132,103 +132,34 @@ export function DiscoverPage() { return (
-
-
-
- -
-
-

- 发现 -

-

- 多源推荐:TMDb / 豆瓣 / Bangumi,可按需组合显示 -

-
-
- -
- -
- {sections.map((section) => { - const active = selected.includes(section.key) - return ( - - ) - })} -
-
-
+ {!sectionsReady && } {sectionsReady && !loading && selected.length === 0 && ( -
- 至少选择一个推荐源,小宇宙才会开始转动。 -
+ )} {sectionsReady && selected.length > 0 && ( -
- {selected.map((key) => { - const items = rows[key] ?? [] - if (items.length === 0) { - if (rowLoading[key]) { - return - } - return null - } - return ( - - ) - })} - - {hasRowErrors && ( -
- -
- {Object.entries(rowErrors).map(([key, message]) => ( -

{sectionMap.get(key)?.label ?? key}:{message}

- ))} -
-
- )} - - {!loading && !hasContent && !hasRowErrors && ( -
-

- 当前选择的推荐源暂未返回内容,可切换豆瓣 / Bangumi 或检查网络代理。 -

-
- )} -
+ )} {activeItem && ( @@ -240,16 +171,3 @@ export function DiscoverPage() {
) } - -function DiscoverRowSkeleton({ title }: { title: string }) { - return ( -
-

{title}

-
- {[1, 2, 3, 4, 5, 6, 7, 8].map((item) => ( -
- ))} -
-
- ) -} diff --git a/web/src/pages/DiscoverPageSections.tsx b/web/src/pages/DiscoverPageSections.tsx new file mode 100644 index 0000000..3c20c5a --- /dev/null +++ b/web/src/pages/DiscoverPageSections.tsx @@ -0,0 +1,178 @@ +import { AlertTriangle, RefreshCw, Sparkles } from 'lucide-react' + +import type { DiscoverItem, DiscoverSection } from '../api/discover' +import { ContentRow } from './DiscoverContentRow' + +type SectionLabel = (key: string) => string + +export function DiscoverHeader({ + sections, + selected, + sectionsReady, + loading, + onRefresh, + onToggleSection, +}: { + sections: DiscoverSection[] + selected: string[] + sectionsReady: boolean + loading: boolean + onRefresh: () => void + onToggleSection: (key: string) => void +}) { + return ( +
+
+
+ +
+
+

+ 发现 +

+

+ 多源推荐:TMDb / 豆瓣 / Bangumi,可按需组合显示 +

+
+
+ +
+ +
+ {sections.map((section) => { + const active = selected.includes(section.key) + return ( + + ) + })} +
+
+
+ ) +} + +export function DiscoverEmptySelection() { + return ( +
+ 至少选择一个推荐源,小宇宙才会开始转动。 +
+ ) +} + +export function DiscoverResults({ + selected, + rows, + rowLoading, + rowErrors, + loading, + hasContent, + imageVersion, + refreshImageVersion, + sectionLabel, + onSelect, +}: { + selected: string[] + rows: Record + rowLoading: Record + rowErrors: Record + loading: boolean + hasContent: boolean + imageVersion: string + refreshImageVersion?: string + sectionLabel: SectionLabel + onSelect: (item: DiscoverItem) => void +}) { + const hasRowErrors = Object.keys(rowErrors).length > 0 + + return ( +
+ {selected.map((key) => { + const items = rows[key] ?? [] + if (items.length === 0) { + if (rowLoading[key]) { + return + } + return null + } + return ( + + ) + })} + + {hasRowErrors && ( + + )} + + {!loading && !hasContent && !hasRowErrors && } +
+ ) +} + +function DiscoverRowErrors({ + rowErrors, + sectionLabel, +}: { + rowErrors: Record + sectionLabel: SectionLabel +}) { + return ( +
+ +
+ {Object.entries(rowErrors).map(([key, message]) => ( +

{sectionLabel(key)}:{message}

+ ))} +
+
+ ) +} + +function DiscoverNoContent() { + return ( +
+

+ 当前选择的推荐源暂未返回内容,可切换豆瓣 / Bangumi 或检查网络代理。 +

+
+ ) +} + +function DiscoverRowSkeleton({ title }: { title: string }) { + return ( +
+

{title}

+
+ {[1, 2, 3, 4, 5, 6, 7, 8].map((item) => ( +
+ ))} +
+
+ ) +}