'use client' import { useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { useContext } from 'use-context-selector' import Link from 'next/link' import { RiBookOpenLine, RiDragDropLine, RiEqualizer2Line, } from '@remixicon/react' import { useBoolean } from 'ahooks' import InstallFromLocalPackage from '../install-plugin/install-from-local-package' import { PluginPageContextProvider, usePluginPageContext, } from './context' import InstallPluginDropdown from './install-plugin-dropdown' import { useUploader } from './use-uploader' import usePermission from './use-permission' import DebugInfo from './debug-info' import PluginTasks from './plugin-tasks' import Button from '@/app/components/base/button' import TabSlider from '@/app/components/base/tab-slider' import Tooltip from '@/app/components/base/tooltip' import cn from '@/utils/classnames' import PermissionSetModal from '@/app/components/plugins/permission-setting-modal/modal' import { useSelector as useAppContextSelector } from '@/context/app-context' import InstallFromMarketplace from '../install-plugin/install-from-marketplace' import { useRouter, useSearchParams, } from 'next/navigation' import type { Dependency } from '../types' import type { PluginDeclaration, PluginManifestInMarket } from '../types' import { sleep } from '@/utils' import { fetchBundleInfoFromMarketPlace, fetchManifestFromMarketPlace } from '@/service/plugins' import { marketplaceApiPrefix } from '@/config' import { SUPPORT_INSTALL_LOCAL_FILE_EXTENSIONS } from '@/config' import { LanguagesSupported } from '@/i18n/language' import I18n from '@/context/i18n' const PACKAGE_IDS_KEY = 'package-ids' const BUNDLE_INFO_KEY = 'bundle-info' export type PluginPageProps = { plugins: React.ReactNode marketplace: React.ReactNode } const PluginPage = ({ plugins, marketplace, }: PluginPageProps) => { const { t } = useTranslation() const { locale } = useContext(I18n) const searchParams = useSearchParams() const { replace } = useRouter() // just support install one package now const packageId = useMemo(() => { const idStrings = searchParams.get(PACKAGE_IDS_KEY) try { return idStrings ? JSON.parse(idStrings)[0] : '' } catch (e) { return '' } }, [searchParams]) const [dependencies, setDependencies] = useState([]) const bundleInfo = useMemo(() => { const info = searchParams.get(BUNDLE_INFO_KEY) try { return info ? JSON.parse(info) : undefined } catch (e) { return undefined } }, [searchParams]) const [isShowInstallFromMarketplace, { setTrue: showInstallFromMarketplace, setFalse: doHideInstallFromMarketplace, }] = useBoolean(false) const hideInstallFromMarketplace = () => { doHideInstallFromMarketplace() const url = new URL(window.location.href) url.searchParams.delete(PACKAGE_IDS_KEY) url.searchParams.delete(BUNDLE_INFO_KEY) replace(url.toString()) } const [manifest, setManifest] = useState(null) useEffect(() => { (async () => { await sleep(100) if (packageId) { const { data } = await fetchManifestFromMarketPlace(encodeURIComponent(packageId)) const { plugin, version } = data setManifest({ ...plugin, version: version.version, icon: `${marketplaceApiPrefix}/plugins/${plugin.org}/${plugin.name}/icon`, }) showInstallFromMarketplace() return } if (bundleInfo) { const { data } = await fetchBundleInfoFromMarketPlace(bundleInfo) setDependencies(data.version.dependencies) showInstallFromMarketplace() } })() // eslint-disable-next-line react-hooks/exhaustive-deps }, [packageId, bundleInfo]) const { canManagement, canDebugger, canSetPermissions, permissions, setPermissions, } = usePermission() const [showPluginSettingModal, { setTrue: setShowPluginSettingModal, setFalse: setHidePluginSettingModal, }] = useBoolean() const [currentFile, setCurrentFile] = useState(null) const containerRef = usePluginPageContext(v => v.containerRef) const options = usePluginPageContext(v => v.options) const activeTab = usePluginPageContext(v => v.activeTab) const setActiveTab = usePluginPageContext(v => v.setActiveTab) const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) const uploaderProps = useUploader({ onFileChange: setCurrentFile, containerRef, enabled: activeTab === 'plugins', }) const { dragging, fileUploader, fileChangeHandle, removeFile } = uploaderProps return (
{ activeTab === 'discover' && ( <>
) } {canManagement && ( setActiveTab('discover')} /> )} { canDebugger && ( ) } { canSetPermissions && ( ) }
{activeTab === 'plugins' && ( <> {plugins} {dragging && (
)}
{t('plugin.installModal.dropPluginToInstall')}
{currentFile && ( { })} onSuccess={() => { }} /> )} { })} /> )} { activeTab === 'discover' && enable_marketplace && marketplace } {showPluginSettingModal && ( )} { isShowInstallFromMarketplace && ( ) }
) } const PluginPageWithContext = (props: PluginPageProps) => { return ( ) } export default PluginPageWithContext