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 ? ", " : ""}
+
+ ))}
+
+
+ )}
+
+
+ )
+}