Adds display name management. Closes issue #23.

This commit is contained in:
Yana Stamcheva 2014-02-11 15:05:17 +01:00
parent 53f97c6c29
commit cc887f4a8a
5 changed files with 220 additions and 31 deletions

168
app.js
View File

@ -25,6 +25,11 @@ function init() {
RTCPeerconnection = TraceablePeerConnection;
connection = new Strophe.Connection(document.getElementById('boshURL').value || config.bosh || '/http-bind');
if (nickname) {
connection.emuc.addDisplayNameToPresence(nickname);
}
if (connection.disco) {
// for chrome, add multistream cap
}
@ -270,22 +275,34 @@ $(document).bind('setLocalDescription.jingle', function (event, sid) {
$(document).bind('joined.muc', function (event, jid, info) {
updateRoomUrl(window.location.href);
document.getElementById('localNick').appendChild(
document.createTextNode(Strophe.getResourceFromJid(jid) + ' (you)')
document.createTextNode(Strophe.getResourceFromJid(jid) + ' (me)')
);
if (Object.keys(connection.emuc.members).length < 1) {
focus = new ColibriFocus(connection, config.hosts.bridge);
}
showFocusIndicator();
// Once we've joined the muc show the toolbar
showToolbar();
var displayName = '';
if (info.displayName)
displayName = info.displayName + ' (me)';
showDisplayName('localVideoContainer', displayName);
});
$(document).bind('entered.muc', function (event, jid, info, pres) {
console.log('entered', jid, info);
console.log(focus);
var container = addRemoteVideoContainer('participant_' + Strophe.getResourceFromJid(jid));
var videoSpanId = 'participant_' + Strophe.getResourceFromJid(jid);
var container = addRemoteVideoContainer(videoSpanId);
if (info.displayName)
showDisplayName(videoSpanId, info.displayName);
var nickfield = document.createElement('span');
nickfield.appendChild(document.createTextNode(Strophe.getResourceFromJid(jid)));
@ -350,6 +367,13 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
//console.log(jid, 'assoc ssrc', ssrc.getAttribute('type'), ssrc.getAttribute('ssrc'));
ssrc2jid[ssrc.getAttribute('ssrc')] = jid;
});
if (info.displayName) {
if (jid === connection.emuc.myroomjid)
showDisplayName('localVideoContainer', info.displayName + ' (me)');
else
showDisplayName('participant_' + Strophe.getResourceFromJid(jid), info.displayName);
}
});
$(document).bind('passwordrequired.muc', function (event, jid) {
@ -371,7 +395,7 @@ $(document).bind('passwordrequired.muc', function (event, jid) {
if (lockKey.value != null)
{
setSharedKey(lockKey);
setSharedKey(lockKey.value);
connection.emuc.doJoin(jid, lockKey.value);
}
}
@ -559,7 +583,9 @@ function toggleAudio() {
function resizeLarge() {
resizeChat();
var availableHeight = window.innerHeight;
var chatspaceWidth = $('#chatspace').width();
var chatspaceWidth = $('#chatspace').is(":visible")
? $('#chatspace').width()
: 0;
var numvids = $('#remoteVideos>video:visible').length;
if (numvids < 5)
@ -631,6 +657,13 @@ function resizeChatConversation() {
}
$(document).ready(function () {
var storedDisplayName = window.localStorage.displayname;
if (storedDisplayName) {
nickname = storedDisplayName;
setChatConversationMode(true);
}
$('#nickinput').keydown(function(event) {
if (event.keyCode == 13) {
event.preventDefault();
@ -638,10 +671,13 @@ $(document).ready(function () {
this.value = '';
if (!nickname) {
nickname = val;
$('#nickname').css({visibility:"hidden"});
$('#chatconversation').css({visibility:'visible'});
$('#usermsg').css({visibility:'visible'});
$('#usermsg').focus();
window.localStorage.displayname = nickname;
connection.emuc.addDisplayNameToPresence(nickname);
connection.emuc.sendPresence();
setChatConversationMode(true);
return;
}
}
@ -743,7 +779,7 @@ function updateChatConversation(nick, message)
divClassName = "localuser";
else
divClassName = "remoteuser";
//replace links and smileys
message = processReplacements(message);
@ -1072,11 +1108,11 @@ function closePageWarning() {
*/
function showFocusIndicator() {
if (focus != null) {
var localVideoToolbar = document.getElementById('localVideoToolbar');
var indicatorSpan = $('#localVideoContainer .focusindicator');
if (localVideoToolbar.childNodes.length === 0)
if (indicatorSpan.children().length == 0)
{
createFocusIndicatorElement(localVideoToolbar);
createFocusIndicatorElement(indicatorSpan[0]);
}
}
else if (Object.keys(connection.jingle.sessions).length > 0) {
@ -1121,12 +1157,11 @@ function scrollChatToBottom() {
}, 5);
}
/*
* Toggles the application in and out of full screen mode
* (a.k.a. presentation mode in Chrome).
*/
function toggleFullScreen() {
function toggleFullScreen() {
var fsElement = document.documentElement;
if (!document.mozFullScreen && !document.webkitIsFullScreen){
@ -1151,3 +1186,104 @@ function toggleFullScreen() {
}
}
}
/**
*
*/
function showDisplayName(videoSpanId, displayName) {
var nameSpan = $('#' + videoSpanId + '>span.displayname');
// If we already have a display name for this video.
if (nameSpan.length > 0) {
var nameSpanElement = nameSpan.get(0);
if (nameSpanElement.id == 'localDisplayName'
&& $('#localDisplayName').html() != displayName)
$('#localDisplayName').html(displayName);
else
$('#' + videoSpanId + '_name').html(displayName);
}
else {
var editButton = null;
if (videoSpanId == 'localVideoContainer') {
editButton = createEditDisplayNameButton();
}
if (displayName.length) {
nameSpan = document.createElement('span');
nameSpan.className = 'displayname';
nameSpan.innerHTML = displayName;
$('#' + videoSpanId)[0].appendChild(nameSpan);
}
if (!editButton) {
nameSpan.id = videoSpanId + '_name';
}
else {
nameSpan.id = 'localDisplayName';
$('#' + videoSpanId)[0].appendChild(editButton);
var editableText = document.createElement('input');
editableText.className = 'displayname';
editableText.id = 'editDisplayName';
if (displayName.length)
editableText.value = displayName.substring(0, displayName.indexOf(' (me)'));
editableText.setAttribute('style', 'display:none;');
editableText.setAttribute('placeholder', 'ex. Jane Pink');
$('#' + videoSpanId)[0].appendChild(editableText);
$('#localVideoContainer .displayname').bind("click", function(e) {
e.preventDefault();
$('#localDisplayName').hide();
$('#editDisplayName').show();
$('#editDisplayName').focus();
$('#editDisplayName').select();
var inputDisplayNameHandler = function(name) {
if (nickname != name) {
nickname = name;
window.localStorage.displayname = nickname;
connection.emuc.addDisplayNameToPresence(nickname);
connection.emuc.sendPresence();
}
if (!$('#localDisplayName').is(":visible")) {
$('#localDisplayName').html(name + " (me)");
$('#localDisplayName').show();
$('#editDisplayName').hide();
}
};
$('#editDisplayName').one("focusout", function (e) {
inputDisplayNameHandler(this.value);
});
$('#editDisplayName').on('keydown', function (e) {
if (e.keyCode == 13) {
e.preventDefault();
inputDisplayNameHandler(this.value);
}
});
});
}
}
}
function createEditDisplayNameButton() {
var editButton = document.createElement('a');
editButton.className = 'displayname';
editButton.innerHTML = '<i class="fa fa-pencil"></i>';
return editButton;
}
function setChatConversationMode(isConversationMode) {
if (isConversationMode) {
$('#nickname').css({visibility:"hidden"});
$('#chatconversation').css({visibility:'visible'});
$('#usermsg').css({visibility:'visible'});
$('#usermsg').focus();
}
}

View File

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

View File

@ -2,7 +2,7 @@ html, body{
margin:0px;
height:100%;
color: #424242;
font-family:'YanoneKaffeesatzLight',Verdana,Tahoma,Arial;
font-family:'Helvetica Neue', Helvetica, sans-serif;
font-weight: 400;
background: #e9e9e9;
overflow-x: hidden;
@ -295,7 +295,6 @@ input[type='text'], textarea {
line-height: 20px;
height: 40px;
color: #333;
font-weight: bold;
text-align: left;
border:1px solid #ACD8F0;
outline: none; /* removes the default outline */
@ -365,6 +364,43 @@ form {
z-index: 2;
}
.videocontainer>span.displayname,
.videocontainer>input.displayname {
display: inline-block;
position: absolute;
background: -webkit-linear-gradient(left, rgba(0,0,0,.7), rgba(0,0,0,0));
color: #b7b7b7;
bottom: 0;
left: 0;
padding: 3px 5px;
width: 100%;
height: auto;
max-height: 18px;
font-size: 9pt;
text-align: left;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
z-index: 2;
box-sizing: border-box;
}
#localVideoContainer>span.displayname:hover {
cursor: text;
}
.videocontainer>a.displayname {
display: inline-block;
position: absolute;
color: #b7b7b7;
bottom: 0;
right: 0;
padding: 3px 5px;
font-size: 9pt;
cursor: pointer;
z-index: 2;
}
#reloadPresentation {
display: none;
position: absolute;

View File

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

30
muc.js
View File

@ -31,15 +31,12 @@ Strophe.addConnectionPlugin('emuc', {
this.connection.addHandler(this.onPresenceError.bind(this), null, 'presence', 'error', null, this.roomjid, {matchBare: true});
this.connection.addHandler(this.onMessage.bind(this), null, 'message', null, null, this.roomjid, {matchBare: true});
}
var join = $pres({to: this.myroomjid }).c('x', {xmlns: 'http://jabber.org/protocol/muc'});
if (password !== undefined) {
join.c('password').t(password);
this.presMap['password'] = password;
}
this.connection.send(join);
this.sendPresence();
},
onPresence: function (pres) {
console.log("PRESENCE", pres);
var from = pres.getAttribute('from');
var type = pres.getAttribute('type');
if (type != null) {
@ -83,6 +80,10 @@ Strophe.addConnectionPlugin('emuc', {
var tmp = $(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>item');
member.affiliation = tmp.attr('affiliation');
member.role = tmp.attr('role');
var nicktag = $(pres).find('>nick[xmlns="http://jabber.org/protocol/nick"]');
member.displayName = (nicktag.length > 0 ? nicktag.text() : null);
if (from == this.myroomjid) {
if (member.affiliation == 'owner') this.isOwner = true;
if (!this.joined) {
@ -90,6 +91,8 @@ Strophe.addConnectionPlugin('emuc', {
$(document).trigger('joined.muc', [from, member]);
this.list_members.push(from);
}
else
$(document).trigger('presence.muc', [from, member, pres]);
} else if (this.members[from] === undefined) {
// new participant
this.members[from] = member;
@ -167,7 +170,19 @@ Strophe.addConnectionPlugin('emuc', {
},
sendPresence: function () {
var pres = $pres({to: this.presMap['to'] });
pres.c('x', {xmlns: this.presMap['xns']}).up();
pres.c('x', {xmlns: this.presMap['xns']});
if (this.presMap['password']) {
pres.c('password').t(this.presMap['password']).up();
}
pres.up();
if (this.presMap['displayName']) {
// XEP-0172
pres.c('nick', {xmlns: 'http://jabber.org/protocol/nick'}).t(this.presMap['displayName']).up();
}
if (this.presMap['prezins']) {
pres.c('prezi', {xmlns: this.presMap['prezins'], 'url': this.presMap['preziurl']}).
c('current').t(this.presMap['prezicurrent']).up().up();
@ -192,6 +207,9 @@ Strophe.addConnectionPlugin('emuc', {
pres.up();
connection.send(pres);
},
addDisplayNameToPresence: function (displayName) {
this.presMap['displayName'] = displayName;
},
addMediaToPresence: function (sourceNumber, mtype, ssrcs) {
if (!this.presMap['medians'])
this.presMap['medians'] = 'http://estos.de/ns/mjs';