Improve handling of multiple linebreaks

This commit is contained in:
Tulir Asokan 2019-04-07 22:54:55 +03:00
parent e6180c9b6f
commit 5d7c1a4caa
4 changed files with 54 additions and 30 deletions

View File

@ -503,12 +503,13 @@ func (view *MessageView) Draw(screen mauview.Screen) {
if len(meta.FormatTime()) > 0 { if len(meta.FormatTime()) > 0 {
widget.WriteLineSimpleColor(screen, meta.FormatTime(), 0, line, meta.TimestampColor()) widget.WriteLineSimpleColor(screen, meta.FormatTime(), 0, line, meta.TimestampColor())
} }
if !bareMode && (prevMeta == nil || meta.Sender() != prevMeta.Sender()) { // TODO hiding senders might not be that nice after all, maybe an option? (disabled for now)
widget.WriteLineColor( //if !bareMode && (prevMeta == nil || meta.Sender() != prevMeta.Sender()) {
screen, mauview.AlignRight, meta.Sender(), widget.WriteLineColor(
usernameX, line, view.widestSender, screen, mauview.AlignRight, meta.Sender(),
meta.SenderColor()) usernameX, line, view.widestSender,
} meta.SenderColor())
//}
prevMeta = meta prevMeta = meta
} }

View File

@ -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) 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 { type BaseHTMLEntity struct {
// Permanent variables // Permanent variables
Tag string Tag string
@ -230,28 +241,6 @@ func (he *BaseHTMLEntity) getStartX() int {
return he.startX 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 { func (he *BaseHTMLEntity) String() string {
var buf strings.Builder var buf strings.Builder
buf.WriteString("&BaseHTMLEntity{\n") buf.WriteString("&BaseHTMLEntity{\n")
@ -297,6 +286,34 @@ func (he *BaseHTMLEntity) PlainText() string {
return buf.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 { func (he *BaseHTMLEntity) calculateBuffer(width, startX int, bare bool) int {
he.startX = startX he.startX = startX
if he.Block { if he.Block {
@ -305,12 +322,18 @@ func (he *BaseHTMLEntity) calculateBuffer(width, startX int, bare bool) int {
he.height = 0 he.height = 0
if len(he.Children) > 0 { if len(he.Children) > 0 {
childStartX := he.startX childStartX := he.startX
prevBreak := false
for _, entity := range he.Children { for _, entity := range he.Children {
if entity.IsBlock() || childStartX == 0 || he.height == 0 { if entity.IsBlock() || childStartX == 0 || he.height == 0 {
he.height++ he.height++
} }
childStartX = entity.calculateBuffer(width-he.Indent, childStartX, bare) childStartX = entity.calculateBuffer(width-he.Indent, childStartX, bare)
he.height += entity.Height() - 1 he.height += entity.Height() - 1
_, isBreak := entity.(*BreakEntity)
if prevBreak && isBreak {
he.height++
}
prevBreak = isBreak
} }
if len(he.Text) == 0 && !he.Block { if len(he.Text) == 0 && !he.Block {
return childStartX return childStartX

View File

@ -289,7 +289,7 @@ func (parser *htmlParser) tagNodeToEntity(node *html.Node, stripLinebreak bool)
case "h1", "h2", "h3", "h4", "h5", "h6": case "h1", "h2", "h3", "h4", "h5", "h6":
return parser.headerToEntity(node, stripLinebreak) return parser.headerToEntity(node, stripLinebreak)
case "br": case "br":
return &messages.BaseHTMLEntity{Tag: "br", Block: true} return messages.NewBreakEntity()
case "b", "strong", "i", "em", "s", "del", "u", "ins", "font": case "b", "strong", "i", "em", "s", "del", "u", "ins", "font":
return parser.basicFormatToEntity(node, stripLinebreak) return parser.basicFormatToEntity(node, stripLinebreak)
case "a": case "a":

View File

@ -113,7 +113,7 @@ func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *mautrix.Eve
replyToEvt.Content.FormattedBody = html.EscapeString(replyToEvt.Content.Body) replyToEvt.Content.FormattedBody = html.EscapeString(replyToEvt.Content.Body)
} }
evt.Content.FormattedBody = fmt.Sprintf( evt.Content.FormattedBody = fmt.Sprintf(
"In reply to <a href='https://matrix.to/#/%[1]s'>%[1]s</a><blockquote>%[2]s</blockquote><br/>%[3]s", "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) replyToEvt.Sender, replyToEvt.Content.FormattedBody, evt.Content.FormattedBody)
} else { } else {
evt.Content.FormattedBody = fmt.Sprintf( evt.Content.FormattedBody = fmt.Sprintf(