PROJECT: Flashy


logo

Overview

Flashy is an application to help users organise their flashcards to help them memorise better.

Summary of contributions

  • Major enhancement: Revamped user interface and enhanced user experience (UI/UX).

    • What was done for UI:

      • Changed to a green colour scheme as it signifies growth, and studies have shown that green improves efficiency and focus.

      • Implemented a 3-panel layout to display more information to the user.

    • What was done for UX:

      • Added an autocompletion engine to help users enter commands quickly.

      • Added the ability to change themes in Flashy to further improve the customisability of the application.

    • Justification: This major enhancement directly shapes the user’s overall experience of the product. An intuitive interface also reduces the learning curve of the features implemented by other team members.

  • Minor enhancement: Enabled autosaving of theme preferences to maintain a hassle-free experience.

  • Code contributed: [Functional Code] [Test Code]

  • Other contributions:

    • Project management:

      • Provided extensive and rigorous discussion in code reviews. (Examples: #121, #111)

      • Reviewed 59 out of 94 pull requests not made by myself.

      • Helped with the management of github issues and milestones.

      • Built the binary executables for Github releases.

    • Documentation:

      • Cosmetic tweaks to existing contents of user guide (Example: #176).

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.

Selecting a flashcard: selectc

You can select a card that is currently being listed with the selectc command.
Format: selectc INDEX

Figure 1 shows where the index of a card can be found at:

cardIndex
Figure 1. Diagram indicating location of the displayed index

Examples:

  • selectc 2
    Selects the 2nd card in the list.

  • select 1
    Selects the 1st card in the list.

Quality-of-Life features

Flashy has many features to speed up your workflow and make your experience as pain-free as possible.

Autocompletion

Instead of memorising the parameters of all the commands, you can instruct Flashy to automatically fill in the relevant parameters for you! After typing a valid command, simply press TAB and let Flashy handle the rest.

Clearing all data : clear

Rather than manually deleting cards and tags, Flashy is able to clear all of its data for you.
Format: clear

This command will instruct Flashy to delete all tags and flashcards. Use this command with caution!

Listing entered commands : history

If you lose track of the actions you have made at any point in time, you can ask Flashy to list them for you in reverse chronological order.
Format: history

You can also press the and arrows to display the previous and next input respectively in the command box.

Undo and Redo

Flashy does not come built in with an eraser. To compensate for that, some commands support undoing and redoing. The commands are add, addc, addm, edit, editc, editm, delete, deletec, and clear.

Undoing previous command : undo

You can restore the state of Flashy’s card bank to its preious state before an undoable command was executed.
Format: undo

Undoable commands: those commands that modify the card bank’s content (add, delete, edit and clear).

Examples:

  • delete 1
    list
    undo (reverses the delete 1 command)

  • select 1
    list
    undo
    The undo command fails as there are no undoable commands executed previously.

  • delete 1
    clear
    undo (reverses the clear command)
    undo (reverses the delete 1 command)

Redoing the previously undone command : redo

Flashy can also revert any undo commands made by mistake!
Format: redo

Examples:

  • delete 1
    undo (reverses the delete 1 command)
    redo (reapplies the delete 1 command)

  • delete 1
    redo
    The redo command fails as there are no undo commands executed previously.

  • delete 1
    clear
    undo (reverses the clear command)
    undo (reverses the delete 1 command)
    redo (reapplies the delete 1 command)
    redo (reapplies the clear command)

Exiting the program : exit or quit

Once you are confident in acing that exam, don’t forget to power down Flashy! When this is done, Flashy will save all changes made to its card bank before gracefully shutting down.
Format: exit or quit

Changing the theme : theme

Flashy knows that not all study sessions occur during the day. When carrying out all-nighters, remember that you can always switch the theme of Flashy’s interface to match the lighting condition of your surroundings!
Format: theme t/THEME

Flashy remembers your most recently used theme and will load it the next time you come back.

Examples:

  • theme t/light

  • theme t/dark

FAQ

Q: How do I transfer my data to another computer?
A: Install Flashy in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous Flashy folder.

Q: Help! I cannot find the save button!
A: Fret not, Flashy automatically saves your data after any changes are made.

Q: Why are there 'c' variants of certain commands? What do they stand for? How do I differentiate them?
A: We added a 'c' suffix to commands that have both tag and flashcard variants to help you distinguish one from the other. For example, the select command selects a tag, whereas the selectc command selects a flashcard.

Q: I added a card, but I cannot find it!
A: You probably created a flashcard without a tag. You can retrieve such flashcards with the list -t command.

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.

Support for multiple themes

To allow the user to personalize their experience with Flashy, we have decided to add support for multiple themes. The architecture of this functionality has been designed to allow for maximum extensibility. Should you wish to add more themes to Flashy, simply duplicate and modify one of the existing CSS files. After that, modify the list of accepted themes in UiManager.java and the theme will be supported. This is the current list of supported themes:

public class UiManager extends ComponentManager implements Ui {
    public static final String[] VALID_THEMES = {"light", "dark"};

    // ...
}

These theme strings map into the following CSS files in ChangeThemeCommand:

public class ChangeThemeCommand extends Command {
    private final String[] themeStrings = {"view/LightTheme.css", "view/DarkTheme.css"};

    // ...
}

Current Implementation

The current implementation uses a single CSS file per designated theme. Flashy will load the selected theme dynamically. Figure 2 illustrates the sequence diagram for the theme changing functionality:

ChangeThemeSequenceDiagram
Figure 2. Sequence diagram for theme

Design considerations

Aspect: Supporting dynamically switchable themes
  • Alternative 1: Do not support dynamic switching, ship a separate version for each theme.

    • Pros: Consistent user experience with a single theme.

    • Cons: No ability to customize the look and feel of the application on the fly.

  • Alternative 2: Support dynamic switching of themes.

    • Pros: Users get a certain extent of customizability in the application.

    • Cons: More development effort needed to support multiple themes and ensure that they can be loaded.

Autocompletion

We built Flashy with an autocompletion feature to save the user the trouble of memorising the parameters of all the possible commands supported by the application. At present, autocompletion is invoked by pressing the TAB key after entering a valid command.

Current Implementation

All autocompletion-related computation is done in the Autocompleter class. It abstracts the logic of validating the eligibility of autocompletion and generating the autocompletion text into two publicly-exposed APIs, as shown in this compressed code segment:

public class Autocompleter {
    public static String getAutocompleteText(String input) {
        // ...
    }

    public static Boolean isValidAutocomplete(String input) {
       // ...
    }
}

The upon pressing TAB, the CommandBox first checks with Autocompleter to see if it is a valid command. If it is valid, it then generates an autocompletion text for CommandBox to be updated with. Figure 3 contains a visual representation of the workflow.

autocompletion ActivityDiagram
Figure 3. Activity Diagram for the autocompletion workflow

Supporting autocompletion in future commands

Should you develop more commands in the future, you can let your command support autocompletion by following these steps:

  1. Declare COMMAND_WORD and PARAMS in your class.

    public class NewCommand extends Command {
        public static final String COMMAND_WORD = "command word here";
        public static final String PARAMS = "parameters here";
        // ...
    }
  2. Include your command’s class in Autocompleter.

    private static List<Class<? extends Command>> getCommandClasses() {
        List<Class<? extends Command>> commands = new ArrayList<>();
    
        // Must be added in increasing specificity so that add is not
        // overridden by addc, for example.
        commands.add(NewCommand.class);
    }

Design Considerations

Aspect: Storage of command and parameters

The commands and parameters used by Autocompleter need to be stored somewhere accessible at runtime so that it can validate and generate autocompletion text.

  • Alternative 1: Hardcode commands and parameters in Autocompleter itself.

    • Pros: This is easy to implement. Simply hardcode the command words and parameters within the Autocompleter class.

    • Cons: Doing so requires the class to be updated whenever any command words or parameters change.

  • Alternative 2 (Current choice): Dynamically poll each command class for their command words and parameters at runtime.

    • Pros: Once this is implemented, there is no longer any need to modify Autocompleter 's code. Any changes made in the command class code is automatically reflected in Autocompleter.

    • Cons: This is a little more challenging to implement. It accessing class parameters at runtime with strings require the use of advanced Java features such as the reflection libary.