aboutsummaryrefslogtreecommitdiff
path: root/ui/messages
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2019-04-09 18:45:41 +0300
committerTulir Asokan <tulir@maunium.net>2019-04-09 18:45:41 +0300
commitdbee49476d47bb391dc6af0b774f9fd101b0c917 (patch)
treeb694605cc84a2e7d430e1b809cec51dfc3141bea /ui/messages
parent2b6c435e5020535a916e23b09d47608d788eaf05 (diff)
Start refactoring various things in message rendering and sending
Diffstat (limited to 'ui/messages')
-rw-r--r--ui/messages/base.go74
-rw-r--r--ui/messages/expandedtextmessage.go11
-rw-r--r--ui/messages/htmlmessage.go5
-rw-r--r--ui/messages/imagemessage.go10
-rw-r--r--ui/messages/message.go8
-rw-r--r--ui/messages/meta.go71
-rw-r--r--ui/messages/parser.go62
-rw-r--r--ui/messages/textmessage.go21
8 files changed, 82 insertions, 180 deletions
diff --git a/ui/messages/base.go b/ui/messages/base.go
index d045e42..b8b1694 100644
--- a/ui/messages/base.go
+++ b/ui/messages/base.go
@@ -17,7 +17,7 @@
package messages
import (
- "encoding/gob"
+ "encoding/json"
"time"
"maunium.net/go/mautrix"
@@ -29,38 +29,51 @@ import (
"maunium.net/go/gomuks/ui/widget"
)
-func init() {
- gob.Register(&BaseMessage{})
-}
-
type BaseMessage struct {
MsgID string
+ MsgTxnID string
MsgType mautrix.MessageType
MsgSenderID string
MsgSender string
MsgSenderColor tcell.Color
MsgTimestamp time.Time
- MsgState ifc.MessageState
+ MsgState mautrix.OutgoingEventState
MsgIsHighlight bool
MsgIsService bool
+ MsgSource json.RawMessage
buffer []tstring.TString
plainBuffer []tstring.TString
}
-func newBaseMessage(id, sender, displayname string, msgtype mautrix.MessageType, timestamp time.Time) BaseMessage {
+func newBaseMessage(event *mautrix.Event, displayname string) BaseMessage {
+ msgtype := event.Content.MsgType
+ if len(msgtype) == 0 {
+ msgtype = mautrix.MessageType(event.Type.String())
+ }
+
return BaseMessage{
- MsgSenderID: sender,
+ MsgSenderID: event.Sender,
MsgSender: displayname,
- MsgTimestamp: timestamp,
- MsgSenderColor: widget.GetHashColor(sender),
+ MsgTimestamp: unixToTime(event.Timestamp),
+ MsgSenderColor: widget.GetHashColor(event.Sender),
MsgType: msgtype,
- MsgID: id,
- MsgState: ifc.MessageStateDefault,
+ MsgID: event.ID,
+ MsgTxnID: event.Unsigned.TransactionID,
+ MsgState: event.Unsigned.OutgoingState,
MsgIsHighlight: false,
MsgIsService: false,
+ MsgSource: event.Content.VeryRaw,
}
}
+func unixToTime(unix int64) time.Time {
+ timestamp := time.Now()
+ if unix != 0 {
+ timestamp = time.Unix(unix/1000, unix%1000*1000)
+ }
+ return timestamp
+}
+
func (msg *BaseMessage) RegisterMatrix(matrix ifc.MatrixContainer) {}
// Sender gets the string that should be displayed as the sender of this message.
@@ -71,9 +84,9 @@ func (msg *BaseMessage) RegisterMatrix(matrix ifc.MatrixContainer) {}
// In any other case, the sender is the display name of the user who sent the message.
func (msg *BaseMessage) Sender() string {
switch msg.MsgState {
- case ifc.MessageStateSending:
+ case mautrix.EventStateLocalEcho:
return "Sending..."
- case ifc.MessageStateFailed:
+ case mautrix.EventStateSendFail:
return "Error"
}
switch msg.MsgType {
@@ -93,13 +106,17 @@ func (msg *BaseMessage) RealSender() string {
return msg.MsgSender
}
+func (msg *BaseMessage) NotificationSenderName() string {
+ return msg.MsgSender
+}
+
func (msg *BaseMessage) getStateSpecificColor() tcell.Color {
switch msg.MsgState {
- case ifc.MessageStateSending:
+ case mautrix.EventStateLocalEcho:
return tcell.ColorGray
- case ifc.MessageStateFailed:
+ case mautrix.EventStateSendFail:
return tcell.ColorRed
- case ifc.MessageStateDefault:
+ case mautrix.EventStateDefault:
fallthrough
default:
return tcell.ColorDefault
@@ -154,17 +171,6 @@ func (msg *BaseMessage) TimestampColor() tcell.Color {
return msg.getStateSpecificColor()
}
-// Buffer returns the computed text buffer.
-//
-// The buffer contains the text of the message split into lines with a maximum
-// width of whatever was provided to CalculateBuffer().
-//
-// N.B. This will NOT automatically calculate the buffer if it hasn't been
-// calculated already, as that requires the target width.
-func (msg *BaseMessage) Buffer() []tstring.TString {
- return msg.buffer
-}
-
// Height returns the number of rows in the computed buffer (see Buffer()).
func (msg *BaseMessage) Height() int {
return len(msg.buffer)
@@ -197,15 +203,11 @@ func (msg *BaseMessage) Type() mautrix.MessageType {
return msg.MsgType
}
-func (msg *BaseMessage) SetType(msgtype mautrix.MessageType) {
- msg.MsgType = msgtype
-}
-
-func (msg *BaseMessage) State() ifc.MessageState {
+func (msg *BaseMessage) State() mautrix.OutgoingEventState {
return msg.MsgState
}
-func (msg *BaseMessage) SetState(state ifc.MessageState) {
+func (msg *BaseMessage) SetState(state mautrix.OutgoingEventState) {
msg.MsgState = state
}
@@ -225,6 +227,10 @@ func (msg *BaseMessage) SetIsService(isService bool) {
msg.MsgIsService = isService
}
+func (msg *BaseMessage) Source() json.RawMessage {
+ return msg.MsgSource
+}
+
func (msg *BaseMessage) Draw(screen mauview.Screen) {
for y, line := range msg.buffer {
line.Draw(screen, 0, y)
diff --git a/ui/messages/expandedtextmessage.go b/ui/messages/expandedtextmessage.go
index 044613f..4a4ed24 100644
--- a/ui/messages/expandedtextmessage.go
+++ b/ui/messages/expandedtextmessage.go
@@ -17,28 +17,21 @@
package messages
import (
- "encoding/gob"
- "time"
-
"maunium.net/go/mautrix"
"maunium.net/go/gomuks/config"
"maunium.net/go/gomuks/ui/messages/tstring"
)
-func init() {
- gob.Register(&ExpandedTextMessage{})
-}
-
type ExpandedTextMessage struct {
BaseMessage
MsgText tstring.TString
}
// NewExpandedTextMessage creates a new ExpandedTextMessage object with the provided values and the default state.
-func NewExpandedTextMessage(id, sender, displayname string, msgtype mautrix.MessageType, text tstring.TString, timestamp time.Time) UIMessage {
+func NewExpandedTextMessage(event *mautrix.Event, displayname string, text tstring.TString) UIMessage {
return &ExpandedTextMessage{
- BaseMessage: newBaseMessage(id, sender, displayname, msgtype, timestamp),
+ BaseMessage: newBaseMessage(event, displayname),
MsgText: text,
}
}
diff --git a/ui/messages/htmlmessage.go b/ui/messages/htmlmessage.go
index ed8b7c1..ceee305 100644
--- a/ui/messages/htmlmessage.go
+++ b/ui/messages/htmlmessage.go
@@ -17,13 +17,12 @@
package messages
import (
- "maunium.net/go/gomuks/ui/messages/html"
-
"maunium.net/go/mautrix"
"maunium.net/go/mauview"
"maunium.net/go/tcell"
"maunium.net/go/gomuks/config"
+ "maunium.net/go/gomuks/ui/messages/html"
)
type HTMLMessage struct {
@@ -36,7 +35,7 @@ type HTMLMessage struct {
func NewHTMLMessage(event *mautrix.Event, displayname string, root html.Entity) UIMessage {
return &HTMLMessage{
- BaseMessage: newBaseMessage(event.ID, event.Sender, displayname, event.Content.MsgType, unixToTime(event.Timestamp)),
+ BaseMessage: newBaseMessage(event, displayname),
Root: root,
}
}
diff --git a/ui/messages/imagemessage.go b/ui/messages/imagemessage.go
index 968f29e..9ce1a8e 100644
--- a/ui/messages/imagemessage.go
+++ b/ui/messages/imagemessage.go
@@ -18,10 +18,8 @@ package messages
import (
"bytes"
- "encoding/gob"
"fmt"
"image/color"
- "time"
"maunium.net/go/mautrix"
"maunium.net/go/tcell"
@@ -33,10 +31,6 @@ import (
"maunium.net/go/gomuks/ui/messages/tstring"
)
-func init() {
- gob.Register(&ImageMessage{})
-}
-
type ImageMessage struct {
BaseMessage
Body string
@@ -48,9 +42,9 @@ type ImageMessage struct {
}
// NewImageMessage creates a new ImageMessage object with the provided values and the default state.
-func NewImageMessage(matrix ifc.MatrixContainer, id, sender, displayname string, msgtype mautrix.MessageType, body, homeserver, fileID string, data []byte, timestamp time.Time) UIMessage {
+func NewImageMessage(matrix ifc.MatrixContainer, event *mautrix.Event, displayname string, body, homeserver, fileID string, data []byte) UIMessage {
return &ImageMessage{
- newBaseMessage(id, sender, displayname, msgtype, timestamp),
+ newBaseMessage(event, displayname),
body,
homeserver,
fileID,
diff --git a/ui/messages/message.go b/ui/messages/message.go
index db93879..634bd11 100644
--- a/ui/messages/message.go
+++ b/ui/messages/message.go
@@ -20,12 +20,20 @@ import (
"maunium.net/go/gomuks/config"
"maunium.net/go/gomuks/interface"
"maunium.net/go/mauview"
+ "maunium.net/go/tcell"
)
// UIMessage is a wrapper for the content and metadata of a Matrix message intended to be displayed.
type UIMessage interface {
ifc.Message
+ Sender() string
+ SenderColor() tcell.Color
+ TextColor() tcell.Color
+ TimestampColor() tcell.Color
+ FormatTime() string
+ FormatDate() string
+
CalculateBuffer(preferences config.UserPreferences, width int)
Draw(screen mauview.Screen)
Height() int
diff --git a/ui/messages/meta.go b/ui/messages/meta.go
deleted file mode 100644
index 0712be1..0000000
--- a/ui/messages/meta.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// gomuks - A terminal Matrix client written in Go.
-// Copyright (C) 2019 Tulir Asokan
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-package messages
-
-import (
- "time"
-
- "maunium.net/go/tcell"
-)
-
-// BasicMeta is a simple variable store implementation of MessageMeta.
-type BasicMeta struct {
- BSender string
- BTimestamp time.Time
- BSenderColor, BTextColor, BTimestampColor tcell.Color
-}
-
-// Sender gets the string that should be displayed as the sender of this message.
-func (meta *BasicMeta) Sender() string {
- return meta.BSender
-}
-
-func (meta *BasicMeta) SenderID() string {
- return meta.BSender
-}
-
-// SenderColor returns the color the name of the sender should be shown in.
-func (meta *BasicMeta) SenderColor() tcell.Color {
- return meta.BSenderColor
-}
-
-// Timestamp returns the full time when the message was sent.
-func (meta *BasicMeta) Timestamp() time.Time {
- return meta.BTimestamp
-}
-
-// FormatTime returns the formatted time when the message was sent.
-func (meta *BasicMeta) FormatTime() string {
- return meta.BTimestamp.Format(TimeFormat)
-}
-
-// FormatDate returns the formatted date when the message was sent.
-func (meta *BasicMeta) FormatDate() string {
- return meta.BTimestamp.Format(DateFormat)
-}
-
-// TextColor returns the color the actual content of the message should be shown in.
-func (meta *BasicMeta) TextColor() tcell.Color {
- return meta.BTextColor
-}
-
-// TimestampColor returns the color the timestamp should be shown in.
-//
-// This usually does not apply to the date, as it is rendered separately from the message.
-func (meta *BasicMeta) TimestampColor() tcell.Color {
- return meta.BTimestampColor
-}
diff --git a/ui/messages/parser.go b/ui/messages/parser.go
index ae0606d..f45eea2 100644
--- a/ui/messages/parser.go
+++ b/ui/messages/parser.go
@@ -18,9 +18,7 @@ package messages
import (
"fmt"
- "html"
"strings"
- "time"
"maunium.net/go/mautrix"
"maunium.net/go/tcell"
@@ -28,12 +26,33 @@ import (
"maunium.net/go/gomuks/debug"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/matrix/rooms"
+ "maunium.net/go/gomuks/ui/messages/html"
"maunium.net/go/gomuks/ui/messages/tstring"
"maunium.net/go/gomuks/ui/widget"
htmlp "maunium.net/go/gomuks/ui/messages/html"
)
func ParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Event) UIMessage {
+ msg := directParseEvent(matrix, room, evt)
+ if msg == nil {
+ return nil
+ }
+ if len(evt.Content.GetReplyTo()) > 0 {
+ roomID := evt.Content.RelatesTo.InReplyTo.RoomID
+ if len(roomID) == 0 {
+ roomID = room.ID
+ }
+ replyToEvt, _ := matrix.GetEvent(room, evt.Content.GetReplyTo())
+ if replyToEvt != nil {
+ // TODO add reply header
+ } else {
+ // TODO add unknown reply header
+ }
+ }
+ return msg
+}
+
+func directParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Event) UIMessage {
switch evt.Type {
case mautrix.EventSticker:
evt.Content.MsgType = mautrix.MsgImage
@@ -48,14 +67,6 @@ func ParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Event
return nil
}
-func unixToTime(unix int64) time.Time {
- timestamp := time.Now()
- if unix != 0 {
- timestamp = time.Unix(unix/1000, unix%1000*1000)
- }
- return timestamp
-}
-
func ParseStateEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Event) UIMessage {
displayname := evt.Sender
member := room.GetMember(evt.Sender)
@@ -91,8 +102,7 @@ func ParseStateEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.
case mautrix.StateAliases:
text = ParseAliasEvent(evt, displayname)
}
- ts := unixToTime(evt.Timestamp)
- return NewExpandedTextMessage(evt.ID, evt.Sender, displayname, mautrix.MessageType(evt.Type.Type), text, ts)
+ return NewExpandedTextMessage(evt, displayname, text)
}
func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Event) UIMessage {
@@ -103,39 +113,20 @@ func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Eve
}
if len(evt.Content.GetReplyTo()) > 0 {
evt.Content.RemoveReplyFallback()
- roomID := evt.Content.RelatesTo.InReplyTo.RoomID
- if len(roomID) == 0 {
- roomID = room.ID
- }
- replyToEvt, _ := matrix.GetEvent(room, evt.Content.GetReplyTo())
- if replyToEvt != nil {
- replyToEvt.Content.RemoveReplyFallback()
- if len(replyToEvt.Content.FormattedBody) == 0 {
- replyToEvt.Content.FormattedBody = html.EscapeString(replyToEvt.Content.Body)
- }
- evt.Content.FormattedBody = fmt.Sprintf(
- "In reply to <a href='https://matrix.to/#/%[1]s'>%[1]s</a><blockquote>%[2]s</blockquote><br/><br/>%[3]s",
- replyToEvt.Sender, replyToEvt.Content.FormattedBody, evt.Content.FormattedBody)
- } else {
- evt.Content.FormattedBody = fmt.Sprintf(
- "In reply to unknown event https://matrix.to/#/%[1]s/%[2]s<br/>%[3]s",
- roomID, evt.Content.GetReplyTo(), evt.Content.FormattedBody)
- }
}
- ts := unixToTime(evt.Timestamp)
switch evt.Content.MsgType {
case "m.text", "m.notice", "m.emote":
if evt.Content.Format == mautrix.FormatHTML {
- return NewHTMLMessage(evt, displayname, htmlp.Parse(room, evt, displayname))
+ return NewHTMLMessage(evt, displayname, html.Parse(room, evt, displayname))
}
evt.Content.Body = strings.Replace(evt.Content.Body, "\t", " ", -1)
- return NewTextMessage(evt.ID, evt.Sender, displayname, evt.Content.MsgType, evt.Content.Body, ts)
+ return NewTextMessage(evt, displayname, evt.Content.Body)
case "m.image":
data, hs, id, err := matrix.Download(evt.Content.URL)
if err != nil {
debug.Printf("Failed to download %s: %v", evt.Content.URL, err)
}
- return NewImageMessage(matrix, evt.ID, evt.Sender, displayname, evt.Content.MsgType, evt.Content.Body, hs, id, data, ts)
+ return NewImageMessage(matrix, evt, displayname, evt.Content.Body, hs, id, data)
}
return nil
}
@@ -220,8 +211,7 @@ func ParseMembershipEvent(room *rooms.Room, evt *mautrix.Event) UIMessage {
return nil
}
- ts := unixToTime(evt.Timestamp)
- return NewExpandedTextMessage(evt.ID, evt.Sender, displayname, "m.room.member", text, ts)
+ return NewExpandedTextMessage(evt, displayname, text)
}
func ParseAliasEvent(evt *mautrix.Event, displayname string) tstring.TString {
diff --git a/ui/messages/textmessage.go b/ui/messages/textmessage.go
index 6364659..f7c54ca 100644
--- a/ui/messages/textmessage.go
+++ b/ui/messages/textmessage.go
@@ -17,21 +17,14 @@
package messages
import (
- "encoding/gob"
"fmt"
- "time"
"maunium.net/go/mautrix"
"maunium.net/go/gomuks/config"
- "maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/ui/messages/tstring"
)
-func init() {
- gob.Register(&TextMessage{})
-}
-
type TextMessage struct {
BaseMessage
cache tstring.TString
@@ -39,9 +32,9 @@ type TextMessage struct {
}
// NewTextMessage creates a new UITextMessage object with the provided values and the default state.
-func NewTextMessage(id, sender, displayname string, msgtype mautrix.MessageType, text string, timestamp time.Time) UIMessage {
+func NewTextMessage(event *mautrix.Event, displayname string, text string) UIMessage {
return &TextMessage{
- BaseMessage: newBaseMessage(id, sender, displayname, msgtype, timestamp),
+ BaseMessage: newBaseMessage(event, displayname),
MsgText: text,
}
}
@@ -59,16 +52,6 @@ func (msg *TextMessage) getCache() tstring.TString {
return msg.cache
}
-func (msg *TextMessage) SetType(msgtype mautrix.MessageType) {
- msg.BaseMessage.SetType(msgtype)
- msg.cache = nil
-}
-
-func (msg *TextMessage) SetState(state ifc.MessageState) {
- msg.BaseMessage.SetState(state)
- msg.cache = nil
-}
-
func (msg *TextMessage) SetIsHighlight(isHighlight bool) {
msg.BaseMessage.SetIsHighlight(isHighlight)
msg.cache = nil