From 5d7c1a4caab46f7e981aed7b9cc825b7602b4098 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 7 Apr 2019 22:54:55 +0300 Subject: Improve handling of multiple linebreaks --- ui/message-view.go | 13 ++++---- ui/messages/htmlmessage.go | 67 +++++++++++++++++++++++++++------------- ui/messages/parser/htmlparser.go | 2 +- ui/messages/parser/parser.go | 2 +- 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/ui/message-view.go b/ui/message-view.go index 20831f1..144bfca 100644 --- a/ui/message-view.go +++ b/ui/message-view.go @@ -503,12 +503,13 @@ func (view *MessageView) Draw(screen mauview.Screen) { if len(meta.FormatTime()) > 0 { widget.WriteLineSimpleColor(screen, meta.FormatTime(), 0, line, meta.TimestampColor()) } - if !bareMode && (prevMeta == nil || meta.Sender() != prevMeta.Sender()) { - widget.WriteLineColor( - screen, mauview.AlignRight, meta.Sender(), - usernameX, line, view.widestSender, - meta.SenderColor()) - } + // TODO hiding senders might not be that nice after all, maybe an option? (disabled for now) + //if !bareMode && (prevMeta == nil || meta.Sender() != prevMeta.Sender()) { + widget.WriteLineColor( + screen, mauview.AlignRight, meta.Sender(), + usernameX, line, view.widestSender, + meta.SenderColor()) + //} prevMeta = meta } diff --git a/ui/messages/htmlmessage.go b/ui/messages/htmlmessage.go index 34bba2b..8685442 100644 --- a/ui/messages/htmlmessage.go +++ b/ui/messages/htmlmessage.go @@ -173,6 +173,17 @@ func (le *ListEntity) String() string { return fmt.Sprintf("&ListEntity{Ordered=%t, Start=%d, Base=%s},\n", le.Ordered, le.Start, le.BaseHTMLEntity) } +type BreakEntity struct { + *BaseHTMLEntity +} + +func NewBreakEntity() *BreakEntity { + return &BreakEntity{&BaseHTMLEntity{ + Tag: "br", + Block: true, + }} +} + type BaseHTMLEntity struct { // Permanent variables Tag string @@ -230,28 +241,6 @@ func (he *BaseHTMLEntity) getStartX() int { return he.startX } -func (he *BaseHTMLEntity) Draw(screen mauview.Screen) { - width, _ := screen.Size() - if len(he.buffer) > 0 { - x := he.startX - for y, line := range he.buffer { - widget.WriteLine(screen, mauview.AlignLeft, line, x, y, width, he.Style) - x = 0 - } - } - if len(he.Children) > 0 { - proxyScreen := &mauview.ProxyScreen{Parent: screen, OffsetX: he.Indent, Width: width - he.Indent} - for i, entity := range he.Children { - if i != 0 && entity.getStartX() == 0 { - proxyScreen.OffsetY++ - } - proxyScreen.Height = entity.Height() - entity.Draw(proxyScreen) - proxyScreen.OffsetY += entity.Height() - 1 - } - } -} - func (he *BaseHTMLEntity) String() string { var buf strings.Builder buf.WriteString("&BaseHTMLEntity{\n") @@ -297,6 +286,34 @@ func (he *BaseHTMLEntity) PlainText() string { return buf.String() } +func (he *BaseHTMLEntity) Draw(screen mauview.Screen) { + width, _ := screen.Size() + if len(he.buffer) > 0 { + x := he.startX + for y, line := range he.buffer { + widget.WriteLine(screen, mauview.AlignLeft, line, x, y, width, he.Style) + x = 0 + } + } + if len(he.Children) > 0 { + prevBreak := false + proxyScreen := &mauview.ProxyScreen{Parent: screen, OffsetX: he.Indent, Width: width - he.Indent} + for i, entity := range he.Children { + if i != 0 && entity.getStartX() == 0 { + proxyScreen.OffsetY++ + } + proxyScreen.Height = entity.Height() + entity.Draw(proxyScreen) + proxyScreen.OffsetY += entity.Height() - 1 + _, isBreak := entity.(*BreakEntity) + if prevBreak && isBreak { + proxyScreen.OffsetY++ + } + prevBreak = isBreak + } + } +} + func (he *BaseHTMLEntity) calculateBuffer(width, startX int, bare bool) int { he.startX = startX if he.Block { @@ -305,12 +322,18 @@ func (he *BaseHTMLEntity) calculateBuffer(width, startX int, bare bool) int { he.height = 0 if len(he.Children) > 0 { childStartX := he.startX + prevBreak := false for _, entity := range he.Children { if entity.IsBlock() || childStartX == 0 || he.height == 0 { he.height++ } childStartX = entity.calculateBuffer(width-he.Indent, childStartX, bare) he.height += entity.Height() - 1 + _, isBreak := entity.(*BreakEntity) + if prevBreak && isBreak { + he.height++ + } + prevBreak = isBreak } if len(he.Text) == 0 && !he.Block { return childStartX diff --git a/ui/messages/parser/htmlparser.go b/ui/messages/parser/htmlparser.go index 464459e..e658c61 100644 --- a/ui/messages/parser/htmlparser.go +++ b/ui/messages/parser/htmlparser.go @@ -289,7 +289,7 @@ func (parser *htmlParser) tagNodeToEntity(node *html.Node, stripLinebreak bool) case "h1", "h2", "h3", "h4", "h5", "h6": return parser.headerToEntity(node, stripLinebreak) case "br": - return &messages.BaseHTMLEntity{Tag: "br", Block: true} + return messages.NewBreakEntity() case "b", "strong", "i", "em", "s", "del", "u", "ins", "font": return parser.basicFormatToEntity(node, stripLinebreak) case "a": diff --git a/ui/messages/parser/parser.go b/ui/messages/parser/parser.go index 4181c09..e48bd5f 100644 --- a/ui/messages/parser/parser.go +++ b/ui/messages/parser/parser.go @@ -113,7 +113,7 @@ func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Eve replyToEvt.Content.FormattedBody = html.EscapeString(replyToEvt.Content.Body) } evt.Content.FormattedBody = fmt.Sprintf( - "In reply to %[1]s
%[2]s

%[3]s", + "In reply to %[1]s
%[2]s


%[3]s", replyToEvt.Sender, replyToEvt.Content.FormattedBody, evt.Content.FormattedBody) } else { evt.Content.FormattedBody = fmt.Sprintf( -- cgit v1.2.3