Allow clicking images and load images from cache

This commit is contained in:
Tulir Asokan
2018-04-11 19:20:40 +03:00
parent ff7ee333a1
commit 92a2428865
11 changed files with 181 additions and 89 deletions

View File

@ -0,0 +1,86 @@
// gomuks - A terminal Matrix client written in Go.
// Copyright (C) 2018 Tulir Asokan
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package messages
import (
"encoding/gob"
"time"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/ui/messages/tstring"
"maunium.net/go/gomuks/ui/widget"
)
func init() {
gob.Register(&UITextMessage{})
gob.Register(&UIExpandedTextMessage{})
}
type UIExpandedTextMessage struct {
UITextMessage
MsgTStringText tstring.TString
}
// NewExpandedTextMessage creates a new UIExpandedTextMessage object with the provided values and the default state.
func NewExpandedTextMessage(id, sender, msgtype string, text tstring.TString, timestamp time.Time) UIMessage {
return &UIExpandedTextMessage{
UITextMessage{
MsgSender: sender,
MsgTimestamp: timestamp,
MsgSenderColor: widget.GetHashColor(sender),
MsgType: msgtype,
MsgText: text.String(),
MsgID: id,
prevBufferWidth: 0,
MsgState: ifc.MessageStateDefault,
MsgIsHighlight: false,
MsgIsService: false,
},
text,
}
}
func (msg *UIExpandedTextMessage) GetTStringText() tstring.TString {
return msg.MsgTStringText
}
// CopyFrom replaces the content of this message object with the content of the given object.
func (msg *UIExpandedTextMessage) CopyFrom(from ifc.MessageMeta) {
msg.MsgSender = from.Sender()
msg.MsgSenderColor = from.SenderColor()
fromMsg, ok := from.(UIMessage)
if ok {
msg.MsgSender = fromMsg.RealSender()
msg.MsgID = fromMsg.ID()
msg.MsgType = fromMsg.Type()
msg.MsgTimestamp = fromMsg.Timestamp()
msg.MsgState = fromMsg.State()
msg.MsgIsService = fromMsg.IsService()
msg.MsgIsHighlight = fromMsg.IsHighlight()
msg.buffer = nil
fromExpandedMsg, ok := from.(*UIExpandedTextMessage)
if ok {
msg.MsgTStringText = fromExpandedMsg.MsgTStringText
} else {
msg.MsgTStringText = tstring.NewColorTString(fromMsg.Text(), from.TextColor())
}
msg.RecalculateBuffer()
}
}

View File

@ -19,15 +19,16 @@ package messages
import (
"bytes"
"encoding/gob"
"fmt"
"time"
"image/color"
"maunium.net/go/gomuks/debug"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/lib/ansimage"
"maunium.net/go/gomuks/ui/messages/tstring"
"maunium.net/go/gomuks/ui/widget"
"maunium.net/go/gomuks/lib/ansimage"
"maunium.net/go/tcell"
)
@ -37,12 +38,15 @@ func init() {
type UIImageMessage struct {
UITextMessage
Path string
data []byte
Homeserver string
FileID string
data []byte
gmx ifc.Gomuks
}
// NewImageMessage creates a new UIImageMessage object with the provided values and the default state.
func NewImageMessage(id, sender, msgtype string, path string, data []byte, timestamp time.Time) UIMessage {
func NewImageMessage(gmx ifc.Gomuks, id, sender, msgtype, homeserver, fileID string, data []byte, timestamp time.Time) UIMessage {
return &UIImageMessage{
UITextMessage{
MsgSender: sender,
@ -55,11 +59,39 @@ func NewImageMessage(id, sender, msgtype string, path string, data []byte, times
MsgIsHighlight: false,
MsgIsService: false,
},
path,
homeserver,
fileID,
data,
gmx,
}
}
func (msg *UIImageMessage) RegisterGomuks(gmx ifc.Gomuks) {
msg.gmx = gmx
debug.Print(len(msg.data), msg.data)
if len(msg.data) == 0 {
go func() {
defer gmx.Recover()
msg.updateData()
}()
}
}
func (msg *UIImageMessage) updateData() {
debug.Print("Loading image:", msg.Homeserver, msg.FileID)
data, _, _, err := msg.gmx.Matrix().Download(fmt.Sprintf("mxc://%s/%s", msg.Homeserver, msg.FileID))
if err != nil {
debug.Print("Failed to download image %s/%s: %v", msg.Homeserver, msg.FileID, err)
return
}
msg.data = data
}
func (msg *UIImageMessage) Path() string {
return msg.gmx.Matrix().GetCachePath(msg.Homeserver, msg.FileID)
}
// CopyFrom replaces the content of this message object with the content of the given object.
func (msg *UIImageMessage) CopyFrom(from ifc.MessageMeta) {
msg.MsgSender = from.Sender()

View File

@ -31,6 +31,7 @@ type UIMessage interface {
Height() int
RealSender() string
RegisterGomuks(gmx ifc.Gomuks)
}
const DateFormat = "January _2, 2006"

View File

@ -29,14 +29,14 @@ import (
"maunium.net/go/tcell"
)
func ParseEvent(mx ifc.MatrixContainer, room *rooms.Room, evt *gomatrix.Event) UIMessage {
func ParseEvent(gmx ifc.Gomuks, room *rooms.Room, evt *gomatrix.Event) UIMessage {
member := room.GetMember(evt.Sender)
if member != nil {
evt.Sender = member.DisplayName
}
switch evt.Type {
case "m.room.message":
return ParseMessage(mx, evt)
return ParseMessage(gmx, evt)
case "m.room.member":
return ParseMembershipEvent(evt)
}
@ -51,7 +51,7 @@ func unixToTime(unix int64) time.Time {
return timestamp
}
func ParseMessage(mx ifc.MatrixContainer, evt *gomatrix.Event) UIMessage {
func ParseMessage(gmx ifc.Gomuks, evt *gomatrix.Event) UIMessage {
msgtype, _ := evt.Content["msgtype"].(string)
ts := unixToTime(evt.Timestamp)
switch msgtype {
@ -60,11 +60,11 @@ func ParseMessage(mx ifc.MatrixContainer, evt *gomatrix.Event) UIMessage {
return NewTextMessage(evt.ID, evt.Sender, msgtype, text, ts)
case "m.image":
url, _ := evt.Content["url"].(string)
data, path, err := mx.Download(url)
data, hs, id, err := gmx.Matrix().Download(url)
if err != nil {
debug.Printf("Failed to download %s: %v", url, err)
}
return NewImageMessage(evt.ID, evt.Sender, msgtype, path, data, ts)
return NewImageMessage(gmx, evt.ID, evt.Sender, msgtype, hs, id, data, ts)
}
return nil
}

View File

@ -22,70 +22,14 @@ import (
"regexp"
"time"
"maunium.net/go/gomuks/ui/messages/tstring"
"maunium.net/go/tcell"
"maunium.net/go/gomuks/interface"
"maunium.net/go/gomuks/ui/messages/tstring"
"maunium.net/go/gomuks/ui/widget"
"maunium.net/go/tcell"
)
func init() {
gob.Register(&UITextMessage{})
gob.Register(&UIExpandedTextMessage{})
}
type UIExpandedTextMessage struct {
UITextMessage
MsgTStringText tstring.TString
}
// NewExpandedTextMessage creates a new UIExpandedTextMessage object with the provided values and the default state.
func NewExpandedTextMessage(id, sender, msgtype string, text tstring.TString, timestamp time.Time) UIMessage {
return &UIExpandedTextMessage{
UITextMessage{
MsgSender: sender,
MsgTimestamp: timestamp,
MsgSenderColor: widget.GetHashColor(sender),
MsgType: msgtype,
MsgText: text.String(),
MsgID: id,
prevBufferWidth: 0,
MsgState: ifc.MessageStateDefault,
MsgIsHighlight: false,
MsgIsService: false,
},
text,
}
}
func (msg *UIExpandedTextMessage) GetTStringText() tstring.TString {
return msg.MsgTStringText
}
// CopyFrom replaces the content of this message object with the content of the given object.
func (msg *UIExpandedTextMessage) CopyFrom(from ifc.MessageMeta) {
msg.MsgSender = from.Sender()
msg.MsgSenderColor = from.SenderColor()
fromMsg, ok := from.(UIMessage)
if ok {
msg.MsgSender = fromMsg.RealSender()
msg.MsgID = fromMsg.ID()
msg.MsgType = fromMsg.Type()
msg.MsgTimestamp = fromMsg.Timestamp()
msg.MsgState = fromMsg.State()
msg.MsgIsService = fromMsg.IsService()
msg.MsgIsHighlight = fromMsg.IsHighlight()
msg.buffer = nil
fromExpandedMsg, ok := from.(*UIExpandedTextMessage)
if ok {
msg.MsgTStringText = fromExpandedMsg.MsgTStringText
} else {
msg.MsgTStringText = tstring.NewColorTString(fromMsg.Text(), from.TextColor())
}
msg.RecalculateBuffer()
}
}
type UITextMessage struct {
@ -118,6 +62,8 @@ func NewTextMessage(id, sender, msgtype, text string, timestamp time.Time) UIMes
}
}
func (msg *UITextMessage) RegisterGomuks(gmx ifc.Gomuks) {}
// CopyFrom replaces the content of this message object with the content of the given object.
func (msg *UITextMessage) CopyFrom(from ifc.MessageMeta) {
msg.MsgSender = from.Sender()