New functions: new message and reply
[progetti-gl-como:friendica-messenger.git] / www / js / index.js
1
2
3 function url(endpoint){
4         return "https://" + app.settings.opts.user + ":" + app.settings.opts.pass + "@" + app.settings. opts.host + "/api/" + endpoint + "?callback=?"; 
5 }
6
7 /**
8  * Message List Object
9  */
10 function MessageList(sel_elm){
11         this.elm = $(sel_elm);
12 }
13
14
15 MessageList.prototype.update = function(clb){
16         $.getJSON(url("direct_messages"), {getText:"plain"}, function(data, status){
17                 //console.log(status);
18                 var senders = [];
19                 var out="";
20                 for (k in data) {
21                         var msg = data[k];
22                         if (senders.indexOf(msg.sender_screen_name)<0){
23                                 senders.push(msg.sender_screen_name);
24                                 out += "<li>";
25                                 out += "<aside class='pack'><img src='"+ msg.sender.profile_image_url + "'></aside>";
26                                 out += "<a href='#message/"+msg.sender_screen_name+"'>";
27                                 out += "<p>" + msg.text + "</p>";
28                                 out += "<p>" + msg.sender_screen_name + " - " + msg.created_at + "</p>";
29                                 out += "</a>";
30                                 out += "</li>";
31                         }
32                 }
33                 
34                 this.elm.html(out);
35                 
36                 if(clb) clb(data);
37                 
38         }.bind(this));
39 }
40
41
42 /**
43  * Conversation with a user
44  */
45 function Messages(sel_elm){
46         this.elm = $(sel_elm);
47         this.username = null;
48 }
49
50 Messages.prototype.update = function(username, clb) {
51         if (username) {
52                 this.username = username;
53         } else {
54                 username = this.username;
55         }
56         
57         if (!username) return;
58         
59         $("#contact_screen_name").html(username);
60         
61         $.getJSON(url("direct_messages/all"), {getText:"html", screen_name: username}, function(data, status){
62                 //console.log(data, status);
63                 data.reverse();
64                 var out="";
65                 var pack="";
66                 var reply_id; // id of the message to reply to. should be the last.
67                 for (k in data) {
68                         var msg = data[k];
69                         out += "<li>";
70                         pack = (msg.sender_screen_name==username ? "pack": "pack-end"); 
71                         out += "<aside class='"+pack+"'><img src='"+ msg.sender.profile_image_url + "'></aside>";
72                         //out += "<a href='#message/"+msg.sender_screen_name+"'>";
73                         out += "<p>" + msg.text + "</p>";
74                         out += "<p>" + msg.sender_screen_name + " - " + msg.created_at + "</p>";
75                         //out += "</a>";
76                         out += "</li>";
77                         reply_id = msg.id;
78                 }
79                 
80                 /* reply form */
81                 $(".message_text").val("");
82                 $(".message_to").val(username);
83                 $(".message_reply").val(reply_id);
84                 
85                 this.elm.html(out);
86                 if(clb) clb(data);
87         }.bind(this));
88         
89 }
90
91 /**
92  * Send Message
93  */
94 function Compose(sel_elm){
95         this.elm = $(sel_elm);
96         this.contact_photo = $(sel_elm).find(".contact_photo");
97         this.contact_photo_empty = this.contact_photo.attr("src");
98         this.friends = {};
99         this.last_update = 0;
100         
101         
102         this.elm.find(".message_to").on('input', function(e){
103                 var f=$(e.target).val();
104                 if (this.friends[f] !== undefined) {
105                         this.contact_photo.attr("src",this.friends[f].profile_image_url);
106                 }
107         }.bind(this));
108 }
109
110 Compose.prototype.update = function(clb){
111         if (this.last_update > (new Date())-60000) {
112                 if (clb) clb(this.friends)
113                 return;
114         }
115         var dl = this.elm.find("#contacts");
116         $.getJSON(url("statuses/friends"), {}, function(data, status) {
117                 var out="";
118                 this.friends = {};
119                 for (k in data){
120                         var friend = data[k];
121                         if (friend.network == "dfrn")
122                                 this.friends[friend.screen_name] = friend;
123                                 out += "<option value='"+friend.screen_name+"'>"+friend.name+" ("+friend.screen_name+")</option>";
124                 }
125                 this.last_update = (new Date()) - 0;
126                 dl.html(out);
127                 if (clb) clb(data);
128         }.bind(this));
129         
130 }
131
132 Compose.prototype.send = function(clb){
133         
134         var screen_name = $(".message_to").val();
135         var replyto = $(".message_reply").val();
136         var text = $(".message_body").val();
137         if (text=="")
138                 text = $(".message_text").val();
139
140         if (text=="") {
141                 alert("Please enter the message body");
142                 return;
143         }
144         if (screen_name=="" || this.friends[screen_name]==undefined){
145                 alert("Please enter a valid recipient");
146                 return;
147         }
148         
149         /**
150                 WARNING: HACK AHEAD!
151
152                 Friendica doesn't set CORS headers (it should.. open a feature request!)
153                 We can't send post requests via ajax on different domains without it 
154                 (we can get with jsonp, wich is another hack, but standard...)
155                 We create an iframe, append it to body and create a form wich post data to
156                 remote server.
157                 We listen for 'load' event to know when the request returned data, so we
158                 can update the message list.
159                 We sould remove it when finished.
160                 We could read the content of the iframe before removeit as it would be json
161                 reply from API...
162         **/
163
164
165         var f = $("<iframe>").appendTo($("body")).hide();
166         
167         f.on('load', function() {
168                 if (clb){
169                         clb({
170                                 screen_name:screen_name,
171                                 replyto:replyto,
172                                 text:text
173                         });
174                 }
175         });
176         // we need a small timeout before we can write to iframe content
177         setTimeout( function() {
178                 var doc = f[0].contentWindow.document;
179                 // build the form
180                 var form = $("<form>").attr('action', url("direct_messages/new")).attr('method','POST').append(
181                                 $("<input>").attr('name','screen_name').val(screen_name)
182                         ).append(
183                                 $("<input>").attr('name','text').val(text)
184                         );
185                 if (replyto!=="") form.append(
186                         $("<input>").attr('name','replyto').val(replyto)        
187                 );
188                 $('body',doc).append(form);
189                 // send the form!
190                 form.submit();
191         }, 1 );
192 }
193
194 /**
195  * App settings
196  */
197 function Settings(sel_elm) {
198         this.elm = $(sel_elm);
199         this.update();
200         
201         
202         this.elm.find(".autoupdate").on("blur", function(e,b){ 
203                 this.set(e.target.id, $(e.target).val());
204         }.bind(this));
205 }
206         
207 Settings.prototype.update = function(clb) {
208         this.opts = JSON.parse( window.localStorage.getItem("opts") );
209         if (this.opts === null) this.opts={};
210
211         for (k in this.opts) {
212                 this.elm.find("#"+k).val(this.opts[k]);
213         }
214         if(clb) clb();
215 }
216         
217 Settings.prototype.is_valid = function() {
218         return this.opts !== null && 
219               this.opts.host !== undefined && this.opts.host !== "" && 
220               this.opts.user !== undefined && this.opts.user !== "" && 
221               this.opts.pass !== undefined && this.opts.pass !=="";
222 }
223         
224 Settings.prototype.set = function(name, value) {
225         this.opts[name] = value;
226         window.localStorage.setItem("opts", JSON.stringify(this.opts));
227 }
228
229
230
231 /**
232  * App Object
233  */
234 var app = {
235     // Application Constructor
236     initialize: function() {
237                 app.settings = new Settings("#settingsPage");
238                 app.messagelist = new MessageList("#messageList");
239                 app.messages    = new Messages("#messages");
240                 app.compose             = new Compose("#newMessagePage");
241                 
242                 routie({
243                         '': app.page_messageList,
244                         'settings' : app.page_settings,
245                         'compose'  : app.page_compose,
246                         'message/:user': app.page_messageUser
247                 });
248                 
249                 
250         this.bindEvents();
251     },
252         
253         page_messageList : function(){
254                 if (!app.settings.is_valid()) {
255                         /* alert("Please fill required settings"); */
256                         routie("settings");
257                         return;
258                 }
259                 app.messagelist.update(function(){
260                         if ($("body > .current").length>0) { 
261                                 $("body > .current").removeClass("current").addClass("right");
262                                 $("#inboxPage").addClass("current");
263                         }
264                 });
265         },
266         
267         page_messageUser : function(user) {
268
269                 app.messages.update(user, function(){
270                         
271                         var ofs = $("#messages li:last-of-type").offset()
272                         if (ofs !== null)
273                                 $("#messagePage .scrollable").scrollTop(ofs.top);
274                         
275                         $("#inboxPage").removeClass("current").addClass("left");
276                         $("#messagePage").removeClass("right").addClass("current");
277                 });
278         },
279         
280         page_settings : function() {
281                 app.settings.update(function(){
282                         $("#inboxPage").removeClass("current").addClass("left");
283                         $("#settingsPage").removeClass("right").addClass("current");
284                 });             
285         },
286         
287         page_compose : function() {
288                 $(".message_body").val("");
289                 $(".message_to").val("");
290                 $(".message_reply").val("");
291                 app.compose.contact_photo.attr("src", app.compose.contact_photo_empty);
292                 
293                 app.compose.update(function(){
294                         $("#inboxPage").removeClass("current").addClass("left");
295                         $("#newMessagePage").removeClass("right").addClass("current");
296                 });
297         },
298         
299     bindEvents: function() {
300         
301                 
302                 /* send reply */
303                 $("#reply_send").on("click", function(e){
304                         e.preventDefault();
305                         app.compose.send(function(){
306                                 app.messages.update();
307                         });
308                 });
309                 
310                 /* send new message */
311                 $("#message_send").on("click", function(e){
312                         e.preventDefault();
313                         app.compose.send(function(data){
314                                 // dovrebbe andare a message/data.screen_name
315                                 // ma per come รจ fatto al momento non funziona...
316                                 // torniamo alla lista messaggi
317                                 routie("");
318                         });
319                 });
320                 
321                 
322     }
323 };
324
325 $("progress").hide();
326 $.ajaxSettings.beforeSend = function() { $("progress").show(); }
327 $.ajaxSettings.complete = function() { $("progress").hide(); }
328
329
330 app.initialize();