* merging manifest and user
This commit is contained in:
commit
3a5321dc5c
|
|
@ -94,4 +94,5 @@ integrate_icecast_into_sessions.sql
|
|||
ms_recording_anonymous_likes.sql
|
||||
ms_user_history_add_instruments.sql
|
||||
icecast_config_changed.sql
|
||||
invited_users_facebook_support.sql
|
||||
first_recording_at.sql
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE invited_users ALTER COLUMN email DROP NOT NULL;
|
||||
ALTER TABLE invited_users ADD COLUMN invite_medium VARCHAR(64);
|
||||
|
||||
|
|
@ -48,7 +48,8 @@ module JamRuby
|
|||
end
|
||||
|
||||
def generate_signup_url(invited_user)
|
||||
"http://www.jamkazam.com/signup?invitation_code=#{invited_user.invitation_code}"
|
||||
invited_user.generate_signup_url
|
||||
# "http://www.jamkazam.com/signup?invitation_code=#{invited_user.invitation_code}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,13 +14,15 @@ module JamRuby
|
|||
belongs_to :sender , :inverse_of => :invited_users, :class_name => "JamRuby::User", :foreign_key => "sender_id"
|
||||
|
||||
# who is the invitation sent to?
|
||||
validates :email, :presence => true, format: {with: VALID_EMAIL_REGEX}
|
||||
validates :email, format: {with: VALID_EMAIL_REGEX}, :if => lambda { |iu| iu.email.present? }
|
||||
validates :autofriend, :inclusion => {:in => [nil, true, false]}
|
||||
validates :invitation_code, :presence => true
|
||||
validates :note, length: {maximum: 400}, no_profanity: true # 400 == arbitrary.
|
||||
|
||||
validate :one_facebook_invite_per_user, :if => lambda { |iu| iu.invite_medium == FB_MEDIUM }
|
||||
validate :valid_personalized_invitation
|
||||
validate :not_accepted_twice
|
||||
# validate :not_accepted_twice
|
||||
validate :not_accepted_twice, :if => lambda { |iu| iu.email }
|
||||
validate :can_invite?
|
||||
|
||||
after_save :track_user_progression
|
||||
|
|
@ -31,6 +33,12 @@ module JamRuby
|
|||
self.sender_id = nil if self.sender_id.blank? # this coercion was done just to make activeadmin work
|
||||
end
|
||||
|
||||
FB_MEDIUM = 'facebook'
|
||||
|
||||
def self.facebook_invite(user)
|
||||
where(:sender_id => user.id, :invite_medium => FB_MEDIUM).limit(1).first
|
||||
end
|
||||
|
||||
def track_user_progression
|
||||
self.sender.update_progression_field(:first_invited_at) unless self.sender.nil?
|
||||
end
|
||||
|
|
@ -54,6 +62,15 @@ module JamRuby
|
|||
def invited_by_administrator?
|
||||
sender.nil? || sender.admin # a nil sender can only be created by someone using jam-admin
|
||||
end
|
||||
|
||||
def generate_signup_url
|
||||
if 'development'==Rails.env
|
||||
"http://jamkazamdev.local:3000/signup?invitation_code=#{self.invitation_code}"
|
||||
else
|
||||
"http://www.jamkazam.com/signup?invitation_code=#{self.invitation_code}"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def can_invite?
|
||||
|
|
@ -67,5 +84,12 @@ module JamRuby
|
|||
def not_accepted_twice
|
||||
errors.add(:accepted, "you can only accept an invitation once") if accepted_twice
|
||||
end
|
||||
|
||||
def one_facebook_invite_per_user
|
||||
rel = InvitedUser.where(:invite_medium => FB_MEDIUM, :sender_id => self.sender_id)
|
||||
rel = rel.where(['id != ?',self.id]) if self.id
|
||||
errors.add(:invite_medium, "one facebook invite allowed per user") if 0 < rel.count
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ module JamRuby
|
|||
InvitedUserMailer.welcome_betauser(invited_user).deliver
|
||||
else
|
||||
InvitedUserMailer.friend_invitation(invited_user).deliver
|
||||
end
|
||||
end if invited_user.email.present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1007,9 +1007,20 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
#def first_recording_at
|
||||
# Recording.where(:owner_id => self.id).order('created_at ASC').first.try(:created_at)
|
||||
#end
|
||||
def first_recording_at
|
||||
Recording.where(:owner_id => self.id).order('created_at ASC').first.try(:created_at)
|
||||
end
|
||||
|
||||
def facebook_invite!
|
||||
unless iu = InvitedUser.facebook_invite(self)
|
||||
iu = InvitedUser.new
|
||||
iu.sender = self
|
||||
iu.autofriend = true
|
||||
iu.invite_medium = InvitedUser::FB_MEDIUM
|
||||
iu.save
|
||||
end
|
||||
iu
|
||||
end
|
||||
|
||||
# devise compatibility
|
||||
|
||||
|
|
|
|||
|
|
@ -104,4 +104,28 @@ describe InvitedUser do
|
|||
invited_user.valid?.should be_false
|
||||
end
|
||||
|
||||
it 'accepts empty emails' do
|
||||
user1 = FactoryGirl.create(:user)
|
||||
invited_user = FactoryGirl.create(:invited_user, :sender_id => user1.id, :email => '')
|
||||
expect(invited_user.valid?).to eq(true)
|
||||
end
|
||||
|
||||
it 'accepts one facebook invite per user' do
|
||||
user1 = FactoryGirl.create(:user)
|
||||
invited_user = FactoryGirl.create(:invited_user, :sender_id => user1.id, :invite_medium => InvitedUser::FB_MEDIUM)
|
||||
expect(invited_user.valid?).to eq(true)
|
||||
invited_user.autofriend = !invited_user.autofriend
|
||||
invited_user.save
|
||||
expect(invited_user.valid?).to eq(true)
|
||||
invited_user1 = InvitedUser.new(:email => 'foobar@example.com', :sender_id => user1.id)
|
||||
invited_user1.autofriend = true
|
||||
invited_user1.invite_medium = InvitedUser::FB_MEDIUM
|
||||
invited_user1.save
|
||||
expect(invited_user1.valid?).to eq(false)
|
||||
expect(InvitedUser.facebook_invite(user1).id).to eq(invited_user.id)
|
||||
user2 = FactoryGirl.create(:user)
|
||||
iu = user1.facebook_invite!
|
||||
expect(user1.facebook_invite!.id).to eq(iu.id)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -200,8 +200,8 @@
|
|||
invitationDialog.showGoogleDialog();
|
||||
});
|
||||
|
||||
$('div[layout-id="createSession"] .btn-facebook-invitation').click(function() {
|
||||
invitationDialog.showFacebookDialog();
|
||||
$('div[layout-id="createSession"] .btn-facebook-invitation').click(function(e) {
|
||||
invitationDialog.showFacebookDialog(e);
|
||||
});
|
||||
|
||||
$('#friend-input').focus(function() { $(this).val(''); })
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
(function(context,$) {
|
||||
|
||||
"use strict";
|
||||
context.JK = context.JK || {};
|
||||
context.JK.InvitationDialog = function(app) {
|
||||
|
|
@ -7,6 +6,7 @@
|
|||
var rest = context.JK.Rest();
|
||||
var waitForUserToStopTypingTimer;
|
||||
var sendingEmail = false;
|
||||
var fbInviteURL_ = null;
|
||||
|
||||
function trackMetrics(emails, googleInviteCount) {
|
||||
var allInvitations = emails.length; // all email invites, regardless of how they got in the form
|
||||
|
|
@ -153,47 +153,112 @@
|
|||
window._oauth_win = window.open("/auth/google_login", "_blank", "height=500,width=500,menubar=no,resizable=no,status=no");
|
||||
}
|
||||
|
||||
function showFacebookDialog() {
|
||||
/*
|
||||
$('#invitation-textarea-container').hide();
|
||||
$('#invitation-checkbox-container').show();
|
||||
$('#btn-send-invitation').hide();
|
||||
$('#btn-next-invitation').show();
|
||||
invitationDialog.showDialog();
|
||||
$('#invitation-checkboxes').html('<div style="text-align: center; margin-top: 100px;">Loading your contacts...</div>');
|
||||
*/
|
||||
window._oauth_callback = function() {
|
||||
window._oauth_win.close();
|
||||
window._oauth_win = null;
|
||||
window._oauth_callback = null;
|
||||
/*
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/gmail_contacts",
|
||||
success: function(response) {
|
||||
$('#invitation-checkboxes').html('');
|
||||
for (var i in response) {
|
||||
$('#invitation-checkboxes').append("<label><input type='checkbox' class='invitation-checkbox' data-email='" + response[i] + "' /> " + response[i] + "</label>");
|
||||
//////////////
|
||||
// FB handlers
|
||||
|
||||
// Additional initialization code such as adding Event Listeners goes here
|
||||
function handle_fblogin_response(response) {
|
||||
if (response.status === 'connected') {
|
||||
// the user is logged in and has authenticated your
|
||||
// app, and response.authResponse supplies
|
||||
// the user's ID, a valid access token, a signed
|
||||
// request, and the time the access token
|
||||
// and signed request each expire
|
||||
var uid = response.authResponse.userID;
|
||||
var accessToken = response.authResponse.accessToken;
|
||||
window.fb_logged_in_state = "connected";
|
||||
} else if (response.status === 'not_authorized') {
|
||||
// the user is logged in to Facebook,
|
||||
// but has not authenticated your app
|
||||
// TODO: popup authorization dialog
|
||||
window.fb_logged_in_state = "not_authorized";
|
||||
}
|
||||
else {
|
||||
// the user isn't logged in to Facebook.
|
||||
window.fb_logged_in_state = "not_logged_in";
|
||||
}
|
||||
}
|
||||
|
||||
$('.invitation-checkbox').change(function() {
|
||||
var checkedBoxes = $('.invitation-checkbox:checkbox:checked');
|
||||
var emails = '';
|
||||
for (var i = 0; i < checkedBoxes.length; i++) {
|
||||
emails += $(checkedBoxes[i]).data('email') + ', ';
|
||||
this.fb_login = function() {
|
||||
FB.login(function(response) {
|
||||
handle_fblogin_response(response);
|
||||
}, {scope:'publish_stream'});
|
||||
}
|
||||
emails = emails.replace(/, $/, '');
|
||||
$('#txt-emails').val(emails);
|
||||
});
|
||||
|
||||
function fbInviteURL() {
|
||||
if (fbInviteURL_ === null) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
async: false,
|
||||
url: '/api/invited_users/facebook',
|
||||
success: function(response) {
|
||||
fbInviteURL_ = response['signup_url'];
|
||||
},
|
||||
error: function() {
|
||||
$('#invitation-checkboxes').html("Load failed");
|
||||
}
|
||||
error: app.ajaxError
|
||||
});
|
||||
*/
|
||||
};
|
||||
window._oauth_win = window.open("/auth/facebook_login", "_blank", "height=500,width=500,menubar=no,resizable=no,status=no");
|
||||
}
|
||||
return fbInviteURL_;
|
||||
}
|
||||
|
||||
function show_feed_dialog() {
|
||||
var obj = {
|
||||
method: 'feed',
|
||||
link: fbInviteURL(),
|
||||
picture: 'http://jamkazam.com/assets/logo.png',
|
||||
name: 'Join me on JamKazam',
|
||||
caption: 'Play live music in real-time sessions with others over the Internet, as if in the same room.',
|
||||
description: '',
|
||||
actions: [{ name: 'Signup', link: fbInviteURL() }]
|
||||
};
|
||||
function fbFeedDialogCallback(response) {
|
||||
//console.log("feedback dialog closed: " + response['post_id'])
|
||||
}
|
||||
FB.ui(obj, fbFeedDialogCallback);
|
||||
}
|
||||
|
||||
function showFacebookDialog(evt) {
|
||||
if (!(evt === undefined)) evt.stopPropagation();
|
||||
|
||||
var fb_state = window.fb_logged_in_state;
|
||||
|
||||
if (fb_state == "connected") {
|
||||
show_feed_dialog();
|
||||
} else if (fb_state == "not_authorized") {
|
||||
this.fb_login();
|
||||
} else {
|
||||
this.fb_login();
|
||||
}
|
||||
}
|
||||
|
||||
function callFB(fbAppID){
|
||||
var fbAppID_ = fbAppID;
|
||||
window.fbAsyncInit = function() {
|
||||
FB.init({
|
||||
appId : fbAppID_,
|
||||
// channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html',
|
||||
status : true, // check the login status upon init?
|
||||
cookie : true, // set sessions cookies to allow server to access the session?
|
||||
xfbml : true, // parse XFBML tags on this page?
|
||||
oauth : true, // enable OAuth 2.0
|
||||
});
|
||||
// listen to see if the user is known/logged in
|
||||
FB.getLoginStatus(function(response) {
|
||||
handle_fblogin_response(response);
|
||||
});
|
||||
};
|
||||
|
||||
// Load the SDK Asynchronously
|
||||
(function(d){
|
||||
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
|
||||
js = d.createElement('script'); js.id = id; js.async = true;
|
||||
js.src = "//connect.facebook.net/en_US/all.js";
|
||||
d.getElementsByTagName('head')[0].appendChild(js);
|
||||
}(document));
|
||||
}
|
||||
|
||||
// END FB handlers
|
||||
//////////////
|
||||
|
||||
|
||||
function clearTextFields() {
|
||||
$('#txt-emails').val('').removeData('google_invite_count');
|
||||
|
|
@ -211,15 +276,16 @@
|
|||
registerEvents(false);
|
||||
}
|
||||
|
||||
function initialize(){
|
||||
function initialize(fbAppID){
|
||||
var dialogBindings = {
|
||||
'beforeShow' : beforeShow,
|
||||
'afterHide': afterHide
|
||||
};
|
||||
|
||||
app.bindDialog('inviteUsers', dialogBindings);
|
||||
};
|
||||
|
||||
callFB(fbAppID);
|
||||
};
|
||||
|
||||
this.initialize = initialize;
|
||||
this.showEmailDialog = showEmailDialog;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@
|
|||
|
||||
}
|
||||
|
||||
function showDialog() {
|
||||
app.layout.showDialog('share-dialog');
|
||||
}
|
||||
|
||||
/*function showEmailDialog() {
|
||||
$('#invitation-dialog').show();
|
||||
$('#invitation-textarea-container').show();
|
||||
|
|
@ -94,8 +98,8 @@
|
|||
app.bindDialog('shareSessionRecording', dialogBindings);
|
||||
};
|
||||
|
||||
|
||||
this.initialize = initialize;
|
||||
this.showDialog = showDialog;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
|
|||
|
|
@ -442,6 +442,11 @@
|
|||
invitationDialog.showGoogleDialog();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#sidebar-div .btn-facebook-invitation').click(function(evt) {
|
||||
invitationDialog.showFacebookDialog(evt);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function registerFriendUpdate() {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@
|
|||
invitationDialog.showEmailDialog();
|
||||
});
|
||||
|
||||
$('.invite-friends .facebook-invite a').on('click', function(e) {
|
||||
invitationDialog.showFacebookDialog(e);
|
||||
});
|
||||
|
||||
$('#header-avatar').on('avatar_changed', function(event, newAvatarUrl) {
|
||||
updateAvatar(newAvatarUrl);
|
||||
event.preventDefault();
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ ul.shortcuts {
|
|||
color:#FFCC00;
|
||||
}
|
||||
|
||||
li.google-invite, li.email-invite {
|
||||
li.google-invite, li.email-invite, li.facebook-invite {
|
||||
padding-left:9px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,12 @@ class ApiInvitedUsersController < ApiController
|
|||
end
|
||||
|
||||
def show
|
||||
if 'facebook' == params[:id]
|
||||
@invited_user = current_user.facebook_invite!
|
||||
else
|
||||
@invited_user = InvitedUser.find(params[:id])
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@invited_user = InvitedUser.new
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class UsersController < ApplicationController
|
|||
|
||||
@invited_user = load_invited_user(params)
|
||||
|
||||
if !@invited_user.nil? && @invited_user.accepted
|
||||
if !@invited_user.nil? && @invited_user.email && @invited_user.accepted
|
||||
# short-circuit out if this invitation is already accepted
|
||||
render "already_signed_up", :layout => 'landing'
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
object @invited_user
|
||||
|
||||
attributes :id, :created_at, :updated_at, :email, :note, :accepted
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
object @invited_user
|
||||
|
||||
extends "api_invited_users/invited_user"
|
||||
|
||||
node :signup_url do @invited_user.generate_signup_url end
|
||||
|
|
|
|||
|
|
@ -98,16 +98,14 @@
|
|||
</div>
|
||||
<div class="right mt5 ml5">E-mail</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="left mr20">
|
||||
<div class="left">
|
||||
<a id="btn-facebook-invitation">
|
||||
<a class="btn-facebook-invitation">
|
||||
<%= image_tag("content/icon_facebook.png", :size => "24x24", :align => "absmiddle") %>
|
||||
</a>
|
||||
</div>
|
||||
<div class="right mt5 ml5">Facebook</div>
|
||||
</div>
|
||||
-->
|
||||
<!-- <div class="left mr20">
|
||||
<div class="left">
|
||||
<a href="/#/createSession" title="This feature is not yet available.">
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@
|
|||
<%= render "addNewGear" %>
|
||||
<%= render "error" %>
|
||||
<%= render "sessionSettings" %>
|
||||
<%= render "shareDialog" %>
|
||||
<%= render :partial => "shareDialog", :locals => {} %>
|
||||
|
||||
<!-- Track Template -->
|
||||
<script type="text/template" id="template-session-track">
|
||||
|
|
|
|||
|
|
@ -69,6 +69,14 @@
|
|||
</div>
|
||||
<div class="right mt5 ml5">Google+</div>
|
||||
</div>
|
||||
<div class="left left">
|
||||
<div class="left">
|
||||
<a class="btn-facebook-invitation">
|
||||
<%= image_tag("content/icon_facebook.png", :size => "24x24", :align => "absmiddle") %>
|
||||
</a>
|
||||
</div>
|
||||
<div class="right mt5 ml5">Facebook</div>
|
||||
</div>
|
||||
</div>
|
||||
<br clear="all" />
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
<%= render "clients/banners/disconnected" %>
|
||||
<%= render "overlay_small" %>
|
||||
<%= render "help" %>
|
||||
<div id="fb-root"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
|
@ -95,7 +96,7 @@
|
|||
var recordingManager = new JK.RecordingManager();
|
||||
|
||||
var invitationDialog = new JK.InvitationDialog(JK.app);
|
||||
invitationDialog.initialize();
|
||||
invitationDialog.initialize('<%= SampleApp::Application.config.facebook_key %>');
|
||||
|
||||
var shareDialog = new JK.ShareDialog(JK.app);
|
||||
shareDialog.initialize();
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@
|
|||
|
||||
<%= javascript_include_tag "web/sessions" %>
|
||||
|
||||
<%= render "clients/shareDialog" %>
|
||||
<%= render :partial => "clients/shareDialog", :locals => {:session => @music_session} %>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
|
|
@ -98,6 +98,10 @@
|
|||
var shareDialog = new JK.ShareDialog(JK.app);
|
||||
shareDialog.initialize();
|
||||
|
||||
$("#btnShare").click(function(e) {
|
||||
shareDialog.showDialog();
|
||||
});
|
||||
|
||||
$("#txtSessionComment").keypress(function(e) {
|
||||
if (e.which === 13) {
|
||||
addComment();
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
|
||||
<%= javascript_include_tag "web/recordings" %>
|
||||
|
||||
<%= render "clients/shareDialog" %>
|
||||
<%= render :partial => "clients/shareDialog", :locals => {:recording => @claimed_recording} %>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
|
|
@ -97,6 +97,10 @@
|
|||
var shareDialog = new JK.ShareDialog(JK.app);
|
||||
shareDialog.initialize();
|
||||
|
||||
$("#btnShare").click(function(e) {
|
||||
shareDialog.showDialog();
|
||||
});
|
||||
|
||||
$("#txtRecordingComment").keypress(function(e) {
|
||||
if (e.which === 13) {
|
||||
addComment();
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
<ul class="shortcuts-submenu">
|
||||
<li class="google-invite"><%= link_to "Google", '#' %></li>
|
||||
<li class="email-invite"><%= link_to "Email", '#' %></li>
|
||||
<li class="facebook-invite"><%= link_to "Facebook", '#' %></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="download-app"><%= link_to "Download App", downloads_path, :rel => "external" %></li>
|
||||
|
|
|
|||
Loading…
Reference in New Issue