Compare commits
663 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b5500fe75 | ||
|
|
2845f48430 | ||
|
|
4ba959e6e1 | ||
|
|
72d9ac508a | ||
|
|
386600baf9 | ||
|
|
eb1825defd | ||
|
|
33069739ee | ||
|
|
dd8c526fb7 | ||
|
|
2701e63406 | ||
|
|
b972da059a | ||
|
|
81862215b4 | ||
|
|
a34e998c42 | ||
|
|
6d1193a751 | ||
|
|
0cd7399dc9 | ||
|
|
f1b0b60340 | ||
|
|
d1cf43f9a4 | ||
|
|
a0b3b1affd | ||
|
|
2a7fdfc832 | ||
|
|
672070e618 | ||
|
|
6a2b1bb48d | ||
|
|
db121c0839 | ||
|
|
ca9db9fd3f | ||
|
|
ecccf673a9 | ||
|
|
e0d7cae3fe | ||
|
|
241526f127 | ||
|
|
4148099115 | ||
|
|
5edf200157 | ||
|
|
bd7ba3acb1 | ||
|
|
e024d9bbb0 | ||
|
|
3d7b8b3162 | ||
|
|
8887272577 | ||
|
|
c86257568f | ||
|
|
ae25538706 | ||
|
|
21e417433b | ||
|
|
cb272be805 | ||
|
|
b79d8d6c82 | ||
|
|
be8aed6a95 | ||
|
|
d06337dddc | ||
|
|
0f3ec47074 | ||
|
|
3a5bad4b7a | ||
|
|
2aecd1035e | ||
|
|
5d04842a80 | ||
|
|
59c73a4814 | ||
|
|
25affe5484 | ||
|
|
399aed4087 | ||
|
|
31dbe2278e | ||
|
|
9ed064b7fc | ||
|
|
a59353df9f | ||
|
|
8acd47bf2f | ||
|
|
be53cb027c | ||
|
|
6ff8c1de05 | ||
|
|
2ebbf062d0 | ||
|
|
fd538bc6c8 | ||
|
|
c0959ceaeb | ||
|
|
6c382c647c | ||
|
|
8f9bed0443 | ||
|
|
dc3996c077 | ||
|
|
5bfd5e4495 | ||
|
|
d646de7184 | ||
|
|
bc2b0f8392 | ||
|
|
f2a7cf5c64 | ||
|
|
0df628dc7a | ||
|
|
a5d1fbff98 | ||
|
|
5cae57601a | ||
|
|
2b7fb7a9a6 | ||
|
|
feb238c5d9 | ||
|
|
0d888eea85 | ||
|
|
bfb6ecbac7 | ||
|
|
2152fe6a79 | ||
|
|
b113696fe6 | ||
|
|
b65a24df96 | ||
|
|
c655bf852f | ||
|
|
be495c17bc | ||
|
|
9785ff4be6 | ||
|
|
5ec37e9112 | ||
|
|
f9f84fd407 | ||
|
|
ed93669693 | ||
|
|
e79ddf2459 | ||
|
|
5efe47cfb6 | ||
|
|
b8045cbcc7 | ||
|
|
aa1090a585 | ||
|
|
0a5589f869 | ||
|
|
383b29dbd8 | ||
|
|
13a9b967e9 | ||
|
|
b798654ca7 | ||
|
|
a5e6890b77 | ||
|
|
2a3a38531b | ||
|
|
4ebf6ebb6f | ||
|
|
6fe736c9fc | ||
|
|
ef682e7023 | ||
|
|
5c3f667fc3 | ||
|
|
a95a055acd | ||
|
|
846499a4fb | ||
|
|
6afb3f70bb | ||
|
|
c063d94aa5 | ||
|
|
261720c941 | ||
|
|
7b3c452316 | ||
|
|
aa00f9bd34 | ||
|
|
b0ff443eac | ||
|
|
a886c598c1 | ||
|
|
2ce4abfdfe | ||
|
|
18c42954ae | ||
|
|
b57b4fa0f8 | ||
|
|
e66cde398a | ||
|
|
3706be77ea | ||
|
|
f481f1e142 | ||
|
|
84b09795f3 | ||
|
|
95954c4b1f | ||
|
|
a56a12a1ef | ||
|
|
5c4b459f57 | ||
|
|
9a616edf2a | ||
|
|
92332b45ea | ||
|
|
5a7fcc3a22 | ||
|
|
6c441353c4 | ||
|
|
b742c95516 | ||
|
|
a59c3da3d0 | ||
|
|
8399f4189f | ||
|
|
67b9fe846b | ||
|
|
0f4ccce0e1 | ||
|
|
01d763eed1 | ||
|
|
41c60419f1 | ||
|
|
195164d9d4 | ||
|
|
518d1da736 | ||
|
|
aade3d4f27 | ||
|
|
22356eb01c | ||
|
|
b5eb88a32f | ||
|
|
6887993f92 | ||
|
|
71b733a018 | ||
|
|
e2eb9cea00 | ||
|
|
99e96a5b13 | ||
|
|
7093254b66 | ||
|
|
f4544b0964 | ||
|
|
c27456277e | ||
|
|
2e824ace00 | ||
|
|
dafa286b18 | ||
|
|
003d01206f | ||
|
|
f0963a332a | ||
|
|
91bdb66f0d | ||
|
|
ffb48c42b0 | ||
|
|
8171828c2a | ||
|
|
a8aa66d191 | ||
|
|
e631d98230 | ||
|
|
1940c67a09 | ||
|
|
c574119718 | ||
|
|
648cd44ddd | ||
|
|
fde8dd9607 | ||
|
|
f1e0cd6c1d | ||
|
|
44df10d6cb | ||
|
|
b6a757842a | ||
|
|
4636c74586 | ||
|
|
2208621050 | ||
|
|
f133dd396c | ||
|
|
ccd04b98b9 | ||
|
|
d37b65e624 | ||
|
|
3e9b811875 | ||
|
|
44c562d8ba | ||
|
|
93c548c013 | ||
|
|
a7d9281768 | ||
|
|
3b369fc98e | ||
|
|
e5cd7e6d40 | ||
|
|
99d05ba967 | ||
|
|
ec9512899e | ||
|
|
26ea6c4e63 | ||
|
|
8e44a7f5c4 | ||
|
|
a093cb6274 | ||
|
|
64f2f330f6 | ||
|
|
473e30e594 | ||
|
|
dc95756ec9 | ||
|
|
2a935868a8 | ||
|
|
f48d8538c0 | ||
|
|
3372dfcd3e | ||
|
|
78d00bcf22 | ||
|
|
9dc9e019f6 | ||
|
|
178c0078c1 | ||
|
|
8478abe378 | ||
|
|
bfc9e43eb4 | ||
|
|
e174025a92 | ||
|
|
89f4408029 | ||
|
|
d7dc277003 | ||
|
|
32bc723745 | ||
|
|
c2ad765424 | ||
|
|
9799afa064 | ||
|
|
e880c14d61 | ||
|
|
e70465c633 | ||
|
|
4ed1835d32 | ||
|
|
19bbccd1a7 | ||
|
|
9d8b80cbce | ||
|
|
dec8264625 | ||
|
|
fe618bd652 | ||
|
|
d208236994 | ||
|
|
4d987f7278 | ||
|
|
193e454fd4 | ||
|
|
bdfb9b4143 | ||
|
|
c9716f3c72 | ||
|
|
7c1704e68b | ||
|
|
771a51224e | ||
|
|
cf275b152a | ||
|
|
98cb85df66 | ||
|
|
032694ad9e | ||
|
|
5437215677 | ||
|
|
5ec80238a0 | ||
|
|
ae6c152988 | ||
|
|
7d15cca1ee | ||
|
|
83c5a67af5 | ||
|
|
c9ad2cd1aa | ||
|
|
fe1f198d99 | ||
|
|
818662c2e6 | ||
|
|
05d0d2a6d6 | ||
|
|
c1a0dad2b7 | ||
|
|
4caf26d069 | ||
|
|
83bc6fb39c | ||
|
|
dbb7568b92 | ||
|
|
45fda44924 | ||
|
|
26f1ade5ba | ||
|
|
9dd93a77a0 | ||
|
|
331d1baad6 | ||
|
|
d3159d86da | ||
|
|
f9e1513491 | ||
|
|
b6e37b7730 | ||
|
|
f9d56eb4c1 | ||
|
|
95565c39ed | ||
|
|
890aacaeee | ||
|
|
e2f0886950 | ||
|
|
fe21b5a502 | ||
|
|
e7043c4d63 | ||
|
|
aae2101131 | ||
|
|
64afed0fb2 | ||
|
|
4d9464ed87 | ||
|
|
b43191506a | ||
|
|
c47781c25a | ||
|
|
f0c4868b3e | ||
|
|
35e5c2329b | ||
|
|
74fc5524ab | ||
|
|
2d4c99a6f7 | ||
|
|
69c73d0a2c | ||
|
|
58510e0208 | ||
|
|
0681d10c51 | ||
|
|
add2356c8a | ||
|
|
c66b2b2291 | ||
|
|
769923c6cc | ||
|
|
27528d084f | ||
|
|
299aa69058 | ||
|
|
d1cc09f40e | ||
|
|
a133b43eed | ||
|
|
9b57725b8c | ||
|
|
34b0f6f014 | ||
|
|
f5cc93ec64 | ||
|
|
4f3263d979 | ||
|
|
b28e374e06 | ||
|
|
918d58ef0a | ||
|
|
5a388d9dde | ||
|
|
0f4909621b | ||
|
|
55d3d8adc3 | ||
|
|
d2d6a6daa4 | ||
|
|
a7f4ac2797 | ||
|
|
25b5027dc7 | ||
|
|
93a967dc74 | ||
|
|
3cfc3dcecf | ||
|
|
e09510ea9f | ||
|
|
4c289fc8fb | ||
|
|
58cf0fa2b1 | ||
|
|
5ca12a73c3 | ||
|
|
fd8e9dad92 | ||
|
|
df0fe0a460 | ||
|
|
646d15b257 | ||
|
|
2eb6848eb8 | ||
|
|
9b3c103f16 | ||
|
|
6a2a13d346 | ||
|
|
b6edf4561d | ||
|
|
c2744700c0 | ||
|
|
f506a5ea6c | ||
|
|
2f702148e3 | ||
|
|
e10c928207 | ||
|
|
a1baa23a52 | ||
|
|
a70e72f75d | ||
|
|
4111da1dd0 | ||
|
|
e7804d014d | ||
|
|
bf87de3706 | ||
|
|
ebc2043055 | ||
|
|
69b1f6c4e1 | ||
|
|
2708777167 | ||
|
|
6e0d62bb65 | ||
|
|
6d706fd222 | ||
|
|
6066265717 | ||
|
|
805e4d01e7 | ||
|
|
e209299af4 | ||
|
|
b3f0a3c9f5 | ||
|
|
1da8841ac7 | ||
|
|
7df5df6351 | ||
|
|
bf85b0c109 | ||
|
|
314e30272b | ||
|
|
61b9a32504 | ||
|
|
01b7d4ffba | ||
|
|
8643972f8c | ||
|
|
1894b8fcf7 | ||
|
|
e59a68cd68 | ||
|
|
466c6da5e3 | ||
|
|
b8cb792831 | ||
|
|
0f9c2a62fe | ||
|
|
04350af96f | ||
|
|
287b3509ab | ||
|
|
2a5bcd3eec | ||
|
|
2a0b9a44dd | ||
|
|
c552db04d7 | ||
|
|
22f1ffc72b | ||
|
|
4f33be20d4 | ||
|
|
9728ddeaf9 | ||
|
|
3c44bdb6b7 | ||
|
|
b236844c94 | ||
|
|
67d12fa6d2 | ||
|
|
215856adc3 | ||
|
|
07e010dfb5 | ||
|
|
dba9ca2084 | ||
|
|
9a60e744d3 | ||
|
|
e1a2ab0d7e | ||
|
|
a605c110a8 | ||
|
|
18c6be0d3b | ||
|
|
ff728e2fc1 | ||
|
|
eff90395b6 | ||
|
|
f4d52b82b4 | ||
|
|
61419b57c8 | ||
|
|
441989a8e1 | ||
|
|
c5a41e1f55 | ||
|
|
0ce4d66601 | ||
|
|
d2d6b319b6 | ||
|
|
47edb71a68 | ||
|
|
1f8626b383 | ||
|
|
0d6a36e187 | ||
|
|
548a0c8517 | ||
|
|
09d85e25c1 | ||
|
|
51b5b14dea | ||
|
|
0d290a2c28 | ||
|
|
c1b3d589c7 | ||
|
|
65430d92ea | ||
|
|
8711830f66 | ||
|
|
c4d919d46b | ||
|
|
3e7a688811 | ||
|
|
2773a675d0 | ||
|
|
9bbdccc111 | ||
|
|
bb8defeb42 | ||
|
|
545dbd0791 | ||
|
|
c7469075ab | ||
|
|
54fa974789 | ||
|
|
2cd3cec478 | ||
|
|
c11b977f1d | ||
|
|
30e8f17b37 | ||
|
|
2c3190ce2a | ||
|
|
ea7796dccc | ||
|
|
a11ca58f36 | ||
|
|
496d711684 | ||
|
|
219b824338 | ||
|
|
df389a365c | ||
|
|
aa2c52c1f8 | ||
|
|
f48ae29f22 | ||
|
|
de00e0e15c | ||
|
|
79fea49272 | ||
|
|
8190b10680 | ||
|
|
1ebd9562a2 | ||
|
|
ebaf63393f | ||
|
|
7c168740d9 | ||
|
|
11b991cddc | ||
|
|
8306e58b75 | ||
|
|
4002739682 | ||
|
|
c259921269 | ||
|
|
2eb3041c1f | ||
|
|
d539d9b5d2 | ||
|
|
d17c985bcb | ||
|
|
e2668e7cfa | ||
|
|
18c2c61bee | ||
|
|
be0b0c1984 | ||
|
|
b00ca217b3 | ||
|
|
874d76b16b | ||
|
|
cfac261516 | ||
|
|
7b5e5c2587 | ||
|
|
db064381d9 | ||
|
|
096c310e0e | ||
|
|
0b87db8b45 | ||
|
|
71cf4a4885 | ||
|
|
a0c6104fae | ||
|
|
8e54ac4dcf | ||
|
|
97b0288c7d | ||
|
|
e3cc8652e4 | ||
|
|
8708a001c7 | ||
|
|
6fc4facddf | ||
|
|
e5536880fb | ||
|
|
44ff8f92ac | ||
|
|
95208267de | ||
|
|
9c579e0d5b | ||
|
|
d1be4c6d96 | ||
|
|
a65afdac95 | ||
|
|
22b47925d4 | ||
|
|
f291e365e5 | ||
|
|
6f176803d4 | ||
|
|
b6a3bb4080 | ||
|
|
c7c1deab81 | ||
|
|
2ded5870b5 | ||
|
|
57f2ae098f | ||
|
|
76c06923d5 | ||
|
|
fb7ac874f0 | ||
|
|
12905f0dcb | ||
|
|
68a313a58f | ||
|
|
152115bf2e | ||
|
|
8bd3051224 | ||
|
|
aa94ca6619 | ||
|
|
e397f72eb2 | ||
|
|
4d495b8d7c | ||
|
|
a142a2717c | ||
|
|
de4a477686 | ||
|
|
4e692e2c1e | ||
|
|
8237e6f7a3 | ||
|
|
d1a9f1feac | ||
|
|
ef1d38462f | ||
|
|
93c8e9aa1f | ||
|
|
ac2dce4bb1 | ||
|
|
f2e1d90c74 | ||
|
|
8e28a229f2 | ||
|
|
363f6cb329 | ||
|
|
b6f7832745 | ||
|
|
74c1db740d | ||
|
|
4bb5dcf50c | ||
|
|
b0d01389c6 | ||
|
|
3e22ada889 | ||
|
|
6d08394adc | ||
|
|
47bdeeef9a | ||
|
|
099440d008 | ||
|
|
eb7201a55b | ||
|
|
6d9f40db30 | ||
|
|
7960706e60 | ||
|
|
8b0e54a95c | ||
|
|
89e8f0ccc3 | ||
|
|
0f67f75bed | ||
|
|
4836173fe6 | ||
|
|
7378ad00b0 | ||
|
|
e876c9b6a6 | ||
|
|
980d20473a | ||
|
|
22511270dd | ||
|
|
89cf733d24 | ||
|
|
a167a8587b | ||
|
|
ffbd488e93 | ||
|
|
fa3117e41e | ||
|
|
4be335b8ac | ||
|
|
3904a9f9a0 | ||
|
|
b683d84df1 | ||
|
|
3ad29f6eb7 | ||
|
|
cf227490d7 | ||
|
|
ffd6f7b326 | ||
|
|
ec2a1b3ddb | ||
|
|
60711471fc | ||
|
|
92738b378c | ||
|
|
c5e9c03de9 | ||
|
|
6637e5b8e3 | ||
|
|
b75442a10e | ||
|
|
811bef41b8 | ||
|
|
65242a503b | ||
|
|
77058b84cd | ||
|
|
673962d6a1 | ||
|
|
c207f68fd9 | ||
|
|
4416dab6c1 | ||
|
|
f59e824ec1 | ||
|
|
310c68a744 | ||
|
|
2d1971123a | ||
|
|
efe3dfad5c | ||
|
|
b10ccce44a | ||
|
|
edadc51e05 | ||
|
|
0e38671224 | ||
|
|
910b2f2b74 | ||
|
|
57387903fd | ||
|
|
8b1ac9fa6e | ||
|
|
ad8c0737d6 | ||
|
|
87d4d46ce7 | ||
|
|
61add763ae | ||
|
|
6562a1f6af | ||
|
|
71efd10c83 | ||
|
|
679347309e | ||
|
|
c8a05137f4 | ||
|
|
f56d80236e | ||
|
|
1b19e870c0 | ||
|
|
684ce09bb5 | ||
|
|
9f08faf263 | ||
|
|
3bd0efa91e | ||
|
|
679330c1c0 | ||
|
|
47d5e54c48 | ||
|
|
03b0c0cff4 | ||
|
|
776dd8b928 | ||
|
|
c2a2f8dabd | ||
|
|
393244d44b | ||
|
|
e6b9caac61 | ||
|
|
81c4166389 | ||
|
|
0b619e50ba | ||
|
|
59ecf375b0 | ||
|
|
338129faea | ||
|
|
151a64f817 | ||
|
|
3461f3dfc7 | ||
|
|
23dc9ef494 | ||
|
|
2fc5b69465 | ||
|
|
f8fc554f78 | ||
|
|
3f58c930e3 | ||
|
|
7705999e57 | ||
|
|
0a754b8982 | ||
|
|
8d3f5820ca | ||
|
|
ef4f0168f8 | ||
|
|
9f5b09c263 | ||
|
|
a1c61daea6 | ||
|
|
90c1c21646 | ||
|
|
bf9069524a | ||
|
|
905376de1d | ||
|
|
6fa556e8ea | ||
|
|
9a8ab84ecb | ||
|
|
5e1b8212b2 | ||
|
|
7ca821f38c | ||
|
|
5c718c7c9a | ||
|
|
7e104805c0 | ||
|
|
21fab77c4b | ||
|
|
770f4a78aa | ||
|
|
c522e047c6 | ||
|
|
92f6949ecc | ||
|
|
478eeea73e | ||
|
|
163ee73719 | ||
|
|
479a6d9ad2 | ||
|
|
b3ffbeb63e | ||
|
|
8a3615281c | ||
|
|
d6b4448d3c | ||
|
|
123523ef62 | ||
|
|
4960e08a24 | ||
|
|
60103f7ad6 | ||
|
|
d3a261de89 | ||
|
|
ecce1edded | ||
|
|
fb8eafab81 | ||
|
|
a6de296703 | ||
|
|
be3e43e6cb | ||
|
|
93678a07a8 | ||
|
|
155b8f1c45 | ||
|
|
e737fa59b3 | ||
|
|
8d27d8efcf | ||
|
|
5174c002cf | ||
|
|
26b8515cb5 | ||
|
|
cf5bd31203 | ||
|
|
d485287a59 | ||
|
|
d0e48a02a1 | ||
|
|
36b702702b | ||
|
|
75db59a8bb | ||
|
|
48548e9303 | ||
|
|
5163905954 | ||
|
|
27d58e1e2a | ||
|
|
78da810114 | ||
|
|
6d65cf2382 | ||
|
|
162da089ec | ||
|
|
228fb2f80d | ||
|
|
8ed600bf3f | ||
|
|
e3b6e1325e | ||
|
|
9101d64b20 | ||
|
|
089c4ceb30 | ||
|
|
dc8abc74ed | ||
|
|
31e3a426a6 | ||
|
|
00969df06f | ||
|
|
c482ccfd4e | ||
|
|
b6432e7d13 | ||
|
|
35a3cb35d5 | ||
|
|
2cadabd60c | ||
|
|
997d1fbc80 | ||
|
|
8ee958bfa0 | ||
|
|
8b64c96381 | ||
|
|
aba6cc2c64 | ||
|
|
0718520f36 | ||
|
|
93b7a797d2 | ||
|
|
4ab0e693c1 | ||
|
|
af5f85a288 | ||
|
|
0a69f3c7fd | ||
|
|
48889ce56e | ||
|
|
4532e59933 | ||
|
|
91d784f9bd | ||
|
|
6f56097c53 | ||
|
|
5b0ad0508a | ||
|
|
f1c06d6743 | ||
|
|
e5949dbb86 | ||
|
|
2b95b96fa3 | ||
|
|
147079ce2a | ||
|
|
e992702783 | ||
|
|
2d05281ba9 | ||
|
|
9a1069c1ae | ||
|
|
561d3e0670 | ||
|
|
d7a41ce8f7 | ||
|
|
784b0a2248 | ||
|
|
346cb4e203 | ||
|
|
de8518a112 | ||
|
|
8ef67c393b | ||
|
|
496c361bdc | ||
|
|
3646301ce4 | ||
|
|
9042109d04 | ||
|
|
91c85ec86b | ||
|
|
7d3919e3f7 | ||
|
|
3a928aac9f | ||
|
|
8b6e24e83d | ||
|
|
ef38572d5a | ||
|
|
a2b04c9d71 | ||
|
|
c20ab0b93e | ||
|
|
c496a34f57 | ||
|
|
27103889a4 | ||
|
|
e781b29d57 | ||
|
|
751506d5b5 | ||
|
|
2061248224 | ||
|
|
dcb748c544 | ||
|
|
ec37867d72 | ||
|
|
20c1b58307 | ||
|
|
e482f041a8 | ||
|
|
ef64d9c188 | ||
|
|
466444e17d | ||
|
|
b420f5b41b | ||
|
|
53a719e1b1 | ||
|
|
5f665b8ecb | ||
|
|
65b2db2160 | ||
|
|
617d21129f | ||
|
|
2d1fdc4485 | ||
|
|
5aa2e66d02 | ||
|
|
8850d974a2 | ||
|
|
e6c4c48261 | ||
|
|
8eb0f3b60a | ||
|
|
5192049194 | ||
|
|
fabf830132 | ||
|
|
c9159e2191 | ||
|
|
f2348fc749 | ||
|
|
264ab285a7 | ||
|
|
f28a92be1d | ||
|
|
d38a6e5047 | ||
|
|
3447aac940 | ||
|
|
711b8cfa36 | ||
|
|
91a6af71a0 | ||
|
|
885e7f0471 | ||
|
|
8c1e546123 | ||
|
|
fd4dedcbdf | ||
|
|
88a82eecf3 | ||
|
|
906122a334 | ||
|
|
6f1529d730 | ||
|
|
46162ed3c4 | ||
|
|
3b911f19f6 | ||
|
|
4e6f55e176 | ||
|
|
14cae1b59a | ||
|
|
9aa23dac80 | ||
|
|
eb099c70e6 | ||
|
|
4837117719 | ||
|
|
550b67236e | ||
|
|
8000ff2cd7 | ||
|
|
da358615e0 | ||
|
|
8f387891e2 | ||
|
|
a961615076 | ||
|
|
bf31722931 | ||
|
|
251f51ca1b | ||
|
|
e8722e1cb2 | ||
|
|
6db4972208 | ||
|
|
f0e18ac619 | ||
|
|
8e7117fa22 | ||
|
|
959859f57c | ||
|
|
f8eef7c9a6 | ||
|
|
595134cab5 | ||
|
|
8b76428c7e | ||
|
|
591fbf0ec6 | ||
|
|
4b5b79e415 | ||
|
|
5a50248055 | ||
|
|
113f665295 | ||
|
|
d56a3d015b | ||
|
|
85c59762a4 | ||
|
|
01b4e1946a | ||
|
|
17cde3426a |
@@ -27,7 +27,7 @@ GOTO:EOF
|
||||
call:logInfo "Clone dependencies repository"
|
||||
git clone -q --depth 1 --branch=master https://github.com/telegramdesktop/dependencies_windows.git %LIB_DIR%
|
||||
cd %LIB_DIR%
|
||||
git clone https://github.com/Microsoft/Range-V3-VS2015 range-v3
|
||||
git clone https://github.com/ericniebler/range-v3
|
||||
if exist prepare.bat (
|
||||
call prepare.bat
|
||||
) else (
|
||||
@@ -48,7 +48,7 @@ GOTO:EOF
|
||||
git submodule init
|
||||
git submodule update
|
||||
cd %SRC_DIR%\Telegram
|
||||
call gyp\refresh.bat
|
||||
call gyp\refresh.bat --api-id 17349 --api-hash 344583e45741c457fe1862106095a5eb
|
||||
GOTO:EOF
|
||||
|
||||
:configureBuild
|
||||
@@ -72,10 +72,6 @@ GOTO:EOF
|
||||
set TDESKTOP_BUILD_DEFINES=%TDESKTOP_BUILD_DEFINES%,TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
|
||||
)
|
||||
|
||||
echo %BUILD_VERSION% | findstr /C:"disable_unity_integration">nul && (
|
||||
set TDESKTOP_BUILD_DEFINES=%TDESKTOP_BUILD_DEFINES%,TDESKTOP_DISABLE_UNITY_INTEGRATION
|
||||
)
|
||||
|
||||
echo %BUILD_VERSION% | findstr /C:"disable_gtk_integration">nul && (
|
||||
set TDESKTOP_BUILD_DEFINES=%TDESKTOP_BUILD_DEFINES%,TDESKTOP_DISABLE_GTK_INTEGRATION
|
||||
)
|
||||
|
||||
3
.github/CONTRIBUTING.md
vendored
@@ -24,6 +24,8 @@ If we find issues with your pull request, we may suggest some changes and improv
|
||||
|
||||
Unfortunately we **do not merge** any pull requests that have new feature implementations, translations to new languages and those which introduce any new user interface elements.
|
||||
|
||||
If you have a translations-related contribution, check out [Translations platform][translate].
|
||||
|
||||
Telegram Desktop is not a standalone application but a part of [Telegram project][telegram], so all the decisions about the features, languages, user experience, user interface and the design are made inside Telegram team, often according to some roadmap which is not public.
|
||||
|
||||
## Build instructions
|
||||
@@ -113,3 +115,4 @@ Before you submit a pull request, please test your changes. Verify that Telegram
|
||||
[pr]: https://github.com/telegramdesktop/tdesktop/compare
|
||||
[build_instructions]: https://github.com/telegramdesktop/tdesktop/blob/master/README.md#build-instructions
|
||||
[closing-issues-via-commit-messages]: https://help.github.com/articles/closing-issues-via-commit-messages/
|
||||
[translate]: https://translations.telegram.org
|
||||
|
||||
@@ -14,7 +14,6 @@ env:
|
||||
- BUILD_VERSION="disable_crash_reports"
|
||||
- BUILD_VERSION="disable_network_proxy"
|
||||
- BUILD_VERSION="disable_desktop_file_generation"
|
||||
- BUILD_VERSION="disable_unity_integration"
|
||||
- BUILD_VERSION="disable_gtk_integration"
|
||||
|
||||
matrix:
|
||||
@@ -45,7 +44,7 @@ addons:
|
||||
- libopus-dev
|
||||
- libpulse-dev
|
||||
- libssl-dev
|
||||
- libunity-dev
|
||||
- libdee-dev
|
||||
- libva-dev
|
||||
- libvdpau-dev
|
||||
- libxcb-xkb-dev
|
||||
|
||||
@@ -17,7 +17,7 @@ XKB_PATH="$BUILD/libxkbcommon"
|
||||
XKB_CACHE_VERSION="3"
|
||||
|
||||
QT_PATH="$BUILD/qt"
|
||||
QT_CACHE_VERSION="3"
|
||||
QT_CACHE_VERSION="4"
|
||||
QT_PATCH="$UPSTREAM/Telegram/Patches/qtbase_${QT_VERSION//\./_}.diff"
|
||||
|
||||
BREAKPAD_PATH="$BUILD/breakpad"
|
||||
@@ -40,7 +40,7 @@ FFMPEG_PATH="$BUILD/ffmpeg"
|
||||
FFMPEG_CACHE_VERSION="3"
|
||||
|
||||
OPENAL_PATH="$BUILD/openal-soft"
|
||||
OPENAL_CACHE_VERSION="3"
|
||||
OPENAL_CACHE_VERSION="4"
|
||||
|
||||
GYP_DEFINES=""
|
||||
|
||||
@@ -116,10 +116,6 @@ build() {
|
||||
GYP_DEFINES+=",TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION"
|
||||
fi
|
||||
|
||||
if [[ $BUILD_VERSION == *"disable_unity_integration"* ]]; then
|
||||
GYP_DEFINES+=",TDESKTOP_DISABLE_UNITY_INTEGRATION"
|
||||
fi
|
||||
|
||||
if [[ $BUILD_VERSION == *"disable_gtk_integration"* ]]; then
|
||||
GYP_DEFINES+=",TDESKTOP_DISABLE_GTK_INTEGRATION"
|
||||
fi
|
||||
@@ -318,6 +314,7 @@ buildVdpau() {
|
||||
git clone git://anongit.freedesktop.org/vdpau/libvdpau
|
||||
|
||||
cd "$EXTERNAL/libvdpau"
|
||||
git checkout libvdpau-1.2
|
||||
./autogen.sh --prefix=$VDPAU_PATH --enable-static
|
||||
make $MAKE_ARGS
|
||||
sudo make install
|
||||
@@ -472,10 +469,12 @@ buildOpenAL() {
|
||||
rm -rf "$EXTERNAL/openal-soft"
|
||||
fi
|
||||
cd $OPENAL_PATH
|
||||
rm -rf *
|
||||
sudo rm -rf *
|
||||
|
||||
cd "$EXTERNAL"
|
||||
git clone https://github.com/kcat/openal-soft.git
|
||||
cd openal-soft
|
||||
git checkout openal-soft-1.19.1
|
||||
|
||||
cd "$EXTERNAL/openal-soft/build"
|
||||
cmake \
|
||||
@@ -602,6 +601,7 @@ buildCustomQt() {
|
||||
cd "$EXTERNAL/qt${QT_VERSION}/qtbase/src/plugins/platforminputcontexts"
|
||||
git clone https://github.com/telegramdesktop/fcitx.git
|
||||
git clone https://github.com/telegramdesktop/hime.git
|
||||
git clone https://github.com/telegramdesktop/nimf.git
|
||||
cd ../../../..
|
||||
|
||||
./configure -prefix $QT_PATH -release -opensource -confirm-license -qt-zlib \
|
||||
@@ -673,6 +673,8 @@ buildTelegram() {
|
||||
|
||||
cd "$UPSTREAM/Telegram/gyp"
|
||||
"$GYP_PATH/gyp" \
|
||||
-Dapi_id=17349 \
|
||||
-Dapi_hash=344583e45741c457fe1862106095a5eb \
|
||||
-Dbuild_defines=${GYP_DEFINES:1} \
|
||||
-Dlinux_path_xkbcommon=$XKB_PATH \
|
||||
-Dlinux_path_va=$VA_PATH \
|
||||
|
||||
2
LEGAL
@@ -1,7 +1,7 @@
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Copyright (c) 2014-2018 John Preston, https://desktop.telegram.org
|
||||
Copyright (c) 2014-2019 John Preston, https://desktop.telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -15,8 +15,8 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||
* Windows XP - Windows 10 (**not** RT)
|
||||
* Mac OS X 10.8 - Mac OS X 10.11
|
||||
* Mac OS X 10.6 - Mac OS X 10.7 (separate build)
|
||||
* Ubuntu 12.04 - Ubuntu 18.04
|
||||
* Fedora 22 - Fedora 28
|
||||
* Ubuntu 12.04 - Ubuntu 18.10
|
||||
* Fedora 22 - Fedora 29
|
||||
* [Snappy](https://snapcraft.io/telegram-desktop)
|
||||
|
||||
## Third-party
|
||||
@@ -31,7 +31,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||
* Google Crashpad ([Apache License 2.0](https://chromium.googlesource.com/crashpad/crashpad/+/master/LICENSE))
|
||||
* GYP ([BSD License](https://github.com/bnoordhuis/gyp/blob/master/LICENSE))
|
||||
* Ninja ([Apache License 2.0](https://github.com/ninja-build/ninja/blob/master/COPYING))
|
||||
* OpenAL Soft ([LGPL](http://kcat.strangesoft.net/openal.html))
|
||||
* OpenAL Soft ([LGPL](https://github.com/kcat/openal-soft/blob/master/COPYING))
|
||||
* Opus codec ([BSD License](http://www.opus-codec.org/license/))
|
||||
* FFmpeg ([LGPL](https://www.ffmpeg.org/legal.html))
|
||||
* Guideline Support Library ([MIT License](https://github.com/Microsoft/GSL/blob/master/LICENSE))
|
||||
@@ -45,7 +45,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||
## Build instructions
|
||||
|
||||
* [Visual Studio 2017][msvc]
|
||||
* [Xcode 9][xcode]
|
||||
* [Xcode 10][xcode]
|
||||
* [GYP/CMake on GNU/Linux][cmake]
|
||||
|
||||
[//]: # (LINKS)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/src/build/common.gypi b/src/build/common.gypi
|
||||
index 29990c6..53e99d4 100644
|
||||
index 29990c65..53e99d44 100644
|
||||
--- a/src/build/common.gypi
|
||||
+++ b/src/build/common.gypi
|
||||
@@ -330,6 +330,7 @@
|
||||
@@ -11,7 +11,7 @@ index 29990c6..53e99d4 100644
|
||||
},
|
||||
}],
|
||||
diff --git a/src/client/mac/Breakpad.xcodeproj/project.pbxproj b/src/client/mac/Breakpad.xcodeproj/project.pbxproj
|
||||
index 1a93ce6..1c1d643 100644
|
||||
index 1a93ce6d..b5986e33 100644
|
||||
--- a/src/client/mac/Breakpad.xcodeproj/project.pbxproj
|
||||
+++ b/src/client/mac/Breakpad.xcodeproj/project.pbxproj
|
||||
@@ -35,6 +35,19 @@
|
||||
@@ -34,7 +34,15 @@ index 1a93ce6..1c1d643 100644
|
||||
162F64F2161C577500CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F0161C577500CD68D5 /* arch_utilities.cc */; };
|
||||
162F64F3161C577500CD68D5 /* arch_utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 162F64F1161C577500CD68D5 /* arch_utilities.h */; };
|
||||
162F64F4161C579B00CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F0161C577500CD68D5 /* arch_utilities.cc */; };
|
||||
@@ -170,11 +183,8 @@
|
||||
@@ -67,6 +80,7 @@
|
||||
4DBE49A7134A4F280072546A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBE4769134A4F080072546A /* CoreServices.framework */; };
|
||||
4DBE49A8134A4F380072546A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBE4769134A4F080072546A /* CoreServices.framework */; };
|
||||
4DBE49A9134A4F460072546A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBE4769134A4F080072546A /* CoreServices.framework */; };
|
||||
+ 5A8B220921E0C5740045F83C /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; };
|
||||
8B3101C611F0CD9F00FCF3E4 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D6A5FE840307C02AAC07 /* AppKit.framework */; };
|
||||
8B3101C711F0CD9F00FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; };
|
||||
8B3101CA11F0CDB000FCF3E4 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D6A5FE840307C02AAC07 /* AppKit.framework */; };
|
||||
@@ -170,11 +184,8 @@
|
||||
F92C564A0ECD10CA009BE4BA /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53850ECCE6AD009BE4BA /* string_conversion.cc */; };
|
||||
F92C564C0ECD10DD009BE4BA /* breakpadUtilities.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F92C563C0ECD10B3009BE4BA /* breakpadUtilities.dylib */; };
|
||||
F92C56570ECD113E009BE4BA /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F92C554A0ECCF530009BE4BA /* Carbon.framework */; };
|
||||
@@ -46,7 +54,7 @@ index 1a93ce6..1c1d643 100644
|
||||
F92C56A90ECE04C5009BE4BA /* crash_report_sender.m in Sources */ = {isa = PBXBuildFile; fileRef = F92C56A80ECE04C5009BE4BA /* crash_report_sender.m */; };
|
||||
F93803CD0F8083B7004D428B /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536B0ECCE3FD009BE4BA /* dynamic_images.cc */; };
|
||||
F93803CE0F8083B7004D428B /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536D0ECCE3FD009BE4BA /* exception_handler.cc */; };
|
||||
@@ -213,7 +223,6 @@
|
||||
@@ -213,7 +224,6 @@
|
||||
F9C44DBD0EF072A0003AEBAA /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F9C44DBA0EF072A0003AEBAA /* MainMenu.xib */; };
|
||||
F9C44E000EF077CD003AEBAA /* Breakpad.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Breakpad.framework */; };
|
||||
F9C44E3C0EF08B12003AEBAA /* Breakpad.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Breakpad.framework */; };
|
||||
@@ -54,7 +62,7 @@ index 1a93ce6..1c1d643 100644
|
||||
F9C44EA20EF09F93003AEBAA /* HTTPMultipartUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = F92C53770ECCE635009BE4BA /* HTTPMultipartUpload.m */; };
|
||||
F9C44EE50EF0A006003AEBAA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9C44EE40EF0A006003AEBAA /* SystemConfiguration.framework */; };
|
||||
F9C44EE90EF0A3C1003AEBAA /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C44EE80EF0A3C1003AEBAA /* GTMLogger.m */; };
|
||||
@@ -410,20 +419,6 @@
|
||||
@@ -410,20 +420,6 @@
|
||||
remoteGlobalIDString = F92C563B0ECD10B3009BE4BA;
|
||||
remoteInfo = breakpadUtilities;
|
||||
};
|
||||
@@ -75,7 +83,7 @@ index 1a93ce6..1c1d643 100644
|
||||
F93DE2FB0F82C3C600608B94 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
|
||||
@@ -536,13 +531,6 @@
|
||||
@@ -536,13 +532,6 @@
|
||||
remoteGlobalIDString = 8DC2EF4F0486A6940098B216;
|
||||
remoteInfo = Breakpad;
|
||||
};
|
||||
@@ -89,7 +97,7 @@ index 1a93ce6..1c1d643 100644
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@@ -714,7 +702,6 @@
|
||||
@@ -714,7 +703,6 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@@ -97,7 +105,7 @@ index 1a93ce6..1c1d643 100644
|
||||
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1181,18 +1168,13 @@
|
||||
@@ -1181,18 +1169,13 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "Breakpad" */;
|
||||
buildPhases = (
|
||||
@@ -116,7 +124,7 @@ index 1a93ce6..1c1d643 100644
|
||||
);
|
||||
name = Breakpad;
|
||||
productInstallPath = "$(HOME)/Library/Frameworks";
|
||||
@@ -1399,6 +1381,8 @@
|
||||
@@ -1399,6 +1382,8 @@
|
||||
/* Begin PBXProject section */
|
||||
0867D690FE84028FC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
@@ -125,7 +133,7 @@ index 1a93ce6..1c1d643 100644
|
||||
buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "Breakpad" */;
|
||||
compatibilityVersion = "Xcode 3.1";
|
||||
developmentRegion = English;
|
||||
@@ -1583,16 +1567,6 @@
|
||||
@@ -1583,16 +1568,6 @@
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
@@ -142,7 +150,7 @@ index 1a93ce6..1c1d643 100644
|
||||
F92C569C0ECE04A7009BE4BA /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -1640,20 +1614,6 @@
|
||||
@@ -1640,20 +1615,6 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "install_name_tool -id \"@executable_path/../Resources/breakpadUtilities.dylib\" \"${BUILT_PRODUCTS_DIR}/breakpadUtilities.dylib\"\n";
|
||||
};
|
||||
@@ -163,10 +171,11 @@ index 1a93ce6..1c1d643 100644
|
||||
F9C77DD80F7DD5CF0045F7DB /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -1674,6 +1634,19 @@
|
||||
@@ -1674,6 +1635,20 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
+ 5A8B220921E0C5740045F83C /* breakpad_nlist_64.cc in Sources */,
|
||||
+ 0748C0501C63C52D004489BF /* bootstrap_compat.cc in Sources */,
|
||||
+ 0748C04F1C63C523004489BF /* macho_walker.cc in Sources */,
|
||||
+ 0748C04E1C63C51C004489BF /* md5.cc in Sources */,
|
||||
@@ -183,7 +192,7 @@ index 1a93ce6..1c1d643 100644
|
||||
F92C565F0ECD116B009BE4BA /* protected_memory_allocator.cc in Sources */,
|
||||
F92C56630ECD1179009BE4BA /* exception_handler.cc in Sources */,
|
||||
F92C55D10ECD0064009BE4BA /* Breakpad.mm in Sources */,
|
||||
@@ -1955,16 +1928,6 @@
|
||||
@@ -1955,16 +1930,6 @@
|
||||
target = F92C563B0ECD10B3009BE4BA /* breakpadUtilities */;
|
||||
targetProxy = F92C564D0ECD10E5009BE4BA /* PBXContainerItemProxy */;
|
||||
};
|
||||
@@ -200,7 +209,7 @@ index 1a93ce6..1c1d643 100644
|
||||
F93DE2FC0F82C3C600608B94 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = F93803BD0F80820F004D428B /* generator_test */;
|
||||
@@ -2025,11 +1988,6 @@
|
||||
@@ -2025,11 +1990,6 @@
|
||||
target = 8DC2EF4F0486A6940098B216 /* Breakpad */;
|
||||
targetProxy = F9C44E190EF0790F003AEBAA /* PBXContainerItemProxy */;
|
||||
};
|
||||
@@ -212,7 +221,7 @@ index 1a93ce6..1c1d643 100644
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
@@ -2126,8 +2084,12 @@
|
||||
@@ -2126,8 +2086,12 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 8B31027711F0D3AF00FCF3E4 /* BreakpadDebug.xcconfig */;
|
||||
buildSettings = {
|
||||
@@ -226,7 +235,7 @@ index 1a93ce6..1c1d643 100644
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2135,7 +2097,12 @@
|
||||
@@ -2135,7 +2099,12 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 8B31027811F0D3AF00FCF3E4 /* BreakpadRelease.xcconfig */;
|
||||
buildSettings = {
|
||||
@@ -239,7 +248,7 @@ index 1a93ce6..1c1d643 100644
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -2454,7 +2421,12 @@
|
||||
@@ -2454,7 +2423,12 @@
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 8B31027711F0D3AF00FCF3E4 /* BreakpadDebug.xcconfig */;
|
||||
buildSettings = {
|
||||
@@ -253,7 +262,7 @@ index 1a93ce6..1c1d643 100644
|
||||
name = "Debug With Code Coverage";
|
||||
};
|
||||
diff --git a/src/client/mac/Framework/Breakpad.mm b/src/client/mac/Framework/Breakpad.mm
|
||||
index 1d2e519..943310f 100644
|
||||
index 1d2e519b..943310fa 100644
|
||||
--- a/src/client/mac/Framework/Breakpad.mm
|
||||
+++ b/src/client/mac/Framework/Breakpad.mm
|
||||
@@ -355,10 +355,10 @@ bool Breakpad::Initialize(NSDictionary *parameters) {
|
||||
@@ -480,7 +489,7 @@ index 1d2e519..943310f 100644
|
||||
}
|
||||
|
||||
diff --git a/src/common/language.cc b/src/common/language.cc
|
||||
index 978fb85..a95ae5f 100644
|
||||
index 978fb855..a95ae5f7 100644
|
||||
--- a/src/common/language.cc
|
||||
+++ b/src/common/language.cc
|
||||
@@ -46,8 +46,27 @@
|
||||
@@ -552,7 +561,7 @@ index 978fb85..a95ae5f 100644
|
||||
#endif
|
||||
}
|
||||
diff --git a/src/common/linux/elf_symbols_to_module.cc b/src/common/linux/elf_symbols_to_module.cc
|
||||
index 562875e..4367851 100644
|
||||
index 562875e1..43678510 100644
|
||||
--- a/src/common/linux/elf_symbols_to_module.cc
|
||||
+++ b/src/common/linux/elf_symbols_to_module.cc
|
||||
@@ -39,6 +39,29 @@
|
||||
@@ -615,7 +624,7 @@ index 562875e..4367851 100644
|
||||
module->AddExtern(ext);
|
||||
}
|
||||
diff --git a/src/tools/linux/tools_linux.gypi b/src/tools/linux/tools_linux.gypi
|
||||
index 1c15992..020e4c1 100644
|
||||
index 1c15992e..020e4c1c 100644
|
||||
--- a/src/tools/linux/tools_linux.gypi
|
||||
+++ b/src/tools/linux/tools_linux.gypi
|
||||
@@ -58,7 +58,7 @@
|
||||
@@ -627,3 +636,16 @@ index 1c15992..020e4c1 100644
|
||||
],
|
||||
'dependencies': [
|
||||
'../common/common.gyp:common',
|
||||
diff --git a/src/tools/mac/dump_syms/macho_dump.cc b/src/tools/mac/dump_syms/macho_dump.cc
|
||||
index d882bbe8..3432bb45 100644
|
||||
--- a/src/tools/mac/dump_syms/macho_dump.cc
|
||||
+++ b/src/tools/mac/dump_syms/macho_dump.cc
|
||||
@@ -140,7 +140,7 @@ void DumpFile(const char *filename) {
|
||||
size_t object_files_size;
|
||||
const SuperFatArch* super_fat_object_files =
|
||||
fat_reader.object_files(&object_files_size);
|
||||
- struct fat_arch *object_files;
|
||||
+ struct fat_arch *object_files = 0;
|
||||
if (!super_fat_object_files->ConvertToFatArch(object_files)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,108 @@ pacman --noconfirm -S pkg-config
|
||||
|
||||
PKG_CONFIG_PATH="/mingw64/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
|
||||
./configure --toolchain=msvc --disable-programs --disable-doc --disable-everything --enable-protocol=file --enable-libopus --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=aasc --enable-decoder=flac --enable-decoder=gif --enable-decoder=h264 --enable-decoder=mp1 --enable-decoder=mp1float --enable-decoder=mp2 --enable-decoder=mp2float --enable-decoder=mp3 --enable-decoder=mp3adu --enable-decoder=mp3adufloat --enable-decoder=mp3float --enable-decoder=mp3on4 --enable-decoder=mp3on4float --enable-decoder=mpeg4 --enable-decoder=msmpeg4v2 --enable-decoder=msmpeg4v3 --enable-decoder=wavpack --enable-decoder=opus --enable-decoder=pcm_alaw --enable-decoder=pcm_alaw_at --enable-decoder=pcm_f32be --enable-decoder=pcm_f32le --enable-decoder=pcm_f64be --enable-decoder=pcm_f64le --enable-decoder=pcm_lxf --enable-decoder=pcm_mulaw --enable-decoder=pcm_mulaw_at --enable-decoder=pcm_s16be --enable-decoder=pcm_s16be_planar --enable-decoder=pcm_s16le --enable-decoder=pcm_s16le_planar --enable-decoder=pcm_s24be --enable-decoder=pcm_s24daud --enable-decoder=pcm_s24le --enable-decoder=pcm_s24le_planar --enable-decoder=pcm_s32be --enable-decoder=pcm_s32le --enable-decoder=pcm_s32le_planar --enable-decoder=pcm_s64be --enable-decoder=pcm_s64le --enable-decoder=pcm_s8 --enable-decoder=pcm_s8_planar --enable-decoder=pcm_u16be --enable-decoder=pcm_u16le --enable-decoder=pcm_u24be --enable-decoder=pcm_u24le --enable-decoder=pcm_u32be --enable-decoder=pcm_u32le --enable-decoder=pcm_u8 --enable-decoder=pcm_zork --enable-decoder=vorbis --enable-decoder=wmalossless --enable-decoder=wmapro --enable-decoder=wmav1 --enable-decoder=wmav2 --enable-decoder=wmavoice --enable-encoder=libopus --enable-hwaccel=h264_d3d11va --enable-hwaccel=h264_dxva2 --enable-parser=aac --enable-parser=aac_latm --enable-parser=flac --enable-parser=h264 --enable-parser=mpeg4video --enable-parser=mpegaudio --enable-parser=opus --enable-parser=vorbis --enable-demuxer=aac --enable-demuxer=flac --enable-demuxer=gif --enable-demuxer=h264 --enable-demuxer=mov --enable-demuxer=mp3 --enable-demuxer=ogg --enable-demuxer=wav --enable-muxer=ogg --enable-muxer=opus --extra-ldflags="-libpath:$FullExecPath/../opus/win32/VS2015/Win32/Release"
|
||||
./configure --toolchain=msvc \
|
||||
--extra-ldflags="-libpath:$FullExecPath/../opus/win32/VS2015/Win32/Release" \
|
||||
--disable-programs \
|
||||
--disable-doc \
|
||||
--disable-network \
|
||||
--disable-everything \
|
||||
--enable-hwaccel=h264_d3d11va \
|
||||
--enable-hwaccel=h264_d3d11va2 \
|
||||
--enable-hwaccel=h264_dxva2 \
|
||||
--enable-hwaccel=hevc_d3d11va \
|
||||
--enable-hwaccel=hevc_d3d11va2 \
|
||||
--enable-hwaccel=hevc_dxva2 \
|
||||
--enable-hwaccel=mpeg2_d3d11va \
|
||||
--enable-hwaccel=mpeg2_d3d11va2 \
|
||||
--enable-hwaccel=mpeg2_dxva2 \
|
||||
--enable-protocol=file --enable-libopus \
|
||||
--enable-decoder=aac \
|
||||
--enable-decoder=aac_at \
|
||||
--enable-decoder=aac_fixed \
|
||||
--enable-decoder=aac_latm \
|
||||
--enable-decoder=aasc \
|
||||
--enable-decoder=alac \
|
||||
--enable-decoder=alac_at \
|
||||
--enable-decoder=flac \
|
||||
--enable-decoder=gif \
|
||||
--enable-decoder=h264 \
|
||||
--enable-decoder=hevc \
|
||||
--enable-decoder=mp1 \
|
||||
--enable-decoder=mp1float \
|
||||
--enable-decoder=mp2 \
|
||||
--enable-decoder=mp2float \
|
||||
--enable-decoder=mp3 \
|
||||
--enable-decoder=mp3adu \
|
||||
--enable-decoder=mp3adufloat \
|
||||
--enable-decoder=mp3float \
|
||||
--enable-decoder=mp3on4 \
|
||||
--enable-decoder=mp3on4float \
|
||||
--enable-decoder=mpeg4 \
|
||||
--enable-decoder=msmpeg4v2 \
|
||||
--enable-decoder=msmpeg4v3 \
|
||||
--enable-decoder=opus \
|
||||
--enable-decoder=pcm_alaw \
|
||||
--enable-decoder=pcm_alaw_at \
|
||||
--enable-decoder=pcm_f32be \
|
||||
--enable-decoder=pcm_f32le \
|
||||
--enable-decoder=pcm_f64be \
|
||||
--enable-decoder=pcm_f64le \
|
||||
--enable-decoder=pcm_lxf \
|
||||
--enable-decoder=pcm_mulaw \
|
||||
--enable-decoder=pcm_mulaw_at \
|
||||
--enable-decoder=pcm_s16be \
|
||||
--enable-decoder=pcm_s16be_planar \
|
||||
--enable-decoder=pcm_s16le \
|
||||
--enable-decoder=pcm_s16le_planar \
|
||||
--enable-decoder=pcm_s24be \
|
||||
--enable-decoder=pcm_s24daud \
|
||||
--enable-decoder=pcm_s24le \
|
||||
--enable-decoder=pcm_s24le_planar \
|
||||
--enable-decoder=pcm_s32be \
|
||||
--enable-decoder=pcm_s32le \
|
||||
--enable-decoder=pcm_s32le_planar \
|
||||
--enable-decoder=pcm_s64be \
|
||||
--enable-decoder=pcm_s64le \
|
||||
--enable-decoder=pcm_s8 \
|
||||
--enable-decoder=pcm_s8_planar \
|
||||
--enable-decoder=pcm_u16be \
|
||||
--enable-decoder=pcm_u16le \
|
||||
--enable-decoder=pcm_u24be \
|
||||
--enable-decoder=pcm_u24le \
|
||||
--enable-decoder=pcm_u32be \
|
||||
--enable-decoder=pcm_u32le \
|
||||
--enable-decoder=pcm_u8 \
|
||||
--enable-decoder=pcm_zork \
|
||||
--enable-decoder=vorbis \
|
||||
--enable-decoder=wavpack \
|
||||
--enable-decoder=wmalossless \
|
||||
--enable-decoder=wmapro \
|
||||
--enable-decoder=wmav1 \
|
||||
--enable-decoder=wmav2 \
|
||||
--enable-decoder=wmavoice \
|
||||
--enable-encoder=libopus \
|
||||
--enable-parser=aac \
|
||||
--enable-parser=aac_latm \
|
||||
--enable-parser=flac \
|
||||
--enable-parser=h264 \
|
||||
--enable-parser=hevc \
|
||||
--enable-parser=mpeg4video \
|
||||
--enable-parser=mpegaudio \
|
||||
--enable-parser=opus \
|
||||
--enable-parser=vorbis \
|
||||
--enable-demuxer=aac \
|
||||
--enable-demuxer=flac \
|
||||
--enable-demuxer=gif \
|
||||
--enable-demuxer=h264 \
|
||||
--enable-demuxer=hevc \
|
||||
--enable-demuxer=m4v \
|
||||
--enable-demuxer=mov \
|
||||
--enable-demuxer=mp3 \
|
||||
--enable-demuxer=ogg \
|
||||
--enable-demuxer=wav \
|
||||
--enable-muxer=ogg \
|
||||
--enable-muxer=opus
|
||||
|
||||
make -j4
|
||||
make -j4 install
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
diff --git a/build/common.gypi b/build/common.gypi
|
||||
index 1affc70..c0d2f6a 100644
|
||||
index 1affc70..0677e4b 100644
|
||||
--- a/build/common.gypi
|
||||
+++ b/build/common.gypi
|
||||
@@ -66,6 +66,11 @@
|
||||
@@ -66,6 +66,13 @@
|
||||
'conditions': [
|
||||
['clang!=0', {
|
||||
'CLANG_CXX_LANGUAGE_STANDARD': 'c++11', # -std=c++11
|
||||
@@ -10,11 +10,13 @@ index 1affc70..c0d2f6a 100644
|
||||
+ 'OTHER_LDFLAGS': [
|
||||
+ '/usr/local/macold/lib/libc++.a',
|
||||
+ '/usr/local/macold/lib/libc++abi.a',
|
||||
+ '-isysroot/',
|
||||
+ '-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/',
|
||||
+ ],
|
||||
|
||||
# Don't link in libarclite_macosx.a, see http://crbug.com/156530.
|
||||
'CLANG_LINK_OBJC_RUNTIME': 'NO', # -fno-objc-link-runtime
|
||||
@@ -116,6 +121,9 @@
|
||||
@@ -116,6 +123,9 @@
|
||||
],
|
||||
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/configure b/configure
|
||||
index cb8d78fd3cb..cadb3f0a880 100755
|
||||
index cb8d78fd3c..cadb3f0a88 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -511,7 +511,8 @@ if [ "$BUILD_ON_MAC" = "yes" ]; then
|
||||
@@ -13,7 +13,7 @@ index cb8d78fd3cb..cadb3f0a880 100755
|
||||
echo " Xcode not set up properly. You may need to confirm the license" >&2
|
||||
echo " agreement by running /usr/bin/xcodebuild without arguments." >&2
|
||||
diff --git a/mkspecs/common/g++-macx.conf b/mkspecs/common/g++-macx.conf
|
||||
index 086510dd963..c485967863d 100644
|
||||
index 086510dd96..078a5ed1dd 100644
|
||||
--- a/mkspecs/common/g++-macx.conf
|
||||
+++ b/mkspecs/common/g++-macx.conf
|
||||
@@ -14,7 +14,13 @@ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -gdwarf-2
|
||||
@@ -27,12 +27,12 @@ index 086510dd963..c485967863d 100644
|
||||
+# Patch: Use C++14 with custom libc++ build.
|
||||
+QMAKE_CXXFLAGS_CXX11 = -std=c++1y
|
||||
+QMAKE_CXXFLAGS += -nostdinc++ -I/usr/local/macold/include/c++/v1
|
||||
+QMAKE_LFLAGS += /usr/local/macold/lib/libc++.a /usr/local/macold/lib/libc++abi.a
|
||||
+QMAKE_LFLAGS += /usr/local/macold/lib/libc++.a /usr/local/macold/lib/libc++abi.a -isysroot /
|
||||
|
||||
QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvmgcc42
|
||||
|
||||
diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf
|
||||
index 0cc8cd6dfdd..ca9725b7791 100644
|
||||
index 0cc8cd6dfd..ca9725b779 100644
|
||||
--- a/mkspecs/features/mac/default_pre.prf
|
||||
+++ b/mkspecs/features/mac/default_pre.prf
|
||||
@@ -12,7 +12,9 @@ isEmpty(QMAKE_XCODE_DEVELOPER_PATH) {
|
||||
@@ -47,7 +47,7 @@ index 0cc8cd6dfdd..ca9725b7791 100644
|
||||
}
|
||||
|
||||
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
|
||||
index bb79a139b3c..5d595bc3b34 100644
|
||||
index bb79a139b3..5d595bc3b3 100644
|
||||
--- a/src/gui/image/qbmphandler.cpp
|
||||
+++ b/src/gui/image/qbmphandler.cpp
|
||||
@@ -220,6 +220,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
|
||||
@@ -74,7 +74,7 @@ index bb79a139b3c..5d595bc3b34 100644
|
||||
if (ncols > 0) { // read color table
|
||||
uchar rgb[4];
|
||||
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
|
||||
index ebff9509ab2..4300ca4c0f0 100644
|
||||
index ebff9509ab..4300ca4c0f 100644
|
||||
--- a/src/gui/painting/qpaintengine_p.h
|
||||
+++ b/src/gui/painting/qpaintengine_p.h
|
||||
@@ -87,8 +87,18 @@ public:
|
||||
@@ -98,7 +98,7 @@ index ebff9509ab2..4300ca4c0f0 100644
|
||||
|
||||
// Make sure we're inside the viewport.
|
||||
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
|
||||
index 4879ae51d7d..56cdcbaf01c 100644
|
||||
index 4879ae51d7..56cdcbaf01 100644
|
||||
--- a/src/gui/text/qtextlayout.cpp
|
||||
+++ b/src/gui/text/qtextlayout.cpp
|
||||
@@ -654,6 +654,9 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
|
||||
@@ -175,7 +175,7 @@ index 4879ae51d7d..56cdcbaf01c 100644
|
||||
|
||||
inline void resetRightBearing()
|
||||
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
|
||||
index cbe42c38444..b273db7e78c 100644
|
||||
index cbe42c3844..b273db7e78 100644
|
||||
--- a/src/gui/text/qtextlayout.h
|
||||
+++ b/src/gui/text/qtextlayout.h
|
||||
@@ -194,6 +194,9 @@ private:
|
||||
@@ -189,7 +189,7 @@ index cbe42c38444..b273db7e78c 100644
|
||||
|
||||
|
||||
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
|
||||
index 360f9722c70..f28f289ef6a 100644
|
||||
index 360f9722c7..f28f289ef6 100644
|
||||
--- a/src/network/access/qhttpnetworkconnection.cpp
|
||||
+++ b/src/network/access/qhttpnetworkconnection.cpp
|
||||
@@ -118,6 +118,8 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
|
||||
@@ -202,7 +202,7 @@ index 360f9722c70..f28f289ef6a 100644
|
||||
delete channels[i].socket;
|
||||
}
|
||||
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
index ca7afb7d1b9..25ae50008db 100644
|
||||
index ca7afb7d1b..25ae50008d 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
@@ -256,6 +256,13 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
|
||||
@@ -220,7 +220,7 @@ index ca7afb7d1b9..25ae50008db 100644
|
||||
fd->weight = QFont::Normal;
|
||||
fd->style = QFont::StyleNormal;
|
||||
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
index 6e2c8a2a9af..3cace8abcbc 100644
|
||||
index 6e2c8a2a9a..3cace8abcb 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
@@ -717,7 +717,8 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metric
|
||||
@@ -234,7 +234,7 @@ index 6e2c8a2a9af..3cace8abcbc 100644
|
||||
|
||||
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
index 92358ecc745..694fee73507 100644
|
||||
index 92358ecc74..694fee7350 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
@@ -213,7 +213,8 @@ static void cleanupCocoaApplicationDelegate()
|
||||
@@ -271,7 +271,7 @@ index 92358ecc745..694fee73507 100644
|
||||
|
||||
- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
|
||||
index b81b9a0b1c2..4e59e833b1d 100644
|
||||
index b81b9a0b1c..4e59e833b1 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
|
||||
@@ -81,7 +81,7 @@ void QCocoaCursor::setPos(const QPoint &position)
|
||||
@@ -284,7 +284,7 @@ index b81b9a0b1c2..4e59e833b1d 100644
|
||||
CFRelease(e);
|
||||
}
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
|
||||
index 9850f83dea8..b2e1d3dfda7 100644
|
||||
index 9850f83dea..b2e1d3dfda 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
|
||||
@@ -649,9 +649,10 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm
|
||||
@@ -317,7 +317,7 @@ index 9850f83dea8..b2e1d3dfda7 100644
|
||||
}
|
||||
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
|
||||
index 9fd05a65ee9..dea60720e78 100644
|
||||
index 9fd05a65ee..dea60720e7 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
|
||||
@@ -402,14 +402,24 @@ void QCocoaIntegration::updateScreens()
|
||||
@@ -348,7 +348,7 @@ index 9fd05a65ee9..dea60720e78 100644
|
||||
|
||||
QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
|
||||
index e46eaff6be3..c62db534a2d 100644
|
||||
index e46eaff6be..c62db534a2 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
|
||||
@@ -382,6 +382,12 @@ bool QCocoaKeyMapper::updateKeyboard()
|
||||
@@ -375,7 +375,7 @@ index e46eaff6be3..c62db534a2d 100644
|
||||
}
|
||||
return ret;
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
index 83c960d9317..03ae9696afe 100755
|
||||
index 83c960d931..03ae9696af 100755
|
||||
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
@@ -102,7 +102,10 @@ QT_USE_NAMESPACE
|
||||
@@ -543,7 +543,7 @@ index 83c960d9317..03ae9696afe 100755
|
||||
}
|
||||
@end
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
index 4d0458a4aa2..3357a5ef817 100644
|
||||
index 4d0458a4aa..3357a5ef81 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
@@ -167,7 +167,8 @@ static bool isMouseEvent(NSEvent *ev)
|
||||
@@ -606,7 +606,7 @@ index 4d0458a4aa2..3357a5ef817 100644
|
||||
[iconButton setImage:image];
|
||||
[image release];
|
||||
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
|
||||
index a18ee7ff71d..1f91feb0ae8 100644
|
||||
index a18ee7ff71..1f91feb0ae 100644
|
||||
--- a/src/plugins/platforms/cocoa/qnsview.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qnsview.mm
|
||||
@@ -393,7 +393,9 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
||||
@@ -675,7 +675,7 @@ index a18ee7ff71d..1f91feb0ae8 100644
|
||||
}
|
||||
return [super performKeyEquivalent:nsevent];
|
||||
diff --git a/src/tools/qlalr/lalr.cpp b/src/tools/qlalr/lalr.cpp
|
||||
index c68076477f3..e2a7aafa586 100644
|
||||
index c68076477f..e2a7aafa58 100644
|
||||
--- a/src/tools/qlalr/lalr.cpp
|
||||
+++ b/src/tools/qlalr/lalr.cpp
|
||||
@@ -246,11 +246,13 @@ void Grammar::buildExtendedGrammar ()
|
||||
@@ -715,7 +715,7 @@ index c68076477f3..e2a7aafa586 100644
|
||||
continue;
|
||||
|
||||
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
|
||||
index 7396808442e..7178aecf800 100644
|
||||
index 7396808442..7178aecf80 100644
|
||||
--- a/src/widgets/kernel/qwidget.cpp
|
||||
+++ b/src/widgets/kernel/qwidget.cpp
|
||||
@@ -4722,6 +4722,17 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
|
||||
@@ -768,7 +768,7 @@ index 7396808442e..7178aecf800 100644
|
||||
|| (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
|
||||
res = focusNextPrevChild(false);
|
||||
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
|
||||
index 0845a5eb02f..5735cb6b396 100644
|
||||
index 0845a5eb02..5735cb6b39 100644
|
||||
--- a/src/widgets/styles/qmacstyle_mac.mm
|
||||
+++ b/src/widgets/styles/qmacstyle_mac.mm
|
||||
@@ -3667,9 +3667,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
@@ -786,7 +786,7 @@ index 0845a5eb02f..5735cb6b396 100644
|
||||
}
|
||||
|
||||
diff --git a/src/widgets/util/qsystemtrayicon_qpa.cpp b/src/widgets/util/qsystemtrayicon_qpa.cpp
|
||||
index f98aeaf6782..00c0734129e 100644
|
||||
index f98aeaf678..00c0734129 100644
|
||||
--- a/src/widgets/util/qsystemtrayicon_qpa.cpp
|
||||
+++ b/src/widgets/util/qsystemtrayicon_qpa.cpp
|
||||
@@ -99,13 +99,18 @@ void QSystemTrayIconPrivate::updateIcon_sys()
|
||||
@@ -815,7 +815,7 @@ index f98aeaf6782..00c0734129e 100644
|
||||
}
|
||||
|
||||
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
index 75f30599be4..980f2be1e93 100644
|
||||
index 75f30599be..980f2be1e9 100644
|
||||
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
@@ -1867,7 +1867,8 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
|
||||
@@ -829,7 +829,7 @@ index 75f30599be4..980f2be1e93 100644
|
||||
#ifndef QT_NO_COMPLETER
|
||||
complete(event->key());
|
||||
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
index 96438a0bdf7..b0b72064056 100644
|
||||
index 96438a0bdf..b0b7206405 100644
|
||||
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
@@ -1342,7 +1342,8 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
|
||||
|
||||
@@ -450,7 +450,7 @@ index 8ebabf3419..7bb8abd0d0 100644
|
||||
}
|
||||
populateFromPattern(pattern);
|
||||
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
index 566abf2126..5b9c714ffa 100644
|
||||
index 566abf2126..5c5fde9813 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
@@ -265,6 +265,13 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
|
||||
@@ -467,6 +467,20 @@ index 566abf2126..5b9c714ffa 100644
|
||||
fd->styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
|
||||
fd->weight = QFont::Normal;
|
||||
fd->style = QFont::StyleNormal;
|
||||
@@ -300,9 +307,10 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
|
||||
|
||||
if (styles) {
|
||||
if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
|
||||
- float normalizedWeight;
|
||||
- if (CFNumberGetValue(weightValue, kCFNumberFloatType, &normalizedWeight))
|
||||
- fd->weight = QCoreTextFontEngine::qtWeightFromCFWeight(normalizedWeight);
|
||||
+ // Patch: backport bugfix from 'b64ea4a3ab' commit.
|
||||
+ double normalizedWeight;
|
||||
+ if (CFNumberGetValue(weightValue, kCFNumberFloat64Type, &normalizedWeight))
|
||||
+ fd->weight = QCoreTextFontEngine::qtWeightFromCFWeight(float(normalizedWeight));
|
||||
}
|
||||
if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
|
||||
double d;
|
||||
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
index 7b459584ea..2ed2fd9b3b 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
@@ -513,7 +527,7 @@ index d1bea9af23..36a15a6473 100644
|
||||
event.setCommitString(QChar(character));
|
||||
QCoreApplication::sendEvent(m_focusObject, &event);
|
||||
diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro
|
||||
index faea54b874..0f9650996e 100644
|
||||
index faea54b874..fe4a837511 100644
|
||||
--- a/src/plugins/platforminputcontexts/platforminputcontexts.pro
|
||||
+++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro
|
||||
@@ -1,7 +1,8 @@
|
||||
@@ -521,8 +535,8 @@ index faea54b874..0f9650996e 100644
|
||||
|
||||
qtHaveModule(dbus) {
|
||||
-!mac:!win32:SUBDIRS += ibus
|
||||
+# Patch: Adding fcitx/hime input context plugin to our static build.
|
||||
+!mac:!win32:SUBDIRS += ibus fcitx hime
|
||||
+# Patch: Adding fcitx/hime/nimf input context plugin to our static build.
|
||||
+!mac:!win32:SUBDIRS += ibus fcitx hime nimf
|
||||
}
|
||||
|
||||
contains(QT_CONFIG, xcb-plugin): SUBDIRS += compose
|
||||
@@ -869,7 +883,7 @@ index c0d5904367..f3c2047196 100644
|
||||
[iconButton setImage:image];
|
||||
[image release];
|
||||
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
|
||||
index c67bcfd23b..2616f420cb 100644
|
||||
index c67bcfd23b..6a60670aee 100644
|
||||
--- a/src/plugins/platforms/cocoa/qnsview.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qnsview.mm
|
||||
@@ -647,6 +647,12 @@ QT_WARNING_POP
|
||||
@@ -943,6 +957,17 @@ index c67bcfd23b..2616f420cb 100644
|
||||
- (void)cancelOperation:(id)sender
|
||||
{
|
||||
Q_UNUSED(sender);
|
||||
@@ -1981,6 +2006,10 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
|
||||
// change the cursor
|
||||
[nativeCursor set];
|
||||
|
||||
+ // Patch: Backport a fix from cd08753d3e. Starting with macOS Mojave this requires accessibility access.
|
||||
+ if (QSysInfo::macVersion() >= Q_MV_OSX(10, 14))
|
||||
+ return;
|
||||
+
|
||||
// Make sure the cursor is updated correctly if the mouse does not move and window is under cursor
|
||||
// by creating a fake move event
|
||||
if (m_updatingDrag)
|
||||
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
|
||||
index 94bb71e429..16ab51e166 100644
|
||||
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
|
||||
|
||||
@@ -92,7 +92,7 @@ msgServiceFont: semiboldFont;
|
||||
msgServiceNameFont: semiboldFont;
|
||||
msgServicePhotoWidth: 100px;
|
||||
msgDateFont: font(13px);
|
||||
msgMinWidth: 190px;
|
||||
msgMinWidth: 160px;
|
||||
msgPhotoSize: 33px;
|
||||
msgPhotoSkip: 40px;
|
||||
msgPadding: margins(13px, 7px, 13px, 8px);
|
||||
@@ -243,12 +243,6 @@ dragPadding: margins(20px, 10px, 20px, 10px);
|
||||
|
||||
dragHeight: 72px;
|
||||
|
||||
minPhotoSize: 100px;
|
||||
maxMediaSize: 430px;
|
||||
maxStickerSize: 256px;
|
||||
maxGifSize: 320px;
|
||||
maxSignatureSize: 144px;
|
||||
|
||||
radialSize: size(50px, 50px);
|
||||
radialLine: 3px;
|
||||
radialDuration: 350;
|
||||
@@ -264,19 +258,6 @@ videoIcon: icon {
|
||||
};
|
||||
locationSize: size(320px, 240px);
|
||||
|
||||
webPageLeft: 10px;
|
||||
webPageBar: 2px;
|
||||
webPageTitleFont: semiboldFont;
|
||||
webPageTitleStyle: semiboldTextStyle;
|
||||
webPageTitleOutFg: historyTextOutFg;
|
||||
webPageTitleInFg: historyTextInFg;
|
||||
webPageDescriptionOutFg: historyTextOutFg;
|
||||
webPageDescriptionInFg: historyTextInFg;
|
||||
webPageDescriptionFont: normalFont;
|
||||
webPageDescriptionStyle: defaultTextStyle;
|
||||
webPagePhotoSize: 100px;
|
||||
webPagePhotoDelta: 8px;
|
||||
|
||||
mediaPlayerSuppressDuration: 150;
|
||||
|
||||
botDescSkip: 8px;
|
||||
|
||||
14
Telegram/Resources/default_shortcuts-custom.json
Normal file
@@ -0,0 +1,14 @@
|
||||
// This is a list of your own shortcuts for Telegram Desktop
|
||||
// You can see full list of commands in the 'shortcuts-default.json' file
|
||||
// Place a null value instead of a command string to switch the shortcut off
|
||||
|
||||
[
|
||||
// {
|
||||
// "command": "close_telegram",
|
||||
// "keys": "ctrl+f4"
|
||||
// },
|
||||
// {
|
||||
// "command": "quit_telegram",
|
||||
// "keys": "ctrl+q"
|
||||
// }
|
||||
]
|
||||
BIN
Telegram/Resources/emoji/set0_preview.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
Telegram/Resources/emoji/set1_preview.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Telegram/Resources/emoji/set2_preview.webp
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
Telegram/Resources/emoji/set3_preview.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
@@ -311,7 +311,8 @@ div.selected {
|
||||
background-position: 12px 12px;
|
||||
background-size: 24px 24px;
|
||||
}
|
||||
.default .media .title {
|
||||
.default .media .title,
|
||||
.default .media_poll .question {
|
||||
padding-top: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
57
Telegram/Resources/fc-custom.conf
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version='1.0'?>
|
||||
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
||||
<fontconfig>
|
||||
<dir>/usr/share/fonts</dir>
|
||||
<dir>/usr/local/share/fonts</dir>
|
||||
<dir>~/.fonts</dir>
|
||||
<dir>~/.local/share/fonts</dir>
|
||||
<dir>/usr/X11R6/lib/X11/fonts</dir>
|
||||
<dir prefix="xdg">fonts</dir>
|
||||
<match target="pattern">
|
||||
<test qual="any" name="family">
|
||||
<string>mono</string>
|
||||
</test>
|
||||
<edit name="family" mode="assign" binding="same">
|
||||
<string>monospace</string>
|
||||
</edit>
|
||||
</match>
|
||||
<match target="pattern">
|
||||
<test qual="any" name="family">
|
||||
<string>sans serif</string>
|
||||
</test>
|
||||
<edit name="family" mode="assign" binding="same">
|
||||
<string>sans-serif</string>
|
||||
</edit>
|
||||
</match>
|
||||
<match target="pattern">
|
||||
<test qual="any" name="family">
|
||||
<string>sans</string>
|
||||
</test>
|
||||
<edit name="family" mode="assign" binding="same">
|
||||
<string>sans-serif</string>
|
||||
</edit>
|
||||
</match>
|
||||
<cachedir>/var/cache/fontconfig_11</cachedir>
|
||||
<cachedir prefix="xdg">fontconfig_11</cachedir>
|
||||
<cachedir>~/.fontconfig_11</cachedir>
|
||||
<match target="font">
|
||||
<edit mode="assign" name="antialias">
|
||||
<bool>true</bool>
|
||||
</edit>
|
||||
<edit mode="assign" name="embeddedbitmap">
|
||||
<bool>false</bool>
|
||||
</edit>
|
||||
<edit mode="assign" name="hinting">
|
||||
<bool>true</bool>
|
||||
</edit>
|
||||
<edit mode="assign" name="hintstyle">
|
||||
<const>hintslight</const>
|
||||
</edit>
|
||||
<edit mode="assign" name="lcdfilter">
|
||||
<const>lcddefault</const>
|
||||
</edit>
|
||||
<edit mode="assign" name="rgba">
|
||||
<const>rgb</const>
|
||||
</edit>
|
||||
</match>
|
||||
</fontconfig>
|
||||
BIN
Telegram/Resources/icons/dialogs_bot.png
Normal file
|
After Width: | Height: | Size: 277 B |
BIN
Telegram/Resources/icons/dialogs_bot@2x.png
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
Telegram/Resources/icons/dialogs_bot@3x.png
Normal file
|
After Width: | Height: | Size: 715 B |
BIN
Telegram/Resources/icons/history_audio_cancel.png
Normal file
|
After Width: | Height: | Size: 153 B |
BIN
Telegram/Resources/icons/history_audio_cancel@2x.png
Normal file
|
After Width: | Height: | Size: 251 B |
BIN
Telegram/Resources/icons/history_audio_cancel@3x.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
Telegram/Resources/icons/history_audio_download.png
Normal file
|
After Width: | Height: | Size: 160 B |
BIN
Telegram/Resources/icons/history_audio_download@2x.png
Normal file
|
After Width: | Height: | Size: 221 B |
BIN
Telegram/Resources/icons/history_audio_download@3x.png
Normal file
|
After Width: | Height: | Size: 453 B |
|
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 178 B |
|
Before Width: | Height: | Size: 419 B After Width: | Height: | Size: 383 B |
|
Before Width: | Height: | Size: 592 B After Width: | Height: | Size: 619 B |
BIN
Telegram/Resources/icons/info_permissions.png
Normal file
|
After Width: | Height: | Size: 672 B |
BIN
Telegram/Resources/icons/info_permissions@2x.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/Resources/icons/info_permissions@3x.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 354 B |
|
Before Width: | Height: | Size: 737 B |
|
Before Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/info_rights_lock.png
Normal file
|
After Width: | Height: | Size: 280 B |
BIN
Telegram/Resources/icons/info_rights_lock@2x.png
Normal file
|
After Width: | Height: | Size: 519 B |
BIN
Telegram/Resources/icons/info_rights_lock@3x.png
Normal file
|
After Width: | Height: | Size: 721 B |
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 177 B |
|
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 278 B |
|
Before Width: | Height: | Size: 285 B After Width: | Height: | Size: 417 B |
BIN
Telegram/Resources/icons/overview_video_download.png
Normal file
|
After Width: | Height: | Size: 156 B |
BIN
Telegram/Resources/icons/overview_video_download@2x.png
Normal file
|
After Width: | Height: | Size: 221 B |
BIN
Telegram/Resources/icons/overview_video_download@3x.png
Normal file
|
After Width: | Height: | Size: 438 B |
BIN
Telegram/Resources/icons/overview_video_play.png
Normal file
|
After Width: | Height: | Size: 175 B |
BIN
Telegram/Resources/icons/overview_video_play@2x.png
Normal file
|
After Width: | Height: | Size: 321 B |
BIN
Telegram/Resources/icons/overview_video_play@3x.png
Normal file
|
After Width: | Height: | Size: 422 B |
|
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 163 B |
|
Before Width: | Height: | Size: 197 B After Width: | Height: | Size: 351 B |
|
Before Width: | Height: | Size: 408 B After Width: | Height: | Size: 534 B |
BIN
Telegram/Resources/icons/settings_emoji.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/settings_emoji@2x.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
Telegram/Resources/icons/settings_emoji@3x.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
Telegram/Resources/icons/voice2x.png
Normal file
|
After Width: | Height: | Size: 479 B |
BIN
Telegram/Resources/icons/voice2x@2x.png
Normal file
|
After Width: | Height: | Size: 1015 B |
BIN
Telegram/Resources/icons/voice2x@3x.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
@@ -128,6 +128,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_gif_error" = "An error has occurred while reading GIF animation :(";
|
||||
"lng_edit_error" = "You cannot edit this message";
|
||||
"lng_join_channel_error" = "Sorry, you have joined too many channels and supergroups. Please leave some before joining this one.";
|
||||
"lng_migrate_error" = "This action will convert the group to a supergroup. Unfortunately, you are a member of too many supergroups and channels. Please leave some of the channels or groups you don't need before proceeding.";
|
||||
"lng_error_phone_flood" = "Sorry, you have deleted and re-created your account too many times recently. Please wait for a few days before signing up again.";
|
||||
"lng_error_start_minimized_passcoded" = "You have set a local passcode, so Telegram Desktop can't be launched minimised; it will ask you to enter your passcode before it can start working.";
|
||||
"lng_error_pinned_max#one" = "Sorry, you can pin no more than {count} chat to the top.";
|
||||
@@ -142,9 +143,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_error_admin_limit_channel" = "Sorry, you've reached the maximum number of admins for this channel.";
|
||||
"lng_sure_add_admin_invite" = "This user is not a member of this group. Add them to the group and promote them to admin?";
|
||||
"lng_sure_add_admin_invite_channel" = "This user is not a subscriber of this channel. Add them to the channel and promote them to admin?";
|
||||
"lng_sure_add_admin_unban" = "This user is currently restricted or banned. Are you sure you want to unban and promote them?";
|
||||
"lng_sure_add_admin_unremove" = "This user is currently restricted or removed. Are you sure you want to promote them?";
|
||||
"lng_sure_ban_admin" = "This user is an admin. Are you sure you want to go ahead and restrict them?";
|
||||
"lng_sure_ban_user_group" = "Ban {user} in the group?";
|
||||
"lng_sure_enable_socks" = "Are you sure you want to enable this proxy?\n\nServer: {server}\nPort: {port}\n\nYou can change your proxy server later in the Settings (Connection Type).";
|
||||
"lng_sure_enable" = "Enable";
|
||||
|
||||
@@ -155,6 +155,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_deleted" = "Deleted Account";
|
||||
"lng_deleted_message" = "Deleted message";
|
||||
"lng_pinned_message" = "Pinned message";
|
||||
"lng_pinned_poll" = "Pinned poll";
|
||||
"lng_pinned_unpin_sure" = "Would you like to unpin this message?";
|
||||
"lng_pinned_pin_sure" = "Would you like to pin this message?";
|
||||
"lng_pinned_pin" = "Pin";
|
||||
@@ -273,15 +274,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_empty_bio" = "None";
|
||||
|
||||
"lng_settings_section_notify" = "Notifications";
|
||||
"lng_settings_notify_title" = "Notifications for chats";
|
||||
"lng_settings_desktop_notify" = "Desktop notifications";
|
||||
"lng_settings_show_name" = "Show sender's name";
|
||||
"lng_settings_show_preview" = "Show message preview";
|
||||
"lng_settings_native_title" = "Native notifications";
|
||||
"lng_settings_use_windows" = "Use Windows notifications";
|
||||
"lng_settings_use_native_notifications" = "Use native notifications";
|
||||
"lng_settings_notifications_position" = "Location on the screen";
|
||||
"lng_settings_notifications_count" = "Notifications count";
|
||||
"lng_settings_sound_notify" = "Play sound";
|
||||
"lng_settings_badge_title" = "Badge counter";
|
||||
"lng_settings_include_muted" = "Include muted chats in unread count";
|
||||
"lng_settings_count_unread" = "Count unread messages";
|
||||
"lng_settings_events_title" = "Events";
|
||||
"lng_settings_events_joined" = "Contact joined Telegram";
|
||||
|
||||
"lng_notification_preview" = "You have a new message";
|
||||
"lng_notification_reply" = "Reply";
|
||||
@@ -328,6 +335,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_bg_tile" = "Tile background";
|
||||
"lng_settings_adaptive_wide" = "Adaptive layout for wide screens";
|
||||
|
||||
"lng_settings_section_call_settings" = "Calls Settings";
|
||||
"lng_settings_call_section_output" = "Speakers and headphones";
|
||||
"lng_settings_call_section_input" = "Microphone";
|
||||
"lng_settings_call_input_device" = "Input device";
|
||||
"lng_settings_call_output_device" = "Output device";
|
||||
"lng_settings_call_input_volume" = "Input volume: {percent}%";
|
||||
"lng_settings_call_output_volume" = "Output volume: {percent}%";
|
||||
"lng_settings_call_test_mic" = "Test microphone";
|
||||
"lng_settings_call_stop_mic_test" = "Stop test";
|
||||
"lng_settings_call_section_other" = "Other settings";
|
||||
"lng_settings_call_open_system_prefs" = "Open system sound preferences";
|
||||
"lng_settings_call_device_default" = "Default";
|
||||
"lng_settings_call_audio_ducking" = "Mute other sounds during calls";
|
||||
|
||||
"lng_settings_language" = "Language";
|
||||
"lng_settings_default_scale" = "Default interface scale";
|
||||
"lng_settings_connection_type" = "Connection type";
|
||||
@@ -335,18 +356,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_privacy_title" = "Privacy";
|
||||
"lng_settings_last_seen" = "Last seen";
|
||||
"lng_settings_calls" = "Voice calls";
|
||||
"lng_settings_calls_peer_to_peer" = "Peer-to-peer in calls";
|
||||
"lng_settings_groups_invite" = "Groups";
|
||||
"lng_settings_group_privacy_about" = "Change who can add you to groups and channels.";
|
||||
"lng_settings_forwards_privacy" = "Forwarded messages";
|
||||
"lng_settings_profile_photo_privacy" = "Profile photo";
|
||||
"lng_settings_sessions_about" = "Control your sessions on other devices.";
|
||||
"lng_settings_passcode_disable" = "Disable passcode";
|
||||
"lng_settings_password_disable" = "Disable cloud password";
|
||||
"lng_settings_password_abort" = "Abort two-step verification setup";
|
||||
"lng_settings_password_reenter_email" = "Re-enter recovery email";
|
||||
"lng_settings_about_bio" = "Any details such as age, occupation or city.\nExample: 23 y.o. designer from San Francisco";
|
||||
"lng_settings_name_label" = "Name";
|
||||
"lng_settings_username_label" = "Username";
|
||||
"lng_settings_phone_label" = "Phone number";
|
||||
"lng_settings_username_add" = "Add username";
|
||||
"lng_settings_close_sure" = "Are you sure you want to close this page? You didn't save your changes.";
|
||||
"lng_settings_peer_to_peer" = "Peer-to-Peer";
|
||||
//"lng_settings_peer_to_peer" = "Peer-to-Peer";
|
||||
"lng_settings_peer_to_peer_about" = "Disabling peer-to-peer will relay all calls through Telegram servers to avoid revealing your IP address, but may slightly decrease audio quality.";
|
||||
"lng_settings_advanced" = "Advanced";
|
||||
"lng_settings_stickers_emoji" = "Stickers and emoji";
|
||||
@@ -371,6 +397,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_theme_reverting#other" = "Reverting to the old theme in {count} seconds.";
|
||||
"lng_theme_keep_changes" = "Keep changes";
|
||||
"lng_theme_revert" = "Revert";
|
||||
"lng_background_header" = "Background preview";
|
||||
"lng_background_text1" = "Ah, you kids today with techno music! You should enjoy the classics, like Hasselhoff!";
|
||||
"lng_background_text2" = "I can't even take you seriously right now.";
|
||||
"lng_background_bad_link" = "This background link appears to be invalid.";
|
||||
"lng_background_apply" = "Apply";
|
||||
"lng_background_share" = "Share";
|
||||
"lng_background_link_copied" = "Link copied to clipboard";
|
||||
"lng_background_blur" = "Blurred";
|
||||
"lng_background_sure_delete" = "Are you sure you want to delete this background?";
|
||||
|
||||
"lng_download_path_ask" = "Ask download path for each file";
|
||||
"lng_download_path" = "Download path";
|
||||
@@ -403,7 +438,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_local_storage_round#other" = "{count} video messages";
|
||||
"lng_local_storage_animation#one" = "{count} animation";
|
||||
"lng_local_storage_animation#other" = "{count} animations";
|
||||
"lng_local_storage_media" = "Media cache";
|
||||
"lng_local_storage_size_limit" = "Total size limit: {size}";
|
||||
"lng_local_storage_media_limit" = "Media cache limit: {size}";
|
||||
"lng_local_storage_time_limit" = "Clear files older than: {limit}";
|
||||
"lng_local_storage_limit_weeks#one" = "{count} week";
|
||||
"lng_local_storage_limit_weeks#other" = "{count} weeks";
|
||||
@@ -447,7 +484,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_passcode_logout" = "Log out";
|
||||
"lng_passcode_need_unblock" = "You need to unlock me first.";
|
||||
|
||||
"lng_cloud_password_waiting" = "Confirmation link sent to {email}...";
|
||||
"lng_cloud_password_waiting_code" = "Confirmation code sent to {email}...";
|
||||
"lng_cloud_password_confirm" = "Confirm recovery email";
|
||||
"lng_cloud_password_change" = "Change cloud password";
|
||||
"lng_cloud_password_create" = "Cloud password";
|
||||
"lng_cloud_password_remove" = "Remove cloud password";
|
||||
@@ -473,6 +511,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_cloud_password_wrong" = "Wrong cloud password";
|
||||
"lng_cloud_password_is_same" = "Password was not changed";
|
||||
"lng_cloud_password_passport_losing" = "Warning! All data saved in your Telegram Passport will be lost!";
|
||||
"lng_cloud_password_resend" = "Resend code";
|
||||
"lng_cloud_password_resent" = "Code was resent.";
|
||||
|
||||
"lng_connection_auto_connecting" = "Default (connecting...)";
|
||||
"lng_connection_auto" = "Default ({transport} used)";
|
||||
@@ -491,7 +531,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_connection_save" = "Save";
|
||||
|
||||
"lng_proxy_settings" = "Proxy settings";
|
||||
"lng_proxy_use" = "Use proxy";
|
||||
"lng_proxy_disable" = "Disable proxy";
|
||||
"lng_proxy_use_system_settings" = "Use system proxy settings";
|
||||
"lng_proxy_use_custom" = "Use custom proxy";
|
||||
"lng_proxy_use_for_calls" = "Use proxy for calls";
|
||||
"lng_proxy_about" = "Proxy servers may be helpful in accessing Telegram if there is no connection in a specific region.";
|
||||
"lng_proxy_add" = "Add proxy";
|
||||
@@ -540,10 +582,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_sessions_other_header" = "Active sessions";
|
||||
"lng_sessions_other_desc" = "You can log in to Telegram from other mobile, tablet and desktop devices, using the same phone number. All your data will be instantly synchronized.";
|
||||
"lng_sessions_terminate_all" = "Terminate all other sessions";
|
||||
"lng_sessions_terminate_all_about" = "Logs out all devices except for this one.";
|
||||
"lng_sessions_incomplete" = "Incomplete login attempts";
|
||||
"lng_sessions_incomplete_about" = "The devices above have no access to your messages. The code was entered correctly, but no correct password was given.";
|
||||
|
||||
"lng_blocked_list_title" = "Blocked users";
|
||||
"lng_blocked_list_unknown_phone" = "unknown phone number";
|
||||
"lng_blocked_list_unblock" = "Unblock";
|
||||
"lng_blocked_list_restart" = "Restart";
|
||||
"lng_blocked_list_add" = "Block user";
|
||||
"lng_blocked_list_add_title" = "Select user to block";
|
||||
"lng_blocked_list_already_blocked" = "blocked already";
|
||||
@@ -555,14 +601,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_edit_privacy_nobody" = "Nobody";
|
||||
"lng_edit_privacy_exceptions" = "Add exceptions";
|
||||
|
||||
"lng_edit_privacy_exceptions_count#one" = "{count} user";
|
||||
"lng_edit_privacy_exceptions_count#other" = "{count} users";
|
||||
"lng_edit_privacy_exceptions_add" = "Add users";
|
||||
|
||||
"lng_edit_privacy_lastseen_title" = "Last seen privacy";
|
||||
"lng_edit_privacy_lastseen_header" = "Who can see your last seen time";
|
||||
"lng_edit_privacy_lastseen_warning" = "Important: you won't be able to see Last Seen times for people with whom you don't share your Last Seen time. Approximate last seen will be shown instead (recently, within a week, within a month).";
|
||||
"lng_edit_privacy_lastseen_always_empty" = "Always share with";
|
||||
"lng_edit_privacy_lastseen_never_empty" = "Never share with";
|
||||
"lng_edit_privacy_exceptions_count#one" = "{count} user";
|
||||
"lng_edit_privacy_exceptions_count#other" = "{count} users";
|
||||
"lng_edit_privacy_exceptions_add" = "Add users";
|
||||
"lng_edit_privacy_lastseen_exceptions" = "These settings will override the values above.";
|
||||
"lng_edit_privacy_lastseen_always_title" = "Always share with";
|
||||
"lng_edit_privacy_lastseen_never_title" = "Never share with";
|
||||
@@ -583,6 +630,39 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_edit_privacy_calls_always_title" = "Always allow";
|
||||
"lng_edit_privacy_calls_never_title" = "Never allow";
|
||||
|
||||
"lng_edit_privacy_calls_p2p_title" = "Peer-to-peer in calls";
|
||||
"lng_edit_privacy_calls_p2p_header" = "With who peer-to-peer is enabled?";
|
||||
"lng_edit_privacy_calls_p2p_always_empty" = "Always allow";
|
||||
"lng_edit_privacy_calls_p2p_never_empty" = "Never allow";
|
||||
"lng_edit_privacy_calls_p2p_exceptions" = "Peer-to-peer in calls will or will not be used with these users regardless of the settings above.";
|
||||
"lng_edit_privacy_calls_p2p_always_title" = "Always allow";
|
||||
"lng_edit_privacy_calls_p2p_never_title" = "Never allow";
|
||||
|
||||
"lng_edit_privacy_calls_p2p_everyone" = "Everybody";
|
||||
"lng_edit_privacy_calls_p2p_contacts" = "My contacts";
|
||||
"lng_edit_privacy_calls_p2p_nobody" = "Nobody";
|
||||
|
||||
"lng_edit_privacy_forwards_title" = "Forwarded messages privacy";
|
||||
"lng_edit_privacy_forwards_header" = "Who can add link to my account when forwarding my messages";
|
||||
"lng_edit_privacy_forwards_warning" = "When forwarded to other chats, messages you send will not link back to your account.";
|
||||
"lng_edit_privacy_forwards_always_empty" = "Always allow";
|
||||
"lng_edit_privacy_forwards_never_empty" = "Never allow";
|
||||
"lng_edit_privacy_forwards_exceptions" = "These settings will override the values above.";
|
||||
"lng_edit_privacy_forwards_always_title" = "Always allow";
|
||||
"lng_edit_privacy_forwards_never_title" = "Never allow";
|
||||
"lng_edit_privacy_forwards_sample_message" = "Reinhardt, we need to find you some new tunes 🎶";
|
||||
"lng_edit_privacy_forwards_sample_everyone" = "Link to your account.";
|
||||
"lng_edit_privacy_forwards_sample_contacts" = "Link if allowed by settings below.";
|
||||
"lng_edit_privacy_forwards_sample_nobody" = "Not a link to your account.";
|
||||
|
||||
"lng_edit_privacy_profile_photo_title" = "Profile photo privacy";
|
||||
"lng_edit_privacy_profile_photo_header" = "Who can see my profile photo";
|
||||
"lng_edit_privacy_profile_photo_always_empty" = "Always allow";
|
||||
"lng_edit_privacy_profile_photo_never_empty" = "Never allow";
|
||||
"lng_edit_privacy_profile_photo_exceptions" = "These settings will override the values above.";
|
||||
"lng_edit_privacy_profile_photo_always_title" = "Always allow";
|
||||
"lng_edit_privacy_profile_photo_never_title" = "Never allow";
|
||||
|
||||
"lng_self_destruct_title" = "Account self-destruction";
|
||||
"lng_self_destruct_description" = "If you don't come online at least once within this period, your account will be deleted along with all groups, messages and contacts.";
|
||||
"lng_self_destruct_months#one" = "{count} month";
|
||||
@@ -604,6 +684,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
"lng_mute_duration_hours#one" = "For {count} hour";
|
||||
"lng_mute_duration_hours#other" = "For {count} hours";
|
||||
"lng_mute_duration_days#one" = "For {count} day";
|
||||
"lng_mute_duration_days#other" = "For {count} days";
|
||||
"lng_mute_duration_forever" = "Forever";
|
||||
"lng_mute_box_tip" = "Choose for how long you would like to turn off notifications for the following chat";
|
||||
|
||||
"lng_preview_loading" = "Getting Link Info...";
|
||||
@@ -617,10 +700,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_profile_create_public_link" = "Create public link";
|
||||
"lng_profile_edit_public_link" = "Edit public link";
|
||||
"lng_profile_search_members" = "Search members";
|
||||
"lng_profile_manage_admins" = "Manage administrators";
|
||||
"lng_profile_manage_blocklist" = "Manage banned users";
|
||||
"lng_profile_manage_restrictedlist" = "Manage restricted users";
|
||||
"lng_profile_recent_actions" = "Recent actions";
|
||||
"lng_profile_common_groups#one" = "{count} group in common";
|
||||
"lng_profile_common_groups#other" = "{count} groups in common";
|
||||
"lng_profile_participants_section" = "Members";
|
||||
@@ -638,7 +717,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_profile_report" = "Report";
|
||||
"lng_profile_search_messages" = "Search for messages";
|
||||
"lng_profile_block_bot" = "Stop and block bot";
|
||||
"lng_profile_unblock_bot" = "Unblock bot";
|
||||
"lng_profile_restart_bot" = "Restart bot";
|
||||
"lng_profile_invite_to_group" = "Add to Group";
|
||||
"lng_profile_delete_contact" = "Delete";
|
||||
"lng_profile_set_group_photo" = "Set Photo";
|
||||
@@ -648,6 +727,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_profile_join_group" = "Join Group";
|
||||
"lng_profile_delete_and_exit" = "Leave";
|
||||
"lng_profile_kick" = "Remove";
|
||||
"lng_profile_delete_removed" = "Delete";
|
||||
"lng_profile_sure_kick" = "Remove {user} from the group?";
|
||||
"lng_profile_sure_kick_channel" = "Remove {user} from the channel?";
|
||||
"lng_profile_sure_remove_admin" = "Remove {user} from admins?";
|
||||
@@ -743,13 +823,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_manage_peer_recent_actions" = "Recent Actions";
|
||||
"lng_manage_peer_members" = "Members";
|
||||
"lng_manage_peer_administrators" = "Administrators";
|
||||
"lng_manage_peer_banned_users" = "Banned users";
|
||||
"lng_manage_peer_restricted_users" = "Restricted users";
|
||||
"lng_manage_peer_exceptions" = "Exceptions";
|
||||
"lng_manage_peer_removed_users" = "Removed users";
|
||||
"lng_manage_peer_permissions" = "Permissions";
|
||||
|
||||
"lng_manage_peer_group_type" = "Group type";
|
||||
"lng_manage_peer_channel_type" = "Channel type";
|
||||
"lng_manage_private_peer_title" = "Private";
|
||||
"lng_manage_public_peer_title" = "Public";
|
||||
|
||||
"lng_manage_history_visibility_title" = "Chat history for new members";
|
||||
"lng_manage_history_visibility_shown" = "Visible";
|
||||
"lng_manage_history_visibility_shown_about" = "New members will see messages that were sent before they joined.";
|
||||
"lng_manage_history_visibility_hidden" = "Hidden";
|
||||
"lng_manage_history_visibility_hidden_about" = "New members won't see earlier messages.";
|
||||
"lng_manage_history_visibility_hidden_legacy" = "New members won't see more than 100 previous messages.";
|
||||
|
||||
"lng_report_title" = "Report channel";
|
||||
"lng_report_group_title" = "Report group";
|
||||
@@ -764,17 +852,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_report_thanks" = "Thank you! Your report will be reviewed by our team very soon.";
|
||||
|
||||
"lng_channel_add_members" = "Add members";
|
||||
"lng_channel_add_banned" = "Ban user";
|
||||
"lng_channel_add_restricted" = "Restrict user";
|
||||
"lng_channel_add_users" = "Add users";
|
||||
"lng_channel_add_removed" = "Remove user";
|
||||
"lng_channel_add_exception" = "Add exception";
|
||||
"lng_channel_admins" = "Administrators";
|
||||
"lng_channel_add_admin" = "Add Administrator";
|
||||
"lng_channel_admin_status_creator" = "Creator";
|
||||
"lng_channel_admin_status_promoted_by" = "Promoted by {user}";
|
||||
"lng_channel_admin_status_not_admin" = "Not administrator";
|
||||
"lng_channel_banned_status_restricted_by" = "Restricted by {user}";
|
||||
"lng_channel_banned_status_removed_by" = "Removed by {user}";
|
||||
|
||||
"lng_group_blocked_list_about" = "Banned users are removed from the group and can only come back if invited by an admin.\nInvite links don't work for them.";
|
||||
"lng_channel_blocked_list_about" = "Banned users are removed from the channel.\nInvite links don't work for them.";
|
||||
"lng_channel_removed_list_about" = "Users removed from the channel by admins cannot rejoin it via invite links.";
|
||||
"lng_group_removed_list_about" = "Users removed from the group by admins cannot rejoin it via invite links.";
|
||||
|
||||
"lng_chat_all_members_admins" = "All Members Are Admins";
|
||||
"lng_chat_about_all_admins" = "Group members can add new members, edit name and photo of the group.";
|
||||
@@ -799,6 +889,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_create_private_group_about" = "People can only join if they were invited or have an invite link";
|
||||
"lng_create_group_skip" = "Skip";
|
||||
|
||||
"lng_create_channel_link_about" = "You can use a-z, 0-9 and underscores.\nMinimum length is 5 characters.";
|
||||
|
||||
"lng_create_channel_link_invalid" = "This link is invalid";
|
||||
"lng_create_channel_link_occupied" = "Sorry, this link is already occupied";
|
||||
"lng_create_channel_link_too_short" = "Sorry, this link is too short";
|
||||
@@ -854,7 +946,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_action_changed_title_channel" = "Channel name was changed to «{title}»";
|
||||
"lng_action_created_chat" = "{from} created group «{title}»";
|
||||
"lng_action_created_channel" = "Channel created";
|
||||
"lng_action_group_migrate" = "The group was upgraded to a supergroup";
|
||||
"lng_action_pinned_message" = "{from} pinned «{text}»";
|
||||
"lng_action_pinned_media" = "{from} pinned {media}";
|
||||
"lng_action_pinned_media_photo" = "a photo";
|
||||
@@ -909,8 +1000,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_profile_convert_feature4" = "— Creator can set a public link for the group";
|
||||
"lng_profile_convert_warning" = "{bold_start}Note:{bold_end} This action can not be undone";
|
||||
"lng_profile_convert_confirm" = "Convert";
|
||||
"lng_profile_add_more_after_upgrade#one" = "You will be able to add up to {count} member after you upgrade your group to a supergroup.";
|
||||
"lng_profile_add_more_after_upgrade#other" = "You will be able to add up to {count} members after you upgrade your group to a supergroup.";
|
||||
"lng_profile_add_more_after_create" = "You will be able to add more members after you create the group.";
|
||||
|
||||
"lng_channel_not_accessible" = "Sorry, this channel is not accessible.";
|
||||
"lng_group_not_accessible" = "Sorry, this group is not accessible.";
|
||||
@@ -943,6 +1033,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_forwarded_via" = "Forwarded from {user} via {inline_bot}";
|
||||
"lng_forwarded_channel_via" = "Forwarded from {channel} via {inline_bot}";
|
||||
"lng_forwarded_signed" = "{channel} ({user})";
|
||||
"lng_forwarded_hidden" = "The account was hidden by the user.";
|
||||
"lng_signed_author" = "Author: {user}";
|
||||
"lng_in_reply_to" = "In reply to";
|
||||
"lng_edited" = "edited";
|
||||
"lng_edited_date" = "Edited: {date}";
|
||||
@@ -967,13 +1059,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_media_audio" = "Voice message";
|
||||
|
||||
"lng_media_auto_settings" = "Automatic media download";
|
||||
"lng_media_auto_in_private" = "In private chats";
|
||||
"lng_media_auto_in_groups" = "In groups";
|
||||
"lng_media_auto_in_channels" = "In channels";
|
||||
"lng_media_auto_title" = "Automatically download";
|
||||
"lng_media_photo_title" = "Photos";
|
||||
"lng_media_video_title" = "Video files";
|
||||
"lng_media_audio_title" = "Voice messages";
|
||||
"lng_media_gif_title" = "GIFs and animations";
|
||||
"lng_media_auto_private_chats" = "Private chats";
|
||||
"lng_media_auto_groups" = "Groups and channels";
|
||||
"lng_media_auto_play" = "Autoplay";
|
||||
"lng_media_video_messages_title" = "Round video messages";
|
||||
"lng_media_file_title" = "Files";
|
||||
"lng_media_music_title" = "Music";
|
||||
"lng_media_animation_title" = "Animated GIFs";
|
||||
"lng_media_size_limit" = "Limit by size";
|
||||
"lng_media_size_up_to" = "up to {size}";
|
||||
"lng_media_chat_background" = "Chat background";
|
||||
|
||||
"lng_emoji_category1" = "People";
|
||||
"lng_emoji_category2" = "Nature";
|
||||
@@ -983,6 +1082,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_emoji_category6" = "Objects";
|
||||
"lng_emoji_category7" = "Symbols & Flags";
|
||||
"lng_emoji_hide_panel" = "Click here to hide the emoji sidebar";
|
||||
"lng_emoji_manage_sets" = "Choose emoji set";
|
||||
"lng_emoji_set_ready" = "Downloaded";
|
||||
"lng_emoji_set_active" = "Current set";
|
||||
"lng_emoji_set_download" = "Download {size}";
|
||||
"lng_emoji_set_loading" = "{percent}, {progress}";
|
||||
|
||||
"lng_recent_stickers" = "Frequently used";
|
||||
"lng_faved_stickers_add" = "Add to Favorites";
|
||||
@@ -991,6 +1095,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_group_stickers_description" = "You can choose a sticker set which will be available for every member while in the group chat.";
|
||||
"lng_group_stickers_add" = "Choose sticker set";
|
||||
|
||||
"lng_group_about_header" = "You have created a group.";
|
||||
"lng_group_about_text" = "Groups can have:";
|
||||
"lng_group_about1" = "Up to 100,000 members";
|
||||
"lng_group_about2" = "Persistent chat history";
|
||||
"lng_group_about3" = "Public links such as t.me/title";
|
||||
"lng_group_about4" = "Admins with different rights";
|
||||
|
||||
"lng_switch_stickers" = "Stickers";
|
||||
"lng_switch_emoji" = "Emoji";
|
||||
"lng_switch_gifs" = "GIFs";
|
||||
@@ -1018,6 +1129,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_stickers_count#one" = "{count} sticker";
|
||||
"lng_stickers_count#other" = "{count} stickers";
|
||||
"lng_stickers_masks_pack" = "This is a pack of mask stickers. You can use them in the photo editor on our mobile apps.";
|
||||
"lng_stickers_attached_sets" = "Sets of attached stickers";
|
||||
"lng_stickers_group_set" = "Group sticker set";
|
||||
"lng_stickers_remove_group_set" = "Remove group sticker set?";
|
||||
"lng_stickers_group_from_your" = "Choose from your stickers";
|
||||
@@ -1036,6 +1148,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_in_dlg_file" = "File";
|
||||
"lng_in_dlg_sticker" = "Sticker";
|
||||
"lng_in_dlg_sticker_emoji" = "{emoji} Sticker";
|
||||
"lng_in_dlg_poll" = "Poll";
|
||||
|
||||
"lng_ban_user" = "Ban User";
|
||||
"lng_delete_all_from" = "Delete all from this user";
|
||||
@@ -1052,7 +1165,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_cant_invite_banned" = "Sorry, only admin can add this user.";
|
||||
"lng_cant_invite_privacy" = "Sorry, you cannot add this user to groups because of their privacy settings.";
|
||||
"lng_cant_invite_privacy_channel" = "Sorry, you cannot add this user to channels because of their privacy settings.";
|
||||
"lng_cant_invite_bot_to_channel" = "Sorry, bots can only be added to channels as administrators.";
|
||||
"lng_cant_do_this" = "Sorry, this action is unavailable.";
|
||||
"lng_cant_invite_offer_admin" = "Bots can only be added as administrators.";
|
||||
"lng_cant_invite_make_admin" = "Make admin";
|
||||
|
||||
"lng_send_button" = "Send";
|
||||
"lng_message_ph" = "Write a message...";
|
||||
@@ -1066,6 +1182,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_from_draft" = "Draft";
|
||||
"lng_bot_description" = "What can this bot do?";
|
||||
"lng_unblock_button" = "Unblock";
|
||||
"lng_restart_button" = "Restart";
|
||||
"lng_channel_mute" = "Mute";
|
||||
"lng_channel_unmute" = "Unmute";
|
||||
"lng_saved_messages" = "Saved Messages";
|
||||
@@ -1153,6 +1270,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_context_edit_permissions" = "Edit permissions";
|
||||
"lng_context_restrict_user" = "Restrict user";
|
||||
"lng_context_remove_from_group" = "Remove from group";
|
||||
"lng_context_add_to_group" = "Add to group";
|
||||
|
||||
"lng_context_copy_link" = "Copy Link";
|
||||
"lng_context_copy_post_link" = "Copy Post Link";
|
||||
@@ -1173,6 +1291,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_context_copy_text" = "Copy Text";
|
||||
"lng_context_open_gif" = "Open GIF";
|
||||
"lng_context_save_gif" = "Save GIF";
|
||||
"lng_context_attached_stickers" = "Attached Stickers";
|
||||
"lng_context_to_msg" = "Go To Message";
|
||||
"lng_context_reply_msg" = "Reply";
|
||||
"lng_context_edit_msg" = "Edit";
|
||||
@@ -1236,9 +1355,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_edit_contact_title" = "Edit contact name";
|
||||
"lng_edit_channel_title" = "Edit channel";
|
||||
"lng_edit_sign_messages" = "Sign messages";
|
||||
"lng_edit_group_who_invites" = "Who can add members";
|
||||
"lng_edit_group_invites_everybody" = "All members";
|
||||
"lng_edit_group_invites_only_admins" = "Only admins";
|
||||
"lng_edit_group" = "Edit group";
|
||||
"lng_edit_self_title" = "Edit your name";
|
||||
"lng_confirm_contact_data" = "New Contact";
|
||||
@@ -1274,8 +1390,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_delete_for_me_chat_hint#other" = "This will delete them just for you, not for other participants of the chat.";
|
||||
"lng_delete_for_me_hint#one" = "This will delete it just for you.";
|
||||
"lng_delete_for_me_hint#other" = "This will delete them just for you.";
|
||||
"lng_selected_unsend_about_user_one" = "You can also delete the message you sent from {user}'s inbox by checking \"Unsend my messages\".";
|
||||
"lng_selected_unsend_about_user#one" = "You can also delete the {count} message you sent from {user}'s inbox by checking \"Unsend my messages\".";
|
||||
"lng_selected_unsend_about_user#other" = "You can also delete the {count} messages you sent from {user}'s inbox by checking \"Unsend my messages\".";
|
||||
"lng_selected_unsend_about_group_one" = "You can also delete the message you sent from the inboxes of other group members by checking \"Unsend my messages\".";
|
||||
"lng_selected_unsend_about_group#one" = "You can also delete the {count} message you sent from the inboxes of other group members by checking \"Unsend my messages\".";
|
||||
"lng_selected_unsend_about_group#other" = "You can also delete the {count} messages you sent from the inboxes of other group members by checking \"Unsend my messages\".";
|
||||
"lng_delete_for_everyone_check" = "Delete for everyone";
|
||||
"lng_delete_for_other_check" = "Delete for {user}";
|
||||
"lng_delete_for_other_check" = "Also delete for {user}";
|
||||
"lng_delete_for_other_my" = "Unsend my messages";
|
||||
"lng_box_delete" = "Delete";
|
||||
"lng_box_leave" = "Leave";
|
||||
|
||||
@@ -1330,7 +1453,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_menu_formatting_link_edit" = "Edit link";
|
||||
"lng_menu_formatting_clear" = "Plain text";
|
||||
"lng_formatting_link_create_title" = "Create link";
|
||||
"lng_formatting_link_edit_title" = "Create link";
|
||||
"lng_formatting_link_edit_title" = "Edit link";
|
||||
"lng_formatting_link_text" = "Text";
|
||||
"lng_formatting_link_url" = "URL";
|
||||
"lng_formatting_link_create" = "Create";
|
||||
@@ -1408,14 +1531,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_player_message_today" = "Today at {time}";
|
||||
"lng_player_message_yesterday" = "Yesterday at {time}";
|
||||
"lng_player_message_date" = "{date} at {time}";
|
||||
//"lng_player_cant_stream" = "This file can't be played before it is fully downloaded.\n\nWould you like to download it?";
|
||||
"lng_player_download" = "Download";
|
||||
|
||||
"lng_rights_edit_admin" = "Manage permissions";
|
||||
"lng_rights_edit_admin_header" = "What can this admin do?";
|
||||
"lng_rights_about_add_admins_yes" = "This admin will be able to add new admins with the same (or more limited) permissions.";
|
||||
"lng_rights_about_add_admins_no" = "This admin will not be able to add new admins.";
|
||||
"lng_rights_about_admin_cant_edit" = "You cannot edit rights of this admin.";
|
||||
|
||||
"lng_rights_about_admin_cant_edit" = "You are not allowed to edit the rights of this admin.";
|
||||
"lng_rights_about_restriction_cant_edit" = "You cannot change the restrictions for this user.";
|
||||
"lng_rights_restriction_for_all" = "This option is disabled for all members in Group Permissions. You can either enable the permission for everyone or make this user an admin.";
|
||||
"lng_rights_permission_for_all" = "This option is enabled for all members in Group Permissions.";
|
||||
"lng_rights_permission_unavailable" = "This permission is not available in public groups.";
|
||||
"lng_rights_permission_cant_edit" = "You cannot edit this permission.";
|
||||
"lng_rights_user_restrictions" = "User restrictions";
|
||||
"lng_rights_user_restrictions_header" = "What can this user do?";
|
||||
"lng_rights_user_restrictions_header" = "What can this member do?";
|
||||
"lng_rights_default_restrictions_header" = "What can members of this group do?";
|
||||
|
||||
"lng_rights_channel_info" = "Change channel info";
|
||||
"lng_rights_channel_post" = "Post messages";
|
||||
@@ -1433,6 +1565,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_rights_chat_send_media" = "Send media";
|
||||
"lng_rights_chat_send_stickers" = "Send stickers & GIFs";
|
||||
"lng_rights_chat_send_links" = "Embed links";
|
||||
"lng_rights_chat_send_polls" = "Send polls";
|
||||
"lng_rights_chat_add_members" = "Add members";
|
||||
"lng_rights_chat_banned_until_header" = "Restricted until";
|
||||
"lng_rights_chat_banned_forever" = "Forever";
|
||||
"lng_rights_chat_banned_day#one" = "For {count} day";
|
||||
@@ -1447,9 +1581,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_restricted_send_stickers" = "The admins of this group restricted you from posting stickers here.";
|
||||
"lng_restricted_send_gifs" = "The admins of this group restricted you from posting GIFs here.";
|
||||
"lng_restricted_send_inline" = "The admins of this group restricted you from posting inline content here.";
|
||||
"lng_restricted_send_polls" = "The admins of this group restricted you from posting polls here.";
|
||||
|
||||
"lng_restricted_list_title" = "Restricted users";
|
||||
"lng_banned_list_title" = "Banned users";
|
||||
"lng_restricted_send_message_all" = "Writing messages isn't allowed in this group.";
|
||||
"lng_restricted_send_media_all" = "Posting media content isn't allowed in this group.";
|
||||
"lng_restricted_send_stickers_all" = "Posting stickers isn't allowed in this group.";
|
||||
"lng_restricted_send_gifs_all" = "Posting GIFs isn't allowed in this group.";
|
||||
"lng_restricted_send_inline_all" = "Posting inline content isn't allowed in this group.";
|
||||
"lng_restricted_send_polls_all" = "Posting polls isn't allowed in this group.";
|
||||
|
||||
"lng_exceptions_list_title" = "Exceptions";
|
||||
"lng_removed_list_title" = "Removed users";
|
||||
|
||||
"lng_admin_log_title_all" = "All actions";
|
||||
"lng_admin_log_title_selected" = "Selected actions";
|
||||
@@ -1509,10 +1651,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_admin_log_participant_joined_channel" = "{from} joined the channel";
|
||||
"lng_admin_log_participant_left" = "{from} left the group";
|
||||
"lng_admin_log_participant_left_channel" = "{from} left the channel";
|
||||
"lng_admin_log_stopped_poll" = "{from} stopped poll:";
|
||||
"lng_admin_log_invited" = "invited {user}";
|
||||
"lng_admin_log_banned" = "banned {user}";
|
||||
"lng_admin_log_restricted" = "changed restrictions for {user} {until}";
|
||||
"lng_admin_log_promoted" = "changed privileges for {user}";
|
||||
"lng_admin_log_changed_default_permissions" = "changed default permissions";
|
||||
"lng_admin_log_changed_stickers_group" = "{from} changed the group's {sticker_set}";
|
||||
"lng_admin_log_changed_stickers_set" = "sticker set";
|
||||
"lng_admin_log_removed_stickers_group" = "{from} removed the group's sticker set";
|
||||
@@ -1524,12 +1668,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_admin_log_banned_send_media" = "Send media";
|
||||
"lng_admin_log_banned_send_stickers" = "Send stickers & GIFs";
|
||||
"lng_admin_log_banned_embed_links" = "Embed links";
|
||||
"lng_admin_log_banned_send_polls" = "Send polls";
|
||||
"lng_admin_log_admin_change_info" = "Change info";
|
||||
"lng_admin_log_admin_post_messages" = "Post messages";
|
||||
"lng_admin_log_admin_edit_messages" = "Edit messages";
|
||||
"lng_admin_log_admin_delete_messages" = "Delete messages";
|
||||
"lng_admin_log_admin_ban_users" = "Ban users";
|
||||
"lng_admin_log_admin_invite_users" = "Add users";
|
||||
"lng_admin_log_admin_invite_users" = "Add members";
|
||||
"lng_admin_log_admin_invite_link" = "Invite users via link";
|
||||
"lng_admin_log_admin_pin_messages" = "Pin messages";
|
||||
"lng_admin_log_admin_add_admins" = "Add new admins";
|
||||
@@ -1586,7 +1731,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_passport_create_password" = "Please create a password which will be used\nto encrypt your personal data.";
|
||||
"lng_passport_about_password" = "This password will also be required whenever\nyou log in to a new device.";
|
||||
"lng_passport_password_create" = "Create a password";
|
||||
"lng_passport_link_sent" = "A confirmation link was sent to your email\n{email}";
|
||||
"lng_passport_email_validate" = "Validate";
|
||||
"lng_passport_code_sent" = "A confirmation code was sent to\n{email}";
|
||||
"lng_passport_stop_password_sure" = "Are you sure you want to cancel setting up your password?";
|
||||
"lng_passport_password_placeholder" = "Your password";
|
||||
"lng_passport_next" = "Next";
|
||||
@@ -1782,6 +1928,41 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_export_about_chats" = "This page lists all chats from this export and where to look for their data.";
|
||||
"lng_export_about_left_chats" = "Below are the supergroups and channels from this export that you've left or where you were banned.\n\nNote that when you leave a channel or supergroup you've created, you have the option to either delete it, or simply leave (in case you want to rejoin later, or keep the community alive despite not being a member).";
|
||||
|
||||
"lng_language_switch_title" = "Change language?";
|
||||
"lng_language_switch_about_official" = "You are about to apply a language pack {lang_name} that is {percent}% complete.\n\nThis will translate the entire interface. You can suggest corrections in the {link}.\n\nYou can change your language back at any time in Settings.";
|
||||
"lng_language_switch_about_unofficial" = "You are about to apply a custom language pack {lang_name} that is {percent}% complete.\n\nThis will translate the entire interface. You can suggest corrections in the {link}.\n\nYou can change your language back at any time in Settings.";
|
||||
"lng_language_switch_link" = "translation panel";
|
||||
"lng_language_switch_apply" = "Change";
|
||||
"lng_language_not_found" = "Sorry, this language pack doesn't exist.";
|
||||
"lng_language_already" = "You're already using this language pack. You can change your language back in Settings.";
|
||||
"lng_language_not_ready_title" = "Insufficient data";
|
||||
"lng_language_not_ready_about" = "Unfortunately, this custom language pack ({lang_name}) doesn't contain data for Telegram Desktop. You can contribute to this language pack using the {link}.";
|
||||
"lng_language_not_ready_link" = "translations platform";
|
||||
|
||||
"lng_launch_exe_warning" = "This file has a {extension} extension.\nAre you sure you want to run it?";
|
||||
"lng_launch_exe_sure" = "Run";
|
||||
"lng_launch_exe_dont_ask" = "Don't ask me again";
|
||||
|
||||
"lng_polls_anonymous" = "Anonymous Poll";
|
||||
"lng_polls_closed" = "Final results";
|
||||
"lng_polls_votes_count#one" = "{count} vote";
|
||||
"lng_polls_votes_count#other" = "{count} votes";
|
||||
"lng_polls_votes_none" = "No votes";
|
||||
"lng_polls_retract" = "Retract vote";
|
||||
"lng_polls_stop" = "Stop poll";
|
||||
"lng_polls_stop_warning" = "If you stop this poll now, nobody will be able to vote in it anymore. This action cannot be undone.";
|
||||
"lng_polls_stop_sure" = "Stop";
|
||||
"lng_polls_create" = "Create poll";
|
||||
"lng_polls_create_title" = "New poll";
|
||||
"lng_polls_create_question" = "Question";
|
||||
"lng_polls_create_question_placeholder" = "Ask a question";
|
||||
"lng_polls_create_options" = "Poll options";
|
||||
"lng_polls_create_option_add" = "Add an option...";
|
||||
"lng_polls_create_limit#one" = "You can add {count} more option.";
|
||||
"lng_polls_create_limit#other" = "You can add {count} more options.";
|
||||
"lng_polls_create_maximum" = "You have added the maximum number of options.";
|
||||
"lng_polls_create_button" = "Create";
|
||||
|
||||
// Wnd specific
|
||||
|
||||
"lng_wnd_choose_program_menu" = "Choose Default Program...";
|
||||
@@ -1794,6 +1975,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_linux_menu_undo" = "Undo";
|
||||
"lng_linux_menu_redo" = "Redo";
|
||||
|
||||
"lng_linux_no_audio_prefs" = "You don't have any audio configuration applications installed.";
|
||||
|
||||
// Mac specific
|
||||
|
||||
"lng_mac_choose_program_menu" = "Other...";
|
||||
|
||||
@@ -207,7 +207,7 @@
|
||||
52;MX;Mexico;
|
||||
51;PE;Peru;51 XXX XXX XXX;11;
|
||||
49;DE;Germany;49 XXX XXXXXXXX;13;
|
||||
48;PL;Poland;48 XX XXX XXXX;11;
|
||||
48;PL;Poland;48 XXX XXX XXX;11;
|
||||
47;NO;Norway;47 XXXX XXXX;10;
|
||||
46;SE;Sweden;46 XX XXX XXXX;11;
|
||||
45;DK;Denmark;45 XXXX XXXX;10;
|
||||
|
||||
@@ -65,6 +65,9 @@
|
||||
<qresource prefix="/qt-project.org">
|
||||
<file>qmime/freedesktop.org.xml</file>
|
||||
</qresource>
|
||||
<qresource prefix="/misc">
|
||||
<file alias="default_shortcuts-custom.json">../default_shortcuts-custom.json</file>
|
||||
</qresource>
|
||||
<qresource prefix="/langs">
|
||||
<file alias="lang_it.strings">../langs/lang_it.strings</file>
|
||||
<file alias="lang_es.strings">../langs/lang_es.strings</file>
|
||||
|
||||
8
Telegram/Resources/qrc/telegram_emoji_preview.qrc
Normal file
@@ -0,0 +1,8 @@
|
||||
<RCC>
|
||||
<qresource prefix="/gui">
|
||||
<file alias="emoji/set0_preview.webp">../emoji/set0_preview.webp</file>
|
||||
<file alias="emoji/set1_preview.webp">../emoji/set1_preview.webp</file>
|
||||
<file alias="emoji/set2_preview.webp">../emoji/set2_preview.webp</file>
|
||||
<file alias="emoji/set3_preview.webp">../emoji/set3_preview.webp</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -2,4 +2,7 @@
|
||||
<qresource prefix="/qt">
|
||||
<file alias="etc/qt.conf">../etc/qt_linux.conf</file>
|
||||
</qresource>
|
||||
<qresource prefix="/fc">
|
||||
<file alias="fc-custom.conf">../fc-custom.conf</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -176,7 +176,8 @@ inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = In
|
||||
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
||||
inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;
|
||||
inputMediaGeoLive#7b1a118f geo_point:InputGeoPoint period:int = InputMedia;
|
||||
inputMediaGeoLive#ce4e82fd flags:# stopped:flags.0?true geo_point:InputGeoPoint period:flags.1?int = InputMedia;
|
||||
inputMediaPoll#6b3765b poll:Poll = InputMedia;
|
||||
|
||||
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
|
||||
inputChatUploadedPhoto#927c55b4 file:InputFile = InputChatPhoto;
|
||||
@@ -194,8 +195,6 @@ inputDocumentFileLocation#196683d9 id:long access_hash:long file_reference:bytes
|
||||
inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
|
||||
inputTakeoutFileLocation#29be5899 = InputFileLocation;
|
||||
|
||||
inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent;
|
||||
|
||||
peerUser#9db1bc6d user_id:int = Peer;
|
||||
peerChat#bad0e5bb chat_id:int = Peer;
|
||||
peerChannel#bddde532 channel_id:int = Peer;
|
||||
@@ -215,7 +214,7 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL
|
||||
fileLocation#91d11eb dc_id:int volume_id:long local_id:int secret:long file_reference:bytes = FileLocation;
|
||||
|
||||
userEmpty#200250ba id:int = User;
|
||||
user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
||||
user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
||||
|
||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
|
||||
@@ -228,13 +227,13 @@ userStatusLastWeek#7bf09fc = UserStatus;
|
||||
userStatusLastMonth#77ebc742 = UserStatus;
|
||||
|
||||
chatEmpty#9ba2d800 id:int = Chat;
|
||||
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
|
||||
chat#3bda1bde flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
||||
chatForbidden#7328bdb id:int title:string = Chat;
|
||||
channel#c88974ac flags:# creator:flags.0?true left:flags.2?true editor:flags.3?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChannelAdminRights banned_rights:flags.15?ChannelBannedRights participants_count:flags.17?int = Chat;
|
||||
channel#4df30834 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
|
||||
channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
|
||||
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
|
||||
channelFull#76af5481 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;
|
||||
chatFull#22a235da flags:# can_set_username:flags.7?true id:int about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int = ChatFull;
|
||||
channelFull#1c87a71a flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_view_stats:flags.12?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;
|
||||
|
||||
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
|
||||
chatParticipantCreator#da13538a user_id:int = ChatParticipant;
|
||||
@@ -247,7 +246,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
|
||||
|
||||
messageEmpty#83e5de54 id:int = Message;
|
||||
message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;
|
||||
message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;
|
||||
messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
@@ -261,6 +260,7 @@ messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:str
|
||||
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
||||
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
|
||||
messageMediaGeoLive#7c3c2609 geo:GeoPoint period:int = MessageMedia;
|
||||
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
|
||||
|
||||
messageActionEmpty#b6aef7b0 = MessageAction;
|
||||
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
|
||||
@@ -284,6 +284,7 @@ messageActionCustomAction#fae69f56 message:string = MessageAction;
|
||||
messageActionBotAllowed#abe9affe domain:string = MessageAction;
|
||||
messageActionSecureValuesSentMe#1b287353 values:Vector<SecureValue> credentials:SecureCredentialsEncrypted = MessageAction;
|
||||
messageActionSecureValuesSent#d95c6154 types:Vector<SecureValueType> = MessageAction;
|
||||
messageActionContactSignUp#f3f25f76 = MessageAction;
|
||||
|
||||
dialog#e4def5db flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
|
||||
|
||||
@@ -293,6 +294,7 @@ photo#9c477dd8 flags:# has_stickers:flags.0?true id:long access_hash:long file_r
|
||||
photoSizeEmpty#e17e23c type:string = PhotoSize;
|
||||
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
|
||||
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
|
||||
photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize;
|
||||
|
||||
geoPointEmpty#1117dd5f = GeoPoint;
|
||||
geoPoint#296f104 long:double lat:double access_hash:long = GeoPoint;
|
||||
@@ -308,6 +310,7 @@ auth.exportedAuthorization#df969c2d id:int bytes:bytes = auth.ExportedAuthorizat
|
||||
inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
|
||||
inputNotifyUsers#193b4417 = InputNotifyPeer;
|
||||
inputNotifyChats#4a95e84e = InputNotifyPeer;
|
||||
inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
|
||||
|
||||
inputPeerNotifySettings#9c3d198e flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = InputPeerNotifySettings;
|
||||
|
||||
@@ -315,16 +318,16 @@ peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bo
|
||||
|
||||
peerSettings#818426cd flags:# report_spam:flags.0?true = PeerSettings;
|
||||
|
||||
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
|
||||
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
|
||||
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
|
||||
|
||||
inputReportReasonSpam#58dbcab8 = ReportReason;
|
||||
inputReportReasonViolence#1e22c78d = ReportReason;
|
||||
inputReportReasonPornography#2e59d922 = ReportReason;
|
||||
inputReportReasonChildAbuse#adf44ee3 = ReportReason;
|
||||
inputReportReasonOther#e1746d0a text:string = ReportReason;
|
||||
inputReportReasonCopyright#9b89f93a = ReportReason;
|
||||
|
||||
userFull#f220f3f flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo common_chats_count:int = UserFull;
|
||||
userFull#8ea4a881 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int = UserFull;
|
||||
|
||||
contact#f911c994 user_id:int mutual:Bool = Contact;
|
||||
|
||||
@@ -349,8 +352,8 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
|
||||
messages.dialogsNotModified#f0e3e596 count:int = messages.Dialogs;
|
||||
|
||||
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.channelMessages#99262e37 flags:# pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesSlice#a6c47aaa flags:# inexact:flags.1?true count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.channelMessages#99262e37 flags:# inexact:flags.1?true pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesNotModified#74535f21 count:int = messages.Messages;
|
||||
|
||||
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
|
||||
@@ -386,7 +389,6 @@ updateChatParticipants#7761198 participants:ChatParticipants = Update;
|
||||
updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
|
||||
updateUserName#a7332b73 user_id:int first_name:string last_name:string username:string = Update;
|
||||
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
|
||||
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
|
||||
updateContactLink#9d2e67c5 user_id:int my_link:ContactLink foreign_link:ContactLink = Update;
|
||||
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
|
||||
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
|
||||
@@ -410,7 +412,6 @@ updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update;
|
||||
updateReadChannelInbox#4214f37f channel_id:int max_id:int = Update;
|
||||
updateDeleteChannelMessages#c37521c9 channel_id:int messages:Vector<int> pts:int pts_count:int = Update;
|
||||
updateChannelMessageViews#98a12b4b channel_id:int id:int views:int = Update;
|
||||
updateChatAdmins#6e947941 chat_id:int enabled:Bool version:int = Update;
|
||||
updateChatParticipantAdmin#b6901959 chat_id:int user_id:int is_admin:Bool version:int = Update;
|
||||
updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update;
|
||||
updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true order:Vector<long> = Update;
|
||||
@@ -437,13 +438,17 @@ updateBotWebhookJSONQuery#9b9240a6 query_id:long data:DataJSON timeout:int = Upd
|
||||
updateBotShippingQuery#e0cdc940 query_id:long user_id:int payload:bytes shipping_address:PostAddress = Update;
|
||||
updateBotPrecheckoutQuery#5d2f3aa9 flags:# query_id:long user_id:int payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string currency:string total_amount:long = Update;
|
||||
updatePhoneCall#ab0f6b1e phone_call:PhoneCall = Update;
|
||||
updateLangPackTooLong#10c2404b = Update;
|
||||
updateLangPackTooLong#46560264 lang_code:string = Update;
|
||||
updateLangPack#56022f4d difference:LangPackDifference = Update;
|
||||
updateFavedStickers#e511996d = Update;
|
||||
updateChannelReadMessagesContents#89893b45 channel_id:int messages:Vector<int> = Update;
|
||||
updateContactsReset#7084a7be = Update;
|
||||
updateChannelAvailableMessages#70db6837 channel_id:int available_min_id:int = Update;
|
||||
updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
|
||||
updateUserPinnedMessage#4c43da18 user_id:int id:int = Update;
|
||||
updateChatPinnedMessage#e10db349 chat_id:int id:int version:int = Update;
|
||||
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
|
||||
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
@@ -470,7 +475,7 @@ upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes
|
||||
|
||||
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
|
||||
|
||||
config#3213dbba flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int = Config;
|
||||
config#e6ca25f6 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config;
|
||||
|
||||
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
|
||||
|
||||
@@ -508,13 +513,14 @@ inputDocumentEmpty#72f0eaae = InputDocument;
|
||||
inputDocument#1abfb575 id:long access_hash:long file_reference:bytes = InputDocument;
|
||||
|
||||
documentEmpty#36f8c871 id:long = Document;
|
||||
document#59534e4c id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumb:PhotoSize dc_id:int attributes:Vector<DocumentAttribute> = Document;
|
||||
document#9ba29cc1 flags:# id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumbs:flags.0?Vector<PhotoSize> dc_id:int attributes:Vector<DocumentAttribute> = Document;
|
||||
|
||||
help.support#17c6b5f6 phone_number:string user:User = help.Support;
|
||||
|
||||
notifyPeer#9fd40bd8 peer:Peer = NotifyPeer;
|
||||
notifyUsers#b4c83b4c = NotifyPeer;
|
||||
notifyChats#c007cec3 = NotifyPeer;
|
||||
notifyBroadcasts#d612e8ef = NotifyPeer;
|
||||
|
||||
sendMessageTypingAction#16bf744e = SendMessageAction;
|
||||
sendMessageCancelAction#fd5ec8f5 = SendMessageAction;
|
||||
@@ -535,10 +541,16 @@ contacts.found#b3134d9d my_results:Vector<Peer> results:Vector<Peer> chats:Vecto
|
||||
inputPrivacyKeyStatusTimestamp#4f96cb18 = InputPrivacyKey;
|
||||
inputPrivacyKeyChatInvite#bdfb0426 = InputPrivacyKey;
|
||||
inputPrivacyKeyPhoneCall#fabadc5f = InputPrivacyKey;
|
||||
inputPrivacyKeyPhoneP2P#db9e70d2 = InputPrivacyKey;
|
||||
inputPrivacyKeyForwards#a4dd4c08 = InputPrivacyKey;
|
||||
inputPrivacyKeyProfilePhoto#5719bacc = InputPrivacyKey;
|
||||
|
||||
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
|
||||
privacyKeyChatInvite#500e6dfa = PrivacyKey;
|
||||
privacyKeyPhoneCall#3d662b7b = PrivacyKey;
|
||||
privacyKeyPhoneP2P#39491cc8 = PrivacyKey;
|
||||
privacyKeyForwards#69ec56a3 = PrivacyKey;
|
||||
privacyKeyProfilePhoto#96151fed = PrivacyKey;
|
||||
|
||||
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
|
||||
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
|
||||
@@ -586,7 +598,7 @@ webPagePending#c586da1c id:long date:int = WebPage;
|
||||
webPage#5f07b4bc flags:# id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page = WebPage;
|
||||
webPageNotModified#85849473 = WebPage;
|
||||
|
||||
authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
|
||||
authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
|
||||
|
||||
account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations;
|
||||
|
||||
@@ -610,7 +622,7 @@ inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
||||
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
|
||||
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
|
||||
|
||||
stickerSet#5585a139 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet;
|
||||
stickerSet#6a90bcb7 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize count:int hash:int = StickerSet;
|
||||
|
||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
||||
|
||||
@@ -667,8 +679,8 @@ channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:
|
||||
channelParticipant#15ebac1d user_id:int date:int = ChannelParticipant;
|
||||
channelParticipantSelf#a3289a6d user_id:int inviter_id:int date:int = ChannelParticipant;
|
||||
channelParticipantCreator#e3e2e1f9 user_id:int = ChannelParticipant;
|
||||
channelParticipantAdmin#a82fa898 flags:# can_edit:flags.0?true user_id:int inviter_id:int promoted_by:int date:int admin_rights:ChannelAdminRights = ChannelParticipant;
|
||||
channelParticipantBanned#222c1886 flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChannelBannedRights = ChannelParticipant;
|
||||
channelParticipantAdmin#5daa6e23 flags:# can_edit:flags.0?true self:flags.1?true user_id:int inviter_id:flags.1?int promoted_by:int date:int admin_rights:ChatAdminRights = ChannelParticipant;
|
||||
channelParticipantBanned#1c0facaf flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant;
|
||||
|
||||
channelParticipantsRecent#de3f3c79 = ChannelParticipantsFilter;
|
||||
channelParticipantsAdmins#b4608969 = ChannelParticipantsFilter;
|
||||
@@ -676,6 +688,7 @@ channelParticipantsKicked#a3b54985 q:string = ChannelParticipantsFilter;
|
||||
channelParticipantsBots#b0d1865b = ChannelParticipantsFilter;
|
||||
channelParticipantsBanned#1427a5e1 q:string = ChannelParticipantsFilter;
|
||||
channelParticipantsSearch#656ac4b q:string = ChannelParticipantsFilter;
|
||||
channelParticipantsContacts#bb6ae88d q:string = ChannelParticipantsFilter;
|
||||
|
||||
channels.channelParticipants#f56ee2a8 count:int participants:Vector<ChannelParticipant> users:Vector<User> = channels.ChannelParticipants;
|
||||
channels.channelParticipantsNotModified#f0173fe9 = channels.ChannelParticipants;
|
||||
@@ -717,7 +730,7 @@ messages.botResults#947ca848 flags:# gallery:flags.0?true query_id:long next_off
|
||||
|
||||
exportedMessageLink#5dab1af4 link:string html:string = ExportedMessageLink;
|
||||
|
||||
messageFwdHeader#559ebe6d flags:# from_id:flags.0?int date:int channel_id:flags.1?int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int = MessageFwdHeader;
|
||||
messageFwdHeader#ec338270 flags:# from_id:flags.0?int from_name:flags.5?string date:int channel_id:flags.1?int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int = MessageFwdHeader;
|
||||
|
||||
auth.codeTypeSms#72a3158c = auth.CodeType;
|
||||
auth.codeTypeCall#741cd3e3 = auth.CodeType;
|
||||
@@ -794,6 +807,12 @@ textFixed#6c3f19b9 text:RichText = RichText;
|
||||
textUrl#3c2884c1 text:RichText url:string webpage_id:long = RichText;
|
||||
textEmail#de5a0dd6 text:RichText email:string = RichText;
|
||||
textConcat#7e6260d7 texts:Vector<RichText> = RichText;
|
||||
textSubscript#ed6a8504 text:RichText = RichText;
|
||||
textSuperscript#c7fb5e01 text:RichText = RichText;
|
||||
textMarked#34b8621 text:RichText = RichText;
|
||||
textPhone#1ccb966a text:RichText phone:string = RichText;
|
||||
textImage#81ccf4f document_id:long w:int h:int = RichText;
|
||||
textAnchor#35553762 text:RichText name:string = RichText;
|
||||
|
||||
pageBlockUnsupported#13567e8a = PageBlock;
|
||||
pageBlockTitle#70abc3fd text:RichText = PageBlock;
|
||||
@@ -806,21 +825,24 @@ pageBlockPreformatted#c070d93e text:RichText language:string = PageBlock;
|
||||
pageBlockFooter#48870999 text:RichText = PageBlock;
|
||||
pageBlockDivider#db20b188 = PageBlock;
|
||||
pageBlockAnchor#ce0d37b0 name:string = PageBlock;
|
||||
pageBlockList#3a58c7f4 ordered:Bool items:Vector<RichText> = PageBlock;
|
||||
pageBlockList#e4e88011 items:Vector<PageListItem> = PageBlock;
|
||||
pageBlockBlockquote#263d7c26 text:RichText caption:RichText = PageBlock;
|
||||
pageBlockPullquote#4f4456d3 text:RichText caption:RichText = PageBlock;
|
||||
pageBlockPhoto#e9c69982 photo_id:long caption:RichText = PageBlock;
|
||||
pageBlockVideo#d9d71866 flags:# autoplay:flags.0?true loop:flags.1?true video_id:long caption:RichText = PageBlock;
|
||||
pageBlockPhoto#1759c560 flags:# photo_id:long caption:PageCaption url:flags.0?string webpage_id:flags.0?long = PageBlock;
|
||||
pageBlockVideo#7c8fe7b6 flags:# autoplay:flags.0?true loop:flags.1?true video_id:long caption:PageCaption = PageBlock;
|
||||
pageBlockCover#39f23300 cover:PageBlock = PageBlock;
|
||||
pageBlockEmbed#cde200d1 flags:# full_width:flags.0?true allow_scrolling:flags.3?true url:flags.1?string html:flags.2?string poster_photo_id:flags.4?long w:int h:int caption:RichText = PageBlock;
|
||||
pageBlockEmbedPost#292c7be9 url:string webpage_id:long author_photo_id:long author:string date:int blocks:Vector<PageBlock> caption:RichText = PageBlock;
|
||||
pageBlockCollage#8b31c4f items:Vector<PageBlock> caption:RichText = PageBlock;
|
||||
pageBlockSlideshow#130c8963 items:Vector<PageBlock> caption:RichText = PageBlock;
|
||||
pageBlockEmbed#a8718dc5 flags:# full_width:flags.0?true allow_scrolling:flags.3?true url:flags.1?string html:flags.2?string poster_photo_id:flags.4?long w:flags.5?int h:flags.5?int caption:PageCaption = PageBlock;
|
||||
pageBlockEmbedPost#f259a80b url:string webpage_id:long author_photo_id:long author:string date:int blocks:Vector<PageBlock> caption:PageCaption = PageBlock;
|
||||
pageBlockCollage#65a0fa4d items:Vector<PageBlock> caption:PageCaption = PageBlock;
|
||||
pageBlockSlideshow#31f9590 items:Vector<PageBlock> caption:PageCaption = PageBlock;
|
||||
pageBlockChannel#ef1751b5 channel:Chat = PageBlock;
|
||||
pageBlockAudio#31b81a7f audio_id:long caption:RichText = PageBlock;
|
||||
|
||||
pagePart#8e3f9ebe blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> = Page;
|
||||
pageFull#556ec7aa blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> = Page;
|
||||
pageBlockAudio#804361ea audio_id:long caption:PageCaption = PageBlock;
|
||||
pageBlockKicker#1e148390 text:RichText = PageBlock;
|
||||
pageBlockTable#bf4dea82 flags:# bordered:flags.0?true striped:flags.1?true title:RichText rows:Vector<PageTableRow> = PageBlock;
|
||||
pageBlockOrderedList#9a8ae1e1 items:Vector<PageListOrderedItem> = PageBlock;
|
||||
pageBlockDetails#76768bed flags:# open:flags.0?true blocks:Vector<PageBlock> title:RichText = PageBlock;
|
||||
pageBlockRelatedArticles#16115a96 title:RichText articles:Vector<PageRelatedArticle> = PageBlock;
|
||||
pageBlockMap#a44f3ef6 geo:GeoPoint zoom:int w:int h:int caption:PageCaption = PageBlock;
|
||||
|
||||
phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason;
|
||||
phoneCallDiscardReasonDisconnect#e095c1a0 = PhoneCallDiscardReason;
|
||||
@@ -879,7 +901,7 @@ phoneCallEmpty#5366c915 id:long = PhoneCall;
|
||||
phoneCallWaiting#1b8f4ad1 flags:# id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
|
||||
phoneCallRequested#83761ce4 id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall;
|
||||
phoneCallAccepted#6d003d3f id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall;
|
||||
phoneCall#ffe6ab67 id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector<PhoneConnection> start_date:int = PhoneCall;
|
||||
phoneCall#e6f9ddf3 flags:# p2p_allowed:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector<PhoneConnection> start_date:int = PhoneCall;
|
||||
phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
|
||||
|
||||
phoneConnection#9d4c17c0 id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection;
|
||||
@@ -901,11 +923,7 @@ langPackStringDeleted#2979eeb2 key:string = LangPackString;
|
||||
|
||||
langPackDifference#f385c1f6 lang_code:string from_version:int version:int strings:Vector<LangPackString> = LangPackDifference;
|
||||
|
||||
langPackLanguage#117698f1 name:string native_name:string lang_code:string = LangPackLanguage;
|
||||
|
||||
channelAdminRights#5d7ceba5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true invite_link:flags.6?true pin_messages:flags.7?true add_admins:flags.9?true manage_call:flags.10?true = ChannelAdminRights;
|
||||
|
||||
channelBannedRights#58cf4249 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true until_date:int = ChannelBannedRights;
|
||||
langPackLanguage#eeca5ce3 flags:# official:flags.0?true rtl:flags.2?true beta:flags.3?true name:string native_name:string lang_code:string base_lang_code:flags.1?string plural_code:string strings_count:int translated_count:int translations_url:string = LangPackLanguage;
|
||||
|
||||
channelAdminLogEventActionChangeTitle#e6dfb825 prev_value:string new_value:string = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeAbout#55188a2e prev_value:string new_value:string = ChannelAdminLogEventAction;
|
||||
@@ -923,6 +941,8 @@ channelAdminLogEventActionParticipantToggleBan#e6d83d7e prev_participant:Channel
|
||||
channelAdminLogEventActionParticipantToggleAdmin#d5676710 prev_participant:ChannelParticipant new_participant:ChannelParticipant = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeStickerSet#b1c3caa7 prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionTogglePreHistoryHidden#5f5c95f1 new_value:Bool = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionDefaultBannedRights#2df5fc0a prev_banned_rights:ChatBannedRights new_banned_rights:ChatBannedRights = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionStopPoll#8f079643 message:Message = ChannelAdminLogEventAction;
|
||||
|
||||
channelAdminLogEvent#3b5a3e40 id:long date:int user_id:int action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||
|
||||
@@ -1042,6 +1062,75 @@ secureRequiredTypeOneOf#27477b4 types:Vector<SecureRequiredType> = SecureRequire
|
||||
help.passportConfigNotModified#bfb9f457 = help.PassportConfig;
|
||||
help.passportConfig#a098d6af hash:int countries_langs:DataJSON = help.PassportConfig;
|
||||
|
||||
inputAppEvent#1d1b1245 time:double type:string peer:long data:JSONValue = InputAppEvent;
|
||||
|
||||
jsonObjectValue#c0de1bd9 key:string value:JSONValue = JSONObjectValue;
|
||||
|
||||
jsonNull#3f6d7b68 = JSONValue;
|
||||
jsonBool#c7345e6a value:Bool = JSONValue;
|
||||
jsonNumber#2be0dfa4 value:double = JSONValue;
|
||||
jsonString#b71e767a value:string = JSONValue;
|
||||
jsonArray#f7444763 value:Vector<JSONValue> = JSONValue;
|
||||
jsonObject#99c1d49d value:Vector<JSONObjectValue> = JSONValue;
|
||||
|
||||
pageTableCell#34566b6a flags:# header:flags.0?true align_center:flags.3?true align_right:flags.4?true valign_middle:flags.5?true valign_bottom:flags.6?true text:flags.7?RichText colspan:flags.1?int rowspan:flags.2?int = PageTableCell;
|
||||
|
||||
pageTableRow#e0c0c5e5 cells:Vector<PageTableCell> = PageTableRow;
|
||||
|
||||
pageCaption#6f747657 text:RichText credit:RichText = PageCaption;
|
||||
|
||||
pageListItemText#b92fb6cd text:RichText = PageListItem;
|
||||
pageListItemBlocks#25e073fc blocks:Vector<PageBlock> = PageListItem;
|
||||
|
||||
pageListOrderedItemText#5e068047 num:string text:RichText = PageListOrderedItem;
|
||||
pageListOrderedItemBlocks#98dd8936 num:string blocks:Vector<PageBlock> = PageListOrderedItem;
|
||||
|
||||
pageRelatedArticle#b390dc08 flags:# url:string webpage_id:long title:flags.0?string description:flags.1?string photo_id:flags.2?long author:flags.3?string published_date:flags.4?int = PageRelatedArticle;
|
||||
|
||||
page#ae891bec flags:# part:flags.0?true rtl:flags.1?true v2:flags.2?true url:string blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> = Page;
|
||||
|
||||
help.supportName#8c05f1c9 name:string = help.SupportName;
|
||||
|
||||
help.userInfoEmpty#f3ae2eed = help.UserInfo;
|
||||
help.userInfo#1eb3758 message:string entities:Vector<MessageEntity> author:string date:int = help.UserInfo;
|
||||
|
||||
pollAnswer#6ca9c2e9 text:string option:bytes = PollAnswer;
|
||||
|
||||
poll#d5529d06 id:long flags:# closed:flags.0?true question:string answers:Vector<PollAnswer> = Poll;
|
||||
|
||||
pollAnswerVoters#3b6ddad2 flags:# chosen:flags.0?true option:bytes voters:int = PollAnswerVoters;
|
||||
|
||||
pollResults#5755785a flags:# min:flags.0?true results:flags.1?Vector<PollAnswerVoters> total_voters:flags.2?int = PollResults;
|
||||
|
||||
chatOnlines#f041e250 onlines:int = ChatOnlines;
|
||||
|
||||
statsURL#47a971e0 url:string = StatsURL;
|
||||
|
||||
chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true = ChatAdminRights;
|
||||
|
||||
chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true until_date:int = ChatBannedRights;
|
||||
|
||||
inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper;
|
||||
inputWallPaperSlug#72091c80 slug:string = InputWallPaper;
|
||||
|
||||
account.wallPapersNotModified#1c199183 = account.WallPapers;
|
||||
account.wallPapers#702b65a9 hash:int wallpapers:Vector<WallPaper> = account.WallPapers;
|
||||
|
||||
codeSettings#302f59f3 flags:# allow_flashcall:flags.0?true current_number:flags.1?true app_hash_persistent:flags.2?true app_hash:flags.3?string = CodeSettings;
|
||||
|
||||
wallPaperSettings#a12f40b8 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int intensity:flags.3?int = WallPaperSettings;
|
||||
|
||||
autoDownloadSettings#d246fd47 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true photo_size_max:int video_size_max:int file_size_max:int = AutoDownloadSettings;
|
||||
|
||||
account.autoDownloadSettings#63cacf26 low:AutoDownloadSettings medium:AutoDownloadSettings high:AutoDownloadSettings = account.AutoDownloadSettings;
|
||||
|
||||
emojiKeyword#d5b3b9f9 keyword:string emoticons:Vector<string> = EmojiKeyword;
|
||||
emojiKeywordDeleted#236df622 keyword:string emoticons:Vector<string> = EmojiKeyword;
|
||||
|
||||
emojiKeywordsDifference#5cc761bd lang_code:string from_version:int version:int keywords:Vector<EmojiKeyword> = EmojiKeywordsDifference;
|
||||
|
||||
emojiURL#a575739d url:string = EmojiURL;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@@ -1052,7 +1141,7 @@ invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
|
||||
invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X;
|
||||
invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
|
||||
|
||||
auth.sendCode#86aef0ec flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool api_id:int api_hash:string = auth.SentCode;
|
||||
auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
|
||||
auth.signUp#1b067634 phone_number:string phone_code_hash:string phone_code:string first_name:string last_name:string = auth.Authorization;
|
||||
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
|
||||
auth.logOut#5717da40 = Bool;
|
||||
@@ -1075,7 +1164,7 @@ account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
||||
account.resetNotifySettings#db7e1747 = Bool;
|
||||
account.updateProfile#78515775 flags:# first_name:flags.0?string last_name:flags.1?string about:flags.2?string = User;
|
||||
account.updateStatus#6628562c offline:Bool = Bool;
|
||||
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
|
||||
account.getWallPapers#aabb1763 hash:int = account.WallPapers;
|
||||
account.reportPeer#ae189d5f peer:InputPeer reason:ReportReason = Bool;
|
||||
account.checkUsername#2714d86c username:string = Bool;
|
||||
account.updateUsername#3e0bdd7c username:string = User;
|
||||
@@ -1084,7 +1173,7 @@ account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> =
|
||||
account.deleteAccount#418d4e0b reason:string = Bool;
|
||||
account.getAccountTTL#8fc711d = AccountDaysTTL;
|
||||
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
|
||||
account.sendChangePhoneCode#8e57deb flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode;
|
||||
account.sendChangePhoneCode#82574ae5 phone_number:string settings:CodeSettings = auth.SentCode;
|
||||
account.changePhone#70c32edb phone_number:string phone_code_hash:string phone_code:string = User;
|
||||
account.updateDeviceLocked#38df3532 period:int = Bool;
|
||||
account.getAuthorizations#e320c158 = account.Authorizations;
|
||||
@@ -1092,7 +1181,7 @@ account.resetAuthorization#df77f3bc hash:long = Bool;
|
||||
account.getPassword#548a30f5 = account.Password;
|
||||
account.getPasswordSettings#9cd4eaf9 password:InputCheckPasswordSRP = account.PasswordSettings;
|
||||
account.updatePasswordSettings#a59b102f password:InputCheckPasswordSRP new_settings:account.PasswordInputSettings = Bool;
|
||||
account.sendConfirmPhoneCode#1516d7bd flags:# allow_flashcall:flags.0?true hash:string current_number:flags.0?Bool = auth.SentCode;
|
||||
account.sendConfirmPhoneCode#1b3faa88 hash:string settings:CodeSettings = auth.SentCode;
|
||||
account.confirmPhone#5f2178c3 phone_code_hash:string phone_code:string = Bool;
|
||||
account.getTmpPassword#449e0b51 password:InputCheckPasswordSRP period:int = account.TmpPassword;
|
||||
account.getWebAuthorizations#182e6d6f = account.WebAuthorizations;
|
||||
@@ -1104,27 +1193,40 @@ account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long =
|
||||
account.deleteSecureValue#b880bc4b types:Vector<SecureValueType> = Bool;
|
||||
account.getAuthorizationForm#b86ba8e1 bot_id:int scope:string public_key:string = account.AuthorizationForm;
|
||||
account.acceptAuthorization#e7027c94 bot_id:int scope:string public_key:string value_hashes:Vector<SecureValueHash> credentials:SecureCredentialsEncrypted = Bool;
|
||||
account.sendVerifyPhoneCode#823380b4 flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode;
|
||||
account.sendVerifyPhoneCode#a5a356f9 phone_number:string settings:CodeSettings = auth.SentCode;
|
||||
account.verifyPhone#4dd3a7f6 phone_number:string phone_code_hash:string phone_code:string = Bool;
|
||||
account.sendVerifyEmailCode#7011509f email:string = account.SentEmailCode;
|
||||
account.verifyEmail#ecba39db email:string code:string = Bool;
|
||||
account.initTakeoutSession#f05b4804 flags:# contacts:flags.0?true message_users:flags.1?true message_chats:flags.2?true message_megagroups:flags.3?true message_channels:flags.4?true files:flags.5?true file_max_size:flags.5?int = account.Takeout;
|
||||
account.finishTakeoutSession#1d2652ee flags:# success:flags.0?true = Bool;
|
||||
account.confirmPasswordEmail#8fdf1920 code:string = Bool;
|
||||
account.resendPasswordEmail#7a7f2a15 = Bool;
|
||||
account.cancelPasswordEmail#c1cbd5b6 = Bool;
|
||||
account.getContactSignUpNotification#9f07c728 = Bool;
|
||||
account.setContactSignUpNotification#cff43f61 silent:Bool = Bool;
|
||||
account.getNotifyExceptions#53577479 flags:# compare_sound:flags.1?true peer:flags.0?InputNotifyPeer = Updates;
|
||||
account.getWallPaper#fc8ddbea wallpaper:InputWallPaper = WallPaper;
|
||||
account.uploadWallPaper#dd853661 file:InputFile mime_type:string settings:WallPaperSettings = WallPaper;
|
||||
account.saveWallPaper#6c5a5b37 wallpaper:InputWallPaper unsave:Bool settings:WallPaperSettings = Bool;
|
||||
account.installWallPaper#feed5769 wallpaper:InputWallPaper settings:WallPaperSettings = Bool;
|
||||
account.resetWallPapers#bb3b9804 = Bool;
|
||||
account.getAutoDownloadSettings#56da0b3f = account.AutoDownloadSettings;
|
||||
account.saveAutoDownloadSettings#76f36233 flags:# low:flags.0?true high:flags.1?true settings:AutoDownloadSettings = Bool;
|
||||
|
||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
|
||||
users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector<SecureValueError> = Bool;
|
||||
|
||||
contacts.getContactIDs#2caa4a42 hash:int = Vector<int>;
|
||||
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
|
||||
contacts.getContacts#c023849f hash:int = contacts.Contacts;
|
||||
contacts.importContacts#2c800be5 contacts:Vector<InputContact> = contacts.ImportedContacts;
|
||||
contacts.deleteContact#8e953744 id:InputUser = contacts.Link;
|
||||
contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool;
|
||||
contacts.deleteByPhones#1013fd9e phones:Vector<string> = Bool;
|
||||
contacts.block#332b49fc id:InputUser = Bool;
|
||||
contacts.unblock#e54100bd id:InputUser = Bool;
|
||||
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
|
||||
contacts.exportCard#84e53737 = Vector<int>;
|
||||
contacts.importCard#4fe196fe export_card:Vector<int> = User;
|
||||
contacts.search#11f812d8 q:string limit:int = contacts.Found;
|
||||
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
|
||||
contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers;
|
||||
@@ -1138,7 +1240,7 @@ messages.getDialogs#b098aee6 flags:# exclude_pinned:flags.0?true offset_date:int
|
||||
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.search#8614ef68 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
|
||||
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true peer:InputPeer max_id:int = messages.AffectedHistory;
|
||||
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int = messages.AffectedHistory;
|
||||
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
|
||||
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
||||
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
|
||||
@@ -1171,7 +1273,7 @@ messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages
|
||||
messages.getStickers#43d4f2c emoticon:string hash:int = messages.Stickers;
|
||||
messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
|
||||
messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
|
||||
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
|
||||
messages.exportChatInvite#df7534c peer:InputPeer = ExportedChatInvite;
|
||||
messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
|
||||
messages.importChatInvite#6c50051c hash:string = Updates;
|
||||
messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet;
|
||||
@@ -1179,7 +1281,6 @@ messages.installStickerSet#c78fe460 stickerset:InputStickerSet archived:Bool = m
|
||||
messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
|
||||
messages.startBot#e6df7378 bot:InputUser peer:InputPeer random_id:long start_param:string = Updates;
|
||||
messages.getMessagesViews#c4c8a55d peer:InputPeer id:Vector<int> increment:Bool = Vector<int>;
|
||||
messages.toggleChatAdmins#ec8bd9e1 chat_id:int enabled:Bool = Updates;
|
||||
messages.editChatAdmin#a9e69f2e chat_id:int user_id:InputUser is_admin:Bool = Bool;
|
||||
messages.migrateChat#15a3b8e3 chat_id:int = Updates;
|
||||
messages.searchGlobal#9e3cacb0 q:string offset_date:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||
@@ -1190,10 +1291,10 @@ messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs;
|
||||
messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
|
||||
messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
|
||||
messages.setInlineBotResults#eb5ea206 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM = Bool;
|
||||
messages.sendInlineBotResult#b16e06fe flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
|
||||
messages.sendInlineBotResult#b16e06fe flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
|
||||
messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
|
||||
messages.editMessage#c000e4c8 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Updates;
|
||||
messages.editInlineBotMessage#adc3e828 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Bool;
|
||||
messages.editMessage#d116f31e flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
|
||||
messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Bool;
|
||||
messages.getBotCallbackAnswer#810a9fec flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes = messages.BotCallbackAnswer;
|
||||
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
|
||||
messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
|
||||
@@ -1233,6 +1334,16 @@ messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
||||
messages.markDialogUnread#c286d98f flags:# unread:flags.0?true peer:InputDialogPeer = Bool;
|
||||
messages.getDialogUnreadMarks#22e24e22 = Vector<DialogPeer>;
|
||||
messages.clearAllDrafts#7e58ee9c = Bool;
|
||||
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true peer:InputPeer id:int = Updates;
|
||||
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
|
||||
messages.getPollResults#73bb643b peer:InputPeer msg_id:int = Updates;
|
||||
messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines;
|
||||
messages.getStatsURL#812c2ae6 flags:# dark:flags.0?true peer:InputPeer params:string = StatsURL;
|
||||
messages.editChatAbout#def60797 peer:InputPeer about:string = Bool;
|
||||
messages.editChatDefaultBannedRights#a5866b41 peer:InputPeer banned_rights:ChatBannedRights = Updates;
|
||||
messages.getEmojiKeywords#35a0e062 lang_code:string = EmojiKeywordsDifference;
|
||||
messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference;
|
||||
messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
@@ -1255,7 +1366,6 @@ upload.getFileHashes#c7025931 location:InputFileLocation offset:int = Vector<Fil
|
||||
help.getConfig#c4f9186b = Config;
|
||||
help.getNearestDc#1fb33026 = NearestDc;
|
||||
help.getAppUpdate#522d5a7d source:string = help.AppUpdate;
|
||||
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
|
||||
help.getInviteText#4d392343 = help.InviteText;
|
||||
help.getSupport#9cdf08cd = help.Support;
|
||||
help.getAppChangelog#9010ef6f prev_app_version:string = Updates;
|
||||
@@ -1266,7 +1376,12 @@ help.getProxyData#3d7758e1 = help.ProxyData;
|
||||
help.getTermsOfServiceUpdate#2ca51fd1 = help.TermsOfServiceUpdate;
|
||||
help.acceptTermsOfService#ee72f79a id:DataJSON = Bool;
|
||||
help.getDeepLinkInfo#3fedc75f path:string = help.DeepLinkInfo;
|
||||
help.getAppConfig#98914110 = JSONValue;
|
||||
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
|
||||
help.getPassportConfig#c661ad08 hash:int = help.PassportConfig;
|
||||
help.getSupportName#d360e72c = help.SupportName;
|
||||
help.getUserInfo#38a08d3 user_id:InputUser = help.UserInfo;
|
||||
help.editUserInfo#66b91b70 user_id:InputUser message:string entities:Vector<MessageEntity> = help.UserInfo;
|
||||
|
||||
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
||||
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
||||
@@ -1278,8 +1393,7 @@ channels.getParticipant#546dd7a6 channel:InputChannel user_id:InputUser = channe
|
||||
channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;
|
||||
channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull;
|
||||
channels.createChannel#f4893d7f flags:# broadcast:flags.0?true megagroup:flags.1?true title:string about:string = Updates;
|
||||
channels.editAbout#13e27f1e channel:InputChannel about:string = Bool;
|
||||
channels.editAdmin#20b88214 channel:InputChannel user_id:InputUser admin_rights:ChannelAdminRights = Updates;
|
||||
channels.editAdmin#70f893ba channel:InputChannel user_id:InputUser admin_rights:ChatAdminRights = Updates;
|
||||
channels.editTitle#566decd0 channel:InputChannel title:string = Updates;
|
||||
channels.editPhoto#f12e57c9 channel:InputChannel photo:InputChatPhoto = Updates;
|
||||
channels.checkUsername#10e6bd2c channel:InputChannel username:string = Bool;
|
||||
@@ -1287,14 +1401,11 @@ channels.updateUsername#3514b3de channel:InputChannel username:string = Bool;
|
||||
channels.joinChannel#24b524c5 channel:InputChannel = Updates;
|
||||
channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
|
||||
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
|
||||
channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite;
|
||||
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
||||
channels.toggleInvites#49609307 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.exportMessageLink#ceb77163 channel:InputChannel id:int grouped:Bool = ExportedMessageLink;
|
||||
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
|
||||
channels.getAdminedPublicChannels#8d8d82d7 = messages.Chats;
|
||||
channels.editBanned#bfd915cd channel:InputChannel user_id:InputUser banned_rights:ChannelBannedRights = Updates;
|
||||
channels.editBanned#72796912 channel:InputChannel user_id:InputUser banned_rights:ChatBannedRights = Updates;
|
||||
channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector<InputUser> max_id:long min_id:long limit:int = channels.AdminLogResults;
|
||||
channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet = Bool;
|
||||
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
|
||||
@@ -1323,12 +1434,13 @@ phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtoc
|
||||
phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||
phone.receivedCall#17d54f61 peer:InputPhoneCall = Bool;
|
||||
phone.discardCall#78d413a6 peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates;
|
||||
phone.setCallRating#1c536a34 peer:InputPhoneCall rating:int comment:string = Updates;
|
||||
phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhoneCall rating:int comment:string = Updates;
|
||||
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
|
||||
|
||||
langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference;
|
||||
langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector<string> = Vector<LangPackString>;
|
||||
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
|
||||
langpack.getDifference#cd984aa5 lang_pack:string lang_code:string from_version:int = LangPackDifference;
|
||||
langpack.getLanguages#42c6978f lang_pack:string = Vector<LangPackLanguage>;
|
||||
langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLanguage;
|
||||
|
||||
// LAYER 86
|
||||
// LAYER 97
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="1.4.4.0" />
|
||||
Version="1.6.2.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||
|
||||
@@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,4,4,0
|
||||
PRODUCTVERSION 1,4,4,0
|
||||
FILEVERSION 1,6,2,0
|
||||
PRODUCTVERSION 1,6,2,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -52,10 +52,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||
VALUE "FileDescription", "Telegram Desktop"
|
||||
VALUE "FileVersion", "1.4.4.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2018"
|
||||
VALUE "FileVersion", "1.6.2.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2019"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "1.4.4.0"
|
||||
VALUE "ProductVersion", "1.6.2.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,4,4,0
|
||||
PRODUCTVERSION 1,4,4,0
|
||||
FILEVERSION 1,6,2,0
|
||||
PRODUCTVERSION 1,6,2,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -43,10 +43,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||
VALUE "FileDescription", "Telegram Desktop Updater"
|
||||
VALUE "FileVersion", "1.4.4.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2018"
|
||||
VALUE "FileVersion", "1.6.2.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2019"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "1.4.4.0"
|
||||
VALUE "ProductVersion", "1.6.2.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -7,9 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
#include <windows.h>
|
||||
#ifdef small
|
||||
#undef small
|
||||
#endif // small
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4091)
|
||||
#include <DbgHelp.h>
|
||||
|
||||
@@ -6,6 +6,7 @@ For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include <sys/xattr.h>
|
||||
|
||||
NSString *appName = @"Telegram.app";
|
||||
NSString *appDir = nil;
|
||||
@@ -44,6 +45,20 @@ void writeLog(NSString *msg) {
|
||||
[_logFile synchronizeFile];
|
||||
}
|
||||
|
||||
void RemoveQuarantineAttribute(NSString *path) {
|
||||
const char *kQuarantineAttribute = "com.apple.quarantine";
|
||||
|
||||
writeLog([@"Removing quarantine: " stringByAppendingString:path]);
|
||||
removexattr([path fileSystemRepresentation], kQuarantineAttribute, 0);
|
||||
}
|
||||
|
||||
void RemoveQuarantineFromBundle(NSString *path) {
|
||||
RemoveQuarantineAttribute(path);
|
||||
RemoveQuarantineAttribute([path stringByAppendingString:@"/Contents/MacOS/Telegram"]);
|
||||
RemoveQuarantineAttribute([path stringByAppendingString:@"/Contents/Helpers/crashpad_handler"]);
|
||||
RemoveQuarantineAttribute([path stringByAppendingString:@"/Contents/Frameworks/Updater"]);
|
||||
}
|
||||
|
||||
void delFolder() {
|
||||
writeLog([@"Fully clearing old path: " stringByAppendingString:[workDir stringByAppendingString:@"tupdates/ready"]]);
|
||||
if (![[NSFileManager defaultManager] removeItemAtPath:[workDir stringByAppendingString:@"tupdates/ready"] error:nil]) {
|
||||
@@ -232,6 +247,9 @@ int main(int argc, const char * argv[]) {
|
||||
}
|
||||
|
||||
NSString *appPath = [[NSArray arrayWithObjects:appDir, appRealName, nil] componentsJoinedByString:@""];
|
||||
|
||||
RemoveQuarantineFromBundle(appPath);
|
||||
|
||||
NSMutableArray *args = [[NSMutableArray alloc] initWithObjects: @"-noupdate", nil];
|
||||
if (toSettings) [args addObject:@"-tosettings"];
|
||||
if (_debug) [args addObject:@"-debug"];
|
||||
@@ -248,18 +266,24 @@ int main(int argc, const char * argv[]) {
|
||||
[args addObject:workDir];
|
||||
}
|
||||
writeLog([[NSArray arrayWithObjects:@"Running application '", appPath, @"' with args '", [args componentsJoinedByString:@"' '"], @"'..", nil] componentsJoinedByString:@""]);
|
||||
NSError *error = nil;
|
||||
NSRunningApplication *result = [[NSWorkspace sharedWorkspace]
|
||||
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
NSError *error = nil;
|
||||
NSRunningApplication *result = [[NSWorkspace sharedWorkspace]
|
||||
launchApplicationAtURL:[NSURL fileURLWithPath:appPath]
|
||||
options:NSWorkspaceLaunchDefault
|
||||
configuration:[NSDictionary
|
||||
dictionaryWithObject:args
|
||||
forKey:NSWorkspaceLaunchConfigurationArguments]
|
||||
error:&error];
|
||||
if (!result) {
|
||||
if (result) {
|
||||
closeLog();
|
||||
return 0;
|
||||
}
|
||||
writeLog([[NSString stringWithFormat:@"Could not run application, error %ld: ", (long)[error code]] stringByAppendingString: error ? [error localizedDescription] : @"(nil)"]);
|
||||
usleep(200000);
|
||||
}
|
||||
closeLog();
|
||||
return result ? 0 : -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "base/timer.h"
|
||||
#include "base/flat_map.h"
|
||||
#include "base/flat_set.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "chat_helpers/stickers.h"
|
||||
#include "data/data_messages.h"
|
||||
@@ -24,6 +23,11 @@ enum class SendMediaType;
|
||||
struct FileLoadTo;
|
||||
class mtpFileLoader;
|
||||
|
||||
namespace Data {
|
||||
struct UpdatedFileReferences;
|
||||
class WallPaper;
|
||||
} // namespace Data
|
||||
|
||||
namespace InlineBots {
|
||||
class Result;
|
||||
} // namespace InlineBots
|
||||
@@ -43,14 +47,6 @@ struct CloudPasswordState;
|
||||
|
||||
namespace Api {
|
||||
|
||||
inline const MTPVector<MTPChat> *getChatsFromMessagesChats(const MTPmessages_Chats &chats) {
|
||||
switch (chats.type()) {
|
||||
case mtpc_messages_chats: return &chats.c_messages_chats().vchats;
|
||||
case mtpc_messages_chatsSlice: return &chats.c_messages_chatsSlice().vchats;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename IntRange>
|
||||
inline int32 CountHash(IntRange &&range) {
|
||||
uint32 acc = 0;
|
||||
@@ -62,7 +58,7 @@ inline int32 CountHash(IntRange &&range) {
|
||||
|
||||
} // namespace Api
|
||||
|
||||
class ApiWrap : private MTP::Sender, private base::Subscriber {
|
||||
class ApiWrap : public MTP::Sender, private base::Subscriber {
|
||||
public:
|
||||
ApiWrap(not_null<AuthSession*> session);
|
||||
|
||||
@@ -87,16 +83,22 @@ public:
|
||||
void requestDialogEntry(
|
||||
not_null<History*> history,
|
||||
Fn<void()> callback = nullptr);
|
||||
void requestDialogEntries(std::vector<not_null<History*>> histories);
|
||||
void dialogEntryApplied(not_null<History*> history);
|
||||
//void applyFeedSources(const MTPDchannels_feedSources &data); // #feed
|
||||
//void setFeedChannels(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// const std::vector<not_null<ChannelData*>> &channels);
|
||||
void changeDialogUnreadMark(not_null<History*> history, bool unread);
|
||||
//void changeDialogUnreadMark(not_null<Data::Feed*> feed, bool unread); // #feed
|
||||
void requestFakeChatListMessage(not_null<History*> history);
|
||||
|
||||
void requestFullPeer(PeerData *peer);
|
||||
void requestPeer(PeerData *peer);
|
||||
void requestWallPaper(
|
||||
const QString &slug,
|
||||
Fn<void(const Data::WallPaper &)> done,
|
||||
Fn<void(const RPCError &)> fail);
|
||||
|
||||
void requestFullPeer(not_null<PeerData*> peer);
|
||||
void requestPeer(not_null<PeerData*> peer);
|
||||
void requestPeers(const QList<PeerData*> &peers);
|
||||
void requestLastParticipants(not_null<ChannelData*> channel);
|
||||
void requestBots(not_null<ChannelData*> channel);
|
||||
@@ -125,32 +127,52 @@ public:
|
||||
void requestTermsUpdate();
|
||||
void acceptTerms(bytes::const_span termsId);
|
||||
|
||||
void checkChatInvite(
|
||||
const QString &hash,
|
||||
FnMut<void(const MTPChatInvite &)> done,
|
||||
FnMut<void(const RPCError &)> fail);
|
||||
void importChatInvite(const QString &hash);
|
||||
|
||||
void requestChannelMembersForAdd(
|
||||
not_null<ChannelData*> channel,
|
||||
Fn<void(const MTPchannels_ChannelParticipants&)> callback);
|
||||
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
|
||||
void processFullPeer(UserData *user, const MTPUserFull &result);
|
||||
void processFullPeer(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPmessages_ChatFull &result);
|
||||
void processFullPeer(
|
||||
not_null<UserData*> user,
|
||||
const MTPUserFull &result);
|
||||
|
||||
void migrateChat(
|
||||
not_null<ChatData*> chat,
|
||||
FnMut<void(not_null<ChannelData*>)> done,
|
||||
FnMut<void(const RPCError &)> fail = nullptr);
|
||||
|
||||
void markMediaRead(const base::flat_set<not_null<HistoryItem*>> &items);
|
||||
void markMediaRead(not_null<HistoryItem*> item);
|
||||
|
||||
void requestSelfParticipant(ChannelData *channel);
|
||||
void requestSelfParticipant(not_null<ChannelData*> channel);
|
||||
void kickParticipant(not_null<ChatData*> chat, not_null<UserData*> user);
|
||||
void kickParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user,
|
||||
const MTPChannelBannedRights ¤tRights);
|
||||
const MTPChatBannedRights ¤tRights);
|
||||
void unblockParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user);
|
||||
void deleteAllFromUser(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> from);
|
||||
void saveDefaultRestrictions(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPChatBannedRights &rights,
|
||||
Fn<void(bool)> callback = nullptr);
|
||||
|
||||
void requestWebPageDelayed(WebPageData *page);
|
||||
void clearWebPageRequest(WebPageData *page);
|
||||
void clearWebPageRequests();
|
||||
|
||||
void requestAttachedStickerSets(not_null<PhotoData*> photo);
|
||||
void scheduleStickerSetRequest(uint64 setId, uint64 access);
|
||||
void requestStickerSets();
|
||||
void saveStickerSets(
|
||||
@@ -189,7 +211,12 @@ public:
|
||||
const MTPUserStatus &status,
|
||||
int currentOnlineTill);
|
||||
|
||||
void clearHistory(not_null<PeerData*> peer);
|
||||
void clearHistory(not_null<PeerData*> peer, bool revoke);
|
||||
void deleteConversation(not_null<PeerData*> peer, bool revoke);
|
||||
void deleteMessages(
|
||||
not_null<PeerData*> peer,
|
||||
const QVector<MTPint> &ids,
|
||||
bool revoke);
|
||||
|
||||
base::Observable<PeerData*> &fullPeerUpdated() {
|
||||
return _fullPeerUpdated;
|
||||
@@ -203,12 +230,9 @@ public:
|
||||
void jumpToDate(Dialogs::Key chat, const QDate &date);
|
||||
|
||||
void preloadEnoughUnreadMentions(not_null<History*> history);
|
||||
void checkForUnreadMentions(const base::flat_set<MsgId> &possiblyReadMentions, ChannelData *channel = nullptr);
|
||||
|
||||
void editChatAdmins(
|
||||
not_null<ChatData*> chat,
|
||||
bool adminsEnabled,
|
||||
base::flat_set<not_null<UserData*>> &&admins);
|
||||
void checkForUnreadMentions(
|
||||
const base::flat_set<MsgId> &possiblyReadMentions,
|
||||
ChannelData *channel = nullptr);
|
||||
|
||||
using SliceType = Data::LoadDirection;
|
||||
void requestSharedMedia(
|
||||
@@ -254,6 +278,9 @@ public:
|
||||
int availableCount,
|
||||
const QVector<MTPChannelParticipant> &list)> callbackList,
|
||||
Fn<void()> callbackNotModified = nullptr);
|
||||
void addChatParticipants(
|
||||
not_null<PeerData*> peer,
|
||||
const std::vector<not_null<UserData*>> &users);
|
||||
|
||||
struct SendOptions {
|
||||
SendOptions(not_null<History*> history);
|
||||
@@ -323,6 +350,7 @@ public:
|
||||
bool handleSupportSwitch = false;
|
||||
};
|
||||
void sendMessage(MessageToSend &&message);
|
||||
void sendBotStart(not_null<UserData*> bot, PeerData *chat = nullptr);
|
||||
void sendInlineResult(
|
||||
not_null<UserData*> bot,
|
||||
not_null<InlineBots::Result*> data,
|
||||
@@ -343,6 +371,11 @@ public:
|
||||
rpl::producer<Core::CloudPasswordState> passwordState() const;
|
||||
std::optional<Core::CloudPasswordState> passwordStateCurrent() const;
|
||||
|
||||
void reloadContactSignupSilent();
|
||||
rpl::producer<bool> contactSignupSilent() const;
|
||||
std::optional<bool> contactSignupSilentCurrent() const;
|
||||
void saveContactSignupSilent(bool silent);
|
||||
|
||||
void saveSelfBio(const QString &text, FnMut<void()> done);
|
||||
|
||||
struct Privacy {
|
||||
@@ -350,6 +383,9 @@ public:
|
||||
LastSeen,
|
||||
Calls,
|
||||
Invites,
|
||||
CallsPeer2Peer,
|
||||
Forwards,
|
||||
ProfilePhoto,
|
||||
};
|
||||
enum class Option {
|
||||
Everyone,
|
||||
@@ -369,6 +405,17 @@ public:
|
||||
rpl::producer<int> selfDestructValue() const;
|
||||
void saveSelfDestruct(int days);
|
||||
|
||||
void createPoll(
|
||||
const PollData &data,
|
||||
const SendOptions &options,
|
||||
FnMut<void()> done,
|
||||
FnMut<void(const RPCError &error)> fail);
|
||||
void sendPollVotes(
|
||||
FullMsgId itemId,
|
||||
const std::vector<QByteArray> &options);
|
||||
void closePoll(FullMsgId itemId);
|
||||
void reloadPollResults(not_null<HistoryItem*> item);
|
||||
|
||||
~ApiWrap();
|
||||
|
||||
private:
|
||||
@@ -383,13 +430,9 @@ private:
|
||||
struct StickersByEmoji {
|
||||
std::vector<not_null<DocumentData*>> list;
|
||||
int32 hash = 0;
|
||||
TimeMs received = 0;
|
||||
crl::time received = 0;
|
||||
};
|
||||
|
||||
using SimpleFileLocationId = Data::SimpleFileLocationId;
|
||||
using DocumentFileLocationId = Data::DocumentFileLocationId;
|
||||
using FileLocationId = Data::FileLocationId;
|
||||
|
||||
void updatesReceived(const MTPUpdates &updates);
|
||||
void checkQuitPreventFinished();
|
||||
|
||||
@@ -404,13 +447,18 @@ private:
|
||||
QVector<MTPInputMessage> collectMessageIds(const MessageDataRequests &requests);
|
||||
MessageDataRequests *messageDataRequests(ChannelData *channel, bool onlyExisting = false);
|
||||
void applyPeerDialogs(const MTPmessages_PeerDialogs &dialogs);
|
||||
void historyDialogEntryApplied(not_null<History*> history);
|
||||
void applyFeedDialogs(
|
||||
not_null<Data::Feed*> feed,
|
||||
const MTPmessages_Dialogs &dialogs);
|
||||
|
||||
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
|
||||
void gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req);
|
||||
void gotChatFull(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPmessages_ChatFull &result,
|
||||
mtpRequestId req);
|
||||
void gotUserFull(
|
||||
not_null<UserData*> user,
|
||||
const MTPUserFull &result,
|
||||
mtpRequestId req);
|
||||
void applyLastParticipantsList(
|
||||
not_null<ChannelData*> channel,
|
||||
int availableCount,
|
||||
@@ -454,9 +502,6 @@ private:
|
||||
void requestSavedGifs(TimeId now);
|
||||
void readFeaturedSets();
|
||||
|
||||
void cancelEditChatAdmins(not_null<ChatData*> chat);
|
||||
void saveChatAdmins(not_null<ChatData*> chat);
|
||||
void sendSaveChatAdminsRequests(not_null<ChatData*> chat);
|
||||
void refreshChannelAdmins(
|
||||
not_null<ChannelData*> channel,
|
||||
const QVector<MTPChannelParticipant> &participants);
|
||||
@@ -500,6 +545,10 @@ private:
|
||||
UserId userId,
|
||||
const SendOptions &options);
|
||||
|
||||
void deleteHistory(
|
||||
not_null<PeerData*> peer,
|
||||
bool justClear,
|
||||
bool revoke);
|
||||
void sendReadRequest(not_null<PeerData*> peer, MsgId upTo);
|
||||
int applyAffectedHistory(
|
||||
not_null<PeerData*> peer,
|
||||
@@ -560,6 +609,13 @@ private:
|
||||
|
||||
void setSelfDestructDays(int days);
|
||||
|
||||
void migrateDone(
|
||||
not_null<PeerData*> peer,
|
||||
not_null<ChannelData*> channel);
|
||||
void migrateFail(not_null<PeerData*> peer, const RPCError &error);
|
||||
|
||||
void sendDialogRequests();
|
||||
|
||||
not_null<AuthSession*> _session;
|
||||
|
||||
MessageDataRequests _messageDataRequests;
|
||||
@@ -588,7 +644,11 @@ private:
|
||||
not_null<UserData*>>;
|
||||
base::flat_map<KickRequest, mtpRequestId> _kickRequests;
|
||||
|
||||
QMap<ChannelData*, mtpRequestId> _selfParticipantRequests;
|
||||
base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
mtpRequestId> _defaultRestrictionsRequests;
|
||||
|
||||
base::flat_set<not_null<ChannelData*>> _selfParticipantRequests;
|
||||
|
||||
base::flat_map<
|
||||
not_null<ChannelData*>,
|
||||
@@ -630,19 +690,13 @@ private:
|
||||
base::flat_map<
|
||||
not_null<History*>,
|
||||
std::vector<Fn<void()>>> _dialogRequests;
|
||||
base::flat_map<
|
||||
not_null<History*>,
|
||||
std::vector<Fn<void()>>> _dialogRequestsPending;
|
||||
base::flat_set<not_null<History*>> _fakeChatListRequests;
|
||||
|
||||
base::flat_map<not_null<History*>, mtpRequestId> _unreadMentionsRequests;
|
||||
|
||||
base::flat_map<
|
||||
not_null<ChatData*>,
|
||||
mtpRequestId> _chatAdminsEnabledRequests;
|
||||
base::flat_map<
|
||||
not_null<ChatData*>,
|
||||
base::flat_set<not_null<UserData*>>> _chatAdminsToSave;
|
||||
base::flat_map<
|
||||
not_null<ChatData*>,
|
||||
base::flat_set<mtpRequestId>> _chatAdminsSaveRequests;
|
||||
|
||||
base::flat_map<std::tuple<
|
||||
not_null<PeerData*>,
|
||||
SharedMediaType,
|
||||
@@ -686,7 +740,7 @@ private:
|
||||
|
||||
rpl::event_stream<uint64> _stickerSetInstalled;
|
||||
|
||||
base::flat_map<not_null<Data::Feed*>, TimeMs> _feedReadsDelayed;
|
||||
base::flat_map<not_null<Data::Feed*>, crl::time> _feedReadsDelayed;
|
||||
base::flat_map<not_null<Data::Feed*>, mtpRequestId> _feedReadRequests;
|
||||
base::Timer _feedReadTimer;
|
||||
|
||||
@@ -704,9 +758,21 @@ private:
|
||||
|
||||
mtpRequestId _deepLinkInfoRequestId = 0;
|
||||
|
||||
TimeMs _termsUpdateSendAt = 0;
|
||||
crl::time _termsUpdateSendAt = 0;
|
||||
mtpRequestId _termsUpdateRequestId = 0;
|
||||
|
||||
mtpRequestId _checkInviteRequestId = 0;
|
||||
FnMut<void(const MTPChatInvite &result)> _checkInviteDone;
|
||||
FnMut<void(const RPCError &error)> _checkInviteFail;
|
||||
|
||||
struct MigrateCallbacks {
|
||||
FnMut<void(not_null<ChannelData*>)> done;
|
||||
FnMut<void(const RPCError&)> fail;
|
||||
};
|
||||
base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
std::vector<MigrateCallbacks>> _migrateCallbacks;
|
||||
|
||||
std::vector<FnMut<void(const MTPUser &)>> _supportContactCallbacks;
|
||||
|
||||
base::flat_map<FullMsgId, not_null<PeerData*>> _peerPhotoUploads;
|
||||
@@ -727,4 +793,19 @@ private:
|
||||
std::optional<int> _selfDestructDays;
|
||||
rpl::event_stream<int> _selfDestructChanges;
|
||||
|
||||
base::flat_map<FullMsgId, mtpRequestId> _pollVotesRequestIds;
|
||||
base::flat_map<FullMsgId, mtpRequestId> _pollCloseRequestIds;
|
||||
base::flat_map<FullMsgId, mtpRequestId> _pollReloadRequestIds;
|
||||
|
||||
mtpRequestId _wallPaperRequestId = 0;
|
||||
QString _wallPaperSlug;
|
||||
Fn<void(const Data::WallPaper &)> _wallPaperDone;
|
||||
Fn<void(const RPCError &)> _wallPaperFail;
|
||||
|
||||
mtpRequestId _contactSignupSilentRequestId = 0;
|
||||
std::optional<bool> _contactSignupSilent;
|
||||
rpl::event_stream<bool> _contactSignupSilentChanges;
|
||||
|
||||
mtpRequestId _attachedStickerSetsRequestId = 0;
|
||||
|
||||
};
|
||||
|
||||
@@ -8,17 +8,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#pragma once
|
||||
|
||||
#include "data/data_types.h"
|
||||
#include "data/data_peer.h"
|
||||
|
||||
enum NewMessageType : char;
|
||||
class Messenger;
|
||||
enum class ImageRoundRadius;
|
||||
class MainWindow;
|
||||
class MainWidget;
|
||||
class LocationCoords;
|
||||
struct LocationData;
|
||||
class HistoryItem;
|
||||
class History;
|
||||
class Histories;
|
||||
namespace HistoryView {
|
||||
class Element;
|
||||
} // namespace HistoryView
|
||||
@@ -39,6 +35,8 @@ enum RoundCorners {
|
||||
SelectedOverlayLargeCorners,
|
||||
DateCorners,
|
||||
DateSelectedCorners,
|
||||
OverviewVideoCorners,
|
||||
OverviewVideoSelectedCorners,
|
||||
ForwardCorners,
|
||||
MediaviewSaveCorners,
|
||||
EmojiHoverCorners,
|
||||
@@ -68,16 +66,6 @@ namespace App {
|
||||
|
||||
QString formatPhone(QString phone);
|
||||
|
||||
UserData *feedUser(const MTPUser &user);
|
||||
UserData *feedUsers(const MTPVector<MTPUser> &users); // returns last user
|
||||
PeerData *feedChat(const MTPChat &chat);
|
||||
PeerData *feedChats(const MTPVector<MTPChat> &chats); // returns last chat
|
||||
|
||||
void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos);
|
||||
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d);
|
||||
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d);
|
||||
void feedChatAdmins(const MTPDupdateChatAdmins &d);
|
||||
void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d);
|
||||
bool checkEntitiesAndViewsUpdate(const MTPDmessage &m); // returns true if item found and it is not detached
|
||||
void updateEditedMessage(const MTPMessage &m);
|
||||
void addSavedGif(DocumentData *doc);
|
||||
@@ -91,71 +79,13 @@ namespace App {
|
||||
|
||||
ImagePtr image(const MTPPhotoSize &size);
|
||||
|
||||
PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded);
|
||||
inline UserData *user(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||
return asUser(peer(id, restriction));
|
||||
}
|
||||
inline ChatData *chat(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||
return asChat(peer(id, restriction));
|
||||
}
|
||||
inline ChannelData *channel(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||
return asChannel(peer(id, restriction));
|
||||
}
|
||||
inline UserData *user(UserId userId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||
return asUser(peer(peerFromUser(userId), restriction));
|
||||
}
|
||||
inline ChatData *chat(ChatId chatId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||
return asChat(peer(peerFromChat(chatId), restriction));
|
||||
}
|
||||
inline ChannelData *channel(ChannelId channelId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||
return asChannel(peer(peerFromChannel(channelId), restriction));
|
||||
}
|
||||
inline PeerData *peerLoaded(const PeerId &id) {
|
||||
return peer(id, PeerData::FullLoaded);
|
||||
}
|
||||
inline UserData *userLoaded(const PeerId &id) {
|
||||
return user(id, PeerData::FullLoaded);
|
||||
}
|
||||
inline ChatData *chatLoaded(const PeerId &id) {
|
||||
return chat(id, PeerData::FullLoaded);
|
||||
}
|
||||
inline ChannelData *channelLoaded(const PeerId &id) {
|
||||
return channel(id, PeerData::FullLoaded);
|
||||
}
|
||||
inline UserData *userLoaded(UserId userId) {
|
||||
return user(userId, PeerData::FullLoaded);
|
||||
}
|
||||
inline ChatData *chatLoaded(ChatId chatId) {
|
||||
return chat(chatId, PeerData::FullLoaded);
|
||||
}
|
||||
inline ChannelData *channelLoaded(ChannelId channelId) {
|
||||
return channel(channelId, PeerData::FullLoaded);
|
||||
}
|
||||
void enumerateUsers(Fn<void(not_null<UserData*>)> action);
|
||||
void enumerateChatsChannels(
|
||||
Fn<void(not_null<PeerData*>)> action);
|
||||
[[nodiscard]] QString peerName(const PeerData *peer, bool forDialogs = false);
|
||||
|
||||
PeerData *peerByName(const QString &username);
|
||||
QString peerName(const PeerData *peer, bool forDialogs = false);
|
||||
|
||||
LocationData *location(const LocationCoords &coords);
|
||||
void forgetMedia();
|
||||
|
||||
Histories &histories();
|
||||
not_null<History*> history(const PeerId &peer);
|
||||
History *historyLoaded(const PeerId &peer);
|
||||
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
|
||||
inline not_null<History*> history(const PeerData *peer) {
|
||||
Assert(peer != nullptr);
|
||||
return history(peer->id);
|
||||
}
|
||||
inline History *historyLoaded(const PeerData *peer) {
|
||||
return peer ? historyLoaded(peer->id) : nullptr;
|
||||
}
|
||||
inline HistoryItem *histItemById(const ChannelData *channel, MsgId itemId) {
|
||||
return histItemById(channel ? peerToChannel(channel->id) : 0, itemId);
|
||||
}
|
||||
inline HistoryItem *histItemById(const FullMsgId &msgId) {
|
||||
[[nodiscard]] HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
|
||||
[[nodiscard]] HistoryItem *histItemById(
|
||||
const ChannelData *channel,
|
||||
MsgId itemId);
|
||||
[[nodiscard]] inline HistoryItem *histItemById(const FullMsgId &msgId) {
|
||||
return histItemById(msgId.channel, msgId.msg);
|
||||
}
|
||||
void historyRegItem(not_null<HistoryItem*> item);
|
||||
@@ -187,13 +117,9 @@ namespace App {
|
||||
|
||||
const style::font &monofont();
|
||||
|
||||
void clearHistories();
|
||||
|
||||
void initMedia();
|
||||
void deinitMedia();
|
||||
|
||||
void checkImageCacheSize();
|
||||
|
||||
enum LaunchState {
|
||||
Launched = 0,
|
||||
QuitRequested = 1,
|
||||
@@ -228,14 +154,4 @@ namespace App {
|
||||
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
|
||||
}
|
||||
|
||||
struct WallPaper {
|
||||
WallPaper(int32 id, ImagePtr thumb, ImagePtr full) : id(id), thumb(thumb), full(full) {
|
||||
}
|
||||
int32 id;
|
||||
ImagePtr thumb;
|
||||
ImagePtr full;
|
||||
};
|
||||
typedef QList<WallPaper> WallPapers;
|
||||
DeclareSetting(WallPapers, ServerBackgrounds);
|
||||
|
||||
};
|
||||
|
||||
@@ -1,501 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "application.h"
|
||||
|
||||
#include "platform/platform_specific.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "core/crash_reports.h"
|
||||
#include "messenger.h"
|
||||
#include "base/timer.h"
|
||||
#include "base/concurrent_timer.h"
|
||||
#include "base/qthelp_url.h"
|
||||
#include "base/qthelp_regex.h"
|
||||
#include "core/update_checker.h"
|
||||
#include "core/crash_report_window.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kEmptyPidForCommandResponse = 0ULL;
|
||||
|
||||
QChar _toHex(ushort v) {
|
||||
v = v & 0x000F;
|
||||
return QChar::fromLatin1((v >= 10) ? ('a' + (v - 10)) : ('0' + v));
|
||||
}
|
||||
ushort _fromHex(QChar c) {
|
||||
return ((c.unicode() >= uchar('a')) ? (c.unicode() - uchar('a') + 10) : (c.unicode() - uchar('0'))) & 0x000F;
|
||||
}
|
||||
|
||||
QString _escapeTo7bit(const QString &str) {
|
||||
QString result;
|
||||
result.reserve(str.size() * 2);
|
||||
for (int i = 0, l = str.size(); i != l; ++i) {
|
||||
QChar ch(str.at(i));
|
||||
ushort uch(ch.unicode());
|
||||
if (uch < 32 || uch > 127 || uch == ushort(uchar('%'))) {
|
||||
result.append('%').append(_toHex(uch >> 12)).append(_toHex(uch >> 8)).append(_toHex(uch >> 4)).append(_toHex(uch));
|
||||
} else {
|
||||
result.append(ch);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString _escapeFrom7bit(const QString &str) {
|
||||
QString result;
|
||||
result.reserve(str.size());
|
||||
for (int i = 0, l = str.size(); i != l; ++i) {
|
||||
QChar ch(str.at(i));
|
||||
if (ch == QChar::fromLatin1('%') && i + 4 < l) {
|
||||
result.append(QChar(ushort((_fromHex(str.at(i + 1)) << 12) | (_fromHex(str.at(i + 2)) << 8) | (_fromHex(str.at(i + 3)) << 4) | _fromHex(str.at(i + 4)))));
|
||||
i += 4;
|
||||
} else {
|
||||
result.append(ch);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool InternalPassportLink(const QString &url) {
|
||||
const auto urlTrimmed = url.trimmed();
|
||||
if (!urlTrimmed.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
|
||||
return false;
|
||||
}
|
||||
const auto command = urlTrimmed.midRef(qstr("tg://").size());
|
||||
|
||||
using namespace qthelp;
|
||||
const auto matchOptions = RegExOption::CaseInsensitive;
|
||||
const auto authMatch = regex_match(
|
||||
qsl("^passport/?\\?(.+)(#|$)"),
|
||||
command,
|
||||
matchOptions);
|
||||
const auto usernameMatch = regex_match(
|
||||
qsl("^resolve/?\\?(.+)(#|$)"),
|
||||
command,
|
||||
matchOptions);
|
||||
const auto usernameValue = usernameMatch->hasMatch()
|
||||
? url_parse_params(
|
||||
usernameMatch->captured(1),
|
||||
UrlParamNameTransform::ToLower).value(qsl("domain"))
|
||||
: QString();
|
||||
const auto authLegacy = (usernameValue == qstr("telegrampassport"));
|
||||
return authMatch->hasMatch() || authLegacy;
|
||||
}
|
||||
|
||||
bool StartUrlRequiresActivate(const QString &url) {
|
||||
return Messenger::Instance().locked()
|
||||
? true
|
||||
: !InternalPassportLink(url);
|
||||
}
|
||||
|
||||
Application::Application(
|
||||
not_null<Core::Launcher*> launcher,
|
||||
int &argc,
|
||||
char **argv)
|
||||
: QApplication(argc, argv)
|
||||
, _launcher(launcher)
|
||||
, _updateChecker(Core::UpdaterDisabled()
|
||||
? nullptr
|
||||
: std::make_unique<Core::UpdateChecker>()) {
|
||||
const auto d = QFile::encodeName(QDir(cWorkingDir()).absolutePath());
|
||||
char h[33] = { 0 };
|
||||
hashMd5Hex(d.constData(), d.size(), h);
|
||||
#ifndef OS_MAC_STORE
|
||||
_localServerName = psServerPrefix() + h + '-' + cGUIDStr();
|
||||
#else // OS_MAC_STORE
|
||||
h[4] = 0; // use only first 4 chars
|
||||
_localServerName = psServerPrefix() + h;
|
||||
#endif // OS_MAC_STORE
|
||||
|
||||
connect(&_localSocket, SIGNAL(connected()), this, SLOT(socketConnected()));
|
||||
connect(&_localSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
|
||||
connect(&_localSocket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(socketError(QLocalSocket::LocalSocketError)));
|
||||
connect(&_localSocket, SIGNAL(bytesWritten(qint64)), this, SLOT(socketWritten(qint64)));
|
||||
connect(&_localSocket, SIGNAL(readyRead()), this, SLOT(socketReading()));
|
||||
connect(&_localServer, SIGNAL(newConnection()), this, SLOT(newInstanceConnected()));
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(startApplication()));
|
||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication()));
|
||||
|
||||
if (cManyInstance()) {
|
||||
LOG(("Many instance allowed, starting..."));
|
||||
singleInstanceChecked();
|
||||
} else {
|
||||
LOG(("Connecting local socket to %1...").arg(_localServerName));
|
||||
_localSocket.connectToServer(_localServerName);
|
||||
}
|
||||
}
|
||||
|
||||
Application::~Application() = default;
|
||||
|
||||
bool Application::event(QEvent *e) {
|
||||
if (e->type() == QEvent::Close) {
|
||||
App::quit();
|
||||
}
|
||||
return QApplication::event(e);
|
||||
}
|
||||
|
||||
void Application::socketConnected() {
|
||||
LOG(("Socket connected, this is not the first application instance, sending show command..."));
|
||||
_secondInstance = true;
|
||||
|
||||
QString commands;
|
||||
const QStringList &lst(cSendPaths());
|
||||
for (QStringList::const_iterator i = lst.cbegin(), e = lst.cend(); i != e; ++i) {
|
||||
commands += qsl("SEND:") + _escapeTo7bit(*i) + ';';
|
||||
}
|
||||
if (!cStartUrl().isEmpty()) {
|
||||
commands += qsl("OPEN:") + _escapeTo7bit(cStartUrl()) + ';';
|
||||
} else {
|
||||
commands += qsl("CMD:show;");
|
||||
}
|
||||
|
||||
DEBUG_LOG(("Application Info: writing commands %1").arg(commands));
|
||||
_localSocket.write(commands.toLatin1());
|
||||
}
|
||||
|
||||
void Application::socketWritten(qint64/* bytes*/) {
|
||||
if (_localSocket.state() != QLocalSocket::ConnectedState) {
|
||||
LOG(("Socket is not connected %1").arg(_localSocket.state()));
|
||||
return;
|
||||
}
|
||||
if (_localSocket.bytesToWrite()) {
|
||||
return;
|
||||
}
|
||||
LOG(("Show command written, waiting response..."));
|
||||
}
|
||||
|
||||
void Application::socketReading() {
|
||||
if (_localSocket.state() != QLocalSocket::ConnectedState) {
|
||||
LOG(("Socket is not connected %1").arg(_localSocket.state()));
|
||||
return;
|
||||
}
|
||||
_localSocketReadData.append(_localSocket.readAll());
|
||||
if (QRegularExpression("RES:(\\d+);").match(_localSocketReadData).hasMatch()) {
|
||||
uint64 pid = _localSocketReadData.mid(4, _localSocketReadData.length() - 5).toULongLong();
|
||||
if (pid != kEmptyPidForCommandResponse) {
|
||||
psActivateProcess(pid);
|
||||
}
|
||||
LOG(("Show command response received, pid = %1, activating and quitting...").arg(pid));
|
||||
return App::quit();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::socketError(QLocalSocket::LocalSocketError e) {
|
||||
if (App::quitting()) return;
|
||||
|
||||
if (_secondInstance) {
|
||||
LOG(("Could not write show command, error %1, quitting...").arg(e));
|
||||
return App::quit();
|
||||
}
|
||||
|
||||
if (e == QLocalSocket::ServerNotFoundError) {
|
||||
LOG(("This is the only instance of Telegram, starting server and app..."));
|
||||
} else {
|
||||
LOG(("Socket connect error %1, starting server and app...").arg(e));
|
||||
}
|
||||
_localSocket.close();
|
||||
|
||||
// Local server does not work in WinRT build.
|
||||
#ifndef Q_OS_WINRT
|
||||
psCheckLocalSocket(_localServerName);
|
||||
|
||||
if (!_localServer.listen(_localServerName)) {
|
||||
LOG(("Failed to start listening to %1 server, error %2").arg(_localServerName).arg(int(_localServer.serverError())));
|
||||
return App::quit();
|
||||
}
|
||||
#endif // !Q_OS_WINRT
|
||||
|
||||
if (!Core::UpdaterDisabled()
|
||||
&& !cNoStartUpdate()
|
||||
&& Core::checkReadyUpdate()) {
|
||||
cSetRestartingUpdate(true);
|
||||
DEBUG_LOG(("Application Info: installing update instead of starting app..."));
|
||||
return App::quit();
|
||||
}
|
||||
|
||||
singleInstanceChecked();
|
||||
}
|
||||
|
||||
void Application::singleInstanceChecked() {
|
||||
if (cManyInstance()) {
|
||||
Logs::multipleInstances();
|
||||
}
|
||||
|
||||
Sandbox::start();
|
||||
refreshGlobalProxy();
|
||||
|
||||
if (!Logs::started() || (!cManyInstance() && !Logs::instanceChecked())) {
|
||||
new NotStartedWindow();
|
||||
} else {
|
||||
const auto status = CrashReports::Start();
|
||||
if (status == CrashReports::CantOpen) {
|
||||
new NotStartedWindow();
|
||||
} else if (status == CrashReports::LastCrashed) {
|
||||
if (Sandbox::LastCrashDump().isEmpty()) { // don't handle bad closing for now
|
||||
if (CrashReports::Restart() == CrashReports::CantOpen) {
|
||||
new NotStartedWindow();
|
||||
} else {
|
||||
Sandbox::launch();
|
||||
}
|
||||
} else {
|
||||
new LastCrashedWindow();
|
||||
}
|
||||
} else {
|
||||
Sandbox::launch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::socketDisconnected() {
|
||||
if (_secondInstance) {
|
||||
DEBUG_LOG(("Application Error: socket disconnected before command response received, quitting..."));
|
||||
return App::quit();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::newInstanceConnected() {
|
||||
DEBUG_LOG(("Application Info: new local socket connected"));
|
||||
for (QLocalSocket *client = _localServer.nextPendingConnection(); client; client = _localServer.nextPendingConnection()) {
|
||||
_localClients.push_back(LocalClient(client, QByteArray()));
|
||||
connect(client, SIGNAL(readyRead()), this, SLOT(readClients()));
|
||||
connect(client, SIGNAL(disconnected()), this, SLOT(removeClients()));
|
||||
}
|
||||
}
|
||||
|
||||
void Application::readClients() {
|
||||
// This method can be called before Messenger is constructed.
|
||||
QString startUrl;
|
||||
QStringList toSend;
|
||||
for (LocalClients::iterator i = _localClients.begin(), e = _localClients.end(); i != e; ++i) {
|
||||
i->second.append(i->first->readAll());
|
||||
if (i->second.size()) {
|
||||
QString cmds(QString::fromLatin1(i->second));
|
||||
int32 from = 0, l = cmds.length();
|
||||
for (int32 to = cmds.indexOf(QChar(';'), from); to >= from; to = (from < l) ? cmds.indexOf(QChar(';'), from) : -1) {
|
||||
QStringRef cmd(&cmds, from, to - from);
|
||||
if (cmd.startsWith(qsl("CMD:"))) {
|
||||
Sandbox::execExternal(cmds.mid(from + 4, to - from - 4));
|
||||
const auto response = qsl("RES:%1;").arg(QCoreApplication::applicationPid()).toLatin1();
|
||||
i->first->write(response.data(), response.size());
|
||||
} else if (cmd.startsWith(qsl("SEND:"))) {
|
||||
if (cSendPaths().isEmpty()) {
|
||||
toSend.append(_escapeFrom7bit(cmds.mid(from + 5, to - from - 5)));
|
||||
}
|
||||
} else if (cmd.startsWith(qsl("OPEN:"))) {
|
||||
auto activateRequired = true;
|
||||
if (cStartUrl().isEmpty()) {
|
||||
startUrl = _escapeFrom7bit(cmds.mid(from + 5, to - from - 5)).mid(0, 8192);
|
||||
activateRequired = StartUrlRequiresActivate(startUrl);
|
||||
}
|
||||
if (activateRequired) {
|
||||
Sandbox::execExternal("show");
|
||||
}
|
||||
const auto responsePid = activateRequired
|
||||
? QCoreApplication::applicationPid()
|
||||
: kEmptyPidForCommandResponse;
|
||||
const auto response = qsl("RES:%1;").arg(responsePid).toLatin1();
|
||||
i->first->write(response.data(), response.size());
|
||||
} else {
|
||||
LOG(("Application Error: unknown command %1 passed in local socket").arg(QString(cmd.constData(), cmd.length())));
|
||||
}
|
||||
from = to + 1;
|
||||
}
|
||||
if (from > 0) {
|
||||
i->second = i->second.mid(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!toSend.isEmpty()) {
|
||||
QStringList paths(cSendPaths());
|
||||
paths.append(toSend);
|
||||
cSetSendPaths(paths);
|
||||
}
|
||||
if (!cSendPaths().isEmpty()) {
|
||||
if (App::wnd()) {
|
||||
App::wnd()->sendPaths();
|
||||
}
|
||||
}
|
||||
if (!startUrl.isEmpty()) {
|
||||
cSetStartUrl(startUrl);
|
||||
}
|
||||
if (auto messenger = Messenger::InstancePointer()) {
|
||||
messenger->checkStartUrl();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::removeClients() {
|
||||
DEBUG_LOG(("Application Info: remove clients slot called, clients %1").arg(_localClients.size()));
|
||||
for (LocalClients::iterator i = _localClients.begin(), e = _localClients.end(); i != e;) {
|
||||
if (i->first->state() != QLocalSocket::ConnectedState) {
|
||||
DEBUG_LOG(("Application Info: removing client"));
|
||||
i = _localClients.erase(i);
|
||||
e = _localClients.end();
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::startApplication() {
|
||||
if (App::quitting()) {
|
||||
quit();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::createMessenger() {
|
||||
Expects(!App::quitting());
|
||||
|
||||
_messengerInstance = std::make_unique<Messenger>(_launcher);
|
||||
}
|
||||
|
||||
void Application::refreshGlobalProxy() {
|
||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
const auto proxy = [&] {
|
||||
if (Global::started()) {
|
||||
return Global::UseProxy()
|
||||
? Global::SelectedProxy()
|
||||
: ProxyData();
|
||||
}
|
||||
return Sandbox::PreLaunchProxy();
|
||||
}();
|
||||
if (proxy.type == ProxyData::Type::Socks5
|
||||
|| proxy.type == ProxyData::Type::Http) {
|
||||
QNetworkProxy::setApplicationProxy(
|
||||
ToNetworkProxy(ToDirectIpProxy(proxy)));
|
||||
} else {
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||
}
|
||||
#endif // TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
}
|
||||
|
||||
void Application::closeApplication() {
|
||||
if (App::launchState() == App::QuitProcessed) return;
|
||||
App::setLaunchState(App::QuitProcessed);
|
||||
|
||||
_messengerInstance.reset();
|
||||
|
||||
Sandbox::finish();
|
||||
|
||||
_localServer.close();
|
||||
for (LocalClients::iterator i = _localClients.begin(), e = _localClients.end(); i != e; ++i) {
|
||||
disconnect(i->first, SIGNAL(disconnected()), this, SLOT(removeClients()));
|
||||
i->first->close();
|
||||
}
|
||||
_localClients.clear();
|
||||
|
||||
_localSocket.close();
|
||||
|
||||
_updateChecker = nullptr;
|
||||
}
|
||||
|
||||
inline Application *application() {
|
||||
return qobject_cast<Application*>(QApplication::instance());
|
||||
}
|
||||
|
||||
namespace Sandbox {
|
||||
|
||||
QRect availableGeometry() {
|
||||
if (auto a = application()) {
|
||||
return a->desktop()->availableGeometry();
|
||||
}
|
||||
return QDesktopWidget().availableGeometry();
|
||||
}
|
||||
|
||||
QRect screenGeometry(const QPoint &p) {
|
||||
if (auto a = application()) {
|
||||
return a->desktop()->screenGeometry(p);
|
||||
}
|
||||
return QDesktopWidget().screenGeometry(p);
|
||||
}
|
||||
|
||||
void setActiveWindow(QWidget *window) {
|
||||
if (auto a = application()) {
|
||||
a->setActiveWindow(window);
|
||||
}
|
||||
}
|
||||
|
||||
bool isSavingSession() {
|
||||
if (auto a = application()) {
|
||||
return a->isSavingSession();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void execExternal(const QString &cmd) {
|
||||
DEBUG_LOG(("Application Info: executing external command '%1'").arg(cmd));
|
||||
if (cmd == "show") {
|
||||
if (App::wnd()) {
|
||||
App::wnd()->activate();
|
||||
} else if (PreLaunchWindow::instance()) {
|
||||
PreLaunchWindow::instance()->activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void adjustSingleTimers() {
|
||||
if (auto a = application()) {
|
||||
a->adjustSingleTimers();
|
||||
}
|
||||
base::Timer::Adjust();
|
||||
base::ConcurrentTimerEnvironment::Adjust();
|
||||
}
|
||||
|
||||
void connect(const char *signal, QObject *object, const char *method) {
|
||||
if (auto a = application()) {
|
||||
a->connect(a, signal, object, method);
|
||||
}
|
||||
}
|
||||
|
||||
void launch() {
|
||||
Assert(application() != 0);
|
||||
|
||||
const auto dpi = Application::primaryScreen()->logicalDotsPerInch();
|
||||
LOG(("Primary screen DPI: %1").arg(dpi));
|
||||
if (dpi <= 108) {
|
||||
cSetScreenScale(100); // 100%: 96 DPI (0-108)
|
||||
} else if (dpi <= 132) {
|
||||
cSetScreenScale(125); // 125%: 120 DPI (108-132)
|
||||
} else if (dpi <= 168) {
|
||||
cSetScreenScale(150); // 150%: 144 DPI (132-168)
|
||||
} else if (dpi <= 216) {
|
||||
cSetScreenScale(200); // 200%: 192 DPI (168-216)
|
||||
} else if (dpi <= 264) {
|
||||
cSetScreenScale(250); // 250%: 240 DPI (216-264)
|
||||
} else {
|
||||
cSetScreenScale(300); // 300%: 288 DPI (264-inf)
|
||||
}
|
||||
|
||||
auto devicePixelRatio = application()->devicePixelRatio();
|
||||
if (devicePixelRatio > 1.) {
|
||||
if ((cPlatform() != dbipMac && cPlatform() != dbipMacOld) || (devicePixelRatio != 2.)) {
|
||||
LOG(("Found non-trivial Device Pixel Ratio: %1").arg(devicePixelRatio));
|
||||
LOG(("Environmental variables: QT_DEVICE_PIXEL_RATIO='%1'").arg(QString::fromLatin1(qgetenv("QT_DEVICE_PIXEL_RATIO"))));
|
||||
LOG(("Environmental variables: QT_SCALE_FACTOR='%1'").arg(QString::fromLatin1(qgetenv("QT_SCALE_FACTOR"))));
|
||||
LOG(("Environmental variables: QT_AUTO_SCREEN_SCALE_FACTOR='%1'").arg(QString::fromLatin1(qgetenv("QT_AUTO_SCREEN_SCALE_FACTOR"))));
|
||||
LOG(("Environmental variables: QT_SCREEN_SCALE_FACTORS='%1'").arg(QString::fromLatin1(qgetenv("QT_SCREEN_SCALE_FACTORS"))));
|
||||
}
|
||||
cSetRetinaFactor(devicePixelRatio);
|
||||
cSetIntRetinaFactor(int32(cRetinaFactor()));
|
||||
cSetScreenScale(kInterfaceScaleDefault);
|
||||
}
|
||||
|
||||
application()->createMessenger();
|
||||
}
|
||||
|
||||
void refreshGlobalProxy() {
|
||||
if (const auto instance = application()) {
|
||||
instance->refreshGlobalProxy();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Sandbox
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Core {
|
||||
class Launcher;
|
||||
class UpdateChecker;
|
||||
} // namespace Core
|
||||
|
||||
bool InternalPassportLink(const QString &url);
|
||||
bool StartUrlRequiresActivate(const QString &url);
|
||||
|
||||
class Application : public QApplication {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Application(not_null<Core::Launcher*> launcher, int &argc, char **argv);
|
||||
|
||||
bool event(QEvent *e) override;
|
||||
|
||||
void createMessenger();
|
||||
void refreshGlobalProxy();
|
||||
|
||||
~Application();
|
||||
|
||||
signals:
|
||||
void adjustSingleTimers();
|
||||
|
||||
// Single instance application
|
||||
public slots:
|
||||
void socketConnected();
|
||||
void socketError(QLocalSocket::LocalSocketError e);
|
||||
void socketDisconnected();
|
||||
void socketWritten(qint64 bytes);
|
||||
void socketReading();
|
||||
void newInstanceConnected();
|
||||
|
||||
void readClients();
|
||||
void removeClients();
|
||||
|
||||
void startApplication(); // will be done in exec()
|
||||
void closeApplication(); // will be done in aboutToQuit()
|
||||
|
||||
private:
|
||||
typedef QPair<QLocalSocket*, QByteArray> LocalClient;
|
||||
typedef QList<LocalClient> LocalClients;
|
||||
|
||||
not_null<Core::Launcher*> _launcher;
|
||||
std::unique_ptr<Messenger> _messengerInstance;
|
||||
|
||||
QString _localServerName, _localSocketReadData;
|
||||
QLocalServer _localServer;
|
||||
QLocalSocket _localSocket;
|
||||
LocalClients _localClients;
|
||||
bool _secondInstance = false;
|
||||
|
||||
void singleInstanceChecked();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Core::UpdateChecker> _updateChecker;
|
||||
|
||||
};
|
||||
|
||||
namespace Sandbox {
|
||||
|
||||
QRect availableGeometry();
|
||||
QRect screenGeometry(const QPoint &p);
|
||||
void setActiveWindow(QWidget *window);
|
||||
bool isSavingSession();
|
||||
|
||||
void execExternal(const QString &cmd);
|
||||
|
||||
void adjustSingleTimers();
|
||||
|
||||
void refreshGlobalProxy();
|
||||
|
||||
void connect(const char *signal, QObject *object, const char *method);
|
||||
|
||||
void launch();
|
||||
|
||||
} // namespace Sandbox
|
||||
@@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "auth_session.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "messenger.h"
|
||||
#include "core/application.h"
|
||||
#include "core/changelogs.h"
|
||||
#include "storage/file_download.h"
|
||||
#include "storage/file_upload.h"
|
||||
@@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "storage/storage_facade.h"
|
||||
#include "storage/serialize_common.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "platform/platform_specific.h"
|
||||
@@ -25,12 +26,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/send_files_box.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "support/support_common.h"
|
||||
#include "support/support_templates.h"
|
||||
#include "support/support_helper.h"
|
||||
#include "observer_peer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kAutoLockTimeoutLateMs = TimeMs(3000);
|
||||
constexpr auto kAutoLockTimeoutLateMs = crl::time(3000);
|
||||
constexpr auto kLegacyCallsPeerToPeerNobody = 4;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -44,11 +46,13 @@ AuthSessionSettings::Variables::Variables()
|
||||
}
|
||||
|
||||
QByteArray AuthSessionSettings::serialize() const {
|
||||
auto size = sizeof(qint32) * 10;
|
||||
const auto autoDownload = _variables.autoDownload.serialize();
|
||||
auto size = sizeof(qint32) * 23;
|
||||
for (auto i = _variables.soundOverrides.cbegin(), e = _variables.soundOverrides.cend(); i != e; ++i) {
|
||||
size += Serialize::stringSize(i.key()) + Serialize::stringSize(i.value());
|
||||
}
|
||||
size += _variables.groupStickersSectionHidden.size() * sizeof(quint64);
|
||||
size += Serialize::bytearraySize(autoDownload);
|
||||
|
||||
auto result = QByteArray();
|
||||
result.reserve(size);
|
||||
@@ -78,11 +82,17 @@ QByteArray AuthSessionSettings::serialize() const {
|
||||
stream << qint32(_variables.thirdColumnWidth.current());
|
||||
stream << qint32(_variables.thirdSectionExtendedBy);
|
||||
stream << qint32(_variables.sendFilesWay);
|
||||
stream << qint32(_variables.callsPeerToPeer.current());
|
||||
stream << qint32(0);// LEGACY _variables.callsPeerToPeer.current());
|
||||
stream << qint32(_variables.sendSubmitWay);
|
||||
stream << qint32(_variables.supportSwitch);
|
||||
stream << qint32(_variables.supportFixChatsOrder ? 1 : 0);
|
||||
stream << qint32(_variables.supportTemplatesAutocomplete ? 1 : 0);
|
||||
stream << qint32(_variables.supportChatsTimeSlice.current());
|
||||
stream << qint32(_variables.includeMutedCounter ? 1 : 0);
|
||||
stream << qint32(_variables.countUnreadMessages ? 1 : 0);
|
||||
stream << qint32(_variables.exeLaunchWarning ? 1 : 0);
|
||||
stream << autoDownload;
|
||||
stream << qint32(_variables.supportAllSearchResults.current() ? 1 : 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -108,11 +118,17 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
|
||||
int thirdColumnWidth = _variables.thirdColumnWidth.current();
|
||||
int thirdSectionExtendedBy = _variables.thirdSectionExtendedBy;
|
||||
qint32 sendFilesWay = static_cast<qint32>(_variables.sendFilesWay);
|
||||
qint32 callsPeerToPeer = qint32(_variables.callsPeerToPeer.current());
|
||||
qint32 legacyCallsPeerToPeer = qint32(0);
|
||||
qint32 sendSubmitWay = static_cast<qint32>(_variables.sendSubmitWay);
|
||||
qint32 supportSwitch = static_cast<qint32>(_variables.supportSwitch);
|
||||
qint32 supportFixChatsOrder = _variables.supportFixChatsOrder ? 1 : 0;
|
||||
qint32 supportTemplatesAutocomplete = _variables.supportTemplatesAutocomplete ? 1 : 0;
|
||||
qint32 supportChatsTimeSlice = _variables.supportChatsTimeSlice.current();
|
||||
qint32 includeMutedCounter = _variables.includeMutedCounter ? 1 : 0;
|
||||
qint32 countUnreadMessages = _variables.countUnreadMessages ? 1 : 0;
|
||||
qint32 exeLaunchWarning = _variables.exeLaunchWarning ? 1 : 0;
|
||||
QByteArray autoDownload;
|
||||
qint32 supportAllSearchResults = _variables.supportAllSearchResults.current() ? 1 : 0;
|
||||
|
||||
stream >> selectorTab;
|
||||
stream >> lastSeenWarningSeen;
|
||||
@@ -166,7 +182,7 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
|
||||
stream >> sendFilesWay;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> callsPeerToPeer;
|
||||
stream >> legacyCallsPeerToPeer;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> sendSubmitWay;
|
||||
@@ -176,11 +192,31 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
|
||||
if (!stream.atEnd()) {
|
||||
stream >> supportTemplatesAutocomplete;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> supportChatsTimeSlice;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> includeMutedCounter;
|
||||
stream >> countUnreadMessages;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> exeLaunchWarning;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> autoDownload;
|
||||
}
|
||||
if (!stream.atEnd()) {
|
||||
stream >> supportAllSearchResults;
|
||||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("App Error: "
|
||||
"Bad data for AuthSessionSettings::constructFromSerialized()"));
|
||||
return;
|
||||
}
|
||||
if (!autoDownload.isEmpty()
|
||||
&& !_variables.autoDownload.setFromSerialized(autoDownload)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto uncheckedTab = static_cast<ChatHelpers::SelectorTab>(selectorTab);
|
||||
switch (uncheckedTab) {
|
||||
@@ -220,14 +256,6 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
|
||||
case SendFilesWay::Photos:
|
||||
case SendFilesWay::Files: _variables.sendFilesWay = uncheckedSendFilesWay; break;
|
||||
}
|
||||
auto uncheckedCallsPeerToPeer = static_cast<Calls::PeerToPeer>(callsPeerToPeer);
|
||||
switch (uncheckedCallsPeerToPeer) {
|
||||
case Calls::PeerToPeer::DefaultContacts:
|
||||
case Calls::PeerToPeer::DefaultEveryone:
|
||||
case Calls::PeerToPeer::Everyone:
|
||||
case Calls::PeerToPeer::Contacts:
|
||||
case Calls::PeerToPeer::Nobody: _variables.callsPeerToPeer = uncheckedCallsPeerToPeer; break;
|
||||
}
|
||||
auto uncheckedSendSubmitWay = static_cast<Ui::InputSubmitSettings>(
|
||||
sendSubmitWay);
|
||||
switch (uncheckedSendSubmitWay) {
|
||||
@@ -243,6 +271,36 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
|
||||
}
|
||||
_variables.supportFixChatsOrder = (supportFixChatsOrder == 1);
|
||||
_variables.supportTemplatesAutocomplete = (supportTemplatesAutocomplete == 1);
|
||||
_variables.supportChatsTimeSlice = supportChatsTimeSlice;
|
||||
_variables.hadLegacyCallsPeerToPeerNobody = (legacyCallsPeerToPeer == kLegacyCallsPeerToPeerNobody);
|
||||
_variables.includeMutedCounter = (includeMutedCounter == 1);
|
||||
_variables.countUnreadMessages = (countUnreadMessages == 1);
|
||||
_variables.exeLaunchWarning = (exeLaunchWarning == 1);
|
||||
_variables.supportAllSearchResults = (supportAllSearchResults == 1);
|
||||
}
|
||||
|
||||
void AuthSessionSettings::setSupportChatsTimeSlice(int slice) {
|
||||
_variables.supportChatsTimeSlice = slice;
|
||||
}
|
||||
|
||||
int AuthSessionSettings::supportChatsTimeSlice() const {
|
||||
return _variables.supportChatsTimeSlice.current();
|
||||
}
|
||||
|
||||
rpl::producer<int> AuthSessionSettings::supportChatsTimeSliceValue() const {
|
||||
return _variables.supportChatsTimeSlice.value();
|
||||
}
|
||||
|
||||
void AuthSessionSettings::setSupportAllSearchResults(bool all) {
|
||||
_variables.supportAllSearchResults = all;
|
||||
}
|
||||
|
||||
bool AuthSessionSettings::supportAllSearchResults() const {
|
||||
return _variables.supportAllSearchResults.current();
|
||||
}
|
||||
|
||||
rpl::producer<bool> AuthSessionSettings::supportAllSearchResultsValue() const {
|
||||
return _variables.supportAllSearchResults.value();
|
||||
}
|
||||
|
||||
void AuthSessionSettings::setTabbedSelectorSectionEnabled(bool enabled) {
|
||||
@@ -314,14 +372,13 @@ rpl::producer<int> AuthSessionSettings::thirdColumnWidthChanges() const {
|
||||
}
|
||||
|
||||
AuthSession &Auth() {
|
||||
auto result = Messenger::Instance().authSession();
|
||||
auto result = Core::App().authSession();
|
||||
Assert(result != nullptr);
|
||||
return *result;
|
||||
}
|
||||
|
||||
AuthSession::AuthSession(const MTPUser &user)
|
||||
: _user(App::user(user.match([](const auto &data) { return data.vid.v; })))
|
||||
, _autoLockTimer([this] { checkAutoLock(); })
|
||||
: _autoLockTimer([this] { checkAutoLock(); })
|
||||
, _api(std::make_unique<ApiWrap>(this))
|
||||
, _calls(std::make_unique<Calls::Instance>())
|
||||
, _downloader(std::make_unique<Storage::Downloader>())
|
||||
@@ -329,21 +386,17 @@ AuthSession::AuthSession(const MTPUser &user)
|
||||
, _storage(std::make_unique<Storage::Facade>())
|
||||
, _notifications(std::make_unique<Window::Notifications::System>(this))
|
||||
, _data(std::make_unique<Data::Session>(this))
|
||||
, _user(_data->processUser(user))
|
||||
, _changelogs(Core::Changelogs::Create(this))
|
||||
, _supportTemplates(
|
||||
(Support::ValidateAccount(user)
|
||||
? std::make_unique<Support::Templates>(this)
|
||||
: nullptr)) {
|
||||
App::feedUser(user);
|
||||
|
||||
, _supportHelper(Support::Helper::Create(this)) {
|
||||
_saveDataTimer.setCallback([=] {
|
||||
Local::writeUserSettings();
|
||||
});
|
||||
Messenger::Instance().passcodeLockChanges(
|
||||
Core::App().passcodeLockChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
_shouldLockAt = 0;
|
||||
}, _lifetime);
|
||||
Messenger::Instance().lockChanges(
|
||||
Core::App().lockChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
notifications().updateAll();
|
||||
}, _lifetime);
|
||||
@@ -376,55 +429,80 @@ AuthSession::AuthSession(const MTPUser &user)
|
||||
}
|
||||
|
||||
bool AuthSession::Exists() {
|
||||
if (const auto messenger = Messenger::InstancePointer()) {
|
||||
return (messenger->authSession() != nullptr);
|
||||
}
|
||||
return false;
|
||||
return Core::IsAppLaunched() && (Core::App().authSession() != nullptr);
|
||||
}
|
||||
|
||||
base::Observable<void> &AuthSession::downloaderTaskFinished() {
|
||||
return downloader().taskFinished();
|
||||
}
|
||||
|
||||
UserId AuthSession::userId() const {
|
||||
return _user->bareId();
|
||||
}
|
||||
|
||||
PeerId AuthSession::userPeerId() const {
|
||||
return _user->id;
|
||||
}
|
||||
|
||||
bool AuthSession::validateSelf(const MTPUser &user) {
|
||||
if (user.type() != mtpc_user || !user.c_user().is_self()) {
|
||||
LOG(("API Error: bad self user received."));
|
||||
return false;
|
||||
} else if (user.c_user().vid.v != userId()) {
|
||||
LOG(("Auth Error: wrong self user received."));
|
||||
crl::on_main(this, [] { Messenger::Instance().logOut(); });
|
||||
crl::on_main(this, [] { Core::App().logOut(); });
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AuthSession::saveSettingsDelayed(TimeMs delay) {
|
||||
void AuthSession::moveSettingsFrom(AuthSessionSettings &&other) {
|
||||
_settings.moveFrom(std::move(other));
|
||||
if (_settings.hadLegacyCallsPeerToPeerNobody()) {
|
||||
api().savePrivacy(
|
||||
MTP_inputPrivacyKeyPhoneP2P(),
|
||||
QVector<MTPInputPrivacyRule>(
|
||||
1,
|
||||
MTP_inputPrivacyValueDisallowAll()));
|
||||
saveSettingsDelayed();
|
||||
}
|
||||
}
|
||||
|
||||
void AuthSession::saveSettingsDelayed(crl::time delay) {
|
||||
Expects(this == &Auth());
|
||||
|
||||
_saveDataTimer.callOnce(delay);
|
||||
}
|
||||
|
||||
void AuthSession::localPasscodeChanged() {
|
||||
_shouldLockAt = 0;
|
||||
_autoLockTimer.cancel();
|
||||
checkAutoLock();
|
||||
}
|
||||
|
||||
void AuthSession::checkAutoLock() {
|
||||
if (!Global::LocalPasscode()
|
||||
|| Messenger::Instance().passcodeLocked()) {
|
||||
|| Core::App().passcodeLocked()) {
|
||||
_shouldLockAt = 0;
|
||||
_autoLockTimer.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
Messenger::Instance().checkLocalTime();
|
||||
auto now = getms(true);
|
||||
auto shouldLockInMs = Global::AutoLock() * 1000LL;
|
||||
auto idleForMs = psIdleTime();
|
||||
auto notPlayingVideoForMs = now - settings().lastTimeVideoPlayedAt();
|
||||
auto checkTimeMs = qMin(idleForMs, notPlayingVideoForMs);
|
||||
Core::App().checkLocalTime();
|
||||
const auto now = crl::now();
|
||||
const auto shouldLockInMs = Global::AutoLock() * 1000LL;
|
||||
const auto checkTimeMs = now - Core::App().lastNonIdleTime();
|
||||
if (checkTimeMs >= shouldLockInMs || (_shouldLockAt > 0 && now > _shouldLockAt + kAutoLockTimeoutLateMs)) {
|
||||
Messenger::Instance().lockByPasscode();
|
||||
_shouldLockAt = 0;
|
||||
_autoLockTimer.cancel();
|
||||
Core::App().lockByPasscode();
|
||||
} else {
|
||||
_shouldLockAt = now + (shouldLockInMs - checkTimeMs);
|
||||
_autoLockTimer.callOnce(shouldLockInMs - checkTimeMs);
|
||||
}
|
||||
}
|
||||
|
||||
void AuthSession::checkAutoLockIn(TimeMs time) {
|
||||
void AuthSession::checkAutoLockIn(crl::time time) {
|
||||
if (_autoLockTimer.isActive()) {
|
||||
auto remain = _autoLockTimer.remainingTime();
|
||||
if (remain > 0 && remain <= time) return;
|
||||
@@ -433,13 +511,20 @@ void AuthSession::checkAutoLockIn(TimeMs time) {
|
||||
}
|
||||
|
||||
bool AuthSession::supportMode() const {
|
||||
return (_supportTemplates != nullptr);
|
||||
return (_supportHelper != nullptr);
|
||||
}
|
||||
|
||||
not_null<Support::Templates*> AuthSession::supportTemplates() const {
|
||||
Support::Helper &AuthSession::supportHelper() const {
|
||||
Expects(supportMode());
|
||||
|
||||
return _supportTemplates.get();
|
||||
return *_supportHelper;
|
||||
}
|
||||
|
||||
AuthSession::~AuthSession() = default;
|
||||
Support::Templates& AuthSession::supportTemplates() const {
|
||||
return supportHelper().templates();
|
||||
}
|
||||
|
||||
AuthSession::~AuthSession() {
|
||||
ClickHandler::clearActive();
|
||||
ClickHandler::unpressed();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <rpl/filter.h>
|
||||
#include <rpl/variable.h>
|
||||
#include "base/timer.h"
|
||||
#include "data/data_auto_download.h"
|
||||
|
||||
class ApiWrap;
|
||||
enum class SendFilesWay;
|
||||
@@ -21,6 +22,7 @@ enum class InputSubmitSettings;
|
||||
|
||||
namespace Support {
|
||||
enum class SwitchSettings;
|
||||
class Helper;
|
||||
class Templates;
|
||||
} // namespace Support
|
||||
|
||||
@@ -28,10 +30,6 @@ namespace Data {
|
||||
class Session;
|
||||
} // namespace Data
|
||||
|
||||
namespace Calls {
|
||||
enum class PeerToPeer;
|
||||
} // namespace Calls
|
||||
|
||||
namespace Storage {
|
||||
class Downloader;
|
||||
class Uploader;
|
||||
@@ -102,6 +100,12 @@ public:
|
||||
bool supportTemplatesAutocomplete() const {
|
||||
return _variables.supportTemplatesAutocomplete;
|
||||
}
|
||||
void setSupportChatsTimeSlice(int slice);
|
||||
int supportChatsTimeSlice() const;
|
||||
rpl::producer<int> supportChatsTimeSliceValue() const;
|
||||
void setSupportAllSearchResults(bool all);
|
||||
bool supportAllSearchResults() const;
|
||||
rpl::producer<bool> supportAllSearchResultsValue() const;
|
||||
|
||||
ChatHelpers::SelectorTab selectorTab() const {
|
||||
return _variables.selectorTab;
|
||||
@@ -135,12 +139,6 @@ public:
|
||||
bool smallDialogsList() const {
|
||||
return _variables.smallDialogsList;
|
||||
}
|
||||
void setLastTimeVideoPlayedAt(TimeMs time) {
|
||||
_lastTimeVideoPlayedAt = time;
|
||||
}
|
||||
TimeMs lastTimeVideoPlayedAt() const {
|
||||
return _lastTimeVideoPlayedAt;
|
||||
}
|
||||
void setSoundOverride(const QString &key, const QString &path) {
|
||||
_variables.soundOverrides.insert(key, path);
|
||||
}
|
||||
@@ -183,14 +181,34 @@ public:
|
||||
_variables.groupStickersSectionHidden.remove(peerId);
|
||||
}
|
||||
|
||||
rpl::producer<Calls::PeerToPeer> callsPeerToPeerValue() const {
|
||||
return _variables.callsPeerToPeer.value();
|
||||
Data::AutoDownload::Full &autoDownload() {
|
||||
return _variables.autoDownload;
|
||||
}
|
||||
Calls::PeerToPeer callsPeerToPeer() const {
|
||||
return _variables.callsPeerToPeer.current();
|
||||
const Data::AutoDownload::Full &autoDownload() const {
|
||||
return _variables.autoDownload;
|
||||
}
|
||||
void setCallsPeerToPeer(Calls::PeerToPeer value) {
|
||||
_variables.callsPeerToPeer = value;
|
||||
|
||||
bool hadLegacyCallsPeerToPeerNobody() const {
|
||||
return _variables.hadLegacyCallsPeerToPeerNobody;
|
||||
}
|
||||
|
||||
bool includeMutedCounter() const {
|
||||
return _variables.includeMutedCounter;
|
||||
}
|
||||
void setIncludeMutedCounter(bool value) {
|
||||
_variables.includeMutedCounter = value;
|
||||
}
|
||||
bool countUnreadMessages() const {
|
||||
return _variables.countUnreadMessages;
|
||||
}
|
||||
void setCountUnreadMessages(bool value) {
|
||||
_variables.countUnreadMessages = value;
|
||||
}
|
||||
bool exeLaunchWarning() const {
|
||||
return _variables.exeLaunchWarning;
|
||||
}
|
||||
void setExeLaunchWarning(bool warning) {
|
||||
_variables.exeLaunchWarning = warning;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -216,13 +234,22 @@ private:
|
||||
= kDefaultDialogsWidthRatio; // per-window
|
||||
rpl::variable<int> thirdColumnWidth
|
||||
= kDefaultThirdColumnWidth; // per-window
|
||||
rpl::variable<Calls::PeerToPeer> callsPeerToPeer
|
||||
= Calls::PeerToPeer();
|
||||
Ui::InputSubmitSettings sendSubmitWay;
|
||||
bool hadLegacyCallsPeerToPeerNobody = false;
|
||||
bool includeMutedCounter = true;
|
||||
bool countUnreadMessages = true;
|
||||
bool exeLaunchWarning = true;
|
||||
Data::AutoDownload::Full autoDownload;
|
||||
|
||||
static constexpr auto kDefaultSupportChatsLimitSlice
|
||||
= 7 * 24 * 60 * 60;
|
||||
|
||||
Support::SwitchSettings supportSwitch;
|
||||
bool supportFixChatsOrder = true;
|
||||
bool supportTemplatesAutocomplete = true;
|
||||
rpl::variable<int> supportChatsTimeSlice
|
||||
= kDefaultSupportChatsLimitSlice;
|
||||
rpl::variable<bool> supportAllSearchResults = false;
|
||||
};
|
||||
|
||||
rpl::event_stream<bool> _thirdSectionInfoEnabledValue;
|
||||
@@ -230,11 +257,9 @@ private:
|
||||
rpl::event_stream<bool> _tabbedReplacedWithInfoValue;
|
||||
|
||||
Variables _variables;
|
||||
TimeMs _lastTimeVideoPlayedAt = 0;
|
||||
|
||||
};
|
||||
|
||||
// One per Messenger.
|
||||
class AuthSession;
|
||||
AuthSession &Auth();
|
||||
|
||||
@@ -249,12 +274,8 @@ public:
|
||||
|
||||
static bool Exists();
|
||||
|
||||
UserId userId() const {
|
||||
return _user->bareId();
|
||||
}
|
||||
PeerId userPeerId() const {
|
||||
return _user->id;
|
||||
}
|
||||
UserId userId() const;
|
||||
PeerId userPeerId() const;
|
||||
not_null<UserData*> user() const {
|
||||
return _user;
|
||||
}
|
||||
@@ -282,7 +303,8 @@ public:
|
||||
AuthSessionSettings &settings() {
|
||||
return _settings;
|
||||
}
|
||||
void saveSettingsDelayed(TimeMs delay = kDefaultSaveDelay);
|
||||
void moveSettingsFrom(AuthSessionSettings &&other);
|
||||
void saveSettingsDelayed(crl::time delay = kDefaultSaveDelay);
|
||||
|
||||
ApiWrap &api() {
|
||||
return *_api;
|
||||
@@ -293,7 +315,8 @@ public:
|
||||
}
|
||||
|
||||
void checkAutoLock();
|
||||
void checkAutoLockIn(TimeMs time);
|
||||
void checkAutoLockIn(crl::time time);
|
||||
void localPasscodeChanged();
|
||||
|
||||
rpl::lifetime &lifetime() {
|
||||
return _lifetime;
|
||||
@@ -303,18 +326,18 @@ public:
|
||||
base::Observable<std::pair<not_null<HistoryItem*>, MsgId>> messageIdChanging;
|
||||
|
||||
bool supportMode() const;
|
||||
not_null<Support::Templates*> supportTemplates() const;
|
||||
Support::Helper &supportHelper() const;
|
||||
Support::Templates &supportTemplates() const;
|
||||
|
||||
~AuthSession();
|
||||
|
||||
private:
|
||||
static constexpr auto kDefaultSaveDelay = TimeMs(1000);
|
||||
static constexpr auto kDefaultSaveDelay = crl::time(1000);
|
||||
|
||||
const not_null<UserData*> _user;
|
||||
AuthSessionSettings _settings;
|
||||
base::Timer _saveDataTimer;
|
||||
|
||||
TimeMs _shouldLockAt = 0;
|
||||
crl::time _shouldLockAt = 0;
|
||||
base::Timer _autoLockTimer;
|
||||
|
||||
const std::unique_ptr<ApiWrap> _api;
|
||||
@@ -324,13 +347,14 @@ private:
|
||||
const std::unique_ptr<Storage::Facade> _storage;
|
||||
const std::unique_ptr<Window::Notifications::System> _notifications;
|
||||
|
||||
// _data depends on _downloader / _uploader, including destructor.
|
||||
// _data depends on _downloader / _uploader / _notifications.
|
||||
const std::unique_ptr<Data::Session> _data;
|
||||
const not_null<UserData*> _user;
|
||||
|
||||
// _changelogs depends on _data, subscribes on chats loading event.
|
||||
const std::unique_ptr<Core::Changelogs> _changelogs;
|
||||
|
||||
const std::unique_ptr<Support::Templates> _supportTemplates;
|
||||
const std::unique_ptr<Support::Helper> _supportHelper;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
|
||||
@@ -24,6 +24,12 @@ inline constexpr size_t array_size(const Type(&)[Size]) {
|
||||
return Size;
|
||||
}
|
||||
|
||||
template <typename Container, typename T>
|
||||
inline bool contains(const Container &container, const T &value) {
|
||||
const auto end = std::end(container);
|
||||
return std::find(std::begin(container), end, value) != end;
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -19,7 +19,10 @@ void log(const char *message, const char *file, int line);
|
||||
inline constexpr void noop() {
|
||||
}
|
||||
|
||||
[[noreturn]] inline void fail(const char *message, const char *file, int line) {
|
||||
[[noreturn]] inline void fail(
|
||||
const char *message,
|
||||
const char *file,
|
||||
int line) {
|
||||
log(message, file, line);
|
||||
|
||||
// Crash with access violation and generate crash report.
|
||||
@@ -30,24 +33,36 @@ inline constexpr void noop() {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
#ifndef GSL_UNLIKELY
|
||||
#define DEFINED_GSL_UNLIKELY_
|
||||
#define GSL_UNLIKELY(expression) (expression)
|
||||
#endif // GSL_UNLIKELY
|
||||
|
||||
inline constexpr void validate(bool condition, const char *message, const char *file, int line) {
|
||||
(GSL_UNLIKELY(!(condition))) ? fail(message, file, line) : noop();
|
||||
constexpr const char* extract_basename(const char* path, size_t size) {
|
||||
while (size != 0 && path[size - 1] != '/' && path[size - 1] != '\\') {
|
||||
--size;
|
||||
}
|
||||
return path + size;
|
||||
}
|
||||
|
||||
#ifdef DEFINED_GSL_UNLIKELY_
|
||||
#undef GSL_UNLIKELY
|
||||
#undef DEFINED_GSL_UNLIKELY_
|
||||
#endif // DEFINED_GSL_UNLIKELY_
|
||||
|
||||
} // namespace assertion
|
||||
} // namespace base
|
||||
|
||||
#define AssertCustom(condition, message) (::base::assertion::validate(condition, message, __FILE__, __LINE__))
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#define AssertUnlikelyHelper(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
#define AssertUnlikelyHelper(x) (!!(x))
|
||||
#endif
|
||||
|
||||
#define AssertValidationCondition(condition, message, file, line)\
|
||||
((AssertUnlikelyHelper(!(condition)))\
|
||||
? ::base::assertion::fail(message, file, line)\
|
||||
: ::base::assertion::noop())
|
||||
|
||||
#define SOURCE_FILE_BASENAME (::base::assertion::extract_basename(\
|
||||
__FILE__,\
|
||||
sizeof(__FILE__)))
|
||||
|
||||
#define AssertCustom(condition, message) (AssertValidationCondition(\
|
||||
condition,\
|
||||
message,\
|
||||
SOURCE_FILE_BASENAME,\
|
||||
__LINE__))
|
||||
#define Assert(condition) AssertCustom(condition, "\"" #condition "\"")
|
||||
|
||||
// Define our own versions of Expects() and Ensures().
|
||||
@@ -55,17 +70,28 @@ inline constexpr void validate(bool condition, const char *message, const char *
|
||||
#ifdef Expects
|
||||
#undef Expects
|
||||
#endif // Expects
|
||||
#define Expects(condition) (::base::assertion::validate(condition, "\"" #condition "\"", __FILE__, __LINE__))
|
||||
#define Expects(condition) (AssertValidationCondition(\
|
||||
condition,\
|
||||
"\"" #condition "\"",\
|
||||
SOURCE_FILE_BASENAME,\
|
||||
__LINE__))
|
||||
|
||||
#ifdef Ensures
|
||||
#undef Ensures
|
||||
#endif // Ensures
|
||||
#define Ensures(condition) (::base::assertion::validate(condition, "\"" #condition "\"", __FILE__, __LINE__))
|
||||
#define Ensures(condition) (AssertValidationCondition(\
|
||||
condition,\
|
||||
"\"" #condition "\"",\
|
||||
SOURCE_FILE_BASENAME,\
|
||||
__LINE__))
|
||||
|
||||
#ifdef Unexpected
|
||||
#undef Unexpected
|
||||
#endif // Unexpected
|
||||
#define Unexpected(message) (::base::assertion::fail("Unexpected: " message, __FILE__, __LINE__))
|
||||
#define Unexpected(message) (::base::assertion::fail(\
|
||||
"Unexpected: " message,\
|
||||
SOURCE_FILE_BASENAME,\
|
||||
__LINE__))
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define AssertIsDebug(...)
|
||||
|
||||
@@ -22,9 +22,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <set>
|
||||
|
||||
#include <range/v3/all.hpp>
|
||||
#ifdef Q_OS_WIN
|
||||
#include "platform/win/windows_range_v3_helpers.h"
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
#include "base/flat_map.h"
|
||||
#include "base/flat_set.h"
|
||||
|
||||
@@ -46,7 +46,6 @@ using uint64 = quint64;
|
||||
using float32 = float;
|
||||
using float64 = double;
|
||||
|
||||
using TimeMs = int64;
|
||||
using TimeId = int32;
|
||||
|
||||
// Define specializations for QByteArray for Qt 5.3.2, because
|
||||
|
||||
@@ -21,7 +21,9 @@ public:
|
||||
~binary_guard();
|
||||
|
||||
bool alive() const;
|
||||
void kill();
|
||||
|
||||
binary_guard &operator=(std::nullptr_t);
|
||||
explicit operator bool() const;
|
||||
|
||||
private:
|
||||
void destroy();
|
||||
@@ -44,15 +46,20 @@ inline binary_guard &binary_guard::operator=(binary_guard &&other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline binary_guard::~binary_guard() {
|
||||
inline binary_guard &binary_guard::operator=(std::nullptr_t) {
|
||||
destroy();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline binary_guard::operator bool() const {
|
||||
return alive();
|
||||
}
|
||||
|
||||
inline bool binary_guard::alive() const {
|
||||
return _bothAlive && _bothAlive->load();
|
||||
}
|
||||
|
||||
inline void binary_guard::kill() {
|
||||
inline binary_guard::~binary_guard() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
@@ -74,3 +81,21 @@ inline std::pair<binary_guard, binary_guard> make_binary_guard() {
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
||||
namespace crl {
|
||||
|
||||
template <typename T, typename Enable>
|
||||
struct guard_traits;
|
||||
|
||||
template <>
|
||||
struct guard_traits<base::binary_guard, void> {
|
||||
static base::binary_guard create(base::binary_guard value) {
|
||||
return value;
|
||||
}
|
||||
static bool check(const base::binary_guard &guard) {
|
||||
return guard.alive();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace crl
|
||||
|
||||
@@ -26,16 +26,16 @@ QMutex EnvironmentMutex;
|
||||
class CallDelayedEvent : public QEvent {
|
||||
public:
|
||||
CallDelayedEvent(
|
||||
crl::time_type timeout,
|
||||
crl::time timeout,
|
||||
Qt::TimerType type,
|
||||
FnMut<void()> method);
|
||||
|
||||
crl::time_type timeout() const;
|
||||
crl::time timeout() const;
|
||||
Qt::TimerType type() const;
|
||||
FnMut<void()> takeMethod();
|
||||
|
||||
private:
|
||||
crl::time_type _timeout = 0;
|
||||
crl::time _timeout = 0;
|
||||
Qt::TimerType _type = Qt::PreciseTimer;
|
||||
FnMut<void()> _method;
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
};
|
||||
|
||||
CallDelayedEvent::CallDelayedEvent(
|
||||
crl::time_type timeout,
|
||||
crl::time timeout,
|
||||
Qt::TimerType type,
|
||||
FnMut<void()> method)
|
||||
: QEvent(kCallDelayedEvent)
|
||||
@@ -58,7 +58,7 @@ CallDelayedEvent::CallDelayedEvent(
|
||||
Expects(_timeout >= 0 && _timeout < std::numeric_limits<int>::max());
|
||||
}
|
||||
|
||||
crl::time_type CallDelayedEvent::timeout() const {
|
||||
crl::time CallDelayedEvent::timeout() const {
|
||||
return _timeout;
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ TimerObjectWrap::~TimerObjectWrap() {
|
||||
}
|
||||
|
||||
void TimerObjectWrap::call(
|
||||
crl::time_type timeout,
|
||||
crl::time timeout,
|
||||
Qt::TimerType type,
|
||||
FnMut<void()> method) {
|
||||
sendEvent(std::make_unique<CallDelayedEvent>(
|
||||
@@ -281,7 +281,7 @@ Fn<void()> ConcurrentTimer::createAdjuster() {
|
||||
}
|
||||
|
||||
void ConcurrentTimer::start(
|
||||
TimeMs timeout,
|
||||
crl::time timeout,
|
||||
Qt::TimerType type,
|
||||
Repeat repeat) {
|
||||
_type = type;
|
||||
@@ -290,7 +290,7 @@ void ConcurrentTimer::start(
|
||||
setTimeout(timeout);
|
||||
|
||||
cancelAndSchedule(_timeout);
|
||||
_next = crl::time() + _timeout;
|
||||
_next = crl::now() + _timeout;
|
||||
}
|
||||
|
||||
void ConcurrentTimer::cancelAndSchedule(int timeout) {
|
||||
@@ -301,11 +301,11 @@ void ConcurrentTimer::cancelAndSchedule(int timeout) {
|
||||
runner = _runner,
|
||||
guard = std::move(guards.second)
|
||||
]() mutable {
|
||||
if (!guard.alive()) {
|
||||
if (!guard) {
|
||||
return;
|
||||
}
|
||||
runner([=, guard = std::move(guard)] {
|
||||
if (!guard.alive()) {
|
||||
if (!guard) {
|
||||
return;
|
||||
}
|
||||
timerEvent();
|
||||
@@ -319,7 +319,7 @@ void ConcurrentTimer::timerEvent() {
|
||||
if (_adjusted) {
|
||||
start(_timeout, _type, repeat());
|
||||
} else {
|
||||
_next = crl::time() + _timeout;
|
||||
_next = crl::now() + _timeout;
|
||||
}
|
||||
} else {
|
||||
cancel();
|
||||
@@ -338,12 +338,12 @@ void ConcurrentTimer::cancel() {
|
||||
}
|
||||
}
|
||||
|
||||
TimeMs ConcurrentTimer::remainingTime() const {
|
||||
crl::time ConcurrentTimer::remainingTime() const {
|
||||
if (!isActive()) {
|
||||
return -1;
|
||||
}
|
||||
const auto now = crl::time();
|
||||
return (_next > now) ? (_next - now) : TimeMs(0);
|
||||
const auto now = crl::now();
|
||||
return (_next > now) ? (_next - now) : crl::time(0);
|
||||
}
|
||||
|
||||
void ConcurrentTimer::adjust() {
|
||||
@@ -354,7 +354,7 @@ void ConcurrentTimer::adjust() {
|
||||
}
|
||||
}
|
||||
|
||||
void ConcurrentTimer::setTimeout(TimeMs timeout) {
|
||||
void ConcurrentTimer::setTimeout(crl::time timeout) {
|
||||
Expects(timeout >= 0 && timeout <= std::numeric_limits<int>::max());
|
||||
|
||||
_timeout = static_cast<unsigned int>(timeout);
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
~TimerObjectWrap();
|
||||
|
||||
void call(
|
||||
crl::time_type timeout,
|
||||
crl::time timeout,
|
||||
Qt::TimerType type,
|
||||
FnMut<void()> method);
|
||||
void cancel();
|
||||
@@ -67,8 +67,8 @@ public:
|
||||
crl::weak_on_queue<Object> weak,
|
||||
Fn<void()> callback = nullptr);
|
||||
|
||||
static Qt::TimerType DefaultType(TimeMs timeout) {
|
||||
constexpr auto kThreshold = TimeMs(1000);
|
||||
static Qt::TimerType DefaultType(crl::time timeout) {
|
||||
constexpr auto kThreshold = crl::time(1000);
|
||||
return (timeout > kThreshold) ? Qt::CoarseTimer : Qt::PreciseTimer;
|
||||
}
|
||||
|
||||
@@ -76,19 +76,19 @@ public:
|
||||
_callback = std::move(callback);
|
||||
}
|
||||
|
||||
void callOnce(TimeMs timeout) {
|
||||
void callOnce(crl::time timeout) {
|
||||
callOnce(timeout, DefaultType(timeout));
|
||||
}
|
||||
|
||||
void callEach(TimeMs timeout) {
|
||||
void callEach(crl::time timeout) {
|
||||
callEach(timeout, DefaultType(timeout));
|
||||
}
|
||||
|
||||
void callOnce(TimeMs timeout, Qt::TimerType type) {
|
||||
void callOnce(crl::time timeout, Qt::TimerType type) {
|
||||
start(timeout, type, Repeat::SingleShot);
|
||||
}
|
||||
|
||||
void callEach(TimeMs timeout, Qt::TimerType type) {
|
||||
void callEach(crl::time timeout, Qt::TimerType type) {
|
||||
start(timeout, type, Repeat::Interval);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
}
|
||||
|
||||
void cancel();
|
||||
TimeMs remainingTime() const;
|
||||
crl::time remainingTime() const;
|
||||
|
||||
private:
|
||||
enum class Repeat : unsigned {
|
||||
@@ -105,12 +105,12 @@ private:
|
||||
SingleShot = 1,
|
||||
};
|
||||
Fn<void()> createAdjuster();
|
||||
void start(TimeMs timeout, Qt::TimerType type, Repeat repeat);
|
||||
void start(crl::time timeout, Qt::TimerType type, Repeat repeat);
|
||||
void adjust();
|
||||
|
||||
void cancelAndSchedule(int timeout);
|
||||
|
||||
void setTimeout(TimeMs timeout);
|
||||
void setTimeout(crl::time timeout);
|
||||
int timeout() const;
|
||||
|
||||
void timerEvent();
|
||||
@@ -127,7 +127,7 @@ private:
|
||||
details::TimerObjectWrap _object;
|
||||
Fn<void()> _callback;
|
||||
base::binary_guard _running;
|
||||
TimeMs _next = 0;
|
||||
crl::time _next = 0;
|
||||
int _timeout = 0;
|
||||
|
||||
Qt::TimerType _type : 2;
|
||||
|
||||
@@ -76,6 +76,7 @@ struct flat_multi_map_pair_type {
|
||||
|
||||
const Key first;
|
||||
Value second;
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
@@ -316,6 +317,18 @@ public:
|
||||
}
|
||||
flat_multi_map &operator=(flat_multi_map &&other) = default;
|
||||
|
||||
template <
|
||||
typename Iterator,
|
||||
typename = typename std::iterator_traits<Iterator>::iterator_category>
|
||||
flat_multi_map(Iterator first, Iterator last)
|
||||
: _data(first, last) {
|
||||
std::sort(std::begin(impl()), std::end(impl()), compare());
|
||||
}
|
||||
|
||||
flat_multi_map(std::initializer_list<pair_type> iter)
|
||||
: flat_multi_map(iter.begin(), iter.end()) {
|
||||
}
|
||||
|
||||
size_type size() const {
|
||||
return impl().size();
|
||||
}
|
||||
@@ -614,6 +627,20 @@ public:
|
||||
using reverse_iterator = typename parent::reverse_iterator;
|
||||
using const_reverse_iterator = typename parent::const_reverse_iterator;
|
||||
|
||||
flat_map() = default;
|
||||
|
||||
template <
|
||||
typename Iterator,
|
||||
typename = typename std::iterator_traits<Iterator>::iterator_category
|
||||
>
|
||||
flat_map(Iterator first, Iterator last) : parent(first, last) {
|
||||
finalize();
|
||||
}
|
||||
|
||||
flat_map(std::initializer_list<pair_type> iter) : parent(iter.begin(), iter.end()) {
|
||||
finalize();
|
||||
}
|
||||
|
||||
using parent::parent;
|
||||
using parent::size;
|
||||
using parent::empty;
|
||||
@@ -732,6 +759,74 @@ public:
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
private:
|
||||
void finalize() {
|
||||
this->impl().erase(
|
||||
std::unique(
|
||||
std::begin(this->impl()),
|
||||
std::end(this->impl()),
|
||||
[&](auto &&a, auto &&b) {
|
||||
return !this->compare()(a, b);
|
||||
}
|
||||
),
|
||||
std::end(this->impl()));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
// Structured bindings support.
|
||||
namespace std {
|
||||
|
||||
template <typename Key, typename Value>
|
||||
class tuple_size<base::flat_multi_map_pair_type<Key, Value>>
|
||||
: public integral_constant<size_t, 2> {
|
||||
};
|
||||
|
||||
template <typename Key, typename Value>
|
||||
class tuple_element<0, base::flat_multi_map_pair_type<Key, Value>> {
|
||||
public:
|
||||
using type = const Key;
|
||||
};
|
||||
|
||||
template <typename Key, typename Value>
|
||||
class tuple_element<1, base::flat_multi_map_pair_type<Key, Value>> {
|
||||
public:
|
||||
using type = Value;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
// Structured bindings support.
|
||||
namespace base {
|
||||
namespace details {
|
||||
|
||||
template <std::size_t N, typename Key, typename Value>
|
||||
using flat_multi_map_pair_element = std::tuple_element_t<
|
||||
N,
|
||||
flat_multi_map_pair_type<Key, Value>>;
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <std::size_t N, typename Key, typename Value>
|
||||
auto get(base::flat_multi_map_pair_type<Key, Value> &value)
|
||||
-> details::flat_multi_map_pair_element<N, Key, Value> & {
|
||||
if constexpr (N == 0) {
|
||||
return value.first;
|
||||
} else {
|
||||
return value.second;
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t N, typename Key, typename Value>
|
||||
auto get(const base::flat_multi_map_pair_type<Key, Value> &value)
|
||||
-> const details::flat_multi_map_pair_element<N, Key, Value> & {
|
||||
if constexpr (N == 0) {
|
||||
return value.first;
|
||||
} else {
|
||||
return value.second;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
||||
@@ -91,3 +91,31 @@ TEST_CASE("flat_maps custom comparator", "[flat_map]") {
|
||||
checkSorted();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("flat_maps structured bindings", "[flat_map]") {
|
||||
base::flat_map<int, std::unique_ptr<double>> v;
|
||||
v.emplace(0, std::make_unique<double>(0.));
|
||||
v.emplace(1, std::make_unique<double>(1.));
|
||||
|
||||
SECTION("structred binded range-based for loop") {
|
||||
for (const auto &[key, value] : v) {
|
||||
REQUIRE(key == int(std::round(*value)));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("non-const structured binded range-based for loop") {
|
||||
base::flat_map<int, int> second = {
|
||||
{ 1, 1 },
|
||||
{ 2, 2 },
|
||||
{ 2, 3 },
|
||||
{ 3, 3 },
|
||||
};
|
||||
REQUIRE(second.size() == 3);
|
||||
//for (auto [a, b] : second) { // #MSVC Bug, reported
|
||||
// REQUIRE(a == b);
|
||||
//}
|
||||
for (const auto [a, b] : second) {
|
||||
REQUIRE(a == b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,36 +602,38 @@ public:
|
||||
using parent::contains;
|
||||
using parent::erase;
|
||||
|
||||
iterator insert(const Type &value) {
|
||||
std::pair<iterator, bool> insert(const Type &value) {
|
||||
if (this->empty() || this->compare()(value, this->front())) {
|
||||
this->impl().push_front(value);
|
||||
return this->begin();
|
||||
return std::make_pair(this->begin(), true);
|
||||
} else if (this->compare()(this->back(), value)) {
|
||||
this->impl().push_back(value);
|
||||
return (this->end() - 1);
|
||||
return std::make_pair(this->end() - 1, true);
|
||||
}
|
||||
auto where = this->getLowerBound(value);
|
||||
if (this->compare()(value, *where)) {
|
||||
return this->impl().insert(where, value);
|
||||
return std::make_pair(this->impl().insert(where, value), true);
|
||||
}
|
||||
return this->end();
|
||||
return std::make_pair(where, false);
|
||||
}
|
||||
iterator insert(Type &&value) {
|
||||
std::pair<iterator, bool> insert(Type &&value) {
|
||||
if (this->empty() || this->compare()(value, this->front())) {
|
||||
this->impl().push_front(std::move(value));
|
||||
return this->begin();
|
||||
return std::make_pair(this->begin(), true);
|
||||
} else if (this->compare()(this->back(), value)) {
|
||||
this->impl().push_back(std::move(value));
|
||||
return (this->end() - 1);
|
||||
return std::make_pair(this->end() - 1, true);
|
||||
}
|
||||
auto where = this->getLowerBound(value);
|
||||
if (this->compare()(value, *where)) {
|
||||
return this->impl().insert(where, std::move(value));
|
||||
return std::make_pair(
|
||||
this->impl().insert(where, std::move(value)),
|
||||
true);
|
||||
}
|
||||
return this->end();
|
||||
return std::make_pair(where, false);
|
||||
}
|
||||
template <typename... Args>
|
||||
iterator emplace(Args&&... args) {
|
||||
std::pair<iterator, bool> emplace(Args&&... args) {
|
||||
return this->insert(Type(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,20 @@ public:
|
||||
|
||||
using value_type = typename Container::value_type;
|
||||
using difference_type = typename Container::difference_type;
|
||||
using pointer = typename Container::pointer;
|
||||
using reference = typename Container::reference;
|
||||
using pointer = std::conditional_t<
|
||||
std::is_const_v<Container>,
|
||||
typename Container::const_pointer,
|
||||
typename Container::pointer>;
|
||||
using reference = std::conditional_t<
|
||||
std::is_const_v<Container>,
|
||||
typename Container::const_reference,
|
||||
typename Container::reference>;
|
||||
using base_type = std::conditional_t<
|
||||
std::is_const_v<Container>,
|
||||
typename Container::const_iterator,
|
||||
typename Container::iterator>;
|
||||
|
||||
index_based_iterator(
|
||||
Container *container,
|
||||
typename Container::iterator impl)
|
||||
index_based_iterator(Container *container, base_type impl)
|
||||
: _container(container)
|
||||
, _index(impl - _container->begin()) {
|
||||
}
|
||||
@@ -99,7 +107,7 @@ public:
|
||||
return !(*this < other);
|
||||
}
|
||||
|
||||
typename Container::iterator base() const {
|
||||
base_type base() const {
|
||||
return _container->begin() + _index;
|
||||
}
|
||||
|
||||
|
||||
69
Telegram/SourceFiles/base/last_used_cache.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace base {
|
||||
|
||||
template <typename Entry>
|
||||
class last_used_cache {
|
||||
public:
|
||||
void up(Entry entry);
|
||||
void remove(Entry entry);
|
||||
void clear();
|
||||
|
||||
Entry take_lowest();
|
||||
|
||||
private:
|
||||
std::list<Entry> _queue;
|
||||
std::unordered_map<Entry, typename std::list<Entry>::iterator> _map;
|
||||
|
||||
};
|
||||
|
||||
template <typename Entry>
|
||||
void last_used_cache<Entry>::up(Entry entry) {
|
||||
if (!_queue.empty() && _queue.back() == entry) {
|
||||
return;
|
||||
}
|
||||
const auto i = _map.find(entry);
|
||||
if (i != end(_map)) {
|
||||
_queue.splice(end(_queue), _queue, i->second);
|
||||
} else {
|
||||
_map.emplace(entry, _queue.insert(end(_queue), entry));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Entry>
|
||||
void last_used_cache<Entry>::remove(Entry entry) {
|
||||
const auto i = _map.find(entry);
|
||||
if (i != end(_map)) {
|
||||
_queue.erase(i->second);
|
||||
_map.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Entry>
|
||||
void last_used_cache<Entry>::clear() {
|
||||
_queue.clear();
|
||||
_map.clear();
|
||||
}
|
||||
|
||||
template <typename Entry>
|
||||
Entry last_used_cache<Entry>::take_lowest() {
|
||||
if (_queue.empty()) {
|
||||
return Entry();
|
||||
}
|
||||
auto result = std::move(_queue.front());
|
||||
_queue.erase(begin(_queue));
|
||||
_map.erase(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
@@ -21,6 +21,10 @@ extern "C" {
|
||||
#include <openssl/evp.h>
|
||||
} // extern "C"
|
||||
|
||||
#ifdef small
|
||||
#undef small
|
||||
#endif // small
|
||||
|
||||
namespace openssl {
|
||||
|
||||
class Context {
|
||||
|
||||
@@ -35,9 +35,12 @@ public:
|
||||
const QRegularExpressionMatch *operator->() const {
|
||||
return &data_;
|
||||
}
|
||||
explicit operator bool() const {
|
||||
bool valid() const {
|
||||
return data_.hasMatch();
|
||||
}
|
||||
explicit operator bool() const {
|
||||
return valid();
|
||||
}
|
||||
|
||||
private:
|
||||
QRegularExpressionMatch data_;
|
||||
|
||||
@@ -40,7 +40,7 @@ Timer::Timer(Fn<void()> callback)
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void Timer::start(TimeMs timeout, Qt::TimerType type, Repeat repeat) {
|
||||
void Timer::start(crl::time timeout, Qt::TimerType type, Repeat repeat) {
|
||||
cancel();
|
||||
|
||||
_type = type;
|
||||
@@ -49,7 +49,7 @@ void Timer::start(TimeMs timeout, Qt::TimerType type, Repeat repeat) {
|
||||
setTimeout(timeout);
|
||||
_timerId = startTimer(_timeout, _type);
|
||||
if (_timerId) {
|
||||
_next = crl::time() + _timeout;
|
||||
_next = crl::now() + _timeout;
|
||||
} else {
|
||||
_next = 0;
|
||||
}
|
||||
@@ -61,12 +61,12 @@ void Timer::cancel() {
|
||||
}
|
||||
}
|
||||
|
||||
TimeMs Timer::remainingTime() const {
|
||||
crl::time Timer::remainingTime() const {
|
||||
if (!isActive()) {
|
||||
return -1;
|
||||
}
|
||||
auto now = crl::time();
|
||||
return (_next > now) ? (_next - now) : TimeMs(0);
|
||||
const auto now = crl::now();
|
||||
return (_next > now) ? (_next - now) : crl::time(0);
|
||||
}
|
||||
|
||||
void Timer::Adjust() {
|
||||
@@ -87,7 +87,7 @@ void Timer::adjust() {
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::setTimeout(TimeMs timeout) {
|
||||
void Timer::setTimeout(crl::time timeout) {
|
||||
Expects(timeout >= 0 && timeout <= std::numeric_limits<int>::max());
|
||||
|
||||
_timeout = static_cast<unsigned int>(timeout);
|
||||
@@ -102,7 +102,7 @@ void Timer::timerEvent(QTimerEvent *e) {
|
||||
if (_adjusted) {
|
||||
start(_timeout, _type, repeat());
|
||||
} else {
|
||||
_next = crl::time() + _timeout;
|
||||
_next = crl::now() + _timeout;
|
||||
}
|
||||
} else {
|
||||
cancel();
|
||||
@@ -114,7 +114,7 @@ void Timer::timerEvent(QTimerEvent *e) {
|
||||
}
|
||||
|
||||
int DelayedCallTimer::call(
|
||||
TimeMs timeout,
|
||||
crl::time timeout,
|
||||
FnMut<void()> callback,
|
||||
Qt::TimerType type) {
|
||||
Expects(timeout >= 0);
|
||||
|
||||
@@ -21,8 +21,8 @@ public:
|
||||
Fn<void()> callback = nullptr);
|
||||
explicit Timer(Fn<void()> callback = nullptr);
|
||||
|
||||
static Qt::TimerType DefaultType(TimeMs timeout) {
|
||||
constexpr auto kThreshold = TimeMs(1000);
|
||||
static Qt::TimerType DefaultType(crl::time timeout) {
|
||||
constexpr auto kThreshold = crl::time(1000);
|
||||
return (timeout > kThreshold) ? Qt::CoarseTimer : Qt::PreciseTimer;
|
||||
}
|
||||
|
||||
@@ -30,19 +30,19 @@ public:
|
||||
_callback = std::move(callback);
|
||||
}
|
||||
|
||||
void callOnce(TimeMs timeout) {
|
||||
void callOnce(crl::time timeout) {
|
||||
callOnce(timeout, DefaultType(timeout));
|
||||
}
|
||||
|
||||
void callEach(TimeMs timeout) {
|
||||
void callEach(crl::time timeout) {
|
||||
callEach(timeout, DefaultType(timeout));
|
||||
}
|
||||
|
||||
void callOnce(TimeMs timeout, Qt::TimerType type) {
|
||||
void callOnce(crl::time timeout, Qt::TimerType type) {
|
||||
start(timeout, type, Repeat::SingleShot);
|
||||
}
|
||||
|
||||
void callEach(TimeMs timeout, Qt::TimerType type) {
|
||||
void callEach(crl::time timeout, Qt::TimerType type) {
|
||||
start(timeout, type, Repeat::Interval);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
}
|
||||
|
||||
void cancel();
|
||||
TimeMs remainingTime() const;
|
||||
crl::time remainingTime() const;
|
||||
|
||||
static void Adjust();
|
||||
|
||||
@@ -63,10 +63,10 @@ private:
|
||||
Interval = 0,
|
||||
SingleShot = 1,
|
||||
};
|
||||
void start(TimeMs timeout, Qt::TimerType type, Repeat repeat);
|
||||
void start(crl::time timeout, Qt::TimerType type, Repeat repeat);
|
||||
void adjust();
|
||||
|
||||
void setTimeout(TimeMs timeout);
|
||||
void setTimeout(crl::time timeout);
|
||||
int timeout() const;
|
||||
|
||||
void setRepeat(Repeat repeat) {
|
||||
@@ -77,7 +77,7 @@ private:
|
||||
}
|
||||
|
||||
Fn<void()> _callback;
|
||||
TimeMs _next = 0;
|
||||
crl::time _next = 0;
|
||||
int _timeout = 0;
|
||||
int _timerId = 0;
|
||||
|
||||
@@ -89,7 +89,7 @@ private:
|
||||
|
||||
class DelayedCallTimer final : private QObject {
|
||||
public:
|
||||
int call(TimeMs timeout, FnMut<void()> callback) {
|
||||
int call(crl::time timeout, FnMut<void()> callback) {
|
||||
return call(
|
||||
timeout,
|
||||
std::move(callback),
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
}
|
||||
|
||||
int call(
|
||||
TimeMs timeout,
|
||||
crl::time timeout,
|
||||
FnMut<void()> callback,
|
||||
Qt::TimerType type);
|
||||
void cancel(int callId);
|
||||
|
||||
@@ -57,12 +57,21 @@ public:
|
||||
}
|
||||
|
||||
~has_weak_ptr() {
|
||||
if (auto alive = _alive.load()) {
|
||||
if (const auto alive = _alive.load()) {
|
||||
alive->value.store(nullptr);
|
||||
details::decrement(alive);
|
||||
}
|
||||
}
|
||||
|
||||
friend inline void invalidate_weak_ptrs(has_weak_ptr *object) {
|
||||
if (auto alive = object->_alive.load()) {
|
||||
if (object->_alive.compare_exchange_strong(alive, nullptr)) {
|
||||
alive->value.store(nullptr);
|
||||
details::decrement(alive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Child>
|
||||
friend class weak_ptr;
|
||||
|
||||
@@ -13,6 +13,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "zip.h"
|
||||
#include "unzip.h"
|
||||
|
||||
#ifdef small
|
||||
#undef small
|
||||
#endif // small
|
||||
|
||||
namespace zlib {
|
||||
namespace internal {
|
||||
|
||||
@@ -172,15 +176,28 @@ public:
|
||||
return error();
|
||||
}
|
||||
|
||||
int goToFirstFile() {
|
||||
if (error() == UNZ_OK) {
|
||||
_error = _handle ? unzGoToFirstFile(_handle) : -1;
|
||||
}
|
||||
return error();
|
||||
}
|
||||
|
||||
int goToNextFile() {
|
||||
if (error() == UNZ_OK) {
|
||||
_error = _handle ? unzGoToNextFile(_handle) : -1;
|
||||
}
|
||||
return error();
|
||||
}
|
||||
|
||||
int getCurrentFileInfo(
|
||||
unz_file_info *pfile_info,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize
|
||||
) {
|
||||
unz_file_info *pfile_info,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize) {
|
||||
if (error() == UNZ_OK) {
|
||||
_error = _handle ? unzGetCurrentFileInfo(
|
||||
_handle,
|
||||
@@ -196,6 +213,21 @@ public:
|
||||
return error();
|
||||
}
|
||||
|
||||
QString getCurrentFileName() {
|
||||
unz_file_info info = { 0 };
|
||||
constexpr auto kMaxName = 128;
|
||||
char name[kMaxName + 1] = { 0 };
|
||||
const auto result = getCurrentFileInfo(
|
||||
&info,
|
||||
name,
|
||||
kMaxName,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
0);
|
||||
return (result == UNZ_OK) ? QString::fromUtf8(name) : QString();
|
||||
}
|
||||
|
||||
int openCurrentFile() {
|
||||
if (error() == UNZ_OK) {
|
||||
_error = _handle ? unzOpenCurrentFile(_handle) : -1;
|
||||
|
||||
@@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "application.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "styles/style_boxes.h"
|
||||
@@ -20,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "core/update_checker.h"
|
||||
|
||||
AboutBox::AboutBox(QWidget *parent)
|
||||
: _version(this, lng_about_version(lt_version, QString::fromLatin1(AppVersionStr.c_str()) + (cAlphaVersion() ? qsl(" alpha %1").arg(cAlphaVersion()) : (AppBetaVersion ? " beta" : ""))), st::aboutVersionLink)
|
||||
: _version(this, lng_about_version(lt_version, currentVersionText()), st::aboutVersionLink)
|
||||
, _text1(this, lang(lng_about_text_1), Ui::FlatLabel::InitType::Rich, st::aboutLabel)
|
||||
, _text2(this, lang(lng_about_text_2), Ui::FlatLabel::InitType::Rich, st::aboutLabel)
|
||||
, _text3(this, st::aboutLabel) {
|
||||
@@ -70,7 +69,7 @@ void AboutBox::showVersionHistory() {
|
||||
}
|
||||
url = url.arg(qsl("talpha%1_%2").arg(cRealAlphaVersion()).arg(Core::countAlphaVersionSignature(cRealAlphaVersion())));
|
||||
|
||||
Application::clipboard()->setText(url);
|
||||
QApplication::clipboard()->setText(url);
|
||||
|
||||
Ui::show(Box<InformBox>("The link to the current private alpha version of Telegram Desktop was copied to the clipboard."));
|
||||
} else {
|
||||
@@ -87,18 +86,24 @@ void AboutBox::keyPressEvent(QKeyEvent *e) {
|
||||
}
|
||||
|
||||
QString telegramFaqLink() {
|
||||
auto result = qsl("https://telegram.org/faq");
|
||||
auto language = Lang::Current().id();
|
||||
for (auto faqLanguage : { "de", "es", "it", "ko", "br" }) {
|
||||
if (language.startsWith(QLatin1String(faqLanguage))) {
|
||||
result.append('/').append(faqLanguage);
|
||||
const auto result = qsl("https://telegram.org/faq");
|
||||
const auto langpacked = [&](const char *language) {
|
||||
return result + '/' + language;
|
||||
};
|
||||
const auto current = Lang::Current().id();
|
||||
for (const auto language : { "de", "es", "it", "ko" }) {
|
||||
if (current.startsWith(QLatin1String(language))) {
|
||||
return langpacked(language);
|
||||
}
|
||||
}
|
||||
if (current.startsWith(qstr("pt-br"))) {
|
||||
return langpacked("br");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString currentVersionText() {
|
||||
auto result = QString::fromLatin1(AppVersionStr.c_str());
|
||||
auto result = QString::fromLatin1(AppVersionStr);
|
||||
if (cAlphaVersion()) {
|
||||
result += qsl(" alpha %1").arg(cAlphaVersion() % 1000);
|
||||
} else if (AppBetaVersion) {
|
||||
|
||||
@@ -77,7 +77,9 @@ void BoxContent::finishPrepare() {
|
||||
void BoxContent::finishScrollCreate() {
|
||||
Expects(_scroll != nullptr);
|
||||
|
||||
_scroll->show();
|
||||
if (!_scroll->isHidden()) {
|
||||
_scroll->show();
|
||||
}
|
||||
updateScrollAreaGeometry();
|
||||
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
|
||||
connect(_scroll, SIGNAL(innerResized()), this, SLOT(onInnerResize()));
|
||||
@@ -143,6 +145,16 @@ void BoxContent::onInnerResize() {
|
||||
updateShadowsVisibility();
|
||||
}
|
||||
|
||||
void BoxContent::setDimensionsToContent(
|
||||
int newWidth,
|
||||
not_null<Ui::RpWidget*> content) {
|
||||
content->resizeToWidth(newWidth);
|
||||
content->heightValue(
|
||||
) | rpl::start_with_next([=](int height) {
|
||||
setDimensions(newWidth, height);
|
||||
}, content->lifetime());
|
||||
}
|
||||
|
||||
void BoxContent::setInnerTopSkip(int innerTopSkip, bool scrollBottomFixed) {
|
||||
if (_innerTopSkip != innerTopSkip) {
|
||||
auto delta = innerTopSkip - _innerTopSkip;
|
||||
@@ -366,11 +378,18 @@ void AbstractBox::updateButtonsPositions() {
|
||||
if (_leftButton) {
|
||||
_leftButton->moveToLeft(right, top);
|
||||
}
|
||||
for_const (auto &button, _buttons) {
|
||||
for (const auto &button : _buttons) {
|
||||
button->moveToRight(right, top);
|
||||
right += button->width() + padding.left();
|
||||
}
|
||||
}
|
||||
if (_topButton) {
|
||||
_topButton->moveToRight(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
QPointer<QWidget> AbstractBox::outerContainer() {
|
||||
return parentWidget();
|
||||
}
|
||||
|
||||
void AbstractBox::updateTitlePosition() {
|
||||
@@ -387,6 +406,7 @@ void AbstractBox::clearButtons() {
|
||||
button.destroy();
|
||||
}
|
||||
_leftButton.destroy();
|
||||
_topButton = nullptr;
|
||||
}
|
||||
|
||||
QPointer<Ui::RoundButton> AbstractBox::addButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) {
|
||||
@@ -407,6 +427,15 @@ QPointer<Ui::RoundButton> AbstractBox::addLeftButton(Fn<QString()> textFactory,
|
||||
return result;
|
||||
}
|
||||
|
||||
QPointer<Ui::IconButton> AbstractBox::addTopButton(const style::IconButton &st, Fn<void()> clickCallback) {
|
||||
_topButton = base::make_unique_q<Ui::IconButton>(this, st);
|
||||
auto result = QPointer<Ui::IconButton>(_topButton.get());
|
||||
result->setClickedCallback(std::move(clickCallback));
|
||||
result->show();
|
||||
updateButtonsPositions();
|
||||
return result;
|
||||
}
|
||||
|
||||
void AbstractBox::setDimensions(int newWidth, int maxHeight) {
|
||||
_maxContentHeight = maxHeight;
|
||||
|
||||
|
||||
@@ -8,10 +8,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#pragma once
|
||||
|
||||
#include "window/layer_widget.h"
|
||||
#include "base/unique_qptr.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
namespace style {
|
||||
struct RoundButton;
|
||||
struct IconButton;
|
||||
struct ScrollArea;
|
||||
} // namespace style
|
||||
|
||||
@@ -35,6 +37,7 @@ public:
|
||||
virtual void clearButtons() = 0;
|
||||
virtual QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) = 0;
|
||||
virtual QPointer<Ui::RoundButton> addLeftButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) = 0;
|
||||
virtual QPointer<Ui::IconButton> addTopButton(const style::IconButton &st, Fn<void()> clickCallback) = 0;
|
||||
virtual void updateButtonsPositions() = 0;
|
||||
|
||||
virtual void showBox(
|
||||
@@ -56,6 +59,8 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual QPointer<QWidget> outerContainer() = 0;
|
||||
|
||||
};
|
||||
|
||||
class BoxContent : public Ui::RpWidget, protected base::Subscriber {
|
||||
@@ -98,8 +103,14 @@ public:
|
||||
void clearButtons() {
|
||||
getDelegate()->clearButtons();
|
||||
}
|
||||
QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, Fn<void()> clickCallback);
|
||||
QPointer<Ui::RoundButton> addLeftButton(Fn<QString()> textFactory, Fn<void()> clickCallback);
|
||||
QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, Fn<void()> clickCallback = nullptr);
|
||||
QPointer<Ui::RoundButton> addLeftButton(Fn<QString()> textFactory, Fn<void()> clickCallback = nullptr);
|
||||
QPointer<Ui::IconButton> addTopButton(const style::IconButton &st, Fn<void()> clickCallback = nullptr) {
|
||||
return getDelegate()->addTopButton(st, std::move(clickCallback));
|
||||
}
|
||||
QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, const style::RoundButton &st) {
|
||||
return getDelegate()->addButton(std::move(textFactory), nullptr, st);
|
||||
}
|
||||
QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) {
|
||||
return getDelegate()->addButton(std::move(textFactory), std::move(clickCallback), st);
|
||||
}
|
||||
@@ -118,12 +129,15 @@ public:
|
||||
_boxClosingStream.fire({});
|
||||
}
|
||||
|
||||
void setDelegate(BoxContentDelegate *newDelegate) {
|
||||
void setDelegate(not_null<BoxContentDelegate*> newDelegate) {
|
||||
_delegate = newDelegate;
|
||||
_preparing = true;
|
||||
prepare();
|
||||
finishPrepare();
|
||||
}
|
||||
not_null<BoxContentDelegate*> getDelegate() const {
|
||||
return _delegate;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void onScrollToY(int top, int bottom = -1);
|
||||
@@ -147,6 +161,9 @@ protected:
|
||||
void setDimensions(int newWidth, int maxHeight) {
|
||||
getDelegate()->setDimensions(newWidth, maxHeight);
|
||||
}
|
||||
void setDimensionsToContent(
|
||||
int newWidth,
|
||||
not_null<Ui::RpWidget*> content);
|
||||
void setInnerTopSkip(int topSkip, bool scrollBottomFixed = false);
|
||||
void setInnerBottomSkip(int bottomSkip);
|
||||
|
||||
@@ -187,10 +204,6 @@ protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
|
||||
not_null<BoxContentDelegate*> getDelegate() const {
|
||||
return _delegate;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void onScroll();
|
||||
void onInnerResize();
|
||||
@@ -247,7 +260,9 @@ public:
|
||||
void clearButtons() override;
|
||||
QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) override;
|
||||
QPointer<Ui::RoundButton> addLeftButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) override;
|
||||
QPointer<Ui::IconButton> addTopButton(const style::IconButton &st, Fn<void()> clickCallback) override;
|
||||
void updateButtonsPositions() override;
|
||||
QPointer<QWidget> outerContainer() override;
|
||||
|
||||
void setDimensions(int newWidth, int maxHeight) override;
|
||||
|
||||
@@ -314,6 +329,7 @@ private:
|
||||
|
||||
std::vector<object_ptr<Ui::RoundButton>> _buttons;
|
||||
object_ptr<Ui::RoundButton> _leftButton = { nullptr };
|
||||
base::unique_qptr<Ui::IconButton> _topButton = { nullptr };
|
||||
|
||||
};
|
||||
|
||||
@@ -332,3 +348,45 @@ enum CreatingGroupType {
|
||||
CreatingGroupGroup,
|
||||
CreatingGroupChannel,
|
||||
};
|
||||
|
||||
class BoxPointer {
|
||||
public:
|
||||
BoxPointer() = default;
|
||||
BoxPointer(const BoxPointer &other) = default;
|
||||
BoxPointer(BoxPointer &&other) : _value(base::take(other._value)) {
|
||||
}
|
||||
BoxPointer &operator=(const BoxPointer &other) {
|
||||
if (_value != other._value) {
|
||||
destroy();
|
||||
_value = other._value;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
BoxPointer &operator=(BoxPointer &&other) {
|
||||
if (_value != other._value) {
|
||||
destroy();
|
||||
_value = base::take(other._value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
BoxPointer &operator=(BoxContent *other) {
|
||||
if (_value != other) {
|
||||
destroy();
|
||||
_value = other;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~BoxPointer() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
private:
|
||||
void destroy() {
|
||||
if (const auto value = base::take(_value)) {
|
||||
value->closeBox();
|
||||
}
|
||||
}
|
||||
|
||||
QPointer<BoxContent> _value;
|
||||
|
||||
};
|
||||
|
||||
@@ -10,13 +10,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "messenger.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "base/flat_set.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/photo_crop_box.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "boxes/peers/add_participants_box.h"
|
||||
#include "boxes/peers/edit_participant_box.h"
|
||||
#include "boxes/peers/edit_participants_box.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "core/application.h"
|
||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
@@ -24,6 +28,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/text_options.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_session.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "apiwrap.h"
|
||||
@@ -58,7 +66,7 @@ style::InputField CreateBioFieldStyle() {
|
||||
|
||||
QString PeerFloodErrorText(PeerFloodType type) {
|
||||
auto link = textcmdLink(
|
||||
Messenger::Instance().createInternalLinkFull(qsl("spambot")),
|
||||
Core::App().createInternalLinkFull(qsl("spambot")),
|
||||
lang(lng_cant_more_info));
|
||||
if (type == PeerFloodType::InviteGroup) {
|
||||
return lng_cant_invite_not_contact(lt_more_info, link);
|
||||
@@ -66,6 +74,77 @@ QString PeerFloodErrorText(PeerFloodType type) {
|
||||
return lng_cant_send_to_not_contact(lt_more_info, link);
|
||||
}
|
||||
|
||||
void ShowAddParticipantsError(
|
||||
const QString &error,
|
||||
not_null<PeerData*> chat,
|
||||
const std::vector<not_null<UserData*>> &users) {
|
||||
if (error == qstr("USER_BOT")) {
|
||||
const auto channel = chat->asChannel();
|
||||
if ((users.size() == 1)
|
||||
&& (users.front()->botInfo != nullptr)
|
||||
&& channel
|
||||
&& !channel->isMegagroup()
|
||||
&& channel->canAddAdmins()) {
|
||||
const auto makeAdmin = [=] {
|
||||
const auto user = users.front();
|
||||
const auto weak = std::make_shared<QPointer<EditAdminBox>>();
|
||||
const auto close = [=](auto&&...) {
|
||||
if (*weak) {
|
||||
(*weak)->closeBox();
|
||||
}
|
||||
};
|
||||
const auto saveCallback = SaveAdminCallback(
|
||||
channel,
|
||||
user,
|
||||
close,
|
||||
close);
|
||||
auto box = Box<EditAdminBox>(
|
||||
channel,
|
||||
user,
|
||||
MTP_chatAdminRights(MTP_flags(0)));
|
||||
box->setSaveCallback(saveCallback);
|
||||
*weak = Ui::show(std::move(box));
|
||||
};
|
||||
Ui::show(
|
||||
Box<ConfirmBox>(
|
||||
lang(lng_cant_invite_offer_admin),
|
||||
lang(lng_cant_invite_make_admin),
|
||||
lang(lng_cancel),
|
||||
makeAdmin),
|
||||
LayerOption::KeepOther);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const auto bot = ranges::find_if(users, [](not_null<UserData*> user) {
|
||||
return user->botInfo != nullptr;
|
||||
});
|
||||
const auto hasBot = (bot != end(users));
|
||||
const auto text = [&] {
|
||||
if (error == qstr("USER_BOT")) {
|
||||
return lang(lng_cant_invite_bot_to_channel);
|
||||
} else if (error == qstr("USER_LEFT_CHAT")) {
|
||||
// Trying to return a user who has left.
|
||||
} else if (error == qstr("USER_KICKED")) {
|
||||
// Trying to return a user who was kicked by admin.
|
||||
return lang(lng_cant_invite_banned);
|
||||
} else if (error == qstr("USER_PRIVACY_RESTRICTED")) {
|
||||
return lang(lng_cant_invite_privacy);
|
||||
} else if (error == qstr("USER_NOT_MUTUAL_CONTACT")) {
|
||||
// Trying to return user who does not have me in contacts.
|
||||
return lang(lng_failed_add_not_mutual);
|
||||
} else if (error == qstr("USER_ALREADY_PARTICIPANT") && hasBot) {
|
||||
return lang(lng_bot_already_in_group);
|
||||
} else if (error == qstr("PEER_FLOOD")) {
|
||||
const auto isGroup = (chat->isChat() || chat->isMegagroup());
|
||||
return PeerFloodErrorText(isGroup
|
||||
? PeerFloodType::InviteGroup
|
||||
: PeerFloodType::InviteChannel);
|
||||
}
|
||||
return lang(lng_failed_add_participant);
|
||||
}();
|
||||
Ui::show(Box<InformBox>(text), LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
class RevokePublicLinkBox::Inner : public TWidget, private MTP::Sender {
|
||||
public:
|
||||
Inner(QWidget *parent, Fn<void()> revokeCallback);
|
||||
@@ -243,8 +322,9 @@ bool AddContactBox::onSaveUserFail(const RPCError &error) {
|
||||
if (MTP::isDefaultHandledError(error)) return false;
|
||||
|
||||
_addRequest = 0;
|
||||
QString err(error.type());
|
||||
QString firstName = _first->getLastText().trimmed(), lastName = _last->getLastText().trimmed();
|
||||
const auto &err = error.type();
|
||||
const auto firstName = _first->getLastText().trimmed();
|
||||
const auto lastName = _last->getLastText().trimmed();
|
||||
if (err == "CHAT_TITLE_NOT_MODIFIED") {
|
||||
_user->setName(firstName, lastName, _user->nameOrPhone, _user->username);
|
||||
closeBox();
|
||||
@@ -262,20 +342,21 @@ void AddContactBox::onImportDone(const MTPcontacts_ImportedContacts &res) {
|
||||
if (!isBoxShown() || !App::main()) return;
|
||||
|
||||
const auto &d = res.c_contacts_importedContacts();
|
||||
App::feedUsers(d.vusers);
|
||||
Auth().data().processUsers(d.vusers);
|
||||
|
||||
const auto &v = d.vimported.v;
|
||||
const auto user = [&]() -> UserData* {
|
||||
if (!v.isEmpty()) {
|
||||
auto &c = v.front().c_importedContact();
|
||||
if (c.vclient_id.v == _contactId) {
|
||||
return App::userLoaded(c.vuser_id.v);
|
||||
return Auth().data().userLoaded(c.vuser_id.v);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}();
|
||||
if (user) {
|
||||
if (user->contactStatus() == UserData::ContactStatus::Contact) {
|
||||
if (user->contactStatus() == UserData::ContactStatus::Contact
|
||||
|| user->session().supportMode()) {
|
||||
Ui::showPeerHistory(user, ShowAtTheEndMsgId);
|
||||
}
|
||||
Ui::hideLayer();
|
||||
@@ -289,7 +370,7 @@ void AddContactBox::onImportDone(const MTPcontacts_ImportedContacts &res) {
|
||||
|
||||
void AddContactBox::onSaveUserDone(const MTPcontacts_ImportedContacts &res) {
|
||||
auto &d = res.c_contacts_importedContacts();
|
||||
App::feedUsers(d.vusers);
|
||||
Auth().data().processUsers(d.vusers);
|
||||
closeBox();
|
||||
}
|
||||
|
||||
@@ -327,9 +408,9 @@ void GroupInfoBox::prepare() {
|
||||
|
||||
_photo.create(
|
||||
this,
|
||||
(_creating == CreatingGroupChannel)
|
||||
? peerFromChannel(0)
|
||||
: peerFromChat(0),
|
||||
lang((_creating == CreatingGroupChannel)
|
||||
? lng_create_channel_crop
|
||||
: lng_create_group_crop),
|
||||
Ui::UserpicButton::Role::ChangePhoto,
|
||||
st::defaultUserpicButton);
|
||||
_title.create(
|
||||
@@ -341,6 +422,9 @@ void GroupInfoBox::prepare() {
|
||||
_title->setMaxLength(kMaxGroupChannelTitle);
|
||||
_title->setInstantReplaces(Ui::InstantReplaces::Default());
|
||||
_title ->setInstantReplacesEnabled(Global::ReplaceEmojiValue());
|
||||
Ui::Emoji::SuggestionsController::Init(
|
||||
getDelegate()->outerContainer(),
|
||||
_title);
|
||||
|
||||
if (_creating == CreatingGroupChannel) {
|
||||
_description.create(
|
||||
@@ -357,6 +441,10 @@ void GroupInfoBox::prepare() {
|
||||
connect(_description, &Ui::InputField::resized, [=] { descriptionResized(); });
|
||||
connect(_description, &Ui::InputField::submitted, [=] { submit(); });
|
||||
connect(_description, &Ui::InputField::cancelled, [=] { closeBox(); });
|
||||
|
||||
Ui::Emoji::SuggestionsController::Init(
|
||||
getDelegate()->outerContainer(),
|
||||
_description);
|
||||
}
|
||||
|
||||
connect(_title, &Ui::InputField::submitted, [=] { submitName(); });
|
||||
@@ -403,7 +491,10 @@ void GroupInfoBox::submitName() {
|
||||
}
|
||||
}
|
||||
|
||||
void GroupInfoBox::createGroup(not_null<PeerListBox*> selectUsersBox, const QString &title, const std::vector<not_null<PeerData*>> &users) {
|
||||
void GroupInfoBox::createGroup(
|
||||
not_null<PeerListBox*> selectUsersBox,
|
||||
const QString &title,
|
||||
const std::vector<not_null<PeerData*>> &users) {
|
||||
if (_creationRequestId) return;
|
||||
|
||||
auto inputs = QVector<MTPInputUser>();
|
||||
@@ -418,10 +509,14 @@ void GroupInfoBox::createGroup(not_null<PeerListBox*> selectUsersBox, const QStr
|
||||
if (inputs.empty()) {
|
||||
return;
|
||||
}
|
||||
_creationRequestId = request(MTPmessages_CreateChat(MTP_vector<MTPInputUser>(inputs), MTP_string(title))).done([this](const MTPUpdates &result) {
|
||||
_creationRequestId = request(MTPmessages_CreateChat(
|
||||
MTP_vector<MTPInputUser>(inputs),
|
||||
MTP_string(title)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
auto image = _photo->takeResultImage();
|
||||
Ui::hideLayer();
|
||||
|
||||
App::main()->sentUpdatesReceived(result);
|
||||
Auth().api().applyUpdates(result);
|
||||
|
||||
auto success = base::make_optional(&result)
|
||||
| [](auto updates) -> std::optional<const QVector<MTPChat>*> {
|
||||
@@ -431,28 +526,32 @@ void GroupInfoBox::createGroup(not_null<PeerListBox*> selectUsersBox, const QStr
|
||||
case mtpc_updatesCombined:
|
||||
return &updates->c_updatesCombined().vchats.v;
|
||||
}
|
||||
LOG(("API Error: unexpected update cons %1 (GroupInfoBox::creationDone)").arg(updates->type()));
|
||||
LOG(("API Error: unexpected update cons %1 "
|
||||
"(GroupInfoBox::creationDone)").arg(updates->type()));
|
||||
return std::nullopt;
|
||||
}
|
||||
| [](auto chats) {
|
||||
return (!chats->empty() && chats->front().type() == mtpc_chat)
|
||||
return (!chats->empty()
|
||||
&& chats->front().type() == mtpc_chat)
|
||||
? base::make_optional(chats)
|
||||
: std::nullopt;
|
||||
}
|
||||
| [](auto chats) {
|
||||
return App::chat(chats->front().c_chat().vid.v);
|
||||
return Auth().data().chat(chats->front().c_chat().vid.v);
|
||||
}
|
||||
| [this](not_null<ChatData*> chat) {
|
||||
auto image = _photo->takeResultImage();
|
||||
| [&](not_null<ChatData*> chat) {
|
||||
if (!image.isNull()) {
|
||||
Auth().api().uploadPeerPhoto(chat, std::move(image));
|
||||
chat->session().api().uploadPeerPhoto(
|
||||
chat,
|
||||
std::move(image));
|
||||
}
|
||||
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
||||
};
|
||||
if (!success) {
|
||||
LOG(("API Error: chat not found in updates (ContactsBox::creationDone)"));
|
||||
LOG(("API Error: chat not found in updates "
|
||||
"(ContactsBox::creationDone)"));
|
||||
}
|
||||
}).fail([this, selectUsersBox](const RPCError &error) {
|
||||
}).fail([=](const RPCError &error) {
|
||||
_creationRequestId = 0;
|
||||
if (error.type() == qstr("NO_CHAT_TITLE")) {
|
||||
auto weak = make_weak(this);
|
||||
@@ -513,8 +612,7 @@ void GroupInfoBox::submit() {
|
||||
};
|
||||
Ui::show(
|
||||
Box<PeerListBox>(
|
||||
std::make_unique<AddParticipantsBoxController>(
|
||||
nullptr),
|
||||
std::make_unique<AddParticipantsBoxController>(),
|
||||
std::move(initBox)),
|
||||
LayerOption::KeepOther);
|
||||
}
|
||||
@@ -523,8 +621,12 @@ void GroupInfoBox::submit() {
|
||||
void GroupInfoBox::createChannel(const QString &title, const QString &description) {
|
||||
bool mega = false;
|
||||
auto flags = mega ? MTPchannels_CreateChannel::Flag::f_megagroup : MTPchannels_CreateChannel::Flag::f_broadcast;
|
||||
_creationRequestId = request(MTPchannels_CreateChannel(MTP_flags(flags), MTP_string(title), MTP_string(description))).done([this](const MTPUpdates &result) {
|
||||
App::main()->sentUpdatesReceived(result);
|
||||
_creationRequestId = request(MTPchannels_CreateChannel(
|
||||
MTP_flags(flags),
|
||||
MTP_string(title),
|
||||
MTP_string(description)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
Auth().api().applyUpdates(result);
|
||||
|
||||
auto success = base::make_optional(&result)
|
||||
| [](auto updates) -> std::optional<const QVector<MTPChat>*> {
|
||||
@@ -543,17 +645,19 @@ void GroupInfoBox::createChannel(const QString &title, const QString &descriptio
|
||||
: std::nullopt;
|
||||
}
|
||||
| [](auto chats) {
|
||||
return App::channel(chats->front().c_channel().vid.v);
|
||||
return Auth().data().channel(chats->front().c_channel().vid.v);
|
||||
}
|
||||
| [this](not_null<ChannelData*> channel) {
|
||||
| [&](not_null<ChannelData*> channel) {
|
||||
auto image = _photo->takeResultImage();
|
||||
if (!image.isNull()) {
|
||||
Auth().api().uploadPeerPhoto(channel, std::move(image));
|
||||
channel->session().api().uploadPeerPhoto(
|
||||
channel,
|
||||
std::move(image));
|
||||
}
|
||||
_createdChannel = channel;
|
||||
_creationRequestId = request(
|
||||
MTPchannels_ExportInvite(_createdChannel->inputChannel)
|
||||
).done([this](const MTPExportedChatInvite &result) {
|
||||
_creationRequestId = request(MTPmessages_ExportChatInvite(
|
||||
_createdChannel->input
|
||||
)).done([=](const MTPExportedChatInvite &result) {
|
||||
_creationRequestId = 0;
|
||||
if (result.type() == mtpc_chatInviteExported) {
|
||||
auto link = qs(result.c_chatInviteExported().vlink);
|
||||
@@ -731,7 +835,7 @@ void SetupChannelBox::mouseMoveEvent(QMouseEvent *e) {
|
||||
void SetupChannelBox::mousePressEvent(QMouseEvent *e) {
|
||||
if (_linkOver) {
|
||||
if (_channel->inviteLink().isEmpty()) {
|
||||
Auth().api().exportInviteLink(_channel);
|
||||
_channel->session().api().exportInviteLink(_channel);
|
||||
} else {
|
||||
QGuiApplication::clipboard()->setText(_channel->inviteLink());
|
||||
Ui::Toast::Show(lang(lng_create_channel_link_copied));
|
||||
@@ -755,26 +859,25 @@ void SetupChannelBox::updateSelected(const QPoint &cursorGlobalPosition) {
|
||||
}
|
||||
|
||||
void SetupChannelBox::save() {
|
||||
if (_privacyGroup->value() == Privacy::Private) {
|
||||
if (_saveRequestId) {
|
||||
return;
|
||||
} else if (_privacyGroup->value() == Privacy::Private) {
|
||||
if (_existing) {
|
||||
_sentUsername = QString();
|
||||
_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
|
||||
} else {
|
||||
closeBox();
|
||||
}
|
||||
} else {
|
||||
const auto link = _link->text().trimmed();
|
||||
if (link.isEmpty()) {
|
||||
_link->setFocus();
|
||||
_link->showError();
|
||||
return;
|
||||
}
|
||||
_sentUsername = link;
|
||||
_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
|
||||
}
|
||||
|
||||
if (_saveRequestId) return;
|
||||
|
||||
QString link = _link->text().trimmed();
|
||||
if (link.isEmpty()) {
|
||||
_link->setFocus();
|
||||
_link->showError();
|
||||
return;
|
||||
}
|
||||
|
||||
_sentUsername = link;
|
||||
_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
|
||||
}
|
||||
|
||||
void SetupChannelBox::handleChange() {
|
||||
@@ -1052,7 +1155,7 @@ void EditNameBox::save() {
|
||||
}
|
||||
|
||||
void EditNameBox::saveSelfDone(const MTPUser &user) {
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, user));
|
||||
_user->owner().processUsers(MTP_vector<MTPUser>(1, user));
|
||||
closeBox();
|
||||
}
|
||||
|
||||
@@ -1079,331 +1182,6 @@ bool EditNameBox::saveSelfFail(const RPCError &error) {
|
||||
return true;
|
||||
}
|
||||
|
||||
EditBioBox::EditBioBox(QWidget*, not_null<UserData*> self) : BoxContent()
|
||||
, _dynamicFieldStyle(CreateBioFieldStyle())
|
||||
, _self(self)
|
||||
, _bio(
|
||||
this,
|
||||
_dynamicFieldStyle,
|
||||
Ui::InputField::Mode::MultiLine,
|
||||
langFactory(lng_bio_placeholder),
|
||||
_self->about())
|
||||
, _countdown(this, QString(), Ui::FlatLabel::InitType::Simple, st::editBioCountdownLabel)
|
||||
, _about(this, lang(lng_bio_about), Ui::FlatLabel::InitType::Simple, st::aboutRevokePublicLabel) {
|
||||
}
|
||||
|
||||
void EditBioBox::prepare() {
|
||||
setTitle(langFactory(lng_bio_title));
|
||||
|
||||
addButton(langFactory(lng_settings_save), [this] { save(); });
|
||||
addButton(langFactory(lng_cancel), [this] { closeBox(); });
|
||||
_bio->setMaxLength(kMaxBioLength);
|
||||
_bio->setSubmitSettings(Ui::InputField::SubmitSettings::Both);
|
||||
auto cursor = _bio->textCursor();
|
||||
cursor.setPosition(_bio->getLastText().size());
|
||||
_bio->setTextCursor(cursor);
|
||||
connect(_bio, &Ui::InputField::submitted, [=] { save(); });
|
||||
connect(_bio, &Ui::InputField::resized, [=] { updateMaxHeight(); });
|
||||
connect(_bio, &Ui::InputField::changed, [=] { handleBioUpdated(); });
|
||||
_bio->setInstantReplaces(Ui::InstantReplaces::Default());
|
||||
_bio->setInstantReplacesEnabled(Global::ReplaceEmojiValue());
|
||||
handleBioUpdated();
|
||||
updateMaxHeight();
|
||||
}
|
||||
|
||||
void EditBioBox::updateMaxHeight() {
|
||||
auto newHeight = st::contactPadding.top() + _bio->height() + st::boxLittleSkip + _about->height() + st::boxPadding.bottom() + st::contactPadding.bottom();
|
||||
setDimensions(st::boxWideWidth, newHeight);
|
||||
}
|
||||
|
||||
void EditBioBox::handleBioUpdated() {
|
||||
auto text = _bio->getLastText();
|
||||
if (text.indexOf('\n') >= 0) {
|
||||
auto position = _bio->textCursor().position();
|
||||
_bio->setText(text.replace('\n', ' '));
|
||||
auto cursor = _bio->textCursor();
|
||||
cursor.setPosition(position);
|
||||
_bio->setTextCursor(cursor);
|
||||
}
|
||||
auto countLeft = qMax(kMaxBioLength - text.size(), 0);
|
||||
_countdown->setText(QString::number(countLeft));
|
||||
}
|
||||
|
||||
void EditBioBox::setInnerFocus() {
|
||||
_bio->setFocusFast();
|
||||
}
|
||||
|
||||
void EditBioBox::resizeEvent(QResizeEvent *e) {
|
||||
BoxContent::resizeEvent(e);
|
||||
|
||||
_bio->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _bio->height());
|
||||
_bio->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), st::contactPadding.top());
|
||||
_countdown->moveToRight(st::boxPadding.right(), _bio->y() + _dynamicFieldStyle.textMargins.top());
|
||||
_about->moveToLeft(st::boxPadding.left(), _bio->y() + _bio->height() + st::boxLittleSkip);
|
||||
}
|
||||
|
||||
void EditBioBox::save() {
|
||||
if (_requestId) return;
|
||||
|
||||
auto text = TextUtilities::PrepareForSending(_bio->getLastText());
|
||||
_sentBio = text;
|
||||
|
||||
auto flags = MTPaccount_UpdateProfile::Flag::f_about;
|
||||
_requestId = request(MTPaccount_UpdateProfile(MTP_flags(flags), MTPstring(), MTPstring(), MTP_string(text))).done([this](const MTPUser &result) {
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, result));
|
||||
_self->setAbout(_sentBio);
|
||||
closeBox();
|
||||
}).send();
|
||||
}
|
||||
|
||||
EditChannelBox::EditChannelBox(QWidget*, not_null<ChannelData*> channel)
|
||||
: _channel(channel)
|
||||
, _title(this, st::defaultInputField, langFactory(_channel->isMegagroup() ? lng_dlg_new_group_name : lng_dlg_new_channel_name), _channel->name)
|
||||
, _description(
|
||||
this,
|
||||
st::newGroupDescription,
|
||||
Ui::InputField::Mode::MultiLine,
|
||||
langFactory(lng_create_group_description),
|
||||
_channel->about())
|
||||
, _sign(this, lang(lng_edit_sign_messages), channel->addsSignature(), st::defaultBoxCheckbox)
|
||||
, _inviteGroup(std::make_shared<Ui::RadioenumGroup<Invites>>(channel->anyoneCanAddMembers() ? Invites::Everybody : Invites::OnlyAdmins))
|
||||
, _inviteEverybody(this, _inviteGroup, Invites::Everybody, lang(lng_edit_group_invites_everybody))
|
||||
, _inviteOnlyAdmins(this, _inviteGroup, Invites::OnlyAdmins, lang(lng_edit_group_invites_only_admins))
|
||||
, _publicLink(this, lang(channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link), st::boxLinkButton) {
|
||||
}
|
||||
|
||||
void EditChannelBox::prepare() {
|
||||
setTitle(langFactory(_channel->isMegagroup() ? lng_edit_group : lng_edit_channel_title));
|
||||
|
||||
addButton(langFactory(lng_settings_save), [this] { save(); });
|
||||
addButton(langFactory(lng_cancel), [this] { closeBox(); });
|
||||
|
||||
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::NameChanged, [this](const Notify::PeerUpdate &update) {
|
||||
if (update.peer == _channel) {
|
||||
handleChannelNameChange();
|
||||
}
|
||||
}));
|
||||
|
||||
setMouseTracking(true);
|
||||
|
||||
_title->setMaxLength(kMaxGroupChannelTitle);
|
||||
_title->setInstantReplaces(Ui::InstantReplaces::Default());
|
||||
_title->setInstantReplacesEnabled(Global::ReplaceEmojiValue());
|
||||
_description->setMaxLength(kMaxChannelDescription);
|
||||
_description->setInstantReplaces(Ui::InstantReplaces::Default());
|
||||
_description->setInstantReplacesEnabled(Global::ReplaceEmojiValue());
|
||||
|
||||
connect(_description, &Ui::InputField::resized, [=] { descriptionResized(); });
|
||||
connect(_description, &Ui::InputField::submitted, [=] { save(); });
|
||||
connect(_description, &Ui::InputField::cancelled, [=] { closeBox(); });
|
||||
|
||||
_publicLink->addClickHandler([=] { setupPublicLink(); });
|
||||
_publicLink->setVisible(_channel->canEditUsername());
|
||||
_sign->setVisible(canEditSignatures());
|
||||
_inviteEverybody->setVisible(canEditInvites());
|
||||
_inviteOnlyAdmins->setVisible(canEditInvites());
|
||||
|
||||
updateMaxHeight();
|
||||
}
|
||||
|
||||
void EditChannelBox::setInnerFocus() {
|
||||
_title->setFocusFast();
|
||||
}
|
||||
|
||||
void EditChannelBox::keyPressEvent(QKeyEvent *e) {
|
||||
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
||||
if (_title->hasFocus()) {
|
||||
save();
|
||||
}
|
||||
} else {
|
||||
BoxContent::keyPressEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void EditChannelBox::handleChannelNameChange() {
|
||||
_publicLink->setText(lang(_channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link));
|
||||
_sign->setChecked(_channel->addsSignature());
|
||||
}
|
||||
|
||||
void EditChannelBox::descriptionResized() {
|
||||
updateMaxHeight();
|
||||
update();
|
||||
}
|
||||
|
||||
bool EditChannelBox::canEditSignatures() const {
|
||||
return _channel->canEditInformation() && !_channel->isMegagroup();
|
||||
}
|
||||
|
||||
bool EditChannelBox::canEditInvites() const {
|
||||
return _channel->canEditInformation() && _channel->isMegagroup();
|
||||
}
|
||||
|
||||
void EditChannelBox::updateMaxHeight() {
|
||||
auto newHeight = st::newGroupInfoPadding.top() + _title->height();
|
||||
newHeight += st::newGroupDescriptionPadding.top() + _description->height() + st::newGroupDescriptionPadding.bottom();
|
||||
if (canEditSignatures()) {
|
||||
newHeight += st::newGroupPublicLinkPadding.top() + _sign->heightNoMargins() + st::newGroupPublicLinkPadding.bottom();
|
||||
}
|
||||
if (canEditInvites()) {
|
||||
newHeight += st::boxTitleHeight + _inviteEverybody->heightNoMargins();
|
||||
newHeight += st::boxLittleSkip + _inviteOnlyAdmins->heightNoMargins();
|
||||
}
|
||||
if (_channel->canEditUsername()) {
|
||||
newHeight += st::newGroupPublicLinkPadding.top() + _publicLink->height() + st::newGroupPublicLinkPadding.bottom();
|
||||
}
|
||||
newHeight += st::boxPadding.bottom() + st::newGroupInfoPadding.bottom();
|
||||
setDimensions(st::boxWideWidth, newHeight);
|
||||
}
|
||||
|
||||
void EditChannelBox::resizeEvent(QResizeEvent *e) {
|
||||
BoxContent::resizeEvent(e);
|
||||
|
||||
_title->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _title->height());
|
||||
_title->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), st::newGroupInfoPadding.top() + st::newGroupNamePosition.y());
|
||||
|
||||
_description->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _description->height());
|
||||
_description->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _title->y() + _title->height() + st::newGroupDescriptionPadding.top());
|
||||
|
||||
_sign->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description->y() + _description->height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
||||
|
||||
_inviteEverybody->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description->y() + _description->height() + st::boxTitleHeight);
|
||||
_inviteOnlyAdmins->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _inviteEverybody->bottomNoMargins() + st::boxLittleSkip);
|
||||
|
||||
if (canEditSignatures()) {
|
||||
_publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _sign->bottomNoMargins() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
||||
} else if (canEditInvites()) {
|
||||
_publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _inviteOnlyAdmins->bottomNoMargins() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
||||
} else {
|
||||
_publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description->y() + _description->height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
|
||||
}
|
||||
}
|
||||
|
||||
void EditChannelBox::paintEvent(QPaintEvent *e) {
|
||||
BoxContent::paintEvent(e);
|
||||
|
||||
if (canEditInvites()) {
|
||||
Painter p(this);
|
||||
p.setPen(st::boxTitleFg);
|
||||
p.setFont(st::autoDownloadTitleFont);
|
||||
p.drawTextLeft(st::boxTitlePosition.x(), _description->y() + _description->height() + st::boxTitlePosition.y(), width(), lang(lng_edit_group_who_invites));
|
||||
}
|
||||
}
|
||||
|
||||
void EditChannelBox::save() {
|
||||
if (_saveTitleRequestId || _saveDescriptionRequestId || _saveSignRequestId || _saveInvitesRequestId) return;
|
||||
|
||||
auto title = TextUtilities::PrepareForSending(_title->getLastText());
|
||||
auto description = TextUtilities::PrepareForSending(_description->getLastText(), TextUtilities::PrepareTextOption::CheckLinks);
|
||||
if (title.isEmpty()) {
|
||||
_title->setFocus();
|
||||
_title->showError();
|
||||
return;
|
||||
}
|
||||
_sentTitle = title;
|
||||
_sentDescription = description;
|
||||
if (_sentTitle == _channel->name) {
|
||||
saveDescription();
|
||||
} else {
|
||||
_saveTitleRequestId = MTP::send(MTPchannels_EditTitle(_channel->inputChannel, MTP_string(_sentTitle)), rpcDone(&EditChannelBox::onSaveTitleDone), rpcFail(&EditChannelBox::onSaveFail));
|
||||
}
|
||||
}
|
||||
|
||||
void EditChannelBox::setupPublicLink() {
|
||||
Ui::show(
|
||||
Box<SetupChannelBox>(_channel, true),
|
||||
LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
void EditChannelBox::saveDescription() {
|
||||
if (_sentDescription == _channel->about()) {
|
||||
saveSign();
|
||||
} else {
|
||||
_saveDescriptionRequestId = MTP::send(MTPchannels_EditAbout(_channel->inputChannel, MTP_string(_sentDescription)), rpcDone(&EditChannelBox::onSaveDescriptionDone), rpcFail(&EditChannelBox::onSaveFail));
|
||||
}
|
||||
}
|
||||
|
||||
void EditChannelBox::saveSign() {
|
||||
if (!canEditSignatures() || _channel->addsSignature() == _sign->checked()) {
|
||||
saveInvites();
|
||||
} else {
|
||||
_saveSignRequestId = MTP::send(MTPchannels_ToggleSignatures(_channel->inputChannel, MTP_bool(_sign->checked())), rpcDone(&EditChannelBox::onSaveSignDone), rpcFail(&EditChannelBox::onSaveFail));
|
||||
}
|
||||
}
|
||||
|
||||
void EditChannelBox::saveInvites() {
|
||||
if (!canEditInvites() || _channel->anyoneCanAddMembers() == (_inviteGroup->value() == Invites::Everybody)) {
|
||||
closeBox();
|
||||
} else {
|
||||
_saveInvitesRequestId = MTP::send(MTPchannels_ToggleInvites(_channel->inputChannel, MTP_bool(_inviteGroup->value() == Invites::Everybody)), rpcDone(&EditChannelBox::onSaveInvitesDone), rpcFail(&EditChannelBox::onSaveFail));
|
||||
}
|
||||
}
|
||||
|
||||
bool EditChannelBox::onSaveFail(const RPCError &error, mtpRequestId req) {
|
||||
if (MTP::isDefaultHandledError(error)) return false;
|
||||
|
||||
QString err(error.type());
|
||||
if (req == _saveTitleRequestId) {
|
||||
_saveTitleRequestId = 0;
|
||||
if (err == qstr("CHAT_NOT_MODIFIED") || err == qstr("CHAT_TITLE_NOT_MODIFIED")) {
|
||||
_channel->setName(_sentTitle, _channel->username);
|
||||
saveDescription();
|
||||
return true;
|
||||
} else if (err == qstr("NO_CHAT_TITLE")) {
|
||||
_title->setFocus();
|
||||
_title->showError();
|
||||
return true;
|
||||
} else {
|
||||
_title->setFocus();
|
||||
}
|
||||
} else if (req == _saveDescriptionRequestId) {
|
||||
_saveDescriptionRequestId = 0;
|
||||
if (err == qstr("CHAT_ABOUT_NOT_MODIFIED")) {
|
||||
_channel->setAbout(_sentDescription);
|
||||
saveSign();
|
||||
return true;
|
||||
} else {
|
||||
_description->setFocus();
|
||||
}
|
||||
} else if (req == _saveSignRequestId) {
|
||||
_saveSignRequestId = 0;
|
||||
if (err == qstr("CHAT_NOT_MODIFIED")) {
|
||||
saveInvites();
|
||||
return true;
|
||||
}
|
||||
} else if (req == _saveInvitesRequestId) {
|
||||
_saveInvitesRequestId = 0;
|
||||
if (err == qstr("CHAT_NOT_MODIFIED")) {
|
||||
closeBox();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditChannelBox::onSaveTitleDone(const MTPUpdates &result) {
|
||||
_saveTitleRequestId = 0;
|
||||
Auth().api().applyUpdates(result);
|
||||
saveDescription();
|
||||
}
|
||||
|
||||
void EditChannelBox::onSaveDescriptionDone(const MTPBool &result) {
|
||||
_saveDescriptionRequestId = 0;
|
||||
_channel->setAbout(_sentDescription);
|
||||
saveSign();
|
||||
}
|
||||
|
||||
void EditChannelBox::onSaveSignDone(const MTPUpdates &result) {
|
||||
_saveSignRequestId = 0;
|
||||
Auth().api().applyUpdates(result);
|
||||
saveInvites();
|
||||
}
|
||||
|
||||
void EditChannelBox::onSaveInvitesDone(const MTPUpdates &result) {
|
||||
_saveSignRequestId = 0;
|
||||
Auth().api().applyUpdates(result);
|
||||
closeBox();
|
||||
}
|
||||
|
||||
RevokePublicLinkBox::Inner::Inner(QWidget *parent, Fn<void()> revokeCallback) : TWidget(parent)
|
||||
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||
, _revokeWidth(st::normalFont->width(lang(lng_channels_too_much_public_revoke)))
|
||||
@@ -1412,27 +1190,29 @@ RevokePublicLinkBox::Inner::Inner(QWidget *parent, Fn<void()> revokeCallback) :
|
||||
|
||||
resize(width(), 5 * _rowHeight);
|
||||
|
||||
request(MTPchannels_GetAdminedPublicChannels()).done([this](const MTPmessages_Chats &result) {
|
||||
if (auto chats = Api::getChatsFromMessagesChats(result)) {
|
||||
for_const (auto &chat, chats->v) {
|
||||
if (auto peer = App::feedChat(chat)) {
|
||||
if (!peer->isChannel() || peer->userName().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto row = ChatRow(peer);
|
||||
row.peer = peer;
|
||||
row.name.setText(
|
||||
st::contactsNameStyle,
|
||||
peer->name,
|
||||
Ui::NameTextOptions());
|
||||
row.status.setText(
|
||||
st::defaultTextStyle,
|
||||
Messenger::Instance().createInternalLink(
|
||||
textcmdLink(1, peer->userName())),
|
||||
Ui::DialogTextOptions());
|
||||
_rows.push_back(std::move(row));
|
||||
request(MTPchannels_GetAdminedPublicChannels(
|
||||
)).done([=](const MTPmessages_Chats &result) {
|
||||
const auto &chats = result.match([](const auto &data) {
|
||||
return data.vchats.v;
|
||||
});
|
||||
for (const auto &chat : chats) {
|
||||
if (const auto peer = Auth().data().processChat(chat)) {
|
||||
if (!peer->isChannel() || peer->userName().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto row = ChatRow(peer);
|
||||
row.peer = peer;
|
||||
row.name.setText(
|
||||
st::contactsNameStyle,
|
||||
peer->name,
|
||||
Ui::NameTextOptions());
|
||||
row.status.setText(
|
||||
st::defaultTextStyle,
|
||||
Core::App().createInternalLink(
|
||||
textcmdLink(1, peer->userName())),
|
||||
Ui::DialogTextOptions());
|
||||
_rows.push_back(std::move(row));
|
||||
}
|
||||
}
|
||||
resize(width(), _rows.size() * _rowHeight);
|
||||
@@ -1440,23 +1220,30 @@ RevokePublicLinkBox::Inner::Inner(QWidget *parent, Fn<void()> revokeCallback) :
|
||||
}).send();
|
||||
}
|
||||
|
||||
RevokePublicLinkBox::RevokePublicLinkBox(QWidget*, Fn<void()> revokeCallback)
|
||||
: _aboutRevoke(this, lang(lng_channels_too_much_public_about), Ui::FlatLabel::InitType::Simple, st::aboutRevokePublicLabel)
|
||||
RevokePublicLinkBox::RevokePublicLinkBox(
|
||||
QWidget*,
|
||||
Fn<void()> revokeCallback)
|
||||
: _aboutRevoke(
|
||||
this,
|
||||
lang(lng_channels_too_much_public_about),
|
||||
Ui::FlatLabel::InitType::Simple,
|
||||
st::aboutRevokePublicLabel)
|
||||
, _revokeCallback(std::move(revokeCallback)) {
|
||||
}
|
||||
|
||||
void RevokePublicLinkBox::prepare() {
|
||||
_innerTop = st::boxPadding.top() + _aboutRevoke->height() + st::boxPadding.top();
|
||||
_inner = setInnerWidget(object_ptr<Inner>(this, [this] {
|
||||
_inner = setInnerWidget(object_ptr<Inner>(this, [=] {
|
||||
const auto callback = _revokeCallback;
|
||||
closeBox();
|
||||
if (_revokeCallback) {
|
||||
_revokeCallback();
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}), st::boxLayerScroll, _innerTop);
|
||||
|
||||
addButton(langFactory(lng_cancel), [this] { closeBox(); });
|
||||
addButton(langFactory(lng_cancel), [=] { closeBox(); });
|
||||
|
||||
subscribe(Auth().downloaderTaskFinished(), [this] { update(); });
|
||||
subscribe(Auth().downloaderTaskFinished(), [=] { update(); });
|
||||
|
||||
_inner->resizeToWidth(st::boxWideWidth);
|
||||
setDimensions(st::boxWideWidth, _innerTop + _inner->height());
|
||||
@@ -1497,16 +1284,20 @@ void RevokePublicLinkBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
setCursor((_selected || _pressed) ? style::cur_pointer : style::cur_default);
|
||||
if (pressed && pressed == _selected) {
|
||||
auto text_method = pressed->isMegagroup() ? lng_channels_too_much_public_revoke_confirm_group : lng_channels_too_much_public_revoke_confirm_channel;
|
||||
auto text = text_method(lt_link, Messenger::Instance().createInternalLink(pressed->userName()), lt_group, pressed->name);
|
||||
auto text = text_method(lt_link, Core::App().createInternalLink(pressed->userName()), lt_group, pressed->name);
|
||||
auto confirmText = lang(lng_channels_too_much_public_revoke);
|
||||
_weakRevokeConfirmBox = Ui::show(Box<ConfirmBox>(text, confirmText, crl::guard(this, [this, pressed]() {
|
||||
if (_revokeRequestId) return;
|
||||
_revokeRequestId = request(MTPchannels_UpdateUsername(pressed->asChannel()->inputChannel, MTP_string(""))).done([this](const MTPBool &result) {
|
||||
_revokeRequestId = request(MTPchannels_UpdateUsername(
|
||||
pressed->asChannel()->inputChannel,
|
||||
MTP_string("")
|
||||
)).done([=](const MTPBool &result) {
|
||||
const auto callback = _revokeCallback;
|
||||
if (_weakRevokeConfirmBox) {
|
||||
_weakRevokeConfirmBox->closeBox();
|
||||
}
|
||||
if (_revokeCallback) {
|
||||
_revokeCallback();
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}).send();
|
||||
})), LayerOption::KeepOther);
|
||||
|
||||
@@ -38,6 +38,10 @@ enum class PeerFloodType {
|
||||
InviteChannel,
|
||||
};
|
||||
QString PeerFloodErrorText(PeerFloodType type);
|
||||
void ShowAddParticipantsError(
|
||||
const QString &error,
|
||||
not_null<PeerData*> chat,
|
||||
const std::vector<not_null<UserData*>> &users);
|
||||
|
||||
class AddContactBox : public BoxContent, public RPCSender {
|
||||
public:
|
||||
@@ -96,7 +100,6 @@ private:
|
||||
|
||||
void descriptionResized();
|
||||
void updateMaxHeight();
|
||||
void updateSelected(const QPoint &cursorGlobalPosition);
|
||||
|
||||
CreatingGroupType _creating;
|
||||
bool _fromTypeChoose = false;
|
||||
@@ -134,7 +137,6 @@ private:
|
||||
};
|
||||
void privacyChanged(Privacy value);
|
||||
void updateSelected(const QPoint &cursorGlobalPosition);
|
||||
void showAddContactsToChannelBox() const;
|
||||
void handleChange();
|
||||
void check();
|
||||
void save();
|
||||
@@ -201,88 +203,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class EditBioBox : public BoxContent, private MTP::Sender {
|
||||
public:
|
||||
EditBioBox(QWidget*, not_null<UserData*> self);
|
||||
|
||||
protected:
|
||||
void setInnerFocus() override;
|
||||
void prepare() override;
|
||||
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
||||
private:
|
||||
void updateMaxHeight();
|
||||
void handleBioUpdated();
|
||||
void save();
|
||||
|
||||
style::InputField _dynamicFieldStyle;
|
||||
not_null<UserData*> _self;
|
||||
|
||||
object_ptr<Ui::InputField> _bio;
|
||||
object_ptr<Ui::FlatLabel> _countdown;
|
||||
object_ptr<Ui::FlatLabel> _about;
|
||||
mtpRequestId _requestId = 0;
|
||||
QString _sentBio;
|
||||
|
||||
};
|
||||
|
||||
class EditChannelBox : public BoxContent, public RPCSender {
|
||||
public:
|
||||
EditChannelBox(QWidget*, not_null<ChannelData*> channel);
|
||||
|
||||
protected:
|
||||
void prepare() override;
|
||||
void setInnerFocus() override;
|
||||
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
private:
|
||||
void updateMaxHeight();
|
||||
bool canEditSignatures() const;
|
||||
bool canEditInvites() const;
|
||||
void handleChannelNameChange();
|
||||
void descriptionResized();
|
||||
void setupPublicLink();
|
||||
void save();
|
||||
|
||||
void onSaveTitleDone(const MTPUpdates &result);
|
||||
void onSaveDescriptionDone(const MTPBool &result);
|
||||
void onSaveSignDone(const MTPUpdates &result);
|
||||
void onSaveInvitesDone(const MTPUpdates &result);
|
||||
bool onSaveFail(const RPCError &error, mtpRequestId req);
|
||||
|
||||
void saveDescription();
|
||||
void saveSign();
|
||||
void saveInvites();
|
||||
|
||||
not_null<ChannelData*> _channel;
|
||||
|
||||
object_ptr<Ui::InputField> _title;
|
||||
object_ptr<Ui::InputField> _description;
|
||||
object_ptr<Ui::Checkbox> _sign;
|
||||
|
||||
enum class Invites {
|
||||
Everybody,
|
||||
OnlyAdmins,
|
||||
};
|
||||
std::shared_ptr<Ui::RadioenumGroup<Invites>> _inviteGroup;
|
||||
object_ptr<Ui::Radioenum<Invites>> _inviteEverybody;
|
||||
object_ptr<Ui::Radioenum<Invites>> _inviteOnlyAdmins;
|
||||
|
||||
object_ptr<Ui::LinkButton> _publicLink;
|
||||
|
||||
mtpRequestId _saveTitleRequestId = 0;
|
||||
mtpRequestId _saveDescriptionRequestId = 0;
|
||||
mtpRequestId _saveSignRequestId = 0;
|
||||
mtpRequestId _saveInvitesRequestId = 0;
|
||||
|
||||
QString _sentTitle, _sentDescription;
|
||||
|
||||
};
|
||||
|
||||
class RevokePublicLinkBox : public BoxContent, public RPCSender {
|
||||
public:
|
||||
RevokePublicLinkBox(QWidget*, Fn<void()> revokeCallback);
|
||||
|
||||