5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 19:50:15 +08:00

Fix Bug with nil parameters.

Added browser and kvstore plugins.
This commit is contained in:
Lea Anthony 2023-03-20 20:28:33 +11:00
parent 13f620ae54
commit ba82f27534
14 changed files with 396 additions and 5 deletions

View File

@ -41,4 +41,9 @@ Informal and incomplete list of things needed in v3.
## Runtime
- [ ] To log or not to log?
- [ ] Unify cross-platform events, eg. `onClose`
- [ ] Unify cross-platform events, eg. `onClose`
## Plugins
- [ ] Move logins to `v3/plugins`
- [ ] Expose application logger to plugins

View File

@ -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 => ../..

View File

@ -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=

View File

@ -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/*
@ -20,7 +22,12 @@ func main() {
ApplicationShouldTerminateAfterLastWindowClosed: true,
},
Plugins: map[string]application.Plugin{
"hashes": hashes.NewPlugin(),
"hashes": hashes.NewPlugin(),
"browser": browser.NewPlugin(),
"kvstore": kvstore.NewPlugin(&kvstore.Config{
Filename: "store.json",
AutoSave: true,
}),
},
Assets: application.AssetOptions{
FS: assets,

View File

@ -0,0 +1 @@
{"url":null,"url2":"https://reddit.com"}

View File

@ -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)
}

View 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).

View 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)
}

View 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,
}
};

View 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"

View 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).

View 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
}

View 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");
}

View 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"