mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Show new chat message notification
This commit is contained in:
parent
596ad4cf1c
commit
c6f51cf5ac
8 changed files with 169 additions and 16 deletions
|
@ -12,7 +12,9 @@ aside.chat(
|
||||||
.loading(ng-show="chat.loading")
|
.loading(ng-show="chat.loading")
|
||||||
i.fa.fa-fw.fa-spin.fa-refresh
|
i.fa.fa-fw.fa-spin.fa-refresh
|
||||||
| Loading...
|
| Loading...
|
||||||
ul.list-unstyled
|
ul.list-unstyled(
|
||||||
|
ng-click="resetUnreadMessages()"
|
||||||
|
)
|
||||||
li.message(
|
li.message(
|
||||||
ng-repeat="message in chat.messages"
|
ng-repeat="message in chat.messages"
|
||||||
ng-controller="ChatMessageController"
|
ng-controller="ChatMessageController"
|
||||||
|
@ -34,6 +36,11 @@ aside.chat(
|
||||||
p(ng-repeat="content in message.contents track by $index") {{ content }}
|
p(ng-repeat="content in message.contents track by $index") {{ content }}
|
||||||
|
|
||||||
.new-message
|
.new-message
|
||||||
textarea(placeholder="Your message...", on-enter="sendMessage()", ng-model="newMessageContent")
|
textarea(
|
||||||
|
placeholder="Your message...",
|
||||||
|
on-enter="sendMessage()",
|
||||||
|
ng-model="newMessageContent",
|
||||||
|
ng-click="resetUnreadMessages()"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,4 +64,9 @@ header.toolbar.toolbar-header(ng-cloak, ng-hide="state.loading")
|
||||||
ng-click="toggleChat()",
|
ng-click="toggleChat()",
|
||||||
ng-controller="ChatButtonController"
|
ng-controller="ChatButtonController"
|
||||||
)
|
)
|
||||||
i.fa.fa-fw.fa-comment
|
i.fa.fa-fw.fa-comment(
|
||||||
|
ng-class="{ 'bounce': unreadMessages > 0 }"
|
||||||
|
)
|
||||||
|
span.label.label-info(
|
||||||
|
ng-show="unreadMessages > 0"
|
||||||
|
) {{ unreadMessages }}
|
|
@ -1,7 +1,46 @@
|
||||||
define [
|
define [
|
||||||
"base"
|
"base"
|
||||||
], (App) ->
|
], (App) ->
|
||||||
App.controller "ChatButtonController", ["$scope", ($scope) ->
|
App.controller "ChatButtonController", ($scope, ide) ->
|
||||||
$scope.toggleChat = () ->
|
$scope.toggleChat = () ->
|
||||||
$scope.ui.chatOpen = !$scope.ui.chatOpen
|
$scope.ui.chatOpen = !$scope.ui.chatOpen
|
||||||
]
|
$scope.resetUnreadMessages()
|
||||||
|
|
||||||
|
$scope.unreadMessages = 0
|
||||||
|
$scope.resetUnreadMessages = () ->
|
||||||
|
$scope.unreadMessages = 0
|
||||||
|
|
||||||
|
$scope.$on "chat:resetUnreadMessages", (e) ->
|
||||||
|
$scope.resetUnreadMessages()
|
||||||
|
|
||||||
|
$scope.$on "chat:newMessage", (e, message) ->
|
||||||
|
if message?
|
||||||
|
if message.user.id != ide.$scope.user.id
|
||||||
|
if !$scope.ui.chatOpen
|
||||||
|
$scope.unreadMessages += 1
|
||||||
|
flashTitle()
|
||||||
|
|
||||||
|
focussed = true
|
||||||
|
newMessageNotificationTimeout = null
|
||||||
|
originalTitle = null
|
||||||
|
$(window).on "focus", () ->
|
||||||
|
clearNewMessageNotification()
|
||||||
|
focussed = true
|
||||||
|
$(window).on "blur", () ->
|
||||||
|
focussed = false
|
||||||
|
|
||||||
|
flashTitle = () ->
|
||||||
|
if !focussed and !newMessageNotificationTimeout?
|
||||||
|
originalTitle ||= window.document.title
|
||||||
|
do changeTitle = () =>
|
||||||
|
if window.document.title == originalTitle
|
||||||
|
window.document.title = "New Message"
|
||||||
|
else
|
||||||
|
window.document.title = originalTitle
|
||||||
|
newMessageNotificationTimeout = setTimeout changeTitle, 800
|
||||||
|
|
||||||
|
clearNewMessageNotification = () ->
|
||||||
|
clearTimeout newMessageNotificationTimeout
|
||||||
|
newMessageNotificationTimeout = null
|
||||||
|
if originalTitle?
|
||||||
|
window.document.title = originalTitle
|
||||||
|
|
|
@ -2,7 +2,7 @@ define [
|
||||||
"base"
|
"base"
|
||||||
"ide/chat/services/chatMessages"
|
"ide/chat/services/chatMessages"
|
||||||
], (App) ->
|
], (App) ->
|
||||||
App.controller "ChatController", ($scope, chatMessages, @ide, $location) ->
|
App.controller "ChatController", ($scope, chatMessages, ide, $location) ->
|
||||||
$scope.chat = chatMessages.state
|
$scope.chat = chatMessages.state
|
||||||
|
|
||||||
$scope.$watch "chat.messages", (messages) ->
|
$scope.$watch "chat.messages", (messages) ->
|
||||||
|
@ -13,6 +13,13 @@ define [
|
||||||
$scope.$on "layout:chat:resize", () ->
|
$scope.$on "layout:chat:resize", () ->
|
||||||
$scope.$emit "updateScrollPosition"
|
$scope.$emit "updateScrollPosition"
|
||||||
|
|
||||||
|
$scope.$watch "chat.newMessage", (message) ->
|
||||||
|
if message?
|
||||||
|
ide.$scope.$broadcast "chat:newMessage", message
|
||||||
|
|
||||||
|
$scope.resetUnreadMessages = () ->
|
||||||
|
ide.$scope.$broadcast "chat:resetUnreadMessages"
|
||||||
|
|
||||||
$scope.sendMessage = ->
|
$scope.sendMessage = ->
|
||||||
chatMessages
|
chatMessages
|
||||||
.sendMessage $scope.newMessageContent
|
.sendMessage $scope.newMessageContent
|
||||||
|
|
|
@ -12,9 +12,12 @@ define [
|
||||||
loading: false
|
loading: false
|
||||||
atEnd: false
|
atEnd: false
|
||||||
nextBeforeTimestamp: null
|
nextBeforeTimestamp: null
|
||||||
|
newMessage: null
|
||||||
}
|
}
|
||||||
|
|
||||||
ide.socket.on "new-chat-message", (message) =>
|
ide.socket.on "new-chat-message", (message) =>
|
||||||
|
ide.$scope.$apply () ->
|
||||||
|
chat.state.newMessage = message
|
||||||
appendMessage(message)
|
appendMessage(message)
|
||||||
|
|
||||||
chat.loadMoreMessages = () ->
|
chat.loadMoreMessages = () ->
|
||||||
|
|
|
@ -13,3 +13,88 @@
|
||||||
margin-top: -10px;
|
margin-top: -10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes bounce {
|
||||||
|
0%, 10%, 26%, 40%, 50% {
|
||||||
|
-webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||||
|
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||||
|
-webkit-transform: translate3d(0,0,0);
|
||||||
|
transform: translate3d(0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
20%, 21% {
|
||||||
|
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||||
|
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||||
|
-webkit-transform: translate3d(0, -10px, 0);
|
||||||
|
transform: translate3d(0, -10px, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
35% {
|
||||||
|
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||||
|
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||||
|
-webkit-transform: translate3d(0, -5px, 0);
|
||||||
|
transform: translate3d(0, -5px, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
45% {
|
||||||
|
-webkit-transform: translate3d(0,-2px,0);
|
||||||
|
transform: translate3d(0,-2px,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
-webkit-transform: translate3d(0,0,0);
|
||||||
|
transform: translate3d(0,0,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounce {
|
||||||
|
0%, 10%, 26%, 40%, 50% {
|
||||||
|
-webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||||
|
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||||
|
-webkit-transform: translate3d(0,0,0);
|
||||||
|
-ms-transform: translate3d(0,0,0);
|
||||||
|
transform: translate3d(0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
20%, 21% {
|
||||||
|
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||||
|
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||||
|
-webkit-transform: translate3d(0, -10px, 0);
|
||||||
|
-ms-transform: translate3d(0, -10px, 0);
|
||||||
|
transform: translate3d(0, -10px, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
35% {
|
||||||
|
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||||
|
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||||
|
-webkit-transform: translate3d(0, -5px, 0);
|
||||||
|
-ms-transform: translate3d(0, -5px, 0);
|
||||||
|
transform: translate3d(0, -5px, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
45% {
|
||||||
|
-webkit-transform: translate3d(0,-2px,0);
|
||||||
|
-ms-transform: translate3d(0,-2px,0);
|
||||||
|
transform: translate3d(0,-2px,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
-webkit-transform: translate3d(0,0,0);
|
||||||
|
-ms-transform: translate3d(0,0,0);
|
||||||
|
transform: translate3d(0,0,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bounce {
|
||||||
|
-webkit-animation-duration: 2s;
|
||||||
|
animation-duration: 2s;
|
||||||
|
-webkit-animation-fill-mode: both;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
-webkit-animation-iteration-count: infinite;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
-webkit-animation-name: bounce;
|
||||||
|
animation-name: bounce;
|
||||||
|
-webkit-transform-origin: center bottom;
|
||||||
|
-ms-transform-origin: center bottom;
|
||||||
|
transform-origin: center bottom;
|
||||||
|
}
|
||||||
|
|
|
@ -75,14 +75,6 @@
|
||||||
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
.log-btn {
|
.log-btn {
|
||||||
position: relative;
|
|
||||||
.label {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: .15em .6em .2em;
|
|
||||||
font-size: 60%;
|
|
||||||
}
|
|
||||||
&.active, &:active {
|
&.active, &:active {
|
||||||
.label {
|
.label {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -2,6 +2,17 @@
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border-bottom: 1px solid @toolbar-border-color;
|
border-bottom: 1px solid @toolbar-border-color;
|
||||||
|
|
||||||
|
a {
|
||||||
|
position: relative;
|
||||||
|
.label {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: .15em .6em .2em;
|
||||||
|
font-size: 60%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a:not(.btn) {
|
a:not(.btn) {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: @gray-light;
|
color: @gray-light;
|
||||||
|
@ -32,6 +43,10 @@
|
||||||
background-color: @link-color;
|
background-color: @link-color;
|
||||||
.box-shadow(inset 0 3px 5px rgba(0, 0, 0, 0.225));
|
.box-shadow(inset 0 3px 5px rgba(0, 0, 0, 0.225));
|
||||||
}
|
}
|
||||||
|
.label {
|
||||||
|
top: 4px;
|
||||||
|
right: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-right {
|
.toolbar-right {
|
||||||
|
|
Loading…
Reference in a new issue