diff --git a/client/.classpath b/client/.classpath
index 99d4cc0..4328dab 100644
--- a/client/.classpath
+++ b/client/.classpath
@@ -20,7 +20,6 @@
+ * Project: client
+ * File: BugReportPane.java
+ * Created: Aug 4, 2020
+ *
+ * @author Leon Hofmeister
+ * @since Envoy Client v0.2-beta
+ */
+public class BugReportPane extends OnlyIfOnlineSettingsPane {
+
+ private final Label titleLabel = new Label("Suggest a title for the bug:");
+ private final TextField titleTextField = new TextField();
+ private final Label pleaseExplainLabel = new Label("Paste here the log of what went wrong and/ or explain what went wrong:");
+ private final TextArea errorDetailArea = new TextArea();
+ private final CheckBox showUsernameInBugReport = new CheckBox("Show your username in the bug report?");
+ private final Button submitReportButton = new Button("Submit report");
+
+ private final EventHandler super InputEvent> inputEventHandler = e -> submitReportButton.setDisable(titleTextField.getText().isBlank());
+
+ /**
+ * Creates a new {@code BugReportPane}.
+ *
+ * @param user the user whose details to use
+ * @param online whether this user is currently online
+ * @since Envoy Client v0.2-beta
+ */
+ public BugReportPane(User user, boolean online) {
+ super("Report a bug", online);
+ setSpacing(10);
+ setToolTipText("A bug can only be reported when being online");
+
+ // Displaying the label to ask for a title
+ titleLabel.setWrapText(true);
+ getChildren().add(titleLabel);
+
+ // Displaying the TextField where to enter the title of this bug
+ titleTextField.setOnKeyTyped(inputEventHandler);
+ titleTextField.setOnInputMethodTextChanged(inputEventHandler);
+ getChildren().add(titleTextField);
+
+ // Displaying the label to ask for clarification
+ pleaseExplainLabel.setWrapText(true);
+ getChildren().add(pleaseExplainLabel);
+
+ // Displaying the TextArea where to enter the log and/or own description
+ errorDetailArea.setWrapText(true);
+ getChildren().add(errorDetailArea);
+
+ // Displaying the consent button that your user name will be shown
+ showUsernameInBugReport.setSelected(true);
+ getChildren().add(showUsernameInBugReport);
+
+ // Displaying the submitReportButton
+ submitReportButton.setDisable(true);
+ submitReportButton.setOnAction(e -> {
+ EventBus.getInstance()
+ .dispatch(new SendEvent(new IssueProposal(titleTextField.getText(), errorDetailArea.getText(),
+ showUsernameInBugReport.isSelected() ? user.getName() : null, true)));
+ });
+ getChildren().add(submitReportButton);
+ }
+}
diff --git a/client/src/main/java/envoy/client/ui/settings/OnlyIfOnlineSettingsPane.java b/client/src/main/java/envoy/client/ui/settings/OnlyIfOnlineSettingsPane.java
new file mode 100644
index 0000000..7e16792
--- /dev/null
+++ b/client/src/main/java/envoy/client/ui/settings/OnlyIfOnlineSettingsPane.java
@@ -0,0 +1,51 @@
+package envoy.client.ui.settings;
+
+import javafx.geometry.Insets;
+import javafx.scene.control.Label;
+import javafx.scene.control.Tooltip;
+import javafx.scene.layout.Background;
+import javafx.scene.layout.BackgroundFill;
+import javafx.scene.layout.CornerRadii;
+import javafx.scene.paint.Color;
+
+/**
+ * Inheriting from this class signifies that options should only be available if
+ * the {@link envoy.data.User} is currently online. If the user is currently
+ * offline, all {@link javafx.scene.Node} variables will be disabled and a
+ * {@link Tooltip} will be displayed for the whole node.
+ *
+ * Project: client
+ * Project: common
+ * Project: server
+ * File: OnlyIfOnlineSettingsPane.java
+ * Created: Aug 4, 2020
+ *
+ * @author Leon Hofmeister
+ * @since Envoy Client v0.2-beta
+ */
+public abstract class OnlyIfOnlineSettingsPane extends SettingsPane {
+
+ private final Tooltip beOnlineReminder = new Tooltip("You need to be online to modify your acount.");
+
+ /**
+ * @param title
+ * @since Envoy Client v0.2-beta
+ */
+ protected OnlyIfOnlineSettingsPane(String title, boolean online) {
+ super(title);
+
+ final var offline = !online;
+
+ setDisable(offline);
+
+ if (offline) {
+ final var infoLabel = new Label("You shall not pass!\n(... Unless you would happen to be online)");
+ infoLabel.setId("infoLabel-warning");
+ infoLabel.setWrapText(true);
+ getChildren().add(infoLabel);
+ setBackground(new Background(new BackgroundFill(Color.grayRgb(100, 0.3), CornerRadii.EMPTY, Insets.EMPTY)));
+
+ Tooltip.install(this, beOnlineReminder);
+ } else Tooltip.uninstall(this, beOnlineReminder);
+ }
+
+ protected void setToolTipText(String text) { beOnlineReminder.setText(text); }
+}
diff --git a/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java b/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java
index cad265b..098abac 100644
--- a/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java
+++ b/client/src/main/java/envoy/client/ui/settings/UserSettingsPane.java
@@ -22,7 +22,6 @@ import envoy.client.event.SendEvent;
import envoy.client.ui.IconUtil;
import envoy.client.ui.SceneContext;
import envoy.client.ui.custom.ProfilePicImageView;
-import envoy.client.util.ReflectionUtil;
import envoy.data.User;
import envoy.event.*;
import envoy.util.Bounds;
@@ -36,7 +35,7 @@ import envoy.util.EnvoyLog;
* @author Leon Hofmeister
* @since Envoy Client v0.2-beta
*/
-public class UserSettingsPane extends SettingsPane {
+public class UserSettingsPane extends OnlyIfOnlineSettingsPane {
private boolean profilePicChanged, usernameChanged, validPassword;
private byte[] currentImageBytes;
@@ -49,8 +48,6 @@ public class UserSettingsPane extends SettingsPane {
private final PasswordField repeatNewPasswordField = new PasswordField();
private final Button saveButton = new Button("Save");
- private final Tooltip beOnlineReminder = new Tooltip("You need to be online to modify your acount.");
-
private static final EventBus eventBus = EventBus.getInstance();
private static final Logger logger = EnvoyLog.getLogger(UserSettingsPane.class);
@@ -63,7 +60,7 @@ public class UserSettingsPane extends SettingsPane {
* @since Envoy Client v0.2-beta
*/
public UserSettingsPane(SceneContext sceneContext, User user, boolean online) {
- super("User");
+ super("User", online);
setSpacing(10);
// Display of profile pic change mechanism
@@ -143,17 +140,6 @@ public class UserSettingsPane extends SettingsPane {
saveButton.setOnAction(e -> save(user.getID(), currentPasswordField.getText()));
saveButton.setAlignment(Pos.BOTTOM_RIGHT);
getChildren().add(saveButton);
-
- final var offline = !online;
- ReflectionUtil.getAllDeclaredNodeVariables(this).forEach(node -> node.setDisable(offline));
- if (offline) {
- final var infoLabel = new Label("You shall not pass!\n(... Unless you would happen to be online)");
- infoLabel.setId("infoLabel-warning");
- infoLabel.setWrapText(true);
- getChildren().add(infoLabel);
-
- Tooltip.install(this, beOnlineReminder);
- } else Tooltip.uninstall(this, beOnlineReminder);
}
/**
diff --git a/client/src/main/java/envoy/client/util/ReflectionUtil.java b/client/src/main/java/envoy/client/util/ReflectionUtil.java
index 132f5da..92c243a 100644
--- a/client/src/main/java/envoy/client/util/ReflectionUtil.java
+++ b/client/src/main/java/envoy/client/util/ReflectionUtil.java
@@ -42,7 +42,6 @@ public class ReflectionUtil {
try {
field.setAccessible(true);
final var value = field.get(instance);
- field.setAccessible(false);
return value;
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
diff --git a/client/src/main/resources/fxml/SettingsScene.fxml b/client/src/main/resources/fxml/SettingsScene.fxml
index 8474c1d..fdf4a8f 100644
--- a/client/src/main/resources/fxml/SettingsScene.fxml
+++ b/client/src/main/resources/fxml/SettingsScene.fxml
@@ -30,7 +30,7 @@
+ * File: IssueProposal.java
+ * Created: Aug 5, 2020
+ *
+ * @author Leon Hofmeister
+ * @since Envoy Common v0.2-beta
+ */
+public class IssueProposal extends Event
+ * File: IssueProposalProcessor.java
+ * Created: Aug 5, 2020
+ *
+ * @author Leon Hofmeister
+ * @since Envoy Server v0.2-beta
+ */
+public class IssueProposalProcessor implements ObjectProcessor
") ? "" : "
")
+ + String.format("Submitted by user %s.", issueProposal.getSubmitterName())
+ : "";
+ // Markdown does not support "\n". It uses "
"
+ issueDescription = issueDescription.replaceAll("\n", "
");
+ // We do not want any Windows artifacts to remain as that may cause problems
+ issueDescription = issueDescription.replaceAll("\r", "");
+ try {
+ final var url = new URL(
+ "https://git.kske.dev/api/v1/repos/zdm/envoy/issues?access_token=6d8ec2a72d64cbaf6319434aa2e7caf0130701b3");
+ final var connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json; utf-8");
+ connection.setRequestProperty("Accept", "application/json");
+ connection.setDoOutput(true);
+
+ final var json = String.format("{\"title\":\"%s\",\"body\":\"%s\",\"labels\":[240, %d]}",
+ issueProposal.get(),
+ issueDescription,
+ // Label 240 should be user-made, label 117 bug and label 119 feature
+ issueProposal.isBug() ? 117 : 119);
+ try (final var os = connection.getOutputStream()) {
+ final byte[] input = json.getBytes("utf-8");
+ os.write(input, 0, input.length);
+ }
+ final var status = connection.getResponseCode();
+ if (status == 201) logger.log(Level.INFO, "Successfully created an issue");
+ else logger.log(Level.WARNING,
+ String.format("Tried creating an issue but received status code %d - Request params:title=%s,description=%s,json=%s",
+ status,
+ issueProposal.get(),
+ issueDescription,
+ json));
+ } catch (final IOException e) {
+ logger.log(Level.WARNING, "An error occurred while creating an issue: ", e);
+ }
+ }
+
+ /**
+ * @return whether issue reporting is enabled
+ * @since Envoy Server v0.2-beta
+ */
+ public static boolean isIssueReportingEnabled() { return issueReportingEnabled; }
+
+ /**
+ * @param issueReportingEnabled whether issue reporting should be enabled - true
+ * by default
+ * @since Envoy Server v0.2-beta
+ */
+ public static void setIssueReportingEnabled(boolean issueReportingEnabled) {
+ IssueProposalProcessor.issueReportingEnabled = issueReportingEnabled;
+ }
+}