package plays import ( "fmt" "net/http" "strings" "time" "gitea.konchin.com/ytshih/inp2025/game/models" "gitea.konchin.com/ytshih/inp2025/game/tracing" "gitea.konchin.com/ytshih/inp2025/game/types" "gitea.konchin.com/ytshih/inp2025/game/utils" tea "github.com/charmbracelet/bubbletea" "go.uber.org/zap" ) var ( lobbyChoices = []string{"Logout"} ) type Lobby struct { *Base choice string cursor int users []models.UserStatus rooms []models.Room } func NewLobby(base *Base) *Lobby { m := Lobby{ Base: base, choice: "", cursor: 0, } return &m } func (m *Lobby) Init() tea.Cmd { return tea.Sequence(tea.ClearScreen, utils.Tick(time.Second)) } func updateLobbyInfo(m *Lobby) error { resp, err := m.Base.client.R(). SetResult(&m.users). ForceContentType("application/json"). Get("/api/lobby/users") if resp.StatusCode() != http.StatusOK { tracing.Logger. Error("failed to get lobby users", zap.Error(err)) return err } _, err = m.Base.client.R(). SetResult(&m.rooms). ForceContentType("application/json"). Get("/api/lobby/rooms") if err != nil { tracing.Logger. Error("failed to get lobby rooms", zap.Error(err)) return err } return nil } func (m *Lobby) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { case "ctrl+l": return m, tea.ClearScreen case "ctrl+c", "q": return m, tea.Interrupt case "enter": m.choice = lobbyChoices[m.cursor] return m, tea.Quit case "tab", "shift+tab", "up", "down": s := msg.String() if s == "up" || s == "shift+tab" { m.cursor-- } else { m.cursor++ } if m.cursor >= len(lobbyChoices) { m.cursor = 0 } else if m.cursor < 0 { m.cursor = len(lobbyChoices) - 1 } } case types.TickMsg: go updateLobbyInfo(m) return m, utils.Tick(time.Second) } return m, nil } func (m *Lobby) View() string { var b strings.Builder fmt.Fprintf(&b, "User Status (%d):\n", len(m.users)) for _, user := range m.users { b.WriteString("- " + user.View() + "\n") } fmt.Fprintf(&b, "Room Status (%d):\n", len(m.rooms)) for _, room := range m.rooms { b.WriteString("- " + room.View() + "\n") } for i := 0; i < len(lobbyChoices); i++ { if m.cursor == i { fmt.Fprintf(&b, "(•) %s\n", lobbyChoices[i]) } else { fmt.Fprintf(&b, "( ) %s\n", lobbyChoices[i]) } } return b.String() } func (m *Lobby) Next(queue *[]*tea.Program) error { switch m.choice { case "Logout": *queue = append(*queue, tea.NewProgram(NewLogout(m.Base))) } return nil }