Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
# Conflicts:
#	docs/UserGuide.adoc
  • Loading branch information
ericyjw committed Nov 11, 2018
2 parents f77a92c + 8749c1e commit babfaed
Show file tree
Hide file tree
Showing 25 changed files with 468 additions and 41 deletions.
10 changes: 5 additions & 5 deletions docs/DeveloperGuide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ By: `Team W16-1`      Since: `Aug 2018`      Licence: `MIT`

== Introduction

Hallper is a desktop application aimed at serving <<jcrc,JCRCs>> of the Halls of NUS.
Hallper follows an event-driven architecture, and is designed to work on any <<mainstream-os,mainstream OS>>.
Hallper is a desktop application aimed at serving the Junior Common Room Committees (<<jcrc,JCRCs>>) of the Halls of NUS.
Hallper follows an event-driven architecture, and is designed to work on any <<mainstream-os,mainstream operating system (OS)>>.
This guide provides you with information on how to contribute to Hallper, whether you are a new or experienced developer.

== Setting up
Expand Down Expand Up @@ -351,7 +351,7 @@ image::UndoRedoActivityDiagram.png[width="650"]
=== Compose email feature
==== Current Implementation

The Compose feature works using a third-party dependency, http://www.simplejavamail.org/#/about[Simple Java Mail].
The Compose email feature works using a third-party dependency, http://www.simplejavamail.org/#/about[Simple Java Mail].
It allows `.eml` files to be saved onto the computer.
The feature is facilitated by `EmailModel` and `EmailDirStorage`.
It implements the following operations:
Expand Down Expand Up @@ -394,9 +394,9 @@ The library is easy to understand so any new developer can easily extend the cur
** Cons: Users unfamiliar with HTML minimally has to learn how the `<br>` tag works.
* **Alternative 2:** Plain text
** Pros: Plain text is easily understood by almost any user.
** Cons: The design of the email content is limited.
** Cons: The design of the email content is very limited.

//end::compose[]
// end::compose[]

// tag::calendar[]
=== Calendar feature
Expand Down
72 changes: 51 additions & 21 deletions docs/UserGuide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -327,47 +327,73 @@ Selects the 2nd person in Hallper.
`select 1` +
Selects the 1st person in the results of the `find` command.


// tag::email[]
=== Email
This section lists features related to email in Hallper.

==== Composing an email to currently listed people: `compose_email_list`
Composes a *`.eml`* file that can be used to send emails to currently listed residents. +
Format: `compose_email_list from/FROM subject/SUBJECT content/CONTENT`
==== Composing an email to selected indexes: `compose_email_index`
Composes a *`.eml`* file that can be used to send emails to residents specified by index. +
Format: `compose_email_index from/FROM to/INDEXES subject/SUBJECT content/CONTENT`

****
* FROM must be a valid email address e.g. johndoe@example.com
* FROM must be a valid email address. E.g. johndoe@example.com
* INDEXES refer to the index numbers shown in the displayed resident list.
* INDEXES *must be positive integers* 1, 2, 3, ...
* SUBJECT has no word limit.
* CONTENT has no word limit.
* `<br>` can be used in CONTENT for new line.
****

[TIP]
====
CONTENT is written in HTML. Users who know HTML can use it to format the CONTENT.
====

Example:

* `compose_email_list from/johndoe@example.com subject/Meeting this Friday
content/Hey there's a meeting this friday.` +
Composes an email from `johndoe@example.com` to currently listed people with subject
`Meeting this Friday` and email body `Hey there's a meeting this friday.` and saves
it as a *`.eml`* file.
* `list`
+
.Result after executing `list`
image::list.png[width="790"]
{empty} +
`compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday
content/Dear All<br><br>There's a meeting this friday.<br><br>John Doe` +
Composes an email from `johndoe@example.com` to residents at indexes 1, 3, and 5 with subject
`Meeting this Friday` and email body `Dear All<br><br>There's a meeting this friday.<br><br>John Doe` and saves it as a *`.eml`* file.
+
.Result after executing `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Dear All<br><br>There's a meeting this friday.<br><br>John Doe`
image::compose_email_index.png[width="790"]

==== Composing an email to selected indexes: `compose_email_index`
Composes a *`.eml`* file that can be used to send emails to residents specified by index. +
Format: `compose_email_index from/FROM to/INDEXES subject/SUBJECT content/CONTENT`
==== Composing an email to currently listed residents: `compose_email_list`
Composes a *`.eml`* file that can be used to send emails to currently listed residents. +
Format: `compose_email_list from/FROM subject/SUBJECT content/CONTENT`

****
* FROM must be a valid email address e.g. johndoe@example.com
* INDEXES refer to the index numbers shown in the displayed person list.
* INDEXES *must be positive integers* 1, 2, 3, ...
* FROM must be a valid email address. E.g. johndoe@example.com
* SUBJECT has no word limit.
* CONTENT has no word limit.
* `<br>` can be used in CONTENT for new line.
****

[TIP]
====
CONTENT is written in HTML. Users who know HTML can use it to format the CONTENT.
====

Example:

* `compose_email_index from/johndoe@example.com to/1 6 10 subject/Meeting this Friday
content/Hey there's a meeting this friday.` +
Composes an email from `johndoe@example.com` to people at indexes 1, 6 and 10 with subject
`Meeting this Friday` and email body `Hey there's a meeting this friday.` and saves
* `list`
+
.Result after executing `list`
image::list.png[width="790"]
{empty} +
`compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Dear All<br><br>There's a meeting this friday.<br><br>John Doe` +
Composes an email from `johndoe@example.com` to currently listed residents with subject
`Meeting this Friday` and email body `Dear All<br><br>There's a meeting this friday.<br><br>John Doe` and saves
it as a *`.eml`* file.
+
.Result after executing `compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Dear All<br><br>There's a meeting this friday.<br><br>John Doe`
image::compose_email_list.png[width="790"]

==== Deleting an email : `delete_email`

Expand Down Expand Up @@ -401,6 +427,10 @@ Examples:

* `view_email Meeting on Friday` +
Displays the email with the subject `Meeting on Friday`.
+
.Result after executing `view_email Meeting on Friday`
image::view_email.png[width="790"]
// end::email[]

=== Calendar
This section lists features related to managing the calendar in Hallper.
Expand Down Expand Up @@ -790,7 +820,7 @@ e.g. `select 1`

===== Email
* *Compose Email (Index)* : `compose_email_index from/FROM to/INDEXES subject/SUBJECT content/CONTENT` +
e.g. `compose_email_index from/johndoe@example.com to/1 6 10 subject/Meeting this Friday content/Hey there's a meeting this friday.`
e.g. `compose_email_index from/johndoe@example.com to/1 3 5 subject/Meeting this Friday content/Hey there's a meeting this friday.`
* *Compose Email (List)* : `compose_email_list from/FROM subject/SUBJECT content/CONTENT` +
e.g. `compose_email_list from/johndoe@example.com subject/Meeting this Friday content/Hey there's a meeting this friday.`
* *List Emails* : `list_emails`
Expand Down
Binary file added docs/images/compose_email_index.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/compose_email_list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/view_email.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class ComposeEmailIndexCommand extends Command {
+ PREFIX_CONTENT + "CONTENT(Input <br> for newline)\n"
+ "Example: " + COMMAND_WORD + " "
+ PREFIX_FROM + "johndoe@example.com "
+ PREFIX_TO + "1 6 10 "
+ PREFIX_TO + "1 3 5 "
+ PREFIX_SUBJECT + "Meeting this Friday "
+ PREFIX_CONTENT + "Dear All<br><br>Remember our meeting this friday.<br><br>John";

Expand Down
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ public static Tag parseTag(String tag) throws ParseException {
return new Tag(trimmedTag);
}

//@@author EatOrBeEaten
/**
* Parses {@code Collection<String> tags} into a {@code Set<Tag>}.
*/
Expand Down
22 changes: 20 additions & 2 deletions src/main/java/seedu/address/model/EmailModel.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package seedu.address.model;

import static java.util.Objects.requireNonNull;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
Expand All @@ -24,7 +27,8 @@ public EmailModel() {
}

public EmailModel(Set<String> emailNamesSet) {
existingEmails = new HashSet<>();
this();
requireNonNull(emailNamesSet);
existingEmails.addAll(emailNamesSet);
}

Expand All @@ -33,6 +37,7 @@ public EmailModel(Set<String> emailNamesSet) {
* @param email The email to be saved.
*/
public void saveEmail(Email email) {
requireNonNull(email);
this.email = email;
savePreview();
}
Expand All @@ -58,12 +63,14 @@ private void savePreview() {
* @param email the newly composed email.
*/
public void saveComposedEmail(Email email) {
requireNonNull(email);
assert !hasEmail(email.getSubject());
saveEmail(email);
addToExistingEmails(email.getSubject());
}

public Set<String> getExistingEmails() {
return existingEmails;
return Collections.unmodifiableSet(existingEmails);
}

public Email getEmail() {
Expand All @@ -74,7 +81,11 @@ public String getPreview() {
return preview;
}

/**
* Returns true if an email with the same subject as {@code fileName} exists in the EmailModel.
*/
public boolean hasEmail(String fileName) {
requireNonNull(fileName);
return existingEmails.contains(fileName + emlExtension);
}

Expand All @@ -86,4 +97,11 @@ public void removeFromExistingEmails(String fileName) {
existingEmails.remove(fileName + emlExtension);
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof EmailModel
&& existingEmails.equals(((EmailModel) other).existingEmails));
}

}
7 changes: 6 additions & 1 deletion src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,15 @@ public interface Model {
void saveEmail(Email email);

/**
* Saves a newly composed email to the EmailModel.
* Saves a newly composed email to the EmailModel, and display it on BrowserPanel.
*/
void saveComposedEmail(Email email);

/**
* Saves a newly composed email to the EmailModel.
*/
void saveComposedEmailWithoutDisplay(Email email);

/**
* Deletes an existing email from EmailModel.
*/
Expand Down
28 changes: 24 additions & 4 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -547,18 +547,22 @@ public boolean equals(Object obj) {
// state check
ModelManager other = (ModelManager) obj;
if (filteredPersons == null) {
return versionedAddressBook.equals(other.versionedAddressBook);
return versionedAddressBook.equals(other.versionedAddressBook)
&& calendarModel.equals(other.calendarModel)
&& emailModel.equals(other.emailModel);
} else if (calendarModel == null) {
return versionedAddressBook.equals(other.versionedAddressBook)
&& filteredPersons.equals(other.filteredPersons);
&& filteredPersons.equals(other.filteredPersons)
&& emailModel.equals(other.emailModel);
}
return versionedAddressBook.equals(other.versionedAddressBook)
&& filteredPersons.equals(other.filteredPersons)
&& calendarModel.equals(other.calendarModel);
&& calendarModel.equals(other.calendarModel)
&& emailModel.equals(other.emailModel);
}

//@@author EatOrBeEaten
//=========== Compose email =================================================================================
//=========== Email =================================================================================

@Override
public void saveEmail(Email email) {
Expand All @@ -572,6 +576,12 @@ public void saveComposedEmail(Email email) {
indicateEmailSaved();
}

@Override
public void saveComposedEmailWithoutDisplay(Email email) {
emailModel.saveComposedEmail(email);
indicateEmailSavedWithoutDisplay();
}

@Override
public void deleteEmail(String fileName) {
emailModel.removeFromExistingEmails(fileName);
Expand All @@ -580,14 +590,24 @@ public void deleteEmail(String fileName) {

@Override
public boolean hasEmail(String fileName) {
requireNonNull(fileName);
return emailModel.hasEmail(fileName);
}

/**
* Raises an event to indicate that a new email has been saved to EmailModel.
*/
private void indicateEmailSavedWithoutDisplay() {
raise(new EmailSavedEvent(emailModel));
}

/**
* Raises an event to indicate that a new email has been saved to EmailModel, and displays it on the BrowserPanel.
*/
private void indicateEmailSaved() {
raise(new EmailSavedEvent(emailModel));
raise(new ToggleBrowserPlaceholderEvent(ToggleBrowserPlaceholderEvent.BROWSER_PANEL));
raise(new EmailViewEvent(emailModel));
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/model/email/Content.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public class Content {

public static final String MESSAGE_CONTENT_CONSTRAINTS =
"Subject can take any values, and it should not be blank";
"Content can take any values, and it should not be blank";

/*
* The first character of the content must not be a whitespace,
Expand Down
3 changes: 0 additions & 3 deletions src/main/java/seedu/address/storage/StorageManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import seedu.address.commons.events.storage.RemoveExistingCalendarInModelEvent;
import seedu.address.commons.events.ui.CalendarNotFoundEvent;
import seedu.address.commons.events.ui.EmailNotFoundEvent;
import seedu.address.commons.events.ui.EmailViewEvent;
import seedu.address.commons.events.ui.ToggleBrowserPlaceholderEvent;
import seedu.address.commons.exceptions.DataConversionException;
import seedu.address.commons.util.StringUtil;
Expand Down Expand Up @@ -235,8 +234,6 @@ public void handleEmailSavedEvent(EmailSavedEvent event) {
logger.info(LogsCenter.getEventHandlingLogMessage(event, "Email composed, saving to directory."));
try {
saveEmail(event.data);
raise(new ToggleBrowserPlaceholderEvent(ToggleBrowserPlaceholderEvent.BROWSER_PANEL));
raise(new EmailViewEvent(event.data));
} catch (IOException e) {
raise(new DataSavingExceptionEvent(e));
}
Expand Down
6 changes: 6 additions & 0 deletions src/test/java/seedu/address/TestApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import java.util.Set;
import java.util.function.Supplier;

import org.simplejavamail.email.Email;

import javafx.stage.Screen;
import javafx.stage.Stage;
import seedu.address.commons.core.Config;
Expand Down Expand Up @@ -147,4 +149,8 @@ private <T> void createDataFileWithData(T data, Path filePath) {
throw new RuntimeException(e);
}
}

public void saveComposedEmailWithoutDisplay(Email email) {
model.saveComposedEmailWithoutDisplay(email);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import static seedu.address.logic.commands.CommandTestUtil.assertCommandSuccess;
import static seedu.address.testutil.TypicalPersons.getTypicalAddressBook;

import java.util.HashSet;

import org.junit.Before;
import org.junit.Test;

Expand Down Expand Up @@ -35,7 +33,7 @@ public void execute_newPerson_success() {
Person validPerson = new PersonBuilder().build();

Model expectedModel = new ModelManager(model.getAddressBook(), new BudgetBook(), new UserPrefs(),
new HashSet<>());
model.getExistingEmails());
expectedModel.addPerson(validPerson);
expectedModel.commitAddressBook();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,11 @@ public void saveComposedEmail(Email email) {
throw new AssertionError("This method should not be called.");
}

@Override
public void saveComposedEmailWithoutDisplay(Email email) {
throw new AssertionError("This method should not be called.");
}

@Override
public void deleteEmail(String fileName) {
throw new AssertionError("This method should not be called.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ public void saveComposedEmail(Email email) {
throw new AssertionError("This method should not be called.");
}

@Override
public void saveComposedEmailWithoutDisplay(Email email) {
throw new AssertionError("This method should not be called.");
}

@Override
public void deleteEmail(String fileName) {
throw new AssertionError("This method should not be called.");
Expand Down
Loading

0 comments on commit babfaed

Please sign in to comment.