From 4d96f9103ddca5d1d1caa7fe159b7feb67dafeaf Mon Sep 17 00:00:00 2001 From: Innei Date: Wed, 7 May 2025 19:26:53 +0800 Subject: [PATCH] feat(discover): enhance recommendations display with new list item component and improved layout Signed-off-by: Innei --- .../src/modules/discover/recommendations.tsx | 188 +++++++++++++++--- 1 file changed, 161 insertions(+), 27 deletions(-) diff --git a/apps/desktop/layer/renderer/src/modules/discover/recommendations.tsx b/apps/desktop/layer/renderer/src/modules/discover/recommendations.tsx index 12f554fc8..c8f1024df 100644 --- a/apps/desktop/layer/renderer/src/modules/discover/recommendations.tsx +++ b/apps/desktop/layer/renderer/src/modules/discover/recommendations.tsx @@ -4,11 +4,11 @@ import { ActionButton } from "@follow/components/ui/button/action-button.js" import { Card, CardContent } from "@follow/components/ui/card/index.jsx" import { ScrollArea } from "@follow/components/ui/scroll-area/ScrollArea.js" import { ResponsiveSelect } from "@follow/components/ui/select/responsive.js" +import { EllipsisHorizontalTextWithTooltip } from "@follow/components/ui/typography/EllipsisWithTooltip.js" import { CategoryMap, RSSHubCategories } from "@follow/constants" import { nextFrame } from "@follow/utils/dom" import { isASCII } from "@follow/utils/utils" import { keepPreviousData } from "@tanstack/react-query" -import { Masonry } from "masonic" import { useCallback, useEffect, useMemo, useState } from "react" import { flushSync } from "react-dom" import { useTranslation } from "react-i18next" @@ -19,7 +19,8 @@ import { useCurrentModal, useModalStack } from "~/components/ui/modal/stacked/ho import { useAuthQuery } from "~/hooks/common" import { Queries } from "~/queries" -import { RecommendationCard } from "./recommendations-card" +import { FeedIcon } from "../feed/feed-icon" +import { RecommendationContent } from "./recommendation-content" const LanguageOptions = [ { @@ -229,9 +230,8 @@ const RecommendationDrawerContent = ({ const { dismiss } = useCurrentModal() - // Delay the masonry rendering to avoid layout shift + // Delay rendering to avoid layout shift const [ready, setReady] = useState(false) - const [masonryReady, setMasonryReady] = useState(false) useEffect(() => { nextFrame(() => { @@ -255,31 +255,29 @@ const RecommendationDrawerContent = ({
{filteredItems.length > 0 ? ( - + {ready && ( - { - setTimeout(() => { - setMasonryReady(true) - }, 36) +
{ - if (!itemData) return null - return ( - - ) - }} - /> + > + {filteredItems.map( + (item) => + item && ( +
+ +
+ ), + )} +
)}
) : ( @@ -300,3 +298,139 @@ const RecommendationDrawerContent = ({
) } + +const RecommendationListItem = ({ + data, + routePrefix, + setCategory, +}: { + data: any + routePrefix: string + setCategory: (category: string) => void +}) => { + const { t } = useTranslation() + const { present } = useModalStack() + + const { maintainers, categories, routes } = useMemo(() => { + const maintainers = new Set() + const categories = new Set() + const routes = Object.keys(data.routes) + + for (const route in data.routes) { + const routeData = data.routes[route]! + if (routeData.maintainers) { + routeData.maintainers.forEach((m) => maintainers.add(m)) + } + if (routeData.categories) { + routeData.categories.forEach((c) => categories.add(c)) + } + } + categories.delete("popular") + return { + maintainers: Array.from(maintainers), + categories: Array.from(categories) as unknown as typeof RSSHubCategories, + routes, + } + }, [data]) + + return ( + +
+
+ +
+ +
+
+
+
+ {categories.map((c) => ( + + ))} +
+
+ +
    + {routes.map((route) => { + const routeData = data.routes[route]! + if (Array.isArray(routeData.path)) { + routeData.path = routeData.path.find((p) => p === route) ?? routeData.path[0] + } + return ( +
  • { + present({ + id: `recommendation-content-${route}`, + content: () => ( + + ), + icon: , + title: `${data.name} - ${data.routes[route]!.name}`, + }) + }} + > +
    + + + {routeData.name} + +
  • + ) + })} +
+ + {maintainers.length > 0 && ( +
+ + + {maintainers.map((m, i) => ( + + + @{m} + + {i < maintainers.length - 1 ? ", " : ""} + + ))} + +
+ )} +
+
+ ) +}