File size: 3,787 Bytes
74aacd5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
134
135
136
137
138
139
140
import React, { useEffect } from 'react'
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import Editor from './Editor/Editor'
import ShortcutsModal from './Shortcuts/ShortcutsModal'
import SettingModal from './Settings/SettingsModal'
import Toast from './shared/Toast'
import {
  AIModel,
  fileState,
  isPaintByExampleState,
  isPix2PixState,
  isSDState,
  settingState,
  showFileManagerState,
  toastState,
} from '../store/Atoms'
import {
  currentModel,
  getMediaFile,
  modelDownloaded,
  switchModel,
} from '../adapters/inpainting'
import SidePanel from './SidePanel/SidePanel'
import PESidePanel from './SidePanel/PESidePanel'
import FileManager from './FileManager/FileManager'
import P2PSidePanel from './SidePanel/P2PSidePanel'
import Plugins from './Plugins/Plugins'
import Flex from './shared/Layout'
import ImageSize from './ImageSize/ImageSize'

const Workspace = () => {
  const setFile = useSetRecoilState(fileState)
  const [settings, setSettingState] = useRecoilState(settingState)
  const [toastVal, setToastState] = useRecoilState(toastState)
  const isSD = useRecoilValue(isSDState)
  const isPaintByExample = useRecoilValue(isPaintByExampleState)
  const isPix2Pix = useRecoilValue(isPix2PixState)

  const [showFileManager, setShowFileManager] =
    useRecoilState(showFileManagerState)

  const onSettingClose = async () => {
    const curModel = await currentModel().then(res => res.text())
    if (curModel === settings.model) {
      return
    }
    const downloaded = await modelDownloaded(settings.model).then(res =>
      res.text()
    )

    const { model } = settings

    let loadingMessage = `Switching to ${model} model`
    let loadingDuration = 3000
    if (downloaded === 'False') {
      loadingMessage = `Downloading ${model} model, this may take a while`
      loadingDuration = 9999999999
    }

    setToastState({
      open: true,
      desc: loadingMessage,
      state: 'loading',
      duration: loadingDuration,
    })

    switchModel(model)
      .then(res => {
        if (res.ok) {
          setToastState({
            open: true,
            desc: `Switch to ${model} model success`,
            state: 'success',
            duration: 3000,
          })
        } else {
          throw new Error('Server error')
        }
      })
      .catch(() => {
        setToastState({
          open: true,
          desc: `Switch to ${model} model failed`,
          state: 'error',
          duration: 3000,
        })
        setSettingState(old => {
          return { ...old, model: curModel as AIModel }
        })
      })
  }

  useEffect(() => {
    currentModel()
      .then(res => res.text())
      .then(model => {
        setSettingState(old => {
          return { ...old, model: model as AIModel }
        })
      })
  }, [setSettingState])

  return (
    <>
      {isSD ? <SidePanel /> : <></>}
      {isPaintByExample ? <PESidePanel /> : <></>}
      {isPix2Pix ? <P2PSidePanel /> : <></>}
      <Flex style={{ position: 'absolute', top: 68, left: 24, gap: 12 }}>
        <Plugins />
        <ImageSize />
      </Flex>
      <FileManager
        photoWidth={256}
        show={showFileManager}
        onClose={() => {
          setShowFileManager(false)
        }}
        onPhotoClick={async (tab: string, filename: string) => {
          const newFile = await getMediaFile(tab, filename)
          setFile(newFile)
          setShowFileManager(false)
        }}
      />
      <Editor />
      <SettingModal onClose={onSettingClose} />
      <ShortcutsModal />
      <Toast
        {...toastVal}
        onOpenChange={(open: boolean) => {
          setToastState(old => {
            return { ...old, open }
          })
        }}
      />
    </>
  )
}

export default Workspace