3 function url(endpoint){
4 return "https://" + app.settings.opts.user + ":" + app.settings.opts.pass + "@" + app.settings. opts.host + "/api/" + endpoint + "?callback=?";
10 function MessageList(sel_elm){
11 this.elm = $(sel_elm);
15 MessageList.prototype.update = function(clb){
16 $.getJSON(url("direct_messages"), {getText:"plain"}, function(data, status){
17 //console.log(status);
22 if (senders.indexOf(msg.sender_screen_name)<0){
23 senders.push(msg.sender_screen_name);
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>";
43 * Conversation with a user
45 function Messages(sel_elm){
46 this.elm = $(sel_elm);
50 Messages.prototype.update = function(username, clb) {
52 this.username = username;
54 username = this.username;
57 if (!username) return;
59 $("#contact_screen_name").html(username);
61 $.getJSON(url("direct_messages/all"), {getText:"html", screen_name: username}, function(data, status){
62 //console.log(data, status);
66 var reply_id; // id of the message to reply to. should be the last.
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>";
81 $(".message_text").val("");
82 $(".message_to").val(username);
83 $(".message_reply").val(reply_id);
94 function Compose(sel_elm){
95 this.elm = $(sel_elm);
96 this.dialog = this.elm.find("#select_contact");
98 this.contact_photo = this.elm.find(".contact_photo");
99 this.contact_photo_empty = this.contact_photo.attr("src");
103 this.last_update = 0;
106 /* contact list dialog */
109 this.contact_photo.on("click",function(e){
111 for (k in this.friends) {
112 var f = this.friends[k];
113 out += "<button type='button' value='"+k+"' class='contact_item'><img src='"+f.profile_image_url+"'>"+f.name+" ("+f.screen_name+")</button>"
115 out += '<button type="button" class="cancel">Cancel</button>';
117 this.dialog.find("menu").html(out);
120 this.dialog.find(".contact_item").on("click", function(e){
121 $(".message_to").val( $(e.target).val() );
122 $(".message_to").trigger("input");
126 this.dialog.find(".cancel").on("click", function(){
131 /* /contact list dialog */
133 this.elm.find(".message_to").on('input', function(e){
134 var f=$(e.target).val().trim();
135 if (this.friends[f] !== undefined) {
136 this.contact_photo.attr("src",this.friends[f].profile_image_url);
138 this.contact_photo.attr("src", this.contact_photo_empty);
143 Compose.prototype.update = function(clb){
144 if (this.last_update > (new Date())-60000) {
145 if (clb) clb(this.friends)
148 var dl = this.elm.find("#contacts");
150 $.getJSON(url("statuses/friends"), {}, function(data, status) {
154 var friend = data[k];
155 if (friend.network == "dfrn")
156 this.friends[friend.screen_name] = friend;
157 out += "<option value='"+friend.screen_name+"'>"+friend.name+" ("+friend.screen_name+")</option>";
159 this.last_update = (new Date()) - 0;
166 Compose.prototype.send = function(clb){
168 var screen_name = $(".message_to").val().trim();
169 var replyto = $(".message_reply").val();
170 var text = $(".message_body").val();
172 text = $(".message_text").val();
175 alert("Please enter the message body");
178 if (screen_name=="" || this.friends[screen_name]==undefined){
179 alert("Please enter a valid recipient");
186 Friendica doesn't set CORS headers (it should.. open a feature request!)
187 We can't send post requests via ajax on different domains without it
188 (we can get with jsonp, wich is another hack, but standard...)
189 We create an iframe, append it to body and create a form wich post data to
191 We listen for 'load' event to know when the request returned data, so we
192 can update the message list.
193 We sould remove it when finished.
194 We could read the content of the iframe before removeit as it would be json
199 var f = $("<iframe>").appendTo($("body")).hide();
201 f.on('load', function() {
204 screen_name:screen_name,
210 // we need a small timeout before we can write to iframe content
211 setTimeout( function() {
212 var doc = f[0].contentWindow.document;
214 var form = $("<form>").attr('action', url("direct_messages/new")).attr('method','POST').append(
215 $("<input>").attr('name','screen_name').val(screen_name)
217 $("<input>").attr('name','text').val(text)
219 if (replyto!=="") form.append(
220 $("<input>").attr('name','replyto').val(replyto)
222 $('body',doc).append(form);
231 function Settings(sel_elm) {
232 this.elm = $(sel_elm);
236 this.elm.find(".autoupdate").on("blur", function(e,b){
237 this.set(e.target.id, $(e.target).val());
241 Settings.prototype.update = function(clb) {
242 this.opts = JSON.parse( window.localStorage.getItem("opts") );
243 if (this.opts === null) this.opts={};
245 for (k in this.opts) {
246 this.elm.find("#"+k).val(this.opts[k]);
251 Settings.prototype.is_valid = function() {
252 return this.opts !== null &&
253 this.opts.host !== undefined && this.opts.host !== "" &&
254 this.opts.user !== undefined && this.opts.user !== "" &&
255 this.opts.pass !== undefined && this.opts.pass !=="";
258 Settings.prototype.set = function(name, value) {
259 this.opts[name] = value;
260 window.localStorage.setItem("opts", JSON.stringify(this.opts));
269 // Application Constructor
270 initialize: function() {
271 app.settings = new Settings("#settingsPage");
272 app.messagelist = new MessageList("#messageList");
273 app.messages = new Messages("#messages");
274 app.compose = new Compose("#newMessagePage");
277 '': app.page_messageList,
278 'settings' : app.page_settings,
279 'compose' : app.page_compose,
280 'message/:user': app.page_messageUser
287 page_messageList : function(){
288 if (!app.settings.is_valid()) {
289 /* alert("Please fill required settings"); */
293 app.messagelist.update(function(){
294 if ($("body > .current").length>0) {
295 $("body > .current").removeClass("current").addClass("right");
296 $("#inboxPage").addClass("current");
301 page_messageUser : function(user) {
303 app.messages.update(user, function(){
305 var ofs = $("#messages li:last-of-type").offset()
307 $("#messagePage .scrollable").scrollTop(ofs.top);
309 $("#inboxPage").removeClass("current").addClass("left");
310 $("#messagePage").removeClass("right").addClass("current");
314 page_settings : function() {
315 app.settings.update(function(){
316 $("#inboxPage").removeClass("current").addClass("left");
317 $("#settingsPage").removeClass("right").addClass("current");
321 page_compose : function() {
322 $(".message_body").val("");
323 $(".message_to").val("");
324 $(".message_reply").val("");
325 app.compose.contact_photo.attr("src", app.compose.contact_photo_empty);
327 app.compose.update(function(){
328 $("#inboxPage").removeClass("current").addClass("left");
329 $("#newMessagePage").removeClass("right").addClass("current");
333 bindEvents: function() {
337 $("#reply_send").on("click", function(e){
339 app.compose.send(function(){
340 app.messages.update();
344 /* send new message */
345 $("#message_send").on("click", function(e){
347 app.compose.send(function(data){
348 // dovrebbe andare a message/data.screen_name
349 // ma per come รจ fatto al momento non funziona...
350 // torniamo alla lista messaggi
359 $("progress").hide();
360 $.ajaxSettings.beforeSend = function() { $("progress").show(); }
361 $.ajaxSettings.complete = function() { $("progress").hide(); }