Use already parsed events for replies if possible
This commit is contained in:
parent
9132e2b750
commit
db0e24ccc2
@ -61,6 +61,7 @@ type RoomView interface {
|
|||||||
UpdateUserList()
|
UpdateUserList()
|
||||||
|
|
||||||
ParseEvent(evt *mautrix.Event) Message
|
ParseEvent(evt *mautrix.Event) Message
|
||||||
|
GetEvent(eventID string) Message
|
||||||
AddMessage(message Message)
|
AddMessage(message Message)
|
||||||
AddServiceMessage(message string)
|
AddServiceMessage(message string)
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ func (view *MessageView) handleMessageClick(message messages.UIMessage) bool {
|
|||||||
case *messages.ImageMessage:
|
case *messages.ImageMessage:
|
||||||
open.Open(message.Path())
|
open.Open(message.Path())
|
||||||
case messages.UIMessage:
|
case messages.UIMessage:
|
||||||
debug.Print("Message clicked:", message.NotificationContent())
|
debug.Print("Message clicked:", message)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,6 @@ type BaseMessage struct {
|
|||||||
MsgSource json.RawMessage
|
MsgSource json.RawMessage
|
||||||
ReplyTo UIMessage
|
ReplyTo UIMessage
|
||||||
buffer []tstring.TString
|
buffer []tstring.TString
|
||||||
plainBuffer []tstring.TString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBaseMessage(event *mautrix.Event, displayname string) BaseMessage {
|
func newBaseMessage(event *mautrix.Event, displayname string) BaseMessage {
|
||||||
@ -259,6 +258,12 @@ func (msg *BaseMessage) Draw(screen mauview.Screen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (msg *BaseMessage) clone() BaseMessage {
|
||||||
|
clone := *msg
|
||||||
|
clone.buffer = nil
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
func (msg *BaseMessage) CalculateReplyBuffer(preferences config.UserPreferences, width int) {
|
func (msg *BaseMessage) CalculateReplyBuffer(preferences config.UserPreferences, width int) {
|
||||||
if msg.ReplyTo == nil {
|
if msg.ReplyTo == nil {
|
||||||
return
|
return
|
||||||
|
@ -55,6 +55,14 @@ func NewDateChangeMessage(text string) UIMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (msg *ExpandedTextMessage) Clone() UIMessage {
|
||||||
|
return &ExpandedTextMessage{
|
||||||
|
BaseMessage: msg.BaseMessage.clone(),
|
||||||
|
MsgText: msg.MsgText.Clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (msg *ExpandedTextMessage) GenerateText() tstring.TString {
|
func (msg *ExpandedTextMessage) GenerateText() tstring.TString {
|
||||||
return msg.MsgText
|
return msg.MsgText
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package html
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"maunium.net/go/mauview"
|
"maunium.net/go/mauview"
|
||||||
)
|
)
|
||||||
@ -37,6 +38,10 @@ func NewBlockquoteEntity(children []Entity) *BlockquoteEntity {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (be *BlockquoteEntity) Clone() Entity {
|
||||||
|
return &BlockquoteEntity{BaseEntity: be.BaseEntity.Clone().(*BaseEntity)}
|
||||||
|
}
|
||||||
|
|
||||||
func (be *BlockquoteEntity) Draw(screen mauview.Screen) {
|
func (be *BlockquoteEntity) Draw(screen mauview.Screen) {
|
||||||
be.BaseEntity.Draw(screen)
|
be.BaseEntity.Draw(screen)
|
||||||
for y := 0; y < be.height; y++ {
|
for y := 0; y < be.height; y++ {
|
||||||
@ -44,6 +49,33 @@ func (be *BlockquoteEntity) Draw(screen mauview.Screen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (be *BlockquoteEntity) PlainText() string {
|
||||||
|
if len(be.Children) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var buf strings.Builder
|
||||||
|
newlined := false
|
||||||
|
for i, child := range be.Children {
|
||||||
|
if i != 0 && child.IsBlock() && !newlined {
|
||||||
|
buf.WriteRune('\n')
|
||||||
|
}
|
||||||
|
newlined = false
|
||||||
|
for i, row := range strings.Split(child.PlainText(), "\n") {
|
||||||
|
if i != 0 {
|
||||||
|
buf.WriteRune('\n')
|
||||||
|
}
|
||||||
|
buf.WriteRune('>')
|
||||||
|
buf.WriteRune(' ')
|
||||||
|
buf.WriteString(row)
|
||||||
|
}
|
||||||
|
if child.IsBlock() {
|
||||||
|
buf.WriteRune('\n')
|
||||||
|
newlined = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
func (be *BlockquoteEntity) String() string {
|
func (be *BlockquoteEntity) String() string {
|
||||||
return fmt.Sprintf("&html.BlockquoteEntity{%s},\n", be.BaseEntity)
|
return fmt.Sprintf("&html.BlockquoteEntity{%s},\n", be.BaseEntity)
|
||||||
}
|
}
|
||||||
|
@ -26,3 +26,15 @@ func NewBreakEntity() *BreakEntity {
|
|||||||
Block: true,
|
Block: true,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (be *BreakEntity) Clone() Entity {
|
||||||
|
return NewBreakEntity()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (be *BreakEntity) PlainText() string {
|
||||||
|
return "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (be *BreakEntity) String() string {
|
||||||
|
return "&html.BreakEntity{},\n"
|
||||||
|
}
|
||||||
|
@ -37,6 +37,13 @@ func NewCodeBlockEntity(children []Entity, background tcell.Style) *CodeBlockEnt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ce *CodeBlockEntity) Clone() Entity {
|
||||||
|
return &CodeBlockEntity{
|
||||||
|
BaseEntity: ce.BaseEntity.Clone().(*BaseEntity),
|
||||||
|
Background: ce.Background,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (ce *CodeBlockEntity) Draw(screen mauview.Screen) {
|
func (ce *CodeBlockEntity) Draw(screen mauview.Screen) {
|
||||||
screen.Fill(' ', ce.Background)
|
screen.Fill(' ', ce.Background)
|
||||||
ce.BaseEntity.Draw(screen)
|
ce.BaseEntity.Draw(screen)
|
||||||
|
@ -165,17 +165,20 @@ func (he *BaseEntity) PlainText() string {
|
|||||||
buf.WriteString(he.Text)
|
buf.WriteString(he.Text)
|
||||||
newlined := false
|
newlined := false
|
||||||
for _, child := range he.Children {
|
for _, child := range he.Children {
|
||||||
if child.IsBlock() && !newlined {
|
text := child.PlainText()
|
||||||
|
if !strings.HasPrefix(text, "\n") && child.IsBlock() && !newlined {
|
||||||
buf.WriteRune('\n')
|
buf.WriteRune('\n')
|
||||||
}
|
}
|
||||||
newlined = false
|
newlined = false
|
||||||
buf.WriteString(child.PlainText())
|
buf.WriteString(text)
|
||||||
if child.IsBlock() {
|
if child.IsBlock() {
|
||||||
buf.WriteRune('\n')
|
if !strings.HasSuffix(text, "\n") {
|
||||||
|
buf.WriteRune('\n')
|
||||||
|
}
|
||||||
newlined = true
|
newlined = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buf.String()
|
return strings.TrimSpace(buf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws this entity onto the given mauview Screen.
|
// Draw draws this entity onto the given mauview Screen.
|
||||||
|
56
ui/messages/html/horizontalline.go
Normal file
56
ui/messages/html/horizontalline.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// 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 html
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"maunium.net/go/mauview"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HorizontalLineEntity struct {
|
||||||
|
*BaseEntity
|
||||||
|
}
|
||||||
|
|
||||||
|
const HorizontalLineChar = '━'
|
||||||
|
|
||||||
|
func NewHorizontalLineEntity() *HorizontalLineEntity {
|
||||||
|
return &HorizontalLineEntity{&BaseEntity{
|
||||||
|
Tag: "hr",
|
||||||
|
Block: true,
|
||||||
|
DefaultHeight: 1,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (he *HorizontalLineEntity) Clone() Entity {
|
||||||
|
return NewHorizontalLineEntity()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (he *HorizontalLineEntity) Draw(screen mauview.Screen) {
|
||||||
|
width, _ := screen.Size()
|
||||||
|
for x := 0; x < width; x++ {
|
||||||
|
screen.SetContent(x, 0, HorizontalLineChar, nil, he.Style)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (he *HorizontalLineEntity) PlainText() string {
|
||||||
|
return strings.Repeat(string(HorizontalLineChar), 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (he *HorizontalLineEntity) String() string {
|
||||||
|
return "&html.HorizontalLineEntity{},\n"
|
||||||
|
}
|
@ -56,6 +56,14 @@ func NewListEntity(ordered bool, start int, children []Entity) *ListEntity {
|
|||||||
return entity
|
return entity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (le *ListEntity) Clone() Entity {
|
||||||
|
return &ListEntity{
|
||||||
|
BaseEntity: le.BaseEntity.Clone().(*BaseEntity),
|
||||||
|
Ordered: le.Ordered,
|
||||||
|
Start: le.Start,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (le *ListEntity) Draw(screen mauview.Screen) {
|
func (le *ListEntity) Draw(screen mauview.Screen) {
|
||||||
width, _ := screen.Size()
|
width, _ := screen.Size()
|
||||||
|
|
||||||
@ -75,6 +83,31 @@ func (le *ListEntity) Draw(screen mauview.Screen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (le *ListEntity) PlainText() string {
|
||||||
|
if len(le.Children) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var buf strings.Builder
|
||||||
|
for i, child := range le.Children {
|
||||||
|
indent := strings.Repeat(" ", le.Indent)
|
||||||
|
if le.Ordered {
|
||||||
|
number := le.Start + i
|
||||||
|
_, _ = fmt.Fprintf(&buf, "%d. %s", number, strings.Repeat(" ", le.Indent-2-digits(number)))
|
||||||
|
} else {
|
||||||
|
buf.WriteString("● ")
|
||||||
|
}
|
||||||
|
for j, row := range strings.Split(child.PlainText(), "\n") {
|
||||||
|
if j != 0 {
|
||||||
|
buf.WriteRune('\n')
|
||||||
|
buf.WriteString(indent)
|
||||||
|
}
|
||||||
|
buf.WriteString(row)
|
||||||
|
}
|
||||||
|
buf.WriteRune('\n')
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
func (le *ListEntity) String() string {
|
func (le *ListEntity) String() string {
|
||||||
return fmt.Sprintf("&html.ListEntity{Ordered=%t, Start=%d, Base=%s},\n", le.Ordered, le.Start, le.BaseEntity)
|
return fmt.Sprintf("&html.ListEntity{Ordered=%t, Start=%d, Base=%s},\n", le.Ordered, le.Start, le.BaseEntity)
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ func (parser *htmlParser) basicFormatToEntity(node *html.Node) Entity {
|
|||||||
entity.AdjustStyle(AdjustStyleBold)
|
entity.AdjustStyle(AdjustStyleBold)
|
||||||
case "i", "em":
|
case "i", "em":
|
||||||
entity.AdjustStyle(AdjustStyleItalic)
|
entity.AdjustStyle(AdjustStyleItalic)
|
||||||
case "s", "del":
|
case "s", "del", "strike":
|
||||||
entity.AdjustStyle(AdjustStyleStrikethrough)
|
entity.AdjustStyle(AdjustStyleStrikethrough)
|
||||||
case "u", "ins":
|
case "u", "ins":
|
||||||
entity.AdjustStyle(AdjustStyleUnderline)
|
entity.AdjustStyle(AdjustStyleUnderline)
|
||||||
@ -237,7 +237,7 @@ func (parser *htmlParser) syntaxHighlight(text, language string) Entity {
|
|||||||
children := make([]Entity, len(tokens))
|
children := make([]Entity, len(tokens))
|
||||||
for i, token := range tokens {
|
for i, token := range tokens {
|
||||||
if token.Value == "\n" {
|
if token.Value == "\n" {
|
||||||
children[i] = &BaseEntity{Block: true, Tag: "br"}
|
children[i] = NewBreakEntity()
|
||||||
} else {
|
} else {
|
||||||
children[i] = &BaseEntity{
|
children[i] = &BaseEntity{
|
||||||
Tag: token.Type.String(),
|
Tag: token.Type.String(),
|
||||||
@ -282,7 +282,7 @@ func (parser *htmlParser) tagNodeToEntity(node *html.Node) Entity {
|
|||||||
return parser.headerToEntity(node)
|
return parser.headerToEntity(node)
|
||||||
case "br":
|
case "br":
|
||||||
return NewBreakEntity()
|
return NewBreakEntity()
|
||||||
case "b", "strong", "i", "em", "s", "del", "u", "ins", "font":
|
case "b", "strong", "i", "em", "s", "strike", "del", "u", "ins", "font":
|
||||||
return parser.basicFormatToEntity(node)
|
return parser.basicFormatToEntity(node)
|
||||||
case "a":
|
case "a":
|
||||||
return parser.linkToEntity(node)
|
return parser.linkToEntity(node)
|
||||||
@ -290,6 +290,10 @@ func (parser *htmlParser) tagNodeToEntity(node *html.Node) Entity {
|
|||||||
return parser.imageToEntity(node)
|
return parser.imageToEntity(node)
|
||||||
case "pre":
|
case "pre":
|
||||||
return parser.codeblockToEntity(node)
|
return parser.codeblockToEntity(node)
|
||||||
|
case "hr":
|
||||||
|
return NewHorizontalLineEntity()
|
||||||
|
case "mx-reply":
|
||||||
|
return nil
|
||||||
default:
|
default:
|
||||||
return &BaseEntity{
|
return &BaseEntity{
|
||||||
Tag: node.Data,
|
Tag: node.Data,
|
||||||
|
@ -40,6 +40,14 @@ func NewHTMLMessage(event *mautrix.Event, displayname string, root html.Entity)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hw *HTMLMessage) Clone() UIMessage {
|
||||||
|
return &HTMLMessage{
|
||||||
|
BaseMessage: hw.BaseMessage.clone(),
|
||||||
|
Root: hw.Root.Clone(),
|
||||||
|
FocusedBg: hw.FocusedBg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (hw *HTMLMessage) Draw(screen mauview.Screen) {
|
func (hw *HTMLMessage) Draw(screen mauview.Screen) {
|
||||||
screen = hw.DrawReply(screen)
|
screen = hw.DrawReply(screen)
|
||||||
if hw.focused {
|
if hw.focused {
|
||||||
|
@ -53,6 +53,19 @@ func NewImageMessage(matrix ifc.MatrixContainer, event *mautrix.Event, displayna
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (msg *ImageMessage) Clone() UIMessage {
|
||||||
|
data := make([]byte, len(msg.data))
|
||||||
|
copy(data, msg.data)
|
||||||
|
return &ImageMessage{
|
||||||
|
BaseMessage: msg.BaseMessage.clone(),
|
||||||
|
Body: msg.Body,
|
||||||
|
Homeserver: msg.Homeserver,
|
||||||
|
FileID: msg.FileID,
|
||||||
|
data: data,
|
||||||
|
matrix: msg.matrix,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (msg *ImageMessage) RegisterMatrix(matrix ifc.MatrixContainer) {
|
func (msg *ImageMessage) RegisterMatrix(matrix ifc.MatrixContainer) {
|
||||||
msg.matrix = matrix
|
msg.matrix = matrix
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@ type UIMessage interface {
|
|||||||
Height() int
|
Height() int
|
||||||
PlainText() string
|
PlainText() string
|
||||||
|
|
||||||
|
Clone() UIMessage
|
||||||
|
|
||||||
RealSender() string
|
RealSender() string
|
||||||
RegisterMatrix(matrix ifc.MatrixContainer)
|
RegisterMatrix(matrix ifc.MatrixContainer)
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,18 @@ import (
|
|||||||
"maunium.net/go/gomuks/ui/widget"
|
"maunium.net/go/gomuks/ui/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Event) UIMessage {
|
func getCachedEvent(mainView ifc.MainView, roomID, eventID string) UIMessage {
|
||||||
|
if roomView := mainView.GetRoom(roomID); roomView != nil {
|
||||||
|
if replyToIfcMsg := roomView.GetEvent(eventID); replyToIfcMsg != nil {
|
||||||
|
if replyToMsg, ok := replyToIfcMsg.(UIMessage); ok && replyToMsg != nil {
|
||||||
|
return replyToMsg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseEvent(matrix ifc.MatrixContainer, mainView ifc.MainView, room *rooms.Room, evt *mautrix.Event) UIMessage {
|
||||||
msg := directParseEvent(matrix, room, evt)
|
msg := directParseEvent(matrix, room, evt)
|
||||||
if msg == nil {
|
if msg == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -41,10 +52,14 @@ func ParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Event
|
|||||||
if len(evt.Content.RelatesTo.InReplyTo.RoomID) > 0 {
|
if len(evt.Content.RelatesTo.InReplyTo.RoomID) > 0 {
|
||||||
replyToRoom = matrix.GetRoom(evt.Content.RelatesTo.InReplyTo.RoomID)
|
replyToRoom = matrix.GetRoom(evt.Content.RelatesTo.InReplyTo.RoomID)
|
||||||
}
|
}
|
||||||
replyToEvt, _ := matrix.GetEvent(replyToRoom, evt.Content.GetReplyTo())
|
|
||||||
if replyToEvt != nil {
|
if replyToMsg := getCachedEvent(mainView, replyToRoom.ID, evt.Content.GetReplyTo()); replyToMsg != nil {
|
||||||
replyToMsg := directParseEvent(matrix, replyToRoom, replyToEvt)
|
debug.Print("Cloning cached UIMessage", replyToMsg)
|
||||||
if replyToMsg != nil {
|
replyToMsg = replyToMsg.Clone()
|
||||||
|
replyToMsg.SetReplyTo(nil)
|
||||||
|
msg.SetReplyTo(replyToMsg)
|
||||||
|
} else if replyToEvt, _ := matrix.GetEvent(replyToRoom, evt.Content.GetReplyTo()); replyToEvt != nil {
|
||||||
|
if replyToMsg := directParseEvent(matrix, replyToRoom, replyToEvt); replyToMsg != nil {
|
||||||
msg.SetReplyTo(replyToMsg)
|
msg.SetReplyTo(replyToMsg)
|
||||||
} else {
|
} else {
|
||||||
// TODO add unrenderable reply header
|
// TODO add unrenderable reply header
|
||||||
@ -68,6 +83,7 @@ func directParseEvent(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix
|
|||||||
case mautrix.StateMember:
|
case mautrix.StateMember:
|
||||||
return ParseMembershipEvent(room, evt)
|
return ParseMembershipEvent(room, evt)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,15 +43,22 @@ func NewTextMessage(event *mautrix.Event, displayname string, text string) UIMes
|
|||||||
func NewServiceMessage(text string) UIMessage {
|
func NewServiceMessage(text string) UIMessage {
|
||||||
return &TextMessage{
|
return &TextMessage{
|
||||||
BaseMessage: BaseMessage{
|
BaseMessage: BaseMessage{
|
||||||
MsgSenderID: "*",
|
MsgSenderID: "*",
|
||||||
MsgSender: "*",
|
MsgSender: "*",
|
||||||
MsgTimestamp: time.Now(),
|
MsgTimestamp: time.Now(),
|
||||||
MsgIsService: true,
|
MsgIsService: true,
|
||||||
},
|
},
|
||||||
MsgText: text,
|
MsgText: text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (msg *TextMessage) Clone() UIMessage {
|
||||||
|
return &TextMessage{
|
||||||
|
BaseMessage: msg.BaseMessage.clone(),
|
||||||
|
MsgText: msg.MsgText,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (msg *TextMessage) getCache() tstring.TString {
|
func (msg *TextMessage) getCache() tstring.TString {
|
||||||
if msg.cache == nil {
|
if msg.cache == nil {
|
||||||
switch msg.MsgType {
|
switch msg.MsgType {
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/mattn/go-runewidth"
|
"github.com/mattn/go-runewidth"
|
||||||
|
|
||||||
"maunium.net/go/mauview"
|
"maunium.net/go/mauview"
|
||||||
|
|
||||||
"maunium.net/go/tcell"
|
"maunium.net/go/tcell"
|
||||||
@ -29,11 +30,11 @@ import (
|
|||||||
type TString []Cell
|
type TString []Cell
|
||||||
|
|
||||||
func NewBlankTString() TString {
|
func NewBlankTString() TString {
|
||||||
return make([]Cell, 0)
|
return make(TString, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTString(str string) TString {
|
func NewTString(str string) TString {
|
||||||
newStr := make([]Cell, len(str))
|
newStr := make(TString, len(str))
|
||||||
for i, char := range str {
|
for i, char := range str {
|
||||||
newStr[i] = NewCell(char)
|
newStr[i] = NewCell(char)
|
||||||
}
|
}
|
||||||
@ -41,7 +42,7 @@ func NewTString(str string) TString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewColorTString(str string, color tcell.Color) TString {
|
func NewColorTString(str string, color tcell.Color) TString {
|
||||||
newStr := make([]Cell, len(str))
|
newStr := make(TString, len(str))
|
||||||
for i, char := range str {
|
for i, char := range str {
|
||||||
newStr[i] = NewColorCell(char, color)
|
newStr[i] = NewColorCell(char, color)
|
||||||
}
|
}
|
||||||
@ -49,7 +50,7 @@ func NewColorTString(str string, color tcell.Color) TString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewStyleTString(str string, style tcell.Style) TString {
|
func NewStyleTString(str string, style tcell.Style) TString {
|
||||||
newStr := make([]Cell, len(str))
|
newStr := make(TString, len(str))
|
||||||
for i, char := range str {
|
for i, char := range str {
|
||||||
newStr[i] = NewStyleCell(char, style)
|
newStr[i] = NewStyleCell(char, style)
|
||||||
}
|
}
|
||||||
@ -74,6 +75,12 @@ func Join(strings []TString, separator string) TString {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (str TString) Clone() TString {
|
||||||
|
newStr := make(TString, len(str))
|
||||||
|
copy(newStr, str)
|
||||||
|
return newStr
|
||||||
|
}
|
||||||
|
|
||||||
func (str TString) AppendTString(dataList ...TString) TString {
|
func (str TString) AppendTString(dataList ...TString) TString {
|
||||||
newStr := str
|
newStr := str
|
||||||
for _, data := range dataList {
|
for _, data := range dataList {
|
||||||
|
@ -445,5 +445,13 @@ func (view *RoomView) AddMessage(message ifc.Message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (view *RoomView) ParseEvent(evt *mautrix.Event) ifc.Message {
|
func (view *RoomView) ParseEvent(evt *mautrix.Event) ifc.Message {
|
||||||
return messages.ParseEvent(view.parent.matrix, view.Room, evt)
|
return messages.ParseEvent(view.parent.matrix, view.parent, view.Room, evt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (view *RoomView) GetEvent(eventID string) ifc.Message {
|
||||||
|
message, ok := view.content.messageIDs[eventID]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return message
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user