Pārlūkot izejas kodu

Fix settings screen layout on iOS and add soft back button

j8
zbettenbuk 7 gadus atpakaļ
vecāks
revīzija
410dc132e1

+ 6
- 1
css/_font.scss Parādīt failu

@@ -24,7 +24,12 @@
24 24
     -webkit-font-smoothing: antialiased;
25 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 33
 .icon-event_note:before {
29 34
     content: "\e616";
30 35
 }

Binārs
fonts/jitsi.eot Parādīt failu


+ 2
- 0
fonts/jitsi.svg Parādīt failu

@@ -11,7 +11,9 @@
11 11
 <glyph unicode="&#xe145;" glyph-name="add" d="M810 470h-256v-256h-84v256h-256v84h256v256h84v-256h256v-84z" />
12 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 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 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 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 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 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" />

Binārs
fonts/jitsi.ttf Parādīt failu


Binārs
fonts/jitsi.woff Parādīt failu


+ 107
- 53
fonts/selection.json Parādīt failu

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

+ 2
- 0
lang/main.json Parādīt failu

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

+ 1
- 4
react/features/app-settings/actions.js Parādīt failu

@@ -1,9 +1,6 @@
1 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 6
 * Redux-signals the request to open the app settings modal.

+ 24
- 147
react/features/app-settings/components/AbstractAppSettings.js Parādīt failu

@@ -10,6 +10,16 @@ import { getProfile, updateProfile } from '../../base/profile';
10 10
 */
11 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 24
     * The current profile object.
15 25
     */
@@ -26,45 +36,13 @@ type Props = {
26 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 40
  * Base (abstract) class for container component rendering
62 41
  * the app settings page.
63 42
  *
64 43
  * @abstract
65 44
  */
66
-export class AbstractAppSettings extends Component<Props, State> {
67
-
45
+export class AbstractAppSettings extends Component<Props> {
68 46
     /**
69 47
      * Initializes a new {@code AbstractAppSettings} instance.
70 48
      *
@@ -76,38 +54,14 @@ export class AbstractAppSettings extends Component<Props, State> {
76 54
 
77 55
         this._onChangeDisplayName = this._onChangeDisplayName.bind(this);
78 56
         this._onChangeEmail = this._onChangeEmail.bind(this);
79
-        this._onChangeServerName = this._onChangeServerName.bind(this);
57
+        this._onChangeServerURL = this._onChangeServerURL.bind(this);
80 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 59
         this._onStartAudioMutedChange
85 60
             = this._onStartAudioMutedChange.bind(this);
86 61
         this._onStartVideoMutedChange
87 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 65
     _onChangeDisplayName: (string) => void;
112 66
 
113 67
     /**
@@ -118,7 +72,7 @@ export class AbstractAppSettings extends Component<Props, State> {
118 72
     * @returns {void}
119 73
     */
120 74
     _onChangeDisplayName(text) {
121
-        this.setState({
75
+        this._updateProfile({
122 76
             displayName: text
123 77
         });
124 78
     }
@@ -133,12 +87,12 @@ export class AbstractAppSettings extends Component<Props, State> {
133 87
     * @returns {void}
134 88
     */
135 89
     _onChangeEmail(text) {
136
-        this.setState({
90
+        this._updateProfile({
137 91
             email: text
138 92
         });
139 93
     }
140 94
 
141
-    _onChangeServerName: (string) => void;
95
+    _onChangeServerURL: (string) => void;
142 96
 
143 97
     /**
144 98
     * Handles the server name field value change.
@@ -147,8 +101,8 @@ export class AbstractAppSettings extends Component<Props, State> {
147 101
     * @param {string} text - The server URL typed in the server field.
148 102
     * @returns {void}
149 103
     */
150
-    _onChangeServerName(text) {
151
-        this.setState({
104
+    _onChangeServerURL(text) {
105
+        this._updateProfile({
152 106
             serverURL: text
153 107
         });
154 108
     }
@@ -156,7 +110,7 @@ export class AbstractAppSettings extends Component<Props, State> {
156 110
     _onRequestClose: () => void;
157 111
 
158 112
     /**
159
-    * Handles the hardware back button.
113
+    * Handles the back button.
160 114
     *
161 115
     * @returns {void}
162 116
     */
@@ -164,61 +118,6 @@ export class AbstractAppSettings extends Component<Props, State> {
164 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 121
     _onStartAudioMutedChange: (boolean) => void;
223 122
 
224 123
     /**
@@ -230,10 +129,6 @@ export class AbstractAppSettings extends Component<Props, State> {
230 129
     * @returns {void}
231 130
     */
232 131
     _onStartAudioMutedChange(newValue) {
233
-        this.setState({
234
-            startWithAudioMuted: newValue
235
-        });
236
-
237 132
         this._updateProfile({
238 133
             startWithAudioMuted: newValue
239 134
         });
@@ -250,10 +145,6 @@ export class AbstractAppSettings extends Component<Props, State> {
250 145
     * @returns {void}
251 146
     */
252 147
     _onStartVideoMutedChange(newValue) {
253
-        this.setState({
254
-            startWithVideoMuted: newValue
255
-        });
256
-
257 148
         this._updateProfile({
258 149
             startWithVideoMuted: newValue
259 150
         });
@@ -274,25 +165,6 @@ export class AbstractAppSettings extends Component<Props, State> {
274 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,8 +176,13 @@ export class AbstractAppSettings extends Component<Props, State> {
304 176
  * @returns {Object}
305 177
  */
306 178
 export function _mapStateToProps(state: Object) {
179
+    const _serverURL = state['features/app'].app._getDefaultURL();
180
+    const _profile = getProfile(state);
181
+
307 182
     return {
308
-        _profile: getProfile(state),
183
+        _aspectRatio: state['features/base/aspect-ratio'].aspectRatio,
184
+        _serverURL,
185
+        _profile,
309 186
         _visible: state['features/app-settings'].visible
310 187
     };
311 188
 }

+ 77
- 24
react/features/app-settings/components/AppSettings.native.js Parādīt failu

@@ -1,6 +1,7 @@
1 1
 import React from 'react';
2 2
 import {
3 3
     Modal,
4
+    ScrollView,
4 5
     Switch,
5 6
     Text,
6 7
     TextInput,
@@ -11,10 +12,16 @@ import {
11 12
     _mapStateToProps,
12 13
     AbstractAppSettings
13 14
 } from './AbstractAppSettings';
15
+import BackButton from './BackButton';
14 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 23
 import { translate } from '../../base/i18n';
24
+import { isIPad } from '../../base/react';
18 25
 
19 26
 /**
20 27
  * The native container rendering the app settings page.
@@ -22,6 +29,16 @@ import { translate } from '../../base/i18n';
22 29
  * @extends AbstractAppSettings
23 30
  */
24 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 44
      * Implements React's {@link Component#render()}, renders the settings page.
@@ -30,49 +47,62 @@ class AppSettings extends AbstractAppSettings {
30 47
      * @returns {ReactElement}
31 48
      */
32 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 55
         return (
36 56
             <Modal
37 57
                 animationType = 'slide'
38 58
                 onRequestClose = { this._onRequestClose }
39
-                presentationStyle = 'fullScreen'
40
-                style = { styles.modal }
59
+                presentationStyle = 'overFullScreen'
60
+                supportedOrientations = { [
61
+                    'landscape',
62
+                    'portrait'
63
+                ] }
41 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 73
                     <Text style = { [ styles.text, styles.headerTitle ] } >
44 74
                         { t('profileModal.header') }
45 75
                     </Text>
46 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 80
                     <FormRow
59 81
                         fieldSeparator = { true }
60 82
                         i18nLabel = 'profileModal.displayName' >
61 83
                         <TextInput
62 84
                             onChangeText = { this._onChangeDisplayName }
63
-                            onEndEditing = { this._onSaveDisplayName }
64 85
                             placeholder = 'John Doe'
65
-                            value = { this.state.displayName } />
86
+                            value = { _profile.displayName } />
66 87
                     </FormRow>
67 88
                     <FormRow
68
-                        fieldSeparator = { true }
69 89
                         i18nLabel = 'profileModal.email' >
70 90
                         <TextInput
71 91
                             keyboardType = { 'email-address' }
72 92
                             onChangeText = { this._onChangeEmail }
73
-                            onEndEditing = { this._onSaveEmail }
74 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 106
                     </FormRow>
77 107
                     <FormRow
78 108
                         fieldSeparator = { true }
@@ -81,7 +111,9 @@ class AppSettings extends AbstractAppSettings {
81 111
                             onValueChange = {
82 112
                                 this._onStartAudioMutedChange
83 113
                             }
84
-                            value = { this.state.startWithAudioMuted } />
114
+                            value = {
115
+                                _profile.startWithAudioMuted
116
+                            } />
85 117
                     </FormRow>
86 118
                     <FormRow
87 119
                         i18nLabel = 'profileModal.startWithVideoMuted' >
@@ -89,12 +121,33 @@ class AppSettings extends AbstractAppSettings {
89 121
                             onValueChange = {
90 122
                                 this._onStartVideoMutedChange
91 123
                             }
92
-                            value = { this.state.startWithVideoMuted } />
124
+                            value = {
125
+                                _profile.startWithVideoMuted
126
+                            } />
93 127
                     </FormRow>
94
-                </View>
128
+                </ScrollView>
95 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 153
 export default translate(connect(_mapStateToProps)(AppSettings));

+ 56
- 0
react/features/app-settings/components/BackButton.native.js Parādīt failu

@@ -0,0 +1,56 @@
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 Parādīt failu

@@ -6,8 +6,11 @@ import {
6 6
     View } from 'react-native';
7 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 14
 import { translate } from '../../base/i18n';
12 15
 
13 16
 /**
@@ -15,6 +18,11 @@ import { translate } from '../../base/i18n';
15 18
 */
16 19
 type Props = {
17 20
 
21
+    /**
22
+    * The current aspect ratio of the screen.
23
+    */
24
+    _aspectRatio: Symbol,
25
+
18 26
     /**
19 27
     */
20 28
     children: Object,
@@ -40,7 +48,6 @@ type Props = {
40 48
  * on a form. The component should have exactly one child component.
41 49
  */
42 50
 class FormRow extends Component<Props> {
43
-
44 51
     /**
45 52
      * Initializes a new {@code FormRow} instance.
46 53
      *
@@ -118,6 +125,7 @@ class FormRow extends Component<Props> {
118 125
 
119 126
     /**
120 127
     * Assembles the row style array based on the row's props.
128
+    * For padding, see comment in functions.js.
121 129
     *
122 130
     * @private
123 131
     * @returns {Array<Object>}
@@ -131,8 +139,33 @@ class FormRow extends Component<Props> {
131 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 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 Parādīt failu

@@ -0,0 +1,119 @@
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 Parādīt failu

@@ -1,25 +1,45 @@
1
+import { Platform } from 'react-native';
1 2
 import {
2 3
     BoxModel,
3 4
     ColorPalette,
4 5
     createStyleSheet
5 6
 } from '../../base/styles';
6 7
 
7
-const LABEL_TAB = 300;
8
-
9 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 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 38
     * Standardized style for a field container {@code View}.
19 39
     */
20 40
     fieldContainer: {
21
-        flexDirection: 'row',
22 41
         alignItems: 'center',
42
+        flexDirection: 'row',
23 43
         minHeight: 65
24 44
     },
25 45
 
@@ -27,16 +47,16 @@ export default createStyleSheet({
27 47
     * Standard container for a {@code View} containing a field label.
28 48
     */
29 49
     fieldLabelContainer: {
30
-        flexDirection: 'row',
31 50
         alignItems: 'center',
32
-        width: LABEL_TAB
51
+        flexDirection: 'row'
33 52
     },
34 53
 
35 54
     /**
36 55
     * Field container style for all but last row {@code View}.
37 56
     */
38 57
     fieldSeparator: {
39
-        borderBottomWidth: 1
58
+        borderBottomWidth: 1,
59
+        borderColor: 'rgba(0, 0, 0, 0.1)'
40 60
     },
41 61
 
42 62
     /**
@@ -44,26 +64,48 @@ export default createStyleSheet({
44 64
     * field values (the actual field).
45 65
     */
46 66
     fieldValueContainer: {
67
+        alignItems: 'center',
47 68
         flex: 1,
48
-        justifyContent: 'flex-end',
49 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 80
     * Page header {@code View}.
55 81
     */
56 82
     headerContainer: {
57
-        backgroundColor: ColorPalette.blue,
58
-        flexDirection: 'row',
59 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 91
     * The title {@code Text} of the header.
65 92
     */
66 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 109
         color: ColorPalette.white,
68 110
         fontSize: 25
69 111
     },
@@ -76,7 +118,8 @@ export default createStyleSheet({
76 118
         flex: 1,
77 119
         flexDirection: 'column',
78 120
         margin: 0,
79
-        padding: 2 * BoxModel.padding
121
+        padding: CONTAINER_PADDING,
122
+        paddingTop: 0
80 123
     },
81 124
 
82 125
     /**
@@ -84,15 +127,15 @@ export default createStyleSheet({
84 127
     */
85 128
     text: {
86 129
         color: ColorPalette.black,
87
-        fontSize: 20
130
+        fontSize: TEXT_SIZE
88 131
     },
89 132
 
90 133
     /**
91 134
     * Standard text input field style.
92 135
     */
93 136
     textInputField: {
94
-        fontSize: 20,
95 137
         flex: 1,
138
+        fontSize: TEXT_SIZE,
96 139
         textAlign: 'right'
97 140
     }
98 141
 });

+ 28
- 0
react/features/app-settings/functions.native.js Parādīt failu

@@ -0,0 +1,28 @@
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 Parādīt failu


+ 0
- 1
react/features/app-settings/index.js Parādīt failu

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

+ 37
- 0
react/features/app-settings/middleware.js Parādīt failu

@@ -0,0 +1,37 @@
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 Parādīt failu

@@ -179,6 +179,8 @@ export class AbstractApp extends Component {
179 179
      * @returns {void}
180 180
      */
181 181
     componentWillReceiveProps(nextProps) {
182
+        const currentProps = this.props;
183
+
182 184
         this.init.then(() => {
183 185
             // The consumer of this AbstractApp did not provide a redux store.
184 186
             if (typeof nextProps.store === 'undefined'
@@ -189,7 +191,7 @@ export class AbstractApp extends Component {
189 191
                     // its own internal redux store. If the consumer did not
190 192
                     // provide a redux store before, then this instance is
191 193
                     // using its own internal redux store already.
192
-                    && typeof this.props.store !== 'undefined') {
194
+                    && typeof currentProps.store !== 'undefined') {
193 195
                 this.setState({
194 196
                     store: this._maybeCreateStore(nextProps)
195 197
                 });
@@ -199,11 +201,11 @@ export class AbstractApp extends Component {
199 201
             let { url } = nextProps;
200 202
 
201 203
             url = toURLString(url);
202
-            if (toURLString(this.props.url) !== url
204
+            if (toURLString(currentProps.url) !== url
203 205
 
204 206
                     // XXX Refer to the implementation of loadURLObject: in
205 207
                     // ios/sdk/src/JitsiMeetView.m for further information.
206
-                    || this.props.timestamp !== nextProps.timestamp) {
208
+                    || currentProps.timestamp !== nextProps.timestamp) {
207 209
                 this._openURL(url || this._getDefaultURL());
208 210
             }
209 211
         });
@@ -373,11 +375,11 @@ export class AbstractApp extends Component {
373 375
             }
374 376
         }
375 377
 
376
-        const profileDefaultURL = getProfile(
378
+        const profileServerURL = getProfile(
377 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 Parādīt failu

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

+ 8
- 7
react/features/base/profile/middleware.js Parādīt failu

@@ -2,7 +2,10 @@
2 2
 import { PROFILE_UPDATED } from './actionTypes';
3 3
 import MiddlewareRegistry from '../redux/MiddlewareRegistry';
4 4
 
5
-import { participantUpdated } from '../participants';
5
+import {
6
+    getLocalParticipant,
7
+    participantUpdated
8
+} from '../participants';
6 9
 import { getProfile } from '../profile';
7 10
 import { toState } from '../redux';
8 11
 
@@ -31,13 +34,11 @@ MiddlewareRegistry.register(store => next => action => {
31 34
  * @returns {void}
32 35
  */
33 36
 function _updateLocalParticipant(store) {
37
+    const localParticipant = getLocalParticipant(toState(store));
34 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 Parādīt failu

@@ -0,0 +1,37 @@
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
+}

Notiek ielāde…
Atcelt
Saglabāt