mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 19:31:20 +08:00
Fix Bug with nil parameters.
Added browser and kvstore plugins.
This commit is contained in:
parent
13f620ae54
commit
ba82f27534
@ -42,3 +42,8 @@ Informal and incomplete list of things needed in v3.
|
||||
|
||||
- [ ] To log or not to log?
|
||||
- [ ] Unify cross-platform events, eg. `onClose`
|
||||
|
||||
## Plugins
|
||||
|
||||
- [ ] Move logins to `v3/plugins`
|
||||
- [ ] Expose application logger to plugins
|
@ -9,11 +9,13 @@ require (
|
||||
github.com/leaanthony/slicer v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 // indirect
|
||||
github.com/samber/lo v1.37.0 // indirect
|
||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||
github.com/wailsapp/wails/v2 v2.3.2-0.20230117193915-45c3a501d9e6 // indirect
|
||||
golang.org/x/exp v0.0.0-20220930202632-ec3f01382ef9 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/wailsapp/wails/v3 => ../..
|
||||
|
@ -11,6 +11,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OH
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/samber/lo v1.37.0 h1:XjVcB8g6tgUp8rsPsJ2CvhClfImrpL04YpQHXeHPhRw=
|
||||
@ -27,6 +29,9 @@ golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -2,10 +2,12 @@ package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
_ "embed"
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"github.com/wailsapp/wails/v3/plugins/browser"
|
||||
"github.com/wailsapp/wails/v3/plugins/kvstore"
|
||||
"log"
|
||||
"plugin_demo/plugins/hashes"
|
||||
//"plugin_demo/plugins/hashes"
|
||||
)
|
||||
|
||||
//go:embed assets/*
|
||||
@ -21,6 +23,11 @@ func main() {
|
||||
},
|
||||
Plugins: map[string]application.Plugin{
|
||||
"hashes": hashes.NewPlugin(),
|
||||
"browser": browser.NewPlugin(),
|
||||
"kvstore": kvstore.NewPlugin(&kvstore.Config{
|
||||
Filename: "store.json",
|
||||
AutoSave: true,
|
||||
}),
|
||||
},
|
||||
Assets: application.AssetOptions{
|
||||
FS: assets,
|
||||
|
1
v3/examples/plugins/store.json
Normal file
1
v3/examples/plugins/store.json
Normal file
@ -0,0 +1 @@
|
||||
{"url":null,"url2":"https://reddit.com"}
|
@ -30,14 +30,14 @@ var reservedPluginMethods = []string{
|
||||
type Parameter struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
TypeName string `json:"type"`
|
||||
reflectType reflect.Type
|
||||
ReflectType reflect.Type
|
||||
}
|
||||
|
||||
func newParameter(Name string, Type reflect.Type) *Parameter {
|
||||
return &Parameter{
|
||||
Name: Name,
|
||||
TypeName: Type.String(),
|
||||
reflectType: Type,
|
||||
ReflectType: Type,
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,6 +243,10 @@ func (b *BoundMethod) Call(args []interface{}) (interface{}, error) {
|
||||
// Iterate over given arguments
|
||||
for index, arg := range args {
|
||||
// Save the converted argument
|
||||
if arg == nil {
|
||||
callArgs[index] = reflect.Zero(b.Inputs[index].ReflectType)
|
||||
continue
|
||||
}
|
||||
callArgs[index] = reflect.ValueOf(arg)
|
||||
}
|
||||
|
||||
|
51
v3/plugins/browser/README.md
Normal file
51
v3/plugins/browser/README.md
Normal file
@ -0,0 +1,51 @@
|
||||
# Browser Plugin
|
||||
|
||||
This plugin provides the ability to open a URL or local file in the default browser.
|
||||
|
||||
## Installation
|
||||
|
||||
Add the plugin to the `Plugins` option in the Applications options:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"github.com/wailsapp/wails/v3/plugins/browser"
|
||||
)
|
||||
|
||||
func main() {
|
||||
browserPlugin := browser.NewPlugin()
|
||||
app := application.New(application.Options{
|
||||
// ...
|
||||
Plugins: map[string]application.Plugin{
|
||||
"browser": browserPlugin,
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Go
|
||||
|
||||
You can call the methods exported by the plugin directly:
|
||||
|
||||
```go
|
||||
browserPlugin.OpenURL("https://www.google.com")
|
||||
// or
|
||||
browserPlugin.OpenFile("/path/to/file")
|
||||
```
|
||||
|
||||
### Javascript
|
||||
|
||||
You can call the methods from the frontend using the Plugin method:
|
||||
|
||||
```js
|
||||
wails.Plugin("browser","OpenURL","https://www.google.com")
|
||||
// or
|
||||
wails.Plugin("browser","OpenFile","/path/to/file")
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
If you find a bug in this plugin, please raise a ticket on the Wails [Issue Tracker](https://github.com/wailsapp/wails/issues).
|
37
v3/plugins/browser/plugin.go
Normal file
37
v3/plugins/browser/plugin.go
Normal file
@ -0,0 +1,37 @@
|
||||
package browser
|
||||
|
||||
import (
|
||||
"github.com/pkg/browser"
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
// ---------------- Plugin Setup ----------------
|
||||
// This is the main plugin struct. It can be named anything you like.
|
||||
// It must implement the application.Plugin interface.
|
||||
// Both the Init() and Shutdown() methods are called synchronously when the app starts and stops.
|
||||
|
||||
type Plugin struct{}
|
||||
|
||||
func NewPlugin() *Plugin {
|
||||
return &Plugin{}
|
||||
}
|
||||
|
||||
func (p *Plugin) Shutdown() {}
|
||||
|
||||
func (p *Plugin) Name() string {
|
||||
return "github.com/wailsapp/wails/v3/plugins/browser"
|
||||
}
|
||||
|
||||
func (p *Plugin) Init(_ *application.App) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ---------------- Plugin Methods ----------------
|
||||
|
||||
func (p *Plugin) OpenURL(url string) error {
|
||||
return browser.OpenURL(url)
|
||||
}
|
||||
|
||||
func (p *Plugin) OpenFile(path string) error {
|
||||
return browser.OpenFile(path)
|
||||
}
|
25
v3/plugins/browser/plugin.js
Normal file
25
v3/plugins/browser/plugin.js
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
/**
|
||||
* Opens the given URL in the default browser.
|
||||
* @param url {string} - The URL to open.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
function OpenURL(url) {
|
||||
return wails.Plugin("browser", "OpenURL", url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the given filename in the default browser.
|
||||
* @param filename {string} - The file to open.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
function OpenFile(filename) {
|
||||
return wails.Plugin("browser", "OpenFile", filename);
|
||||
}
|
||||
|
||||
export default {
|
||||
Browser: {
|
||||
OpenURL,
|
||||
OpenFile,
|
||||
}
|
||||
};
|
11
v3/plugins/browser/plugin.toml
Normal file
11
v3/plugins/browser/plugin.toml
Normal file
@ -0,0 +1,11 @@
|
||||
# This is the plugin definition file for the "browser" plugin.
|
||||
|
||||
Name = "browser"
|
||||
Description = "Opens URLs and files in the default browser."
|
||||
Author = "Lea Anthony"
|
||||
Version = "v1.0.0"
|
||||
Website = "https://wails.io"
|
||||
Repository = "https://github.com/wailsapp/wails/v3/plugins/browser"
|
||||
License = "MIT"
|
||||
|
||||
|
66
v3/plugins/kvstore/README.md
Normal file
66
v3/plugins/kvstore/README.md
Normal file
@ -0,0 +1,66 @@
|
||||
# KVStore Plugin
|
||||
|
||||
This plugin provides a simple key/value store for your Wails applications.
|
||||
|
||||
## Installation
|
||||
|
||||
Add the plugin to the `Plugins` option in the Applications options:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"github.com/wailsapp/wails/v3/plugins/kvstore"
|
||||
)
|
||||
|
||||
func main() {
|
||||
kvstorePlugin := kvstore.NewPlugin(&kvstore.Config{
|
||||
Filename: "myapp.db",
|
||||
})
|
||||
app := application.New(application.Options{
|
||||
// ...
|
||||
Plugins: map[string]application.Plugin{
|
||||
"kvstore": kvstorePlugin,
|
||||
},
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Go
|
||||
|
||||
You can call the methods exported by the plugin directly:
|
||||
|
||||
```go
|
||||
err := kvstore.Set("url", "https://www.google.com")
|
||||
if err != nil {
|
||||
// handle error
|
||||
}
|
||||
url := kvstore.Get("url").(string)
|
||||
|
||||
// If you have not enables AutoSave, you will need to call Save() to persist the changes
|
||||
err = kvstore.Save()
|
||||
if err != nil {
|
||||
// handle error
|
||||
}
|
||||
```
|
||||
|
||||
### Javascript
|
||||
|
||||
You can call the methods from the frontend using the Plugin method:
|
||||
|
||||
```js
|
||||
wails.Plugin("kvstore","Set", "url", "https://www.google.com")
|
||||
wails.Plugin("kvstore","Get", "url").then((url) => {
|
||||
|
||||
})
|
||||
|
||||
// or
|
||||
wails.Plugin("browser","OpenFile","/path/to/file")
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
If you find a bug in this plugin, please raise a ticket on the Wails [Issue Tracker](https://github.com/wailsapp/wails/issues).
|
135
v3/plugins/kvstore/kvstore.go
Normal file
135
v3/plugins/kvstore/kvstore.go
Normal file
@ -0,0 +1,135 @@
|
||||
package kvstore
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type KeyValueStore struct {
|
||||
config *Config
|
||||
filename string
|
||||
data map[string]any
|
||||
unsaved bool
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Filename string
|
||||
AutoSave bool
|
||||
}
|
||||
|
||||
type Plugin struct{}
|
||||
|
||||
func NewPlugin(config *Config) *KeyValueStore {
|
||||
return &KeyValueStore{
|
||||
config: config,
|
||||
data: make(map[string]any),
|
||||
}
|
||||
}
|
||||
|
||||
// Shutdown will save the store to disk if there are unsaved changes.
|
||||
func (kvs *KeyValueStore) Shutdown() {
|
||||
if kvs.unsaved {
|
||||
err := kvs.Save()
|
||||
if err != nil {
|
||||
println("Error saving store: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns the name of the plugin.
|
||||
func (kvs *KeyValueStore) Name() string {
|
||||
return "github.com/wailsapp/wails/v3/plugins/kvstore"
|
||||
}
|
||||
|
||||
// Init is called when the plugin is loaded. It is passed the application.App
|
||||
// instance. This is where you should do any setup.
|
||||
func (kvs *KeyValueStore) Init(_ *application.App) error {
|
||||
err := kvs.open(kvs.config.Filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ---------------- Plugin Methods ----------------
|
||||
|
||||
func (kvs *KeyValueStore) open(filename string) error {
|
||||
kvs.filename = filename
|
||||
kvs.data = make(map[string]any)
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
bytes, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(bytes) > 0 {
|
||||
if err := json.Unmarshal(bytes, &kvs.data); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Save saves the store to disk
|
||||
func (kvs *KeyValueStore) Save() error {
|
||||
kvs.lock.Lock()
|
||||
defer kvs.lock.Unlock()
|
||||
|
||||
bytes, err := json.Marshal(kvs.data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.WriteFile(kvs.filename, bytes, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kvs.unsaved = false
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the value for the given key. If key is empty, the entire store is returned.
|
||||
func (kvs *KeyValueStore) Get(key string) any {
|
||||
kvs.lock.RLock()
|
||||
defer kvs.lock.RUnlock()
|
||||
|
||||
if key == "" {
|
||||
return kvs.data
|
||||
}
|
||||
|
||||
return kvs.data[key]
|
||||
}
|
||||
|
||||
// Set sets the value for the given key. If AutoSave is true, the store is saved to disk.
|
||||
func (kvs *KeyValueStore) Set(key string, value any) error {
|
||||
kvs.lock.Lock()
|
||||
kvs.data[key] = value
|
||||
kvs.lock.Unlock()
|
||||
if kvs.config.AutoSave {
|
||||
err := kvs.Save()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
kvs.unsaved = false
|
||||
} else {
|
||||
kvs.unsaved = true
|
||||
}
|
||||
return nil
|
||||
}
|
31
v3/plugins/kvstore/plugin.js
Normal file
31
v3/plugins/kvstore/plugin.js
Normal file
@ -0,0 +1,31 @@
|
||||
// plugin.js
|
||||
// This file should contain helper functions for the that can be used by the frontend.
|
||||
// Below are examples of how to use JSDoc to define the Hashes struct and the exported functions.
|
||||
|
||||
/**
|
||||
* Get the value of a key.
|
||||
* @param key {string} - The store key.
|
||||
* @returns {Promise<any>} - The value of the key.
|
||||
*/
|
||||
export function Get(key) {
|
||||
return wails.Plugin("kvstore", "Get", key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a key.
|
||||
@param key {string} - The store key.
|
||||
@param value {any} - The value to set.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export function Set(key, value) {
|
||||
return wails.Plugin("kvstore", "Set", key, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save the database to disk.
|
||||
* @returns {Promise<void|Error>}
|
||||
*/
|
||||
export function Save() {
|
||||
return wails.Plugin("kvstore", "Save");
|
||||
}
|
11
v3/plugins/kvstore/plugin.toml
Normal file
11
v3/plugins/kvstore/plugin.toml
Normal file
@ -0,0 +1,11 @@
|
||||
# This is the plugin definition file for the "kvstore" plugin.
|
||||
|
||||
Name = "kvstore"
|
||||
Description = "A Simple Key/Value Store for Wails Applications"
|
||||
Author = "Lea Anthony"
|
||||
Version = "v1.0.0"
|
||||
Website = "https://wails.io"
|
||||
Repository = "https://github.com/wailsapp/wails/v3/plugins/kvstore"
|
||||
License = "MIT"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user