Add bare mode and fix terminal resize bug. Fixes #48
This commit is contained in:
@ -41,7 +41,9 @@ type BaseMessage struct {
|
||||
MsgIsHighlight bool
|
||||
MsgIsService bool
|
||||
buffer []tstring.TString
|
||||
plainBuffer []tstring.TString
|
||||
prevBufferWidth int
|
||||
prevBareMode bool
|
||||
}
|
||||
|
||||
func newBaseMessage(id, sender, displayname, msgtype string, timestamp time.Time) BaseMessage {
|
||||
@ -53,6 +55,7 @@ func newBaseMessage(id, sender, displayname, msgtype string, timestamp time.Time
|
||||
MsgType: msgtype,
|
||||
MsgID: id,
|
||||
prevBufferWidth: 0,
|
||||
prevBareMode: false,
|
||||
MsgState: ifc.MessageStateDefault,
|
||||
MsgIsHighlight: false,
|
||||
MsgIsService: false,
|
||||
|
@ -28,14 +28,14 @@ func init() {
|
||||
}
|
||||
|
||||
type ExpandedTextMessage struct {
|
||||
BaseTextMessage
|
||||
BaseMessage
|
||||
MsgText tstring.TString
|
||||
}
|
||||
|
||||
// NewExpandedTextMessage creates a new ExpandedTextMessage object with the provided values and the default state.
|
||||
func NewExpandedTextMessage(id, sender, displayname, msgtype string, text tstring.TString, timestamp time.Time) UIMessage {
|
||||
return &ExpandedTextMessage{
|
||||
BaseTextMessage: newBaseTextMessage(id, sender, displayname, msgtype, timestamp),
|
||||
BaseMessage: newBaseMessage(id, sender, displayname, msgtype, timestamp),
|
||||
MsgText: text,
|
||||
}
|
||||
}
|
||||
@ -48,11 +48,15 @@ func (msg *ExpandedTextMessage) NotificationContent() string {
|
||||
return msg.MsgText.String()
|
||||
}
|
||||
|
||||
func (msg *ExpandedTextMessage) CalculateBuffer(width int) {
|
||||
msg.BaseTextMessage.calculateBufferWithText(msg.MsgText, width)
|
||||
func (msg *ExpandedTextMessage) PlainText() string {
|
||||
return msg.MsgText.String()
|
||||
}
|
||||
|
||||
func (msg *ExpandedTextMessage) CalculateBuffer(bare bool, width int) {
|
||||
msg.calculateBufferWithText(bare, msg.MsgText, width)
|
||||
}
|
||||
|
||||
// RecalculateBuffer calculates the buffer again with the previously provided width.
|
||||
func (msg *ExpandedTextMessage) RecalculateBuffer() {
|
||||
msg.CalculateBuffer(msg.prevBufferWidth)
|
||||
msg.CalculateBuffer(msg.prevBareMode, msg.prevBufferWidth)
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ func init() {
|
||||
|
||||
type ImageMessage struct {
|
||||
BaseMessage
|
||||
Body string
|
||||
Homeserver string
|
||||
FileID string
|
||||
data []byte
|
||||
@ -45,9 +46,10 @@ type ImageMessage struct {
|
||||
}
|
||||
|
||||
// NewImageMessage creates a new ImageMessage object with the provided values and the default state.
|
||||
func NewImageMessage(matrix ifc.MatrixContainer, id, sender, displayname, msgtype, homeserver, fileID string, data []byte, timestamp time.Time) UIMessage {
|
||||
func NewImageMessage(matrix ifc.MatrixContainer, id, sender, displayname, msgtype, body, homeserver, fileID string, data []byte, timestamp time.Time) UIMessage {
|
||||
return &ImageMessage{
|
||||
newBaseMessage(id, sender, displayname, msgtype, timestamp),
|
||||
body,
|
||||
homeserver,
|
||||
fileID,
|
||||
data,
|
||||
@ -67,6 +69,10 @@ func (msg *ImageMessage) NotificationContent() string {
|
||||
return "Sent an image"
|
||||
}
|
||||
|
||||
func (msg *ImageMessage) PlainText() string {
|
||||
return fmt.Sprintf("%s: %s", msg.Body, msg.matrix.GetDownloadURL(msg.Homeserver, msg.FileID))
|
||||
}
|
||||
|
||||
func (msg *ImageMessage) updateData() {
|
||||
defer debug.Recover()
|
||||
debug.Print("Loading image:", msg.Homeserver, msg.FileID)
|
||||
@ -86,11 +92,16 @@ func (msg *ImageMessage) Path() string {
|
||||
// CalculateBuffer generates the internal buffer for this message that consists
|
||||
// of the text of this message split into lines at most as wide as the width
|
||||
// parameter.
|
||||
func (msg *ImageMessage) CalculateBuffer(width int) {
|
||||
func (msg *ImageMessage) CalculateBuffer(bare bool, width int) {
|
||||
if width < 2 {
|
||||
return
|
||||
}
|
||||
|
||||
if bare {
|
||||
msg.calculateBufferWithText(bare, tstring.NewTString(msg.PlainText()), width)
|
||||
return
|
||||
}
|
||||
|
||||
image, err := ansimage.NewScaledFromReader(bytes.NewReader(msg.data), 0, width, color.Black)
|
||||
if err != nil {
|
||||
msg.buffer = []tstring.TString{tstring.NewColorTString("Failed to display image", tcell.ColorRed)}
|
||||
@ -100,9 +111,10 @@ func (msg *ImageMessage) CalculateBuffer(width int) {
|
||||
|
||||
msg.buffer = image.Render()
|
||||
msg.prevBufferWidth = width
|
||||
msg.prevBareMode = false
|
||||
}
|
||||
|
||||
// RecalculateBuffer calculates the buffer again with the previously provided width.
|
||||
func (msg *ImageMessage) RecalculateBuffer() {
|
||||
msg.CalculateBuffer(msg.prevBufferWidth)
|
||||
msg.CalculateBuffer(msg.prevBareMode, msg.prevBufferWidth)
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
type UIMessage interface {
|
||||
ifc.Message
|
||||
|
||||
CalculateBuffer(width int)
|
||||
CalculateBuffer(bare bool, width int)
|
||||
RecalculateBuffer()
|
||||
Buffer() []tstring.TString
|
||||
Height() int
|
||||
|
@ -56,6 +56,7 @@ func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Ev
|
||||
displayname = member.DisplayName
|
||||
}
|
||||
msgtype, _ := evt.Content["msgtype"].(string)
|
||||
text, _ := evt.Content["body"].(string)
|
||||
ts := unixToTime(evt.Timestamp)
|
||||
switch msgtype {
|
||||
case "m.text", "m.notice", "m.emote":
|
||||
@ -64,7 +65,6 @@ func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Ev
|
||||
text := ParseHTMLMessage(room, evt, displayname)
|
||||
return messages.NewExpandedTextMessage(evt.ID, evt.Sender, displayname, msgtype, text, ts)
|
||||
}
|
||||
text, _ := evt.Content["body"].(string)
|
||||
text = strings.Replace(text, "\t", " ", -1)
|
||||
return messages.NewTextMessage(evt.ID, evt.Sender, displayname, msgtype, text, ts)
|
||||
case "m.image":
|
||||
@ -73,7 +73,7 @@ func ParseMessage(matrix ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Ev
|
||||
if err != nil {
|
||||
debug.Printf("Failed to download %s: %v", url, err)
|
||||
}
|
||||
return messages.NewImageMessage(matrix, evt.ID, evt.Sender, displayname, msgtype, hs, id, data, ts)
|
||||
return messages.NewImageMessage(matrix, evt.ID, evt.Sender, displayname, msgtype, text, hs, id, data, ts)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -17,35 +17,26 @@
|
||||
package messages
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"maunium.net/go/gomuks/ui/messages/tstring"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func init() {
|
||||
gob.Register(BaseTextMessage{})
|
||||
}
|
||||
|
||||
type BaseTextMessage struct {
|
||||
BaseMessage
|
||||
}
|
||||
|
||||
func newBaseTextMessage(id, sender, displayname, msgtype string, timestamp time.Time) BaseTextMessage {
|
||||
return BaseTextMessage{newBaseMessage(id, sender, displayname, msgtype, timestamp)}
|
||||
}
|
||||
|
||||
// Regular expressions used to split lines when calculating the buffer.
|
||||
//
|
||||
// From tview/textview.go
|
||||
var (
|
||||
boundaryPattern = regexp.MustCompile("([[:punct:]]\\s*|\\s+)")
|
||||
boundaryPattern = regexp.MustCompile(`([[:punct:]]\s*|\s+)`)
|
||||
bareBoundaryPattern = regexp.MustCompile(`(\s+)`)
|
||||
spacePattern = regexp.MustCompile(`\s+`)
|
||||
)
|
||||
|
||||
func matchBoundaryPattern(extract tstring.TString) tstring.TString {
|
||||
matches := boundaryPattern.FindAllStringIndex(extract.String(), -1)
|
||||
func matchBoundaryPattern(bare bool, extract tstring.TString) tstring.TString {
|
||||
regex := boundaryPattern
|
||||
if bare {
|
||||
regex = bareBoundaryPattern
|
||||
}
|
||||
matches := regex.FindAllStringIndex(extract.String(), -1)
|
||||
if len(matches) > 0 {
|
||||
if match := matches[len(matches)-1]; len(match) >= 2 {
|
||||
if until := match[1]; until < len(extract) {
|
||||
@ -59,13 +50,20 @@ func matchBoundaryPattern(extract tstring.TString) tstring.TString {
|
||||
// CalculateBuffer generates the internal buffer for this message that consists
|
||||
// of the text of this message split into lines at most as wide as the width
|
||||
// parameter.
|
||||
func (msg *BaseTextMessage) calculateBufferWithText(text tstring.TString, width int) {
|
||||
func (msg *BaseMessage) calculateBufferWithText(bare bool, text tstring.TString, width int) {
|
||||
if width < 2 {
|
||||
return
|
||||
}
|
||||
|
||||
msg.buffer = []tstring.TString{}
|
||||
|
||||
if bare {
|
||||
text = tstring.
|
||||
NewTString(msg.FormatTime()).
|
||||
AppendTString(tstring.NewColorTString(fmt.Sprintf(" <%s> ", msg.Sender()), msg.SenderColor())).
|
||||
AppendTString(text)
|
||||
}
|
||||
|
||||
forcedLinebreaks := text.Split('\n')
|
||||
newlines := 0
|
||||
for _, str := range forcedLinebreaks {
|
||||
@ -82,11 +80,12 @@ func (msg *BaseTextMessage) calculateBufferWithText(text tstring.TString, width
|
||||
if spaces := spacePattern.FindStringIndex(str[len(extract):].String()); spaces != nil && spaces[0] == 0 {
|
||||
extract = str[:len(extract)+spaces[1]]
|
||||
}
|
||||
extract = matchBoundaryPattern(extract)
|
||||
extract = matchBoundaryPattern(bare, extract)
|
||||
}
|
||||
msg.buffer = append(msg.buffer, extract)
|
||||
str = str[len(extract):]
|
||||
}
|
||||
}
|
||||
msg.prevBufferWidth = width
|
||||
msg.prevBareMode = bare
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ func init() {
|
||||
}
|
||||
|
||||
type TextMessage struct {
|
||||
BaseTextMessage
|
||||
BaseMessage
|
||||
cache tstring.TString
|
||||
MsgText string
|
||||
}
|
||||
@ -38,7 +38,7 @@ type TextMessage struct {
|
||||
// NewTextMessage creates a new UITextMessage object with the provided values and the default state.
|
||||
func NewTextMessage(id, sender, displayname, msgtype, text string, timestamp time.Time) UIMessage {
|
||||
return &TextMessage{
|
||||
BaseTextMessage: newBaseTextMessage(id, sender, displayname, msgtype, timestamp),
|
||||
BaseMessage: newBaseMessage(id, sender, displayname, msgtype, timestamp),
|
||||
MsgText: text,
|
||||
}
|
||||
}
|
||||
@ -57,22 +57,22 @@ func (msg *TextMessage) getCache() tstring.TString {
|
||||
}
|
||||
|
||||
func (msg *TextMessage) SetType(msgtype string) {
|
||||
msg.BaseTextMessage.SetType(msgtype)
|
||||
msg.BaseMessage.SetType(msgtype)
|
||||
msg.cache = nil
|
||||
}
|
||||
|
||||
func (msg *TextMessage) SetState(state ifc.MessageState) {
|
||||
msg.BaseTextMessage.SetState(state)
|
||||
msg.BaseMessage.SetState(state)
|
||||
msg.cache = nil
|
||||
}
|
||||
|
||||
func (msg *TextMessage) SetIsHighlight(isHighlight bool) {
|
||||
msg.BaseTextMessage.SetIsHighlight(isHighlight)
|
||||
msg.BaseMessage.SetIsHighlight(isHighlight)
|
||||
msg.cache = nil
|
||||
}
|
||||
|
||||
func (msg *TextMessage) SetIsService(isService bool) {
|
||||
msg.BaseTextMessage.SetIsService(isService)
|
||||
msg.BaseMessage.SetIsService(isService)
|
||||
msg.cache = nil
|
||||
}
|
||||
|
||||
@ -80,11 +80,15 @@ func (msg *TextMessage) NotificationContent() string {
|
||||
return msg.MsgText
|
||||
}
|
||||
|
||||
func (msg *TextMessage) CalculateBuffer(width int) {
|
||||
msg.BaseTextMessage.calculateBufferWithText(msg.getCache(), width)
|
||||
func (msg *TextMessage) PlainText() string {
|
||||
return msg.MsgText
|
||||
}
|
||||
|
||||
func (msg *TextMessage) CalculateBuffer(bare bool, width int) {
|
||||
msg.calculateBufferWithText(bare, msg.getCache(), width)
|
||||
}
|
||||
|
||||
// RecalculateBuffer calculates the buffer again with the previously provided width.
|
||||
func (msg *TextMessage) RecalculateBuffer() {
|
||||
msg.CalculateBuffer(msg.prevBufferWidth)
|
||||
msg.CalculateBuffer(msg.prevBareMode, msg.prevBufferWidth)
|
||||
}
|
||||
|
Reference in New Issue
Block a user