jam-cloud/web/app/assets/javascripts/notificationPanel.js

1374 lines
47 KiB
JavaScript

(function(context,$) {
"use strict";
context.JK = context.JK || {};
context.JK.NotificationPanel = function(app) {
var EVENTS = context.JK.EVENTS;
var logger = context.JK.logger;
var friends = [];
var rest = context.JK.Rest();
var missedNotificationsWhileAway = false;
var $panel = null;
var $expanded = null;
var $contents = null;
var $count = null;
var $list = null;
var $notificationTemplate = null;
var sidebar = null;
var darkenedColor = '#0D7B89';
var highlightedColor = 'white'
var textMessageDialog = null;
var queuedNotification = null;
var queuedNotificationCreatedAt = null;
var sessionUtils = context.JK.SessionUtils;
var notificationBatchSize = 20;
var currentNotificationPage = 0;
var didLoadAllNotifications = false, isLoading = false;
var ui = new context.JK.UIHelper(JK.app);
function isNotificationsPanelVisible() {
return $contents.is(':visible')
}
function incrementNotificationCount() {
var count = parseInt($count.text());
setCount(count + 1);
}
function decrementNotificationCount() {
var count = parseInt($count.text());
if(count > 0) {
count = count - 1;
setCount(count);
if(count == 0) {
lowlightCount();
missedNotificationsWhileAway = false;
}
}
}
// set the element to white, and pulse it down to the un-highlighted value 2x, then set
function pulseToDark() {
logger.debug("pulsing notification badge")
lowlightCount();
$count.pulse({'background-color' : highlightedColor}, {pulses: 2}, function() {
$count.removeAttr('style')
setCount(0);
})
}
function setCount(count) {
$count.text(count);
}
function lowlightCount() {
$count.removeClass('highlighted');
}
function highlightCount() {
$count.addClass('highlighted');
}
function queueNotificationSeen(notificationId, notificationCreatedAt, type) {
var time = new Date(notificationCreatedAt);
if(!notificationCreatedAt) {
throw 'invalid value passed to queuedNotificationCreatedAt'
}
if(!queuedNotificationCreatedAt) {
queuedNotification = notificationId;
queuedNotificationCreatedAt = notificationCreatedAt;
logger.debug("updated queuedNotificationCreatedAt with: " + notificationCreatedAt);
}
else if(time.getTime() > new Date(queuedNotificationCreatedAt).getTime()) {
queuedNotification = notificationId;
queuedNotificationCreatedAt = notificationCreatedAt;
logger.debug("updated queuedNotificationCreatedAt with: " + notificationCreatedAt);
}
else {
logger.debug("ignored queuedNotificationCreatedAt for: " + notificationCreatedAt);
}
}
function onNotificationOccurred(payload) {
if(userCanSeeNotifications(payload)) {
app.updateNotificationSeen(payload.notification_id, payload.created_at);
}
else {
if(app.layout.isNoisyNotification(payload) && !missedNotificationsWhileAway) {
// this handles a special case--if a notification is too noisy while away, then don't bother
// incrementing anything on the sidebar or otherwise distracting the user
app.updateNotificationSeen(payload.notification_id, payload.created_at);
}
else {
queueNotificationSeen(payload.notification_id, payload.created_at, payload.description);
highlightCount();
incrementNotificationCount();
missedNotificationsWhileAway = true;
}
}
}
function userCameBack() {
if(isNotificationsPanelVisible()) {
if(missedNotificationsWhileAway) {
// catch user's eye, then put count to 0
pulseToDark();
if(queuedNotificationCreatedAt) {
app.updateNotificationSeen(queuedNotification, queuedNotificationCreatedAt);
}
}
}
queuedNotification = null;
queuedNotificationCreatedAt = null;
missedNotificationsWhileAway = false;
}
function opened() {
queuedNotification = null;
queuedNotificationCreatedAt = null;
rest.updateUser({notification_seen_at: 'LATEST'})
.done(function(response) {
lowlightCount();
setCount(0);
})
.fail(app.ajaxError)
}
function windowBlurred() {
}
function events() {
$(context).on(EVENTS.DIALOG_CLOSED, function(e, data) {if(data.dialogCount == 0) userCameBack(); });
$(window).focus(userCameBack);
$(window).blur(windowBlurred);
app.user()
.done(function(user) {
setCount(user.new_notifications);
if(user.new_notifications > 0) {
highlightCount();
}
});
$panel.on('open', opened);
// friend notifications
registerFriendRequest();
registerFriendRequestAccepted();
registerNewUserFollower();
registerNewBandFollower();
// session notifications
registerSessionInvitation();
registerSessionEnded();
registerJoinRequest();
registerJoinRequestApproved();
registerJoinRequestRejected();
registerMusicianSessionJoin();
registerBandSessionJoin();
// scheduled sessions
registerScheduledSessionInvitation();
registerScheduledSessionRsvp();
registerScheduledSessionRsvpApproved();
registerScheduledSessionRsvpCancelled();
registerScheduledSessionRsvpCancelledOrg();
registerScheduledSessionCancelled();
registerScheduledSessionRescheduled();
registerScheduledSessionReminder();
registerScheduledSessionComment();
// recording notifications
registerMusicianRecordingSaved();
registerBandRecordingSaved();
registerRecordingMasterMixComplete();
registerRecordingStreamMixComplete();
// band notifications
registerBandInvitation();
registerBandInvitationAccepted();
// register text messages
registerTextMessage();
}
function buildParams() {
return { offset: currentNotificationPage * notificationBatchSize, limit: notificationBatchSize};
}
function populate() {
if (isLoading || didLoadAllNotifications) return;
isLoading = true;
// retrieve pending notifications for this user
rest.getNotifications(buildParams())
.done(function(response) {
updateNotificationList(response);
isLoading = false;
})
.fail(function() {
isLoading = false;
app.ajaxError();
})
}
function updateNotificationList(response) {
$.each(response, function(index, val) {
if(val.description == 'TEXT_MESSAGE') {
val.formatted_msg = textMessageDialog.formatTextMessage(val.message.substring(0, 200), val.source_user_id, val.source_user.name, val.message.length > 200).html();
}
// fill in template for Connect pre-click
var template = $notificationTemplate.html();
var notificationHtml = context.JK.fillTemplate(template, {
notificationId: val.notification_id,
sessionId: val.session_id,
hoveraction: val.session_id ? "session" : "",
avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
text: val.formatted_msg,
date: $.timeago(val.created_at),
userId: val.source_user_id
});
$list.append(notificationHtml);
// val.description contains the notification record's description value from the DB (i.e., type)
initializeActions(val, val.description);
});
if(response.length < notificationBatchSize) {
didLoadAllNotifications = true;
}
currentNotificationPage++;
}
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($btnNotificationAction);
$action_btn.text('ACCEPT');
$action_btn.click(function() {
acceptFriendRequest(payload);
});
}
else if (type === context.JK.MessageType.FRIEND_REQUEST_ACCEPTED) {
$notification.find('#div-actions').hide();
}
else if (type === context.JK.MessageType.NEW_USER_FOLLOWER || type === context.JK.MessageType.NEW_BAND_FOLLOWER) {
$notification.find('#div-actions').hide();
}
else if (type === context.JK.MessageType.SESSION_INVITATION) {
var $action_btn = $notification.find($btnNotificationAction);
$action_btn.text('JOIN');
$action_btn.click(function() {
openTerms(payload);
});
}
else if (type === context.JK.MessageType.RECORDING_MASTER_MIX_COMPLETE) {
var $action_btn = $notification.find($btnNotificationAction);
$action_btn.text('SHARE');
$action_btn.click(function() {
rest.getRecording({id: payload.recording_id})
.done(function(recording) {
if(recording.my) {
ui.launchShareDialog(recording.my.id, 'recording');
}
else {
context.JK.Banner.showAlert('Unable to share recording')
}
})
.fail(app.ajaxError)
});
}
else if (type === context.JK.MessageType.RECORDING_STREAM_MIX_COMPLETE) {
var $action_btn = $notification.find($btnNotificationAction);
$action_btn.text('SHARE');
$action_btn.click(function() {
rest.getRecording({id: payload.recording_id})
.done(function(recording) {
if(recording.my) {
ui.launchShareDialog(recording.my.id, 'recording');
}
else {
context.JK.Banner.showAlert('Unable to share recording')
}
})
.fail(app.ajaxError)
});
}
else if (type === context.JK.MessageType.JOIN_REQUEST) {
var $action_btn = $notification.find($btnNotificationAction);
$action_btn.text('APPROVE');
$action_btn.click(function() {
approveJoinRequest(payload);
});
}
else if (type === context.JK.MessageType.JOIN_REQUEST_APPROVED) {
var $action_btn = $notification.find($btnNotificationAction);
$action_btn.text('JOIN');
$action_btn.click(function() {
openTerms(payload);
});
}
else if (type === context.JK.MessageType.JOIN_REQUEST_REJECTED) {
$notification.find('#div-actions').hide();
}
else if (type === context.JK.MessageType.MUSICIAN_SESSION_JOIN || type === context.JK.MessageType.BAND_SESSION_JOIN) {
var actionText = '';
var callback;
if (context.JK.currentUserMusician) {
// user is MUSICIAN; musician_access = TRUE
if (payload.musician_access) {
actionText = "JOIN";
callback = joinSession;
}
// user is MUSICIAN; fan_access = TRUE
else if (payload.fan_access) {
actionText = "LISTEN";
callback = listenToSession;
}
}
else {
// user is FAN; fan_access = TRUE
if (payload.fan_access) {
actionText = "LISTEN";
callback = listenToSession;
}
}
var $action_btn = $notification.find($btnNotificationAction);
if (actionText === '') {
$action_btn.hide();
}
else {
$action_btn.text(actionText);
$action_btn.click(function() {
callback(payload);
});
}
}
else if (type === context.JK.MessageType.MUSICIAN_RECORDING_SAVED || type === context.JK.MessageType.BAND_RECORDING_SAVED) {
var $action_btn = $notification.find($btnNotificationAction);
$action_btn.text('LISTEN');
$action_btn.click(function() {
listenToRecording(payload);
});
}
else if (type === context.JK.MessageType.RECORDING_MASTER_MIX_COMPLETE) {
$notification.find('#div-actions').hide();
logger.debug("context.jamClient.OnDownloadAvailable!")
context.jamClient.OnDownloadAvailable(); // poke backend, letting it know a download is available
}
else if (type === context.JK.MessageType.BAND_INVITATION) {
var $action_btn = $notification.find($btnNotificationAction);
$action_btn.text('ACCEPT');
$action_btn.click(function() {
acceptBandInvitation(payload);
});
}
else if (type === context.JK.MessageType.BAND_INVITATION_ACCEPTED) {
$notification.find('#div-actions').hide();
}
else if (type === context.JK.MessageType.TEXT_MESSAGE) {
var $action_btn = $notification.find($btnNotificationAction);
$action_btn.text('REPLY');
$action_btn.click(function() {
var userId = $notification.find('.more-text-available').attr('data-sender-id');
app.layout.showDialog('text-message', { d1: userId });
});
var moreTextLink = $notification.find('.more-text-available');
var textMessage = $notification.find('.text-message');
var clipped_msg = textMessage.attr('data-is-clipped') === 'true';
if(clipped_msg) {
moreTextLink.text('more').show();
moreTextLink.click(function(e) {
var userId = $(this).attr('data-sender-id');
app.layout.showDialog('text-message', { d1: userId });
return false;
});
}
else {
moreTextLink.hide();
}
}
else if (type === context.JK.MessageType.SCHEDULED_SESSION_INVITATION) {
linkSessionInfoNotification(payload, $notification, $btnNotificationAction);
}
else if (type === context.JK.MessageType.SCHEDULED_SESSION_RSVP) {
var $action_btn = $notification.find($btnNotificationAction);
$action_btn.text('MANAGE RSVP');
$action_btn.click(function() {
context.location = "/client#/account/sessionDetail/" + payload.session_id;
});
}
else if (type === context.JK.MessageType.SCHEDULED_SESSION_RSVP_APPROVED) {
linkSessionInfoNotification(payload, $notification, $btnNotificationAction);
}
else if (type === context.JK.MessageType.SCHEDULED_SESSION_RSVP_CANCELLED) {
linkSessionInfoNotification(payload, $notification, $btnNotificationAction);
}
else if (type === context.JK.MessageType.SCHEDULED_SESSION_RSVP_CANCELLED_ORG) {
linkSessionInfoNotification(payload, $notification, $btnNotificationAction);
}
else if (type === context.JK.MessageType.SCHEDULED_SESSION_CANCELLED) {
linkSessionInfoNotification(payload, $notification, $btnNotificationAction);
}
else if (type === context.JK.MessageType.SCHEDULED_SESSION_RESCHEDULED) {
linkSessionInfoNotification(payload, $notification, $btnNotificationAction);
}
else if (type === context.JK.MessageType.SCHEDULED_SESSION_REMINDER) {
linkSessionInfoNotification(payload, $notification, $btnNotificationAction);
}
else if (type === context.JK.MessageType.SCHEDULED_SESSION_COMMENT) {
linkSessionInfoNotification(payload, $notification, $btnNotificationAction);
}
context.JK.bindHoverEvents($("#sidebar-div"));
}
function linkSessionInfoNotification(payload, $notification, $btnNotificationAction) {
var $action_btn = $notification.find($btnNotificationAction);
$action_btn.text('SESSION DETAILS');
$action_btn.click(function() {
openSessionInfoWebPage({"session_id": payload.session_id});
});
}
function acceptBandInvitation(args) {
rest.updateBandInvitation(
args.band_id,
args.band_invitation_id,
true
).done(function(response) {
deleteNotification(args.notification_id); // delete notification corresponding to this friend request
}).error(app.ajaxError);
}
function deleteNotification(notificationId) {
var url = "/api/users/" + context.JK.currentUserId + "/notifications/" + notificationId;
$.ajax({
type: "DELETE",
dataType: "json",
contentType: 'application/json',
url: url,
processData: false,
success: function(response) {
var notification = $('li[notification-id=' + notificationId + ']');
if(notification.length > 0) {
decrementNotificationCount();
}
notification.remove();
},
error: app.ajaxError
});
}
function listenToSession(args) {
deleteNotification(args.notification_id);
context.JK.popExternalLink('/sessions/' + args.session_id);
}
function joinSession(args) {
sessionUtils.joinSession(args.session_id);
deleteNotification(args.notification_id);
}
function registerJoinRequestApproved() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.JOIN_REQUEST_APPROVED, function(header, payload) {
logger.debug("Handling JOIN_REQUEST_APPROVED msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Join Request Approved",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-join",
text: "JOIN SESSION",
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: openTerms,
callback_args: {
"session_id": payload.session_id,
"notification_id": payload.notification_id
}
}]
);
});
}
function registerJoinRequestRejected() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.JOIN_REQUEST_REJECTED, function(header, payload) {
logger.debug("Handling JOIN_REQUEST_REJECTED msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Join Request Rejected",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
});
});
}
function registerJoinRequest() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.JOIN_REQUEST, function(header, payload) {
logger.debug("Handling JOIN_REQUEST msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "New Join Request",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-approve",
text: "APPROVE",
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: approveJoinRequest,
callback_args: {
"join_request_id": payload.join_request_id,
"notification_id": payload.notification_id
}
},
{
id: "btn-reject",
text: "REJECT",
"layout-action": "close",
href: "#",
"class": "button-grey",
callback: rejectJoinRequest,
callback_args: {
"join_request_id": payload.join_request_id,
"notification_id": payload.notification_id
}
}]
);
});
}
function registerFriendRequestAccepted() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_REQUEST_ACCEPTED, function(header, payload) {
logger.debug("Handling FRIEND_REQUEST_ACCEPTED msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
sidebar.refreshFriends();
app.notify({
"title": "Friend Request Accepted",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
});
});
}
function registerNewUserFollower() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.NEW_USER_FOLLOWER, function(header, payload) {
logger.debug("Handling NEW_USER_FOLLOWER msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "New Follower",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
});
});
}
function registerNewBandFollower() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.NEW_BAND_FOLLOWER, function(header, payload) {
logger.debug("Handling NEW_BAND_FOLLOWER msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "New Band Follower",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
});
});
}
function registerFriendRequest() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_REQUEST, function(header, payload) {
logger.debug("Handling FRIEND_REQUEST msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "New Friend Request",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-accept",
text: "ACCEPT",
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: acceptFriendRequest,
callback_args: {
"friend_request_id": payload.friend_request_id,
"notification_id": payload.notification_id
}
}]
);
});
}
function acceptFriendRequest(args) {
rest.acceptFriendRequest({
status: 'accept',
friend_request_id: args.friend_request_id
}).done(function(response) {
deleteNotification(args.notification_id); // delete notification corresponding to this friend request
sidebar.refreshFriends(); // refresh friends panel when request is accepted
}).error(app.ajaxError);
}
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) {
$('li[session-id=' + sessionId + ']').hide();
//decrementNotificationCount();
}
function registerSessionInvitation() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SESSION_INVITATION, function(header, payload) {
logger.debug("Handling SESSION_INVITATION msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Session Invitation",
"text": payload.msg
}, [{
id: "btn-join",
text: "JOIN SESSION",
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: openTerms,
callback_args: {
"session_id": payload.session_id,
"notification_id": payload.notification_id
}
}]
);
// THERE IS A RACE CONDITION THAT CAUSES AN ERROR WHEN INVOKING THE CODE BELOW
// THE ACTIVEMUSICSESSION HAS NOT YET BEEN FULLY CREATED B/C THE CREATOR'S CLIENT IS
// STILL SETTING UP THE SESSION WHEN THE NOTIFICATION IS SENT
// SEE ActiveMusicSession#participant_create
// var participants = [];
// rest.getSession(payload.session_id)
// .done(function(response) {
// $.each(response.participants, function(index, val) {
// participants.push({"photo_url": context.JK.resolveAvatarUrl(val.user.photo_url), "name": val.user.name});
// });
// var participantHtml = "You have been invited to join a session with: <br/><br/>";
// participantHtml += "<table><tbody>";
// $.each(participants, function(index, val) {
// if (index < 4) {
// participantHtml += "<tr><td><img class='avatar-small' src='" + context.JK.resolveAvatarUrl(val.photo_url) + "' /></td><td>" + val.name + "</td></tr>";
// }
// });
// participantHtml += "</tbody></table>";
// app.notify({
// "title": "Session Invitation",
// "text": participantHtml
// }, [{
// id: "btn-join",
// text: "JOIN SESSION",
// "layout-action": "close",
// href: "#",
// "class": "button-orange",
// callback: openTerms,
// callback_args: {
// "session_id": payload.session_id,
// "notification_id": payload.notification_id
// }
// }]
// );
// }).error(app.ajaxError);
});
}
function registerMusicianSessionJoin() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, function(header, payload) {
logger.debug("Handling MUSICIAN_SESSION_JOIN msg " + JSON.stringify(payload));
var okText = '';
var showNotification = false;
var callback;
if (context.JK.currentUserMusician) {
// user is MUSICIAN; musician_access = TRUE
if (payload.musician_access) {
showNotification = true;
okText = "JOIN";
callback = joinSession;
}
// user is MUSICIAN; fan_access = TRUE
else if (payload.fan_access) {
showNotification = true;
okText = "LISTEN";
callback = listenToSession;
}
}
else {
// user is FAN; fan_access = TRUE
if (payload.fan_access) {
showNotification = true;
okText = "LISTEN";
callback = listenToSession;
}
}
if (showNotification) {
handleNotification(payload, header.type);
app.notify({
"title": "Musician Joined Session",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-action",
text: okText,
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: callback,
callback_args: {
"session_id": payload.session_id,
"fan_access": payload.fan_access,
"musician_access": payload.musician_access,
"approval_required": payload.approval_required,
"notification_id": payload.notification_id
}
}]
);
}
});
}
function registerBandSessionJoin() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.BAND_SESSION_JOIN, function(header, payload) {
logger.debug("Handling BAND_SESSION_JOIN msg " + JSON.stringify(payload));
var okText = '';
var showNotification = false;
var callback;
if (context.JK.currentUserMusician) {
// user is MUSICIAN; musician_access = TRUE
if (payload.musician_access) {
showNotification = true;
okText = "JOIN";
callback = joinSession;
}
// user is MUSICIAN; fan_access = TRUE
else if (payload.fan_access) {
showNotification = true;
okText = "LISTEN";
callback = listenToSession;
}
}
else {
// user is FAN; fan_access = TRUE
if (payload.fan_access) {
showNotification = true;
okText = "LISTEN";
callback = listenToSession;
}
}
if (showNotification) {
handleNotification(payload, header.type);
app.notify({
"title": "Band Joined Session",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-listen",
text: okText,
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: callback,
callback_args: {
"session_id": payload.session_id,
"fan_access": payload.fan_access,
"musician_access": payload.musician_access,
"approval_required": payload.approval_required,
"notification_id": payload.notification_id
}
}]
);
}
});
}
function registerScheduledSessionInvitation() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SCHEDULED_SESSION_INVITATION, function(header, payload) {
logger.debug("Handling SCHEDULED_SESSION_INVITATION msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Session Invitation",
"text": payload.msg + "<br/><br/>" + payload.session_name + "<br/>" + payload.session_date,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-more-info",
text: "MORE INFO",
rel: "external",
"class": "button-orange",
callback: openSessionInfoWebPage,
callback_args: {
"session_id": payload.session_id
}
}]
);
});
}
function registerScheduledSessionRsvp() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SCHEDULED_SESSION_RSVP, function(header, payload) {
logger.debug("Handling SCHEDULED_SESSION_RSVP msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Session RSVP",
"text": payload.msg + "<br/><br/>" + payload.session_name + "<br/>" + payload.session_date,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-manage-rsvp",
text: "MANAGE RSVP",
"class": "button-orange",
callback: navigateToSessionDetails,
callback_args: {
"session_id": payload.session_id
}
}]
);
});
}
function registerScheduledSessionRsvpApproved() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SCHEDULED_SESSION_RSVP_APPROVED, function(header, payload) {
logger.debug("Handling SCHEDULED_SESSION_RSVP_APPROVED msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Session RSVP Approved!",
"text": payload.msg + "<br/><br/>" + payload.session_name + "<br/>" + payload.session_date,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-session-details",
text: "SESSION DETAILS",
"layout-action": "close",
rel: "external",
"class": "button-orange",
callback: openSessionInfoWebPage,
callback_args: {
"session_id": payload.session_id
}
}]
);
});
}
function registerScheduledSessionRsvpCancelled() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SCHEDULED_SESSION_RSVP_CANCELLED, function(header, payload) {
logger.debug("Handling SCHEDULED_SESSION_RSVP_CANCELLED msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Session RSVP Cancelled",
"text": payload.msg + "<br/><br/>" + payload.session_name + "<br/>" + payload.session_date,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-session-details",
text: "SESSION DETAILS",
rel: "external",
"class": "button-orange",
callback: openSessionInfoWebPage,
callback_args: {
"session_id": payload.session_id
}
}]
);
});
}
function registerScheduledSessionRsvpCancelledOrg() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SCHEDULED_SESSION_RSVP_CANCELLED_ORG, function(header, payload) {
logger.debug("Handling SCHEDULED_SESSION_RSVP_CANCELLED_ORG msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Session RSVP Cancelled",
"text": payload.msg + "<br/><br/>" + payload.session_name + "<br/>" + payload.session_date,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-session-details",
text: "SESSION DETAILS",
rel: "external",
"class": "button-orange",
callback: openSessionInfoWebPage,
callback_args: {
"session_id": payload.session_id
}
}]
);
});
}
function registerScheduledSessionCancelled() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SCHEDULED_SESSION_CANCELLED, function(header, payload) {
logger.debug("Handling SCHEDULED_SESSION_CANCELLED msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Session Cancelled",
"text": payload.msg + "<br/><br/>" + payload.session_name + "<br/>" + payload.session_date,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-session-details",
text: "SESSION DETAILS",
rel: "external",
"class": "button-orange",
callback: openSessionInfoWebPage,
callback_args: {
"session_id": payload.session_id
}
}]
);
});
}
function registerScheduledSessionRescheduled() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SCHEDULED_SESSION_RESCHEDULED, function(header, payload) {
logger.debug("Handling SCHEDULED_SESSION_RESCHEDULED msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Session Rescheduled",
"text": payload.msg + "<br/><br/>" + payload.session_name + "<br/>" + payload.session_date,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-session-details",
text: "SESSION DETAILS",
rel: "external",
"class": "button-orange",
callback: openSessionInfoWebPage,
callback_args: {
"session_id": payload.session_id
}
}]
);
});
}
function registerScheduledSessionReminder() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SCHEDULED_SESSION_REMINDER, function(header, payload) {
logger.debug("Handling SCHEDULED_SESSION_REMINDER msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Session Reminder",
"text": payload.msg + "<br/><br/>" + payload.session_name + "<br/>" + payload.session_date,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-session-details",
text: "SESSION DETAILS",
rel: "external",
"class": "button-orange",
callback: openSessionInfoWebPage,
callback_args: {
"session_id": payload.session_id
}
}]
);
});
}
function registerScheduledSessionComment() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SCHEDULED_SESSION_COMMENT, function(header, payload) {
logger.debug("Handling SCHEDULED_SESSION_COMMENT msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Session Comment",
"text": payload.msg + "<br/><br/>" + payload.session_name + "<br/>" + payload.session_date,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-session-details",
text: "SESSION DETAILS",
rel: "external",
"class": "button-orange",
callback: openSessionInfoWebPage,
callback_args: {
"session_id": payload.session_id
}
}]
);
});
}
function registerMusicianRecordingSaved() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.MUSICIAN_RECORDING_SAVED, function(header, payload) {
logger.debug("Handling MUSICIAN_RECORDING_SAVED msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Musician Recording Saved",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-listen",
text: "LISTEN",
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: listenToRecording,
callback_args: {
"recording_id": payload.recording_id,
"notification_id": payload.notification_id
}
}]
);
});
}
function registerBandRecordingSaved() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.BAND_RECORDING_SAVED, function(header, payload) {
logger.debug("Handling BAND_RECORDING_SAVED msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Band Recording Saved",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-listen",
text: "LISTEN",
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: listenToRecording,
callback_args: {
"recording_id": payload.recording_id,
"notification_id": payload.notification_id
}
}]
);
});
}
function registerRecordingMasterMixComplete() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.RECORDING_MASTER_MIX_COMPLETE, function(header, payload) {
logger.debug("Handling RECORDING_MASTER_MIX_COMPLETE msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Recording Master Mix Complete",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-share",
text: "SHARE",
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: shareRecording,
callback_args: {
"claimed_recording_id": payload.claimed_recording_id
}
}]
);
});
}
function registerRecordingStreamMixComplete() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.RECORDING_STREAM_MIX_COMPLETE, function(header, payload) {
logger.debug("Handling RECORDING_STREAM_MIX_COMPLETE msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Recording Stream Mix Complete",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-share",
text: "SHARE",
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: shareRecording,
callback_args: {
"claimed_recording_id": payload.claimed_recording_id
}
}]
);
});
}
function shareRecording(args) {
var claimedRecordingId = args.claimed_recording_id;
ui.launchShareDialog(claimedRecordingId, 'recording');
}
function registerBandInvitation() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.BAND_INVITATION, function(header, payload) {
logger.debug("Handling BAND_INVITATION msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Band Invitation",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}, [{
id: "btn-accept",
text: "ACCEPT",
"layout-action": "close",
href: "#",
"class": "button-orange",
callback: acceptBandInvitation,
callback_args: {
"band_invitation_id": payload.band_invitation_id,
"band_id": payload.band_id,
"notification_id": payload.notification_id
}
}]
);
});
}
function registerTextMessage() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.TEXT_MESSAGE, function(header, payload) {
logger.debug("Handling TEXT_MESSAGE msg " + JSON.stringify(payload));
textMessageDialog.messageReceived(payload);
handleNotification(payload, header.type);
});
}
function registerBandInvitationAccepted() {
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.BAND_INVITATION_ACCEPTED, function(header, payload) {
logger.debug("Handling BAND_INVITATION_ACCEPTED msg " + JSON.stringify(payload));
handleNotification(payload, header.type);
app.notify({
"title": "Band Invitation Accepted",
"text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
});
});
}
// one important limitation; if the user is focused on an iframe, this will be false
// however, if they are doing something with Facebook or the photo picker, this may actually still be desirable
function userCanSeeNotifications(payload) {
return document.hasFocus() && !app.layout.dialogObscuredNotification(payload);
}
// default handler for incoming notification
function handleNotification(payload, type) {
// on a load of notifications, it is possible to load a very new notification,
// and get a websocket notification right after for that same notification,
// so we need to protect against such duplicates
if($list.find('li[notification-id="' + payload.notification_id + '"]').length > 0) {
return false;
}
// add notification to sidebar
var template = $notificationTemplate.html();
var notificationHtml = context.JK.fillTemplate(template, {
notificationId: payload.notification_id,
sessionId: payload.session_id,
hoveraction: payload.session_id ? "session" : "",
avatar_url: context.JK.resolveAvatarUrl(payload.photo_url),
text: payload.msg instanceof jQuery ? payload.msg.html() : payload.msg ,
date: $.timeago(payload.created_at)
});
$list.prepend(notificationHtml);
onNotificationOccurred(payload);
initializeActions(payload, type);
return true;
}
function approveJoinRequest(args) {
rest.updateJoinRequest(args.join_request_id, true)
.done(function(response) {
deleteNotification(args.notification_id);
}).error(app.ajaxError);
}
function openTerms(args) {
var termsDialog = new context.JK.TermsDialog(app, args, onTermsAccepted);
termsDialog.initialize();
app.layout.showDialog('terms');
}
function onTermsAccepted(args) {
deleteNotification(args.notification_id);
context.location = '/client#/session/' + args.session_id;
}
function rejectJoinRequest(args) {
rest.updateJoinRequest(args.join_request_id, false)
.done(function(response) {
deleteNotification(args.notification_id);
}).error(app.ajaxError);
}
function listenToRecording(args) {
deleteNotification(args.notification_id);
context.JK.popExternalLink('/recordings/' + args.recording_id);
}
function navigateToSessionDetails(args) {
context.location = '/client#/account/sessionDetail/' + args.session_id;
}
function openSessionInfoWebPage(args) {
context.JK.popExternalLink('/sessions/' + args.session_id + '/details');
}
function deleteNotificationHandler(evt) {
evt.stopPropagation();
var notificationId = $(this).attr('notification-id');
deleteNotification(notificationId);
}
function registerNotificationScroll() {
$('.notification-scroller').scroll(function() {
var wintop = $('.notification-scroller').scrollTop();
var winheight = $('.notification-scroller').height();
var docheight = $('#sidebar-notification-list').height();
var scrollTrigger = 0.90;
// console.log("notification scroll: wintop="+wintop+" docheight="+docheight+" winheight="+winheight+" ratio="+(wintop / (docheight - winheight)));
if ((wintop / (docheight - winheight)) > scrollTrigger) {
populate();
}
});
}
function initialize(sidebarInstance, textMessageDialogInstance) {
sidebar = sidebarInstance;
textMessageDialog = textMessageDialogInstance;
$panel = $('[layout-id="panelNotifications"]');
$expanded = $panel.find('.panel.expanded');
$contents = $panel.find('.panelcontents');
$count = $panel.find('#sidebar-notification-count');
$list = $panel.find('#sidebar-notification-list');
$notificationTemplate = $('#template-notification-panel');
if($panel.length == 0) throw "notifications panel not found"
if($expanded.length == 0) throw "notifications expanded content not found"
if($contents.length == 0) throw "notifications contents not found"
if($count.length == 0) throw "notifications count element not found";
if($list.length == 0) throw "notification list element not found";
if($notificationTemplate.length == 0) throw "notification template not found";
registerNotificationScroll();
events();
populate();
};
this.initialize = initialize;
this.onNotificationOccurred = onNotificationOccurred;
};
})(window, jQuery);