diff --git a/ruby/lib/jam_ruby/models/notification.rb b/ruby/lib/jam_ruby/models/notification.rb
index 6bb3ec67a..3acda624f 100644
--- a/ruby/lib/jam_ruby/models/notification.rb
+++ b/ruby/lib/jam_ruby/models/notification.rb
@@ -1,6 +1,8 @@
module JamRuby
class Notification < ActiveRecord::Base
+ @@log = Logging.logger[Notification]
+
self.primary_key = 'id'
default_scope order('created_at DESC')
@@ -504,7 +506,11 @@ module JamRuby
# send email notifications
unless offline_ff.empty?
- UserMailer.musician_session_join(offline_ff.map! {|f| f.email}, notification_msg).deliver
+ begin
+ UserMailer.musician_session_join(offline_ff.map! {|f| f.email}, notification_msg).deliver if APP_CONFIG.send_join_session_email_notifications
+ rescue => e
+ @@log.error("unable to send email to offline participants #{e}")
+ end
end
end
end
diff --git a/ruby/spec/support/utilities.rb b/ruby/spec/support/utilities.rb
index ab6c023f3..564ec7b34 100644
--- a/ruby/spec/support/utilities.rb
+++ b/ruby/spec/support/utilities.rb
@@ -105,6 +105,10 @@ def app_config
100
end
+ def send_join_session_email_notifications
+ true
+ end
+
private
def audiomixer_workspace_path
diff --git a/web/app/assets/javascripts/layout.js b/web/app/assets/javascripts/layout.js
index d8d164ac5..aa24db43e 100644
--- a/web/app/assets/javascripts/layout.js
+++ b/web/app/assets/javascripts/layout.js
@@ -456,6 +456,8 @@
function onHashChange(e, postFunction) {
+ if(currentHash == context.location.hash) { return }
+
if(resettingHash) {
resettingHash = false;
e.preventDefault();
@@ -474,7 +476,7 @@
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;
+ //resettingHash = true;
// reset the hash to where it just was
context.location.hash = currentHash;
}
diff --git a/web/app/assets/javascripts/profile.js b/web/app/assets/javascripts/profile.js
index 8924d9ae5..569cbdb03 100644
--- a/web/app/assets/javascripts/profile.js
+++ b/web/app/assets/javascripts/profile.js
@@ -11,6 +11,7 @@
var rest = context.JK.Rest();
var decrementedFriendCountOnce = false;
var sentFriendRequest = false;
+ var profileScreen = null;
var instrument_logo_map = context.JK.getInstrumentIconMap24();
@@ -307,6 +308,7 @@
}
function bindAbout() {
+
$('#profile-instruments').empty();
// name
@@ -359,61 +361,93 @@
$('#profile-favorite-stats').html(user.favorite_count + text);
}
- if(isCurrentUser) {
+ renderBio();
+ }
+
+ /** The biography show/edit functionality */
+ function renderBio() {
+
+
+ function initializeBioVisibility() {
+
+ $showBio.hide();
+ $noBio.hide();
+ $biographyEditor.hide();
+
+ $bioTextArea.val(user.biography);
+
if(user.biography) {
- $('#profile-biography').text(user.biography);
+ $showBio.show();
+ if(isCurrentUser()) {
+ $editBiographyButton.show();
+ }
+ $biographyText.text(user.biography).show();
}
else {
- var createBio = $(context._.template($('#template-add-user-profile').html(), {}, { variable: 'data' }));
- $('a.enter-bio', createBio).click(function() {
- $('.update-biography').show();
- return false;
- });
-
- $('#btn-update-user-biography', createBio).click(function() {
- var $bio = $('#profile-biography .user-biography');
- var bio = $bio.val();
- $bio.closest('div.field').removeClass('error');
- $('.error-text', $bio.closest('div.field')).remove();
- rest.updateUser({
- biography: bio
- })
- .done(function(response) {
- if(response.biography){
- $('#profile-biography').text(response.biography);
- } else {
- $('.update-biography').hide();
- }
- })
- .fail(function(jqXHR) {
- if(jqXHR.status == 422) {
- var errors = JSON.parse(jqXHR.responseText)
- var biography = context.JK.format_errors("biography", errors);
- if(biography != null) {
- $bio.closest('div.field').addClass('error').end().after(biography);
- }
- else {
- app.notifyServerError(jqXHR, "Unable to update biography")
- }
- }
- else {
- app.notifyServerError(jqXHR, "Unable to update biography")
- }
- })
- return false;
- });
-
- $('#btn-cancel-user-biography', createBio).click(function() {
- $('.update-biography').hide();
- return false;
- });
- $('#profile-biography').html(createBio);
+ if(isCurrentUser()) {
+ $noBio.show();
+ }
}
}
- else {
- $('#profile-biography').text(user.biography);
- }
+ var $bioTextArea = $('.user-biography', profileScreen);
+ var $showBio = $('.have-bio', profileScreen);
+ var $noBio = $('.no-bio', profileScreen);
+ var $biographyEditor = $('.update-biography', profileScreen);
+ var $addBiographyButton = $('a.enter-bio', profileScreen);
+ var $editBiographyButton = $('#profile-edit-biography', profileScreen);
+ var $submitBiographyButton = $('#btn-update-user-biography', profileScreen);
+ var $cancelBiographyButton = $('#btn-cancel-user-biography', profileScreen);
+ var $biographyText = $('#profile-biography', profileScreen);
+
+ initializeBioVisibility();
+
+ $addBiographyButton.unbind('click').click(function() {
+ $biographyEditor.val(user.biography).show();
+ return false;
+ });
+
+ $editBiographyButton.unbind('click').click(function() {
+ $editBiographyButton.hide();
+ $biographyText.hide();
+ $bioTextArea.val(user.biography);
+ $biographyEditor.show();
+ return false;
+ })
+
+ $submitBiographyButton.unbind('click').click(function() {
+ var bio = $bioTextArea.val();
+ $bioTextArea.closest('div.field').removeClass('error');
+ $('.error-text', $bioTextArea.closest('div.field')).remove();
+ userDefer = rest.updateUser({
+ biography: bio
+ })
+ .done(function(response) {
+ user = response;
+ initializeBioVisibility();
+ })
+ .fail(function(jqXHR) {
+ if(jqXHR.status == 422) {
+ var errors = JSON.parse(jqXHR.responseText)
+ var biography = context.JK.format_errors("biography", errors);
+ if(biography != null) {
+ $bioTextArea.closest('div.field').addClass('error').end().after(biography);
+ }
+ else {
+ app.notifyServerError(jqXHR, "Unable to update biography")
+ }
+ }
+ else {
+ app.notifyServerError(jqXHR, "Unable to update biography")
+ }
+ })
+ return false;
+ })
+
+ $cancelBiographyButton.unbind('click').click(function() {
+ initializeBioVisibility();
+ return false;
+ })
}
/****************** SOCIAL TAB *****************/
@@ -696,7 +730,7 @@
'afterShow': afterShow
};
app.bindScreen('profile', screenBindings);
-
+ profileScreen = $('#user-profile');
events();
}
diff --git a/web/app/assets/javascripts/session.js b/web/app/assets/javascripts/session.js
index 768004dae..5b99f3b15 100644
--- a/web/app/assets/javascripts/session.js
+++ b/web/app/assets/javascripts/session.js
@@ -279,6 +279,10 @@
// a client can only be in one session at a time,
// and other parts of the code want to know at any certain times
// about the current session, if any (for example, reconnect logic)
+ if(context.JK.CurrentSessionModel) {
+ context.JK.CurrentSessionModel.unsubscribe();
+ }
+
context.JK.CurrentSessionModel = sessionModel = new context.JK.SessionModel(
context.JK.app,
context.JK.JamServer,
@@ -442,6 +446,7 @@
app.layout.showDialog('leave-session-warning');
return false;
}
+ return true;
}
function beforeHide(data) {
diff --git a/web/app/assets/javascripts/sessionModel.js b/web/app/assets/javascripts/sessionModel.js
index 6c975cdb1..d80436f8a 100644
--- a/web/app/assets/javascripts/sessionModel.js
+++ b/web/app/assets/javascripts/sessionModel.js
@@ -100,7 +100,10 @@
logger.debug("SessionModel.leaveCurrentSession()");
// TODO - sessionChanged will be called with currentSession = null
server.unregisterMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, refreshCurrentSession);
- server.unregisterMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_DEPART, refreshCurrentSession);
+ server.unregisterMessageCallback(context.JK.MessageType.SESSION_JOIN, refreshCurrentSession);
+ server.unregisterMessageCallback(context.JK.MessageType.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
// 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
@@ -143,7 +146,7 @@
*/
function refreshCurrentSession() {
// XXX use backend instead: https://jamkazam.atlassian.net/browse/VRFS-854
- logger.debug("SessionModel.refreshCurrentSession()");
+ logger.debug("SessionModel.refreshCurrentSession(" + currentSessionId +")");
refreshCurrentSessionRest(sessionChanged);
}
@@ -171,6 +174,7 @@
if(sessionData != null) {
currentOrLastSession = sessionData;
}
+
currentSession = sessionData;
}
@@ -189,7 +193,6 @@
$.ajax({
type: "GET",
url: url,
- async: false,
success: function(response) {
sendClientParticipantChanges(currentSession, response);
updateCurrentSession(response);
@@ -378,8 +381,7 @@
var url = "/api/participants/" + clientId;
return $.ajax({
type: "DELETE",
- url: url,
- async: true
+ url: url
});
}
@@ -489,6 +491,12 @@
this.getCurrentOrLastSession = function() {
return currentOrLastSession;
};
+ this.unsubscribe = function() {
+ server.unregisterMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, refreshCurrentSession);
+ server.unregisterMessageCallback(context.JK.MessageType.SESSION_JOIN, refreshCurrentSession);
+ server.unregisterMessageCallback(context.JK.MessageType.SESSION_DEPART, refreshCurrentSession);
+ }
+
};
})(window,jQuery);
\ No newline at end of file
diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js
index e0cd22df3..098ce3fb3 100644
--- a/web/app/assets/javascripts/utils.js
+++ b/web/app/assets/javascripts/utils.js
@@ -248,6 +248,7 @@
//
// use context._.template for something more powerful
context.JK.fillTemplate = function(template, vals) {
+ if(template == null) throw 'null template in fillTemplate'
for(var val in vals)
template=template.replace(new RegExp('{'+val+'}','g'), vals[val]);
return template;
diff --git a/web/app/assets/stylesheets/client/profile.css.scss b/web/app/assets/stylesheets/client/profile.css.scss
index 8a93e1872..f1c207801 100644
--- a/web/app/assets/stylesheets/client/profile.css.scss
+++ b/web/app/assets/stylesheets/client/profile.css.scss
@@ -1,20 +1,13 @@
@import "client/common.css.scss";
#user-profile {
- #profile-biography {
- a.enter-bio {
-
- }
+ .profile-about-right {
textarea {
width:100%;
height:150px;
padding:0;
}
-
- .update-biography {
- display:none;
- }
}
}
diff --git a/web/app/views/clients/_profile.html.erb b/web/app/views/clients/_profile.html.erb
index 908b44667..8df180292 100644
--- a/web/app/views/clients/_profile.html.erb
+++ b/web/app/views/clients/_profile.html.erb
@@ -61,8 +61,27 @@