Skip to content

Commit 401b82b

Browse files
committed
Migrate UI to Next.js/React
1 parent 4fa525d commit 401b82b

18 files changed

+236
-159
lines changed

package-lock.json

+70-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "icarus",
3-
"version": "0.1.5",
3+
"version": "0.1.6",
44
"description": "",
55
"scripts": {
66
"build": "npm run build:web && npm run build:app && npm run build:service && npm run build:package",
@@ -11,7 +11,7 @@
1111
"build:clean": "node scripts/build-clean.js",
1212
"build:assets": "node scripts/build-assets.js",
1313
"dev:web": "next src\\web",
14-
"dev:service": "nodemon src/service/main.js",
14+
"dev:service": "node src/service/main.js --proxy=\"http://localhost:3000\" &",
1515
"lint": "npm run lint:go && npm run lint:javascript",
1616
"lint:go": "go fmt src\\app\\main.go",
1717
"lint:javascript": "npx standard --fix"
@@ -34,6 +34,7 @@
3434
},
3535
"dependencies": {
3636
"connect": "^3.7.0",
37+
"http-proxy": "^1.18.1",
3738
"serve-static": "^1.14.1",
3839
"ws": "^8.2.3",
3940
"yargs": "^17.2.1"

scripts/lib/build-options.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const path = require('path')
2-
const package = require('../../package.json')
2+
const packageJson = require('../../package.json')
33

4-
const PRODUCT_VERSION = `${package.version}.0`
4+
const PRODUCT_VERSION = `${packageJson.version}.0`
55
const APP_FILE_VERSION = PRODUCT_VERSION
66
const SERVICE_FILE_VERSION = PRODUCT_VERSION
77

src/service/main.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
const connect = require('connect')
22
const serveStatic = require('serve-static')
33
const http = require('http')
4+
const httpProxy = require('http-proxy')
5+
const proxy = httpProxy.createProxyServer({})
46
const WebSocket = require('ws')
57
const eventHandlers = require('./lib/event-handlers')
68
const yargs = require('yargs')
79

810
const commandLineArgs = yargs.argv
911
const PORT = commandLineArgs.port || process.env.PORT || 3300
1012
const WEBROOT = process.env.WEBROOT || 'build/web'
13+
const PROXY = commandLineArgs.proxy || false
1114

1215
// Start simple HTTP server and add WebSocket server
1316
const webServer = connect().use(serveStatic(WEBROOT))
14-
const httpServer = http.createServer(webServer)
17+
console.log('PROXY', PROXY)
18+
// Proxy requests if PROXY specified (i.e. in development)
19+
const httpServer = PROXY
20+
? http.createServer((req, res) => proxy.web(req, res, { target: PROXY }))
21+
: http.createServer(webServer)
22+
1523
const webSocketServer = new WebSocket.Server({ server: httpServer })
1624

1725
// Bind message event handler to WebSocket server before starting server

src/web/components/loader.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11

22
export default function Loader ({ visible }) {
3-
if (!visible) return null
43
return (
5-
<div id='loader'>
4+
<div id='loader' style={{ opacity: visible ? 1 : 0 }}>
65
<div className='loader__row'>
76
<div className='loader__arrow loader__arrow--outer-18' />
87
<div className='loader__arrow loader__arrow--down lloader__arrow--outer-17' />

src/web/components/panel.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
export default function Panel ({ children, visible }) {
3+
return (
4+
<div className='panel' style={{ opacity: visible ? 1 : 0 }}>
5+
{children}
6+
</div>
7+
)
8+
}
9+
10+
Panel.defaultProps = {
11+
visible: true
12+
}

src/web/components/socket.js

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* global WebSocket */
2+
import { createContext, useState, useContext } from 'react'
3+
4+
let socket
5+
6+
const defaultSocketState = {
7+
connected: false
8+
}
9+
10+
// function sendEvent (name, message = null) {
11+
// if (socket) {
12+
// socket.send(JSON.stringify({ name, message }))
13+
// }
14+
// }
15+
16+
function connect (socketState, setSocketState) {
17+
socket = new WebSocket('ws://' + window.location.host)
18+
socket.onmessage = (event) => {
19+
const { name, message } = JSON.parse(event.data)
20+
console.log('message received', name, message)
21+
}
22+
socket.onopen = (e) => {
23+
console.log('Connected to socket server')
24+
setSocketState({
25+
...socketState,
26+
connected: true
27+
})
28+
}
29+
socket.onclose = (e) => {
30+
console.log('Disconnected from socket server')
31+
setSocketState({
32+
...socketState,
33+
connected: false
34+
})
35+
}
36+
}
37+
38+
const SocketContext = createContext()
39+
40+
export function Socket ({ children }) {
41+
const [socketState, setSocketState] = useState(defaultSocketState)
42+
43+
if (typeof WebSocket !== 'undefined' && socketState.connected !== true) {
44+
connect(socketState, setSocketState)
45+
}
46+
47+
return (
48+
<SocketContext.Provider value={socketState}>
49+
{children}
50+
</SocketContext.Provider>
51+
)
52+
}
53+
54+
export function useSocket () {
55+
return useContext(SocketContext)
56+
}
File renamed without changes.
File renamed without changes.

src/web/public/css/main.css renamed to src/web/css/main.css

+7-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
@font-face {
88
font-family: 'Jura';
9-
src: url('../fonts/Jura-VariableFont_wght.ttf') format('truetype');
9+
src: url('../public/fonts/Jura-VariableFont_wght.ttf') format('truetype');
1010
}
1111

1212
* {
13-
cursor: url('../images/cursor.png'), crosshair;
13+
cursor: url('../public/images/cursor.png'), crosshair;
1414
}
1515

1616
::selection {
@@ -105,10 +105,14 @@ html, body {
105105
}
106106

107107
#main {
108-
transition: .25s ease-in-out;
109108
z-index: 10;
110109
}
111110

111+
.panel {
112+
transition: .25s ease-in-out;
113+
opacity: 0;
114+
}
115+
112116
h1 {
113117
margin: .25rem 0;
114118
}
File renamed without changes.
File renamed without changes.

src/web/lib/window.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function toggleFullScreen () {
2+
if (typeof window.app_toggleFullScreen === 'function') { return window.app_toggleFullScreen() }
3+
4+
if (!document.fullscreenElement) {
5+
document.documentElement.requestFullscreen()
6+
} else {
7+
if (document.exitFullscreen) {
8+
document.exitFullscreen()
9+
}
10+
}
11+
}
12+
13+
function closeWindow () {
14+
if (typeof window.app_quit === 'function') { return window.app_quit() }
15+
16+
window.close()
17+
}
18+
19+
module.exports = {
20+
toggleFullScreen,
21+
closeWindow
22+
}

src/web/pages/_app.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import '../public/css/main.css'
2-
import Loader from 'components/loader'
1+
import '../css/main.css'
2+
import { Socket } from 'components/socket'
33

44
export default function MyApp ({ Component, pageProps }) {
55
return (
6-
<>
7-
<Loader />
6+
<Socket>
87
<Component {...pageProps} />
9-
</>
8+
</Socket>
109
)
1110
}

src/web/pages/index.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { toggleFullScreen, closeWindow } from 'lib/window'
2+
import { useSocket } from 'components/socket'
3+
import Loader from 'components/loader'
4+
import Panel from 'components/panel'
5+
6+
export default function IndexPage () {
7+
const { connected } = useSocket()
8+
return (
9+
<>
10+
<Loader visible={!connected} />
11+
<Panel visible={connected}>
12+
<h3>ICARUS Terminal</h3>
13+
<p>
14+
<button onClick={toggleFullScreen}>Toggle Fullscreen</button>
15+
</p>
16+
<p>
17+
<button onClick={closeWindow}>Close Terminal</button>
18+
</p>
19+
</Panel>
20+
</>
21+
)
22+
}

0 commit comments

Comments
 (0)