Quellcode durchsuchen

feat(connection-indicator): implement automatic hiding on good connection (#2009)

* ref(connection-stats): use PropTypes package

* feat(connection-stats): display a summary of the connection quality

* feat(connection-indicator): show empty bars for interrupted connection

* feat(connection-indicator): change background color based on status

* feat(connection-indicator): implement automatic hiding on good connection

* fix(connection-indicator): explicitly set font size

Currently non-react code will set an icon size on ConnectionIndicator.
This doesn't work on initial call join in vertical filmstrip after
some changes to support hiding the indicator. The chosen fix is
passing in the icon size to mirror what would happe with full
filmstrip reactification.

* ref(connection-stats): rename statuses

* feat(connection-indicator): make hiding behavior configurable

The original implementation made the auto hiding of the indicator
configured in interfaceConfig.

* fix(connection-indicator): readd class expected by torture tests

* fix(connection-indicator): change connection quality display styling

Bold the connection summary in the stats popover so it stands out.
Change the summaries so there are only three--strong, nonoptimal,
poor.

* fix(connection-indicator): gray background on lost connection

* feat(icons): add new gsm bars icon

* feat(connection-indicator): use new 3-bar icon

* ref(icons): remove icon-connection and icon-connection-lost

Both have been replaced by icon-gsm-bars so they are not
being referenced anymore. Mobile looks to have connect-lost
as a separate icon in font-icons/jitsi.json.
j8
virtuacoplenny vor 7 Jahren
Ursprung
Commit
483e2ee202

+ 5
- 0
css/_connection-info.scss Datei anzeigen

37
         color: $downloadConnectionIconColor;
37
         color: $downloadConnectionIconColor;
38
     }
38
     }
39
 
39
 
40
+    &__status
41
+    {
42
+        font-weight: bold;
43
+    }
44
+
40
     &__upload
45
     &__upload
41
     {
46
     {
42
         @extend .connection-info__icon;
47
         @extend .connection-info__icon;

+ 3
- 6
css/_font.scss Datei anzeigen

127
 .icon-volume:before {
127
 .icon-volume:before {
128
     content: "\e91a";
128
     content: "\e91a";
129
 }
129
 }
130
-.icon-connection-lost:before {
131
-    content: "\e900";
132
-}
133
-.icon-connection:before {
134
-    content: "\e61a";
135
-}
136
 .icon-recDisable:before {
130
 .icon-recDisable:before {
137
     content: "\e613";
131
     content: "\e613";
138
 }
132
 }
160
 .icon-info:before {
154
 .icon-info:before {
161
     content: "\e922";
155
     content: "\e922";
162
 }
156
 }
157
+.icon-gsm-bars:before {
158
+    content: "\e926";
159
+}

+ 29
- 20
css/_videolayout_default.scss Datei anzeigen

87
          * positioning depends on the trigger (indicator icon).
87
          * positioning depends on the trigger (indicator icon).
88
          */
88
          */
89
         .indicator {
89
         .indicator {
90
+            margin-left: 5px;
90
             margin-top: $toolbarIconMargin;
91
             margin-top: $toolbarIconMargin;
91
         }
92
         }
92
 
93
 
94
             margin-left: $toolbarIconMargin;
95
             margin-left: $toolbarIconMargin;
95
         }
96
         }
96
 
97
 
97
-        .connection-indicator,
98
-        div.indicator-container,
99
-         {
100
-            margin-right: 4px;
101
-        }
102
-
103
-        div.indicator:last-child {
104
-            margin-right: 0;
105
-        }
106
-
107
         .indicator-container {
98
         .indicator-container {
108
             display: inline-block;
99
             display: inline-block;
109
             vertical-align: top;
100
             vertical-align: top;
138
                 left: 0;
129
                 left: 0;
139
                 @include transform(translate(0, -50%));
130
                 @include transform(translate(0, -50%));
140
 
131
 
141
-                &_empty
132
+                &_empty,
133
+                &_lost
142
                 {
134
                 {
143
                     color: #8B8B8B;/*#FFFFFF*/
135
                     color: #8B8B8B;/*#FFFFFF*/
144
                     overflow: hidden;
136
                     overflow: hidden;
145
                 }
137
                 }
146
 
138
 
147
-                &_lost
148
-                {
149
-                    color: #8B8B8B;
150
-                    overflow: visible;
151
-                }
152
-
153
                 &_full
139
                 &_full
154
                 {
140
                 {
155
                     @include topLeft();
141
                     @include topLeft();
163
                 }
149
                 }
164
             }
150
             }
165
 
151
 
166
-            .icon-connection,
167
-            .icon-connection-lost {
152
+            .icon-gsm-bars {
168
                 cursor: pointer;
153
                 cursor: pointer;
169
                 font-size: 1em;
154
                 font-size: 1em;
170
             }
155
             }
171
         }
156
         }
157
+
158
+        .hide-connection-indicator {
159
+            display: none;
160
+        }
172
     }
161
     }
173
 
162
 
174
     &__hoverOverlay {
163
     &__hoverOverlay {
355
 }
344
 }
356
 
345
 
357
 .connection-indicator {
346
 .connection-indicator {
358
-  background: $connectionIndicatorBg;
347
+    background: $connectionIndicatorBg;
348
+
349
+    &.status-high {
350
+        background: green;
351
+    }
352
+
353
+    &.status-med {
354
+        background: #FFD740;
355
+    }
356
+
357
+    &.status-lost {
358
+        background: gray;
359
+    }
360
+
361
+    &.status-low {
362
+        background: #BF2117;
363
+    }
364
+
365
+    &.status-other {
366
+        background: $connectionIndicatorBg;
367
+    }
359
 }
368
 }
360
 
369
 
361
 .remote-video-menu-trigger,
370
 .remote-video-menu-trigger,

BIN
fonts/jitsi.eot Datei anzeigen


+ 1
- 2
fonts/jitsi.svg Datei anzeigen

13
 <glyph unicode="&#xe603;" glyph-name="presentation" horiz-adv-x="1088" d="M952.495 1019.065h-818.689c-72.81 0-132.183-60.63-132.183-135.162v-750.719c0-74.473 59.372-135.101 132.183-135.101h818.686c72.936 0 132.314 60.625 132.314 135.101v750.722c0.003 74.532-59.378 135.159-132.311 135.159zM946.346 139.651h-806.14v737.822h806.015l0.126-737.822zM685.753 738.544h216.911v-566.758h-216.911v566.758zM428.672 610.002h216.911v-438.216h-216.911v438.216zM172.339 481.46h216.161v-309.677h-216.161v309.677z" />
13
 <glyph unicode="&#xe603;" glyph-name="presentation" horiz-adv-x="1088" d="M952.495 1019.065h-818.689c-72.81 0-132.183-60.63-132.183-135.162v-750.719c0-74.473 59.372-135.101 132.183-135.101h818.686c72.936 0 132.314 60.625 132.314 135.101v750.722c0.003 74.532-59.378 135.159-132.311 135.159zM946.346 139.651h-806.14v737.822h806.015l0.126-737.822zM685.753 738.544h216.911v-566.758h-216.911v566.758zM428.672 610.002h216.911v-438.216h-216.911v438.216zM172.339 481.46h216.161v-309.677h-216.161v309.677z" />
14
 <glyph unicode="&#xe613;" glyph-name="recDisable" horiz-adv-x="1140" d="M1123.444 1003.015c-23.593 26.481-64.131 28.989-90.74 5.395l-1008.269-893.436c-26.609-23.468-28.991-64.131-5.46-90.676 12.674-14.306 30.308-21.649 48.126-21.649 15.123 0 30.372 5.401 42.544 16.195l130.045 115.22c90.743-81.844 210.569-132.165 342.473-132.101 282.816 0.061 510.913 227.969 511.287 510.972 0.126 109.934-34.682 211.367-93.499 294.72l118.088 104.625c26.483 23.526 28.997 64.129 5.404 90.735zM944.422 513.818c0.128-200.922-161.896-363.201-362.509-362.952-87.56 0.123-167.573 31.151-230.061 82.569l331.277 293.509v-73.176c1.071-60.993 32.696-92.18 94.944-93.692 61.997 1.512 93.686 32.763 95.131 93.756v41.096h-72.227v-47.499c0.251-4.642-0.564-10.607-2.511-17.949-1.25-3.261-3.448-6.020-6.525-8.093-3.197-2.572-7.845-3.828-13.868-3.828-10.543 0.31-17.132 4.268-19.827 11.921-1.068 3.512-1.947 6.905-2.508 10.163-0.254 2.887-0.377 5.532-0.377 7.786v143.511l42.477 37.634c0.215-0.432 0.452-0.851 0.63-1.303 1.947-6.467 2.762-12.799 2.511-19.076v-36.772h72.227v30.121c-0.246 31.245-9.086 54.699-26.363 70.447l40.711 36.069c35.787-56.055 56.803-122.585 56.867-194.244zM239.795 395.47c-12.613 37.023-19.827 76.557-19.827 117.913-0.19 200.236 161.584 362.009 361.945 362.135 56.853 0 110.313-13.302 158.133-36.398l117.846 104.421c-79.444 50.952-173.758 80.817-275.292 80.948-283.377 0.181-511.354-227.729-511.789-511.675-0.126-79.567 18.636-154.679 51.137-221.882l117.848 104.538zM388.576 690.020h-97.514v-249.057l72.23 64.070v0.689h0.815l117.72 104.418c0 0.564 0.123 0.94 0.123 1.509 0.753 53.898-30.369 80.069-93.374 78.37zM405.959 625.517c1.942-2.767 3.074-6.469 3.323-11.112 0.312-4.452 0.438-9.6 0.438-15.246 0.251-10.916-0.689-19.83-2.949-26.985-2.952-7.594-10.983-11.357-24.159-11.357h-19.325v74.043h15.31c7.842 0 13.865-0.683 18.072-2.19 4.397-1.573 7.468-3.953 9.29-7.153z" />
14
 <glyph unicode="&#xe613;" glyph-name="recDisable" horiz-adv-x="1140" d="M1123.444 1003.015c-23.593 26.481-64.131 28.989-90.74 5.395l-1008.269-893.436c-26.609-23.468-28.991-64.131-5.46-90.676 12.674-14.306 30.308-21.649 48.126-21.649 15.123 0 30.372 5.401 42.544 16.195l130.045 115.22c90.743-81.844 210.569-132.165 342.473-132.101 282.816 0.061 510.913 227.969 511.287 510.972 0.126 109.934-34.682 211.367-93.499 294.72l118.088 104.625c26.483 23.526 28.997 64.129 5.404 90.735zM944.422 513.818c0.128-200.922-161.896-363.201-362.509-362.952-87.56 0.123-167.573 31.151-230.061 82.569l331.277 293.509v-73.176c1.071-60.993 32.696-92.18 94.944-93.692 61.997 1.512 93.686 32.763 95.131 93.756v41.096h-72.227v-47.499c0.251-4.642-0.564-10.607-2.511-17.949-1.25-3.261-3.448-6.020-6.525-8.093-3.197-2.572-7.845-3.828-13.868-3.828-10.543 0.31-17.132 4.268-19.827 11.921-1.068 3.512-1.947 6.905-2.508 10.163-0.254 2.887-0.377 5.532-0.377 7.786v143.511l42.477 37.634c0.215-0.432 0.452-0.851 0.63-1.303 1.947-6.467 2.762-12.799 2.511-19.076v-36.772h72.227v30.121c-0.246 31.245-9.086 54.699-26.363 70.447l40.711 36.069c35.787-56.055 56.803-122.585 56.867-194.244zM239.795 395.47c-12.613 37.023-19.827 76.557-19.827 117.913-0.19 200.236 161.584 362.009 361.945 362.135 56.853 0 110.313-13.302 158.133-36.398l117.846 104.421c-79.444 50.952-173.758 80.817-275.292 80.948-283.377 0.181-511.354-227.729-511.789-511.675-0.126-79.567 18.636-154.679 51.137-221.882l117.848 104.538zM388.576 690.020h-97.514v-249.057l72.23 64.070v0.689h0.815l117.72 104.418c0 0.564 0.123 0.94 0.123 1.509 0.753 53.898-30.369 80.069-93.374 78.37zM405.959 625.517c1.942-2.767 3.074-6.469 3.323-11.112 0.312-4.452 0.438-9.6 0.438-15.246 0.251-10.916-0.689-19.83-2.949-26.985-2.952-7.594-10.983-11.357-24.159-11.357h-19.325v74.043h15.31c7.842 0 13.865-0.683 18.072-2.19 4.397-1.573 7.468-3.953 9.29-7.153z" />
15
 <glyph unicode="&#xe614;" glyph-name="recEnable" horiz-adv-x="1142" d="M581.278 1025.708c284.857-0.19 514.807-230.517 514.427-514.997-0.378-285.047-230.073-514.553-514.869-514.615-284.541-0.062-515.311 230.517-514.933 514.422 0.439 285.936 230.009 515.439 515.375 515.19zM580.579 875.756c-201.764-0.123-364.666-163.032-364.478-364.663 0-202.018 162.524-364.735 364.478-364.984 202.018-0.316 365.174 163.030 365.048 365.423-0.252 201.767-163.156 364.35-365.048 364.224zM287.698 688.907h98.196c63.442 1.767 94.785-24.518 94.027-78.863 0.254-19.081-2.211-34.882-7.456-47.521-6.005-12.508-18.706-21.988-38.167-28.181v-0.819c28.373-6.259 43.031-23.573 43.981-51.946v-57.689c0-11.247 0.254-22.813 0.758-34.756 0.819-12.005 3.033-20.979 6.696-27.043h-71.846c-3.727 6.064-6.128 15.038-7.14 27.043-1.012 11.943-1.454 23.509-1.138 34.756v52.321c0 9.603-2.214 16.553-6.573 20.979-4.675 4.107-12.701 6.19-24.012 6.19h-14.599v-141.291h-72.73v326.82zM360.428 558.861h19.463c13.271 0 21.359 3.794 24.331 11.375 2.276 7.204 3.221 16.304 2.969 27.171 0 5.815-0.126 10.867-0.442 15.418-0.252 4.675-1.392 8.404-3.352 11.247-1.831 3.157-4.926 5.561-9.352 7.14-4.233 1.454-10.299 2.211-18.2 2.211h-15.418v-74.564zM498.372 688.907h162.082v-62.687h-89.35v-65.587h78.103v-62.685h-78.103v-73.11h92.822v-62.749h-165.557v326.818zM682.507 599.999c0.316 31.782 9.416 55.542 27.425 71.407 17.44 15.29 40.185 22.936 68.181 22.936 28.247 0 51.119-7.646 68.623-23 17.82-15.798 26.92-39.623 27.171-71.407v-30.333h-72.73v37.031c0.254 6.192-0.57 12.639-2.527 19.209-1.264 3.157-3.475 5.938-6.573 8.214-3.221 1.515-7.898 2.404-13.964 2.404-10.615-0.316-17.249-3.855-19.967-10.618-2.211-6.573-3.223-13.017-2.907-19.209v-161.956c0-2.273 0.126-4.865 0.38-7.772 0.568-3.411 1.454-6.824 2.527-10.233 2.717-7.775 9.352-11.756 19.967-12.007 6.067 0 10.744 1.261 13.964 3.791 3.098 2.15 5.309 4.867 6.573 8.216 1.96 7.33 2.782 13.33 2.527 18.007v47.837h72.73v-41.328c-1.451-61.547-33.364-93.015-95.794-94.469-62.685 1.454-94.53 32.922-95.607 94.343v148.937z" />
15
 <glyph unicode="&#xe614;" glyph-name="recEnable" horiz-adv-x="1142" d="M581.278 1025.708c284.857-0.19 514.807-230.517 514.427-514.997-0.378-285.047-230.073-514.553-514.869-514.615-284.541-0.062-515.311 230.517-514.933 514.422 0.439 285.936 230.009 515.439 515.375 515.19zM580.579 875.756c-201.764-0.123-364.666-163.032-364.478-364.663 0-202.018 162.524-364.735 364.478-364.984 202.018-0.316 365.174 163.030 365.048 365.423-0.252 201.767-163.156 364.35-365.048 364.224zM287.698 688.907h98.196c63.442 1.767 94.785-24.518 94.027-78.863 0.254-19.081-2.211-34.882-7.456-47.521-6.005-12.508-18.706-21.988-38.167-28.181v-0.819c28.373-6.259 43.031-23.573 43.981-51.946v-57.689c0-11.247 0.254-22.813 0.758-34.756 0.819-12.005 3.033-20.979 6.696-27.043h-71.846c-3.727 6.064-6.128 15.038-7.14 27.043-1.012 11.943-1.454 23.509-1.138 34.756v52.321c0 9.603-2.214 16.553-6.573 20.979-4.675 4.107-12.701 6.19-24.012 6.19h-14.599v-141.291h-72.73v326.82zM360.428 558.861h19.463c13.271 0 21.359 3.794 24.331 11.375 2.276 7.204 3.221 16.304 2.969 27.171 0 5.815-0.126 10.867-0.442 15.418-0.252 4.675-1.392 8.404-3.352 11.247-1.831 3.157-4.926 5.561-9.352 7.14-4.233 1.454-10.299 2.211-18.2 2.211h-15.418v-74.564zM498.372 688.907h162.082v-62.687h-89.35v-65.587h78.103v-62.685h-78.103v-73.11h92.822v-62.749h-165.557v326.818zM682.507 599.999c0.316 31.782 9.416 55.542 27.425 71.407 17.44 15.29 40.185 22.936 68.181 22.936 28.247 0 51.119-7.646 68.623-23 17.82-15.798 26.92-39.623 27.171-71.407v-30.333h-72.73v37.031c0.254 6.192-0.57 12.639-2.527 19.209-1.264 3.157-3.475 5.938-6.573 8.214-3.221 1.515-7.898 2.404-13.964 2.404-10.615-0.316-17.249-3.855-19.967-10.618-2.211-6.573-3.223-13.017-2.907-19.209v-161.956c0-2.273 0.126-4.865 0.38-7.772 0.568-3.411 1.454-6.824 2.527-10.233 2.717-7.775 9.352-11.756 19.967-12.007 6.067 0 10.744 1.261 13.964 3.791 3.098 2.15 5.309 4.867 6.573 8.216 1.96 7.33 2.782 13.33 2.527 18.007v47.837h72.73v-41.328c-1.451-61.547-33.364-93.015-95.794-94.469-62.685 1.454-94.53 32.922-95.607 94.343v148.937z" />
16
-<glyph unicode="&#xe61a;" glyph-name="connection" horiz-adv-x="1444" d="M3.881 210.835h220.26v-210.835h-220.26v210.835zM308.817 414.143h220.27v-414.143h-220.27v414.143zM613.764 617.412h220.268v-617.412h-220.268v617.412zM918.685 820.715h220.265v-820.715h-220.265v820.715zM1223.629 1024h220.263v-1024h-220.263v1024z" />
17
-<glyph unicode="&#xe900;" glyph-name="connection-lost" horiz-adv-x="1414" d="M0 299.153h196.337v-187.951h-196.337v187.951zM271.842 480.372h196.337v-369.169h-196.337v369.169zM543.656 661.562h196.337v-550.36h-196.337v550.36zM815.47 842.766v-731.564h119.56c-14.589 33.025-23.125 71.503-23.232 111.943 0.132 86.42 38.697 163.851 99.656 216.468l0.348 403.153h-196.332zM1087.292 1024v-533.672c28.874 10.572 62.222 16.73 97.009 16.825 35.717-0.129 69.823-6.614 101.322-18.371l-1.999 535.218h-196.332zM1192.868 439.852c-0.009 0-0.020 0-0.031 0-122.247 0-221.351-98.447-221.372-219.896 0-0.007 0-0.014 0-0.021 0-121.467 99.111-219.935 221.372-219.935 0.011 0 0.021 0 0.032 0 122.248 0.014 221.345 98.477 221.345 219.935 0 0.007 0 0.013 0 0.020-0.021 121.441-99.11 219.883-221.345 219.897zM1194.706 372.607c87.601-0.006 158.614-69.787 158.614-155.866 0-0.006 0-0.012 0-0.019-0.022-86.062-71.026-155.822-158.614-155.828-87.588 0.006-158.593 69.766-158.615 155.826 0 0.007 0 0.014 0 0.020 0 86.079 71.013 155.86 158.613 155.866zM1286.795 355.682l48.348-52.528-236.375-217.567-48.348 52.528 236.375 217.567z" />
18
 <glyph unicode="&#xe901;" glyph-name="avatar" d="M512 204c106 0 200 56 256 138-2 84-172 132-256 132-86 0-254-48-256-132 56-82 150-138 256-138zM512 810c-70 0-128-58-128-128s58-128 128-128 128 58 128 128-58 128-128 128zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
16
 <glyph unicode="&#xe901;" glyph-name="avatar" d="M512 204c106 0 200 56 256 138-2 84-172 132-256 132-86 0-254-48-256-132 56-82 150-138 256-138zM512 810c-70 0-128-58-128-128s58-128 128-128 128 58 128 128-58 128-128 128zM512 938c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
19
 <glyph unicode="&#xe902;" glyph-name="download" d="M726 470h-128v170h-172v-170h-128l214-214zM826 596c110-8 198-100 198-212 0-118-96-214-214-214h-554c-142 0-256 114-256 256 0 132 100 240 228 254 54 102 160 174 284 174 156 0 284-110 314-258z" />
17
 <glyph unicode="&#xe902;" glyph-name="download" d="M726 470h-128v170h-172v-170h-128l214-214zM826 596c110-8 198-100 198-212 0-118-96-214-214-214h-554c-142 0-256 114-256 256 0 132 100 240 228 254 54 102 160 174 284 174 156 0 284-110 314-258z" />
20
 <glyph unicode="&#xe903;" glyph-name="mic-camera-combined" d="M756.704 628.138l267.296 202.213v-635.075l-267.296 202.213v-191.923c0-12.085-11.296-21.863-25.216-21.863h-706.272c-13.92 0-25.216 9.777-25.216 21.863v612.25c0 12.085 11.296 21.863 25.216 21.863h706.272c13.92 0 25.216-9.777 25.216-21.863v-189.679zM371.338 376.228c47.817 0 86.529 40.232 86.529 89.811v184.835c0 49.651-38.713 89.883-86.529 89.883-47.788 0-86.515-40.232-86.515-89.883v-184.835c0-49.579 38.756-89.811 86.515-89.811v0zM356.754 314.070v-32.78h33.718v33.412c73.858 9.606 131.235 73.73 131.235 151.351v88.232h-30.636v-88.232c0-67.57-53.696-122.534-119.734-122.534-66.024 0-119.691 54.964-119.691 122.534v88.232h-30.636v-88.232c0-79.215 59.674-144.502 135.744-151.969v-0.014z" />
18
 <glyph unicode="&#xe903;" glyph-name="mic-camera-combined" d="M756.704 628.138l267.296 202.213v-635.075l-267.296 202.213v-191.923c0-12.085-11.296-21.863-25.216-21.863h-706.272c-13.92 0-25.216 9.777-25.216 21.863v612.25c0 12.085 11.296 21.863 25.216 21.863h706.272c13.92 0 25.216-9.777 25.216-21.863v-189.679zM371.338 376.228c47.817 0 86.529 40.232 86.529 89.811v184.835c0 49.651-38.713 89.883-86.529 89.883-47.788 0-86.515-40.232-86.515-89.883v-184.835c0-49.579 38.756-89.811 86.515-89.811v0zM356.754 314.070v-32.78h33.718v33.412c73.858 9.606 131.235 73.73 131.235 151.351v88.232h-30.636v-88.232c0-67.57-53.696-122.534-119.734-122.534-66.024 0-119.691 54.964-119.691 122.534v88.232h-30.636v-88.232c0-79.215 59.674-144.502 135.744-151.969v-0.014z" />
52
 <glyph unicode="&#xe923;" glyph-name="visibility" d="M512 640c70 0 128-58 128-128s-58-128-128-128-128 58-128 128 58 128 128 128zM512 298c118 0 214 96 214 214s-96 214-214 214-214-96-214-214 96-214 214-214zM512 832c214 0 396-132 470-320-74-188-256-320-470-320s-396 132-470 320c74 188 256 320 470 320z" />
50
 <glyph unicode="&#xe923;" glyph-name="visibility" d="M512 640c70 0 128-58 128-128s-58-128-128-128-128 58-128 128 58 128 128 128zM512 298c118 0 214 96 214 214s-96 214-214 214-214-96-214-214 96-214 214-214zM512 832c214 0 396-132 470-320-74-188-256-320-470-320s-396 132-470 320c74 188 256 320 470 320z" />
53
 <glyph unicode="&#xe924;" glyph-name="visibility-off" d="M506 640h6c70 0 128-58 128-128v-8zM322 606c-14-28-24-60-24-94 0-118 96-214 214-214 34 0 66 10 94 24l-66 66c-8-2-18-4-28-4-70 0-128 58-128 128 0 10 2 20 4 28zM86 842l54 54 756-756-54-54c-47.968 47.365-96.266 94.401-144 142-58-24-120-36-186-36-214 0-396 132-470 320 34 84 90 156 160 212-39.017 38.983-77.307 78.693-116 118zM512 726c-28 0-54-6-78-16l-92 92c52 20 110 30 170 30 214 0 394-132 468-320-32-80-82-148-146-202l-124 124c10 24 16 50 16 78 0 118-96 214-214 214z" />
51
 <glyph unicode="&#xe924;" glyph-name="visibility-off" d="M506 640h6c70 0 128-58 128-128v-8zM322 606c-14-28-24-60-24-94 0-118 96-214 214-214 34 0 66 10 94 24l-66 66c-8-2-18-4-28-4-70 0-128 58-128 128 0 10 2 20 4 28zM86 842l54 54 756-756-54-54c-47.968 47.365-96.266 94.401-144 142-58-24-120-36-186-36-214 0-396 132-470 320 34 84 90 156 160 212-39.017 38.983-77.307 78.693-116 118zM512 726c-28 0-54-6-78-16l-92 92c52 20 110 30 170 30 214 0 394-132 468-320-32-80-82-148-146-202l-124 124c10 24 16 50 16 78 0 118-96 214-214 214z" />
54
 <glyph unicode="&#xe925;" glyph-name="dialpad" d="M512 982c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 726c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM768 726c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM768 470c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 470c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM768 810c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86zM256 470c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM256 726c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM256 982c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 214c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86z" />
52
 <glyph unicode="&#xe925;" glyph-name="dialpad" d="M512 982c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 726c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM768 726c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM768 470c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 470c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM768 810c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86zM256 470c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM256 726c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM256 982c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 214c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86z" />
53
+<glyph unicode="&#xe926;" glyph-name="gsm-bars-black" d="M896 1024c70.692 0 128-57.308 128-128v-768c0-70.692-57.308-128-128-128s-128 57.308-128 128v768c0 70.692 57.308 128 128 128zM512 768c70.692 0 128-57.308 128-128v-512c0-70.692-57.308-128-128-128s-128 57.308-128 128v512c0 70.692 57.308 128 128 128zM128 384v0c70.692 0 128-57.308 128-128v-128c0-70.692-57.308-128-128-128s-128 57.308-128 128v128c0 70.692 57.308 128 128 128v0z" />
55
 </font></defs></svg>
54
 </font></defs></svg>

BIN
fonts/jitsi.ttf Datei anzeigen


BIN
fonts/jitsi.woff Datei anzeigen


+ 71
- 163
fonts/selection.json Datei anzeigen

1
 {
1
 {
2
   "IcoMoonType": "selection",
2
   "IcoMoonType": "selection",
3
   "icons": [
3
   "icons": [
4
+    {
5
+      "icon": {
6
+        "paths": [
7
+          "M896 0c70.692 0 128 57.308 128 128v768c0 70.692-57.308 128-128 128s-128-57.308-128-128v-768c0-70.692 57.308-128 128-128zM512 256c70.692 0 128 57.308 128 128v512c0 70.692-57.308 128-128 128s-128-57.308-128-128v-512c0-70.692 57.308-128 128-128zM128 640v0c70.692 0 128 57.308 128 128v128c0 70.692-57.308 128-128 128s-128-57.308-128-128v-128c0-70.692 57.308-128 128-128v0z"
8
+        ],
9
+        "attrs": [
10
+          {}
11
+        ],
12
+        "isMulticolor": false,
13
+        "isMulticolor2": false,
14
+        "grid": 0,
15
+        "tags": [
16
+          "gsm-bars-black"
17
+        ]
18
+      },
19
+      "attrs": [
20
+        {}
21
+      ],
22
+      "properties": {
23
+        "order": 901,
24
+        "id": 0,
25
+        "name": "gsm-bars-black",
26
+        "prevSize": 32,
27
+        "code": 59686
28
+      },
29
+      "setIdx": 0,
30
+      "setId": 1,
31
+      "iconIdx": 0
32
+    },
4
     {
33
     {
5
       "icon": {
34
       "icon": {
6
         "paths": [
35
         "paths": [
28
       },
57
       },
29
       "setIdx": 0,
58
       "setIdx": 0,
30
       "setId": 1,
59
       "setId": 1,
31
-      "iconIdx": 0
60
+      "iconIdx": 1
32
     },
61
     },
33
     {
62
     {
34
       "icon": {
63
       "icon": {
57
       },
86
       },
58
       "setIdx": 0,
87
       "setIdx": 0,
59
       "setId": 1,
88
       "setId": 1,
60
-      "iconIdx": 1
89
+      "iconIdx": 2
61
     },
90
     },
62
     {
91
     {
63
       "icon": {
92
       "icon": {
86
       },
115
       },
87
       "setIdx": 0,
116
       "setIdx": 0,
88
       "setId": 1,
117
       "setId": 1,
89
-      "iconIdx": 2
118
+      "iconIdx": 3
90
     },
119
     },
91
     {
120
     {
92
       "icon": {
121
       "icon": {
115
       },
144
       },
116
       "setIdx": 0,
145
       "setIdx": 0,
117
       "setId": 1,
146
       "setId": 1,
118
-      "iconIdx": 3
147
+      "iconIdx": 4
119
     },
148
     },
120
     {
149
     {
121
       "icon": {
150
       "icon": {
141
       },
170
       },
142
       "setIdx": 0,
171
       "setIdx": 0,
143
       "setId": 1,
172
       "setId": 1,
144
-      "iconIdx": 4
173
+      "iconIdx": 5
145
     },
174
     },
146
     {
175
     {
147
       "icon": {
176
       "icon": {
167
       },
196
       },
168
       "setIdx": 0,
197
       "setIdx": 0,
169
       "setId": 1,
198
       "setId": 1,
170
-      "iconIdx": 5
199
+      "iconIdx": 6
171
     },
200
     },
172
     {
201
     {
173
       "icon": {
202
       "icon": {
193
       },
222
       },
194
       "setIdx": 0,
223
       "setIdx": 0,
195
       "setId": 1,
224
       "setId": 1,
196
-      "iconIdx": 6
225
+      "iconIdx": 7
197
     },
226
     },
198
     {
227
     {
199
       "icon": {
228
       "icon": {
219
       },
248
       },
220
       "setIdx": 0,
249
       "setIdx": 0,
221
       "setId": 1,
250
       "setId": 1,
222
-      "iconIdx": 7
251
+      "iconIdx": 8
223
     },
252
     },
224
     {
253
     {
225
       "icon": {
254
       "icon": {
245
       },
274
       },
246
       "setIdx": 0,
275
       "setIdx": 0,
247
       "setId": 1,
276
       "setId": 1,
248
-      "iconIdx": 8
277
+      "iconIdx": 9
249
     },
278
     },
250
     {
279
     {
251
       "icon": {
280
       "icon": {
271
       },
300
       },
272
       "setIdx": 0,
301
       "setIdx": 0,
273
       "setId": 1,
302
       "setId": 1,
274
-      "iconIdx": 9
303
+      "iconIdx": 10
275
     },
304
     },
276
     {
305
     {
277
       "icon": {
306
       "icon": {
297
       },
326
       },
298
       "setIdx": 0,
327
       "setIdx": 0,
299
       "setId": 1,
328
       "setId": 1,
300
-      "iconIdx": 10
329
+      "iconIdx": 11
301
     },
330
     },
302
     {
331
     {
303
       "icon": {
332
       "icon": {
323
       },
352
       },
324
       "setIdx": 0,
353
       "setIdx": 0,
325
       "setId": 1,
354
       "setId": 1,
326
-      "iconIdx": 11
355
+      "iconIdx": 12
327
     },
356
     },
328
     {
357
     {
329
       "icon": {
358
       "icon": {
349
       },
378
       },
350
       "setIdx": 0,
379
       "setIdx": 0,
351
       "setId": 1,
380
       "setId": 1,
352
-      "iconIdx": 12
381
+      "iconIdx": 13
353
     },
382
     },
354
     {
383
     {
355
       "icon": {
384
       "icon": {
375
       },
404
       },
376
       "setIdx": 0,
405
       "setIdx": 0,
377
       "setId": 1,
406
       "setId": 1,
378
-      "iconIdx": 13
407
+      "iconIdx": 14
379
     },
408
     },
380
     {
409
     {
381
       "icon": {
410
       "icon": {
401
       },
430
       },
402
       "setIdx": 0,
431
       "setIdx": 0,
403
       "setId": 1,
432
       "setId": 1,
404
-      "iconIdx": 14
433
+      "iconIdx": 15
405
     },
434
     },
406
     {
435
     {
407
       "icon": {
436
       "icon": {
427
       },
456
       },
428
       "setIdx": 0,
457
       "setIdx": 0,
429
       "setId": 1,
458
       "setId": 1,
430
-      "iconIdx": 15
459
+      "iconIdx": 16
431
     },
460
     },
432
     {
461
     {
433
       "icon": {
462
       "icon": {
453
       },
482
       },
454
       "setIdx": 0,
483
       "setIdx": 0,
455
       "setId": 1,
484
       "setId": 1,
456
-      "iconIdx": 16
485
+      "iconIdx": 17
457
     },
486
     },
458
     {
487
     {
459
       "icon": {
488
       "icon": {
479
       },
508
       },
480
       "setIdx": 0,
509
       "setIdx": 0,
481
       "setId": 1,
510
       "setId": 1,
482
-      "iconIdx": 17
511
+      "iconIdx": 18
483
     },
512
     },
484
     {
513
     {
485
       "icon": {
514
       "icon": {
505
       },
534
       },
506
       "setIdx": 0,
535
       "setIdx": 0,
507
       "setId": 1,
536
       "setId": 1,
508
-      "iconIdx": 18
537
+      "iconIdx": 19
509
     },
538
     },
510
     {
539
     {
511
       "icon": {
540
       "icon": {
531
       },
560
       },
532
       "setIdx": 0,
561
       "setIdx": 0,
533
       "setId": 1,
562
       "setId": 1,
534
-      "iconIdx": 19
563
+      "iconIdx": 20
535
     },
564
     },
536
     {
565
     {
537
       "icon": {
566
       "icon": {
557
       },
586
       },
558
       "setIdx": 0,
587
       "setIdx": 0,
559
       "setId": 1,
588
       "setId": 1,
560
-      "iconIdx": 20
589
+      "iconIdx": 21
561
     },
590
     },
562
     {
591
     {
563
       "icon": {
592
       "icon": {
583
       },
612
       },
584
       "setIdx": 0,
613
       "setIdx": 0,
585
       "setId": 1,
614
       "setId": 1,
586
-      "iconIdx": 21
615
+      "iconIdx": 22
587
     },
616
     },
588
     {
617
     {
589
       "icon": {
618
       "icon": {
609
       },
638
       },
610
       "setIdx": 0,
639
       "setIdx": 0,
611
       "setId": 1,
640
       "setId": 1,
612
-      "iconIdx": 22
641
+      "iconIdx": 23
613
     },
642
     },
614
     {
643
     {
615
       "icon": {
644
       "icon": {
635
       },
664
       },
636
       "setIdx": 0,
665
       "setIdx": 0,
637
       "setId": 1,
666
       "setId": 1,
638
-      "iconIdx": 23
667
+      "iconIdx": 24
639
     },
668
     },
640
     {
669
     {
641
       "icon": {
670
       "icon": {
661
       },
690
       },
662
       "setIdx": 0,
691
       "setIdx": 0,
663
       "setId": 1,
692
       "setId": 1,
664
-      "iconIdx": 24
693
+      "iconIdx": 25
665
     },
694
     },
666
     {
695
     {
667
       "icon": {
696
       "icon": {
687
       },
716
       },
688
       "setIdx": 0,
717
       "setIdx": 0,
689
       "setId": 1,
718
       "setId": 1,
690
-      "iconIdx": 25
719
+      "iconIdx": 26
691
     },
720
     },
692
     {
721
     {
693
       "icon": {
722
       "icon": {
713
       },
742
       },
714
       "setIdx": 0,
743
       "setIdx": 0,
715
       "setId": 1,
744
       "setId": 1,
716
-      "iconIdx": 26
745
+      "iconIdx": 27
717
     },
746
     },
718
     {
747
     {
719
       "icon": {
748
       "icon": {
739
       },
768
       },
740
       "setIdx": 0,
769
       "setIdx": 0,
741
       "setId": 1,
770
       "setId": 1,
742
-      "iconIdx": 27
771
+      "iconIdx": 28
743
     },
772
     },
744
     {
773
     {
745
       "icon": {
774
       "icon": {
765
       },
794
       },
766
       "setIdx": 0,
795
       "setIdx": 0,
767
       "setId": 1,
796
       "setId": 1,
768
-      "iconIdx": 28
797
+      "iconIdx": 29
769
     },
798
     },
770
     {
799
     {
771
       "icon": {
800
       "icon": {
791
       },
820
       },
792
       "setIdx": 0,
821
       "setIdx": 0,
793
       "setId": 1,
822
       "setId": 1,
794
-      "iconIdx": 29
823
+      "iconIdx": 30
795
     },
824
     },
796
     {
825
     {
797
       "icon": {
826
       "icon": {
817
       },
846
       },
818
       "setIdx": 0,
847
       "setIdx": 0,
819
       "setId": 1,
848
       "setId": 1,
820
-      "iconIdx": 30
849
+      "iconIdx": 31
821
     },
850
     },
822
     {
851
     {
823
       "icon": {
852
       "icon": {
843
       },
872
       },
844
       "setIdx": 0,
873
       "setIdx": 0,
845
       "setId": 1,
874
       "setId": 1,
846
-      "iconIdx": 31
875
+      "iconIdx": 32
847
     },
876
     },
848
     {
877
     {
849
       "icon": {
878
       "icon": {
869
       },
898
       },
870
       "setIdx": 0,
899
       "setIdx": 0,
871
       "setId": 1,
900
       "setId": 1,
872
-      "iconIdx": 32
873
-    },
874
-    {
875
-      "icon": {
876
-        "paths": [
877
-          "M-0 724.847h196.337v187.951h-196.337v-187.951z",
878
-          "M271.842 543.628h196.337v369.169h-196.337v-369.169z",
879
-          "M543.656 362.438h196.337v550.36h-196.337v-550.36z",
880
-          "M815.47 181.234v731.564h119.56c-14.589-33.025-23.125-71.503-23.232-111.943 0.132-86.42 38.697-163.851 99.656-216.468l0.348-403.153h-196.332z",
881
-          "M1087.292-0v533.672c28.874-10.572 62.222-16.73 97.009-16.825 35.717 0.129 69.823 6.614 101.322 18.371l-1.999-535.218h-196.332z",
882
-          "M1192.868 584.148c-0.009-0-0.020-0-0.031-0-122.247 0-221.351 98.447-221.372 219.896-0 0.007-0 0.014-0 0.021 0 121.467 99.111 219.935 221.372 219.935 0.011 0 0.021-0 0.032-0 122.248-0.014 221.345-98.477 221.345-219.935 0-0.007-0-0.013-0-0.020-0.021-121.441-99.11-219.883-221.345-219.897zM1194.706 651.393c87.601 0.006 158.614 69.787 158.614 155.866 0 0.006-0 0.012-0 0.019-0.022 86.062-71.026 155.822-158.614 155.828-87.588-0.006-158.593-69.766-158.615-155.826-0-0.007-0-0.014-0-0.020 0-86.079 71.013-155.86 158.613-155.866z",
883
-          "M1286.795 668.318l48.348 52.528-236.375 217.567-48.348-52.528 236.375-217.567z"
884
-        ],
885
-        "width": 1414,
886
-        "attrs": [
887
-          {},
888
-          {},
889
-          {},
890
-          {},
891
-          {},
892
-          {},
893
-          {}
894
-        ],
895
-        "isMulticolor": false,
896
-        "isMulticolor2": false,
897
-        "tags": [
898
-          "connection-lost"
899
-        ],
900
-        "grid": 0
901
-      },
902
-      "attrs": [
903
-        {},
904
-        {},
905
-        {},
906
-        {},
907
-        {},
908
-        {},
909
-        {}
910
-      ],
911
-      "properties": {
912
-        "order": 888,
913
-        "id": 32,
914
-        "name": "connection-lost",
915
-        "prevSize": 32,
916
-        "code": 59648
917
-      },
918
-      "setIdx": 0,
919
-      "setId": 1,
920
       "iconIdx": 33
901
       "iconIdx": 33
921
     },
902
     },
922
-    {
923
-      "icon": {
924
-        "paths": [
925
-          "M3.881 813.165h220.26v210.835h-220.26v-210.835z",
926
-          "M308.817 609.857h220.27v414.143h-220.27v-414.143z",
927
-          "M613.764 406.588h220.268v617.412h-220.268v-617.412z",
928
-          "M918.685 203.285h220.265v820.715h-220.265v-820.715z",
929
-          "M1223.629 0h220.263v1024h-220.263v-1024z"
930
-        ],
931
-        "width": 1444,
932
-        "attrs": [
933
-          {
934
-            "opacity": 1,
935
-            "visibility": false
936
-          },
937
-          {
938
-            "opacity": 1,
939
-            "visibility": false
940
-          },
941
-          {
942
-            "opacity": 1,
943
-            "visibility": false
944
-          },
945
-          {
946
-            "opacity": 1,
947
-            "visibility": false
948
-          },
949
-          {
950
-            "opacity": 1,
951
-            "visibility": false
952
-          }
953
-        ],
954
-        "isMulticolor": false,
955
-        "isMulticolor2": false,
956
-        "tags": [
957
-          "connection-2"
958
-        ],
959
-        "grid": 0
960
-      },
961
-      "attrs": [
962
-        {
963
-          "opacity": 1,
964
-          "visibility": false
965
-        },
966
-        {
967
-          "opacity": 1,
968
-          "visibility": false
969
-        },
970
-        {
971
-          "opacity": 1,
972
-          "visibility": false
973
-        },
974
-        {
975
-          "opacity": 1,
976
-          "visibility": false
977
-        },
978
-        {
979
-          "opacity": 1,
980
-          "visibility": false
981
-        }
982
-      ],
983
-      "properties": {
984
-        "order": 889,
985
-        "id": 33,
986
-        "prevSize": 32,
987
-        "code": 58906,
988
-        "name": "connection",
989
-        "ligatures": ""
990
-      },
991
-      "setIdx": 0,
992
-      "setId": 1,
993
-      "iconIdx": 34
994
-    },
995
     {
903
     {
996
       "icon": {
904
       "icon": {
997
         "paths": [
905
         "paths": [
1019
       },
927
       },
1020
       "setIdx": 0,
928
       "setIdx": 0,
1021
       "setId": 1,
929
       "setId": 1,
1022
-      "iconIdx": 35
930
+      "iconIdx": 36
1023
     },
931
     },
1024
     {
932
     {
1025
       "icon": {
933
       "icon": {
1049
       },
957
       },
1050
       "setIdx": 0,
958
       "setIdx": 0,
1051
       "setId": 1,
959
       "setId": 1,
1052
-      "iconIdx": 36
960
+      "iconIdx": 37
1053
     },
961
     },
1054
     {
962
     {
1055
       "icon": {
963
       "icon": {
1079
       },
987
       },
1080
       "setIdx": 0,
988
       "setIdx": 0,
1081
       "setId": 1,
989
       "setId": 1,
1082
-      "iconIdx": 37
990
+      "iconIdx": 38
1083
     },
991
     },
1084
     {
992
     {
1085
       "icon": {
993
       "icon": {
1105
       },
1013
       },
1106
       "setIdx": 0,
1014
       "setIdx": 0,
1107
       "setId": 1,
1015
       "setId": 1,
1108
-      "iconIdx": 38
1016
+      "iconIdx": 39
1109
     },
1017
     },
1110
     {
1018
     {
1111
       "icon": {
1019
       "icon": {
1131
       },
1039
       },
1132
       "setIdx": 0,
1040
       "setIdx": 0,
1133
       "setId": 1,
1041
       "setId": 1,
1134
-      "iconIdx": 39
1042
+      "iconIdx": 40
1135
     },
1043
     },
1136
     {
1044
     {
1137
       "icon": {
1045
       "icon": {
1157
       },
1065
       },
1158
       "setIdx": 0,
1066
       "setIdx": 0,
1159
       "setId": 1,
1067
       "setId": 1,
1160
-      "iconIdx": 40
1068
+      "iconIdx": 41
1161
     },
1069
     },
1162
     {
1070
     {
1163
       "icon": {
1071
       "icon": {
1184
       },
1092
       },
1185
       "setIdx": 0,
1093
       "setIdx": 0,
1186
       "setId": 1,
1094
       "setId": 1,
1187
-      "iconIdx": 41
1095
+      "iconIdx": 42
1188
     },
1096
     },
1189
     {
1097
     {
1190
       "icon": {
1098
       "icon": {
1213
       },
1121
       },
1214
       "setIdx": 0,
1122
       "setIdx": 0,
1215
       "setId": 1,
1123
       "setId": 1,
1216
-      "iconIdx": 42
1124
+      "iconIdx": 43
1217
     },
1125
     },
1218
     {
1126
     {
1219
       "icon": {
1127
       "icon": {
1240
       },
1148
       },
1241
       "setIdx": 0,
1149
       "setIdx": 0,
1242
       "setId": 1,
1150
       "setId": 1,
1243
-      "iconIdx": 43
1151
+      "iconIdx": 44
1244
     },
1152
     },
1245
     {
1153
     {
1246
       "icon": {
1154
       "icon": {
1267
       },
1175
       },
1268
       "setIdx": 0,
1176
       "setIdx": 0,
1269
       "setId": 1,
1177
       "setId": 1,
1270
-      "iconIdx": 44
1178
+      "iconIdx": 45
1271
     }
1179
     }
1272
   ],
1180
   ],
1273
   "height": 1024,
1181
   "height": 1024,

+ 21
- 2
interface_config.js Datei anzeigen

98
      *
98
      *
99
      * @type {number}
99
      * @type {number}
100
      */
100
      */
101
-    MAXIMUM_ZOOMING_COEFFICIENT: 1.3
101
+    MAXIMUM_ZOOMING_COEFFICIENT: 1.3,
102
 
102
 
103
     /*
103
     /*
104
      * If indicated some of the error dialogs may point to the support URL for
104
      * If indicated some of the error dialogs may point to the support URL for
105
      * help.
105
      * help.
106
      */
106
      */
107
-    // SUPPORT_URL: ""
107
+    // SUPPORT_URL: "",
108
+
109
+    /**
110
+     * Whether the connection indicator icon should hide itself based on
111
+     * connection strength. If true, the connection indicator will remain
112
+     * displayed while the participant has a weak connection and will hide
113
+     * itself after the CONNECTION_INDICATOR_HIDE_TIMEOUT when the connection is
114
+     * strong.
115
+     *
116
+     * @type {boolean}
117
+     */
118
+    CONNECTION_INDICATOR_AUTO_HIDE_ENABLED: false,
119
+
120
+    /**
121
+     * How long the connection indicator should remain displayed before hiding.
122
+     * Used in conjunction with CONNECTION_INDICATOR_AUTOHIDE_ENABLED.
123
+     *
124
+     * @type {number}
125
+     */
126
+    CONNECTION_INDICATOR_AUTO_HIDE_TIMEOUT: 5000
108
 };
127
 };

+ 9
- 1
lang/main.json Datei anzeigen

200
         "bandwidth": "Estimated bandwidth:",
200
         "bandwidth": "Estimated bandwidth:",
201
         "na": "Come back here for connection information once the conference starts",
201
         "na": "Come back here for connection information once the conference starts",
202
         "peer_to_peer": " (p2p)",
202
         "peer_to_peer": " (p2p)",
203
-        "turn": " (turn)"
203
+        "turn": " (turn)",
204
+        "quality": {
205
+            "good": "Good",
206
+            "inactive": "Inactive",
207
+            "lost": "Lost",
208
+            "nonoptimal": "Nonoptimal",
209
+            "poor": "Poor"
210
+        },
211
+        "status": "Connection:"
204
     },
212
     },
205
     "notify": {
213
     "notify": {
206
         "disconnected": "disconnected",
214
         "disconnected": "disconnected",

+ 6
- 0
modules/UI/videolayout/SmallVideo.js Datei anzeigen

253
         () => {
253
         () => {
254
             this.videoIsHovered = true;
254
             this.videoIsHovered = true;
255
             this.updateView();
255
             this.updateView();
256
+            this.updateIndicators();
256
         },
257
         },
257
         () => {
258
         () => {
258
             this.videoIsHovered = false;
259
             this.videoIsHovered = false;
259
             this.updateView();
260
             this.updateView();
261
+            this.updateIndicators();
260
         }
262
         }
261
     );
263
     );
262
 };
264
 };
755
         = this.container.querySelector('.videocontainer__toptoolbar');
757
         = this.container.querySelector('.videocontainer__toptoolbar');
756
 
758
 
757
     const iconSize = UIUtil.getIndicatorFontSize();
759
     const iconSize = UIUtil.getIndicatorFontSize();
760
+    const showConnectionIndicator = this.videoIsHovered
761
+        || !interfaceConfig.CONNECTION_INDICATOR_AUTO_HIDE_ENABLED;
758
     const tooltipPosition = interfaceConfig.VERTICAL_FILMSTRIP ? 'left' : 'top';
762
     const tooltipPosition = interfaceConfig.VERTICAL_FILMSTRIP ? 'left' : 'top';
759
 
763
 
760
     /* jshint ignore:start */
764
     /* jshint ignore:start */
763
             <div>
767
             <div>
764
                 { this._showConnectionIndicator
768
                 { this._showConnectionIndicator
765
                     ? <ConnectionIndicator
769
                     ? <ConnectionIndicator
770
+                        alwaysVisible = { showConnectionIndicator }
766
                         connectionStatus = { this._connectionStatus }
771
                         connectionStatus = { this._connectionStatus }
772
+                        iconSize = { iconSize }
767
                         isLocalVideo = { this.isLocal }
773
                         isLocalVideo = { this.isLocal }
768
                         enableStatsDisplay = { !interfaceConfig.filmStripOnly }
774
                         enableStatsDisplay = { !interfaceConfig.filmStripOnly }
769
                         statsPopoverPosition = { this.statsPopoverLocation }
775
                         statsPopoverPosition = { this.statsPopoverLocation }

+ 223
- 57
react/features/connection-indicator/components/ConnectionIndicator.js Datei anzeigen

1
+import PropTypes from 'prop-types';
1
 import React, { Component } from 'react';
2
 import React, { Component } from 'react';
2
 
3
 
4
+import { translate } from '../../base/i18n';
3
 import { JitsiParticipantConnectionStatus } from '../../base/lib-jitsi-meet';
5
 import { JitsiParticipantConnectionStatus } from '../../base/lib-jitsi-meet';
4
 import { Popover } from '../../base/popover';
6
 import { Popover } from '../../base/popover';
5
 import { ConnectionStatsTable } from '../../connection-stats';
7
 import { ConnectionStatsTable } from '../../connection-stats';
6
 
8
 
7
 import statsEmitter from '../statsEmitter';
9
 import statsEmitter from '../statsEmitter';
8
 
10
 
9
-declare var $: Object;
10
 declare var interfaceConfig: Object;
11
 declare var interfaceConfig: Object;
11
 
12
 
12
-// Converts the percent for connection quality into a string recognized for CSS.
13
+/**
14
+ * The connection quality percentage that must be reached to be considered of
15
+ * good quality and can result in the connection indicator being hidden.
16
+ *
17
+ * @type {number}
18
+ */
19
+const INDICATOR_DISPLAY_THRESHOLD = 70;
20
+
21
+/**
22
+ * An array of display configurations for the connection indicator and its bars.
23
+ * The ordering is done specifically for faster iteration to find a matching
24
+ * configuration to the current connection strength percentage.
25
+ *
26
+ * @type {Object[]}
27
+ */
13
 const QUALITY_TO_WIDTH = [
28
 const QUALITY_TO_WIDTH = [
14
 
29
 
15
-    // Full (5 bars)
30
+    // Full (3 bars)
16
     {
31
     {
17
-        percent: 80,
32
+        colorClass: 'status-high',
33
+        percent: INDICATOR_DISPLAY_THRESHOLD,
34
+        tip: 'connectionindicator.quality.good',
18
         width: '100%'
35
         width: '100%'
19
     },
36
     },
20
 
37
 
21
-    // 4 bars
22
-    {
23
-        percent: 60,
24
-        width: '80%'
25
-    },
26
-
27
-    // 3 bars
28
-    {
29
-        percent: 40,
30
-        width: '55%'
31
-    },
32
-
33
     // 2 bars
38
     // 2 bars
34
     {
39
     {
35
-        percent: 20,
36
-        width: '40%'
40
+        colorClass: 'status-med',
41
+        percent: 40,
42
+        tip: 'connectionindicator.quality.nonoptimal',
43
+        width: '66%'
37
     },
44
     },
38
 
45
 
39
     // 1 bar
46
     // 1 bar
40
     {
47
     {
48
+        colorClass: 'status-low',
41
         percent: 0,
49
         percent: 0,
42
-        width: '20%'
50
+        tip: 'connectionindicator.quality.poor',
51
+        width: '33%'
43
     }
52
     }
44
 
53
 
45
-    // Note: we never show 0 bars.
54
+    // Note: we never show 0 bars as long as there is a connection.
46
 ];
55
 ];
47
 
56
 
48
 /**
57
 /**
58
      * @static
67
      * @static
59
      */
68
      */
60
     static propTypes = {
69
     static propTypes = {
70
+        /**
71
+         * Whether or not the component should ignore setting a visibility class
72
+         * for hiding the component when the connection quality is not strong.
73
+         */
74
+        alwaysVisible: PropTypes.bool,
75
+
61
         /**
76
         /**
62
          * The current condition of the user's connection, matching one of the
77
          * The current condition of the user's connection, matching one of the
63
          * enumerated values in the library.
78
          * enumerated values in the library.
64
          *
79
          *
65
          * @type {JitsiParticipantConnectionStatus}
80
          * @type {JitsiParticipantConnectionStatus}
66
          */
81
          */
67
-        connectionStatus: React.PropTypes.string,
82
+        connectionStatus: PropTypes.string,
68
 
83
 
69
         /**
84
         /**
70
          * Whether or not clicking the indicator should display a popover for
85
          * Whether or not clicking the indicator should display a popover for
71
          * more details.
86
          * more details.
72
          */
87
          */
73
-        enableStatsDisplay: React.PropTypes.bool,
88
+        enableStatsDisplay: PropTypes.bool,
89
+
90
+        /**
91
+         * The font-size for the icon.
92
+         */
93
+        iconSize: PropTypes.number,
74
 
94
 
75
         /**
95
         /**
76
          * Whether or not the displays stats are for local video.
96
          * Whether or not the displays stats are for local video.
77
          */
97
          */
78
-        isLocalVideo: React.PropTypes.bool,
98
+        isLocalVideo: PropTypes.bool,
79
 
99
 
80
         /**
100
         /**
81
          * Relative to the icon from where the popover for more connection
101
          * Relative to the icon from where the popover for more connection
82
          * details should display.
102
          * details should display.
83
          */
103
          */
84
-        statsPopoverPosition: React.PropTypes.string,
104
+        statsPopoverPosition: PropTypes.string,
85
 
105
 
86
         /**
106
         /**
87
          * Invoked to obtain translated strings.
107
          * Invoked to obtain translated strings.
88
          */
108
          */
89
-        t: React.PropTypes.func,
109
+        t: PropTypes.func,
90
 
110
 
91
         /**
111
         /**
92
          * The user ID associated with the displayed connection indication and
112
          * The user ID associated with the displayed connection indication and
93
          * stats.
113
          * stats.
94
          */
114
          */
95
-        userID: React.PropTypes.string
115
+        userID: PropTypes.string
96
     };
116
     };
97
 
117
 
98
     /**
118
     /**
105
         super(props);
125
         super(props);
106
 
126
 
107
         this.state = {
127
         this.state = {
128
+            /**
129
+             * The timeout for automatically hiding the indicator.
130
+             *
131
+             * @type {timeoutID}
132
+             */
133
+            autoHideTimeout: null,
134
+
135
+            /**
136
+             * Whether or not a CSS class should be applied to the root for
137
+             * hiding the connection indicator. By default the indicator should
138
+             * start out hidden because the current connection status is not
139
+             * known at mount.
140
+             *
141
+             * @type {boolean}
142
+             */
143
+            showIndicator: false,
144
+
108
             /**
145
             /**
109
              * Whether or not the popover content should display additional
146
              * Whether or not the popover content should display additional
110
              * statistics.
147
              * statistics.
154
     }
191
     }
155
 
192
 
156
     /**
193
     /**
157
-     * Sets the state to hide the Statistics Table popover.
194
+     * Cleans up any queued processes, which includes listening for new stats
195
+     * and clearing any timeout to hide the indicator.
158
      *
196
      *
159
      * @private
197
      * @private
160
      * @returns {void}
198
      * @returns {void}
162
     componentWillUnmount() {
200
     componentWillUnmount() {
163
         statsEmitter.unsubscribeToClientStats(
201
         statsEmitter.unsubscribeToClientStats(
164
             this.props.userID, this._onStatsUpdated);
202
             this.props.userID, this._onStatsUpdated);
203
+
204
+        clearTimeout(this.state.autoHideTimeout);
165
     }
205
     }
166
 
206
 
167
     /**
207
     /**
171
      * @returns {ReactElement}
211
      * @returns {ReactElement}
172
      */
212
      */
173
     render() {
213
     render() {
214
+        const visibilityClass = this._getVisibilityClass();
215
+        const rootClassNames = `indicator-container ${visibilityClass}`;
216
+
217
+        const colorClass = this._getConnectionColorClass();
218
+        const indicatorContainerClassNames
219
+            = `connection-indicator indicator ${colorClass}`;
220
+
174
         return (
221
         return (
175
             <Popover
222
             <Popover
176
-                className = 'indicator-container'
223
+                className = { rootClassNames }
177
                 content = { this._renderStatisticsTable() }
224
                 content = { this._renderStatisticsTable() }
178
                 position = { this.props.statsPopoverPosition }>
225
                 position = { this.props.statsPopoverPosition }>
179
                 <div className = 'popover-trigger'>
226
                 <div className = 'popover-trigger'>
180
-                    <div className = 'connection-indicator indicator'>
227
+                    <div
228
+                        className = { indicatorContainerClassNames }
229
+                        style = {{ fontSize: this.props.iconSize }}>
181
                         <div className = 'connection indicatoricon'>
230
                         <div className = 'connection indicatoricon'>
182
                             { this._renderIcon() }
231
                             { this._renderIcon() }
183
                         </div>
232
                         </div>
187
         );
236
         );
188
     }
237
     }
189
 
238
 
239
+    /**
240
+     * Returns a CSS class that interprets the current connection status as a
241
+     * color.
242
+     *
243
+     * @private
244
+     * @returns {string}
245
+     */
246
+    _getConnectionColorClass() {
247
+        const { connectionStatus } = this.props;
248
+        const { percent } = this.state.stats;
249
+        const { INACTIVE, INTERRUPTED } = JitsiParticipantConnectionStatus;
250
+
251
+        if (connectionStatus === INACTIVE) {
252
+            return 'status-other';
253
+        } else if (connectionStatus === INTERRUPTED) {
254
+            return 'status-lost';
255
+        } else if (typeof percent === 'undefined') {
256
+            return 'status-high';
257
+        }
258
+
259
+        return QUALITY_TO_WIDTH.find(x => percent >= x.percent).colorClass;
260
+    }
261
+
262
+    /**
263
+     * Returns a string that describes the current connection status.
264
+     *
265
+     * @private
266
+     * @returns {string}
267
+     */
268
+    _getConnectionStatusTip() {
269
+        let tipKey;
270
+
271
+        switch (this.props.connectionStatus) {
272
+        case JitsiParticipantConnectionStatus.INTERRUPTED:
273
+            tipKey = 'connectionindicator.quality.lost';
274
+            break;
275
+
276
+        case JitsiParticipantConnectionStatus.INACTIVE:
277
+            tipKey = 'connectionindicator.quality.inactive';
278
+            break;
279
+
280
+        default: {
281
+            const { percent } = this.state.stats;
282
+
283
+            if (typeof percent === 'undefined') {
284
+                // If percentage is undefined then there are no stats available
285
+                // yet, likely because only a local connection has been
286
+                // established so far. Assume a strong connection to start.
287
+                tipKey = 'connectionindicator.quality.good';
288
+            } else {
289
+                const config = QUALITY_TO_WIDTH.find(x => percent >= x.percent);
290
+
291
+                tipKey = config.tip;
292
+            }
293
+        }
294
+        }
295
+
296
+        return this.props.t(tipKey);
297
+    }
298
+
299
+    /**
300
+     * Returns additional class names to add to the root of the component. The
301
+     * class names are intended to be used for hiding or showing the indicator.
302
+     *
303
+     * @private
304
+     * @returns {string}
305
+     */
306
+    _getVisibilityClass() {
307
+        const { connectionStatus } = this.props;
308
+
309
+        return this.state.showIndicator
310
+            || this.props.alwaysVisible
311
+            || connectionStatus === JitsiParticipantConnectionStatus.INTERRUPTED
312
+            || connectionStatus === JitsiParticipantConnectionStatus.INACTIVE
313
+            ? 'show-connection-indicator' : 'hide-connection-indicator';
314
+    }
315
+
190
     /**
316
     /**
191
      * Callback invoked when new connection stats associated with the passed in
317
      * Callback invoked when new connection stats associated with the passed in
192
      * user ID are available. Will update the component's display of current
318
      * user ID are available. Will update the component's display of current
209
         this.setState({
335
         this.setState({
210
             stats: newStats
336
             stats: newStats
211
         });
337
         });
338
+
339
+        // Rely on React to batch setState actions.
340
+        this._updateIndicatorAutoHide(newStats.percent);
212
     }
341
     }
213
 
342
 
214
     /**
343
     /**
229
      * @returns {ReactElement}
358
      * @returns {ReactElement}
230
      */
359
      */
231
     _renderIcon() {
360
     _renderIcon() {
232
-        switch (this.props.connectionStatus) {
233
-        case JitsiParticipantConnectionStatus.INTERRUPTED:
234
-            return (
235
-                <span className = 'connection_lost'>
236
-                    <i className = 'icon-connection-lost' />
237
-                </span>
238
-            );
239
-        case JitsiParticipantConnectionStatus.INACTIVE:
361
+        if (this.props.connectionStatus
362
+            === JitsiParticipantConnectionStatus.INACTIVE) {
240
             return (
363
             return (
241
                 <span className = 'connection_ninja'>
364
                 <span className = 'connection_ninja'>
242
                     <i className = 'icon-ninja' />
365
                     <i className = 'icon-ninja' />
243
                 </span>
366
                 </span>
244
             );
367
             );
245
-        default: {
246
-            const { percent } = this.state.stats;
247
-            const width = QUALITY_TO_WIDTH.find(x => percent >= x.percent);
248
-            const iconWidth = width && width.width
249
-                ? { width: width && width.width } : {};
250
-
251
-            return [
252
-                <span
253
-                    className = 'connection_empty'
254
-                    key = 'icon-empty'>
255
-                    <i className = 'icon-connection' />
256
-                </span>,
257
-                <span
258
-                    className = 'connection_full'
259
-                    key = 'icon-full'
260
-                    style = { iconWidth }>
261
-                    <i className = 'icon-connection' />
262
-                </span>
263
-            ];
264
         }
368
         }
369
+
370
+        let iconWidth;
371
+        let emptyIconWrapperClassName = 'connection_empty';
372
+
373
+        if (this.props.connectionStatus
374
+            === JitsiParticipantConnectionStatus.INTERRUPTED) {
375
+
376
+            // emptyIconWrapperClassName is used by the torture tests to
377
+            // identify lost connection status handling.
378
+            emptyIconWrapperClassName = 'connection_lost';
379
+            iconWidth = '0%';
380
+        } else if (typeof this.state.stats.percent === 'undefined') {
381
+            iconWidth = '100%';
382
+        } else {
383
+            const { percent } = this.state.stats;
384
+
385
+            iconWidth = QUALITY_TO_WIDTH.find(x => percent >= x.percent).width;
265
         }
386
         }
387
+
388
+        return [
389
+            <span
390
+                className = { emptyIconWrapperClassName }
391
+                key = 'icon-empty'>
392
+                <i className = 'icon-gsm-bars' />
393
+            </span>,
394
+            <span
395
+                className = 'connection_full'
396
+                key = 'icon-full'
397
+                style = {{ width: iconWidth }}>
398
+                <i className = 'icon-gsm-bars' />
399
+            </span>
400
+        ];
266
     }
401
     }
267
 
402
 
268
     /**
403
     /**
284
             <ConnectionStatsTable
419
             <ConnectionStatsTable
285
                 bandwidth = { bandwidth }
420
                 bandwidth = { bandwidth }
286
                 bitrate = { bitrate }
421
                 bitrate = { bitrate }
422
+                connectionSummary = { this._getConnectionStatusTip() }
287
                 framerate = { framerate }
423
                 framerate = { framerate }
288
                 isLocalVideo = { this.props.isLocalVideo }
424
                 isLocalVideo = { this.props.isLocalVideo }
289
                 onShowMore = { this._onToggleShowMore }
425
                 onShowMore = { this._onToggleShowMore }
293
                 transport = { transport } />
429
                 transport = { transport } />
294
         );
430
         );
295
     }
431
     }
432
+
433
+    /**
434
+     * Updates the internal state for automatically hiding the indicator.
435
+     *
436
+     * @param {number} percent - The current connection quality percentage
437
+     * between the values 0 and 100.
438
+     * @private
439
+     * @returns {void}
440
+     */
441
+    _updateIndicatorAutoHide(percent) {
442
+        if (percent < INDICATOR_DISPLAY_THRESHOLD) {
443
+            clearTimeout(this.state.autoHideTimeout);
444
+            this.setState({
445
+                autoHideTimeout: null,
446
+                showIndicator: true
447
+            });
448
+        } else if (this.state.autoHideTimeout) {
449
+            // This clause is intentionally left blank because no further action
450
+            // is needed if the percent is below the threshold and there is an
451
+            // autoHideTimeout set.
452
+        } else {
453
+            this.setState({
454
+                autoHideTimeout: setTimeout(() => {
455
+                    this.setState({
456
+                        showIndicator: false
457
+                    });
458
+                }, interfaceConfig.CONNECTION_INDICATOR_AUTO_HIDE_TIMEOUT)
459
+            });
460
+        }
461
+    }
296
 }
462
 }
297
 
463
 
298
-export default ConnectionIndicator;
464
+export default translate(ConnectionIndicator);

+ 35
- 10
react/features/connection-stats/components/ConnectionStatsTable.js Datei anzeigen

1
+import PropTypes from 'prop-types';
1
 import React, { Component } from 'react';
2
 import React, { Component } from 'react';
2
 
3
 
3
 import { translate } from '../../base/i18n';
4
 import { translate } from '../../base/i18n';
21
          *     upload: Number
22
          *     upload: Number
22
          * }}
23
          * }}
23
          */
24
          */
24
-        bandwidth: React.PropTypes.object,
25
+        bandwidth: PropTypes.object,
25
 
26
 
26
         /**
27
         /**
27
          * Statistics related to bitrate.
28
          * Statistics related to bitrate.
30
          *     upload: Number
31
          *     upload: Number
31
          * }}
32
          * }}
32
          */
33
          */
33
-        bitrate: React.PropTypes.object,
34
+        bitrate: PropTypes.object,
35
+
36
+        /**
37
+         * A message describing the connection quality.
38
+         */
39
+        connectionSummary: PropTypes.string,
34
 
40
 
35
         /**
41
         /**
36
          * Statistics related to framerates for each ssrc.
42
          * Statistics related to framerates for each ssrc.
38
          *     [ ssrc ]: Number
44
          *     [ ssrc ]: Number
39
          * }}
45
          * }}
40
          */
46
          */
41
-        framerate: React.PropTypes.object,
47
+        framerate: PropTypes.object,
42
 
48
 
43
         /**
49
         /**
44
          * Whether or not the statitics are for local video.
50
          * Whether or not the statitics are for local video.
45
          */
51
          */
46
-        isLocalVideo: React.PropTypes.bool,
52
+        isLocalVideo: PropTypes.bool,
47
 
53
 
48
         /**
54
         /**
49
          * Callback to invoke when the show additional stats link is clicked.
55
          * Callback to invoke when the show additional stats link is clicked.
50
          */
56
          */
51
-        onShowMore: React.PropTypes.func,
57
+        onShowMore: PropTypes.func,
52
 
58
 
53
         /**
59
         /**
54
          * Statistics related to packet loss.
60
          * Statistics related to packet loss.
57
          *     upload: Number
63
          *     upload: Number
58
          * }}
64
          * }}
59
          */
65
          */
60
-        packetLoss: React.PropTypes.object,
66
+        packetLoss: PropTypes.object,
61
 
67
 
62
         /**
68
         /**
63
          * Statistics related to display resolutions for each ssrc.
69
          * Statistics related to display resolutions for each ssrc.
68
          *     }
74
          *     }
69
          * }}
75
          * }}
70
          */
76
          */
71
-        resolution: React.PropTypes.object,
77
+        resolution: PropTypes.object,
72
 
78
 
73
         /**
79
         /**
74
          * Whether or not additional stats about bandwidth and transport should
80
          * Whether or not additional stats about bandwidth and transport should
75
          * be displayed. Will not display even if true for remote participants.
81
          * be displayed. Will not display even if true for remote participants.
76
          */
82
          */
77
-        shouldShowMore: React.PropTypes.bool,
83
+        shouldShowMore: PropTypes.bool,
78
 
84
 
79
         /**
85
         /**
80
          * Invoked to obtain translated strings.
86
          * Invoked to obtain translated strings.
81
          */
87
          */
82
-        t: React.PropTypes.func,
88
+        t: PropTypes.func,
83
 
89
 
84
         /**
90
         /**
85
          * Statistics related to transports.
91
          * Statistics related to transports.
86
          */
92
          */
87
-        transport: React.PropTypes.array
93
+        transport: PropTypes.array
88
     };
94
     };
89
 
95
 
90
     /**
96
     /**
184
         );
190
         );
185
     }
191
     }
186
 
192
 
193
+    /**
194
+     * Creates a table row as a ReactElement for displaying a summary message
195
+     * about the current connection status.
196
+     *
197
+     * @private
198
+     * @returns {ReactElement}
199
+     */
200
+    _renderConnectionSummary() {
201
+        return (
202
+            <tr className = 'connection-info__status'>
203
+                <td>
204
+                    <span>{ this.props.t('connectionindicator.status') }</span>
205
+                </td>
206
+                <td>{ this.props.connectionSummary }</td>
207
+            </tr>
208
+        );
209
+    }
210
+
187
     /**
211
     /**
188
      * Creates a table row as a ReactElement for displaying frame rate related
212
      * Creates a table row as a ReactElement for displaying frame rate related
189
      * statistics.
213
      * statistics.
309
         return (
333
         return (
310
             <table className = 'connection-info__container'>
334
             <table className = 'connection-info__container'>
311
                 <tbody>
335
                 <tbody>
336
+                    { this._renderConnectionSummary() }
312
                     { this._renderBitrate() }
337
                     { this._renderBitrate() }
313
                     { this._renderPacketLoss() }
338
                     { this._renderPacketLoss() }
314
                     { this._renderResolution() }
339
                     { this._renderResolution() }

Laden…
Abbrechen
Speichern