Skip to content

Commit

Permalink
Extract out the logic of checking Gopher message type to Message.java
Browse files Browse the repository at this point in the history
Currently, Gopher's response will be styled as red background if the
response is a warning message that contains text "Please try again".
Even though such implementation works in most cases, it will introduce
styling error in the system if user creates a task with "Please try
again" as part of its name, hence affecting user experience. Also, such
way of recognizing message type and styling is not very extensible and
flexible, hence a better idea would be extract out the logic to another
class to explicitly handle this, so as to provide more flexibility when
similar features need to be developed in the future.

As a result, Message class is created to wrap around the text returned
by Gopher so that other information such as message type can be input
and pass around the program for checks. This offers more flexibility as
compared to the initial approach and hence should be included in the
latest update
  • Loading branch information
MAOXIONGKAI committed Sep 18, 2024
1 parent f6c0e45 commit bde26d3
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 84 deletions.
51 changes: 26 additions & 25 deletions src/main/java/gopher/Gopher.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import gopher.exception.MissingTaskNumberException;
import gopher.exception.MissingTokenException;
import gopher.exception.UnknownCommandException;
import gopher.message.Message;
import gopher.parser.Parser;
import gopher.storage.TaskManager;
import gopher.task.Task;
Expand Down Expand Up @@ -42,39 +43,39 @@ public Gopher() {
/**
* Executes the relevant actions when user input exit program command
*
* @return response by gopher after successful action
* @return Message object indicating response by gopher after successful action
*/
public static String executeExitCommand() {
public static Message executeExitCommand() {
Platform.exit();
return UI.getExitMessage();
}

/**
* Executes the relevant actions when user input list tasks command
*
* @return response by gopher after successful action
* @return Message object indicating response by gopher after successful action
*/
public static String executeListTasksCommand() {
public static Message executeListTasksCommand() {
return UI.getTaskListMessage(taskList);
}

/**
* Executes the relevant actions when user input mark task as done command.
*
* @param userInput command input by the user
* @return response by gopher after successful action
* @return Message object indicating response by gopher after successful action
*/
public static String executeMarkTaskCommand(String userInput) {
public static Message executeMarkTaskCommand(String userInput) {
try {
int[] taskNumbers = Parser.parseMarkCommand(userInput);
taskList.markAsDone(taskNumbers);
StringBuilder message = new StringBuilder();
for (int taskNumber : taskNumbers) {
message.append(UI.getMarkAsDoneMessage(taskList.getTask(taskNumber)));
}
return message.toString();
return UI.getMessage(message.toString());
} catch (MissingTaskNumberException | InvalidTaskNumberException e) {
return e.getMessage();
return UI.getErrorMessage(e);
} finally {
taskList.save();
}
Expand All @@ -84,19 +85,19 @@ public static String executeMarkTaskCommand(String userInput) {
* Executes the relevant actions when user input mark task as not done command.
*
* @param userInput command input by the user
* @return response by gopher after successful action
* @return Message object indicating response by gopher after successful action
*/
public static String executeUnmarkTaskCommand(String userInput) {
public static Message executeUnmarkTaskCommand(String userInput) {
try {
int[] taskNumbers = Parser.parseUnmarkCommand(userInput);
taskList.markAsUndone(taskNumbers);
StringBuilder message = new StringBuilder();
for (int taskNumber : taskNumbers) {
message.append(UI.getMarkAsUndoneMessage(taskList.getTask(taskNumber)));
}
return message.toString();
return UI.getMessage(message.toString());
} catch (MissingTaskNumberException | InvalidTaskNumberException e) {
return e.getMessage();
return UI.getErrorMessage(e);
} finally {
taskList.save();
}
Expand All @@ -106,19 +107,19 @@ public static String executeUnmarkTaskCommand(String userInput) {
* Executes the relevant actions when user input delete task command.
*
* @param userInput command input by the user
* @return response by gopher after successful action
* @return Message object indicating response by gopher after successful action
*/
public static String executeDeleteTaskCommand(String userInput) {
public static Message executeDeleteTaskCommand(String userInput) {
try {
int[] taskNumbers = Parser.parseDeleteCommand(userInput);
StringBuilder message = new StringBuilder();
for (int taskNumber : taskNumbers) {
message.append(UI.getDeleteTaskMessage(taskList.getTask(taskNumber)));
}
taskList.delete(taskNumbers);
return message.toString();
return UI.getMessage(message.toString());
} catch (MissingTaskNumberException | InvalidTaskNumberException e) {
return e.getMessage();
return UI.getErrorMessage(e);
} finally {
taskList.save();
}
Expand All @@ -128,9 +129,9 @@ public static String executeDeleteTaskCommand(String userInput) {
* Executes the relevant actions when user input find task command.
*
* @param userInput command input by the user
* @return response by gopher after successful action
* @return Message object indicating response by gopher after successful action
*/
public static String executeFindTaskCommand(String userInput) {
public static Message executeFindTaskCommand(String userInput) {
String keyword = Parser.parseFindCommand(userInput);
TaskList matchedTasks = taskList.find(keyword);
return UI.getMatchedTasksMessage(matchedTasks);
Expand All @@ -140,9 +141,9 @@ public static String executeFindTaskCommand(String userInput) {
* Executes the relevant actions when user input create task command.
*
* @param userInput command input by the user
* @return response by gopher after successful action
* @return Message object indicating response by gopher after successful action
*/
public static String executeCreateTaskCommand(String userInput)
public static Message executeCreateTaskCommand(String userInput)
throws UnknownCommandException {
try {
Task task = Task.of(userInput);
Expand All @@ -152,32 +153,32 @@ public static String executeCreateTaskCommand(String userInput)
return UI.getInvalidDateWarning();
} catch (EmptyTaskDescriptionException | MissingTokenException
| InvalidTokenException | InvalidDurationException e) {
return e.getMessage();
return UI.getErrorMessage(e);
}
}

/**
* Executes the relevant actions when user input update task command.
*
* @param userInput command input by the user
* @return response by gopher after successful action
* @return Message object indicating response by gopher after successful action
*/
public static String executeUpdateTaskCommand(String userInput) {
public static Message executeUpdateTaskCommand(String userInput) {
try {
String[] tokens = userInput.split(" ");
return taskList.update(tokens);
} catch (DateTimeParseException e) {
return UI.getInvalidDateWarning();
} catch (InvalidTokenException | MissingTaskNumberException
| InvalidTaskNumberException | InvalidDurationException e) {
return e.getMessage();
return UI.getErrorMessage(e);
}
}

/**
* Start the main event loop.
*/
public static String getResponse(String userInput)
public static Message getResponse(String userInput)
throws UnknownCommandException {
if (userInput.equalsIgnoreCase("bye")) {
return executeExitCommand();
Expand Down
17 changes: 16 additions & 1 deletion src/main/java/gopher/exception/UnknownCommandException.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ public UnknownCommandException(String command) {
public String getMessage() {
return "Sorry, but I can't recognize this command: "
+ this.command
+ "\nPlease try again...\n\n";
+ "\nPlease try again...\n\n"
+ """
Currently I can understand the following commands:
1. todo - Create a ToDo Task
2. deadline - Create a Deadline Task
3. event - Create an Event Task
4. mark - Mark tasks as done
5. unmark - Mark tasks as not done
6. find - Find tasks based on keywords
7. update - Update a task with provided information
8. delete - Delete tasks from the task list
9. bye - Exit the chatbot
Note that the command is case-insensitive,
as long as the input characters match,
I would be able to respond to the given command""";
}
}
35 changes: 24 additions & 11 deletions src/main/java/gopher/gui/DialogBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import java.io.IOException;
import java.util.Collections;
import java.util.regex.Pattern;

import gopher.message.Message;
import gopher.message.MessageType;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
Expand Down Expand Up @@ -54,30 +55,42 @@ private void flip() {
}

/**
* Render the background of the gopher dialog box based whether the message
* Renders the background of the gopher dialog box based whether the message
* is a normal conversation or a warning
*
* @param text text within the gopher's dialog box
* @param message text within the gopher's dialog box
*/
private void renderBackground(String text) {
Pattern warningPattern = Pattern.compile("Please try again",
Pattern.CASE_INSENSITIVE);
if (warningPattern.matcher(text).find()) {
private void renderBackground(Message message) {
if (message.getType() == MessageType.ERROR) {
dialog.getStyleClass().add("warning-color");
} else {
dialog.getStyleClass().add("reply-color");
return;
}
dialog.getStyleClass().add("reply-color");
}

/**
* Creates a User Dialog Box to represent user's input to Gopher
*
* @param text input from the user
* @param img profile image for the user
* @return DialogBox Object that represents user's input
*/
public static DialogBox getUserDialog(String text, Image img) {
var db = new DialogBox(text, img);
Circle clip = new Circle(32, 32, 32);
db.displayPicture.setClip(clip);
return db;
}

public static DialogBox getGopherDialog(String text, Image img) {
var db = new DialogBox(text, img);
/**
* Creates a Gopher Dialog Box to represent Gopher's response to user
*
* @param text response by Gopher
* @param img profile image for Gopher
* @return DialogBox Object that represents Gopher's response
*/
public static DialogBox getGopherDialog(Message text, Image img) {
var db = new DialogBox(text.toString(), img);
db.flip();
db.renderBackground(text);
return db;
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/gopher/gui/MainWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import gopher.Gopher;
import gopher.exception.UnknownCommandException;
import gopher.message.Message;
import gopher.ui.UI;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
Expand Down Expand Up @@ -64,7 +65,7 @@ private void handleUserInput() {
return;
}
try {
String response = gopher.getResponse(input);
Message response = gopher.getResponse(input);
dialogContainer.getChildren().addAll(
DialogBox.getUserDialog(input, userImage),
DialogBox.getGopherDialog(response, gopherImage)
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/gopher/message/Message.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package gopher.message;

/**
* Represents message returned by Gopher when user input any commands.
* Contains information such as text, message type.
*/
public class Message {
private String text;
private MessageType type;

/**
* Constructor for Message class.
*
* @param text text within the message
* @param type type of message, specified by MessageType Enum class
*/
public Message(String text, MessageType type) {
this.text = text;
this.type = type;
}

/**
* Gets the type of the Message Object
*
* @return type of message
*/
public MessageType getType() {
return this.type;
}

@Override
public String toString() {
return text;
}
}
17 changes: 17 additions & 0 deletions src/main/java/gopher/message/MessageType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package gopher.message;

/**
* Types of messages that Gopher would respond to the user
* @see #TEXT
* @see #ERROR
*/
public enum MessageType {
/**
* Normal text message
*/
TEXT,
/**
* Error message
*/
ERROR
}
3 changes: 2 additions & 1 deletion src/main/java/gopher/task/TaskList.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import gopher.exception.InvalidTaskNumberException;
import gopher.exception.InvalidTokenException;
import gopher.exception.MissingTaskNumberException;
import gopher.message.Message;
import gopher.storage.TaskManager;
import gopher.ui.UI;

Expand Down Expand Up @@ -64,7 +65,7 @@ public void add(Task task) {
* @param tokens tokens from the update command
* @return UI message showing the detail of the updated task
*/
public String update(String[] tokens)
public Message update(String[] tokens)
throws InvalidTokenException, MissingTaskNumberException,
InvalidTaskNumberException, InvalidDurationException {
try {
Expand Down
Loading

0 comments on commit bde26d3

Please sign in to comment.