From 39a6f0943d5cf45aa9853c63a9b6f2c0d4278eab Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Sat, 12 Oct 2024 18:02:24 +0800 Subject: [PATCH] marketplace --- .../plugins/marketplace/context.tsx | 45 +++++++++++++++++++ .../marketplace/description/wrapper.tsx | 39 ---------------- .../plugins/marketplace/header/index.tsx | 20 --------- .../plugins/marketplace/header/wrapper.tsx | 27 ----------- .../components/plugins/marketplace/index.tsx | 23 +++++----- .../marketplace/intersection-line/hooks.ts | 17 +++++-- .../marketplace/intersection-line/index.tsx | 17 ++----- .../plugins/marketplace/list/index.tsx | 4 +- .../plugins/marketplace/list/wrapper.tsx | 39 ---------------- .../marketplace/plugin-type-switch.tsx | 4 +- .../plugins/marketplace/search-box/index.tsx | 8 ++-- .../marketplace/search-box/wrapper.tsx | 14 ------ .../plugins/plugin-page/context.tsx | 8 ---- .../components/plugins/plugin-page/index.tsx | 4 +- 14 files changed, 83 insertions(+), 186 deletions(-) create mode 100644 web/app/components/plugins/marketplace/context.tsx delete mode 100644 web/app/components/plugins/marketplace/description/wrapper.tsx delete mode 100644 web/app/components/plugins/marketplace/header/index.tsx delete mode 100644 web/app/components/plugins/marketplace/header/wrapper.tsx delete mode 100644 web/app/components/plugins/marketplace/list/wrapper.tsx delete mode 100644 web/app/components/plugins/marketplace/search-box/wrapper.tsx diff --git a/web/app/components/plugins/marketplace/context.tsx b/web/app/components/plugins/marketplace/context.tsx new file mode 100644 index 0000000000..bbadb4bf3a --- /dev/null +++ b/web/app/components/plugins/marketplace/context.tsx @@ -0,0 +1,45 @@ +'use client' + +import type { ReactNode } from 'react' +import { + useState, +} from 'react' +import { + createContext, + useContextSelector, +} from 'use-context-selector' + +export type MarketplaceContextValue = { + intersected: boolean + setIntersected: (intersected: boolean) => void +} + +export const MarketplaceContext = createContext({ + intersected: true, + setIntersected: () => {}, +}) + +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) + + return ( + + {children} + + ) +} diff --git a/web/app/components/plugins/marketplace/description/wrapper.tsx b/web/app/components/plugins/marketplace/description/wrapper.tsx deleted file mode 100644 index 91dd3a2ba6..0000000000 --- a/web/app/components/plugins/marketplace/description/wrapper.tsx +++ /dev/null @@ -1,39 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import { useCallback } from 'react' -import IntersectionLine from '../intersection-line' -import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' - -type DescriptionWrapperProps = { - children: ReactNode -} -const DescriptionWrapper = ({ - children, -}: DescriptionWrapperProps) => { - const containerRef = usePluginPageContext(v => v.containerRef) - const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) - const setScrollDisabled = usePluginPageContext(v => v.setScrollDisabled) - - const handleScrollIntersectionChange = useCallback((isIntersecting: boolean) => { - if (!isIntersecting && !scrollDisabled) { - setScrollDisabled(true) - setTimeout(() => { - if (containerRef && containerRef.current) - containerRef.current.scrollTop = 0 - }, 100) - } - }, [containerRef, scrollDisabled, setScrollDisabled]) - - return !scrollDisabled && ( - <> - {children} - - - ) -} - -export default DescriptionWrapper diff --git a/web/app/components/plugins/marketplace/header/index.tsx b/web/app/components/plugins/marketplace/header/index.tsx deleted file mode 100644 index 3caeea6c7f..0000000000 --- a/web/app/components/plugins/marketplace/header/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import Description from '../description' -import DescriptionWrapper from '../description/wrapper' -import SearchBoxWrapper from '../search-box/wrapper' -import PluginTypeSwitch from '../plugin-type-switch' - -const Header = () => { - return ( - <> - - - -
- -
- - - ) -} - -export default Header diff --git a/web/app/components/plugins/marketplace/header/wrapper.tsx b/web/app/components/plugins/marketplace/header/wrapper.tsx deleted file mode 100644 index a0c45bbc1a..0000000000 --- a/web/app/components/plugins/marketplace/header/wrapper.tsx +++ /dev/null @@ -1,27 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' -import cn from '@/utils/classnames' - -type HeaderWrapperProps = { - children: ReactNode -} -const HeaderWrapper = ({ - children, -}: HeaderWrapperProps) => { - const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) - - return ( -
- {children} -
- ) -} - -export default HeaderWrapper diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index 5d737db448..e85411c1ed 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -1,18 +1,19 @@ -import Header from './header' -import HeaderWrapper from './header/wrapper' +import { MarketplaceContextProvider } from './context' +import Description from './description' +import IntersectionLine from './intersection-line' +import SearchBox from './search-box' +import PluginTypeSwitch from './plugin-type-switch' import List from './list' -import ListWrapper from './list/wrapper' const Marketplace = () => { return ( -
- -
- - - - -
+ + + + + + + ) } diff --git a/web/app/components/plugins/marketplace/intersection-line/hooks.ts b/web/app/components/plugins/marketplace/intersection-line/hooks.ts index a31d196179..2ebc7842df 100644 --- a/web/app/components/plugins/marketplace/intersection-line/hooks.ts +++ b/web/app/components/plugins/marketplace/intersection-line/hooks.ts @@ -1,21 +1,30 @@ import { useEffect } from 'react' +import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' +import { useMarketplaceContext } from '@/app/components/plugins/marketplace/context' export const useScrollIntersection = ( - containerRef: React.RefObject, anchorRef: React.RefObject, - callback: (isIntersecting: boolean) => void, ) => { + const containerRef = usePluginPageContext(v => v.containerRef) + const intersected = useMarketplaceContext(v => v.intersected) + const setIntersected = useMarketplaceContext(v => v.setIntersected) + useEffect(() => { let observer: IntersectionObserver | undefined if (containerRef?.current && anchorRef.current) { observer = new IntersectionObserver((entries) => { const isIntersecting = entries[0].isIntersecting - callback(isIntersecting) + + if (isIntersecting && !intersected) + setIntersected(true) + + if (!isIntersecting && intersected) + setIntersected(false) }, { root: containerRef.current, }) observer.observe(anchorRef.current) } return () => observer?.disconnect() - }, [containerRef, anchorRef, callback]) + }, [containerRef, anchorRef, intersected, setIntersected]) } diff --git a/web/app/components/plugins/marketplace/intersection-line/index.tsx b/web/app/components/plugins/marketplace/intersection-line/index.tsx index 3805ec6f13..e521d43f8c 100644 --- a/web/app/components/plugins/marketplace/intersection-line/index.tsx +++ b/web/app/components/plugins/marketplace/intersection-line/index.tsx @@ -3,24 +3,13 @@ import { useRef } from 'react' import { useScrollIntersection } from './hooks' -type IntersectionLineProps = { - containerRef: React.RefObject - intersectedCallback: (isIntersecting: boolean) => void -} -const IntersectionLine = ({ - containerRef, - intersectedCallback, -}: IntersectionLineProps) => { +const IntersectionLine = () => { const ref = useRef(null) - useScrollIntersection( - containerRef, - ref, - intersectedCallback, - ) + useScrollIntersection(ref) return ( -
+
) } diff --git a/web/app/components/plugins/marketplace/list/index.tsx b/web/app/components/plugins/marketplace/list/index.tsx index 7a8d6daa5d..fa5975bb5a 100644 --- a/web/app/components/plugins/marketplace/list/index.tsx +++ b/web/app/components/plugins/marketplace/list/index.tsx @@ -7,7 +7,7 @@ const List = () => { const locale = getLocaleOnServer() return ( - <> +
Featured
Our top picks to get you started
@@ -223,7 +223,7 @@ const List = () => { />
- + ) } diff --git a/web/app/components/plugins/marketplace/list/wrapper.tsx b/web/app/components/plugins/marketplace/list/wrapper.tsx deleted file mode 100644 index cf040c8d6b..0000000000 --- a/web/app/components/plugins/marketplace/list/wrapper.tsx +++ /dev/null @@ -1,39 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' -import cn from '@/utils/classnames' - -type ListWrapperProps = { - children: ReactNode -} -const ListWrapper = ({ - children, -}: ListWrapperProps) => { - const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) - const setScrollDisabled = usePluginPageContext(v => v.setScrollDisabled) - - return ( - <> - { - scrollDisabled && ( -
- ) - } -
{ - if ((e.target as HTMLElement).scrollTop <= 0) - setScrollDisabled(false) - }} - > - {children} -
- - ) -} - -export default ListWrapper diff --git a/web/app/components/plugins/marketplace/plugin-type-switch.tsx b/web/app/components/plugins/marketplace/plugin-type-switch.tsx index 9c9d73cdb7..16be79db26 100644 --- a/web/app/components/plugins/marketplace/plugin-type-switch.tsx +++ b/web/app/components/plugins/marketplace/plugin-type-switch.tsx @@ -43,7 +43,9 @@ const PluginTypeSwitch = ({ const [activeType, setActiveType] = useState('all') return ( -
+
{ options.map(option => (
void - widthShouldChange?: boolean } const SearchBox = ({ onChange, - widthShouldChange, }: SearchBoxProps) => { + const intersected = useMarketplaceContext(v => v.intersected) const [searchText, setSearchText] = useState('') const [selectedTags, setSelectedTags] = useState([]) @@ -28,8 +28,8 @@ const SearchBox = ({ return (
{ - const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) - - return ( - - ) -} - -export default Wrapper diff --git a/web/app/components/plugins/plugin-page/context.tsx b/web/app/components/plugins/plugin-page/context.tsx index 57e00d9c5d..2d026c7cd1 100644 --- a/web/app/components/plugins/plugin-page/context.tsx +++ b/web/app/components/plugins/plugin-page/context.tsx @@ -3,7 +3,6 @@ import type { ReactNode } from 'react' import { useRef, - useState, } from 'react' import { createContext, @@ -12,14 +11,10 @@ import { export type PluginPageContextValue = { containerRef: React.RefObject - scrollDisabled: boolean - setScrollDisabled: (scrollDisabled: boolean) => void } export const PluginPageContext = createContext({ containerRef: { current: null }, - scrollDisabled: false, - setScrollDisabled: () => {}, }) type PluginPageContextProviderProps = { @@ -34,14 +29,11 @@ export const PluginPageContextProvider = ({ children, }: PluginPageContextProviderProps) => { const containerRef = useRef(null) - const [scrollDisabled, setScrollDisabled] = useState(false) return ( {children} diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index f79e0af275..b7c55f48e3 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -32,7 +32,6 @@ const PluginPage = ({ const { t } = useTranslation() const { setShowPluginSettingModal } = useModalContext() as any const containerRef = usePluginPageContext(v => v.containerRef) - const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) const options = useMemo(() => { return [ @@ -51,12 +50,11 @@ const PluginPage = ({ className={cn('grow relative flex flex-col overflow-y-auto border-t border-divider-subtle', activeTab === 'plugins' ? 'rounded-t-xl bg-components-panel-bg' : 'bg-background-body', - activeTab === 'discover' && scrollDisabled && 'overflow-hidden', )} >