File size: 2,848 Bytes
8a37e0a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import {
  Modal,
  ModalBody,
  ModalCloseButton,
  ModalContent,
  ModalFooter,
  ModalHeader,
  ModalOverlay,
  Spinner,
} from '@invoke-ai/ui-library';
import { useStore } from '@nanostores/react';
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
import { convertImageUrlToBlob } from 'common/util/convertImageUrlToBlob';
import type { PrefilledFormData } from 'features/stylePresets/store/stylePresetModal';
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';

import type { StylePresetFormData } from './StylePresetForm';
import { StylePresetForm } from './StylePresetForm';

export const StylePresetModal = () => {
  useAssertSingleton('StylePresetModal');
  const [formData, setFormData] = useState<StylePresetFormData | null>(null);
  const { t } = useTranslation();
  const stylePresetModalState = useStore($stylePresetModalState);

  const modalTitle = useMemo(() => {
    return stylePresetModalState.updatingStylePresetId
      ? t('stylePresets.updatePromptTemplate')
      : t('stylePresets.createPromptTemplate');
  }, [stylePresetModalState.updatingStylePresetId, t]);

  const handleCloseModal = useCallback(() => {
    $stylePresetModalState.set({
      prefilledFormData: null,
      updatingStylePresetId: null,
      isModalOpen: false,
    });
  }, []);

  useEffect(() => {
    setFormData(null);
  }, []);

  useEffect(() => {
    const convertImageToBlob = async (data: PrefilledFormData | null) => {
      if (!data) {
        setFormData(null);
      } else {
        let file = null;
        if (data.imageUrl) {
          try {
            const blob = await convertImageUrlToBlob(data.imageUrl);
            if (blob) {
              file = new File([blob], 'style_preset.png', { type: 'image/png' });
            }
          } catch (error) {
            // do nothing
          }
        }
        setFormData({
          ...data,
          image: file,
        });
      }
    };
    convertImageToBlob(stylePresetModalState.prefilledFormData);
  }, [stylePresetModalState.prefilledFormData]);

  return (
    <Modal isOpen={stylePresetModalState.isModalOpen} onClose={handleCloseModal} isCentered size="2xl" useInert={false}>
      <ModalOverlay />
      <ModalContent>
        <ModalHeader>{modalTitle}</ModalHeader>
        <ModalCloseButton />
        <ModalBody display="flex" flexDir="column" gap={4}>
          {!stylePresetModalState.prefilledFormData || formData ? (
            <StylePresetForm updatingStylePresetId={stylePresetModalState.updatingStylePresetId} formData={formData} />
          ) : (
            <Spinner />
          )}
        </ModalBody>
        <ModalFooter p={2} />
      </ModalContent>
    </Modal>
  );
};