2018-04-10 18:31:28 +02:00
|
|
|
// gomuks - A terminal Matrix client written in Go.
|
2020-04-19 17:10:14 +02:00
|
|
|
// Copyright (C) 2020 Tulir Asokan
|
2018-04-10 18:31:28 +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-10 18:31:28 +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-10 18:31:28 +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-10 18:31:28 +02:00
|
|
|
|
2019-04-09 17:42:49 +02:00
|
|
|
package messages
|
2018-04-10 18:31:28 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2018-04-24 21:08:57 +02:00
|
|
|
"strings"
|
2018-04-10 18:31:28 +02:00
|
|
|
|
2022-04-15 11:53:09 +02:00
|
|
|
"go.mau.fi/tcell"
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
"maunium.net/go/mautrix/event"
|
|
|
|
"maunium.net/go/mautrix/id"
|
2019-04-09 17:42:49 +02:00
|
|
|
|
2020-04-29 01:45:54 +02:00
|
|
|
"maunium.net/go/gomuks/debug"
|
2022-04-15 11:53:09 +02:00
|
|
|
ifc "maunium.net/go/gomuks/interface"
|
2020-04-29 01:45:54 +02:00
|
|
|
"maunium.net/go/gomuks/matrix/muksevt"
|
2018-04-10 18:31:28 +02:00
|
|
|
"maunium.net/go/gomuks/matrix/rooms"
|
2019-04-09 17:45:41 +02:00
|
|
|
"maunium.net/go/gomuks/ui/messages/html"
|
2018-04-11 16:57:15 +02:00
|
|
|
"maunium.net/go/gomuks/ui/messages/tstring"
|
2018-04-10 18:31:28 +02:00
|
|
|
"maunium.net/go/gomuks/ui/widget"
|
|
|
|
)
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
func getCachedEvent(mainView ifc.MainView, roomID id.RoomID, eventID id.EventID) *UIMessage {
|
2019-04-10 20:06:19 +02:00
|
|
|
if roomView := mainView.GetRoom(roomID); roomView != nil {
|
|
|
|
if replyToIfcMsg := roomView.GetEvent(eventID); replyToIfcMsg != nil {
|
2019-06-15 00:11:51 +02:00
|
|
|
if replyToMsg, ok := replyToIfcMsg.(*UIMessage); ok && replyToMsg != nil {
|
2019-04-10 20:06:19 +02:00
|
|
|
return replyToMsg
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
func ParseEvent(matrix ifc.MatrixContainer, mainView ifc.MainView, room *rooms.Room, evt *muksevt.Event) *UIMessage {
|
2019-04-09 17:45:41 +02:00
|
|
|
msg := directParseEvent(matrix, room, evt)
|
|
|
|
if msg == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2020-04-19 14:00:49 +02:00
|
|
|
if content, ok := evt.Content.Parsed.(*event.MessageEventContent); ok && len(content.GetReplyTo()) > 0 {
|
|
|
|
if replyToMsg := getCachedEvent(mainView, room.ID, content.GetReplyTo()); replyToMsg != nil {
|
2019-06-16 13:29:03 +02:00
|
|
|
msg.ReplyTo = replyToMsg.Clone()
|
2020-04-19 14:00:49 +02:00
|
|
|
} else if replyToEvt, _ := matrix.GetEvent(room, content.GetReplyTo()); replyToEvt != nil {
|
2022-04-15 13:03:08 +02:00
|
|
|
if replyToMsg = directParseEvent(matrix, room, replyToEvt); replyToMsg != nil {
|
2019-06-15 00:11:51 +02:00
|
|
|
msg.ReplyTo = replyToMsg
|
2020-02-20 20:56:03 +01:00
|
|
|
msg.ReplyTo.Reactions = nil
|
2019-04-10 01:19:38 +02:00
|
|
|
} else {
|
|
|
|
// TODO add unrenderable reply header
|
|
|
|
}
|
2019-04-09 17:45:41 +02:00
|
|
|
} else {
|
|
|
|
// TODO add unknown reply header
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return msg
|
|
|
|
}
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
func directParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *muksevt.Event) *UIMessage {
|
|
|
|
displayname := string(evt.Sender)
|
2019-06-15 00:11:51 +02:00
|
|
|
member := room.GetMember(evt.Sender)
|
|
|
|
if member != nil {
|
|
|
|
displayname = member.Displayname
|
|
|
|
}
|
2020-04-16 18:27:35 +02:00
|
|
|
if evt.Unsigned.RedactedBecause != nil || evt.Type == event.EventRedaction {
|
2019-06-16 19:42:13 +02:00
|
|
|
return NewRedactedMessage(evt, displayname)
|
|
|
|
}
|
2020-04-19 14:00:49 +02:00
|
|
|
switch content := evt.Content.Parsed.(type) {
|
|
|
|
case *event.MessageEventContent:
|
|
|
|
if evt.Type == event.EventSticker {
|
|
|
|
content.MsgType = event.MsgImage
|
|
|
|
}
|
2019-06-15 00:11:51 +02:00
|
|
|
return ParseMessage(matrix, room, evt, displayname)
|
2020-06-23 21:28:28 +02:00
|
|
|
case *muksevt.BadEncryptedContent:
|
|
|
|
return NewExpandedTextMessage(evt, displayname, tstring.NewStyleTString(content.Reason, tcell.StyleDefault.Italic(true)))
|
|
|
|
case *muksevt.EncryptionUnsupportedContent:
|
|
|
|
return NewExpandedTextMessage(evt, displayname, tstring.NewStyleTString("gomuks not built with encryption support", tcell.StyleDefault.Italic(true)))
|
2020-04-19 14:00:49 +02:00
|
|
|
case *event.TopicEventContent, *event.RoomNameEventContent, *event.CanonicalAliasEventContent:
|
2019-06-15 00:11:51 +02:00
|
|
|
return ParseStateEvent(evt, displayname)
|
2020-04-19 14:00:49 +02:00
|
|
|
case *event.MemberEventContent:
|
2018-04-18 12:38:33 +02:00
|
|
|
return ParseMembershipEvent(room, evt)
|
2020-04-19 14:00:49 +02:00
|
|
|
default:
|
|
|
|
debug.Printf("Unknown event content type %T in directParseEvent", content)
|
|
|
|
return nil
|
2018-04-10 18:31:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-23 20:43:25 +02:00
|
|
|
func findAltAliasDifference(newList, oldList []id.RoomAlias) (addedStr, removedStr tstring.TString) {
|
2020-06-17 13:15:22 +02:00
|
|
|
var addedList, removedList []tstring.TString
|
|
|
|
OldLoop:
|
|
|
|
for _, oldAlias := range oldList {
|
|
|
|
for _, newAlias := range newList {
|
|
|
|
if oldAlias == newAlias {
|
|
|
|
continue OldLoop
|
|
|
|
}
|
|
|
|
}
|
2020-06-23 20:43:25 +02:00
|
|
|
removedList = append(removedList, tstring.NewStyleTString(string(oldAlias), tcell.StyleDefault.Foreground(widget.GetHashColor(oldAlias)).Underline(true)))
|
2020-06-17 13:15:22 +02:00
|
|
|
}
|
|
|
|
NewLoop:
|
|
|
|
for _, newAlias := range newList {
|
|
|
|
for _, oldAlias := range oldList {
|
|
|
|
if newAlias == oldAlias {
|
|
|
|
continue NewLoop
|
|
|
|
}
|
|
|
|
}
|
2020-06-23 20:43:25 +02:00
|
|
|
addedList = append(addedList, tstring.NewStyleTString(string(newAlias), tcell.StyleDefault.Foreground(widget.GetHashColor(newAlias)).Underline(true)))
|
2020-06-17 13:15:22 +02:00
|
|
|
}
|
|
|
|
if len(addedList) == 1 {
|
|
|
|
addedStr = tstring.NewColorTString("added alternative address ", tcell.ColorGreen).AppendTString(addedList[0])
|
|
|
|
} else if len(addedList) != 0 {
|
|
|
|
addedStr = tstring.
|
|
|
|
Join(addedList[:len(addedList)-1], ", ").
|
|
|
|
PrependColor("added alternative addresses ", tcell.ColorGreen).
|
|
|
|
AppendColor(" and ", tcell.ColorGreen).
|
|
|
|
AppendTString(addedList[len(addedList)-1])
|
|
|
|
}
|
|
|
|
if len(removedList) == 1 {
|
|
|
|
removedStr = tstring.NewColorTString("removed alternative address ", tcell.ColorGreen).AppendTString(removedList[0])
|
|
|
|
} else if len(removedList) != 0 {
|
|
|
|
removedStr = tstring.
|
|
|
|
Join(removedList[:len(removedList)-1], ", ").
|
|
|
|
PrependColor("removed alternative addresses ", tcell.ColorGreen).
|
|
|
|
AppendColor(" and ", tcell.ColorGreen).
|
|
|
|
AppendTString(removedList[len(removedList)-1])
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
func ParseStateEvent(evt *muksevt.Event, displayname string) *UIMessage {
|
2020-06-17 13:15:22 +02:00
|
|
|
text := tstring.NewColorTString(displayname, widget.GetHashColor(evt.Sender)).Append(" ")
|
2020-04-19 14:00:49 +02:00
|
|
|
switch content := evt.Content.Parsed.(type) {
|
|
|
|
case *event.TopicEventContent:
|
|
|
|
if len(content.Topic) == 0 {
|
2020-06-17 13:15:22 +02:00
|
|
|
text = text.AppendColor("removed the topic.", tcell.ColorGreen)
|
2019-01-11 22:28:47 +01:00
|
|
|
} else {
|
2020-06-17 13:15:22 +02:00
|
|
|
text = text.AppendColor("changed the topic to ", tcell.ColorGreen).
|
2020-04-19 14:00:49 +02:00
|
|
|
AppendStyle(content.Topic, tcell.StyleDefault.Underline(true)).
|
2019-01-11 22:28:47 +01:00
|
|
|
AppendColor(".", tcell.ColorGreen)
|
|
|
|
}
|
2020-04-19 14:00:49 +02:00
|
|
|
case *event.RoomNameEventContent:
|
|
|
|
if len(content.Name) == 0 {
|
2020-06-17 13:15:22 +02:00
|
|
|
text = text.AppendColor("removed the room name.", tcell.ColorGreen)
|
2019-01-11 22:28:47 +01:00
|
|
|
} else {
|
2020-06-17 13:15:22 +02:00
|
|
|
text = text.AppendColor("changed the room name to ", tcell.ColorGreen).
|
2020-04-19 14:00:49 +02:00
|
|
|
AppendStyle(content.Name, tcell.StyleDefault.Underline(true)).
|
2019-01-11 22:28:47 +01:00
|
|
|
AppendColor(".", tcell.ColorGreen)
|
|
|
|
}
|
2020-04-19 14:00:49 +02:00
|
|
|
case *event.CanonicalAliasEventContent:
|
2020-06-24 21:54:41 +02:00
|
|
|
prevContent := &event.CanonicalAliasEventContent{}
|
|
|
|
if evt.Unsigned.PrevContent != nil {
|
|
|
|
_ = evt.Unsigned.PrevContent.ParseRaw(evt.Type)
|
|
|
|
prevContent = evt.Unsigned.PrevContent.AsCanonicalAlias()
|
|
|
|
}
|
2020-06-17 13:15:22 +02:00
|
|
|
debug.Printf("%+v -> %+v", prevContent, content)
|
|
|
|
if len(content.Alias) == 0 && len(prevContent.Alias) != 0 {
|
|
|
|
text = text.AppendColor("removed the main address of the room", tcell.ColorGreen)
|
|
|
|
} else if content.Alias != prevContent.Alias {
|
|
|
|
text = text.
|
|
|
|
AppendColor("changed the main address of the room to ", tcell.ColorGreen).
|
|
|
|
AppendStyle(string(content.Alias), tcell.StyleDefault.Underline(true))
|
2019-01-11 22:28:47 +01:00
|
|
|
} else {
|
2020-06-17 13:15:22 +02:00
|
|
|
added, removed := findAltAliasDifference(content.AltAliases, prevContent.AltAliases)
|
|
|
|
if len(added) > 0 {
|
|
|
|
if len(removed) > 0 {
|
|
|
|
text = text.
|
|
|
|
AppendTString(added).
|
|
|
|
AppendColor(" and ", tcell.ColorGreen).
|
|
|
|
AppendTString(removed)
|
|
|
|
} else {
|
|
|
|
text = text.AppendTString(added)
|
|
|
|
}
|
|
|
|
} else if len(removed) > 0 {
|
|
|
|
text = text.AppendTString(removed)
|
|
|
|
} else {
|
|
|
|
text = text.AppendColor("changed nothing", tcell.ColorGreen)
|
|
|
|
}
|
|
|
|
text = text.AppendColor(" for this room", tcell.ColorGreen)
|
2019-01-11 22:28:47 +01:00
|
|
|
}
|
|
|
|
}
|
2019-04-09 17:45:41 +02:00
|
|
|
return NewExpandedTextMessage(evt, displayname, text)
|
2019-01-11 22:28:47 +01:00
|
|
|
}
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *muksevt.Event, displayname string) *UIMessage {
|
2020-04-19 14:00:49 +02:00
|
|
|
content := evt.Content.AsMessage()
|
|
|
|
if len(content.GetReplyTo()) > 0 {
|
|
|
|
content.RemoveReplyFallback()
|
2018-11-13 23:00:35 +01:00
|
|
|
}
|
2019-06-17 12:46:02 +02:00
|
|
|
if len(evt.Gomuks.Edits) > 0 {
|
2020-07-05 16:54:05 +02:00
|
|
|
newContent := evt.Gomuks.Edits[len(evt.Gomuks.Edits)-1].Content.AsMessage().NewContent
|
|
|
|
if newContent != nil {
|
|
|
|
content = newContent
|
|
|
|
}
|
2019-06-15 00:11:51 +02:00
|
|
|
}
|
2020-04-19 14:00:49 +02:00
|
|
|
switch content.MsgType {
|
2020-04-16 18:27:35 +02:00
|
|
|
case event.MsgText, event.MsgNotice, event.MsgEmote:
|
2020-04-19 14:00:49 +02:00
|
|
|
if content.Format == event.FormatHTML {
|
2022-04-15 21:09:15 +02:00
|
|
|
return NewHTMLMessage(evt, displayname, html.Parse(matrix.Preferences(), room, content, evt, displayname))
|
2018-04-13 23:34:25 +02:00
|
|
|
}
|
2020-04-19 14:00:49 +02:00
|
|
|
content.Body = strings.Replace(content.Body, "\t", " ", -1)
|
2022-04-15 22:44:59 +02:00
|
|
|
return NewHTMLMessage(evt, displayname, html.TextToEntity(content.Body, evt.ID, matrix.Preferences().InlineURLs))
|
2020-04-16 18:27:35 +02:00
|
|
|
case event.MsgImage, event.MsgVideo, event.MsgAudio, event.MsgFile:
|
2020-04-08 14:30:29 +02:00
|
|
|
msg := NewFileMessage(matrix, evt, displayname)
|
|
|
|
if !matrix.Preferences().DisableDownloads {
|
|
|
|
renderer := msg.Renderer.(*FileMessage)
|
|
|
|
renderer.DownloadPreview()
|
2018-04-10 18:31:28 +02:00
|
|
|
}
|
2020-04-08 14:30:29 +02:00
|
|
|
return msg
|
2018-04-10 18:31:28 +02:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-04-19 14:00:49 +02:00
|
|
|
func getMembershipChangeMessage(evt *muksevt.Event, content *event.MemberEventContent, prevMembership event.Membership, senderDisplayname, displayname, prevDisplayname string) (sender string, text tstring.TString) {
|
|
|
|
switch content.Membership {
|
2018-05-22 16:36:41 +02:00
|
|
|
case "invite":
|
|
|
|
sender = "---"
|
|
|
|
text = tstring.NewColorTString(fmt.Sprintf("%s invited %s.", senderDisplayname, displayname), tcell.ColorGreen)
|
|
|
|
text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender))
|
2020-04-16 18:27:35 +02:00
|
|
|
text.Colorize(len(senderDisplayname)+len(" invited "), len(displayname), widget.GetHashColor(evt.StateKey))
|
2018-05-22 16:36:41 +02:00
|
|
|
case "join":
|
|
|
|
sender = "-->"
|
2020-04-16 18:27:35 +02:00
|
|
|
if prevMembership == event.MembershipInvite {
|
2020-02-22 01:56:10 +01:00
|
|
|
text = tstring.NewColorTString(fmt.Sprintf("%s accepted the invite.", displayname), tcell.ColorGreen)
|
|
|
|
} else {
|
|
|
|
text = tstring.NewColorTString(fmt.Sprintf("%s joined the room.", displayname), tcell.ColorGreen)
|
|
|
|
}
|
2020-04-16 18:27:35 +02:00
|
|
|
text.Colorize(0, len(displayname), widget.GetHashColor(evt.StateKey))
|
2018-05-22 16:36:41 +02:00
|
|
|
case "leave":
|
|
|
|
sender = "<--"
|
2020-04-16 18:27:35 +02:00
|
|
|
if evt.Sender != id.UserID(*evt.StateKey) {
|
|
|
|
if prevMembership == event.MembershipBan {
|
2018-05-22 16:36:41 +02:00
|
|
|
text = tstring.NewColorTString(fmt.Sprintf("%s unbanned %s", senderDisplayname, displayname), tcell.ColorGreen)
|
2020-04-16 18:27:35 +02:00
|
|
|
text.Colorize(len(senderDisplayname)+len(" unbanned "), len(displayname), widget.GetHashColor(evt.StateKey))
|
2018-05-22 16:36:41 +02:00
|
|
|
} else {
|
2020-04-19 14:00:49 +02:00
|
|
|
text = tstring.NewColorTString(fmt.Sprintf("%s kicked %s: %s", senderDisplayname, displayname, content.Reason), tcell.ColorRed)
|
2020-04-16 18:27:35 +02:00
|
|
|
text.Colorize(len(senderDisplayname)+len(" kicked "), len(displayname), widget.GetHashColor(evt.StateKey))
|
2018-05-22 16:36:41 +02:00
|
|
|
}
|
|
|
|
text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender))
|
|
|
|
} else {
|
|
|
|
if displayname == *evt.StateKey {
|
|
|
|
displayname = prevDisplayname
|
|
|
|
}
|
2020-04-16 18:27:35 +02:00
|
|
|
if prevMembership == event.MembershipInvite {
|
2020-02-22 01:56:10 +01:00
|
|
|
text = tstring.NewColorTString(fmt.Sprintf("%s rejected the invite.", displayname), tcell.ColorRed)
|
|
|
|
} else {
|
|
|
|
text = tstring.NewColorTString(fmt.Sprintf("%s left the room.", displayname), tcell.ColorRed)
|
|
|
|
}
|
2020-04-16 18:27:35 +02:00
|
|
|
text.Colorize(0, len(displayname), widget.GetHashColor(evt.StateKey))
|
2018-05-22 16:36:41 +02:00
|
|
|
}
|
|
|
|
case "ban":
|
2020-04-19 14:00:49 +02:00
|
|
|
text = tstring.NewColorTString(fmt.Sprintf("%s banned %s: %s", senderDisplayname, displayname, content.Reason), tcell.ColorRed)
|
2020-04-16 18:27:35 +02:00
|
|
|
text.Colorize(len(senderDisplayname)+len(" banned "), len(displayname), widget.GetHashColor(evt.StateKey))
|
2018-05-22 16:36:41 +02:00
|
|
|
text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender))
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
func getMembershipEventContent(room *rooms.Room, evt *muksevt.Event) (sender string, text tstring.TString) {
|
2018-04-18 12:38:33 +02:00
|
|
|
member := room.GetMember(evt.Sender)
|
2020-04-16 18:27:35 +02:00
|
|
|
senderDisplayname := string(evt.Sender)
|
2018-04-18 12:38:33 +02:00
|
|
|
if member != nil {
|
2018-09-05 09:55:48 +02:00
|
|
|
senderDisplayname = member.Displayname
|
2018-04-18 12:38:33 +02:00
|
|
|
}
|
2018-04-18 16:33:59 +02:00
|
|
|
|
2020-04-19 14:00:49 +02:00
|
|
|
content := evt.Content.AsMember()
|
|
|
|
displayname := content.Displayname
|
2018-04-10 18:31:28 +02:00
|
|
|
if len(displayname) == 0 {
|
|
|
|
displayname = *evt.StateKey
|
|
|
|
}
|
2018-04-18 16:33:59 +02:00
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
prevMembership := event.MembershipLeave
|
2018-04-18 16:33:59 +02:00
|
|
|
prevDisplayname := *evt.StateKey
|
2018-04-10 18:31:28 +02:00
|
|
|
if evt.Unsigned.PrevContent != nil {
|
2020-06-24 21:59:47 +02:00
|
|
|
_ = evt.Unsigned.PrevContent.ParseRaw(evt.Type)
|
2020-04-19 14:00:49 +02:00
|
|
|
prevContent := evt.Unsigned.PrevContent.AsMember()
|
|
|
|
prevMembership = prevContent.Membership
|
|
|
|
prevDisplayname = prevContent.Displayname
|
2018-05-15 15:09:56 +02:00
|
|
|
if len(prevDisplayname) == 0 {
|
|
|
|
prevDisplayname = *evt.StateKey
|
|
|
|
}
|
2018-04-10 18:31:28 +02:00
|
|
|
}
|
|
|
|
|
2020-04-19 14:00:49 +02:00
|
|
|
if content.Membership != prevMembership {
|
|
|
|
sender, text = getMembershipChangeMessage(evt, content, prevMembership, senderDisplayname, displayname, prevDisplayname)
|
2018-04-10 18:31:28 +02:00
|
|
|
} else if displayname != prevDisplayname {
|
|
|
|
sender = "---"
|
2020-04-16 18:27:35 +02:00
|
|
|
color := widget.GetHashColor(evt.StateKey)
|
2019-01-11 22:28:47 +01:00
|
|
|
text = tstring.NewBlankTString().
|
|
|
|
AppendColor(prevDisplayname, color).
|
|
|
|
AppendColor(" changed their display name to ", tcell.ColorGreen).
|
|
|
|
AppendColor(displayname, color).
|
|
|
|
AppendColor(".", tcell.ColorGreen)
|
2018-04-10 18:31:28 +02:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-04-16 18:27:35 +02:00
|
|
|
func ParseMembershipEvent(room *rooms.Room, evt *muksevt.Event) *UIMessage {
|
2018-04-18 12:38:33 +02:00
|
|
|
displayname, text := getMembershipEventContent(room, evt)
|
2018-04-18 16:33:59 +02:00
|
|
|
if len(text) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-04-09 17:45:41 +02:00
|
|
|
return NewExpandedTextMessage(evt, displayname, text)
|
2018-04-10 18:31:28 +02:00
|
|
|
}
|