1$(document).ready(function(){ 2 bindGlobalFacebookEvents (); 3 bindFacebookPhotoUploadEvents (); 4}); 5 6/** 7 * Namespace for facebook actions 8 */ 9var LLFacebook = function () { 10 var sdkDoneLoading = false; 11 return { 12 // when set, currentStatus has fields (connected, id, accessToken, and signedRequest) 13 // and it is what you get in your onLogin and checkLoginStatus callbacks (in onLogin, connected will be true) 14 currentStatus : null, 15 16 // mechanism for scheduling code to run as soon as the FB SDK is loaded 17 onSDKLoaded : [], 18 onLoad : function (callback) 19 { 20 LLFacebook.onSDKLoaded.push(callback); 21 }, 22 sdkLoaded : function () 23 { 24 sdkDoneLoading = true; 25 $.each (LLFacebook.onSDKLoaded, function (index, callback) { 26 callback (); 27 }); 28 }, 29 isActive: function () { 30 return sdkDoneLoading; 31 }, 32 33 login : function (loginCallback, scope) { 34 var doLogin = function (callback, scope) { 35 FB.login(function(response) { 36 var loggedIn = false; 37 if (response.authResponse) 38 { 39 var granted = {}; 40 $.each (response.authResponse.grantedScopes.split (','), function (index, perm) { 41 granted[perm] = true; 42 }); 43 if (LLFacebook.scopeCovered (granted, scope)) { 44 loggedIn = true; 45 } 46 } 47 if (loggedIn) { 48 LLFacebook.currentStatus = LLFacebook.parseCurrentStatus (true, response.authResponse); 49 callback (LLFacebook.currentStatus); 50 } else { 51 LLFacebook.onLoginCancel (response); 52 } 53 }, 54 { scope: scope, return_scopes: true }); 55 }; 56 57 if (!scope) { 58 scope = LLFacebook.defaultScope; 59 } 60 LLFacebook.checkLoginStatus (function (status) { 61 if (!loginCallback) { 62 loginCallback = LLFacebook.onLogin; 63 } 64 65 if (status.connected) 66 { 67 LLFacebook.checkScope (scope, function (scopeCovered) { 68 if (scopeCovered) { 69 loginCallback (status); 70 } else { 71 doLogin (loginCallback, scope); 72 } 73 }); 74 } else { 75 doLogin (loginCallback, scope); 76 } 77 }); 78 }, 79 80 getUserInfo : function (callback) 81 { 82 // fields are id, first_name, last_name, gender, email, username 83 FB.api('/me', function (response) { callback (response); }); 84 }, 85 86 getInfoForImagePost : function (callback) 87 { 88 FB.api('/me?fields=albums,accounts,first_name,last_name', function (response) { callback (response); }); 89 }, 90 91 getPageAlbums : function (pageID, callback) 92 { 93 FB.api('/' + pageID + '/albums', function (response) { callback (response); }); 94 }, 95 96 checkLoginStatus : function (callback, forceReload) 97 { 98 if (LLFacebook.currentStatus && LLFacebook.currentStatus.connected && !forceReload) 99 { 100 // if we're already connected, not much is changing, so we cache the info 101 callback (LLFacebook.currentStatus); 102 } 103 else 104 { 105 FB.getLoginStatus( 106 function(response) { 107 LLFacebook.currentStatus = LLFacebook.parseCurrentStatus (response.status == 'connected', response.authResponse); 108 callback (LLFacebook.currentStatus); 109 } 110 ); 111 } 112 }, 113 114 // read the info supplied by Facebook and store the connection status and info here 115 parseCurrentStatus : function (connected, authResponse) 116 { 117 var status = { 118 connected : false, 119 id : null, 120 accessToken : null, 121 signedRequest : null 122 }; 123 if (connected) { 124 status.connected = true; 125 status.id = authResponse.userID; 126 status.accessToken = authResponse.accessToken; 127 status.signedRequest = authResponse.signedRequest; 128 } 129 return status; 130 }, 131 132 // override these to do something with the response 133 onLogin : function (response) { return; }, 134 onLoginCancel : function (response) { return; }, 135 136 linkFacebookIDToCurrentAccount : function (accessToken, source, success, failure) { 137 var info = { 138 action : 'LinkFacebookAccount', 139 AccessToken: accessToken, 140 Source: source 141 }; 142 setTokenValue (info); 143 $.post(LLFacebook.facebookActionUrl, info, function(response,status) 144 { 145 if(status == "success" && response == "SUCCESS") 146 { 147 success (); 148 } 149 else 150 { 151 failure (); 152 } 153 },"text"); 154 }, 155 156 unlinkCurrentAccount : function (success, failure) { 157 var info = { 158 action : 'UnlinkFacebookAccount' 159 }; 160 setTokenValue (info); 161 $.post(LLFacebook.facebookActionUrl, info, function(response,status) 162 { 163 if(status == "success" && response == "SUCCESS") 164 { 165 success (); 166 } 167 else 168 { 169 failure (); 170 } 171 },"text"); 172 }, 173
174 loginViaFacebook : function (currentStatus, callback, createAccount, autoLogin, source) { 175 LLFacebook.getUserInfo (function (user) { 176 var info = { 177 action : 'LoginViaFacebook', 178 AccessToken: currentStatus.accessToken, 179 CreateAccount : createAccount ? 1 : 0, 180 LinkedOnly: autoLogin ? 1 : 0, 181 Source: source 182 }; 183 setTokenValue (info); 184 $.post(LLFacebook.facebookActionUrl, info, function(response,status) 185 { 186 if(status == "success") 187 { 188 /* 189 * response looks like { 190 * Status: "Pending", 191 * CandidateAccounts: [ { (acct info) }, ... ], 192 * LoginRedirect: '/url' } 193 * Status can be SUCCESS, ERROR, Pending, or Not Found 194 * Pending and Not Found are handled below, while the others are handled in the callback 195 */ 196 197 try { 198 response = $.parseJSON (response); 199 } catch ($e) { 200 response = { Status: 'ERROR' }; 201 } 202 203 if (response.Status == 'Not Found' && !autoLogin) { 204 LLFacebook.setFeedbackMessage ('noAccount'); 205 resetSpinnerAndButtons (); 206 } else if (response.Status == 'Staff') { 207 LLFacebook.setFeedbackMessage ('staffAccount'); 208 resetSpinnerAndButtons (); 209 } else if (response.Status == 'Pending') { 210 LLFacebook.showUserChooserPopup (user, currentStatus.accessToken, response.CandidateAccounts, response.LoginRedirect, callback); 211 } else { 212 callback (response); 213 } 214 } 215 },"text"); 216 }); 217 }, 218 219 showUserChooserPopup: function (fbUser, access_token, matchingAccounts, loginRedirect, callback) { 220 var popup = $("#fb-user-chooser"); 221 var hasStaff = false;
222 popup.data ('login_info', { 223 response: { CandidateAccounts: [], LoginRedirect: loginRedirect }, 224 callback: callback, 225 access_token: access_token 226 }); 227 popup.find (".fb-email-address").text (fbUser.email); 228 var tableBody = popup.find ("tbody").html (''); 229 $.each (matchingAccounts, function (index, account) { 230 var row = $('<tr/>', { 'data-userid': account.UserID }); 231 $('<td/>', { text: account.FirstName + ' ' + account.LastName}).appendTo (row); 232 $('<td/>', { text: account.Username }).appendTo (row); 233 $('<td/>', { text: account.LastActiveFormatted }).appendTo (row); 234 var actionCell = $('<td/>'); 235 if (account.Staff == "1") { 236 hasStaff = true; 237 $('<span/>', { text: 'N/A*', 'class': 'staff' }).appendTo (actionCell); 238 } else { 239 $('<a/>', { href: '#', text: 'Log In', 'class': 'selectUser btn-sm btn-org' }).appendTo (actionCell); 240 } 241 actionCell.appendTo (row); 242 row.appendTo (tableBody); 243 }); 244 if (hasStaff) { 245 popup.find ('.staffAccountNotice').show (); 246 } else { 247 popup.find ('.staffAccountNotice').hide (); 248 } 249 LLUtil.stripe ('#fb-user-chooser tbody tr'); 250 $("#fb-open-user-chooser").trigger ('click'); 251 252 if (!ll_fancyboxInitDone) { 253 console.log ('Fancybox is not set up! Call bindFancyboxEvents() in the script on this page.'); 254 } 255 }, 256 257 finishLoginWithChosenUser: function (userID) { 258 var popup = $("#fb-user-chooser"); 259 var login_info = popup.data ('login_info'); 260 261 LLUtil.replaceButtonWithSpinner (popup.find ('.selectUser'), 20); 262 263 var info = { 264 action: 'LinkSelectedUserAcccount', 265 AccessToken: login_info.access_token, 266 UserID: userID 267 }; 268 setTokenValue (info); 269 270 $.post(LLFacebook.facebookActionUrl, info, function(response, status) { 271 login_info.response.Status = response; 272 login_info.callback (login_info.response); 273 },"text"); 274 }, 275 276 uploadPhoto : function (imageID, albumID, title, page_id, access_token, success, failure) { 277 var info = { 278 action : 'PostPhoto', 279 ImageID : imageID, 280 AlbumID: albumID, 281 Title : title, 282 PageID: page_id, 283 access_token : access_token 284 }; 285 setTokenValue (info); 286 287 $.post(LLFacebook.facebookActionUrl, info, function(response,status) 288 { 289 if(status == "success" && response == "SUCCESS") 290 { 291 success (); 292 } 293 else 294 { 295 failure (); 296 } 297 },"text"); 298 }, 299 300 getPermissions: function (callback) 301 { 302 FB.api('/me/permissions', function (response) { 303 var perms = {}; 304 if (response && response.data) { 305 $.each (response.data, function (index, perm) {
306 if (perm.status == "granted") { 307 perms[perm.permission] = true; 308 } 309 }); 310 } 311 callback (perms); 312 }); 313 }, 314 315 checkScope: function (scope, callback) { 316 LLFacebook.getPermissions (function (permissions) { 317 callback (LLFacebook.scopeCovered (permissions, scope)); 318 }); 319 }, 320 321 scopeCovered: function (aGranted, sRequested) { 322 var scopeCovered = true; 323 $.each (sRequested.split (','), function (index, perm) { 324 if (!aGranted[$.trim (perm)]) { 325 scopeCovered = false; 326 return false; 327 } 328 }); 329 return scopeCovered; 330 }, 331 332 getMultipleProfiles : function (aIDs, callback) 333 { 334 var batch = []; 335 $.each (aIDs, function (key, id) { 336 batch.push ({ 337 method: 'GET', 338 relative_url: id + "?fields=id,first_name,last_name,name,picture,gender" 339 }); 340 }); 341 LLFacebook.checkLoginStatus (function (currentStatus) { 342 if (currentStatus.accessToken) { 343 var params = { 344 batch: batch, 345 access_token: currentStatus.accessToken 346 }; 347 FB.api ('/', 'post', { batch: batch }, function (responses) { 348 var users = []; 349 $.each (responses, function (key, response) { 350 var userInfo = $.parseJSON (response.body); 351 if (response.code == 200) { 352 var user = $.extend ({}, userInfo); 353 user.pic = userInfo.picture.data.url; 354 user.pic_is_default = userInfo.picture.data.is_silhouette; 355 delete user.picture; 356 users.push(user); 357 } 358 }); 359 callback (users); 360 }); 361 } else { 362 callback ([]); 363 } 364 }); 365 }, 366 367 requestDialog: function (teamID, message, callback) { 368 FB.ui({ 369 method: 'apprequests', 370 message: message 371 }, function (response) { 372 if (response && response.request && response.to.length > 0) { 373 var requestID = response.request; 374 var facebookIDs = response.to; 375 LLFacebook.getMultipleProfiles (facebookIDs, function (fbUsers) { 376 var toInvite = []; 377 $.each (fbUsers, function (key, fbUser) { 378 toInvite.push ({ 379 FacebookID: fbUser.id, 380 FirstName: fbUser.first_name, 381 LastName: fbUser.last_name, 382 Gender: fbUser.gender, 383 ProfileImage: fbUser.pic, 384 pic_is_default: fbUser.pic_is_default, 385 FacebookRequestID: requestID 386 }); 387 }); 388 389 var info = { 390 action: 'RecordInvites', 391 FacebookRequestID: requestID, 392 Invites: JSON.stringify (toInvite), 393 TeamID: teamID 394 }; 395 setTokenValue (info); 396 397 $.post(LLFacebook.facebookActionUrl, info, function(response,status) 398 { 399 if(status == "success" && response != "ERROR") { 400 var playersInvited = $.parseJSON (response); 401 callback (playersInvited); 402 } else { 403 LLFacebook.setFeedbackMessage ('inviteError'); 404 } 405 },"text"); 406 }); 407 } 408 else if (response.error_message){ 409 LLFacebook.reportError(response.error_message); 410 } 411 } 412 ); 413 }, 414 415 deleteRequests : function (teamID, participantIDs, callback) { 416 var info = { 417 action: 'DeleteInvites', 418 ParticipantIDs: participantIDs.join (','), 419 TeamID: teamID 420 }; 421 setTokenValue (info); 422 423 $.post(LLFacebook.facebookActionUrl, info, function(response,status) 424 { 425 if (callback) { 426 callback (response); 427 } 428 },"text"); 429 }, 430 431 sendRequests : function (message, friendIDs, callback) 432 { 433 if (friendIDs instanceof Array) { 434 friendIDs = friendIDs.join(',') 435 } 436 FB.ui( 437 { 438 method: 'apprequests', 439 message: message, 440 to: friendIDs 441 }, 442 function (response) { callback (response); } 443 ); 444 }, 445 446 addPageTab : function (callback) 447 { 448 FB.ui ( 449 { 450 method: 'pagetab' 451 }, 452 function (response) { callback (response); } 453 ); 454 }, 455 456 setFeedbackMessage : function (messageType) { 457 var msgBox = $("#fb-feedback"); 458 msgBox.find ('.feedback').addClass ('hidden').filter ('.' + messageType).removeClass ('hidden'); 459 msgBox.removeClass ('').addClass (messageType).hide (); 460 msgBox.prependTo ($('body')).slideDown (400); 461 }, 462 463 // @BUGBUG: We use the private _apiKey property to get our app id... this may break! 464 removePageTab : function (pageID, callback) 465 { 466 FB.api('/' + pageID + '?fields=access_token', function (response) { 467 FB.api ( 468 '/' + pageID + '/tabs/app_' + FB._apiKey + '?access_token='
468+ response.access_token, 469 'delete', 470 function (responseTwo) { 471 callback (responseTwo); 472 } 473 ); 474 }); 475 }, 476 477 updatePrimaryFacebookPage : function (llFacebookPageID, success, failure) 478 { 479 var info = { 480 action : 'UpdatePrimaryFacebookPage', 481 FacebookPageID : llFacebookPageID 482 }; 483 setTokenValue (info); 484 485 $.post(LLFacebook.facebookActionUrl, info, function(response,status) 486 { 487 if(status == "success" && response == "SUCCESS") 488 { 489 success (); 490 } 491 else 492 { 493 failure (); 494 } 495 },"text"); 496 }, 497 498 reportError: function (errorMessage) { 499 var info = { 500 action : 'ReportError', 501 Message : errorMessage 502 }; 503 setTokenValue (info); 504 $.post(LLFacebook.facebookActionUrl, info, function (response, status){ 505 console.log ('Facebook Error: ' + errorMessage); 506 },"text"); 507 }, 508 509 facebookActionUrl : '/async/facebook', 510 defaultScope : 'public_profile,email' 511 }; 512}(); 513 514function bindFacebookPhotoUploadEvents () { 515 if ($("#postImageToFacebook").length > 0) { 516 517 function updateAlbumList (albums) { 518 var albumSelector = $("#facebookAlbumSelector").html (''); 519 $.each (albums, function (key, album) { 520 $('<option/>', { value: album.id, text: album.name }).appendTo (albumSelector); 521 }); 522 } 523 524 function doUpload () { 525 var id = $("#facebookAlbumSelector").val (); 526 var account_id = $("#facebookAccountSelector").val (); 527 if (!id) { 528 id = account_id; 529 } 530 var fbInfo = $("#postImageToFacebookContainer").data ('FBInfo'); 531 var page_id = (account_id == fbInfo.FacebookUserID) ? '' : account_id; 532 var image_id = $("#postImageToFacebook").attr ('data-imageid'); 533 var title = $("#postImageToFacebook").attr ('data-title'); 534 535 $("#postImageToFacebookContainer").removeClass ("active error").addClass ("loading"); 536 LLFacebook.uploadPhoto ( 537 image_id, 538 id, 539 title, 540 page_id, 541 fbInfo.AccessToken, 542 function () { 543 $("#postImageToFacebookContainer").removeClass ("loading").addClass ("success"); 544 setTimeout (function () { $.fancybox.close (); }, 1000); 545 }, 546 function () { 547 $("#postImageToFacebookContainer").removeClass ("loading").addClass ("error"); 548 } 549 ); 550 } 551 552 $("#postImageToFacebook").on ('click', function () { 553 if (!ll_fancyboxInitDone) { 554 console.log ('Fancybox is not set up! Call bindFancyboxEvents() in the script on this page.'); 555 } 556 $("#postToFacebookPreview").attr ('src', $(this).attr ('href')); 557 $("#postImageToFacebookContainer").removeClass ("error success loading").addClass ("active"); 558 $("#openPostToFacebook").trigger ('click'); 559 560 if ($("#facebookAlbumSelector option").length > 0) { 561 return false; // the controls are already initialized 562 } 563 564 LLFacebook.login (function (status) { 565 if (!status.connected) { 566 $.fancybox.close (); 567 return; 568 } 569 LLFacebook.getInfoForImagePost (function (me) { 570 var user_name = me.first_name + ' ' + me.last_name; 571 var user_id = me.id; 572 var my_albums = me.albums ? me.albums.data : []; 573 var my_pages = me.accounts ? me.accounts.data : []; 574 var acctSelector = $("#facebookAccountSelector").html (''); 575 $('<option/>', { value: user_id, text: user_name }).appendTo (acctSelector); 576 $.each (my_pages, function (key, page) { 577 $('<option/>', { value: page.id, text: page.name }).appendTo (acctSelector); 578 }); 579 acctSelector.val (user_id); 580 acctSelector.unbind ('change').on ('change', function () { 581 var account_id = $(this).val (); 582 LLFacebook.getPageAlbums (account_id, function (albums) { 583 updateAlbumList (albums.data); 584 }); 585 }); 586 587 if (my_pages.length > 0) { 588 acctSelector.parents ('p.inputRow').show (); 589 } else { 590 acctSelector.parents ('p.inputRow').hide (); 591 } 592 updateAlbumList (my_albums); 593 594 // Bind other events 595 $("#postImageToFacebookSubmit").unbind ('click').on ('click', function () { 596 doUpload (); 597 return false; 598 }); 599 $("#postImageToFacebookContainer").unbind ('click').on ('click', '.tryAgain', function () { 600 $("#postImageToFacebookContainer").removeClass ("error").addClass ("active"); 601 }).on ('click', '.cancel', function () { 602 $.fancybox.close (); 603 }); 604 605 // save some data for later use 606 $("#postImageToFacebookContainer").data ('FBInfo', { 607 FacebookUserID: user_id, 608 AccessToken: status.accessToken 609 }); 610 }); 611 }, 'email,user_photos,manage_pages,publish_actions'); 612 return false;
613 }); 614 } 615} 616 617function resetSpinnerAndButtons () { 618 $(".facebookButton").show (); 619 $(".loadingGraphic").hide (); 620} 621 622function bindGlobalFacebookEvents () { 623 /** 624 * in page code, override LLFacebook.onLogin to control what happens when the login is finished 625 */ 626 $(".facebookLoginButton,.facebookSignupButton,.facebookConnectButton,.facebookLoginPlain").click (function () { 627 if ($(this).hasClass ('disabled-for-admin')) { 628 alert ('Sorry. As an admin user, you cannot connect to Facebook on behalf of the player.'); 629 return false; 630 } 631 LLUtil.replaceButtonWithSpinner ($(this), 30); 632 LLFacebook.login (); 633 return false; 634 }); 635 636 // default action when user cancels login (or refuses permissions) 637 LLFacebook.onLoginCancel = function () { 638 LLFacebook.setFeedbackMessage ('loginError'); 639 resetSpinnerAndButtons (); 640 }; 641 642 $("#fb-feedback").on ("click", function () { 643 $(this).slideUp (); 644 }); 645 646 $("#fb-user-chooser").on ('click', '.cancel', function () { 647 $.fancybox.close (); 648 resetSpinnerAndButtons (); 649 return false; 650 }).on ('click', '.selectUser', function () { 651 var userID = $(this).parents ('tr').attr ('data-userid'); 652 LLFacebook.finishLoginWithChosenUser (userID); 653 return false; 654 }); 655 656 $(".fb-account-unlink").on ("click", function () { 657 LLUtil.replaceButtonWithSpinner ($(this)); 658 $("#facebookUnlinkContainer p").hide (); 659 LLFacebook.unlinkCurrentAccount (function () { 660 $("#facebookUnlinkContainer").hide (); 661 LLFacebook.setFeedbackMessage ('unlink'); 662 }, function () { 663 $("#facebookUnlinkContainer .loadingGraphic").hide (); 664 $("#facebookUnlinkContainer .fb-account-unlink, #facebookUnlinkContainer p").show (); 665 LLFacebook.setFeedbackMessage ('unlinkError'); 666 }); 667 }); 668 669 /** 670 * If the fb-root element (inserted by the SDK) has the checkLoginStatus (only exists on first try of the session), 671 * we check to see if the user is logged-in with an authorized, linked Facebook account. If so, we log them in! 672 */ 673 if ($("#fb-root").hasClass('checkLoginStatus')) 674 { 675 LLFacebook.onLoad (function () { LLFacebook.checkLoginStatus( 676 function(status) { 677 if (status.connected) { 678 LLFacebook.loginViaFacebook (status, function (response) { 679 if (response.Status == 'SUCCESS') { 680 LLFacebook.setFeedbackMessage ('autoLogin'); 681 } 682 }, false, true, 'Auto Login'); 683 } 684 } 685 )}); 686 } 687}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.