Add support for m.emote. Fixes #6
This commit is contained in:
parent
702a75a8c0
commit
152b89ed5e
@ -28,7 +28,7 @@ type MatrixContainer interface {
|
||||
Login(user, password string) error
|
||||
Start()
|
||||
Stop()
|
||||
SendMessage(roomID, message string) (string, error)
|
||||
SendMessage(roomID, msgtype, message string) (string, error)
|
||||
SendTyping(roomID string, typing bool)
|
||||
JoinRoom(roomID string) error
|
||||
LeaveRoom(roomID string) error
|
||||
|
@ -47,7 +47,7 @@ type MainView interface {
|
||||
SaveAllHistory()
|
||||
|
||||
SetTyping(roomID string, users []string)
|
||||
AddServiceMessage(roomID string, message string)
|
||||
AddServiceMessage(roomID *widget.RoomView, message string)
|
||||
ProcessMessageEvent(evt *gomatrix.Event) (*widget.RoomView, *types.Message)
|
||||
ProcessMembershipEvent(evt *gomatrix.Event, new bool) (*widget.RoomView, *types.Message)
|
||||
}
|
||||
|
@ -280,10 +280,11 @@ func (c *Container) HandleTyping(evt *gomatrix.Event) {
|
||||
}
|
||||
|
||||
// SendMessage sends a message with the given text to the given room.
|
||||
func (c *Container) SendMessage(roomID, text string) (string, error) {
|
||||
func (c *Container) SendMessage(roomID, msgtype, text string) (string, error) {
|
||||
defer c.gmx.Recover()
|
||||
c.SendTyping(roomID, false)
|
||||
resp, err := c.client.SendText(roomID, text)
|
||||
resp, err := c.client.SendMessageEvent(roomID, "m.room.message",
|
||||
gomatrix.TextMessage{MsgType: msgtype, Body: text})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -225,6 +225,11 @@ func (room *Room) GetMember(userID string) *Member {
|
||||
return member
|
||||
}
|
||||
|
||||
// GetSessionOwner returns the Member instance of the user whose session this room was created for.
|
||||
func (room *Room) GetSessionOwner() *Member {
|
||||
return room.GetMember(room.SessionUserID)
|
||||
}
|
||||
|
||||
// NewRoom creates a new Room with the given ID
|
||||
func NewRoom(roomID, owner string) *Room {
|
||||
return &Room{
|
||||
|
@ -17,6 +17,7 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@ -26,13 +27,15 @@ import (
|
||||
|
||||
type Message struct {
|
||||
BasicMeta
|
||||
Type string
|
||||
ID string
|
||||
Text string
|
||||
sending bool
|
||||
buffer []string
|
||||
prevBufferWidth int
|
||||
}
|
||||
|
||||
func NewMessage(id, sender, text, timestamp, date string, senderColor tcell.Color) *Message {
|
||||
func NewMessage(id, sender, msgtype, text, timestamp, date string, senderColor tcell.Color) *Message {
|
||||
return &Message{
|
||||
BasicMeta: BasicMeta{
|
||||
Sender: sender,
|
||||
@ -42,9 +45,11 @@ func NewMessage(id, sender, text, timestamp, date string, senderColor tcell.Colo
|
||||
TextColor: tcell.ColorDefault,
|
||||
TimestampColor: tcell.ColorDefault,
|
||||
},
|
||||
Type: msgtype,
|
||||
Text: text,
|
||||
ID: id,
|
||||
prevBufferWidth: 0,
|
||||
sending: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,7 +70,11 @@ func (message *Message) CalculateBuffer(width int) {
|
||||
return
|
||||
}
|
||||
message.buffer = []string{}
|
||||
forcedLinebreaks := strings.Split(message.Text, "\n")
|
||||
text := message.Text
|
||||
if message.Type == "m.emote" {
|
||||
text = fmt.Sprintf("* %s %s", message.Sender, message.Text)
|
||||
}
|
||||
forcedLinebreaks := strings.Split(text, "\n")
|
||||
newlines := 0
|
||||
for _, str := range forcedLinebreaks {
|
||||
if len(str) == 0 && newlines < 1 {
|
||||
@ -94,6 +103,22 @@ func (message *Message) CalculateBuffer(width int) {
|
||||
message.prevBufferWidth = width
|
||||
}
|
||||
|
||||
func (message *Message) GetDisplaySender() string {
|
||||
if message.sending {
|
||||
return "Sending..."
|
||||
}
|
||||
switch message.Type {
|
||||
case "m.emote":
|
||||
return ""
|
||||
default:
|
||||
return message.Sender
|
||||
}
|
||||
}
|
||||
|
||||
func (message *Message) SetIsSending(sending bool) {
|
||||
message.sending = sending
|
||||
}
|
||||
|
||||
func (message *Message) RecalculateBuffer() {
|
||||
message.CalculateBuffer(message.prevBufferWidth)
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
|
||||
type MessageMeta interface {
|
||||
GetSender() string
|
||||
GetDisplaySender() string
|
||||
GetSenderColor() tcell.Color
|
||||
GetTextColor() tcell.Color
|
||||
GetTimestampColor() tcell.Color
|
||||
@ -34,6 +35,10 @@ type BasicMeta struct {
|
||||
SenderColor, TextColor, TimestampColor tcell.Color
|
||||
}
|
||||
|
||||
func (meta *BasicMeta) GetDisplaySender() string {
|
||||
return meta.Sender
|
||||
}
|
||||
|
||||
func (meta *BasicMeta) GetSender() string {
|
||||
return meta.Sender
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ package ui
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
@ -123,42 +122,40 @@ func (view *MainView) InputSubmit(roomView *widget.RoomView, text string) {
|
||||
args := strings.SplitN(text, " ", 2)
|
||||
command := strings.ToLower(args[0])
|
||||
args = args[1:]
|
||||
go view.HandleCommand(roomView.Room.ID, command, args)
|
||||
go view.HandleCommand(roomView, command, args)
|
||||
} else {
|
||||
view.SendMessage(roomView.Room.ID, text)
|
||||
view.SendMessage(roomView, text)
|
||||
}
|
||||
roomView.SetInputText("")
|
||||
}
|
||||
|
||||
func (view *MainView) SendMessage(room, text string) {
|
||||
now := time.Now()
|
||||
roomView := view.GetRoom(room)
|
||||
tempMessage := roomView.NewMessage(
|
||||
strconv.FormatInt(now.UnixNano(), 10),
|
||||
"Sending...", text, now)
|
||||
tempMessage.TimestampColor = tcell.ColorGray
|
||||
tempMessage.TextColor = tcell.ColorGray
|
||||
tempMessage.SenderColor = tcell.ColorGray
|
||||
roomView.AddMessage(tempMessage, widget.AppendMessage)
|
||||
go func() {
|
||||
defer view.gmx.Recover()
|
||||
eventID, err := view.matrix.SendMessage(room, text)
|
||||
if err != nil {
|
||||
tempMessage.TextColor = tcell.ColorRed
|
||||
tempMessage.TimestampColor = tcell.ColorRed
|
||||
tempMessage.SenderColor = tcell.ColorRed
|
||||
tempMessage.Sender = "Error"
|
||||
roomView.SetStatus(fmt.Sprintf("Failed to send message: %s", err))
|
||||
} else {
|
||||
roomView.MessageView().UpdateMessageID(tempMessage, eventID)
|
||||
}
|
||||
}()
|
||||
func (view *MainView) SendMessage(roomView *widget.RoomView, text string) {
|
||||
tempMessage := roomView.NewTempMessage("m.text", text)
|
||||
go view.sendTempMessage(roomView, tempMessage)
|
||||
}
|
||||
|
||||
func (view *MainView) HandleCommand(room, command string, args []string) {
|
||||
func (view *MainView) sendTempMessage(roomView *widget.RoomView, tempMessage *types.Message) {
|
||||
defer view.gmx.Recover()
|
||||
eventID, err := view.matrix.SendMessage(roomView.Room.ID, tempMessage.Type, tempMessage.Text)
|
||||
if err != nil {
|
||||
tempMessage.TextColor = tcell.ColorRed
|
||||
tempMessage.TimestampColor = tcell.ColorRed
|
||||
tempMessage.SenderColor = tcell.ColorRed
|
||||
tempMessage.Sender = "Error"
|
||||
roomView.SetStatus(fmt.Sprintf("Failed to send message: %s", err))
|
||||
} else {
|
||||
roomView.MessageView().UpdateMessageID(tempMessage, eventID)
|
||||
}
|
||||
}
|
||||
|
||||
func (view *MainView) HandleCommand(roomView *widget.RoomView, command string, args []string) {
|
||||
defer view.gmx.Recover()
|
||||
debug.Print("Handling command", command, args)
|
||||
switch command {
|
||||
case "/me":
|
||||
tempMessage := roomView.NewTempMessage("m.emote", strings.Join(args, " "))
|
||||
go view.sendTempMessage(roomView, tempMessage)
|
||||
view.parent.Render()
|
||||
case "/quit":
|
||||
view.gmx.Stop()
|
||||
case "/clearcache":
|
||||
@ -169,15 +166,15 @@ func (view *MainView) HandleCommand(room, command string, args []string) {
|
||||
case "/part":
|
||||
fallthrough
|
||||
case "/leave":
|
||||
debug.Print(view.matrix.LeaveRoom(room))
|
||||
debug.Print("Leave room result:", view.matrix.LeaveRoom(roomView.Room.ID))
|
||||
case "/join":
|
||||
if len(args) == 0 {
|
||||
view.AddServiceMessage(room, "Usage: /join <room>")
|
||||
view.AddServiceMessage(roomView, "Usage: /join <room>")
|
||||
break
|
||||
}
|
||||
debug.Print(view.matrix.JoinRoom(args[0]))
|
||||
debug.Print("Join room result:", view.matrix.JoinRoom(args[0]))
|
||||
default:
|
||||
view.AddServiceMessage(room, "Unknown command.")
|
||||
view.AddServiceMessage(roomView, "Unknown command.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,13 +328,12 @@ func (view *MainView) SetTyping(room string, users []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (view *MainView) AddServiceMessage(room, message string) {
|
||||
roomView, ok := view.rooms[room]
|
||||
if ok {
|
||||
message := roomView.NewMessage("", "*", message, time.Now())
|
||||
roomView.AddMessage(message, widget.AppendMessage)
|
||||
view.parent.Render()
|
||||
}
|
||||
func (view *MainView) AddServiceMessage(roomView *widget.RoomView, text string) {
|
||||
message := roomView.NewMessage("", "*", "gomuks.service", text, time.Now())
|
||||
message.TextColor = tcell.ColorGray
|
||||
message.SenderColor = tcell.ColorGray
|
||||
roomView.AddMessage(message, widget.AppendMessage)
|
||||
view.parent.Render()
|
||||
}
|
||||
|
||||
func (view *MainView) LoadMoreHistory(room string) {
|
||||
@ -375,7 +371,7 @@ func (view *MainView) LoadHistory(room string, initial bool) {
|
||||
debug.Print("Loading history for", room, "starting from", batch, "(initial:", initial, ")")
|
||||
history, prevBatch, err := view.matrix.GetHistory(roomView.Room.ID, batch, 50)
|
||||
if err != nil {
|
||||
view.AddServiceMessage(room, "Failed to fetch history")
|
||||
view.AddServiceMessage(roomView, "Failed to fetch history")
|
||||
debug.Print("Failed to fetch history for", roomView.Room.ID, err)
|
||||
return
|
||||
}
|
||||
@ -404,7 +400,8 @@ func (view *MainView) ProcessMessageEvent(evt *gomatrix.Event) (room *widget.Roo
|
||||
room = view.GetRoom(evt.RoomID)
|
||||
if room != nil {
|
||||
text, _ := evt.Content["body"].(string)
|
||||
message = room.NewMessage(evt.ID, evt.Sender, text, unixToTime(evt.Timestamp))
|
||||
msgtype, _ := evt.Content["msgtype"].(string)
|
||||
message = room.NewMessage(evt.ID, evt.Sender, msgtype, text, unixToTime(evt.Timestamp))
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -452,7 +449,7 @@ func (view *MainView) ProcessMembershipEvent(evt *gomatrix.Event, new bool) (roo
|
||||
room = nil
|
||||
return
|
||||
}
|
||||
message = room.NewMessage(evt.ID, sender, text, unixToTime(evt.Timestamp))
|
||||
message = room.NewMessage(evt.ID, sender, "m.room.member", text, unixToTime(evt.Timestamp))
|
||||
message.TextColor = tcell.ColorGreen
|
||||
}
|
||||
return
|
||||
|
@ -74,8 +74,8 @@ func NewMessageView() *MessageView {
|
||||
}
|
||||
}
|
||||
|
||||
func (view *MessageView) NewMessage(id, sender, text string, timestamp time.Time) *types.Message {
|
||||
return types.NewMessage(id, sender, text,
|
||||
func (view *MessageView) NewMessage(id, sender, msgtype, text string, timestamp time.Time) *types.Message {
|
||||
return types.NewMessage(id, sender, msgtype, text,
|
||||
timestamp.Format(view.TimestampFormat),
|
||||
timestamp.Format(view.DateFormat),
|
||||
GetHashColor(sender))
|
||||
@ -151,6 +151,8 @@ func (view *MessageView) AddMessage(message *types.Message, direction MessageDir
|
||||
msg, messageExists := view.messageIDs[message.ID]
|
||||
if msg != nil && messageExists {
|
||||
message.CopyTo(msg)
|
||||
message = msg
|
||||
message.SetIsSending(false)
|
||||
direction = IgnoreMessage
|
||||
}
|
||||
|
||||
@ -338,9 +340,9 @@ func (view *MessageView) Draw(screen tcell.Screen) {
|
||||
if len(meta.GetTimestamp()) > 0 {
|
||||
view.writeLine(screen, meta.GetTimestamp(), x, y+line, meta.GetTimestampColor())
|
||||
}
|
||||
if len(meta.GetSender()) > 0 && (prevMeta == nil || meta.GetSender() != prevMeta.GetSender()) {
|
||||
if prevMeta == nil || meta.GetSender() != prevMeta.GetSender() {
|
||||
view.writeLineRight(
|
||||
screen, meta.GetSender(),
|
||||
screen, meta.GetDisplaySender(),
|
||||
x+usernameOffsetX, y+line,
|
||||
view.widestSender, meta.GetSenderColor())
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package widget
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -239,12 +240,25 @@ func (view *RoomView) UpdateUserList() {
|
||||
}
|
||||
}
|
||||
|
||||
func (view *RoomView) NewMessage(id, sender, text string, timestamp time.Time) *types.Message {
|
||||
func (view *RoomView) NewMessage(id, sender, msgtype, text string, timestamp time.Time) *types.Message {
|
||||
member := view.Room.GetMember(sender)
|
||||
if member != nil {
|
||||
sender = member.DisplayName
|
||||
}
|
||||
return view.content.NewMessage(id, sender, text, timestamp)
|
||||
return view.content.NewMessage(id, sender, msgtype, text, timestamp)
|
||||
}
|
||||
|
||||
func (view *RoomView) NewTempMessage(msgtype, text string) *types.Message {
|
||||
now := time.Now()
|
||||
id := strconv.FormatInt(now.UnixNano(), 10)
|
||||
sender := view.Room.GetSessionOwner().DisplayName
|
||||
message := view.NewMessage(id, sender, msgtype, text, now)
|
||||
message.SetIsSending(true)
|
||||
message.TimestampColor = tcell.ColorGray
|
||||
message.TextColor = tcell.ColorGray
|
||||
message.SenderColor = tcell.ColorGray
|
||||
view.AddMessage(message, AppendMessage)
|
||||
return message
|
||||
}
|
||||
|
||||
func (view *RoomView) AddMessage(message *types.Message, direction MessageDirection) {
|
||||
|
Loading…
Reference in New Issue
Block a user