(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('
') } 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: $('
Loading ...
'), 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);