Redirecting to Previous Route in Ember

The Open-Event-Frontend allows the event organiser to create tickets for his or her event. Other uses can buy these tickets in order to attend the event. In order to make the user experience smooth, we redirect the user to their previous route when they successfully login into their account. This blog explains how we have achieved this functionality in the project.

Insight

We have two different cases to handle in order to solve this problem:

  1. The user was in route A and wanted to move to route B. Here route A doesn’t require authorization and route B requires authorization. In this case, we would like to direct the user to the login route and once they are done, redirect them back to route B.
  2. The user was in route A and directly entered the login route using the login button. In this case we want to direct them back to the route A after successful login.

We use Ember-simple-auth in order to manage authentication in the project. Not only does it make it easy to manage authentication, it also handles the case 1 for us out of the box. So now the simplified problem is to redirect the user back to the previous route if they entered the login route directly using the web address or the login button.

Approach

If we can somehow store the previous route visited by a user, then we can easily redirect them back once they are logged in.

We will add a custom property in the session service called previousRouteName which will store the URL of the previous route visited by the user. We will make use of the willTransition hook in the application.js file. This hook is called everytime the user transitions from one route to another which makes it suitable for us to update the previousRouteName.

actions: {
    willTransition(transition) {
      transition.then(() => {
        let params = this._mergeParams(transition.params);
        let url;

        // generate doesn't like empty params.
        if (isEmpty(params)) {
          url = transition.router.generate(transition.targetName);
        } else {
          url = transition.router.generate(transition.targetName, params);
        }
        // Do not save the url of the transition to login route.
        if (!url.includes('login')) {
          this.set('session.previousRouteName', url);
        }
      });
    }
  }

_mergeParams is a helper function which makes use of merge function of the Lodash library.

/**
   * Merge all params into one param.
   * @param params
   * @return {*}
   * @private
   */
  _mergeParams(params) {
    return merge({}, ...values(params));
  },

Now we’re done with saving the URL of the previous route. All that remains is to trigger the redirect once the user has successfully logged in. We will use the sessionAuthenticated hook which is triggered everytime the user logs in.

sessionAuthenticated() {
    if (this.get('session.previousRouteName')) {
      this.transitionTo(this.get('session.previousRouteName'));
    } else {
      this._super(...arguments);
    }
  },

If the previous route variable is set, we redirect to it otherwise we can the super method and let Ember-simple-auth handle case 1 mentioned earlier for us.

References

Continue ReadingRedirecting to Previous Route in Ember

Implementing Badgename Update Functionality

Badgeyay project is divided into two parts i.e front-end with Ember JS and back-end with REST-API programmed in Python.

Badgeyay has many features related to enhancement in generation of badges. It gives choice of uploading data entries i.e by CSV or manually. There are options available for choosing Badge Background and font specifications. Now the next important thing from User perspective is that there should be a feature in My badges panel where user can see all badges & other details  and should be able to edit them if he want to, so moving forward with this feature I have implemented Badge Name update functionality in the frontend.

In this blog, I will be discussing how I implemented Update Badge Name functionality in my Pull Request so that the User can change his Badge Name  at any point of time in my badges panel.

Let’s get started and understand it step by step.

Step 1:

Create Badge Name component with Ember CLI.

$ ember g component badge-name

 

Step 2:

Make changes in Handlebar of Badge Name. We will be using semantic UI form for making the changes in Handlebars.

<form class="ui form" {{action 'updateBadgeName' on="change"}}>
    
class="ui icon input"> class="pen square icon"> {{input type="text" value=badge.badge_name }}
</form>

 

We have used action on submitting the Form for changing and updating the Badgename in Database.

Step 3:

We will now define the action in badge name JS file. We will also add the validations in Form so that empty form cannot be submitted to the server.

import Component from '@ember/component';
import Ember from 'ember';
const { inject } = Ember;
export default Component.extend({
  init() {
    this._super(...arguments);
  },
  notifications : inject.service('notification-messages'),
  actions       : {
    updateBadgeName() {
      this.get('sendBadgeName')(this.get('badge'));
    },
    didRender() {
      this.$('.ui.form')
        .form({
          inline : true,
          delay  : false,
          fields : {
            Name: {
              identifier : 'Name',
              rules      : [
                {
                  type   : 'empty',
                  prompt : 'Please enter a valid Badge Name'
                }
              ]
            }
          }
        });
    }
  }
});

 

Step 4:

We will now configure the controller to customize the action that we have defined above.

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default Controller.extend({
  routing       : service('-routing'),
  notifications : service('notification-messages'),
  actions       : {
    updateBadgeName(badge) {
      badge.save()
        .then(() => this.get('notifications').success('Badge Name Successfully Updated!', {
          autoClear     : true,
          clearDuration : 1500
        }));
    }
  }
});

 

Now, I am done with doing all the changes in Frontend.

Step 6:

Now run the Frontend & Backend to see the implemented changes.

  • My Badges Panel

Resources:

  1. Ember Docs –  Link
  2. Badgeyay Repository – Link
  3. Issue Link – Link
  4. Pull Request Link – Link
  5. Semantic UI –  LInk

 

Continue ReadingImplementing Badgename Update Functionality

Implementing Different Alignment for Different Line

Badgeyay project is divided into two parts i.e front-end with Ember JS and back-end with REST-API programmed in Python.

Badgeyay comes with many features for customising the process of generation of Badges. Now to provide more freedom to the user in generation of badges, I have worked on feature which will provide user more freedom in choosing different text alignment  for different lines and create badges more creatively.

In this Blog, I will be discussing how I implemented different text alignment for Different Line in Badgeyay Backend in my Pull Request.

To implement different text alignment for Different Line feature,  first, the component in SVG that is determining the text alignment of the label has to be identified. The label that determines the text on the badge is the <text> label and within it, the label that determines the properties of the text is <tspan>. So mainly we need to alter the properties in the tspan.

The property that determines the font type for the badge is text-align and its default value is set to start(right alignment). If the property in the labels changed, then we can see the corresponding changes in the PDF generated from the svg.

Now the challenges were:

  • To Determine the text-align value from the frontend.
  • Using the same for the text-align in SVG..
  • Changing the built SVG accordingly.

In this Blog, I will be dealing with changing the SVG in Backend according to text-align property provided by the User in the Frontend.

 def change_text_align(self,
                          filename,
                          badge_size,
                          paper_size,
                          align_1, // Values from Frontend
                          align_2,
                          align_3,
                          align_4,
                          align_5):

        """
            Module to change Text Alignment of each badge line
                :param `filename` - svg file to modify.
                :param `align_1` - Text Alignment to be applied on first line
                :param `align_2` - Text Alignment to be applied on Second line
                :param `align_3` - Text Alignment to be applied on Third line
                :param `align_4` - Text Alignment to be applied on Fourth line
                :param `align_5` - Text Alignment to be applied on Fifth line
        """
// Storing the Values passed altogether in a list.
        align = [1, align_1, align_2, align_3, align_4, align_5]
// Selecting the dimension config based on the parameters passed in the function.
        dimensions = badge_config[paper_size][badge_size]
        if config.ENV == 'LOCAL':
            filename = 'static/badges/' + dimensions.badgeSize + 'on' + dimensions.paperSize + '.svg'
        else:
            filename = os.getcwd() + '/api/static/badges/' + dimensions.badgeSize + 'on' + dimensions.paperSize + '.svg'
        tree = etree.parse(open(os.path.join(self.APP_ROOT, filename), 'r'))
        element = tree.getroot()

        for idx in range(1, dimensions.badges + 1):

            for row in range(1, 6):
                //Selecting the text element with the ID
                _id = 'Person_color_{}_{}'.format(idx, row)
                path = element.xpath(("//*[@id='{}']").format(_id))[0]
                style_detail = path.get("style")
                style_detail = style_detail.split(";")

                for ind, i in enumerate(style_detail):
                    if i.split(':')[0] == 'text-align':
                        style_detail[ind] = "text-align:" + align[row]
                style_detail = ';'.join(style_detail)
                text_nodes = path.getchildren()
                path.set("text-align", style_detail)

                for t in text_nodes:
                    text_style_detail = t.get("style")
                    text_style_detail = text_style_detail.split(";")
 // Fill the text-align argument of the selected object by changing the value of text-align.
                    text_style_detail[-1] = "text-align:" + align[row]
                    text_style_detail = ";".join(text_style_detail)
                    t.set("style", text_style_detail)

        etree.ElementTree(element).write(filename, pretty_print=True)
        print("Text Alignment Saved!")

 

After all the changes, the Updated SVG is used for Badge Generation with different text-align embedded.

Now, we are done with implementation of different text alignment  for Different Line in Badgeyay Backend.

Resources:

  1. Extracting map information from the SVG –  Link
  2. LXML documentation – Link
  3. Parsing the SVG – Link
  4. Badgeyay Repository – Link
  5. Issue Link – Link
  6. Pull Request Link – Link
Continue ReadingImplementing Different Alignment for Different Line

Implementing Different Font Type for Different Line

Badgeyay project is divided into two parts i.e front-end with Ember JS and back-end with REST-API programmed in Python.

Badgeyay comes with many features for customising the process of generation of Badges. Now to provide more freedom to the user in generation of badges, I have worked on feature which will provide user more freedom in choosing font types for different lines and create badges more creatively.

In this Blog, I will be discussing how I implemented Different Font types for Different Line in Badgeyay Backend in my Pull Request.

To implement Different Font type for Different Line feature,  first, the component in SVG that is determining the font of the label has to be identified. The label that determines the text on the badge is the <text> label and within it, the label that determines the properties of the text is <tspan>. So mainly we need to alter the properties in the tspan.

The property that determines the font type for the badge is font-family and its default value is set to sans-serif. If the property in the labels changed, then we can see the corresponding changes in the PDF generated from the svg.

Now the challenges were:

  • To Determine the font-type value from the frontend.
  • Using the same for the font-type in SVG..
  • Changing the built SVG accordingly.

In this Blog, I will be dealing with changing the SVG in Backend according to Font type provided by the User in the Frontend.

  def change_font_family(self,
                           filename,
                           badge_size,
                           paper_size,
                           Font_1, // Values from Frontend
                           Font_2, 
                           font_3,
                           font_4,
                           font_5):

        """
            Module to change Font Family of each badge lines
                :param `filename` - svg file to modify.
                :param `font_1` - Family to be applied on first line
                :param `font_2` - Family to be applied on Second line
                :param `font_3` - Family to be applied on Third line
                :param `font_4` - Family to be applied on Fourth line
                :param `font_5` - Family to be applied on Fifth line
        """
// Storing the Values passed altogether in a list.
        font = [1, font_1, font_2, font_3, font_4, font_5]
// Selecting the dimension config based on the parameters passed in the function.
        dimensions = badge_config[paper_size][badge_size]
        if config.ENV == 'LOCAL':
            filename = 'static/badges/' + dimensions.badgeSize + 'on' + dimensions.paperSize + '.svg'
        else:
            filename = os.getcwd() + '/api/static/badges/' + dimensions.badgeSize + 'on' + dimensions.paperSize + '.svg'
        tree = etree.parse(open(os.path.join(self.APP_ROOT, filename), 'r'))
        element = tree.getroot()

        for idx in range(1, dimensions.badges + 1):

            for row in range(1, 6):
               //Selecting the text element with the ID
                _id = 'Person_color_{}_{}'.format(idx, row)
                path = element.xpath(("//*[@id='{}']").format(_id))[0]
                style_detail = path.get("style")
                style_detail = style_detail.split(";")

                for ind, i in enumerate(style_detail):
                    if i.split(':')[0] == 'font-family':
                        style_detail[ind] = "font-family:" + font[row]
                style_detail = ';'.join(style_detail)
                text_nodes = path.getchildren()
                path.set("font-family", style_detail)

                for t in text_nodes:
                    text_style_detail = t.get("style")
                    text_style_detail = text_style_detail.split(";")
  // Fill the font family argument of the selected object by changing the value of font-family.
                    text_style_detail[-1] = "font-family:" + font[row]
                    text_style_detail = ";".join(text_style_detail)
                    t.set("style", text_style_detail)

        etree.ElementTree(element).write(filename, pretty_print=True)
        print("Font Family Saved!")

 

After all the changes, the Updated SVG is used for Badge Generation with different font type embedded.

Now, we are done with implementation of Different Font type for Different Line in

Badgeyay Backend.

Resources:

  1. Extracting map information from the SVG –  Link
  2. LXML documentation – Link
  3. Parsing the SVG – Link
  4. Badgeyay Repository – Link
  5. Issue Link – Link
  6. Pull Request Link – Link
Continue ReadingImplementing Different Font Type for Different Line

Implementing Different Font Size for Different Line

Badgeyay project is divided into two parts i.e front-end with Ember JS and back-end with REST-API programmed in Python.

Badgeyay comes with many features for customising the process of generation of Badges. Now to provide more freedom to the user in generation of badges, I have worked on feature which will provide user more freedom in choosing font sizes for different lines and create badges more creatively.

In this Blog, I will be discussing how I implemented Different Font Size for Different Line in Badgeyay Backend in my Pull Request.

To implement Different Font Size for Different Line feature,  first, the component in SVG that is determining the font size of the label has to be identified. The label that determines the text on the badge is the <text> label and within it, the label that determines the properties of the text is <tspan>. So mainly we need to alter the properties in the tspan.

The property that determines the font size for the badge is font-size and its default value is set to 31.25 px. If the property in the labels changed, then we can see the corresponding changes in the PDF generated from the svg.

Now the challenges were:

  • To Determine the font-size value from the frontend.
  • Using the same for the font-size in SVG..
  • Changing the built SVG accordingly.

In this Blog, I will be dealing with changing the SVG in Backend according to Font Size provided by the User in the Frontend.

def change_font_size(self,
                         filename,
                         badge_size,
                         paper_size,
                         Font_size_1, // Values from Frontend
                         font_size_2,
                         font_size_3,
                         font_size_4,
                         font_size_5):

        """
   Module to change size of each badge lines
   :param `filename` - svg file to modify.
   :param `font_size_1` - Size to be applied on first line
   :param `font_size_2` - Size to be applied on Second line
   :param `font_size_3` - Size to be applied on Third line
   :param `font_size_4` - Size to be applied on Fourth line
   :param `font_size_5` - Size to be applied on Fifth line
        """
// Storing the Values passed altogether in a list.
        font_size = [1, font_size_1, font_size_2, font_size_3, font_size_4, font_size_5]
// Selecting the dimension config based on the parameters passed in the function.
        dimensions = badge_config[paper_size][badge_size]
        if config.ENV == 'LOCAL':
            filename = 'static/badges/' + dimensions.badgeSize + 'on' + dimensions.paperSize + '.svg'
        else:
            filename = os.getcwd() + '/api/static/badges/' + dimensions.badgeSize + 'on' + dimensions.paperSize + '.svg'
        tree = etree.parse(open(os.path.join(self.APP_ROOT, filename), 'r'))
        element = tree.getroot()

        for idx in range(1, dimensions.badges + 1):

            for row in range(1, 6):
                 //Selecting the text element with the ID
                _id = 'Person_color_{}_{}'.format(idx, row)                 path = element.xpath(("//*[@id='{}']").format(_id))[0]
                style_detail = path.get("style")
                style_detail = style_detail.split(";")

                for ind, i in enumerate(style_detail):
                    if i.split(':')[0] == 'font-size':
                        style_detail[ind] = "font-size:" + font_size[row]
                style_detail = ';'.join(style_detail)
                text_nodes = path.getchildren()
                path.set("font-size", style_detail)

                for t in text_nodes:
                    text_style_detail = t.get("style")
                    text_style_detail = text_style_detail.split(";")
   // Fill the font size argument of the selected object by changing the value of font-size.
                    text_style_detail[-1] = "font-size:" + font_size[row]
                    text_style_detail = ";".join(text_style_detail)
                    t.set("style", text_style_detail)

        etree.ElementTree(element).write(filename, pretty_print=True)
        print("Font Size Saved!")

 

 

After all the changes, the Updated SVG is used for Badge Generation with different font size embedded

Now, we are done with implementation of Different Font Size for Different Line in

Badgeyay Backend.

Resources:

  1. Extracting map information from the SVG –  Link
  2. LXML documentation – Link
  3. Parsing the SVG – Link
  4. Badgeyay Repository – Link
  5. Issue Link – Link

Pull Request Link – Link

Continue ReadingImplementing Different Font Size for Different Line

Implementing Password Update Functionality

The Badgeyay  Ember JS frontend has many features like Login and Sign up features and Login with OAuth and most important, the badge generation feature is also up and running. Now the next important thing from User perspective is that there should be a settings panel where user can see its account details like username, Email & password and he should be able to change them if he want to.

I have implemented the setting panel in Badgeyay where user can see his account details. In this blog, I will be discussing how I implemented Update Password functionality in my Pull Request so that the User can change his Password at any point of time.

Let’s get started and understand it step by step.

Step 1:

Generate User Password component with help of ember cli.

Step 2:

Make changes in Handlebar of User Password. We will be using semantic UI form for making the changes in Handlebars.

<h2 class="ui header">Password</h2>
<h5 class="ui dividing header">Change your password.</h5>
<form class="ui form" {{action 'updateUserPassword' on="submit"}}>
    
class="field"> New Password
class="fields">
class="ten wide field"> {{input type="password" id="newPassword" name=newPassword value=user.password}}
</div> </div>
class="field"> Verify Password
class="fields">
class="ten wide field"> {{input type="password" id="newPasswordVerify" name=newPasswordVerify placeholder="Re-enter Password"}}
</div> </div> <button type="submit" class="ui basic orange button" tabindex="0"> Save Changes </button> </form>

 

We have used action on submitting the Form for changing and updating the Password in Database and Firebase.

Step 3:

We will now define the action in user component JS file. We will also add the validations in Form so that empty form cannot be submitted to the server.

import Component from '@ember/component';
export default Component.extend({
  init() {
    this._super(...arguments);
  },
  actions: {
    updateUserPassword() {
      let password = this.get('newPassword');
      this.get('sendUserPassword')(password);
    }
  },
  didRender() {
    this.$('.ui.form')
      .form({
        inline : true,
        delay  : false,
        fields : {
          newPassword: {
            identifier : 'newPassword',
            rules      : [
              {
                type   : 'empty',
                prompt : 'Please enter a password'
              },
              {
                type   : 'minLength[6]',
                prompt : 'Your password must have at least {ruleValue} characters'
              }
            ]
          },
          newPasswordVerify: {
            identifier : 'newPasswordVerify',
            rules      : [
              {
                type   : 'match[newPassword]',
                prompt : 'Passwords do not match'
              }
            ]
          }
        }
      });
  }
});

 

Step 4:

We will now configure the controller to customize the action that we have defined above.

.......
export default Controller.extend({
  routing : service('-routing'),
  notify  : service('notify'),
  uid     : '',
  actions : {
...............
   updateUserPassword() {
      this.get('user').save()
        .then(() => this.get('notify').success('Password Successfully Updated!'))
    }
  }
});

 

Step 5:

We have configured the frontend for sending the details to backend. Now, we have to edit the endpoint so that if Password changes in params, It should change the password and send the response with the updated user schema.

api/controllers/registerUser.py
...............
   if 'password' in data.keys():
        user.password = data['password']
        update_firebase_password(user.id, user.password)
        user.save_to_db()

 

Now, I am done with doing all the changes in backend API and Frontend.

Step 6:

Now run the Frontend & Backend to see the implemented changes.

  • User password Panel

Now, we are done with implementation of Update password Functionality.

Resources:

  1. Ember Docs –  Link
  2. Badgeyay Repository – Link
  3. Issue Link – Link
  4. Pull Request Link – Link
  5. Semantic UI –  LInk
Continue ReadingImplementing Password Update Functionality

Implementing User-name Update Functionality

The Badgeyay  Ember JS frontend has many features like Login and Sign up features and Login with OAuth and the most important, the badge generation feature is also up and running. Now the next important thing from User perspective is that there should be a settings panel where user can see its account details like username, Email & password and he should be able to change them if he want to.

I have implemented the setting panel in Badgeyay where user can see his account details. In this blog, I will be discussing how I implemented Update Username functionality in my Pull Request so that the User can change his username at any point of time.

Let’s get started and understand it step by step.

Step 1:

Generate User account component with help of ember cli.

$ ember g component user-component/user-account

 

Step 2:

Make changes in Handlebar of User Account. We will be using semantic UI form for making the changes in Handlebars.

// user-account.hbs

<h2 class="ui dividing header">Account</h2>
<form class="ui form" {{action 'updateUserName' on="submit"}}>
    
class="ui field"> Username
class="ui fields">
class="ten wide field"> {{input type="text" id="profileName" name=profileName value=user.username}}
</div> </div>
class="ui field"> Email
class="ui fields">
class="ten wide disabled field"> {{input type="email" name=email value=user.email}}
</div> </div> <button type="submit" class="ui basic orange button" tabindex="0" >Save Changes</button> </form>

 

We have used action on submitting the Form for changing and updating the username in Database and Firebase.

Step 3:

We will now define the action in user component JS file. We will also add the validations in Form so that empty form cannot be submitted to the server.

import Component from '@ember/component';
export default Component.extend({
  init() {
    this._super(...arguments);
  },
  actions: {
    updateUserName() {
      let profileName = this.get('profileName');
      this.get('sendUserName')(profileName);
    }
  },
  didRender() {
    this.$('.ui.form')
      .form({
        inline : true,
        delay  : false,
        fields : {
          username: {
            identifier : 'profileName',
            rules      : [
              {
                type   : 'empty',
                prompt : 'Please enter a valid username'
              }
            ]
          }
        }
      });
}});

 

Step 4:

We will now configure the controller to customize the action that we have defined above.

…….
export default Controller.extend({
  routing : service('-routing'),
  notify  : service('notify'),
  uid     : '',
  actions : {
…………...
   updateUserName(profileName) {
      const _this = this;
      const user = this.get('store').peekAll('user');
      user.forEach(user_ => {
        _this.set('uid', user_.get('id'));
      });
      _this.get('user').save();
      _this.get('notify').success('Username Successfully Updated!');
    }
  }
});

 

Step 5:

We have configured the frontend for sending the details to backend. Now, we have to edit the endpoint so that if username is change in params, It should change the username and send the response with the updated username.

api/controllers/registerUser.py
…………...
   if 'username' in data.keys():
        user.username = data['username']
        update_firebase_username(user.id, user.username)
        user.save_to_db()

 

Now, I am done with doing all the changes in backend API and Frontend.

Step 6:

Now run the Frontend & Backend to see the implemented changes.

User Account Panel

Now, we are done with implementation of Update Username Functionality.

Resources:

  1. Ember Docs –  Link
  2. Badgeyay Repository – Link
  3. Issue Link – Link
  4. Pull Request Link – Link
  5. Semantic UI –  LInk
Continue ReadingImplementing User-name Update Functionality

Integrate static maps API in an android project

This blog article will illustrate about how an event is located on a map in the Open Event Android app. The app found it necessary to have a feature where users will be able to view the location of the event they are interested in. So we, at Open Event Android took a different approach to map out the location. Let us delve into that !

Google provides us with two ways to map out a location in an android app. One requires us to implement the GoogleMaps Sdk, which is a quite a tiresome process. But the other is a quite less popular way and it doesn’t receive enough recognition. It is the static maps API approach.

This API by Google had been released quite a few years ago and is seemingly one of the most useful and interesting APIs among all of them. So the question is, how does this fit in ?

It is a simple API to use. We provide latitude and longitude of a place. The API then sends us an image response which shows us exactly where the place is located in a world map. Quite Unique!

Let us run through the steps about how it is implemented in the Open Event Android app.

The project uses Picasso to load images as it has a cache feature, which basically means it stores the image as long as the app is running. To start with, the code below shows how to load an image.

//load image

Picasso.get()

      .load(loadMap(event))

      .placeholder(R.drawable.ic_map_black_24dp)

      .into(rootView.image_map)

This will seem to a bit complex at first, but lets just head into it steadily.

.load() function is used to load an image from a given URL. .placeholder() is used to provide the view with a placeholder image if the image hasn’t been loaded properly. .into() is used to load the image ( or the placeholder ) into the view.

We can see that in the .load() function, we are using another function .loadMap(). Let us go through the .loadMap() function

fun loadMap(event: Event): String{

  //location handling

  val mapUrlInitial = “https://maps.googleapis.com/maps/api/staticmap?center=”

  val mapUrlProperties = “&zoom=12&size=1200×390&markers=color:red%7C”

  val mapUrlMapType = “&markers=size:mid&maptype=roadmap”
  val latLong: String = “” +event.latitude + “,” + event.longitude
  return mapUrlInitial + latLong + mapUrlProperties + latLong + mapUrlMapType

}

The .loadMap() function has many declared variables. This is the heart of the whole process.

So what is required for the static maps API to give us an image is that we make an http request with a given url, for which an image response (URL) is received. Let us run through the meaning and utility of these variables. Yes, all of them have a completely different meaning!

The mapUrlInitial variable is always the same while making an API call. It has a query of center ( ?center ) which specifies that we want the location to be centered in the map.

The mapUrlProperties variable contains a string where you control the actual zooming of the image response you will get, the size ofthe image and the color of the marker which will point out our place.

The mapUrlMapType variable is a string where you can actually determine the marker size you want and the type of the map. We are using a roadtype map in the app.

Finally latLong is a string which concatenates the latitude and the longitude of the place we want to pinpoint!

We then concatenate all of these strings to form a feasible Url. The Url is then loaded as we have seen above, in the Picasso code. One thing we can notice is that an event object is always required for all of this to happen, because we are able to fetch the position details using the event object! Final Code:-

fun loadMap(event: Event): String{

  //location handling

  val mapUrlInitial = “https://maps.googleapis.com/maps/api/staticmap?center=”

  val mapUrlProperties = “&zoom=12&size=1200×390&markers=color:red%7C”

  val mapUrlMapType = “&markers=size:mid&maptype=roadmap”
  val latLong: String = “” +event.latitude + “,” + event.longitude
  return mapUrlInitial + latLong + mapUrlProperties + latLong + mapUrlMapType

}
//load image

Picasso.get()

      .load(loadMap(event))

      .placeholder(R.drawable.ic_map_black_24dp)

      .into(rootView.image_map)

After all this doing, we are finally able to receive the static image perfectly.

References

Tags: GSoC18, FOSSASIA, Open Event, Android, Static Maps API

Continue ReadingIntegrate static maps API in an android project

Implementing Pagination for listing Badges

Badgeyay project is divided into two parts i.e front-end with Ember JS and back-end with REST-API programmed in Python.

Badgeyay comes with many features for customising the process of generation of Badges. Badgeyay also keeps record of all the badges generated by user and also gives option to directly download the previously generated badges.
All the badges appear on single page which creates problem when a user has generated lot of badges and all the badges listed on single page.

To resolve this issue and make Badgeyay more user friendly I have implemented pagination in listing badges so that if there are more number of badges, user can see the badges listed in multiple pages in my Pull Request.

To implement this, I have used actions and made the changes accordingly.

Let’s get started and understand it step by step.

Step 1:

We will use semantic icons in handlebars for changing pages.

Step 2:

I will add action for changing page to next and previous page.

// components/user-component/my-badges.js 

import Component from '@ember/component';
import Ember from 'ember';
const { inject } = Ember;
export default Component.extend({
  queryParams : ['page'],
  page        : 1,
  notify      : inject.service('notify'),
  actions     : {
    nextPage() {  // Action for Next Page
      let filter = {};
      if (this.page > 1) {
        filter.page = this.page + 1;
        this.get('store').query('my-badges', filter)
          .then(records => {
            if (records.length > 0) {
              this.set('my-badges', records);
              this.set('page', this.page + 1);
            } else {
              this.notify.error('No More Badges found');
            }
          })
          .catch(err => {
            this.get('notify').error('Please try again!');
          });
      } else {
        this.notify.error('No More Badges Found');
      }
    },
    prevPage() {  // Action for Previous Page
      let filter = {};
      if (this.page - 1 > 0) {
        filter.page = this.page - 1;
        this.get('store').query('my-badges', filter)
          .then(records => {
            this.set('my-badges', records);
            this.set('page', this.page - 1);
          })
          .catch(err => {
            this.get('notify').error('Please try again!');
          });
      } else {
        this.notify.error('No More Badges Found');
      }
    }
  }
});

 

Step 3:

Now, We have to make the query for all badges generated by a user on opening the my-badges route in Frontend.

import Route from '@ember/routing/route';

import Ember from 'ember';

const { set } = Ember;

export default Route.extend({
  beforeModel(transition) {
    this._super(...arguments);
  },

  model(params) {
    let filter = {};
    this.set('params', params);
    filter.state = 'all';
    filter.page = params.page;
    return this.get('store').query('my-badges', filter);
  }
});

 

I have implemented the pagination feature for listing all badges by the user.

 

Step 4:

Now run the server to see the implemented changes by following command.

My Badges Route with Pagination Feature:

Now we are done with implementing the pagination feature for listing all badges by the user.

Resources:

  1. Ember Docs –  Link
  2. Badgeyay Repository – Link
  3. Issue Link – Link
  4. Semantic UI –  LInk

 

Continue ReadingImplementing Pagination for listing Badges

Implementing Custom Tab Viewing on click of an Organizer link in Open Event Android

The Open Event Android app shows a list of organizer social links in the Event Details section. The API fetches the type of social link and the link to the page. For example, if a facebook icon based link is clicked, the default browser will open the facebook page of the Organizer. Our aim was to open the page in the app itself so that the user won’t have to juggle between two different apps. This blog will thus illustrate about how the implementation of a CustomTab is done.

We will move onto the SocialLinkViewHolder file. There we will remove the code for which an explicit intent used to be fired everytime a SocialLink was clicked. We initially add the dependency to the app.gradle file.

implementation “com.android.support:customtabs:27.1.1”

We can clearly observe that custom tabs is supported by the Support library of Android.

We add another field in SocialLinksViewHolder model class. This field will be a Context type field. context will be required in future steps.

class SocialLinksViewHolder(itemView: View, private var context: Context) : RecyclerView.ViewHolder(itemView) {

}

Our next step is to change the overridden function  onCreateViewHolder in the the SocialLinks RecyclerAdapter class. We will now return both the view and the parent context in the method. We return parent context, as it is required in the ViewHolder.

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SocialLinksViewHolder {

  val view = LayoutInflater.from(parent.context).inflate(R.layout.item_social_link, parent, false)

  return SocialLinksViewHolder(view, parent.context)

}

We now declare the function showCustomTab() in the bind function of the SocialLinkViewHolder class. Error will be resolved as we still haven’t initialised the function showCustomTab(). This function will be fired only when the link is clicked. That’s why we are firing the function in the onClickListener of itemView

fun bind(socialLink: SocialLink) {

 …

 …
  itemView.setOnClickListener{

      setUpCustomTab(context, socialLink.link)

  }

}

Heading onto initialising the function showCustomTab(). The below code represents the function.

private fun setUpCustomTab(context: Context, url: String) {

  var finalUrl = url

  if (!url.startsWith(“http://”) && !url.startsWith(“https://”)) {

      finalUrl = “http://$url

  }
  CustomTabsIntent.Builder()

          .setToolbarColor(ContextCompat.getColor(context, R.color.colorPrimaryDark))

          .setCloseButtonIcon(BitmapFactory.decodeResource(context.resources, R.drawable.ic_arrow_back_white_cct_24dp))

          .setStartAnimations(context, R.anim.slide_in_right, R.anim.slide_out_left)

          .setExitAnimations(context, R.anim.slide_in_left, R.anim.slide_out_right)

          .build()

          .launchUrl(context, Uri.parse(finalUrl))

}

Breaking the function into two parts. Firstly, we are verifying the validity of the Url. We are appending http:// to the Url if the Url is not present like that. We skip it, if it is indeed a valid Url

var finalUrl = url

  if (!url.startsWith(“http://”) && !url.startsWith(“https://”)) {

      finalUrl = “http://$url

  }

Then, comes the actual part of the CustomTabsIntent builder. We create a Chrome CustomTab by setting properties regarding toolbar colour, close-button icon, starting and ending animations!

  CustomTabsIntent.Builder()

          .setToolbarColor(ContextCompat.getColor(context, R.color.colorPrimaryDark))

          .setCloseButtonIcon(BitmapFactory.decodeResource(context.resources, R.drawable.ic_arrow_back_white_cct_24dp))

          .setStartAnimations(context, R.anim.slide_in_right, R.anim.slide_out_left)

          .setExitAnimations(context, R.anim.slide_in_left, R.anim.slide_out_right)

          .build()

          .launchUrl(context, Uri.parse(finalUrl))

setToolbarColor is used to set the toolbar colour of the intent. In this case it was our colourPrimaryDark. setCloseButtonIcon() takes a close icon Bitmap as input. setStartAnimations() takes care of the animation which will occur when the Tab is opened.

build will build the CustomTabIntent and launchUrl will launch the TabIntent with the url being finalUrl.

Thus, we can are clearly able to achieve the feat of showing the web page in the app itself using a CustomTab.

Additional Resources

Tags: GSoC18, FOSSASIA, Open Event, Android, CustomTabsIntent

Continue ReadingImplementing Custom Tab Viewing on click of an Organizer link in Open Event Android