wwf
2025-05-20 938c3e5a587ce950a94964ea509b9e7f8834dfae
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
'use client'
 
import React, { useCallback, useState } from 'react'
import Modal from '@/app/components/base/modal'
import type { Dependency, PluginDeclaration } from '../../types'
import { InstallStep } from '../../types'
import Uploading from './steps/uploading'
import { useTranslation } from 'react-i18next'
import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon'
import ReadyToInstallPackage from './ready-to-install'
import ReadyToInstallBundle from '../install-bundle/ready-to-install'
import useHideLogic from '../hooks/use-hide-logic'
import cn from '@/utils/classnames'
 
const i18nPrefix = 'plugin.installModal'
 
type InstallFromLocalPackageProps = {
  file: File
  onSuccess: () => void
  onClose: () => void
}
 
const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({
  file,
  onClose,
}) => {
  const { t } = useTranslation()
  // uploading -> !uploadFailed -> readyToInstall -> installed/failed
  const [step, setStep] = useState<InstallStep>(InstallStep.uploading)
  const [uniqueIdentifier, setUniqueIdentifier] = useState<string | null>(null)
  const [manifest, setManifest] = useState<PluginDeclaration | null>(null)
  const [errorMsg, setErrorMsg] = useState<string | null>(null)
  const isBundle = file.name.endsWith('.difybndl')
  const [dependencies, setDependencies] = useState<Dependency[]>([])
 
  const {
    modalClassName,
    foldAnimInto,
    setIsInstalling,
    handleStartToInstall,
  } = useHideLogic(onClose)
 
  const getTitle = useCallback(() => {
    if (step === InstallStep.uploadFailed)
      return t(`${i18nPrefix}.uploadFailed`)
    if (isBundle && step === InstallStep.installed)
      return t(`${i18nPrefix}.installComplete`)
    if (step === InstallStep.installed)
      return t(`${i18nPrefix}.installedSuccessfully`)
    if (step === InstallStep.installFailed)
      return t(`${i18nPrefix}.installFailed`)
 
    return t(`${i18nPrefix}.installPlugin`)
  }, [isBundle, step, t])
 
  const { getIconUrl } = useGetIcon()
 
  const handlePackageUploaded = useCallback(async (result: {
    uniqueIdentifier: string
    manifest: PluginDeclaration
  }) => {
    const {
      manifest,
      uniqueIdentifier,
    } = result
    const icon = await getIconUrl(manifest!.icon)
    setUniqueIdentifier(uniqueIdentifier)
    setManifest({
      ...manifest,
      icon,
    })
    setStep(InstallStep.readyToInstall)
  }, [getIconUrl])
 
  const handleBundleUploaded = useCallback((result: Dependency[]) => {
    setDependencies(result)
    setStep(InstallStep.readyToInstall)
  }, [])
 
  const handleUploadFail = useCallback((errorMsg: string) => {
    setErrorMsg(errorMsg)
    setStep(InstallStep.uploadFailed)
  }, [])
 
  return (
    <Modal
      isShow={true}
      onClose={foldAnimInto}
      className={cn(modalClassName, 'shadows-shadow-xl flex min-w-[560px] flex-col items-start rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg p-0')}
      closable
    >
      <div className='flex items-start gap-2 self-stretch pb-3 pl-6 pr-14 pt-6'>
        <div className='title-2xl-semi-bold self-stretch text-text-primary'>
          {getTitle()}
        </div>
      </div>
      {step === InstallStep.uploading && (
        <Uploading
          isBundle={isBundle}
          file={file}
          onCancel={onClose}
          onPackageUploaded={handlePackageUploaded}
          onBundleUploaded={handleBundleUploaded}
          onFailed={handleUploadFail}
        />
      )}
      {isBundle ? (
        <ReadyToInstallBundle
          step={step}
          onStepChange={setStep}
          onStartToInstall={handleStartToInstall}
          setIsInstalling={setIsInstalling}
          onClose={onClose}
          allPlugins={dependencies}
        />
      ) : (
        <ReadyToInstallPackage
          step={step}
          onStepChange={setStep}
          onStartToInstall={handleStartToInstall}
          setIsInstalling={setIsInstalling}
          onClose={onClose}
          uniqueIdentifier={uniqueIdentifier}
          manifest={manifest}
          errorMsg={errorMsg}
          onError={setErrorMsg}
        />
      )}
    </Modal>
  )
}
 
export default InstallFromLocalPackage