@@ -10,15 +10,8 @@ import { SIZE_S } from '@tdev-components/shared/iconSizes';
1010import { mdiClose , mdiImageEditOutline } from '@mdi/js' ;
1111import ImageMarkupEditor from '..' ;
1212import requestDocusaurusRootAcess from '@tdev-components/util/localFS/requestDocusaurusRootAcess' ;
13- import requestFileHandle from '@tdev-components/util/localFS/requestFileHandle' ;
14- import { createExcalidrawMarkup , updateRectangleDimensions } from '../helpers/createExcalidrawMarkup' ;
15- import type { ExcalidrawInitialDataState } from '@excalidraw/excalidraw/types' ;
1613import type { PopupActions } from 'reactjs-popup/dist/types' ;
17- import extractExalidrawImageName from '../helpers/extractExalidrawImageName' ;
18- import dataUrlToBlob from '../helpers/dataUrlToBlob' ;
19- import { getImageElementFromScene , getImageFileFromScene } from '../helpers/getElementsFromScene' ;
20- import type { OrderedExcalidrawElement } from '@excalidraw/excalidraw/element/types' ;
21- import { CustomData } from '../helpers/constants' ;
14+ import useExcalidrawSource from '../hooks/useExcalidrawSource' ;
2215
2316interface Props {
2417 src : string ;
@@ -28,11 +21,11 @@ interface Props {
2821const EditorPopup = observer ( ( props : Props ) => {
2922 const sessionStore = useStore ( 'sessionStore' ) ;
3023 const ref = React . useRef < PopupActions > ( null ) ;
31- const { excaliName, excaliSrc, imgName, mimeType } = React . useMemo (
32- ( ) => extractExalidrawImageName ( props . src ) ,
33- [ props . src ]
24+ const root = sessionStore . fileSystemDirectoryHandles . get ( 'root' ) || null ;
25+ const { excaliState, setExcaliState, mimeType, load, save, restore } = useExcalidrawSource (
26+ root ,
27+ props . src
3428 ) ;
35- const [ excaliState , setExcaliState ] = React . useState < ExcalidrawInitialDataState | null > ( null ) ;
3629
3730 return (
3831 < Popup
@@ -53,38 +46,11 @@ const EditorPopup = observer((props: Props) => {
5346 return ;
5447 }
5548 }
56- const root = sessionStore . fileSystemDirectoryHandles . get ( 'root' ) ;
57- if ( ! root ) {
49+ if ( ! sessionStore . fileSystemDirectoryHandles . get ( 'root' ) ) {
5850 window . alert ( 'Kein Zugriff auf lokale Dateien. Bitte aktiviere den Zugriff.' ) ;
5951 return ;
6052 }
61- try {
62- let fileHandle : FileSystemFileHandle ;
63- let parentDir : FileSystemDirectoryHandle ;
64- try {
65- ( { fileHandle, parentDir } = await requestFileHandle ( root , excaliSrc , 'readwrite' ) ) ;
66- } catch ( error ) {
67- // If the file does not exist, create a new one
68- ( { fileHandle, parentDir } = await requestFileHandle ( root , props . src , 'read' ) ) ;
69- const excaliData = await createExcalidrawMarkup ( fileHandle ) ;
70- const excaliFile = await parentDir . getFileHandle ( excaliName , { create : true } ) ;
71- await excaliFile . createWritable ( ) . then ( async ( writable ) => {
72- await writable . write ( JSON . stringify ( excaliData , null , 2 ) ) ;
73- await writable . close ( ) ;
74- } ) ;
75- fileHandle = excaliFile ;
76- }
77- const data = await fileHandle
78- . getFile ( )
79- . then ( ( content ) => {
80- return content . text ( ) ;
81- } )
82- . then ( ( text ) => JSON . parse ( text ) as ExcalidrawInitialDataState ) ;
83- setExcaliState ( updateRectangleDimensions ( data ) ) ;
84- } catch ( error ) {
85- console . error ( 'Error processing image:' , error ) ;
86- window . alert ( `Error processing image: ${ error } ` ) ;
87- }
53+ await load ( ) ;
8854 } }
8955 onClose = { ( ) => {
9056 setExcaliState ( null ) ;
@@ -117,83 +83,12 @@ const EditorPopup = observer((props: Props) => {
11783 ref . current ?. close ( ) ;
11884 } }
11985 onSave = { async ( state , blob , asWebp ) => {
120- const root = sessionStore . fileSystemDirectoryHandles . get ( 'root' ) ;
121- let exaliExport = excaliSrc ;
122- let imgExport = props . src ;
123- const needsTransform = asWebp && ! / \. w e b p $ / i. test ( props . src ) ;
124- if ( needsTransform ) {
125- exaliExport = exaliExport . replace (
126- `${ imgName } .excalidraw` ,
127- `${ imgName . split ( '.' ) . slice ( 0 , - 1 ) . join ( '.' ) } .webp.excalidraw`
128- ) ;
129- imgExport = imgExport . replace (
130- `${ imgName } ` ,
131- `${ imgName . split ( '.' ) . slice ( 0 , - 1 ) . join ( '.' ) } .webp`
132- ) ;
133- }
134-
135- const { fileHandle, parentDir } = await requestFileHandle (
136- root ! ,
137- exaliExport ,
138- 'readwrite' ,
139- true
140- ) ;
141- const { fileHandle : imgHandle } = await requestFileHandle (
142- root ! ,
143- imgExport ,
144- 'readwrite' ,
145- true
146- ) ;
147- await fileHandle . createWritable ( ) . then ( async ( writable ) => {
148- await writable . write ( JSON . stringify ( state , null , 2 ) ) ;
149- await writable . close ( ) ;
150- } ) ;
151- await imgHandle . createWritable ( ) . then ( async ( writable ) => {
152- await writable . write ( blob ) ;
153- await writable . close ( ) ;
154- } ) ;
155- if ( needsTransform ) {
156- try {
157- await parentDir . removeEntry ( imgName ) ;
158- await parentDir . removeEntry ( `${ imgName } .excalidraw` ) ;
159- } catch ( err ) {
160- console . error ( `Error removing entry when transforming to WebP:` , err ) ;
161- }
162- }
86+ await save ( state , blob , asWebp ) ;
16387 ref . current ?. close ( ) ;
16488 } }
16589 onRestore = { async ( ) => {
166- const root = sessionStore . fileSystemDirectoryHandles . get ( 'root' ) ;
167- const { fileHandle, parentDir } = await requestFileHandle (
168- root ! ,
169- excaliSrc ,
170- 'read'
171- ) ;
172- const data = await fileHandle
173- . getFile ( )
174- . then ( ( content ) => content . text ( ) )
175- . then ( ( text ) => JSON . parse ( text ) as ExcalidrawInitialDataState ) ;
176- const [ backgroundImage ] = getImageElementFromScene (
177- data . elements as readonly OrderedExcalidrawElement [ ]
178- ) ;
179- const backgroundFile = getImageFileFromScene ( data . files ) ;
180- if ( backgroundFile && backgroundImage ) {
181- const data = backgroundImage . customData as Partial < CustomData > ;
182- const initExtension = data . initExtension || '.png' ;
183- const restoredName = imgName . endsWith ( initExtension )
184- ? imgName
185- : `${ imgName . split ( '.' ) . slice ( 0 , - 1 ) . join ( '.' ) } ${ initExtension } ` ;
186- const imgHandle = await parentDir . getFileHandle ( restoredName , {
187- create : true
188- } ) ;
189- await imgHandle . createWritable ( ) . then ( async ( writable ) => {
190- await writable . write ( dataUrlToBlob ( backgroundFile . dataURL ) ) ;
191- await writable . close ( ) ;
192- } ) ;
193- await parentDir . removeEntry ( excaliName ) ;
194- if ( restoredName !== imgName ) {
195- await parentDir . removeEntry ( imgName ) ;
196- }
90+ const restored = await restore ( ) ;
91+ if ( restored ) {
19792 ref . current ?. close ( ) ;
19893 }
19994 } }
0 commit comments