ZeroTierNode.jsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. var ZeroTierNode = React.createClass({
  2. getInitialState: function() {
  3. return {
  4. address: '----------',
  5. online: false,
  6. version: '_._._',
  7. _networks: [],
  8. _peers: []
  9. };
  10. },
  11. ago: function(ms) {
  12. if (ms > 0) {
  13. var tmp = Math.round((Date.now() - ms) / 1000);
  14. return ((tmp > 0) ? tmp : 0);
  15. } else return 0;
  16. },
  17. updatePeers: function() {
  18. Ajax.call({
  19. url: 'peer?auth='+this.props.authToken,
  20. cache: false,
  21. type: 'GET',
  22. success: function(data) {
  23. if (data) {
  24. var pl = JSON.parse(data);
  25. if (Array.isArray(pl)) {
  26. this.setState({_peers: pl});
  27. }
  28. }
  29. }.bind(this),
  30. error: function() {
  31. }.bind(this)
  32. });
  33. },
  34. updateNetworks: function() {
  35. Ajax.call({
  36. url: 'network?auth='+this.props.authToken,
  37. cache: false,
  38. type: 'GET',
  39. success: function(data) {
  40. if (data) {
  41. var nwl = JSON.parse(data);
  42. if (Array.isArray(nwl)) {
  43. this.setState({_networks: nwl});
  44. }
  45. }
  46. }.bind(this),
  47. error: function() {
  48. }.bind(this)
  49. });
  50. },
  51. updateAll: function() {
  52. Ajax.call({
  53. url: 'status?auth='+this.props.authToken,
  54. cache: false,
  55. type: 'GET',
  56. success: function(data) {
  57. if (data)
  58. this.setState(JSON.parse(data));
  59. this.updateNetworks();
  60. this.updatePeers();
  61. }.bind(this),
  62. error: function() {
  63. this.setState({online: false});
  64. }.bind(this)
  65. });
  66. },
  67. joinNetwork: function(event) {
  68. event.preventDefault();
  69. alert('foo');
  70. },
  71. handleNetworkIdEntry: function(event) {
  72. var nid = event.target.value;
  73. if (nid) {
  74. nid = nid.toLowerCase();
  75. var nnid = '';
  76. for(var i=0;((i<nid.length)&&(i<16));++i) {
  77. if ("0123456789abcdef".indexOf(nid.charAt(i)) >= 0)
  78. nnid += nid.charAt(i);
  79. }
  80. this.networkToJoin = nnid;
  81. event.target.value = nnid;
  82. } else {
  83. this.networkToJoin = '';
  84. event.target.value = '';
  85. }
  86. },
  87. componentDidMount: function() {
  88. this.tabIndex = 0;
  89. this.updateAll();
  90. this.updateIntervalId = setInterval(this.updateAll,2500);
  91. },
  92. componentWillUnmount: function() {
  93. clearInterval(this.updateIntervalId);
  94. },
  95. render: function() {
  96. return (
  97. <div className="zeroTierNode">
  98. <div className="top">&nbsp;&nbsp;
  99. <button disabled={this.tabIndex === 0} onClick={function() {this.tabIndex = 0; this.forceUpdate();}.bind(this)}>Networks</button>
  100. <button disabled={this.tabIndex === 1} onClick={function() {this.tabIndex = 1; this.forceUpdate();}.bind(this)}>Peers</button>
  101. </div>
  102. <div className="middle">
  103. <div className="middleScroll">
  104. {
  105. (this.tabIndex === 1) ? (
  106. <div className="peers">
  107. <div className="peerHeader">
  108. <div className="f">Address</div>
  109. <div className="f">Version</div>
  110. <div className="f">Latency</div>
  111. <div className="f">Direct&nbsp;Paths</div>
  112. <div className="f">Role</div>
  113. </div>
  114. {
  115. this.state._peers.map(function(peer) {
  116. return (
  117. <div className="peer">
  118. <div className="f zeroTierAddress">{peer['address']}</div>
  119. <div className="f">{(peer['version'] === '-1.-1.-1') ? '-' : peer['version']}</div>
  120. <div className="f">{peer['latency']}</div>
  121. <div className="f">
  122. {
  123. (peer['paths'].length === 0) ? (
  124. <div className="peerPath"><i>(none)</i></div>
  125. ) : (
  126. <div>
  127. {
  128. peer['paths'].map(function(path) {
  129. if ((path.active)||(path.fixed)) {
  130. return (
  131. <div className="peerPath">{path.address}&nbsp;{this.ago(path.lastSend)}&nbsp;{this.ago(path.lastReceive)}{path.preferred ? ' *' : ''}</div>
  132. );
  133. } else {
  134. return (
  135. <div className="peerPathInactive">{path.address}&nbsp;{this.ago(path.lastSend)}&nbsp;{this.ago(path.lastReceive)}</div>
  136. );
  137. }
  138. }.bind(this))
  139. }
  140. </div>
  141. )
  142. }
  143. </div>
  144. <div className="f">{peer['role']}</div>
  145. </div>
  146. );
  147. }.bind(this))
  148. }
  149. </div>
  150. ) : (
  151. <div className="networks">
  152. {
  153. this.state._networks.map(function(network) {
  154. return React.createElement('div',{className: 'network'},React.createElement(ZeroTierNetwork,network));
  155. }.bind(this))
  156. }
  157. </div>
  158. )
  159. }
  160. </div>
  161. </div>
  162. <div className="bottom">
  163. <div className="left">
  164. <span className="statusLine"><span className="zeroTierAddress">{this.state.address}</span>&nbsp;&nbsp;{this.state.online ? 'ONLINE' : 'OFFLINE'}&nbsp;&nbsp;{this.state.version}</span>
  165. </div>
  166. <div className="right">
  167. <form onSubmit={this.joinNetwork}><input type="text" placeholder="################" onChange={this.handleNetworkIdEntry} size="16"/><button type="submit">Join</button></form>
  168. </div>
  169. </div>
  170. </div>
  171. );
  172. }
  173. });