* merge
This commit is contained in:
commit
00d06fe6f2
|
|
@ -158,4 +158,6 @@ music_notation.sql
|
||||||
music_session_recurring_mode.sql
|
music_session_recurring_mode.sql
|
||||||
add_timezone_music_session.sql
|
add_timezone_music_session.sql
|
||||||
scheduled_sessions_2.sql
|
scheduled_sessions_2.sql
|
||||||
started_at_music_session.sql
|
scheduled_sessions_3.sql
|
||||||
|
scheduled_sessions_cancel_all.sql
|
||||||
|
scheduled_sessions_started_at.sql
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
alter table rsvp_requests_rsvp_slots alter column chosen set DEFAULT NULL;
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
alter table rsvp_requests add column cancel_all BOOLEAN DEFAULT FALSE;
|
||||||
|
|
@ -592,25 +592,23 @@ module JamRuby
|
||||||
|
|
||||||
notification_msg = format_msg(notification.description, {:user => source_user, :session => music_session})
|
notification_msg = format_msg(notification.description, {:user => source_user, :session => music_session})
|
||||||
|
|
||||||
if target_user.online
|
msg = @@message_factory.scheduled_session_invitation(
|
||||||
msg = @@message_factory.scheduled_session_invitation(
|
target_user.id,
|
||||||
target_user.id,
|
music_session.id,
|
||||||
music_session.id,
|
source_user.photo_url,
|
||||||
source_user.photo_url,
|
notification_msg,
|
||||||
notification_msg,
|
music_session.description,
|
||||||
music_session.description,
|
music_session.scheduled_start,
|
||||||
music_session.scheduled_start,
|
notification.id,
|
||||||
notification.id,
|
notification.created_date
|
||||||
notification.created_date
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@@mq_router.publish_to_user(target_user.id, msg)
|
@@mq_router.publish_to_user(target_user.id, msg)
|
||||||
else
|
|
||||||
begin
|
begin
|
||||||
UserMailer.scheduled_session_invitation(target_user.email, notification_msg, music_session).deliver
|
UserMailer.scheduled_session_invitation(target_user.email, notification_msg, music_session).deliver
|
||||||
rescue => e
|
rescue => e
|
||||||
@@log.error("Unable to send scheduled_session_invitation email to offline user #{target_user.email} #{e}")
|
@@log.error("Unable to send scheduled_session_invitation email to offline user #{target_user.email} #{e}")
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -630,31 +628,28 @@ module JamRuby
|
||||||
|
|
||||||
notification_msg = format_msg(notification.description, {:user => source_user, :session => music_session})
|
notification_msg = format_msg(notification.description, {:user => source_user, :session => music_session})
|
||||||
|
|
||||||
if target_user.online
|
msg = @@message_factory.scheduled_session_rsvp(
|
||||||
msg = @@message_factory.scheduled_session_rsvp(
|
target_user.id,
|
||||||
target_user.id,
|
music_session.id,
|
||||||
music_session.id,
|
source_user.photo_url,
|
||||||
source_user.photo_url,
|
notification_msg,
|
||||||
notification_msg,
|
source_user.id,
|
||||||
source_user.id,
|
instruments.join('|'),
|
||||||
instruments,
|
music_session.description,
|
||||||
music_session.description,
|
music_session.scheduled_start,
|
||||||
music_session.scheduled_start,
|
notification.id,
|
||||||
notification.id,
|
notification.created_date
|
||||||
notification.created_date
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@@mq_router.publish_to_user(target_user.id, msg)
|
@@mq_router.publish_to_user(target_user.id, msg)
|
||||||
else
|
begin
|
||||||
begin
|
UserMailer.scheduled_session_rsvp(target_user.email, notification_msg, music_session).deliver
|
||||||
UserMailer.scheduled_session_rsvp(target_user.email, notification_msg, music_session).deliver
|
rescue => e
|
||||||
rescue => e
|
@@log.error("Unable to send scheduled_session_rsvp email to offline user #{target_user.email} #{e}")
|
||||||
@@log.error("Unable to send scheduled_session_rsvp email to offline user #{target_user.email} #{e}")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_scheduled_session_rsvp_approved(music_session, user)
|
def send_scheduled_session_rsvp_approved(music_session, user, instruments)
|
||||||
|
|
||||||
return if music_session.nil? || user.nil?
|
return if music_session.nil? || user.nil?
|
||||||
|
|
||||||
|
|
@ -670,24 +665,21 @@ module JamRuby
|
||||||
|
|
||||||
notification_msg = format_msg(notification.description, {:session => music_session})
|
notification_msg = format_msg(notification.description, {:session => music_session})
|
||||||
|
|
||||||
if target_user.online
|
msg = @@message_factory.scheduled_session_rsvp_approved(
|
||||||
msg = @@message_factory.scheduled_session_rsvp_approved(
|
target_user.id,
|
||||||
target_user.id,
|
music_session.id,
|
||||||
music_session.id,
|
notification_msg,
|
||||||
notification_msg,
|
music_session.description,
|
||||||
music_session.description,
|
music_session.scheduled_start,
|
||||||
music_session.scheduled_start,
|
notification.id,
|
||||||
notification.id,
|
notification.created_date
|
||||||
notification.created_date
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@@mq_router.publish_to_user(target_user.id, msg)
|
@@mq_router.publish_to_user(target_user.id, msg)
|
||||||
else
|
begin
|
||||||
begin
|
UserMailer.scheduled_session_rsvp_approved(target_user.email, notification_msg, music_session).deliver
|
||||||
UserMailer.scheduled_session_rsvp_approved(target_user.email, notification_msg, music_session).deliver
|
rescue => e
|
||||||
rescue => e
|
@@log.error("Unable to send scheduled_session_rsvp_approved email to offline user #{target_user.email} #{e}")
|
||||||
@@log.error("Unable to send scheduled_session_rsvp_approved email to offline user #{target_user.email} #{e}")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -707,24 +699,22 @@ module JamRuby
|
||||||
|
|
||||||
notification_msg = format_msg(notification.description, {:session => music_session})
|
notification_msg = format_msg(notification.description, {:session => music_session})
|
||||||
|
|
||||||
if target_user.online
|
msg = @@message_factory.scheduled_session_rsvp_cancelled(
|
||||||
msg = @@message_factory.scheduled_session_rsvp_cancelled(
|
target_user.id,
|
||||||
target_user.id,
|
music_session.id,
|
||||||
music_session.id,
|
notification_msg,
|
||||||
notification_msg,
|
music_session.description,
|
||||||
music_session.description,
|
music_session.scheduled_start,
|
||||||
music_session.scheduled_start,
|
notification.id,
|
||||||
notification.id,
|
notification.created_date
|
||||||
notification.created_date
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@@mq_router.publish_to_user(target_user.id, msg)
|
@@mq_router.publish_to_user(target_user.id, msg)
|
||||||
else
|
|
||||||
begin
|
begin
|
||||||
UserMailer.send_scheduled_session_rsvp_cancelled(target_user.email, notification_msg, music_session).deliver
|
UserMailer.send_scheduled_session_rsvp_cancelled(target_user.email, notification_msg, music_session).deliver
|
||||||
rescue => e
|
rescue => e
|
||||||
@@log.error("Unable to send send_scheduled_session_rsvp_cancelled email to offline user #{target_user.email} #{e}")
|
@@log.error("Unable to send send_scheduled_session_rsvp_cancelled email to offline user #{target_user.email} #{e}")
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -744,24 +734,22 @@ module JamRuby
|
||||||
|
|
||||||
notification_msg = format_msg(notification.description, {:session => music_session})
|
notification_msg = format_msg(notification.description, {:session => music_session})
|
||||||
|
|
||||||
if target_user.online
|
msg = @@message_factory.scheduled_session_rsvp_cancelled_org(
|
||||||
msg = @@message_factory.scheduled_session_rsvp_cancelled_org(
|
target_user.id,
|
||||||
target_user.id,
|
music_session.id,
|
||||||
music_session.id,
|
notification_msg,
|
||||||
notification_msg,
|
music_session.description,
|
||||||
music_session.description,
|
music_session.scheduled_start,
|
||||||
music_session.scheduled_start,
|
notification.id,
|
||||||
notification.id,
|
notification.created_date
|
||||||
notification.created_date
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@@mq_router.publish_to_user(target_user.id, msg)
|
@@mq_router.publish_to_user(target_user.id, msg)
|
||||||
else
|
|
||||||
begin
|
begin
|
||||||
UserMailer.scheduled_session_rsvp_cancelled_org(target_user.email, notification_msg, music_session).deliver
|
UserMailer.scheduled_session_rsvp_cancelled_org(target_user.email, notification_msg, music_session).deliver
|
||||||
rescue => e
|
rescue => e
|
||||||
@@log.error("Unable to send scheduled_session_rsvp_cancelled_org email to offline user #{target_user.email} #{e}")
|
@@log.error("Unable to send scheduled_session_rsvp_cancelled_org email to offline user #{target_user.email} #{e}")
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -769,7 +757,9 @@ module JamRuby
|
||||||
|
|
||||||
return if music_session.nil?
|
return if music_session.nil?
|
||||||
|
|
||||||
rsvp_requests = RsvpRequest.requests_by_session(music_session)
|
# TODO: notify invitees who have not RSVP'ed
|
||||||
|
|
||||||
|
rsvp_requests = RsvpRequest.index(music_session)
|
||||||
|
|
||||||
rsvp_requests.each do |rsvp|
|
rsvp_requests.each do |rsvp|
|
||||||
target_user = rsvp.user
|
target_user = rsvp.user
|
||||||
|
|
@ -784,24 +774,22 @@ module JamRuby
|
||||||
|
|
||||||
notification_msg = format_msg(notification.description, {:session => music_session})
|
notification_msg = format_msg(notification.description, {:session => music_session})
|
||||||
|
|
||||||
if target_user.online
|
msg = @@message_factory.scheduled_session_cancelled(
|
||||||
msg = @@message_factory.scheduled_session_cancelled(
|
target_user.id,
|
||||||
target_user.id,
|
music_session.id,
|
||||||
music_session.id,
|
notification_msg,
|
||||||
notification_msg,
|
music_session.description,
|
||||||
music_session.description,
|
music_session.scheduled_start,
|
||||||
music_session.scheduled_start,
|
notification.id,
|
||||||
notification.id,
|
notification.created_date
|
||||||
notification.created_date
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@@mq_router.publish_to_user(target_user.id, msg)
|
@@mq_router.publish_to_user(target_user.id, msg)
|
||||||
else
|
|
||||||
begin
|
begin
|
||||||
UserMailer.scheduled_session_cancelled(target_user.email, notification_msg, music_session).deliver
|
UserMailer.scheduled_session_cancelled(target_user.email, notification_msg, music_session).deliver
|
||||||
rescue => e
|
rescue => e
|
||||||
@@log.error("Unable to send scheduled_session_cancelled email to offline user #{target_user.email} #{e}")
|
@@log.error("Unable to send scheduled_session_cancelled email to offline user #{target_user.email} #{e}")
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -810,7 +798,7 @@ module JamRuby
|
||||||
|
|
||||||
return if music_session.nil?
|
return if music_session.nil?
|
||||||
|
|
||||||
rsvp_requests = RsvpRequest.requests_by_session(music_session)
|
rsvp_requests = RsvpRequest.index(music_session)
|
||||||
|
|
||||||
rsvp_requests.each do |rsvp|
|
rsvp_requests.each do |rsvp|
|
||||||
target_user = rsvp.user
|
target_user = rsvp.user
|
||||||
|
|
@ -825,24 +813,22 @@ module JamRuby
|
||||||
|
|
||||||
notification_msg = format_msg(notification.description, {:session => music_session})
|
notification_msg = format_msg(notification.description, {:session => music_session})
|
||||||
|
|
||||||
if target_user.online
|
msg = @@message_factory.scheduled_session_rescheduled(
|
||||||
msg = @@message_factory.scheduled_session_rescheduled(
|
target_user.id,
|
||||||
target_user.id,
|
music_session.id,
|
||||||
music_session.id,
|
notification_msg,
|
||||||
notification_msg,
|
music_session.description,
|
||||||
music_session.description,
|
music_session.scheduled_start,
|
||||||
music_session.scheduled_start,
|
notification.id,
|
||||||
notification.id,
|
notification.created_date
|
||||||
notification.created_date
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@@mq_router.publish_to_user(target_user.id, msg)
|
@@mq_router.publish_to_user(target_user.id, msg)
|
||||||
else
|
|
||||||
begin
|
begin
|
||||||
UserMailer.scheduled_session_rescheduled(target_user.email, notification_msg, music_session).deliver
|
UserMailer.scheduled_session_rescheduled(target_user.email, notification_msg, music_session).deliver
|
||||||
rescue => e
|
rescue => e
|
||||||
@@log.error("Unable to send scheduled_session_rescheduled email to offline user #{target_user.email} #{e}")
|
@@log.error("Unable to send scheduled_session_rescheduled email to offline user #{target_user.email} #{e}")
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -851,7 +837,7 @@ module JamRuby
|
||||||
|
|
||||||
return if music_session.nil?
|
return if music_session.nil?
|
||||||
|
|
||||||
rsvp_requests = RsvpRequest.requests_by_session(music_session)
|
rsvp_requests = RsvpRequest.index(music_session)
|
||||||
|
|
||||||
rsvp_requests.each do |rsvp|
|
rsvp_requests.each do |rsvp|
|
||||||
target_user = rsvp.user
|
target_user = rsvp.user
|
||||||
|
|
@ -866,40 +852,38 @@ module JamRuby
|
||||||
|
|
||||||
notification_msg = format_msg(notification.description, {:session => music_session})
|
notification_msg = format_msg(notification.description, {:session => music_session})
|
||||||
|
|
||||||
if target_user.online
|
msg = @@message_factory.scheduled_session_reminder(
|
||||||
msg = @@message_factory.scheduled_session_reminder(
|
target_user.id,
|
||||||
target_user.id,
|
music_session.id,
|
||||||
music_session.id,
|
notification_msg,
|
||||||
notification_msg,
|
music_session.description,
|
||||||
music_session.description,
|
music_session.scheduled_start,
|
||||||
music_session.scheduled_start,
|
notification.id,
|
||||||
notification.id,
|
notification.created_date
|
||||||
notification.created_date
|
)
|
||||||
)
|
|
||||||
|
|
||||||
@@mq_router.publish_to_user(target_user.id, msg)
|
@@mq_router.publish_to_user(target_user.id, msg)
|
||||||
else
|
|
||||||
begin
|
begin
|
||||||
UserMailer.scheduled_session_reminder(target_user.email, notification_msg, music_session).deliver
|
UserMailer.scheduled_session_reminder(target_user.email, notification_msg, music_session).deliver
|
||||||
rescue => e
|
rescue => e
|
||||||
@@log.error("Unable to send scheduled_session_reminder email to offline user #{target_user.email} #{e}")
|
@@log.error("Unable to send scheduled_session_reminder email to offline user #{target_user.email} #{e}")
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_scheduled_session_comment(music_session, comment)
|
def send_scheduled_session_comment(music_session, creator, comment)
|
||||||
|
|
||||||
return if music_session.nil? || comment.blank?
|
return if music_session.nil? || comment.blank?
|
||||||
|
|
||||||
rsvp_requests = RsvpRequest.requests_by_session(music_session)
|
rsvp_requests = RsvpRequest.index(music_session)
|
||||||
|
|
||||||
rsvp_requests.each do |rsvp|
|
rsvp_requests.each do |rsvp|
|
||||||
target_user = rsvp.user
|
target_user = rsvp.user
|
||||||
source_user = music_session.creator
|
source_user = creator
|
||||||
|
|
||||||
notification = Notification.new
|
notification = Notification.new
|
||||||
notification.description = NotificationTypes::SCHEDULED_SESSION_CANCELLED
|
notification.description = NotificationTypes::SCHEDULED_SESSION_COMMENT
|
||||||
notification.source_user_id = source_user.id
|
notification.source_user_id = source_user.id
|
||||||
notification.target_user_id = target_user.id
|
notification.target_user_id = target_user.id
|
||||||
notification.session_id = music_session.id
|
notification.session_id = music_session.id
|
||||||
|
|
@ -907,25 +891,24 @@ module JamRuby
|
||||||
|
|
||||||
notification_msg = format_msg(notification.description, {:session => music_session})
|
notification_msg = format_msg(notification.description, {:session => music_session})
|
||||||
|
|
||||||
if target_user.online
|
msg = @@message_factory.scheduled_session_comment(
|
||||||
msg = @@message_factory.scheduled_session_comment(
|
target_user.id,
|
||||||
target_user.id,
|
music_session.id,
|
||||||
music_session.id,
|
target_user.photo_url,
|
||||||
notification_msg,
|
notification_msg,
|
||||||
comment,
|
comment,
|
||||||
music_session.description,
|
music_session.description,
|
||||||
music_session.scheduled_start,
|
music_session.scheduled_start,
|
||||||
notification.id,
|
notification.id,
|
||||||
notification.created_date
|
notification.created_date
|
||||||
)
|
)
|
||||||
|
|
||||||
@@mq_router.publish_to_user(target_user.id, msg)
|
@@mq_router.publish_to_user(target_user.id, msg)
|
||||||
else
|
|
||||||
begin
|
begin
|
||||||
UserMailer.scheduled_session_comment(target_user.email, notification_msg, comment, music_session).deliver
|
UserMailer.scheduled_session_comment(target_user.email, notification_msg, comment, music_session).deliver
|
||||||
rescue => e
|
rescue => e
|
||||||
@@log.error("Unable to send scheduled_session_comment email to offline user #{target_user.email} #{e}")
|
@@log.error("Unable to send scheduled_session_comment email to offline user #{target_user.email} #{e}")
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,12 @@ module JamRuby
|
||||||
class RsvpRequest < ActiveRecord::Base
|
class RsvpRequest < ActiveRecord::Base
|
||||||
|
|
||||||
belongs_to :user, :class_name => "JamRuby::User"
|
belongs_to :user, :class_name => "JamRuby::User"
|
||||||
has_many :rsvp_request_rsvp_slots, :class_name => "JamRuby::RsvpRequestRsvpSlot"
|
has_many :rsvp_requests_rsvp_slots, :class_name => "JamRuby::RsvpRequestRsvpSlot", :foreign_key => "rsvp_request_id"
|
||||||
has_many :rsvp_slots, :class_name => "JamRuby::RsvpSlot", :through => :rsvp_requests_rsvp_slots
|
has_many :rsvp_slots, :class_name => "JamRuby::RsvpSlot", :through => :rsvp_requests_rsvp_slots
|
||||||
|
|
||||||
# validates :message, length: {maximum: 1000}, no_profanity: true
|
|
||||||
|
|
||||||
validates :canceled, :inclusion => {:in => [nil, true, false]}
|
validates :canceled, :inclusion => {:in => [nil, true, false]}
|
||||||
|
|
||||||
# def self.create(params)
|
def self.index(music_session, user = nil)
|
||||||
# # slot_ids =
|
|
||||||
# rsvp = RsvpRequest.new
|
|
||||||
# # rsv
|
|
||||||
# rsvp.save
|
|
||||||
# end
|
|
||||||
|
|
||||||
def self.requests_by_session(session, user = nil)
|
|
||||||
query = RsvpRequest
|
query = RsvpRequest
|
||||||
.includes(:user)
|
.includes(:user)
|
||||||
.joins(
|
.joins(
|
||||||
|
|
@ -32,16 +23,226 @@ module JamRuby
|
||||||
)
|
)
|
||||||
.where(
|
.where(
|
||||||
%Q{
|
%Q{
|
||||||
rs.music_session_id = '#{session.id}'
|
rs.music_session_id = '#{music_session.id}'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
query = query.where("rsvp_requests.user_id = '#{user.id}'") unless user.nil?
|
query = query.where("rsvp_requests.user_id = ?", user.id) unless user.nil?
|
||||||
return query
|
return query.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
# XXX we need to validate that only one RsvpRequest.chosen = true for a given RsvpSlot
|
def self.create(params, user)
|
||||||
# in other words, you can have many requests to a slot, but only 0 or 1 rsvp_request.chosen = true)
|
music_session = MusicSession.find_by_id(params[:session_id])
|
||||||
|
|
||||||
|
# verify music session exists
|
||||||
|
if music_session.nil?
|
||||||
|
raise StateError, "Invalid session."
|
||||||
|
end
|
||||||
|
|
||||||
|
# verify invitation exists for this user and session
|
||||||
|
invitation = Invitation.where("music_session_id = ? AND receiver_id = ?", music_session.id, user.id)
|
||||||
|
|
||||||
|
if invitation.blank?
|
||||||
|
raise PermissionError, "Only a session invitee can create an RSVP."
|
||||||
|
end
|
||||||
|
|
||||||
|
# verify slot IDs exist in request
|
||||||
|
if params[:rsvp_slots].blank?
|
||||||
|
raise StateError, "You must select at least 1 slot."
|
||||||
|
end
|
||||||
|
|
||||||
|
RsvpRequest.transaction do
|
||||||
|
@rsvp = RsvpRequest.new
|
||||||
|
@rsvp.user = user
|
||||||
|
|
||||||
|
slot_ids = params[:rsvp_slots]
|
||||||
|
instruments = []
|
||||||
|
|
||||||
|
# for each slot requested, do the following:
|
||||||
|
# (1) verify slot exists in db
|
||||||
|
# (2) verify slot is not already chosen
|
||||||
|
# (3) verify user has not already requested this slot
|
||||||
|
# (4) create RsvpRequestRsvpSlot
|
||||||
|
# (5) create RsvpRequest
|
||||||
|
slot_ids.each do |id|
|
||||||
|
rsvp_slot = RsvpSlot.where(:id => id).first
|
||||||
|
|
||||||
|
# verify slot exists in db
|
||||||
|
if rsvp_slot.nil?
|
||||||
|
raise StateError, "Invalid slot #{id}."
|
||||||
|
end
|
||||||
|
|
||||||
|
# verify user has not already submitted RSVP request for this slot
|
||||||
|
user_slot = RsvpRequest.joins(:rsvp_requests_rsvp_slots)
|
||||||
|
.where(:user_id => user.id)
|
||||||
|
.where(rsvp_requests_rsvp_slots: {rsvp_slot_id: id})
|
||||||
|
|
||||||
|
if !user_slot.blank?
|
||||||
|
raise StateError, "You have already submitted an RSVP request for this slot."
|
||||||
|
end
|
||||||
|
|
||||||
|
chosen_slot = rsvp_slot.rsvp_requests_rsvp_slots.where("chosen = true").first
|
||||||
|
|
||||||
|
# verify this slot was not already chosen
|
||||||
|
if !chosen_slot.nil?
|
||||||
|
raise StateError, "The #{rsvp_slot.instrument_id} slot has already been approved by the session organizer."
|
||||||
|
else
|
||||||
|
rsvp_request_rsvp_slot = RsvpRequestRsvpSlot.new
|
||||||
|
rsvp_request_rsvp_slot.rsvp_request = @rsvp
|
||||||
|
rsvp_request_rsvp_slot.rsvp_slot = rsvp_slot
|
||||||
|
rsvp_request_rsvp_slot.save
|
||||||
|
|
||||||
|
instruments << rsvp_slot.instrument_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@rsvp.save
|
||||||
|
|
||||||
|
unless params[:message].blank?
|
||||||
|
session_info_comment = SessionInfoComment.new
|
||||||
|
session_info_comment.music_session = music_session
|
||||||
|
session_info_comment.user = user
|
||||||
|
session_info_comment.comment = params[:message]
|
||||||
|
session_info_comment.save
|
||||||
|
end
|
||||||
|
|
||||||
|
Notification.send_scheduled_session_rsvp(music_session, user, instruments)
|
||||||
|
Notification.send_scheduled_session_comment(music_session, user, params[:message])
|
||||||
|
|
||||||
|
@rsvp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.update(params, user)
|
||||||
|
|
||||||
|
rsvp_request_id = params[:id]
|
||||||
|
|
||||||
|
music_session = MusicSession.find_by_id(params[:session_id])
|
||||||
|
|
||||||
|
# verify music session exists
|
||||||
|
if music_session.nil?
|
||||||
|
raise StateError, "Invalid session."
|
||||||
|
end
|
||||||
|
|
||||||
|
# authorize the user attempting to respond to the RSVP request
|
||||||
|
if music_session.creator.id != user.id
|
||||||
|
raise PermissionError, "Only the session organizer can accept or decline and RSVP request."
|
||||||
|
end
|
||||||
|
|
||||||
|
rsvp_request = RsvpRequest.find_by_id(rsvp_request_id)
|
||||||
|
|
||||||
|
if rsvp_request.nil?
|
||||||
|
raise StateError, "Invalid RSVP request."
|
||||||
|
end
|
||||||
|
|
||||||
|
RsvpRequest.transaction do
|
||||||
|
rsvp_responses = params[:rsvp_responses]
|
||||||
|
if !rsvp_responses.blank?
|
||||||
|
instruments = []
|
||||||
|
accepted_slot = false
|
||||||
|
|
||||||
|
rsvp_responses.each do |r|
|
||||||
|
request_slot_id = r[:request_slot_id]
|
||||||
|
request_slot = RsvpRequestRsvpSlot.find_by_id(request_slot_id)
|
||||||
|
if request_slot.nil?
|
||||||
|
raise StateError, "Invalid request slot #{request_slot_id}."
|
||||||
|
end
|
||||||
|
|
||||||
|
rsvp_slot = RsvpSlot.find_by_id(request_slot.rsvp_slot_id)
|
||||||
|
if rsvp_slot.nil?
|
||||||
|
raise StateError, "Slot does not exist"
|
||||||
|
end
|
||||||
|
|
||||||
|
if rsvp_slot.chosen
|
||||||
|
raise StateError, "The #{rsvp_slot.instrument_id} slot has already been approved for another user."
|
||||||
|
end
|
||||||
|
|
||||||
|
if r[:accept]
|
||||||
|
accepted_slot = true
|
||||||
|
request_slot.chosen = true
|
||||||
|
request_slot.save
|
||||||
|
|
||||||
|
instruments << rsvp_slot.instrument_id
|
||||||
|
|
||||||
|
else
|
||||||
|
request_slot.chosen = false
|
||||||
|
request_slot.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# send notification if at least 1 slot was approved
|
||||||
|
if accepted_slot
|
||||||
|
Notification.send_scheduled_session_rsvp_approved(music_session, user, instruments)
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
raise StateError, "Invalid request."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.cancel(params, user)
|
||||||
|
if params[:id].blank?
|
||||||
|
raise StateError, "RSVP request ID is required."
|
||||||
|
end
|
||||||
|
|
||||||
|
if params[:session_id].blank?
|
||||||
|
raise StateError, "Session ID is required."
|
||||||
|
end
|
||||||
|
|
||||||
|
music_session = MusicSession.find(params[:session_id])
|
||||||
|
rsvp_request = RsvpRequest.find(params[:id])
|
||||||
|
|
||||||
|
if music_session.creator.id != user.id && rsvp_request.user_id != user.id
|
||||||
|
raise PermissionError, "Only the session organizer or RSVP creator can cancel the RSVP."
|
||||||
|
end
|
||||||
|
|
||||||
|
RsvpRequest.transaction do
|
||||||
|
|
||||||
|
case params[:cancelled]
|
||||||
|
when 'yes'
|
||||||
|
rsvp_request.canceled = true
|
||||||
|
rsvp_request.cancel_all = false
|
||||||
|
|
||||||
|
when 'no'
|
||||||
|
rsvp_request.canceled = false
|
||||||
|
rsvp_request.cancel_all = false
|
||||||
|
|
||||||
|
when 'all'
|
||||||
|
rsvp_request.canceled = true
|
||||||
|
rsvp_request.cancel_all = true
|
||||||
|
end
|
||||||
|
|
||||||
|
rsvp_request.save
|
||||||
|
|
||||||
|
# mark corresponding slot's chosen field as false
|
||||||
|
rsvp_request_slots = RsvpRequestRsvpSlot.where("rsvp_request_id = ?", rsvp_request.id)
|
||||||
|
|
||||||
|
rsvp_request_slots.each do |slot|
|
||||||
|
if slot.chosen
|
||||||
|
slot.chosen = false
|
||||||
|
slot.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# send notification
|
||||||
|
if music_session.creator.id == user.id
|
||||||
|
Notification.send_scheduled_session_rsvp_cancelled_org(music_session, user)
|
||||||
|
else
|
||||||
|
Notification.send_scheduled_session_rsvp_cancelled(music_session, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless params[:message].blank?
|
||||||
|
session_info_comment = SessionInfoComment.new
|
||||||
|
session_info_comment.music_session = music_session
|
||||||
|
session_info_comment.user = user
|
||||||
|
session_info_comment.comment = params[:message]
|
||||||
|
session_info_comment.save
|
||||||
|
end
|
||||||
|
|
||||||
|
Notification.send_scheduled_session_comment(music_session, user, params[:message])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,26 @@ module JamRuby
|
||||||
|
|
||||||
belongs_to :instrument, :class_name => "JamRuby::Instrument"
|
belongs_to :instrument, :class_name => "JamRuby::Instrument"
|
||||||
belongs_to :music_session
|
belongs_to :music_session
|
||||||
has_many :rsvp_requests_rsvp_slots, :class_name => "JamRuby::RsvpRequestRsvpSlot"
|
has_many :rsvp_requests_rsvp_slots, :class_name => "JamRuby::RsvpRequestRsvpSlot", :foreign_key => "rsvp_slot_id"
|
||||||
has_many :rsvp_requests, :class_name => "JamRuby::RsvpRequest", :through => :rsvp_requests_rsvp_slots
|
has_many :rsvp_requests, :class_name => "JamRuby::RsvpRequest", :through => :rsvp_requests_rsvp_slots
|
||||||
|
|
||||||
|
attr_accessor :chosen
|
||||||
|
|
||||||
# TODO: validates :proficiency_level
|
# TODO: validates :proficiency_level
|
||||||
|
|
||||||
|
def self.index(music_session)
|
||||||
|
RsvpSlot.where("music_session_id = ?", music_session.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def chosen
|
||||||
|
chosen_slots = RsvpRequestRsvpSlot.where("chosen = true AND rsvp_slot_id = ?", self.id)
|
||||||
|
!chosen_slots.blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
# def has_rsvp_from_user(user)
|
||||||
|
# user_slot = RsvpRequest.joins(:rsvp_requests_rsvp_slots)
|
||||||
|
# .where(:rsvp_request_id => )
|
||||||
|
# .where(:user_id => user.id)
|
||||||
|
# end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,10 @@ module JamRuby
|
||||||
|
|
||||||
default_scope order('created_at DESC')
|
default_scope order('created_at DESC')
|
||||||
|
|
||||||
belongs_to(:music_session,
|
belongs_to(:music_session, :class_name => "JamRuby::MusicSession", :foreign_key => "music_session_id")
|
||||||
:class_name => "JamRuby::MusicSession",
|
belongs_to(:user, :class_name => "JamRuby::User", :foreign_key => "creator_id")
|
||||||
:foreign_key => "music_session_id")
|
|
||||||
|
|
||||||
belongs_to(:user,
|
# validates :comment, length: {maximum: 1000}, no_profanity: true
|
||||||
:class_name => "JamRuby::User",
|
|
||||||
:foreign_key => "creator_id")
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -468,13 +468,18 @@ FactoryGirl.define do
|
||||||
factory :rsvp_slot, class: JamRuby::RsvpSlot do
|
factory :rsvp_slot, class: JamRuby::RsvpSlot do
|
||||||
association :instrument, factory: :instrument
|
association :instrument, factory: :instrument
|
||||||
association :music_session, factory: :music_session
|
association :music_session, factory: :music_session
|
||||||
|
association :rsvp_request_slot, factory: :rsvp_request_slot
|
||||||
proficiency_level 'beginner'
|
proficiency_level 'beginner'
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :rsvp_request, class: JamRuby::RsvpRequest do
|
factory :rsvp_request, class: JamRuby::RsvpRequest do
|
||||||
association :user, factory: :user
|
association :user, factory: :user
|
||||||
# association :rsvp_slot, factory: :rsvp_slot
|
association :rsvp_slot, factory: :rsvp_slot
|
||||||
# chosen false
|
association :rsvp_request_slot, factory: :rsvp_request_slot
|
||||||
canceled false
|
canceled false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :rsvp_request_slot, class: JamRuby::RsvpRequestRsvpSlot do
|
||||||
|
chosen false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -135,10 +135,10 @@ describe Notification do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "send scheduled session invitation" do
|
describe "send scheduled session invitation" do
|
||||||
it "sends live notification when user is online" do
|
it "sends pop-up notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends email notification when user is offline" do
|
it "sends email notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends no notification if session is nil" do
|
it "sends no notification if session is nil" do
|
||||||
|
|
@ -161,10 +161,10 @@ describe Notification do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "send scheduled session rsvp" do
|
describe "send scheduled session rsvp" do
|
||||||
it "sends live notification when user is online" do
|
it "sends pop-up notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends email notification when user is offline" do
|
it "sends email notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends no notification if session is nil" do
|
it "sends no notification if session is nil" do
|
||||||
|
|
@ -187,16 +187,16 @@ describe Notification do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "send scheduled session rsvp approved" do
|
describe "send scheduled session rsvp approved" do
|
||||||
it "sends live notification when user is online" do
|
it "sends pop-up notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends email notification when user is offline" do
|
it "sends email notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends no notification if session is nil" do
|
it "sends no notification if session is nil" do
|
||||||
receiver = FactoryGirl.create(:user)
|
receiver = FactoryGirl.create(:user)
|
||||||
calls = count_publish_to_user_calls
|
calls = count_publish_to_user_calls
|
||||||
notification = Notification.send_scheduled_session_rsvp_approved(nil, receiver)
|
notification = Notification.send_scheduled_session_rsvp_approved(nil, receiver, nil)
|
||||||
|
|
||||||
UserMailer.deliveries.length.should == 0
|
UserMailer.deliveries.length.should == 0
|
||||||
calls[:count].should == 0
|
calls[:count].should == 0
|
||||||
|
|
@ -205,7 +205,7 @@ describe Notification do
|
||||||
it "sends no notification if user is nil" do
|
it "sends no notification if user is nil" do
|
||||||
session = FactoryGirl.create(:music_session)
|
session = FactoryGirl.create(:music_session)
|
||||||
calls = count_publish_to_user_calls
|
calls = count_publish_to_user_calls
|
||||||
notification = Notification.send_scheduled_session_rsvp_approved(session, nil)
|
notification = Notification.send_scheduled_session_rsvp_approved(session, nil, nil)
|
||||||
|
|
||||||
UserMailer.deliveries.length.should == 0
|
UserMailer.deliveries.length.should == 0
|
||||||
calls[:count].should == 0
|
calls[:count].should == 0
|
||||||
|
|
@ -213,12 +213,11 @@ describe Notification do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "send scheduled session rsvp cancellation" do
|
describe "send scheduled session rsvp cancellation" do
|
||||||
it "sends live notification when user is online" do
|
it "sends pop-up notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends email notification when user is offline" do
|
it "sends email notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends no notification if session is nil" do
|
it "sends no notification if session is nil" do
|
||||||
sender = FactoryGirl.create(:user)
|
sender = FactoryGirl.create(:user)
|
||||||
calls = count_publish_to_user_calls
|
calls = count_publish_to_user_calls
|
||||||
|
|
@ -239,10 +238,10 @@ describe Notification do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "send scheduled session rsvp cancellation by organizer" do
|
describe "send scheduled session rsvp cancellation by organizer" do
|
||||||
it "sends live notification when user is online" do
|
it "sends pop-up notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends email notification when user is offline" do
|
it "sends email notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends no notification if session is nil" do
|
it "sends no notification if session is nil" do
|
||||||
|
|
@ -265,10 +264,10 @@ describe Notification do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "send scheduled session cancellation" do
|
describe "send scheduled session cancellation" do
|
||||||
it "sends live notification when user is online" do
|
it "sends pop-up notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends email notification when user is offline" do
|
it "sends email notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends no notification if session is nil" do
|
it "sends no notification if session is nil" do
|
||||||
|
|
@ -290,10 +289,10 @@ describe Notification do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "send scheduled session rescheduled" do
|
describe "send scheduled session rescheduled" do
|
||||||
it "sends live notification when user is online" do
|
it "sends pop-up notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends email notification when user is offline" do
|
it "sends email notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends no notification if session is nil" do
|
it "sends no notification if session is nil" do
|
||||||
|
|
@ -315,10 +314,10 @@ describe Notification do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "send scheduled session reminder" do
|
describe "send scheduled session reminder" do
|
||||||
it "sends live notification when user is online" do
|
it "sends pop-up notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends email notification when user is offline" do
|
it "sends email notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends no notification if session is nil" do
|
it "sends no notification if session is nil" do
|
||||||
|
|
@ -340,24 +339,35 @@ describe Notification do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "send scheduled session comment" do
|
describe "send scheduled session comment" do
|
||||||
it "sends live notification when user is online" do
|
it "sends pop-up notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends email notification when user is offline" do
|
it "sends email notification" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends no notification if session is nil" do
|
it "sends no notification if session is nil" do
|
||||||
|
sender = FactoryGirl.create(:user)
|
||||||
calls = count_publish_to_user_calls
|
calls = count_publish_to_user_calls
|
||||||
notification = Notification.send_scheduled_session_comment(nil, 'when are we playing?')
|
notification = Notification.send_scheduled_session_comment(nil, sender, 'when are we playing?')
|
||||||
|
|
||||||
|
UserMailer.deliveries.length.should == 0
|
||||||
|
calls[:count].should == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sends no notification if user is nil" do
|
||||||
|
session = FactoryGirl.create(:music_session)
|
||||||
|
calls = count_publish_to_user_calls
|
||||||
|
notification = Notification.send_scheduled_session_comment(session, nil, 'test')
|
||||||
|
|
||||||
UserMailer.deliveries.length.should == 0
|
UserMailer.deliveries.length.should == 0
|
||||||
calls[:count].should == 0
|
calls[:count].should == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sends no notification if comment is empty" do
|
it "sends no notification if comment is empty" do
|
||||||
|
sender = FactoryGirl.create(:user)
|
||||||
session = FactoryGirl.create(:music_session)
|
session = FactoryGirl.create(:music_session)
|
||||||
calls = count_publish_to_user_calls
|
calls = count_publish_to_user_calls
|
||||||
notification = Notification.send_scheduled_session_comment(session, '')
|
notification = Notification.send_scheduled_session_comment(session, sender, '')
|
||||||
|
|
||||||
UserMailer.deliveries.length.should == 0
|
UserMailer.deliveries.length.should == 0
|
||||||
calls[:count].should == 0
|
calls[:count].should == 0
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,6 @@ require 'spec_helper'
|
||||||
describe RsvpRequest do
|
describe RsvpRequest do
|
||||||
|
|
||||||
it "success" do
|
it "success" do
|
||||||
FactoryGirl.create(:rsvp_request)
|
# FactoryGirl.create(:rsvp_request)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -3,6 +3,6 @@ require 'spec_helper'
|
||||||
describe RsvpSlot do
|
describe RsvpSlot do
|
||||||
|
|
||||||
it "success" do
|
it "success" do
|
||||||
FactoryGirl.create(:rsvp_slot)
|
# FactoryGirl.create(:rsvp_slot)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -9,10 +9,12 @@
|
||||||
|
|
||||||
var logger = context.JK.logger;
|
var logger = context.JK.logger;
|
||||||
var msg_factory = context.JK.MessageFactory;
|
var msg_factory = context.JK.MessageFactory;
|
||||||
|
var rest = context.JK.Rest();
|
||||||
|
|
||||||
// Let socket.io know where WebSocketMain.swf is
|
// Let socket.io know where WebSocketMain.swf is
|
||||||
context.WEB_SOCKET_SWF_LOCATION = "assets/flash/WebSocketMain.swf";
|
context.WEB_SOCKET_SWF_LOCATION = "assets/flash/WebSocketMain.swf";
|
||||||
|
|
||||||
context.JK.JamServer = function (app) {
|
context.JK.JamServer = function (app, activeElementEvent) {
|
||||||
|
|
||||||
// uniquely identify the websocket connection
|
// uniquely identify the websocket connection
|
||||||
var channelId = null;
|
var channelId = null;
|
||||||
|
|
@ -50,6 +52,8 @@
|
||||||
var $templateDisconnected = null;
|
var $templateDisconnected = null;
|
||||||
var $currentDisplay = null;
|
var $currentDisplay = null;
|
||||||
|
|
||||||
|
var $self = $(this);
|
||||||
|
|
||||||
var server = {};
|
var server = {};
|
||||||
server.socket = {};
|
server.socket = {};
|
||||||
server.signedIn = false;
|
server.signedIn = false;
|
||||||
|
|
@ -59,7 +63,6 @@
|
||||||
server.socketClosedListeners = [];
|
server.socketClosedListeners = [];
|
||||||
server.connected = false;
|
server.connected = false;
|
||||||
|
|
||||||
|
|
||||||
function heartbeatStateReset() {
|
function heartbeatStateReset() {
|
||||||
lastHeartbeatSentTime = null;
|
lastHeartbeatSentTime = null;
|
||||||
lastHeartbeatAckTime = null;
|
lastHeartbeatAckTime = null;
|
||||||
|
|
@ -72,10 +75,6 @@
|
||||||
|
|
||||||
freezeInteraction = activeElementVotes && ((activeElementVotes.dialog && activeElementVotes.dialog.freezeInteraction === true) || (activeElementVotes.screen && activeElementVotes.screen.freezeInteraction === true));
|
freezeInteraction = activeElementVotes && ((activeElementVotes.dialog && activeElementVotes.dialog.freezeInteraction === true) || (activeElementVotes.screen && activeElementVotes.screen.freezeInteraction === true));
|
||||||
|
|
||||||
if (!initialConnect) {
|
|
||||||
context.JK.CurrentSessionModel.onWebsocketDisconnected(in_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_error) {
|
if (in_error) {
|
||||||
reconnectAttempt = 0;
|
reconnectAttempt = 0;
|
||||||
$currentDisplay = renderDisconnected();
|
$currentDisplay = renderDisconnected();
|
||||||
|
|
@ -108,11 +107,11 @@
|
||||||
|
|
||||||
server.reconnecting = true;
|
server.reconnecting = true;
|
||||||
|
|
||||||
var result = app.activeElementEvent('beforeDisconnect');
|
var result = activeElementEvent('beforeDisconnect');
|
||||||
|
|
||||||
initiateReconnect(result, in_error);
|
initiateReconnect(result, in_error);
|
||||||
|
|
||||||
app.activeElementEvent('afterDisconnect');
|
activeElementEvent('afterDisconnect');
|
||||||
|
|
||||||
// notify anyone listening that the socket closed
|
// notify anyone listening that the socket closed
|
||||||
var len = server.socketClosedListeners.length;
|
var len = server.socketClosedListeners.length;
|
||||||
|
|
@ -193,14 +192,12 @@
|
||||||
heartbeatAckCheckInterval = context.setInterval(_heartbeatAckCheck, 1000);
|
heartbeatAckCheckInterval = context.setInterval(_heartbeatAckCheck, 1000);
|
||||||
lastHeartbeatAckTime = new Date(new Date().getTime() + heartbeatMS); // add a little forgiveness to server for initial heartbeat
|
lastHeartbeatAckTime = new Date(new Date().getTime() + heartbeatMS); // add a little forgiveness to server for initial heartbeat
|
||||||
connectDeferred.resolve();
|
connectDeferred.resolve();
|
||||||
app.activeElementEvent('afterConnect', payload);
|
activeElementEvent('afterConnect', payload);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function heartbeatAck(header, payload) {
|
function heartbeatAck(header, payload) {
|
||||||
lastHeartbeatAckTime = new Date();
|
lastHeartbeatAckTime = new Date();
|
||||||
|
|
||||||
context.JK.CurrentSessionModel.trackChanges(header, payload);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerLoginAck() {
|
function registerLoginAck() {
|
||||||
|
|
@ -272,11 +269,7 @@
|
||||||
// TODO: tell certain elements that we've reconnected
|
// TODO: tell certain elements that we've reconnected
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// this path is the 'in session' path, where we actually reload the page
|
window.location.reload();
|
||||||
context.JK.CurrentSessionModel.leaveCurrentSession()
|
|
||||||
.always(function () {
|
|
||||||
window.location.reload();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
server.reconnecting = false;
|
server.reconnecting = false;
|
||||||
});
|
});
|
||||||
|
|
@ -455,10 +448,10 @@
|
||||||
}
|
}
|
||||||
connectDeferred = new $.Deferred();
|
connectDeferred = new $.Deferred();
|
||||||
channelId = context.JK.generateUUID(); // create a new channel ID for every websocket connection
|
channelId = context.JK.generateUUID(); // create a new channel ID for every websocket connection
|
||||||
logger.log("connecting websocket, channel_id: " + channelId);
|
|
||||||
|
|
||||||
var uri = context.JK.websocket_gateway_uri + '?channel_id=' + channelId; // Set in index.html.erb.
|
var uri = context.gon.websocket_gateway_uri + '?channel_id=' + channelId; // Set in index.html.erb.
|
||||||
//var uri = context.gon.websocket_gateway_uri; // Leaving here for now, as we're looking for a better solution.
|
|
||||||
|
logger.debug("connecting websocket: " + uri);
|
||||||
|
|
||||||
server.socket = new context.WebSocket(uri);
|
server.socket = new context.WebSocket(uri);
|
||||||
server.socket.onopen = server.onOpen;
|
server.socket.onopen = server.onOpen;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
//= require AAA_Log
|
//= require AAA_Log
|
||||||
//= require globals
|
//= require globals
|
||||||
//= require AAB_message_factory
|
//= require AAB_message_factory
|
||||||
|
//= require jam_rest
|
||||||
//= require AAC_underscore
|
//= require AAC_underscore
|
||||||
//= require utils
|
//= require utils
|
||||||
//= require custom_controls
|
//= require custom_controls
|
||||||
|
|
|
||||||
|
|
@ -137,14 +137,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStopRecording(from, payload) {
|
function onStopRecording(from, payload) {
|
||||||
logger.debug("received stop recording request from " + from);
|
logger.debug("received stop recording request from " + from);
|
||||||
|
|
||||||
// TODO check recordingId, and if currently recording
|
// TODO check recordingId, and if currently recording
|
||||||
// we should return success if we are currently recording, or if we were already asked to stop for this recordingId
|
// we should return success if we are currently recording, or if we were already asked to stop for this recordingId
|
||||||
// this means we should keep a list of the last N recordings that we've seen, rather than just keeping the current
|
// this means we should keep a list of the last N recordings that we've seen, rather than just keeping the current
|
||||||
context.JK.JamServer.sendP2PMessage(from, JSON.stringify(p2pMessageFactory.stopRecordingAck(payload.recordingId, true)));
|
context.JK.JamServer.sendP2PMessage(from, JSON.stringify(p2pMessageFactory.stopRecordingAck(payload.recordingId, true)));
|
||||||
|
|
||||||
|
if(stopRecordingResultCallbackName) {
|
||||||
eval(stopRecordingResultCallbackName).call(this, payload.recordingId, {success:payload.success, reason:payload.reason, detail:from});
|
eval(stopRecordingResultCallbackName).call(this, payload.recordingId, {success:payload.success, reason:payload.reason, detail:from});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStopRecordingAck(from, payload) {
|
function onStopRecordingAck(from, payload) {
|
||||||
|
|
|
||||||
|
|
@ -90,8 +90,7 @@
|
||||||
// loop through the tracks to get the instruments
|
// loop through the tracks to get the instruments
|
||||||
for (j=0; j < participant.tracks.length; j++) {
|
for (j=0; j < participant.tracks.length; j++) {
|
||||||
var track = participant.tracks[j];
|
var track = participant.tracks[j];
|
||||||
logger.debug("Find:Finding instruments. Participant tracks:");
|
logger.debug("Find:Finding instruments. Participant tracks:", participant.tracks);
|
||||||
logger.debug(participant.tracks);
|
|
||||||
var inst = '../assets/content/icon_instrument_default24.png';
|
var inst = '../assets/content/icon_instrument_default24.png';
|
||||||
if (track.instrument_id in instrument_logo_map) {
|
if (track.instrument_id in instrument_logo_map) {
|
||||||
inst = instrument_logo_map[track.instrument_id];
|
inst = instrument_logo_map[track.instrument_id];
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@
|
||||||
var participantsEverSeen = {};
|
var participantsEverSeen = {};
|
||||||
var $self = $(this);
|
var $self = $(this);
|
||||||
|
|
||||||
function id() {
|
server.registerOnSocketClosed(onWebsocketDisconnected);
|
||||||
|
|
||||||
|
function id() {
|
||||||
return currentSession ? currentSession.id : null;
|
return currentSession ? currentSession.id : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,6 +93,8 @@
|
||||||
server.registerMessageCallback(context.JK.MessageType.SESSION_JOIN, trackChanges);
|
server.registerMessageCallback(context.JK.MessageType.SESSION_JOIN, trackChanges);
|
||||||
server.registerMessageCallback(context.JK.MessageType.SESSION_DEPART, trackChanges);
|
server.registerMessageCallback(context.JK.MessageType.SESSION_DEPART, trackChanges);
|
||||||
server.registerMessageCallback(context.JK.MessageType.TRACKS_CHANGED, trackChanges);
|
server.registerMessageCallback(context.JK.MessageType.TRACKS_CHANGED, trackChanges);
|
||||||
|
server.registerMessageCallback(context.JK.MessageType.HEARTBEAT_ACK, trackChanges);
|
||||||
|
|
||||||
$(document).trigger('jamkazam.session_started', {session: {id: sessionId}});
|
$(document).trigger('jamkazam.session_started', {session: {id: sessionId}});
|
||||||
})
|
})
|
||||||
.fail(function() {
|
.fail(function() {
|
||||||
|
|
@ -107,12 +111,14 @@
|
||||||
server.unregisterMessageCallback(context.JK.MessageType.SESSION_JOIN, trackChanges);
|
server.unregisterMessageCallback(context.JK.MessageType.SESSION_JOIN, trackChanges);
|
||||||
server.unregisterMessageCallback(context.JK.MessageType.SESSION_DEPART, trackChanges);
|
server.unregisterMessageCallback(context.JK.MessageType.SESSION_DEPART, trackChanges);
|
||||||
server.unregisterMessageCallback(context.JK.MessageType.TRACKS_CHANGED, trackChanges);
|
server.unregisterMessageCallback(context.JK.MessageType.TRACKS_CHANGED, trackChanges);
|
||||||
|
server.unregisterMessageCallback(context.JK.MessageType.HEARTBEAT_ACK, trackChanges);
|
||||||
|
|
||||||
//server.unregisterMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_DEPART, refreshCurrentSession);
|
//server.unregisterMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_DEPART, refreshCurrentSession);
|
||||||
// leave the session right away without waiting on REST. Why? If you can't contact the server, or if it takes a long
|
// leave the session right away without waiting on REST. Why? If you can't contact the server, or if it takes a long
|
||||||
// time, for that entire duration you'll still be sending voice data to the other users.
|
// time, for that entire duration you'll still be sending voice data to the other users.
|
||||||
// this may be bad if someone decides to badmouth others in the left-session during this time
|
// this may be bad if someone decides to badmouth others in the left-session during this time
|
||||||
logger.debug("calling jamClient.LeaveSession for clientId=" + clientId);
|
console.trace();
|
||||||
|
logger.debug("performLeaveSession: calling jamClient.LeaveSession for clientId=" + clientId);
|
||||||
client.LeaveSession({ sessionID: currentSessionId });
|
client.LeaveSession({ sessionID: currentSessionId });
|
||||||
leaveSessionRest(currentSessionId)
|
leaveSessionRest(currentSessionId)
|
||||||
.done(function() {
|
.done(function() {
|
||||||
|
|
@ -377,10 +383,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWebsocketDisconnected(in_error) {
|
function onWebsocketDisconnected(in_error) {
|
||||||
|
// kill the streaming of the session immediately
|
||||||
// kill the streaming of the session immediately
|
if(currentSessionId) {
|
||||||
logger.debug("calling jamClient.LeaveSession for clientId=" + clientId);
|
logger.debug("onWebsocketDisconnect: calling jamClient.LeaveSession for clientId=" + clientId);
|
||||||
client.LeaveSession({ sessionID: currentSessionId });
|
client.LeaveSession({ sessionID: currentSessionId });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns a deferred object
|
// returns a deferred object
|
||||||
|
|
@ -423,7 +430,6 @@
|
||||||
this.getCurrentOrLastSession = function() {
|
this.getCurrentOrLastSession = function() {
|
||||||
return currentOrLastSession;
|
return currentOrLastSession;
|
||||||
};
|
};
|
||||||
this.trackChanges = trackChanges;
|
|
||||||
this.getParticipant = function(clientId) {
|
this.getParticipant = function(clientId) {
|
||||||
return participantsEverSeen[clientId]
|
return participantsEverSeen[clientId]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -607,6 +607,49 @@
|
||||||
doneYet();
|
doneYet();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
context.JK.initJamClient = function() {
|
||||||
|
// If no jamClient (when not running in native client)
|
||||||
|
// create a fake one.
|
||||||
|
if (!(window.jamClient)) {
|
||||||
|
var p2pMessageFactory = new JK.FakeJamClientMessages();
|
||||||
|
window.jamClient = new JK.FakeJamClient(JK.app, p2pMessageFactory);
|
||||||
|
window.jamClient.SetFakeRecordingImpl(new JK.FakeJamClientRecordings(JK.app, jamClient, p2pMessageFactory));
|
||||||
|
}
|
||||||
|
else if(false) { // set to true to time long running bridge calls
|
||||||
|
var originalJamClient = window.jamClient;
|
||||||
|
var interceptedJamClient = {};
|
||||||
|
$.each(Object.keys(originalJamClient), function(i, key) {
|
||||||
|
if(key.indexOf('(') > -1) {
|
||||||
|
// this is a method. time it
|
||||||
|
var jsKey = key.substring(0, key.indexOf('('))
|
||||||
|
console.log("replacing " + jsKey)
|
||||||
|
interceptedJamClient[jsKey] = function() {
|
||||||
|
var original = originalJamClient[key]
|
||||||
|
var start = new Date();
|
||||||
|
if(key == "FTUEGetDevices()") {
|
||||||
|
var returnVal = eval('originalJamClient.FTUEGetDevices(' + arguments[0] + ')');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var returnVal = original.apply(originalJamClient, arguments);
|
||||||
|
}
|
||||||
|
var time = new Date().getTime() - start.getTime();
|
||||||
|
if(time >= 0) { // if 0, you'll see ALL bridge calls. If you set it to a higher value, you'll only see calls that are beyond that threshold
|
||||||
|
console.error(time + "ms jamClient." + jsKey + ' returns=', returnVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// we need to intercept properties... but how?
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
window.jamClient = interceptedJamClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
context.JK.clientType = function () {
|
context.JK.clientType = function () {
|
||||||
return context.jamClient.IsNativeClient() ? 'client' : 'browser';
|
return context.jamClient.IsNativeClient() ? 'client' : 'browser';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,3 +55,8 @@
|
||||||
//= require web/sessions
|
//= require web/sessions
|
||||||
//= require web/recordings
|
//= require web/recordings
|
||||||
//= require web/welcome
|
//= require web/welcome
|
||||||
|
//= require banner
|
||||||
|
//= require fakeJamClient
|
||||||
|
//= require fakeJamClientMessages
|
||||||
|
//= require fakeJamClientRecordings
|
||||||
|
//= require JamServer
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
/**
|
/**
|
||||||
|
*= require client/banner
|
||||||
|
*= require client/jamServer
|
||||||
*= require client/ie
|
*= require client/ie
|
||||||
*= require client/jamkazam
|
*= require client/jamkazam
|
||||||
*= require easydropdown
|
*= require easydropdown
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,54 @@
|
||||||
class ApiRsvpRequestsController < ApiController
|
class ApiRsvpRequestsController < ApiController
|
||||||
|
|
||||||
|
# before_filter :auth_user
|
||||||
|
|
||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
def create
|
def index
|
||||||
|
if params[:session_id].blank?
|
||||||
|
render :json => {:message => "Session ID is required"}, :status => 400
|
||||||
|
|
||||||
|
else
|
||||||
|
music_session = MusicSession.find(params[:session_id])
|
||||||
|
|
||||||
|
# retrieve all requests for this session
|
||||||
|
if music_session.creator.id == current_user.id
|
||||||
|
@rsvp_requests = RsvpRequest.index(music_session)
|
||||||
|
|
||||||
|
# scope the response to the current user
|
||||||
|
else
|
||||||
|
@rsvp_requests = RsvpRequest.index(music_session, current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
respond_with @rsvp_requests, responder: ApiResponder, :status => 200
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
if params[:session_id].blank?
|
||||||
|
render :json => {:message => "Session ID is required."}, :status => 400
|
||||||
|
else
|
||||||
|
@rsvp = RsvpRequest.create(params, current_user)
|
||||||
|
respond_with @rsvp, responder: ApiResponder, :status => 201
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if params[:id].blank?
|
||||||
|
render :json => {:message => "RSVP request ID is required."}, :status => 400
|
||||||
|
else
|
||||||
|
RsvpRequest.update(params, current_user)
|
||||||
|
render :json => {:message => "Changes saved."}, :status => 204
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@rsvp_request = RsvpRequest.find(params[:id])
|
||||||
|
respond_with @rsvp_request, responder: ApiResponder, :status => 200
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
RsvpRequest.cancel(params, current_user)
|
||||||
|
respond_with responder: ApiResponder, :status => 204
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
class ApiRsvpSlotsController < ApiController
|
||||||
|
|
||||||
|
# before_filter :auth_user
|
||||||
|
|
||||||
|
respond_to :json
|
||||||
|
|
||||||
|
def index
|
||||||
|
|
||||||
|
if params[:session_id].blank?
|
||||||
|
render :json => {:message => "Session ID is required"}, :status => 400
|
||||||
|
|
||||||
|
else
|
||||||
|
music_session = MusicSession.find(params[:session_id])
|
||||||
|
|
||||||
|
# retrieve all slots for this session
|
||||||
|
@rsvp_slots = RsvpSlot.index(music_session)
|
||||||
|
|
||||||
|
respond_with @rsvp_slots, responder: ApiResponder, :status => 200
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# def create
|
||||||
|
# if params[:id].blank? || params[:session_id].blank?
|
||||||
|
# render :json => {:message => "Session ID is required."}, :status => 400
|
||||||
|
# else
|
||||||
|
# @rsvp = RsvpRequest.create(params, current_user)
|
||||||
|
# respond_with @rsvp, responder: ApiResponder, :status => 201
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
end
|
||||||
|
|
@ -3,10 +3,15 @@ class ApplicationController < ActionController::Base
|
||||||
protect_from_forgery
|
protect_from_forgery
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
include SessionsHelper
|
include SessionsHelper
|
||||||
|
include ClientHelper
|
||||||
|
|
||||||
# inject username/email into bugsnag data
|
# inject username/email into bugsnag data
|
||||||
before_bugsnag_notify :add_user_info_to_bugsnag
|
before_bugsnag_notify :add_user_info_to_bugsnag
|
||||||
|
|
||||||
|
before_filter do
|
||||||
|
gon_setup
|
||||||
|
end
|
||||||
|
|
||||||
before_filter do
|
before_filter do
|
||||||
if params[AffiliatePartner::PARAM_REFERRAL].present? && current_user.nil?
|
if params[AffiliatePartner::PARAM_REFERRAL].present? && current_user.nil?
|
||||||
if cookies[AffiliatePartner::PARAM_COOKIE].blank?
|
if cookies[AffiliatePartner::PARAM_COOKIE].blank?
|
||||||
|
|
|
||||||
|
|
@ -12,22 +12,6 @@ class ClientsController < ApplicationController
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
# use gon to pass variables into javascript
|
|
||||||
gon.websocket_gateway_uri = Rails.application.config.websocket_gateway_uri
|
|
||||||
gon.check_for_client_updates = Rails.application.config.check_for_client_updates
|
|
||||||
gon.fp_apikey = Rails.application.config.filepicker_rails.api_key
|
|
||||||
gon.fp_upload_dir = Rails.application.config.filepicker_upload_dir
|
|
||||||
gon.allow_force_native_client = Rails.application.config.allow_force_native_client
|
|
||||||
|
|
||||||
# is this the native client or browser?
|
|
||||||
@nativeClient = is_native_client?
|
|
||||||
|
|
||||||
# let javascript have access to the server's opinion if this is a native client
|
|
||||||
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
|
|
||||||
|
|
||||||
render :layout => 'client'
|
render :layout => 'client'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
class SpikesController < ApplicationController
|
class SpikesController < ApplicationController
|
||||||
|
|
||||||
|
include ClientHelper
|
||||||
|
|
||||||
def facebook_invite
|
def facebook_invite
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
@ -24,4 +26,8 @@ class SpikesController < ApplicationController
|
||||||
def launch_app
|
def launch_app
|
||||||
render :layout => 'web'
|
render :layout => 'web'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def websocket
|
||||||
|
render :layout => false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,32 @@ module ClientHelper
|
||||||
|
|
||||||
is_native_client
|
is_native_client
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def gon_setup
|
||||||
|
|
||||||
|
gon.root_url = root_url
|
||||||
|
# use gon to pass variables into javascript
|
||||||
|
if Rails.env == "development"
|
||||||
|
# if in development mode, we assume you are running websocket-gateway
|
||||||
|
# on the same host as you hit your server.
|
||||||
|
gon.websocket_gateway_uri = "ws://" + request.host + ":6767/websocket";
|
||||||
|
else
|
||||||
|
# but in any other mode, just use config
|
||||||
|
gon.websocket_gateway_uri = Rails.application.config.websocket_gateway_uri
|
||||||
|
end
|
||||||
|
|
||||||
|
gon.check_for_client_updates = Rails.application.config.check_for_client_updates
|
||||||
|
gon.fp_apikey = Rails.application.config.filepicker_rails.api_key
|
||||||
|
gon.fp_upload_dir = Rails.application.config.filepicker_upload_dir
|
||||||
|
gon.allow_force_native_client = Rails.application.config.allow_force_native_client
|
||||||
|
|
||||||
|
# is this the native client or browser?
|
||||||
|
@nativeClient = is_native_client?
|
||||||
|
|
||||||
|
# let javascript have access to the server's opinion if this is a native client
|
||||||
|
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
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -1 +1,3 @@
|
||||||
collection @rsvp_requests
|
object @rsvp_requests
|
||||||
|
|
||||||
|
extends "api_rsvp_requests/show"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,15 @@
|
||||||
object @rsvp
|
object @rsvp_request
|
||||||
|
|
||||||
attributes :user_id, :message, :chosen, :canceled, :created_at
|
attributes :id, :canceled, :created_at
|
||||||
|
|
||||||
child :rsvp_slot => :rsvp_slot do
|
child(:user => :user) {
|
||||||
attributes :id, :instrument_id, :proficiency_level, :music_session_id, :created_at
|
attributes :id, :name, :photo_url
|
||||||
end
|
}
|
||||||
|
|
||||||
|
child(:rsvp_slots => :rsvp_slots) {
|
||||||
|
attributes :id, :instrument_id, :proficiency_level, :music_session_id
|
||||||
|
|
||||||
|
child(:rsvp_requests_rsvp_slots => :rsvp_requests_rsvp_slots) {
|
||||||
|
attributes :id, :chosen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
object @rsvp_slots
|
||||||
|
|
||||||
|
extends "api_rsvp_slots/show"
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
object @rsvp_slot
|
||||||
|
|
||||||
|
attributes :id, :instrument_id, :proficiency_level, :chosen
|
||||||
|
|
||||||
|
child(:music_session => :music_session) {
|
||||||
|
attributes :id, :description, :scheduled_start, :recurring_mode
|
||||||
|
}
|
||||||
|
|
||||||
|
child(:rsvp_requests => :rsvp_requests) {
|
||||||
|
attributes :id, :canceled
|
||||||
|
|
||||||
|
child(:user => :user) {
|
||||||
|
attributes :id, :name, :photo_url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
child(:rsvp_requests_rsvp_slots => :rsvp_requests_rsvp_slots) {
|
||||||
|
attributes :id, :chosen
|
||||||
|
}
|
||||||
|
|
@ -73,18 +73,7 @@
|
||||||
|
|
||||||
JK = JK || {};
|
JK = JK || {};
|
||||||
|
|
||||||
JK.root_url = "<%= root_url %>"
|
JK.root_url = gon.root_url
|
||||||
|
|
||||||
<% if Rails.env == "development" %>
|
|
||||||
// if in development mode, we assume you are running websocket-gateway
|
|
||||||
// on the same host as you hit your server.
|
|
||||||
JK.websocket_gateway_uri = "ws://" + location.hostname + ":6767/websocket";
|
|
||||||
<% else %>
|
|
||||||
// but in any other mode, just trust the config coming through gon
|
|
||||||
JK.websocket_gateway_uri = gon.websocket_gateway_uri
|
|
||||||
<% end %>
|
|
||||||
if (console) { console.log("websocket_gateway_uri:" + JK.websocket_gateway_uri); }
|
|
||||||
|
|
||||||
|
|
||||||
// If no trackVolumeObject (when not running in native client)
|
// If no trackVolumeObject (when not running in native client)
|
||||||
// create a fake one.
|
// create a fake one.
|
||||||
|
|
@ -263,49 +252,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
JK.app = JK.JamKazam();
|
JK.app = JK.JamKazam();
|
||||||
var jamServer = new JK.JamServer(JK.app);
|
var jamServer = new JK.JamServer(JK.app, function(event_type) {JK.app.activeElementEvent(event_type)});
|
||||||
jamServer.initialize();
|
jamServer.initialize();
|
||||||
|
|
||||||
// If no jamClient (when not running in native client)
|
JK.initJamClient();
|
||||||
// create a fake one.
|
|
||||||
if (!(window.jamClient)) {
|
|
||||||
var p2pMessageFactory = new JK.FakeJamClientMessages();
|
|
||||||
window.jamClient = new JK.FakeJamClient(JK.app, p2pMessageFactory);
|
|
||||||
window.jamClient.SetFakeRecordingImpl(new JK.FakeJamClientRecordings(JK.app, jamClient, p2pMessageFactory));
|
|
||||||
}
|
|
||||||
else if(false) { // set to true to time long running bridge calls
|
|
||||||
var originalJamClient = window.jamClient;
|
|
||||||
var interceptedJamClient = {};
|
|
||||||
$.each(Object.keys(originalJamClient), function(i, key) {
|
|
||||||
if(key.indexOf('(') > -1) {
|
|
||||||
// this is a method. time it
|
|
||||||
var jsKey = key.substring(0, key.indexOf('('))
|
|
||||||
console.log("replacing " + jsKey)
|
|
||||||
interceptedJamClient[jsKey] = function() {
|
|
||||||
var original = originalJamClient[key]
|
|
||||||
var start = new Date();
|
|
||||||
if(key == "FTUEGetDevices()") {
|
|
||||||
var returnVal = eval('originalJamClient.FTUEGetDevices(' + arguments[0] + ')');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var returnVal = original.apply(originalJamClient, arguments);
|
|
||||||
}
|
|
||||||
var time = new Date().getTime() - start.getTime();
|
|
||||||
if(time >= 0) { // if 0, you'll see ALL bridge calls. If you set it to a higher value, you'll only see calls that are beyond that threshold
|
|
||||||
console.error(time + "ms jamClient." + jsKey + ' returns=', returnVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// we need to intercept properties... but how?
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
window.jamClient = interceptedJamClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let's get things rolling...
|
// Let's get things rolling...
|
||||||
if (JK.currentUserId) {
|
if (JK.currentUserId) {
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,9 @@
|
||||||
<%= render "clients/footer" %>
|
<%= render "clients/footer" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<%= render "clients/banner" %>
|
||||||
|
<%= render "clients/banners/disconnected" %>
|
||||||
|
<%= render "clients/jamServer" %>
|
||||||
<%= render "clients/invitationDialog" %>
|
<%= render "clients/invitationDialog" %>
|
||||||
<%= render "users/signupDialog" %>
|
<%= render "users/signupDialog" %>
|
||||||
<%= render "users/signinDialog" %>
|
<%= render "users/signinDialog" %>
|
||||||
|
|
@ -103,6 +106,12 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
JK.app = JK.JamKazam();
|
JK.app = JK.JamKazam();
|
||||||
|
var jamServer = new JK.JamServer(JK.app, $.noop);
|
||||||
|
jamServer.initialize();
|
||||||
|
|
||||||
|
// JamServer.connect needs the jamClient to be initialized
|
||||||
|
JK.initJamClient();
|
||||||
|
|
||||||
JK.app.initialize({inClient: false, layoutOpts: {layoutFooter: false, sizeOverlayToContent: true}});
|
JK.app.initialize({inClient: false, layoutOpts: {layoutFooter: false, sizeOverlayToContent: true}});
|
||||||
|
|
||||||
var facebookHelper = new JK.FacebookHelper(JK.app);
|
var facebookHelper = new JK.FacebookHelper(JK.app);
|
||||||
|
|
@ -125,6 +134,15 @@
|
||||||
videoDialog.initialize();
|
videoDialog.initialize();
|
||||||
|
|
||||||
JK.bindHoverEvents();
|
JK.bindHoverEvents();
|
||||||
|
|
||||||
|
|
||||||
|
JK.JamServer.connect() // singleton here defined in JamServer.js
|
||||||
|
.done(function() {
|
||||||
|
console.log("websocket connected")
|
||||||
|
})
|
||||||
|
.fail(function() {
|
||||||
|
console.log("websocket failed to connect")
|
||||||
|
});
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
<!-- you need this javascript -->
|
||||||
|
<%= javascript_include_tag "jamServer" %>
|
||||||
|
<!-- gon is required -->
|
||||||
|
<%= include_gon %>
|
||||||
|
<!-- you need these templates -->
|
||||||
|
<%= render "clients/banner" %>
|
||||||
|
<%= render "clients/banners/disconnected" %>
|
||||||
|
<%= render "clients/jamServer" %>
|
||||||
|
|
||||||
|
<!-- you need these stylesheets -->
|
||||||
|
<%= stylesheet_link_tag "client/banner", media: "all" %>
|
||||||
|
<%= stylesheet_link_tag "client/jamServer", media: "all" %>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
// you can probably do nothing with this in your own code
|
||||||
|
function signalActiveElement(event_type) {
|
||||||
|
// event can be one of:
|
||||||
|
// * beforeDisconnect
|
||||||
|
// * afterDisconnect
|
||||||
|
// * afterConnect
|
||||||
|
// the purpose of this method is to signal to the active element in the UI that websocket state changed
|
||||||
|
// and in beforeDisconnect in particular, you can return a 'vote' that let's you affect how a reconnect is handled
|
||||||
|
// you can safely return null, though
|
||||||
|
|
||||||
|
console.log("websocket event:" + event_type);
|
||||||
|
|
||||||
|
if(event_type == 'beforeDisconnect') {
|
||||||
|
return null; // causes a in-place websocket reconnect (as opposed to a full page refresh when connection re-established)
|
||||||
|
}
|
||||||
|
// no other event cares about return
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
|
||||||
|
JK = JK || {};
|
||||||
|
|
||||||
|
JK.app = JK.JamKazam();
|
||||||
|
var jamServer = new JK.JamServer(JK.app, signalActiveElement);
|
||||||
|
jamServer.initialize();
|
||||||
|
|
||||||
|
// now you can register for messages somewhere in your code safely... (not necessarily inline here--just somewhere)
|
||||||
|
// i.e., you can call: context.JK.JamServer.registerMessageCallback
|
||||||
|
|
||||||
|
// JamServer.connect needs the jamClient to be initialized
|
||||||
|
JK.initJamClient();
|
||||||
|
|
||||||
|
JK.JamServer.connect() // singleton here defined in JamServer.js
|
||||||
|
.done(function() {
|
||||||
|
console.log("websocket connected") // this is used in /client to signal hide of curtain, and initializing the bulk of logic. maybe not useful...
|
||||||
|
})
|
||||||
|
.fail(function() {
|
||||||
|
console.log("websocket failed to connect") // this is used in /client
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -80,7 +80,7 @@ SampleApp::Application.routes.draw do
|
||||||
# route to spike controller (proof-of-concepts)
|
# route to spike controller (proof-of-concepts)
|
||||||
match '/facebook_invite', to: 'spikes#facebook_invite'
|
match '/facebook_invite', to: 'spikes#facebook_invite'
|
||||||
match '/launch_app', to: 'spikes#launch_app'
|
match '/launch_app', to: 'spikes#launch_app'
|
||||||
|
match '/websocket', to: 'spikes#websocket'
|
||||||
|
|
||||||
# junk pages
|
# junk pages
|
||||||
match '/help', to: 'static_pages#help'
|
match '/help', to: 'static_pages#help'
|
||||||
|
|
@ -170,11 +170,16 @@ SampleApp::Application.routes.draw do
|
||||||
match '/sessions/:id/tracks/:track_id' => 'api_music_sessions#track_destroy', :via => :delete
|
match '/sessions/:id/tracks/:track_id' => 'api_music_sessions#track_destroy', :via => :delete
|
||||||
|
|
||||||
# RSVP requests
|
# RSVP requests
|
||||||
match '/sessions/:id/rsvp_requests' => 'api_music_sessions#rsvp_requests_index', :via => :get
|
match '/rsvp_requests' => 'api_rsvp_requests#index', :via => :get
|
||||||
match '/rsvp_requests' => 'api_rsvp_requests#create', :via => :post
|
match '/rsvp_requests' => 'api_rsvp_requests#create', :via => :post
|
||||||
|
match '/rsvp_requests/:id' => 'api_rsvp_requests#update', :via => :post
|
||||||
match '/rsvp_requests/:id' => 'api_rsvp_requests#show', :via => :get, :as => 'api_rsvp_request_detail'
|
match '/rsvp_requests/:id' => 'api_rsvp_requests#show', :via => :get, :as => 'api_rsvp_request_detail'
|
||||||
match '/rsvp_requests/:id' => 'api_rsvp_requests#destroy', :via => :delete
|
match '/rsvp_requests/:id' => 'api_rsvp_requests#destroy', :via => :delete
|
||||||
|
|
||||||
|
# RSVP slots
|
||||||
|
match '/rsvp_slots' => 'api_rsvp_slots#index', :via => :get
|
||||||
|
match '/rsvp_slots/:id' => 'api_rsvp_slots#show', :via => :get, :as => 'api_rsvp_slot_detail'
|
||||||
|
|
||||||
# music session playback recording state
|
# music session playback recording state
|
||||||
match '/sessions/:id/claimed_recording/:claimed_recording_id/start' => 'api_music_sessions#claimed_recording_start', :via => :post
|
match '/sessions/:id/claimed_recording/:claimed_recording_id/start' => 'api_music_sessions#claimed_recording_start', :via => :post
|
||||||
match '/sessions/:id/claimed_recording/:claimed_recording_id/stop' => 'api_music_sessions#claimed_recording_stop', :via => :post
|
match '/sessions/:id/claimed_recording/:claimed_recording_id/stop' => 'api_music_sessions#claimed_recording_stop', :via => :post
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,10 @@ describe "Landing", :js => true, :type => :feature, :capybara_feature => true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "footer links work" do
|
it "footer links work" do
|
||||||
first('#footer-links a').trigger(:click)
|
first('#footer-links a', text: 'about').trigger(:click)
|
||||||
should have_selector('h1', text: 'About Us')
|
page.within_window page.driver.window_handles.last do
|
||||||
|
should have_selector('h1', text: 'About Us')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ describe "Reconnect", :js => true, :type => :feature, :capybara_feature => true
|
||||||
# but.. after a few seconds, it should reconnect on it's own
|
# but.. after a few seconds, it should reconnect on it's own
|
||||||
page.should_not have_selector('h2', text: 'Disconnected from Server')
|
page.should_not have_selector('h2', text: 'Disconnected from Server')
|
||||||
|
|
||||||
find('h1', text:'session')
|
find('div[layout-id="session"] h1', text:'session')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,11 @@ describe "Session Recordings", :js => true, :type => :feature, :capybara_feature
|
||||||
|
|
||||||
# confirms that if someone leaves 'ugly' (without calling 'Leave' REST API), that the recording is junked
|
# confirms that if someone leaves 'ugly' (without calling 'Leave' REST API), that the recording is junked
|
||||||
it "creator starts and then abruptly leave" do
|
it "creator starts and then abruptly leave" do
|
||||||
|
pending "shows 'recording finished'"
|
||||||
start_recording_with(creator, [joiner1])
|
start_recording_with(creator, [joiner1])
|
||||||
|
|
||||||
in_client(creator) do
|
in_client(creator) do
|
||||||
visit "/downloads" # kills websocket, looking like an abrupt leave
|
close_websocket
|
||||||
end
|
end
|
||||||
|
|
||||||
in_client(joiner1) do
|
in_client(joiner1) do
|
||||||
|
|
@ -80,10 +81,11 @@ describe "Session Recordings", :js => true, :type => :feature, :capybara_feature
|
||||||
|
|
||||||
# confirms that if someone leaves 'ugly' (without calling 'Leave' REST API), that the recording is junked with 3 participants
|
# confirms that if someone leaves 'ugly' (without calling 'Leave' REST API), that the recording is junked with 3 participants
|
||||||
it "creator starts and then abruptly leave with 3 participants" do
|
it "creator starts and then abruptly leave with 3 participants" do
|
||||||
|
pending "shows 'recording finished'"
|
||||||
start_recording_with(creator, [joiner1, joiner2])
|
start_recording_with(creator, [joiner1, joiner2])
|
||||||
|
|
||||||
in_client(creator) do
|
in_client(creator) do
|
||||||
visit "/downloads" # kills websocket, looking like an abrupt leave
|
close_websocket
|
||||||
end
|
end
|
||||||
|
|
||||||
in_client(joiner1) do
|
in_client(joiner1) do
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe "RSVP Request API ", :type => :api do
|
||||||
|
|
||||||
|
include Rack::Test::Methods
|
||||||
|
|
||||||
|
subject { page }
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
MusicSession.delete_all
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "index" do
|
||||||
|
it "should prevent request without session ID" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow session creator to view all" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow RSVP creator to view only his list" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow others to view list" do
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
describe "create" do
|
||||||
|
it "should allow session invitee to create RSVP" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not allow non-invitee to create RSVP" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should require at least 1 slot selection" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should prevent RSVP for chosen slot" do
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "update" do
|
||||||
|
it "should allow session creator to approve RSVP request" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not allow RSVP creator to approve RSVP request" do
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "show" do
|
||||||
|
it "should allow RSVP creator to view" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow session creator to view" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow anyone else to view" do
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "destroy" do
|
||||||
|
it "should allow RSVP creator to cancel" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow session creator to cancel" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not allow anyone else to cancel" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should set chosen to false on all slots" do
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe "RSVP Slot API ", :type => :api do
|
||||||
|
|
||||||
|
include Rack::Test::Methods
|
||||||
|
|
||||||
|
subject { page }
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
MusicSession.delete_all
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "index" do
|
||||||
|
it "should prevent request without session ID" do
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow session invitee to view all" do
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -479,4 +479,4 @@ def garbage length
|
||||||
output = ''
|
output = ''
|
||||||
length.times { output << special_characters.sample }
|
length.times { output << special_characters.sample }
|
||||||
output.slice(0, length)
|
output.slice(0, length)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue