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

490 lines
13 KiB
JavaScript

(function (context, $) {
"use strict";
context.JK = context.JK || {};
context.JK.FindSessionScreen = function (app) {
var CATEGORY = {
INVITATION: {index: 0, id: "table#sessions-invitations"},
FRIEND: {index: 1, id: "table#sessions-friends"},
OTHER: {index: 2, id: "table#sessions-other"}
};
var logger = context.JK.logger;
var rest = context.JK.Rest();
var sessionLatency;
var sessions = {};
var invitationSessionGroup = {};
var friendSessionGroup = {};
var otherSessionGroup = {};
var sessionCounts = [0, 0, 0];
var sessionList;
var currentQuery = defaultQuery();
var currentPage = 0;
var LIMIT = 20;
var $next = null;
var $scroller = null;
var $noMoreSessions = null;
function defaultQuery() {
return {offset:currentPage * LIMIT, limit:LIMIT, page:currentPage};
}
// for unit tests
function getCategoryEnum() {
return CATEGORY;
}
function removeSpinner() {
$('div[layout-id=findSession] .content .spinner').remove();// remove any existing spinners
}
function addSpinner() {
removeSpinner();
$('div[layout-id=findSession] .content').append('<div class="spinner spinner-large"></div>')
}
function loadSessionsOriginal() {
addSpinner();
rest.findSessions(currentQuery)
.done(afterLoadSessions)
.fail(app.ajaxError)
.always(removeSpinner)
}
function loadSessionsNew() {
addSpinner();
rest.findScoredSessions(app.clientId, currentQuery)
.done(function(response) { afterLoadScoredSessions(response); })
.always(function(){ removeSpinner(); })
.fail(app.ajaxError)
}
function loadSessions() {
if (gon.use_cached_session_scores) {
loadSessionsNew();
}
else {
loadSessionsOriginal();
}
}
function buildQuery() {
currentQuery = defaultQuery();
// genre filter
var genres = context.JK.GenreSelectorHelper.getSelectedGenres('#find-session-genre');
if (genres !== null && genres.length > 0) {
currentQuery.genres = genres.join(',');
}
// keyword filter
var keyword = $('#session-keyword-srch').val();
if (keyword !== null && keyword.length > 0 && keyword !== 'Search by Keyword') {
currentQuery.keyword = $('#session-keyword-srch').val();
}
return currentQuery;
}
function search() {
logger.debug("Searching for sessions...");
clearResults();
buildQuery();
refreshDisplay();
loadSessions();
}
function refreshDisplay() {
var priorVisible;
var INVITATION = 'div#sessions-invitations';
var FRIEND = 'div#sessions-friends';
var OTHER = 'div#sessions-other';
// INVITATION
//logger.debug("sessionCounts[CATEGORY.INVITATION.index]=" + sessionCounts[CATEGORY.INVITATION.index]);
if (sessionCounts[CATEGORY.INVITATION.index] === 0) {
priorVisible = false;
$(INVITATION).hide();
}
else {
priorVisible = true;
$(INVITATION).show();
}
// FRIEND
if (!priorVisible) {
$(FRIEND).removeClass('mt35');
}
//logger.debug("sessionCounts[CATEGORY.FRIEND.index]=" + sessionCounts[CATEGORY.FRIEND.index]);
if (sessionCounts[CATEGORY.FRIEND.index] === 0) {
priorVisible = false;
$(FRIEND).hide();
}
else {
priorVisible = true;
$(FRIEND).show();
}
// OTHER
if (!priorVisible) {
$(OTHER).removeClass('mt35');
}
//logger.debug("sessionCounts[CATEGORY.OTHER.index]=" + sessionCounts[CATEGORY.OTHER.index]);
if (sessionCounts[CATEGORY.OTHER.index] === 0) {
$(OTHER).hide();
}
else {
$(OTHER).show();
}
}
function afterLoadScoredSessions(sessionList) {
// display the 'no sessions' banner if appropriate
var $noSessionsFound = $('#sessions-none-found');
if (currentPage == 0 && sessionList.length == 0) {
$noSessionsFound.show();
}
else {
$noSessionsFound.hide();
}
// update pager so infinitescroll can do it's thing
//$next.attr('href', '/api/sessions/nindex/' + app.clientId + '?' + $.param(currentQuery))
/**
// XXX
if(sessionList.length > 0) {
for(var i = 0; i < 20; i++) {
var copied = $.extend(true, {}, sessionList[0]);
copied.id = 'session_' + i;
sessionList.push(copied);
}
}
*/
$.each(sessionList, function (i, session) {
sessions[session.id] = session;
});
$.each(sessionList, function (i, session) {
renderSession(session.id);
});
if(sessionList.length < LIMIT) {
// if we less results than asked for, end searching
$scroller.infinitescroll('pause');
if(currentPage > 0) {
$noMoreSessions.show();
}
}else {
currentPage++;
buildQuery();
registerInfiniteScroll();
}
context.JK.GA.trackFindSessions(sessionList.length);
}
function afterLoadSessions(sessionList) {
// display the 'no sessions' banner if appropriate
var $noSessionsFound = $('#sessions-none-found');
if (sessionList.length == 0) {
$noSessionsFound.show();
}
else {
$noSessionsFound.hide();
}
startSessionLatencyChecks(sessionList);
context.JK.GA.trackFindSessions(sessionList.length);
}
function startSessionLatencyChecks(sessionList) {
logger.debug("Starting latency checks on " + sessionList.length + " sessions");
sessionLatency.subscribe(app.clientId, latencyResponse);
$.each(sessionList, function (index, session) {
sessions[session.id] = session;
sessionLatency.sessionPings(session);
});
}
function containsInvitation(session) {
var i, invitation = null;
if (session !== undefined) {
if ("invitations" in session) {
// user has invitations for this session
for (i = 0; i < session.invitations.length; i++) {
invitation = session.invitations[i];
// session contains an invitation for this user
if (invitation.receiver_id == context.JK.currentUserId) {
return true;
}
}
}
}
return false;
}
function containsFriend(session) {
var i, participant = null;
if (session !== undefined) {
if ("participants" in session) {
for (i = 0; i < session.participants.length; i++) {
participant = session.participants[i];
// this session participant is a friend
if (participant !== null && participant !== undefined && participant.user.is_friend) {
return true;
}
}
}
}
return false;
}
function latencyResponse(sessionId) {
logger.debug("Received latency response for session " + sessionId);
renderSession(sessionId);
}
/**
* Not used normally. Allows modular unit testing
* of the renderSession method without having to do
* as much heavy setup.
*/
function setSession(session) {
invitationSessionGroup[session.id] = session;
}
/**
* Render a single session line into the table.
* It will be inserted at the appropriate place according to the
* sortScore in sessionLatency.
*/
function renderSession(sessionId) {
// store session in the appropriate bucket and increment category counts
var session = sessions[sessionId];
if (containsInvitation(session)) {
invitationSessionGroup[sessionId] = session;
sessionCounts[CATEGORY.INVITATION.index]++;
}
else if (containsFriend(session)) {
friendSessionGroup[sessionId] = session;
sessionCounts[CATEGORY.FRIEND.index]++;
}
else {
otherSessionGroup[sessionId] = session;
sessionCounts[CATEGORY.OTHER.index]++;
}
// hack to prevent duplicate rows from being rendered when filtering
var sessionAlreadyRendered = false;
var $tbGroup;
logger.debug('Rendering session ID = ' + sessionId);
if (invitationSessionGroup[sessionId] != null) {
$tbGroup = $(CATEGORY.INVITATION.id);
if ($("table#sessions-invitations tr[id='" + sessionId + "']").length > 0) {
sessionAlreadyRendered = true;
}
}
else if (friendSessionGroup[sessionId] != null) {
;
$tbGroup = $(CATEGORY.FRIEND.id);
if ($("table#sessions-friends tr[id='" + sessionId + "']").length > 0) {
sessionAlreadyRendered = true;
}
}
else if (otherSessionGroup[sessionId] != null) {
$tbGroup = $(CATEGORY.OTHER.id);
if ($("table#sessions-other tr[id='" + sessionId + "']").length > 0) {
sessionAlreadyRendered = true;
}
}
else {
logger.debug('ERROR: No session with ID = ' + sessionId + ' found.');
return;
}
if (!sessionAlreadyRendered) {
var row = sessionList.renderSession(session, sessionLatency, $tbGroup, $('#template-session-row').html(), $('#template-musician-info').html());
}
refreshDisplay();
}
function beforeShow(data) {
context.JK.GenreSelectorHelper.render('#find-session-genre');
}
function afterShow(data) {
if(!context.JK.JamServer.connected) {
app.notifyAlert("Not Connected", 'To create or join a session, you must be connected to the server.');
window.location = '/client#/home'
return;
}
clearResults();
buildQuery();
refreshDisplay();
loadSessions();
context.JK.guardAgainstBrowser(app);
}
function clearResults() {
currentPage = 0;
$noMoreSessions.hide();
$scroller.infinitescroll('resume');
$('table#sessions-invitations').children(':not(:first-child)').remove();
$('table#sessions-friends').children(':not(:first-child)').remove();
$('table#sessions-other').children(':not(:first-child)').remove();
sessionCounts = [0, 0, 0];
sessions = {};
invitationSessionGroup = {};
friendSessionGroup = {};
otherSessionGroup = {};
}
function deleteSession(evt) {
var sessionId = $(evt.currentTarget).attr("action-id");
if (sessionId) {
$.ajax({
type: "DELETE",
url: "/api/sessions/" + sessionId,
error: app.ajaxError
}).done(loadSessions);
}
}
function tempDebugStuff() {
if (gon.allow_both_find_algos && context.JK.currentUserAdmin) {
// show extra Refresh button, and distinguish between them
$('#btn-refresh-other').show().click(function() {
clearResults();
buildQuery();
refreshDisplay();
if(gon.use_cached_session_scores) {
loadSessionsOriginal();
}
else {
loadSessionsNew();
}
});
$('#btn-refresh').find('.extra').text(gon.use_cached_session_scores ? ' (new way)' : ' (old way)')
$('#btn-refresh-other').find('.extra').text(gon.use_cached_session_scores ? ' (old way)' : ' (new way)')
}
}
function registerInfiniteScroll() {
if(gon.use_cached_session_scores) {
$scroller.infinitescroll({
behavior: 'local',
navSelector: '#findSession .btn-next-wrapper',
nextSelector: '#findSession .btn-next',
binder: $scroller,
dataType: 'json',
appendCallback: false,
debug: true,
prefill: false,
bufferPx:100,
loading: {
msg: $('<div class="infinite-scroll-loader">Loading ...</div>'),
img: '/assets/shared/spinner.gif'
},
path: function(page) {
return '/api/sessions/nindex/' + app.clientId + '?' + $.param(buildQuery());
}
},function(json, opts) {
// Get current page
//currentPage = opts.state.currPage;
// Do something with JSON data, create DOM elements, etc ..
afterLoadScoredSessions(json);
});
}
}
function events() {
$('#session-keyword-srch').focus(function () {
$(this).val('');
});
$("#session-keyword-srch").keypress(function (evt) {
if (evt.which === 13) {
evt.preventDefault();
search();
}
});
$('#btn-refresh').on("click", search);
tempDebugStuff();
}
/**
* Initialize, providing an instance of the SessionLatency class.
*/
function initialize(latency) {
var screenBindings = {
'beforeShow': beforeShow,
'afterShow': afterShow
};
app.bindScreen('findSession', screenBindings);
if (latency) {
sessionLatency = latency;
}
else {
logger.warn("No sessionLatency provided.");
}
sessionList = new context.JK.SessionList(app);
$next = $('#findSession .btn-next')
$scroller = $('#findSession .content-body-scroller');
$noMoreSessions = $('#end-of-session-list');
events();
}
this.initialize = initialize;
this.renderSession = renderSession;
this.afterShow = afterShow;
// Following exposed for easier testing.
this.setSession = setSession;
this.clearResults = clearResults;
this.getCategoryEnum = getCategoryEnum;
return this;
};
})(window, jQuery);