1 /** @fileoverview <pre> Multimedia widget para TelaSocial/Janelas Virtuais 2 Desenhado em tempo real usando SVG. 3 Baseado no antigo widget do Flickr by Taboca. 4 </pre> 5 @version 1.0 6 @author Matheus Martins Teixeira <a href="mailto:mteixeira@grad.icmc.usp.br"><mteixeira@grad.icmc.usp.br></a> 7 */ 8 /* ***** BEGIN LICENSE BLOCK ***** 9 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 10 * 11 * The contents of this file are subject to the Mozilla Public License Version 12 * 1.1 (the "License"); you may not use this file except in compliance with 13 * the License. You may obtain a copy of the License at 14 * http://www.mozilla.org/MPL/ 15 * 16 * Software distributed under the License is distributed on an "AS IS" basis, 17 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 18 * for the specific language governing rights and limitations under the 19 * License. 20 * 21 * The Original Code is TelaSocial 22 * 23 * The Initial Developer of the Original Code is Taboca TelaSocial. 24 * Portions created by the Initial Developer are Copyright (C) 2010 25 * the Initial Developer. All Rights Reserved. 26 * 27 * Contributor(s): 28 * Marcio Galli <mgalli@taboca.com> 29 * Rafael Sartori <faelsartori@gmail.com> 30 * Matheus Teixeira <teixeira.mdk@gmail.com> 31 * 32 * Alternatively, the contents of this file may be used under the terms of 33 * either the GNU General Public License Version 2 or later (the "GPL"), or 34 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 35 * in which case the provisions of the GPL or the LGPL are applicable instead 36 * of those above. If you wish to allow use of your version of this file only 37 * under the terms of either the GPL or the LGPL, and not to allow others to 38 * use your version of this file under the terms of the MPL, indicate your 39 * decision by deleting the provisions above and replace them with the notice 40 * and other provisions required by the GPL or the LGPL. If you do not delete 41 * the provisions above, a recipient may use your version of this file under 42 * the terms of any one of the MPL, the GPL or the LGPL. 43 * 44 * ***** END LICENSE BLOCK ***** */ 45 46 /** 47 Objeto com as ações do widget 48 @class 49 @name multimedia 50 */ 51 var multimedia = { 52 /** 53 Url para o json com as fotos do perfil no Facebook. 54 @type String 55 */ 56 URL : ICMC_FB_ALBUMS, 57 /** 58 Array com os objetos albums. 59 @type array 60 */ 61 albums : null, 62 /** 63 Div que irá armazenar o widget 64 @type DOM Object 65 */ 66 container : null 67 , 68 /** 69 Div que contém a fila de fotos 70 @type DOM Object 71 */ 72 queueDiv : null, 73 /** 74 Div que exibe as fotos como um slideshow 75 @type DOM object 76 */ 77 slideShowDiv : null, 78 /** 79 Tempo de troca em milisegundos 80 @default 5000 81 @type int 82 */ 83 swapTime : 5000, 84 /** 85 Inicializa o widget 86 @param {DOM Object} obj Container do widget 87 @public 88 @function 89 */ 90 init : function(obj) { 91 multimedia.container = $("<div>").addClass('mainWrapper').appendTo($(obj)); 92 multimedia.container.html('<div class="slideshow"><div class="name"></div></div><div class="slideshow"><div class="name"></div></div>'); 93 multimedia.slideShowDiv = multimedia.container.find('.slideshow'); 94 multimedia.queueDiv = $('<div>').addClass('queue').appendTo(multimedia.container); 95 multimedia.albums = new Array(); 96 $('<input>').attr('type', 'hidden').attr('id', 'hascontent').attr('id', 'hascontent').appendTo("#container"); 97 }, 98 /** 99 Inicia o widget 100 @public 101 @function 102 */ 103 start : function() { 104 multimedia.__loadAlbums(); 105 }, 106 /** 107 Carrega os albums do link {@link multimedia.URL} 108 @private 109 @function 110 */ 111 __loadAlbums : function() { 112 $.getJSON(multimedia.URL, function(e) { 113 multimedia.__storeAlbums(e.data); 114 }) 115 }, 116 /** 117 Armazena os albums no array de albums. 118 @param {JSON Object} e Json com os albums carregados 119 @private 120 @function 121 */ 122 __storeAlbums : function(e) { 123 var i = 0; 124 for( i = 0; i < e.length; i++) { 125 var album = new multimedia.prepareAlbum(e[i]); 126 album.loadPhotos(); 127 this.albums.push(album); 128 } 129 if(e.length > 0) 130 $('#hascontent').attr('value', '1'); 131 else 132 $('#hascontent').attr('value', '0'); 133 setTimeout(function() { 134 multimedia.render(); 135 }, 1000); 136 }, 137 cc : 0, 138 /** 139 Renderiza os albums dentro da div container. 140 @private 141 @function 142 */ 143 render : function() { 144 var album = Math.floor(Math.random() * multimedia.albums.length); 145 var present = multimedia.albums[album]; 146 147 if(present.photos.length != 0 && multimedia.cc > 0) { 148 var wrapper = $('<div>').addClass('imageWrap').appendTo(multimedia.queueDiv); 149 var photo = present.photos.pop(); 150 if(photo.message == null) 151 $('<div>').append($('<img>').attr('likes', photo.likes).attr("src", photo.image).attr('alt', present.name)).appendTo(wrapper); 152 else 153 $('<div>').append($('<img>').attr('likes', photo.likes).attr("src", photo.image).attr('alt', photo.message)).appendTo(wrapper); 154 multimedia.cc--; 155 } 156 if(multimedia.cc > 0) 157 setTimeout(function() { 158 multimedia.render(); 159 }, 100); 160 if(multimedia.cc == 0) 161 multimedia.slideshowStart(); 162 163 }, 164 /** 165 Inicia o efeito de slideshow 166 @private 167 @function 168 */ 169 slideshowStart : function() { 170 setTimeout(function() { 171 multimedia.swapPhotos() 172 }, 100); 173 }, 174 /** 175 Produz o efeito de troca entre as imagens. 176 @private 177 @function 178 */ 179 swapPhotos : function() { 180 $(multimedia.queueDiv.children()).animate({ 181 'opacity' : '0.5' 182 }, multimedia.swapTime / 5); 183 184 $($(multimedia.queueDiv.children()[0])).animate({ 185 "opacity" : "0", 186 "margin-top" : "-330px" 187 }, multimedia.swapTime / 5, function() { 188 var next1 = $(multimedia.queueDiv.children()[3]).animate({ 189 'opacity' : '1' 190 }, multimedia.swapTime / 5); 191 $($($(multimedia.slideShowDiv[0]).find('.name')[0])).animate({ 192 "margin-top" : "585" 193 }, multimedia.swapTime / 5, function() { 194 $(this).html(next1.find('img').attr('alt')); 195 if(next1.find('img').attr('likes') > 0) 196 $(this).append($('<span>').html('<img src=\'./like-50.png\'/><b>' + next1.find('img').attr('likes')+'</b>')); 197 $(this).animate({ 198 "margin-top" : "515" 199 }, multimedia.swapTime / 5); 200 }); 201 $(multimedia.slideShowDiv[0]).css('background-image', 'url(' + next1.find('img').attr('src') + ')'); 202 var next2 = $(multimedia.queueDiv.children()[6]).animate({ 203 'opacity' : '1' 204 }, multimedia.swapTime / 5); 205 206 $($($(multimedia.slideShowDiv[1]).find('.name')[0])).animate({ 207 "margin-top" : "585" 208 }, multimedia.swapTime / 5, function() { 209 $(this).html(next2.find('img').attr('alt')); 210 if(next2.find('img').attr('likes') > 0) 211 $(this).append($('<span>').html('<img src=\'./like-50.png\'/><b>' + next2.find('img').attr('likes')+'</b>')); 212 $(multimedia.slideShowDiv[1]).css('background-image', 'url(' + next2.find('img').attr('src') + ')'); 213 $(this).animate({ 214 "margin-top" : "515" 215 }, multimedia.swapTime / 5); 216 }); 217 218 $($(multimedia.queueDiv.children()[1])).remove().appendTo(multimedia.queueDiv).css('margin-top', "10px").css("opacity", "0.5"); 219 $(this).remove().appendTo(multimedia.queueDiv).css('margin-top', "10px").css("opacity", "0.5"); 220 221 setTimeout(function() { 222 multimedia.swapPhotos(); 223 }, multimedia.swapTime); 224 }); 225 }, 226 /** 227 Formata um objeto JSON para um objeto album do widget. 228 @param {JSON Object} obj Album do tipo objeto JSON com o padrão do Facebook 229 @private 230 @function 231 */ 232 prepareAlbum:function(obj){ 233 this.name = obj.name; 234 this.fbId = obj.id; 235 this.description = obj.description; 236 this.photos = new Array(); 237 var self = this; 238 this.storePhotos = function(e) { 239 for(var i = 0; i < e.length; i++) { 240 var ph = new multimedia.preparePhoto(e[i]); 241 self.photos.push(ph); 242 multimedia.cc++; 243 } 244 }; 245 this.loadPhotos = function() { 246 $.getJSON("https://graph.facebook.com/" + this.fbId + "/photos?access_token=" + API_KEY_FACEBOOK + "&format=json", function(e) { 247 self.storePhotos(e.data); 248 }).error(function(e){console.log(e+" ERROR!")}); 249 } 250 var self = this; 251 if(obj.updatedTime != null) { 252 var date = (obj.updated_time.split('T')[0]).split('-'); 253 var time = ((obj.updated_time.split('T')[1]).split('+')[0]).split(':'); 254 } else { 255 var date = (obj.created_time.split('T')[0]).split('-'); 256 var time = ((obj.created_time.split('T')[1]).split('+')[0]).split(':'); 257 } 258 this.updated_time = new Date(date[0], date[1] - 1, date[2], time[0], time[1], time[2], 0); 259 this.updated_time = new Date((this.updated_time.getTime() - (this.updated_time.getTimezoneOffset() * 60 * 1000))); 260 this.likes = 0; 261 if(obj.likes != null) 262 this.likes = obj.likes.data.length; 263 }, 264 /** 265 Formata um objeto JSON para um objeto foto do widget. 266 @param {JSON Object} obj Photo do tipo objeto JSON com o padrão do Facebook 267 @private 268 @function 269 */ 270 preparePhoto:function(obj){ 271 this.image = obj.images[0].source; 272 this.w = obj.images[0].width; 273 this.h = obj.images[0].height; 274 this.id = obj.id; 275 276 if(obj.message != null) 277 this.message = obj.message; 278 else 279 this.message = null; 280 281 var self = this; 282 if(obj.updatedTime != null) { 283 var date = (obj.updated_time.split('T')[0]).split('-'); 284 var time = ((obj.updated_time.split('T')[1]).split('+')[0]).split(':'); 285 } else { 286 var date = (obj.created_time.split('T')[0]).split('-'); 287 var time = ((obj.created_time.split('T')[1]).split('+')[0]).split(':'); 288 } 289 this.updated_time = new Date(date[0], date[1] - 1, date[2], time[0], time[1], time[2], 0); 290 this.updated_time = new Date((this.updated_time.getTime() - (this.updated_time.getTimezoneOffset() * 60 * 1000))); 291 this.likes = 0; 292 if(obj.likes != null) 293 this.likes = obj.likes.data.length; 294 } 295 } 296 297 /* call all elements */ 298 $(document).ready(function() { 299 multimedia.init('#container'); 300 multimedia.start(); 301 }); 302