diff options
-rw-r--r-- | interface/matrix.go | 1 | ||||
-rw-r--r-- | interface/ui.go | 1 | ||||
-rw-r--r-- | matrix/matrix.go | 25 | ||||
-rw-r--r-- | ui/message-view.go | 32 | ||||
-rw-r--r-- | ui/messages/base.go | 19 | ||||
-rw-r--r-- | ui/messages/expandedtextmessage.go | 15 | ||||
-rw-r--r-- | ui/messages/imagemessage.go | 12 | ||||
-rw-r--r-- | ui/messages/meta.go | 14 | ||||
-rw-r--r-- | ui/messages/parser/htmlparser.go | 14 | ||||
-rw-r--r-- | ui/messages/parser/parser.go | 2 | ||||
-rw-r--r-- | ui/messages/textmessage.go | 12 | ||||
-rw-r--r-- | ui/view-main.go | 2 |
12 files changed, 66 insertions, 83 deletions
diff --git a/interface/matrix.go b/interface/matrix.go index 3a1ec14..b53adca 100644 --- a/interface/matrix.go +++ b/interface/matrix.go @@ -29,6 +29,7 @@ type MatrixContainer interface { Start() Stop() SendMessage(roomID, msgtype, message string) (string, error) + SendMarkdownMessage(roomID, msgtype, message string) (string, error) SendTyping(roomID string, typing bool) JoinRoom(roomID string) error LeaveRoom(roomID string) error diff --git a/interface/ui.go b/interface/ui.go index 27212af..271dbd2 100644 --- a/interface/ui.go +++ b/interface/ui.go @@ -89,7 +89,6 @@ type MessageMeta interface { Timestamp() time.Time FormatTime() string FormatDate() string - CopyFrom(from MessageMeta) } // MessageState is an enum to specify if a Message is being sent, failed to send or was successfully sent. diff --git a/matrix/matrix.go b/matrix/matrix.go index 3a37e64..3c97dbb 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -31,6 +31,7 @@ import ( "strings" "time" + "gopkg.in/russross/blackfriday.v2" "maunium.net/go/gomatrix" "maunium.net/go/gomuks/config" "maunium.net/go/gomuks/debug" @@ -326,6 +327,30 @@ func (c *Container) SendMessage(roomID, msgtype, text string) (string, error) { return resp.EventID, nil } +func (c *Container) SendMarkdownMessage(roomID, msgtype, text string) (string, error) { + defer c.gmx.Recover() + + html := string(blackfriday.Run([]byte(text))) + if html == text { + return c.SendMessage(roomID, msgtype, text) + } + debug.Print(html) + debug.Print(text) + + c.SendTyping(roomID, false) + resp, err := c.client.SendMessageEvent(roomID, "m.room.message", + map[string]interface{}{ + "msgtype": msgtype, + "body": text, + "format": "org.matrix.custom.html", + "formatted_body": html, + }) + if err != nil { + return "", err + } + return resp.EventID, nil +} + // SendTyping sets whether or not the user is typing in the given room. func (c *Container) SendTyping(roomID string, typing bool) { defer c.gmx.Recover() diff --git a/ui/message-view.go b/ui/message-view.go index b78f135..4b67c6a 100644 --- a/ui/message-view.go +++ b/ui/message-view.go @@ -162,8 +162,7 @@ func (view *MessageView) AddMessage(ifcMessage ifc.Message, direction ifc.Messag oldMsg, messageExists := view.messageIDs[message.ID()] if messageExists { - oldMsg.CopyFrom(message) - message = oldMsg + view.replaceMessage(oldMsg, message) direction = ifc.IgnoreMessage } @@ -181,8 +180,10 @@ func (view *MessageView) AddMessage(ifcMessage ifc.Message, direction ifc.Messag view.appendBuffer(message) } else if direction == ifc.PrependMessage { view.messages = append([]messages.UIMessage{message}, view.messages...) + } else if oldMsg != nil { + view.replaceBuffer(oldMsg, message) } else { - view.replaceBuffer(message) + view.replaceBuffer(message, message) } view.messageIDs[message.ID()] = message @@ -207,11 +208,20 @@ func (view *MessageView) appendBuffer(message messages.UIMessage) { view.prevMsgCount++ } -func (view *MessageView) replaceBuffer(message messages.UIMessage) { +func (view *MessageView) replaceMessage(original messages.UIMessage, new messages.UIMessage) { + view.messageIDs[new.ID()] = new + for index, msg := range view.messages { + if msg == original { + view.messages[index] = new + } + } +} + +func (view *MessageView) replaceBuffer(original messages.UIMessage, new messages.UIMessage) { start := -1 end := -1 for index, meta := range view.metaBuffer { - if meta == message { + if meta == original { if start == -1 { start = index } @@ -225,13 +235,17 @@ func (view *MessageView) replaceBuffer(message messages.UIMessage) { end++ } - view.textBuffer = append(append(view.textBuffer[0:start], message.Buffer()...), view.textBuffer[end:]...) - if len(message.Buffer()) != end-start+1 { + view.textBuffer = append(append(view.textBuffer[0:start], new.Buffer()...), view.textBuffer[end:]...) + if len(new.Buffer()) != end-start+1 { metaBuffer := view.metaBuffer[0:start] - for range message.Buffer() { - metaBuffer = append(metaBuffer, message) + for range new.Buffer() { + metaBuffer = append(metaBuffer, new) } view.metaBuffer = append(metaBuffer, view.metaBuffer[end:]...) + } else { + for i := start; i < end; i++ { + view.metaBuffer[i] = new + } } } diff --git a/ui/messages/base.go b/ui/messages/base.go index 50f2735..5322b34 100644 --- a/ui/messages/base.go +++ b/ui/messages/base.go @@ -61,25 +61,6 @@ func newBaseMessage(id, sender, displayname, msgtype string, timestamp time.Time func (msg *BaseMessage) RegisterGomuks(gmx ifc.Gomuks) {} -// CopyFrom replaces the content of this message object with the content of the given object. -func (msg *BaseMessage) CopyFrom(from ifc.MessageMeta) { - msg.MsgSender = from.Sender() - msg.MsgSenderColor = from.SenderColor() - - fromMsg, ok := from.(UIMessage) - if ok { - msg.MsgSenderID = fromMsg.SenderID() - msg.MsgSender = fromMsg.RealSender() - msg.MsgID = fromMsg.ID() - msg.MsgType = fromMsg.Type() - msg.MsgTimestamp = fromMsg.Timestamp() - msg.MsgState = fromMsg.State() - msg.MsgIsService = fromMsg.IsService() - msg.MsgIsHighlight = fromMsg.IsHighlight() - msg.buffer = nil - } -} - // Sender gets the string that should be displayed as the sender of this message. // // If the message is being sent, the sender is "Sending...". diff --git a/ui/messages/expandedtextmessage.go b/ui/messages/expandedtextmessage.go index ec359c9..38e0afd 100644 --- a/ui/messages/expandedtextmessage.go +++ b/ui/messages/expandedtextmessage.go @@ -20,7 +20,6 @@ import ( "encoding/gob" "time" - "maunium.net/go/gomuks/interface" "maunium.net/go/gomuks/ui/messages/tstring" ) @@ -37,7 +36,7 @@ type ExpandedTextMessage struct { func NewExpandedTextMessage(id, sender, displayname, msgtype string, text tstring.TString, timestamp time.Time) UIMessage { return &ExpandedTextMessage{ BaseTextMessage: newBaseTextMessage(id, sender, displayname, msgtype, timestamp), - MsgText: text, + MsgText: text, } } @@ -45,18 +44,6 @@ func (msg *ExpandedTextMessage) GenerateText() tstring.TString { return msg.MsgText } -// CopyFrom replaces the content of this message object with the content of the given object. -func (msg *ExpandedTextMessage) CopyFrom(from ifc.MessageMeta) { - msg.BaseTextMessage.CopyFrom(from) - - fromExpandedMsg, ok := from.(*ExpandedTextMessage) - if ok { - msg.MsgText = fromExpandedMsg.MsgText - } - - msg.RecalculateBuffer() -} - func (msg *ExpandedTextMessage) NotificationContent() string { return msg.MsgText.String() } diff --git a/ui/messages/imagemessage.go b/ui/messages/imagemessage.go index 7478876..cd8c2fe 100644 --- a/ui/messages/imagemessage.go +++ b/ui/messages/imagemessage.go @@ -85,18 +85,6 @@ func (msg *ImageMessage) Path() string { return msg.gmx.Matrix().GetCachePath(msg.Homeserver, msg.FileID) } -// CopyFrom replaces the content of this message object with the content of the given object. -func (msg *ImageMessage) CopyFrom(from ifc.MessageMeta) { - msg.BaseMessage.CopyFrom(from) - - fromImgMsg, ok := from.(*ImageMessage) - if ok { - msg.data = fromImgMsg.data - } - - msg.RecalculateBuffer() -} - // CalculateBuffer generates the internal buffer for this message that consists // of the text of this message split into lines at most as wide as the width // parameter. diff --git a/ui/messages/meta.go b/ui/messages/meta.go index 7e2f29f..3a1dd19 100644 --- a/ui/messages/meta.go +++ b/ui/messages/meta.go @@ -20,13 +20,12 @@ import ( "time" "maunium.net/go/tcell" - "maunium.net/go/gomuks/interface" ) // BasicMeta is a simple variable store implementation of MessageMeta. type BasicMeta struct { - BSender string - BTimestamp time.Time + BSender string + BTimestamp time.Time BSenderColor, BTextColor, BTimestampColor tcell.Color } @@ -66,12 +65,3 @@ func (meta *BasicMeta) TextColor() tcell.Color { func (meta *BasicMeta) TimestampColor() tcell.Color { return meta.BTimestampColor } - -// CopyFrom replaces the content of this meta object with the content of the given object. -func (meta *BasicMeta) CopyFrom(from ifc.MessageMeta) { - meta.BSender = from.Sender() - meta.BTimestamp = from.Timestamp() - meta.BSenderColor = from.SenderColor() - meta.BTextColor = from.TextColor() - meta.BTimestampColor = from.TimestampColor() -} diff --git a/ui/messages/parser/htmlparser.go b/ui/messages/parser/htmlparser.go index 4f3522a..5e3b289 100644 --- a/ui/messages/parser/htmlparser.go +++ b/ui/messages/parser/htmlparser.go @@ -37,6 +37,9 @@ var matrixToURL = regexp.MustCompile("^(?:https?://)?(?:www\\.)?matrix\\.to/#/([ type MatrixHTMLProcessor struct { text tstring.TString + sender string + msgtype string + indent string listType string lineIsNew bool @@ -52,7 +55,11 @@ func (parser *MatrixHTMLProcessor) newline() { } } -func (parser *MatrixHTMLProcessor) Preprocess() {} +func (parser *MatrixHTMLProcessor) Preprocess() { + if parser.msgtype == "m.emote" { + parser.text = tstring.NewColorTString(fmt.Sprintf("* %s ", parser.sender), widget.GetHashColor(parser.sender)) + } +} func (parser *MatrixHTMLProcessor) HandleText(text string) { style := tcell.StyleDefault @@ -170,12 +177,15 @@ func (parser *MatrixHTMLProcessor) Postprocess() { } // ParseHTMLMessage parses a HTML-formatted Matrix event into a UIMessage. -func ParseHTMLMessage(room *rooms.Room, evt *gomatrix.Event) tstring.TString { +func ParseHTMLMessage(room *rooms.Room, evt *gomatrix.Event, senderDisplayname string) tstring.TString { htmlData, _ := evt.Content["formatted_body"].(string) + msgtype, _ := evt.Content["msgtype"].(string) processor := &MatrixHTMLProcessor{ room: room, text: tstring.NewBlankTString(), + msgtype: msgtype, + sender: senderDisplayname, indent: "", listType: "", lineIsNew: true, diff --git a/ui/messages/parser/parser.go b/ui/messages/parser/parser.go index 58b0248..d12383a 100644 --- a/ui/messages/parser/parser.go +++ b/ui/messages/parser/parser.go @@ -60,7 +60,7 @@ func ParseMessage(gmx ifc.Gomuks, room *rooms.Room, evt *gomatrix.Event) message case "m.text", "m.notice", "m.emote": format, hasFormat := evt.Content["format"].(string) if hasFormat && format == "org.matrix.custom.html" { - text := ParseHTMLMessage(room, evt) + text := ParseHTMLMessage(room, evt, displayname) return messages.NewExpandedTextMessage(evt.ID, evt.Sender, displayname, msgtype, text, ts) } else { text, _ := evt.Content["body"].(string) diff --git a/ui/messages/textmessage.go b/ui/messages/textmessage.go index 489e8a7..5139e07 100644 --- a/ui/messages/textmessage.go +++ b/ui/messages/textmessage.go @@ -56,18 +56,6 @@ func (msg *TextMessage) getCache() tstring.TString { return msg.cache } -// CopyFrom replaces the content of this message object with the content of the given object. -func (msg *TextMessage) CopyFrom(from ifc.MessageMeta) { - msg.BaseTextMessage.CopyFrom(from) - - fromTextMsg, ok := from.(*TextMessage) - if ok { - msg.MsgText = fromTextMsg.MsgText - } - - msg.cache = nil - msg.RecalculateBuffer() -} func (msg *TextMessage) SetType(msgtype string) { msg.BaseTextMessage.SetType(msgtype) msg.cache = nil diff --git a/ui/view-main.go b/ui/view-main.go index 018fb1a..f54654a 100644 --- a/ui/view-main.go +++ b/ui/view-main.go @@ -144,7 +144,7 @@ func (view *MainView) SendMessage(roomView *RoomView, text string) { func (view *MainView) sendTempMessage(roomView *RoomView, tempMessage ifc.Message, text string) { defer view.gmx.Recover() - eventID, err := view.matrix.SendMessage(roomView.Room.ID, tempMessage.Type(), text) + eventID, err := view.matrix.SendMarkdownMessage(roomView.Room.ID, tempMessage.Type(), text) if err != nil { tempMessage.SetState(ifc.MessageStateFailed) roomView.SetStatus(fmt.Sprintf("Failed to send message: %s", err)) |