forked from I2P_Developers/i2p.i2p
Console: Add js to /configui to preview themes
Save theme change before form processing so no refresh required Enable/disable reset and apply buttons on config clicks Prep for theme picker in wizard
This commit is contained in:
@@ -69,6 +69,16 @@ public class CSSHelper extends HelperBase {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* So we don't have to refresh after saving. Called from css.jsi.
|
||||
* @since 0.9.52
|
||||
*/
|
||||
public void setTheme(String theme) {
|
||||
if (theme != null && theme.length() > 0 &&
|
||||
theme.replaceAll("[a-zA-Z0-9_-]", "").length() == 0)
|
||||
_context.router().saveConfig(PROP_THEME_NAME, theme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether app embedding is enabled or disabled
|
||||
* @since 0.9.32
|
||||
|
||||
@@ -28,7 +28,7 @@ public class ConfigUIHandler extends FormHandler {
|
||||
delUser();
|
||||
} else if (_action.equals(_t("Add user"))) {
|
||||
addUser();
|
||||
}
|
||||
} // else lang change, handled in CSSHelper
|
||||
}
|
||||
|
||||
public void setShouldsave(String moo) { _shouldSave = true; }
|
||||
@@ -43,22 +43,23 @@ public class ConfigUIHandler extends FormHandler {
|
||||
_config = val;
|
||||
}
|
||||
|
||||
/** note - lang change is handled in CSSHelper but we still need to save it here */
|
||||
/**
|
||||
* This is for the theme options only.
|
||||
* Lang change is handled in CSSHelper.
|
||||
*/
|
||||
private void saveChanges() {
|
||||
if (_config == null || _config.length() <= 0)
|
||||
return;
|
||||
if (_config.replaceAll("[a-zA-Z0-9_-]", "").length() != 0) {
|
||||
addFormError("Bad theme name");
|
||||
return;
|
||||
}
|
||||
Map<String, String> changes = new HashMap<String, String>();
|
||||
List<String> removes = new ArrayList<String>();
|
||||
String oldTheme = _context.getProperty(CSSHelper.PROP_THEME_NAME, CSSHelper.DEFAULT_THEME);
|
||||
boolean oldForceMobileConsole = _context.getBooleanProperty(CSSHelper.PROP_FORCE_MOBILE_CONSOLE);
|
||||
if (_config.equals("default")) // obsolete
|
||||
removes.add(CSSHelper.PROP_THEME_NAME);
|
||||
else
|
||||
changes.put(CSSHelper.PROP_THEME_NAME, _config);
|
||||
boolean validTheme = _config != null && _config.length() > 0 &&
|
||||
_config.replaceAll("[a-zA-Z0-9_-]", "").length() == 0;
|
||||
if (validTheme) {
|
||||
if (_config.equals("default")) // obsolete
|
||||
removes.add(CSSHelper.PROP_THEME_NAME);
|
||||
else
|
||||
changes.put(CSSHelper.PROP_THEME_NAME, _config);
|
||||
}
|
||||
if (_universalTheming)
|
||||
changes.put(CSSHelper.PROP_UNIVERSAL_THEMING, "true");
|
||||
else
|
||||
@@ -73,11 +74,11 @@ public class ConfigUIHandler extends FormHandler {
|
||||
removes.add(CSSHelper.PROP_EMBED_APPS);
|
||||
boolean ok = _context.router().saveConfig(changes, removes);
|
||||
if (ok) {
|
||||
if (!oldTheme.equals(_config))
|
||||
addFormNoticeNoEscape(_t("Theme change saved.") +
|
||||
" <a href=\"configui\">" +
|
||||
_t("Refresh the page to view.") +
|
||||
"</a>");
|
||||
// Theme saving happens in CSSHelper
|
||||
// so output this even if it didn't change
|
||||
//if (!oldTheme.equals(_config))
|
||||
if (validTheme)
|
||||
addFormNotice(_t("Theme change saved."));
|
||||
if (oldForceMobileConsole != _forceMobileConsole)
|
||||
addFormNoticeNoEscape(_t("Mobile console option saved.") +
|
||||
" <a href=\"configui\">" +
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ConfigUIHelper extends HelperBase {
|
||||
}
|
||||
boolean universalTheming = _context.getBooleanProperty(CSSHelper.PROP_UNIVERSAL_THEMING);
|
||||
buf.append("</div><div id=\"themeoptions\">" +
|
||||
"<label><input type=\"checkbox\" name=\"universalTheming\" ");
|
||||
"<label><input id=\"themebox1\" type=\"checkbox\" name=\"universalTheming\" ");
|
||||
if (universalTheming)
|
||||
buf.append(CHECKED);
|
||||
buf.append("value=\"1\">")
|
||||
@@ -53,7 +53,7 @@ public class ConfigUIHelper extends HelperBase {
|
||||
public String getForceMobileConsole() {
|
||||
StringBuilder buf = new StringBuilder(256);
|
||||
boolean forceMobileConsole = _context.getBooleanProperty(CSSHelper.PROP_FORCE_MOBILE_CONSOLE);
|
||||
buf.append("<label><input type=\"checkbox\" name=\"forceMobileConsole\" ");
|
||||
buf.append("<label><input id=\"themebox2\" type=\"checkbox\" name=\"forceMobileConsole\" ");
|
||||
if (forceMobileConsole)
|
||||
buf.append(CHECKED);
|
||||
buf.append("value=\"1\">")
|
||||
@@ -62,7 +62,7 @@ public class ConfigUIHelper extends HelperBase {
|
||||
boolean embedApps = _context.getBooleanProperty(CSSHelper.PROP_EMBED_APPS);
|
||||
buf.append("<label title=\"")
|
||||
.append(_t("Enabling the Universal Theming option is recommended when embedding these applications"))
|
||||
.append("\"><input type=\"checkbox\" name=\"embedApps\" ");
|
||||
.append("\"><input id=\"themebox3\" type=\"checkbox\" name=\"embedApps\" ");
|
||||
if (embedApps)
|
||||
buf.append(CHECKED);
|
||||
buf.append("value=\"1\">")
|
||||
|
||||
@@ -13,6 +13,7 @@ input.default {
|
||||
}
|
||||
</style>
|
||||
<%@include file="summaryajax.jsi" %>
|
||||
<script src="/js/configui.js?<%=net.i2p.CoreVersion.VERSION%>" type="text/javascript"></script>
|
||||
</head><body>
|
||||
<%@include file="summary.jsi" %>
|
||||
<jsp:useBean class="net.i2p.router.web.helpers.ConfigUIHelper" id="uihelper" scope="request" />
|
||||
@@ -26,7 +27,7 @@ input.default {
|
||||
<jsp:useBean class="net.i2p.router.web.helpers.ConfigUIHandler" id="formhandler" scope="request" />
|
||||
<%@include file="formhandler.jsi" %>
|
||||
<h3 id="themeheading"><%=uihelper._t("Router Console Theme")%></h3>
|
||||
<form action="" method="POST">
|
||||
<form id="themeForm" action="" method="POST">
|
||||
<input type="hidden" name="consoleNonce" value="<%=net.i2p.router.web.CSSHelper.getNonce()%>" >
|
||||
<input type="hidden" name="nonce" value="<%=pageNonce%>" >
|
||||
<input type="hidden" name="action" value="blah" >
|
||||
@@ -43,8 +44,8 @@ input.default {
|
||||
<% } %>
|
||||
<jsp:getProperty name="uihelper" property="forceMobileConsole" />
|
||||
<hr><div class="formaction" id="themeui">
|
||||
<input type="reset" class="cancel" value="<%=intl._t("Cancel")%>" >
|
||||
<input type="submit" name="shouldsave" class="accept" value="<%=intl._t("Apply")%>" >
|
||||
<input id="themeCancel" type="reset" class="cancel" value="<%=intl._t("Cancel")%>" >
|
||||
<input id="themeApply" type="submit" name="shouldsave" class="accept" value="<%=intl._t("Apply")%>" >
|
||||
</div></div></form>
|
||||
<h3 id="langheading"><%=uihelper._t("Router Console Language")%></h3>
|
||||
<form action="" method="POST">
|
||||
@@ -56,7 +57,7 @@ input.default {
|
||||
<p id="helptranslate"><%=uihelper._t("Please contribute to the router console translation project! Contact the developers in #i2p-dev on IRC to help.")%>
|
||||
</p><hr><div class="formaction" id="langui">
|
||||
<input type="reset" class="cancel" value="<%=intl._t("Cancel")%>" >
|
||||
<input type="submit" name="shouldsave" class="accept" value="<%=intl._t("Apply")%>" >
|
||||
<input type="submit" name="foo" class="accept" value="<%=intl._t("Apply")%>" >
|
||||
</div></div></form>
|
||||
|
||||
<h3 id="passwordheading"><%=uihelper._t("Router Console Password")%></h3>
|
||||
|
||||
@@ -33,11 +33,6 @@
|
||||
<jsp:useBean class="net.i2p.router.web.CSSHelper" id="intl" scope="request" />
|
||||
<jsp:setProperty name="intl" property="contextId" value="<%=i2pcontextId%>" /><%
|
||||
|
||||
// used several times below
|
||||
String theUserAgent = request.getHeader("User-Agent");
|
||||
String theThemePath = intl.getTheme(theUserAgent);
|
||||
|
||||
%><link rel="icon" href="<%=theThemePath%>images/favicon.ico"><%
|
||||
response.setHeader("Accept-Ranges", "none");
|
||||
|
||||
String cspNonce = Integer.toHexString(net.i2p.util.RandomSource.getInstance().nextInt());
|
||||
@@ -61,8 +56,13 @@
|
||||
if (net.i2p.router.web.CSSHelper.getNonce().equals(conNonceParam)) {
|
||||
intl.setLang(request.getParameter("lang"));
|
||||
intl.setNews(request.getParameter("news"));
|
||||
intl.setTheme(request.getParameter("theme"));
|
||||
}
|
||||
%><link href="<%=theThemePath%>console.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css">
|
||||
// used several times below
|
||||
String theUserAgent = request.getHeader("User-Agent");
|
||||
String theThemePath = intl.getTheme(theUserAgent);
|
||||
%><link rel="icon" href="<%=theThemePath%>images/favicon.ico">
|
||||
<link id="pagestyle" href="<%=theThemePath%>console.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css">
|
||||
<%
|
||||
if (intl.getLang().equals("zh")) {
|
||||
// make the fonts bigger for chinese
|
||||
|
||||
67
apps/routerconsole/jsp/js/configui.js
Normal file
67
apps/routerconsole/jsp/js/configui.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/* @license http://creativecommons.org/publicdomain/zero/1.0/legalcode CC0-1.0 */
|
||||
|
||||
// This component is dedicated to the public domain. It uses the CC0
|
||||
// as a formal dedication to the public domain and in circumstances where
|
||||
// a public domain is not usable.
|
||||
|
||||
var prefersDarkTheme = false;
|
||||
var oldTheme = "light";
|
||||
|
||||
function detectDark() {
|
||||
// https://stackoverflow.com/questions/56393880/how-do-i-detect-dark-mode-using-javascript
|
||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
// dark mode
|
||||
prefersDarkTheme = true;
|
||||
}
|
||||
}
|
||||
|
||||
function swapStyleSheet(theme) {
|
||||
// https://stackoverflow.com/questions/14292997/changing-style-sheet-javascript
|
||||
document.getElementById("pagestyle").setAttribute("href", "/themes/console/" + theme + "/console.css");
|
||||
document.getElementById("i2plogo").setAttribute("src", "/themes/console/" + theme + "/images/i2plogo.png");
|
||||
}
|
||||
|
||||
function disableButtons(disabled) {
|
||||
document.getElementById("themeApply").disabled = disabled;
|
||||
document.getElementById("themeCancel").disabled = disabled;
|
||||
}
|
||||
|
||||
function resetStyleSheet() {
|
||||
swapStyleSheet(oldTheme);
|
||||
document.getElementById("themeForm").reset();
|
||||
disableButtons(true);
|
||||
}
|
||||
|
||||
function initThemeSwitcher() {
|
||||
var dark = document.getElementById("dark");
|
||||
dark.onclick = function() {
|
||||
swapStyleSheet("dark");
|
||||
disableButtons(false);
|
||||
}
|
||||
if (dark.checked) {
|
||||
oldTheme = "dark";
|
||||
}
|
||||
var light = document.getElementById("light");
|
||||
light.onclick = function() {
|
||||
swapStyleSheet("light");
|
||||
disableButtons(false);
|
||||
}
|
||||
var apply = document.getElementById("themeApply");
|
||||
apply.setAttribute("disabled", true);
|
||||
var cancel = document.getElementById("themeCancel");
|
||||
cancel.setAttribute("disabled", true);
|
||||
cancel.onclick = function() {
|
||||
resetStyleSheet();
|
||||
}
|
||||
document.getElementById("themebox1").onclick = function() { disableButtons(false); }
|
||||
document.getElementById("themebox2").onclick = function() { disableButtons(false); }
|
||||
document.getElementById("themebox3").onclick = function() { disableButtons(false); }
|
||||
// unused for now
|
||||
detectDark();
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
initThemeSwitcher();
|
||||
}, true);
|
||||
|
||||
/* @license-end */
|
||||
@@ -8,7 +8,7 @@
|
||||
%>
|
||||
<div>
|
||||
<a href="/" target="_top">
|
||||
<img src="<%=intl.getTheme(request.getHeader("User-Agent"))%>images/i2plogo.png" alt="<%=intl._t("I2P Router Console")%>" title="<%=intl._t("I2P Router Console")%>">
|
||||
<img id="i2plogo" src="<%=intl.getTheme(request.getHeader("User-Agent"))%>images/i2plogo.png" alt="<%=intl._t("I2P Router Console")%>" title="<%=intl._t("I2P Router Console")%>">
|
||||
</a>
|
||||
</div>
|
||||
<div id="xhr">
|
||||
|
||||
Reference in New Issue
Block a user