mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 06:51:26 +08:00
Bridge working for calls. Notify TBD
This commit is contained in:
parent
e4b03f510b
commit
7c22cbcf38
@ -3,12 +3,12 @@
|
|||||||
"browser": true,
|
"browser": true,
|
||||||
"es6": true,
|
"es6": true,
|
||||||
"amd": true,
|
"amd": true,
|
||||||
"node": true,
|
"node": true
|
||||||
},
|
},
|
||||||
"extends": "eslint:recommended",
|
"extends": "eslint:recommended",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2016,
|
"ecmaVersion": 2016,
|
||||||
"sourceType": "module",
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"indent": [
|
"indent": [
|
||||||
|
@ -54,7 +54,6 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
|
|||||||
var debugBinaryProcess *process.Process = nil
|
var debugBinaryProcess *process.Process = nil
|
||||||
var buildFrontend bool = false
|
var buildFrontend bool = false
|
||||||
var extensionsThatTriggerARebuild = strings.Split(extensions, ",")
|
var extensionsThatTriggerARebuild = strings.Split(extensions, ",")
|
||||||
println(extensionsThatTriggerARebuild)
|
|
||||||
|
|
||||||
// Setup signal handler
|
// Setup signal handler
|
||||||
quitChannel := make(chan os.Signal, 1)
|
quitChannel := make(chan os.Signal, 1)
|
||||||
|
@ -7,6 +7,7 @@ require (
|
|||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/fatih/structtag v1.2.0
|
github.com/fatih/structtag v1.2.0
|
||||||
github.com/fsnotify/fsnotify v1.4.9
|
github.com/fsnotify/fsnotify v1.4.9
|
||||||
|
github.com/gorilla/websocket v1.4.1
|
||||||
github.com/imdario/mergo v0.3.11
|
github.com/imdario/mergo v0.3.11
|
||||||
github.com/jackmordaunt/icns v1.0.0
|
github.com/jackmordaunt/icns v1.0.0
|
||||||
github.com/leaanthony/clir v1.0.4
|
github.com/leaanthony/clir v1.0.4
|
||||||
|
@ -231,7 +231,5 @@ func (a *App) Run() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Desktop.Run() finished")
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -232,8 +232,6 @@ func (a *App) Run() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Desktop.Run() finished")
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,56 @@
|
|||||||
package bridge
|
package bridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/wailsapp/wails/v2/internal/logger"
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Bridge struct {
|
type Bridge struct {
|
||||||
upgrader websocket.Upgrader
|
upgrader websocket.Upgrader
|
||||||
server *http.Server
|
server *http.Server
|
||||||
myLogger *logger.Logger
|
myLogger *logger.Logger
|
||||||
|
|
||||||
|
bindings string
|
||||||
|
dispatcher *messagedispatcher.Dispatcher
|
||||||
|
|
||||||
|
mu sync.Mutex
|
||||||
|
sessions map[string]*session
|
||||||
|
|
||||||
|
ctx context.Context
|
||||||
|
cancel context.CancelFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBridge(myLogger *logger.Logger) *Bridge {
|
func NewBridge(myLogger *logger.Logger) *Bridge {
|
||||||
result := &Bridge{
|
result := &Bridge{
|
||||||
myLogger: myLogger,
|
myLogger: myLogger,
|
||||||
upgrader: websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }},
|
upgrader: websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }},
|
||||||
|
sessions: make(map[string]*session),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myLogger.SetLogLevel(1)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
result.ctx = ctx
|
||||||
|
result.cancel = cancel
|
||||||
result.server = &http.Server{Addr: ":34115"}
|
result.server = &http.Server{Addr: ":34115"}
|
||||||
http.HandleFunc("/bridge", result.wsBridgeHandler)
|
http.HandleFunc("/bridge", result.wsBridgeHandler)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bridge) Run(dispatcher *messagedispatcher.Dispatcher, bindingDump string, debug bool) error {
|
func (b *Bridge) Run(dispatcher *messagedispatcher.Dispatcher, bindings string, debug bool) error {
|
||||||
|
|
||||||
|
// Ensure we cancel the context when we shutdown
|
||||||
|
defer b.cancel()
|
||||||
|
|
||||||
|
b.bindings = bindings
|
||||||
|
b.dispatcher = dispatcher
|
||||||
|
|
||||||
b.myLogger.Info("Bridge mode started.")
|
b.myLogger.Info("Bridge mode started.")
|
||||||
|
|
||||||
@ -44,18 +68,32 @@ func (b *Bridge) wsBridgeHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Print("upgrade:", err)
|
log.Print("upgrade:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer c.Close()
|
|
||||||
for {
|
if err != nil {
|
||||||
mt, message, err := c.ReadMessage()
|
http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
|
||||||
if err != nil {
|
|
||||||
log.Println("read:", err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
log.Printf("recv: %s", message)
|
|
||||||
err = c.WriteMessage(mt, message)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("write:", err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
b.myLogger.Info("Connection from frontend accepted [%s].", c.RemoteAddr().String())
|
||||||
|
b.startSession(c)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bridge) startSession(conn *websocket.Conn) {
|
||||||
|
|
||||||
|
// Create a new session for this connection
|
||||||
|
s := newSession(conn, b.bindings, b.dispatcher, b.myLogger, b.ctx)
|
||||||
|
|
||||||
|
// Setup the close handler
|
||||||
|
conn.SetCloseHandler(func(int, string) error {
|
||||||
|
b.myLogger.Info("Connection dropped [%s].", s.Identifier())
|
||||||
|
|
||||||
|
b.mu.Lock()
|
||||||
|
delete(b.sessions, s.Identifier())
|
||||||
|
b.mu.Unlock()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
b.mu.Lock()
|
||||||
|
go s.start(len(b.sessions) == 0)
|
||||||
|
b.sessions[s.Identifier()] = s
|
||||||
|
b.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
121
v2/internal/bridge/client.go
Normal file
121
v2/internal/bridge/client.go
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package bridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/wailsapp/wails/v2/pkg/options/dialog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BridgeClient struct {
|
||||||
|
session *session
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) Quit() {
|
||||||
|
b.session.log.Info("Quit unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) NotifyEvent(message string) {
|
||||||
|
//b.session.sendMessage("n" + message)
|
||||||
|
b.session.log.Info("NotifyEvent: %s", message)
|
||||||
|
b.session.log.Info("NotifyEvent unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) CallResult(message string) {
|
||||||
|
b.session.sendMessage("c" + message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) OpenDialog(dialogOptions *dialog.OpenDialog, callbackID string) {
|
||||||
|
b.session.log.Info("OpenDialog unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) SaveDialog(dialogOptions *dialog.SaveDialog, callbackID string) {
|
||||||
|
b.session.log.Info("SaveDialog unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) MessageDialog(dialogOptions *dialog.MessageDialog, callbackID string) {
|
||||||
|
b.session.log.Info("MessageDialog unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowSetTitle(title string) {
|
||||||
|
b.session.log.Info("WindowSetTitle unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowShow() {
|
||||||
|
b.session.log.Info("WindowShow unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowHide() {
|
||||||
|
b.session.log.Info("WindowHide unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowCenter() {
|
||||||
|
b.session.log.Info("WindowCenter unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowMaximise() {
|
||||||
|
b.session.log.Info("WindowMaximise unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowUnmaximise() {
|
||||||
|
b.session.log.Info("WindowUnmaximise unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowMinimise() {
|
||||||
|
b.session.log.Info("WindowMinimise unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowUnminimise() {
|
||||||
|
b.session.log.Info("WindowUnminimise unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowPosition(x int, y int) {
|
||||||
|
b.session.log.Info("WindowPosition unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowSize(width int, height int) {
|
||||||
|
b.session.log.Info("WindowSize unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowSetMinSize(width int, height int) {
|
||||||
|
b.session.log.Info("WindowSetMinSize unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowSetMaxSize(width int, height int) {
|
||||||
|
b.session.log.Info("WindowSetMaxSize unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowFullscreen() {
|
||||||
|
b.session.log.Info("WindowFullscreen unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowUnFullscreen() {
|
||||||
|
b.session.log.Info("WindowUnFullscreen unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) WindowSetColour(colour int) {
|
||||||
|
b.session.log.Info("WindowSetColour unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) DarkModeEnabled(callbackID string) {
|
||||||
|
b.session.log.Info("DarkModeEnabled unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) SetApplicationMenu(menuJSON string) {
|
||||||
|
b.session.log.Info("SetApplicationMenu unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) SetTrayMenu(trayMenuJSON string) {
|
||||||
|
b.session.log.Info("SetTrayMenu unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) UpdateTrayMenuLabel(JSON string) {
|
||||||
|
b.session.log.Info("UpdateTrayMenuLabel unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BridgeClient) UpdateContextMenu(contextMenuJSON string) {
|
||||||
|
b.session.log.Info("UpdateContextMenu unsupported in Bridge mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBridgeClient(session *session) *BridgeClient {
|
||||||
|
return &BridgeClient{
|
||||||
|
session: session,
|
||||||
|
}
|
||||||
|
}
|
145
v2/internal/bridge/session.go
Normal file
145
v2/internal/bridge/session.go
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
package bridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
_ "embed"
|
||||||
|
"log"
|
||||||
|
"runtime"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
"github.com/wailsapp/wails/v2/internal/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed darwin.js
|
||||||
|
var darwinRuntime string
|
||||||
|
|
||||||
|
// session represents a single websocket session
|
||||||
|
type session struct {
|
||||||
|
bindings string
|
||||||
|
conn *websocket.Conn
|
||||||
|
//eventManager interfaces.EventManager
|
||||||
|
log *logger.Logger
|
||||||
|
//ipc interfaces.IPCManager
|
||||||
|
|
||||||
|
// Mutex for writing to the socket
|
||||||
|
shutdown chan bool
|
||||||
|
writeChan chan []byte
|
||||||
|
|
||||||
|
done bool
|
||||||
|
|
||||||
|
// context
|
||||||
|
ctx context.Context
|
||||||
|
|
||||||
|
// client
|
||||||
|
client *messagedispatcher.DispatchClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSession(conn *websocket.Conn, bindings string, dispatcher *messagedispatcher.Dispatcher, logger *logger.Logger, ctx context.Context) *session {
|
||||||
|
result := &session{
|
||||||
|
conn: conn,
|
||||||
|
bindings: bindings,
|
||||||
|
log: logger,
|
||||||
|
shutdown: make(chan bool),
|
||||||
|
writeChan: make(chan []byte, 100),
|
||||||
|
ctx: ctx,
|
||||||
|
}
|
||||||
|
|
||||||
|
result.client = dispatcher.RegisterClient(newBridgeClient(result))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identifier returns a string identifier for the remote connection.
|
||||||
|
// Taking the form of the client's <ip address>:<port>.
|
||||||
|
func (s *session) Identifier() string {
|
||||||
|
if s.conn != nil {
|
||||||
|
return s.conn.RemoteAddr().String()
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *session) sendMessage(msg string) error {
|
||||||
|
if !s.done {
|
||||||
|
s.writeChan <- []byte(msg)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *session) start(firstSession bool) {
|
||||||
|
s.log.SetLogLevel(1)
|
||||||
|
s.log.Info("Connected to frontend.")
|
||||||
|
go s.writePump()
|
||||||
|
|
||||||
|
var wailsRuntime string
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin":
|
||||||
|
wailsRuntime = darwinRuntime
|
||||||
|
default:
|
||||||
|
log.Fatal("platform not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingsMessage := "window.wailsbindings = `" + s.bindings + "`;"
|
||||||
|
s.log.Info(bindingsMessage)
|
||||||
|
bootstrapMessage := bindingsMessage + wailsRuntime
|
||||||
|
|
||||||
|
s.sendMessage("b" + bootstrapMessage)
|
||||||
|
|
||||||
|
for {
|
||||||
|
messageType, buffer, err := s.conn.ReadMessage()
|
||||||
|
if messageType == -1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
s.log.Error("Error reading message: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
message := string(buffer)
|
||||||
|
|
||||||
|
s.log.Debug("Got message: %#v\n", message)
|
||||||
|
|
||||||
|
// Dispatch message as normal
|
||||||
|
s.client.DispatchMessage(message)
|
||||||
|
|
||||||
|
if s.done {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shutdown
|
||||||
|
func (s *session) Shutdown() {
|
||||||
|
s.conn.Close()
|
||||||
|
s.done = true
|
||||||
|
s.log.Info("session %v exit", s.Identifier())
|
||||||
|
}
|
||||||
|
|
||||||
|
// writePump pulls messages from the writeChan and sends them to the client
|
||||||
|
// since it uses a channel to read the messages the socket is protected without locks
|
||||||
|
func (s *session) writePump() {
|
||||||
|
s.log.Debug("Session %v - writePump start", s.Identifier())
|
||||||
|
defer s.log.Debug("Session %v - writePump shutdown", s.Identifier())
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-s.ctx.Done():
|
||||||
|
s.Shutdown()
|
||||||
|
return
|
||||||
|
case msg, ok := <-s.writeChan:
|
||||||
|
s.conn.SetWriteDeadline(time.Now().Add(1 * time.Second))
|
||||||
|
if !ok {
|
||||||
|
s.log.Debug("writeChan was closed!")
|
||||||
|
s.conn.WriteMessage(websocket.CloseMessage, []byte{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.conn.WriteMessage(websocket.TextMessage, msg); err != nil {
|
||||||
|
s.log.Debug(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -169,7 +169,6 @@ func (a *Application) Run(incomingDispatcher Dispatcher, bindings string, debug
|
|||||||
// Yes - Save memory reference and run app, cleaning up afterwards
|
// Yes - Save memory reference and run app, cleaning up afterwards
|
||||||
a.saveMemoryReference(unsafe.Pointer(app))
|
a.saveMemoryReference(unsafe.Pointer(app))
|
||||||
C.Run(app, 0, nil)
|
C.Run(app, 0, nil)
|
||||||
println("Back in ffenestri.go")
|
|
||||||
} else {
|
} else {
|
||||||
// Oh no! We couldn't initialise the application
|
// Oh no! We couldn't initialise the application
|
||||||
a.logger.Fatal("Cannot initialise Application.")
|
a.logger.Fatal("Cannot initialise Application.")
|
||||||
|
File diff suppressed because one or more lines are too long
@ -65,7 +65,7 @@ export function SetBindings(bindingsMap) {
|
|||||||
window.backend[packageName][structName][methodName] = function () {
|
window.backend[packageName][structName][methodName] = function () {
|
||||||
|
|
||||||
// No timeout by default
|
// No timeout by default
|
||||||
var timeout = 0;
|
let timeout = 0;
|
||||||
|
|
||||||
// Actual function
|
// Actual function
|
||||||
function dynamic() {
|
function dynamic() {
|
||||||
@ -89,19 +89,3 @@ export function SetBindings(bindingsMap) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// /**
|
|
||||||
// * Determines if the given identifier is valid Javascript
|
|
||||||
// *
|
|
||||||
// * @param {boolean} name
|
|
||||||
// * @returns
|
|
||||||
// */
|
|
||||||
// function isValidIdentifier(name) {
|
|
||||||
// // Don't xss yourself :-)
|
|
||||||
// try {
|
|
||||||
// new Function('var ' + name);
|
|
||||||
// return true;
|
|
||||||
// } catch (e) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import { Error } from './log';
|
|||||||
import { SendMessage } from 'ipc';
|
import { SendMessage } from 'ipc';
|
||||||
|
|
||||||
// Defines a single listener with a maximum number of times to callback
|
// Defines a single listener with a maximum number of times to callback
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Listener class defines a listener! :-)
|
* The Listener class defines a listener! :-)
|
||||||
*
|
*
|
||||||
@ -43,7 +44,7 @@ class Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var eventListeners = {};
|
let eventListeners = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers an event listener that will be invoked `maxCallbacks` times before being destroyed
|
* Registers an event listener that will be invoked `maxCallbacks` times before being destroyed
|
||||||
@ -96,7 +97,7 @@ export function Once(eventName, callback) {
|
|||||||
function notifyListeners(eventData) {
|
function notifyListeners(eventData) {
|
||||||
|
|
||||||
// Get the event name
|
// Get the event name
|
||||||
var eventName = eventData.name;
|
let eventName = eventData.name;
|
||||||
|
|
||||||
// Check if we have any listeners for this event
|
// Check if we have any listeners for this event
|
||||||
if (eventListeners[eventName]) {
|
if (eventListeners[eventName]) {
|
||||||
@ -110,7 +111,7 @@ function notifyListeners(eventData) {
|
|||||||
// Get next listener
|
// Get next listener
|
||||||
const listener = eventListeners[eventName][count];
|
const listener = eventListeners[eventName][count];
|
||||||
|
|
||||||
var data = eventData.data;
|
let data = eventData.data;
|
||||||
|
|
||||||
// Do the callback
|
// Do the callback
|
||||||
const destroy = listener.Callback(data);
|
const destroy = listener.Callback(data);
|
||||||
@ -120,7 +121,7 @@ function notifyListeners(eventData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update callbacks with new list of listners
|
// Update callbacks with new list of listeners
|
||||||
eventListeners[eventName] = newEventListenerList;
|
eventListeners[eventName] = newEventListenerList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,4 @@ export function Init() {
|
|||||||
|
|
||||||
// Do platform specific Init
|
// Do platform specific Init
|
||||||
Platform.Init();
|
Platform.Init();
|
||||||
|
|
||||||
window.wailsloader.runtime = true;
|
|
||||||
}
|
}
|
@ -27,7 +27,7 @@ export function Init() {
|
|||||||
// Setup drag handler
|
// Setup drag handler
|
||||||
// Based on code from: https://github.com/patr0nus/DeskGap
|
// Based on code from: https://github.com/patr0nus/DeskGap
|
||||||
window.addEventListener('mousedown', function (e) {
|
window.addEventListener('mousedown', function (e) {
|
||||||
var currentElement = e.target;
|
let currentElement = e.target;
|
||||||
while (currentElement != null) {
|
while (currentElement != null) {
|
||||||
if (currentElement.hasAttribute('data-wails-no-drag')) {
|
if (currentElement.hasAttribute('data-wails-no-drag')) {
|
||||||
break;
|
break;
|
||||||
|
@ -22,7 +22,7 @@ function init() {
|
|||||||
overlayHTML:
|
overlayHTML:
|
||||||
'<div class="wails-reconnect-overlay"><div class="wails-reconnect-overlay-content"><div class="wails-reconnect-overlay-loadingspinner"></div></div></div>',
|
'<div class="wails-reconnect-overlay"><div class="wails-reconnect-overlay-content"><div class="wails-reconnect-overlay-loadingspinner"></div></div></div>',
|
||||||
overlayCSS:
|
overlayCSS:
|
||||||
'.wails-reconnect-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:linear-gradient(45deg,rgb(0 0 0 / 60%) 0%,rgb(4 0 255 / 60%) 100%);font-family:sans-serif;display:none;z-index:999999}.wails-reconnect-overlay-content{text-align:center;width:10em;position:relative;margin:5% auto 0;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAAuCAMAAACPpbA7AAAAflBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAAAAABAQEEBAQAAAAAAAAEBAQAAAADAwMAAAABAQEAAAAAAAAAAAAAAAAAAAACAgICAgIBAQEAAAAAAAAAAAAAAAAAAAACAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQWCC3waAAAAKXRSTlMALgUMIBk0+xEqJs70Xhb3lu3EjX2EZTlv5eHXvbarQj3cdmpXSqOeUDwaqNAAAAKCSURBVEjHjZTntqsgEIUPVVCwtxg1vfD+L3hHRe8K6snZf+KKn8OewvzsSSeXLruLnz+KHs0gr6DkT3xsRkU6VVn4Ha/UxLe1Z4y64i847sykPBh/AvQ7ry3eFN70oKrfcBJYvm/tQ1qxP4T3emXPeXAkvodPUvtdjbhk+Ft4c0hslTiXVOzxOJ15NWUblQhRsdu3E1AfCjj3Gdm18zSOsiH8Lk4TB480ksy62fiqNo4OpyU8O21l6+hyRtS6z8r1pHlmle5sR1/WXS6Mq2Nl+YeKt3vr+vdH/q4O68tzXuwkiZmngYb4R8Co1jh0+Ww2UTyWxBvtyxLO7QVjO3YOD/lWZpbXDGellFG2Mws58mMnjVZSn7p+XvZ6IF4nn02OJZV0aTO22arp/DgLPtrgpVoi6TPbZm4XQBjY159w02uO0BDdYsfrOEi0M2ulRXlCIPAOuN1NOVhi+riBR3dgwQplYsZRZJLXq23Mlo5njkbY0rZFu3oiNIYG2kqsbVz67OlNuZZIOlfxHDl0UpyRX86z/OYC/3qf1A1xTrMp/PWWM4ePzf8DDp1nesQRpcFk7BlwdzN08ZIALJpCaciQXO0f6k4dnuT/Ewg4l7qSTNzm2SykdHn6GJ12mWc6aCNj/g1cTXpB8YFfr0uVc96aFkkqiIiX4nO+salKwGtIkvfB+Ja8DxMeD3hIXP5mTOYPB4eVT0+32I5ykvPZjesnkGgIREgYnmLrPb0PdV3hoLup2TjcGBPM4mgsfF5BrawZR4/GpzYQzQfrUZCf0TCWYo2DqhdhTJBQ6j4xqmmLN5LjdRIY8LWExiFUsSrza/nmFBqw3I9tEZB9h0lIQSO9if8DkISDAj8CDawAAAAASUVORK5CYII=);background-repeat:no-repeat;background-position:center}.wails-reconnect-overlay-loadingspinner{pointer-events:none;width:2.5em;height:2.5em;border:.4em solid transparent;border-color:#fff #eee0 #fff #eee0;border-radius:50%;animation:loadingspin 1s linear infinite;margin:auto;padding:2.5em}@keyframes loadingspin{100%{transform:rotate(360deg); opacity}}',
|
'.wails-reconnect-overlay{position:fixed;top:0;left:0;width:100%;height:100%;backdrop-filter: blur(20px) saturate(160%) contrast(45%) brightness(140%);display:none;z-index:999999}.wails-reconnect-overlay-content{position:relative;top:50%;transform:translateY(-50%);margin: 0;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAAuCAMAAACPpbA7AAAAflBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAAAAABAQEEBAQAAAAAAAAEBAQAAAADAwMAAAABAQEAAAAAAAAAAAAAAAAAAAACAgICAgIBAQEAAAAAAAAAAAAAAAAAAAACAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQWCC3waAAAAKXRSTlMALgUMIBk0+xEqJs70Xhb3lu3EjX2EZTlv5eHXvbarQj3cdmpXSqOeUDwaqNAAAAKCSURBVEjHjZTntqsgEIUPVVCwtxg1vfD+L3hHRe8K6snZf+KKn8OewvzsSSeXLruLnz+KHs0gr6DkT3xsRkU6VVn4Ha/UxLe1Z4y64i847sykPBh/AvQ7ry3eFN70oKrfcBJYvm/tQ1qxP4T3emXPeXAkvodPUvtdjbhk+Ft4c0hslTiXVOzxOJ15NWUblQhRsdu3E1AfCjj3Gdm18zSOsiH8Lk4TB480ksy62fiqNo4OpyU8O21l6+hyRtS6z8r1pHlmle5sR1/WXS6Mq2Nl+YeKt3vr+vdH/q4O68tzXuwkiZmngYb4R8Co1jh0+Ww2UTyWxBvtyxLO7QVjO3YOD/lWZpbXDGellFG2Mws58mMnjVZSn7p+XvZ6IF4nn02OJZV0aTO22arp/DgLPtrgpVoi6TPbZm4XQBjY159w02uO0BDdYsfrOEi0M2ulRXlCIPAOuN1NOVhi+riBR3dgwQplYsZRZJLXq23Mlo5njkbY0rZFu3oiNIYG2kqsbVz67OlNuZZIOlfxHDl0UpyRX86z/OYC/3qf1A1xTrMp/PWWM4ePzf8DDp1nesQRpcFk7BlwdzN08ZIALJpCaciQXO0f6k4dnuT/Ewg4l7qSTNzm2SykdHn6GJ12mWc6aCNj/g1cTXpB8YFfr0uVc96aFkkqiIiX4nO+salKwGtIkvfB+Ja8DxMeD3hIXP5mTOYPB4eVT0+32I5ykvPZjesnkGgIREgYnmLrPb0PdV3hoLup2TjcGBPM4mgsfF5BrawZR4/GpzYQzQfrUZCf0TCWYo2DqhdhTJBQ6j4xqmmLN5LjdRIY8LWExiFUsSrza/nmFBqw3I9tEZB9h0lIQSO9if8DkISDAj8CDawAAAAASUVORK5CYII=);background-repeat:no-repeat;background-position:center}.wails-reconnect-overlay-loadingspinner{pointer-events:none;width:2.5em;height:2.5em;border:.4em solid transparent;border-color:#f00 #eee0 #f00 #eee0;border-radius:50%;animation:loadingspin 1s linear infinite;margin:auto;padding:2.5em}@keyframes loadingspin{100%{transform:rotate(360deg); opacity}}',
|
||||||
log: function (message) {
|
log: function (message) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.log(
|
console.log(
|
||||||
@ -34,6 +34,19 @@ function init() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupIPCBridge() {
|
||||||
|
// darwin
|
||||||
|
window.webkit = {
|
||||||
|
messageHandlers: {
|
||||||
|
external: {
|
||||||
|
postMessage: (message) => {
|
||||||
|
window.wailsbridge.websocket.send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Adapted from webview - thanks zserge!
|
// Adapted from webview - thanks zserge!
|
||||||
function injectCSS(css) {
|
function injectCSS(css) {
|
||||||
const elem = document.createElement('style');
|
const elem = document.createElement('style');
|
||||||
@ -116,6 +129,7 @@ function startBridge() {
|
|||||||
// Handles incoming websocket connections
|
// Handles incoming websocket connections
|
||||||
function handleConnect() {
|
function handleConnect() {
|
||||||
window.wailsbridge.log('Connected to backend');
|
window.wailsbridge.log('Connected to backend');
|
||||||
|
setupIPCBridge();
|
||||||
hideReconnectOverlay();
|
hideReconnectOverlay();
|
||||||
clearInterval(window.wailsbridge.connectTimer);
|
clearInterval(window.wailsbridge.connectTimer);
|
||||||
window.wailsbridge.websocket.onclose = handleDisconnect;
|
window.wailsbridge.websocket.onclose = handleDisconnect;
|
||||||
@ -132,7 +146,7 @@ function startBridge() {
|
|||||||
connect();
|
connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to connect to the backend every 300ms (default value).
|
// Try to connect to the backend every 1s (default value).
|
||||||
// Change this value in the main wailsbridge object.
|
// Change this value in the main wailsbridge object.
|
||||||
function connect() {
|
function connect() {
|
||||||
window.wailsbridge.connectTimer = setInterval(function () {
|
window.wailsbridge.connectTimer = setInterval(function () {
|
||||||
@ -154,37 +168,37 @@ function startBridge() {
|
|||||||
// As a bridge we ignore js and css injections
|
// As a bridge we ignore js and css injections
|
||||||
switch (message.data[0]) {
|
switch (message.data[0]) {
|
||||||
// Wails library - inject!
|
// Wails library - inject!
|
||||||
case 'w':
|
case 'b':
|
||||||
addScript(message.data.slice(1));
|
message = message.data.slice(1)
|
||||||
|
addScript(message);
|
||||||
|
window.wailsbridge.log('Loaded Wails Runtime');
|
||||||
|
|
||||||
// Now wails runtime is loaded, wails for the ready event
|
// Now wails runtime is loaded, wails for the ready event
|
||||||
// and callback to the main app
|
// and callback to the main app
|
||||||
window.wails.Events.On('wails:loaded', function () {
|
// window.wails.Events.On('wails:loaded', function () {
|
||||||
window.wailsbridge.log('Wails Ready');
|
if (window.wailsbridge.callback) {
|
||||||
if (window.wailsbridge.callback) {
|
window.wailsbridge.log('Notifying application');
|
||||||
window.wailsbridge.log('Notifying application');
|
window.wailsbridge.callback(window.wails);
|
||||||
window.wailsbridge.callback(window.wails);
|
}
|
||||||
}
|
// });
|
||||||
});
|
|
||||||
window.wailsbridge.log('Loaded Wails Runtime');
|
|
||||||
break;
|
break;
|
||||||
// Notifications
|
// // Notifications
|
||||||
case 'n':
|
// case 'n':
|
||||||
addScript(message.data.slice(1), true);
|
// addScript(message.data.slice(1), true);
|
||||||
break;
|
// break;
|
||||||
// Binding
|
// // Binding
|
||||||
case 'b':
|
// case 'b':
|
||||||
const binding = message.data.slice(1);
|
// const binding = message.data.slice(1);
|
||||||
//log("Binding: " + binding)
|
// //log("Binding: " + binding)
|
||||||
window.wails._.NewBinding(binding);
|
// window.wails._.NewBinding(binding);
|
||||||
break;
|
// break;
|
||||||
// Call back
|
// // Call back
|
||||||
case 'c':
|
case 'c':
|
||||||
const callbackData = message.data.slice(1);
|
const callbackData = message.data.slice(1);
|
||||||
window.wails._.Callback(callbackData);
|
window.wails._.Callback(callbackData);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
window.wails.Log.Error('Unknown message type received: ' + message.data[0]);
|
window.wailsbridge.log('Unknown message: ' + message.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ function ready(callback) {
|
|||||||
|
|
||||||
// If window.wails exists, we are ready
|
// If window.wails exists, we are ready
|
||||||
if( window.wails ) {
|
if( window.wails ) {
|
||||||
return callback;
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not we need to setup the bridge
|
// If not we need to setup the bridge
|
||||||
|
@ -50,12 +50,20 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
wailsJS := fs.RelativePath("../../../internal/runtime/assets/desktop_" + platform + ".js")
|
wailsJS := fs.RelativePath("../assets/desktop_" + platform + ".js")
|
||||||
runtimeData, err := ioutil.ReadFile(wailsJS)
|
runtimeData, err := ioutil.ReadFile(wailsJS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy this file to bridge directory for embedding
|
||||||
|
bridgeDir := fs.RelativePath("../../bridge/" + platform + ".js")
|
||||||
|
println("Copying", wailsJS, "to", bridgeDir)
|
||||||
|
err = fs.CopyFile(wailsJS, bridgeDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Convert to C structure
|
// Convert to C structure
|
||||||
runtimeC := `
|
runtimeC := `
|
||||||
// runtime.c (c) 2019-Present Lea Anthony.
|
// runtime.c (c) 2019-Present Lea Anthony.
|
||||||
|
Loading…
Reference in New Issue
Block a user