(function (context, $) { "use strict"; context.JK = context.JK || {}; context.JK.ProfileScreen = function (app) { var logger = context.JK.logger; var userId; var user = null; var userDefer = null; var rest = context.JK.Rest(); var decrementedFriendCountOnce = false; var sentFriendRequest = false; var profileScreen = null; var textMessageDialog = null; var feed = null; var instrument_logo_map = context.JK.getInstrumentIconMap24(); var proficiencyDescriptionMap = { "1": "BEGINNER", "2": "INTERMEDIATE", "3": "EXPERT" }; var proficiencyCssMap = { "1": "proficiency-beginner", "2": "proficiency-intermediate", "3": "proficiency-expert" }; function beforeShow(data) { userId = data.id; feed.setUser(userId); } function afterShow(data) { initUser(); resetForm(); } function beforeHide(data) { feed.setUser(null); } function resetForm() { $('#profile-instruments').empty(); $('#profile-about').show(); $('#profile-history').hide(); $('#profile-bands').hide(); $('#profile-social').hide(); $('#profile-favorites').hide(); $('.profile-nav a.active').removeClass('active'); $('.profile-nav a#profile-about-link').addClass('active'); } function initUser() { user = null; decrementedFriendCountOnce = false; sentFriendRequest = false; userDefer = rest.getUserDetail({id: userId}) .done(function (response) { user = response; configureUserType(); renderActive(); }) .fail(function (jqXHR) { if (jqXHR.status >= 500) { context.JK.fetchUserNetworkOrServerFailure(); } else if (jqXHR.status == 404) { context.JK.entityNotFound("User"); } else { app.ajaxError(arguments); } }); } function isMusician() { return user.musician; } function isCurrentUser() { return userId === context.JK.currentUserId; } function configureUserType() { if (isMusician()) { $('#profile-history-link').show(); $('#profile-bands-link').show(); $('#profile-instruments').show(); $('#profile-session-stats').show(); $('#profile-recording-stats').show(); // $('#profile-following-stats').hide(); // $('#profile-favorites-stats').hide(); $('.profile-social-left').show(); $('#profile-type-label').text('musician'); $('#profile-location-label').text('Location'); } else { $('#profile-history-link').hide(); $('#profile-bands-link').hide(); $('#profile-instruments').hide(); $('#profile-session-stats').hide(); $('#profile-recording-stats').hide(); // $('#profile-following-stats').show(); // $('#profile-favorites-stats').show(); $('.profile-social-left').hide(); $('#profile-type-label').text('fan'); $('#profile-location-label').text('Presence'); } if (isCurrentUser()) { $('#btn-profile-edit').show(); $('#btn-add-friend').hide(); $('#btn-follow-user').hide(); $('#btn-message-user').hide(); } else { configureFriendFollowersControls(); $('#btn-profile-edit').hide(); $('#btn-add-friend').show(); $('#btn-follow-user').show(); $('#btn-message-user').show(); } } function configureFriendFollowersControls() { // wire up Add Friend click configureFriendButton(); // wire up Follow click configureFollowingButton(); } /****************** MAIN PORTION OF SCREEN *****************/ // events for main screen function events() { // wire up panel clicks -- these need to check deferred because they can't be hidden when in an invalid state $('#profile-about-link').click(function () { renderTabDeferred(renderAbout) }); $('#profile-history-link').click(function () { renderTabDeferred(renderHistory) }); $('#profile-bands-link').click(function () { renderTabDeferred(renderBands) }); $('#profile-social-link').click(function () { renderTabDeferred(renderSocial) }); $('#profile-favorites-link').click(function () { renderTabDeferred(renderFavorites) }); // this doesn't need deferred because it's only shown when valid $('#btn-add-friend').click(handleFriendChange); $('#btn-follow-user').click(handleFollowingChange); $('#btn-message-user').click(handleMessageMusician); } function handleFriendChange(evt) { if (isFriend()) { removeFriend(evt); } else { sendFriendRequest(evt); } return false; } function handleFollowingChange(evt) { if (isFollowing()) { removeFollowing(false, userId); } else { addFollowing(); } return false; } function handleMessageMusician(evt) { app.layout.showDialog('text-message', { d1: userId }); return false; } function sendFriendRequest(evt) { evt.stopPropagation(); setFriend(true); // TODO: you aren't a friend yet. just a request to be one really there are 3 states here. sentFriendRequest = true; rest.sendFriendRequest(app, userId, friendRequestCallback); } function removeFriend(evt) { evt.stopPropagation(); rest.removeFriend({friend_id: userId}) .done(function () { updateFriendCount(-1); setFriend(false); configureFriendButton(); }) .fail(app.ajaxError); } function isFriend() { return user.is_friend; } function setFriend(isFriend) { user.is_friend = isFriend; } function friendRequestCallback() { configureFriendButton(); } function configureFriendButton() { if (isFriend()) { $('#btn-add-friend').text('DISCONNECT'); } else { $('#btn-add-friend').text('CONNECT'); } } function addFollowing() { rest.addFollowing({user_id: userId}) .done(function () { updateFollowingCount(1); setFollowing(true); configureFollowingButton(); context.JK.GA.trackJKSocial(context.JK.GA.Categories.jkFollow, isMusician() ? context.JK.GA.JKSocialTargets.musician : context.JK.GA.JKSocialTargets.fan); }) .fail(app.ajaxError); } function removeFollowing(isBand, id) { rest.removeFollowing(id) .done(function () { if (!isBand) { updateFollowingCount(-1); setFollowing(false); configureFollowingButton(); } else { updateBandFollowingCount(id, -1); // refresh stats configureBandFollowingButton(false, id); } }) .fail(app.ajaxError); } function isFollowing() { return user.is_following; } function setFollowing(isFollowing) { user.is_following = isFollowing; } function configureFollowingButton() { if (isFollowing()) { $('#btn-follow-user').text('UNFOLLOW'); } else { $('#btn-follow-user').text('FOLLOW'); } } function configureEditProfileButton() { $('#btn-follow-user').click(addFollowing); } // refreshes the currently active tab function renderActive() { if ($('#profile-about-link').hasClass('active')) { renderAbout(); } else if ($('#profile-history-link').hasClass('active')) { renderHistory(); } else if ($('#profile-bands-link').hasClass('active')) { renderBands(); } else if ($('#profile-social-link').hasClass('active')) { renderSocial(); } else if ($('#profile-favorites-link').hasClass('active')) { renderFavorites(); } } function renderTabDeferred(tabRenderer) { userDefer .done(function () { tabRenderer(); }) .fail(function () { // try again initUser(); }) } /****************** ABOUT TAB *****************/ function renderAbout() { $('#profile-instruments').empty(); $('#profile-about').show(); $('#profile-history').hide(); $('#profile-bands').hide(); $('#profile-social').hide(); $('#profile-favorites').hide(); $('.profile-nav a.active').removeClass('active'); $('.profile-nav a#profile-about-link').addClass('active'); bindAbout(); } function bindAbout() { $('#profile-instruments').empty(); // name $('#profile-username').html(user.name); // avatar $('#profile-avatar').attr('src', context.JK.resolveAvatarUrl(user.photo_url)); // instruments if (user.instruments) { for (var i = 0; i < user.instruments.length; i++) { var instrument = user.instruments[i]; var description = instrument.instrument_id; var proficiency = instrument.proficiency_level; var instrument_icon_url = context.JK.getInstrumentIcon256(description); // add instrument info to layout var template = $('#template-profile-instruments').html(); var instrumentHtml = context.JK.fillTemplate(template, { instrument_logo_url: instrument_icon_url, instrument_description: description, proficiency_level: proficiencyDescriptionMap[proficiency], proficiency_level_css: proficiencyCssMap[proficiency] }); $('#profile-instruments').append(instrumentHtml); } } // location $('#profile-location').html(user.location); // stats var text = user.friend_count > 1 || user.friend_count === 0 ? " Friends" : " Friend"; $('#profile-friend-stats').html('' + user.friend_count + '' + text); text = user.follower_count > 1 || user.follower_count === 0 ? " Followers" : " Follower"; $('#profile-follower-stats').html('' + user.follower_count + '' + text); if (isMusician()) { text = user.session_count > 1 || user.session_count === 0 ? " Sessions" : " Session"; $('#profile-session-stats').html(user.session_count + text); text = user.recording_count > 1 || user.recording_count === 0 ? " Recordings" : " Recording"; $('#profile-recording-stats').html(user.recording_count + text); } else { text = " Following"; $('#profile-following-stats').html(user.following_count + text); text = user.favorite_count > 1 || user.favorite_count === 0 ? " Favorites" : " Favorite"; $('#profile-favorite-stats').html(user.favorite_count + text); } renderBio(); } /** The biography show/edit functionality */ function renderBio() { function initializeBioVisibility() { $showBio.hide(); $noBio.hide(); $biographyEditor.hide(); $bioTextArea.val(user.biography); if(user.biography) { $showBio.show(); if(isCurrentUser()) { $editBiographyButton.show(); } else { $editBiographyButton.hide(); } $biographyText.text(user.biography).show(); } else { if(isCurrentUser()) { $noBio.show(); } } } var $bioTextArea = $('.user-biography', profileScreen); var $showBio = $('.have-bio', profileScreen); var $noBio = $('.no-bio', profileScreen); var $biographyEditor = $('.update-biography', profileScreen); var $addBiographyButton = $('a.enter-bio', profileScreen); var $editBiographyButton = $('#profile-edit-biography', profileScreen); var $submitBiographyButton = $('#btn-update-user-biography', profileScreen); var $cancelBiographyButton = $('#btn-cancel-user-biography', profileScreen); var $biographyText = $('#profile-biography', profileScreen); initializeBioVisibility(); $addBiographyButton.unbind('click').click(function() { $biographyEditor.val(user.biography).show(); return false; }); $editBiographyButton.unbind('click').click(function() { $editBiographyButton.hide(); $biographyText.hide(); $bioTextArea.val(user.biography); $biographyEditor.show(); return false; }) $submitBiographyButton.unbind('click').click(function() { var bio = $bioTextArea.val(); $bioTextArea.closest('div.field').removeClass('error'); $('.error-text', $bioTextArea.closest('div.field')).remove(); userDefer = rest.updateUser({ biography: bio }) .done(function(response) { user = response; initializeBioVisibility(); }) .fail(function(jqXHR) { if(jqXHR.status == 422) { var errors = JSON.parse(jqXHR.responseText) var biography = context.JK.format_errors("biography", errors); if(biography != null) { $bioTextArea.closest('div.field').addClass('error').end().after(biography); } else { app.notifyServerError(jqXHR, "Unable to update biography") } } else { app.notifyServerError(jqXHR, "Unable to update biography") } }) return false; }) $cancelBiographyButton.unbind('click').click(function() { initializeBioVisibility(); return false; }) } /****************** SOCIAL TAB *****************/ function renderSocial() { $('#profile-social-friends').empty(); $('#profile-social-followings').empty(); $('#profile-social-followers').empty(); $('#profile-about').hide(); $('#profile-history').hide(); $('#profile-bands').hide(); $('#profile-social').show(); $('#profile-favorites').hide(); $('.profile-nav a.active').removeClass('active'); $('.profile-nav a#profile-social-link').addClass('active'); bindSocial(); } function bindSocial() { if (isMusician()) { // FRIENDS rest.getFriends({id: userId}) .done(function (response) { if (response && response.length > 0) { $.each(response, function (index, val) { var template = $('#template-profile-social').html(); var friendHtml = context.JK.fillTemplate(template, { userId: val.id, hoverAttributeId: "user-id", hoverAction: val.musician ? "musician" : "fan", avatar_url: context.JK.resolveAvatarUrl(val.photo_url), userName: val.name, location: val.location, type: "Friends" }); $('#profile-social-friends').append(friendHtml); }); } else { $('#profile-social-friends').html(' '); } context.JK.bindHoverEvents(); }) .fail(app.ajaxError) } rest.getFollowings({id: userId}) .done(function (response) { if (response && response.length > 0) { $.each(response, function (index, val) { var template = $('#template-profile-social').html(); var followingHtml = context.JK.fillTemplate(template, { userId: val.id, hoverAttributeId: val.type === "user" ? "user-id" : "band-id", hoverAction: val.type === "user" ? (val.musician ? "musician" : "fan") : "band", avatar_url: context.JK.resolveAvatarUrl(val.photo_url), userName: val.name, location: val.location }); $('#profile-social-followings').append(followingHtml); }); } else { $('#profile-social-followings').html(' '); } context.JK.bindHoverEvents(); }) .fail(app.ajaxError); rest.getFollowers({id: userId}) .done(function (response) { $.each(response, function (index, val) { var template = $('#template-profile-social').html(); var followerHtml = context.JK.fillTemplate(template, { userId: val.id, hoverAttributeId: "user-id", hoverAction: val.musician ? "musician" : "fan", avatar_url: context.JK.resolveAvatarUrl(val.photo_url), userName: val.name, location: val.location }); $('#profile-social-followers').append(followerHtml); }); context.JK.bindHoverEvents(); }) .fail(app.ajaxError); } /****************** HISTORY TAB *****************/ function renderHistory() { $('#profile-about').hide(); $('#profile-history').show(); $('#profile-bands').hide(); $('#profile-social').hide(); $('#profile-favorites').hide(); $('.profile-nav a.active').removeClass('active'); $('.profile-nav a#profile-history-link').addClass('active'); bindHistory(); } function bindHistory() { feed.refresh(); } /****************** BANDS TAB *****************/ function renderBands() { $('#profile-bands').empty(); $('#profile-about').hide(); $('#profile-history').hide(); $('#profile-bands').show(); $('#profile-social').hide(); $('#profile-favorites').hide(); $('.profile-nav a.active').removeClass('active'); $('.profile-nav a#profile-bands-link').addClass('active'); bindBands(); } function bindBands() { rest.getBands({id: userId}) .done(function (response) { if ((!response || response.length === 0) && isCurrentUser()) { var noBandHtml = $('#template-no-bands').html(); $("#profile-bands").html(noBandHtml); } else { addMoreBandsLink(); $.each(response, function (index, val) { // build band member HTML var musicianHtml = ''; if (val.musicians) { for (var i = 0; i < val.musicians.length; i++) { var musician = val.musicians[i]; var instrumentLogoHtml = ''; if (musician.instruments) { for (var j = 0; j < musician.instruments.length; j++) { var instrument = musician.instruments[j]; var inst = '/assets/content/icon_instrument_default24.png'; if (instrument.instrument_id in instrument_logo_map) { inst = instrument_logo_map[instrument.instrument_id].asset; } instrumentLogoHtml += ' '; } } // this template is in _findSession.html.erb var musicianTemplate = $('#template-musician-info').html(); musicianHtml += context.JK.fillTemplate(musicianTemplate, { userId: musician.id, avatar_url: context.JK.resolveAvatarUrl(musician.photo_url), profile_url: "/client#/profile/" + musician.id, musician_name: musician.name, instruments: instrumentLogoHtml }); } } var template = $('#template-profile-bands').html(); var bandHtml = context.JK.fillTemplate(template, { bandId: val.id, biography: val.biography, band_url: "/client#/bandProfile/" + val.id, avatar_url: context.JK.resolveBandAvatarUrl(val.photo_url), name: val.name, location: val.location, genres: formatGenres(val.genres), follower_count: val.follower_count, recording_count: val.recording_count, session_count: val.session_count, musicians: musicianHtml }); $('#profile-bands').append(bandHtml); // wire up Band Follow button click handler configureBandFollowingButton(val.is_following, val.id); }); if (response.length >= 3) { addMoreBandsLink(); } } context.JK.bindHoverEvents(); }) .fail(app.ajaxError); } function addMoreBandsLink() { if (isCurrentUser()) { var moreBandsHtml = $('#template-more-bands').html(); $("#profile-bands").append(moreBandsHtml); } } function formatGenres(genres) { var formattedGenres = ''; if (genres) { for (var i = 0; i < genres.length; i++) { var genre = genres[i]; formattedGenres += genre.description; if (i < genres.length - 1) { formattedGenres += ', '; } } } return formattedGenres; } function updateFriendCount(value) { if (!decrementedFriendCountOnce && !sentFriendRequest) { decrementedFriendCountOnce = true; var friendCount = $('#profile-friend-stats span.friend-count'); friendCount.text(value + parseInt(friendCount.text())); } } function updateFollowingCount(value) { var followingCount = $('#profile-follower-stats span.follower-count'); followingCount.text(value + parseInt(followingCount.text())); } function updateBandFollowingCount(bandId, value) { var bandFollowing = $('div[band-id="' + bandId + '"].profile-bands span.follower-count'); bandFollowing.text(value + parseInt(bandFollowing.text())); } function addBandFollowing(evt) { evt.stopPropagation(); var bandId = $(this).parent().parent().parent().parent().attr('band-id'); var newFollowing = {}; newFollowing.band_id = bandId; rest.addFollowing(newFollowing) .done(function (response) { logger.debug("following band " + bandId); updateBandFollowingCount(bandId, 1); // increase counter configureBandFollowingButton(true, bandId); context.JK.GA.trackJKSocial(context.JK.GA.Categories.jkFollow, context.JK.GA.JKSocialTargets.band); }) .fail(app.ajaxError); } function configureBandFollowingButton(following, bandId) { var $btnFollowBand = $('div[band-id=' + bandId + ']', '#profile-bands').find('#btn-follow-band-2'); $btnFollowBand.unbind("click"); if (following) { $btnFollowBand.text('UNFOLLOW'); $btnFollowBand.click(function (evt) { removeFollowing(true, bandId); evt.stopPropagation(); return false; }); } else { $btnFollowBand.text('FOLLOW'); $btnFollowBand.click(addBandFollowing); } } /****************** FAVORITES TAB *****************/ function renderFavorites() { $('#profile-about').hide(); $('#profile-history').hide(); $('#profile-bands').hide(); $('#profile-social').hide(); $('#profile-favorites').show(); $('.profile-nav a.active').removeClass('active'); $('.profile-nav a#profile-favorites-link').addClass('active'); bindFavorites(); } function bindFavorites() { } function initializeFeed() { var $scroller = profileScreen.find('.content-body-scroller'); var $content = profileScreen.find('.feed-content'); var $noMoreFeeds = $('#end-of-feeds-list'); var $refresh = profileScreen.find('.btn-refresh-entries'); var $sortFeedBy = profileScreen.find('#feed_order_by'); var $includeDate = profileScreen.find('#feed_date'); var $includeType = profileScreen.find('#feed_show'); feed = new context.JK.Feed(app); feed.initialize(profileScreen, $scroller, $content, $noMoreFeeds, $refresh, $sortFeedBy, $includeDate, $includeType); } function initialize(textMessageDialogInstance) { textMessageDialog = textMessageDialogInstance; var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow, 'beforeHide' : beforeHide }; app.bindScreen('profile', screenBindings); profileScreen = $('#user-profile'); events(); initializeFeed(); } this.initialize = initialize; this.beforeShow = beforeShow; this.afterShow = afterShow; return this; }; })(window, jQuery);