Commit b89d9f6e authored by obscuren's avatar obscuren

Added DApp url bar (TBD) & changed behaviour for the menu selection

parent d22db772
// this function is included locally, but you can also include separately via a header definition
function request(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = (function(req) {
return function() {
if(req.readyState === 4) {
callback(req);
}
}
})(xhr);
xhr.open('GET', url, true);
xhr.send('');
}
...@@ -7,750 +7,864 @@ import QtQuick.Controls.Styles 1.1 ...@@ -7,750 +7,864 @@ import QtQuick.Controls.Styles 1.1
import Ethereum 1.0 import Ethereum 1.0
import "../ext/filter.js" as Eth import "../ext/filter.js" as Eth
import "../ext/http.js" as Http
ApplicationWindow { ApplicationWindow {
id: root id: root
property alias miningButtonText: miningButton.text property alias miningButtonText: miningButton.text
property var ethx : Eth.ethx property var ethx : Eth.ethx
width: 900 width: 900
height: 600 height: 600
minimumHeight: 300 minimumHeight: 300
title: "Ether Browser" title: "Ether Browser"
// This signal is used by the filter API. The filter API connects using this signal handler from // This signal is used by the filter API. The filter API connects using this signal handler from
// the different QML files and plugins. // the different QML files and plugins.
signal message(var callback, int seed); signal message(var callback, int seed);
function invokeFilterCallback(data, receiverSeed) { function invokeFilterCallback(data, receiverSeed) {
//var messages = JSON.parse(data) //var messages = JSON.parse(data)
// Signal handler // Signal handler
message(data, receiverSeed); message(data, receiverSeed);
} }
TextField { TextField {
id: copyElementHax id: copyElementHax
visible: false visible: false
} }
function copyToClipboard(text) { function copyToClipboard(text) {
copyElementHax.text = text copyElementHax.text = text
copyElementHax.selectAll() copyElementHax.selectAll()
copyElementHax.copy() copyElementHax.copy()
} }
// Takes care of loading all default plugins // Takes care of loading all default plugins
Component.onCompleted: { Component.onCompleted: {
addPlugin("./views/wallet.qml", {noAdd: true, section: "ethereum", active: true}); addPlugin("./views/wallet.qml", {noAdd: true, section: "ethereum", active: true});
addPlugin("./views/transaction.qml", {noAdd: true, section: "legacy"}); addPlugin("./views/transaction.qml", {noAdd: true, section: "legacy"});
addPlugin("./views/chain.qml", {noAdd: true, section: "legacy"}); addPlugin("./views/chain.qml", {noAdd: true, section: "legacy"});
addPlugin("./views/info.qml", {noAdd: true, section: "legacy"}); addPlugin("./views/info.qml", {noAdd: true, section: "legacy"});
addPlugin("./views/pending_tx.qml", {noAdd: true, section: "legacy"}); addPlugin("./views/pending_tx.qml", {noAdd: true, section: "legacy"});
addPlugin("./views/javascript.qml", {noAdd: true, section: "legacy"}); addPlugin("./views/javascript.qml", {noAdd: true, section: "legacy"});
// Call the ready handler // Call the ready handler
gui.done(); gui.done();
} }
function addPlugin(path, options) { function addViews(view, path, options) {
try { var views = mainSplit.addComponent(view, options)
var component = Qt.createComponent(path); views.menuItem.path = path
if(component.status != Component.Ready) {
if(component.status == Component.Error) { mainSplit.views.push(views);
ethx.note("error: ", component.errorString());
} if(!options.noAdd) {
gui.addPlugin(path)
return }
}
return views
var views = mainSplit.addComponent(component, options) }
views.menuItem.path = path
function addPlugin(path, options) {
mainSplit.views.push(views); try {
if(typeof(path) === "string" && /^https?/.test(path)) {
if(!options.noAdd) { console.log('load http')
gui.addPlugin(path) Http.request(path, function(o) {
} if(o.status === 200) {
var view = Qt.createQmlObject(o.responseText, mainView, path)
return views.view addViews(view, path, options)
} catch(e) { }
ethx.note(e) })
}
} return
}
MenuBar {
Menu { var component = Qt.createComponent(path);
title: "File" if(component.status != Component.Ready) {
MenuItem { if(component.status == Component.Error) {
text: "Import App" ethx.note("error: ", component.errorString());
shortcut: "Ctrl+o" }
onTriggered: {
generalFileDialog.show(true, importApp) return
} }
}
var view = mainView.createView(component, options)
MenuItem { var views = addViews(view, path, options)
text: "Browser"
onTriggered: eth.openBrowser() return views.view
} } catch(e) {
ethx.note(e)
MenuItem { }
text: "Add plugin" }
onTriggered: {
generalFileDialog.show(true, function(path) { MenuBar {
addPlugin(path, {canClose: true, section: "apps"}) Menu {
}) title: "File"
} MenuItem {
} text: "Import App"
shortcut: "Ctrl+o"
MenuSeparator {} onTriggered: {
generalFileDialog.show(true, importApp)
MenuItem { }
text: "Import key" }
shortcut: "Ctrl+i"
onTriggered: { MenuItem {
generalFileDialog.show(true, function(path) { text: "Browser"
gui.importKey(path) onTriggered: eth.openBrowser()
}) }
}
} MenuItem {
text: "Add plugin"
MenuItem { onTriggered: {
text: "Export keys" generalFileDialog.show(true, function(path) {
shortcut: "Ctrl+e" addPlugin(path, {canClose: true, section: "apps"})
onTriggered: { })
generalFileDialog.show(false, function(path) { }
}) }
}
} MenuSeparator {}
}
MenuItem {
Menu { text: "Import key"
title: "Developer" shortcut: "Ctrl+i"
MenuItem { onTriggered: {
text: "Debugger" generalFileDialog.show(true, function(path) {
shortcut: "Ctrl+d" gui.importKey(path)
onTriggered: eth.startDebugger() })
} }
}
MenuItem {
text: "Import Tx" MenuItem {
onTriggered: { text: "Export keys"
txImportDialog.visible = true shortcut: "Ctrl+e"
} onTriggered: {
} generalFileDialog.show(false, function(path) {
})
MenuItem { }
text: "Run JS file" }
onTriggered: { }
generalFileDialog.show(true, function(path) {
eth.evalJavascriptFile(path) Menu {
}) title: "Developer"
} MenuItem {
} text: "Debugger"
shortcut: "Ctrl+d"
MenuItem { onTriggered: eth.startDebugger()
text: "Dump state" }
onTriggered: {
generalFileDialog.show(false, function(path) { MenuItem {
// Empty hash for latest text: "Import Tx"
gui.dumpState("", path) onTriggered: {
}) txImportDialog.visible = true
} }
} }
MenuSeparator {} MenuItem {
text: "Run JS file"
MenuItem { onTriggered: {
id: miningSpeed generalFileDialog.show(true, function(path) {
text: "Mining: Turbo" eth.evalJavascriptFile(path)
onTriggered: { })
gui.toggleTurboMining() }
if(text == "Mining: Turbo") { }
text = "Mining: Normal";
} else { MenuItem {
text = "Mining: Turbo"; text: "Dump state"
} onTriggered: {
} generalFileDialog.show(false, function(path) {
} // Empty hash for latest
} gui.dumpState("", path)
})
Menu { }
title: "Network" }
MenuItem {
text: "Add Peer" MenuSeparator {}
shortcut: "Ctrl+p"
onTriggered: { MenuItem {
addPeerWin.visible = true id: miningSpeed
} text: "Mining: Turbo"
} onTriggered: {
MenuItem { gui.toggleTurboMining()
text: "Show Peers" if(text == "Mining: Turbo") {
shortcut: "Ctrl+e" text = "Mining: Normal";
onTriggered: { } else {
peerWindow.visible = true text = "Mining: Turbo";
} }
} }
} }
}
Menu {
title: "Help" Menu {
MenuItem { title: "Network"
text: "About" MenuItem {
onTriggered: { text: "Add Peer"
aboutWin.visible = true shortcut: "Ctrl+p"
} onTriggered: {
} addPeerWin.visible = true
} }
}
} MenuItem {
text: "Show Peers"
statusBar: StatusBar { shortcut: "Ctrl+e"
height: 32 onTriggered: {
RowLayout { peerWindow.visible = true
Button { }
id: miningButton }
text: "Start Mining" }
onClicked: {
gui.toggleMining() Menu {
} title: "Help"
} MenuItem {
text: "About"
Button { onTriggered: {
id: importAppButton aboutWin.visible = true
text: "Browser" }
onClicked: { }
eth.openBrowser() }
}
} }
RowLayout { statusBar: StatusBar {
Label { height: 32
id: walletValueLabel RowLayout {
Button {
font.pixelSize: 10 id: miningButton
styleColor: "#797979" text: "Start Mining"
} onClicked: {
} gui.toggleMining()
} }
}
Label {
y: 6 Button {
objectName: "miningLabel" id: importAppButton
visible: true text: "Browser"
font.pixelSize: 10 onClicked: {
anchors.right: lastBlockLabel.left eth.openBrowser()
anchors.rightMargin: 5 }
} }
Label { RowLayout {
y: 6 Label {
id: lastBlockLabel id: walletValueLabel
objectName: "lastBlockLabel"
visible: true font.pixelSize: 10
text: "" styleColor: "#797979"
font.pixelSize: 10 }
anchors.right: peerGroup.left }
anchors.rightMargin: 5 }
}
Label {
ProgressBar { y: 6
id: syncProgressIndicator objectName: "miningLabel"
visible: false visible: true
objectName: "syncProgressIndicator" font.pixelSize: 10
y: 3 anchors.right: lastBlockLabel.left
width: 140 anchors.rightMargin: 5
indeterminate: true }
anchors.right: peerGroup.left
anchors.rightMargin: 5 Label {
} y: 6
id: lastBlockLabel
RowLayout { objectName: "lastBlockLabel"
id: peerGroup visible: true
y: 7 text: ""
anchors.right: parent.right font.pixelSize: 10
MouseArea { anchors.right: peerGroup.left
onDoubleClicked: peerWindow.visible = true anchors.rightMargin: 5
anchors.fill: parent }
}
ProgressBar {
Label { id: syncProgressIndicator
id: peerLabel visible: false
font.pixelSize: 8 objectName: "syncProgressIndicator"
text: "0 / 0" y: 3
} width: 140
Image { indeterminate: true
id: peerImage anchors.right: peerGroup.left
width: 10; height: 10 anchors.rightMargin: 5
source: "../network.png" }
}
} RowLayout {
} id: peerGroup
y: 7
anchors.right: parent.right
property var blockModel: ListModel { MouseArea {
id: blockModel onDoubleClicked: peerWindow.visible = true
} anchors.fill: parent
}
SplitView {
property var views: []; Label {
id: peerLabel
id: mainSplit font.pixelSize: 8
anchors.fill: parent text: "0 / 0"
resizing: false }
Image {
function setView(view, menu) { id: peerImage
for(var i = 0; i < views.length; i++) { width: 10; height: 10
views[i].view.visible = false source: "../network.png"
}
views[i].menuItem.border.color = "#00000000" }
views[i].menuItem.color = "#00000000" }
}
view.visible = true
property var blockModel: ListModel {
menu.border.color = "#CCCCCC" id: blockModel
menu.color = "#FFFFFFFF" }
}
SplitView {
function addComponent(component, options) { property var views: [];
var view = mainView.createView(component, options)
view.visible = false id: mainSplit
view.anchors.fill = mainView anchors.fill: parent
resizing: false
if( !view.hasOwnProperty("iconSource") ) {
console.log("Could not load plugin. Property 'iconSourc' not found on view."); function setView(view, menu) {
return; for(var i = 0; i < views.length; i++) {
} views[i].view.visible = false
views[i].menuItem.setSelection(false)
var menuItem = menu.createMenuItem(view.iconSource, view, options); }
if( view.hasOwnProperty("menuItem") ) { view.visible = true
view.menuItem = menuItem;
} //menu.border.color = "#CCCCCC"
//menu.color = "#FFFFFFFF"
if( view.hasOwnProperty("onReady") ) { menu.setSelection(true)
view.onReady.call(view) }
}
function addComponent(view, options) {
if( options.active ) { view.visible = false
setView(view, menuItem) view.anchors.fill = mainView
}
if( !view.hasOwnProperty("iconSource") ) {
console.log("Could not load plugin. Property 'iconSourc' not found on view.");
return {view: view, menuItem: menuItem} return;
} }
/********************* var menuItem = menu.createMenuItem(view.iconSource, view, options);
* Main menu. if( view.hasOwnProperty("menuItem") ) {
********************/ view.menuItem = menuItem;
Rectangle { }
id: menu
Layout.minimumWidth: 180 if( view.hasOwnProperty("onReady") ) {
Layout.maximumWidth: 180 view.onReady.call(view)
anchors.top: parent.top }
color: "#ececec"
if( options.active ) {
Component { setView(view, menuItem)
id: menuItemTemplate }
Rectangle {
id: menuItem
property var view; return {view: view, menuItem: menuItem}
property var path; }
property alias title: label.text /*********************
property alias icon: icon.source * Main menu.
property alias secondaryTitle: secondary.text ********************/
Rectangle {
width: 180 id: menu
height: 28 Layout.minimumWidth: 180
border.color: "#00000000" Layout.maximumWidth: 180
border.width: 1 anchors.top: parent.top
radius: 5 color: "#ececec"
color: "#00000000"
Component {
anchors { id: menuItemTemplate
left: parent.left Rectangle {
leftMargin: 4 id: menuItem
} property var view;
property var path;
MouseArea {
anchors.fill: parent property alias title: label.text
onClicked: { property alias icon: icon.source
mainSplit.setView(view, menuItem) property alias secondaryTitle: secondary.text
} function setSelection(on) {
} sel.visible = on
}
Image {
id: icon width: 176
height: 20 height: 28
width: 20 color: "#00000000"
anchors {
left: parent.left anchors {
verticalCenter: parent.verticalCenter left: parent.left
leftMargin: 3 leftMargin: 4
} }
MouseArea {
anchors.fill: parent Rectangle {
onClicked: { id: sel
menuItem.closeApp() visible: false
} anchors.fill: parent
} color: "#00000000"
} Rectangle {
id: r
Text { anchors.fill: parent
id: label border.color: "#CCCCCC"
anchors { border.width: 1
left: icon.right radius: 5
verticalCenter: parent.verticalCenter color: "#FFFFFFFF"
leftMargin: 3 }
} Rectangle {
anchors {
color: "#0D0A01" top: r.top
font.pixelSize: 12 bottom: r.bottom
} right: r.right
}
Text { width: 10
id: secondary color: "#FFFFFFFF"
anchors {
right: parent.right Rectangle {
rightMargin: 8 anchors {
verticalCenter: parent.verticalCenter left: parent.left
} right: parent.right
color: "#AEADBE" top: parent.top
font.pixelSize: 12 }
} height: 1
color: "#CCCCCC"
}
function closeApp() {
if(this.view.hasOwnProperty("onDestroy")) { Rectangle {
this.view.onDestroy.call(this.view) anchors {
} left: parent.left
right: parent.right
this.view.destroy() bottom: parent.bottom
this.destroy() }
gui.removePlugin(this.path) height: 1
} color: "#CCCCCC"
} }
} }
}
function createMenuItem(icon, view, options) {
if(options === undefined) { MouseArea {
options = {}; anchors.fill: parent
} onClicked: {
mainSplit.setView(view, menuItem)
var section; }
switch(options.section) { }
case "ethereum":
section = menuDefault; Image {
break; id: icon
case "legacy": height: 20
section = menuLegacy; width: 20
break; anchors {
default: left: parent.left
section = menuApps; verticalCenter: parent.verticalCenter
break; leftMargin: 3
} }
MouseArea {
var comp = menuItemTemplate.createObject(section) anchors.fill: parent
onClicked: {
comp.view = view menuItem.closeApp()
comp.title = view.title }
comp.icon = view.iconSource }
/* }
if(view.secondary !== undefined) {
comp.secondary = view.secondary Text {
} id: label
*/ anchors {
left: icon.right
return comp verticalCenter: parent.verticalCenter
leftMargin: 3
/* }
if(options.canClose) {
//comp.closeButton.visible = options.canClose color: "#0D0A01"
} font.pixelSize: 12
*/ }
}
Text {
ColumnLayout { id: secondary
id: menuColumn anchors {
y: 10 right: parent.right
width: parent.width rightMargin: 8
anchors.left: parent.left verticalCenter: parent.verticalCenter
anchors.right: parent.right }
spacing: 3 color: "#AEADBE"
font.pixelSize: 12
Text { }
text: "ETHEREUM"
font.bold: true
anchors { function closeApp() {
left: parent.left if(this.view.hasOwnProperty("onDestroy")) {
leftMargin: 5 this.view.onDestroy.call(this.view)
} }
color: "#888888"
} this.view.destroy()
this.destroy()
ColumnLayout { gui.removePlugin(this.path)
id: menuDefault }
spacing: 3 }
anchors { }
left: parent.left
right: parent.right function createMenuItem(icon, view, options) {
} if(options === undefined) {
} options = {};
}
Text { var section;
text: "APPS" switch(options.section) {
font.bold: true case "ethereum":
anchors { section = menuDefault;
left: parent.left break;
leftMargin: 5 case "legacy":
} section = menuLegacy;
color: "#888888" break;
} default:
section = menuApps;
ColumnLayout { break;
id: menuApps }
spacing: 3
anchors { var comp = menuItemTemplate.createObject(section)
left: parent.left
right: parent.right comp.view = view
} comp.title = view.title
} comp.icon = view.iconSource
/*
Text { if(view.secondary !== undefined) {
text: "DEBUG" comp.secondary = view.secondary
font.bold: true }
anchors { */
left: parent.left
leftMargin: 5 return comp
}
color: "#888888" /*
} if(options.canClose) {
//comp.closeButton.visible = options.canClose
ColumnLayout { }
id: menuLegacy */
spacing: 3 }
anchors {
left: parent.left ColumnLayout {
right: parent.right id: menuColumn
} y: 10
} width: parent.width
} anchors.left: parent.left
} anchors.right: parent.right
spacing: 3
/*********************
* Main view Text {
********************/ text: "ETHEREUM"
Rectangle { font.bold: true
id: mainView anchors {
color: "#00000000" left: parent.left
leftMargin: 5
anchors.right: parent.right }
anchors.left: menu.right color: "#888888"
anchors.bottom: parent.bottom }
anchors.top: parent.top
ColumnLayout {
function createView(component) { id: menuDefault
var view = component.createObject(mainView) spacing: 3
anchors {
return view; left: parent.left
} right: parent.right
} }
}
}
Text {
text: "APPS"
/****************** font.bold: true
* Dialogs anchors {
*****************/ left: parent.left
FileDialog { leftMargin: 5
id: generalFileDialog }
property var callback; color: "#888888"
onAccepted: { }
var path = this.fileUrl.toString();
callback.call(this, path); ColumnLayout {
} id: menuApps
spacing: 3
function show(selectExisting, callback) { anchors {
generalFileDialog.callback = callback; left: parent.left
generalFileDialog.selectExisting = selectExisting; right: parent.right
}
this.open(); }
}
} Text {
text: "DEBUG"
font.bold: true
/****************** anchors {
* Wallet functions left: parent.left
*****************/ leftMargin: 5
function importApp(path) { }
var ext = path.split('.').pop() color: "#888888"
if(ext == "html" || ext == "htm") { }
eth.openHtml(path)
}else if(ext == "qml"){ ColumnLayout {
addPlugin(path, {canClose: true, section: "apps"}) id: menuLegacy
} spacing: 3
} anchors {
left: parent.left
right: parent.right
function setWalletValue(value) { }
walletValueLabel.text = value }
} }
}
function loadPlugin(name) {
console.log("Loading plugin" + name) /*********************
var view = mainView.addPlugin(name) * Main view
} ********************/
Rectangle {
function setPeers(text) { anchors.right: parent.right
peerLabel.text = text anchors.left: menu.right
} anchors.bottom: parent.bottom
anchors.top: parent.top
function addPeer(peer) { color: "#00000000"
// 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}) Rectangle {
} id: urlPane
height: 40
function resetPeers(){ color: "#00000000"
peerModel.clear() anchors {
} left: parent.left
right: parent.right
function timeAgo(unixTs){ leftMargin: 5
var lapsed = (Date.now() - new Date(unixTs*1000)) / 1000 rightMargin: 5
return (lapsed + " seconds ago") top: parent.top
} topMargin: 5
}
function convertToPretty(unixTs){ TextField {
var a = new Date(unixTs*1000); id: url
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; objectName: "url"
var year = a.getFullYear(); placeholderText: "DApp URL"
var month = months[a.getMonth()]; anchors {
var date = a.getDate(); left: parent.left
var hour = a.getHours(); right: parent.right
var min = a.getMinutes(); top: parent.top
var sec = a.getSeconds(); topMargin: 5
var time = date+' '+month+' '+year+' '+hour+':'+min+':'+sec ; rightMargin: 5
return time; leftMargin: 5
} }
/********************** Keys.onReturnPressed: {
* Windows addPlugin(this.text, {canClose: true, section: "apps"})
*********************/ }
Window { }
id: peerWindow
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint }
height: 200
width: 700 // Border
Rectangle { Rectangle {
anchors.fill: parent id: divider
property var peerModel: ListModel { anchors {
id: peerModel left: parent.left
} right: parent.right
TableView { top: urlPane.bottom
anchors.fill: parent }
id: peerTable z: -1
model: peerModel height: 1
TableViewColumn{width: 100; role: "ip" ; title: "IP" } color: "#CCCCCC"
TableViewColumn{width: 60; role: "port" ; title: "Port" } }
TableViewColumn{width: 140; role: "lastResponse"; title: "Last event" }
TableViewColumn{width: 100; role: "latency"; title: "Latency" } Rectangle {
TableViewColumn{width: 260; role: "version" ; title: "Version" } id: mainView
}
}
} anchors.right: parent.right
anchors.left: parent.left
Window { anchors.bottom: parent.bottom
id: aboutWin anchors.top: divider.bottom
visible: false
title: "About" function createView(component) {
minimumWidth: 350 var view = component.createObject(mainView)
maximumWidth: 350
maximumHeight: 200 return view;
minimumHeight: 200 }
}
Image { }
id: aboutIcon }
height: 150
width: 150
fillMode: Image.PreserveAspectFit /******************
smooth: true * Dialogs
source: "../facet.png" *****************/
x: 10 FileDialog {
y: 10 id: generalFileDialog
} property var callback;
onAccepted: {
Text { var path = this.fileUrl.toString();
anchors.left: aboutIcon.right callback.call(this, path);
anchors.leftMargin: 10 }
font.pointSize: 12
text: "<h2>Ethereal - Aitne</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Maran Hidskes<br>Viktor Trón<br>" function show(selectExisting, callback) {
} generalFileDialog.callback = callback;
} generalFileDialog.selectExisting = selectExisting;
Window { this.open();
id: txImportDialog }
minimumWidth: 270 }
maximumWidth: 270
maximumHeight: 50
minimumHeight: 50 /******************
TextField { * Wallet functions
id: txImportField *****************/
width: 170 function importApp(path) {
anchors.verticalCenter: parent.verticalCenter var ext = path.split('.').pop()
anchors.left: parent.left if(ext == "html" || ext == "htm") {
anchors.leftMargin: 10 eth.openHtml(path)
onAccepted: { }else if(ext == "qml"){
} addPlugin(path, {canClose: true, section: "apps"})
} }
Button { }
anchors.left: txImportField.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 5 function setWalletValue(value) {
text: "Import" walletValueLabel.text = value
onClicked: { }
eth.importTx(txImportField.text)
txImportField.visible = false function loadPlugin(name) {
} console.log("Loading plugin" + name)
} var view = mainView.addPlugin(name)
Component.onCompleted: { }
addrField.focus = true
} function setPeers(text) {
} peerLabel.text = text
}
Window {
id: addPeerWin function addPeer(peer) {
visible: false // We could just append the whole peer object but it cries if you try to alter them
minimumWidth: 230 peerModel.append({ip: peer.ip, port: peer.port, lastResponse:timeAgo(peer.lastSend), latency: peer.latency, version: peer.version})
maximumWidth: 230 }
maximumHeight: 50
minimumHeight: 50 function resetPeers(){
peerModel.clear()
TextField { }
id: addrField
anchors.verticalCenter: parent.verticalCenter function timeAgo(unixTs){
anchors.left: parent.left var lapsed = (Date.now() - new Date(unixTs*1000)) / 1000
anchors.leftMargin: 10 return (lapsed + " seconds ago")
placeholderText: "address:port" }
onAccepted: {
eth.connectToPeer(addrField.text) function convertToPretty(unixTs){
addPeerWin.visible = false var a = new Date(unixTs*1000);
} var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
} var year = a.getFullYear();
Button { var month = months[a.getMonth()];
anchors.left: addrField.right var date = a.getDate();
anchors.verticalCenter: parent.verticalCenter var hour = a.getHours();
anchors.leftMargin: 5 var min = a.getMinutes();
text: "Add" var sec = a.getSeconds();
onClicked: { var time = date+' '+month+' '+year+' '+hour+':'+min+':'+sec ;
eth.connectToPeer(addrField.text) return time;
addPeerWin.visible = false }
}
} /**********************
Component.onCompleted: { * Windows
addrField.focus = true *********************/
} 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: 100; role: "ip" ; title: "IP" }
TableViewColumn{width: 60; role: "port" ; title: "Port" }
TableViewColumn{width: 140; role: "lastResponse"; title: "Last event" }
TableViewColumn{width: 100; role: "latency"; title: "Latency" }
TableViewColumn{width: 260; role: "version" ; title: "Version" }
}
}
}
Window {
id: aboutWin
visible: false
title: "About"
minimumWidth: 350
maximumWidth: 350
maximumHeight: 200
minimumHeight: 200
Image {
id: aboutIcon
height: 150
width: 150
fillMode: Image.PreserveAspectFit
smooth: true
source: "../facet.png"
x: 10
y: 10
}
Text {
anchors.left: aboutIcon.right
anchors.leftMargin: 10
font.pointSize: 12
text: "<h2>Ethereal - Aitne</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Maran Hidskes<br>Viktor Trón<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: 230
maximumWidth: 230
maximumHeight: 50
minimumHeight: 50
TextField {
id: addrField
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 10
placeholderText: "address:port"
text: "54.76.56.74:30303"
onAccepted: {
eth.connectToPeer(addrField.text)
addPeerWin.visible = false
}
}
Button {
anchors.left: addrField.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 5
text: "Add"
onClicked: {
eth.connectToPeer(addrField.text)
addPeerWin.visible = false
}
}
Component.onCompleted: {
addrField.focus = true
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment