Overview
My team of 5 Computer Science students, including myself, aimed to build a product centered on making students who procrastinate more productive. This manifested itself into BBProductive. It is a gamified task manager that utilizes the Pomodoro productivity technique. The gamefied aspect comes into play in the form of a pet that gets hangry(hungry and angry) when tasks are not completed. The pomodoro technique consists of 25 minutes focused work and 5 minutes rest. These 2 aspects of the application as well as the task manager come together as a comprehensive solution for procrastinators to be productive.
Summary of contributions
-
Major enhancement: I added the ability to have reminders for the tasks.
-
What it does: The “r/” flag allows the user to set the date and time inputted to be the time they are reminded. Once the time has arrived, a pop up with the task’s name and description appears, alerting and reminding the user to do the task.
-
Justification: In the event users have a time sensitive task or wants to come back to the task at a later date, the “r/” flag can be added in the AddCommand or EditCommand to remind the user of the task.
-
Highlights: This enhancement works with the AddCommand or EditCommand and is optional. This implementation was challenging due to the nature of when the user closes the application. The duration until the stipulated time has to be recalculated on boot and thus the decision to trigger the reminder has to be made. Also when a task is marked as done, the reminder should not be triggered.
-
-
Major enhancement: I added the ability to have recurring tasks.
-
What it does: The “rec/” flag allows the user to make the task reappear on a daily or weekly basis.
-
Justification: In the event users have a repeatable task that occurs on a weekly basis, he can set the task as either daily or weekly recurring to ensure the task is set as undone after the stipulated time interval. (daily or weekly)
-
Highlights: This enhancement works with the AddCommand or EditCommand and is optional as well. This implementation was challenging due to how it requires to be deeply intertwined in the application’s MainWindow and model manager in order to display the fact that recurring behaviour has happened on the result display. This resulted in me applying the observer design pattern to facilitate further communication between the MainWindow and model manager.
-
-
My code contributions on RepoSense: [RepoSense]
-
Other contributions:
-
Project management:
-
Managed milestones
v1.1
-v1.4rc
(3 milestones) on GitHub
-
-
Enhancements to existing features:
-
Implemented the foundation of the new stylesheet used for the application
-
Adjusted the JavaFX layout to fit the Adobe XD mockup
-
Wrote tests for both reminders and recurring tasks
-
-
Design:
-
I was primarily responsible for the design and UI/UX of the application for BBProductive
-
This includes coming up with wireframes for BBProductive. (Link: wireframe)
-
As well as a proper interactive mockup the team has been using for reference when building the application itself. (Link: mockup)
-
I also was responsible for any additional design collateral for the group, this means the BBProductive logo, user guide cover page, as well as minor styling of the user guide.
-
-
Documentation:
-
Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
Quick Start (Arthur)
Follow the steps below to install and launch BB Productive:
-
Ensure you have Java
11
or above installed in your Computer. -
Download the latest
bb_productive.jar
here. -
Copy the file to the folder you want to use as the home folder for your BB Productive.
-
Double-click the file to start the app. The GUI should appear in a few seconds.
-
Type the command in the Pet Chat (Command box) and press Enter to execute it.
e.g. typinghelp
and pressing Enter will open the help window. -
Some example commands you can try:
-
add
n/Do math homework des/pages 1-2 r/11/11/21@23:59
: adds a task of the nameDo math homework
to the Task List with a date and time that follows the r/ prefix and apages 1-2
description. -
delete
3
: deletes the 3rd task shown in the list -
exit
: exits the app
-
-
Refer to Section 6 Features for details of each command.
Reminders (Arthur)
What’s a reminder?
BBProductive provides you with the option to remind you during those forgetful times. BBProductive can help to remind you to do time-sensitive tasks such as taking temperature in the afternoon. When the time for the reminder has arrived, BBProductive alerts you to do the task! Never forget to buy milk or any other time-sensitive task ever again!
How do you use it?
You can add a reminder to your task by adding r/DD/MM/YY@HH:mm
when editing or adding a task. A pop up containing the task name and description will then appear reminding you to complete the task at the specified date and time.
Command r/DD/MM/YY@HH:MM
Add Task with reminder
Add a task with a reminder using the following command add n/<name> r/DD/MM/YY@HH:mm
. You can also include the other flags such as t/
, des/
and more.
For example: add n/Buy Milk r/11/11/20@23:59
.
After you have successfully added the task, you will see the following success message in the dialogue box!
|
Edit Task with reminder
Edit a task to include a reminder with the following command edit <index> r/DD/MM/YY@HH:MM
. You can also include the other flags such as t/
, des/
and more.
For example: edit 1 r/01/11/20@11:59
.
This results in a task with the reminder’s date in the task card as well as result display giving feedback.
Recurring (Arthur)
What’s Recurring?
Have a task you need to complete every day or every week? BBProductive has you covered with recurring tasks! Add a recurring task and the task will be marked as unfinished every day or every week? This means not having to add the same task over and over again! Furthermore, you can accompany these recurring tasks with reminders. Now you don’t have to worry about forgetting to do your daily or weekly tasks!
How do you use it?
Add a recurring attribute to your task by adding rec/d
for daily recurring tasks or rec/w
for weekly. This will trigger the recurring behaviour for the task, meaning tasks will be reset according to the delay you set! This means after marking a task as done, the next day (or week) it will be marked as unfinished. For reminders, BBProductive will also add a day(or week) to the reminder date! This ensures you are reminded on a recurring basis!
Add Task with recurring
Add a task with a recurring attribute using the following command add n/<name> rec/d
or add n/<name> rec/w
. You can also include the other flags such as t/
, des/
and more.
For example: add n/Buy Milk rec/d
After you have successfully added the task, you will see the following success message in the dialogue box!
You will see the task appear in the tasklist with a recurring attribute at the side!
The format for recurring is strictly |
Edit Task with recurring
Want to make an existing task recurring? You can edit a task to include a recurring with the following command edit <index> rec/d
or edit <index> rec/w
. You can also include the other flags such as t/
, des/
and more.
For example: edit 1 rec/w
.
Once completed, you will see that the task details will be updated with a recurring attribute.
Recurring behaviour when a task is marked as done (Arthur)
Mark a task as done as you would normally using the command done <index>
. For a recurring task, after the stipulated amount of time(either daily or weekly), the task will be reset as unfinished.
For example: done 1
on a daily recurring task.
After one day, the task will be set from done to unfinished, meaning the tick in the checkbox will disappear.
Recurring behaviour when the task has a reminder (Arthur)
Add a reminder as you would normally using the command edit <index> r/DD/MM/YY@HH:mm
or add n/<name> r/DD/MM/YY@HH:mm rec/<type>
if you are adding the task. For a recurring task, after the stipulated amount of time(either daily or weekly), the reminder will be incremented by the time interval if it has been triggered. This means that the reminder will be incremented by 1 day if the time interval is daily, and 7 days if the time interval is weekly.
After one day, you will see that the reminder time is updated!
I also contributed content to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
Edit
The edit feature allows the user to edit the task, adding or updating fields in a task accordingly.
Implementation
The edit command is done in 2 parts. EditCommandParser
as well as EditCommand
itself.
EditCommandParser
parses the user input including the index
and the relevant prefixes that will be edited. This is done by checking the prefixes for each of the different task fields and calling the relevant parser for it. The parser then returns the relevant field, be it name
, priority
, reminder
etc and this is set in the EditTaskDescriptor
instance. This EditTaskDescriptor
instance is a container for the updated fields. This instance is passed in the constructor of a new EditCommand
.
EditCommand
is executed. During execution, an edited task is created from retrieving the stored updated fields data from EditTaskDescriptor
and copying the field from the original task to edit for the unchanged fields. This updated task is set in the Model
for storage. Subsequently, a new CommandResult
is generated to display that the task has been edited in the result display to the user. The general flow of EditCommand
and EditCommandParser
can be seen in the sequence diagram below.
Reminders
The user’s reminder functionality is achieved by calculating the time delay from the current time and the time from the user input. This time delay as well as the Task name and description is passed to the MainWindow for the reminder to be triggered as a pop up at the right time.
Implementation
A DateTimeFormatter
is used to parse the date time from the user input, which is just the date in the r/ flag when adding or editing a task, into a LocalDateTime
object. This LocalDateTime
is used to store the date and time information. When the reminder is instantiated, a setDelay
method is called setting in motion the calculation of time delay between the current time and the reminder time, and triggering of reminder on the MainWindow
. The reminder class is stored as an Optional
in the Task class itself.
Reminder is stored as a string in the JsonAdaptedTask
. This string contains the exact format of the date and time that the user inputs, this allows the same constructor to be used when the data is read and changed to a task and thus reminder object. A sequence diagram of the reminder flow is shown below for reference.
Recurring
The user’s recurring tasks functionality is twofold. Resetting the task to be unfinished after the stipulated time interval and resetting the task’s reminder date according to the stipulated time interval. The behaviour for this recurring feature is mainly represented in the activity diagram below.
Implementation
The logic is mainly implemented in the Recurring
class and ModelManager
class in seedu.address.model
, which interacts with the app’s storage system especially with respect to task storage. This Recurring
instance is stored in Task
as an optional field.
In the Recurring
class, whenever a task is added or edited, the recurring type is then parsed to be either daily or weekly. Afterward, based on the time the recurring attribute is added, a reference LocalDateTime is noted in the Recurring
instance itself. This ensures that the first recurring behaviour will trigger in the given interval with respect to that referenceDateTime and following the same interval afterwards.
The recurring behaviour is orchestrated in ModelManager
whenever a task is added or edited, a setTask
method is called that will generate a Timer
and TimerTask
. A TimerTask
is the logic run to update the task, namely resetting the done and the reminder accordingly. The Timer
schedules TimerTasks
at a fixed rate based on the the time interval chosen, if it is daily it will be every 24 hours (but for testing purposes it will be every 60 seconds) and if it is weekly it will be every 7 days. There is only 1 Timer
for the ModelManager
that handles the scheduling of each TimerTask
that corresponds to every task that has a recurring behaviour. On boot the Timer
is canceled and replaced with a new instance, subsequently all the tasks are iterated through. Every task with a recurring attribute will have a TimerTask
generated and scheduled accordingly.
The recurring behaviour triggered will set the task as undone. If a reminder exists and has been triggered, it will increment the reminder to be the next day or week depending on the interval set. When the recurring behaviour is triggered, the result display will show a message that the recurring task has been reset.
Additionally, a flag has been made to check if the task needs to be changed, if it does not it will not be unnecessarily updated in the Model
. A class diagram of the tasks and all its attributes is shown below.
Recurring is stored as a string in the JsonAdaptedTask
. This string contains the LocalDateTime information for the reference date as well as the type of interval itself. A special constructor for this string is used to reconstruct the recurring attribute when reading from storage.
Appendix A: User Stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
|
new user |
see usage instructions |
refer to instructions when I forget how to use the App |
|
user |
view all current ongoing tasks |
manage my tasks and time |
|
user |
able to edit my task description |
make changes in the event something unexpected happens |
|
user |
add a task by specifying a task description only |
record tasks that needs to be done. |
|
user |
add a task by specifying a task description and a reminder |
record tasks that needs to be done by a specific period |
|
user |
add a task that is recurring |
record tasks that are either recurring daily or weekly without having to input it every day or week |
|
user |
sort upcoming tasks by date |
filter out the latest/oldest tasks according to my needs |
|
user |
sort my tasks by priority |
manage my tasks |
|
user |
delete a task |
remove tasks that I no longer care to track |
|
user |
utilise the Pomodoro technique to break down my work into structured intervals |
boost productivity and keep track of time |
|
user |
be able to remind myself on when I plan to work on a task |
be on track to complete my tasks |
|
user |
get a visual cue from my pet to prompt me to do work |
be motivated to work when my productivity is low |
|
user |
keep track of the time spent on each task |
check my progress |
|
pro user |
navigate commands using shortcuts |
save more time |
|
pro user |
customise the rate at which I should do work in the Pomodoro |
fit my workstyle better |
|
pro user |
be able to remind myself on a recurring basis for repetitive tasks |
be on track to complete my tasks, including those that are repetitive and also done on a recurring basis |
|
user |
view the total number of tasks/duration spent on tasks I have done over a period of time |
track my productivity over different periods |
|
user |
view the durations in which I have currently spent on different tasks |
better allocate my time |
|
user |
see my pet grow because of my productivity |
am more motivated to stay productive |
|
user |
be greeted by a cute mascot |
feel happy and motivated to do work |
Appendix B: Instructions for Manual Testing
Given below are instructions to test the app manually.
These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. |
Launch and Shutdown
-
Initial launch
-
Download the jar file and copy into an empty folder
-
In the home folder for BBproductive, launch the jar file by double clicking on the jar file itself.
Expected: Shows the GUI with a set of sample items. The window size may not be optimum.
-
-
Saving user preferences
-
Add or edit tasks accordingly
-
Re-launch the app by double clicking the jar file.
Expected: The same GUI list of tasks appears.
-
{ more test cases … }
Viewing Relevant Screens on command
-
On launch
-
Upon double clicking the JAR file, a GUI with the tasks list on the right panel appears.
-
-
On typing stats
-
Type stats in the input command box if you are in either the tasks or settings panel.
-
Expected: The right panel shows a GUI with multiple graphs.
-
-
-
On typing settings
-
Type settings in the input command box if you are in either the tasks or statistics panel.
-
Expected: The right panel shows a GUI with multiple fields for the settings.
-
-
-
On typing tasks
-
Type tasks in the input command box if you are in either the settings or statistics panel.
-
Expected: The right panel shows a GUI with the task list.
-
-
Adding a task
-
Adding from a screen with 0 tasks
-
First run
clear
to clear all tasks if there are still tasks on the screen. -
Add a task by running the command
add n/test1
Expected: A task card appears in the tasklist with the name test1.
-
-
Adding from a screen with 1 task
-
Add another task by running the command
add n/test2
Expected: A task card appears in the tasklist with the name test2.
-
Editing a task
+ Prerequisite : Run clear
and add a task using the command add n/editTest
-
Editing a task’s name
-
Run the command
edit 1 n/editedTest
.
Expected: The command will result in the first task card’s name to change from editTest to editedTest.
-
-
Editing a task’s description
-
Run the command
edit 1 des/testDescription
.
Expected: The command will result in the testDescription being the description of the task card.
-
-
Editing a task’s priority
-
Run the command
edit 1 p/2
.
Expected: The command will result in the priority to change from low to medium on the task card.
-
-
Editing a task’s tags
-
Run the command
edit 1 t/test
.
Expected: The command will result in the test tag to appear below the task name on the task card.
-
Adding and triggering a reminder for the task
-
Adding a task with a reminder.
Prerequisite: Take note of the current time plus 1 minute and date in the formatDD/MM/YY@HH:mm
, for example if the current time is15/03/20@15:47
then you should get the command ready15/03/20@15:48
(but use the current date and time instead)-
Run the command
add n/reminderTest des/test r/DD/MM/YY@HH:mm
Expected: When the time has arrived a a pop up with a titlereminderTest
and descriptiontest
appears.
-
-
Editing a task to have a reminder.
Prerequisite: Take note of the current time plus 1 minute and date in the formatDD/MM/YY@HH:mm
, for example if the current time is15/03/20@15:47
then you should get the command ready15/03/20@15:48
(but use the current date and time instead)-
Add a task
add n/editReminderTest des/test
first and see it added on the tasklist panel -
Take note of the index of that task
-
Edit the task with
edit <index> r/DD/MM/YY@HH:mm
Expected: The task displays the reminder date in the task card. When the time comes, a pop up with a titleeditReminderTest
and descriptiontest
appears.
-
Adding a recurring attribute to a task
-
Adding a task with a recurring attribute.
-
Run the command add n/recurTest rec/t
-
Take note of the index of that task.
-
Run the done command done <index>
Expected: For testing purposes, the time delay is set to 60 seconds and it mimics a weekly recurring task. After 60 seconds, the done is set back to unfinished, with the tick being removed from the task card.
-
-
Editing a task to have a recurring attribute.
-
Add a task add n/editRecurringTest first and see it added on the tasklist panel
-
Take note of the index of that task
-
Edit the task with edit <index> rec/t
-
Run the done command done <index>
Expected: The task is marked as done at first. After 60 seconds, the done is set back to unfinished, with the tick being removed from the task card.
-
-
Adding a task with a reminder and recurring attribute.
Prerequisite: Take note of the current time plus 1 minute and date in the format DD/MM/YY@HH:mm, for example if the current time is 15/03/20@15:47 then you should get the command ready 15/03/20@15:48 (but use the current date and time instead)-
Run the command add n/recurReminderTest r/DD/MM/YY@HH:mm rec/t
-
Take note of the index of that task.
-
Run the done command done <index>
Expected: After 60 seconds, the done is set back to unfinished, with the tick being removed from the task card. After the reminder appears, the date displayed changes to the next week as it mimics a weekly recurring task albeit with a 60 second time delay, for example 15 March at 15:48 changes to 22 March at 15:48.
-
Sorting the task list
-
Add a bunch of tasks with different priorities, reminder dates and done values
-
Next perform sorts of various permutations of {(r-)priority, (r-)name, (r-)done, (r-)date} with spaces in between
-
sort fields that appear first are of higher priority than those that appear less
-
Expect the sort order of the tasklist to change, please reference our user guide for the specific changes to the tasklist if unsure
-
also expect the UI to change to display the most recent sort order
-
e.g. sort name priority → UI shows Tasks by name
-
Note that sort order is not maintained after application closes
-
-
Finding a task
-
Add a bunch of tasks with names with phrases that overlap and tags as well
-
Next you can perform one of the three permutations
-
find phrase
-
find phrase [t/TAG]…
-
find t/TAG [t/TAG]…
-
-
Expected order of search results: [those mentioned first should appear first]
-
tasks that have multiple tag matches
-
tasks that have full name match and tag match
-
tasks that have full name match or 2 tag matches
-
tasks that match a tag or phrase is partially matched
-
-
tasks that don’t meet any of the above won’t be shown
Auto complete
-
UI changes
-
Any known command words will have command text field set to green
-
Any unknown command words will have command text field set to red
-
Any input deletion or invalid indexes will have the result display set to orange
-
-
Test the command words
-
try partial start matches:
fi
→find
-
try typo matches:
fand
→find
-
All command word partial matches should work
-
-
asdf
→asdf
-
[command text field set to red]
-
-
try misspelled words by 1 character:
fand
→find
-
-
Test prefix completion
-
Add:
add 20/10/20@10:30 3
→add r/20/10/20@10:30 p/3
-
Edit:
edit 2 20/10/20@10:30 1
→edit 2 r/20/10/20@10:30 p/1
-
Ensure that the date values are valid
-
-
Pom:
pom 2 2.5
→pom 2 tm/2.5
-
-
Test index checking
-
Edit:
edit -2
→edit -2
-
[result display shown to user and turned orange]
-
any non positive integer or integers outside of the displayed task list’s size will trigger the same deletion and feedback
-
-
delete/done:
done -2 a 1999 2
→done 2
-
[result display also set to orange]
-
-
-
Sort field completion
-
sort:
sort na prioruty blabla
→sort name priority
-
result display set to orange if input has been deleted
-
-
Activating Pomodoro
-
Activating Pomodoro.
-
Run the command
pom 1
-
Take note of the index of that task.
Expected: Pomodoro timer will start counting down from 25:00 minutes (default). Upon expiry of the time, app will prompt user in the response bubble, asking if done or no.
-
-
Activating Pomodoro with special time.
-
Run the command
pom 1 tm/0.5
-
Take note of the index of that task
Expected: Pomodoro timer will start counting down from 00:30 minutes. Upon expiry of the time, app will prompt user in the response bubble, asking if done or no.
-
-
Pausing and Resuming Pomodoro.
-
Run the command
pom 2
-
Then, run the command
pom pause
. -
Then, run the command
pom continue
.
Expected: After the firs command, Pomodoro timer will start counting down from 25:00 minutes (default). Afterpom pause
, the timer will pause. Afterpom continue
, timer will resume.
-
{ more test cases … } === Saving data
-
Dealing with missing/corrupted data files
-
{explain how to simulate a missing/corrupted file and the expected behavior}
-
{ more test cases … }
-
Community:
-
Tools:
-
Adobe XD
-
Adobe Illustrator
-