jam-cloud/web/app/assets/javascripts/profile.js

686 lines
25 KiB
JavaScript

(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 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;
}
function afterShow(data) {
initUser();
resetForm();
}
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) {
fetchUserNetworkOrServerFailure();
}
else if(jqXHR.status == 404) {
fetchUserGone();
}
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();
}
else {
configureFriendFollowersControls();
$('#btn-profile-edit').hide();
$('#btn-add-friend').show();
$('#btn-follow-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);
}
function handleFriendChange(evt) {
if(isFriend()) {
removeFriend(evt);
}
else {
sendFriendRequest(evt);
}
}
function handleFollowingChange(evt) {
if (isFollowing()) {
removeFollowing(false, userId);
}
else {
addFollowing();
}
}
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;
context.JK.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('REMOVE FRIEND');
}
else {
$('#btn-add-friend').text('ADD FRIEND');
}
}
function addFollowing() {
rest.addFollowing({user_id: userId})
.done(function() {
updateFollowingCount(1);
setFollowing(true);
configureFollowingButton();
})
.fail(app.ajaxError);
}
function removeFollowing(isBand, id) {
var following = {};
if (!isBand) {
following.user_id = id;
}
else {
following.band_id = id;
}
rest.removeFollowing(following)
.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('STOP FOLLOWING');
}
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.getInstrumentIcon45(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('<span class="friend-count">' + user.friend_count + '</span>' + text);
text = user.follower_count > 1 || user.follower_count === 0 ? " Followers" : " Follower";
$('#profile-follower-stats').html('<span class="follower-count">' + user.follower_count + '</span>' + 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);
}
$('#profile-biography').html(user.biography);
}
/****************** 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');
/*if (isMusician()) {
$('.profile-social-left').show();
} else {
$('.profile-social-left').hide();
}*/
bindSocial();
}
function bindSocial() {
if (isMusician()) {
// FRIENDS
rest.getFriends({id:userId})
.done(function(response) {
$.each(response, function(index, val) {
var template = $('#template-profile-social').html();
var friendHtml = context.JK.fillTemplate(template, {
avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
userName: val.name,
location: val.location,
type: "Friends"
});
$('#profile-social-friends').append(friendHtml);
});
})
.fail(app.ajaxError)
}
rest.getFollowings({id: userId})
.done(function(response) {
$.each(response, function(index, val) {
var template = $('#template-profile-social').html();
var followingHtml = context.JK.fillTemplate(template, {
avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
userName: val.name,
location: val.location
});
$('#profile-social-followings').append(followingHtml);
});
})
.fail(app.ajaxError);
rest.getBandFollowings({id: userId})
.done(function(response) {
$.each(response, function(index, val) {
var template = $('#template-profile-social').html();
var followingHtml = context.JK.fillTemplate(template, {
avatar_url: context.JK.resolveBandAvatarUrl(val.logo_url),
userName: val.name,
location: val.location
});
$('#profile-social-followings').append(followingHtml);
});
})
.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, {
avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
userName: val.name,
location: val.location
});
$('#profile-social-followers').append(followerHtml);
});
})
.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() {
}
/****************** 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];
}
instrumentLogoHtml += '<img src="' + inst + '" width="24" height="24" />&nbsp;';
}
}
// this template is in _findSession.html.erb
var musicianTemplate = $('#template-musician-info').html();
musicianHtml += context.JK.fillTemplate(musicianTemplate, {
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.logo_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
// XXX; we should return if you are following the band in the rabl, so we don't
// have to hit the server per band shown
rest.getBandFollowing({band_id: val.id})
.done(function(response) {
var alreadyFollowing = response.id !== undefined;
configureBandFollowingButton(alreadyFollowing, val.id);
});
});
if(response.length >= 3) {
addMoreBandsLink();
}
}
})
.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().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);
})
.fail(app.ajaxError);
}
function configureBandFollowingButton(following, bandId) {
var $btnFollowBand = $('div[band-id=' + bandId + ']', '#profile-bands').find('#btn-follow-band');
$btnFollowBand.unbind("click");
if (following) {
$btnFollowBand.text('UN-FOLLOW');
$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 fetchUserGone() {
app.notify({
title: "User Deleted",
text: "The user you are looking for is gone",
icon_url: "/assets/content/icon_alert_big.png"
})
}
function fetchUserNetworkOrServerFailure() {
app.notify({
title: "Unable to communicate with server",
text: "Please try again later",
icon_url: "/assets/content/icon_alert_big.png"
})
}
function bindFavorites() {
}
function initialize() {
var screenBindings = {
'beforeShow': beforeShow,
'afterShow': afterShow
};
app.bindScreen('profile', screenBindings);
events();
}
this.initialize = initialize;
this.beforeShow = beforeShow;
this.afterShow = afterShow;
return this;
};
})(window,jQuery);