+ basic address book support

+ notify of new transactions
+ refresh transactions
! fixed a lot of transactions bugs
This commit is contained in:
Taegus
2018-12-26 10:12:42 +01:00
parent 655cd441b7
commit 3315677ede
13 changed files with 382 additions and 46 deletions

View File

@@ -4,10 +4,10 @@
* *
* To rebuild or modify this file with the latest versions of the included * To rebuild or modify this file with the latest versions of the included
* software please visit: * software please visit:
* https://datatables.net/download/#dt/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.18/b-1.5.4/b-html5-1.5.4/fc-3.2.5/fh-3.1.4/r-2.2.2/sc-1.5.0/sl-1.2.6 * https://datatables.net/download/#dt/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.18/b-1.5.4/b-colvis-1.5.4/b-html5-1.5.4/fc-3.2.5/fh-3.1.4/r-2.2.2/sc-1.5.0/sl-1.2.6
* *
* Included libraries: * Included libraries:
* JSZip 2.5.0, pdfmake 0.1.36, DataTables 1.10.18, Buttons 1.5.4, HTML5 export 1.5.4, FixedColumns 3.2.5, FixedHeader 3.1.4, Responsive 2.2.2, Scroller 1.5.0, Select 1.2.6 * JSZip 2.5.0, pdfmake 0.1.36, DataTables 1.10.18, Buttons 1.5.4, Column visibility 1.5.4, HTML5 export 1.5.4, FixedColumns 3.2.5, FixedHeader 3.1.4, Responsive 2.2.2, Scroller 1.5.0, Select 1.2.6
*/ */
/*! /*!
@@ -187,7 +187,7 @@ Z(n.defaults.column);n.models.oSettings={oFeatures:{bAutoWidth:null,bDeferRender
aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button", aoFooter:[],oPreviousSearch:{},aoPreSearchCols:[],aaSorting:null,aaSortingFixed:[],asStripeClasses:null,asDestroyStripes:[],sDestroyWidth:0,aoRowCallback:[],aoHeaderCallback:[],aoFooterCallback:[],aoDrawCallback:[],aoRowCreatedCallback:[],aoPreDrawCallback:[],aoInitComplete:[],aoStateSaveParams:[],aoStateLoadParams:[],aoStateLoaded:[],sTableId:"",nTable:null,nTHead:null,nTFoot:null,nTBody:null,nTableWrapper:null,bDeferLoading:!1,bInitialised:!1,aoOpenRows:[],sDom:null,searchDelay:null,sPaginationType:"two_button",
iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:k,oAjaxData:k,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==y(this)?1*this._iRecordsTotal: iStateDuration:0,aoStateSave:[],aoStateLoad:[],oSavedState:null,oLoadedState:null,sAjaxSource:null,sAjaxDataProp:null,bAjaxDataGet:!0,jqXHR:null,json:k,oAjaxData:k,fnServerData:null,aoServerParams:[],sServerMethod:null,fnFormatNumber:null,aLengthMenu:null,iDraw:0,bDrawing:!1,iDrawError:-1,_iDisplayLength:10,_iDisplayStart:0,_iRecordsTotal:0,_iRecordsDisplay:0,oClasses:{},bFiltered:!1,bSorted:!1,bSortCellsTop:null,oInit:null,aoDestroyCallback:[],fnRecordsTotal:function(){return"ssp"==y(this)?1*this._iRecordsTotal:
this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==y(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};n.ext=x={buttons:{}, this.aiDisplayMaster.length},fnRecordsDisplay:function(){return"ssp"==y(this)?1*this._iRecordsDisplay:this.aiDisplay.length},fnDisplayEnd:function(){var a=this._iDisplayLength,b=this._iDisplayStart,c=b+a,d=this.aiDisplay.length,e=this.oFeatures,f=e.bPaginate;return e.bServerSide?!1===f||-1===a?b+d:Math.min(b+a,this._iRecordsDisplay):!f||c>d||-1===a?d:c},oInstance:null,sInstance:null,iTabIndex:0,nScrollHead:null,nScrollFoot:null,aLastSort:[],oPlugins:{},rowIdFn:null,rowId:null};n.ext=x={buttons:{},
classes:{},build:"dt/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.18/b-1.5.4/b-html5-1.5.4/fc-3.2.5/fh-3.1.4/r-2.2.2/sc-1.5.0/sl-1.2.6",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:n.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:n.version};h.extend(x,{afnFiltering:x.search,aTypes:x.type.detect,ofnSearch:x.type.search,oSort:x.type.order,afnSortData:x.order,aoFeatures:x.feature,oApi:x.internal,oStdClasses:x.classes,oPagination:x.pager}); classes:{},build:"dt/jszip-2.5.0/pdfmake-0.1.36/dt-1.10.18/b-1.5.4/b-colvis-1.5.4/b-html5-1.5.4/fc-3.2.5/fh-3.1.4/r-2.2.2/sc-1.5.0/sl-1.2.6",errMode:"alert",feature:[],search:[],selector:{cell:[],column:[],row:[]},internal:{},legacy:{ajax:null},pager:{},renderer:{pageButton:{},header:{}},order:{},type:{detect:[],search:{},order:{}},_unique:0,fnVersionCheck:n.fnVersionCheck,iApiIndex:0,oJUIClasses:{},sVersion:n.version};h.extend(x,{afnFiltering:x.search,aTypes:x.type.detect,ofnSearch:x.type.search,oSort:x.type.order,afnSortData:x.order,aoFeatures:x.feature,oApi:x.internal,oStdClasses:x.classes,oPagination:x.pager});
h.extend(n.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled", h.extend(n.ext.classes,{sTable:"dataTable",sNoFooter:"no-footer",sPageButton:"paginate_button",sPageButtonActive:"current",sPageButtonDisabled:"disabled",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",
sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"", sSortableDesc:"sorting_desc_disabled",sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sFilterInput:"",sLengthSelect:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sHeaderTH:"",sFooterTH:"",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",
sJUIHeader:"",sJUIFooter:""});var Kb=n.ext.pager;h.extend(Kb,{simple:function(){return["previous","next"]},full:function(){return["first","previous","next","last"]},numbers:function(a,b){return[ia(a,b)]},simple_numbers:function(a,b){return["previous",ia(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ia(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ia(a,b),"last"]},_numbers:ia,numbers_length:7});h.extend(!0,n.ext.renderer,{pageButton:{_:function(a,b,c,d,e, sJUIHeader:"",sJUIFooter:""});var Kb=n.ext.pager;h.extend(Kb,{simple:function(){return["previous","next"]},full:function(){return["first","previous","next","last"]},numbers:function(a,b){return[ia(a,b)]},simple_numbers:function(a,b){return["previous",ia(a,b),"next"]},full_numbers:function(a,b){return["first","previous",ia(a,b),"next","last"]},first_last_numbers:function(a,b){return["first",ia(a,b),"last"]},_numbers:ia,numbers_length:7});h.extend(!0,n.ext.renderer,{pageButton:{_:function(a,b,c,d,e,
@@ -251,6 +251,18 @@ a.rows(c.rows,d.extend({selected:!0},h)).any()&&d.extend(h,{selected:!0});h=a.ro
a.namespace&&(a=b.oInit.buttons||g.defaults.buttons)&&!b._buttons&&(new r(b,a)).container()});g.ext.feature.push({fnInit:function(a){a=new g.Api(a);var b=a.init().buttons||g.defaults.buttons;return(new r(a,b)).container()},cFeature:"B"});return r}); a.namespace&&(a=b.oInit.buttons||g.defaults.buttons)&&!b._buttons&&(new r(b,a)).container()});g.ext.feature.push({fnInit:function(a){a=new g.Api(a);var b=a.init().buttons||g.defaults.buttons;return(new r(a,b)).container()},cFeature:"B"});return r});
/*!
Column visibility buttons for Buttons and DataTables.
2016 SpryMedia Ltd - datatables.net/license
*/
(function(f){"function"===typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(c){return f(c,window,document)}):"object"===typeof exports?module.exports=function(c,e){c||(c=window);e&&e.fn.dataTable||(e=require("datatables.net")(c,e).$);e.fn.dataTable.Buttons||require("datatables.net-buttons")(c,e);return f(e,c,c.document)}:f(jQuery,window,document)})(function(f,c,e,h){c=f.fn.dataTable;f.extend(c.ext.buttons,{colvis:function(b,a){return{extend:"collection",
text:function(a){return a.i18n("buttons.colvis","Column visibility")},className:"buttons-colvis",buttons:[{extend:"columnsToggle",columns:a.columns,columnText:a.columnText}]}},columnsToggle:function(b,a){return b.columns(a.columns).indexes().map(function(b){return{extend:"columnToggle",columns:b,columnText:a.columnText}}).toArray()},columnToggle:function(b,a){return{extend:"columnVisibility",columns:a.columns,columnText:a.columnText}},columnsVisibility:function(b,a){return b.columns(a.columns).indexes().map(function(b){return{extend:"columnVisibility",
columns:b,visibility:a.visibility,columnText:a.columnText}}).toArray()},columnVisibility:{columns:h,text:function(b,a,d){return d._columnText(b,d)},className:"buttons-columnVisibility",action:function(b,a,d,g){b=a.columns(g.columns);a=b.visible();b.visible(g.visibility!==h?g.visibility:!(a.length&&a[0]))},init:function(b,a,d){var g=this;a.attr("data-cv-idx",d.columns);b.on("column-visibility.dt"+d.namespace,function(a,c){c.bDestroying||c.nTable!=b.settings()[0].nTable||g.active(b.column(d.columns).visible())}).on("column-reorder.dt"+
d.namespace,function(c,g,e){1===b.columns(d.columns).count()&&(d.columns=f.inArray(d.columns,e.mapping),a.attr("data-cv-idx",d.columns),a.parent().children("[data-cv-idx]").sort(function(a,b){return 1*a.getAttribute("data-cv-idx")-1*b.getAttribute("data-cv-idx")}).appendTo(a.parent()))});this.active(b.column(d.columns).visible())},destroy:function(b,a,d){b.off("column-visibility.dt"+d.namespace).off("column-reorder.dt"+d.namespace)},_columnText:function(b,a){var d=b.column(a.columns).index(),c=b.settings()[0].aoColumns[d].sTitle.replace(/\n/g,
" ").replace(/<br\s*\/?>/gi," ").replace(/<select(.*?)<\/select>/g,"").replace(/<!\-\-.*?\-\->/g,"").replace(/<.*?>/g,"").replace(/^\s+|\s+$/g,"");return a.columnText?a.columnText(b,d,c):c}},colvisRestore:{className:"buttons-colvisRestore",text:function(b){return b.i18n("buttons.colvisRestore","Restore visibility")},init:function(b,a,d){d._visOriginal=b.columns().indexes().map(function(a){return b.column(a).visible()}).toArray()},action:function(b,a,d,c){a.columns().every(function(b){b=a.colReorder&&
a.colReorder.transpose?a.colReorder.transpose(b,"toOriginal"):b;this.visible(c._visOriginal[b])})}},colvisGroup:{className:"buttons-colvisGroup",action:function(b,a,d,c){a.columns(c.show).visible(!0,!1);a.columns(c.hide).visible(!1,!1);a.columns.adjust()},show:[],hide:[]}});return c.Buttons});
/*! /*!
HTML5 export buttons for Buttons and DataTables. HTML5 export buttons for Buttons and DataTables.
2016 SpryMedia Ltd - datatables.net/license 2016 SpryMedia Ltd - datatables.net/license

File diff suppressed because one or more lines are too long

View File

@@ -103,24 +103,29 @@ body.pg-loaded > .inner {
margin-right: 10px; margin-right: 10px;
} }
.modalBodyPassword { .modalBody {
margin: 20px; margin: 20px;
} }
#dlgGeneralError .modalBodyPassword { #dlgGeneralError .modalBody {
height: 100px; height: 100px;
} }
#dlgCreateWalletPassword .modalBodyPassword, #dlgDeleteAddressConfirm .modalBody {
#dlgCreateWalletPassword .modalBodyPassword { height: 100px;
}
#dlgCreateWalletPassword .modalBody,
#dlgCreateAddressAndName .modalBody {
height: 200px; height: 200px;
} }
#dlgSendWalletPassword .modalBodyPassword { #dlgSendWalletPassword .modalBody {
height: 300px; height: 300px;
} }
#dlgChangeWalletName .modalBodyPassword { #dlgChangeWalletName .modalBody,
#dlgChangeAddressName .modalBody {
height: 150px; height: 150px;
} }
@@ -136,6 +141,12 @@ body.pg-loaded > .inner {
right: 20px; right: 20px;
} }
.btn-dialog-cancel {
position: absolute;
bottom: 10px;
right: 80px;
}
.modalDialog { .modalDialog {
display: none; display: none;
border-bottom: 3px solid #7A1336 !important; border-bottom: 3px solid #7A1336 !important;
@@ -312,11 +323,14 @@ div.sidebar svg {
margin: 10px; margin: 10px;
} }
#noWalletsPresent { #noWalletsPresent,
#noAddressPresent {
font-size: 1.3em; font-size: 1.3em;
} }
div.noWalletsWrapper { div.noWalletsWrapper,
div.noAddressWrapper {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

View File

@@ -1,3 +1,54 @@
/*
* Table button styles
*/
.dt-button {
margin-left: 10px !important;
color: #ffffff !important;
background-color: #7A1336 !important;
border: 1px solid #450118 !important;
background-image: none !important;
}
.dt-button:hover,
.dt-button:focus,
.dt-button.active,
.open .dropdown-toggle.dt-button {
color: #ffffff !important;
background-color: #B01549 !important;
border: 1px solid #450118 !important;
background-image: none !important;
}
.dt-button.active,
.open .dropdown-toggle.dt-button.dt-button {
background-image: none !important;
}
.dt-button.disabled,
.dt-button[disabled],
fieldset[disabled] .dt-button,
.dt-button.disabled:hover,
.dt-button[disabled]:hover,
fieldset[disabled] .dt-button:hover,
.dt-button.disabled:focus,
.dt-button[disabled]:focus,
fieldset[disabled] .dt-button:focus,
.dt-button.disabled:active,
.dt-button[disabled]:active,
fieldset[disabled] .dt-button:active,
.dt-button.disabled.active,
.dt-button[disabled].active,
fieldset[disabled] .dt-button.active {
background-color: #7A1336 !important;
border-color: #450118 !important;
}
.dt-button .badge {
color: #7A1336 !important;
background-color: #ffffff !important;
}
/* /*
* Table styles * Table styles
*/ */

View File

@@ -0,0 +1,67 @@
<div id="walletsToolbar">
<button type="button" class="btn btn-etho" id="btnNewAddress"><i class="fas fa-plus"></i></button>
</div>
<div id="addressList" class="{{#if addressData.length}}addressWrapper{{else}}noAddressWrapper{{/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>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{{#addressData}}
<tr>
<th scope="row" class="colEdit"><button type="button" class="btn btn-etho btnChangAddressName" data-address="{{address}}" data-name="{{name}}">Edit</button></th>
<td>{{name}}</td>
<td><span class="textAddress">{{address}}</span></td>
<td><button type="button" class="btn btn-etho btnDeleteAddress" data-wallet="{{address}}"><i class="far fa-trash-alt"></i></button></td>
</tr>
{{/addressData}}
</tbody>
</table>
{{else}}
<div id="noAddressPresent">You don't have any addresses, create a new one</div>
{{/if}}
</div>
<div id="dlgCreateAddressAndName" class="modalDialog" data-iziModal-title="Create new address" data-iziModal-subtitle="Enter the name and the address" data-iziModal-icon="icon-home">
<div class="modalBody">
<div class="form-group">
<label for="addressName">Address Name:</label>
<input type="text" class="form-control" id="addressName">
</div>
<div class="form-group">
<label for="addressHash">Address Hash:</label>
<input type="text" class="form-control" id="addressHash">
</div>
<button type="button" class="btn btn-etho btn-dialog-confirm" id="btnCreateAddressConfirm">Confirm</button>
</div>
</div>
<!-- The modal to change address name -->
<div id="dlgChangeAddressName" class="modalDialog" data-iziModal-title="Address Name" data-iziModal-subtitle="Enter the name for this address" data-iziModal-icon="icon-home">
<div class="modalBody">
<div class="form-group">
<label for="usr">Type Name:</label>
<input type="text" class="form-control" id="inputAddressName">
</div>
<button type="button" class="btn btn-etho btn-dialog-confirm" id="btnChangeAddressNameConfirm">Confirm</button>
</div>
</div>
<!-- The modal for delete confirmation -->
<div id="dlgDeleteAddressConfirm" class="modalDialog" data-iziModal-title="Application Error" data-iziModal-subtitle="Something went wrong, don't kill the fish..." data-iziModal-icon="icon-home">
<div class="modalBody">
<div class="form-group">
<span>Do you really want to delete the address?</span>
</div>
<button type="button" class="btn btn-etho btn-dialog-cancel" id="btnDeleteAddressCancel">No</button>
<button type="button" class="btn btn-etho btn-dialog-confirm" id="btnDeleteAddressConfirm">Yes</button>
</div>
</div>

View File

@@ -60,7 +60,7 @@
<!-- The modal for wallet password --> <!-- The modal for wallet password -->
<div id="dlgSendWalletPassword" class="modalDialog" data-iziModal-title="Wallet Password" data-iziModal-subtitle="To send from this wallet, please enter the wallet password" data-iziModal-icon="icon-home"> <div id="dlgSendWalletPassword" class="modalDialog" data-iziModal-title="Wallet Password" data-iziModal-subtitle="To send from this wallet, please enter the wallet password" data-iziModal-icon="icon-home">
<div class="modalBodyPassword"> <div class="modalBody">
<div class="form-group sendTXInfo"> <div class="form-group sendTXInfo">
<i class="fas fa-wallet"></i> <i class="fas fa-wallet"></i>
<label>From address:</label><label id="fromAddressInfo"></label> <label>From address:</label><label id="fromAddressInfo"></label>
@@ -88,7 +88,7 @@
<!-- The modal for address list --> <!-- 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 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 class="modalBody" id="dlgAddressListBody">
</div> </div>
</div> </div>

View File

@@ -12,6 +12,7 @@
<th scope="col"></th> <th scope="col"></th>
<th scope="col">Name</th> <th scope="col">Name</th>
<th scope="col">Address</th> <th scope="col">Address</th>
<th scope="col"></th>
<th scope="col">Balance</th> <th scope="col">Balance</th>
</tr> </tr>
</thead> </thead>
@@ -34,7 +35,7 @@
<!-- 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">
<div class="modalBodyPassword"> <div class="modalBody">
<div class="form-group"> <div class="form-group">
<label for="usr">Type Password:</label> <label for="usr">Type Password:</label>
<input type="password" class="form-control" id="walletPasswordFirst"> <input type="password" class="form-control" id="walletPasswordFirst">
@@ -50,7 +51,7 @@
<!-- The modal to change wallet name --> <!-- The modal to change wallet name -->
<div id="dlgChangeWalletName" class="modalDialog" data-iziModal-title="Wallet Name" data-iziModal-subtitle="Enter the name for this address" data-iziModal-icon="icon-home"> <div id="dlgChangeWalletName" class="modalDialog" data-iziModal-title="Wallet Name" data-iziModal-subtitle="Enter the name for this address" data-iziModal-icon="icon-home">
<div class="modalBodyPassword"> <div class="modalBody">
<div class="form-group"> <div class="form-group">
<label for="usr">Type Name:</label> <label for="usr">Type Name:</label>
<input type="text" class="form-control" id="inputWalletName"> <input type="text" class="form-control" id="inputWalletName">

View File

@@ -60,6 +60,9 @@
<div class="sidebarIconWrapper iconSelected" id="mainNavBtnWalletsWrapper" data-tippy="Wallets" data-tippy-delay="500"> <div class="sidebarIconWrapper iconSelected" id="mainNavBtnWalletsWrapper" data-tippy="Wallets" data-tippy-delay="500">
<a class="sidebarIcon" id="mainNavBtnWallets" href="#"><i class="fas fa-wallet fa-2x"></i></a> <a class="sidebarIcon" id="mainNavBtnWallets" href="#"><i class="fas fa-wallet fa-2x"></i></a>
</div> </div>
<div class="sidebarIconWrapper iconSelected" id="mainNavBtnAddressBoookWrapper" data-tippy="Address Book" data-tippy-delay="500">
<a class="sidebarIcon" id="mainNavBtnAddressBoook" href="#"><i class="far fa-address-book fa-2x"></i></a>
</div>
<div class="sidebarIconWrapper" id="mainNavBtnSendWrapper" data-tippy="Send Funds" data-tippy-delay="500"> <div class="sidebarIconWrapper" id="mainNavBtnSendWrapper" data-tippy="Send Funds" data-tippy-delay="500">
<a class="sidebarIcon" id="mainNavBtnSend" href="#"><i class="fas fas fa-share-square fa-2x"></i></a> <a class="sidebarIcon" id="mainNavBtnSend" href="#"><i class="fas fas fa-share-square fa-2x"></i></a>
</div> </div>
@@ -84,6 +87,7 @@
require('./renderer/settings.js'); require('./renderer/settings.js');
require('./renderer/wallets.js'); require('./renderer/wallets.js');
require('./renderer/blockchain.js'); require('./renderer/blockchain.js');
require('./renderer/addressBook.js');
require('./renderer/transactions.js'); require('./renderer/transactions.js');
require('./renderer/tableTransactions.js'); require('./renderer/tableTransactions.js');
</script> </script>
@@ -91,7 +95,7 @@
<!-- The modal for general error --> <!-- The modal for general error -->
<div id="dlgGeneralError" class="modalDialog" data-iziModal-title="Application Error" data-iziModal-subtitle="Something went wrong, don't kill the fish..." data-iziModal-icon="icon-home"> <div id="dlgGeneralError" class="modalDialog" data-iziModal-title="Application Error" data-iziModal-subtitle="Something went wrong, don't kill the fish..." data-iziModal-icon="icon-home">
<div class="modalBodyPassword"> <div class="modalBody">
<div class="form-group"> <div class="form-group">
<span id="txtGeneralError"></span> <span id="txtGeneralError"></span>
</div> </div>

159
renderer/addressBook.js Normal file
View File

@@ -0,0 +1,159 @@
const {ipcRenderer} = require('electron');
class AddressBook {
constructor() {
}
setAddressName(address, name) {
console.log(address);
console.log(name);
var addressBook = ipcRenderer.sendSync('getJSONFile', 'addresses.json');
if (!addressBook) {
addressBook = { names: {} };
}
// set the wallet name from the dialog box
addressBook.names[address] = name;
ipcRenderer.sendSync('setJSONFile',
{
file: 'addresses.json',
data: addressBook
});
}
getAddressName(address) {
var addressBook = ipcRenderer.sendSync('getJSONFile', 'addresses.json');
if (!addressBook) {
addressBook = { names: {} };
}
// set the wallet name from the dialog box
return addressBook.names[address] || "";
}
getAddressList() {
var addressBook = ipcRenderer.sendSync('getJSONFile', 'addresses.json');
if (!addressBook) {
addressBook = { names: {} };
}
return addressBook.names;
}
deleteAddress(address) {
var addressBook = ipcRenderer.sendSync('getJSONFile', 'addresses.json');
if (!addressBook) {
addressBook = { names: {} };
} else {
delete addressBook.names[address];
}
ipcRenderer.sendSync('setJSONFile',
{
file: 'addresses.json',
data: addressBook
});
}
enableButtonTooltips() {
}
renderAddressBook() {
var addressObject = EthoAddressBook.getAddressList();
var renderData = { addressData: [] };
for (var key in addressObject) {
if (addressObject.hasOwnProperty(key)) {
var addressEntry = {};
addressEntry.name = addressObject[key];
addressEntry.address = key;
renderData.addressData.push(addressEntry);
}
}
// render the wallets current state
EthoMainGUI.renderTemplate("addressBook.html", renderData);
$(document).trigger("render_addressBook");
EthoAddressBook.enableButtonTooltips();
}
}
// the event to tell us that the wallets are rendered
$(document).on("render_addressBook", function() {
$("#btnNewAddress").off('click').on('click', function() {
$("#dlgCreateAddressAndName").iziModal();
$("#addressName").val("");
$("#addressHash").val("");
$('#dlgCreateAddressAndName').iziModal('open');
function doCreateNewWallet() {
$('#dlgCreateAddressAndName').iziModal('close');
EthoAddressBook.setAddressName($("#addressHash").val(), $("#addressName").val());
EthoAddressBook.renderAddressBook();
iziToast.success({
title: 'Created',
message: 'New address was successfully created',
position: 'topRight',
timeout: 5000
});
}
$("#btnCreateAddressConfirm").off('click').on('click', function() {
doCreateNewWallet();
});
$("#dlgCreateAddressAndName").off('keypress').on('keypress', function(e) {
if(e.which == 13) {
doCreateNewWallet();
}
});
});
$(".btnChangAddressName").off('click').on('click', function() {
var walletAddress = $(this).attr('data-address');
var walletName = $(this).attr('data-name');
$("#dlgChangeAddressName").iziModal();
$("#inputAddressName").val(walletName);
$('#dlgChangeAddressName').iziModal('open');
function doChangeAddressName() {
EthoAddressBook.setAddressName(walletAddress, $("#inputAddressName").val());
$('#dlgChangeAddressName').iziModal('close');
EthoAddressBook.renderAddressBook();
}
$("#btnChangeAddressNameConfirm").off('click').on('click', function() {
doChangeAddressName();
});
$("#dlgChangeAddressName").off('keypress').on('keypress', function(e) {
if(e.which == 13) {
doChangeAddressName();
}
});
});
$(".btnDeleteAddress").off('click').on('click', function() {
$("#dlgDeleteAddressConfirm").iziModal();
$('#dlgDeleteAddressConfirm').iziModal('open');
$("#btnDeleteAddressCancel").off('click').on('click', function() {
$('#dlgDeleteAddressConfirm').iziModal('close');
});
$("#btnDeleteAddressConfirm").off('click').on('click', function() {
EthoAddressBook.deleteAddress($(this).attr('data-address'));
$('#dlgDeleteAddressConfirm').iziModal('close');
EthoAddressBook.renderAddressBook();
});
});
});
EthoAddressBook = new AddressBook();

View File

@@ -14,7 +14,10 @@ class MainGUI {
case "account": case "account":
$("#mainNavBtnWalletsWrapper").addClass("iconSelected"); $("#mainNavBtnWalletsWrapper").addClass("iconSelected");
break; break;
case "send": case "addressBook":
$("#mainNavBtnAddressBoookWrapper").addClass("iconSelected");
break;
case "send":
$("#mainNavBtnSendWrapper").addClass("iconSelected"); $("#mainNavBtnSendWrapper").addClass("iconSelected");
break; break;
case "transactions": case "transactions":
@@ -69,6 +72,11 @@ $("#mainNavBtnTransactions").click(function() {
EthoTransactions.renderTransactions(); EthoTransactions.renderTransactions();
}); });
$("#mainNavBtnAddressBoook").click(function() {
EthoMainGUI.changeAppState("addressBook");
EthoAddressBook.renderAddressBook();
});
$("#mainNavBtnSend").click(function() { $("#mainNavBtnSend").click(function() {
EthoMainGUI.changeAppState("send"); EthoMainGUI.changeAppState("send");
EthoSend.renderSendState(); EthoSend.renderSendState();

View File

@@ -79,7 +79,7 @@ $(document).on("render_send", function() {
}, },
function(data) { function(data) {
$("#dlgAddressList").iziModal({ width: "800px" }); $("#dlgAddressList").iziModal({ width: "800px" });
EthoMainGUI.renderTemplate("addresslist.html", data, $("#dlgAddressListBody")); EthoMainGUI.renderTemplate("addressList.html", data, $("#dlgAddressListBody"));
$('#dlgAddressList').iziModal('open'); $('#dlgAddressList').iziModal('open');
$(".btnSelectToAddress").off('click').on('click', function() { $(".btnSelectToAddress").off('click').on('click', function() {

View File

@@ -7,12 +7,13 @@ class tableTransactions {
// register the sort datetime format // register the sort datetime format
$.fn.dataTable.moment('MMM Do YYYY HH:mm:ss'); $.fn.dataTable.moment('MMM Do YYYY HH:mm:ss');
var namesType = $.fn.dataTable.absoluteOrder( var namesType = $.fn.dataTable.absoluteOrderNumber(
[ [
{ value: null, position: 'top' } { value: null, position: 'top' }
]); ]);
// render the transactions // render the transactions
$(id).DataTable({ $(id).DataTable({
"dom": 'Bfrtip',
"paging": false, "paging": false,
"scrollY": "calc(100vh - 115px)", "scrollY": "calc(100vh - 115px)",
"responsive": true, "responsive": true,
@@ -20,6 +21,15 @@ class tableTransactions {
"order": [[ 1, "desc" ]], "order": [[ 1, "desc" ]],
"data": data, "data": data,
"oSearch": {"sSearch": EthoTransactions.getFilter() }, "oSearch": {"sSearch": EthoTransactions.getFilter() },
"buttons":
[
{
text: 'Refresh',
action: function ( e, dt, node, config ) {
EthoTransactions.renderTransactions();
}
}
],
"columnDefs": [ "columnDefs": [
{ {
"targets": 0, "targets": 0,

View File

@@ -119,22 +119,33 @@ $(document).on("onSyncInterval", function() {
counters = {}; counters = {};
} }
function finalizeCounters(lastBlock) {
counters.transactions = lastBlock;
ipcRenderer.sendSync('setJSONFile',
{
file: 'counters.json',
data: counters
});
}
function doSyncRemainingBlocks() { function doSyncRemainingBlocks() {
EthoBlockchain.getBlock("latest", false, EthoBlockchain.getBlock("latest", false,
function(error) { function(error) {
EthoMainGUI.showGeneralError(error); EthoMainGUI.showGeneralError(error);
}, },
function(block) { function(block) {
var lastBlock = counters.transactions || 0; var lastBlock = counters.transactions || 1;
if (lastBlock < block.number) { if (lastBlock < block.number) {
function getNextBlockTransactions(blockNumber, maxBlock) { function getNextBlockTransactions(blockNumber, maxBlock) {
EthoBlockchain.getBlock(blockNumber, true, if (blockNumber < maxBlock) {
function(error) { EthoBlockchain.getBlock(blockNumber, true,
EthoMainGUI.showGeneralError(error); function(error) {
}, EthoMainGUI.showGeneralError(error);
function(data) { getNextBlockTransactions(blockNumber + 1 , maxBlock);
if (blockNumber < maxBlock) { },
function(data) {
if (data.transactions) { if (data.transactions) {
data.transactions.forEach(element => { data.transactions.forEach(element => {
if ((EthoWallets.getAddressExists(element.from)) || (EthoWallets.getAddressExists(element.to))) { if ((EthoWallets.getAddressExists(element.from)) || (EthoWallets.getAddressExists(element.to))) {
@@ -151,34 +162,33 @@ $(document).on("onSyncInterval", function() {
ipcRenderer.send('storeTransaction', Transaction); ipcRenderer.send('storeTransaction', Transaction);
$(document).trigger("onNewAccountTransaction"); $(document).trigger("onNewAccountTransaction");
if (EthoMainGUI.getAppState() == "transactions") { iziToast.info({
//$('#tableTransactionsForAll').DataTable().ajax.reload(); title: 'New Transaction',
} message: vsprintf('Transaction from address %s to address %s was just processed', [Transaction.fromaddr, Transaction.toaddr]),
position: 'topRight',
timeout: 10000
});
} }
}); });
} }
// call the next iteration for the next block // call the next iteration for the next block
getNextBlockTransactions(blockNumber + 1 , maxBlock) getNextBlockTransactions(blockNumber + 1 , maxBlock);
} else {
setTimeout(function() {
doSyncRemainingBlocks();
}, 10000);
} }
);
} else {
finalizeCounters(blockNumber);
} setTimeout(function() {
); doSyncRemainingBlocks();
}, 10000);
}
} }
// call initial call of function // call initial call of function
getNextBlockTransactions(lastBlock, block.number); getNextBlockTransactions(lastBlock, block.number);
} else { } else {
counters.transactions = block.number; finalizeCounters(lastBlock);
ipcRenderer.sendSync('setJSONFile',
{
file: 'counters.json',
data: counters
});
setTimeout(function() { setTimeout(function() {
doSyncRemainingBlocks(); doSyncRemainingBlocks();