Add support for encrypted files
This commit is contained in:
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@@ -21,7 +21,7 @@ require (
 | 
				
			|||||||
	golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
 | 
						golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e
 | 
				
			||||||
	gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2
 | 
						gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2
 | 
				
			||||||
	gopkg.in/yaml.v2 v2.2.8
 | 
						gopkg.in/yaml.v2 v2.2.8
 | 
				
			||||||
	maunium.net/go/mautrix v0.2.0-beta.4.0.20200428185931-73915bafb538
 | 
						maunium.net/go/mautrix v0.2.0-beta.4.0.20200428234424-a14b55c5445f
 | 
				
			||||||
	maunium.net/go/mauview v0.1.0
 | 
						maunium.net/go/mauview v0.1.0
 | 
				
			||||||
	maunium.net/go/tcell v0.1.0
 | 
						maunium.net/go/tcell v0.1.0
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							@@ -88,6 +88,8 @@ maunium.net/go/mautrix v0.2.0-beta.4.0.20200427215704-fe82e2b914c8 h1:xflYDdpEon
 | 
				
			|||||||
maunium.net/go/mautrix v0.2.0-beta.4.0.20200427215704-fe82e2b914c8/go.mod h1:SkGZzch8CvU2qKtNpYxtzZ0sQxfVEJ3IsVVLSUBUx9Y=
 | 
					maunium.net/go/mautrix v0.2.0-beta.4.0.20200427215704-fe82e2b914c8/go.mod h1:SkGZzch8CvU2qKtNpYxtzZ0sQxfVEJ3IsVVLSUBUx9Y=
 | 
				
			||||||
maunium.net/go/mautrix v0.2.0-beta.4.0.20200428185931-73915bafb538 h1:E/6URkgRmxhNid8mA+PV25Bi8F/4Yg5nmsxIi/MWDrU=
 | 
					maunium.net/go/mautrix v0.2.0-beta.4.0.20200428185931-73915bafb538 h1:E/6URkgRmxhNid8mA+PV25Bi8F/4Yg5nmsxIi/MWDrU=
 | 
				
			||||||
maunium.net/go/mautrix v0.2.0-beta.4.0.20200428185931-73915bafb538/go.mod h1:SkGZzch8CvU2qKtNpYxtzZ0sQxfVEJ3IsVVLSUBUx9Y=
 | 
					maunium.net/go/mautrix v0.2.0-beta.4.0.20200428185931-73915bafb538/go.mod h1:SkGZzch8CvU2qKtNpYxtzZ0sQxfVEJ3IsVVLSUBUx9Y=
 | 
				
			||||||
 | 
					maunium.net/go/mautrix v0.2.0-beta.4.0.20200428234424-a14b55c5445f h1:kYrIUjr2v6fuVZfs5QnzRJ2YzbZVH21aP77a5ynFHNk=
 | 
				
			||||||
 | 
					maunium.net/go/mautrix v0.2.0-beta.4.0.20200428234424-a14b55c5445f/go.mod h1:SkGZzch8CvU2qKtNpYxtzZ0sQxfVEJ3IsVVLSUBUx9Y=
 | 
				
			||||||
maunium.net/go/mauview v0.1.0 h1:x2WdkKI2zdriJuPAB0CKlwmnHGE7W9xfM5z6RgG+IIg=
 | 
					maunium.net/go/mauview v0.1.0 h1:x2WdkKI2zdriJuPAB0CKlwmnHGE7W9xfM5z6RgG+IIg=
 | 
				
			||||||
maunium.net/go/mauview v0.1.0/go.mod h1:og9WbzmWe9SNYNyOFlCv8qa9zMcOvG2nzRJ5vYyud9U=
 | 
					maunium.net/go/mauview v0.1.0/go.mod h1:og9WbzmWe9SNYNyOFlCv8qa9zMcOvG2nzRJ5vYyud9U=
 | 
				
			||||||
maunium.net/go/tcell v0.1.0 h1:XzsEoGCvOw5nac+tlkSLzQcliLYTN4PrtA7ar2ptjSM=
 | 
					maunium.net/go/tcell v0.1.0 h1:XzsEoGCvOw5nac+tlkSLzQcliLYTN4PrtA7ar2ptjSM=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ package ifc
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"maunium.net/go/mautrix"
 | 
						"maunium.net/go/mautrix"
 | 
				
			||||||
 | 
						"maunium.net/go/mautrix/crypto/attachment"
 | 
				
			||||||
	"maunium.net/go/mautrix/event"
 | 
						"maunium.net/go/mautrix/event"
 | 
				
			||||||
	"maunium.net/go/mautrix/id"
 | 
						"maunium.net/go/mautrix/id"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -59,8 +60,8 @@ type MatrixContainer interface {
 | 
				
			|||||||
	GetRoom(roomID id.RoomID) *rooms.Room
 | 
						GetRoom(roomID id.RoomID) *rooms.Room
 | 
				
			||||||
	GetOrCreateRoom(roomID id.RoomID) *rooms.Room
 | 
						GetOrCreateRoom(roomID id.RoomID) *rooms.Room
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Download(uri id.ContentURI) ([]byte, error)
 | 
						Download(uri id.ContentURI, file *attachment.EncryptedFile) ([]byte, error)
 | 
				
			||||||
	DownloadToDisk(uri id.ContentURI, target string) (string, error)
 | 
						DownloadToDisk(uri id.ContentURI, file *attachment.EncryptedFile, target string) (string, error)
 | 
				
			||||||
	GetDownloadURL(uri id.ContentURI) string
 | 
						GetDownloadURL(uri id.ContentURI) string
 | 
				
			||||||
	GetCachePath(uri id.ContentURI) string
 | 
						GetCachePath(uri id.ContentURI) string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,6 @@
 | 
				
			|||||||
package matrix
 | 
					package matrix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"crypto/tls"
 | 
						"crypto/tls"
 | 
				
			||||||
	"encoding/gob"
 | 
						"encoding/gob"
 | 
				
			||||||
@@ -38,6 +37,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"maunium.net/go/mautrix"
 | 
						"maunium.net/go/mautrix"
 | 
				
			||||||
	"maunium.net/go/mautrix/crypto"
 | 
						"maunium.net/go/mautrix/crypto"
 | 
				
			||||||
 | 
						"maunium.net/go/mautrix/crypto/attachment"
 | 
				
			||||||
	"maunium.net/go/mautrix/event"
 | 
						"maunium.net/go/mautrix/event"
 | 
				
			||||||
	"maunium.net/go/mautrix/format"
 | 
						"maunium.net/go/mautrix/format"
 | 
				
			||||||
	"maunium.net/go/mautrix/id"
 | 
						"maunium.net/go/mautrix/id"
 | 
				
			||||||
@@ -1061,7 +1061,7 @@ func cp(src, dst string) error {
 | 
				
			|||||||
	return out.Close()
 | 
						return out.Close()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Container) DownloadToDisk(uri id.ContentURI, target string) (fullPath string, err error) {
 | 
					func (c *Container) DownloadToDisk(uri id.ContentURI, file *attachment.EncryptedFile, target string) (fullPath string, err error) {
 | 
				
			||||||
	cachePath := c.GetCachePath(uri)
 | 
						cachePath := c.GetCachePath(uri)
 | 
				
			||||||
	if target == "" {
 | 
						if target == "" {
 | 
				
			||||||
		fullPath = cachePath
 | 
							fullPath = cachePath
 | 
				
			||||||
@@ -1072,21 +1072,27 @@ func (c *Container) DownloadToDisk(uri id.ContentURI, target string) (fullPath s
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if _, statErr := os.Stat(cachePath); os.IsNotExist(statErr) {
 | 
						if _, statErr := os.Stat(cachePath); os.IsNotExist(statErr) {
 | 
				
			||||||
		var file *os.File
 | 
					 | 
				
			||||||
		file, err = os.OpenFile(cachePath, os.O_CREATE|os.O_WRONLY, 0600)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		defer file.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		var body io.ReadCloser
 | 
							var body io.ReadCloser
 | 
				
			||||||
		body, err = c.client.Download(uri)
 | 
							body, err = c.client.Download(uri)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		defer body.Close()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		_, err = io.Copy(file, body)
 | 
							var data []byte
 | 
				
			||||||
 | 
							data, err = ioutil.ReadAll(body)
 | 
				
			||||||
 | 
							_ = body.Close()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if file != nil {
 | 
				
			||||||
 | 
								data, err = file.Decrypt(data)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err = ioutil.WriteFile(cachePath, data, 0600)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -1106,7 +1112,7 @@ func (c *Container) DownloadToDisk(uri id.ContentURI, target string) (fullPath s
 | 
				
			|||||||
// Download fetches the given Matrix content (mxc) URL and returns the data, homeserver, file ID and potential errors.
 | 
					// Download fetches the given Matrix content (mxc) URL and returns the data, homeserver, file ID and potential errors.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// The file will be either read from the media cache (if found) or downloaded from the server.
 | 
					// The file will be either read from the media cache (if found) or downloaded from the server.
 | 
				
			||||||
func (c *Container) Download(uri id.ContentURI) (data []byte, err error) {
 | 
					func (c *Container) Download(uri id.ContentURI, file *attachment.EncryptedFile) (data []byte, err error) {
 | 
				
			||||||
	cacheFile := c.GetCachePath(uri)
 | 
						cacheFile := c.GetCachePath(uri)
 | 
				
			||||||
	var info os.FileInfo
 | 
						var info os.FileInfo
 | 
				
			||||||
	if info, err = os.Stat(cacheFile); err == nil && !info.IsDir() {
 | 
						if info, err = os.Stat(cacheFile); err == nil && !info.IsDir() {
 | 
				
			||||||
@@ -1116,7 +1122,7 @@ func (c *Container) Download(uri id.ContentURI) (data []byte, err error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data, err = c.download(uri, cacheFile)
 | 
						data, err = c.download(uri, file, cacheFile)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1124,21 +1130,25 @@ func (c *Container) GetDownloadURL(uri id.ContentURI) string {
 | 
				
			|||||||
	return c.client.GetDownloadURL(uri)
 | 
						return c.client.GetDownloadURL(uri)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Container) download(uri id.ContentURI, cacheFile string) (data []byte, err error) {
 | 
					func (c *Container) download(uri id.ContentURI, file *attachment.EncryptedFile, cacheFile string) (data []byte, err error) {
 | 
				
			||||||
	var body io.ReadCloser
 | 
						var body io.ReadCloser
 | 
				
			||||||
	body, err = c.client.Download(uri)
 | 
						body, err = c.client.Download(uri)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer body.Close()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var buf bytes.Buffer
 | 
						data, err = ioutil.ReadAll(body)
 | 
				
			||||||
	_, err = io.Copy(&buf, body)
 | 
						_ = body.Close()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data = buf.Bytes()
 | 
						if file != nil {
 | 
				
			||||||
 | 
							data, err = file.Decrypt(data)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = ioutil.WriteFile(cacheFile, data, 0600)
 | 
						err = ioutil.WriteFile(cacheFile, data, 0600)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ import (
 | 
				
			|||||||
	"image"
 | 
						"image"
 | 
				
			||||||
	"image/color"
 | 
						"image/color"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"maunium.net/go/gomuks/matrix/muksevt"
 | 
						"maunium.net/go/mautrix/crypto/attachment"
 | 
				
			||||||
	"maunium.net/go/mautrix/event"
 | 
						"maunium.net/go/mautrix/event"
 | 
				
			||||||
	"maunium.net/go/mautrix/id"
 | 
						"maunium.net/go/mautrix/id"
 | 
				
			||||||
	"maunium.net/go/mauview"
 | 
						"maunium.net/go/mauview"
 | 
				
			||||||
@@ -32,14 +32,19 @@ import (
 | 
				
			|||||||
	"maunium.net/go/gomuks/debug"
 | 
						"maunium.net/go/gomuks/debug"
 | 
				
			||||||
	"maunium.net/go/gomuks/interface"
 | 
						"maunium.net/go/gomuks/interface"
 | 
				
			||||||
	"maunium.net/go/gomuks/lib/ansimage"
 | 
						"maunium.net/go/gomuks/lib/ansimage"
 | 
				
			||||||
 | 
						"maunium.net/go/gomuks/matrix/muksevt"
 | 
				
			||||||
	"maunium.net/go/gomuks/ui/messages/tstring"
 | 
						"maunium.net/go/gomuks/ui/messages/tstring"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type FileMessage struct {
 | 
					type FileMessage struct {
 | 
				
			||||||
	Type event.MessageType
 | 
						Type event.MessageType
 | 
				
			||||||
	Body string
 | 
						Body string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	URL           id.ContentURI
 | 
						URL           id.ContentURI
 | 
				
			||||||
 | 
						File          *attachment.EncryptedFile
 | 
				
			||||||
	Thumbnail     id.ContentURI
 | 
						Thumbnail     id.ContentURI
 | 
				
			||||||
 | 
						ThumbnailFile *attachment.EncryptedFile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	imageData []byte
 | 
						imageData []byte
 | 
				
			||||||
	buffer    []tstring.TString
 | 
						buffer    []tstring.TString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -49,13 +54,22 @@ type FileMessage struct {
 | 
				
			|||||||
// NewFileMessage creates a new FileMessage object with the provided values and the default state.
 | 
					// NewFileMessage creates a new FileMessage object with the provided values and the default state.
 | 
				
			||||||
func NewFileMessage(matrix ifc.MatrixContainer, evt *muksevt.Event, displayname string) *UIMessage {
 | 
					func NewFileMessage(matrix ifc.MatrixContainer, evt *muksevt.Event, displayname string) *UIMessage {
 | 
				
			||||||
	content := evt.Content.AsMessage()
 | 
						content := evt.Content.AsMessage()
 | 
				
			||||||
	url, _ := content.URL.Parse()
 | 
						var file, thumbnailFile *attachment.EncryptedFile
 | 
				
			||||||
	thumbnail, _ := content.GetInfo().ThumbnailURL.Parse()
 | 
						if content.File != nil {
 | 
				
			||||||
 | 
							file = &content.File.EncryptedFile
 | 
				
			||||||
 | 
							content.URL = content.File.URL
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if content.GetInfo().ThumbnailFile != nil {
 | 
				
			||||||
 | 
							thumbnailFile = &content.Info.ThumbnailFile.EncryptedFile
 | 
				
			||||||
 | 
							content.Info.ThumbnailURL = content.Info.ThumbnailFile.URL
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return newUIMessage(evt, displayname, &FileMessage{
 | 
						return newUIMessage(evt, displayname, &FileMessage{
 | 
				
			||||||
		Type:          content.MsgType,
 | 
							Type:          content.MsgType,
 | 
				
			||||||
		Body:          content.Body,
 | 
							Body:          content.Body,
 | 
				
			||||||
		URL:       url,
 | 
							URL:           content.URL,
 | 
				
			||||||
		Thumbnail: thumbnail,
 | 
							File:          file,
 | 
				
			||||||
 | 
							Thumbnail:     content.GetInfo().ThumbnailURL,
 | 
				
			||||||
 | 
							ThumbnailFile: thumbnailFile,
 | 
				
			||||||
		matrix:        matrix,
 | 
							matrix:        matrix,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -96,17 +110,20 @@ func (msg *FileMessage) String() string {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (msg *FileMessage) DownloadPreview() {
 | 
					func (msg *FileMessage) DownloadPreview() {
 | 
				
			||||||
	url := msg.Thumbnail
 | 
						var url id.ContentURI
 | 
				
			||||||
	if url.IsEmpty() {
 | 
						var file *attachment.EncryptedFile
 | 
				
			||||||
		if msg.Type == event.MsgImage && !msg.URL.IsEmpty() {
 | 
						if !msg.Thumbnail.IsEmpty() {
 | 
				
			||||||
			msg.Thumbnail = msg.URL
 | 
					 | 
				
			||||||
		url = msg.Thumbnail
 | 
							url = msg.Thumbnail
 | 
				
			||||||
 | 
							file = msg.ThumbnailFile
 | 
				
			||||||
 | 
						} else if msg.Type == event.MsgImage && !msg.URL.IsEmpty() {
 | 
				
			||||||
 | 
							msg.Thumbnail = msg.URL
 | 
				
			||||||
 | 
							url = msg.URL
 | 
				
			||||||
 | 
							file = msg.File
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	debug.Print("Loading file:", url)
 | 
						debug.Print("Loading file:", url)
 | 
				
			||||||
	data, err := msg.matrix.Download(url)
 | 
						data, err := msg.matrix.Download(url, file)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		debug.Printf("Failed to download file %s: %v", url, err)
 | 
							debug.Printf("Failed to download file %s: %v", url, err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,13 +20,13 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"maunium.net/go/gomuks/debug"
 | 
					 | 
				
			||||||
	"maunium.net/go/gomuks/matrix/muksevt"
 | 
					 | 
				
			||||||
	"maunium.net/go/mautrix/event"
 | 
						"maunium.net/go/mautrix/event"
 | 
				
			||||||
	"maunium.net/go/mautrix/id"
 | 
						"maunium.net/go/mautrix/id"
 | 
				
			||||||
	"maunium.net/go/tcell"
 | 
						"maunium.net/go/tcell"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"maunium.net/go/gomuks/debug"
 | 
				
			||||||
	"maunium.net/go/gomuks/interface"
 | 
						"maunium.net/go/gomuks/interface"
 | 
				
			||||||
 | 
						"maunium.net/go/gomuks/matrix/muksevt"
 | 
				
			||||||
	"maunium.net/go/gomuks/matrix/rooms"
 | 
						"maunium.net/go/gomuks/matrix/rooms"
 | 
				
			||||||
	"maunium.net/go/gomuks/ui/messages/html"
 | 
						"maunium.net/go/gomuks/ui/messages/html"
 | 
				
			||||||
	"maunium.net/go/gomuks/ui/messages/tstring"
 | 
						"maunium.net/go/gomuks/ui/messages/tstring"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,7 @@ import (
 | 
				
			|||||||
	"github.com/kyokomi/emoji"
 | 
						"github.com/kyokomi/emoji"
 | 
				
			||||||
	"github.com/mattn/go-runewidth"
 | 
						"github.com/mattn/go-runewidth"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"maunium.net/go/mautrix/crypto/attachment"
 | 
				
			||||||
	"maunium.net/go/mauview"
 | 
						"maunium.net/go/mauview"
 | 
				
			||||||
	"maunium.net/go/tcell"
 | 
						"maunium.net/go/tcell"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -122,6 +123,10 @@ func NewRoomView(parent *MainView, room *rooms.Room) *RoomView {
 | 
				
			|||||||
		SetPressKeyUpAtStartFunc(view.EditPrevious).
 | 
							SetPressKeyUpAtStartFunc(view.EditPrevious).
 | 
				
			||||||
		SetPressKeyDownAtEndFunc(view.EditNext)
 | 
							SetPressKeyDownAtEndFunc(view.EditNext)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if room.Encrypted {
 | 
				
			||||||
 | 
							view.input.SetPlaceholder("Send an encrypted message...")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	view.topic.
 | 
						view.topic.
 | 
				
			||||||
		SetTextColor(tcell.ColorWhite).
 | 
							SetTextColor(tcell.ColorWhite).
 | 
				
			||||||
		SetBackgroundColor(tcell.ColorDarkGreen)
 | 
							SetBackgroundColor(tcell.ColorDarkGreen)
 | 
				
			||||||
@@ -202,7 +207,7 @@ func (view *RoomView) OnSelect(message *messages.UIMessage) {
 | 
				
			|||||||
			} else if view.selectReason == SelectDownload {
 | 
								} else if view.selectReason == SelectDownload {
 | 
				
			||||||
				path = msg.Body
 | 
									path = msg.Body
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			go view.Download(msg.URL, path, view.selectReason == SelectOpen)
 | 
								go view.Download(msg.URL, msg.File, path, view.selectReason == SelectOpen)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	view.selecting = false
 | 
						view.selecting = false
 | 
				
			||||||
@@ -624,8 +629,8 @@ func (view *RoomView) InputSubmit(text string) {
 | 
				
			|||||||
	view.SetInputText("")
 | 
						view.SetInputText("")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (view *RoomView) Download(url id.ContentURI, filename string, openFile bool) {
 | 
					func (view *RoomView) Download(url id.ContentURI, file *attachment.EncryptedFile, filename string, openFile bool) {
 | 
				
			||||||
	path, err := view.parent.matrix.DownloadToDisk(url, filename)
 | 
						path, err := view.parent.matrix.DownloadToDisk(url, file, filename)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		view.AddServiceMessage(fmt.Sprintf("Failed to download media: %v", err))
 | 
							view.AddServiceMessage(fmt.Sprintf("Failed to download media: %v", err))
 | 
				
			||||||
		view.parent.parent.Render()
 | 
							view.parent.parent.Render()
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user