diff --git a/lib/filepicker/filepicker.go b/lib/filepicker/filepicker.go
new file mode 100644
index 0000000..3f07431
--- /dev/null
+++ b/lib/filepicker/filepicker.go
@@ -0,0 +1,49 @@
+// gomuks - A terminal Matrix client written in Go.
+// Copyright (C) 2022 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 .
+
+package filepicker
+
+import (
+ "bytes"
+ "errors"
+ "os/exec"
+ "strings"
+)
+
+var zenity string
+
+func init() {
+ zenity, _ = exec.LookPath("zenity")
+}
+
+func IsSupported() bool {
+ return len(zenity) > 0
+}
+
+func Open() (string, error) {
+ cmd := exec.Command(zenity, "--file-selection")
+ var output bytes.Buffer
+ cmd.Stdout = &output
+ err := cmd.Run()
+ if err != nil {
+ var exitErr *exec.ExitError
+ if errors.As(err, &exitErr) && exitErr.ExitCode() == 1 {
+ return "", nil
+ }
+ return "", err
+ }
+ return strings.TrimSpace(output.String()), nil
+}
diff --git a/ui/commands.go b/ui/commands.go
index 4d9c531..7466511 100644
--- a/ui/commands.go
+++ b/ui/commands.go
@@ -45,6 +45,7 @@ import (
"maunium.net/go/mautrix/id"
"maunium.net/go/gomuks/debug"
+ "maunium.net/go/gomuks/lib/filepicker"
)
func cmdMe(cmd *Command) {
@@ -258,15 +259,28 @@ func cmdDownload(cmd *Command) {
}
func cmdUpload(cmd *Command) {
+ var path string
+ var err error
if len(cmd.Args) == 0 {
- cmd.Reply("Usage: /upload ")
- return
- }
-
- path, err := filepath.Abs(cmd.RawArgs)
- if err != nil {
- cmd.Reply("Failed to get absolute path: %v", err)
- return
+ if filepicker.IsSupported() {
+ path, err = filepicker.Open()
+ if err != nil {
+ cmd.Reply("Failed to open file picker: %v", err)
+ return
+ } else if len(path) == 0 {
+ cmd.Reply("File picking cancelled")
+ return
+ }
+ } else {
+ cmd.Reply("Usage: /upload ")
+ return
+ }
+ } else {
+ path, err = filepath.Abs(cmd.RawArgs)
+ if err != nil {
+ cmd.Reply("Failed to get absolute path: %v", err)
+ return
+ }
}
go cmd.Room.SendMessageMedia(path)