Compare commits
839 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0981ea8e3 | ||
|
|
a141d01a23 | ||
|
|
6a000207ee | ||
|
|
ee6edf9caa | ||
|
|
37907636e6 | ||
|
|
3f0f3a3c11 | ||
|
|
db0856f71c | ||
|
|
86cdda2277 | ||
|
|
3888e8084a | ||
|
|
517b456670 | ||
|
|
77d6e19214 | ||
|
|
fb64452495 | ||
|
|
24fabf2590 | ||
|
|
9b2847a11d | ||
|
|
c18e8fd777 | ||
|
|
f4afa762d8 | ||
|
|
5e1fb6ebbf | ||
|
|
2c7922ce7b | ||
|
|
ac78ae823c | ||
|
|
1ef6f462f6 | ||
|
|
c81f406759 | ||
|
|
889ec0c731 | ||
|
|
677fbdd84e | ||
|
|
1ebe3255e0 | ||
|
|
c70866a995 | ||
|
|
fd982b90db | ||
|
|
9461095c88 | ||
|
|
a2fa1a52e2 | ||
|
|
a847969e9c | ||
|
|
4d647e64b7 | ||
|
|
f8b756d447 | ||
|
|
484c647b5b | ||
|
|
730c968b1e | ||
|
|
8a6a749296 | ||
|
|
2f22a8f46b | ||
|
|
f123a9e16c | ||
|
|
11c45b0342 | ||
|
|
2cd6bfef06 | ||
|
|
61ca619db4 | ||
|
|
675ee9088f | ||
|
|
28a6aa45b9 | ||
|
|
08ec9e6bfd | ||
|
|
ee9f99a754 | ||
|
|
2412183b83 | ||
|
|
e83704982f | ||
|
|
6f86acf712 | ||
|
|
c22698084f | ||
|
|
8c55364afa | ||
|
|
2c3ef13b01 | ||
|
|
03454ca3b4 | ||
|
|
8a92c89f39 | ||
|
|
b83b403b75 | ||
|
|
8aac07b3c0 | ||
|
|
b4dfc25df5 | ||
|
|
917d1841c1 | ||
|
|
8ce10d5503 | ||
|
|
a130bb1be6 | ||
|
|
de52ac6b28 | ||
|
|
310837c9e1 | ||
|
|
8e6d7bb190 | ||
|
|
025ab40687 | ||
|
|
2a5071b66c | ||
|
|
2a63496054 | ||
|
|
a52d4eb4e8 | ||
|
|
4f7a124f3e | ||
|
|
4b9eb37bd5 | ||
|
|
1d5e4040f4 | ||
|
|
6818b8d8dc | ||
|
|
3f0b962ae5 | ||
|
|
8ac1ad3484 | ||
|
|
c6e1cf639e | ||
|
|
5b9278eced | ||
|
|
03d4dd00d4 | ||
|
|
f7d698b9ff | ||
|
|
46b69a938b | ||
|
|
ebba58217c | ||
|
|
94ad8f9bc3 | ||
|
|
6effac7915 | ||
|
|
78093173a9 | ||
|
|
a01d48f063 | ||
|
|
149c69c9f5 | ||
|
|
df277b366b | ||
|
|
f20475f07e | ||
|
|
b6664625ea | ||
|
|
1028219276 | ||
|
|
219671a3bc | ||
|
|
8c97e915ec | ||
|
|
b648548001 | ||
|
|
b377c02ad3 | ||
|
|
66d6b461f3 | ||
|
|
054a6db3ae | ||
|
|
bf7042df44 | ||
|
|
aa140b2919 | ||
|
|
8d0d9bb0bd | ||
|
|
9ca9904732 | ||
|
|
e6e1b9446d | ||
|
|
a507d28b49 | ||
|
|
ec2faca145 | ||
|
|
17bb430006 | ||
|
|
8cbeadc68a | ||
|
|
3947056654 | ||
|
|
ad7d1fddf0 | ||
|
|
ab20f8eb31 | ||
|
|
f75429cbaa | ||
|
|
dc8c4a8332 | ||
|
|
096530c96a | ||
|
|
ed0850d823 | ||
|
|
4a2173deaf | ||
|
|
f40a584905 | ||
|
|
e54204b136 | ||
|
|
715dff0a3e | ||
|
|
558daa3382 | ||
|
|
7265297b19 | ||
|
|
1fac6db8bd | ||
|
|
c9bd776d1e | ||
|
|
179e81478e | ||
|
|
9ef74c510c | ||
|
|
36f6917bd3 | ||
|
|
707951accb | ||
|
|
7eb98b50ec | ||
|
|
65f7bdb914 | ||
|
|
876c47c436 | ||
|
|
e8f16840de | ||
|
|
dd57ad567f | ||
|
|
54934fb835 | ||
|
|
bd49887607 | ||
|
|
aaa72b7c30 | ||
|
|
4cafacc8db | ||
|
|
374b3c68ac | ||
|
|
69d21f73ef | ||
|
|
6dc3bd65e8 | ||
|
|
deb9aa435b | ||
|
|
68cb568898 | ||
|
|
1ed81b1c9c | ||
|
|
a95fb5b28d | ||
|
|
4f7b5ca7da | ||
|
|
29b7673b88 | ||
|
|
66f375d2c6 | ||
|
|
77d214d2a5 | ||
|
|
09e6077e97 | ||
|
|
631d6abb06 | ||
|
|
c833b8a1b0 | ||
|
|
b58c03f0de | ||
|
|
1988435cdf | ||
|
|
7e704d9529 | ||
|
|
a39a8dbd2c | ||
|
|
90dfae52f5 | ||
|
|
dfc422b505 | ||
|
|
54cc12cf22 | ||
|
|
d81e832ae6 | ||
|
|
1399d2501d | ||
|
|
57254ca259 | ||
|
|
043e3ae97e | ||
|
|
68b9a8bc6a | ||
|
|
157d5c743b | ||
|
|
54d0290ba2 | ||
|
|
0fc2df8eec | ||
|
|
d9caf15d1d | ||
|
|
b674826392 | ||
|
|
37181f9d0a | ||
|
|
93aebc747d | ||
|
|
a84ac933dd | ||
|
|
b79c306bfe | ||
|
|
57d62423b3 | ||
|
|
f4674389d5 | ||
|
|
63c4c5064f | ||
|
|
ae1f364730 | ||
|
|
c6e322de86 | ||
|
|
68bf6f991c | ||
|
|
b15f5f8596 | ||
|
|
27a71a8dcd | ||
|
|
2044f8f9ad | ||
|
|
ffa4b1db87 | ||
|
|
cad25ae644 | ||
|
|
21094fe11b | ||
|
|
101dbdf243 | ||
|
|
0dc92762bc | ||
|
|
5fdaa6b91f | ||
|
|
968d036834 | ||
|
|
d47c5df73d | ||
|
|
6c1e7357c6 | ||
|
|
479b63c33a | ||
|
|
950a946a16 | ||
|
|
5f8da27c86 | ||
|
|
a9bd7803e6 | ||
|
|
3ece9b1566 | ||
|
|
e71a067f4b | ||
|
|
ebf456abe4 | ||
|
|
3552da5ce7 | ||
|
|
b5bd0f53ad | ||
|
|
7d115b3fab | ||
|
|
d0a030ab58 | ||
|
|
712c06756e | ||
|
|
301ffc15ef | ||
|
|
3c4a711b5d | ||
|
|
989145726d | ||
|
|
9eebd3b514 | ||
|
|
eb997ae9e3 | ||
|
|
db4c9b83f3 | ||
|
|
1196b6a3fb | ||
|
|
bef216bc93 | ||
|
|
811d75e383 | ||
|
|
049cde48ee | ||
|
|
cb65c50c19 | ||
|
|
f23c9a61bc | ||
|
|
b5d5ff3cbb | ||
|
|
c5ba0fa705 | ||
|
|
71893f4ef7 | ||
|
|
4a60c57661 | ||
|
|
fbbcc21198 | ||
|
|
d993386756 | ||
|
|
30819509d3 | ||
|
|
10c3fe0f63 | ||
|
|
3498a7f0ee | ||
|
|
648b23b548 | ||
|
|
ba89912834 | ||
|
|
c1bc7e6ab1 | ||
|
|
eea50ed6b0 | ||
|
|
006d6fe2c0 | ||
|
|
5180e0ec57 | ||
|
|
490ec7949f | ||
|
|
671a15d763 | ||
|
|
d2d5226dc7 | ||
|
|
b58ece3a38 | ||
|
|
2b4a2b5b97 | ||
|
|
382b175db2 | ||
|
|
2db81211c8 | ||
|
|
46157c99c4 | ||
|
|
c3ed5224c2 | ||
|
|
acee7c7cfc | ||
|
|
002fe9a72a | ||
|
|
93b7c47cda | ||
|
|
053f8ad1c0 | ||
|
|
60ca6895db | ||
|
|
fc5e9414b7 | ||
|
|
f768e405fa | ||
|
|
a22cf8e303 | ||
|
|
8a5797e1bd | ||
|
|
750ad600be | ||
|
|
eaf4575eb8 | ||
|
|
b9677fe1db | ||
|
|
4047f1733d | ||
|
|
3d114131e0 | ||
|
|
5810149a77 | ||
|
|
032fe3e0fc | ||
|
|
81d7fcba7e | ||
|
|
4e9b5b0d33 | ||
|
|
90068f6261 | ||
|
|
f37d056c14 | ||
|
|
f748988ae3 | ||
|
|
9a25d2c413 | ||
|
|
ec40292cbf | ||
|
|
5e8c3fb146 | ||
|
|
fa8ed186d8 | ||
|
|
c1f36d43d0 | ||
|
|
501cae2200 | ||
|
|
8ad5117495 | ||
|
|
d79da3d884 | ||
|
|
e4d88f829c | ||
|
|
2673e1df53 | ||
|
|
99e88d74bc | ||
|
|
43ffc9d67c | ||
|
|
053c462dc0 | ||
|
|
174b627a78 | ||
|
|
bb33d0b997 | ||
|
|
6f6fb3d1b6 | ||
|
|
3f216ad946 | ||
|
|
c49eb7041f | ||
|
|
a1d8202644 | ||
|
|
82428aef28 | ||
|
|
10f7b985c7 | ||
|
|
06075411a5 | ||
|
|
7e01b12825 | ||
|
|
273119fc55 | ||
|
|
e47e4ba338 | ||
|
|
cbcdeae200 | ||
|
|
c585112e37 | ||
|
|
392df8b56f | ||
|
|
0e6470a087 | ||
|
|
6c0ea0eb9f | ||
|
|
9229de2658 | ||
|
|
2935721cd0 | ||
|
|
a48cd5f15a | ||
|
|
9e77e80f92 | ||
|
|
deb50ee528 | ||
|
|
14909ae913 | ||
|
|
d5d9da7d0a | ||
|
|
86a048a021 | ||
|
|
aafa8631e0 | ||
|
|
9176bf2e47 | ||
|
|
72c667b153 | ||
|
|
fe6f65b3ab | ||
|
|
5db2821f8c | ||
|
|
9e3e7265d2 | ||
|
|
749b2e0e95 | ||
|
|
5b45397383 | ||
|
|
61c17c0a93 | ||
|
|
93e592472c | ||
|
|
379a94db42 | ||
|
|
4f4d216987 | ||
|
|
6400875d55 | ||
|
|
06d0e78b00 | ||
|
|
9043c18725 | ||
|
|
88e742927f | ||
|
|
a6fcc6d51d | ||
|
|
23a13ab54e | ||
|
|
e8a929bdbd | ||
|
|
eafc01e02b | ||
|
|
f817504d67 | ||
|
|
f91eb65239 | ||
|
|
e978770fbd | ||
|
|
9c83b8bac5 | ||
|
|
47ce34e987 | ||
|
|
1656a9c3e2 | ||
|
|
47e06cf385 | ||
|
|
f61f649a7e | ||
|
|
a7bffe7abd | ||
|
|
51b866293f | ||
|
|
bd20a3cfe4 | ||
|
|
86778aa4d9 | ||
|
|
12eecec501 | ||
|
|
26345208a9 | ||
|
|
ee680ac1f1 | ||
|
|
bb79a07262 | ||
|
|
70fe649743 | ||
|
|
400f0f8785 | ||
|
|
eac7bf1c48 | ||
|
|
f4abe37dff | ||
|
|
b7f165a259 | ||
|
|
c1b95afd88 | ||
|
|
36766e7546 | ||
|
|
59c016e4ce | ||
|
|
e9e347fa6c | ||
|
|
7aef0b0a83 | ||
|
|
d9572949f6 | ||
|
|
233e80d22d | ||
|
|
5c83858a50 | ||
|
|
c681569349 | ||
|
|
bb43afdd93 | ||
|
|
3ba1941808 | ||
|
|
72d1b43453 | ||
|
|
0c1b487956 | ||
|
|
ba611d0f2d | ||
|
|
50ce847b31 | ||
|
|
dd0d88ccd3 | ||
|
|
a1049ec7ce | ||
|
|
0fffeac8da | ||
|
|
1f0acae151 | ||
|
|
521c17b76c | ||
|
|
f9f51b4e41 | ||
|
|
4e8895ddd9 | ||
|
|
ad342a5324 | ||
|
|
5cfd86b829 | ||
|
|
27eb3e45be | ||
|
|
4953246c5d | ||
|
|
4df5372dab | ||
|
|
40fbd415ef | ||
|
|
974bf99921 | ||
|
|
8c0351be4e | ||
|
|
67f7816088 | ||
|
|
924d80ecba | ||
|
|
d219bccf2b | ||
|
|
02bd2bca64 | ||
|
|
57ecc2be1d | ||
|
|
d3a01b6235 | ||
|
|
58c060c59d | ||
|
|
cd7507fb23 | ||
|
|
9a5923676a | ||
|
|
c0f3d263a3 | ||
|
|
056ba644ed | ||
|
|
ebaffc333e | ||
|
|
be099880d8 | ||
|
|
885dcf0b28 | ||
|
|
a0d97f03cb | ||
|
|
c942034ca4 | ||
|
|
0bd780b20f | ||
|
|
7d75c25214 | ||
|
|
5defb9fb17 | ||
|
|
0549c8f037 | ||
|
|
3c246e1e92 | ||
|
|
58da617e3f | ||
|
|
1edf0ed70b | ||
|
|
c27c567225 | ||
|
|
93eff78cd6 | ||
|
|
a2a27e115c | ||
|
|
e9fb580ba4 | ||
|
|
d73313479b | ||
|
|
e4e343b871 | ||
|
|
dda6b92bec | ||
|
|
3dd894ad30 | ||
|
|
f08ff92470 | ||
|
|
923aaec085 | ||
|
|
1d3110228d | ||
|
|
7194781bb8 | ||
|
|
97a5e0c6ea | ||
|
|
a3ef36f9f7 | ||
|
|
d13bf19b79 | ||
|
|
493f0450b4 | ||
|
|
74861a334d | ||
|
|
a87a221f26 | ||
|
|
923a9ec6a8 | ||
|
|
b299881bf8 | ||
|
|
5ee2bca616 | ||
|
|
d1e914fb30 | ||
|
|
43cb315f47 | ||
|
|
dcc52a7333 | ||
|
|
84cde1354d | ||
|
|
3d81414c71 | ||
|
|
69c48e2b5b | ||
|
|
5ca9b74142 | ||
|
|
e11755af46 | ||
|
|
174fb62c32 | ||
|
|
0e30e306ff | ||
|
|
5e29f382cd | ||
|
|
8eb24f620d | ||
|
|
5adde6c93a | ||
|
|
42d6d0d58a | ||
|
|
6336df2bd6 | ||
|
|
030d35ea7e | ||
|
|
d81c3554cc | ||
|
|
ca37ffa086 | ||
|
|
154fe63b43 | ||
|
|
65384d54f1 | ||
|
|
2bf8cb84d0 | ||
|
|
f0a82de784 | ||
|
|
1a393ddebb | ||
|
|
9b11b95c5b | ||
|
|
d0bfee6963 | ||
|
|
f1636de572 | ||
|
|
b5eb195f43 | ||
|
|
4a0bffe618 | ||
|
|
53d97b4146 | ||
|
|
2a224c839e | ||
|
|
bc7aa91fbb | ||
|
|
ac2f35f12b | ||
|
|
39e03c3ca7 | ||
|
|
1ce49df123 | ||
|
|
1865fd382c | ||
|
|
e00c6ecfb8 | ||
|
|
279db771cf | ||
|
|
7b7438cd7b | ||
|
|
42d53e5543 | ||
|
|
fce520c9c0 | ||
|
|
b21bcb86cc | ||
|
|
7d61ab9412 | ||
|
|
701bf0d553 | ||
|
|
583bcca6a9 | ||
|
|
6a8edefc87 | ||
|
|
dd5643ac67 | ||
|
|
787cf7853e | ||
|
|
5bfbae3afc | ||
|
|
363b700f1f | ||
|
|
cde70b9807 | ||
|
|
f7ab8a2174 | ||
|
|
a011a7c316 | ||
|
|
487fa9728a | ||
|
|
8a58ded582 | ||
|
|
ec5d8b7373 | ||
|
|
732b67ca04 | ||
|
|
d102d256a9 | ||
|
|
bbb3a51b74 | ||
|
|
d0d1ef9e66 | ||
|
|
b01244fc42 | ||
|
|
b92a05011f | ||
|
|
5fb7992b04 | ||
|
|
f371cd1af2 | ||
|
|
144109db05 | ||
|
|
e120ae6ae6 | ||
|
|
d1106e5ae6 | ||
|
|
396ba9a984 | ||
|
|
92133e7f50 | ||
|
|
a19e71324b | ||
|
|
f762634036 | ||
|
|
ee4f83ffde | ||
|
|
f8188f360a | ||
|
|
2bbc7406da | ||
|
|
a9dd9aeb90 | ||
|
|
aa4156d1e7 | ||
|
|
4f5594c8cc | ||
|
|
0527e9a0f7 | ||
|
|
28cbb02b20 | ||
|
|
7d636820ac | ||
|
|
e2b78b673b | ||
|
|
a9a0fe7cf5 | ||
|
|
2b9e7a6b25 | ||
|
|
d6e827e982 | ||
|
|
d2e6003521 | ||
|
|
465fc42718 | ||
|
|
0dd6ff9d9b | ||
|
|
8a6b1677f4 | ||
|
|
470b3a2cbd | ||
|
|
a60783eae3 | ||
|
|
de73d8766c | ||
|
|
cd7cfcdf2f | ||
|
|
aee62c7591 | ||
|
|
0f524ac67d | ||
|
|
f223ae7eee | ||
|
|
68df8448a2 | ||
|
|
da31fef1ae | ||
|
|
4427ae4306 | ||
|
|
ef2aa05197 | ||
|
|
e5132e3fe8 | ||
|
|
3b6870396c | ||
|
|
f6b849e4f7 | ||
|
|
48e3802565 | ||
|
|
26ba7e57ce | ||
|
|
2605e754ff | ||
|
|
9e85b1aa23 | ||
|
|
88cd886ec8 | ||
|
|
adc536b81d | ||
|
|
275327c789 | ||
|
|
72471c74d0 | ||
|
|
b9f63f80f1 | ||
|
|
32cd2120ac | ||
|
|
7db9abf725 | ||
|
|
f09a939a7c | ||
|
|
f1c1c900bf | ||
|
|
a43143d01c | ||
|
|
7357b40ba1 | ||
|
|
ad6e34f3a4 | ||
|
|
daf30dcab8 | ||
|
|
0033ad749f | ||
|
|
62c249015d | ||
|
|
31fcca245f | ||
|
|
f4864cddc9 | ||
|
|
36db1105a2 | ||
|
|
364f62660c | ||
|
|
b67a1bca49 | ||
|
|
000911546b | ||
|
|
e26b8e7ebc | ||
|
|
f03935ad9a | ||
|
|
d91b75b8f8 | ||
|
|
4d4cf472c8 | ||
|
|
685c7a865e | ||
|
|
0551550e61 | ||
|
|
c3fab28e1c | ||
|
|
74db2167f9 | ||
|
|
cedd8fc546 | ||
|
|
db486e957c | ||
|
|
1c6f45d8d3 | ||
|
|
ba8bb2d50f | ||
|
|
ec6d6a78cf | ||
|
|
f10f3c08de | ||
|
|
39c1da6642 | ||
|
|
84ec2a5f74 | ||
|
|
5e3e9ba824 | ||
|
|
198528f79f | ||
|
|
8a5ad581b8 | ||
|
|
7dbf8ca1f4 | ||
|
|
df808df8d3 | ||
|
|
4fddaef112 | ||
|
|
2bdc204c47 | ||
|
|
6734f99ba8 | ||
|
|
af4e0178d0 | ||
|
|
65b62485be | ||
|
|
98b58c1168 | ||
|
|
ad13048cdc | ||
|
|
a753c1515b | ||
|
|
bd48e2fff2 | ||
|
|
88ad1be4c3 | ||
|
|
1f31d8032f | ||
|
|
b5f5aed119 | ||
|
|
213326a212 | ||
|
|
264e35a6a8 | ||
|
|
76137ca1cf | ||
|
|
e4323ecd26 | ||
|
|
b406e2b99b | ||
|
|
c1c49e8ddc | ||
|
|
41e414af37 | ||
|
|
2afb69e787 | ||
|
|
3e7d4af4a0 | ||
|
|
bc11c66777 | ||
|
|
7a95b38d3c | ||
|
|
334fd4e951 | ||
|
|
923e3ee808 | ||
|
|
3358673ba4 | ||
|
|
d28b9f10b4 | ||
|
|
6ebbca58e8 | ||
|
|
15697f4f2b | ||
|
|
2cb0651b04 | ||
|
|
1f3a3ec04b | ||
|
|
c1a0172822 | ||
|
|
593e76479c | ||
|
|
5d622b906e | ||
|
|
7e253314ec | ||
|
|
78a05768d8 | ||
|
|
ddf6514a90 | ||
|
|
3847b97f80 | ||
|
|
046bc03037 | ||
|
|
7ff5f81b88 | ||
|
|
fb444e7dd4 | ||
|
|
c4f0db5bc5 | ||
|
|
a866ba8cdd | ||
|
|
129d356909 | ||
|
|
7289292f02 | ||
|
|
638e88ec79 | ||
|
|
19ead551d9 | ||
|
|
fccaa587e1 | ||
|
|
1709fcd0df | ||
|
|
de1f222bac | ||
|
|
5e1f0e9f7f | ||
|
|
e3a14d432b | ||
|
|
2b013c108f | ||
|
|
0194687181 | ||
|
|
bb47f4659d | ||
|
|
2b580d29ae | ||
|
|
b7e52119bc | ||
|
|
fd633ecb49 | ||
|
|
9c77346f36 | ||
|
|
641e74763f | ||
|
|
2e71427427 | ||
|
|
95ec0633ed | ||
|
|
14e8b8fb91 | ||
|
|
d40951f068 | ||
|
|
ab85d18cc8 | ||
|
|
6becaaa953 | ||
|
|
26e8c29f40 | ||
|
|
47800ee02d | ||
|
|
12a24dd473 | ||
|
|
ad6321d3ae | ||
|
|
7e071c770f | ||
|
|
a62d1dfa63 | ||
|
|
b3eb1dbc14 | ||
|
|
3170a45158 | ||
|
|
32483fa13b | ||
|
|
9166a1c3a6 | ||
|
|
6fa0afff37 | ||
|
|
bc649af941 | ||
|
|
16ce5ef046 | ||
|
|
bb6fd4bc4d | ||
|
|
63e1731d7c | ||
|
|
b9b7d9e337 | ||
|
|
ef8c07e6eb | ||
|
|
20a13663a6 | ||
|
|
2f0aa6ef05 | ||
|
|
62bd1354dc | ||
|
|
be255f1d09 | ||
|
|
b8b02b2285 | ||
|
|
e0db0642bd | ||
|
|
e81465a54e | ||
|
|
6e67cfc7be | ||
|
|
c0db5ee98a | ||
|
|
372b3da09c | ||
|
|
79532954dc | ||
|
|
aff2be605e | ||
|
|
363c191a6e | ||
|
|
2949cdab61 | ||
|
|
7addcf2d25 | ||
|
|
a272807a99 | ||
|
|
c803603de4 | ||
|
|
e6c22ec1ca | ||
|
|
b3ae843f0e | ||
|
|
12a78c1f45 | ||
|
|
612b81ee87 | ||
|
|
e5b91d2f3d | ||
|
|
82293c98eb | ||
|
|
629da68cfc | ||
|
|
643ecd2c2c | ||
|
|
dd1cb00c62 | ||
|
|
2c4d8418c1 | ||
|
|
9fcb5d6f31 | ||
|
|
38fc6bfbb9 | ||
|
|
804991a69c | ||
|
|
7388f46adf | ||
|
|
10c427127e | ||
|
|
c6d034174b | ||
|
|
471831bcd6 | ||
|
|
b1e64419a5 | ||
|
|
e2f17f1131 | ||
|
|
ae4a73a15b | ||
|
|
a84ca00270 | ||
|
|
c16d820b88 | ||
|
|
ef614150d5 | ||
|
|
b46ca1ec17 | ||
|
|
d5a347ede7 | ||
|
|
72d5a9b3e0 | ||
|
|
e6d72b4861 | ||
|
|
3da51b1bc9 | ||
|
|
17b7db6219 | ||
|
|
8353180161 | ||
|
|
f675a8dcf7 | ||
|
|
493f1d69e2 | ||
|
|
331e8c3ec6 | ||
|
|
56bce70558 | ||
|
|
d82e48f8e4 | ||
|
|
97ecc57be8 | ||
|
|
25bd2b145b | ||
|
|
7111c92ae7 | ||
|
|
e066cf1589 | ||
|
|
6f328b2ef8 | ||
|
|
7a6c55bd8a | ||
|
|
b35d3f57fe | ||
|
|
eef65af173 | ||
|
|
bea715b41c | ||
|
|
7be68ca82c | ||
|
|
287d5a7413 | ||
|
|
1448cea01c | ||
|
|
768e8b457b | ||
|
|
05474f4a3f | ||
|
|
8acada9b0f | ||
|
|
a86e7f035f | ||
|
|
9caff93c35 | ||
|
|
e6ba85e112 | ||
|
|
046803dbed | ||
|
|
615f4b1d1c | ||
|
|
a11535806d | ||
|
|
34a7169b4f | ||
|
|
4f365c73ad | ||
|
|
705bd9693d | ||
|
|
a88770a8ec | ||
|
|
da423b5bd2 | ||
|
|
56080bd0e4 | ||
|
|
63f66a1369 | ||
|
|
ca1a30196e | ||
|
|
b2d8e2a1e6 | ||
|
|
2ab8bb13c5 | ||
|
|
3a2c5c6d0a | ||
|
|
ed13a325e9 | ||
|
|
f43f99cff2 | ||
|
|
a3b8397361 | ||
|
|
4fb03e532c | ||
|
|
645ad5e1bd | ||
|
|
9036e9e8e3 | ||
|
|
468d8b04d6 | ||
|
|
4b98ab1246 | ||
|
|
d33e3dc13a | ||
|
|
df16e7c00b | ||
|
|
225c0e0af3 | ||
|
|
5543927042 | ||
|
|
72b274a2bf | ||
|
|
ac15990b48 | ||
|
|
7387dfdd9c | ||
|
|
74a7e7d1b4 | ||
|
|
a0a9de1d18 | ||
|
|
360366ba9e | ||
|
|
0180fe9468 | ||
|
|
19f5d95a3c | ||
|
|
051ca51d3b | ||
|
|
2a6ff9203b | ||
|
|
2e0529bd9a | ||
|
|
e24ab4f1ab | ||
|
|
3dbadeb232 | ||
|
|
4cdd939028 | ||
|
|
c11f4efc5c | ||
|
|
e1c21b908c | ||
|
|
a6c1def6fe | ||
|
|
19ae76d8de | ||
|
|
56e28feb00 | ||
|
|
b259c566b7 | ||
|
|
18598f8dca | ||
|
|
11e4c45969 | ||
|
|
39658ffe52 | ||
|
|
2f03b9aa29 | ||
|
|
dc438cff23 | ||
|
|
18f5521be5 | ||
|
|
bae9af1076 | ||
|
|
8d2805f226 | ||
|
|
0ad18c8182 | ||
|
|
9046b2cafb | ||
|
|
3d994b58a0 | ||
|
|
4310c4978e | ||
|
|
01bfa46729 | ||
|
|
3510ca7184 | ||
|
|
8d7845daa1 | ||
|
|
cb5fdac0da | ||
|
|
78c8d0562b | ||
|
|
bb0280f096 | ||
|
|
566b53ce9f | ||
|
|
ec95db0945 | ||
|
|
a0d7d07543 | ||
|
|
fe73bf9053 | ||
|
|
49c9e08b6c | ||
|
|
abcf55c498 | ||
|
|
849ce310c4 | ||
|
|
a3e593b747 | ||
|
|
5433f95eda | ||
|
|
0459196982 | ||
|
|
6f1457d30d | ||
|
|
ce596e29c4 | ||
|
|
86b9d16747 | ||
|
|
06911ae42a | ||
|
|
af2cb9b757 | ||
|
|
6a28cd1a35 | ||
|
|
f4a09a9ca0 | ||
|
|
a35f020f56 | ||
|
|
3d48111368 | ||
|
|
39ed7d7f4c | ||
|
|
abe83ccb8f | ||
|
|
d1be7c1ff7 | ||
|
|
1c223e570a | ||
|
|
a37cbd7d05 | ||
|
|
7ffa9844e2 | ||
|
|
bdf5872f04 | ||
|
|
da1909cc1d | ||
|
|
a503197352 | ||
|
|
d9d9a8f49d | ||
|
|
f57e2edf2a | ||
|
|
a1e2e3d011 | ||
|
|
5e546d1198 | ||
|
|
90405f3ebc | ||
|
|
11b57ff7d3 | ||
|
|
fe06cd63ac | ||
|
|
6c9d5e1499 | ||
|
|
6ed910de9f | ||
|
|
a506b8b25c | ||
|
|
170ebb57c6 | ||
|
|
29dd574e22 | ||
|
|
72770aa76d | ||
|
|
7f1c319aee | ||
|
|
60805bd916 | ||
|
|
10272ee0cf | ||
|
|
7c44cda76e | ||
|
|
0152d2c48e | ||
|
|
c5febce548 | ||
|
|
129b07c2c0 | ||
|
|
47bf099b88 | ||
|
|
94f1d23788 | ||
|
|
84ce72ec7a | ||
|
|
3da8351522 | ||
|
|
542153d950 | ||
|
|
090fdfb458 | ||
|
|
77835a43a5 | ||
|
|
1a2a1f1c17 | ||
|
|
eaaa704fa4 | ||
|
|
7803f8e670 | ||
|
|
f36e3c213e | ||
|
|
6fb1e23ed5 | ||
|
|
86d0c49e44 | ||
|
|
9251e6faba | ||
|
|
8f8725e1af | ||
|
|
0ce6a4cbdb | ||
|
|
ad3f705f50 | ||
|
|
c5847caa91 | ||
|
|
8df6d9db7e | ||
|
|
a9c1970f41 | ||
|
|
c3f0d2ef31 | ||
|
|
0dcc439dda | ||
|
|
5b0cac47ad | ||
|
|
b39e78a4a9 |
6
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
@@ -1,32 +1,11 @@
|
||||
name: No Response
|
||||
name: Can't reproduce.
|
||||
|
||||
# Both `issue_comment` and `scheduled` event types are required for this Action
|
||||
# to work properly.
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
- cron: '0 3 * * *'
|
||||
|
||||
jobs:
|
||||
waiting-for-answer:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: lee-dohm/no-response@v0.5.0
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
responseRequiredLabel: waiting for answer
|
||||
|
||||
needs-user-action:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: lee-dohm/no-response@v0.5.0
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
responseRequiredLabel: needs user action
|
||||
|
||||
cant-reproduce:
|
||||
if: github.event_name != 'issue_comment'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: lee-dohm/no-response@v0.5.0
|
||||
4
.github/workflows/docker.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone.
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin
|
||||
|
||||
- name: Free up some disk space.
|
||||
uses: jlumbroso/free-disk-space@f68fdb76e2ea636224182cfb7377ff9a1708f9b8
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
|
||||
|
||||
- name: Docker image build.
|
||||
run: |
|
||||
|
||||
5
.github/workflows/linux.yml
vendored
@@ -49,7 +49,6 @@ jobs:
|
||||
defines:
|
||||
- ""
|
||||
- "DESKTOP_APP_DISABLE_X11_INTEGRATION"
|
||||
- "DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION"
|
||||
|
||||
env:
|
||||
UPLOAD_ARTIFACT: "true"
|
||||
@@ -59,7 +58,7 @@ jobs:
|
||||
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Clone.
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
path: ${{ env.REPO_NAME }}
|
||||
@@ -117,7 +116,7 @@ jobs:
|
||||
cd $REPO_NAME/out/Debug
|
||||
sudo mkdir artifact
|
||||
sudo mv {Telegram,Updater} artifact/
|
||||
- uses: actions/upload-artifact@master
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: env.UPLOAD_ARTIFACT == 'true'
|
||||
name: Upload artifact.
|
||||
with:
|
||||
|
||||
2
.github/workflows/lock.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v3
|
||||
- uses: dessant/lock-threads@v5
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-inactive-days: 45
|
||||
|
||||
8
.github/workflows/mac.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
||||
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Clone.
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
path: ${{ env.REPO_NAME }}
|
||||
@@ -76,7 +76,7 @@ jobs:
|
||||
|
||||
- name: ThirdParty cache.
|
||||
id: cache-third-party
|
||||
uses: actions/cache@v3.0.11
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ThirdParty
|
||||
key: ${{ runner.OS }}-third-party-${{ hashFiles(format('{0}/{1}', env.REPO_NAME, env.PREPARE_PATH)) }}
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
|
||||
- name: Libraries cache.
|
||||
id: cache-libs
|
||||
uses: actions/cache@v3.0.11
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: Libraries
|
||||
key: ${{ runner.OS }}-libs-${{ hashFiles(format('{0}/{1}', env.REPO_NAME, env.PREPARE_PATH)) }}
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
mkdir artifact
|
||||
mv Telegram.app artifact/
|
||||
mv Updater artifact/
|
||||
- uses: actions/upload-artifact@master
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: env.UPLOAD_ARTIFACT == 'true'
|
||||
name: Upload artifact.
|
||||
with:
|
||||
|
||||
12
.github/workflows/mac_packaged.yml
vendored
@@ -49,7 +49,7 @@ jobs:
|
||||
|
||||
env:
|
||||
GIT: "https://github.com"
|
||||
OPENALDIR: "/usr/local/opt/openal-soft"
|
||||
CMAKE_PREFIX_PATH: "/usr/local/opt/ffmpeg@6:/usr/local/opt/openal-soft"
|
||||
UPLOAD_ARTIFACT: "true"
|
||||
ONLY_CACHE: "false"
|
||||
MANUAL_CACHING: "1"
|
||||
@@ -60,7 +60,7 @@ jobs:
|
||||
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Clone.
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
path: ${{ env.REPO_NAME }}
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
run: |
|
||||
brew update
|
||||
brew upgrade || true
|
||||
brew install autoconf automake boost cmake ffmpeg openal-soft openssl opus ninja pkg-config python qt yasm xz
|
||||
brew install autoconf automake boost cmake ffmpeg@6 openal-soft openh264 openssl opus ninja pkg-config python qt yasm xz
|
||||
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
|
||||
|
||||
xcodebuild -version > CACHE_KEY.txt
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
|
||||
- name: WebRTC cache.
|
||||
id: cache-webrtc
|
||||
uses: actions/cache@v3.0.11
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.LibrariesPath }}/tg_owt
|
||||
key: ${{ runner.OS }}-webrtc-${{ env.CACHE_KEY }}-${{ hashFiles('**/tg_owt-version.json') }}
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
run: |
|
||||
cd $LibrariesPath
|
||||
|
||||
git clone --recursive --depth=1 $GIT/desktop-app/tg_owt.git
|
||||
git clone --depth=1 --recursive --shallow-submodules $GIT/desktop-app/tg_owt.git
|
||||
cd tg_owt
|
||||
|
||||
cmake -B build . -GNinja -DCMAKE_BUILD_TYPE=Debug
|
||||
@@ -153,7 +153,7 @@ jobs:
|
||||
cd $REPO_NAME/build
|
||||
mkdir artifact
|
||||
mv Telegram.dmg artifact/
|
||||
- uses: actions/upload-artifact@master
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: env.UPLOAD_ARTIFACT == 'true'
|
||||
name: Upload artifact.
|
||||
with:
|
||||
|
||||
2
.github/workflows/master_updater.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
SKIP: "0"
|
||||
to_branch: "master"
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.0
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
if: env.SKIP == '0'
|
||||
|
||||
16
.github/workflows/needs-user-action.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Needs user action.
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
schedule:
|
||||
- cron: '0 2 * * *'
|
||||
|
||||
jobs:
|
||||
needs-user-action:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: lee-dohm/no-response@v0.5.0
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
responseRequiredLabel: needs user action
|
||||
8
.github/workflows/snap.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Clone.
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
@@ -61,10 +61,10 @@ jobs:
|
||||
sudo snap run lxd waitready
|
||||
|
||||
- name: Free up some disk space.
|
||||
uses: jlumbroso/free-disk-space@f68fdb76e2ea636224182cfb7377ff9a1708f9b8
|
||||
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
|
||||
|
||||
- name: Telegram Desktop snap build.
|
||||
run: sg lxd -c 'snap run snapcraft -v'
|
||||
run: sg lxd -c 'snap run snapcraft --verbosity=debug'
|
||||
|
||||
- name: Move artifact.
|
||||
if: env.UPLOAD_ARTIFACT == 'true'
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
mkdir artifact
|
||||
mv $artifact_name artifact
|
||||
|
||||
- uses: actions/upload-artifact@master
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: env.UPLOAD_ARTIFACT == 'true'
|
||||
name: Upload artifact.
|
||||
with:
|
||||
|
||||
2
.github/workflows/stale.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
stale-issue-message: |
|
||||
Hey there!
|
||||
|
||||
16
.github/workflows/waiting-for-answer.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Waiting for answer.
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
schedule:
|
||||
- cron: '30 0 * * *'
|
||||
|
||||
jobs:
|
||||
waiting-for-answer:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: lee-dohm/no-response@v0.5.0
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
responseRequiredLabel: waiting for answer
|
||||
10
.github/workflows/win.yml
vendored
@@ -69,13 +69,13 @@ jobs:
|
||||
shell: bash
|
||||
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
|
||||
|
||||
- uses: ilammy/msvc-dev-cmd@v1.12.0
|
||||
- uses: ilammy/msvc-dev-cmd@v1.13.0
|
||||
name: Native Tools Command Prompt.
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
|
||||
- name: Clone.
|
||||
uses: actions/checkout@v3.1.0
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
path: ${{ env.TBUILD }}\${{ env.REPO_NAME }}
|
||||
@@ -96,7 +96,7 @@ jobs:
|
||||
|
||||
- name: Libraries cache.
|
||||
id: cache-libs
|
||||
uses: actions/cache@v3.0.11
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.TBUILD }}\Libraries
|
||||
key: ${{ runner.OS }}-${{ matrix.arch }}-libs-${{ env.CACHE_KEY }}
|
||||
@@ -169,6 +169,8 @@ jobs:
|
||||
%TDESKTOP_BUILD_GENERATOR% ^
|
||||
%TDESKTOP_BUILD_ARCH% ^
|
||||
%TDESKTOP_BUILD_API% ^
|
||||
-D CMAKE_C_FLAGS="/WX" ^
|
||||
-D CMAKE_CXX_FLAGS="/WX" ^
|
||||
-D DESKTOP_APP_DISABLE_AUTOUPDATE=OFF ^
|
||||
-D DESKTOP_APP_DISABLE_CRASH_REPORTS=OFF ^
|
||||
-D DESKTOP_APP_NO_PDB=ON ^
|
||||
@@ -183,7 +185,7 @@ jobs:
|
||||
mkdir artifact
|
||||
move %OUT%\Telegram.exe artifact/
|
||||
move %OUT%\Updater.exe artifact/
|
||||
- uses: actions/upload-artifact@master
|
||||
- uses: actions/upload-artifact@v4
|
||||
name: Upload artifact.
|
||||
if: (env.UPLOAD_ARTIFACT == 'true') || (github.ref == 'refs/heads/nightly')
|
||||
with:
|
||||
|
||||
1
.gitignore
vendored
@@ -18,6 +18,7 @@ Release/
|
||||
*.xcodeproj
|
||||
ipch/
|
||||
.vs/
|
||||
.vscode/
|
||||
|
||||
/Telegram/log.txt
|
||||
/Telegram/data
|
||||
|
||||
12
.gitmodules
vendored
@@ -76,15 +76,12 @@
|
||||
[submodule "Telegram/lib_webview"]
|
||||
path = Telegram/lib_webview
|
||||
url = https://github.com/desktop-app/lib_webview.git
|
||||
[submodule "Telegram/ThirdParty/jemalloc"]
|
||||
path = Telegram/ThirdParty/jemalloc
|
||||
url = https://github.com/jemalloc/jemalloc
|
||||
[submodule "Telegram/ThirdParty/dispatch"]
|
||||
path = Telegram/ThirdParty/dispatch
|
||||
url = https://github.com/apple/swift-corelibs-libdispatch
|
||||
[submodule "Telegram/ThirdParty/plasma-wayland-protocols"]
|
||||
path = Telegram/ThirdParty/plasma-wayland-protocols
|
||||
url = https://github.com/KDE/plasma-wayland-protocols.git
|
||||
[submodule "Telegram/ThirdParty/wayland-protocols"]
|
||||
path = Telegram/ThirdParty/wayland-protocols
|
||||
url = https://github.com/gitlab-freedesktop-mirrors/wayland-protocols.git
|
||||
[submodule "Telegram/ThirdParty/kimageformats"]
|
||||
path = Telegram/ThirdParty/kimageformats
|
||||
url = https://github.com/KDE/kimageformats.git
|
||||
@@ -94,9 +91,6 @@
|
||||
[submodule "Telegram/ThirdParty/cld3"]
|
||||
path = Telegram/ThirdParty/cld3
|
||||
url = https://github.com/google/cld3.git
|
||||
[submodule "Telegram/ThirdParty/wayland"]
|
||||
path = Telegram/ThirdParty/wayland
|
||||
url = https://github.com/gitlab-freedesktop-mirrors/wayland.git
|
||||
[submodule "Telegram/ThirdParty/libprisma"]
|
||||
path = Telegram/ThirdParty/libprisma
|
||||
url = https://github.com/desktop-app/libprisma.git
|
||||
|
||||
@@ -57,14 +57,6 @@ include(cmake/validate_d3d_compiler.cmake)
|
||||
include(cmake/target_prepare_qrc.cmake)
|
||||
|
||||
include(cmake/options.cmake)
|
||||
|
||||
if (NOT DESKTOP_APP_USE_PACKAGED)
|
||||
if (WIN32)
|
||||
set(qt_version 5.15.13)
|
||||
elseif (APPLE)
|
||||
set(qt_version 6.2.7)
|
||||
endif()
|
||||
endif()
|
||||
include(cmake/external/qt/package.cmake)
|
||||
|
||||
set(desktop_app_skip_libs
|
||||
|
||||
@@ -120,10 +120,13 @@ PRIVATE
|
||||
api/api_common.h
|
||||
api/api_confirm_phone.cpp
|
||||
api/api_confirm_phone.h
|
||||
api/api_credits.cpp
|
||||
api/api_credits.h
|
||||
api/api_earn.cpp
|
||||
api/api_earn.h
|
||||
api/api_editing.cpp
|
||||
api/api_editing.h
|
||||
api/api_filter_updates.h
|
||||
api/api_global_privacy.cpp
|
||||
api/api_global_privacy.h
|
||||
api/api_hash.cpp
|
||||
@@ -162,6 +165,10 @@ PRIVATE
|
||||
api/api_single_message_search.h
|
||||
api/api_statistics.cpp
|
||||
api/api_statistics.h
|
||||
api/api_statistics_data_deserialize.cpp
|
||||
api/api_statistics_data_deserialize.h
|
||||
api/api_statistics_sender.cpp
|
||||
api/api_statistics_sender.h
|
||||
api/api_text_entities.cpp
|
||||
api/api_text_entities.h
|
||||
api/api_toggling_media.cpp
|
||||
@@ -273,6 +280,8 @@ PRIVATE
|
||||
boxes/local_storage_box.h
|
||||
boxes/max_invite_box.cpp
|
||||
boxes/max_invite_box.h
|
||||
boxes/moderate_messages_box.cpp
|
||||
boxes/moderate_messages_box.h
|
||||
boxes/peer_list_box.cpp
|
||||
boxes/peer_list_box.h
|
||||
boxes/peer_list_controllers.cpp
|
||||
@@ -297,6 +306,8 @@ PRIVATE
|
||||
boxes/ringtones_box.h
|
||||
boxes/self_destruction_box.cpp
|
||||
boxes/self_destruction_box.h
|
||||
boxes/send_credits_box.cpp
|
||||
boxes/send_credits_box.h
|
||||
boxes/send_files_box.cpp
|
||||
boxes/send_files_box.h
|
||||
boxes/sessions_box.cpp
|
||||
@@ -439,6 +450,8 @@ PRIVATE
|
||||
core/launcher.h
|
||||
core/local_url_handlers.cpp
|
||||
core/local_url_handlers.h
|
||||
core/phone_click_handler.cpp
|
||||
core/phone_click_handler.h
|
||||
core/sandbox.cpp
|
||||
core/sandbox.h
|
||||
core/shortcuts.cpp
|
||||
@@ -460,6 +473,18 @@ PRIVATE
|
||||
data/business/data_business_info.h
|
||||
data/business/data_shortcut_messages.cpp
|
||||
data/business/data_shortcut_messages.h
|
||||
data/components/factchecks.cpp
|
||||
data/components/factchecks.h
|
||||
data/components/location_pickers.cpp
|
||||
data/components/location_pickers.h
|
||||
data/components/recent_peers.cpp
|
||||
data/components/recent_peers.h
|
||||
data/components/scheduled_messages.cpp
|
||||
data/components/scheduled_messages.h
|
||||
data/components/sponsored_messages.cpp
|
||||
data/components/sponsored_messages.h
|
||||
data/components/top_peers.cpp
|
||||
data/components/top_peers.h
|
||||
data/notify/data_notify_settings.cpp
|
||||
data/notify/data_notify_settings.h
|
||||
data/notify/data_peer_notify_settings.cpp
|
||||
@@ -529,6 +554,8 @@ PRIVATE
|
||||
data/data_groups.h
|
||||
data/data_histories.cpp
|
||||
data/data_histories.h
|
||||
data/data_history_messages.cpp
|
||||
data/data_history_messages.h
|
||||
data/data_lastseen_status.h
|
||||
data/data_location.cpp
|
||||
data/data_location.h
|
||||
@@ -577,14 +604,10 @@ PRIVATE
|
||||
data/data_send_action.h
|
||||
data/data_session.cpp
|
||||
data/data_session.h
|
||||
data/data_scheduled_messages.cpp
|
||||
data/data_scheduled_messages.h
|
||||
data/data_shared_media.cpp
|
||||
data/data_shared_media.h
|
||||
data/data_sparse_ids.cpp
|
||||
data/data_sparse_ids.h
|
||||
data/data_sponsored_messages.cpp
|
||||
data/data_sponsored_messages.h
|
||||
data/data_statistics.h
|
||||
data/data_stories.cpp
|
||||
data/data_stories.h
|
||||
@@ -608,6 +631,18 @@ PRIVATE
|
||||
data/data_wall_paper.h
|
||||
data/data_web_page.cpp
|
||||
data/data_web_page.h
|
||||
dialogs/ui/dialogs_layout.cpp
|
||||
dialogs/ui/dialogs_layout.h
|
||||
dialogs/ui/dialogs_message_view.cpp
|
||||
dialogs/ui/dialogs_message_view.h
|
||||
dialogs/ui/dialogs_stories_content.cpp
|
||||
dialogs/ui/dialogs_stories_content.h
|
||||
dialogs/ui/dialogs_suggestions.cpp
|
||||
dialogs/ui/dialogs_suggestions.h
|
||||
dialogs/ui/dialogs_topics_view.cpp
|
||||
dialogs/ui/dialogs_topics_view.h
|
||||
dialogs/ui/dialogs_video_userpic.cpp
|
||||
dialogs/ui/dialogs_video_userpic.h
|
||||
dialogs/dialogs_entry.cpp
|
||||
dialogs/dialogs_entry.h
|
||||
dialogs/dialogs_indexed_list.cpp
|
||||
@@ -630,16 +665,6 @@ PRIVATE
|
||||
dialogs/dialogs_search_tags.h
|
||||
dialogs/dialogs_widget.cpp
|
||||
dialogs/dialogs_widget.h
|
||||
dialogs/ui/dialogs_layout.cpp
|
||||
dialogs/ui/dialogs_layout.h
|
||||
dialogs/ui/dialogs_message_view.cpp
|
||||
dialogs/ui/dialogs_message_view.h
|
||||
dialogs/ui/dialogs_stories_content.cpp
|
||||
dialogs/ui/dialogs_stories_content.h
|
||||
dialogs/ui/dialogs_topics_view.cpp
|
||||
dialogs/ui/dialogs_topics_view.h
|
||||
dialogs/ui/dialogs_video_userpic.cpp
|
||||
dialogs/ui/dialogs_video_userpic.h
|
||||
editor/color_picker.cpp
|
||||
editor/color_picker.h
|
||||
editor/controllers/controllers.h
|
||||
@@ -680,6 +705,8 @@ PRIVATE
|
||||
history/view/controls/compose_controls_common.h
|
||||
history/view/controls/history_view_compose_controls.cpp
|
||||
history/view/controls/history_view_compose_controls.h
|
||||
history/view/controls/history_view_compose_media_edit_manager.cpp
|
||||
history/view/controls/history_view_compose_media_edit_manager.h
|
||||
history/view/controls/history_view_compose_search.cpp
|
||||
history/view/controls/history_view_compose_search.h
|
||||
history/view/controls/history_view_draft_options.cpp
|
||||
@@ -702,8 +729,6 @@ PRIVATE
|
||||
history/view/media/history_view_dice.h
|
||||
history/view/media/history_view_document.cpp
|
||||
history/view/media/history_view_document.h
|
||||
history/view/media/history_view_extended_preview.cpp
|
||||
history/view/media/history_view_extended_preview.h
|
||||
history/view/media/history_view_file.cpp
|
||||
history/view/media/history_view_file.h
|
||||
history/view/media/history_view_game.cpp
|
||||
@@ -771,6 +796,8 @@ PRIVATE
|
||||
history/view/history_view_about_view.h
|
||||
history/view/history_view_bottom_info.cpp
|
||||
history/view/history_view_bottom_info.h
|
||||
history/view/history_view_chat_preview.cpp
|
||||
history/view/history_view_chat_preview.h
|
||||
history/view/history_view_contact_status.cpp
|
||||
history/view/history_view_contact_status.h
|
||||
history/view/history_view_context_menu.cpp
|
||||
@@ -785,6 +812,8 @@ PRIVATE
|
||||
history/view/history_view_emoji_interactions.h
|
||||
history/view/history_view_empty_list_bubble.cpp
|
||||
history/view/history_view_empty_list_bubble.h
|
||||
history/view/history_view_fake_items.cpp
|
||||
history/view/history_view_fake_items.h
|
||||
history/view/history_view_group_call_bar.cpp
|
||||
history/view/history_view_group_call_bar.h
|
||||
history/view/history_view_item_preview.h
|
||||
@@ -815,14 +844,14 @@ PRIVATE
|
||||
history/view/history_view_send_action.h
|
||||
history/view/history_view_service_message.cpp
|
||||
history/view/history_view_service_message.h
|
||||
history/view/history_view_spoiler_click_handler.cpp
|
||||
history/view/history_view_spoiler_click_handler.h
|
||||
history/view/history_view_sponsored_click_handler.cpp
|
||||
history/view/history_view_sponsored_click_handler.h
|
||||
history/view/history_view_sticker_toast.cpp
|
||||
history/view/history_view_sticker_toast.h
|
||||
history/view/history_view_sublist_section.cpp
|
||||
history/view/history_view_sublist_section.h
|
||||
history/view/history_view_text_helper.cpp
|
||||
history/view/history_view_text_helper.h
|
||||
history/view/history_view_transcribe_button.cpp
|
||||
history/view/history_view_transcribe_button.h
|
||||
history/view/history_view_translate_bar.cpp
|
||||
@@ -863,6 +892,10 @@ PRIVATE
|
||||
history/history_view_highlight_manager.h
|
||||
history/history_widget.cpp
|
||||
history/history_widget.h
|
||||
info/bot/earn/info_bot_earn_list.cpp
|
||||
info/bot/earn/info_bot_earn_list.h
|
||||
info/bot/earn/info_bot_earn_widget.cpp
|
||||
info/bot/earn/info_bot_earn_widget.h
|
||||
info/channel_statistics/boosts/create_giveaway_box.cpp
|
||||
info/channel_statistics/boosts/create_giveaway_box.h
|
||||
info/channel_statistics/boosts/giveaway/giveaway_list_controllers.cpp
|
||||
@@ -871,10 +904,10 @@ PRIVATE
|
||||
info/channel_statistics/boosts/info_boosts_inner_widget.h
|
||||
info/channel_statistics/boosts/info_boosts_widget.cpp
|
||||
info/channel_statistics/boosts/info_boosts_widget.h
|
||||
info/channel_statistics/earn/info_earn_inner_widget.cpp
|
||||
info/channel_statistics/earn/info_earn_inner_widget.h
|
||||
info/channel_statistics/earn/info_earn_widget.cpp
|
||||
info/channel_statistics/earn/info_earn_widget.h
|
||||
info/channel_statistics/earn/info_channel_earn_list.cpp
|
||||
info/channel_statistics/earn/info_channel_earn_list.h
|
||||
info/channel_statistics/earn/info_channel_earn_widget.cpp
|
||||
info/channel_statistics/earn/info_channel_earn_widget.h
|
||||
info/common_groups/info_common_groups_inner_widget.cpp
|
||||
info/common_groups/info_common_groups_inner_widget.h
|
||||
info/common_groups/info_common_groups_widget.cpp
|
||||
@@ -1199,11 +1232,8 @@ PRIVATE
|
||||
payments/payments_checkout_process.h
|
||||
payments/payments_form.cpp
|
||||
payments/payments_form.h
|
||||
platform/linux/linux_wayland_integration_dummy.cpp
|
||||
platform/linux/linux_wayland_integration.cpp
|
||||
platform/linux/linux_wayland_integration.h
|
||||
platform/linux/linux_xdp_open_with_dialog.cpp
|
||||
platform/linux/linux_xdp_open_with_dialog.h
|
||||
payments/payments_non_panel_process.cpp
|
||||
payments/payments_non_panel_process.h
|
||||
platform/linux/file_utilities_linux.cpp
|
||||
platform/linux/file_utilities_linux.h
|
||||
platform/linux/launcher_linux.cpp
|
||||
@@ -1349,6 +1379,10 @@ PRIVATE
|
||||
settings/settings_codes.h
|
||||
settings/settings_common_session.cpp
|
||||
settings/settings_common_session.h
|
||||
settings/settings_credits.cpp
|
||||
settings/settings_credits.h
|
||||
settings/settings_credits_graphics.cpp
|
||||
settings/settings_credits_graphics.h
|
||||
settings/settings_experimental.cpp
|
||||
settings/settings_experimental.h
|
||||
settings/settings_folders.cpp
|
||||
@@ -1440,10 +1474,14 @@ PRIVATE
|
||||
ui/chat/choose_send_as.h
|
||||
ui/chat/choose_theme_controller.cpp
|
||||
ui/chat/choose_theme_controller.h
|
||||
ui/controls/location_picker.cpp
|
||||
ui/controls/location_picker.h
|
||||
ui/controls/silent_toggle.cpp
|
||||
ui/controls/silent_toggle.h
|
||||
ui/controls/userpic_button.cpp
|
||||
ui/controls/userpic_button.h
|
||||
ui/effects/credits_graphics.cpp
|
||||
ui/effects/credits_graphics.h
|
||||
ui/effects/emoji_fly_animation.cpp
|
||||
ui/effects/emoji_fly_animation.h
|
||||
ui/effects/message_sending_animation_common.h
|
||||
@@ -1459,8 +1497,10 @@ PRIVATE
|
||||
ui/image/image_location.h
|
||||
ui/image/image_location_factory.cpp
|
||||
ui/image/image_location_factory.h
|
||||
ui/widgets/level_meter.cpp
|
||||
ui/widgets/level_meter.h
|
||||
ui/text/format_song_document_name.cpp
|
||||
ui/text/format_song_document_name.h
|
||||
ui/widgets/label_with_custom_emoji.cpp
|
||||
ui/widgets/label_with_custom_emoji.h
|
||||
ui/countryinput.cpp
|
||||
ui/countryinput.h
|
||||
ui/dynamic_thumbnails.cpp
|
||||
@@ -1474,8 +1514,6 @@ PRIVATE
|
||||
ui/resize_area.h
|
||||
ui/search_field_controller.cpp
|
||||
ui/search_field_controller.h
|
||||
ui/text/format_song_document_name.cpp
|
||||
ui/text/format_song_document_name.h
|
||||
ui/unread_badge.cpp
|
||||
ui/unread_badge.h
|
||||
window/main_window.cpp
|
||||
@@ -1491,6 +1529,8 @@ PRIVATE
|
||||
window/section_widget.h
|
||||
window/window_adaptive.cpp
|
||||
window/window_adaptive.h
|
||||
window/window_chat_preview.cpp
|
||||
window/window_chat_preview.h
|
||||
window/window_connecting_widget.cpp
|
||||
window/window_connecting_widget.h
|
||||
window/window_controller.cpp
|
||||
@@ -1503,11 +1543,15 @@ PRIVATE
|
||||
window/window_lock_widgets.h
|
||||
window/window_main_menu.cpp
|
||||
window/window_main_menu.h
|
||||
window/window_main_menu_helpers.cpp
|
||||
window/window_main_menu_helpers.h
|
||||
window/window_media_preview.cpp
|
||||
window/window_media_preview.h
|
||||
window/window_peer_menu.cpp
|
||||
window/window_peer_menu.h
|
||||
window/window_section_common.h
|
||||
window/window_separate_id.cpp
|
||||
window/window_separate_id.h
|
||||
window/window_session_controller.cpp
|
||||
window/window_session_controller.h
|
||||
window/window_session_controller_link_info.h
|
||||
@@ -1554,16 +1598,6 @@ if (NOT build_winstore)
|
||||
)
|
||||
endif()
|
||||
|
||||
if (DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
|
||||
remove_target_sources(Telegram ${src_loc}
|
||||
platform/linux/linux_wayland_integration.cpp
|
||||
)
|
||||
else()
|
||||
remove_target_sources(Telegram ${src_loc}
|
||||
platform/linux/linux_wayland_integration_dummy.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (DESKTOP_APP_USE_PACKAGED)
|
||||
remove_target_sources(Telegram ${src_loc}
|
||||
platform/mac/mac_iconv_helper.c
|
||||
@@ -1584,6 +1618,7 @@ PRIVATE
|
||||
qrc/telegram/animations.qrc
|
||||
qrc/telegram/export.qrc
|
||||
qrc/telegram/iv.qrc
|
||||
qrc/telegram/picker.qrc
|
||||
qrc/telegram/telegram.qrc
|
||||
qrc/telegram/sounds.qrc
|
||||
winrc/Telegram.rc
|
||||
@@ -1701,19 +1736,6 @@ else()
|
||||
desktop-app::external_xcb
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
|
||||
qt_generate_wayland_protocol_client_sources(Telegram
|
||||
FILES
|
||||
${third_party_loc}/wayland/protocol/wayland.xml
|
||||
${third_party_loc}/plasma-wayland-protocols/src/protocols/plasma-shell.xml
|
||||
)
|
||||
|
||||
target_link_libraries(Telegram
|
||||
PRIVATE
|
||||
desktop-app::external_wayland_client
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (build_macstore)
|
||||
@@ -1820,12 +1842,49 @@ if (WIN32)
|
||||
/DELAYLOAD:uxtheme.dll
|
||||
/DELAYLOAD:crypt32.dll
|
||||
/DELAYLOAD:bcrypt.dll
|
||||
/DELAYLOAD:imm32.dll
|
||||
/DELAYLOAD:netapi32.dll
|
||||
/DELAYLOAD:imm32.dll
|
||||
/DELAYLOAD:userenv.dll
|
||||
/DELAYLOAD:wtsapi32.dll
|
||||
/DELAYLOAD:propsys.dll
|
||||
)
|
||||
if (QT_VERSION GREATER 6)
|
||||
if (NOT build_winarm)
|
||||
target_link_options(Telegram PRIVATE
|
||||
/DELAYLOAD:API-MS-Win-EventLog-Legacy-l1-1-0.dll
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_options(Telegram
|
||||
PRIVATE
|
||||
/DELAYLOAD:API-MS-Win-Core-Console-l1-1-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-Fibers-l2-1-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-Fibers-l2-1-1.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-File-l1-1-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-LibraryLoader-l1-2-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-Localization-l1-2-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-Memory-l1-1-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-Memory-l1-1-1.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-ProcessThreads-l1-1-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-Synch-l1-2-0.dll # Synchronization.lib
|
||||
/DELAYLOAD:API-MS-Win-Core-SysInfo-l1-1-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-Timezone-l1-1-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-WinRT-l1-1-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-WinRT-Error-l1-1-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Core-WinRT-String-l1-1-0.dll
|
||||
/DELAYLOAD:API-MS-Win-Security-CryptoAPI-l1-1-0.dll
|
||||
# /DELAYLOAD:API-MS-Win-Shcore-Scaling-l1-1-1.dll # We shadowed GetDpiForMonitor
|
||||
/DELAYLOAD:authz.dll # Authz.lib
|
||||
/DELAYLOAD:comdlg32.dll
|
||||
/DELAYLOAD:dwrite.dll # DWrite.lib
|
||||
/DELAYLOAD:dxgi.dll # DXGI.lib
|
||||
/DELAYLOAD:d3d9.dll # D3D9.lib
|
||||
/DELAYLOAD:d3d11.dll # D3D11.lib
|
||||
/DELAYLOAD:d3d12.dll # D3D12.lib
|
||||
/DELAYLOAD:setupapi.dll # SetupAPI.lib
|
||||
/DELAYLOAD:winhttp.dll
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_prepare_qrc(Telegram)
|
||||
|
||||
BIN
Telegram/Resources/animations/noresults.tgs
Normal file
BIN
Telegram/Resources/animations/search.tgs
Normal file
BIN
Telegram/Resources/icons/chat/filled_location.png
Normal file
|
After Width: | Height: | Size: 536 B |
BIN
Telegram/Resources/icons/chat/filled_location@2x.png
Normal file
|
After Width: | Height: | Size: 987 B |
BIN
Telegram/Resources/icons/chat/filled_location@3x.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
Telegram/Resources/icons/chat/live_location_long.png
Normal file
|
After Width: | Height: | Size: 416 B |
BIN
Telegram/Resources/icons/chat/live_location_long@2x.png
Normal file
|
After Width: | Height: | Size: 913 B |
BIN
Telegram/Resources/icons/chat/live_location_long@3x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Telegram/Resources/icons/dialogs/dialogs_pinned_shadow.png
Normal file
|
After Width: | Height: | Size: 754 B |
BIN
Telegram/Resources/icons/dialogs/dialogs_pinned_shadow@2x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Telegram/Resources/icons/dialogs/dialogs_pinned_shadow@3x.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
Telegram/Resources/icons/menu/chats.png
Normal file
|
After Width: | Height: | Size: 766 B |
BIN
Telegram/Resources/icons/menu/chats@2x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Telegram/Resources/icons/menu/chats@3x.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
Telegram/Resources/icons/menu/factcheck.png
Normal file
|
After Width: | Height: | Size: 588 B |
BIN
Telegram/Resources/icons/menu/factcheck@2x.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/Resources/icons/menu/factcheck@3x.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
Telegram/Resources/icons/menu/fonts.png
Normal file
|
After Width: | Height: | Size: 563 B |
BIN
Telegram/Resources/icons/menu/fonts@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/menu/fonts@3x.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
Telegram/Resources/icons/menu/passcode_finger.png
Normal file
|
After Width: | Height: | Size: 911 B |
BIN
Telegram/Resources/icons/menu/passcode_finger@2x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
Telegram/Resources/icons/menu/passcode_finger@3x.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
Telegram/Resources/icons/menu/passcode_watch.png
Normal file
|
After Width: | Height: | Size: 438 B |
BIN
Telegram/Resources/icons/menu/passcode_watch@2x.png
Normal file
|
After Width: | Height: | Size: 631 B |
BIN
Telegram/Resources/icons/menu/passcode_watch@3x.png
Normal file
|
After Width: | Height: | Size: 886 B |
BIN
Telegram/Resources/icons/menu/passcode_winhello.png
Normal file
|
After Width: | Height: | Size: 454 B |
BIN
Telegram/Resources/icons/menu/passcode_winhello@2x.png
Normal file
|
After Width: | Height: | Size: 772 B |
BIN
Telegram/Resources/icons/menu/passcode_winhello@3x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/payments/small_star.png
Normal file
|
After Width: | Height: | Size: 484 B |
BIN
Telegram/Resources/icons/payments/small_star@2x.png
Normal file
|
After Width: | Height: | Size: 860 B |
BIN
Telegram/Resources/icons/payments/small_star@3x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/settings/premium/effects.png
Normal file
|
After Width: | Height: | Size: 726 B |
BIN
Telegram/Resources/icons/settings/premium/effects@2x.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/Resources/icons/settings/premium/effects@3x.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 771 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
@@ -134,9 +134,32 @@ html.custom_scroll ::-webkit-scrollbar-thumb:hover {
|
||||
.page-slide {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
margin-left: 0%;
|
||||
transition: margin 240ms ease-in-out;
|
||||
}
|
||||
.page-footer {
|
||||
height: 32px;
|
||||
margin-top: -32px;
|
||||
background: var(--td-window-bg-over);
|
||||
}
|
||||
.page-footer .content {
|
||||
padding: 3px 18px;
|
||||
font-size: 15px;
|
||||
color: var(--td-window-sub-text-fg);
|
||||
text-align: center;
|
||||
}
|
||||
.page-footer .wrong {
|
||||
position: relative;
|
||||
padding: 5px;
|
||||
margin: -5px;
|
||||
color: var(--td-window-sub-text-fg);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.page-footer .wrong:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.hidden-left,
|
||||
.hidden-right {
|
||||
pointer-events: none;
|
||||
@@ -148,7 +171,7 @@ html.custom_scroll ::-webkit-scrollbar-thumb:hover {
|
||||
margin-left: 100%;
|
||||
}
|
||||
article {
|
||||
padding-bottom: 12px;
|
||||
padding-bottom: 40px;
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
white-space: pre-wrap;
|
||||
@@ -893,6 +916,9 @@ section.related a.related-link:after {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
section.related a.related-link:last-child:after {
|
||||
border-bottom: 0px;
|
||||
}
|
||||
section.related .related-link-url {
|
||||
display: block;
|
||||
font-size: 15px;
|
||||
@@ -1027,6 +1053,9 @@ section.channel > a > h4 {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.media-outer {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.photo-wrap,
|
||||
.video-wrap {
|
||||
width: 100%;
|
||||
|
||||
@@ -26,7 +26,7 @@ var IV = {
|
||||
}
|
||||
target = target.parentNode;
|
||||
}
|
||||
if (!target || !target.hasAttribute('href')) {
|
||||
if (!target || (context === '' && !target.hasAttribute('href'))) {
|
||||
return;
|
||||
}
|
||||
var base = document.createElement('A');
|
||||
@@ -413,9 +413,12 @@ var IV = {
|
||||
var article = function (el) {
|
||||
return el.getElementsByTagName('article')[0];
|
||||
};
|
||||
var from = article(IV.findPageScroll());
|
||||
var to = article(IV.makeScrolledContent(data.html));
|
||||
morphdom(from, to, {
|
||||
var footer = function (el) {
|
||||
return el.getElementsByClassName('page-footer')[0];
|
||||
};
|
||||
var from = IV.findPageScroll();
|
||||
var to = IV.makeScrolledContent(data.html);
|
||||
morphdom(article(from), article(to), {
|
||||
onBeforeElUpdated: function (fromEl, toEl) {
|
||||
if (fromEl.classList.contains('video')
|
||||
&& toEl.classList.contains('video')
|
||||
@@ -439,6 +442,7 @@ var IV = {
|
||||
return !fromEl.isEqualNode(toEl);
|
||||
}
|
||||
});
|
||||
morphdom(footer(from), footer(to));
|
||||
IV.initMedia();
|
||||
eval(data.js);
|
||||
},
|
||||
@@ -477,9 +481,7 @@ var IV = {
|
||||
var result = document.createElement('div');
|
||||
result.className = 'page-scroll';
|
||||
result.tabIndex = '-1';
|
||||
result.innerHTML = '<div class="page-slide"><article>'
|
||||
+ html
|
||||
+ '</article></div>';
|
||||
result.innerHTML = html.trim();
|
||||
result.onscroll = IV.frameScrolled;
|
||||
return result;
|
||||
},
|
||||
|
||||
@@ -251,6 +251,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_caption_limit2#other" = "Make the caption shorter or subscribe to **Telegram Premium** to double the limit to **{count}** characters.";
|
||||
"lng_caption_limit_reached#one" = "You've reached the media caption limit. Please make the caption shorter by {count} character.";
|
||||
"lng_caption_limit_reached#other" = "You've reached the media caption limit. Please make the caption shorter by {count} characters.";
|
||||
"lng_caption_move_up" = "Move Caption Up";
|
||||
"lng_caption_move_down" = "Move Caption Down";
|
||||
|
||||
"lng_file_size_limit_title" = "File Too Large";
|
||||
"lng_file_size_limit#one" = "{count} Gb";
|
||||
@@ -302,6 +304,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_sure_ban_admin" = "This user is an admin. Are you sure you want to go ahead and restrict them?";
|
||||
"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";
|
||||
"lng_proxy_box_title" = "Enable proxy";
|
||||
"lng_proxy_box_server" = "Server";
|
||||
"lng_proxy_box_port" = "Port";
|
||||
"lng_proxy_box_secret" = "Secret";
|
||||
"lng_proxy_box_status" = "Status";
|
||||
"lng_proxy_box_username" = "Username";
|
||||
"lng_proxy_box_password" = "Password";
|
||||
"lng_proxy_invalid" = "The proxy link is invalid.";
|
||||
"lng_proxy_unsupported" = "Your Telegram Desktop version doesn't support this proxy type or the proxy link is invalid. Please update Telegram Desktop to the latest version.";
|
||||
|
||||
@@ -309,7 +318,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_edit_limit_reached#one" = "You've reached the message text limit. Please make the text shorter by {count} character.";
|
||||
"lng_edit_limit_reached#other" = "You've reached the message text limit. Please make the text shorter by {count} characters.";
|
||||
"lng_edit_message" = "Edit message";
|
||||
"lng_edit_message_text" = "New message text...";
|
||||
"lng_edit_message_text" = "Caption";
|
||||
"lng_deleted" = "Deleted Account";
|
||||
"lng_deleted_message" = "Deleted message";
|
||||
"lng_deleted_story" = "Deleted story";
|
||||
@@ -561,6 +570,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_reaction_invoice" = "{reaction} to your invoice";
|
||||
"lng_reaction_gif" = "{reaction} to your GIF";
|
||||
|
||||
"lng_effect_add_title" = "Add an animated effect";
|
||||
"lng_effect_stickers_title" = "Effects from stickers";
|
||||
"lng_effect_send" = "Send with Effect";
|
||||
"lng_effect_none" = "No effects found.";
|
||||
"lng_effect_premium" = "Subscribe to {link} to add this animated effect.";
|
||||
"lng_effect_premium_link" = "Telegram Premium";
|
||||
|
||||
"lng_languages" = "Languages";
|
||||
"lng_languages_none" = "No languages found.";
|
||||
"lng_languages_count#one" = "{count} language";
|
||||
@@ -667,6 +683,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_privacy_premium_link" = "Telegram Premium";
|
||||
"lng_settings_passcode_disable" = "Disable Passcode";
|
||||
"lng_settings_passcode_disable_sure" = "Are you sure you want to disable passcode?";
|
||||
"lng_settings_use_winhello" = "Unlock with Windows Hello";
|
||||
"lng_settings_use_winhello_about" = "You need to enter your passcode once before unlocking Telegram with Windows Hello.";
|
||||
"lng_settings_use_touchid" = "Unlock with Touch ID";
|
||||
"lng_settings_use_touchid_about" = "You need to enter your passcode once before unlocking Telegram with Touch ID.";
|
||||
"lng_settings_use_applewatch" = "Unlock with Apple Watch";
|
||||
"lng_settings_use_applewatch_about" = "You need to enter your passcode once before unlocking Telegram with Apple Watch.";
|
||||
"lng_settings_use_systempwd" = "Unlock with System Password";
|
||||
"lng_settings_use_systempwd_about" = "You need to enter your passcode once before unlocking Telegram with System Password.";
|
||||
"lng_settings_password_disable" = "Disable Cloud Password";
|
||||
"lng_settings_password_abort" = "Abort two-step verification setup";
|
||||
"lng_settings_about_bio" = "Any details such as age, occupation or city.\nExample: 23 y.o. designer from San Francisco";
|
||||
@@ -730,10 +754,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_angle_backend_d3d11on12" = "D3D11on12";
|
||||
"lng_settings_angle_backend_opengl" = "OpenGL";
|
||||
"lng_settings_angle_backend_disabled" = "Disabled";
|
||||
"lng_settings_top_peers_title" = "Frequent contacts";
|
||||
"lng_settings_top_peers_suggest" = "Suggest frequent contacts";
|
||||
"lng_settings_top_peers_about" = "Display people you message frequently at the top of the search section for quick access.";
|
||||
"lng_settings_sensitive_title" = "Sensitive content";
|
||||
"lng_settings_sensitive_disable_filtering" = "Disable filtering";
|
||||
"lng_settings_sensitive_about" = "Display sensitive media in public channels on all your Telegram devices.";
|
||||
"lng_settings_security_bots" = "Bots and websites";
|
||||
"lng_settings_file_confirmations" = "File open confirmations";
|
||||
"lng_settings_edit_extensions" = "Extensions whitelist";
|
||||
"lng_settings_edit_extensions_about" = "Open files with the following extensions without additional confirmation.";
|
||||
"lng_settings_edit_ip_confirm" = "IP reveal warning";
|
||||
"lng_settings_edit_ip_confirm_about" = "Show confirmation when opening files that may reveal your IP address.";
|
||||
"lng_settings_clear_payment_info" = "Clear Payment and Shipping Info";
|
||||
"lng_settings_logged_in" = "Connected websites";
|
||||
"lng_settings_logged_in_title" = "Logged in with Telegram";
|
||||
@@ -761,6 +793,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_power_chat" = "Animations in Chats";
|
||||
"lng_settings_power_chat_background" = "Background rotation";
|
||||
"lng_settings_power_chat_spoiler" = "Animated spoiler effect";
|
||||
"lng_settings_power_chat_effects" = "Effects in messages";
|
||||
"lng_settings_power_calls" = "Animations in Calls";
|
||||
"lng_settings_power_ui" = "Interface animations";
|
||||
"lng_settings_power_auto" = "Save Power on Low Battery";
|
||||
@@ -835,6 +868,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_auto_night_mode_on" = "System";
|
||||
"lng_settings_auto_night_warning" = "You have enabled auto-night mode. If you want to change the dark mode settings, you'll need to disable it first.";
|
||||
"lng_settings_auto_night_disable" = "Disable";
|
||||
"lng_settings_font_family" = "Font family";
|
||||
|
||||
"lng_settings_color_title" = "Color preview";
|
||||
"lng_settings_color_reply" = "Reply to your message";
|
||||
@@ -871,6 +905,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_gift_premium_users_confirm" = "Proceed";
|
||||
"lng_settings_gift_premium_users_error#one" = "You can select maximum {count} user.";
|
||||
"lng_settings_gift_premium_users_error#other" = "You can select maximum {count} users.";
|
||||
"lng_settings_gift_premium_choose" = "Please choose at least one recipient.";
|
||||
|
||||
"lng_backgrounds_header" = "Choose Wallpaper";
|
||||
"lng_theme_sure_keep" = "Keep this theme?";
|
||||
@@ -965,6 +1000,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_passcode_ph" = "Your passcode";
|
||||
"lng_passcode_submit" = "Submit";
|
||||
"lng_passcode_logout" = "Log out";
|
||||
"lng_passcode_winhello" = "You need to enter your passcode\nbefore you can use Windows Hello.";
|
||||
"lng_passcode_touchid" = "You need to enter your passcode\nbefore you can use Touch ID.";
|
||||
"lng_passcode_applewatch" = "You need to enter your passcode\nbefore you can use Watch to unlock.";
|
||||
"lng_passcode_systempwd" = "You need to enter your passcode\nbefore you can use system password.";
|
||||
"lng_passcode_winhello_unlock" = "Telegram wants to unlock with Windows Hello.";
|
||||
"lng_passcode_touchid_unlock" = "unlock";
|
||||
"lng_passcode_create_button" = "Save Passcode";
|
||||
"lng_passcode_check_button" = "Submit";
|
||||
"lng_passcode_change_button" = "Save Passcode";
|
||||
@@ -1044,6 +1085,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_proxy_sponsor" = "Proxy sponsor";
|
||||
"lng_proxy_sponsor_about" = "This channel is shown by your proxy server.\nTo remove this channel from your chats list,\ndisable the proxy in Telegram Settings.";
|
||||
"lng_proxy_sponsor_warning" = "This proxy may display a sponsored channel in your chat list. This doesn't reveal any of your Telegram traffic.";
|
||||
"lng_proxy_add_from_clipboard" = "Add proxy from clipboard";
|
||||
"lng_proxy_add_from_clipboard_good_toast" = "Proxy was added from clipboard.";
|
||||
"lng_proxy_add_from_clipboard_failed_toast" = "This is not a proxy link.";
|
||||
"lng_proxy_add_from_clipboard_existing_toast" = "This proxy is already in the list.";
|
||||
"lng_badge_psa_default" = "PSA";
|
||||
"lng_about_psa_default" = "This message provides you with a public service announcement. To remove it from your chats list, right click it and select **Hide**.";
|
||||
"lng_tooltip_psa_default" = "This message provides you with a public service announcement.";
|
||||
@@ -1070,6 +1115,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_faq" = "Telegram FAQ";
|
||||
"lng_settings_faq_link" = "https://telegram.org/faq#general-questions";
|
||||
"lng_settings_features" = "Telegram Features";
|
||||
"lng_settings_credits" = "Your Stars";
|
||||
"lng_settings_logout" = "Log Out";
|
||||
"lng_sure_logout" = "Are you sure you want to log out?";
|
||||
|
||||
@@ -1487,6 +1533,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_manage_peer_reactions_none_about" = "Members of the group can't add any reactions to messages.";
|
||||
"lng_manage_peer_reactions_some_title" = "Only allow these reactions";
|
||||
"lng_manage_peer_reactions_available" = "Available reactions";
|
||||
"lng_manage_peer_reactions_available_ph" = "Add reactions...";
|
||||
"lng_manage_peer_reactions_own" = "You can also {link} emoji packs and use them as reactions.";
|
||||
"lng_manage_peer_reactions_own_link" = "create your own";
|
||||
"lng_manage_peer_reactions_level#one" = "Your channel needs to reach level **{count}** to use **{same_count}** custom reaction.";
|
||||
@@ -1495,6 +1542,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_manage_peer_reactions_boost_link" = "here";
|
||||
"lng_manage_peer_reactions_limit" = "Channels can't have more custom reactions.";
|
||||
|
||||
"lng_manage_peer_reactions_max_title" = "Maximum number of reactions";
|
||||
"lng_manage_peer_reactions_max_slider#one" = "{count} reaction per post";
|
||||
"lng_manage_peer_reactions_max_slider#other" = "{count} reactions per post";
|
||||
"lng_manage_peer_reactions_max_about" = "Limit the number of different reactions that can be added to a post, including already published ones.";
|
||||
|
||||
"lng_manage_peer_antispam" = "Aggressive Anti-Spam";
|
||||
"lng_manage_peer_antispam_about" = "Telegram will filter more spam but may occasionally affect ordinary messages. You can report False Positives in Recent Actions.";
|
||||
"lng_manage_peer_antispam_not_enough#one" = "Aggressive filtering can be enabled only in groups with more than **{count} member**.";
|
||||
@@ -1507,8 +1559,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_manage_peer_link_invite" = "Invite link";
|
||||
"lng_manage_peer_link_expired" = "Expired link";
|
||||
"lng_manage_private_group_title" = "Private";
|
||||
"lng_manage_private_group_noforwards_title" = "Private restricted";
|
||||
"lng_manage_public_group_title" = "Public";
|
||||
"lng_manage_private_peer_title" = "Private";
|
||||
"lng_manage_private_peer_noforwards_title" = "Private restricted";
|
||||
"lng_manage_public_peer_title" = "Public";
|
||||
"lng_manage_peer_send_title" = "Who can send new messages?";
|
||||
"lng_manage_peer_send_only_members" = "Only members";
|
||||
@@ -1522,6 +1576,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
"lng_manage_peer_bot_public_link" = "Public Link";
|
||||
"lng_manage_peer_bot_public_links" = "Public Links";
|
||||
"lng_manage_peer_bot_balance" = "Balance";
|
||||
"lng_manage_peer_bot_edit_intro" = "Edit Intro";
|
||||
"lng_manage_peer_bot_edit_commands" = "Edit Commands";
|
||||
"lng_manage_peer_bot_edit_settings" = "Change Bot Settings";
|
||||
@@ -1834,6 +1889,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_action_boost_apply#one" = "{from} boosted the group";
|
||||
"lng_action_boost_apply#other" = "{from} boosted the group {count} times";
|
||||
"lng_action_set_chat_intro" = "{from} added the message below for all empty chats. How?";
|
||||
"lng_action_payment_refunded" = "{peer} refunded back {amount}";
|
||||
|
||||
"lng_similar_channels_title" = "Similar channels";
|
||||
"lng_similar_channels_view_all" = "View all";
|
||||
@@ -2147,6 +2203,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_premium_summary_about_translation" = "Real-time translation of channels and chats into other languages.";
|
||||
"lng_premium_summary_subtitle_business" = "Telegram Business";
|
||||
"lng_premium_summary_about_business" = "Upgrade your account with business features such as location, opening hours and quick replies.";
|
||||
"lng_premium_summary_subtitle_effects" = "Message Effects";
|
||||
"lng_premium_summary_about_effects" = "Add over 500 animated effects to private messages.";
|
||||
"lng_premium_summary_bottom_subtitle" = "About Telegram Premium";
|
||||
"lng_premium_summary_bottom_about" = "While the free version of Telegram already gives its users more than any other messaging application, **Telegram Premium** pushes its capabilities even further.\n\n**Telegram Premium** is a paid option, because most Premium Features require additional expenses from Telegram to third parties such as data center providers and server manufacturers. Contributions from **Telegram Premium** users allow us to cover such costs and also help Telegram stay free for everyone.";
|
||||
"lng_premium_summary_button" = "Subscribe for {cost} per month";
|
||||
@@ -2264,10 +2322,72 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_business_about_chat_intro" = "Customize the message people see before they start a chat with you.";
|
||||
"lng_business_subtitle_chat_links" = "Links to Chat";
|
||||
"lng_business_about_chat_links" = "Create links that start a chat with you, suggesting the first message.";
|
||||
"lng_business_subtitle_sponsored" = "Ads in Channels";
|
||||
"lng_business_button_sponsored" = "Do Not Hide Ads";
|
||||
"lng_business_about_sponsored" = "As a Premium subscriber, you don’t see any ads on Telegram, but you can turn them on, for example, to view your own ads that you launched on the {link}";
|
||||
"lng_business_about_sponsored_link" = "Telegram Ad Platform {emoji}";
|
||||
"lng_business_about_sponsored_url" = "https://ads.telegram.org";
|
||||
|
||||
"lng_credits_summary_title" = "Telegram Stars";
|
||||
"lng_credits_summary_about" = "Buy Stars to unlock content and services in miniapps on Telegram.";
|
||||
"lng_credits_summary_options_subtitle" = "Choose package";
|
||||
"lng_credits_summary_options_credits#one" = "{count} Star";
|
||||
"lng_credits_summary_options_credits#other" = "{count} Stars";
|
||||
"lng_credits_summary_options_more" = "More Options";
|
||||
"lng_credits_summary_options_about" = "By proceeding and purchasing Stars, you agree with the {link}.";
|
||||
"lng_credits_summary_options_about_link" = "Terms and Conditions";
|
||||
"lng_credits_summary_options_about_url" = "https://telegram.org/tos/stars";
|
||||
"lng_credits_summary_history_tab_full" = "All Transactions";
|
||||
"lng_credits_summary_history_tab_in" = "Incoming";
|
||||
"lng_credits_summary_history_tab_out" = "Outgoing";
|
||||
"lng_credits_summary_history_entry_inner_in" = "In-App Purchase";
|
||||
"lng_credits_summary_balance" = "Balance";
|
||||
"lng_credits_box_out_title" = "Confirm Your Purchase";
|
||||
"lng_credits_box_out_sure#one" = "Do you want to buy **\"{text}\"** in **{bot}** for **{count} Star**?";
|
||||
"lng_credits_box_out_sure#other" = "Do you want to buy **\"{text}\"** in **{bot}** for **{count} Stars**?";
|
||||
"lng_credits_box_out_media#one" = "Do you want to unlock {media} in {chat} for **{count} Star**?";
|
||||
"lng_credits_box_out_media#other" = "Do you want to unlock {media} in {chat} for **{count} Stars**?";
|
||||
"lng_credits_box_out_photo" = "a photo";
|
||||
"lng_credits_box_out_photos#one" = "{count} photo";
|
||||
"lng_credits_box_out_photos#other" = "{count} photos";
|
||||
"lng_credits_box_out_video" = "a video";
|
||||
"lng_credits_box_out_videos#one" = "{count} video";
|
||||
"lng_credits_box_out_videos#other" = "{count} videos";
|
||||
"lng_credits_box_out_both" = "{photo} and {video}";
|
||||
"lng_credits_box_out_confirm#one" = "Confirm and Pay {emoji} {count} Star";
|
||||
"lng_credits_box_out_confirm#other" = "Confirm and Pay {emoji} {count} Stars";
|
||||
"lng_credits_box_out_about" = "Review the {link} for Stars.";
|
||||
"lng_credits_media_done_title" = "Media Unlocked";
|
||||
"lng_credits_media_done_text#one" = "**{count} Star** transferred to {chat}.";
|
||||
"lng_credits_media_done_text#other" = "**{count} Stars** transferred to {chat}.";
|
||||
"lng_credits_summary_in_toast_title" = "Stars Acquired";
|
||||
"lng_credits_summary_in_toast_about#one" = "**{count}** Star added to your balance.";
|
||||
"lng_credits_summary_in_toast_about#other" = "**{count}** Stars added to your balance.";
|
||||
"lng_credits_box_history_entry_peer" = "Recipient";
|
||||
"lng_credits_box_history_entry_peer_in" = "From";
|
||||
"lng_credits_box_history_entry_via" = "Via";
|
||||
"lng_credits_box_history_entry_play_market" = "Play Market";
|
||||
"lng_credits_box_history_entry_app_store" = "App Store";
|
||||
"lng_credits_box_history_entry_fragment" = "Fragment";
|
||||
"lng_credits_box_history_entry_ads" = "Ads Platform";
|
||||
"lng_credits_box_history_entry_premium_bot" = "Stars Top-Up";
|
||||
"lng_credits_box_history_entry_via_premium_bot" = "Premium Bot";
|
||||
"lng_credits_box_history_entry_id" = "Transaction ID";
|
||||
"lng_credits_box_history_entry_id_copied" = "Transaction ID copied to clipboard.";
|
||||
"lng_credits_box_history_entry_success_date" = "Transaction date";
|
||||
"lng_credits_box_history_entry_success_url" = "Transaction link";
|
||||
"lng_credits_box_history_entry_media" = "Media";
|
||||
"lng_credits_box_history_entry_about" = "You can dispute this transaction {link}.";
|
||||
"lng_credits_box_history_entry_about_link" = "here";
|
||||
"lng_credits_small_balance_title#one" = "{count} Star Needed";
|
||||
"lng_credits_small_balance_title#other" = "{count} Stars Needed";
|
||||
"lng_credits_small_balance_about" = "Buy **Stars** and use them on **{bot}** and other miniapps.";
|
||||
"lng_credits_purchase_blocked" = "Sorry, you can't purchase this item with Telegram Stars.";
|
||||
|
||||
"lng_location_title" = "Location";
|
||||
"lng_location_about" = "Display the location of your business on your account.";
|
||||
"lng_location_address" = "Enter Address";
|
||||
"lng_location_set_map" = "Set Location on Map";
|
||||
"lng_location_fallback" = "You can set your location on the map from your mobile device.";
|
||||
|
||||
"lng_hours_title" = "Business Hours";
|
||||
@@ -2696,12 +2816,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_prizes_badge" = "x{amount}";
|
||||
|
||||
"lng_prizes_results_title" = "Winners Selected!";
|
||||
"lng_prizes_results_title_one" = "Winner Selected!";
|
||||
"lng_prizes_results_about#one" = "**{count}** winner of the {link} was randomly selected by Telegram.";
|
||||
"lng_prizes_results_about#other" = "**{count}** winners of the {link} were randomly selected by Telegram.";
|
||||
"lng_prizes_results_link" = "Giveaway";
|
||||
"lng_prizes_results_winner" = "Winner";
|
||||
"lng_prizes_results_winners" = "Winners";
|
||||
"lng_prizes_results_more#one" = "and {count} more!";
|
||||
"lng_prizes_results_more#other" = "and {count} more!";
|
||||
"lng_prizes_results_one" = "The winner received their gift link in a private message.";
|
||||
"lng_prizes_results_all" = "All winners received gift links in private messages.";
|
||||
"lng_prizes_results_some" = "Some winners couldn't be selected.";
|
||||
|
||||
@@ -2834,7 +2957,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_in_dlg_audio_count#other" = "{count} audio";
|
||||
|
||||
"lng_ban_user" = "Ban User";
|
||||
"lng_ban_users" = "Ban users";
|
||||
"lng_restrict_users" = "Restrict users";
|
||||
"lng_delete_all_from_user" = "Delete all from {user}";
|
||||
"lng_delete_all_from_users" = "Delete all from users";
|
||||
"lng_restrict_user_part" = "Partially restrict this user {emoji}";
|
||||
"lng_restrict_users_part" = "Partially restrict users {emoji}";
|
||||
"lng_restrict_user_full" = "Fully ban this user {emoji}";
|
||||
"lng_restrict_users_full" = "Fully ban users {emoji}";
|
||||
"lng_restrict_users_part_single_header" = "What can this user do?";
|
||||
"lng_restrict_users_part_header#one" = "What can {count} selected user do?";
|
||||
"lng_restrict_users_part_header#other" = "What can {count} selected users do?";
|
||||
"lng_report_spam" = "Report Spam";
|
||||
"lng_report_spam_and_leave" = "Report spam and leave";
|
||||
"lng_report_spam_done" = "Thank you for your report.";
|
||||
@@ -3027,6 +3160,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_bot_close_warning_sure" = "Close anyway";
|
||||
"lng_bot_add_to_side_menu" = "{bot} asks your permission to be added as an option to your main menu so you can access it any time.";
|
||||
"lng_bot_add_to_side_menu_done" = "Bot added to the main menu.";
|
||||
"lng_bot_no_scan_qr" = "QR Codes for bots are not supported on Desktop. Please use one of Telegram's mobile apps.";
|
||||
"lng_bot_click_to_start" = "Click here to use this bot.";
|
||||
|
||||
"lng_typing" = "typing";
|
||||
"lng_user_typing" = "{user} is typing";
|
||||
@@ -3062,6 +3197,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_unread_bar_some" = "Unread messages";
|
||||
|
||||
"lng_maps_point" = "Location";
|
||||
"lng_maps_select_on_map" = "Select on the Map";
|
||||
"lng_maps_point_send" = "Send This Location";
|
||||
"lng_maps_point_set" = "Set This Location";
|
||||
"lng_maps_or_choose" = "Or choose a venue";
|
||||
"lng_maps_places_in_area" = "Places in this area";
|
||||
"lng_maps_no_places" = "No places found";
|
||||
"lng_maps_choose_to_search" = "Choose location to see places nearby.";
|
||||
"lng_maps_venues_source" = "Powered by Foursquare";
|
||||
"lng_live_location" = "Live Location";
|
||||
"lng_live_location_now" = "updated just now";
|
||||
"lng_live_location_minutes#one" = "updated {count} minute ago";
|
||||
"lng_live_location_minutes#other" = "updated {count} minutes ago";
|
||||
"lng_live_location_hours#one" = "updated {count} hour ago";
|
||||
"lng_live_location_hours#other" = "updated {count} hours ago";
|
||||
"lng_live_location_today" = "updated today at {time}";
|
||||
"lng_live_location_yesterday" = "updated yesterday at {time}";
|
||||
"lng_live_location_date_time" = "updated {date} at {time}";
|
||||
"lng_save_photo" = "Save image";
|
||||
"lng_save_video" = "Save video";
|
||||
"lng_save_audio_file" = "Save audio file";
|
||||
@@ -3138,6 +3290,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_context_reply_msg" = "Reply";
|
||||
"lng_context_quote_and_reply" = "Quote & Reply";
|
||||
"lng_context_edit_msg" = "Edit";
|
||||
"lng_context_add_factcheck" = "Add Fact Check";
|
||||
"lng_context_edit_factcheck" = "Edit Fact Check";
|
||||
"lng_context_forward_msg" = "Forward Message";
|
||||
"lng_context_send_now_msg" = "Send now";
|
||||
"lng_context_reschedule" = "Reschedule";
|
||||
@@ -3208,6 +3362,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
"lng_context_spoiler_effect" = "Hide with Spoiler";
|
||||
"lng_context_disable_spoiler" = "Remove Spoiler";
|
||||
"lng_context_make_paid" = "Make This Content Paid";
|
||||
"lng_context_change_price" = "Change Price";
|
||||
|
||||
"lng_factcheck_title" = "Fact Check";
|
||||
"lng_factcheck_placeholder" = "Add Facts or Context";
|
||||
"lng_factcheck_whats_this" = "what's this?";
|
||||
"lng_factcheck_about" = "This clarification was provided by a fact checking agency assigned by the department of the government of your country ({country}) responsible for combatting misinformation.";
|
||||
"lng_factcheck_add_done" = "Fact check added.";
|
||||
"lng_factcheck_edit_done" = "Fact check edited.";
|
||||
"lng_factcheck_remove_done" = "Fact check removed.";
|
||||
"lng_factcheck_bottom" = "This clarification was provided by a fact checking agency assigned by the department of the government of your country ({country}) responsible for combatting misinformation.";
|
||||
"lng_factcheck_links" = "Only **t.me/** links are allowed.";
|
||||
|
||||
"lng_paid_title" = "Paid Content";
|
||||
"lng_paid_enter_cost" = "Enter Unlock Cost";
|
||||
"lng_paid_cost_placeholder" = "Stars to Unlock";
|
||||
"lng_paid_about" = "Users will have to transfer this amount of Stars to your channel in order to view this media. {link}";
|
||||
"lng_paid_about_link" = "More about stars >";
|
||||
"lng_paid_about_link_url" = "https://telegram.org/blog/telegram-stars";
|
||||
"lng_paid_price" = "Unlock for {price}";
|
||||
|
||||
"lng_translate_show_original" = "Show Original";
|
||||
"lng_translate_bar_to" = "Translate to {name}";
|
||||
@@ -3329,6 +3503,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_add_contact" = "Create";
|
||||
"lng_add_contact_button" = "New contact";
|
||||
"lng_contacts_header" = "Contacts";
|
||||
"lng_menu_not_contact" = "This number is not on Telegram";
|
||||
"lng_contacts_hidden_stories" = "Hidden Stories";
|
||||
"lng_contacts_stories_status#one" = "{count} story";
|
||||
"lng_contacts_stories_status#other" = "{count} stories";
|
||||
@@ -3405,6 +3580,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_mediaview_forward" = "Forward";
|
||||
"lng_mediaview_delete" = "Delete";
|
||||
"lng_mediaview_save_to_profile" = "Save to Profile";
|
||||
"lng_mediaview_pin_story_done" = "Story pinned";
|
||||
"lng_mediaview_pin_story_about" = "Now it will be always shown on the top.";
|
||||
"lng_mediaview_pin_stories_done#one" = "{count} story pinned";
|
||||
"lng_mediaview_pin_stories_done#other" = "{count} stories pinned";
|
||||
"lng_mediaview_pin_stories_about#one" = "Now it will be always shown on the top.";
|
||||
"lng_mediaview_pin_stories_about#other" = "Now they will be always shown on the top.";
|
||||
"lng_mediaview_unpin_story_done" = "Story unpinned.";
|
||||
"lng_mediaview_unpin_stories_done#one" = "{count} story unpinned";
|
||||
"lng_mediaview_unpin_stories_done#other" = "{count} stories unpinned";
|
||||
"lng_mediaview_pin_limit#one" = "You can't pin more than {count} story.";
|
||||
"lng_mediaview_pin_limit#other" = "You can't pin more than {count} stories.";
|
||||
"lng_mediaview_archive_story" = "Archive Story";
|
||||
"lng_mediaview_photos_all" = "View all photos";
|
||||
"lng_mediaview_files_all" = "View all files";
|
||||
@@ -3463,6 +3649,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_formatting_link_text" = "Text";
|
||||
"lng_formatting_link_url" = "URL";
|
||||
"lng_formatting_link_create" = "Create";
|
||||
"lng_formatting_code_title" = "Code Language";
|
||||
"lng_formatting_code_language" = "Language for syntax highlighting.";
|
||||
"lng_formatting_code_auto" = "Auto-Detect";
|
||||
|
||||
"lng_text_copied" = "Text copied to clipboard.";
|
||||
"lng_code_copied" = "Block copied to clipboard.";
|
||||
@@ -3570,6 +3759,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_payments_card_declined" = "Your card was declined.";
|
||||
"lng_payments_payment_failed" = "Payment failed. Your card has not been billed.";
|
||||
"lng_payments_precheckout_failed" = "The bot couldn't process your payment. Your card has not been billed.";
|
||||
"lng_payments_precheckout_timeout" = "The bot didn't respond in time. Your card has not been billed.";
|
||||
"lng_payments_precheckout_stars_failed" = "The bot couldn't process your payment.";
|
||||
"lng_payments_precheckout_stars_timeout" = "The bot didn't respond in time.";
|
||||
"lng_payments_already_paid" = "You have already paid for this item.";
|
||||
|
||||
"lng_payments_terms_title" = "Terms of Service";
|
||||
@@ -4013,6 +4205,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_restricted_send_polls_all" = "Posting polls isn't allowed in this group.";
|
||||
|
||||
"lng_restricted_send_public_polls" = "Sorry, public polls can't be forwarded to channels.";
|
||||
"lng_restricted_send_paid_media" = "Sorry, paid media can't be sent to this channel.";
|
||||
|
||||
"lng_restricted_send_voice_messages" = "{user} restricted sending of voice messages to them.";
|
||||
"lng_restricted_send_video_messages" = "{user} restricted sending of video messages to them.";
|
||||
@@ -4480,10 +4673,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_translate_settings_about" = "The 'Translate' button will appear when you open a context menu on a text message.";
|
||||
"lng_translate_settings_one" = "Please choose at least one language so that it can be used as the \"Translate to\" language.";
|
||||
|
||||
"lng_launch_exe_warning" = "This file has a {extension} extension.\nAre you sure you want to run it?";
|
||||
"lng_launch_exe_warning" = "This file has {extension} extension.\nAre you sure you want to run it?";
|
||||
"lng_launch_other_warning" = "This file has {extension} extension.\nAre you sure you want to open it?";
|
||||
"lng_launch_svg_warning" = "Opening this file can potentially expose your IP address to its sender. Continue?";
|
||||
"lng_launch_exe_sure" = "Run";
|
||||
"lng_launch_other_sure" = "Open";
|
||||
"lng_launch_exe_dont_ask" = "Don't ask me again";
|
||||
"lng_launch_dont_ask" = "Remember for this file type";
|
||||
"lng_launch_dont_ask_settings" = "You can later edit trusted file types in Settings > Privacy and Security > File open confirmations.";
|
||||
|
||||
"lng_polls_anonymous" = "Anonymous Poll";
|
||||
"lng_polls_public" = "Poll";
|
||||
@@ -4695,6 +4892,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_view_button_boost" = "Boost";
|
||||
"lng_view_button_giftcode" = "Open";
|
||||
"lng_view_button_iv" = "Instant View";
|
||||
"lng_view_button_stickerset" = "View stickers";
|
||||
"lng_view_button_emojipack" = "View emoji";
|
||||
|
||||
"lng_sponsored_hide_ads" = "Hide";
|
||||
"lng_sponsored_title" = "What are sponsored messages?";
|
||||
@@ -5034,6 +5233,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_channel_earn_history_return" = "Refund";
|
||||
"lng_channel_earn_history_return_about" = "Refunded back";
|
||||
"lng_channel_earn_history_pending" = "Pending";
|
||||
"lng_channel_earn_history_failed" = "Failed";
|
||||
"lng_channel_earn_history_show_more#one" = "Show {count} More Transaction";
|
||||
"lng_channel_earn_history_show_more#other" = "Show {count} More Transactions";
|
||||
"lng_channel_earn_off" = "Switch Off Ads";
|
||||
@@ -5056,6 +5256,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_channel_earn_chart_revenue" = "Ad revenue";
|
||||
"lng_channel_earn_chart_overriden_detail_currency" = "Revenue in TON";
|
||||
"lng_channel_earn_chart_overriden_detail_usd" = "Revenue in USD";
|
||||
"lng_channel_earn_currency_history" = "TON Transactions";
|
||||
"lng_channel_earn_credits_history" = "Stars Transactions";
|
||||
"lng_channel_earn_out_check_password_about" = "You can withdraw only if you have:";
|
||||
|
||||
"lng_bot_earn_title" = "Stars Balance";
|
||||
"lng_bot_earn_chart_revenue" = "Revenue";
|
||||
"lng_bot_earn_overview_title" = "Proceeds overview";
|
||||
"lng_bot_earn_available" = "Available balance";
|
||||
"lng_bot_earn_total" = "Total lifetime proceeds";
|
||||
"lng_bot_earn_balance_title" = "Available balance";
|
||||
"lng_bot_earn_balance_about" = "Stars from your total balance become available for spending on ads and rewards 21 days after they are earned.";
|
||||
"lng_bot_earn_balance_about_url" = "https://telegram.org/tos/stars";
|
||||
"lng_bot_earn_balance_button#one" = "Withdraw {emoji} {count}";
|
||||
"lng_bot_earn_balance_button#other" = "Withdraw {emoji} {count}";
|
||||
"lng_bot_earn_balance_button_all" = "Withdraw all stars";
|
||||
"lng_bot_earn_balance_button_locked" = "Withdraw";
|
||||
"lng_bot_earn_balance_button_buy_ads" = "Buy Ads";
|
||||
"lng_bot_earn_learn_credits_out_about" = "You can withdraw Stars using Fragment, or use Stars to advertise your bot. {link}";
|
||||
"lng_bot_earn_out_ph" = "Enter amount to withdraw";
|
||||
"lng_bot_earn_balance_password_title" = "Two-step verification";
|
||||
"lng_bot_earn_balance_password_description" = "Please enter your password to collect.";
|
||||
"lng_bot_earn_credits_out_minimal" = "You cannot withdraw less then {link}.";
|
||||
"lng_bot_earn_credits_out_minimal_link#one" = "{count} star";
|
||||
"lng_bot_earn_credits_out_minimal_link#other" = "{count} stars";
|
||||
|
||||
"lng_contact_add" = "Add";
|
||||
"lng_contact_send_message" = "message";
|
||||
@@ -5064,6 +5288,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_iv_share" = "Share";
|
||||
"lng_iv_join_channel" = "Join";
|
||||
"lng_iv_window_title" = "Instant View";
|
||||
"lng_iv_wrong_layout" = "Wrong layout?";
|
||||
|
||||
"lng_limit_download_title" = "Download speed limited";
|
||||
"lng_limit_download_subscribe" = "Subscribe to {link} and increase download speed {increase}.";
|
||||
@@ -5078,6 +5303,58 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_limit_upload_increase_speed" = "by **{percent}**";
|
||||
"lng_limit_upload_subscribe_link" = "Telegram Premium";
|
||||
|
||||
"lng_recent_frequent" = "Frequent contacts";
|
||||
"lng_recent_frequent_all" = "Show all";
|
||||
"lng_recent_frequent_collapse" = "Collapse";
|
||||
"lng_recent_title" = "Recent";
|
||||
"lng_recent_clear" = "Clear";
|
||||
"lng_recent_clear_sure" = "Do you want to clear your search history?";
|
||||
"lng_recent_remove" = "Remove from Recent";
|
||||
"lng_recent_clear_all" = "Clear all";
|
||||
"lng_recent_hide_top" = "Remove all & Disable";
|
||||
"lng_recent_hide_sure" = "Are you sure you want to clear and disable frequent contacts list?\n\nYou can always turn this feature back on in Settings > Privacy > Suggest Frequent Contacts.";
|
||||
"lng_recent_hide_button" = "Hide";
|
||||
"lng_recent_none" = "Recent search results\nwill appear here.";
|
||||
"lng_recent_chats" = "Chats";
|
||||
"lng_recent_channels" = "Channels";
|
||||
"lng_channels_none_title" = "No channels yet...";
|
||||
"lng_channels_none_about" = "You are not currently subscribed to any channels.";
|
||||
"lng_channels_your_title" = "Channels you joined";
|
||||
"lng_channels_your_more" = "Show more";
|
||||
"lng_channels_your_less" = "Show less";
|
||||
"lng_channels_recommended" = "Recommended channels";
|
||||
|
||||
"lng_font_box_title" = "Choose font family";
|
||||
"lng_font_default" = "Default";
|
||||
"lng_font_system" = "System font";
|
||||
"lng_font_not_found" = "Font not found.";
|
||||
|
||||
"lng_search_tab_my_messages" = "My Messages";
|
||||
"lng_search_tab_this_topic" = "This Topic";
|
||||
"lng_search_tab_this_chat" = "This Chat";
|
||||
"lng_search_tab_this_channel" = "This Channel";
|
||||
"lng_search_tab_this_group" = "This Group";
|
||||
"lng_search_tab_public_posts" = "Public Posts";
|
||||
"lng_search_tab_no_results" = "No Results";
|
||||
"lng_search_tab_no_results_text" = "There were no results for \"{query}\".";
|
||||
"lng_search_tab_no_results_retry" = "Try another hashtag.";
|
||||
"lng_search_tab_by_hashtag" = "Enter a hashtag to find messages containing it.";
|
||||
|
||||
"lng_contact_details_button" = "View Contact";
|
||||
"lng_contact_details_title" = "Contact details";
|
||||
"lng_contact_details_phone" = "Phone";
|
||||
"lng_contact_details_phone_main" = "Main Phone";
|
||||
"lng_contact_details_phone_home" = "Home Phone";
|
||||
"lng_contact_details_phone_mobile" = "Mobile Phone";
|
||||
"lng_contact_details_phone_work" = "Work Phone";
|
||||
"lng_contact_details_phone_other" = "Other Phone";
|
||||
"lng_contact_details_email" = "Email";
|
||||
"lng_contact_details_address" = "Address";
|
||||
"lng_contact_details_url" = "URL";
|
||||
"lng_contact_details_note" = "Note";
|
||||
"lng_contact_details_birthday" = "Birthday";
|
||||
"lng_contact_details_organization" = "Organization";
|
||||
|
||||
// Wnd specific
|
||||
|
||||
"lng_wnd_choose_program_menu" = "Choose Default Program...";
|
||||
|
||||
120
Telegram/Resources/picker_html/picker.css
Normal file
@@ -0,0 +1,120 @@
|
||||
:root {
|
||||
--font-sans: -apple-system, BlinkMacSystemFont, avenir next, avenir, Segoe UI Variable Text, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, tahoma, arial, sans-serif;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-sans);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background-color: var(--td-window-bg);
|
||||
color: var(--td-window-fg);
|
||||
}
|
||||
|
||||
html.custom_scroll ::-webkit-scrollbar {
|
||||
border-radius: 5px !important;
|
||||
border: 3px solid transparent !important;
|
||||
background-color: var(--td-scroll-bg) !important;
|
||||
background-clip: content-box !important;
|
||||
width: 10px !important;
|
||||
}
|
||||
html.custom_scroll ::-webkit-scrollbar:hover {
|
||||
background-color: var(--td-scroll-bg-over) !important;
|
||||
}
|
||||
html.custom_scroll ::-webkit-scrollbar-thumb {
|
||||
border-radius: 5px !important;
|
||||
border: 3px solid transparent !important;
|
||||
background-color: var(--td-scroll-bar-bg) !important;
|
||||
background-clip: content-box !important;
|
||||
}
|
||||
html.custom_scroll ::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--td-scroll-bar-bg-over) !important;
|
||||
}
|
||||
|
||||
#map {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#marker {
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
#marker_drop {
|
||||
margin-bottom: 0px;
|
||||
transition: margin 160ms ease-in-out;
|
||||
}
|
||||
#marker_drop.moving {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
#marker_shadow {
|
||||
position: absolute;
|
||||
}
|
||||
#search_venues {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 2;
|
||||
top: -30px;
|
||||
transition: top 200ms ease-in-out;
|
||||
}
|
||||
#search_venues.shown {
|
||||
top: 6px;
|
||||
}
|
||||
#search_venues_inner {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
background: var(--td-window-bg);
|
||||
color: var(--td-window-active-text-fg);
|
||||
cursor: pointer;
|
||||
border-radius: 14px;
|
||||
padding: 5px 12px 6px;
|
||||
box-shadow: 0 0 3px 0px var(--td-history-to-down-shadow);
|
||||
}
|
||||
#search_venues_inner:hover {
|
||||
background: var(--td-window-bg-over);
|
||||
}
|
||||
#search_venues_content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
#search_venues_content:before {
|
||||
content: var(--td-lng-maps-places-in-area);
|
||||
}
|
||||
#search_venues_inner .ripple .inner {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
transform: scale(0);
|
||||
opacity: 1;
|
||||
animation: ripple 650ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
|
||||
background-color: var(--td-window-bg-ripple);
|
||||
}
|
||||
#search_venues_inner .ripple.hiding {
|
||||
animation: fadeOut 200ms linear forwards;
|
||||
}
|
||||
@keyframes ripple {
|
||||
to {
|
||||
transform: scale(2);
|
||||
}
|
||||
}
|
||||
@keyframes fadeOut {
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
199
Telegram/Resources/picker_html/picker.js
Normal file
@@ -0,0 +1,199 @@
|
||||
var LocationPicker = {
|
||||
startZoom: 14,
|
||||
flySpeed: 2.4,
|
||||
notify: function(message) {
|
||||
if (window.external && window.external.invoke) {
|
||||
window.external.invoke(JSON.stringify(message));
|
||||
}
|
||||
},
|
||||
frameKeyDown: function (e) {
|
||||
const keyW = (e.key === 'w')
|
||||
|| (e.code === 'KeyW')
|
||||
|| (e.keyCode === 87);
|
||||
const keyQ = (e.key === 'q')
|
||||
|| (e.code === 'KeyQ')
|
||||
|| (e.keyCode === 81);
|
||||
const keyM = (e.key === 'm')
|
||||
|| (e.code === 'KeyM')
|
||||
|| (e.keyCode === 77);
|
||||
if ((e.metaKey || e.ctrlKey) && (keyW || keyQ || keyM)) {
|
||||
e.preventDefault();
|
||||
LocationPicker.notify({
|
||||
event: 'keydown',
|
||||
modifier: e.ctrlKey ? 'ctrl' : 'cmd',
|
||||
key: keyW ? 'w' : keyQ ? 'q' : 'm',
|
||||
});
|
||||
} else if (e.key === 'Escape' || e.keyCode === 27) {
|
||||
e.preventDefault();
|
||||
LocationPicker.notify({
|
||||
event: 'keydown',
|
||||
key: 'escape',
|
||||
});
|
||||
}
|
||||
},
|
||||
isNight: function() {
|
||||
var html = document.getElementsByTagName('html')[0];
|
||||
return html.style.getPropertyValue('--td-night') == '1';
|
||||
},
|
||||
lightPreset: function() {
|
||||
return LocationPicker.isNight() ? 'night' : 'day';
|
||||
},
|
||||
updateStyles: function (styles) {
|
||||
if (LocationPicker.styles !== styles) {
|
||||
LocationPicker.styles = styles;
|
||||
document.getElementsByTagName('html')[0].style = styles;
|
||||
|
||||
LocationPicker.map.setConfigProperty(
|
||||
'basemap',
|
||||
'lightPreset',
|
||||
LocationPicker.lightPreset());
|
||||
}
|
||||
},
|
||||
init: function (params) {
|
||||
mapboxgl.accessToken = params.token;
|
||||
if (params.protocol) {
|
||||
mapboxgl.config.API_URL = params.protocol + '://domain/api.mapbox.com';
|
||||
}
|
||||
|
||||
var options = { container: 'map', config: {
|
||||
basemap: { lightPreset: LocationPicker.lightPreset() }
|
||||
} };
|
||||
var center = params.center;
|
||||
if (center) {
|
||||
center = [center[1], center[0]];
|
||||
options.center = center;
|
||||
options.zoom = LocationPicker.startZoom;
|
||||
} else if (params.bounds) {
|
||||
options.bounds = params.bounds;
|
||||
center = new mapboxgl.LngLatBounds(params.bounds).getCenter();
|
||||
} else {
|
||||
center = [0, 0];
|
||||
}
|
||||
LocationPicker.map = new mapboxgl.Map(options);
|
||||
LocationPicker.createMarker(center);
|
||||
LocationPicker.trackMovement();
|
||||
LocationPicker.initSearchVenueRipple();
|
||||
},
|
||||
marker: function() {
|
||||
return document.getElementById('marker_drop');
|
||||
},
|
||||
createMarker: function(center) {
|
||||
document.getElementById('marker').style.display = 'flex';
|
||||
},
|
||||
clearMovingTimer: function() {
|
||||
if (LocationPicker.clearMovingTimeoutId) {
|
||||
clearTimeout(LocationPicker.clearMovingTimeoutId);
|
||||
LocationPicker.clearMovingTimeoutId = 0;
|
||||
}
|
||||
},
|
||||
startMovingTimer: function(done) {
|
||||
LocationPicker.clearMovingTimer();
|
||||
LocationPicker.clearMovingTimeoutId = setTimeout(done, 500);
|
||||
},
|
||||
trackMovement: function() {
|
||||
LocationPicker.map.on('movestart', function() {
|
||||
LocationPicker.marker().classList.add('moving');
|
||||
LocationPicker.clearMovingTimer();
|
||||
LocationPicker.toggleSearchVenues(false);
|
||||
LocationPicker.notify({ event: 'move_start' });
|
||||
});
|
||||
LocationPicker.map.on('moveend', function() {
|
||||
LocationPicker.startMovingTimer(function() {
|
||||
LocationPicker.marker().classList.remove('moving');
|
||||
LocationPicker.notify({
|
||||
event: 'move_end',
|
||||
latitude: LocationPicker.map.getCenter().lat,
|
||||
longitude: LocationPicker.map.getCenter().lng
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
narrowTo: function (point) {
|
||||
LocationPicker.map.flyTo({
|
||||
center: [point[1], point[0]],
|
||||
zoom: LocationPicker.startZoom,
|
||||
speed: LocationPicker.flySpeed,
|
||||
});
|
||||
},
|
||||
send: function () {
|
||||
LocationPicker.notify({
|
||||
event: 'send',
|
||||
latitude: LocationPicker.map.getCenter().lat,
|
||||
longitude: LocationPicker.map.getCenter().lng
|
||||
});
|
||||
},
|
||||
addRipple: function (button, x, y) {
|
||||
const ripple = document.createElement('span');
|
||||
ripple.classList.add('ripple');
|
||||
|
||||
const inner = document.createElement('span');
|
||||
inner.classList.add('inner');
|
||||
|
||||
var rect = button.getBoundingClientRect();
|
||||
x -= rect.x;
|
||||
y -= rect.y;
|
||||
|
||||
const mx = button.clientWidth - x;
|
||||
const my = button.clientHeight - y;
|
||||
const sq1 = x * x + y * y;
|
||||
const sq2 = mx * mx + y * y;
|
||||
const sq3 = x * x + my * my;
|
||||
const sq4 = mx * mx + my * my;
|
||||
const radius = Math.sqrt(Math.max(sq1, sq2, sq3, sq4));
|
||||
|
||||
inner.style.width = inner.style.height = `${2 * radius}px`;
|
||||
inner.style.left = `${x - radius}px`;
|
||||
inner.style.top = `${y - radius}px`;
|
||||
inner.classList.add('inner');
|
||||
|
||||
ripple.addEventListener('animationend', function (e) {
|
||||
if (e.animationName === 'fadeOut') {
|
||||
ripple.remove();
|
||||
}
|
||||
});
|
||||
|
||||
ripple.appendChild(inner);
|
||||
button.appendChild(ripple);
|
||||
},
|
||||
stopRipples: function (button) {
|
||||
const id = button.id ? button.id : button;
|
||||
button = document.getElementById(id);
|
||||
const ripples = button.getElementsByClassName('ripple');
|
||||
for (var i = 0; i < ripples.length; ++i) {
|
||||
const ripple = ripples[i];
|
||||
if (!ripple.classList.contains('hiding')) {
|
||||
ripple.classList.add('hiding');
|
||||
}
|
||||
}
|
||||
},
|
||||
initSearchVenueRipple: function() {
|
||||
var button = document.getElementById('search_venues_inner');
|
||||
button.addEventListener('mousedown', function (e) {
|
||||
LocationPicker.addRipple(e.currentTarget, e.clientX, e.clientY);
|
||||
LocationPicker.searchVenuesPressed = true;
|
||||
});
|
||||
button.addEventListener('mouseup', function (e) {
|
||||
const id = e.currentTarget.id;
|
||||
setTimeout(function () {
|
||||
LocationPicker.stopRipples(id);
|
||||
}, 0);
|
||||
if (LocationPicker.searchVenuesPressed) {
|
||||
LocationPicker.searchVenuesPressed = false;
|
||||
LocationPicker.toggleSearchVenues(false);
|
||||
LocationPicker.notify({
|
||||
event: 'search_venues',
|
||||
latitude: LocationPicker.map.getCenter().lat,
|
||||
longitude: LocationPicker.map.getCenter().lng
|
||||
});
|
||||
}
|
||||
});
|
||||
button.addEventListener('mouseleave', function (e) {
|
||||
LocationPicker.stopRipples(e.currentTarget);
|
||||
LocationPicker.searchVenuesPressed = false;
|
||||
});
|
||||
},
|
||||
toggleSearchVenues: function(shown) {
|
||||
var button = document.getElementById('search_venues');
|
||||
button.classList.toggle('shown', shown);
|
||||
},
|
||||
};
|
||||
@@ -24,5 +24,7 @@
|
||||
<file alias="chat_link.tgs">../../animations/chat_link.tgs</file>
|
||||
<file alias="collectible_username.tgs">../../animations/collectible_username.tgs</file>
|
||||
<file alias="collectible_phone.tgs">../../animations/collectible_phone.tgs</file>
|
||||
<file alias="search.tgs">../../animations/search.tgs</file>
|
||||
<file alias="noresults.tgs">../../animations/noresults.tgs</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
6
Telegram/Resources/qrc/telegram/picker.qrc
Normal file
@@ -0,0 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/picker">
|
||||
<file alias="picker.css">../../picker_html/picker.css</file>
|
||||
<file alias="picker.js">../../picker_html/picker.js</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -10,7 +10,7 @@
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="4.16.2.0" />
|
||||
Version="5.2.6.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||
|
||||
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,16,2,0
|
||||
PRODUCTVERSION 4,16,2,0
|
||||
FILEVERSION 5,2,6,0
|
||||
PRODUCTVERSION 5,2,6,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -62,10 +62,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||
VALUE "FileDescription", "Telegram Desktop"
|
||||
VALUE "FileVersion", "4.16.2.0"
|
||||
VALUE "FileVersion", "5.2.6.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "4.16.2.0"
|
||||
VALUE "ProductVersion", "5.2.6.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,16,2,0
|
||||
PRODUCTVERSION 4,16,2,0
|
||||
FILEVERSION 5,2,6,0
|
||||
PRODUCTVERSION 5,2,6,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -53,10 +53,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||
VALUE "FileDescription", "Telegram Desktop Updater"
|
||||
VALUE "FileVersion", "4.16.2.0"
|
||||
VALUE "FileVersion", "5.2.6.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "4.16.2.0"
|
||||
VALUE "ProductVersion", "5.2.6.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -155,6 +155,7 @@ int main(int argc, char *argv[])
|
||||
QString remove;
|
||||
int version = 0;
|
||||
[[maybe_unused]] bool targetwin64 = false;
|
||||
[[maybe_unused]] bool targetwinarm = false;
|
||||
[[maybe_unused]] bool targetarmac = false;
|
||||
QFileInfoList files;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
@@ -165,6 +166,7 @@ int main(int argc, char *argv[])
|
||||
if (remove.isEmpty()) remove = info.canonicalPath() + "/";
|
||||
} else if (string("-target") == argv[i] && i + 1 < argc) {
|
||||
targetwin64 = (string("win64") == argv[i + 1]);
|
||||
targetwinarm = (string("winarm") == argv[i + 1]);
|
||||
} else if (string("-arch") == argv[i] && i + 1 < argc) {
|
||||
targetarmac = (string("arm64") == argv[i + 1]);
|
||||
if (!targetarmac && string("x86_64") != argv[i + 1]) {
|
||||
@@ -493,7 +495,7 @@ int main(int argc, char *argv[])
|
||||
cout << "Signature verified!\n";
|
||||
RSA_free(pbKey);
|
||||
#ifdef Q_OS_WIN
|
||||
QString outName((targetwin64 ? QString("tx64upd%1") : QString("tupdate%1")).arg(AlphaVersion ? AlphaVersion : version));
|
||||
QString outName((targetwinarm ? QString("tarm64upd%1") : targetwin64 ? QString("tx64upd%1") : QString("tupdate%1")).arg(AlphaVersion ? AlphaVersion : version));
|
||||
#elif defined Q_OS_MAC
|
||||
QString outName((targetarmac ? QString("tarmacupd%1") : QString("tmacupd%1")).arg(AlphaVersion ? AlphaVersion : version));
|
||||
#else
|
||||
|
||||
@@ -571,8 +571,8 @@ void _generateDump(EXCEPTION_POINTERS* pExceptionPointers) {
|
||||
}
|
||||
if (!hDumpFile || hDumpFile == INVALID_HANDLE_VALUE) {
|
||||
WCHAR wstrPath[maxFileLen];
|
||||
DWORD wstrPathLen;
|
||||
if (wstrPathLen = GetEnvironmentVariable(L"APPDATA", wstrPath, maxFileLen)) {
|
||||
DWORD wstrPathLen = GetEnvironmentVariable(L"APPDATA", wstrPath, maxFileLen);
|
||||
if (wstrPathLen) {
|
||||
wsprintf(wstrPath + wstrPathLen, L"\\%s\\", _programName);
|
||||
hDumpFile = _generateDumpFileAtPath(wstrPath);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history_item_components.h"
|
||||
#include "inline_bots/bot_attach_web_view.h"
|
||||
#include "payments/payments_checkout_process.h"
|
||||
#include "payments/payments_non_panel_process.h"
|
||||
#include "main/main_session.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
@@ -126,11 +127,7 @@ void SendBotCallbackData(
|
||||
UrlClickHandler::Open(link);
|
||||
return;
|
||||
}
|
||||
const auto scoreLink = AppendShareGameScoreUrl(
|
||||
session,
|
||||
link,
|
||||
item->fullId());
|
||||
BotGameUrlClickHandler(bot, scoreLink).onClick({
|
||||
BotGameUrlClickHandler(bot, link).onClick({
|
||||
Qt::LeftButton,
|
||||
QVariant::fromValue(ClickHandlerContext{
|
||||
.itemId = item->fullId(),
|
||||
@@ -236,14 +233,14 @@ void SendBotCallbackDataWithPassword(
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
const auto box = std::make_shared<QPointer<PasscodeBox>>();
|
||||
auto fields = PasscodeBox::CloudFields::From(state);
|
||||
fields.customTitle = tr::lng_bots_password_confirm_title();
|
||||
fields.customDescription
|
||||
= tr::lng_bots_password_confirm_description(tr::now);
|
||||
fields.customSubmitButton = tr::lng_passcode_submit();
|
||||
fields.customCheckCallback = [=](
|
||||
const Core::CloudPasswordResult &result) {
|
||||
const Core::CloudPasswordResult &result,
|
||||
QPointer<PasscodeBox> box) {
|
||||
if (const auto button = getButton()) {
|
||||
if (button->requestId) {
|
||||
return;
|
||||
@@ -257,18 +254,17 @@ void SendBotCallbackDataWithPassword(
|
||||
return;
|
||||
}
|
||||
SendBotCallbackData(strongController, item, row, column, result, [=] {
|
||||
if (*box) {
|
||||
(*box)->closeBox();
|
||||
if (box) {
|
||||
box->closeBox();
|
||||
}
|
||||
}, [=](const QString &error) {
|
||||
if (*box) {
|
||||
(*box)->handleCustomCheckError(error);
|
||||
if (box) {
|
||||
box->handleCustomCheckError(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
auto object = Box<PasscodeBox>(session, fields);
|
||||
*box = Ui::MakeWeak(object.data());
|
||||
show->showBox(std::move(object), Ui::LayerOption::CloseOther);
|
||||
}, *lifetime);
|
||||
}
|
||||
@@ -336,7 +332,8 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
|
||||
Payments::Mode::Payment,
|
||||
crl::guard(controller, [=](auto) {
|
||||
controller->widget()->activate();
|
||||
}));
|
||||
}),
|
||||
Payments::ProcessNonPanelPaymentFormFactory(controller, item));
|
||||
} break;
|
||||
|
||||
case ButtonType::Url: {
|
||||
@@ -491,20 +488,23 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
|
||||
|
||||
case ButtonType::WebView: {
|
||||
if (const auto bot = item->getMessageBot()) {
|
||||
bot->session().attachWebView().request(
|
||||
controller,
|
||||
Api::SendAction(bot->owner().history(bot)),
|
||||
bot,
|
||||
{ .text = button->text, .url = button->data });
|
||||
bot->session().attachWebView().open({
|
||||
.bot = bot,
|
||||
.context = { .controller = controller },
|
||||
.button = { .text = button->text, .url = button->data },
|
||||
.source = InlineBots::WebViewSourceButton{ .simple = false },
|
||||
});
|
||||
}
|
||||
} break;
|
||||
|
||||
case ButtonType::SimpleWebView: {
|
||||
if (const auto bot = item->getMessageBot()) {
|
||||
bot->session().attachWebView().requestSimple(
|
||||
controller,
|
||||
bot,
|
||||
{ .text = button->text, .url = button->data });
|
||||
bot->session().attachWebView().open({
|
||||
.bot = bot,
|
||||
.context = { .controller = controller },
|
||||
.button = {.text = button->text, .url = button->data },
|
||||
.source = InlineBots::WebViewSourceButton{ .simple = true },
|
||||
});
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
@@ -112,8 +112,8 @@ void ApplyLastList(
|
||||
channel->mgInfo->lastAdmins.clear();
|
||||
channel->mgInfo->lastRestricted.clear();
|
||||
channel->mgInfo->lastParticipants.clear();
|
||||
channel->mgInfo->lastParticipantsStatus =
|
||||
MegagroupInfo::LastParticipantsUpToDate
|
||||
channel->mgInfo->lastParticipantsStatus
|
||||
= MegagroupInfo::LastParticipantsUpToDate
|
||||
| MegagroupInfo::LastParticipantsOnceReceived;
|
||||
|
||||
auto botStatus = channel->mgInfo->botStatus;
|
||||
@@ -212,7 +212,7 @@ void ApplyBotsList(
|
||||
}
|
||||
|
||||
[[nodiscard]] ChatParticipants::Channels ParseSimilar(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<Main::Session*> session,
|
||||
const MTPmessages_Chats &chats) {
|
||||
auto result = ChatParticipants::Channels();
|
||||
std::vector<not_null<ChannelData*>>();
|
||||
@@ -220,13 +220,13 @@ void ApplyBotsList(
|
||||
const auto &list = data.vchats().v;
|
||||
result.list.reserve(list.size());
|
||||
for (const auto &chat : list) {
|
||||
const auto peer = channel->owner().processChat(chat);
|
||||
const auto peer = session->data().processChat(chat);
|
||||
if (const auto channel = peer->asChannel()) {
|
||||
result.list.push_back(channel);
|
||||
}
|
||||
}
|
||||
if constexpr (MTPDmessages_chatsSlice::Is<decltype(data)>()) {
|
||||
if (channel->session().premiumPossible()) {
|
||||
if (session->premiumPossible()) {
|
||||
result.more = data.vcount().v - data.vchats().v.size();
|
||||
}
|
||||
}
|
||||
@@ -234,6 +234,12 @@ void ApplyBotsList(
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] ChatParticipants::Channels ParseSimilar(
|
||||
not_null<ChannelData*> channel,
|
||||
const MTPmessages_Chats &chats) {
|
||||
return ParseSimilar(&channel->session(), chats);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ChatParticipant::ChatParticipant(
|
||||
@@ -351,7 +357,8 @@ QString ChatParticipant::rank() const {
|
||||
}
|
||||
|
||||
ChatParticipants::ChatParticipants(not_null<ApiWrap*> api)
|
||||
: _api(&api->instance()) {
|
||||
: _session(&api->session())
|
||||
, _api(&api->instance()) {
|
||||
}
|
||||
|
||||
void ChatParticipants::requestForAdd(
|
||||
@@ -585,6 +592,33 @@ ChatParticipants::Parsed ChatParticipants::ParseRecent(
|
||||
return result;
|
||||
}
|
||||
|
||||
void ChatParticipants::Restrict(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<PeerData*> participant,
|
||||
ChatRestrictionsInfo oldRights,
|
||||
ChatRestrictionsInfo newRights,
|
||||
Fn<void()> onDone,
|
||||
Fn<void()> onFail) {
|
||||
channel->session().api().request(MTPchannels_EditBanned(
|
||||
channel->inputChannel,
|
||||
participant->input,
|
||||
MTP_chatBannedRights(
|
||||
MTP_flags(MTPDchatBannedRights::Flags::from_raw(
|
||||
uint32(newRights.flags))),
|
||||
MTP_int(newRights.until))
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
channel->session().api().applyUpdates(result);
|
||||
channel->applyEditBanned(participant, oldRights, newRights);
|
||||
if (onDone) {
|
||||
onDone();
|
||||
}
|
||||
}).fail([=] {
|
||||
if (onFail) {
|
||||
onFail();
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ChatParticipants::requestSelf(not_null<ChannelData*> channel) {
|
||||
if (_selfParticipantRequests.contains(channel)) {
|
||||
return;
|
||||
@@ -730,8 +764,11 @@ void ChatParticipants::loadSimilarChannels(not_null<ChannelData*> channel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
using Flag = MTPchannels_GetChannelRecommendations::Flag;
|
||||
_similar[channel].requestId = _api.request(
|
||||
MTPchannels_GetChannelRecommendations(channel->inputChannel)
|
||||
MTPchannels_GetChannelRecommendations(
|
||||
MTP_flags(Flag::f_channel),
|
||||
channel->inputChannel)
|
||||
).done([=](const MTPmessages_Chats &result) {
|
||||
auto &similar = _similar[channel];
|
||||
similar.requestId = 0;
|
||||
@@ -766,4 +803,29 @@ auto ChatParticipants::similarLoaded() const
|
||||
return _similarLoaded.events();
|
||||
}
|
||||
|
||||
void ChatParticipants::loadRecommendations() {
|
||||
if (_recommendationsLoaded.current() || _recommendations.requestId) {
|
||||
return;
|
||||
}
|
||||
_recommendations.requestId = _api.request(
|
||||
MTPchannels_GetChannelRecommendations(
|
||||
MTP_flags(0),
|
||||
MTP_inputChannelEmpty())
|
||||
).done([=](const MTPmessages_Chats &result) {
|
||||
_recommendations.requestId = 0;
|
||||
auto parsed = ParseSimilar(_session, result);
|
||||
_recommendations.channels = std::move(parsed);
|
||||
_recommendations.channels.more = 0;
|
||||
_recommendationsLoaded = true;
|
||||
}).send();
|
||||
}
|
||||
|
||||
const ChatParticipants::Channels &ChatParticipants::recommendations() const {
|
||||
return _recommendations.channels;
|
||||
}
|
||||
|
||||
rpl::producer<> ChatParticipants::recommendationsLoaded() const {
|
||||
return _recommendationsLoaded.changes() | rpl::to_empty;
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -14,6 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
class ApiWrap;
|
||||
class ChannelData;
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Ui {
|
||||
class Show;
|
||||
} // namespace Ui
|
||||
@@ -96,6 +100,13 @@ public:
|
||||
static Parsed ParseRecent(
|
||||
not_null<ChannelData*> channel,
|
||||
const TLMembers &data);
|
||||
static void Restrict(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<PeerData*> participant,
|
||||
ChatRestrictionsInfo oldRights,
|
||||
ChatRestrictionsInfo newRights,
|
||||
Fn<void()> onDone,
|
||||
Fn<void()> onFail);
|
||||
void add(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
@@ -134,12 +145,18 @@ public:
|
||||
[[nodiscard]] auto similarLoaded() const
|
||||
-> rpl::producer<not_null<ChannelData*>>;
|
||||
|
||||
void loadRecommendations();
|
||||
[[nodiscard]] const Channels &recommendations() const;
|
||||
[[nodiscard]] rpl::producer<> recommendationsLoaded() const;
|
||||
|
||||
private:
|
||||
struct SimilarChannels {
|
||||
Channels channels;
|
||||
mtpRequestId requestId = 0;
|
||||
};
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
|
||||
MTP::Sender _api;
|
||||
|
||||
using PeerRequests = base::flat_map<PeerData*, mtpRequestId>;
|
||||
@@ -165,6 +182,9 @@ private:
|
||||
base::flat_map<not_null<ChannelData*>, SimilarChannels> _similar;
|
||||
rpl::event_stream<not_null<ChannelData*>> _similarLoaded;
|
||||
|
||||
SimilarChannels _recommendations;
|
||||
rpl::variable<bool> _recommendationsLoaded = false;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -20,13 +20,20 @@ namespace Api {
|
||||
inline constexpr auto kScheduledUntilOnlineTimestamp = TimeId(0x7FFFFFFE);
|
||||
|
||||
struct SendOptions {
|
||||
uint64 price = 0;
|
||||
PeerData *sendAs = nullptr;
|
||||
TimeId scheduled = 0;
|
||||
BusinessShortcutId shortcutId = 0;
|
||||
EffectId effectId = 0;
|
||||
bool silent = false;
|
||||
bool handleSupportSwitch = false;
|
||||
bool invertCaption = false;
|
||||
bool hideViaBot = false;
|
||||
crl::time ttlSeconds = 0;
|
||||
|
||||
friend inline bool operator==(
|
||||
const SendOptions &,
|
||||
const SendOptions &) = default;
|
||||
};
|
||||
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();
|
||||
|
||||
@@ -49,6 +56,10 @@ struct SendAction {
|
||||
MsgId replaceMediaOf = 0;
|
||||
|
||||
[[nodiscard]] MTPInputReplyTo mtpReplyTo() const;
|
||||
|
||||
friend inline bool operator==(
|
||||
const SendAction &,
|
||||
const SendAction &) = default;
|
||||
};
|
||||
|
||||
struct MessageToSend {
|
||||
|
||||
@@ -62,6 +62,10 @@ void ConfirmPhone::resolve(
|
||||
return bad("FirebaseSms");
|
||||
}, [&](const MTPDauth_sentCodeTypeEmailCode &) {
|
||||
return bad("EmailCode");
|
||||
}, [&](const MTPDauth_sentCodeTypeSmsWord &) {
|
||||
return bad("SmsWord");
|
||||
}, [&](const MTPDauth_sentCodeTypeSmsPhrase &) {
|
||||
return bad("SmsPhrase");
|
||||
}, [&](const MTPDauth_sentCodeTypeSetUpEmailRequired &) {
|
||||
return bad("SetUpEmailRequired");
|
||||
});
|
||||
@@ -93,8 +97,10 @@ void ConfirmPhone::resolve(
|
||||
box->resendRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
_api.request(MTPauth_ResendCode(
|
||||
MTP_flags(0),
|
||||
MTP_string(phone),
|
||||
MTP_string(phoneHash)
|
||||
MTP_string(phoneHash),
|
||||
MTPstring() // reason
|
||||
)).done([=] {
|
||||
if (boxWeak) {
|
||||
boxWeak->callDone();
|
||||
|
||||
306
Telegram/SourceFiles/api/api_credits.cpp
Normal file
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
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 "api/api_credits.h"
|
||||
|
||||
#include "api/api_statistics_data_deserialize.h"
|
||||
#include "api/api_updates.h"
|
||||
#include "apiwrap.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "main/main_app_config.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
namespace Api {
|
||||
namespace {
|
||||
|
||||
constexpr auto kTransactionsLimit = 100;
|
||||
|
||||
[[nodiscard]] Data::CreditsHistoryEntry HistoryFromTL(
|
||||
const MTPStarsTransaction &tl,
|
||||
not_null<PeerData*> peer) {
|
||||
using HistoryPeerTL = MTPDstarsTransactionPeer;
|
||||
using namespace Data;
|
||||
const auto owner = &peer->owner();
|
||||
const auto photo = tl.data().vphoto()
|
||||
? owner->photoFromWeb(*tl.data().vphoto(), ImageLocation())
|
||||
: nullptr;
|
||||
auto extended = std::vector<CreditsHistoryMedia>();
|
||||
if (const auto list = tl.data().vextended_media()) {
|
||||
extended.reserve(list->v.size());
|
||||
for (const auto &media : list->v) {
|
||||
media.match([&](const MTPDmessageMediaPhoto &photo) {
|
||||
if (const auto inner = photo.vphoto()) {
|
||||
const auto photo = owner->processPhoto(*inner);
|
||||
if (!photo->isNull()) {
|
||||
extended.push_back(CreditsHistoryMedia{
|
||||
.type = CreditsHistoryMediaType::Photo,
|
||||
.id = photo->id,
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [&](const MTPDmessageMediaDocument &document) {
|
||||
if (const auto inner = document.vdocument()) {
|
||||
const auto document = owner->processDocument(*inner);
|
||||
if (document->isAnimation()
|
||||
|| document->isVideoFile()
|
||||
|| document->isGifv()) {
|
||||
extended.push_back(CreditsHistoryMedia{
|
||||
.type = CreditsHistoryMediaType::Video,
|
||||
.id = document->id,
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [&](const auto &) {});
|
||||
}
|
||||
}
|
||||
const auto barePeerId = tl.data().vpeer().match([](
|
||||
const HistoryPeerTL &p) {
|
||||
return peerFromMTP(p.vpeer());
|
||||
}, [](const auto &) {
|
||||
return PeerId(0);
|
||||
}).value;
|
||||
return Data::CreditsHistoryEntry{
|
||||
.id = qs(tl.data().vid()),
|
||||
.title = qs(tl.data().vtitle().value_or_empty()),
|
||||
.description = qs(tl.data().vdescription().value_or_empty()),
|
||||
.date = base::unixtime::parse(tl.data().vdate().v),
|
||||
.photoId = photo ? photo->id : 0,
|
||||
.extended = std::move(extended),
|
||||
.credits = tl.data().vstars().v,
|
||||
.bareMsgId = uint64(tl.data().vmsg_id().value_or_empty()),
|
||||
.barePeerId = barePeerId,
|
||||
.peerType = tl.data().vpeer().match([](const HistoryPeerTL &) {
|
||||
return Data::CreditsHistoryEntry::PeerType::Peer;
|
||||
}, [](const MTPDstarsTransactionPeerPlayMarket &) {
|
||||
return Data::CreditsHistoryEntry::PeerType::PlayMarket;
|
||||
}, [](const MTPDstarsTransactionPeerFragment &) {
|
||||
return Data::CreditsHistoryEntry::PeerType::Fragment;
|
||||
}, [](const MTPDstarsTransactionPeerAppStore &) {
|
||||
return Data::CreditsHistoryEntry::PeerType::AppStore;
|
||||
}, [](const MTPDstarsTransactionPeerUnsupported &) {
|
||||
return Data::CreditsHistoryEntry::PeerType::Unsupported;
|
||||
}, [](const MTPDstarsTransactionPeerPremiumBot &) {
|
||||
return Data::CreditsHistoryEntry::PeerType::PremiumBot;
|
||||
}, [](const MTPDstarsTransactionPeerAds &) {
|
||||
return Data::CreditsHistoryEntry::PeerType::Ads;
|
||||
}),
|
||||
.refunded = tl.data().is_refund(),
|
||||
.pending = tl.data().is_pending(),
|
||||
.failed = tl.data().is_failed(),
|
||||
.successDate = tl.data().vtransaction_date()
|
||||
? base::unixtime::parse(tl.data().vtransaction_date()->v)
|
||||
: QDateTime(),
|
||||
.successLink = qs(tl.data().vtransaction_url().value_or_empty()),
|
||||
.in = (int64(tl.data().vstars().v) >= 0),
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] Data::CreditsStatusSlice StatusFromTL(
|
||||
const MTPpayments_StarsStatus &status,
|
||||
not_null<PeerData*> peer) {
|
||||
peer->owner().processUsers(status.data().vusers());
|
||||
peer->owner().processChats(status.data().vchats());
|
||||
return Data::CreditsStatusSlice{
|
||||
.list = ranges::views::all(
|
||||
status.data().vhistory().v
|
||||
) | ranges::views::transform([&](const MTPStarsTransaction &tl) {
|
||||
return HistoryFromTL(tl, peer);
|
||||
}) | ranges::to_vector,
|
||||
.balance = status.data().vbalance().v,
|
||||
.allLoaded = !status.data().vnext_offset().has_value(),
|
||||
.token = qs(status.data().vnext_offset().value_or_empty()),
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CreditsTopupOptions::CreditsTopupOptions(not_null<PeerData*> peer)
|
||||
: _peer(peer)
|
||||
, _api(&peer->session().api().instance()) {
|
||||
}
|
||||
|
||||
rpl::producer<rpl::no_value, QString> CreditsTopupOptions::request() {
|
||||
return [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
|
||||
using TLOption = MTPStarsTopupOption;
|
||||
_api.request(MTPpayments_GetStarsTopupOptions(
|
||||
)).done([=](const MTPVector<TLOption> &result) {
|
||||
_options = ranges::views::all(
|
||||
result.v
|
||||
) | ranges::views::transform([](const TLOption &option) {
|
||||
return Data::CreditTopupOption{
|
||||
.credits = option.data().vstars().v,
|
||||
.product = qs(
|
||||
option.data().vstore_product().value_or_empty()),
|
||||
.currency = qs(option.data().vcurrency()),
|
||||
.amount = option.data().vamount().v,
|
||||
.extended = option.data().is_extended(),
|
||||
};
|
||||
}) | ranges::to_vector;
|
||||
consumer.put_done();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
consumer.put_error_copy(error.type());
|
||||
}).send();
|
||||
|
||||
return lifetime;
|
||||
};
|
||||
}
|
||||
|
||||
CreditsStatus::CreditsStatus(not_null<PeerData*> peer)
|
||||
: _peer(peer)
|
||||
, _api(&peer->session().api().instance()) {
|
||||
}
|
||||
|
||||
void CreditsStatus::request(
|
||||
const Data::CreditsStatusSlice::OffsetToken &token,
|
||||
Fn<void(Data::CreditsStatusSlice)> done) {
|
||||
if (_requestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
using TLResult = MTPpayments_StarsStatus;
|
||||
|
||||
_requestId = _api.request(MTPpayments_GetStarsStatus(
|
||||
_peer->isSelf() ? MTP_inputPeerSelf() : _peer->input
|
||||
)).done([=](const TLResult &result) {
|
||||
_requestId = 0;
|
||||
done(StatusFromTL(result, _peer));
|
||||
}).fail([=] {
|
||||
_requestId = 0;
|
||||
done({});
|
||||
}).send();
|
||||
}
|
||||
|
||||
CreditsHistory::CreditsHistory(not_null<PeerData*> peer, bool in, bool out)
|
||||
: _peer(peer)
|
||||
, _flags((in == out)
|
||||
? HistoryTL::Flags(0)
|
||||
: HistoryTL::Flags(0)
|
||||
| (in ? HistoryTL::Flag::f_inbound : HistoryTL::Flags(0))
|
||||
| (out ? HistoryTL::Flag::f_outbound : HistoryTL::Flags(0)))
|
||||
, _api(&peer->session().api().instance()) {
|
||||
}
|
||||
|
||||
void CreditsHistory::request(
|
||||
const Data::CreditsStatusSlice::OffsetToken &token,
|
||||
Fn<void(Data::CreditsStatusSlice)> done) {
|
||||
if (_requestId) {
|
||||
return;
|
||||
}
|
||||
_requestId = _api.request(MTPpayments_GetStarsTransactions(
|
||||
MTP_flags(_flags),
|
||||
_peer->isSelf() ? MTP_inputPeerSelf() : _peer->input,
|
||||
MTP_string(token),
|
||||
MTP_int(kTransactionsLimit)
|
||||
)).done([=](const MTPpayments_StarsStatus &result) {
|
||||
_requestId = 0;
|
||||
done(StatusFromTL(result, _peer));
|
||||
}).fail([=] {
|
||||
_requestId = 0;
|
||||
done({});
|
||||
}).send();
|
||||
}
|
||||
|
||||
Data::CreditTopupOptions CreditsTopupOptions::options() const {
|
||||
return _options;
|
||||
}
|
||||
|
||||
rpl::producer<not_null<PeerData*>> PremiumPeerBot(
|
||||
not_null<Main::Session*> session) {
|
||||
const auto username = session->appConfig().get<QString>(
|
||||
u"premium_bot_username"_q,
|
||||
QString());
|
||||
if (username.isEmpty()) {
|
||||
return rpl::never<not_null<PeerData*>>();
|
||||
}
|
||||
if (const auto p = session->data().peerByUsername(username)) {
|
||||
return rpl::single<not_null<PeerData*>>(p);
|
||||
}
|
||||
return [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
|
||||
const auto api = lifetime.make_state<MTP::Sender>(&session->mtp());
|
||||
|
||||
api->request(MTPcontacts_ResolveUsername(
|
||||
MTP_string(username)
|
||||
)).done([=](const MTPcontacts_ResolvedPeer &result) {
|
||||
session->data().processUsers(result.data().vusers());
|
||||
session->data().processChats(result.data().vchats());
|
||||
const auto botPeer = session->data().peerLoaded(
|
||||
peerFromMTP(result.data().vpeer()));
|
||||
if (!botPeer) {
|
||||
return consumer.put_done();
|
||||
}
|
||||
consumer.put_next(not_null{ botPeer });
|
||||
}).send();
|
||||
|
||||
return lifetime;
|
||||
};
|
||||
}
|
||||
|
||||
CreditsEarnStatistics::CreditsEarnStatistics(not_null<PeerData*> peer)
|
||||
: StatisticsRequestSender(peer)
|
||||
, _isUser(peer->isUser()) {
|
||||
}
|
||||
|
||||
rpl::producer<rpl::no_value, QString> CreditsEarnStatistics::request() {
|
||||
return [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
|
||||
const auto finish = [=](const QString &url) {
|
||||
makeRequest(MTPpayments_GetStarsRevenueStats(
|
||||
MTP_flags(0),
|
||||
(_isUser ? user()->input : channel()->input)
|
||||
)).done([=](const MTPpayments_StarsRevenueStats &result) {
|
||||
const auto &data = result.data();
|
||||
const auto &status = data.vstatus().data();
|
||||
_data = Data::CreditsEarnStatistics{
|
||||
.revenueGraph = StatisticalGraphFromTL(
|
||||
data.vrevenue_graph()),
|
||||
.currentBalance = status.vcurrent_balance().v,
|
||||
.availableBalance = status.vavailable_balance().v,
|
||||
.overallRevenue = status.voverall_revenue().v,
|
||||
.usdRate = data.vusd_rate().v,
|
||||
.isWithdrawalEnabled = status.is_withdrawal_enabled(),
|
||||
.nextWithdrawalAt = status.vnext_withdrawal_at()
|
||||
? base::unixtime::parse(
|
||||
status.vnext_withdrawal_at()->v)
|
||||
: QDateTime(),
|
||||
.buyAdsUrl = url,
|
||||
};
|
||||
|
||||
consumer.put_done();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
consumer.put_error_copy(error.type());
|
||||
}).send();
|
||||
};
|
||||
|
||||
makeRequest(
|
||||
MTPpayments_GetStarsRevenueAdsAccountUrl(
|
||||
(_isUser ? user()->input : channel()->input))
|
||||
).done([=](const MTPpayments_StarsRevenueAdsAccountUrl &result) {
|
||||
finish(qs(result.data().vurl()));
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
finish({});
|
||||
}).send();
|
||||
|
||||
return lifetime;
|
||||
};
|
||||
}
|
||||
|
||||
Data::CreditsEarnStatistics CreditsEarnStatistics::data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
93
Telegram/SourceFiles/api/api_credits.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
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 "api/api_statistics_sender.h"
|
||||
#include "data/data_credits.h"
|
||||
#include "data/data_credits_earn.h"
|
||||
#include "mtproto/sender.h"
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
class UserData;
|
||||
|
||||
namespace Api {
|
||||
|
||||
class CreditsTopupOptions final {
|
||||
public:
|
||||
CreditsTopupOptions(not_null<PeerData*> peer);
|
||||
|
||||
[[nodiscard]] rpl::producer<rpl::no_value, QString> request();
|
||||
[[nodiscard]] Data::CreditTopupOptions options() const;
|
||||
|
||||
private:
|
||||
const not_null<PeerData*> _peer;
|
||||
|
||||
Data::CreditTopupOptions _options;
|
||||
|
||||
MTP::Sender _api;
|
||||
|
||||
};
|
||||
|
||||
class CreditsStatus final {
|
||||
public:
|
||||
CreditsStatus(not_null<PeerData*> peer);
|
||||
|
||||
void request(
|
||||
const Data::CreditsStatusSlice::OffsetToken &token,
|
||||
Fn<void(Data::CreditsStatusSlice)> done);
|
||||
|
||||
private:
|
||||
const not_null<PeerData*> _peer;
|
||||
|
||||
mtpRequestId _requestId = 0;
|
||||
|
||||
MTP::Sender _api;
|
||||
|
||||
};
|
||||
|
||||
class CreditsHistory final {
|
||||
public:
|
||||
CreditsHistory(not_null<PeerData*> peer, bool in, bool out);
|
||||
|
||||
void request(
|
||||
const Data::CreditsStatusSlice::OffsetToken &token,
|
||||
Fn<void(Data::CreditsStatusSlice)> done);
|
||||
|
||||
private:
|
||||
using HistoryTL = MTPpayments_GetStarsTransactions;
|
||||
const not_null<PeerData*> _peer;
|
||||
const HistoryTL::Flags _flags;
|
||||
|
||||
mtpRequestId _requestId = 0;
|
||||
|
||||
MTP::Sender _api;
|
||||
|
||||
};
|
||||
|
||||
class CreditsEarnStatistics final : public StatisticsRequestSender {
|
||||
public:
|
||||
explicit CreditsEarnStatistics(not_null<PeerData*>);
|
||||
|
||||
[[nodiscard]] rpl::producer<rpl::no_value, QString> request();
|
||||
[[nodiscard]] Data::CreditsEarnStatistics data() const;
|
||||
|
||||
private:
|
||||
Data::CreditsEarnStatistics _data;
|
||||
bool _isUser = false;
|
||||
|
||||
mtpRequestId _requestId = 0;
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]] rpl::producer<not_null<PeerData*>> PremiumPeerBot(
|
||||
not_null<Main::Session*> session);
|
||||
|
||||
} // namespace Api
|
||||
@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "api/api_cloud_password.h"
|
||||
#include "apiwrap.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "boxes/passcode_box.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_session.h"
|
||||
@@ -34,22 +35,33 @@ void RestrictSponsored(
|
||||
}
|
||||
|
||||
void HandleWithdrawalButton(
|
||||
not_null<ChannelData*> channel,
|
||||
RewardReceiver receiver,
|
||||
not_null<Ui::RippleButton*> button,
|
||||
std::shared_ptr<Ui::Show> show) {
|
||||
Expects(receiver.currencyReceiver
|
||||
|| (receiver.creditsReceiver && receiver.creditsAmount));
|
||||
struct State {
|
||||
rpl::lifetime lifetime;
|
||||
bool loading = false;
|
||||
};
|
||||
|
||||
const auto channel = receiver.currencyReceiver;
|
||||
const auto peer = receiver.creditsReceiver;
|
||||
|
||||
const auto state = button->lifetime().make_state<State>();
|
||||
const auto session = &channel->session();
|
||||
const auto session = (channel ? &channel->session() : &peer->session());
|
||||
|
||||
using ChannelOutUrl = MTPstats_BroadcastRevenueWithdrawalUrl;
|
||||
using CreditsOutUrl = MTPpayments_StarsRevenueWithdrawalUrl;
|
||||
|
||||
session->api().cloudPassword().reload();
|
||||
button->setClickedCallback([=] {
|
||||
const auto processOut = [=] {
|
||||
if (state->loading) {
|
||||
return;
|
||||
}
|
||||
if (peer && !receiver.creditsAmount()) {
|
||||
return;
|
||||
}
|
||||
state->loading = true;
|
||||
state->lifetime = session->api().cloudPassword().state(
|
||||
) | rpl::take(
|
||||
@@ -58,30 +70,81 @@ void HandleWithdrawalButton(
|
||||
state->loading = false;
|
||||
|
||||
auto fields = PasscodeBox::CloudFields::From(pass);
|
||||
fields.customTitle =
|
||||
tr::lng_channel_earn_balance_password_title();
|
||||
fields.customDescription =
|
||||
tr::lng_channel_earn_balance_password_description(tr::now);
|
||||
fields.customTitle = channel
|
||||
? tr::lng_channel_earn_balance_password_title()
|
||||
: tr::lng_bot_earn_balance_password_title();
|
||||
fields.customDescription = channel
|
||||
? tr::lng_channel_earn_balance_password_description(tr::now)
|
||||
: tr::lng_bot_earn_balance_password_description(tr::now);
|
||||
fields.customSubmitButton = tr::lng_passcode_submit();
|
||||
fields.customCheckCallback = crl::guard(button, [=](
|
||||
const Core::CloudPasswordResult &result) {
|
||||
session->api().request(
|
||||
MTPstats_GetBroadcastRevenueWithdrawalUrl(
|
||||
channel->inputChannel,
|
||||
result.result
|
||||
)).done([=](const MTPstats_BroadcastRevenueWithdrawalUrl &r) {
|
||||
const auto url = qs(r.data().vurl());
|
||||
|
||||
if (!url.isEmpty()) {
|
||||
UrlClickHandler::Open(url);
|
||||
const Core::CloudPasswordResult &result,
|
||||
QPointer<PasscodeBox> box) {
|
||||
const auto done = [=](const QString &result) {
|
||||
if (!result.isEmpty()) {
|
||||
UrlClickHandler::Open(result);
|
||||
if (box) {
|
||||
box->closeBox();
|
||||
}
|
||||
}
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
};
|
||||
const auto fail = [=](const MTP::Error &error) {
|
||||
show->showToast(error.type());
|
||||
}).send();
|
||||
};
|
||||
if (channel) {
|
||||
session->api().request(
|
||||
MTPstats_GetBroadcastRevenueWithdrawalUrl(
|
||||
channel->inputChannel,
|
||||
result.result
|
||||
)).done([=](const ChannelOutUrl &r) {
|
||||
done(qs(r.data().vurl()));
|
||||
}).fail(fail).send();
|
||||
} else if (peer) {
|
||||
session->api().request(
|
||||
MTPpayments_GetStarsRevenueWithdrawalUrl(
|
||||
peer->input,
|
||||
MTP_long(receiver.creditsAmount()),
|
||||
result.result
|
||||
)).done([=](const CreditsOutUrl &r) {
|
||||
done(qs(r.data().vurl()));
|
||||
}).fail(fail).send();
|
||||
}
|
||||
});
|
||||
show->show(Box<PasscodeBox>(session, fields));
|
||||
});
|
||||
|
||||
};
|
||||
button->setClickedCallback([=] {
|
||||
if (state->loading) {
|
||||
return;
|
||||
}
|
||||
const auto fail = [=](const MTP::Error &error) {
|
||||
auto box = PrePasswordErrorBox(
|
||||
error.type(),
|
||||
session,
|
||||
TextWithEntities{
|
||||
tr::lng_channel_earn_out_check_password_about(tr::now),
|
||||
});
|
||||
if (box) {
|
||||
show->show(std::move(box));
|
||||
state->loading = false;
|
||||
} else {
|
||||
processOut();
|
||||
}
|
||||
};
|
||||
if (channel) {
|
||||
session->api().request(
|
||||
MTPstats_GetBroadcastRevenueWithdrawalUrl(
|
||||
channel->inputChannel,
|
||||
MTP_inputCheckPasswordEmpty()
|
||||
)).fail(fail).send();
|
||||
} else if (peer) {
|
||||
session->api().request(
|
||||
MTPpayments_GetStarsRevenueWithdrawalUrl(
|
||||
peer->input,
|
||||
MTP_long(std::numeric_limits<int64_t>::max()),
|
||||
MTP_inputCheckPasswordEmpty()
|
||||
)).fail(fail).send();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,14 @@ void RestrictSponsored(
|
||||
bool restricted,
|
||||
Fn<void(QString)> failed);
|
||||
|
||||
struct RewardReceiver final {
|
||||
ChannelData *currencyReceiver = nullptr;
|
||||
PeerData *creditsReceiver = nullptr;
|
||||
Fn<uint64()> creditsAmount;
|
||||
};
|
||||
|
||||
void HandleWithdrawalButton(
|
||||
not_null<ChannelData*> channel,
|
||||
RewardReceiver receiver,
|
||||
not_null<Ui::RippleButton*> button,
|
||||
std::shared_ptr<Ui::Show> show);
|
||||
|
||||
|
||||
@@ -12,12 +12,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_text_entities.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "data/business/data_shortcut_messages.h"
|
||||
#include "data/components/scheduled_messages.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_scheduled_messages.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_web_page.h"
|
||||
#include "history/view/controls/history_view_compose_media_edit_manager.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "mtproto/mtproto_response.h"
|
||||
@@ -29,20 +30,20 @@ namespace {
|
||||
using namespace rpl::details;
|
||||
|
||||
template <typename T>
|
||||
constexpr auto WithId =
|
||||
is_callable_plain_v<T, Fn<void()>, mtpRequestId>;
|
||||
constexpr auto WithId
|
||||
= is_callable_plain_v<T, Fn<void()>, mtpRequestId>;
|
||||
template <typename T>
|
||||
constexpr auto WithoutId =
|
||||
is_callable_plain_v<T, Fn<void()>>;
|
||||
constexpr auto WithoutId
|
||||
= is_callable_plain_v<T, Fn<void()>>;
|
||||
template <typename T>
|
||||
constexpr auto WithoutCallback =
|
||||
is_callable_plain_v<T>;
|
||||
constexpr auto WithoutCallback
|
||||
= is_callable_plain_v<T>;
|
||||
template <typename T>
|
||||
constexpr auto ErrorWithId =
|
||||
is_callable_plain_v<T, QString, mtpRequestId>;
|
||||
constexpr auto ErrorWithId
|
||||
= is_callable_plain_v<T, QString, mtpRequestId>;
|
||||
template <typename T>
|
||||
constexpr auto ErrorWithoutId =
|
||||
is_callable_plain_v<T, QString>;
|
||||
constexpr auto ErrorWithoutId
|
||||
= is_callable_plain_v<T, QString>;
|
||||
|
||||
template <typename DoneCallback, typename FailCallback>
|
||||
mtpRequestId EditMessage(
|
||||
@@ -81,7 +82,8 @@ mtpRequestId EditMessage(
|
||||
| ((!webpage.removed && !webpage.url.isEmpty())
|
||||
? MTPmessages_EditMessage::Flag::f_media
|
||||
: emptyFlag)
|
||||
| ((!webpage.removed && !webpage.url.isEmpty() && webpage.invert)
|
||||
| (((!webpage.removed && !webpage.url.isEmpty() && webpage.invert)
|
||||
|| options.invertCaption)
|
||||
? MTPmessages_EditMessage::Flag::f_invert_media
|
||||
: emptyFlag)
|
||||
| (!sentEntities.v.isEmpty()
|
||||
@@ -95,7 +97,7 @@ mtpRequestId EditMessage(
|
||||
: emptyFlag);
|
||||
|
||||
const auto id = item->isScheduled()
|
||||
? session->data().scheduledMessages().lookupId(item)
|
||||
? session->scheduledMessages().lookupId(item)
|
||||
: item->isBusinessShortcut()
|
||||
? session->data().shortcutMessages().lookupId(item)
|
||||
: item->id;
|
||||
@@ -151,9 +153,7 @@ mtpRequestId EditMessage(
|
||||
const auto &text = item->originalText();
|
||||
const auto webpage = (!item->media() || !item->media()->webpage())
|
||||
? Data::WebPageDraft{ .removed = true }
|
||||
: Data::WebPageDraft{
|
||||
.id = item->media()->webpage()->id,
|
||||
};
|
||||
: Data::WebPageDraft::FromItem(item);
|
||||
return EditMessage(
|
||||
item,
|
||||
text,
|
||||
@@ -203,6 +203,7 @@ void RescheduleMessage(
|
||||
not_null<HistoryItem*> item,
|
||||
SendOptions options) {
|
||||
const auto empty = [] {};
|
||||
options.invertCaption = item->invertMedia();
|
||||
EditMessage(item, options, empty, empty);
|
||||
}
|
||||
|
||||
@@ -253,12 +254,100 @@ mtpRequestId EditTextMessage(
|
||||
Data::WebPageDraft webpage,
|
||||
SendOptions options,
|
||||
Fn<void(mtpRequestId requestId)> done,
|
||||
Fn<void(const QString &, mtpRequestId requestId)> fail) {
|
||||
Fn<void(const QString &error, mtpRequestId requestId)> fail,
|
||||
bool spoilered) {
|
||||
const auto media = item->media();
|
||||
if (media
|
||||
&& HistoryView::MediaEditManager::CanBeSpoilered(item)
|
||||
&& spoilered != media->hasSpoiler()) {
|
||||
auto takeInputMedia = Fn<std::optional<MTPInputMedia>()>(nullptr);
|
||||
auto takeFileReference = Fn<QByteArray()>(nullptr);
|
||||
if (const auto photo = media->photo()) {
|
||||
using Flag = MTPDinputMediaPhoto::Flag;
|
||||
const auto flags = Flag()
|
||||
| (media->ttlSeconds() ? Flag::f_ttl_seconds : Flag())
|
||||
| (spoilered ? Flag::f_spoiler : Flag());
|
||||
takeInputMedia = [=] {
|
||||
return MTP_inputMediaPhoto(
|
||||
MTP_flags(flags),
|
||||
photo->mtpInput(),
|
||||
MTP_int(media->ttlSeconds()));
|
||||
};
|
||||
takeFileReference = [=] { return photo->fileReference(); };
|
||||
} else if (const auto document = media->document()) {
|
||||
using Flag = MTPDinputMediaDocument::Flag;
|
||||
const auto flags = Flag()
|
||||
| (media->ttlSeconds() ? Flag::f_ttl_seconds : Flag())
|
||||
| (spoilered ? Flag::f_spoiler : Flag());
|
||||
takeInputMedia = [=] {
|
||||
return MTP_inputMediaDocument(
|
||||
MTP_flags(flags),
|
||||
document->mtpInput(),
|
||||
MTP_int(media->ttlSeconds()),
|
||||
MTPstring()); // query
|
||||
};
|
||||
takeFileReference = [=] { return document->fileReference(); };
|
||||
}
|
||||
|
||||
const auto usedFileReference = takeFileReference
|
||||
? takeFileReference()
|
||||
: QByteArray();
|
||||
const auto origin = item->fullId();
|
||||
const auto api = &item->history()->session().api();
|
||||
const auto performRequest = [=](
|
||||
const auto &repeatRequest,
|
||||
mtpRequestId originalRequestId) -> mtpRequestId {
|
||||
const auto handleReference = [=](
|
||||
const QString &error,
|
||||
mtpRequestId requestId) {
|
||||
if (error.startsWith(u"FILE_REFERENCE_"_q)) {
|
||||
api->refreshFileReference(origin, [=](const auto &) {
|
||||
if (takeFileReference &&
|
||||
(takeFileReference() != usedFileReference)) {
|
||||
repeatRequest(
|
||||
repeatRequest,
|
||||
originalRequestId
|
||||
? originalRequestId
|
||||
: requestId);
|
||||
} else {
|
||||
fail(error, requestId);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fail(error, requestId);
|
||||
}
|
||||
};
|
||||
const auto callback = [=](
|
||||
Fn<void()> applyUpdates,
|
||||
mtpRequestId requestId) {
|
||||
applyUpdates();
|
||||
done(originalRequestId ? originalRequestId : requestId);
|
||||
};
|
||||
const auto requestId = EditMessage(
|
||||
item,
|
||||
caption,
|
||||
webpage,
|
||||
options,
|
||||
callback,
|
||||
handleReference,
|
||||
takeInputMedia ? takeInputMedia() : std::nullopt);
|
||||
return originalRequestId ? originalRequestId : requestId;
|
||||
};
|
||||
return performRequest(performRequest, 0);
|
||||
}
|
||||
|
||||
const auto callback = [=](Fn<void()> applyUpdates, mtpRequestId id) {
|
||||
applyUpdates();
|
||||
done(id);
|
||||
};
|
||||
return EditMessage(item, caption, webpage, options, callback, fail);
|
||||
return EditMessage(
|
||||
item,
|
||||
caption,
|
||||
webpage,
|
||||
options,
|
||||
callback,
|
||||
fail,
|
||||
std::nullopt);
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -55,6 +55,7 @@ mtpRequestId EditTextMessage(
|
||||
Data::WebPageDraft webpage,
|
||||
SendOptions options,
|
||||
Fn<void(mtpRequestId requestId)> done,
|
||||
Fn<void(const QString &error, mtpRequestId requestId)> fail);
|
||||
Fn<void(const QString &error, mtpRequestId requestId)> fail,
|
||||
bool spoilered);
|
||||
|
||||
} // namespace Api
|
||||
|
||||
27
Telegram/SourceFiles/api/api_filter_updates.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
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 Api {
|
||||
|
||||
template <typename Type>
|
||||
void PerformForUpdate(
|
||||
const MTPUpdates &updates,
|
||||
Fn<void(const Type &)> callback) {
|
||||
updates.match([&](const MTPDupdates &updates) {
|
||||
for (const auto &update : updates.vupdates().v) {
|
||||
update.match([&](const Type &d) {
|
||||
callback(d);
|
||||
}, [](const auto &) {
|
||||
});
|
||||
}
|
||||
}, [](const auto &) {
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
@@ -34,7 +34,7 @@ namespace {
|
||||
|
||||
constexpr auto kSharedMediaLimit = 100;
|
||||
|
||||
[[nodiscard]] SendMediaReady PreparePeerPhoto(
|
||||
[[nodiscard]] std::shared_ptr<FilePrepareResult> PreparePeerPhoto(
|
||||
MTP::DcId dcId,
|
||||
PeerId peerId,
|
||||
QImage &&image) {
|
||||
@@ -80,24 +80,17 @@ constexpr auto kSharedMediaLimit = 100;
|
||||
MTPVector<MTPVideoSize>(),
|
||||
MTP_int(dcId));
|
||||
|
||||
QString file, filename;
|
||||
int64 filesize = 0;
|
||||
QByteArray data;
|
||||
|
||||
return SendMediaReady(
|
||||
SendMediaType::Photo,
|
||||
file,
|
||||
filename,
|
||||
filesize,
|
||||
data,
|
||||
id,
|
||||
id,
|
||||
u"jpg"_q,
|
||||
peerId,
|
||||
photo,
|
||||
photoThumbs,
|
||||
MTP_documentEmpty(MTP_long(0)),
|
||||
jpeg);
|
||||
auto result = MakePreparedFile({
|
||||
.id = id,
|
||||
.type = SendMediaType::Photo,
|
||||
});
|
||||
result->type = SendMediaType::Photo;
|
||||
result->setFileData(jpeg);
|
||||
result->thumbId = id;
|
||||
result->thumbname = "thumb.jpg";
|
||||
result->photo = photo;
|
||||
result->photoThumbs = photoThumbs;
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<MTPVideoSize> PrepareMtpMarkup(
|
||||
@@ -239,7 +232,7 @@ void PeerPhoto::upload(
|
||||
_api.instance().mainDcId(),
|
||||
peer->id,
|
||||
base::take(photo.image));
|
||||
_session->uploader().uploadMedia(fakeId, ready);
|
||||
_session->uploader().upload(fakeId, ready);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,9 @@ void Polls::create(
|
||||
if (action.options.shortcutId) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
|
||||
}
|
||||
if (action.options.effectId) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||
}
|
||||
const auto sendAs = action.options.sendAs;
|
||||
if (sendAs) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_send_as;
|
||||
@@ -89,7 +92,8 @@ void Polls::create(
|
||||
MTPVector<MTPMessageEntity>(),
|
||||
MTP_int(action.options.scheduled),
|
||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||
Data::ShortcutIdToMTP(_session, action.options.shortcutId)
|
||||
Data::ShortcutIdToMTP(_session, action.options.shortcutId),
|
||||
MTP_long(action.options.effectId)
|
||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||
if (clearCloudDraft) {
|
||||
history->finishSavingCloudDraft(
|
||||
|
||||
@@ -602,6 +602,41 @@ bool PremiumGiftCodeOptions::giveawayGiftsPurchaseAvailable() const {
|
||||
false);
|
||||
}
|
||||
|
||||
SponsoredToggle::SponsoredToggle(not_null<Main::Session*> session)
|
||||
: _api(&session->api().instance()) {
|
||||
}
|
||||
|
||||
rpl::producer<bool> SponsoredToggle::toggled() {
|
||||
return [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
|
||||
_api.request(MTPusers_GetFullUser(
|
||||
MTP_inputUserSelf()
|
||||
)).done([=](const MTPusers_UserFull &result) {
|
||||
consumer.put_next_copy(
|
||||
result.data().vfull_user().data().is_sponsored_enabled());
|
||||
}).fail([=] { consumer.put_next(false); }).send();
|
||||
|
||||
return lifetime;
|
||||
};
|
||||
}
|
||||
|
||||
rpl::producer<rpl::no_value, QString> SponsoredToggle::setToggled(bool v) {
|
||||
return [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
|
||||
_api.request(MTPaccount_ToggleSponsoredMessages(
|
||||
MTP_bool(v)
|
||||
)).done([=] {
|
||||
consumer.put_done();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
consumer.put_error_copy(error.type());
|
||||
}).send();
|
||||
|
||||
return lifetime;
|
||||
};
|
||||
}
|
||||
|
||||
RequirePremiumState ResolveRequiresPremiumToWrite(
|
||||
not_null<PeerData*> peer,
|
||||
History *maybeHistory) {
|
||||
|
||||
@@ -216,6 +216,18 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class SponsoredToggle final {
|
||||
public:
|
||||
explicit SponsoredToggle(not_null<Main::Session*> session);
|
||||
|
||||
[[nodiscard]] rpl::producer<bool> toggled();
|
||||
[[nodiscard]] rpl::producer<rpl::no_value, QString> setToggled(bool);
|
||||
|
||||
private:
|
||||
MTP::Sender _api;
|
||||
|
||||
};
|
||||
|
||||
enum class RequirePremiumState {
|
||||
Unknown,
|
||||
Yes,
|
||||
|
||||
@@ -24,16 +24,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
namespace Api {
|
||||
namespace {
|
||||
|
||||
SendMediaReady PrepareRingtoneDocument(
|
||||
std::shared_ptr<FilePrepareResult> PrepareRingtoneDocument(
|
||||
MTP::DcId dcId,
|
||||
const QString &filename,
|
||||
const QString &filemime,
|
||||
const QByteArray &content) {
|
||||
const auto id = base::RandomValue<DocumentId>();
|
||||
auto attributes = QVector<MTPDocumentAttribute>(
|
||||
1,
|
||||
MTP_documentAttributeFilename(MTP_string(filename)));
|
||||
const auto id = base::RandomValue<DocumentId>();
|
||||
const auto document = MTP_document(
|
||||
|
||||
auto result = MakePreparedFile({
|
||||
.id = id,
|
||||
.type = SendMediaType::File,
|
||||
});
|
||||
result->filename = filename;
|
||||
result->content = content;
|
||||
result->filesize = content.size();
|
||||
result->setFileData(content);
|
||||
result->document = MTP_document(
|
||||
MTP_flags(0),
|
||||
MTP_long(id),
|
||||
MTP_long(0),
|
||||
@@ -45,21 +54,7 @@ SendMediaReady PrepareRingtoneDocument(
|
||||
MTPVector<MTPVideoSize>(),
|
||||
MTP_int(dcId),
|
||||
MTP_vector<MTPDocumentAttribute>(std::move(attributes)));
|
||||
|
||||
return SendMediaReady(
|
||||
SendMediaType::File,
|
||||
QString(), // filepath
|
||||
filename,
|
||||
content.size(),
|
||||
content,
|
||||
id,
|
||||
0,
|
||||
QString(),
|
||||
PeerId(),
|
||||
MTP_photoEmpty(MTP_long(0)),
|
||||
PreparedPhotoThumbs(),
|
||||
document,
|
||||
QByteArray());
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -102,7 +97,7 @@ void Ringtones::upload(
|
||||
_uploads.erase(already);
|
||||
}
|
||||
_uploads.emplace(fakeId, uploadedData);
|
||||
_session->uploader().uploadMedia(fakeId, ready);
|
||||
_session->uploader().upload(fakeId, ready);
|
||||
}
|
||||
|
||||
void Ringtones::ready(const FullMsgId &msgId, const MTPInputFile &file) {
|
||||
|
||||
@@ -62,6 +62,79 @@ void InnerFillMessagePostFlags(
|
||||
}
|
||||
}
|
||||
|
||||
void SendSimpleMedia(SendAction action, MTPInputMedia inputMedia) {
|
||||
const auto history = action.history;
|
||||
const auto peer = history->peer;
|
||||
const auto session = &history->session();
|
||||
const auto api = &session->api();
|
||||
|
||||
action.clearDraft = false;
|
||||
action.generateLocal = false;
|
||||
api->sendAction(action);
|
||||
|
||||
const auto randomId = base::RandomValue<uint64>();
|
||||
|
||||
auto flags = NewMessageFlags(peer);
|
||||
auto sendFlags = MTPmessages_SendMedia::Flags(0);
|
||||
if (action.replyTo) {
|
||||
flags |= MessageFlag::HasReplyInfo;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
|
||||
}
|
||||
const auto silentPost = ShouldSendSilent(peer, action.options);
|
||||
InnerFillMessagePostFlags(action.options, peer, flags);
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
|
||||
}
|
||||
const auto sendAs = action.options.sendAs;
|
||||
if (sendAs) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_send_as;
|
||||
}
|
||||
const auto messagePostAuthor = peer->isBroadcast()
|
||||
? session->user()->name()
|
||||
: QString();
|
||||
|
||||
if (action.options.scheduled) {
|
||||
flags |= MessageFlag::IsOrWasScheduled;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
|
||||
}
|
||||
if (action.options.shortcutId) {
|
||||
flags |= MessageFlag::ShortcutMessage;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
|
||||
}
|
||||
if (action.options.effectId) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||
}
|
||||
if (action.options.invertCaption) {
|
||||
flags |= MessageFlag::InvertMedia;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||
}
|
||||
|
||||
auto &histories = history->owner().histories();
|
||||
histories.sendPreparedMessage(
|
||||
history,
|
||||
action.replyTo,
|
||||
randomId,
|
||||
Data::Histories::PrepareMessage<MTPmessages_SendMedia>(
|
||||
MTP_flags(sendFlags),
|
||||
peer->input,
|
||||
Data::Histories::ReplyToPlaceholder(),
|
||||
std::move(inputMedia),
|
||||
MTPstring(),
|
||||
MTP_long(randomId),
|
||||
MTPReplyMarkup(),
|
||||
MTPvector<MTPMessageEntity>(),
|
||||
MTP_int(action.options.scheduled),
|
||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||
Data::ShortcutIdToMTP(session, action.options.shortcutId),
|
||||
MTP_long(action.options.effectId)
|
||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||
api->sendMessageFail(error, peer, randomId);
|
||||
});
|
||||
|
||||
api->finishForwarding(action);
|
||||
}
|
||||
|
||||
template <typename MediaData>
|
||||
void SendExistingMedia(
|
||||
MessageToSend &&message,
|
||||
@@ -133,6 +206,13 @@ void SendExistingMedia(
|
||||
flags |= MessageFlag::ShortcutMessage;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
|
||||
}
|
||||
if (action.options.effectId) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||
}
|
||||
if (action.options.invertCaption) {
|
||||
flags |= MessageFlag::InvertMedia;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||
}
|
||||
|
||||
session->data().registerMessageRandomId(randomId, newId);
|
||||
|
||||
@@ -144,6 +224,7 @@ void SendExistingMedia(
|
||||
.date = HistoryItem::NewMessageDate(action.options),
|
||||
.shortcutId = action.options.shortcutId,
|
||||
.postAuthor = messagePostAuthor,
|
||||
.effectId = action.options.effectId,
|
||||
}, media, caption);
|
||||
|
||||
const auto performRequest = [=](const auto &repeatRequest) -> void {
|
||||
@@ -165,7 +246,8 @@ void SendExistingMedia(
|
||||
sentEntities,
|
||||
MTP_int(action.options.scheduled),
|
||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||
Data::ShortcutIdToMTP(session, action.options.shortcutId)
|
||||
Data::ShortcutIdToMTP(session, action.options.shortcutId),
|
||||
MTP_long(action.options.effectId)
|
||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||
if (error.code() == 400
|
||||
@@ -306,6 +388,13 @@ bool SendDice(MessageToSend &message) {
|
||||
flags |= MessageFlag::ShortcutMessage;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
|
||||
}
|
||||
if (action.options.effectId) {
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||
}
|
||||
if (action.options.invertCaption) {
|
||||
flags |= MessageFlag::InvertMedia;
|
||||
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||
}
|
||||
|
||||
session->data().registerMessageRandomId(randomId, newId);
|
||||
|
||||
@@ -317,6 +406,7 @@ bool SendDice(MessageToSend &message) {
|
||||
.date = HistoryItem::NewMessageDate(action.options),
|
||||
.shortcutId = action.options.shortcutId,
|
||||
.postAuthor = messagePostAuthor,
|
||||
.effectId = action.options.effectId,
|
||||
}, TextWithEntities(), MTP_messageMediaDice(
|
||||
MTP_int(0),
|
||||
MTP_string(emoji)));
|
||||
@@ -335,7 +425,8 @@ bool SendDice(MessageToSend &message) {
|
||||
MTP_vector<MTPMessageEntity>(),
|
||||
MTP_int(action.options.scheduled),
|
||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||
Data::ShortcutIdToMTP(session, action.options.shortcutId)
|
||||
Data::ShortcutIdToMTP(session, action.options.shortcutId),
|
||||
MTP_long(action.options.effectId)
|
||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||
api->sendMessageFail(error, peer, randomId, newId);
|
||||
@@ -344,6 +435,33 @@ bool SendDice(MessageToSend &message) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SendLocation(SendAction action, float64 lat, float64 lon) {
|
||||
SendSimpleMedia(
|
||||
action,
|
||||
MTP_inputMediaGeoPoint(
|
||||
MTP_inputGeoPoint(
|
||||
MTP_flags(0),
|
||||
MTP_double(lat),
|
||||
MTP_double(lon),
|
||||
MTPint()))); // accuracy_radius
|
||||
}
|
||||
|
||||
void SendVenue(SendAction action, Data::InputVenue venue) {
|
||||
SendSimpleMedia(
|
||||
action,
|
||||
MTP_inputMediaVenue(
|
||||
MTP_inputGeoPoint(
|
||||
MTP_flags(0),
|
||||
MTP_double(venue.lat),
|
||||
MTP_double(venue.lon),
|
||||
MTPint()), // accuracy_radius
|
||||
MTP_string(venue.title),
|
||||
MTP_string(venue.address),
|
||||
MTP_string(venue.provider),
|
||||
MTP_string(venue.id),
|
||||
MTP_string(venue.venueType)));
|
||||
}
|
||||
|
||||
void FillMessagePostFlags(
|
||||
const SendAction &action,
|
||||
not_null<PeerData*> peer,
|
||||
@@ -353,7 +471,7 @@ void FillMessagePostFlags(
|
||||
|
||||
void SendConfirmedFile(
|
||||
not_null<Main::Session*> session,
|
||||
const std::shared_ptr<FileLoadResult> &file) {
|
||||
const std::shared_ptr<FilePrepareResult> &file) {
|
||||
const auto isEditing = (file->type != SendMediaType::Audio)
|
||||
&& (file->to.replaceMediaOf != 0);
|
||||
const auto newId = FullMsgId(
|
||||
@@ -430,6 +548,9 @@ void SendConfirmedFile(
|
||||
flags |= MessageFlag::MediaIsUnread;
|
||||
}
|
||||
}
|
||||
if (file->to.options.invertCaption) {
|
||||
flags |= MessageFlag::InvertMedia;
|
||||
}
|
||||
|
||||
const auto messageFromId = file->to.options.sendAs
|
||||
? file->to.options.sendAs->id
|
||||
@@ -493,6 +614,7 @@ void SendConfirmedFile(
|
||||
edition.ttl = 0;
|
||||
edition.mtpMedia = &media;
|
||||
edition.textWithEntities = caption;
|
||||
edition.invertMedia = file->to.options.invertCaption;
|
||||
edition.useSameViews = true;
|
||||
edition.useSameForwards = true;
|
||||
edition.useSameMarkup = true;
|
||||
@@ -510,6 +632,7 @@ void SendConfirmedFile(
|
||||
.shortcutId = file->to.options.shortcutId,
|
||||
.postAuthor = messagePostAuthor,
|
||||
.groupedId = groupId,
|
||||
.effectId = file->to.options.effectId,
|
||||
}, caption, media);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
class History;
|
||||
class PhotoData;
|
||||
class DocumentData;
|
||||
struct FileLoadResult;
|
||||
struct FilePrepareResult;
|
||||
|
||||
namespace Data {
|
||||
struct InputVenue;
|
||||
} // namespace Data
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Api {
|
||||
|
||||
@@ -33,6 +37,13 @@ void SendExistingPhoto(
|
||||
|
||||
bool SendDice(MessageToSend &message);
|
||||
|
||||
// We can't create Data::LocationPoint() and use it
|
||||
// for a local sending message, because we can't request
|
||||
// map thumbnail in messages history without access hash.
|
||||
void SendLocation(SendAction action, float64 lat, float64 lon);
|
||||
|
||||
void SendVenue(SendAction action, Data::InputVenue venue);
|
||||
|
||||
void FillMessagePostFlags(
|
||||
const SendAction &action,
|
||||
not_null<PeerData*> peer,
|
||||
@@ -40,6 +51,6 @@ void FillMessagePostFlags(
|
||||
|
||||
void SendConfirmedFile(
|
||||
not_null<Main::Session*> session,
|
||||
const std::shared_ptr<FileLoadResult> &file);
|
||||
const std::shared_ptr<FilePrepareResult> &file);
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "api/api_statistics.h"
|
||||
|
||||
#include "api/api_statistics_data_deserialize.h"
|
||||
#include "apiwrap.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "data/data_channel.h"
|
||||
@@ -15,33 +16,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_story.h"
|
||||
#include "history/history.h"
|
||||
#include "main/main_session.h"
|
||||
#include "statistics/statistics_data_deserialize.h"
|
||||
|
||||
namespace Api {
|
||||
namespace {
|
||||
|
||||
constexpr auto kCheckRequestsTimer = 10 * crl::time(1000);
|
||||
|
||||
[[nodiscard]] Data::StatisticalGraph StatisticalGraphFromTL(
|
||||
const MTPStatsGraph &tl) {
|
||||
return tl.match([&](const MTPDstatsGraph &d) {
|
||||
using namespace Statistic;
|
||||
const auto zoomToken = d.vzoom_token().has_value()
|
||||
? qs(*d.vzoom_token()).toUtf8()
|
||||
: QByteArray();
|
||||
return Data::StatisticalGraph{
|
||||
StatisticalChartFromJSON(qs(d.vjson().data().vdata()).toUtf8()),
|
||||
zoomToken,
|
||||
};
|
||||
}, [&](const MTPDstatsGraphAsync &data) {
|
||||
return Data::StatisticalGraph{
|
||||
.zoomToken = qs(data.vtoken()).toUtf8(),
|
||||
};
|
||||
}, [&](const MTPDstatsGraphError &data) {
|
||||
return Data::StatisticalGraph{ .error = qs(data.verror()) };
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] Data::StatisticalValue StatisticalValueFromTL(
|
||||
const MTPStatsAbsValueAndPrev &tl) {
|
||||
const auto current = tl.data().vcurrent().v;
|
||||
@@ -223,61 +201,6 @@ Statistics::Statistics(not_null<ChannelData*> channel)
|
||||
: StatisticsRequestSender(channel) {
|
||||
}
|
||||
|
||||
StatisticsRequestSender::StatisticsRequestSender(not_null<ChannelData *> channel)
|
||||
: _channel(channel)
|
||||
, _api(&_channel->session().api().instance())
|
||||
, _timer([=] { checkRequests(); }) {
|
||||
}
|
||||
|
||||
StatisticsRequestSender::~StatisticsRequestSender() {
|
||||
for (const auto &[dcId, ids] : _requests) {
|
||||
for (const auto id : ids) {
|
||||
_channel->session().api().unregisterStatsRequest(dcId, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StatisticsRequestSender::checkRequests() {
|
||||
for (auto i = begin(_requests); i != end(_requests);) {
|
||||
for (auto j = begin(i->second); j != end(i->second);) {
|
||||
if (_api.pending(*j)) {
|
||||
++j;
|
||||
} else {
|
||||
_channel->session().api().unregisterStatsRequest(
|
||||
i->first,
|
||||
*j);
|
||||
j = i->second.erase(j);
|
||||
}
|
||||
}
|
||||
if (i->second.empty()) {
|
||||
i = _requests.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
if (_requests.empty()) {
|
||||
_timer.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Request, typename, typename>
|
||||
auto StatisticsRequestSender::makeRequest(Request &&request) {
|
||||
const auto id = _api.allocateRequestId();
|
||||
const auto dcId = _channel->owner().statsDcId(_channel);
|
||||
if (dcId) {
|
||||
_channel->session().api().registerStatsRequest(dcId, id);
|
||||
_requests[dcId].emplace(id);
|
||||
if (!_timer.isActive()) {
|
||||
_timer.callEach(kCheckRequestsTimer);
|
||||
}
|
||||
}
|
||||
return std::move(_api.request(
|
||||
std::forward<Request>(request)
|
||||
).toDC(
|
||||
dcId ? MTP::ShiftDcId(dcId, MTP::kStatsDcShift) : 0
|
||||
).overrideId(id));
|
||||
}
|
||||
|
||||
rpl::producer<rpl::no_value, QString> Statistics::request() {
|
||||
return [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
@@ -747,11 +670,11 @@ Data::BoostStatus Boosts::boostStatus() const {
|
||||
return _boostStatus;
|
||||
}
|
||||
|
||||
EarnStatistics::EarnStatistics(not_null<ChannelData*> channel)
|
||||
ChannelEarnStatistics::ChannelEarnStatistics(not_null<ChannelData*> channel)
|
||||
: StatisticsRequestSender(channel) {
|
||||
}
|
||||
|
||||
rpl::producer<rpl::no_value, QString> EarnStatistics::request() {
|
||||
rpl::producer<rpl::no_value, QString> ChannelEarnStatistics::request() {
|
||||
return [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
|
||||
@@ -760,14 +683,14 @@ rpl::producer<rpl::no_value, QString> EarnStatistics::request() {
|
||||
channel()->inputChannel
|
||||
)).done([=](const MTPstats_BroadcastRevenueStats &result) {
|
||||
const auto &data = result.data();
|
||||
|
||||
const auto &balances = data.vbalances().data();
|
||||
_data = Data::EarnStatistics{
|
||||
.topHoursGraph = StatisticalGraphFromTL(
|
||||
data.vtop_hours_graph()),
|
||||
.revenueGraph = StatisticalGraphFromTL(data.vrevenue_graph()),
|
||||
.currentBalance = data.vcurrent_balance().v,
|
||||
.availableBalance = data.vavailable_balance().v,
|
||||
.overallRevenue = data.voverall_revenue().v,
|
||||
.currentBalance = balances.vcurrent_balance().v,
|
||||
.availableBalance = balances.vavailable_balance().v,
|
||||
.overallRevenue = balances.voverall_revenue().v,
|
||||
.usdRate = data.vusd_rate().v,
|
||||
};
|
||||
|
||||
@@ -795,7 +718,7 @@ rpl::producer<rpl::no_value, QString> EarnStatistics::request() {
|
||||
};
|
||||
}
|
||||
|
||||
void EarnStatistics::requestHistory(
|
||||
void ChannelEarnStatistics::requestHistory(
|
||||
const Data::EarnHistorySlice::OffsetToken &token,
|
||||
Fn<void(Data::EarnHistorySlice)> done) {
|
||||
if (_requestId) {
|
||||
@@ -860,11 +783,12 @@ void EarnStatistics::requestHistory(
|
||||
.token = Data::EarnHistorySlice::OffsetToken(nextToken),
|
||||
});
|
||||
}).fail([=] {
|
||||
done({});
|
||||
_requestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
||||
Data::EarnStatistics EarnStatistics::data() const {
|
||||
Data::EarnStatistics ChannelEarnStatistics::data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,45 +7,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/timer.h"
|
||||
#include "api/api_statistics_sender.h"
|
||||
#include "data/data_boosts.h"
|
||||
#include "data/data_channel_earn.h"
|
||||
#include "data/data_statistics.h"
|
||||
#include "mtproto/sender.h"
|
||||
|
||||
class ChannelData;
|
||||
class PeerData;
|
||||
|
||||
namespace Api {
|
||||
|
||||
class StatisticsRequestSender {
|
||||
protected:
|
||||
explicit StatisticsRequestSender(not_null<ChannelData*> channel);
|
||||
~StatisticsRequestSender();
|
||||
|
||||
template <
|
||||
typename Request,
|
||||
typename = std::enable_if_t<!std::is_reference_v<Request>>,
|
||||
typename = typename Request::Unboxed>
|
||||
[[nodiscard]] auto makeRequest(Request &&request);
|
||||
|
||||
[[nodiscard]] MTP::Sender &api() {
|
||||
return _api;
|
||||
}
|
||||
[[nodiscard]] not_null<ChannelData*> channel() {
|
||||
return _channel;
|
||||
}
|
||||
|
||||
private:
|
||||
void checkRequests();
|
||||
|
||||
const not_null<ChannelData*> _channel;
|
||||
MTP::Sender _api;
|
||||
base::Timer _timer;
|
||||
base::flat_map<MTP::DcId, base::flat_set<mtpRequestId>> _requests;
|
||||
|
||||
};
|
||||
|
||||
class Statistics final : public StatisticsRequestSender {
|
||||
public:
|
||||
explicit Statistics(not_null<ChannelData*> channel);
|
||||
@@ -108,9 +79,9 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class EarnStatistics final : public StatisticsRequestSender {
|
||||
class ChannelEarnStatistics final : public StatisticsRequestSender {
|
||||
public:
|
||||
explicit EarnStatistics(not_null<ChannelData*> channel);
|
||||
explicit ChannelEarnStatistics(not_null<ChannelData*> channel);
|
||||
|
||||
[[nodiscard]] rpl::producer<rpl::no_value, QString> request();
|
||||
void requestHistory(
|
||||
|
||||
35
Telegram/SourceFiles/api/api_statistics_data_deserialize.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
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 "api/api_statistics_data_deserialize.h"
|
||||
|
||||
#include "data/data_statistics_chart.h"
|
||||
#include "statistics/statistics_data_deserialize.h"
|
||||
|
||||
namespace Api {
|
||||
|
||||
Data::StatisticalGraph StatisticalGraphFromTL(const MTPStatsGraph &tl) {
|
||||
return tl.match([&](const MTPDstatsGraph &d) {
|
||||
using namespace Statistic;
|
||||
const auto zoomToken = d.vzoom_token().has_value()
|
||||
? qs(*d.vzoom_token()).toUtf8()
|
||||
: QByteArray();
|
||||
return Data::StatisticalGraph{
|
||||
StatisticalChartFromJSON(qs(d.vjson().data().vdata()).toUtf8()),
|
||||
zoomToken,
|
||||
};
|
||||
}, [&](const MTPDstatsGraphAsync &data) {
|
||||
return Data::StatisticalGraph{
|
||||
.zoomToken = qs(data.vtoken()).toUtf8(),
|
||||
};
|
||||
}, [&](const MTPDstatsGraphError &data) {
|
||||
return Data::StatisticalGraph{ .error = qs(data.verror()) };
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
} // namespace Api
|
||||
19
Telegram/SourceFiles/api/api_statistics_data_deserialize.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
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 Data {
|
||||
struct StatisticalGraph;
|
||||
} // namespace Data
|
||||
|
||||
namespace Api {
|
||||
|
||||
[[nodiscard]] Data::StatisticalGraph StatisticalGraphFromTL(
|
||||
const MTPStatsGraph &tl);
|
||||
|
||||
} // namespace Api
|
||||
86
Telegram/SourceFiles/api/api_statistics_sender.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
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 "api/api_statistics_sender.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
namespace Api {
|
||||
|
||||
StatisticsRequestSender::StatisticsRequestSender(
|
||||
not_null<PeerData*> peer)
|
||||
: _peer(peer)
|
||||
, _channel(peer->asChannel())
|
||||
, _user(peer->asUser())
|
||||
, _api(&_peer->session().api().instance())
|
||||
, _timer([=] { checkRequests(); }) {
|
||||
}
|
||||
|
||||
MTP::Sender &StatisticsRequestSender::api() {
|
||||
return _api;
|
||||
}
|
||||
|
||||
not_null<ChannelData*> StatisticsRequestSender::channel() {
|
||||
Expects(_channel);
|
||||
return _channel;
|
||||
}
|
||||
|
||||
not_null<UserData*> StatisticsRequestSender::user() {
|
||||
Expects(_user);
|
||||
return _user;
|
||||
}
|
||||
|
||||
void StatisticsRequestSender::checkRequests() {
|
||||
for (auto i = begin(_requests); i != end(_requests);) {
|
||||
for (auto j = begin(i->second); j != end(i->second);) {
|
||||
if (_api.pending(*j)) {
|
||||
++j;
|
||||
} else {
|
||||
_peer->session().api().unregisterStatsRequest(
|
||||
i->first,
|
||||
*j);
|
||||
j = i->second.erase(j);
|
||||
}
|
||||
}
|
||||
if (i->second.empty()) {
|
||||
i = _requests.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
if (_requests.empty()) {
|
||||
_timer.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
auto StatisticsRequestSender::ensureRequestIsRegistered()
|
||||
-> StatisticsRequestSender::Registered {
|
||||
const auto id = _api.allocateRequestId();
|
||||
const auto dcId = _peer->owner().statsDcId(_peer);
|
||||
if (dcId) {
|
||||
_peer->session().api().registerStatsRequest(dcId, id);
|
||||
_requests[dcId].emplace(id);
|
||||
if (!_timer.isActive()) {
|
||||
constexpr auto kCheckRequestsTimer = 10 * crl::time(1000);
|
||||
_timer.callEach(kCheckRequestsTimer);
|
||||
}
|
||||
}
|
||||
return StatisticsRequestSender::Registered{ id, dcId };
|
||||
}
|
||||
|
||||
StatisticsRequestSender::~StatisticsRequestSender() {
|
||||
for (const auto &[dcId, ids] : _requests) {
|
||||
for (const auto id : ids) {
|
||||
_peer->session().api().unregisterStatsRequest(dcId, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
58
Telegram/SourceFiles/api/api_statistics_sender.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
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 "base/timer.h"
|
||||
#include "mtproto/sender.h"
|
||||
|
||||
class ChannelData;
|
||||
class PeerData;
|
||||
class UserData;
|
||||
|
||||
namespace Api {
|
||||
|
||||
class StatisticsRequestSender {
|
||||
protected:
|
||||
explicit StatisticsRequestSender(not_null<PeerData*> peer);
|
||||
~StatisticsRequestSender();
|
||||
|
||||
template <
|
||||
typename Request,
|
||||
typename = std::enable_if_t<!std::is_reference_v<Request>>,
|
||||
typename = typename Request::Unboxed>
|
||||
[[nodiscard]] auto makeRequest(Request &&request) {
|
||||
const auto [id, dcId] = ensureRequestIsRegistered();
|
||||
return std::move(_api.request(
|
||||
std::forward<Request>(request)
|
||||
).toDC(
|
||||
dcId ? MTP::ShiftDcId(dcId, MTP::kStatsDcShift) : 0
|
||||
).overrideId(id));
|
||||
}
|
||||
|
||||
[[nodiscard]] MTP::Sender &api();
|
||||
[[nodiscard]] not_null<ChannelData*> channel();
|
||||
[[nodiscard]] not_null<UserData*> user();
|
||||
|
||||
private:
|
||||
struct Registered final {
|
||||
mtpRequestId id;
|
||||
MTP::DcId dcId;
|
||||
};
|
||||
[[nodiscard]] Registered ensureRequestIsRegistered();
|
||||
void checkRequests();
|
||||
|
||||
const not_null<PeerData*> _peer;
|
||||
ChannelData * const _channel;
|
||||
UserData * const _user;
|
||||
MTP::Sender _api;
|
||||
base::Timer _timer;
|
||||
base::flat_map<MTP::DcId, base::flat_set<mtpRequestId>> _requests;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Api
|
||||
@@ -7,12 +7,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "api/api_text_entities.h"
|
||||
|
||||
#include "main/main_session.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "data/stickers/data_stickers_set.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_user.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
namespace Api {
|
||||
namespace {
|
||||
@@ -62,67 +62,168 @@ using namespace TextUtilities;
|
||||
EntitiesInText EntitiesFromMTP(
|
||||
Main::Session *session,
|
||||
const QVector<MTPMessageEntity> &entities) {
|
||||
if (entities.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
auto result = EntitiesInText();
|
||||
if (!entities.isEmpty()) {
|
||||
result.reserve(entities.size());
|
||||
for (const auto &entity : entities) {
|
||||
switch (entity.type()) {
|
||||
case mtpc_messageEntityUrl: { auto &d = entity.c_messageEntityUrl(); result.push_back({ EntityType::Url, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityTextUrl: { auto &d = entity.c_messageEntityTextUrl(); result.push_back({ EntityType::CustomUrl, d.voffset().v, d.vlength().v, qs(d.vurl()) }); } break;
|
||||
case mtpc_messageEntityEmail: { auto &d = entity.c_messageEntityEmail(); result.push_back({ EntityType::Email, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityHashtag: { auto &d = entity.c_messageEntityHashtag(); result.push_back({ EntityType::Hashtag, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityCashtag: { auto &d = entity.c_messageEntityCashtag(); result.push_back({ EntityType::Cashtag, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityPhone: break; // Skipping phones.
|
||||
case mtpc_messageEntityMention: { auto &d = entity.c_messageEntityMention(); result.push_back({ EntityType::Mention, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityMentionName: if (session) {
|
||||
const auto &d = entity.c_messageEntityMentionName();
|
||||
const auto userId = UserId(d.vuser_id());
|
||||
const auto user = session->data().userLoaded(userId);
|
||||
const auto data = MentionNameDataFromFields({
|
||||
.selfId = session->userId().bare,
|
||||
.userId = userId.bare,
|
||||
.accessHash = user ? user->accessHash() : 0,
|
||||
});
|
||||
result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data });
|
||||
} break;
|
||||
case mtpc_inputMessageEntityMentionName: if (session) {
|
||||
const auto &d = entity.c_inputMessageEntityMentionName();
|
||||
const auto data = d.vuser_id().match([&](
|
||||
const MTPDinputUserSelf &) {
|
||||
return MentionNameDataFromFields({
|
||||
.selfId = session->userId().bare,
|
||||
.userId = session->userId().bare,
|
||||
.accessHash = session->user()->accessHash(),
|
||||
});
|
||||
}, [&](const MTPDinputUser &data) {
|
||||
return MentionNameDataFromFields({
|
||||
.selfId = session->userId().bare,
|
||||
.userId = UserId(data.vuser_id()).bare,
|
||||
.accessHash = data.vaccess_hash().v,
|
||||
});
|
||||
}, [&](const auto &) {
|
||||
return QString();
|
||||
});
|
||||
if (!data.isEmpty()) {
|
||||
result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data });
|
||||
}
|
||||
} break;
|
||||
case mtpc_messageEntityBotCommand: { auto &d = entity.c_messageEntityBotCommand(); result.push_back({ EntityType::BotCommand, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityBold: { auto &d = entity.c_messageEntityBold(); result.push_back({ EntityType::Bold, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityItalic: { auto &d = entity.c_messageEntityItalic(); result.push_back({ EntityType::Italic, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityUnderline: { auto &d = entity.c_messageEntityUnderline(); result.push_back({ EntityType::Underline, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityStrike: { auto &d = entity.c_messageEntityStrike(); result.push_back({ EntityType::StrikeOut, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityCode: { auto &d = entity.c_messageEntityCode(); result.push_back({ EntityType::Code, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityPre: { auto &d = entity.c_messageEntityPre(); result.push_back({ EntityType::Pre, d.voffset().v, d.vlength().v, qs(d.vlanguage()) }); } break;
|
||||
case mtpc_messageEntityBlockquote: { auto &d = entity.c_messageEntityBlockquote(); result.push_back({ EntityType::Blockquote, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityBankCard: break; // Skipping cards. // #TODO entities
|
||||
case mtpc_messageEntitySpoiler: { auto &d = entity.c_messageEntitySpoiler(); result.push_back({ EntityType::Spoiler, d.voffset().v, d.vlength().v }); } break;
|
||||
case mtpc_messageEntityCustomEmoji: {
|
||||
const auto &d = entity.c_messageEntityCustomEmoji();
|
||||
result.push_back({ EntityType::CustomEmoji, d.voffset().v, d.vlength().v, CustomEmojiEntityData(d) });
|
||||
} break;
|
||||
result.reserve(entities.size());
|
||||
|
||||
for (const auto &entity : entities) {
|
||||
entity.match([&](const MTPDmessageEntityUnknown &d) {
|
||||
}, [&](const MTPDmessageEntityMention &d) {
|
||||
result.push_back({
|
||||
EntityType::Mention,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityHashtag &d) {
|
||||
result.push_back({
|
||||
EntityType::Hashtag,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityBotCommand &d) {
|
||||
result.push_back({
|
||||
EntityType::BotCommand,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityUrl &d) {
|
||||
result.push_back({
|
||||
EntityType::Url,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityEmail &d) {
|
||||
result.push_back({
|
||||
EntityType::Email,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityBold &d) {
|
||||
result.push_back({
|
||||
EntityType::Bold,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityItalic &d) {
|
||||
result.push_back({
|
||||
EntityType::Italic,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityCode &d) {
|
||||
result.push_back({
|
||||
EntityType::Code,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityPre &d) {
|
||||
result.push_back({
|
||||
EntityType::Pre,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
qs(d.vlanguage()),
|
||||
});
|
||||
}, [&](const MTPDmessageEntityTextUrl &d) {
|
||||
result.push_back({
|
||||
EntityType::CustomUrl,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
qs(d.vurl()),
|
||||
});
|
||||
}, [&](const MTPDmessageEntityMentionName &d) {
|
||||
if (!session) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const auto userId = UserId(d.vuser_id());
|
||||
const auto user = session->data().userLoaded(userId);
|
||||
const auto data = MentionNameDataFromFields({
|
||||
.selfId = session->userId().bare,
|
||||
.userId = userId.bare,
|
||||
.accessHash = user ? user->accessHash() : 0,
|
||||
});
|
||||
result.push_back({
|
||||
EntityType::MentionName,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
data,
|
||||
});
|
||||
}, [&](const MTPDinputMessageEntityMentionName &d) {
|
||||
if (!session) {
|
||||
return;
|
||||
}
|
||||
const auto data = d.vuser_id().match([&](
|
||||
const MTPDinputUserSelf &) {
|
||||
return MentionNameDataFromFields({
|
||||
.selfId = session->userId().bare,
|
||||
.userId = session->userId().bare,
|
||||
.accessHash = session->user()->accessHash(),
|
||||
});
|
||||
}, [&](const MTPDinputUser &data) {
|
||||
return MentionNameDataFromFields({
|
||||
.selfId = session->userId().bare,
|
||||
.userId = UserId(data.vuser_id()).bare,
|
||||
.accessHash = data.vaccess_hash().v,
|
||||
});
|
||||
}, [](const auto &) {
|
||||
return QString();
|
||||
});
|
||||
if (!data.isEmpty()) {
|
||||
result.push_back({
|
||||
EntityType::MentionName,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
data,
|
||||
});
|
||||
}
|
||||
}, [&](const MTPDmessageEntityPhone &d) {
|
||||
result.push_back({
|
||||
EntityType::Phone,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityCashtag &d) {
|
||||
result.push_back({
|
||||
EntityType::Cashtag,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityUnderline &d) {
|
||||
result.push_back({
|
||||
EntityType::Underline,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityStrike &d) {
|
||||
result.push_back({
|
||||
EntityType::StrikeOut,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityBankCard &d) {
|
||||
// Skipping cards. // #TODO entities
|
||||
}, [&](const MTPDmessageEntitySpoiler &d) {
|
||||
result.push_back({
|
||||
EntityType::Spoiler,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
});
|
||||
}, [&](const MTPDmessageEntityCustomEmoji &d) {
|
||||
result.push_back({
|
||||
EntityType::CustomEmoji,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
CustomEmojiEntityData(d),
|
||||
});
|
||||
}, [&](const MTPDmessageEntityBlockquote &d) {
|
||||
result.push_back({
|
||||
EntityType::Blockquote,
|
||||
d.voffset().v,
|
||||
d.vlength().v,
|
||||
d.is_collapsed() ? u"1"_q : QString(),
|
||||
});
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -134,7 +235,9 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(
|
||||
auto v = QVector<MTPMessageEntity>();
|
||||
v.reserve(entities.size());
|
||||
for (const auto &entity : entities) {
|
||||
if (entity.length() <= 0) continue;
|
||||
if (entity.length() <= 0) {
|
||||
continue;
|
||||
}
|
||||
if (option == ConvertOption::SkipLocal
|
||||
&& entity.type() != EntityType::Bold
|
||||
//&& entity.type() != EntityType::Semibold // Not in API.
|
||||
@@ -154,28 +257,85 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(
|
||||
auto offset = MTP_int(entity.offset());
|
||||
auto length = MTP_int(entity.length());
|
||||
switch (entity.type()) {
|
||||
case EntityType::Url: v.push_back(MTP_messageEntityUrl(offset, length)); break;
|
||||
case EntityType::CustomUrl: v.push_back(MTP_messageEntityTextUrl(offset, length, MTP_string(entity.data()))); break;
|
||||
case EntityType::Email: v.push_back(MTP_messageEntityEmail(offset, length)); break;
|
||||
case EntityType::Hashtag: v.push_back(MTP_messageEntityHashtag(offset, length)); break;
|
||||
case EntityType::Cashtag: v.push_back(MTP_messageEntityCashtag(offset, length)); break;
|
||||
case EntityType::Mention: v.push_back(MTP_messageEntityMention(offset, length)); break;
|
||||
case EntityType::Url: {
|
||||
v.push_back(MTP_messageEntityUrl(offset, length));
|
||||
} break;
|
||||
case EntityType::CustomUrl: {
|
||||
v.push_back(
|
||||
MTP_messageEntityTextUrl(
|
||||
offset,
|
||||
length,
|
||||
MTP_string(entity.data())));
|
||||
} break;
|
||||
case EntityType::Email: {
|
||||
v.push_back(MTP_messageEntityEmail(offset, length));
|
||||
} break;
|
||||
case EntityType::Phone: {
|
||||
v.push_back(MTP_messageEntityPhone(offset, length));
|
||||
} break;
|
||||
case EntityType::Hashtag: {
|
||||
v.push_back(MTP_messageEntityHashtag(offset, length));
|
||||
} break;
|
||||
case EntityType::Cashtag: {
|
||||
v.push_back(MTP_messageEntityCashtag(offset, length));
|
||||
} break;
|
||||
case EntityType::Mention: {
|
||||
v.push_back(MTP_messageEntityMention(offset, length));
|
||||
} break;
|
||||
case EntityType::MentionName: {
|
||||
if (const auto valid = MentionNameEntity(session, offset, length, entity.data())) {
|
||||
const auto valid = MentionNameEntity(
|
||||
session,
|
||||
offset,
|
||||
length,
|
||||
entity.data());
|
||||
if (valid) {
|
||||
v.push_back(*valid);
|
||||
}
|
||||
} break;
|
||||
case EntityType::BotCommand: v.push_back(MTP_messageEntityBotCommand(offset, length)); break;
|
||||
case EntityType::Bold: v.push_back(MTP_messageEntityBold(offset, length)); break;
|
||||
case EntityType::Italic: v.push_back(MTP_messageEntityItalic(offset, length)); break;
|
||||
case EntityType::Underline: v.push_back(MTP_messageEntityUnderline(offset, length)); break;
|
||||
case EntityType::StrikeOut: v.push_back(MTP_messageEntityStrike(offset, length)); break;
|
||||
case EntityType::Code: v.push_back(MTP_messageEntityCode(offset, length)); break; // #TODO entities
|
||||
case EntityType::Pre: v.push_back(MTP_messageEntityPre(offset, length, MTP_string(entity.data()))); break;
|
||||
case EntityType::Blockquote: v.push_back(MTP_messageEntityBlockquote(offset, length)); break;
|
||||
case EntityType::Spoiler: v.push_back(MTP_messageEntitySpoiler(offset, length)); break;
|
||||
case EntityType::BotCommand: {
|
||||
v.push_back(MTP_messageEntityBotCommand(offset, length));
|
||||
} break;
|
||||
case EntityType::Bold: {
|
||||
v.push_back(MTP_messageEntityBold(offset, length));
|
||||
} break;
|
||||
case EntityType::Italic: {
|
||||
v.push_back(MTP_messageEntityItalic(offset, length));
|
||||
} break;
|
||||
case EntityType::Underline: {
|
||||
v.push_back(MTP_messageEntityUnderline(offset, length));
|
||||
} break;
|
||||
case EntityType::StrikeOut: {
|
||||
v.push_back(MTP_messageEntityStrike(offset, length));
|
||||
} break;
|
||||
case EntityType::Code: {
|
||||
// #TODO entities.
|
||||
v.push_back(MTP_messageEntityCode(offset, length));
|
||||
} break;
|
||||
case EntityType::Pre: {
|
||||
v.push_back(
|
||||
MTP_messageEntityPre(
|
||||
offset,
|
||||
length,
|
||||
MTP_string(entity.data())));
|
||||
} break;
|
||||
case EntityType::Blockquote: {
|
||||
using Flag = MTPDmessageEntityBlockquote::Flag;
|
||||
const auto collapsed = !entity.data().isEmpty();
|
||||
v.push_back(
|
||||
MTP_messageEntityBlockquote(
|
||||
MTP_flags(collapsed ? Flag::f_collapsed : Flag()),
|
||||
offset,
|
||||
length));
|
||||
} break;
|
||||
case EntityType::Spoiler: {
|
||||
v.push_back(MTP_messageEntitySpoiler(offset, length));
|
||||
} break;
|
||||
case EntityType::CustomEmoji: {
|
||||
if (const auto valid = CustomEmojiEntity(offset, length, entity.data())) {
|
||||
const auto valid = CustomEmojiEntity(
|
||||
offset,
|
||||
length,
|
||||
entity.data());
|
||||
if (valid) {
|
||||
v.push_back(*valid);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -21,6 +21,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mtproto/mtproto_config.h"
|
||||
#include "mtproto/mtproto_dc_options.h"
|
||||
#include "data/business/data_shortcut_messages.h"
|
||||
#include "data/components/scheduled_messages.h"
|
||||
#include "data/components/top_peers.h"
|
||||
#include "data/notify/data_notify_settings.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "data/data_saved_messages.h"
|
||||
@@ -37,7 +39,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_scheduled_messages.h"
|
||||
#include "data/data_send_action.h"
|
||||
#include "data/data_stories.h"
|
||||
#include "data/data_message_reactions.h"
|
||||
@@ -94,7 +95,7 @@ void ProcessScheduledMessageWithElapsedTime(
|
||||
// Note that when a message is scheduled until online
|
||||
// while the recipient is already online, the server sends
|
||||
// an ordinary new message with skipped "from_scheduled" flag.
|
||||
session->data().scheduledMessages().checkEntitiesAndUpdate(data);
|
||||
session->scheduledMessages().checkEntitiesAndUpdate(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1136,7 +1137,9 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
|
||||
MTPMessageReactions(),
|
||||
MTPVector<MTPRestrictionReason>(),
|
||||
MTP_int(d.vttl_period().value_or_empty()),
|
||||
MTPint()), // quick_reply_shortcut_id
|
||||
MTPint(), // quick_reply_shortcut_id
|
||||
MTPlong(), // effect
|
||||
MTPFactCheck()),
|
||||
MessageFlags(),
|
||||
NewMessageType::Unread);
|
||||
} break;
|
||||
@@ -1171,7 +1174,9 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
|
||||
MTPMessageReactions(),
|
||||
MTPVector<MTPRestrictionReason>(),
|
||||
MTP_int(d.vttl_period().value_or_empty()),
|
||||
MTPint()), // quick_reply_shortcut_id
|
||||
MTPint(), // quick_reply_shortcut_id
|
||||
MTPlong(), // effect
|
||||
MTPFactCheck()),
|
||||
MessageFlags(),
|
||||
NewMessageType::Unread);
|
||||
} break;
|
||||
@@ -1464,7 +1469,9 @@ void Updates::applyUpdates(
|
||||
if (const auto id = owner.messageIdByRandomId(randomId)) {
|
||||
const auto local = owner.message(id);
|
||||
if (local && local->isScheduled()) {
|
||||
owner.scheduledMessages().sendNowSimpleMessage(d, local);
|
||||
session().scheduledMessages().sendNowSimpleMessage(
|
||||
d,
|
||||
local);
|
||||
}
|
||||
}
|
||||
const auto wasAlready = (lookupMessage() != nullptr);
|
||||
@@ -1561,7 +1568,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
auto &owner = session().data();
|
||||
if (const auto local = owner.message(id)) {
|
||||
if (local->isScheduled()) {
|
||||
session().data().scheduledMessages().apply(d, local);
|
||||
session().scheduledMessages().apply(d, local);
|
||||
} else if (local->isBusinessShortcut()) {
|
||||
session().data().shortcutMessages().apply(d, local);
|
||||
} else {
|
||||
@@ -1575,6 +1582,11 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
} else {
|
||||
if (existing) {
|
||||
existing->destroy();
|
||||
} else {
|
||||
// Not the server-side date, but close enough.
|
||||
session().topPeers().increment(
|
||||
local->history()->peer,
|
||||
local->date());
|
||||
}
|
||||
local->setRealId(d.vid().v);
|
||||
}
|
||||
@@ -1684,7 +1696,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
const auto peerId = peerFromMTP(d.vpeer());
|
||||
const auto msgId = d.vmsg_id().v;
|
||||
if (const auto item = session().data().message(peerId, msgId)) {
|
||||
item->applyEdition(d.vextended_media());
|
||||
item->applyEdition(d.vextended_media().v);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -1771,12 +1783,12 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updateNewScheduledMessage: {
|
||||
const auto &d = update.c_updateNewScheduledMessage();
|
||||
session().data().scheduledMessages().apply(d);
|
||||
session().scheduledMessages().apply(d);
|
||||
} break;
|
||||
|
||||
case mtpc_updateDeleteScheduledMessages: {
|
||||
const auto &d = update.c_updateDeleteScheduledMessages();
|
||||
session().data().scheduledMessages().apply(d);
|
||||
session().scheduledMessages().apply(d);
|
||||
} break;
|
||||
|
||||
case mtpc_updateQuickReplies: {
|
||||
@@ -2109,6 +2121,8 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
};
|
||||
if (IsForceLogoutNotification(d)) {
|
||||
Core::App().forceLogOut(&session().account(), text);
|
||||
} else if (IsWithdrawalNotification(d)) {
|
||||
return;
|
||||
} else if (d.is_popup()) {
|
||||
const auto &windows = session().windows();
|
||||
if (!windows.empty()) {
|
||||
@@ -2602,7 +2616,16 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
_session->data().stories().apply(data.vstealth_mode());
|
||||
} break;
|
||||
|
||||
case mtpc_updateStarsBalance: {
|
||||
const auto &data = update.c_updateStarsBalance();
|
||||
_session->setCredits(data.vbalance().v);
|
||||
} break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool IsWithdrawalNotification(const MTPDupdateServiceNotification &data) {
|
||||
return qs(data.vtype()).startsWith(u"API_WITHDRAWAL_FEATURE_DISABLED_"_q);
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -211,4 +211,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]] bool IsWithdrawalNotification(
|
||||
const MTPDupdateServiceNotification &);
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -307,8 +307,8 @@ void UserPrivacy::reload(Key key) {
|
||||
}
|
||||
|
||||
void UserPrivacy::pushPrivacy(Key key, const TLRules &rules) {
|
||||
const auto &saved = (_privacyValues[key] =
|
||||
TLToRules(rules, _session->data()));
|
||||
const auto &saved
|
||||
= (_privacyValues[key] = TLToRules(rules, _session->data()));
|
||||
const auto i = _privacyChanges.find(key);
|
||||
if (i != end(_privacyChanges)) {
|
||||
i->second.fire_copy(saved);
|
||||
|
||||
@@ -55,7 +55,9 @@ void ViewsManager::removeIncremented(not_null<PeerData*> peer) {
|
||||
_incremented.remove(peer);
|
||||
}
|
||||
|
||||
void ViewsManager::pollExtendedMedia(not_null<HistoryItem*> item) {
|
||||
void ViewsManager::pollExtendedMedia(
|
||||
not_null<HistoryItem*> item,
|
||||
bool force) {
|
||||
if (!item->isRegular()) {
|
||||
return;
|
||||
}
|
||||
@@ -63,14 +65,20 @@ void ViewsManager::pollExtendedMedia(not_null<HistoryItem*> item) {
|
||||
const auto peer = item->history()->peer;
|
||||
auto &request = _pollRequests[peer];
|
||||
if (request.ids.contains(id) || request.sent.contains(id)) {
|
||||
return;
|
||||
if (!force || request.forced) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
request.ids.emplace(id);
|
||||
if (!request.id && !request.when) {
|
||||
request.when = crl::now() + kPollExtendedMediaPeriod;
|
||||
if (force) {
|
||||
request.forced = true;
|
||||
}
|
||||
if (!_pollTimer.isActive()) {
|
||||
_pollTimer.callOnce(kPollExtendedMediaPeriod);
|
||||
const auto delay = force ? 1 : kPollExtendedMediaPeriod;
|
||||
if (!request.id && (!request.when || force)) {
|
||||
request.when = crl::now() + delay;
|
||||
}
|
||||
if (!_pollTimer.isActive() || force) {
|
||||
_pollTimer.callOnce(delay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,9 +168,12 @@ void ViewsManager::sendPollRequests(
|
||||
if (i->second.ids.empty()) {
|
||||
i = _pollRequests.erase(i);
|
||||
} else {
|
||||
i->second.when = now + kPollExtendedMediaPeriod;
|
||||
if (!_pollTimer.isActive()) {
|
||||
_pollTimer.callOnce(kPollExtendedMediaPeriod);
|
||||
const auto delay = i->second.forced
|
||||
? 1
|
||||
: kPollExtendedMediaPeriod;
|
||||
i->second.when = now + delay;
|
||||
if (!_pollTimer.isActive() || i->second.forced) {
|
||||
_pollTimer.callOnce(delay);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
void scheduleIncrement(not_null<HistoryItem*> item);
|
||||
void removeIncremented(not_null<PeerData*> peer);
|
||||
|
||||
void pollExtendedMedia(not_null<HistoryItem*> item);
|
||||
void pollExtendedMedia(not_null<HistoryItem*> item, bool force = false);
|
||||
|
||||
private:
|
||||
struct PollExtendedMediaRequest {
|
||||
@@ -34,6 +34,7 @@ private:
|
||||
mtpRequestId id = 0;
|
||||
base::flat_set<MsgId> ids;
|
||||
base::flat_set<MsgId> sent;
|
||||
bool forced = false;
|
||||
};
|
||||
|
||||
void viewsIncrement();
|
||||
|
||||
@@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_user_names.h"
|
||||
#include "api/api_websites.h"
|
||||
#include "data/business/data_shortcut_messages.h"
|
||||
#include "data/components/scheduled_messages.h"
|
||||
#include "data/notify/data_notify_settings.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_web_page.h"
|
||||
@@ -43,13 +44,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "data/data_search_controller.h"
|
||||
#include "data/data_scheduled_messages.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_chat_filters.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_history_messages.h"
|
||||
#include "core/core_cloud_password.h"
|
||||
#include "core/application.h"
|
||||
#include "base/unixtime.h"
|
||||
@@ -542,7 +543,7 @@ void ApiWrap::sendMessageFail(
|
||||
}
|
||||
}
|
||||
} else if (error == u"SCHEDULE_STATUS_PRIVATE"_q) {
|
||||
auto &scheduled = _session->data().scheduledMessages();
|
||||
auto &scheduled = _session->scheduledMessages();
|
||||
Assert(peer->isUser());
|
||||
if (const auto item = scheduled.lookupItem(peer->id, itemId.msg)) {
|
||||
scheduled.removeSending(item);
|
||||
@@ -1544,8 +1545,8 @@ void ApiWrap::saveStickerSets(
|
||||
writeRecent = true;
|
||||
}
|
||||
|
||||
const auto isAttached =
|
||||
(removedSetId == Data::Stickers::CloudRecentAttachedSetId);
|
||||
const auto isAttached
|
||||
= (removedSetId == Data::Stickers::CloudRecentAttachedSetId);
|
||||
const auto flags = isAttached
|
||||
? MTPmessages_ClearRecentStickers::Flag::f_attached
|
||||
: MTPmessages_ClearRecentStickers::Flags(0);
|
||||
@@ -2164,7 +2165,8 @@ void ApiWrap::saveDraftsToCloud() {
|
||||
entities,
|
||||
Data::WebPageForMTP(
|
||||
cloudDraft->webpage,
|
||||
textWithTags.text.isEmpty())
|
||||
textWithTags.text.isEmpty()),
|
||||
MTP_long(0) // effect
|
||||
)).done([=](const MTPBool &result, const MTP::Response &response) {
|
||||
const auto requestId = response.requestId;
|
||||
history->finishSavingCloudDraft(
|
||||
@@ -2447,8 +2449,8 @@ void ApiWrap::refreshFileReference(
|
||||
_session->data().peer(storyId.peer)->input,
|
||||
MTP_vector<MTPint>(1, MTP_int(storyId.story))));
|
||||
} else if (item->isScheduled()) {
|
||||
const auto &scheduled = _session->data().scheduledMessages();
|
||||
const auto realId = scheduled.lookupId(item);
|
||||
const auto realId = _session->scheduledMessages().lookupId(
|
||||
item);
|
||||
request(MTPmessages_GetScheduledMessages(
|
||||
item->history()->peer->input,
|
||||
MTP_vector<MTPint>(1, MTP_int(realId))));
|
||||
@@ -2494,8 +2496,8 @@ void ApiWrap::refreshFileReference(
|
||||
}, [&](Data::FileOriginPeerPhoto data) {
|
||||
fail();
|
||||
}, [&](Data::FileOriginStickerSet data) {
|
||||
const auto isRecentAttached =
|
||||
(data.setId == Data::Stickers::CloudRecentAttachedSetId);
|
||||
const auto isRecentAttached
|
||||
= (data.setId == Data::Stickers::CloudRecentAttachedSetId);
|
||||
if (data.setId == Data::Stickers::CloudRecentSetId
|
||||
|| data.setId == Data::Stickers::RecentSetId
|
||||
|| isRecentAttached) {
|
||||
@@ -3078,6 +3080,46 @@ void ApiWrap::resolveJumpToHistoryDate(
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::requestHistory(
|
||||
not_null<History*> history,
|
||||
MsgId messageId,
|
||||
SliceType slice) {
|
||||
const auto peer = history->peer;
|
||||
const auto key = HistoryRequest{
|
||||
peer,
|
||||
messageId,
|
||||
slice,
|
||||
};
|
||||
if (_historyRequests.contains(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto prepared = Api::PrepareHistoryRequest(peer, messageId, slice);
|
||||
auto &histories = history->owner().histories();
|
||||
const auto requestType = Data::Histories::RequestType::History;
|
||||
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
||||
return request(
|
||||
std::move(prepared)
|
||||
).done([=](const Api::HistoryRequestResult &result) {
|
||||
_historyRequests.remove(key);
|
||||
auto parsed = Api::ParseHistoryResult(
|
||||
peer,
|
||||
messageId,
|
||||
slice,
|
||||
result);
|
||||
history->messages().addSlice(
|
||||
std::move(parsed.messageIds),
|
||||
parsed.noSkipRange,
|
||||
parsed.fullCount);
|
||||
finish();
|
||||
}).fail([=] {
|
||||
_historyRequests.remove(key);
|
||||
finish();
|
||||
}).send();
|
||||
});
|
||||
_historyRequests.emplace(key);
|
||||
}
|
||||
|
||||
void ApiWrap::requestSharedMedia(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
@@ -3342,6 +3384,9 @@ void ApiWrap::forwardMessages(
|
||||
.date = HistoryItem::NewMessageDate(action.options),
|
||||
.shortcutId = action.options.shortcutId,
|
||||
.postAuthor = messagePostAuthor,
|
||||
|
||||
// forwarded messages don't have effects
|
||||
//.effectId = action.options.effectId,
|
||||
}, item);
|
||||
_session->data().registerMessageRandomId(randomId, newId);
|
||||
if (!localIds) {
|
||||
@@ -3442,6 +3487,7 @@ void ApiWrap::sendSharedContact(
|
||||
.date = HistoryItem::NewMessageDate(action.options),
|
||||
.shortcutId = action.options.shortcutId,
|
||||
.postAuthor = messagePostAuthor,
|
||||
.effectId = action.options.effectId,
|
||||
}, TextWithEntities(), MTP_messageMediaContact(
|
||||
MTP_string(phone),
|
||||
MTP_string(firstName),
|
||||
@@ -3729,7 +3775,8 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
const auto anonymousPost = peer->amAnonymous();
|
||||
const auto silentPost = ShouldSendSilent(peer, action.options);
|
||||
FillMessagePostFlags(action, peer, flags);
|
||||
if (exactWebPage && !ignoreWebPage && message.webPage.invert) {
|
||||
if ((exactWebPage && !ignoreWebPage && message.webPage.invert)
|
||||
|| action.options.invertCaption) {
|
||||
flags |= MessageFlag::InvertMedia;
|
||||
sendFlags |= MTPmessages_SendMessage::Flag::f_invert_media;
|
||||
mediaFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
|
||||
@@ -3775,6 +3822,10 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
sendFlags |= MTPmessages_SendMessage::Flag::f_quick_reply_shortcut;
|
||||
mediaFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
|
||||
}
|
||||
if (action.options.effectId) {
|
||||
sendFlags |= MTPmessages_SendMessage::Flag::f_effect;
|
||||
mediaFlags |= MTPmessages_SendMedia::Flag::f_effect;
|
||||
}
|
||||
lastMessage = history->addNewLocalMessage({
|
||||
.id = newId.msg,
|
||||
.flags = flags,
|
||||
@@ -3783,6 +3834,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
.date = HistoryItem::NewMessageDate(action.options),
|
||||
.shortcutId = action.options.shortcutId,
|
||||
.postAuthor = messagePostAuthor,
|
||||
.effectId = action.options.effectId,
|
||||
}, sending, media);
|
||||
const auto done = [=](
|
||||
const MTPUpdates &result,
|
||||
@@ -3828,7 +3880,8 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
sentEntities,
|
||||
MTP_int(action.options.scheduled),
|
||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||
mtpShortcut
|
||||
mtpShortcut,
|
||||
MTP_long(action.options.effectId)
|
||||
), done, fail);
|
||||
} else {
|
||||
histories.sendPreparedMessage(
|
||||
@@ -3845,7 +3898,8 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
sentEntities,
|
||||
MTP_int(action.options.scheduled),
|
||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||
mtpShortcut
|
||||
mtpShortcut,
|
||||
MTP_long(action.options.effectId)
|
||||
), done, fail);
|
||||
}
|
||||
isFirst = false;
|
||||
@@ -4119,7 +4173,9 @@ void ApiWrap::sendMediaWithRandomId(
|
||||
| (!sentEntities.v.isEmpty() ? Flag::f_entities : Flag(0))
|
||||
| (options.scheduled ? Flag::f_schedule_date : Flag(0))
|
||||
| (options.sendAs ? Flag::f_send_as : Flag(0))
|
||||
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0));
|
||||
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0))
|
||||
| (options.effectId ? Flag::f_effect : Flag(0))
|
||||
| (options.invertCaption ? Flag::f_invert_media : Flag(0));
|
||||
|
||||
auto &histories = history->owner().histories();
|
||||
const auto peer = history->peer;
|
||||
@@ -4132,14 +4188,19 @@ void ApiWrap::sendMediaWithRandomId(
|
||||
MTP_flags(flags),
|
||||
peer->input,
|
||||
Data::Histories::ReplyToPlaceholder(),
|
||||
media,
|
||||
(options.price
|
||||
? MTPInputMedia(MTP_inputMediaPaidMedia(
|
||||
MTP_long(options.price),
|
||||
MTP_vector<MTPInputMedia>(1, media)))
|
||||
: media),
|
||||
MTP_string(caption.text),
|
||||
MTP_long(randomId),
|
||||
MTPReplyMarkup(),
|
||||
sentEntities,
|
||||
MTP_int(options.scheduled),
|
||||
(options.sendAs ? options.sendAs->input : MTP_inputPeerEmpty()),
|
||||
Data::ShortcutIdToMTP(_session, options.shortcutId)
|
||||
Data::ShortcutIdToMTP(_session, options.shortcutId),
|
||||
MTP_long(options.effectId)
|
||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||
if (done) done(true);
|
||||
if (updateRecentStickers) {
|
||||
@@ -4151,6 +4212,82 @@ void ApiWrap::sendMediaWithRandomId(
|
||||
});
|
||||
}
|
||||
|
||||
void ApiWrap::sendMultiPaidMedia(
|
||||
not_null<HistoryItem*> item,
|
||||
not_null<SendingAlbum*> album,
|
||||
Fn<void(bool)> done) {
|
||||
Expects(album->options.price > 0);
|
||||
|
||||
const auto groupId = album->groupId;
|
||||
const auto &options = album->options;
|
||||
const auto randomId = album->items.front().randomId;
|
||||
auto medias = album->items | ranges::view::transform([](
|
||||
const SendingAlbum::Item &part) {
|
||||
Assert(part.media.has_value());
|
||||
return MTPInputMedia(part.media->data().vmedia());
|
||||
}) | ranges::to<QVector<MTPInputMedia>>();
|
||||
|
||||
const auto history = item->history();
|
||||
const auto replyTo = item->replyTo();
|
||||
|
||||
auto caption = item->originalText();
|
||||
TextUtilities::Trim(caption);
|
||||
auto sentEntities = Api::EntitiesToMTP(
|
||||
_session,
|
||||
caption.entities,
|
||||
Api::ConvertOption::SkipLocal);
|
||||
|
||||
using Flag = MTPmessages_SendMedia::Flag;
|
||||
const auto flags = Flag(0)
|
||||
| (replyTo ? Flag::f_reply_to : Flag(0))
|
||||
| (ShouldSendSilent(history->peer, options)
|
||||
? Flag::f_silent
|
||||
: Flag(0))
|
||||
| (!sentEntities.v.isEmpty() ? Flag::f_entities : Flag(0))
|
||||
| (options.scheduled ? Flag::f_schedule_date : Flag(0))
|
||||
| (options.sendAs ? Flag::f_send_as : Flag(0))
|
||||
| (options.shortcutId ? Flag::f_quick_reply_shortcut : Flag(0))
|
||||
| (options.effectId ? Flag::f_effect : Flag(0))
|
||||
| (options.invertCaption ? Flag::f_invert_media : Flag(0));
|
||||
|
||||
auto &histories = history->owner().histories();
|
||||
const auto peer = history->peer;
|
||||
const auto itemId = item->fullId();
|
||||
histories.sendPreparedMessage(
|
||||
history,
|
||||
replyTo,
|
||||
randomId,
|
||||
Data::Histories::PrepareMessage<MTPmessages_SendMedia>(
|
||||
MTP_flags(flags),
|
||||
peer->input,
|
||||
Data::Histories::ReplyToPlaceholder(),
|
||||
MTP_inputMediaPaidMedia(
|
||||
MTP_long(options.price),
|
||||
MTP_vector<MTPInputMedia>(std::move(medias))),
|
||||
MTP_string(caption.text),
|
||||
MTP_long(randomId),
|
||||
MTPReplyMarkup(),
|
||||
sentEntities,
|
||||
MTP_int(options.scheduled),
|
||||
(options.sendAs ? options.sendAs->input : MTP_inputPeerEmpty()),
|
||||
Data::ShortcutIdToMTP(_session, options.shortcutId),
|
||||
MTP_long(options.effectId)
|
||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||
if (const auto album = _sendingAlbums.take(groupId)) {
|
||||
const auto copy = (*album)->items;
|
||||
for (const auto &part : copy) {
|
||||
if (const auto item = history->owner().message(part.msgId)) {
|
||||
item->destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (done) done(true);
|
||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||
if (done) done(false);
|
||||
sendMessageFail(error, peer, randomId, itemId);
|
||||
});
|
||||
}
|
||||
|
||||
void ApiWrap::sendAlbumWithUploaded(
|
||||
not_null<HistoryItem*> item,
|
||||
const MessageGroupId &groupId,
|
||||
@@ -4204,8 +4341,11 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
||||
if (!sample) {
|
||||
_sendingAlbums.remove(groupId);
|
||||
return;
|
||||
} else if (album->options.price > 0) {
|
||||
sendMultiPaidMedia(sample, album);
|
||||
return;
|
||||
} else if (medias.size() < 2) {
|
||||
const auto &single = medias.front().c_inputSingleMedia();
|
||||
const auto &single = medias.front().data();
|
||||
sendMediaWithRandomId(
|
||||
sample,
|
||||
single.vmedia(),
|
||||
@@ -4227,7 +4367,9 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
||||
| (sendAs ? Flag::f_send_as : Flag(0))
|
||||
| (album->options.shortcutId
|
||||
? Flag::f_quick_reply_shortcut
|
||||
: Flag(0));
|
||||
: Flag(0))
|
||||
| (album->options.effectId ? Flag::f_effect : Flag(0))
|
||||
| (album->options.invertCaption ? Flag::f_invert_media : Flag(0));
|
||||
auto &histories = history->owner().histories();
|
||||
const auto peer = history->peer;
|
||||
histories.sendPreparedMessage(
|
||||
@@ -4241,7 +4383,8 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
|
||||
MTP_vector<MTPInputSingleMedia>(medias),
|
||||
MTP_int(album->options.scheduled),
|
||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||
Data::ShortcutIdToMTP(_session, album->options.shortcutId)
|
||||
Data::ShortcutIdToMTP(_session, album->options.shortcutId),
|
||||
MTP_long(album->options.effectId)
|
||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||
_sendingAlbums.remove(groupId);
|
||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||
|
||||
@@ -274,6 +274,10 @@ public:
|
||||
Fn<void(not_null<PeerData*>, MsgId)> callback);
|
||||
|
||||
using SliceType = Data::LoadDirection;
|
||||
void requestHistory(
|
||||
not_null<History*> history,
|
||||
MsgId messageId,
|
||||
SliceType slice);
|
||||
void requestSharedMedia(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
@@ -511,7 +515,8 @@ private:
|
||||
not_null<PeerData*> peer,
|
||||
bool justClear,
|
||||
bool revoke);
|
||||
void applyAffectedMessages(const MTPmessages_AffectedMessages &result) const;
|
||||
void applyAffectedMessages(
|
||||
const MTPmessages_AffectedMessages &result) const;
|
||||
|
||||
void deleteAllFromParticipantSend(
|
||||
not_null<ChannelData*> channel,
|
||||
@@ -540,6 +545,10 @@ private:
|
||||
Api::SendOptions options,
|
||||
uint64 randomId,
|
||||
Fn<void(bool)> done = nullptr);
|
||||
void sendMultiPaidMedia(
|
||||
not_null<HistoryItem*> item,
|
||||
not_null<SendingAlbum*> album,
|
||||
Fn<void(bool)> done = nullptr);
|
||||
|
||||
void getTopPromotionDelayed(TimeId now, TimeId next);
|
||||
void topPromotionDone(const MTPhelp_PromoData &proxy);
|
||||
@@ -645,6 +654,17 @@ private:
|
||||
};
|
||||
base::flat_set<SharedMediaRequest> _sharedMediaRequests;
|
||||
|
||||
struct HistoryRequest {
|
||||
not_null<PeerData*> peer;
|
||||
MsgId aroundId = 0;
|
||||
SliceType sliceType = {};
|
||||
|
||||
friend inline auto operator<=>(
|
||||
const HistoryRequest&,
|
||||
const HistoryRequest&) = default;
|
||||
};
|
||||
base::flat_set<HistoryRequest> _historyRequests;
|
||||
|
||||
std::unique_ptr<DialogsLoadState> _dialogsLoadState;
|
||||
TimeId _dialogsLoadTill = 0;
|
||||
rpl::variable<bool> _dialogsLoadMayBlockByDate = false;
|
||||
|
||||