126 lines
3.2 KiB
Go
Executable File
126 lines
3.2 KiB
Go
Executable File
package file_picker
|
|
|
|
import (
|
|
"encoding/json"
|
|
"github.com/gen2brain/dlgs"
|
|
"github.com/go-flutter-desktop/go-flutter"
|
|
"github.com/go-flutter-desktop/go-flutter/plugin"
|
|
"github.com/pkg/errors"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
const channelName = "miguelruivo.flutter.plugins.filepicker"
|
|
|
|
type FilePickerPlugin struct{}
|
|
|
|
var _ flutter.Plugin = &FilePickerPlugin{} // compile-time type check
|
|
|
|
func (p *FilePickerPlugin) InitPlugin(messenger plugin.BinaryMessenger) error {
|
|
channel := plugin.NewMethodChannel(messenger, channelName, plugin.JSONMethodCodec{})
|
|
channel.CatchAllHandleFunc(p.handleFilePicker)
|
|
return nil
|
|
}
|
|
|
|
func (p *FilePickerPlugin) handleFilePicker(methodCall interface{}) (reply interface{}, err error) {
|
|
method := methodCall.(plugin.MethodCall).Method
|
|
|
|
if "dir" == method {
|
|
dirPath, err := dirDialog("Select a directory")
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to open dialog picker")
|
|
}
|
|
return dirPath, nil
|
|
}
|
|
|
|
var arguments map[string]interface{}
|
|
|
|
err = json.Unmarshal(methodCall.(plugin.MethodCall).Arguments.(json.RawMessage), &arguments)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to decode arguments")
|
|
}
|
|
|
|
var allowedExtensions []string
|
|
|
|
// Parse extensions
|
|
if arguments != nil && arguments["allowedExtensions"] != nil {
|
|
allowedExtensions = make([]string, len(arguments["allowedExtensions"].([]interface{})))
|
|
for i := range arguments["allowedExtensions"].([]interface{}) {
|
|
allowedExtensions[i] = arguments["allowedExtensions"].([]interface{})[i].(string)
|
|
}
|
|
}
|
|
|
|
selectMultiple, ok := arguments["allowMultipleSelection"].(bool) //method.Arguments.(bool)
|
|
if !ok {
|
|
return nil, errors.Wrap(err, "invalid format for argument, not a bool")
|
|
}
|
|
|
|
filter, err := fileFilter(method, allowedExtensions, len(allowedExtensions), selectMultiple)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to get filter")
|
|
}
|
|
|
|
withData, ok := arguments["withData"].(bool)
|
|
|
|
var selectedFilePaths []string
|
|
|
|
if selectMultiple {
|
|
filePaths, _, err := dlgs.FileMulti("Select one or more files", filter)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to open dialog picker")
|
|
}
|
|
|
|
selectedFilePaths = make([]string, len(filePaths))
|
|
|
|
for i, filePath := range filePaths {
|
|
selectedFilePaths[i] = filePath
|
|
}
|
|
} else {
|
|
selectedFilePaths = make([]string, 1)
|
|
|
|
filePath, err := fileDialog("Select a file", filter)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed to open dialog picker")
|
|
}
|
|
|
|
selectedFilePaths[0] = filePath
|
|
}
|
|
|
|
result := make([]map[string]interface{}, len(selectedFilePaths))
|
|
|
|
for i, filePath := range selectedFilePaths {
|
|
file, err := os.Open(filePath)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Can't open selected file")
|
|
}
|
|
|
|
fi, err := file.Stat()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Can't open selected file")
|
|
}
|
|
|
|
var bytes []byte
|
|
|
|
if withData {
|
|
_, err := file.Read(bytes)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Can't read selected file")
|
|
}
|
|
}
|
|
|
|
result[i] = map[string]interface{}{
|
|
"path": filePath,
|
|
"name": filepath.Base(filePath),
|
|
"bytes": bytes,
|
|
"size": fi.Size(),
|
|
}
|
|
|
|
err = file.Close()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "Can't close selected file after reading")
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|