diff --git a/pb/src/client_container.proto b/pb/src/client_container.proto index 0e54b3528..4d06a0319 100644 --- a/pb/src/client_container.proto +++ b/pb/src/client_container.proto @@ -252,7 +252,7 @@ message SessionInvitation { } message SessionEnded { - + optional string session_id = 1; } message JoinRequest { diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb index 973ed5efe..41ffebc8b 100755 --- a/ruby/lib/jam_ruby.rb +++ b/ruby/lib/jam_ruby.rb @@ -122,7 +122,8 @@ require "jam_ruby/models/icecast_mount_template" require "jam_ruby/models/facebook_signup" require "jam_ruby/models/recording_play" require "jam_ruby/models/feed" - +require "jam_ruby/models/jam_isp" +require "jam_ruby/models/geo_ip_blocks" include Jampb diff --git a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb index 9fbc5bf66..dcae48185 100644 --- a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb +++ b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb @@ -92,78 +92,155 @@ def friend_request(email, msg) subject = "You have a new friend request on JamKazam" unique_args = {:type => "friend_request"} - send_notification(email, subject, msg, unique_args) + + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:to => email, :subject => subject) do |format| + format.text + format.html + end end def friend_request_accepted(email, msg) subject = "You have a new friend on JamKazam" unique_args = {:type => "friend_request_accepted"} - send_notification(email, subject, msg, unique_args) + + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:to => email, :subject => subject) do |format| + format.text + format.html + end end def new_user_follower(email, msg) subject = "You have a new follower on JamKazam" unique_args = {:type => "new_user_follower"} - send_notification(email, subject, msg, unique_args) + + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:to => email, :subject => subject) do |format| + format.text + format.html + end end def new_band_follower(email, msg) subject = "Your band has a new follower on JamKazam" unique_args = {:type => "new_band_follower"} - send_notification(email, subject, msg, unique_args) + + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:to => email, :subject => subject) do |format| + format.text + format.html + end end def session_invitation(email, msg) subject = "You have been invited to a session on JamKazam" unique_args = {:type => "session_invitation"} - send_notification(email, subject, msg, unique_args) + + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:to => email, :subject => subject) do |format| + format.text + format.html + end end def musician_session_join(email, msg) subject = "Someone you know is in a session on JamKazam" unique_args = {:type => "musician_session_join"} - send_notification(email, subject, msg, unique_args) + + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:to => email, :subject => subject) do |format| + format.text + format.html + end end def band_session_join(email, msg) subject = "A band that you follow has joined a session" unique_args = {:type => "band_session_join"} - send_notification(email, subject, msg, unique_args) + + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:to => email, :subject => subject) do |format| + format.text + format.html + end end def musician_recording_saved(email, msg) subject = msg unique_args = {:type => "musician_recording_saved"} - send_notification(email, subject, msg, unique_args) + + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:to => email, :subject => subject) do |format| + format.text + format.html + end end def band_recording_saved(email, msg) subject = msg unique_args = {:type => "band_recording_saved"} - send_notification(email, subject, msg, unique_args) + + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:to => email, :subject => subject) do |format| + format.text + format.html + end end def band_invitation(email, msg) subject = "You have been invited to join a band on JamKazam" unique_args = {:type => "band_invitation"} - send_notification(email, subject, msg, unique_args) + + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:to => email, :subject => subject) do |format| + format.text + format.html + end end def band_invitation_accepted(email, msg) subject = "Your band invitation was accepted" unique_args = {:type => "band_invitation_accepted"} - send_notification(email, subject, msg, unique_args) - end - def send_notification(email, subject, msg, unique_args) @body = msg sendgrid_category "Notification" sendgrid_unique_args :type => unique_args[:type] - mail(:bcc => email, :subject => subject) do |format| + mail(:to => email, :subject => subject) do |format| format.text format.html end end + + # def send_notification(email, subject, msg, unique_args) + # @body = msg + # sendgrid_category "Notification" + # sendgrid_unique_args :type => unique_args[:type] + # mail(:to => email, :subject => subject) do |format| + # format.text + # format.html + # end + # end ############################################################################################# end diff --git a/ruby/lib/jam_ruby/connection_manager.rb b/ruby/lib/jam_ruby/connection_manager.rb index 0e9ee5baf..2320218b6 100644 --- a/ruby/lib/jam_ruby/connection_manager.rb +++ b/ruby/lib/jam_ruby/connection_manager.rb @@ -57,6 +57,26 @@ module JamRuby if ip_address # todo turn ip_address string into a number, then fetch the locid and ispid and the other stuff... + + addr = JamIsp.ip_to_num(ip_address) + puts("============= JamIsp.ip_to_num returns #{addr} for #{ip_address} =============") + + isp = JamIsp.lookup(addr) + if isp.nil? then ispid = 0 else ispid = isp.coid end + puts("============= JamIsp.lookup returns #{ispid} for #{addr} =============") + + block = GeoIpBlocks.lookup(addr) + if block.nil? then locid = 0 else locid = block.locid end + puts("============= GeoIpBlocks.lookup returns #{locid} for #{addr} =============") + + locidispid = 0 + latitude = 0.0 + longitude = 0.0 + countrycode = 'US' + region = 'TX' + city = 'Austin' + + # todo stuff this stuff into the connection records end sql =< session_id + ) + + Jampb::ClientMessage.new( + :type => ClientMessage::Type::SESSION_ENDED, + :route_to => USER_TARGET_PREFIX + receiver_id, + :session_ended => session_ended + ) + end + # create a join request session message def join_request(join_request_id, session_id, photo_url, msg, notification_id, created_at) req = Jampb::JoinRequest.new( diff --git a/ruby/lib/jam_ruby/models/geo_ip_blocks.rb b/ruby/lib/jam_ruby/models/geo_ip_blocks.rb new file mode 100644 index 000000000..417d5bb95 --- /dev/null +++ b/ruby/lib/jam_ruby/models/geo_ip_blocks.rb @@ -0,0 +1,20 @@ +module JamRuby + class GeoIpBlocks < ActiveRecord::Base + + self.table_name = 'geoipblocks' + + def self.lookup(ipnum) + GeoIpBlocks.select(:locid) + .where('geom && ST_MakePoint(?, 0) AND ? BETWEEN beginip AND endip', ipnum, ipnum) + .limit(1) + .first + end + + def self.make_row(beginip, endip, locid) + c = ActiveRecord::Base.connection.raw_connection + c.prepare('blah', 'insert into geoipblocks (beginip, endip, locid, geom) values($1::bigint, $2::bigint, $3, ST_MakeEnvelope($1::bigint, -1, $2::bigint, 1))') + c.exec_prepared('blah', [beginip, endip, locid]) + c.exec("deallocate blah") + end + end +end diff --git a/ruby/lib/jam_ruby/models/jam_isp.rb b/ruby/lib/jam_ruby/models/jam_isp.rb new file mode 100644 index 000000000..4157b1ce3 --- /dev/null +++ b/ruby/lib/jam_ruby/models/jam_isp.rb @@ -0,0 +1,28 @@ +require 'ipaddr' + +module JamRuby + class JamIsp < ActiveRecord::Base + + self.table_name = 'jamisp' + + def self.ip_to_num(ip_addr) + i = IPAddr.new(ip_addr) + return i.to_i if i.ipv4? + nil + end + + def self.lookup(ipnum) + JamIsp.select(:coid) + .where('geom && ST_MakePoint(?, 0) AND ? BETWEEN beginip AND endip', ipnum, ipnum) + .limit(1) + .first + end + + def self.make_row(beginip, endip, coid) + c = ActiveRecord::Base.connection.raw_connection + c.prepare('blah', 'insert into jamisp (beginip, endip, coid, geom) values($1::bigint, $2::bigint, $3, ST_MakeEnvelope($1::bigint, -1, $2::bigint, 1))') + c.exec_prepared('blah', [beginip, endip, coid]) + c.exec("deallocate blah") + end + end +end diff --git a/ruby/lib/jam_ruby/models/music_session_history.rb b/ruby/lib/jam_ruby/models/music_session_history.rb index e504db256..f728493b5 100644 --- a/ruby/lib/jam_ruby/models/music_session_history.rb +++ b/ruby/lib/jam_ruby/models/music_session_history.rb @@ -172,6 +172,10 @@ module JamRuby .first hist.end_history if hist + + puts "**************NOTIFICATION SESSION ENDED**************" + + Notification.send_session_ended(session_id) end def remove_non_alpha_num(token) diff --git a/ruby/lib/jam_ruby/models/notification.rb b/ruby/lib/jam_ruby/models/notification.rb index 48c363a1b..ab6708ca4 100644 --- a/ruby/lib/jam_ruby/models/notification.rb +++ b/ruby/lib/jam_ruby/models/notification.rb @@ -47,10 +47,6 @@ module JamRuby @@mq_router = MQRouter.new @@message_factory = MessageFactory.new - def delete_all(session_id) - Notification.delete_all "(session_id = '#{session_id}')" - end - ################### HELPERS ################### def retrieve_friends(connection, user_id) friend_ids = [] @@ -232,7 +228,7 @@ module JamRuby @@mq_router.publish_to_user(friend_id, msg) else - UserMailer.friend_request(friend.email, notification_msg) + UserMailer.friend_request(friend.email, notification_msg).deliver end end @@ -260,7 +256,7 @@ module JamRuby @@mq_router.publish_to_user(user.id, msg) else - UserMailer.friend_request_accepted(user.email, notification_msg) + UserMailer.friend_request_accepted(user.email, notification_msg).deliver end end @@ -287,7 +283,7 @@ module JamRuby @@mq_router.publish_to_user(user.id, msg) else - UserMailer.new_user_follower(user.email, notification_msg) + UserMailer.new_user_follower(user.email, notification_msg).deliver end end end @@ -321,7 +317,7 @@ module JamRuby @@mq_router.publish_to_user(bm.user_id, msg) else - UserMailer.new_band_follower(bm.user.email, notification_msg) + UserMailer.new_band_follower(bm.user.email, notification_msg).deliver end end end @@ -350,14 +346,23 @@ module JamRuby @@mq_router.publish_to_user(receiver.id, msg) else - UserMailer.session_invitation(receiver.email, notification_msg) + UserMailer.session_invitation(receiver.email, notification_msg).deliver end end - def send_session_ended(music_session, connection) + def send_session_ended(session_id) - # TODO: this should actually publish to all users who have a notification for this session - @@mq_router.server_publish_to_session(music_session, nil, sender = {:client_id => connection.client_id}) + notifications = Notification.where(:session_id => session_id) + + # publish to all users who have a notification for this session + # TODO: do this in BULK or in async block + notifications.each do |n| + puts "*************SENDING SESSION_ENDED TO #{n.target_user_id}***************" + msg = @@message_factory.session_ended(n.target_user_id, session_id) + @@mq_router.publish_to_user(n.target_user_id, msg) + end + + Notification.delete_all "(session_id = '#{session_id}')" end def send_join_request(music_session, join_request, text) @@ -467,8 +472,8 @@ module JamRuby follower_users = user_followers.map { |uf| uf.user } friends_and_followers = friend_users.concat(follower_users).uniq - # remove anyone in the session - friends_and_followers = friends_and_followers - music_session.users + # remove anyone in the session and invited musicians + friends_and_followers = friends_and_followers - music_session.users - music_session.invited_musicians notifications, online_ff, offline_ff = [], [], [] notification_msg = format_msg(NotificationTypes::MUSICIAN_SESSION_JOIN, user) @@ -478,6 +483,7 @@ module JamRuby notification.description = NotificationTypes::MUSICIAN_SESSION_JOIN notification.source_user_id = user.id notification.target_user_id = ff.id + notification.session_id = music_session.id notification.save if ff.online @@ -499,7 +505,7 @@ module JamRuby # send email notifications unless offline_ff.empty? - UserMailer.musician_session_join(offline_ff.map! {|f| f.email}, notification_msg) + UserMailer.musician_session_join(offline_ff.map! {|f| f.email}, notification_msg).deliver end end end @@ -519,6 +525,7 @@ module JamRuby notification.band_id = band.id notification.description = NotificationTypes::BAND_SESSION_JOIN notification.target_user_id = follower.id + notification.session_id = music_session.id notification.save if follower.online @@ -540,7 +547,7 @@ module JamRuby # send email notifications unless offline_followers.empty? - UserMailer.band_session_join(offline_followers.map! {|f| f.email}, notification_msg) + UserMailer.band_session_join(offline_followers.map! {|f| f.email}, notification_msg).deliver end end end @@ -562,9 +569,10 @@ module JamRuby friends_and_followers.each do |ff| notification = Notification.new - notification.description = NotificationTypes::MUSICIAN_SESSION_JOIN + notification.description = NotificationTypes::MUSICIAN_RECORDING_SAVED notification.source_user_id = user.id notification.target_user_id = ff.id + notification.recording_id = recording.id notification.save if ff.online @@ -585,7 +593,7 @@ module JamRuby # send email notifications unless offline_ff.empty? - UserMailer.musician_recording_saved(offline_ff.map! {|f| f.email}, notification_msg) + UserMailer.musician_recording_saved(offline_ff.map! {|f| f.email}, notification_msg).deliver end end @@ -620,7 +628,7 @@ module JamRuby # send email notifications unless offline_followers.empty? - UserMailer.band_recording_saved(offline_followers.map! {|f| f.email}, notification_msg) + UserMailer.band_recording_saved(offline_followers.map! {|f| f.email}, notification_msg).deliver end end @@ -704,7 +712,7 @@ module JamRuby @@mq_router.publish_to_user(receiver.id, msg) else - UserMailer.band_invitation(receiver.email, notification_msg) + UserMailer.band_invitation(receiver.email, notification_msg).deliver end end @@ -731,7 +739,7 @@ module JamRuby @@mq_router.publish_to_user(receiver.id, msg) else - UserMailer.band_invitation_accepted(receiver.email, notification_msg) + UserMailer.band_invitation_accepted(receiver.email, notification_msg).deliver end end diff --git a/ruby/spec/jam_ruby/models/geo_ip_blocks_spec.rb b/ruby/spec/jam_ruby/models/geo_ip_blocks_spec.rb new file mode 100644 index 000000000..dd914143c --- /dev/null +++ b/ruby/spec/jam_ruby/models/geo_ip_blocks_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe GeoIpBlocks do + + before do + GeoIpBlocks.delete_all + GeoIpBlocks.make_row(0x00000000, 0xffffffff, 17192) + end + + it "count" do GeoIpBlocks.count.should == 1 end + + let(:first) { GeoIpBlocks.lookup(0x01020304) } + let(:second) { GeoIpBlocks.lookup(0x02030405) } + let(:seventh) { GeoIpBlocks.lookup(9999999999) } # bogus + + it "first.locid" do first.locid.should == 17192 end + it "second.locid" do second.locid.should == 17192 end + it "seventh" do seventh.should be_nil end +end diff --git a/ruby/spec/jam_ruby/models/jam_isp_spec.rb b/ruby/spec/jam_ruby/models/jam_isp_spec.rb new file mode 100644 index 000000000..b68b309f7 --- /dev/null +++ b/ruby/spec/jam_ruby/models/jam_isp_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +describe JamIsp do + + before do + JamIsp.delete_all + JamIsp.make_row(0x01020300, 0x010203ff, 1) + JamIsp.make_row(0x02030400, 0x020304ff, 2) + JamIsp.make_row(0x03040500, 0x030405ff, 3) + JamIsp.make_row(0x04050600, 0x040506ff, 4) + JamIsp.make_row(0xc0A80100, 0xc0A801ff, 5) + JamIsp.make_row(0xfffefd00, 0xfffefdff, 6) + end + + after do + JamIsp.delete_all + JamIsp.make_row(0x00000000, 0xffffffff, 1) + end + + it "count" do JamIsp.count.should == 6 end + + let(:first_addr) { JamIsp.ip_to_num('1.2.3.4') } + let(:second_addr) { JamIsp.ip_to_num('2.3.4.5') } + let(:third_addr) { JamIsp.ip_to_num('3.4.5.6') } + let(:fourth_addr) { JamIsp.ip_to_num('4.5.6.7') } + let(:fifth_addr) { JamIsp.ip_to_num('192.168.1.107') } + let(:sixth_addr) { JamIsp.ip_to_num('255.254.253.252') } + + it "first_addr" do first_addr.should == 0x01020304 end + it "second_addr" do second_addr.should == 0x02030405 end + it "third_addr" do third_addr.should == 0x03040506 end + it "fourth_addr" do fourth_addr.should == 0x04050607 end + it "fifth_addr" do fifth_addr.should == 0xc0A8016b end + it "sixth_addr" do sixth_addr.should == 0xfffefdfc end + + let(:first) { JamIsp.lookup(0x01020304) } + let(:second) { JamIsp.lookup(0x02030405) } + let(:third) { JamIsp.lookup(0x03040506) } + let(:fourth) { JamIsp.lookup(0x04050607) } + let(:fifth) { JamIsp.lookup(0xc0A8016b) } + let(:sixth) { JamIsp.lookup(0xfffefdfc) } + let(:seventh) { JamIsp.lookup(0) } # bogus + + it "first.coid" do first.coid.should == 1 end + it "second.coid" do second.coid.should == 2 end + it "third.coid" do third.coid.should == 3 end + it "fourth.coid" do fourth.coid.should == 4 end + it "fifth.coid" do fifth.coid.should == 5 end + it "sixth.coid" do sixth.coid.should == 6 end + it "seventh" do seventh.should be_nil end +end diff --git a/ruby/spec/jam_ruby/models/max_mind_geo_spec.rb b/ruby/spec/jam_ruby/models/max_mind_geo_spec.rb index 1df42817d..08cfb0766 100644 --- a/ruby/spec/jam_ruby/models/max_mind_geo_spec.rb +++ b/ruby/spec/jam_ruby/models/max_mind_geo_spec.rb @@ -35,4 +35,3 @@ describe MaxMindGeo do it { third.ip_start.should == '1.0.1.0' } it { third.ip_end.should == '1.0.1.255' } end - diff --git a/web/app/assets/javascripts/addNewGear.js b/web/app/assets/javascripts/addNewGear.js index e835ef4b9..26af81510 100644 --- a/web/app/assets/javascripts/addNewGear.js +++ b/web/app/assets/javascripts/addNewGear.js @@ -3,12 +3,14 @@ "use strict"; context.JK = context.JK || {}; - context.JK.AddNewGearDialog = function(app) { + context.JK.AddNewGearDialog = function(app, sessionScreen) { var logger = context.JK.logger; function events() { $('#btn-leave-session-test').click(function() { + sessionScreen.setPromptLeave(false); + app.layout.closeDialog('configure-audio'); context.location = "/client#/home"; diff --git a/web/app/assets/javascripts/fakeJamClient.js b/web/app/assets/javascripts/fakeJamClient.js index ea2d54535..95d997168 100644 --- a/web/app/assets/javascripts/fakeJamClient.js +++ b/web/app/assets/javascripts/fakeJamClient.js @@ -10,6 +10,7 @@ // Change this to false if you want to see FTUE with fake jam client var ftueStatus = true; var eventCallbackName = ''; + var alertCallbackName = ''; var eventCallbackRate = 1000; var vuValue = -70; var vuChange = 10; @@ -304,7 +305,12 @@ } function SessionSetAlertCallback(callback) { + alertCallbackName = callback; + // simulate a backend alert + /**setTimeout(function() { + eval(alertCallbackName + '(27)'); + }, 3000)*/ } function SessionSetConnectionStatusRefreshRate(milliseconds) { @@ -357,6 +363,7 @@ vuValue += vuChange; if (vuValue > 10 || vuValue < -70) { vuChange = vuChange * -1; } + } function SetVURefreshRate(rateMS) { eventCallbackRate = rateMS; diff --git a/web/app/assets/javascripts/jamkazam.js b/web/app/assets/javascripts/jamkazam.js index 6356d15f7..0db35ebe6 100644 --- a/web/app/assets/javascripts/jamkazam.js +++ b/web/app/assets/javascripts/jamkazam.js @@ -49,6 +49,7 @@ targetUrl = target, targetArg = $(this).attr('layout-arg'), fn = function (data) { + data.screen = target; app.layout.changeToScreen(target, data); }; if (targetArg) { @@ -59,7 +60,7 @@ }); routes.context(routingContext); for (rule in rules) if (rules.hasOwnProperty(rule)) routes.add(rules[rule]); - $(context).bind('hashchange', routes.handler); + $(context).bind('hashchange', function(e) { app.layout.onHashChange(e, routes.handler)}); $(routes.handler); } diff --git a/web/app/assets/javascripts/layout.js b/web/app/assets/javascripts/layout.js index 2788ecfdb..1ed20ff15 100644 --- a/web/app/assets/javascripts/layout.js +++ b/web/app/assets/javascripts/layout.js @@ -52,6 +52,7 @@ var expandedPanel = null; var previousScreen = null; var currentScreen = null; + var currentHash = null; var screenBindings = {}; var dialogBindings = {}; @@ -59,6 +60,8 @@ var openDialogs = []; // FIFO stack + var resettingHash = false; + function setup() { requiredStyles(); hideAll(); @@ -434,7 +437,7 @@ function screenEvent(screen, evtName, data) { if (screen && screen in screenBindings) { if (evtName in screenBindings[screen]) { - screenBindings[screen][evtName].call(me, data); + return screenBindings[screen][evtName].call(me, data); } } } @@ -451,40 +454,52 @@ return true; } - function onSessionLeaveWarningAccepted(args) { - changeScreen(args.screen, args.data); - } + function onHashChange(e, postFunction) { - function onSessionLeaveWarningDeclined() { - context.location = "/client#/session/" + context.JK.CurrentSessionModel.id(); - closeDialog('leave-session-warning'); + if(resettingHash) { + resettingHash = false; + e.preventDefault(); + return false; + } + + try { + var location = context.RouteMap.parse(context.location.hash); + } + catch (e) { + // this is nowhere in the rich client; just let it go through + return postFunction(e); + } + + var screen = location.page.substring(1); // remove leading slash + var accepted = screenEvent(currentScreen, 'beforeLeave', {screen:screen, hash: context.location.hash}); + if(accepted === false) { + console.log("navigation to " + context.location.hash + " rejected by " + currentScreen); + resettingHash = true; + // reset the hash to where it just was + context.location.hash = currentHash; + } + else { + // not rejected by the screen; let it go + return postFunction(e); + } } function changeToScreen(screen, data) { if (screen === currentScreen) { return; } - // special case to prompt user if they really want to leave session - if (currentScreen === "session") { - var args = {}; - args.screen = screen; - args.data = data; - var leaveSessionWarningDialog = new context.JK.LeaveSessionWarningDialog(context.JK.app, onSessionLeaveWarningAccepted, onSessionLeaveWarningDeclined, args); - leaveSessionWarningDialog.initialize(); - showDialog('leave-session-warning'); - return; - } - else { - changeScreen(screen, data); - } + changeScreen(screen, data); } function changeScreen(screen, data) { previousScreen = currentScreen; currentScreen = screen; + currentHash = context.location.hash; + + var accepted = screenEvent(previousScreen, 'beforeHide', data); + if(accepted === false) return; - screenEvent(previousScreen, 'beforeHide', data); screenEvent(currentScreen, 'beforeShow', data); // For now -- it seems we want it open always. @@ -811,6 +826,10 @@ changeToScreen(screen, data); }; + this.onHashChange = function(e, postFunction) { + return onHashChange(e, postFunction); + } + this.showDialog = function (dialog) { showDialog(dialog); }; diff --git a/web/app/assets/javascripts/leaveSessionWarning.js b/web/app/assets/javascripts/leaveSessionWarning.js index e7ec15f5a..9c2cd2f84 100644 --- a/web/app/assets/javascripts/leaveSessionWarning.js +++ b/web/app/assets/javascripts/leaveSessionWarning.js @@ -3,25 +3,19 @@ "use strict"; context.JK = context.JK || {}; - context.JK.LeaveSessionWarningDialog = function(app, acceptCallback, declinedCallback, args) { + context.JK.LeaveSessionWarningDialog = function(app, acceptCallback) { var logger = context.JK.logger; var dialogId = 'leave-session-warning'; var $scopeSelector = "[layout-id='leave-session-warning']"; function events() { - $('#btn-accept', $scopeSelector).click(function(evt) { + $('#btn-accept-leave-session', $scopeSelector).click(function(evt) { if (acceptCallback) { - acceptCallback(args); + acceptCallback(); } app.layout.closeDialog(dialogId); }); - - $('#btn-cancel', $scopeSelector).click(function(evt) { - if (declinedCallback) { - declinedCallback(); - } - }); } function initialize() { diff --git a/web/app/assets/javascripts/session.js b/web/app/assets/javascripts/session.js index 31c6610f1..887b4b98d 100644 --- a/web/app/assets/javascripts/session.js +++ b/web/app/assets/javascripts/session.js @@ -5,6 +5,7 @@ context.JK = context.JK || {}; context.JK.SessionScreen = function(app) { var logger = context.JK.logger; + var self = this; var sessionModel = null; var sessionId; var tracks = {}; @@ -28,7 +29,7 @@ var startingRecording = false; // double-click guard var claimedRecording = null; var playbackControls = null; - + var promptLeave = false; var rest = JK.Rest(); @@ -127,6 +128,7 @@ function beforeShow(data) { sessionId = data.id; + promptLeave = true; $('#session-mytracks-container').empty(); displayDoneRecording(); // assumption is that you can't join a recording session, so this should be safe @@ -203,6 +205,11 @@ "icon_url": "/assets/content/icon_alert_big.png" }); } + else if (type === 27) { // WINDOW_CLOSE_BACKGROUND_MODE + // the window was closed; just attempt to nav to home, which will cause all the right REST calls to happen + promptLeave = false; + context.location = '/client#/home' + } else { context.setTimeout(function() { var alert = alert_type[type]; @@ -411,6 +418,7 @@ .fail(function(xhr, textStatus, errorMessage) { if(xhr.status == 404) { // we tried to join the session, but it's already gone. kick user back to join session screen + promptLeave = false; context.window.location = "/client#/findSession"; app.notify( { title: "Unable to Join Session", @@ -424,10 +432,21 @@ }); } + function beforeLeave(data) { + if(promptLeave) { + var leaveSessionWarningDialog = new context.JK.LeaveSessionWarningDialog(context.JK.app, + function() { promptLeave = false; context.location.hash = data.hash }); + + leaveSessionWarningDialog.initialize(); + app.layout.showDialog('leave-session-warning'); + return false; + } + } + function beforeHide(data) { - screenActive = false; - sessionModel.leaveCurrentSession() - .fail(app.ajaxError); + screenActive = false; + sessionModel.leaveCurrentSession() + .fail(app.ajaxError); } function handleTransitionsInRecordingPlayback() { @@ -839,7 +858,7 @@ }); configureTrackDialog = new context.JK.ConfigureTrackDialog(app, myTracks, sessionId, sessionModel); - addNewGearDialog = new context.JK.AddNewGearDialog(app); + addNewGearDialog = new context.JK.AddNewGearDialog(app, self); } function connectTrackToMixer(trackSelector, clientId, mixerId, gainPercent) { @@ -1399,7 +1418,8 @@ var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow, - 'beforeHide': beforeHide + 'beforeHide': beforeHide, + 'beforeLeave' : beforeLeave }; app.bindScreen('session', screenBindings); }; @@ -1415,6 +1435,10 @@ sessionModel.refreshCurrentSession(); }; + this.setPromptLeave = function(_promptLeave) { + promptLeave = _promptLeave; + } + context.JK.HandleVolumeChangeCallback = handleVolumeChangeCallback; context.JK.HandleBridgeCallback = handleBridgeCallback; context.JK.AlertCallback = alertCallback; diff --git a/web/app/assets/javascripts/sidebar.js b/web/app/assets/javascripts/sidebar.js index 32e91cea1..d670f8ea6 100644 --- a/web/app/assets/javascripts/sidebar.js +++ b/web/app/assets/javascripts/sidebar.js @@ -143,6 +143,7 @@ var template = $('#template-notification-panel').html(); var notificationHtml = context.JK.fillTemplate(template, { notificationId: val.notification_id, + sessionId: val.sessionId, avatar_url: context.JK.resolveAvatarUrl(val.photo_url), text: val.formatted_msg, date: context.JK.formatDateTime(val.created_at) @@ -158,13 +159,14 @@ function initializeActions(payload, type) { var $notification = $('li[notification-id=' + payload.notification_id + ']'); + var $btnNotificationAction = '#btn-notification-action'; // wire up "x" button to delete notification $notification.find('#img-delete-notification').click(deleteNotificationHandler); // customize action buttons based on notification type if (type === context.JK.MessageType.FRIEND_REQUEST) { - var $action_btn = $notification.find('#btn-notification-action'); + var $action_btn = $notification.find($btnNotificationAction); $action_btn.text('ACCEPT'); $action_btn.click(function() { acceptFriendRequest({ "friend_request_id": payload.friend_request_id, "notification_id": payload.notification_id }); @@ -180,7 +182,7 @@ } else if (type === context.JK.MessageType.SESSION_INVITATION) { - var $action_btn = $notification.find('#btn-notification-action'); + var $action_btn = $notification.find($btnNotificationAction); $action_btn.text('JOIN'); $action_btn.click(function() { openTerms({ "session_id": payload.session_id, "notification_id": payload.notification_id }); @@ -188,7 +190,7 @@ } else if (type === context.JK.MessageType.JOIN_REQUEST) { - var $action_btn = $notification.find('#btn-notification-action'); + var $action_btn = $notification.find($btnNotificationAction); $action_btn.text('APPROVE'); $action_btn.click(function() { approveJoinRequest({ "join_request_id": payload.join_request_id, "notification_id": payload.notification_id }); @@ -196,7 +198,7 @@ } else if (type === context.JK.MessageType.JOIN_REQUEST_APPROVED) { - var $action_btn = $notification.find('#btn-notification-action'); + var $action_btn = $notification.find($btnNotificationAction); $action_btn.text('JOIN'); $action_btn.click(function() { openTerms({ "session_id": payload.session_id, "notification_id": payload.notification_id }); @@ -208,15 +210,17 @@ } else if (type === context.JK.MessageType.MUSICIAN_SESSION_JOIN || type === context.JK.MessageType.BAND_SESSION_JOIN) { - var $action_btn = $notification.find('#btn-notification-action'); + var $action_btn = $notification.find($btnNotificationAction); $action_btn.text('LISTEN'); + $action_btn.attr('href', '/sessions/' + payload.session_id); + $action_btn.attr('rel', 'external'); $action_btn.click(function() { listenToSession({ "session_id": payload.session_id, "notification_id": payload.notification_id }); }); } else if (type === context.JK.MessageType.MUSICIAN_RECORDING_SAVED || type === context.JK.MessageType.BAND_RECORDING_SAVED) { - var $action_btn = $notification.find('#btn-notification-action'); + var $action_btn = $notification.find($btnNotificationAction); $action_btn.text('LISTEN'); $action_btn.click(function() { listenToRecording({ "recording_id": payload.recording_id, "notification_id": payload.notification_id }); @@ -229,7 +233,7 @@ } else if (type === context.JK.MessageType.BAND_INVITATION) { - var $action_btn = $notification.find('#btn-notification-action'); + var $action_btn = $notification.find($btnNotificationAction); $action_btn.text('ACCEPT'); $action_btn.click(function() { acceptBandInvitation({ "band_invitation_id": payload.band_invitation_id, "band_id": payload.band_id, "notification_id": payload.notification_id }); @@ -335,6 +339,7 @@ var template = $("#template-notification-panel").html(); var notificationHtml = context.JK.fillTemplate(template, { notificationId: payload.notification_id, + sessionId: payload.session_id, avatar_url: context.JK.resolveAvatarUrl(payload.photo_url), text: sidebarText, date: context.JK.formatDateTime(payload.created_at) @@ -553,8 +558,7 @@ var participants = []; rest.getSession(payload.session_id).done(function(response) { $.each(response.participants, function(index, val) { - logger.debug(val.user.photo_url + "," + val.user.name); - participants.push({"photo_url": val.user.photo_url, "name": val.user.name}); + participants.push({"photo_url": context.JK.resolveAvatarUrl(val.user.photo_url), "name": val.user.name}); }); }).error(app.ajaxError); @@ -563,7 +567,7 @@ $.each(participants, function(index, val) { if (index < 4) { - participantHtml += "" + val.name + ""; + participantHtml += "" + val.name + ""; } }); @@ -593,6 +597,17 @@ function registerSessionEnded() { // TODO: this should clean up all notifications related to this session + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SESSION_ENDED, function(header, payload) { + logger.debug("Handling SESSION_ENDED msg " + JSON.stringify(payload)); + deleteSessionNotifications(payload.session_id); + }); + } + + // remove all notifications for this session + function deleteSessionNotifications(sessionId) { + console.log("sessionId=%o", sessionId); + $('li[session-id=' + sessionId + ']').hide(); + decrementNotificationCount(); } function registerJoinRequest() { @@ -681,13 +696,8 @@ var recordingId = payload.recording_id; - if(recordingId&& context.JK.CurrentSessionModel.recordingModel.isRecording(recordingId)) { + if(recordingId && context.JK.CurrentSessionModel.recordingModel.isRecording(recordingId)) { context.JK.CurrentSessionModel.recordingModel.onServerStopRecording(recordingId); - /**app.notify({ - "title": "Recording Stopped", - "text": payload.username + " has left the session.", - "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) - }); */ } else { app.notify({ @@ -713,7 +723,8 @@ "ok_text": "LISTEN", "ok_callback": listenToSession, "ok_callback_args": { - "session_id": payload.session_id + "session_id": payload.session_id, + "notification_id": payload.notification_id } }); }); @@ -734,7 +745,8 @@ "ok_text": "LISTEN", "ok_callback": listenToSession, "ok_callback_args": { - "session_id": payload.session_id + "session_id": payload.session_id, + "notification_id": payload.notification_id } }); }); @@ -742,7 +754,7 @@ function listenToSession(args) { deleteNotification(args.notification_id); - context.location = '/client#/session/' + args.session_id; + context.JK.popExternalLink('/recordings/' + args.session_id); } function registerMusicianRecordingSaved() { @@ -759,7 +771,8 @@ "ok_text": "LISTEN", "ok_callback": listenToRecording, "ok_callback_args": { - "recording_id": payload.recording_id + "recording_id": payload.recording_id, + "notification_id": payload.notification_id } }); }); @@ -780,7 +793,8 @@ "ok_text": "LISTEN", "ok_callback": listenToRecording, "ok_callback_args": { - "recording_id": payload.recording_id + "recording_id": payload.recording_id, + "notification_id": payload.notification_id } }); }); @@ -788,7 +802,7 @@ function listenToRecording(args) { deleteNotification(args.notification_id); - context.location = '/client#/recording/' + args.recording_id; + context.JK.popExternalLink('/recordings/' + args.recording_id); } function registerRecordingStarted() { diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js index 2cc124c70..8af730244 100644 --- a/web/app/assets/javascripts/utils.js +++ b/web/app/assets/javascripts/utils.js @@ -549,6 +549,22 @@ }); } + context.JK.popExternalLink = function(href) { + if(!context.jamClient) { + return; + } + + if (href) { + // make absolute if not already + if(href.indexOf('http') != 0 && href.indexOf('mailto') != 0) { + href = window.location.protocol + '//' + window.location.host + href; + } + + context.jamClient.OpenSystemBrowser(href); + } + return false; + } + context.JK.checkbox = function($checkbox) { $checkbox.iCheck({ checkboxClass: 'icheckbox_minimal', diff --git a/web/app/assets/stylesheets/client/client.css b/web/app/assets/stylesheets/client/client.css index d92534feb..c403ed71f 100644 --- a/web/app/assets/stylesheets/client/client.css +++ b/web/app/assets/stylesheets/client/client.css @@ -40,6 +40,8 @@ *= require ./recordingFinishedDialog *= require ./localRecordingsDialog *= require ./serverErrorDialog + *= require ./leaveSessionWarning + *= require ./terms *= require ./createSession *= require ./genreSelector *= require ./sessionList diff --git a/web/app/assets/stylesheets/client/leaveSessionWarning.css.scss b/web/app/assets/stylesheets/client/leaveSessionWarning.css.scss new file mode 100644 index 000000000..807353886 --- /dev/null +++ b/web/app/assets/stylesheets/client/leaveSessionWarning.css.scss @@ -0,0 +1,8 @@ +#leave-session-warning { + max-width:550px; + min-height:0; + p { + line-height:22px; + } + +} \ No newline at end of file diff --git a/web/app/assets/stylesheets/client/terms.css.scss b/web/app/assets/stylesheets/client/terms.css.scss new file mode 100644 index 000000000..107e307eb --- /dev/null +++ b/web/app/assets/stylesheets/client/terms.css.scss @@ -0,0 +1,7 @@ +#session-terms-conditions { + max-width:550px; + min-height:0; + p { + line-height:22px; + } +} \ No newline at end of file diff --git a/web/app/views/clients/_leaveSessionWarning.html.erb b/web/app/views/clients/_leaveSessionWarning.html.erb index cdb5c2ee4..6bf5005ec 100644 --- a/web/app/views/clients/_leaveSessionWarning.html.erb +++ b/web/app/views/clients/_leaveSessionWarning.html.erb @@ -1,21 +1,21 @@ -
+
<%= image_tag "content/icon_alert.png", {:width => 19, :height => 19, :class => 'content-icon' } %>

Warning

- +

WARNING: This action will result in you leaving this session. You will no longer be able to transmit or hear audio. Click OK below to proceed. - +



-
- CANCEL +
+ OK
- OK + CANCEL
-
+
\ No newline at end of file diff --git a/web/app/views/clients/_sidebar.html.erb b/web/app/views/clients/_sidebar.html.erb index 10c6a0bd5..77e5e9489 100644 --- a/web/app/views/clients/_sidebar.html.erb +++ b/web/app/views/clients/_sidebar.html.erb @@ -170,9 +170,9 @@ <% end %> diff --git a/web/spec/features/in_session_spec.rb b/web/spec/features/in_session_spec.rb index 9bd595f2d..992e459a9 100644 --- a/web/spec/features/in_session_spec.rb +++ b/web/spec/features/in_session_spec.rb @@ -54,7 +54,7 @@ describe "In a Session", :js => true, :type => :feature, :capybara_feature => tr find('#btn-leave-session-test').trigger(:click) wait_for_ajax - expect(page).to have_selector('h1', text: 'audio gear setup') + expect(page).to have_selector('h1', text: 'audio gear settings') end leave_music_session_sleep_delay diff --git a/websocket-gateway/spec/factories.rb b/websocket-gateway/spec/factories.rb index 4bc7c87a6..35f0c4b84 100644 --- a/websocket-gateway/spec/factories.rb +++ b/websocket-gateway/spec/factories.rb @@ -39,7 +39,7 @@ FactoryGirl.define do countrycode 'US' region 'TX' city 'Austin' - ip_address "1.1.1.1" + ip_address '1.1.1.1' as_musician true end