Skip to content

Commit

Permalink
add config command for chat TUI
Browse files Browse the repository at this point in the history
  • Loading branch information
qnkhuat committed Jul 14, 2021
1 parent 079b50e commit eccc230
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 35 deletions.
8 changes: 7 additions & 1 deletion tstream/pkg/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const (
TError MType = "Error"
TRoomInfo MType = "RoomInfo"
TClientInfo MType = "ClientInfo"
TRoomUpdate MType = "RoomUpdate"

// When streamer resize their termianl
TWinsize MType = "Winsize"
Expand Down Expand Up @@ -63,7 +64,7 @@ type Chat struct {
Content string
Color string
Time string
Role string
Role CRole
}

// *** Room ***
Expand All @@ -87,6 +88,11 @@ type RoomInfo struct {
Status RoomStatus
}

// used for streamer to update room info
type RoomUpdate struct {
Title string
}

// *** Client ***
// Client Roles
type CRole string
Expand Down
72 changes: 58 additions & 14 deletions tstream/pkg/room/room.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ func (r *Room) Start() {
continue
}

if wrapperMsg.Type == message.TWinsize {
switch msgType := wrapperMsg.Type; msgType {
case message.TWinsize:
winsize := &message.Winsize{}
err := json.Unmarshal(wrapperMsg.Data, winsize)
if err == nil {
Expand All @@ -207,13 +208,15 @@ func (r *Room) Start() {

r.addMsgBuffer(msg)
r.lastActiveTime = time.Now()
r.Broadcast(msg, message.RViewer, []string{})
r.Broadcast(msg, []message.CRole{message.RViewer}, []string{})

case message.TWrite:

} else if wrapperMsg.Type == message.TWrite {
r.addMsgBuffer(msg)
r.lastActiveTime = time.Now()
r.Broadcast(msg, message.RViewer, []string{})
} else {
r.Broadcast(msg, []message.CRole{message.RViewer}, []string{})

default:
log.Printf("Unknown message type: %s", wrapperMsg.Type)
}
}
Expand Down Expand Up @@ -246,7 +249,8 @@ func (r *Room) ReadAndHandleClientMessage(ID string) {
log.Printf("Failed to decode msg", err)
}

if msgObj.Type == message.TRequestWinsize {
switch msgType := msgObj.Type; msgType {
case message.TRequestWinsize:

msg, _ := message.Wrap(message.TWinsize, message.Winsize{
Rows: r.lastWinsize.Rows,
Expand All @@ -255,12 +259,13 @@ func (r *Room) ReadAndHandleClientMessage(ID string) {
payload, _ := json.Marshal(msg)
client.Out <- payload

} else if msgObj.Type == message.TRequestCacheContent {
case message.TRequestCacheContent:
// Send msg buffer so clients doesn't face a idle screen when first started
for _, msg := range r.msgBuffer {
client.Out <- msg
}
} else if msgObj.Type == message.TRequestRoomInfo {

case message.TRequestRoomInfo:

roomInfo := r.PrepareRoomInfo()
msg, err := message.Wrap(message.TRoomInfo, roomInfo)
Expand All @@ -271,7 +276,7 @@ func (r *Room) ReadAndHandleClientMessage(ID string) {
} else {
log.Printf("Error wrapping room info message: %s", err)
}
} else if msgObj.Type == message.TRequestCacheChat {
case message.TRequestCacheChat:

msg, err := message.Wrap(message.TChat, r.cacheChat)
if err == nil {
Expand All @@ -281,7 +286,7 @@ func (r *Room) ReadAndHandleClientMessage(ID string) {
log.Printf("Error wrapping room info message: %s", err)
}

} else if msgObj.Type == message.TChat {
case message.TChat:

var chatList []message.Chat
err := json.Unmarshal(msgObj.Data, &chatList)
Expand All @@ -300,21 +305,60 @@ func (r *Room) ReadAndHandleClientMessage(ID string) {

if err == nil {
payload, _ := json.Marshal(msg)
r.Broadcast(payload, message.RViewer, []string{ID})
r.Broadcast(payload, message.RStreamerChat, []string{ID})
r.Broadcast(payload, []message.CRole{message.RViewer, message.RStreamerChat}, []string{ID})
} else {
log.Printf("Failed to wrap message")
}
case message.TRoomUpdate:
if client.Role() != message.RStreamerChat && client.Role() != message.RStreamer {
log.Printf("Unauthorized set room title")
continue
}

newRoomInfo := message.RoomUpdate{}
err := json.Unmarshal(msgObj.Data, &newRoomInfo)
if err != nil {
log.Printf("Failed to decode roominfo: %s", err)
continue
} else {
r.title = newRoomInfo.Title
roomInfo := r.PrepareRoomInfo()
msg, err := message.Wrap(message.TRoomInfo, roomInfo)
if err != nil {
log.Printf("Failed to wrap roominfo message")
continue
}

payload, _ := json.Marshal(msg)
// Broadcast to all participants
r.Broadcast(payload,
[]message.CRole{message.RStreamer, message.RStreamerChat, message.RViewer},
[]string{})
}

default:
log.Printf("Unknown message type :%s", msgType)

}
}
}

func (r *Room) Broadcast(msg []uint8, role message.CRole, IDExclude []string) {
func (r *Room) Broadcast(msg []uint8, roles []message.CRole, IDExclude []string) {

for id, client := range r.clients {
if client.Role() != role {
// Check if client is in the list of roles to broadcast
found := false
for _, role := range roles {
if role == client.Role() {
found = true
break
}
}

if !found {
continue
}

// TODO: make this for loop run in parallel
var isExcluded bool = false
for _, idExclude := range IDExclude {
Expand Down
95 changes: 75 additions & 20 deletions tstream/pkg/streamer/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ func (c *Chat) Start() error {
err := c.connectWS()
if err != nil {
log.Printf("Error: %s", err)
fmt.Printf("Failed to connect to server\n")
c.app.Stop()
return err
}

// Receive
Expand Down Expand Up @@ -179,30 +182,33 @@ func (c *Chat) initUI() error {
messageInput.SetLabel("[red]>[red] ").
SetDoneFunc(func(key tcell.Key) {
text := messageInput.GetText()
if text == "/exit" {
c.Stop()
if len(text) > 0 && text[0] == '/' {
command := strings.TrimSpace(strings.ToLower(text[1:]))
c.HandleCommand(command)
messageInput.SetText("")
return
}

chat := message.Chat{
Name: c.username,
Color: c.color,
Content: text,
Time: time.Now().String(),
Role: "Streamer",
}
} else {
chat := message.Chat{
Name: c.username,
Color: c.color,
Content: text,
Time: time.Now().String(),
Role: message.RStreamer,
}

chatList := []message.Chat{chat}
msg, err := message.Wrap(message.TChat, chatList)
chatList := []message.Chat{chat}
msg, err := message.Wrap(message.TChat, chatList)

if err == nil {
payload, _ := json.Marshal(msg)
c.conn.WriteMessage(websocket.TextMessage, payload)
} else {
log.Printf("Failed to wrap message")
if err == nil {
payload, _ := json.Marshal(msg)
c.conn.WriteMessage(websocket.TextMessage, payload)
} else {
log.Printf("Failed to wrap message")
}
c.addChatMsgs(chatList)
messageInput.SetText("")
}
c.addChatMsgs(chatList)
messageInput.SetText("")

})

layout.AddItem(header, 0, 0, 1, 1, 0, 0, false).
Expand All @@ -213,6 +219,41 @@ func (c *Chat) initUI() error {
return nil
}

func (c *Chat) HandleCommand(command string) error {
args := strings.Split(command, " ")
switch args[0] {
case "help":
c.addNoti(`
TStream - Streaming from terimnal
[green]/title[yellow] title[white] - to change stream title
[green]/exit[white] - to exit chat room`)
case "title":
if len(args) > 1 {
newTitle := strings.Trim(strings.Join(args[1:], " "), "\"")
msg := message.RoomUpdate{
Title: newTitle,
}
wrappedMsg, _ := message.Wrap(message.TRoomUpdate, msg)
payload, _ := json.Marshal(wrappedMsg)
err := c.conn.WriteMessage(websocket.TextMessage, payload)
if err != nil {
log.Printf("Failed to set new title : %s", err)
c.addNoti(`[red]Faield to change title. Please try again[white]`)
}
} else {
c.addNoti(`[yellow]/title : no title found[white]`)
}
case "exit":
c.Stop()

default:
c.addNoti(`Unknown command. Type /help to get list of available commands.`)
}

return nil
}

func (c *Chat) connectWS() error {
scheme := "wss"
if strings.HasPrefix(c.serverAddr, "http://") {
Expand Down Expand Up @@ -256,6 +297,20 @@ func (c *Chat) connectWS() error {
return nil
}

func (c *Chat) addNoti(msg string) {

if len(msg) > 0 && msg[len(msg)-1] != '\n' {
msg += "\n"
}

currentChat := c.chatTextView.GetText(false)
if len(currentChat) > 1 && currentChat[len(currentChat)-1] == '\n' {
currentChat = currentChat[0 : len(currentChat)-1]
}

c.chatTextView.SetText(currentChat + msg)
}

func (c *Chat) addChatMsgs(chatList []message.Chat) {
if len(chatList) == 0 {
return
Expand Down

0 comments on commit eccc230

Please sign in to comment.