Author: scottbw
Date: Fri Jan 13 08:56:37 2012
New Revision: 1230925

URL: http://svn.apache.org/viewvc?rev=1230925&view=rev
Log:
Added friendly times to tweets such as "about a minute ago" using JQuery 
TimeAgo plugin

Added:
    
incubator/wookie/trunk/widgets/templates/widgets/twitter/content_scripts.html
    incubator/wookie/trunk/widgets/templates/widgets/twitter/lib/
    
incubator/wookie/trunk/widgets/templates/widgets/twitter/lib/jquery.timeago.js
    incubator/wookie/trunk/widgets/templates/widgets/twitter/scripts/
    
incubator/wookie/trunk/widgets/templates/widgets/twitter/scripts/twidget_controller.js
Modified:
    
incubator/wookie/trunk/widgets/templates/widgets/twitter/style/screen.css.add
    incubator/wookie/trunk/widgets/templates/widgets/twitter/widget.properties

Added: 
incubator/wookie/trunk/widgets/templates/widgets/twitter/content_scripts.html
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/templates/widgets/twitter/content_scripts.html?rev=1230925&view=auto
==============================================================================
--- 
incubator/wookie/trunk/widgets/templates/widgets/twitter/content_scripts.html 
(added)
+++ 
incubator/wookie/trunk/widgets/templates/widgets/twitter/content_scripts.html 
Fri Jan 13 08:56:37 2012
@@ -0,0 +1,5 @@
+<script type="text/javascript" 
src="http://code.jquery.com/jquery-1.6.4.min.js";></script>
+<script type="text/javascript" 
src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js";></script>
+<!-- Added the timeago JQuery plugin -->
+<script type="text/javascript" src="lib/jquery.timeago.js"></script>
+<script type="text/javascript" src="scripts/controller.js"></script>

Added: 
incubator/wookie/trunk/widgets/templates/widgets/twitter/lib/jquery.timeago.js
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/templates/widgets/twitter/lib/jquery.timeago.js?rev=1230925&view=auto
==============================================================================
--- 
incubator/wookie/trunk/widgets/templates/widgets/twitter/lib/jquery.timeago.js 
(added)
+++ 
incubator/wookie/trunk/widgets/templates/widgets/twitter/lib/jquery.timeago.js 
Fri Jan 13 08:56:37 2012
@@ -0,0 +1,146 @@
+/**
+ * Timeago is a jQuery plugin that makes it easy to support automatically
+ * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
+ *
+ * @name timeago
+ * @version 0.10.0
+ * @requires jQuery v1.2.3+
+ * @author Ryan McGeary
+ * @license MIT License - http://www.opensource.org/licenses/mit-license.php
+ *
+ * For usage and examples, visit:
+ * http://timeago.yarp.com/
+ *
+ * Copyright (c) 2008-2011, Ryan McGeary (ryanonjavascript -[at]- mcgeary 
[*dot*] org)
+ */
+(function($) {
+  $.timeago = function(timestamp) {
+    if (timestamp instanceof Date) {
+      return inWords(timestamp);
+    } else if (typeof timestamp === "string") {
+      return inWords($.timeago.parse(timestamp));
+    } else {
+      return inWords($.timeago.datetime(timestamp));
+    }
+  };
+  var $t = $.timeago;
+
+  $.extend($.timeago, {
+    settings: {
+      refreshMillis: 60000,
+      allowFuture: false,
+      strings: {
+        prefixAgo: null,
+        prefixFromNow: null,
+        suffixAgo: "ago",
+        suffixFromNow: "from now",
+        seconds: "less than a minute",
+        minute: "about a minute",
+        minutes: "%d minutes",
+        hour: "about an hour",
+        hours: "about %d hours",
+        day: "a day",
+        days: "%d days",
+        month: "about a month",
+        months: "%d months",
+        year: "about a year",
+        years: "%d years",
+        numbers: []
+      }
+    },
+    inWords: function(distanceMillis) {
+      var $l = this.settings.strings;
+      var prefix = $l.prefixAgo;
+      var suffix = $l.suffixAgo;
+      if (this.settings.allowFuture) {
+        if (distanceMillis < 0) {
+          prefix = $l.prefixFromNow;
+          suffix = $l.suffixFromNow;
+        }
+      }
+
+      var seconds = Math.abs(distanceMillis) / 1000;
+      var minutes = seconds / 60;
+      var hours = minutes / 60;
+      var days = hours / 24;
+      var years = days / 365;
+
+      function substitute(stringOrFunction, number) {
+        var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, 
distanceMillis) : stringOrFunction;
+        var value = ($l.numbers && $l.numbers[number]) || number;
+        return string.replace(/%d/i, value);
+      }
+
+      var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) 
||
+        seconds < 90 && substitute($l.minute, 1) ||
+        minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
+        minutes < 90 && substitute($l.hour, 1) ||
+        hours < 24 && substitute($l.hours, Math.round(hours)) ||
+        hours < 48 && substitute($l.day, 1) ||
+        days < 30 && substitute($l.days, Math.floor(days)) ||
+        days < 60 && substitute($l.month, 1) ||
+        days < 365 && substitute($l.months, Math.floor(days / 30)) ||
+        years < 2 && substitute($l.year, 1) ||
+        substitute($l.years, Math.floor(years));
+
+      return $.trim([prefix, words, suffix].join(" "));
+    },
+    parse: function(iso8601) {
+      var s = $.trim(iso8601);
+      s = s.replace(/\.\d\d\d+/,""); // remove milliseconds
+      s = s.replace(/-/,"/").replace(/-/,"/");
+      s = s.replace(/T/," ").replace(/Z/," UTC");
+      s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
+      return new Date(s);
+    },
+    datetime: function(elem) {
+      // jQuery's `is()` doesn't play well with HTML5 in IE
+      var isTime = $(elem).get(0).tagName.toLowerCase() === "time"; // 
$(elem).is("time");
+      var iso8601 = isTime ? $(elem).attr("datetime") : $(elem).attr("title");
+      return $t.parse(iso8601);
+    }
+  });
+
+  $.fn.timeago = function() {
+    var self = this;
+    self.each(refresh);
+
+    var $s = $t.settings;
+    if ($s.refreshMillis > 0) {
+      setInterval(function() { self.each(refresh); }, $s.refreshMillis);
+    }
+    return self;
+  };
+
+  function refresh() {
+    var data = prepareData(this);
+    if (!isNaN(data.datetime)) {
+      $(this).text(inWords(data.datetime));
+    }
+    return this;
+  }
+
+  function prepareData(element) {
+    element = $(element);
+    if (!element.data("timeago")) {
+      element.data("timeago", { datetime: $t.datetime(element) });
+      var text = $.trim(element.text());
+      if (text.length > 0) {
+        element.attr("title", text);
+      }
+    }
+    return element.data("timeago");
+  }
+
+  function inWords(date) {
+    return $t.inWords(distance(date));
+  }
+
+  function distance(date) {
+    return (new Date().getTime() - date.getTime());
+  }
+
+  // fix for IE6 suckage
+  document.createElement("abbr");
+  document.createElement("time");
+}(jQuery));

Added: 
incubator/wookie/trunk/widgets/templates/widgets/twitter/scripts/twidget_controller.js
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/templates/widgets/twitter/scripts/twidget_controller.js?rev=1230925&view=auto
==============================================================================
--- 
incubator/wookie/trunk/widgets/templates/widgets/twitter/scripts/twidget_controller.js
 (added)
+++ 
incubator/wookie/trunk/widgets/templates/widgets/twitter/scripts/twidget_controller.js
 Fri Jan 13 08:56:37 2012
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Change created times into friendly strings like "2 minutes ago"
+ * using the TimeAgo JQuery plugin. We trigger this on document
+ * load and whenever the results are updated.
+ */
+$(document).ready(function() {
+ $('abbr.timeago').timeago();
+ $('body').bind('results_updated', function() {
+   $('abbr.timeago').timeago();
+});
+});
\ No newline at end of file

Modified: 
incubator/wookie/trunk/widgets/templates/widgets/twitter/style/screen.css.add
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/templates/widgets/twitter/style/screen.css.add?rev=1230925&r1=1230924&r2=1230925&view=diff
==============================================================================
--- 
incubator/wookie/trunk/widgets/templates/widgets/twitter/style/screen.css.add 
(original)
+++ 
incubator/wookie/trunk/widgets/templates/widgets/twitter/style/screen.css.add 
Fri Jan 13 08:56:37 2012
@@ -29,9 +29,21 @@
        background-image: none;
 }
 
+/*
+ * The time metadata for the tweet
+ */
+.timeago {
+       font-size: 60%;
+    color: #186268;
+}
+
+/*
+ * Override slightly annoying text shadow from JQMobile
+ */
 .tweet {
     font: 100% Georgia, serif;
     color: #085258;
+    text-shadow: none;
 }
 
 .tweet_list {
@@ -52,11 +64,4 @@
 
 .tweet_list .tweet_avatar {
   padding-right: .5em; float: left;
-}
-
-/*
- * Override slightly annoying text shadow from JQMobile
- */
-.tweet_text {
-  text-shadow: none;
 }
\ No newline at end of file

Modified: 
incubator/wookie/trunk/widgets/templates/widgets/twitter/widget.properties
URL: 
http://svn.apache.org/viewvc/incubator/wookie/trunk/widgets/templates/widgets/twitter/widget.properties?rev=1230925&r1=1230924&r2=1230925&view=diff
==============================================================================
--- incubator/wookie/trunk/widgets/templates/widgets/twitter/widget.properties 
(original)
+++ incubator/wookie/trunk/widgets/templates/widgets/twitter/widget.properties 
Fri Jan 13 08:56:37 2012
@@ -53,7 +53,7 @@ browse.collection.template = "<div id='r
 #
 # type: string
 #
-browse.item.summary.template = <li class='tweet result' wid='${ID}'><a 
href='#' 
onclick=${widget.shortname}_browse_controller.search('${SCREEN_NAME}')><img 
class='tweet_avatar' alt='Avatar for ${SCREEN_NAME}; click to read more tweets 
from this user' title='See more tweets from ${SCREEN_NAME}'  
src='${PROFILE_IMAGE_URL}'></a><span class='tweet_text'>${TEXT}</span></b><div 
class='detail'></div></li>
+browse.item.summary.template = <li class='tweet result' wid='${ID}'><a 
href='#' 
onclick=${widget.shortname}_browse_controller.search('${SCREEN_NAME}')><img 
class='tweet_avatar' alt='Avatar for ${SCREEN_NAME}; click to read more tweets 
from this user' title='See more tweets from ${SCREEN_NAME}'  
src='${PROFILE_IMAGE_URL}'></a><span class='tweet_text'>${TEXT}</span></b><br 
clear='left'><abbr class='timeago' 
title='${CREATED_AT}'>${CREATED_AT}</abbr><div class='detail'></div></li>
 
 #
 # The names of the elements to map into the template placeholders. E.g. if it 
contains "title", then $TITLE in the template 


Reply via email to