diff options
author | obscuren <geffobscura@gmail.com> | 2015-02-13 22:05:56 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2015-02-13 22:05:56 +0800 |
commit | a5ea21cd85530eee6eb1bb83c37c20d009f11f74 (patch) | |
tree | e5be5bd595139ff7dfbe6261e1e659d8e7dd6f9c /cmd/mist/assets/qml | |
parent | db24fb792cf0dab91bc85e79aecf6758349002a4 (diff) | |
parent | 38faf2c51a1e4a86cda5dfa1b4f7fdae4fd7f58d (diff) | |
download | dexon-a5ea21cd85530eee6eb1bb83c37c20d009f11f74.tar dexon-a5ea21cd85530eee6eb1bb83c37c20d009f11f74.tar.gz dexon-a5ea21cd85530eee6eb1bb83c37c20d009f11f74.tar.bz2 dexon-a5ea21cd85530eee6eb1bb83c37c20d009f11f74.tar.lz dexon-a5ea21cd85530eee6eb1bb83c37c20d009f11f74.tar.xz dexon-a5ea21cd85530eee6eb1bb83c37c20d009f11f74.tar.zst dexon-a5ea21cd85530eee6eb1bb83c37c20d009f11f74.zip |
merge
Diffstat (limited to 'cmd/mist/assets/qml')
25 files changed, 2166 insertions, 1398 deletions
diff --git a/cmd/mist/assets/qml/browser.qml b/cmd/mist/assets/qml/browser.qml deleted file mode 100644 index a89c3c97d..000000000 --- a/cmd/mist/assets/qml/browser.qml +++ /dev/null @@ -1,491 +0,0 @@ -import QtQuick 2.1 -import QtWebKit 3.0 -import QtWebKit.experimental 1.0 -import QtQuick.Controls 1.0; -import QtQuick.Controls.Styles 1.0 -import QtQuick.Layouts 1.0; -import QtQuick.Window 2.1; -import Ethereum 1.0 - -Rectangle { - id: window - objectName: "browserView" - anchors.fill: parent - color: "#00000000" - - property var title: "Browser" - property var iconSource: "../browser.png" - property var menuItem - - property alias url: webview.url - property alias webView: webview - - property var cleanPath: false - property var open: function(url) { - if(!window.cleanPath) { - var uri = url; - if(!/.*\:\/\/.*/.test(uri)) { - uri = "http://" + uri; - } - - var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ - - if(reg.test(uri)) { - uri.replace(reg, function(match, pre, domain, path) { - uri = pre; - - var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4)); - var ip = []; - for(var i = 0, l = lookup.length; i < l; i++) { - ip.push(lookup.charCodeAt(i)) - } - - if(ip.length != 0) { - uri += lookup; - } else { - uri += domain; - } - - uri += path; - }); - } - - window.cleanPath = true; - - webview.url = uri; - - //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2<span style='color:#CCC'>$3</span>"); - uriNav.text = uri; - } else { - // Prevent inf loop. - window.cleanPath = false; - } - } - - Component.onCompleted: { - webview.url = "http://etherian.io" - } - - signal messages(var messages, int id); - onMessages: { - // Bit of a cheat to get proper JSON - var m = JSON.parse(JSON.parse(JSON.stringify(messages))) - webview.postEvent("eth_changed", id, m); - } - - function onShhMessage(message, id) { - webview.postEvent("shh_changed", id, message) - } - - Item { - objectName: "root" - id: root - anchors.fill: parent - state: "inspectorShown" - - RowLayout { - id: navBar - height: 40 - anchors { - left: parent.left - right: parent.right - leftMargin: 7 - } - - Button { - id: back - onClicked: { - webview.goBack() - } - style: ButtonStyle { - background: Image { - source: "../back.png" - width: 30 - height: 30 - } - } - } - - TextField { - anchors { - left: back.right - right: toggleInspector.left - leftMargin: 10 - rightMargin: 10 - } - text: webview.url; - id: uriNav - y: parent.height / 2 - this.height / 2 - - Keys.onReturnPressed: { - webview.url = this.text; - } - } - - Button { - id: toggleInspector - anchors { - right: parent.right - } - iconSource: "../bug.png" - onClicked: { - if(inspector.visible == true){ - inspector.visible = false - }else{ - inspector.visible = true - inspector.url = webview.experimental.remoteInspectorUrl - } - } - } - } - - // Border - Rectangle { - id: divider - anchors { - left: parent.left - right: parent.right - top: navBar.bottom - } - z: -1 - height: 1 - color: "#CCCCCC" - } - - WebView { - objectName: "webView" - id: webview - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - top: divider.bottom - } - - function injectJs(js) { - webview.experimental.navigatorQtObjectEnabled = true; - webview.experimental.evaluateJavaScript(js) - webview.experimental.javascriptEnabled = true; - } - - function sendMessage(data) { - webview.experimental.postMessage(JSON.stringify(data)) - } - - - experimental.preferences.javascriptEnabled: true - experimental.preferences.webGLEnabled: true - experimental.itemSelector: MouseArea { - // To avoid conflicting with ListView.model when inside Initiator context. - property QtObject selectorModel: model - anchors.fill: parent - onClicked: selectorModel.reject() - - Menu { - visible: true - id: itemSelector - - Instantiator { - model: selectorModel.items - delegate: MenuItem { - text: model.text - onTriggered: { - selectorModel.accept(index) - } - } - onObjectAdded: itemSelector.insertItem(index, object) - onObjectRemoved: itemSelector.removeItem(object) - } - } - - Component.onCompleted: { - itemSelector.popup() - } - } - experimental.preferences.webAudioEnabled: true - experimental.preferences.navigatorQtObjectEnabled: true - experimental.preferences.developerExtrasEnabled: true - experimental.userScripts: ["../ext/q.js", "../ext/ethereum.js/lib/web3.js", "../ext/ethereum.js/lib/qt.js", "../ext/setup.js"] - experimental.onMessageReceived: { - console.log("[onMessageReceived]: ", message.data) - // TODO move to messaging.js - var data = JSON.parse(message.data) - - try { - switch(data.call) { - case "eth_compile": - postData(data._id, eth.compile(data.args[0])) - break - - case "eth_coinbase": - postData(data._id, eth.coinBase()) - - case "eth_account": - postData(data._id, eth.key().address); - - case "eth_istening": - postData(data._id, eth.isListening()) - - break - - case "eth_mining": - postData(data._id, eth.isMining()) - - break - - case "eth_peerCount": - postData(data._id, eth.peerCount()) - - break - - case "eth_countAt": - require(1) - postData(data._id, eth.txCountAt(data.args[0])) - - break - - case "eth_codeAt": - require(1) - var code = eth.codeAt(data.args[0]) - postData(data._id, code); - - break - - case "eth_blockByNumber": - require(1) - var block = eth.blockByNumber(data.args[0]) - postData(data._id, block) - break - - case "eth_blockByHash": - require(1) - var block = eth.blockByHash(data.args[0]) - postData(data._id, block) - break - - require(2) - var block = eth.blockByHash(data.args[0]) - postData(data._id, block.transactions[data.args[1]]) - break - - case "eth_transactionByHash": - case "eth_transactionByNumber": - require(2) - - var block; - if (data.call === "transactionByHash") - block = eth.blockByHash(data.args[0]) - else - block = eth.blockByNumber(data.args[0]) - - var tx = block.transactions.get(data.args[1]) - - postData(data._id, tx) - break - - case "eth_uncleByHash": - case "eth_uncleByNumber": - require(2) - - var block; - if (data.call === "uncleByHash") - block = eth.blockByHash(data.args[0]) - else - block = eth.blockByNumber(data.args[0]) - - var uncle = block.uncles.get(data.args[1]) - - postData(data._id, uncle) - - break - - case "transact": - require(5) - - var tx = eth.transact(data.args) - postData(data._id, tx) - - break - - case "eth_stateAt": - require(2); - - var storage = eth.storageAt(data.args[0], data.args[1]); - postData(data._id, storage) - - break - - case "eth_call": - require(1); - var ret = eth.call(data.args) - postData(data._id, ret) - break - - case "eth_balanceAt": - require(1); - - postData(data._id, eth.balanceAt(data.args[0])); - break - - case "eth_watch": - require(2) - eth.watch(data.args[0], data.args[1]) - - case "eth_disconnect": - require(1) - postData(data._id, null) - break; - - case "eth_newFilterString": - require(1) - var id = eth.newFilterString(data.args[0]) - postData(data._id, id); - break; - - case "eth_newFilter": - require(1) - var id = eth.newFilter(data.args[0]) - - postData(data._id, id); - break; - - case "eth_filterLogs": - require(1); - - var messages = eth.messages(data.args[0]); - var m = JSON.parse(JSON.parse(JSON.stringify(messages))) - postData(data._id, m); - - break; - - case "eth_deleteFilter": - require(1); - eth.uninstallFilter(data.args[0]) - break; - - - case "shh_newFilter": - require(1); - var id = shh.watch(data.args[0], window); - postData(data._id, id); - break; - - case "shh_newIdentity": - var id = shh.newIdentity() - postData(data._id, id) - - break - - case "shh_post": - require(1); - - var params = data.args[0]; - var fields = ["payload", "to", "from"]; - for(var i = 0; i < fields.length; i++) { - params[fields[i]] = params[fields[i]] || ""; - } - if(typeof params.payload !== "object") { params.payload = [params.payload]; } //params.payload = params.payload.join(""); } - params.topics = params.topics || []; - params.priority = params.priority || 1000; - params.ttl = params.ttl || 100; - - shh.post(params.payload, params.to, params.from, params.topics, params.priority, params.ttl); - - break; - - case "shh_getMessages": - require(1); - - var m = shh.messages(data.args[0]); - var messages = JSON.parse(JSON.parse(JSON.stringify(m))); - postData(data._id, messages); - - break; - - case "ssh_newGroup": - postData(data._id, ""); - break; - } - } catch(e) { - console.log(data.call + ": " + e) - - postData(data._id, null); - } - } - - - function post(seed, data) { - postData(data._id, data) - } - - function require(args, num) { - if(args.length < num) { - throw("required argument count of "+num+" got "+args.length); - } - } - function postData(seed, data) { - webview.experimental.postMessage(JSON.stringify({data: data, _id: seed})) - } - function postEvent(event, id, data) { - webview.experimental.postMessage(JSON.stringify({data: data, _id: id, _event: event})) - } - - function onWatchedCb(data, id) { - var messages = JSON.parse(data) - postEvent("watched:"+id, messages) - } - - function onNewBlockCb(block) { - postEvent("block:new", block) - } - function onObjectChangeCb(stateObject) { - postEvent("object:"+stateObject.address(), stateObject) - } - function onStorageChangeCb(storageObject) { - var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":"); - postEvent(ev, [storageObject.address, storageObject.value]) - } - } - - - Rectangle { - id: sizeGrip - color: "gray" - visible: false - height: 10 - anchors { - left: root.left - right: root.right - } - y: Math.round(root.height * 2 / 3) - - MouseArea { - anchors.fill: parent - drag.target: sizeGrip - drag.minimumY: 0 - drag.maximumY: root.height - drag.axis: Drag.YAxis - } - } - - WebView { - id: inspector - visible: false - anchors { - left: root.left - right: root.right - top: sizeGrip.bottom - bottom: root.bottom - } - } - - states: [ - State { - name: "inspectorShown" - PropertyChanges { - target: inspector - } - } - ] - } -} diff --git a/cmd/mist/assets/qml/depricated_browser.qml b/cmd/mist/assets/qml/depricated_browser.qml new file mode 100644 index 000000000..7056dbbf3 --- /dev/null +++ b/cmd/mist/assets/qml/depricated_browser.qml @@ -0,0 +1,486 @@ +import QtQuick 2.1 +import QtWebKit 3.0 +import QtWebKit.experimental 1.0 +import QtQuick.Controls 1.0; +import QtQuick.Controls.Styles 1.0 +import QtQuick.Layouts 1.0; +import QtQuick.Window 2.1; +import Ethereum 1.0 + +Rectangle { + id: window + anchors.fill: parent + color: "#00000000" + + property var title: "DApps" + property var iconSource: "../browser.png" + property var menuItem + property var hideUrl: true + + property alias url: webview.url + property alias windowTitle: webview.title + property alias webView: webview + + property var cleanPath: false + property var open: function(url) { + if(!window.cleanPath) { + var uri = url; + if(!/.*\:\/\/.*/.test(uri)) { + uri = "http://" + uri; + } + + var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ + + if(reg.test(uri)) { + uri.replace(reg, function(match, pre, domain, path) { + uri = pre; + + var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4)); + var ip = []; + for(var i = 0, l = lookup.length; i < l; i++) { + ip.push(lookup.charCodeAt(i)) + } + + if(ip.length != 0) { + uri += lookup; + } else { + uri += domain; + } + + uri += path; + }); + } + + window.cleanPath = true; + + webview.url = uri; + + //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2<span style='color:#CCC'>$3</span>"); + uriNav.text = uri; + } else { + // Prevent inf loop. + window.cleanPath = false; + } + } + + Component.onCompleted: { + webview.url = "http://etherian.io" + } + + function messages(messages, id) { + // Bit of a cheat to get proper JSON + var m = JSON.parse(JSON.parse(JSON.stringify(messages))) + webview.postEvent("eth_changed", id, m); + } + + function onShhMessage(message, id) { + webview.postEvent("shh_changed", id, message) + } + + Item { + objectName: "root" + id: root + anchors.fill: parent + state: "inspectorShown" + + RowLayout { + id: navBar + height: 40 + anchors { + left: parent.left + right: parent.right + leftMargin: 7 + } + + Button { + id: back + onClicked: { + webview.goBack() + } + style: ButtonStyle { + background: Image { + source: "../back.png" + width: 30 + height: 30 + } + } + } + + TextField { + anchors { + left: back.right + right: toggleInspector.left + leftMargin: 10 + rightMargin: 10 + } + text: webview.url; + id: uriNav + y: parent.height / 2 - this.height / 2 + + Keys.onReturnPressed: { + webview.url = this.text; + } + } + + Button { + id: toggleInspector + anchors { + right: parent.right + } + iconSource: "../bug.png" + onClicked: { + if(inspector.visible == true){ + inspector.visible = false + }else{ + inspector.visible = true + inspector.url = webview.experimental.remoteInspectorUrl + } + } + } + } + + // Border + Rectangle { + id: divider + anchors { + left: parent.left + right: parent.right + top: navBar.bottom + } + z: -1 + height: 1 + color: "#CCCCCC" + } + + ScrollView { + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + top: divider.bottom + } + WebView { + objectName: "webView" + id: webview + anchors.fill: parent + + function sendMessage(data) { + webview.experimental.postMessage(JSON.stringify(data)) + } + + experimental.preferences.javascriptEnabled: true + experimental.preferences.webAudioEnabled: true + experimental.preferences.pluginsEnabled: true + experimental.preferences.navigatorQtObjectEnabled: true + experimental.preferences.developerExtrasEnabled: true + experimental.preferences.webGLEnabled: true + experimental.preferences.notificationsEnabled: true + experimental.preferences.localStorageEnabled: true + experimental.userAgent:"Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Mist/0.1 Safari/537.36" + + experimental.itemSelector: MouseArea { + // To avoid conflicting with ListView.model when inside Initiator context. + property QtObject selectorModel: model + anchors.fill: parent + onClicked: selectorModel.reject() + + Menu { + visible: true + id: itemSelector + + Instantiator { + model: selectorModel.items + delegate: MenuItem { + text: model.text + onTriggered: { + selectorModel.accept(index) + } + } + onObjectAdded: itemSelector.insertItem(index, object) + onObjectRemoved: itemSelector.removeItem(object) + } + } + + Component.onCompleted: { + itemSelector.popup() + } + } + experimental.userScripts: ["../ext/q.js", "../ext/ethereum.js/lib/web3.js", "../ext/ethereum.js/lib/qt.js", "../ext/setup.js"] + experimental.onMessageReceived: { + //console.log("[onMessageReceived]: ", message.data) + var data = JSON.parse(message.data) + + try { + switch(data.call) { + case "eth_compile": + postData(data._id, eth.compile(data.args[0])) + break + + case "eth_coinbase": + postData(data._id, eth.coinBase()) + + case "eth_account": + postData(data._id, eth.key().address); + + case "eth_istening": + postData(data._id, eth.isListening()) + + break + + case "eth_mining": + postData(data._id, eth.isMining()) + + break + + case "eth_peerCount": + postData(data._id, eth.peerCount()) + + break + + case "eth_countAt": + require(1) + postData(data._id, eth.txCountAt(data.args[0])) + + break + + case "eth_codeAt": + require(1) + var code = eth.codeAt(data.args[0]) + postData(data._id, code); + + break + + case "eth_blockByNumber": + require(1) + var block = eth.blockByNumber(data.args[0]) + postData(data._id, block) + break + + case "eth_blockByHash": + require(1) + var block = eth.blockByHash(data.args[0]) + postData(data._id, block) + break + + require(2) + var block = eth.blockByHash(data.args[0]) + postData(data._id, block.transactions[data.args[1]]) + break + + case "eth_transactionByHash": + case "eth_transactionByNumber": + require(2) + + var block; + if (data.call === "transactionByHash") + block = eth.blockByHash(data.args[0]) + else + block = eth.blockByNumber(data.args[0]) + + var tx = block.transactions.get(data.args[1]) + + postData(data._id, tx) + break + + case "eth_uncleByHash": + case "eth_uncleByNumber": + require(2) + + var block; + if (data.call === "uncleByHash") + block = eth.blockByHash(data.args[0]) + else + block = eth.blockByNumber(data.args[0]) + + var uncle = block.uncles.get(data.args[1]) + + postData(data._id, uncle) + + break + + case "transact": + require(5) + + var tx = eth.transact(data.args) + postData(data._id, tx) + + break + + case "eth_stateAt": + require(2); + + var storage = eth.storageAt(data.args[0], data.args[1]); + postData(data._id, storage) + + break + + case "eth_call": + require(1); + var ret = eth.call(data.args) + postData(data._id, ret) + break + + case "eth_balanceAt": + require(1); + + postData(data._id, eth.balanceAt(data.args[0])); + break + + case "eth_watch": + require(2) + eth.watch(data.args[0], data.args[1]) + + case "eth_disconnect": + require(1) + postData(data._id, null) + break; + + case "eth_newFilterString": + require(1) + var id = eth.newFilterString(data.args[0], window) + postData(data._id, id); + break; + + case "eth_newFilter": + require(1) + var id = eth.newFilter(data.args[0], window) + + postData(data._id, id); + break; + + case "eth_filterLogs": + require(1); + + var messages = eth.messages(data.args[0]); + var m = JSON.parse(JSON.parse(JSON.stringify(messages))) + postData(data._id, m); + + break; + + case "eth_deleteFilter": + require(1); + eth.uninstallFilter(data.args[0]) + break; + + + case "shh_newFilter": + require(1); + var id = shh.watch(data.args[0], window); + postData(data._id, id); + break; + + case "shh_newIdentity": + var id = shh.newIdentity() + postData(data._id, id) + + break + + case "shh_post": + require(1); + + var params = data.args[0]; + var fields = ["payload", "to", "from"]; + for(var i = 0; i < fields.length; i++) { + params[fields[i]] = params[fields[i]] || ""; + } + if(typeof params.payload !== "object") { params.payload = [params.payload]; } //params.payload = params.payload.join(""); } + params.topics = params.topics || []; + params.priority = params.priority || 1000; + params.ttl = params.ttl || 100; + + shh.post(params.payload, params.to, params.from, params.topics, params.priority, params.ttl); + + break; + + case "shh_getMessages": + require(1); + + var m = shh.messages(data.args[0]); + var messages = JSON.parse(JSON.parse(JSON.stringify(m))); + postData(data._id, messages); + + break; + + case "ssh_newGroup": + postData(data._id, ""); + break; + } + } catch(e) { + console.log(data.call + ": " + e) + + postData(data._id, null); + } + } + + function post(seed, data) { + postData(data._id, data) + } + function require(args, num) { + if(args.length < num) { + throw("required argument count of "+num+" got "+args.length); + } + } + function postData(seed, data) { + webview.experimental.postMessage(JSON.stringify({data: data, _id: seed})) + } + function postEvent(event, id, data) { + webview.experimental.postMessage(JSON.stringify({data: data, _id: id, _event: event})) + } + function onWatchedCb(data, id) { + var messages = JSON.parse(data) + postEvent("watched:"+id, messages) + } + function onNewBlockCb(block) { + postEvent("block:new", block) + } + function onObjectChangeCb(stateObject) { + postEvent("object:"+stateObject.address(), stateObject) + } + function onStorageChangeCb(storageObject) { + var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":"); + postEvent(ev, [storageObject.address, storageObject.value]) + } + } + } + + Rectangle { + id: sizeGrip + color: "gray" + visible: false + height: 10 + anchors { + left: root.left + right: root.right + } + y: Math.round(root.height * 2 / 3) + + MouseArea { + anchors.fill: parent + drag.target: sizeGrip + drag.minimumY: 0 + drag.maximumY: root.height + drag.axis: Drag.YAxis + } + } + + WebView { + id: inspector + visible: false + anchors { + left: root.left + right: root.right + top: sizeGrip.bottom + bottom: root.bottom + } + } + + states: [ + State { + name: "inspectorShown" + PropertyChanges { + target: inspector + } + } + ] + } +} diff --git a/cmd/mist/assets/qml/fonts/Simple-Line-Icons.ttf b/cmd/mist/assets/qml/fonts/Simple-Line-Icons.ttf Binary files differnew file mode 100755 index 000000000..2194f1f87 --- /dev/null +++ b/cmd/mist/assets/qml/fonts/Simple-Line-Icons.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-Black.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-Black.ttf Binary files differnew file mode 100644 index 000000000..be1a3108e --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-Black.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-BlackIt.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-BlackIt.ttf Binary files differnew file mode 100644 index 000000000..ac5c4ef7c --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-BlackIt.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-Bold.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-Bold.ttf Binary files differnew file mode 100644 index 000000000..f47161c6b --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-Bold.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-BoldIt.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-BoldIt.ttf Binary files differnew file mode 100644 index 000000000..6b3db698b --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-BoldIt.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-ExtraLight.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-ExtraLight.ttf Binary files differnew file mode 100644 index 000000000..0a3e51fdb --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-ExtraLight.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-ExtraLightIt.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-ExtraLightIt.ttf Binary files differnew file mode 100644 index 000000000..a0eb86aca --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-ExtraLightIt.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-It.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-It.ttf Binary files differnew file mode 100644 index 000000000..fcc95fc7c --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-It.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-Light.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-Light.ttf Binary files differnew file mode 100644 index 000000000..9cae13c97 --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-Light.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-LightIt.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-LightIt.ttf Binary files differnew file mode 100644 index 000000000..2ed784284 --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-LightIt.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-Regular.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-Regular.ttf Binary files differnew file mode 100644 index 000000000..8e8255e17 --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-Regular.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-Semibold.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-Semibold.ttf Binary files differnew file mode 100644 index 000000000..121ee9bbf --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-Semibold.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSansPro-SemiboldIt.ttf b/cmd/mist/assets/qml/fonts/SourceSansPro-SemiboldIt.ttf Binary files differnew file mode 100644 index 000000000..6ceaa885f --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSansPro-SemiboldIt.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSerifPro-Bold.ttf b/cmd/mist/assets/qml/fonts/SourceSerifPro-Bold.ttf Binary files differnew file mode 100644 index 000000000..ac7837fd9 --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSerifPro-Bold.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSerifPro-Regular.ttf b/cmd/mist/assets/qml/fonts/SourceSerifPro-Regular.ttf Binary files differnew file mode 100644 index 000000000..7201a8890 --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSerifPro-Regular.ttf diff --git a/cmd/mist/assets/qml/fonts/SourceSerifPro-Semibold.ttf b/cmd/mist/assets/qml/fonts/SourceSerifPro-Semibold.ttf Binary files differnew file mode 100644 index 000000000..db2fc804b --- /dev/null +++ b/cmd/mist/assets/qml/fonts/SourceSerifPro-Semibold.ttf diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index 7b207cbcc..2b56b7236 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -9,897 +9,1096 @@ import Ethereum 1.0 import "../ext/filter.js" as Eth import "../ext/http.js" as Http + ApplicationWindow { - id: root - - property var ethx : Eth.ethx - property var browser - - width: 1200 - height: 820 - minimumHeight: 300 - - title: "Mist" - - // This signal is used by the filter API. The filter API connects using this signal handler from - // the different QML files and plugins. - signal messages(var messages, int id); - function invokeFilterCallback(data, receiverSeed) { - //var messages = JSON.parse(data) - // Signal handler - messages(data, receiverSeed); - root.browser.view.messages(data, receiverSeed); - } - - TextField { - id: copyElementHax - visible: false - } - - function copyToClipboard(text) { - copyElementHax.text = text - copyElementHax.selectAll() - copyElementHax.copy() - } - - // Takes care of loading all default plugins - Component.onCompleted: { - var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true}); - var browser = addPlugin("./browser.qml", {noAdd: true, close: false, section: "ethereum", active: true}); - root.browser = browser; - addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true}); - - addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"}); - addPlugin("./views/whisper.qml", {noAdd: true, close: false, section: "legacy"}); - addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"}); - addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"}); - addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"}); - - addPlugin("./views/jeffcoin/jeffcoin.qml", {noAdd: true, close: false, section: "apps"}) - - mainSplit.setView(wallet.view, wallet.menuItem); - - // Command setup - gui.sendCommand(0) - } - - function activeView(view, menuItem) { - mainSplit.setView(view, menuItem) - if (view.objectName === "browserView") { - urlPane.visible = false; - mainView.anchors.top = rootView.top - } else { - urlPane.visible = true; - mainView.anchors.top = divider.bottom - } - } - - function addViews(view, path, options) { - var views = mainSplit.addComponent(view, options) - views.menuItem.path = path - - mainSplit.views.push(views); - - if(!options.noAdd) { - gui.addPlugin(path) - } - - return views - } - - function addPlugin(path, options) { - try { - if(typeof(path) === "string" && /^https?/.test(path)) { - console.log('load http') - Http.request(path, function(o) { - if(o.status === 200) { - var view = Qt.createQmlObject(o.responseText, mainView, path) - addViews(view, path, options) - } - }) - - return - } - - var component = Qt.createComponent(path); - if(component.status != Component.Ready) { - if(component.status == Component.Error) { - ethx.note("error: ", component.errorString()); - } - - return - } - - var view = mainView.createView(component, options) - var views = addViews(view, path, options) - - return views - } catch(e) { - ethx.note(e) - } - } - - menuBar: MenuBar { - Menu { - title: "File" - MenuItem { - text: "Import App" - shortcut: "Ctrl+o" - onTriggered: { - generalFileDialog.show(true, importApp) - } - } - - /* - MenuItem { - text: "Browser" - onTriggered: eth.openBrowser() - } - */ - - MenuItem { - text: "Add plugin" - onTriggered: { - generalFileDialog.show(true, function(path) { - addPlugin(path, {close: true, section: "apps"}) - }) - } - } - - MenuSeparator {} - - MenuItem { - text: "Import key" - shortcut: "Ctrl+i" - onTriggered: { - generalFileDialog.show(true, function(path) { - gui.importKey(path) - }) - } - } - - MenuItem { - text: "Export keys" - shortcut: "Ctrl+e" - onTriggered: { - generalFileDialog.show(false, function(path) { - }) - } - } - - } - - Menu { - title: "Developer" - MenuItem { - iconSource: "../icecream.png" - text: "Debugger" - shortcut: "Ctrl+d" - onTriggered: eth.startDebugger() - } - - MenuItem { - text: "Import Tx" - onTriggered: { - txImportDialog.visible = true - } - } - - MenuItem { - text: "Run JS file" - onTriggered: { - generalFileDialog.show(true, function(path) { - eth.evalJavascriptFile(path) - }) - } - } - - MenuItem { - text: "Dump state" - onTriggered: { - generalFileDialog.show(false, function(path) { - // Empty hash for latest - gui.dumpState("", path) - }) - } - } - - MenuSeparator {} - - /* - MenuItem { - id: miningSpeed - text: "Mining: Turbo" - onTriggered: { - gui.toggleTurboMining() - if(text == "Mining: Turbo") { - text = "Mining: Normal"; - } else { - text = "Mining: Turbo"; - } - } - } - */ - } - - Menu { - title: "Network" - MenuItem { - text: "Add Peer" - shortcut: "Ctrl+p" - onTriggered: { - addPeerWin.visible = true - } - } - MenuItem { - text: "Show Peers" - shortcut: "Ctrl+e" - onTriggered: { - peerWindow.visible = true - } - } - } - - Menu { - title: "Help" - MenuItem { - text: "About" - onTriggered: { - aboutWin.visible = true - } - } - } - - Menu { - title: "GLOBAL SHORTCUTS" - visible: false - MenuItem { - visible: false - shortcut: "Ctrl+l" - onTriggered: { - url.focus = true - } - } - } - } - - statusBar: StatusBar { - //height: 32 - id: statusBar - Label { - //y: 6 - id: walletValueLabel - - font.pixelSize: 10 - styleColor: "#797979" - } - - Label { - //y: 6 - objectName: "miningLabel" - visible: true - font.pixelSize: 10 - anchors.right: lastBlockLabel.left - anchors.rightMargin: 5 - } - - Label { - //y: 6 - id: lastBlockLabel - objectName: "lastBlockLabel" - visible: true - text: "" - font.pixelSize: 10 - anchors.right: peerGroup.left - anchors.rightMargin: 5 - } - - ProgressBar { - visible: false - id: downloadIndicator - value: 0 - objectName: "downloadIndicator" - y: -4 - x: statusBar.width / 2 - this.width / 2 - width: 160 - } - - Label { - visible: false - objectName: "downloadLabel" - //y: 7 - anchors.left: downloadIndicator.right - anchors.leftMargin: 5 - font.pixelSize: 10 - text: "0 / 0" - } - - - RowLayout { - id: peerGroup - //y: 7 - anchors.right: parent.right - MouseArea { - onDoubleClicked: peerWindow.visible = true - anchors.fill: parent - } - - Label { - id: peerLabel - font.pixelSize: 10 - text: "0 / 0" - } - } - } - - - property var blockModel: ListModel { - id: blockModel - } - - SplitView { - property var views: []; - - id: mainSplit - anchors.fill: parent - resizing: false - - function setView(view, menu) { - for(var i = 0; i < views.length; i++) { - views[i].view.visible = false - views[i].menuItem.setSelection(false) - } - view.visible = true - - //menu.border.color = "#CCCCCC" - //menu.color = "#FFFFFFFF" - menu.setSelection(true) - } - - function addComponent(view, options) { - view.visible = false - view.anchors.fill = mainView - - var menuItem = menu.createMenuItem(view, options); - if( view.hasOwnProperty("menuItem") ) { - view.menuItem = menuItem; - } - - if( view.hasOwnProperty("onReady") ) { - view.onReady.call(view) - } - - if( options.active ) { - setView(view, menuItem) - } - - - return {view: view, menuItem: menuItem} - } - - /********************* - * Main menu. - ********************/ - Rectangle { - id: menu - Layout.minimumWidth: 210 - Layout.maximumWidth: 210 - anchors.top: parent.top - color: "#ececec" - - Component { - id: menuItemTemplate - Rectangle { - id: menuItem - property var view; - property var path; - property var closable; - - property alias title: label.text - property alias icon: icon.source - property alias secondaryTitle: secondary.text - function setSelection(on) { - sel.visible = on - } - - width: 206 - height: 28 - color: "#00000000" - - anchors { - left: parent.left - leftMargin: 4 - } - - Rectangle { - id: sel - visible: false - anchors.fill: parent - color: "#00000000" - Rectangle { - id: r - anchors.fill: parent - border.color: "#CCCCCC" - border.width: 1 - radius: 5 - color: "#FFFFFFFF" - } - Rectangle { - anchors { - top: r.top - bottom: r.bottom - right: r.right - } - width: 10 - color: "#FFFFFFFF" - - Rectangle { - anchors { - left: parent.left - right: parent.right - top: parent.top - } - height: 1 - color: "#CCCCCC" - } - - Rectangle { - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - } - height: 1 - color: "#CCCCCC" - } - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - activeView(view, menuItem); - } - } - - Image { - id: icon - height: 20 - width: 20 - anchors { - left: parent.left - verticalCenter: parent.verticalCenter - leftMargin: 3 - } - MouseArea { - anchors.fill: parent - onClicked: { - menuItem.closeApp() - } - } - } - - Text { - id: label - anchors { - left: icon.right - verticalCenter: parent.verticalCenter - leftMargin: 3 - } - - color: "#0D0A01" - font.pixelSize: 12 - } - - Text { - id: secondary - anchors { - right: parent.right - rightMargin: 8 - verticalCenter: parent.verticalCenter - } - color: "#AEADBE" - font.pixelSize: 12 - } - - - function closeApp() { - if(!this.closable) { return; } - - if(this.view.hasOwnProperty("onDestroy")) { - this.view.onDestroy.call(this.view) - } - - this.view.destroy() - this.destroy() - gui.removePlugin(this.path) - } - } - } - - function createMenuItem(view, options) { - if(options === undefined) { - options = {}; - } - - var section; - switch(options.section) { - case "ethereum": - section = menuDefault; - break; - case "legacy": - section = menuLegacy; - break; - default: - section = menuApps; - break; - } - - var comp = menuItemTemplate.createObject(section) - comp.view = view - comp.title = view.title - - if(view.hasOwnProperty("iconSource")) { - comp.icon = view.iconSource; - } - comp.closable = options.close; - - return comp - } - - ColumnLayout { - id: menuColumn - y: 10 - width: parent.width - anchors.left: parent.left - anchors.right: parent.right - spacing: 3 - - Text { - text: "ETHEREUM" - font.bold: true - anchors { - left: parent.left - leftMargin: 5 - } - color: "#888888" - } - - ColumnLayout { - id: menuDefault - spacing: 3 - anchors { - left: parent.left - right: parent.right - } - } - - - Text { - text: "APPS" - font.bold: true - anchors { - left: parent.left - leftMargin: 5 - } - color: "#888888" - } - - ColumnLayout { - id: menuApps - spacing: 3 - anchors { - left: parent.left - right: parent.right - } - } - - Text { - text: "DEBUG" - font.bold: true - anchors { - left: parent.left - leftMargin: 5 - } - color: "#888888" - } - - ColumnLayout { - id: menuLegacy - spacing: 3 - anchors { - left: parent.left - right: parent.right - } - } - } - } - - /********************* - * Main view - ********************/ - Rectangle { - id: rootView - anchors.right: parent.right - anchors.left: menu.right - anchors.bottom: parent.bottom - anchors.top: parent.top - color: "#00000000" - - Rectangle { - id: urlPane - height: 40 - color: "#00000000" - anchors { - left: parent.left - right: parent.right - leftMargin: 5 - rightMargin: 5 - top: parent.top - topMargin: 5 - } - TextField { - id: url - objectName: "url" - placeholderText: "DApp URL" - anchors { - left: parent.left - right: parent.right - top: parent.top - topMargin: 5 - rightMargin: 5 - leftMargin: 5 - } - - Keys.onReturnPressed: { - if(/^https?/.test(this.text)) { - activeView(root.browser.view, root.browser.menuItem); - } else { - addPlugin(this.text, {close: true, section: "apps"}) - } - } - } - - } - - // Border - Rectangle { - id: divider - anchors { - left: parent.left - right: parent.right - top: urlPane.bottom - } - z: -1 - height: 1 - color: "#CCCCCC" - } - - Rectangle { - id: mainView - color: "#00000000" - anchors.right: parent.right - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.top: divider.bottom - - function createView(component) { - var view = component.createObject(mainView) - - return view; - } - } - } - } - - - /****************** - * Dialogs - *****************/ - FileDialog { - id: generalFileDialog - property var callback; - onAccepted: { - var path = this.fileUrl.toString(); - callback.call(this, path); - } - - function show(selectExisting, callback) { - generalFileDialog.callback = callback; - generalFileDialog.selectExisting = selectExisting; - - this.open(); - } - } - - - /****************** - * Wallet functions - *****************/ - function importApp(path) { - var ext = path.split('.').pop() - if(ext == "html" || ext == "htm") { - eth.openHtml(path) - }else if(ext == "qml"){ - addPlugin(path, {close: true, section: "apps"}) - } - } - - - function setWalletValue(value) { - walletValueLabel.text = value - } - - function loadPlugin(name) { - console.log("Loading plugin" + name) - var view = mainView.addPlugin(name) - } - - function setPeers(text) { - peerLabel.text = text - } - - function addPeer(peer) { - // We could just append the whole peer object but it cries if you try to alter them - peerModel.append({ip: peer.ip, port: peer.port, lastResponse:timeAgo(peer.lastSend), latency: peer.latency, version: peer.version, caps: peer.caps}) - } - - function resetPeers(){ - peerModel.clear() - } - - function timeAgo(unixTs){ - var lapsed = (Date.now() - new Date(unixTs*1000)) / 1000 - return (lapsed + " seconds ago") - } - - function convertToPretty(unixTs){ - var a = new Date(unixTs*1000); - var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; - var year = a.getFullYear(); - var month = months[a.getMonth()]; - var date = a.getDate(); - var hour = a.getHours(); - var min = a.getMinutes(); - var sec = a.getSeconds(); - var time = date+' '+month+' '+year+' '+hour+':'+min+':'+sec ; - return time; - } - - /********************** - * Windows - *********************/ - Window { - id: peerWindow - //flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint - height: 200 - width: 700 - Rectangle { - anchors.fill: parent - property var peerModel: ListModel { - id: peerModel - } - TableView { - anchors.fill: parent - id: peerTable - model: peerModel - TableViewColumn{width: 200; role: "ip" ; title: "IP" } - TableViewColumn{width: 260; role: "version" ; title: "Version" } - TableViewColumn{width: 180; role: "caps" ; title: "Capabilities" } - } - } - } - - Window { - id: aboutWin - visible: false - title: "About" - minimumWidth: 350 - maximumWidth: 350 - maximumHeight: 280 - minimumHeight: 280 - - Image { - id: aboutIcon - height: 150 - width: 150 - fillMode: Image.PreserveAspectFit - smooth: true - source: "../facet.png" - x: 10 - y: 30 - } - - Text { - anchors.left: aboutIcon.right - anchors.leftMargin: 10 - anchors.top: parent.top - anchors.topMargin: 30 - font.pointSize: 12 - text: "<h2>Mist (0.7.10)</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor TrĂ³n<br>Felix Lange<br>Taylor Gerring<br>Daniel Nagy<br><h3>UX</h3>Alex van de Sande<br>" - } - } - - Window { - id: txImportDialog - minimumWidth: 270 - maximumWidth: 270 - maximumHeight: 50 - minimumHeight: 50 - TextField { - id: txImportField - width: 170 - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: 10 - onAccepted: { - } - } - Button { - anchors.left: txImportField.right - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: 5 - text: "Import" - onClicked: { - eth.importTx(txImportField.text) - txImportField.visible = false - } - } - Component.onCompleted: { - addrField.focus = true - } - } - - Window { - id: addPeerWin - visible: false - minimumWidth: 300 - maximumWidth: 300 - maximumHeight: 50 - minimumHeight: 50 - title: "Connect to peer" - - ComboBox { - id: addrField - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.right: addPeerButton.left - anchors.leftMargin: 10 - anchors.rightMargin: 10 - onAccepted: { - eth.connectToPeer(addrField.currentText) - addPeerWin.visible = false - } - - editable: true - model: ListModel { id: pastPeers } - - Component.onCompleted: { - pastPeers.insert(0, {text: "poc-8.ethdev.com:30303"}) - /* - var ips = eth.pastPeers() - for(var i = 0; i < ips.length; i++) { - pastPeers.append({text: ips.get(i)}) - } - - pastPeers.insert(0, {text: "poc-7.ethdev.com:30303"}) - */ - } - } - - Button { - id: addPeerButton - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.rightMargin: 10 - text: "Add" - onClicked: { - eth.connectToPeer(addrField.currentText) - addPeerWin.visible = false - } - } - Component.onCompleted: { - addrField.focus = true - } - } - } + id: root + + //flags: Qt.FramelessWindowHint + // Use this to make the window frameless. But then you'll need to do move and resize by hand + + property var ethx : Eth.ethx + property var catalog; + + width: 1200 + height: 820 + minimumHeight: 600 + minimumWidth: 800 + + title: "Mist" + + TextField { + id: copyElementHax + visible: false + } + + function copyToClipboard(text) { + copyElementHax.text = text + copyElementHax.selectAll() + copyElementHax.copy() + } + + // Takes care of loading all default plugins + Component.onCompleted: { + + catalog = addPlugin("./views/catalog.qml", {noAdd: true, close: false, section: "begin"}); + var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true}); + + addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true}); + addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"}); + addPlugin("./views/whisper.qml", {noAdd: true, close: false, section: "legacy"}); + addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"}); + addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"}); + addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"}); + + mainSplit.setView(catalog.view, catalog.menuItem); + + //newBrowserTab("http://ethereum-dapp-catalog.meteor.com"); + + // Command setup + gui.sendCommand(0) + } + + function activeView(view, menuItem) { + mainSplit.setView(view, menuItem) + if (view.hideUrl) { + urlPane.visible = false; + mainView.anchors.top = rootView.top + } else { + urlPane.visible = true; + mainView.anchors.top = divider.bottom + } + } + + function addViews(view, path, options) { + var views = mainSplit.addComponent(view, options) + views.menuItem.path = path + + mainSplit.views.push(views); + + if(!options.noAdd) { + gui.addPlugin(path) + } + + return views + } + + function addPlugin(path, options) { + try { + if(typeof(path) === "string" && /^https?/.test(path)) { + console.log('load http') + Http.request(path, function(o) { + if(o.status === 200) { + var view = Qt.createQmlObject(o.responseText, mainView, path) + addViews(view, path, options) + } + }) + + return + } + + var component = Qt.createComponent(path); + if(component.status != Component.Ready) { + if(component.status == Component.Error) { + ethx.note("error: ", component.errorString()); + } + + return + } + + var view = mainView.createView(component, options) + var views = addViews(view, path, options) + + return views + } catch(e) { + console.log(e) + } + } + + function newBrowserTab(url) { + + var urlMatches = url.toString().match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); + var requestedDomain = urlMatches && urlMatches[1]; + + var domainAlreadyOpen = false; + + console.log("requested: " + requestedDomain ) + + for(var i = 0; i < mainSplit.views.length; i++) { + if (mainSplit.views[i].view.url) { + var matches = mainSplit.views[i].view.url.toString().match(/^[a-z]*\:\/\/(?:www\.)?([^\/?#]+)(?:[\/?#]|$)/i); + var existingDomain = matches && matches[1]; + console.log("exists: " + existingDomain); + if (requestedDomain == existingDomain) { + domainAlreadyOpen = true; + mainSplit.views[i].view.url = url; + activeView(mainSplit.views[i].view, mainSplit.views[i].menuItem); + } + } + } + + if (!domainAlreadyOpen) { + var window = addPlugin("./views/browser.qml", {noAdd: true, close: true, section: "apps", active: true}); + window.view.url = url; + window.menuItem.title = "Mist"; + activeView(window.view, window.menuItem); + } + } + + + + menuBar: MenuBar { + Menu { + title: "File" + MenuItem { + text: "Import App" + shortcut: "Ctrl+o" + onTriggered: { + generalFileDialog.show(true, importApp) + } + } + + MenuItem { + text: "Add plugin" + onTriggered: { + generalFileDialog.show(true, function(path) { + addPlugin(path, {close: true, section: "apps"}) + }) + } + } + + MenuItem { + text: "New tab" + shortcut: "Ctrl+t" + onTriggered: { + activeView(catalog.view, catalog.menuItem); + } + } + + MenuSeparator {} + + MenuItem { + text: "Import key" + shortcut: "Ctrl+i" + onTriggered: { + generalFileDialog.show(true, function(path) { + gui.importKey(path) + }) + } + } + + MenuItem { + text: "Export keys" + shortcut: "Ctrl+e" + onTriggered: { + generalFileDialog.show(false, function(path) { + }) + } + } + + } + + Menu { + title: "Developer" + MenuItem { + iconSource: "../icecream.png" + text: "Debugger" + shortcut: "Ctrl+d" + onTriggered: eth.startDebugger() + } + + MenuItem { + text: "Import Tx" + onTriggered: { + txImportDialog.visible = true + } + } + + MenuItem { + text: "Run JS file" + onTriggered: { + generalFileDialog.show(true, function(path) { + eth.evalJavascriptFile(path) + }) + } + } + + MenuItem { + text: "Dump state" + onTriggered: { + generalFileDialog.show(false, function(path) { + // Empty hash for latest + gui.dumpState("", path) + }) + } + } + + MenuSeparator {} + } + + Menu { + title: "Network" + MenuItem { + text: "Add Peer" + shortcut: "Ctrl+p" + onTriggered: { + addPeerWin.visible = true + } + } + MenuItem { + text: "Show Peers" + shortcut: "Ctrl+e" + onTriggered: { + peerWindow.visible = true + } + } + } + + Menu { + title: "Help" + MenuItem { + text: "About" + onTriggered: { + aboutWin.visible = true + } + } + } + + Menu { + title: "GLOBAL SHORTCUTS" + visible: false + MenuItem { + visible: false + shortcut: "Ctrl+l" + onTriggered: { + url.focus = true + } + } + } + } + + statusBar: StatusBar { + //height: 32 + visible: false + + id: statusBar + Label { + //y: 6 + id: walletValueLabel + + font.pixelSize: 10 + styleColor: "#797979" + } + + Label { + //y: 6 + objectName: "miningLabel" + visible: true + font.pixelSize: 10 + anchors.right: lastBlockLabel.left + anchors.rightMargin: 5 + } + + Label { + id: lastBlockLabel + objectName: "lastBlockLabel" + visible: true + text: "---" + font.pixelSize: 10 + anchors.right: peerGroup.left + anchors.rightMargin: 5 + } + + ProgressBar { + visible: false + id: downloadIndicator + value: 0 + objectName: "downloadIndicator" + y: -4 + x: statusBar.width / 2 - this.width / 2 + width: 160 + } + + Label { + visible: false + objectName: "downloadLabel" + //y: 7 + anchors.left: downloadIndicator.right + anchors.leftMargin: 5 + font.pixelSize: 10 + text: "0 / 0" + } + + + RowLayout { + id: peerGroup + //y: 7 + anchors.right: parent.right + MouseArea { + onDoubleClicked: peerWindow.visible = true + anchors.fill: parent + } + + Label { + id: peerLabel + font.pixelSize: 10 + text: "0 / 0" + } + } + } + + + property var blockModel: ListModel { + id: blockModel + } + + SplitView { + property var views: []; + + id: mainSplit + anchors.fill: parent + //resizing: false // this is NOT where we remove that damning resizing handle.. + handleDelegate: Item { + //This handle is a way to remove the line between the split views + Rectangle { + anchors.fill: parent + } + } + + function setView(view, menu) { + for(var i = 0; i < views.length; i++) { + views[i].view.visible = false + views[i].menuItem.setSelection(false) + } + view.visible = true + menu.setSelection(true) + } + + function addComponent(view, options) { + view.visible = false + view.anchors.fill = mainView + + var menuItem = menu.createMenuItem(view, options); + if( view.hasOwnProperty("menuItem") ) { + view.menuItem = menuItem; + } + + if( view.hasOwnProperty("onReady") ) { + view.onReady.call(view) + } + + if( options.active ) { + setView(view, menuItem) + } + + + return {view: view, menuItem: menuItem} + } + + /********************* + * Main menu. + ********************/ + Rectangle { + id: menu + Layout.minimumWidth: 192 + Layout.maximumWidth: 192 + + FontLoader { + id: sourceSansPro + source: "fonts/SourceSansPro-Regular.ttf" + } + FontLoader { + source: "fonts/SourceSansPro-Semibold.ttf" + } + FontLoader { + source: "fonts/SourceSansPro-Bold.ttf" + } + FontLoader { + source: "fonts/SourceSansPro-Black.ttf" + } + FontLoader { + source: "fonts/SourceSansPro-Light.ttf" + } + FontLoader { + source: "fonts/SourceSansPro-ExtraLight.ttf" + } + FontLoader { + id: simpleLineIcons + source: "fonts/Simple-Line-Icons.ttf" + } + + Rectangle { + color: "steelblue" + anchors.fill: parent + + MouseArea { + anchors.fill: parent + property real lastMouseX: 0 + property real lastMouseY: 0 + onPressed: { + lastMouseX = mouseX + lastMouseY = mouseY + } + onPositionChanged: { + root.x += (mouseX - lastMouseX) + root.y += (mouseY - lastMouseY) + } + /*onDoubleClicked: { + //!maximized ? view.set_max() : view.set_normal()} + visibility = "Minimized" + }*/ + } + } + + + + anchors.top: parent.top + Rectangle { + width: parent.height + height: parent.width + anchors.centerIn: parent + rotation: 90 + + gradient: Gradient { + GradientStop { position: 0.0; color: "#E2DEDE" } + GradientStop { position: 0.1; color: "#EBE8E8" } + GradientStop { position: 1.0; color: "#EBE8E8" } + } + } + + Component { + id: menuItemTemplate + Rectangle { + id: menuItem + property var view; + property var path; + property var closable; + + property alias title: label.text + property alias icon: icon.source + property alias secondaryTitle: secondary.text + function setSelection(on) { + sel.visible = on + + if (this.closable == true) { + closeIcon.visible = on + } + } + + function setAsBigButton(on) { + newAppButton.visible = on + label.visible = !on + buttonLabel.visible = on + } + + width: 192 + height: 55 + color: "#00000000" + + anchors { + left: parent.left + leftMargin: 4 + } + + Rectangle { + // New App Button + id: newAppButton + visible: false + anchors.fill: parent + anchors.rightMargin: 8 + border.width: 0 + radius: 5 + height: 55 + width: 180 + color: "#F3F1F3" + } + + Rectangle { + id: sel + visible: false + anchors.fill: parent + color: "#00000000" + Rectangle { + id: r + anchors.fill: parent + border.width: 0 + radius: 5 + color: "#FAFAFA" + } + Rectangle { + anchors { + top: r.top + bottom: r.bottom + right: r.right + } + width: 10 + color: "#FAFAFA" + border.width:0 + + Rectangle { + // Small line on top of selection. What's this for? + anchors { + left: parent.left + right: parent.right + top: parent.top + } + height: 1 + color: "#FAFAFA" + } + + Rectangle { + // Small line on bottom of selection. What's this for again? + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + height: 1 + color: "#FAFAFA" + } + } + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onClicked: { + activeView(view, menuItem); + } + onEntered: { + if (parent.closable == true) { + closeIcon.visible = sel.visible + } + + } + onExited: { + closeIcon.visible = false + } + } + + Image { + id: icon + height: 24 + width: 24 + anchors { + left: parent.left + verticalCenter: parent.verticalCenter + leftMargin: 6 + } + } + + Text { + id: buttonLabel + visible: false + text: "GO TO NEW APP" + font.family: sourceSansPro.name + font.weight: Font.DemiBold + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + color: "#AAA0A0" + } + + Text { + id: label + font.family: sourceSansPro.name + font.weight: Font.DemiBold + anchors { + left: icon.right + verticalCenter: parent.verticalCenter + leftMargin: 6 + // verticalCenterOffset: -10 + } + x:250 + color: "#665F5F" + font.pixelSize: 14 + } + + + Text { + id: secondary + font.family: sourceSansPro.name + font.weight: Font.Light + anchors { + left: icon.right + leftMargin: 6 + top: label.bottom + } + color: "#6691C2" + font.pixelSize: 12 + } + + Rectangle { + id: closeIcon + visible: false + width: 10 + height: 10 + color: "#FFFFFF" + anchors { + fill: icon + } + + MouseArea { + anchors.fill: parent + onClicked: { + menuItem.closeApp() + } + } + + Text { + + font.family: simpleLineIcons.name + anchors { + centerIn: parent + } + color: "#665F5F" + font.pixelSize: 18 + text: "\ue082" + } + } + + + + function closeApp() { + if(!this.closable) { return; } + + if(this.view.hasOwnProperty("onDestroy")) { + this.view.onDestroy.call(this.view) + } + + this.view.destroy() + this.destroy() + for (var i = 0; i < mainSplit.views.length; i++) { + var view = mainSplit.views[i]; + if (view.menuItem === this) { + mainSplit.views.splice(i, 1); + break; + } + } + gui.removePlugin(this.path) + activeView(mainSplit.views[0].view, mainSplit.views[0].menuItem); + } + } + } + + function createMenuItem(view, options) { + if(options === undefined) { + options = {}; + } + + var section; + switch(options.section) { + case "begin": + section = menuBegin + break; + case "ethereum": + section = menuDefault; + break; + case "legacy": + section = menuLegacy; + break; + default: + section = menuApps; + break; + } + + var comp = menuItemTemplate.createObject(section) + comp.view = view + comp.title = view.title + + if(view.hasOwnProperty("iconSource")) { + comp.icon = view.iconSource; + } + comp.closable = options.close; + + if (options.section === "begin") { + comp.setAsBigButton(true) + } + + return comp + } + + ColumnLayout { + id: menuColumn + y: 10 + width: parent.width + anchors.left: parent.left + anchors.right: parent.right + spacing: 3 + + + + ColumnLayout { + id: menuBegin + spacing: 3 + anchors { + left: parent.left + right: parent.right + } + } + + Rectangle { + height: 55 + color: "transparent" + Text { + text: "ETHEREUM" + font.family: sourceSansPro.name + font.weight: Font.DemiBold + anchors { + left: parent.left + top: parent.verticalCenter + leftMargin: 16 + } + color: "#AAA0A0" + } + } + + + ColumnLayout { + id: menuDefault + spacing: 3 + anchors { + left: parent.left + right: parent.right + } + } + + Rectangle { + height: 55 + color: "transparent" + Text { + text: "APPS" + font.family: sourceSansPro.name + font.weight: Font.DemiBold + anchors { + left: parent.left + top: parent.verticalCenter + leftMargin: 16 + } + color: "#AAA0A0" + } + } + + ColumnLayout { + id: menuApps + spacing: 3 + anchors { + left: parent.left + right: parent.right + } + } + + Rectangle { + height: 55 + color: "transparent" + Text { + text: "DEBUG" + font.family: sourceSansPro.name + font.weight: Font.DemiBold + anchors { + left: parent.left + top: parent.verticalCenter + leftMargin: 16 + } + color: "#AAA0A0" + } + } + + + ColumnLayout { + id: menuLegacy + spacing: 3 + anchors { + left: parent.left + right: parent.right + } + } + } + } + + /********************* + * Main view + ********************/ + Rectangle { + id: rootView + anchors.right: parent.right + anchors.left: menu.right + anchors.bottom: parent.bottom + anchors.top: parent.top + color: "#00000000" + + /*Rectangle { + id: urlPane + height: 40 + color: "#00000000" + anchors { + left: parent.left + right: parent.right + leftMargin: 5 + rightMargin: 5 + top: parent.top + topMargin: 5 + } + TextField { + id: url + objectName: "url" + placeholderText: "DApp URL" + anchors { + left: parent.left + right: parent.right + top: parent.top + topMargin: 5 + rightMargin: 5 + leftMargin: 5 + } + + Keys.onReturnPressed: { + if(/^https?/.test(this.text)) { + newBrowserTab(this.text); + } else { + addPlugin(this.text, {close: true, section: "apps"}) + } + } + } + + } + + // Border + Rectangle { + id: divider + anchors { + left: parent.left + right: parent.right + top: urlPane.bottom + } + z: -1 + height: 1 + color: "#CCCCCC" + }*/ + + Rectangle { + id: mainView + color: "#00000000" + anchors.right: parent.right + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.top: parent.top + + function createView(component) { + var view = component.createObject(mainView) + + return view; + } + } + } + } + + + /****************** + * Dialogs + *****************/ + FileDialog { + id: generalFileDialog + property var callback; + onAccepted: { + var path = this.fileUrl.toString(); + callback.call(this, path); + } + + function show(selectExisting, callback) { + generalFileDialog.callback = callback; + generalFileDialog.selectExisting = selectExisting; + + this.open(); + } + } + + + /****************** + * Wallet functions + *****************/ + function importApp(path) { + var ext = path.split('.').pop() + if(ext == "html" || ext == "htm") { + eth.openHtml(path) + }else if(ext == "qml"){ + addPlugin(path, {close: true, section: "apps"}) + } + } + + + function setWalletValue(value) { + walletValueLabel.text = value + } + + function loadPlugin(name) { + console.log("Loading plugin" + name) + var view = mainView.addPlugin(name) + } + + function setPeers(text) { + peerLabel.text = text + } + + function addPeer(peer) { + // We could just append the whole peer object but it cries if you try to alter them + peerModel.append({ip: peer.ip, port: peer.port, lastResponse:timeAgo(peer.lastSend), latency: peer.latency, version: peer.version, caps: peer.caps}) + } + + function resetPeers(){ + peerModel.clear() + } + + function timeAgo(unixTs){ + var lapsed = (Date.now() - new Date(unixTs*1000)) / 1000 + return (lapsed + " seconds ago") + } + + function convertToPretty(unixTs){ + var a = new Date(unixTs*1000); + var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; + var year = a.getFullYear(); + var month = months[a.getMonth()]; + var date = a.getDate(); + var hour = a.getHours(); + var min = a.getMinutes(); + var sec = a.getSeconds(); + var time = date+' '+month+' '+year+' '+hour+':'+min+':'+sec ; + return time; + } + + /********************** + * Windows + *********************/ + Window { + id: peerWindow + //flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint + height: 200 + width: 700 + Rectangle { + anchors.fill: parent + property var peerModel: ListModel { + id: peerModel + } + TableView { + anchors.fill: parent + id: peerTable + model: peerModel + TableViewColumn{width: 200; role: "ip" ; title: "IP" } + TableViewColumn{width: 260; role: "version" ; title: "Version" } + TableViewColumn{width: 180; role: "caps" ; title: "Capabilities" } + } + } + } + + Window { + id: aboutWin + visible: false + title: "About" + minimumWidth: 350 + maximumWidth: 350 + maximumHeight: 280 + minimumHeight: 280 + + Image { + id: aboutIcon + height: 150 + width: 150 + fillMode: Image.PreserveAspectFit + smooth: true + source: "../facet.png" + x: 10 + y: 30 + } + + Text { + anchors.left: aboutIcon.right + anchors.leftMargin: 10 + anchors.top: parent.top + anchors.topMargin: 30 + font.pointSize: 12 + text: "<h2>Mist (0.7.10)</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor TrĂ³n<br>Felix Lange<br>Taylor Gerring<br>Daniel Nagy<br><h3>UX</h3>Alex van de Sande<br>" + } + } + + Window { + id: txImportDialog + minimumWidth: 270 + maximumWidth: 270 + maximumHeight: 50 + minimumHeight: 50 + TextField { + id: txImportField + width: 170 + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 10 + onAccepted: { + } + } + Button { + anchors.left: txImportField.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 5 + text: "Import" + onClicked: { + eth.importTx(txImportField.text) + txImportField.visible = false + } + } + Component.onCompleted: { + addrField.focus = true + } + } + + Window { + id: addPeerWin + visible: false + minimumWidth: 300 + maximumWidth: 300 + maximumHeight: 50 + minimumHeight: 50 + title: "Connect to peer" + + ComboBox { + id: addrField + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: addPeerButton.left + anchors.leftMargin: 10 + anchors.rightMargin: 10 + onAccepted: { + eth.connectToPeer(addrField.currentText) + addPeerWin.visible = false + } + + editable: true + model: ListModel { id: pastPeers } + + Component.onCompleted: { + pastPeers.insert(0, {text: "poc-8.ethdev.com:30303"}) + /* + var ips = eth.pastPeers() + for(var i = 0; i < ips.length; i++) { + pastPeers.append({text: ips.get(i)}) + } + + pastPeers.insert(0, {text: "poc-7.ethdev.com:30303"}) + */ + } + } + + Button { + id: addPeerButton + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.rightMargin: 10 + text: "Add" + onClicked: { + eth.connectToPeer(addrField.currentText) + addPeerWin.visible = false + } + } + Component.onCompleted: { + addrField.focus = true + } + } + }
\ No newline at end of file diff --git a/cmd/mist/assets/qml/views/browser.qml b/cmd/mist/assets/qml/views/browser.qml new file mode 100644 index 000000000..04b2229ec --- /dev/null +++ b/cmd/mist/assets/qml/views/browser.qml @@ -0,0 +1,426 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0; +import QtQuick.Controls.Styles 1.0 +import QtQuick.Layouts 1.0; +import QtWebEngine 1.0 +//import QtWebEngine.experimental 1.0 +import QtQuick.Window 2.0; + +Rectangle { + id: window + anchors.fill: parent + color: "#00000000" + + property var title: "" + property var iconSource: "../browser.png" + property var menuItem + property var hideUrl: true + + property alias url: webview.url + property alias windowTitle: webview.title + property alias webView: webview + + property var cleanPath: false + property var open: function(url) { + if(!window.cleanPath) { + var uri = url; + if(!/.*\:\/\/.*/.test(uri)) { + uri = "http://" + uri; + } + + var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ + + if(reg.test(uri)) { + uri.replace(reg, function(match, pre, domain, path) { + uri = pre; + + var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4)); + var ip = []; + for(var i = 0, l = lookup.length; i < l; i++) { + ip.push(lookup.charCodeAt(i)) + } + + if(ip.length != 0) { + uri += lookup; + } else { + uri += domain; + } + + uri += path; + }); + } + + window.cleanPath = true; + + webview.url = uri; + + //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2<span style='color:#CCC'>$3</span>"); + uriNav.text = uri; + + } else { + // Prevent inf loop. + window.cleanPath = false; + } + } + + function showFullUrlBar(on){ + if (on) { + //appTitle.visible = false + //appDomain.visible = false + + //uriNav.visible = true + clickAnywhereOnApp.visible = true + + navBar.state = "fullUrlVisible" + } else { + //appTitle.visible = true + //appDomain.visible = true + //uriNav.visible = false + clickAnywhereOnApp.visible = false + + navBar.state = "titleVisible" + + } + + } + + Component.onCompleted: { + } + + Item { + objectName: "root" + id: root + anchors.fill: parent + state: "inspectorShown" + + MouseArea { + id: clickAnywhereOnApp + z:15 + //hoverEnabled: true + anchors.fill: parent + /*hoverEnabled: true*/ + + onClicked: { + showFullUrlBar(false); + } + + /*Rectangle { + anchors.fill: parent + color: "#88888888" + }*/ + } + + RowLayout { + id: navBar + height: 74 + z: 20 + anchors { + left: parent.left + right: parent.right + } + + Button { + id: back + + onClicked: { + webview.goBack() + } + + anchors{ + left: parent.left + leftMargin: 6 + } + + style: ButtonStyle { + background: Image { + source: "../../backButton.png" + width: 20 + height: 30 + } + } + } + + Rectangle { + id: appInfoPane + height: 28 + color: "#FFFFFF" + radius: 6 + + + MouseArea { + anchors.fill: parent + z: 10 + hoverEnabled: true + + onEntered: { + showFullUrlBar(true); + } + + } + + anchors { + left: back.right + right: parent.right + leftMargin: 10 + rightMargin: 10 + } + + Text { + id: appTitle + text: "LOADING" + font.bold: true + font.capitalization: Font.AllUppercase + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + + anchors { + left: parent.left + right: parent.horizontalCenter + top: parent.top + bottom: parent.bottom + rightMargin: 10 + } + color: "#928484" + } + + Text { + id: appDomain + text: "loading domain" + font.bold: false + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignVCenter + + anchors { + left: parent.horizontalCenter + right: parent.right + top: parent.top + bottom: parent.bottom + leftMargin: 10 + } + color: "#C0AFAF" + } + + + TextField { + id: uriNav + opacity: 0.0 + + anchors { + left: parent.left + right: parent.right + leftMargin: 16 + } + + horizontalAlignment: Text.AlignHCenter + + style: TextFieldStyle { + textColor: "#928484" + background: Rectangle { + border.width: 0 + color: "transparent" + } + } + text: webview.url; + y: parent.height / 2 - this.height / 2 + z: 20 + activeFocusOnPress: true + Keys.onReturnPressed: { + webview.url = this.text; + } + /* onFocusedChanged: { + if (focused) { + //uriNav.selectAll(); + } + }*/ + } + + z:2 + } + + Rectangle { + id: appInfoPaneShadow + width: 10 + height: 30 + color: "#BDB6B6" + radius: 6 + + anchors { + left: back.right + right: parent.right + leftMargin:10 + rightMargin:10 + top: parent.top + topMargin: 23 + } + + z:1 + } + + Rectangle { + id: navBarBackground + anchors.fill: parent + gradient: Gradient { + GradientStop { position: 0.0; color: "#F6F1F2" } + GradientStop { position: 1.0; color: "#DED5D5" } + } + z:-1 + } + + states: [ + State { + name: "fullUrlVisible" + PropertyChanges { + target: appTitle + anchors.rightMargin: -50 + opacity: 0.0 + } + PropertyChanges { + target: appDomain + anchors.leftMargin: -50 + opacity: 0.0 + } + PropertyChanges { + target: uriNav + anchors.leftMargin: 0 + opacity: 1.0 + } + }, + State { + name: "titleVisible" + + PropertyChanges { + target: appTitle + anchors.rightMargin: 10 + opacity: 1.0 + } + PropertyChanges { + target: appDomain + anchors.leftMargin: 10 + opacity: 1.0 + } + PropertyChanges { + target: uriNav + anchors.leftMargin: -50 + opacity: 0.0 + } + } + + ] + + transitions: [ + // This adds a transition that defaults to applying to all state changes + + Transition { + + // This applies a default NumberAnimation to any changes a state change makes to x or y properties + NumberAnimation { + properties: "anchors.leftMargin, anchors.rightMargin, opacity" + easing.type: Easing.InOutQuad //Easing.InOutBack + duration: 300 + } + } + ] + + } + + WebEngineView { + objectName: "webView" + id: webview + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + top: navBar.bottom + } + z: 10 + + onLoadingChanged: { + if (loadRequest.status == WebEngineView.LoadSucceededStatus) { + webview.runJavaScript("document.title", function(pageTitle) { + menuItem.title = pageTitle; + }); + + //var topBarStyle + webView.runJavaScript("document.querySelector(\"meta[name='ethereum-dapp-url-bar-style']\").getAttribute(\"content\")", function(topBarStyle){ + if (topBarStyle=="transparent") { + + // Adjust for a transparent sidebar Dapp + navBarBackground.visible = false; + back.visible = false; + appInfoPane.anchors.leftMargin = -16; + appInfoPaneShadow.anchors.leftMargin = -16; + webview.anchors.topMargin = -74; + webview.runJavaScript("document.querySelector('body').classList.add('ethereum-dapp-url-bar-style-transparent')") + + } else { + navBarBackground.visible = true; + back.visible = true; + appInfoPane.anchors.leftMargin = 0; + appInfoPaneShadow.anchors.leftMargin = 0; + webview.anchors.topMargin = 0; + + }; + }); + + + + webview.runJavaScript(eth.readFile("bignumber.min.js")); + webview.runJavaScript(eth.readFile("ethereum.js/dist/ethereum.js")); + + var cleanTitle = webview.url.toString() + var matches = cleanTitle.match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); + var domain = matches && matches[1]; + + appDomain.text = domain //webview.url.replace("a", "z") + appTitle.text = webview.title + + showFullUrlBar(false); + } + } + onJavaScriptConsoleMessage: { + console.log(sourceID + ":" + lineNumber + ":" + JSON.stringify(message)); + } + } + + Rectangle { + id: sizeGrip + color: "gray" + visible: false + height: 10 + anchors { + left: root.left + right: root.right + } + y: Math.round(root.height * 2 / 3) + + MouseArea { + anchors.fill: parent + drag.target: sizeGrip + drag.minimumY: 0 + drag.maximumY: root.height + drag.axis: Drag.YAxis + } + } + + WebEngineView { + id: inspector + visible: false + anchors { + left: root.left + right: root.right + top: sizeGrip.bottom + bottom: root.bottom + } + + } + + states: [ + State { + name: "inspectorShown" + PropertyChanges { + target: inspector + } + } + ] + } +} diff --git a/cmd/mist/assets/qml/views/catalog.qml b/cmd/mist/assets/qml/views/catalog.qml new file mode 100644 index 000000000..a7832e9fa --- /dev/null +++ b/cmd/mist/assets/qml/views/catalog.qml @@ -0,0 +1,155 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0; +import QtQuick.Controls.Styles 1.0 +import QtQuick.Layouts 1.0; +import QtWebEngine 1.0 +//import QtWebEngine.experimental 1.0 +import QtQuick.Window 2.0; + + +Rectangle { + id: window + anchors.fill: parent + color: "#00000000" + + property var title: "Catalog" + property var iconSource: "" + property var menuItem + property var hideUrl: true + + property alias url: webview.url + property alias windowTitle: webview.title + property alias webView: webview + + + + property var cleanPath: false + property var open: function(url) { + if(!window.cleanPath) { + var uri = url; + if(!/.*\:\/\/.*/.test(uri)) { + uri = "http://" + uri; + } + + var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ + + if(reg.test(uri)) { + uri.replace(reg, function(match, pre, domain, path) { + uri = pre; + + var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4)); + var ip = []; + for(var i = 0, l = lookup.length; i < l; i++) { + ip.push(lookup.charCodeAt(i)) + } + + if(ip.length != 0) { + uri += lookup; + } else { + uri += domain; + } + + uri += path; + }); + } + + window.cleanPath = true; + + webview.url = uri; + + //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2<span style='color:#CCC'>$3</span>"); + uriNav.text = uri; + + } else { + // Prevent inf loop. + window.cleanPath = false; + } + } + + Component.onCompleted: { + } + + Item { + objectName: "root" + id: root + anchors.fill: parent + state: "inspectorShown" + + WebEngineView { + objectName: "webView" + id: webview + anchors.fill: parent + + property var protocol: "http://" + //property var domain: "localhost:3000" + property var domain: "ethereum-dapp-catalog.meteor.com" + url: protocol + domain + + //navigationRequest: WebEngineView.IgnoreRequest + // onLoadingChanged: { + // if (loadRequest.status == WebEngineView.LoadSucceededStatus) { + // webview.runJavaScript(eth.readFile("bignumber.min.js")); + // webview.runJavaScript(eth.readFile("ethereum.js/dist/ethereum.js")); + // } + // } + + //onNavigationRequested: { + // detect URL scheme prefix, most likely an external link + //var schemaRE = /^\w+:/; + //if (schemaRE.test(request.url)) { + // request.action = WebView.AcceptRequest; + //} else { + //request.action = WebView.IgnoreRequest; + // delegate request.url here + //} + //} + + onJavaScriptConsoleMessage: { + console.log(sourceID + ":" + lineNumber + ":" + JSON.stringify(message)); + } + + onNavigationRequested: { + var cleanTitle = request.url.toString() + var matches = cleanTitle.match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); + var requestedDomain = matches && matches[1]; + + console.debug ("NavigationRequested: " + request.url + " navigationType=" + request.navigationType) + + if(request.navigationType==0){ + + if (requestedDomain === this.domain){ + request.action = WebEngineView.AcceptRequest; + } else { + request.action = WebEngineView.IgnoreRequest; + newBrowserTab(request.url); + } + + } + } + } + + + + WebEngineView { + id: inspector + visible: false + z:10 + anchors { + left: root.left + right: root.right + top: sizeGrip.bottom + bottom: root.bottom + } + + } + + states: [ + State { + name: "inspectorShown" + PropertyChanges { + target: inspector + } + } + ] + } +} diff --git a/cmd/mist/assets/qml/views/chain.qml b/cmd/mist/assets/qml/views/chain.qml index 6baf757a5..4d1bc0e03 100644 --- a/cmd/mist/assets/qml/views/chain.qml +++ b/cmd/mist/assets/qml/views/chain.qml @@ -111,7 +111,7 @@ Rectangle { if(initial){ blockModel.append({raw: block.raw, bloom: block.bloom, size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)}) } else { - blockModel.insert(0, {bloom: block.bloom, size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)}) + blockModel.insert(0, {raw: block.raw, bloom: block.bloom, size: block.size, number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)}) } } diff --git a/cmd/mist/assets/qml/views/info.qml b/cmd/mist/assets/qml/views/info.qml index 3ff551b05..14ee0bce1 100644 --- a/cmd/mist/assets/qml/views/info.qml +++ b/cmd/mist/assets/qml/views/info.qml @@ -28,7 +28,7 @@ Rectangle { text: "Address" } TextField { - text: eth.key().address + text: eth.coinbase() width: 500 } diff --git a/cmd/mist/assets/qml/views/wallet.qml b/cmd/mist/assets/qml/views/wallet.qml index b81273a17..545098284 100644 --- a/cmd/mist/assets/qml/views/wallet.qml +++ b/cmd/mist/assets/qml/views/wallet.qml @@ -20,9 +20,9 @@ Rectangle { } function setBalance() { - //balance.text = "<b>Balance</b>: " + eth.numberToHuman(eth.balanceAt(eth.key().address)) + balance.text = "<b>Balance</b>: " + eth.numberToHuman(eth.balanceAt(eth.coinbase())) if(menuItem) - menuItem.secondaryTitle = eth.numberToHuman(eth.balanceAt(eth.key().address)) + menuItem.secondaryTitle = eth.numberToHuman(eth.balanceAt(eth.coinbase())) } ListModel { @@ -130,7 +130,7 @@ Rectangle { onClicked: { var value = txValue.text + denomModel.get(valueDenom.currentIndex).zeros; var gasPrice = "10000000000000" - var res = eth.transact({from: eth.key().privateKey, to: txTo.text, value: value, gas: "500", gasPrice: gasPrice}) + var res = eth.transact({from: eth.coinbase(), to: txTo.text, value: value, gas: "500", gasPrice: gasPrice}) } } } @@ -155,17 +155,10 @@ Rectangle { model: ListModel { id: txModel Component.onCompleted: { - var me = eth.key().address; - var filterTo = ethx.watch({latest: -1, to: me}); - var filterFrom = ethx.watch({latest: -1, from: me}); - filterTo.changed(addTxs) - filterFrom.changed(addTxs) - - addTxs(filterTo.messages()) - addTxs(filterFrom.messages()) } function addTxs(messages) { + /* setBalance() for(var i = 0; i < messages.length; i++) { @@ -179,6 +172,7 @@ Rectangle { } txModel.insert(0, {num: txModel.count, from: from, to: to, value: eth.numberToHuman(message.value)}) } + */ } } } diff --git a/cmd/mist/assets/qml/views/whisper.qml b/cmd/mist/assets/qml/views/whisper.qml index 029376c45..dc097b806 100644 --- a/cmd/mist/assets/qml/views/whisper.qml +++ b/cmd/mist/assets/qml/views/whisper.qml @@ -18,7 +18,6 @@ Rectangle { property var identity: "" Component.onCompleted: { identity = shh.newIdentity() - console.log("New identity:", identity) var t = shh.watch({}, root) } |