Squash a lot of things
This commit is contained in:
parent
5090443b7a
commit
bf486dd276
|
@ -1,15 +1,15 @@
|
|||
package mdnet.base;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import mdnet.base.settings.ClientSettings;
|
||||
import mdnet.cache.DiskLruCache;
|
||||
import mdnet.webui.WebConsole;
|
||||
import org.http4k.server.Http4kServer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -171,36 +171,63 @@ public class MangaDexClient {
|
|||
+ ") initializing\n");
|
||||
System.out.println("Copyright (c) 2020, MangaDex Network");
|
||||
|
||||
String file = "settings.json";
|
||||
if (args.length == 1) {
|
||||
file = args[0];
|
||||
} else if (args.length != 0) {
|
||||
MangaDexClient.dieWithError("Expected one argument: path to config file, or nothing");
|
||||
}
|
||||
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
ClientSettings settings;
|
||||
|
||||
try {
|
||||
String file = "settings.json";
|
||||
if (args.length == 1) {
|
||||
file = args[0];
|
||||
} else if (args.length != 0) {
|
||||
MangaDexClient.dieWithError("Expected one argument: path to config file, or nothing");
|
||||
settings = gson.fromJson(new FileReader(file), ClientSettings.class);
|
||||
} catch (FileNotFoundException ignored) {
|
||||
settings = new ClientSettings();
|
||||
LOGGER.warn("Settings file {} not found, generating file", file);
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
writer.write(gson.toJson(settings));
|
||||
} catch (IOException e) {
|
||||
MangaDexClient.dieWithError(e);
|
||||
}
|
||||
}
|
||||
|
||||
ClientSettings settings = new Gson().fromJson(new FileReader(file), ClientSettings.class);
|
||||
if (!ClientSettings.isSecretValid(settings.getClientSecret()))
|
||||
MangaDexClient.dieWithError("Config Error: API Secret is invalid, must be 52 alphanumeric characters");
|
||||
|
||||
if (!ClientSettings.isSecretValid(settings.getClientSecret()))
|
||||
MangaDexClient.dieWithError("Config Error: API Secret is invalid, must be 52 alphanumeric characters");
|
||||
if (settings.getClientPort() == 0) {
|
||||
MangaDexClient.dieWithError("Config Error: Invalid port number");
|
||||
}
|
||||
|
||||
if (settings.getClientPort() == 0) {
|
||||
MangaDexClient.dieWithError("Config Error: Invalid port number");
|
||||
}
|
||||
if (settings.getMaxCacheSizeMib() < 1024) {
|
||||
MangaDexClient.dieWithError("Config Error: Invalid max cache size, must be >= 1024 MiB (1GiB)");
|
||||
}
|
||||
|
||||
if (settings.getMaxCacheSizeMib() < 1024) {
|
||||
MangaDexClient.dieWithError("Config Error: Invalid max cache size, must be >= 1024 MiB (1GiB)");
|
||||
}
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Client settings loaded: {}", settings);
|
||||
}
|
||||
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Client settings loaded: {}", settings);
|
||||
}
|
||||
MangaDexClient client = new MangaDexClient(settings);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(client::shutdown));
|
||||
client.runLoop();
|
||||
|
||||
MangaDexClient client = new MangaDexClient(settings);
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(client::shutdown));
|
||||
client.runLoop();
|
||||
} catch (FileNotFoundException e) {
|
||||
MangaDexClient.dieWithError(e);
|
||||
if (settings.getWebSettings() != null) {
|
||||
// java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
|
||||
// System.setOut(new java.io.PrintStream(out));
|
||||
// TODO: system.out redirect
|
||||
ClientSettings finalSettings = settings;
|
||||
new Thread(() -> {
|
||||
WebConsole webConsole = new WebConsole(finalSettings.getWebSettings().getClientWebsocketPort()) {
|
||||
@Override
|
||||
protected void parseMessage(String message) {
|
||||
System.out.println(message);
|
||||
// TODO: something happens here
|
||||
// the message should be formatted in json
|
||||
}
|
||||
};
|
||||
// TODO: webConsole.sendMessage(t,m) whenever system.out is written to
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package mdnet.base;
|
|||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.Unirest;
|
||||
import kong.unirest.json.JSONObject;
|
||||
import mdnet.base.settings.ClientSettings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package mdnet.base;
|
||||
package mdnet.base.settings;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
|
@ -18,15 +18,28 @@ public final class ClientSettings {
|
|||
private final String clientSecret;
|
||||
@SerializedName("threads")
|
||||
private final int threads;
|
||||
@SerializedName("web_settings")
|
||||
private final WebSettings webSettings;
|
||||
|
||||
public ClientSettings() {
|
||||
this.maxCacheSizeMib = 20480;
|
||||
this.maxBandwidthMibPerHour = 0;
|
||||
this.maxBurstRateKibPerSecond = 0;
|
||||
this.clientPort = 1200;
|
||||
this.clientSecret = "PASTE-YOUR-SECRET-HERE";
|
||||
this.threads = 32;
|
||||
this.webSettings = new WebSettings();
|
||||
}
|
||||
|
||||
public ClientSettings(long maxCacheSizeMib, long maxBandwidthMibPerHour, long maxBurstRateKibPerSecond,
|
||||
int clientPort, String clientSecret, int threads) {
|
||||
int clientPort, String clientSecret, int threads, WebSettings webSettings) {
|
||||
this.maxCacheSizeMib = maxCacheSizeMib;
|
||||
this.maxBandwidthMibPerHour = maxBandwidthMibPerHour;
|
||||
this.maxBurstRateKibPerSecond = maxBurstRateKibPerSecond;
|
||||
this.clientPort = clientPort;
|
||||
this.clientSecret = Objects.requireNonNull(clientSecret);
|
||||
this.threads = threads;
|
||||
this.webSettings = webSettings;
|
||||
}
|
||||
|
||||
public long getMaxCacheSizeMib() {
|
||||
|
@ -48,9 +61,12 @@ public final class ClientSettings {
|
|||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
public WebSettings getWebSettings() {
|
||||
return webSettings;
|
||||
}
|
||||
|
||||
public int getThreads() {
|
||||
return (threads > 0) ? threads : 16;
|
||||
return threads;
|
||||
}
|
||||
|
||||
@Override
|
25
src/main/java/mdnet/base/settings/WebSettings.java
Normal file
25
src/main/java/mdnet/base/settings/WebSettings.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package mdnet.base.settings;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public final class WebSettings {
|
||||
@SerializedName("client_websocket_port")
|
||||
private final int clientWebsocketPort;
|
||||
|
||||
public WebSettings() {
|
||||
this.clientWebsocketPort = 33333;
|
||||
}
|
||||
|
||||
public WebSettings(int clientWebsocketPort) {
|
||||
this.clientWebsocketPort = clientWebsocketPort;
|
||||
}
|
||||
|
||||
public int getClientWebsocketPort() {
|
||||
return clientWebsocketPort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WebSettings{" + "clientWebsocketPort=" + clientWebsocketPort + '}';
|
||||
}
|
||||
}
|
107
src/main/java/mdnet/webui/WebConsole.java
Normal file
107
src/main/java/mdnet/webui/WebConsole.java
Normal file
|
@ -0,0 +1,107 @@
|
|||
package mdnet.webui;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import mdnet.base.Statistics;
|
||||
import org.java_websocket.WebSocket;
|
||||
import org.java_websocket.handshake.ClientHandshake;
|
||||
import org.java_websocket.server.WebSocketServer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class WebConsole extends WebSocketServer {
|
||||
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(WebConsole.class);
|
||||
|
||||
public WebConsole(int port) {
|
||||
super(new InetSocketAddress(port));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket conn, ClientHandshake handshake) {
|
||||
LOGGER.info("Webclient {} connected", conn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
|
||||
LOGGER.info("Webclient {} disconnected: {} ", conn, reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket conn, String message) {
|
||||
parseMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket conn, ByteBuffer message) {
|
||||
// parseMessage(message.array().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebSocket conn, Exception ex) {
|
||||
ex.printStackTrace();
|
||||
if (conn != null) {
|
||||
// some errors like port binding failed may not be assignable to a specific
|
||||
// websocket
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
LOGGER.info("Listening for connections on port: {}", this.getPort());
|
||||
setConnectionLostTimeout(0);
|
||||
setConnectionLostTimeout(100);
|
||||
}
|
||||
|
||||
protected abstract void parseMessage(String message);
|
||||
|
||||
// void parseCommand(String x) {
|
||||
// switch (x) {
|
||||
// case "help":
|
||||
// this.broadcast(formatMessage("command", "Available commands:"));
|
||||
// this.broadcast(formatMessage("command", "you"));
|
||||
// this.broadcast(formatMessage("command", "are"));
|
||||
// this.broadcast(formatMessage("command", "big"));
|
||||
// this.broadcast(formatMessage("command", "gay"));
|
||||
// break;
|
||||
// case "stop":
|
||||
// this.broadcast(formatMessage("command", "Mangadex Client has shut down,
|
||||
// shutting down web client now"));
|
||||
// return;
|
||||
// default:
|
||||
// this.broadcast(formatMessage("command", "That command was not recognized"));
|
||||
// this.broadcast(formatMessage("command", "Try help for a list of available
|
||||
// commands"));
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
public void sendMessage(String type, Object message) {
|
||||
// JSONObject out = new JSONObject();
|
||||
// switch (type) {
|
||||
// case "command" :
|
||||
// out.put("type", "command");
|
||||
// out.put("data", message.toString());
|
||||
// break;
|
||||
// case "stats" :
|
||||
// out.put("type", "stats");
|
||||
// AtomicReference<Statistics> temp = (AtomicReference<Statistics>) message;
|
||||
// out.put("hits", temp.get().getCacheHits());
|
||||
// out.put("misses", temp.get().getCacheMisses());
|
||||
// out.put("bytes_sent", temp.get().getBytesSent());
|
||||
// out.put("req_served", temp.get().getRequestsServed());
|
||||
// out.put("dataval", "empty");
|
||||
// out.put("dataval", "empty");
|
||||
// out.put("dataval", "empty");
|
||||
// break;
|
||||
// case "auth" :
|
||||
// break;
|
||||
// default :
|
||||
// out.put("type", "command");
|
||||
// out.put("data", message.toString());
|
||||
// break;
|
||||
// }
|
||||
// broadcast(out.toString());
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
/* ktlint-disable no-wildcard-imports */
|
||||
package mdnet.base
|
||||
|
||||
import mdnet.base.settings.ClientSettings
|
||||
import mdnet.cache.DiskLruCache
|
||||
import org.apache.http.client.config.CookieSpecs
|
||||
import org.apache.http.client.config.RequestConfig
|
||||
|
@ -18,8 +19,10 @@ import org.http4k.filter.CachingFilters
|
|||
import org.http4k.filter.MaxAgeTtl
|
||||
import org.http4k.filter.ServerFilters
|
||||
import org.http4k.lens.Path
|
||||
import org.http4k.routing.ResourceLoader
|
||||
import org.http4k.routing.bind
|
||||
import org.http4k.routing.routes
|
||||
import org.http4k.routing.singlePageApp
|
||||
import org.http4k.server.Http4kServer
|
||||
import org.http4k.server.asServer
|
||||
import org.slf4j.LoggerFactory
|
||||
|
@ -211,7 +214,9 @@ fun getServer(cache: DiskLruCache, serverSettings: ServerSettings, clientSetting
|
|||
"/data/{chapterHash}/{fileName}" bind Method.GET to app(false),
|
||||
"/data-saver/{chapterHash}/{fileName}" bind Method.GET to app(true),
|
||||
"/{token}/data/{chapterHash}/{fileName}" bind Method.GET to app(false),
|
||||
"/{token}/data-saver/{chapterHash}/{fileName}" bind Method.GET to app(true)
|
||||
"/{token}/data-saver/{chapterHash}/{fileName}" bind Method.GET to app(true),
|
||||
|
||||
singlePageApp(ResourceLoader.Classpath("/webui"))
|
||||
)
|
||||
)
|
||||
.asServer(Netty(serverSettings.tls, clientSettings, statistics))
|
||||
|
|
405
src/main/resources/webui/dataReceive.js
Normal file
405
src/main/resources/webui/dataReceive.js
Normal file
|
@ -0,0 +1,405 @@
|
|||
let connection;
|
||||
let theme;
|
||||
let style;
|
||||
let port;
|
||||
let ip;
|
||||
let refreshRate;
|
||||
let maxConsoleLines;
|
||||
let graphTimeFrame;
|
||||
let showConsoleLatest;
|
||||
let doAnimations;
|
||||
//non-option var
|
||||
let statRequest;
|
||||
//stat vars
|
||||
|
||||
|
||||
jQuery(document).ready(function () {
|
||||
loadOptions();
|
||||
$("#theme").attr("href", "themes/" + theme + ".css");
|
||||
$("#style").attr("href", "themes/" + style + ".css");
|
||||
if (doAnimations) {
|
||||
$(".optionInput").addClass("smooth");
|
||||
$(".slider").addClass("smoothslider").addClass("smooth");
|
||||
$(".content").addClass("slide_up");
|
||||
$(".sideOption").addClass("smooth");
|
||||
$(".button").addClass("smooth");
|
||||
}
|
||||
if (showConsoleLatest)
|
||||
$("#consoleLatest").attr("hidden", false);
|
||||
reconnect();
|
||||
$("#console_input").keyup(function (e) {
|
||||
if (e.keyCode === 13) {
|
||||
sendCommand($(this).text());
|
||||
$(this).text("");
|
||||
$('#console_text').scrollTop($("#console_text")[0].scrollHeight)
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
//site functions, no connections involved
|
||||
|
||||
$(window).on("click", function () {
|
||||
let sideBar = $("#sideBar");
|
||||
if (sideBar.hasClass("expanded")) {
|
||||
sideBar.removeClass("expanded").addClass("retract").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("retract").removeClass("expanded");
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
function loadOptions() {
|
||||
let options = JSON.parse(localStorage.getItem("options"));
|
||||
if (options === null) {
|
||||
options = {
|
||||
refresh_rate: 5000,
|
||||
theme: "lightTheme",
|
||||
style: "sharpStyle",
|
||||
client_port: 33333,
|
||||
client_ip: "localhost",
|
||||
max_console_lines: 1000,
|
||||
show_console_latest: false,
|
||||
graph_time_frame: 30000,
|
||||
do_animations: true
|
||||
}
|
||||
}
|
||||
theme = options.theme;
|
||||
style = options.style;
|
||||
port = options.client_port;
|
||||
ip = options.client_ip;
|
||||
refreshRate = options.refresh_rate;
|
||||
maxConsoleLines = options.max_console_lines;
|
||||
graphTimeFrame = options.graph_time_frame;
|
||||
showConsoleLatest = options.show_console_latest;
|
||||
doAnimations = options.do_animations;
|
||||
$("#dataRefreshRate").val(refreshRate);
|
||||
$("#port").val(port);
|
||||
$("#ip").val(ip);
|
||||
$("#maxConsoleLines").val(maxConsoleLines);
|
||||
$("#graphTimeFrame").val(graphTimeFrame);
|
||||
$("#themeIn").val(theme);
|
||||
$("#styleIn").val(style);
|
||||
$("#newestconsole").prop("checked", showConsoleLatest);
|
||||
$("#doAnimations").prop("checked", doAnimations);
|
||||
}
|
||||
|
||||
function resetOptions() {
|
||||
if (confirm("Do you really want to reset to defaults?")) {
|
||||
$("#dataRefreshRate").val(5000);
|
||||
$("#port").val(33333);
|
||||
$("#ip").val("localhost");
|
||||
$("#maxConsoleLines").val(1000);
|
||||
$("#graphTimeFrame").val(30000);
|
||||
$("#themeIn").val("lightTheme");
|
||||
$("#styleIn").val("sharpStyle");
|
||||
$("#newestconsole").prop("checked", false);
|
||||
$("#doAnimations").prop("checked", true);
|
||||
applyOptions()
|
||||
}
|
||||
}
|
||||
|
||||
function applyOptions() {
|
||||
let options = {
|
||||
refresh_rate: parseInt($("#dataRefreshRate").val()),
|
||||
theme: $("#themeIn").val(),
|
||||
style: $("#styleIn").val(),
|
||||
client_port: parseInt($("#port").val()),
|
||||
client_ip: $("#ip").val(),
|
||||
max_console_lines: parseInt($("#maxConsoleLines").val()),
|
||||
show_console_latest: $("#newestconsole").prop("checked"),
|
||||
graph_time_frame: parseInt($("#graphTimeFrame").val()),
|
||||
do_animations: $("#doAnimations").prop("checked")
|
||||
};
|
||||
if (options.do_animations !== doAnimations) {
|
||||
doAnimations = options.do_animations;
|
||||
if (doAnimations) {
|
||||
$(".optionInput").addClass("smooth");
|
||||
$(".slider").addClass("smoothslider").addClass("smooth");
|
||||
$(".content").addClass("slide_up");
|
||||
$(".sideOption").addClass("smooth");
|
||||
$(".button").addClass("smooth");
|
||||
} else {
|
||||
$(".optionInput").removeClass("smooth");
|
||||
$(".slider").removeClass("smoothslider").removeClass("smooth");
|
||||
$(".content").removeClass("slide_up");
|
||||
$(".sideOption").removeClass("smooth");
|
||||
$(".button").removeClass("smooth");
|
||||
}
|
||||
$("#doAnimationscb").addClass("updated").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("updated");
|
||||
}
|
||||
).prop("checked", doAnimations);
|
||||
}
|
||||
if (options.refresh_rate !== refreshRate) {
|
||||
console.log(options.refresh_rate + " " + refreshRate);
|
||||
refreshRate = Math.max(options.refresh_rate, 500);
|
||||
$("#dataRefreshRate").addClass("updated").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("updated");
|
||||
}
|
||||
).val(refreshRate);
|
||||
}
|
||||
if (options.style !== style) {
|
||||
style = options.style;
|
||||
applyStyle(options.style);
|
||||
$("#styleIn").addClass("updated").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("updated");
|
||||
}
|
||||
);
|
||||
}
|
||||
if (options.theme !== theme) {
|
||||
theme = options.theme;
|
||||
applyTheme(options.theme);
|
||||
$("#themeIn").addClass("updated").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("updated");
|
||||
}
|
||||
);
|
||||
}
|
||||
if (options.client_port !== port) {
|
||||
port = options.client_port;
|
||||
$("#port").addClass("updated").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("updated");
|
||||
}
|
||||
).val(port);
|
||||
reconnect();
|
||||
}
|
||||
if (options.client_ip !== ip) {
|
||||
ip = options.client_ip;
|
||||
$("#ip").addClass("updated").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("updated");
|
||||
}
|
||||
).val(ip);
|
||||
reconnect();
|
||||
}
|
||||
if (options.graph_time_frame !== graphTimeFrame) {
|
||||
graphTimeFrame = Math.max(options.graph_time_frame, 5000);
|
||||
$("#graphTimeFrame").addClass("updated").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("updated");
|
||||
}
|
||||
).val(graphTimeFrame);
|
||||
}
|
||||
if (options.max_console_lines !== maxConsoleLines) {
|
||||
maxConsoleLines = Math.max(options.max_console_lines, 100);
|
||||
$("#maxConsoleLines").addClass("updated").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("updated");
|
||||
}
|
||||
).val(maxConsoleLines);
|
||||
}
|
||||
if (options.show_console_latest !== showConsoleLatest) {
|
||||
showConsoleLatest = options.show_console_latest;
|
||||
if (showConsoleLatest)
|
||||
$("#consoleLatest").attr("hidden", false);
|
||||
else
|
||||
$("#consoleLatest").attr("hidden", true);
|
||||
$("#newestconsolecb").addClass("updated").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("updated");
|
||||
}
|
||||
).prop("checked", showConsoleLatest);
|
||||
}
|
||||
localStorage.setItem("options", JSON.stringify(options));
|
||||
}
|
||||
|
||||
function selectTab(t, l) {
|
||||
let sideBar = $("#sideBar");
|
||||
sideBar.children("div").each(function () {
|
||||
let tmp = $(this);
|
||||
if (tmp.attr("id") === t) {
|
||||
tmp.addClass("sideSelected");
|
||||
} else
|
||||
tmp.removeClass("sideSelected");
|
||||
});
|
||||
$("#content").children("div").each(function () {
|
||||
let tmp = $(this);
|
||||
if (tmp.attr("id") === l) {
|
||||
tmp.attr("hidden", false);
|
||||
} else
|
||||
tmp.attr("hidden", true);
|
||||
});
|
||||
if (sideBar.hasClass("expanded")) {
|
||||
sideBar.removeClass("expanded").addClass("retract").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("retract").removeClass("expanded");
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function expSide() {
|
||||
let sideBar = $("#sideBar");
|
||||
if (sideBar.hasClass("expanded")) {
|
||||
sideBar.removeClass("expanded").addClass("retract").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).removeClass("retract").removeClass("expanded");
|
||||
}
|
||||
);
|
||||
} else {
|
||||
sideBar.addClass("expand").on(
|
||||
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
|
||||
function () {
|
||||
$(this).addClass("expanded").removeClass("expand");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function applyTheme(t) {
|
||||
if (doAnimations)
|
||||
$("*").each(function () {
|
||||
if (!$(this).attr("hidden"))
|
||||
$(this).addClass("tempsmooth").on(
|
||||
"webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend",
|
||||
function () {
|
||||
$(this).removeClass("tempsmooth");
|
||||
}
|
||||
);
|
||||
});
|
||||
$("#theme").attr("href", "themes/" + t + ".css");
|
||||
}
|
||||
|
||||
function applyStyle(s) {
|
||||
if (doAnimations)
|
||||
$("*").each(function () {
|
||||
if (!$(this).attr("hidden"))
|
||||
$(this).addClass("tempsmooth").on(
|
||||
"webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend",
|
||||
function () {
|
||||
$(this).removeClass("tempsmooth");
|
||||
}
|
||||
);
|
||||
});
|
||||
$("#style").attr("href", "themes/" + s + ".css");
|
||||
}
|
||||
|
||||
//update data functions
|
||||
|
||||
function updateWithMessage(m) {
|
||||
//TODO: get this to talk with client
|
||||
let result;
|
||||
try {
|
||||
result = JSON.parse(m);
|
||||
switch (result.type) {
|
||||
case "command":
|
||||
updateConsole(result.data, 2);
|
||||
break;
|
||||
case "stats":
|
||||
|
||||
updateValues();
|
||||
break;
|
||||
default:
|
||||
updateConsole("[WEB-INFO] The message received is improperly formatted: " + result.data, 2);
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
updateConsole("[WEB-INFO] There was an error parsing the data \n" + e, 2);
|
||||
}
|
||||
}
|
||||
|
||||
function updateValues() {
|
||||
//TODO: use values and update web info
|
||||
}
|
||||
|
||||
//console functions
|
||||
|
||||
function updateConsole(x, status) {
|
||||
let scroll = false;
|
||||
let temp = $('#console_text');
|
||||
let latest = $("#consoleLatest");
|
||||
if (temp.scrollTop() === (temp[0].scrollHeight - temp[0].clientHeight))
|
||||
scroll = true;
|
||||
switch (status) {
|
||||
case 1:
|
||||
temp.append('<div class="consoleLine sent">' + x + '</div>');
|
||||
break;
|
||||
case 0:
|
||||
temp.append('<div class="consoleLine unsent">' + x + '</div>');
|
||||
break;
|
||||
default:
|
||||
temp.append('<div class="consoleLine">' + x + '</div>');
|
||||
latest.html('<div class="consoleLine">' + x + '</div>');
|
||||
}
|
||||
let childs = temp.children();
|
||||
if (childs.length > maxConsoleLines) {
|
||||
let length = childs.length;
|
||||
for (let i = 0; i < length - maxConsoleLines; i++) {
|
||||
childs[i].remove();
|
||||
}
|
||||
}
|
||||
if (scroll)
|
||||
temp.scrollTop(temp[0].scrollHeight);
|
||||
}
|
||||
|
||||
function sendCommand(x) {
|
||||
if (x === "")
|
||||
return;
|
||||
if (connection.readyState === "OPEN") {
|
||||
let data = {
|
||||
type: "command",
|
||||
data: x
|
||||
};
|
||||
let message = JSON.stringify(data);
|
||||
connection.send(message);
|
||||
} else {
|
||||
updateConsole(x, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//network commuication
|
||||
|
||||
function reconnect() {
|
||||
if (connection != null)
|
||||
connection.close();
|
||||
updateConsole("[WEB-CONSOLE] Attempting to connect to client on " + ip + ":" + port, 2);
|
||||
connection = new WebSocket("ws://" + ip + ":" + port);
|
||||
$("#connection").removeClass("disconnected").removeClass("connected").addClass("connecting").text("Connecting");
|
||||
addListeners(connection)
|
||||
}
|
||||
|
||||
function addListeners(c) {
|
||||
let opened = false;
|
||||
c.onopen = function (event) {
|
||||
$("#connection").removeClass("disconnected").removeClass("connecting").addClass("connected").text("Connected");
|
||||
opened = true;
|
||||
updateConsole("[WEB-CONSOLE] Successfully to connect to client on " + ip + ":" + port, 2);
|
||||
statRequest = setInterval(function () {
|
||||
requestStats();
|
||||
}, refreshRate);
|
||||
};
|
||||
c.onclose = function (event) {
|
||||
$("#connection").addClass("disconnected").removeClass("connecting").removeClass("connected").text("Disconnected");
|
||||
if (opened)
|
||||
updateConsole("[WEB-CONSOLE] Disconnected from client");
|
||||
else
|
||||
updateConsole("[WEB-CONSOLE] Failed to connect to client on " + ip + ":" + port, 2);
|
||||
clearInterval(statRequest);
|
||||
};
|
||||
c.onmessage = function (event) {
|
||||
updateWithMessage(event.data());
|
||||
};
|
||||
}
|
||||
|
||||
function requestStats() {
|
||||
let req = {type: "stats"};
|
||||
connection.send(JSON.stringify(req));
|
||||
}
|
BIN
src/main/resources/webui/icons/console.png
Normal file
BIN
src/main/resources/webui/icons/console.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 675 B |
BIN
src/main/resources/webui/icons/dashboard.png
Normal file
BIN
src/main/resources/webui/icons/dashboard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 756 B |
BIN
src/main/resources/webui/icons/info.png
Normal file
BIN
src/main/resources/webui/icons/info.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 723 B |
BIN
src/main/resources/webui/icons/options.png
Normal file
BIN
src/main/resources/webui/icons/options.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 793 B |
BIN
src/main/resources/webui/icons/showmore.png
Normal file
BIN
src/main/resources/webui/icons/showmore.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 374 B |
149
src/main/resources/webui/index.html
Normal file
149
src/main/resources/webui/index.html
Normal file
|
@ -0,0 +1,149 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>MD@H Client</title>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
||||
<script src="dataReceive.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="layout.css">
|
||||
<link rel="stylesheet" type="text/css" href="" id="style">
|
||||
<link rel="stylesheet" type="text/css" href="themes/darkTheme.css" id="theme">
|
||||
</head>
|
||||
<body>
|
||||
<div id="pageBar">
|
||||
<a href="https://mangadex.org/">
|
||||
<img src="https://mangadex.org/images/misc/navbar.svg?3" alt="mangadex" width="65px"
|
||||
height="65px" style="float: left; padding: 5px; border-radius: 50%">
|
||||
</a>
|
||||
<h1 style="position: absolute; left: 75px; margin-left: 10px">MangaDex@Home Client Interface</h1>
|
||||
<div id="consoleLatest" hidden></div>
|
||||
<button id="connection" class="connecting button" onclick="reconnect()">Disconnected</button>
|
||||
</div>
|
||||
<div id="sideBar">
|
||||
<div id="expSide" class="sideOption" onclick="expSide()">
|
||||
<img src="icons/showmore.png" alt="dash" width="30px" height="30px" style="padding: 10px" class="img">
|
||||
<h2 style="position: absolute; left: 50px; top: 0; margin: calc((50px - 29px)/2)">Menu</h2>
|
||||
</div>
|
||||
<div id="dash" class="sideOption sideSelected" onclick="selectTab('dash','dashb')">
|
||||
<img src="icons/dashboard.png" alt="dash" width="30px" height="30px" style="padding: 10px" class="img">
|
||||
<h2 style="position: absolute; left: 50px; top: 50px; margin: calc((50px - 29px)/2)">Dashboard</h2>
|
||||
</div>
|
||||
<div id="cons" class="sideOption" onclick="selectTab('cons','console')">
|
||||
<img src="icons/console.png" alt="dash" width="30px" height="30px" style="padding: 10px" class="img">
|
||||
<h2 style="position: absolute; left: 50px; top: 100px; margin: calc((50px - 29px)/2)">Console</h2>
|
||||
</div>
|
||||
<div id="opt" class="sideOption" onclick="selectTab('opt','dashOptions')">
|
||||
<img src="icons/options.png" alt="dash" width="30px" height="30px" style="padding: 10px" class="img">
|
||||
<h2 style="position: absolute; left: 50px; top: 150px; margin: calc((50px - 29px)/2)">Options</h2>
|
||||
</div>
|
||||
<div id="inf" class="sideOption" onclick="selectTab('inf','info')">
|
||||
<img src="icons/info.png" alt="dash" width="30px" height="30px" style="padding: 10px" class="img">
|
||||
<h2 style="position: absolute; left: 50px; top: 200px; margin: calc((50px - 29px)/2)">Info</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div id="dashb" class="content">
|
||||
<div class="contentHeader">
|
||||
<h1 style="margin: 0;position:absolute; top: 42px; padding-left: 30px">Dashboard</h1>
|
||||
</div>
|
||||
<div id="nDat">
|
||||
<div id="hits" class="numerical_data"></div>
|
||||
<div id="misses" class="numerical_data"></div>
|
||||
<div id="hitPercent" class="numerical_data"></div>
|
||||
<div id="reqServed" class="numerical_data"></div>
|
||||
<div id="bytesSent" class="numerical_data"></div>
|
||||
</div>
|
||||
<div id="gDat">
|
||||
<div id="cpuUtil" class="line_graph_data"></div>
|
||||
<div id="networkUtil" class="line_graph_data"></div>
|
||||
<div id="discUtil" class="line_graph_data"></div>
|
||||
<div id="cacheSize" class="line_graph_data"></div>
|
||||
<div id="ramUtil" class="line_graph_data"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="console" class="content" hidden>
|
||||
<div class="contentHeader">
|
||||
<h1 style="margin: 0;position:absolute; top: 42px; padding-left: 30px">Console</h1>
|
||||
</div>
|
||||
<div id="buttonBoard">
|
||||
<!-- client control stuffs-->
|
||||
<h2 style="margin-left: 40px">Client Status: Stopped</h2>
|
||||
</div>
|
||||
<div id="liveConsole">
|
||||
<div id="console_text"></div>
|
||||
<div id="console_input" contenteditable="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dashOptions" class="content" hidden>
|
||||
<div class="contentHeader">
|
||||
<h1 style="margin: 0;position:absolute; top: 42px; padding-left: 30px">Options</h1>
|
||||
</div>
|
||||
<div id="options">
|
||||
<h3>General</h3>
|
||||
<div class="option">
|
||||
<h4>Data Refresh Rate</h4>
|
||||
<label><input id="dataRefreshRate" type="number" class="optionInput input" placeholder="5000" min="500"></label>
|
||||
</div>
|
||||
<div class="option">
|
||||
<h4>Websocket Port</h4>
|
||||
<label><input id="port" type="number" class="optionInput input" placeholder="33333"></label>
|
||||
</div>
|
||||
<div class="option">
|
||||
<h4>Client IP</h4>
|
||||
<label><input id="ip" type="text" class="optionInput input" placeholder="localhost"></label>
|
||||
</div>
|
||||
<div class="option">
|
||||
<h4>Max Console Lines</h4>
|
||||
<label><input id="maxConsoleLines" type="number" class="optionInput input" placeholder="1000" min="100"></label>
|
||||
</div>
|
||||
<div class="option">
|
||||
<h4>Graph Time Frame</h4>
|
||||
<label><input id="graphTimeFrame" type="number" class="optionInput input" placeholder="30000"
|
||||
min="5000"></label>
|
||||
</div>
|
||||
<h3>Display</h3>
|
||||
<div class="option">
|
||||
<h4>Theme</h4>
|
||||
<label><select id="themeIn" class="optionInput input">
|
||||
<option value="lightTheme">Light</option>
|
||||
<option value="darkTheme">Dark</option>
|
||||
<option value="midnightTheme">Midnight</option>
|
||||
<option value="eyekillerTheme">High Vibrancy</option>
|
||||
</select></label>
|
||||
</div>
|
||||
<div class="option">
|
||||
<h4>Style</h4>
|
||||
<label><select id="styleIn" class="optionInput input">
|
||||
<option value="sharpStyle">Sharp</option>
|
||||
<option value="softStyle">Soft</option>
|
||||
</select></label>
|
||||
</div>
|
||||
<div class="option">
|
||||
<h4>Show Console Latest</h4>
|
||||
<label class="switch switchInput">
|
||||
<input id="newestconsole" type="checkbox">
|
||||
<span id="newestconsolecb" class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="option">
|
||||
<h4>Animations</h4>
|
||||
<label class="switch switchInput">
|
||||
<input id="doAnimations" type="checkbox">
|
||||
<span id="doAnimationscb" class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button id="apply" class="button" onclick="applyOptions()">Apply</button>
|
||||
<button id="reset" class="button" onclick="resetOptions()">Reset</button>
|
||||
</div>
|
||||
<div id="info" class="content" hidden>
|
||||
<div class="contentHeader">
|
||||
<h1 style="margin: 0;position:absolute; top: 42px; padding-left: 30px">Client Info</h1>
|
||||
</div>
|
||||
<div id="information">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
372
src/main/resources/webui/layout.css
Normal file
372
src/main/resources/webui/layout.css
Normal file
|
@ -0,0 +1,372 @@
|
|||
body {
|
||||
margin: 0;
|
||||
font-family: Calibri, serif;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.smooth {
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.tempsmooth {
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
/*Content holder positions*/
|
||||
|
||||
#pageBar {
|
||||
height: 75px;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#consoleLatest {
|
||||
position: absolute;
|
||||
min-height: 20px;
|
||||
width: calc(100% - 755px);
|
||||
margin: 30px 20px 25px 20px;
|
||||
left: 545px;
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
#consoleLatest::-webkit-scrollbar {
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
#connection {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
margin: 20px 20px 20px 20px;
|
||||
width: 150px;
|
||||
height: 35px;
|
||||
border-style: solid;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.connecting {
|
||||
animation: connecting 1.5s;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@keyframes connecting {
|
||||
0%, 100% {
|
||||
filter: brightness(120%)
|
||||
}
|
||||
50% {
|
||||
filter: brightness(80%)
|
||||
}
|
||||
}
|
||||
|
||||
#sideBar {
|
||||
height: calc(100% - 75px);
|
||||
width: 50px;
|
||||
top: 75px;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.sideOption {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
float: left;;
|
||||
}
|
||||
|
||||
.expand {
|
||||
animation: expand 150ms ease-out;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.expanded {
|
||||
width: 200px !important;
|
||||
}
|
||||
|
||||
.retract {
|
||||
animation: expand 150ms reverse ease-in;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
@keyframes expand {
|
||||
0% {
|
||||
width: 50px
|
||||
}
|
||||
100% {
|
||||
width: 200px
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#content {
|
||||
height: calc(100% - 75px);
|
||||
width: calc(100% - 50px);
|
||||
top: 75px;
|
||||
left: 50px;
|
||||
position: absolute;
|
||||
/*overflow-y: auto;*/
|
||||
}
|
||||
|
||||
.contentHeader {
|
||||
width: calc(100% - 40px);
|
||||
height: 80px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
/*Main dashboard positions*/
|
||||
|
||||
#dashb {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#nDat {
|
||||
width: 40%;
|
||||
height: calc(100% - 140px);
|
||||
margin: 20px;
|
||||
top: 100px;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
|
||||
.numerical_data {
|
||||
height: 150px;
|
||||
width: calc(50% - 20px);
|
||||
margin: 10px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#gDat {
|
||||
height: calc(100% - 140px);
|
||||
width: calc(60% - 60px);
|
||||
margin: 20px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: calc(40% + 20px);
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.line_graph_data {
|
||||
height: 200px;
|
||||
width: calc((100% - 20px));
|
||||
margin: 10px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/*Console and options positions*/
|
||||
|
||||
#console {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#buttonBoard {
|
||||
width: calc(100% - 40px);
|
||||
height: calc(40% - 20px);
|
||||
margin: 20px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
}
|
||||
|
||||
#liveConsole {
|
||||
width: calc(100% - 40px);
|
||||
height: calc(60% - 180px);
|
||||
margin: 20px;
|
||||
position: absolute;
|
||||
top: calc(40% + 100px);
|
||||
padding-bottom: 40px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.consoleLine {
|
||||
width: calc(100% - 5px);
|
||||
float: left;
|
||||
margin: 0 5px 0;
|
||||
left: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.consoleLine > p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#console_input {
|
||||
position: absolute;
|
||||
width: calc(100% - 30px);
|
||||
height: 20px;
|
||||
bottom: 10px;
|
||||
left: 0;
|
||||
margin: 0 15px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
outline: none;
|
||||
background-color: inherit;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#console_text {
|
||||
height: calc(100% - 40px);
|
||||
width: calc(100% - 20px);
|
||||
position: absolute;
|
||||
outline: none;
|
||||
border-width: 0;
|
||||
resize: none;
|
||||
font-family: monospace;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
padding-bottom: 40px;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
/*Web option positions*/
|
||||
#dashOptions {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#options {
|
||||
width: calc(100% - 80px);
|
||||
height: calc(100% - 140px);
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
margin: 20px 20px 20px 60px;
|
||||
}
|
||||
|
||||
#apply {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 150px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
#reset{
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 190px;
|
||||
width: 150px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.option {
|
||||
height: 40px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.option > h4 {
|
||||
margin: 0;
|
||||
float: left;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.optionLabel {
|
||||
|
||||
}
|
||||
|
||||
.optionInput {
|
||||
left: 200px;
|
||||
position: absolute;
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.switchInput > span {
|
||||
left: 200px;
|
||||
position: absolute;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.updated {
|
||||
animation: fade 1.5s linear;
|
||||
}
|
||||
|
||||
@keyframes fade {
|
||||
0%, 100% {
|
||||
filter: alpha(100%);
|
||||
}
|
||||
100% {
|
||||
filter: alpha(0%);
|
||||
}
|
||||
}
|
||||
|
||||
/*misc modifications*/
|
||||
|
||||
.input {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
outline: none;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.slider {
|
||||
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
/*border-width: 1px;*/
|
||||
position: absolute;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.smoothslider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
/*Webkit modifications*/
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/*animations*/
|
||||
|
||||
.slide_up {
|
||||
animation: slideup .1s ease-out;
|
||||
}
|
||||
|
||||
@keyframes slideup {
|
||||
0% {
|
||||
transform: translateY(50px);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
167
src/main/resources/webui/themes/darkTheme.css
Normal file
167
src/main/resources/webui/themes/darkTheme.css
Normal file
|
@ -0,0 +1,167 @@
|
|||
body {
|
||||
background-color: #404040;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
#pageBar {
|
||||
background-color: #303030;
|
||||
}
|
||||
|
||||
#consoleLatest{
|
||||
background-color: black;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
.connected {
|
||||
border-color: #0fff00 !important;
|
||||
}
|
||||
|
||||
.disconnected {
|
||||
border-color: #e50100 !important;
|
||||
}
|
||||
|
||||
.connecting {
|
||||
border-color: #e5d700 !important;
|
||||
}
|
||||
|
||||
#sideBar {
|
||||
background-color: #303030;
|
||||
}
|
||||
|
||||
.sideOption {
|
||||
background-color: #303030;
|
||||
}
|
||||
|
||||
.sideOption:hover {
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
.sideSelected {
|
||||
background-color: #606060;
|
||||
}
|
||||
|
||||
#content {
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
.contentHeader {
|
||||
background-color: #606060;
|
||||
}
|
||||
|
||||
/*Main dashboard colors*/
|
||||
|
||||
#dashb {
|
||||
|
||||
}
|
||||
|
||||
#nDat {
|
||||
}
|
||||
|
||||
.numerical_data {
|
||||
background-color: #606060;
|
||||
}
|
||||
|
||||
#gDat {
|
||||
}
|
||||
|
||||
.line_graph_data {
|
||||
background-color: #606060;
|
||||
}
|
||||
|
||||
/*Console and options colors*/
|
||||
|
||||
#liveConsole {
|
||||
background-color: black;
|
||||
caret-color: #f0f0f0;
|
||||
}
|
||||
|
||||
#console_text {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
#console_input {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
.unsent {
|
||||
color: #e50100;
|
||||
}
|
||||
|
||||
.sent {
|
||||
color: #0fff00;
|
||||
}
|
||||
|
||||
|
||||
/*Web option colors*/
|
||||
#dashOptions {
|
||||
}
|
||||
|
||||
#options {
|
||||
}
|
||||
|
||||
.option {
|
||||
}
|
||||
|
||||
.optionLabel {
|
||||
|
||||
}
|
||||
|
||||
.optionInput {
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
background-color: #606060;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
/*misc*/
|
||||
|
||||
.button{
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
background-color: #606060;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
.button:hover{
|
||||
background-color: #909090;
|
||||
}
|
||||
|
||||
.img {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.updated {
|
||||
border-color: #1ec70d !important;
|
||||
}
|
||||
|
||||
.slider {
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
background-color: #606060;
|
||||
}
|
||||
|
||||
.slider::before{
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #909090;
|
||||
}
|
||||
|
||||
/*Webkit colors*/
|
||||
|
||||
::-webkit-scrollbar {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #555555;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #888888;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
|
||||
}
|
97
src/main/resources/webui/themes/eyekillerTheme.css
Normal file
97
src/main/resources/webui/themes/eyekillerTheme.css
Normal file
|
@ -0,0 +1,97 @@
|
|||
body {
|
||||
background-color: #ffffff;
|
||||
color: #202020;
|
||||
}
|
||||
|
||||
#pageBar {
|
||||
background-color: #faff00;
|
||||
}
|
||||
|
||||
#sideBar {
|
||||
background-color: #faff00;
|
||||
}
|
||||
|
||||
.sideOption {
|
||||
|
||||
}
|
||||
|
||||
.sideOption:hover {
|
||||
background-color: #faff00;
|
||||
}
|
||||
|
||||
.sideSelected {
|
||||
background-color: #faff00;
|
||||
}
|
||||
|
||||
#content {
|
||||
background-color: #0fff00;
|
||||
}
|
||||
|
||||
.contentHeader {
|
||||
background-color: #ff00af;
|
||||
}
|
||||
|
||||
/*Main dashboard colors*/
|
||||
|
||||
#dashb {
|
||||
|
||||
}
|
||||
|
||||
#nDat {
|
||||
}
|
||||
|
||||
.numerical_data {
|
||||
background-color: #00ffec;
|
||||
}
|
||||
|
||||
#gDat {
|
||||
}
|
||||
|
||||
.line_graph_data {
|
||||
background-color: #00ffec;
|
||||
}
|
||||
|
||||
/*Console and options colors*/
|
||||
|
||||
#liveConsole {
|
||||
background-color: black;
|
||||
caret-color: #f0f0f0;
|
||||
}
|
||||
|
||||
#console_text {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
#console_input {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
/*misc*/
|
||||
|
||||
.img {
|
||||
}
|
||||
|
||||
.updated {
|
||||
border-color: #1ec70d;
|
||||
}
|
||||
|
||||
/*Webkit colors*/
|
||||
|
||||
::-webkit-scrollbar {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #aaaaaa;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #888888;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
|
||||
}
|
166
src/main/resources/webui/themes/lightTheme.css
Normal file
166
src/main/resources/webui/themes/lightTheme.css
Normal file
|
@ -0,0 +1,166 @@
|
|||
body {
|
||||
background-color: #ffffff;
|
||||
color: #202020;
|
||||
}
|
||||
|
||||
#pageBar {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
#consoleLatest{
|
||||
background-color: black;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
.connected {
|
||||
border-color: #0fff00 !important;
|
||||
}
|
||||
|
||||
.disconnected {
|
||||
border-color: #e50100 !important;
|
||||
}
|
||||
|
||||
.connecting {
|
||||
border-color: #e5d700 !important;
|
||||
}
|
||||
|
||||
#sideBar {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.sideOption {
|
||||
|
||||
}
|
||||
|
||||
.sideOption:hover {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.sideSelected {
|
||||
background-color: #e1e1e1;
|
||||
}
|
||||
|
||||
#content {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.contentHeader {
|
||||
background-color: #ededed;
|
||||
}
|
||||
|
||||
/*Main dashboard colors*/
|
||||
|
||||
#dashb {
|
||||
|
||||
}
|
||||
|
||||
#nDat {
|
||||
}
|
||||
|
||||
.numerical_data {
|
||||
background-color: #ededed;
|
||||
}
|
||||
|
||||
#gDat {
|
||||
}
|
||||
|
||||
.line_graph_data {
|
||||
background-color: #ededed;
|
||||
}
|
||||
|
||||
/*Console and options colors*/
|
||||
|
||||
#liveConsole {
|
||||
background-color: black;
|
||||
caret-color: #f0f0f0;
|
||||
}
|
||||
|
||||
#console_text {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
#console_input {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
.unsent {
|
||||
color: #cb0000;
|
||||
}
|
||||
|
||||
.sent {
|
||||
color: #1ec70d;
|
||||
}
|
||||
|
||||
|
||||
/*Web option colors*/
|
||||
#dashOptions {
|
||||
}
|
||||
|
||||
#options {
|
||||
}
|
||||
|
||||
.option {
|
||||
}
|
||||
|
||||
.optionLabel {
|
||||
|
||||
}
|
||||
|
||||
.optionInput {
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
background-color: #eaeaea;
|
||||
color: #202020;
|
||||
}
|
||||
|
||||
/*misc*/
|
||||
|
||||
.button{
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
background-color: #eaeaea;
|
||||
color: #202020;
|
||||
}
|
||||
|
||||
.button:hover{
|
||||
background-color: #dadada;
|
||||
}
|
||||
|
||||
.img {
|
||||
}
|
||||
|
||||
.updated {
|
||||
border-color: #1ec70d !important;
|
||||
}
|
||||
|
||||
.slider {
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
background-color: #eaeaea;
|
||||
}
|
||||
|
||||
.slider::before{
|
||||
background-color: #202020;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #adadad;
|
||||
}
|
||||
|
||||
/*Webkit colors*/
|
||||
|
||||
::-webkit-scrollbar {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #cacaca;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #dedede;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
|
||||
}
|
163
src/main/resources/webui/themes/midnightTheme.css
Normal file
163
src/main/resources/webui/themes/midnightTheme.css
Normal file
|
@ -0,0 +1,163 @@
|
|||
body {
|
||||
background-color: #101010;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
#pageBar {
|
||||
background-color: #202020;
|
||||
}
|
||||
|
||||
#consoleLatest {
|
||||
background-color: black;
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
.connected {
|
||||
border-color: #0fff00 !important;
|
||||
}
|
||||
|
||||
.disconnected {
|
||||
border-color: #e50100 !important;
|
||||
}
|
||||
|
||||
.connecting {
|
||||
border-color: #e5d700 !important;
|
||||
}
|
||||
|
||||
#sideBar {
|
||||
background-color: #202020;
|
||||
}
|
||||
|
||||
.sideOption:hover {
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
.sideSelected {
|
||||
background-color: #505050;
|
||||
}
|
||||
|
||||
#content {
|
||||
background-color: #101010;
|
||||
}
|
||||
|
||||
.contentHeader {
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
/*Main dashboard colors*/
|
||||
|
||||
#dashb {
|
||||
|
||||
}
|
||||
|
||||
#nDat {
|
||||
}
|
||||
|
||||
.numerical_data {
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
#gDat {
|
||||
}
|
||||
|
||||
.line_graph_data {
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
/*Console and options colors*/
|
||||
|
||||
#liveConsole {
|
||||
background-color: black;
|
||||
caret-color: #f0f0f0;
|
||||
}
|
||||
|
||||
#console_text {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
#console_input {
|
||||
color: #f0f0f0;
|
||||
}
|
||||
|
||||
.unsent {
|
||||
color: #e50100;
|
||||
}
|
||||
|
||||
.sent {
|
||||
color: #0fff00;
|
||||
}
|
||||
|
||||
|
||||
/*Web option colors*/
|
||||
#dashOptions {
|
||||
}
|
||||
|
||||
#options {
|
||||
}
|
||||
|
||||
.option {
|
||||
}
|
||||
|
||||
.optionLabel {
|
||||
|
||||
}
|
||||
|
||||
.optionInput {
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
background-color: #404040;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
/*misc*/
|
||||
|
||||
.button{
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
background-color: #404040;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
.button:hover{
|
||||
background-color: #797979;
|
||||
}
|
||||
|
||||
.img {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.updated {
|
||||
border-color: #1ec70d !important;
|
||||
}
|
||||
|
||||
.slider {
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
.slider::before {
|
||||
background-color: #bfbfbf;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #757575;
|
||||
}
|
||||
|
||||
/*Webkit colors*/
|
||||
|
||||
::-webkit-scrollbar {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #555555;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #888888;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
|
||||
}
|
22
src/main/resources/webui/themes/sharpStyle.css
Normal file
22
src/main/resources/webui/themes/sharpStyle.css
Normal file
|
@ -0,0 +1,22 @@
|
|||
.input {
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.slider {
|
||||
width: 60px;
|
||||
height: 12px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
height: 12px;
|
||||
width: 30px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(30px);
|
||||
-ms-transform: translateX(30px);
|
||||
transform: translateX(30px);
|
||||
}
|
145
src/main/resources/webui/themes/softStyle.css
Normal file
145
src/main/resources/webui/themes/softStyle.css
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*Content holder positions*/
|
||||
|
||||
#pageBar {
|
||||
}
|
||||
|
||||
#connection {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#consoleLatest {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#sideBar {
|
||||
}
|
||||
|
||||
.sideSelected {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.sideOption:hover {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#expSide {
|
||||
}
|
||||
|
||||
#dash {
|
||||
}
|
||||
|
||||
#cons {
|
||||
}
|
||||
|
||||
#opt {
|
||||
}
|
||||
|
||||
#content {
|
||||
}
|
||||
|
||||
.contentHeader {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/*Main dashboard positions*/
|
||||
|
||||
#dashb {
|
||||
}
|
||||
|
||||
#nDat {
|
||||
|
||||
}
|
||||
|
||||
.numerical_data {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#gDat {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.line_graph_data {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/*Console and options positions*/
|
||||
|
||||
#console {
|
||||
}
|
||||
|
||||
#buttonBoard {
|
||||
}
|
||||
|
||||
#liveConsole {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#console_input {
|
||||
}
|
||||
|
||||
#console_text {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/*Web option positions*/
|
||||
#dashOptions {
|
||||
}
|
||||
|
||||
#options {
|
||||
}
|
||||
|
||||
#apply {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.option {
|
||||
}
|
||||
|
||||
.optionLabel {
|
||||
|
||||
}
|
||||
|
||||
.optionInput {
|
||||
}
|
||||
|
||||
/*misc modifications*/
|
||||
|
||||
.input {
|
||||
padding-left: 5px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.slider {
|
||||
border-radius: 30px;
|
||||
width: 60px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
border-radius: 7px;
|
||||
height: 14px;
|
||||
width: 28px;
|
||||
left: 3px;
|
||||
bottom: 1px;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(26px);
|
||||
-ms-transform: translateX(26px);
|
||||
transform: translateX(26px);
|
||||
}
|
||||
|
||||
/*Webkit modifications*/
|
||||
|
||||
::-webkit-scrollbar {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-button {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
}
|
Loading…
Reference in a new issue