Merge branch 'feat/plugins' into dev/plugin-deploy

This commit is contained in:
JzoNg 2025-01-08 20:02:34 +08:00
commit f1794a3d1b
4 changed files with 55 additions and 16 deletions

View File

@ -1,7 +1,8 @@
import { sleep } from '@/utils'
// modalElem fold into plugin install task btn
const animTime = 2000
const modalClassName = 'install-modal'
const COUNT_DOWN_TIME = 15000 // 15s
function getElemCenter(elem: HTMLElement) {
const rect = elem.getBoundingClientRect()
@ -12,7 +13,13 @@ function getElemCenter(elem: HTMLElement) {
}
const useFoldAnimInto = (onClose: () => void) => {
return async function foldIntoAnim(modalClassName: string) {
let countDownRunId: number
const clearCountDown = () => {
clearTimeout(countDownRunId)
}
// modalElem fold into plugin install task btn
const foldIntoAnim = async () => {
clearCountDown()
const modalElem = document.querySelector(`.${modalClassName}`) as HTMLElement
const pluginTaskTriggerElem = document.getElementById('plugin-task-trigger')
@ -32,6 +39,19 @@ const useFoldAnimInto = (onClose: () => void) => {
await sleep(animTime)
onClose()
}
const countDownFoldIntoAnim = async () => {
countDownRunId = window.setTimeout(() => {
foldIntoAnim()
}, COUNT_DOWN_TIME)
}
return {
modalClassName,
foldIntoAnim,
clearCountDown,
countDownFoldIntoAnim,
}
}
export default useFoldAnimInto

View File

@ -1,6 +1,6 @@
'use client'
import React, { useCallback, useRef, useState } from 'react'
import React, { useCallback, useState } from 'react'
import Modal from '@/app/components/base/modal'
import type { Dependency, Plugin, PluginManifestInMarket } from '../../types'
import { InstallStep } from '../../types'
@ -37,8 +37,27 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({
const [errorMsg, setErrorMsg] = useState<string | null>(null)
const { refreshPluginList } = useRefreshPluginList()
const modalRef = useRef<HTMLElement>(null)
const foldAnimInto = useFoldAnimInto(onClose)
const {
modalClassName,
foldIntoAnim: doFoldAnimInto,
clearCountDown,
countDownFoldIntoAnim,
} = useFoldAnimInto(onClose)
const [isInstalling, setIsInstalling] = useState(false)
const foldAnimInto = useCallback(() => {
if (isInstalling) {
doFoldAnimInto()
return
}
onClose()
}, [doFoldAnimInto, isInstalling, onClose])
const handleStartToInstall = useCallback(() => {
setIsInstalling(true)
countDownFoldIntoAnim()
}, [countDownFoldIntoAnim])
const getTitle = useCallback(() => {
if (isBundle && step === InstallStep.installed)
@ -53,20 +72,20 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({
const handleInstalled = useCallback(() => {
setStep(InstallStep.installed)
refreshPluginList(manifest)
setIsInstalling(false)
}, [manifest, refreshPluginList])
const handleFailed = useCallback((errorMsg?: string) => {
setStep(InstallStep.installFailed)
setIsInstalling(false)
if (errorMsg)
setErrorMsg(errorMsg)
}, [])
const modalClassName = 'install-modal'
return (
<Modal
isShow={true}
onClose={() => step === InstallStep.readyToInstall ? foldAnimInto(modalClassName) : onClose()}
onClose={foldAnimInto}
wrapperClassName='z-[9999]'
className={cn(modalClassName, 'flex min-w-[560px] p-0 flex-col items-start rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadows-shadow-xl')}
closable
@ -94,6 +113,7 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({
onCancel={onClose}
onInstalled={handleInstalled}
onFailed={handleFailed}
onStartToInstall={handleStartToInstall}
/>
)}
{

View File

@ -56,6 +56,7 @@ const Installed: FC<Props> = ({
useEffect(() => {
if (hasInstalled && uniqueIdentifier === installedInfoPayload.uniqueIdentifier)
onInstalled()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasInstalled])
const handleCancel = () => {
@ -67,7 +68,6 @@ const Installed: FC<Props> = ({
if (isInstalling) return
onStartToInstall?.()
setIsInstalling(true)
try {
let taskId
let isInstalled

View File

@ -108,10 +108,6 @@ const beforeRequestAuthorization: BeforeRequestHook = (request) => {
request.headers.set('Authorization', `Bearer ${accessToken}`)
}
const beforeRequestDeleteContentType: BeforeRequestHook = (request) => {
request.headers.delete('Content-Type')
}
const baseHooks: Hooks = {
afterResponse: [
afterResponse204,
@ -134,7 +130,7 @@ export const baseOptions: RequestInit = {
}
async function base<T>(url: string, options: FetchOptionType = {}, otherOptions: IOtherOptions = {}): Promise<T> {
const { params, body, ...init } = Object.assign({}, baseOptions, options)
const { params, body, headers, ...init } = Object.assign({}, baseOptions, options)
const {
isPublicAPI = false,
isMarketplaceAPI = false,
@ -159,6 +155,9 @@ async function base<T>(url: string, options: FetchOptionType = {}, otherOptions:
const fetchPathname = `${base}${url.startsWith('/') ? url : `/${url}`}`
if (deleteContentType)
(headers as any).delete('Content-Type')
const client = baseClient.extend({
hooks: {
...baseHooks,
@ -170,8 +169,7 @@ async function base<T>(url: string, options: FetchOptionType = {}, otherOptions:
...baseHooks.beforeRequest || [],
isPublicAPI && beforeRequestPublicAuthorization,
!isPublicAPI && !isMarketplaceAPI && beforeRequestAuthorization,
deleteContentType && beforeRequestDeleteContentType,
].filter(i => !!i),
].filter(Boolean),
afterResponse: [
...baseHooks.afterResponse || [],
afterResponseErrorCode(otherOptions),
@ -181,6 +179,7 @@ async function base<T>(url: string, options: FetchOptionType = {}, otherOptions:
const res = await client(fetchPathname, {
...init,
headers,
credentials: isMarketplaceAPI
? 'omit'
: (options.credentials || 'include'),