Explorar el Código

Adds notifications when a user joins/leaves or is added/removed from lastN.

master
fo hace 10 años
padre
commit
f2a310f6c3
Se han modificado 9 ficheros con 652 adiciones y 4 borrados
  1. 33
    0
      app.js
  2. 9
    0
      chat.js
  3. 7
    0
      contact_list.js
  4. 53
    0
      css/main.css
  5. 180
    0
      css/toastr.css
  6. 7
    4
      index.html
  7. 342
    0
      libs/toastr.js
  8. 10
    0
      message_handler.js
  9. 11
    0
      videolayout.js

+ 33
- 0
app.js Ver fichero

@@ -695,6 +695,9 @@ $(document).bind('joined.muc', function (event, jid, info) {
695 695
 
696 696
 $(document).bind('entered.muc', function (event, jid, info, pres) {
697 697
     console.log('entered', jid, info);
698
+    messageHandler.notify(info.displayName || 'Somebody',
699
+        'connected',
700
+        'connected');
698 701
 
699 702
     console.log('is focus? ' + (focus ? 'true' : 'false'));
700 703
 
@@ -726,6 +729,11 @@ $(document).bind('entered.muc', function (event, jid, info, pres) {
726 729
 
727 730
 $(document).bind('left.muc', function (event, jid) {
728 731
     console.log('left.muc', jid);
732
+    var displayName = $('#participant_' + Strophe.getResourceFromJid(jid) +
733
+        '>.displayname').text();
734
+    messageHandler.notify(displayName || 'Somebody',
735
+        'disconnected',
736
+        'disconnected');
729 737
     // Need to call this with a slight delay, otherwise the element couldn't be
730 738
     // found for some reason.
731 739
     window.setTimeout(function () {
@@ -1315,6 +1323,31 @@ $(document).ready(function () {
1315 1323
             init();
1316 1324
         };
1317 1325
     }
1326
+
1327
+    toastr.options = {
1328
+        "closeButton": true,
1329
+        "debug": false,
1330
+        "positionClass": "notification-bottom-right",
1331
+        "onclick": null,
1332
+        "showDuration": "300",
1333
+        "hideDuration": "1000",
1334
+        "timeOut": "2000",
1335
+        "extendedTimeOut": "1000",
1336
+        "showEasing": "swing",
1337
+        "hideEasing": "linear",
1338
+        "showMethod": "fadeIn",
1339
+        "hideMethod": "fadeOut",
1340
+        "reposition": function() {
1341
+            if(Chat.isVisible() || ContactList.isVisible()) {
1342
+                $("#toast-container").addClass("toast-bottom-right-center");
1343
+            } else {
1344
+                $("#toast-container").removeClass("toast-bottom-right-center");
1345
+            }
1346
+        },
1347
+        "newestOnTop": false
1348
+    }
1349
+
1350
+
1318 1351
 });
1319 1352
 
1320 1353
 $(window).bind('beforeunload', function () {

+ 9
- 0
chat.js Ver fichero

@@ -214,9 +214,13 @@ var Chat = (function (my) {
214 214
         );
215 215
 
216 216
         if (Chat.isVisible()) {
217
+            $("#toast-container").animate({right: '5px'},
218
+                                {queue: false,
219
+                                duration: 500});
217 220
             chatspace.hide("slide", { direction: "right",
218 221
                                             queue: false,
219 222
                                             duration: 500});
223
+
220 224
         }
221 225
         else {
222 226
             // Undock the toolbar when the chat is shown and if we're in a 
@@ -225,6 +229,10 @@ var Chat = (function (my) {
225 229
                 ToolbarToggler.dockToolbar(false);
226 230
             }
227 231
 
232
+
233
+            $("#toast-container").animate({right: (chatSize[0] + 5) + 'px'},
234
+                {queue: false,
235
+                    duration: 500});
228 236
             chatspace.show("slide", { direction: "right",
229 237
                                             queue: false,
230 238
                                             duration: 500,
@@ -237,6 +245,7 @@ var Chat = (function (my) {
237 245
                                                 }
238 246
                                             }
239 247
             });
248
+
240 249
             Chat.resizeChat();
241 250
         }
242 251
 

+ 7
- 0
contact_list.js Ver fichero

@@ -158,6 +158,9 @@ var ContactList = (function (my) {
158 158
                                     });
159 159
 
160 160
         if (ContactList.isVisible()) {
161
+            $("#toast-container").animate({right: '12px'},
162
+                {queue: false,
163
+                    duration: 500});
161 164
             $('#contactlist').hide("slide", { direction: "right",
162 165
                                             queue: false,
163 166
                                             duration: 500});
@@ -167,6 +170,10 @@ var ContactList = (function (my) {
167 170
             if (VideoLayout.isLargeVideoVisible())
168 171
                 ToolbarToggler.dockToolbar(false);
169 172
 
173
+
174
+            $("#toast-container").animate({right: '212px'},
175
+                {queue: false,
176
+                    duration: 500});
170 177
             $('#contactlist').show("slide", { direction: "right",
171 178
                                             queue: false,
172 179
                                             duration: 500});

+ 53
- 0
css/main.css Ver fichero

@@ -311,3 +311,56 @@ form {
311 311
     text-decoration: none;
312 312
     z-index: 100;
313 313
 }
314
+
315
+#toast-container.notification-bottom-right {
316
+    bottom: 120px;
317
+    right: 5px;
318
+}
319
+
320
+#toast-container.notification-bottom-right-center {
321
+    right: 205px;
322
+}
323
+
324
+#toast-container .toast-info {
325
+    -webkit-box-shadow: none;
326
+    box-shadow: none;
327
+}
328
+
329
+.toast-close-button {
330
+    right: -7px;
331
+    top: -19px;
332
+}
333
+
334
+#toast-container .toast-info {
335
+    background-color: black;
336
+    border: 1px solid #3a3a3a;
337
+    width: 220px;
338
+    padding: 10px 10px 10px 50px;
339
+}
340
+
341
+.connected {
342
+    color: forestgreen;
343
+    font-size: 12px;
344
+}
345
+
346
+.disconnected {
347
+    color: darkred;
348
+    font-size: 12px;
349
+}
350
+
351
+.lastN {
352
+    color: #a3a3a3;
353
+    font-size: 12px;
354
+}
355
+
356
+.toast-close-button:hover,
357
+.toast-close-button:focus {
358
+    color: #ffffff;
359
+    opacity: 1;
360
+    -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
361
+    filter: alpha(opacity=100);
362
+}
363
+
364
+.toast-message .nickname {
365
+    font-weight: bold;
366
+}

+ 180
- 0
css/toastr.css Ver fichero

@@ -0,0 +1,180 @@
1
+/*
2
+ * Toastr
3
+ * Copyright 2012-2014 John Papa and Hans Fjällemark.
4
+ * All Rights Reserved.
5
+ * Use, reproduction, distribution, and modification of this code is subject to the terms and
6
+ * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
7
+ *
8
+ * Author: John Papa and Hans Fjällemark
9
+ * Project: https://github.com/CodeSeven/toastr
10
+ */
11
+.toast-title {
12
+  font-weight: bold;
13
+}
14
+.toast-message {
15
+  -ms-word-wrap: break-word;
16
+  word-wrap: break-word;
17
+}
18
+.toast-message a,
19
+.toast-message label {
20
+  color: #ffffff;
21
+}
22
+.toast-message a:hover {
23
+  color: #cccccc;
24
+  text-decoration: none;
25
+}
26
+.toast-close-button {
27
+  position: relative;
28
+  right: -0.3em;
29
+  top: -0.3em;
30
+  float: right;
31
+  font-size: 20px;
32
+  font-weight: bold;
33
+  color: #ffffff;
34
+  -webkit-text-shadow: 0 1px 0 #ffffff;
35
+  text-shadow: 0 1px 0 #ffffff;
36
+  opacity: 0.8;
37
+  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
38
+  filter: alpha(opacity=80);
39
+}
40
+.toast-close-button:hover,
41
+.toast-close-button:focus {
42
+  color: #000000;
43
+  text-decoration: none;
44
+  cursor: pointer;
45
+  opacity: 0.4;
46
+  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
47
+  filter: alpha(opacity=40);
48
+}
49
+/*Additional properties for button version
50
+ iOS requires the button element instead of an anchor tag.
51
+ If you want the anchor version, it requires `href="#"`.*/
52
+button.toast-close-button {
53
+  padding: 0;
54
+  cursor: pointer;
55
+  background: transparent;
56
+  border: 0;
57
+  -webkit-appearance: none;
58
+}
59
+.toast-top-full-width {
60
+  top: 0;
61
+  right: 0;
62
+  width: 100%;
63
+}
64
+.toast-bottom-full-width {
65
+  bottom: 0;
66
+  right: 0;
67
+  width: 100%;
68
+}
69
+.toast-top-left {
70
+  top: 12px;
71
+  left: 12px;
72
+}
73
+.toast-top-right {
74
+  top: 12px;
75
+  right: 12px;
76
+}
77
+.toast-bottom-right {
78
+  right: 12px;
79
+  bottom: 12px;
80
+}
81
+.toast-bottom-left {
82
+  bottom: 12px;
83
+  left: 12px;
84
+}
85
+#toast-container {
86
+  position: fixed;
87
+  z-index: 999999;
88
+  /*overrides*/
89
+
90
+}
91
+#toast-container * {
92
+  -moz-box-sizing: border-box;
93
+  -webkit-box-sizing: border-box;
94
+  box-sizing: border-box;
95
+}
96
+#toast-container > div {
97
+  margin: 0 0 6px;
98
+  padding: 15px 15px 15px 50px;
99
+  width: 300px;
100
+  -moz-border-radius: 3px 3px 3px 3px;
101
+  -webkit-border-radius: 3px 3px 3px 3px;
102
+  border-radius: 3px 3px 3px 3px;
103
+  background-position: 15px center;
104
+  background-repeat: no-repeat;
105
+  -moz-box-shadow: 0 0 12px #999999;
106
+  -webkit-box-shadow: 0 0 12px #999999;
107
+  box-shadow: 0 0 12px #999999;
108
+  color: #ffffff;
109
+  opacity: 0.8;
110
+  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
111
+  filter: alpha(opacity=80);
112
+}
113
+#toast-container > :hover {
114
+  -moz-box-shadow: 0 0 12px #000000;
115
+  -webkit-box-shadow: 0 0 12px #000000;
116
+  box-shadow: 0 0 12px #000000;
117
+  opacity: 1;
118
+  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
119
+  filter: alpha(opacity=100);
120
+  cursor: pointer;
121
+}
122
+#toast-container > .toast-info {
123
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important;
124
+}
125
+#toast-container > .toast-error {
126
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important;
127
+}
128
+#toast-container > .toast-success {
129
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important;
130
+}
131
+#toast-container > .toast-warning {
132
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important;
133
+}
134
+#toast-container.toast-top-full-width > div,
135
+#toast-container.toast-bottom-full-width > div {
136
+  width: 96%;
137
+  margin: auto;
138
+}
139
+.toast {
140
+  background-color: #030303;
141
+}
142
+.toast-success {
143
+  background-color: #51a351;
144
+}
145
+.toast-error {
146
+  background-color: #bd362f;
147
+}
148
+.toast-info {
149
+  background-color: #2f96b4;
150
+}
151
+.toast-warning {
152
+  background-color: #f89406;
153
+}
154
+/*Responsive Design*/
155
+@media all and (max-width: 240px) {
156
+  #toast-container > div {
157
+    padding: 8px 8px 8px 50px;
158
+    width: 11em;
159
+  }
160
+  #toast-container .toast-close-button {
161
+    right: -0.2em;
162
+    top: -0.2em;
163
+  }
164
+}
165
+@media all and (min-width: 241px) and (max-width: 480px) {
166
+  #toast-container > div {
167
+    padding: 8px 8px 8px 50px;
168
+    width: 18em;
169
+  }
170
+  #toast-container .toast-close-button {
171
+    right: -0.2em;
172
+    top: -0.2em;
173
+  }
174
+}
175
+@media all and (min-width: 481px) and (max-width: 768px) {
176
+  #toast-container > div {
177
+    padding: 15px 15px 15px 50px;
178
+    width: 25em;
179
+  }
180
+}

+ 7
- 4
index.html Ver fichero

@@ -29,13 +29,14 @@
29 29
     <script src="libs/tooltip.js?v=1"></script><!-- bootstrap tooltip lib -->
30 30
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
31 31
     <script src="interface_config.js?v=3"></script>
32
+    <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
32 33
     <script src="muc.js?v=16"></script><!-- simple MUC library -->
33 34
     <script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
34 35
     <script src="desktopsharing.js?v=3"></script><!-- desktop sharing -->
35 36
     <script src="data_channels.js?v=3"></script><!-- data channels -->
36 37
     <script src="app.js?v=20"></script><!-- application logic -->
37 38
     <script src="commands.js?v=1"></script><!-- application logic -->
38
-    <script src="chat.js?v=13"></script><!-- chat logic -->
39
+    <script src="chat.js?v=14"></script><!-- chat logic -->
39 40
     <script src="contact_list.js?v=5"></script><!-- contact list logic -->
40 41
     <script src="util.js?v=6"></script><!-- utility functions -->
41 42
     <script src="etherpad.js?v=9"></script><!-- etherpad plugin -->
@@ -46,7 +47,7 @@
46 47
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
47 48
     <script src="rtp_sts.js?v=5"></script><!-- RTP stats processing -->
48 49
     <script src="local_sts.js?v=2"></script><!-- Local stats processing -->
49
-    <script src="videolayout.js?v=24"></script><!-- video ui -->
50
+    <script src="videolayout.js?v=25"></script><!-- video ui -->
50 51
     <script src="connectionquality.js?v=1"></script>
51 52
     <script src="toolbar.js?v=6"></script><!-- toolbar ui -->
52 53
     <script src="toolbar_toggler.js?v=2"></script>
@@ -58,17 +59,18 @@
58 59
     <script src="keyboard_shortcut.js?v=3"></script>
59 60
     <script src="tracking.js?v=1"></script><!-- tracking -->
60 61
     <script src="jitsipopover.js?v=3"></script>
61
-    <script src="message_handler.js?v=1"></script>
62
+    <script src="message_handler.js?v=2"></script>
62 63
     <script src="api_connector.js?v=2"></script>
63 64
     <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
64 65
     <link rel="stylesheet" href="css/font.css?v=5"/>
66
+    <link rel="stylesheet" href="css/toastr.css?v=1">
65 67
     <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=29"/>
66 68
     <link rel="stylesheet" type="text/css" media="screen" href="css/videolayout_default.css?v=13" id="videolayout_default"/>
67 69
     <link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
68 70
     <link rel="stylesheet" href="css/modaldialog.css?v=3">
69 71
     <link rel="stylesheet" href="css/popup_menu.css?v=4">
70 72
     <link rel="stylesheet" href="css/popover.css?v=2">
71
-      <link rel="stylesheet" href="css/jitsi_popover.css?v=2">
73
+    <link rel="stylesheet" href="css/jitsi_popover.css?v=2">
72 74
     <link rel="stylesheet" href="css/contact_list.css?v=3">
73 75
     <link rel="stylesheet" href="css/chat.css?v=5">
74 76
     <link rel="stylesheet" href="css/welcome_page.css?v=2">
@@ -318,6 +320,7 @@
318 320
             </ul>
319 321
         </div>
320 322
         <a id="downloadlog" onclick='dump(event.target);' data-container="body" data-toggle="popover" data-placement="right" data-content="Download logs" ><i class="fa fa-cloud-download"></i></a>
323
+        <span id="poweredby">Powered by jitsi.org</span>
321 324
     </div>
322 325
   </body>
323 326
 </html>

+ 342
- 0
libs/toastr.js Ver fichero

@@ -0,0 +1,342 @@
1
+/*
2
+ * Toastr
3
+ * Copyright 2012-2014 John Papa and Hans Fjällemark.
4
+ * All Rights Reserved.
5
+ * Use, reproduction, distribution, and modification of this code is subject to the terms and
6
+ * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
7
+ *
8
+ * Author: John Papa and Hans Fjällemark
9
+ * ARIA Support: Greta Krafsig
10
+ * Project: https://github.com/CodeSeven/toastr
11
+ */
12
+; (function (define) {
13
+    define(['jquery'], function ($) {
14
+        return (function () {
15
+            var $container;
16
+            var listener;
17
+            var toastId = 0;
18
+            var toastType = {
19
+                error: 'error',
20
+                info: 'info',
21
+                success: 'success',
22
+                warning: 'warning'
23
+            };
24
+
25
+            var toastr = {
26
+                clear: clear,
27
+                remove: remove,
28
+                error: error,
29
+                getContainer: getContainer,
30
+                info: info,
31
+                options: {},
32
+                subscribe: subscribe,
33
+                success: success,
34
+                version: '2.0.3',
35
+                warning: warning
36
+            };
37
+
38
+            return toastr;
39
+
40
+            //#region Accessible Methods
41
+            function error(message, title, optionsOverride) {
42
+                return notify({
43
+                    type: toastType.error,
44
+                    iconClass: getOptions().iconClasses.error,
45
+                    message: message,
46
+                    optionsOverride: optionsOverride,
47
+                    title: title
48
+                });
49
+            }
50
+
51
+            function getContainer(options, create) {
52
+                if (!options) { options = getOptions(); }
53
+                $container = $('#' + options.containerId);
54
+                if ($container.length) {
55
+                    return $container;
56
+                }
57
+                if(create) {
58
+                    $container = createContainer(options);
59
+                }
60
+                return $container;
61
+            }
62
+
63
+            function info(message, title, optionsOverride) {
64
+                return notify({
65
+                    type: toastType.info,
66
+                    iconClass: getOptions().iconClasses.info,
67
+                    message: message,
68
+                    optionsOverride: optionsOverride,
69
+                    title: title
70
+                });
71
+            }
72
+
73
+            function subscribe(callback) {
74
+                listener = callback;
75
+            }
76
+
77
+            function success(message, title, optionsOverride) {
78
+                return notify({
79
+                    type: toastType.success,
80
+                    iconClass: getOptions().iconClasses.success,
81
+                    message: message,
82
+                    optionsOverride: optionsOverride,
83
+                    title: title
84
+                });
85
+            }
86
+
87
+            function warning(message, title, optionsOverride) {
88
+                return notify({
89
+                    type: toastType.warning,
90
+                    iconClass: getOptions().iconClasses.warning,
91
+                    message: message,
92
+                    optionsOverride: optionsOverride,
93
+                    title: title
94
+                });
95
+            }
96
+
97
+            function clear($toastElement) {
98
+                var options = getOptions();
99
+                if (!$container) { getContainer(options); }
100
+                if (!clearToast($toastElement, options)) {
101
+                    clearContainer(options);
102
+                }
103
+            }
104
+
105
+            function remove($toastElement) {
106
+                var options = getOptions();
107
+                if (!$container) { getContainer(options); }
108
+                if ($toastElement && $(':focus', $toastElement).length === 0) {
109
+                    removeToast($toastElement);
110
+                    return;
111
+                }
112
+                if ($container.children().length) {
113
+                    $container.remove();
114
+                }
115
+            }
116
+            //#endregion
117
+
118
+            //#region Internal Methods
119
+
120
+            function clearContainer(options){
121
+                var toastsToClear = $container.children();
122
+                for (var i = toastsToClear.length - 1; i >= 0; i--) {
123
+                    clearToast($(toastsToClear[i]), options);
124
+                };
125
+            }
126
+
127
+            function clearToast($toastElement, options){
128
+                if ($toastElement && $(':focus', $toastElement).length === 0) {
129
+                    $toastElement[options.hideMethod]({
130
+                        duration: options.hideDuration,
131
+                        easing: options.hideEasing,
132
+                        complete: function () { removeToast($toastElement); }
133
+                    });
134
+                    return true;
135
+                }
136
+                return false;
137
+            }
138
+
139
+            function createContainer(options) {
140
+                $container = $('<div/>')
141
+                    .attr('id', options.containerId)
142
+                    .addClass(options.positionClass)
143
+                    .attr('aria-live', 'polite')
144
+                    .attr('role', 'alert');
145
+
146
+                $container.appendTo($(options.target));
147
+                return $container;
148
+            }
149
+
150
+            function getDefaults() {
151
+                return {
152
+                    tapToDismiss: true,
153
+                    toastClass: 'toast',
154
+                    containerId: 'toast-container',
155
+                    debug: false,
156
+
157
+                    showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery
158
+                    showDuration: 300,
159
+                    showEasing: 'swing', //swing and linear are built into jQuery
160
+                    onShown: undefined,
161
+                    hideMethod: 'fadeOut',
162
+                    hideDuration: 1000,
163
+                    hideEasing: 'swing',
164
+                    onHidden: undefined,
165
+
166
+                    extendedTimeOut: 1000,
167
+                    iconClasses: {
168
+                        error: 'toast-error',
169
+                        info: 'toast-info',
170
+                        success: 'toast-success',
171
+                        warning: 'toast-warning'
172
+                    },
173
+                    iconClass: 'toast-info',
174
+                    positionClass: 'toast-top-right',
175
+                    timeOut: 5000, // Set timeOut and extendedTimeout to 0 to make it sticky
176
+                    titleClass: 'toast-title',
177
+                    messageClass: 'toast-message',
178
+                    target: 'body',
179
+                    closeHtml: '<button>&times;</button>',
180
+                    newestOnTop: true
181
+                };
182
+            }
183
+
184
+            function publish(args) {
185
+                if (!listener) { return; }
186
+                listener(args);
187
+            }
188
+
189
+            function notify(map) {
190
+                var options = getOptions(),
191
+                    iconClass = map.iconClass || options.iconClass;
192
+
193
+                if (typeof (map.optionsOverride) !== 'undefined') {
194
+                    options = $.extend(options, map.optionsOverride);
195
+                    iconClass = map.optionsOverride.iconClass || iconClass;
196
+                }
197
+
198
+                toastId++;
199
+
200
+                $container = getContainer(options, true);
201
+                var intervalId = null,
202
+                    $toastElement = $('<div/>'),
203
+                    $titleElement = $('<div/>'),
204
+                    $messageElement = $('<div/>'),
205
+                    $closeElement = $(options.closeHtml),
206
+                    response = {
207
+                        toastId: toastId,
208
+                        state: 'visible',
209
+                        startTime: new Date(),
210
+                        options: options,
211
+                        map: map
212
+                    };
213
+
214
+                if (map.iconClass) {
215
+                    $toastElement.addClass(options.toastClass).addClass(iconClass);
216
+                }
217
+
218
+                if (map.title) {
219
+                    $titleElement.append(map.title).addClass(options.titleClass);
220
+                    $toastElement.append($titleElement);
221
+                }
222
+
223
+                if (map.message) {
224
+                    $messageElement.append(map.message).addClass(options.messageClass);
225
+                    $toastElement.append($messageElement);
226
+                }
227
+
228
+                if (options.closeButton) {
229
+                    $closeElement.addClass('toast-close-button').attr("role", "button");
230
+                    $toastElement.prepend($closeElement);
231
+                }
232
+
233
+                if (options.reposition) {
234
+                    options.reposition();
235
+                }
236
+
237
+                $toastElement.hide();
238
+                if (options.newestOnTop) {
239
+                    $container.prepend($toastElement);
240
+                } else {
241
+                    $container.append($toastElement);
242
+                }
243
+
244
+
245
+                $toastElement[options.showMethod](
246
+                    { duration: options.showDuration, easing: options.showEasing, complete: options.onShown }
247
+                );
248
+
249
+                if (options.timeOut > 0) {
250
+                    intervalId = setTimeout(hideToast, options.timeOut);
251
+                }
252
+
253
+                $toastElement.hover(stickAround, delayedHideToast);
254
+                if (!options.onclick && options.tapToDismiss) {
255
+                    $toastElement.click(hideToast);
256
+                }
257
+
258
+                if (options.closeButton && $closeElement) {
259
+                    $closeElement.click(function (event) {
260
+                        if( event.stopPropagation ) {
261
+                            event.stopPropagation();
262
+                        } else if( event.cancelBubble !== undefined && event.cancelBubble !== true ) {
263
+                            event.cancelBubble = true;
264
+                        }
265
+                        hideToast(true);
266
+                    });
267
+                }
268
+
269
+                if (options.onclick) {
270
+                    $toastElement.click(function () {
271
+                        options.onclick();
272
+                        hideToast();
273
+                    });
274
+                }
275
+
276
+                publish(response);
277
+
278
+                if (options.debug && console) {
279
+                    console.log(response);
280
+                }
281
+
282
+                return $toastElement;
283
+
284
+                function hideToast(override) {
285
+                    if ($(':focus', $toastElement).length && !override) {
286
+                        return;
287
+                    }
288
+                    return $toastElement[options.hideMethod]({
289
+                        duration: options.hideDuration,
290
+                        easing: options.hideEasing,
291
+                        complete: function () {
292
+                            removeToast($toastElement);
293
+                            if (options.onHidden && response.state !== 'hidden') {
294
+                                options.onHidden();
295
+                            }
296
+                            response.state = 'hidden';
297
+                            response.endTime = new Date();
298
+                            publish(response);
299
+                        }
300
+                    });
301
+                }
302
+
303
+                function delayedHideToast() {
304
+                    if (options.timeOut > 0 || options.extendedTimeOut > 0) {
305
+                        intervalId = setTimeout(hideToast, options.extendedTimeOut);
306
+                    }
307
+                }
308
+
309
+                function stickAround() {
310
+                    clearTimeout(intervalId);
311
+                    $toastElement.stop(true, true)[options.showMethod](
312
+                        { duration: options.showDuration, easing: options.showEasing }
313
+                    );
314
+                }
315
+            }
316
+
317
+            function getOptions() {
318
+                return $.extend({}, getDefaults(), toastr.options);
319
+            }
320
+
321
+            function removeToast($toastElement) {
322
+                if (!$container) { $container = getContainer(); }
323
+                if ($toastElement.is(':visible')) {
324
+                    return;
325
+                }
326
+                $toastElement.remove();
327
+                $toastElement = null;
328
+                if ($container.children().length === 0) {
329
+                    $container.remove();
330
+                }
331
+            }
332
+            //#endregion
333
+
334
+        })();
335
+    });
336
+}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
337
+    if (typeof module !== 'undefined' && module.exports) { //Node
338
+        module.exports = factory(require('jquery'));
339
+    } else {
340
+        window['toastr'] = factory(window['jQuery']);
341
+    }
342
+}));

+ 10
- 0
message_handler.js Ver fichero

@@ -106,6 +106,16 @@ var messageHandler = (function(my) {
106 106
         messageHandler.openMessageDialog(title, message);
107 107
     };
108 108
 
109
+    my.notify = function(displayName, cls, message) {
110
+        toastr.info(
111
+            '<span class="nickname">' +
112
+                displayName +
113
+            '</span><br>' +
114
+            '<span class=' + cls + '>' +
115
+                message +
116
+            '</span>');
117
+    };
118
+
109 119
     return my;
110 120
 }(messageHandler || {}));
111 121
 

+ 11
- 0
videolayout.js Ver fichero

@@ -1363,6 +1363,12 @@ var VideoLayout = (function (my) {
1363 1363
             if (resourceJid
1364 1364
                 && lastNEndpoints.indexOf(resourceJid) < 0) {
1365 1365
                 console.log("Remove from last N", resourceJid);
1366
+                var jid = connection.emuc.findJidFromResource(resourceJid);
1367
+                messageHandler.notify(
1368
+                    connection.emuc.members[jid].displayName || 'Somebody',
1369
+                    'lastN',
1370
+                    'is out of dominant speakers'
1371
+                );
1366 1372
                 showPeerContainer(resourceJid, false);
1367 1373
             }
1368 1374
         });
@@ -1375,6 +1381,11 @@ var VideoLayout = (function (my) {
1375 1381
 
1376 1382
                 if (!$('#participant_' + resourceJid).is(':visible')) {
1377 1383
                     console.log("Add to last N", resourceJid);
1384
+                    var jid = connection.emuc.findJidFromResource(resourceJid);
1385
+                    messageHandler.notify(
1386
+                        connection.emuc.members[jid].displayName || 'Somebody',
1387
+                        'lastN',
1388
+                        'is in dominant speakers');
1378 1389
                     showPeerContainer(resourceJid, true);
1379 1390
 
1380 1391
                     mediaStreams.some(function (mediaStream) {

Loading…
Cancelar
Guardar