From c1e5eb285b73e93635cf84d242c3696e5e30e785 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Fri, 13 Nov 2015 13:34:01 +0100 Subject: [PATCH 1/2] US #3440 - Send notifications (live announcement) to the user through taiga-events --- CHANGELOG.md | 1 + app/coffee/modules/events.coffee | 32 ++++++-- app/images/notification-decoration.png | Bin 0 -> 14313 bytes app/index.jade | 1 + .../live-announcement.directive.coffee | 54 +++++++++++++ .../live-announcement/live-announcement.jade | 12 +++ .../live-announcement/live-announcement.scss | 72 ++++++++++++++++++ .../live-announcement.service.coffee | 31 ++++++++ app/modules/projects/project/project.jade | 2 +- app/themes/taiga/variables.scss | 4 + 10 files changed, 202 insertions(+), 7 deletions(-) create mode 100644 app/images/notification-decoration.png create mode 100644 app/modules/components/live-announcement/live-announcement.directive.coffee create mode 100644 app/modules/components/live-announcement/live-announcement.jade create mode 100644 app/modules/components/live-announcement/live-announcement.scss create mode 100644 app/modules/components/live-announcement/live-announcement.service.coffee diff --git a/CHANGELOG.md b/CHANGELOG.md index ba4bc13f..8c46e982 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ## 1.9.1 Taiga Tribe (unreleased) - [118n] Now taiga plugins can be translatable. - New Taiga plugins system. +- Now superadmins can send notifications (live announcement) to the user (through taiga-events). ### Misc - Statics folder hash to prevent cache problems when a new version is released. diff --git a/app/coffee/modules/events.coffee b/app/coffee/modules/events.coffee index 82043d22..f7acf0bc 100644 --- a/app/coffee/modules/events.coffee +++ b/app/coffee/modules/events.coffee @@ -27,7 +27,7 @@ module = angular.module("taigaEvents", []) class EventsService - constructor: (@win, @log, @config, @auth) -> + constructor: (@win, @log, @config, @auth, @liveAnnouncementService, @rootScope) -> bindMethods(@) initialize: (sessionId) -> @@ -78,6 +78,11 @@ class EventsService delete @.ws + notifications: -> + @.subscribe null, 'notifications', (data) => + @liveAnnouncementService.show(data.title, data.desc) + @rootScope.$digest() + ########################################### # Heartbeat (Ping - Pong) ########################################### @@ -144,7 +149,12 @@ class EventsService return subscription = @.subscriptions[routingKey] - subscription.scope.$apply -> + + if subscription.scope + subscription.scope.$apply -> + subscription.callback(data.data) + + else subscription.callback(data.data) ########################################### @@ -168,7 +178,8 @@ class EventsService @.subscriptions[routingKey] = subscription @.sendMessage(message) - scope.$on("$destroy", => @.unsubscribe(routingKey)) + + scope.$on("$destroy", => @.unsubscribe(routingKey)) if scope unsubscribe: (routingKey) -> if @.error @@ -189,6 +200,7 @@ class EventsService onOpen: -> @.connected = true @.startHeartBeatMessages() + @.notifications() @log.debug("WebSocket connection opened") token = @auth.getToken() @@ -204,6 +216,7 @@ class EventsService @.log.debug "WebSocket message received: #{event.data}" data = JSON.parse(event.data) + if data.cmd == "pong" @.processHeartBeatPongMessage(data) else @@ -223,11 +236,18 @@ class EventsProvider setSessionId: (sessionId) -> @.sessionId = sessionId - $get: ($win, $log, $conf, $auth) -> - service = new EventsService($win, $log, $conf, $auth) + $get: ($win, $log, $conf, $auth, liveAnnouncementService, $rootScope) -> + service = new EventsService($win, $log, $conf, $auth, liveAnnouncementService, $rootScope) service.initialize(@.sessionId) return service - @.prototype.$get.$inject = ["$window", "$log", "$tgConfig", "$tgAuth"] + @.prototype.$get.$inject = [ + "$window", + "$log", + "$tgConfig", + "$tgAuth", + "tgLiveAnnouncementService", + "$rootScope" + ] module.provider("$tgEvents", EventsProvider) diff --git a/app/images/notification-decoration.png b/app/images/notification-decoration.png new file mode 100644 index 0000000000000000000000000000000000000000..2147968c637938ff4e5f650dcddbd226c64e4880 GIT binary patch literal 14313 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 Q1^@s+ML|=(PS!H~e;Cz3f&c&j literal 0 HcmV?d00001 diff --git a/app/index.jade b/app/index.jade index 96aa95cd..b53656f9 100644 --- a/app/index.jade +++ b/app/index.jade @@ -38,6 +38,7 @@ html(lang="en") include partials/includes/components/notification-message div(tg-joy-ride) + div(tg-live-announcement) script(src="/#{v}/js/libs.js") script(src="/#{v}/js/templates.js") diff --git a/app/modules/components/live-announcement/live-announcement.directive.coffee b/app/modules/components/live-announcement/live-announcement.directive.coffee new file mode 100644 index 00000000..97f037d8 --- /dev/null +++ b/app/modules/components/live-announcement/live-announcement.directive.coffee @@ -0,0 +1,54 @@ +### +# Copyright (C) 2014-2015 Andrey Antukh +# Copyright (C) 2014-2015 Jesús Espino Garcia +# Copyright (C) 2014-2015 David Barragán Merino +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# File: live-announcement.directive.coffee +### + + +LiveAnnouncementDirective = (liveAnnouncementService) -> + link = (scope, el, attrs) -> + + return { + restrict: "AE", + scope: {}, + controllerAs: 'vm', + controller: () -> + this.close = () -> + liveAnnouncementService.open = false + + Object.defineProperties(this, { + open: { + get: () -> return liveAnnouncementService.open + }, + title: { + get: () -> return liveAnnouncementService.title + }, + desc: { + get: () -> return liveAnnouncementService.desc + } + }) + link: link, + templateUrl: "components/live-announcement/live-announcement.html" + } + +LiveAnnouncementDirective.$inject = [ + "tgLiveAnnouncementService" +] + +angular.module("taigaComponents") + .directive("tgLiveAnnouncement", LiveAnnouncementDirective) diff --git a/app/modules/components/live-announcement/live-announcement.jade b/app/modules/components/live-announcement/live-announcement.jade new file mode 100644 index 00000000..25df0db7 --- /dev/null +++ b/app/modules/components/live-announcement/live-announcement.jade @@ -0,0 +1,12 @@ +.live-announcement(ng-class="{visible: vm.open}") + .live-announcement-inner + img.anouncement-decoration(src="/#{v}/images/notification-decoration.png", alt="Loading...") + .text + h2.title {{vm.title}} + p.warning(ng-bind-html="vm.desc") + a.close( + ng-click="vm.close()" + href="" + title="{{ COMMON.CLOSE | translate }}" + ) + include ../../../svg/remove.svg diff --git a/app/modules/components/live-announcement/live-announcement.scss b/app/modules/components/live-announcement/live-announcement.scss new file mode 100644 index 00000000..d30cdd00 --- /dev/null +++ b/app/modules/components/live-announcement/live-announcement.scss @@ -0,0 +1,72 @@ +.live-announcement { + $animation-steps-duration: .5s; + align-content: center; + background: $tribe-primary; + display: flex; + height: 0; + justify-content: center; + overflow: hidden; + pointer-events: none; + position: fixed; + top: 0; + transition: width $animation-steps-duration, height $animation-steps-duration; + transition-delay: $animation-steps-duration; + width: 0; + z-index: 99; + .live-announcement-inner { + opacity: 0; + transition: opacity $animation-steps-duration; + width: 100%; + } + &.visible { + height: 146px; + pointer-events: auto; + transition-delay: 0s; + width: 100%; + .live-announcement-inner { + opacity: 1; + transition: opacity $animation-steps-duration $animation-steps-duration; + } + } +} + +.live-announcement-inner { + display: flex; + max-width: 1200px; + .announcement-decoration { + align-self: flex-end; + margin-right: 1rem; + } + .text { + padding: 1.25rem 3rem 1.25rem 2rem; + position: relative; + width: 100%; + } + .title { + @extend %bold; + @extend %larger; + color: $tribe-secondary; + margin-bottom: .5rem; + } + .warning { + color: $tribe-secondary; + a { + @extend %bold; + color: $tribe-secondary; + } + } + .close { + height: 2.5rem; + position: absolute; + right: 0; + top: 1rem; + width: 2.5rem; + svg { + fill: lighten($tribe-secondary, 15%); + transition: fill .2s; + &:hover { + fill: $tribe-secondary; + } + } + } +} diff --git a/app/modules/components/live-announcement/live-announcement.service.coffee b/app/modules/components/live-announcement/live-announcement.service.coffee new file mode 100644 index 00000000..a8c8168b --- /dev/null +++ b/app/modules/components/live-announcement/live-announcement.service.coffee @@ -0,0 +1,31 @@ +### +# Copyright (C) 2014-2015 Taiga Agile LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# File: notification.service.coffee +### + +class LiveAnnouncementService extends taiga.Service + constructor: () -> + @.open = false + @.title = "" + @.desc = "" + + show: (title, desc) -> + @.open = true + @.title = title + @.desc = desc + +angular.module("taigaComponents").service("tgLiveAnnouncementService", LiveAnnouncementService) diff --git a/app/modules/projects/project/project.jade b/app/modules/projects/project/project.jade index 9f48bf12..8977c920 100644 --- a/app/modules/projects/project/project.jade +++ b/app/modules/projects/project/project.jade @@ -1,6 +1,6 @@ div.wrapper tg-project-menu - div.centered.single-project + div.single-project.centered section.single-project-intro div.intro-options h1 diff --git a/app/themes/taiga/variables.scss b/app/themes/taiga/variables.scss index 2eb4144b..12202bf2 100755 --- a/app/themes/taiga/variables.scss +++ b/app/themes/taiga/variables.scss @@ -31,6 +31,10 @@ $red-amaranth: #e43050; $purple-eggplant: #810061; $yellow-pear: #bbe831; +$tribe-primary: #98e0eb; +$tribe-secondary: #107a8a; + + $top-icon-color: #11241f; $dropdown-color: rgba(darken($grayer, 20%), 1); From 7130737f3415315416906df9f82ef7993af448e0 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 5 Jan 2016 07:56:01 +0100 Subject: [PATCH 2/2] Fixing events for anonymous users --- app/coffee/app.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/coffee/app.coffee b/app/coffee/app.coffee index 4a8796b1..5c4521e3 100644 --- a/app/coffee/app.coffee +++ b/app/coffee/app.coffee @@ -573,9 +573,10 @@ init = ($log, $rootscope, $auth, $events, $analytics, $translate, $location, $na Promise.setScheduler (cb) -> $rootscope.$evalAsync(cb) + $events.setupConnection() + # Load user if $auth.isAuthenticated() - $events.setupConnection() user = $auth.getUser() # Analytics