Skip to content
This repository was archived by the owner on Dec 16, 2021. It is now read-only.

Commit 31f9d86

Browse files
authored
Merge pull request #30 from delvedor/installer-ui
Installer ui
2 parents c149eaf + dbde413 commit 31f9d86

File tree

8 files changed

+503
-262
lines changed

8 files changed

+503
-262
lines changed

browser.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
'use strict'
2+
/* globals alert, Prism */
3+
4+
const semver = require('semver')
5+
6+
const getInstalledVersion = require('./lib/check-node')
7+
const loadVersions = require('./lib/load.js')
8+
const installNode = require('./lib/install')
9+
const getExample = require('./lib/examples')
10+
11+
// utility
12+
const errIcon = '<i class="fa fa-exclamation-triangle"></i>'
13+
const domElement = e => document.querySelector(e)
14+
const writeHTML = (e, h) => { domElement(e).innerHTML = h }
15+
const compare = (a, l) => semver.lt(a, l)
16+
const major = v => v.split('.')[0]
17+
18+
const installing = {
19+
run: false,
20+
start: function () {
21+
domElement('#installing').style.display = 'block'
22+
this.run = true
23+
},
24+
done: function () {
25+
domElement('#installing').style.display = 'none'
26+
this.run = false
27+
}
28+
}
29+
30+
// Sets the text of the 'installed version' label
31+
getInstalledVersion((err, version) => {
32+
writeHTML('#installed-version span', err ? errIcon : `v${version}`)
33+
})
34+
35+
// Sets the text of the 'install version' buttons
36+
loadVersions((err, versions) => {
37+
// get versions
38+
const stable = versions.latestLTS().version
39+
const latest = versions.latest().version
40+
41+
// write versions into buttons
42+
writeHTML('#install-stable span', err ? errIcon : stable)
43+
writeHTML('#install-latest span', err ? errIcon : latest)
44+
45+
if (err) return
46+
47+
// checks if needs to update nodejs
48+
getInstalledVersion((err2, actual) => {
49+
if (err2) return
50+
const updateButton = domElement('#update-to')
51+
// checks if stable is up to date
52+
if (major(actual) === major(stable) && compare(actual, stable)) {
53+
updateButton.style.display = 'inline-block'
54+
updateButton.children[1].innerHTML = stable
55+
// checks if latest is up to date
56+
} else if (major(actual) <= major(latest) && compare(actual, latest)) {
57+
updateButton.style.display = 'inline-block'
58+
updateButton.children[1].innerHTML = latest
59+
}
60+
// event listeners are attached after that the loadVersions retrieves the node versions
61+
domElement('#install-stable').addEventListener('click', installEvent)
62+
domElement('#install-latest').addEventListener('click', installEvent)
63+
domElement('#update-to').addEventListener('click', installEvent)
64+
})
65+
})
66+
67+
// Install events listener for 'install version' buttons
68+
function installEvent (e) {
69+
if (!installing.run) {
70+
installing.start()
71+
// gets version number from button text
72+
const version = this.children[1].innerHTML.slice(1)
73+
installNode(version, () => {}, (err, v) => {
74+
if (err) {
75+
console.log(err)
76+
domElement('#installing .error-message').style.display = 'block'
77+
domElement('.sk-folding-cube').style.display = 'none'
78+
writeHTML('#error-text', err.message)
79+
return
80+
}
81+
console.log('Done!', v)
82+
writeHTML('#installed-version span', `v${version}`)
83+
domElement('#update-to').style.display = 'none'
84+
installing.done()
85+
})
86+
} else {
87+
alert('Already performing an installation!')
88+
}
89+
}
90+
91+
function installErrorEvent (e) {
92+
domElement('#installing .error-message').style.display = 'none'
93+
domElement('.sk-folding-cube').style.display = 'block'
94+
writeHTML('#error-text', '')
95+
installing.done()
96+
}
97+
98+
// Adds a random code example and refreshes Prism lib
99+
getExample((title, code) => {
100+
writeHTML('#code-title', title)
101+
writeHTML('#code-example', code)
102+
Prism.highlightElement(domElement('#code-example'))
103+
})
104+
105+
domElement('#error-button').addEventListener('click', installErrorEvent)

images/lgoonodejswhite.png

20.4 KB
Loading

images/nodejs-new-white-bw.png

72.6 KB
Loading

index.html

Lines changed: 70 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -3,169 +3,80 @@
33
<head>
44
<meta charset="UTF-8">
55
<title>Node.js Installer</title>
6+
<link rel="stylesheet" href="./node_modules/flexboxgrid/dist/flexboxgrid.min.css" type="text/css">
7+
<link rel="stylesheet" href="./node_modules/font-awesome/css/font-awesome.min.css" type="text/css">
8+
<link rel="stylesheet" href="./node_modules/prismjs/themes/prism.css" type="text/css">
69
<link rel="stylesheet" type="text/css" href="style.css"/>
710
</head>
811
<body>
9-
<div id="main">
10-
<div id="load">
11-
<div>Acquiring Latest Version Information</div>
12-
<div class="loader">Loading...</div>
12+
<div id="main" class="row">
13+
<div class="col-xs-4 left-panel background-green">
14+
<div class="row">
15+
<div class="col-xs-12 node-image-container">
16+
<img id="node-logo" src="./images/nodejs-new-white-bw.png" alt="node logo" onclick="require('electron').shell.openExternal('https://nodejs.org/en/')"/>
17+
</div>
18+
</div>
19+
<div class="row">
20+
<div class="col-xs-12">
21+
<p id="installed-version">Installed version: <span><i class="fa fa-spinner fa-pulse fa-fw"></i></span></p>
22+
</div>
23+
<div class="col-xs-12">
24+
<a href="#" id="update-to" class="version-button"><img src="./images/lgoonodejswhite.png" alt="" /> Update to: <span></span></a>
25+
</div>
26+
</div>
27+
<div class="row bottom">
28+
<div class="col-xs-12">
29+
<p>Latest versions:</p>
30+
</div>
31+
<div class="col-xs-12">
32+
<a href="#" id="install-stable" class="version-button"><img src="./images/lgoonodejswhite.png" alt="" /> Install stable: <span><i class="fa fa-spinner fa-pulse fa-fw"></i></span></a>
33+
</div>
34+
<div class="col-xs-12">
35+
<a href="#" id="install-latest" class="version-button"><img src="./images/lgoonodejswhite.png" alt="" /> Install current: <span><i class="fa fa-spinner fa-pulse fa-fw"></i></span></a>
36+
</div>
37+
</div>
38+
</div>
39+
<div class="col-xs-8 right-panel">
40+
<div class="row">
41+
<div class="col-xs-12 school-image-container">
42+
<img src="./images/schoolhouse.svg" alt="" />
43+
</div>
44+
</div>
45+
<div class="row">
46+
<div class="col-xs-12">
47+
<h3 class="title color-green">Educational resources:</h3>
48+
<p class="text">Open source workshops that teach web software skills.<br />Do them on your own or at a workshop nearby.<br /><a href="#" onclick="require('electron').shell.openExternal('http://nodeschool.io/')">http://nodeschool.io/</a></p>
49+
</div>
50+
</div>
51+
<div class="row">
52+
<div class="col-xs-12">
53+
<h4 id="code-title" class="title color-green">A simple http file server:</h4>
54+
<pre id="code-container">
55+
<code id="code-example" class="language-javascript">
56+
</code>
57+
</pre>
58+
</div>
59+
</div>
60+
</div>
61+
</div>
62+
<div id="installing" class="row">
63+
<div class="col-xs-12">
64+
<h1 class="color-green">Installing Node.js</h1>
65+
</div>
66+
<div class="col-xs-12">
67+
<div class="sk-folding-cube">
68+
<div class="sk-cube1 sk-cube"></div>
69+
<div class="sk-cube2 sk-cube"></div>
70+
<div class="sk-cube4 sk-cube"></div>
71+
<div class="sk-cube3 sk-cube"></div>
72+
</div>
73+
</div>
74+
<div class="col-xs-offset-3 col-xs-6 error-message">
75+
<p id="error-text" class="color-red"></p>
76+
<a id="error-button" href="#" class="color-red">Return to installer</a>
1377
</div>
1478
</div>
15-
16-
<!-- All of the Node.js APIs are available in this renderer process. -->
17-
<!--We are using node <script>document.write(process.versions.node)</script>,
18-
Chromium <script>document.write(process.versions.chrome)</script>,
19-
and Electron <script>document.write(process.versions.electron)</script>.-->
79+
<script src="./node_modules/prismjs/prism.js"></script>
80+
<script src="./browser.js"></script>
2081
</body>
21-
22-
<script>
23-
// You can also require other files to run in this process
24-
const yo = require('yo-yo')
25-
const semver = require('semver')
26-
27-
const check = require('./lib/check-node')
28-
const load = require('./lib/load.js')
29-
const install = require('./lib/install')
30-
const opn = require('opn')
31-
const mainElement = document.getElementById('main')
32-
33-
function clear () {
34-
mainElement.innerHTML = ''
35-
}
36-
load((err, versions) => {
37-
if (err) throw err
38-
39-
function installPage (button) {
40-
clear()
41-
42-
var version = button.getAttribute('nodejs-version')
43-
44-
var el = yo`
45-
<div class="card">
46-
<div class="downloading">Downloading ${version}...<div class="loader">Loading...</div></div>
47-
</div>`
48-
mainElement.appendChild(el)
49-
50-
function up () {
51-
var update = yo`
52-
<div class="card">
53-
<div class="installing">Installing ${version}...<div class="loader">Loading...</div></div>
54-
</div>`
55-
yo.update(el, update)
56-
}
57-
58-
install(version, up, (err, v) => {
59-
if (err) {
60-
alert(err)
61-
allVersionsPage()
62-
throw err
63-
}
64-
// TODO: Check to make sure that versions match.
65-
allVersionsPage(v)
66-
})
67-
}
68-
69-
function allVersionsPage (installedVersion) { // true if we just installed a version
70-
clear()
71-
check((err, version) => {
72-
let el = yo`
73-
<div class="item">
74-
<div id="node-logo">
75-
<a href="http://nodejs.org"><img src="images/nodejs-new-white-pantone.png" width="100"/></a>
76-
</div>
77-
</div>
78-
</div>`
79-
mainElement.appendChild(el)
80-
if (installedVersion) {
81-
let el = yo`
82-
<div class="item">
83-
<div class="card">
84-
<div id="installed-version">
85-
<div class="installed-message">You just installed Node.js ${installedVersion}</div>
86-
</div>
87-
</div>
88-
</div>`
89-
mainElement.appendChild(el)
90-
el = yo`
91-
<div class="item">
92-
<div class="card">
93-
<div id="nodeschool">
94-
<center>
95-
<a href="http://nodeschool.io">
96-
<img src="images/schoolhouse.svg" width="200" title="Open source workshops that teach web software skills. Do them on your own or at a workshop nearby."/></a>
97-
</center>
98-
<div class="nodeschool-desc">To start learning Node.js, visit <a href="http://nodeschool.io" class="nodeschool-link">NodeSchool.io</a> where you'll find open-source automated workshops and in-person events all over the world.</div>
99-
</div>
100-
</div>
101-
</div>`
102-
mainElement.appendChild(el)
103-
}
104-
if (version) {
105-
var latest = versions.latest(version)
106-
let el
107-
if (semver.eq(latest.version, version)) {
108-
el = yo`
109-
<div class="item">
110-
<div class="card">
111-
<div id="current-version">
112-
<div class="big-version">Installed: ${latest.version}</div>
113-
<div class="version-desc">This is the latest version of v${semver.major(version)}.</div>
114-
</div>
115-
</div>
116-
</div>`
117-
} else {
118-
el = yo`
119-
<div class="item">
120-
<div class="card">
121-
<div id="current-version">
122-
<div class="big-version">Installed: v${version}</div>
123-
<div class="version-desc">There is an updated version of v${semver.major(latest.version)}.</div>
124-
<button class="install" style="margin-top:10px;" nodejs-version="${latest.version}">Update to ${latest.version}</button>
125-
</div>
126-
</div>
127-
</div>`
128-
}
129-
mainElement.appendChild(el)
130-
}
131-
132-
var stable = versions.latestLTS()
133-
console.log(stable)
134-
el = yo`
135-
<div class="item">
136-
<div class="card">
137-
<div id="current-version">
138-
<div class="big-version">Latest Stable: <button class="install" nodejs-version="${stable.version}">${stable.version}</button>
139-
</div>
140-
</div>
141-
</div>
142-
</div>`
143-
mainElement.appendChild(el)
144-
145-
var current = versions.latest()
146-
el = yo`
147-
<div class="item">
148-
<div class="card">
149-
<div id="current-version">
150-
<div class="big-version">Latest Current: <button class="install" nodejs-version="${current.version}">${current.version}</button>
151-
</div>
152-
</div>
153-
</div>
154-
</div>`
155-
mainElement.appendChild(el)
156-
157-
document.body.addEventListener('click', function (event) {
158-
let target = event.target
159-
if (target.tagName === 'A' && target.className == 'nodeschool-link') {
160-
event.preventDefault()
161-
opn('http://nodeschool.io')
162-
}
163-
if (target.tagName !== 'BUTTON') return // Only listen for buttons
164-
installPage(target)
165-
})
166-
})
167-
}
168-
allVersionsPage()
169-
})
170-
</script>
17182
</html>

lib/examples.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use strict'
2+
3+
const examples = [{
4+
title: 'A simple http file server',
5+
code: `
6+
const http = require('http')
7+
const fs = require('fs')
8+
9+
const server = http.createServer(function (req, res) {
10+
res.writeHead(200, { 'content-type': 'text/plain' })
11+
fs.createReadStream('./file.txt').pipe(res)
12+
})
13+
14+
server.listen(3000)`
15+
}, {
16+
title: 'A simple http server',
17+
code: `
18+
const http = require('http')
19+
20+
const server = http.createServer(function (req, res) {
21+
res.writeHead(200, {'Content-Type': 'text/plain'})
22+
res.end('Hello World')
23+
})
24+
25+
server.listen(8000, function (error) {
26+
if (error) console.log(error)
27+
console.log('Server running at http://127.0.0.1:8000/')
28+
})`
29+
}, {
30+
title: 'Line count of a file',
31+
code: `
32+
const fs = require('fs')
33+
// Reads the first argoment in your CLI,
34+
// eg: '$ node index.js filename.txt'
35+
const file = process.argv[2]
36+
37+
fs.readFile(file, function (err, contents) {
38+
if (err) console.log(err)
39+
const lines = contents.toString().split('\\n').length - 1
40+
console.log(lines)
41+
})
42+
`}]
43+
44+
module.exports = function (callback) {
45+
const { title, code } = examples[Math.floor(Math.random() * examples.length)]
46+
callback(title, code)
47+
}

0 commit comments

Comments
 (0)