##// END OF EJS Templates
favicon: added favicon notifications
ergo -
r882:d869b56a default
parent child Browse files
Show More
@@ -0,0 +1,7 b''
1 <link rel="import" href="../../../../../../bower_components/polymer/polymer.html">
2
3 <dom-module id="rhodecode-favicon">
4 <template>
5 </template>
6 <script src="rhodecode-favicon.js"></script>
7 </dom-module>
@@ -0,0 +1,20 b''
1 Polymer({
2 is: 'rhodecode-favicon',
3 properties: {
4 favicon: Object,
5 counter: {
6 type: Number,
7 observer: '_handleCounter'
8 }
9 },
10
11 ready: function () {
12 this.favicon = new Favico({
13 type: 'rectangle',
14 animation: 'none'
15 });
16 },
17 _handleCounter: function (newVal, oldVal) {
18 this.favicon.badge(this.counter);
19 }
20 });
@@ -1,190 +1,191 b''
1 1 {
2 2 "dirs": {
3 3 "css": {
4 4 "src":"rhodecode/public/css",
5 5 "dest":"rhodecode/public/css"
6 6 },
7 7 "js": {
8 8 "src": "rhodecode/public/js/src",
9 9 "dest": "rhodecode/public/js",
10 10 "bower": "bower_components",
11 11 "node_modules": "node_modules"
12 12 }
13 13 },
14 14 "copy": {
15 15 "main": {
16 16 "expand": true,
17 17 "cwd": "bower_components",
18 18 "src": "webcomponentsjs/webcomponents-lite.js",
19 19 "dest": "<%= dirs.js.dest %>/vendors"
20 20 }
21 21 },
22 22 "concat": {
23 23 "polymercss": {
24 24 "src": [
25 25 "<%= dirs.js.src %>/components/root-styles-prefix.html",
26 26 "<%= dirs.css.src %>/style-polymer.css",
27 27 "<%= dirs.js.src %>/components/root-styles-suffix.html"
28 28 ],
29 29 "dest": "<%= dirs.js.dest %>/src/components/root-styles.gen.html",
30 30 "nonull": true
31 31 },
32 32 "dist": {
33 33 "src": [
34 34 "<%= dirs.js.src %>/jquery-1.11.1.min.js",
35 35 "<%= dirs.js.src %>/logging.js",
36 36 "<%= dirs.js.src %>/bootstrap.js",
37 37 "<%= dirs.js.src %>/mousetrap.js",
38 38 "<%= dirs.js.src %>/moment.js",
39 39 "<%= dirs.js.node_modules %>/appenlight-client/appenlight-client.min.js",
40 "<%= dirs.js.node_modules %>/favico.js/favico-0.3.10.min.js",
40 41 "<%= dirs.js.src %>/i18n_utils.js",
41 42 "<%= dirs.js.src %>/deform.js",
42 43 "<%= dirs.js.src %>/plugins/jquery.pjax.js",
43 44 "<%= dirs.js.src %>/plugins/jquery.dataTables.js",
44 45 "<%= dirs.js.src %>/plugins/flavoured_checkbox.js",
45 46 "<%= dirs.js.src %>/plugins/jquery.auto-grow-input.js",
46 47 "<%= dirs.js.src %>/plugins/jquery.autocomplete.js",
47 48 "<%= dirs.js.src %>/plugins/jquery.debounce.js",
48 49 "<%= dirs.js.src %>/plugins/jquery.mark.js",
49 50 "<%= dirs.js.src %>/plugins/jquery.timeago.js",
50 51 "<%= dirs.js.src %>/plugins/jquery.timeago-extension.js",
51 52 "<%= dirs.js.src %>/select2/select2.js",
52 53 "<%= dirs.js.src %>/codemirror/codemirror.js",
53 54 "<%= dirs.js.src %>/codemirror/codemirror_loadmode.js",
54 55 "<%= dirs.js.src %>/codemirror/codemirror_hint.js",
55 56 "<%= dirs.js.src %>/codemirror/codemirror_overlay.js",
56 57 "<%= dirs.js.src %>/codemirror/codemirror_placeholder.js",
57 58 "<%= dirs.js.dest %>/mode/meta.js",
58 59 "<%= dirs.js.dest %>/mode/meta_ext.js",
59 60 "<%= dirs.js.dest %>/rhodecode/i18n/select2/translations.js",
60 61 "<%= dirs.js.src %>/rhodecode/utils/array.js",
61 62 "<%= dirs.js.src %>/rhodecode/utils/string.js",
62 63 "<%= dirs.js.src %>/rhodecode/utils/pyroutes.js",
63 64 "<%= dirs.js.src %>/rhodecode/utils/ajax.js",
64 65 "<%= dirs.js.src %>/rhodecode/utils/autocomplete.js",
65 66 "<%= dirs.js.src %>/rhodecode/utils/colorgenerator.js",
66 67 "<%= dirs.js.src %>/rhodecode/utils/ie.js",
67 68 "<%= dirs.js.src %>/rhodecode/utils/os.js",
68 69 "<%= dirs.js.src %>/rhodecode/utils/topics.js",
69 70 "<%= dirs.js.src %>/rhodecode/widgets/multiselect.js",
70 71 "<%= dirs.js.src %>/rhodecode/init.js",
71 72 "<%= dirs.js.src %>/rhodecode/codemirror.js",
72 73 "<%= dirs.js.src %>/rhodecode/comments.js",
73 74 "<%= dirs.js.src %>/rhodecode/constants.js",
74 75 "<%= dirs.js.src %>/rhodecode/files.js",
75 76 "<%= dirs.js.src %>/rhodecode/followers.js",
76 77 "<%= dirs.js.src %>/rhodecode/menus.js",
77 78 "<%= dirs.js.src %>/rhodecode/notifications.js",
78 79 "<%= dirs.js.src %>/rhodecode/permissions.js",
79 80 "<%= dirs.js.src %>/rhodecode/pjax.js",
80 81 "<%= dirs.js.src %>/rhodecode/pullrequests.js",
81 82 "<%= dirs.js.src %>/rhodecode/settings.js",
82 83 "<%= dirs.js.src %>/rhodecode/select2_widgets.js",
83 84 "<%= dirs.js.src %>/rhodecode/tooltips.js",
84 85 "<%= dirs.js.src %>/rhodecode/users.js",
85 86 "<%= dirs.js.src %>/rhodecode/appenlight.js",
86 87 "<%= dirs.js.src %>/rhodecode.js"
87 88 ],
88 89 "dest": "<%= dirs.js.dest %>/scripts.js",
89 90 "nonull": true
90 91 }
91 92 },
92 93 "crisper": {
93 94 "dist": {
94 95 "options": {
95 96 "cleanup": false,
96 97 "onlySplit": true
97 98 },
98 99 "src": "<%= dirs.js.dest %>/rhodecode-components.html",
99 100 "dest": "<%= dirs.js.dest %>/rhodecode-components.js"
100 101 }
101 102 },
102 103 "less": {
103 104 "development": {
104 105 "options": {
105 106 "compress": false,
106 107 "yuicompress": false,
107 108 "optimization": 0
108 109 },
109 110 "files": {
110 111 "<%= dirs.css.dest %>/style.css": "<%= dirs.css.src %>/main.less",
111 112 "<%= dirs.css.dest %>/style-polymer.css": "<%= dirs.css.src %>/polymer.less"
112 113 }
113 114 },
114 115 "production": {
115 116 "options": {
116 117 "compress": true,
117 118 "yuicompress": true,
118 119 "optimization": 2
119 120 },
120 121 "files": {
121 122 "<%= dirs.css.dest %>/style.css": "<%= dirs.css.src %>/main.less",
122 123 "<%= dirs.css.dest %>/style-polymer.css": "<%= dirs.css.src %>/polymer.less"
123 124 }
124 125 },
125 126 "components": {
126 127 "files": [
127 128 {
128 129 "cwd": "<%= dirs.js.src %>/components/",
129 130 "dest": "<%= dirs.js.src %>/components/",
130 131 "src": [
131 132 "**/*.less"
132 133 ],
133 134 "expand": true,
134 135 "ext": ".css"
135 136 }
136 137 ]
137 138 }
138 139 },
139 140 "watch": {
140 141 "less": {
141 142 "files": [
142 143 "<%= dirs.css.src %>/**/*.less",
143 144 "<%= dirs.js.src %>/components/**/*.less"
144 145 ],
145 146 "tasks": [
146 147 "less:development",
147 148 "less:components",
148 149 "concat:polymercss",
149 150 "vulcanize",
150 151 "crisper",
151 152 "concat:dist"
152 153 ]
153 154 },
154 155 "js": {
155 156 "files": [
156 157 "!<%= dirs.js.src %>/components/root-styles.gen.html",
157 158 "<%= dirs.js.src %>/**/*.js",
158 159 "<%= dirs.js.src %>/components/**/*.html"
159 160 ],
160 161 "tasks": [
161 162 "less:components",
162 163 "concat:polymercss",
163 164 "vulcanize",
164 165 "crisper",
165 166 "concat:dist"
166 167 ]
167 168 }
168 169 },
169 170 "jshint": {
170 171 "rhodecode": {
171 172 "src": "<%= dirs.js.src %>/rhodecode/**/*.js",
172 173 "options": {
173 174 "jshintrc": ".jshintrc"
174 175 }
175 176 }
176 177 },
177 178 "vulcanize": {
178 179 "default": {
179 180 "options": {
180 181 "abspath": "",
181 182 "inlineScripts": true,
182 183 "inlineCss": true,
183 184 "stripComments": true
184 185 },
185 186 "files": {
186 187 "<%= dirs.js.dest %>/rhodecode-components.html": "<%= dirs.js.src %>/components/shared-components.html"
187 188 }
188 189 }
189 190 }
190 191 }
@@ -1,15 +1,18 b''
1 1 <link rel="import" href="../../../../../../bower_components/polymer/polymer.html">
2 2 <link rel="import" href="../channelstream-connection/channelstream-connection.html">
3 <link rel="import" href="../rhodecode-toast/rhodecode-toast.html">
4 <link rel="import" href="../rhodecode-favicon/rhodecode-favicon.html">
3 5
4 6 <dom-module id="rhodecode-app">
5 7 <template>
8 <rhodecode-favicon></rhodecode-favicon>
6 9 <rhodecode-toast id="notifications"></rhodecode-toast>
7 10 <channelstream-connection
8 11 id="channelstream-connection"
9 12 on-channelstream-listen-message="receivedMessage"
10 13 on-channelstream-connected="handleConnected"
11 14 on-channelstream-subscribed="handleSubscribed">
12 15 </channelstream-connection>
13 16 </template>
14 17 <script src="rhodecode-app.js"></script>
15 18 </dom-module>
@@ -1,132 +1,137 b''
1 1 ccLog = Logger.get('RhodeCodeApp');
2 2 ccLog.setLevel(Logger.OFF);
3 3
4 4 var rhodeCodeApp = Polymer({
5 5 is: 'rhodecode-app',
6 6 attached: function () {
7 7 ccLog.debug('rhodeCodeApp created');
8 8 $.Topic('/notifications').subscribe(this.handleNotifications.bind(this));
9 $.Topic('/favicon/update').subscribe(this.faviconUpdate.bind(this));
9 10 $.Topic('/connection_controller/subscribe').subscribe(
10 11 this.subscribeToChannelTopic.bind(this));
11 12 // this event can be used to coordinate plugins to do their
12 13 // initialization before channelstream is kicked off
13 14 $.Topic('/__MAIN_APP__').publish({});
14 15
15 16 for (var i = 0; i < alertMessagePayloads.length; i++) {
16 17 $.Topic('/notifications').publish(alertMessagePayloads[i]);
17 18 }
18 19 this.kickoffChannelstreamPlugin();
19 20 },
20 21
21 22 /** proxy to channelstream connection */
22 23 getChannelStreamConnection: function () {
23 24 return this.$['channelstream-connection'];
24 25 },
25 26
26 27 handleNotifications: function (data) {
27 28 this.$['notifications'].handleNotification(data);
28 29 },
29 30
31 faviconUpdate: function (data) {
32 this.$$('rhodecode-favicon').counter = data.count;
33 },
34
30 35 /** opens connection to ws server */
31 36 kickoffChannelstreamPlugin: function (data) {
32 37 ccLog.debug('kickoffChannelstreamPlugin');
33 38 var channels = ['broadcast'];
34 39 var addChannels = this.checkViewChannels();
35 40 for (var i = 0; i < addChannels.length; i++) {
36 41 channels.push(addChannels[i]);
37 42 }
38 43 if (window.CHANNELSTREAM_SETTINGS && CHANNELSTREAM_SETTINGS.enabled){
39 44 var channelstreamConnection = this.getChannelStreamConnection();
40 45 channelstreamConnection.connectUrl = CHANNELSTREAM_URLS.connect;
41 46 channelstreamConnection.subscribeUrl = CHANNELSTREAM_URLS.subscribe;
42 47 channelstreamConnection.websocketUrl = CHANNELSTREAM_URLS.ws + '/ws';
43 48 channelstreamConnection.longPollUrl = CHANNELSTREAM_URLS.longpoll + '/listen';
44 49 // some channels might already be registered by topic
45 50 for (var i = 0; i < channels.length; i++) {
46 51 channelstreamConnection.push('channels', channels[i]);
47 52 }
48 53 // append any additional channels registered in other plugins
49 54 $.Topic('/connection_controller/subscribe').processPrepared();
50 55 channelstreamConnection.connect();
51 56 }
52 57 },
53 58
54 59 checkViewChannels: function () {
55 60 var channels = []
56 61 // subscribe to PR repo channel for PR's'
57 62 if (templateContext.pull_request_data.pull_request_id) {
58 63 var channelName = '/repo$' + templateContext.repo_name + '$/pr/' +
59 64 String(templateContext.pull_request_data.pull_request_id);
60 65 channels.push(channelName);
61 66 }
62 67 return channels;
63 68 },
64 69
65 70 /** subscribes users from channels in channelstream */
66 71 subscribeToChannelTopic: function (channels) {
67 72 var channelstreamConnection = this.$['channelstream-connection'];
68 73 var toSubscribe = channelstreamConnection.calculateSubscribe(channels);
69 74 ccLog.debug('subscribeToChannelTopic', toSubscribe);
70 75 if (toSubscribe.length > 0) {
71 76 // if we are connected then subscribe
72 77 if (channelstreamConnection.connected) {
73 78 channelstreamConnection.subscribe(toSubscribe);
74 79 }
75 80 // not connected? just push channels onto the stack
76 81 else {
77 82 for (var i = 0; i < toSubscribe.length; i++) {
78 83 channelstreamConnection.push('channels', toSubscribe[i]);
79 84 }
80 85 }
81 86 }
82 87 },
83 88
84 89 /** publish received messages into correct topic */
85 90 receivedMessage: function (event) {
86 91 for (var i = 0; i < event.detail.length; i++) {
87 92 var message = event.detail[i];
88 93 if (message.message.topic) {
89 94 ccLog.debug('publishing', message.message.topic);
90 95 $.Topic(message.message.topic).publish(message);
91 96 }
92 97 else if (message.type === 'presence'){
93 98 $.Topic('/connection_controller/presence').publish(message);
94 99 }
95 100 else {
96 101 ccLog.warn('unhandled message', message);
97 102 }
98 103 }
99 104 },
100 105
101 106 handleConnected: function (event) {
102 107 var channelstreamConnection = this.$['channelstream-connection'];
103 108 channelstreamConnection.set('channelsState',
104 109 event.detail.channels_info);
105 110 channelstreamConnection.set('userState', event.detail.state);
106 111 channelstreamConnection.set('channels', event.detail.channels);
107 112 this.propagageChannelsState();
108 113 },
109 114 handleSubscribed: function (event) {
110 115 var channelstreamConnection = this.$['channelstream-connection'];
111 116 var channelInfo = event.detail.channels_info;
112 117 var channelKeys = Object.keys(event.detail.channels_info);
113 118 for (var i = 0; i < channelKeys.length; i++) {
114 119 var key = channelKeys[i];
115 120 channelstreamConnection.set(['channelsState', key], channelInfo[key]);
116 121 }
117 122 channelstreamConnection.set('channels', event.detail.channels);
118 123 this.propagageChannelsState();
119 124 },
120 125 /** propagates channel states on topics */
121 126 propagageChannelsState: function (event) {
122 127 var channelstreamConnection = this.$['channelstream-connection'];
123 128 var channel_data = channelstreamConnection.channelsState;
124 129 var channels = channelstreamConnection.channels;
125 130 for (var i = 0; i < channels.length; i++) {
126 131 var key = channels[i];
127 132 $.Topic('/connection_controller/channel_update').publish(
128 133 {channel: key, state: channel_data[key]}
129 134 );
130 135 }
131 136 }
132 137 });
@@ -1,38 +1,40 b''
1 1 Polymer({
2 2 is: 'rhodecode-toast',
3 3 properties: {
4 4 toasts: {
5 5 type: Array,
6 6 value: function(){
7 7 return []
8 8 }
9 9 }
10 10 },
11 11 observers: [
12 12 '_changedToasts(toasts.splices)'
13 13 ],
14 14 _changedToasts: function(newValue, oldValue){
15 15 this.$['p-toast'].notifyResize();
16 $.Topic('/favicon/update').publish({count: this.toasts.length});
16 17 },
17 18 dismissNotifications: function(){
18 19 this.$['p-toast'].close();
20 $.Topic('/favicon/update').publish({count: 0});
19 21 },
20 22 handleClosed: function(){
21 23 this.splice('toasts', 0);
22 24 },
23 25 open: function(){
24 26 this.$['p-toast'].open();
25 27 },
26 28 handleNotification: function(data){
27 29 if (!templateContext.rhodecode_user.notification_status && !data.message.force) {
28 30 // do not act if notifications are disabled
29 31 return
30 32 }
31 33 this.push('toasts',{
32 34 level: data.message.level,
33 35 message: data.message.message
34 36 });
35 37 this.open();
36 38 },
37 39 _gettext: _gettext
38 40 });
@@ -1,8 +1,9 b''
1 1 /__MAIN_APP__ - launched when rhodecode-app element is attached to DOM
2 2 /plugins/__REGISTER__ - launched after the onDomReady() code from rhodecode.js is executed
3 3 /ui/plugins/code/anchor_focus - launched when rc starts to scroll on load to anchor on PR/Codeview
4 4 /ui/plugins/code/comment_form_built - launched when injectInlineForm() is executed and the form object is created
5 5 /notifications - shows new event notifications
6 6 /connection_controller/subscribe - subscribes user to new channels
7 7 /connection_controller/presence - receives presence change messages
8 8 /connection_controller/channel_update - receives channel states
9 /favicon/update - notify state change for favicon
General Comments 0
You need to be logged in to leave comments. Login now