From 000dd3fdd065fde4e7422e7fb41e06580fe06cb7 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Sun, 9 Mar 2014 18:04:56 +0000 Subject: [PATCH] * VRFS-1253 - working in a basic sense with pagination --- web/app/assets/images/shared/spinner-32.gif | Bin 0 -> 4410 bytes web/app/assets/javascripts/application.js | 2 + web/app/assets/javascripts/findSession.js | 852 ++++++++++-------- web/app/assets/javascripts/jam_rest.js | 8 +- web/app/assets/javascripts/sessionList.js | 2 +- .../stylesheets/client/findSession.css.scss | 77 +- .../stylesheets/client/jamkazam.css.scss | 8 + web/app/controllers/clients_controller.rb | 1 + web/app/views/clients/_findSession.html.erb | 14 +- web/app/views/clients/index.html.erb | 2 + web/config/application.rb | 7 +- web/config/environments/development.rb | 7 +- web/config/environments/test.rb | 2 +- web/config/initializers/dev_users.rb | 3 - web/spec/features/find_sessions_spec.rb | 50 +- .../javascripts/jquery.infinitescroll.js | 814 +++++++++++++++++ 16 files changed, 1418 insertions(+), 431 deletions(-) create mode 100644 web/app/assets/images/shared/spinner-32.gif create mode 100644 web/vendor/assets/javascripts/jquery.infinitescroll.js diff --git a/web/app/assets/images/shared/spinner-32.gif b/web/app/assets/images/shared/spinner-32.gif new file mode 100644 index 0000000000000000000000000000000000000000..bd39fb1a9a1f5d890faaa938388b371777d37438 GIT binary patch literal 4410 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 literal 0 HcmV?d00001 diff --git a/web/app/assets/javascripts/application.js b/web/app/assets/javascripts/application.js index e180fa24f..e96b3b6fe 100644 --- a/web/app/assets/javascripts/application.js +++ b/web/app/assets/javascripts/application.js @@ -24,6 +24,8 @@ //= require jquery.clipboard //= require jquery.timeago //= require jquery.easydropdown +//= require jquery.scrollTo +//= require jquery.infinitescroll //= require globals //= require AAB_message_factory //= require AAC_underscore diff --git a/web/app/assets/javascripts/findSession.js b/web/app/assets/javascripts/findSession.js index 24868b217..31421dfcd 100644 --- a/web/app/assets/javascripts/findSession.js +++ b/web/app/assets/javascripts/findSession.js @@ -1,377 +1,483 @@ -(function(context,$) { +(function (context, $) { - "use strict"; + "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; - - // for unit tests - function getCategoryEnum() { - return CATEGORY; - } - - function removeSpinner() { - $('') - - } - - function loadSessions(queryString) { - - addSpinner(); - - // squelch nulls and undefines - queryString = !!queryString ? queryString : ""; - - if(gon.use_cached_session_scores) { - rest.findScoredSessions(app.clientId, queryString) - .done(afterLoadScoredSessions) - .always(removeSpinner) - .fail(app.ajaxError) - } - else { - rest.findSessions(queryString) - .done(afterLoadSessions) - .fail(app.ajaxError) - .always(removeSpinner) - } - - } - - function search() { - logger.debug("Searching for sessions..."); - clearResults(); - var queryString = ''; - - // genre filter - var genres = context.JK.GenreSelectorHelper.getSelectedGenres('#find-session-genre'); - if (genres !== null && genres.length > 0) { - queryString += "genres=" + genres.join(','); - } - - // keyword filter - var keyword = $('#session-keyword-srch').val(); - if (keyword !== null && keyword.length > 0 && keyword !== 'Search by Keyword') { - if (queryString.length > 0) { - queryString += "&"; - } - - queryString += "keyword=" + $('#session-keyword-srch').val(); - } - - loadSessions(queryString); - } - - 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(sessionList.length == 0) { - $noSessionsFound.show(); - } - else { - $noSessionsFound.hide(); - } - - $.each(sessionList, function(i, session) { - sessions[session.id] = session; - session.latencyInfo - }); - - $.each(sessionList, function(i, session) { - renderSession(session.id); - }) - - 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) { - clearResults(); - refreshDisplay(); - loadSessions(); - } - - function clearResults() { - $('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 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); - } - - /** - * 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); - - 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; + 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"} }; - })(window,jQuery); \ No newline at end of file + 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() { + $('') + } + + 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) { + clearResults(); + buildQuery(); + refreshDisplay(); + loadSessions(); + } + + 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); \ No newline at end of file diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js index ce4bc3939..79b0c7fca 100644 --- a/web/app/assets/javascripts/jam_rest.js +++ b/web/app/assets/javascripts/jam_rest.js @@ -34,17 +34,17 @@ }); } - function findSessions(queryString) { + function findSessions(query) { return $.ajax({ type: "GET", - url: "/api/sessions?" + queryString + url: "/api/sessions?" + $.param(query) }); } - function findScoredSessions(clientId, queryString) { + function findScoredSessions(clientId, query) { return $.ajax({ type: "GET", - url: "/api/sessions/nindex/" + clientId + "?" + queryString + url: "/api/sessions/nindex/" + clientId + "?" + $.param(query) }); } diff --git a/web/app/assets/javascripts/sessionList.js b/web/app/assets/javascripts/sessionList.js index a282710e5..cc857545a 100644 --- a/web/app/assets/javascripts/sessionList.js +++ b/web/app/assets/javascripts/sessionList.js @@ -61,7 +61,7 @@ else { latencyDescription = LATENCY.POOR.description; latencyStyle = LATENCY.POOR.style; - showJoinLink = false; + //showJoinLink = false; } } diff --git a/web/app/assets/stylesheets/client/findSession.css.scss b/web/app/assets/stylesheets/client/findSession.css.scss index 396923544..5c4e47c0c 100644 --- a/web/app/assets/stylesheets/client/findSession.css.scss +++ b/web/app/assets/stylesheets/client/findSession.css.scss @@ -1,4 +1,4 @@ -div[layout-id="findSession"] { +#findSession { th, td { margin: 4px; padding:4px; } @@ -11,36 +11,53 @@ div[layout-id="findSession"] { bottom: 0; right: 0; } -} -.session-filter { - width:100%; - padding-top: 11px; - padding-bottom: 11px; - background-color:#4c4c4c; - min-height:20px; - overflow-x:visible; - vertical-align:middle; -} + .content-body-scroller { + overflow:auto !important; + } -.session-filter select { - background-color:#c5c5c5; - border:none; - -webkit-box-shadow: inset 2px 2px 3px 0px #888; - box-shadow: inset 2px 2px 3px 0px #888; - color:#666; -} + .session-filter { + width:100%; + padding-top: 11px; + padding-bottom: 11px; + background-color:#4c4c4c; + min-height:20px; + overflow-x:visible; + vertical-align:middle; + } -#sessions-none-found { - color:#CCCCCC; - display:none; - overflow: none; - margin: auto; - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - text-align:center; - height:20px; + .session-filter select { + background-color:#c5c5c5; + border:none; + -webkit-box-shadow: inset 2px 2px 3px 0px #888; + box-shadow: inset 2px 2px 3px 0px #888; + color:#666; + } + + #sessions-none-found { + color:#CCCCCC; + display:none; + overflow: none; + margin: auto; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + text-align:center; + height:20px; + } + + #end-of-session-list { + display:none; + overflow: visibility; + margin:40px auto 10px; + width:100%; + height:20px; + text-align:center; + } + + .btn-next { + display:none; + } } \ No newline at end of file diff --git a/web/app/assets/stylesheets/client/jamkazam.css.scss b/web/app/assets/stylesheets/client/jamkazam.css.scss index dad78e959..1eadb6116 100644 --- a/web/app/assets/stylesheets/client/jamkazam.css.scss +++ b/web/app/assets/stylesheets/client/jamkazam.css.scss @@ -485,6 +485,14 @@ input[type="text"], input[type="password"]{ background-size: 50% 50%; } +.infinite-scroll-loader { + position:absolute; + overflow:hidden; + height:14px; + text-align: center; + margin:auto; + width:100%; +} // disable text selection for the in-session panel, ftue, and arbitrary elements marked with .no-selection-range div[layout-id=session], div[layout-id=ftue], .no-selection-range { diff --git a/web/app/controllers/clients_controller.rb b/web/app/controllers/clients_controller.rb index debfda761..c186e0f64 100644 --- a/web/app/controllers/clients_controller.rb +++ b/web/app/controllers/clients_controller.rb @@ -26,6 +26,7 @@ class ClientsController < ApplicationController gon.isNativeClient = @nativeClient gon.use_cached_session_scores = Rails.application.config.use_cached_session_scores + gon.allow_both_find_algos = Rails.application.config.allow_both_find_algos if current_user render :layout => 'client' diff --git a/web/app/views/clients/_findSession.html.erb b/web/app/views/clients/_findSession.html.erb index 2765fa7a2..c3d48139c 100644 --- a/web/app/views/clients/_findSession.html.erb +++ b/web/app/views/clients/_findSession.html.erb @@ -1,5 +1,5 @@ -
+
@@ -27,7 +27,9 @@
@@ -42,14 +44,18 @@
<%= render :partial => "sessionList", :locals => {:title => "other sessions", :category => "sessions-other"} %>
+ Next
-
There are currently no public sessions.
+ +
+ No more sessions. +
@@ -57,7 +63,7 @@