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

[Cloud7050] iP #532

Open
wants to merge 123 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
123 commits
Select commit Hold shift + click to select a range
28ad2b8
Add Gradle support
May 24, 2020
ed6d4d2
Bump gradle and lib version
Eclipse-Dominator Aug 5, 2023
e8b3258
chore(gitignore): Trim gitignore
Cloud7050 Aug 31, 2023
cc7b41d
chore(md): Delete CONTRIBUTORS.md
Cloud7050 Aug 31, 2023
fb5add2
feat(): Rename Duke to Cloud
Cloud7050 Aug 31, 2023
0b33360
feat(Cloud): Change default text to greeting/farewell
Cloud7050 Aug 31, 2023
1d9a846
feat(Cloud): Command handler, docs, bye command, echo unknown commands
Cloud7050 Aug 31, 2023
304ec50
feat(Cloud): Commands to add TODOs, list TODOs
Cloud7050 Aug 31, 2023
2b43d5a
feat(): Trim private docs, create Todo class
Cloud7050 Aug 31, 2023
a76b0db
feat(Cloud): Extract first word, handle empty, display isDone
Cloud7050 Aug 31, 2023
1a28c69
ref(Todo): Rename done to complete
Cloud7050 Aug 31, 2023
6881b0d
feat(Cloud): Mark/unmark with error handling, trim comments
Cloud7050 Aug 31, 2023
f8ea187
feat(Cloud): Simplify error checking, change todo display
Cloud7050 Aug 31, 2023
dbc3b33
feat(todo): Move to todo package, simplify, create Deadline/Event
Cloud7050 Aug 31, 2023
9be3d20
style(): Fix accidental tabs, update VSCode settings for repo
Cloud7050 Aug 31, 2023
774a366
devfeat(Token): Create initial token handler
Cloud7050 Aug 31, 2023
21d63d0
ref(): Handle commands mostly as tokens
Cloud7050 Aug 31, 2023
0f15682
ref(): TokenManager, trim setters
Cloud7050 Aug 31, 2023
eddd8a2
devfeat(): Add type strings, Todo toString
Cloud7050 Aug 31, 2023
4fe1224
fix(TokenManager): Fix infinite removeTokens()
Cloud7050 Aug 31, 2023
e2b528a
ref(TokenManager): Store sub input without flag
Cloud7050 Aug 31, 2023
35067fb
feat(todo): Different Todo string representations
Cloud7050 Aug 31, 2023
b88606a
feat(Cloud): Create different Todos based on flags!
Cloud7050 Aug 31, 2023
4f1f3f6
chore(tests): Remove shell test script
Cloud7050 Sep 3, 2023
5610437
feat(src): Handle EOF, move packages
Cloud7050 Sep 3, 2023
811a80c
chore(gitignore): Trim, edit for tests
Cloud7050 Sep 3, 2023
e945188
devfeat(tests): Update for semi-auto test
Cloud7050 Sep 3, 2023
ca81c37
ref(todo): Improve toString()
Cloud7050 Sep 3, 2023
373f286
feat(src): Require command to add TODOs
Cloud7050 Sep 3, 2023
0e01257
devfeat(tests): Update inputs/outputs
Cloud7050 Sep 3, 2023
becf338
fix(): Use new MissingInputException, fix empty split() corner case
Cloud7050 Sep 3, 2023
541f6bc
ref(src): Use new @Nullable
Cloud7050 Sep 3, 2023
9a7cdee
feat(): TokenManager child classes, empty sub input exception
Cloud7050 Sep 3, 2023
59bb19f
feat(): Intelligent space handling!
Cloud7050 Sep 3, 2023
e161bc5
feat(): Add deletion, fix boundary error
Cloud7050 Sep 3, 2023
abb83ad
ref(src): Add CommandType enum!
Cloud7050 Sep 3, 2023
ed9c0c6
ref(src): Remove redundant default constructors
Cloud7050 Sep 7, 2023
bc86d2e
docs(src): Add missing public constructor docs
Cloud7050 Sep 7, 2023
c6eed14
chore(src): Restore src/main/java/ structure
Cloud7050 Sep 7, 2023
8d26682
ref(src): TodoManager to prepare for file storage
Cloud7050 Sep 11, 2023
69f990f
ref(): Rename TODO to Item, add Item parent class
Cloud7050 Sep 11, 2023
e7c1de2
fix(test): Fix new src path in test's javac
Cloud7050 Sep 11, 2023
badd237
ref(src): Rename task to item in package
Cloud7050 Sep 11, 2023
f2e99fb
chore(lib): Add org.json
Cloud7050 Sep 11, 2023
3818dd7
devfeat(src): Add export() item to JSON
Cloud7050 Sep 11, 2023
5681260
feat(src): Save to file with every item change
Cloud7050 Sep 11, 2023
b7153f7
feat(): Create directory if not exists. Gitignore
Cloud7050 Sep 11, 2023
8308678
docs(FileManager): JavaDoc
Cloud7050 Sep 11, 2023
c90a50a
feat(src): Read from file if exists
Cloud7050 Sep 11, 2023
bde28cb
fix(test): Update for lib & data folder
Cloud7050 Sep 11, 2023
09b9691
ref(src): Enums for ItemType, JSON Key
Cloud7050 Sep 11, 2023
07914d4
Merge branch 'branch-Level-7'
Cloud7050 Sep 11, 2023
996216e
FEAT(src): Handle real timestamps
Cloud7050 Sep 11, 2023
3befadd
feat(tests): Update tests for new timestamps
Cloud7050 Sep 11, 2023
a0fdfd2
Merge branch 'branch-Level-8'
Cloud7050 Sep 11, 2023
3349793
ref(src): Extract Ui class
Cloud7050 Sep 11, 2023
910bca7
ref(src): Extract Handler class
Cloud7050 Sep 11, 2023
4d16a80
ref(src): Singular package names
Cloud7050 Sep 11, 2023
8a692b5
ref(src): Split into Commands
Cloud7050 Sep 11, 2023
3a3d1d2
Merge branch 'add-gradle-support' of https://github.com/Cloud7050/ip
Cloud7050 Sep 12, 2023
d0d2b64
style(test): Cosmetic capitalisation
Cloud7050 Sep 12, 2023
1f39294
chore(gradle): Remove unix script
Cloud7050 Sep 12, 2023
6b463ae
chore(gitignore): Ignore .gradle/
Cloud7050 Sep 12, 2023
5df2d8e
devfeat(): Set up working gradle
Cloud7050 Sep 13, 2023
735bfd5
devfeat(test): Set up runnable dummy tests
Cloud7050 Sep 14, 2023
0baff58
devfeat(test): Add real tests
Cloud7050 Sep 14, 2023
8e5e69d
chore(gradle): Tweaks for jar
Cloud7050 Sep 14, 2023
929e65c
docs(src): Docs tweaks in root src dir
Cloud7050 Sep 14, 2023
c9fddc3
docs(FileStorage): Tweak docs
Cloud7050 Sep 14, 2023
1013ed1
feat(src): FindCommand
Cloud7050 Sep 14, 2023
6a981f3
devfeat(test): Update & fix overall test script
Cloud7050 Sep 14, 2023
e3b0f11
feat(FindCommand): No match message contains query
Cloud7050 Sep 14, 2023
d11ff49
Merge branch 'branch-A-JavaDoc'
Cloud7050 Sep 14, 2023
0712206
Merge branch 'branch-A-CodingStandard'
Cloud7050 Sep 14, 2023
dd837a3
Merge branch 'branch-Level-9'
Cloud7050 Sep 14, 2023
95daf36
devfeat(): Add initial checkstyle
Cloud7050 Sep 20, 2023
0b5a85f
chore(checkstyle): Tweak config
Cloud7050 Sep 20, 2023
69c2957
chore(gitignore): Ignore bin/ from VSCode build
Cloud7050 Sep 20, 2023
cecdeec
style(src): Fix checkstyle issues
Cloud7050 Sep 20, 2023
d1ba67a
Merge branch 'branch-A-CheckStyle'
Cloud7050 Sep 20, 2023
d8bb3d8
chore(gradle): Add JavaFX
Cloud7050 Sep 21, 2023
b48a507
feat(src): Launch UI with label
Cloud7050 Sep 21, 2023
6f4c459
feat(Ui): Add initial nodes with neat styling
Cloud7050 Sep 21, 2023
b5eaec2
deat(Ui): Initial event handlers
Cloud7050 Sep 21, 2023
1cd0649
chore(checkstyle): Allow lambda on nested newline
Cloud7050 Sep 21, 2023
8a65ca9
feat(): Directional message rows with images
Cloud7050 Sep 21, 2023
4cebf4f
feat(src): Add padding
Cloud7050 Sep 21, 2023
3e9daf6
style(checkstyle): Tweak formatting
Cloud7050 Sep 21, 2023
e50e606
ref(src): Rename to CloudApp
Cloud7050 Sep 21, 2023
3828a89
feat(view): Add template fxml with slight edits
Cloud7050 Sep 21, 2023
49cffd0
feat(fxml): Create new components
Cloud7050 Sep 21, 2023
e42feef
feat(fxml): Update views
Cloud7050 Sep 21, 2023
50ec32f
feat(): Run using FXML
Cloud7050 Sep 21, 2023
86355bf
fix(fxml): Fix events. Set lower API version
Cloud7050 Sep 21, 2023
54b73ea
fix(fxml): Fix alignment width bug
Cloud7050 Sep 21, 2023
fdb9b57
feat(src): Bring back isUser, not using flipping
Cloud7050 Sep 21, 2023
9a50a91
FEAT(): Hook real logic back up to UI
Cloud7050 Sep 21, 2023
9ec23bd
devfeat(checkstyle): Readd ParameterName but allow leading _
Cloud7050 Sep 21, 2023
5acbd95
Merge branch 'branch-Level-10'
Cloud7050 Sep 21, 2023
25d48ee
chore(): Scrap text-based tests
Cloud7050 Sep 21, 2023
baf4879
feat(): Use Java assertions
Cloud7050 Sep 21, 2023
70a2ccf
chore(gradle): Tidy config
Cloud7050 Sep 21, 2023
c00a210
Merge pull request #2 from Cloud7050/branch-A-Assertions
Cloud7050 Sep 21, 2023
0244d3e
Merge branch 'master' into branch-A-CodeQuality
Cloud7050 Sep 21, 2023
02b1845
Merge pull request #3 from Cloud7050/branch-A-CodeQuality
Cloud7050 Sep 21, 2023
4533db1
devfeat(github): Add action
Cloud7050 Sep 21, 2023
e2d717a
chore(gradle): Update gradlew and readd sh script
Cloud7050 Sep 21, 2023
8fd31e0
fix(gradle): Set executable bit of gradlew
Cloud7050 Sep 21, 2023
6dc36eb
devfeat(test): Support UTC tests
Cloud7050 Sep 21, 2023
b80e03f
chore(test): Remove unused import
Cloud7050 Sep 21, 2023
c75c6a4
fix(test): Fix timestamp for UTC variant
Cloud7050 Sep 21, 2023
d72feec
docs(): Add screenshot
Cloud7050 Sep 22, 2023
df6551d
docs(readme): Add image and UG link
Cloud7050 Sep 22, 2023
59c7896
docs(readme): Add alt link to GitHub Page
Cloud7050 Sep 22, 2023
8fdaaf9
docs(readme): Reorder paras due to tall image
Cloud7050 Sep 22, 2023
22e50cb
docs(readme): Add real user guide
Cloud7050 Sep 22, 2023
aae82a4
feat(src): Polish messages
Cloud7050 Sep 22, 2023
3a6835a
feat(fxml): Shrink profile pics
Cloud7050 Sep 22, 2023
749eba0
fix(fxml): Fix messages overflowing X
Cloud7050 Sep 22, 2023
e8ad23a
feat(): Change completion text to emoji
Cloud7050 Sep 22, 2023
2bb8116
Revert "feat(): Change completion text to emoji"
Cloud7050 Sep 22, 2023
af543d1
docs(): Update showcase image
Cloud7050 Sep 22, 2023
b64185d
docs(): Header capitalisation
Cloud7050 Sep 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,17 +1,2 @@
# IDEA files
/.idea/
/out/
/*.iml

# Gradle build files
/.gradle/
/build/
src/main/resources/docs/

# MacOS custom attributes files created by Finder
.DS_Store
*.iml
bin/

/text-ui-test/ACTUAL.TXT
text-ui-test/EXPECTED-UNIX.TXT
tests/ACTUAL.txt
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"editor.insertSpaces": true,
"editor.detectIndentation": false,
"editor.tabSize": 4
}
9 changes: 0 additions & 9 deletions CONTRIBUTORS.md

This file was deleted.

25 changes: 2 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,3 @@
# Duke project template
# The Cloud Chatbot

This is a project template for a greenfield Java project. It's named after the Java mascot _Duke_. Given below are instructions on how to use it.

## Setting up in Intellij

Prerequisites: JDK 11, update Intellij to the most recent version.

1. Open Intellij (if you are not in the welcome screen, click `File` > `Close Project` to close the existing project first)
1. Open the project into Intellij as follows:
1. Click `Open`.
1. Select the project directory, and click `OK`.
1. If there are any further prompts, accept the defaults.
1. Configure the project to use **JDK 11** (not other versions) as explained in [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk).<br>
In the same dialog, set the **Project language level** field to the `SDK default` option.
3. After that, locate the `src/main/java/Duke.java` file, right-click it, and choose `Run Duke.main()` (if the code editor is showing compile errors, try restarting the IDE). If the setup is correct, you should see something like the below as the output:
```
Hello from
____ _
| _ \ _ _| | _____
| | | | | | | |/ / _ \
| |_| | |_| | < __/
|____/ \__,_|_|\_\___|
```
This is a chatbot named **Cloud**. The name has no relation to the actual cloud.
196 changes: 196 additions & 0 deletions src/com/cloud/chatbot/Cloud.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package com.cloud.chatbot;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import com.cloud.chatbot.annotations.Nullable;
import com.cloud.chatbot.exceptions.MissingFlagInputException;
import com.cloud.chatbot.exceptions.MissingInputException;
import com.cloud.chatbot.todo.Deadline;
import com.cloud.chatbot.todo.Event;
import com.cloud.chatbot.todo.Todo;
import com.cloud.chatbot.token.CommandManager;
import com.cloud.chatbot.token.FlagManager;
import com.cloud.chatbot.token.Token;



/**
* The chatbot's main class.
*/
public final class Cloud {
private static final Scanner SCANNER = new Scanner(System.in);
Cloud7050 marked this conversation as resolved.
Show resolved Hide resolved
private static final List<Todo> TODOS = new ArrayList<>();

private static void handle(String input) {
CommandManager manager = new CommandManager(input);
String command;
try {
command = manager.getCommand();
} catch (MissingInputException e) {
// Ignore empty inputs
return;
}

switch (CommandType.stringToCommandType(command)) {
case ADD: {
@Nullable Todo todo = Cloud.createTodo(manager);
if (todo == null) {
break;
}

Cloud.TODOS.add(todo);
Cloud.say(todo.toString(Cloud.TODOS.size()));
break;
}
case LIST: {
if (Cloud.TODOS.size() <= 0) {
Cloud.say("Your TODO list is empty.");
break;
}

for (int i = 0; i < Cloud.TODOS.size(); i++) {
Todo todo = Cloud.TODOS.get(i);
Cloud.say(todo.toString(i + 1));
}
break;
}
case MARK: {
@Nullable Integer number = Cloud.verifyNumber(manager);
if (number == null) {
break;
}

Todo todo = Cloud.TODOS.get(number - 1);
todo.setComplete(true);
Cloud.say(todo.toString(number));
break;
}
case UNMARK: {
@Nullable Integer number = Cloud.verifyNumber(manager);
if (number == null) {
break;
}

Todo todo = Cloud.TODOS.get(number - 1);
todo.setComplete(false);
Cloud.say(todo.toString(number));
break;
}
case DELETE: {
@Nullable Integer number = Cloud.verifyNumber(manager);
if (number == null) {
break;
}

Todo todo = Cloud.TODOS.remove(number - 1);
Cloud.say("Yeeted:");
Cloud.say(todo.toString(number));
break;
}
case EXIT: {
Cloud.say("\\o");
System.exit(0);
break;
}
case UNKNOWN:
default: {
Cloud.say(
String.format(
"\"%s\" is not a valid command.",
command
)
);
break;
}
Cloud7050 marked this conversation as resolved.
Show resolved Hide resolved
}
}

private static @Nullable Todo createTodo(CommandManager manager) {
String description;
try {
description = manager.getDetails();
} catch (MissingInputException e) {
Cloud.say("Please enter a description for your TODO.");
return null;
}

@Nullable FlagManager managerBy = manager.findFlag("by");
@Nullable FlagManager managerFrom = manager.findFlag("from");
@Nullable FlagManager managerTo = manager.findFlag("to");

try {
if (managerBy != null) {
return new Deadline(description, managerBy.getSubInput());
}
if (managerFrom != null && managerTo != null) {
return new Event(description, managerFrom.getSubInput(), managerTo.getSubInput());
}
} catch (MissingFlagInputException e) {
Cloud.say(
String.format(
"Please enter a description for the \"%s\" flag.",
e.getFlagText()
)
);
return null;
}

return new Todo(description);
}

private static @Nullable Integer verifyNumber(CommandManager manager) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function name does not suit with the return type. verifyNumber sounds like it would return a boolean.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean. This one is also more of a utility function. I'm a bit apprehensive about starting static methods with get since it sounds to me like an instance getter.

I named it so because part of its logic involves giving error feedback to the user, but at the end of the call, if the number is valid, then the callee needs to actually use said number (while also knowing whether or not it was valid), thus @Nullable Integer instead of just int.

I am open to better name suggestions.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Come to think of it, if the method were meant to return a boolean, I think it would be called something like isNumberValid(). That thought occurred to me when reading this part of the code quality guide:

image

if (manager.getTokenCount() <= 1) {
return null;
}

Token numberToken = manager.getToken(1);
if (!numberToken.isInt()) {
Cloud.say(
String.format(
"\"%s\" is not a valid number.",
numberToken.toString()
)
);
return null;
}

if (!numberToken.isValidNumber(Cloud.TODOS)) {
Cloud.say(
String.format(
"TODO #%d does not exist.",
numberToken.toInt()
)
);
return null;
}
Cloud7050 marked this conversation as resolved.
Show resolved Hide resolved

return numberToken.toInt();
}

private static void say(String text) {
System.out.println(text);
}

private static void inputMarker() {
System.out.print("\n>>> ");
}

/**
* The chatbot's main method.
*
* @param args Java arguments.
*/
public static void main(String[] args) {
Cloud.say("Cloud online.");
Cloud.inputMarker();

while (Cloud.SCANNER.hasNextLine()) {
String input = Cloud.SCANNER.nextLine();
Cloud.handle(input);

Cloud.inputMarker();
}
}
}
55 changes: 55 additions & 0 deletions src/com/cloud/chatbot/CommandType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.cloud.chatbot;



/**
* Represents all possible command types, including unknown commands.
*/
public enum CommandType {
ADD,
LIST,
MARK,
UNMARK,
DELETE,
EXIT,
UNKNOWN;

/**
* Returns the matching command type for the specified command.
*
* @param command The command.
*/
public static CommandType stringToCommandType(String command) {
switch (command) {
case "todo":
case "t":
case "deadline":
case "d":
case "event":
case "e":
case "add":
return CommandType.ADD;
case "list":
case "l":
return CommandType.LIST;
case "mark":
case "m":
return CommandType.MARK;
case "unmark":
case "un":
return CommandType.UNMARK;
case "delete":
case "del":
case "yeet":
return CommandType.DELETE;
case "bye":
case "exit":
case "quit":
case "q":
case "done":
return CommandType.EXIT;
default:
return CommandType.UNKNOWN;
}
}
}
9 changes: 9 additions & 0 deletions src/com/cloud/chatbot/annotations/Nullable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.cloud.chatbot.annotations;



/**
* Explicitly marks types as potentially being null, meaning appropriate null
* checking is in order.
*/
public @interface Nullable {}
23 changes: 23 additions & 0 deletions src/com/cloud/chatbot/exceptions/MissingFlagInputException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.cloud.chatbot.exceptions;

import com.cloud.chatbot.token.FlagManager;



/**
* Thrown when the user does not specify all required sub inputs for a flag.
*/
public class MissingFlagInputException extends MissingInputException {
private FlagManager manager;

public MissingFlagInputException(FlagManager _manager) {
this.manager = _manager;
}

/**
* Returns the text portion of the associated flag.
*/
public String getFlagText() {
return manager.getFlagText();
}
}
14 changes: 14 additions & 0 deletions src/com/cloud/chatbot/exceptions/MissingInputException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.cloud.chatbot.exceptions;



/**
* Thrown when the user does not specify all required inputs.
*/
public class MissingInputException extends Exception {
public MissingInputException() {}

public MissingInputException(String message) {
super(message);
}
}
34 changes: 34 additions & 0 deletions src/com/cloud/chatbot/todo/Deadline.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.cloud.chatbot.todo;



/**
* Represents a deadline TODO, which has an ending timestamp.
*/
public class Deadline extends Todo {
private String timestampEnd;

public Deadline(String _description, String end) {
super(_description);

this.timestampEnd = end;
}

@Override
public String toString(int number) {
return String.format(
"%s | BY %s",
this.getBasicString(number),
this.getEnd()
);
}

@Override
public String getTypeString() {
return "D";
}

public String getEnd() {
return this.timestampEnd;
}
}
Loading