Skip to content
Permalink
Browse files

Version 563. Added HTML rendering of client results.

  • Loading branch information
n-y-z-o committed Jan 5, 2020
1 parent f31c016 commit 7bd4383dd0460dc312c0e067a096caa361f6e463
@@ -2,7 +2,7 @@

public class Version {

private static final int version = 562;
private static final int version = 563;

public static int getVersion() {

@@ -98,7 +98,7 @@ public static EndpointResponse page(EndpointRequest request) {
// Add buttons for all commands except exit.
for (Command command : CommandManager.getCommands()) {
if (!(command instanceof ExitCommand)) {
body.add(new A().attr("class", "simple-hover-button").attr("href", "/" + command.getLongCommand())
body.add(new A().attr("class", "hover-button").attr("href", "/" + command.getLongCommand())
.addRaw(command.getDescription()));
}
}
@@ -63,7 +63,7 @@ private EndpointResponse getFormPage(ValidationResult validationResult, boolean
Div container = (Div) body.add(new Div().attr("class", "content-container"));

// Add a button to return to the menu.
container.add(new A().attr("href", "/").attr("class", "simple-hover-button").addRaw("←"));
container.add(new A().attr("href", "/").attr("class", "hover-button").addRaw("←"));

// Add the title.
container.add(new H1(title));
@@ -183,28 +183,39 @@ private EndpointResponse getProgressPage(List<String> argumentValues) {
head.add(WebUtil.hoverButtonStyles);

// Add a button to return to the menu.
body.add(new A().attr("href", "/").attr("class", "simple-hover-button").addRaw("&larr;"));
body.add(new A().attr("href", "/").attr("class", "hover-button").addRaw("&larr;"));

// Add the title.
body.add(new H1(title));

// Make the command-output handler and make the progress box.
CommandOutputWeb commandOutput = new CommandOutputWeb();
CommandOutputWebManager.register(commandOutput);
Div progress = (Div) body.add(new Div().attr("class", "progress-box").attr("id", "progress-box"));
body.add(progressUpdateScript(progress.getAttr("id"), commandOutput.getIdentifier()));

// Run the command.
new Thread(new Runnable() {
@Override
public void run() {
ExecutionResult result = command.run(argumentValues, commandOutput);
if (result != null) {
result.toConsole(commandOutput);
if (command.isLongRunning()) {
// Make the command-output handler and make the progress box.
CommandOutputWeb commandOutput = new CommandOutputWeb();
CommandOutputWebManager.register(commandOutput);
Div progress = (Div) body.add(new Div().attr("class", "progress-box").attr("id", "progress-box"));
body.add(progressUpdateScript(progress.getAttr("id"), commandOutput.getIdentifier()));

// Run the command asynchronously.
new Thread(new Runnable() {
@Override
public void run() {
ExecutionResult result = command.run(argumentValues, commandOutput);
if (result != null) {
result.toConsole(commandOutput);
}
commandOutput.setComplete();
}
commandOutput.setComplete();
}).start();
} else {
// For commands that complete immediately, run the command synchronously and render the results.
CommandOutputWeb commandOutput = new CommandOutputWeb();
ExecutionResult result = command.run(argumentValues, commandOutput);

// If a result is available, render it.
if (result != null) {
body.add(result.toHtml());
}
}).start();
}

return new EndpointResponse(html.renderByteArray());
}
@@ -4,10 +4,18 @@

private String label;
private String identifier;
private boolean extraWrapColumn;

public CommandTableHeader(String label, String identifier) {
this.label = label;
this.identifier = identifier;
this.extraWrapColumn = false;
}

public CommandTableHeader(String label, String identifier, boolean extraWrapColumn) {
this.label = label;
this.identifier = identifier;
this.extraWrapColumn = extraWrapColumn;
}

public String getLabel() {
@@ -17,4 +25,8 @@ public String getLabel() {
public String getIdentifier() {
return identifier;
}

public boolean isExtraWrapColumn() {
return extraWrapColumn;
}
}
@@ -2,8 +2,7 @@

import co.nyzo.verifier.client.commands.PublicNyzoStringCommand;
import co.nyzo.verifier.util.UpdateUtil;
import co.nyzo.verifier.web.elements.HtmlElement;
import co.nyzo.verifier.web.elements.HtmlElementList;
import co.nyzo.verifier.web.elements.*;

import java.lang.reflect.Array;
import java.lang.reflect.Method;
@@ -44,7 +43,89 @@ public String toJson() {

@Override
public HtmlElement toHtml() {
return null;

// Create the div and add the styles that will be used.
HtmlElementList resultList = new HtmlElementList();
resultList.add(new Style(".error { background-color: #f88; padding: 0.3rem; border: 1px solid #c00; " +
"border-radius: 0.5rem; max-inline-size: fit-content; margin: 0.5rem 0 0.5rem 0; }" +
".notice { background-color: #ff8; padding: 0.3rem; border: 1px solid #cc0; border-radius: 0.5rem; " +
"max-inline-size: fit-content; margin: 0.5rem 0 0.5rem 0; }" +
".table { display: table; border: 1px solid gray; border-radius: 0.5rem; margin: 0.5rem 0 0.5rem 0; }" +
".table div { padding: 0.1rem; }" +
".header-row > div { background-color: #ddd; }" +
".header-row > div:first-child { border-top-left-radius: 0.5rem; }" +
".header-row > div:last-child { border-top-right-radius: 0.5rem; }" +
".header-row { display: table-row; }" +
".header-row > div { display: table-cell; }" +
".header-row > div:not(:first-child) { border-left: 1px solid gray; }" +
".data-row { display: table-row; }" +
".data-row > div { display: table-cell; border-top: 1px solid gray; }" +
".data-row > div:not(:first-child) { border-left: 1px solid gray; }" +
".row-inverted { display: table-row; }" +
".row-inverted > div { display: table-cell; }" +
".row-inverted:not(:first-child) > div { border-top: 1px solid gray; }" +
".row-inverted > div:first-child { background-color: #ddd; }" +
".row-inverted:first-child > div:first-child { border-top-left-radius: 0.5rem; }" +
".row-inverted:last-child > div:first-child { border-bottom-left-radius: 0.5rem; }" +
".row-inverted > div:not(:first-child) { border-left: 1px solid gray; }" +
".extra-wrap { word-break: break-all; }"));

// Add the errors.
if (result != null) {
for (String error : errors) {
resultList.add(new P(error).attr("class", "error"));
}
}

// Add the notices.
if (notices != null) {
for (String notice : notices) {
resultList.add(new P(notice).attr("class", "notice"));
}
}

// Add the result.
if (result != null) {
// Create the table.
Div tableDiv = (Div) resultList.add(new Div().attr("class", "table"));

if (result.isInvertedRowsColumns()) {
// This is the inverted rows/columns case. Render the header to the left.
int numberOfColumns = 1 + result.getRows().size();
for (int i = 0; i < result.getHeaders().length; i++) {
Div row = (Div) tableDiv.add(new Div().attr("class", "row-inverted"));
row.add(new Div().addRaw(result.getHeaders()[i].getLabel()));
for (String[] dataRow : result.getRows()) {
Div cell = (Div) row.add(new Div().addRaw(dataRow[i]));
if (result.getHeaders()[i].isExtraWrapColumn()) {
cell.attr("class", "extra-wrap");
}
}
}
} else {
// This is the non-inverted case. Add the header row.
Div headerRowDiv = (Div) tableDiv.add(new Div().attr("class", "header-row"));
CommandTableHeader[] headers = result.getHeaders();
for (CommandTableHeader header : result.getHeaders()) {
headerRowDiv.add(new Div().addRaw(header.getLabel()));
}

// Add the data rows.
for (String[] row : result.getRows()) {
Div dataRowDiv = (Div) tableDiv.add(new Div().attr("class", "data-row"));
int numberOfColumns = Math.min(headers.length, row.length);
for (int i = 0; i < numberOfColumns; i++) {
String value = row[i];
Div cell = (Div) dataRowDiv.add(new Div().addRaw(value));
if (headers[i].isExtraWrapColumn()) {
cell.attr("class", "extra-wrap");
}
}
}
}
}

return resultList;
}

public void toConsole(CommandOutput output) {
@@ -70,8 +70,8 @@ public ExecutionResult run(List<String> argumentValues, CommandOutput output) {
List<String> notices = new ArrayList<>();
List<String> errors = new ArrayList<>();
CommandTable table = new CommandTable(new CommandTableHeader("block height", "blockHeight"),
new CommandTableHeader("wallet ID", "walletId"),
new CommandTableHeader("ID string", "walletIdNyzoString"),
new CommandTableHeader("wallet ID", "walletId", true),
new CommandTableHeader("ID string", "walletIdNyzoString", true),
new CommandTableHeader("balance", "balance"));

// Add a notice showing the prefix after normalization.
@@ -109,7 +109,9 @@ public ValidationResult validate(List<String> argumentValues, CommandOutput outp
public ExecutionResult run(List<String> argumentValues, CommandOutput output) {

CommandTable table = new CommandTable(new CommandTableHeader("NTTP number", "nttpNumber"),
new CommandTableHeader("Git hash", "gitHash"), new CommandTableHeader("sender data", "senderData"));;
new CommandTableHeader("Git hash", "gitHash", true),
new CommandTableHeader("sender data", "senderData", true));
table.setInvertedRowsColumns(true);
List<String> notices = new ArrayList<>();
List<String> errors = new ArrayList<>();
try {
@@ -126,9 +126,9 @@ public ExecutionResult run(List<String> argumentValues, CommandOutput output) {
senderData);

// Build the output table. Note that the individual fields are retrieved from the prefilled-data string.
CommandTable table = new CommandTable(new CommandTableHeader("receiver ID", "receiverId"),
new CommandTableHeader("sender data", "senderData"), new CommandTableHeader("prefilled-data string",
"prefilledDataString"));
CommandTable table = new CommandTable(new CommandTableHeader("receiver ID", "receiverId", true),
new CommandTableHeader("sender data", "senderData", true),
new CommandTableHeader("prefilled-data string", "prefilledDataString", true));
table.setInvertedRowsColumns(true);
table.addRow(
NyzoStringEncoder.encode(new NyzoStringPublicIdentifier(prefilledDataString.getReceiverIdentifier())),
@@ -67,10 +67,10 @@ public ExecutionResult run(List<String> argumentValues, CommandOutput output) {
NyzoStringPublicIdentifier publicIdentifierString = new NyzoStringPublicIdentifier(publicIdentifier);

// Build the output table.
CommandTable table = new CommandTable(new CommandTableHeader("private seed (raw)", "privateSeedBytes"),
new CommandTableHeader("private seed (Nyzo string)", "privateSeedNyzoString"),
new CommandTableHeader("public ID (raw)", "publicIdBytes"),
new CommandTableHeader("public ID (Nyzo string)", "publicIdNyzoString"));
CommandTable table = new CommandTable(new CommandTableHeader("private seed (raw)", "privateSeedBytes", true),
new CommandTableHeader("private seed (Nyzo string)", "privateSeedNyzoString", true),
new CommandTableHeader("public ID (raw)", "publicIdBytes", true),
new CommandTableHeader("public ID (Nyzo string)", "publicIdNyzoString", true));
table.setInvertedRowsColumns(true);
table.addRow(ByteUtil.arrayAsStringWithDashes(privateSeed), NyzoStringEncoder.encode(privateSeedString),
ByteUtil.arrayAsStringWithDashes(publicIdentifier), NyzoStringEncoder.encode(publicIdentifierString));
@@ -79,8 +79,8 @@ public ExecutionResult run(List<String> argumentValues, CommandOutput output) {

// Build the output table.
NyzoStringPublicIdentifier publicIdentifierString = new NyzoStringPublicIdentifier(publicIdentifier);
CommandTable table = new CommandTable(new CommandTableHeader("public ID (raw)", "publicIdBytes"),
new CommandTableHeader("public ID (Nyzo string)", "publicIdNyzoString"));
CommandTable table = new CommandTable(new CommandTableHeader("public ID (raw)", "publicIdBytes", true),
new CommandTableHeader("public ID (Nyzo string)", "publicIdNyzoString", true));
table.setInvertedRowsColumns(true);
table.addRow(ByteUtil.arrayAsStringWithDashes(publicIdentifier),
NyzoStringEncoder.encode(publicIdentifierString));
@@ -212,7 +212,7 @@ public EndpointResponse getResponseForHtml() {
if (i > 0) {
body.add(new RawHtml("&rarr;"));
}
body.add(new A().attr("class", "simple-hover-button").attr("href", endpointPath.get(i).getPath())
body.add(new A().attr("class", "hover-button").attr("href", endpointPath.get(i).getPath())
.addRaw(endpointPath.get(i).getTitle()));
}
body.add(new Hr());
@@ -236,8 +236,7 @@ public EndpointResponse getResponseForHtml() {
// Add buttons for all HTML children.
for (DocumentationEndpoint child : children) {
if (child.getType() == DocumentationEndpointType.Html) {
body.add(new A().attr("class", "simple-hover-button").attr("href", child.getPath())
.addRaw(child.getTitle()));
body.add(new A().attr("class", "hover-button").attr("href", child.getPath()).addRaw(child.getTitle()));
}
}

@@ -19,12 +19,12 @@
public static final String acceptButtonStyle = buttonStyle + " border-color: #080; background-color: #484;";
public static final String cancelButtonStyle = buttonStyle + "border-color: #f00; background-color: #f44;";

public static final Style hoverButtonStyles = new Style(".simple-hover-button { " +
public static final Style hoverButtonStyles = new Style(".hover-button { " +
"color: black; text-decoration: none; margin: 0.1rem; " +
"padding: 0.5rem; border: 1px solid black; cursor: default; border-radius: 0.5rem; " +
"display: inline-block; } " +
".simple-hover-button-selected { background-color: rgba(0,0,0,0.3); cursor: default; } " +
".simple-hover-button:hover { background-color: rgba(0,0,0,0.3); }");
".hover-button-selected { background-color: rgba(0,0,0,0.3); cursor: default; } " +
".hover-button:hover { background-color: rgba(0,0,0,0.3); }");

private static final Map<Character, String> characterToPercentEncodingMap = new HashMap<>();
private static final Map<String, Character> percentEncodingToCharacterMap = new HashMap<>();

0 comments on commit 7bd4383

Please sign in to comment.
You can’t perform that action at this time.