VRFS-1669 find session wip

This commit is contained in:
Brian Smith 2014-06-21 16:16:39 -04:00
parent 6aa51e43b9
commit bc47a0a599
15 changed files with 126 additions and 412 deletions

View File

@ -13,7 +13,6 @@ module JamRuby
attr_accessor :legal_terms, :language_description, :scheduled_start_time, :access_description
attr_accessor :approved_rsvps, :open_slots, :pending_invitations
attr_accessor :approved_rsvps_detail, :open_slots_detail
self.table_name = "music_sessions"
@ -463,37 +462,6 @@ module JamRuby
# retrieve users that have approved RSVPs
def approved_rsvps
users = User.find_by_sql(%Q{select u.id, u.photo_url, u.first_name, u.last_name, rs.instrument_id
from rsvp_slots rs
inner join rsvp_requests_rsvp_slots rrrs on rrrs.rsvp_slot_id = rs.id
inner join rsvp_requests rr on rrrs.rsvp_request_id = rr.id
inner join users u on u.id = rr.user_id
where rrrs.chosen = true and rs.music_session_id = '#{self.id}'
order by u.id}
)
users_collapsed_instruments = []
user = User.new
# build User array with instruments collapsed
users.each_with_index do |u, index|
if index == 0 || users[index].id != users[index-1].id
user = User.new
user.id = u.id
user.photo_url = u.photo_url
user.first_name = u.first_name
user.last_name = u.last_name
user.instrument_list = [u.instrument_id]
users_collapsed_instruments << user
else
user.instrument_list << u.instrument_id
end
end
users_collapsed_instruments
end
def approved_rsvps_detail
users = User.find_by_sql(%Q{select u.id, u.photo_url, u.first_name, u.last_name, rs.instrument_id, ii.description, rs.proficiency_level
from rsvp_slots rs
inner join rsvp_requests_rsvp_slots rrrs on rrrs.rsvp_slot_id = rs.id
@ -528,20 +496,6 @@ module JamRuby
# get all slots for this session and perform a set difference with all chosen slots;
# this will return those that are not filled yet
def open_slots
RsvpSlot.find_by_sql(%Q{select rs.*
from rsvp_slots rs
where rs.music_session_id = '#{self.id}'
except
select distinct rs.*
from rsvp_slots rs
inner join rsvp_requests_rsvp_slots rrrs on rrrs.rsvp_slot_id = rs.id
where rs.music_session_id = '#{self.id}'
and rrrs.chosen = true
}
)
end
def open_slots_detail
RsvpSlot.find_by_sql(%Q{select rs.*, ii.description
from rsvp_slots rs
inner join instruments ii on ii.id = rs.instrument_id

View File

@ -13,11 +13,6 @@
var logger = context.JK.logger;
var rest = context.JK.Rest();
var sessionLatency;
var sessions = {};
var activeSessionGroup = {};
var scheduledSessionGroup = {};
var sessionCounts = [0, 0];
var sessionList;
var currentQuery = defaultQuery();
var currentPage = 0;
@ -26,7 +21,6 @@
var $scroller = null;
var $noMoreSessions = null;
function defaultQuery() {
return {offset:currentPage * LIMIT, limit:LIMIT, page:currentPage};
}
@ -35,52 +29,47 @@
return CATEGORY;
}
function removeSpinner() {
function removeSpinner($selector) {
$('div[layout-id=findSession] .content .spinner').remove();// remove any existing spinners
}
function addSpinner() {
function addSpinner($selector) {
removeSpinner();
$('div[layout-id=findSession] .content').append('<div class="spinner spinner-large"></div>')
$selector.append('<div class="spinner spinner-large"></div>')
}
function loadSessionsOriginal() {
addSpinner();
function loadSessions() {
addSpinner($('#sessions-active'));
addSpinner($('#sessions-scheduled'));
// get active sessions
rest.findActiveSessions(currentQuery)
.done(afterLoadSessions)
.fail(app.ajaxError)
.always(removeSpinner)
.done(function(sessions) {
$.each(sessions, function(i, session) {
renderSession(session, $(CATEGORY.ACTIVE.id));
});
afterLoadSessions(sessions, $('#no-active-sessions'));
})
.fail(app.ajaxError)
.always(function() {
removeSpinner($('#sessions-active'));
})
// get scheduled sessions
rest.findInactiveSessions(currentQuery)
.done(afterLoadSessions)
.done(function(sessions) {
$.each(sessions, function(i, session) {
renderSession(session, $(CATEGORY.SCHEDULED.id));
});
afterLoadSessions(sessions, $('#no-scheduled-sessions'));
})
.fail(app.ajaxError)
.always(removeSpinner)
.always(function() {
removeSpinner($('#sessions-scheduled'));
})
}
// 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();
@ -103,216 +92,26 @@
logger.debug("Searching for sessions...");
clearResults();
buildQuery();
refreshDisplay();
loadSessions();
}
function refreshDisplay() {
var priorVisible;
var ACTIVE = 'div#sessions-active';
var SCHEDULED = 'div#sessions-scheduled';
// ACTIVE
//logger.debug("sessionCounts[CATEGORY.ACTIVE.index]=" + sessionCounts[CATEGORY.ACTIVE.index]);
if (sessionCounts[CATEGORY.ACTIVE.index] === 0) {
priorVisible = false;
$(ACTIVE).hide();
}
else {
priorVisible = true;
$(ACTIVE).show();
}
// FRIEND
if (!priorVisible) {
$(SCHEDULED).removeClass('mt35');
}
//logger.debug("sessionCounts[CATEGORY.SCHEDULED.index]=" + sessionCounts[CATEGORY.SCHEDULED.index]);
if (sessionCounts[CATEGORY.SCHEDULED.index] === 0) {
priorVisible = false;
$(SCHEDULED).hide();
}
else {
priorVisible = true;
$(SCHEDULED).show();
}
}
function afterLoadScoredSessions(sessionList) {
function afterLoadSessions(sessionList, $selector) {
// 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();
$selector.show();
}
else {
$noSessionsFound.hide();
$selector.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];
activeSessionGroup[sessionId] = session;
sessionCounts[CATEGORY.ACTIVE.index]++;
scheduledSessionGroup[sessionId] = session;
sessionCounts[CATEGORY.SCHEDULED.index]++;
// hack to prevent duplicate rows from being rendered when filtering
var sessionAlreadyRendered = false;
var $tbGroup;
function renderSession(session, $group) {
var sessionId = session.id;
logger.debug('Rendering session ID = ' + sessionId);
if (activeSessionGroup[sessionId] != null) {
$tbGroup = $(CATEGORY.ACTIVE.id);
if ($("table#sessions-active tr[id='" + sessionId + "']").length > 0) {
sessionAlreadyRendered = true;
}
}
else if (scheduledSessionGroup[sessionId] != null) {
;
$tbGroup = $(CATEGORY.SCHEDULED.id);
if ($("table#sessions-scheduled 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();
sessionList.renderSession(session, sessionLatency, $group, $('#template-session-row').html(), $('#template-musician-info').html());
}
function beforeShow(data) {
@ -328,7 +127,6 @@
clearResults();
buildQuery();
refreshDisplay();
loadSessions();
context.JK.guardAgainstBrowser(app);
}
@ -339,73 +137,57 @@
$scroller.infinitescroll('resume');
$('table#sessions-active').children(':not(:first-child)').remove();
$('table#sessions-scheduled').children(':not(:first-child)').remove();
sessionCounts = [0, 0];
sessions = {};
activeSessionGroup = {};
scheduledSessionGroup = {};
}
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 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() {
// function registerInfiniteScroll() {
if(gon.use_cached_session_scores) {
// if(gon.use_cached_session_scores) {
$scroller.infinitescroll({
// $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);
});
}
}
// 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() {
@ -421,14 +203,9 @@
});
$('#btn-refresh').on("click", search);
tempDebugStuff();
}
/**
* Initialize, providing an instance of the SessionLatency class.
*/
function initialize(latency) {
function initialize() {
var screenBindings = {
'beforeShow': beforeShow,
@ -436,13 +213,6 @@
};
app.bindScreen('findSession', screenBindings);
if (latency) {
sessionLatency = latency;
}
else {
logger.warn("No sessionLatency provided.");
}
sessionList = new context.JK.SessionList(app);
$next = $('#findSession .btn-next')

View File

@ -38,7 +38,7 @@
function render(parentSelector) {
$('select', parentSelector).empty();
$('select', parentSelector).append('<option value="">Select Genre</option>');
$('select', parentSelector).append('<option value="">Any Genre</option>');
var template = $('#template-genre-option').html();
$.each(_genres, function(index, value) {
// value will be a dictionary entry from _genres:

View File

@ -111,13 +111,6 @@
});
}
function findSessions(query) {
return $.ajax({
type: "GET",
url: "/api/sessions?" + $.param(query)
});
}
function findActiveSessions(query) {
return $.ajax({
type: "GET",
@ -139,13 +132,6 @@
});
}
function findScoredSessions(clientId, query) {
return $.ajax({
type: "GET",
url: "/api/sessions/nindex/" + clientId + "?" + $.param(query)
});
}
function updateSession(id, newSession) {
return $.ajax('/api/sessions/' + id, {
type: "PUT",
@ -1192,9 +1178,9 @@
this.getFollowers = getFollowers;
this.getBands = getBands;
this.getBandFollowers = getBandFollowers;
this.findSessions = findSessions;
this.findActiveSessions = findActiveSessions;
this.findInactiveSessions = findInactiveSessions;
this.findScheduledSessions = findScheduledSessions;
this.findScoredSessions = findScoredSessions;
this.updateSession = updateSession;
this.getSessionHistory = getSessionHistory;
this.addSessionComment = addSessionComment;

View File

@ -234,9 +234,9 @@
if (createSessionSettings.createType == 'start-scheduled') {
var session = scheduledSessions[createSessionSettings.selectedSessionId];
if (session.approved_rsvps_detail.length > 0) {
if (session.approved_rsvps.length > 0) {
var instruments_me = [];
$.each(session.approved_rsvps_detail, function(index, user) {
$.each(session.approved_rsvps, function(index, user) {
if (user.id == context.JK.currentUserId) {
$.each(user.instrument_list, function(index, instrument) {
instruments_me.push(instrument.desc);
@ -246,9 +246,9 @@
$('#session-instruments-me-disp').html(instruments_me.join(', '));
}
if (session.open_slots_detail.length > 0) {
if (session.open_slots.length > 0) {
var instruments_rsvp = {};
$.each(session.open_slots_detail, function(index, slot) {
$.each(session.open_slots, function(index, slot) {
if (instruments_rsvp[slot.description]) {
instruments_rsvp[slot.description]["count"] = instruments_rsvp[slot.description]["count"] + 1;
}

View File

@ -27,7 +27,7 @@
* It will be inserted at the appropriate place according to the
* sortScore in sessionLatency.
*/
function renderSession(session, sessionLatency, tbGroup, rowTemplate, musicianTemplate) {
function renderSession(session, tbGroup, rowTemplate, musicianTemplate) {
// latency
var latencyInfo = sessionLatency.sessionInfo(session.id);
var latencyDescription = "";

View File

@ -79,7 +79,7 @@
});
// retrieve RSVP requests for this user
// retrieve RSVP requests for this user to determine which CTA to display
rest.getRsvpRequests(musicSessionId)
.done(function(rsvps) {
if (rsvps && rsvps.length > 0) {

View File

@ -67,9 +67,7 @@ class ApiMusicSessionsController < ApiController
# tag is 1 for chosen rsvp'd sessions, 2 for invited sessions, 3 for all others (musician_access).
# TODO: if you're the creator of a session it will be treated the same as if you had rsvp'd and been accepted.
ActiveRecord::Base.transaction do
ActiveRecord::Base.transaction do
@music_sessions, @user_scores = ActiveMusicSession.ams_index(current_user, params)
end
@music_sessions, @user_scores = ActiveMusicSession.ams_index(current_user, params)
end
end

View File

@ -65,7 +65,7 @@ else
child(:music_notations => :music_notations) {
node do |music_notation|
attributes :id
attributes :id, :file_name, :file_url
# note(:filename) { |music_notation| music_notation.filename }
end
}
@ -86,16 +86,8 @@ else
end
}
child({:approved_rsvps_detail => :approved_rsvps_detail}) {
attributes :id, :photo_url, :first_name, :last_name, :instrument_list
}
child({:open_slots_detail => :open_slots_detail}) {
attributes :id, :instrument_id, :proficiency_level, :proficiency_desc, :description
}
child({:open_slots => :open_slots}) {
attributes :id, :instrument_id, :proficiency_level, :proficiency_desc
attributes :id, :instrument_id, :proficiency_level, :proficiency_desc, :description
}
child({:pending_invitations => :pending_invitations}) {

View File

@ -22,17 +22,26 @@
<%= render "genreSelector" %>
</div>
<div class="right ib w85 h40">
<input type="text" id="session-date-filter">
<!-- date filter -->
<div class="search-box" style="height:25px;">
<input type="text" id="session-date-filter" placeholder="Any Date" />
</div>
<!-- language filter -->
<div class="search-box" style="height:25px;">
<select id="session-language-filter">
<% music_session_languages.each do |language| %>
<option value="<%= language[:id] %>"><%= language[:label] %></option>
<% end %>
</select>
</div>
<!-- keyword filter -->
<div class="search-box" style="height:25px;">
<input id="session-keyword-srch" type="text" name="search" placeholder="Search by Keyword" />
</div>
<div class="right mr10">
<!-- can be removed once new find session is stable-->
<a id="btn-refresh-other" href="/client#/findSession" style="display:none;text-decoration:none;" class="button-grey">REFRESH<span class="extra"></span></a>
<a id="btn-refresh" href="/client#/findSession" style="text-decoration:none;" class="button-grey">REFRESH<span class="extra"></span></a>
</div>
</div>
@ -40,20 +49,24 @@
<div class="content-scroller">
<div class="content-wrapper" style="padding-left:35px;padding-top:10px;">
<div id="sessions-active">
<%= render :partial => "sessionList", :locals => {:title => "current, active sessions", :category => "sessions-active"} %>
<%= render :partial => "sessionList", :locals => {:title => "current, active sessions", :category => "sessions-active"} %>
<br />
<div id="no-active-sessions">
No active public sessions found.
</div>
</div>
<div id="sessions-friends" class="mt35">
<%= render :partial => "sessionList", :locals => {:title => "future, scheduled sessions", :category => "sessions-scheduled"} %>
<%= render :partial => "sessionList", :locals => {:title => "future, scheduled sessions", :category => "sessions-scheduled"} %>
<br />
<div id="no-scheduled-sessions">
No scheduled sessions found.
</div>
</div>
<span class="btn-next-wrapper"><a href="/api/sessions/nindex/clientid?page=1" class="btn-next">Next</a></span>
</div>
</div>
</form>
<div id="sessions-none-found">
There are currently no public sessions.
</div>
<div id="end-of-session-list" class="end-of-list">
No more sessions.
</div>
@ -65,7 +78,7 @@
<!-- Session Row Template -->
<script type="text/template" id="template-session-row">
<tr id="{id}" class="found-session" data-sortScore="{sortScore}">
<td width="100">{genres}</td>
<td width="75">{genres}</td>
<td width="25%">{description}</td>
<td width="20%">
<!-- sub-table of musicians -->

View File

@ -1,3 +1,3 @@
<select class="genre-list easydropdown" name="genres">
<option value="">Select Genre</option>
<option value="">Any Genre</option>
</select>

View File

@ -122,7 +122,7 @@
<div class="left ib w15 h40">Date:</div>
<div class="right ib w85 h40">
<input type="text" id="session-start-date">
<input type="text" id="session-start-date" />
</div>
<div class="clearall left ib w15 h40">Start:</div>

View File

@ -2,7 +2,7 @@
<table id="<%= category %>" class="findsession-table" cellspacing="0" cellpadding="0" border="0">
<!-- header -->
<tr>
<th align="left" width="100">SESSION</th>
<th align="left" width="75">SESSION</th>
<th align="left" width="20%">MUSICIANS</th>
<th width="60" style="text-align:center">LATENCY</th>
<th align="left" width="15%">POLICIES</th>

View File

@ -232,11 +232,12 @@
feedScreen.initialize();
var findSessionScreen = new JK.FindSessionScreen(JK.app);
var sessionLatency = null;
if ("jamClient" in window) {
sessionLatency = new JK.SessionLatency(window.jamClient);
}
findSessionScreen.initialize(sessionLatency);
findSessionScreen.initialize();
// var sessionLatency = null;
// if ("jamClient" in window) {
// sessionLatency = new JK.SessionLatency(window.jamClient);
// }
// findSessionScreen.initialize(sessionLatency);
var findMusicianScreen = new JK.FindMusicianScreen(JK.app);
findMusicianScreen.initialize(textMessageDialog);

View File

@ -83,7 +83,7 @@
= rsvp.name
.left.ml10
- rsvp.instrument_list.each do |i|
%img.instrument-icon{'instrument-id' => i, height:24, width:24}
%img.instrument-icon{'instrument-id' => i[:id], height:24, width:24}
%br{:clear => "all"}/
%br/