1 | 'use strict'
|
2 |
|
3 | const {remote} = require('electron')
|
4 | const {app, dialog, shell} = remote
|
5 | const async = require('async')
|
6 | const chokidar = require('chokidar')
|
7 | const fs = require('fs')
|
8 | const git = require('simple-git')
|
9 | const lodash = require('lodash')
|
10 | const path = require('path')
|
11 |
|
12 | const renderer = require('../renderer.js')
|
13 |
|
14 |
|
15 | var confFile = localStorage.getItem('confFile')
|
16 | var render
|
17 | var gitRepo = ''
|
18 | var gitRemote = ''
|
19 | var gitBranch = ''
|
20 | var appConf = {}
|
21 | var serverStarted = false
|
22 | var serverUrl = ''
|
23 | var errors = {}
|
24 | var watcher
|
25 |
|
26 |
|
27 | document.getElementById('version').innerHTML = app.getVersion()
|
28 |
|
29 |
|
30 | var openConf = () => {
|
31 | render = new renderer(confFile)
|
32 |
|
33 | if(!render.sourceDir || !render.buildDir) {
|
34 | localStorage.removeItem('confFile')
|
35 | remote.getCurrentWindow().reload()
|
36 | }
|
37 |
|
38 | async.waterfall([
|
39 | (callback) => {
|
40 | git(path.dirname(confFile)).revparse(['--show-toplevel'], callback)
|
41 | },
|
42 | (repo, callback) => {
|
43 | gitRepo = repo.trim()
|
44 | git(gitRepo).raw(['config', '--get', 'remote.origin.url'], callback)
|
45 | },
|
46 | (remote, callback) => {
|
47 | gitRemote = remote.trim()
|
48 | git(gitRepo).branchLocal(callback)
|
49 | },
|
50 | (branches, callback) => {
|
51 | gitBranch = branches.current
|
52 |
|
53 | let select = []
|
54 | for (let i = 0; i < branches.all.length; i++) {
|
55 | select.push(`<option value="${branches.all[i]}" ${(branches.all[i] === branches.current ? 'selected' : '')}>${branches.all[i]}</option>`)
|
56 | }
|
57 | document.getElementById('branch').innerHTML = select.join('')
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 | callback(null)
|
78 | }
|
79 | ], err => {
|
80 | if (err) {
|
81 | dialog.showMessageBox({
|
82 | type: 'error',
|
83 | message: err.toString(),
|
84 | buttons: ['OK']
|
85 | }, () => {
|
86 | confFile = null
|
87 | openConfFile()
|
88 | })
|
89 | } else {
|
90 | document.getElementById('remote').innerHTML = gitRemote.replace('http://', '').replace('https://', '')
|
91 | document.getElementById('remote').setAttribute('title', gitRemote)
|
92 |
|
93 | document.getElementById('repo').innerHTML = gitRepo.replace(app.getPath('home'), '~')
|
94 | document.getElementById('repo').setAttribute('title', gitRepo)
|
95 |
|
96 | document.getElementById('conf').innerHTML = confFile.replace(gitRepo, '.')
|
97 | document.getElementById('conf').setAttribute('title', confFile)
|
98 |
|
99 | document.getElementById('source').innerHTML = render.sourceDir.replace(gitRepo, '.')
|
100 | document.getElementById('source').setAttribute('title', render.sourceDir)
|
101 |
|
102 | document.getElementById('build').innerHTML = render.buildDir.replace(gitRepo, '.')
|
103 | document.getElementById('build').setAttribute('title', render.buildDir)
|
104 |
|
105 | document.getElementById('log').style.left = document.getElementById('tools').offsetWidth + 'px'
|
106 |
|
107 | if (fs.existsSync(render.buildDir)) {
|
108 |
|
109 | startRendering('all')
|
110 | } else {
|
111 | startRendering('all')
|
112 | }
|
113 |
|
114 | startServer()
|
115 | }
|
116 | })
|
117 | }
|
118 |
|
119 |
|
120 | var openConfFile = () => {
|
121 | var files = dialog.showOpenDialog({
|
122 | properties: ['openFile'],
|
123 | filters: [
|
124 | { name: 'Yaml files', extensions: ['yaml'] }
|
125 | ]
|
126 | })
|
127 | if (!files && !confFile) { app.quit() }
|
128 | if (!files) { return }
|
129 |
|
130 | confFile = files[0]
|
131 | localStorage.setItem('confFile', confFile)
|
132 |
|
133 | openConf()
|
134 | }
|
135 |
|
136 |
|
137 | var setBranch = () => {
|
138 | clearLog()
|
139 |
|
140 | let e = document.getElementById('branch')
|
141 | gitBranch = e.options[e.selectedIndex].value
|
142 |
|
143 | git(gitRepo).checkout(gitBranch).fetch().status(function (err, data) {
|
144 | if (err) { console.error(err) }
|
145 |
|
146 | openConf()
|
147 | })
|
148 | }
|
149 |
|
150 |
|
151 | var startRendering = (type) => {
|
152 | try {
|
153 | watcher.close()
|
154 | } catch (e) {
|
155 |
|
156 | }
|
157 |
|
158 | watcher = chokidar.watch(render.sourceDir).on(type, (et, filename) => {
|
159 | const dirName = path.dirname(filename)
|
160 | const fileName = path.basename(filename)
|
161 | const eventType = et
|
162 |
|
163 | if (fileName.startsWith('_')) { return }
|
164 | if (!fileName.endsWith('.pug') && !fileName.endsWith('.js') && !fileName.endsWith('.styl')) { return }
|
165 |
|
166 | if (render.paths.length) {
|
167 | var ignore = true
|
168 | for (let i = 0; i < render.paths.length; i++) {
|
169 | if (render.paths[i] && item.path.startsWith(path.join(render.sourceDir, render.paths[i]))) {
|
170 | ignore = false
|
171 | break
|
172 | }
|
173 | }
|
174 | if (ignore) { return }
|
175 | }
|
176 |
|
177 | if (fileName.startsWith('index.') && fileName.endsWith('.pug')) {
|
178 | render.makeHTML(dirName, (err, files) => {
|
179 | if (err) {
|
180 |
|
181 |
|
182 | if (Array.isArray(err)) {
|
183 | var error = `${err[1]}\n${err[0].message || err[0].stack || err[0]}`
|
184 | } else {
|
185 | var error = `${err.message || err.stack || err}`
|
186 | }
|
187 |
|
188 | addLogError(
|
189 | eventType.toUpperCase(),
|
190 | filename.replace(render.sourceDir, '.'),
|
191 | `javascript:shell.showItemInFolder('${filename}')`,
|
192 | error.trim(),
|
193 | false
|
194 | )
|
195 | } else if (files && files.length) {
|
196 | addLog(
|
197 | eventType.toUpperCase(),
|
198 | filename,
|
199 | files
|
200 | )
|
201 | }
|
202 | })
|
203 | }
|
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 |
|
210 |
|
211 | })
|
212 |
|
213 |
|
214 |
|
215 |
|
216 |
|
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 |
|
246 |
|
247 |
|
248 |
|
249 |
|
250 |
|
251 |
|
252 |
|
253 | }
|
254 |
|
255 |
|
256 | var startServer = () => {
|
257 | render.serve((err) => {
|
258 | serverUrl = `http://localhost:${render.serverPort}`
|
259 | document.getElementById('preview').innerHTML = serverUrl
|
260 | document.getElementById('preview').setAttribute('href', `javascript:shell.openExternal('${serverUrl}');`)
|
261 |
|
262 | if (err) {
|
263 | addLogError(
|
264 | err.event,
|
265 | err.source,
|
266 | `javascript:shell.openExternal('${serverUrl + err.source}')`,
|
267 | err.error.toString().trim(),
|
268 | false
|
269 | )
|
270 | } else {
|
271 | serverStarted = true
|
272 |
|
273 | let myNotification = new Notification('Server started', { body: serverUrl })
|
274 |
|
275 | myNotification.onclick = () => {
|
276 | shell.openExternal(serverUrl)
|
277 | }
|
278 | }
|
279 | })
|
280 | }
|
281 |
|
282 |
|
283 | var clearLog = () => {
|
284 | document.getElementById('log-table').innerHTML = ''
|
285 | }
|
286 |
|
287 |
|
288 | var addLogError = (event, source, sourceLink, error, notify) => {
|
289 | if (notify) {
|
290 | let myNotification = new Notification('Error in file', { body: source })
|
291 | }
|
292 |
|
293 | document.getElementById('log-table').innerHTML = document.getElementById('log-table').innerHTML + `
|
294 | <tr class="error">
|
295 | <td style="width:5%">${event}</td>
|
296 | <td style="width:95%" colspan="2">
|
297 | <a href="${sourceLink}">${source}</a><br>
|
298 | <pre>${error}</pre>
|
299 | </td>
|
300 | </tr>
|
301 | `
|
302 | document.getElementById('log').scrollTop = document.getElementById('log').scrollHeight
|
303 | }
|
304 |
|
305 |
|
306 | var addLog = (event, source, build) => {
|
307 | let links = []
|
308 | for (let i = 0; i < build.length; i++) {
|
309 | let buildUrl = build[i].build.replace(render.buildDir, '').replace(/\\/g, '/').replace('/index.html', '')
|
310 | links.push(`<a class="${build[i].alias ? 'alias' : ''}" href="javascript:shell.openExternal('${serverUrl + buildUrl}')">${buildUrl || '/'}</a>`)
|
311 | }
|
312 | links.sort()
|
313 | document.getElementById('log-table').innerHTML = document.getElementById('log-table').innerHTML + `
|
314 | <tr class="log">
|
315 | <td style="width:5%">${event}</td>
|
316 | <td style="width:5%"><a href="javascript:shell.showItemInFolder('${source}')">${source.replace(render.sourceDir ,'.')}</a></td>
|
317 | <td style="width:90%">${links.join('<br>')}</td>
|
318 | </tr>
|
319 | `
|
320 |
|
321 | document.getElementById('log').scrollTop = document.getElementById('log').scrollHeight
|
322 | }
|
323 |
|
324 |
|
325 | var badge = (source, add) => {
|
326 | if (add) {
|
327 | errors[source] = true
|
328 | } else {
|
329 | delete errors[source]
|
330 | }
|
331 |
|
332 | app.setBadgeCount(Object.keys(errors).length)
|
333 | }
|
334 |
|
335 |
|
336 | if (confFile) {
|
337 | openConf()
|
338 | } else {
|
339 | openConfFile()
|
340 | }
|