Various upgrades and bugfixes
authorveltr
Wed, 24 Apr 2013 17:54:48 +0200
changeset 22 4e1e66b2fdf1
parent 21 007254e97333
child 23 933b388521f6
Various upgrades and bugfixes
assets/sprites.psd
css/playscreen.css
img/sprites.png
js/playscreen.js
playscreen-frame.html
playscreen.html
Binary file assets/sprites.psd has changed
--- a/css/playscreen.css	Mon Apr 22 18:42:40 2013 +0200
+++ b/css/playscreen.css	Wed Apr 24 17:54:48 2013 +0200
@@ -45,11 +45,15 @@
 }
 
 .lock-button {
-	width: 36px; background-position: -36px -54px;
+	width: 72px; height: 24px; margin: 3px 4px; background-position: -36px -42px;
 }
 
-.lock-button.locked {
-	background-position: -36px -36px;
+.lock-button.locked, .lock-button:hover {
+	background-position: -36px -18px;
+}
+
+.lock-button.locked:hover {
+    background-position: -36px -42px;
 }
 
 .duration, .time-separator, .current-time {
@@ -61,7 +65,7 @@
 	width: 6px; text-align: center;
 }
 .duration, .current-time {
-	width: 120px; margin: 0 8px;
+	width: 100px; margin: 0 8px;
 }
 .current-time {
 	text-align: right; color: #CCCCCC;
@@ -93,7 +97,7 @@
 }
 
 .home-button {
-	background-position: -36px -18px;
+	background-position: -72px 0;
 }
 
 .play-canvas {
@@ -159,20 +163,21 @@
 
 .play-localtweets {
     left: 390px;
+    width: 450px;
     position: absolute;
     z-index: 2;
 }
 
-.play-localtweets .tweet {
-	width: 320px; background: #666666; padding: 4px;
+.tweet {
+    background: #666666; padding: 4px; min-height: 32px;
 }
 
 .tweet img {
-	width: 20px; height: 20px; float: left;
+	width: 32px; height: 32px; float: left;
 }
 
 .tweet p {
-	margin-left: 24px; font-size: 12px;
+	margin-left: 36px; font-size: 15px; text-shadow: 0 0 2px #000000; line-height: 16px;
 }
 
 .tweet a {
@@ -180,49 +185,46 @@
 }
 
 .play-tagcloud {
-	left: 720px;
+	right: 0;
 	top: 5px;
     position: absolute;
-    width: 296px;
+    width: 140px;
 }
 
 .play-tagcloud li {
     cursor: pointer;
-    float: left;
-    height: 16px;
-    line-height: 16px;
+    height: 20px;
+    padding: 3px 0;
     text-align: center;
-    width: 98px;
-    display: inline-block;
-    margin-bottom: -6px;
 }
 
 .play-tagcloud li.selected {
 	background: #FFFF00; color: #000000;
 }
 
-.play-tagcloud li:nth-child(3n+2) {
-	margin-top: 5px;
-}
-
-.play-tagcloud li:nth-child(3n) {
-	margin-top: 10px;
-}
-
 .user-tweets {
-	position: absolute; left: 730px; top: 300px; bottom: 0; right: 0; display: none;
+	position: absolute; left: 420px; top: 40px; bottom: 40px; right: 60px; display: none;
+	background: rgba(64,64,64,.8); border-radius: 10px; z-index: 4; box-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
 }
 
 .user-tweets-head {
-	font-size: 14px; text-align: center;
+	font-size: 14px; text-align: center; margin: 10px 0 0;
 }
 
 .user-tweets-list {
-	position: absolute; left: 0; top: 20px; bottom: 0; right: 0; overflow: auto;
+	position: absolute; left: 10px; top: 30px; bottom: 10px; right: 10px; overflow: auto;
+}
+
+.close-user-tweets {
+    float: right; font-size: 20px; font-weight: bold; margin: 5px; text-decoration: none; color: #FFFFFF;
 }
 
 .user-tweets-list .tweet {
-	background: #666666; font-size: 12px; padding: 4px; margin: 5px 0;
+	margin-bottom: 10px; cursor: hand;
+}
+
+.user-tweets-list .tweet:hover {
+    background: #808080; cursor: pointer;
 }
 
 .user-name {
Binary file img/sprites.png has changed
--- a/js/playscreen.js	Mon Apr 22 18:42:40 2013 +0200
+++ b/js/playscreen.js	Wed Apr 24 17:54:48 2013 +0200
@@ -242,7 +242,8 @@
         xscale = globW/mx,
         yscale,
         localyscale,
-        filteredSegments = [];
+        filteredSegments = [],
+        currentTweetTc = -1;
     
     function showLocal() {
     	var $c = $(".play-canvas"),
@@ -421,19 +422,54 @@
         
         var deltaY = $(".play-bottom").offset().top;
         
-        $(".play-localtweets .tweet:visible").each(function() {
+		ctx.strokeStyle = "#ccc";
+		
+        $(".play-localtweets .tweet").each(function() {
         	var el = $(this),
         		liY = + el.offset().top + el.outerHeight() / 2 - deltaY,
-        		tY = localyscale * (+el.attr("data-timestamp") - localpos + localduration / 2);
+        		t = +el.attr("data-timestamp"),
+        		tY = localyscale * (t - localpos + localduration / 2),
+                tX = localL + lxscale * (data.fiveseconds[Math.floor(t / 5)].count - lmi);
     		ctx.beginPath();
-    		ctx.strokeStyle = "#ccc";
-    		ctx.moveTo(localL, tY);
+    		ctx.moveTo(tX, tY);
     		ctx.lineTo(localR, tY);
     		ctx.lineTo(400, liY);
     		ctx.stroke();
     		$(this).css("background",colors[el.attr("data-topic-id")] || "");
         });
         
+		ctx.strokeStyle = "#000";
+        ctx.fillStyle = "#ff0";
+		
+        $(".user-tweets .tweet:visible").each(function() {
+            var el = $(this),
+                t = +el.attr("data-timestamp"),
+                hover = (t === currentTweetTc);
+            if (hover) {
+                ctx.strokeStyle = "#900";
+                ctx.lineWidth = 3;
+            }
+            if (t > localstart && t < localend) {
+                var tY = localyscale * (t - localpos + localduration / 2),
+                    tX = localL + lxscale * (data.fiveseconds[Math.floor(t / 5)].count - lmi);
+        		ctx.beginPath();
+        		ctx.arc(tX,tY,hover ? 6 : 3,0,2*Math.PI,true);
+        		ctx.fill();
+        		ctx.stroke();
+            }
+            var n = Math.floor(t / 60),
+                x = globL + xscale * data.minutes[n].count,
+                y = yscale * t;
+            ctx.beginPath();
+            ctx.arc(x,y,hover ? 6 : 3,0,2*Math.PI,true);
+            ctx.fill();
+            ctx.stroke();
+            if (hover) {
+                ctx.strokeStyle = "#000";
+                ctx.lineWidth = 1;
+            }
+        });
+        
         ctx.fillStyle = '#ffffff';
         ctx.strokeStyle = '#999999';
         ctx.font = '10px Arial,Helvetica';
@@ -549,7 +585,7 @@
 	    	.sortBy(function(w) {
 	    		return -w.score;
 	    	})
-	    	.first(39)
+	    	.first(tcLength)
 	    	.value();
     	
     	var values = _(localkeywords).pluck('score'),
@@ -560,7 +596,7 @@
     		tc = $(".play-tagcloud li");
     		
 		localkeywords.forEach(function(w, i) {
-			var size = 10 + (w.score - min) * scale,
+			var size = 12 + (w.score - min) * scale,
 				selected = (w.word === selectedWord),
 				e = $(tc[i]),
 				t = e.text();
@@ -575,8 +611,8 @@
 			}
 			selectedVisible = selectedVisible || selected;
 		});
-		if (localkeywords.length < 39) {
-			for (var i = localkeywords.length; i < 39; i++) {
+		if (localkeywords.length < tcLength) {
+			for (var i = localkeywords.length; i < tcLength; i++) {
 				$(tc[i]).text("").removeClass("selected");
 			}
 		}
@@ -588,7 +624,9 @@
 		throttledGetTweets();
     }
     
-    for (var i = 0; i < 39; i++) {
+    var tcLength = 20;
+    
+    for (var i = 0; i < tcLength; i++) {
     	$(".play-tagcloud").append("<li>");
     }
     
@@ -618,7 +656,9 @@
     	tweetstructure = {},
     	requestedtweets = {},
     	_NTWEETS = 50,
-    	selectedWord = false;
+    	selectedWord = false,
+    	lastHtml = "";
+    
     
     function showTweets() {
     	var toshow = [];
@@ -669,7 +709,7 @@
 			return b.topic.weight - a.topic.weight; 
 		});
 		
-		if (tweetstoshow.length < 8) {
+		if (tweetstoshow.length < 4) {
 			var randtweets = data.randomtweets.filter(function(tw) {
 				return (tw.timestamp > (localpos - localduration / 2)) && (tw.timestamp < (localpos + localduration / 2))
 			});
@@ -679,14 +719,14 @@
 					return rx.test(tw.data.text);
 				});
 			}
-			var mod = Math.ceil(randtweets.length / 8);
+			var mod = Math.ceil(randtweets.length / 5);
 			randtweets = randtweets.filter(function(v,k) {
 				return !(k % mod);
 			});
 			tweetstoshow = tweetstoshow.concat(randtweets);
 		}
 		
-		tweetstoshow = tweetstoshow.slice(0,10);
+		tweetstoshow = tweetstoshow.slice(0,6);
 		
 		if (selectedWord) {
 			var rx = new RegExp( '(' + selectedWord.replace(/(\W)/gm,'\\$1') + ')', 'gim' );
@@ -710,7 +750,10 @@
 		
 		var html = tweetstoshow.map(tweetTemplate).join("");
 		
-		$(".play-localtweets").html(html);
+		if (lastHtml !== html) {
+		    $(".play-localtweets").html(html);
+		}
+		lastHtml = html;
 		var h = 0;
 		$(".play-localtweets .tweet").each(function() {
 			h += $(this).outerHeight();
@@ -873,7 +916,7 @@
    	player.on("timeupdate", function(t) {
    		playTime.text(secsToString(t));
     	if (timelock) {
-    		localpos = Math.max(localduration / 2, Math.min(data.duration - localduration / 2, t));
+    		localpos = Math.max(localduration / 2, Math.min(data.duration - localduration / 2, t + localduration / 6));
     	}
     	throttledShowLocal();
    	});
@@ -924,7 +967,7 @@
 			if (timelock) {
     			player.setCurrentTime(Math.max(0, Math.min(data.duration, Math.floor(posY / yscale))));
 			} else {
-				localpos = Math.max(localduration / 2, Math.min(data.duration - localduration / 2, Math.floor(posY / yscale)));
+				localpos = Math.max(localduration / 2, Math.min(data.duration - localduration / 2, Math.floor(posY / yscale) + localduration / 6));
 				throttledShowLocal();
 			}
 		}
@@ -985,8 +1028,9 @@
 	    		newlevel = Math.max(0, Math.min(zoomlevels.length - 1, currentlevel + d));
     		if (newlevel !== currentlevel) {
     			currentlevel = newlevel;
+    			var oldduration = localduration;
     			localduration = zoomlevels[currentlevel];
-    			localpos = Math.max(localduration / 2, Math.min(data.duration - localduration / 2, localpos));
+    			localpos = Math.max(localduration / 2, Math.min(data.duration - localduration / 2, localpos - (oldduration - localduration) / 6 ));
     			throttledShowLocal();
     		}
 	        totalScroll = 0;
@@ -1020,49 +1064,73 @@
     	.on("mouseleave touchend", function() {
     		clearInterval(moveInterval);
     	});
+    var usersCache = {};
     
-    $(".play-localtweets").on("click", "li", function() {
-    	player.setCurrentTime(parseInt($(this).attr("data-timestamp")));
-    	return false;
-    });
+    function showUserTweets(userid) {
+        var tweets = usersCache[userid];
+		tweets.forEach(function(tweet) {
+			tweet.timestamp = new Date(tweet.created_at).valueOf() / 1000 - deltaT;
+		});
+		tweets = tweets.filter(function(tweet) {
+		    return tweet.timestamp > 0 && tweet.timestamp < data.duration;
+		});
+		tweets.sort(function(a,b) {
+			return a.timestamp - b.timestamp;
+		})
+		var html = tweets.reduce(function(mem, tweet) {
+			return mem + tweetTemplate({
+				timestamp: tweet.timestamp,
+				topic: {topic: -1},
+				weight: 0,
+				data: tweet,
+				htext: _(tweet.text).escape(),
+				show_link: false,
+				show_time: true
+			});
+		},"");
+		$(".user-tweets").show();
+		$(".user-tweets-list").html(html);
+		$(".user-name").text(tweets[0].from_user_name);
+    }
+    
     $(".play-localtweets").on("click", "li a", function() {
     	var userid = $(this).attr("data-user-id");
-    	$.getJSON(
-			solrUrl(
-				"twitter",
-				{
-					q: "from_user_id:" + userid,
-					fl: "id_str,created_at,from_user_name,text,profile_image_url,from_user_id",
-					rows: 500
-				}
-			),
-			function(t) {
-				var tweets = t.response.docs;
-				tweets.forEach(function(tweet) {
-					tweet.timestamp = new Date(tweet.created_at).valueOf() / 1000 - deltaT;
-				});
-				tweets.sort(function(a,b) {
-					return a.timestamp - b.timestamp;
-				})
-				var html = tweets.reduce(function(mem, tweet) {
-					return mem + tweetTemplate({
-						timestamp: tweet.timestamp,
-						topic: {topic: -1},
-						weight: 0,
-						data: tweet,
-						htext: _(tweet.text).escape(),
-						show_link: false,
-						show_time: true
-					});
-				},"");
-				$(".user-tweets").show();
-				$(".user-tweets-list").html(html);
-				$(".user-name").text(tweets[0].from_user_name);
-			}
-		);
+        $(".user-tweets").show();
+        $(".user-tweets-list").html("<li class='loading'>Chargement en cours</li>");
+        $(".user-name").text($(this).parents("li.tweet").find("p a").text().replace(/(^@|:$)/g,""));
+    	if (!usersCache[userid]) {
+    	    usersCache[userid] = [];
+        	$.getJSON(
+    			solrUrl(
+    				"twitter",
+    				{
+    					q: "from_user_id:" + userid,
+    					fl: "id_str,created_at,from_user_name,text,profile_image_url,from_user_id",
+    					rows: 500
+    				}
+    			),
+    			function(t) {
+    				usersCache[userid] = t.response.docs;
+                    showUserTweets(userid);
+    			}
+    		);
+		} else {
+		    showUserTweets(userid);
+		}
 		return false;
     });
     
+    $(".user-tweets").on("click", "li", function() {
+        player.setCurrentTime(parseInt($(this).attr("data-timestamp")));
+        return false;
+    }).on("mouseenter", "li", function() {
+        currentTweetTc = parseInt($(this).attr("data-timestamp"));
+        throttledShowLocal();
+    }).on("mouseleave", "li", function() {
+        currentTweetTc = -1;
+        throttledShowLocal();
+    });
+    
     var timelock = true;
     
     $(".lock-button").click(function() {
@@ -1075,7 +1143,13 @@
     	return false;
     });
     
-    $(window).on("resize", throttledShowLocal)
+    $(window).on("resize", throttledShowLocal);
+    
+    $(".close-user-tweets").click(function() {
+        currentTweetTc = -1;
+        $(".user-tweets").hide();
+        return false;
+    })
     
     checkOrGoNext();
 }
--- a/playscreen-frame.html	Mon Apr 22 18:42:40 2013 +0200
+++ b/playscreen-frame.html	Wed Apr 24 17:54:48 2013 +0200
@@ -49,6 +49,7 @@
                 	<ul class="play-localtweets"></ul>
                 	<ul class="play-tagcloud"></ul>
                 	<div class="user-tweets">
+                	    <a class="close-user-tweets" href="#">&times;</a>
                 		<h3 class="user-tweets-head">Tweets par <span class="user-name"></span></h3>
                 		<ul class="user-tweets-list"></ul>
                 	</div>
--- a/playscreen.html	Mon Apr 22 18:42:40 2013 +0200
+++ b/playscreen.html	Wed Apr 24 17:54:48 2013 +0200
@@ -48,6 +48,7 @@
                 	<ul class="play-localtweets"></ul>
                 	<ul class="play-tagcloud"></ul>
                 	<div class="user-tweets">
+                        <a class="close-user-tweets" href="#">&times;</a>
                 		<h3 class="user-tweets-head">Tweets par <span class="user-name"></span></h3>
                 		<ul class="user-tweets-list"></ul>
                 	</div>