+ address list for recipient
+ filter table helper * copy address simply by clicking on it
This commit is contained in:
@@ -124,6 +124,12 @@ body.pg-loaded > .inner {
|
|||||||
height: 150px;
|
height: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#dlgAddressListBody {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-dialog-confirm {
|
.btn-dialog-confirm {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
@@ -316,6 +322,18 @@ div.noWalletsWrapper {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btnCopyWalletAddress {
|
.textAddress {
|
||||||
margin-right: 10px;
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.addressInputWrapper {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#addressToolbar {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#addressListFilter {
|
||||||
|
color: #aaa;
|
||||||
}
|
}
|
||||||
28
assets/templates/addresslist.html
Normal file
28
assets/templates/addresslist.html
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<div id="addressToolbar">
|
||||||
|
<input id="addressListFilter" placeholder="enter search text" type="text">
|
||||||
|
<button type="button" class="btn btn-etho" id="btnClearSearchField"><i class="far fa-trash-alt"></i></button>
|
||||||
|
</div>
|
||||||
|
<div id="addressList" class="{{#if addressData.length}}walletsWrapper{{else}}noWalletsWrapper{{/if}}">
|
||||||
|
{{#if addressData.length}}
|
||||||
|
<table class="bordered" id="addressTable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col"></th>
|
||||||
|
<th scope="col">Name</th>
|
||||||
|
<th scope="col">Address</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#addressData}}
|
||||||
|
<tr>
|
||||||
|
<th scope="row" class="colEdit"><button type="button" class="btn btn-etho btnSelectToAddress" data-wallet="{{address}}">Select</button></th>
|
||||||
|
<td>{{name}}</td>
|
||||||
|
<td><span class="textAddress">{{address}}</span></td>
|
||||||
|
</tr>
|
||||||
|
{{/addressData}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{else}}
|
||||||
|
<div id="noWalletsPresent">You don't have any wallets, please import them, or create a new one</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
@@ -11,9 +11,10 @@
|
|||||||
</select>
|
</select>
|
||||||
<label for="sendFromAddress">From address:</label>
|
<label for="sendFromAddress">From address:</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-field col s6">
|
<div class="input-field col s6 addressInputWrapper">
|
||||||
<input id="sendToAddress" placeholder="recipient address" type="text">
|
<input id="sendToAddress" placeholder="recipient address" type="text">
|
||||||
<label for="sendToAddress" class="active">To address:</label>
|
<label for="sendToAddress" class="active">To address:</label>
|
||||||
|
<button type="button" class="btn btn-etho addressLookup" id="btnLookForToAddress"><i class="fas fa-search"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -84,3 +85,10 @@
|
|||||||
<button type="button" class="btn btn-etho btn-dialog-confirm" id="btnSendWalletPasswordConfirm">Confirm</button>
|
<button type="button" class="btn btn-etho btn-dialog-confirm" id="btnSendWalletPasswordConfirm">Confirm</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- The modal for address list -->
|
||||||
|
<div id="dlgAddressList" class="modalDialog" data-iziModal-title="AddressList" data-iziModal-subtitle="Please select an address from the list" data-iziModal-icon="icon-home">
|
||||||
|
<div class="modalBodyPassword" id="dlgAddressListBody">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th scope="row" class="colEdit"><button type="button" class="btn btn-etho btnChangWalletName" data-wallet="{{address}}" data-name="{{name}}">Edit</button></th>
|
<th scope="row" class="colEdit"><button type="button" class="btn btn-etho btnChangWalletName" data-wallet="{{address}}" data-name="{{name}}">Edit</button></th>
|
||||||
<td>{{name}}</td>
|
<td>{{name}}</td>
|
||||||
<td><button type="button" class="btn btn-etho btnCopyWalletAddress" data-wallet="{{address}}"><i class="far fa-copy"></i></button><span class="textAddress">{{address}}</span></td>
|
<td><span class="textAddress">{{address}}</span></td>
|
||||||
<td>{{balance}}</td>
|
<td>{{balance}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{/addressData}}
|
{{/addressData}}
|
||||||
@@ -28,8 +28,6 @@
|
|||||||
<div id="noWalletsPresent">You don't have any wallets, please import them, or create a new one</div>
|
<div id="noWalletsPresent">You don't have any wallets, please import them, or create a new one</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div id="transactionList">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- The modal for new wallet -->
|
<!-- The modal for new wallet -->
|
||||||
<div id="dlgCreateWalletPassword" class="modalDialog" data-iziModal-title="Wallet Password" data-iziModal-subtitle="Make sure to write it down or remember it!!!" data-iziModal-icon="icon-home">
|
<div id="dlgCreateWalletPassword" class="modalDialog" data-iziModal-title="Wallet Password" data-iziModal-subtitle="Make sure to write it down or remember it!!!" data-iziModal-icon="icon-home">
|
||||||
|
|||||||
4
main.js
4
main.js
@@ -12,8 +12,8 @@ function createWindow () {
|
|||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 800,
|
height: 800,
|
||||||
minWidth: 1000,
|
minWidth: 1100,
|
||||||
minHeight: 800,
|
minHeight: 700,
|
||||||
backgroundColor: "#000000"
|
backgroundColor: "#000000"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
12
package.json
12
package.json
@@ -13,16 +13,14 @@
|
|||||||
"appId": "Ether1DesktopWallet",
|
"appId": "Ether1DesktopWallet",
|
||||||
"win": {
|
"win": {
|
||||||
"icon": "build/icon.png",
|
"icon": "build/icon.png",
|
||||||
"target": "portable"
|
"target": "7z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"repository": "https://github.com/electron/electron-quick-start",
|
"repository": "https://github.com/taeguscromis/Ether1DesktopWallet",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Electron",
|
"Ether1",
|
||||||
"quick",
|
"Desktop",
|
||||||
"start",
|
"Wallet"
|
||||||
"tutorial",
|
|
||||||
"demo"
|
|
||||||
],
|
],
|
||||||
"author": "Ether1",
|
"author": "Ether1",
|
||||||
"license": "CC0-1.0",
|
"license": "CC0-1.0",
|
||||||
|
|||||||
@@ -164,6 +164,34 @@ class Blockchain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAddressListData(clbError, clbSuccess) {
|
||||||
|
var rendererData = {};
|
||||||
|
rendererData.addressData = [];
|
||||||
|
|
||||||
|
var wallets = ipcRenderer.sendSync('getJSONFile', 'wallets.json');
|
||||||
|
var counter = 0;
|
||||||
|
|
||||||
|
web3Local.eth.getAccounts(function(err, res) {
|
||||||
|
if (err) {
|
||||||
|
clbError(err);
|
||||||
|
} else {
|
||||||
|
for (var i = 0; i < res.length; i++) {
|
||||||
|
var walletName = vsprintf("Account %d", [i + 1]);
|
||||||
|
if (wallets) {
|
||||||
|
walletName = wallets.names[res[i]] || walletName;
|
||||||
|
}
|
||||||
|
|
||||||
|
var addressInfo = {};
|
||||||
|
addressInfo.address = res[i];
|
||||||
|
addressInfo.name = walletName;
|
||||||
|
rendererData.addressData.push(addressInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
clbSuccess(rendererData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
createNewAccount(password, clbError, clbSuccess) {
|
createNewAccount(password, clbError, clbSuccess) {
|
||||||
web3Local.eth.personal.newAccount(password, function(error, account) {
|
web3Local.eth.personal.newAccount(password, function(error, account) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|||||||
@@ -43,11 +43,15 @@ class MainGUI {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTemplate(template, data) {
|
renderTemplate(template, data, container) {
|
||||||
var template = Handlebars.compile(ipcRenderer.sendSync('getTemplateContent', template));
|
var template = Handlebars.compile(ipcRenderer.sendSync('getTemplateContent', template));
|
||||||
|
|
||||||
$("#mainContent").empty();
|
if (!container) {
|
||||||
$("#mainContent").html(template(data));
|
container = $("#mainContent")
|
||||||
|
}
|
||||||
|
|
||||||
|
container.empty();
|
||||||
|
container.html(template(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
copyToClipboard(text) {
|
copyToClipboard(text) {
|
||||||
|
|||||||
@@ -66,48 +66,6 @@ $(document).on("render_send", function() {
|
|||||||
web3Local.eth.getBalance(this.value, function(error, balance) {
|
web3Local.eth.getBalance(this.value, function(error, balance) {
|
||||||
$("#sendMaxAmmount").html(parseFloat(web3Local.utils.fromWei(balance, 'ether')));
|
$("#sendMaxAmmount").html(parseFloat(web3Local.utils.fromWei(balance, 'ether')));
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
// list all transactions for this address
|
|
||||||
if (this.value) {
|
|
||||||
$("#cardTransactionsForAddress").css("display", "block");
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
// render the transactions
|
|
||||||
$('#tableTransactionsForAddress').DataTable({
|
|
||||||
"paging": false,
|
|
||||||
"scrollY": "calc(100vh - 115px)",
|
|
||||||
"responsive": true,
|
|
||||||
"processing": true,
|
|
||||||
"order": [[ 0, "desc" ]],
|
|
||||||
"data": ipcRenderer.sendSync('getTransactions', this.value),
|
|
||||||
"columnDefs": [
|
|
||||||
{
|
|
||||||
"className": "transactionsBlockNum",
|
|
||||||
"targets": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"targets": 1,
|
|
||||||
"render": function ( data, type, row ) {
|
|
||||||
return moment(data).format("MMM Do YYYY");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"targets": 4,
|
|
||||||
"render": function ( data, type, row ) {
|
|
||||||
return parseFloat(web3Local.utils.fromWei(EthoUtils.toFixed(parseFloat(data)).toString(), 'ether')).toFixed(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"drawCallback": function( settings ) {
|
|
||||||
$("#loadingTransactionsOverlay").css("display", "none");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 200);
|
|
||||||
} else {
|
|
||||||
$("#cardTransactionsForAddress").css("display", "none");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#btnSendAll").off('click').on('click', function() {
|
$("#btnSendAll").off('click').on('click', function() {
|
||||||
@@ -115,6 +73,33 @@ $(document).on("render_send", function() {
|
|||||||
$("#sendAmmount").val($("#sendMaxAmmount").html());
|
$("#sendAmmount").val($("#sendMaxAmmount").html());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$("#btnLookForToAddress").off('click').on('click', function() {
|
||||||
|
EthoBlockchain.getAddressListData(
|
||||||
|
function(error) {
|
||||||
|
EthoMainGUI.showGeneralError(error);
|
||||||
|
},
|
||||||
|
function(data) {
|
||||||
|
$("#dlgAddressList").iziModal({ width: "800px" });
|
||||||
|
EthoMainGUI.renderTemplate("addresslist.html", data, $("#dlgAddressListBody"));
|
||||||
|
$('#dlgAddressList').iziModal('open');
|
||||||
|
|
||||||
|
$(".btnSelectToAddress").off('click').on('click', function() {
|
||||||
|
$("#sendToAddress").val($(this).attr('data-wallet'));
|
||||||
|
$('#dlgAddressList').iziModal('close');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#addressListFilter').off('input').on('input',function(e){
|
||||||
|
EthoUtils.filterTable($("#addressTable"), $('#addressListFilter').val());
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#btnClearSearchField").off('click').on('click', function() {
|
||||||
|
EthoUtils.filterTable($("#addressTable"), "");
|
||||||
|
$('#addressListFilter').val("")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
$("#btnSendTransaction").off('click').on('click', function() {
|
$("#btnSendTransaction").off('click').on('click', function() {
|
||||||
if (EthoSend.validateSendForm()) {
|
if (EthoSend.validateSendForm()) {
|
||||||
EthoBlockchain.getTranasctionFee($("#sendFromAddress").val(), $("#sendToAddress").val(), $("#sendAmmount").val(),
|
EthoBlockchain.getTranasctionFee($("#sendFromAddress").val(), $("#sendToAddress").val(), $("#sendAmmount").val(),
|
||||||
|
|||||||
@@ -18,6 +18,27 @@ class Utils {
|
|||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filterTable(table, text) {
|
||||||
|
// Declare variables
|
||||||
|
var filter, tr, td, i, txtValue;
|
||||||
|
filter = text.toUpperCase();
|
||||||
|
tr = $(table).find("tr");
|
||||||
|
|
||||||
|
// Loop through all table rows, and hide those who don't match the search query
|
||||||
|
for (i = 0; i < tr.length; i++) {
|
||||||
|
td = $(tr[i]).find("td")[0];
|
||||||
|
|
||||||
|
if (td) {
|
||||||
|
txtValue = td.textContent || td.innerText;
|
||||||
|
if (txtValue.toUpperCase().indexOf(filter) > -1) {
|
||||||
|
$(tr[i]).css("display", "");
|
||||||
|
} else {
|
||||||
|
$(tr[i]).css("display", "none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EthoUtils = new Utils();
|
EthoUtils = new Utils();
|
||||||
@@ -63,7 +63,7 @@ renderWalletsState() {
|
|||||||
$(document).trigger("render_wallets");
|
$(document).trigger("render_wallets");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the event to tell us that the wallets are rendered
|
// the event to tell us that the wallets are rendered
|
||||||
@@ -142,8 +142,8 @@ $(document).on("render_wallets", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".btnCopyWalletAddress").off('click').on('click', function() {
|
$(".textAddress").off('click').on('click', function() {
|
||||||
EthoMainGUI.copyToClipboard($(this).attr('data-wallet'));
|
EthoMainGUI.copyToClipboard($(this).html());
|
||||||
|
|
||||||
iziToast.success({
|
iziToast.success({
|
||||||
title: 'Copied',
|
title: 'Copied',
|
||||||
|
|||||||
Reference in New Issue
Block a user