@@ -10,6 +10,11 @@ import useErrors from "../../utils/use-errors.js"
1010import useLocalStorage from "../../utils/use-local-storage.js"
1111import useElectron from "../../utils/use-electron.js"
1212import templates from "../StartingPage/templates"
13+ import useEventCallback from "use-event-callback"
14+ import { setIn } from "seamless-immutable"
15+ import toUDTCSV from "../../utils/to-udt-csv.js"
16+
17+ import useFileHandler from "../../utils/file-handlers"
1318
1419const useStyles = makeStyles ( {
1520 empty : {
@@ -20,142 +25,78 @@ const useStyles = makeStyles({
2025 }
2126} )
2227
28+ const randomId = ( ) =>
29+ Math . random ( )
30+ . toString ( )
31+ . split ( "." ) [ 1 ]
32+
2333export default ( ) => {
2434 const c = useStyles ( )
25- const [ pageName , changePageName ] = useState ( "welcome" )
26- const [ currentFile , changeCurrentFile ] = useState ( )
35+ const {
36+ file,
37+ changeFile,
38+ openFile,
39+ openUrl,
40+ makeSession,
41+ saveFile,
42+ recentItems
43+ } = useFileHandler ( )
44+
2745 const [ oha , changeOHA ] = useState ( )
2846 const [ errors , addError ] = useErrors ( )
29- let [ recentItems , changeRecentItems ] = [ [ ] , ( ) => null ] // useLocalStorage("recentItems", [])
3047 const { addToast } = useToasts ( )
31- if ( ! recentItems ) recentItems = [ ]
48+
3249 const { remote, ipcRenderer } = useElectron ( )
3350
34- const onCreateTemplate = useMemo (
35- ( ) => template => {
36- changeCurrentFile ( {
37- fileName : "unnamed" ,
38- content : template . oha ,
39- id : Math . random ( )
40- . toString ( )
41- . split ( "." ) [ 1 ]
42- } )
43- changeOHA ( template . oha )
44- changePageName ( "edit" )
45- } ,
46- [ ]
47- )
51+ const onCreateTemplate = useEventCallback ( template => {
52+ changeFile ( {
53+ fileName : "unnamed" ,
54+ content : template . oha ,
55+ id : randomId ( ) ,
56+ mode : "filesystem"
57+ } )
58+ } )
59+
60+ const openRecentItem = useEventCallback ( item => changeFile ( item ) )
61+ const onClickHome = useEventCallback ( ( ) => changeFile ( null ) )
4862
4963 useEffect ( ( ) => {
50- const onOpenWelcomePage = ( ) => changePageName ( "welcome" )
51- const onOpenSettingsPage = ( ) => changePageName ( "edit" )
52- const onOpenSamplesPage = ( ) => changePageName ( "edit" )
53- const onOpenLabelPage = ( ) => changePageName ( "edit" )
54- const onNewFile = ( e , data ) => {
55- if ( data . templateName ) {
56- onCreateTemplate (
57- templates . find ( template => template . name === data . templateName )
58- )
59- } else {
60- changeCurrentFile ( {
61- fileName : "unnamed" ,
62- content : { } ,
63- id : Math . random ( )
64- . toString ( )
65- . split ( "." ) [ 1 ]
66- } )
67- changeOHA ( { } )
68- changePageName ( "edit" )
69- }
64+ const onOpenWelcomePage = ( ) => changeFile ( null )
65+ const onNewFile = ( arg0 , { templateName } = { } ) => {
66+ onCreateTemplate (
67+ templates . find ( t => t . name === templateName ) || templates [ 0 ]
68+ )
7069 }
71- const onOpenFile = ( e , data ) => {
72- try {
73- const oha = JSON . parse ( data . content )
74- changeCurrentFile ( {
75- ...data ,
76- content : oha
77- } )
78- changeOHA ( oha )
79- changePageName ( "edit" )
80- } catch ( e ) {
81- addError ( e . toString ( ) )
82- }
83- }
84- const onSaveFile = async ( e , data ) => {
85- let filePath = currentFile . filePath
86- if ( ! currentFile . filePath ) {
87- const {
88- cancelled,
89- filePath : newFilePath
90- } = await remote . dialog . showSaveDialog ( )
91- filePath = newFilePath
92- if ( cancelled || ! filePath ) {
93- addError ( "Could not save" )
94- return
95- }
96- changeCurrentFile ( { ...currentFile , filePath } )
97- }
70+ const saveFileAs = ( ) => saveFile ( { saveAs : true } )
71+ const exportToCSV = async ( ) => {
72+ if ( ! file ) return
73+ let { cancelled, filePath } = await remote . dialog . showSaveDialog ( {
74+ filters : [ { name : ".udt.csv" , extensions : [ "udt.csv" ] } ]
75+ } )
76+ filePath =
77+ ! filePath || filePath . endsWith ( ".json" )
78+ ? filePath
79+ : `${ filePath } .udt.json`
80+
9881 await remote
9982 . require ( "fs" )
100- . promises . writeFile ( filePath , JSON . stringify ( oha , null , " " ) )
101- addToast ( "File Saved!" )
83+ . promises . writeFile ( filePath , toUDTCSV ( file . content ) )
10284 }
10385 ipcRenderer . on ( "open-welcome-page" , onOpenWelcomePage )
104- ipcRenderer . on ( "open-settings-page" , onOpenSettingsPage )
105- ipcRenderer . on ( "open-samples-page" , onOpenSamplesPage )
106- ipcRenderer . on ( "open-label-page" , onOpenLabelPage )
10786 ipcRenderer . on ( "new-file" , onNewFile )
108- ipcRenderer . on ( "open-file" , onOpenFile )
109- ipcRenderer . on ( "save-file" , onSaveFile )
87+ ipcRenderer . on ( "open-file" , openFile )
88+ ipcRenderer . on ( "save-file" , saveFile )
89+ ipcRenderer . on ( "save-file-as" , saveFileAs )
90+ ipcRenderer . on ( "export-to-csv" , exportToCSV )
11091 return ( ) => {
11192 ipcRenderer . removeListener ( "open-welcome-page" , onOpenWelcomePage )
112- ipcRenderer . removeListener ( "open-settings-page" , onOpenWelcomePage )
113- ipcRenderer . removeListener ( "open-samples-page" , onOpenWelcomePage )
114- ipcRenderer . removeListener ( "open-label-page" , onOpenWelcomePage )
11593 ipcRenderer . removeListener ( "new-file" , onNewFile )
116- ipcRenderer . removeListener ( "open-file" , onOpenFile )
117- ipcRenderer . removeListener ( "save-file" , onSaveFile )
118- }
119- } , [ currentFile ] )
120-
121- const openRecentItem = useMemo ( ( ) => item => {
122- changeCurrentFile ( item )
123- try {
124- changeOHA ( JSON . parse ( item . content ) )
125- } catch ( e ) {
126- addError ( "Couldn't parse content into JSON" )
94+ ipcRenderer . removeListener ( "open-file" , openFile )
95+ ipcRenderer . removeListener ( "save-file" , saveFile )
96+ ipcRenderer . removeListener ( "save-file-as" , saveFileAs )
97+ ipcRenderer . removeListener ( "export-to-csv" , exportToCSV )
12798 }
128- changePageName ( "edit" )
129- } )
130-
131- const onClickHome = useMemo ( ( ) => ( ) => changePageName ( "welcome" ) , [ ] )
132-
133- const handleOpenFile = useMemo (
134- ( ) => file => {
135- const { name : fileName , path : filePath } = file
136- const reader = new FileReader ( )
137- reader . onload = e => {
138- const content = e . target . result
139- try {
140- const oha = JSON . parse ( content )
141- // TODO validate OHA and prompt to open anyway if invalid
142- changeCurrentFile ( {
143- fileName,
144- filePath,
145- content : oha ,
146- id : filePath
147- } )
148- changeOHA ( oha )
149- changePageName ( "edit" )
150- } catch ( e ) {
151- console . log ( e . toString ( ) )
152- addError ( `Could not read file "${ file . name } "` )
153- }
154- }
155- reader . readAsText ( file )
156- } ,
157- [ ]
158- )
99+ } , [ file ] )
159100
160101 return (
161102 < >
@@ -164,30 +105,33 @@ export default () => {
164105 recentItems,
165106 onClickTemplate : onCreateTemplate ,
166107 onClickHome,
108+ title : file ? file . fileName : null ,
109+ fileOpen : Boolean ( file ) ,
167110 onOpenRecentItem : openRecentItem ,
168- isDesktop : true
111+ isDesktop : true ,
112+ onOpenFile : openFile
169113 } }
170114 >
171- { pageName === "welcome" ? (
115+ { ! file ? (
172116 < StartingPage
173117 showDownloadLink = { false }
174- onFileDrop = { handleOpenFile }
118+ onFileDrop = { openFile }
175119 onOpenTemplate = { onCreateTemplate }
176120 recentItems = { recentItems }
177121 onOpenRecentItem = { openRecentItem }
178122 />
179- ) : pageName === "edit" && currentFile ? (
123+ ) : (
180124 < OHAEditor
181- key = { currentFile . id }
182- { ...currentFile }
183- oha = { oha }
125+ key = { file . id }
126+ { ...file }
127+ oha = { file . content }
184128 onChangeFileName = { newName => {
185- changeCurrentFile ( { ...currentFile , fileName : newName } )
129+ changeFile ( setIn ( file , [ "fileName" ] , newName ) )
130+ } }
131+ onChangeOHA = { newOHA => {
132+ changeFile ( setIn ( file , [ "content" ] , newOHA ) )
186133 } }
187- onChangeOHA = { changeOHA }
188134 />
189- ) : (
190- < div className = { c . empty } > Unknown Page "{ pageName } "</ div >
191135 ) }
192136 </ HeaderContext . Provider >
193137 < ErrorToasts errors = { errors } />
0 commit comments