diff --git a/web/app/assets/javascripts/layout.js b/web/app/assets/javascripts/layout.js index aec9eecca..970307673 100644 --- a/web/app/assets/javascripts/layout.js +++ b/web/app/assets/javascripts/layout.js @@ -99,7 +99,9 @@ layoutScreens(width, height); layoutSidebar(width, height); layoutHeader(width, height); - layoutNotify(width, height); + layoutNotify1(width, height); + layoutNotify2(width, height); + layoutNotify3(width, height); layoutFooter(width, height); $(document).triggerHandler('layout_resized'); @@ -325,14 +327,41 @@ $('[layout="header"]').css(css); } - function layoutNotify(screenWidth, screenHeight) { - var $notify = $('[layout="notify"]'); - var nHeight = $notify.height(); + function layoutNotify1(screenWidth, screenHeight) { + var $notify1 = $('[layout="notify1"]'); + //var nHeight = $notify1.height(); var notifyStyle = { bottom: '0px', - position: 'fixed' + position: 'fixed', + padding: '20px' }; - $notify.css(notifyStyle); + $notify1.css(notifyStyle); + } + + function layoutNotify2(screenWidth, screenHeight) { + var $notify1 = $('[layout="notify1"]'); + var $notify2 = $('[layout="notify2"]'); + var nHeight = $notify1.height(); + var notifyStyle = { + bottom: (nHeight + 41).toString()+'px', + position: 'fixed', + padding: '20px' + }; + $notify2.css(notifyStyle); + } + + function layoutNotify3(screenWidth, screenHeight) { + var $notify1 = $('[layout="notify1"]'); + var $notify2 = $('[layout="notify2"]'); + var $notify3 = $('[layout="notify3"]'); + var nHeight1 = $notify1.height(); + var nHeight2 = $notify2.height(); + var notifyStyle = { + bottom: (nHeight1 + nHeight2 + 41 + 41).toString()+'px', + position: 'fixed', + padding: '20px' + }; + $notify3.css(notifyStyle); } function layoutFooter(screenWidth, screenHeight) { @@ -806,6 +835,16 @@ return false; } + function expandNotificationPanel(){ + if(!context.JK.currentUserId) { + showDialog('login-required-dialog'); + return false; + } + expandedPanel = 'panelNotifications'; + layout(); + return false; + } + function wizardLinkClicked(evt) { evt.preventDefault(); var targetStepId = $(evt.currentTarget).attr("layout-wizard-link"); @@ -915,8 +954,73 @@ // used for concurrent notifications var notifyQueue = []; - var firstNotification = false; - var notifyDetails; + var notify1Showing = false; + var notify2Showing = false; + var notify3Showing = false; + var isMouseOverNotify1 = false; + var isMouseOverNotify2 = false; + var isMouseOverNotify3 = false; + var notify1Elapsed = false; + var notify2Elapsed = false; + var notify3Elapsed = false; + + var $notify1 = $('[layout="notify1"]'); + var $notify2 = $('[layout="notify2"]'); + var $notify3 = $('[layout="notify3"]'); + + $notify1.on('mouseenter', mouseEnterNotification) + $notify1.on('mouseleave', mouseLeaveToNotification) + $notify2.on('mouseenter', mouseEnterNotification) + $notify2.on('mouseleave', mouseLeaveToNotification) + $notify3.on('mouseenter', mouseEnterNotification) + $notify3.on('mouseleave', mouseLeaveToNotification) + + function mouseEnterNotification(evt){ + var $notify = $(evt.target); + console.log("mouseEnter", $notify.prop("id")); + switch($notify.prop("id")){ + case 'notification1': + isMouseOverNotify1 = true; + break; + case 'notification2': + isMouseOverNotify2 = true; + break; + case 'notification3': + isMouseOverNotify3 = true; + break; + } + } + + function mouseLeaveToNotification(evt){ + var $notify = $(evt.target); + console.log("mouseLeave", $notify.prop("id")); + switch($notify.prop("id")){ + case 'notification1': + if(notify1Elapsed){ + $notify1.hide(0); + notify1Showing = false; + } + isMouseOverNotify1 = false; + break; + case 'notification2': + if(notify2Elapsed){ + $notify2.hide(0); + notify2Showing = false; + } + isMouseOverNotify2 = false; + break; + case 'notification3': + if(notify3Elapsed){ + $notify3.hide(0); + notify3Showing = false; + } + isMouseOverNotify3 = false; + break; + } + } + + //var firstNotification = false; + //var notifyDetails; var okButton = { id: "btn-okay", @@ -939,7 +1043,58 @@ cancelButton ]; + // this.notify = function (message, buttons, noCancel) { + // if (!buttons) { + // if (noCancel) { + // buttons = [okButton]; + // } + // else { + // buttons = defaultButtons; + // } + // } + + // // this allows clients to just specify the important action button without having to repeat the cancel descripton everywhere + // if (buttons.length === 1) { + // // jkolyer: changed default to remove cancel as this is used as an alert, not a confirmation (see ConfirmDialog) + // // buttons.push(cancelButton); + // } + + // var $notify = $('[layout="notify"]'); + + // if (notifyQueue.length === 0) { + // firstNotification = true; + // setNotificationInfo(message, buttons, $notify); + // } + + // notifyQueue.push({message: message, descriptor: buttons}); + // // JW - speeding up the in/out parts of notify. Extending non-moving time. + // $notify.hide(0) + // .show({ + // duration: 0, + // queue: true, + // complete: function () { + // notifyDetails = notifyQueue.shift(); + + // // shift 1 more time if this is first notification being displayed + // if (firstNotification) { + // notifyDetails = notifyQueue.shift(); + // firstNotification = false; + // } + + // if (notifyDetails !== undefined) { + // setNotificationInfo(notifyDetails.message, notifyDetails.descriptor, $notify); + // } + + // notifyDetails = {}; + // } + // }) + // .delay(8000) + // .hide(0) + // }; + this.notify = function (message, buttons, noCancel) { + console.log("call this.notify"); + if (!buttons) { if (noCancel) { buttons = [okButton]; @@ -949,46 +1104,182 @@ } } - // this allows clients to just specify the important action button without having to repeat the cancel descripton everywhere - if (buttons.length === 1) { - // jkolyer: changed default to remove cancel as this is used as an alert, not a confirmation (see ConfirmDialog) - // buttons.push(cancelButton); - } - - var $notify = $('[layout="notify"]'); - - if (notifyQueue.length === 0) { - firstNotification = true; - setNotificationInfo(message, buttons, $notify); - } - notifyQueue.push({message: message, descriptor: buttons}); - // JW - speeding up the in/out parts of notify. Extending non-moving time. - $notify.slideDown(250) - .delay(4000) - .slideUp({ - duration: 400, - queue: true, - complete: function () { - notifyDetails = notifyQueue.shift(); - // shift 1 more time if this is first notification being displayed - if (firstNotification) { - notifyDetails = notifyQueue.shift(); - firstNotification = false; + showNotificationToast(); + + } + + function showNotificationToast(){ + if(!notify1Showing){ + var notifyDetails1 = notifyQueue.shift(); + if (notifyDetails1 !== undefined) { + setNotificationInfo(notifyDetails1.message, notifyDetails1.descriptor, $notify1); + notify1Elapsed = false; + $notify1.hide(0) + .show({ + duration: 0, + //queue: true, + complete: function () { + console.log("Show notification1") + notify1Showing = true; + notifyDetails1 = {}; } - - if (notifyDetails !== undefined) { - setNotificationInfo(notifyDetails.message, notifyDetails.descriptor, $notify); + }) + //.delay(8000); + + setTimeout(function(){ + notify1Elapsed = true; + if(!isMouseOverNotify1){ + $notify1.hide(0, function(){ + notify1Showing = false; + console.log("Hide notification1") + }) } + }, 8000) + + } - notifyDetails = {}; - } - }); - }; + }else if(!notify2Showing){ + var notifyDetails2 = notifyQueue.shift(); + if (notifyDetails2 !== undefined) { + setNotificationInfo(notifyDetails2.message, notifyDetails2.descriptor, $notify2); + notify2Elapsed = false; + $notify2.hide(0) + .show({ + duration: 0, + //queue: true, + complete: function () { + console.log("Show notification2") + notify2Showing = true; + notifyDetails2 = {}; + } + }); + // .delay(8000) + // .hide(0, function(){ + // notify2Showing = false; + // console.log("Hide notification2") + // }) + setTimeout(function(){ + notify2Elapsed = true; + if(!isMouseOverNotify2){ + $notify2.hide(0, function(){ + notify2Showing = false; + console.log("Hide notification2") + }) + } + }, 8000); + } + + }else if(!notify3Showing){ + var notifyDetails3 = notifyQueue.shift(); + if (notifyDetails3 !== undefined) { + setNotificationInfo(notifyDetails3.message, notifyDetails3.descriptor, $notify3); + notify3Elapsed = false; + $notify3.hide(0) + .show({ + duration: 0, + //queue: true, + complete: function () { + console.log("Show notification3") + notify3Showing = true; + notifyDetails3 = {}; + } + }) + // .delay(8000) + // .hide(0, function(){ + // notify3Showing = false; + // console.log("Hide notification3") + // }) + setTimeout(function(){ + notify3Elapsed = true; + if(!isMouseOverNotify3){ + $notify3.hide(0, function(){ + notify3Showing = false; + console.log("Hide notification3") + }) + } + }, 8000); + } + + }else if(notify1Showing && notify2Showing && notify3Showing){ + //try again after 1 second + setTimeout(function(){ + showNotificationToast() + }, 1000) + } + } + + // function setNotificationInfo(message, buttons, notificationSelector) { + // var $notify = $('[layout="notify"]'); + // $('h2', $notify).text(message.title); + // $('p', $notify).empty(); + // if (message.text instanceof jQuery) { + // $('p', $notify).append(message.text) + // } + // else { + // $('p', $notify).html(message.text); + // } + + // if (message.icon_url) { + // $('#avatar', $notify).attr('src', message.icon_url); + // $('#notify-avatar', $notify).show(); + // } + // else { + // $('#notify-avatar', $notify).hide(); + // } + + // if (message.detail) { + // $('div.detail', $notify).html(message.detail).show(); + // } + // else { + // $('div.detail', $notify).hide(); + // } + + // var $buttonDiv = $('#buttons', $notify); + // $buttonDiv.empty(); + + // $.each(buttons, function(index, val) { + + // // build button HTML based on KV pairs + // var keys = Object.keys(val); + // var buttonHtml = '' + val['text'] + ' '; + // $buttonDiv.append(buttonHtml); + + // // ensure it doesn't fire twice + // $('#' + val.id, $notify).unbind('click'); + + // $('#' + val.id, $notify).click(function() { + // if (val.callback !== undefined) { + // if (val.callback_args) { + // val.callback(val.callback_args); + // } + // else { + // val.callback(); + // } + // return false; + // } + // else { + // notificationSelector.hide(); + // return false; + // } + // }); + // }); + // } function setNotificationInfo(message, buttons, notificationSelector) { - var $notify = $('[layout="notify"]'); + var $notify = notificationSelector; $('h2', $notify).text(message.title); $('p', $notify).empty(); if (message.text instanceof jQuery) { @@ -1048,7 +1339,7 @@ return false; } else { - notificationSelector.hide(); + $notify.hide(); return false; } }); @@ -1093,6 +1384,7 @@ this.getCurrentScreen = function() { return currentScreen; // will be a string of the layout-id of the active screen } + this.close = function (evt) { close(evt); }; @@ -1156,6 +1448,10 @@ events(); }; + this.expandNotificationPanel = function(){ + return expandNotificationPanel() + } + return this; }; diff --git a/web/app/assets/javascripts/notificationPanel.js b/web/app/assets/javascripts/notificationPanel.js index 2cd252382..937def4c6 100644 --- a/web/app/assets/javascripts/notificationPanel.js +++ b/web/app/assets/javascripts/notificationPanel.js @@ -119,7 +119,7 @@ if(isNotificationsPanelVisible()) { if(missedNotificationsWhileAway) { // catch user's eye, then put count to 0 - pulseToDark(); + // pulseToDark(); if(queuedNotificationCreatedAt) { app.updateNotificationSeen(queuedNotification, queuedNotificationCreatedAt); } @@ -147,9 +147,11 @@ } function events() { - $(context).on(EVENTS.DIALOG_CLOSED, function(e, data) {if(data.dialogCount == 0) userCameBack(); }); - $(window).focus(userCameBack); - $(window).blur(windowBlurred); + // $(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); @@ -160,6 +162,8 @@ $panel.on('open', opened); + $contents.on('click', opened); + // friend notifications registerFriendRequest(); registerFriendRequestAccepted(); @@ -582,6 +586,7 @@ } }] ); + context.JK.layout.expandNotificationPanel(); }); } @@ -635,6 +640,7 @@ } }] ); + context.JK.layout.expandNotificationPanel(); }); } @@ -652,6 +658,7 @@ "text": payload.msg, "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) }); + context.JK.layout.expandNotificationPanel(); }); } @@ -692,7 +699,7 @@ logger.debug("Handling FRIEND_REQUEST msg " + JSON.stringify(payload)); handleNotification(payload, header.type); - + app.notify({ "title": "New Friend Request", "text": payload.msg, @@ -710,6 +717,8 @@ } }] ); + context.JK.layout.expandNotificationPanel(); + //opened() }); } @@ -790,6 +799,7 @@ } }] ); + context.JK.layout.expandNotificationPanel(); // 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 @@ -1410,13 +1420,33 @@ $list.prepend(notificationHtml); - onNotificationOccurred(payload); + drawAttentionToNotification(payload, type); + + onNotificationOccurred(payload, type); initializeActions(payload, type); return true; } + function drawAttentionToNotification(payload, type){ + if (type === context.JK.MessageType.FRIEND_REQUEST || + type === context.JK.MessageType.FRIEND_REQUEST_ACCEPTED || + type === context.JK.MessageType.JOIN_REQUEST || + type === context.JK.MessageType.JOIN_REQUEST_APPROVED || + type === context.JK.MessageType.SESSION_INVITATION) { + var $newLi = $list.find('li[notification-id="' + payload.notification_id + '"]'); + $newLi.css("border", "solid 1px #01545f"); + $newLi.css("margin-bottom", "5px"); + $newLi.css("padding", "10px 0"); + $newLi.css("background-color", "#1099aa"); + } + } + + function notificationPanelClick(){ + opened() + } + function approveJoinRequest(args) { rest.updateJoinRequest(args.join_request_id, true) .done(function(response) { diff --git a/web/app/assets/stylesheets/client/notify.scss b/web/app/assets/stylesheets/client/notify.scss index 806f8f790..8891b7a84 100644 --- a/web/app/assets/stylesheets/client/notify.scss +++ b/web/app/assets/stylesheets/client/notify.scss @@ -1,6 +1,6 @@ @import "client/common.scss"; -#notification { +.notification { position:absolute; left:30%; padding:20px; @@ -14,7 +14,7 @@ box-shadow: 0px 0px 15px rgba(50, 50, 50, 1); } -#notification h2 { +.notification h2 { font-size: 1.5em; color:#fff; font-weight:200; @@ -23,7 +23,7 @@ margin-bottom:10px; } -#notification p { +.notification p { margin-bottom:20px; .error-text { @@ -31,7 +31,7 @@ } } -#notification p .text-message { +.notification p .text-message { white-space: pre-wrap; word-wrap: break-word; } diff --git a/web/app/views/clients/_notify.html.erb b/web/app/views/clients/_notify.html.erb index d058e9903..f4d8966d0 100644 --- a/web/app/views/clients/_notify.html.erb +++ b/web/app/views/clients/_notify.html.erb @@ -1,4 +1,4 @@ -