Project: BoNUS

BoNUS is a desktop personal organizer application created for National University of Singapore (NUS) students, by NUS students. The application aims to better organize the lives of NUS students. This is accomplished through having a contacts list for students to keep up with their social lives and a planner for students to keep abreast of their upcoming events in school. BoNUS uses a Command Line Interface (CLI) where users input their commands to a console.

This project is the result of a semester-long Software Engineering module, CS2103T, in NUS. BoNUS is developed alongside my teammates based on Address Book (Level 4), an initiative from the SE-EDU team, the current codebase has expanded to around 10 kLoC. The backend of the application is done in Java. The frontend of the application is mostly done up with JavaFX.

Code contributed: [Functional code] [Test code]

Purpose

This Project Portfolio page aims to show the contributions made by Ng Jun Yang to Project BoNUS. This Project Portfolio provides an outline of the contributions which includes the enhancements added, enhancements proposed followed by other additional contributions towards Project BoNUS.

Adding an event : (aE)addE

You want to record your friend’s birthday party coming up.
Format: (aE)addE n/NAME dt/DATE_TIME a/EMAIL a/ADDRESS

This will add a new event to your list of events.

Examples:

  • addE n/Does Birthday dt/25122015 20:30 a/12 Kent Ridge Drive

  • addE n/Betsy Birthday dt/25122016 21:30 a/23 Marina Road

  • The standard format for time should be DDMMYYYY HH:MM in 24-hour format.

  • However, the application may sometimes be smart enough to interpret what you typed. For example, if you type this afternoon or tomorrow evening, it will be automatically converted to the standard format.

  • Do NOT try to challenge the application, it is not promised to produce an expected result if you use non-standard format or if the expression is not simple or clear enough.

  • Avoid putting the year first when using the non-standard format.

  • Reminders will automatically be added and start to notify you from 2 days before the actual event.

  • Reminders in the form of a bell image will be displayed on the event card itself.

  • Red Bell : Day of event
    Orange Bell: One day before event
    Green Bell: Two days before event


Justification

The support for auto reminders in BoNUS is pivotal. Taking into consideration the busy schedules of students, having an auto reminder function allows students to be more in line with their upcoming events.

As for the latest BoNUS v1.5 official release, reminders only come in the form of additional icons at the side of their events. We seek to further improve the auto reminders function to allow students to be notified of upcoming events in a better manner.

Auto reminders

We are adding a reminder to the event whenever an event is added. Reminders will notify users 2 days in advance before event itself.

As we are targeting NUS students, in view of the busy schedules of students, students should be able to set reminders for events that they have to attend to. In the case that students forget to set reminders themselves, we automatically preset a reminder that will trigger from 2 days before the event such that students have ample time to be aware and be prepared for the event itself.

Learning from many modern applications, the logic behind the applications are usually efficient and is able to handle multiple tasks at once. By automatically adding reminders alongside the addition of events, it makes it more convenient for the users themselves. We have set a default reminder to trigger 2 days before the actual event to remind users of their upcoming events via different colour schemes.

As shown in the Figure 4.4.1

  1. The red bell indicates the day of the event

  2. The orange bell indicates one day before event.

  3. The green bell indicates two days before event.

ReminderColorScheme

Figure 4.4.1 : Reminders via different colour schemes to indicate urgency

Design Consideration

Aspect: How to implement the idea of reminders into Events
Alternative 1 (current choice): Create a new reminder class that contains an event parameter to it. Events have a
list of reminders within them (Figure 4.4.1.1).
Pros: Independent. Reminder class is on its own and easy for future usage since it is already a class by itself.
Each reminder is tagged to an event, such that if we want to access the reminders in an event, it is easy to do so.
Cons: Require major changes to Logic and Model components for Event
Alternative 2: Add a new parameter for Event called Reminders to display time till event.
Pros: Less changes as it is just an implementation of a new parameter.
Cons: Less versatile and reminders cannot be applied anywhere else if needed.

ReminderClassDiagram

Figure 4.4.1.1 : Class Diagram for `Reminder`

Therefore we have decided to adopt alternative 1 of creating a Reminder class as it is more versatile for future usage.

Implementation Outline

  1. Create a ReadOnlyReminder class such that it only contains immutable instances of Reminders.

  2. Create a general class such that Reminder that implements ReadOnlyReminder. It can inherit properties such as DateTime from PropertyClass as well. In the event that a new property needs to be added, it can be done. Such a design makes Reminder class more adaptable to changes and ready for future code usage.

  3. Reminder is now more open to changes if needed and can easily add parameters and methods now that it is a class on its own.

  4. Have a list of reminders in Event class (Figure 4.4.2.1). Since Event can have multiple reminders, each reminder is instantiated with an Event parameter in it such that a Reminder is tagged to an Event itself. Figure 4.4.2.2 depicts the relationship between Event and Reminder.

EventClassDiagram

Figure 4.4.2.1 : Class Diagram for `Event`

EventReminderRS

Figure 4.4.2.2 : Relationship of Event and Reminder

The following sequence diagram (Figure 4.4.2.3) shows how reminders are automatically added upon the addition of events.

SDaddEventLogicReminder

Figure 4.4.2.3 : Sequence Diagram for Adding an event (reminders are automatically added)


Switching themes : (t)theme

Switches between Dark Theme and Bright Theme.
Format: (t)theme

Examples:

  • theme

Theme will be saved upon exit. When BoNUS is opened again, theme will be initialized to the theme that was saved previously.

As shown in Figure 5.15.1 and Figure 5.15.2, Figures depict the Bright Theme and Dark Theme respectively.

BrightTheme

Figure 5.15.1 : Bright Theme

DarkTheme

Figure 5.15.2 : Dark Theme


Justification

As the target audience for BoNUS are students, we aim to allow students to personalize their own BoNUS. Therefore, to kick start such an initiative, we decided to allow the switching of themes between Dark and Bright Themes. Also, this adds to the aesthetic aspect of our product, attracting more students to start using BoNUS.

To further develop on this aspect of personalisation, we seek to add more themes for students to personalize their own BoNUS in future releases.

Switch themes mechanism

As BoNUS is targeted at students, we want to allow students to personalise BoNUS. To open up such a possibility, we decided to introduce the SwitchThemeCommand to support bright and dark themes.

In the following sections below, the Switch Themes mechanism will be elaborated with the aid of illustrated diagrams to depict the interactions between the components in BoNUS.

The Sequence Diagram in Figure 4.5.1 illustrates how the components interact for the scenario where the user issues the command theme. Also, the Sequence Diagram illustrates the events-driven architectural style in BoNUS.

SDforSwitchTheme

Figure 4.5.1 : Events-Driven nature of Switch Theme

SDforSwitchThemesEmphasis

Figure 4.5.2 : Sequence diagram for Switch Theme mechanism

As can be seen from Figure 4.5.2, upon the execution of theme command, SwitchThemeEvent is then raised :

public class SwitchThemeCommand extends Command {

    public static final String COMMAND_WORD = "theme";
    public static final String COMMAND_ALIAS = "t";

    public static final String MESSAGE_USAGE = COMMAND_WORD + ": Toggles between bright and dark theme.\n"
            + "Example: " + COMMAND_WORD;

    public static final String MESSAGE_SUCCESS = "Theme switched!";

    @Override
    public CommandResult execute() {
        raise(new SwitchThemeEvent());
        return new CommandResult(MESSAGE_SUCCESS);
    }
}

It is from there that the event will be handled by MainWindow where the change of theme occurs as shown below:

 @Subscribe
    private void handleThemeChanged(SwitchThemeEvent event) {
        if (prefs.getAddressBookTheme() == darkTheme) {
            getRoot().getStylesheets().clear();
            getRoot().getStylesheets().add(brightTheme);
            getRoot().getStylesheets().add(brightExtension);
            prefs.setAddressBookTheme(brightTheme);
        } else {
            getRoot().getStylesheets().clear();
            getRoot().getStylesheets().add(darkTheme);
            getRoot().getStylesheets().add(darkExtension);
            prefs.setAddressBookTheme(darkTheme);
        }

    }

Design Consideration

Aspect: How to implement the theme command
Alternative 1 (current choice): Create a SwitchThemeCommand command under Logic component. Create an event for it to handle
the switching of themes in MainWindow. Implement the switch theme process in MainWindow. No parsing is involved since
it is switching between two themes.
Pros: Simple interaction between UI and Logic by raising an event to handle the changing of themes in MainWindow
from SwitchThemeCommand under the Logic component.
Cons: Without parsing, only two themes can be set.
Alternative 2: Handle theme switch by directly accessing MainWindow from SwitchThemeCommand
Pros: Shortcut to make the theme command work.
Cons: Logic and UI component should not be easily interchangeably accessed in this manner. Also, it violates Single Responsibility Principle (SRP). Logic is only supposed to handle logic components such as commands, it should not be able to openly access UI components such as MainWindow.

Implementation Outline

  1. Create a SwitchThemeCommand under logic component. Create a SwitchThemeEvent for EventBus to handle the event accordingly whenever SwitchThemeCommand is executed.

  2. Create a CSS file for BrightTheme which include its main CSS file as well as its extension files. Remove the default CSS styles from the FXML files in BoNUS.

  3. Implement the switching of themes in MainWindow. Create a method in MainWindow to subscribe it to the event change. Raise the event whenever SwitchThemeCommand is executed such that the theme will change accordingly in MainWindow.


Booking of NUS facilities: (book)bookNUS

(Exclusive feature for NUS students)
(Coming in v2.0)

The BoNUS team understands that booking of facilities in NUS may be troublesome. Therefore, we have decided to integrate the facility booking website with BoNUS such that upon successful booking of a specific facility, your Events List will be updated accordingly with the Date, Time and Venue of booking.

Format: (book)bookNUS

  • Upon execution the command, you will be brought the the NUS facility booking website on a separate browser.

  • Upon successful booking of the facility, Event with date, time and venue will automatically be added as events to the application.

Example:

  • bookNUS

  • Make sure you have stable Internet connection when using this command.

  • There may be some waiting time involved due to the retrieval of information from the website to update BoNUS.


Justification

Since NUSMods is already being integrated with BoNUS, what is another factor that NUS students are largely concerned with in terms of school resources? The idea of integrating the booking of facilities in NUS with BoNUS then came about.

BoNUS is an organizer for NUS students. In view of the busy schedules of students in school, BoNUS not only aims to make lives for students more convenient, but also allow students to be updated of their personal upcoming events. As such, we took into consideration the booking of facilities for consultation, group meetings or even study groups. To facilitate this , we decided to integrate the booking of facilities with the Event component from BoNUS such that upon successful booking of facilities, the Event list in BoNUS would automatically be updated with your latest booking.

Enhancement proposed: Importing of contacts / events from Google

From Google Accounts

(Coming in v2.0)

Imports your contacts and events from Google Contacts and Google Calender respectively.
Format: (i)import --google https://myaccount.google.com/

  • Upon execution of the command, you will be brought to Google’s login page for authentication.

  • Upon successful authentication, data from Google contacts and calendar will automatically be imported into BoNUS's contact list and event list.

Example: import --google https://myaccount.google.com/

  • URL as shown in example is the default URL that will be opened for you

  • You would have to enter your login credentials on Google’s sign in page before data from Google Contacts and Google Calendar gets imported.

  • In the case of you not entering proper login credentials after three tries, BoNUS will cancel the request for importing from Google.


Justification

Since majority of students often use Google for multiple purposes, GMail, Google Docs or even Google slides. It is no wonder that most students have Google Accounts and have important information stored within.

Therefore, to facilitate your transition to BoNUS, we have decided to include the import of contacts / events from Google itself, making the transition to BoNUS a comfortable one. Furthermore, as Google acts as a back up for Contact Storage, with BoNUS, it can act as a secondary storage/backup for each of your contacts and events stored in calendar.

With facilitated transition towards BoNUS, your life can now be better organized with BoNUS.

Other contributions

  • Introduced Events component in BoNUS (Pull request #55, #73, #76)

  • Modified small parts of the UI (Pull request #90, #68)

  • Wrote JUnit tests in various classes (Pull request #140, #55, #182, #206, #207)

  • Assisted Project UNIBOOK in bug reporting (Issues #73)

  • Assisted Project BlueBird in bug reporting (Issues #268)