proper node-webkit desktop notifications

Published:

Desktop notifications plays an important role in success of desktop apps since is allowing to bring attention of a user when something is happenning.

So far in node-webkit we have several solutions for desktop notifications.

1) HTML5 notifications

  • pros: is a html5 standart, same as in web.
  • cons: looks differently in differen OSes, low interaction capabilities, have bugs for node-webkit:)

2) NW Desktop Notifications

  • pros: customizable, same in different OSes.
  • cons: no interaction, animations are ugly, API is not a standart.

3) node-notifier

  • pros: you can do it from node, you can use standart OSes notification systems (win8 is coming soon!).
  • cons: looks differently in differen OSes, low interaction.

All those solutions were not working for me. Thus I had to create another one. Based on same idea as NW Desktop Notifications but implemented a little bit better.

node-webkit-desktop-notifications should become drop-in replacement for HTML5 notifications. So ideally you just use it instead of html5 Notification with some more API around. And if the code is executed in node-webkit context it does all kinds of rich notifications otherwise it degrades to html5.

Additionally to simple notifications you will get ability to build any complex interations inside your notification. Like change layout, buttons, textfields or gestures.

how to build interactive notifications

The notification itself is a window. Thus it has it's own context, html and css/javascript. Rich interactions are built on events. You can emit events on the window object inside notification window and catch them on DesktopNotification instance inside your application. So you can build any kind of presentation and keep interaction inside your appcode.

use it

To use the lib in your app you need to take 2 files:

1
2
src/desktopNotification.js
src/desktopNotification.html

You need to place them in same folder of your app. Load desktopNotification.js to your index.html to use the DesktopNotification

1
2
var notif = new DesktopNotification('Hello', {body: 'World'});
notif.show();

check other ways to use DesktopNotification in example.

try live

  • Fetch the repo
  • npm install
  • npm start
  • find an app for your OS in build/node-webkit-desktop-notification
  • play

semantic styling

Published:

Driving from #OdessaJs with @listochkin we had discussed the future of web development and our perceptions of what makes sense. It was priceless talk. And lot of things were formulated and validated for me. One of concepts popped out is the "semantic styling".

Not long ago there was a hype around semantic layout. Which is a great concept around giving more sense to layout. But it looks like nobody noticed the next big revolution in styles. The twitter did it. Twitter bootstrap has formulated smallest footprint of layout + styles for common design patterns.

So right now everybody agrees that button can be <button> as well as <a> and it should look the same and dropdown will look like:

1
2
3
4
5
6
7
<div class="dropdown">
  <button class="btn btn-default dropdown-toggle">Dropdown</button>
  <ul class="dropdown-menu">
    <li><a href="#1">Action</a></li>
    <li><a href="#2">Another action</a></li>
  </ul>
</div>

and nobody tries to invent something else. Bootstrap made a standart. What we can call "semantic styles".

What is also great about twitter bootstrap that it is built with less thus you can use parts of it. The variables in bootstrap are mainly colors and you can override them. Thus your css (less) code consists of two parts: the logic (the relations between html elements/classes, that describes the footprint) and the presentation (that makes the design individualistic - variables that change your colors and paddings)

With TWBS we have a vocabulary of semantic styles that represent commonly used design patterns and we can adjust them to branded design style overriding less variables.

Unlike bootstrap does though I think this vocabulary should be managed in a different way.

Bootstrap has just a lot of files in twitter bootstrap repo. Package managers on other hand provide better development experience, more abilities to handle dependencies and structure the code. I prefer components style over bower thus I would like and I believe it is possible to handle vocabulary of semantic styles in the same manner. But instead of CommonJs require("modulename") being able to (CommonLess - why not?) @import "buttons" without putting complete path to the component.

So from a development perspective we will just need to install some "less terms" as a components (example: $ component install twbs/forms twbs/buttons twbs/grid). And then inside my main.less file:

1
2
3
4
5
6
7
8
//importing vocabulary
@import "forms"
@import "buttons"
@import "grid"

//overriding default variables to adjust to branded design.
$brand-success: #AAAAAA;
$brand-default: #BBBBBB;

Almost everything is ready. CommonLess thing is not there yet. So far we just need to put complete relative path for less/sass components we use.


node-webkit autoupdate

Published:

Node-webkit allows you to build cross platform desktop application with node and JavaScript. Though building desktop application unlike pure online webapp means you got no control over the code after the app was installed. Thus releases are painful and bugs after the code was released are frustrating.

Right now desktop apps usually update themselves. Node-webkit do not have this functionality out of the box. Which is reasonable because such functionality would hardly rely on specific implementation.

So I created webkit-updater. It relies on suggestion that your app will be packaged with grunt-node-webkit-builder, compressed with grunt-contrib-compress and with windows package unzip.exe will be packaged. Basically the example of packaging app you can find here.

webkit-updater is working/tested under mac, win and linux(32/64).

how does it work

It gives you api to:

  1. Check the manifest for version.
  2. If the version is different from local one download new package to temp.
  3. Unpack the package to temp.
  4. Run new version from temp and exit the process.
  5. The new version from temp will copy itself to original folder.
  6. The new version will run itself from original folder and exit the process.

you should build this logic by yourself though. As a reference you can use example.

what are the plans

There should be bugs, probably. Need to stabilize it and test it extensively in real world app.

It would also be great to have different rates of updates:

  • update assets only without page reload (..x)
  • update assets with page reload (.x.)
  • update assets and node-webkit engine - full cycle (x..)

There is a bug for newer versions of linux. Updater should resolve things like that. Also there should be some preInstall and postInstall scripts handling.

You are welcome to use and commit.


framework vs microlib architecture

Published:

Just recently seems like I understood why holywars between programmers are happening. During revolution I basically saw the same holywar between people that believe that their truth is the only truth. Why even for smart people from both sides it is hard to negotiate for the same vision? I believe that the reason is that they have different values.

We often underestimate how much common values important for us to feel comfortable and productive in a team. We often do not care about having common values while looking for new jobs , we care about salaries more. Agree we make decision of accepting offer based on many factors, shared values as well though we do that unconsciously.

JavaScript community is quite inhomogeneous so you can see all kinds of values there. So far I can distinct two types of people, those who love classical OOP languages with strict and stable structure and patterns and people that love alternative languages that doesn’t have determined patterns and have ‘unexpected’ flexibilities. While talking with first group of people seems like they afraid of chaos and are intolerable for any unpredictability. The second one so bored with structures and solutions that are running away from enterprises like from hell. I know very few people that are ok with both.

So here I am coming to framework vs microlib architecture discourse. Inside JavaScript community itself we have kind of holywar around this topic. Now I feel it doesn’t make sense to participate in this war since final decision is always based on our values and that means that “common sense” that we are appealing to is quite individual.

PS: Main question in any job interview should be around values, always!


Angularjs is evil: overengineering hell

Published:

This I hope is the last post about how Angular will bring you to a world of pain.

Recently I stumbled on this Angularjs hate article that I am totally alligned with on emotional level. Angular is clearly overengineering. And unlike some may say It is not giving you exclusive scalability.

I would compare Angular to React. I know that those are not comparable. But I believe that React based architecture is something that beats Angular solution in terms of simplicity and scalability.

React vs AngularJS by number of concepts to learn

  • React stack: 4 (everything is a component, some components have state, you may use model instead, Commonjs modules, router).
  • AngularJS: 7 (modules, router, controllers, directives, scopes, templates, services, filters).

There are twice more concepts to learn for Angular than React. Not even saying that React's concepts are much more simple. For example you have controller and directive with templates that do more or less the same things. With React you have component only as a building block of your application. We all know that simplicity scales better, right?

directive vs component

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Angular
App.directive('myDirective', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {
   	  link: '@link'
    },
    template: '<a href="#/" ng-transclude></a>',
    link: function (scope, element, attrs) {
	  //do stuff with scope
    }
  };
});
//usage
<myDirective link='somewhere'><span>GO</span></myDirective>
1
2
3
4
5
6
7
8
9
10
11
12
13
//React
var myComponent = React.createClass({
  componentDidMount: function(){
    //do stuff with this.props
  },
  render: function() {
    return <div href={'#/' + this.props.link}>{this.props.children}</div>;
  }
});
//usage
<myComponent link='somewhere'><span>GO</span></myComponent>
//JSX transformed
myComponent({link:'somewhere'}, span(null,'GO'));

Substantial difference between React and Angular here is that React is Javascript friendly - you just put stuff as props and since components are functions these are passed as function arguments.

Component is a function!

service vs function

1
2
3
4
5
6
7
8
9
10
11
12
//Angular
myApp.service('unicornLauncher', ["apiToken", UnicornLauncher]);

function UnicornLauncher(apiToken) {

  this.launchedCount = 0;
  this.launch = function() {
    // make a request to the remote api and include the apiToken
    ...
    this.launchedCount++;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
//Javascript
var apiToken = require('../apiToken.js');

module.exports = function UnicornLauncher() {

  this.launchedCount = 0;
  this.launch = function() {
    // make a request to the remote api and include the apiToken
    ...
    this.launchedCount++;
  }

}

Service/provider in Angular is a solution for a made up problem. Just use CommonJs and you won't need service/provider thing. You will just use modules and functions that are natural for JS.

Service is a function!

filter vs function

1
2
3
4
5
6
7
//Angular
App.filter('incr', function() {
    return function(input) {
      return input + 1;
    };
  })
<div>{ {value | incr} }</div>
1
2
3
4
5
6
//React
function incr(input){
  return input + 1;
}

<div>incr(value)</div>

Well, directive is pretty useful if you use html templates as strings. Life is easier with React when you do not use strings for templates.

Filter is a function!

template vs JSX

1
2
3
4
5
//Angular
<div>
  <ProfilePic username='username' />
  <ProfileLink username='username' />
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Reactjs
/** @jsx React.DOM */
var Avatar = React.createClass({
  render: function() {
    return (
      <div>
        <ProfilePic username={this.props.username} />
        <ProfileLink username={this.props.username} />
      </div>
    );
  }
});
//transformed
var Avatar = React.createClass({
  render: function() {
    return (
      div(null,
        ProfilePic({username:this.props.username}),
        ProfileLink({username:this.props.username})
      )
    );
  }
});

Functions are better than strings. Functions could work with closures. Functions are faster. And in javascript functions are first class citizens. Functions are much more logical than strings.

Template is a function!

With react you can live in function world. And with Angular you live in enterprize patterns world.

My next story will be about why Angular might work for you.


managers are taking your project's breath

Published:

Theoretically there is no manager in agile. If someone is telling you that they have agile team with a manager they are lying. That mostly mean that they are not ready for some reason to share responsibility across the team - they do not have agile.

Few years ago I was lucky to participate in @jeffpatton agile workshop. This had huge impact on my understanding of application development. Right now I had embraced some agile basic principles and consider them as healthier for internal group dynamics of a team. Agile is literally makes healthier and happier each individual in the team.

People are lazy. Developers are not exclusions. We do not like to work and take responsibility. We easily give out our responsibilities for anyone who will take em. And worst thing you can do is to give all responsibility of project's success to one person. That what is happening when you put manager in your team.

On other hand people tend to step up and take responsibilities on products they are building and when they do they become more engaged and proud by stuff they do. They stop asking stupid questions and start committing themselves to the product.

We are developers and we are coming to our jobs and spend eight hours in a day to do magic. We really want to build something that makes sense, that could make world better. Isn't that the best motivation for us? Business, please, spend time to share your passion about product with us!

PS: There is only one case when having a project manager is a good idea. When you have short time project and manager who takes BA role. It just do not make sense to commit in building a team.


Angularjs is evil: the scope horror

Published:

This is the second post about how angular makes my life painful.

The scope is most one of most complex concepts in Angular. You never know what scope are you in and what is available inside. Things may change if you add anguments somewhere at the top node.

1
2
3
4
5
6
7
8
9
var app = angular.module('myApp', []);

function foo($scope) {
    $scope.value = "foo";
}

function bar($scope) {
    $scope.value = "bar";
}
1
2
3
4
5
<div ng-controller="foo">
    <div ng-controller="bar">
    {value}
    </div>
</div>

You can miss new ng-controller or someone could overwrite your context. It looks like ok, until you have really complex html.

Things become more infernal when you try to create a directive. Directive may have or may not have the scope. Obviously you are passing the stuff to the scope through arguments of the newly created "element". You can do it in three different ways with craziest API I ever seen - you got three magic symbols & = @ and they do different things with stuff you are throwing inside your arguments. I can only tell that it looks reasonable untill you find alternative that do same thing and make sense in the same time.

And then you try to do what every angular developer does at least once in his life. You take transclusion and try to put directive scope inside transcluded html. Which looks like a great idea at the beginning.

The other thing that I hate about $scope is that I never know when the template will be rendered. It is quite painful to see the magic without knowing what's happening. I know that I can learn it, my point though is that if I need to learn to embrace it is probably done in a wrong way.


Angularjs is evil: dependency injection

Published:

A year ago I was excited of angular and I still think angular is a game changer. I see how community charmed with angular and how easy to start building webapps apps with it. However after a year of using angular I must say that I am not recommending investing time into this framework. I will write several posts about why.

One of things I hate most about angular is its module system. Sadly it is deeply injected in its DNA. Someone decided that DI in JavaScript should look like this:

1
2
3
4
5
6
7
8
function someFactory(stuff){
	//use stuff
}
someFactory.$inject = ['stuff'];

app.factory(['stuff', function(stuff){
	//use stuff
}])

It looks cool. But for me as a JS developer it's too messy and complex (someFactory->someFactoryProvider o_O WTF?!) Here is a dependency injection in pure JS:

1
2
3
4
5
6
function someFactory(stuff){
	return function(){ //we're using closure for DI here
    	//use stuff
    }
}
someFactory(stuff) // injecting stuff

I am using simple closure for dependency injection. It feels more natural. But we still can't replace angular's module system right? Thus we need to use CommonJS (you can use browserify or brunch).

1
2
3
4
var stuff = require('./stuff');
module.exports = function someFactory(){ //and again we use closure
	//use stuff
}

Why is that better? It is simple. It is better way for structuring your app - it gives you references and you can directly say where the dependency lives. It already works well for nodejs. It is compatible with existing package managers.

I know that how JS modules should look like is a debatable topic. I think that CommonJS pattern quite usable and much better fit for JS than AMD or ES6 modules. Though I definitely think that Angular got it wrong.


Reactjs mixing with Backbone

Published:

Reactjs is a javascript librarby for building user interfaces opensourced by facebook just recently.

Not long ago I felt that as a developer I have more or less two best options to build an app. Whether do it in #angular or #backbone. Now I feel that #react is taking best of angular, do it better and allows to use best parts of backbone.

I hate Backbone Views and I hate $scope of angular, especially when it comes to directive scope and all &-@-= stuff. Transclusion and scope is a double hell and I am not talking about digesting and performance yet.

React has really small API and it does one thing, but does it really well. It abstracts DOM for you and optimizes the rendering part. So each time you need react to reflect state changes in the DOM it renders lightweight DOM in javascript and applies only diff to the real DOM. In that way rendering becomes really cheap unlike in angular. And that allows us to build apps with diffenrent patterns in mind.

And here are some tips I got from several weeks of playing around #Reactjs

React is just V

React needs other stuff like routes and models. I am taking them from Backbone.

Models are state

By default React have single state this.state. Which is not usually best solution. It appears that cleaner way is to have multiple states. Where this.state is not persisting state and backbone models are.

In the React's example you can find BackboneMixin but it has some flaws. Following one is better since it does proper cleanup.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var  ModelMixin = {
  componentDidMount: function() {
    // Whenever there may be a change in the Backbone data, trigger a reconcile.
    this.getBackboneModels().forEach(this.injectModel, this);
  },
  componentWillUnmount: function() {
    // Ensure that we clean up any dangling references when the component is
    // destroyed.
    this.__syncedModels.forEach(function(model) {
      model.off(null, model.__updater, this);
    }, this);
  },
  injectModel: function(model){
    if(!this.__syncedModels) this.__syncedModels = [];
    if(!~this.__syncedModels.indexOf(model)){
      var updater = this.forceUpdate.bind(this, null);
      model.__updater = updater;
      model.on('add change remove', updater, this);
      this.__syncedModels.push(model);
    }
  }
}

In that way you can use same models in several nested components.

1
2
3
4
  <rootComponent user="new UserModel({id: id})">
    <contactComponent user = {this.props.user}/>
    <userpicComponent user = {this.props.user}/>
  </rootComponent>

2 way binding

It's kinda logical to have 2 way binding with those Backbone models. LinkedState plugin is working only for state thus here is BindMixin wich does basically the same as LinkedState but for Backbone models.

1
2
3
4
5
6
7
8
9
10
var  BindMixin = {
  bindTo: function(model, key){
    return {
      value: model.get(key),
      requestChange: function(value){
          model.set(key, value);
      }.bind(this)
    }
  }
}

This mixin adds bindTo method that binds control with model property as simple as this.bindTo(user, 'name'):

1
2
3
4
5
6
7
8
9
10
11
12
13
var Hello = React.createClass({
  mixins:[ModelMixin, BindMixin],
  getBackboneModels: function(){
    return [this.props.instance]
  },
  render: function() {
    var model = this.props.instance;
    return <div>
        <div>Hello {model.get('initial')}</div>
        <input type="text" valueLink={this.bindTo(model, 'initial')}/>
      </div>
  }
});

Here is working example: http://jsfiddle.net/djkojb/qZf48/24/


using private components in compy

Published:

There are core limitations in component that makes hard to use private git repositories directly, unless you use github. Component FAQ proposes to use remotes property and any web server that uses the same urls as Github.

package.json

1
2
3
4
5
6
7
{
  ...
  "compy":{
    ...
    "remotes":["https://user:pass@raw.github.com"]
  }
}

But there is a better way to manage private components with any git server you like.

using git submodules to manage private components

Component supports local dependencies. That means it can serve components from any local folder you put in as local param in config.

package.json

1
2
3
4
5
6
7
8
{
  ...
  "compy":{
    ...
    "paths":["local"],
    "local":["component1","component2"]
  }
}

So if you want to use local dependencies, you should put git submodules with those private components in the folder.

Compy will serve them as usual components and you will manage them with git-cli.

adding component to folder

You can add component to local folder like this:

1
2
cd local;
submodule add git://github.com/chneukirchen/rack.git