* VRFS-1228

This commit is contained in:
Seth Call 2014-02-25 19:22:32 +00:00
parent 89a5f2747e
commit 7a41b74549
11 changed files with 145 additions and 89 deletions

View File

@ -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

View File

@ -105,6 +105,10 @@ def app_config
100
end
def send_join_session_email_notifications
true
end
private
def audiomixer_workspace_path

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -61,8 +61,27 @@
<span id="profile-recording-stats"></span><br />
</div>
<div class="profile-about-right">
<p id="profile-biography"></p><br />
<div id="profile-instruments"></div>
<div class="no-bio">
<span>You have no bio to describe yourself as a musician. <a href="#" class="enter-bio">Enter one now!</a></span>
</div>
<div class="have-bio">
<p id="profile-biography"></p><a id="profile-edit-biography" class="button-orange right" href="#">Edit Bio</a>
</div>
<div class="update-biography">
<div class="field">
<textarea name="biography" class="user-biography"></textarea>
</div>
<br clear="left" /><br />
<div class="right">
<a id="btn-update-user-biography" layout-action="close" class="button-orange">OK</a>
</div>
<div class="right">
<a id="btn-cancel-user-biography" layout-action="close" class="button-grey">CANCEL</a>
</div>
<br clear="all" />
</div>
<br />
<div id="profile-instruments"></div>
</div>
<br clear="all" />
</div>
@ -192,24 +211,3 @@
<div class="profile-block-city">{location}</div>
</div>
</script>
<script type="text/template" id="template-add-user-profile">
<div>
<span>You have no bio to describe yourself as a musician. <a href="#" class="enter-bio">Enter one now!</a></span>
<div class="update-biography">
<div class="field">
<textarea name="biography" class="user-biography"/>
</div>
<br clear="left" /><br />
<div class="right">
<a id="btn-update-user-biography" layout-action="close" class="button-orange">OK</a>
</div>
<div class="right">
<a id="btn-cancel-user-biography" layout-action="close" class="button-grey">CANCEL</a>
</div>
<br clear="all" />
</div>
<div>
</script>

View File

@ -207,5 +207,7 @@ if defined?(Bundler)
config.autocheck_create_session_agreement = false
config.max_audio_downloads = 100
config.send_join_session_email_notifications = true
end
end

View File

@ -45,7 +45,7 @@ SampleApp::Application.configure do
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = false
config.assets.debug = true
# Set the logging destination(s)
config.log_to = %w[stdout file]
@ -55,6 +55,7 @@ SampleApp::Application.configure do
config.websocket_gateway_enable = true
TEST_CONNECT_STATES = false
# Overloaded value to match production for using cloudfront in dev mode
@ -77,4 +78,6 @@ SampleApp::Application.configure do
# set CREATE_SESSION_AGREEMENT=0 if you don't want the autoclick behavior
config.autocheck_create_session_agreement = ENV['CREATE_SESSION_AGREEMENT'] ? ENV['CREATE_SESSION_AGREEMENT'] == "1" : true
config.send_join_session_email_notifications = false
end