From bb36996194492db6cc17f9cfd91769f31df7003b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 18 Apr 2018 14:20:57 +0300 Subject: Add support for sending Markdown messages --- ui/message-view.go | 32 +++++++++++++++++++++++--------- ui/messages/base.go | 19 ------------------- ui/messages/expandedtextmessage.go | 15 +-------------- ui/messages/imagemessage.go | 12 ------------ ui/messages/meta.go | 14 ++------------ ui/messages/parser/htmlparser.go | 14 ++++++++++++-- ui/messages/parser/parser.go | 2 +- ui/messages/textmessage.go | 12 ------------ ui/view-main.go | 2 +- 9 files changed, 40 insertions(+), 82 deletions(-) (limited to 'ui') 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)) -- cgit v1.2.3