ButterKnife for Open Event Android

Open Event Android, by FOSSASIA has been coded in a very clean and systematic manner. One of the great things used in it is the ButterKnife library. It has made increased the readability and understand ability of the app’s code.

ButterKnife, developed and maintained by Jake Wharton(Square Inc.) is an Android library designed to make Java code less complex and efficient. The library operates with the use of annotations and hence, binds classes to the relevant annotations in Java and do the job.

First off, here’s the very first thing that you want to do before starting to use ButterKnife — Adding it’s dependency in the build.gradle file of your project.

compile 'com.jakewharton:butterknife:8.6.0
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'

At FOSSASIA, we have extensively used this amazing library to simplify the code for our Open Event Android application. I hope this blog will help newcomers in understanding our code base in a better way.

We have the famous @Bindview annotation by ButterKnife to bind views to Android components without having to call R.FindViewById() method for every view. The following is a code sample from Open Event Android about the same.

@BindView(R.id.toolbar) Toolbar toolbar;

@BindView(R.id.nav_view) NavigationView navigationView;

@BindView(R.id.progress) ProgressBar downloadProgress;

@BindView(R.id.layout_main) CoordinatorLayout mainFrame;

@BindView(R.id.drawer) DrawerLayout drawerLayout;

@BindView(R.id.appbar) AppBarLayout appBarLayout;

Similarly, the ButterKnife library also handles events in an Android application and has annotations like @onClick, @onLongClick among others. So while using ButterKnife for an event, choose the appropriate event and the corresponding annotation followed by the Java method that is to be executed. Here is an example for the same.

@OnClick(R.id.submit)

public void submit(View view) {

// TODO submit data to server...

}

The ButterKnife library also helps to bind resources in your project.

It simplifies the View holder pattern inside a list adapter as illustrated in the following example.

public class MyAdapter extends BaseAdapter {

@Override public View getView(int position, View view, ViewGroup parent) {

   ViewHolder holder;

   if (view != null) {

     holder = (ViewHolder) view.getTag();

   } else {

     view = inflater.inflate(R.layout.whatever, parent, false);

     holder = new ViewHolder(view);

     view.setTag(holder);

   }

   holder.name.setText("John Doe");

   // etc...

   return view;

 }

static class ViewHolder {

   @BindView(R.id.title) TextView name;

   @BindView(R.id.job_title) TextView jobTitle;

   public ViewHolder(View view) {

     ButterKnife.bind(this, view);

   }

 }

}

The above code sample has been taken from http://jakewharton.github.io/butterknife/ and you can visit the site for further in-depth knowledge on ButterKnife.

How ButterKnife works?

I will be talking a bit about the working of the ButterKnife library. Firstly, I would like to introduce annotations concept in Java briefly before proceeding.

“In the Java, computer programming language, an annotation is a form of syntactic metadata that can be added to Javasource code. Classes, methods, variables, parameters and packages may be annotated.” As it is rightly said, Annotations can be of various uses like Getting information for the compiler, Compile-time and deployment-time processing, Runtime processing. However, please note that annotations can NOT modify and edit the existing classes. They can simply make more classes.

With this, I’m gonna continue on the working of ButterKnife. From the above discussion it must be clear now that ButterKnife is not changing any of our classes. It makes new classes to handle the code.

ButterKnife goes through all the files in your project and identifies the ButterKnife annotations used, if any. It then creates new classes for every annotation encountered, based on the annotations used. These new classes contain the general methods that would have been used in a project without ButterKnife. When we finally call ButterKnife.inject(this) , the inject()of all the new classes made by ButterKnife are called which then perform the desired function during execution.

Finally, try to go through the complete documentation for Butterknife and Java annotations for more information. 

Continue ReadingButterKnife for Open Event Android

Using Flexbox for Responsive Layout in Open Event Webapp

Recently, I tackled the issue of alignment of different buttons and input bar in the Open Event Webapp. The major challenge was to create a responsive design which adapts well on all the platforms: desktop, tablets and mobile. Doing it using grid layout provided by Bootstrap was rather tough and complicated and I solved the problem using the flexbox.

What is Flexbox?

Flexible Boxes, also called as Flexbox, is a new layout mode introduced in CSS3. The best part of using flexbox is that it ensures that the elements behave in a predictable manner when the page layout accommodates different screen sizes and display devices. In other words, it helps us in making a responsive design in a simpler manner. It is an alternative to block elements being floated and manipulated using media queries. Using Flexbox, a container and its children can be arranged in any direction: up, down or left and right. Size is flexible and elements inside the flexbox can grow or shrink to occupy unused space or prevent overflow respectively.

The difference with grid layouts?

There is a slight difference between flexbox and grid layouts which makes one suitable for creating a fully complete layout and the other not so much.

Ideally, grids (provided by Bootstrap for example) are used for creating an entire layout. Flexbox is suited for styling separate containers such as navbars for example.

flex_terms.png

                                 Structure of Flexbox Container

How did I solve it?

First I defined a container which acted as a wrapper for all the buttons and the search bar. Now, to convert this container into an actual flexbox, we have to add display: flex property to it.

.container {
 display: flex;
}

Did the issue got solved? It doesn’t look so. The container enclosed in the red border is the flexbox.

flexnogrow.png

As we can see from the picture itself, the elements are quite close to each other and a lot of space is wasted. Fortunately, flexbox provides us a handy property called flex-grow which deals with this type of problem. It defines the ability for a flex item to grow if necessary. That it, it tells how much amount of the available space inside the flex container the item is allowed to take. If all the items have flex-grow set to 1, then the remaining space in the container would be equally distributed to all the items. In a similar way, if an item has flex-grow set to 2, then it would occupy twice the amount of available space when compared to the other items.

So, I applied the flex-grow:1 on the items.

.list-btn {
   flex-grow: 1;
}

.search-filter {
   flex-grow: 1;
}
.starred-btn {
   flex-grow: 1;
}

.calendar-btn {
   flex-grow: 1;
}

How does it look now?

flexbox_initial.png

Much better. But is the problem solved now? No. There is one more thing that we haven’t checked yet. Yes. It’s the responsiveness. We haven’t yet checked how it displays on tablets and mobiles yet? Let’s test and check and what we see.

mobilenowrap.png

Ok. Something is not right. The items are squeezing together. That doesn’t look good. We don’t want the elements to wrap on a single line. What we actually want is that the items would stack on top of each other when the screen size is reduced. That would look much more neat and tidy.

To change this default behavior of wrapping of items, we use the flex-wrap property on the container. Specifying flex-wrap: wrap does the trick and the items wrap as needed.

mobilewrap2.pngmobilewrap1.png

 

.container {
   display: flex;
   flex-wrap: wrap;
}

The result looks much better now. The items wrap on a single line only when there is enough space available. Otherwise, they wrap up onto multiple lines from top to bottom.

Flexbox is a great tool for creating custom layouts for separate containers. Apart from the properties discussed here, there are a plethora of other options which can be used to customize the behavior of flexbox and the items contained inside it.  Check out the links below for more information!

Resources:

Continue ReadingUsing Flexbox for Responsive Layout in Open Event Webapp

Intro to concurrency and Refactoring Open Event Android using RxJava

Functional reactive programming seems to have taken the whole development world by storm. It’s one of the hottest thing even after 2 years of constant traction in the communities of several programming languages, where different implementations of the specifications defined by Rx or Reactive Extensions have changed the paradigm of programming for many professional and enthusiast developers.

RxJava is no exception, not only has it been widely adopted by Android and Java developers unanimously, but also received attention of well known and top developers of both communities. The reason of its success is the fluent API with heavy toolset it provides from the Functional Programming paradigm and its ease and natural ability to handle concurrency on different levels based on the type of operation being performed, i.e., computations, I/O, etc. It basically takes away the several constraints and concurrency related checklists developers had to maintain while working with thread management. So, now, developers can’t make an excuse for using database operations on the Main Thread because offloading it on another thread is hard.

So, in this blog post, I will be detailing the process of converting the existing synchronous code of your app into a performant reactive code without breaking the structure of your project, like we did in Open Event Android (Github Repo). Before starting, I have assumed that you know how to add RxJava dependency to your project as it is covered in many other blog posts and the documentation is also very clear. Secondly, you should also add RxAndroid dependency as it contains the Scheduler needed to work on Android’s Main Thread. So, Let’s start.

Current State

Currently, our code loads the queries from database synchronously on Main Thread using the SQLiteDatabase for an Android application. This is how it looks like –

As we can see, we are directly returning the loaded results to the caller. This is called synchronous call, meaning the caller will block till the function is returned, and can’t move further to do anything else. It basically waits for the function to return, which may take hundreds of milliseconds to seconds based on the function it performs.

New Android version crash the applications that perform Network interactions on the main thread but no such restriction for disk based operations is there, making it hard to enforce best performance practices. Before RxJava, there were interfaces made for different kinds of objects, passed in as parameters of the db request function, which created a new thread and performed operations and when completed, returned back the results to the main thread using the postOnUiThread method, so that the views could update themselves. The interface implementations passed are called callbacks because they call a particular function that you provide back when the asynchronous operation is completed. Even the calling of callback function is delegated on the implementor and may result in undesired effects. The query done in this fashion is called an asynchronous query because the execution of this takes place in parallel with main thread and is not synchronised with the main thread. It may take up forever to complete, complete even before the main thread moved on to next operation or even return when the main thread was completed and done waiting for it and destroyed. This will result in a weird crash even when the application was closed, because the returned function will try to update the views which are not even there.

Problems like these made Android Devs lazy and compromise with the performance of their application. Not anymore! RxJava is here to solve half of our problems. You see, RxJava does provide a solution to achieve effortless concurrency but does not ensure thread safety, memory contention, race conditions, deadlocks and other concurrency related issues for you. These you must code up for yourself.

So, after the introduction of Rx and its dire need in Android projects, we will move on to a basic procedure to convert any synchronous code to asynchronous call using RxJava Observable.

Let’s subscribe

The Observable class in RxJava is the most used and standard stream class you will use. Observable handles a stream of object and passes them as they arrive to the Subscriber attached to it. As you may guess, for a stream of data that arrives in a non deterministic fashion ( we don’t know when it will arrive ), we require an asynchronous query, and this is where RxJava excels at. You can configure an Observable to wait for result in one thread so that main thread doesn’t block and deliver result on another thread. You can either create a new thread or use certain pre configured schedulers for basic type of operations :

  1. Schedulers.newThread() : Creates a new thread for each request
  2. Schedulers.io() : For I/O bound work like a network call, database access
  3. Schedulers.computation() : For heavy computations
  4. AndroidSchedulers.mainThread() : For returning to UI thread of Android ( Present in RxAndroid )

There are other types of Schedulers like Schedulers.trampoline(), etc that are used for other purposes like testing, but the above ones are most commonly used ones and we’ll be using Schedulers.computation() for loading the SQLite query on the thread from Computation Thread Pool and AndroidSchedulers.mainThread() for delivering the result on UI thread.

Using Computation instead of I/O because I/O uses unbounded executor, meaning it continues adding threads to the thread pool, which isn’t good. So, we use computation instead. You can create your own bounded executor and pass it as a scheduler

The basic operation of passing an object to a subscriber is :

Observable.just(getEventDetails())
        .subscribe(new Consumer<Event>() {
          @Override
          public void accept(@NonNull Event event) throws Exception {
              Log.d("EVENT", event.toString());
          }
      });

 

Using lambda notation, we get a terse form of the same :

Observable.just(getEventDetails())
 	.subscribe(event -> Log.d("EVENT", event.toString()));

We’ll be using lambda notations from now on.

In the above example, we are just loading and passing the Event object to the subscriber below who logs it. But this is not asynchronous, everything gets executed on main thread. The above code is equivalent to :

Event event = getEventDetails();
Log.d("EVENT", event.toString());

 

So why use it, you say? Well, we can still get a lot of goodies from functional programming this way. For example,

String track = "Android";

Observable.fromIterable(getSessionList())
    .filter(session -> session.getTrack().getName().equals(track))
    .map(Session::getTitle)
    .toList()
    .subscribe(titles -> Log.d("Titles", titles.toString()));

 

What this code does is, take a list of sessions and emit each session at a time, filter out the ones which don’t have Android as their track name, take out their titles and puts them in a list and gives it to subscriber.

Now imagine doing it in plain Java. Create a list of string, loop through each session, check track, push title to that list and this much when this example is the most basic of use cases of RxJava.

But how to achieve concurrency. If the there are 10000 sessions, this code will take huge time even if sessions are in memory and not loaded from database. So we will listen to these list events on computation thread.

Observable.fromIterable(getSessionList())
    .filter(session -> session.getTrack().getName().equals(track))
    .map(Session::getTitle)
    .subscribeOn(Schedulers.computation())
    .subscribe(titles -> adapter.setItems(titles));

 

That’s it. Now each filtering and mapping and converging to a list is done on another thread.

If you want to listen to each session one at a time, and not all at once when it is completed, you can remove toList() operator

But now, our app will crash! Because when we deliver the result to subscriber, we are still on computation thread, so we need to come back to Main Thread because Android Views are not thread safe, meaning they cannot be accessed from any thread other than UI thread. So in order to do that, we just use observeOn() operator :

Observable.fromIterable(getSessionList())
    .filter(session -> session.getTrack().getName().equals(track))
    .map(Session::getTitle)
    .toList()
    .subscribeOn(Schedulers.computation())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(titles -> adapter.setItems(titles));

 

Still, our code has a critical problem, the mapping and filtering takes place on background thread, but the loading of session list still takes place on UI thread because it is loaded first and then passed to Observable

Observable methods like just, from, fromIterable, etc all take object from the current thread, meaning passing the object to these functions will not occur on the Scheduler you have supplied. This is very basic programming concept that language parses rightmost parameter first but usually is misunderstood in terms of Rx programming.

So, what do we do? We use fromCallable which waits till the containing function returns and then operates on it

Observable.fromCallable(this::getSessionList)
    .flatMapIterable(sessions -> sessions)
    .filter(session -> session.getTrack().getName().equals(track))
    .map(Session::getTitle)
    .toList()
    .subscribeOn(Schedulers.computation())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(titles -> adapter.setItems(titles));

 

We’re done! We have changed our synchronous database call to an asynchronous call.

Another use case is when you just have to do an operation asynchronously and not return anything, then fromCallable won’t work as it expects some return value to operate on, instead use Completable

Completable.fromAction(this::clearDatabase)
    .subscribeOn(Schedulers.computation())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(() -> {
        // Completed
        showToast("Success");
    });

 

Note that here we use method reference to call a function, you can just pass in a lambda or Action implementation to do some in place work like this

Completable.fromAction(() -> {
    doSomeStuff();
    // ...
    doOtherStuff(); 
}).subscribeOn(Schedulers.computation())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(() -> {
      // Completed
      showToast("Success");
  });

 

Now, you can wrap all your slow methods into observable or completable without changing any code structure and your code will look like this :

On parting note, a trick to avoid repeated subscribeOn observeOn :

private <T> ObservableTransformer<T, T> applySchedulers() {
    return upstream -> upstream.subscribeOn(Schedulers.computation())
                               .observeOn(AndroidSchedulers.mainThread());
}

 

Create this function and just call compose on each Observable and call the function inside that, passing the transformer., like it is shown in the picture above

That’s it for now. Have a happy and lag free day!

Continue ReadingIntro to concurrency and Refactoring Open Event Android using RxJava

Handling date-time in the Open Event Project

Handling date time in code becomes little tricky when the project is used internationally because then there comes additional term Timezone. Timezone is a property of a location which needs to be considered while comparing that time with the time in another location. For example – there are two villages A and B. One day Ram from village A calls his friend Shyam in village B at 8:00 am to wish “good morning”. But Shyam receives Ram’s call at 6pm on same day and he replies “good evening”. That means village A’s timezone is 10 hrs  behind village B’s timezone. So here we need some reference timezone about which all other timezones can be declared. This is where UTC (Coordinated Universal Time) comes into play. UTC is reference timezone by which all the timezones are declared. For example – Indian timezone is 5 hrs and 30 mins ahead of UTC which is denoted as UTC+05:30. In languages, these timezones are declared in date time library using constants such as ‘Asia/Kolkata’ which is Indian Standard Time. I will be talking about working with  date time in python in this blog. In the FOSSASIA’s Open Event project since it is event management system, handling date-time with the timezone is one of the important tasks.

Here is the relevant code:

>>> import datetime
>>> import pytz
>>> now = datetime.datetime.now()

datetime.datetime.now()  returns naive datetime as of the time setting of the machine on which the code is running. Naive date means it doesn’t contain any info about the timezone. It just contains some number values of year, month, hours etc. So just by looking at naive date we cannot actually understand the time. There comes aware datetime which contains timezone info.

>> now
datetime.datetime(2017, 5, 12, 21, 46, 16, 909983)
>>> now.isoformat()
'2017-05-12T21:46:16.909983'
>>> aware_now = pytz.timezone('Asia/Kolkata').localize(now)
>>> aware_now
datetime.datetime(2017, 5, 12, 21, 46, 16, 909983, tzinfo=<DstTzInfo 'Asia/Kolkata' IST+5:30:00 STD>

Pytz provides timezone object which takes string argument for timezone which has localize method which adds timezone info to the datetime object. Hence now aware datetime has timezone info too. Now if we print the time.

>>> aware_now.isoformat()
'2017-05-12T21:46:16.909983+05:30

We get the +05:30 extra string at the end which gives timezone info. +05:30 means the timezone is 5 hrs and 30 mins ahead of UTC timezone. The comparison between datetimes can be made between naive-naive and aware-aware. If we try to compare between naive and aware,

>>> now < aware_now
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes

>>> now2 = datetime.datetime.now()
>>> now2
datetime.datetime(2017, 5, 15, 9, 44, 25, 990666)
>>> now < now2
True
>>> aware_now.tzinfo
<DstTzInfo 'Asia/Kolkata' IST+5:30:00 STD>

tzinfo carries timezone info of the datetime object. We can make aware date to unaware by method replacing tzinfo to None.

>>> unaware_now = aware_now.replace(tzinfo=None)
>>> unaware_now.isoformat()
'2017-05-12T21:46:16.909983'

Formating datetime is done by mostly these two methods. One of which takes string format in which the result is required and another returns datetime in iso format.

>>> now.strftime('%Y-%m-%dT%H:%M:%S%z')
'2017-05-12T21:46:16'
>>> aware_now.strftime('%Y-%m-%dT%H:%M:%S%z')
'2017-05-12T21:46:16+0530'

>>> now.time().isoformat()
'21:46:16.909983'
>>> now.date().isoformat()
'2017-05-12'

>>> now_in_brazil_east = datetime.datetime.now(pytz.timezone('Brazil/East'))
>>> now_in_brazil_east.isoformat()
'2017-05-15T06:49:51.311012-03:00'

We can pass timezone argument to the now method to get current time in the passed timezone. But the care must be taken as this will use the timezone setting of the machine on which code is running to calculate the time at the supplied timezone.

Application

In the FOSSASIA’s Open Event Project, date-time is taken from the user along with the timezone like in one of the example shown below.

Date Time Getter Open Event
Date Time Getter in Create Event Step 1 Open Event Front End

This is part of the event creation page where user has to provide date-time along with the timezone choice. At back-end the date-time and timezone are stored separately in the database. The event model looks like

class Event(db.Model):
 """Event object table"""
 ...
 start_time = db.Column(db.DateTime, nullable=False)
 end_time = db.Column(db.DateTime, nullable=False)
 timezone = db.Column(db.String, nullable=False, default="UTC")
 ...

The comparison between the stored date-time info with the real time cannot be done directly. Since the timezones of the both times need to be considered along with the date-time values while comparison. Likewise there is one case in the project code where tickets are filtered based on the start time.

def get_sales_open_tickets(event_id, event_timezone='UTC'):
  tickets = Ticket.query.filter(Ticket.event_id == event_id).filter(
      Ticket.sales_start <= datetime.datetime.now(pytz.timezone(event_timezone)).replace(tzinfo=None)).filter(
      Ticket.sales_end >= datetime.datetime.now(pytz.timezone(event_timezone)).replace(tzinfo=None))
  …

In this case, first current time is found out using timezone method in the timezone which is stored as a separate data field in the database. Since comparison cannot be done between aware and naive date-time. Hence once current date-time is found out in the user’s timezone, it is made naive using replace method which makes the aware date-time into naive again. Hence can be compared with the naive date-time stored already.

Continue ReadingHandling date-time in the Open Event Project

Debugging Using Stetho in Open Event Android

The Open Event Android project helps event organizers to generator Apps (apk format) for their events/conferences by providing api end point or zip generated using Open Event server. In this android app data is fetched from the internet using network calls to the Open Event server and the data of the event is stored in a database. It is difficult to debug an app with so many network calls and database connectivity. A way to approach this is using  Stetho which is very helpful tool for debugging an app which deals with network calls and database.  

Stetho is Facebook’s open source project works as debug bridge for android applications which gives powerful Chrome Developers Tools for debugging android applications using Chrome desktop browser.

What can you do using stetho ?

  • Analyze network traffic
  • Inspect elements(layouts/views)  
  • View SQLite database in table format
  • Run queries on SQLite database
  • View shared preference and edit it
  • Manipulate android app from command line

Setup

1. Add Gradle dependency

To add stetho in your app add ‘com.facebook.stetho:stetho:1.5.0’ dependency in your app  module’s build.gradle file. This dependency is strictly required.

dependencies{
    compile 'com.facebook.stetho:stetho:1.5.0'
}

For network inspection add one of the following dependency according to which you will be using

'com.facebook.stetho:stetho-okhttp:1.5.0'
'com.facebook.stetho:stetho-okhttp3:1.5.0'
'com.facebook.stetho:stetho-urlconnection:1.5.0'

2. Initialize stetho

Initialize stetho in class MyApplication which extends Application class by overriding  onCreate() method. Make sure you have added MyAppication in manifest.

public class MyApplication extends Application {
    public void onCreate() {
        super.onCreate()
        Stetho.initializeWithDefaults(this);
    }
}

Stetho.initializeWithDefaults(this) initializes stetho with defaults configuration(without network inspection and more). It will be able to debug database.

Manifest file

<Application   android:name=”.MyApplication    …   />

For enabling network inspection add StethoInterceptor  in OkHttpClient

new OkHttpClient.Builder()
    .addNetworkInterceptor(new StethoInterceptor())
    .build();

Using Chrome Developer Tools

1. Open Inspect window

Run stetho initialized app on device or emulator then start Google chrome and type chrome://inspect. You will see you device with your app’s package name. Click on “inspect”2. Network Inspection

Go to Network tab. It will show all network calls. With almost all info like url(path), method, returned status code, returned data type, size, time taken etc.

You can also see preview of image and preview, response of returned json data by clicking on Name.

3. SQLite Database

Go to “Resources”  tab and select “Web SQL”. You will see database file(.db). By clicking on database file you will see all tables in that database file. And by clicking on table name you will see data in row-column format for that table.

4. Run queries on SQLite database

Same as above go to “Resources”  tab and select “Web SQL”. You will see database file(.db). By clicking on database file you will see console on right side, where you can run queries on SQLite database. Example,

SELECT * FROM tracks ;

5. Shared Preferences Inspection

Go to “Resources”  tab and select “Local Storage”. You will show all files that your app used to save key-value pairs in shared preference and by clicking on file you will see all key-value pairs.

6. Element(View/Layout) Inspection

Go to “Elements” tab. You will see top layout/view in view hierarchy. By clicking it you will see child layout/view of that layout/view. On hover on layout/view you view will be inspected in your device/emulator.

 

In this blog the most important have been put forward, but there are still  some nice stuff available,like:

  • An integration with JavaScript Console : Enables JavaScript code execution that can interact with the application
  • Dumpapp  : It allows an integration higher than the Developer Tools, enabling the development of custom plugins.

By now, you must have realized that stetho can significantly improve your debugging experience. To learn more about stetho, refer to

Continue ReadingDebugging Using Stetho in Open Event Android

Handling Zip Upload in Open Event Webapp

In Open Event Webapp, we use Socket.IO library for real-time communication between client and the server. To be able to generate a site for an event, the user has to first upload the file to the generator. There are a lot of node libraries like multer and formidable which exists for this purpose. But they don’t support display of real-time stats regarding the progress of the uploaded file. To solve this issue, the project used socket-io-file-upload library which uploads the file to the Node.js server using Socket.IO and show live percentage denoting how much of the zip has been uploaded to the server.

It was working quite well until we discovered a major problem with the library. It didn’t support canceling the upload. If we clicked on the cancel button, it stopped showing the progress on the front end but actually continued to upload the file to the server on the back end. We had only two choices: Either to refresh the page or just wait for the existing zip file to upload completely. The former is a really bad solution and the latter result in wastage of time and bandwidth.

On investigating the issue, the problem was with how the library is designed. This was not a fault in our code or the library either. It was just that the library didn’t support this functionality.  After thoroughly searching for the solutions, we came across this library named socket-io-stream which met our requirements. It supports bidirectional binary data transfer with Stream API through Socket.IO. We can also cancel the upload in between.

For streaming between server and client, we will send stream instances first. To receive streams, we just wrap socket with socket-io-stream and then listen for any events as usual.

Client Side:

function uploadFile(file) {
  // Calculating size of the file and creating a stream to be sent to the server

  var size = (file.size/(1024*1024)).toString().substring(0, 3);
  var stream = ss.createStream();

  /* Creating a read stream and initializing variable to keep track of the size of the file uploaded so far */

  var blobStream = ss.createBlobReadStream(file);
  var fileUploadSize = 0;

  // Tracking upload progress and updating the variables

  blobStream.on('data', function(chunk) {
    fileUploadSize += chunk.length;
    var percent = (fileUploadSize / file.size * 100);

    /* isCancelling is a boolean which stores the status of the zip upload.That is, whether it is live or canceled */

      if (isCancelling) {
           var msg = 'File upload was cancelled by user';
           stream.destroy();
           socket.emit('cancelled', msg);
           isCancelling = false;
           console.log(msg);
       }

       updateUploadProgress(Math.floor(percent));
       if (percent === 100) {
           uploadFinished = true;
           enableGenerateButton(true);
       }
     });

  // Sending the stream to the server and transferring read data to it

   ss(socket).emit('file', stream, {size: file.size, name: file.name});
   blobStream.pipe(stream);
}

Server Side:

// Importing the library
const ss = require('socket.io-stream');

// Listening to the stream sent from the client
ss(socket).on('file', function(stream, file) {
  generator.startZipUpload(socket.connId);

  // Declare a filename and write the incoming data to it
  var filename = path.join(__dirname, '..', 'uploads/connection-' + id.toString()) + '/upload.zip';

  stream.pipe(fs.createWriteStream(filename));
});

That’s all we need to do to stream data from the client to the server. Head over here for more information regarding the library.

Continue ReadingHandling Zip Upload in Open Event Webapp

Diving into the codebase of the Open Event Front-end Project

This post aims to help any new contributor to get acquainted with the code base of the Open Event Front-end project.

The open event front-end is primarily the front-end for the Open Event API server. The project provides the functionality of signing up, add, update and view events details and many other functions to the organisers, speakers and attendees of the event which can be concert, conference, summit or a meetup. The open event front-end project is built on a JavaScript web application framework Ember.js. Ember uses a library Ember data for managing the data in the application and for communicating with server API via endpoints. Ember is a battery included framework which means that it creates all the boilerplate code required to set up the project and create a working web application which can be modified according to our needs.

The open event front-end is primarily the front-end for the Open Event API server. The project provides the functionality of signing up, add, update and view events details and many other functions to the organisers, speakers and attendees of the event which can be concert, conference, summit or a meetup. The open event front-end project is built on a JavaScript web application framework Ember.js. Ember uses a library Ember data for managing the data in the application and for communicating with server API via endpoints. Ember is a battery included framework which means that it creates all the boilerplate code required to set up the project and create a working web application which can be modified according to our needs.

For example: When I created a new project using the command:

$ ember new open-event-frontend

It created a new project open-event-frontend with all the boilerplate code required to set up the project which can be seen below.

create .editorconfig
create .ember-cli
create .eslintrc.js
create .travis.yml
create .watchmanconfig
create README.md
create app/app.js
create app/components/.gitkeep
Installing app
create app/controllers/.gitkeep
create app/helpers/.gitkeep
create app/index.html
create app/models/.gitkeep
create app/resolver.js
create app/router.js
create app/routes/.gitkeep
create app/styles/app.css
create app/templates/application.hbs
create app/templates/components/.gitkeep
create config/environment.js
create config/targets.js
create ember-cli-build.js
create .gitignore
create package.json
create public/crossdomain.xml
create public/robots.txt
create testem.js
create tests/.eslintrc.js
create tests/helpers/destroy-app.js
create tests/helpers/module-for-acceptance.js
create tests/helpers/resolver.js
create tests/helpers/start-app.js
create tests/index.html
create tests/integration/.gitkeep
create tests/test-helper.js
create tests/unit/.gitkeep
create vendor/.gitkeep
NPM: Installed dependencies
Successfully initialized git.

Now if we go inside the project directory we can see the following files and folders have been generated by the Ember-CLI which is nothing but a toolkit to create, develop and build ember application. Ember has a runtime resolver which automatically resolves the code if it’s placed at the conventional location which ember knows.

➜ ~ cd open-event-frontend
➜ open-event-frontend git:(master) ls
app  config  ember-cli-build.js  node_modules  package.json  public  README.md  testem.js  tests  vendor

What do these files and folders contain and what is their role in reference to the project, “Open event front-end”?

Directory structure of open event frontend project

Fig 1: Directory structure of the Open Event Front-end project

Let’s take a look at the folders and files Ember CLI generates.

App: This is the heart of the project. It is responsible for deciding how our application will look and work. This is the place where folders and files for models, components, routes, templates and styles are stored. The majority of our application’s code is written in this folder. The adapter directory contains the application.js file which is responsible for authorising all outgoing API requests. Since our application is an event application so it has various screens which display the list of events, sessions, schedule, speakers, functionality to add, delete, modify the event details etc. Most of the screens have some features in common which can be reused everywhere inside the application which is kept in components directory. The controllers directory contains the files which will be responsible for the front-end behaviour which is not related to the models of our application. For example actions like sharing the event details. The data of the event is fetched by API but when the share functionality has to work is decided by the controller. Models directory helps in mapping the format of data i.e. in which format the data is fetched from the API. As we interact with the application, it moves through many different states/screens using different URLs. The routes directory decides which template will be rendered and which model will be loaded to display the data in the current template. The services directory contains the services which kept on running in the application like authentication service to check whether the current user has logged in or not, translation service to translate the details into some other language other than English which is supported by the app if required. The styles directory contains .scss files for styling of layouts. The template directory contains the layouts for the user interface of the application in form of Handlebar Templates which contains the HTML code which will be rendered on the screen when the template will be called via routes. The utils directory contains all the utility files like the format of date and time, demographic details, event type, type of topics etc.   

Directory structure of App folder

Fig 2: Directory structure of the app folder

Config: It contains files where we can we configure the settings of our application. The environment.js file contains the details like application name and API endpoints and other details required to configure the application. The deploy.js file contains the configurational details about the deployment.

Directory structure of config folder

Fig 3: Directory structure of config folder

Mirage: It contains the files which are required to mock the API server. Since we need to fetch the data from the server so whenever we make a request to get and post the data, mirage will respond to that data. It also contains the file which helps in seeding fake data for the application. Here mocking means creating objects that simulate the behaviour of real objects. The default.js application handles the seeding the fake data but currently, we don’t require that hence it’s empty. The config.js file has the method which sets the API host and namespace of the application.

Directory structure of mirage folder

Fig 4: Directory structure of mirage folder

Node_modules: As we know that Ember is built with Node and uses various node.js modules for functioning. So this directory contains all the files generated from the running the npm package manager which we run at starting while installing and setting up the project on the local device. The package.json file contains all the file maintains the list of npm dependencies for our app.

Public: This directory contains all the assets such as images and fonts related to the application. In the case of our application, to add images apart from the ones that are fetched from the API, they have to be placed here.

Directory structure of public folder

Fig 5: Directory structure of public folder

Translations: Since our application provides various languages support so this directory contains the files to translate the messages.

Directory structure of translations folder

Fig 6: Directory structure of translations folder

Tests: This is the best feature which Ember has provided. We don’t have to generate test they are automatically generated by the Ember-CLI which can be modified according to our requirements. Ember generates three types of test which are Acceptance, Integration and Unit tests. Other than that Ember offers testing for helpers, controllers, routes and models. Test runner of Ember-CLI testem is configured in testem.js. All three types of test have been used in our application.

Directory structure of test folder

Fig 7: Directory structure of test folder

ember-cli-build.js: This file contains the detail how Ember CLI should build our app. In the case of our project, it contains all the metadata such as app imports and other details to build the app.   

Vendor: This directory usually contains all the front-end dependencies (such as JavaScript or CSS) which are not managed by Bower go (which is a package manager for managing components that contain HTML, CSS, JavaScript, fonts). But in the case of our project, we have only kept .gitkeep inside this since we have not included any dependency which Bower doesn’t maintain.

To summarise, this post explains about the content and the role of different files and folders in the directory structure of the Open Event Front-end Project which may help a new contributor to get started by getting a basic understanding of the project.

Continue ReadingDiving into the codebase of the Open Event Front-end Project

Creating functional components in Ember JS in Open Event Front-end

In the Open Event Front-end using Ember JS we are creating a functional ticket ordering component which lets users select the amount of tickets and update the total & subtotal price accordingly. How are we doing it?

Creating a component

Components in ember are modular widgets which are used to define a single HTML element, as an independent element. Components can be reused without any dependencies across the project. This provides us a modular architecture to define a component once and reuse it across the project.

For creating a new component use:

ember g component ticket-component

In ember all components must have at least one hyphen in their name. This is an Ember convention, but it is an important one as it ensures there are no naming collisions with future HTML elements. After execution of the above command three new files are generated in the project under:

  • app/components: Contains the logic of the component.
  • app/templates: Contains the view of the component.
  • tests/integration/components: Contains all tests related to component.

Passing an array of ticket detail to template

We can pass data from APIs to the templates using ember-data, but for simplicity we are passing an array of dummy data to get it working. To pass the array to the template we need to add the following JSON to the application controller under controllers/application.js in the application.

tickets:[
  {
    description: 'Discounted ticket for all community members',
    date: 'Mon, May 22',
    price: 40.50,
    name: 'Community Ticket',
    type: 'paid',
    id: 1,
    quantity: 10,
    orderQuantity: 0,
    min: 0,
    max: 5
  }
]

For passing the data to the component template we need to pass the above object to the template using the following syntax in the application.hbs route.

{{public/ticket-component tickets=tickets}}

Rendering ticket details

We iterate over the tickets array passed by application.hbs using each handlebars helper, and we are also using semantic ui dropdown.

For computing subtotals we are using a ember-math-helpers which can be installed using

ember install ember-math-helpers

The semantic ui dropdown is used for selecting the number of orders. This allows us to bind a hidden field for storing the selected value from the dropdown.

{{#ui-dropdown class='compact selection' forceSelection=false}}
 {{input type='hidden' id=(concat ticket.id '_quantity') value=ticket.orderQuantity}}
{{/ui-dropdown}}

For downloading semantic-ui to the project we use:

ember install semantic-ui-ember

Computing subtotal using ember-math-helpers using the mult function which multiplies the price of tickets and the number of order selected from the dropdown.

<td id='{{ticket.id}}_subtotal' class="ui right aligned">
  $ {{number-format (mult ticket.orderQuantity ticket.price)}}
</td>

Computing total price of ordered tickets

To compute total price we are using computed properties which lets us observe properties in the component and compute other properties which are dependent on it. We add a computed property for the orderQuantity property associated with each of the tickets and update the total accordingly.

total: computed('tickets.@each.orderQuantity', function() {
  let sum = 0.0;
  this.get('tickets').forEach(ticket => {
    sum += (ticket.price * ticket.orderQuantity);
  });
  return sum;
})

This ensures an update of the total if any changes are made to the orderQuantity property of any ticket.

 

Continue ReadingCreating functional components in Ember JS in Open Event Front-end

Recyclerview in Open Event Android: A great upgradation to ListView

Recently, I was fixing a trivial bug in the Open Event Android app, an interesting thing caught my attention. Most of the lists in the app where actually not implemented using the traditional ListView, but instead used something called RecyclerView. The beautiful transitions that make this app the beauty it is, is due to the amazing and easy to code Recycler Views used in it.

A screen shot showcasing the simplicity of the FOSSASIA Open event android app.

 

List View is one among the various views that Android provides. In a nutshell, it is literally a group of generic views in Android. Why then use an entire new and more complex view, if all that it offers is a number of views displayed together? Well, it certainly has certain add-ons to the most generic set of views like Image and TextViews in Android.

I encourage you to think about what different could the ListView be as compared to multiple declarations of TextView. The thing with multiple declarations of a Text or Image View is that they aren’t “scrollable”, that is, if you want numerous Views in a single activity, without List View, you will have to fit them on one screen, else make another activity. So, if you want a scrollable view with same basic view items, List View is the way to go about it in Android.

The next question that may arise is:

How does a Listview work?

Google defines Adapters as “a bridge between an AdapterView and the underlying data for that view”. List Views use Adapters that retrieve data from Arrays, Lists and other data structures and queries, plugs them into our List View and thus, creates a beautiful looking List in no time. In Spite of all this, List View certainly lags in various fields that deal with performance, memory and compactness issues. As a great improvement Recycler View was introduced.

Using Recyclerview you are not restricted to vertical scrollable views. It has the ability to provide horizontal, vertical, grid and staggered layouts among others, with the help of different layout managers:-

recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
recyclerView.setLayoutManager(new LinearLayoutManager(RecyclerView_Activity.this,LinearLayoutManager.HORIZONTAL, false));

RecyclerView.ItemDecoration class allows us to add special drawings to our view. Thus, we can add dividers, borders and much more using this class.

public class DividerItemDecoration extends RecyclerView.ItemDecoration {
 
     private Drawable mDivider;
 
     public DividerItemDecoration(Drawable divider) {
         mDivider = divider;
     }

Adding animation used to be a devil of a task in Listview days, however with the release of Recyclerview, it has become a lot more easy. RecyclerView.ItemAnimator class helps in animating items while the adapters are being changed.

Next, we have something related to the performance:-

In a List View, you might have come across the term, ‘Viewholder’, but if you haven’t, that’s okay too. However, in Recyclerview, using View Holders have been made mandatory and for a good reason. The class goes by the name RecyclerView.ViewHolder.

What exactly are View Holders?
The clean dividers and minimal design in the Recyclerview makes up for a subtle UI.

In a broader sense, it is used to provide information about the identity of an itemView and it’s position within a Recyclerview. Without View Holders we have an overhead of calling the function findViewById() for every item in our Recyclerview! This upgradation from the typical findViewById() to View Holders awards us with better and more smooth scrolling through the list.

How does Recyclerview work?

List View is an ancestor to Recyclerview. Recyclerview has everything that List View offers to us (except for a few things like setchoicemode(), which I might take up in my upcoming blog posts), and much more.

A great achievement that Android achieved through Recyclerview has been it’s ability to “recycle” views on the way. In laymen terms, if you scroll through a Recyclerview, the views that go away from the screen during scrolling are the same views that come into the screen. The only difference is that the data in the views leaving the screen is changed to the data of the views entering your screen and so they are presented as new views. In this way, a Recyclerview helps saving memory for sure as compared to List Views.

There are still a lot of other things to learn about Recycler and List Views and you find more resources here.

 

Continue ReadingRecyclerview in Open Event Android: A great upgradation to ListView

Implementing Google Maps in Open Event ember Front-end

In the deployment of the Open Event Front-end on eventyay.com we want to show an event’s location on a map using Google Maps. Since Eventyay.com requires Google map to be used at several web pages, we can use Google map as an ember component for reusability.

How did we do it? The following walks you through the entire process.

The first step is to: Install g-map addon-

  • ember g-map, which is an addon, is available on ember add-on library which can be found at emberobserver.com. So first import that library using ember cli command
ember install ember-g-map
  • This command adds an ember-g-map module in our node_modules and also updated package.json file of our app now our ember-g-map modules contains the following directories. The following three are required to be highlighted that serves our purpose-
  • Addon/ – this directory contains all the implementation logic which acts as a prototype for the g-map component
  • App/- this directory basically exports a copy of g-map from our Addon/ directory to the web page where it is required. The export includes the logic implement inside the Addon/ directory which can later be imported by the parent app for use.Package.json – this file holds various metadata relevant to the ember-g-map

Generate Component-

  • The next step is to generate a component event-map (we can name our component anything we want but be sure to add a hyphen between the name). The component can be generated with the help of the following command of ember cli-
ember g component public/event-map

This will add three files in our app –

event-map.js located at app/component/public/event-map.js

event-map.hbs located at app/template/component/public/event-map.hbs

event-map-test.js located at tests/integration/component/public/event-map-test.js

Define Component-

Now let us use these files to add a google map component in our app-

  • First of all, we have to tell index.hbs about our new component that we are going to add. So we add our component {{public/event-map}} in our index.hbs file which is located at app/templates/public/index.hbs And we fetch latitude, longitude and location name from model and store in the event object and pass it to our component so that this information is available in the component.
<div class="location">
<h1 id="getting-here">{{t 'Getting Here'}}</h1>
 {{public/event-map event=model.event}}
</div>
  • The event-map.js file will be used to add ui grid class to assign a class to the div of the component. This will alleviate the redundancy regarding the creation of an extra div to enclose the component and then giving it the ui grid class.
import Ember from 'ember';
 
const { Component } = Ember;
 
export default Component.extend({
 classNames: ['ui', 'stackable', 'grid']
});
  • In our event-map.hbs we have with us the latitude, longitude, and locationName available and we are good to use our g-map addon. So in our event-map.hbs we can directly add g-map and g-map-marker but make sure that we pass lat and lang attributes to it. We can use custom options like backgroundColor, draggable etc. but here we have used street view and gestureHandling. gestureHandling is set as “cooperative” so that for smaller screen device,  zooming is possible only with two fingers so that scrolling would become easy.
<div class="eight wide column event-map">
 {{#g-map lat=event.latitude lng=event.longitude 
 zoom=12 gestureHandling='cooperative' 
 streetView='StreetViewPanorama' as |context|}}
 {{g-map-marker context lat=event.latitude lng=event.longitude}}
 {{/g-map}}
</div>
<div class="eight wide column address">
 <h1>{{t 'Address'}}</h1>
 <p>{{event.locationName}}</p>
</div>
  • Next we have to decide the size of aur google map canvas on which our map is to be displayed. We define the size of our canvas in the public-event.scss file which is located under styles/pages/public-event-scss.
.event-map > .g-map {
 height: 100%;
 width: 100%;
}
 
.event-map > .g-map > .g-map-canvas {
 height: 300px;
}
  • Lastly, we have to modify our event-map-test.js file. Here we perform integration test for our component. We create a dummy object with latitude, longitude, and locationName in it and pass it to our component and then check if it renders correctly or not.
import { test } from 'ember-qunit';

import moduleForComponent from 'open-event-frontend/tests/helpers/component-helper';

import hbs from 'htmlbars-inline-precompile';

moduleForComponent('public/event-map', 'Integration | Component | public/event map');

let event = Object.create({ latitude: 37.7833, longitude: -122.4167, locationName: 'Sample event location address' });

test('it renders', function(assert) {

  this.set('event', event);

  this.render(hbs `{{public/event-map event=event}}`);

  assert.equal(this.$('.address p').text(), 'Sample event location address');

});

Now use ember s command in our ember cli and visit localhost:4200

Then open a event at the end we see our Google map integrated.

Use ember test –server command to check if all our tests (integration, acceptance, etc.) are passed.

 

Find out more at – ember-g-map

Continue ReadingImplementing Google Maps in Open Event ember Front-end