Compare commits
4 Commits
8cd94b30f6
...
93b66b6a26
Author | SHA1 | Date | |
---|---|---|---|
93b66b6a26 | |||
ee1750c23c | |||
f5104c807d | |||
2c49a72d94 |
@ -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
|
||||
|
@ -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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user