mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-01-04 05:42:28 +00:00
Compare commits
651 Commits
7356
...
android-sd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9571c51506 | ||
|
|
5a38ba6257 | ||
|
|
36dfb4c956 | ||
|
|
29c33ed38b | ||
|
|
c159a54fbf | ||
|
|
107a5b845c | ||
|
|
6953255375 | ||
|
|
d358dd8ec6 | ||
|
|
3d158fb2b4 | ||
|
|
b7785a9f91 | ||
|
|
86d869a107 | ||
|
|
1c81b93c1d | ||
|
|
052070a6c1 | ||
|
|
c531c0e65c | ||
|
|
e1055ebf9b | ||
|
|
467023f77a | ||
|
|
1249aa2dcb | ||
|
|
0c45d87d1a | ||
|
|
7140a90201 | ||
|
|
0a846606fc | ||
|
|
68dc111e3c | ||
|
|
c81184df69 | ||
|
|
9b0747a0d9 | ||
|
|
c8cd80a8df | ||
|
|
f1d4332668 | ||
|
|
55b3256dc4 | ||
|
|
aa8bb55f3e | ||
|
|
58b73e21de | ||
|
|
b1c955890a | ||
|
|
6ab945c2cb | ||
|
|
7291e1ef00 | ||
|
|
43e075d48e | ||
|
|
885e1afdaa | ||
|
|
e2ec4842a1 | ||
|
|
ea075d9bae | ||
|
|
68f7448624 | ||
|
|
954ef6df4f | ||
|
|
6a3c12b316 | ||
|
|
5be616a224 | ||
|
|
58d8f3be12 | ||
|
|
8ae6ba76cc | ||
|
|
a06c2e056c | ||
|
|
fa0b06b859 | ||
|
|
4c3512b375 | ||
|
|
92e3a1ff99 | ||
|
|
701e3d2b43 | ||
|
|
2626a894e2 | ||
|
|
a6f6b3a2d2 | ||
|
|
05aa48774a | ||
|
|
e82fc480f0 | ||
|
|
9f8662c0a1 | ||
|
|
5b860c20b1 | ||
|
|
a4c52b02e7 | ||
|
|
73952ee1f7 | ||
|
|
0a9f6c2e4d | ||
|
|
94f9ccfe1c | ||
|
|
ff9f767cfd | ||
|
|
5a5ec9e4d9 | ||
|
|
aff671b44a | ||
|
|
495b925fa0 | ||
|
|
2f6b11a6ac | ||
|
|
2b7052995b | ||
|
|
5c69baefbf | ||
|
|
8b25265f9e | ||
|
|
f43020f650 | ||
|
|
ba95ea3ac8 | ||
|
|
7dcd9c21bc | ||
|
|
990d21038e | ||
|
|
a4d53f271f | ||
|
|
2a1f472873 | ||
|
|
8679119677 | ||
|
|
b02c072ba7 | ||
|
|
e8317fccfe | ||
|
|
bbc9c64978 | ||
|
|
8d2b8bc772 | ||
|
|
52c2911350 | ||
|
|
a1ebcd559b | ||
|
|
5bc47ec16a | ||
|
|
e1ac7d1609 | ||
|
|
8a596f1ba2 | ||
|
|
38e7c65836 | ||
|
|
9602a939d8 | ||
|
|
07b01b1371 | ||
|
|
a1549086aa | ||
|
|
7e0b00ba5f | ||
|
|
3016853d81 | ||
|
|
ead27ace30 | ||
|
|
067bb653e6 | ||
|
|
ba20fc71a8 | ||
|
|
a7b2726ebe | ||
|
|
a98eef7eb3 | ||
|
|
895afbab65 | ||
|
|
1d6529af65 | ||
|
|
4d5fb719d2 | ||
|
|
4061a77af8 | ||
|
|
7f889b2028 | ||
|
|
6f49041d80 | ||
|
|
e73c3b6697 | ||
|
|
5a6b1d0b47 | ||
|
|
da9cded75b | ||
|
|
9b61ad3616 | ||
|
|
583725bf31 | ||
|
|
9e2244210d | ||
|
|
361b82a1ed | ||
|
|
0ed25cda7e | ||
|
|
73ee1205eb | ||
|
|
21f2c60638 | ||
|
|
fd062c40fb | ||
|
|
b87e6abc11 | ||
|
|
9f25726706 | ||
|
|
d5ee7f3069 | ||
|
|
ba1102100a | ||
|
|
e1ce83d0c3 | ||
|
|
78cf510c0b | ||
|
|
3f657c3ded | ||
|
|
2035cd7e62 | ||
|
|
6207e95cad | ||
|
|
40b63a187a | ||
|
|
6c40250e18 | ||
|
|
0268374b88 | ||
|
|
b1b60ec143 | ||
|
|
82c58178b3 | ||
|
|
46d15a9c5c | ||
|
|
248908f476 | ||
|
|
4a5ba0f05d | ||
|
|
b23f3b9e17 | ||
|
|
b6b77f55f1 | ||
|
|
b106c20fa2 | ||
|
|
fab61d8c32 | ||
|
|
9ac614cc4b | ||
|
|
a3bb1a3459 | ||
|
|
34abd279be | ||
|
|
ad6554a789 | ||
|
|
2be8377009 | ||
|
|
0a0b0a760e | ||
|
|
fec6de4536 | ||
|
|
29b2a519b3 | ||
|
|
831d39d447 | ||
|
|
35bc430549 | ||
|
|
77927f3f2e | ||
|
|
7f6d55f5f0 | ||
|
|
32f4767edd | ||
|
|
ba88fc0279 | ||
|
|
ba7ed83d48 | ||
|
|
5a96050973 | ||
|
|
7e8c1fd99a | ||
|
|
6e6433e2d9 | ||
|
|
4ff2422e3c | ||
|
|
cfbcfdc857 | ||
|
|
3074b1741f | ||
|
|
00503d163a | ||
|
|
f847a3e2e0 | ||
|
|
93d0ee710b | ||
|
|
0102efd2d0 | ||
|
|
8afdebca08 | ||
|
|
d2bfb464ba | ||
|
|
5f3233b9a6 | ||
|
|
3c32d9c552 | ||
|
|
f51d8d54e4 | ||
|
|
ac26dce0a5 | ||
|
|
7a23625752 | ||
|
|
4cb4a4db00 | ||
|
|
05e484c4aa | ||
|
|
5871e50a20 | ||
|
|
95ad04b19c | ||
|
|
36fab239cc | ||
|
|
92492dc482 | ||
|
|
51c3658205 | ||
|
|
418d333caf | ||
|
|
7f3f2f7034 | ||
|
|
bd3012f110 | ||
|
|
f8cef330f7 | ||
|
|
e00b6be06c | ||
|
|
9b7da0be2d | ||
|
|
3effbca700 | ||
|
|
cf1f97f486 | ||
|
|
9273022e8f | ||
|
|
5d35398b6b | ||
|
|
60d4b626a5 | ||
|
|
b8da93f64f | ||
|
|
c411d3352f | ||
|
|
33e38f95b1 | ||
|
|
9ae5677c00 | ||
|
|
06f434e924 | ||
|
|
caa1ef952b | ||
|
|
4f371dfacc | ||
|
|
b6447770c7 | ||
|
|
7aad0fd853 | ||
|
|
bae2a977d1 | ||
|
|
ed3f57385a | ||
|
|
c806a432f3 | ||
|
|
5966df96e8 | ||
|
|
6cd876078e | ||
|
|
b56073ea68 | ||
|
|
ee98841078 | ||
|
|
3816b9d20a | ||
|
|
e6096f5a6c | ||
|
|
68de287171 | ||
|
|
cdc8f69e25 | ||
|
|
fc9ccce29c | ||
|
|
4bbbbea183 | ||
|
|
b2232172f6 | ||
|
|
1d66045ec4 | ||
|
|
5c35c23e74 | ||
|
|
bd04f9b72b | ||
|
|
269d1cf5e0 | ||
|
|
90628f56f8 | ||
|
|
fcdc2f500d | ||
|
|
14a23f800b | ||
|
|
3bde570ec5 | ||
|
|
26ad7cffec | ||
|
|
e697ee717b | ||
|
|
89dd85d61a | ||
|
|
7b57ebca4a | ||
|
|
bd49036ed8 | ||
|
|
36963d6dfb | ||
|
|
213f1b68e1 | ||
|
|
bf211fbd4d | ||
|
|
998854a22e | ||
|
|
8247f478f4 | ||
|
|
f07b762d6a | ||
|
|
8504b4b5bb | ||
|
|
392c8e9aa8 | ||
|
|
7f87d4eada | ||
|
|
6d11aa8049 | ||
|
|
0c1ce152fe | ||
|
|
82ae6a8456 | ||
|
|
9ebab2c7d0 | ||
|
|
af4488d1e9 | ||
|
|
d9599d31f1 | ||
|
|
d094ac0034 | ||
|
|
c6b7ec7c9c | ||
|
|
6e35e5b310 | ||
|
|
429787f9c8 | ||
|
|
f7995b395f | ||
|
|
72b4c8123a | ||
|
|
4c6cadea6d | ||
|
|
1bc50ea71c | ||
|
|
60b5225ffd | ||
|
|
5fe3685a05 | ||
|
|
fbfc0f6c2f | ||
|
|
bbed4be61b | ||
|
|
68f954d068 | ||
|
|
30144b8707 | ||
|
|
dd232f55a9 | ||
|
|
3a836eba63 | ||
|
|
55a16f31c2 | ||
|
|
7de88f4e47 | ||
|
|
d71b827d1a | ||
|
|
3811caa8a0 | ||
|
|
32f6bc376b | ||
|
|
8b4ebe4fa3 | ||
|
|
45415ef8da | ||
|
|
99bba14628 | ||
|
|
8b8b2568e2 | ||
|
|
ca144e127c | ||
|
|
965760df41 | ||
|
|
6ab25f7bc0 | ||
|
|
701ae5b2b1 | ||
|
|
b2d6ee06df | ||
|
|
18f5bdeaf8 | ||
|
|
dd6ce33296 | ||
|
|
5a7a6bf59c | ||
|
|
20d8a403f3 | ||
|
|
0bce8e185d | ||
|
|
7f21075613 | ||
|
|
e833860fcb | ||
|
|
376b17e011 | ||
|
|
87541a63d3 | ||
|
|
109b83d6f1 | ||
|
|
3a1fc363ed | ||
|
|
71658a5de6 | ||
|
|
40ac57a5d4 | ||
|
|
a20bf845ea | ||
|
|
95943b725c | ||
|
|
0813ae0f3c | ||
|
|
a33e34c309 | ||
|
|
821cc11364 | ||
|
|
caf7df4a82 | ||
|
|
bda39ef876 | ||
|
|
9e2ed855eb | ||
|
|
3be453e76a | ||
|
|
dec54692c1 | ||
|
|
e77d19b128 | ||
|
|
a83bf98625 | ||
|
|
3307365885 | ||
|
|
341fc774a6 | ||
|
|
56673f14b5 | ||
|
|
ab08eb2f99 | ||
|
|
000458697d | ||
|
|
b0c56d8963 | ||
|
|
0ecd65777e | ||
|
|
6d02f50d09 | ||
|
|
a71143891e | ||
|
|
6fda5924a3 | ||
|
|
b09574f62f | ||
|
|
8cdde88049 | ||
|
|
9cd42b988d | ||
|
|
8b559ad4f2 | ||
|
|
192fce8740 | ||
|
|
235016d7cf | ||
|
|
27792b0be4 | ||
|
|
765fd7d766 | ||
|
|
d49a5097f0 | ||
|
|
cfcc3fdbbe | ||
|
|
fdbceb0e42 | ||
|
|
89197cbdb2 | ||
|
|
f067f07d64 | ||
|
|
4594a978e0 | ||
|
|
fcddccf018 | ||
|
|
7a9285b326 | ||
|
|
11f0ab9226 | ||
|
|
0b6705610c | ||
|
|
9d9199ba3b | ||
|
|
ff656a0625 | ||
|
|
148fc103e3 | ||
|
|
77abbee308 | ||
|
|
83c4ce98b4 | ||
|
|
898741e40d | ||
|
|
0c3e7395e7 | ||
|
|
c530bdd107 | ||
|
|
29dbcb309d | ||
|
|
8a4990d9ae | ||
|
|
0e55cbbda6 | ||
|
|
6da94aecf2 | ||
|
|
2a3c962e88 | ||
|
|
34f1eb60f4 | ||
|
|
4115ebe856 | ||
|
|
d7dadfc157 | ||
|
|
2851eeeab3 | ||
|
|
84d75f2ae8 | ||
|
|
73b3309adf | ||
|
|
e2de06f60d | ||
|
|
cdc7962d11 | ||
|
|
59242e1217 | ||
|
|
631e39d4fd | ||
|
|
4290cdf53d | ||
|
|
84c1e20216 | ||
|
|
e6caeb86b0 | ||
|
|
5854e38a09 | ||
|
|
3e9ee9451f | ||
|
|
29d02f0a2b | ||
|
|
c780f9bbba | ||
|
|
d5a0bac0a3 | ||
|
|
f0187cc0f8 | ||
|
|
4708d894cc | ||
|
|
f38d120406 | ||
|
|
53960baf76 | ||
|
|
a0f061aa6f | ||
|
|
f2fb525d0a | ||
|
|
5a59bee597 | ||
|
|
07b903d887 | ||
|
|
1a39315001 | ||
|
|
97e5f00dae | ||
|
|
bae77f21f8 | ||
|
|
24d788f333 | ||
|
|
c4d553c605 | ||
|
|
fa64e2e67c | ||
|
|
94c29180e4 | ||
|
|
b864d91572 | ||
|
|
2006182a2a | ||
|
|
8fc3de416c | ||
|
|
4c5787511e | ||
|
|
8a2e4bc628 | ||
|
|
f78ebbb9a9 | ||
|
|
4cc4c25691 | ||
|
|
d02c7dc3a7 | ||
|
|
8741ee771e | ||
|
|
006e8463cd | ||
|
|
86e295e9bc | ||
|
|
07bade2557 | ||
|
|
0becc890d8 | ||
|
|
a1ce6f1ce5 | ||
|
|
43a7d00c63 | ||
|
|
9c04ba767c | ||
|
|
7e1d10fb4d | ||
|
|
4ce2280e31 | ||
|
|
2918a89d35 | ||
|
|
8f1c83edfd | ||
|
|
106452d857 | ||
|
|
a4d3fb6c70 | ||
|
|
a7af01b9e3 | ||
|
|
f7f434ab55 | ||
|
|
09c0854779 | ||
|
|
b4d12d74f7 | ||
|
|
50b064907a | ||
|
|
b9d6a0f269 | ||
|
|
2414e57260 | ||
|
|
6c41ddb622 | ||
|
|
55e75d56fd | ||
|
|
32ac299422 | ||
|
|
cb7146f954 | ||
|
|
144c1ce4f4 | ||
|
|
2102d6eda1 | ||
|
|
1f8e3fe26f | ||
|
|
8b0285a9d7 | ||
|
|
b546d01c2d | ||
|
|
7bf3e7df1d | ||
|
|
f9ac965e18 | ||
|
|
d70412166c | ||
|
|
a843406cb0 | ||
|
|
58115477a2 | ||
|
|
e1dc573c3c | ||
|
|
c025102511 | ||
|
|
54d052de73 | ||
|
|
7e633f0136 | ||
|
|
4b4bc1c823 | ||
|
|
767e23f34c | ||
|
|
b003d28cc5 | ||
|
|
91c8e9bd86 | ||
|
|
1f52c0b49f | ||
|
|
16fd4d4411 | ||
|
|
b8a669ad21 | ||
|
|
f0cb33a627 | ||
|
|
b5b7019325 | ||
|
|
7ccd68eb18 | ||
|
|
44b0ac57eb | ||
|
|
a411b7c969 | ||
|
|
fc8ce532f6 | ||
|
|
ef56b3c5b6 | ||
|
|
37e13804a5 | ||
|
|
8b209b3c6e | ||
|
|
cb26042d08 | ||
|
|
2952d1cde8 | ||
|
|
8a7f456560 | ||
|
|
f74b6cd82f | ||
|
|
d04515c35a | ||
|
|
2aca0ce110 | ||
|
|
d0e49b27a1 | ||
|
|
d97c365aed | ||
|
|
8304e77a04 | ||
|
|
b1db315582 | ||
|
|
4e785dd982 | ||
|
|
40f5afcf43 | ||
|
|
de2688bb33 | ||
|
|
76db09303b | ||
|
|
ea4e20f9a7 | ||
|
|
01a74856a3 | ||
|
|
36045100bf | ||
|
|
cc344cb548 | ||
|
|
a2624952a0 | ||
|
|
b8259e00dc | ||
|
|
463c823d3b | ||
|
|
5a6f3ead5a | ||
|
|
1b4d666af3 | ||
|
|
77d299338a | ||
|
|
33fc6e2f3f | ||
|
|
a95eaa6c2e | ||
|
|
5a3947bb23 | ||
|
|
f84a561d9e | ||
|
|
295878ffff | ||
|
|
609942654a | ||
|
|
60ad0196c3 | ||
|
|
caea6966ef | ||
|
|
d4c269f7cb | ||
|
|
54a1ee53b4 | ||
|
|
2c51e8ac06 | ||
|
|
3cbd69eef2 | ||
|
|
ee539644d8 | ||
|
|
465263bc97 | ||
|
|
1def65eb90 | ||
|
|
746be98bfc | ||
|
|
99b58dd318 | ||
|
|
df3ef0d895 | ||
|
|
83e4042668 | ||
|
|
c6e87568b6 | ||
|
|
0170c65c7b | ||
|
|
a7c1ccec71 | ||
|
|
1adbebf9dc | ||
|
|
9d68cb52b3 | ||
|
|
44272b650c | ||
|
|
5ce96d379a | ||
|
|
173c5fe430 | ||
|
|
e10595c3ed | ||
|
|
9138f56701 | ||
|
|
974e2a5106 | ||
|
|
509cf661f5 | ||
|
|
25fdea9984 | ||
|
|
9979e470fc | ||
|
|
2a492f5036 | ||
|
|
baf1f01e44 | ||
|
|
1f8dc944e3 | ||
|
|
dc07c6fede | ||
|
|
94a63f8aea | ||
|
|
a47cb595db | ||
|
|
86ccc176e8 | ||
|
|
b31041f0ce | ||
|
|
e434a78de9 | ||
|
|
6ddb77e03c | ||
|
|
f6665d79c0 | ||
|
|
75a7b99a42 | ||
|
|
3858a40c1c | ||
|
|
3d6aa8f2b5 | ||
|
|
54436f97c1 | ||
|
|
dca40dc6cb | ||
|
|
c19d91a373 | ||
|
|
840cfd8ab0 | ||
|
|
8cf6ba88e1 | ||
|
|
4ac81b030e | ||
|
|
e5cd1b29fe | ||
|
|
ebc932572f | ||
|
|
f0a6c6e67e | ||
|
|
e1454b5c4a | ||
|
|
f6e2abdf01 | ||
|
|
e2a02f4b21 | ||
|
|
934d7db24e | ||
|
|
2b520cbc4c | ||
|
|
e37dd73b9e | ||
|
|
c646319657 | ||
|
|
7a3a5a3f43 | ||
|
|
5345a77092 | ||
|
|
91de33550d | ||
|
|
85fb7513db | ||
|
|
c9d907e3fe | ||
|
|
5dfd02151e | ||
|
|
e446802ac9 | ||
|
|
bb71a4bb7d | ||
|
|
7ea2b9c8c0 | ||
|
|
056bc55e1f | ||
|
|
b1f89276cf | ||
|
|
f75ae6bd21 | ||
|
|
1066c65a6a | ||
|
|
03daaa4832 | ||
|
|
faea112f5e | ||
|
|
4461196ba3 | ||
|
|
ef3f20830d | ||
|
|
6d3ff5a956 | ||
|
|
9b6ef10555 | ||
|
|
1ac86cf979 | ||
|
|
1303040e17 | ||
|
|
5e2f745407 | ||
|
|
dc6861d5a4 | ||
|
|
7e5833bed2 | ||
|
|
55af587836 | ||
|
|
f59174d6ce | ||
|
|
c83c4488bf | ||
|
|
38280c358f | ||
|
|
f7c1500bc0 | ||
|
|
ae90e96a3e | ||
|
|
c05a49567d | ||
|
|
96fe34e6c7 | ||
|
|
c9f6de1371 | ||
|
|
60a995d654 | ||
|
|
1b053b0ff2 | ||
|
|
6293b586f1 | ||
|
|
f615b0133c | ||
|
|
06f509b475 | ||
|
|
47d261e45c | ||
|
|
961dbd81c7 | ||
|
|
190755126b | ||
|
|
f21ebf63ba | ||
|
|
beb30c5224 | ||
|
|
2253393ac8 | ||
|
|
965a6981db | ||
|
|
214c53220f | ||
|
|
c5af0ba621 | ||
|
|
22eff7fa21 | ||
|
|
0f57928585 | ||
|
|
7fee0297e8 | ||
|
|
df81e0fe53 | ||
|
|
c58de5c690 | ||
|
|
cf1fa52426 | ||
|
|
e58cad0464 | ||
|
|
2bf982452e | ||
|
|
891278d0b3 | ||
|
|
056226b8af | ||
|
|
f8dae86798 | ||
|
|
309f23ba94 | ||
|
|
3f93a81818 | ||
|
|
83196cda10 | ||
|
|
f3670ce86d | ||
|
|
5fd5804245 | ||
|
|
c58e557019 | ||
|
|
50515e0143 | ||
|
|
05f082ef06 | ||
|
|
20ef19ecf1 | ||
|
|
65450e36ef | ||
|
|
1b7a81afa5 | ||
|
|
470e987fad | ||
|
|
419db67267 | ||
|
|
ff70025429 | ||
|
|
7a305ef96e | ||
|
|
28efcea9d8 | ||
|
|
3927f3423f | ||
|
|
0c3b5139b1 | ||
|
|
ec9fcdf1cb | ||
|
|
d335438f12 | ||
|
|
69b536cfb9 | ||
|
|
edb4555699 | ||
|
|
8b6728c65d | ||
|
|
d3336192c3 | ||
|
|
10eadbb7e6 | ||
|
|
36a5282823 | ||
|
|
555be6c229 | ||
|
|
3f5e6883b5 | ||
|
|
ddcf90e95c | ||
|
|
683e9e72b9 | ||
|
|
123eaf77fa | ||
|
|
bb29f20a07 | ||
|
|
866390ece1 | ||
|
|
5b844e45e3 | ||
|
|
1c80771405 | ||
|
|
d42cbbd9f8 | ||
|
|
18873a9659 | ||
|
|
7859397790 | ||
|
|
bc23f9cd33 | ||
|
|
02f0057578 | ||
|
|
63761d515a | ||
|
|
5cc4b31f35 | ||
|
|
a03bf2cb8e | ||
|
|
312902ea77 | ||
|
|
961a9236fd | ||
|
|
364e63da14 | ||
|
|
27c62b3d78 | ||
|
|
51623b47f0 | ||
|
|
824cfc0c9c | ||
|
|
398e170e2d | ||
|
|
f1de6887cd | ||
|
|
7d31a838c1 | ||
|
|
61e3dc10dd | ||
|
|
7877ff4528 | ||
|
|
e8766b265d | ||
|
|
da5d1033c3 | ||
|
|
13323e423e | ||
|
|
5297252efb | ||
|
|
5ce2bef556 | ||
|
|
472c8d7808 | ||
|
|
a51b377d6b | ||
|
|
f5d764e3df | ||
|
|
f71f6d9a0d | ||
|
|
78b8c811af | ||
|
|
10d8d71d8b | ||
|
|
9e48943daf | ||
|
|
9f118c6b82 | ||
|
|
2c8dedcb85 | ||
|
|
f950dc90b9 | ||
|
|
92ca7a598a | ||
|
|
97f9d747c0 | ||
|
|
159dd13c2d | ||
|
|
98c6df0c10 | ||
|
|
8acce9a2f5 | ||
|
|
52fbd3aeb8 | ||
|
|
e9b2d8ecdf | ||
|
|
cdc4154cdf | ||
|
|
16cacec43c | ||
|
|
877fbe63c1 | ||
|
|
322d846bd9 | ||
|
|
ca8c055a58 | ||
|
|
2d8014775a | ||
|
|
699b797e0f | ||
|
|
a8e2fcdfea |
3
.github/workflows/ci-lua.yml
vendored
3
.github/workflows/ci-lua.yml
vendored
@@ -17,7 +17,8 @@ jobs:
|
||||
|
||||
- name: Check lua codes
|
||||
run: |
|
||||
set -o pipefail && luacheck . | awk -F: '
|
||||
set -o pipefail && luacheck . \
|
||||
--exclude-files=resources/prosody-plugins/mod_firewall/mod_firewall.lua | awk -F: '
|
||||
{
|
||||
print $0
|
||||
printf "::warning file=%s,line=%s,col=%s::%s\n", $1, $2, $3, $4
|
||||
|
||||
27
.github/workflows/ci.yml
vendored
27
.github/workflows/ci.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
cache: 'npm'
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v35
|
||||
uses: tj-actions/changed-files@v41
|
||||
- name: Get changed lang files
|
||||
id: lang-files
|
||||
run: echo "all=$(echo "${{ steps.changed-files.outputs.all_changed_files }}" | grep -oE 'lang\/\S+' | tr '\n' ' ')" >> "$GITHUB_OUTPUT"
|
||||
@@ -73,4 +73,29 @@ jobs:
|
||||
node-version: 16
|
||||
cache: 'npm'
|
||||
- run: npm install
|
||||
- name: setup-cocoapods
|
||||
uses: maxim-lobanov/setup-cocoapods@v1
|
||||
with:
|
||||
podfile-path: ios/Podfile.lock
|
||||
- name: Install Pods
|
||||
run: |
|
||||
pod --version
|
||||
cd ios
|
||||
pod install --repo-update
|
||||
- name: Check if the git repository is clean
|
||||
run: $(exit $(git status --porcelain --untracked-files=no | head -255 | wc -l)) || (echo "Dirty git tree"; git diff; exit 1)
|
||||
- run: npx react-native bundle --entry-file react/index.native.js --platform ios --bundle-output /tmp/ios.bundle --reset-cache
|
||||
debian-build:
|
||||
name: Test Debian packages build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: 'npm'
|
||||
- run: npm install
|
||||
- run: make
|
||||
- run: sudo apt-get install -y debhelper
|
||||
- run: dpkg-buildpackage -A -rfakeroot -us -uc -d
|
||||
- run: make source-package
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -99,6 +99,7 @@ tsconfig.json
|
||||
#
|
||||
react-native-sdk/*.tgz
|
||||
react-native-sdk/android/src
|
||||
!react-native-sdk/android/src/main/java/org/jitsi/meet/sdk/JitsiMeetReactNativePackage.java
|
||||
react-native-sdk/images
|
||||
react-native-sdk/ios
|
||||
react-native-sdk/lang
|
||||
|
||||
4
Makefile
4
Makefile
@@ -55,6 +55,8 @@ deploy-appbundle:
|
||||
$(BUILD_DIR)/face-landmarks-worker.min.js.map \
|
||||
$(BUILD_DIR)/noise-suppressor-worklet.min.js \
|
||||
$(BUILD_DIR)/noise-suppressor-worklet.min.js.map \
|
||||
$(BUILD_DIR)/screenshot-capture-worker.min.js \
|
||||
$(BUILD_DIR)/screenshot-capture-worker.min.js.map \
|
||||
$(DEPLOY_DIR)
|
||||
cp \
|
||||
$(BUILD_DIR)/close3.min.js \
|
||||
@@ -123,7 +125,7 @@ dev: deploy-init deploy-css deploy-rnnoise-binary deploy-tflite deploy-meet-mode
|
||||
|
||||
source-package:
|
||||
mkdir -p source_package/jitsi-meet/css && \
|
||||
cp -r *.js *.html resources/*.txt favicon.ico fonts images libs static sounds LICENSE lang source_package/jitsi-meet && \
|
||||
cp -r *.js *.html resources/*.txt fonts images libs static sounds LICENSE lang source_package/jitsi-meet && \
|
||||
cp css/all.css source_package/jitsi-meet/css && \
|
||||
(cd source_package ; tar cjf ../jitsi-meet.tar.bz2 jitsi-meet) && \
|
||||
rm -rf source_package
|
||||
|
||||
@@ -27,7 +27,7 @@ And many more!
|
||||
|
||||
## Using Jitsi Meet
|
||||
|
||||
Using Jitsi Meet is straightforward, as it's browser based. Head over to [meet.jit.si](https://meet.jit.si) and give it a try. It's anonymous, scalable and free to use. All browsers are supported!
|
||||
Using Jitsi Meet is straightforward, as it's browser based. Head over to [meet.jit.si](https://meet.jit.si) and give it a try. It's scalable and free to use. All you need is a Google, Facebook or GitHub account in order to start a meeting. All browsers are supported!
|
||||
|
||||
Using mobile? No problem, you can either use your mobile web browser or our fully-featured
|
||||
mobile apps:
|
||||
|
||||
@@ -15,11 +15,13 @@ def vcode = (int) (((new Date().getTime() / 1000) - 1546297200) / 10)
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
packagingOptions {
|
||||
exclude 'lib/*/libhermes*.so'
|
||||
jniLibs {
|
||||
excludes += ['lib/*/libhermes*.so']
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'org.jitsi.meet'
|
||||
versionCode vcode
|
||||
@@ -72,23 +74,24 @@ android {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
namespace 'org.jitsi.meet'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.13'
|
||||
|
||||
if (!rootProject.ext.libreBuild) {
|
||||
implementation 'com.google.android.gms:play-services-auth:16.0.1'
|
||||
// Sync with react-native-google-signin
|
||||
implementation 'com.google.android.gms:play-services-auth:20.5.0'
|
||||
|
||||
// Firebase
|
||||
// - Crashlytics
|
||||
// - Dynamic Links
|
||||
implementation 'com.google.firebase:firebase-analytics:17.5.0'
|
||||
implementation 'com.google.firebase:firebase-crashlytics:17.2.1'
|
||||
implementation 'com.google.firebase:firebase-dynamic-links:19.1.0'
|
||||
implementation 'com.google.firebase:firebase-analytics:21.3.0'
|
||||
implementation 'com.google.firebase:firebase-crashlytics:18.4.3'
|
||||
implementation 'com.google.firebase:firebase-dynamic-links:21.1.0'
|
||||
}
|
||||
|
||||
implementation project(':sdk')
|
||||
|
||||
40
android/app/proguard-rules.pro
vendored
40
android/app/proguard-rules.pro
vendored
@@ -1,3 +1,8 @@
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
|
||||
@@ -9,20 +14,25 @@
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# Disabling obfuscation is useful if you collect stack traces from production crashes
|
||||
# (unless you are using a system that supports de-obfuscate the stack traces).
|
||||
# -dontobfuscate
|
||||
|
||||
# React Native
|
||||
|
||||
# Keep our interfaces so they can be used by other ProGuard rules.
|
||||
# See http://sourceforge.net/p/proguard/bugs/466/
|
||||
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
|
||||
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
|
||||
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
|
||||
|
||||
# Do not strip any method/class that is annotated with @DoNotStrip
|
||||
-keep @com.facebook.proguard.annotations.DoNotStrip class *
|
||||
-keep @com.facebook.common.internal.DoNotStrip class *
|
||||
-keepclassmembers class * {
|
||||
@com.facebook.proguard.annotations.DoNotStrip *;
|
||||
@com.facebook.common.internal.DoNotStrip *;
|
||||
}
|
||||
|
||||
-keep @com.facebook.proguard.annotations.DoNotStripAny class * {
|
||||
*;
|
||||
}
|
||||
|
||||
-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
|
||||
@@ -30,32 +40,32 @@
|
||||
*** get*();
|
||||
}
|
||||
|
||||
-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
|
||||
-keep class * extends com.facebook.react.bridge.NativeModule { *; }
|
||||
-keep class * implements com.facebook.react.bridge.JavaScriptModule { *; }
|
||||
-keep class * implements com.facebook.react.bridge.NativeModule { *; }
|
||||
-keepclassmembers,includedescriptorclasses class * { native <methods>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.UIProp <fields>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }
|
||||
|
||||
-dontwarn com.facebook.react.**
|
||||
-keep,includedescriptorclasses class com.facebook.react.bridge.** { *; }
|
||||
-keep,includedescriptorclasses class com.facebook.react.turbomodule.core.** { *; }
|
||||
|
||||
# okhttp
|
||||
|
||||
-keepattributes Signature
|
||||
-keepattributes *Annotation*
|
||||
-keep class okhttp3.** { *; }
|
||||
-keep interface okhttp3.** { *; }
|
||||
-dontwarn okhttp3.**
|
||||
# hermes
|
||||
-keep class com.facebook.jni.** { *; }
|
||||
|
||||
# okio
|
||||
|
||||
-keep class sun.misc.Unsafe { *; }
|
||||
-dontwarn java.nio.file.*
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
-keep class okio.** { *; }
|
||||
-dontwarn okio.**
|
||||
|
||||
# yoga
|
||||
-keep,allowobfuscation @interface com.facebook.yoga.annotations.DoNotStrip
|
||||
-keep @com.facebook.yoga.annotations.DoNotStrip class *
|
||||
-keepclassmembers class * {
|
||||
@com.facebook.yoga.annotations.DoNotStrip *;
|
||||
}
|
||||
|
||||
# WebRTC
|
||||
|
||||
-keep class org.webrtc.** { *; }
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.jitsi.meet"
|
||||
android:installLocation="auto">
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
||||
@@ -152,7 +152,6 @@ public class MainActivity extends JitsiMeetActivity {
|
||||
= new JitsiMeetConferenceOptions.Builder()
|
||||
.setServerURL(buildURL(defaultURL))
|
||||
.setFeatureFlag("welcomepage.enabled", true)
|
||||
.setFeatureFlag("call-integration.enabled", false)
|
||||
.setFeatureFlag("resolution", 360)
|
||||
.setFeatureFlag("server-url-change.enabled", !configurationByRestrictions)
|
||||
.build();
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Server URL configuration -->
|
||||
<restriction
|
||||
android:defaultValue="https://meet.jit.si"
|
||||
android:description="@string/restriction_server_url_description"
|
||||
android:key="SERVER_URL"
|
||||
android:restrictionType="string"
|
||||
android:title="@string/restriction_server_url_title"/>
|
||||
</restrictions>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Server URL configuration -->
|
||||
<restriction
|
||||
android:description="@string/restriction_server_url_description"
|
||||
android:key="SERVER_URL"
|
||||
android:restrictionType="string"
|
||||
android:title="@string/restriction_server_url_title"/>
|
||||
</restrictions>
|
||||
|
||||
@@ -10,29 +10,24 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.1.1'
|
||||
classpath 'com.google.gms:google-services:4.3.14'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2'
|
||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||
classpath 'com.google.gms:google-services:4.4.0'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
kotlinVersion = "1.7.0"
|
||||
buildToolsVersion = "31.0.0"
|
||||
compileSdkVersion = 32
|
||||
buildToolsVersion = "33.0.2"
|
||||
compileSdkVersion = 34
|
||||
minSdkVersion = 24
|
||||
targetSdkVersion = 32
|
||||
targetSdkVersion = 34
|
||||
supportLibVersion = "28.0.0"
|
||||
|
||||
if (System.properties['os.arch'] == "aarch64") {
|
||||
// For M1 Users we need to use the NDK 24 which added support for aarch64
|
||||
ndkVersion = "24.0.8215888"
|
||||
} else {
|
||||
// Otherwise we default to the side-by-side NDK version from AGP.
|
||||
ndkVersion = "21.4.7075529"
|
||||
}
|
||||
// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
|
||||
ndkVersion = "23.1.7779620"
|
||||
|
||||
// The Maven artifact groupdId of the third-party react-native modules which
|
||||
// The Maven artifact groupId of the third-party react-native modules which
|
||||
// Jitsi Meet SDK for Android depends on and which are not available in
|
||||
// third-party Maven repositories so we have to deploy to a Maven repository
|
||||
// of ours.
|
||||
@@ -47,21 +42,16 @@ ext {
|
||||
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
|
||||
|
||||
googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
|
||||
|
||||
//React Native Version
|
||||
rnVersion = "0.72.9"
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
// React Native (JS, Obj-C sources, Android binaries) is installed from npm.
|
||||
maven { url "$rootDir/../node_modules/react-native/android" }
|
||||
// Android JSC is installed from npm.
|
||||
maven { url("$rootDir/../node_modules/jsc-android/dist") }
|
||||
mavenCentral {
|
||||
// We don't want to fetch react-native from Maven Central as there are
|
||||
// older versions over there.
|
||||
content {
|
||||
excludeGroup "com.facebook.react"
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
google()
|
||||
maven { url 'https://www.jitpack.io' }
|
||||
}
|
||||
@@ -71,11 +61,13 @@ allprojects {
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
eachDependency { DependencyResolveDetails details ->
|
||||
if (details.requested.group == 'com.facebook.react'
|
||||
&& details.requested.name == 'react-native') {
|
||||
def file = new File("$rootDir/../node_modules/react-native/package.json")
|
||||
def version = new JsonSlurper().parseText(file.text).version
|
||||
details.useVersion version
|
||||
if (details.requested.group == 'com.facebook.react') {
|
||||
if (details.requested.name == 'react-native') {
|
||||
details.useTarget "com.facebook.react:react-android:$rnVersion"
|
||||
}
|
||||
if (details.requested.name == 'react-android') {
|
||||
details.useVersion rootProject.ext.rnVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,5 +26,5 @@ android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
android.bundle.enableUncompressedNativeLibs=false
|
||||
|
||||
appVersion=99.0.0
|
||||
sdkVersion=99.0.0
|
||||
appVersion=24.0.1
|
||||
sdkVersion=9.0.2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -9,7 +9,6 @@ THE_MVN_REPO=${MVN_REPO:-${1:-$DEFAULT_MVN_REPO}}
|
||||
MVN_HTTP=0
|
||||
DEFAULT_SDK_VERSION=$(grep sdkVersion ${THIS_DIR}/../gradle.properties | cut -d"=" -f2)
|
||||
SDK_VERSION=${OVERRIDE_SDK_VERSION:-${DEFAULT_SDK_VERSION}}
|
||||
RN_VERSION=$(jq -r '.version' ${THIS_DIR}/../../node_modules/react-native/package.json)
|
||||
JSC_VERSION="r"$(jq -r '.dependencies."jsc-android"' ${THIS_DIR}/../../node_modules/react-native/package.json | cut -d . -f 1 | cut -c 2-)
|
||||
DO_GIT_TAG=${GIT_TAG:-0}
|
||||
|
||||
@@ -25,19 +24,7 @@ export MVN_REPO=$THE_MVN_REPO
|
||||
echo "Releasing Jitsi Meet SDK ${SDK_VERSION}"
|
||||
echo "Using ${MVN_REPO} as the Maven repo"
|
||||
|
||||
if [[ $MVN_HTTP == 1 ]]; then
|
||||
# Push React Native
|
||||
echo "Pushing React Native ${RN_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/react-native/android/com/facebook/react/react-native/${RN_VERSION}
|
||||
mvn \
|
||||
deploy:deploy-file \
|
||||
-Durl=${MVN_REPO} \
|
||||
-DrepositoryId=${MVN_REPO_ID} \
|
||||
-Dfile=react-native-${RN_VERSION}-release.aar \
|
||||
-Dpackaging=aar \
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=react-native-${RN_VERSION}.pom || true
|
||||
popd
|
||||
if [[ $MVN_HTTP == 1 ]]; then
|
||||
# Push JSC
|
||||
echo "Pushing JSC ${JSC_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/jsc-android/dist/org/webkit/android-jsc/${JSC_VERSION}
|
||||
@@ -51,20 +38,6 @@ if [[ $MVN_HTTP == 1 ]]; then
|
||||
-DpomFile=android-jsc-${JSC_VERSION}.pom || true
|
||||
popd
|
||||
else
|
||||
# Push React Native, if necessary
|
||||
if [[ ! -d ${MVN_REPO}/com/facebook/react/react-native/${RN_VERSION} ]]; then
|
||||
echo "Pushing React Native ${RN_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/react-native/android/com/facebook/react/react-native/${RN_VERSION}
|
||||
mvn \
|
||||
deploy:deploy-file \
|
||||
-Durl=${MVN_REPO} \
|
||||
-Dfile=react-native-${RN_VERSION}-release.aar \
|
||||
-Dpackaging=aar \
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=react-native-${RN_VERSION}.pom
|
||||
popd
|
||||
fi
|
||||
|
||||
# Push JSC, if necessary
|
||||
if [[ ! -d ${MVN_REPO}/org/webkit/android-jsc/${JSC_VERSION} ]]; then
|
||||
echo "Pushing JSC ${JSC_VERSION} to the Maven repo"
|
||||
@@ -89,8 +62,8 @@ fi
|
||||
# Now build and publish the Jitsi Meet SDK and its dependencies
|
||||
echo "Building and publishing the Jitsi Meet SDK"
|
||||
pushd ${THIS_DIR}/../
|
||||
./gradlew clean
|
||||
./gradlew assembleRelease
|
||||
./gradlew clean
|
||||
./gradlew assembleRelease
|
||||
./gradlew publish
|
||||
popd
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ android {
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace 'org.jitsi.meet.sdk'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -39,8 +40,8 @@ dependencies {
|
||||
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
|
||||
//noinspection GradleDynamicVersion
|
||||
api 'com.facebook.react:react-native:+'
|
||||
api "com.facebook.react:react-android:$rootProject.ext.rnVersion"
|
||||
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation 'org.webkit:android-jsc:+'
|
||||
|
||||
@@ -49,7 +50,7 @@ dependencies {
|
||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||
implementation 'com.squareup.duktape:duktape-android:1.3.0'
|
||||
implementation 'com.google.code.gson:gson:2.8.6'
|
||||
implementation "androidx.startup:startup-runtime:1.1.0"
|
||||
implementation 'androidx.startup:startup-runtime:1.1.0'
|
||||
|
||||
// Only add these packages if we are NOT doing a LIBRE_BUILD
|
||||
if (!rootProject.ext.libreBuild) {
|
||||
@@ -74,7 +75,7 @@ dependencies {
|
||||
}
|
||||
implementation project(':react-native-gesture-handler')
|
||||
implementation project(':react-native-get-random-values')
|
||||
implementation project(':react-native-immersive')
|
||||
implementation project(':react-native-immersive-mode')
|
||||
implementation project(':react-native-keep-awake')
|
||||
implementation project(':react-native-orientation-locker')
|
||||
implementation project(':react-native-pager-view')
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="org.jitsi.meet.sdk">
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- XXX ACCESS_NETWORK_STATE is required by WebRTC. -->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
@@ -13,6 +12,7 @@
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||
|
||||
<uses-feature
|
||||
android:glEsVersion="0x00020000"
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
<service
|
||||
android:name="org.jitsi.meet.sdk.JitsiMeetOngoingConferenceService"
|
||||
android:foregroundServiceType="mediaProjection" />
|
||||
android:foregroundServiceType="mediaPlayback" />
|
||||
|
||||
<provider
|
||||
android:name="com.reactnativecommunity.webview.RNCWebViewFileProvider"
|
||||
@@ -66,4 +66,4 @@
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
||||
@@ -87,6 +87,7 @@ class AudioDeviceHandlerGeneric implements
|
||||
devices.add(AudioModeModule.DEVICE_EARPIECE);
|
||||
break;
|
||||
case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
|
||||
case AudioDeviceInfo.TYPE_HDMI:
|
||||
devices.add(AudioModeModule.DEVICE_SPEAKER);
|
||||
break;
|
||||
case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
|
||||
|
||||
@@ -77,7 +77,8 @@ public class BroadcastAction {
|
||||
CLOSE_CHAT("org.jitsi.meet.CLOSE_CHAT"),
|
||||
SEND_CHAT_MESSAGE("org.jitsi.meet.SEND_CHAT_MESSAGE"),
|
||||
SET_VIDEO_MUTED("org.jitsi.meet.SET_VIDEO_MUTED"),
|
||||
SET_CLOSED_CAPTIONS_ENABLED("org.jitsi.meet.SET_CLOSED_CAPTIONS_ENABLED");
|
||||
SET_CLOSED_CAPTIONS_ENABLED("org.jitsi.meet.SET_CLOSED_CAPTIONS_ENABLED"),
|
||||
TOGGLE_CAMERA("org.jitsi.meet.TOGGLE_CAMERA");
|
||||
|
||||
private final String action;
|
||||
|
||||
|
||||
@@ -75,6 +75,8 @@ public class BroadcastEvent {
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
CONFERENCE_BLURRED("org.jitsi.meet.CONFERENCE_BLURRED"),
|
||||
CONFERENCE_FOCUSED("org.jitsi.meet.CONFERENCE_FOCUSED"),
|
||||
CONFERENCE_JOINED("org.jitsi.meet.CONFERENCE_JOINED"),
|
||||
CONFERENCE_TERMINATED("org.jitsi.meet.CONFERENCE_TERMINATED"),
|
||||
CONFERENCE_WILL_JOIN("org.jitsi.meet.CONFERENCE_WILL_JOIN"),
|
||||
@@ -89,6 +91,8 @@ public class BroadcastEvent {
|
||||
VIDEO_MUTED_CHANGED("org.jitsi.meet.VIDEO_MUTED_CHANGED"),
|
||||
READY_TO_CLOSE("org.jitsi.meet.READY_TO_CLOSE");
|
||||
|
||||
private static final String CONFERENCE_BLURRED_NAME = "CONFERENCE_BLURRED";
|
||||
private static final String CONFERENCE_FOCUSED_NAME = "CONFERENCE_FOCUSED";
|
||||
private static final String CONFERENCE_WILL_JOIN_NAME = "CONFERENCE_WILL_JOIN";
|
||||
private static final String CONFERENCE_JOINED_NAME = "CONFERENCE_JOINED";
|
||||
private static final String CONFERENCE_TERMINATED_NAME = "CONFERENCE_TERMINATED";
|
||||
@@ -124,6 +128,10 @@ public class BroadcastEvent {
|
||||
|
||||
private static Type buildTypeFromName(String name) {
|
||||
switch (name) {
|
||||
case CONFERENCE_BLURRED_NAME:
|
||||
return CONFERENCE_BLURRED;
|
||||
case CONFERENCE_FOCUSED_NAME:
|
||||
return CONFERENCE_FOCUSED;
|
||||
case CONFERENCE_WILL_JOIN_NAME:
|
||||
return CONFERENCE_WILL_JOIN;
|
||||
case CONFERENCE_JOINED_NAME:
|
||||
|
||||
@@ -54,4 +54,14 @@ public class BroadcastIntentHelper {
|
||||
intent.putExtra("enabled", enabled);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent buildRetrieveParticipantsInfo(String requestId) {
|
||||
Intent intent = new Intent(BroadcastAction.Type.RETRIEVE_PARTICIPANTS_INFO.getAction());
|
||||
intent.putExtra("requestId", requestId);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent buildToggleCameraIntent() {
|
||||
return new Intent(BroadcastAction.Type.TOGGLE_CAMERA.getAction());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ class ExternalAPIModule extends ReactContextBaseJavaModule {
|
||||
constants.put("SEND_CHAT_MESSAGE", BroadcastAction.Type.SEND_CHAT_MESSAGE.getAction());
|
||||
constants.put("SET_VIDEO_MUTED", BroadcastAction.Type.SET_VIDEO_MUTED.getAction());
|
||||
constants.put("SET_CLOSED_CAPTIONS_ENABLED", BroadcastAction.Type.SET_CLOSED_CAPTIONS_ENABLED.getAction());
|
||||
constants.put("TOGGLE_CAMERA", BroadcastAction.Type.TOGGLE_CAMERA.getAction());
|
||||
|
||||
return constants;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.Service;
|
||||
@@ -23,6 +24,7 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@@ -32,6 +34,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* This class implements an Android {@link Service}, a foreground one specifically, and it's
|
||||
@@ -51,8 +54,12 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
|
||||
private boolean isAudioMuted;
|
||||
|
||||
static final int NOTIFICATION_ID = new Random().nextInt(99999) + 10000;
|
||||
|
||||
|
||||
public static void launch(Context context, HashMap<String, Object> extraData) {
|
||||
OngoingNotification.createOngoingConferenceNotificationChannel();
|
||||
|
||||
OngoingNotification.createNotificationChannel((Activity) context);
|
||||
|
||||
Intent intent = new Intent(context, JitsiMeetOngoingConferenceService.class);
|
||||
|
||||
@@ -89,13 +96,16 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted);
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted, this);
|
||||
if (notification == null) {
|
||||
stopSelf();
|
||||
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
|
||||
} else {
|
||||
startForeground(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
JitsiMeetLogger.i(TAG + " Service started");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
|
||||
} else {
|
||||
startForeground(NOTIFICATION_ID, notification);
|
||||
}
|
||||
}
|
||||
|
||||
OngoingConferenceTracker.getInstance().addListener(this);
|
||||
@@ -126,13 +136,13 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
if (isAudioMuted != null) {
|
||||
this.isAudioMuted = Boolean.parseBoolean(intent.getStringExtra("muted"));
|
||||
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted);
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted, this);
|
||||
if (notification == null) {
|
||||
stopSelf();
|
||||
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
|
||||
} else {
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
notificationManager.notify(NOTIFICATION_ID, notification);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,13 +222,13 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
isAudioMuted = Boolean.parseBoolean(intent.getStringExtra("muted"));
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted);
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted, context);
|
||||
if (notification == null) {
|
||||
stopSelf();
|
||||
JitsiMeetLogger.w(TAG + " Couldn't update service, notification is null");
|
||||
} else {
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
notificationManager.notify(NOTIFICATION_ID, notification);
|
||||
|
||||
JitsiMeetLogger.i(TAG + " audio muted changed");
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.rnimmersive.RNImmersiveModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
@@ -229,22 +228,4 @@ public class JitsiMeetView extends FrameLayout {
|
||||
dispose();
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the window containing this view gains or loses focus.
|
||||
*
|
||||
* @param hasFocus If the window of this view now has focus, {@code true};
|
||||
* otherwise, {@code false}.
|
||||
*/
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
|
||||
// https://github.com/mockingbot/react-native-immersive#restore-immersive-state
|
||||
RNImmersiveModule immersive = RNImmersiveModule.getInstance();
|
||||
|
||||
if (hasFocus && immersive != null) {
|
||||
immersive.emitImmersiveStateChangeEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NotificationChannels {
|
||||
static final String ONGOING_CONFERENCE_CHANNEL_ID = "JitsiOngoingConferenceChannel";
|
||||
|
||||
public static List<String> allIds = new ArrayList<String>() {{ add(ONGOING_CONFERENCE_CHANNEL_ID); }};
|
||||
}
|
||||
@@ -16,22 +16,21 @@
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import static org.jitsi.meet.sdk.NotificationChannels.ONGOING_CONFERENCE_CHANNEL_ID;
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import android.os.Build;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Helper class for creating the ongoing notification which is used with
|
||||
@@ -41,15 +40,15 @@ import java.util.Random;
|
||||
class OngoingNotification {
|
||||
private static final String TAG = OngoingNotification.class.getSimpleName();
|
||||
|
||||
static final int NOTIFICATION_ID = new Random().nextInt(99999) + 10000;
|
||||
private static long startingTime = 0;
|
||||
|
||||
static void createOngoingConferenceNotificationChannel() {
|
||||
static final String ONGOING_CONFERENCE_CHANNEL_ID = "JitsiOngoingConferenceChannel";
|
||||
|
||||
static void createNotificationChannel(Activity context) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
return;
|
||||
}
|
||||
|
||||
Context context = ReactInstanceManagerHolder.getCurrentActivity();
|
||||
if (context == null) {
|
||||
JitsiMeetLogger.w(TAG + " Cannot create notification channel: no current context");
|
||||
return;
|
||||
@@ -60,12 +59,13 @@ class OngoingNotification {
|
||||
|
||||
NotificationChannel channel
|
||||
= notificationManager.getNotificationChannel(ONGOING_CONFERENCE_CHANNEL_ID);
|
||||
|
||||
if (channel != null) {
|
||||
// The channel was already created, no need to do it again.
|
||||
return;
|
||||
}
|
||||
|
||||
channel = new NotificationChannel(ONGOING_CONFERENCE_CHANNEL_ID, context.getString(R.string.ongoing_notification_action_unmute), NotificationManager.IMPORTANCE_DEFAULT);
|
||||
channel = new NotificationChannel(ONGOING_CONFERENCE_CHANNEL_ID, context.getString(R.string.ongoing_notification_channel_name), NotificationManager.IMPORTANCE_DEFAULT);
|
||||
channel.enableLights(false);
|
||||
channel.enableVibration(false);
|
||||
channel.setShowBadge(false);
|
||||
@@ -73,8 +73,8 @@ class OngoingNotification {
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
static Notification buildOngoingConferenceNotification(boolean isMuted) {
|
||||
Context context = ReactInstanceManagerHolder.getCurrentActivity();
|
||||
static Notification buildOngoingConferenceNotification(Boolean isMuted, Context context) {
|
||||
|
||||
if (context == null) {
|
||||
JitsiMeetLogger.w(TAG + " Cannot create notification: no current context");
|
||||
return null;
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.oney.WebRTCModule.webrtcutils.H264AndSoftwareVideoEncoderFactory;
|
||||
|
||||
import org.devio.rn.splashscreen.SplashScreenModule;
|
||||
import org.webrtc.EglBase;
|
||||
import org.webrtc.Logging;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
@@ -105,7 +106,7 @@ class ReactInstanceManagerHolder {
|
||||
new com.oney.WebRTCModule.WebRTCModulePackage(),
|
||||
new com.swmansion.gesturehandler.RNGestureHandlerPackage(),
|
||||
new org.linusu.RNGetRandomValuesPackage(),
|
||||
new com.rnimmersive.RNImmersivePackage(),
|
||||
new com.rnimmersivemode.RNImmersiveModePackage(),
|
||||
new com.swmansion.rnscreens.RNScreensPackage(),
|
||||
new com.zmxv.RNSound.RNSoundPackage(),
|
||||
new com.th3rdwave.safeareacontext.SafeAreaContextPackage(),
|
||||
@@ -240,6 +241,8 @@ class ReactInstanceManagerHolder {
|
||||
|
||||
options.videoDecoderFactory = new H264AndSoftwareVideoDecoderFactory(eglContext);
|
||||
options.videoEncoderFactory = new H264AndSoftwareVideoEncoderFactory(eglContext);
|
||||
options.enableMediaProjectionService = true;
|
||||
// options.loggingSeverity = Logging.Severity.LS_INFO;
|
||||
|
||||
Log.d(TAG, "initializing RN with Activity");
|
||||
|
||||
|
||||
9
android/sdk/src/main/res/values-ru/strings.xml
Normal file
9
android/sdk/src/main/res/values-ru/strings.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="ongoing_notification_title">Текущая встреча</string>
|
||||
<string name="ongoing_notification_text">Нажмите, чтобы вернуться к встрече.</string>
|
||||
<string name="ongoing_notification_action_hang_up">Отключиться</string>
|
||||
<string name="ongoing_notification_action_mute">Отключить звук</string>
|
||||
<string name="ongoing_notification_action_unmute">Включить звук</string>
|
||||
<string name="ongoing_notification_channel_name">Ongoing Conference Notifications</string>
|
||||
</resources>
|
||||
@@ -1,6 +1,8 @@
|
||||
<resources>
|
||||
<string name="app_name">Jitsi Meet SDK</string>
|
||||
<string name="dropbox_app_key"></string>
|
||||
<string name="media_projection_notification_title">Media projection</string>
|
||||
<string name="media_projection_notification_text">You are currently sharing your screen.</string>
|
||||
<string name="ongoing_notification_title">Ongoing meeting</string>
|
||||
<string name="ongoing_notification_text">You are currently in a meeting. Tap to return to it.</string>
|
||||
<string name="ongoing_notification_action_hang_up">Hang up</string>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
rootProject.name = 'jitsi-meet'
|
||||
|
||||
include ':app', ':sdk'
|
||||
includeBuild('../node_modules/react-native-gradle-plugin')
|
||||
|
||||
include ':react-native-amplitude'
|
||||
project(':react-native-amplitude').projectDir = new File(rootProject.projectDir, '../node_modules/@amplitude/react-native//android')
|
||||
project(':react-native-amplitude').projectDir = new File(rootProject.projectDir, '../node_modules/@amplitude/react-native/android')
|
||||
include ':react-native-async-storage'
|
||||
project(':react-native-async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-async-storage/async-storage/android')
|
||||
include ':react-native-background-timer'
|
||||
@@ -27,8 +26,8 @@ include ':react-native-giphy'
|
||||
project(':react-native-giphy').projectDir = new File(rootProject.projectDir, '../node_modules/@giphy/react-native-sdk/android')
|
||||
include ':react-native-google-signin'
|
||||
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-google-signin/google-signin/android')
|
||||
include ':react-native-immersive'
|
||||
project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
|
||||
include ':react-native-immersive-mode'
|
||||
project(':react-native-immersive-mode').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive-mode/android')
|
||||
include ':react-native-keep-awake'
|
||||
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android')
|
||||
include ':react-native-orientation-locker'
|
||||
|
||||
6
app.js
6
app.js
@@ -31,12 +31,6 @@ if (window.Olm) {
|
||||
window.APP = {
|
||||
API,
|
||||
conference,
|
||||
|
||||
// Used for automated performance tests.
|
||||
connectionTimes: {
|
||||
'index.loaded': window.indexLoadedTime
|
||||
},
|
||||
|
||||
translation,
|
||||
UI
|
||||
};
|
||||
|
||||
531
conference.js
531
conference.js
@@ -4,12 +4,8 @@ import { jitsiLocalStorage } from '@jitsi/js-utils';
|
||||
import Logger from '@jitsi/logger';
|
||||
import EventEmitter from 'events';
|
||||
|
||||
import { openConnection } from './connection';
|
||||
import { ENDPOINT_TEXT_MESSAGE_NAME } from './modules/API/constants';
|
||||
import { AUDIO_ONLY_SCREEN_SHARE_NO_TRACK } from './modules/UI/UIErrors';
|
||||
import AuthHandler from './modules/UI/authentication/AuthHandler';
|
||||
import UIUtil from './modules/UI/util/UIUtil';
|
||||
import VideoLayout from './modules/UI/videolayout/VideoLayout';
|
||||
import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
|
||||
import Recorder from './modules/recorder/Recorder';
|
||||
import { createTaskQueue } from './modules/util/helpers';
|
||||
@@ -37,11 +33,12 @@ import {
|
||||
conferenceSubjectChanged,
|
||||
conferenceTimestampChanged,
|
||||
conferenceUniqueIdSet,
|
||||
conferenceWillJoin,
|
||||
conferenceWillInit,
|
||||
conferenceWillLeave,
|
||||
dataChannelClosed,
|
||||
dataChannelOpened,
|
||||
e2eRttChanged,
|
||||
endpointMessageReceived,
|
||||
kickedOut,
|
||||
lockStateChanged,
|
||||
nonParticipantMessageReceived,
|
||||
@@ -57,12 +54,10 @@ import {
|
||||
commonUserJoinedHandling,
|
||||
commonUserLeftHandling,
|
||||
getConferenceOptions,
|
||||
getVisitorOptions,
|
||||
restoreConferenceOptions,
|
||||
sendLocalParticipant
|
||||
} from './react/features/base/conference/functions';
|
||||
import { overwriteConfig } from './react/features/base/config/actions';
|
||||
import { getReplaceParticipant } from './react/features/base/config/functions';
|
||||
import { connect } from './react/features/base/connection/actions.web';
|
||||
import {
|
||||
checkAndNotifyForNewDevice,
|
||||
getAvailableDevices,
|
||||
@@ -71,21 +66,22 @@ import {
|
||||
updateDeviceList
|
||||
} from './react/features/base/devices/actions.web';
|
||||
import {
|
||||
areDevicesDifferent,
|
||||
filterIgnoredDevices,
|
||||
flattenAvailableDevices,
|
||||
getDefaultDeviceId,
|
||||
logDevices,
|
||||
setAudioOutputDeviceId
|
||||
} from './react/features/base/devices/functions.web';
|
||||
import {
|
||||
JitsiConferenceErrors,
|
||||
JitsiConferenceEvents,
|
||||
JitsiConnectionErrors,
|
||||
JitsiConnectionEvents,
|
||||
JitsiE2ePingEvents,
|
||||
JitsiMediaDevicesEvents,
|
||||
JitsiTrackErrors,
|
||||
JitsiTrackEvents,
|
||||
browser
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
|
||||
import {
|
||||
gumPending,
|
||||
setAudioAvailable,
|
||||
@@ -95,7 +91,7 @@ import {
|
||||
setVideoMuted,
|
||||
setVideoUnmutePermissions
|
||||
} from './react/features/base/media/actions';
|
||||
import { MEDIA_TYPE } from './react/features/base/media/constants';
|
||||
import { MEDIA_TYPE, VIDEO_TYPE } from './react/features/base/media/constants';
|
||||
import {
|
||||
getStartWithAudioMuted,
|
||||
getStartWithVideoMuted,
|
||||
@@ -139,13 +135,19 @@ import {
|
||||
isUserInteractionRequiredForUnmute
|
||||
} from './react/features/base/tracks/functions';
|
||||
import { downloadJSON } from './react/features/base/util/downloadJSON';
|
||||
import { openLeaveReasonDialog } from './react/features/conference/actions.web';
|
||||
import { showDesktopPicker } from './react/features/desktop-picker/actions';
|
||||
import { appendSuffix } from './react/features/display-name/functions';
|
||||
import { maybeOpenFeedbackDialog, submitFeedback } from './react/features/feedback/actions';
|
||||
import { initKeyboardShortcuts } from './react/features/keyboard-shortcuts/actions';
|
||||
import { maybeSetLobbyChatMessageListener } from './react/features/lobby/actions.any';
|
||||
import { setNoiseSuppressionEnabled } from './react/features/noise-suppression/actions';
|
||||
import { hideNotification, showNotification, showWarningNotification } from './react/features/notifications/actions';
|
||||
import {
|
||||
hideNotification,
|
||||
showErrorNotification,
|
||||
showNotification,
|
||||
showWarningNotification
|
||||
} from './react/features/notifications/actions';
|
||||
import {
|
||||
DATA_CHANNEL_CLOSED_NOTIFICATION_ID,
|
||||
NOTIFICATION_TIMEOUT_TYPE
|
||||
@@ -153,7 +155,7 @@ import {
|
||||
import { isModerationNotificationDisplayed } from './react/features/notifications/functions';
|
||||
import { mediaPermissionPromptVisibilityChanged } from './react/features/overlay/actions';
|
||||
import { suspendDetected } from './react/features/power-monitor/actions';
|
||||
import { initPrejoin, makePrecallTest, setJoiningInProgress } from './react/features/prejoin/actions';
|
||||
import { initPrejoin } from './react/features/prejoin/actions';
|
||||
import { isPrejoinPageVisible } from './react/features/prejoin/functions';
|
||||
import { disableReceiver, stopReceiver } from './react/features/remote-control/actions';
|
||||
import { setScreenAudioShareState } from './react/features/screen-share/actions.web';
|
||||
@@ -161,11 +163,8 @@ import { isScreenAudioShared } from './react/features/screen-share/functions';
|
||||
import { toggleScreenshotCaptureSummary } from './react/features/screenshot-capture/actions';
|
||||
import { AudioMixerEffect } from './react/features/stream-effects/audio-mixer/AudioMixerEffect';
|
||||
import { createRnnoiseProcessor } from './react/features/stream-effects/rnnoise';
|
||||
import { endpointMessageReceived } from './react/features/subtitles/actions.any';
|
||||
import { handleToggleVideoMuted } from './react/features/toolbox/actions.any';
|
||||
import { muteLocal } from './react/features/video-menu/actions.any';
|
||||
import { setIAmVisitor } from './react/features/visitors/actions';
|
||||
import { iAmVisitor } from './react/features/visitors/functions';
|
||||
import UIEvents from './service/UI/UIEvents';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
@@ -173,25 +172,6 @@ const logger = Logger.getLogger(__filename);
|
||||
const eventEmitter = new EventEmitter();
|
||||
|
||||
let room;
|
||||
let connection;
|
||||
|
||||
/**
|
||||
* The promise is used when the prejoin screen is shown.
|
||||
* While the user configures the devices the connection can be made.
|
||||
*
|
||||
* @type {Promise<Object>}
|
||||
* @private
|
||||
*/
|
||||
let _connectionPromise;
|
||||
|
||||
/**
|
||||
* We are storing the resolve function of a Promise that waits for the _connectionPromise to be created. This is needed
|
||||
* when the prejoin button was pressed before the conference object was initialized and the _connectionPromise has not
|
||||
* been initialized when we tried to execute prejoinStart. In this case in prejoinStart we create a new Promise, assign
|
||||
* the resolve function to this variable and wait for the promise to resolve before we continue. The
|
||||
* _onConnectionPromiseCreated will be called once the _connectionPromise is created.
|
||||
*/
|
||||
let _onConnectionPromiseCreated;
|
||||
|
||||
/*
|
||||
* Logic to open a desktop picker put on the window global for
|
||||
@@ -213,26 +193,6 @@ const commands = {
|
||||
ETHERPAD: 'etherpad'
|
||||
};
|
||||
|
||||
/**
|
||||
* Open Connection. When authentication failed it shows auth dialog.
|
||||
* @param roomName the room name to use
|
||||
* @returns Promise<JitsiConnection>
|
||||
*/
|
||||
function connect(roomName) {
|
||||
return openConnection({
|
||||
retry: true,
|
||||
roomName
|
||||
})
|
||||
.catch(err => {
|
||||
if (err === JitsiConnectionErrors.PASSWORD_REQUIRED) {
|
||||
APP.UI.notifyTokenAuthFailed();
|
||||
} else {
|
||||
APP.UI.notifyConnectionFailed(err);
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Share data to other users.
|
||||
* @param command the command
|
||||
@@ -326,63 +286,25 @@ class ConferenceConnector {
|
||||
break;
|
||||
}
|
||||
|
||||
// not enough rights to create conference
|
||||
case JitsiConferenceErrors.AUTHENTICATION_REQUIRED: {
|
||||
|
||||
const replaceParticipant = getReplaceParticipant(APP.store.getState());
|
||||
|
||||
// Schedule reconnect to check if someone else created the room.
|
||||
this.reconnectTimeout = setTimeout(() => {
|
||||
APP.store.dispatch(conferenceWillJoin(room));
|
||||
room.join(null, replaceParticipant);
|
||||
}, 5000);
|
||||
|
||||
const { password }
|
||||
= APP.store.getState()['features/base/conference'];
|
||||
|
||||
AuthHandler.requireAuth(room, password);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case JitsiConferenceErrors.RESERVATION_ERROR: {
|
||||
const [ code, msg ] = params;
|
||||
|
||||
APP.UI.notifyReservationError(code, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
case JitsiConferenceErrors.REDIRECTED: {
|
||||
const newConfig = getVisitorOptions(APP.store.getState(), params);
|
||||
|
||||
if (!newConfig) {
|
||||
logger.warn('Not redirected missing params');
|
||||
break;
|
||||
}
|
||||
|
||||
const [ vnode ] = params;
|
||||
|
||||
APP.store.dispatch(overwriteConfig(newConfig))
|
||||
.then(() => this._conference.leaveRoom())
|
||||
.then(() => APP.store.dispatch(setIAmVisitor(Boolean(vnode))))
|
||||
|
||||
// we do not clear local tracks on error, so we need to manually clear them
|
||||
.then(() => APP.store.dispatch(destroyLocalTracks()))
|
||||
.then(() => {
|
||||
// Reset VideoLayout. It's destroyed in features/video-layout/middleware.web.js so re-initialize it.
|
||||
VideoLayout.initLargeVideo();
|
||||
VideoLayout.resizeVideoArea();
|
||||
|
||||
connect(this._conference.roomName).then(con => {
|
||||
this._conference.startConference(con, []);
|
||||
});
|
||||
});
|
||||
|
||||
APP.store.dispatch(showErrorNotification({
|
||||
descriptionArguments: {
|
||||
code,
|
||||
msg
|
||||
},
|
||||
descriptionKey: 'dialog.reservationErrorMsg',
|
||||
titleKey: 'dialog.reservationError'
|
||||
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
|
||||
break;
|
||||
}
|
||||
|
||||
case JitsiConferenceErrors.GRACEFUL_SHUTDOWN:
|
||||
APP.UI.notifyGracefulShutdown();
|
||||
APP.store.dispatch(showErrorNotification({
|
||||
descriptionKey: 'dialog.gracefulShutdown',
|
||||
titleKey: 'dialog.serviceUnavailable'
|
||||
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
|
||||
break;
|
||||
|
||||
// FIXME FOCUS_DISCONNECTED is a confusing event name.
|
||||
@@ -408,31 +330,9 @@ class ConferenceConnector {
|
||||
// FIXME the conference should be stopped by the library and not by
|
||||
// the app. Both the errors above are unrecoverable from the library
|
||||
// perspective.
|
||||
room.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR).then(() => connection.disconnect());
|
||||
room.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR).then(() => APP.connection.disconnect());
|
||||
break;
|
||||
|
||||
case JitsiConferenceErrors.CONFERENCE_MAX_USERS: {
|
||||
APP.UI.notifyMaxUsersLimitReached();
|
||||
|
||||
// in case of max users(it can be from a visitor node), let's restore
|
||||
// oldConfig if any as we will be back to the main prosody
|
||||
const newConfig = restoreConferenceOptions(APP.store.getState());
|
||||
|
||||
if (newConfig) {
|
||||
APP.store.dispatch(overwriteConfig(newConfig))
|
||||
.then(() => this._conference.leaveRoom())
|
||||
.then(() => {
|
||||
_connectionPromise = connect(this._conference.roomName);
|
||||
|
||||
return _connectionPromise;
|
||||
})
|
||||
.then(con => {
|
||||
APP.connection = connection = con;
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case JitsiConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS:
|
||||
APP.store.dispatch(reloadWithStoredParams());
|
||||
break;
|
||||
@@ -488,11 +388,11 @@ function disconnect() {
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
if (!connection) {
|
||||
if (!APP.connection) {
|
||||
return onDisconnected();
|
||||
}
|
||||
|
||||
return connection.disconnect().then(onDisconnected, onDisconnected);
|
||||
return APP.connection.disconnect().then(onDisconnected, onDisconnected);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -504,31 +404,18 @@ function disconnect() {
|
||||
* @returns {void}
|
||||
*/
|
||||
function setGUMPendingStateOnFailedTracks(tracks) {
|
||||
const tracksTypes = tracks.map(track => track.getType());
|
||||
const tracksTypes = tracks.map(track => {
|
||||
if (track.getVideoType() === VIDEO_TYPE.DESKTOP) {
|
||||
return MEDIA_TYPE.SCREENSHARE;
|
||||
}
|
||||
|
||||
return track.getType();
|
||||
});
|
||||
const nonPendingTracks = [ MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO ].filter(type => !tracksTypes.includes(type));
|
||||
|
||||
APP.store.dispatch(gumPending(nonPendingTracks, IGUMPendingState.NONE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles CONNECTION_FAILED events from lib-jitsi-meet.
|
||||
*
|
||||
* @param {JitsiConnectionError} error - The reported error.
|
||||
* @returns {void}
|
||||
* @private
|
||||
*/
|
||||
function _connectionFailedHandler(error) {
|
||||
if (isFatalJitsiConnectionError(error)) {
|
||||
APP.connection.removeEventListener(
|
||||
JitsiConnectionEvents.CONNECTION_FAILED,
|
||||
_connectionFailedHandler);
|
||||
if (room) {
|
||||
APP.store.dispatch(conferenceWillLeave(room));
|
||||
room.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Flag used to delay modification of the muted status of local media tracks
|
||||
@@ -547,7 +434,16 @@ export default {
|
||||
/**
|
||||
* Returns an object containing a promise which resolves with the created tracks &
|
||||
* the errors resulting from that process.
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {boolean} options.startAudioOnly=false - if <tt>true</tt> then
|
||||
* only audio track will be created and the audio only mode will be turned
|
||||
* on.
|
||||
* @param {boolean} options.startScreenSharing=false - if <tt>true</tt>
|
||||
* should start with screensharing instead of camera video.
|
||||
* @param {boolean} options.startWithAudioMuted - will start the conference
|
||||
* without any audio tracks.
|
||||
* @param {boolean} options.startWithVideoMuted - will start the conference
|
||||
* without any video tracks.
|
||||
* @returns {Promise<JitsiLocalTrack[]>, Object}
|
||||
*/
|
||||
createInitialLocalTracks(options = {}) {
|
||||
@@ -555,7 +451,7 @@ export default {
|
||||
|
||||
// Always get a handle on the audio input device so that we have statistics (such as "No audio input" or
|
||||
// "Are you trying to speak?" ) even if the user joins the conference muted.
|
||||
const initialDevices = config.disableInitialGUM ? [] : [ MEDIA_TYPE.AUDIO ];
|
||||
const initialDevices = config.startSilent || config.disableInitialGUM ? [] : [ MEDIA_TYPE.AUDIO ];
|
||||
const requestedAudio = !config.disableInitialGUM;
|
||||
let requestedVideo = false;
|
||||
|
||||
@@ -725,37 +621,7 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates local media tracks and connects to a room. Will show error
|
||||
* dialogs in case accessing the local microphone and/or camera failed. Will
|
||||
* show guidance overlay for users on how to give access to camera and/or
|
||||
* microphone.
|
||||
* @param {string} roomName
|
||||
* @param {object} options
|
||||
* @param {boolean} options.startAudioOnly=false - if <tt>true</tt> then
|
||||
* only audio track will be created and the audio only mode will be turned
|
||||
* on.
|
||||
* @param {boolean} options.startScreenSharing=false - if <tt>true</tt>
|
||||
* should start with screensharing instead of camera video.
|
||||
* @param {boolean} options.startWithAudioMuted - will start the conference
|
||||
* without any audio tracks.
|
||||
* @param {boolean} options.startWithVideoMuted - will start the conference
|
||||
* without any video tracks.
|
||||
* @returns {Promise.<JitsiLocalTrack[], JitsiConnection>}
|
||||
*/
|
||||
createInitialLocalTracksAndConnect(roomName, options = {}) {
|
||||
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(options);
|
||||
|
||||
return Promise.all([ tryCreateLocalTracks, connect(roomName) ])
|
||||
.then(([ tracks, con ]) => {
|
||||
|
||||
this._displayErrorsForCreateInitialLocalTracks(errors);
|
||||
|
||||
return [ tracks, con ];
|
||||
});
|
||||
},
|
||||
|
||||
startConference(con, tracks) {
|
||||
startConference(tracks) {
|
||||
tracks.forEach(track => {
|
||||
if ((track.isAudioTrack() && this.isLocalAudioMuted())
|
||||
|| (track.isVideoTrack() && this.isLocalVideoMuted())) {
|
||||
@@ -768,9 +634,6 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
con.addEventListener(JitsiConnectionEvents.CONNECTION_FAILED, _connectionFailedHandler);
|
||||
APP.connection = connection = con;
|
||||
|
||||
this._createRoom(tracks);
|
||||
|
||||
// if user didn't give access to mic or camera or doesn't have
|
||||
@@ -778,7 +641,7 @@ export default {
|
||||
// so that the user can try unmute later on and add audio/video
|
||||
// to the conference
|
||||
if (!tracks.find(t => t.isAudioTrack())) {
|
||||
this.setAudioMuteStatus(true);
|
||||
this.updateAudioIconEnabled();
|
||||
}
|
||||
|
||||
if (!tracks.find(t => t.isVideoTrack())) {
|
||||
@@ -821,6 +684,8 @@ export default {
|
||||
startWithVideoMuted: getStartWithVideoMuted(state) || isUserInteractionRequiredForUnmute(state)
|
||||
};
|
||||
|
||||
logger.debug(`Executed conference.init with roomName: ${roomName}`);
|
||||
|
||||
this.roomName = roomName;
|
||||
|
||||
try {
|
||||
@@ -839,10 +704,6 @@ export default {
|
||||
const handleInitialTracks = (options, tracks) => {
|
||||
let localTracks = tracks;
|
||||
|
||||
// No local tracks are added when user joins as a visitor.
|
||||
if (iAmVisitor(state)) {
|
||||
return [];
|
||||
}
|
||||
if (options.startWithAudioMuted || room?.isStartAudioMuted()) {
|
||||
// Always add the track on Safari because of a known issue where audio playout doesn't happen
|
||||
// if the user joins audio and video muted, i.e., if there is no local media capture.
|
||||
@@ -860,19 +721,6 @@ export default {
|
||||
};
|
||||
|
||||
if (isPrejoinPageVisible(state)) {
|
||||
_connectionPromise = connect(roomName).then(c => {
|
||||
// We want to initialize it early, in case of errors to be able to gather logs.
|
||||
APP.connection = c;
|
||||
|
||||
return c;
|
||||
});
|
||||
|
||||
if (_onConnectionPromiseCreated) {
|
||||
_onConnectionPromiseCreated();
|
||||
}
|
||||
|
||||
APP.store.dispatch(makePrecallTest(this._getConferenceOptions()));
|
||||
|
||||
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(initialOptions);
|
||||
const localTracks = await tryCreateLocalTracks;
|
||||
|
||||
@@ -897,41 +745,26 @@ export default {
|
||||
return this._setLocalAudioVideoStreams(tracks);
|
||||
}
|
||||
|
||||
const [ tracks, con ] = await this.createInitialLocalTracksAndConnect(roomName, initialOptions);
|
||||
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(initialOptions);
|
||||
|
||||
this._initDeviceList(true);
|
||||
return Promise.all([
|
||||
tryCreateLocalTracks.then(tr => {
|
||||
this._displayErrorsForCreateInitialLocalTracks(errors);
|
||||
|
||||
const filteredTracks = handleInitialTracks(initialOptions, tracks);
|
||||
return tr;
|
||||
}).then(tr => {
|
||||
this._initDeviceList(true);
|
||||
|
||||
setGUMPendingStateOnFailedTracks(filteredTracks);
|
||||
const filteredTracks = handleInitialTracks(initialOptions, tr);
|
||||
|
||||
return this.startConference(con, filteredTracks);
|
||||
},
|
||||
setGUMPendingStateOnFailedTracks(filteredTracks);
|
||||
|
||||
/**
|
||||
* Joins conference after the tracks have been configured in the prejoin screen.
|
||||
*
|
||||
* @param {Object[]} tracks - An array with the configured tracks
|
||||
* @returns {void}
|
||||
*/
|
||||
async prejoinStart(tracks) {
|
||||
if (!_connectionPromise) {
|
||||
// The conference object isn't initialized yet. Wait for the promise to initialise.
|
||||
await new Promise(resolve => {
|
||||
_onConnectionPromiseCreated = resolve;
|
||||
});
|
||||
_onConnectionPromiseCreated = undefined;
|
||||
}
|
||||
|
||||
let con;
|
||||
|
||||
try {
|
||||
con = await _connectionPromise;
|
||||
this.startConference(con, tracks);
|
||||
} catch (error) {
|
||||
logger.error(`An error occurred while trying to join a meeting from the prejoin screen: ${error}`);
|
||||
APP.store.dispatch(setJoiningInProgress(false));
|
||||
}
|
||||
return filteredTracks;
|
||||
}),
|
||||
APP.store.dispatch(connect())
|
||||
]).then(([ tracks, _ ]) => {
|
||||
this.startConference(tracks).catch(logger.error);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1013,7 +846,7 @@ export default {
|
||||
// This will only modify base/media.audio.muted which is then synced
|
||||
// up with the track at the end of local tracks initialization.
|
||||
muteLocalAudio(mute);
|
||||
this.setAudioMuteStatus(mute);
|
||||
this.updateAudioIconEnabled();
|
||||
|
||||
return;
|
||||
} else if (this.isLocalAudioMuted() === mute) {
|
||||
@@ -1207,17 +1040,6 @@ export default {
|
||||
.filter(p => !p.isHidden() || !(config.iAmRecorder && p.isHiddenFromRecorder())).length + 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the callstats integration is enabled, otherwise returns
|
||||
* false.
|
||||
*
|
||||
* @returns true if the callstats integration is enabled, otherwise returns
|
||||
* false.
|
||||
*/
|
||||
isCallstatsEnabled() {
|
||||
return room && room.isCallstatsEnabled();
|
||||
},
|
||||
|
||||
/**
|
||||
* Get speaker stats that track total dominant speaker time.
|
||||
*
|
||||
@@ -1229,13 +1051,6 @@ export default {
|
||||
return room.getSpeakerStats();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the connection times stored in the library.
|
||||
*/
|
||||
getConnectionTimes() {
|
||||
return room.getConnectionTimes();
|
||||
},
|
||||
|
||||
// used by torture currently
|
||||
isJoined() {
|
||||
return room && room.isJoined();
|
||||
@@ -1413,9 +1228,7 @@ export default {
|
||||
* Used by the Breakout Rooms feature to join a breakout room or go back to the main room.
|
||||
*/
|
||||
async joinRoom(roomName, options) {
|
||||
// Reset VideoLayout. It's destroyed in features/video-layout/middleware.web.js so re-initialize it.
|
||||
VideoLayout.initLargeVideo();
|
||||
VideoLayout.resizeVideoArea();
|
||||
APP.store.dispatch(conferenceWillInit());
|
||||
|
||||
// Restore initial state.
|
||||
this._localTracksInitialized = false;
|
||||
@@ -1440,10 +1253,27 @@ export default {
|
||||
},
|
||||
|
||||
_createRoom(localTracks) {
|
||||
room = connection.initJitsiConference(APP.conference.roomName, this._getConferenceOptions());
|
||||
room = APP.connection.initJitsiConference(APP.conference.roomName, this._getConferenceOptions());
|
||||
|
||||
// Filter out the tracks that are muted (except on Safari).
|
||||
const tracks = browser.isWebKitBased() ? localTracks : localTracks.filter(track => !track.isMuted());
|
||||
let tracks = localTracks;
|
||||
|
||||
if (!browser.isWebKitBased()) {
|
||||
const mutedTrackTypes = [];
|
||||
|
||||
tracks = localTracks.filter(track => {
|
||||
if (!track.isMuted()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (track.getVideoType() !== VIDEO_TYPE.DESKTOP) {
|
||||
mutedTrackTypes.push(track.getType());
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
APP.store.dispatch(gumPending(mutedTrackTypes, IGUMPendingState.NONE));
|
||||
}
|
||||
|
||||
this._setLocalAudioVideoStreams(tracks);
|
||||
this._room = room; // FIXME do not use this
|
||||
@@ -1564,7 +1394,7 @@ export default {
|
||||
APP.store.dispatch(
|
||||
replaceLocalTrack(oldTrack, newTrack, room))
|
||||
.then(() => {
|
||||
this.setAudioMuteStatus(this.isLocalAudioMuted());
|
||||
this.updateAudioIconEnabled();
|
||||
})
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
@@ -1787,10 +1617,10 @@ export default {
|
||||
titleKey = 'notify.screenShareNoAudioTitle';
|
||||
}
|
||||
|
||||
APP.UI.messageHandler.showError({
|
||||
APP.store.dispatch(showErrorNotification({
|
||||
descriptionKey,
|
||||
titleKey
|
||||
});
|
||||
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1821,10 +1651,14 @@ export default {
|
||||
APP.store.dispatch(conferenceUniqueIdSet(room, ...args));
|
||||
});
|
||||
|
||||
room.on(
|
||||
JitsiConferenceEvents.AUTH_STATUS_CHANGED,
|
||||
(authEnabled, authLogin) =>
|
||||
APP.store.dispatch(authStatusChanged(authEnabled, authLogin)));
|
||||
// we want to ignore this event in case of tokenAuthUrl config
|
||||
// we are deprecating this and at some point will get rid of it
|
||||
if (!config.tokenAuthUrl) {
|
||||
room.on(
|
||||
JitsiConferenceEvents.AUTH_STATUS_CHANGED,
|
||||
(authEnabled, authLogin) =>
|
||||
APP.store.dispatch(authStatusChanged(authEnabled, authLogin)));
|
||||
}
|
||||
|
||||
room.on(JitsiConferenceEvents.PARTCIPANT_FEATURES_CHANGED, user => {
|
||||
APP.store.dispatch(updateRemoteParticipantFeatures(user));
|
||||
@@ -2010,28 +1844,24 @@ export default {
|
||||
|
||||
room.on(
|
||||
JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
|
||||
(...args) => {
|
||||
APP.store.dispatch(endpointMessageReceived(...args));
|
||||
if (args && args.length >= 2) {
|
||||
const [ sender, eventData ] = args;
|
||||
|
||||
if (eventData.name === ENDPOINT_TEXT_MESSAGE_NAME) {
|
||||
APP.API.notifyEndpointTextMessageReceived({
|
||||
senderInfo: {
|
||||
jid: sender._jid,
|
||||
id: sender._id
|
||||
},
|
||||
eventData
|
||||
});
|
||||
}
|
||||
(participant, data) => {
|
||||
APP.store.dispatch(endpointMessageReceived(participant, data));
|
||||
if (data?.name === ENDPOINT_TEXT_MESSAGE_NAME) {
|
||||
APP.API.notifyEndpointTextMessageReceived({
|
||||
senderInfo: {
|
||||
jid: participant.getJid(),
|
||||
id: participant.getId()
|
||||
},
|
||||
eventData: data
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
room.on(
|
||||
JitsiConferenceEvents.NON_PARTICIPANT_MESSAGE_RECEIVED,
|
||||
(...args) => {
|
||||
APP.store.dispatch(nonParticipantMessageReceived(...args));
|
||||
APP.API.notifyNonParticipantMessageReceived(...args);
|
||||
(id, data) => {
|
||||
APP.store.dispatch(nonParticipantMessageReceived(id, data));
|
||||
APP.API.notifyNonParticipantMessageReceived(id, data);
|
||||
});
|
||||
|
||||
room.on(
|
||||
@@ -2184,21 +2014,6 @@ export default {
|
||||
this.hangup(true);
|
||||
});
|
||||
|
||||
// logout
|
||||
APP.UI.addListener(UIEvents.LOGOUT, () => {
|
||||
AuthHandler.logout(room).then(url => {
|
||||
if (url) {
|
||||
UIUtil.redirect(url);
|
||||
} else {
|
||||
this.hangup(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
APP.UI.addListener(UIEvents.AUTH_CLICKED, () => {
|
||||
AuthHandler.authenticate(room);
|
||||
});
|
||||
|
||||
APP.UI.addListener(
|
||||
UIEvents.VIDEO_DEVICE_CHANGED,
|
||||
cameraDeviceId => {
|
||||
@@ -2230,10 +2045,6 @@ export default {
|
||||
|
||||
return this.useVideoStream(stream);
|
||||
})
|
||||
.then(() => {
|
||||
logger.info(`Switched local video device to ${cameraDeviceId}.`);
|
||||
this._updateVideoDeviceId();
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error(`Failed to switch to selected camera:${cameraDeviceId}, error:${error}`);
|
||||
|
||||
@@ -2288,8 +2099,6 @@ export default {
|
||||
// above mentioned chrome bug.
|
||||
localAudio._realDeviceId = localAudio.deviceId = 'default';
|
||||
}
|
||||
logger.info(`switched local audio input device to: ${selectedDeviceId}`);
|
||||
this._updateAudioDeviceId();
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error(`Failed to switch to selected audio input device ${selectedDeviceId}, error=${err}`);
|
||||
@@ -2374,13 +2183,6 @@ export default {
|
||||
|
||||
return dispatch(getAvailableDevices())
|
||||
.then(devices => {
|
||||
// Ugly way to synchronize real device IDs with local
|
||||
// storage and settings menu. This is a workaround until
|
||||
// getConstraints() method will be implemented in browsers.
|
||||
this._updateAudioDeviceId();
|
||||
|
||||
this._updateVideoDeviceId();
|
||||
|
||||
APP.UI.onAvailableDevicesChanged(devices);
|
||||
});
|
||||
}
|
||||
@@ -2388,36 +2190,6 @@ export default {
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the settings for the currently used video device, extracting
|
||||
* the device id from the used track.
|
||||
* @private
|
||||
*/
|
||||
_updateVideoDeviceId() {
|
||||
const localVideo = getLocalJitsiVideoTrack(APP.store.getState());
|
||||
|
||||
if (localVideo && localVideo.videoType === 'camera') {
|
||||
APP.store.dispatch(updateSettings({
|
||||
cameraDeviceId: localVideo.getDeviceId()
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the settings for the currently used audio device, extracting
|
||||
* the device id from the used track.
|
||||
* @private
|
||||
*/
|
||||
_updateAudioDeviceId() {
|
||||
const localAudio = getLocalJitsiAudioTrack(APP.store.getState());
|
||||
|
||||
if (localAudio) {
|
||||
APP.store.dispatch(updateSettings({
|
||||
micDeviceId: localAudio.getDeviceId()
|
||||
}));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Event listener for JitsiMediaDevicesEvents.DEVICE_LIST_CHANGED to
|
||||
* handle change of available media devices.
|
||||
@@ -2426,19 +2198,28 @@ export default {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async _onDeviceListChanged(devices) {
|
||||
const oldDevices = APP.store.getState()['features/base/devices'].availableDevices;
|
||||
const localAudio = getLocalJitsiAudioTrack(APP.store.getState());
|
||||
const localVideo = getLocalJitsiVideoTrack(APP.store.getState());
|
||||
const state = APP.store.getState();
|
||||
const { filteredDevices, ignoredDevices } = filterIgnoredDevices(devices);
|
||||
const oldDevices = state['features/base/devices'].availableDevices;
|
||||
|
||||
APP.store.dispatch(updateDeviceList(devices));
|
||||
if (!areDevicesDifferent(flattenAvailableDevices(oldDevices), filteredDevices)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
logDevices(ignoredDevices, 'Ignored devices on device list changed:');
|
||||
|
||||
const localAudio = getLocalJitsiAudioTrack(state);
|
||||
const localVideo = getLocalJitsiVideoTrack(state);
|
||||
|
||||
APP.store.dispatch(updateDeviceList(filteredDevices));
|
||||
|
||||
// Firefox users can choose their preferred device in the gUM prompt. In that case
|
||||
// we should respect that and not attempt to switch to the preferred device from
|
||||
// our settings.
|
||||
const newLabelsOnly = mediaDeviceHelper.newDeviceListAddedLabelsOnly(oldDevices, devices);
|
||||
const newLabelsOnly = mediaDeviceHelper.newDeviceListAddedLabelsOnly(oldDevices, filteredDevices);
|
||||
const newDevices
|
||||
= mediaDeviceHelper.getNewMediaDevicesAfterDeviceListChanged(
|
||||
devices,
|
||||
filteredDevices,
|
||||
localVideo,
|
||||
localAudio,
|
||||
newLabelsOnly);
|
||||
@@ -2557,21 +2338,17 @@ export default {
|
||||
this.useAudioStream(track)
|
||||
.then(() => {
|
||||
hasDefaultMicChanged && (track._realDeviceId = track.deviceId = 'default');
|
||||
this._updateAudioDeviceId();
|
||||
}));
|
||||
} else {
|
||||
promises.push(
|
||||
this.useVideoStream(track)
|
||||
.then(() => {
|
||||
this._updateVideoDeviceId();
|
||||
}));
|
||||
this.useVideoStream(track));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(() => {
|
||||
APP.UI.onAvailableDevicesChanged(devices);
|
||||
APP.UI.onAvailableDevicesChanged(filteredDevices);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -2614,9 +2391,10 @@ export default {
|
||||
/**
|
||||
* Disconnect from the conference and optionally request user feedback.
|
||||
* @param {boolean} [requestFeedback=false] if user feedback should be
|
||||
* @param {string} [hangupReason] the reason for leaving the meeting
|
||||
* requested
|
||||
*/
|
||||
hangup(requestFeedback = false) {
|
||||
hangup(requestFeedback = false, hangupReason) {
|
||||
APP.store.dispatch(disableReceiver());
|
||||
|
||||
this._stopProxyConnection();
|
||||
@@ -2633,36 +2411,42 @@ export default {
|
||||
|
||||
APP.UI.removeAllListeners();
|
||||
|
||||
let requestFeedbackPromise;
|
||||
let feedbackResultPromise = Promise.resolve({});
|
||||
|
||||
if (requestFeedback) {
|
||||
requestFeedbackPromise
|
||||
= APP.store.dispatch(maybeOpenFeedbackDialog(room))
|
||||
const feedbackDialogClosed = (feedbackResult = {}) => {
|
||||
if (!feedbackResult.wasDialogShown && hangupReason) {
|
||||
return APP.store.dispatch(
|
||||
openLeaveReasonDialog(hangupReason)).then(() => feedbackResult);
|
||||
}
|
||||
|
||||
// false because the thank you dialog shouldn't be displayed
|
||||
.catch(() => Promise.resolve(false));
|
||||
} else {
|
||||
requestFeedbackPromise = Promise.resolve(true);
|
||||
return Promise.resolve(feedbackResult);
|
||||
};
|
||||
|
||||
feedbackResultPromise
|
||||
= APP.store.dispatch(maybeOpenFeedbackDialog(room, hangupReason))
|
||||
.then(feedbackDialogClosed, feedbackDialogClosed);
|
||||
}
|
||||
|
||||
Promise.all([
|
||||
requestFeedbackPromise,
|
||||
this.leaveRoom()
|
||||
])
|
||||
.then(values => {
|
||||
const leavePromise = this.leaveRoom().catch(() => Promise.resolve());
|
||||
|
||||
Promise.allSettled([ feedbackResultPromise, leavePromise ]).then(([ feedback, _ ]) => {
|
||||
this._room = undefined;
|
||||
room = undefined;
|
||||
|
||||
/**
|
||||
* Don't call {@code notifyReadyToClose} if the promotional page flag is set
|
||||
* and let the page take care of sending the message, since there will be
|
||||
* a redirect to the page regardlessly.
|
||||
* a redirect to the page anyway.
|
||||
*/
|
||||
if (!interfaceConfig.SHOW_PROMOTIONAL_CLOSE_PAGE) {
|
||||
APP.API.notifyReadyToClose();
|
||||
}
|
||||
APP.store.dispatch(maybeRedirectToWelcomePage(values[0]));
|
||||
|
||||
APP.store.dispatch(maybeRedirectToWelcomePage(feedback.value ?? {}));
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -2672,7 +2456,7 @@ export default {
|
||||
* @param {string} reason - reason for leaving the room.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async leaveRoom(doDisconnect = true, reason = '') {
|
||||
leaveRoom(doDisconnect = true, reason = '') {
|
||||
APP.store.dispatch(conferenceWillLeave(room));
|
||||
|
||||
const maybeDisconnect = () => {
|
||||
@@ -2849,15 +2633,6 @@ export default {
|
||||
APP.UI.setVideoMuted(this.getMyUserId());
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the audio muted status.
|
||||
*
|
||||
* @param {boolean} muted - New muted status.
|
||||
*/
|
||||
setAudioMuteStatus(muted) {
|
||||
APP.UI.setAudioMuted(this.getMyUserId(), muted);
|
||||
},
|
||||
|
||||
/**
|
||||
* Dispatches the passed in feedback for submission. The submitted score
|
||||
* should be a number inclusively between 1 through 5, or -1 for no score.
|
||||
|
||||
388
config.js
388
config.js
@@ -51,6 +51,9 @@ var config = {
|
||||
// Websocket URL (XMPP)
|
||||
// websocket: 'wss://jitsi-meet.example.com/' + subdir + 'xmpp-websocket',
|
||||
|
||||
// Whether BOSH should be preferred over WebSocket if both are configured.
|
||||
// preferBosh: false,
|
||||
|
||||
// The real JID of focus participant - can be overridden here
|
||||
// Do not change username - FIXME: Make focus username configurable
|
||||
// https://github.com/jitsi/jitsi-meet/issues/7376
|
||||
@@ -81,6 +84,9 @@ var config = {
|
||||
// issues related to insertable streams.
|
||||
// disableE2EE: false,
|
||||
|
||||
// Enables supports for AV1 codec.
|
||||
// enableAv1Support: false,
|
||||
|
||||
// Enables XMPP WebSocket (as opposed to BOSH) for the given amount of users.
|
||||
// mobileXmppWsThreshold: 10, // enable XMPP WebSockets on mobile for 10% of the users
|
||||
|
||||
@@ -95,10 +101,11 @@ var config = {
|
||||
// This is useful when the client runs on a host with limited resources.
|
||||
// noAutoPlayVideo: false,
|
||||
|
||||
// Enable callstats only for a percentage of users.
|
||||
// This takes a value between 0 and 100 which determines the probability for
|
||||
// the callstats to be enabled.
|
||||
// callStatsThreshold: 5, // enable callstats for 5% of the users.
|
||||
// Experiment: Whether to skip interim transcriptions.
|
||||
// skipInterimTranscriptions: false,
|
||||
|
||||
// Dump transcripts to a <transcript> element for debugging.
|
||||
// dumpTranscript: false,
|
||||
},
|
||||
|
||||
// Disables moderator indicators.
|
||||
@@ -215,6 +222,9 @@ var config = {
|
||||
|
||||
// Video
|
||||
|
||||
// Sets the default camera facing mode.
|
||||
// cameraFacingMode: 'user',
|
||||
|
||||
// Sets the preferred resolution (height) for local video. Defaults to 720.
|
||||
// resolution: 720,
|
||||
|
||||
@@ -288,12 +298,19 @@ var config = {
|
||||
// max: 5,
|
||||
// },
|
||||
|
||||
// This option has been deprecated since it is no longer supported as per the w3c spec.
|
||||
// https://w3c.github.io/mediacapture-screen-share/#dom-mediadevices-getdisplaymedia. If the user has not
|
||||
// interacted with the webpage before the getDisplayMedia call, the promise will be rejected by the browser. This
|
||||
// has already been implemented in Firefox and Safari and will be implemented in Chrome soon.
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1198918
|
||||
// startScreenSharing: false,
|
||||
// Optional screenshare settings that give more control over screen capture in the browser.
|
||||
// screenShareSettings: {
|
||||
// // Show users the current tab is the preferred capture source, default: false.
|
||||
// desktopPreferCurrentTab: false,
|
||||
// // Allow users to select system audio, default: include.
|
||||
// desktopSystemAudio: 'include',
|
||||
// // Allow users to seamlessly switch which tab they are sharing without having to select the tab again.
|
||||
// desktopSurfaceSwitching: 'include',
|
||||
// // Allow a user to be shown a preference for what screen is to be captured, default: unset.
|
||||
// desktopDisplaySurface: undefined,
|
||||
// // Allow users to select the current tab as a capture source, default: exclude.
|
||||
// desktopSelfBrowserSurface: 'exclude'
|
||||
// },
|
||||
|
||||
// Recording
|
||||
|
||||
@@ -310,6 +327,18 @@ var config = {
|
||||
// 'https://jitsi-meet.example.com/subfolder/static/oauth.html',
|
||||
// },
|
||||
|
||||
// configuration for all things recording related. Existing settings will be migrated here in the future.
|
||||
// recordings: {
|
||||
// // IF true (default) recording audio and video is selected by default in the recording dialog.
|
||||
// // recordAudioAndVideo: true,
|
||||
// // If true, shows a notification at the start of the meeting with a call to action button
|
||||
// // to start recording (for users who can do so).
|
||||
// // suggestRecording: true,
|
||||
// // If true, shows a warning label in the prejoin screen to point out the possibility that
|
||||
// // the call you're joining might be recorded.
|
||||
// // showPrejoinWarning: true,
|
||||
// },
|
||||
|
||||
// recordingService: {
|
||||
// // When integrations like dropbox are enabled only that will be shown,
|
||||
// // by enabling fileRecordingsServiceEnabled, we show both the integrations
|
||||
@@ -370,7 +399,7 @@ var config = {
|
||||
// DEPRECATED. Use transcription.preferredLanguage instead.
|
||||
// preferredTranscribeLanguage: 'en-US',
|
||||
|
||||
// DEPRECATED. Use transcription.autoCaptionOnRecord instead.
|
||||
// DEPRECATED. Use transcription.autoTranscribeOnRecord instead.
|
||||
// autoCaptionOnRecord: false,
|
||||
|
||||
// Transcription options.
|
||||
@@ -399,11 +428,8 @@ var config = {
|
||||
// // ./src/react/features/transcribing/transcriber-langs.json.
|
||||
// preferredLanguage: 'en-US',
|
||||
|
||||
// // Disable start transcription for all participants.
|
||||
// disableStartForAll: false,
|
||||
|
||||
// // Enables automatic turning on captions when recording is started
|
||||
// autoCaptionOnRecord: false,
|
||||
// // Enables automatic turning on transcribing when recording is started
|
||||
// autoTranscribeOnRecord: false,
|
||||
// },
|
||||
|
||||
// Misc
|
||||
@@ -427,26 +453,53 @@ var config = {
|
||||
|
||||
// Specify the settings for video quality optimizations on the client.
|
||||
// videoQuality: {
|
||||
// // Provides a way to prevent a video codec from being negotiated on the JVB connection. The codec specified
|
||||
// // here will be removed from the list of codecs present in the SDP answer generated by the client. If the
|
||||
// // same codec is specified for both the disabled and preferred option, the disable settings will prevail.
|
||||
// // Note that 'VP8' cannot be disabled since it's a mandatory codec, the setting will be ignored in this case.
|
||||
// disabledCodec: 'H264',
|
||||
//
|
||||
// // Provides a way to set a preferred video codec for the JVB connection. If 'H264' is specified here,
|
||||
// // simulcast will be automatically disabled since JVB doesn't support H264 simulcast yet. This will only
|
||||
// // rearrange the the preference order of the codecs in the SDP answer generated by the browser only if the
|
||||
// // preferred codec specified here is present. Please ensure that the JVB offers the specified codec for this
|
||||
// // to take effect.
|
||||
// preferredCodec: 'VP8',
|
||||
// // Provides a way to set the codec preference on desktop based endpoints.
|
||||
// codecPreferenceOrder: [ 'VP9', 'VP8', 'H264' ],
|
||||
//
|
||||
// // Provides a way to enforce the preferred codec for the conference even when the conference has endpoints
|
||||
// // that do not support the preferred codec. For example, older versions of Safari do not support VP9 yet.
|
||||
// // This will result in Safari not being able to decode video from endpoints sending VP9 video.
|
||||
// // When set to false, the conference falls back to VP8 whenever there is an endpoint that doesn't support the
|
||||
// // preferred codec and goes back to the preferred codec when that endpoint leaves.
|
||||
// enforcePreferredCodec: false,
|
||||
// // Codec specific settings for scalability modes and max bitrates.
|
||||
// av1: {
|
||||
// maxBitratesVideo: {
|
||||
// low: 100000,
|
||||
// standard: 300000,
|
||||
// high: 1000000,
|
||||
// ssHigh: 2500000
|
||||
// },
|
||||
// scalabilityModeEnabled: true,
|
||||
// useSimulcast: false,
|
||||
// useKSVC: true
|
||||
// },
|
||||
// h264: {
|
||||
// maxBitratesVideo: {
|
||||
// low: 200000,
|
||||
// standard: 500000,
|
||||
// high: 1500000,
|
||||
// ssHigh: 2500000
|
||||
// },
|
||||
// scalabilityModeEnabled: true
|
||||
// },
|
||||
// vp8: {
|
||||
// maxBitratesVideo: {
|
||||
// low: 200000,
|
||||
// standard: 500000,
|
||||
// high: 1500000,
|
||||
// ssHigh: 2500000
|
||||
// },
|
||||
// scalabilityModeEnabled: false
|
||||
// },
|
||||
// vp9: {
|
||||
// maxBitratesVideo: {
|
||||
// low: 100000,
|
||||
// standard: 300000,
|
||||
// high: 1200000,
|
||||
// ssHigh: 2500000
|
||||
// },
|
||||
// scalabilityModeEnabled: true,
|
||||
// useSimulcast: false,
|
||||
// useKSVC: true
|
||||
// }
|
||||
//
|
||||
// DEPRECATED! Use `codec specific settings` instead.
|
||||
// // Provides a way to configure the maximum bitrates that will be enforced on the simulcast streams for
|
||||
// // video tracks. The keys in the object represent the type of the stream (LD, SD or HD) and the values
|
||||
// // are the max.bitrates to be set on that particular type of stream. The actual send may vary based on
|
||||
@@ -485,6 +538,24 @@ var config = {
|
||||
// 720: 'high',
|
||||
// },
|
||||
//
|
||||
// // Provides a way to set the codec preference on mobile devices, both on RN and mobile browser based endpoint
|
||||
// mobileCodecPreferenceOrder: [ 'VP8', 'VP9', 'H264' ],
|
||||
//
|
||||
// // DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
|
||||
// // Provides a way to prevent a video codec from being negotiated on the JVB connection. The codec specified
|
||||
// // here will be removed from the list of codecs present in the SDP answer generated by the client. If the
|
||||
// // same codec is specified for both the disabled and preferred option, the disable settings will prevail.
|
||||
// // Note that 'VP8' cannot be disabled since it's a mandatory codec, the setting will be ignored in this case.
|
||||
// disabledCodec: 'H264',
|
||||
//
|
||||
// // DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
|
||||
// // Provides a way to set a preferred video codec for the JVB connection. If 'H264' is specified here,
|
||||
// // simulcast will be automatically disabled since JVB doesn't support H264 simulcast yet. This will only
|
||||
// // rearrange the the preference order of the codecs in the SDP answer generated by the browser only if the
|
||||
// // preferred codec specified here is present. Please ensure that the JVB offers the specified codec for this
|
||||
// // to take effect.
|
||||
// preferredCodec: 'VP8',
|
||||
//
|
||||
// },
|
||||
|
||||
// Notification timeouts
|
||||
@@ -581,12 +652,12 @@ var config = {
|
||||
// // Whether to disable welcome page. In case it's disabled a random room
|
||||
// // will be joined when no room is specified.
|
||||
// disabled: false,
|
||||
// // If set,landing page will redirect to this URL.
|
||||
// // If set, landing page will redirect to this URL.
|
||||
// customUrl: ''
|
||||
// },
|
||||
|
||||
// Configs for the lobby screen.
|
||||
// lobby {
|
||||
// lobby: {
|
||||
// // If Lobby is enabled, it starts knocking automatically. Replaces `autoKnockLobby`.
|
||||
// autoKnock: false,
|
||||
// // Enables the lobby chat. Replaces `enableLobbyChat`.
|
||||
@@ -630,6 +701,7 @@ var config = {
|
||||
// hideDominantSpeakerBadge: false,
|
||||
|
||||
// Default language for the user interface. Cannot be overwritten.
|
||||
// DEPRECATED! Use the `lang` iframe option directly instead.
|
||||
// defaultLanguage: 'en',
|
||||
|
||||
// Disables profile and the edit of all fields from the profile settings (display name and email)
|
||||
@@ -653,7 +725,7 @@ var config = {
|
||||
// Configs for prejoin page.
|
||||
// prejoinConfig: {
|
||||
// // When 'true', it shows an intermediate page before joining, where the user can configure their devices.
|
||||
// // This replaces `prejoinPageEnabled`.
|
||||
// // This replaces `prejoinPageEnabled`. Defaults to true.
|
||||
// enabled: true,
|
||||
// // Hides the participant name editing field in the prejoin screen.
|
||||
// // If requireDisplayName is also set as true, a name should still be provided through
|
||||
@@ -824,6 +896,42 @@ var config = {
|
||||
// 'whiteboard',
|
||||
// ],
|
||||
|
||||
// Participant context menu buttons which have their click/tap event exposed through the API on
|
||||
// `participantMenuButtonClick`. Passing a string for the button key will
|
||||
// prevent execution of the click/tap routine; passing an object with `key` and
|
||||
// `preventExecution` flag on false will not prevent execution of the click/tap
|
||||
// routine. Below array with mixed mode for passing the buttons.
|
||||
// participantMenuButtonsWithNotifyClick: [
|
||||
// 'allow-video',
|
||||
// {
|
||||
// key: 'ask-unmute',
|
||||
// preventExecution: false
|
||||
// },
|
||||
// 'conn-status',
|
||||
// 'flip-local-video',
|
||||
// 'grant-moderator',
|
||||
// {
|
||||
// key: 'kick',
|
||||
// preventExecution: true
|
||||
// },
|
||||
// {
|
||||
// key: 'hide-self-view',
|
||||
// preventExecution: false
|
||||
// },
|
||||
// 'mute',
|
||||
// 'mute-others',
|
||||
// 'mute-others-video',
|
||||
// 'mute-video',
|
||||
// 'pinToStage',
|
||||
// 'privateMessage',
|
||||
// {
|
||||
// key: 'remote-control',
|
||||
// preventExecution: false
|
||||
// },
|
||||
// 'send-participant-to-room',
|
||||
// 'verify',
|
||||
// ],
|
||||
|
||||
// List of pre meeting screens buttons to hide. The values must be one or more of the 5 allowed buttons:
|
||||
// 'microphone', 'camera', 'select-background', 'invite', 'settings'
|
||||
// hiddenPremeetingButtons: [],
|
||||
@@ -833,7 +941,7 @@ var config = {
|
||||
// customParticipantMenuButtons: [],
|
||||
|
||||
// An array with custom option buttons for the toolbar
|
||||
// type: Array<{ icon: string; id: string; text: string; }>
|
||||
// type: Array<{ icon: string; id: string; text: string; backgroundColor?: string; }>
|
||||
// customToolbarButtons: [],
|
||||
|
||||
// Stats
|
||||
@@ -848,38 +956,10 @@ var config = {
|
||||
// The interval at which PeerConnection.getStats() is called. Defaults to 10000
|
||||
// pcStatsInterval: 10000,
|
||||
|
||||
// To enable sending statistics to callstats.io you must provide the
|
||||
// Application ID and Secret.
|
||||
// callStatsID: '',
|
||||
// callStatsSecret: '',
|
||||
// callStatsApplicationLogsDisabled: false,
|
||||
|
||||
// The callstats initialize config params as described in the API:
|
||||
// https://docs.callstats.io/docs/javascript#callstatsinitialize-with-app-secret
|
||||
// callStatsConfigParams: {
|
||||
// disableBeforeUnloadHandler: true, // disables callstats.js's window.onbeforeunload parameter.
|
||||
// applicationVersion: "app_version", // Application version specified by the developer.
|
||||
// disablePrecalltest: true, // disables the pre-call test, it is enabled by default.
|
||||
// siteID: "siteID", // The name/ID of the site/campus from where the call/pre-call test is made.
|
||||
// additionalIDs: { // additionalIDs object, contains application related IDs.
|
||||
// customerID: "Customer Identifier. Example, walmart.",
|
||||
// tenantID: "Tenant Identifier. Example, monster.",
|
||||
// productName: "Product Name. Example, Jitsi.",
|
||||
// meetingsName: "Meeting Name. Example, Jitsi loves callstats.",
|
||||
// serverName: "Server/MiddleBox Name. Example, jvb-prod-us-east-mlkncws12.",
|
||||
// pbxID: "PBX Identifier. Example, walmart.",
|
||||
// pbxExtensionID: "PBX Extension Identifier. Example, 5625.",
|
||||
// fqExtensionID: "Fully qualified Extension Identifier. Example, +71 (US) +5625.",
|
||||
// sessionID: "Session Identifier. Example, session-12-34",
|
||||
// },
|
||||
// collectLegacyStats: true, //enables the collection of legacy stats in chrome browser
|
||||
// collectIP: true, //enables the collection localIP address
|
||||
// },
|
||||
|
||||
// Enables sending participants' display names to callstats
|
||||
// Enables sending participants' display names to stats
|
||||
// enableDisplayNameInStats: false,
|
||||
|
||||
// Enables sending participants' emails (if available) to callstats and other analytics
|
||||
// Enables sending participants' emails (if available) to stats and other analytics
|
||||
// enableEmailInStats: false,
|
||||
|
||||
// faceLandmarks: {
|
||||
@@ -902,7 +982,7 @@ var config = {
|
||||
// captureInterval: 1000,
|
||||
// },
|
||||
|
||||
// Controls the percentage of automatic feedback shown to participants when callstats is enabled.
|
||||
// Controls the percentage of automatic feedback shown to participants.
|
||||
// The default value is 100%. If set to 0, no automatic feedback will be requested
|
||||
// feedbackPercentage: 100,
|
||||
|
||||
@@ -910,7 +990,7 @@ var config = {
|
||||
//
|
||||
|
||||
// If third party requests are disabled, no other server will be contacted.
|
||||
// This means avatars will be locally generated and callstats integration
|
||||
// This means avatars will be locally generated and external stats integration
|
||||
// will not function.
|
||||
// disableThirdPartyRequests: false,
|
||||
|
||||
@@ -935,12 +1015,12 @@ var config = {
|
||||
// If not set, the effective value is 'all'.
|
||||
// iceTransportPolicy: 'all',
|
||||
|
||||
// Provides a way to set the video codec preference on the p2p connection. Acceptable
|
||||
// codec values are 'VP8', 'VP9' and 'H264'.
|
||||
// preferredCodec: 'H264',
|
||||
|
||||
// Provides a way to prevent a video codec from being negotiated on the p2p connection.
|
||||
// disabledCodec: '',
|
||||
// Provides a way to set the codec preference on mobile devices, both on RN and mobile browser based
|
||||
// endpoints.
|
||||
// mobileCodecPreferenceOrder: [ 'H264', 'VP8', 'VP9' ],
|
||||
//
|
||||
// Provides a way to set the codec preference on desktop based endpoints.
|
||||
// codecPreferenceOrder: [ 'VP9', 'VP8', 'H264 ],
|
||||
|
||||
// How long we're going to wait, before going back to P2P after the 3rd
|
||||
// participant has left the conference (to filter out page reload).
|
||||
@@ -952,6 +1032,15 @@ var config = {
|
||||
// { urls: 'stun:jitsi-meet.example.com:3478' },
|
||||
{ urls: 'stun:meet-jit-si-turnrelay.jitsi.net:443' },
|
||||
],
|
||||
|
||||
// DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
|
||||
// Provides a way to set the video codec preference on the p2p connection. Acceptable
|
||||
// codec values are 'VP8', 'VP9' and 'H264'.
|
||||
// preferredCodec: 'H264',
|
||||
|
||||
// DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
|
||||
// Provides a way to prevent a video codec from being negotiated on the p2p connection.
|
||||
// disabledCodec: '',
|
||||
},
|
||||
|
||||
analytics: {
|
||||
@@ -968,6 +1057,10 @@ var config = {
|
||||
// The Amplitude APP Key:
|
||||
// amplitudeAPPKey: '<APP_KEY>',
|
||||
|
||||
// Enables Amplitude UTM tracking:
|
||||
// Default value is false.
|
||||
// amplitudeIncludeUTM: false,
|
||||
|
||||
// Obfuscates room name sent to analytics (amplitude, rtcstats)
|
||||
// Default value is false.
|
||||
// obfuscateRoomName: false,
|
||||
@@ -997,6 +1090,11 @@ var config = {
|
||||
// "libs/analytics-ga.min.js", // google-analytics
|
||||
// "https://example.com/my-custom-analytics.js",
|
||||
// ],
|
||||
|
||||
// By enabling watchRTCEnabled option you would want to use watchRTC feature
|
||||
// This would also require to configure watchRTCConfigParams.
|
||||
// Please remember to keep rtcstatsEnabled disabled for watchRTC to work.
|
||||
// watchRTCEnabled: false,
|
||||
},
|
||||
|
||||
// Logs that should go be passed through the 'log' event if a handler is defined for it
|
||||
@@ -1111,9 +1209,17 @@ var config = {
|
||||
// https://firebase.google.com/docs/dynamic-links/create-manually
|
||||
// deeplinking: {
|
||||
//
|
||||
// // The desktop deeplinking config.
|
||||
// // The desktop deeplinking config, disabled by default.
|
||||
// desktop: {
|
||||
// appName: 'Jitsi Meet'
|
||||
// appName: 'Jitsi Meet',
|
||||
// appScheme: 'jitsi-meet,
|
||||
// download: {
|
||||
// linux:
|
||||
// 'https://github.com/jitsi/jitsi-meet-electron/releases/latest/download/jitsi-meet-x86_64.AppImage',
|
||||
// macos: 'https://github.com/jitsi/jitsi-meet-electron/releases/latest/download/jitsi-meet.dmg',
|
||||
// windows: 'https://github.com/jitsi/jitsi-meet-electron/releases/latest/download/jitsi-meet.exe'
|
||||
// },
|
||||
// enabled: false
|
||||
// },
|
||||
// // If true, any checks to handoff to another application will be prevented
|
||||
// // and instead the app will continue to display in the current browser.
|
||||
@@ -1196,6 +1302,8 @@ var config = {
|
||||
// remoteVideoMenu: {
|
||||
// // Whether the remote video context menu to be rendered or not.
|
||||
// disabled: true,
|
||||
// // If set to true the 'Switch to visitor' button will be disabled.
|
||||
// disableDemote: true,
|
||||
// // If set to true the 'Kick out' button will be disabled.
|
||||
// disableKick: true,
|
||||
// // If set to true the 'Grant moderator' button will be disabled.
|
||||
@@ -1216,9 +1324,6 @@ var config = {
|
||||
// If set to true all muting operations of remote participants will be disabled.
|
||||
// disableRemoteMute: true,
|
||||
|
||||
// Enables support for lip-sync for this client (if the browser supports it).
|
||||
// enableLipSync: false,
|
||||
|
||||
/**
|
||||
External API url used to receive branding specific information.
|
||||
If there is no url set or there are missing fields, the defaults are applied.
|
||||
@@ -1242,6 +1347,16 @@ var config = {
|
||||
// A list of images that can be used as video backgrounds.
|
||||
// When this field is present, the default images will be replaced with those provided.
|
||||
virtualBackgrounds: ['https://example.com/img.jpg'],
|
||||
// Object containing customized icons that should replace the default ones.
|
||||
// The keys need to be the exact same icon names used in here:
|
||||
// https://github.com/jitsi/jitsi-meet/blob/master/react/features/base/icons/svg/index.ts
|
||||
// To avoid having the icons trimmed or displayed in an unexpected way, please provide svg
|
||||
// files containing svg xml icons in the size that the default icons come in.
|
||||
customIcons: {
|
||||
IconArrowUp: 'https://example.com/arrow-up.svg',
|
||||
IconDownload: 'https://example.com/download.svg',
|
||||
IconRemoteControlStart: 'https://example.com/remote-start.svg',
|
||||
},
|
||||
// Object containing a theme's properties. It also supports partial overwrites of the main theme.
|
||||
// For a list of all possible theme tokens and their current defaults, please check:
|
||||
// https://github.com/jitsi/jitsi-meet/tree/master/resources/custom-theme/custom-theme.json
|
||||
@@ -1277,6 +1392,8 @@ var config = {
|
||||
|
||||
// Options related to the participants pane.
|
||||
// participantsPane: {
|
||||
// // Enables feature
|
||||
// enabled: true,
|
||||
// // Hides the moderator settings tab.
|
||||
// hideModeratorSettingsTab: false,
|
||||
// // Hides the more actions button.
|
||||
@@ -1295,13 +1412,13 @@ var config = {
|
||||
// hideJoinRoomButton: false,
|
||||
// },
|
||||
|
||||
// When true, virtual background feature will be disabled.
|
||||
// disableVirtualBackground: false,
|
||||
|
||||
// When true the user cannot add more images to be used as virtual background.
|
||||
// Only the default ones from will be available.
|
||||
// disableAddingBackgroundImages: false,
|
||||
|
||||
// Disables using screensharing as virtual background.
|
||||
// disableScreensharingVirtualBackground: false,
|
||||
|
||||
// Sets the background transparency level. '0' is fully transparent, '1' is opaque.
|
||||
// backgroundAlpha: 1,
|
||||
|
||||
@@ -1328,7 +1445,6 @@ var config = {
|
||||
// 'conference-timer',
|
||||
// 'participants-count',
|
||||
// 'e2ee',
|
||||
// 'transcribing',
|
||||
// 'video-quality',
|
||||
// 'insecure-room',
|
||||
// 'highlight-moment',
|
||||
@@ -1372,6 +1488,31 @@ var config = {
|
||||
// dialInConfCodeUrl is the conference mapper converting a meeting id to a PIN used for dial-in
|
||||
// or the other way around (more info in resources/cloud-api.swagger)
|
||||
|
||||
// You can use external service for authentication that will redirect back passing a jwt token
|
||||
// You can use tokenAuthUrl config to point to a URL of such service.
|
||||
// The URL for the service supports few params which will be filled in by the code.
|
||||
// tokenAuthUrl:
|
||||
// 'https://myservice.com/auth/{room}?code_challenge_method=S256&code_challenge={code_challenge}&state={state}'
|
||||
// Supported parameters in tokenAuthUrl:
|
||||
// {room} - will be replaced with the room name
|
||||
// {code_challenge} - (A web only). A oauth 2.0 code challenge that will be sent to the service. See:
|
||||
// https://datatracker.ietf.org/doc/html/rfc7636. The code verifier will be saved in the sessionStorage
|
||||
// under key: 'code_verifier'.
|
||||
// {state} - A json with the current state before redirecting. Keys that are included in the state:
|
||||
// - room (The current room name as shown in the address bar)
|
||||
// - roomSafe (the backend safe room name to use (lowercase), that is passed to the backend)
|
||||
// - tenant (The tenant if any)
|
||||
// - config.xxx (all config overrides)
|
||||
// - interfaceConfig.xxx (all interfaceConfig overrides)
|
||||
// - ios=true (in case ios mobile app is used)
|
||||
// - android=true (in case android mobile app is used)
|
||||
// - electron=true (when web is loaded in electron app)
|
||||
// If there is a logout service you can specify its URL with:
|
||||
// tokenLogoutUrl: 'https://myservice.com/logout'
|
||||
// You can enable tokenAuthUrlAutoRedirect which will detect that you have logged in successfully before
|
||||
// and will automatically redirect to the token service to get the token for the meeting.
|
||||
// tokenAuthUrlAutoRedirect: false
|
||||
|
||||
// List of undocumented settings used in jitsi-meet
|
||||
/**
|
||||
_immediateReloadThreshold
|
||||
@@ -1391,7 +1532,6 @@ var config = {
|
||||
peopleSearchQueryTypes
|
||||
peopleSearchUrl
|
||||
requireDisplayName
|
||||
tokenAuthUrl
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -1406,8 +1546,6 @@ var config = {
|
||||
_peerConnStatusOutOfLastNTimeout
|
||||
_peerConnStatusRtcMuteTimeout
|
||||
avgRtpStatsN
|
||||
callStatsConfIDNamespace
|
||||
callStatsCustomScriptUrl
|
||||
desktopSharingSources
|
||||
disableAEC
|
||||
disableAGC
|
||||
@@ -1416,7 +1554,6 @@ var config = {
|
||||
disableLocalStats
|
||||
disableNS
|
||||
enableTalkWhileMuted
|
||||
forceJVB121Ratio
|
||||
forceTurnRelay
|
||||
hiddenDomain
|
||||
hiddenFromRecorderFeatureEnabled
|
||||
@@ -1440,6 +1577,7 @@ var config = {
|
||||
*/
|
||||
// notifications: [
|
||||
// 'connection.CONNFAIL', // shown when the connection fails,
|
||||
// 'dialog.cameraConstraintFailedError', // shown when the camera failed
|
||||
// 'dialog.cameraNotSendingData', // shown when there's no feed from user's camera
|
||||
// 'dialog.kickTitle', // shown when user has been kicked
|
||||
// 'dialog.liveStreaming', // livestreaming notifications (pending, on, off, limits)
|
||||
@@ -1450,10 +1588,12 @@ var config = {
|
||||
// 'dialog.recording', // recording notifications (pending, on, off, limits)
|
||||
// 'dialog.remoteControlTitle', // remote control notifications (allowed, denied, start, stop, error)
|
||||
// 'dialog.reservationError',
|
||||
// 'dialog.screenSharingFailedTitle', // shown when the screen sharing failed
|
||||
// 'dialog.serviceUnavailable', // shown when server is not reachable
|
||||
// 'dialog.sessTerminated', // shown when there is a failed conference session
|
||||
// 'dialog.sessionRestarted', // show when a client reload is initiated because of bridge migration
|
||||
// 'dialog.tokenAuthFailed', // show when an invalid jwt is used
|
||||
// 'dialog.tokenAuthFailedWithReasons', // show when an invalid jwt is used with the reason behind the error
|
||||
// 'dialog.transcribing', // transcribing notifications (pending, off)
|
||||
// 'dialOut.statusMessage', // shown when dial out status is updated.
|
||||
// 'liveStreaming.busy', // shown when livestreaming service is busy
|
||||
@@ -1461,37 +1601,45 @@ var config = {
|
||||
// 'liveStreaming.unavailableTitle', // shown when livestreaming service is not reachable
|
||||
// 'lobby.joinRejectedMessage', // shown when while in a lobby, user's request to join is rejected
|
||||
// 'lobby.notificationTitle', // shown when lobby is toggled and when join requests are allowed / denied
|
||||
// 'notify.audioUnmuteBlockedTitle', // shown when mic unmute blocked
|
||||
// 'notify.chatMessages', // shown when receiving chat messages while the chat window is closed
|
||||
// 'notify.disconnected', // shown when a participant has left
|
||||
// 'notify.connectedOneMember', // show when a participant joined
|
||||
// 'notify.connectedTwoMembers', // show when two participants joined simultaneously
|
||||
// 'notify.connectedThreePlusMembers', // show when more than 2 participants joined simultaneously
|
||||
// 'notify.leftOneMember', // show when a participant left
|
||||
// 'notify.leftTwoMembers', // show when two participants left simultaneously
|
||||
// 'notify.leftThreePlusMembers', // show when more than 2 participants left simultaneously
|
||||
// 'notify.grantedTo', // shown when moderator rights were granted to a participant
|
||||
// 'notify.connectedTwoMembers', // show when two participants joined simultaneously
|
||||
// 'notify.dataChannelClosed', // shown when the bridge channel has been disconnected
|
||||
// 'notify.hostAskedUnmute', // shown to participant when host asks them to unmute
|
||||
// 'notify.invitedOneMember', // shown when 1 participant has been invited
|
||||
// 'notify.invitedThreePlusMembers', // shown when 3+ participants have been invited
|
||||
// 'notify.invitedTwoMembers', // shown when 2 participants have been invited
|
||||
// 'notify.kickParticipant', // shown when a participant is kicked
|
||||
// 'notify.leftOneMember', // show when a participant left
|
||||
// 'notify.leftThreePlusMembers', // show when more than 2 participants left simultaneously
|
||||
// 'notify.leftTwoMembers', // show when two participants left simultaneously
|
||||
// 'notify.linkToSalesforce', // shown when joining a meeting with salesforce integration
|
||||
// 'notify.moderationStartedTitle', // shown when AV moderation is activated
|
||||
// 'notify.moderationStoppedTitle', // shown when AV moderation is deactivated
|
||||
// 'notify.localRecordingStarted', // shown when the local recording has been started
|
||||
// 'notify.localRecordingStopped', // shown when the local recording has been stopped
|
||||
// 'notify.moderationInEffectCSTitle', // shown when user attempts to share content during AV moderation
|
||||
// 'notify.moderationInEffectTitle', // shown when user attempts to unmute audio during AV moderation
|
||||
// 'notify.moderationInEffectVideoTitle', // shown when user attempts to enable video during AV moderation
|
||||
// 'notify.moderationInEffectCSTitle', // shown when user attempts to share content during AV moderation
|
||||
// 'notify.moderator', // shown when user gets moderator privilege
|
||||
// 'notify.mutedRemotelyTitle', // shown when user is muted by a remote party
|
||||
// 'notify.mutedTitle', // shown when user has been muted upon joining,
|
||||
// 'notify.newDeviceAudioTitle', // prompts the user to use a newly detected audio device
|
||||
// 'notify.newDeviceCameraTitle', // prompts the user to use a newly detected camera
|
||||
// 'notify.noiseSuppressionFailedTitle', // shown when failed to start noise suppression
|
||||
// 'notify.participantWantsToJoin', // shown when lobby is enabled and participant requests to join meeting
|
||||
// 'notify.participantsWantToJoin', // shown when lobby is enabled and participants request to join meeting
|
||||
// 'notify.passwordRemovedRemotely', // shown when a password has been removed remotely
|
||||
// 'notify.passwordSetRemotely', // shown when a password has been set remotely
|
||||
// 'notify.raisedHand', // shown when a partcipant used raise hand,
|
||||
// 'notify.screenShareNoAudio', // shown when the audio could not be shared for the selected screen
|
||||
// 'notify.screenSharingAudioOnlyTitle', // shown when the best performance has been affected by screen sharing
|
||||
// 'notify.selfViewTitle', // show "You can always un-hide the self-view from settings"
|
||||
// 'notify.startSilentTitle', // shown when user joined with no audio
|
||||
// 'notify.suboptimalExperienceTitle', // show the browser warning
|
||||
// 'notify.unmute', // shown to moderator when user raises hand during AV moderation
|
||||
// 'notify.videoMutedRemotelyTitle', // shown when user's video is muted by a remote party,
|
||||
// 'notify.videoUnmuteBlockedTitle', // shown when camera unmute and desktop sharing are blocked
|
||||
// 'prejoin.errorDialOut',
|
||||
// 'prejoin.errorDialOutDisconnected',
|
||||
// 'prejoin.errorDialOutFailed',
|
||||
@@ -1514,6 +1662,8 @@ var config = {
|
||||
// disableFilmstripAutohiding: false,
|
||||
|
||||
// filmstrip: {
|
||||
// // Disable the vertical/horizonal filmstrip.
|
||||
// disabled: false,
|
||||
// // Disables user resizable filmstrip. Also, allows configuration of the filmstrip
|
||||
// // (width, tiles aspect ratios) through the interfaceConfig options.
|
||||
// disableResizable: false,
|
||||
@@ -1536,6 +1686,8 @@ var config = {
|
||||
|
||||
// Tile view related config options.
|
||||
// tileView: {
|
||||
// // Whether tileview should be disabled.
|
||||
// disabled: false,
|
||||
// // The optimal number of tiles that are going to be shown in tile view. Depending on the screen size it may
|
||||
// // not be possible to show the exact number of participants specified here.
|
||||
// numberOfVisibleTiles: 25,
|
||||
@@ -1567,13 +1719,12 @@ var config = {
|
||||
// logging: {
|
||||
// // Default log level for the app and lib-jitsi-meet.
|
||||
// defaultLogLevel: 'trace',
|
||||
// // Option to disable LogCollector (which stores the logs on CallStats).
|
||||
// // Option to disable LogCollector.
|
||||
// //disableLogCollector: true,
|
||||
// // Individual loggers are customizable.
|
||||
// loggers: {
|
||||
// // The following are too verbose in their logging with the default level.
|
||||
// 'modules/RTC/TraceablePeerConnection.js': 'info',
|
||||
// 'modules/statistics/CallStats.js': 'info',
|
||||
// 'modules/xmpp/strophe.util.js': 'log',
|
||||
// },
|
||||
|
||||
@@ -1587,6 +1738,45 @@ var config = {
|
||||
// // The server used to support whiteboard collaboration.
|
||||
// // https://github.com/jitsi/excalidraw-backend
|
||||
// collabServerBaseUrl: 'https://excalidraw-backend.example.com',
|
||||
// // The user access limit to the whiteboard, introduced as a means
|
||||
// // to control the performance.
|
||||
// userLimit: 25,
|
||||
// // The url for more info about the whiteboard and its usage limitations.
|
||||
// limitUrl: 'https://example.com/blog/whiteboard-limits,
|
||||
// },
|
||||
|
||||
// The watchRTC initialize config params as described :
|
||||
// https://testrtc.com/docs/installing-the-watchrtc-javascript-sdk/#h-set-up-the-sdk
|
||||
// https://www.npmjs.com/package/@testrtc/watchrtc-sdk
|
||||
// watchRTCConfigParams: {
|
||||
// /** Watchrtc api key */
|
||||
// rtcApiKey: string;
|
||||
// /** Identifier for the session */
|
||||
// rtcRoomId?: string;
|
||||
// /** Identifier for the current peer */
|
||||
// rtcPeerId?: string;
|
||||
// /**
|
||||
// * ["tag1", "tag2", "tag3"]
|
||||
// * @deprecated use 'keys' instead
|
||||
// */
|
||||
// rtcTags?: string[];
|
||||
// /** { "key1": "value1", "key2": "value2"} */
|
||||
// keys?: any;
|
||||
// /** Enables additional logging */
|
||||
// debug?: boolean;
|
||||
// rtcToken?: string;
|
||||
// /**
|
||||
// * @deprecated No longer needed. Use "proxyUrl" instead.
|
||||
// */
|
||||
// wsUrl?: string;
|
||||
// proxyUrl?: string;
|
||||
// console?: {
|
||||
// level: string;
|
||||
// override: boolean;
|
||||
// };
|
||||
// allowBrowserLogCollection?: boolean;
|
||||
// collectionInterval?: number;
|
||||
// logGetStats?: boolean;
|
||||
// },
|
||||
};
|
||||
|
||||
|
||||
209
connection.js
209
connection.js
@@ -1,209 +0,0 @@
|
||||
/* global APP, JitsiMeetJS, config */
|
||||
|
||||
import { jitsiLocalStorage } from '@jitsi/js-utils';
|
||||
import Logger from '@jitsi/logger';
|
||||
|
||||
import { redirectToTokenAuthService } from './modules/UI/authentication/AuthHandler';
|
||||
import { LoginDialog } from './react/features/authentication/components';
|
||||
import { isTokenAuthEnabled } from './react/features/authentication/functions';
|
||||
import {
|
||||
connectionEstablished,
|
||||
connectionFailed,
|
||||
constructOptions
|
||||
} from './react/features/base/connection/actions.web';
|
||||
import { openDialog } from './react/features/base/dialog/actions';
|
||||
import { setJWT } from './react/features/base/jwt/actions';
|
||||
import {
|
||||
JitsiConnectionErrors,
|
||||
JitsiConnectionEvents
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
|
||||
import { getCustomerDetails } from './react/features/jaas/actions.any';
|
||||
import { getJaasJWT, isVpaasMeeting } from './react/features/jaas/functions';
|
||||
import {
|
||||
setPrejoinDisplayNameRequired
|
||||
} from './react/features/prejoin/actions';
|
||||
const logger = Logger.getLogger(__filename);
|
||||
|
||||
/**
|
||||
* The feature announced so we can distinguish jibri participants.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
export const DISCO_JIBRI_FEATURE = 'http://jitsi.org/protocol/jibri';
|
||||
|
||||
/**
|
||||
* Try to open connection using provided credentials.
|
||||
* @param {string} [id]
|
||||
* @param {string} [password]
|
||||
* @returns {Promise<JitsiConnection>} connection if
|
||||
* everything is ok, else error.
|
||||
*/
|
||||
export async function connect(id, password) {
|
||||
const state = APP.store.getState();
|
||||
let { jwt } = state['features/base/jwt'];
|
||||
const { iAmRecorder, iAmSipGateway } = state['features/base/config'];
|
||||
|
||||
if (!iAmRecorder && !iAmSipGateway && isVpaasMeeting(state)) {
|
||||
await APP.store.dispatch(getCustomerDetails());
|
||||
|
||||
if (!jwt) {
|
||||
jwt = await getJaasJWT(state);
|
||||
APP.store.dispatch(setJWT(jwt));
|
||||
}
|
||||
}
|
||||
|
||||
const connection = new JitsiMeetJS.JitsiConnection(null, jwt, constructOptions(state));
|
||||
|
||||
if (config.iAmRecorder) {
|
||||
connection.addFeature(DISCO_JIBRI_FEATURE);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
connection.addEventListener(
|
||||
JitsiConnectionEvents.CONNECTION_ESTABLISHED,
|
||||
handleConnectionEstablished);
|
||||
connection.addEventListener(
|
||||
JitsiConnectionEvents.CONNECTION_FAILED,
|
||||
handleConnectionFailed);
|
||||
connection.addEventListener(
|
||||
JitsiConnectionEvents.CONNECTION_FAILED,
|
||||
connectionFailedHandler);
|
||||
connection.addEventListener(
|
||||
JitsiConnectionEvents.DISPLAY_NAME_REQUIRED,
|
||||
displayNameRequiredHandler
|
||||
);
|
||||
|
||||
/* eslint-disable max-params */
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function connectionFailedHandler(error, message, credentials, details) {
|
||||
/* eslint-enable max-params */
|
||||
APP.store.dispatch(
|
||||
connectionFailed(
|
||||
connection, {
|
||||
credentials,
|
||||
details,
|
||||
message,
|
||||
name: error
|
||||
}));
|
||||
|
||||
if (isFatalJitsiConnectionError(error)) {
|
||||
connection.removeEventListener(
|
||||
JitsiConnectionEvents.CONNECTION_FAILED,
|
||||
connectionFailedHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function unsubscribe() {
|
||||
connection.removeEventListener(
|
||||
JitsiConnectionEvents.CONNECTION_ESTABLISHED,
|
||||
handleConnectionEstablished);
|
||||
connection.removeEventListener(
|
||||
JitsiConnectionEvents.CONNECTION_FAILED,
|
||||
handleConnectionFailed);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function handleConnectionEstablished() {
|
||||
APP.store.dispatch(connectionEstablished(connection, Date.now()));
|
||||
unsubscribe();
|
||||
resolve(connection);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function handleConnectionFailed(err) {
|
||||
unsubscribe();
|
||||
logger.error('CONNECTION FAILED:', err);
|
||||
reject(err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the display name for the prejoin screen as required.
|
||||
* This can happen if a user tries to join a room with lobby enabled.
|
||||
*/
|
||||
function displayNameRequiredHandler() {
|
||||
APP.store.dispatch(setPrejoinDisplayNameRequired());
|
||||
}
|
||||
|
||||
connection.connect({
|
||||
id,
|
||||
password
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Open JitsiConnection using provided credentials.
|
||||
* If retry option is true it will show auth dialog on PASSWORD_REQUIRED error.
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {string} [options.id]
|
||||
* @param {string} [options.password]
|
||||
* @param {string} [options.roomName]
|
||||
* @param {boolean} [retry] if we should show auth dialog
|
||||
* on PASSWORD_REQUIRED error.
|
||||
*
|
||||
* @returns {Promise<JitsiConnection>}
|
||||
*/
|
||||
export function openConnection({ id, password, retry, roomName }) {
|
||||
const usernameOverride
|
||||
= jitsiLocalStorage.getItem('xmpp_username_override');
|
||||
const passwordOverride
|
||||
= jitsiLocalStorage.getItem('xmpp_password_override');
|
||||
|
||||
if (usernameOverride && usernameOverride.length > 0) {
|
||||
id = usernameOverride; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
if (passwordOverride && passwordOverride.length > 0) {
|
||||
password = passwordOverride; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
|
||||
return connect(id, password).catch(err => {
|
||||
if (retry) {
|
||||
const { jwt } = APP.store.getState()['features/base/jwt'];
|
||||
|
||||
if (err === JitsiConnectionErrors.PASSWORD_REQUIRED && !jwt) {
|
||||
return requestAuth(roomName);
|
||||
}
|
||||
}
|
||||
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Authentication Dialog and try to connect with new credentials.
|
||||
* If failed to connect because of PASSWORD_REQUIRED error
|
||||
* then ask for password again.
|
||||
* @param {string} [roomName] name of the conference room
|
||||
*
|
||||
* @returns {Promise<JitsiConnection>}
|
||||
*/
|
||||
function requestAuth(roomName) {
|
||||
const config = APP.store.getState()['features/base/config'];
|
||||
|
||||
if (isTokenAuthEnabled(config)) {
|
||||
// This Promise never resolves as user gets redirected to another URL
|
||||
return new Promise(() => redirectToTokenAuthService(roomName));
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
const onSuccess = connection => {
|
||||
resolve(connection);
|
||||
};
|
||||
|
||||
APP.store.dispatch(
|
||||
openDialog(LoginDialog, { onSuccess,
|
||||
roomName })
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -31,8 +31,8 @@ body {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
overflow: hidden;
|
||||
color: $defaultColor;
|
||||
background: $defaultBackground;
|
||||
color: #F1F1F1;
|
||||
background: #040404; // should match DEFAULT_BACKGROUND from interface_config
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,10 +66,6 @@ body, input, textarea, keygen, select, button {
|
||||
font-family: $baseFontFamily !important;
|
||||
}
|
||||
|
||||
#nowebrtc {
|
||||
display:none;
|
||||
}
|
||||
|
||||
button, input, select, textarea {
|
||||
margin: 0;
|
||||
vertical-align: baseline;
|
||||
@@ -94,7 +90,7 @@ input[type='text'], input[type='password'], textarea {
|
||||
|
||||
button {
|
||||
color: #FFF;
|
||||
background-color: $buttonBackground;
|
||||
background-color: #44A5FF;
|
||||
border-radius: $borderRadius;
|
||||
|
||||
&.no-icon {
|
||||
@@ -119,17 +115,18 @@ form {
|
||||
}
|
||||
|
||||
.leftwatermark {
|
||||
max-width: 140px;
|
||||
max-height:70px;
|
||||
left: 32px;
|
||||
top: 32px;
|
||||
background-position: center left;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.leftwatermarknomargin {
|
||||
background-position: center left;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
&.no-margin {
|
||||
left:0;
|
||||
top:0;
|
||||
}
|
||||
}
|
||||
|
||||
.rightwatermark {
|
||||
@@ -145,22 +142,7 @@ form {
|
||||
font-size: 11pt;
|
||||
color: rgba(255,255,255,.50);
|
||||
text-decoration: none;
|
||||
z-index: $poweredByZ;
|
||||
}
|
||||
|
||||
.connected {
|
||||
color: #21B9FC;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.lastN, .disconnected {
|
||||
color: #a3a3a3;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#inviteLinkRef {
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +167,7 @@ form {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, .5);
|
||||
background: #3D3D3D;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
@@ -193,3 +175,16 @@ form {
|
||||
.jitsi-icon svg path {
|
||||
fill: inherit !important;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
border: 0 !important;
|
||||
clip: rect(1px, 1px, 1px, 1px) !important;
|
||||
clip-path: inset(50%) !important;
|
||||
height: 1px !important;
|
||||
margin: -1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
179
css/_chat.scss
179
css/_chat.scss
@@ -1,35 +1,3 @@
|
||||
#sideToolbarContainer {
|
||||
background-color: $chatBackgroundColor;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
transition: width .16s ease-in-out;
|
||||
width: $sidebarWidth;
|
||||
z-index: $sideToolbarContainerZ;
|
||||
|
||||
@media (max-width: 580px) {
|
||||
height: 100vh;
|
||||
height: -webkit-fill-available;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// extract header + tabs height
|
||||
height: calc(100% - 119px);
|
||||
}
|
||||
|
||||
.chat-panel-no-tabs {
|
||||
// extract header height
|
||||
height: calc(100% - 70px);
|
||||
}
|
||||
|
||||
#chat-conversation-container {
|
||||
// extract message input height
|
||||
height: calc(100% - 64px);
|
||||
@@ -76,27 +44,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.chat-header {
|
||||
height: 70px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 16px;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 24px;
|
||||
line-height: 32px;
|
||||
|
||||
.jitsi-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-input-container {
|
||||
padding: 0 16px 24px;
|
||||
}
|
||||
@@ -112,61 +59,6 @@
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.smiley-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 38px;
|
||||
width: 38px;
|
||||
margin: 2px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#chat-input .smiley-button {
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&:hover {
|
||||
background-color: #484A4F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.remoteuser {
|
||||
color: #B8C7E0;
|
||||
}
|
||||
|
||||
.usrmsg-form {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#usermsg {
|
||||
-ms-overflow-style: none;
|
||||
border: 0px none;
|
||||
border-radius:0;
|
||||
box-shadow: none;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
padding: 10px;
|
||||
overflow-y: auto;
|
||||
resize: none;
|
||||
scrollbar-width: none;
|
||||
width: 100%;
|
||||
word-break: break-word;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#usermsg:hover {
|
||||
border: 0px none;
|
||||
box-shadow: none;
|
||||
}
|
||||
#usermsg:focus,
|
||||
#usermsg:active {
|
||||
border-bottom: 1px solid white;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
#nickname {
|
||||
text-align: center;
|
||||
color: #9d9d9d;
|
||||
@@ -174,11 +66,6 @@
|
||||
margin: auto 0;
|
||||
padding: 0 16px;
|
||||
|
||||
#nickname-title {
|
||||
margin-bottom: 5px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
label[for="nickinput"] {
|
||||
> div > span {
|
||||
color: #B8C7E0;
|
||||
@@ -191,24 +78,6 @@
|
||||
label {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.enter-chat {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 16px;
|
||||
height: 40px;
|
||||
background: #1B67EC;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
|
||||
&.disabled {
|
||||
color: #AFB6BC;
|
||||
background: #11336E;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-browser {
|
||||
@@ -216,14 +85,6 @@
|
||||
input {
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.enter-chat {
|
||||
height: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
#usermsg {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.chatmessage .usermessage {
|
||||
@@ -231,32 +92,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.sideToolbarContainer {
|
||||
* {
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
border: 0 !important;
|
||||
clip: rect(1px, 1px, 1px, 1px) !important;
|
||||
clip-path: inset(50%) !important;
|
||||
height: 1px !important;
|
||||
margin: -1px !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
.chatmessage {
|
||||
&.localuser {
|
||||
background-color: $chatLocalMessageBackgroundColor;
|
||||
border-radius: 6px 0px 6px 6px;
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-radius: 0px;
|
||||
|
||||
@@ -288,13 +124,6 @@
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#smileysarea {
|
||||
display: flex;
|
||||
max-height: 150px;
|
||||
min-height: 35px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.smiley-input {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
@@ -324,7 +153,7 @@
|
||||
|
||||
#smileysContainer {
|
||||
background-color: $chatBackgroundColor;
|
||||
border-top: 1px solid $chatInputSeparatorColor;
|
||||
border-top: 1px solid #A4B8D1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,15 +169,11 @@
|
||||
}
|
||||
|
||||
.smileyContainer:hover {
|
||||
background-color: $newToolbarButtonToggleColor;
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#usermsg::-webkit-scrollbar-track-piece {
|
||||
background: #3a3a3a;
|
||||
}
|
||||
|
||||
.chat-message-group {
|
||||
&.local {
|
||||
align-items: flex-end;
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
.drawer-portal {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: $drawerZ;
|
||||
border-radius: 16px 16px 0 0;
|
||||
|
||||
&.notification-portal {
|
||||
z-index: $dropdownZ;
|
||||
}
|
||||
}
|
||||
|
||||
.drawer-portal::after {
|
||||
content: '';
|
||||
background-color: $participantsPaneBgColor;
|
||||
margin-bottom: env(safe-area-inset-bottom, 0);
|
||||
}
|
||||
|
||||
.drawer-menu-container {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.drawer-menu {
|
||||
overflow-y: auto;
|
||||
margin-bottom: env(safe-area-inset-bottom, 0);
|
||||
width: 100%;
|
||||
|
||||
.drawer-toggle {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
cursor: pointer;
|
||||
|
||||
svg {
|
||||
fill: none;
|
||||
}
|
||||
}
|
||||
|
||||
&#{&} .overflow-menu {
|
||||
margin: auto;
|
||||
font-size: 1.2em;
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
height: calc(80vh - 144px - 64px);
|
||||
overflow-y: auto;
|
||||
|
||||
.overflow-menu-item {
|
||||
box-sizing: border-box;
|
||||
height: 48px;
|
||||
padding: 12px 16px;
|
||||
|
||||
align-items: center;
|
||||
color: $overflowMenuItemColor;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
font-size: 16px;
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&.unclickable {
|
||||
cursor: default;
|
||||
}
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
&.unclickable:hover {
|
||||
background: inherit;
|
||||
}
|
||||
}
|
||||
&.disabled {
|
||||
cursor: initial;
|
||||
color: #3b475c;
|
||||
}
|
||||
}
|
||||
|
||||
.profile-text {
|
||||
max-width: 100%;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#e2ee-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.description {
|
||||
font-size: 13px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.control-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-top: 15px;
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,20 +3,20 @@
|
||||
@include border-radius(4px);
|
||||
padding: 40px 38px 44px;
|
||||
color: #fff;
|
||||
background: $inlayColorBg;
|
||||
background: lighten(#474747, 20%);
|
||||
text-align: center;
|
||||
|
||||
&__title {
|
||||
margin: 17px 0;
|
||||
padding-bottom: 17px;
|
||||
color: $popoverFontColor;
|
||||
color: #ffffff;
|
||||
font-size: 21px;
|
||||
letter-spacing: 0.3px;
|
||||
border-bottom: 1px solid $inlayBorderColor;
|
||||
border-bottom: 1px solid lighten(#FFFFFF, 10%);
|
||||
}
|
||||
|
||||
&__text {
|
||||
color: $popoverFontColor;
|
||||
color: #ffffff;
|
||||
display: block;
|
||||
margin-top: 22px;
|
||||
font-size: 16px;
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*Initialize*/
|
||||
div.loginmenu {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
top: 40px;
|
||||
left: 20px;
|
||||
}
|
||||
|
||||
a.disabled {
|
||||
color: gray !important;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.loginmenu.extendedToolbarPopup {
|
||||
top: 20px;
|
||||
left: 40px;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
.filmstrip-toolbox,
|
||||
.always-on-top-toolbox {
|
||||
background-color: $newToolbarBackgroundColor;
|
||||
border-radius: 3px;
|
||||
@@ -29,7 +28,3 @@
|
||||
transform: translateX(-50%);
|
||||
padding: 3px !important;
|
||||
}
|
||||
|
||||
.filmstrip-toolbox {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
.jqistates {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.jqistates h2 {
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 18px;
|
||||
line-height: 25px;
|
||||
text-align: center;
|
||||
color: #424242;
|
||||
}
|
||||
|
||||
.jqistates input {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.jqistates input[type='text'], input[type='password'] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button.jqidefaultbutton #inviteLinkRef {
|
||||
color: #2c8ad2;
|
||||
}
|
||||
|
||||
#inviteLinkRef {
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
@@ -75,6 +75,3 @@
|
||||
margin-bottom: 36px;
|
||||
width: 100%;
|
||||
}
|
||||
.navigate-section-list-empty {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
.notice {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
z-index: $zindex3;
|
||||
margin-top: 6px;
|
||||
|
||||
@include transform(translateX(-50%));
|
||||
|
||||
&__message {
|
||||
background-color: #000000;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +1,3 @@
|
||||
.participants_pane {
|
||||
background-color: $participantsPaneBgColor;
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
transition: width .16s ease-in-out;
|
||||
width: 315px;
|
||||
z-index: $zindex0;
|
||||
}
|
||||
|
||||
.participants_pane-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-weight: 600;
|
||||
height: 100%;
|
||||
width: 315px;
|
||||
|
||||
& > *:first-child,
|
||||
& > *:last-child {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 580px) {
|
||||
.participants_pane {
|
||||
height: 100vh;
|
||||
height: -webkit-fill-available;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.participants_pane-content {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.jitsi-icon {
|
||||
&-dominant-speaker {
|
||||
background-color: #1EC26A;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.polls-panel {
|
||||
height: calc(100% - 119px);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
.popover {
|
||||
z-index: $popoverZ;
|
||||
z-index: 8;
|
||||
|
||||
.popover-content {
|
||||
position: relative;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
.reactions-menu {
|
||||
width: 280px;
|
||||
background: $menuBG;
|
||||
background: #242528;
|
||||
box-shadow: 0px 3px 16px rgba(0, 0, 0, 0.6), 0px 0px 4px 1px rgba(0, 0, 0, 0.25);
|
||||
border-radius: 6px;
|
||||
padding: 16px;
|
||||
@@ -104,7 +104,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.reactions-animations-container {
|
||||
.reactions-animations-overflow-container {
|
||||
position: absolute;
|
||||
width: 20%;
|
||||
bottom: 0;
|
||||
@@ -117,6 +117,13 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.reactions-animations-container {
|
||||
left: 50%;
|
||||
bottom: 0px;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
$reactionCount: 20;
|
||||
|
||||
@function random($min, $max) {
|
||||
@@ -154,17 +161,17 @@ $reactionCount: 20;
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: translate(40px, -70vh) scale(1.5);
|
||||
transform: translate(40px, -70dvh) scale(1.5);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
75% {
|
||||
transform: translate(40px, -70vh) scale(1.5);
|
||||
transform: translate(40px, -70dvh) scale(1.5);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate(140px, -50vh) scale(1);
|
||||
transform: translate(140px, -50dvh) scale(1);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -187,17 +194,17 @@ $reactionCount: 20;
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: translate(#{$topX}px, -#{$topY}vh) scale(1.5);
|
||||
transform: translate(#{$topX}px, -#{$topY}dvh) scale(1.5);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
75% {
|
||||
transform: translate(#{$topX}px, -#{$topY}vh) scale(1.5);
|
||||
transform: translate(#{$topX}px, -#{$topY}dvh) scale(1.5);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate(#{$bottomX}px, -#{$bottomY}vh) scale(1);
|
||||
transform: translate(#{$bottomX}px, -#{$bottomY}dvh) scale(1);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
.recordingSpinner {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.recording-dialog {
|
||||
flex: 0;
|
||||
flex-direction: column;
|
||||
@@ -19,6 +15,10 @@
|
||||
font-size: 14px;
|
||||
margin-left: 16px;
|
||||
max-width: 70%;
|
||||
|
||||
&-no-space {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.space-top {
|
||||
@@ -50,10 +50,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.recording-switch-disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.recording-icon-container {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -156,8 +152,7 @@
|
||||
*/
|
||||
font-size: 14px;
|
||||
|
||||
.broadcast-dropdown,
|
||||
.broadcast-dropdown-trigger {
|
||||
.broadcast-dropdown {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@@ -186,7 +181,7 @@
|
||||
}
|
||||
|
||||
.google-error {
|
||||
color: $errorColor;
|
||||
color: #c61600;
|
||||
}
|
||||
|
||||
.google-panel {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
font-size: 24px;
|
||||
|
||||
.thanks-msg {
|
||||
border-bottom: 1px solid $selectBg;
|
||||
border-bottom: 1px solid #FFFFFF;
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
p {
|
||||
@@ -14,7 +14,7 @@
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
.hint-msg{
|
||||
.hint-msg {
|
||||
p {
|
||||
margin: 26px auto;
|
||||
font-weight: 600;
|
||||
@@ -28,7 +28,13 @@
|
||||
width: 120px;
|
||||
height: 86px;
|
||||
margin: 0 auto;
|
||||
background: $happySoftwareBackground;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
.forbidden-msg {
|
||||
p {
|
||||
font-size: 16px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,14 +34,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.subject-info {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-bottom: 4px;
|
||||
max-width: 80%;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.details-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
@@ -49,7 +41,6 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 48px;
|
||||
max-width: calc(100% - 24px);
|
||||
}
|
||||
|
||||
@keyframes hideSubject {
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
* Round badge.
|
||||
*/
|
||||
.badge-round {
|
||||
background-color: $toolbarBadgeBackground;
|
||||
background-color: #165ECC;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
color: $toolbarBadgeColor;
|
||||
color: #FFFFFF;
|
||||
// Do not inherit the font-family from the toolbar button, because it's an
|
||||
// icon style.
|
||||
font-family: $baseFontFamily;
|
||||
@@ -58,21 +58,6 @@
|
||||
z-index: $toolbarZ;
|
||||
pointer-events: none;
|
||||
|
||||
.button-group-center,
|
||||
.button-group-left,
|
||||
.button-group-right {
|
||||
display: flex;
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
.button-group-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button-group-right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.toolbox-button-wth-dialog {
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -112,16 +97,6 @@
|
||||
padding-bottom: env(safe-area-inset-bottom, 0);
|
||||
}
|
||||
|
||||
.beta-tag {
|
||||
background: #36383C;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
margin-left: 8px;
|
||||
padding: 0 4px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.overflow-menu-hr {
|
||||
border-top: 1px solid #4C4D50;
|
||||
border-bottom: 0;
|
||||
@@ -192,7 +167,7 @@ div.hangup-menu-button {
|
||||
background: none;
|
||||
|
||||
&:hover {
|
||||
background: $newToolbarButtonHoverColor;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
1px 0px 1px rgba(0,0,0,0.3),
|
||||
0px 0px 1px rgba(0,0,0,0.3);
|
||||
transform: translateX(-50%);
|
||||
z-index: $subtitlesZ;
|
||||
z-index: 7;
|
||||
|
||||
&.lifted {
|
||||
// Lift subtitle above toolbar+dominant speaker box.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,24 +24,6 @@
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows an inline element.
|
||||
*/
|
||||
.show-inline {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a flex element.
|
||||
*/
|
||||
.show-flex {
|
||||
display: -webkit-box !important;
|
||||
display: -moz-box !important;
|
||||
display: -ms-flexbox !important;
|
||||
display: -webkit-flex !important;
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* resets default button styles,
|
||||
* mostly intended to be used on interactive elements that
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
@import "themes/light";
|
||||
|
||||
/**
|
||||
* Style variables
|
||||
*/
|
||||
@@ -10,83 +8,26 @@ $baseFontFamily: -apple-system, BlinkMacSystemFont, 'open_sanslight', 'Helvetica
|
||||
*/
|
||||
|
||||
// Video layout.
|
||||
$thumbnailVideoMargin: 2px;
|
||||
$thumbnailsBorder: 2px;
|
||||
$thumbnailVideoBorder: 2px;
|
||||
$filmstripToggleButtonWidth: 17px;
|
||||
|
||||
|
||||
/**
|
||||
* Color variables.
|
||||
*/
|
||||
$defaultColor: #F1F1F1;
|
||||
$defaultSideBarFontColor: #44A5FF;
|
||||
$defaultSemiDarkColor: #ACACAC;
|
||||
$defaultDarkColor: #2b3d5c;
|
||||
$defaultWarningColor: rgb(215, 121, 118);
|
||||
$participantsPaneBgColor: #141414;
|
||||
|
||||
/**
|
||||
* Toolbar
|
||||
*/
|
||||
$newToolbarBackgroundColor: #131519;
|
||||
$newToolbarButtonHoverColor: rgba(255, 255, 255, 0.2);
|
||||
$newToolbarButtonToggleColor: rgba(255, 255, 255, 0.15);
|
||||
$menuBG:#242528;
|
||||
$newToolbarFontSize: 24px;
|
||||
$newToolbarHangupFontSize: 32px;
|
||||
$newToolbarSize: 48px;
|
||||
$newToolbarSizeMobile: 60px;
|
||||
$newToolbarSizeWithPadding: calc(#{$newToolbarSize} + 24px);
|
||||
$toolbarTitleFontSize: 19px;
|
||||
$overflowMenuItemColor: #fff;
|
||||
|
||||
|
||||
/**
|
||||
* Video layout
|
||||
*/
|
||||
$participantNameColor: #fff;
|
||||
$audioLevelBg: #44A5FF;
|
||||
$audioLevelShadow: rgba(9, 36, 77, 0.9);
|
||||
$videoStateIndicatorColor: $defaultColor;
|
||||
$videoStateIndicatorBackground: $toolbarBackground;
|
||||
$videoStateIndicatorSize: 40px;
|
||||
|
||||
/**
|
||||
* Feedback Modal
|
||||
*/
|
||||
$feedbackContentBg: #fff;
|
||||
$feedbackInputBg: #fff;
|
||||
$feedbackTextColor: #000;
|
||||
$feedbackInputTextColor: #333;
|
||||
$feedbackInputPlaceholderColor: #777;
|
||||
|
||||
/**
|
||||
* Modals
|
||||
*/
|
||||
$modalButtonFontSize: 14px;
|
||||
$modalMockAKInputBackground: #fafbfc;
|
||||
$modalMockAKInputBorder: 1px solid #f4f5f7;
|
||||
$modalTextColor: #333;
|
||||
|
||||
/**
|
||||
* Chat
|
||||
*/
|
||||
$chatActionsSeparatorColor: rgb(173, 105, 112);
|
||||
$chatBackgroundColor: #131519;
|
||||
$chatInputSeparatorColor: #A4B8D1;
|
||||
$chatLobbyActionsSeparatorColor: #6A50D3;
|
||||
$chatLocalMessageBackgroundColor: #484A4F;
|
||||
$chatPrivateMessageBackgroundColor: rgb(153, 69, 77);
|
||||
$chatRemoteMessageBackgroundColor: #242528;
|
||||
$sidebarWidth: 315px;
|
||||
|
||||
/**
|
||||
* Misc.
|
||||
*/
|
||||
$borderRadius: 4px;
|
||||
$happySoftwareBackground: transparent;
|
||||
$desktopAppDragBarHeight: 25px;
|
||||
$scrollHeight: 7px;
|
||||
|
||||
/**
|
||||
@@ -96,38 +37,11 @@ $zindex0: 0;
|
||||
$zindex1: 1;
|
||||
$zindex2: 2;
|
||||
$zindex3: 3;
|
||||
$subtitlesZ: 7;
|
||||
$popoverZ: 8;
|
||||
$reloadZ: 20;
|
||||
$poweredByZ: 100;
|
||||
$ringingZ: 300;
|
||||
$sideToolbarContainerZ: 300;
|
||||
$toolbarZ: 250;
|
||||
$drawerZ: 351;
|
||||
$dropdownZ: 901;
|
||||
$overlayZ: 1016;
|
||||
// Place filmstrip videos over toolbar in order
|
||||
// to make connection info visible.
|
||||
$filmstripVideosZ: $toolbarZ + 1;
|
||||
|
||||
|
||||
/**
|
||||
* Font Colors
|
||||
*/
|
||||
$defaultFontColor: #777;
|
||||
$defaultLightFontColor: #F1F1F1;
|
||||
$defaultDarkFontColor: #000;
|
||||
|
||||
/**
|
||||
* Forms
|
||||
*/
|
||||
//inputs
|
||||
$inputControlEmColor: #f29424;
|
||||
//buttons
|
||||
$linkFontColor: #489afe;
|
||||
$linkHoverFontColor: #287ade;
|
||||
$formPadding: 16px;
|
||||
|
||||
/**
|
||||
* Unsupported browser
|
||||
*/
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
opacity: 0;
|
||||
display: inline-block;
|
||||
@include circle(5px);
|
||||
background: $audioLevelShadow;
|
||||
background: rgba(9, 36, 77, 0.9);
|
||||
margin: 1px 0 1px 0;
|
||||
transition: opacity .25s ease-in-out;
|
||||
-moz-transition: opacity .25s ease-in-out;
|
||||
@@ -205,27 +205,10 @@
|
||||
border-radius: 50%;
|
||||
-webkit-filter: blur(0.5px);
|
||||
filter: blur(0.5px);
|
||||
background: $audioLevelBg;
|
||||
background: #44A5FF;
|
||||
}
|
||||
}
|
||||
|
||||
#reloadPresentation {
|
||||
display: none;
|
||||
position: absolute;
|
||||
color: #FFFFFF;
|
||||
top: 0;
|
||||
right:0;
|
||||
padding: 10px 10px;
|
||||
font-size: 11pt;
|
||||
cursor: pointer;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 5px;
|
||||
background-clip: padding-box;
|
||||
-webkit-border-radius: 5px;
|
||||
-webkit-background-clip: padding-box;
|
||||
z-index: $reloadZ; /*The reload button should appear on top of the header!*/
|
||||
}
|
||||
|
||||
#dominantSpeaker {
|
||||
visibility: hidden;
|
||||
width: 300px;
|
||||
@@ -236,10 +219,6 @@
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
#mixedstream {
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
#dominantSpeakerAvatarContainer,
|
||||
.dynamic-shadow {
|
||||
width: 200px;
|
||||
@@ -287,10 +266,10 @@
|
||||
#avatarContainer {
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
height: 50vh;
|
||||
margin-top: 25vh;
|
||||
height: 50dvh;
|
||||
margin-top: 25dvh;
|
||||
overflow: hidden;
|
||||
width: 50vh;
|
||||
width: 50dvh;
|
||||
|
||||
#avatar {
|
||||
height: 100%;
|
||||
@@ -309,11 +288,6 @@
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.videoMessageFilter {
|
||||
-webkit-filter: grayscale(.5) opacity(0.8);
|
||||
filter: grayscale(.5) opacity(0.8);
|
||||
}
|
||||
|
||||
#remotePresenceMessage,
|
||||
#remoteConnectionMessage {
|
||||
position: absolute;
|
||||
@@ -365,7 +339,7 @@
|
||||
}
|
||||
|
||||
.presence-label {
|
||||
color: $participantNameColor;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-weight: 100;
|
||||
left: 0;
|
||||
|
||||
@@ -10,7 +10,7 @@ body.welcome-page {
|
||||
flex-direction: column;
|
||||
font-family: $welcomePageFontFamily;
|
||||
justify-content: space-between;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
position: relative;
|
||||
|
||||
.header {
|
||||
@@ -61,9 +61,38 @@ body.welcome-page {
|
||||
|
||||
}
|
||||
|
||||
.not-allow-title-character-div {
|
||||
color: #f03e3e;
|
||||
background-color: #fff;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin: 10px 0px 5px 0px;
|
||||
text-align: $welcomePageHeaderTextAlign;
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
.not-allow-title-character-text {
|
||||
float: right;
|
||||
line-height: 1.9;
|
||||
};
|
||||
.jitsi-icon {
|
||||
margin-right: 9px;
|
||||
float: left;
|
||||
|
||||
|
||||
svg {
|
||||
fill:#f03e3e;
|
||||
|
||||
& > *:first-child {
|
||||
fill: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.insecure-room-name-warning {
|
||||
align-items: center;
|
||||
color: $defaultWarningColor;
|
||||
color: rgb(215, 121, 118);
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -75,7 +104,7 @@ body.welcome-page {
|
||||
margin-right: 15px;
|
||||
|
||||
svg {
|
||||
fill: $defaultWarningColor;
|
||||
fill: rgb(215, 121, 118);
|
||||
|
||||
& > *:first-child {
|
||||
fill: none !important;
|
||||
@@ -231,11 +260,6 @@ body.welcome-page {
|
||||
width: $welcomePageWatermarkWidth;
|
||||
height: $welcomePageWatermarkHeight;
|
||||
}
|
||||
|
||||
.watermark.leftwatermarknomargin {
|
||||
width: $welcomePageWatermarkWidth;
|
||||
height: $welcomePageWatermarkHeight;
|
||||
}
|
||||
}
|
||||
|
||||
&.without-content {
|
||||
|
||||
@@ -19,7 +19,7 @@ input[type=range]:focus {
|
||||
* Include the mixin for a range input style.
|
||||
*/
|
||||
@include slider {
|
||||
background: $sliderTrackBackground;
|
||||
background: #474747;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
@@ -33,9 +33,9 @@ input[type=range]:focus {
|
||||
@include slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
background: white;
|
||||
border: 1px solid $sliderThumbBackground;
|
||||
border: 1px solid #3572b0;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0px 0px 1px $sliderThumbBackground;
|
||||
box-shadow: 0px 0px 1px #3572b0;
|
||||
cursor: pointer;
|
||||
height: 14px;
|
||||
margin-top: -4px;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.deep-linking-mobile {
|
||||
background-color: #fff;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
width: 100vw;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
width: auto;
|
||||
|
||||
&__title {
|
||||
border-bottom: 1px solid $inlayBorderColor;
|
||||
border-bottom: 1px solid lighten(#FFFFFF, 10%);
|
||||
color: $unsupportedBrowserTitleColor;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.5px;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
background-size: contain;
|
||||
border: $thumbnailVideoBorder solid transparent;
|
||||
border: 2px solid transparent;
|
||||
border-radius: $borderRadius;
|
||||
margin: 0 $thumbnailVideoMargin;
|
||||
margin: 0 2px;
|
||||
|
||||
&:hover {
|
||||
cursor: hand;
|
||||
|
||||
@@ -36,8 +36,8 @@ $flagsImagePath: "../images/";
|
||||
@import 'modals/invite/info';
|
||||
@import 'modals/screen-share/share-audio';
|
||||
@import 'modals/screen-share/share-screen-warning';
|
||||
@import 'modals/whiteboard';
|
||||
@import 'videolayout_default';
|
||||
@import 'notice';
|
||||
@import 'subject';
|
||||
@import 'popup_menu';
|
||||
@import 'recording';
|
||||
@@ -73,12 +73,9 @@ $flagsImagePath: "../images/";
|
||||
@import 'premeeting/main';
|
||||
@import 'modals/invite/invite_more';
|
||||
@import 'modals/security/security';
|
||||
@import 'e2ee';
|
||||
@import 'responsive';
|
||||
@import 'drawer';
|
||||
@import 'participants-pane';
|
||||
@import 'reactions-menu';
|
||||
@import 'plan-limit';
|
||||
@import 'polls';
|
||||
|
||||
/* Modules END */
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
margin-top: 5px !important;
|
||||
|
||||
.input-control {
|
||||
background: $modalMockAKInputBackground;
|
||||
border: $modalMockAKInputBorder;
|
||||
background: #fafbfc;
|
||||
border: 1px solid #f4f5f7;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
|
||||
7
css/modals/_whiteboard.scss
Normal file
7
css/modals/_whiteboard.scss
Normal file
@@ -0,0 +1,7 @@
|
||||
.whiteboard {
|
||||
|
||||
.excalidraw-wrapper {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,12 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
z-index: $overlayZ;
|
||||
background: $defaultBackground;
|
||||
z-index: 1016;
|
||||
background: #474747;
|
||||
}
|
||||
|
||||
&__container-light {
|
||||
@include transparentBg($defaultBackground, 0.7);
|
||||
@include transparentBg(#474747, 0.7);
|
||||
}
|
||||
|
||||
&__content {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
width: 180px;
|
||||
|
||||
.progress-indicator-fill {
|
||||
background: $reloadProgressBarBg;
|
||||
background: #0074E0;
|
||||
height: 100%;
|
||||
transition: width .5s;
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
z-index: $ringingZ;
|
||||
z-index: 300;
|
||||
@include transparentBg(#283447, 0.95);
|
||||
|
||||
&.solidBG {
|
||||
background: $defaultBackground;
|
||||
background: #040404;
|
||||
}
|
||||
|
||||
&__content {
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/**
|
||||
* Base
|
||||
*/
|
||||
$baseLight: #FFFFFF;
|
||||
|
||||
/**
|
||||
* Controls
|
||||
*/
|
||||
$sliderTrackBackground: #474747;
|
||||
$sliderThumbBackground: #3572b0;
|
||||
|
||||
/**
|
||||
* Buttons
|
||||
*/
|
||||
$buttonBackground: #44A5FF;
|
||||
$buttonHoverBackground: #2c4062;
|
||||
$buttonBorder: transparent;
|
||||
$buttonHoverBorder: transparent;
|
||||
$buttonColor: #eceef1;
|
||||
|
||||
$buttonLightBackground: #f5f5f5;
|
||||
$buttonLightHoverBackground: #e9e9e9;
|
||||
$buttonLightBorder: #ccc;
|
||||
$buttonLightHoverBorder: #999;
|
||||
|
||||
$buttonLinkBackground: transparent;
|
||||
$buttonLinkColor: #0090e8;
|
||||
|
||||
$primaryButtonBackground: #3572b0;
|
||||
$primaryButtonHoverBackground: #2a67a5;
|
||||
$primaryButtonColor: $baseLight;
|
||||
$primaryButtonFontWeight: 400;
|
||||
|
||||
$buttonShadowColor: #192d4f;
|
||||
|
||||
$overlayButtonBg: #0074E0;
|
||||
|
||||
/**
|
||||
* Color variables
|
||||
**/
|
||||
$defaultBackground: #474747;
|
||||
$reloadProgressBarBg: #0074E0;
|
||||
|
||||
/**
|
||||
* Dialog colors
|
||||
**/
|
||||
$dialogErrorText: #344563;
|
||||
|
||||
/**
|
||||
* Inlay colors
|
||||
**/
|
||||
$inlayColorBg: lighten($defaultBackground, 20%);
|
||||
$inlayBorderColor: lighten($baseLight, 10%);
|
||||
|
||||
// Main controls
|
||||
$placeHolderColor: #a7a7a7;
|
||||
$readOnlyInputColor: #a7a7a7;
|
||||
$defaultDarkSelectionColor: #ccc;
|
||||
$buttonFontWeight: 400;
|
||||
$labelFontWeight: 400;
|
||||
$linkFontColor: #3572b0;
|
||||
$linkHoverFontColor: darken(#3572b0, 10%);
|
||||
$errorColor: #c61600;
|
||||
|
||||
|
||||
// Popover colors
|
||||
$popoverFontColor: #ffffff !important;
|
||||
|
||||
// Toolbar
|
||||
$toolbarBackground: rgba(0, 0, 0, 0.5);
|
||||
$toolbarBadgeBackground: #165ECC;
|
||||
$toolbarBadgeColor: #FFFFFF;
|
||||
|
||||
/**
|
||||
* Forms
|
||||
*/
|
||||
$selectBg: $baseLight;
|
||||
@@ -25,11 +25,11 @@
|
||||
}
|
||||
|
||||
&__link {
|
||||
color: $linkFontColor;
|
||||
color: #489afe;
|
||||
@include transition(color .1s ease-out);
|
||||
|
||||
&:hover {
|
||||
color: $linkHoverFontColor;
|
||||
color: #287ade;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
|
||||
|
||||
5
debian/jitsi-meet-tokens.postinst
vendored
5
debian/jitsi-meet-tokens.postinst
vendored
@@ -38,6 +38,11 @@ case "$1" in
|
||||
if [ "$RET" = "false" ] ; then
|
||||
echo "Application secret is mandatory"
|
||||
fi
|
||||
# Not allowed unix special characters in secret: /, \, ", ', `
|
||||
if echo "$RET" | grep -q "[/\\\"\`\']" ; then
|
||||
echo "Application secret contains invalid characters: /, \\, \", ', \`"
|
||||
exit 1
|
||||
fi
|
||||
APP_SECRET=$RET
|
||||
|
||||
PROSODY_HOST_CONFIG="/etc/prosody/conf.avail/$JVB_HOSTNAME.cfg.lua"
|
||||
|
||||
1
debian/jitsi-meet-web.install
vendored
1
debian/jitsi-meet-web.install
vendored
@@ -1,6 +1,5 @@
|
||||
interface_config.js /usr/share/jitsi-meet/
|
||||
*.html /usr/share/jitsi-meet/
|
||||
*.ico /usr/share/jitsi-meet/
|
||||
libs /usr/share/jitsi-meet/
|
||||
static /usr/share/jitsi-meet/
|
||||
css/all.css /usr/share/jitsi-meet/css/
|
||||
|
||||
@@ -51,12 +51,10 @@ VirtualHost "jitmeet.example.com"
|
||||
}
|
||||
av_moderation_component = "avmoderation.jitmeet.example.com"
|
||||
speakerstats_component = "speakerstats.jitmeet.example.com"
|
||||
conference_duration_component = "conferenceduration.jitmeet.example.com"
|
||||
end_conference_component = "endconference.jitmeet.example.com"
|
||||
-- we need bosh
|
||||
modules_enabled = {
|
||||
"bosh";
|
||||
"pubsub";
|
||||
"ping"; -- Enable mod_ping
|
||||
"speakerstats";
|
||||
"external_services";
|
||||
@@ -131,9 +129,6 @@ Component "focus.jitmeet.example.com" "client_proxy"
|
||||
Component "speakerstats.jitmeet.example.com" "speakerstats_component"
|
||||
muc_component = "conference.jitmeet.example.com"
|
||||
|
||||
Component "conferenceduration.jitmeet.example.com" "conference_duration_component"
|
||||
muc_component = "conference.jitmeet.example.com"
|
||||
|
||||
Component "endconference.jitmeet.example.com" "end_conference"
|
||||
muc_component = "conference.jitmeet.example.com"
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@ server {
|
||||
}
|
||||
}
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name jitsi-meet.example.com;
|
||||
|
||||
# Mozilla Guideline v5.4, nginx 1.17.7, OpenSSL 1.1.1d, intermediate configuration
|
||||
|
||||
@@ -38,9 +38,9 @@ apt install token-generator
|
||||
|
||||
mkdir -p /etc/jitsi/meet/jaas
|
||||
|
||||
VPASS_COOKIE=$(echo -n ${JAAS_KEY_ID}| cut -d/ -f1)
|
||||
VPAAS_COOKIE=$(echo -n ${JAAS_KEY_ID}| cut -d/ -f1)
|
||||
cp /usr/share/jitsi-meet-web-config/nginx-jaas.conf /etc/jitsi/meet/jaas
|
||||
sed -i "s/jaas_magic_cookie/${VPASS_COOKIE}/g" /etc/jitsi/meet/jaas/nginx-jaas.conf
|
||||
sed -i "s/jaas_magic_cookie/${VPAAS_COOKIE}/g" /etc/jitsi/meet/jaas/nginx-jaas.conf
|
||||
|
||||
cp /usr/share/jitsi-meet-web-config/8x8.vc-config.js /etc/jitsi/meet/jaas/
|
||||
echo "set \$config_js_location /etc/jitsi/meet/jaas/8x8.vc-config.js;" >> /etc/jitsi/meet/jaas/jaas-vars
|
||||
|
||||
BIN
favicon.ico
BIN
favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 3.6 KiB |
3
globals.d.ts
vendored
3
globals.d.ts
vendored
@@ -19,6 +19,9 @@ declare global {
|
||||
interfaceConfig?: any;
|
||||
JitsiMeetJS?: any;
|
||||
JitsiMeetElectron?: any;
|
||||
PressureObserver?: any;
|
||||
PressureRecord?: any;
|
||||
ReactNativeWebView?: any;
|
||||
// selenium tests handler
|
||||
_sharedVideoPlayer: any;
|
||||
alwaysOnTop: { api: any };
|
||||
|
||||
5
globals.native.d.ts
vendored
5
globals.native.d.ts
vendored
@@ -17,6 +17,11 @@ interface IWindow {
|
||||
innerWidth: number;
|
||||
interfaceConfig: any;
|
||||
location: ILocation;
|
||||
PressureObserver?: any;
|
||||
PressureRecord?: any;
|
||||
ReactNativeWebView?: any;
|
||||
TextDecoder?: any;
|
||||
TextEncoder?: any;
|
||||
self: any;
|
||||
top: any;
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB |
13
images/favicon.svg
Normal file
13
images/favicon.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 8.5 KiB |
23
inlang.config.js
Normal file
23
inlang.config.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @type { import("@inlang/core/config").DefineConfig }
|
||||
*/
|
||||
export async function defineConfig(env) {
|
||||
const { default: i18nextPlugin } = await env.$import(
|
||||
'https://cdn.jsdelivr.net/npm/@inlang/plugin-i18next@2/dist/index.js'
|
||||
);
|
||||
|
||||
const { default: standardLintRules } = await env.$import(
|
||||
'https://cdn.jsdelivr.net/npm/@inlang/plugin-standard-lint-rules@3/dist/index.js'
|
||||
);
|
||||
|
||||
return {
|
||||
referenceLanguage: 'main',
|
||||
plugins: [
|
||||
i18nextPlugin({
|
||||
pathPattern: 'lang/{language}.json',
|
||||
ignore: [ 'languages.json', 'translation-languages.json' ]
|
||||
}),
|
||||
standardLintRules()
|
||||
]
|
||||
};
|
||||
}
|
||||
@@ -107,8 +107,8 @@ var interfaceConfig = {
|
||||
// Names of browsers which should show a warning stating the current browser
|
||||
// has a suboptimal experience. Browsers which are not listed as optimal or
|
||||
// unsupported are considered suboptimal. Valid values are:
|
||||
// chrome, chromium, edge, electron, firefox, nwjs, opera, safari
|
||||
OPTIMAL_BROWSERS: [ 'chrome', 'chromium', 'firefox', 'nwjs', 'electron', 'safari' ],
|
||||
// chrome, chromium, electron, firefox , safari, webkit
|
||||
OPTIMAL_BROWSERS: [ 'chrome', 'chromium', 'firefox', 'electron', 'safari', 'webkit' ],
|
||||
|
||||
POLICY_LOGO: null,
|
||||
PROVIDER_NAME: 'Jitsi',
|
||||
|
||||
2
ios/.xcode.env
Normal file
2
ios/.xcode.env
Normal file
@@ -0,0 +1,2 @@
|
||||
export NODE_BINARY=$(command -v node)
|
||||
export ENTRY_FILE="${PROJECT_DIR}/../../index.ios.js"
|
||||
31
ios/Podfile
31
ios/Podfile
@@ -1,13 +1,15 @@
|
||||
require_relative '../node_modules/react-native/scripts/react_native_pods'
|
||||
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
# Resolve react_native_pods.rb with node to allow for hoisting.
|
||||
require Pod::Executable.execute_command('node', ['-p',
|
||||
'require.resolve(
|
||||
"react-native/scripts/react_native_pods.rb",
|
||||
{paths: [process.argv[1]]},
|
||||
)', __dir__]).strip
|
||||
|
||||
platform :ios, '12.4'
|
||||
platform :ios, '13.4'
|
||||
workspace 'jitsi-meet'
|
||||
|
||||
install! 'cocoapods', :deterministic_uuids => false
|
||||
|
||||
production = ENV["PRODUCTION"] == "1"
|
||||
|
||||
target 'JitsiMeet' do
|
||||
project 'app/app.xcodeproj'
|
||||
|
||||
@@ -26,7 +28,6 @@ target 'JitsiMeetSDK' do
|
||||
flags = get_default_flags()
|
||||
use_react_native!(
|
||||
:path => config[:reactNativePath],
|
||||
:production => production,
|
||||
:hermes_enabled => false,
|
||||
:fabric_enabled => false,
|
||||
# An absolute path to your application root.
|
||||
@@ -46,7 +47,6 @@ target 'JitsiMeetSDK' do
|
||||
|
||||
pod 'CocoaLumberjack', '3.7.2'
|
||||
pod 'ObjectiveDropboxOfficial', '6.2.3'
|
||||
pod 'JitsiWebRTC', '~> 111.0.0'
|
||||
end
|
||||
|
||||
target 'JitsiMeetSDKLite' do
|
||||
@@ -57,24 +57,28 @@ target 'JitsiMeetSDKLite' do
|
||||
|
||||
# React Native and its dependencies
|
||||
#
|
||||
|
||||
|
||||
config = use_native_modules!
|
||||
use_react_native!(
|
||||
:path => config["reactNativePath"],
|
||||
:path => config[:reactNativePath],
|
||||
:hermes_enabled => false,
|
||||
:fabric_enabled => false,
|
||||
# An absolute path to your application root.
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
|
||||
|
||||
# Native pod dependencies
|
||||
#
|
||||
|
||||
|
||||
pod 'CocoaLumberjack', '3.7.2'
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
react_native_post_install(installer)
|
||||
react_native_post_install(
|
||||
installer,
|
||||
use_native_modules![:reactNativePath],
|
||||
:mac_catalyst_enabled => false
|
||||
)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
installer.pods_project.targets.each do |target|
|
||||
# https://github.com/CocoaPods/CocoaPods/issues/11402
|
||||
@@ -85,7 +89,8 @@ post_install do |installer|
|
||||
end
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['SUPPORTS_MACCATALYST'] = 'NO'
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.4'
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.4'
|
||||
config.build_settings['OTHER_SWIFT_FLAGS'] = '$(inherited) -no-verify-emitted-module-interface'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
922
ios/Podfile.lock
922
ios/Podfile.lock
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 52;
|
||||
objectVersion = 54;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@@ -862,7 +862,6 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -892,7 +891,6 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -978,7 +976,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
@@ -1013,6 +1011,7 @@
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
@@ -1025,9 +1024,15 @@
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
@@ -1039,7 +1044,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
@@ -1069,6 +1074,10 @@
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
@@ -1079,8 +1088,14 @@
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>24.0.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
|
||||
@@ -38,12 +38,6 @@
|
||||
[builder setFeatureFlag:@"resolution" withValue:@(360)];
|
||||
[builder setFeatureFlag:@"ios.screensharing.enabled" withBoolean:YES];
|
||||
[builder setFeatureFlag:@"ios.recording.enabled" withBoolean:YES];
|
||||
builder.serverURL = [NSURL URLWithString:@"https://meet.jit.si"];
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
// CallKit has started to create problems starting with the iOS 16 simulator.
|
||||
// Disable it since it never worked in the simulator anyway.
|
||||
[builder setFeatureFlag:@"call-integration.enabled" withBoolean:NO];
|
||||
#endif
|
||||
}];
|
||||
|
||||
[jitsiMeet application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
@@ -131,7 +125,7 @@
|
||||
|
||||
- (UIInterfaceOrientationMask)application:(UIApplication *)application
|
||||
supportedInterfaceOrientationsForWindow:(UIWindow *)window {
|
||||
return [[JitsiMeet sharedInstance] application:application
|
||||
return [[JitsiMeet sharedInstance] application:application
|
||||
supportedInterfaceOrientationsForWindow:window];
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>24.0.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>24.0.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>24.0.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CLKComplicationPrincipalClass</key>
|
||||
|
||||
@@ -629,7 +629,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\nexport NODE_ARGS=\"--max_old_space_size=4096\"\n../../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
shellScript = "WITH_ENVIRONMENT=\"../../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
|
||||
};
|
||||
DE9A016B289A9A9A00E41CBB /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -728,7 +728,7 @@
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
@@ -766,6 +766,7 @@
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
@@ -773,9 +774,15 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
@@ -791,7 +798,7 @@
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
@@ -824,14 +831,24 @@
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OTHER_CFLAGS = "$(inherited)";
|
||||
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
" ",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
|
||||
@@ -70,10 +70,7 @@ RCT_EXPORT_MODULE();
|
||||
= [[NSBundle bundleForClass:self.class] infoDictionary];
|
||||
NSString *sdkVersion = sdkInfoDictionary[@"CFBundleShortVersionString"];
|
||||
if (sdkVersion == nil) {
|
||||
sdkVersion = sdkInfoDictionary[@"CFBundleVersion"];
|
||||
if (sdkVersion == nil) {
|
||||
sdkVersion = @"";
|
||||
}
|
||||
sdkVersion = @"";
|
||||
}
|
||||
|
||||
// build number
|
||||
|
||||
@@ -30,5 +30,6 @@ static NSString * const sendEventNotificationName = @"org.jitsi.meet.SendEvent";
|
||||
- (void)sendChatMessage:(NSString*)message :(NSString*)to ;
|
||||
- (void)sendSetVideoMuted:(BOOL)muted;
|
||||
- (void)sendSetClosedCaptionsEnabled:(BOOL)enabled;
|
||||
- (void)toggleCamera;
|
||||
|
||||
@end
|
||||
|
||||
@@ -27,6 +27,7 @@ static NSString * const closeChatAction = @"org.jitsi.meet.CLOSE_CHAT";
|
||||
static NSString * const sendChatMessageAction = @"org.jitsi.meet.SEND_CHAT_MESSAGE";
|
||||
static NSString * const setVideoMutedAction = @"org.jitsi.meet.SET_VIDEO_MUTED";
|
||||
static NSString * const setClosedCaptionsEnabledAction = @"org.jitsi.meet.SET_CLOSED_CAPTIONS_ENABLED";
|
||||
static NSString * const toggleCameraAction = @"org.jitsi.meet.TOGGLE_CAMERA";
|
||||
|
||||
@implementation ExternalAPI
|
||||
|
||||
@@ -50,7 +51,8 @@ RCT_EXPORT_MODULE();
|
||||
@"CLOSE_CHAT": closeChatAction,
|
||||
@"SEND_CHAT_MESSAGE": sendChatMessageAction,
|
||||
@"SET_VIDEO_MUTED" : setVideoMutedAction,
|
||||
@"SET_CLOSED_CAPTIONS_ENABLED": setClosedCaptionsEnabledAction
|
||||
@"SET_CLOSED_CAPTIONS_ENABLED": setClosedCaptionsEnabledAction,
|
||||
@"TOGGLE_CAMERA": toggleCameraAction
|
||||
};
|
||||
};
|
||||
|
||||
@@ -75,7 +77,8 @@ RCT_EXPORT_MODULE();
|
||||
closeChatAction,
|
||||
sendChatMessageAction,
|
||||
setVideoMutedAction,
|
||||
setClosedCaptionsEnabledAction
|
||||
setClosedCaptionsEnabledAction,
|
||||
toggleCameraAction
|
||||
];
|
||||
}
|
||||
|
||||
@@ -173,4 +176,8 @@ RCT_EXPORT_METHOD(sendEvent:(NSString *)name
|
||||
[self sendEventWithName:setClosedCaptionsEnabledAction body:data];
|
||||
}
|
||||
|
||||
- (void)toggleCamera {
|
||||
[self sendEventWithName:toggleCameraAction body:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>9.0.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
@@ -46,5 +46,6 @@
|
||||
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to;
|
||||
- (void)setVideoMuted:(BOOL)muted;
|
||||
- (void)setClosedCaptionsEnabled:(BOOL)enabled;
|
||||
- (void)toggleCamera;
|
||||
|
||||
@end
|
||||
|
||||
@@ -138,6 +138,11 @@ static NSString *const PiPEnabledFeatureFlag = @"pip.enabled";
|
||||
[externalAPI sendSetClosedCaptionsEnabled:enabled];
|
||||
}
|
||||
|
||||
- (void)toggleCamera {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI toggleCamera];
|
||||
}
|
||||
|
||||
#pragma mark Private methods
|
||||
|
||||
- (void)registerObservers {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>9.0.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
@@ -197,7 +197,7 @@ static CXProviderConfiguration *_providerConfiguration = nil;
|
||||
|
||||
+ (BOOL)hasActiveCallForUUID:(nonnull NSString *)callUUID {
|
||||
CXCall *activeCallForUUID = [[self.callController calls] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(CXCall *evaluatedObject, NSDictionary<NSString *,id> *bindings) {
|
||||
return evaluatedObject.UUID.UUIDString == callUUID;
|
||||
return [evaluatedObject.UUID.UUIDString isEqualToString:callUUID];
|
||||
}]].firstObject;
|
||||
|
||||
if (!activeCallForUUID) {
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
"dsb": "Dolnoserbšćina",
|
||||
"el": "Ελληνικά",
|
||||
"en": "English",
|
||||
"enGB": "English (United Kingdom)",
|
||||
"eo": "Esperanto",
|
||||
"es": "Español",
|
||||
"esUS": "Español (Latinoamérica)",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user