mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-30 11:22:31 +00:00
Compare commits
712 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd6e905b95 | ||
|
|
ddaf7a3180 | ||
|
|
47aa51a58c | ||
|
|
66f7b9de53 | ||
|
|
bab87be9c9 | ||
|
|
6549d47233 | ||
|
|
2063e66b8e | ||
|
|
4dd241712d | ||
|
|
a574d5ec79 | ||
|
|
4b2b85bd12 | ||
|
|
77ab1ea8ed | ||
|
|
05e47ade7c | ||
|
|
6c78ec9099 | ||
|
|
4c5afc0b5e | ||
|
|
2e31ab9dca | ||
|
|
02787b1394 | ||
|
|
2476a06237 | ||
|
|
2d8909911e | ||
|
|
d06b847319 | ||
|
|
b517f614b3 | ||
|
|
10f77f1fbc | ||
|
|
77b89ece4a | ||
|
|
129264c3c9 | ||
|
|
96c5a9abd1 | ||
|
|
93ef2337ae | ||
|
|
854a077684 | ||
|
|
f903a7ae6e | ||
|
|
9013881f76 | ||
|
|
b6e7e0a19e | ||
|
|
ae42e42534 | ||
|
|
21e2504cf9 | ||
|
|
7a9ba79783 | ||
|
|
1f5a3b5b0f | ||
|
|
fe2aff4f3c | ||
|
|
d847f6f96b | ||
|
|
45ce467dcd | ||
|
|
2b81fa6bd3 | ||
|
|
6f6100ceb2 | ||
|
|
62cd1c29d7 | ||
|
|
64869e8970 | ||
|
|
29464e6886 | ||
|
|
5ed92f2bc5 | ||
|
|
048d12de24 | ||
|
|
40c240c7ca | ||
|
|
289c1907e7 | ||
|
|
35adea48ae | ||
|
|
d72114d5bc | ||
|
|
2f6b6ca837 | ||
|
|
615bbdc39b | ||
|
|
ef97778158 | ||
|
|
2885f39355 | ||
|
|
ae256b23b8 | ||
|
|
412aa83268 | ||
|
|
f4c61e4760 | ||
|
|
f313fb81d0 | ||
|
|
975af80e27 | ||
|
|
0a30a51bab | ||
|
|
54e28e223c | ||
|
|
a4def96763 | ||
|
|
dad4fb9e06 | ||
|
|
3772b9a5ae | ||
|
|
89b9c75242 | ||
|
|
b24b60b735 | ||
|
|
486a1f6511 | ||
|
|
80b3f1d7d4 | ||
|
|
421b21edeb | ||
|
|
a58b0d9a85 | ||
|
|
1aca8ab985 | ||
|
|
f9daba728f | ||
|
|
fbb6456317 | ||
|
|
52ead26bed | ||
|
|
8d1da83e3c | ||
|
|
5453b615f5 | ||
|
|
81a7301a3e | ||
|
|
1138b7779b | ||
|
|
2fd653d928 | ||
|
|
012c9fb329 | ||
|
|
fdf95444e9 | ||
|
|
919c60b3d2 | ||
|
|
e02c4e8f7f | ||
|
|
3fd9ce5f11 | ||
|
|
93022b3281 | ||
|
|
5d63b31071 | ||
|
|
4432f727a4 | ||
|
|
6f1bdb513a | ||
|
|
ad144e6fd3 | ||
|
|
076d77a982 | ||
|
|
5afdda7568 | ||
|
|
6cb57c472c | ||
|
|
e026bac42c | ||
|
|
b29e48d471 | ||
|
|
99cb5e6c40 | ||
|
|
01834903c2 | ||
|
|
2929317972 | ||
|
|
57865d74c6 | ||
|
|
f8f331a576 | ||
|
|
c610e955cd | ||
|
|
53899947a9 | ||
|
|
bf23107e7a | ||
|
|
6784921429 | ||
|
|
a5ca57b8e4 | ||
|
|
fa9703a41e | ||
|
|
e82ef6de4b | ||
|
|
e0cad48734 | ||
|
|
fff6636a9e | ||
|
|
077602c427 | ||
|
|
b2f7b3be6c | ||
|
|
29fd5df16a | ||
|
|
f324122d93 | ||
|
|
82d4628976 | ||
|
|
8ab02d598c | ||
|
|
5b23072bd0 | ||
|
|
7b4cc552fb | ||
|
|
eb188ff02a | ||
|
|
b40c24db70 | ||
|
|
a855f76377 | ||
|
|
c481e7ede4 | ||
|
|
17b4c2156a | ||
|
|
ca6579e032 | ||
|
|
f3e99624e9 | ||
|
|
3b5c2d9b0b | ||
|
|
bab9ddbb57 | ||
|
|
8d4193ce1e | ||
|
|
7d2cf3dbf2 | ||
|
|
9309d61c00 | ||
|
|
4089702060 | ||
|
|
bf2254c753 | ||
|
|
641b52c51d | ||
|
|
083037d152 | ||
|
|
a3200a172f | ||
|
|
ebff46971d | ||
|
|
657aefefc2 | ||
|
|
683d6eb208 | ||
|
|
a62fa3f833 | ||
|
|
88f1ef27c5 | ||
|
|
95ecf73c71 | ||
|
|
a96908dd7c | ||
|
|
a103b0e5bd | ||
|
|
d67622f6f2 | ||
|
|
ecec65f7af | ||
|
|
447be3f6a9 | ||
|
|
1255b4dcf3 | ||
|
|
47e420f10e | ||
|
|
698aa8db3e | ||
|
|
50bad7bbca | ||
|
|
9d4e6c2d0d | ||
|
|
f3e1fbfdce | ||
|
|
6287c14dd3 | ||
|
|
8a7ee9bae5 | ||
|
|
38677dbe0a | ||
|
|
1900c42098 | ||
|
|
6deb0a6385 | ||
|
|
ce567955f0 | ||
|
|
9d2f1ce8e0 | ||
|
|
841ab8c052 | ||
|
|
3e4f45dc7b | ||
|
|
19cff49ab1 | ||
|
|
a06c3fe715 | ||
|
|
5580301ef7 | ||
|
|
69b0ac4686 | ||
|
|
9f7eb6b657 | ||
|
|
386bdbfc22 | ||
|
|
a45453e391 | ||
|
|
07554a156b | ||
|
|
70c3c8db13 | ||
|
|
9bb1c36508 | ||
|
|
a93ca9d7c4 | ||
|
|
d2f20c49af | ||
|
|
c5f82d4f20 | ||
|
|
36a3e700e1 | ||
|
|
77464ddcc4 | ||
|
|
36ce5a1661 | ||
|
|
23c831e9b0 | ||
|
|
e6fbeb9458 | ||
|
|
e15a59c994 | ||
|
|
f5e1a97d64 | ||
|
|
cd25652182 | ||
|
|
2bf0b1922f | ||
|
|
469406d7cd | ||
|
|
60679aa2d3 | ||
|
|
319e8d1e4b | ||
|
|
40b8d6168b | ||
|
|
753d0399c9 | ||
|
|
2475aff21a | ||
|
|
121aabeb25 | ||
|
|
086f01aa5b | ||
|
|
6b6920693b | ||
|
|
566b3ba2d5 | ||
|
|
7373123166 | ||
|
|
cc312877f4 | ||
|
|
eb8b6159ec | ||
|
|
f9d8feacd2 | ||
|
|
f5668b6e8b | ||
|
|
4219d9ad4d | ||
|
|
d68b9b1cad | ||
|
|
8f0b9575c4 | ||
|
|
f780207c22 | ||
|
|
ce19e6d40b | ||
|
|
b108db832f | ||
|
|
e4283e61dd | ||
|
|
50e2458124 | ||
|
|
329df31811 | ||
|
|
fce39be9d2 | ||
|
|
6c5a9ea199 | ||
|
|
196192c97f | ||
|
|
71f358c62a | ||
|
|
7aa7e76ccd | ||
|
|
cd77b6bbe4 | ||
|
|
e94df6799e | ||
|
|
2e92818b53 | ||
|
|
8a3129f7bf | ||
|
|
eb03642ea6 | ||
|
|
c436e48956 | ||
|
|
58db02bab8 | ||
|
|
abc1f3d33b | ||
|
|
b2166d9874 | ||
|
|
901a13a99a | ||
|
|
1e15d9421b | ||
|
|
9252bbb036 | ||
|
|
f1bae8bc10 | ||
|
|
5a54511d2c | ||
|
|
61764273b2 | ||
|
|
e39f38f75b | ||
|
|
2d25f48c72 | ||
|
|
2cb727fc58 | ||
|
|
c069c0d7c3 | ||
|
|
5de69d501d | ||
|
|
599c88a71d | ||
|
|
5476321df6 | ||
|
|
076b6a2a7e | ||
|
|
8b9df0cd37 | ||
|
|
44f5de3db4 | ||
|
|
fb69225d42 | ||
|
|
32df284277 | ||
|
|
253679cfb9 | ||
|
|
057c19f4dd | ||
|
|
6159a23c55 | ||
|
|
1685c39c5d | ||
|
|
2cecc61b97 | ||
|
|
df2262ae53 | ||
|
|
d61deab163 | ||
|
|
e7eab72c0c | ||
|
|
c1e803c6e3 | ||
|
|
dc1f20e059 | ||
|
|
61ee9af304 | ||
|
|
d75de3642e | ||
|
|
1ae1729545 | ||
|
|
8cea505417 | ||
|
|
b0a96b32d2 | ||
|
|
dac9b5e244 | ||
|
|
d15cfd845a | ||
|
|
91e4ac1665 | ||
|
|
fda42e5230 | ||
|
|
142d4441c1 | ||
|
|
5814c4dda7 | ||
|
|
8c1dc03363 | ||
|
|
ff6fc198f1 | ||
|
|
f1a0012fc1 | ||
|
|
85522aea25 | ||
|
|
000c370c64 | ||
|
|
a762d585b8 | ||
|
|
ded8f22363 | ||
|
|
c3e1c9d568 | ||
|
|
8901132af9 | ||
|
|
71f92f6e17 | ||
|
|
76166df81a | ||
|
|
eb2ba39289 | ||
|
|
048b089acd | ||
|
|
b774f18f80 | ||
|
|
dbe4e6a784 | ||
|
|
d2e52d2c2a | ||
|
|
b5ad984dab | ||
|
|
81ce664ad7 | ||
|
|
181ef92e1f | ||
|
|
79dbc2d1ee | ||
|
|
f56ce78b9d | ||
|
|
8269b88796 | ||
|
|
252ef4604a | ||
|
|
fc816aa149 | ||
|
|
6de18fe82d | ||
|
|
5b7e3bb2d7 | ||
|
|
bc08b38791 | ||
|
|
6613f630d7 | ||
|
|
719b6d68c8 | ||
|
|
6a62c5120f | ||
|
|
64270f3015 | ||
|
|
cb621f8e32 | ||
|
|
3c80cfddd7 | ||
|
|
557f6defb8 | ||
|
|
52fa36f930 | ||
|
|
b050e5f5e8 | ||
|
|
bf8d83953b | ||
|
|
f16bf466eb | ||
|
|
29ea811527 | ||
|
|
435d034fdb | ||
|
|
419baa7ab7 | ||
|
|
9eb7b7bb01 | ||
|
|
19ee989cda | ||
|
|
ab1dcc5375 | ||
|
|
3047b4c8c4 | ||
|
|
2afce3d151 | ||
|
|
1cea9b1786 | ||
|
|
2b7299ae05 | ||
|
|
4b50f13e96 | ||
|
|
c639acebcf | ||
|
|
1a34ed9a2d | ||
|
|
0939e207eb | ||
|
|
8c3ea05ae6 | ||
|
|
daf8a929b1 | ||
|
|
2f3df2c66f | ||
|
|
d8d1f8331e | ||
|
|
0e69336f94 | ||
|
|
ede8ae6cb9 | ||
|
|
7e57156d2a | ||
|
|
6742435487 | ||
|
|
99f34aaef4 | ||
|
|
69f9838c03 | ||
|
|
dbfd24261d | ||
|
|
2305ae85a0 | ||
|
|
31a30f1118 | ||
|
|
eacf7addb2 | ||
|
|
2cf788ebee | ||
|
|
6bd3ed5ae4 | ||
|
|
b511f4b8df | ||
|
|
ead019f71b | ||
|
|
7a97d15e89 | ||
|
|
1acb99d763 | ||
|
|
adbe990867 | ||
|
|
a4367567ab | ||
|
|
7f56cbc4ce | ||
|
|
d636d084c8 | ||
|
|
298567be48 | ||
|
|
c233629e51 | ||
|
|
75b5702a7e | ||
|
|
540f01d47e | ||
|
|
5c7ed6a8b3 | ||
|
|
3c5d33fefa | ||
|
|
be04236834 | ||
|
|
ec1bfe73b3 | ||
|
|
d2ed9ffef6 | ||
|
|
6141ff78f8 | ||
|
|
c6a75fb9ed | ||
|
|
3438438219 | ||
|
|
7cedea6740 | ||
|
|
69f26c8a38 | ||
|
|
92a4750d0e | ||
|
|
370a884765 | ||
|
|
877fc98eef | ||
|
|
7bed0b36bd | ||
|
|
cd5aed37e9 | ||
|
|
b8dad082df | ||
|
|
f84f98e8e5 | ||
|
|
d1328d68f2 | ||
|
|
43d5c1e3ba | ||
|
|
22ed00724d | ||
|
|
0b095f36eb | ||
|
|
327376d85e | ||
|
|
f28bd67ff4 | ||
|
|
3a54c3418b | ||
|
|
b6026dcd04 | ||
|
|
2eff0d8f78 | ||
|
|
1ab7989a1a | ||
|
|
b8c6c2381c | ||
|
|
3f9202ce04 | ||
|
|
965b413d26 | ||
|
|
1cb2025951 | ||
|
|
4decb41a1e | ||
|
|
8a79d200c8 | ||
|
|
2f9436afb1 | ||
|
|
66dc158c22 | ||
|
|
921ed99676 | ||
|
|
bd612ef8ea | ||
|
|
b93c69c24e | ||
|
|
cc6326a23f | ||
|
|
d6776f234d | ||
|
|
2763c4fdee | ||
|
|
2aaf0ed543 | ||
|
|
17f335f0c9 | ||
|
|
e280d1d963 | ||
|
|
a43472985b | ||
|
|
e5187de9c3 | ||
|
|
b296776ed7 | ||
|
|
93bc4019ad | ||
|
|
a4c20469cd | ||
|
|
196fd455cd | ||
|
|
e75bacae4a | ||
|
|
d238386085 | ||
|
|
a1634eb813 | ||
|
|
566d76a28d | ||
|
|
494afde82a | ||
|
|
51ba5d31aa | ||
|
|
5f88b117ae | ||
|
|
4500a5aba5 | ||
|
|
fb64d1b68b | ||
|
|
a39d8d35a2 | ||
|
|
6bc12766f9 | ||
|
|
ecf9bee7d0 | ||
|
|
6b5245be44 | ||
|
|
6b71122cac | ||
|
|
f060ab9d26 | ||
|
|
df3dd2b14e | ||
|
|
be9e1136de | ||
|
|
e2337e8db8 | ||
|
|
293b6fa908 | ||
|
|
34da0ff99e | ||
|
|
06713a4ffa | ||
|
|
94813163e8 | ||
|
|
bb1eade1f0 | ||
|
|
2f0ca6c839 | ||
|
|
45bbf06a85 | ||
|
|
042007adb5 | ||
|
|
dc73d1e328 | ||
|
|
db4c9666c3 | ||
|
|
45cfc0e112 | ||
|
|
fa9aab953d | ||
|
|
c16f652378 | ||
|
|
6f3ae47a2e | ||
|
|
6afbff9b36 | ||
|
|
c7b6af1df3 | ||
|
|
308faf71bf | ||
|
|
78efddc447 | ||
|
|
d370e79237 | ||
|
|
97b01b910e | ||
|
|
3bb28c4090 | ||
|
|
589baab2ae | ||
|
|
85fe5cf31e | ||
|
|
7fabb33733 | ||
|
|
5342712019 | ||
|
|
deb0e36f84 | ||
|
|
65e3886d43 | ||
|
|
337435e738 | ||
|
|
7a1f5885d0 | ||
|
|
253f43ab9e | ||
|
|
f17a4387d9 | ||
|
|
7ac43abd03 | ||
|
|
67b44f4406 | ||
|
|
7f601db349 | ||
|
|
26423f8e76 | ||
|
|
392d694563 | ||
|
|
107687583d | ||
|
|
0085544a36 | ||
|
|
79cab9e7df | ||
|
|
1be9107ac7 | ||
|
|
762d59a4ad | ||
|
|
b213c445de | ||
|
|
05079e5480 | ||
|
|
b087b54575 | ||
|
|
c586fd9592 | ||
|
|
b966796d0c | ||
|
|
734ab449a6 | ||
|
|
869a149ccd | ||
|
|
90a831074e | ||
|
|
3be2a2d607 | ||
|
|
ec61563e8a | ||
|
|
8459e38b30 | ||
|
|
916fd64178 | ||
|
|
34d7ff78c0 | ||
|
|
a99e122801 | ||
|
|
4735911b6c | ||
|
|
82f2060ebf | ||
|
|
0897db3efc | ||
|
|
4d7d1a84bb | ||
|
|
9f133b3a28 | ||
|
|
f24e02425f | ||
|
|
7d2771167a | ||
|
|
49fb2bbaa1 | ||
|
|
ca7ece97bd | ||
|
|
0c68a1eb51 | ||
|
|
8bab15d13a | ||
|
|
914ace576a | ||
|
|
9f80448f92 | ||
|
|
d5793c2445 | ||
|
|
805afd33d2 | ||
|
|
f22315cf92 | ||
|
|
0ee2378ff0 | ||
|
|
8157e528c3 | ||
|
|
ca16f54dc9 | ||
|
|
1825ab6c41 | ||
|
|
3d5c08d86f | ||
|
|
f2babbf994 | ||
|
|
403b9043b6 | ||
|
|
561271d926 | ||
|
|
e21da045ad | ||
|
|
88b45c9182 | ||
|
|
33a771fe8c | ||
|
|
a01f4468a0 | ||
|
|
9361e3209b | ||
|
|
6c6ed8d7a8 | ||
|
|
bffcc9092b | ||
|
|
728cf900e0 | ||
|
|
cf63dcb8f4 | ||
|
|
1556f1b81a | ||
|
|
598d3764dd | ||
|
|
cff91756d0 | ||
|
|
f1384eb117 | ||
|
|
5c0c3c2e0d | ||
|
|
b123d140fa | ||
|
|
a4ffd8546e | ||
|
|
1ab3309323 | ||
|
|
0b2db71a6d | ||
|
|
087ca5e6e4 | ||
|
|
f9927e4cd7 | ||
|
|
f31f9e1979 | ||
|
|
25cbe888a1 | ||
|
|
6a43ecc1dc | ||
|
|
082c4c325d | ||
|
|
4878874a68 | ||
|
|
178e87d408 | ||
|
|
5a4306ee38 | ||
|
|
4fcab33afb | ||
|
|
99669dc869 | ||
|
|
bf34c9ab19 | ||
|
|
f6f4ebf185 | ||
|
|
b500c9dcde | ||
|
|
d5670a2b4f | ||
|
|
ee3f82bf0c | ||
|
|
a07a1cfe93 | ||
|
|
16c45c15c8 | ||
|
|
5d5d6c3068 | ||
|
|
19399ec123 | ||
|
|
3c27f15490 | ||
|
|
607073c669 | ||
|
|
f92ee57f9c | ||
|
|
32331d7465 | ||
|
|
88685c43fb | ||
|
|
348573b254 | ||
|
|
1a05991b8c | ||
|
|
c3f2390642 | ||
|
|
7cf8902fdd | ||
|
|
3e4fb82d58 | ||
|
|
057dc0e4d2 | ||
|
|
ce4cbacceb | ||
|
|
af4f122602 | ||
|
|
b7f5b8ecd2 | ||
|
|
d15e51adbd | ||
|
|
affef1ac66 | ||
|
|
7f95dbb6d6 | ||
|
|
8065da61c7 | ||
|
|
b6df08f072 | ||
|
|
73752618a3 | ||
|
|
3c7829a457 | ||
|
|
0b0bbcf194 | ||
|
|
3cd29fd63e | ||
|
|
c486dc07db | ||
|
|
b48772f898 | ||
|
|
21533f0261 | ||
|
|
1ecfa3a78e | ||
|
|
921c27165d | ||
|
|
6fa94b0bb4 | ||
|
|
3f3a074e02 | ||
|
|
ecb57774ed | ||
|
|
1e82f1fb1a | ||
|
|
b4b54108c5 | ||
|
|
6903ccf009 | ||
|
|
6e45643cce | ||
|
|
379b26a753 | ||
|
|
e8faa99ff0 | ||
|
|
62d2c9f633 | ||
|
|
311c404a1a | ||
|
|
b17a3a9d86 | ||
|
|
5477e46489 | ||
|
|
7e170fe0d0 | ||
|
|
bbbc9d1f46 | ||
|
|
084905545f | ||
|
|
d542b05bc4 | ||
|
|
58b73d8dbd | ||
|
|
471853ef15 | ||
|
|
a0070c34f7 | ||
|
|
5bc8bc8b64 | ||
|
|
ea04c5e96e | ||
|
|
d4e2f17acc | ||
|
|
4dcc4b3711 | ||
|
|
80081ce31c | ||
|
|
5314d779ed | ||
|
|
cf7c39d3e5 | ||
|
|
4e4f91f184 | ||
|
|
972a13f3fe | ||
|
|
2ec3cfcb9e | ||
|
|
a3d89ea66f | ||
|
|
487fd5de1f | ||
|
|
bed94e6698 | ||
|
|
939fdf6c8e | ||
|
|
0f5412715a | ||
|
|
dd8f2f53f3 | ||
|
|
92df4bfbbb | ||
|
|
b97798e1ca | ||
|
|
f488ef1e5c | ||
|
|
c4fcfb8666 | ||
|
|
0ccb088c05 | ||
|
|
a7f4d9cadd | ||
|
|
716c6cc567 | ||
|
|
153f67d852 | ||
|
|
8745f07052 | ||
|
|
0a467f78ee | ||
|
|
1e8cc9d085 | ||
|
|
65e7fa571a | ||
|
|
68b471ba29 | ||
|
|
c09a3524c7 | ||
|
|
101bd637b0 | ||
|
|
078503b1b3 | ||
|
|
8c4e9f823d | ||
|
|
fe1f858ef9 | ||
|
|
dd7b953a92 | ||
|
|
1f2aaa8dc0 | ||
|
|
80bf228a65 | ||
|
|
62e0f09f98 | ||
|
|
6654feacee | ||
|
|
3d4defd799 | ||
|
|
e15bf2d4dd | ||
|
|
6de935b372 | ||
|
|
3397b9cbc9 | ||
|
|
45626a0d23 | ||
|
|
b7bccb0801 | ||
|
|
475ec6d427 | ||
|
|
a28b155c41 | ||
|
|
5f44c7580d | ||
|
|
3d1eb5282c | ||
|
|
10935ec692 | ||
|
|
95a0a8418f | ||
|
|
0a5e914862 | ||
|
|
02ff359de2 | ||
|
|
fecac0322e | ||
|
|
bd1c3332ea | ||
|
|
5ee0738e45 | ||
|
|
c3518208e1 | ||
|
|
21116c09f4 | ||
|
|
875a9cbaf3 | ||
|
|
5fd050b77f | ||
|
|
fee6ecc82d | ||
|
|
2ba57730cd | ||
|
|
78c304cba8 | ||
|
|
b082354773 | ||
|
|
8bd377098d | ||
|
|
7d6990b3f8 | ||
|
|
a51e97f318 | ||
|
|
bc65d21ce4 | ||
|
|
e9236fd9ff | ||
|
|
c4dff9a75e | ||
|
|
edf0a35392 | ||
|
|
f291dc90f4 | ||
|
|
ea0f9e7934 | ||
|
|
480b6f7cdc | ||
|
|
19f91bea84 | ||
|
|
59420ea1a8 | ||
|
|
d969a5311e | ||
|
|
3e025c9f01 | ||
|
|
1e558b143f | ||
|
|
5cfc0378f7 | ||
|
|
6ad8ad3506 | ||
|
|
c2488f4071 | ||
|
|
a63a344f6e | ||
|
|
53acd386f0 | ||
|
|
4469917d45 | ||
|
|
f967efa3e4 | ||
|
|
dc6ee21b5d | ||
|
|
481e8634e0 | ||
|
|
bca746cfc4 | ||
|
|
29663bcec2 | ||
|
|
bd7b2c6e7a | ||
|
|
eee80941b0 | ||
|
|
06c571cafb | ||
|
|
5c3ea96131 | ||
|
|
e6bf6a09f4 | ||
|
|
6e6a3b2f72 | ||
|
|
cbfa5e38b3 | ||
|
|
94c55f7aa4 | ||
|
|
9843aca00a | ||
|
|
816e991ae5 | ||
|
|
cfbdbd4783 | ||
|
|
f83ad5af27 | ||
|
|
a5afd011a1 | ||
|
|
c88891da5b | ||
|
|
b1af0c800b | ||
|
|
146d2c8b66 | ||
|
|
a18e193611 | ||
|
|
6ae0bc36cc | ||
|
|
b1410c34e0 | ||
|
|
070991d7ef | ||
|
|
874f59f0ff | ||
|
|
fa547b5aac | ||
|
|
d27580c016 | ||
|
|
2093ef1ea2 | ||
|
|
75540a588d | ||
|
|
fe51b4c56a | ||
|
|
c7c42f6983 | ||
|
|
68df1b1281 | ||
|
|
00efcfaae5 | ||
|
|
c6b194a073 | ||
|
|
8ac44dfbb3 | ||
|
|
ea2ab9edc0 | ||
|
|
9d27c705f6 | ||
|
|
ebdd9755ba | ||
|
|
fa2a8c5084 | ||
|
|
ac2d73b57c | ||
|
|
93902e6364 | ||
|
|
42163731b3 | ||
|
|
01ce04fe9b | ||
|
|
5d29363764 | ||
|
|
bfe8bc9b73 | ||
|
|
a6f6235dd0 | ||
|
|
ee6bf011e9 | ||
|
|
bea8a7f984 | ||
|
|
2edca5dacb | ||
|
|
69ac73c556 | ||
|
|
89556ecd66 | ||
|
|
462f91f070 | ||
|
|
d29a77b15f | ||
|
|
c31fe521c4 | ||
|
|
8f6f542e9c | ||
|
|
69d9e7d405 | ||
|
|
5e6748a88a | ||
|
|
8bc70f9c87 |
@@ -14,3 +14,12 @@ trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
|
||||
[*.{java,kt}]
|
||||
indent_size = 4
|
||||
|
||||
[*.xml]
|
||||
indent_size = 2
|
||||
|
||||
[*.{swift,m,mm,h}]
|
||||
indent_size = 4
|
||||
|
||||
@@ -17,3 +17,8 @@ react/features/face-landmarks/resources/*
|
||||
|
||||
# Not worth it.
|
||||
actionTypes.ts
|
||||
|
||||
# It's not complete until all files are copied at build time.
|
||||
react-native-sdk/
|
||||
|
||||
*.d.ts
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
module.exports = {
|
||||
'extends': [
|
||||
extends: [
|
||||
'@jitsi/eslint-config'
|
||||
],
|
||||
'ignorePatterns': [ '*.d.ts' ]
|
||||
]
|
||||
};
|
||||
|
||||
12
.github/dependabot.yml
vendored
Normal file
12
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
version: 2
|
||||
updates:
|
||||
# Monitor GitHub Actions versions
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
labels:
|
||||
- "dependencies"
|
||||
- "github-actions"
|
||||
commit-message:
|
||||
prefix: "chore(ci)"
|
||||
2
.github/workflows/ci-lua.yml
vendored
2
.github/workflows/ci-lua.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
name: Luacheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install luarocks
|
||||
run: sudo apt-get --install-recommends -y install luarocks
|
||||
|
||||
47
.github/workflows/ci.yml
vendored
47
.github/workflows/ci.yml
vendored
@@ -7,8 +7,8 @@ jobs:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
npm -v
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v41
|
||||
uses: jitsi/changed-files@main
|
||||
- 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"
|
||||
@@ -42,8 +42,8 @@ jobs:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
@@ -59,8 +59,8 @@ jobs:
|
||||
name: Build mobile bundle (Android)
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
@@ -74,8 +74,8 @@ jobs:
|
||||
name: Build mobile bundle (iOS)
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
@@ -103,10 +103,10 @@ jobs:
|
||||
android-sdk-build:
|
||||
name: Build mobile SDK (Android)
|
||||
runs-on: ubuntu-latest
|
||||
container: reactnativecommunity/react-native-android:v13.0
|
||||
container: reactnativecommunity/react-native-android:v15.0
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
@@ -119,12 +119,15 @@ jobs:
|
||||
cd android
|
||||
./gradlew :sdk:clean
|
||||
./gradlew :sdk:assembleRelease
|
||||
- run: |
|
||||
git config --global --add safe.directory /__w/jitsi-meet/jitsi-meet
|
||||
git clean -dfx
|
||||
ios-sdk-build:
|
||||
name: Build mobile SDK (iOS)
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
@@ -139,6 +142,12 @@ jobs:
|
||||
xcode-select -p
|
||||
sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
|
||||
xcodebuild -version
|
||||
- name: clean Xcode
|
||||
run: |
|
||||
rm -rf ios/sdk/out
|
||||
xcodebuild clean \
|
||||
-workspace ios/jitsi-meet.xcworkspace \
|
||||
-scheme JitsiMeetSDK
|
||||
- name: setup-cocoapods
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
@@ -149,15 +158,13 @@ jobs:
|
||||
working-directory: ./ios
|
||||
run: bundle exec pod install --repo-update --deployment
|
||||
- run: |
|
||||
xcodebuild clean \
|
||||
-workspace ios/jitsi-meet.xcworkspace \
|
||||
-scheme JitsiMeetSDK
|
||||
xcodebuild -downloadPlatform iOS -buildVersion 18.2
|
||||
xcodebuild archive \
|
||||
-workspace ios/jitsi-meet.xcworkspace \
|
||||
-scheme JitsiMeetSDK \
|
||||
-configuration Release \
|
||||
-sdk iphoneos \
|
||||
-destination='generic/platform=iOS' \
|
||||
-destination 'generic/platform=iOS' \
|
||||
-archivePath ios/sdk/out/ios-device \
|
||||
SKIP_INSTALL=NO \
|
||||
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
|
||||
@@ -169,8 +176,8 @@ jobs:
|
||||
name: Test Debian packages build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
|
||||
267
CLAUDE.md
Normal file
267
CLAUDE.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Building and Development
|
||||
- `npm run lint-fix` - Automatically fix linting issues
|
||||
- `npm run tsc:ci` - Run TypeScript checks for both web and native platforms
|
||||
- `npm run tsc:web` - TypeScript check for web platform only
|
||||
- `npm run tsc:native` - TypeScript check for native platform only
|
||||
- `npm run lint:ci` - Run ESLint without type checking
|
||||
- `make dev` - Start development server with webpack-dev-server
|
||||
- `make compile` - Build production bundles
|
||||
- `make clean` - Clean build directory
|
||||
- `make all` - Full build (compile + deploy)
|
||||
|
||||
### Testing
|
||||
- `npm test` - Run full test suite using WebDriverIO
|
||||
- `npm run test-single -- <spec-file>` - Run single test file
|
||||
- `npm run test-dev` - Run tests against development environment
|
||||
- `npm run test-dev-single -- <spec-file>` - Run single test in dev mode
|
||||
|
||||
|
||||
### Language Tools
|
||||
- `npm run lang-sort` - Sort language files
|
||||
- `npm run lint:lang` - Validate JSON language files
|
||||
|
||||
### Platform-Specific TypeScript
|
||||
TypeScript configuration is split between web and native platforms with separate tsconfig files.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Multi-Platform Structure
|
||||
Jitsi Meet supports both web and React Native platforms with platform-specific file extensions and directories:
|
||||
- `.web.ts/.web.tsx` - Web-specific implementations
|
||||
- `.native.ts/.native.tsx` - React Native-specific implementations
|
||||
- `.any.ts/.any.tsx` - Shared cross-platform code
|
||||
- `.android.ts/.android.tsx` - Android-specific code
|
||||
- `.ios.ts/.ios.tsx` - iOS-specific code
|
||||
- `web/` directories - Web-specific components and modules
|
||||
- `native/` directories - React Native-specific components and modules
|
||||
- `react/features/mobile/` - Native-only features
|
||||
|
||||
### Core Directories
|
||||
- `react/features/` - Main application features organized by domain (83+ feature modules)
|
||||
- `modules/` - Legacy JavaScript modules and APIs
|
||||
- `css/` - SCSS stylesheets compiled to CSS
|
||||
- `libs/` - Compiled output directory for JavaScript bundles
|
||||
- `static/` - Static assets and HTML files
|
||||
- `tests/` - WebDriverIO end-to-end tests
|
||||
|
||||
### Feature-Driven Architecture
|
||||
The application is organized under `react/features/` with each feature containing:
|
||||
|
||||
- **`actionTypes.ts`** - Redux action type constants
|
||||
- **`actions.ts`** - Redux action creators (platform-specific variants with `.any.ts`, `.web.ts`, `.native.ts`)
|
||||
- **`reducer.ts`** - Redux reducer functions
|
||||
- **`middleware.ts`** - Redux middleware for side effects
|
||||
- **`functions.ts`** - Utility functions and selectors
|
||||
- **`constants.ts`** - Feature-specific constants
|
||||
- **`logger.ts`** - Feature-specific logger instance
|
||||
- **`types.ts`** - TypeScript type definitions
|
||||
|
||||
### Key Application Files
|
||||
- `app.js` - Main web application entry point
|
||||
- `webpack.config.js` - Multi-bundle Webpack configuration
|
||||
- `Makefile` - Build system for development and production
|
||||
- `package.json` - Dependencies and scripts with version requirements
|
||||
|
||||
### Bundle Architecture
|
||||
The application builds multiple bundles:
|
||||
- `app.bundle.js` / `app.bundle.min.js` - Main application bundle (entry: `./app.js`)
|
||||
- `external_api.js` / `external_api.min.js` - External API for embedders (entry: `./modules/API/external/index.js`)
|
||||
- `alwaysontop.js` / `alwaysontop.min.js` - Always-on-top window functionality (entry: `./react/features/always-on-top/index.tsx`)
|
||||
- `close3.js` / `close3.min.js` - Close3 functionality (entry: `./static/close3.js`)
|
||||
- `face-landmarks-worker.js` / `face-landmarks-worker.min.js` - Face landmarks detection worker (entry: `./react/features/face-landmarks/faceLandmarksWorker.ts`)
|
||||
- `noise-suppressor-worklet.js` / `noise-suppressor-worklet.min.js` - Audio noise suppression worklet (entry: `./react/features/stream-effects/noise-suppression/NoiseSuppressorWorklet.ts`)
|
||||
- `screenshot-capture-worker.js` / `screenshot-capture-worker.min.js` - Screenshot capture worker (entry: `./react/features/screenshot-capture/worker.ts`)
|
||||
|
||||
### Redux Architecture
|
||||
Features follow a Redux-based architecture with:
|
||||
- Actions, reducers, and middleware in each feature directory
|
||||
- Cross-platform state management
|
||||
- Modular feature organization with clear boundaries
|
||||
|
||||
The codebase uses a registry-based Redux architecture:
|
||||
- **ReducerRegistry** - Features register their reducers independently
|
||||
- **MiddlewareRegistry** - Features register middleware without cross-dependencies
|
||||
- **IReduxState** - Global state is strongly typed with 80+ feature states
|
||||
|
||||
### Dependencies
|
||||
- Uses `lib-jitsi-meet` as the core WebRTC library
|
||||
- React with TypeScript support
|
||||
- React Native for mobile applications
|
||||
- Webpack for bundling with development server
|
||||
|
||||
### TypeScript Configuration
|
||||
- `tsconfig.web.json` - Web platform TypeScript config (excludes native files)
|
||||
- `tsconfig.native.json` - React Native TypeScript config (excludes web files)
|
||||
- Strict TypeScript settings with ES2024 target
|
||||
- Platform-specific module suffixes (`.web`, `.native`)
|
||||
|
||||
### Key Base Features
|
||||
- **`base/app/`** - Application lifecycle management
|
||||
- **`base/conference/`** - Core conference logic
|
||||
- **`base/tracks/`** - Media track management
|
||||
- **`base/participants/`** - Participant management
|
||||
- **`base/config/`** - Configuration management
|
||||
- **`base/redux/`** - Redux infrastructure
|
||||
|
||||
### Component Patterns
|
||||
- **Abstract Components** - Base classes for cross-platform components
|
||||
- **Platform-Specific Components** - Separate implementations in `web/` and `native/` directories
|
||||
- **Hook-based patterns** - Modern React patterns for component logic
|
||||
### Testing Framework
|
||||
- WebDriverIO for end-to-end testing
|
||||
- Test files are located in `tests/specs/` and use page objects in `tests/pageobjects/`.
|
||||
- Environment configuration via `.env` files
|
||||
- Support for Chrome, Firefox, and grid testing
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
### Adding New Features
|
||||
1. Create feature directory under `react/features/[feature-name]/`
|
||||
2. Follow the standard file structure (actionTypes, actions, reducer, etc.)
|
||||
3. Register reducers and middleware using the registry pattern
|
||||
4. Define TypeScript interfaces for state and props
|
||||
5. Use platform-specific files for web/native differences
|
||||
6. Add feature-specific logger for debugging
|
||||
|
||||
### Working with Existing Features
|
||||
1. Check for existing `.any.ts`, `.web.ts`, `.native.ts` variants
|
||||
2. Follow established action-reducer-middleware patterns
|
||||
3. Use existing base utilities rather than creating new ones
|
||||
4. Leverage abstract components for cross-platform logic
|
||||
5. Maintain type safety across the entire state tree
|
||||
|
||||
### Testing
|
||||
The project uses WebDriver (WebdriverIO) for end-to-end testing. Test files are located in `tests/specs/` and use page objects in `tests/pageobjects/`.
|
||||
|
||||
### Build System
|
||||
- **Webpack** - Main build system for web bundles
|
||||
- **Makefile** - Coordinates build process and asset deployment
|
||||
- **Metro** - React Native bundler (configured in `metro.config.js`)
|
||||
|
||||
### Platform-Specific Notes
|
||||
- Web builds exclude files matching `**/native/*`, `**/*.native.ts`, etc.
|
||||
- Native builds exclude files matching `**/web/*`, `**/*.web.ts`, etc.
|
||||
- Use `moduleSuffixes` in TypeScript config to handle platform-specific imports
|
||||
- Check `tsconfig.web.json` and `tsconfig.native.json` for platform-specific exclusions
|
||||
|
||||
## Environment and Setup Requirements
|
||||
|
||||
### System Requirements
|
||||
- **Node.js and npm** are required
|
||||
- Development server runs at https://localhost:8080/
|
||||
- Certificate errors in development are expected (self-signed certificates)
|
||||
|
||||
### Development Workflow
|
||||
- Development server proxies to configurable target (default: https://alpha.jitsi.net)
|
||||
- Hot module replacement enabled for development
|
||||
- Bundle analysis available via `ANALYZE_BUNDLE=true` environment variable
|
||||
- Circular dependency detection via `DETECT_CIRCULAR_DEPS=true`
|
||||
|
||||
## Code Quality Requirements
|
||||
- All code must pass `npm run lint:ci` and `npm run tsc:ci` with 0 warnings before committing
|
||||
- TypeScript strict mode enabled - avoid `any` type
|
||||
- ESLint config extends `@jitsi/eslint-config`
|
||||
- Prefer TypeScript for new features, convert existing JavaScript when possible
|
||||
|
||||
## Code Style and Standards
|
||||
|
||||
### Conventional Commits Format
|
||||
Follow [Conventional Commits](https://www.conventionalcommits.org) with **mandatory scopes**:
|
||||
```
|
||||
feat(feature-name): description
|
||||
fix(feature-name): description
|
||||
docs(section): description
|
||||
```
|
||||
Available types: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test
|
||||
|
||||
### Feature Layout Structure
|
||||
When adding new features:
|
||||
```
|
||||
react/features/sample/
|
||||
├── actionTypes.ts
|
||||
├── actions.ts
|
||||
├── components/
|
||||
│ ├── AnotherComponent.tsx
|
||||
│ └── OneComponent.tsx
|
||||
├── middleware.ts
|
||||
└── reducer.ts
|
||||
```
|
||||
|
||||
### TypeScript Requirements
|
||||
- All new features must be written in TypeScript
|
||||
- Convert JavaScript to TypeScript when modifying existing code
|
||||
- Import middleware in `react/features/app/middlewares.{any,native,web}.js`
|
||||
- Import reducers in appropriate registry files
|
||||
- Avoid `index` files
|
||||
|
||||
### Bundle Size Management
|
||||
- Bundle size limits are enforced to prevent bloat
|
||||
- For increases, analyze first: `npx webpack -p --analyze-bundle`
|
||||
- Open analyzer: `npx webpack-bundle-analyzer build/app-stats.json`
|
||||
- Justify any dependency additions that increase bundle size
|
||||
|
||||
## Testing and Quality Assurance
|
||||
|
||||
### Tests
|
||||
- End-to-end tests are defined in the tests/
|
||||
- Tests run automatically for project member PRs via Jenkins
|
||||
- Tests cover peer-to-peer, invites, iOS, Android, and web platforms
|
||||
- Beta testing available at https://beta.meet.jit.si/
|
||||
|
||||
### Manual Testing Checklist
|
||||
- Test with 2 participants (P2P mode)
|
||||
- Test with 3+ participants (JVB mode)
|
||||
- Verify audio/video in both modes
|
||||
- Test mobile apps if changes affect mobile
|
||||
- Check that TLS certificate chain is complete for mobile app compatibility
|
||||
|
||||
## Common Issues and Debugging
|
||||
|
||||
### P2P vs JVB Problems
|
||||
- **Works with 2 participants, fails with 3+**: JVB/firewall issue, check UDP 10000
|
||||
- **Works on web, fails on mobile apps**: TLS certificate chain issue, need fullchain.pem
|
||||
- Use the tests from tests/ directory to verify functionality across platforms
|
||||
|
||||
### Development Server Issues
|
||||
- Certificate warnings are normal for development (self-signed)
|
||||
- Use different backend with WEBPACK_DEV_SERVER_PROXY_TARGET environment variable
|
||||
- Check firewall settings if local development fails
|
||||
|
||||
### Configuration and Customization
|
||||
- Extensive configuration options documented in handbook
|
||||
- See `config.js` for client-side options
|
||||
- Options marked 🚫 are not overwritable through `configOverwrite`
|
||||
- Reference [Configuration Guide](https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-configuration) for details
|
||||
|
||||
## Architecture Deep Dive
|
||||
|
||||
### Core Application Files
|
||||
- **`./conference.js`** - Foundation for user-conference interactions (connection, joining, muting)
|
||||
- **`./modules/external-api`** - External API for iframe integration and events
|
||||
- **`./lang/`** - Translations in `main-[language].json` files
|
||||
- **`./css/`** - SCSS files organized by features, matching React feature structure
|
||||
|
||||
### State Management Flow
|
||||
1. Actions dispatched from components
|
||||
2. Middleware processes side effects
|
||||
3. Reducers update state
|
||||
4. Components re-render based on state changes
|
||||
5. Registry pattern keeps features decoupled
|
||||
|
||||
### Cross-Platform Strategy
|
||||
- Abstract components handle shared logic
|
||||
- Platform files (.web.ts, .native.ts) handle platform differences
|
||||
- Build system excludes irrelevant platform files
|
||||
- TypeScript configs ensure proper platform targeting
|
||||
|
||||
## External Resources
|
||||
- [Jitsi Handbook](https://jitsi.github.io/handbook/) - Comprehensive documentation
|
||||
- [Community Forum](https://community.jitsi.org/) - Ask questions and get support
|
||||
- [Architecture Guide](https://jitsi.github.io/handbook/docs/architecture) - System overview
|
||||
- [Contributing Guidelines](https://jitsi.github.io/handbook/docs/dev-guide/contributing) - Detailed contribution process
|
||||
@@ -1,14 +1,20 @@
|
||||
# Follow Our Updated Guide to See How You Can Contribute
|
||||
|
||||
Hello there! 👋
|
||||
**Hello there! 👋**
|
||||
|
||||
We're thrilled that you're eager to contribute to Jitsi Meet! ❤️
|
||||
We're thrilled that you're eager to contribute to **Jitsi Meet! ❤️**
|
||||
|
||||
Your interest in improving our platform means a lot to us. To ensure your contributions align seamlessly with our goals and processes, we've recently updated our guide. This guide will provide you with clear instructions on how to get involved effectively.
|
||||
|
||||
Ready to get started? Head over to our [Jitsi Meet Handbook](https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-contributing/) and let's make Jitsi Meet even better together!
|
||||
### 📖 Get Started
|
||||
|
||||
Ready to get started? Head over to our [Jitsi Meet Handbook](https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-contributing/) and let's make **Jitsi Meet** even better together!
|
||||
|
||||
### 💬 Join the Discussion
|
||||
|
||||
Have questions or need help? Join our community discussions on the [Jitsi Forum](https://community.jitsi.org/) where contributors and maintainers can assist you.
|
||||
|
||||
### ❗️Additional Note
|
||||
Before sending us your code, double-check that it meets our coding standards. You can do this by running a command: `npm run lint`. If there are any issues, don't worry! You can fix them by running: `npm run lint-fix`. Once your code passes these checks, feel free to submit your pull request.
|
||||
|
||||
Happy coding!
|
||||
**Happy coding!**
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
// Crashlytics integration is done as part of Firebase now, so it gets
|
||||
// automagically activated with google-services.json
|
||||
@@ -27,6 +28,14 @@ android {
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON", "-DANDROID_STL=c++_shared"
|
||||
cppFlags "-std=c++17"
|
||||
cFlags "-DANDROID_PLATFORM=android-26"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
@@ -42,10 +51,11 @@ android {
|
||||
debug {
|
||||
buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${googleServicesEnabled}"
|
||||
buildConfigField "boolean", "LIBRE_BUILD", "${rootProject.ext.libreBuild}"
|
||||
applicationIdSuffix ".debug"
|
||||
}
|
||||
release {
|
||||
// Uncomment the following line for singing a test release build.
|
||||
//signingConfig signingConfigs.debug
|
||||
// Uncomment the following line for signing a test release build.
|
||||
// signingConfig signingConfigs.debug
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-release.pro'
|
||||
buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${googleServicesEnabled}"
|
||||
@@ -65,9 +75,18 @@ android {
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility rootProject.ext.javaVersion
|
||||
targetCompatibility rootProject.ext.javaVersion
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = rootProject.ext.jvmTargetVersion
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(rootProject.ext.jvmToolchainVersion)
|
||||
}
|
||||
|
||||
namespace 'org.jitsi.meet'
|
||||
}
|
||||
|
||||
@@ -82,10 +101,8 @@ dependencies {
|
||||
|
||||
// Firebase
|
||||
// - Crashlytics
|
||||
// - Dynamic Links
|
||||
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')
|
||||
@@ -93,8 +110,6 @@ dependencies {
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
// Dropbox integration
|
||||
//
|
||||
|
||||
def dropboxAppKey
|
||||
if (project.file('dropbox.key').exists()) {
|
||||
dropboxAppKey = project.file('dropbox.key').text.trim() - 'db-'
|
||||
@@ -165,7 +180,6 @@ gradle.projectsEvaluated {
|
||||
|
||||
packageTask.dependsOn(currentRunPackagerTask)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (googleServicesEnabled) {
|
||||
|
||||
@@ -4,3 +4,7 @@
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keep public class * extends java.lang.Exception
|
||||
|
||||
# R8 missing classes - suppress warnings
|
||||
-dontwarn com.facebook.memory.config.MemorySpikeConfig
|
||||
-dontwarn kotlinx.parcelize.Parcelize
|
||||
|
||||
5
android/app/proguard-rules.pro
vendored
5
android/app/proguard-rules.pro
vendored
@@ -96,8 +96,3 @@
|
||||
|
||||
# Rule to avoid build errors related to SVGs.
|
||||
-keep public class com.horcrux.svg.** {*;}
|
||||
|
||||
# https://github.com/facebook/fresco/issues/2638
|
||||
-keep public class com.facebook.imageutils.** {
|
||||
public *;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics;
|
||||
import com.google.firebase.dynamiclinks.FirebaseDynamicLinks;
|
||||
|
||||
import org.jitsi.meet.sdk.JitsiMeet;
|
||||
import org.jitsi.meet.sdk.JitsiMeetActivity;
|
||||
@@ -22,18 +21,6 @@ final class GoogleServicesHelper {
|
||||
Log.d(activity.getClass().getSimpleName(), "Initializing Google Services");
|
||||
|
||||
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!JitsiMeet.isCrashReportingDisabled(activity));
|
||||
FirebaseDynamicLinks.getInstance().getDynamicLink(activity.getIntent())
|
||||
.addOnSuccessListener(activity, pendingDynamicLinkData -> {
|
||||
Uri dynamicLink = null;
|
||||
|
||||
if (pendingDynamicLinkData != null) {
|
||||
dynamicLink = pendingDynamicLinkData.getLink();
|
||||
}
|
||||
|
||||
if (dynamicLink != null) {
|
||||
activity.join(dynamicLink.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,12 @@ import android.view.KeyEvent;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.oney.WebRTCModule.WebRTCModuleOptions;
|
||||
|
||||
import org.jitsi.meet.sdk.JitsiMeet;
|
||||
import org.jitsi.meet.sdk.JitsiMeetActivity;
|
||||
import org.jitsi.meet.sdk.JitsiMeetConferenceOptions;
|
||||
import org.webrtc.Logging;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
@@ -79,6 +82,10 @@ public class MainActivity extends JitsiMeetActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
JitsiMeet.showSplashScreen(this);
|
||||
|
||||
WebRTCModuleOptions options = WebRTCModuleOptions.getInstance();
|
||||
options.loggingSeverity = Logging.Severity.LS_ERROR;
|
||||
|
||||
super.onCreate(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#17A0DB</color>
|
||||
<color name="navigationBarColor">#161618</color>
|
||||
<color name="navigationBarColor">#040404</color>
|
||||
<color name="statusBarColor">#040404</color>
|
||||
</resources>
|
||||
@@ -3,6 +3,7 @@
|
||||
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="android:navigationBarColor">@color/navigationBarColor</item>
|
||||
<item name="android:statusBarColor">@color/statusBarColor</item>
|
||||
<item name="android:windowDisablePreview">true</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -5,46 +5,52 @@ import org.gradle.util.VersionNumber
|
||||
// sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext {
|
||||
kotlinVersion = "2.0.21"
|
||||
gradlePluginVersion = "8.6.0"
|
||||
buildToolsVersion = "35.0.0"
|
||||
compileSdkVersion = 35
|
||||
minSdkVersion = 26
|
||||
targetSdkVersion = 35
|
||||
supportLibVersion = "28.0.0"
|
||||
ndkVersion = "27.1.12297006"
|
||||
|
||||
// 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.
|
||||
moduleGroupId = 'com.facebook.react'
|
||||
|
||||
// Maven repo where artifacts will be published
|
||||
mavenRepo = System.env.MVN_REPO ?: ""
|
||||
mavenUser = System.env.MVN_USER ?: ""
|
||||
mavenPassword = System.env.MVN_PASSWORD ?: ""
|
||||
|
||||
// Libre build
|
||||
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
|
||||
|
||||
googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
|
||||
|
||||
//React Native and Hermes Version
|
||||
rnVersion = "0.77.2"
|
||||
|
||||
// Java dependencies
|
||||
javaVersion = JavaVersion.VERSION_17
|
||||
jvmToolchainVersion = 17
|
||||
jvmTargetVersion = '17'
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$rootProject.ext.kotlinVersion"
|
||||
classpath "com.android.tools.build:gradle:$rootProject.ext.gradlePluginVersion"
|
||||
classpath 'com.google.gms:google-services:4.4.0'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
kotlinVersion = "1.9.24"
|
||||
buildToolsVersion = "34.0.0"
|
||||
compileSdkVersion = 34
|
||||
minSdkVersion = 26
|
||||
targetSdkVersion = 34
|
||||
supportLibVersion = "28.0.0"
|
||||
ndkVersion = "26.1.10909125"
|
||||
|
||||
// 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.
|
||||
moduleGroupId = 'com.facebook.react'
|
||||
|
||||
// Maven repo where artifacts will be published
|
||||
mavenRepo = System.env.MVN_REPO ?: ""
|
||||
mavenUser = System.env.MVN_USER ?: ""
|
||||
mavenPassword = System.env.MVN_PASSWORD ?: ""
|
||||
|
||||
// Libre build
|
||||
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
|
||||
|
||||
googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
|
||||
|
||||
//React Native and Hermes Version
|
||||
rnVersion = "0.75.5"
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@@ -69,26 +75,6 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
// Due to a dependency conflict between React Native and the Fresco library used by GiphySDK,
|
||||
// GIFs appear as static images instead of animating
|
||||
// https://github.com/Giphy/giphy-react-native-sdk/commit/7fe466ed6fddfaec95f9cbc959d33bd75ad8f900
|
||||
|
||||
configurations.configureEach {
|
||||
resolutionStrategy {
|
||||
forcedModules = [
|
||||
'com.facebook.fresco:fresco:3.2.0',
|
||||
'com.facebook.fresco:animated-gif:3.2.0',
|
||||
'com.facebook.fresco:animated-base:3.2.0',
|
||||
'com.facebook.fresco:animated-drawable:3.2.0',
|
||||
'com.facebook.fresco:animated-webp:3.2.0',
|
||||
'com.facebook.fresco:webpsupport:3.2.0',
|
||||
'com.facebook.fresco:imagepipeline-okhttp3:3.2.0',
|
||||
'com.facebook.fresco:middleware:3.2.0',
|
||||
'com.facebook.fresco:nativeimagetranscoder:3.2.0'
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// Third-party react-native modules which Jitsi Meet SDK for Android depends
|
||||
// on and which are not available in third-party Maven repositories need to
|
||||
// be deployed in a Maven repository of ours.
|
||||
@@ -134,7 +120,7 @@ allprojects {
|
||||
project.version = "${json.version}-jitsi-${versionQualifierNumber}"
|
||||
|
||||
task jitsiAndroidSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
archiveClassifier = 'sources'
|
||||
from android.sourceSets.main.java.source
|
||||
}
|
||||
|
||||
@@ -185,16 +171,46 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
// Force the version of the Android build tools we have chosen on all
|
||||
// subprojects. The forcing was introduced for react-native and the third-party
|
||||
// modules that we utilize such as react-native-background-timer.
|
||||
// Force the version of the Android build tools we have chosen on all subprojects.
|
||||
subprojects { subproject ->
|
||||
afterEvaluate{
|
||||
if ((subproject.plugins.hasPlugin('android')
|
||||
|| subproject.plugins.hasPlugin('android-library'))
|
||||
&& rootProject.ext.has('buildToolsVersion')) {
|
||||
|
||||
android {
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
buildFeatures {
|
||||
buildConfig true
|
||||
}
|
||||
|
||||
// Set JVM target across all subprojects
|
||||
compileOptions {
|
||||
sourceCompatibility rootProject.ext.javaVersion
|
||||
targetCompatibility rootProject.ext.javaVersion
|
||||
}
|
||||
|
||||
// Disable lint errors for problematic third-party modules
|
||||
// react-native-background-timer
|
||||
// react-native-calendar-events
|
||||
lint {
|
||||
abortOnError = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add Kotlin configuration for subprojects that use Kotlin
|
||||
if (subproject.plugins.hasPlugin('kotlin-android')) {
|
||||
subproject.kotlin {
|
||||
jvmToolchain(rootProject.ext.jvmToolchainVersion)
|
||||
}
|
||||
|
||||
// Set Kotlin JVM target
|
||||
subproject.android {
|
||||
kotlinOptions {
|
||||
jvmTarget = rootProject.ext.jvmTargetVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,20 +11,26 @@
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx1024m -XX:MaxPermSize=256m
|
||||
|
||||
org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
org.gradle.jvmargs=-Xmx4048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
# This one fixes a weird WebRTC runtime problem on some devices.
|
||||
# https://github.com/jitsi/jitsi-meet/issues/7911#issuecomment-714323255
|
||||
android.enableDexingArtifactTransform.desugaring=false
|
||||
|
||||
android.useAndroidX=true
|
||||
|
||||
android.enableJetifier=true
|
||||
android.bundle.enableUncompressedNativeLibs=false
|
||||
|
||||
# Use this property to enable support to the new architecture.
|
||||
# This will allow you to use TurboModules and the Fabric render in
|
||||
# your application. You should enable this flag either if you want
|
||||
# to write custom TurboModules/Fabric components OR use libraries that
|
||||
# are providing them.
|
||||
newArchEnabled=false
|
||||
|
||||
# Use this property to enable or disable the Hermes JS engine.
|
||||
hermesEnabled=true
|
||||
|
||||
appVersion=99.0.0
|
||||
sdkVersion=0.0.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
113
android/scripts/check_elf_alignment.sh
Executable file
113
android/scripts/check_elf_alignment.sh
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/bin/bash
|
||||
progname="${0##*/}"
|
||||
progname="${progname%.sh}"
|
||||
|
||||
# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
|
||||
|
||||
cleanup_trap() {
|
||||
if [ -n "${tmp}" -a -d "${tmp}" ]; then
|
||||
rm -rf ${tmp}
|
||||
fi
|
||||
exit $1
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "Host side script to check the ELF alignment of shared libraries."
|
||||
echo "Shared libraries are reported ALIGNED when their ELF regions are"
|
||||
echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
|
||||
echo
|
||||
echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
|
||||
}
|
||||
|
||||
if [ ${#} -ne 1 ]; then
|
||||
usage
|
||||
exit
|
||||
fi
|
||||
|
||||
case ${1} in
|
||||
--help | -h | -\?)
|
||||
usage
|
||||
exit
|
||||
;;
|
||||
|
||||
*)
|
||||
dir="${1}"
|
||||
;;
|
||||
esac
|
||||
|
||||
if ! [ -f "${dir}" -o -d "${dir}" ]; then
|
||||
echo "Invalid file: ${dir}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${dir}" == *.apk ]]; then
|
||||
trap 'cleanup_trap' EXIT
|
||||
|
||||
echo
|
||||
echo "Recursively analyzing $dir"
|
||||
echo
|
||||
|
||||
if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
|
||||
echo "=== APK zip-alignment ==="
|
||||
zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
|
||||
echo "========================="
|
||||
else
|
||||
echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
|
||||
echo " You can install the latest build-tools by running the below command"
|
||||
echo " and updating your \$PATH:"
|
||||
echo
|
||||
echo " sdkmanager \"build-tools;35.0.0-rc3\""
|
||||
fi
|
||||
|
||||
dir_filename=$(basename "${dir}")
|
||||
tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
|
||||
unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
|
||||
dir="${tmp}"
|
||||
fi
|
||||
|
||||
if [[ "${dir}" == *.apex ]]; then
|
||||
trap 'cleanup_trap' EXIT
|
||||
|
||||
echo
|
||||
echo "Recursively analyzing $dir"
|
||||
echo
|
||||
|
||||
dir_filename=$(basename "${dir}")
|
||||
tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
|
||||
deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
|
||||
dir="${tmp}"
|
||||
fi
|
||||
|
||||
RED="\e[31m"
|
||||
GREEN="\e[32m"
|
||||
ENDCOLOR="\e[0m"
|
||||
|
||||
unaligned_libs=()
|
||||
|
||||
echo
|
||||
echo "=== ELF alignment ==="
|
||||
|
||||
matches="$(find "${dir}" -type f)"
|
||||
IFS=$'\n'
|
||||
for match in $matches; do
|
||||
# We could recursively call this script or rewrite it to though.
|
||||
[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
|
||||
[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
|
||||
|
||||
[[ $(file "${match}") == *"ELF"* ]] || continue
|
||||
|
||||
res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
|
||||
if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
|
||||
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
|
||||
else
|
||||
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
|
||||
unaligned_libs+=("${match}")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#unaligned_libs[@]} -gt 0 ]; then
|
||||
echo -e "${RED}Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
|
||||
elif [ -n "${dir_filename}" ]; then
|
||||
echo -e "ELF Verification Successful"
|
||||
fi
|
||||
echo "====================="
|
||||
@@ -44,15 +44,11 @@ dependencies {
|
||||
api "com.facebook.react:react-android:$rootProject.ext.rnVersion"
|
||||
api "com.facebook.react:hermes-android:$rootProject.ext.rnVersion"
|
||||
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation 'org.webkit:android-jsc:+'
|
||||
|
||||
implementation 'com.facebook.fresco:animated-gif:2.5.0'
|
||||
implementation 'com.dropbox.core:dropbox-core-sdk:4.0.1'
|
||||
implementation 'com.jakewharton.timber:timber:5.0.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 'com.google.j2objc:j2objc-annotations:3.0.0'
|
||||
|
||||
// Only add these packages if we are NOT doing a LIBRE_BUILD
|
||||
if (!rootProject.ext.libreBuild) {
|
||||
@@ -77,7 +73,6 @@ dependencies {
|
||||
}
|
||||
implementation project(':react-native-gesture-handler')
|
||||
implementation project(':react-native-get-random-values')
|
||||
implementation project(':react-native-immersive-mode')
|
||||
implementation project(':react-native-keep-awake')
|
||||
implementation project(':react-native-orientation-locker')
|
||||
implementation project(':react-native-pager-view')
|
||||
@@ -86,11 +81,14 @@ dependencies {
|
||||
implementation project(':react-native-screens')
|
||||
implementation project(':react-native-slider')
|
||||
implementation project(':react-native-sound')
|
||||
implementation project(':react-native-splash-screen')
|
||||
implementation project(':react-native-splash-view')
|
||||
implementation project(':react-native-svg')
|
||||
implementation project(':react-native-video')
|
||||
implementation project(':react-native-webrtc')
|
||||
implementation project(':react-native-webview')
|
||||
implementation project(':react-native-worklets-core')
|
||||
|
||||
// Use `api` here so consumers can use WebRTCModuleOptions.
|
||||
api project(':react-native-webrtc')
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
}
|
||||
@@ -138,8 +136,16 @@ android.libraryVariants.all { def variant ->
|
||||
def devEnabled = !targetName.toLowerCase().contains("release")
|
||||
|
||||
// Run the bundler
|
||||
// Use full path to node to avoid PATH issues in Gradle
|
||||
def nodePath = System.getenv('NVM_BIN') ? "${System.getenv('NVM_BIN')}/node" : "node"
|
||||
|
||||
// Debug: Print the node path and environment
|
||||
println "Using node path: ${nodePath}"
|
||||
println "NVM_BIN: ${System.getenv('NVM_BIN')}"
|
||||
println "Working directory: ${reactRoot}"
|
||||
|
||||
commandLine(
|
||||
"node",
|
||||
nodePath,
|
||||
"node_modules/react-native/scripts/bundle.js",
|
||||
"--platform", "android",
|
||||
"--dev", "${devEnabled}",
|
||||
@@ -152,6 +158,70 @@ android.libraryVariants.all { def variant ->
|
||||
enabled !devEnabled
|
||||
}
|
||||
|
||||
// GRADLE REQUIREMENTS (Gradle 8.7+ / AGP 8.5.0+):
|
||||
|
||||
// This task requires explicit dependencies on resource tasks from all React Native modules
|
||||
// due to Gradle's strict validation of task dependencies.
|
||||
|
||||
// Without these dependencies,
|
||||
// builds will fail with errors like:
|
||||
// "Task ':sdk:bundleReleaseJsAndAssets' uses the output of task ':react-native-amplitude:packageReleaseResources'
|
||||
// without declaring a dependency on it."
|
||||
|
||||
// The automatic dependency resolution below ensures all required resource tasks are properly
|
||||
// declared as dependencies before this task executes.
|
||||
|
||||
if (variant.name.toLowerCase().contains("release")) {
|
||||
rootProject.subprojects.each { subproject ->
|
||||
if (
|
||||
subproject.name.startsWith("react-native-") ||
|
||||
subproject.name.startsWith("@react-native-") ||
|
||||
subproject.name.startsWith("@giphy/")
|
||||
) {
|
||||
[
|
||||
"packageReleaseResources",
|
||||
"generateReleaseResValues",
|
||||
"generateReleaseResources",
|
||||
"generateReleaseBuildConfig",
|
||||
"processReleaseManifest",
|
||||
"writeReleaseAarMetadata",
|
||||
"generateReleaseRFile",
|
||||
"compileReleaseLibraryResources",
|
||||
"compileReleaseJavaWithJavac",
|
||||
"javaPreCompileRelease",
|
||||
"bundleLibCompileToJarRelease",
|
||||
"exportReleaseConsumerProguardFiles",
|
||||
"mergeReleaseGeneratedProguardFiles",
|
||||
"mergeReleaseJniLibFolders",
|
||||
"mergeReleaseShaders",
|
||||
"packageReleaseAssets",
|
||||
"processReleaseJavaRes",
|
||||
"prepareReleaseArtProfile",
|
||||
"copyReleaseJniLibsProjectOnly",
|
||||
"extractDeepLinksRelease",
|
||||
"createFullJarRelease",
|
||||
"generateReleaseLintModel",
|
||||
"writeReleaseLintModelMetadata",
|
||||
"generateReleaseLintVitalModel",
|
||||
"lintVitalAnalyzeRelease",
|
||||
"lintReportRelease",
|
||||
"lintAnalyzeRelease",
|
||||
"lintReportDebug",
|
||||
"lintAnalyzeDebug"
|
||||
].each { taskName ->
|
||||
if (subproject.tasks.findByName(taskName)) {
|
||||
currentBundleTask.dependsOn(subproject.tasks.named(taskName))
|
||||
}
|
||||
}
|
||||
|
||||
// Also depend on the main build task to ensure all sub-tasks are completed
|
||||
if (subproject.tasks.findByName("build")) {
|
||||
currentBundleTask.dependsOn(subproject.tasks.named("build"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentBundleTask.ext.generatedResFolders = files(resourcesDir).builtBy(currentBundleTask)
|
||||
currentBundleTask.ext.generatedAssetsFolders = files(jsBundleDir).builtBy(currentBundleTask)
|
||||
variant.registerGeneratedResFolders(currentBundleTask.generatedResFolders)
|
||||
|
||||
@@ -62,7 +62,8 @@
|
||||
<provider
|
||||
android:name="androidx.startup.InitializationProvider"
|
||||
android:authorities="${applicationId}.androidx-startup"
|
||||
android:exported="false">
|
||||
android:exported="false"
|
||||
tools:node="merge">
|
||||
<meta-data android:name="org.jitsi.meet.sdk.JitsiInitializer"
|
||||
android:value="androidx.startup" />
|
||||
</provider>
|
||||
|
||||
@@ -3,12 +3,6 @@ package org.jitsi.meet.sdk;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Wraps the name and extra data for events that were broadcasted locally.
|
||||
*/
|
||||
@@ -16,57 +10,21 @@ public class BroadcastAction {
|
||||
private static final String TAG = BroadcastAction.class.getSimpleName();
|
||||
|
||||
private final Type type;
|
||||
private final HashMap<String, Object> data;
|
||||
private final Bundle data;
|
||||
|
||||
public BroadcastAction(Intent intent) {
|
||||
this.type = Type.buildTypeFromAction(intent.getAction());
|
||||
this.data = buildDataFromBundle(intent.getExtras());
|
||||
this.data = intent.getExtras();
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public HashMap<String, Object> getData() {
|
||||
public Bundle getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public WritableNativeMap getDataAsWritableNativeMap() {
|
||||
WritableNativeMap nativeMap = new WritableNativeMap();
|
||||
|
||||
for (String key : this.data.keySet()) {
|
||||
try {
|
||||
if (this.data.get(key) instanceof Boolean) {
|
||||
nativeMap.putBoolean(key, (Boolean) this.data.get(key));
|
||||
} else if (this.data.get(key) instanceof Integer) {
|
||||
nativeMap.putInt(key, (Integer) this.data.get(key));
|
||||
} else if (this.data.get(key) instanceof Double) {
|
||||
nativeMap.putDouble(key, (Double) this.data.get(key));
|
||||
} else if (this.data.get(key) instanceof String) {
|
||||
nativeMap.putString(key, (String) this.data.get(key));
|
||||
} else {
|
||||
throw new Exception("Unsupported extra data type");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
JitsiMeetLogger.w(TAG + " invalid extra data in event", e);
|
||||
}
|
||||
}
|
||||
|
||||
return nativeMap;
|
||||
}
|
||||
|
||||
private static HashMap<String, Object> buildDataFromBundle(Bundle bundle) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
|
||||
if (bundle != null) {
|
||||
for (String key : bundle.keySet()) {
|
||||
map.put(key, bundle.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
enum Type {
|
||||
SET_AUDIO_MUTED("org.jitsi.meet.SET_AUDIO_MUTED"),
|
||||
HANG_UP("org.jitsi.meet.HANG_UP"),
|
||||
@@ -82,7 +40,9 @@ public class BroadcastAction {
|
||||
SHOW_NOTIFICATION("org.jitsi.meet.SHOW_NOTIFICATION"),
|
||||
HIDE_NOTIFICATION("org.jitsi.meet.HIDE_NOTIFICATION"),
|
||||
START_RECORDING("org.jitsi.meet.START_RECORDING"),
|
||||
STOP_RECORDING("org.jitsi.meet.STOP_RECORDING");
|
||||
STOP_RECORDING("org.jitsi.meet.STOP_RECORDING"),
|
||||
OVERWRITE_CONFIG("org.jitsi.meet.OVERWRITE_CONFIG"),
|
||||
SEND_CAMERA_FACING_MODE_MESSAGE("org.jitsi.meet.SEND_CAMERA_FACING_MODE_MESSAGE");
|
||||
|
||||
private final String action;
|
||||
|
||||
|
||||
@@ -91,7 +91,9 @@ public class BroadcastEvent {
|
||||
VIDEO_MUTED_CHANGED("org.jitsi.meet.VIDEO_MUTED_CHANGED"),
|
||||
READY_TO_CLOSE("org.jitsi.meet.READY_TO_CLOSE"),
|
||||
TRANSCRIPTION_CHUNK_RECEIVED("org.jitsi.meet.TRANSCRIPTION_CHUNK_RECEIVED"),
|
||||
CUSTOM_BUTTON_PRESSED("org.jitsi.meet.CUSTOM_BUTTON_PRESSED");
|
||||
CUSTOM_BUTTON_PRESSED("org.jitsi.meet.CUSTOM_BUTTON_PRESSED"),
|
||||
CONFERENCE_UNIQUE_ID_SET("org.jitsi.meet.CONFERENCE_UNIQUE_ID_SET"),
|
||||
RECORDING_STATUS_CHANGED("org.jitsi.meet.RECORDING_STATUS_CHANGED");
|
||||
|
||||
private static final String CONFERENCE_BLURRED_NAME = "CONFERENCE_BLURRED";
|
||||
private static final String CONFERENCE_FOCUSED_NAME = "CONFERENCE_FOCUSED";
|
||||
@@ -110,6 +112,8 @@ public class BroadcastEvent {
|
||||
private static final String READY_TO_CLOSE_NAME = "READY_TO_CLOSE";
|
||||
private static final String TRANSCRIPTION_CHUNK_RECEIVED_NAME = "TRANSCRIPTION_CHUNK_RECEIVED";
|
||||
private static final String CUSTOM_BUTTON_PRESSED_NAME = "CUSTOM_BUTTON_PRESSED";
|
||||
private static final String CONFERENCE_UNIQUE_ID_SET_NAME = "CONFERENCE_UNIQUE_ID_SET";
|
||||
private static final String RECORDING_STATUS_CHANGED_NAME = "RECORDING_STATUS_CHANGED";
|
||||
|
||||
private final String action;
|
||||
|
||||
@@ -166,6 +170,10 @@ public class BroadcastEvent {
|
||||
return TRANSCRIPTION_CHUNK_RECEIVED;
|
||||
case CUSTOM_BUTTON_PRESSED_NAME:
|
||||
return CUSTOM_BUTTON_PRESSED;
|
||||
case CONFERENCE_UNIQUE_ID_SET_NAME:
|
||||
return CONFERENCE_UNIQUE_ID_SET;
|
||||
case RECORDING_STATUS_CHANGED_NAME:
|
||||
return RECORDING_STATUS_CHANGED;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -139,4 +139,19 @@ public class BroadcastIntentHelper {
|
||||
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent buildOverwriteConfigIntent(Bundle config) {
|
||||
Intent intent = new Intent(BroadcastAction.Type.OVERWRITE_CONFIG.getAction());
|
||||
intent.putExtra("config", config);
|
||||
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent buildSendCameraFacingModeMessageIntent(String to, String facingMode) {
|
||||
Intent intent = new Intent(BroadcastAction.Type.SEND_CAMERA_FACING_MODE_MESSAGE.getAction());
|
||||
intent.putExtra("to", to);
|
||||
intent.putExtra("facingMode", facingMode);
|
||||
|
||||
return intent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package org.jitsi.meet.sdk;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
@@ -28,7 +31,14 @@ public class BroadcastReceiver extends android.content.BroadcastReceiver {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
BroadcastAction action = new BroadcastAction(intent);
|
||||
String actionName = action.getType().getAction();
|
||||
|
||||
ReactInstanceManagerHolder.emitEvent(actionName, action.getDataAsWritableNativeMap());
|
||||
Bundle data = action.getData();
|
||||
|
||||
// For actions without data bundle (like hangup), we create an empty map
|
||||
// instead of attempting to convert a null bundle to avoid crashes.
|
||||
if (data != null) {
|
||||
ReactInstanceManagerHolder.emitEvent(actionName, Arguments.fromBundle(data));
|
||||
} else {
|
||||
ReactInstanceManagerHolder.emitEvent(actionName, Arguments.createMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,8 @@ class ExternalAPIModule extends ReactContextBaseJavaModule {
|
||||
constants.put("HIDE_NOTIFICATION", BroadcastAction.Type.HIDE_NOTIFICATION.getAction());
|
||||
constants.put("START_RECORDING", BroadcastAction.Type.START_RECORDING.getAction());
|
||||
constants.put("STOP_RECORDING", BroadcastAction.Type.STOP_RECORDING.getAction());
|
||||
constants.put("OVERWRITE_CONFIG", BroadcastAction.Type.OVERWRITE_CONFIG.getAction());
|
||||
constants.put("SEND_CAMERA_FACING_MODE_MESSAGE", BroadcastAction.Type.SEND_CAMERA_FACING_MODE_MESSAGE.getAction());
|
||||
|
||||
return constants;
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.squareup.duktape.Duktape;
|
||||
|
||||
@ReactModule(name = JavaScriptSandboxModule.NAME)
|
||||
class JavaScriptSandboxModule extends ReactContextBaseJavaModule {
|
||||
public static final String NAME = "JavaScriptSandbox";
|
||||
|
||||
public JavaScriptSandboxModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the given code in a Duktape VM.
|
||||
* @param code - The code that needs to evaluated.
|
||||
* @param promise - Resolved with the output in case of success or rejected with an exception
|
||||
* in case of failure.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void evaluate(String code, Promise promise) {
|
||||
Duktape vm = Duktape.create();
|
||||
try {
|
||||
Object res = vm.evaluate(code);
|
||||
promise.resolve(res.toString());
|
||||
} catch (Throwable tr) {
|
||||
promise.reject(tr);
|
||||
} finally {
|
||||
vm.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,10 @@ import androidx.annotation.NonNull;
|
||||
import androidx.startup.Initializer;
|
||||
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import com.facebook.react.soloader.OpenSourceMergedSoMapping;
|
||||
import org.wonday.orientation.OrientationActivityLifecycle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -35,7 +37,11 @@ public class JitsiInitializer implements Initializer<Boolean> {
|
||||
public Boolean create(@NonNull Context context) {
|
||||
Log.d(this.getClass().getCanonicalName(), "create");
|
||||
|
||||
SoLoader.init(context, /* native exopackage */ false);
|
||||
try {
|
||||
SoLoader.init(context, OpenSourceMergedSoMapping.INSTANCE);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// Register our uncaught exception handler.
|
||||
JitsiMeetUncaughtExceptionHandler.register();
|
||||
@@ -43,6 +49,10 @@ public class JitsiInitializer implements Initializer<Boolean> {
|
||||
// Register activity lifecycle handler for the orientation locker module.
|
||||
((Application) context).registerActivityLifecycleCallbacks(OrientationActivityLifecycle.getInstance());
|
||||
|
||||
// Initialize ReactInstanceManager during application startup
|
||||
// This ensures it's ready before any Activity onCreate is called
|
||||
ReactInstanceManagerHolder.initReactInstanceManager((Application) context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import android.os.Bundle;
|
||||
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
|
||||
import org.devio.rn.splashscreen.SplashScreen;
|
||||
import com.splashview.SplashView;
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
public class JitsiMeet {
|
||||
@@ -92,7 +92,7 @@ public class JitsiMeet {
|
||||
*/
|
||||
public static void showSplashScreen(Activity activity) {
|
||||
try {
|
||||
SplashScreen.show(activity);
|
||||
SplashView.INSTANCE.showSplashView(activity);
|
||||
} catch (Exception e) {
|
||||
JitsiMeetLogger.e(e, "Failed to show splash screen");
|
||||
}
|
||||
|
||||
@@ -24,10 +24,17 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
@@ -87,6 +94,27 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||
launch(context, options);
|
||||
}
|
||||
|
||||
public static void addTopBottomInsets(@NonNull Window w, @NonNull View v) {
|
||||
|
||||
View decorView = w.getDecorView();
|
||||
|
||||
decorView.post(() -> {
|
||||
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(decorView);
|
||||
if (insets != null) {
|
||||
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
|
||||
params.topMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top;
|
||||
params.bottomMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom;
|
||||
v.setLayoutParams(params);
|
||||
|
||||
decorView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
|
||||
view.setBackgroundColor(JitsiMeetView.BACKGROUND_COLOR);
|
||||
|
||||
return windowInsets;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Overrides
|
||||
//
|
||||
|
||||
@@ -102,7 +130,17 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// ReactInstanceManager is now initialized by JitsiInitializer during application startup
|
||||
// Just call onHostResume since the manager is already ready
|
||||
JitsiMeetActivityDelegate.onHostResume(this);
|
||||
|
||||
setContentView(R.layout.activity_jitsi_meet);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
|
||||
&& getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||
addTopBottomInsets(getWindow(), findViewById(android.R.id.content));
|
||||
}
|
||||
|
||||
this.jitsiView = findViewById(R.id.jitsiView);
|
||||
|
||||
registerForBroadcastMessages();
|
||||
@@ -272,8 +310,16 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||
// }
|
||||
|
||||
// protected void onCustomButtonPressed(HashMap<String, Object> extraData) {
|
||||
// JitsiMeetLogger.i("Custom button pressed: " + extraData);
|
||||
// }
|
||||
// JitsiMeetLogger.i("Custom button pressed: " + extraData);
|
||||
// }
|
||||
|
||||
// protected void onConferenceUniqueIdSet(HashMap<String, Object> extraData) {
|
||||
// JitsiMeetLogger.i("Conference unique id set: " + extraData);
|
||||
// }
|
||||
|
||||
// protected void onRecordingStatusChanged(HashMap<String, Object> extraData) {
|
||||
// JitsiMeetLogger.i("Recording status changed: " + extraData);
|
||||
// }
|
||||
|
||||
// Activity lifecycle methods
|
||||
//
|
||||
@@ -358,12 +404,18 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||
case READY_TO_CLOSE:
|
||||
onReadyToClose();
|
||||
break;
|
||||
// case TRANSCRIPTION_CHUNK_RECEIVED:
|
||||
// onTranscriptionChunkReceived(event.getData());
|
||||
// break;
|
||||
// case CUSTOM_BUTTON_PRESSED:
|
||||
// onCustomButtonPressed(event.getData());
|
||||
// break;
|
||||
// case TRANSCRIPTION_CHUNK_RECEIVED:
|
||||
// onTranscriptionChunkReceived(event.getData());
|
||||
// break;
|
||||
// case CUSTOM_BUTTON_PRESSED:
|
||||
// onCustomButtonPressed(event.getData());
|
||||
// break;
|
||||
// case CONFERENCE_UNIQUE_ID_SET:
|
||||
// onConferenceUniqueIdSet(event.getData());
|
||||
// break;
|
||||
// case RECORDING_STATUS_CHANGED:
|
||||
// onRecordingStatusChanged(event.getData());
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ public class JitsiMeetActivityDelegate {
|
||||
* React Native module.
|
||||
*/
|
||||
private static PermissionListener permissionListener;
|
||||
private static Callback permissionsCallback;
|
||||
|
||||
/**
|
||||
* Tells whether or not the permissions request is currently in progress.
|
||||
@@ -142,11 +141,6 @@ public class JitsiMeetActivityDelegate {
|
||||
if (reactInstanceManager != null) {
|
||||
reactInstanceManager.onHostResume(activity, new DefaultHardwareBackBtnHandlerImpl(activity));
|
||||
}
|
||||
|
||||
if (permissionsCallback != null) {
|
||||
permissionsCallback.invoke();
|
||||
permissionsCallback = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,15 +163,10 @@ public class JitsiMeetActivityDelegate {
|
||||
|
||||
public static void onRequestPermissionsResult(
|
||||
final int requestCode, final String[] permissions, final int[] grantResults) {
|
||||
permissionsCallback = new Callback() {
|
||||
@Override
|
||||
public void invoke(Object... args) {
|
||||
if (permissionListener != null
|
||||
&& permissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
|
||||
permissionListener = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
// Invoke the callback immediately
|
||||
if (permissionListener != null && permissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
|
||||
permissionListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void requestPermissions(Activity activity, String[] permissions, int requestCode, PermissionListener listener) {
|
||||
|
||||
@@ -99,6 +99,7 @@ public class JitsiMeetOngoingConferenceService extends Service implements Ongoin
|
||||
|
||||
public static void launch(Context context, HashMap<String, Object> extraData) {
|
||||
List<String> permissionsList = new ArrayList<>();
|
||||
Activity activity = (Activity) context;
|
||||
|
||||
PermissionListener listener = new PermissionListener() {
|
||||
@Override
|
||||
@@ -134,7 +135,7 @@ public class JitsiMeetOngoingConferenceService extends Service implements Ongoin
|
||||
|
||||
if (permissionsArray.length > 0) {
|
||||
JitsiMeetActivityDelegate.requestPermissions(
|
||||
(Activity) context,
|
||||
activity,
|
||||
permissionsArray,
|
||||
PERMISSIONS_REQUEST_CODE,
|
||||
listener
|
||||
@@ -159,12 +160,20 @@ public class JitsiMeetOngoingConferenceService extends Service implements Ongoin
|
||||
stopSelf();
|
||||
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
|
||||
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
|
||||
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
|
||||
} else {
|
||||
startForeground(NOTIFICATION_ID, notification);
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
|
||||
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
|
||||
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
|
||||
} else {
|
||||
startForeground(NOTIFICATION_ID, notification);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Handle ForegroundServiceStartNotAllowedException when app is in background and cannot start foreground service.
|
||||
// See: https://developer.android.com/develop/background-work/services/fgs/restrictions-bg-start#wiu-restrictions
|
||||
JitsiMeetLogger.w(TAG + " Failed to start foreground service", e);
|
||||
stopSelf();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
@@ -33,10 +34,9 @@ import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
public class JitsiMeetView extends FrameLayout {
|
||||
|
||||
/**
|
||||
* Background color used by {@code BaseReactView} and the React Native root
|
||||
* view.
|
||||
* Background color. Should match the background color set in JS.
|
||||
*/
|
||||
private static final int BACKGROUND_COLOR = 0xFF111111;
|
||||
public static final int BACKGROUND_COLOR = 0xFF040404;
|
||||
|
||||
/**
|
||||
* React Native root view.
|
||||
@@ -197,8 +197,6 @@ public class JitsiMeetView extends FrameLayout {
|
||||
}
|
||||
|
||||
setBackgroundColor(BACKGROUND_COLOR);
|
||||
|
||||
ReactInstanceManagerHolder.initReactInstanceManager((Activity) context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
/*
|
||||
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
import android.media.MediaCodecInfo;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.oney.WebRTCModule.webrtcutils.SoftwareVideoDecoderFactoryProxy;
|
||||
|
||||
import org.webrtc.EglBase;
|
||||
import org.webrtc.HardwareVideoDecoderFactory;
|
||||
import org.webrtc.JitsiPlatformVideoDecoderFactory;
|
||||
import org.webrtc.Predicate;
|
||||
import org.webrtc.VideoCodecInfo;
|
||||
import org.webrtc.VideoDecoder;
|
||||
import org.webrtc.VideoDecoderFactory;
|
||||
import org.webrtc.VideoDecoderFallback;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
/**
|
||||
* Custom decoder factory which uses HW decoders and falls back to SW.
|
||||
*/
|
||||
public class JitsiVideoDecoderFactory implements VideoDecoderFactory {
|
||||
private final VideoDecoderFactory hardwareVideoDecoderFactory;
|
||||
private final VideoDecoderFactory softwareVideoDecoderFactory = new SoftwareVideoDecoderFactoryProxy();
|
||||
private final VideoDecoderFactory platformSoftwareVideoDecoderFactory;
|
||||
|
||||
/**
|
||||
* Predicate to filter out the AV1 hardware decoder, as we've seen decoding issues with it.
|
||||
*/
|
||||
private static final String GOOGLE_AV1_DECODER = "c2.google.av1";
|
||||
private static final Predicate<MediaCodecInfo> hwCodecPredicate = arg -> {
|
||||
// Filter out the Google AV1 codec.
|
||||
return !arg.getName().startsWith(GOOGLE_AV1_DECODER);
|
||||
};
|
||||
private static final Predicate<MediaCodecInfo> swCodecPredicate = arg -> {
|
||||
// Noop, just making sure we can customize it easily if needed.
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create decoder factory using default hardware decoder factory.
|
||||
*/
|
||||
public JitsiVideoDecoderFactory(@Nullable EglBase.Context eglContext) {
|
||||
this.hardwareVideoDecoderFactory = new HardwareVideoDecoderFactory(eglContext, hwCodecPredicate);
|
||||
this.platformSoftwareVideoDecoderFactory = new JitsiPlatformVideoDecoderFactory(eglContext, swCodecPredicate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable VideoDecoder createDecoder(VideoCodecInfo codecType) {
|
||||
VideoDecoder softwareDecoder = softwareVideoDecoderFactory.createDecoder(codecType);
|
||||
final VideoDecoder hardwareDecoder = hardwareVideoDecoderFactory.createDecoder(codecType);
|
||||
if (softwareDecoder == null) {
|
||||
softwareDecoder = platformSoftwareVideoDecoderFactory.createDecoder(codecType);
|
||||
}
|
||||
if (hardwareDecoder != null && softwareDecoder != null) {
|
||||
// Both hardware and software supported, wrap it in a software fallback
|
||||
return new VideoDecoderFallback(
|
||||
/* fallback= */ softwareDecoder, /* primary= */ hardwareDecoder);
|
||||
}
|
||||
return hardwareDecoder != null ? hardwareDecoder : softwareDecoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VideoCodecInfo[] getSupportedCodecs() {
|
||||
LinkedHashSet<VideoCodecInfo> supportedCodecInfos = new LinkedHashSet<>();
|
||||
|
||||
supportedCodecInfos.addAll(Arrays.asList(softwareVideoDecoderFactory.getSupportedCodecs()));
|
||||
supportedCodecInfos.addAll(Arrays.asList(hardwareVideoDecoderFactory.getSupportedCodecs()));
|
||||
supportedCodecInfos.addAll(Arrays.asList(platformSoftwareVideoDecoderFactory.getSupportedCodecs()));
|
||||
|
||||
return supportedCodecInfos.toArray(new VideoCodecInfo[supportedCodecInfos.size()]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.oney.WebRTCModule.webrtcutils.H264AndSoftwareVideoEncoderFactory;
|
||||
|
||||
import org.webrtc.EglBase;
|
||||
|
||||
/**
|
||||
* Custom encoder factory which uses HW for H.264 and SW for everything else.
|
||||
*/
|
||||
public class JitsiVideoEncoderFactory extends H264AndSoftwareVideoEncoderFactory {
|
||||
public JitsiVideoEncoderFactory(@Nullable EglBase.Context eglContext) {
|
||||
super(eglContext);
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.util.Log;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -32,12 +32,9 @@ import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
import com.oney.WebRTCModule.EglUtils;
|
||||
import com.oney.WebRTCModule.WebRTCModuleOptions;
|
||||
import com.oney.WebRTCModule.webrtcutils.H264AndSoftwareVideoDecoderFactory;
|
||||
import com.oney.WebRTCModule.webrtcutils.H264AndSoftwareVideoEncoderFactory;
|
||||
|
||||
import org.devio.rn.splashscreen.SplashScreenModule;
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import org.webrtc.EglBase;
|
||||
import org.webrtc.Logging;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
@@ -67,10 +64,8 @@ class ReactInstanceManagerHolder {
|
||||
new AudioModeModule(reactContext),
|
||||
new DropboxModule(reactContext),
|
||||
new ExternalAPIModule(reactContext),
|
||||
new JavaScriptSandboxModule(reactContext),
|
||||
new LocaleDetector(reactContext),
|
||||
new LogBridgeModule(reactContext),
|
||||
new SplashScreenModule(reactContext),
|
||||
new PictureInPictureModule(reactContext),
|
||||
new ProximityModule(reactContext),
|
||||
new org.jitsi.meet.sdk.net.NAT64AddrInfoModule(reactContext)));
|
||||
@@ -92,7 +87,7 @@ class ReactInstanceManagerHolder {
|
||||
new com.reactnativecommunity.asyncstorage.AsyncStoragePackage(),
|
||||
new com.ocetnik.timer.BackgroundTimerPackage(),
|
||||
new com.calendarevents.RNCalendarEventsPackage(),
|
||||
new com.corbt.keepawake.KCKeepAwakePackage(),
|
||||
new com.sayem.keepawake.KCKeepAwakePackage(),
|
||||
new com.facebook.react.shell.MainReactPackage(),
|
||||
new com.reactnativecommunity.clipboard.ClipboardPackage(),
|
||||
new com.reactnativecommunity.netinfo.NetInfoPackage(),
|
||||
@@ -106,12 +101,13 @@ class ReactInstanceManagerHolder {
|
||||
new com.oney.WebRTCModule.WebRTCModulePackage(),
|
||||
new com.swmansion.gesturehandler.RNGestureHandlerPackage(),
|
||||
new org.linusu.RNGetRandomValuesPackage(),
|
||||
new com.rnimmersivemode.RNImmersiveModePackage(),
|
||||
new com.swmansion.rnscreens.RNScreensPackage(),
|
||||
new com.zmxv.RNSound.RNSoundPackage(),
|
||||
new com.th3rdwave.safeareacontext.SafeAreaContextPackage(),
|
||||
new com.horcrux.svg.SvgPackage(),
|
||||
new org.wonday.orientation.OrientationPackage(),
|
||||
new com.splashview.SplashViewPackage(),
|
||||
new com.worklets.WorkletsCorePackage(),
|
||||
new ReactPackageAdapter() {
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
@@ -126,31 +122,31 @@ class ReactInstanceManagerHolder {
|
||||
// AmplitudeReactNativePackage
|
||||
try {
|
||||
Class<?> amplitudePackageClass = Class.forName("com.amplitude.reactnative.AmplitudeReactNativePackage");
|
||||
Constructor constructor = amplitudePackageClass.getConstructor();
|
||||
Constructor<?> constructor = amplitudePackageClass.getConstructor();
|
||||
packages.add((ReactPackage)constructor.newInstance());
|
||||
} catch (Exception e) {
|
||||
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
|
||||
Log.d(TAG, "Not loading AmplitudeReactNativePackage");
|
||||
JitsiMeetLogger.d(TAG, "Not loading AmplitudeReactNativePackage");
|
||||
}
|
||||
|
||||
// GiphyReactNativeSdkPackage
|
||||
try {
|
||||
Class<?> giphyPackageClass = Class.forName("com.giphyreactnativesdk.GiphyReactNativeSdkPackage");
|
||||
Constructor constructor = giphyPackageClass.getConstructor();
|
||||
Class<?> giphyPackageClass = Class.forName("com.giphyreactnativesdk.RTNGiphySdkPackage");
|
||||
Constructor<?> constructor = giphyPackageClass.getConstructor();
|
||||
packages.add((ReactPackage)constructor.newInstance());
|
||||
} catch (Exception e) {
|
||||
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
|
||||
Log.d(TAG, "Not loading GiphyReactNativeSdkPackage");
|
||||
JitsiMeetLogger.d(TAG, "Not loading GiphyReactNativeSdkPackage");
|
||||
}
|
||||
|
||||
// RNGoogleSignInPackage
|
||||
try {
|
||||
Class<?> googlePackageClass = Class.forName("com.reactnativegooglesignin.RNGoogleSigninPackage");
|
||||
Constructor constructor = googlePackageClass.getConstructor();
|
||||
Constructor<?> constructor = googlePackageClass.getConstructor();
|
||||
packages.add((ReactPackage)constructor.newInstance());
|
||||
} catch (Exception e) {
|
||||
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
|
||||
Log.d(TAG, "Not loading RNGoogleSignInPackage");
|
||||
JitsiMeetLogger.d(TAG, "Not loading RNGoogleSignInPackage");
|
||||
}
|
||||
|
||||
return packages;
|
||||
@@ -169,7 +165,7 @@ class ReactInstanceManagerHolder {
|
||||
= ReactInstanceManagerHolder.getReactInstanceManager();
|
||||
|
||||
if (reactInstanceManager != null) {
|
||||
ReactContext reactContext
|
||||
@SuppressLint("VisibleForTests") ReactContext reactContext
|
||||
= reactInstanceManager.getCurrentReactContext();
|
||||
|
||||
if (reactContext != null) {
|
||||
@@ -192,7 +188,7 @@ class ReactInstanceManagerHolder {
|
||||
*/
|
||||
static <T extends NativeModule> T getNativeModule(
|
||||
Class<T> nativeModuleClass) {
|
||||
ReactContext reactContext
|
||||
@SuppressLint("VisibleForTests") ReactContext reactContext
|
||||
= reactInstanceManager != null
|
||||
? reactInstanceManager.getCurrentReactContext() : null;
|
||||
|
||||
@@ -210,35 +206,38 @@ class ReactInstanceManagerHolder {
|
||||
* time. All {@code ReactRootView} instances will be tied to the one and
|
||||
* only {@code ReactInstanceManager}.
|
||||
*
|
||||
* @param activity {@code Activity} current running Activity.
|
||||
* @param app {@code Application}
|
||||
*/
|
||||
static void initReactInstanceManager(Activity activity) {
|
||||
static void initReactInstanceManager(Application app) {
|
||||
if (reactInstanceManager != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the WebRTC module options.
|
||||
WebRTCModuleOptions options = WebRTCModuleOptions.getInstance();
|
||||
|
||||
EglBase.Context eglContext = EglUtils.getRootEglBaseContext();
|
||||
|
||||
options.videoDecoderFactory = new H264AndSoftwareVideoDecoderFactory(eglContext);
|
||||
options.videoEncoderFactory = new H264AndSoftwareVideoEncoderFactory(eglContext);
|
||||
options.enableMediaProjectionService = true;
|
||||
// options.loggingSeverity = Logging.Severity.LS_INFO;
|
||||
if (options.videoDecoderFactory == null || options.videoEncoderFactory == null) {
|
||||
EglBase.Context eglContext = EglUtils.getRootEglBaseContext();
|
||||
if (options.videoDecoderFactory == null) {
|
||||
options.videoDecoderFactory = new JitsiVideoDecoderFactory(eglContext);
|
||||
}
|
||||
if (options.videoEncoderFactory == null) {
|
||||
options.videoEncoderFactory = new JitsiVideoEncoderFactory(eglContext);
|
||||
}
|
||||
}
|
||||
|
||||
Log.d(TAG, "initializing RN with Activity");
|
||||
JitsiMeetLogger.d(TAG, "initializing RN");
|
||||
|
||||
reactInstanceManager
|
||||
= ReactInstanceManager.builder()
|
||||
.setApplication(activity.getApplication())
|
||||
.setCurrentActivity(activity)
|
||||
.setApplication(app)
|
||||
.setCurrentActivity(null)
|
||||
.setBundleAssetName("index.android.bundle")
|
||||
.setJSMainModulePath("index.android")
|
||||
.setJavaScriptExecutorFactory(new HermesExecutorFactory())
|
||||
.addPackages(getReactNativePackages())
|
||||
.setUseDeveloperSupport(BuildConfig.DEBUG)
|
||||
.setInitialLifecycleState(LifecycleState.RESUMED)
|
||||
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
import android.media.MediaCodecInfo;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/** Factory for Android platform software VideoDecoders. */
|
||||
public class JitsiPlatformVideoDecoderFactory extends MediaCodecVideoDecoderFactory {
|
||||
/**
|
||||
* Default allowed predicate.
|
||||
*/
|
||||
private static final Predicate<MediaCodecInfo> defaultAllowedPredicate =
|
||||
codecInfo -> {
|
||||
// We only want to use the platform software codecs.
|
||||
return MediaCodecUtils.isSoftwareOnly(codecInfo);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a PlatformSoftwareVideoDecoderFactory that supports surface texture rendering.
|
||||
*
|
||||
* @param sharedContext The textures generated will be accessible from this context. May be null,
|
||||
* this disables texture support.
|
||||
*/
|
||||
public JitsiPlatformVideoDecoderFactory(@Nullable EglBase.Context sharedContext) {
|
||||
super(sharedContext, defaultAllowedPredicate);
|
||||
}
|
||||
|
||||
public JitsiPlatformVideoDecoderFactory(@Nullable EglBase.Context sharedContext, @Nullable Predicate<MediaCodecInfo> codecAllowedPredicate) {
|
||||
super(sharedContext, codecAllowedPredicate == null ? defaultAllowedPredicate : codecAllowedPredicate.and(defaultAllowedPredicate));
|
||||
}
|
||||
}
|
||||
5
android/sdk/src/main/res/values/colors.xml
Normal file
5
android/sdk/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="navigationBarColor">#040404</color>
|
||||
<color name="statusBarColor">#040404</color>
|
||||
</resources>
|
||||
@@ -1,3 +1,6 @@
|
||||
<resources>
|
||||
<style name="JitsiMeetActivityStyle" parent="Theme.AppCompat.Light.NoActionBar"/>
|
||||
<style name="JitsiMeetActivityStyle" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<item name="android:navigationBarColor">@color/navigationBarColor</item>
|
||||
<item name="android:statusBarColor">@color/statusBarColor</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
rootProject.name = 'jitsi-meet'
|
||||
|
||||
include ':app', ':sdk'
|
||||
|
||||
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/analytics-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'
|
||||
@@ -26,10 +24,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-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')
|
||||
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/@sayem314/react-native-keep-awake/android')
|
||||
include ':react-native-orientation-locker'
|
||||
project(':react-native-orientation-locker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation-locker/android')
|
||||
include ':react-native-pager-view'
|
||||
@@ -44,8 +40,8 @@ include ':react-native-slider'
|
||||
project(':react-native-slider').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/slider/android')
|
||||
include ':react-native-sound'
|
||||
project(':react-native-sound').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sound/android')
|
||||
include ':react-native-splash-screen'
|
||||
project(':react-native-splash-screen').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-splash-screen/android')
|
||||
include ':react-native-splash-view'
|
||||
project(':react-native-splash-view').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-splash-view/android')
|
||||
include ':react-native-svg'
|
||||
project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')
|
||||
include ':react-native-video'
|
||||
@@ -54,3 +50,5 @@ include ':react-native-webrtc'
|
||||
project(':react-native-webrtc').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webrtc/android')
|
||||
include ':react-native-webview'
|
||||
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
|
||||
include ':react-native-worklets-core'
|
||||
project(':react-native-worklets-core').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-worklets-core/android')
|
||||
|
||||
26
app.js
26
app.js
@@ -10,6 +10,32 @@ import '@matrix-org/olm';
|
||||
|
||||
import 'focus-visible';
|
||||
|
||||
/*
|
||||
* Safari polyfill for createImageBitmap
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap
|
||||
*
|
||||
* Support source image types: Canvas.
|
||||
*/
|
||||
if (!('createImageBitmap' in window)) {
|
||||
window.createImageBitmap = function(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let dataURL;
|
||||
|
||||
if (data instanceof HTMLCanvasElement) {
|
||||
dataURL = data.toDataURL();
|
||||
} else {
|
||||
reject(new Error('createImageBitmap does not handle the provided image source type'));
|
||||
}
|
||||
const img = document.createElement('img');
|
||||
|
||||
img.addEventListener('load', () => {
|
||||
resolve(img);
|
||||
});
|
||||
img.src = dataURL;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// We need to setup the jitsi-local-storage as early as possible so that we can start using it.
|
||||
// NOTE: If jitsi-local-storage is used before the initial setup is performed this will break the use case when we use
|
||||
// the local storage from the parent page when the localStorage is disabled. Also the setup is relying that
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [ 'module:metro-react-native-babel-preset' ],
|
||||
presets: [ 'module:@react-native/babel-preset' ],
|
||||
env: {
|
||||
production: {
|
||||
plugins: [ 'react-native-paper/babel' ]
|
||||
@@ -8,9 +8,13 @@ module.exports = {
|
||||
|
||||
// This happens because react native has conflict with @babel/plugin-transform-private-methods plugin
|
||||
// https://github.com/ethers-io/ethers.js/discussions/4309#discussioncomment-6694524
|
||||
plugins: [ 'optional-require',
|
||||
[ '@babel/plugin-transform-private-methods', {
|
||||
'loose': true
|
||||
} ]
|
||||
plugins: [
|
||||
'optional-require',
|
||||
[
|
||||
'@babel/plugin-transform-private-methods', {
|
||||
'loose': true
|
||||
}
|
||||
],
|
||||
'react-native-worklets-core/plugin'
|
||||
]
|
||||
};
|
||||
|
||||
266
conference.js
266
conference.js
@@ -18,8 +18,6 @@ import {
|
||||
maybeRedirectToWelcomePage,
|
||||
reloadWithStoredParams
|
||||
} from './react/features/app/actions';
|
||||
import { showModeratedNotification } from './react/features/av-moderation/actions';
|
||||
import { shouldShowModeratedNotification } from './react/features/av-moderation/functions';
|
||||
import {
|
||||
_conferenceWillJoin,
|
||||
authStatusChanged,
|
||||
@@ -52,7 +50,8 @@ import {
|
||||
commonUserJoinedHandling,
|
||||
commonUserLeftHandling,
|
||||
getConferenceOptions,
|
||||
sendLocalParticipant
|
||||
sendLocalParticipant,
|
||||
updateTrackMuteState
|
||||
} from './react/features/base/conference/functions';
|
||||
import { getReplaceParticipant, getSsrcRewritingFeatureFlag } from './react/features/base/config/functions';
|
||||
import { connect } from './react/features/base/connection/actions.web';
|
||||
@@ -89,7 +88,7 @@ import {
|
||||
setVideoMuted,
|
||||
setVideoUnmutePermissions
|
||||
} from './react/features/base/media/actions';
|
||||
import { MEDIA_TYPE, VIDEO_TYPE } from './react/features/base/media/constants';
|
||||
import { MEDIA_TYPE, VIDEO_MUTISM_AUTHORITY, VIDEO_TYPE } from './react/features/base/media/constants';
|
||||
import {
|
||||
getStartWithAudioMuted,
|
||||
getStartWithVideoMuted,
|
||||
@@ -131,11 +130,11 @@ import {
|
||||
createLocalTracksF,
|
||||
getLocalJitsiAudioTrack,
|
||||
getLocalJitsiVideoTrack,
|
||||
getLocalTracks,
|
||||
getLocalVideoTrack,
|
||||
isLocalTrackMuted,
|
||||
isUserInteractionRequiredForUnmute
|
||||
} from './react/features/base/tracks/functions';
|
||||
import { getLocalJitsiAudioTrackSettings } from './react/features/base/tracks/functions.web';
|
||||
import { downloadJSON } from './react/features/base/util/downloadJSON';
|
||||
import { getJitsiMeetGlobalNSConnectionTimes } from './react/features/base/util/helpers';
|
||||
import { openLeaveReasonDialog } from './react/features/conference/actions.web';
|
||||
@@ -154,20 +153,20 @@ import {
|
||||
DATA_CHANNEL_CLOSED_NOTIFICATION_ID,
|
||||
NOTIFICATION_TIMEOUT_TYPE
|
||||
} from './react/features/notifications/constants';
|
||||
import { isModerationNotificationDisplayed } from './react/features/notifications/functions';
|
||||
import { suspendDetected } from './react/features/power-monitor/actions';
|
||||
import { initPrejoin, isPrejoinPageVisible } from './react/features/prejoin/functions';
|
||||
import { disableReceiver, stopReceiver } from './react/features/remote-control/actions';
|
||||
import { setScreenAudioShareState } from './react/features/screen-share/actions.web';
|
||||
import { isScreenAudioShared } from './react/features/screen-share/functions';
|
||||
import { toggleScreenshotCaptureSummary } from './react/features/screenshot-capture/actions';
|
||||
import { setAudioSettings } from './react/features/settings/actions.web';
|
||||
import { AudioMixerEffect } from './react/features/stream-effects/audio-mixer/AudioMixerEffect';
|
||||
import { createRnnoiseProcessor } from './react/features/stream-effects/rnnoise';
|
||||
import { handleToggleVideoMuted } from './react/features/toolbox/actions.any';
|
||||
import { transcriberJoined, transcriberLeft } from './react/features/transcribing/actions';
|
||||
import { muteLocal } from './react/features/video-menu/actions.any';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
const logger = Logger.getLogger('app:conference-web');
|
||||
let room;
|
||||
|
||||
/*
|
||||
@@ -206,23 +205,6 @@ function sendData(command, value) {
|
||||
room.sendCommand(command, { value });
|
||||
}
|
||||
|
||||
/**
|
||||
* Mute or unmute local audio stream if it exists.
|
||||
* @param {boolean} muted - if audio stream should be muted or unmuted.
|
||||
*/
|
||||
function muteLocalAudio(muted) {
|
||||
APP.store.dispatch(setAudioMuted(muted));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mute or unmute local video stream if it exists.
|
||||
* @param {boolean} muted if video stream should be muted or unmuted.
|
||||
*
|
||||
*/
|
||||
function muteLocalVideo(muted) {
|
||||
APP.store.dispatch(setVideoMuted(muted));
|
||||
}
|
||||
|
||||
/**
|
||||
* A queue for the async replaceLocalTrack action so that multiple audio
|
||||
* replacements cannot happen simultaneously. This solves the issue where
|
||||
@@ -586,7 +568,15 @@ export default {
|
||||
if (browser.isWebKitBased()) {
|
||||
this.muteAudio(true, true);
|
||||
} else {
|
||||
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
|
||||
localTracks = localTracks.filter(track => {
|
||||
if (track.getType() === MEDIA_TYPE.AUDIO) {
|
||||
track.stopStream();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,7 +591,7 @@ export default {
|
||||
|
||||
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(initialOptions, true);
|
||||
|
||||
tryCreateLocalTracks.then(async tr => {
|
||||
tryCreateLocalTracks.then(tr => {
|
||||
const createLocalTracksEnd = window.performance.now();
|
||||
|
||||
connectionTimes['conference.init.createLocalTracks.end'] = createLocalTracksEnd;
|
||||
@@ -709,11 +699,10 @@ export default {
|
||||
* Simulates toolbar button click for audio mute. Used by shortcuts and API.
|
||||
*
|
||||
* @param {boolean} mute true for mute and false for unmute.
|
||||
* @param {boolean} [showUI] when set to false will not display any error
|
||||
* dialogs in case of media permissions error.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async muteAudio(mute, showUI = true) {
|
||||
async muteAudio(mute) {
|
||||
const state = APP.store.getState();
|
||||
|
||||
if (!mute
|
||||
@@ -723,56 +712,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// check for A/V Moderation when trying to unmute
|
||||
if (!mute && shouldShowModeratedNotification(MEDIA_TYPE.AUDIO, state)) {
|
||||
if (!isModerationNotificationDisplayed(MEDIA_TYPE.AUDIO, state)) {
|
||||
APP.store.dispatch(showModeratedNotification(MEDIA_TYPE.AUDIO));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Not ready to modify track's state yet
|
||||
if (!this._localTracksInitialized) {
|
||||
// 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.updateAudioIconEnabled();
|
||||
|
||||
return;
|
||||
} else if (this.isLocalAudioMuted() === mute) {
|
||||
// NO-OP
|
||||
return;
|
||||
}
|
||||
|
||||
const localAudio = getLocalJitsiAudioTrack(APP.store.getState());
|
||||
|
||||
if (!localAudio && !mute) {
|
||||
const maybeShowErrorDialog = error => {
|
||||
showUI && APP.store.dispatch(notifyMicError(error));
|
||||
};
|
||||
|
||||
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO ], IGUMPendingState.PENDING_UNMUTE));
|
||||
|
||||
await createLocalTracksF({ devices: [ 'audio' ] })
|
||||
.then(([ audioTrack ]) => audioTrack)
|
||||
.catch(error => {
|
||||
maybeShowErrorDialog(error);
|
||||
|
||||
// Rollback the audio muted status by using null track
|
||||
return null;
|
||||
})
|
||||
.then(async audioTrack => {
|
||||
await this._maybeApplyAudioMixerEffect(audioTrack);
|
||||
|
||||
return this.useAudioStream(audioTrack);
|
||||
})
|
||||
.finally(() => {
|
||||
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO ], IGUMPendingState.NONE));
|
||||
});
|
||||
} else {
|
||||
muteLocalAudio(mute);
|
||||
}
|
||||
await APP.store.dispatch(setAudioMuted(mute, true));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -802,16 +742,9 @@ export default {
|
||||
/**
|
||||
* Simulates toolbar button click for video mute. Used by shortcuts and API.
|
||||
* @param mute true for mute and false for unmute.
|
||||
* @param {boolean} [showUI] when set to false will not display any error
|
||||
* dialogs in case of media permissions error.
|
||||
*/
|
||||
muteVideo(mute, showUI = true) {
|
||||
if (this.videoSwitchInProgress) {
|
||||
logger.warn('muteVideo - unable to perform operations while video switch is in progress');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
muteVideo(mute) {
|
||||
const state = APP.store.getState();
|
||||
|
||||
if (!mute
|
||||
@@ -821,65 +754,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// check for A/V Moderation when trying to unmute and return early
|
||||
if (!mute && shouldShowModeratedNotification(MEDIA_TYPE.VIDEO, state)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If not ready to modify track's state yet adjust the base/media
|
||||
if (!this._localTracksInitialized) {
|
||||
// This will only modify base/media.video.muted which is then synced
|
||||
// up with the track at the end of local tracks initialization.
|
||||
muteLocalVideo(mute);
|
||||
this.setVideoMuteStatus();
|
||||
|
||||
return;
|
||||
} else if (this.isLocalVideoMuted() === mute) {
|
||||
// NO-OP
|
||||
return;
|
||||
}
|
||||
|
||||
const localVideo = getLocalJitsiVideoTrack(state);
|
||||
|
||||
if (!localVideo && !mute && !this.isCreatingLocalTrack) {
|
||||
const maybeShowErrorDialog = error => {
|
||||
showUI && APP.store.dispatch(notifyCameraError(error));
|
||||
};
|
||||
|
||||
this.isCreatingLocalTrack = true;
|
||||
|
||||
APP.store.dispatch(gumPending([ MEDIA_TYPE.VIDEO ], IGUMPendingState.PENDING_UNMUTE));
|
||||
|
||||
// Try to create local video if there wasn't any.
|
||||
// This handles the case when user joined with no video
|
||||
// (dismissed screen sharing screen or in audio only mode), but
|
||||
// decided to add it later on by clicking on muted video icon or
|
||||
// turning off the audio only mode.
|
||||
//
|
||||
// FIXME when local track creation is moved to react/redux
|
||||
// it should take care of the use case described above
|
||||
createLocalTracksF({ devices: [ 'video' ] })
|
||||
.then(([ videoTrack ]) => videoTrack)
|
||||
.catch(error => {
|
||||
// FIXME should send some feedback to the API on error ?
|
||||
maybeShowErrorDialog(error);
|
||||
|
||||
// Rollback the video muted status by using null track
|
||||
return null;
|
||||
})
|
||||
.then(videoTrack => {
|
||||
logger.debug(`muteVideo: calling useVideoStream for track: ${videoTrack}`);
|
||||
|
||||
return this.useVideoStream(videoTrack);
|
||||
})
|
||||
.finally(() => {
|
||||
this.isCreatingLocalTrack = false;
|
||||
APP.store.dispatch(gumPending([ MEDIA_TYPE.VIDEO ], IGUMPendingState.NONE));
|
||||
});
|
||||
} else {
|
||||
// FIXME show error dialog if it fails (should be handled by react)
|
||||
muteLocalVideo(mute);
|
||||
}
|
||||
APP.store.dispatch(setVideoMuted(mute, VIDEO_MUTISM_AUTHORITY.USER, true));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1060,6 +935,14 @@ export default {
|
||||
downloadJSON(logs, filename);
|
||||
},
|
||||
|
||||
/**
|
||||
* Download app state, a function that can be called from console while debugging.
|
||||
* @param filename (optional) specify target filename
|
||||
*/
|
||||
saveState(filename = 'meet-state.json') {
|
||||
downloadJSON(APP.store.getState(), filename);
|
||||
},
|
||||
|
||||
/**
|
||||
* Exposes a Command(s) API on this instance. It is necessitated by (1) the
|
||||
* desire to keep room private to this instance and (2) the need of other
|
||||
@@ -1124,7 +1007,6 @@ export default {
|
||||
|
||||
// Restore initial state.
|
||||
this._localTracksInitialized = false;
|
||||
this.isSharingScreen = false;
|
||||
this.roomName = roomName;
|
||||
|
||||
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(options);
|
||||
@@ -1303,8 +1185,6 @@ export default {
|
||||
return Boolean(APP.store.getState()['features/base/audio-only'].enabled);
|
||||
},
|
||||
|
||||
videoSwitchInProgress: false,
|
||||
|
||||
/**
|
||||
* This fields stores a handler which will create a Promise which turns off
|
||||
* the screen sharing and restores the previous video state (was there
|
||||
@@ -1333,7 +1213,6 @@ export default {
|
||||
*/
|
||||
async _turnScreenSharingOff(didHaveVideo, ignoreDidHaveVideo) {
|
||||
this._untoggleScreenSharing = null;
|
||||
this.videoSwitchInProgress = true;
|
||||
|
||||
APP.store.dispatch(stopReceiver());
|
||||
|
||||
@@ -1385,13 +1264,11 @@ export default {
|
||||
|
||||
return promise.then(
|
||||
() => {
|
||||
this.videoSwitchInProgress = false;
|
||||
sendAnalytics(createScreenSharingEvent('stopped',
|
||||
duration === 0 ? null : duration));
|
||||
logger.info('Screen sharing stopped.');
|
||||
},
|
||||
error => {
|
||||
this.videoSwitchInProgress = false;
|
||||
logger.error(`_turnScreenSharingOff failed: ${error}`);
|
||||
|
||||
throw error;
|
||||
@@ -1421,14 +1298,13 @@ export default {
|
||||
this._untoggleScreenSharing
|
||||
= this._turnScreenSharingOff.bind(this, didHaveVideo);
|
||||
|
||||
const desktopVideoStream = desktopStreams.find(stream => stream.getType() === MEDIA_TYPE.VIDEO);
|
||||
const desktopAudioStream = desktopStreams.find(stream => stream.getType() === MEDIA_TYPE.AUDIO);
|
||||
|
||||
if (desktopAudioStream) {
|
||||
desktopAudioStream.on(
|
||||
JitsiTrackEvents.LOCAL_TRACK_STOPPED,
|
||||
() => {
|
||||
logger.debug(`Local screensharing audio track stopped. ${this.isSharingScreen}`);
|
||||
logger.debug('Local screensharing audio track stopped.');
|
||||
|
||||
// Handle case where screen share was stopped from the browsers 'screen share in progress'
|
||||
// window. If audio screen sharing is stopped via the normal UX flow this point shouldn't
|
||||
@@ -1440,21 +1316,6 @@ export default {
|
||||
);
|
||||
}
|
||||
|
||||
if (desktopVideoStream) {
|
||||
desktopVideoStream.on(
|
||||
JitsiTrackEvents.LOCAL_TRACK_STOPPED,
|
||||
() => {
|
||||
logger.debug(`Local screensharing track stopped. ${this.isSharingScreen}`);
|
||||
|
||||
// If the stream was stopped during screen sharing
|
||||
// session then we should switch back to video.
|
||||
this.isSharingScreen
|
||||
&& this._untoggleScreenSharing
|
||||
&& this._untoggleScreenSharing();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return desktopStreams;
|
||||
}, error => {
|
||||
throw error;
|
||||
@@ -1514,7 +1375,7 @@ export default {
|
||||
}
|
||||
|
||||
APP.store.dispatch(updateRemoteParticipantFeatures(user));
|
||||
logger.log(`USER ${id} connected:`, user);
|
||||
logger.log(`USER ${id} connected`);
|
||||
APP.UI.addUser(user);
|
||||
});
|
||||
|
||||
@@ -1548,7 +1409,6 @@ export default {
|
||||
}
|
||||
|
||||
APP.store.dispatch(localParticipantRoleChanged(role));
|
||||
APP.API.notifyUserRoleChanged(id, role);
|
||||
} else {
|
||||
APP.store.dispatch(participantRoleChanged(id, role));
|
||||
}
|
||||
@@ -1603,10 +1463,6 @@ export default {
|
||||
room.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED, (track, participantThatMutedUs) => {
|
||||
if (participantThatMutedUs) {
|
||||
APP.store.dispatch(participantMutedUs(participantThatMutedUs, track));
|
||||
if (this.isSharingScreen && track.isVideoTrack()) {
|
||||
logger.debug('TRACK_MUTE_CHANGED while screen sharing');
|
||||
this._turnScreenSharingOff(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1818,39 +1674,14 @@ export default {
|
||||
room.on(
|
||||
JitsiConferenceEvents.START_MUTED_POLICY_CHANGED,
|
||||
({ audio, video }) => {
|
||||
APP.store.dispatch(
|
||||
onStartMutedPolicyChanged(audio, video));
|
||||
APP.store.dispatch(onStartMutedPolicyChanged(audio, video));
|
||||
|
||||
const state = APP.store.getState();
|
||||
|
||||
updateTrackMuteState(state, APP.store.dispatch, true);
|
||||
updateTrackMuteState(state, APP.store.dispatch, false);
|
||||
}
|
||||
);
|
||||
room.on(JitsiConferenceEvents.STARTED_MUTED, () => {
|
||||
const audioMuted = room.isStartAudioMuted();
|
||||
const videoMuted = room.isStartVideoMuted();
|
||||
const localTracks = getLocalTracks(APP.store.getState()['features/base/tracks']);
|
||||
const promises = [];
|
||||
|
||||
APP.store.dispatch(setAudioMuted(audioMuted));
|
||||
APP.store.dispatch(setVideoMuted(videoMuted));
|
||||
|
||||
// Remove the tracks from the peerconnection.
|
||||
for (const track of localTracks) {
|
||||
// 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.
|
||||
if (audioMuted && track.jitsiTrack?.getType() === MEDIA_TYPE.AUDIO && !browser.isWebKitBased()) {
|
||||
promises.push(this.useAudioStream(null));
|
||||
}
|
||||
if (videoMuted && track.jitsiTrack?.getType() === MEDIA_TYPE.VIDEO) {
|
||||
promises.push(this.useVideoStream(null));
|
||||
}
|
||||
}
|
||||
|
||||
Promise.allSettled(promises)
|
||||
.then(() => {
|
||||
APP.store.dispatch(showNotification({
|
||||
titleKey: 'notify.mutedTitle',
|
||||
descriptionKey: 'notify.muted'
|
||||
}, NOTIFICATION_TIMEOUT_TYPE.SHORT));
|
||||
});
|
||||
});
|
||||
|
||||
room.on(
|
||||
JitsiConferenceEvents.DATA_CHANNEL_OPENED, () => {
|
||||
@@ -1888,6 +1719,16 @@ export default {
|
||||
}, timeout);
|
||||
}
|
||||
);
|
||||
|
||||
room.on(JitsiConferenceEvents.PERMISSIONS_RECEIVED, p => {
|
||||
const localParticipant = getLocalParticipant(APP.store.getState());
|
||||
|
||||
APP.store.dispatch(participantUpdated({
|
||||
id: localParticipant.id,
|
||||
local: true,
|
||||
features: p
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1932,7 +1773,11 @@ export default {
|
||||
return this.useAudioStream(stream);
|
||||
})
|
||||
.then(() => {
|
||||
const localAudio = getLocalJitsiAudioTrack(APP.store.getState());
|
||||
const state = APP.store.getState();
|
||||
const localAudio = getLocalJitsiAudioTrack(state);
|
||||
const settings = getLocalJitsiAudioTrackSettings(state);
|
||||
|
||||
APP.store.dispatch(setAudioSettings(settings));
|
||||
|
||||
if (localAudio && isDefaultMicSelected) {
|
||||
// workaround for the default device to be shown as selected in the
|
||||
@@ -2052,8 +1897,7 @@ export default {
|
||||
_initDeviceList(setDeviceListChangeHandler = false) {
|
||||
const { mediaDevices } = JitsiMeetJS;
|
||||
|
||||
if (mediaDevices.isDeviceListAvailable()
|
||||
&& mediaDevices.isDeviceChangeAvailable()) {
|
||||
if (mediaDevices.isDeviceChangeAvailable()) {
|
||||
if (setDeviceListChangeHandler) {
|
||||
this.deviceChangeListener = devices =>
|
||||
window.setTimeout(() => this._onDeviceListChanged(devices), 0);
|
||||
@@ -2278,8 +2122,10 @@ export default {
|
||||
* @param {boolean} [requestFeedback=false] if user feedback should be
|
||||
* @param {string} [hangupReason] the reason for leaving the meeting
|
||||
* requested
|
||||
* @param {boolean} [notifyOnConferenceTermination] whether to notify
|
||||
* the user on conference termination
|
||||
*/
|
||||
hangup(requestFeedback = false, hangupReason) {
|
||||
hangup(requestFeedback = false, hangupReason, notifyOnConferenceTermination) {
|
||||
APP.store.dispatch(disableReceiver());
|
||||
|
||||
this._stopProxyConnection();
|
||||
@@ -2298,7 +2144,7 @@ export default {
|
||||
|
||||
if (requestFeedback) {
|
||||
const feedbackDialogClosed = (feedbackResult = {}) => {
|
||||
if (!feedbackResult.wasDialogShown && hangupReason) {
|
||||
if (!feedbackResult.wasDialogShown && hangupReason && notifyOnConferenceTermination) {
|
||||
return APP.store.dispatch(
|
||||
openLeaveReasonDialog(hangupReason)).then(() => feedbackResult);
|
||||
}
|
||||
|
||||
138
config.js
138
config.js
@@ -49,7 +49,9 @@ var config = {
|
||||
bosh: 'https://jitsi-meet.example.com/' + subdir + 'http-bind',
|
||||
|
||||
// Websocket URL (XMPP)
|
||||
// websocket: 'wss://jitsi-meet.example.com/' + subdir + 'xmpp-websocket',
|
||||
websocket: 'wss://jitsi-meet.example.com/' + subdir + 'xmpp-websocket',
|
||||
|
||||
// websocketKeepAliveUrl: 'https://jitsi-meet.example.com/' + subdir + '_unlock',
|
||||
|
||||
// Whether BOSH should be preferred over WebSocket if both are configured.
|
||||
// preferBosh: false,
|
||||
@@ -87,6 +89,9 @@ var config = {
|
||||
// Enables use of getDisplayMedia in electron
|
||||
// electronUseGetDisplayMedia: false,
|
||||
|
||||
// Enables AV1 codec for FF. Note: By default it is disabled.
|
||||
// enableAV1ForFF: false,
|
||||
|
||||
// Enables the use of the codec selection API supported by the browsers .
|
||||
// enableCodecSelectionAPI: false,
|
||||
|
||||
@@ -112,6 +117,11 @@ var config = {
|
||||
|
||||
// Will replace ice candidates IPs with invalid ones in order to fail ice.
|
||||
// failICE: true,
|
||||
|
||||
// When running on Spot TV, this controls whether to show the recording consent dialog.
|
||||
// If false (default), Spot instances will not show the recording consent dialog.
|
||||
// If true, Spot instances will show the recording consent dialog like regular clients.
|
||||
// showSpotConsentDialog: false,
|
||||
},
|
||||
|
||||
// Disables moderator indicators.
|
||||
@@ -123,9 +133,15 @@ var config = {
|
||||
// Disables the reactions moderation feature.
|
||||
// disableReactionsModeration: false,
|
||||
|
||||
// Disables the reactions in chat feature.
|
||||
// disableReactionsInChat: false,
|
||||
|
||||
// Disables polls feature.
|
||||
// disablePolls: false,
|
||||
|
||||
// Disables chat feature entirely including notifications, sounds, and private messages.
|
||||
// disableChat: false,
|
||||
|
||||
// Disables demote button from self-view
|
||||
// disableSelfDemote: false,
|
||||
|
||||
@@ -350,6 +366,7 @@ var config = {
|
||||
// Desktop sharing
|
||||
|
||||
// Optional desktop sharing frame rate options. Default value: min:5, max:5.
|
||||
// Setting higher min/max values will affect the resolution, it makes it worse.
|
||||
// desktopSharingFrameRate: {
|
||||
// min: 5,
|
||||
// max: 5,
|
||||
@@ -393,6 +410,13 @@ var config = {
|
||||
// // showPrejoinWarning: true,
|
||||
// // If true, the notification for recording start will display a link to download the cloud recording.
|
||||
// // showRecordingLink: true,
|
||||
// // If true, mutes audio and video when a recording begins and displays a dialog
|
||||
// // explaining the effect of unmuting.
|
||||
// // requireConsent: true,
|
||||
// // If true consent will be skipped for users who are already in the meeting.
|
||||
// // skipConsentInMeeting: true,
|
||||
// // Link for the recording consent dialog's "Learn more" link.
|
||||
// // consentLearnMoreLink: 'https://jitsi.org/meet/consent',
|
||||
// },
|
||||
|
||||
// recordingService: {
|
||||
@@ -490,6 +514,12 @@ var config = {
|
||||
// // Enables automatic request of subtitles when transcriber is present in the meeting, uses the default
|
||||
// // language that is set
|
||||
// autoCaptionOnTranscribe: false,
|
||||
//
|
||||
// // Disables everything related to closed captions - the tab in the chat area, the button in the menu,
|
||||
// // subtitles on stage and the "Show subtitles on stage" checkbox in the settings.
|
||||
// // Note: Starting transcriptions from the recording dialog will still work.
|
||||
// disableClosedCaptions: false,
|
||||
|
||||
// },
|
||||
|
||||
// Misc
|
||||
@@ -515,7 +545,7 @@ var config = {
|
||||
// videoQuality: {
|
||||
//
|
||||
// // Provides a way to set the codec preference on desktop based endpoints.
|
||||
// codecPreferenceOrder: [ 'VP9', 'VP8', 'H264', 'AV1' ],
|
||||
// codecPreferenceOrder: [ 'AV1', 'VP9', 'VP8', 'H264' ],
|
||||
//
|
||||
// // Provides a way to set the codec for screenshare.
|
||||
// screenshareCodec: 'AV1',
|
||||
@@ -592,7 +622,7 @@ var config = {
|
||||
// },
|
||||
//
|
||||
// // Provides a way to set the codec preference on mobile devices, both on RN and mobile browser based endpoint
|
||||
// mobileCodecPreferenceOrder: [ 'VP8', 'VP9', 'H264' ],
|
||||
// mobileCodecPreferenceOrder: [ 'VP8', 'VP9', 'H264', 'AV1' ],
|
||||
// },
|
||||
|
||||
// Notification timeouts
|
||||
@@ -601,6 +631,7 @@ var config = {
|
||||
// medium: 5000,
|
||||
// long: 10000,
|
||||
// extraLong: 60000,
|
||||
// sticky: 0,
|
||||
// },
|
||||
|
||||
// // Options for the recording limit notification.
|
||||
@@ -692,6 +723,8 @@ var config = {
|
||||
// autoKnock: false,
|
||||
// // Enables the lobby chat. Replaces `enableLobbyChat`.
|
||||
// enableChat: true,
|
||||
// // Shows the hangup button in the lobby screen.
|
||||
// showHangUp: true,
|
||||
// },
|
||||
|
||||
// Configs for the security related UI elements.
|
||||
@@ -731,7 +764,7 @@ var config = {
|
||||
// hideDominantSpeakerBadge: false,
|
||||
|
||||
// Default language for the user interface. Cannot be overwritten.
|
||||
// DEPRECATED! Use the `lang` iframe option directly instead.
|
||||
// For iframe integrations, use the `lang` option directly instead.
|
||||
// defaultLanguage: 'en',
|
||||
|
||||
// Disables profile and the edit of all fields from the profile settings (display name and email)
|
||||
@@ -752,13 +785,15 @@ var config = {
|
||||
// and microsoftApiApplicationClientID
|
||||
// enableCalendarIntegration: false,
|
||||
|
||||
// Whether to notify when the conference is terminated because it was destroyed.
|
||||
// notifyOnConferenceDestruction: true,
|
||||
|
||||
// The client id for the google APIs used for the calendar integration, youtube livestreaming, etc.
|
||||
// googleApiApplicationClientID: '<client_id>',
|
||||
|
||||
// Configs for prejoin page.
|
||||
// prejoinConfig: {
|
||||
// // When 'true', it shows an intermediate page before joining, where the user can configure their devices.
|
||||
// // 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
|
||||
@@ -770,7 +805,9 @@ var config = {
|
||||
// // By setting preCallTestEnabled, you enable the pre-call test in the prejoin page.
|
||||
// // ICE server credentials need to be provided over the preCallTestICEUrl
|
||||
// preCallTestEnabled: false,
|
||||
// preCallTestICEUrl: ''
|
||||
// preCallTestICEUrl: '',
|
||||
// // Shows the hangup button in the lobby screen.
|
||||
// showHangUp: true,
|
||||
// },
|
||||
|
||||
// When 'true', the user cannot edit the display name.
|
||||
@@ -815,8 +852,7 @@ var config = {
|
||||
// some other values in config.js to be enabled. Also, the "profile" button will
|
||||
// not display for users with a JWT.
|
||||
// Notes:
|
||||
// - it's impossible to choose which buttons go in the "More actions" menu
|
||||
// - it's impossible to control the placement of buttons
|
||||
// - it's possible to reorder the buttons in the maintoolbar by changing the order of the mainToolbarButtons
|
||||
// - 'desktop' controls the "Share your screen" button
|
||||
// - if `toolbarButtons` is undefined, we fallback to enabling all buttons on the UI
|
||||
// toolbarButtons: [
|
||||
@@ -868,6 +904,8 @@ var config = {
|
||||
// alwaysVisible: false,
|
||||
// // Indicates whether the toolbar should still autohide when chat is open
|
||||
// autoHideWhileChatIsOpen: false,
|
||||
// // Default background color for the main toolbar. Accepts any valid CSS color.
|
||||
// // backgroundColor: '#ffffff',
|
||||
// },
|
||||
|
||||
// Overrides the buttons displayed in the main toolbar. Depending on the screen size the number of displayed
|
||||
@@ -886,6 +924,11 @@ var config = {
|
||||
// [ 'microphone', 'camera' ]
|
||||
// ],
|
||||
|
||||
// Overrides the buttons displayed in the main toolbar for reduced UI.
|
||||
// When there isn't an override for a certain configuration the default jitsi-meet configuration will be used.
|
||||
// The order of the buttons in the array is preserved.
|
||||
// reducedUImainToolbarButtons: [ 'microphone', 'camera' ],
|
||||
|
||||
// Toolbar buttons which have their click/tap event exposed through the API on
|
||||
// `toolbarButtonClicked`. Passing a string for the button key will
|
||||
// prevent execution of the click/tap routine; passing an object with `key` and
|
||||
@@ -1067,10 +1110,10 @@ var config = {
|
||||
|
||||
// Provides a way to set the codec preference on mobile devices, both on RN and mobile browser based
|
||||
// endpoints.
|
||||
// mobileCodecPreferenceOrder: [ 'H264', 'VP8', 'VP9' ],
|
||||
// mobileCodecPreferenceOrder: [ 'H264', 'VP8', 'VP9', 'AV1' ],
|
||||
//
|
||||
// Provides a way to set the codec preference on desktop based endpoints.
|
||||
// codecPreferenceOrder: [ 'VP9', 'VP8', 'H264 ],
|
||||
// codecPreferenceOrder: [ 'AV1', 'VP9', 'VP8', 'H264 ],
|
||||
|
||||
// Provides a way to set the codec for screenshare.
|
||||
// screenshareCodec: 'AV1',
|
||||
@@ -1099,10 +1142,6 @@ 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,
|
||||
@@ -1246,9 +1285,6 @@ var config = {
|
||||
// disableDeepLinking: false,
|
||||
|
||||
// The deeplinking config.
|
||||
// For information about the properties of
|
||||
// deeplinking.[ios/android].dynamicLink check:
|
||||
// https://firebase.google.com/docs/dynamic-links/create-manually
|
||||
// deeplinking: {
|
||||
//
|
||||
// // The desktop deeplinking config, disabled by default.
|
||||
@@ -1277,13 +1313,6 @@ var config = {
|
||||
// appScheme: 'org.jitsi.meet',
|
||||
// // Custom URL for downloading ios mobile app.
|
||||
// downloadLink: 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905',
|
||||
// dynamicLink: {
|
||||
// apn: 'org.jitsi.meet',
|
||||
// appCode: 'w2atb',
|
||||
// customDomain: undefined,
|
||||
// ibi: 'com.atlassian.JitsiMeet.ios',
|
||||
// isi: '1165103905'
|
||||
// }
|
||||
// },
|
||||
|
||||
// // The android deeplinking config.
|
||||
@@ -1296,13 +1325,6 @@ var config = {
|
||||
// // Android app package name.
|
||||
// appPackage: 'org.jitsi.meet',
|
||||
// fDroidUrl: 'https://f-droid.org/en/packages/org.jitsi.meet/',
|
||||
// dynamicLink: {
|
||||
// apn: 'org.jitsi.meet',
|
||||
// appCode: 'w2atb',
|
||||
// customDomain: undefined,
|
||||
// ibi: 'com.atlassian.JitsiMeet.ios',
|
||||
// isi: '1165103905'
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
|
||||
@@ -1350,18 +1372,13 @@ var config = {
|
||||
// disableKick: true,
|
||||
// // If set to true the 'Grant moderator' button will be disabled.
|
||||
// disableGrantModerator: true,
|
||||
// // If set to true the 'Send private message' button will be disabled.
|
||||
// disablePrivateChat: true,
|
||||
// // If set to 'all' the 'Private chat' button will be disabled for all participants.
|
||||
// // If set to 'allow-moderator-chat' the 'Private chat' button will be available for chats with moderators.
|
||||
// // If set to 'disable-visitor-chat' the 'Private chat' button will be disabled for visitor-main participant
|
||||
// // conversations.
|
||||
// disablePrivateChat: 'all' | 'allow-moderator-chat' | 'disable-visitor-chat',
|
||||
// },
|
||||
|
||||
// Endpoint that enables support for salesforce integration with in-meeting resource linking
|
||||
// This is required for:
|
||||
// listing the most recent records - salesforceUrl/records/recents
|
||||
// searching records - salesforceUrl/records?text=${text}
|
||||
// retrieving record details - salesforceUrl/records/${id}?type=${type}
|
||||
// and linking the meeting - salesforceUrl/sessions/${sessionId}/records/${id}
|
||||
//
|
||||
// salesforceUrl: 'https://api.example.com/',
|
||||
|
||||
// If set to true all muting operations of remote participants will be disabled.
|
||||
// disableRemoteMute: true,
|
||||
@@ -1372,8 +1389,12 @@ var config = {
|
||||
The config file should be in JSON.
|
||||
None of the fields are mandatory and the response must have the shape:
|
||||
{
|
||||
// Whether participant can only send group chat message if `send-groupchat` feature is enabled in jwt.
|
||||
groupChatRequiresPermission: false,
|
||||
// Whether participant can only create polls if `create-polls` feature is enabled in jwt.
|
||||
pollCreationRequiresPermission: false,
|
||||
// The domain url to apply (will replace the domain in the sharing conference link/embed section)
|
||||
inviteDomain: 'example-company.org,
|
||||
inviteDomain: 'example-company.org',
|
||||
// The hex value for the colour used as background
|
||||
backgroundColor: '#fff',
|
||||
// The url for the image used as background
|
||||
@@ -1382,6 +1403,13 @@ var config = {
|
||||
logoClickUrl: 'https://example-company.org',
|
||||
// The url used for the image used as logo
|
||||
logoImageUrl: 'https://example.com/logo-img.png',
|
||||
// Endpoint that enables support for salesforce integration with in-meeting resource linking
|
||||
// This is required for:
|
||||
// listing the most recent records - salesforceUrl/records/recents
|
||||
// searching records - salesforceUrl/records?text=${text}
|
||||
// retrieving record details - salesforceUrl/records/${id}?type=${type}
|
||||
// and linking the meeting - salesforceUrl/sessions/${sessionId}/records/${id}
|
||||
// salesforceUrl: 'https://api.example.com/',
|
||||
// Overwrite for pool of background images for avatars
|
||||
avatarBackgrounds: ['url(https://example.com/avatar-background-1.png)', '#FFF'],
|
||||
// The lobby/prejoin screen background
|
||||
@@ -1561,6 +1589,11 @@ var config = {
|
||||
// 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
|
||||
// An option to respect the context.tenant jwt field compared to the current tenant from the url
|
||||
// tokenRespectTenant: false,
|
||||
// An option to get for user info (name, picture, email) in the token outside the user context.
|
||||
// Can be used with Firebase tokens.
|
||||
// tokenGetUserInfoOutOfContext: false,
|
||||
|
||||
// You can put an array of values to target different entity types in the invite dialog.
|
||||
// Valid values are "phone", "room", "sip", "user", "videosipgw" and "email"
|
||||
@@ -1581,6 +1614,10 @@ var config = {
|
||||
// audio: true,
|
||||
// video: true
|
||||
// },
|
||||
// // Hides the visitor count for visitors.
|
||||
// // hideVisitorCountForVisitors: false,
|
||||
// // Whether to show the join meeting dialog when joining as a visitor.
|
||||
// // showJoinMeetingDialog: true,
|
||||
// },
|
||||
// The default type of desktop sharing sources that will be used in the electron app.
|
||||
// desktopSharingSources: ['screen', 'window'],
|
||||
@@ -1760,6 +1797,13 @@ var config = {
|
||||
// // The minimum number of participants that must be in the call for
|
||||
// // the top panel layout to be used.
|
||||
// minParticipantCountForTopPanel: 50,
|
||||
|
||||
// // The width of the filmstrip on joining meeting. Can be resized afterwards.
|
||||
// initialWidth: 400,
|
||||
|
||||
// // Whether the draggable resize bar of the filmstrip is always visible. Setting this to true will make
|
||||
// // the filmstrip always visible in case `disableResizable` is false.
|
||||
// alwaysShowResizeBar: true,
|
||||
// },
|
||||
|
||||
// Tile view related config options.
|
||||
@@ -1861,6 +1905,16 @@ var config = {
|
||||
|
||||
// If true remove the tint foreground on focused user camera in filmstrip
|
||||
// disableCameraTintForeground: false,
|
||||
|
||||
// File sharign service.
|
||||
// fileSharing: {
|
||||
// // The URL of the file sharing service API. See resources/file-sharing.yaml for more details.
|
||||
// apiUrl: 'https://example.com',
|
||||
// // Whether the file sharing service is enabled or not.
|
||||
// enabled: true,
|
||||
// // Maximum file size limit (-1 value disables any file size limit check)
|
||||
// maxFileSize: 50,
|
||||
// },
|
||||
};
|
||||
|
||||
// Set the default values for JaaS customers
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
text-align: center;
|
||||
|
||||
h2 {
|
||||
font-size: 48px;
|
||||
font-size: 3rem;
|
||||
color : #f2f2f2;
|
||||
}
|
||||
|
||||
&__message {
|
||||
font-size: 24px;
|
||||
font-size: 1.5rem;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ body {
|
||||
margin: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 400;
|
||||
overflow: hidden;
|
||||
color: #F1F1F1;
|
||||
@@ -111,7 +111,7 @@ form {
|
||||
height: $watermarkHeight;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
z-index: $zindex2;
|
||||
z-index: $watermarkZ;
|
||||
}
|
||||
|
||||
.leftwatermark {
|
||||
@@ -139,10 +139,10 @@ form {
|
||||
position: absolute;
|
||||
left: 25;
|
||||
bottom: 7;
|
||||
font-size: 11pt;
|
||||
font-size: 0.875rem;
|
||||
color: rgba(255,255,255,.50);
|
||||
text-decoration: none;
|
||||
z-index: 100;
|
||||
z-index: $watermarkZ;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
#chatconversation {
|
||||
box-sizing: border-box;
|
||||
flex: 1;
|
||||
font-size: 10pt;
|
||||
font-size: 0.75rem;
|
||||
height: calc(100% - 10px);
|
||||
line-height: 20px;
|
||||
line-height: 1.25rem;
|
||||
overflow: auto;
|
||||
padding: 16px;
|
||||
text-align: left;
|
||||
@@ -72,7 +72,7 @@
|
||||
#nickname {
|
||||
text-align: center;
|
||||
color: #9d9d9d;
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
margin: auto 0;
|
||||
padding: 0 16px;
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
}
|
||||
|
||||
label {
|
||||
line-height: 24px;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
}
|
||||
|
||||
.chatmessage .usermessage {
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
}
|
||||
|
||||
#smileys {
|
||||
font-size: 20pt;
|
||||
font-size: 1.625rem;
|
||||
margin: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -141,34 +141,8 @@
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.smileys-panel {
|
||||
bottom: 100%;
|
||||
box-sizing: border-box;
|
||||
background-color: rgba(0, 0, 0, .6) !important;
|
||||
height: auto;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
width: calc(#{$sidebarWidth} - 32px);
|
||||
margin-bottom: 5px;
|
||||
margin-left: -5px;
|
||||
|
||||
/**
|
||||
* CSS transitions do not apply for auto dimensions. So to produce the css
|
||||
* accordion effect for showing and hiding the smiley-panel, while allowing
|
||||
* for variable panel, height, use a very large max-height and animate off
|
||||
* of that.
|
||||
*/
|
||||
transition: max-height 0.3s;
|
||||
|
||||
#smileysContainer {
|
||||
background-color: $chatBackgroundColor;
|
||||
border-top: 1px solid #A4B8D1;
|
||||
}
|
||||
}
|
||||
|
||||
#smileysContainer .smiley {
|
||||
font-size: 20pt;
|
||||
font-size: 1.625rem;
|
||||
}
|
||||
|
||||
.smileyContainer {
|
||||
@@ -219,8 +193,8 @@
|
||||
box-sizing: border-box;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 24px;
|
||||
line-height: 32px;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
|
||||
.jitsi-icon {
|
||||
cursor: pointer;
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
}
|
||||
|
||||
&__checkbox-label {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.125rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
letter-spacing: -0.006em;
|
||||
@@ -51,8 +51,8 @@
|
||||
}
|
||||
|
||||
&__text-container {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.125rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
letter-spacing: -0.006em;
|
||||
@@ -84,8 +84,8 @@
|
||||
|
||||
&__button-text {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 2.5rem;
|
||||
text-align: center;
|
||||
letter-spacing: -0.006em;
|
||||
color: #FFFFFF;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
margin: 17px 0;
|
||||
padding-bottom: 17px;
|
||||
color: #ffffff;
|
||||
font-size: 21px;
|
||||
font-size: 1.25rem;
|
||||
letter-spacing: 0.3px;
|
||||
border-bottom: 1px solid lighten(#FFFFFF, 10%);
|
||||
}
|
||||
@@ -19,12 +19,12 @@
|
||||
color: #ffffff;
|
||||
display: block;
|
||||
margin-top: 22px;
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
margin: 0 10px;
|
||||
font-size: 50px;
|
||||
font-size: 3.125rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
.meetings-list {
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
color: #253858;
|
||||
line-height: 20px;
|
||||
line-height: 1.25rem;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
flex-grow: 1;
|
||||
|
||||
.meetings-list-empty {
|
||||
text-align: center;
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
.description {
|
||||
color: #2f3237;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.125rem;
|
||||
margin-bottom: 16px;
|
||||
max-width: 436px;
|
||||
}
|
||||
@@ -37,8 +37,8 @@
|
||||
color: #0163FF;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.125rem;
|
||||
margin: 24px 0 32px 0;
|
||||
}
|
||||
|
||||
@@ -101,17 +101,17 @@
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
line-height: 16px;
|
||||
line-height: 1rem;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #5E6D7A;
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
|
||||
|
||||
@@ -174,4 +174,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) { /* Targets iPads and smaller devices */
|
||||
.item {
|
||||
.delete-meeting {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
%navigate-section-list-text {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
color: $welcomePageTitleColor;
|
||||
text-align: left;
|
||||
font-family: 'open_sanslight', Helvetica, sans-serif;
|
||||
@@ -52,7 +52,7 @@
|
||||
.navigate-section-tile-body {
|
||||
@extend %navigate-section-list-tile-text;
|
||||
font-weight: normal;
|
||||
line-height: 24px;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
.navigate-section-list-tile-info {
|
||||
flex: 1;
|
||||
@@ -61,7 +61,7 @@
|
||||
.navigate-section-tile-title {
|
||||
@extend %navigate-section-list-tile-text;
|
||||
font-weight: bold;
|
||||
line-height: 24px;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
.navigate-section-section-header {
|
||||
@extend %navigate-section-list-text;
|
||||
|
||||
@@ -4,9 +4,3 @@
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-browser.shift-right {
|
||||
.participants_pane {
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
&__text {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 21px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@
|
||||
span.emoji {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 22px;
|
||||
font-size: 1.375rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
@for $i from 1 through 12 {
|
||||
&.increase-#{$i}{
|
||||
font-size: calc(20px + #{$i}px);
|
||||
font-size: calc(1.25rem + #{$i}px);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,8 +96,8 @@
|
||||
span.text {
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5rem;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
@@ -132,8 +132,8 @@ $reactionCount: 20;
|
||||
|
||||
.reaction-emoji {
|
||||
position: absolute;
|
||||
font-size: 24px;
|
||||
line-height: 32px;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
top: 0;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
.recording-title {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
margin-left: 16px;
|
||||
max-width: 70%;
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
.local-recording-warning {
|
||||
margin-top: 8px;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
padding: 8px 16px;
|
||||
|
||||
&.text {
|
||||
@@ -126,7 +126,7 @@
|
||||
|
||||
.recording-info-title {
|
||||
display: inline-flex;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
width: 290px
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
/**
|
||||
* Set font-size to be consistent with Atlaskit FieldText.
|
||||
*/
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
|
||||
.broadcast-dropdown {
|
||||
text-align: left;
|
||||
@@ -194,6 +194,6 @@
|
||||
|
||||
.warning-text {
|
||||
color:#FFD740;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
width: 30%;
|
||||
margin: 20% auto;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
font-size: 1.5rem;
|
||||
|
||||
.thanks-msg {
|
||||
border-bottom: 1px solid #FFFFFF;
|
||||
@@ -10,16 +10,16 @@
|
||||
padding-right: 30px;
|
||||
p {
|
||||
margin: 30px auto;
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
}
|
||||
.hint-msg {
|
||||
p {
|
||||
margin: 26px auto;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
line-height: 18px;
|
||||
font-size: 1rem;
|
||||
line-height: 1.125rem;
|
||||
.hint-msg__holder{
|
||||
font-weight: 200;
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
}
|
||||
.forbidden-msg {
|
||||
p {
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ input[type="reset"] {
|
||||
body {
|
||||
color: #333;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.42857142857143;
|
||||
}
|
||||
/* International Font Stacks*/
|
||||
@@ -113,7 +113,7 @@ pre:first-child {
|
||||
/* Headings: desired line height in px / font size = unitless line height */
|
||||
h1 {
|
||||
color: #333;
|
||||
font-size: 32px;
|
||||
font-size: 2rem;
|
||||
font-weight: normal;
|
||||
line-height: 1.25;
|
||||
text-transform: none;
|
||||
@@ -121,7 +121,7 @@ h1 {
|
||||
}
|
||||
h2 {
|
||||
color: #333;
|
||||
font-size: 24px;
|
||||
font-size: 1.5rem;
|
||||
font-weight: normal;
|
||||
line-height: 1.25;
|
||||
text-transform: none;
|
||||
@@ -129,14 +129,14 @@ h2 {
|
||||
}
|
||||
h3 {
|
||||
color: #333;
|
||||
font-size: 20px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: normal;
|
||||
line-height: 1.5;
|
||||
text-transform: none;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.25;
|
||||
text-transform: none;
|
||||
@@ -144,7 +144,7 @@ h4 {
|
||||
}
|
||||
h5 {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.42857143;
|
||||
text-transform: none;
|
||||
@@ -152,7 +152,7 @@ h5 {
|
||||
}
|
||||
h6 {
|
||||
color: #707070;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.66666667;
|
||||
text-transform: uppercase;
|
||||
@@ -179,7 +179,7 @@ h5 + h6 {
|
||||
/* Other typographical elements */
|
||||
small {
|
||||
color: #707070;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.33333333333333;
|
||||
}
|
||||
code,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#enter_room {
|
||||
.welcome-page-button {
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
@@ -53,25 +53,10 @@
|
||||
}
|
||||
|
||||
.welcome-footer-row-block {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.desktop-browser {
|
||||
&.shift-right {
|
||||
|
||||
@media only screen and (max-width: $verySmallScreen + $sidebarWidth) {
|
||||
|
||||
#videoResolutionLabel {
|
||||
display: none;
|
||||
}
|
||||
.vertical-filmstrip .filmstrip {
|
||||
display: none;
|
||||
}
|
||||
.chrome-extension-banner {
|
||||
display: none;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap:12px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
// Do not inherit the font-family from the toolbar button, because it's an
|
||||
// icon style.
|
||||
font-family: $baseFontFamily;
|
||||
font-size: 9px;
|
||||
font-size: 0.5rem;
|
||||
font-weight: 700;
|
||||
line-height: 13px;
|
||||
line-height: 0.75rem;
|
||||
min-width: 13px;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
@@ -69,8 +69,8 @@
|
||||
|
||||
.badge-round {
|
||||
bottom: -5px;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.25rem;
|
||||
min-width: 20px;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
|
||||
@@ -22,7 +22,6 @@ $newToolbarSizeWithPadding: calc(#{$newToolbarSize} + 24px);
|
||||
* Chat
|
||||
*/
|
||||
$chatBackgroundColor: #131519;
|
||||
$sidebarWidth: 315px;
|
||||
|
||||
/**
|
||||
* Misc.
|
||||
@@ -38,6 +37,8 @@ $zindex1: 1;
|
||||
$zindex2: 2;
|
||||
$zindex3: 3;
|
||||
$toolbarZ: 250;
|
||||
$watermarkZ: 253;
|
||||
|
||||
// Place filmstrip videos over toolbar in order
|
||||
// to make connection info visible.
|
||||
$filmstripVideosZ: $toolbarZ + 1;
|
||||
@@ -48,11 +49,11 @@ $filmstripVideosZ: $toolbarZ + 1;
|
||||
$primaryUnsupportedBrowserButtonBgColor: #0052CC;
|
||||
$unsupportedBrowserButtonBgColor: rgba(9, 30, 66, 0.04);
|
||||
$unsupportedBrowserTextColor: #4a4a4a;
|
||||
$unsupportedBrowserTextSmallFontSize: 17px;
|
||||
$unsupportedBrowserTextSmallFontSize: 1rem;
|
||||
$unsupportedBrowserTitleColor: #fff;
|
||||
$unsupportedBrowserTitleFontSize: 24px;
|
||||
$unsupportedBrowserTitleFontSize: 1.5rem;
|
||||
$unsupportedDesktopBrowserTextColor: rgba(255, 255, 255, 0.7);
|
||||
$unsupportedDesktopBrowserTextFontSize: 21px;
|
||||
$unsupportedDesktopBrowserTextFontSize: 1.25rem;
|
||||
|
||||
/**
|
||||
* The size of the default watermark.
|
||||
@@ -75,18 +76,21 @@ $welcomePageHeaderBackground: linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0,
|
||||
$welcomePageHeaderBackgroundPosition: center;
|
||||
$welcomePageHeaderBackgroundRepeat: none;
|
||||
$welcomePageHeaderBackgroundSize: cover;
|
||||
$welcomePageHeaderPaddingBottom: 15px;
|
||||
$welcomePageHeaderPadding: 1rem;
|
||||
$welcomePageHeaderTitleMaxWidth: initial;
|
||||
$welcomePageHeaderTextAlign: center;
|
||||
$welcomePageButtonBg: #0074E0;
|
||||
$welcomePageButtonHoverBg: #4687ED;
|
||||
$welcomePageButtonFocusOutline: #00225A;
|
||||
|
||||
$welcomePageHeaderContainerMarginTop: 104px;
|
||||
$welcomePageHeaderContainerDisplay: flex;
|
||||
$welcomePageHeaderContainerMargin: $welcomePageHeaderContainerMarginTop auto 0;
|
||||
|
||||
$welcomePageHeaderTextTitleMarginBottom: 0;
|
||||
$welcomePageHeaderTextTitleFontSize: 42px;
|
||||
$welcomePageHeaderTextTitleFontSize: 2.625rem;
|
||||
$welcomePageHeaderTextTitleFontWeight: normal;
|
||||
$welcomePageHeaderTextTitleLineHeight: 50px;
|
||||
$welcomePageHeaderTextTitleLineHeight: 3.125rem;
|
||||
$welcomePageHeaderTextTitleOpacity: 1;
|
||||
|
||||
$welcomePageEnterRoomDisplay: flex;
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
}
|
||||
|
||||
#alwaysOnTop .displayname {
|
||||
font-size: 15px;
|
||||
font-size: 0.875rem;
|
||||
position: inherit;
|
||||
width: 100%;
|
||||
left: 0px;
|
||||
@@ -294,7 +294,7 @@
|
||||
width: auto;
|
||||
z-index: $zindex2;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
text-align: center;
|
||||
color: #FFF;
|
||||
left: 50%;
|
||||
@@ -340,7 +340,7 @@
|
||||
|
||||
.presence-label {
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 100;
|
||||
left: 0;
|
||||
margin: 0 auto;
|
||||
|
||||
@@ -18,7 +18,7 @@ body.welcome-page {
|
||||
background-position: $welcomePageHeaderBackgroundPosition;
|
||||
background-repeat: $welcomePageHeaderBackgroundRepeat;
|
||||
background-size: $welcomePageHeaderBackgroundSize;
|
||||
padding-bottom: $welcomePageHeaderPaddingBottom;
|
||||
padding: $welcomePageHeaderPadding;
|
||||
background-color: #131519;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
@@ -53,9 +53,9 @@ body.welcome-page {
|
||||
|
||||
.header-text-subtitle {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
line-height: 26px;
|
||||
line-height: 1.625rem;
|
||||
margin: 16px 0 32px 0;
|
||||
text-align: $welcomePageHeaderTextAlign;
|
||||
|
||||
@@ -64,7 +64,7 @@ body.welcome-page {
|
||||
.not-allow-title-character-div {
|
||||
color: #f03e3e;
|
||||
background-color: #fff;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
margin: 10px 0px 5px 0px;
|
||||
text-align: $welcomePageHeaderTextAlign;
|
||||
@@ -147,7 +147,7 @@ body.welcome-page {
|
||||
display: inline-block;
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
padding-left: 10px;
|
||||
|
||||
&.focus-visible {
|
||||
@@ -172,7 +172,7 @@ body.welcome-page {
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
display: $welcomePageTabContainerDisplay;
|
||||
@@ -191,8 +191,8 @@ body.welcome-page {
|
||||
background-color: #c7ddff;
|
||||
border-radius: 6px;
|
||||
color: #0163FF;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.125rem;
|
||||
margin: 4px;
|
||||
display: $welcomePageTabButtonsDisplay;
|
||||
|
||||
@@ -218,15 +218,19 @@ body.welcome-page {
|
||||
|
||||
.welcome-page-button {
|
||||
border: 0;
|
||||
font-size: 14px;
|
||||
background: #0074E0;
|
||||
font-size: 0.875rem;
|
||||
background: $welcomePageButtonBg;
|
||||
border-radius: 3px;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
padding: 16px 20px;
|
||||
|
||||
transition: all 0.2s;
|
||||
&:focus-within {
|
||||
outline: auto 2px #022e61;
|
||||
outline: auto 2px $welcomePageButtonFocusOutline;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $welcomePageButtonHoverBg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +246,7 @@ body.welcome-page {
|
||||
|
||||
* {
|
||||
cursor: pointer;
|
||||
font-size: 32px;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.toolbox-icon {
|
||||
@@ -264,8 +268,7 @@ body.welcome-page {
|
||||
|
||||
&.without-content {
|
||||
.welcome-card {
|
||||
min-width: 500px;
|
||||
max-width: 580px;
|
||||
max-width: 100dvw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,6 +349,6 @@ body.welcome-page {
|
||||
|
||||
.welcome-footer-row-1-text {
|
||||
max-width: 200px;
|
||||
margin-right: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,15 +91,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shift-right .remote-videos > div {
|
||||
/**
|
||||
* Max-width corresponding to the ASPECT_RATIO_BREAKPOINT from features/filmstrip/constants,
|
||||
* from which we subtract the chat size.
|
||||
*/
|
||||
@media only screen and (max-width: calc(500px + #{$sidebarWidth})) {
|
||||
video {
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
width: 28px;
|
||||
|
||||
i {
|
||||
line-height: 28px;
|
||||
line-height: 1.75rem;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@
|
||||
padding-left: 10px;
|
||||
|
||||
i {
|
||||
line-height: 20px;
|
||||
line-height: 1.25rem;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.info-dialog {
|
||||
cursor: default;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
|
||||
.info-dialog-column {
|
||||
margin-right: 10px;
|
||||
@@ -53,8 +53,8 @@
|
||||
max-width: 334px;
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.5rem;
|
||||
border-collapse: collapse;
|
||||
|
||||
* {
|
||||
@@ -107,7 +107,7 @@
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
max-height: 100%;
|
||||
overflow: auto;
|
||||
padding: 15pt;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.invite-more {
|
||||
&-dialog {
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5rem;
|
||||
|
||||
&.separator {
|
||||
margin: 24px 0 24px -20px;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.share-screen-warn-dialog {
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
|
||||
.separator-line {
|
||||
margin: 24px 0 24px -20px;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
.security {
|
||||
&-dialog {
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5rem;
|
||||
|
||||
&.password-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.description {
|
||||
font-size: 13px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.password {
|
||||
@@ -24,7 +24,7 @@
|
||||
button {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
color: #6FB1EA;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.lobby-screen {
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 26px;
|
||||
line-height: 1.625rem;
|
||||
|
||||
&-content {
|
||||
align-items: center;
|
||||
@@ -43,7 +43,7 @@
|
||||
flex-direction: column;
|
||||
|
||||
.description {
|
||||
font-size: 13px;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.control-row {
|
||||
@@ -53,7 +53,7 @@
|
||||
margin-top: 15px;
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
@@ -191,9 +191,9 @@
|
||||
.title {
|
||||
flex: 1;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
line-height: 28px;
|
||||
line-height: 1.75rem;
|
||||
letter-spacing: -1.2%;
|
||||
}
|
||||
}
|
||||
@@ -214,8 +214,8 @@
|
||||
border-radius: 6px;
|
||||
box-sizing: border-box;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
margin-bottom: 16px;
|
||||
margin-top: -8px;
|
||||
padding: 4px;
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
line-height: 1.5rem;
|
||||
margin-bottom: 16px;
|
||||
padding: 7px 16px;
|
||||
position: relative;
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
&.text {
|
||||
width: auto;
|
||||
font-size: 13px;
|
||||
font-size: 0.75rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@@ -98,7 +98,7 @@
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
margin-bottom: 8px;
|
||||
padding: 11px 16px;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
.reload_overlay_title {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
font-size: 1rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
.reload_overlay_text {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.875rem;
|
||||
}
|
||||
|
||||
#reloadProgressBar {
|
||||
|
||||
@@ -34,12 +34,12 @@
|
||||
|
||||
&__status{
|
||||
margin-top: 15px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-size: 24px;
|
||||
line-height: 32px;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
font-family: Roboto, arial, sans-serif;
|
||||
font-size: 14px;
|
||||
font-size: 0.875rem;
|
||||
padding: 1px;
|
||||
|
||||
.google-cta {
|
||||
@@ -17,7 +17,7 @@
|
||||
/**
|
||||
* Hack the line height for vertical centering of text.
|
||||
*/
|
||||
line-height: 32px;
|
||||
line-height: 2rem;
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
.microsoft-cta {
|
||||
display: inline-block;
|
||||
color: #5E5E5E;
|
||||
font-size: 15px;
|
||||
line-height: 41px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
|
||||
.microsoft-logo {
|
||||
|
||||
5
custom.d.ts
vendored
5
custom.d.ts
vendored
@@ -2,3 +2,8 @@ declare module '*.svg' {
|
||||
const content: any;
|
||||
export default content;
|
||||
}
|
||||
|
||||
declare module '*.svg?raw' {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
||||
4
debian/control
vendored
4
debian/control
vendored
@@ -34,7 +34,7 @@ Description: Configuration for web serving of Jitsi Meet
|
||||
|
||||
Package: jitsi-meet-prosody
|
||||
Architecture: all
|
||||
Depends: openssl, prosody (>= 0.11.7) | prosody-trunk | prosody-0.12 | prosody-0.11, lua-sec, lua-basexx, lua-luaossl, lua-cjson, lua-inspect
|
||||
Depends: openssl, prosody (>= 0.12.0) | prosody-trunk | prosody-0.12 | prosody-13.0, lua-sec, lua-basexx, lua-luaossl, lua-cjson, lua-inspect
|
||||
Replaces: jitsi-meet-tokens
|
||||
Description: Prosody configuration for Jitsi Meet
|
||||
Jitsi Meet is a WebRTC JavaScript application that uses Jitsi
|
||||
@@ -48,7 +48,7 @@ Description: Prosody configuration for Jitsi Meet
|
||||
|
||||
Package: jitsi-meet-tokens
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, prosody-trunk | prosody-0.11 | prosody-0.12 | prosody (>= 0.11.7), jitsi-meet-prosody
|
||||
Depends: ${misc:Depends}, prosody-trunk | prosody-0.12 | prosody-13.0 | prosody (>= 0.12.0), jitsi-meet-prosody
|
||||
Description: Prosody token authentication plugin for Jitsi Meet
|
||||
|
||||
Package: jitsi-meet-turnserver
|
||||
|
||||
59
debian/jitsi-meet-prosody.postinst
vendored
59
debian/jitsi-meet-prosody.postinst
vendored
@@ -124,23 +124,20 @@ case "$1" in
|
||||
ln -s $PROSODY_HOST_CONFIG /etc/prosody/conf.d/$JVB_HOSTNAME.cfg.lua
|
||||
fi
|
||||
PROSODY_CREATE_JICOFO_USER="true"
|
||||
fi
|
||||
|
||||
if ! grep -q "VirtualHost \"$JVB_HOSTNAME\"" $PROSODY_CONFIG_OLD; then
|
||||
# on some distributions main prosody config doesn't include configs
|
||||
# from conf.d folder enable it as this where we put our config by default
|
||||
# also when upgrading to new prosody version from prosody repo we need to add it again
|
||||
if ! grep -q "Include \"conf\.d\/\*\.cfg.lua\"" $PROSODY_CONFIG_OLD; then
|
||||
echo -e "\nInclude \"conf.d/*.cfg.lua\"" >> $PROSODY_CONFIG_OLD
|
||||
|
||||
# trigger a restart
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$PROSODY_CREATE_JICOFO_USER" = "true" ]; then
|
||||
# create 'focus@auth.domain' prosody user
|
||||
prosodyctl register $JICOFO_AUTH_USER $JICOFO_AUTH_DOMAIN $JICOFO_AUTH_PASSWORD
|
||||
# trigger a restart
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
|
||||
# creates the user if it does not exist
|
||||
echo -e "$JVB_SECRET\n$JVB_SECRET" | prosodyctl adduser jvb@$JICOFO_AUTH_DOMAIN > /dev/null || true
|
||||
|
||||
# Check whether prosody config has the internal muc, if not add it,
|
||||
# as we are migrating configs
|
||||
if [ -f $PROSODY_HOST_CONFIG ] && ! grep -q "internal.$JICOFO_AUTH_DOMAIN" $PROSODY_HOST_CONFIG; then
|
||||
@@ -164,6 +161,16 @@ case "$1" in
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
|
||||
# Start using the polls component
|
||||
if ! grep -q "Component \"polls.$JVB_HOSTNAME\"" $PROSODY_HOST_CONFIG ;then
|
||||
echo -e "\nComponent \"polls.$JVB_HOSTNAME\" \"polls_component\"" >> $PROSODY_HOST_CONFIG
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
if ! grep -q -- '--"polls";' $PROSODY_HOST_CONFIG ;then
|
||||
sed -i "s/\"polls\";/--\"polls\";/g" $PROSODY_HOST_CONFIG
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
|
||||
# Old versions of jitsi-meet-prosody come with the extra plugin path commented out (https://github.com/jitsi/jitsi-meet/commit/e11d4d3101e5228bf956a69a9e8da73d0aee7949)
|
||||
# Make sure it is uncommented, as it contains required modules.
|
||||
if grep -q -- '--plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }' $PROSODY_HOST_CONFIG ;then
|
||||
@@ -184,6 +191,12 @@ case "$1" in
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
|
||||
# Since prosody 13 admins are not automatically room owners and we expect that for jicofo
|
||||
if ! grep -q -- 'component_admins_as_room_owners = ' $PROSODY_HOST_CONFIG ;then
|
||||
sed -i "1s/^/component_admins_as_room_owners = true\n/" $PROSODY_HOST_CONFIG
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
|
||||
JAAS_HOST_CONFIG="/etc/prosody/conf.avail/jaas.cfg.lua"
|
||||
if [ "${JAAS_INPUT}" = "true" ] && [ ! -f $JAAS_HOST_CONFIG ]; then
|
||||
sed -i "s/enabled = false -- Jitsi meet components/enabled = true -- Jitsi meet components/g" $PROSODY_HOST_CONFIG
|
||||
@@ -207,9 +220,6 @@ case "$1" in
|
||||
fi
|
||||
fi
|
||||
|
||||
# Make sure the focus@auth user's roster includes the proxy component (this is idempotent)
|
||||
prosodyctl mod_roster_command subscribe focus.$JVB_HOSTNAME $JICOFO_AUTH_USER@$JICOFO_AUTH_DOMAIN
|
||||
|
||||
if [ ! -f /var/lib/prosody/$JVB_HOSTNAME.crt ]; then
|
||||
# prosodyctl takes care for the permissions
|
||||
# echo for using all default values
|
||||
@@ -252,6 +262,29 @@ case "$1" in
|
||||
if [ "$PROSODY_CONFIG_PRESENT" = "false" ]; then
|
||||
invoke-rc.d prosody restart || true
|
||||
|
||||
# give it some time to warm up
|
||||
sleep 10
|
||||
|
||||
if [ "$PROSODY_CREATE_JICOFO_USER" = "true" ]; then
|
||||
# create 'focus@auth.domain' prosody user
|
||||
echo -e "$JICOFO_AUTH_PASSWORD\n$JICOFO_AUTH_PASSWORD" | prosodyctl adduser $JICOFO_AUTH_USER@$JICOFO_AUTH_DOMAIN > /dev/null || true
|
||||
|
||||
# trigger a restart
|
||||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
|
||||
# creates the user if it does not exist
|
||||
echo -e "$JVB_SECRET\n$JVB_SECRET" | prosodyctl adduser jvb@$JICOFO_AUTH_DOMAIN > /dev/null || true
|
||||
|
||||
# Make sure the focus@auth user's roster includes the proxy component (this is idempotent)
|
||||
prosodyctl mod_roster_command subscribe focus.$JVB_HOSTNAME $JICOFO_AUTH_USER@$JICOFO_AUTH_DOMAIN
|
||||
|
||||
# To make sure the roster command is loaded
|
||||
# Once we have https://issues.prosody.im/1908 we can start using prosodyctl shell roster subscribe
|
||||
# and drop the wait and the prosody restart
|
||||
sleep 1
|
||||
invoke-rc.d prosody restart || true
|
||||
|
||||
# In case we had updated the certificates and restarted prosody, let's restart and the bridge and jicofo if possible
|
||||
if [ -d /run/systemd/system ] && [ "$CERT_ADDED_TO_TRUST" = "true" ]; then
|
||||
systemctl restart jitsi-videobridge2.service >/dev/null || true
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
-- We need this for prosody 13.0
|
||||
component_admins_as_room_owners = true
|
||||
|
||||
plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }
|
||||
|
||||
-- domain mapper options, must at least have domain base set to use the mapper
|
||||
@@ -12,6 +15,7 @@ external_services = {
|
||||
|
||||
cross_domain_bosh = false;
|
||||
consider_bosh_secure = true;
|
||||
consider_websocket_secure = true;
|
||||
-- https_ports = { }; -- Remove this line to prevent listening on port 5284
|
||||
|
||||
-- by default prosody 0.12 sends cors headers, if you want to disable it uncomment the following (the config is available on 0.12.1)
|
||||
@@ -35,6 +39,11 @@ unlimited_jids = {
|
||||
"jvb@auth.jitmeet.example.com"
|
||||
}
|
||||
|
||||
-- https://prosody.im/doc/modules/mod_smacks
|
||||
smacks_max_unacked_stanzas = 5;
|
||||
smacks_hibernation_time = 60;
|
||||
smacks_max_old_sessions = 1;
|
||||
|
||||
VirtualHost "jitmeet.example.com"
|
||||
authentication = "jitsi-anonymous" -- do not delete me
|
||||
-- Properties below are modified by jitsi-meet-tokens package config
|
||||
@@ -49,26 +58,21 @@ VirtualHost "jitmeet.example.com"
|
||||
key = "/etc/prosody/certs/jitmeet.example.com.key";
|
||||
certificate = "/etc/prosody/certs/jitmeet.example.com.crt";
|
||||
}
|
||||
av_moderation_component = "avmoderation.jitmeet.example.com"
|
||||
speakerstats_component = "speakerstats.jitmeet.example.com"
|
||||
end_conference_component = "endconference.jitmeet.example.com"
|
||||
-- we need bosh
|
||||
modules_enabled = {
|
||||
"bosh";
|
||||
"websocket";
|
||||
"smacks";
|
||||
"ping"; -- Enable mod_ping
|
||||
"speakerstats";
|
||||
"external_services";
|
||||
"features_identity";
|
||||
"conference_duration";
|
||||
"end_conference";
|
||||
"muc_lobby_rooms";
|
||||
"muc_breakout_rooms";
|
||||
"av_moderation";
|
||||
"room_metadata";
|
||||
}
|
||||
c2s_require_encryption = false
|
||||
lobby_muc = "lobby.jitmeet.example.com"
|
||||
breakout_rooms_muc = "breakout.jitmeet.example.com"
|
||||
room_metadata_component = "metadata.jitmeet.example.com"
|
||||
main_muc = "conference.jitmeet.example.com"
|
||||
-- muc_lobby_whitelist = { "recorder.jitmeet.example.com" } -- Here we can whitelist jibri to enter lobby enabled rooms
|
||||
|
||||
@@ -79,7 +83,6 @@ Component "conference.jitmeet.example.com" "muc"
|
||||
"muc_hide_all";
|
||||
"muc_meeting_id";
|
||||
"muc_domain_mapper";
|
||||
"polls";
|
||||
--"token_verification";
|
||||
"muc_rate_limit";
|
||||
"muc_password_whitelist";
|
||||
@@ -124,6 +127,13 @@ VirtualHost "auth.jitmeet.example.com"
|
||||
authentication = "internal_hashed"
|
||||
smacks_hibernation_time = 15;
|
||||
|
||||
VirtualHost "recorder.jitmeet.example.com"
|
||||
modules_enabled = {
|
||||
"smacks";
|
||||
}
|
||||
authentication = "internal_hashed"
|
||||
smacks_max_old_sessions = 2000;
|
||||
|
||||
-- Proxy to jicofo's user JID, so that it doesn't have to register as a component.
|
||||
Component "focus.jitmeet.example.com" "client_proxy"
|
||||
target_address = "focusUser@auth.jitmeet.example.com"
|
||||
@@ -137,6 +147,9 @@ Component "endconference.jitmeet.example.com" "end_conference"
|
||||
Component "avmoderation.jitmeet.example.com" "av_moderation_component"
|
||||
muc_component = "conference.jitmeet.example.com"
|
||||
|
||||
Component "filesharing.jitmeet.example.com" "filesharing_component"
|
||||
muc_component = "conference.jitmeet.example.com"
|
||||
|
||||
Component "lobby.jitmeet.example.com" "muc"
|
||||
storage = "memory"
|
||||
restrict_room_creation = true
|
||||
@@ -145,9 +158,10 @@ Component "lobby.jitmeet.example.com" "muc"
|
||||
modules_enabled = {
|
||||
"muc_hide_all";
|
||||
"muc_rate_limit";
|
||||
"polls";
|
||||
}
|
||||
|
||||
Component "metadata.jitmeet.example.com" "room_metadata_component"
|
||||
muc_component = "conference.jitmeet.example.com"
|
||||
breakout_rooms_component = "breakout.jitmeet.example.com"
|
||||
|
||||
Component "polls.jitmeet.example.com" "polls_component"
|
||||
|
||||
@@ -10,6 +10,7 @@ no-cli
|
||||
no-loopback-peers
|
||||
no-tcp-relay
|
||||
no-tcp
|
||||
no-dtls
|
||||
listening-port=3478
|
||||
tls-listening-port=5349
|
||||
no-tlsv1
|
||||
|
||||
@@ -150,6 +150,12 @@ server {
|
||||
# alias /usr/share/jitsi-meet/load-test/libs/$1;
|
||||
#}
|
||||
|
||||
location = /_unlock {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains';
|
||||
add_header "Cache-Control" "no-cache, no-store";
|
||||
}
|
||||
|
||||
location ~ ^/conference-request/v1(\/.*)?$ {
|
||||
proxy_pass http://127.0.0.1:8888/conference-request/v1$1;
|
||||
add_header "Cache-Control" "no-cache, no-store";
|
||||
|
||||
16
giphy-analytics-stub.js
Normal file
16
giphy-analytics-stub.js
Normal file
@@ -0,0 +1,16 @@
|
||||
// Stub replacement for @giphy/js-analytics to prevent beforeunload handlers
|
||||
// This completely disables all Giphy analytics functionality
|
||||
|
||||
export const pingback = () => {
|
||||
// Completely disabled - do nothing
|
||||
|
||||
};
|
||||
|
||||
export const mergeAttributes = (attributes, newAttributes) => {
|
||||
// Return merged attributes without any analytics calls
|
||||
return { ...attributes,
|
||||
...newAttributes };
|
||||
};
|
||||
|
||||
// Ensure no beforeunload handlers are ever registered
|
||||
export default pingback;
|
||||
@@ -36,7 +36,7 @@
|
||||
Component: JitsiMeetJS.app.entryPoints.APP
|
||||
})
|
||||
|
||||
const inIframe = () => {
|
||||
const isEmbedded = () => {
|
||||
try {
|
||||
return window.self !== window.top;
|
||||
} catch (e) {
|
||||
@@ -45,7 +45,7 @@
|
||||
};
|
||||
|
||||
const isElectron = navigator.userAgent.includes('Electron');
|
||||
const shouldRegisterWorker = !isElectron && !inIframe() && 'serviceWorker' in navigator;
|
||||
const shouldRegisterWorker = !isElectron && !isEmbedded() && 'serviceWorker' in navigator;
|
||||
|
||||
if (shouldRegisterWorker) {
|
||||
navigator.serviceWorker
|
||||
|
||||
@@ -192,17 +192,6 @@ var interfaceConfig = {
|
||||
|
||||
// NATIVE_APP_NAME: 'Jitsi Meet',
|
||||
|
||||
/**
|
||||
* Specify Firebase dynamic link properties for the mobile apps.
|
||||
*/
|
||||
// MOBILE_DYNAMIC_LINK: {
|
||||
// APN: 'org.jitsi.meet',
|
||||
// APP_CODE: 'w2atb',
|
||||
// CUSTOM_DOMAIN: undefined,
|
||||
// IBI: 'com.atlassian.JitsiMeet.ios',
|
||||
// ISI: '1165103905'
|
||||
// },
|
||||
|
||||
/**
|
||||
* Hide the logo on the deep linking pages.
|
||||
*/
|
||||
|
||||
12
ios/Podfile
12
ios/Podfile
@@ -19,7 +19,6 @@ target 'JitsiMeet' do
|
||||
|
||||
pod 'Firebase/Analytics', '~> 8.0'
|
||||
pod 'Firebase/Crashlytics', '~> 8.0'
|
||||
pod 'Firebase/DynamicLinks', '~> 8.0'
|
||||
end
|
||||
|
||||
target 'JitsiMeetSDK' do
|
||||
@@ -34,6 +33,7 @@ target 'JitsiMeetSDK' do
|
||||
:path => config[:reactNativePath],
|
||||
:hermes_enabled => true,
|
||||
:fabric_enabled => false,
|
||||
:new_arch_enabled => false,
|
||||
# An absolute path to your application root.
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
@@ -44,7 +44,6 @@ target 'JitsiMeetSDK' do
|
||||
pod 'giphy-react-native-sdk', :path => '../node_modules/@giphy/react-native-sdk'
|
||||
pod 'RNCalendarEvents', :path => '../node_modules/react-native-calendar-events'
|
||||
pod 'RNGoogleSignin', :path => '../node_modules/@react-native-google-signin/google-signin'
|
||||
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
|
||||
|
||||
# Native pod dependencies
|
||||
#
|
||||
@@ -67,6 +66,7 @@ target 'JitsiMeetSDKLite' do
|
||||
:path => config[:reactNativePath],
|
||||
:hermes_enabled => true,
|
||||
:fabric_enabled => false,
|
||||
:new_arch_enabled => false,
|
||||
# An absolute path to your application root.
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
@@ -78,10 +78,12 @@ target 'JitsiMeetSDKLite' do
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
|
||||
react_native_post_install(
|
||||
installer,
|
||||
use_native_modules![:reactNativePath],
|
||||
:mac_catalyst_enabled => false
|
||||
:mac_catalyst_enabled => false,
|
||||
# :ccache_enabled => true
|
||||
)
|
||||
installer.pods_project.targets.each do |target|
|
||||
# https://github.com/CocoaPods/CocoaPods/issues/11402
|
||||
@@ -97,4 +99,8 @@ post_install do |installer|
|
||||
config.build_settings['OTHER_SWIFT_FLAGS'] = '$(inherited) -no-verify-emitted-module-interface'
|
||||
end
|
||||
end
|
||||
|
||||
# Patch SocketRocket to support TLS 1.3
|
||||
%x(patch Pods/SocketRocket/SocketRocket/SRSecurityPolicy.m -N < patches/ws-tls13.diff)
|
||||
|
||||
end
|
||||
|
||||
1347
ios/Podfile.lock
1347
ios/Podfile.lock
File diff suppressed because it is too large
Load Diff
@@ -30,6 +30,14 @@
|
||||
<string>35F9.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>85F4.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
|
||||
@@ -7,22 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0B412F1F1EDEE6E800B1A0A6 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B412F1E1EDEE6E800B1A0A6 /* ViewController.m */; };
|
||||
0B412F211EDEE95300B1A0A6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0B412F201EDEE95300B1A0A6 /* Main.storyboard */; };
|
||||
0B5418471F7C5D8C00A2DD86 /* MeetingRowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B5418461F7C5D8C00A2DD86 /* MeetingRowController.swift */; };
|
||||
0B7001701F7C51CC005944F4 /* InCallController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B70016F1F7C51CC005944F4 /* InCallController.swift */; };
|
||||
0BEA5C291F7B8F73000D0AB4 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0BEA5C271F7B8F73000D0AB4 /* Interface.storyboard */; };
|
||||
0BEA5C2B1F7B8F73000D0AB4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0BEA5C2A1F7B8F73000D0AB4 /* Assets.xcassets */; };
|
||||
0BEA5C321F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0BEA5C311F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
0BEA5C371F7B8F73000D0AB4 /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BEA5C361F7B8F73000D0AB4 /* InterfaceController.swift */; };
|
||||
0BEA5C391F7B8F73000D0AB4 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BEA5C381F7B8F73000D0AB4 /* ExtensionDelegate.swift */; };
|
||||
0BEA5C3B1F7B8F73000D0AB4 /* ComplicationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BEA5C3A1F7B8F73000D0AB4 /* ComplicationController.swift */; };
|
||||
0BEA5C3D1F7B8F73000D0AB4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */; };
|
||||
0BEA5C411F7B8F73000D0AB4 /* JitsiMeetCompanion.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.storyboard */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
2681BB562C7A0B42CFBA6719 /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D6152FF9E9F7B0E86F70A21D /* libPods-JitsiMeet.a */; };
|
||||
361974E2A13624D7735D619D /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 5C1BE20ECD5DEEB48FED90B5 /* PrivacyInfo.xcprivacy */; };
|
||||
4341A9062CF0D63200940D93 /* hermes.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4341A9052CF0D63200940D93 /* hermes.xcframework */; };
|
||||
@@ -34,32 +20,17 @@
|
||||
4EB0603C260E09D000F524C5 /* SocketConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB06039260E09D000F524C5 /* SocketConnection.swift */; };
|
||||
4EB0603D260E09D000F524C5 /* DarwinNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0603A260E09D000F524C5 /* DarwinNotificationCenter.swift */; };
|
||||
4EB0603E260E09D000F524C5 /* SampleUploader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0603B260E09D000F524C5 /* SampleUploader.swift */; };
|
||||
DE4C456121DE1E4E00EA0709 /* FIRUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */; };
|
||||
DEA0B7122D7EF16E0062A9F6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEA0B7112D7EF16E0062A9F6 /* ViewController.swift */; };
|
||||
DEA0B7142D7EF7590062A9F6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEA0B7132D7EF7590062A9F6 /* AppDelegate.swift */; };
|
||||
DEA9F289258A6EA800D4CD74 /* JitsiMeetSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEA9F288258A6EA800D4CD74 /* JitsiMeetSDK.framework */; };
|
||||
DEA9F28A258A6EA800D4CD74 /* JitsiMeetSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DEA9F288258A6EA800D4CD74 /* JitsiMeetSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
DED016F128ECBC9D009D5E8D /* WebRTC.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DED016F028ECBC9D009D5E8D /* WebRTC.xcframework */; };
|
||||
DED016F228ECBC9D009D5E8D /* WebRTC.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DED016F028ECBC9D009D5E8D /* WebRTC.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
E588011722789D43008B0561 /* JitsiMeetContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = E58801132278944E008B0561 /* JitsiMeetContext.swift */; };
|
||||
E5C97B63227A1EB400199214 /* JitsiMeetCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5C97B62227A1EB400199214 /* JitsiMeetCommands.swift */; };
|
||||
FD572B9827EDF32300A800FB /* GiphyUISDK.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = FD572B9727EDF32300A800FB /* GiphyUISDK.xcframework */; };
|
||||
FD572B9927EDF32300A800FB /* GiphyUISDK.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FD572B9727EDF32300A800FB /* GiphyUISDK.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
0BEA5C331F7B8F73000D0AB4 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 0BEA5C301F7B8F73000D0AB4;
|
||||
remoteInfo = "JitsiMeetCompanion Extension";
|
||||
};
|
||||
0BEA5C3F1F7B8F73000D0AB4 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 0BEA5C241F7B8F73000D0AB4;
|
||||
remoteInfo = JitsiMeetCompanion;
|
||||
};
|
||||
4EB06029260E026600F524C5 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
@@ -84,24 +55,12 @@
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0BEA5C471F7B8F73000D0AB4 /* Embed App Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
0BEA5C321F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0BEA5C491F7B8F73000D0AB4 /* Embed Watch Content */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
0BEA5C411F7B8F73000D0AB4 /* JitsiMeetCompanion.app in Embed Watch Content */,
|
||||
);
|
||||
name = "Embed Watch Content";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -121,30 +80,11 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0B26BE6D1EC5BC3C00EEFB41 /* JitsiMeet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = JitsiMeet.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0B412F1D1EDEE6E800B1A0A6 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
|
||||
0B412F1E1EDEE6E800B1A0A6 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
|
||||
0B412F201EDEE95300B1A0A6 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
0B5418461F7C5D8C00A2DD86 /* MeetingRowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingRowController.swift; sourceTree = "<group>"; };
|
||||
0B70016F1F7C51CC005944F4 /* InCallController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InCallController.swift; sourceTree = "<group>"; };
|
||||
0BBD021F212EB69D00CCB19F /* Types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Types.h; sourceTree = "<group>"; };
|
||||
0BD6B4361EF82A6B00D1F4CD /* WebRTC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebRTC.framework; path = "../../node_modules/react-native-webrtc/ios/WebRTC.framework"; sourceTree = "<group>"; };
|
||||
0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JitsiMeetCompanion.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0BEA5C281F7B8F73000D0AB4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = "<group>"; };
|
||||
0BEA5C2A1F7B8F73000D0AB4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
0BEA5C2C1F7B8F73000D0AB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
0BEA5C311F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "JitsiMeetCompanion Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0BEA5C361F7B8F73000D0AB4 /* InterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceController.swift; sourceTree = "<group>"; };
|
||||
0BEA5C381F7B8F73000D0AB4 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = "<group>"; };
|
||||
0BEA5C3A1F7B8F73000D0AB4 /* ComplicationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComplicationController.swift; sourceTree = "<group>"; };
|
||||
0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
0BEA5C3E1F7B8F73000D0AB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* jitsi-meet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "jitsi-meet.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = src/Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
3E0F4ED943C0B12BE77F6B45 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
|
||||
4341A9052CF0D63200940D93 /* hermes.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = hermes.xcframework; path = "../Pods/hermes-engine/destroot/Library/Frameworks/universal/hermes.xcframework"; sourceTree = "<group>"; };
|
||||
4E90F93F2632D1AB001102D4 /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = "<group>"; };
|
||||
@@ -157,29 +97,19 @@
|
||||
4EB0603B260E09D000F524C5 /* SampleUploader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SampleUploader.swift; sourceTree = "<group>"; };
|
||||
4EC49B8625BED71300E76218 /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; };
|
||||
5C1BE20ECD5DEEB48FED90B5 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = ../PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
756FCE06C08D9B947653C98A /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
B3B083EB1D4955FF0069CEE7 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = app.entitlements; sourceTree = "<group>"; };
|
||||
D6152FF9E9F7B0E86F70A21D /* libPods-JitsiMeet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JitsiMeet.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DE050388256E904600DEE3A5 /* WebRTC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = WebRTC.xcframework; path = "../../node_modules/react-native-webrtc/apple/WebRTC.xcframework"; sourceTree = "<group>"; };
|
||||
DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRUtilities.m; sourceTree = "<group>"; };
|
||||
DE4C456021DE1E4E00EA0709 /* FIRUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIRUtilities.h; sourceTree = "<group>"; };
|
||||
DEA0B7112D7EF16E0062A9F6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
DEA0B7132D7EF7590062A9F6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
DEA9F288258A6EA800D4CD74 /* JitsiMeetSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = JitsiMeetSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DED016F028ECBC9D009D5E8D /* WebRTC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = WebRTC.xcframework; path = ../Pods/JitsiWebRTC/WebRTC.xcframework; sourceTree = "<group>"; };
|
||||
DEFDBBDB25656E3B00344B23 /* WebRTC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = WebRTC.xcframework; path = "../../node_modules/react-native-webrtc/ios/WebRTC.xcframework"; sourceTree = "<group>"; };
|
||||
E58801132278944E008B0561 /* JitsiMeetContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JitsiMeetContext.swift; sourceTree = "<group>"; };
|
||||
E5C97B62227A1EB400199214 /* JitsiMeetCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JitsiMeetCommands.swift; sourceTree = "<group>"; };
|
||||
FD572B9727EDF32300A800FB /* GiphyUISDK.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:925PGC4MV7:Giphy, Inc."; lastKnownFileType = wrapper.xcframework; name = GiphyUISDK.xcframework; path = ../Pods/Giphy/GiphySDK/GiphyUISDK.xcframework; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
0BEA5C2E1F7B8F73000D0AB4 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -192,13 +122,6 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1F021A8A5B056078665DE530 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
4EB06020260E026600F524C5 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -227,49 +150,13 @@
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0BEA5C261F7B8F73000D0AB4 /* Watch app */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0BEA5C271F7B8F73000D0AB4 /* Interface.storyboard */,
|
||||
0BEA5C2A1F7B8F73000D0AB4 /* Assets.xcassets */,
|
||||
0BEA5C2C1F7B8F73000D0AB4 /* Info.plist */,
|
||||
);
|
||||
name = "Watch app";
|
||||
path = watchos/app;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0BEA5C351F7B8F73000D0AB4 /* WatchKit extension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0BEA5C361F7B8F73000D0AB4 /* InterfaceController.swift */,
|
||||
0BEA5C381F7B8F73000D0AB4 /* ExtensionDelegate.swift */,
|
||||
0BEA5C3A1F7B8F73000D0AB4 /* ComplicationController.swift */,
|
||||
0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */,
|
||||
0BEA5C3E1F7B8F73000D0AB4 /* Info.plist */,
|
||||
0B70016F1F7C51CC005944F4 /* InCallController.swift */,
|
||||
0B5418461F7C5D8C00A2DD86 /* MeetingRowController.swift */,
|
||||
E58801132278944E008B0561 /* JitsiMeetContext.swift */,
|
||||
E5C97B62227A1EB400199214 /* JitsiMeetCommands.swift */,
|
||||
);
|
||||
name = "WatchKit extension";
|
||||
path = watchos/extension;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13B07FAE1A68108700A75B9A /* src */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
DE4C456021DE1E4E00EA0709 /* FIRUtilities.h */,
|
||||
DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */,
|
||||
DEA0B7132D7EF7590062A9F6 /* AppDelegate.swift */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
0B412F201EDEE95300B1A0A6 /* Main.storyboard */,
|
||||
0BBD021F212EB69D00CCB19F /* Types.h */,
|
||||
0B412F1D1EDEE6E800B1A0A6 /* ViewController.h */,
|
||||
0B412F1E1EDEE6E800B1A0A6 /* ViewController.m */,
|
||||
DEA0B7112D7EF16E0062A9F6 /* ViewController.swift */,
|
||||
);
|
||||
path = src;
|
||||
sourceTree = "<group>";
|
||||
@@ -298,12 +185,10 @@
|
||||
0B26BE711EC5BC4D00EEFB41 /* Frameworks */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
13B07FAE1A68108700A75B9A /* src */,
|
||||
0BEA5C261F7B8F73000D0AB4 /* Watch app */,
|
||||
0BEA5C351F7B8F73000D0AB4 /* WatchKit extension */,
|
||||
4EB06025260E026600F524C5 /* JitsiMeetBroadcast Extension */,
|
||||
CDD71F5E1157E9F283DF92A8 /* Pods */,
|
||||
6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */,
|
||||
5C1BE20ECD5DEEB48FED90B5 /* PrivacyInfo.xcprivacy */,
|
||||
DEAC44E22E97D2C200AD7BEE /* Recovered References */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
@@ -313,8 +198,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* jitsi-meet.app */,
|
||||
0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */,
|
||||
0BEA5C311F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex */,
|
||||
4EB06023260E026600F524C5 /* JitsiMeetBroadcastExtension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
@@ -330,44 +213,17 @@
|
||||
path = ../Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DEAC44E22E97D2C200AD7BEE /* Recovered References */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.storyboard */,
|
||||
);
|
||||
name = "Recovered References";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
0BEA5C241F7B8F73000D0AB4 /* JitsiMeetCompanion */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0BEA5C481F7B8F73000D0AB4 /* Build configuration list for PBXNativeTarget "JitsiMeetCompanion" */;
|
||||
buildPhases = (
|
||||
0BEA5C231F7B8F73000D0AB4 /* Resources */,
|
||||
0BEA5C471F7B8F73000D0AB4 /* Embed App Extensions */,
|
||||
1F021A8A5B056078665DE530 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
0BEA5C341F7B8F73000D0AB4 /* PBXTargetDependency */,
|
||||
);
|
||||
name = JitsiMeetCompanion;
|
||||
productName = JitsiMeetCompanion;
|
||||
productReference = 0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */;
|
||||
productType = "com.apple.product-type.application.watchapp2";
|
||||
};
|
||||
0BEA5C301F7B8F73000D0AB4 /* JitsiMeetCompanion Extension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0BEA5C461F7B8F73000D0AB4 /* Build configuration list for PBXNativeTarget "JitsiMeetCompanion Extension" */;
|
||||
buildPhases = (
|
||||
0BEA5C2D1F7B8F73000D0AB4 /* Sources */,
|
||||
0BEA5C2E1F7B8F73000D0AB4 /* Frameworks */,
|
||||
0BEA5C2F1F7B8F73000D0AB4 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "JitsiMeetCompanion Extension";
|
||||
productName = "JitsiMeetCompanion Extension";
|
||||
productReference = 0BEA5C311F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex */;
|
||||
productType = "com.apple.product-type.watchkit2-extension";
|
||||
};
|
||||
13B07F861A680F5B00A75B9A /* JitsiMeet */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "JitsiMeet" */;
|
||||
@@ -389,7 +245,6 @@
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
0BEA5C401F7B8F73000D0AB4 /* PBXTargetDependency */,
|
||||
4EB0602A260E026600F524C5 /* PBXTargetDependency */,
|
||||
);
|
||||
name = JitsiMeet;
|
||||
@@ -424,17 +279,8 @@
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = Jitsi;
|
||||
TargetAttributes = {
|
||||
0BEA5C241F7B8F73000D0AB4 = {
|
||||
CreatedOnToolsVersion = 9.0;
|
||||
DevelopmentTeam = FC967L3QRG;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
0BEA5C301F7B8F73000D0AB4 = {
|
||||
CreatedOnToolsVersion = 9.0;
|
||||
DevelopmentTeam = FC967L3QRG;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
13B07F861A680F5B00A75B9A = {
|
||||
LastSwiftMigration = 1620;
|
||||
SystemCapabilities = {
|
||||
com.apple.SafariKeychain = {
|
||||
enabled = 1;
|
||||
@@ -463,38 +309,18 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* JitsiMeet */,
|
||||
0BEA5C241F7B8F73000D0AB4 /* JitsiMeetCompanion */,
|
||||
0BEA5C301F7B8F73000D0AB4 /* JitsiMeetCompanion Extension */,
|
||||
4EB06022260E026600F524C5 /* JitsiMeetBroadcastExtension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
0BEA5C231F7B8F73000D0AB4 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0BEA5C2B1F7B8F73000D0AB4 /* Assets.xcassets in Resources */,
|
||||
0BEA5C291F7B8F73000D0AB4 /* Interface.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0BEA5C2F1F7B8F73000D0AB4 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0BEA5C3D1F7B8F73000D0AB4 /* Assets.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0B412F211EDEE95300B1A0A6 /* Main.storyboard in Resources */,
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.storyboard in Resources */,
|
||||
361974E2A13624D7735D619D /* PrivacyInfo.xcprivacy in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -558,7 +384,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "if test \"$PRODUCT_BUNDLE_IDENTIFIER\" = \"com.atlassian.JitsiMeet.ios\"; then\n ENTITLEMENTS_PLIST=\"$PROJECT_DIR/app.entitlements\"\n \n /usr/libexec/PlistBuddy -c \"Add :com.apple.developer.avfoundation.multitasking-camera-access bool 1\" $ENTITLEMENTS_PLIST\nfi\n";
|
||||
shellScript = "#if test \"$PRODUCT_BUNDLE_IDENTIFIER\" = \"com.atlassian.JitsiMeet.ios\"; then\n# ENTITLEMENTS_PLIST=\"$PROJECT_DIR/app.entitlements\"\n# \n# /usr/libexec/PlistBuddy -c \"Add :com.apple.developer.avfoundation.multitasking-camera-access bool 1\" $ENTITLEMENTS_PLIST\n#fi\n";
|
||||
};
|
||||
69BC5020DBE393B56BD76636 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -642,28 +468,12 @@
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
0BEA5C2D1F7B8F73000D0AB4 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0B7001701F7C51CC005944F4 /* InCallController.swift in Sources */,
|
||||
E5C97B63227A1EB400199214 /* JitsiMeetCommands.swift in Sources */,
|
||||
0B5418471F7C5D8C00A2DD86 /* MeetingRowController.swift in Sources */,
|
||||
E588011722789D43008B0561 /* JitsiMeetContext.swift in Sources */,
|
||||
0BEA5C391F7B8F73000D0AB4 /* ExtensionDelegate.swift in Sources */,
|
||||
0BEA5C371F7B8F73000D0AB4 /* InterfaceController.swift in Sources */,
|
||||
0BEA5C3B1F7B8F73000D0AB4 /* ComplicationController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0B412F1F1EDEE6E800B1A0A6 /* ViewController.m in Sources */,
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
DE4C456121DE1E4E00EA0709 /* FIRUtilities.m in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
DEA0B7122D7EF16E0062A9F6 /* ViewController.swift in Sources */,
|
||||
DEA0B7142D7EF7590062A9F6 /* AppDelegate.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -682,16 +492,6 @@
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
0BEA5C341F7B8F73000D0AB4 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 0BEA5C301F7B8F73000D0AB4 /* JitsiMeetCompanion Extension */;
|
||||
targetProxy = 0BEA5C331F7B8F73000D0AB4 /* PBXContainerItemProxy */;
|
||||
};
|
||||
0BEA5C401F7B8F73000D0AB4 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 0BEA5C241F7B8F73000D0AB4 /* JitsiMeetCompanion */;
|
||||
targetProxy = 0BEA5C3F1F7B8F73000D0AB4 /* PBXContainerItemProxy */;
|
||||
};
|
||||
4EB0602A260E026600F524C5 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 4EB06022260E026600F524C5 /* JitsiMeetBroadcastExtension */;
|
||||
@@ -700,175 +500,23 @@
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
0BEA5C271F7B8F73000D0AB4 /* Interface.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
0BEA5C281F7B8F73000D0AB4 /* Base */,
|
||||
);
|
||||
name = Interface.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
13B07FB21A68108700A75B9A /* Base */,
|
||||
);
|
||||
name = LaunchScreen.xib;
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
0BEA5C421F7B8F73000D0AB4 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = FC967L3QRG;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
IBSC_MODULE = JitsiMeetCompanion_Extension;
|
||||
INFOPLIST_FILE = watchos/app/Info.plist;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.watchkit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0BEA5C431F7B8F73000D0AB4 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = FC967L3QRG;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
IBSC_MODULE = JitsiMeetCompanion_Extension;
|
||||
INFOPLIST_FILE = watchos/app/Info.plist;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.watchkit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
0BEA5C441F7B8F73000D0AB4 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = FC967L3QRG;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = watchos/extension/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.watchkit.extension;
|
||||
PRODUCT_NAME = "${TARGET_NAME}";
|
||||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0BEA5C451F7B8F73000D0AB4 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = FC967L3QRG;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = watchos/extension/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.watchkit.extension;
|
||||
PRODUCT_NAME = "${TARGET_NAME}";
|
||||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 756FCE06C08D9B947653C98A /* Pods-JitsiMeet.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIconDebug;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = app.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
@@ -893,6 +541,8 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 6.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -901,8 +551,8 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3E0F4ED943C0B12BE77F6B45 /* Pods-JitsiMeet.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIconRelease;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = app.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
@@ -926,6 +576,7 @@
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||
SWIFT_VERSION = 6.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
@@ -1148,24 +799,6 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
0BEA5C461F7B8F73000D0AB4 /* Build configuration list for PBXNativeTarget "JitsiMeetCompanion Extension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0BEA5C441F7B8F73000D0AB4 /* Debug */,
|
||||
0BEA5C451F7B8F73000D0AB4 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
0BEA5C481F7B8F73000D0AB4 /* Build configuration list for PBXNativeTarget "JitsiMeetCompanion" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0BEA5C421F7B8F73000D0AB4 /* Debug */,
|
||||
0BEA5C431F7B8F73000D0AB4 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "JitsiMeet" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2017-present Atlassian Pty Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
@end
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2018-present 8x8, Inc.
|
||||
* Copyright @ 2017-2018 Atlassian Pty Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "FIRUtilities.h"
|
||||
#import "Types.h"
|
||||
#import "ViewController.h"
|
||||
|
||||
@import Firebase;
|
||||
@import JitsiMeetSDK;
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
JitsiMeet *jitsiMeet = [JitsiMeet sharedInstance];
|
||||
|
||||
#if 0
|
||||
jitsiMeet.webRtcLoggingSeverity = WebRTCLoggingSeverityVerbose;
|
||||
#endif
|
||||
|
||||
jitsiMeet.conferenceActivityType = JitsiMeetConferenceActivityType;
|
||||
jitsiMeet.customUrlScheme = @"org.jitsi.meet";
|
||||
jitsiMeet.universalLinkDomains = @[@"meet.jit.si", @"alpha.jitsi.net", @"beta.meet.jit.si"];
|
||||
|
||||
jitsiMeet.defaultConferenceOptions = [JitsiMeetConferenceOptions fromBuilder:^(JitsiMeetConferenceOptionsBuilder *builder) {
|
||||
|
||||
// For testing configOverrides a room needs to be set
|
||||
// builder.room = @"https://meet.jit.si/test0988test";
|
||||
|
||||
[builder setFeatureFlag:@"welcomepage.enabled" withBoolean:YES];
|
||||
[builder setFeatureFlag:@"ios.screensharing.enabled" withBoolean:YES];
|
||||
[builder setFeatureFlag:@"ios.recording.enabled" withBoolean:YES];
|
||||
}];
|
||||
|
||||
[jitsiMeet application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
// Initialize Crashlytics and Firebase if a valid GoogleService-Info.plist file was provided.
|
||||
if ([FIRUtilities appContainsRealServiceInfoPlist]) {
|
||||
NSLog(@"Enabling Firebase");
|
||||
[FIRApp configure];
|
||||
// Crashlytics defaults to disabled with the FirebaseCrashlyticsCollectionEnabled Info.plist key.
|
||||
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:![jitsiMeet isCrashReportingDisabled]];
|
||||
}
|
||||
|
||||
ViewController *rootController = (ViewController *)self.window.rootViewController;
|
||||
[jitsiMeet showSplashScreen:rootController.view];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) applicationWillTerminate:(UIApplication *)application {
|
||||
NSLog(@"Application will terminate!");
|
||||
// Try to leave the current meeting graceefully.
|
||||
ViewController *rootController = (ViewController *)self.window.rootViewController;
|
||||
[rootController terminate];
|
||||
}
|
||||
|
||||
#pragma mark Linking delegate methods
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
continueUserActivity:(NSUserActivity *)userActivity
|
||||
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *restorableObjects))restorationHandler {
|
||||
|
||||
if ([FIRUtilities appContainsRealServiceInfoPlist]) {
|
||||
// 1. Attempt to handle Universal Links through Firebase in order to support
|
||||
// its Dynamic Links (which we utilize for the purposes of deferred deep
|
||||
// linking).
|
||||
BOOL handled
|
||||
= [[FIRDynamicLinks dynamicLinks]
|
||||
handleUniversalLink:userActivity.webpageURL
|
||||
completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) {
|
||||
NSURL *firebaseUrl = [FIRUtilities extractURL:dynamicLink];
|
||||
if (firebaseUrl != nil) {
|
||||
userActivity.webpageURL = firebaseUrl;
|
||||
[[JitsiMeet sharedInstance] application:application
|
||||
continueUserActivity:userActivity
|
||||
restorationHandler:restorationHandler];
|
||||
}
|
||||
}];
|
||||
|
||||
if (handled) {
|
||||
return handled;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Default to plain old, non-Firebase-assisted Universal Links.
|
||||
return [[JitsiMeet sharedInstance] application:application
|
||||
continueUserActivity:userActivity
|
||||
restorationHandler:restorationHandler];
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)app
|
||||
openURL:(NSURL *)url
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
|
||||
// This shows up during a reload in development, skip it.
|
||||
// https://github.com/firebase/firebase-ios-sdk/issues/233
|
||||
if ([[url absoluteString] containsString:@"google/link/?dismiss=1&is_weak_match=1"]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSURL *openUrl = url;
|
||||
|
||||
if ([FIRUtilities appContainsRealServiceInfoPlist]) {
|
||||
// Process Firebase Dynamic Links
|
||||
FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
|
||||
NSURL *firebaseUrl = [FIRUtilities extractURL:dynamicLink];
|
||||
if (firebaseUrl != nil) {
|
||||
openUrl = firebaseUrl;
|
||||
}
|
||||
}
|
||||
|
||||
return [[JitsiMeet sharedInstance] application:app
|
||||
openURL:openUrl
|
||||
options:options];
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientationMask)application:(UIApplication *)application
|
||||
supportedInterfaceOrientationsForWindow:(UIWindow *)window {
|
||||
return [[JitsiMeet sharedInstance] application:application
|
||||
supportedInterfaceOrientationsForWindow:window];
|
||||
}
|
||||
|
||||
@end
|
||||
78
ios/app/src/AppDelegate.swift
Normal file
78
ios/app/src/AppDelegate.swift
Normal file
@@ -0,0 +1,78 @@
|
||||
import UIKit
|
||||
import Firebase
|
||||
import JitsiMeetSDK
|
||||
|
||||
@main
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
self.window = UIWindow(frame: UIScreen.main.bounds)
|
||||
|
||||
let jitsiMeet = JitsiMeet.sharedInstance()
|
||||
|
||||
// jitsiMeet.webRtcLoggingSeverity = .verbose
|
||||
|
||||
jitsiMeet.conferenceActivityType = "org.jitsi.JitsiMeet.ios.conference" // Must match the one defined in Info.plist{}
|
||||
jitsiMeet.customUrlScheme = "org.jitsi.meet"
|
||||
jitsiMeet.universalLinkDomains = ["meet.jit.si", "alpha.jitsi.net", "beta.meet.jit.si"]
|
||||
|
||||
jitsiMeet.defaultConferenceOptions = JitsiMeetConferenceOptions.fromBuilder { builder in
|
||||
// For testing configOverrides a room needs to be set
|
||||
// builder.room = "https://meet.jit.si/test0988test"
|
||||
|
||||
builder.setFeatureFlag("welcomepage.enabled", withBoolean: true)
|
||||
builder.setFeatureFlag("ios.screensharing.enabled", withBoolean: true)
|
||||
builder.setFeatureFlag("ios.recording.enabled", withBoolean: true)
|
||||
}
|
||||
|
||||
jitsiMeet.application(application, didFinishLaunchingWithOptions: launchOptions ?? [:])
|
||||
|
||||
if self.appContainsRealServiceInfoPlist() {
|
||||
print("Enabling Firebase")
|
||||
FirebaseApp.configure()
|
||||
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(!jitsiMeet.isCrashReportingDisabled())
|
||||
}
|
||||
|
||||
let vc = ViewController()
|
||||
self.window?.rootViewController = vc
|
||||
jitsiMeet.showSplashScreen()
|
||||
|
||||
self.window?.makeKeyAndVisible()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ application: UIApplication) {
|
||||
print("Application will terminate!")
|
||||
if let rootController = self.window?.rootViewController as? ViewController {
|
||||
rootController.terminate()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Linking delegate methods
|
||||
|
||||
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
|
||||
return JitsiMeet.sharedInstance().application(application, continue: userActivity, restorationHandler: restorationHandler)
|
||||
}
|
||||
|
||||
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
|
||||
if url.absoluteString.contains("google/link/?dismiss=1&is_weak_match=1") {
|
||||
return false
|
||||
}
|
||||
|
||||
return JitsiMeet.sharedInstance().application(app, open: url, options: options)
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
|
||||
return JitsiMeet.sharedInstance().application(application, supportedInterfaceOrientationsFor: window)
|
||||
}
|
||||
}
|
||||
|
||||
// Firebase utilities
|
||||
extension AppDelegate {
|
||||
func appContainsRealServiceInfoPlist() -> Bool {
|
||||
return InfoPlistUtil.containsRealServiceInfoPlist(in: Bundle.main)
|
||||
}
|
||||
}
|
||||
42
ios/app/src/Base.lproj/LaunchScreen.storyboard
Normal file
42
ios/app/src/Base.lproj/LaunchScreen.storyboard
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" userInteractionEnabled="NO" contentMode="center" image="LaunchScreen" translatesAutoresizingMaskIntoConstraints="NO" id="4B8-Xf-NDE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.090196078431372548" green="0.62745098039215685" blue="0.85882352941176465" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="4B8-Xf-NDE" secondAttribute="bottom" id="aFF-BR-glX"/>
|
||||
<constraint firstItem="4B8-Xf-NDE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="glR-YN-1GF"/>
|
||||
<constraint firstAttribute="trailing" secondItem="4B8-Xf-NDE" secondAttribute="trailing" id="tva-gl-jRX"/>
|
||||
<constraint firstItem="4B8-Xf-NDE" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="yaV-1V-oEh"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="LaunchScreen" width="480" height="480"/>
|
||||
</resources>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" userInteractionEnabled="NO" contentMode="center" image="LaunchScreen" translatesAutoresizingMaskIntoConstraints="NO" id="4B8-Xf-NDE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.090196078431372548" green="0.62745098039215685" blue="0.85882352941176465" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="4B8-Xf-NDE" secondAttribute="bottom" id="aFF-BR-glX"/>
|
||||
<constraint firstItem="4B8-Xf-NDE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="glR-YN-1GF"/>
|
||||
<constraint firstAttribute="trailing" secondItem="4B8-Xf-NDE" secondAttribute="trailing" id="tva-gl-jRX"/>
|
||||
<constraint firstItem="4B8-Xf-NDE" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="yaV-1V-oEh"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="LaunchScreen" width="480" height="480"/>
|
||||
</resources>
|
||||
</document>
|
||||
@@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="u7g-vg-A8m">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="xSm-U5-Hdu">
|
||||
<objects>
|
||||
<viewController id="u7g-vg-A8m" customClass="ViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="d40-fc-Y8P"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="1KD-Ho-g0H"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="QpR-jB-WOw" customClass="JitsiMeetView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="ZIj-K3-jVH" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="28" y="138"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Google
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@import Firebase;
|
||||
|
||||
|
||||
@interface FIRUtilities : NSObject
|
||||
|
||||
+ (BOOL)appContainsRealServiceInfoPlist;
|
||||
+ (NSURL *_Nullable)extractURL: (FIRDynamicLink* _Nullable)dynamicLink;
|
||||
|
||||
@end
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Google
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRUtilities.h"
|
||||
|
||||
@import JitsiMeetSDK;
|
||||
|
||||
@implementation FIRUtilities
|
||||
|
||||
+ (BOOL)appContainsRealServiceInfoPlist {
|
||||
static BOOL containsRealServiceInfoPlist = NO;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
containsRealServiceInfoPlist = [InfoPlistUtil containsRealServiceInfoPlistInBundle:bundle];
|
||||
});
|
||||
return containsRealServiceInfoPlist;
|
||||
}
|
||||
|
||||
+ (NSURL *)extractURL: (FIRDynamicLink*)dynamicLink {
|
||||
NSURL *url = nil;
|
||||
if (dynamicLink != nil) {
|
||||
NSURL *dynamicLinkURL = dynamicLink.url;
|
||||
if (dynamicLinkURL != nil
|
||||
&& (dynamicLink.matchType == FIRDLMatchTypeUnique
|
||||
|| dynamicLink.matchType == FIRDLMatchTypeDefault)) {
|
||||
// Strong match, process it.
|
||||
url = dynamicLinkURL;
|
||||
}
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -88,11 +88,9 @@
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UIStatusBarStyle</key>
|
||||
<string>UIStatusBarStyleLightContent</string>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// This must match what's defined in the NSUserActivityTypes array in the
|
||||
// Info.plist file.
|
||||
static NSString *const JitsiMeetConferenceActivityType
|
||||
= @"org.jitsi.JitsiMeet.ios.conference";
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2017-present Atlassian Pty Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@import UIKit;
|
||||
@import JitsiMeetSDK;
|
||||
|
||||
@interface ViewController : UIViewController<JitsiMeetViewDelegate>
|
||||
|
||||
- (void)terminate;
|
||||
|
||||
@end
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2017-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@import CoreSpotlight;
|
||||
@import MobileCoreServices;
|
||||
@import Intents; // Needed for NSUserActivity suggestedInvocationPhrase
|
||||
|
||||
@import JitsiMeetSDK;
|
||||
|
||||
#import "Types.h"
|
||||
#import "ViewController.h"
|
||||
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
JitsiMeetView *view = (JitsiMeetView *) self.view;
|
||||
view.delegate = self;
|
||||
|
||||
[view join:[[JitsiMeet sharedInstance] getInitialConferenceOptions]];
|
||||
}
|
||||
|
||||
// JitsiMeetViewDelegate
|
||||
|
||||
- (void)_onJitsiMeetViewDelegateEvent:(NSString *)name
|
||||
withData:(NSDictionary *)data {
|
||||
NSLog(
|
||||
@"[%s:%d] JitsiMeetViewDelegate %@ %@",
|
||||
__FILE__, __LINE__, name, data);
|
||||
|
||||
#if DEBUG
|
||||
NSAssert(
|
||||
[NSThread isMainThread],
|
||||
@"JitsiMeetViewDelegate %@ method invoked on a non-main thread",
|
||||
name);
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)conferenceJoined:(NSDictionary *)data {
|
||||
[self _onJitsiMeetViewDelegateEvent:@"CONFERENCE_JOINED" withData:data];
|
||||
|
||||
// Register a NSUserActivity for this conference so it can be invoked as a
|
||||
// Siri shortcut.
|
||||
NSUserActivity *userActivity
|
||||
= [[NSUserActivity alloc] initWithActivityType:JitsiMeetConferenceActivityType];
|
||||
|
||||
NSString *urlStr = data[@"url"];
|
||||
NSURL *url = [NSURL URLWithString:urlStr];
|
||||
NSString *conference = [url.pathComponents lastObject];
|
||||
|
||||
userActivity.title = [NSString stringWithFormat:@"Join %@", conference];
|
||||
userActivity.suggestedInvocationPhrase = @"Join my Jitsi meeting";
|
||||
userActivity.userInfo = @{@"url": urlStr};
|
||||
[userActivity setEligibleForSearch:YES];
|
||||
[userActivity setEligibleForPrediction:YES];
|
||||
[userActivity setPersistentIdentifier:urlStr];
|
||||
|
||||
// Subtitle
|
||||
CSSearchableItemAttributeSet *attributes
|
||||
= [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *)kUTTypeItem];
|
||||
attributes.contentDescription = urlStr;
|
||||
userActivity.contentAttributeSet = attributes;
|
||||
|
||||
self.userActivity = userActivity;
|
||||
[userActivity becomeCurrent];
|
||||
}
|
||||
|
||||
- (void)conferenceTerminated:(NSDictionary *)data {
|
||||
[self _onJitsiMeetViewDelegateEvent:@"CONFERENCE_TERMINATED" withData:data];
|
||||
}
|
||||
|
||||
- (void)conferenceWillJoin:(NSDictionary *)data {
|
||||
[self _onJitsiMeetViewDelegateEvent:@"CONFERENCE_WILL_JOIN" withData:data];
|
||||
}
|
||||
|
||||
// - (void)customButtonPressed:(NSDictionary *)data {
|
||||
// [self _onJitsiMeetViewDelegateEvent:@"CUSTOM_BUTTON_PRESSED" withData:data];
|
||||
// }
|
||||
|
||||
#if 0
|
||||
- (void)enterPictureInPicture:(NSDictionary *)data {
|
||||
[self _onJitsiMeetViewDelegateEvent:@"ENTER_PICTURE_IN_PICTURE" withData:data];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)readyToClose:(NSDictionary *)data {
|
||||
[self _onJitsiMeetViewDelegateEvent:@"READY_TO_CLOSE" withData:data];
|
||||
}
|
||||
|
||||
// - (void)transcriptionChunkReceived:(NSDictionary *)data {
|
||||
// [self _onJitsiMeetViewDelegateEvent:@"TRANSCRIPTION_CHUNK_RECEIVED" withData:data];
|
||||
// }
|
||||
|
||||
- (void)participantJoined:(NSDictionary *)data {
|
||||
NSLog(@"%@%@", @"Participant joined: ", data[@"participantId"]);
|
||||
}
|
||||
|
||||
- (void)participantLeft:(NSDictionary *)data {
|
||||
NSLog(@"%@%@", @"Participant left: ", data[@"participantId"]);
|
||||
}
|
||||
|
||||
- (void)audioMutedChanged:(NSDictionary *)data {
|
||||
NSLog(@"%@%@", @"Audio muted changed: ", data[@"muted"]);
|
||||
}
|
||||
|
||||
- (void)endpointTextMessageReceived:(NSDictionary *)data {
|
||||
NSLog(@"%@%@", @"Endpoint text message received: ", data);
|
||||
}
|
||||
|
||||
- (void)screenShareToggled:(NSDictionary *)data {
|
||||
NSLog(@"%@%@", @"Screen share toggled: ", data);
|
||||
}
|
||||
|
||||
- (void)chatMessageReceived:(NSDictionary *)data {
|
||||
NSLog(@"%@%@", @"Chat message received: ", data);
|
||||
}
|
||||
|
||||
- (void)chatToggled:(NSDictionary *)data {
|
||||
NSLog(@"%@%@", @"Chat toggled: ", data);
|
||||
}
|
||||
|
||||
- (void)videoMutedChanged:(NSDictionary *)data {
|
||||
NSLog(@"%@%@", @"Video muted changed: ", data[@"muted"]);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Helpers
|
||||
|
||||
- (void)terminate {
|
||||
JitsiMeetView *view = (JitsiMeetView *) self.view;
|
||||
[view leave];
|
||||
}
|
||||
|
||||
@end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user