Merge branch 'develop' of bitbucket.org:jamkazam/jam-cloud into develop

This commit is contained in:
Seth Call 2014-01-22 16:23:46 -06:00
commit 35466433ca
22 changed files with 469 additions and 242 deletions

View File

@ -74,8 +74,9 @@ module JamRuby
PARAM_MUSICIAN = :srch_m
PARAM_BAND = :srch_b
PARAM_FEED = :srch_f
B_PER_PAGE = M_PER_PAGE = 10
F_PER_PAGE = B_PER_PAGE = M_PER_PAGE = 10
M_MILES_DEFAULT = 500
B_MILES_DEFAULT = 0
@ -87,6 +88,18 @@ module JamRuby
DISTANCE_OPTS = B_DISTANCE_OPTS = M_DISTANCE_OPTS = [['Any', 0], [1000.to_s, 1000], [500.to_s, 500], [250.to_s, 250], [100.to_s, 100], [50.to_s, 50], [25.to_s, 25]]
F_SORT_RECENT = ['Most Recent', :recent]
F_SORT_OLDEST = ['Ending Soonest', :ending_soon]
F_SORT_LENGTH = ['Session Length', :session_length]
F_SORT_OPTS = [F_SORT_RECENT, F_SORT_LENGTH, F_SORT_OLDEST]
SHOW_BOTH = ['Both', :both]
SHOW_SESSIONS = ['Sessions', :sessions]
SHOW_RECORDINGS = ['Recordings', :recordings]
SHOW_OPTS = [SHOW_BOTH, SHOW_SESSIONS, SHOW_RECORDINGS]
DATE_OPTS = [['Today', 0], ['This week', 7], ['Past 2 weeks', 14], ['This month', 30], ['Past year', 365], ['All', -1]]
def self.order_param(params, keys=M_ORDERING_KEYS)
ordering = params[:orderby]
ordering.blank? ? keys[0] : keys.detect { |oo| oo.to_s == ordering }

View File

@ -7,81 +7,19 @@
var logger = context.JK.logger;
var rest = context.JK.Rest();
var realtimeMessaging = context.JK.JamServer;
var friendSelectorDialog = null;
var invitationDialog = null;
var autoComplete = null;
var userNames = [];
var userIds = [];
var userPhotoUrls = [];
var inviteMusiciansUtil = null;
var MAX_GENRES = 1;
var selectedFriendIds = {};
var sessionSettings = {};
function beforeShow(data) {
userNames = [];
userIds = [];
userPhotoUrls = [];
inviteMusiciansUtil.clearSelections();
context.JK.GenreSelectorHelper.render('#create-session-genre');
resetForm();
}
function afterShow(data) {
friendSelectorDialog.setCallback(friendSelectorCallback);
var friends = rest.getFriends({ id: context.JK.currentUserId })
.done(function(friends) {
$.each(friends, function() {
userNames.push(this.name);
userIds.push(this.id);
userPhotoUrls.push(this.photo_url);
});
var autoCompleteOptions = {
lookup: { suggestions: userNames, data: userIds },
onSelect: addInvitation
};
$('#friend-input').attr("placeholder", "Type a friend\'s name").prop('disabled', false);
if (!autoComplete) {
autoComplete = $('#friend-input').autocomplete(autoCompleteOptions);
}
else {
autoComplete.setOptions(autoCompleteOptions);
}
$(".autocomplete").width("150px");
})
.fail(function() {
$('#friend-input').attr("placeholder", "Unable to lookup friends");
app.ajaxError(arguments);
});
}
function friendSelectorCallback(newSelections) {
var keys = Object.keys(newSelections);
for (var i=0; i < keys.length; i++) {
addInvitation(newSelections[keys[i]].userName, newSelections[keys[i]].userId);
}
}
function addInvitation(value, data) {
if ($('#selected-friends div[user-id=' + data + ']').length === 0) {
var template = $('#template-added-invitation').html();
var invitationHtml = context.JK.fillTemplate(template, {userId: data, userName: value});
$('#selected-friends').append(invitationHtml);
$('#friend-input').select();
selectedFriendIds[data] = true;
}
else {
$('#friend-input').select();
context.alert('Invitation already exists for this musician.');
}
}
function removeInvitation(evt) {
delete selectedFriendIds[$(evt.currentTarget).parent().attr('user-id')];
$(evt.currentTarget).closest('.invitation').remove();
inviteMusiciansUtil.loadFriends();
}
function resetForm() {
@ -226,7 +164,7 @@
data: jsonData,
success: function(response) {
var newSessionId = response.id;
var invitationCount = createInvitations(newSessionId, function() {
var invitationCount = inviteMusiciansUtil.createInvitations(newSessionId, function() {
context.location = '#/session/' + newSessionId;
});
// Re-loading the session settings will cause the form to reset with the right stuff in it.
@ -248,49 +186,12 @@
return false;
}
function createInvitations(sessionId, onComplete) {
var callCount = 0;
var totalInvitations = 0;
$('#selected-friends .invitation').each(function(index, invitation) {
callCount++;
totalInvitations++;
var invite_id = $(invitation).attr('user-id');
var invite = {
music_session: sessionId,
receiver: invite_id
};
$.ajax({
type: "POST",
url: "/api/invitations",
data: invite
}).done(function(response) {
callCount--;
}).fail(app.ajaxError);
});
// TODO - this is the second time I've used this pattern.
// refactor to make a common utility for this.
function checker() {
if (callCount === 0) {
onComplete();
} else {
context.setTimeout(checker, 10);
}
}
checker();
return totalInvitations;
}
function events() {
$('#create-session-form').on('submit', submitForm);
$('#btn-create-session').on("click", submitForm);
$('#selected-friends').on("click", ".invitation a", removeInvitation);
$('#musician-access').change(toggleMusicianAccess);
$('#fan-access').change(toggleFanAccess);
$('#btn-choose-friends').click(function() {
friendSelectorDialog.showDialog(selectedFriendIds);
});
$('div[layout-id="createSession"] .btn-email-invitation').click(function() {
invitationDialog.showEmailDialog();
});
@ -373,38 +274,10 @@
});
}
function searchFriends(query) {
if (query.length < 2) {
$('#friend-search-results').empty();
return;
}
var url = "/api/search?query=" + query + "&userId=" + context.JK.currentUserId;
$.ajax({
type: "GET",
url: url,
success: friendSearchComplete
});
}
function friendSearchComplete(response) {
// reset search results each time
$('#friend-search-results').empty();
// loop through each
$.each(response.friends, function() {
// only show friends who are musicians
if (this.musician === true) {
var template = $('#template-friend-search-results').html();
var searchResultHtml = context.JK.fillTemplate(template, {userId: this.id, name: this.first_name + ' ' + this.last_name});
$('#friend-search-results').append(searchResultHtml);
$('#friend-search-results').attr('style', 'display:block');
}
});
}
function initialize(invitationDialogInstance, friendSelectorDialogInstance) {
friendSelectorDialog = friendSelectorDialogInstance;
function initialize(invitationDialogInstance, inviteMusiciansUtilInstance) {
invitationDialog = invitationDialogInstance;
inviteMusiciansUtil = inviteMusiciansUtilInstance;
inviteMusiciansUtil.inviteSessionCreate('#create-session-invite-musicians');
events();
loadBands();
loadSessionSettings();
@ -419,8 +292,6 @@
this.submitForm = submitForm;
this.validateForm = validateForm;
this.loadBands = loadBands;
this.searchFriends = searchFriends;
this.addInvitation = addInvitation;
return this;
};

View File

@ -89,6 +89,10 @@
for (ii=0, len=musicians.length; ii < len; ii++) {
mm = musicians[ii];
if (context.JK.currentUserId === mm.id) {
// VRFS-294.3 (David) => skip if current user is musician
continue;
}
instr_logos = '';
for (var jj=0, ilen=mm['instruments'].length; jj<ilen; jj++) {
if (mm['instruments'][jj].instrument_id in instrument_logo_map) {
@ -110,8 +114,10 @@
}
var actionVals = {
profile_url: "/#/profile/" + mm.id,
button_friend: mm['is_friend'] ? '' : 'button-orange',
button_follow: mm['is_following'] ? '' : 'button-orange',
friend_class: 'button-' + (mm['is_friend'] ? 'grey' : 'orange'),
friend_caption: (mm.is_friend ? 'DIS':'')+'CONNECT',
follow_class: 'button-' + (mm['is_following'] ? 'grey' : 'orange'),
follow_caption: (mm.is_following ? 'UN':'')+'FOLLOW',
button_message: 'button-orange'
};
var musician_actions = context.JK.fillTemplate(aTemplate, actionVals);
@ -122,7 +128,7 @@
musician_name: mm.name,
musician_location: mm.city + ', ' + mm.state,
instruments: instr_logos,
biography: mm['biography'],
biography: mm['biography'] || 'Lorum Ipsum Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.',
follow_count: mm['follow_count'],
friend_count: mm['friend_count'],
recording_count: mm['recording_count'],

View File

@ -0,0 +1,207 @@
(function(context,$) {
"use strict";
context.JK = context.JK || {};
context.JK.InviteMusiciansUtil = function(app) {
var logger = context.JK.logger;
var userNames = [];
var userIds = [];
var userPhotoUrls = [];
var friendSelectorDialog = null;
var invitedFriends = [];
var existingInvites = [];
var autoComplete = null;
var rest = context.JK.Rest();
var inviteAction = 'create'; // create/update
var updateSessionID = null;
this.inviteSessionCreate = function(elemSelector) {
inviteAction = 'create';
_appendFriendSelector($(elemSelector));
};
this.inviteSessionUpdate = function(elemSelector, sessionId) {
this.clearSelections();
updateSessionID = sessionId;
friendSelectorDialog.setCallback(friendSelectorCallback);
inviteAction = 'update';
if (0 == $(elemSelector + ' .friendbox').length) {
_appendFriendSelector($(elemSelector));
$('#btn-save-invites').click(function() {
createInvitations(updateSessionID);
});
}
$.ajax({
url: "/api/invitations",
data: { session_id: sessionId, sender: context.JK.currentUserId }
}).done(function(response) {
response.map(function(item) {
var dd = item['receiver'];
existingInvites.push(dd.id);
addInvitation(dd.name, dd.id);
});
}).fail(app.ajaxError);
}
this.clearSelections = function() {
userNames = [];
userIds = [];
userPhotoUrls = [];
invitedFriends = [];
existingInvites = [];
updateSessionID = null;
$('.selected-friends').empty();
};
this.loadFriends = function() {
friendSelectorDialog.setCallback(friendSelectorCallback);
var friends = rest.getFriends({ id: context.JK.currentUserId })
.done(function(friends) {
$.each(friends, function() {
userNames.push(this.name);
userIds.push(this.id);
userPhotoUrls.push(this.photo_url);
});
var autoCompleteOptions = {
lookup: { suggestions: userNames, data: userIds },
onSelect: addInvitation
};
$('#friend-input').attr("placeholder", "Type a friend\'s name").prop('disabled', false);
if (!autoComplete) {
autoComplete = $('#friend-input').autocomplete(autoCompleteOptions);
}
else {
autoComplete.setOptions(autoCompleteOptions);
}
$(".autocomplete").width("150px");
})
.fail(function() {
$('#friend-input').attr("placeholder", "Unable to lookup friends");
app.ajaxError(arguments);
});
}
function friendSelectorCallback(newSelections) {
var keys = Object.keys(newSelections);
for (var i=0; i < keys.length; i++) {
var dd = newSelections[keys[i]];
addInvitation(dd.userName, dd.userId);
}
}
function _inviteExists(userID) {
return 0 <= existingInvites.indexOf(userID);
}
function addInvitation(value, data) {
if (0 > invitedFriends.indexOf(data)) {
var template = $('#template-added-invitation').html();
var imgStyle = _inviteExists(data) ? 'display:none' : '';
var invitationHtml = context.JK.fillTemplate(template,
{userId: data,
userName: value,
imageStyle: imgStyle});
$('.selected-friends').append(invitationHtml);
$('#friend-input').select();
invitedFriends.push(data);
} else {
$('#friend-input').select();
context.alert('Invitation already exists for this musician.');
}
}
function removeInvitation(evt) {
var idx = invitedFriends.indexOf($(evt.currentTarget).parent().attr('user-id'));
if (0 <= idx) invitedFriends.splice(idx, 1);
$(evt.currentTarget).closest('.invitation').remove();
}
function createInvitations(sessionId, onComplete) {
var callCount = 0;
var totalInvitations = invitedFriends.length - existingInvites.length;
invitedFriends.map(function(invite_id) {
if (!_inviteExists(invite_id)) {
callCount++;
var invite = {
music_session: sessionId,
receiver: invite_id
};
$.ajax({
type: "POST",
url: "/api/invitations",
data: invite
}).done(function(response) {
callCount--;
}).fail(app.ajaxError);
}
});
// TODO - this is the second time I've used this pattern.
// refactor to make a common utility for this.
function checker() {
callCount === 0 ? onComplete() : context.setTimeout(checker, 10);
}
if (onComplete) checker();
return totalInvitations;
}
this.createInvitations = createInvitations;
function searchFriends(query) {
if (query.length < 2) {
$('#friend-search-results').empty();
return;
}
var url = "/api/search?query=" + query + "&userId=" + context.JK.currentUserId;
$.ajax({
type: "GET",
url: url,
success: friendSearchComplete
});
}
function friendSearchComplete(response) {
// reset search results each time
$('#friend-search-results').empty();
// loop through each
$.each(response.friends, function() {
// only show friends who are musicians
if (this.musician === true) {
var template = $('#template-friend-search-results').html();
var searchResultHtml = context.JK.fillTemplate(template, {userId: this.id, name: this.first_name + ' ' + this.last_name});
$('#friend-search-results').append(searchResultHtml);
$('#friend-search-results').attr('style', 'display:block');
}
});
}
function _friendSelectorHTML() {
return context.JK.fillTemplate($('#template-session-invite-musicians').html(),
{choose_friends_id: 'btn-choose-friends-'+inviteAction,
selected_friends_id: 'selected-friends-'+inviteAction});
}
function _appendFriendSelector(elemSelector) {
elemSelector.append(_friendSelectorHTML());
$('#selected-friends-'+inviteAction).on("click", ".invitation a", removeInvitation);
$('#btn-choose-friends-'+inviteAction).click(function(){
var obj = {};
invitedFriends.map(function(uid) { obj[uid] = true; });
friendSelectorDialog.showDialog(obj);
});
};
this.initialize = function(friendSelectorDialogInstance) {
friendSelectorDialog = friendSelectorDialogInstance;
};
return this;
};
})(window,jQuery);

View File

@ -14,6 +14,8 @@
var addNewGearDialog;
var localRecordingsDialog = null;
var recordingFinishedDialog = null;
var friendSelectorDialog = null;
var inviteMusiciansUtil = null;
var screenActive = false;
var currentMixerRangeMin = null;
var currentMixerRangeMax = null;
@ -1302,12 +1304,17 @@
}
}
function inviteMusicians() {
inviteMusiciansUtil.inviteSessionUpdate('#update-session-invite-musicians', sessionId);
}
function events() {
$('#session-resync').on('click', sessionResync);
$('#session-contents').on("click", '[action="delete"]', deleteSession);
$('#tracks').on('click', 'div[control="mute"]', toggleMute);
$('#recording-start-stop').on('click', startStopRecording);
$('#open-a-recording').on('click', openRecording);
$('#session-invite-musicians').on('click', inviteMusicians);
$('#track-settings').click(function() {
configureTrackDialog.showVoiceChatPanel(true);
configureTrackDialog.showMusicAudioPanel(true);
@ -1319,9 +1326,10 @@
.on('change-position', onChangePlayPosition);
}
this.initialize = function(localRecordingsDialogInstance, recordingFinishedDialogInstance) {
this.initialize = function(localRecordingsDialogInstance, recordingFinishedDialogInstance, inviteMusiciansUtilInstance) {
localRecordingsDialog = localRecordingsDialogInstance;
recordingFinishedDialog = recordingFinishedDialogInstance;
inviteMusiciansUtil = inviteMusiciansUtilInstance;
context.jamClient.SetVURefreshRate(150);
playbackControls = new context.JK.PlaybackControls($('.session-recordings .recording-controls'));
events();

View File

@ -155,6 +155,9 @@
margin-bottom: 10px;
> a.smallbutton {
margin: 2px;
&.button-grey {
display:none; // @FIXME VRFS-930 / VRFS-931 per comment from David - don't show.
}
}
}
@ -204,7 +207,6 @@
.friendbox {
padding:5px;
width:100%;
height:60px;
}

View File

@ -11,7 +11,7 @@
}
}
#btn-choose-friends {
.btn-choose-friends {
margin:0;
}
#create-session-genre select, #create-session-band select {

View File

@ -1,5 +1,11 @@
@import "client/common.css.scss";
.profile-head {
}
.profile-body {
}
.profile-header {
padding:10px 20px;
// height:120px;

View File

@ -716,3 +716,6 @@ table.vu td {
}
#update-session-invite-musicians {
margin: 10px;
}

View File

@ -14,8 +14,11 @@ class ApiInvitationsController < ApiController
if current_user.id != sender_id
raise PermissionError, "You can only ask for your own sent invitations"
end
@invitations = Invitation.where(:sender_id => current_user.id)
if session_id = params[:session_id]
@invitations = Invitation.where(:sender_id => sender_id, :music_session_id => session_id)
else
@invitations = Invitation.where(:sender_id => current_user.id)
end
elsif !receiver_id.nil?
if current_user.id != receiver_id
raise PermissionError, "You can only ask for your own received invitations"
@ -34,25 +37,33 @@ class ApiInvitationsController < ApiController
sender = current_user
join_request = JoinRequest.find(params[:join_request]) unless params[:join_request].nil?
@invitation = Invitation.new
@invitation.music_session = music_session
@invitation.sender = sender
@invitation.receiver = receiver
@invitation.join_request = join_request
@invitation.save
unless @invitation.errors.any?
User.save_session_settings(current_user, music_session)
# send notification
Notification.send_session_invitation(receiver, current_user, music_session.id)
@invitation = Invitation.limit(1)
.where(:receiver_id => params[:receiver],
:sender_id => current_user.id,
:music_session_id => params[:music_session])
.first
if @invitation
respond_with @invitation, :responder => ApiResponder, :location => api_invitation_detail_url(@invitation)
else
# we have to do this because api_invitation_detail_url will fail with a bad @invitation
response.status = :unprocessable_entity
respond_with @invitation
@invitation = Invitation.new
@invitation.music_session = music_session
@invitation.sender = sender
@invitation.receiver = receiver
@invitation.join_request = join_request
@invitation.save
unless @invitation.errors.any?
User.save_session_settings(current_user, music_session)
# send notification
Notification.send_session_invitation(receiver, current_user, music_session.id)
respond_with @invitation, :responder => ApiResponder, :location => api_invitation_detail_url(@invitation)
else
# we have to do this because api_invitation_detail_url will fail with a bad @invitation
response.status = :unprocessable_entity
respond_with @invitation
end
end
end

View File

@ -43,6 +43,10 @@ if @search.musicians_filter_search?
@search.is_follower?(musician)
end
node :biography do |musician|
musician.biography.nil? ? "" : musician.biography
end
child :musician_instruments => :instruments do
attributes :instrument_id, :description, :proficiency_level, :priority
end
@ -73,6 +77,10 @@ if @search.bands_filter_search?
@search.is_follower?(band)
end
node :biography do |band|
band.biography.nil? ? "" : band.biography
end
child :genres => :genres do
attributes :genre_id, :description
end
@ -81,7 +89,7 @@ if @search.bands_filter_search?
node :user_id do |uu| uu.id end
node :photo_url do |uu| uu.photo_url end
node :name do |uu| uu.name end
node :instruments do |uu| uu.instruments.map(&:id).join(',') end
node :instruments do |uu| uu.instruments.map(&:id).join(',') end
end
node :follow_count do |band| @search.follow_count(band) end

View File

@ -26,4 +26,8 @@ node :genres do |band|
attributes :id, :description
end
end
end
end
node :biography do |band|
band.biography.nil? ? "" : band.biography
end

View File

@ -22,7 +22,7 @@
<!-- Session Row Template -->
<script type="text/template" id="template-find-band-row">
<div class="profile-band-list-result band-list-result">
<div style="float:left">
<div class="left">
<!-- avatar -->
<div class="avatar-small"><img src="{avatar_url}" /></div>

View File

@ -84,22 +84,7 @@
<h2>invite musicians</h2>
<br />
<div>
<div class="right" layout-link="select-friends">
<a href="#" id="btn-choose-friends" class="button-grey">CHOOSE FRIENDS</a>
</div>
<div style="margin-right:140px;">
Start typing friends' names or:
</div>
<div class="clearall"></div>
</div>
<br />
<!-- friend invitation box -->
<div class="friendbox">
<div id="selected-friends"></div>
<input id="friend-input" type="text" placeholder="Looking up friends..." />
</div>
<div id="create-session-invite-musicians"></div>
<div class="mt35 mb15">
Invite friends and contacts to join you on JamKazam from:
@ -171,13 +156,6 @@
</div>
</div>
<!-- Added Invitation Template -->
<script type="text/template" id="template-added-invitation">
<div user-id="{userId}" class="invitation">{userName}
<a><%= image_tag "shared/icon_delete_sm.png", :size => "13x13" %></a>
</div>
</script>
<!-- Band option template -->
<script type="text/template" id="template-band-option">
<option value="{value}">{label}</option>

View File

@ -1,18 +1,49 @@
<!-- Feed Screen -->
<div layout="screen" layout-id="feed" class="screen secondary">
<div class="content">
<div class="content-head">
<div class="content-icon">
<%= image_tag "content/icon_feed.png", {:height => 19, :width => 19} %>
</div>
<h1>feed</h1>
<%= content_tag(:div, :layout => 'screen', 'layout-id' => 'feed', :class => "screen secondary") do -%>
<%= content_tag(:div, :class => :content) do -%>
<%= content_tag(:div, :class => 'content-head') do -%>
<%= content_tag(:div, image_tag("content/icon_feed.png", {:height => 19, :width => 19}), :class => 'content-icon') %>
<%= content_tag(:h1, 'feed') %>
<%= render "screen_navigation" %>
</div>
<div class="content-body">
<div class="content-body-scroller">
<p>This feature not yet implemented</p>
</div>
</div>
<% end -%>
<%= content_tag(:div, :class => 'content-body') do -%>
<%= form_tag('', {:id => 'find-session-form', :class => 'inner-content'}) do -%>
<%= render(:partial => "web_filter", :locals => {:search_type => Search::PARAM_FEED}) %>
<%= content_tag(:div, :class => 'filter-body') do %>
<%= content_tag(:div, :class => 'content-body-scroller') do -%>
<p>This feature not yet implemented</p>
<%= content_tag(:div, content_tag(:div, '', :id => 'session-filter-results', :class => 'filter-results'), :class => 'content-wrapper') %>
<% end -%>
<% end -%>
<% end -%>
<% end -%>
<% end -%>
<% end -%>
<!-- Session Row Template -->
<script type="text/template" id="template-find-session-row">
<div class="profile-band-list-result band-list-result">
<div class="left">
<!-- avatar -->
<div class="avatar-small"><img src="{avatar_url}" /></div>
<!-- name & location -->
<div style="width:220px;" class="result-name">{band_name}<br />
<span class="result-location">{band_location}</span>
<br /><br />
<div id="result_sessions" class="nowrap">{genres}</div>
<br /><br />
{follow_count} <img src="../assets/content/icon_followers.png" width="22" height="12" align="absmiddle" />&nbsp;&nbsp;&nbsp;{recording_count} <img src="../assets/content/icon_recordings.png" width="12" height="13" align="absmiddle" />&nbsp;&nbsp;&nbsp;{session_count} <img src="../assets/content/icon_session_tiny.png" width="12" height="12" align="absmiddle" /><br /><br />
</div>
</div>
</div>
<div class="left ml20 f11 whitespace w35"><br />
{biography}<br />
<br />
<div data-band-id={band_id}>{band_action_template}</div>
</div>
<div class="left ml10 w25 band-players">
<table class="musicians" cellpadding="0" cellspacing="5">{band_player_template}</table>
</div>
<br clear="all" />
</div>
</script>

View File

@ -0,0 +1,38 @@
<!-- Session Update Invite Musicians Dialog -->
<div class="dialog invitemusicians-overlay" layout="dialog" layout-id="select-invites">
<div class="invitemusicians-inner" id="update-session-invite-musicians">
</div>
<br clear="all" />
<div class="left">
<a id="btn-cancel-invites" layout-action="close" class="button-grey">CANCEL</a>&nbsp;
</div>
<div class="right">
<a id="btn-save-invites" layout-action="close" class="button-orange">INVITE</a>
</div>
</div>
<!-- invite musician friend selector template -->
<script type="text/template" id="template-session-invite-musicians">
<div>
<div class="right" layout-link="select-friends">
<a href="#" class="btn-choose-friends button-grey" id="{choose_friends_id}">CHOOSE FRIENDS</a>
</div>
<div style="margin-right:140px;">
Start typing friends' names or:
</div>
<div class="clearall"></div>
</div>
<br />
<!-- friend invitation box -->
<div class="friendbox">
<div class="selected-friends" id="{selected_friends_id}"></div>
<!--<input id="friend-input" type="text" placeholder="Looking up friends..." />-->
</div>
</script>
<!-- Added Invitation Template -->
<script type="text/template" id="template-added-invitation">
<div user-id="{userId}" class="invitation">{userName}
<a><%= image_tag "shared/icon_delete_sm.png", :size => "13x13", :style => "{imageStyle}" %></a>
</div>
</script>

View File

@ -22,24 +22,35 @@
<!-- Session Row Template -->
<script type="text/template" id="template-find-musician-row">
<div class="profile-band-list-result musician-list-result">
<div class="left">
<!-- avatar -->
<div class="avatar-small"><img src="{avatar_url}" /></div>
<!-- name & location -->
<div style="width:220px;" class="result-name">{musician_name}<br />
<span class="result-location">{musician_location}
<br /><br />
<div id="result_instruments" class="nowrap">{instruments}</div>
<br clear="all" /><br />
{friend_count} <img src="../assets/content/icon_friend.png" width="14" height="12" align="absmiddle" />&nbsp;&nbsp;&nbsp;{follow_count} <img src="../assets/content/icon_followers.png" width="22" height="12" align="absmiddle" />&nbsp;&nbsp;&nbsp;{recording_count} <img src="../assets/content/icon_recordings.png" width="12" height="13" align="absmiddle" />&nbsp;&nbsp;&nbsp;{session_count} <img src="../assets/content/icon_session_tiny.png" width="12" height="12" align="absmiddle" /></span><br /><br />
<div class="left" data-hint="container">
<div class="left">
<!-- avatar -->
<div class="avatar-small"><img src="{avatar_url}" /></div>
</div>
</div>
<div class="left ml35 f11 whitespace w40"><br />
{biography}<br />
<br />
<div class="result-list-button-wrapper" data-musician-id={musician_id}>
{musician_action_template}
<div class="left">
<div data-hint="top-row">
<div class="left">
<!-- name & location -->
<div style="" class="result-name">{musician_name}</div>
<div class="result-location">{musician_location}</div>
<div id="result_instruments" class="nowrap">{instruments}</div>
</div>
<div class="left ml35 f11 whitespace w40">
<div class="biography">{biography}</div>
</div>
</div>
<div data-hint="button-row">
<div class="stats">
{friend_count} <img src="../assets/content/icon_friend.png" width="14" height="12" align="absmiddle" />&nbsp;&nbsp;&nbsp;
{follow_count} <img src="../assets/content/icon_followers.png" width="22" height="12" align="absmiddle" />&nbsp;&nbsp;&nbsp;
{recording_count} <img src="../assets/content/icon_recordings.png" width="12" height="13" align="absmiddle" />&nbsp;&nbsp;&nbsp;
{session_count} <img src="../assets/content/icon_session_tiny.png" width="12" height="12" align="absmiddle" />
</div>
<div class="result-list-button-wrapper" data-musician-id={musician_id}>
{musician_action_template}
</div>
</div>
</div>
</div>
<div class="left ml10 w20 musician-following">
@ -54,9 +65,9 @@
<script type="text/template" id="template-musician-action-btns">
<a href="{profile_url}" class="button-orange smallbutton">PROFILE</a>
<% if current_user.musician? %>
<a href="#" class="{button_friend} smallbutton search-m-friend">CONNECT</a>
<a href="#" class="{friend_class} smallbutton search-m-friend">{friend_caption}</a>
<% end %>
<a href="#" class="{button_follow} smallbutton search-m-follow">FOLLOW</a>
<a href="#" class="{follow_class} smallbutton search-m-follow">{follow_caption}</a>
<!--<a href="#" class="{button_message} smallbutton search-m-like">MESSAGE</a>-->
<div class="clearall"></div>
</script>

View File

@ -69,8 +69,8 @@
<!-- live tracks -->
<div class="session-livetracks">
<h2>live tracks</h2>
<div class="session-add">
<a>
<div class="session-add" layout-link="select-invites">
<a href="#" id="session-invite-musicians">
<%= image_tag "content/icon_add.png", {:width => 19, :height => 19, :align => "texttop"} %>&nbsp;&nbsp;Invite Musicians
</a>
</div>
@ -178,3 +178,4 @@
<script type="text/template" id="template-genre-option">
<option value="{value}">{label}</option>
</script>

View File

@ -40,7 +40,7 @@
<input type="button" value="Get"/>
<textarea data-what="GetFTUE"></textarea>
</div>
<div style="float:left;"
<div style="float:left;">
<h2>SetFTUE</h2>
<form>
<label>true <input name="ftue" type="radio" value="true"/></label>

View File

@ -4,36 +4,61 @@
filter_label = :band
when Search::PARAM_MUSICIAN
filter_label = :musician
when Search::PARAM_FEED
filter_label = :feed
end %>
<%= content_tag(:div, :id => defined?(id) ? id : 'session-controls', :class => "#{filter_label}-filter filter-head") do %>
<%= content_tag(:div, :class => "filter-element wrapper") do -%>
<%= content_tag(:div, 'Filter By:', :class => 'filter-element desc') %>
<!-- order by filter -->
<%= select_tag("#{filter_label}_order_by", options_for_select(Search::ORDERINGS), {:class => "#{filter_label}-order-by"} ) %>
<% if :feed == filter_label %>
<!-- @begin sort filter -->
<%= content_tag(:div, 'Sort Feed by:', :class => 'filter-element desc') %>
<%= select_tag("#{filter_label}_order_by", options_for_select(Search::F_SORT_OPTS), {:class => "#{filter_label}-order-by"} ) %>
<!-- @end sort filter -->
<% else %>
<!-- @begin order by filter -->
<%= content_tag(:div, 'Filter By:', :class => 'filter-element desc') %>
<%= select_tag("#{filter_label}_order_by", options_for_select(Search::ORDERINGS), {:class => "#{filter_label}-order-by"} ) %>
<!-- @end order by filter -->
<% end %>
<% end -%>
<%= content_tag(:div, :class => 'filter-element wrapper') do -%>
<% if :musician == filter_label %>
<!-- instrument filter -->
<!-- @begin instrument filter -->
<%= content_tag(:div, 'Instrument:', :class => 'filter-element desc') %>
<%= select_tag("#{filter_label}_instrument",
options_for_select([['Any', '']].concat(JamRuby::Instrument.all.collect { |ii| [ii.description, ii.id] }))) %>
<!-- @end instrument filter -->
<% elsif :band == filter_label %>
<!-- genre filter -->
<!-- @begin genre filter -->
<%= content_tag(:div, 'Genre:', :class => 'filter-element desc') %>
<%= select_tag("#{filter_label}_genre",
options_for_select([['Any', '']].concat(JamRuby::Genre.all.collect { |ii| [ii.description, ii.id] }))) %>
<!-- @end genre filter -->
<% elsif :feed == filter_label %>
<!-- @begin date filter -->
<%= content_tag(:div, 'Include Dates:', :class => 'filter-element desc') %>
<%= select_tag("#{filter_label}_date", options_for_select(Search::DATE_OPTS)) %>
<!-- @end date filter -->
<% end %>
<% end -%>
<!-- distance filter -->
<%= content_tag(:div, :class => 'filter-element wrapper') do -%>
<%= content_tag(:div, 'Within', :class => 'filter-element desc') %>
<%= content_tag(:div, :class => 'query-distance-params') do -%>
<% default_distance = :musician == filter_label ? Search::M_MILES_DEFAULT : Search::B_MILES_DEFAULT %>
<%= select_tag("#{filter_label}_query_distance", options_for_select(Search::DISTANCE_OPTS, default_distance)) %>
<% end -%>
<%= content_tag(:div, :class => 'filter-element desc') do -%>
miles of <%= content_tag(:span, current_user.current_city(request.remote_ip), :id => "#{filter_label}-filter-city") %>
<% end -%>
<% if :feed == filter_label %>
<!-- @begin show filter -->
<%= content_tag(:div, 'Show:', :class => 'filter-element desc') %>
<%= select_tag("#{filter_label}_show", options_for_select(Search::SHOW_OPTS)) %>
<!-- @end show filter -->
<% else %>
<!-- @begin distance filter -->
<%= content_tag(:div, 'Within', :class => 'filter-element desc') %>
<%= content_tag(:div, :class => 'query-distance-params') do -%>
<% default_distance = :musician == filter_label ? Search::M_MILES_DEFAULT : Search::B_MILES_DEFAULT %>
<%= select_tag("#{filter_label}_query_distance", options_for_select(Search::DISTANCE_OPTS, default_distance)) %>
<% end -%>
<%= content_tag(:div, :class => 'filter-element desc') do -%>
miles of <%= content_tag(:span, current_user.current_city(request.remote_ip), :id => "#{filter_label}-filter-city") %>
<% end -%>
<!-- @end distance filter -->
<% end %>
<% end -%>
<% end -%>
<!-- @end web_filter -->

View File

@ -35,6 +35,7 @@
<%= render "account_profile_avatar" %>
<%= render "account_audio_profile" %>
<%= render "invitationDialog" %>
<%= render "inviteMusicians" %>
<%= render "whatsNextDialog" %>
<%= render "recordingFinishedDialog" %>
<%= render "localRecordingsDialog" %>
@ -105,6 +106,9 @@
var friendSelectorDialog = new JK.FriendSelectorDialog(JK.app);
friendSelectorDialog.initialize();
var inviteMusiciansUtil = new JK.InviteMusiciansUtil(JK.app);
inviteMusiciansUtil.initialize(friendSelectorDialog);
var userDropdown = new JK.UserDropdown(JK.app);
JK.UserDropdown = userDropdown;
userDropdown.initialize(invitationDialog);
@ -148,7 +152,7 @@
JK.Banner.initialize();
var createSessionScreen = new JK.CreateSessionScreen(JK.app);
createSessionScreen.initialize(invitationDialog, friendSelectorDialog);
createSessionScreen.initialize(invitationDialog, inviteMusiciansUtil);
var bandSetupScreen = new JK.BandSetupScreen(JK.app);
bandSetupScreen.initialize(invitationDialog, friendSelectorDialog);
@ -170,7 +174,7 @@
findBandScreen.initialize();
var sessionScreen = new JK.SessionScreen(JK.app);
sessionScreen.initialize(localRecordingsDialog, recordingFinishedDialog);
sessionScreen.initialize(localRecordingsDialog, recordingFinishedDialog, inviteMusiciansUtil);
var sessionSettingsDialog = new JK.SessionSettingsDialog(JK.app, sessionScreen);
sessionSettingsDialog.initialize();

View File

@ -102,7 +102,7 @@
<input type="text" /> <br clear="all" /><br />
-->
<%= f.submit "CREATE ACCOUNT", class: "right button-orange" %><br/ style="clear:both;"><br/>
<%= f.submit "CREATE ACCOUNT", class: "right button-orange" %><br style="clear:both;"/><br/>
<a href="/auth/facebook" class="right"><img src="/fb-signup-button.png"></a>
</div>