Files
odroid-power-mate/example/powermate-console-frontend/terminal.go
2025-12-16 06:16:48 +09:00

84 lines
1.6 KiB
Go

package main
import (
"fmt"
"os"
tea "github.com/charmbracelet/bubbletea"
"github.com/gorilla/websocket"
"golang.org/x/term"
"google.golang.org/protobuf/proto"
"odroid-tui/pb"
)
func startRawTerminal(m *model) tea.Cmd {
return func() tea.Msg {
fd := int(os.Stdin.Fd())
oldState, err := term.MakeRaw(fd)
if err != nil {
return err
}
defer term.Restore(fd, oldState)
fmt.Print("\033[2J\033[H")
fmt.Printf("\r\n\033[32m--- Terminal Connected (Ctrl+A to exit) ---\033[0m\r\n")
u := fmt.Sprintf("ws://%s/ws?token=%s", m.connDetails.IP, m.connDetails.Token)
ws, _, err := websocket.DefaultDialer.Dial(u, nil)
if err != nil {
return err
}
defer ws.Close()
done := make(chan struct{})
sendChan := make(chan []byte, 256)
go func() {
for d := range sendChan {
ws.WriteMessage(websocket.BinaryMessage, d)
}
}()
go func() {
for {
_, msg, err := ws.ReadMessage()
if err != nil {
close(done)
return
}
var st pb.StatusMessage
if proto.Unmarshal(msg, &st) == nil {
if u := st.GetUartData(); u != nil {
os.Stdout.Write(u.GetData())
}
} else {
os.Stdout.Write(msg)
}
}
}()
buf := make([]byte, 1024)
for {
n, err := os.Stdin.Read(buf)
if err != nil {
close(sendChan)
return TerminalFinishedMsg{}
}
if n > 0 {
for i := 0; i < n; i++ {
if buf[i] == 1 {
ws.Close()
return TerminalFinishedMsg{}
}
}
d := make([]byte, n)
copy(d, buf[:n])
sendChan <- d
}
select {
case <-done:
close(sendChan)
return TerminalFinishedMsg{}
default:
}
}
}
}