Fixed cache issues. Fixed a major long-polling issue with a keepalive function
[flowspy] / templates / poller.js
1 // Copyright 2009 FriendFeed
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may
4 // not use this file except in compliance with the License. You may obtain
5 // a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations
13 // under the License.
14 var xhrlp = '';
15 $(document).ready(function() {
16     if (!window.console) window.console = {};
17     if (!window.console.log) window.console.log = function() {};
18
19     $("#messageform").live("submit", function() {
20         newMessage($(this));
21         return false;
22     });
23     $("#messageform").live("keypress", function(e) {
24         if (e.keyCode == 13) {
25             newMessage($(this));
26             return false;
27         }
28     });
29     $("#message").select();
30     {% if user.is_authenticated %}
31     updater.start();
32     updater.keepalive();
33     
34     {% endif %}
35 });
36
37
38
39 function newMessage(form) {
40     var message = form.formToDict();
41     var disabled = form.find("input[type=submit]");
42     disabled.disable();
43     $.postJSON("{% url fetch-new %}", message, function(response) {
44         updater.showMessage(response);
45         if (message.id) {
46             form.parent().remove();
47         } else {
48             form.find("input[type=text]").val("").select();
49             disabled.enable();
50         }
51     });
52 }
53
54 function getCookie(name) {
55     var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
56     return r ? r[1] : undefined;
57 }
58
59 jQuery.postJSON = function(url, args, callback) {
60     $.ajax({url: url, dataType: "text", type: "POST",
61             success: function(response) {
62         if (callback) callback(eval("(" + response + ")"));
63     }, error: function(response) {
64         console.log("ERROR:", response)
65     }});
66 };
67
68 jQuery.fn.formToDict = function() {
69     var fields = this.serializeArray();
70     var json = {}
71     for (var i = 0; i < fields.length; i++) {
72         json[fields[i].name] = fields[i].value;
73     }
74     if (json.next) delete json.next;
75     return json;
76 };
77
78 jQuery.fn.disable = function() {
79     this.enable(false);
80     return this;
81 };
82
83 jQuery.fn.enable = function(opt_enable) {
84     if (arguments.length && !opt_enable) {
85         this.attr("disabled", "disabled");
86     } else {
87         this.removeAttr("disabled");
88     }
89     return this;
90 };
91
92 var updater = {
93     errorSleepTime: 500,
94     cursor: null,
95     xhrlp: null,
96     
97     keepalive: function (){
98         try {
99                 updater.xhrlp.abort();
100         }
101         catch (e) {      
102         }
103         updater.poll();
104         if (updater.errorSleepTime == 500){
105                 window.setTimeout(updater.keepalive, 180000);
106         }
107 //      if (updater.errorSleepTime > 60000){
108 //              window.setTimeout('location.reload()', 3000);
109 //              }
110         },
111     
112     start: function() {
113                 $.ajax({url: "{% url fetch-existing %}", type: "POST", dataType: "text",
114                 success: updater.onFetchExisting,
115                 error: updater.onError});
116         },
117     
118     poll: function() {
119         {% if user.is_authenticated %}
120         if (updater.errorSleepTime > 60000){
121                 window.setTimeout('location.reload()', 1000);
122                 }
123         updater.xhrlp=$.ajax({url: "{% url fetch-updates %}", type: "POST", dataType: "text",
124                 success: updater.onSuccess,
125                 error: updater.onError});
126         {% endif %}
127     },
128     onSuccess: function(response) {
129         try {
130             updater.newMessages(eval("(" + response + ")"));
131         } catch (e) {
132             updater.onError();
133             return;
134         }
135         updater.errorSleepTime = 500;
136         window.setTimeout(updater.poll, 0);
137     },
138
139     onFetchExisting: function(response) {
140         try {
141             updater.existingMessages(eval("(" + response + ")"));
142         } catch (e) {
143 //          updater.onError();
144             return;
145         }
146         },
147      
148     onError: function(response, text) {
149                 if (text != 'abort'){
150                                 updater.errorSleepTime *= 2;
151                                 console.log("Poll error; sleeping for", updater.errorSleepTime, "ms");
152                                 window.setTimeout(updater.keepalive, updater.errorSleepTime);
153                 }
154     },
155
156     newMessages: function(response) {
157         if (!response.messages) return;
158         updater.cursor = response.cursor;
159         var messages = response.messages;
160         updater.cursor = messages[messages.length - 1].id;
161 //      console.log(messages.length, "new messages, cursor:", updater.cursor);
162         
163         for (var i = 0; i < messages.length; i++) {
164             updater.showMessage(messages[i]);
165         }
166         $("#hid_mid").val('UPDATED');
167         if (($('#console').dialog('isOpen')) == false){
168                 blink("#consolebutton");
169                 window.setTimeout('location.reload()', 3000);
170         }
171     },
172
173     existingMessages: function(response) {
174         if (!response.messages) return;
175         updater.cursor = response.cursor;
176         var messages = response.messages;
177         updater.cursor = messages[messages.length - 1].id;
178         for (var i = 0; i < messages.length; i++) {
179             updater.showMessage(messages[i]);
180         }
181         },
182    
183     showMessage: function(message) {
184         var existing = $("#m" + message.id);
185         if (existing.length > 0) return;
186         var node = $(message.html);
187         node.hide();
188 //       $('#inbox').val($('#inbox').val()+message.text); 
189         $("#inbox").append(node);
190         node.slideDown();
191     }
192 };
193
194 function blink(selector){
195         $(selector).animate({ color: "red" }, 500, function(){
196         $(this).animate({ color: "#555555" }, 500, function(){
197         blink(this);
198         });
199         });
200 }
201