1. Introduction
This project portfolio aims to document my contributions to Mark, a project by my team of 5 Computer Science students from NUS.
Mark is a user-friendly bookmark manager desktop application targeted at NUS Computing students, mainly for use on a computer and for students who prefer getting things done by typing out commands via the command line interface (CLI).
My team was tasked to develop this application over the course of six weeks by morphing AddressBook (Level 3).
Here are some key features of Mark:
-
Save and annotate content from a website for convenient offline access
-
Set reminders for your to-dos
-
Organize your bookmarks automatically
In particular, my task was to help achieve the last point, and I did so by implementing an alternative way to organize bookmarks via folders.
Some special symbols and formatting are used later on in the text, so here is a list of them and what they mean:
Important text critical to the usage of Mark. |
Helpful tips that can make using Mark easier. |
Information that is good to know. |
2. Contribution Summary
This section serves to describe some of contributions I made to the development of Mark, such as enhancements, documentation, and code reviews.
-
Major enhancement: implemented folders in a hierarchical structure to organize bookmarks:
-
What it does: Allows users to have an alternate organization of their bookmarks, instead of showing all of them in one long list and having to search for them.
-
Justification: Users are familiar with organising their files on a computer into folders, so providing this functionality makes their transition to Mark smoother.
-
Highlights: This enhancement required knowledge of data structures and algorithms, as displaying, transforming, and other interactions with the folder hierarchy was quite challenging.
-
-
Minor enhancement: added a caching command that allows the user to "download" an copy of a website, for access when there is limited internet access.
-
Code contributed: Click [here] to see all of my code and documentation contributions to Mark.
-
Other contributions:
-
Enhancements to existing features:
-
Documentation:
-
Community:
-
Tools:
-
Integrated a third party library (Readability4J) to the project #121
-
-
3. Contributions to the User Guide
Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
(start of extract from User Guide)
3.1. Folders
The following commands carry out operations on folders in Mark. The results of these operations can be viewed in the folder hierarchy of dashboard tab.
The bookmarks that are displayed in the folder hierarchy correspond to the bookmarks in the bookmarks list on the left. For example, if you have have just performed a find command and the bookmark list shrinks from 100 entries to just 10, the folder hierarchy will also
shrink from showing 100 bookmarks to 10.
|
You can use the list command to see all your bookmarks in the folder hierarchy.
|
3.1.1. Adding a folder: folder
When your bookmark list is getting too long, you may want to use this command to create new folders to organize bookmarks into.
Format: folder FOLDER_NAME [p/PARENT_FOLDER=ROOT]
For example:
-
You notice you have 20 bookmarks all related to CS2103T. You decide to create a folder for them, so you enter the command
folder CS2103T
and hit Enter. -
You see a new empty folder
CS2103T
appear in the dashboard.
Parameter constraints:
Other examples:
-
folder CS2103 p/NUS
Creates a new folder namedCS2103
under the parent folderNUS
.
3.1.2. Editing a folder: folder-edit
If your favorite band recently changed its name, you may want to edit your folder for it to reflect its new name. You can do so with this command.
Format: folder-edit FROM_FOLDER​_NAME t/TO_FOLDER_NAME
For example:
-
You recently broke up, and want to edit the folder
Dear
containing all your previous memories toEx
. So you enter the commandfolder-edit Dear t/Ex
and hit Enter. -
You see folder
Dear
renamed toEx
. All your bookmarks previously in the folderDear
have also been edited to now be in the folderEx
.
Parameter constraints:
(end of extract from User Guide)
4. Contributions 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. |
(start of extract from Developer Guide)
4.1. Folders feature
This section aims to explore the implementation of Mark’s folders and some design considerations.
4.1.1. Implementation
The following two sections will explain in more detail how the backend and frontend of this feature works.
Model implementation of folders
A bookmark can be in a folder, and a folder can be nested within other folders for traditional directory organization.
This mechanism is facilitated mainly by Folder
and FolderStructure
.
Folder
is simply another field in Bookmark
, just like Url
or Name
, and has a single String
property that contains the folder in which the bookmark is located.
FolderStructure
represents the hierarchy of folders, containing the folder it represents and its subfolders
Given below is an example usage scenario and how the folder structure behaves at each step.
Step 1. The user launches the application for the first time. The root FolderStructure
will be initialized with the initial hierarchy in the stored data.
Step 2. The user enters a folder GER1000 p/Work
command to create a new FolderStructure
in the subfolders of work
. Starting from the root
, a depth first search will be performed to locate work
. When found, ger1000
will be added to its subfolders.
If the parent folder is not provided, the parent folder will default to root .
|
The following sequence diagram shows in more detail how the execution of folder GER1000 p/Work
works:
The lifeline for AddFolderCommand should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
Finally, the user sees his folder added successfully in the folder hierarchy.
UI implementation of the expand command
Mark displays the folders and their bookmarks in a JavaFX TreeView
, and listens for any updates to the bookmarks
or the folder structure via Observable
s so that the UI can also be updated accordingly.
As Mark is mainly a CLI-based application, the expand
command is provided to allow users to "click" on all unexpanded folders.
As the underlying folder structure is not altered, Oberservable
s cannot help us and so the command must send a signal to the UI that
an expand
command needs to be performed.
Then, the following method is called to perform the expansion:
seedu.mark.ui.FolderStructureTreeView
private void expand(TreeItem<String> node, int levels) {
if (levels <= 0) {
return;
}
if (node.isExpanded()) {
node.getChildren().forEach(child -> expand(child, levels));
} else {
node.expandedProperty().set(true); // we expand it
// make sure all children are not expanded
node.getChildren().forEach(child -> child.setExpanded(false));
expand(node, levels - 1);
}
}
The method expands a folder if it is not already expanded, and then recursively calls itself on all of that folder’s subfolders until the desired level of expansion is achieved.
4.1.2. Design considerations
The following are a few design considerations made in deciding how to implement the folders feature.
Aspect: How the folder hierarchy is saved into storage
The following were two alternatives considered when implementing the model for the folders feature.
-
Alternative 1 (current choice): Saves bookmark folder as its own field, and the hierarchy as a separate data structure.
-
Pros: Easy to implement. Adding another field to a bookmark is simple, and storing the folder structure on its own makes it more modular and easy to test as well.
-
Cons: Easy for model to get into invalid state. For example, when renaming folders, the bookmarks containing the old folder names needs to be updated separately. This leads to tight coupling and potential future maintenance issues.
-
-
Alternative 2: Change the bookmarks from being stored in a list to being stored in a tree structure.
-
Pros: Single source of truth, a bookmark’s folder is simply which part of the tree it resides in. When a folder is renamed, the bookmarks in that folder will still be in the same folder, so there is no extra step needed to update the bookmarks. This reduces coupling between the bookmarks and folders too.
-
Cons: The whole
BookmarkList
abstraction will have to be rewritten. It is also significantly harder (in terms of ease of implementation) to filter, edit, and add bookmarks due to having to use more advanced tree traversal algorithms as compared to naive list or array operations.
-
Aspect: What the expand/collapse command does
In designing the expand and collapse command, the below two alternatives were considered. Only the expand command shall be elaborated upon, since the collapse command is simply the opposite of the expand command.
-
Alternative 1 (current choice): Expand to a certain level of folders.
For example, whenexpand 2
is executed, the folder hierarchy will always display folders until two levels deep, regardless of its state before the command.-
Pros: State is more easily managed. Mark can keep track of which level to expand until, and the UI can listen to changes to this via an
Observable
instead, leading to better separation of concerns. -
Cons: Not intuitive for the user to understand. Since the folder hierarchy can be interacted with via the mouse also, the user may decide to expand the folders with his mouse and then execute
expand 2
, resulting in the folders expanding to two levels deep. This may result in the user thinking the folders were collapsed instead, if he had expanded his folders all the way before the command. This leads to confusion for the user.
-
-
Alternative 2: Go through all folders and check if they have been expanded. If a folder is not expanded, expand it. Repeat for the desired nmber of levels.
-
Pros: Easier for the user to understand. No matter what commands the user types or what he clicks, the expand command will always "expand" to a deeper level than what he originally saw (unless it was already expanded all the way).
-
Cons: An extra coupling is needed to tie the UI and the expand command together, since it cannot simply listen to changes from the model. This decreases extensibility and increases maintenance costs.
-
(end of extract from Developer Guide)