浏览代码

Fix settings screen layout on iOS and add soft back button

master
zbettenbuk 7 年前
父节点
当前提交
410dc132e1

+ 6
- 1
css/_font.scss 查看文件

24
     -webkit-font-smoothing: antialiased;
24
     -webkit-font-smoothing: antialiased;
25
     -moz-osx-font-smoothing: grayscale;
25
     -moz-osx-font-smoothing: grayscale;
26
 }
26
 }
27
-
27
+.icon-arrow_back:before {
28
+  content: "\e5c4";
29
+}
30
+.icon-navigate_before:before {
31
+  content: "\e408";
32
+}
28
 .icon-event_note:before {
33
 .icon-event_note:before {
29
     content: "\e616";
34
     content: "\e616";
30
 }
35
 }

二进制
fonts/jitsi.eot 查看文件


+ 2
- 0
fonts/jitsi.svg 查看文件

11
 <glyph unicode="&#xe145;" glyph-name="add" d="M810 470h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" />
11
 <glyph unicode="&#xe145;" glyph-name="add" d="M810 470h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" />
12
 <glyph unicode="&#xe1aa;" glyph-name="bluetooth" d="M550 328l-80 82v-162zM470 776v-162l80 82zM670 696l-184-184 184-184-244-242h-42v324l-196-196-60 60 238 238-238 238 60 60 196-196v324h42zM834 738c40-64 62-142 62-222 0-84-24-160-66-226l-50 50c26 52 42 110 42 172s-16 120-42 172zM608 512l98 98c12-30 20-64 20-98s-8-70-20-100z" />
12
 <glyph unicode="&#xe1aa;" glyph-name="bluetooth" d="M550 328l-80 82v-162zM470 776v-162l80 82zM670 696l-184-184 184-184-244-242h-42v324l-196-196-60 60 238 238-238 238 60 60 196-196v324h42zM834 738c40-64 62-142 62-222 0-84-24-160-66-226l-50 50c26 52 42 110 42 172s-16 120-42 172zM608 512l98 98c12-30 20-64 20-98s-8-70-20-100z" />
13
 <glyph unicode="&#xe310;" glyph-name="headset" d="M512 982c212 0 384-172 384-384v-300c0-70-58-128-128-128h-128v342h170v86c0 166-132 298-298 298s-298-132-298-298v-86h170v-342h-128c-70 0-128 58-128 128v300c0 212 172 384 384 384z" />
13
 <glyph unicode="&#xe310;" glyph-name="headset" d="M512 982c212 0 384-172 384-384v-300c0-70-58-128-128-128h-128v342h170v86c0 166-132 298-298 298s-298-132-298-298v-86h170v-342h-128c-70 0-128 58-128 128v300c0 212 172 384 384 384z" />
14
+<glyph unicode="&#xe408;" glyph-name="navigate_before" d="M658 708l-196-196 196-196-60-60-256 256 256 256z" />
14
 <glyph unicode="&#xe425;" glyph-name="timer" d="M512 170c166 0 298 134 298 300s-132 298-298 298-298-132-298-298 132-300 298-300zM812 708c52-66 84-148 84-238 0-212-172-384-384-384s-384 172-384 384 172 384 384 384c90 0 174-34 240-86l60 62c22-18 42-38 60-60zM470 426v256h84v-256h-84zM640 982v-86h-256v86h256z" />
15
 <glyph unicode="&#xe425;" glyph-name="timer" d="M512 170c166 0 298 134 298 300s-132 298-298 298-298-132-298-298 132-300 298-300zM812 708c52-66 84-148 84-238 0-212-172-384-384-384s-384 172-384 384 172 384 384 384c90 0 174-34 240-86l60 62c22-18 42-38 60-60zM470 426v256h84v-256h-84zM640 982v-86h-256v86h256z" />
16
+<glyph unicode="&#xe5c4;" glyph-name="arrow_back" d="M854 554v-84h-520l238-240-60-60-342 342 342 342 60-60-238-240h520z" />
15
 <glyph unicode="&#xe5d4;" glyph-name="thumb-menu" d="M512 342c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 598c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 682c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86z" />
17
 <glyph unicode="&#xe5d4;" glyph-name="thumb-menu" d="M512 342c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 598c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM512 682c-46 0-86 40-86 86s40 86 86 86 86-40 86-86-40-86-86-86z" />
16
 <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" />
18
 <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" />
17
 <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" />
19
 <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" />

二进制
fonts/jitsi.ttf 查看文件


二进制
fonts/jitsi.woff 查看文件


+ 107
- 53
fonts/selection.json 查看文件

1
 {
1
 {
2
   "IcoMoonType": "selection",
2
   "IcoMoonType": "selection",
3
   "icons": [
3
   "icons": [
4
+    {
5
+      "icon": {
6
+        "paths": [
7
+          "M854 470v84h-520l238 240-60 60-342-342 342-342 60 60-238 240h520z"
8
+        ],
9
+        "attrs": [],
10
+        "isMulticolor": false,
11
+        "isMulticolor2": false,
12
+        "tags": [
13
+          "arrow_back"
14
+        ],
15
+        "defaultCode": 58820,
16
+        "grid": 24
17
+      },
18
+      "attrs": [],
19
+      "properties": {
20
+        "ligatures": "arrow_back",
21
+        "id": 45,
22
+        "order": 924,
23
+        "prevSize": 24,
24
+        "code": 58820,
25
+        "name": "arrow_back"
26
+      },
27
+      "setIdx": 0,
28
+      "setId": 2,
29
+      "iconIdx": 45
30
+    },
31
+    {
32
+      "icon": {
33
+        "paths": [
34
+          "M658 316l-196 196 196 196-60 60-256-256 256-256z"
35
+        ],
36
+        "attrs": [],
37
+        "isMulticolor": false,
38
+        "isMulticolor2": false,
39
+        "tags": [
40
+          "navigate_before"
41
+        ],
42
+        "defaultCode": 58376,
43
+        "grid": 24
44
+      },
45
+      "attrs": [],
46
+      "properties": {
47
+        "ligatures": "chevron_left, navigate_before",
48
+        "id": 152,
49
+        "order": 923,
50
+        "prevSize": 24,
51
+        "code": 58376,
52
+        "name": "navigate_before"
53
+      },
54
+      "setIdx": 0,
55
+      "setId": 2,
56
+      "iconIdx": 152
57
+    },
4
     {
58
     {
5
       "icon": {
59
       "icon": {
6
         "paths": [
60
         "paths": [
24
         "code": 59403,
78
         "code": 59403,
25
         "name": "public"
79
         "name": "public"
26
       },
80
       },
27
-      "setIdx": 0,
28
-      "setId": 2,
29
-      "iconIdx": 605
81
+      "setIdx": 1,
82
+      "setId": 1,
83
+      "iconIdx": 0
30
     },
84
     },
31
     {
85
     {
32
       "icon": {
86
       "icon": {
53
       },
107
       },
54
       "setIdx": 1,
108
       "setIdx": 1,
55
       "setId": 1,
109
       "setId": 1,
56
-      "iconIdx": 0
110
+      "iconIdx": 1
57
     },
111
     },
58
     {
112
     {
59
       "icon": {
113
       "icon": {
80
       },
134
       },
81
       "setIdx": 1,
135
       "setIdx": 1,
82
       "setId": 1,
136
       "setId": 1,
83
-      "iconIdx": 1
137
+      "iconIdx": 2
84
     },
138
     },
85
     {
139
     {
86
       "icon": {
140
       "icon": {
107
       },
161
       },
108
       "setIdx": 1,
162
       "setIdx": 1,
109
       "setId": 1,
163
       "setId": 1,
110
-      "iconIdx": 2
164
+      "iconIdx": 3
111
     },
165
     },
112
     {
166
     {
113
       "icon": {
167
       "icon": {
134
       },
188
       },
135
       "setIdx": 1,
189
       "setIdx": 1,
136
       "setId": 1,
190
       "setId": 1,
137
-      "iconIdx": 3
191
+      "iconIdx": 4
138
     },
192
     },
139
     {
193
     {
140
       "icon": {
194
       "icon": {
161
       },
215
       },
162
       "setIdx": 1,
216
       "setIdx": 1,
163
       "setId": 1,
217
       "setId": 1,
164
-      "iconIdx": 4
218
+      "iconIdx": 5
165
     },
219
     },
166
     {
220
     {
167
       "icon": {
221
       "icon": {
188
       },
242
       },
189
       "setIdx": 1,
243
       "setIdx": 1,
190
       "setId": 1,
244
       "setId": 1,
191
-      "iconIdx": 5
245
+      "iconIdx": 6
192
     },
246
     },
193
     {
247
     {
194
       "icon": {
248
       "icon": {
217
       },
271
       },
218
       "setIdx": 1,
272
       "setIdx": 1,
219
       "setId": 1,
273
       "setId": 1,
220
-      "iconIdx": 6
274
+      "iconIdx": 7
221
     },
275
     },
222
     {
276
     {
223
       "icon": {
277
       "icon": {
244
       },
298
       },
245
       "setIdx": 1,
299
       "setIdx": 1,
246
       "setId": 1,
300
       "setId": 1,
247
-      "iconIdx": 7
301
+      "iconIdx": 8
248
     },
302
     },
249
     {
303
     {
250
       "icon": {
304
       "icon": {
271
       },
325
       },
272
       "setIdx": 1,
326
       "setIdx": 1,
273
       "setId": 1,
327
       "setId": 1,
274
-      "iconIdx": 8
328
+      "iconIdx": 9
275
     },
329
     },
276
     {
330
     {
277
       "icon": {
331
       "icon": {
300
       },
354
       },
301
       "setIdx": 1,
355
       "setIdx": 1,
302
       "setId": 1,
356
       "setId": 1,
303
-      "iconIdx": 9
357
+      "iconIdx": 10
304
     },
358
     },
305
     {
359
     {
306
       "icon": {
360
       "icon": {
329
       },
383
       },
330
       "setIdx": 1,
384
       "setIdx": 1,
331
       "setId": 1,
385
       "setId": 1,
332
-      "iconIdx": 10
386
+      "iconIdx": 11
333
     },
387
     },
334
     {
388
     {
335
       "icon": {
389
       "icon": {
358
       },
412
       },
359
       "setIdx": 1,
413
       "setIdx": 1,
360
       "setId": 1,
414
       "setId": 1,
361
-      "iconIdx": 11
415
+      "iconIdx": 12
362
     },
416
     },
363
     {
417
     {
364
       "icon": {
418
       "icon": {
387
       },
441
       },
388
       "setIdx": 1,
442
       "setIdx": 1,
389
       "setId": 1,
443
       "setId": 1,
390
-      "iconIdx": 12
444
+      "iconIdx": 13
391
     },
445
     },
392
     {
446
     {
393
       "icon": {
447
       "icon": {
416
       },
470
       },
417
       "setIdx": 1,
471
       "setIdx": 1,
418
       "setId": 1,
472
       "setId": 1,
419
-      "iconIdx": 13
473
+      "iconIdx": 14
420
     },
474
     },
421
     {
475
     {
422
       "icon": {
476
       "icon": {
442
       },
496
       },
443
       "setIdx": 1,
497
       "setIdx": 1,
444
       "setId": 1,
498
       "setId": 1,
445
-      "iconIdx": 14
499
+      "iconIdx": 15
446
     },
500
     },
447
     {
501
     {
448
       "icon": {
502
       "icon": {
468
       },
522
       },
469
       "setIdx": 1,
523
       "setIdx": 1,
470
       "setId": 1,
524
       "setId": 1,
471
-      "iconIdx": 15
525
+      "iconIdx": 16
472
     },
526
     },
473
     {
527
     {
474
       "icon": {
528
       "icon": {
494
       },
548
       },
495
       "setIdx": 1,
549
       "setIdx": 1,
496
       "setId": 1,
550
       "setId": 1,
497
-      "iconIdx": 16
551
+      "iconIdx": 17
498
     },
552
     },
499
     {
553
     {
500
       "icon": {
554
       "icon": {
520
       },
574
       },
521
       "setIdx": 1,
575
       "setIdx": 1,
522
       "setId": 1,
576
       "setId": 1,
523
-      "iconIdx": 17
577
+      "iconIdx": 18
524
     },
578
     },
525
     {
579
     {
526
       "icon": {
580
       "icon": {
546
       },
600
       },
547
       "setIdx": 1,
601
       "setIdx": 1,
548
       "setId": 1,
602
       "setId": 1,
549
-      "iconIdx": 18
603
+      "iconIdx": 19
550
     },
604
     },
551
     {
605
     {
552
       "icon": {
606
       "icon": {
572
       },
626
       },
573
       "setIdx": 1,
627
       "setIdx": 1,
574
       "setId": 1,
628
       "setId": 1,
575
-      "iconIdx": 19
629
+      "iconIdx": 20
576
     },
630
     },
577
     {
631
     {
578
       "icon": {
632
       "icon": {
598
       },
652
       },
599
       "setIdx": 1,
653
       "setIdx": 1,
600
       "setId": 1,
654
       "setId": 1,
601
-      "iconIdx": 20
655
+      "iconIdx": 21
602
     },
656
     },
603
     {
657
     {
604
       "icon": {
658
       "icon": {
616
       "attrs": [],
670
       "attrs": [],
617
       "properties": {
671
       "properties": {
618
         "id": 10,
672
         "id": 10,
619
-        "order": 900,
673
+        "order": 922,
620
         "ligatures": "expand_less",
674
         "ligatures": "expand_less",
621
         "prevSize": 32,
675
         "prevSize": 32,
622
         "code": 59679,
676
         "code": 59679,
624
       },
678
       },
625
       "setIdx": 1,
679
       "setIdx": 1,
626
       "setId": 1,
680
       "setId": 1,
627
-      "iconIdx": 21
681
+      "iconIdx": 22
628
     },
682
     },
629
     {
683
     {
630
       "icon": {
684
       "icon": {
650
       },
704
       },
651
       "setIdx": 1,
705
       "setIdx": 1,
652
       "setId": 1,
706
       "setId": 1,
653
-      "iconIdx": 22
707
+      "iconIdx": 23
654
     },
708
     },
655
     {
709
     {
656
       "icon": {
710
       "icon": {
676
       },
730
       },
677
       "setIdx": 1,
731
       "setIdx": 1,
678
       "setId": 1,
732
       "setId": 1,
679
-      "iconIdx": 23
733
+      "iconIdx": 24
680
     },
734
     },
681
     {
735
     {
682
       "icon": {
736
       "icon": {
702
       },
756
       },
703
       "setIdx": 1,
757
       "setIdx": 1,
704
       "setId": 1,
758
       "setId": 1,
705
-      "iconIdx": 24
759
+      "iconIdx": 25
706
     },
760
     },
707
     {
761
     {
708
       "icon": {
762
       "icon": {
728
       },
782
       },
729
       "setIdx": 1,
783
       "setIdx": 1,
730
       "setId": 1,
784
       "setId": 1,
731
-      "iconIdx": 25
785
+      "iconIdx": 26
732
     },
786
     },
733
     {
787
     {
734
       "icon": {
788
       "icon": {
754
       },
808
       },
755
       "setIdx": 1,
809
       "setIdx": 1,
756
       "setId": 1,
810
       "setId": 1,
757
-      "iconIdx": 26
811
+      "iconIdx": 27
758
     },
812
     },
759
     {
813
     {
760
       "icon": {
814
       "icon": {
780
       },
834
       },
781
       "setIdx": 1,
835
       "setIdx": 1,
782
       "setId": 1,
836
       "setId": 1,
783
-      "iconIdx": 27
837
+      "iconIdx": 28
784
     },
838
     },
785
     {
839
     {
786
       "icon": {
840
       "icon": {
806
       },
860
       },
807
       "setIdx": 1,
861
       "setIdx": 1,
808
       "setId": 1,
862
       "setId": 1,
809
-      "iconIdx": 28
863
+      "iconIdx": 29
810
     },
864
     },
811
     {
865
     {
812
       "icon": {
866
       "icon": {
832
       },
886
       },
833
       "setIdx": 1,
887
       "setIdx": 1,
834
       "setId": 1,
888
       "setId": 1,
835
-      "iconIdx": 29
889
+      "iconIdx": 30
836
     },
890
     },
837
     {
891
     {
838
       "icon": {
892
       "icon": {
858
       },
912
       },
859
       "setIdx": 1,
913
       "setIdx": 1,
860
       "setId": 1,
914
       "setId": 1,
861
-      "iconIdx": 30
915
+      "iconIdx": 31
862
     },
916
     },
863
     {
917
     {
864
       "icon": {
918
       "icon": {
884
       },
938
       },
885
       "setIdx": 1,
939
       "setIdx": 1,
886
       "setId": 1,
940
       "setId": 1,
887
-      "iconIdx": 31
941
+      "iconIdx": 32
888
     },
942
     },
889
     {
943
     {
890
       "icon": {
944
       "icon": {
910
       },
964
       },
911
       "setIdx": 1,
965
       "setIdx": 1,
912
       "setId": 1,
966
       "setId": 1,
913
-      "iconIdx": 32
967
+      "iconIdx": 33
914
     },
968
     },
915
     {
969
     {
916
       "icon": {
970
       "icon": {
936
       },
990
       },
937
       "setIdx": 1,
991
       "setIdx": 1,
938
       "setId": 1,
992
       "setId": 1,
939
-      "iconIdx": 33
993
+      "iconIdx": 34
940
     },
994
     },
941
     {
995
     {
942
       "icon": {
996
       "icon": {
962
       },
1016
       },
963
       "setIdx": 1,
1017
       "setIdx": 1,
964
       "setId": 1,
1018
       "setId": 1,
965
-      "iconIdx": 34
1019
+      "iconIdx": 35
966
     },
1020
     },
967
     {
1021
     {
968
       "icon": {
1022
       "icon": {
988
       },
1042
       },
989
       "setIdx": 1,
1043
       "setIdx": 1,
990
       "setId": 1,
1044
       "setId": 1,
991
-      "iconIdx": 35
1045
+      "iconIdx": 36
992
     },
1046
     },
993
     {
1047
     {
994
       "icon": {
1048
       "icon": {
1014
       },
1068
       },
1015
       "setIdx": 1,
1069
       "setIdx": 1,
1016
       "setId": 1,
1070
       "setId": 1,
1017
-      "iconIdx": 36
1071
+      "iconIdx": 37
1018
     },
1072
     },
1019
     {
1073
     {
1020
       "icon": {
1074
       "icon": {
1040
       },
1094
       },
1041
       "setIdx": 1,
1095
       "setIdx": 1,
1042
       "setId": 1,
1096
       "setId": 1,
1043
-      "iconIdx": 37
1097
+      "iconIdx": 38
1044
     },
1098
     },
1045
     {
1099
     {
1046
       "icon": {
1100
       "icon": {
1066
       },
1120
       },
1067
       "setIdx": 1,
1121
       "setIdx": 1,
1068
       "setId": 1,
1122
       "setId": 1,
1069
-      "iconIdx": 38
1123
+      "iconIdx": 39
1070
     },
1124
     },
1071
     {
1125
     {
1072
       "icon": {
1126
       "icon": {
1092
       },
1146
       },
1093
       "setIdx": 1,
1147
       "setIdx": 1,
1094
       "setId": 1,
1148
       "setId": 1,
1095
-      "iconIdx": 39
1149
+      "iconIdx": 40
1096
     },
1150
     },
1097
     {
1151
     {
1098
       "icon": {
1152
       "icon": {
1118
       },
1172
       },
1119
       "setIdx": 1,
1173
       "setIdx": 1,
1120
       "setId": 1,
1174
       "setId": 1,
1121
-      "iconIdx": 40
1175
+      "iconIdx": 41
1122
     },
1176
     },
1123
     {
1177
     {
1124
       "icon": {
1178
       "icon": {
1144
       },
1198
       },
1145
       "setIdx": 1,
1199
       "setIdx": 1,
1146
       "setId": 1,
1200
       "setId": 1,
1147
-      "iconIdx": 41
1201
+      "iconIdx": 42
1148
     },
1202
     },
1149
     {
1203
     {
1150
       "icon": {
1204
       "icon": {
1170
       },
1224
       },
1171
       "setIdx": 1,
1225
       "setIdx": 1,
1172
       "setId": 1,
1226
       "setId": 1,
1173
-      "iconIdx": 42
1227
+      "iconIdx": 43
1174
     },
1228
     },
1175
     {
1229
     {
1176
       "icon": {
1230
       "icon": {
1199
       },
1253
       },
1200
       "setIdx": 1,
1254
       "setIdx": 1,
1201
       "setId": 1,
1255
       "setId": 1,
1202
-      "iconIdx": 43
1256
+      "iconIdx": 44
1203
     },
1257
     },
1204
     {
1258
     {
1205
       "icon": {
1259
       "icon": {
1229
       },
1283
       },
1230
       "setIdx": 1,
1284
       "setIdx": 1,
1231
       "setId": 1,
1285
       "setId": 1,
1232
-      "iconIdx": 44
1286
+      "iconIdx": 45
1233
     },
1287
     },
1234
     {
1288
     {
1235
       "icon": {
1289
       "icon": {
1259
       },
1313
       },
1260
       "setIdx": 1,
1314
       "setIdx": 1,
1261
       "setId": 1,
1315
       "setId": 1,
1262
-      "iconIdx": 45
1316
+      "iconIdx": 46
1263
     },
1317
     },
1264
     {
1318
     {
1265
       "icon": {
1319
       "icon": {
1285
       },
1339
       },
1286
       "setIdx": 1,
1340
       "setIdx": 1,
1287
       "setId": 1,
1341
       "setId": 1,
1288
-      "iconIdx": 46
1342
+      "iconIdx": 47
1289
     },
1343
     },
1290
     {
1344
     {
1291
       "icon": {
1345
       "icon": {
1311
       },
1365
       },
1312
       "setIdx": 1,
1366
       "setIdx": 1,
1313
       "setId": 1,
1367
       "setId": 1,
1314
-      "iconIdx": 47
1368
+      "iconIdx": 48
1315
     },
1369
     },
1316
     {
1370
     {
1317
       "icon": {
1371
       "icon": {
1337
       },
1391
       },
1338
       "setIdx": 1,
1392
       "setIdx": 1,
1339
       "setId": 1,
1393
       "setId": 1,
1340
-      "iconIdx": 48
1394
+      "iconIdx": 49
1341
     }
1395
     }
1342
   ],
1396
   ],
1343
   "height": 1024,
1397
   "height": 1024,

+ 2
- 0
lang/main.json 查看文件

539
         "tooltip": "Get access info about the meeting"
539
         "tooltip": "Get access info about the meeting"
540
     },
540
     },
541
     "profileModal": {
541
     "profileModal": {
542
+        "conferenceSection": "Conference",
542
         "displayName": "Display name",
543
         "displayName": "Display name",
543
         "email": "Email",
544
         "email": "Email",
544
         "header": "Settings",
545
         "header": "Settings",
546
+        "profileSection": "Profile",
545
         "serverURL": "Server URL",
547
         "serverURL": "Server URL",
546
         "startWithAudioMuted": "Start with audio muted",
548
         "startWithAudioMuted": "Start with audio muted",
547
         "startWithVideoMuted": "Start with video muted"
549
         "startWithVideoMuted": "Start with video muted"

+ 1
- 4
react/features/app-settings/actions.js 查看文件

1
 /* @flow */
1
 /* @flow */
2
 
2
 
3
-import {
4
-    HIDE_APP_SETTINGS,
5
-    SHOW_APP_SETTINGS
6
-} from './actionTypes';
3
+import { HIDE_APP_SETTINGS, SHOW_APP_SETTINGS } from './actionTypes';
7
 
4
 
8
 /**
5
 /**
9
 * Redux-signals the request to open the app settings modal.
6
 * Redux-signals the request to open the app settings modal.

+ 24
- 147
react/features/app-settings/components/AbstractAppSettings.js 查看文件

10
 */
10
 */
11
 type Props = {
11
 type Props = {
12
 
12
 
13
+    /**
14
+    * The current aspect ratio of the screen.
15
+    */
16
+    _aspectRatio: Symbol,
17
+
18
+    /**
19
+    * The default URL for when there is no custom URL set in the profile.
20
+    */
21
+    _serverURL: string,
22
+
13
     /**
23
     /**
14
     * The current profile object.
24
     * The current profile object.
15
     */
25
     */
26
     dispatch: Dispatch<*>
36
     dispatch: Dispatch<*>
27
 };
37
 };
28
 
38
 
29
-/**
30
- * The type of the React {@code Component} state of {@link AbstractAppSettings}.
31
- */
32
-type State = {
33
-
34
-    /**
35
-    * The display name field value on the settings screen.
36
-    */
37
-    displayName: string,
38
-
39
-    /**
40
-    * The email field value on the settings screen.
41
-    */
42
-    email: string,
43
-
44
-    /**
45
-    * The server url field value on the settings screen.
46
-    */
47
-    serverURL: string,
48
-
49
-    /**
50
-    * The start audio muted switch value on the settings screen.
51
-    */
52
-    startWithAudioMuted: boolean,
53
-
54
-    /**
55
-    * The start video muted switch value on the settings screen.
56
-    */
57
-    startWithVideoMuted: boolean
58
-}
59
-
60
 /**
39
 /**
61
  * Base (abstract) class for container component rendering
40
  * Base (abstract) class for container component rendering
62
  * the app settings page.
41
  * the app settings page.
63
  *
42
  *
64
  * @abstract
43
  * @abstract
65
  */
44
  */
66
-export class AbstractAppSettings extends Component<Props, State> {
67
-
45
+export class AbstractAppSettings extends Component<Props> {
68
     /**
46
     /**
69
      * Initializes a new {@code AbstractAppSettings} instance.
47
      * Initializes a new {@code AbstractAppSettings} instance.
70
      *
48
      *
76
 
54
 
77
         this._onChangeDisplayName = this._onChangeDisplayName.bind(this);
55
         this._onChangeDisplayName = this._onChangeDisplayName.bind(this);
78
         this._onChangeEmail = this._onChangeEmail.bind(this);
56
         this._onChangeEmail = this._onChangeEmail.bind(this);
79
-        this._onChangeServerName = this._onChangeServerName.bind(this);
57
+        this._onChangeServerURL = this._onChangeServerURL.bind(this);
80
         this._onRequestClose = this._onRequestClose.bind(this);
58
         this._onRequestClose = this._onRequestClose.bind(this);
81
-        this._onSaveDisplayName = this._onSaveDisplayName.bind(this);
82
-        this._onSaveEmail = this._onSaveEmail.bind(this);
83
-        this._onSaveServerName = this._onSaveServerName.bind(this);
84
         this._onStartAudioMutedChange
59
         this._onStartAudioMutedChange
85
             = this._onStartAudioMutedChange.bind(this);
60
             = this._onStartAudioMutedChange.bind(this);
86
         this._onStartVideoMutedChange
61
         this._onStartVideoMutedChange
87
             = this._onStartVideoMutedChange.bind(this);
62
             = this._onStartVideoMutedChange.bind(this);
88
     }
63
     }
89
 
64
 
90
-    /**
91
-     * Invokes React's {@link Component#componentWillReceiveProps()} to make
92
-     * sure we have the state Initialized on component mount.
93
-     *
94
-     * @inheritdoc
95
-     */
96
-    componentWillMount() {
97
-        this._updateStateFromProps(this.props);
98
-    }
99
-
100
-    /**
101
-     * Implements React's {@link Component#componentWillReceiveProps()}. Invoked
102
-     * before this mounted component receives new props.
103
-     *
104
-     * @inheritdoc
105
-     * @param {Props} nextProps - New props component will receive.
106
-     */
107
-    componentWillReceiveProps(nextProps: Props) {
108
-        this._updateStateFromProps(nextProps);
109
-    }
110
-
111
     _onChangeDisplayName: (string) => void;
65
     _onChangeDisplayName: (string) => void;
112
 
66
 
113
     /**
67
     /**
118
     * @returns {void}
72
     * @returns {void}
119
     */
73
     */
120
     _onChangeDisplayName(text) {
74
     _onChangeDisplayName(text) {
121
-        this.setState({
75
+        this._updateProfile({
122
             displayName: text
76
             displayName: text
123
         });
77
         });
124
     }
78
     }
133
     * @returns {void}
87
     * @returns {void}
134
     */
88
     */
135
     _onChangeEmail(text) {
89
     _onChangeEmail(text) {
136
-        this.setState({
90
+        this._updateProfile({
137
             email: text
91
             email: text
138
         });
92
         });
139
     }
93
     }
140
 
94
 
141
-    _onChangeServerName: (string) => void;
95
+    _onChangeServerURL: (string) => void;
142
 
96
 
143
     /**
97
     /**
144
     * Handles the server name field value change.
98
     * Handles the server name field value change.
147
     * @param {string} text - The server URL typed in the server field.
101
     * @param {string} text - The server URL typed in the server field.
148
     * @returns {void}
102
     * @returns {void}
149
     */
103
     */
150
-    _onChangeServerName(text) {
151
-        this.setState({
104
+    _onChangeServerURL(text) {
105
+        this._updateProfile({
152
             serverURL: text
106
             serverURL: text
153
         });
107
         });
154
     }
108
     }
156
     _onRequestClose: () => void;
110
     _onRequestClose: () => void;
157
 
111
 
158
     /**
112
     /**
159
-    * Handles the hardware back button.
113
+    * Handles the back button.
160
     *
114
     *
161
     * @returns {void}
115
     * @returns {void}
162
     */
116
     */
164
         this.props.dispatch(hideAppSettings());
118
         this.props.dispatch(hideAppSettings());
165
     }
119
     }
166
 
120
 
167
-    _onSaveDisplayName: () => void;
168
-
169
-    /**
170
-    * Handles the display name field onEndEditing.
171
-    *
172
-    * @protected
173
-    * @returns {void}
174
-    */
175
-    _onSaveDisplayName() {
176
-        this._updateProfile({
177
-            displayName: this.state.displayName
178
-        });
179
-    }
180
-
181
-    _onSaveEmail: () => void;
182
-
183
-    /**
184
-    * Handles the email field onEndEditing.
185
-    *
186
-    * @protected
187
-    * @returns {void}
188
-    */
189
-    _onSaveEmail() {
190
-        this._updateProfile({
191
-            email: this.state.email
192
-        });
193
-    }
194
-
195
-    _onSaveServerName: () => void;
196
-
197
-    /**
198
-    * Handles the server name field onEndEditing.
199
-    *
200
-    * @protected
201
-    * @returns {void}
202
-    */
203
-    _onSaveServerName() {
204
-        let serverURL;
205
-
206
-        if (this.state.serverURL.endsWith('/')) {
207
-            serverURL = this.state.serverURL.substr(
208
-                0, this.state.serverURL.length - 1
209
-            );
210
-        } else {
211
-            serverURL = this.state.serverURL;
212
-        }
213
-
214
-        this._updateProfile({
215
-            defaultURL: serverURL
216
-        });
217
-        this.setState({
218
-            serverURL
219
-        });
220
-    }
221
-
222
     _onStartAudioMutedChange: (boolean) => void;
121
     _onStartAudioMutedChange: (boolean) => void;
223
 
122
 
224
     /**
123
     /**
230
     * @returns {void}
129
     * @returns {void}
231
     */
130
     */
232
     _onStartAudioMutedChange(newValue) {
131
     _onStartAudioMutedChange(newValue) {
233
-        this.setState({
234
-            startWithAudioMuted: newValue
235
-        });
236
-
237
         this._updateProfile({
132
         this._updateProfile({
238
             startWithAudioMuted: newValue
133
             startWithAudioMuted: newValue
239
         });
134
         });
250
     * @returns {void}
145
     * @returns {void}
251
     */
146
     */
252
     _onStartVideoMutedChange(newValue) {
147
     _onStartVideoMutedChange(newValue) {
253
-        this.setState({
254
-            startWithVideoMuted: newValue
255
-        });
256
-
257
         this._updateProfile({
148
         this._updateProfile({
258
             startWithVideoMuted: newValue
149
             startWithVideoMuted: newValue
259
         });
150
         });
274
             ...updateObject
165
             ...updateObject
275
         }));
166
         }));
276
     }
167
     }
277
-
278
-    _updateStateFromProps: (Object) => void;
279
-
280
-    /**
281
-    * Updates the component state when (new) props are received.
282
-    *
283
-    * @private
284
-    * @param {Object} props - The component's props.
285
-    * @returns {void}
286
-    */
287
-    _updateStateFromProps(props) {
288
-        this.setState({
289
-            displayName: props._profile.displayName,
290
-            email: props._profile.email,
291
-            serverURL: props._profile.defaultURL,
292
-            startWithAudioMuted: props._profile.startWithAudioMuted,
293
-            startWithVideoMuted: props._profile.startWithVideoMuted
294
-        });
295
-    }
296
 }
168
 }
297
 
169
 
298
 /**
170
 /**
304
  * @returns {Object}
176
  * @returns {Object}
305
  */
177
  */
306
 export function _mapStateToProps(state: Object) {
178
 export function _mapStateToProps(state: Object) {
179
+    const _serverURL = state['features/app'].app._getDefaultURL();
180
+    const _profile = getProfile(state);
181
+
307
     return {
182
     return {
308
-        _profile: getProfile(state),
183
+        _aspectRatio: state['features/base/aspect-ratio'].aspectRatio,
184
+        _serverURL,
185
+        _profile,
309
         _visible: state['features/app-settings'].visible
186
         _visible: state['features/app-settings'].visible
310
     };
187
     };
311
 }
188
 }

+ 77
- 24
react/features/app-settings/components/AppSettings.native.js 查看文件

1
 import React from 'react';
1
 import React from 'react';
2
 import {
2
 import {
3
     Modal,
3
     Modal,
4
+    ScrollView,
4
     Switch,
5
     Switch,
5
     Text,
6
     Text,
6
     TextInput,
7
     TextInput,
11
     _mapStateToProps,
12
     _mapStateToProps,
12
     AbstractAppSettings
13
     AbstractAppSettings
13
 } from './AbstractAppSettings';
14
 } from './AbstractAppSettings';
15
+import BackButton from './BackButton';
14
 import FormRow from './FormRow';
16
 import FormRow from './FormRow';
15
-import styles from './styles';
17
+import FormSectionHeader from './FormSectionHeader';
18
+import styles, { HEADER_PADDING } from './styles';
16
 
19
 
20
+import { getSafetyOffset } from '../functions.native';
21
+
22
+import { ASPECT_RATIO_NARROW } from '../../base/aspect-ratio';
17
 import { translate } from '../../base/i18n';
23
 import { translate } from '../../base/i18n';
24
+import { isIPad } from '../../base/react';
18
 
25
 
19
 /**
26
 /**
20
  * The native container rendering the app settings page.
27
  * The native container rendering the app settings page.
22
  * @extends AbstractAppSettings
29
  * @extends AbstractAppSettings
23
  */
30
  */
24
 class AppSettings extends AbstractAppSettings {
31
 class AppSettings extends AbstractAppSettings {
32
+    /**
33
+    * Instantiates a new {@code AppSettings} instance.
34
+    *
35
+    * @inheritdoc
36
+    */
37
+    constructor(props) {
38
+        super(props);
39
+
40
+        this._getSafetyPadding = this._getSafetyPadding.bind(this);
41
+    }
25
 
42
 
26
     /**
43
     /**
27
      * Implements React's {@link Component#render()}, renders the settings page.
44
      * Implements React's {@link Component#render()}, renders the settings page.
30
      * @returns {ReactElement}
47
      * @returns {ReactElement}
31
      */
48
      */
32
     render() {
49
     render() {
33
-        const { t } = this.props;
50
+        const { _profile, t } = this.props;
51
+
52
+        // FIXME: presentationStyle is added to workaround
53
+        // orientation issue on iOS
34
 
54
 
35
         return (
55
         return (
36
             <Modal
56
             <Modal
37
                 animationType = 'slide'
57
                 animationType = 'slide'
38
                 onRequestClose = { this._onRequestClose }
58
                 onRequestClose = { this._onRequestClose }
39
-                presentationStyle = 'fullScreen'
40
-                style = { styles.modal }
59
+                presentationStyle = 'overFullScreen'
60
+                supportedOrientations = { [
61
+                    'landscape',
62
+                    'portrait'
63
+                ] }
41
                 visible = { this.props._visible }>
64
                 visible = { this.props._visible }>
42
-                <View style = { styles.headerContainer } >
65
+                <View
66
+                    style = { [
67
+                        styles.headerContainer,
68
+                        this._getSafetyPadding()
69
+                    ] } >
70
+                    <BackButton
71
+                        onPress = { this._onRequestClose }
72
+                        style = { styles.settingsBackButton } />
43
                     <Text style = { [ styles.text, styles.headerTitle ] } >
73
                     <Text style = { [ styles.text, styles.headerTitle ] } >
44
                         { t('profileModal.header') }
74
                         { t('profileModal.header') }
45
                     </Text>
75
                     </Text>
46
                 </View>
76
                 </View>
47
-                <View style = { styles.settingsContainer } >
48
-                    <FormRow
49
-                        fieldSeparator = { true }
50
-                        i18nLabel = 'profileModal.serverURL' >
51
-                        <TextInput
52
-                            autoCapitalize = 'none'
53
-                            onChangeText = { this._onChangeServerName }
54
-                            onEndEditing = { this._onSaveServerName }
55
-                            placeholder = 'https://jitsi.example.com'
56
-                            value = { this.state.serverURL } />
57
-                    </FormRow>
77
+                <ScrollView style = { styles.settingsContainer } >
78
+                    <FormSectionHeader
79
+                        i18nLabel = 'profileModal.profileSection' />
58
                     <FormRow
80
                     <FormRow
59
                         fieldSeparator = { true }
81
                         fieldSeparator = { true }
60
                         i18nLabel = 'profileModal.displayName' >
82
                         i18nLabel = 'profileModal.displayName' >
61
                         <TextInput
83
                         <TextInput
62
                             onChangeText = { this._onChangeDisplayName }
84
                             onChangeText = { this._onChangeDisplayName }
63
-                            onEndEditing = { this._onSaveDisplayName }
64
                             placeholder = 'John Doe'
85
                             placeholder = 'John Doe'
65
-                            value = { this.state.displayName } />
86
+                            value = { _profile.displayName } />
66
                     </FormRow>
87
                     </FormRow>
67
                     <FormRow
88
                     <FormRow
68
-                        fieldSeparator = { true }
69
                         i18nLabel = 'profileModal.email' >
89
                         i18nLabel = 'profileModal.email' >
70
                         <TextInput
90
                         <TextInput
71
                             keyboardType = { 'email-address' }
91
                             keyboardType = { 'email-address' }
72
                             onChangeText = { this._onChangeEmail }
92
                             onChangeText = { this._onChangeEmail }
73
-                            onEndEditing = { this._onSaveEmail }
74
                             placeholder = 'email@example.com'
93
                             placeholder = 'email@example.com'
75
-                            value = { this.state.email } />
94
+                            value = { _profile.email } />
95
+                    </FormRow>
96
+                    <FormSectionHeader
97
+                        i18nLabel = 'profileModal.conferenceSection' />
98
+                    <FormRow
99
+                        fieldSeparator = { true }
100
+                        i18nLabel = 'profileModal.serverURL' >
101
+                        <TextInput
102
+                            autoCapitalize = 'none'
103
+                            onChangeText = { this._onChangeServerURL }
104
+                            placeholder = { this.props._serverURL }
105
+                            value = { _profile.serverURL } />
76
                     </FormRow>
106
                     </FormRow>
77
                     <FormRow
107
                     <FormRow
78
                         fieldSeparator = { true }
108
                         fieldSeparator = { true }
81
                             onValueChange = {
111
                             onValueChange = {
82
                                 this._onStartAudioMutedChange
112
                                 this._onStartAudioMutedChange
83
                             }
113
                             }
84
-                            value = { this.state.startWithAudioMuted } />
114
+                            value = {
115
+                                _profile.startWithAudioMuted
116
+                            } />
85
                     </FormRow>
117
                     </FormRow>
86
                     <FormRow
118
                     <FormRow
87
                         i18nLabel = 'profileModal.startWithVideoMuted' >
119
                         i18nLabel = 'profileModal.startWithVideoMuted' >
89
                             onValueChange = {
121
                             onValueChange = {
90
                                 this._onStartVideoMutedChange
122
                                 this._onStartVideoMutedChange
91
                             }
123
                             }
92
-                            value = { this.state.startWithVideoMuted } />
124
+                            value = {
125
+                                _profile.startWithVideoMuted
126
+                            } />
93
                     </FormRow>
127
                     </FormRow>
94
-                </View>
128
+                </ScrollView>
95
             </Modal>
129
             </Modal>
96
         );
130
         );
97
     }
131
     }
132
+
133
+    /**
134
+    * Calculates header safety padding for mobile devices.
135
+    * See comment in functions.js.
136
+    *
137
+    * @private
138
+    * @returns {Object}
139
+    */
140
+    _getSafetyPadding() {
141
+        if (isIPad() || this.props._aspectRatio === ASPECT_RATIO_NARROW) {
142
+            const safeOffset = Math.max(getSafetyOffset(), HEADER_PADDING);
143
+
144
+            return {
145
+                paddingTop: safeOffset
146
+            };
147
+        }
148
+
149
+        return undefined;
150
+    }
98
 }
151
 }
99
 
152
 
100
 export default translate(connect(_mapStateToProps)(AppSettings));
153
 export default translate(connect(_mapStateToProps)(AppSettings));

+ 56
- 0
react/features/app-settings/components/BackButton.native.js 查看文件

1
+// @flow
2
+
3
+import React, { Component } from 'react';
4
+import { TouchableOpacity } from 'react-native';
5
+
6
+import styles from './styles';
7
+
8
+import { Icon } from '../../base/font-icons';
9
+import { Platform } from '../../base/react';
10
+
11
+/**
12
+* The icon glyph to be used on a specific platform.
13
+*/
14
+const BACK_ICON = Platform.OS === 'android' ? 'arrow_back' : 'navigate_before';
15
+
16
+/**
17
+* The type of the React {@code Component} props of {@link BackButton}
18
+*/
19
+type Props = {
20
+
21
+    /**
22
+    * The action to be performed when the button is pressed.
23
+    */
24
+    onPress: Function,
25
+
26
+    /**
27
+    * An external style object passed to the component.
28
+    */
29
+    style: Object
30
+};
31
+
32
+/**
33
+ * A component rendering a back button that looks native on both platforms.
34
+ */
35
+export default class BackButton extends Component<Props> {
36
+    /**
37
+     * Implements React's {@link Component#render()}, renders the button.
38
+     *
39
+     * @inheritdoc
40
+     * @returns {ReactElement}
41
+     */
42
+    render() {
43
+        return (
44
+            <TouchableOpacity
45
+                accessibilityLabel = { 'Back' }
46
+                onPress = { this.props.onPress }>
47
+                <Icon
48
+                    name = { BACK_ICON }
49
+                    style = { [
50
+                        styles.backIcon,
51
+                        this.props.style
52
+                    ] } />
53
+            </TouchableOpacity>
54
+        );
55
+    }
56
+}

+ 36
- 3
react/features/app-settings/components/FormRow.native.js 查看文件

6
     View } from 'react-native';
6
     View } from 'react-native';
7
 import { connect } from 'react-redux';
7
 import { connect } from 'react-redux';
8
 
8
 
9
-import styles, { ANDROID_UNDERLINE_COLOR } from './styles';
9
+import styles, { ANDROID_UNDERLINE_COLOR, CONTAINER_PADDING } from './styles';
10
 
10
 
11
+import { getSafetyOffset } from '../functions';
12
+
13
+import { ASPECT_RATIO_WIDE } from '../../base/aspect-ratio';
11
 import { translate } from '../../base/i18n';
14
 import { translate } from '../../base/i18n';
12
 
15
 
13
 /**
16
 /**
15
 */
18
 */
16
 type Props = {
19
 type Props = {
17
 
20
 
21
+    /**
22
+    * The current aspect ratio of the screen.
23
+    */
24
+    _aspectRatio: Symbol,
25
+
18
     /**
26
     /**
19
     */
27
     */
20
     children: Object,
28
     children: Object,
40
  * on a form. The component should have exactly one child component.
48
  * on a form. The component should have exactly one child component.
41
  */
49
  */
42
 class FormRow extends Component<Props> {
50
 class FormRow extends Component<Props> {
43
-
44
     /**
51
     /**
45
      * Initializes a new {@code FormRow} instance.
52
      * Initializes a new {@code FormRow} instance.
46
      *
53
      *
118
 
125
 
119
     /**
126
     /**
120
     * Assembles the row style array based on the row's props.
127
     * Assembles the row style array based on the row's props.
128
+    * For padding, see comment in functions.js.
121
     *
129
     *
122
     * @private
130
     * @private
123
     * @returns {Array<Object>}
131
     * @returns {Array<Object>}
131
             rowStyle.push(styles.fieldSeparator);
139
             rowStyle.push(styles.fieldSeparator);
132
         }
140
         }
133
 
141
 
142
+        if (this.props._aspectRatio === ASPECT_RATIO_WIDE) {
143
+            const safeOffset = Math.max(
144
+                getSafetyOffset() - CONTAINER_PADDING, 0
145
+            );
146
+
147
+            rowStyle.push({
148
+                marginLeft: safeOffset,
149
+                marginRight: safeOffset
150
+            });
151
+        }
152
+
134
         return rowStyle;
153
         return rowStyle;
135
     }
154
     }
136
 }
155
 }
137
 
156
 
138
-export default translate(connect()(FormRow));
157
+/**
158
+ * Maps (parts of) the redux state to the React {@code Component} props of
159
+ * {@code FormRow}.
160
+ *
161
+ * @param {Object} state - The redux state.
162
+ * @protected
163
+ * @returns {Object}
164
+ */
165
+export function _mapStateToProps(state: Object) {
166
+    return {
167
+        _aspectRatio: state['features/base/aspect-ratio'].aspectRatio
168
+    };
169
+}
170
+
171
+export default translate(connect(_mapStateToProps)(FormRow));

+ 119
- 0
react/features/app-settings/components/FormSectionHeader.native.js 查看文件

1
+/* @flow */
2
+
3
+import React, { Component } from 'react';
4
+import { Text, View } from 'react-native';
5
+import { connect } from 'react-redux';
6
+
7
+import styles, { CONTAINER_PADDING } from './styles';
8
+
9
+import { getSafetyOffset } from '../functions';
10
+
11
+import { ASPECT_RATIO_WIDE } from '../../base/aspect-ratio';
12
+import { translate } from '../../base/i18n';
13
+
14
+/**
15
+* The type of the React {@code Component} props of {@link FormSectionHeader}
16
+*/
17
+type Props = {
18
+
19
+    /**
20
+    * The current aspect ratio of the screen.
21
+    */
22
+    _aspectRatio: Symbol,
23
+
24
+    /**
25
+    * The i18n key of the text label of the section.
26
+    */
27
+    i18nLabel: string,
28
+
29
+    /**
30
+    * An external style object passed to the component.
31
+    */
32
+    style: Object,
33
+
34
+    /**
35
+     * Invoked to obtain translated strings.
36
+     */
37
+    t: Function
38
+}
39
+
40
+/**
41
+ * Implements a React {@code Component} which renders
42
+ * a section header on a form. This calculates the available safe view as well.
43
+ */
44
+class FormSectionHeader extends Component<Props> {
45
+    /**
46
+     * Initializes a new {@code FormSectionHeader} instance.
47
+     *
48
+     * @param {Object} props - Component properties.
49
+     */
50
+    constructor(props) {
51
+        super(props);
52
+
53
+        this._getSafetyMargin = this._getSafetyMargin.bind(this);
54
+    }
55
+
56
+    /**
57
+     * Implements React's {@link Component#render()}.
58
+     *
59
+     * @inheritdoc
60
+     * @override
61
+     * @returns {ReactElement}
62
+     */
63
+    render() {
64
+        const { t } = this.props;
65
+
66
+        return (
67
+            <View
68
+                style = { [
69
+                    styles.formSectionTitle,
70
+                    this.props.style,
71
+                    this._getSafetyMargin()
72
+                ] } >
73
+                <Text>
74
+                    { t(this.props.i18nLabel) }
75
+                </Text>
76
+            </View>
77
+        );
78
+    }
79
+
80
+    _getSafetyMargin: () => Object;
81
+
82
+    /**
83
+    * Calculates the safety margin for this header.
84
+    * See comment in functions.js.
85
+    *
86
+    * @private
87
+    * @returns {Object}
88
+    */
89
+    _getSafetyMargin() {
90
+        if (this.props._aspectRatio === ASPECT_RATIO_WIDE) {
91
+            const safeOffset = Math.max(
92
+                getSafetyOffset() - CONTAINER_PADDING, 0
93
+            );
94
+
95
+            return {
96
+                marginLeft: safeOffset,
97
+                marginRight: safeOffset
98
+            };
99
+        }
100
+
101
+        return undefined;
102
+    }
103
+}
104
+
105
+/**
106
+ * Maps (parts of) the redux state to the React {@code Component} props of
107
+ * {@code FormSectionHeader}.
108
+ *
109
+ * @param {Object} state - The redux state.
110
+ * @protected
111
+ * @returns {Object}
112
+ */
113
+export function _mapStateToProps(state: Object) {
114
+    return {
115
+        _aspectRatio: state['features/base/aspect-ratio'].aspectRatio
116
+    };
117
+}
118
+
119
+export default translate(connect(_mapStateToProps)(FormSectionHeader));

+ 59
- 16
react/features/app-settings/components/styles.js 查看文件

1
+import { Platform } from 'react-native';
1
 import {
2
 import {
2
     BoxModel,
3
     BoxModel,
3
     ColorPalette,
4
     ColorPalette,
4
     createStyleSheet
5
     createStyleSheet
5
 } from '../../base/styles';
6
 } from '../../base/styles';
6
 
7
 
7
-const LABEL_TAB = 300;
8
-
9
 export const ANDROID_UNDERLINE_COLOR = 'transparent';
8
 export const ANDROID_UNDERLINE_COLOR = 'transparent';
9
+export const CONTAINER_PADDING = 2 * BoxModel.padding;
10
+export const HEADER_COLOR = ColorPalette.blue;
11
+export const HEADER_PADDING = BoxModel.padding;
12
+const TEXT_SIZE = 17;
10
 
13
 
11
 /**
14
 /**
12
- * The styles of the React {@code Components} of the feature welcome including
13
- * {@code WelcomePage} and {@code BlankPage}.
15
+ * The styles of the React {@code Components} of the feature
16
+ * {@code AppSettings}.
14
  */
17
  */
15
 export default createStyleSheet({
18
 export default createStyleSheet({
16
 
19
 
20
+    /**
21
+    *The platform specific back button style.
22
+    */
23
+    backIcon: {
24
+        alignSelf: 'center',
25
+        ...Platform.select({
26
+            ios: {
27
+                alignSelf: 'center',
28
+                fontSize: 30
29
+            },
30
+            android: {
31
+                fontSize: 24,
32
+                padding: 8
33
+            }
34
+        })
35
+    },
36
+
17
     /**
37
     /**
18
     * Standardized style for a field container {@code View}.
38
     * Standardized style for a field container {@code View}.
19
     */
39
     */
20
     fieldContainer: {
40
     fieldContainer: {
21
-        flexDirection: 'row',
22
         alignItems: 'center',
41
         alignItems: 'center',
42
+        flexDirection: 'row',
23
         minHeight: 65
43
         minHeight: 65
24
     },
44
     },
25
 
45
 
27
     * Standard container for a {@code View} containing a field label.
47
     * Standard container for a {@code View} containing a field label.
28
     */
48
     */
29
     fieldLabelContainer: {
49
     fieldLabelContainer: {
30
-        flexDirection: 'row',
31
         alignItems: 'center',
50
         alignItems: 'center',
32
-        width: LABEL_TAB
51
+        flexDirection: 'row'
33
     },
52
     },
34
 
53
 
35
     /**
54
     /**
36
     * Field container style for all but last row {@code View}.
55
     * Field container style for all but last row {@code View}.
37
     */
56
     */
38
     fieldSeparator: {
57
     fieldSeparator: {
39
-        borderBottomWidth: 1
58
+        borderBottomWidth: 1,
59
+        borderColor: 'rgba(0, 0, 0, 0.1)'
40
     },
60
     },
41
 
61
 
42
     /**
62
     /**
44
     * field values (the actual field).
64
     * field values (the actual field).
45
     */
65
     */
46
     fieldValueContainer: {
66
     fieldValueContainer: {
67
+        alignItems: 'center',
47
         flex: 1,
68
         flex: 1,
48
-        justifyContent: 'flex-end',
49
         flexDirection: 'row',
69
         flexDirection: 'row',
50
-        alignItems: 'center'
70
+        justifyContent: 'flex-end'
71
+    },
72
+
73
+    formSectionTitle: {
74
+        backgroundColor: 'rgba(0, 0, 0, 0.1)',
75
+        marginTop: 5,
76
+        padding: 5
51
     },
77
     },
52
 
78
 
53
     /**
79
     /**
54
     * Page header {@code View}.
80
     * Page header {@code View}.
55
     */
81
     */
56
     headerContainer: {
82
     headerContainer: {
57
-        backgroundColor: ColorPalette.blue,
58
-        flexDirection: 'row',
59
         alignItems: 'center',
83
         alignItems: 'center',
60
-        padding: 2 * BoxModel.margin
84
+        backgroundColor: HEADER_COLOR,
85
+        flexDirection: 'row',
86
+        justifyContent: 'flex-start',
87
+        padding: HEADER_PADDING
61
     },
88
     },
62
 
89
 
63
     /**
90
     /**
64
     * The title {@code Text} of the header.
91
     * The title {@code Text} of the header.
65
     */
92
     */
66
     headerTitle: {
93
     headerTitle: {
94
+        color: ColorPalette.white,
95
+        fontSize: 24
96
+    },
97
+
98
+    /**
99
+    * Style of the scrollview to be able to scroll the content.
100
+    */
101
+    scrollView: {
102
+        flex: 1
103
+    },
104
+
105
+    /**
106
+    * The back button style on the settings screen.
107
+    */
108
+    settingsBackButton: {
67
         color: ColorPalette.white,
109
         color: ColorPalette.white,
68
         fontSize: 25
110
         fontSize: 25
69
     },
111
     },
76
         flex: 1,
118
         flex: 1,
77
         flexDirection: 'column',
119
         flexDirection: 'column',
78
         margin: 0,
120
         margin: 0,
79
-        padding: 2 * BoxModel.padding
121
+        padding: CONTAINER_PADDING,
122
+        paddingTop: 0
80
     },
123
     },
81
 
124
 
82
     /**
125
     /**
84
     */
127
     */
85
     text: {
128
     text: {
86
         color: ColorPalette.black,
129
         color: ColorPalette.black,
87
-        fontSize: 20
130
+        fontSize: TEXT_SIZE
88
     },
131
     },
89
 
132
 
90
     /**
133
     /**
91
     * Standard text input field style.
134
     * Standard text input field style.
92
     */
135
     */
93
     textInputField: {
136
     textInputField: {
94
-        fontSize: 20,
95
         flex: 1,
137
         flex: 1,
138
+        fontSize: TEXT_SIZE,
96
         textAlign: 'right'
139
         textAlign: 'right'
97
     }
140
     }
98
 });
141
 });

+ 28
- 0
react/features/app-settings/functions.native.js 查看文件

1
+// @flow
2
+
3
+import { isIPhoneX, Platform } from '../base/react';
4
+
5
+const IPHONE_OFFSET = 20;
6
+const IPHONEX_OFFSET = 44;
7
+
8
+/**
9
+* Determines the offset to be used for the device.
10
+* This uses a custom implementation to minimize empty area around screen,
11
+* especially on iPhone X.
12
+*
13
+* @returns {number}
14
+*/
15
+export function getSafetyOffset() {
16
+    if (Platform.OS === 'android') {
17
+        /* Android doesn't need offset, except the Essential phone. Should be
18
+        * addressed later with a generic solution.
19
+        */
20
+        return 0;
21
+    }
22
+
23
+    if (isIPhoneX()) {
24
+        return IPHONEX_OFFSET;
25
+    }
26
+
27
+    return IPHONE_OFFSET;
28
+}

react/features/app-settings/functions.js → react/features/app-settings/functions.web.js 查看文件


+ 0
- 1
react/features/app-settings/index.js 查看文件

1
 export * from './actions';
1
 export * from './actions';
2
 export * from './components';
2
 export * from './components';
3
-export * from './functions';
4
 
3
 
5
 import './reducer';
4
 import './reducer';

+ 37
- 0
react/features/app-settings/middleware.js 查看文件

1
+/* @flow */
2
+
3
+import { hideAppSettings } from './actions';
4
+
5
+import { SET_ROOM } from '../base/conference';
6
+import { MiddlewareRegistry } from '../base/redux';
7
+
8
+/**
9
+ * The Redux middleware to trigger settings screen show or hide
10
+ * when necessary.
11
+ *
12
+ * @param {Store} store - The Redux store.
13
+ * @returns {Function}
14
+ */
15
+MiddlewareRegistry.register(store => next => action => {
16
+    switch (action.type) {
17
+    case SET_ROOM:
18
+        return _closeAppSettings(store, next, action);
19
+    }
20
+
21
+    return next(action);
22
+});
23
+
24
+/**
25
+ * Hides the settings screen.
26
+ *
27
+ * @param {Store} store - The redux store.
28
+ * @param {Dispatch} next - The redux dispatch function.
29
+ * @param {Action} action - The redux action.
30
+ * @private
31
+ * @returns {Object} The new state.
32
+ */
33
+function _closeAppSettings(store, next, action) {
34
+    store.dispatch(hideAppSettings());
35
+
36
+    return next(action);
37
+}

+ 8
- 6
react/features/app/components/AbstractApp.js 查看文件

179
      * @returns {void}
179
      * @returns {void}
180
      */
180
      */
181
     componentWillReceiveProps(nextProps) {
181
     componentWillReceiveProps(nextProps) {
182
+        const currentProps = this.props;
183
+
182
         this.init.then(() => {
184
         this.init.then(() => {
183
             // The consumer of this AbstractApp did not provide a redux store.
185
             // The consumer of this AbstractApp did not provide a redux store.
184
             if (typeof nextProps.store === 'undefined'
186
             if (typeof nextProps.store === 'undefined'
189
                     // its own internal redux store. If the consumer did not
191
                     // its own internal redux store. If the consumer did not
190
                     // provide a redux store before, then this instance is
192
                     // provide a redux store before, then this instance is
191
                     // using its own internal redux store already.
193
                     // using its own internal redux store already.
192
-                    && typeof this.props.store !== 'undefined') {
194
+                    && typeof currentProps.store !== 'undefined') {
193
                 this.setState({
195
                 this.setState({
194
                     store: this._maybeCreateStore(nextProps)
196
                     store: this._maybeCreateStore(nextProps)
195
                 });
197
                 });
199
             let { url } = nextProps;
201
             let { url } = nextProps;
200
 
202
 
201
             url = toURLString(url);
203
             url = toURLString(url);
202
-            if (toURLString(this.props.url) !== url
204
+            if (toURLString(currentProps.url) !== url
203
 
205
 
204
                     // XXX Refer to the implementation of loadURLObject: in
206
                     // XXX Refer to the implementation of loadURLObject: in
205
                     // ios/sdk/src/JitsiMeetView.m for further information.
207
                     // ios/sdk/src/JitsiMeetView.m for further information.
206
-                    || this.props.timestamp !== nextProps.timestamp) {
208
+                    || currentProps.timestamp !== nextProps.timestamp) {
207
                 this._openURL(url || this._getDefaultURL());
209
                 this._openURL(url || this._getDefaultURL());
208
             }
210
             }
209
         });
211
         });
373
             }
375
             }
374
         }
376
         }
375
 
377
 
376
-        const profileDefaultURL = getProfile(
378
+        const profileServerURL = getProfile(
377
             this._getStore().getState()
379
             this._getStore().getState()
378
-        ).defaultURL;
380
+        ).serverURL;
379
 
381
 
380
-        return this.props.defaultURL || profileDefaultURL || DEFAULT_URL;
382
+        return this.props.defaultURL || profileServerURL || DEFAULT_URL;
381
     }
383
     }
382
 
384
 
383
     /**
385
     /**

+ 107
- 53
react/features/base/font-icons/jitsi.json 查看文件

1
 {
1
 {
2
   "IcoMoonType": "selection",
2
   "IcoMoonType": "selection",
3
   "icons": [
3
   "icons": [
4
+    {
5
+      "icon": {
6
+        "paths": [
7
+          "M854 470v84h-520l238 240-60 60-342-342 342-342 60 60-238 240h520z"
8
+        ],
9
+        "attrs": [],
10
+        "isMulticolor": false,
11
+        "isMulticolor2": false,
12
+        "tags": [
13
+          "arrow_back"
14
+        ],
15
+        "defaultCode": 58820,
16
+        "grid": 24
17
+      },
18
+      "attrs": [],
19
+      "properties": {
20
+        "ligatures": "arrow_back",
21
+        "id": 45,
22
+        "order": 924,
23
+        "prevSize": 24,
24
+        "code": 58820,
25
+        "name": "arrow_back"
26
+      },
27
+      "setIdx": 0,
28
+      "setId": 2,
29
+      "iconIdx": 45
30
+    },
31
+    {
32
+      "icon": {
33
+        "paths": [
34
+          "M658 316l-196 196 196 196-60 60-256-256 256-256z"
35
+        ],
36
+        "attrs": [],
37
+        "isMulticolor": false,
38
+        "isMulticolor2": false,
39
+        "tags": [
40
+          "navigate_before"
41
+        ],
42
+        "defaultCode": 58376,
43
+        "grid": 24
44
+      },
45
+      "attrs": [],
46
+      "properties": {
47
+        "ligatures": "chevron_left, navigate_before",
48
+        "id": 152,
49
+        "order": 923,
50
+        "prevSize": 24,
51
+        "code": 58376,
52
+        "name": "navigate_before"
53
+      },
54
+      "setIdx": 0,
55
+      "setId": 2,
56
+      "iconIdx": 152
57
+    },
4
     {
58
     {
5
       "icon": {
59
       "icon": {
6
         "paths": [
60
         "paths": [
24
         "code": 59403,
78
         "code": 59403,
25
         "name": "public"
79
         "name": "public"
26
       },
80
       },
27
-      "setIdx": 0,
28
-      "setId": 2,
29
-      "iconIdx": 605
81
+      "setIdx": 1,
82
+      "setId": 1,
83
+      "iconIdx": 0
30
     },
84
     },
31
     {
85
     {
32
       "icon": {
86
       "icon": {
53
       },
107
       },
54
       "setIdx": 1,
108
       "setIdx": 1,
55
       "setId": 1,
109
       "setId": 1,
56
-      "iconIdx": 0
110
+      "iconIdx": 1
57
     },
111
     },
58
     {
112
     {
59
       "icon": {
113
       "icon": {
80
       },
134
       },
81
       "setIdx": 1,
135
       "setIdx": 1,
82
       "setId": 1,
136
       "setId": 1,
83
-      "iconIdx": 1
137
+      "iconIdx": 2
84
     },
138
     },
85
     {
139
     {
86
       "icon": {
140
       "icon": {
107
       },
161
       },
108
       "setIdx": 1,
162
       "setIdx": 1,
109
       "setId": 1,
163
       "setId": 1,
110
-      "iconIdx": 2
164
+      "iconIdx": 3
111
     },
165
     },
112
     {
166
     {
113
       "icon": {
167
       "icon": {
134
       },
188
       },
135
       "setIdx": 1,
189
       "setIdx": 1,
136
       "setId": 1,
190
       "setId": 1,
137
-      "iconIdx": 3
191
+      "iconIdx": 4
138
     },
192
     },
139
     {
193
     {
140
       "icon": {
194
       "icon": {
161
       },
215
       },
162
       "setIdx": 1,
216
       "setIdx": 1,
163
       "setId": 1,
217
       "setId": 1,
164
-      "iconIdx": 4
218
+      "iconIdx": 5
165
     },
219
     },
166
     {
220
     {
167
       "icon": {
221
       "icon": {
188
       },
242
       },
189
       "setIdx": 1,
243
       "setIdx": 1,
190
       "setId": 1,
244
       "setId": 1,
191
-      "iconIdx": 5
245
+      "iconIdx": 6
192
     },
246
     },
193
     {
247
     {
194
       "icon": {
248
       "icon": {
217
       },
271
       },
218
       "setIdx": 1,
272
       "setIdx": 1,
219
       "setId": 1,
273
       "setId": 1,
220
-      "iconIdx": 6
274
+      "iconIdx": 7
221
     },
275
     },
222
     {
276
     {
223
       "icon": {
277
       "icon": {
244
       },
298
       },
245
       "setIdx": 1,
299
       "setIdx": 1,
246
       "setId": 1,
300
       "setId": 1,
247
-      "iconIdx": 7
301
+      "iconIdx": 8
248
     },
302
     },
249
     {
303
     {
250
       "icon": {
304
       "icon": {
271
       },
325
       },
272
       "setIdx": 1,
326
       "setIdx": 1,
273
       "setId": 1,
327
       "setId": 1,
274
-      "iconIdx": 8
328
+      "iconIdx": 9
275
     },
329
     },
276
     {
330
     {
277
       "icon": {
331
       "icon": {
300
       },
354
       },
301
       "setIdx": 1,
355
       "setIdx": 1,
302
       "setId": 1,
356
       "setId": 1,
303
-      "iconIdx": 9
357
+      "iconIdx": 10
304
     },
358
     },
305
     {
359
     {
306
       "icon": {
360
       "icon": {
329
       },
383
       },
330
       "setIdx": 1,
384
       "setIdx": 1,
331
       "setId": 1,
385
       "setId": 1,
332
-      "iconIdx": 10
386
+      "iconIdx": 11
333
     },
387
     },
334
     {
388
     {
335
       "icon": {
389
       "icon": {
358
       },
412
       },
359
       "setIdx": 1,
413
       "setIdx": 1,
360
       "setId": 1,
414
       "setId": 1,
361
-      "iconIdx": 11
415
+      "iconIdx": 12
362
     },
416
     },
363
     {
417
     {
364
       "icon": {
418
       "icon": {
387
       },
441
       },
388
       "setIdx": 1,
442
       "setIdx": 1,
389
       "setId": 1,
443
       "setId": 1,
390
-      "iconIdx": 12
444
+      "iconIdx": 13
391
     },
445
     },
392
     {
446
     {
393
       "icon": {
447
       "icon": {
416
       },
470
       },
417
       "setIdx": 1,
471
       "setIdx": 1,
418
       "setId": 1,
472
       "setId": 1,
419
-      "iconIdx": 13
473
+      "iconIdx": 14
420
     },
474
     },
421
     {
475
     {
422
       "icon": {
476
       "icon": {
442
       },
496
       },
443
       "setIdx": 1,
497
       "setIdx": 1,
444
       "setId": 1,
498
       "setId": 1,
445
-      "iconIdx": 14
499
+      "iconIdx": 15
446
     },
500
     },
447
     {
501
     {
448
       "icon": {
502
       "icon": {
468
       },
522
       },
469
       "setIdx": 1,
523
       "setIdx": 1,
470
       "setId": 1,
524
       "setId": 1,
471
-      "iconIdx": 15
525
+      "iconIdx": 16
472
     },
526
     },
473
     {
527
     {
474
       "icon": {
528
       "icon": {
494
       },
548
       },
495
       "setIdx": 1,
549
       "setIdx": 1,
496
       "setId": 1,
550
       "setId": 1,
497
-      "iconIdx": 16
551
+      "iconIdx": 17
498
     },
552
     },
499
     {
553
     {
500
       "icon": {
554
       "icon": {
520
       },
574
       },
521
       "setIdx": 1,
575
       "setIdx": 1,
522
       "setId": 1,
576
       "setId": 1,
523
-      "iconIdx": 17
577
+      "iconIdx": 18
524
     },
578
     },
525
     {
579
     {
526
       "icon": {
580
       "icon": {
546
       },
600
       },
547
       "setIdx": 1,
601
       "setIdx": 1,
548
       "setId": 1,
602
       "setId": 1,
549
-      "iconIdx": 18
603
+      "iconIdx": 19
550
     },
604
     },
551
     {
605
     {
552
       "icon": {
606
       "icon": {
572
       },
626
       },
573
       "setIdx": 1,
627
       "setIdx": 1,
574
       "setId": 1,
628
       "setId": 1,
575
-      "iconIdx": 19
629
+      "iconIdx": 20
576
     },
630
     },
577
     {
631
     {
578
       "icon": {
632
       "icon": {
598
       },
652
       },
599
       "setIdx": 1,
653
       "setIdx": 1,
600
       "setId": 1,
654
       "setId": 1,
601
-      "iconIdx": 20
655
+      "iconIdx": 21
602
     },
656
     },
603
     {
657
     {
604
       "icon": {
658
       "icon": {
616
       "attrs": [],
670
       "attrs": [],
617
       "properties": {
671
       "properties": {
618
         "id": 10,
672
         "id": 10,
619
-        "order": 900,
673
+        "order": 922,
620
         "ligatures": "expand_less",
674
         "ligatures": "expand_less",
621
         "prevSize": 32,
675
         "prevSize": 32,
622
         "code": 59679,
676
         "code": 59679,
624
       },
678
       },
625
       "setIdx": 1,
679
       "setIdx": 1,
626
       "setId": 1,
680
       "setId": 1,
627
-      "iconIdx": 21
681
+      "iconIdx": 22
628
     },
682
     },
629
     {
683
     {
630
       "icon": {
684
       "icon": {
650
       },
704
       },
651
       "setIdx": 1,
705
       "setIdx": 1,
652
       "setId": 1,
706
       "setId": 1,
653
-      "iconIdx": 22
707
+      "iconIdx": 23
654
     },
708
     },
655
     {
709
     {
656
       "icon": {
710
       "icon": {
676
       },
730
       },
677
       "setIdx": 1,
731
       "setIdx": 1,
678
       "setId": 1,
732
       "setId": 1,
679
-      "iconIdx": 23
733
+      "iconIdx": 24
680
     },
734
     },
681
     {
735
     {
682
       "icon": {
736
       "icon": {
702
       },
756
       },
703
       "setIdx": 1,
757
       "setIdx": 1,
704
       "setId": 1,
758
       "setId": 1,
705
-      "iconIdx": 24
759
+      "iconIdx": 25
706
     },
760
     },
707
     {
761
     {
708
       "icon": {
762
       "icon": {
728
       },
782
       },
729
       "setIdx": 1,
783
       "setIdx": 1,
730
       "setId": 1,
784
       "setId": 1,
731
-      "iconIdx": 25
785
+      "iconIdx": 26
732
     },
786
     },
733
     {
787
     {
734
       "icon": {
788
       "icon": {
754
       },
808
       },
755
       "setIdx": 1,
809
       "setIdx": 1,
756
       "setId": 1,
810
       "setId": 1,
757
-      "iconIdx": 26
811
+      "iconIdx": 27
758
     },
812
     },
759
     {
813
     {
760
       "icon": {
814
       "icon": {
780
       },
834
       },
781
       "setIdx": 1,
835
       "setIdx": 1,
782
       "setId": 1,
836
       "setId": 1,
783
-      "iconIdx": 27
837
+      "iconIdx": 28
784
     },
838
     },
785
     {
839
     {
786
       "icon": {
840
       "icon": {
806
       },
860
       },
807
       "setIdx": 1,
861
       "setIdx": 1,
808
       "setId": 1,
862
       "setId": 1,
809
-      "iconIdx": 28
863
+      "iconIdx": 29
810
     },
864
     },
811
     {
865
     {
812
       "icon": {
866
       "icon": {
832
       },
886
       },
833
       "setIdx": 1,
887
       "setIdx": 1,
834
       "setId": 1,
888
       "setId": 1,
835
-      "iconIdx": 29
889
+      "iconIdx": 30
836
     },
890
     },
837
     {
891
     {
838
       "icon": {
892
       "icon": {
858
       },
912
       },
859
       "setIdx": 1,
913
       "setIdx": 1,
860
       "setId": 1,
914
       "setId": 1,
861
-      "iconIdx": 30
915
+      "iconIdx": 31
862
     },
916
     },
863
     {
917
     {
864
       "icon": {
918
       "icon": {
884
       },
938
       },
885
       "setIdx": 1,
939
       "setIdx": 1,
886
       "setId": 1,
940
       "setId": 1,
887
-      "iconIdx": 31
941
+      "iconIdx": 32
888
     },
942
     },
889
     {
943
     {
890
       "icon": {
944
       "icon": {
910
       },
964
       },
911
       "setIdx": 1,
965
       "setIdx": 1,
912
       "setId": 1,
966
       "setId": 1,
913
-      "iconIdx": 32
967
+      "iconIdx": 33
914
     },
968
     },
915
     {
969
     {
916
       "icon": {
970
       "icon": {
936
       },
990
       },
937
       "setIdx": 1,
991
       "setIdx": 1,
938
       "setId": 1,
992
       "setId": 1,
939
-      "iconIdx": 33
993
+      "iconIdx": 34
940
     },
994
     },
941
     {
995
     {
942
       "icon": {
996
       "icon": {
962
       },
1016
       },
963
       "setIdx": 1,
1017
       "setIdx": 1,
964
       "setId": 1,
1018
       "setId": 1,
965
-      "iconIdx": 34
1019
+      "iconIdx": 35
966
     },
1020
     },
967
     {
1021
     {
968
       "icon": {
1022
       "icon": {
988
       },
1042
       },
989
       "setIdx": 1,
1043
       "setIdx": 1,
990
       "setId": 1,
1044
       "setId": 1,
991
-      "iconIdx": 35
1045
+      "iconIdx": 36
992
     },
1046
     },
993
     {
1047
     {
994
       "icon": {
1048
       "icon": {
1014
       },
1068
       },
1015
       "setIdx": 1,
1069
       "setIdx": 1,
1016
       "setId": 1,
1070
       "setId": 1,
1017
-      "iconIdx": 36
1071
+      "iconIdx": 37
1018
     },
1072
     },
1019
     {
1073
     {
1020
       "icon": {
1074
       "icon": {
1040
       },
1094
       },
1041
       "setIdx": 1,
1095
       "setIdx": 1,
1042
       "setId": 1,
1096
       "setId": 1,
1043
-      "iconIdx": 37
1097
+      "iconIdx": 38
1044
     },
1098
     },
1045
     {
1099
     {
1046
       "icon": {
1100
       "icon": {
1066
       },
1120
       },
1067
       "setIdx": 1,
1121
       "setIdx": 1,
1068
       "setId": 1,
1122
       "setId": 1,
1069
-      "iconIdx": 38
1123
+      "iconIdx": 39
1070
     },
1124
     },
1071
     {
1125
     {
1072
       "icon": {
1126
       "icon": {
1092
       },
1146
       },
1093
       "setIdx": 1,
1147
       "setIdx": 1,
1094
       "setId": 1,
1148
       "setId": 1,
1095
-      "iconIdx": 39
1149
+      "iconIdx": 40
1096
     },
1150
     },
1097
     {
1151
     {
1098
       "icon": {
1152
       "icon": {
1118
       },
1172
       },
1119
       "setIdx": 1,
1173
       "setIdx": 1,
1120
       "setId": 1,
1174
       "setId": 1,
1121
-      "iconIdx": 40
1175
+      "iconIdx": 41
1122
     },
1176
     },
1123
     {
1177
     {
1124
       "icon": {
1178
       "icon": {
1144
       },
1198
       },
1145
       "setIdx": 1,
1199
       "setIdx": 1,
1146
       "setId": 1,
1200
       "setId": 1,
1147
-      "iconIdx": 41
1201
+      "iconIdx": 42
1148
     },
1202
     },
1149
     {
1203
     {
1150
       "icon": {
1204
       "icon": {
1170
       },
1224
       },
1171
       "setIdx": 1,
1225
       "setIdx": 1,
1172
       "setId": 1,
1226
       "setId": 1,
1173
-      "iconIdx": 42
1227
+      "iconIdx": 43
1174
     },
1228
     },
1175
     {
1229
     {
1176
       "icon": {
1230
       "icon": {
1199
       },
1253
       },
1200
       "setIdx": 1,
1254
       "setIdx": 1,
1201
       "setId": 1,
1255
       "setId": 1,
1202
-      "iconIdx": 43
1256
+      "iconIdx": 44
1203
     },
1257
     },
1204
     {
1258
     {
1205
       "icon": {
1259
       "icon": {
1229
       },
1283
       },
1230
       "setIdx": 1,
1284
       "setIdx": 1,
1231
       "setId": 1,
1285
       "setId": 1,
1232
-      "iconIdx": 44
1286
+      "iconIdx": 45
1233
     },
1287
     },
1234
     {
1288
     {
1235
       "icon": {
1289
       "icon": {
1259
       },
1313
       },
1260
       "setIdx": 1,
1314
       "setIdx": 1,
1261
       "setId": 1,
1315
       "setId": 1,
1262
-      "iconIdx": 45
1316
+      "iconIdx": 46
1263
     },
1317
     },
1264
     {
1318
     {
1265
       "icon": {
1319
       "icon": {
1285
       },
1339
       },
1286
       "setIdx": 1,
1340
       "setIdx": 1,
1287
       "setId": 1,
1341
       "setId": 1,
1288
-      "iconIdx": 46
1342
+      "iconIdx": 47
1289
     },
1343
     },
1290
     {
1344
     {
1291
       "icon": {
1345
       "icon": {
1311
       },
1365
       },
1312
       "setIdx": 1,
1366
       "setIdx": 1,
1313
       "setId": 1,
1367
       "setId": 1,
1314
-      "iconIdx": 47
1368
+      "iconIdx": 48
1315
     },
1369
     },
1316
     {
1370
     {
1317
       "icon": {
1371
       "icon": {
1337
       },
1391
       },
1338
       "setIdx": 1,
1392
       "setIdx": 1,
1339
       "setId": 1,
1393
       "setId": 1,
1340
-      "iconIdx": 48
1394
+      "iconIdx": 49
1341
     }
1395
     }
1342
   ],
1396
   ],
1343
   "height": 1024,
1397
   "height": 1024,

+ 8
- 7
react/features/base/profile/middleware.js 查看文件

2
 import { PROFILE_UPDATED } from './actionTypes';
2
 import { PROFILE_UPDATED } from './actionTypes';
3
 import MiddlewareRegistry from '../redux/MiddlewareRegistry';
3
 import MiddlewareRegistry from '../redux/MiddlewareRegistry';
4
 
4
 
5
-import { participantUpdated } from '../participants';
5
+import {
6
+    getLocalParticipant,
7
+    participantUpdated
8
+} from '../participants';
6
 import { getProfile } from '../profile';
9
 import { getProfile } from '../profile';
7
 import { toState } from '../redux';
10
 import { toState } from '../redux';
8
 
11
 
31
  * @returns {void}
34
  * @returns {void}
32
  */
35
  */
33
 function _updateLocalParticipant(store) {
36
 function _updateLocalParticipant(store) {
37
+    const localParticipant = getLocalParticipant(toState(store));
34
     const profile = getProfile(toState(store));
38
     const profile = getProfile(toState(store));
35
 
39
 
36
-    const newLocalParticipant = {
37
-        email: profile.email,
38
-        local: true,
39
-        name: profile.displayName
40
-    };
40
+    localParticipant.email = profile.email;
41
+    localParticipant.name = profile.displayName;
41
 
42
 
42
-    store.dispatch(participantUpdated(newLocalParticipant));
43
+    store.dispatch(participantUpdated(localParticipant));
43
 }
44
 }

+ 37
- 0
react/features/base/react/functions.native.js 查看文件

1
+// @flow
2
+
3
+import { Dimensions } from 'react-native';
4
+import Platform from './Platform';
5
+
6
+const IPHONEX_HEIGHT = 812;
7
+const IPHONEX_WIDTH = 375;
8
+
9
+/**
10
+* Determines if the device is an iPad or not.
11
+*
12
+* @returns {boolean}
13
+*/
14
+export function isIPad() {
15
+    const { height, width } = Dimensions.get('window');
16
+
17
+    return Platform.OS === 'ios' && (
18
+        Math.max(height, width)
19
+            / Math.min(height, width)) < 1.6;
20
+}
21
+
22
+/**
23
+* Determines if it's an iPhone X or not.
24
+*
25
+* @returns {boolean}
26
+*/
27
+export function isIPhoneX() {
28
+    const { height, width } = Dimensions.get('window');
29
+
30
+    return (
31
+        Platform.OS === 'ios'
32
+            && ((height === IPHONEX_HEIGHT
33
+                && width === IPHONEX_WIDTH)
34
+            || (height === IPHONEX_WIDTH
35
+                && width === IPHONEX_HEIGHT))
36
+    );
37
+}

正在加载...
取消
保存