From 653d977130495a9e9c8188c2e4271fd9d4d80c8a Mon Sep 17 00:00:00 2001 From: Mohammed Saud Date: Sun, 6 Oct 2019 19:26:18 +0530 Subject: [PATCH 1/5] separate data from component --- webui-src/app/network/network.js | 31 +++--------------- webui-src/app/network/network_data.js | 45 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 webui-src/app/network/network_data.js diff --git a/webui-src/app/network/network.js b/webui-src/app/network/network.js index 3449848..a78d06e 100644 --- a/webui-src/app/network/network.js +++ b/webui-src/app/network/network.js @@ -1,6 +1,7 @@ let m = require('mithril'); let rs = require('rswebui'); let widget = require('widgets'); +let data = require('network_data'); const ConfirmRemove = () => { @@ -103,36 +104,14 @@ const SearchBar = () => { const Friends = () => { return { oninit: () => { - FriendNodes = {}; - rs.rsJsonApiRequest( - '/rsPeers/getFriendList', {}, - (friendListIds) => { - friendListIds.sslIds.map( - (sslId) => rs.rsJsonApiRequest( - '/rsPeers/getPeerDetails', { - sslId - }, - (details) => { - // Store nodes obj with gpg id as key - // single node can have multiple identities - if(FriendNodes[details.det.gpg_id] === undefined) - FriendNodes[details.det.gpg_id] = { - locations: [details.det], - isSearched: true - } - else - FriendNodes[details.det.gpg_id].locations.push( - details.det); - }) - ); - }); + data.refreshGpgDetails(); }, view: () => m('.widget', [ m('h3', 'Friend nodes'), m('hr'), - Object.keys(FriendNodes).map((id) => m(Node, { - data: FriendNodes[id].locations, - isSearched: FriendNodes[id].isSearched, + Object.keys(data.gpgDetails).map((id) => m(Node, { + data: data.gpgDetails[id].locations, + isSearched: data.gpgDetails[id].isSearched, })), ]), }; diff --git a/webui-src/app/network/network_data.js b/webui-src/app/network/network_data.js new file mode 100644 index 0000000..45c8540 --- /dev/null +++ b/webui-src/app/network/network_data.js @@ -0,0 +1,45 @@ +let rs = require('rswebui'); + +module.exports = { + sslIds: [], + sslDetails: [], + gpgDetails: {}, + + refreshIds() { + return rs.rsJsonApiRequest( + '/rsPeers/getFriendList', + {}, + data => (this.sslIds = data.sslIds), + ); + }, + + loadSslDetails() { + this.sslDetails = []; + + return Promise.all( + this.sslIds.map(sslId => + rs.rsJsonApiRequest('/rsPeers/getPeerDetails', {sslId}, data => + this.sslDetails.push(data.det), + ), + ), + ); + }, + + refreshGpgDetails() { + let details = {}; + + this.refreshIds() + .then(() => this.loadSslDetails()) + .then(() => { + this.sslDetails.map(data => { + if (details[data.gpg_id] === undefined) { + details[data.gpg_id] = {isSearched: true, locations: [data]}; + console.log(data); + } else { + details[data.gpg_id].locations.push(data); + } + }); + this.gpgDetails = details; + }); + }, +}; From 0fd9010dfc60de0c547bc82a55bb8cd4df9f1d29 Mon Sep 17 00:00:00 2001 From: Mohammed Saud Date: Sun, 6 Oct 2019 22:05:13 +0530 Subject: [PATCH 2/5] display last seen, online for each node separately --- webui-src/app/network/network.css | 3 + webui-src/app/network/network.js | 165 ++++++++++++++------------ webui-src/app/network/network_data.js | 36 ++++-- 3 files changed, 119 insertions(+), 85 deletions(-) diff --git a/webui-src/app/network/network.css b/webui-src/app/network/network.css index a3b62cf..b04c0f0 100644 --- a/webui-src/app/network/network.css +++ b/webui-src/app/network/network.css @@ -20,6 +20,9 @@ .friend button { font-size: 0.9em; } +.friend.hidden { + display: none; +} .friend .location { margin: 5px; diff --git a/webui-src/app/network/network.js b/webui-src/app/network/network.js index a78d06e..075641e 100644 --- a/webui-src/app/network/network.js +++ b/webui-src/app/network/network.js @@ -1,119 +1,128 @@ -let m = require('mithril'); -let rs = require('rswebui'); -let widget = require('widgets'); -let data = require('network_data'); +const m = require('mithril'); +const rs = require('rswebui'); +const widget = require('widgets'); +const Data = require('network_data'); const ConfirmRemove = () => { return { - view: (vnode) => [m('h3', 'Remove Friend'), + view: vnode => [ + m('h3', 'Remove Friend'), m('hr'), m('p', 'Are you sure you want to end connections with this node?'), - m('button', { - onclick: () => { - rs.rsJsonApiRequest('/rsPeers/removeFriend', { - pgpId: vnode.attrs.gpg - }); - m.redraw(); - } - }, 'Confirm'), + m( + 'button', + { + onclick: () => { + rs.rsJsonApiRequest('/rsPeers/removeFriend', { + pgpId: vnode.attrs.gpg_id, + }); + m.redraw(); + }, + }, + 'Confirm', + ), ], }; }; -const Node = () => { +const Locations = () => { + return { + view: v => [ + m('h4', 'Locations'), + v.attrs.locations.map(loc => + m('.location', [ + m('i.fas.fa-user-tag'), + m('span', loc.name), + m('p', 'ID :'), + m('p', loc.id), + m('p', 'Last contacted :'), + m('p', new Date(loc.lastSeen * 1000).toDateString()), + m('p', 'Online :'), + m('i.fas', { + class: loc.isOnline ? 'fa-check-circle' : 'fa-times-circle', + }), + m( + 'button.red', + { + onclick: () => + widget.popupMessage( + m(ConfirmRemove, { + gpg: loc.gpg_id, + }), + ), + }, + 'Remove node', + ), + ]), + ), + ], + }; +}; + +const Friend = () => { return { - isOnline: false, isExpanded: false, - oninit(v) { - v.state.isOnline = false; - // check if any one location is online - v.attrs.data.map(node => rs.rsJsonApiRequest( - '/rsPeers/isOnline', { - sslId: node.id - }, (data) => data.retval ? v.state.isOnline = true : undefined)); - }, - view: (vnode) => m('.friend', { - key: vnode.attrs.data[0].gpg_id, - style: "display:" + (vnode.attrs.isSearched ? "block" : "none"), + key: vnode.attrs.id, + class: Data.gpgDetails[vnode.attrs.id].isSearched ? "" : "hidden", }, [ m('i.fas.fa-angle-right', { class: 'fa-rotate-' + (vnode.state.isExpanded ? '90' : '0'), onclick: () => vnode.state.isExpanded = !vnode.state.isExpanded, }), m('i.fas.fa-2x.fa-user-circle'), - m('span', vnode.attrs.data[0].name), + m('span', Data.gpgDetails[vnode.attrs.id].name), m('i.fas', { - class: vnode.state.isOnline ? 'fa-check-circle' : 'fa-times-circle' + class: Data.gpgDetails[vnode.attrs.id].isOnline ? 'fa-check-circle' : 'fa-times-circle' }), m('.details', { style: "display:" + (vnode.state.isExpanded ? "block" : "none"), }, [ - m('.grid-2col', [ - m('p', 'Last contacted :'), - m('p', new Date(vnode.attrs.data[0].lastConnect * 1000).toDateString()), - m('p', 'Online :'), - m('i.fas', { - class: vnode.state.isOnline ? 'fa-check-circle' : 'fa-times-circle' - }), - ]), - m('h4', 'Locations'), - vnode.attrs.data.map((loc) => m('.location', [ - m('i.fas.fa-user-tag'), m('span', loc.location), - m('p', 'ID :'), - m('p', loc.id), - m('p', 'Online :'), - m('i.fas', { - class: vnode.state.isOnline ? 'fa-check-circle' : 'fa-times-circle' - }), - m('button.red', { - onclick: () => widget.popupMessage(m(ConfirmRemove, { - gpg: loc.gpg_id, - })) - }, 'Remove node'), - ])), + m(Locations, {locations: Data.gpgDetails[vnode.attrs.id].locations}), ]) ]), }; }; -let FriendNodes = {}; - -let searchString = ''; const SearchBar = () => { + let searchString = ''; return { - view: () => m('input[type=text][placeholder=search].searchbar', { - value: searchString, - oninput: (e) => { - searchString = e.target.value.toLowerCase(); - for(let id in FriendNodes) { - if(FriendNodes[id].locations[0].name.toLowerCase().indexOf( - searchString) > -1) { - FriendNodes[id].isSearched = true; - } else { - FriendNodes[id].isSearched = false; + view: () => + m('input.searchbar', { + type: 'text', + placeholder: 'search', + value: searchString, + oninput: e => { + searchString = e.target.value.toLowerCase(); + for (let id in Data.gpgDetails) { + if ( + Data.gpgDetails[id].name.toLowerCase().indexOf(searchString) > -1 + ) { + Data.gpgDetails[id].isSearched = true; + } else { + Data.gpgDetails[id].isSearched = false; + } } - } - }, - }) + }, + }), }; }; -const Friends = () => { +const FriendsList = () => { return { oninit: () => { - data.refreshGpgDetails(); + Data.refreshGpgDetails(); }, - view: () => m('.widget', [ - m('h3', 'Friend nodes'), - m('hr'), - Object.keys(data.gpgDetails).map((id) => m(Node, { - data: data.gpgDetails[id].locations, - isSearched: data.gpgDetails[id].isSearched, - })), - ]), + view: () => + m('.widget', [ + m('h3', 'Friend nodes'), + m('hr'), + Object.keys(Data.gpgDetails).map(id => + m(Friend, {id}), + ), + ]), }; }; @@ -121,7 +130,7 @@ const Layout = () => { return { view: () => m('.tab-page', [ m(SearchBar), - m(Friends), + m(FriendsList), ]) } }; diff --git a/webui-src/app/network/network_data.js b/webui-src/app/network/network_data.js index 45c8540..a2e67de 100644 --- a/webui-src/app/network/network_data.js +++ b/webui-src/app/network/network_data.js @@ -32,14 +32,36 @@ module.exports = { .then(() => this.loadSslDetails()) .then(() => { this.sslDetails.map(data => { - if (details[data.gpg_id] === undefined) { - details[data.gpg_id] = {isSearched: true, locations: [data]}; - console.log(data); - } else { - details[data.gpg_id].locations.push(data); - } + let isOnline = false; + rs.rsJsonApiRequest( + '/rsPeers/isOnline', + {sslId: data.id}, + stat => (isOnline = stat.retval), + ).then(() => { + loc = { + name: data.location, + id: data.id, + lastSeen: data.lastConnect, + isOnline, + gpg_id: data.gpg_id, + }; + + if (details[data.gpg_id] === undefined) { + details[data.gpg_id] = { + name: data.name, + isSearched: true, + isOnline, + locations: [loc], + }; + } else { + details[data.gpg_id].locations.push(loc); + } + details[data.gpg_id].isOnline = + details[data.gpg_id].isOnline || isOnline; + + this.gpgDetails = details; + }); }); - this.gpgDetails = details; }); }, }; From c1b21c4850ba462a648b6a3637e44953f269ff13 Mon Sep 17 00:00:00 2001 From: Mohammed Saud Date: Sun, 6 Oct 2019 22:42:36 +0530 Subject: [PATCH 3/5] improve display of online friends --- webui-src/app/network/network.css | 3 +++ webui-src/app/network/network.js | 9 ++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/webui-src/app/network/network.css b/webui-src/app/network/network.css index b04c0f0..b5a46cc 100644 --- a/webui-src/app/network/network.css +++ b/webui-src/app/network/network.css @@ -23,6 +23,9 @@ .friend.hidden { display: none; } +.friend .brief-info.online { + color: green; +} .friend .location { margin: 5px; diff --git a/webui-src/app/network/network.js b/webui-src/app/network/network.js index 075641e..b0f5287 100644 --- a/webui-src/app/network/network.js +++ b/webui-src/app/network/network.js @@ -72,11 +72,10 @@ const Friend = () => { class: 'fa-rotate-' + (vnode.state.isExpanded ? '90' : '0'), onclick: () => vnode.state.isExpanded = !vnode.state.isExpanded, }), - m('i.fas.fa-2x.fa-user-circle'), - m('span', Data.gpgDetails[vnode.attrs.id].name), - m('i.fas', { - class: Data.gpgDetails[vnode.attrs.id].isOnline ? 'fa-check-circle' : 'fa-times-circle' - }), + m('.brief-info',{class:Data.gpgDetails[vnode.attrs.id].isOnline?'online':''},[ + m('i.fas.fa-2x.fa-user-circle'), + m('span', Data.gpgDetails[vnode.attrs.id].name), + ]), m('.details', { style: "display:" + (vnode.state.isExpanded ? "block" : "none"), }, [ From bf82a165ae46971b47bf825c4d6f6d1d851dd9f0 Mon Sep 17 00:00:00 2001 From: Mohammed Saud Date: Sun, 6 Oct 2019 23:38:31 +0530 Subject: [PATCH 4/5] add visible online status theme --- webui-src/app/network/network.js | 71 +++++++++++++++++++------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/webui-src/app/network/network.js b/webui-src/app/network/network.js index b0f5287..f53fd4a 100644 --- a/webui-src/app/network/network.js +++ b/webui-src/app/network/network.js @@ -3,7 +3,6 @@ const rs = require('rswebui'); const widget = require('widgets'); const Data = require('network_data'); - const ConfirmRemove = () => { return { view: vnode => [ @@ -64,24 +63,39 @@ const Friend = () => { return { isExpanded: false, - view: (vnode) => m('.friend', { - key: vnode.attrs.id, - class: Data.gpgDetails[vnode.attrs.id].isSearched ? "" : "hidden", - }, [ - m('i.fas.fa-angle-right', { - class: 'fa-rotate-' + (vnode.state.isExpanded ? '90' : '0'), - onclick: () => vnode.state.isExpanded = !vnode.state.isExpanded, - }), - m('.brief-info',{class:Data.gpgDetails[vnode.attrs.id].isOnline?'online':''},[ - m('i.fas.fa-2x.fa-user-circle'), - m('span', Data.gpgDetails[vnode.attrs.id].name), - ]), - m('.details', { - style: "display:" + (vnode.state.isExpanded ? "block" : "none"), - }, [ - m(Locations, {locations: Data.gpgDetails[vnode.attrs.id].locations}), - ]) - ]), + view: vnode => + m( + '.friend', + { + key: vnode.attrs.id, + class: Data.gpgDetails[vnode.attrs.id].isSearched ? '' : 'hidden', + }, + [ + m('i.fas.fa-angle-right', { + class: 'fa-rotate-' + (vnode.state.isExpanded ? '90' : '0'), + onclick: () => (vnode.state.isExpanded = !vnode.state.isExpanded), + }), + m( + '.brief-info', + {class: Data.gpgDetails[vnode.attrs.id].isOnline ? 'online' : ''}, + [ + m('i.fas.fa-2x.fa-user-circle'), + m('span', Data.gpgDetails[vnode.attrs.id].name), + ], + ), + m( + '.details', + { + style: 'display:' + (vnode.state.isExpanded ? 'block' : 'none'), + }, + [ + m(Locations, { + locations: Data.gpgDetails[vnode.attrs.id].locations, + }), + ], + ), + ], + ), }; }; @@ -111,28 +125,27 @@ const SearchBar = () => { const FriendsList = () => { return { - oninit: () => { + oninit: () =>{ Data.refreshGpgDetails(); + //rs.setBackgroundTask( + // Data.refreshGpgDetails, + // 10000, + // () => m.route.get() === '/network', + //) }, view: () => m('.widget', [ m('h3', 'Friend nodes'), m('hr'), - Object.keys(Data.gpgDetails).map(id => - m(Friend, {id}), - ), + Object.keys(Data.gpgDetails).map(id => m(Friend, {id})), ]), }; }; const Layout = () => { return { - view: () => m('.tab-page', [ - m(SearchBar), - m(FriendsList), - ]) - } + view: () => m('.tab-page', [m(SearchBar), m(FriendsList)]), + }; }; module.exports = Layout; - From 93fa7c430e8a9f18d28a2a4cb449c2d732ccc0e6 Mon Sep 17 00:00:00 2001 From: Mohammed Saud Date: Tue, 8 Oct 2019 20:19:55 +0530 Subject: [PATCH 5/5] use Promises and awaits for fetching data --- webui-src/app/network/network_data.js | 131 +++++++++++++------------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/webui-src/app/network/network_data.js b/webui-src/app/network/network_data.js index a2e67de..0f5cff1 100644 --- a/webui-src/app/network/network_data.js +++ b/webui-src/app/network/network_data.js @@ -1,67 +1,70 @@ -let rs = require('rswebui'); +const rs = require('rswebui'); -module.exports = { - sslIds: [], - sslDetails: [], +const Data = { gpgDetails: {}, - - refreshIds() { - return rs.rsJsonApiRequest( - '/rsPeers/getFriendList', - {}, - data => (this.sslIds = data.sslIds), - ); - }, - - loadSslDetails() { - this.sslDetails = []; - - return Promise.all( - this.sslIds.map(sslId => - rs.rsJsonApiRequest('/rsPeers/getPeerDetails', {sslId}, data => - this.sslDetails.push(data.det), - ), - ), - ); - }, - - refreshGpgDetails() { - let details = {}; - - this.refreshIds() - .then(() => this.loadSslDetails()) - .then(() => { - this.sslDetails.map(data => { - let isOnline = false; - rs.rsJsonApiRequest( - '/rsPeers/isOnline', - {sslId: data.id}, - stat => (isOnline = stat.retval), - ).then(() => { - loc = { - name: data.location, - id: data.id, - lastSeen: data.lastConnect, - isOnline, - gpg_id: data.gpg_id, - }; - - if (details[data.gpg_id] === undefined) { - details[data.gpg_id] = { - name: data.name, - isSearched: true, - isOnline, - locations: [loc], - }; - } else { - details[data.gpg_id].locations.push(loc); - } - details[data.gpg_id].isOnline = - details[data.gpg_id].isOnline || isOnline; - - this.gpgDetails = details; - }); - }); - }); - }, + refreshGpgDetails, }; + +async function refreshIds() { + let sslIds = []; + await rs.rsJsonApiRequest( + '/rsPeers/getFriendList', + {}, + data => (sslIds = data.sslIds), + ); + return sslIds; +} + +async function loadSslDetails() { + let sslDetails = []; + let sslIds = await refreshIds(); + await Promise.all( + sslIds.map(sslId => + rs.rsJsonApiRequest('/rsPeers/getPeerDetails', {sslId}, data => + sslDetails.push(data.det), + ), + ), + ); + return sslDetails; +} + +async function refreshGpgDetails() { + let details = {}; + let sslDetails = await loadSslDetails(); + await Promise.all( + sslDetails.map(data => { + let isOnline = false; + return rs + .rsJsonApiRequest( + '/rsPeers/isOnline', + {sslId: data.id}, + stat => (isOnline = stat.retval), + ) + .then(() => { + loc = { + name: data.location, + id: data.id, + lastSeen: data.lastConnect, + isOnline, + gpg_id: data.gpg_id, + }; + + if (details[data.gpg_id] === undefined) { + details[data.gpg_id] = { + name: data.name, + isSearched: true, + isOnline, + locations: [loc], + }; + } else { + details[data.gpg_id].locations.push(loc); + } + details[data.gpg_id].isOnline = + details[data.gpg_id].isOnline || isOnline; + }); + }), + ); + Data.gpgDetails = details; +} + +module.exports = Data;