<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>endless_tweets/load_indicator.gif</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -104,6 +104,9 @@ class Gm &lt; Thor
       target ||= StringIO.new
       render_js_with_partials(file, target)
       target.string if StringIO === target
+    when 'gif', 'png', 'jpg'
+      encoded = [file.read].pack('m').gsub(/\s+/, '')
+      javascript_string('data:image/%s;base64,%s' % [file.extension, encoded])
     else
       raise &quot;don't know how to handle .#{file.extension}&quot;
     end</diff>
      <filename>Thorfile</filename>
    </modified>
    <modified>
      <diff>@@ -18,6 +18,8 @@ function livequeryRun() {
   jQuery.livequery &amp;&amp; jQuery.livequery.run()
 }
 
+var spinnerData = //= load_indicator.gif
+
 var $et = {
   getTimeline: function() { return(this.timeline = $('timeline')) },
   getPage: function() { return(this.page = document.body.id) },
@@ -35,6 +37,11 @@ var $et = {
   
   getSessionCookie: function() {
     return (document.cookie.toString().match(/_twitter_sess=[^\s;]+/) || [])[0]
+  },
+  createLoadIndicator: function(element) {
+    var img = $E('img', {src: spinnerData, 'class': 'load-indicator'})
+    if (element) insertAfter(img, $(element))
+    return img
   }
 }
 
@@ -175,35 +182,49 @@ if (content) {
   // catch click to &quot;in reply to ...&quot; links
   content.addEventListener('click', function(e) {
     var link = up(e.target, 'a', this)
-    if (link &amp;&amp; /^\s*in reply to /.test(link.textContent)) {
-      var statusID = link.href.match(/(\d+)$/)[1],
-          statusUrl = '/statuses/show/' + statusID + '.json',
-          fallback = function(xhr) { window.location = link.href }
-          
-      twttr.loading()
-      loadJSON(statusUrl, function(response, xhr) {
-        if (xhr.status &gt;= 400) { fallback(xhr); return }
-        onAvatarLoad(response, function() {
-          var update = buildUpdateFromJSON(response),
-              currentStatus = up(link, '.status', content)
-              
-          if (currentStatus) {
-            // we're in a list of statuses
-            insertAfter(update, currentStatus)
-          } else {
-            // we're on a fresh single tweet page
-            insertAfter(update.parentNode, $('permalink'))
-          }
-          reveal(update)
-          twttr.loaded()
-          livequeryRun()
-          $et.trackEvent('timeline', 'in_reply_to', 'loaded status ' + statusID)
-        })
-      }, { onerror: fallback })
+    if (link &amp;&amp; /^\s*in reply to\b/.test(link.textContent)) {
+      loadInReplyTo(link, 'show' == $et.page)
       e.preventDefault()
     }
   }, false)
   
+  function loadInReplyTo(link, recursive) {
+    var statusID = link.href.match(/(\d+)$/)[1],
+        statusUrl = '/statuses/show/' + statusID + '.json',
+        fallback = function(xhr) { window.location = link.href }
+    
+    if ($('status_' + statusID)) return false
+    
+    var indicator = $et.createLoadIndicator(link)
+    
+    loadJSON(statusUrl, function(response, xhr) {
+      if (xhr.status &gt;= 400) { fallback(xhr); return }
+      onAvatarLoad(response, function() {
+        var update = buildUpdateFromJSON(response)
+        
+        if (up(link, '.statuses', content)) {
+          // we're in a list of statuses
+          insertAfter(update, up(link, '.status', content))
+        } else {
+          // we're on a single tweet page, so create a timeline list
+          insertAfter(update.parentNode, $('permalink'))
+        }
+        reveal(update)
+        $et.trackEvent('timeline', 'in_reply_to', 'loaded status ' + statusID)
+        
+        var nextInReplyLink = find(update, './/a[@href][starts-with(text(), &quot;in reply to &quot;)]')
+        if (recursive &amp;&amp; nextInReplyLink) {
+          loadInReplyTo(nextInReplyLink, recursive)
+        } else {
+          livequeryRun()
+        }
+        removeChild(indicator)
+      })
+    }, { onerror: fallback })
+    
+    return true
+  }
+  
   // catch TAB keypresses in the update form
   content.addEventListener('keydown', function(e) {
     var textarea = null</diff>
      <filename>endless_tweets/endless_tweets.js</filename>
    </modified>
    <modified>
      <diff>@@ -38,6 +38,11 @@ a.googlemap
   input[type=checkbox]
     :vertical-align top
 
+img.load-indicator
+  :display inline-block
+  :margin -3px 0 -3px 5px
+  :vertical-align middle
+
 body#show
   .user-info
     :border-top-color white 
@@ -48,8 +53,6 @@ body#show
       :padding-bottom 0
     .screen-name
       :font-size inherit
-    .actions a
-      :padding 3px 8px
 
   #content ol.statuses
     .entry-content</diff>
      <filename>endless_tweets/endless_tweets.sass</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
-var replyLink = find('content', '.actions .reply')
+var replyLink = find('content', '.status .reply a')
 if (replyLink) {
   var actions = replyLink.parentNode
   actions.style.top = actions.offsetTop + 'px'
@@ -8,7 +8,7 @@ if (replyLink) {
     container.innerHTML = //= update_form.haml
     
     var username = selectString('meta[@name=&quot;page-user-screen_name&quot;]/@content'),
-        replyForm = $('permalink').parentNode.appendChild(container.firstChild),
+        replyForm = insertAfter(container.firstChild, $('permalink')),
         label = find(replyForm, 'label.doing'),
         textInput = $('status'),
         counter = $('status-field-char-counter'),</diff>
      <filename>endless_tweets/inline_reply.js</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>ee54ffd48b659c8341b120cb5c985fe411508e9d</id>
    </parent>
  </parents>
  <author>
    <name>Mislav Marohni&#263;</name>
    <email>mislav.marohnic@gmail.com</email>
  </author>
  <url>http://github.com/mislav/user-scripts/commit/ef99572ea6e14f1d058c48d398799aa8daf4bb66</url>
  <id>ef99572ea6e14f1d058c48d398799aa8daf4bb66</id>
  <committed-date>2009-10-31T16:58:43-07:00</committed-date>
  <authored-date>2009-10-31T03:35:08-07:00</authored-date>
  <message>single tweet page: fix dynamic &quot;in reply to&quot; and inline reply form

Also dynamically load the whole conversation on single tweet page</message>
  <tree>2523579a5380edbb6cd8873cb35351bf663a02a3</tree>
  <committer>
    <name>Mislav Marohni&#263;</name>
    <email>mislav.marohnic@gmail.com</email>
  </committer>
</commit>
