(function(context,$) { "use strict"; context.JK = context.JK || {}; context.JK.Sidebar = function(app) { var logger = context.JK.logger; var friends = []; var notifications = []; function initializeFriendsPanel() { $('#sidebar-search-header').hide(); var url = "/api/users/" + context.JK.currentUserId + "/friends" $.ajax({ type: "GET", dataType: "json", contentType: 'application/json', url: url, processData: false, success: function(response) { friends = response; updateFriendList(response); // set friend count $('#sidebar-friend-count').html(response.length); }, error: app.ajaxError }); return false; } function updateFriendList(response) { $('#sidebar-friend-list').empty(); // show online friends first (sort by first name within online/offline groups) response.sort(function(a, b) { var a_online = a.online; var b_online = b.online; var a_firstname = a.first_name.toLowerCase(); var b_firstname = b.first_name.toLowerCase(); if (b_online != a_online) { if (b_online < a_online) return -1; if (b_online > a_online) return 1; return 0; } if (a_firstname < b_firstname) return -1; if (a_firstname > b_firstname) return 1; return 0; }); $.each(response, function(index, val) { var css = val.online ? '' : 'offline'; friends[val.id] = val; // fill in template for Connect pre-click var template = $('#template-friend-panel').html(); var searchResultHtml = context.JK.fillTemplate(template, { userId: val.id, cssClass: css, avatar_url: context.JK.resolveAvatarUrl(val.photo_url), userName: val.name, status: val.online ? 'Available' : 'Offline', extra_info: '', info_image_url: '' }); $('#sidebar-friend-list').append(searchResultHtml); }); } function initializeNotificationsPanel() { // retrieve pending notifications for this user var url = "/api/users/" + context.JK.currentUserId + "/notifications" $.ajax({ type: "GET", dataType: "json", contentType: 'application/json', url: url, processData: false, success: function(response) { notifications = response; updateNotificationList(response); // set notification count $('#sidebar-notification-count').html(response.length); }, error: app.ajaxError }); } function updateNotificationList(response) { $('#sidebar-notification-list').empty(); $.each(response, function(index, val) { notifications[val.notification_id] = val; // fill in template for Connect pre-click var template = $('#template-notification-panel').html(); var notificationHtml = context.JK.fillTemplate(template, { notificationId: val.notification_id, avatar_url: context.JK.resolveAvatarUrl(val.photo_url), text: val.formatted_msg, date: val.created_at }); $('#sidebar-notification-list').append(notificationHtml); initializeActions(val, val.description); }); } function initializeActions(notification, type) { // wire up "x" button to delete notification $('li[notification-id=' + notification.notification_id + ']').find('#img-delete-notification').click(deleteNotification); if (type == context.JK.MessageType.FRIEND_REQUEST) { var $action_btn = $('li[notification-id=' + notification.notification_id + ']').find('#btn-notification-action'); $action_btn.text('ACCEPT'); $action_btn.click(function() { acceptFriendRequest(notification.friend_request_id); }); } } function deleteNotification(evt) { evt.stopPropagation(); var notificationId = $(this).attr('notification-id'); var url = "/api/users/" + context.JK.currentUserId + "/notifications/" + notificationId; $.ajax({ type: "DELETE", dataType: "json", contentType: 'application/json', url: url, processData: false, success: function(response) { delete notifications[notificationId]; $('li[notification-id=' + notificationId + ']').hide(); decrementNotificationCount(); }, error: app.ajaxError }); } function initializeChatPanel() { } function search(query) { logger.debug('query=' + query); if (query !== '') { context.JK.search(query, app, onSearchSuccess); } } function onSearchSuccess(response) { $.each(response.musicians, function(index, val) { // fill in template for Connect pre-click var template = $('#template-sidebar-search-result').html(); var searchResultHtml = context.JK.fillTemplate(template, { userId: val.id, avatar_url: context.JK.resolveAvatarUrl(val.photo_url), userName: val.name, location: val.location }); $('#sidebar-search-results').append(searchResultHtml); // fill in template for Connect post-click template = $('#template-sidebar-invitation-sent').html(); var invitationSentHtml = context.JK.fillTemplate(template, { userId: val.id, first_name: val.first_name, profile_url: "/users/" + val.id }); $('#sidebar-search-results').append(invitationSentHtml); // initialize visibility of the divs $('div[layout=sidebar] div[user-id=' + val.id + '].sidebar-search-connected').hide(); $('div[layout=sidebar] div[user-id=' + val.id + '].sidebar-search-result').show(); // wire up button click handler if search result is not a friend if (!val.is_friend) { $('div[layout=sidebar] div[user-id=' + val.id + ']').find('#btn-connect-friend').click(sendFriendRequest); } // hide the button if the search result is already a friend else { $('div[layout=sidebar] div[user-id=' + val.id + ']').find('#btn-connect-friend').hide(); } }); // show header $('#sidebar-search-header').show(); // hide panels $('[layout-panel="contents"]').hide(); $('[layout-panel="contents"]').css({"height": "1px"}); // resize search results area $('#sidebar-search-results').height(getHeight() + 'px'); } function getHeight() { // TODO: refactor this - copied from layout.js var sidebarHeight = $(context).height() - 75 - 2 * 60 + $('[layout-sidebar-expander]').height(); var combinedHeaderHeight = $('[layout-panel="contents"]').length * 36; var searchHeight = $('.sidebar .search').first().height(); var expanderHeight = $('[layout-sidebar-expander]').height(); var expandedPanelHeight = sidebarHeight - (combinedHeaderHeight + expanderHeight + searchHeight); return expandedPanelHeight; } function showFriendsPanel() { var $expandedPanelContents = $('[layout-id="panelFriends"] [layout-panel="contents"]'); var expandedPanelHeight = getHeight(); // hide all other contents $('[layout-panel="contents"]').hide(); $('[layout-panel="contents"]').css({"height": "1px"}); // show the appropriate contens $expandedPanelContents.show(); $expandedPanelContents.animate({"height": expandedPanelHeight + "px"}, 400); } function friendRequestCallback(userId) { // toggle the pre-click and post-click divs $('div[layout=sidebar] div[user-id=' + userId + '].sidebar-search-connected').show(); $('div[layout=sidebar] div[user-id=' + userId + '].sidebar-search-result').hide(); } function sendFriendRequest(evt) { evt.stopPropagation(); var userId = $(this).parent().attr('user-id'); context.JK.sendFriendRequest(app, userId, friendRequestCallback); } function hideSearchResults() { emptySearchResults(); $('#search-input').val(''); $('#sidebar-search-header').hide(); showFriendsPanel(); } function emptySearchResults() { $('#sidebar-search-results').empty(); $('#sidebar-search-results').height('0px'); } function incrementNotificationCount() { var count = parseInt($('#sidebar-notification-count').html()); $('#sidebar-notification-count').html(count + 1); } function decrementNotificationCount() { var count = parseInt($('#sidebar-notification-count').html()); $('#sidebar-notification-count').html(count - 1); } function acceptFriendRequest(friend_request_id) { var friend_request = {}; friend_request.status = 'accept'; var jsonData = JSON.stringify(friend_request); var url = "/api/users/" + context.JK.currentUserId + "/friend_requests/" + friend_request_id; $.ajax({ type: "POST", dataType: "json", contentType: 'application/json', url: url, data: jsonData, processData: false, success: function(response) { initializeFriendsPanel(); // refresh friends panel when request is accepted }, error: app.ajaxError }); } // default handler for incoming notification function handleNotification(payload, type) { // update notifications panel in sidebar notifications[payload.notification_id] = { "id": payload.notification_id, "photo_url": payload.photo_url, "formatted_msg": payload.msg, "created_at": payload.created_at }; incrementNotificationCount(); var template = $("#template-notification-panel").html(); var notificationHtml = context.JK.fillTemplate(template, { notificationId: payload.notification_id, avatar_url: context.JK.resolveAvatarUrl(payload.photo_url), text: payload.msg, date: payload.created_at }); $('#sidebar-notification-list').prepend(notificationHtml); initializeActions(payload, type); } // TODO: optimize so we're not hitting server on each keyup once > 2 characters are entered function events() { $('#search-input').keyup(function(evt) { // ENTER KEY if (evt.which === 13) { return hideSearchResults(); } // ESCAPE KEY if (evt.which === 27) { return hideSearchResults(); } var query = $(this).val(); if (query === '') { return hideSearchResults(); } if (query !== '' && query.length > 2) { emptySearchResults(); search(query); } }); $('#sidebar-search-expand').click(function(evt) { $('#searchForm').submit(); hideSearchResults(); }); // wire up FRIEND_UPDATE handler context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_UPDATE, function(header, payload) { logger.debug("Handling FRIEND_UPDATE msg " + JSON.stringify(payload)); // update friends panel in sidebar friends[payload.user_id].online = payload.online; updateFriendList(friends); // display notification var online_text = payload.online ? "online" : "offline"; app.notify({ "title": "Friend is now " + online_text, "text": payload.msg, "avatar_url": payload.photo_url }); }); ////////////////////////////////////////////////////////////// // wire up FRIEND_REQUEST handler context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_REQUEST, function(header, payload) { logger.debug("Handling FRIEND_REQUEST msg " + JSON.stringify(payload)); handleNotification(payload, header.type); // display notification app.notify({ "title": "New Friend Request", "text": payload.msg, "avatar_url": payload.photo_url }, { "ok_text": "ACCEPT", "ok_callback": acceptFriendRequest, "ok_callback_args": payload.friend_request_id } ); }); ////////////////////////////////////////////////////////////// // wire up FRIEND_REQUEST_ACCEPTED handler context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_REQUEST_ACCEPTED, function(header, payload) { logger.debug("Handling FRIEND_REQUEST_ACCEPTED msg " + JSON.stringify(payload)); handleNotification(payload, header.type); // refresh friends panel initializeFriendsPanel(); // display notification app.notify({ "title": "Friend Request Accepted", "text": payload.msg, "avatar_url": payload.photo_url }); }); ////////////////////////////////////////////////////////////// } this.initialize = function() { events(); initializeFriendsPanel(); initializeChatPanel(); initializeNotificationsPanel(); }; }; })(window,jQuery);