forked from I2P_Developers/i2p.i2p
Console sidebar improvements
Sidebar: - Adjust vertical spacing of general section - Rename 'General' section to 'Router Info' and move ident info to h3 tooltip (ticket #1996) - Replace 'Short Router Info' with a new 'Advanced Router Info' section in default advanced sidebar (adds memory usage and clock skew) - Add optional embedded bandwidth graph (experimental) - Add optional memory usage bar - Add optional Advanced Peers section (adds failing and banned peers) - Add Help link to 'I2P Internals' section - Add help page anchored links and troubleshooting to 'Help & FAQ' section - Add download progress bar for router and plugin updates - Add 'Advanced Minimal' sidebar configuration - Add Jobs and Events links to Advanced section - Add additional reachability states for clockskew and vmcomm (with icons) Homepage: Add 'Customize Sidebar' link to signpost the feature now that there are more optional sections available (ticket #1996)
This commit is contained in:
@ -997,13 +997,18 @@ public class ConsoleUpdateManager implements UpdateManager, RouterApp {
|
||||
|
||||
public void notifyProgress(UpdateTask task, String status, long downloaded, long totalSize) {
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
buf.append(status).append(' ');
|
||||
buf.append("<div class=\"sb_updatestatus\">");
|
||||
buf.append(status).append("</div>");
|
||||
double pct = ((double)downloaded) / ((double)totalSize);
|
||||
synchronized (_pct) {
|
||||
buf.append("<div class=\"percentBarOuter\"><div class=\"percentBarText\">");
|
||||
buf.append(DataHelper.formatSize2(downloaded));
|
||||
buf.append("B / ");
|
||||
buf.append(DataHelper.formatSize2(totalSize));
|
||||
buf.append("B</div><div class=\"percentBarInner\" style=\"width: ");
|
||||
buf.append(_pct.format(pct));
|
||||
buf.append("\">");
|
||||
}
|
||||
buf.append("<br>\n");
|
||||
buf.append(_t("{0}B transferred", DataHelper.formatSize2(downloaded)));
|
||||
updateStatus(buf.toString());
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ class UpdateHandler implements Updater {
|
||||
return null;
|
||||
UpdateRunner update = new UpdateRunner(_context, _mgr, type, method, updateSources);
|
||||
// set status before thread to ensure UI feedback
|
||||
_mgr.notifyProgress(update, "<b>" + _mgr._t("Updating") + "</b>");
|
||||
_mgr.notifyProgress(update, "<b>" + _mgr._t("Updating") + " I2P</b>");
|
||||
return update;
|
||||
}
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
if (_isPartial)
|
||||
return;
|
||||
long d = currentWrite + bytesTransferred;
|
||||
String status = "<b>" + _t("Updating") + "</b>";
|
||||
String status = "<b>" + _t("Updating") + " I2P</b>";
|
||||
_mgr.notifyProgress(this, status, d, d + bytesRemaining);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ public class ConfigSummaryHandler extends FormHandler {
|
||||
addFormNotice(_t("Full summary bar default restored.") + " " +
|
||||
_t("Summary bar will refresh shortly."));
|
||||
} else if (_action.equals(_t("Restore minimal default"))) {
|
||||
_context.router().saveConfig(SummaryHelper.PROP_SUMMARYBAR + "default", SummaryHelper.DEFAULT_MINIMAL);
|
||||
_context.router().saveConfig(SummaryHelper.PROP_SUMMARYBAR + "default", isAdvanced() ? SummaryHelper.DEFAULT_MINIMAL_ADVANCED : SummaryHelper.DEFAULT_MINIMAL);
|
||||
addFormNotice(_t("Minimal summary bar default restored.") + " " +
|
||||
_t("Summary bar will refresh shortly."));
|
||||
} else if (adding || deleting || saving || moving) {
|
||||
|
@ -32,6 +32,7 @@ public class HomeHelper extends HelperBase {
|
||||
// FIXME wasn't escaped
|
||||
_x("Configure UI") + S + _x("Select console theme & language & set optional console password").replace("&", "&") + S + "/configui" + S + I + "info/ui.png" + S +
|
||||
_x("Customize Home Page") + S + _x("I2P Home Page Configuration") + S + "/confighome" + S + I + "home_page.png" + S +
|
||||
_x("Customize Sidebar") + S + _x("Customize the sidebar by adding or removing or repositioning elements") + S + "/configsidebar" + S + I + "info/sidebar.png" + S +
|
||||
_x("Email") + S + _x("Anonymous webmail client") + S + "/susimail/susimail" + S + I + "email.png" + S +
|
||||
_x("Help") + S + _x("I2P Router Help") + S + "/help" + S + I + "support.png" + S +
|
||||
_x("Manage Plugins") + S + _x("Install and configure I2P plugins") + S + "/configplugins" + S + I + "plugin.png" + S +
|
||||
|
@ -26,8 +26,8 @@ import net.i2p.util.SystemVersion;
|
||||
class SummaryBarRenderer {
|
||||
|
||||
static final String ALL_SECTIONS[] =
|
||||
{"HelpAndFAQ", "I2PServices", "I2PInternals", "General", "ShortGeneral", "NetworkReachability",
|
||||
"UpdateStatus", "RestartStatus", "Peers", "FirewallAndReseedStatus", "Bandwidth", "Tunnels",
|
||||
{"HelpAndFAQ", "I2PServices", "I2PInternals", "RouterInfo", "ShortRouterInfo", "AdvancedRouterInfo", "MemoryBar", "NetworkReachability",
|
||||
"UpdateStatus", "RestartStatus", "Peers", "PeersAdvanced", "FirewallAndReseedStatus", "Bandwidth", "BandwidthGraph", "Tunnels",
|
||||
"Congestion", "TunnelStatus", "Destinations", "NewsHeadings", "Advanced" };
|
||||
static final Map<String, String> SECTION_NAMES;
|
||||
|
||||
@ -36,20 +36,24 @@ class SummaryBarRenderer {
|
||||
aMap.put("HelpAndFAQ", "Help & FAQ");
|
||||
aMap.put("I2PServices", "I2P Services");
|
||||
aMap.put("I2PInternals", "I2P Internals");
|
||||
aMap.put("General", "General");
|
||||
aMap.put("ShortGeneral", "Short General");
|
||||
aMap.put("RouterInfo", "Router Information");
|
||||
aMap.put("ShortRouterInfo", "Short Router Information");
|
||||
aMap.put("AdvancedRouterInfo", "Router Information (advanced)");
|
||||
aMap.put("MemoryBar", "Memory Usage Bar");
|
||||
aMap.put("NetworkReachability", "Network Reachability");
|
||||
aMap.put("UpdateStatus", "Update Status");
|
||||
aMap.put("RestartStatus", "Restart Status");
|
||||
aMap.put("Peers", "Peers");
|
||||
aMap.put("PeersAdvanced", "Peers (advanced)");
|
||||
aMap.put("FirewallAndReseedStatus", "Firewall & Reseed Status");
|
||||
aMap.put("Bandwidth", "Bandwidth");
|
||||
aMap.put("BandwidthGraph", "Bandwidth Graph (experimental)");
|
||||
aMap.put("Tunnels", "Tunnels");
|
||||
aMap.put("Congestion", "Congestion");
|
||||
aMap.put("TunnelStatus", "Tunnel Status");
|
||||
aMap.put("Destinations", "Local Tunnels");
|
||||
aMap.put("NewsHeadings", "News & Updates");
|
||||
aMap.put("Advanced", "Advanced");
|
||||
aMap.put("Advanced", "Advanced Console Links");
|
||||
SECTION_NAMES = Collections.unmodifiableMap(aMap);
|
||||
}
|
||||
|
||||
@ -91,10 +95,14 @@ class SummaryBarRenderer {
|
||||
buf.append(renderI2PInternalsHTML());
|
||||
else if ("Advanced".equals(section))
|
||||
buf.append(renderAdvancedHTML());
|
||||
else if ("General".equals(section))
|
||||
buf.append(renderGeneralHTML());
|
||||
else if ("ShortGeneral".equals(section))
|
||||
buf.append(renderShortGeneralHTML());
|
||||
else if ("RouterInfo".equals(section) || "General".equals(section)) // Backwards-compatibility
|
||||
buf.append(renderRouterInfoHTML());
|
||||
else if ("ShortRouterInfo".equals(section) || "ShortGeneral".equals(section)) //Backwards-compatibility
|
||||
buf.append(renderShortRouterInfoHTML());
|
||||
else if ("AdvancedRouterInfo".equals(section))
|
||||
buf.append(renderAdvancedRouterInfoHTML());
|
||||
else if ("MemoryBar".equals(section))
|
||||
buf.append(renderMemoryBarHTML());
|
||||
else if ("NetworkReachability".equals(section))
|
||||
buf.append(renderNetworkReachabilityHTML());
|
||||
else if ("UpdateStatus".equals(section))
|
||||
@ -103,10 +111,14 @@ class SummaryBarRenderer {
|
||||
buf.append(renderRestartStatusHTML());
|
||||
else if ("Peers".equals(section))
|
||||
buf.append(renderPeersHTML());
|
||||
else if ("PeersAdvanced".equals(section))
|
||||
buf.append(renderPeersAdvancedHTML());
|
||||
else if ("FirewallAndReseedStatus".equals(section))
|
||||
buf.append(renderFirewallAndReseedStatusHTML());
|
||||
else if ("Bandwidth".equals(section))
|
||||
buf.append(renderBandwidthHTML());
|
||||
else if ("BandwidthGraph".equals(section))
|
||||
buf.append(renderBandwidthGraphHTML());
|
||||
else if ("Tunnels".equals(section))
|
||||
buf.append(renderTunnelsHTML());
|
||||
else if ("Congestion".equals(section))
|
||||
@ -130,7 +142,59 @@ class SummaryBarRenderer {
|
||||
.append(_t("I2P Router Help & FAQ"))
|
||||
.append("\">")
|
||||
.append(_t("Help & FAQ"))
|
||||
.append("</a></h3>");
|
||||
.append("</a></h3><hr class=\"b\">\n" +
|
||||
|
||||
"<table id=\"sb_help\"><tr><td>" +
|
||||
|
||||
"<a href=\"/help#advancedsettings\" target=\"_top\" title=\"")
|
||||
.append(_t("A guide to some of the less-used configuration settings"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Advanced Settings")))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"/help#changelog\" target=\"_top\" title=\"")
|
||||
.append(_t("Recent development changes to the router"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Changelog")))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"/help#configurationhelp\" target=\"_top\" title=\"")
|
||||
.append(_t("An introduction to configuring your router"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Configuration")))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"/help#faq\" target=\"_top\" title=\"")
|
||||
.append(_t("A shortened version of the official Frequently Asked Questions"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("FAQ")))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"/help#legal\" target=\"_top\" title=\"")
|
||||
.append(_t("Information regarding software and licenses used by I2P"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Legal")))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"/help#reachability\" target=\"_top\" title=\"")
|
||||
.append(_t("A short guide to the sidebar's network reachability notification"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Reachability")))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"/help#sidebarhelp\" target=\"_top\" title=\"")
|
||||
.append(_t("An introduction to the router sidebar"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Sidebar")))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"/console#trouble\" target=\"_top\" title=\"")
|
||||
.append(_t("Troubleshooting & Further Assistance"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Troubleshoot")))
|
||||
.append("</a>\n")
|
||||
|
||||
.append("</td></tr></table>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@ -196,18 +260,18 @@ class SummaryBarRenderer {
|
||||
.append("</a>\n");
|
||||
}
|
||||
|
||||
buf.append("<a href=\"/i2ptunnelmgr\" target=\"_top\" title=\"")
|
||||
buf.append("<a href=\"/help\" target=\"_top\" title=\"")
|
||||
.append(_t("Router Help and FAQ"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Help")))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"/i2ptunnelmgr\" target=\"_top\" title=\"")
|
||||
.append(_t("Local Tunnels"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Hidden Services Manager")))
|
||||
.append("</a>\n" +
|
||||
|
||||
// "<a href=\"/jobs.jsp\" target=\"_top\" title=\"")
|
||||
// .append(_t("Show the router's workload, and how it's performing"))
|
||||
// .append("\">")
|
||||
// .append(_t("Jobs"))
|
||||
// .append("</a>\n" +
|
||||
|
||||
"<a href=\"/logs\" target=\"_top\" title=\"")
|
||||
.append(_t("Health Report"))
|
||||
.append("\">")
|
||||
@ -247,13 +311,13 @@ class SummaryBarRenderer {
|
||||
|
||||
buf.append("<h3 id=\"advanced\"><a title=\"")
|
||||
.append(_t("Advanced Configuration"))
|
||||
.append("\" href=\"/configadvanced\">")
|
||||
.append("\" href=\"/configadvanced\" target=\"_top\">")
|
||||
.append(_t("Advanced"))
|
||||
.append("</a></h3>\n")
|
||||
|
||||
.append("<hr class=\"b\"><table id=\"sb_advanced\"><tr><td>")
|
||||
|
||||
.append("<a title=\"")
|
||||
.append("<a target=\"_top\" title=\"")
|
||||
.append(_t("Review active encryption certificates used in console"))
|
||||
.append("\" href=\"/certs\">")
|
||||
.append(nbsp(_t("Certs")))
|
||||
@ -267,35 +331,49 @@ class SummaryBarRenderer {
|
||||
|
||||
.append("<a title=\"")
|
||||
.append(_t("View router debug information"))
|
||||
.append("\" href=\"/debug\">")
|
||||
.append("\" href=\"/debug\" target=\"_top\">")
|
||||
.append(nbsp(_t("Debug")))
|
||||
.append("</a>\n")
|
||||
|
||||
.append("<a href=\"/events\" target=\"_top\" title=\"")
|
||||
.append(_t("View historical log of router events"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Events")))
|
||||
.append("</a>\n")
|
||||
|
||||
.append("<a title=\"")
|
||||
.append(_t("Review extended info about installed .jar and .war files"))
|
||||
.append("\" href=\"/jars\">")
|
||||
.append("\" href=\"/jars\" target=\"_top\">")
|
||||
.append(nbsp(_t("Jars")))
|
||||
.append("</a>\n");
|
||||
|
||||
File javadoc = new File(_context.getBaseDir(), "docs/javadoc/index.html");
|
||||
if (javadoc.exists())
|
||||
buf.append("<a href=\"/javadoc/index.html\" target=\"_blank\">Javadoc</a>\n");
|
||||
buf.append("<a title=\"")
|
||||
.append(_t("Documentation for the I2P API"))
|
||||
.append("\" href=\"/javadoc/index.html\" target=\"_blank\">Javadoc</a>\n");
|
||||
|
||||
buf.append("<a title=\"")
|
||||
buf.append("<a href=\"/jobs\" target=\"_top\" title=\"")
|
||||
.append(_t("Show the router's workload, and how it's performing"))
|
||||
.append("\">")
|
||||
.append(nbsp(_t("Jobs")))
|
||||
.append("</a>\n")
|
||||
|
||||
.append("<a title=\"")
|
||||
.append(_t("View active leasesets (debug mode)"))
|
||||
.append("\" href=\"/netdb?l=2\">")
|
||||
.append("\" href=\"/netdb?l=2\" target=\"_top\">")
|
||||
.append(nbsp(_t("LeaseSets")))
|
||||
.append("</a>\n")
|
||||
|
||||
.append("<a title=\"")
|
||||
.append(_t("Network database search tool"))
|
||||
.append("\" href=\"/netdb?f=4\">")
|
||||
.append("\" href=\"/netdb?f=4\" target=\"_top\">")
|
||||
.append(nbsp(_t("NetDB Search")))
|
||||
.append("</a>\n")
|
||||
|
||||
.append("<a title=\"")
|
||||
.append(_t("Signed proof of ownership of this router"))
|
||||
.append("\" href=\"/proof\">")
|
||||
.append("\" href=\"/proof\" target=\"_top\">")
|
||||
.append(nbsp(_t("Proof")))
|
||||
.append("</a>\n")
|
||||
|
||||
@ -307,7 +385,7 @@ class SummaryBarRenderer {
|
||||
|
||||
.append("<a title=\"")
|
||||
.append(_t("Review possible sybils in network database"))
|
||||
.append("\" href=\"/netdb?f=3\">")
|
||||
.append("\" href=\"/netdb?f=3\" target=\"_top\">")
|
||||
.append(nbsp(_t("Sybils")))
|
||||
.append("</a>\n")
|
||||
|
||||
@ -315,34 +393,17 @@ class SummaryBarRenderer {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String renderGeneralHTML() {
|
||||
public String renderRouterInfoHTML() {
|
||||
if (_helper == null) return "";
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
buf.append("<h3><a href=\"/help\" target=\"_top\" title=\"")
|
||||
.append(_t("I2P Router Help"))
|
||||
buf.append("<h3><a href=\"/netdb?r=.\" target=\"_top\" title=\"")
|
||||
.append(_t("Your Local Identity [{0}] is your unique I2P router identity, similar to an IP address but tailored to I2P. ", _helper.getIdent()))
|
||||
.append(_t("Never disclose this to anyone, as it can reveal your real world IP."))
|
||||
.append("\">")
|
||||
.append(_t("General"))
|
||||
.append(_t("Router Info"))
|
||||
.append("</a></h3><hr class=\"b\">\n" +
|
||||
|
||||
"<table id=\"sb_localid\"><tr>" +
|
||||
"<td align=\"left\"><b title=\"")
|
||||
.append(_t("Your Local Identity is your unique I2P router identity, similar to an ip address but tailored to I2P. "))
|
||||
.append(_t("Never disclose this to anyone, as it can reveal your real world ip."))
|
||||
.append("\">")
|
||||
.append(_t("Local Identity"))
|
||||
.append(":</b></td>" +
|
||||
"<td align=\"right\">" +
|
||||
"<a title=\"")
|
||||
.append(_t("Your unique I2P router identity is"))
|
||||
.append(' ')
|
||||
.append(_helper.getIdent())
|
||||
.append(", ")
|
||||
.append(_t("never reveal it to anyone"))
|
||||
.append("\" href=\"/netdb?r=.\" target=\"_top\">")
|
||||
.append(_t("show"))
|
||||
.append("</a></td></tr>\n" +
|
||||
|
||||
"</table><table id=\"sb_version\">" + // fix for some rows with a big left side and some with a big right side
|
||||
"</table><table id=\"sb_general\">" +
|
||||
"<tr title=\"")
|
||||
.append(_t("The version of the I2P software we are running"))
|
||||
.append("\">" +
|
||||
@ -353,7 +414,6 @@ class SummaryBarRenderer {
|
||||
.append(_helper.getVersion())
|
||||
.append("</td></tr>\n" +
|
||||
|
||||
"</table><table id=\"sb_uptime\">" + // fix for some rows with a big left side and some with a big right side
|
||||
"<tr title=\"")
|
||||
.append(_t("How long we've been running for this session"))
|
||||
.append("\">" +
|
||||
@ -366,7 +426,7 @@ class SummaryBarRenderer {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String renderShortGeneralHTML() {
|
||||
public String renderShortRouterInfoHTML() {
|
||||
if (_helper == null) return "";
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
buf.append("<table id=\"sb_shortgeneral\">" +
|
||||
@ -392,12 +452,80 @@ class SummaryBarRenderer {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** @since 0.9.32 */
|
||||
public String renderAdvancedRouterInfoHTML() {
|
||||
if (_helper == null) return "";
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
buf.append("<h3><a href=\"/netdb?r=.\" target=\"_top\" title=\"")
|
||||
.append(_t("Your Local Identity [{0}] is your unique I2P router identity, similar to an IP address but tailored to I2P. ", _helper.getIdent()))
|
||||
.append(_t("Never disclose this to anyone, as it can reveal your real world IP."))
|
||||
.append("\">")
|
||||
.append(_t("Router Info"))
|
||||
.append("</a></h3><hr class=\"b\">\n" +
|
||||
|
||||
"<table id=\"sb_advancedgeneral\">" +
|
||||
"<tr title=\"")
|
||||
.append(_t("The version of the I2P software we are running"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><b>")
|
||||
.append(_t("Version"))
|
||||
.append(":</b></td>" +
|
||||
"<td align=\"right\">")
|
||||
.append(_helper.getVersion())
|
||||
.append("</td></tr>\n" +
|
||||
|
||||
"<tr title=\"")
|
||||
.append(_t("How long we've been running for this session"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><b>")
|
||||
.append(_t("Uptime"))
|
||||
.append(":</b></td>" +
|
||||
"<td align=\"right\">")
|
||||
.append(_helper.getUptime())
|
||||
.append("</td></tr>\n" +
|
||||
|
||||
"<tr title=\"")
|
||||
.append(_t("Difference between network-synced time and local time"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><b>")
|
||||
.append(_t("Clock Skew"))
|
||||
.append(":</b></td>" +
|
||||
"<td align=\"right\">")
|
||||
.append(_context.clock().getOffset())
|
||||
.append(" ms</td></tr>\n" +
|
||||
|
||||
"<tr title=\"")
|
||||
.append(_t("How much RAM I2P is using / total RAM available to I2P (excludes RAM allocated to the JVM)"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><b>")
|
||||
.append(_t("Memory"))
|
||||
.append(":</b></td>" +
|
||||
"<td align=\"right\">")
|
||||
.append(_helper.getMemory())
|
||||
.append("</td></tr></table>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** @since 0.9.32 */
|
||||
public String renderMemoryBarHTML() {
|
||||
if (_helper == null) return "";
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
buf.append(_helper.getMemoryBar());
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String renderNetworkReachabilityHTML() {
|
||||
if (_helper == null) return "";
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
SummaryHelper.NetworkStateMessage reachability = _helper.getReachability();
|
||||
buf.append("<h4><span class=\"");
|
||||
buf.append("<h4><span class=\"sb_netstatus ");
|
||||
switch (reachability.getState()) {
|
||||
case VMCOMM:
|
||||
buf.append("vmcomm");
|
||||
break;
|
||||
case CLOCKSKEW:
|
||||
buf.append("clockskew");
|
||||
break;
|
||||
case ERROR:
|
||||
buf.append("error");
|
||||
break;
|
||||
@ -528,6 +656,90 @@ class SummaryBarRenderer {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String renderPeersAdvancedHTML() {
|
||||
if (_helper == null) return "";
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
buf.append("<h3><a href=\"/peers\" target=\"_top\" title=\"")
|
||||
.append(_t("Show all current peer connections"))
|
||||
.append("\">")
|
||||
.append(_t("Peers"))
|
||||
.append("</a></h3><hr class=\"b\">\n" +
|
||||
|
||||
"<table id=\"sb_peersadvanced\">\n" +
|
||||
|
||||
"<tr title=\"")
|
||||
.append(_t("Peers we've been talking to in the last few minutes/last hour"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><b>")
|
||||
.append(_t("Active"))
|
||||
.append(":</b></td><td align=\"right\">");
|
||||
int active = _helper.getActivePeers();
|
||||
buf.append(active)
|
||||
.append(SummaryHelper.THINSP)
|
||||
.append(Math.max(active, _helper.getActiveProfiles()))
|
||||
.append("</td></tr>\n" +
|
||||
|
||||
"<tr title=\"")
|
||||
.append(_t("The number of peers available for building client tunnels"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><b>")
|
||||
.append(_t("Fast"))
|
||||
.append(":</b></td><td align=\"right\">")
|
||||
.append(_helper.getFastPeers())
|
||||
.append("</td></tr>\n" +
|
||||
|
||||
"<tr title=\"")
|
||||
.append(_t("The number of peers available for building exploratory tunnels"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><b>")
|
||||
.append(_t("High capacity"))
|
||||
.append(":</b></td><td align=\"right\">")
|
||||
.append(_helper.getHighCapacityPeers())
|
||||
.append("</td></tr>\n" +
|
||||
|
||||
"<tr title=\"")
|
||||
.append(_t("The number of peers available for network database inquiries"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><b>")
|
||||
.append(_t("Integrated"))
|
||||
.append(":</b></td><td align=\"right\">")
|
||||
.append(_helper.getWellIntegratedPeers())
|
||||
.append("</td></tr>\n" +
|
||||
|
||||
"<tr title=\"")
|
||||
.append(_t("The total number of peers in our network database"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><b>")
|
||||
.append(_t("Known"))
|
||||
.append(":</b></td><td align=\"right\">")
|
||||
.append(_helper.getAllPeers())
|
||||
.append("</td></tr>\n" +
|
||||
|
||||
"<tr class=\"separator\"><td colspan=\"2\"><hr></td></tr>" +
|
||||
|
||||
"<tr title=\"")
|
||||
.append(_t("The number of peers failing network tests"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><a href=\"/profiles\"><b>")
|
||||
.append(_t("Failing"))
|
||||
.append(":</b></a></td><td align=\"right\">")
|
||||
.append(_helper.getFailingPeers())
|
||||
.append("</td></tr>\n" +
|
||||
|
||||
"<tr title=\"")
|
||||
.append(_t("The number of banned peers"))
|
||||
.append("\">" +
|
||||
"<td align=\"left\"><a href=\"/profiles?f=3\"><b>")
|
||||
.append(_t("Banned"))
|
||||
.append(":</b></a></td><td align=\"right\">")
|
||||
.append(_helper. getBanlistedPeers())
|
||||
.append("</td></tr>\n" +
|
||||
|
||||
"</table>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
||||
public String renderFirewallAndReseedStatusHTML() {
|
||||
if (_helper == null) return "";
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
@ -579,6 +791,21 @@ class SummaryBarRenderer {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** @since 0.9.32 */
|
||||
public String renderBandwidthGraphHTML() {
|
||||
if (_helper == null) return "";
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
if (!StatSummarizer.isDisabled())
|
||||
buf.append("<div id=\"sb_graphcontainer\"><a href=\"/graphs\"><table id=\"sb_bandwidthgraph\">" +
|
||||
"<tr title=\"")
|
||||
.append(_t("Our inbound & outbound traffic for the last 20 minutes"))
|
||||
.append("\"><td><span id=\"sb_graphstats\">")
|
||||
.append(_helper.getSecondKBps())
|
||||
.append("Bps</span></td></tr></table></a></div>\n");
|
||||
// .append("<script src=\"/js/refreshGraph.js\" type=\"text/javascript\"></script>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String renderTunnelsHTML() {
|
||||
if (_helper == null) return "";
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
|
@ -30,7 +30,7 @@ import net.i2p.util.PortMapper;
|
||||
|
||||
/**
|
||||
* Simple helper to query the appropriate router for data necessary to render
|
||||
* the summary sections on the router console.
|
||||
* the summary sections on the router console.
|
||||
*
|
||||
* For the full summary bar use renderSummaryBar()
|
||||
*/
|
||||
@ -43,14 +43,14 @@ public class SummaryHelper extends HelperBase {
|
||||
static final String PROP_SUMMARYBAR = "routerconsole.summaryBar.";
|
||||
|
||||
static final String DEFAULT_FULL =
|
||||
"HelpAndFAQ" + S +
|
||||
"ShortGeneral" + S +
|
||||
"RouterInfo" + S +
|
||||
"UpdateStatus" + S +
|
||||
"Bandwidth" + S +
|
||||
"NetworkReachability" + S +
|
||||
"FirewallAndReseedStatus" + S +
|
||||
"I2PServices" + S +
|
||||
"I2PInternals" + S +
|
||||
"HelpAndFAQ" + S +
|
||||
"Peers" + S +
|
||||
"Tunnels" + S +
|
||||
"TunnelStatus" + S +
|
||||
@ -59,8 +59,8 @@ public class SummaryHelper extends HelperBase {
|
||||
"";
|
||||
|
||||
static final String DEFAULT_FULL_ADVANCED =
|
||||
"HelpAndFAQ" + S +
|
||||
"ShortGeneral" + S +
|
||||
"AdvancedRouterInfo" + S +
|
||||
"MemoryBar" + S +
|
||||
"UpdateStatus" + S +
|
||||
"Bandwidth" + S +
|
||||
"NetworkReachability" + S +
|
||||
@ -77,7 +77,20 @@ public class SummaryHelper extends HelperBase {
|
||||
"";
|
||||
|
||||
static final String DEFAULT_MINIMAL =
|
||||
"ShortGeneral" + S +
|
||||
"ShortRouterInfo" + S +
|
||||
"Bandwidth" + S +
|
||||
"UpdateStatus" + S +
|
||||
"NewsHeadings" + S +
|
||||
"NetworkReachability" + S +
|
||||
"FirewallAndReseedStatus" + S +
|
||||
"RestartStatus" + S +
|
||||
"Destinations" + S +
|
||||
"";
|
||||
|
||||
/** @since 0.9.32 */
|
||||
static final String DEFAULT_MINIMAL_ADVANCED =
|
||||
"AdvancedRouterInfo" + S +
|
||||
"MemoryBar" + S +
|
||||
"Bandwidth" + S +
|
||||
"UpdateStatus" + S +
|
||||
"NewsHeadings" + S +
|
||||
@ -152,7 +165,9 @@ public class SummaryHelper extends HelperBase {
|
||||
FIREWALLED,
|
||||
RUNNING,
|
||||
WARN,
|
||||
ERROR;
|
||||
ERROR,
|
||||
CLOCKSKEW,
|
||||
VMCOMM;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,7 +212,7 @@ public class SummaryHelper extends HelperBase {
|
||||
|
||||
private NetworkStateMessage reachability() {
|
||||
if (_context.commSystem().isDummy())
|
||||
return new NetworkStateMessage(NetworkState.RUNNING, "VM Comm System");
|
||||
return new NetworkStateMessage(NetworkState.VMCOMM, "VM Comm System");
|
||||
if (_context.router().getUptime() > 60*1000 && (!_context.router().gracefulShutdownInProgress()) &&
|
||||
!_context.clientManager().isAlive())
|
||||
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-Client Manager I2CP Error - check logs")); // not a router problem but the user should know
|
||||
@ -207,7 +222,7 @@ public class SummaryHelper extends HelperBase {
|
||||
long skew = _context.commSystem().getFramedAveragePeerClockSkew(33);
|
||||
// Display the actual skew, not the offset
|
||||
if (Math.abs(skew) > 30*1000)
|
||||
return new NetworkStateMessage(NetworkState.ERROR, _t("ERR-Clock Skew of {0}", DataHelper.formatDuration2(Math.abs(skew))));
|
||||
return new NetworkStateMessage(NetworkState.CLOCKSKEW, _t("ERR-Clock Skew of {0}", DataHelper.formatDuration2(Math.abs(skew))));
|
||||
if (_context.router().isHidden())
|
||||
return new NetworkStateMessage(NetworkState.HIDDEN, _t("Hidden"));
|
||||
RouterInfo routerInfo = _context.router().getRouterInfo();
|
||||
@ -281,21 +296,37 @@ public class SummaryHelper extends HelperBase {
|
||||
* Retrieve amount of used memory.
|
||||
*
|
||||
*/
|
||||
/********
|
||||
|
||||
public String getMemory() {
|
||||
DecimalFormat integerFormatter = new DecimalFormat("###,###,##0");
|
||||
long used = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024;
|
||||
long used = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024;
|
||||
long usedPc = 100 - ((Runtime.getRuntime().freeMemory() * 100) / Runtime.getRuntime().totalMemory());
|
||||
return integerFormatter.format(used) + "KB (" + usedPc + "%)";
|
||||
long total = (Runtime.getRuntime().totalMemory())/1024/1024;
|
||||
// long free = Runtime.getRuntime().freeMemory()/1024/1024;
|
||||
// return integerFormatter.format(used) + "MB (" + usedPc + "%)";
|
||||
// return integerFormatter.format(used) + "MB / " + free + " MB";
|
||||
return integerFormatter.format(used) + " / " + total + "MB";
|
||||
}
|
||||
|
||||
public String getMemoryBar() {
|
||||
DecimalFormat integerFormatter = new DecimalFormat("###,###,##0");
|
||||
long used = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024;
|
||||
long usedPc = 100 - ((Runtime.getRuntime().freeMemory() * 100) / Runtime.getRuntime().totalMemory());
|
||||
long total = (Runtime.getRuntime().totalMemory())/1024/1024;
|
||||
// long free = Runtime.getRuntime().freeMemory()/1024/1024;
|
||||
// return integerFormatter.format(used) + "MB (" + usedPc + "%)";
|
||||
// return integerFormatter.format(used) + "MB / " + free + " MB";
|
||||
return "<div class=\"percentBarOuter\"><div class=\"percentBarText\">RAM: " + integerFormatter.format(used) + " / " + total + "MB" +
|
||||
"</div><div class=\"percentBarInner\" style=\"width: " + integerFormatter.format(usedPc) +
|
||||
"%;\"></div></div>";
|
||||
}
|
||||
********/
|
||||
|
||||
/**
|
||||
* How many peers we are talking to now
|
||||
*
|
||||
*/
|
||||
public int getActivePeers() {
|
||||
if (_context == null)
|
||||
public int getActivePeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.commSystem().countActivePeers();
|
||||
@ -305,7 +336,7 @@ public class SummaryHelper extends HelperBase {
|
||||
* Should we warn about a possible firewall problem?
|
||||
*/
|
||||
public boolean showFirewallWarning() {
|
||||
return _context != null &&
|
||||
return _context != null &&
|
||||
_context.netDb().isInitialized() &&
|
||||
_context.router().getUptime() > 2*60*1000 &&
|
||||
(!_context.commSystem().isDummy()) &&
|
||||
@ -317,8 +348,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* How many active identities have we spoken with recently
|
||||
*
|
||||
*/
|
||||
public int getActiveProfiles() {
|
||||
if (_context == null)
|
||||
public int getActiveProfiles() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.profileOrganizer().countActivePeers();
|
||||
@ -327,8 +358,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* How many active peers the router ranks as fast.
|
||||
*
|
||||
*/
|
||||
public int getFastPeers() {
|
||||
if (_context == null)
|
||||
public int getFastPeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.profileOrganizer().countFastPeers();
|
||||
@ -337,8 +368,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* How many active peers the router ranks as having a high capacity.
|
||||
*
|
||||
*/
|
||||
public int getHighCapacityPeers() {
|
||||
if (_context == null)
|
||||
public int getHighCapacityPeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.profileOrganizer().countHighCapacityPeers();
|
||||
@ -347,8 +378,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* How many active peers the router ranks as well integrated.
|
||||
*
|
||||
*/
|
||||
public int getWellIntegratedPeers() {
|
||||
if (_context == null)
|
||||
public int getWellIntegratedPeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
//return _context.profileOrganizer().countWellIntegratedPeers();
|
||||
return _context.peerManager().getPeersByCapability(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL).size();
|
||||
@ -357,34 +388,34 @@ public class SummaryHelper extends HelperBase {
|
||||
* How many peers the router ranks as failing.
|
||||
*
|
||||
*/
|
||||
/********
|
||||
public int getFailingPeers() {
|
||||
if (_context == null)
|
||||
|
||||
public int getFailingPeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.profileOrganizer().countFailingPeers();
|
||||
}
|
||||
********/
|
||||
|
||||
/**
|
||||
* How many peers totally suck.
|
||||
*
|
||||
*/
|
||||
/********
|
||||
public int getBanlistedPeers() {
|
||||
if (_context == null)
|
||||
|
||||
public int getBanlistedPeers() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.banlist().getRouterCount();
|
||||
}
|
||||
********/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return "x.xx / y.yy {K|M}"
|
||||
*/
|
||||
public String getSecondKBps() {
|
||||
if (_context == null)
|
||||
public String getSecondKBps() {
|
||||
if (_context == null)
|
||||
return "0 / 0";
|
||||
return formatPair(_context.bandwidthLimiter().getReceiveBps(),
|
||||
return formatPair(_context.bandwidthLimiter().getReceiveBps(),
|
||||
_context.bandwidthLimiter().getSendBps());
|
||||
}
|
||||
|
||||
@ -392,7 +423,7 @@ public class SummaryHelper extends HelperBase {
|
||||
* @return "x.xx / y.yy {K|M}"
|
||||
*/
|
||||
public String getFiveMinuteKBps() {
|
||||
if (_context == null)
|
||||
if (_context == null)
|
||||
return "0 / 0";
|
||||
|
||||
RateStat receiveRate = _context.statManager().getRate("bw.recvRate");
|
||||
@ -415,8 +446,8 @@ public class SummaryHelper extends HelperBase {
|
||||
/**
|
||||
* @return "x.xx / y.yy {K|M}"
|
||||
*/
|
||||
public String getLifetimeKBps() {
|
||||
if (_context == null)
|
||||
public String getLifetimeKBps() {
|
||||
if (_context == null)
|
||||
return "0 / 0";
|
||||
|
||||
RateStat receiveRate = _context.statManager().getRate("bw.recvRate");
|
||||
@ -464,8 +495,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* string with 2 decimal places and the appropriate units - GB/MB/KB/bytes)
|
||||
*
|
||||
*/
|
||||
public String getInboundTransferred() {
|
||||
if (_context == null)
|
||||
public String getInboundTransferred() {
|
||||
if (_context == null)
|
||||
return "0";
|
||||
|
||||
long received = _context.bandwidthLimiter().getTotalAllocatedInboundBytes();
|
||||
@ -478,8 +509,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* string with 2 decimal places and the appropriate units - GB/MB/KB/bytes)
|
||||
*
|
||||
*/
|
||||
public String getOutboundTransferred() {
|
||||
if (_context == null)
|
||||
public String getOutboundTransferred() {
|
||||
if (_context == null)
|
||||
return "0";
|
||||
|
||||
long sent = _context.bandwidthLimiter().getTotalAllocatedOutboundBytes();
|
||||
@ -529,7 +560,7 @@ public class SummaryHelper extends HelperBase {
|
||||
buf.append("<td><img src=\"/themes/console/images/local_inprogress.png\" alt=\"").append(_t("Rebuilding")).append("…\" title=\"").append(_t("Leases expired")).append(" ").append(DataHelper.formatDuration2(0-timeToExpire));
|
||||
buf.append(" ").append(_t("ago")).append(". ").append(_t("Rebuilding")).append("…\"></td></tr>\n");
|
||||
} else {
|
||||
// green light
|
||||
// green light
|
||||
buf.append("<td><img src=\"/themes/console/images/local_up.png\" alt=\"Ready\" title=\"").append(_t("Ready")).append("\"></td></tr>\n");
|
||||
}
|
||||
} else {
|
||||
@ -585,8 +616,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* How many free inbound tunnels we have.
|
||||
*
|
||||
*/
|
||||
public int getInboundTunnels() {
|
||||
if (_context == null)
|
||||
public int getInboundTunnels() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.tunnelManager().getFreeTunnelCount();
|
||||
@ -596,8 +627,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* How many active outbound tunnels we have.
|
||||
*
|
||||
*/
|
||||
public int getOutboundTunnels() {
|
||||
if (_context == null)
|
||||
public int getOutboundTunnels() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.tunnelManager().getOutboundTunnelCount();
|
||||
@ -607,8 +638,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* How many inbound client tunnels we have.
|
||||
*
|
||||
*/
|
||||
public int getInboundClientTunnels() {
|
||||
if (_context == null)
|
||||
public int getInboundClientTunnels() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.tunnelManager().getInboundClientTunnelCount();
|
||||
@ -618,8 +649,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* How many active outbound client tunnels we have.
|
||||
*
|
||||
*/
|
||||
public int getOutboundClientTunnels() {
|
||||
if (_context == null)
|
||||
public int getOutboundClientTunnels() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.tunnelManager().getOutboundClientTunnelCount();
|
||||
@ -629,16 +660,16 @@ public class SummaryHelper extends HelperBase {
|
||||
* How many tunnels we are participating in.
|
||||
*
|
||||
*/
|
||||
public int getParticipatingTunnels() {
|
||||
if (_context == null)
|
||||
public int getParticipatingTunnels() {
|
||||
if (_context == null)
|
||||
return 0;
|
||||
else
|
||||
return _context.tunnelManager().getParticipatingCount();
|
||||
}
|
||||
|
||||
/** @since 0.7.10 */
|
||||
public String getShareRatio() {
|
||||
if (_context == null)
|
||||
public String getShareRatio() {
|
||||
if (_context == null)
|
||||
return "0";
|
||||
double sr = _context.tunnelManager().getShareRatio();
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
@ -650,8 +681,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* the units attached)
|
||||
*
|
||||
*/
|
||||
public String getJobLag() {
|
||||
if (_context == null)
|
||||
public String getJobLag() {
|
||||
if (_context == null)
|
||||
return "0";
|
||||
|
||||
RateStat rs = _context.statManager().getRate("jobQueue.jobLag");
|
||||
@ -666,8 +697,8 @@ public class SummaryHelper extends HelperBase {
|
||||
* (pretty printed with the units attached)
|
||||
*
|
||||
*/
|
||||
public String getMessageDelay() {
|
||||
if (_context == null)
|
||||
public String getMessageDelay() {
|
||||
if (_context == null)
|
||||
return "0";
|
||||
|
||||
return DataHelper.formatDuration2(_context.throttle().getMessageDelay());
|
||||
@ -678,15 +709,15 @@ public class SummaryHelper extends HelperBase {
|
||||
* (pretty printed with the units attached)
|
||||
*
|
||||
*/
|
||||
public String getTunnelLag() {
|
||||
if (_context == null)
|
||||
public String getTunnelLag() {
|
||||
if (_context == null)
|
||||
return "0";
|
||||
|
||||
return DataHelper.formatDuration2(_context.throttle().getTunnelLag());
|
||||
}
|
||||
|
||||
public String getTunnelStatus() {
|
||||
if (_context == null)
|
||||
public String getTunnelStatus() {
|
||||
if (_context == null)
|
||||
return "";
|
||||
return _context.throttle().getTunnelStatus();
|
||||
}
|
||||
@ -722,30 +753,30 @@ public class SummaryHelper extends HelperBase {
|
||||
}
|
||||
********/
|
||||
|
||||
private static boolean updateAvailable() {
|
||||
private static boolean updateAvailable() {
|
||||
return NewsHelper.isUpdateAvailable();
|
||||
}
|
||||
|
||||
private boolean unsignedUpdateAvailable() {
|
||||
private boolean unsignedUpdateAvailable() {
|
||||
return NewsHelper.isUnsignedUpdateAvailable(_context);
|
||||
}
|
||||
|
||||
/** @since 0.9.20 */
|
||||
private boolean devSU3UpdateAvailable() {
|
||||
private boolean devSU3UpdateAvailable() {
|
||||
return NewsHelper.isDevSU3UpdateAvailable(_context);
|
||||
}
|
||||
|
||||
private static String getUpdateVersion() {
|
||||
private static String getUpdateVersion() {
|
||||
return DataHelper.escapeHTML(NewsHelper.updateVersion());
|
||||
}
|
||||
|
||||
private static String getUnsignedUpdateVersion() {
|
||||
private static String getUnsignedUpdateVersion() {
|
||||
// value is a formatted date, does not need escaping
|
||||
return NewsHelper.unsignedUpdateVersion();
|
||||
}
|
||||
|
||||
/** @since 0.9.20 */
|
||||
private static String getDevSU3UpdateVersion() {
|
||||
private static String getDevSU3UpdateVersion() {
|
||||
return DataHelper.escapeHTML(NewsHelper.devSU3UpdateVersion());
|
||||
}
|
||||
|
||||
@ -759,7 +790,7 @@ public class SummaryHelper extends HelperBase {
|
||||
String status = NewsHelper.getUpdateStatus();
|
||||
boolean needSpace = false;
|
||||
if (status.length() > 0) {
|
||||
buf.append("<h4 class=\"sb_info\">").append(status).append("</h4>\n");
|
||||
buf.append("<h4 class=\"sb_info sb_update\">").append(status).append("</h4>\n");
|
||||
needSpace = true;
|
||||
}
|
||||
String dver = NewsHelper.updateVersionDownloaded();
|
||||
@ -775,7 +806,7 @@ public class SummaryHelper extends HelperBase {
|
||||
buf.append("<hr>");
|
||||
else
|
||||
needSpace = true;
|
||||
buf.append("<h4 class=\"sb_info\"><b>").append(_t("Update downloaded")).append("<br>");
|
||||
buf.append("<h4 class=\"sb_info sb_update\"><b>").append(_t("Update downloaded")).append("<br>");
|
||||
if (_context.hasWrapper())
|
||||
buf.append(_t("Click Restart to install"));
|
||||
else
|
||||
@ -796,7 +827,7 @@ public class SummaryHelper extends HelperBase {
|
||||
buf.append("<hr>");
|
||||
else
|
||||
needSpace = true;
|
||||
buf.append("<h4 class=\"sb_info\"><b>").append(_t("Update available")).append(":<br>");
|
||||
buf.append("<h4 class=\"sb_info sb_update\"><b>").append(_t("Update available")).append(":<br>");
|
||||
buf.append(_t("Version {0}", getUpdateVersion())).append("<br>");
|
||||
buf.append(constraint).append("</b></h4>");
|
||||
avail = false;
|
||||
@ -808,7 +839,7 @@ public class SummaryHelper extends HelperBase {
|
||||
buf.append("<hr>");
|
||||
else
|
||||
needSpace = true;
|
||||
buf.append("<h4 class=\"sb_info\"><b>").append(_t("Update available")).append(":<br>");
|
||||
buf.append("<h4 class=\"sb_info sb_update\"><b>").append(_t("Update available")).append(":<br>");
|
||||
buf.append(_t("Version {0}", getUnsignedUpdateVersion())).append("<br>");
|
||||
buf.append(unsignedConstraint).append("</b></h4>");
|
||||
unsignedAvail = false;
|
||||
@ -820,7 +851,7 @@ public class SummaryHelper extends HelperBase {
|
||||
buf.append("<hr>");
|
||||
else
|
||||
needSpace = true;
|
||||
buf.append("<h4 class=\"sb_info\"><b>").append(_t("Update available")).append(":<br>");
|
||||
buf.append("<h4 class=\"sb_info sb_update\"><b>").append(_t("Update available")).append(":<br>");
|
||||
buf.append(_t("Version {0}", getDevSU3UpdateVersion())).append("<br>");
|
||||
buf.append(devSU3Constraint).append("</b></h4>");
|
||||
devSU3Avail = false;
|
||||
@ -930,7 +961,7 @@ public class SummaryHelper extends HelperBase {
|
||||
public List<String> getSummaryBarSections(String page) {
|
||||
String config = "";
|
||||
if ("home".equals(page)) {
|
||||
config = _context.getProperty(PROP_SUMMARYBAR + page, DEFAULT_MINIMAL);
|
||||
config = _context.getProperty(PROP_SUMMARYBAR + page, isAdvanced() ? DEFAULT_MINIMAL_ADVANCED : DEFAULT_MINIMAL);
|
||||
} else {
|
||||
config = _context.getProperty(PROP_SUMMARYBAR + page);
|
||||
if (config == null)
|
||||
@ -982,6 +1013,16 @@ public class SummaryHelper extends HelperBase {
|
||||
List<String> sections = getSummaryBarSections("default");
|
||||
TreeSet<String> sortedSections = new TreeSet<String>();
|
||||
|
||||
// Forward-convert old section names
|
||||
int pos = sections.indexOf("General");
|
||||
if (pos >= 0) {
|
||||
sections.set(pos, "RouterInfo");
|
||||
}
|
||||
pos = sections.indexOf("ShortGeneral");
|
||||
if (pos >= 0) {
|
||||
sections.set(pos, "ShortRouterInfo");
|
||||
}
|
||||
|
||||
for (int i = 0; i < allSections.length; i++) {
|
||||
String section = allSections[i];
|
||||
if (!sections.contains(section))
|
||||
|
@ -266,7 +266,7 @@ class SummaryRenderer {
|
||||
def.area(dsNames[0], AREA_COLOR, _listener.getRate().getRateStat().getDescription());
|
||||
def.line(dsNames[1], LINE_COLOR, "Events per period");
|
||||
*/
|
||||
if (hideLegend)
|
||||
if (hideLegend)
|
||||
def.setNoLegend(true);
|
||||
if (hideGrid) {
|
||||
def.setDrawXGrid(false);
|
||||
|
@ -34,6 +34,17 @@ function ajaxDone(url, target, refresh) {
|
||||
document.getElementById(target).innerHTML = failMessage;
|
||||
//document.getElementByClassName("hideifdown").style.display="none";
|
||||
}
|
||||
|
||||
// conditionally load sidebar refreshGraph script
|
||||
var graph = document.getElementById('sb_graphcontainer');
|
||||
if (graph) {
|
||||
var js_refreshGraph = document.createElement('script');
|
||||
js_refreshGraph.type = "text/javascript";
|
||||
js_refreshGraph.src = "/js/refreshGraph.js";
|
||||
js_refreshGraph.async = true;
|
||||
document.getElementsByTagName('head')[0].appendChild(js_refreshGraph);
|
||||
}
|
||||
|
||||
setTimeout(function() {ajax(url, target, refresh);}, refresh);
|
||||
}
|
||||
}
|
||||
|
8
apps/routerconsole/jsp/js/refreshGraph.js
Normal file
8
apps/routerconsole/jsp/js/refreshGraph.js
Normal file
@ -0,0 +1,8 @@
|
||||
// refresh the sidebar mini graph every 15 seconds
|
||||
|
||||
function refreshGraph() {
|
||||
document.getElementById('sb_graphcontainer').style.backgroundImage = 'url(/viewstat.jsp?stat=bw.combined&periodCount=20&width=220&height=50&hideLegend=true&hideGrid=true&time=' + new Date().getTime();
|
||||
setTimeout(refreshGraph, 15000);
|
||||
}
|
||||
|
||||
refreshGraph();
|
17
history.txt
17
history.txt
@ -5,6 +5,23 @@
|
||||
- Adjust size of up/down bw graph to match other graphs (ticket #1996)
|
||||
- Modify image font color to better blend with themes
|
||||
- Tweak spacing of elements for non-Debian installs
|
||||
- Sidebar:
|
||||
- Adjust vertical spacing of general section
|
||||
- Rename 'General' section to 'Router Info' and move ident info to h3
|
||||
tooltip (ticket #1996)
|
||||
- Replace 'Short Router Info' with a new 'Advanced Router Info' section in
|
||||
default advanced sidebar (adds memory usage and clock skew)
|
||||
- Add optional embedded bandwidth graph (experimental)
|
||||
- Add optional memory usage bar
|
||||
- Add optional Advanced Peers section (adds failing and banned peers)
|
||||
- Add Help link to 'I2P Internals' section
|
||||
- Add help page anchored links and troubleshooting to 'Help & FAQ' section
|
||||
- Add download progress bar for router and plugin updates
|
||||
- Add 'Advanced Minimal' sidebar configuration
|
||||
- Add Jobs and Events links to Advanced section
|
||||
- Add additional reachability states for clockskew and vmcomm (with icons)
|
||||
- Homepage: Add 'Customize Sidebar' link to signpost the feature now that
|
||||
there are more optional sections available (ticket #1996)
|
||||
|
||||
2017-10-11 zzz
|
||||
* Console: Validate host header (thx Kevin Froman)
|
||||
|
@ -527,18 +527,20 @@ img[src="/themes/console/images/i2plogo.png"] {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
#sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
|
||||
#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
|
||||
margin-bottom: -5px !important;
|
||||
margin-top: -6px !important;
|
||||
}
|
||||
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after, #sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
min-height: 14px;
|
||||
}
|
||||
|
||||
#sb_peers td:first-child, #sb_tunnels td:first-child, #sb_queue td:first-child, #sb_bandwidth td:first-child, #sb_general td:first-child, #sb_shortgeneral td:first-child {
|
||||
#sb_peers td:first-child, #sb_peersadvanced td:first-child, #sb_tunnels td:first-child, #sb_queue td:first-child,
|
||||
#sb_bandwidth td:first-child, #sb_general td:first-child, #sb_shortgeneral td:first-child, #sb_advancedgeneral td:first-child {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@ -547,6 +549,29 @@ img[src="/themes/console/images/i2plogo.png"] {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
#sb_peersadvanced a {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#sb_peersadvanced a b {
|
||||
color: #2c354f;
|
||||
}
|
||||
|
||||
#sb_peersadvanced a:hover b {
|
||||
color: #f60;
|
||||
}
|
||||
|
||||
#sb_peersadvanced .separator td::after {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
#sb_peersadvanced .separator hr {
|
||||
margin: 3px 0 2px !important;
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
border-bottom: 1px dashed #89f;
|
||||
}
|
||||
|
||||
#sb_localid {
|
||||
margin: -3px 0 -1px;
|
||||
}
|
||||
@ -559,11 +584,11 @@ img[src="/themes/console/images/i2plogo.png"] {
|
||||
margin: -1px 0 -3px;
|
||||
}
|
||||
|
||||
#sb_internals, #sb_services, #sb_advanced {
|
||||
#sb_internals, #sb_services, #sb_advanced, #sb_help {
|
||||
margin-top: -3px !important;
|
||||
}
|
||||
|
||||
#sb_internals a, #sb_services a, #sb_advanced a {
|
||||
#sb_internals a, #sb_services a, #sb_advanced a, #sb_help a {
|
||||
display: inline-block;
|
||||
padding: 2px;
|
||||
max-width: 194px;
|
||||
@ -834,6 +859,179 @@ div.refresh {
|
||||
|
||||
/* end network status */
|
||||
|
||||
/* mini sidebar graph */
|
||||
|
||||
#sb_bandwidthgraph {
|
||||
width: 202px !important;
|
||||
margin: 0;
|
||||
margin: -20px 0 0 0;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
padding: 0;
|
||||
border: 1px solid #89f;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 1px #ccf;
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph:hover {
|
||||
border: 1px solid #f60;
|
||||
cursor: url(/themes/console/images/cursor_zoom.png), pointer;
|
||||
}
|
||||
|
||||
a:active #sb_bandwidthgraph {
|
||||
border: 1px solid #f30;
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph td {
|
||||
background: linear-gradient(to top, #f3f3ff 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 89%, #f3f3ff 93%), linear-gradient(to right, #f3f3ff, rgba(255,255,255,0.0) 2%, rgba(255,255,255,0.0) 98%, #f3f3ff), repeating-linear-gradient(to right, rgba(255,255,255,0.0) 10px, rgba(120,120,255,0.8) 11px, rgba(255,255,255,0.0) 11px, rgba(255,255,255,0.0) 20px), repeating-linear-gradient(to top, rgba(255,255,255,0.0) 1px, rgba(120,120,255,0.8) 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 10px) !important;
|
||||
padding: 0 1px;
|
||||
box-shadow: inset 0 0 0 1px #fff;
|
||||
height: 38px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#sb_graphstats {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
font-weight: bold;
|
||||
background: #ddf;
|
||||
background: linear-gradient(to right, #ddf, #efefff, #ddf);
|
||||
border: 1px solid #89f;
|
||||
border-top: none;
|
||||
border-radius: 0 0 3px 3px;
|
||||
box-shadow: inset 0 0 0 1px #fff;
|
||||
opacity: 0;
|
||||
transition: ease opacity 0.3s;
|
||||
}
|
||||
|
||||
#sb_graphcontainer:hover #sb_graphstats {
|
||||
opacity: 1;
|
||||
transition: ease opacity 0.3s;
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
background-color: #f3f3ff;
|
||||
background-position: left -60px top -35px !important;
|
||||
background-position: left -60px top -29px !important;
|
||||
background-size: 280px 92px !important;
|
||||
background-size: 280px 77px !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-blend-mode: multiply;
|
||||
margin: 0 2px -21px 1px !important;
|
||||
padding: 0 5px 0 0;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
#sb_bandwidthgraph {
|
||||
width: 223px !important;
|
||||
background-size: 300px 92px !important;
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
background-size: 300px 77px !important;
|
||||
}
|
||||
}
|
||||
/* end mini sidebar graph */
|
||||
|
||||
/* status bars */
|
||||
|
||||
.percentBarOuter {
|
||||
width: 196px;
|
||||
margin: -4px 0 -5px 3px;
|
||||
text-align: center;
|
||||
border: 1px solid #99f;
|
||||
box-shadow: 0 0 1px rgba(200,200,200,0.8);
|
||||
background: #eef;
|
||||
background: repeating-linear-gradient(to right, rgba(180, 180, 255,0.7) 1px, rgba(180, 180, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 4px);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
.percentBarOuter {
|
||||
width: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
.percentBarInner {
|
||||
vertical-align: middle;
|
||||
border: none;
|
||||
height: 14px;
|
||||
background: #bbf;
|
||||
background: linear-gradient(to right, rgba(0,255,0,0.1) 65px, rgba(255,255,0,0.1) 110px, rgba(255,128,0,0.1) 175px, rgba(255,0,0,0.1)), linear-gradient(to bottom, rgba(255, 255, 255,0.6) 0%, rgba(238, 238, 255, 0.6) 50%, rgba(180, 180, 255, 0.7) 50%, rgba(140, 140, 255, 0.7) 100%);
|
||||
box-shadow: inset 0 0 0 1px #ddf;
|
||||
}
|
||||
|
||||
.percentBarText {
|
||||
display: inline !important;
|
||||
white-space: nowrap;
|
||||
text-align: center !important;
|
||||
font-weight: bold !important;
|
||||
color: #2c354f;
|
||||
text-shadow: 0 1px 1px rgba(255,255,255,0.8);
|
||||
float: left;
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
opacity: 0;
|
||||
transition: ease opacity 0.2s;
|
||||
}
|
||||
|
||||
.percentBarOuter:hover .percentBarText {
|
||||
opacity: 1;
|
||||
transition: ease opacity 0.2s;
|
||||
}
|
||||
|
||||
/* updates download bar */
|
||||
|
||||
.sb_updatestatus {
|
||||
display: block;
|
||||
border: 1px solid #99f;
|
||||
border-top: none;
|
||||
color: #2c354f;
|
||||
border-radius: 0 0 3px 3px;
|
||||
box-sizing: border-box;
|
||||
background: #ccf;
|
||||
background: linear-gradient(to right, #eef, #eff2ff 30%, #eff2ff 60%, #eef);
|
||||
box-shadow: inset 0 0 0 1px #fff;
|
||||
margin: -8px 2px 5px !important;
|
||||
padding: 3px 0 4px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.sb_info .percentBarOuter {
|
||||
margin: 3px -4px -5px 2px;
|
||||
background: repeating-linear-gradient(135deg, rgba(238, 238, 255,0.7) 1px, rgba(238, 238, 255, 0.7) 5px, rgba(221, 221, 255, 0.7) 6px, rgba(221, 221, 255, 0.7) 11px);
|
||||
}
|
||||
|
||||
@keyframes downloadbar {
|
||||
from {
|
||||
background: repeating-linear-gradient(135deg, rgba(221, 221, 255, 0.7) 1px, rgba(221, 221, 255, 0.7) 6px, rgba(238, 238, 255,0.7) 7px, rgba(238, 238, 255,0.7) 11px);
|
||||
}
|
||||
|
||||
to {
|
||||
background: repeating-linear-gradient(135deg, rgba(238, 238, 255,0.7) 1px, rgba(238, 238, 255, 0.7) 5px, rgba(221, 221, 255, 0.7) 6px, rgba(221, 221, 255, 0.7) 11px);
|
||||
}
|
||||
}
|
||||
|
||||
.sb_info .percentBarOuter {
|
||||
animation: downloadbar 3s infinite;
|
||||
}
|
||||
|
||||
.sb_info .percentBarInner {
|
||||
height: 16px;
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255,0.6) 0%, rgba(238, 238, 255, 0.6) 50%, rgba(180, 180, 255, 0.7) 50%, rgba(140, 140, 255, 0.7) 100%);
|
||||
|
||||
}
|
||||
|
||||
.sb_info .percentBarText {
|
||||
opacity: 1;
|
||||
padding-top: 2px;
|
||||
mix-blend-mode: multiply;
|
||||
color: #33f;
|
||||
|
||||
}
|
||||
/* end updates download bar */
|
||||
/* end status bars */
|
||||
|
||||
/* end sidebar */
|
||||
|
||||
/* welcome */
|
||||
@ -6886,8 +7084,8 @@ table.sybil_routerinfo:last-child {
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1500px) {
|
||||
#sb_general td:first-child::after, #sb_shortgeneral td:first-child::after, #sb_bandwidth td:first-child::after,
|
||||
#sb_peers td:first-child::after, #sb_tunnels td:first-child::after, #sb_queue td:first-child::after {
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
min-height: 12px;
|
||||
}
|
||||
|
||||
@ -6988,7 +7186,7 @@ tt a, .cells tt, #profilelist tt {
|
||||
padding: 4.5px 0 !important;
|
||||
}
|
||||
|
||||
#sb_internals a, #sb_services a, #sb_advanced a {
|
||||
#sb_internals a, #sb_services a, #sb_advanced a, #sb_help a {
|
||||
max-width: 212px;
|
||||
}
|
||||
|
||||
@ -6997,6 +7195,10 @@ tt a, .cells tt, #profilelist tt {
|
||||
margin: 2px 4px 1px;
|
||||
}
|
||||
|
||||
.percentBarOuter {
|
||||
width: 217px;
|
||||
}
|
||||
|
||||
div.app {
|
||||
width: 160px !important;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ input[type="submit"], input[type="cancel"], input[type="file"], button, button.s
|
||||
width: 80% !important;
|
||||
}
|
||||
|
||||
#sb_bandwidth td:last-child, #sb_peers td:last-child, #sb_queue td:last-child, #sb_tunnels td:last-child, #sb_general td:last-child, #sb_shortgeneral td:last-child {
|
||||
#sb_bandwidth td:last-child, #sb_peers td:last-child, #sb_peersadvanced td:last-child, #sb_queue td:last-child, #sb_tunnels td:last-child, #sb_general td:last-child, #sb_shortgeneral td:last-child, #sb_advancedgeneral td:last-child {
|
||||
font-size: 10pt !important;
|
||||
}
|
||||
|
||||
@ -76,6 +76,31 @@ input[type="submit"], input[type="cancel"], input[type="file"], button, button.s
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph {
|
||||
width: 218px !important;
|
||||
margin: -25px 0 -6px !important;
|
||||
}
|
||||
|
||||
#sb_graphstats {
|
||||
font-size: 9pt !important;
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
background-position: left -66px top -30px !important;
|
||||
background-size: 340px 80px !important;
|
||||
}
|
||||
|
||||
.percentBarOuter {
|
||||
width: 212px !important;
|
||||
margin: -3px 0 -4px 3px;
|
||||
}
|
||||
|
||||
.percentBarText {
|
||||
font-size: 9pt !important;
|
||||
padding: 0 !important;
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
/* end sidepanel */
|
||||
|
||||
/* global overrides */
|
||||
|
@ -397,22 +397,22 @@ div.warning {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
#sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
|
||||
#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
|
||||
margin-bottom: -4px !important;
|
||||
}
|
||||
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
min-height: 14px;
|
||||
}
|
||||
|
||||
#sb_general td, #sb_shortgeneral td {
|
||||
#sb_general td, #sb_shortgeneral td, #sb_advancedgeneral td, #sb_peersadvanced td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#sb_general td:first-child, #sb_shortgeneral td:first-child {
|
||||
#sb_general td:first-child, #sb_shortgeneral td:first-child, #sb_advancedgeneral td:first-child, #sb_peersadvanced td:first-child {
|
||||
max-width: 130px;
|
||||
}
|
||||
|
||||
@ -457,15 +457,15 @@ div.warning {
|
||||
line-height: 120%;
|
||||
}
|
||||
|
||||
#sb_internals td, #sb_services td, #sb_advanced td { /* color ellipsis */
|
||||
#sb_internals td, #sb_services td, #sb_advanced td, #sb_help td { /* color ellipsis */
|
||||
color: #595 !important;
|
||||
}
|
||||
|
||||
#sb_services, #sb_internals, #sb_advanced {
|
||||
#sb_services, #sb_internals, #sb_advanced, #sb_help {
|
||||
margin-top: -4px !important;
|
||||
}
|
||||
|
||||
#sb_internals a, #sb_services a, #sb_advanced a {
|
||||
#sb_internals a, #sb_services a, #sb_advanced a, #sb_help a {
|
||||
padding: 1px 3px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
@ -480,7 +480,7 @@ div.warning {
|
||||
margin-bottom: -5px !important;
|
||||
}
|
||||
|
||||
#sb_services a:link, #sb_internals a:link, #sb_advanced a:link {
|
||||
#sb_services a:link, #sb_internals a:link, #sb_advanced a:link, #sb_help a:link {
|
||||
word-break: break-all;
|
||||
max-width: 192px;
|
||||
overflow: hidden;
|
||||
@ -489,6 +489,23 @@ div.warning {
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
#sb_peersadvanced a {
|
||||
color: #ee9;
|
||||
}
|
||||
|
||||
#sb_peersadvanced .separator td::after {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.routersummary .separator hr, .routersummary .separator hr:last-child {
|
||||
display: block !important;
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
border-bottom: 1px dashed #141;
|
||||
height: 1px;
|
||||
margin: 4px 0 3px !important;
|
||||
}
|
||||
|
||||
.sb_notice {
|
||||
background: #010;
|
||||
border: 1px solid #262;
|
||||
@ -678,6 +695,168 @@ div.refresh {
|
||||
}
|
||||
|
||||
/* end sidebar news */
|
||||
|
||||
/* mini sidebar graph */
|
||||
|
||||
#sb_bandwidthgraph {
|
||||
width: 100%;
|
||||
margin: -5px 0 -5px -5px;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
padding: 0;
|
||||
border: 1px solid #5df;
|
||||
box-shadow: 0 0 1px #ccf;
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph:hover {
|
||||
border: 1px solid #f60;
|
||||
cursor: url(/themes/console/images/cursor_zoom.png), pointer;
|
||||
}
|
||||
|
||||
a:active #sb_bandwidthgraph {
|
||||
border: 1px solid #f30;
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph td {
|
||||
background: linear-gradient(to top, #fff 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 89%, #fff 93%), repeating-linear-gradient(to right, rgba(255,255,255,0.0) 10px, rgba(120,120,255,0.8) 11px, rgba(255,255,255,0.0) 11px, rgba(255,255,255,0.0) 20px), repeating-linear-gradient(to top, rgba(255,255,255,0.0) 1px, rgba(120,120,255,0.8) 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 10px) !important;
|
||||
padding: 0 1px;
|
||||
box-shadow: inset 0 0 0 1px #fff;
|
||||
height: 40px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#sb_graphstats {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
font-weight: bold;
|
||||
background: #ddf;
|
||||
background: linear-gradient(to right, #ddf, #efefff, #ddf);
|
||||
border: 1px solid #89f;
|
||||
border-top: none;
|
||||
border-radius: 0 0 3px 3px;
|
||||
box-shadow: inset 0 0 0 1px #fff, 0 0 1px #fff;
|
||||
opacity: 0;
|
||||
transition: ease opacity 0.3s;
|
||||
color: #89f;
|
||||
}
|
||||
|
||||
#sb_graphcontainer:hover #sb_graphstats {
|
||||
opacity: 1;
|
||||
transition: ease opacity 0.3s;
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
background-color: #000;
|
||||
background-position: left -72px top -23px !important;
|
||||
background-size: 280px 77px !important;
|
||||
background-repeat: no-repeat !important;
|
||||
margin-bottom: -7px !important;
|
||||
filter: invert(1) hue-rotate(90deg);
|
||||
}
|
||||
|
||||
/* reduce flicker as graph image gets inverted and hue-rotated */
|
||||
|
||||
@keyframes graphfadein {
|
||||
from {
|
||||
filter: invert(1) hue-rotate(90deg) opacity(0);
|
||||
}
|
||||
|
||||
to {
|
||||
filter: invert(1) hue-rotate(90deg) opacity(1);
|
||||
}
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
animation: graphfadein 0.3s ease-in;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
#sb_graphcontainer {
|
||||
background-size: 300px 77px !important;
|
||||
}
|
||||
}
|
||||
/* end mini sidebar graph */
|
||||
|
||||
/* status bar */
|
||||
|
||||
.percentBarOuter {
|
||||
width: 194px;
|
||||
background: #000;
|
||||
background: repeating-linear-gradient(135deg, #000 1px, #000 5px, #010 6px, #010 11px);
|
||||
background: repeating-linear-gradient(to right, #000 1px, #000 2px, #010 2px, #010 4px);
|
||||
border: 1px solid #040;
|
||||
border-bottom: 1px solid #020;
|
||||
border-right: 1px solid #020;
|
||||
opacity: 1;
|
||||
box-shadow: 0 0 1px 1px rgba(0,0,0,0.8);
|
||||
margin: -3px 0 -5px -6px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
.percentBarOuter {
|
||||
width: 220px;
|
||||
}
|
||||
}
|
||||
|
||||
.percentBarOuter:hover .percentBarText {
|
||||
opacity: 1;
|
||||
transition: ease opacity 0.2s;
|
||||
}
|
||||
|
||||
.percentBarInner {
|
||||
height: 14px;
|
||||
background: #0e5f00;
|
||||
background: linear-gradient(to bottom, rgba(28, 148, 58, 0.6) 0%, rgba(9, 47, 16, 0.6) 50%, rgba(13, 39, 7, 0.6) 50%, rgba(9, 27, 5, 0.6) 50%, rgba(9, 21, 3, 0.6) 100%);
|
||||
box-shadow: inset 0 0 0 1px #000;
|
||||
}
|
||||
|
||||
.percentBarText {
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
float: left;
|
||||
opacity: 0;
|
||||
transition: ease opacity 0.2s;
|
||||
}
|
||||
|
||||
/* update bar */
|
||||
|
||||
.sb_updatestatus {
|
||||
background: #000;
|
||||
background: linear-gradient(to right, #020, #000, #020);
|
||||
margin: -6px -2px -2px;
|
||||
padding: 2px 0 4px;
|
||||
border-bottom: 1px solid #494;
|
||||
}
|
||||
|
||||
.sb_info .percentBarOuter {
|
||||
margin: 6px -2px -18px 2px;
|
||||
box-shadow: none !important;
|
||||
background: repeating-linear-gradient(135deg, #000 1px, #000 5px, #010 6px, #010 11px);
|
||||
animation: downloadbar 3s infinite alternate;
|
||||
}
|
||||
|
||||
.sb_info .percentBarText {
|
||||
opacity: 1;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.sb_info .percentBarInner {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
@keyframes downloadbar {
|
||||
from {
|
||||
background: repeating-linear-gradient(135deg, #000 1px, #000 5px, #010 6px, #010 11px);
|
||||
}
|
||||
|
||||
to {
|
||||
background: repeating-linear-gradient(135deg, #010 1px, #010 6px, #000 7px, #000 11px);
|
||||
}
|
||||
}
|
||||
|
||||
/* end status bar */
|
||||
/* end sidebar */
|
||||
|
||||
/* console error messages */
|
||||
@ -6896,8 +7075,8 @@ td.optionsave {
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1500px) {
|
||||
#sb_general td:first-child::after, #sb_shortgeneral td:first-child::after, #sb_bandwidth td:first-child::after,
|
||||
#sb_peers td:first-child::after, #sb_tunnels td:first-child::after, #sb_queue td:first-child::after {
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
min-height: 12px;
|
||||
}
|
||||
|
||||
@ -7081,7 +7260,7 @@ p#fullhistory {
|
||||
min-height: 19px;
|
||||
}
|
||||
|
||||
#sb_services a:link, #sb_internals a:link, #sb_advanced a:link {
|
||||
#sb_services a:link, #sb_internals a:link, #sb_advanced a:link, #sb_help a:link {
|
||||
max-width: 216px !important;
|
||||
}
|
||||
|
||||
|
@ -532,6 +532,20 @@ a.viewfullentry::after, a[href^="viewprofile"]::after {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.percentBarOuter {
|
||||
margin: -3px -6px -5px 0;
|
||||
}
|
||||
|
||||
.sb_info .percentBarOuter {
|
||||
margin: 6px 2px -18px -2px;
|
||||
}
|
||||
|
||||
.sb_info .percentBarText {
|
||||
font-size: 9pt;
|
||||
padding-top: 1px;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.main#console .twocol {
|
||||
margin: 15px 35px 5px 0 !important;
|
||||
background: rgba(0, 32, 0, 0.5);
|
||||
|
@ -201,6 +201,13 @@ li .twocol {
|
||||
line-height: 120% !important;
|
||||
}
|
||||
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
min-height: 14px !important;
|
||||
}
|
||||
|
||||
.sb_newsheadings td, .sb_newsheadings tr:hover td {
|
||||
background-position: 4px center !important;
|
||||
padding-left: 24px !important;
|
||||
@ -210,6 +217,16 @@ li .twocol {
|
||||
font-size: 10pt !important;
|
||||
}
|
||||
|
||||
.percentBarOuter {
|
||||
width: 206px;
|
||||
margin: -1px 0 -2px -4px;
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
background-position: left -74px top -21px !important;
|
||||
background-size: 300px 77px !important;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 0) {
|
||||
body {
|
||||
font-family: "Droid Sans", "Noto Sans", Verdana, "Bitstream Vera Sans", Tahoma, Helvetica, sans-serif;
|
||||
|
BIN
installer/resources/themes/console/images/info/sidebar.png
Normal file
BIN
installer/resources/themes/console/images/info/sidebar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 896 B |
@ -14,6 +14,7 @@ body {
|
||||
background: #a4a4cb url(images/tile2.png) fixed;
|
||||
background-size: 32px 32px;
|
||||
}
|
||||
}
|
||||
|
||||
/* preload button mouseovers */
|
||||
body {
|
||||
@ -130,7 +131,7 @@ pre {
|
||||
|
||||
.routersummary div[style="height: 36px;"] {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding: 0 0 1px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@ -141,46 +142,41 @@ pre {
|
||||
}
|
||||
|
||||
.routersummary img[src$="i2plogo.png"] {
|
||||
opacity: 0.9;
|
||||
opacity: 0.7;
|
||||
transition: ease filter 0.3s 0s, ease opacity 0.3s 0s;
|
||||
margin-top: -1px;
|
||||
margin-left: -1px !important;
|
||||
width: 194px;
|
||||
margin: 0 !important;
|
||||
width: 190px;
|
||||
height: auto;
|
||||
filter: drop-shadow(0 0 1px #ccf);
|
||||
}
|
||||
|
||||
@media screen and (-webkit-min-device-pixel-ratio: 0) {
|
||||
.routersummary img[src$="i2plogo.png"] {
|
||||
margin-top: -2px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.routersummary img[src$="i2plogo.png"]:hover {
|
||||
opacity: 1;
|
||||
transition: ease filter 0.3s 0s, ease opacity 0.3s 0s;
|
||||
filter: drop-shadow(0 0 1px #f60);
|
||||
}
|
||||
|
||||
.routersummary a[href="/"]:focus img, .routersummary a[href="/console"]:focus img {
|
||||
filter: drop-shadow(0 0 1px #f60);
|
||||
}
|
||||
|
||||
.routersummary a:active img[src$="i2plogo.png"] {
|
||||
filter: drop-shadow(0 0 2px #f30);
|
||||
filter: drop-shadow(0 0 2px #d30);
|
||||
}
|
||||
|
||||
.routersummary a[href="/"], .routersummary a[href="/console"] {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.routersummary a[href="/"]:focus img, .routersummary a[href="/console"]:focus img {
|
||||
filter: drop-shadow(0 0 1px #f60);
|
||||
}
|
||||
|
||||
.routersummary form {
|
||||
margin: 0 -7px;
|
||||
margin: -2px -7px;
|
||||
padding: 0 0 3px;
|
||||
}
|
||||
|
||||
.routersummary form[action="/config"] {
|
||||
margin: -2px -7px;
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
.routersummary form {
|
||||
margin: -1px -7px -3px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.routersummary form button.download {
|
||||
@ -331,8 +327,8 @@ h4.sb_info + hr + form {
|
||||
}
|
||||
|
||||
#sb_version {
|
||||
margin-top: 5px !important;
|
||||
margin-bottom: 8px !important;
|
||||
margin-top: 7px !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
#sb_localtunnels td {
|
||||
@ -374,11 +370,12 @@ h4.sb_info + hr + form {
|
||||
background: #fffff0 !important;
|
||||
}
|
||||
|
||||
#sb_internals, #sb_advanced {
|
||||
margin: -9px -6px -6px;
|
||||
#sb_internals, #sb_advanced, #sb_help {
|
||||
margin: -9px -6px -5px;
|
||||
width: 204px !important;
|
||||
}
|
||||
|
||||
#sb_internals a, #sb_advanced a {
|
||||
#sb_internals a, #sb_advanced a, #sb_help a {
|
||||
padding: 2px;
|
||||
display: inline-block;
|
||||
vertical-align: middle !important;
|
||||
@ -387,34 +384,237 @@ h4.sb_info + hr + form {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
#sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
|
||||
#sb_internals a:hover, #sb_advanced a:hover, #sb_help a:hover {
|
||||
background: #ffd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
|
||||
margin-bottom: -4px !important;
|
||||
margin-top: -10px !important;
|
||||
}
|
||||
|
||||
#sb_general, #sb_shortgeneral {
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
|
||||
margin-bottom: -6px !important;
|
||||
}
|
||||
}
|
||||
|
||||
#sb_shortgeneral {
|
||||
margin-top: -7px !important;
|
||||
}
|
||||
|
||||
#sb_general td, #sb_shortgeneral td {
|
||||
#sb_general td, #sb_shortgeneral td, #sb_advancedgeneral td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#sb_general td:first-child, #sb_shortgeneral td:first-child {
|
||||
#sb_general td:first-child, #sb_shortgeneral td:first-child, #sb_advancedgeneral td:first-child {
|
||||
max-width: 130px;
|
||||
}
|
||||
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
min-height: 13px;
|
||||
}
|
||||
|
||||
#sb_peers td:first-child, #sb_tunnels td:first-child, #sb_queue td:first-child, #sb_bandwidth td:first-child, #sb_general td:first-child, #sb_shortgeneral td:first-child {
|
||||
#sb_peers td:first-child, #sb_peersadvanced td:first-child, #sb_tunnels td:first-child, #sb_queue td:first-child, #sb_bandwidth td:first-child,
|
||||
#sb_general td:first-child, #sb_shortgeneral td:first-child, #sb_advancedgeneral td:first-child {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
#sb_peersadvanced a:hover b, #sb_peersadvanced a:visited:hover b {
|
||||
color: #f60 !important
|
||||
}
|
||||
|
||||
#sb_peersadvanced a:active b, #sb_peersadvanced a:visited:active b {
|
||||
color: #f90 !important
|
||||
}
|
||||
|
||||
#sb_peersadvanced .separator td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.separator hr, .separator hr:last-child {
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
height: 1px;
|
||||
border-bottom: 1px dashed #99f !important;
|
||||
margin: 3px 0 -10px !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* mini sidebar graph */
|
||||
|
||||
#sb_bandwidthgraph {
|
||||
width: 100%;
|
||||
margin: -5px 0 -5px -5px;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
padding: 0;
|
||||
border: 1px solid #89f;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 1px #ccf;
|
||||
}
|
||||
|
||||
@media screen and (-webkit-min-device-pixel-ratio: 0) {
|
||||
#sb_bandwidthgraph {
|
||||
margin: -5px 0 -6px -5px !important;
|
||||
}
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph:hover {
|
||||
border: 1px solid #f60;
|
||||
cursor: url(/themes/console/images/cursor_zoom.png), pointer;
|
||||
}
|
||||
|
||||
a:active #sb_bandwidthgraph {
|
||||
border: 1px solid #f30;
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph td {
|
||||
background: linear-gradient(to top, #f3f3ff 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 89%, #f3f3ff 93%), linear-gradient(to right, #f3f3ff, rgba(255,255,255,0.0) 2%, rgba(255,255,255,0.0) 98%, #f3f3ff), repeating-linear-gradient(to right, rgba(255,255,255,0.0) 10px, rgba(120,120,255,0.8) 11px, rgba(255,255,255,0.0) 11px, rgba(255,255,255,0.0) 20px), repeating-linear-gradient(to top, rgba(255,255,255,0.0) 1px, rgba(120,120,255,0.8) 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 10px) !important;
|
||||
padding: 0 1px;
|
||||
box-shadow: inset 0 0 0 1px #fff;
|
||||
height: 40px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#sb_graphstats {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
font-weight: bold;
|
||||
background: #ddf;
|
||||
background: linear-gradient(to right, #ddf, #efefff, #ddf);
|
||||
border: 1px solid #89f;
|
||||
border-top: none;
|
||||
border-radius: 0 0 3px 3px;
|
||||
box-shadow: inset 0 0 0 1px #fff, 0 0 1px #fff;
|
||||
opacity: 0;
|
||||
transition: ease opacity 0.3s;
|
||||
}
|
||||
|
||||
#sb_graphcontainer:hover #sb_graphstats {
|
||||
opacity: 1;
|
||||
transition: ease opacity 0.3s;
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
background-color: #f3f3ff;
|
||||
background-position: left -60px top -23px !important;
|
||||
background-size: 280px 77px !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-blend-mode: multiply;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
#sb_graphcontainer {
|
||||
background-size: 300px 77px !important;
|
||||
}
|
||||
}
|
||||
/* end mini sidebar graph */
|
||||
|
||||
/* status bars for memory usage and router/plugin updates */
|
||||
|
||||
.percentBarOuter {
|
||||
width: 196px;
|
||||
margin: -4px -5px -4px -3px;
|
||||
text-align: center;
|
||||
border: 1px solid #99f;
|
||||
box-shadow: 0 0 1px rgba(200,200,200,0.8);
|
||||
background: #eef;
|
||||
background: linear-gradient(to right, rgba(0,255,0,0.05) 50%, rgba(255,255,0,0.05) 75%, rgba(255,128,0,0.05) 90%, rgba(255,0,0,0.1)), repeating-linear-gradient(to right, rgba(180, 180, 255,0.7) 1px, rgba(180, 180, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 4px);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
.percentBarOuter {
|
||||
width: 212px;
|
||||
}
|
||||
}
|
||||
|
||||
.percentBarInner {
|
||||
vertical-align: middle;
|
||||
border: none;
|
||||
height: 14px;
|
||||
background: #bbf;
|
||||
background: linear-gradient(to right, rgba(0,255,0,0.1) 65px, rgba(255,255,0,0.1) 110px, rgba(255,128,0,0.1) 175px, rgba(255,0,0,0.1)), linear-gradient(to bottom, rgba(255, 255, 255,0.6) 0%, rgba(238, 238, 255, 0.6) 50%, rgba(180, 180, 255, 0.7) 50%, rgba(140, 140, 255, 0.7) 100%);
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255,0.6) 0%, rgba(238, 238, 255, 0.6) 50%, rgba(180, 180, 255, 0.7) 50%, rgba(140, 140, 255, 0.7) 100%);
|
||||
box-shadow: inset 0 0 0 1px #ddf;
|
||||
}
|
||||
|
||||
.percentBarText {
|
||||
display: inline !important;
|
||||
white-space: nowrap;
|
||||
text-align: center !important;
|
||||
font-weight: bold !important;
|
||||
color: #41465f;
|
||||
text-shadow: 0 1px 1px rgba(255,255,255,0.8);
|
||||
float: left;
|
||||
width: 100%;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
opacity: 0;
|
||||
transition: ease opacity 0.2s;
|
||||
}
|
||||
|
||||
.percentBarOuter:hover .percentBarText {
|
||||
opacity: 1;
|
||||
transition: ease opacity 0.2s;
|
||||
}
|
||||
|
||||
/* updates download bar */
|
||||
|
||||
.sb_update a {
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.sb_updatestatus {
|
||||
display: block;
|
||||
font-style: italic;
|
||||
border: 1px solid #99f;
|
||||
border-top: none;
|
||||
border-radius: 0 0 3px 3px;
|
||||
background: #ccf;
|
||||
background: linear-gradient(to right, #ddf, #efefff 30%, #efefff 60%, #ddf);
|
||||
box-shadow: inset 0 0 0 1px #fff;
|
||||
margin: -7px 2px 5px !important;
|
||||
padding: 4px 0 3px;
|
||||
filter: drop-shadow(0 0 1px #ccf);
|
||||
}
|
||||
|
||||
.sb_info .percentBarOuter {
|
||||
margin: 3px -4px -19px 2px;
|
||||
background: repeating-linear-gradient(135deg, rgba(238, 238, 255,0.7) 1px, rgba(238, 238, 255, 0.7) 5px, rgba(221, 221, 255, 0.7) 6px, rgba(221, 221, 255, 0.7) 11px);
|
||||
}
|
||||
|
||||
@keyframes downloadbar {
|
||||
from {
|
||||
background: repeating-linear-gradient(135deg, rgba(221, 221, 255, 0.7) 1px, rgba(221, 221, 255, 0.7) 6px, rgba(238, 238, 255,0.7) 7px, rgba(238, 238, 255,0.7) 11px);
|
||||
}
|
||||
|
||||
to {
|
||||
background: repeating-linear-gradient(135deg, rgba(238, 238, 255,0.7) 1px, rgba(238, 238, 255, 0.7) 5px, rgba(221, 221, 255, 0.7) 6px, rgba(221, 221, 255, 0.7) 11px);
|
||||
}
|
||||
}
|
||||
|
||||
.sb_info .percentBarOuter {
|
||||
animation: downloadbar 3s infinite;
|
||||
}
|
||||
|
||||
.sb_info .percentBarInner {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.sb_info .percentBarText {
|
||||
opacity: 1;
|
||||
padding-top: 3px;
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
/* end updates download bar */
|
||||
/* end status bars */
|
||||
|
||||
#sb_warning {
|
||||
border-bottom: 1px solid #99f;
|
||||
}
|
||||
@ -551,16 +751,6 @@ p:empty + .sb_notice {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.routersummary img:first-child {
|
||||
margin-bottom: -2px !important;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.routersummary img:hover:first-child {
|
||||
margin-bottom: -2px !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* sidebar network status */
|
||||
|
||||
.routersummary .error, .routersummary .warn, .routersummary .testing, .routersummary .hidden,
|
||||
@ -713,7 +903,7 @@ p:empty + .sb_notice {
|
||||
|
||||
.sb_newsheadings table {
|
||||
table-layout: auto;
|
||||
width: 202px !important;
|
||||
width: 204px !important;
|
||||
margin: -12px 0 -8px -14px;
|
||||
}
|
||||
|
||||
@ -1715,7 +1905,7 @@ p#enablefullstats {
|
||||
|
||||
#sidebarconf button {
|
||||
margin: 2px 0 2px 3px !important;
|
||||
padding: 2px;
|
||||
padding: 2px 3px;
|
||||
min-width: 0;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
@ -3103,7 +3293,7 @@ h1 {
|
||||
background: #fcfcff;
|
||||
background: linear-gradient(135deg, #fcfcff, rgba(252,252,255,0) 600px), linear-gradient(to bottom, #fcfcff 50%, rgba(248,248,255,0.6) 50%), repeating-linear-gradient(135deg, rgba(255,255,255,0.5) 2px, rgba(221, 221, 255, 0.3) 3px, #fff 5px) #fafaff !important;
|
||||
border: 1px solid #447;
|
||||
border-radius: 2px;
|
||||
border-radius: 2px 2px 0 0;
|
||||
min-width: 546px;
|
||||
z-index: 999;
|
||||
}
|
||||
@ -7075,12 +7265,12 @@ body {
|
||||
margin: 5px 4px;
|
||||
}
|
||||
|
||||
#sb_general td:first-child::after, #sb_shortgeneral td:first-child::after, #sb_bandwidth td:first-child::after,
|
||||
#sb_peers td:first-child::after, #sb_tunnels td:first-child::after, #sb_queue td:first-child::after {
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after,
|
||||
#sb_bandwidth td::after, #sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
min-height: 12px;
|
||||
}
|
||||
|
||||
#sb_internals a, #sb_advanced a {
|
||||
#sb_internals a, #sb_advanced a #sb_help a {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
@ -7258,22 +7448,22 @@ h1 {
|
||||
margin-top: -2px !important;
|
||||
}
|
||||
|
||||
#sb_internals a, #sb_advanced a {
|
||||
#sb_internals a, #sb_advanced a, #sb_help a {
|
||||
max-width: 212px;
|
||||
}
|
||||
|
||||
#sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
|
||||
#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
|
||||
margin-bottom: -4px !important;
|
||||
margin-top: -10px !important;
|
||||
}
|
||||
|
||||
#sb_general, #sb_shortgeneral {
|
||||
margin-top: -7px !important;
|
||||
#sb_general, #sb_shortgeneral, #sb_advancedgeneral {
|
||||
margin-top: -7px !important;
|
||||
}
|
||||
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
min-height: 14px;
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
min-height: 14px;
|
||||
}
|
||||
|
||||
#banlist li {
|
||||
|
@ -46,6 +46,14 @@ h2, h3 {
|
||||
margin-bottom: -10px !important;
|
||||
}
|
||||
|
||||
.routersummaryouter {
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
.routersummary {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.routersummary h4 {
|
||||
text-align: center;
|
||||
}
|
||||
@ -203,6 +211,40 @@ div.wideload {
|
||||
background-position: right 6px center !important;
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
background-position: left -60px top -20px !important;
|
||||
transform: scale(-1, +1);
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph {
|
||||
margin: -5px -5px -5px 0;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (-webkit-min-device-pixel-ratio: 0) {
|
||||
#sb_bandwidthgraph {
|
||||
margin: -5px -5px -6px 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.percentBarOuter {
|
||||
margin: -4px -3px -4px -5px;
|
||||
background: linear-gradient(to left, rgba(0,255,0,0.05) 50%, rgba(255,255,0,0.05) 75%, rgba(255,128,0,0.05) 90%, rgba(255,0,0,0.1)), repeating-linear-gradient(to right, rgba(180, 180, 255,0.7) 1px, rgba(180, 180, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 2px, rgba(221, 221, 255, 0.7) 4px);
|
||||
}
|
||||
|
||||
.sb_info .percentBarOuter {
|
||||
margin: 3px 2px -19px -4px;
|
||||
}
|
||||
|
||||
.sb_updatestatus, .sb_info .percentBarText {
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
.sb_info .percentBarText {
|
||||
padding-top: 1px;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.routersummary td:last-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
@ -74,11 +74,20 @@ button.control {
|
||||
line-height: 130%;
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
background-position: left -60px top -20px !important;
|
||||
}
|
||||
|
||||
.sb_newsheadings td, .sb_newsheadings tr:hover td {
|
||||
background-position: 4px center !important;
|
||||
padding-left: 22px !important;
|
||||
}
|
||||
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after,
|
||||
#sb_bandwidth td::after, #sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
min-height: 15px !important;
|
||||
}
|
||||
|
||||
div.news, .newscontent p {
|
||||
font-size: 10pt !important;
|
||||
}
|
||||
|
@ -1293,20 +1293,20 @@ div.logo hr {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
#sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
|
||||
#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
|
||||
margin-top: -6px !important;
|
||||
margin-bottom: -5px !important;
|
||||
}
|
||||
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
min-height: 16px !important;
|
||||
}
|
||||
|
||||
#sb_general td, #sb_shortgeneral td {
|
||||
#sb_general td, #sb_shortgeneral td, #sb_advancedgeneral td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@ -1355,7 +1355,7 @@ div.logo hr {
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
|
||||
#sb_services a:link, #sb_internals a:link, #sb_advanced a:link {
|
||||
#sb_services a:link, #sb_internals a:link, #sb_advanced a:link, #sb_help a:link {
|
||||
word-break: break-all;
|
||||
max-width: 190px;
|
||||
overflow: hidden;
|
||||
@ -1367,14 +1367,15 @@ div.logo hr {
|
||||
padding: 1px 3px;
|
||||
}
|
||||
|
||||
#sb_services a:hover, #sb_internals a:hover, #sb_advanced a:hover, #sb_localtunnels tr:hover, #sb_localtunnels tr:hover a,
|
||||
#sb_services a:hover, #sb_internals a:hover, #sb_advanced a:hover, #sb_localtunnels tr:hover, #sb_localtunnels tr:hover a, #sb_help a:hover,
|
||||
.news a:hover, #console a:hover, tt a:hover {
|
||||
background: #652787;
|
||||
color: #fff !important;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
#sb_services a:active, #sb_internals a:active, #sb_advanced a:active, #sb_localtunnels tr:active, .news a:active, #console a:active, tt a:active {
|
||||
#sb_services a:active, #sb_internals a:active, #sb_advanced a:active, #sb_help a:active,
|
||||
#sb_localtunnels tr:active, .news a:active, #console a:active, tt a:active {
|
||||
background: #39144f;
|
||||
color: #c9ceff !important;
|
||||
}
|
||||
@ -1383,6 +1384,27 @@ div.logo hr {
|
||||
color: #c9ceff !important;
|
||||
}
|
||||
|
||||
#sb_peersadvanced a {
|
||||
padding: 0;
|
||||
color: #c9ceff;
|
||||
}
|
||||
|
||||
#sb_peersadvanced a:hover, #sb_peersadvanced a:focus {
|
||||
color: #652787;
|
||||
}
|
||||
|
||||
#sb_peersadvanced .separator td::after {
|
||||
min-height: 0 !important;
|
||||
}
|
||||
|
||||
#sb_peersadvanced .separator hr, #sb_peersadvanced .separator hr:last-child {
|
||||
display: block !important;
|
||||
margin: 3px 0 2px !important;
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
border-bottom: 1px dashed #2d296f;
|
||||
}
|
||||
|
||||
.sb_notice {
|
||||
background: #001;
|
||||
border: 1px solid #241f69;
|
||||
@ -1570,6 +1592,170 @@ p:empty + .sb_notice {
|
||||
}
|
||||
|
||||
/* end sidebar news */
|
||||
|
||||
/* mini sidebar graph */
|
||||
|
||||
#sb_bandwidthgraph {
|
||||
width: 100%;
|
||||
margin: -13px 0 0 -8px !important;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
padding: 0;
|
||||
border: 1px solid #5df;
|
||||
box-shadow: 0 0 1px #ccf;
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph:hover {
|
||||
border: 1px solid #f60;
|
||||
cursor: url(/themes/console/images/cursor_zoom.png), pointer;
|
||||
}
|
||||
|
||||
a:active #sb_bandwidthgraph {
|
||||
border: 1px solid #f30;
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph td {
|
||||
background: linear-gradient(to top, #f3f3ff 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 89%, #f3f3ff 93%), linear-gradient(to right, #f3f3ff, rgba(255,255,255,0.0) 2%, rgba(255,255,255,0.0) 98%, #f3f3ff), repeating-linear-gradient(to right, rgba(255,255,255,0.0) 10px, rgba(120,120,255,0.8) 11px, rgba(255,255,255,0.0) 11px, rgba(255,255,255,0.0) 20px), repeating-linear-gradient(to top, rgba(255,255,255,0.0) 1px, rgba(120,120,255,0.8) 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 10px) !important;
|
||||
background: linear-gradient(to top, #fff 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 89%, #fff 93%), repeating-linear-gradient(to right, rgba(255,255,255,0.0) 10px, rgba(120,120,255,0.8) 11px, rgba(255,255,255,0.0) 11px, rgba(255,255,255,0.0) 20px), repeating-linear-gradient(to top, rgba(255,255,255,0.0) 1px, rgba(120,120,255,0.8) 2px, rgba(255,255,255,0.0) 2px, rgba(255,255,255,0.0) 10px) !important;
|
||||
padding: 0 1px;
|
||||
box-shadow: inset 0 0 0 1px #fff;
|
||||
height: 40px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#sb_graphstats {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
font-weight: bold;
|
||||
background: #444;
|
||||
border: 1px solid #999;
|
||||
border-top: none;
|
||||
box-shadow: inset 0 0 0 1px #fff, 0 0 1px #fff;
|
||||
opacity: 0;
|
||||
transition: ease opacity 0.3s;
|
||||
}
|
||||
|
||||
#sb_graphcontainer:hover #sb_graphstats {
|
||||
opacity: 1;
|
||||
transition: ease opacity 0.3s;
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
background-color: #000;
|
||||
background-position: left -72px top -26px !important;
|
||||
background-size: 280px 90px !important;
|
||||
background-repeat: no-repeat !important;
|
||||
margin: -7px 0 -3px !important;
|
||||
height: 40px;
|
||||
filter: invert(1) sepia(1) hue-rotate(180deg);
|
||||
}
|
||||
|
||||
@keyframes graphfadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
animation: graphfadein 0.4s ease-in; /* attempt to mitigate strobe effect as image loads before filters are applied */
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
#sb_graphcontainer {
|
||||
background-size: 300px 77px !important;
|
||||
background-position: left -72px top -20px !important;
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph {
|
||||
width: 100%;
|
||||
margin: -15px 0 0 -8px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* end mini sidebar graph */
|
||||
|
||||
/* status bar */
|
||||
|
||||
.percentBarOuter {
|
||||
width: 194px;
|
||||
background: #000;
|
||||
background: repeating-linear-gradient(135deg, #001 1px, #001 5px, #003 6px, #003 11px);
|
||||
background: repeating-linear-gradient(to right, #000 1px, #000 2px, #003 2px, #003 4px);
|
||||
border: 1px solid #171c3f;
|
||||
opacity: 1;
|
||||
box-shadow: 0 0 1px 1px rgba(0,0,0,0.8);
|
||||
margin: -3px 0 -5px -6px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1500px) {
|
||||
.percentBarOuter {
|
||||
width: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
.percentBarOuter:hover .percentBarText {
|
||||
opacity: 1;
|
||||
transition: ease opacity 0.2s;
|
||||
}
|
||||
|
||||
.percentBarInner {
|
||||
height: 14px;
|
||||
background: #0e5f00;
|
||||
background: linear-gradient(to bottom, #33a 0%, #226 50%, #003 50%, #000 100%);
|
||||
box-shadow: inset 0 0 0 1px #000;
|
||||
}
|
||||
|
||||
.percentBarText {
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
float: left;
|
||||
opacity: 0;
|
||||
transition: ease opacity 0.2s;
|
||||
}
|
||||
|
||||
/* update bar */
|
||||
|
||||
.sb_updatestatus {
|
||||
background: #000;
|
||||
margin: -6px -4px -2px;
|
||||
padding: 2px 0 4px;
|
||||
border-bottom: 1px solid #443da0;
|
||||
color: #c9ceff;
|
||||
}
|
||||
|
||||
.sb_info .percentBarOuter {
|
||||
margin: 5px -2px -4px 0;
|
||||
box-shadow: none !important;
|
||||
background: repeating-linear-gradient(135deg, #001 1px, #001 5px, #003 6px, #003 11px);
|
||||
animation: downloadbar 3s infinite alternate;
|
||||
}
|
||||
.sb_info .percentBarText {
|
||||
opacity: 1;
|
||||
padding-top: 2px;
|
||||
color: #c9ceff;
|
||||
}
|
||||
|
||||
.sb_info .percentBarInner {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
@keyframes downloadbar {
|
||||
from {
|
||||
background: repeating-linear-gradient(135deg, #001 1px, #001 5px, #003 6px, #003 11px);
|
||||
}
|
||||
|
||||
to {
|
||||
background: repeating-linear-gradient(135deg, #003 1px, #003 6px, #001 7px, #001 11px);
|
||||
}
|
||||
}
|
||||
|
||||
/* end status bar */
|
||||
/* end sidebar */
|
||||
|
||||
/* console error messages */
|
||||
@ -6806,7 +6992,7 @@ form[action="events"] {
|
||||
|
||||
/* end network status */
|
||||
|
||||
#sb_services, #sb_internals, #sb_advanced {
|
||||
#sb_services, #sb_internals, #sb_advanced, #sb_help {
|
||||
margin-top: -3px !important;
|
||||
margin-bottom: -5px !important;
|
||||
}
|
||||
@ -7334,8 +7520,8 @@ table#i2pupdates td:first-child {
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1500px) {
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after, #sb_bandwidth td::after,
|
||||
#sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
min-height: 14px;
|
||||
}
|
||||
|
||||
@ -7431,7 +7617,8 @@ h1 {
|
||||
width: 216px !important;
|
||||
}
|
||||
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_bandwidth td::after, #sb_peers td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
#sb_general td::after, #sb_shortgeneral td::after, #sb_advancedgeneral td::after,
|
||||
#sb_bandwidth td::after, #sb_peers td::after, #sb_peersadvanced td::after, #sb_tunnels td::after, #sb_queue td::after {
|
||||
min-height: 18px;
|
||||
}
|
||||
|
||||
@ -7511,11 +7698,11 @@ div.joblog h3 {
|
||||
margin-top: 8px !important;
|
||||
}
|
||||
|
||||
#sb_services a:link, #sb_internals a:link, #sb_advanced a:link {
|
||||
#sb_services a:link, #sb_internals a:link, #sb_advanced a:link, #sb_help a:link {
|
||||
max-width: 207px;
|
||||
}
|
||||
|
||||
#sb_general, #sb_shortgeneral, #sb_bandwidth, #sb_peers, #sb_tunnels, #sb_queue {
|
||||
#sb_general, #sb_shortgeneral, #sb_advancedgeneral, #sb_bandwidth, #sb_peers, #sb_peersadvanced, #sb_tunnels, #sb_queue {
|
||||
margin-top: -4px !important;
|
||||
margin-bottom: -4px !important;
|
||||
}
|
||||
|
@ -91,6 +91,35 @@ button.search {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#sb_bandwidthgraph {
|
||||
margin: -13px -8px 0 0 !important;
|
||||
}
|
||||
|
||||
#sb_graphcontainer {
|
||||
background-position: left -72px top -24px !important;
|
||||
}
|
||||
|
||||
.percentBarOuter {
|
||||
margin: -3px -6px -5px 0;
|
||||
}
|
||||
|
||||
.sb_info .percentBarOuter {
|
||||
margin: 5px 0 -4px -2px;
|
||||
}
|
||||
|
||||
.sb_updatestatus b {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
.sb_updatestatus, .sb_info .percentBarText {
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
.sb_info .percentBarText {
|
||||
padding-top: 0;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.routersummary td a, .routersummary td:first-child {
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
Reference in New Issue
Block a user