mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-01-07 07:12:28 +00:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12344ab486 | ||
|
|
b6e18d8a68 | ||
|
|
1a0677cb59 | ||
|
|
c483587853 | ||
|
|
9b25467080 | ||
|
|
f37fd15fca | ||
|
|
5092f52716 | ||
|
|
0013745783 | ||
|
|
ad5fa13339 | ||
|
|
e1fa5ecb34 | ||
|
|
e1512e3776 | ||
|
|
dab5252746 | ||
|
|
d8dd564b06 | ||
|
|
407b082780 | ||
|
|
a671093489 | ||
|
|
29f0c0b311 | ||
|
|
955680018f | ||
|
|
686e85cd4f | ||
|
|
297d4e65fc | ||
|
|
0e94bf7e0b | ||
|
|
a5bc9625ef | ||
|
|
cbde4f89b2 | ||
|
|
891c108191 | ||
|
|
764d767789 | ||
|
|
7ded10cd8d | ||
|
|
3b05a16b32 | ||
|
|
cf49c8c6ff | ||
|
|
99bf4bc44d | ||
|
|
929639b06b | ||
|
|
4c72833f5a | ||
|
|
e3eaac5bef |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,3 +9,4 @@ all.css
|
||||
*css.map
|
||||
unsupported_browser.css
|
||||
.remote-sync.json
|
||||
.sync-config.cson
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 0.75em;
|
||||
line-height: 1.22em;
|
||||
font-size: 1.22em;
|
||||
|
||||
/* Better Font Rendering =========== */
|
||||
@@ -84,6 +84,9 @@
|
||||
.icon-mic-disabled:before {
|
||||
content: "\e912";
|
||||
}
|
||||
.icon-raised-hand:before {
|
||||
content: "\e91e";
|
||||
}
|
||||
.icon-contactList:before {
|
||||
content: "\e91b";
|
||||
}
|
||||
|
||||
@@ -36,6 +36,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
@mixin circle($diameter) {
|
||||
width: $diameter;
|
||||
height: $diameter;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@mixin absoluteAligning($sizeX, $sizeY) {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
@include transform(translate(-#{$sizeX / 2}, -#{$sizeY / 2}))
|
||||
}
|
||||
|
||||
@mixin transform($func) {
|
||||
-moz-transform: $func;
|
||||
-ms-transform: $func;
|
||||
|
||||
@@ -56,11 +56,11 @@
|
||||
}
|
||||
|
||||
#extendedToolbar {
|
||||
display: flex;
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
width: $defaultToolbarSize;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/**
|
||||
<<<<<<< HEAD
|
||||
* Style variables
|
||||
*/
|
||||
$baseFontFamily: 'open_sanslight', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
@@ -11,6 +10,11 @@ $hangupFontSize: 2em;
|
||||
*/
|
||||
$defaultToolbarSize: 50px;
|
||||
|
||||
// Video layout.
|
||||
$thumbnailIndicatorSize: 23px;
|
||||
$thumbnailIndicatorBorder: 0px;
|
||||
$thumbnailVideoMargin: 2px;
|
||||
|
||||
/**
|
||||
* Color variables.
|
||||
*/
|
||||
@@ -18,13 +22,29 @@ $defaultColor: #F1F1F1;
|
||||
$defaultSemiDarkColor: #ACACAC;
|
||||
$defaultDarkColor: #4F4F4F;
|
||||
$defaultBackground: #474747;
|
||||
|
||||
// Toolbar
|
||||
$toolbarSelectBackground: rgba(0, 0, 0, .6);
|
||||
|
||||
// Main controls
|
||||
$inputBackground: rgba(132, 132, 132, .5);
|
||||
$inputSemiBackground: rgba(132, 132, 132, .8);
|
||||
$inputLightBackground: #EBEBEB;
|
||||
$inputBorderColor: #EBEBEB;
|
||||
$buttonBackground: #44A5FF;
|
||||
|
||||
// Video layout.
|
||||
$videoThumbnailHovered: #44A5FF;
|
||||
$videoThumbnailSelected: #165ecc;
|
||||
$participantNameColor: #fff;
|
||||
$thumbnailPictogramColor: #fff;
|
||||
$dominantSpeakerBg: #165ecc;
|
||||
$raiseHandBg: #D6D61E;
|
||||
|
||||
$rateStarDefault: #ccc;
|
||||
$rateStarActivity: #165ecc;
|
||||
$rateStarLabelColor: #333;
|
||||
|
||||
/**
|
||||
* Misc.
|
||||
*/
|
||||
@@ -35,8 +55,4 @@ $defaultWatermarkLink: '../images/watermark.png';
|
||||
* Z-indexes. TODO: Replace this by a function.
|
||||
*/
|
||||
$toolbarZ: 900;
|
||||
$overlayZ: 800;
|
||||
|
||||
$rateStarDefault: #ccc;
|
||||
$rateStarActivity: #f6c342;
|
||||
$rateStarLabelColor: #333;
|
||||
$overlayZ: 800;
|
||||
@@ -13,17 +13,17 @@
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-direction: row-reverse;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-end;
|
||||
justify-content: flex-start;
|
||||
|
||||
position:absolute;
|
||||
text-align:right;
|
||||
height:196px;
|
||||
padding: 18px;
|
||||
padding: 10px 10px 10px 5px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 20px;
|
||||
right: 0;
|
||||
width:auto;
|
||||
border:1px solid transparent;
|
||||
z-index: 5;
|
||||
@@ -43,10 +43,23 @@
|
||||
|
||||
#remoteVideos .videocontainer {
|
||||
display: none;
|
||||
position: relative;
|
||||
background-color: black;
|
||||
background-size: contain;
|
||||
border-radius:1px;
|
||||
border: 1px solid #212425;
|
||||
margin: 0 $thumbnailVideoMargin;
|
||||
border: 1px solid $defaultDarkColor;
|
||||
}
|
||||
|
||||
.videocontainer__toolbar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 25px;
|
||||
max-height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
#remoteVideos .videocontainer.videoContainerFocused {
|
||||
@@ -58,18 +71,13 @@
|
||||
-webkit-animation-iteration-count: 1;
|
||||
}
|
||||
|
||||
#remoteVideos .videocontainer:hover {
|
||||
border: 1px solid #c1c1c1;
|
||||
}
|
||||
|
||||
#remoteVideos .videocontainer.videoContainerFocused {
|
||||
box-shadow: inset 0 0 28px #006d91;
|
||||
border: 1px solid #006d91;
|
||||
border: 1px solid $videoThumbnailSelected;
|
||||
}
|
||||
|
||||
#remoteVideos .videocontainer:hover,
|
||||
#remoteVideos .videocontainer.videoContainerFocused:hover {
|
||||
box-shadow: inset 0 0 5px #c1c1c1, 0 0 10px #c1c1c1, inset 0 0 60px #006d91;
|
||||
border: 1px solid #c1c1c1;
|
||||
border: 1px solid $videoThumbnailHovered;
|
||||
}
|
||||
|
||||
#localVideoWrapper {
|
||||
@@ -145,11 +153,11 @@
|
||||
#remoteVideos .videocontainer>div.remotevideomenu {
|
||||
position: absolute;
|
||||
color: #FFFFFF;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 5px 0px;
|
||||
width: 25px;
|
||||
font-size: 11pt;
|
||||
font-size: 9pt;
|
||||
text-shadow: 0px 1px 0px rgba(255,255,255,.3), 0px -1px 0px rgba(0,0,0,.7);
|
||||
border: 0px;
|
||||
z-index: 2;
|
||||
@@ -166,22 +174,28 @@
|
||||
|
||||
.videocontainer>span.displayname,
|
||||
.videocontainer>input.displayname {
|
||||
display: none;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
color: #FFFFFF;
|
||||
background: rgba(0,0,0,.7);
|
||||
bottom: 4px;
|
||||
left: 25%;
|
||||
color: $participantNameColor;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
width: 70%;
|
||||
height: 20%;
|
||||
left: 15%;
|
||||
top: 40%;
|
||||
padding: 5px;
|
||||
font-size: 11pt;
|
||||
width: 50%;
|
||||
font-size: 12px;
|
||||
font-weight: 100;
|
||||
letter-spacing: 1px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
z-index: 2;
|
||||
border-radius:3px;
|
||||
}
|
||||
|
||||
.videocontainer>input.displayname {
|
||||
outline: none;
|
||||
border: none;
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.videocontainer>span.status {
|
||||
@@ -291,7 +305,8 @@
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
color: #FFFFFF;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 8px 5px;
|
||||
width: 25px;
|
||||
font-size: 8pt;
|
||||
@@ -305,8 +320,7 @@
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
color: #FFFFFF;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 8px 5px;
|
||||
width: 25px;
|
||||
font-size: 8pt;
|
||||
@@ -316,24 +330,30 @@
|
||||
}
|
||||
|
||||
.videocontainer>span.indicator {
|
||||
bottom: 0px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
@include circle($thumbnailIndicatorSize);
|
||||
box-sizing: border-box;
|
||||
line-height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
|
||||
z-index: 3;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
background: #21B9FC;
|
||||
margin: 5px;
|
||||
background: $dominantSpeakerBg;
|
||||
margin: 7px;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
color: #FFFFFF;
|
||||
font-size: 11pt;
|
||||
border: 0px;
|
||||
color: $thumbnailPictogramColor;
|
||||
font-size: 8pt;
|
||||
border: $thumbnailIndicatorBorder solid $thumbnailPictogramColor;
|
||||
}
|
||||
|
||||
.videocontainer>#raisehandindicator {
|
||||
background: $raiseHandBg;
|
||||
}
|
||||
|
||||
#indicatoricon {
|
||||
padding-top: 5px;
|
||||
width: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
|
||||
height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
|
||||
line-height: $thumbnailIndicatorSize - 2*$thumbnailIndicatorBorder;
|
||||
}
|
||||
|
||||
#reloadPresentation {
|
||||
@@ -395,10 +415,8 @@
|
||||
}
|
||||
|
||||
.userAvatar {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
border-radius: 2px;
|
||||
@include circle(60px);
|
||||
@include absoluteAligning(60px, 60px);
|
||||
}
|
||||
|
||||
.sharedVideoAvatar {
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
background: linear-gradient(transparent, #000);
|
||||
opacity: 0.8;
|
||||
|
||||
&.solidBG {
|
||||
background: $defaultBackground;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&__content {
|
||||
position: absolute;
|
||||
width: 400px;
|
||||
@@ -33,4 +38,4 @@
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
fonts/jitsi.eot
BIN
fonts/jitsi.eot
Binary file not shown.
@@ -41,4 +41,5 @@
|
||||
<glyph unicode="" glyph-name="contactList" d="M704 746c-46 0-86-38-86-84s40-86 86-86 86 40 86 86-40 84-86 84zM704 512c-82 0-150 68-150 150s68 148 150 148 150-66 150-148-68-150-150-150zM320 746c-46 0-86-38-86-84s40-86 86-86 86 40 86 86-40 84-86 84zM320 512c-82 0-150 68-150 150s68 148 150 148 150-66 150-148-68-150-150-150zM918 278v52c0 24-110 76-214 76-46 0-90-12-128-24 14-16 22-32 22-52v-52h320zM534 278v52c0 24-110 76-214 76s-214-52-214-76v-52h428zM704 470c92 0 278-48 278-140v-116h-940v116c0 92 186 140 278 140 52 0 130-16 192-44 62 28 140 44 192 44z" />
|
||||
<glyph unicode="" glyph-name="toggle-filmstrip" d="M896 896h-768c-46.933 0-85.333-38.4-85.333-85.333v-597.333c0-46.933 38.4-85.333 85.333-85.333h768c46.933 0 85.333 38.4 85.333 85.333v597.333c0 46.933-38.4 85.333-85.333 85.333zM896 213.333h-768v128h768v-128z" />
|
||||
<glyph unicode="" glyph-name="feedback" d="M42.667 128h170.667v512h-170.667v-512zM981.333 597.333c0 46.933-38.4 85.333-85.333 85.333h-269.227l40.533 194.987 1.28 13.653c0 17.493-7.253 33.707-18.773 45.227l-45.227 44.8-280.747-281.173c-15.787-15.36-25.173-36.693-25.173-60.16v-426.667c0-46.933 38.4-85.333 85.333-85.333h384c35.413 0 65.707 21.333 78.507 52.053l128.853 300.8c3.84 9.813 5.973 20.053 5.973 31.147v81.493l-0.427 0.427 0.427 3.413z" />
|
||||
<glyph unicode="" glyph-name="raised-hand" d="M982 790v-620c0-94-78-170-172-170h-310c-46 0-90 18-122 50l-336 342s54 52 56 52c10 8 22 12 34 12 10 0 18-2 26-6 2 0 184-104 184-104v508c0 36 28 64 64 64s64-28 64-64v-300h42v406c0 36 28 64 64 64s64-28 64-64v-406h42v364c0 36 28 64 64 64s64-28 64-64v-364h44v236c0 36 28 64 64 64s64-28 64-64z" />
|
||||
</font></defs></svg>
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
BIN
fonts/jitsi.ttf
BIN
fonts/jitsi.ttf
Binary file not shown.
BIN
fonts/jitsi.woff
BIN
fonts/jitsi.woff
Binary file not shown.
@@ -69,8 +69,10 @@
|
||||
"tags": [
|
||||
"account_circle"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 11,
|
||||
"order": 60,
|
||||
@@ -93,8 +95,10 @@
|
||||
"tags": [
|
||||
"autorenew"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 68,
|
||||
"order": 84,
|
||||
@@ -117,8 +121,10 @@
|
||||
"tags": [
|
||||
"call_end"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 122,
|
||||
"order": 63,
|
||||
@@ -141,8 +147,10 @@
|
||||
"tags": [
|
||||
"chat_bubble_outline"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 148,
|
||||
"order": 61,
|
||||
@@ -165,8 +173,10 @@
|
||||
"tags": [
|
||||
"cloud_download"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 164,
|
||||
"order": 99,
|
||||
@@ -189,8 +199,10 @@
|
||||
"tags": [
|
||||
"mode_edit"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 185,
|
||||
"order": 89,
|
||||
@@ -213,8 +225,10 @@
|
||||
"tags": [
|
||||
"description"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 206,
|
||||
"order": 85,
|
||||
@@ -237,8 +251,10 @@
|
||||
"tags": [
|
||||
"dialer_sip"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 215,
|
||||
"order": 95,
|
||||
@@ -261,8 +277,10 @@
|
||||
"tags": [
|
||||
"eject"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 242,
|
||||
"order": 98,
|
||||
@@ -285,8 +303,10 @@
|
||||
"tags": [
|
||||
"fullscreen"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 350,
|
||||
"order": 94,
|
||||
@@ -309,8 +329,10 @@
|
||||
"tags": [
|
||||
"fullscreen_exit"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 351,
|
||||
"order": 92,
|
||||
@@ -333,8 +355,10 @@
|
||||
"tags": [
|
||||
"star"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 363,
|
||||
"order": 101,
|
||||
@@ -357,8 +381,10 @@
|
||||
"tags": [
|
||||
"lock_open"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 473,
|
||||
"order": 66,
|
||||
@@ -381,8 +407,10 @@
|
||||
"tags": [
|
||||
"lock_outline"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 474,
|
||||
"order": 65,
|
||||
@@ -405,8 +433,10 @@
|
||||
"tags": [
|
||||
"sync"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 482,
|
||||
"order": 67,
|
||||
@@ -429,8 +459,10 @@
|
||||
"tags": [
|
||||
"mic"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 492,
|
||||
"order": 68,
|
||||
@@ -453,8 +485,10 @@
|
||||
"tags": [
|
||||
"mic_none"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 493,
|
||||
"order": 69,
|
||||
@@ -477,8 +511,10 @@
|
||||
"tags": [
|
||||
"mic_off"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 494,
|
||||
"order": 70,
|
||||
@@ -491,6 +527,32 @@
|
||||
"setId": 2,
|
||||
"iconIdx": 495
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
"paths": [
|
||||
"M982 234v620c0 94-78 170-172 170h-310c-46 0-90-18-122-50l-336-342s54-52 56-52c10-8 22-12 34-12 10 0 18 2 26 6 2 0 184 104 184 104v-508c0-36 28-64 64-64s64 28 64 64v300h42v-406c0-36 28-64 64-64s64 28 64 64v406h42v-364c0-36 28-64 64-64s64 28 64 64v364h44v-236c0-36 28-64 64-64s64 28 64 64z"
|
||||
],
|
||||
"isMulticolor": false,
|
||||
"isMulticolor2": false,
|
||||
"tags": [
|
||||
"pan_tool"
|
||||
],
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 539,
|
||||
"order": 105,
|
||||
"ligatures": "pan_tool",
|
||||
"prevSize": 32,
|
||||
"code": 59678,
|
||||
"name": "raised-hand"
|
||||
},
|
||||
"setIdx": 0,
|
||||
"setId": 2,
|
||||
"iconIdx": 540
|
||||
},
|
||||
{
|
||||
"icon": {
|
||||
"paths": [
|
||||
@@ -501,8 +563,10 @@
|
||||
"tags": [
|
||||
"people_outline"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 549,
|
||||
"order": 100,
|
||||
@@ -525,8 +589,10 @@
|
||||
"tags": [
|
||||
"person_add"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 559,
|
||||
"order": 87,
|
||||
@@ -549,8 +615,10 @@
|
||||
"tags": [
|
||||
"play_circle_outline"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 590,
|
||||
"order": 82,
|
||||
@@ -573,8 +641,10 @@
|
||||
"tags": [
|
||||
"settings"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 665,
|
||||
"order": 81,
|
||||
@@ -597,8 +667,10 @@
|
||||
"tags": [
|
||||
"star_border"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 717,
|
||||
"order": 76,
|
||||
@@ -621,8 +693,10 @@
|
||||
"tags": [
|
||||
"tv"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 783,
|
||||
"order": 93,
|
||||
@@ -645,8 +719,10 @@
|
||||
"tags": [
|
||||
"videocam"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 798,
|
||||
"order": 77,
|
||||
@@ -669,8 +745,10 @@
|
||||
"tags": [
|
||||
"videocam_off"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 799,
|
||||
"order": 78,
|
||||
@@ -693,8 +771,10 @@
|
||||
"tags": [
|
||||
"volume_up"
|
||||
],
|
||||
"grid": 0
|
||||
"grid": 0,
|
||||
"attrs": []
|
||||
},
|
||||
"attrs": [],
|
||||
"properties": {
|
||||
"id": 821,
|
||||
"order": 79,
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
<a class="button icon-contactList" id="toolbar_contact_list" data-container="body" data-toggle="popover" data-placement="right" shortcut="contactlistpopover" data-i18n="[content]bottomtoolbar.contactlist" content="Open / close contact list">
|
||||
<span id="numberOfParticipants"></span>
|
||||
</a>
|
||||
<!--a class="button icon-link" id="toolbar_button_link" data-container="body" data-toggle="popover" data-placement="right" data-i18n="[content]toolbar.invite" content="Invite others"></a-->
|
||||
<a class="button icon-chat" id="toolbar_button_chat" data-container="body" data-toggle="popover" shortcut="toggleChatPopover" data-placement="right" data-i18n="[content]toolbar.chat" content="Open / close chat">
|
||||
<span id="unreadMessages"></span>
|
||||
</a>
|
||||
@@ -137,6 +138,7 @@
|
||||
<a class="button icon-telephone" id="toolbar_button_sip" data-container="body" data-toggle="popover" data-placement="right" content="Call SIP number" data-i18n="[content]toolbar.sip" style="display: none"></a>
|
||||
<a class="button icon-dialpad" id="toolbar_button_dialpad" data-container="body" data-toggle="popover" data-placement="right" content="Open dialpad" data-i18n="[content]toolbar.dialpad" style="display: none"></a>
|
||||
<a class="button icon-settings" id="toolbar_button_settings" data-container="body" data-toggle="popover" data-placement="right" content="Settings" data-i18n="[content]toolbar.Settings"></a>
|
||||
<a class="button icon-raised-hand" id="toolbar_button_raisehand" data-container="body" data-toggle="popover" data-placement="right" data-i18n="[content]toolbar.raiseHand" content="Raise Hand" shortcut="raiseHandPopover"></a>
|
||||
<a class="button icon-full-screen" id="toolbar_button_fullScreen" data-container="body" data-toggle="popover" data-placement="right" shortcut="toggleFullscreenPopover" data-i18n="[content]toolbar.fullscreen" content="Enter / Exit Full Screen"></a>
|
||||
<a class="button icon-toggle-filmstrip" id="toolbar_film_strip" data-container="body" data-toggle="popover" shortcut="filmstripPopover" data-placement="right" data-i18n="[content]toolbar.filmstrip" content="Show / hide videos"></a>
|
||||
<a class="button icon-feedback" id="feedbackButton" data-container="body" data-toggle="popover" data-placement="right" data-i18n="[content]feedback"></a>
|
||||
@@ -236,12 +238,13 @@
|
||||
</div>
|
||||
|
||||
<div id="remoteVideos">
|
||||
<span id="localVideoContainer" class="videocontainer">
|
||||
<span id="localVideoContainer" class="videocontainer videocontainer_small">
|
||||
<span id="localVideoWrapper">
|
||||
<!--<video id="localVideo" autoplay muted></video> - is now per stream generated -->
|
||||
</span>
|
||||
<audio id="localAudio" autoplay muted></audio>
|
||||
<span class="focusindicator"></span>
|
||||
<div class="videocontainer__toolbar"></div>
|
||||
</span>
|
||||
<audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
|
||||
<audio id="userLeft" src="sounds/left.wav" preload="auto"></audio>
|
||||
|
||||
@@ -20,18 +20,23 @@ var interfaceConfig = {
|
||||
// the toolbar buttons line is intentionally left in one line, to be able
|
||||
// to easily override values or remove them using regex
|
||||
MAIN_TOOLBAR_BUTTONS: ['microphone', 'camera', 'desktop', 'invite', 'hangup'], // jshint ignore:line
|
||||
TOOLBAR_BUTTONS: ['profile', 'authentication', 'microphone', 'camera', 'desktop', 'recording', 'security', 'invite', 'chat', 'etherpad', 'sharedvideo', 'fullscreen', 'sip', 'dialpad', 'settings', 'hangup', 'filmstrip', 'contacts'], // jshint ignore:line
|
||||
TOOLBAR_BUTTONS: ['profile', 'authentication', 'microphone', 'camera', 'desktop', 'recording', 'security', 'raisehand', 'chat', 'etherpad', 'sharedvideo', 'fullscreen', 'sip', 'dialpad', 'settings', 'hangup', 'filmstrip', 'contacts'], // jshint ignore:line
|
||||
SETTINGS_SECTIONS: ['language', 'devices', 'moderator'],
|
||||
// Determines how the video would fit the screen. 'both' would fit the whole
|
||||
// screen, 'height' would fit the original video height to the height of the
|
||||
// screen, 'width' would fit the original video width to the width of the
|
||||
// screen respecting ratio.
|
||||
VIDEO_LAYOUT_FIT: 'both',
|
||||
SHOW_CONTACTLIST_AVATARS: false,
|
||||
/**
|
||||
* Whether to only show the filmstrip (and hide the toolbar).
|
||||
*/
|
||||
filmStripOnly: false,
|
||||
RANDOM_AVATAR_URL_PREFIX: false,
|
||||
RANDOM_AVATAR_URL_SUFFIX: false,
|
||||
FILM_STRIP_MAX_HEIGHT: 120
|
||||
};
|
||||
FILM_STRIP_MAX_HEIGHT: 120,
|
||||
LOCAL_THUMBNAIL_RATIO_WIDTH: 16,
|
||||
LOCAL_THUMBNAIL_RATIO_HEIGHT: 9,
|
||||
REMOTE_THUMBNAIL_RATIO_WIDTH: 1,
|
||||
REMOTE_THUMBNAIL_RATIO_HEIGHT: 1
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"downloadlogs": "Download logs",
|
||||
"feedback": "Give us your feedback",
|
||||
"roomUrlDefaultMsg": "Your conference is currently being created...",
|
||||
"participant": "Participant",
|
||||
"me": "me",
|
||||
"speaker": "Speaker",
|
||||
"raisedHand": "Would like to speak",
|
||||
@@ -94,7 +93,8 @@
|
||||
"unableToUnmutePopup": "You cannot un-mute while the shared video is on.",
|
||||
"cameraDisabled": "Camera is not available",
|
||||
"micDisabled": "Microphone is not available",
|
||||
"filmstrip": "Show / hide videos"
|
||||
"filmstrip": "Show / hide videos",
|
||||
"raiseHand": "Raise hand to speak"
|
||||
},
|
||||
"bottomtoolbar": {
|
||||
"chat": "Open / close chat",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* global $, APP, config, interfaceConfig, JitsiMeetJS */
|
||||
import UIEvents from "../../service/UI/UIEvents";
|
||||
import UIUtil from "./util/UIUtil";
|
||||
|
||||
/**
|
||||
* Constructs the html for the overall feedback window.
|
||||
|
||||
@@ -292,7 +292,7 @@ UI.initConference = function () {
|
||||
}
|
||||
|
||||
// Add myself to the contact list.
|
||||
ContactList.addContact(id);
|
||||
ContactList.addContact(id, true);
|
||||
|
||||
//update default button states before showing the toolbar
|
||||
//if local role changes buttons state will be again updated
|
||||
|
||||
@@ -10,7 +10,7 @@ let ASDrawContext = null;
|
||||
let audioLevelCanvasCache = {};
|
||||
let dominantSpeakerAudioElement = null;
|
||||
|
||||
function initDominantSpeakerAudioLevels(dominantSpeakerAvatarSize) {
|
||||
function _initDominantSpeakerAudioLevels(dominantSpeakerAvatarSize) {
|
||||
let ASRadius = dominantSpeakerAvatarSize / 2;
|
||||
let ASCenter = (dominantSpeakerAvatarSize + ASRadius) / 2;
|
||||
|
||||
@@ -28,7 +28,9 @@ function initDominantSpeakerAudioLevels(dominantSpeakerAvatarSize) {
|
||||
/**
|
||||
* Resizes the given audio level canvas to match the given thumbnail size.
|
||||
*/
|
||||
function resizeAudioLevelCanvas(audioLevelCanvas, thumbnailWidth, thumbnailHeight) {
|
||||
function _resizeAudioLevelCanvas( audioLevelCanvas,
|
||||
thumbnailWidth,
|
||||
thumbnailHeight) {
|
||||
audioLevelCanvas.width = thumbnailWidth + interfaceConfig.CANVAS_EXTRA;
|
||||
audioLevelCanvas.height = thumbnailHeight + interfaceConfig.CANVAS_EXTRA;
|
||||
}
|
||||
@@ -138,18 +140,18 @@ const AudioLevels = {
|
||||
dominantSpeakerAudioElement.height = dominantSpeakerHeight;
|
||||
|
||||
let dominantSpeakerAvatar = $("#dominantSpeakerAvatar");
|
||||
initDominantSpeakerAudioLevels(dominantSpeakerAvatar.width());
|
||||
_initDominantSpeakerAudioLevels(dominantSpeakerAvatar.width());
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the audio level canvas for the given id. If the canvas
|
||||
* didn't exist we create it.
|
||||
*/
|
||||
updateAudioLevelCanvas (id, thumbWidth, thumbHeight) {
|
||||
let videoSpanId = 'localVideoContainer';
|
||||
if (id) {
|
||||
videoSpanId = `participant_${id}`;
|
||||
}
|
||||
createAudioLevelCanvas (id, thumbWidth, thumbHeight) {
|
||||
|
||||
let videoSpanId = (id === "local")
|
||||
? "localVideoContainer"
|
||||
: `participant_${id}`;
|
||||
|
||||
let videoSpan = document.getElementById(videoSpanId);
|
||||
|
||||
@@ -172,13 +174,13 @@ const AudioLevels = {
|
||||
= `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
||||
audioLevelCanvas.style.left
|
||||
= `-${interfaceConfig.CANVAS_EXTRA/2}px`;
|
||||
resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
||||
_resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
||||
|
||||
videoSpan.appendChild(audioLevelCanvas);
|
||||
} else {
|
||||
audioLevelCanvas = audioLevelCanvas.get(0);
|
||||
|
||||
resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
||||
_resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -242,19 +244,29 @@ const AudioLevels = {
|
||||
ASDrawContext.fill();
|
||||
},
|
||||
|
||||
updateCanvasSize (thumbWidth, thumbHeight) {
|
||||
let canvasWidth = thumbWidth + interfaceConfig.CANVAS_EXTRA;
|
||||
let canvasHeight = thumbHeight + interfaceConfig.CANVAS_EXTRA;
|
||||
updateCanvasSize (localVideo, remoteVideo) {
|
||||
let localCanvasWidth
|
||||
= localVideo.thumbWidth + interfaceConfig.CANVAS_EXTRA;
|
||||
let localCanvasHeight
|
||||
= localVideo.thumbHeight + interfaceConfig.CANVAS_EXTRA;
|
||||
let remoteCanvasWidth
|
||||
= remoteVideo.thumbWidth + interfaceConfig.CANVAS_EXTRA;
|
||||
let remoteCanvasHeight
|
||||
= remoteVideo.thumbHeight + interfaceConfig.CANVAS_EXTRA;
|
||||
|
||||
FilmStrip.getThumbs().children('canvas').each(function () {
|
||||
$(this).attr('width', canvasWidth);
|
||||
$(this).attr('height', canvasHeight);
|
||||
let { remoteThumbs, localThumb } = FilmStrip.getThumbs();
|
||||
|
||||
remoteThumbs.children('canvas').each(function () {
|
||||
$(this).attr('width', remoteCanvasWidth);
|
||||
$(this).attr('height', remoteCanvasHeight);
|
||||
});
|
||||
|
||||
Object.keys(audioLevelCanvasCache).forEach(function (id) {
|
||||
audioLevelCanvasCache[id].width = canvasWidth;
|
||||
audioLevelCanvasCache[id].height = canvasHeight;
|
||||
});
|
||||
if(localThumb) {
|
||||
localThumb.children('canvas').each(function () {
|
||||
$(this).attr('width', localCanvasWidth);
|
||||
$(this).attr('height', localCanvasHeight);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
/* global $ */
|
||||
/* global $, APP */
|
||||
/* jshint -W101 */
|
||||
import UIEvents from "../../../service/UI/UIEvents";
|
||||
|
||||
/**
|
||||
* Store the current ring overlay instance.
|
||||
* Note: We want to have only 1 instance at a time.
|
||||
*/
|
||||
let overlay = null;
|
||||
|
||||
/**
|
||||
* Handler for UIEvents.LARGE_VIDEO_AVATAR_DISPLAYED event.
|
||||
* @param {boolean} shown indicates whether the avatar on the large video is
|
||||
* currently displayed or not.
|
||||
*/
|
||||
function onAvatarDisplayed(shown) {
|
||||
overlay._changeBackground(shown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows ring overlay
|
||||
@@ -11,25 +27,46 @@ class RingOverlay {
|
||||
constructor(callee) {
|
||||
this._containerId = 'ringOverlay';
|
||||
this._audioContainerId = 'ringOverlayRinging';
|
||||
|
||||
this.isRinging = true;
|
||||
this.callee = callee;
|
||||
this.render();
|
||||
this.audio = document.getElementById(this._audioContainerId);
|
||||
this.audio.play();
|
||||
this._setAudioTimeout();
|
||||
this._timeout = setTimeout(() => {
|
||||
this.destroy();
|
||||
this.render();
|
||||
}, 30000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Chagnes the background of the ring overlay.
|
||||
* @param {boolean} solid - if true the new background will be the solid
|
||||
* one, otherwise the background will be default one.
|
||||
* NOTE: The method just toggles solidBG css class.
|
||||
*/
|
||||
_changeBackground(solid) {
|
||||
const container = $("#" + this._containerId);
|
||||
if(solid) {
|
||||
container.addClass("solidBG");
|
||||
} else {
|
||||
container.removeClass("solidBG");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and appends the ring overlay to the html document
|
||||
*/
|
||||
_getHtmlStr(callee) {
|
||||
let callingLabel = this.isRinging? "<p>Calling...</p>" : "";
|
||||
let callerStateLabel = this.isRinging? "" : " isn't available";
|
||||
return `
|
||||
<div id="${this._containerId}" class='ringing' >
|
||||
<div class='ringing__content'>
|
||||
<p>Calling...</p>
|
||||
${callingLabel}
|
||||
<img class='ringing__avatar' src="${callee.getAvatarUrl()}" />
|
||||
<div class="ringing__caller-info">
|
||||
<p>${callee.getName()}</p>
|
||||
<p>${callee.getName()}${callerStateLabel}</p>
|
||||
</div>
|
||||
</div>
|
||||
<audio id="${this._audioContainerId}" src="/sounds/ring.ogg" />
|
||||
@@ -49,10 +86,7 @@ class RingOverlay {
|
||||
* related to the ring overlay.
|
||||
*/
|
||||
destroy() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
|
||||
this._stopAudio();
|
||||
this._detach();
|
||||
}
|
||||
|
||||
@@ -64,6 +98,16 @@ class RingOverlay {
|
||||
$(`#${this._containerId}`).remove();
|
||||
}
|
||||
|
||||
_stopAudio() {
|
||||
this.isRinging = false;
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
if(this._timeout) {
|
||||
clearTimeout(this._timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the interval that is going to play the ringing sound.
|
||||
*/
|
||||
@@ -74,12 +118,6 @@ class RingOverlay {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the current ring overlay instance.
|
||||
* Note: We want to have only 1 instance at a time.
|
||||
*/
|
||||
let overlay = null;
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Shows the ring overlay for the passed callee.
|
||||
@@ -92,6 +130,8 @@ export default {
|
||||
}
|
||||
|
||||
overlay = new RingOverlay(callee);
|
||||
APP.UI.addListener(UIEvents.LARGE_VIDEO_AVATAR_DISPLAYED,
|
||||
onAvatarDisplayed);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -104,6 +144,8 @@ export default {
|
||||
}
|
||||
overlay.destroy();
|
||||
overlay = null;
|
||||
APP.UI.removeListener(UIEvents.LARGE_VIDEO_AVATAR_DISPLAYED,
|
||||
onAvatarDisplayed);
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
@@ -3,20 +3,24 @@
|
||||
import {processReplacements, linkify} from './Replacement';
|
||||
import CommandsProcessor from './Commands';
|
||||
import ToolbarToggler from '../../toolbars/ToolbarToggler';
|
||||
import VideoLayout from "../../videolayout/VideoLayout";
|
||||
|
||||
import UIUtil from '../../util/UIUtil';
|
||||
import UIEvents from '../../../../service/UI/UIEvents';
|
||||
|
||||
var smileys = require("./smileys.json").smileys;
|
||||
|
||||
var notificationInterval = false;
|
||||
var unreadMessages = 0;
|
||||
|
||||
/**
|
||||
* The container id, which is and the element id.
|
||||
*/
|
||||
var CHAT_CONTAINER_ID = "chat_container";
|
||||
|
||||
/**
|
||||
* Shows/hides a visual notification, indicating that a message has arrived.
|
||||
* Updates visual notification, indicating that a message has arrived.
|
||||
*/
|
||||
function setVisualNotification(show) {
|
||||
function updateVisualNotification() {
|
||||
var unreadMsgElement = document.getElementById('unreadMessages');
|
||||
|
||||
var glower = $('#toolbar_button_chat');
|
||||
@@ -37,27 +41,9 @@ function setVisualNotification(show) {
|
||||
'style',
|
||||
'top:' + topIndent +
|
||||
'; left:' + leftIndent + ';');
|
||||
|
||||
if (!glower.hasClass('icon-chat-simple')) {
|
||||
glower.removeClass('icon-chat');
|
||||
glower.addClass('icon-chat-simple');
|
||||
}
|
||||
}
|
||||
else {
|
||||
unreadMsgElement.innerHTML = '';
|
||||
glower.removeClass('icon-chat-simple');
|
||||
glower.addClass('icon-chat');
|
||||
}
|
||||
|
||||
if (show && !notificationInterval) {
|
||||
notificationInterval = window.setInterval(function () {
|
||||
glower.toggleClass('active');
|
||||
}, 800);
|
||||
}
|
||||
else if (!show && notificationInterval) {
|
||||
window.clearInterval(notificationInterval);
|
||||
notificationInterval = false;
|
||||
glower.removeClass('active');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +117,7 @@ function addSmileys() {
|
||||
*/
|
||||
function resizeChatConversation() {
|
||||
var msgareaHeight = $('#usermsg').outerHeight();
|
||||
var chatspace = $('#chat_container');
|
||||
var chatspace = $('#' + CHAT_CONTAINER_ID);
|
||||
var width = chatspace.width();
|
||||
var chat = $('#chatconversation');
|
||||
var smileys = $('#smileysarea');
|
||||
@@ -187,10 +173,26 @@ var Chat = {
|
||||
};
|
||||
usermsg.autosize({callback: onTextAreaResize});
|
||||
|
||||
$("#chat_container").bind("shown",
|
||||
function () {
|
||||
eventEmitter.on(UIEvents.SIDE_TOOLBAR_CONTAINER_TOGGLED,
|
||||
function(containerId, isVisible) {
|
||||
if (containerId !== CHAT_CONTAINER_ID || !isVisible)
|
||||
return;
|
||||
|
||||
unreadMessages = 0;
|
||||
setVisualNotification(false);
|
||||
updateVisualNotification();
|
||||
|
||||
// Undock the toolbar when the chat is shown and if we're in a
|
||||
// video mode.
|
||||
if (VideoLayout.isLargeVideoVisible()) {
|
||||
ToolbarToggler.dockToolbar(false);
|
||||
}
|
||||
|
||||
// if we are in conversation mode focus on the text input
|
||||
// if we are not, focus on the display name input
|
||||
if (APP.settings.getDisplayName())
|
||||
$('#usermsg').focus();
|
||||
else
|
||||
$('#nickinput').focus();
|
||||
});
|
||||
|
||||
addSmileys();
|
||||
@@ -210,7 +212,7 @@ var Chat = {
|
||||
if (!Chat.isVisible()) {
|
||||
unreadMessages++;
|
||||
UIUtil.playSoundNotification('chatNotification');
|
||||
setVisualNotification(true);
|
||||
updateVisualNotification();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,12 +273,18 @@ var Chat = {
|
||||
|
||||
/**
|
||||
* Sets the chat conversation mode.
|
||||
* Conversation mode is the normal chat mode, non conversation mode is
|
||||
* where we ask user to input its display name.
|
||||
* @param {boolean} isConversationMode if chat should be in
|
||||
* conversation mode or not.
|
||||
*/
|
||||
setChatConversationMode (isConversationMode) {
|
||||
$('#chat_container')
|
||||
$('#' + CHAT_CONTAINER_ID)
|
||||
.toggleClass('is-conversation-mode', isConversationMode);
|
||||
|
||||
// this is needed when we transition from no conversation mode to
|
||||
// conversation mode. When user enters his nickname and hits enter,
|
||||
// to focus on the write area.
|
||||
if (isConversationMode) {
|
||||
$('#usermsg').focus();
|
||||
}
|
||||
@@ -286,7 +294,7 @@ var Chat = {
|
||||
* Resizes the chat area.
|
||||
*/
|
||||
resizeChat (width, height) {
|
||||
$('#chat_container').width(width).height(height);
|
||||
$('#' + CHAT_CONTAINER_ID).width(width).height(height);
|
||||
|
||||
resizeChatConversation();
|
||||
},
|
||||
@@ -296,7 +304,7 @@ var Chat = {
|
||||
*/
|
||||
isVisible () {
|
||||
return UIUtil.isVisible(
|
||||
document.getElementById("chat_container"));
|
||||
document.getElementById(CHAT_CONTAINER_ID));
|
||||
},
|
||||
/**
|
||||
* Shows and hides the window with the smileys
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* global $, APP */
|
||||
/* global $, APP, interfaceConfig */
|
||||
import Avatar from '../../avatar/Avatar';
|
||||
import UIEvents from '../../../../service/UI/UIEvents';
|
||||
import UIUtil from '../../util/UIUtil';
|
||||
@@ -96,9 +96,9 @@ var ContactList = {
|
||||
|
||||
/**
|
||||
* Adds a contact for the given id.
|
||||
*
|
||||
* @param isLocal is an id for the local user.
|
||||
*/
|
||||
addContact (id) {
|
||||
addContact (id, isLocal) {
|
||||
let contactlist = $('#contacts');
|
||||
|
||||
let newContact = document.createElement('li');
|
||||
@@ -110,8 +110,13 @@ var ContactList = {
|
||||
}
|
||||
};
|
||||
|
||||
newContact.appendChild(createAvatar(id));
|
||||
newContact.appendChild(createDisplayNameParagraph("participant"));
|
||||
if (interfaceConfig.SHOW_CONTACTLIST_AVATARS)
|
||||
newContact.appendChild(createAvatar(id));
|
||||
|
||||
newContact.appendChild(
|
||||
createDisplayNameParagraph(
|
||||
isLocal ? interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME : null,
|
||||
isLocal ? null : interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME));
|
||||
|
||||
if (APP.conference.isLocalId(id)) {
|
||||
contactlist.prepend(newContact);
|
||||
|
||||
@@ -7,7 +7,6 @@ import SideContainerToggler from "../side_pannels/SideContainerToggler";
|
||||
let roomUrl = null;
|
||||
let emitter = null;
|
||||
|
||||
|
||||
/**
|
||||
* Opens the invite link dialog.
|
||||
*/
|
||||
@@ -168,8 +167,13 @@ const buttonHandlers = {
|
||||
},
|
||||
"toolbar_film_strip": function () {
|
||||
JitsiMeetJS.analytics.sendEvent(
|
||||
'bottomtoolbar.filmstrip.toggled');
|
||||
'toolbar.filmstrip.toggled');
|
||||
emitter.emit(UIEvents.TOGGLE_FILM_STRIP);
|
||||
},
|
||||
"toolbar_button_raisehand": function () {
|
||||
JitsiMeetJS.analytics.sendEvent(
|
||||
'toolbar.raiseHand.clicked');
|
||||
APP.conference.maybeToggleRaisedHand();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -288,6 +292,19 @@ const defaultToolbarButtons = {
|
||||
APP.UI.toggleFilmStrip();
|
||||
},
|
||||
shortcutDescription: "keyboardShortcuts.toggleFilmstrip"
|
||||
},
|
||||
'raisehand': {
|
||||
id: "toolbar_button_raisehand",
|
||||
className: "button icon-raised-hand",
|
||||
shortcut: "R",
|
||||
shortcutAttr: "raiseHandPopover",
|
||||
shortcutFunc: function() {
|
||||
JitsiMeetJS.analytics.sendEvent("shortcut.raisehand.clicked");
|
||||
APP.conference.maybeToggleRaisedHand();
|
||||
},
|
||||
shortcutDescription: "keyboardShortcuts.raiseHand",
|
||||
content: "Raise Hand",
|
||||
i18n: "[content]toolbar.raiseHand"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -323,10 +340,14 @@ const Toolbar = {
|
||||
this.toolbarSelector = $("#mainToolbarContainer");
|
||||
this.extendedToolbarSelector = $("#extendedToolbar");
|
||||
|
||||
this._initMainToolbarButtons();
|
||||
|
||||
// First hide all disabled buttons in the extended toolbar.
|
||||
// TODO: Make the extended toolbar dynamically created.
|
||||
UIUtil.hideDisabledButtons(defaultToolbarButtons);
|
||||
|
||||
// Initialise the main toolbar. The main toolbar will only take into
|
||||
// account it's own configuration from interface_config.
|
||||
this._initMainToolbarButtons();
|
||||
|
||||
Object.keys(defaultToolbarButtons).forEach(
|
||||
id => {
|
||||
if (UIUtil.isButtonEnabled(id)) {
|
||||
@@ -679,16 +700,9 @@ const Toolbar = {
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* TODO: Fix mic popups
|
||||
* <a class="button icon-microphone" id="toolbar_button_mute" data-container="body" data-toggle="popover" data-placement="bottom" shortcut="mutePopover" data-i18n="[content]toolbar.mute" content="Mute / Unmute">
|
||||
* <ul id="micMutedPopup" class="loginmenu">
|
||||
* <li data-i18n="[html]toolbar.micMutedPopup"></li>
|
||||
* </ul>
|
||||
* <ul id="unableToUnmutePopup" class="loginmenu">
|
||||
* <li data-i18n="[html]toolbar.unableToUnmutePopup"></li>
|
||||
* </ul>
|
||||
* </a>
|
||||
* Initialise main toolbar buttons.
|
||||
*/
|
||||
_initMainToolbarButtons() {
|
||||
interfaceConfig.MAIN_TOOLBAR_BUTTONS.forEach((value, index) => {
|
||||
@@ -751,4 +765,4 @@ const Toolbar = {
|
||||
}
|
||||
};
|
||||
|
||||
export default Toolbar;
|
||||
export default Toolbar;
|
||||
@@ -35,9 +35,11 @@ function hideToolbar(force) {
|
||||
clearTimeout(toolbarTimeoutObject);
|
||||
toolbarTimeoutObject = null;
|
||||
|
||||
if (Toolbar.isHovered() || APP.UI.isRingOverlayVisible()) {
|
||||
if (Toolbar.isHovered()
|
||||
|| APP.UI.isRingOverlayVisible()
|
||||
|| SideContainerToggler.isVisible()) {
|
||||
toolbarTimeoutObject = setTimeout(hideToolbar, toolbarTimeout);
|
||||
} else if (!SideContainerToggler.isVisible() || force) {
|
||||
} else {
|
||||
Toolbar.hide();
|
||||
$('#subject').animate({top: "-=40"}, 300);
|
||||
}
|
||||
@@ -50,7 +52,8 @@ const ToolbarToggler = {
|
||||
init() {
|
||||
alwaysVisibleToolbar = (config.alwaysVisibleToolbar === true);
|
||||
|
||||
this._registerWindowClickListeners();
|
||||
// disabled
|
||||
//this._registerWindowClickListeners();
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -112,7 +112,8 @@
|
||||
* is enabled, {false} - otherwise
|
||||
*/
|
||||
isButtonEnabled: function (name) {
|
||||
return interfaceConfig.TOOLBAR_BUTTONS.indexOf(name) !== -1;
|
||||
return interfaceConfig.TOOLBAR_BUTTONS.indexOf(name) !== -1
|
||||
|| interfaceConfig.MAIN_TOOLBAR_BUTTONS.indexOf(name) !== -1;
|
||||
},
|
||||
/**
|
||||
* Indicates if the setting section is enabled.
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
import UIEvents from "../../../service/UI/UIEvents";
|
||||
import UIUtil from "../util/UIUtil";
|
||||
|
||||
const thumbAspectRatio = 1 / 1;
|
||||
|
||||
const FilmStrip = {
|
||||
/**
|
||||
*
|
||||
@@ -66,13 +64,52 @@ const FilmStrip = {
|
||||
- parseInt(this.filmStrip.css('paddingRight'), 10);
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the thumbnail size.
|
||||
*/
|
||||
calculateThumbnailSize () {
|
||||
let availableHeight = interfaceConfig.FILM_STRIP_MAX_HEIGHT;
|
||||
calculateThumbnailSize() {
|
||||
let availableSizes = this.calculateAvailableSize();
|
||||
let width = availableSizes.availableWidth;
|
||||
let height = availableSizes.availableHeight;
|
||||
|
||||
let numvids = this.getThumbs(true).length;
|
||||
return this.calculateThumbnailSizeFromAvailable(width, height);
|
||||
},
|
||||
|
||||
/**
|
||||
* Normalizes local and remote thumbnail ratios
|
||||
*/
|
||||
normalizeThumbnailRatio () {
|
||||
let remoteHeightRatio = interfaceConfig.REMOTE_THUMBNAIL_RATIO_HEIGHT;
|
||||
let remoteWidthRatio = interfaceConfig.REMOTE_THUMBNAIL_RATIO_WIDTH;
|
||||
|
||||
let localHeightRatio = interfaceConfig.LOCAL_THUMBNAIL_RATIO_HEIGHT;
|
||||
let localWidthRatio = interfaceConfig.LOCAL_THUMBNAIL_RATIO_WIDTH;
|
||||
|
||||
let commonHeightRatio = remoteHeightRatio * localHeightRatio;
|
||||
|
||||
let localRatioCoefficient = localWidthRatio / localHeightRatio;
|
||||
let remoteRatioCoefficient = remoteWidthRatio / remoteHeightRatio;
|
||||
|
||||
remoteWidthRatio = commonHeightRatio * remoteRatioCoefficient;
|
||||
remoteHeightRatio = commonHeightRatio;
|
||||
|
||||
localWidthRatio = commonHeightRatio * localRatioCoefficient;
|
||||
localHeightRatio = commonHeightRatio;
|
||||
|
||||
let localRatio = {
|
||||
widthRatio: localWidthRatio,
|
||||
heightRatio: localHeightRatio
|
||||
};
|
||||
|
||||
let remoteRatio = {
|
||||
widthRatio: remoteWidthRatio,
|
||||
heightRatio: remoteHeightRatio
|
||||
};
|
||||
|
||||
return { localRatio, remoteRatio };
|
||||
},
|
||||
|
||||
calculateAvailableSize() {
|
||||
let availableHeight = interfaceConfig.FILM_STRIP_MAX_HEIGHT;
|
||||
let thumbs = this.getThumbs(true);
|
||||
let numvids = thumbs.remoteThumbs.length;
|
||||
|
||||
let localVideoContainer = $("#localVideoContainer");
|
||||
|
||||
@@ -92,11 +129,10 @@ const FilmStrip = {
|
||||
|
||||
let availableWidth = videoAreaAvailableWidth;
|
||||
|
||||
// If the number of videos is 0 or undefined we don't need to calculate
|
||||
// further.
|
||||
if (numvids)
|
||||
// If local thumb is not hidden
|
||||
if(thumbs.localThumb) {
|
||||
availableWidth = Math.floor(
|
||||
(videoAreaAvailableWidth - numvids * (
|
||||
(videoAreaAvailableWidth - (
|
||||
UIUtil.parseCssInt(
|
||||
localVideoContainer.css('borderLeftWidth'), 10)
|
||||
+ UIUtil.parseCssInt(
|
||||
@@ -109,36 +145,90 @@ const FilmStrip = {
|
||||
localVideoContainer.css('marginLeft'), 10)
|
||||
+ UIUtil.parseCssInt(
|
||||
localVideoContainer.css('marginRight'), 10)))
|
||||
/ numvids);
|
||||
);
|
||||
}
|
||||
|
||||
// If the number of videos is 0 or undefined we don't need to calculate
|
||||
// further.
|
||||
if (numvids) {
|
||||
let remoteVideoContainer = thumbs.remoteThumbs.eq(0);
|
||||
availableWidth = Math.floor(
|
||||
(videoAreaAvailableWidth - numvids * (
|
||||
UIUtil.parseCssInt(
|
||||
remoteVideoContainer.css('borderLeftWidth'), 10)
|
||||
+ UIUtil.parseCssInt(
|
||||
remoteVideoContainer.css('borderRightWidth'), 10)
|
||||
+ UIUtil.parseCssInt(
|
||||
remoteVideoContainer.css('paddingLeft'), 10)
|
||||
+ UIUtil.parseCssInt(
|
||||
remoteVideoContainer.css('paddingRight'), 10)
|
||||
+ UIUtil.parseCssInt(
|
||||
remoteVideoContainer.css('marginLeft'), 10)
|
||||
+ UIUtil.parseCssInt(
|
||||
remoteVideoContainer.css('marginRight'), 10)))
|
||||
);
|
||||
}
|
||||
|
||||
let maxHeight
|
||||
// If the MAX_HEIGHT property hasn't been specified
|
||||
// we have the static value.
|
||||
= Math.min( interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120,
|
||||
availableHeight);
|
||||
= Math.min(interfaceConfig.FILM_STRIP_MAX_HEIGHT || 120,
|
||||
availableHeight);
|
||||
|
||||
availableHeight
|
||||
= Math.min( maxHeight, window.innerHeight - 18);
|
||||
= Math.min(maxHeight, window.innerHeight - 18);
|
||||
|
||||
if (availableHeight < availableWidth) {
|
||||
availableWidth = availableHeight;
|
||||
return { availableWidth, availableHeight };
|
||||
},
|
||||
|
||||
calculateThumbnailSizeFromAvailable(availableWidth, availableHeight) {
|
||||
let { localRatio, remoteRatio } = this.normalizeThumbnailRatio();
|
||||
let { remoteThumbs } = this.getThumbs(true);
|
||||
let remoteProportion = remoteRatio.widthRatio * remoteThumbs.length;
|
||||
let widthProportion = remoteProportion + localRatio.widthRatio;
|
||||
|
||||
let heightUnit = availableHeight / localRatio.heightRatio;
|
||||
let widthUnit = availableWidth / widthProportion;
|
||||
|
||||
if (heightUnit < widthUnit) {
|
||||
widthUnit = heightUnit;
|
||||
}
|
||||
else
|
||||
availableHeight = availableWidth;
|
||||
heightUnit = widthUnit;
|
||||
|
||||
let localVideo = {
|
||||
thumbWidth: widthUnit * localRatio.widthRatio,
|
||||
thumbHeight: heightUnit * localRatio.heightRatio
|
||||
};
|
||||
let remoteVideo = {
|
||||
thumbWidth: widthUnit * remoteRatio.widthRatio,
|
||||
thumbHeight: widthUnit * remoteRatio.heightRatio
|
||||
};
|
||||
|
||||
return {
|
||||
thumbWidth: availableWidth,
|
||||
thumbHeight: availableHeight
|
||||
localVideo,
|
||||
remoteVideo
|
||||
};
|
||||
},
|
||||
|
||||
resizeThumbnails (thumbWidth, thumbHeight,
|
||||
resizeThumbnails (local, remote,
|
||||
animate = false, forceUpdate = false) {
|
||||
|
||||
return new Promise(resolve => {
|
||||
this.getThumbs(!forceUpdate).animate({
|
||||
height: thumbHeight,
|
||||
width: thumbWidth
|
||||
let thumbs = this.getThumbs(!forceUpdate);
|
||||
|
||||
thumbs.localThumb.animate({
|
||||
height: local.thumbHeight,
|
||||
width: local.thumbWidth
|
||||
}, {
|
||||
queue: false,
|
||||
duration: animate ? 500 : 0,
|
||||
complete: resolve
|
||||
});
|
||||
|
||||
thumbs.remoteThumbs.animate({
|
||||
height: remote.thumbHeight,
|
||||
width: remote.thumbWidth
|
||||
}, {
|
||||
queue: false,
|
||||
duration: animate ? 500 : 0,
|
||||
@@ -147,7 +237,7 @@ const FilmStrip = {
|
||||
|
||||
this.filmStrip.animate({
|
||||
// adds 2 px because of small video 1px border
|
||||
height: thumbHeight + 2
|
||||
height: remote.thumbHeight + 2
|
||||
}, {
|
||||
queue: false,
|
||||
duration: animate ? 500 : 0
|
||||
@@ -165,13 +255,19 @@ const FilmStrip = {
|
||||
selector += ':visible';
|
||||
}
|
||||
|
||||
let localThumb = $("#localVideoContainer");
|
||||
let remoteThumbs = this.filmStrip.children(selector)
|
||||
.not("#localVideoContainer");
|
||||
|
||||
// Exclude the local video container if it has been hidden.
|
||||
if ($("#localVideoContainer").hasClass("hidden"))
|
||||
return this.filmStrip.children(selector)
|
||||
.not("#localVideoContainer");
|
||||
else
|
||||
return this.filmStrip.children(selector);
|
||||
}
|
||||
if (localThumb.hasClass("hidden")) {
|
||||
return { remoteThumbs };
|
||||
} else {
|
||||
return { remoteThumbs, localThumb };
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default FilmStrip;
|
||||
|
||||
@@ -164,11 +164,12 @@ class VideoContainer extends LargeContainer {
|
||||
return getStreamOwnerId(this.stream);
|
||||
}
|
||||
|
||||
constructor (onPlay) {
|
||||
constructor (onPlay, emitter) {
|
||||
super();
|
||||
this.stream = null;
|
||||
this.videoType = null;
|
||||
this.localFlipX = true;
|
||||
this.emitter = emitter;
|
||||
|
||||
this.isVisible = false;
|
||||
|
||||
@@ -327,6 +328,8 @@ class VideoContainer extends LargeContainer {
|
||||
(show) ? interfaceConfig.DEFAULT_BACKGROUND : "#000");
|
||||
|
||||
this.$avatar.css("visibility", show ? "visible" : "hidden");
|
||||
|
||||
this.emitter.emit(UIEvents.LARGE_VIDEO_AVATAR_DISPLAYED, show);
|
||||
}
|
||||
|
||||
// We are doing fadeOut/fadeIn animations on parent div which wraps
|
||||
@@ -385,12 +388,12 @@ class VideoContainer extends LargeContainer {
|
||||
* Manager for all Large containers.
|
||||
*/
|
||||
export default class LargeVideoManager {
|
||||
constructor () {
|
||||
constructor (emitter) {
|
||||
this.containers = {};
|
||||
|
||||
this.state = VIDEO_CONTAINER_TYPE;
|
||||
this.videoContainer = new VideoContainer(
|
||||
() => this.resizeContainer(VIDEO_CONTAINER_TYPE));
|
||||
() => this.resizeContainer(VIDEO_CONTAINER_TYPE), emitter);
|
||||
this.addContainer(VIDEO_CONTAINER_TYPE, this.videoContainer);
|
||||
|
||||
// use the same video container to handle and desktop tracks
|
||||
|
||||
@@ -11,7 +11,6 @@ function LocalVideo(VideoLayout, emitter) {
|
||||
this.videoSpanId = "localVideoContainer";
|
||||
this.container = $("#localVideoContainer").get(0);
|
||||
this.localVideoId = null;
|
||||
this.bindHoverHandler();
|
||||
if(config.enableLocalVideoFlip)
|
||||
this._buildContextMenu();
|
||||
this.isLocal = true;
|
||||
@@ -44,7 +43,7 @@ function createEditDisplayNameButton() {
|
||||
editButton.className = 'displayname';
|
||||
UIUtil.setTooltip(editButton,
|
||||
"videothumbnail.editnickname",
|
||||
"top");
|
||||
"left");
|
||||
editButton.innerHTML = '<i class="icon-edit"></i>';
|
||||
|
||||
return editButton;
|
||||
@@ -72,7 +71,7 @@ LocalVideo.prototype.setDisplayName = function(displayName, key) {
|
||||
if (displayName && displayName.length > 0) {
|
||||
meHTML = APP.translation.generateTranslationHTML("me");
|
||||
$('#localDisplayName').html(
|
||||
UIUtil.escapeHtml(displayName) + ' (' + meHTML + ')'
|
||||
`${UIUtil.escapeHtml(displayName)} (${meHTML})`
|
||||
);
|
||||
} else {
|
||||
$('#localDisplayName').html(defaultLocalDisplayName);
|
||||
@@ -80,11 +79,9 @@ LocalVideo.prototype.setDisplayName = function(displayName, key) {
|
||||
}
|
||||
this.updateView();
|
||||
} else {
|
||||
var editButton = createEditDisplayNameButton();
|
||||
|
||||
nameSpan = document.createElement('span');
|
||||
nameSpan.className = 'displayname';
|
||||
$('#' + this.videoSpanId)[0].appendChild(nameSpan);
|
||||
document.getElementById(this.videoSpanId).appendChild(nameSpan);
|
||||
|
||||
|
||||
if (displayName && displayName.length > 0) {
|
||||
@@ -97,7 +94,6 @@ LocalVideo.prototype.setDisplayName = function(displayName, key) {
|
||||
|
||||
|
||||
nameSpan.id = 'localDisplayName';
|
||||
this.container.appendChild(editButton);
|
||||
//translates popover of edit button
|
||||
APP.translation.translateElement($("a.displayname"));
|
||||
|
||||
@@ -124,21 +120,23 @@ LocalVideo.prototype.setDisplayName = function(displayName, key) {
|
||||
var self = this;
|
||||
$('#localVideoContainer .displayname')
|
||||
.bind("click", function (e) {
|
||||
let $editDisplayName = $('#editDisplayName');
|
||||
let $localDisplayName = $('#localDisplayName');
|
||||
|
||||
var editDisplayName = $('#editDisplayName');
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
$('#localDisplayName').hide();
|
||||
editDisplayName.show();
|
||||
editDisplayName.focus();
|
||||
editDisplayName.select();
|
||||
$localDisplayName.hide();
|
||||
$editDisplayName.show();
|
||||
$editDisplayName.focus();
|
||||
$editDisplayName.select();
|
||||
|
||||
editDisplayName.one("focusout", function (e) {
|
||||
$editDisplayName.one("focusout", function (e) {
|
||||
self.emitter.emit(UIEvents.NICKNAME_CHANGED, this.value);
|
||||
$('#editDisplayName').hide();
|
||||
$editDisplayName.hide();
|
||||
$localDisplayName.show();
|
||||
});
|
||||
|
||||
editDisplayName.on('keydown', function (e) {
|
||||
$editDisplayName.on('keydown', function (e) {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
$('#editDisplayName').hide();
|
||||
|
||||
@@ -17,7 +17,6 @@ function RemoteVideo(id, VideoLayout, emitter) {
|
||||
this.addRemoteVideoContainer();
|
||||
this.connectionIndicator = new ConnectionIndicator(this, id);
|
||||
this.setDisplayName();
|
||||
this.bindHoverHandler();
|
||||
this.flipX = false;
|
||||
this.isLocal = false;
|
||||
this.isMuted = false;
|
||||
@@ -34,8 +33,10 @@ RemoteVideo.prototype.addRemoteVideoContainer = function() {
|
||||
if (APP.conference.isModerator) {
|
||||
this.addRemoteVideoMenu();
|
||||
}
|
||||
let {thumbWidth, thumbHeight} = this.VideoLayout.resizeThumbnails();
|
||||
AudioLevels.updateAudioLevelCanvas(this.id, thumbWidth, thumbHeight);
|
||||
|
||||
let { remoteVideo } = this.VideoLayout.resizeThumbnails();
|
||||
let { thumbHeight, thumbWidth } = remoteVideo;
|
||||
AudioLevels.createAudioLevelCanvas(this.id, thumbWidth, thumbHeight);
|
||||
|
||||
return this.container;
|
||||
};
|
||||
@@ -427,12 +428,16 @@ RemoteVideo.prototype.removeRemoteVideoMenu = function() {
|
||||
};
|
||||
|
||||
RemoteVideo.createContainer = function (spanId) {
|
||||
var container = document.createElement('span');
|
||||
let container = document.createElement('span');
|
||||
container.id = spanId;
|
||||
container.className = 'videocontainer';
|
||||
|
||||
let toolbar = document.createElement('div');
|
||||
toolbar.className = "videocontainer__toolbar";
|
||||
container.appendChild(toolbar);
|
||||
|
||||
var remotes = document.getElementById('remoteVideos');
|
||||
return remotes.appendChild(container);
|
||||
};
|
||||
|
||||
|
||||
export default RemoteVideo;
|
||||
|
||||
@@ -171,26 +171,6 @@ SmallVideo.getStreamElementID = function (stream) {
|
||||
return (isVideo ? 'remoteVideo_' : 'remoteAudio_') + stream.getId();
|
||||
};
|
||||
|
||||
/**
|
||||
* Configures hoverIn/hoverOut handlers.
|
||||
*/
|
||||
SmallVideo.prototype.bindHoverHandler = function () {
|
||||
// Add hover handler
|
||||
var self = this;
|
||||
$(this.container).hover(
|
||||
function () {
|
||||
self.showDisplayName(true);
|
||||
},
|
||||
function () {
|
||||
// If the video has been "pinned" by the user we want to
|
||||
// keep the display name on place.
|
||||
if (!self.VideoLayout.isLargeVideoVisible() ||
|
||||
!self.VideoLayout.isCurrentlyOnLarge(self.id))
|
||||
self.showDisplayName(false);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the data for the indicator
|
||||
* @param id the id of the indicator
|
||||
@@ -219,6 +199,7 @@ SmallVideo.prototype.showAudioIndicator = function(isMuted) {
|
||||
if (audioMutedSpan.length > 0) {
|
||||
audioMutedSpan.popover('hide');
|
||||
audioMutedSpan.remove();
|
||||
this.updateIconPositions();
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -230,12 +211,14 @@ SmallVideo.prototype.showAudioIndicator = function(isMuted) {
|
||||
"top");
|
||||
|
||||
this.container.appendChild(audioMutedSpan);
|
||||
APP.translation.translateElement($('#' + this.videoSpanId + " > span"));
|
||||
APP.translation
|
||||
.translateElement($('#' + this.videoSpanId + " > span"));
|
||||
var mutedIndicator = document.createElement('i');
|
||||
mutedIndicator.className = 'icon-mic-disabled';
|
||||
audioMutedSpan.appendChild(mutedIndicator);
|
||||
|
||||
}
|
||||
|
||||
this.updateIconPositions();
|
||||
}
|
||||
this.isMuted = isMuted;
|
||||
@@ -254,6 +237,7 @@ SmallVideo.prototype.setMutedView = function(isMuted) {
|
||||
if (isMuted === false) {
|
||||
if (videoMutedSpan.length > 0) {
|
||||
videoMutedSpan.remove();
|
||||
this.updateIconPositions();
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -270,7 +254,8 @@ SmallVideo.prototype.setMutedView = function(isMuted) {
|
||||
"top");
|
||||
videoMutedSpan.appendChild(mutedIndicator);
|
||||
//translate texts for muted indicator
|
||||
APP.translation.translateElement($('#' + this.videoSpanId + " > span > i"));
|
||||
APP.translation
|
||||
.translateElement($('#' + this.videoSpanId + " > span > i"));
|
||||
}
|
||||
|
||||
this.updateIconPositions();
|
||||
@@ -278,13 +263,18 @@ SmallVideo.prototype.setMutedView = function(isMuted) {
|
||||
};
|
||||
|
||||
SmallVideo.prototype.updateIconPositions = function () {
|
||||
var audioMutedSpan = $('#' + this.videoSpanId + '>span.audioMuted');
|
||||
var connectionIndicator = $('#' + this.videoSpanId + '>div.connectionindicator');
|
||||
var videoMutedSpan = $('#' + this.videoSpanId + '>span.videoMuted');
|
||||
let audioMutedSpan = $('#' + this.videoSpanId + '>span.audioMuted');
|
||||
let videoMutedSpan = $('#' + this.videoSpanId + '>span.videoMuted');
|
||||
audioMutedSpan.css({left: "0px"});
|
||||
videoMutedSpan.css({left: (audioMutedSpan.length > 0? 25 : 0) + "px"});
|
||||
|
||||
var connectionIndicator
|
||||
= $('#' + this.videoSpanId + '>div.connectionindicator');
|
||||
if(connectionIndicator.length > 0 &&
|
||||
connectionIndicator[0].style.display != "none") {
|
||||
audioMutedSpan.css({right: "23px"});
|
||||
videoMutedSpan.css({right: ((audioMutedSpan.length > 0? 23 : 0) + 30) + "px"});
|
||||
videoMutedSpan.css({right:
|
||||
((audioMutedSpan.length > 0? 23 : 0) + 30) + "px"});
|
||||
} else {
|
||||
audioMutedSpan.css({right: "0px"});
|
||||
videoMutedSpan.css({right: (audioMutedSpan.length > 0? 30 : 0) + "px"});
|
||||
@@ -317,7 +307,8 @@ SmallVideo.prototype.createModeratorIndicatorElement = function () {
|
||||
"top");
|
||||
|
||||
//translates text in focus indicators
|
||||
APP.translation.translateElement($('#' + this.videoSpanId + ' .focusindicator'));
|
||||
APP.translation
|
||||
.translateElement($('#' + this.videoSpanId + ' .focusindicator'));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -406,8 +397,6 @@ SmallVideo.prototype.updateView = function () {
|
||||
setVisibility(video, showVideo);
|
||||
}
|
||||
setVisibility(avatar, showAvatar);
|
||||
|
||||
this.showDisplayName(!showVideo && !showAvatar);
|
||||
};
|
||||
|
||||
SmallVideo.prototype.avatarChanged = function (avatarUrl) {
|
||||
@@ -465,9 +454,8 @@ SmallVideo.prototype.showRaisedHandIndicator = function (show) {
|
||||
var indicatorSpanId = "raisehandindicator";
|
||||
var indicatorSpan = this.getIndicatorSpan(indicatorSpanId);
|
||||
|
||||
indicatorSpan.style.background = "#D6D61E";
|
||||
indicatorSpan.innerHTML
|
||||
= "<i id='indicatoricon' class='fa fa-hand-paper-o'></i>";
|
||||
= "<i id='indicatoricon' class='icon-raised-hand'></i>";
|
||||
|
||||
// adds a tooltip
|
||||
UIUtil.setTooltip(indicatorSpan, "raisedHand", "left");
|
||||
|
||||
@@ -105,16 +105,16 @@ var VideoLayout = {
|
||||
localVideoThumbnail.setVideoType(VIDEO_CONTAINER_TYPE);
|
||||
// if we do not resize the thumbs here, if there is no video device
|
||||
// the local video thumb maybe one pixel
|
||||
let {thumbWidth, thumbHeight}
|
||||
= this.resizeThumbnails(false, true, false);
|
||||
AudioLevels.updateAudioLevelCanvas(null, thumbWidth, thumbHeight);
|
||||
let { localVideo } = this.resizeThumbnails(false, true);
|
||||
AudioLevels.createAudioLevelCanvas(
|
||||
"local", localVideo.thumbWidth, localVideo.thumbHeight);
|
||||
|
||||
emitter.addListener(UIEvents.CONTACT_CLICKED, onContactClicked);
|
||||
this.lastNCount = config.channelLastN;
|
||||
},
|
||||
|
||||
initLargeVideo () {
|
||||
largeVideo = new LargeVideoManager();
|
||||
largeVideo = new LargeVideoManager(eventEmitter);
|
||||
if(localFlipX) {
|
||||
largeVideo.onLocalFlipXChange(localFlipX);
|
||||
}
|
||||
@@ -255,7 +255,8 @@ var VideoLayout = {
|
||||
electLastVisibleVideo () {
|
||||
// pick the last visible video in the row
|
||||
// if nobody else is left, this picks the local video
|
||||
let thumbs = FilmStrip.getThumbs(true).filter('[id!="mixedstream"]');
|
||||
let remoteThumbs = FilmStrip.getThumbs(true).remoteThumbs;
|
||||
let thumbs = remoteThumbs.filter('[id!="mixedstream"]');
|
||||
|
||||
let lastVisible = thumbs.filter(':visible:last');
|
||||
if (lastVisible.length) {
|
||||
@@ -269,7 +270,7 @@ var VideoLayout = {
|
||||
}
|
||||
|
||||
console.info("Last visible video no longer exists");
|
||||
thumbs = FilmStrip.getThumbs();
|
||||
thumbs = FilmStrip.getThumbs().remoteThumbs;
|
||||
if (thumbs.length) {
|
||||
let id = getPeerContainerResourceId(thumbs[0]);
|
||||
if (remoteVideos[id]) {
|
||||
@@ -402,7 +403,7 @@ var VideoLayout = {
|
||||
|
||||
// In case this is not currently in the last n we don't show it.
|
||||
if (localLastNCount && localLastNCount > 0 &&
|
||||
FilmStrip.getThumbs().length >= localLastNCount + 2) {
|
||||
FilmStrip.getThumbs().remoteThumbs.length >= localLastNCount + 2) {
|
||||
remoteVideo.showPeerContainer('hide');
|
||||
} else {
|
||||
VideoLayout.resizeThumbnails(false, true);
|
||||
@@ -414,7 +415,7 @@ var VideoLayout = {
|
||||
console.info(resourceJid + " video is now active", videoelem);
|
||||
|
||||
VideoLayout.resizeThumbnails(
|
||||
false, false, false, function() {$(videoelem).show();});
|
||||
false, false, function() {$(videoelem).show();});
|
||||
|
||||
// Update the large video to the last added video only if there's no
|
||||
// current dominant, focused speaker or update it to
|
||||
@@ -487,19 +488,19 @@ var VideoLayout = {
|
||||
forceUpdate = false,
|
||||
onComplete = null) {
|
||||
|
||||
let {thumbWidth, thumbHeight}
|
||||
let { localVideo, remoteVideo }
|
||||
= FilmStrip.calculateThumbnailSize();
|
||||
|
||||
$('.userAvatar').css('left', (thumbWidth - thumbHeight) / 2);
|
||||
let {thumbWidth, thumbHeight} = remoteVideo;
|
||||
|
||||
FilmStrip.resizeThumbnails(thumbWidth, thumbHeight,
|
||||
FilmStrip.resizeThumbnails(localVideo, remoteVideo,
|
||||
animate, forceUpdate)
|
||||
.then(function () {
|
||||
AudioLevels.updateCanvasSize(thumbWidth, thumbHeight);
|
||||
AudioLevels.updateCanvasSize(localVideo, remoteVideo);
|
||||
if (onComplete && typeof onComplete === "function")
|
||||
onComplete();
|
||||
});
|
||||
return {thumbWidth, thumbHeight};
|
||||
});
|
||||
return { localVideo, remoteVideo };
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -657,7 +658,7 @@ var VideoLayout = {
|
||||
var updateLargeVideo = false;
|
||||
|
||||
// Handle LastN/local LastN changes.
|
||||
FilmStrip.getThumbs().each(( index, element ) => {
|
||||
FilmStrip.getThumbs().remoteThumbs.each(( index, element ) => {
|
||||
var resourceJid = getPeerContainerResourceId(element);
|
||||
var smallVideo = remoteVideos[resourceJid];
|
||||
|
||||
|
||||
@@ -17,11 +17,6 @@ function initGlobalShortcuts() {
|
||||
APP.UI.toggleKeyboardShortcutsPanel();
|
||||
}, "keyboardShortcuts.toggleShortcuts");
|
||||
|
||||
KeyboardShortcut.registerShortcut("R", null, function() {
|
||||
JitsiMeetJS.analytics.sendEvent("shortcut.raisedhand.toggled");
|
||||
APP.conference.maybeToggleRaisedHand();
|
||||
}, "keyboardShortcuts.raiseHand");
|
||||
|
||||
KeyboardShortcut.registerShortcut("T", null, function() {
|
||||
JitsiMeetJS.analytics.sendEvent("shortcut.talk.clicked");
|
||||
APP.conference.muteAudio(true);
|
||||
|
||||
10
package.json
10
package.json
@@ -21,18 +21,18 @@
|
||||
"bootstrap": "3.1.1",
|
||||
"events": "*",
|
||||
"i18next-client": "1.7.7",
|
||||
"jquery": "~2.1.1",
|
||||
"jQuery-Impromptu": "git+https://github.com/trentrichardson/jQuery-Impromptu.git#v6.0.0",
|
||||
"lib-jitsi-meet": "git+https://github.com/jitsi/lib-jitsi-meet.git",
|
||||
"jquery": "~2.1.1",
|
||||
"jquery-contextmenu": "*",
|
||||
"jquery-ui": "1.10.5",
|
||||
"jssha": "1.5.0",
|
||||
"jws": "*",
|
||||
"lib-jitsi-meet": "git+https://github.com/jitsi/lib-jitsi-meet.git",
|
||||
"postis": "^2.2.0",
|
||||
"retry": "0.6.1",
|
||||
"strophe": "^1.2.2",
|
||||
"strophejs-plugins": "^0.0.6",
|
||||
"toastr": "^2.0.3",
|
||||
"postis": "^2.2.0",
|
||||
"jws": "*"
|
||||
"toastr": "^2.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-polyfill": "*",
|
||||
|
||||
@@ -105,5 +105,10 @@ export default {
|
||||
* event must contain the identifier of the container that has been toggled
|
||||
* and information about toggle on or off.
|
||||
*/
|
||||
SIDE_TOOLBAR_CONTAINER_TOGGLED: "UI.side_container_toggled"
|
||||
SIDE_TOOLBAR_CONTAINER_TOGGLED: "UI.side_container_toggled",
|
||||
|
||||
/**
|
||||
* Notifies that the avatar is displayed or not on the largeVideo.
|
||||
*/
|
||||
LARGE_VIDEO_AVATAR_DISPLAYED: "UI.large_video_avatar_displayed"
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user