Explorar el Código

Adds display name management. Closes issue #23.

j8
Yana Stamcheva hace 11 años
padre
commit
cc887f4a8a
Se han modificado 5 ficheros con 220 adiciones y 31 borrados
  1. 152
    16
      app.js
  2. 1
    2
      css/jquery-impromptu.css
  3. 38
    2
      css/main.css
  4. 5
    5
      index.html
  5. 24
    6
      muc.js

+ 152
- 16
app.js Ver fichero

@@ -25,6 +25,11 @@ function init() {
25 25
     RTCPeerconnection = TraceablePeerConnection; 
26 26
 
27 27
     connection = new Strophe.Connection(document.getElementById('boshURL').value || config.bosh || '/http-bind');
28
+
29
+    if (nickname) {
30
+        connection.emuc.addDisplayNameToPresence(nickname);
31
+    }
32
+
28 33
     if (connection.disco) {
29 34
         // for chrome, add multistream cap
30 35
     }
@@ -270,22 +275,34 @@ $(document).bind('setLocalDescription.jingle', function (event, sid) {
270 275
 $(document).bind('joined.muc', function (event, jid, info) {
271 276
     updateRoomUrl(window.location.href);
272 277
     document.getElementById('localNick').appendChild(
273
-        document.createTextNode(Strophe.getResourceFromJid(jid) + ' (you)')
278
+        document.createTextNode(Strophe.getResourceFromJid(jid) + ' (me)')
274 279
     );
275 280
 
276 281
     if (Object.keys(connection.emuc.members).length < 1) {
277 282
         focus = new ColibriFocus(connection, config.hosts.bridge);
278 283
     }
279
-                 
284
+
285
+    showFocusIndicator();
286
+
280 287
     // Once we've joined the muc show the toolbar
281 288
     showToolbar();
289
+
290
+    var displayName = '';
291
+    if (info.displayName)
292
+        displayName = info.displayName + ' (me)';
293
+
294
+    showDisplayName('localVideoContainer', displayName);
282 295
 });
283 296
 
284 297
 $(document).bind('entered.muc', function (event, jid, info, pres) {
285 298
     console.log('entered', jid, info);
286 299
     console.log(focus);
287
-    
288
-    var container = addRemoteVideoContainer('participant_' + Strophe.getResourceFromJid(jid));
300
+
301
+    var videoSpanId = 'participant_' + Strophe.getResourceFromJid(jid);
302
+    var container = addRemoteVideoContainer(videoSpanId);
303
+
304
+    if (info.displayName)
305
+        showDisplayName(videoSpanId, info.displayName);
289 306
 
290 307
     var nickfield = document.createElement('span');
291 308
     nickfield.appendChild(document.createTextNode(Strophe.getResourceFromJid(jid)));
@@ -350,6 +367,13 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
350 367
         //console.log(jid, 'assoc ssrc', ssrc.getAttribute('type'), ssrc.getAttribute('ssrc'));
351 368
         ssrc2jid[ssrc.getAttribute('ssrc')] = jid;
352 369
     });
370
+
371
+    if (info.displayName) {
372
+        if (jid === connection.emuc.myroomjid)
373
+            showDisplayName('localVideoContainer', info.displayName + ' (me)');
374
+        else
375
+            showDisplayName('participant_' + Strophe.getResourceFromJid(jid), info.displayName);
376
+    }
353 377
 });
354 378
 
355 379
 $(document).bind('passwordrequired.muc', function (event, jid) {
@@ -371,7 +395,7 @@ $(document).bind('passwordrequired.muc', function (event, jid) {
371 395
 
372 396
                         if (lockKey.value != null)
373 397
                         {
374
-                            setSharedKey(lockKey);
398
+                            setSharedKey(lockKey.value);
375 399
                             connection.emuc.doJoin(jid, lockKey.value);
376 400
                         }
377 401
                     }
@@ -559,7 +583,9 @@ function toggleAudio() {
559 583
 function resizeLarge() {
560 584
     resizeChat();
561 585
     var availableHeight = window.innerHeight;
562
-    var chatspaceWidth = $('#chatspace').width();
586
+    var chatspaceWidth = $('#chatspace').is(":visible")
587
+                            ? $('#chatspace').width()
588
+                            : 0;
563 589
 
564 590
     var numvids = $('#remoteVideos>video:visible').length;
565 591
     if (numvids < 5)
@@ -631,6 +657,13 @@ function resizeChatConversation() {
631 657
 }
632 658
 
633 659
 $(document).ready(function () {
660
+    var storedDisplayName = window.localStorage.displayname;
661
+    if (storedDisplayName) {
662
+        nickname = storedDisplayName;
663
+
664
+        setChatConversationMode(true);
665
+    }
666
+
634 667
     $('#nickinput').keydown(function(event) {
635 668
         if (event.keyCode == 13) {
636 669
             event.preventDefault();
@@ -638,10 +671,13 @@ $(document).ready(function () {
638 671
             this.value = '';
639 672
             if (!nickname) {
640 673
                 nickname = val;
641
-                $('#nickname').css({visibility:"hidden"});
642
-                $('#chatconversation').css({visibility:'visible'});
643
-                $('#usermsg').css({visibility:'visible'});
644
-                $('#usermsg').focus();
674
+                window.localStorage.displayname = nickname;
675
+
676
+                connection.emuc.addDisplayNameToPresence(nickname);
677
+                connection.emuc.sendPresence();
678
+
679
+                setChatConversationMode(true);
680
+
645 681
                 return;
646 682
             }
647 683
         }
@@ -743,7 +779,7 @@ function updateChatConversation(nick, message)
743 779
         divClassName = "localuser";
744 780
     else
745 781
         divClassName = "remoteuser";
746
-   
782
+
747 783
     //replace links and smileys
748 784
     message = processReplacements(message);
749 785
 
@@ -1072,11 +1108,11 @@ function closePageWarning() {
1072 1108
  */
1073 1109
 function showFocusIndicator() {
1074 1110
     if (focus != null) {
1075
-        var localVideoToolbar = document.getElementById('localVideoToolbar');
1111
+        var indicatorSpan = $('#localVideoContainer .focusindicator');
1076 1112
 
1077
-        if (localVideoToolbar.childNodes.length === 0)
1113
+        if (indicatorSpan.children().length == 0)
1078 1114
         {
1079
-            createFocusIndicatorElement(localVideoToolbar);
1115
+            createFocusIndicatorElement(indicatorSpan[0]);
1080 1116
         }
1081 1117
     }
1082 1118
     else if (Object.keys(connection.jingle.sessions).length > 0) {
@@ -1121,12 +1157,11 @@ function scrollChatToBottom() {
1121 1157
     }, 5);
1122 1158
 }
1123 1159
 
1124
-
1125 1160
 /*
1126 1161
  * Toggles the application in and out of full screen mode 
1127 1162
  * (a.k.a. presentation mode in Chrome).
1128 1163
  */
1129
-function toggleFullScreen() {    
1164
+function toggleFullScreen() {
1130 1165
     var fsElement = document.documentElement;
1131 1166
 
1132 1167
     if (!document.mozFullScreen && !document.webkitIsFullScreen){
@@ -1151,3 +1186,104 @@ function toggleFullScreen() {
1151 1186
         }
1152 1187
     }
1153 1188
 }
1189
+
1190
+/**
1191
+ *
1192
+ */
1193
+function showDisplayName(videoSpanId, displayName) {
1194
+    var nameSpan = $('#' + videoSpanId + '>span.displayname');
1195
+
1196
+    // If we already have a display name for this video.
1197
+    if (nameSpan.length > 0) {
1198
+        var nameSpanElement = nameSpan.get(0);
1199
+
1200
+        if (nameSpanElement.id == 'localDisplayName'
1201
+            && $('#localDisplayName').html() != displayName)
1202
+            $('#localDisplayName').html(displayName);
1203
+        else
1204
+            $('#' + videoSpanId + '_name').html(displayName);
1205
+    }
1206
+    else {
1207
+        var editButton = null;
1208
+        if (videoSpanId == 'localVideoContainer') {
1209
+            editButton = createEditDisplayNameButton();
1210
+        }
1211
+
1212
+        if (displayName.length) {
1213
+            nameSpan = document.createElement('span');
1214
+            nameSpan.className = 'displayname';
1215
+            nameSpan.innerHTML = displayName;
1216
+            $('#' + videoSpanId)[0].appendChild(nameSpan);
1217
+        }
1218
+
1219
+        if (!editButton) {
1220
+            nameSpan.id = videoSpanId + '_name';
1221
+        }
1222
+        else {
1223
+            nameSpan.id = 'localDisplayName';
1224
+            $('#' + videoSpanId)[0].appendChild(editButton);
1225
+            
1226
+            var editableText = document.createElement('input');
1227
+            editableText.className = 'displayname';
1228
+            editableText.id = 'editDisplayName';
1229
+
1230
+            if (displayName.length)
1231
+                editableText.value = displayName.substring(0, displayName.indexOf(' (me)'));
1232
+
1233
+            editableText.setAttribute('style', 'display:none;');
1234
+            editableText.setAttribute('placeholder', 'ex. Jane Pink');
1235
+            $('#' + videoSpanId)[0].appendChild(editableText);
1236
+
1237
+            $('#localVideoContainer .displayname').bind("click", function(e) {
1238
+                e.preventDefault();
1239
+                $('#localDisplayName').hide();
1240
+                $('#editDisplayName').show();
1241
+                $('#editDisplayName').focus();
1242
+                $('#editDisplayName').select();
1243
+
1244
+                var inputDisplayNameHandler = function(name) {
1245
+                    if (nickname != name) {
1246
+                        nickname = name;
1247
+                        window.localStorage.displayname = nickname;
1248
+                        connection.emuc.addDisplayNameToPresence(nickname);
1249
+                        connection.emuc.sendPresence();
1250
+                    }
1251
+
1252
+                    if (!$('#localDisplayName').is(":visible")) {
1253
+                        $('#localDisplayName').html(name + " (me)");
1254
+                        $('#localDisplayName').show();
1255
+                        $('#editDisplayName').hide();
1256
+                    }
1257
+                };
1258
+
1259
+                $('#editDisplayName').one("focusout", function (e) {
1260
+                    inputDisplayNameHandler(this.value);
1261
+                });
1262
+
1263
+                $('#editDisplayName').on('keydown', function (e) {
1264
+                    if (e.keyCode == 13) {
1265
+                        e.preventDefault();
1266
+                        inputDisplayNameHandler(this.value);
1267
+                    }
1268
+                });
1269
+            });
1270
+        }
1271
+    }
1272
+}
1273
+
1274
+function createEditDisplayNameButton() {
1275
+    var editButton = document.createElement('a');
1276
+    editButton.className = 'displayname';
1277
+    editButton.innerHTML = '<i class="fa fa-pencil"></i>';
1278
+
1279
+    return editButton;
1280
+}
1281
+
1282
+function setChatConversationMode(isConversationMode) {
1283
+    if (isConversationMode) {
1284
+        $('#nickname').css({visibility:"hidden"});
1285
+        $('#chatconversation').css({visibility:'visible'});
1286
+        $('#usermsg').css({visibility:'visible'});
1287
+        $('#usermsg').focus();
1288
+    }
1289
+}

+ 1
- 2
css/jquery-impromptu.css Ver fichero

@@ -8,8 +8,7 @@
8 8
 	background-color: #000;
9 9
 }
10 10
 div.jqi{ 
11
-	width: 400px; 
12
-	font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; 
11
+	width: 400px;
13 12
 	position: absolute; 
14 13
 	background-color: #ffffff; 
15 14
 	font-size: 11px; 

+ 38
- 2
css/main.css Ver fichero

@@ -2,7 +2,7 @@ html, body{
2 2
     margin:0px;
3 3
     height:100%;
4 4
     color: #424242;
5
-    font-family:'YanoneKaffeesatzLight',Verdana,Tahoma,Arial;
5
+    font-family:'Helvetica Neue', Helvetica, sans-serif;
6 6
 	font-weight: 400;
7 7
     background: #e9e9e9;
8 8
     overflow-x: hidden;
@@ -295,7 +295,6 @@ input[type='text'], textarea {
295 295
     line-height: 20px;
296 296
     height: 40px;
297 297
     color: #333;
298
-    font-weight: bold;
299 298
     text-align: left;
300 299
     border:1px solid #ACD8F0;
301 300
     outline: none; /* removes the default outline */
@@ -365,6 +364,43 @@ form {
365 364
     z-index: 2;
366 365
 }
367 366
 
367
+.videocontainer>span.displayname,
368
+.videocontainer>input.displayname {
369
+    display: inline-block;
370
+    position: absolute;
371
+    background: -webkit-linear-gradient(left, rgba(0,0,0,.7), rgba(0,0,0,0));
372
+    color: #b7b7b7;
373
+    bottom: 0;
374
+    left: 0;
375
+    padding: 3px 5px;
376
+    width: 100%;
377
+    height: auto;
378
+    max-height: 18px;
379
+    font-size: 9pt;
380
+    text-align: left;
381
+    text-overflow: ellipsis;
382
+    overflow: hidden;
383
+    white-space: nowrap;
384
+    z-index: 2;
385
+    box-sizing: border-box;
386
+}
387
+
388
+#localVideoContainer>span.displayname:hover {
389
+    cursor: text;
390
+}
391
+
392
+.videocontainer>a.displayname {
393
+    display: inline-block;
394
+    position: absolute;
395
+    color: #b7b7b7;
396
+    bottom: 0;
397
+    right: 0;
398
+    padding: 3px 5px;
399
+    font-size: 9pt;
400
+    cursor: pointer;
401
+    z-index: 2;
402
+}
403
+
368 404
 #reloadPresentation {
369 405
     display: none;
370 406
     position: absolute;

+ 5
- 5
index.html Ver fichero

@@ -5,14 +5,14 @@
5 5
     <script src="libs/strophejingle.bundle.js?v=7"></script><!-- strophe.jingle bundle -->
6 6
     <script src="libs/colibri.js?v=7"></script><!-- colibri focus implementation -->
7 7
     <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
8
-    <script src="muc.js?v=4"></script><!-- simple MUC library -->
8
+    <script src="muc.js?v=5"></script><!-- simple MUC library -->
9 9
     <script src="estos_log.js?v=2"></script><!-- simple stanza logger -->
10
-    <script src="app.js?v=17"></script><!-- application logic -->
10
+    <script src="app.js?v=18"></script><!-- application logic -->
11 11
     <script src="smileys.js?v=1"></script><!-- smiley images -->
12 12
     <script src="replacement.js?v=5"></script><!-- link and smiley replacement -->
13 13
     <link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
14
-    <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=14"/>
15
-    <link rel="stylesheet" href="css/jquery-impromptu.css?v=3">
14
+    <link rel="stylesheet" type="text/css" media="screen" href="css/main.css?v=15"/>
15
+    <link rel="stylesheet" href="css/jquery-impromptu.css?v=4">
16 16
     <link rel="stylesheet" href="css/modaldialog.css?v=3">
17 17
     <script src="libs/jquery-impromptu.js"></script>
18 18
     <script src="libs/jquery.autosize.js"></script>
@@ -65,7 +65,7 @@
65 65
             <span id="localVideoContainer" class="videocontainer">
66 66
                 <span id="localNick"></span>
67 67
                 <video id="localVideo" autoplay oncontextmenu="return false;" muted></video>
68
-                <span id="localVideoToolbar" class="focusindicator"></span>
68
+                <span class="focusindicator"></span>
69 69
             </span>
70 70
         </div>
71 71
     </div>

+ 24
- 6
muc.js Ver fichero

@@ -31,15 +31,12 @@ Strophe.addConnectionPlugin('emuc', {
31 31
             this.connection.addHandler(this.onPresenceError.bind(this), null, 'presence', 'error', null, this.roomjid, {matchBare: true});
32 32
             this.connection.addHandler(this.onMessage.bind(this), null, 'message', null, null, this.roomjid, {matchBare: true});
33 33
         }
34
-
35
-        var join = $pres({to: this.myroomjid }).c('x', {xmlns: 'http://jabber.org/protocol/muc'});
36 34
         if (password !== undefined) {
37
-            join.c('password').t(password);
35
+            this.presMap['password'] = password;
38 36
         }
39
-        this.connection.send(join);
37
+        this.sendPresence();
40 38
     },
41 39
     onPresence: function (pres) {
42
-        console.log("PRESENCE", pres);
43 40
         var from = pres.getAttribute('from');
44 41
         var type = pres.getAttribute('type');
45 42
         if (type != null) {
@@ -83,6 +80,10 @@ Strophe.addConnectionPlugin('emuc', {
83 80
         var tmp = $(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>item');
84 81
         member.affiliation = tmp.attr('affiliation');
85 82
         member.role = tmp.attr('role');
83
+
84
+        var nicktag = $(pres).find('>nick[xmlns="http://jabber.org/protocol/nick"]');
85
+        member.displayName = (nicktag.length > 0 ? nicktag.text() : null);
86
+
86 87
         if (from == this.myroomjid) {
87 88
             if (member.affiliation == 'owner') this.isOwner = true;
88 89
             if (!this.joined) {
@@ -90,6 +91,8 @@ Strophe.addConnectionPlugin('emuc', {
90 91
                 $(document).trigger('joined.muc', [from, member]);
91 92
                 this.list_members.push(from);
92 93
             }
94
+            else
95
+                $(document).trigger('presence.muc', [from, member, pres]);
93 96
         } else if (this.members[from] === undefined) {
94 97
             // new participant
95 98
             this.members[from] = member;
@@ -167,7 +170,19 @@ Strophe.addConnectionPlugin('emuc', {
167 170
     },
168 171
     sendPresence: function () {
169 172
         var pres = $pres({to: this.presMap['to'] });
170
-        pres.c('x', {xmlns: this.presMap['xns']}).up();
173
+        pres.c('x', {xmlns: this.presMap['xns']});
174
+
175
+        if (this.presMap['password']) {
176
+            pres.c('password').t(this.presMap['password']).up();
177
+        }
178
+
179
+        pres.up();
180
+
181
+        if (this.presMap['displayName']) {
182
+            // XEP-0172
183
+            pres.c('nick', {xmlns: 'http://jabber.org/protocol/nick'}).t(this.presMap['displayName']).up();
184
+        }
185
+
171 186
         if (this.presMap['prezins']) {
172 187
             pres.c('prezi', {xmlns: this.presMap['prezins'], 'url': this.presMap['preziurl']}).
173 188
                             c('current').t(this.presMap['prezicurrent']).up().up();
@@ -192,6 +207,9 @@ Strophe.addConnectionPlugin('emuc', {
192 207
         pres.up();
193 208
         connection.send(pres);
194 209
     },
210
+    addDisplayNameToPresence: function (displayName) {
211
+        this.presMap['displayName'] = displayName;
212
+    },
195 213
     addMediaToPresence: function (sourceNumber, mtype, ssrcs) {
196 214
         if (!this.presMap['medians'])
197 215
             this.presMap['medians'] = 'http://estos.de/ns/mjs';

Loading…
Cancelar
Guardar