Finish basic file upload support. Fixes #62
This commit is contained in:
		
							
								
								
									
										58
									
								
								ui/autocomplete.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								ui/autocomplete.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
// gomuks - A terminal Matrix client written in Go.
 | 
			
		||||
// Copyright (C) 2020 Tulir Asokan
 | 
			
		||||
//
 | 
			
		||||
// This program is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
package ui
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func autocompleteFile(cmd *CommandAutocomplete) (completions []string, newText string) {
 | 
			
		||||
	inputPath, err := filepath.Abs(cmd.RawArgs)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var searchNamePrefix, searchDir string
 | 
			
		||||
	if strings.HasSuffix(cmd.RawArgs, "/") {
 | 
			
		||||
		searchDir = inputPath
 | 
			
		||||
	} else {
 | 
			
		||||
		searchNamePrefix = filepath.Base(inputPath)
 | 
			
		||||
		searchDir = filepath.Dir(inputPath)
 | 
			
		||||
	}
 | 
			
		||||
	files, err := ioutil.ReadDir(searchDir)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	for _, file := range files {
 | 
			
		||||
		name := file.Name()
 | 
			
		||||
		if !strings.HasPrefix(name, searchNamePrefix) || (name[0] == '.' && searchNamePrefix == "") {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		fullPath := filepath.Join(searchDir, name)
 | 
			
		||||
		if file.IsDir() {
 | 
			
		||||
			fullPath += "/"
 | 
			
		||||
		}
 | 
			
		||||
		completions = append(completions, fullPath)
 | 
			
		||||
	}
 | 
			
		||||
	if len(completions) == 1 {
 | 
			
		||||
		newText = fmt.Sprintf("/%s %s", cmd.OrigCommand, completions[0])
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
@@ -20,7 +20,6 @@ import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"math"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
@@ -34,7 +33,6 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
	"unicode"
 | 
			
		||||
 | 
			
		||||
	"github.com/gabriel-vasile/mimetype"
 | 
			
		||||
	"github.com/lucasb-eyer/go-colorful"
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
	"github.com/russross/blackfriday/v2"
 | 
			
		||||
@@ -179,40 +177,6 @@ func cmdRedact(cmd *Command) {
 | 
			
		||||
	cmd.Room.StartSelecting(SelectRedact, strings.Join(cmd.Args, " "))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func autocompleteFile(cmd *CommandAutocomplete) (completions []string, newText string) {
 | 
			
		||||
	inputPath, err := filepath.Abs(cmd.RawArgs)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var searchNamePrefix, searchDir string
 | 
			
		||||
	if strings.HasSuffix(cmd.RawArgs, "/") {
 | 
			
		||||
		searchDir = inputPath
 | 
			
		||||
	} else {
 | 
			
		||||
		searchNamePrefix = filepath.Base(inputPath)
 | 
			
		||||
		searchDir = filepath.Dir(inputPath)
 | 
			
		||||
	}
 | 
			
		||||
	files, err := ioutil.ReadDir(searchDir)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	for _, file := range files {
 | 
			
		||||
		name := file.Name()
 | 
			
		||||
		if !strings.HasPrefix(name, searchNamePrefix) || (name[0] == '.' && searchNamePrefix == "") {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		fullPath := filepath.Join(searchDir, name)
 | 
			
		||||
		if file.IsDir() {
 | 
			
		||||
			fullPath += "/"
 | 
			
		||||
		}
 | 
			
		||||
		completions = append(completions, fullPath)
 | 
			
		||||
	}
 | 
			
		||||
	if len(completions) == 1 {
 | 
			
		||||
		newText = fmt.Sprintf("/%s %s", cmd.OrigCommand, completions[0])
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdDownload(cmd *Command) {
 | 
			
		||||
	cmd.Room.StartSelecting(SelectDownload, strings.Join(cmd.Args, " "))
 | 
			
		||||
}
 | 
			
		||||
@@ -229,30 +193,7 @@ func cmdUpload(cmd *Command) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ftype, err := mimetype.DetectFile(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cmd.Reply("Failed to get conetnt type: %v", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fi, err := os.Stat(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cmd.Reply("Failed to stat file: %v", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	reader, err := os.Open(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		cmd.Reply("Failed to open file: %v", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cmd.Room.UploadMedia(mautrix.ReqUploadMedia{
 | 
			
		||||
		reader,
 | 
			
		||||
		fi.Size(),
 | 
			
		||||
		ftype.String(),
 | 
			
		||||
		filepath.Base(cmd.RawArgs),
 | 
			
		||||
	})
 | 
			
		||||
	go cmd.Room.SendMessageMedia(path)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cmdOpen(cmd *Command) {
 | 
			
		||||
 
 | 
			
		||||
@@ -31,17 +31,16 @@ import (
 | 
			
		||||
	"maunium.net/go/mauview"
 | 
			
		||||
	"maunium.net/go/tcell"
 | 
			
		||||
 | 
			
		||||
	"maunium.net/go/gomuks/lib/util"
 | 
			
		||||
	"maunium.net/go/mautrix/crypto/attachment"
 | 
			
		||||
 | 
			
		||||
	"maunium.net/go/mautrix"
 | 
			
		||||
	"maunium.net/go/mautrix/crypto/attachment"
 | 
			
		||||
	"maunium.net/go/mautrix/event"
 | 
			
		||||
	"maunium.net/go/mautrix/id"
 | 
			
		||||
 | 
			
		||||
	"maunium.net/go/gomuks/config"
 | 
			
		||||
	"maunium.net/go/gomuks/debug"
 | 
			
		||||
	ifc "maunium.net/go/gomuks/interface"
 | 
			
		||||
	"maunium.net/go/gomuks/interface"
 | 
			
		||||
	"maunium.net/go/gomuks/lib/open"
 | 
			
		||||
	"maunium.net/go/gomuks/lib/util"
 | 
			
		||||
	"maunium.net/go/gomuks/matrix/muksevt"
 | 
			
		||||
	"maunium.net/go/gomuks/matrix/rooms"
 | 
			
		||||
	"maunium.net/go/gomuks/ui/messages"
 | 
			
		||||
@@ -762,25 +761,46 @@ func (view *RoomView) SendMessage(msgtype event.MessageType, text string) {
 | 
			
		||||
	view.SendMessageHTML(msgtype, text, "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) getRelationForNewEvent() *ifc.Relation {
 | 
			
		||||
	if view.editing != nil {
 | 
			
		||||
		return &ifc.Relation{
 | 
			
		||||
			Type:  event.RelReplace,
 | 
			
		||||
			Event: view.editing,
 | 
			
		||||
		}
 | 
			
		||||
	} else if view.replying != nil {
 | 
			
		||||
		return &ifc.Relation{
 | 
			
		||||
			Type:  event.RelReference,
 | 
			
		||||
			Event: view.replying,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) SendMessageHTML(msgtype event.MessageType, text, html string) {
 | 
			
		||||
	defer debug.Recover()
 | 
			
		||||
	debug.Print("Sending message", msgtype, text, "to", view.Room.ID)
 | 
			
		||||
	if !view.config.Preferences.DisableEmojis {
 | 
			
		||||
		text = emoji.Sprint(text)
 | 
			
		||||
	}
 | 
			
		||||
	var rel *ifc.Relation
 | 
			
		||||
	if view.editing != nil {
 | 
			
		||||
		rel = &ifc.Relation{
 | 
			
		||||
			Type:  event.RelReplace,
 | 
			
		||||
			Event: view.editing,
 | 
			
		||||
		}
 | 
			
		||||
	} else if view.replying != nil {
 | 
			
		||||
		rel = &ifc.Relation{
 | 
			
		||||
			Type:  event.RelReference,
 | 
			
		||||
			Event: view.replying,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	rel := view.getRelationForNewEvent()
 | 
			
		||||
	evt := view.parent.matrix.PrepareMarkdownMessage(view.Room.ID, msgtype, text, html, rel)
 | 
			
		||||
	view.addLocalEcho(evt)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) SendMessageMedia(path string) {
 | 
			
		||||
	defer debug.Recover()
 | 
			
		||||
	debug.Print("Sending media at", path, "to", view.Room.ID)
 | 
			
		||||
	rel := view.getRelationForNewEvent()
 | 
			
		||||
	evt, err := view.parent.matrix.PrepareMediaMessage(view.Room, path, rel)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		view.AddServiceMessage(fmt.Sprintf("Failed to upload media: %v", err))
 | 
			
		||||
		view.parent.parent.Render()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	view.addLocalEcho(evt)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) addLocalEcho(evt *muksevt.Event) {
 | 
			
		||||
	msg := view.parseEvent(evt.SomewhatDangerousCopy())
 | 
			
		||||
	view.content.AddMessage(msg, AppendMessage)
 | 
			
		||||
	view.ClearAllContext()
 | 
			
		||||
@@ -806,20 +826,6 @@ func (view *RoomView) SendMessageHTML(msgtype event.MessageType, text, html stri
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) SendImage(body string, url id.ContentURI) {
 | 
			
		||||
	// evt := view.parent.matrix.SendImage(view.Room.ID, body, url)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) UploadMedia(data mautrix.ReqUploadMedia) {
 | 
			
		||||
	contentUri, err := view.parent.matrix.UploadMedia(data)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		view.AddServiceMessage(fmt.Sprintf("Failed to upload file: %v", err))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	view.AddServiceMessage(fmt.Sprintf("ContentURI: %v", contentUri))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (view *RoomView) MessageView() *MessageView {
 | 
			
		||||
	return view.content
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user