2018-04-13 20:25:45 +02:00
|
|
|
|
// gomuks - A terminal Matrix client written in Go.
|
2019-01-17 13:13:25 +01:00
|
|
|
|
// Copyright (C) 2019 Tulir Asokan
|
2018-04-13 20:25:45 +02:00
|
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
2019-01-17 13:13:25 +01:00
|
|
|
|
// it under the terms of the GNU Affero General Public License as published by
|
2018-04-13 20:25:45 +02:00
|
|
|
|
// 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
|
2019-01-17 13:13:25 +01:00
|
|
|
|
// GNU Affero General Public License for more details.
|
2018-04-13 20:25:45 +02:00
|
|
|
|
//
|
2019-01-17 13:13:25 +01:00
|
|
|
|
// 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/>.
|
2018-04-13 20:25:45 +02:00
|
|
|
|
|
|
|
|
|
package messages
|
|
|
|
|
|
|
|
|
|
import (
|
2019-04-12 23:51:58 +02:00
|
|
|
|
"fmt"
|
2020-02-20 20:56:03 +01:00
|
|
|
|
"sort"
|
2018-04-13 20:25:45 +02:00
|
|
|
|
"time"
|
|
|
|
|
|
2019-04-10 01:19:38 +02:00
|
|
|
|
"maunium.net/go/gomuks/config"
|
2020-04-16 18:27:35 +02:00
|
|
|
|
"maunium.net/go/gomuks/matrix/muksevt"
|
|
|
|
|
"maunium.net/go/mautrix/event"
|
|
|
|
|
"maunium.net/go/mautrix/id"
|
2019-04-07 17:21:38 +02:00
|
|
|
|
"maunium.net/go/mauview"
|
2019-01-17 13:13:25 +01:00
|
|
|
|
"maunium.net/go/tcell"
|
|
|
|
|
|
2018-04-13 20:25:45 +02:00
|
|
|
|
"maunium.net/go/gomuks/ui/widget"
|
|
|
|
|
)
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
type MessageRenderer interface {
|
|
|
|
|
Draw(screen mauview.Screen)
|
|
|
|
|
NotificationContent() string
|
|
|
|
|
PlainText() string
|
|
|
|
|
CalculateBuffer(prefs config.UserPreferences, width int, msg *UIMessage)
|
|
|
|
|
Height() int
|
|
|
|
|
Clone() MessageRenderer
|
|
|
|
|
String() string
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 20:56:03 +01:00
|
|
|
|
type ReactionItem struct {
|
|
|
|
|
Key string
|
|
|
|
|
Count int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (ri ReactionItem) String() string {
|
2020-02-20 21:11:09 +01:00
|
|
|
|
return fmt.Sprintf("%d×%s", ri.Count, ri.Key)
|
2020-02-20 20:56:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ReactionSlice []ReactionItem
|
|
|
|
|
|
|
|
|
|
func (rs ReactionSlice) Len() int {
|
|
|
|
|
return len(rs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (rs ReactionSlice) Less(i, j int) bool {
|
|
|
|
|
return rs[i].Key < rs[j].Key
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (rs ReactionSlice) Swap(i, j int) {
|
|
|
|
|
rs[i], rs[j] = rs[j], rs[i]
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
type UIMessage struct {
|
2020-04-16 18:27:35 +02:00
|
|
|
|
EventID id.EventID
|
2019-06-15 00:11:51 +02:00
|
|
|
|
TxnID string
|
2020-04-16 18:27:35 +02:00
|
|
|
|
Relation event.RelatesTo
|
|
|
|
|
Type event.MessageType
|
|
|
|
|
SenderID id.UserID
|
2019-06-15 00:11:51 +02:00
|
|
|
|
SenderName string
|
|
|
|
|
DefaultSenderColor tcell.Color
|
|
|
|
|
Timestamp time.Time
|
2020-04-16 18:27:35 +02:00
|
|
|
|
State muksevt.OutgoingState
|
2019-06-15 00:11:51 +02:00
|
|
|
|
IsHighlight bool
|
|
|
|
|
IsService bool
|
2020-02-20 23:29:29 +01:00
|
|
|
|
IsSelected bool
|
2019-06-17 12:46:02 +02:00
|
|
|
|
Edited bool
|
2020-04-16 18:27:35 +02:00
|
|
|
|
Event *muksevt.Event
|
2019-06-15 00:11:51 +02:00
|
|
|
|
ReplyTo *UIMessage
|
2020-02-20 20:56:03 +01:00
|
|
|
|
Reactions ReactionSlice
|
2019-06-15 00:11:51 +02:00
|
|
|
|
Renderer MessageRenderer
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
|
func (msg *UIMessage) GetEvent() *muksevt.Event {
|
2020-03-01 16:11:56 +01:00
|
|
|
|
if msg == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return msg.Event
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
const DateFormat = "January _2, 2006"
|
|
|
|
|
const TimeFormat = "15:04:05"
|
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
|
func newUIMessage(evt *muksevt.Event, displayname string, renderer MessageRenderer) *UIMessage {
|
2020-04-19 14:00:49 +02:00
|
|
|
|
msgContent := evt.Content.AsMessage()
|
|
|
|
|
msgtype := msgContent.MsgType
|
2019-04-09 17:45:41 +02:00
|
|
|
|
if len(msgtype) == 0 {
|
2020-04-16 18:27:35 +02:00
|
|
|
|
msgtype = event.MessageType(evt.Type.String())
|
2019-04-09 17:45:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 20:56:03 +01:00
|
|
|
|
reactions := make(ReactionSlice, 0, len(evt.Unsigned.Relations.Annotations.Map))
|
|
|
|
|
for key, count := range evt.Unsigned.Relations.Annotations.Map {
|
|
|
|
|
reactions = append(reactions, ReactionItem{
|
|
|
|
|
Key: key,
|
|
|
|
|
Count: count,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(reactions)
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
return &UIMessage{
|
2019-06-17 11:27:31 +02:00
|
|
|
|
SenderID: evt.Sender,
|
2019-06-15 00:11:51 +02:00
|
|
|
|
SenderName: displayname,
|
2019-06-17 11:27:31 +02:00
|
|
|
|
Timestamp: unixToTime(evt.Timestamp),
|
|
|
|
|
DefaultSenderColor: widget.GetHashColor(evt.Sender),
|
2019-06-15 00:11:51 +02:00
|
|
|
|
Type: msgtype,
|
2019-06-17 11:27:31 +02:00
|
|
|
|
EventID: evt.ID,
|
|
|
|
|
TxnID: evt.Unsigned.TransactionID,
|
2020-04-19 14:00:49 +02:00
|
|
|
|
Relation: *msgContent.GetRelatesTo(),
|
2019-06-17 11:27:31 +02:00
|
|
|
|
State: evt.Gomuks.OutgoingState,
|
2019-06-15 00:11:51 +02:00
|
|
|
|
IsHighlight: false,
|
|
|
|
|
IsService: false,
|
2019-06-17 12:46:02 +02:00
|
|
|
|
Edited: len(evt.Gomuks.Edits) > 0,
|
2020-02-20 20:56:03 +01:00
|
|
|
|
Reactions: reactions,
|
2020-02-19 00:14:02 +01:00
|
|
|
|
Event: evt,
|
2019-06-15 00:11:51 +02:00
|
|
|
|
Renderer: renderer,
|
2018-04-13 20:25:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 20:56:03 +01:00
|
|
|
|
func (msg *UIMessage) AddReaction(key string) {
|
|
|
|
|
found := false
|
|
|
|
|
for _, rs := range msg.Reactions {
|
|
|
|
|
if rs.Key == key {
|
|
|
|
|
rs.Count++
|
|
|
|
|
found = true
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if !found {
|
|
|
|
|
msg.Reactions = append(msg.Reactions, ReactionItem{
|
|
|
|
|
Key: key,
|
|
|
|
|
Count: 1,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(msg.Reactions)
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-09 17:45:41 +02:00
|
|
|
|
func unixToTime(unix int64) time.Time {
|
|
|
|
|
timestamp := time.Now()
|
|
|
|
|
if unix != 0 {
|
|
|
|
|
timestamp = time.Unix(unix/1000, unix%1000*1000)
|
|
|
|
|
}
|
|
|
|
|
return timestamp
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 20:25:45 +02:00
|
|
|
|
// 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.
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) Sender() string {
|
|
|
|
|
switch msg.State {
|
2020-04-16 18:27:35 +02:00
|
|
|
|
case muksevt.StateLocalEcho:
|
2018-04-13 20:25:45 +02:00
|
|
|
|
return "Sending..."
|
2020-04-16 18:27:35 +02:00
|
|
|
|
case muksevt.StateSendFail:
|
2018-04-13 20:25:45 +02:00
|
|
|
|
return "Error"
|
|
|
|
|
}
|
2019-06-15 00:11:51 +02:00
|
|
|
|
switch msg.Type {
|
2018-04-13 20:25:45 +02:00
|
|
|
|
case "m.emote":
|
|
|
|
|
// Emotes don't show a separate sender, it's included in the buffer.
|
|
|
|
|
return ""
|
|
|
|
|
default:
|
2019-06-15 00:11:51 +02:00
|
|
|
|
return msg.SenderName
|
2018-04-13 20:25:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) NotificationSenderName() string {
|
|
|
|
|
return msg.SenderName
|
2018-04-18 12:38:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) NotificationContent() string {
|
|
|
|
|
return msg.Renderer.NotificationContent()
|
2018-04-13 20:25:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) getStateSpecificColor() tcell.Color {
|
|
|
|
|
switch msg.State {
|
2020-04-16 18:27:35 +02:00
|
|
|
|
case muksevt.StateLocalEcho:
|
2018-04-13 20:25:45 +02:00
|
|
|
|
return tcell.ColorGray
|
2020-04-16 18:27:35 +02:00
|
|
|
|
case muksevt.StateSendFail:
|
2018-04-13 20:25:45 +02:00
|
|
|
|
return tcell.ColorRed
|
2020-04-16 18:27:35 +02:00
|
|
|
|
case muksevt.StateDefault:
|
2018-04-13 20:25:45 +02:00
|
|
|
|
fallthrough
|
|
|
|
|
default:
|
|
|
|
|
return tcell.ColorDefault
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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)
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) SenderColor() tcell.Color {
|
2018-04-13 20:25:45 +02:00
|
|
|
|
stateColor := msg.getStateSpecificColor()
|
|
|
|
|
switch {
|
|
|
|
|
case stateColor != tcell.ColorDefault:
|
|
|
|
|
return stateColor
|
2019-06-15 00:11:51 +02:00
|
|
|
|
case msg.Type == "m.room.member":
|
|
|
|
|
return widget.GetHashColor(msg.SenderName)
|
|
|
|
|
case msg.IsService:
|
2018-04-13 20:25:45 +02:00
|
|
|
|
return tcell.ColorGray
|
|
|
|
|
default:
|
2019-06-15 00:11:51 +02:00
|
|
|
|
return msg.DefaultSenderColor
|
2018-04-13 20:25:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TextColor returns the color the actual content of the message should be shown in.
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) TextColor() tcell.Color {
|
2018-04-13 20:25:45 +02:00
|
|
|
|
stateColor := msg.getStateSpecificColor()
|
|
|
|
|
switch {
|
|
|
|
|
case stateColor != tcell.ColorDefault:
|
|
|
|
|
return stateColor
|
2019-06-15 00:11:51 +02:00
|
|
|
|
case msg.IsService, msg.Type == "m.notice":
|
2018-04-13 20:25:45 +02:00
|
|
|
|
return tcell.ColorGray
|
2019-06-15 00:11:51 +02:00
|
|
|
|
case msg.IsHighlight:
|
2018-04-13 20:25:45 +02:00
|
|
|
|
return tcell.ColorYellow
|
2019-06-15 00:11:51 +02:00
|
|
|
|
case msg.Type == "m.room.member":
|
2018-04-13 20:25:45 +02:00
|
|
|
|
return tcell.ColorGreen
|
|
|
|
|
default:
|
|
|
|
|
return tcell.ColorDefault
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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.
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) TimestampColor() tcell.Color {
|
|
|
|
|
if msg.IsService {
|
2019-04-10 16:08:39 +02:00
|
|
|
|
return tcell.ColorGray
|
|
|
|
|
}
|
2018-04-13 20:25:45 +02:00
|
|
|
|
return msg.getStateSpecificColor()
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) ReplyHeight() int {
|
2019-04-10 01:19:38 +02:00
|
|
|
|
if msg.ReplyTo != nil {
|
2019-04-13 16:04:52 +02:00
|
|
|
|
return 1 + msg.ReplyTo.Height()
|
2019-04-10 01:19:38 +02:00
|
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 20:56:03 +01:00
|
|
|
|
func (msg *UIMessage) ReactionHeight() int {
|
|
|
|
|
if len(msg.Reactions) > 0 {
|
|
|
|
|
return 1
|
|
|
|
|
}
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-13 20:25:45 +02:00
|
|
|
|
// Height returns the number of rows in the computed buffer (see Buffer()).
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) Height() int {
|
2020-02-20 20:56:03 +01:00
|
|
|
|
return msg.ReplyHeight() + msg.Renderer.Height() + msg.ReactionHeight()
|
2018-04-13 20:25:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) Time() time.Time {
|
|
|
|
|
return msg.Timestamp
|
2018-04-13 20:25:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FormatTime returns the formatted time when the message was sent.
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) FormatTime() string {
|
|
|
|
|
return msg.Timestamp.Format(TimeFormat)
|
2018-04-13 20:25:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FormatDate returns the formatted date when the message was sent.
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) FormatDate() string {
|
|
|
|
|
return msg.Timestamp.Format(DateFormat)
|
2018-04-13 20:25:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) SameDate(message *UIMessage) bool {
|
|
|
|
|
year1, month1, day1 := msg.Timestamp.Date()
|
|
|
|
|
year2, month2, day2 := message.Timestamp.Date()
|
2019-04-10 00:42:27 +02:00
|
|
|
|
return day1 == day2 && month1 == month2 && year1 == year2
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
|
func (msg *UIMessage) ID() id.EventID {
|
2019-06-15 00:11:51 +02:00
|
|
|
|
if len(msg.EventID) == 0 {
|
2020-04-16 18:27:35 +02:00
|
|
|
|
return id.EventID(msg.TxnID)
|
2019-04-10 00:04:39 +02:00
|
|
|
|
}
|
2019-06-15 00:11:51 +02:00
|
|
|
|
return msg.EventID
|
2018-04-13 20:25:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
|
func (msg *UIMessage) SetID(id id.EventID) {
|
2019-06-15 00:11:51 +02:00
|
|
|
|
msg.EventID = id
|
2019-04-09 17:45:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) SetIsHighlight(isHighlight bool) {
|
|
|
|
|
msg.IsHighlight = isHighlight
|
2019-04-10 01:19:38 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-20 20:56:03 +01:00
|
|
|
|
func (msg *UIMessage) DrawReactions(screen mauview.Screen) {
|
|
|
|
|
if len(msg.Reactions) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
width, height := screen.Size()
|
|
|
|
|
screen = mauview.NewProxyScreen(screen, 0, height-1, width, 1)
|
2020-02-20 21:11:09 +01:00
|
|
|
|
|
|
|
|
|
x := 0
|
|
|
|
|
for _, reaction := range msg.Reactions {
|
2020-02-20 21:42:53 +01:00
|
|
|
|
_, drawn := mauview.PrintWithStyle(screen, reaction.String(), x, 0, width-x, mauview.AlignLeft, tcell.StyleDefault.Foreground(mauview.Styles.PrimaryTextColor).Background(tcell.ColorDarkGreen))
|
2020-02-20 21:11:09 +01:00
|
|
|
|
x += drawn + 1
|
|
|
|
|
if x >= width {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-02-20 20:56:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) Draw(screen mauview.Screen) {
|
2020-03-01 16:11:56 +01:00
|
|
|
|
proxyScreen := msg.DrawReply(screen)
|
|
|
|
|
msg.Renderer.Draw(proxyScreen)
|
|
|
|
|
msg.DrawReactions(proxyScreen)
|
2020-02-20 23:29:29 +01:00
|
|
|
|
if msg.IsSelected {
|
|
|
|
|
w, h := screen.Size()
|
|
|
|
|
for x := 0; x < w; x++ {
|
|
|
|
|
for y := 0; y < h; y++ {
|
|
|
|
|
mainc, combc, style, _ := screen.GetContent(x, y)
|
|
|
|
|
_, bg, _ := style.Decompose()
|
|
|
|
|
if bg == tcell.ColorDefault {
|
2020-03-01 16:11:56 +01:00
|
|
|
|
screen.SetContent(x, y, mainc, combc, style.Background(tcell.ColorDarkGreen))
|
2020-02-20 23:29:29 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-07 17:21:38 +02:00
|
|
|
|
}
|
2019-04-10 01:19:38 +02:00
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) Clone() *UIMessage {
|
2019-04-10 20:06:19 +02:00
|
|
|
|
clone := *msg
|
2019-06-16 13:29:03 +02:00
|
|
|
|
clone.ReplyTo = nil
|
2020-02-20 20:56:03 +01:00
|
|
|
|
clone.Reactions = nil
|
2019-06-15 00:11:51 +02:00
|
|
|
|
clone.Renderer = clone.Renderer.Clone()
|
|
|
|
|
return &clone
|
2019-04-10 20:06:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) CalculateReplyBuffer(preferences config.UserPreferences, width int) {
|
2019-04-10 01:19:38 +02:00
|
|
|
|
if msg.ReplyTo == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
msg.ReplyTo.CalculateBuffer(preferences, width-1)
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) CalculateBuffer(preferences config.UserPreferences, width int) {
|
2019-06-16 13:29:03 +02:00
|
|
|
|
msg.Renderer.CalculateBuffer(preferences, width, msg)
|
|
|
|
|
msg.CalculateReplyBuffer(preferences, width)
|
2019-06-15 00:11:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (msg *UIMessage) DrawReply(screen mauview.Screen) mauview.Screen {
|
2019-04-10 01:19:38 +02:00
|
|
|
|
if msg.ReplyTo == nil {
|
|
|
|
|
return screen
|
|
|
|
|
}
|
|
|
|
|
width, height := screen.Size()
|
|
|
|
|
replyHeight := msg.ReplyTo.Height()
|
2019-04-13 16:04:52 +02:00
|
|
|
|
widget.WriteLineSimpleColor(screen, "In reply to", 1, 0, tcell.ColorGreen)
|
2019-06-15 00:11:51 +02:00
|
|
|
|
widget.WriteLineSimpleColor(screen, msg.ReplyTo.SenderName, 13, 0, msg.ReplyTo.SenderColor())
|
2019-04-13 16:04:52 +02:00
|
|
|
|
for y := 0; y < 1+replyHeight; y++ {
|
|
|
|
|
screen.SetCell(0, y, tcell.StyleDefault, '▊')
|
2019-04-10 01:19:38 +02:00
|
|
|
|
}
|
|
|
|
|
replyScreen := mauview.NewProxyScreen(screen, 1, 1, width-1, replyHeight)
|
|
|
|
|
msg.ReplyTo.Draw(replyScreen)
|
2019-04-13 16:04:52 +02:00
|
|
|
|
return mauview.NewProxyScreen(screen, 0, replyHeight+1, width, height-replyHeight-1)
|
2019-04-10 01:19:38 +02:00
|
|
|
|
}
|
2019-04-12 23:51:58 +02:00
|
|
|
|
|
2019-06-15 00:11:51 +02:00
|
|
|
|
func (msg *UIMessage) String() string {
|
|
|
|
|
return fmt.Sprintf(`&messages.UIMessage{
|
2019-04-12 23:51:58 +02:00
|
|
|
|
ID="%s", TxnID="%s",
|
|
|
|
|
Type="%s", Timestamp=%s,
|
|
|
|
|
Sender={ID="%s", Name="%s", Color=#%X},
|
|
|
|
|
IsService=%t, IsHighlight=%t,
|
2019-06-15 00:11:51 +02:00
|
|
|
|
Renderer=%s,
|
2019-04-12 23:51:58 +02:00
|
|
|
|
}`,
|
2019-06-15 00:11:51 +02:00
|
|
|
|
msg.EventID, msg.TxnID,
|
|
|
|
|
msg.Type, msg.Timestamp.String(),
|
|
|
|
|
msg.SenderID, msg.SenderName, msg.DefaultSenderColor.Hex(),
|
2020-02-20 20:56:03 +01:00
|
|
|
|
msg.IsService, msg.IsHighlight, msg.Renderer.String())
|
2019-04-12 23:51:58 +02:00
|
|
|
|
}
|
2019-06-15 00:11:51 +02:00
|
|
|
|
|
|
|
|
|
func (msg *UIMessage) PlainText() string {
|
|
|
|
|
return msg.Renderer.PlainText()
|
|
|
|
|
}
|