'use client' import type { ReactNode, } from 'react' import { useCallback, useRef, useState, } from 'react' import { createContext, useContextSelector, } from 'use-context-selector' import { PLUGIN_TYPE_SEARCH_MAP } from './plugin-type-switch' import type { Plugin } from '../types' import type { MarketplaceCollection, PluginsSort, } from './types' import { DEFAULT_SORT } from './constants' import { useMarketplaceCollectionsAndPlugins, useMarketplacePlugins, } from './hooks' export type MarketplaceContextValue = { intersected: boolean setIntersected: (intersected: boolean) => void searchPluginText: string handleSearchPluginTextChange: (text: string) => void filterPluginTags: string[] handleFilterPluginTagsChange: (tags: string[]) => void activePluginType: string handleActivePluginTypeChange: (type: string) => void plugins?: Plugin[] setPlugins: (plugins: Plugin[]) => void sort: PluginsSort handleSortChange: (sort: PluginsSort) => void marketplaceCollectionsFromClient?: MarketplaceCollection[] setMarketplaceCollectionsFromClient: (collections: MarketplaceCollection[]) => void marketplaceCollectionPluginsMapFromClient?: Record setMarketplaceCollectionPluginsMapFromClient: (map: Record) => void } export const MarketplaceContext = createContext({ intersected: true, setIntersected: () => {}, searchPluginText: '', handleSearchPluginTextChange: () => {}, filterPluginTags: [], handleFilterPluginTagsChange: () => {}, activePluginType: PLUGIN_TYPE_SEARCH_MAP.all, handleActivePluginTypeChange: () => {}, plugins: undefined, setPlugins: () => {}, sort: DEFAULT_SORT, handleSortChange: () => {}, marketplaceCollectionsFromClient: [], setMarketplaceCollectionsFromClient: () => {}, marketplaceCollectionPluginsMapFromClient: {}, setMarketplaceCollectionPluginsMapFromClient: () => {}, }) type MarketplaceContextProviderProps = { children: ReactNode } export function useMarketplaceContext(selector: (value: MarketplaceContextValue) => any) { return useContextSelector(MarketplaceContext, selector) } export const MarketplaceContextProvider = ({ children, }: MarketplaceContextProviderProps) => { const [intersected, setIntersected] = useState(true) const [searchPluginText, setSearchPluginText] = useState('') const searchPluginTextRef = useRef(searchPluginText) const [filterPluginTags, setFilterPluginTags] = useState([]) const filterPluginTagsRef = useRef(filterPluginTags) const [activePluginType, setActivePluginType] = useState(PLUGIN_TYPE_SEARCH_MAP.all) const activePluginTypeRef = useRef(activePluginType) const [sort, setSort] = useState(DEFAULT_SORT) const sortRef = useRef(sort) const { marketplaceCollections: marketplaceCollectionsFromClient, setMarketplaceCollections: setMarketplaceCollectionsFromClient, marketplaceCollectionPluginsMap: marketplaceCollectionPluginsMapFromClient, setMarketplaceCollectionPluginsMap: setMarketplaceCollectionPluginsMapFromClient, queryMarketplaceCollectionsAndPlugins, } = useMarketplaceCollectionsAndPlugins() const { plugins, setPlugins, queryPlugins, queryPluginsWithDebounced, } = useMarketplacePlugins() const handleSearchPluginTextChange = useCallback((text: string) => { setSearchPluginText(text) searchPluginTextRef.current = text queryPluginsWithDebounced({ query: text, category: activePluginTypeRef.current === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : activePluginTypeRef.current, tags: filterPluginTagsRef.current, sortBy: sortRef.current.sortBy, sortOrder: sortRef.current.sortOrder, }) }, [queryPluginsWithDebounced]) const handleFilterPluginTagsChange = useCallback((tags: string[]) => { setFilterPluginTags(tags) filterPluginTagsRef.current = tags queryPlugins({ query: searchPluginTextRef.current, category: activePluginTypeRef.current === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : activePluginTypeRef.current, tags, sortBy: sortRef.current.sortBy, sortOrder: sortRef.current.sortOrder, }) }, [queryPlugins]) const handleActivePluginTypeChange = useCallback((type: string) => { setActivePluginType(type) activePluginTypeRef.current = type if (!searchPluginTextRef.current && !filterPluginTagsRef.current.length) { queryMarketplaceCollectionsAndPlugins({ category: type === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : type, }) setPlugins([]) return } queryPlugins({ query: searchPluginTextRef.current, category: type === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : type, tags: filterPluginTagsRef.current, sortBy: sortRef.current.sortBy, sortOrder: sortRef.current.sortOrder, }) }, [queryPlugins, setPlugins, queryMarketplaceCollectionsAndPlugins]) const handleSortChange = useCallback((sort: PluginsSort) => { setSort(sort) sortRef.current = sort queryPlugins({ query: searchPluginTextRef.current, category: activePluginTypeRef.current === PLUGIN_TYPE_SEARCH_MAP.all ? undefined : activePluginTypeRef.current, tags: filterPluginTagsRef.current, sortBy: sortRef.current.sortBy, sortOrder: sortRef.current.sortOrder, }) }, [queryPlugins]) return ( {children} ) }