diff -r f7ceddf99d6d -r bf5cf5a9e737 tweetcast/nodejs/client/js/script.js --- a/tweetcast/nodejs/client/js/script.js Wed Dec 07 19:28:46 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,446 +0,0 @@ -var socket, - tlPaper, - twPaper, - tweetData = { - "tweetcount" : 0, - "position" : 0, - "feedMode" : true, - "followLast" : true, - "zoomLevel" : 3, - "timeLevel" : 2, - "tweets" : [], - "posIndex" : [], - "tlChanged" : true, - "tlLevelChanged" : true, - "blockUpdate" : false, - "waitUpdate" : true, - "htmlBuffer" : '', - "wheelDelta" : 0 - }, - displaySplitting = [ - { - positions : [ 10, 20, 22, 24, 25, 26, 27, 28, 29, 31, 33, 43, 53 ], - classNames : [ 'icons fade', 'icons', 'quarter fade', 'quarter', 'half fade', 'half', 'full', 'half', 'half fade', 'quarter', 'quarter fade', 'icons', 'icons fade' ] - }, - { - positions : [ 1, 3, 5, 7, 13, 33, 53 ], - classNames : [ 'full', 'half', 'half fade', 'quarter', 'quarter fade', 'icons', 'icons fade' ] - } - ]; - -function placeHolder(className) { - return '
  • '; -} - -function getLinkedTweets() { - socket.emit('linkedTweets',{"tweetpos":tweetData.position}); -} - -function changeMode() { - if (tweetData.feedMode) { - getLinkedTweets(); - } else { - tweetData.feedMode = true; - updateDisplay(); - } -} - -function clicTweet(tweetPos) { - if (tweetPos != tweetData.position) { - tweetData.position = tweetPos; - if (tweetData.feedMode) { - tweetData.followLast = (tweetData.position == tweetData.tweetcount); - } else { - getLinkedTweets(); - } - return false; - } else { - changeMode(); - } -} - -function tweetToHtml(tweet, className) { - if (!tweet) { - return placeHolder(className); - } - var html = '
  • '; - } - html += ''; - } - html += '
    '; - a_user = ''; - if (tweet.user.profile_image_url) { - html += a_user + ''; - } - html += '

    ' + a_user + '@' + tweet.user.screen_name + '

    ' + new Date(tweet.created_at).toLocaleTimeString() + '

    '; - lastend = 0; - var tab = tweet.text.split(/\&\#|\;/); - var txta = ''; - for (i = 0; i < tab.length; i++) { - txta += (i % 2 && parseInt(tab[i]) != NaN) ? String.fromCharCode(tab[i]) : tab[i]; - } - var txt = '', - entities = []; - for (var i in tweet.entities.hashtags) { - entities.push({ - "start" : tweet.entities.hashtags[i].indices[0], - "end" : tweet.entities.hashtags[i].indices[1], - "html" : '#' + tweet.entities.hashtags[i].text + '' - }); - } - for (var i in tweet.entities.urls) { - entities.push({ - "start" : tweet.entities.urls[i].indices[0], - "end" : tweet.entities.urls[i].indices[1], - "html" : '' + tweet.entities.urls[i].expanded_url + '' - }); - } - for (var i in tweet.entities.user_mentions) { - entities.push({ - "start" : tweet.entities.user_mentions[i].indices[0], - "end" : tweet.entities.user_mentions[i].indices[1], - "html" : '@' + tweet.entities.user_mentions[i].screen_name + '' - }); - } - entities.sort(function(a, b) { return a.start - b.start }); - for (var i in entities) { - txt += txta.substring(lastend, entities[i].start) + entities[i].html; - lastend = entities[i].end; - } - txt += txta.substring(lastend); - html += txt + '

  • '; - return html; -} - - -function getUpdate() { - tweetData.posToDisplay = []; - if (tweetData.feedMode) { - if (tweetData.followLast) { - tweetData.position = tweetData.tweetcount; - for (var i = tweetData.tweetcount; i >= tweetData.tweetcount - 52; i--) { - tweetData.posToDisplay.push( i > 0 ? i : -1 ); - } - tweetData.end = tweetData.tweetcount; - tweetData.start = Math.max(1, tweetData.end - 52); - } else { - for (var i = tweetData.position + 26; i >= tweetData.position - 26; i--) { - tweetData.posToDisplay.push( i > 0 && i <= tweetData.tweetcount ? i : -1 ); - } - tweetData.end = Math.min(tweetData.tweetcount, tweetData.position + 26 ); - tweetData.start = Math.max(1, tweetData.position - 26); - } - if ($("#modeselector").text() != "Mode flux") { - $("#modeselector").html("Mode Flux").css({"color":"#000000","background":"#ffffff"}); - $("#tweetlist").css({"background":"#ffffff"}); - } - } else { - tweetData.linkedTweets.referenced_by.sort(function(a,b) { return b.pos - a.pos }); - tweetData.linkedTweets.referencing.sort(function(a,b) { return b.pos - a.pos }); - for (var i in tweetData.linkedTweets.referenced_by) { - tweetData.posToDisplay.push(tweetData.linkedTweets.referenced_by[i].pos); - } - tweetData.posToDisplay.push(tweetData.position); - for (var i in tweetData.linkedTweets.referencing) { - tweetData.posToDisplay.push(tweetData.linkedTweets.referencing[i].pos); - } - if ($("#modeselector").text() != "Conversation") { - $("#modeselector").html("Conversation").css({"color":"#ffffff","background":"#000080"}); - $("#tweetlist").css({"background":"#000080"}); - } - } - var tweetsToGet = []; - for (var i in tweetData.posToDisplay) { - if (tweetData.posToDisplay[i] != -1 && !tweetByPos(tweetData.posToDisplay[i])) { - tweetsToGet.push(tweetData.posToDisplay[i]); - } - } - if (tweetsToGet.length) { -// console.log('We need to get '+tweetsToGet.join(',')); - socket.emit('updateTweets', { - "tweets" : tweetsToGet - }); - } else { - drawTweetList(); - } -/* html = ''; - for (var i in tweetData.linkedTweets.referenced_by) { - console.log(tweetData.linkedTweets.referenced_by[i]); - html += tweetToHtml(tweetData.linkedTweets.referenced_by[i].tweet,'half'); - } - html += tweetToHtml(tweetByPos(tweetData.position),'full'); - for (var i in tweetData.linkedTweets.referencing) { - console.log(tweetData.linkedTweets.referencing[i]); - html += tweetToHtml(tweetData.linkedTweets.referencing[i].tweet,'half'); - } - if (tweetData.htmlBuffer != html) { - $("#tweetlist").html(html); - tweetData.htmlBuffer = html; - } */ - if (tweetData.tlChanged || tweetData.tlLevelChanged) { - socket.emit('updateTimeline', { - "level" : tweetData.timeLevel, - "full" : tweetData.tlLevelChanged - }); - } else { - drawTimeLine(); - } -} - -function addTweet(tweet) { - if (tweetData.posIndex.indexOf(tweet.pos) == -1) { - tweetData.tweets.push(tweet); - tweetData.posIndex.push(tweet.pos); - } -} - -function tweetByPos(pos) { - var index = tweetData.posIndex.indexOf(pos); - return (index == -1 ? false : tweetData.tweets[index]); -} - -function delayedUpdate() { - tweetData.blockUpdate = false; - if (tweetData.waitUpdate) { - updateDisplay(); - } -} - -function updateDisplay() { - if (tweetData.blockUpdate) { - tweetData.waitUpdate = true; - } else { - tweetData.waitUpdate = false; - getUpdate(); - tweetData.blockUpdate = true; - setTimeout(delayedUpdate, 100); - } -} - -function setTimeZoom(level) { - if (level >= 0 && level <= 4) { - tweetData.timeLevel = level; - tweetData.tlChanged = true; - updateDisplay(); - } -} - -function drawTweetList() { - html = ''; - var i = 0; - while (i < tweetData.posIndex.length) { - if (tweetData.posToDisplay.indexOf(tweetData.posIndex[i]) == -1) { - tweetData.posIndex.splice(i,1); - tweetData.tweets.splice(i,1); - } else { - i++; - } - } - if (tweetData.feedMode) { - for (var i in tweetData.posToDisplay) { - var ds = displaySplitting[tweetData.followLast ? 1 : 0]; - for (var j in ds.positions) { - if (ds.positions[j] > i) { - var className = ds.classNames[j]; - break; - } - } - html += ( tweetData.posToDisplay[i] != -1 ? tweetToHtml(tweetByPos(tweetData.posToDisplay[i]), className) : placeHolder(className) ); - } - } else { - for (var i in tweetData.posToDisplay) { - html += tweetToHtml(tweetByPos(tweetData.posToDisplay[i]), (tweetData.posToDisplay[i] == tweetData.position ? 'full' : 'half' )); - } - } - if (tweetData.htmlBuffer != html) { - $("#tweetlist").html(html); - tweetData.htmlBuffer = html; - } - if (tweetData.followLast) { - $("#tweet_" + tweetData.position).fadeIn(500); - } - drawTimeWindow(); -} - -function drawTimeWindow() { - twPaper.clear(); - if (!tweetData.timeline || !tweetData.timeline.length) return; - - var dtfintl = tweetData.timeline[ tweetData.timeline.length - 1 ].end, - dtdebtl = tweetData.timeline[0].start, - scY = 600 / ( dtfintl - dtdebtl ); - if (tweetData.feedMode) { - var dtfintw = new Date( tweetByPos( tweetData.end ).created_at ), - dtdebtw = new Date( tweetByPos( tweetData.start ).created_at ), - rTop = scY * ( dtfintl - dtfintw ), - rHeight = scY * ( dtfintw - dtdebtw ); - if (rHeight > 0) { - twPaper.rect( 0, rTop, 300, rHeight).attr({"stroke":"none","fill":"#8080ff","fill-opacity":.2}); - } - } else { - for (var i in tweetData.posToDisplay) { - if (tweetData.posToDisplay[i] != -1) { - var tw = tweetByPos(tweetData.posToDisplay[i]); - if (tw) { - var dtcour = new Date( tw.created_at ), - posY = scY * ( dtfintl - dtcour ); - twPaper.path("M0 "+posY+"L300 "+posY).attr({"stroke":"#88f"}); - } - } - } - } - var dtcour = new Date( tweetByPos( tweetData.position ).created_at ), - posY = scY * ( dtfintl - dtcour ); - twPaper.path("M0 "+posY+"L300 "+posY).attr({"stroke":"#ff0"}); -} - -function drawTimeLine() { - tlPaper.clear(); - if (!tweetData.timeline || !tweetData.timeline.length) return; - tweetData.tlTweetRects = []; - var scaleY = 600 / tweetData.timeline.length, - max = 0; - for (var i = 0; i < tweetData.timeline.length; i++) { - max = Math.max(max, tweetData.timeline[i].tweets); - } - var scaleX = 160 / max; - - // dessin de l'axe vertical - - tlPaper.path("M160 0L160 600").attr({"stroke":"#ccc"}); - - // dessin de la date de début - - tlPaper.text(165, 592, new Date(tweetData.timeline[0].start).toLocaleTimeString()).attr({ "text-anchor" : "start", "font-size": "12px" }); - - // dessin de la date de fin - - tlPaper.text(165, 7, new Date(tweetData.timeline[tweetData.timeline.length - 1].end).toLocaleTimeString()).attr({ "text-anchor" : "start", "font-size": "12px" }); - for (var i = 0; i < tweetData.timeline.length; i++) { - var posY = 600 - (i * scaleY); - - // Si on est à une demi-heure, on trace un axe secondaire + heure - - if (i && !(new Date(tweetData.timeline[i].start).valueOf() % 1800000)) { - tlPaper.path("M0 "+posY+"L165 "+posY).attr({"stroke":"#ccc"}); - tlPaper.text(165, posY, new Date(tweetData.timeline[i].start).toLocaleTimeString()).attr({ "text-anchor" : "start", "font-size": "12px" }); - } - var anz = { - "default" :tweetData.timeline[i].tweets - }; - for (var j in tweetData.timeline[i].annotations) { - anz.default -= tweetData.timeline[i].annotations[j]; - anz[j] = tweetData.timeline[i].annotations[j]; - } - var posX = 0; - for (var j in anz) { - var largX = scaleX * anz[j]; - if (largX > 0) { - tlPaper.rect(posX, 600 - scaleY * (i+1), largX, scaleY).attr({"stroke": "none", "fill": annotations[j].colors.timeline}); - posX += largX; - } - } - } - - drawTimeWindow(); -} - -$(document).ready(function() { - tlPaper = Raphael("timeline", 220, 600); - twPaper = Raphael("timewindow", 220, 600); - socket = io.connect('http://' + document.location.hostname ); - socket.on('tweetSummary', function (data) { - if (tweetData.tweetcount != data.tweetcount) { - tweetData.tweetcount = data.tweetcount; - tweetData.tlLevelChanged = true; - updateDisplay(); - } - }); - socket.on('tweetPosByDate', function (data) { - tweetData.position = data.tweetpos; - tweetData.feedMode = true; - tweetData.followLast = (tweetData.position == tweetData.tweetcount); - updateDisplay(); - }); - socket.on('tweets', function (data) { - for (var i in data) { - addTweet(data[i]); - } - drawTweetList(); - }); - socket.on('timeline', function (data) { - tweetData.tlChanged = false; - if (data.full) { - tweetData.timeline = data.data; - } else { - if (tweetData.timeline[tweetData.timeline.length - 1].start == data.data[0].start) { - tweetData.timeline[tweetData.timeline.length - 1] = data.data[0]; - } else { - tweetData.timeline.push(data.data[0]); - } - } - while (tweetData.length > 50) { - tweetData.splice(0,1); - } - drawTimeLine(); - }); - socket.on('linkedTweets', function(data) { - tweetData.followLast = false; - tweetData.feedMode = false; - tweetData.position = data.tweetpos; - tweetData.linkedTweets = data; - updateDisplay(); - }); - $("#tweetlist").mousewheel(function(e, d) { - tweetData.wheelDelta += d; - if (Math.abs(tweetData.wheelDelta) >= 1) { - if (tweetData.feedMode) { - tweetData.position = Math.min( tweetData.tweetcount, Math.max(1, parseInt(tweetData.wheelDelta) + tweetData.position ) ); - tweetData.followLast = (tweetData.position == tweetData.tweetcount); - updateDisplay(); - } else { - if (tweetData.wheelDelta > 0) { - if (tweetData.linkedTweets.referenced_by.length) { - tweetData.position = tweetData.linkedTweets.referenced_by[tweetData.linkedTweets.referenced_by.length - 1].pos; - getLinkedTweets(); - } - } else { - if (tweetData.linkedTweets.referencing.length) { - tweetData.position = tweetData.linkedTweets.referencing[0].pos; - getLinkedTweets(); - } - } - } - tweetData.wheelDelta = 0; - } - return false; - }); - $("#timewindow").mousewheel(function(e, d) { - tweetData.wheelDelta += d; - if (Math.abs(tweetData.wheelDelta) >= 1) { - if (tweetData.wheelDelta > 0) { - setTimeZoom(tweetData.timeLevel + 1); - } else { - setTimeZoom(tweetData.timeLevel - 1); - } - tweetData.wheelDelta = 0; - } - return false; - }); - $("#timewindow").click(function(evt) { - var offsetY = evt.pageY - $(this).offset().top, - dtfintl = tweetData.timeline[ tweetData.timeline.length - 1 ].end, - dtdebtl = tweetData.timeline[0].start, - clicTime = dtdebtl + (1 - ( offsetY / 600 ) ) * ( dtfintl - dtdebtl ); - socket.emit('tweetPosByDate',{ date: clicTime }); - }); - $("#modeselector").click(changeMode); -}); \ No newline at end of file