Node.JS News

Everything you should know on NodeJS

Build effective html5 app with node.js socket.io Twitter bootstrap

Build an effective Twitter stream client on top of NodeJS, using Socket.io and Twitter Bootstrap with few node.js lines of code! That’s the way I track node.js news!

twitter

To build this html5 webapp, I use Node.JS and the realtime socket library Socket.io. On top of that, the UI relies on Twitter Bootstrap!

This node.js app is simple to use, start the server, start your browser, add/remove keywords you want to track on Twitter. All of that made in a single page html5 app!

Fill free to fork me on GitHUB!

#!/usr/local/bin/node

sys     = require('util');
express = require('express');
twitter = require('ntwitter');

app = express.createServer();
app.configure(function(){
  app.use(express.static(__dirname + '/public'));
});
app.get('/', function(req, res, next){
  res.render('/public/index.html');
});
app.listen(8080);
console.log('Server running at http://localhost:8080/');

var io  = require('socket.io').listen(app);
io.set('log level', 1);
// myList handle list of streamed keywords
myList = [];
// util func to help delete val in array
Array.prototype.del = function(val) {
    for(var i=0; i<this.length; i++) {
        if(this[i] == val) {
            this.splice(i, 1);
            break;
        }
    }
}
CreateTwitter();
io.sockets.on('connection', function(socket) {
    socket.on('data', function(action,data) {
	if(action==='+') { // We add a keyword from the client
        	myList.push(data);
	}
	else { // We remove a keyword from the client
		myList.del(data);
	}
    });
    socket.on('getfilter', function() { // client ask for list of keywords we push it in myList array
        socket.emit('pushfilter', myList);
    });
    if(myList.length!=0) { // if array not empty the stream :)
        twit.stream('user',{track:myList}, function(stream) {
            stream.on('data', function (tweet) {
  	    	    socket.emit('message', JSON.stringify(tweet));
            });
        });
    }
});

function CreateTwitter() {
twit = new twitter({ // add your own Twitter parameters
    consumer_key: '',
    consumer_secret: '',
    access_token_key: '',
    access_token_secret: ''
});
}
<!DOCTYPE HTML>
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="bootstrap/css/bootstrap.css">
  <link rel="stylesheet" href="bootstrap/css/bootstrap-responsive.css">
  <title>Dashboard Node.JS + Socket.io from http://www.nodejs-news.com</title>
</head>
<body>
    <div class="container-fluid">
    <div class="navbar">
        <div class="navbar-inner">
            <div class="container">
            <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </a>
            <!-- Be sure to leave the brand out there if you want it shown -->
            <a class="brand" href="/public/index.html">Dashboard</a>
            <!-- Everything you want hidden at 940px or less, place within here -->
            <div class="nav-collapse collapse" style="height:0px;">
                <!-- .nav, .navbar-search, .navbar-form, etc -->
                <ul class="nav">
                  <li class="active">
                    <a href="http://www.nodejs-news.com" target="_blank" title="Node.js News web site">NodeJS News</a>
                  </li>
                  <li class="divider-vertical"></li>
                  <li class="">
                    <a href="http://www.it-wars.com" target="_blank" title="IT Wars yet another Geek">My French blog</a>
                  </li>
                </ul>
            </div>
            </div>
        </div>
    </div>
        <div class="row-fluid">
            <div class="span3">
                <form class="well" id="chat" >
                    <label>Twitter filter</label>
                    <input type="text" id="data" class="span2" placeholder="Add a Twitter tracker…">
                    <span class="help-inline">Submit an additional tracker!</span>
                    <button type="submit" class="btn" onclick="addTrack(); return false;" >Submit</button>
                </form>
                <div class="well">
                    <p>Twitter stream tracker(s):</p>
                    <div id="tracker">
                    </div>
                </div>
            </div>
            <div class="span9">
                <div class="well" id="twitter-stream">
            	  <ul class="unstyled">
        	      </ul>
                </div>
            </div>
        </div>
    </div>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="/myscript.js"></script>
<script src="/bootstrap/js/bootstrap-alert.js"></script>
<script src="/bootstrap/js/bootstrap-collapse.js"></script>
</body>
</html>

myscript.js file :

var filters='';
var socket = io.connect();
socket.on('message', function(json) {
    data = JSON.parse(json);
    var replacePattern = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
    var replacedText = (data.text).replace(replacePattern, '<a href="$1" target="_blank">$1</a>');
    filters.forEach(function(str) {
        var search = new RegExp(str, "gim");
        replacedText = replacedText.replace(search, '<span class="label label-important">'+str+'</span>');
    });
	$("<li></li>").html("[" + data.user.screen_name + "] " + replacedText)
      	.prependTo("ul.unstyled")
      	.css({opacity:0}).slideDown("slow").animate({opacity:1},"slow");
});
socket.on("connect", function() {
    socket.emit('getfilter', function() {
    });
    console.log("connected");
});
socket.on("disconnect", function() {
    console.log("disconnected");
});
socket.on('pushfilter', function(f) {
    filters=f;
    $('#tracker').empty();    
    filters.forEach(function(str) {
	$('<div class="alert alert-block alert-error fade in" id="'+str+'"><a class="close" data-dismiss="alert" id="'+str+'" href="#">&times;</a><p>'+str+'</p></div></div>').prependTo("#tracker");
    });
});

function addTrack() {
    socket.emit( 'data', '+', $('#data').attr('value'));
    $('#data').val('');
    socket.disconnect();
    socket.socket.reconnect();
}
$("#tracker").delegate('a', 'click', function() { 
    socket.emit( 'data', '-', $(this).attr('id'));
    socket.disconnect();
    socket.socket.reconnect();
});

Fill free to fork me on GitHUB!

May 17, 2012



blog comments powered by Disqus