Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement show command #100

Merged
merged 6 commits into from Oct 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.gradle
Expand Up @@ -57,6 +57,12 @@ dependencies {
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win'
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac'
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux'
implementation group: 'org.openjfx', name: 'javafx-media', version: javaFxVersion, classifier: 'win'
implementation group: 'org.openjfx', name: 'javafx-media', version: javaFxVersion, classifier: 'mac'
implementation group: 'org.openjfx', name: 'javafx-media', version: javaFxVersion, classifier: 'linux'
implementation group: 'org.openjfx', name: 'javafx-web', version: javaFxVersion, classifier: 'win'
implementation group: 'org.openjfx', name: 'javafx-web', version: javaFxVersion, classifier: 'mac'
implementation group: 'org.openjfx', name: 'javafx-web', version: javaFxVersion, classifier: 'linux'

implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.7.0'
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.7.4'
Expand Down
45 changes: 39 additions & 6 deletions src/main/java/seedu/address/logic/commands/CommandResult.java
Expand Up @@ -4,27 +4,39 @@

import java.util.Objects;

import seedu.address.model.eatery.Eatery;

/**
* Represents the result of a command execution.
*/
public class CommandResult {

private final String feedbackToUser;

/** Help information should be shown to the user. */
private final Eatery eateryToShow;

/**
* Help information should be shown to the user.
*/
private final boolean showHelp;

/** The application should exit. */
/**
* The application should exit.
*/
private final boolean exit;

/** The application should save to-do eatery to eatery list. */
/**
* The application should save to-do eatery to eatery list.
*/
private final boolean wantToSave;

/**
* Constructs a {@code CommandResult} with the specified fields.
*/
public CommandResult(String feedbackToUser, boolean showHelp, boolean exit, boolean wantToSave) {
public CommandResult(String feedbackToUser, Eatery eateryToShow,
boolean showHelp, boolean exit, boolean wantToSave) {
this.feedbackToUser = requireNonNull(feedbackToUser);
this.eateryToShow = eateryToShow;
this.showHelp = showHelp;
this.exit = exit;
this.wantToSave = wantToSave;
Expand All @@ -35,13 +47,33 @@ public CommandResult(String feedbackToUser, boolean showHelp, boolean exit, bool
* and other fields set to their default value.
*/
public CommandResult(String feedbackToUser) {
this(feedbackToUser, false, false, false);
this(feedbackToUser, null, false, false, false);
}

/**
* Constructs a {@code CommandResult} with the specified {@code feedbackToUser} and {@code eateryToShow},
* and other fields set to their default value.
*/
public CommandResult(String feedbackToUser, Eatery eateryToShow) {
this(feedbackToUser, eateryToShow, false, false, false);
}

/**
* Constructs a {@code CommandResult} with the specified fields,
* and {@code eateryToShow} set to its default value
*/
public CommandResult(String feedbackToUser, boolean showHelp, boolean exit, boolean wantToSave) {
this(feedbackToUser, null, showHelp, exit, wantToSave);
}

public String getFeedbackToUser() {
return feedbackToUser;
}

public Eatery getEateryToShow() {
return eateryToShow;
}

public boolean isShowHelp() {
return showHelp;
}
Expand All @@ -67,13 +99,14 @@ public boolean equals(Object other) {

CommandResult otherCommandResult = (CommandResult) other;
return feedbackToUser.equals(otherCommandResult.feedbackToUser)
&& (Objects.equals(eateryToShow, otherCommandResult.eateryToShow))
&& showHelp == otherCommandResult.showHelp
&& exit == otherCommandResult.exit;
}

@Override
public int hashCode() {
return Objects.hash(feedbackToUser, showHelp, exit);
return Objects.hash(feedbackToUser, eateryToShow, showHelp, exit);
}

}
53 changes: 53 additions & 0 deletions src/main/java/seedu/address/logic/commands/ShowCommand.java
@@ -0,0 +1,53 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;

import java.util.List;

import seedu.address.commons.core.Messages;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.eatery.Eatery;

/**
* Shows a eatery identified using it's displayed index from the address book.
*/
public class ShowCommand extends Command {

public static final String COMMAND_WORD = "show";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Shows the eatery identified by the index number used in the displayed eatery list.\n"
+ "Parameters: INDEX (must be a positive integer)\n"
+ "Example: " + COMMAND_WORD + " 1";

public static final String MESSAGE_SHOW_EATERY_SUCCESS = "Shown Eatery: %s";

private final Index targetIndex;

public ShowCommand(Index targetIndex) {
this.targetIndex = targetIndex;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Eatery> lastShownList = model.isMainMode() ? model.getFilteredEateryList() : model.getFilteredTodoList();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_EATERY_DISPLAYED_INDEX);
}

Eatery eateryToShow = lastShownList.get(targetIndex.getZeroBased());
return new CommandResult(
String.format(MESSAGE_SHOW_EATERY_SUCCESS, eateryToShow.getName().fullName), eateryToShow);
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof ShowCommand // instanceof handles nulls
&& targetIndex.equals(((ShowCommand) other).targetIndex)); // state check
}
}
Expand Up @@ -23,6 +23,7 @@
import seedu.address.logic.commands.ReviewCommand;
import seedu.address.logic.commands.SaveTodoCommand;

import seedu.address.logic.commands.ShowCommand;
import seedu.address.logic.parser.exceptions.ParseException;

/**
Expand Down Expand Up @@ -102,6 +103,9 @@ public Command parseCommand(String userInput, boolean isMainMode) throws ParseEx
case DeleteFeedCommand.COMMAND_WORD:
return new DeleteFeedCommandParser().parse(arguments);

case ShowCommand.COMMAND_WORD:
return new ShowCommandParser().parse(arguments);

default:
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
}
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/seedu/address/logic/parser/ShowCommandParser.java
@@ -0,0 +1,32 @@
package seedu.address.logic.parser;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.ShowCommand;
import seedu.address.logic.parser.exceptions.ParseException;

/**
* Parses input arguments and creates a new ShowCommand object
*/
public class ShowCommandParser implements Parser<ShowCommand> {

/**
* Parses the given {@code String} of arguments in the context of the ShowCommand
* and returns a ShowCommand object for execution.
*
* @throws ParseException if the user input does not conform the expected format
*/
public ShowCommand parse(String args) throws ParseException {
try {
requireNonNull(args);
Index index = ParserUtil.parseIndex(args);
return new ShowCommand(index);
} catch (ParseException pe) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ShowCommand.MESSAGE_USAGE), pe);
}
}

}
5 changes: 3 additions & 2 deletions src/main/java/seedu/address/ui/EateryCard.java
Expand Up @@ -8,6 +8,7 @@
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import seedu.address.model.eatery.Eatery;
import seedu.address.model.eatery.Tag;

/**
* An UI component that displays information of a {@code Eatery}.
Expand Down Expand Up @@ -47,8 +48,8 @@ public EateryCard(Eatery eatery, int displayedIndex) {
address.setText(eatery.getAddress().value);
category.setText(eatery.getCategory().getName());
eatery.getTags().stream()
.sorted(Comparator.comparing(tag -> tag.getName()))
.forEach(tag -> tags.getChildren().add(new Label(tag.getName())));
.sorted(Comparator.comparing(Tag::getName))
.forEach(tag -> tags.getChildren().add(new Label(String.format("#%s", tag.getName()))));
}

@Override
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/seedu/address/ui/MainWindow.java
Expand Up @@ -5,6 +5,7 @@
import javafx.fxml.FXML;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.LogsCenter;
Expand Down Expand Up @@ -37,7 +38,7 @@ public class MainWindow extends UiPart<Stage> {
private CommandBox commandBox;

@FXML
private StackPane commandBoxPlaceholder;
private VBox commandBoxPlaceholder;

@FXML
private MenuItem helpMenuItem;
Expand All @@ -46,13 +47,13 @@ public class MainWindow extends UiPart<Stage> {
private StackPane eateryListPanelPlaceholder;

@FXML
private StackPane resultDisplayPlaceholder;
private VBox resultDisplayPlaceholder;

@FXML
private StackPane feedPostListPanelPlaceholder;

@FXML
private StackPane statusbarPlaceholder;
private VBox statusbarPlaceholder;

public MainWindow(Stage primaryStage, Logic logic) {
super(FXML, primaryStage);
Expand Down Expand Up @@ -169,7 +170,7 @@ private CommandResult executeCommand(String commandText) throws CommandException
try {
CommandResult commandResult = logic.execute(commandText);
logger.info("Result: " + commandResult.getFeedbackToUser());
resultDisplay.setFeedbackToUser(commandResult.getFeedbackToUser());
resultDisplay.setFeedbackToUser(commandResult);

if (commandResult.isShowHelp()) {
handleHelp();
Expand All @@ -187,7 +188,7 @@ private CommandResult executeCommand(String commandText) throws CommandException
return commandResult;
} catch (CommandException | ParseException e) {
logger.info("Invalid command: " + commandText);
resultDisplay.setFeedbackToUser(e.getMessage());
resultDisplay.setFeedbackToUser(e);
throw e;
}
}
Expand Down
77 changes: 73 additions & 4 deletions src/main/java/seedu/address/ui/ResultDisplay.java
Expand Up @@ -2,9 +2,19 @@

import static java.util.Objects.requireNonNull;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Comparator;

import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.Region;
import javafx.scene.web.WebView;
import seedu.address.logic.commands.CommandResult;
import seedu.address.model.eatery.Eatery;
import seedu.address.model.eatery.Tag;

/**
* A ui for the status bar that is displayed at the header of the application.
Expand All @@ -13,16 +23,75 @@ public class ResultDisplay extends UiPart<Region> {

private static final String FXML = "ResultDisplay.fxml";

private static final String K = "";
private static final String WEBVIEW_WRAPPER = "<html style=\"background: #212121;\">%s</html>";
private static final String MAPS_WRAPPER = "<iframe width=\"100%%\" height=\"330\" frameborder=\"0\" "
+ "style=\"border:0\" src=\"https://www.google.com/maps/embed/v1/search?q=%s&key=%s\" "
+ "allowfullscreen></iframe>";

@FXML
private TextArea resultDisplay;
private Label commandFeedback;

@FXML
private Label eateryName;
@FXML
private Label eateryCategory;
@FXML
private Label eateryAddress;
@FXML
private FlowPane eateryTags;
@FXML
private WebView eateryMap;

public ResultDisplay() {
super(FXML);
eateryMap.getEngine().loadContent(String.format(WEBVIEW_WRAPPER, ""));
}

public void setFeedbackToUser(String feedbackToUser) {
public void setFeedbackToUser(CommandResult commandResult) {
reset();

String feedbackToUser = commandResult.getFeedbackToUser();
Eatery eateryToShow = commandResult.getEateryToShow();

requireNonNull(feedbackToUser);
resultDisplay.setText(feedbackToUser);
commandFeedback.setText(feedbackToUser);

if (eateryToShow != null) {
// Basic info
eateryName.setText(eateryToShow.getName().fullName);
eateryCategory.setText(eateryToShow.getCategory().getName());
eateryAddress.setText(eateryToShow.getAddress().value);

// Tags
eateryToShow.getTags().stream()
.sorted(Comparator.comparing(Tag::getName))
.forEach(tag -> eateryTags.getChildren().add(new Label(String.format("#%s", tag.getName()))));

// Map
String doc = String.format(MAPS_WRAPPER,
URLEncoder.encode(eateryToShow.getAddress().value, StandardCharsets.UTF_8),
new String(Base64.getDecoder().decode(K)));
eateryMap.getEngine().loadContent(String.format(WEBVIEW_WRAPPER, doc));
}
}

public void setFeedbackToUser(Exception e) {
requireNonNull(e);
reset();
commandFeedback.setText(e.getMessage());
}

/**
* Resets the UI to its initial empty state.
*/
private void reset() {
commandFeedback.setText("");
eateryName.setText("");
eateryCategory.setText("");
eateryAddress.setText("");
eateryTags.getChildren().clear();
eateryMap.getEngine().loadContent(String.format(WEBVIEW_WRAPPER, ""));
}

}
2 changes: 1 addition & 1 deletion src/main/resources/view/CommandBox.fxml
Expand Up @@ -2,5 +2,5 @@

<?import javafx.scene.control.TextField?>

<TextField xmlns:fx="http://javafx.com/fxml/1" fx:id="commandTextField" styleClass="plain-border-box"
<TextField xmlns:fx="http://javafx.com/fxml/1" fx:id="commandTextField" minWidth="280" prefWidth="280"
onAction="#handleCommandEntered" promptText="Enter command"/>