diff options
Diffstat (limited to 'ui/messages/parser/parser.go')
-rw-r--r-- | ui/messages/parser/parser.go | 287 |
1 files changed, 0 insertions, 287 deletions
diff --git a/ui/messages/parser/parser.go b/ui/messages/parser/parser.go deleted file mode 100644 index e48bd5f..0000000 --- a/ui/messages/parser/parser.go +++ /dev/null @@ -1,287 +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 parser - -import ( - "fmt" - "html" - "strings" - "time" - - "maunium.net/go/gomuks/debug" - "maunium.net/go/gomuks/interface" - "maunium.net/go/gomuks/matrix/rooms" - "maunium.net/go/gomuks/ui/messages" - "maunium.net/go/gomuks/ui/messages/tstring" - "maunium.net/go/gomuks/ui/widget" - "maunium.net/go/mautrix" - "maunium.net/go/tcell" -) - -func ParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Event) messages.UIMessage { - switch evt.Type { - case mautrix.EventSticker: - evt.Content.MsgType = mautrix.MsgImage - fallthrough - case mautrix.EventMessage: - return ParseMessage(matrix, room, evt) - case mautrix.StateTopic, mautrix.StateRoomName, mautrix.StateAliases, mautrix.StateCanonicalAlias: - return ParseStateEvent(matrix, room, evt) - case mautrix.StateMember: - return ParseMembershipEvent(room, evt) - } - 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) messages.UIMessage { - displayname := evt.Sender - member := room.GetMember(evt.Sender) - if member != nil { - displayname = member.Displayname - } - text := tstring.NewColorTString(displayname, widget.GetHashColor(evt.Sender)) - switch evt.Type { - case mautrix.StateTopic: - if len(evt.Content.Topic) == 0 { - text = text.AppendColor(" removed the topic.", tcell.ColorGreen) - } else { - text = text.AppendColor(" changed the topic to ", tcell.ColorGreen). - AppendStyle(evt.Content.Topic, tcell.StyleDefault.Underline(true)). - AppendColor(".", tcell.ColorGreen) - } - case mautrix.StateRoomName: - if len(evt.Content.Name) == 0 { - text = text.AppendColor(" removed the room name.", tcell.ColorGreen) - } else { - text = text.AppendColor(" changed the room name to ", tcell.ColorGreen). - AppendStyle(evt.Content.Name, tcell.StyleDefault.Underline(true)). - AppendColor(".", tcell.ColorGreen) - } - case mautrix.StateCanonicalAlias: - if len(evt.Content.Alias) == 0 { - text = text.AppendColor(" removed the main address of the room.", tcell.ColorGreen) - } else { - text = text.AppendColor(" changed the main address of the room to ", tcell.ColorGreen). - AppendStyle(evt.Content.Alias, tcell.StyleDefault.Underline(true)). - AppendColor(".", tcell.ColorGreen) - } - case mautrix.StateAliases: - text = ParseAliasEvent(evt, displayname) - } - ts := unixToTime(evt.Timestamp) - return messages.NewExpandedTextMessage(evt.ID, evt.Sender, displayname, mautrix.MessageType(evt.Type.Type), text, ts) -} - -func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Event) messages.UIMessage { - displayname := evt.Sender - member := room.GetMember(evt.Sender) - if member != nil { - displayname = member.Displayname - } - 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 messages.NewHTMLMessage(evt.ID, evt.Sender, displayname, evt.Content.MsgType, ParseHTMLMessage(room, evt, displayname), ts) - } - evt.Content.Body = strings.Replace(evt.Content.Body, "\t", " ", -1) - return messages.NewTextMessage(evt.ID, evt.Sender, displayname, evt.Content.MsgType, evt.Content.Body, ts) - 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 messages.NewImageMessage(matrix, evt.ID, evt.Sender, displayname, evt.Content.MsgType, evt.Content.Body, hs, id, data, ts) - } - return nil -} - -func getMembershipChangeMessage(evt *mautrix.Event, membership, prevMembership mautrix.Membership, senderDisplayname, displayname, prevDisplayname string) (sender string, text tstring.TString) { - switch membership { - case "invite": - sender = "---" - text = tstring.NewColorTString(fmt.Sprintf("%s invited %s.", senderDisplayname, displayname), tcell.ColorGreen) - text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender)) - text.Colorize(len(senderDisplayname)+len(" invited "), len(displayname), widget.GetHashColor(*evt.StateKey)) - case "join": - sender = "-->" - text = tstring.NewColorTString(fmt.Sprintf("%s joined the room.", displayname), tcell.ColorGreen) - text.Colorize(0, len(displayname), widget.GetHashColor(*evt.StateKey)) - case "leave": - sender = "<--" - if evt.Sender != *evt.StateKey { - if prevMembership == mautrix.MembershipBan { - text = tstring.NewColorTString(fmt.Sprintf("%s unbanned %s", senderDisplayname, displayname), tcell.ColorGreen) - text.Colorize(len(senderDisplayname)+len(" unbanned "), len(displayname), widget.GetHashColor(*evt.StateKey)) - } else { - text = tstring.NewColorTString(fmt.Sprintf("%s kicked %s: %s", senderDisplayname, displayname, evt.Content.Reason), tcell.ColorRed) - text.Colorize(len(senderDisplayname)+len(" kicked "), len(displayname), widget.GetHashColor(*evt.StateKey)) - } - text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender)) - } else { - if displayname == *evt.StateKey { - displayname = prevDisplayname - } - text = tstring.NewColorTString(fmt.Sprintf("%s left the room.", displayname), tcell.ColorRed) - text.Colorize(0, len(displayname), widget.GetHashColor(*evt.StateKey)) - } - case "ban": - text = tstring.NewColorTString(fmt.Sprintf("%s banned %s: %s", senderDisplayname, displayname, evt.Content.Reason), tcell.ColorRed) - text.Colorize(len(senderDisplayname)+len(" banned "), len(displayname), widget.GetHashColor(*evt.StateKey)) - text.Colorize(0, len(senderDisplayname), widget.GetHashColor(evt.Sender)) - } - return -} - -func getMembershipEventContent(room *rooms.Room, evt *mautrix.Event) (sender string, text tstring.TString) { - member := room.GetMember(evt.Sender) - senderDisplayname := evt.Sender - if member != nil { - senderDisplayname = member.Displayname - } - - membership := evt.Content.Membership - displayname := evt.Content.Displayname - if len(displayname) == 0 { - displayname = *evt.StateKey - } - - prevMembership := mautrix.MembershipLeave - prevDisplayname := *evt.StateKey - if evt.Unsigned.PrevContent != nil { - prevMembership = evt.Unsigned.PrevContent.Membership - prevDisplayname = evt.Unsigned.PrevContent.Displayname - if len(prevDisplayname) == 0 { - prevDisplayname = *evt.StateKey - } - } - - if membership != prevMembership { - sender, text = getMembershipChangeMessage(evt, membership, prevMembership, senderDisplayname, displayname, prevDisplayname) - } else if displayname != prevDisplayname { - sender = "---" - color := widget.GetHashColor(*evt.StateKey) - text = tstring.NewBlankTString(). - AppendColor(prevDisplayname, color). - AppendColor(" changed their display name to ", tcell.ColorGreen). - AppendColor(displayname, color). - AppendColor(".", tcell.ColorGreen) - } - return -} - -func ParseMembershipEvent(room *rooms.Room, evt *mautrix.Event) messages.UIMessage { - displayname, text := getMembershipEventContent(room, evt) - if len(text) == 0 { - return nil - } - - ts := unixToTime(evt.Timestamp) - return messages.NewExpandedTextMessage(evt.ID, evt.Sender, displayname, "m.room.member", text, ts) -} - -func ParseAliasEvent(evt *mautrix.Event, displayname string) tstring.TString { - var prevAliases []string - if evt.Unsigned.PrevContent != nil { - prevAliases = evt.Unsigned.PrevContent.Aliases - } - aliases := evt.Content.Aliases - var added, removed []tstring.TString -Outer1: - for _, oldAlias := range prevAliases { - for _, newAlias := range aliases { - if oldAlias == newAlias { - continue Outer1 - } - } - removed = append(removed, tstring.NewStyleTString(oldAlias, tcell.StyleDefault.Foreground(widget.GetHashColor(oldAlias)).Underline(true))) - } -Outer2: - for _, newAlias := range aliases { - for _, oldAlias := range prevAliases { - if oldAlias == newAlias { - continue Outer2 - } - } - added = append(added, tstring.NewStyleTString(newAlias, tcell.StyleDefault.Foreground(widget.GetHashColor(newAlias)).Underline(true))) - } - var addedStr, removedStr tstring.TString - if len(added) == 1 { - addedStr = added[0] - } else if len(added) > 1 { - addedStr = tstring. - Join(added[:len(added)-1], ", "). - Append(" and "). - AppendTString(added[len(added)-1]) - } - if len(removed) == 1 { - removedStr = removed[0] - } else if len(removed) > 1 { - removedStr = tstring. - Join(removed[:len(removed)-1], ", "). - Append(" and "). - AppendTString(removed[len(removed)-1]) - } - text := tstring.NewBlankTString() - if len(addedStr) > 0 && len(removedStr) > 0 { - text = text.AppendColor(fmt.Sprintf("%s added ", displayname), tcell.ColorGreen). - AppendTString(addedStr). - AppendColor(" and removed ", tcell.ColorGreen). - AppendTString(removedStr). - AppendColor(" as addresses for this room.", tcell.ColorGreen) - } else if len(addedStr) > 0 { - text = text.AppendColor(fmt.Sprintf("%s added ", displayname), tcell.ColorGreen). - AppendTString(addedStr). - AppendColor(" as addresses for this room.", tcell.ColorGreen) - } else if len(removedStr) > 0 { - text = text.AppendColor(fmt.Sprintf("%s removed ", displayname), tcell.ColorGreen). - AppendTString(removedStr). - AppendColor(" as addresses for this room.", tcell.ColorGreen) - } else { - return nil - } - return text -} |