finish up minimal replacement for admin console with no deps

This commit is contained in:
Ted Unangst 2019-11-10 19:13:28 -05:00
parent 9e6a0c7581
commit e165a7877c
1 changed files with 131 additions and 6 deletions

137
admin.go
View File

@ -20,6 +20,7 @@ package main
*/
import "C"
import (
"bufio"
"fmt"
"io/ioutil"
"log"
@ -28,27 +29,72 @@ import (
func adminscreen() {
log.SetOutput(ioutil.Discard)
stdout := os.Stdout
stdout := bufio.NewWriter(os.Stdout)
esc := "\x1b"
smcup := esc + "[?1049h"
rmcup := esc + "[?1049l"
messages := []*struct {
name string
label string
text string
}{
{
name: "servermsg",
label: "server",
text: string(serverMsg),
},
{
name: "aboutmsg",
label: "about",
text: string(aboutMsg),
},
{
name: "loginmsg",
label: "login",
text: string(loginMsg),
},
}
cursel := 0
hidecursor := func() {
stdout.WriteString(esc + "[?25l")
}
showcursor := func() {
stdout.WriteString(esc + "[?12;25h")
}
movecursor := func(x, y int) {
stdout.WriteString(fmt.Sprintf(esc+"[%d;%dH", x, y))
stdout.WriteString(fmt.Sprintf(esc+"[%d;%dH", y, x))
}
moveleft := func() {
stdout.WriteString(esc + "[1D")
}
clearscreen := func() {
stdout.WriteString(esc + "[2J")
}
clearline := func() {
stdout.WriteString(esc + "[2K")
}
colorfn := func(code int) func(string) string {
return func(s string) string {
return fmt.Sprintf(esc+"[%dm"+"%s"+esc+"[0m", code, s)
}
}
reverse := colorfn(7)
magenta := colorfn(35)
readchar := func() byte {
var buf [1]byte
os.Stdin.Read(buf[:])
c := buf[0]
return c
}
savedtio := new(C.struct_termios)
C.tcgetattr(1, savedtio)
restore := func() {
stdout.WriteString(rmcup)
showcursor()
stdout.Flush()
C.tcsetattr(1, C.TCSAFLUSH, savedtio)
}
defer restore()
@ -63,19 +109,98 @@ func adminscreen() {
stdout.WriteString(smcup)
clearscreen()
movecursor(1, 1)
stdout.Flush()
}
msglineno := func(idx int) int {
return 4 + idx*2
}
drawmessage := func(idx int) {
line := msglineno(idx)
movecursor(4, line)
label := messages[idx].label
if idx == cursel {
label = reverse(label)
}
stdout.WriteString(fmt.Sprintf("%s %s", label, messages[idx].text))
}
drawscreen := func() {
clearscreen()
movecursor(4, msglineno(-1))
stdout.WriteString(magenta(serverName + " admin panel"))
for i := range messages {
drawmessage(i)
}
movecursor(4, msglineno(len(messages)))
stdout.WriteString(magenta("j/k to move - q to quit - enter to edit"))
stdout.Flush()
}
selectnext := func() {
if cursel < len(messages)-1 {
cursel++
}
drawscreen()
}
selectprev := func() {
if cursel > 0 {
cursel--
}
drawscreen()
}
editsel := func() {
movecursor(4, msglineno(cursel))
clearline()
m := messages[cursel]
stdout.WriteString(reverse(magenta(m.label)))
text := m.text
stdout.WriteString(" ")
stdout.WriteString(text)
showcursor()
stdout.Flush()
loop:
for {
c := readchar()
switch c {
case '\n':
break loop
case 127:
if len(text) > 0 {
moveleft()
stdout.WriteString(" ")
moveleft()
text = text[:len(text)-1]
}
default:
text = text + string(c)
stdout.WriteString(string(c))
}
stdout.Flush()
}
m.text = text
updateconfig(m.name, m.text)
hidecursor()
drawscreen()
}
init()
drawscreen()
for {
var buf [1]byte
os.Stdin.Read(buf[:])
c := buf[0]
c := readchar()
switch c {
case 'q':
return
case 'j':
selectnext()
case 'k':
selectprev()
case '\n':
editsel()
default:
os.Stdout.Write(buf[:])
}
}
}