Stylr: making a mobile app with AngularJS
{% vimeo 99956183 %}
Stylr is a mobile app that, for lack of a better explanation, is probably best referred to as "Tinder for fashion". My friend Brendon Verissimo and I conceived and developed it. The idea behind the app is that users can tell the app about their tastes, and the app will track their preferences, eventually revealing their most prevelent style taste, and then go on to recommend actual fashion items to the user.
The stack for Stylr consists of:
mongoDB instance, hosted by mongoLab
NodeJS / Express server, hosted on a Digital Ocean droplet
AngularJS / Ionic Framework web app
Apache Cordova to wrap the app in a mobile native container
The performance of the web app on a phone, in relationship to native apps, is pretty remarkable. The ionic framework is basically bootstrap for your mobile web app. While we didn't use many of its features, it specializes in recreating familar native views, flows and gestures, all in an AngularJS app that's running in a webkit browser.
One of the key components of Ionic's framework is the Angular-UI Router. Once I got to know this module, I basically vowed to never again use Angular's native $routeProvider. The Angular-UI Router allows for nested states, which makes it very easy to implement views as parents and children, allowing for a pattern that much closer suits the way we think about views. It gives the developer a stateProvider, through which states can be accessed through various means.
Perhaps the most difficult challenge during the developemnt of Stylr was implementing the horizontal swipe-cards. I started with an old example of vertically swiped cards that behaved quite differently. A few days of tweaking and I was able to dictate the behaviors I was looking for - namely, the proper interpretation of the user's intent, and the corresponding actions. For instance:
if the user is moving at an accelerating velocity at the moment of release, they likely intent to toss this card. So this must trigger an animation that continues the current trajectory of the card view. It must also trigger the logic to pop the last card off the stack of cards to be played.
if the user is not accelerating at the moment of releasing their finger, it's likely that they intend to reconsider their own intent. The appropriate action here was to snap the card back to it's starting place, and be sure not to register any preference from the user.
The original card interaction demo has since been iterated on (check the pull requests), and can be found here.