mirror of https://github.com/jitsi/jitsi-meet
parent
c438676eae
commit
1d4177faeb
@ -0,0 +1,138 @@ |
||||
var Avatar = (function(my) { |
||||
var users = {}; |
||||
var activeSpeakerJid; |
||||
/** |
||||
* Sets the user's avatar in the settings menu(if local user), contact list |
||||
* and thumbnail |
||||
* @param jid jid of the user |
||||
* @param id email or userID to be used as a hash |
||||
*/ |
||||
my.setUserAvatar = function(jid, id) { |
||||
if(id) { |
||||
if(users[jid] === id) { |
||||
return; |
||||
} |
||||
users[jid] = id; |
||||
} |
||||
var url = getGravatarUrl(users[jid]); |
||||
var resourceJid = Strophe.getResourceFromJid(jid); |
||||
var thumbnail = $('#participant_' + resourceJid); |
||||
var avatar = $('#avatar_' + resourceJid); |
||||
|
||||
// set the avatar in the settings menu if it is local user and get the
|
||||
// local video container
|
||||
if(jid === connection.emuc.myroomjid) { |
||||
$('#avatar').get(0).src = url; |
||||
thumbnail = $('#localVideoContainer'); |
||||
} |
||||
|
||||
// set the avatar in the contact list
|
||||
var contact = $('#' + resourceJid + '>img'); |
||||
if(contact && contact.length > 0) { |
||||
contact.get(0).src = url; |
||||
} |
||||
|
||||
// set the avatar in the thumbnail
|
||||
if(avatar && avatar.length > 0) { |
||||
avatar[0].src = url; |
||||
} else { |
||||
if (thumbnail && thumbnail.length > 0) { |
||||
avatar = document.createElement('img'); |
||||
avatar.id = 'avatar_' + resourceJid; |
||||
avatar.className = 'userAvatar'; |
||||
avatar.src = url; |
||||
thumbnail.append(avatar); |
||||
} |
||||
} |
||||
|
||||
//if the user is the current active speaker - update the active speaker
|
||||
// avatar
|
||||
if(jid === activeSpeakerJid) { |
||||
Avatar.updateActiveSpeakerAvatarSrc(jid); |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* Hides or shows the user's avatar |
||||
* @param jid jid of the user |
||||
* @param show whether we should show the avatar or not |
||||
* video because there is no dominant speaker and no focused speaker |
||||
*/ |
||||
my.showUserAvatar = function(jid, show) { |
||||
if(users[jid]) { |
||||
var resourceJid = Strophe.getResourceFromJid(jid); |
||||
var video = $('#participant_' + resourceJid + '>video'); |
||||
var avatar = $('#avatar_' + resourceJid); |
||||
|
||||
if(jid === connection.emuc.myroomjid) { |
||||
video = $('#localVideoWrapper>video'); |
||||
} |
||||
if(show === undefined || show === null) { |
||||
show = isUserMuted(jid); |
||||
} |
||||
|
||||
//if the user is the currently focused, the dominant speaker or if
|
||||
//there is no focused and no dominant speaker
|
||||
if (activeSpeakerJid === jid) { |
||||
setVisibility($("#largeVideo"), !show); |
||||
setVisibility($('#activeSpeakerAvatar'), show); |
||||
setVisibility(avatar, false); |
||||
setVisibility(video, false); |
||||
} else { |
||||
if (video && video.length > 0) { |
||||
setVisibility(video, !show); |
||||
setVisibility(avatar, show); |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* Updates the src of the active speaker avatar |
||||
* @param jid of the current active speaker |
||||
*/ |
||||
my.updateActiveSpeakerAvatarSrc = function(jid) { |
||||
if(!jid) { |
||||
if (focusedVideoSrc) { |
||||
jid = getJidFromVideoSrc(focusedVideoSrc); |
||||
} else { |
||||
jid = connection.emuc.findJidFromResource( |
||||
VideoLayout.getDominantSpeakerResourceJid()); |
||||
} |
||||
} |
||||
var avatar = $("#activeSpeakerAvatar")[0]; |
||||
var url = getGravatarUrl(users[jid], |
||||
interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE); |
||||
if(jid === activeSpeakerJid && avatar.src === url) { |
||||
return; |
||||
} |
||||
activeSpeakerJid = jid; |
||||
var isMuted = isUserMuted(jid); |
||||
if(jid && isMuted !== null) { |
||||
avatar.src = url; |
||||
setVisibility($("#largeVideo"), !isMuted); |
||||
Avatar.showUserAvatar(jid, isMuted); |
||||
} |
||||
}; |
||||
|
||||
function setVisibility(selector, show) { |
||||
if (selector && selector.length > 0) { |
||||
selector.css("visibility", show ? "visible" : "hidden"); |
||||
} |
||||
} |
||||
|
||||
function isUserMuted(jid) { |
||||
if(!mediaStreams[jid] || !mediaStreams[jid][MediaStream.VIDEO_TYPE]) { |
||||
return null; |
||||
} |
||||
return mediaStreams[jid][MediaStream.VIDEO_TYPE].muted; |
||||
} |
||||
|
||||
function getGravatarUrl(email, size) { |
||||
return 'https://www.gravatar.com/avatar/' + |
||||
(email ? MD5.hexdigest(email.trim().toLowerCase()) : SettingsMenu.getUID()) + |
||||
"?d=retro&size=" + (size || "30"); |
||||
} |
||||
|
||||
return my; |
||||
}(Avatar || {})); |
@ -0,0 +1,45 @@ |
||||
#settingsmenu { |
||||
background: black; |
||||
color: #00ccff; |
||||
} |
||||
|
||||
#settingsmenu input { |
||||
margin-top: 10px; |
||||
margin-left: 10%; |
||||
width: 80%; |
||||
font-size: 14px; |
||||
background: #3a3a3a; |
||||
border: none; |
||||
box-shadow: none; |
||||
color: #a7a7a7; |
||||
} |
||||
|
||||
#settingsmenu .arrow-up { |
||||
width: 0; |
||||
height: 0; |
||||
border-left: 5px solid transparent; |
||||
border-right: 5px solid transparent; |
||||
border-bottom: 5px solid #3a3a3a; |
||||
position: relative; |
||||
top: 10px; |
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
} |
||||
|
||||
#settingsmenu button { |
||||
width: 36%; |
||||
left: 32%; |
||||
padding: 0; |
||||
margin-top: 10px; |
||||
} |
||||
|
||||
#settingsmenu #avatar { |
||||
width: 24%; |
||||
left: 38%; |
||||
border-radius: 25px; |
||||
position: relative; |
||||
} |
||||
|
||||
#settingsmenu .icon-settings { |
||||
padding: 34px; |
||||
} |
Binary file not shown.
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 33 KiB |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,83 @@ |
||||
var SettingsMenu = (function(my) { |
||||
|
||||
var email = ''; |
||||
var displayName = ''; |
||||
var userId; |
||||
|
||||
if(supportsLocalStorage()) { |
||||
if(!window.localStorage.jitsiMeetId) { |
||||
window.localStorage.jitsiMeetId = generateUniqueId(); |
||||
console.log("generated id", window.localStorage.jitsiMeetId); |
||||
} |
||||
userId = window.localStorage.jitsiMeetId || ''; |
||||
email = window.localStorage.email || ''; |
||||
displayName = window.localStorage.displayname || ''; |
||||
} else { |
||||
console.log("local storage is not supported"); |
||||
userId = generateUniqueId(); |
||||
} |
||||
|
||||
my.update = function() { |
||||
var newDisplayName = Util.escapeHtml($('#setDisplayName').get(0).value); |
||||
if(newDisplayName) { |
||||
displayName = newDisplayName; |
||||
connection.emuc.addDisplayNameToPresence(displayName); |
||||
window.localStorage.displayname = displayName; |
||||
} |
||||
|
||||
var newEmail = Util.escapeHtml($('#setEmail').get(0).value); |
||||
connection.emuc.addEmailToPresence(newEmail); |
||||
email = newEmail; |
||||
window.localStorage.email = newEmail; |
||||
|
||||
connection.emuc.sendPresence(); |
||||
Avatar.setUserAvatar(connection.emuc.myroomjid, email); |
||||
}; |
||||
|
||||
my.isVisible = function() { |
||||
return $('#settingsmenu').is(':visible'); |
||||
}; |
||||
|
||||
my.getUID = function() { |
||||
return userId; |
||||
}; |
||||
|
||||
my.getEmail = function() { |
||||
return email; |
||||
}; |
||||
|
||||
my.getDisplayName = function() { |
||||
return displayName; |
||||
}; |
||||
|
||||
my.setDisplayName = function(newDisplayName) { |
||||
displayName = newDisplayName; |
||||
window.localStorage.displayname = displayName; |
||||
$('#setDisplayName').get(0).value = displayName; |
||||
}; |
||||
|
||||
function supportsLocalStorage() { |
||||
try { |
||||
return 'localStorage' in window && window.localStorage !== null; |
||||
} catch (e) { |
||||
console.log("localstorage is not supported"); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
function generateUniqueId() { |
||||
function _p8() { |
||||
return (Math.random().toString(16)+"000000000").substr(2,8); |
||||
} |
||||
return _p8() + _p8() + _p8() + _p8(); |
||||
} |
||||
|
||||
$(document).bind('displaynamechanged', function(event, peerJid, newDisplayName) { |
||||
if(peerJid === 'localVideoContainer' || |
||||
peerJid === connection.emuc.myroomjid) { |
||||
SettingsMenu.setDisplayName(newDisplayName); |
||||
} |
||||
}); |
||||
|
||||
return my; |
||||
}(SettingsMenu || {})); |
@ -0,0 +1,245 @@ |
||||
/** |
||||
* Toggler for the chat, contact list, settings menu, etc.. |
||||
*/ |
||||
var PanelToggler = (function(my) { |
||||
|
||||
var currentlyOpen = null; |
||||
var buttons = { |
||||
'#chatspace': '#chatBottomButton', |
||||
'#contactlist': '#contactListButton', |
||||
'#settingsmenu': '#settingsButton' |
||||
}; |
||||
|
||||
/** |
||||
* Resizes the video area |
||||
* @param isClosing whether the side panel is going to be closed or is going to open / remain opened |
||||
* @param completeFunction a function to be called when the video space is resized |
||||
*/ |
||||
var resizeVideoArea = function(isClosing, completeFunction) { |
||||
var videospace = $('#videospace'); |
||||
|
||||
var panelSize = isClosing ? [0, 0] : PanelToggler.getPanelSize(); |
||||
var videospaceWidth = window.innerWidth - panelSize[0]; |
||||
var videospaceHeight = window.innerHeight; |
||||
var videoSize |
||||
= getVideoSize(null, null, videospaceWidth, videospaceHeight); |
||||
var videoWidth = videoSize[0]; |
||||
var videoHeight = videoSize[1]; |
||||
var videoPosition = getVideoPosition(videoWidth, |
||||
videoHeight, |
||||
videospaceWidth, |
||||
videospaceHeight); |
||||
var horizontalIndent = videoPosition[0]; |
||||
var verticalIndent = videoPosition[1]; |
||||
|
||||
var thumbnailSize = VideoLayout.calculateThumbnailSize(videospaceWidth); |
||||
var thumbnailsWidth = thumbnailSize[0]; |
||||
var thumbnailsHeight = thumbnailSize[1]; |
||||
//for chat
|
||||
|
||||
videospace.animate({ |
||||
right: panelSize[0], |
||||
width: videospaceWidth, |
||||
height: videospaceHeight |
||||
}, |
||||
{ |
||||
queue: false, |
||||
duration: 500, |
||||
complete: completeFunction |
||||
}); |
||||
|
||||
$('#remoteVideos').animate({ |
||||
height: thumbnailsHeight |
||||
}, |
||||
{ |
||||
queue: false, |
||||
duration: 500 |
||||
}); |
||||
|
||||
$('#remoteVideos>span').animate({ |
||||
height: thumbnailsHeight, |
||||
width: thumbnailsWidth |
||||
}, |
||||
{ |
||||
queue: false, |
||||
duration: 500, |
||||
complete: function () { |
||||
$(document).trigger( |
||||
"remotevideo.resized", |
||||
[thumbnailsWidth, |
||||
thumbnailsHeight]); |
||||
} |
||||
}); |
||||
|
||||
$('#largeVideoContainer').animate({ |
||||
width: videospaceWidth, |
||||
height: videospaceHeight |
||||
}, |
||||
{ |
||||
queue: false, |
||||
duration: 500 |
||||
}); |
||||
|
||||
$('#largeVideo').animate({ |
||||
width: videoWidth, |
||||
height: videoHeight, |
||||
top: verticalIndent, |
||||
bottom: verticalIndent, |
||||
left: horizontalIndent, |
||||
right: horizontalIndent |
||||
}, |
||||
{ |
||||
queue: false, |
||||
duration: 500 |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* Toggles the windows in the side panel |
||||
* @param object the window that should be shown |
||||
* @param selector the selector for the element containing the panel |
||||
* @param onOpenComplete function to be called when the panel is opened |
||||
* @param onOpen function to be called if the window is going to be opened |
||||
* @param onClose function to be called if the window is going to be closed |
||||
*/ |
||||
var toggle = function(object, selector, onOpenComplete, onOpen, onClose) { |
||||
buttonClick(buttons[selector], "active"); |
||||
|
||||
if (object.isVisible()) { |
||||
$("#toast-container").animate({ |
||||
right: '5px' |
||||
}, |
||||
{ |
||||
queue: false, |
||||
duration: 500 |
||||
}); |
||||
$(selector).hide("slide", { |
||||
direction: "right", |
||||
queue: false, |
||||
duration: 500 |
||||
}); |
||||
if(typeof onClose === "function") { |
||||
onClose(); |
||||
} |
||||
|
||||
currentlyOpen = null; |
||||
} |
||||
else { |
||||
// Undock the toolbar when the chat is shown and if we're in a
|
||||
// video mode.
|
||||
if (VideoLayout.isLargeVideoVisible()) { |
||||
ToolbarToggler.dockToolbar(false); |
||||
} |
||||
|
||||
if(currentlyOpen) { |
||||
var current = $(currentlyOpen); |
||||
buttonClick(buttons[currentlyOpen], "active"); |
||||
current.css('z-index', 4); |
||||
setTimeout(function () { |
||||
current.css('display', 'none'); |
||||
current.css('z-index', 5); |
||||
}, 500); |
||||
} |
||||
|
||||
$("#toast-container").animate({ |
||||
right: (PanelToggler.getPanelSize()[0] + 5) + 'px' |
||||
}, |
||||
{ |
||||
queue: false, |
||||
duration: 500 |
||||
}); |
||||
$(selector).show("slide", { |
||||
direction: "right", |
||||
queue: false, |
||||
duration: 500, |
||||
complete: onOpenComplete |
||||
}); |
||||
if(typeof onOpen === "function") { |
||||
onOpen(); |
||||
} |
||||
|
||||
currentlyOpen = selector; |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* Opens / closes the chat area. |
||||
*/ |
||||
my.toggleChat = function() { |
||||
var chatCompleteFunction = Chat.isVisible() ? |
||||
function() {} : function () { |
||||
Chat.scrollChatToBottom(); |
||||
$('#chatspace').trigger('shown'); |
||||
}; |
||||
|
||||
resizeVideoArea(Chat.isVisible(), chatCompleteFunction); |
||||
|
||||
toggle(Chat, |
||||
'#chatspace', |
||||
function () { |
||||
// Request the focus in the nickname field or the chat input field.
|
||||
if ($('#nickname').css('visibility') === 'visible') { |
||||
$('#nickinput').focus(); |
||||
} else { |
||||
$('#usermsg').focus(); |
||||
} |
||||
}, |
||||
null, |
||||
Chat.resizeChat, |
||||
null); |
||||
}; |
||||
|
||||
/** |
||||
* Opens / closes the contact list area. |
||||
*/ |
||||
my.toggleContactList = function () { |
||||
var completeFunction = ContactList.isVisible() ? |
||||
function() {} : function () { $('#contactlist').trigger('shown');}; |
||||
resizeVideoArea(ContactList.isVisible(), completeFunction); |
||||
|
||||
toggle(ContactList, |
||||
'#contactlist', |
||||
null, |
||||
function() { |
||||
ContactList.setVisualNotification(false); |
||||
}, |
||||
null); |
||||
}; |
||||
|
||||
/** |
||||
* Opens / closes the settings menu |
||||
*/ |
||||
my.toggleSettingsMenu = function() { |
||||
resizeVideoArea(SettingsMenu.isVisible(), function (){}); |
||||
toggle(SettingsMenu, |
||||
'#settingsmenu', |
||||
null, |
||||
function() { |
||||
$('#setDisplayName').get(0).value = SettingsMenu.getDisplayName(); |
||||
$('#setEmail').get(0).value = SettingsMenu.getEmail(); |
||||
}, |
||||
null); |
||||
}; |
||||
|
||||
/** |
||||
* Returns the size of the side panel. |
||||
*/ |
||||
my.getPanelSize = function () { |
||||
var availableHeight = window.innerHeight; |
||||
var availableWidth = window.innerWidth; |
||||
|
||||
var panelWidth = 200; |
||||
if (availableWidth * 0.2 < 200) { |
||||
panelWidth = availableWidth * 0.2; |
||||
} |
||||
|
||||
return [panelWidth, availableHeight]; |
||||
}; |
||||
|
||||
my.isVisible = function() { |
||||
return (Chat.isVisible() || ContactList.isVisible() || SettingsMenu.isVisible()); |
||||
}; |
||||
|
||||
return my; |
||||
|
||||
}(PanelToggler || {})); |
Loading…
Reference in new issue