From 408d5bf7753a7fe7879a2593f1b3e917b435abe5 Mon Sep 17 00:00:00 2001 From: dr|z3d Date: Wed, 11 Aug 2021 19:41:54 +0000 Subject: [PATCH] More webconsole UI refinements --- daemon/HTTPServer.cpp | 94 ++++++++++++++++++++---------- libi2pd/Tunnel.cpp | 12 ++-- webconsole/style.css | 132 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 178 insertions(+), 60 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 38225450..c9f477e4 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -559,12 +559,12 @@ namespace http { s << ""; } /* - s << "" << "HTTP " << tr("Proxy") << "" << (httpproxy ? tr("Enabled") : tr("Disabled")) << "\r\n"; - s << "" << "SOCKS " << tr("Proxy") << "" << (socksproxy ? tr("Enabled") : tr("Disabled")) << "\r\n"; - s << "" << "BOB" << "" << (bob ? tr("Enabled") : tr("Disabled")) << "\r\n"; - s << "" << "SAM" << "" << (sam ? tr("Enabled") : tr("Disabled")) << "\r\n"; - s << "" << "I2CP" << "" << (i2cp ? tr("Enabled") : tr("Disabled")) << "\r\n"; - s << "" << "I2PControl" << "" << (i2pcontrol ? tr("Enabled") : tr("Disabled")) << "\r\n"; + s << "" << "HTTP " << tr("Proxy") << "" << (socksproxy ? tr("Enabled") : tr("Disabled")) << "\r\n"; + s << "" << "BOB" << "" << (sam ? tr("Enabled") : tr("Disabled")) << "\r\n"; + s << "" << "I2CP" << "" << (i2pcontrol ? tr("Enabled") : tr("Disabled")) << "\r\n"; */ } @@ -606,7 +606,7 @@ namespace http { { s << "\r\n"; s << "
\r\n" - << "\r\n"; + << "\r\n"; s << "
\r\n
"; s << dest->GetIdentity ()->ToBase64 () << "
\r\n
\r\n
\r\n\r\n"; if (dest->IsEncryptedLeaseSet ()) @@ -637,7 +637,9 @@ namespace http { { s << "\r\n"; s << "
\r\n\r\n" - << "\r\n"; + << "\r\n"; s << "
\r\n\r\n\r\n" << "" << "" @@ -657,18 +659,24 @@ namespace http { { s << "\r\n"; out_tags += it.second->GetNumOutgoingTags (); } - s << "\r\n" + s << "\r\n" << "\r\n"; @@ -710,7 +726,9 @@ namespace http { auto numECIESx25519Tags = dest->GetNumIncomingECIESx25519Tags (); if (numECIESx25519Tags > 0) { - s << "\r\n"; + s << "\r\n"; if (!dest->GetECIESx25519Sessions ().empty ()) { std::stringstream tmp_s; uint32_t ecies_sessions = 0; @@ -722,8 +740,9 @@ namespace http { } s << "
" << tr("Address") << "" << tr("Type") << "
\r\n"; s << "
\r\n\r\n" - << "\r\n"; + << "\r\n"; s << "
\r\n
\r\n"; for (auto & it : pool->GetInboundTunnels ()) { // inbound tunnels s << "
" << "[" << tr("In") << "] " << ""; it->Print(s); - if(it->LatencyIsKnown()) - s << " " - << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << ""; - else // placeholder for alignment + if(it->LatencyIsKnown()) { + s << " "; + if (it->GetMeanLatency() >= 1000) { + s << std::fixed << std::setprecision(2); + s << (double) it->GetMeanLatency() / 1000 << tr(/* tr: seconds */ "s") << ""; + } else { + s << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << ""; + } + } else { // placeholder for alignment s << " ---"; + } ShowTunnelDetails(s, it->GetState (), false, it->GetNumReceivedBytes ()); s << "
\r\n"; } @@ -677,11 +685,17 @@ namespace http { << "[" << tr("Out") << "] " << ""; it->Print(s); - if(it->LatencyIsKnown()) - s << " " - << it->GetMeanLatency() << tr("ms") << ""; - else // placeholder for alignment + if(it->LatencyIsKnown()) { + s << " "; + if (it->GetMeanLatency() >= 1000) { + s << std::fixed << std::setprecision(2); + s << (double) it->GetMeanLatency() / 1000 << tr(/* tr: seconds */ "s") << ""; + } else { + s << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << ""; + } + } else { // placeholder for alignment s << " ---"; + } ShowTunnelDetails(s, it->GetState (), false, it->GetNumSentBytes ()); s << "
\r\n"; } @@ -701,7 +715,9 @@ namespace http { << "
" << it.second->GetNumOutgoingTags () << "
" << tr("Outgoing Session Tags") << " [" << out_tags << "]
" << tr("Outgoing Session Tags") + << " [" << out_tags + << "]
\r\n" << "\r\n\r\n\r\n" << tmp_s.str () << "
" << tr("Destination") << "" << tr("Count") << "
\r\n
ECIESx25519
\r\n" << tr("Incoming Tags") << " [" << numECIESx25519Tags << "]
ECIESx25519
\r\n" << tr("Incoming Tags") + << " [" << numECIESx25519Tags + << "]
\r\n" << "
\r\n" - << "\r\n" + << "\r\n" << "
\r\n\r\n\r\n\r\n" << tmp_s.str () << "
" << tr("Destination") << "" << tr("Status") << "
\r\n
\r\n
\r\n"; } else @@ -748,7 +767,7 @@ namespace http { // Print table with streams information s << "
\r\n"; s << "
\r\n\r\n" - << "\r\n"; + << "\r\n"; s << "
\r\n\r\n\r\n"; s << ""; s << ""; @@ -886,17 +905,24 @@ namespace http { s << "
IDDestination
\r\n"; s << "
\r\n\r\n" - << "\r\n"; // TODO: separate client & exploratory tunnels into sections + << "\r\n"; // TODO: separate client & exploratory tunnels into sections s << "
\r\n
\r\n"; for (auto & it : i2p::tunnel::tunnels.GetInboundTunnels ()) { s << "
" << "[" << tr("In") << "] " << ""; it->Print(s); - if(it->LatencyIsKnown()) - s << " " << it->GetMeanLatency() << tr("ms") << ""; - else // placeholder for alignment + if(it->LatencyIsKnown()) { + s << " "; + if (it->GetMeanLatency() >= 1000) { + s << std::fixed << std::setprecision(2); + s << (double) it->GetMeanLatency() / 1000 << tr(/* tr: seconds */ "s") << ""; + } else { + s << it->GetMeanLatency() << tr(/* tr: Milliseconds */ "ms") << ""; + } + } else { // placeholder for alignment s << " ---"; + } ShowTunnelDetails(s, it->GetState (), (it->GetTunnelPool () == ExplPool), it->GetNumReceivedBytes ()); s << "
\r\n"; } @@ -1078,15 +1104,17 @@ namespace http { if (!tmp_s.str ().empty ()) { s << "
\r\n\r\n
" + << "\" />\r\n\r\n
" << tmp_s.str () << "
\r\n
\r\n"; } if (!tmp_s6.str ().empty ()) { s << "
\r\n" - << "\r\n
" + << "\r\n
" << tmp_s6.str () << "
\r\n
\r\n"; } } @@ -1109,7 +1137,8 @@ namespace http { if (!sessions.empty ()) { s << "
\r\n" - << "\r\n" + << "\r\n" << "
\r\n"; for (const auto& it: sessions) { @@ -1150,7 +1179,8 @@ namespace http { if (!sessions6.empty ()) { s << "
\r\n\r\n" - << "\r\n" + << "\r\n" << "
\r\n"; for (const auto& it: sessions6) { diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 3c7c0a54..fa6a73db 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -252,10 +252,11 @@ namespace tunnel void InboundTunnel::Print (std::stringstream& s) const { + s << ""; PrintHops (s); s << " "; s << " Local"; + s << GetTunnelID () << "\">Local"; s << "" << GetTunnelID () << ""; } @@ -277,8 +278,9 @@ namespace tunnel void ZeroHopsInboundTunnel::Print (std::stringstream& s) const { + s << ""; s << " Local"; + << GetTunnelID () << "\">Local"; s << "" << GetTunnelID () << ""; } @@ -318,9 +320,10 @@ namespace tunnel void OutboundTunnel::Print (std::stringstream& s) const { + s << ""; s << "Local"; PrintHops (s); - s << "" << GetTunnelID () << ""; + s << " " << GetTunnelID () << ""; } ZeroHopsOutboundTunnel::ZeroHopsOutboundTunnel (): @@ -354,9 +357,10 @@ namespace tunnel void ZeroHopsOutboundTunnel::Print (std::stringstream& s) const { + s << ""; s << " "; s << "" << GetTunnelID () << "\">Local"; + << GetTunnelID () << "\">" << GetTunnelID () << "\">Local"; s << "" << GetTunnelID () << ""; } diff --git a/webconsole/style.css b/webconsole/style.css index 3a3c4b98..95dc8efb 100644 --- a/webconsole/style.css +++ b/webconsole/style.css @@ -32,9 +32,10 @@ /* theme colors */ --scrollbar: #414 #101; --ink: #dbd; + --ink-darker: #b9b; --ink-faded: rgba(221,187,221, .5); --notify: #5f5; - --page: #140014; + --page: #120012; --main-boxshadow: 0 0 0 1px #000, 0 0 0 4px #313, 0 0 0 5px #000; --link: #ae6ba8; --link_hover: #fafafa; @@ -47,7 +48,7 @@ --active_shadow: inset 3px 3px 3px rgba(0,0,0,.6); --hr: linear-gradient(to right, #313, #414, #313); --highlight: inset 0 0 0 1px #101; - --tr: #1a001a; + --tr: #180818; --tr-alt: #202; --tr-inner: #240024; --header: linear-gradient(to bottom, #202, #101 50%, #101 50%, #000); @@ -136,6 +137,25 @@ a, .slide label { font-weight: 600; } +.slide label { + font-weight: 700; +} + +.count { + margin: -1px 0 -1px 3px; + padding: 0 10px; + display: inline-block; + vertical-align: baseline; + border-radius: 2px; + background: var(--ink-darker); + color: var(--page); + text-shadow: none; +} + +.count:hover { + background: var(--ink); +} + a { padding: 1px 8px; display: inline-block; @@ -354,6 +374,10 @@ th[colspan="2"], .slide label, #routerservices { background: var(--th); } +th:not(.sectiontitle)[colspan="2"], .slide label { + font-size: 95%; +} + th.sectiontitle { padding: 0 0 10px !important; font-weight: 700; @@ -398,7 +422,7 @@ td:last-child { } .error, .notify { - padding: 30px 12px; + padding: 30px 12px 40px; font-size: 110%; color: #fff; box-shadow: var(--highlight), inset 0 0 3px 3px rgba(0,0,0,.6); @@ -409,7 +433,7 @@ td:last-child { display: block; width: 100%; height: 48px; - background: var(--error) no-repeat center top / 40px; + background: var(--error) no-repeat center top / 44px; } #success { @@ -463,7 +487,7 @@ td:last-child { .arrowright, .arrowleft, .arrowleftright, .arrowup, .arrowdown { width: 12px; - height: 12px; + height: 16px; display: inline-block; vertical-align: middle; font-size: 0 !important; @@ -482,11 +506,11 @@ td:last-child { } .arrowup { - background: var(--arrow_up) no-repeat center center / 11px; + background: var(--arrow_up) no-repeat center center / 12px; } .arrowdown { - background: var(--arrow_down) no-repeat center center / 11px; + background: var(--arrow_down) no-repeat center center / 12px; } .listitem, .tableitem { @@ -512,13 +536,14 @@ td:last-child { } .listitem.out .arrowup, .listitem.in .arrowdown { - margin: 0 4px; + margin: 3px 8px 0 16px; + float: left; } - +/* #transports .listitem .arrowup, #transports .listitem .arrowdown { - margin: 0 10px; + margin: 3px 10px 0 16px; } - +*/ .tableitem .button { margin: 0 !important; padding: 1px 4px !important; @@ -674,7 +699,7 @@ table.services { } .tunnel { - margin: 3px 5px 0; + margin: 1px 5px 0; width: 26px; height: 16px; float: left; @@ -718,6 +743,10 @@ span[data-tooltip] { position: relative; } +.hops { + text-align: right; +} + .hop, .host { padding: 1px 4px; display: inline-block; @@ -736,6 +765,10 @@ span[data-tooltip] { background: #303 var(--planet) no-repeat 4px center / 9px; } +a[href^="https://gwhois"]:hover, a[href^="https://gwhois"]:focus { + background: none !important +} + a:hover .host, a:focus .host, a:active .host { background: #505 var(--exploratory) no-repeat 2px center / 13px; } @@ -747,13 +780,13 @@ a:hover .host, a:focus .host, a:active .host { } .latency { - padding: 2px 5px 2px 18px; - min-width: 52px; + padding: 2px 5px 2px 20px; + min-width: 40px; display: inline-block; vertical-align: middle; text-align: right; float: right; - background: var(--page) var(--time) no-repeat 3px center / 13px; + background: var(--page) var(--time) no-repeat 5px center / 13px; border-radius: 2px; } @@ -801,8 +834,7 @@ a[href^="https://gwhois"] { } span[data-tooltip]:hover::after, span[data-tooltip]:active::after, -.itag[data-tooltip]:hover::after, .itag[data-tooltip]:active::after, -/*a[href^="https://gwhois"][data-tooltip]:hover::after, a[href^="https://gwhois"][data-tooltip]:active::after*/ { +.itag[data-tooltip]:hover::after, .itag[data-tooltip]:active::after { padding: 3px 6px; display: inline-block; position: absolute; @@ -888,11 +920,13 @@ input[type=checkbox]:checked + label::after { } .tunnel, .latency { - margin: 0 4px; + margin: 1px 6px 0 4px; } - .tunnel { - margin-left: 8px; + .tunnel, .hops { + margin-top: 2px; + display: inline-block; + vertical-align: middle; } } @@ -905,7 +939,6 @@ input[type=checkbox]:checked + label::after { max-width: 200px !important; } } -} @media screen and (max-width: 800px) { #main { @@ -924,6 +957,16 @@ input[type=checkbox]:checked + label::after { max-width: 300px; } + .arrowup, .arrowdown, .tunnel { + float: none; + } + + .latency { + min-width: 0; + background-size: 11px; + background-color: transparent !important; + } + .hop { margin: 0 -3px; } @@ -939,6 +982,11 @@ input[type=checkbox]:checked + label::after { .tunnelid[data-tooltip]:hover::after, .tunnelid[data-tooltip]:active::after { display: none; } + + .hops { + display: inline-block; + min-width: 240px; + } } @media screen and (min-width: 1200px) { @@ -950,6 +998,11 @@ input[type=checkbox]:checked + label::after { background-size: 16px; } + .tunnelid:not(.local), .latency, .hops { + margin-top: 1px; + margin-bottom: -1px; + } + .tunnelid:not(.local) { margin-left: 12px; float: right; @@ -959,11 +1012,10 @@ input[type=checkbox]:checked + label::after { min-width: 560px; display: inline-block; vertical-align: middle; - text-align: right; } #transports .chain { - min-width: 540px; + min-width: 580px; text-align: left; } @@ -972,6 +1024,12 @@ input[type=checkbox]:checked + label::after { text-align: center; } + .hops { + min-width: 280px; + display: inline-block; + text-align: right; + } + .recvd, .sent { min-width: 64px; } @@ -984,6 +1042,10 @@ input[type=checkbox]:checked + label::after { min-width: 144px; } + .host a { + margin-bottom: -1px; + } + .SSU .host { min-width: 190px; } @@ -999,6 +1061,7 @@ input[type=checkbox]:checked + label::after { } .listitem.out .arrowup, .listitem.in .arrowdown { + margin-top: 2px; background-size: 14px; } @@ -1006,8 +1069,18 @@ input[type=checkbox]:checked + label::after { margin-right: 10px; } + .itag, .host { + margin-top: 1px; + } + .itag { + padding: 2px 5px 2px 20px; float: right; + min-width: 100px; + display: inline-block; + border-radius: 2px; + background-color: var(--menu); + background-position: 5px center; } .latency { @@ -1019,6 +1092,10 @@ input[type=checkbox]:checked + label::after { .transferred { min-width: 48px; } + + .tunnel { + margin: 2px 0 0 -48px; + } } @media screen and (min-width: 1200px) and (min-height: 600px) { @@ -1040,4 +1117,11 @@ input[type=checkbox]:checked + label::after { padding-top: 3px; padding-bottom: 1px; } -} \ No newline at end of file +} + +/* enable for screenshots */ +/* +.hop { + filter: blur(8px); +} +*/ \ No newline at end of file