<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>.gitignore</filename>
    </added>
    <added>
      <filename>public/audio/CRcv.mp3</filename>
    </added>
    <added>
      <filename>public/audio/CSnd.mp3</filename>
    </added>
    <added>
      <filename>public/audio/New.mp3</filename>
    </added>
    <added>
      <filename>public/audio/Off.mp3</filename>
    </added>
    <added>
      <filename>public/audio/On.mp3</filename>
    </added>
    <added>
      <filename>public/images/main/refresh_bolt.png</filename>
    </added>
    <added>
      <filename>public/images/notification.png</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,5 +1,6 @@
 --- 
-:aid: 3f11c3b0-a24a-012b-db63-001b63ad589b
+:websdk: 3.0.0
+:service: websdk
 :controls: 
 - :version: 3.0.0
   :checksum: 7b9c5f2803041dc431947d13948ffe2a
@@ -28,10 +29,31 @@
 - :version: 3.0.0
   :checksum: 29580baeab55aa1ec40755eec311ab8e
   :name: textarea
-:service: websdk
-:websdk: 3.0.0
+:aid: a7c36d00-a2e7-012b-ac97-001b63ad589b
 :name: tweetanium
 :service_version: 3.0.0
+:behaviors: 
+- :version: 3.0.0
+  :checksum: 5c0f768af325b5c88c7efbd0e08a9d6c
+  :name: draggable
+- :version: 3.0.0
+  :checksum: 8a678b67665ea104a1ce6ac89c5a540a
+  :name: modal
+- :version: 3.0.0
+  :checksum: 69973cee238c78231617c5d154454026
+  :name: reflection
+- :version: 3.0.0
+  :checksum: 2ace88a4a49f4dd46cdd1d1dc29c91ba
+  :name: resizable
+- :version: 3.0.0
+  :checksum: 5647c370f68b8c8c226b83bec4ad745e
+  :name: rounded
+- :version: 3.0.0
+  :checksum: b625f21b617c4a159dd0574ec21fc181
+  :name: shadow
+- :version: 3.0.0
+  :checksum: 47d4342f36fa998ec4f340cea7271068
+  :name: tooltip
 :widgets: 
 - :version: 3.0.0
   :checksum: 85f81f8bdef04171d3fb48472ab65c51
@@ -69,28 +91,6 @@
 - :version: 3.0.0
   :checksum: 50385bf1ec85d18840f53c6b8f12fb60
   :name: app:upload
-:behaviors: 
-- :version: 3.0.0
-  :checksum: 5c0f768af325b5c88c7efbd0e08a9d6c
-  :name: draggable
-- :version: 3.0.0
-  :checksum: 8a678b67665ea104a1ce6ac89c5a540a
-  :name: modal
-- :version: 3.0.0
-  :checksum: 69973cee238c78231617c5d154454026
-  :name: reflection
-- :version: 3.0.0
-  :checksum: 2ace88a4a49f4dd46cdd1d1dc29c91ba
-  :name: resizable
-- :version: 3.0.0
-  :checksum: 5647c370f68b8c8c226b83bec4ad745e
-  :name: rounded
-- :version: 3.0.0
-  :checksum: b625f21b617c4a159dd0574ec21fc181
-  :name: shadow
-- :version: 3.0.0
-  :checksum: 47d4342f36fa998ec4f340cea7271068
-  :name: tooltip
 :layouts: 
 - :version: 3.0.0
   :checksum: 931dc8c7cff6f8066a7369ef053fb4eb</diff>
      <filename>config/appcelerator.config</filename>
    </modified>
    <modified>
      <diff>@@ -14,15 +14,15 @@
 			twitter credentials to get started. 
 		&lt;/div&gt;
 		&lt;div id=&quot;form&quot;&gt;
-			&lt;form&gt;
+			&lt;form on=&quot;submit! then script[login()]&quot;&gt;
 				&lt;div class=&quot;input&quot;&gt;
 					&lt;div&gt;Twitter Username:&lt;/div&gt;
-					&lt;input type=&quot;text&quot; value=&quot;&quot; id=&quot;username&quot; validator=&quot;required&quot; on=&quot;compiled then focus&quot;/&gt;
+					&lt;input type=&quot;text&quot; value=&quot;appcelerator&quot; id=&quot;username&quot; validator=&quot;required&quot; on=&quot;compiled then focus&quot;/&gt;
 					&lt;div class=&quot;shadow&quot;&gt;&lt;/div&gt;
 				&lt;/div&gt;
 				&lt;div class=&quot;input&quot;&gt;
 					&lt;div&gt;Twitter Password:&lt;/div&gt;
-					&lt;input type=&quot;password&quot; value=&quot;&quot; id=&quot;password&quot; validator=&quot;required&quot; /&gt;
+					&lt;input type=&quot;password&quot; value=&quot;moreapp&quot; id=&quot;password&quot; validator=&quot;required&quot; /&gt;
 					&lt;div class=&quot;shadow&quot;&gt;&lt;/div&gt;
 				&lt;/div&gt;
 				&lt;div&gt;&lt;center&gt;&lt;button id=&quot;remember&quot;&gt;Remember Me&lt;/button&gt;&lt;/center&gt;&lt;/div&gt;</diff>
      <filename>public/index.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,35 @@
+function login()
+{
+	var username = $('#username').val();
+	var password = $('#password').val();
+	var remember = $('#remember').val();
+	$.ajax(
+	{
+		'username':username,
+		'password':password,
+		'url':'https://twitter.com/account/verify_credentials.json',
+		'dataType':'json',
+		success:function(data,textStatus)
+		{
+			if (textStatus == 'success' &amp;&amp; data.authorized)
+			{
+				window.document.location.href = 'main.html?u='+encodeURIComponent(username)+'&amp;p='+encodeURIComponent(password)+'&amp;r='+remember;
+			}
+			else
+			{
+				//FIXME
+				alert('login error = '+textStatus);
+			}
+		},
+		error:function(XMLHttpRequest, textStatus, errorThrown)
+		{
+			//FIXME
+			alert('error='+textStatus+',error='+errorThrown);
+		}
+	});
+
+	return false;
+}
 ti.ready(function($)
 {
 	$('#remember').click(function()
@@ -13,36 +45,7 @@ ti.ready(function($)
 		return false;
 	})
 	
-	$('#login').click(function()
-	{
-		var username = $('#username').val();
-		var password = $('#password').val();
-		var remember = $('#remember').val();
-		$.ajax(
-		{
-			'username':username,
-			'password':password,
-			'url':'https://twitter.com/account/verify_credentials.json',
-			'dataType':'json',
-			success:function(data,textStatus)
-			{
-				if (textStatus == 'success' &amp;&amp; data.authorized)
-				{
-					window.document.location.href = 'main.html?u='+encodeURIComponent(username)+'&amp;p='+encodeURIComponent(password)+'&amp;r='+remember;
-				}
-				else
-				{
-					alert('login error = '+textStatus);
-				}
-			},
-			error:function(XMLHttpRequest, textStatus, errorThrown)
-			{
-				alert('error='+textStatus+',error='+errorThrown);
-			}
-		});
-
-		return false;
-	});
+	$('#login').click(login);
 	
 	// make the username become active
 	setTimeout(function()</diff>
      <filename>public/javascripts/login.js</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 (function($)
 {
-	$(function()
+	ti.ready(function()
 	{
 		//TODO: since, paging
 		var username = AppC.params.u;
@@ -8,6 +8,8 @@
 		var remember = AppC.params.r;
 		
 		var months = {'Jan':0,'Feb':1,'Mar':2,'Apr':3,'May':4,'Jun':5,'Jul':6,'Aug':7,'Sep':8,'Oct':9,'Nov':10,'Dec':11};
+		var days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
+		
 		function today(d)
 		{
 			var now = new Date;
@@ -39,7 +41,7 @@
 			}
 			else
 			{
-				h = 24 - h;
+				h = h - 12;
 			}
 			return h + ':' + m + ' ' + ampm;	
 		}
@@ -56,7 +58,8 @@
 		{
 			return $.gsub(tweet,unRE,function(m)
 			{
-				return '&lt;a target=&quot;_new&quot; href=&quot;http://twitter.com/' + m[0].substring(1) + '&quot;&gt;' + m[0] + '&lt;/a&gt;';
+				// target ti:systembrowser will cause titanium to open the link in the systembrowser (doh!)
+				return '&lt;a target=&quot;ti:systembrowser&quot; href=&quot;http://twitter.com/' + m[0].substring(1) + '&quot;&gt;' + m[0] + '&lt;/a&gt;';
 			})
 		}
 		function formatTweet(obj)
@@ -74,10 +77,10 @@
 		var rowTemplate = AppC.compileTemplate(''+
 		'&lt;div class=&quot;entry&quot;&gt;'+
 		'	&lt;div class=&quot;top&quot;&gt;'+
-		'		&lt;a href=&quot;http://twitter.com/#{user.screen_name}&quot; alt=&quot;Go to profile for #{user.name}&quot;&gt;#{user.name}&lt;/a&gt; &lt;span&gt;#{created_at} via #{source}&lt;/span&gt;'+
+		'		&lt;a target=&quot;ti:systembrowser&quot; href=&quot;http://twitter.com/#{user.screen_name}&quot; alt=&quot;Go to profile for #{user.name}&quot;&gt;#{user.name}&lt;/a&gt; &lt;span&gt;#{created_at} via #{source}&lt;/span&gt;'+
 		'	&lt;/div&gt;'+
 		'	&lt;div class=&quot;icon&quot;&gt;'+
-		'		&lt;a href=&quot;http://twitter.com/#{user.screen_name}&quot; alt=&quot;Go to profile for #{user.name}&quot;&gt;&lt;img src=&quot;#{user.profile_image_url}&quot;/&gt;&lt;/a&gt;'+
+		'		&lt;a target=&quot;ti:systembrowser&quot; href=&quot;http://twitter.com/#{user.screen_name}&quot; alt=&quot;Go to profile for #{user.name}&quot;&gt;&lt;img src=&quot;#{user.profile_image_url}&quot;/&gt;&lt;/a&gt;'+
 		'	&lt;/div&gt;'+
 		'	&lt;div class=&quot;message&quot;&gt;#{text}&lt;/div&gt;'+
 		'&lt;/div&gt;');
@@ -86,6 +89,13 @@
 		
 		function loadTweets()
 		{
+			if (remaining_tweets &lt; 0)
+			{
+				$('#status_msg').html('Rate limit exceeded');
+				checkRateLimit(); // go check again
+				return;
+			}
+			$('#refresh').attr('src','images/main/refresh_bolt.png');
 			$.ajax(
 			{
 				'username':username,
@@ -95,6 +105,17 @@
 				success:function(tweets,textStatus)
 				{
 					content.empty();
+					
+					var now = new Date;
+					//Last Updated:13:57 with 6 tweets / next update 13:59
+					var nextTweet = now.getTime() + interval;
+					var msg = 'Updated: '+formatTime(now.getHours(),now.getMinutes())+' with '+tweets.length+' tweet'+(tweets.length&gt;1?'s':'');
+					var next = new Date;
+					next.setTime(nextTweet);
+					ti.App.debug('nextTime='+next+', interval='+interval+',next.getHours()='+next.getHours());
+					msg+='. Next: '+formatTime(next.getHours(),next.getMinutes());
+					$('#status_msg').html(msg);
+					
 					for (var c=0;c&lt;tweets.length;c++)
 					{
 						try
@@ -104,9 +125,14 @@
 						}
 						catch(E)
 						{
-							alert(E);
+							alert(E); //FIXME
 						}
 					}
+					
+					remaining_tweets--;
+					resetInterval();
+					onNewTweets(tweets.length);
+					$('#refresh').attr('src','images/main/refresh.png');
 				},
 				error:function(XMLHttpRequest, textStatus, errorThrown)
 				{
@@ -115,13 +141,125 @@
 			});
 		}
 		
-		loadTweets();
-
-	    var visible = true;
+		// wire up refresh button
+		$('#refresh').click(loadTweets).mouseover(function()
+		{
+			$(this).attr('src','images/main/refresh_hover.png');
+		}).mouseout(function()
+		{
+			$(this).attr('src','images/main/refresh.png');
+		});
+		
+		var remaining_tweets = 100;
+		var reset_time_in_seconds = 0;
+		var interval = 100000;
+		var timer = 0;
+		var firstTimeLoad = true;
+		
+		function startTimer()
+		{
+			if (timer)
+			{
+				clearTimeout(timer);
+			}
+			if (interval &gt; 0)
+			{
+				timer = setTimeout(loadTweets,interval);
+			}
+		}
+		
+		var soundPlaying = false;
+		var soundEnabled = true;
+		
+		function playSound(path)
+		{
+			if (!soundEnabled) return; // if turned off, don't use it!
+			if (soundPlaying) return; // just prevent in case we get into situation where we're playing already
+			try
+			{
+				soundPlaying = true;
+				var sound = ti.Media.createSound(path);
+				sound.onComplete(function()
+				{
+					soundPlaying = false;
+				})
+				sound.play();
+			}
+			catch(E)
+			{
+				ti.App.debug('sound exception for '+path+', exception = '+E);
+			}
+		}
+		
+		var notification = new ti.Notification;
+		
+		function onNewTweets(count)
+		{
+			if (count &gt; 0)
+			{
+				playSound('app://audio/New.mp3');
+				
+				try
+				{
+					var ps = count &gt; 1 ? 's':'';
+					notification.setTitle('New Tweet'+ps+' received');
+					notification.setMessage(count+' new tweet'+ps+' received');
+					notification.setIcon('app://images/notification.png');
+					notification.show();
+				}
+				catch(E)
+				{
+					alert(E);
+				}
+			}
+		}
+		
+		function onStartup()
+		{
+			playSound('app://audio/On.mp3');
+		}
+		
+		// we need to adjust our interval
+		function resetInterval()
+		{
+			var minutes_left = 60 - new Date().getMinutes();
+			interval = (remaining_tweets / minutes_left) * 60000;
+			ti.App.debug('adjusting rate limit minutes remaining='+minutes_left+', interval='+interval+', remaining='+remaining_tweets);
+			startTimer();
+		}
+		
+		// determine the rate limit
+		function checkRateLimit()
+		{
+			$.ajax(
+			{
+				'username':username,
+				'password':password,
+				'url':'http://twitter.com/account/rate_limit_status.json',
+				'dataType':'json',
+				success:function(rate)
+				{
+					if (firstTimeLoad)
+					{
+						onStartup();
+						firstTimeLoad = false;
+					}
+					var minutes_left = 60 - new Date().getMinutes();
+					reset_time_in_seconds = rate.reset_time_in_seconds;
+					remaining_tweets = rate.remaining_hits;
+					resetInterval();
+					loadTweets();
+				}
+			});
+		}
+		
+		// initially check the rate and set it
+		checkRateLimit();
 
-	    var menu = ti.Menu.createSystemMenu(&quot;app://images/tray_msg.png&quot;,null,function(sysmenu)
+		// create our tray area icon
+	    var menu = ti.Menu.createTrayMenu(&quot;app://images/tray_msg.png&quot;,null,function(sysmenu)
 	    {
-	       if (visible)
+	       if (ti.Window.currentWindow.isVisible())
 	       {
 	          ti.Window.currentWindow.hide();
 	       }
@@ -129,17 +267,40 @@
 	       {
 	          ti.Window.currentWindow.show();
 	       }
-	       visible = !visible;
 	    });
-		function calcLength()
+	
+		function displayLength(e)
 		{
-			var len = 140 - $('#tweettext').val().length;
-			$('#tweetcount').html(len);
+			var count = $(&quot;#tweettext&quot;).val().length;
+			$('#tweetcount').html(140-count);
+			if (count &gt; 0)
+			{
+				$(&quot;#go&quot;).removeAttr('disabled');
+			}
+			else
+			{
+				$(&quot;#go&quot;).attr('disabled','true');
+			}
 		}
 
-		$('#tweettext').get(0).onkeyup = calcLength;
+		function calcLength(e)
+		{
+			var count = $(&quot;#tweettext&quot;).val().length;
+			var len = 140 - (count + 1); // we add once since the new key isn't yet counted
+			if (len &lt; 0 &amp;&amp; e.keyCode!=8) // allow backspace!
+			{
+				e.preventDefault();
+				ti.Media.beep();
+				return false;
+			}
+		}
+
+		$('#tweettext').keyup(displayLength);
+		$('#tweettext').keydown(calcLength);
 
-		calcLength();
+		displayLength();
+		
+		var height = ti.Window.currentWindow.getHeight();
 
 		$('#shade').click(function()
 		{
@@ -147,11 +308,13 @@
 			{
 				$('#shade').attr('class','')
 				$('#top').css('display','');
+				ti.Window.currentWindow.setHeight(height);
 			}
 			else
 			{
 				$('#shade').attr('class','open');
 				$('#top').css('display','none');
+				ti.Window.currentWindow.setHeight(height-145);
 			}
 		});
 		
@@ -172,12 +335,15 @@
 				},
 				error:function(XMLHttpRequest, textStatus, errorThrown)
 				{
+					//FIXME
 					alert('error:'+textStatus+',error:'+errorThrown);
 				}
 			});
 		});
+		
+		setTimeout(function(){
+			$(&quot;#tweettext&quot;).focus();	
+		},1000);
 	});
-	
-	
 })(jQuery);
 </diff>
      <filename>public/javascripts/main.js</filename>
    </modified>
    <modified>
      <diff>@@ -30,19 +30,15 @@
 				&lt;li class=&quot;activex&quot;&gt;&lt;span&gt;Direct Msg&lt;/span&gt;&lt;span class=&quot;count&quot;&gt;(6)&lt;/span&gt;&lt;/li&gt;
 			&lt;/ul&gt;
 		&lt;/div&gt;
-		&lt;div id=&quot;content&quot;&gt;
-			Loading...
-		&lt;/div&gt;
+		&lt;div id=&quot;content&quot;&gt;&lt;/div&gt;
 	&lt;/div&gt;
 	&lt;div id=&quot;status&quot;&gt;
-		&lt;img src=&quot;images/main/refresh.png&quot; /&gt;
-		&lt;div&gt;
-			Last Updated:13:57 with 6 tweets / next update 13:59
-		&lt;/div&gt;
+		&lt;img src=&quot;images/main/refresh.png&quot; id=&quot;refresh&quot;/&gt;
+		&lt;div id=&quot;status_msg&quot;&gt;Loading...&lt;/div&gt;
 	&lt;/div&gt;
 	&lt;div id=&quot;footer&quot;&gt;
 		&lt;div&gt;
-			&lt;a href=&quot;http://titaniumapp.com&quot;&gt;&lt;img src=&quot;images/poweredby.png&quot; /&gt;&lt;/a&gt;
+			&lt;a target=&quot;ti:systembrowser&quot; href=&quot;http://titaniumapp.com&quot; target=&quot;_new&quot;&gt;&lt;img src=&quot;images/poweredby.png&quot; /&gt;&lt;/a&gt;
 		&lt;/div&gt;
 	&lt;/div&gt;
   &lt;/div&gt;</diff>
      <filename>public/main.html</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,5 @@
 body
 {
-/*	width:350px;*/
 	width:100%;
 	height:100%;
 }
@@ -8,7 +7,6 @@ body
 #body
 {
 	height:100%;
-/*	-webkit-border-radius:10px; */
 }
 
 #header
@@ -89,17 +87,19 @@ body
 	border:none;
 	outline:none;
 	padding:10px;
-	width:330px;
-	height:99px;
+	width:300px;
+	height:75px;
 	position:absolute;
 	top:0px;
-	bottom:10px;
+	bottom:15px;
 	left:0px;
-	right:0px;
+	right:10px;
 	z-index:2;
 	background-color:transparent;
 	color:#fff;
 	font-size:15px;
+	padding-right:10px;
+	margin-right:10px;
 }
 
 #go
@@ -123,7 +123,6 @@ body
 #tabs
 {
 	height:29px;
-/*	border:1px solid red;*/
 }
 
 #tabs ul
@@ -271,4 +270,15 @@ div.entry .message a
 {
 	color:#3da0df;
 	text-decoration:none;
-}
\ No newline at end of file
+}
+
+#refresh
+{
+	cursor:pointer;
+}
+
+#go[disabled]
+{
+	opacity:0.5;
+}
+</diff>
      <filename>public/stylesheets/main.css</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>b9ff85e6ba905dc504cbf636c81947675a431371</id>
    </parent>
  </parents>
  <author>
    <name>Jeff Haynie</name>
    <email>jhaynie@gmail.com</email>
  </author>
  <url>http://github.com/jhaynie/tweetanium/commit/4e867e70568279bce222ebbccdbc8c470b6798ea</url>
  <id>4e867e70568279bce222ebbccdbc8c470b6798ea</id>
  <committed-date>2008-12-05T18:40:59-08:00</committed-date>
  <authored-date>2008-12-05T18:40:59-08:00</authored-date>
  <message>lots 'o changes</message>
  <tree>479344ef6e79125f623be8c4d73eaddff8da169c</tree>
  <committer>
    <name>Jeff Haynie</name>
    <email>jhaynie@gmail.com</email>
  </committer>
</commit>
