feat: TUI room creation + daemon-side room persistence

/room <name> in the TUI sends create_room to the daemon, which persists
it in the rooms SQLite table and echoes room_created back. state_snapshot
now includes persisted rooms so they survive reconnects. Tab navigation
and room rendering pick them up automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Fredrik Johansson
2026-06-26 22:26:12 +02:00
parent 1308082c7b
commit 340735f992
4 changed files with 73 additions and 1 deletions

View File

@@ -15,6 +15,7 @@ import (
"log"
"net"
"net/http"
"strings"
"time"
"nhooyr.io/websocket"
@@ -239,6 +240,23 @@ func handleClient(conn net.Conn, mgr *netmgr.Manager) {
})
}
case proto.CmdCreateRoom:
n := mgr.Resolve(cmd.NetworkID)
if n == nil {
send(errMsg("create_room: not joined to any network"))
continue
}
name := strings.TrimSpace(cmd.Room)
if name == "" || name == "general" {
send(errMsg("create_room: room name is required and cannot be 'general'"))
continue
}
if err := n.Store.SaveRoom(name); err != nil {
send(errMsg(fmt.Sprintf("create_room: %v", err)))
continue
}
send(proto.IpcMessage{Type: proto.EvtRoomCreated, NetworkID: n.ID, Room: name})
case proto.CmdGetState:
send(stateSnapshot(mgr))
@@ -416,6 +434,11 @@ func stateSnapshot(mgr *netmgr.Manager) proto.IpcMessage {
pi := all[0].Identity.PeerInfo()
msg.LocalPeer = &pi
msg.ConnectedPeers = all[0].Mesh.ConnectedPeers()
if extra, err := all[0].Store.Rooms(); err == nil {
for _, r := range extra {
msg.Rooms = append(msg.Rooms, r)
}
}
}
return msg