Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Now even better #37

Open
wants to merge 2 commits into from

2 participants

@ArdaXi

Modified to use Streamie's linkify, and removed jQuery, among others.

@cramforce cramforce commented on the diff
public/lib/stream/streamplugins.js
((23 lines not shown))
- //hide after 5 seconds
- setTimeout(function() {
- notification.cancel();
- }, 5000);
- } catch(e) {
+ if(tweet.mentioned && !settings.get('notifications', 'mentions')) {
+ return
+ }
+ if(tweet.direct_message && !settings.get('notifications', 'direct')) {
+ return
+ }
+ if(!tweet.mentioned && !tweet.direct_message && !settings.get('notifications', 'tweets')) {
+ return
+ }
+ try {
+ var tweetHash = {
@cramforce Owner

Here the formatting is a little off. Two space indent and no quoting of keys please. 1 space after :.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@cramforce cramforce commented on the diff
public/lib/stream/streamplugins.js
((31 lines not shown))
+ if(tweet.direct_message && !settings.get('notifications', 'direct')) {
+ return
+ }
+ if(!tweet.mentioned && !tweet.direct_message && !settings.get('notifications', 'tweets')) {
+ return
+ }
+ try {
+ var tweetHash = {
+ 'name':tweet.data.user.screen_name,
+ 'screen_name':tweet.data.user.screen_name,
+ 'avatar':tweet.data.user.profile_image_url,
+ 'text':tweet.textHTML,
+ 'created_at':tweet.data.created_at,
+ 'source':tweet.data.source,
+ };
+ if(tweet.data.retweeted_status)
@cramforce Owner

Please always use brackets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@cramforce cramforce commented on the diff
public/lib/stream/streamplugins.js
((32 lines not shown))
+ return
+ }
+ if(!tweet.mentioned && !tweet.direct_message && !settings.get('notifications', 'tweets')) {
+ return
+ }
+ try {
+ var tweetHash = {
+ 'name':tweet.data.user.screen_name,
+ 'screen_name':tweet.data.user.screen_name,
+ 'avatar':tweet.data.user.profile_image_url,
+ 'text':tweet.textHTML,
+ 'created_at':tweet.data.created_at,
+ 'source':tweet.data.source,
+ };
+ if(tweet.data.retweeted_status)
+ tweetHash.RTby = {
@cramforce Owner

above you use _ to separate, here MIXEDCase

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@cramforce cramforce commented on the diff
public/notification/notification.html
((25 lines not shown))
+ width: 48px;
+}
+#img{
+ width: 48px;
+}
+a
+{
+ color: #2276BB;
+}
+a:link {text-decoration:none}
+a:visited {text-decoration:none}
+a:hover {text-decoration:underline}
+a:active {text-decoration:underline}
+a#user
+{
+ font-weight: bold;
@cramforce Owner

You are not completly consistent with the CSS indenting. Please also put the opening { on the opening line

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@cramforce cramforce commented on the diff
public/notification/notification.js
((91 lines not shown))
+ var img = document.getElementById('avatar'), span = document.getElementById('msg'), user = document.getElementById('user'), entities = tweet.entities, retweeted = false;
+ img.src = tweet.avatar;
+ img.onclick = function() { openLink("http://twitter.com/"+tweet.screen_name); };
+ user.onclick = function() { openLink("http://twitter.com/"+tweet.screen_name); };
+ user.innerHTML = tweet.name;
+ if(tweet.RTby != null)
+ {
+ $('#rtby').text(tweet.RTby.name).click(function() { openLink("http://twitter.com/"+tweet.RTby.screen_name); });
+ $('#rt').show();
+ }
+ span.innerHTML = tweet.text;
+ var tweetDate = new Date(tweet.created_at);
+ $('#timestamp').attr({
+ 'title': iso8601(tweetDate),
+ 'href': "http://twitter.com/"+tweet.screen_name+"/status/"+tweet.id_str
+ }).text(tweetDate.format("H:i M jS")).timeago();
@cramforce Owner

I think tweet.age should have the info you need (maybe the streamie-age plugin needs to persist the formatted string into the tweet structure). THen could remove the full plugin.

@ArdaXi
ArdaXi added a note

I would use Streamie's age, but then it wouldn't auto-update, and it would always be stuck on 5 seconds or some such.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@cramforce cramforce commented on the diff
public/notification/notification.js
((70 lines not shown))
+ U: function() { return this.getTime() / 1000; }
+};var zeropad = function (num) {
+ return ((num < 10) ? '0' : '') + num;
+};
+
+var iso8601 = function (date) {
+ return date.getUTCFullYear()
+ + "-" + zeropad(date.getUTCMonth()+1)
+ + "-" + zeropad(date.getUTCDate())
+ + "T" + zeropad(date.getUTCHours())
+ + ":" + zeropad(date.getUTCMinutes())
+ + ":" + zeropad(date.getUTCSeconds()) + "Z";
+};
+
+function openLink(url)
+{
@cramforce Owner

Please up the { on the opening line.
I'm so string about this because this is fatal:

return
{
foo: 'bar'
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@cramforce
Owner

Thanks! I added a few comments. I think we are not too far off from putting this in!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 13, 2011
  1. @ArdaXi
Commits on Feb 22, 2011
  1. @ArdaXi
This page is out of date. Refresh to see the latest.
View
141 public/ext/jquery.timeago.js
@@ -0,0 +1,141 @@
+/*
+ * timeago: a jQuery plugin, version: 0.9.2 (2010-09-14)
+ * @requires jQuery v1.2.3 or later
+ *
+ * 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").
+ *
+ * For usage and examples, visit:
+ * http://timeago.yarp.com/
+ *
+ * Licensed under the MIT:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * Copyright (c) 2008-2010, 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;
+ }
+ distanceMillis = Math.abs(distanceMillis);
+ }
+
+ var seconds = 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);
View
54 public/lib/stream/streamplugins.js
@@ -443,30 +443,36 @@ require.def("stream/streamplugins",
settings.get('notifications', 'enableWebkitNotifications') &&
window.webkitNotifications &&
window.webkitNotifications.checkPermission() == 0) {
- if(tweet.mentioned && !settings.get('notifications', 'mentions')) {
- return
- }
- if(tweet.direct_message && !settings.get('notifications', 'direct')) {
- return
- }
- if(!tweet.mentioned && !tweet.direct_message && !settings.get('notifications', 'tweets')) {
- return
- }
- try {
- var notification =
- window.webkitNotifications.createNotification(tweet.data.user.profile_image_url,
- tweet.data.user.name,
- tweet.data.text);
- notification.show();
- notification.onclose = function() {
- --plugin.current;
- } //onclose
- ++plugin.current;
- //hide after 5 seconds
- setTimeout(function() {
- notification.cancel();
- }, 5000);
- } catch(e) {
+ if(tweet.mentioned && !settings.get('notifications', 'mentions')) {
+ return
+ }
+ if(tweet.direct_message && !settings.get('notifications', 'direct')) {
+ return
+ }
+ if(!tweet.mentioned && !tweet.direct_message && !settings.get('notifications', 'tweets')) {
+ return
+ }
+ try {
+ var tweetHash = {
@cramforce Owner

Here the formatting is a little off. Two space indent and no quoting of keys please. 1 space after :.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ 'name':tweet.data.user.screen_name,
+ 'screen_name':tweet.data.user.screen_name,
+ 'avatar':tweet.data.user.profile_image_url,
+ 'text':tweet.textHTML,
+ 'created_at':tweet.data.created_at,
+ 'source':tweet.data.source,
+ };
+ if(tweet.data.retweeted_status)
@cramforce Owner

Please always use brackets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ tweetHash.RTby = {
@cramforce Owner

above you use _ to separate, here MIXEDCase

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ 'screen_name': tweet.data.retweeted_status.user.screen_name,
+ 'name': tweet.data.retweeted_status.user.name
+ };
+ var notification = window.webkitNotifications.createHTMLNotification("notification\notification.html#"+JSON.stringify(tweetHash));
+ notification.show();
+ notification.onclose = function() {
+ --plugin.current;
+ } //onclose
+ ++plugin.current;
+ } catch(e) {
}
}
this();
View
96 public/notification/notification.html
@@ -0,0 +1,96 @@
+<html>
+<head>
+<script type="text/javascript" src="http://www.google.com/jsapi">
+</script>
+<script type="text/javascript">
+ google.load("jquery", "1.4.2");
+</script>
+<script type="text/javascript" src="ext/jquery.timeago.js"></script>
+<script type="text/javascript" src="notification.js"></script>
+<style>
+body
+{
+ font: 84% Arial, sans-serif
+}
+#top
+{
+ width: 270px;
+}
+#avatar
+{
+ margin: 0px 5px 5px 0px;
+ padding-bottom: 5px;
+ float: left;
+ height: 48px;
+ width: 48px;
+}
+#img{
+ width: 48px;
+}
+a
+{
+ color: #2276BB;
+}
+a:link {text-decoration:none}
+a:visited {text-decoration:none}
+a:hover {text-decoration:underline}
+a:active {text-decoration:underline}
+a#user
+{
+ font-weight: bold;
@cramforce Owner

You are not completly consistent with the CSS indenting. Please also put the opening { on the opening line

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+}
+a#user:link {color:#333}
+a#user:visited {color:#333}
+a#user:hover {color:#2276BB}
+a#user:active {color:#2276BB}
+span#rt
+{
+ color:#333;
+ font-size: 11px;
+ display: none;
+}
+#main
+{
+ width: 217px;
+ float: right;
+ padding-bottom: 5px;
+}
+#bottom
+{
+ color: #999 !important;
+ font-size: 11px;
+ padding-bottom: 5px;
+}
+#bottom a
+{
+ color: #999 !important;
+}
+.btext
+{
+ white-space:nowrap;
+}
+#tlogo
+{
+ float: right;
+ padding-bottom: 5px;
+ margin-right: 5px;
+}
+</style>
+</head>
+<body>
+<div id="container">
+ <div id="top">
+ <div id="img">
+ <a href="#"><img width="48" height="48" id="avatar"/></a>
+ </div>
+ <div id="main">
+ <a id="user" href="#"></a> <span id="rt">(Retweeted by <a id="rtby" href="#"></a>)</span> <span id="msg"></span><br/>
+ </div>
+ </div>
+ <div id="bottom">
+ <span class="btext"><a id="timestamp"></a> <span id="via">via web</span></span>
+ <a href="http://twitter.com/"><img id="tlogo" src="http://a0.twimg.com/a/1285890902/images/twitter_t_logo_outline.png" height="20" width="16"/></a>
+ </div>
+</div>
+</body>
+</html>
View
125 public/notification/notification.js
@@ -0,0 +1,125 @@
+
+// Simulates PHP's date function
+Date.prototype.format = function(format) {
+ var returnStr = '';
+ var replace = Date.replaceChars;
+ for (var i = 0; i < format.length; i++) {
+ var curChar = format.charAt(i);
+ if (i - 1 >= 0 && format.charAt(i - 1) == "\\") {
+ returnStr += curChar;
+ }
+ else if (replace[curChar]) {
+ returnStr += replace[curChar].call(this);
+ } else if (curChar != "\\"){
+ returnStr += curChar;
+ }
+ }
+ return returnStr;
+};
+
+Date.replaceChars = {
+ shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+ longMonths: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ longDays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+
+ // Day
+ d: function() { return (this.getDate() < 10 ? '0' : '') + this.getDate(); },
+ D: function() { return Date.replaceChars.shortDays[this.getDay()]; },
+ j: function() { return this.getDate(); },
+ l: function() { return Date.replaceChars.longDays[this.getDay()]; },
+ N: function() { return this.getDay() + 1; },
+ S: function() { return (this.getDate() % 10 == 1 && this.getDate() != 11 ? 'st' : (this.getDate() % 10 == 2 && this.getDate() != 12 ? 'nd' : (this.getDate() % 10 == 3 && this.getDate() != 13 ? 'rd' : 'th'))); },
+ w: function() { return this.getDay(); },
+ z: function() { var d = new Date(this.getFullYear(),0,1); return Math.ceil((this - d) / 86400000); }, // Fixed now
+ // Week
+ W: function() { var d = new Date(this.getFullYear(), 0, 1); return Math.ceil((((this - d) / 86400000) + d.getDay() + 1) / 7); }, // Fixed now
+ // Month
+ F: function() { return Date.replaceChars.longMonths[this.getMonth()]; },
+ m: function() { return (this.getMonth() < 9 ? '0' : '') + (this.getMonth() + 1); },
+ M: function() { return Date.replaceChars.shortMonths[this.getMonth()]; },
+ n: function() { return this.getMonth() + 1; },
+ t: function() { var d = new Date(); return new Date(d.getFullYear(), d.getMonth(), 0).getDate() }, // Fixed now, gets #days of date
+ // Year
+ L: function() { var year = this.getFullYear(); return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)); }, // Fixed now
+ o: function() { var d = new Date(this.valueOf()); d.setDate(d.getDate() - ((this.getDay() + 6) % 7) + 3); return d.getFullYear();}, //Fixed now
+ Y: function() { return this.getFullYear(); },
+ y: function() { return ('' + this.getFullYear()).substr(2); },
+ // Time
+ a: function() { return this.getHours() < 12 ? 'am' : 'pm'; },
+ A: function() { return this.getHours() < 12 ? 'AM' : 'PM'; },
+ B: function() { return Math.floor((((this.getUTCHours() + 1) % 24) + this.getUTCMinutes() / 60 + this.getUTCSeconds() / 3600) * 1000 / 24); }, // Fixed now
+ g: function() { return this.getHours() % 12 || 12; },
+ G: function() { return this.getHours(); },
+ h: function() { return ((this.getHours() % 12 || 12) < 10 ? '0' : '') + (this.getHours() % 12 || 12); },
+ H: function() { return (this.getHours() < 10 ? '0' : '') + this.getHours(); },
+ i: function() { return (this.getMinutes() < 10 ? '0' : '') + this.getMinutes(); },
+ s: function() { return (this.getSeconds() < 10 ? '0' : '') + this.getSeconds(); },
+ u: function() { var m = this.getMilliseconds(); return (m < 10 ? '00' : (m < 100 ?
+'0' : '')) + m; },
+ // Timezone
+ e: function() { return "Not Yet Supported"; },
+ I: function() { return "Not Yet Supported"; },
+ O: function() { return (-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + '00'; },
+ P: function() { return (-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + ':00'; }, // Fixed now
+ T: function() { var m = this.getMonth(); this.setMonth(0); var result = this.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/, '$1'); this.setMonth(m); return result;},
+ Z: function() { return -this.getTimezoneOffset() * 60; },
+ // Full Date/Time
+ c: function() { return this.format("Y-m-d\\TH:i:sP"); }, // Fixed now
+ r: function() { return this.toString(); },
+ U: function() { return this.getTime() / 1000; }
+};var zeropad = function (num) {
+ return ((num < 10) ? '0' : '') + num;
+};
+
+var iso8601 = function (date) {
+ return date.getUTCFullYear()
+ + "-" + zeropad(date.getUTCMonth()+1)
+ + "-" + zeropad(date.getUTCDate())
+ + "T" + zeropad(date.getUTCHours())
+ + ":" + zeropad(date.getUTCMinutes())
+ + ":" + zeropad(date.getUTCSeconds()) + "Z";
+};
+
+function openLink(url)
+{
@cramforce Owner

Please up the { on the opening line.
I'm so string about this because this is fatal:

return
{
foo: 'bar'
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ window.open(url);
+}
+
+function tweetToHTML(tweet)
+{
+ var img = document.getElementById('avatar'), span = document.getElementById('msg'), user = document.getElementById('user'), entities = tweet.entities, retweeted = false;
+ img.src = tweet.avatar;
+ img.onclick = function() { openLink("http://twitter.com/"+tweet.screen_name); };
+ user.onclick = function() { openLink("http://twitter.com/"+tweet.screen_name); };
+ user.innerHTML = tweet.name;
+ if(tweet.RTby != null)
+ {
+ $('#rtby').text(tweet.RTby.name).click(function() { openLink("http://twitter.com/"+tweet.RTby.screen_name); });
+ $('#rt').show();
+ }
+ span.innerHTML = tweet.text;
+ var tweetDate = new Date(tweet.created_at);
+ $('#timestamp').attr({
+ 'title': iso8601(tweetDate),
+ 'href': "http://twitter.com/"+tweet.screen_name+"/status/"+tweet.id_str
+ }).text(tweetDate.format("H:i M jS")).timeago();
@cramforce Owner

I think tweet.age should have the info you need (maybe the streamie-age plugin needs to persist the formatted string into the tweet structure). THen could remove the full plugin.

@ArdaXi
ArdaXi added a note

I would use Streamie's age, but then it wouldn't auto-update, and it would always be stuck on 5 seconds or some such.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $('#via').html("via "+tweet.source);
+
+ $('a').filter(function(index){ return this.href != "#" }).each(function(index){
+ $(this).click(function(){
+ openLink(this.href);
+ });
+ this.href = "#";
+ });
+}
+
+$().ready(function() {
+ var tweet = JSON.parse(window.location.hash.substring(1));
+ tweetToHTML(tweet);
+ setTimeout("window.close()", 20000);
+ if($("#main").height() > 48)
+ {
+ $("#top").height($("#main").height());
+ }
+});
Something went wrong with that request. Please try again.