PROJECT: Infinity Book

Overview

Infinity Book (IB) is an address book application for Tech recruiters, providing end-to-end support, from searching for candidates,to adding job postings and saving their resumes and interviews.

Summary of contributions

  • Major enhancement: Implementation of Facebook integration.

    • Description: Facebook integration allows tech recruiters to integrate their facebook accounts to InfinityBook so that they conveniently use Facebook features on InfinityBook itself.

    • Justification: Infinity Book is an end-to-end application designed for tech recruiters. We understand that many tech recruiters use social network platform to screen their candidates. With this in mind, we want to improve their productivity by integrating facebook into Infinity itself. Recruiters no longer need to switch between different applications. Instead, they can mostly rely on InfinityBook alone.

    • Highlights: This enhancement touches multiple components:

      • Added a new panel to UI component to handle authorisation and to act as a GUI for facebook page.

      • Modified Logic component to accept new commands.

      • Register InfinityBook as an application under Facebook for Developer page to make use of Facebook Graph API

      • Made use of RestFB API as a Facebook Graph client API to communicate with Facebook

  • Minor enhancement: Added a command to change theme.

    • Description: Previously, InfinityBook has a single dark theme that might not be very appealing to tech recruiters. This feature allows recruiters to switch between different pre-defined theme.

    • Justification: This feature is much needed to improve the look of the app. Moreover, we can continue working on building better-looking themes to release in future iterations.

  • Minor enhancement: Added a 'remark' field to person.

    • Description: Added a flexible 'remark' field and the command to edit it.

    • Justification: Tech recruiters might have additional information for their contacts and relying on tags alone is not enough.

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

  • Other contributions:

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.

Social Media (FB, Linkedin) Integration

Facebook Login [Since v1.4]

  • Description: Connect your Facebook account to InfinityBook

  • Format: facebooklogin

  • Alias: fblogin

  • Example: facebooklogin

  • Any arguments supplied after facebooklogin or fblogin will be ignored

  • For example, facebooklogin a b c 1 2 3 will be treated the same as facebooklogin

You will be prompted by a Facebook authorization page (displayed in the right-most panel)

You can key in your facebook credentials. InfinityBook is then connected to that facebook account and you can use other features that Infinity Book offers.

  • If there is no Internet connection, the right-most panel will display a blank page. You can try login again at a later time.

  • If you are already logged-in, the command will simple re-direct you to your facebook page instead of displaying the login page

Make a post to facebook wall: facebookpost [Since v1.5rc]

  • Description: Posting a message to your facebook wall

  • Format: facebookpost [MESSAGE]
    [MESSAGE] is the message that users wants to post

  • Alias: fbpost [MESSAGE]

  • Example: facebookpost Good morning!

  • Note that the current Facebook API does not allow an app to post on your behalf. Thus, we need to add your facebook account manually to our app in the Facebook Developer platform before you can use this feature.

  • We have nevertheless created a test facebook account for you to try out this feature

  • username: infinitybook6@gmail.com

  • password: 1d2c3b4a

  • If you have logged in to your personal account and want to switch to this account. Simply re-launch the app.

  • If you are not yet logged in to facebook (by using the command facebooklogin), you will be re-directed to the login page.

After logging in, you need to make the facebookpost command again to post the message.
  • You can use the facebook page in the right-most panel to review your post

Even when you are logged in and you use the correct syntax, your message might not be posted to Facebook if it is rejected at Facebook’s end. This might be due to errors such as duplicate post, 'not enough permission' or change in Facebook API. However, under normal circumstances, you can expect that the message will be posted.

Changing theme : theme [Since v1.3]

  • Description: Change the theme of InfinityBook

  • Format: theme [THEME_NAME]
    [THEME_NAME] can be morning, dark, or light.

  • Alias: t [THEME_NAME]

  • Examples:

    • theme light
      Change the user interface to the 'light' theme

  • [THEME_NAME] is case-insensitive.

  • For example, theme morning and theme MORNING are treated the same

You can find my other contributions to User Guide: Delete Tags and Improved Find command in Appendices.

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.

Facebook Integration

The Facebook features (facebooklogin and facebookpost) are facilitated by Facebook Graph API and RestFB API. The Graph API is low-level HTTP-based API used to get data into and out of the Facebook platform while RestAPI is a high level third-party Graph API client.

Preparation

Firstly, we need to build a Graddle dependency in the graddle.properties file for RestFB API

compile group: 'com.restfb', name: 'restfb', version: '2.4.0'

To use Facebook Graph API, we followed the instruction here to create a Facebook Application on the Facebook for developer site

Finishing the steps, we reached this page

FacebookAppCreated
Figure 1. Facebook Application page

Implementation

Facebooklogin

We allow users to log in by loading the authentication URL associated with our Facebook Application to the FacebookPanel (to be explained later) specified by Graph API

private static final String FACEBOOK_AUTH_URL =
    "https://graph.facebook.com/oauth/authorize?type=user_agent&client_id=" + FACEBOOK_APP_ID
        + "&redirect_uri=" + FACEBOOK_DOMAIN + "&scope" + FACEBOOK_PERMISSIONS;
Platform.runLater(() -> webEngine.load(FACEBOOK_AUTH_URL));

If login credentials are accepted, facebook will return an access_token in its redirected url. An example of a redirected url

https://www.facebook.com/?#access_token=EAAC15Ydo408BANN5h1MoSHWhLATnte3EchlxqsXA7x2WASMlZBJzlZC3rZCmlu4Wib3hi1bXR2r2sx2ZCgIJvJCrXaTAnQVN4f0ksFLSvCuezLhG43myLJtxT3Qtn0PpcIXXZBjgYUI4LwGvv837KGC2V4ifctNaBnHqRX6e7qAZDZD&expires_in=5184000

Using this access_token, we 'capture' this login session by making use of RestFB API. We set up the session in FacebookLoginCommand as followed

fbClient = new DefaultFacebookClient(accessToken, Version.LATEST);
user = fbClient.fetchObject("me", User.class);

'fbClient' is the Facebook Graph API client with the supplied token.

'user' is the authenticated user object.

Facebookpost

We will check if user is authenticated via the boolean variable isAuthenticated before allowing posting on facebook. If user is not authenticated, he will be redirected to log in

if (!FacebookLoginCommand.getAuthenticateState()) {
    FacebookLoginCommand fbLoginCommand = new FacebookLoginCommand();
    fbLoginCommand.execute();
} else {
    completePost();
}

We simply post the message to Facebook using the authenticated fbClient in FacebookLoginCommand

DefaultFacebookClient fbClient = FacebookLoginCommand.getFbClient();
fbClient.publish("me/feed", FacebookType.class, Parameter.with("message", toPost));

Implementation details

'FacebookPanel' extends UiPart<Region> and shares the same region with BrowserPanel or ReportPanel. When facebooklogin is executed, MainWindow class will swap out the BrowserPanel or ReportPanel and replace by FacebookPanel. We achieve this by posting ToggleFacebookPanelEvent (showing in the below sequence diagram).

'FacebookPanel' is used mainly as a browser to authorize a user to Facebook. It is also used to display the Facebook page after the user is authorized.

For capturing the access_token, we register FacebookPanel as an event handler. If the url (of FacebookPanel) changes to a new one that contains the access_token, we raise a BrowserUrlChangedEvent. Also, our FacebookPanel is subscribed to handle BrowserUrlChangedEvent by passing the url (with access_token) back to FacebookLoginCommand to complete the authentication.

The below sequence diagram show interactions within Logic component when user executes facebookpost hello.

FbSequenceDiagram
Figure 2. Sequence diagram detailing Logic component when executing facebookpost

Design considerations

Aspect: Choice of client API for Facebook Graph API
Alternative 1 (current choice): Use RestFB
Pros: RestFB is simple and easy to use with well-documented API Cons: Features are limited
Alternative 2: Facebook4j
Pros: Facebook4j provides more extensive features
Cons: It is harder to use and we do not really need advanced features for now


Aspect: Authentication
Alternative 1 (current choice): Authenticate using the built-in web browser (in FacebookPanel)
Pros: Convenient for user as authentication is done inside the app itself
Cons: The built-in Java web-engine might not support certain features of a webpage
Alternative 2: Authenticate by opening a full-pledged web browser such as Chrome/ Safari
Pros: The Facebook authorization page will be better supported by such a browser
Cons: User needs to switch between different applications

Theming Mechanism [since v1.3]

The theme mechanism is facilitated by a singleton class UiTheme which will be called inside the MainWindow constructor where it passes its scene into the UiTheme class. The scene is necessary for changing the CSS at runtime.

The class UiTheme requires the scene to be set at MainWindow class so that it can be used to edit themes.

public class UiTheme {
    ...
    public static void setScene(Scene s) {
        scene = s;
        setDefaultTheme();
    }

    private static void setDefaultTheme() {
        setToMorningTheme();
    }

    public static void setToLightTheme() {
        scene.getStylesheets().setAll(LIGHT_THEME_STYLE);
    }

    public static void setToDarkTheme() {
        scene.getStylesheets().setAll(DARK_THEME_STYLE);
    }

    public static void setToMorningTheme() {
        scene.getStylesheets().setAll(MORNING_THEME_STYLE);
    }
    ...
}

Example of calling the application to change to light theme:

UiTheme.getInstance().setToLightTheme();

Design Considerations

Aspect: Ways to change the application theme
Alternative 1 (current choice): Use a dedicated singleton class UiTheme to change the theme
Pros: Provide a dedicated class that manages all the changing of themes. UiTheme can contain many CSS theme file paths and thus the theme mechanism is more scalable . It is easier for ThemeCommand class to call UiTheme instance and use its methods directly.
Cons: Increases coupling
Alternative 2: Change the themes in MainWindow class directly
Pros: Decreases coupling
Cons: Violates the single responsibility principle since MainWindow class also controls the changing of theme. It is harder for ThemeCommand class to access the methods from MainWindow to change theme

Tag colors [since v1.0]

Current Implementation

Use different colors for different tags inside person cards. For example, friends tags can be all in red and colleagues tags can be all in blue. Pre-defined colors are included in DarkTheme.css, LightTheme.css and MorningTheme.css. We use hash code of the tag names to generate a color. This is deliberately designed to ensure consistent colors each time the application runs.

Design considerations

Aspect: Implementation of color for tags

Alternative 1 (current choice): Have tags to be colored using hashcode instead of randomization
Pros: The color stay consistent each time the app is launched
Cons: Limited number of colors (the limiting factor is the size of pre-define color array)

Alternative 2: Have tag colors to be a random hexadecimal color value
Pros: Number of different color is very big (i.e. there is less repetitive color used)
Cons: The color for each tag value might be different between app launchs