Migrating AngularJS html5mode links to Cordova

Gainstrack is implemented both for the desktop and for mobile – a true hybrid app. 90% of the code and views are shared with 10% having to be specifically customised.

One key difference is that a desktop AngularJS app looks much better with html5mode enabled so that URLs look natural without the # character. However, Cordova apps must have html5mode disabled. Thus links in vanilla <a href=”/foo”> tags would only work on one platform or the other but not both (only desktop in this case). It can be worked around by having links on both platforms like <a href=”#/foo”> and disabling html5mode link rewriting on the desktop side. However, clicking such a link on the desktop side would cause a page reload while Angular removes the #.

After hours of trying different solutions including Grunt building two different targets, trying to get html5mode working on Cordova, creating a urlFor method to put links in, in the end this simple snippet solved all problems on the mobile side.

angular.module('Gainstrack').directive('a', function() {
  return {
    priority: 1,
    restrict: 'E',
    link: function($scope, $element, $attrs) {
      $attrs.$observe('href', function (value) {
        if (value && value.indexOf('/') === 0) {
          $attrs.$set('href', '#' + value);

With this snippet only on the mobile side javascript, vanilla html5mode links are rewritten to hashbang links as required on the mobile side. Problem solved

Gainstrack 0.0.8 updates

A critical bug was found in 0.0.6 where one couldn’t edit historic workouts. That’s now fixed in 0.0.8. Assuming no more bugs found, I’ll also push this to the Android store.

In addition, thanks to feedback from “britPaul”, the workout planner is starting to make progress again – it is now unit aware like the rest of the site, able to handle planning in lbs or kgs. A fair amount of work is still needed for it to be truly useful though.

The only other technical update is the removal of the jQuery dependency. AngularJS doesn’t need jQuery and neither do I. That reduces the 3rd party javascript payload by 20%, which should result in slightly faster loads.

One final mention is my anecdotal testing of the mobile site is that it is definitely performing better on my phone! With all the changes, I can’t tell if it is Cordova, Angular or what but the speed increase is definitely useful.

Gainstrack 0.0.6 Updates

The website has been updated and the Android app will be updated in the app store shortly. Feature-wise, the main items are to fix the previously mentioned annoying issues

  • Navigating away from the app mid-workout and coming back – your workout will still be there
  • Using the app without internet reception will still allow you to record your workout
  • A news link so you can see this blog for updates

The last feature is only really for the Android app but if you are using the iPhone app, you can still pre-load by opening in reception and then using while out of internet reception.

Behind the scenes, a bunch of technical updates have been maded

Ideally these changes won’t have any functional changes but should boost performance a little by using libraries a year newer. On the other hand there may be a few glitches on the way. If so, please email or message me.

Annoying issues

So I’ve been back lifting regularly again and therefore been dogfooding my own app and mobile website. I like to log my workouts from my phone as I do them in the gym. Here are the most annoying things about my own app!

  • If you switch away from the app and your phone is low on memory, your workout in progress gets wiped out. Super annoying. (Need to persist progress in local storage to fix it). Workaround: Regularly submit/save and edit it. Pain
  • If you aren’t in internet coverage, it appears as if you are not logged in. And then logging in doesn’t help. Workaround: Wait for network coverage

Chinese new year is probably a good time to address some of these issues! If they are bothering you too are have found other bugs, please drop me an email (just reply to your registrastion mail)

Back with the power cleans

It’s been a while since I’ve been either lifting or working on this site! I’ve been busy with other sports, getting married, honeymoon and all the other things that happen in life.

But then a CrossFit gym opened up near my workplace. Upon visiting, I realised a CrossFit gym (or box…) has all the equipment one would ever need or want for gaining strength. While I’m not so into CrossFit because it trains you to be a more jack of all trades from endurance to strength, even if you’re after strength alone there is something there. Crucially the owners are happy to let me get one with getting strong and missing out on the WODs. And they still help me out with technique. So for the first time ever, I got some education on power cleans.

Here’s my latest attempt at a power clean. While it is me giving the analysis, some of the points (particularly the lack of leg extension) came from the coach there.

Outage from 19th April to 24th April

Unfortunately, I’ve had a difficult time with the backend this past week. The server unexpectedly shut down on April 19th and I wasn’t able to even log into my account until April 21st. Even having brought up the server, I experienced some data screw-ups.

The good news is that although most people couldn’t log any workouts, no data was lost and those of you who were able to log your workouts, that data is all safe as well and should be recovered to their rightful locations!

I’m still working on the root cause but I’m not overly worried as the system operates with numerous backups and the backend data is write-only so no data should ever get totally lost.

Plan your workout before you go to the gym

Failing to plan is planning to fail. Successful gainers know what they are going to do in the gym before they go to the gym. What weights they will do, how many reps they will attempt.

With this in mind, I’m incubating a new feature were you create your workout first – with some help to auto-generate the workout perhaps. Next up is a more simplified mobile interface to actually perform the logging.

Optimizing https performance on Ubuntu/Trusty/Nginx

At the time of writing, Ubuntu Trusty LTS is the latest LTS version of Ubuntu out there so perhaps it is not surprising that the version of Nginx that comes with it is not the absolute latest. Still Ubuntu’s nginx/1.4.6 is a long way behind the latest nginx/1.6.2. Functionally, they both serve the basics fine but in trying to optimize https performance, I realised the upgrade is well worth it.

Here are the steps to upgrade

Add these contents to /etc/apt/sources.list.d/nginx.list file:

deb http://nginx.org/packages/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/ubuntu/ trusty nginx

Then run the following commands:

apt-get remove nginx nginx-full nginx-common nginx-core
apt-get update
apt-get install nginx

Installing directly over is supposed to work but you can get weird errors with /etc/logrotate.d/nginx so it is better to remove first.

Just by updating to the latest, initial SSL handshake latency reduced by 50% in my test case! (600ms to 400ms for a Dallas client connecting to the HK server).

Reducing initial SSL handshake is important for that first visitor experience but it is equally important to maximise performance for subsequent visits. Here, one still needs to get hands-on with the config. Here is my result:

server {
listen 80;
listen 443 ssl spdy;
server_name gainstrack.com;
rewrite ^/(.*) https://www.gainstrack.com/$1 permanent;

ssl_certificate /etc/nginx/gainstrack.com.unified.crt;
ssl_certificate_key /etc/nginx/gainstrack.com.private.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";

Substitute server_name/ssl_certificate/ssl_certificate_key for your own server and ignore the rewrite rule, which is for AngularJS. The important optimizations here are

  • Enabling the spdy protocol, along side https. This is Google’s enhancement to further reduce latency in modern browsers
  • Choosing the “best” set of ciphers available (at the cost of excluding IE8 and below. I don’t care because my Angular site only supports later IE versions anyway). The “best” includes forward secrecy protocols that are not only more secure but offer lower latency because some parts of the expensive SSL handshake can be skipped
  • Enabling SSL session caching so that most browers don’t need to do the expensive SLL handshake when reconnecting.

Finally, with everything optimized for performance close to unsecure HTTP, the Strict-Transport-Security header will encourage modern browsers to treat HTTPS as the default secure way to connect to the website.

The result? Almost the best possible performant nginx setup with this version of nginx and a nice A grade at SSLLabs gainstrack.com analysis.

https://www.gainstrack.com is now secure.

Gainstrack automatic workout generation

A new beta feature has just appeared when logging workouts. By default, all of you are entering your workouts manually – typing or selecting an exercise. But if you’re on a standard program, can’t the computer generate it all for you?

Indeed, it should! As a new proof of concept feature, Gainstrack can now auto-generate Stronglifts 5×5 workouts – automatically determining if you should be on the A or B workout, filling out the exercises and determining the weights you should be doing for your worksets!

Generate Stronglifts

This is really just the start. Planned in the works are

  • Handle auto-deloads on programs like 5×5
  • Support many different kinds of programs – 3×5, Madcow etc. should be straightforward
  • Open source the whole framework so people can create their own workouts, or use the code in their own websites – yes, I plan to be that generous

Auto stronglifts