mirror of
https://github.com/langgenius/dify.git
synced 2026-09-08 02:43:49 +08:00
- resample the 3MB trending background to a 97KB webp and serve a frozen recommend banner from the E2E stub so the benchmark covers the carousel - show the on-page filtered count in template search and redirect out-of-range pages to the last available page - localize the carousel controls across all 24 locales and replace the i18n type casts with typed selectors - surface Marketplace API failures with a retry action instead of rendering them as empty results - use iconify marks for the hero decorations, share the carousel page-size hook to avoid a hydration mismatch, move banner types into @dify/contracts, scope the Cmd+K shortcut to the standalone platform, point the embedded logo at /marketplace, pass resolvedTheme to the detail dialogs, and reveal the detail iframe after a loading timeout Co-authored-by: Cursor <cursoragent@cursor.com>
47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
'use client'
|
|
|
|
import type { PluginBanner } from '@dify/contracts/marketplace'
|
|
import type { MarketplaceViewProps } from './view'
|
|
import { queryOptions, useQuery } from '@tanstack/react-query'
|
|
import { useLocale } from '@/context/i18n'
|
|
import { useResetMarketplaceSearchModeOnMount } from './atoms'
|
|
import { fetchPluginBanners } from './home/banners'
|
|
import { MarketplaceView } from './view'
|
|
|
|
const BANNER_STALE_TIME = 1000 * 60 * 5
|
|
|
|
export type EmbeddedMarketplaceProps = Omit<MarketplaceViewProps, 'banners'> & {
|
|
initialBanners?: PluginBanner[]
|
|
/**
|
|
* Locale used to fetch `initialBanners` during server rendering. `initialBanners`
|
|
* is only applied while the client locale still matches it, so a client-side
|
|
* language change refetches banners instead of seeding the new locale's cache
|
|
* with banners from the previous language.
|
|
*/
|
|
initialLocale?: string
|
|
}
|
|
|
|
export function EmbeddedMarketplace({
|
|
initialBanners,
|
|
initialLocale,
|
|
variant = 'default',
|
|
...props
|
|
}: EmbeddedMarketplaceProps) {
|
|
useResetMarketplaceSearchModeOnMount()
|
|
const locale = useLocale()
|
|
const { data: banners = [] } = useQuery(
|
|
queryOptions({
|
|
// fetchPluginBanners returns normalized PluginBanner[] rather than the
|
|
// raw contract response, so it uses its own cache key instead of
|
|
// impersonating the generated banners.list contract query.
|
|
queryKey: ['marketplace-banners', locale],
|
|
queryFn: () => fetchPluginBanners(locale),
|
|
enabled: variant === 'home',
|
|
initialData: locale === initialLocale ? initialBanners : undefined,
|
|
staleTime: BANNER_STALE_TIME,
|
|
}),
|
|
)
|
|
|
|
return <MarketplaceView {...props} banners={banners} variant={variant} />
|
|
}
|