Reworking GUI interaction. Fixed javascript inject. Closes #132
This commit is contained in:
parent
b25126a277
commit
ee84b20247
|
@ -59,7 +59,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
webview.url = "http://etherian.io"
|
webview.url = "/Users/jeffrey/test.html"
|
||||||
}
|
}
|
||||||
|
|
||||||
signal messages(var messages, int id);
|
signal messages(var messages, int id);
|
||||||
|
@ -109,7 +109,8 @@ Rectangle {
|
||||||
leftMargin: 5
|
leftMargin: 5
|
||||||
rightMargin: 5
|
rightMargin: 5
|
||||||
}
|
}
|
||||||
text: "http://etherian.io"
|
//text: "http://etherian.io"
|
||||||
|
text: webview.url;
|
||||||
id: uriNav
|
id: uriNav
|
||||||
y: parent.height / 2 - this.height / 2
|
y: parent.height / 2 - this.height / 2
|
||||||
|
|
||||||
|
@ -151,6 +152,10 @@ Rectangle {
|
||||||
window.open(request.url.toString());
|
window.open(request.url.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function injectJs(js) {
|
||||||
|
experimental.evaluateJavaScript(js)
|
||||||
|
}
|
||||||
|
|
||||||
function sendMessage(data) {
|
function sendMessage(data) {
|
||||||
webview.experimental.postMessage(JSON.stringify(data))
|
webview.experimental.postMessage(JSON.stringify(data))
|
||||||
}
|
}
|
||||||
|
@ -159,8 +164,7 @@ Rectangle {
|
||||||
experimental.preferences.javascriptEnabled: true
|
experimental.preferences.javascriptEnabled: true
|
||||||
experimental.preferences.navigatorQtObjectEnabled: true
|
experimental.preferences.navigatorQtObjectEnabled: true
|
||||||
experimental.preferences.developerExtrasEnabled: true
|
experimental.preferences.developerExtrasEnabled: true
|
||||||
//experimental.userScripts: ["../ext/qt_messaging_adapter.js", "../ext/q.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"]
|
//experimental.userScripts: ["../ext/q.js", "../ext/eth.js/main.js", "../ext/eth.js/qt.js", "../ext/setup.js"]
|
||||||
experimental.userScripts: ["../ext/q.js", "../ext/eth.js/main.js", "../ext/eth.js/qt.js", "../ext/setup.js"]
|
|
||||||
experimental.onMessageReceived: {
|
experimental.onMessageReceived: {
|
||||||
console.log("[onMessageReceived]: ", message.data)
|
console.log("[onMessageReceived]: ", message.data)
|
||||||
// TODO move to messaging.js
|
// TODO move to messaging.js
|
||||||
|
|
|
@ -59,8 +59,8 @@ ApplicationWindow {
|
||||||
|
|
||||||
mainSplit.setView(wallet.view, wallet.menuItem);
|
mainSplit.setView(wallet.view, wallet.menuItem);
|
||||||
|
|
||||||
// Call the ready handler
|
// Command setup
|
||||||
gui.done();
|
gui.sendCommand(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
function addViews(view, path, options) {
|
function addViews(view, path, options) {
|
||||||
|
|
106
cmd/mist/gui.go
106
cmd/mist/gui.go
|
@ -26,7 +26,9 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -48,15 +50,22 @@ import (
|
||||||
|
|
||||||
var guilogger = logger.NewLogger("GUI")
|
var guilogger = logger.NewLogger("GUI")
|
||||||
|
|
||||||
|
type ServEv byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
setup ServEv = iota
|
||||||
|
update
|
||||||
|
)
|
||||||
|
|
||||||
type Gui struct {
|
type Gui struct {
|
||||||
// The main application window
|
// The main application window
|
||||||
win *qml.Window
|
win *qml.Window
|
||||||
// QML Engine
|
// QML Engine
|
||||||
engine *qml.Engine
|
engine *qml.Engine
|
||||||
component *qml.Common
|
component *qml.Common
|
||||||
qmlDone bool
|
|
||||||
// The ethereum interface
|
// The ethereum interface
|
||||||
eth *eth.Ethereum
|
eth *eth.Ethereum
|
||||||
|
serviceEvents chan ServEv
|
||||||
|
|
||||||
// The public Ethereum library
|
// The public Ethereum library
|
||||||
uiLib *UiLib
|
uiLib *UiLib
|
||||||
|
@ -86,7 +95,17 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIden
|
||||||
}
|
}
|
||||||
|
|
||||||
xeth := xeth.NewJSXEth(ethereum)
|
xeth := xeth.NewJSXEth(ethereum)
|
||||||
gui := &Gui{eth: ethereum, txDb: db, xeth: xeth, logLevel: logger.LogLevel(logLevel), Session: session, open: false, clientIdentity: clientIdentity, config: config, plugins: make(map[string]plugin)}
|
gui := &Gui{eth: ethereum,
|
||||||
|
txDb: db,
|
||||||
|
xeth: xeth,
|
||||||
|
logLevel: logger.LogLevel(logLevel),
|
||||||
|
Session: session,
|
||||||
|
open: false,
|
||||||
|
clientIdentity: clientIdentity,
|
||||||
|
config: config,
|
||||||
|
plugins: make(map[string]plugin),
|
||||||
|
serviceEvents: make(chan ServEv, 1),
|
||||||
|
}
|
||||||
data, _ := ethutil.ReadAllFile(path.Join(ethutil.Config.ExecPath, "plugins.json"))
|
data, _ := ethutil.ReadAllFile(path.Join(ethutil.Config.ExecPath, "plugins.json"))
|
||||||
json.Unmarshal([]byte(data), &gui.plugins)
|
json.Unmarshal([]byte(data), &gui.plugins)
|
||||||
|
|
||||||
|
@ -98,6 +117,8 @@ func (gui *Gui) Start(assetPath string) {
|
||||||
|
|
||||||
guilogger.Infoln("Starting GUI")
|
guilogger.Infoln("Starting GUI")
|
||||||
|
|
||||||
|
go gui.service()
|
||||||
|
|
||||||
// Register ethereum functions
|
// Register ethereum functions
|
||||||
qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{
|
qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{
|
||||||
Init: func(p *xeth.JSBlock, obj qml.Object) { p.Number = 0; p.Hash = "" },
|
Init: func(p *xeth.JSBlock, obj qml.Object) { p.Number = 0; p.Hash = "" },
|
||||||
|
@ -154,18 +175,11 @@ func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.win = gui.createWindow(component)
|
gui.createWindow(component)
|
||||||
|
|
||||||
gui.update()
|
|
||||||
|
|
||||||
return gui.win, nil
|
return gui.win, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// The done handler will be called by QML when all views have been loaded
|
|
||||||
func (gui *Gui) Done() {
|
|
||||||
gui.qmlDone = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gui *Gui) ImportKey(filePath string) {
|
func (gui *Gui) ImportKey(filePath string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,10 +193,8 @@ func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) createWindow(comp qml.Object) *qml.Window {
|
func (gui *Gui) createWindow(comp qml.Object) *qml.Window {
|
||||||
win := comp.CreateWindow(nil)
|
gui.win = comp.CreateWindow(nil)
|
||||||
|
gui.uiLib.win = gui.win
|
||||||
gui.win = win
|
|
||||||
gui.uiLib.win = win
|
|
||||||
|
|
||||||
return gui.win
|
return gui.win
|
||||||
}
|
}
|
||||||
|
@ -335,11 +347,48 @@ func (self *Gui) getObjectByName(objectName string) qml.Object {
|
||||||
return self.win.Root().ObjectByName(objectName)
|
return self.win.Root().ObjectByName(objectName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple go routine function that updates the list of peers in the GUI
|
func loadJavascriptAssets(gui *Gui) (jsfiles string) {
|
||||||
func (gui *Gui) update() {
|
for _, fn := range []string{"ext/q.js", "ext/eth.js/main.js", "ext/eth.js/qt.js", "ext/setup.js"} {
|
||||||
// We have to wait for qml to be done loading all the windows.
|
f, err := os.Open(gui.uiLib.AssetPath(fn))
|
||||||
for !gui.qmlDone {
|
if err != nil {
|
||||||
time.Sleep(300 * time.Millisecond)
|
fmt.Println(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := ioutil.ReadAll(f)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
jsfiles += string(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) SendCommand(cmd ServEv) {
|
||||||
|
gui.serviceEvents <- cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) service() {
|
||||||
|
for ev := range gui.serviceEvents {
|
||||||
|
switch ev {
|
||||||
|
case setup:
|
||||||
|
go gui.setup()
|
||||||
|
case update:
|
||||||
|
go gui.update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) setup() {
|
||||||
|
for gui.win == nil {
|
||||||
|
time.Sleep(time.Millisecond * 200)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, plugin := range gui.plugins {
|
||||||
|
guilogger.Infoln("Loading plugin ", plugin.Name)
|
||||||
|
gui.win.Root().Call("addPlugin", plugin.Path, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -349,14 +398,21 @@ func (gui *Gui) update() {
|
||||||
gui.setPeerInfo()
|
gui.setPeerInfo()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
gui.whisper.SetView(gui.win.Root().ObjectByName("whisperView"))
|
// Inject javascript files each time navigation is requested.
|
||||||
|
// Unfortunately webview.experimental.userScripts injects _after_
|
||||||
|
// the page has loaded which kind of renders it useless...
|
||||||
|
jsfiles := loadJavascriptAssets(gui)
|
||||||
|
gui.getObjectByName("webView").On("navigationRequested", func() {
|
||||||
|
gui.getObjectByName("webView").Call("injectJs", jsfiles)
|
||||||
|
})
|
||||||
|
|
||||||
for _, plugin := range gui.plugins {
|
gui.whisper.SetView(gui.getObjectByName("whisperView"))
|
||||||
guilogger.Infoln("Loading plugin ", plugin.Name)
|
|
||||||
|
|
||||||
gui.win.Root().Call("addPlugin", plugin.Path, "")
|
gui.SendCommand(update)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simple go routine function that updates the list of peers in the GUI
|
||||||
|
func (gui *Gui) update() {
|
||||||
peerUpdateTicker := time.NewTicker(5 * time.Second)
|
peerUpdateTicker := time.NewTicker(5 * time.Second)
|
||||||
generalUpdateTicker := time.NewTicker(500 * time.Millisecond)
|
generalUpdateTicker := time.NewTicker(500 * time.Millisecond)
|
||||||
statsUpdateTicker := time.NewTicker(5 * time.Second)
|
statsUpdateTicker := time.NewTicker(5 * time.Second)
|
||||||
|
@ -375,7 +431,6 @@ func (gui *Gui) update() {
|
||||||
core.TxPostEvent{},
|
core.TxPostEvent{},
|
||||||
)
|
)
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer events.Unsubscribe()
|
defer events.Unsubscribe()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@ -445,7 +500,6 @@ func (gui *Gui) update() {
|
||||||
gui.setStatsPane()
|
gui.setStatsPane()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) setStatsPane() {
|
func (gui *Gui) setStatsPane() {
|
||||||
|
|
Loading…
Reference in New Issue