@@ -19,9 +19,9 @@ import {
19
19
} from '/components' ;
20
20
import { AlgorithmApi , GitHubApi } from '/apis' ;
21
21
import { actions } from '/reducers' ;
22
- import { extension , getFiles , getTitleArray , handleError , refineGist } from '/common/util' ;
22
+ import { extension , handleError , refineGist } from '/common/util' ;
23
23
import { exts , languages } from '/common/config' ;
24
- import { SCRATCH_PAPER_MD } from '/skeletons ' ;
24
+ import { SCRATCH_PAPER_MD } from '/files ' ;
25
25
import styles from './stylesheet.scss' ;
26
26
27
27
loadProgressBar ( ) ;
@@ -53,7 +53,9 @@ class App extends React.Component {
53
53
. then ( ( { categories } ) => this . props . setCategories ( categories ) )
54
54
. catch ( handleError . bind ( this ) ) ;
55
55
56
- window . onbeforeunload = ( ) => this . isGistSaved ( ) ? undefined : 'Changes you made will not be saved.' ;
56
+ this . props . history . block ( ( ) => {
57
+ if ( ! this . isSaved ( ) ) return 'Are you sure want to discard changes?' ;
58
+ } ) ;
57
59
}
58
60
59
61
componentWillUnmount ( ) {
@@ -65,26 +67,12 @@ class App extends React.Component {
65
67
66
68
componentWillReceiveProps ( nextProps ) {
67
69
const { params } = nextProps . match ;
68
- const { algorithm, scratchPaper } = nextProps . current ;
69
-
70
- const categoryKey = algorithm && algorithm . categoryKey ;
71
- const algorithmKey = algorithm && algorithm . algorithmKey ;
72
- const gistId = scratchPaper && scratchPaper . gistId ;
73
-
74
- if ( params . categoryKey !== categoryKey ||
75
- params . algorithmKey !== algorithmKey ||
76
- params . gistId !== gistId ) {
77
- if ( nextProps . location . pathname !== this . props . location . pathname ) {
78
- this . loadAlgorithm ( params ) ;
79
- } else {
80
- if ( categoryKey && algorithmKey ) {
81
- this . props . history . push ( `/${ categoryKey } /${ algorithmKey } ` ) ;
82
- } else if ( gistId ) {
83
- this . props . history . push ( `/scratch-paper/${ gistId } ` ) ;
84
- } else {
85
- this . props . history . push ( '/' ) ;
86
- }
87
- }
70
+ if ( params !== this . props . match . params ) {
71
+ const { categoryKey, algorithmKey, gistId } = params ;
72
+ const { algorithm, scratchPaper } = nextProps . current ;
73
+ if ( algorithm && algorithm . categoryKey === categoryKey && algorithm . algorithmKey === algorithmKey ) return ;
74
+ if ( scratchPaper && scratchPaper . gistId === gistId ) return ;
75
+ this . loadAlgorithm ( params ) ;
88
76
}
89
77
}
90
78
@@ -95,7 +83,6 @@ class App extends React.Component {
95
83
. then ( user => {
96
84
const { login, avatar_url } = user ;
97
85
this . props . setUser ( { login, avatar_url } ) ;
98
- Cookies . set ( 'login' , login ) ;
99
86
} )
100
87
. then ( ( ) => this . loadScratchPapers ( ) )
101
88
. catch ( ( ) => this . signOut ( ) ) ;
@@ -106,7 +93,6 @@ class App extends React.Component {
106
93
GitHubApi . auth ( undefined )
107
94
. then ( ( ) => {
108
95
this . props . setUser ( undefined ) ;
109
- Cookies . remove ( 'login' ) ;
110
96
} )
111
97
. then ( ( ) => this . props . setScratchPapers ( [ ] ) ) ;
112
98
}
@@ -134,44 +120,37 @@ class App extends React.Component {
134
120
. catch ( handleError . bind ( this ) ) ;
135
121
}
136
122
137
- loadAlgorithm ( { categoryKey, algorithmKey, gistId } , forceLoad = false ) {
138
- if ( ! forceLoad && ! this . isGistSaved ( ) && ! window . confirm ( 'Are you sure want to discard changes?' ) ) return ;
139
-
123
+ loadAlgorithm ( { categoryKey, algorithmKey, gistId } ) {
140
124
const { ext } = this . props . env ;
141
- let fetchPromise = null ;
142
- if ( categoryKey && algorithmKey ) {
143
- fetchPromise = AlgorithmApi . getAlgorithm ( categoryKey , algorithmKey )
144
- . then ( ( { algorithm } ) => this . props . setAlgorithm ( algorithm ) ) ;
145
- } else if ( [ 'new' , 'forked' ] . includes ( gistId ) ) {
146
- gistId = 'new' ;
147
- const language = languages . find ( language => language . ext === ext ) ;
148
- fetchPromise = Promise . resolve ( this . props . setScratchPaper ( {
149
- gistId,
150
- title : 'Untitled' ,
151
- files : [ {
152
- name : 'README.md' ,
153
- content : SCRATCH_PAPER_MD ,
154
- contributors : undefined ,
155
- } , {
156
- name : `code.${ ext } ` ,
157
- content : language . skeleton ,
158
- contributors : undefined ,
159
- } ] ,
160
- } ) ) ;
161
- } else if ( gistId ) {
162
- fetchPromise = GitHubApi . getGist ( gistId , { timestamp : Date . now ( ) } )
163
- . then ( refineGist )
164
- . then ( this . props . setScratchPaper ) ;
165
- } else {
166
- fetchPromise = Promise . reject ( new Error ( ) ) ;
167
- }
168
- fetchPromise
125
+ const fetch = ( ) => {
126
+ if ( categoryKey && algorithmKey ) {
127
+ return AlgorithmApi . getAlgorithm ( categoryKey , algorithmKey )
128
+ . then ( ( { algorithm } ) => this . props . setAlgorithm ( algorithm ) ) ;
129
+ } else if ( gistId === 'new' ) {
130
+ const language = languages . find ( language => language . ext === ext ) ;
131
+ this . props . setScratchPaper ( {
132
+ login : undefined ,
133
+ gistId,
134
+ title : 'Untitled' ,
135
+ files : [ SCRATCH_PAPER_MD , language . skeleton ] ,
136
+ } ) ;
137
+ return Promise . resolve ( ) ;
138
+ } else if ( gistId ) {
139
+ return GitHubApi . getGist ( gistId , { timestamp : Date . now ( ) } )
140
+ . then ( refineGist )
141
+ . then ( this . props . setScratchPaper ) ;
142
+ } else {
143
+ this . props . setHome ( ) ;
144
+ return Promise . resolve ( ) ;
145
+ }
146
+ } ;
147
+ fetch ( )
169
148
. catch ( error => {
170
- if ( error . message ) handleError . bind ( this ) ( error ) ;
149
+ handleError . bind ( this ) ( error ) ;
171
150
this . props . setHome ( ) ;
172
151
} )
173
152
. finally ( ( ) => {
174
- const files = getFiles ( this . props . current ) ;
153
+ const { files } = this . props . current ;
175
154
let editorTabIndex = files . findIndex ( file => extension ( file . name ) === ext ) ;
176
155
if ( ! ~ editorTabIndex ) editorTabIndex = files . findIndex ( file => exts . includes ( extension ( file . name ) ) ) ;
177
156
if ( ! ~ editorTabIndex ) editorTabIndex = Math . min ( 0 , files . length - 1 ) ;
@@ -185,15 +164,15 @@ class App extends React.Component {
185
164
}
186
165
187
166
handleChangeEditorTabIndex ( editorTabIndex ) {
188
- const files = getFiles ( this . props . current ) ;
167
+ const { files } = this . props . current ;
189
168
if ( editorTabIndex === files . length ) this . handleAddFile ( ) ;
190
169
this . setState ( { editorTabIndex } ) ;
191
170
this . props . shouldBuild ( ) ;
192
171
}
193
172
194
173
handleAddFile ( ) {
195
174
const { ext } = this . props . env ;
196
- const files = getFiles ( this . props . current ) ;
175
+ const { files } = this . props . current ;
197
176
let name = `code.${ ext } ` ;
198
177
let count = 0 ;
199
178
while ( files . some ( file => file . name === name ) ) name = `code-${ ++ count } .${ ext } ` ;
@@ -213,7 +192,7 @@ class App extends React.Component {
213
192
214
193
handleDeleteFile ( ) {
215
194
const { editorTabIndex } = this . state ;
216
- const files = getFiles ( this . props . current ) ;
195
+ const { files } = this . props . current ;
217
196
this . handleChangeEditorTabIndex ( Math . min ( editorTabIndex , files . length - 2 ) ) ;
218
197
this . props . deleteFile ( editorTabIndex ) ;
219
198
}
@@ -222,16 +201,17 @@ class App extends React.Component {
222
201
this . setState ( { navigatorOpened } ) ;
223
202
}
224
203
225
- isGistSaved ( ) {
226
- const { scratchPaper } = this . props . current ;
227
- if ( ! scratchPaper ) return true ;
228
- const { title, files, lastTitle, lastFiles } = scratchPaper ;
229
- const serializeFiles = files => JSON . stringify ( files . map ( ( { name, content } ) => ( { name, content } ) ) ) ;
230
- return title === lastTitle && serializeFiles ( files ) === serializeFiles ( lastFiles ) ;
204
+ isSaved ( ) {
205
+ const { titles, files, lastTitles, lastFiles } = this . props . current ;
206
+ const serialize = ( titles , files ) => JSON . stringify ( {
207
+ titles,
208
+ files : files . map ( ( { name, content } ) => ( { name, content } ) ) ,
209
+ } ) ;
210
+ return serialize ( titles , files ) === serialize ( lastTitles , lastFiles ) ;
231
211
}
232
212
233
213
getDescription ( ) {
234
- const files = getFiles ( this . props . current ) ;
214
+ const { files } = this . props . current ;
235
215
const readmeFile = files . find ( file => file . name === 'README.md' ) ;
236
216
if ( ! readmeFile ) return '' ;
237
217
const groups = / ^ \s * # .* \n + ( [ ^ \n ] + ) / . exec ( readmeFile . content ) ;
@@ -241,10 +221,9 @@ class App extends React.Component {
241
221
render ( ) {
242
222
const { navigatorOpened, workspaceWeights, editorTabIndex } = this . state ;
243
223
244
- const files = getFiles ( this . props . current ) ;
245
- const titleArray = getTitleArray ( this . props . current ) ;
246
- const gistSaved = this . isGistSaved ( ) ;
247
- const title = `${ gistSaved ? '' : '(Unsaved) ' } ${ titleArray . join ( ' - ' ) } ` ;
224
+ const { files, titles } = this . props . current ;
225
+ const saved = this . isSaved ( ) ;
226
+ const title = `${ saved ? '' : '(Unsaved) ' } ${ titles . join ( ' - ' ) } ` ;
248
227
const description = this . getDescription ( ) ;
249
228
const file = files [ editorTabIndex ] ;
250
229
@@ -265,14 +244,12 @@ class App extends React.Component {
265
244
< title > { title } </ title >
266
245
< meta name = "description" content = { description } />
267
246
</ Helmet >
268
- < Header className = { styles . header } onClickTitleBar = { ( ) => this . toggleNavigatorOpened ( ) }
269
- navigatorOpened = { navigatorOpened } loadScratchPapers = { ( ) => this . loadScratchPapers ( ) }
270
- loadAlgorithm = { this . loadAlgorithm . bind ( this ) } gistSaved = { gistSaved }
271
- file = { file } />
247
+ < Header className = { styles . header } onClickTitleBar = { ( ) => this . toggleNavigatorOpened ( ) } saved = { saved }
248
+ navigatorOpened = { navigatorOpened } loadScratchPapers = { ( ) => this . loadScratchPapers ( ) } file = { file } />
272
249
< ResizableContainer className = { styles . workspace } horizontal weights = { workspaceWeights }
273
250
visibles = { [ navigatorOpened , true , true ] }
274
251
onChangeWeights = { weights => this . handleChangeWorkspaceWeights ( weights ) } >
275
- < Navigator loadAlgorithm = { this . loadAlgorithm . bind ( this ) } />
252
+ < Navigator />
276
253
< VisualizationViewer className = { styles . visualization_viewer } />
277
254
< TabContainer className = { styles . editor_tab_container } titles = { editorTitles } tabIndex = { editorTabIndex }
278
255
onChangeTabIndex = { tabIndex => this . handleChangeEditorTabIndex ( tabIndex ) } >
0 commit comments