React Placeholder loading state

Loading Messages

It seems like loading transitions and states come and go over time, and people try to get as creative as they can with them. Making cool animations from parts of their logo’s, to using nice imagery to give the impression of loading, You only need to search around your favorite search engine to find some amazing examples of loading UI’s.

It may of been around longer that I think, but it seems the “placeholder” style loading UI is becoming a lot more popular this days, or maybe it’s just the site’s I visit most regular are starting to use them. Even that popular that I have been working on a “placeholder” loader for my day job. Just in case your wonder what I am calling a “placeholder” loader, it’s a loading UI that simulates the look of the content that will be loaded but using a wireframe like design. So a user will see some shapes that are light in color.

Sample Placeholder loading UI


You may or may not of seen something very similar used on Facebook, the image is taken from a blog post that explain’s how it’s achieved. After reading the post, I was quite surprised on the amount of markup needed to achieve the desired affect. Having a requirement to produce a similar looking loading UI for a project I took some time to see if there was a nicer approach for the project I was needing to apply it to. The project I was going to be applying this too was a little simpler in terms of what was being displayed to the user, the UI I was going to be applying this to was a list of messages, consisting of an icon, couple items of text and another icon.

Rather than use div’s to mask the background and fill in the spot’s that I did not want to show the background animation, I used the elements of the messages from a loaded state to apply a loading state on to. Example of my demo can be seen here, with the code available on GitHub.

In the demo a message has a title and a created prop in it’s loaded state which should be text, which is what you see once the messages have been loading (in the case of the demo I use a setTimeout to simulate loading). To get the loading affect I set up the react component with some initial state for the messages, but with the values of the props empty, also telling the component we are in a loading state which applies a placeholder class to the messages div, then using CSS I make the p’s in the message component have a min-height of 1em to ensure the blocks are rendered out as blocks rather than no appearing as the contents are empty.

While it’s not a one stop solution for all placeholder loading within a web application to simulate the content’s UI, for simple items it’s a nice simple solution to apply.

Two months I’ve been using for iOS and it’s been a better two months with it. Just noticed they even have an extension for Safari on the Mac which I use as my browser for general browsing.

I recommend you install them both if you are running iOS or Mac, not just for less ads on sites, but also for a safer online experience. All round it’s better!

Pot of tea for one

Photo taken at: Starbucks Dumfries

Little walk at Mabie

Photo taken at: Mabie Forest

Clothes folder. Best invention ever for keeping your drawers tidy!

Old vs New, before and after.

GitHub Project Pages Source

GitHub Pages Repository Settings

Something I recently found out was you serve your GitHub repositories on your domain like so: <username><repository-name>. So I have and I wanted to add a page for one of repositories so people could see a demo of the code. After some time just waiting for GitHub to deploy the page it was beginning to fell like I was missing a piece of the puzzle. The site was all working, but trying to visit the project page: was giving me 404. After some searching around I was not getting my info on what I was missing then I discovered there is a setting inside of the repository settings to turn on GitHub pages for repository. My guess is that I was using the Master branch, this leading it to not be active by default. Quick switch in the settings to tell it to use master and within minutes I could see my project page in all it’s glory.

Slack command with API Gateway and AWS Lambda

Stop Sprint 99, and the winner is...

At work we operate the Agile methodology and work in two week sprints. At the end of each sprint we hold the retrospective, something that was introduced a few sprints back was to vote for the past sprints MVP (Most Valuable Player), or as I like to say; Most Valuable Programmer. At the end of the sprint the team leads ask’s for everyone to send their votes for MVP, and for a couple of days up to the sprint this is asked over and over, and also asked during the retro. So I made an assumption, of why people might not be voting.

People are not voting due to in not being anonymous

With this in mind, and having wanted to make a bot for Slack I thought it could not be too hard to create a slack command that users could use to cast their vote for MVP.

For it to be simple and not get too complicated the minimum requirements I set myself were:

  1. People votes by using a slack command and the users name eg: /mvp @matthewroach
  2. You can not vote for yourself
  3. You can only vote once
  4. Voting is per sprint, need a way to start and stop voting
  5. Only one active vote topic at a time
  6. Upon stopping the vote the bot would send an in channel message saying who the winner was

Maybe not a small list to accomplish. Over the course of a weekend I created a slack command that did all the above.

One requirement that Slack enforce for integrations is that they must be using https. With this is mind and not wanting to set up SSL and host things myself for something that’s likely to used very infrequent. I decided to use AWS services to handle this, most notable API Gateway and Lambda, for storing the data I went with MongoDB using mLab, mainly because I am familiar with Mongo. mLab offer a free 500mb sandbox database that would be ideal for this.

Slack slash commands

Slash commands are commands that allow users to interact with a third party service. The part of the / (slash) is the command name, then any text after the command is used by the service to do what it needs to do. A slash command can use either a GET or POST request. I decided to use the POST verb to pass along the data from the command.

Slash commands can either post back to use anonymously, or send back the result to the channel it was triggered in. By default it’s anonymous. The other options that you have like better formatting of messages, attachments you can see at their documentation.

AWS API Gateway

API Gateway act’s as a “front door” for applications to access data, business logic or functionality from your back-end services.

API gateway is not limited to the AWS infrastructure, for the slack command I hooked up a POST interface to a lambda function.

Once you deploy your API to an environment, Amazon allows you to deploy your API to multiple stages so you can have a test, staging and production set up. With each stage you get a different URL you can use to call your endpoints with.

The UI for setting up API’s via the AWS console is not the greatest and takes quite a few clicks to go through the different steps. Also, when you hook up an API to a lambda function you need to create a body mapping template that will take the incoming requests and convert to a format you wish to consume in your lambda function. In this case I added a mapping for the content type: application/x-www-form-urlencoded that look like this:

## convert HTTP POST data to JSON for insertion directly into a Lambda function
## first we we set up our variable that holds the tokenised key value pairs
#set($httpPost = $input.path('$').split("&"))
## next we set up our loop inside the output structure
#foreach( $kvPair in $httpPost )
 ## now we tokenise each key value pair using "="
 #set($kvTokenised = $kvPair.split("="))
 ## finally we output the JSON for this pair and add a "," if this isn't the last pair
 "$kvTokenised[0]" : "$kvTokenised[1]"#if( $foreach.hasNext ),#end

Hopefully the comments in the code make it easy for you to understand what’s happening. Basically we are converting the form body slack pass us into a JSON object of key value pairs.

AWS Lambda

Is a serverless compute service that runs your code in response to events and automatically manages the underlying compute resources for you.

Lambda is where all the magic happens. I wrote some simple nodejs code that handles the different inputs from the slash command, does it’s logic, reads/stores data to MongoDB and then responds with a result for the user issuing the slack command.

I have pushed the code to a repository on my GitHub account if you wish to take a look at the node code.

As I mentioned earlier, I converted the incoming data from slack into a JSON object that is available to my node code under the event object. With this JSON object now available to me within my function I am able to look at the keys I need and do the required actions. The main thing we are after is the text key from the object this holds the text after the /mvp part of the slash command. I use this key to work out what action I should be taking from the caller.

There are only three commands available from to the user using /mvp; that is start, stop and voting. Voting is working about by looking for an @ as the first character of the text. If I don’t match either of these three, I tell the user you can not perform that action.

Some of the other keys I am using for the function is the team_domain, this is used to determine the mongoDB collection I need to look into. This keeps other teams data away for each other, and avoid having huge one huge collection of data. I also use the user_id to track if the user has voted already. The command does not track who voted for who, it will also not let you vote more than once, and you can only vote if we find an active mvp vote, which also means it’s only possible to have one mvp vote at a time.

I added some sample JSON files that I was using for testing the code locally. I used lambda-local to test my function locally, which makes for a much better experience than having to deal with the AWS interface all the time for writing code and testing.

Without going into great depths of lambda, you have up to three function arguments available to you within your main function, event, context, and callback. Data comes in on the event, context contains information about the lambda function that is executing and the callback is used to return information to the caller. The callback is an optional argument. You can read more about this in the lambda documentation.

Screenshots of working /mvp

Starting/ Opening the voting for a given item, I called this vote Sprint 99

Start Voting

Casting your vote for the MVP

/mvp @docbrown

Vote has been cast

Thank you, your vote has been cast

Stopping/ Closing the voting for Sprint 99 and seeing who was the MVP!

Stop Sprint 99, and the winner is...


Choosy Browser PickerBeing someone who uses different web browsers for different purposes. I primarily use Chrome and Chrome Canary for developing in, Safari for personal browsing and Opera for random other things. Having to set a default browser is a hard choice because I don’t always want links to open in the default browser. Take for example I want to open a link from the Twitter App, I would like this to be opened in Safari, but if someone messages me on Slack with a URL for a test server or production server issue I will want to open that in one of the Chrome browsers I have open for that environment. The same applies for emails, especially ones that come from ticket systems or source control emails, again I want these to open in the browser I am using for those sites.

Having recently moved back to Mac full time I was confident there would be an App or some solution to fill my needs, and one quick search found Choosy, a preference pane application for the Mac that does exactly want I want and more. After 24 hours of use I am sold, and purchased it.

A great feature of Choosy is you can set up rules so you don’t have to choose the browser you wish for link. You can do it based on URL, or the Application the link is coming from. I have a rule for any links from the Twitter App to open in Safari for example.