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

This commit is contained in:
Seth Call 2014-02-18 13:35:11 +00:00
commit 4808514032
18 changed files with 877 additions and 426 deletions

View File

@ -22,6 +22,20 @@ module JamRuby
self.text_search({ SEARCH_TEXT_TYPE_ID => :musicians, :query => txt }, user)
end
def self.session_invite_search(query, user)
srch = Search.new
srch.search_type = :session_invite
like_str = "%#{query.downcase}%"
rel = User
.musicians
.where(["users.id IN (SELECT friend_id FROM friendships WHERE user_id = '#{user.id}')"])
.where(["first_name ILIKE ? OR last_name ILIKE ?", like_str, like_str])
.limit(10)
.order([:last_name, :first_name])
srch.results = rel.all
srch
end
def self.text_search(params, user = nil)
srch = Search.new
unless (params.blank? || params[:query].blank? || 2 > params[:query].length)
@ -72,11 +86,12 @@ module JamRuby
args
end
PARAM_SESSION_INVITE = :srch_sessinv
PARAM_MUSICIAN = :srch_m
PARAM_BAND = :srch_b
PARAM_FEED = :srch_f
F_PER_PAGE = B_PER_PAGE = M_PER_PAGE = 10
F_PER_PAGE = B_PER_PAGE = M_PER_PAGE = 20
M_MILES_DEFAULT = 500
B_MILES_DEFAULT = 0
@ -205,6 +220,10 @@ module JamRuby
public
def session_invite_search?
:session_invite == @search_type
end
def musicians_text_search?
:musicians == @search_type
end

View File

@ -1091,8 +1091,8 @@ module JamRuby
end
def top_followings
@topf ||= User.joins("INNER JOIN follows ON follows.followable_id = users.id")
.where(['follows.user_id = ?',self.id])
@topf ||= User.joins("INNER JOIN follows ON follows.followable_id = users.id AND follows.followable_type = '#{self.class.to_s}'")
.where(['follows.user_id = ?', self.id])
.order('follows.created_at DESC')
.limit(3)
end

View File

@ -33,10 +33,24 @@ describe Search do
end
it "search for band & musician " do
create_peachy_data
# it "search for band & musician " do
# create_peachy_data
# assert_peachy_data
# end
assert_peachy_data
let(:user1) { FactoryGirl.create(:user, :first_name => Faker::Name.first_name, :last_name => Faker::Name.last_name) }
let(:user2) { FactoryGirl.create(:user, :first_name => Faker::Name.first_name, :last_name => Faker::Name.last_name) }
let(:user3) { FactoryGirl.create(:user, :first_name => Faker::Name.first_name, :last_name => Faker::Name.last_name) }
it 'find autocomplete friend musicians' do
Friendship.save_using_models(user1, user2)
Friendship.save_using_models(user1, user3)
srch = Search.session_invite_search(user1.first_name[0..3], user2)
expect(srch.results.size).to eq(1)
srch = Search.session_invite_search(user1.last_name[0..3], user2)
expect(srch.results.size).to eq(1)
end
end

View File

@ -35,8 +35,12 @@
var genre = sessionSettings.hasOwnProperty('genres') && sessionSettings.genres.length > 0 ? sessionSettings.genres[0].id : '';
context.JK.GenreSelectorHelper.reset('#create-session-genre', genre);
var musician_access = sessionSettings.hasOwnProperty('musician_access') ? sessionSettings.musician_access : true;
var bandId = sessionSettings.hasOwnProperty('band_id') ? sessionSettings.band_id : '';
$('#band-list', $form).val(bandId);
var musician_access = sessionSettings.hasOwnProperty('musician_access') ? sessionSettings.musician_access : false;
$('#musician-access option[value=' + musician_access + ']').attr('selected', 'selected');
toggleMusicianAccess();
if (musician_access) {
@ -44,10 +48,7 @@
$('#musician-access-option-' + approval_required).iCheck('check').attr('checked', 'checked');
}
var bandId = sessionSettings.hasOwnProperty('band_id') ? sessionSettings.band_id : '';
$('#band-list', $form).val(bandId);
var fan_access = sessionSettings.hasOwnProperty('fan_access') ? sessionSettings.fan_access : true;
var fan_access = sessionSettings.hasOwnProperty('fan_access') ? sessionSettings.fan_access : false;
$('#fan-access option[value=' + fan_access + ']').attr('selected', 'selected');
toggleFanAccess();
@ -56,11 +57,13 @@
$('#fan-chat-option-' + fan_chat).iCheck('check').attr('checked', 'checked');
}
context.JK.dropdown($('#musician-access', $form));
context.JK.dropdown($('#fan-access', $form));
$('#friend-input')
.unbind('blur')
.attr("placeholder", "Looking up friends...")
.prop('disabled', true)
// Should easily be able to grab other items out of sessionSettings and put them into the appropriate ui elements.
}
function validateForm() {
@ -216,11 +219,11 @@
var value = $("#musician-access option:selected").val();
if (value == "false") {
$("input[name='musician-access-option']").attr('disabled', 'disabled');
$("input[name='musician-access-option']").parent().addClass("op50");
$("input[name='musician-access-option']").parent().addClass("op10");
}
else {
$("input[name='musician-access-option']").removeAttr('disabled');
$("input[name='musician-access-option']").parent().removeClass("op50");
$("input[name='musician-access-option']").parent().removeClass("op10");
}
}
@ -228,11 +231,11 @@
var value = $("#fan-access option:selected").val();
if (value == "false") {
$("input[name='fan-chat-option']").attr('disabled', 'disabled');
$("input[name='fan-chat-option']").parent().addClass("op50");
$("input[name='fan-chat-option']").parent().addClass("op10");
}
else {
$("input[name='fan-chat-option']").removeAttr('disabled');
$("input[name='fan-chat-option']").parent().removeClass("op50");
$("input[name='fan-chat-option']").parent().removeClass("op10");
}
}
@ -264,8 +267,7 @@
}
function sessionSettingsLoaded(response) {
if (response != null)
{
if (response != null) {
sessionSettings = response;
}
resetForm();

View File

@ -200,7 +200,7 @@
$('#band_genre').change(refreshDisplay);
$('#band_order_by').change(refreshDisplay);
$('#band-filter-results').bind('scroll', function() {
$('#band-filter-results').closest('.content-body-scroller').bind('scroll', function() {
if ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
if (page_num < page_count) {
page_num += 1;

View File

@ -222,7 +222,7 @@
$('#musician_instrument').change(refreshDisplay);
$('#musician_order_by').change(refreshDisplay);
$('#musician-filter-results').bind('scroll', function() {
$('#musician-filter-results').closest('.content-body-scroller').bind('scroll', function() {
if ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
if (page_num < page_count) {
page_num += 1;

View File

@ -26,9 +26,11 @@
musicianHtml += '<td width="75"><a href="#">' + val.name + '</a></td>';
instrumentHtml = '<td><div class="nowrap">';
$.each(val.instruments, function(index, instrument) {
instrumentHtml += '<img src="' + instrumentLogoMap[instrument.instrument_id] + '" width="24" height="24" />&nbsp;';
});
if (val.instruments) { // @FIXME: edge case for Test user that has no instruments?
$.each(val.instruments, function(index, instrument) {
instrumentHtml += '<img src="' + instrumentLogoMap[instrument.instrument_id] + '" width="24" height="24" />&nbsp;';
});
}
instrumentHtml += '</div></td>';

View File

@ -67,15 +67,16 @@
var autoCompleteOptions = {
lookup: { suggestions: userNames, data: userIds },
onSelect: addInvitation
onSelect: addInvitation,
serviceUrl: '/api/search.json?srch_sessinv=1',
minChars: 3,
};
$('#friend-input').attr("placeholder", "Type a friend\'s name").prop('disabled', false);
if (!autoComplete) {
autoComplete = $('#friend-input').autocomplete(autoCompleteOptions);
}
else {
} else {
autoComplete.setOptions(autoCompleteOptions);
}
@ -100,6 +101,10 @@
}
function addInvitation(value, data) {
if (undefined === data) {
data = value.data;
value = value.value;
}
if (0 > invitedFriends.indexOf(data)) {
var template = $('#template-added-invitation').html();
var imgStyle = _inviteExists(data) ? 'display:none' : '';

File diff suppressed because it is too large Load Diff

View File

@ -170,7 +170,7 @@
context.jamClient.SessionRegisterCallback("JK.HandleBridgeCallback");
context.jamClient.RegisterRecordingCallbacks("JK.HandleRecordingStartResult", "JK.HandleRecordingStopResult", "JK.HandleRecordingStarted", "JK.HandleRecordingStopped", "JK.HandleRecordingAborted");
context.jamClient.SessionSetAlertCallback("JK.AlertCallback");
context.jamClient.SessionSetConnectionStatusRefreshRate(3000);
context.jamClient.SessionSetConnectionStatusRefreshRate(1000);
// If you load this page directly, the loading of the current user
// is happening in parallel. We can't join the session until the

View File

@ -21,7 +21,15 @@
}
function events() {
$('.userinfo').hoverIntent(menuHoverIn, menuHoverOut);
$('.userinfo').hoverIntent({
over: function () {
$('ul.shortcuts', this).fadeIn(100);
},
out: function() {
$('ul.shortcuts', this).fadeOut(100);
},
timeout: 500
});
$('.userinfo .invite-friends .menuheader').on('click', function(e) {
$(this).closest('li').css('height', 'auto').find('ul').toggle();

View File

@ -235,6 +235,11 @@ input[type="button"] {
_overflow-x:hidden;
}
.autocomplete-suggestions { border: 1px solid #999; background: #666; overflow: auto; }
.autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; }
.autocomplete-selected { background: #F0F0F0; }
.autocomplete-suggestions strong { font-weight: normal; color: #3399FF; }
.autocomplete .selected {
background:$ColorScreenBackground;
cursor:pointer;
@ -345,20 +350,26 @@ input[type="text"], input[type="password"]{
margin-left:35px;
}
.op50 {
opacity: .5;
-ms-filter: "alpha(opacity=50)";
}
.op70 {
opacity: .7;
-ms-filter: "alpha(opacity=70)";
}
.op50 {
opacity: .5;
-ms-filter: "alpha(opacity=50)";
}
.op30 {
opacity: .3;
-ms-filter: "alpha(opacity=30)";
}
.op10 {
opacity: .1;
-ms-filter: "alpha(opacity=10)";
}
.nowrap {
display:inline-block;
white-space:nowrap;

View File

@ -328,6 +328,11 @@ small, .small {font-size:11px;}
-ms-filter: "alpha(opacity=30)";
}
.op10 {
opacity: .1;
-ms-filter: "alpha(opacity=10)";
}
.nowrap {
display:inline-block;
white-space:nowrap;

View File

@ -15,6 +15,9 @@ class ApiSearchController < ApiController
@search = Search.band_filter(query, current_user)
end
respond_with @search, responder: ApiResponder, :status => 200
elsif 1 == params[Search::PARAM_SESSION_INVITE].to_i
@search = Search.session_invite_search(params[:query], current_user)
else
@search = Search.text_search(params, current_user)
end

View File

@ -2,6 +2,13 @@ object @search
node :search_type do |ss| ss.search_type end
if @search.session_invite_search?
child(:results => :suggestions) {
node :value do |uu| uu.name end
node :data do |uu| uu.id end
}
end
if @search.bands_text_search?
child(:results => :bands) {
attributes :id, :name, :location, :photo_url, :logo_url, :website

View File

@ -49,7 +49,7 @@
<div class="mb5">Musician Access:</div>
<div>
<div class="left mr20">
<div class="left mr20" style="width:75px;">
<select id="musician-access" class="easydropdown">
<option selected="selected" value="true">Public</option>
<option value="false">Private</option>
@ -66,7 +66,7 @@
<div class="mb5">Fan Access:</div>
<div>
<div class="left mr20">
<div class="left mr20" style="width:75px;">
<select id="fan-access" class="easydropdown">
<option value="true">Public</option>
<option selected="selected" value="false">Private</option>

View File

@ -26,7 +26,7 @@
<!-- 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..." />-->
<input id="friend-input" type="text" placeholder="Looking up friends..." />
</div>
</script>

View File

@ -82,33 +82,18 @@ describe "Musician Search API", :type => :api do
f3.followable = @user4
f3.save
# @user3
f4 = Follow.new
f4.user = @user3
f4.followable = @user3
f4.save
f5 = Follow.new
f5.user = @user4
f5.followable = @user3
f5.save
# @user2
f6 = Follow.new
f6.user = @user1
f6.followable = @user2
f6.save
# @user4.followers.concat([@user2, @user3, @user4])
# @user3.followers.concat([@user3, @user4])
# @user2.followers.concat([@user4])
expect(@user4.followers.count).to be 3
get_query
good_response
musician = json["musicians"][0]
expect(musician["id"]).to eq(@user4.id)
followings = musician['followings']
# expect(followings.length).to be 3
expect(followings.length).to be 2
expect(musician['follow_count'].to_i).to be > 0
end