[WEB] add UI for transcription (#3213)

* [WEB] add UI for transcription

* add analytics event for button, do not use global APP object

* use props instead of state, use local conference to kick participant

* put imports in alphabetical order

* add translation for TranscribingLabel

* fix merge conflict

* add closed caption button

* purge OverFlowMenuItem which starts and stops Transcription

* readd closed caption icon and fix small issues due to purge

* delete unused icon in _font.scss
This commit is contained in:
Nik 2018-07-26 18:33:40 +02:00 committed by virtuacoplenny
parent 39f1958300
commit b8daf0a9f9
26 changed files with 1191 additions and 309 deletions

View File

@ -72,6 +72,8 @@ import {
getAvatarURLByParticipantId,
getLocalParticipant,
getParticipantById,
hiddenParticipantJoined,
hiddenParticipantLeft,
localParticipantConnectionStatusChanged,
localParticipantRoleChanged,
MAX_DISPLAY_NAME_LENGTH,
@ -1654,10 +1656,13 @@ export default {
room.on(JitsiConferenceEvents.PARTCIPANT_FEATURES_CHANGED,
user => APP.UI.onUserFeaturesChanged(user));
room.on(JitsiConferenceEvents.USER_JOINED, (id, user) => {
const displayName = user.getDisplayName();
if (user.isHidden()) {
APP.store.dispatch(hiddenParticipantJoined(id, displayName));
return;
}
const displayName = user.getDisplayName();
APP.store.dispatch(participantJoined({
botType: user.getBotType(),
@ -1682,8 +1687,11 @@ export default {
room.on(JitsiConferenceEvents.USER_LEFT, (id, user) => {
if (user.isHidden()) {
APP.store.dispatch(hiddenParticipantLeft(id));
return;
}
APP.store.dispatch(participantLeft(id, room));
logger.log('USER %s LEFT', id, user);
APP.API.notifyUserLeft(id);

View File

@ -175,6 +175,10 @@ var config = {
// Whether to enable live streaming or not.
// liveStreamingEnabled: false,
// Transcription (in interface_config,
// subtitles and buttons can be configured)
transcribingEnabled: false,
// Misc
// Default value for the channel "last N" attribute. -1 for unlimited.

View File

@ -24,6 +24,7 @@
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-arrow_back:before {
content: "\e5c4";
}
@ -216,3 +217,6 @@
.icon-tiles-one:before {
content: "\e92f";
}
.icon-closed_caption:before {
content: "\e930";
}

Binary file not shown.

View File

@ -74,4 +74,5 @@
<glyph unicode="&#xe92d;" glyph-name="speaker" d="M0 512c0-282.795 229.205-512 512-512s512 229.205 512 512c0 282.795-229.205 512-512 512s-512-229.205-512-512zM525.005 759.362c-20.475 24.944-16.326 61.342 9.268 81.297s62.94 15.911 83.416-9.033c16.036-19.536 38.593-52.97 60.894-97.797 81.621-164.065 89.461-340.992-26.857-506.352-8.384-11.919-17.386-23.69-27.012-35.307-20.593-24.851-57.959-28.727-83.458-8.657s-29.476 56.487-8.882 81.338c7.686 9.275 14.833 18.621 21.455 28.035 88.66 126.041 82.71 260.306 17.953 390.475-10.599 21.305-21.94 40.51-33.198 57.196-6.515 9.657-11.322 16.057-13.578 18.805zM353.479 647.46c-19.353 24.679-15.129 60.448 9.434 79.893s60.164 15.2 79.517-9.479c9.635-12.287 22.577-32.644 35.209-60.034 50.35-109.176 50.35-231.689-33.639-349.612-18.198-25.551-53.566-31.441-78.997-13.157s-31.294 53.819-13.096 79.37c57.564 80.822 57.564 160.581 22.983 235.565-8.601 18.65-16.892 31.691-21.412 37.455z" />
<glyph unicode="&#xe92e;" glyph-name="tiles-many" d="M113.778 1024h227.556c62.838 0 113.778-50.94 113.778-113.778v-227.556c0-62.838-50.94-113.778-113.778-113.778h-227.556c-62.838 0-113.778 50.94-113.778 113.778v227.556c0 62.838 50.94 113.778 113.778 113.778zM170.667 910.222c-31.419 0-56.889-25.47-56.889-56.889v-113.778c0-31.419 25.47-56.889 56.889-56.889h113.778c31.419 0 56.889 25.47 56.889 56.889v113.778c0 31.419-25.47 56.889-56.889 56.889h-113.778zM113.778 455.111h227.556c62.838 0 113.778-50.94 113.778-113.778v-227.556c0-62.838-50.94-113.778-113.778-113.778h-227.556c-62.838 0-113.778 50.94-113.778 113.778v227.556c0 62.838 50.94 113.778 113.778 113.778zM170.667 341.333c-31.419 0-56.889-25.47-56.889-56.889v-113.778c0-31.419 25.47-56.889 56.889-56.889h113.778c31.419 0 56.889 25.47 56.889 56.889v113.778c0 31.419-25.47 56.889-56.889 56.889h-113.778zM682.667 1024h227.556c62.838 0 113.778-50.94 113.778-113.778v-227.556c0-62.838-50.94-113.778-113.778-113.778h-227.556c-62.838 0-113.778 50.94-113.778 113.778v227.556c0 62.838 50.94 113.778 113.778 113.778zM739.556 910.222c-31.419 0-56.889-25.47-56.889-56.889v-113.778c0-31.419 25.47-56.889 56.889-56.889h113.778c31.419 0 56.889 25.47 56.889 56.889v113.778c0 31.419-25.47 56.889-56.889 56.889h-113.778zM682.667 455.111h227.556c62.838 0 113.778-50.94 113.778-113.778v-227.556c0-62.838-50.94-113.778-113.778-113.778h-227.556c-62.838 0-113.778 50.94-113.778 113.778v227.556c0 62.838 50.94 113.778 113.778 113.778zM739.556 341.333c-31.419 0-56.889-25.47-56.889-56.889v-113.778c0-31.419 25.47-56.889 56.889-56.889h113.778c31.419 0 56.889 25.47 56.889 56.889v113.778c0 31.419-25.47 56.889-56.889 56.889h-113.778z" />
<glyph unicode="&#xe92f;" glyph-name="tiles-one" d="M170.667 810.667h682.667c47.128 0 85.333-38.205 85.333-85.333v-426.667c0-47.128-38.205-85.333-85.333-85.333h-682.667c-47.128 0-85.333 38.205-85.333 85.333v426.667c0 47.128 38.205 85.333 85.333 85.333zM213.333 725.333c-23.564 0-42.667-19.103-42.667-42.667v-341.333c0-23.564 19.103-42.667 42.667-42.667h597.333c23.564 0 42.667 19.103 42.667 42.667v341.333c0 23.564-19.103 42.667-42.667 42.667h-597.333z" />
<glyph unicode="&#xe930;" glyph-name="closed_caption" d="M768 554v44c0 24-18 42-42 42h-128c-24 0-44-18-44-42v-172c0-24 20-42 44-42h128c24 0 42 18 42 42v44h-64v-22h-86v128h86v-22h64zM470 554v44c0 24-20 42-44 42h-128c-24 0-42-18-42-42v-172c0-24 18-42 42-42h128c24 0 44 18 44 42v44h-64v-22h-86v128h86v-22h64zM810 854c46 0 86-40 86-86v-512c0-46-40-86-86-86h-596c-48 0-86 40-86 86v512c0 46 38 86 86 86h596z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,35 @@
{
"IcoMoonType": "selection",
"icons": [
{
"icon": {
"paths": [
"M768 470v-44c0-24-18-42-42-42h-128c-24 0-44 18-44 42v172c0 24 20 42 44 42h128c24 0 42-18 42-42v-44h-64v22h-86v-128h86v22h64zM470 470v-44c0-24-20-42-44-42h-128c-24 0-42 18-42 42v172c0 24 18 42 42 42h128c24 0 44-18 44-42v-44h-64v22h-86v-128h86v22h64zM810 170c46 0 86 40 86 86v512c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-512c0-46 38-86 86-86h596z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"closed_caption"
],
"grid": 24
},
"attrs": [
{}
],
"properties": {
"order": 1,
"id": 0,
"prevSize": 24,
"code": 59696,
"name": "closed_caption"
},
"setIdx": 0,
"setId": 2,
"iconIdx": 0
},
{
"icon": {
"paths": [
@ -23,10 +52,10 @@
"order": 1377,
"id": 1065,
"name": "tiles-many",
"prevSize": 32,
"prevSize": 24,
"code": 59694
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 0
},
@ -52,10 +81,10 @@
"order": 1378,
"id": 1064,
"name": "tiles-one",
"prevSize": 32,
"prevSize": 24,
"code": 59695
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 1
},
@ -78,13 +107,13 @@
"ligatures": "clear, close",
"id": 157,
"order": 1313,
"prevSize": 32,
"prevSize": 24,
"code": 58829,
"name": "close"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 50
"iconIdx": 2
},
{
"icon": {
@ -105,13 +134,13 @@
"ligatures": "launch, open_in_new",
"id": 1047,
"order": 1314,
"prevSize": 32,
"prevSize": 24,
"name": "open_in_new",
"code": 59550
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 51
"iconIdx": 3
},
{
"icon": {
@ -132,13 +161,13 @@
"ligatures": "history, restore",
"id": 1048,
"order": 1315,
"prevSize": 32,
"prevSize": 24,
"code": 59571,
"name": "restore"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 52
"iconIdx": 4
},
{
"icon": {
@ -159,13 +188,13 @@
"ligatures": "chevron_right, navigate_next",
"id": 1049,
"order": 1316,
"prevSize": 32,
"prevSize": 24,
"code": 58377,
"name": "navigate_next"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 53
"iconIdx": 5
},
{
"icon": {
@ -186,13 +215,13 @@
"ligatures": "menu",
"id": 1050,
"order": 1317,
"prevSize": 32,
"prevSize": 24,
"code": 58834,
"name": "menu"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 54
"iconIdx": 6
},
{
"icon": {
@ -213,13 +242,13 @@
"ligatures": "arrow_back",
"id": 1051,
"order": 1318,
"prevSize": 32,
"prevSize": 24,
"code": 58820,
"name": "arrow_back"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 55
"iconIdx": 7
},
{
"icon": {
@ -240,13 +269,13 @@
"ligatures": "chevron_left, navigate_before",
"id": 1052,
"order": 1319,
"prevSize": 32,
"prevSize": 24,
"code": 58376,
"name": "navigate_before"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 56
"iconIdx": 8
},
{
"icon": {
@ -267,13 +296,13 @@
"ligatures": "public",
"id": 1053,
"order": 1320,
"prevSize": 32,
"prevSize": 24,
"code": 59403,
"name": "public"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 57
"iconIdx": 9
},
{
"icon": {
@ -294,13 +323,13 @@
"ligatures": "event_note",
"id": 1054,
"order": 1321,
"prevSize": 32,
"prevSize": 24,
"code": 58902,
"name": "event_note"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 58
"iconIdx": 10
},
{
"icon": {
@ -321,13 +350,13 @@
"ligatures": "timer",
"id": 1055,
"order": 1322,
"prevSize": 32,
"prevSize": 24,
"code": 58405,
"name": "timer"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 59
"iconIdx": 11
},
{
"icon": {
@ -348,13 +377,13 @@
"ligatures": "bluetooth_audio, bluetooth_searching",
"id": 1056,
"order": 1323,
"prevSize": 32,
"prevSize": 24,
"code": 57770,
"name": "bluetooth"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 60
"iconIdx": 12
},
{
"icon": {
@ -375,13 +404,13 @@
"ligatures": "headset",
"id": 1057,
"order": 1324,
"prevSize": 32,
"prevSize": 24,
"code": 58128,
"name": "headset"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 61
"iconIdx": 13
},
{
"icon": {
@ -402,13 +431,13 @@
"ligatures": "phone_in_talk",
"id": 1058,
"order": 1325,
"prevSize": 32,
"prevSize": 24,
"code": 58909,
"name": "phone-talk"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 62
"iconIdx": 14
},
{
"icon": {
@ -429,13 +458,13 @@
"ligatures": "more_vert",
"id": 1059,
"order": 1326,
"prevSize": 32,
"prevSize": 24,
"code": 58836,
"name": "thumb-menu"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 63
"iconIdx": 15
},
{
"icon": {
@ -459,12 +488,12 @@
"order": 1327,
"id": 1060,
"name": "ninja",
"prevSize": 32,
"prevSize": 24,
"code": 59657
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 64
"iconIdx": 16
},
{
"icon": {
@ -485,13 +514,13 @@
"ligatures": "call, local_phone, phone",
"id": 1061,
"order": 1328,
"prevSize": 32,
"prevSize": 24,
"code": 57549,
"name": "phone"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 65
"iconIdx": 17
},
{
"icon": {
@ -512,13 +541,13 @@
"ligatures": "add",
"id": 1062,
"order": 1329,
"prevSize": 32,
"prevSize": 24,
"code": 57669,
"name": "add"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 66
"iconIdx": 18
},
{
"icon": {
@ -545,9 +574,9 @@
"prevSize": 32,
"code": 59693
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 2
"iconIdx": 19
},
{
"icon": {
@ -574,9 +603,9 @@
"prevSize": 32,
"code": 59692
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 3
"iconIdx": 20
},
{
"icon": {
@ -603,9 +632,9 @@
"prevSize": 32,
"code": 59691
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 4
"iconIdx": 21
},
{
"icon": {
@ -635,9 +664,9 @@
"prevSize": 32,
"code": 59690
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 5
"iconIdx": 22
},
{
"icon": {
@ -664,9 +693,9 @@
"prevSize": 32,
"code": 59648
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 6
"iconIdx": 23
},
{
"icon": {
@ -693,9 +722,9 @@
"prevSize": 32,
"code": 59687
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 7
"iconIdx": 24
},
{
"icon": {
@ -722,9 +751,9 @@
"prevSize": 32,
"code": 59688
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 8
"iconIdx": 25
},
{
"icon": {
@ -751,9 +780,9 @@
"prevSize": 32,
"code": 59689
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 9
"iconIdx": 26
},
{
"icon": {
@ -780,9 +809,9 @@
"prevSize": 32,
"code": 59686
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 10
"iconIdx": 27
},
{
"icon": {
@ -809,9 +838,9 @@
"prevSize": 32,
"code": 59682
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 11
"iconIdx": 28
},
{
"icon": {
@ -838,9 +867,9 @@
"prevSize": 32,
"code": 59651
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 12
"iconIdx": 29
},
{
"icon": {
@ -867,9 +896,9 @@
"prevSize": 32,
"code": 59677
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 13
"iconIdx": 30
},
{
"icon": {
@ -896,9 +925,9 @@
"prevSize": 32,
"code": 59676
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 14
"iconIdx": 31
},
{
"icon": {
@ -922,9 +951,9 @@
"code": 59649,
"name": "avatar"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 15
"iconIdx": 32
},
{
"icon": {
@ -948,9 +977,9 @@
"code": 59653,
"name": "hangup"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 16
"iconIdx": 33
},
{
"icon": {
@ -974,9 +1003,9 @@
"code": 59654,
"name": "chat"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 17
"iconIdx": 34
},
{
"icon": {
@ -1000,9 +1029,9 @@
"code": 59650,
"name": "download"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 18
"iconIdx": 35
},
{
"icon": {
@ -1026,9 +1055,9 @@
"code": 59655,
"name": "edit"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 19
"iconIdx": 36
},
{
"icon": {
@ -1052,9 +1081,9 @@
"code": 59656,
"name": "share-doc"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 20
"iconIdx": 37
},
{
"icon": {
@ -1078,9 +1107,9 @@
"code": 59652,
"name": "kick"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 21
"iconIdx": 38
},
{
"icon": {
@ -1104,9 +1133,9 @@
"code": 59679,
"name": "menu-up"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 22
"iconIdx": 39
},
{
"icon": {
@ -1130,9 +1159,9 @@
"code": 59680,
"name": "menu-down"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 23
"iconIdx": 40
},
{
"icon": {
@ -1156,9 +1185,9 @@
"code": 59659,
"name": "full-screen"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 24
"iconIdx": 41
},
{
"icon": {
@ -1182,9 +1211,9 @@
"code": 59660,
"name": "exit-full-screen"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 25
"iconIdx": 42
},
{
"icon": {
@ -1208,9 +1237,9 @@
"code": 59658,
"name": "star-full"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 26
"iconIdx": 43
},
{
"icon": {
@ -1234,9 +1263,9 @@
"code": 59661,
"name": "security"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 27
"iconIdx": 44
},
{
"icon": {
@ -1260,9 +1289,9 @@
"code": 59662,
"name": "security-locked"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 28
"iconIdx": 45
},
{
"icon": {
@ -1286,9 +1315,9 @@
"code": 59663,
"name": "reload"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 29
"iconIdx": 46
},
{
"icon": {
@ -1312,9 +1341,9 @@
"code": 59664,
"name": "microphone"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 30
"iconIdx": 47
},
{
"icon": {
@ -1338,9 +1367,9 @@
"code": 59665,
"name": "mic-empty"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 31
"iconIdx": 48
},
{
"icon": {
@ -1364,9 +1393,9 @@
"code": 59666,
"name": "mic-disabled"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 32
"iconIdx": 49
},
{
"icon": {
@ -1390,9 +1419,9 @@
"code": 59678,
"name": "raised-hand"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 33
"iconIdx": 50
},
{
"icon": {
@ -1416,9 +1445,9 @@
"code": 59675,
"name": "contactList"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 34
"iconIdx": 51
},
{
"icon": {
@ -1442,9 +1471,9 @@
"code": 59667,
"name": "link"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 35
"iconIdx": 52
},
{
"icon": {
@ -1468,9 +1497,9 @@
"code": 59668,
"name": "shared-video"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 36
"iconIdx": 53
},
{
"icon": {
@ -1494,9 +1523,9 @@
"code": 59669,
"name": "settings"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 37
"iconIdx": 54
},
{
"icon": {
@ -1520,9 +1549,9 @@
"code": 59670,
"name": "star"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 38
"iconIdx": 55
},
{
"icon": {
@ -1546,9 +1575,9 @@
"code": 59681,
"name": "switch-camera"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 39
"iconIdx": 56
},
{
"icon": {
@ -1572,9 +1601,9 @@
"code": 59671,
"name": "share-desktop"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 40
"iconIdx": 57
},
{
"icon": {
@ -1598,9 +1627,9 @@
"code": 59672,
"name": "camera"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 41
"iconIdx": 58
},
{
"icon": {
@ -1624,9 +1653,9 @@
"code": 59673,
"name": "camera-disabled"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 42
"iconIdx": 59
},
{
"icon": {
@ -1650,9 +1679,9 @@
"code": 59674,
"name": "volume"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 43
"iconIdx": 60
},
{
"icon": {
@ -1679,9 +1708,9 @@
"name": "recDisable",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 44
"iconIdx": 61
},
{
"icon": {
@ -1709,9 +1738,9 @@
"name": "recEnable",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 45
"iconIdx": 62
},
{
"icon": {
@ -1739,9 +1768,9 @@
"name": "presentation",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 46
"iconIdx": 63
},
{
"icon": {
@ -1765,9 +1794,9 @@
"code": 59685,
"name": "dialpad"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 47
"iconIdx": 64
},
{
"icon": {
@ -1791,9 +1820,9 @@
"code": 59683,
"name": "visibility"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 48
"iconIdx": 65
},
{
"icon": {
@ -1817,9 +1846,9 @@
"code": 59684,
"name": "visibility-off"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 49
"iconIdx": 66
}
],
"height": 1024,

View File

@ -45,10 +45,10 @@ var interfaceConfig = {
* jwt.
*/
TOOLBAR_BUTTONS: [
'microphone', 'camera', 'desktop', 'fullscreen', 'fodeviceselection', 'hangup',
'profile', 'info', 'chat', 'recording', 'livestreaming', 'etherpad',
'sharedvideo', 'settings', 'raisehand', 'videoquality', 'filmstrip',
'invite', 'feedback', 'stats', 'shortcuts'
'microphone', 'camera', 'closedcaptions', 'desktop', 'fullscreen',
'fodeviceselection', 'hangup', 'profile', 'info', 'chat', 'recording',
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts'
],
SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile' ],

View File

@ -81,6 +81,7 @@
"audioRoute": "Select the sound device",
"callQuality": "Manage call quality",
"chat": "Toggle chat window",
"cc": "Toggle subtitles",
"document": "Toggle shared document",
"feedback": "Leave feedback",
"fullScreen": "Toggle full screen",
@ -381,7 +382,8 @@
"shareYourScreenDisabled": "Screen sharing disabled.",
"shareYourScreenDisabledForGuest": "Guests can't screen share.",
"yourEntireScreen": "Your entire screen",
"applicationWindow": "Application window"
"applicationWindow": "Application window",
"transcribing": "Transcribing"
},
"email":
{
@ -448,6 +450,16 @@
"unavailable": "Oops! The __serviceName__ is currently unavailable. We're working on resolving the issue. Please try again later.",
"unavailableTitle": "Recording unavailable"
},
"transcribing":
{
"pending" : "Preparing to transcribe the meeting...",
"off" : "Transcribing stopped",
"error": "Transcribing failed. Please try again.",
"failedToStart": "Transcribing failed to start",
"tr": "TR",
"labelToolTip": "The meeting is being transcribed",
"ccButtonTooltip": "Start / Stop showing subtitles"
},
"liveStreaming":
{
"busy": "We're working on freeing streaming resources. Please try again in a few minutes.",

View File

@ -1,6 +1,35 @@
{
"IcoMoonType": "selection",
"icons": [
{
"icon": {
"paths": [
"M768 470v-44c0-24-18-42-42-42h-128c-24 0-44 18-44 42v172c0 24 20 42 44 42h128c24 0 42-18 42-42v-44h-64v22h-86v-128h86v22h64zM470 470v-44c0-24-20-42-44-42h-128c-24 0-42 18-42 42v172c0 24 18 42 42 42h128c24 0 44-18 44-42v-44h-64v22h-86v-128h86v22h64zM810 170c46 0 86 40 86 86v512c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-512c0-46 38-86 86-86h596z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"tags": [
"closed_caption"
],
"grid": 24
},
"attrs": [
{}
],
"properties": {
"order": 1,
"id": 0,
"prevSize": 24,
"code": 59696,
"name": "closed_caption"
},
"setIdx": 0,
"setId": 2,
"iconIdx": 0
},
{
"icon": {
"paths": [
@ -23,10 +52,10 @@
"order": 1377,
"id": 1065,
"name": "tiles-many",
"prevSize": 32,
"prevSize": 24,
"code": 59694
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 0
},
@ -52,10 +81,10 @@
"order": 1378,
"id": 1064,
"name": "tiles-one",
"prevSize": 32,
"prevSize": 24,
"code": 59695
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 1
},
@ -78,13 +107,13 @@
"ligatures": "clear, close",
"id": 157,
"order": 1313,
"prevSize": 32,
"prevSize": 24,
"code": 58829,
"name": "close"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 50
"iconIdx": 2
},
{
"icon": {
@ -105,13 +134,13 @@
"ligatures": "launch, open_in_new",
"id": 1047,
"order": 1314,
"prevSize": 32,
"prevSize": 24,
"name": "open_in_new",
"code": 59550
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 51
"iconIdx": 3
},
{
"icon": {
@ -132,13 +161,13 @@
"ligatures": "history, restore",
"id": 1048,
"order": 1315,
"prevSize": 32,
"prevSize": 24,
"code": 59571,
"name": "restore"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 52
"iconIdx": 4
},
{
"icon": {
@ -159,13 +188,13 @@
"ligatures": "chevron_right, navigate_next",
"id": 1049,
"order": 1316,
"prevSize": 32,
"prevSize": 24,
"code": 58377,
"name": "navigate_next"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 53
"iconIdx": 5
},
{
"icon": {
@ -186,13 +215,13 @@
"ligatures": "menu",
"id": 1050,
"order": 1317,
"prevSize": 32,
"prevSize": 24,
"code": 58834,
"name": "menu"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 54
"iconIdx": 6
},
{
"icon": {
@ -213,13 +242,13 @@
"ligatures": "arrow_back",
"id": 1051,
"order": 1318,
"prevSize": 32,
"prevSize": 24,
"code": 58820,
"name": "arrow_back"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 55
"iconIdx": 7
},
{
"icon": {
@ -240,13 +269,13 @@
"ligatures": "chevron_left, navigate_before",
"id": 1052,
"order": 1319,
"prevSize": 32,
"prevSize": 24,
"code": 58376,
"name": "navigate_before"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 56
"iconIdx": 8
},
{
"icon": {
@ -267,13 +296,13 @@
"ligatures": "public",
"id": 1053,
"order": 1320,
"prevSize": 32,
"prevSize": 24,
"code": 59403,
"name": "public"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 57
"iconIdx": 9
},
{
"icon": {
@ -294,13 +323,13 @@
"ligatures": "event_note",
"id": 1054,
"order": 1321,
"prevSize": 32,
"prevSize": 24,
"code": 58902,
"name": "event_note"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 58
"iconIdx": 10
},
{
"icon": {
@ -321,13 +350,13 @@
"ligatures": "timer",
"id": 1055,
"order": 1322,
"prevSize": 32,
"prevSize": 24,
"code": 58405,
"name": "timer"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 59
"iconIdx": 11
},
{
"icon": {
@ -348,13 +377,13 @@
"ligatures": "bluetooth_audio, bluetooth_searching",
"id": 1056,
"order": 1323,
"prevSize": 32,
"prevSize": 24,
"code": 57770,
"name": "bluetooth"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 60
"iconIdx": 12
},
{
"icon": {
@ -375,13 +404,13 @@
"ligatures": "headset",
"id": 1057,
"order": 1324,
"prevSize": 32,
"prevSize": 24,
"code": 58128,
"name": "headset"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 61
"iconIdx": 13
},
{
"icon": {
@ -402,13 +431,13 @@
"ligatures": "phone_in_talk",
"id": 1058,
"order": 1325,
"prevSize": 32,
"prevSize": 24,
"code": 58909,
"name": "phone-talk"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 62
"iconIdx": 14
},
{
"icon": {
@ -429,13 +458,13 @@
"ligatures": "more_vert",
"id": 1059,
"order": 1326,
"prevSize": 32,
"prevSize": 24,
"code": 58836,
"name": "thumb-menu"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 63
"iconIdx": 15
},
{
"icon": {
@ -459,12 +488,12 @@
"order": 1327,
"id": 1060,
"name": "ninja",
"prevSize": 32,
"prevSize": 24,
"code": 59657
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 64
"iconIdx": 16
},
{
"icon": {
@ -485,13 +514,13 @@
"ligatures": "call, local_phone, phone",
"id": 1061,
"order": 1328,
"prevSize": 32,
"prevSize": 24,
"code": 57549,
"name": "phone"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 65
"iconIdx": 17
},
{
"icon": {
@ -512,13 +541,13 @@
"ligatures": "add",
"id": 1062,
"order": 1329,
"prevSize": 32,
"prevSize": 24,
"code": 57669,
"name": "add"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 66
"iconIdx": 18
},
{
"icon": {
@ -545,9 +574,9 @@
"prevSize": 32,
"code": 59693
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 2
"iconIdx": 19
},
{
"icon": {
@ -574,9 +603,9 @@
"prevSize": 32,
"code": 59692
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 3
"iconIdx": 20
},
{
"icon": {
@ -603,9 +632,9 @@
"prevSize": 32,
"code": 59691
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 4
"iconIdx": 21
},
{
"icon": {
@ -635,9 +664,9 @@
"prevSize": 32,
"code": 59690
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 5
"iconIdx": 22
},
{
"icon": {
@ -664,9 +693,9 @@
"prevSize": 32,
"code": 59648
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 6
"iconIdx": 23
},
{
"icon": {
@ -693,9 +722,9 @@
"prevSize": 32,
"code": 59687
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 7
"iconIdx": 24
},
{
"icon": {
@ -722,9 +751,9 @@
"prevSize": 32,
"code": 59688
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 8
"iconIdx": 25
},
{
"icon": {
@ -751,9 +780,9 @@
"prevSize": 32,
"code": 59689
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 9
"iconIdx": 26
},
{
"icon": {
@ -780,9 +809,9 @@
"prevSize": 32,
"code": 59686
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 10
"iconIdx": 27
},
{
"icon": {
@ -809,9 +838,9 @@
"prevSize": 32,
"code": 59682
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 11
"iconIdx": 28
},
{
"icon": {
@ -838,9 +867,9 @@
"prevSize": 32,
"code": 59651
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 12
"iconIdx": 29
},
{
"icon": {
@ -867,9 +896,9 @@
"prevSize": 32,
"code": 59677
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 13
"iconIdx": 30
},
{
"icon": {
@ -896,9 +925,9 @@
"prevSize": 32,
"code": 59676
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 14
"iconIdx": 31
},
{
"icon": {
@ -922,9 +951,9 @@
"code": 59649,
"name": "avatar"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 15
"iconIdx": 32
},
{
"icon": {
@ -948,9 +977,9 @@
"code": 59653,
"name": "hangup"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 16
"iconIdx": 33
},
{
"icon": {
@ -974,9 +1003,9 @@
"code": 59654,
"name": "chat"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 17
"iconIdx": 34
},
{
"icon": {
@ -1000,9 +1029,9 @@
"code": 59650,
"name": "download"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 18
"iconIdx": 35
},
{
"icon": {
@ -1026,9 +1055,9 @@
"code": 59655,
"name": "edit"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 19
"iconIdx": 36
},
{
"icon": {
@ -1052,9 +1081,9 @@
"code": 59656,
"name": "share-doc"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 20
"iconIdx": 37
},
{
"icon": {
@ -1078,9 +1107,9 @@
"code": 59652,
"name": "kick"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 21
"iconIdx": 38
},
{
"icon": {
@ -1104,9 +1133,9 @@
"code": 59679,
"name": "menu-up"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 22
"iconIdx": 39
},
{
"icon": {
@ -1130,9 +1159,9 @@
"code": 59680,
"name": "menu-down"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 23
"iconIdx": 40
},
{
"icon": {
@ -1156,9 +1185,9 @@
"code": 59659,
"name": "full-screen"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 24
"iconIdx": 41
},
{
"icon": {
@ -1182,9 +1211,9 @@
"code": 59660,
"name": "exit-full-screen"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 25
"iconIdx": 42
},
{
"icon": {
@ -1208,9 +1237,9 @@
"code": 59658,
"name": "star-full"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 26
"iconIdx": 43
},
{
"icon": {
@ -1234,9 +1263,9 @@
"code": 59661,
"name": "security"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 27
"iconIdx": 44
},
{
"icon": {
@ -1260,9 +1289,9 @@
"code": 59662,
"name": "security-locked"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 28
"iconIdx": 45
},
{
"icon": {
@ -1286,9 +1315,9 @@
"code": 59663,
"name": "reload"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 29
"iconIdx": 46
},
{
"icon": {
@ -1312,9 +1341,9 @@
"code": 59664,
"name": "microphone"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 30
"iconIdx": 47
},
{
"icon": {
@ -1338,9 +1367,9 @@
"code": 59665,
"name": "mic-empty"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 31
"iconIdx": 48
},
{
"icon": {
@ -1364,9 +1393,9 @@
"code": 59666,
"name": "mic-disabled"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 32
"iconIdx": 49
},
{
"icon": {
@ -1390,9 +1419,9 @@
"code": 59678,
"name": "raised-hand"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 33
"iconIdx": 50
},
{
"icon": {
@ -1416,9 +1445,9 @@
"code": 59675,
"name": "contactList"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 34
"iconIdx": 51
},
{
"icon": {
@ -1442,9 +1471,9 @@
"code": 59667,
"name": "link"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 35
"iconIdx": 52
},
{
"icon": {
@ -1468,9 +1497,9 @@
"code": 59668,
"name": "shared-video"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 36
"iconIdx": 53
},
{
"icon": {
@ -1494,9 +1523,9 @@
"code": 59669,
"name": "settings"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 37
"iconIdx": 54
},
{
"icon": {
@ -1520,9 +1549,9 @@
"code": 59670,
"name": "star"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 38
"iconIdx": 55
},
{
"icon": {
@ -1546,9 +1575,9 @@
"code": 59681,
"name": "switch-camera"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 39
"iconIdx": 56
},
{
"icon": {
@ -1572,9 +1601,9 @@
"code": 59671,
"name": "share-desktop"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 40
"iconIdx": 57
},
{
"icon": {
@ -1598,9 +1627,9 @@
"code": 59672,
"name": "camera"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 41
"iconIdx": 58
},
{
"icon": {
@ -1624,9 +1653,9 @@
"code": 59673,
"name": "camera-disabled"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 42
"iconIdx": 59
},
{
"icon": {
@ -1650,9 +1679,9 @@
"code": 59674,
"name": "volume"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 43
"iconIdx": 60
},
{
"icon": {
@ -1679,9 +1708,9 @@
"name": "recDisable",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 44
"iconIdx": 61
},
{
"icon": {
@ -1709,9 +1738,9 @@
"name": "recEnable",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 45
"iconIdx": 62
},
{
"icon": {
@ -1739,9 +1768,9 @@
"name": "presentation",
"ligatures": ""
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 46
"iconIdx": 63
},
{
"icon": {
@ -1765,9 +1794,9 @@
"code": 59685,
"name": "dialpad"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 47
"iconIdx": 64
},
{
"icon": {
@ -1791,9 +1820,9 @@
"code": 59683,
"name": "visibility"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 48
"iconIdx": 65
},
{
"icon": {
@ -1817,9 +1846,9 @@
"code": 59684,
"name": "visibility-off"
},
"setIdx": 0,
"setIdx": 1,
"setId": 1,
"iconIdx": 49
"iconIdx": 66
}
],
"height": 1024,

View File

@ -98,3 +98,25 @@ export const PARTICIPANT_UPDATED = Symbol('PARTICIPANT_UPDATED');
* }
*/
export const PIN_PARTICIPANT = Symbol('PIN_PARTICIPANT');
/**
* Action to signal that a hidden participant has joined.
*
* {
* type: HIDDEN_PARTICIPANT_JOINED,
* participant: Participant
* }
*/
export const HIDDEN_PARTICIPANT_JOINED = Symbol('HIDDEN_PARTICIPANT_JOINED');
/**
* Action to handle case when hidden participant leaves.
*
* {
* type: PARTICIPANT_LEFT,
* participant: {
* id: string
* }
* }
*/
export const HIDDEN_PARTICIPANT_LEFT = Symbol('HIDDEN_PARTICIPANT_LEFT');

View File

@ -7,6 +7,8 @@ import { showNotification } from '../../notifications';
import {
DOMINANT_SPEAKER_CHANGED,
HIDDEN_PARTICIPANT_JOINED,
HIDDEN_PARTICIPANT_LEFT,
KICK_PARTICIPANT,
MUTE_REMOTE_PARTICIPANT,
PARTICIPANT_DISPLAY_NAME_CHANGED,
@ -276,6 +278,42 @@ export function participantJoined(participant) {
};
}
/**
* Action to signal that a hidden participant has joined the conference.
*
* @param {string} id - The id of the participant.
* @param {string} displayName - The display name, or undefined when
* unknown.
* @returns {{
* type: HIDDEN_PARTICIPANT_JOINED,
* displayName: string,
* id: string
* }}
*/
export function hiddenParticipantJoined(id, displayName) {
return {
type: HIDDEN_PARTICIPANT_JOINED,
id,
displayName
};
}
/**
* Action to signal that a hidden participant has left the conference.
*
* @param {string} id - The id of the participant.
* @returns {{
* type: HIDDEN_PARTICIPANT_LEFT,
* id: string
* }}
*/
export function hiddenParticipantLeft(id) {
return {
type: HIDDEN_PARTICIPANT_LEFT,
id
};
}
/**
* Action to signal that a participant has left.
*

View File

@ -5,6 +5,7 @@ import React, { Component } from 'react';
import { isFilmstripVisible } from '../../filmstrip';
import { RecordingLabel } from '../../recording';
import { VideoQualityLabel } from '../../video-quality';
import { TranscribingLabel } from '../../transcribing/';
/**
* The type of the React {@code Component} props of {@link AbstractLabels}.
@ -50,6 +51,18 @@ export default class AbstractLabels<P: Props, S> extends Component<P, S> {
<VideoQualityLabel />
);
}
/**
* Renders the {@code TranscribingLabel}.
*
* @returns {React$Element}
* @protected
*/
_renderTranscribingLabel() {
return (
<TranscribingLabel />
);
}
}
/**

View File

@ -85,6 +85,9 @@ class Labels extends AbstractLabels<Props, State> {
this._renderRecordingLabel(
JitsiRecordingConstants.mode.STREAM)
}
{
this._renderTranscribingLabel()
}
{
this._renderVideoQualityLabel()
}
@ -95,6 +98,8 @@ class Labels extends AbstractLabels<Props, State> {
_renderRecordingLabel: string => React$Element<*>
_renderVideoQualityLabel: () => React$Element<*>
_renderTranscribingLabel: () => React$Element<*>
}
export default connect(_mapStateToProps)(Labels);

View File

@ -14,7 +14,8 @@ import { translate } from '../../../base/i18n';
import {
getLocalParticipant,
getParticipants,
participantUpdated
participantUpdated,
isLocalParticipantModerator
} from '../../../base/participants';
import { getLocalVideoTrack, toggleScreensharing } from '../../../base/tracks';
import { ChatCounter } from '../../../chat';
@ -56,6 +57,9 @@ import OverflowMenuItem from './OverflowMenuItem';
import OverflowMenuProfileItem from './OverflowMenuProfileItem';
import ToolbarButton from './ToolbarButton';
import VideoMuteButton from '../VideoMuteButton';
import {
ClosedCaptionButton
} from '../../../transcribing';
/**
* The type of the React {@code Component} props of {@link Toolbox}.
@ -144,6 +148,11 @@ type Props = {
*/
_sharingVideo: boolean,
/**
* Whether or not transcribing is enabled.
*/
_transcribingEnabled: boolean,
/**
* Flag showing whether toolbar is visible.
*/
@ -302,6 +311,7 @@ class Toolbox extends Component<Props> {
_chatOpen,
_hideInviteButton,
_overflowMenuVisible,
_transcribingEnabled,
_raisedHand,
_visible,
_visibleButtons,
@ -344,6 +354,11 @@ class Toolbox extends Component<Props> {
tooltip = { t('toolbar.chat') } />
<ChatCounter />
</div> }
{
_transcribingEnabled
&& this._shouldShowButton('closedcaptions')
&& <ClosedCaptionButton />
}
</div>
<div className = 'button-group-center'>
<AudioMuteButton
@ -990,6 +1005,9 @@ function _mapStateToProps(state) {
callStatsID,
iAmRecorder
} = state['features/base/config'];
let {
transcribingEnabled
} = state['features/base/config'];
const sharedVideoStatus = state['features/shared-video'].status;
const { current } = state['features/side-panel'];
const {
@ -1006,6 +1024,9 @@ function _mapStateToProps(state) {
let desktopSharingDisabledTooltipKey;
transcribingEnabled
= isLocalParticipantModerator(state) && transcribingEnabled;
if (state['features/base/config'].enableFeaturesBasedOnToken) {
// we enable desktop sharing if any participant already have this
// feature enabled
@ -1040,6 +1061,7 @@ function _mapStateToProps(state) {
_overflowMenuVisible: overflowMenuVisible,
_raisedHand: localParticipant.raisedHand,
_screensharing: localVideo && localVideo.videoType === 'desktop',
_transcribingEnabled: transcribingEnabled,
_sharingVideo: sharedVideoStatus === 'playing'
|| sharedVideoStatus === 'start'
|| sharedVideoStatus === 'pause',

View File

@ -0,0 +1,78 @@
/**
* The type of Redux action triggering the transcriber to join (be 'dialed' in)
*
* {
* type: DIAL_TRANSCRIBER
* }
* @public
*/
export const DIAL_TRANSCRIBER = Symbol('DIAL_TRANSCRIBER');
/**
* The type of Redux action triggering the transcriber to leave.
*
* {
* type: STOP_TRANSCRBIBING
* }
* @public
*/
export const STOP_TRANSCRIBING = Symbol('STOP_TRANSCRBIBING');
/**
* The type of Redux action triggering storage of participantId of transcriber,
* so that it can later be kicked
*
* {
* type: TRANSCRIBER_JOINED,
* participantId: String
* }
* @private
*/
export const _TRANSCRIBER_JOINED = Symbol('TRANSCRIBER_JOINED');
/**
* The type of Redux action signalling that the transcriber has left
*
* {
* type: TRANSCRIBER_LEFT,
* participantId: String
* }
* @private
*/
export const _TRANSCRIBER_LEFT = Symbol('TRANSCRIBER_LEFT');
/**
* The type of a Redux action signalling that a hidden participant has joined,
* which can be candidate for being a transcriber.
*
* {
* type: _POTENTIAL_TRANSCRIBER_JOINED,
* }
* @private
*/
export const _POTENTIAL_TRANSCRIBER_JOINED
= Symbol('POTENTIAL_TRANSCRIBER_JOINED');
/**
* The type of a Redux action signalling that dialing the transcriber failed.
*
* {
* type: _DIAL_ERROR,
* }
* @private
*/
export const _DIAL_ERROR = Symbol('DIAL_ERROR');
/**
* The type of Redux action which sets the pending transcribing notification UID
* to use it for when hiding the notification is necessary, or unsets it when
* undefined (or no param) is passed.
*
* {
* type: SET_PENDING_TRANSCRIBING_NOTIFICATION_UID,
* uid: ?number
* }
* @public
*/
export const SET_PENDING_TRANSCRIBING_NOTIFICATION_UID
= Symbol('SET_PENDING_TRANSCRIBING_NOTIFICATION_UID');

View File

@ -0,0 +1,189 @@
// @flow
import {
_DIAL_ERROR,
_POTENTIAL_TRANSCRIBER_JOINED,
_TRANSCRIBER_JOINED,
_TRANSCRIBER_LEFT,
DIAL_TRANSCRIBER,
SET_PENDING_TRANSCRIBING_NOTIFICATION_UID,
STOP_TRANSCRIBING
} from './actionTypes';
import {
hideNotification,
showErrorNotification,
showNotification
} from '../notifications';
/**
* Dial the transcriber into the room.
*
* @public
* @returns {{
* type: DIAL_TRANSCRIBER
* }}
*/
export function dialTranscriber() {
return {
type: DIAL_TRANSCRIBER
};
}
/**
* Stop the transcribing by kicking the transcriber participant.
*
* @returns {{
* type: STOP_TRANSCRIBING
* }}
*/
export function stopTranscribing() {
return {
type: STOP_TRANSCRIBING
};
}
/**
* Notify that the transcriber, with a unique ID, has joined.
*
* @param {string} participantId - The participant id of the transcriber.
* @returns {{
* type: _TRANSCRIBER_JOINED,
* participantId: string
* }}
*/
export function transcriberJoined(participantId: string) {
return {
type: _TRANSCRIBER_JOINED,
transcriberJID: participantId
};
}
/**
* Notify that the transcriber, with a unique ID, has left.
*
* @param {string} participantId - The participant id of the transcriber.
* @returns {{
* type: _TRANSCRIBER_LEFT,
* participantId: string
* }}
*/
export function transcriberLeft(participantId: string) {
return {
type: _TRANSCRIBER_LEFT,
transcriberJID: participantId
};
}
/**
* Notify that a potential transcriber, with a unique ID, has joined.
*
* @param {string} participantId - The participant id of the transcriber.
* @returns {{
* type: _POTENTIAL_TRANSCRIBER_JOINED,
* participantId: string
* }}
*/
export function potentialTranscriberJoined(participantId: string) {
return {
type: _POTENTIAL_TRANSCRIBER_JOINED,
transcriberJID: participantId
};
}
/**
* Notify that dialing the transcriber resulted in an error.
*
* @returns {{
* type: _DIAL_ERROR
* }}
*/
export function dialError() {
return {
type: _DIAL_ERROR
};
}
/**
* Signals that the pending transcribing notification should be shown on the
* screen.
*
* @returns {Function}
*/
export function showPendingTranscribingNotification() {
return (dispatch: Function) => {
const showNotificationAction = showNotification({
descriptionKey: 'transcribing.pending',
isDismissAllowed: false,
titleKey: 'dialog.transcribing'
});
dispatch(showNotificationAction);
dispatch(setPendingTranscribingNotificationUid(
showNotificationAction.uid));
};
}
/**
* Sets UID of the the pending transcribing notification to use it when hiding
* the notification is necessary, or unsets it when
* undefined (or no param) is passed.
*
* @param {?number} uid - The UID of the notification.
* redux.
* @returns {{
* type: SET_PENDING_TRANSCRIBING_NOTIFICATION_UID,
* uid: number
* }}
*/
export function setPendingTranscribingNotificationUid(uid: ?number) {
return {
type: SET_PENDING_TRANSCRIBING_NOTIFICATION_UID,
uid
};
}
/**
* Signals that the pending transcribing notification should be removed from the
* screen.
*
* @returns {Function}
*/
export function hidePendingTranscribingNotification() {
return (dispatch: Function, getState: Function) => {
const { pendingNotificationUid } = getState()['features/transcribing'];
if (pendingNotificationUid) {
dispatch(hideNotification(pendingNotificationUid));
dispatch(setPendingTranscribingNotificationUid());
}
};
}
/**
* Signals that the stopped transcribing notification should be shown on the
* screen for a 2500 ms.
*
* @returns {showNotification}
*/
export function showStoppedTranscribingNotification() {
return showNotification({
descriptionKey: 'transcribing.off',
titleKey: 'dialog.transcribing'
}, 2500);
}
/**
* Signals that the transcribing error notification should be shown.
*
* @returns {showErrorNotification}
*/
export function showTranscribingError() {
return showErrorNotification({
descriptionKey: 'transcribing.error',
titleKey: 'transcribing.failedToStart'
});
}

View File

@ -0,0 +1,131 @@
// @flow
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { translate } from '../../base/i18n/index';
import { ToolbarButton } from '../../toolbox/';
import { dialTranscriber, stopTranscribing } from '../actions';
import { createToolbarEvent, sendAnalytics } from '../../analytics';
/**
* The type of the React {@code Component} props of {@link TranscribingLabel}.
*/
type Props = {
/**
* Invoked to obtain translated strings.
*/
t: Function,
/**
* Invoked to Dispatch an Action to the redux store.
*/
dispatch: Function,
/**
* Boolean value indicating current transcribing status
*/
_transcribing: boolean,
/**
* Boolean value indicating current dialing status
*/
_dialing: boolean
};
/**
* React Component for displaying a label when a transcriber is in the
* conference.
*
* @extends Component
*/
class ClosedCaptionButton extends Component<Props> {
/**
* Initializes a new {@code ClosedCaptionButton} instance.
*
* @param {Props} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Props) {
super(props);
// Bind event handler so it is only bound once for every instance.
this._onToggleButton = this._onToggleButton.bind(this);
}
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
const { _dialing, _transcribing, t } = this.props;
const iconClass = `icon-closed_caption ${_dialing || _transcribing
? 'toggled' : ''}`;
return (
<ToolbarButton
accessibilityLabel
= { t('toolbar.accessibilityLabel.cc') }
iconName = { iconClass }
onClick = { this._onToggleButton }
tooltip = { t('transcribing.ccButtonTooltip') } />
);
}
_onToggleButton: () => void;
/**
* Dispatch actions for starting or stopping transcription, based on
* current state.
*
* @private
* @returns {void}
*/
_onToggleButton() {
const { _transcribing, _dialing, dispatch } = this.props;
sendAnalytics(createToolbarEvent(
'transcribing.ccButton',
{
'is_transcribing': Boolean(_transcribing),
'is_dialing': Boolean(_dialing)
}));
if (_dialing) {
return;
}
if (_transcribing) {
dispatch(stopTranscribing());
} else {
dispatch(dialTranscriber());
}
}
}
/**
* Maps (parts of) the Redux state to the associated props for the
* {@code ClosedCaptionButton} component.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* }}
*/
function _mapStateToProps(state) {
const { isTranscribing, isDialing } = state['features/transcribing'];
return {
_transcribing: isTranscribing,
_dialing: isDialing
};
}
export default translate(connect(_mapStateToProps)(ClosedCaptionButton));

View File

@ -0,0 +1,75 @@
// @flow
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { translate } from '../../base/i18n/index';
import { CircularLabel } from '../../base/label/index';
import Tooltip from '@atlaskit/tooltip';
/**
* The type of the React {@code Component} props of {@link TranscribingLabel}.
*/
type Props = {
/**
* Invoked to obtain translated strings.
*/
t: Function,
/**
* Boolean value indicating current transcribing status
*/
_transcribing: boolean
};
/**
* React Component for displaying a label when a transcriber is in the
* conference.
*
* @extends Component
*/
class TranscribingLabel extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*
* @inheritdoc
* @returns {ReactElement}
*/
render() {
if (!this.props._transcribing) {
return null;
}
return (
<Tooltip
content = { this.props.t('transcribing.labelToolTip') }
position = { 'left' }>
<CircularLabel
className = 'recording-label'
label = { this.props.t('transcribing.tr') } />
</Tooltip>
);
}
}
/**
* Maps (parts of) the Redux state to the associated props for the
* {@code TranscribingLabel} component.
*
* @param {Object} state - The Redux state.
* @private
* @returns {{
* }}
*/
function _mapStateToProps(state) {
const { isTranscribing } = state['features/transcribing'];
return {
_transcribing: isTranscribing
};
}
export default translate(connect(_mapStateToProps)(TranscribingLabel));

View File

@ -0,0 +1,2 @@
export { default as TranscribingLabel } from './TranscribingLabel';
export { default as ClosedCaptionButton } from './ClosedCaptionButton';

View File

@ -0,0 +1,5 @@
export * from './actions';
export * from './components';
import './middleware';
import './reducer';

View File

@ -0,0 +1,100 @@
// @flow
import { MiddlewareRegistry } from '../base/redux';
import {
_TRANSCRIBER_LEFT,
DIAL_TRANSCRIBER,
STOP_TRANSCRIBING
} from './actionTypes';
import {
dialError,
hidePendingTranscribingNotification,
potentialTranscriberJoined,
showPendingTranscribingNotification,
showStoppedTranscribingNotification,
showTranscribingError,
transcriberJoined,
transcriberLeft
} from './actions';
import {
HIDDEN_PARTICIPANT_JOINED,
HIDDEN_PARTICIPANT_LEFT,
PARTICIPANT_UPDATED
} from './../base/participants';
declare var APP: Object;
const TRANSCRIBER_DIAL_COMMAND = 'jitsi_meet_transcribe';
const TRANSCRIBER_DISPLAY_NAME = 'Transcriber';
/**
* Implements the middleware of the feature transcribing.
*
* @param {Store} store - The redux store.
* @returns {Function}
*/
// eslint-disable-next-line no-unused-vars
MiddlewareRegistry.register(store => next => action => {
const {
isDialing,
isTranscribing,
transcriberJID,
potentialTranscriberJIDs
} = store.getState()['features/transcribing'];
const { conference } = store.getState()['features/base/conference'];
switch (action.type) {
case DIAL_TRANSCRIBER:
if (!(isDialing || isTranscribing)) {
store.dispatch(showPendingTranscribingNotification());
conference.room.dial(TRANSCRIBER_DIAL_COMMAND).catch(
() => {
store.dispatch(dialError());
store.dispatch(hidePendingTranscribingNotification());
store.dispatch(showTranscribingError());
}
);
}
break;
case STOP_TRANSCRIBING:
if (isTranscribing) {
const participant = conference.getParticipantById(transcriberJID);
conference.room.kick(participant.getJid());
}
break;
case _TRANSCRIBER_LEFT:
store.dispatch(showStoppedTranscribingNotification());
break;
case HIDDEN_PARTICIPANT_JOINED:
if (action.displayName
&& action.displayName === TRANSCRIBER_DISPLAY_NAME) {
store.dispatch(transcriberJoined(action.id));
} else {
store.dispatch(potentialTranscriberJoined(action.id));
}
break;
case HIDDEN_PARTICIPANT_LEFT:
if (action.id === transcriberJID) {
store.dispatch(transcriberLeft(action.id));
}
break;
case PARTICIPANT_UPDATED: {
const { participant } = action;
if (potentialTranscriberJIDs.includes(participant.id)
&& participant.name === TRANSCRIBER_DISPLAY_NAME) {
store.dispatch(transcriberJoined(participant.id));
store.dispatch(hidePendingTranscribingNotification());
}
break;
}
}
return next(action);
});

View File

@ -0,0 +1,115 @@
import { ReducerRegistry } from '../base/redux';
import {
_DIAL_ERROR,
_TRANSCRIBER_JOINED,
_TRANSCRIBER_LEFT,
_POTENTIAL_TRANSCRIBER_JOINED,
DIAL_TRANSCRIBER,
SET_PENDING_TRANSCRIBING_NOTIFICATION_UID,
STOP_TRANSCRIBING
} from '../transcribing/actionTypes';
/**
* Returns initial state for transcribing feature part of Redux store.
*
* @returns {{
* isTranscribing: boolean,
* isDialing: boolean,
* transcriberJID: null,
* potentialTranscriberJIDs: Array
* }}
* @private
*/
function _getInitialState() {
return {
/**
* Indicates whether there is currently an active transcriber in the
* room
*
* @type {boolean}
*/
isTranscribing: false,
/**
* Indicates whether the transcriber has been dialed into the room and
* we're currently awaiting successfull joining or failure of joining
*
* @type {boolean}
*/
isDialing: false,
/**
* Indicates whether the transcribing feature is in the process of
* terminating; the transcriber has been told to leave.
*/
isTerminating: false,
/**
* The JID of the active transcriber
*
* @type { string }
*/
transcriberJID: null,
/**
* A list containing potential JID's of transcriber participants
*
* @type { Array }
*/
potentialTranscriberJIDs: []
};
}
/**
* Reduces the Redux actions of the feature features/transcribing.
*/
ReducerRegistry.register('features/transcribing',
(state = _getInitialState(), action) => {
switch (action.type) {
case DIAL_TRANSCRIBER:
return {
...state,
isDialing: true
};
case STOP_TRANSCRIBING:
return {
...state,
isTerminating: true
};
case _DIAL_ERROR:
return {
...state,
isDialing: false,
potentialTranscriberJIDs: []
};
case _TRANSCRIBER_JOINED:
return {
...state,
isTranscribing: true,
isDialing: false,
transcriberJID: action.transcriberJID
};
case _TRANSCRIBER_LEFT:
return {
...state,
isTerminating: false,
isTranscribing: false,
transcriberJID: undefined,
potentialTranscriberJIDs: []
};
case _POTENTIAL_TRANSCRIBER_JOINED:
return {
...state,
potentialTranscriberJIDs:
[ action.transcriberJID ]
.concat(state.potentialTranscriberJIDs)
};
case SET_PENDING_TRANSCRIBING_NOTIFICATION_UID:
return {
...state,
pendingNotificationUid: action.uid
};
default:
return state;
}
});