Compare commits

...

4 Commits

2 changed files with 55 additions and 23 deletions

View File

@ -26,8 +26,7 @@ As a unique bonus, you can launch a full text editor from within.
xP
--
The web frontend for 'xC', making use of its networked relay interface.
So far it's quite basic, yet usable. Build it using `make` in its directory,
and run it from within the _public_ subdirectory.
So far it's quite basic, yet usable.
xF
--
@ -116,6 +115,11 @@ a Screen or tmux session.
file or something like `killall` if you want to terminate it. You can run it
as a `forking` type systemd user service.
xP
~~
Install the Go compiler, and build the server using `make` in its directory,
then run it from within the _public_ subdirectory.
Client Certificates
-------------------
'xC' will use the SASL EXTERNAL method to authenticate using the TLS client

View File

@ -24,8 +24,8 @@ class RelayRpc extends EventTarget {
}
// It's going to be code 1006 with no further info.
ws.onclose = event => {
reject()
this.ws = undefined
reject()
}
})
}
@ -122,15 +122,25 @@ class RelayRpc extends EventTarget {
// ---- Event processing -------------------------------------------------------
// TODO: Probably reset state on disconnect, and indicate to user.
let rpc = new RelayRpc(proxy)
rpc.connect()
.then(result => {
rpc.send({command: 'Hello', version: 1})
})
let buffers = new Map()
let bufferCurrent = undefined
let connecting = true
rpc.connect().then(result => {
buffers.clear()
bufferCurrent = undefined
rpc.send({command: 'Hello', version: 1})
connecting = false
m.redraw()
}).catch(error => {
connecting = false
m.redraw()
})
rpc.addEventListener('close', event => {
m.redraw()
})
rpc.addEventListener('BufferUpdate', event => {
let e = event.detail, b = buffers.get(e.bufferName)
@ -155,14 +165,18 @@ rpc.addEventListener('BufferRemove', event => {
rpc.addEventListener('BufferActivate', event => {
let e = event.detail
bufferCurrent = e.bufferName
// TODO: Somehow scroll to the end of it immediately.
// TODO: Focus the textarea.
setTimeout(() => {
let el = document.getElementById('input')
if (el !== null)
el.focus()
})
})
rpc.addEventListener('BufferLine', event => {
let e = event.detail, b = buffers.get(e.bufferName)
if (b !== undefined)
b.lines.push({when: e.when, rendition: e.rendition, items: e.items})
if (b === undefined)
return
b.lines.push({when: e.when, rendition: e.rendition, items: e.items})
})
rpc.addEventListener('BufferClear', event => {
@ -194,11 +208,11 @@ function applyColor(fg, bg, inverse) {
if (inverse)
[fg, bg] = [bg >= 0 ? bg : 15, fg >= 0 ? fg : 0]
let style = ''
let style = {}
if (fg >= 0)
style += `color: ${palette[fg]};`
style.color = palette[fg]
if (bg >= 0)
style += `background-color: ${palette[bg]};`
style.backgroundColor = palette[bg]
if (style)
return style
}
@ -295,6 +309,19 @@ let Content = {
}
let Buffer = {
oncreate: vnode => {
if (vnode.dom === undefined)
return
let el = vnode.dom.children[1]
if (el !== null)
el.scrollTop = el.scrollHeight
},
onupdate: vnode => {
Buffer.oncreate(vnode)
},
view: vnode => {
let lines = []
let b = buffers.get(bufferCurrent)
@ -365,7 +392,7 @@ function onKeyDown(event) {
// and we'll probably have to intercept /all/ key presses.
let Input = {
view: vnode => {
return m('textarea', {
return m('textarea#input', {
rows: 1,
onkeydown: onKeyDown,
})
@ -374,8 +401,14 @@ let Input = {
let Main = {
view: vnode => {
let state = "Connected"
if (connecting)
state = "Connecting..."
else if (rpc.ws === undefined)
state = "Disconnected"
return m('.xP', {}, [
m('.title', {}, "xP"),
m('.title', {}, `xP (${state})`),
m('.middle', {}, [m(BufferList), m(Buffer)]),
m('.status', {}, bufferCurrent),
m(Input),
@ -383,9 +416,4 @@ let Main = {
},
}
// TODO: Buffer names should work as routes.
window.addEventListener('load', () => {
m.route(document.body, '/', {
'/': Main,
})
})
window.addEventListener('load', () => m.mount(document.body, Main))