aboutsummaryrefslogtreecommitdiff
path: root/ui/messages/textmessage.go
diff options
context:
space:
mode:
Diffstat (limited to 'ui/messages/textmessage.go')
-rw-r--r--ui/messages/textmessage.go304
1 files changed, 43 insertions, 261 deletions
diff --git a/ui/messages/textmessage.go b/ui/messages/textmessage.go
index f630ef0..4c99e5b 100644
--- a/ui/messages/textmessage.go
+++ b/ui/messages/textmessage.go
@@ -19,302 +19,84 @@ package messages
import (
"encoding/gob"
"fmt"
- "regexp"
"time"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/ui/messages/tstring"
- "maunium.net/go/gomuks/ui/widget"
- "maunium.net/go/tcell"
)
func init() {
- gob.Register(&UITextMessage{})
+ gob.Register(&TextMessage{})
}
-type UITextMessage struct {
- MsgID string
- MsgType string
- MsgSender string
- MsgSenderColor tcell.Color
- MsgTimestamp time.Time
- MsgText string
- MsgState ifc.MessageState
- MsgIsHighlight bool
- MsgIsService bool
- text tstring.TString
- buffer []tstring.TString
- prevBufferWidth int
+type TextMessage struct {
+ BaseTextMessage
+ cache tstring.TString
+ MsgText string
}
// NewTextMessage creates a new UITextMessage object with the provided values and the default state.
func NewTextMessage(id, sender, msgtype, text string, timestamp time.Time) UIMessage {
- return &UITextMessage{
- MsgSender: sender,
- MsgTimestamp: timestamp,
- MsgSenderColor: widget.GetHashColor(sender),
- MsgType: msgtype,
+ return &TextMessage{
+ BaseTextMessage: newBaseTextMessage(id, sender, msgtype, timestamp),
MsgText: text,
- MsgID: id,
- prevBufferWidth: 0,
- MsgState: ifc.MessageStateDefault,
- MsgIsHighlight: false,
- MsgIsService: false,
}
}
-func (msg *UITextMessage) RegisterGomuks(gmx ifc.Gomuks) {}
-
-// CopyFrom replaces the content of this message object with the content of the given object.
-func (msg *UITextMessage) CopyFrom(from ifc.MessageMeta) {
- msg.MsgSender = from.Sender()
- msg.MsgSenderColor = from.SenderColor()
-
- fromMsg, ok := from.(UIMessage)
- if ok {
- msg.MsgSender = fromMsg.RealSender()
- msg.MsgID = fromMsg.ID()
- msg.MsgType = fromMsg.Type()
- msg.MsgTimestamp = fromMsg.Timestamp()
- msg.MsgText = fromMsg.Text()
- msg.MsgState = fromMsg.State()
- msg.MsgIsService = fromMsg.IsService()
- msg.MsgIsHighlight = fromMsg.IsHighlight()
- msg.buffer = nil
-
- msg.RecalculateBuffer()
- }
-}
-
-// Sender gets the string that should be displayed as the sender of this message.
-//
-// If the message is being sent, the sender is "Sending...".
-// If sending has failed, the sender is "Error".
-// If the message is an emote, the sender is blank.
-// In any other case, the sender is the display name of the user who sent the message.
-func (msg *UITextMessage) Sender() string {
- switch msg.MsgState {
- case ifc.MessageStateSending:
- return "Sending..."
- case ifc.MessageStateFailed:
- return "Error"
- }
- switch msg.MsgType {
- case "m.emote":
- // Emotes don't show a separate sender, it's included in the buffer.
- return ""
- default:
- return msg.MsgSender
- }
-}
-
-func (msg *UITextMessage) RealSender() string {
- return msg.MsgSender
-}
-
-func (msg *UITextMessage) getStateSpecificColor() tcell.Color {
- switch msg.MsgState {
- case ifc.MessageStateSending:
- return tcell.ColorGray
- case ifc.MessageStateFailed:
- return tcell.ColorRed
- case ifc.MessageStateDefault:
- fallthrough
- default:
- return tcell.ColorDefault
+func (msg *TextMessage) getCache() tstring.TString {
+ if msg.cache == nil {
+ switch msg.MsgType {
+ case "m.emote":
+ msg.cache = tstring.NewColorTString(fmt.Sprintf("* %s %s", msg.MsgSender, msg.MsgText), msg.TextColor())
+ msg.cache.Colorize(0, len(msg.MsgSender)+2, msg.SenderColor())
+ default:
+ msg.cache = tstring.NewColorTString(msg.MsgText, msg.TextColor())
+ }
}
+ return msg.cache
}
-// SenderColor returns the color the name of the sender should be shown in.
-//
-// If the message is being sent, the color is gray.
-// If sending has failed, the color is red.
-//
-// In any other case, the color is whatever is specified in the Message struct.
-// Usually that means it is the hash-based color of the sender (see ui/widget/color.go)
-func (msg *UITextMessage) SenderColor() tcell.Color {
- stateColor := msg.getStateSpecificColor()
- switch {
- case stateColor != tcell.ColorDefault:
- return stateColor
- case msg.MsgIsService:
- return tcell.ColorGray
- default:
- return msg.MsgSenderColor
- }
-}
+// 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)
-// TextColor returns the color the actual content of the message should be shown in.
-func (msg *UITextMessage) TextColor() tcell.Color {
- stateColor := msg.getStateSpecificColor()
- switch {
- case stateColor != tcell.ColorDefault:
- return stateColor
- case msg.MsgIsService:
- return tcell.ColorGray
- case msg.MsgIsHighlight:
- return tcell.ColorYellow
- case msg.MsgType == "m.room.member":
- return tcell.ColorGreen
- default:
- return tcell.ColorDefault
+ fromTextMsg, ok := from.(*TextMessage)
+ if ok {
+ msg.MsgText = fromTextMsg.MsgText
}
-}
-
-// TimestampColor returns the color the timestamp should be shown in.
-//
-// As with SenderColor(), messages being sent and messages that failed to be sent are
-// gray and red respectively.
-//
-// However, other messages are the default color instead of a color stored in the struct.
-func (msg *UITextMessage) TimestampColor() tcell.Color {
- return msg.getStateSpecificColor()
-}
-
-// RecalculateBuffer calculates the buffer again with the previously provided width.
-func (msg *UITextMessage) RecalculateBuffer() {
- msg.CalculateBuffer(msg.prevBufferWidth)
-}
-
-// 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 *UITextMessage) Buffer() []tstring.TString {
- return msg.buffer
-}
-// Height returns the number of rows in the computed buffer (see Buffer()).
-func (msg *UITextMessage) Height() int {
- return len(msg.buffer)
+ msg.cache = nil
+ msg.RecalculateBuffer()
}
-
-// Timestamp returns the full timestamp when the message was sent.
-func (msg *UITextMessage) Timestamp() time.Time {
- return msg.MsgTimestamp
-}
-
-// FormatTime returns the formatted time when the message was sent.
-func (msg *UITextMessage) FormatTime() string {
- return msg.MsgTimestamp.Format(TimeFormat)
-}
-
-// FormatDate returns the formatted date when the message was sent.
-func (msg *UITextMessage) FormatDate() string {
- return msg.MsgTimestamp.Format(DateFormat)
+func (msg *TextMessage) SetType(msgtype string) {
+ msg.BaseTextMessage.SetType(msgtype)
+ msg.cache = nil
}
-func (msg *UITextMessage) ID() string {
- return msg.MsgID
+func (msg *TextMessage) SetState(state ifc.MessageState) {
+ msg.BaseTextMessage.SetState(state)
+ msg.cache = nil
}
-func (msg *UITextMessage) SetID(id string) {
- msg.MsgID = id
+func (msg *TextMessage) SetIsHighlight(isHighlight bool) {
+ msg.BaseTextMessage.SetIsHighlight(isHighlight)
+ msg.cache = nil
}
-func (msg *UITextMessage) Type() string {
- return msg.MsgType
+func (msg *TextMessage) SetIsService(isService bool) {
+ msg.BaseTextMessage.SetIsService(isService)
+ msg.cache = nil
}
-func (msg *UITextMessage) SetType(msgtype string) {
- msg.MsgType = msgtype
- msg.text = nil
-}
-
-func (msg *UITextMessage) Text() string {
+func (msg *TextMessage) NotificationContent() string {
return msg.MsgText
}
-func (msg *UITextMessage) SetText(text string) {
- msg.MsgText = text
- msg.text = nil
-}
-
-func (msg *UITextMessage) State() ifc.MessageState {
- return msg.MsgState
+func (msg *TextMessage) CalculateBuffer(width int) {
+ msg.BaseTextMessage.calculateBufferWithText(msg.getCache(), width)
}
-func (msg *UITextMessage) SetState(state ifc.MessageState) {
- msg.MsgState = state
- msg.text = nil
-}
-
-func (msg *UITextMessage) IsHighlight() bool {
- return msg.MsgIsHighlight
-}
-
-func (msg *UITextMessage) SetIsHighlight(isHighlight bool) {
- msg.MsgIsHighlight = isHighlight
- msg.text = nil
-}
-
-func (msg *UITextMessage) IsService() bool {
- return msg.MsgIsService
-}
-
-func (msg *UITextMessage) SetIsService(isService bool) {
- msg.MsgIsService = isService
- msg.text = nil
-}
-
-func (msg *UITextMessage) GetTStringText() tstring.TString {
- if msg.text == nil || len(msg.text) == 0 {
- msg.text = tstring.NewColorTString(msg.Text(), msg.TextColor())
- }
- return msg.text
-}
-
-// Regular expressions used to split lines when calculating the buffer.
-//
-// From tview/textview.go
-var (
- boundaryPattern = regexp.MustCompile("([[:punct:]]\\s*|\\s+)")
- spacePattern = regexp.MustCompile(`\s+`)
-)
-
-// 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.
-func (msg *UITextMessage) CalculateBuffer(width int) {
- if width < 2 {
- return
- }
-
- msg.buffer = []tstring.TString{}
- text := msg.GetTStringText()
- if msg.MsgType == "m.emote" {
- text = tstring.NewColorTString(fmt.Sprintf("* %s %s", msg.MsgSender, text.String()), msg.TextColor())
- text.Colorize(0, len(msg.MsgSender), msg.SenderColor())
- }
-
- forcedLinebreaks := text.Split('\n')
- newlines := 0
- for _, str := range forcedLinebreaks {
- if len(str) == 0 && newlines < 1 {
- msg.buffer = append(msg.buffer, tstring.TString{})
- newlines++
- } else {
- newlines = 0
- }
- // Mostly from tview/textview.go#reindexBuffer()
- for len(str) > 0 {
- extract := str.Truncate(width)
- if len(extract) < len(str) {
- if spaces := spacePattern.FindStringIndex(str[len(extract):].String()); spaces != nil && spaces[0] == 0 {
- extract = str[:len(extract)+spaces[1]]
- }
-
- matches := boundaryPattern.FindAllStringIndex(extract.String(), -1)
- if len(matches) > 0 {
- extract = extract[:matches[len(matches)-1][1]]
- }
- }
- msg.buffer = append(msg.buffer, extract)
- str = str[len(extract):]
- }
- }
- msg.prevBufferWidth = width
+// RecalculateBuffer calculates the buffer again with the previously provided width.
+func (msg *TextMessage) RecalculateBuffer() {
+ msg.CalculateBuffer(msg.prevBufferWidth)
}