Compare commits
463 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ab40de8b9 | ||
|
|
35659536c5 | ||
|
|
31ec831c71 | ||
|
|
866c5e9b7b | ||
|
|
d6a00523a8 | ||
|
|
9ebeddbed8 | ||
|
|
c85fd368fe | ||
|
|
16f3ca87f5 | ||
|
|
e47d110f28 | ||
|
|
20b67ee000 | ||
|
|
d8a4ede4b5 | ||
|
|
5ed15cd0b3 | ||
|
|
87c07a13a1 | ||
|
|
73ce722147 | ||
|
|
233be5ec13 | ||
|
|
50b78034a5 | ||
|
|
777bf7d8d9 | ||
|
|
4a4544c883 | ||
|
|
d03d699331 | ||
|
|
d16cbbf279 | ||
|
|
72f95b984f | ||
|
|
9055b33e92 | ||
|
|
812ffb4297 | ||
|
|
958d55a594 | ||
|
|
4559888113 | ||
|
|
294ed1bb17 | ||
|
|
a52392241d | ||
|
|
31998406dd | ||
|
|
5a63fc7bbb | ||
|
|
a2d4b9260e | ||
|
|
1d1bd5e1e7 | ||
|
|
a42fb1f7b7 | ||
|
|
dd81f5d59f | ||
|
|
8d1cdea31a | ||
|
|
fae4b92d8d | ||
|
|
18f38f0983 | ||
|
|
a29e8f9a06 | ||
|
|
5c0cc8a947 | ||
|
|
308fb19da4 | ||
|
|
6aecb81c23 | ||
|
|
72b29dd90d | ||
|
|
2f5f1fbac9 | ||
|
|
ab797b4dff | ||
|
|
ab5f35e952 | ||
|
|
275ec3e679 | ||
|
|
44b551898d | ||
|
|
4a8b6ff5ba | ||
|
|
60582a24ab | ||
|
|
67e698a374 | ||
|
|
46af87a00a | ||
|
|
d6d942bc64 | ||
|
|
5cb44834dc | ||
|
|
6795ecea61 | ||
|
|
22bdf15825 | ||
|
|
704e3c9423 | ||
|
|
67ea175fc6 | ||
|
|
6c2a39f1fc | ||
|
|
395f22063b | ||
|
|
9f6130cd20 | ||
|
|
5b615519e8 | ||
|
|
03b7a3ca2b | ||
|
|
4f1a633019 | ||
|
|
362b3bc578 | ||
|
|
6de3112c8a | ||
|
|
1064208be9 | ||
|
|
49578836be | ||
|
|
e4ae5bfcad | ||
|
|
e82430cb50 | ||
|
|
e7ce4ca10a | ||
|
|
f8b2e474b9 | ||
|
|
8969a7d929 | ||
|
|
ead31757d7 | ||
|
|
c20cf243db | ||
|
|
9142313a6b | ||
|
|
ccb57a6d69 | ||
|
|
11fd757e99 | ||
|
|
1c48f33dc1 | ||
|
|
9903546a2d | ||
|
|
e4e05a14b7 | ||
|
|
62389f5ef7 | ||
|
|
4e2a109a46 | ||
|
|
35dcbe0aa0 | ||
|
|
d0e854e9d8 | ||
|
|
f1519b76f6 | ||
|
|
94bfd59b76 | ||
|
|
2790919733 | ||
|
|
f0b7ff24b1 | ||
|
|
5cfead762d | ||
|
|
a2dabfde56 | ||
|
|
b0a9d26a94 | ||
|
|
2bc60fa54f | ||
|
|
c2aa9c571c | ||
|
|
083b520eee | ||
|
|
1392e05ab1 | ||
|
|
b2014f403e | ||
|
|
f633ead3ab | ||
|
|
07e8a2bd85 | ||
|
|
ddb4527159 | ||
|
|
e122353bfb | ||
|
|
b4a2e84aa3 | ||
|
|
b64bbc7708 | ||
|
|
364aaaae5b | ||
|
|
2bd8737410 | ||
|
|
e62e7d1de2 | ||
|
|
bffd852b4e | ||
|
|
fdfdd0acce | ||
|
|
80be464d95 | ||
|
|
2878e46d2b | ||
|
|
b198c9b975 | ||
|
|
cf7a779689 | ||
|
|
53b3b24867 | ||
|
|
8edf4c8711 | ||
|
|
ad12d6cc46 | ||
|
|
7db7c05da8 | ||
|
|
43d19920e0 | ||
|
|
bfc748cd31 | ||
|
|
b3059248d4 | ||
|
|
0cbad9098e | ||
|
|
5c5438c12e | ||
|
|
734c410879 | ||
|
|
4b4e22d59d | ||
|
|
8f63fa71c9 | ||
|
|
267293d21b | ||
|
|
20ee1fa0d3 | ||
|
|
c70e9b529a | ||
|
|
e42e973ed5 | ||
|
|
03037121aa | ||
|
|
d257b2ee17 | ||
|
|
59a1e13955 | ||
|
|
4e858ba839 | ||
|
|
0eb3d20250 | ||
|
|
c0896f5357 | ||
|
|
f334e2d0f4 | ||
|
|
dfbe11efdb | ||
|
|
becbad32c9 | ||
|
|
46976c4e03 | ||
|
|
1e4cf4c466 | ||
|
|
2e1517474d | ||
|
|
08897aa83a | ||
|
|
7252e9b266 | ||
|
|
07d8dafa5e | ||
|
|
cca46448fe | ||
|
|
3f7947b404 | ||
|
|
4870558827 | ||
|
|
c23ec41622 | ||
|
|
544aef19b4 | ||
|
|
24834ced9e | ||
|
|
10fa6f0c13 | ||
|
|
7a32ad5409 | ||
|
|
4f7df6987c | ||
|
|
3d75d21a3e | ||
|
|
250718e766 | ||
|
|
a5cbade8ec | ||
|
|
3ac50cf77f | ||
|
|
f35bf41d26 | ||
|
|
f1816815a9 | ||
|
|
37bf9ffcff | ||
|
|
5e7642b42a | ||
|
|
6f6ec217e3 | ||
|
|
017ec87d60 | ||
|
|
30dd8fe070 | ||
|
|
8e442563f2 | ||
|
|
c43dcf0567 | ||
|
|
f2a5a29d12 | ||
|
|
678b9a8eb5 | ||
|
|
96f7c0c02e | ||
|
|
66b7b6da2a | ||
|
|
38daffdbfe | ||
|
|
0238c03956 | ||
|
|
425e56b3ea | ||
|
|
4478c0a143 | ||
|
|
a053384618 | ||
|
|
694e8cd19f | ||
|
|
4bcd1e3c59 | ||
|
|
5f063c0151 | ||
|
|
5a1d4d55c6 | ||
|
|
d3f85b4c4e | ||
|
|
df9ec4b466 | ||
|
|
4f9507ed97 | ||
|
|
f761b6aa9e | ||
|
|
168a7ce2e5 | ||
|
|
4b763a76df | ||
|
|
8764da787b | ||
|
|
7d8ba15252 | ||
|
|
96c0c30f7c | ||
|
|
bb6ab5314c | ||
|
|
e3c6abfc3d | ||
|
|
5c5bccae0b | ||
|
|
296e009808 | ||
|
|
4d84781a65 | ||
|
|
710b9bf454 | ||
|
|
0f54315495 | ||
|
|
c3fc91a6fc | ||
|
|
d2048f3c25 | ||
|
|
cc2c13d018 | ||
|
|
48c1576d7f | ||
|
|
d2fa8ef0b0 | ||
|
|
97b576f446 | ||
|
|
257dfa6b3f | ||
|
|
678d2a58c5 | ||
|
|
e0431d270b | ||
|
|
7797e5a3b7 | ||
|
|
d15b0cdb08 | ||
|
|
1af2769209 | ||
|
|
e6906b84f3 | ||
|
|
ca0f6c7ded | ||
|
|
f9ff676e57 | ||
|
|
db7041f2dc | ||
|
|
ad1f089802 | ||
|
|
62c812858e | ||
|
|
4bf66cb6e9 | ||
|
|
95fee543ec | ||
|
|
df4daca15b | ||
|
|
f794d8dbd8 | ||
|
|
9935a36c3d | ||
|
|
a7c77682d7 | ||
|
|
8bbea976ea | ||
|
|
900d1ddb36 | ||
|
|
8e99135f37 | ||
|
|
dc9483e07a | ||
|
|
48e913bf2c | ||
|
|
993cb987a6 | ||
|
|
65f968ec1b | ||
|
|
93f6d4b6e7 | ||
|
|
7482025c10 | ||
|
|
909acb25fd | ||
|
|
4a9db99082 | ||
|
|
a2606c4fc4 | ||
|
|
647c609bf8 | ||
|
|
cf98025177 | ||
|
|
e0f20e9f82 | ||
|
|
597a5c9d75 | ||
|
|
d055908f4f | ||
|
|
f3eac6b259 | ||
|
|
87d6081408 | ||
|
|
dd53bd1c55 | ||
|
|
3ff033cdf3 | ||
|
|
c1c3b6a7e5 | ||
|
|
64d5a6acd5 | ||
|
|
e5b2e0a6b5 | ||
|
|
9895b45293 | ||
|
|
811fc43b63 | ||
|
|
9dcfa3ad6e | ||
|
|
67bda19458 | ||
|
|
6c38919c3d | ||
|
|
ce9445287c | ||
|
|
d4bd8862bd | ||
|
|
6904e023d3 | ||
|
|
91a7a77bb0 | ||
|
|
d9306e3e30 | ||
|
|
efdd3df129 | ||
|
|
63098d3c7d | ||
|
|
aa5781b550 | ||
|
|
d6e1862c08 | ||
|
|
9aa2831fef | ||
|
|
70eb29c1a9 | ||
|
|
13e07b1623 | ||
|
|
27ce1f8d44 | ||
|
|
38c20fc3c2 | ||
|
|
4a32b00068 | ||
|
|
3406f88fdc | ||
|
|
c96cb37680 | ||
|
|
0d415837a0 | ||
|
|
9dc48522d8 | ||
|
|
31b82a5d92 | ||
|
|
87ab4d9dd1 | ||
|
|
b6e7625016 | ||
|
|
c5e6bfce95 | ||
|
|
7a849b2899 | ||
|
|
999fa39d7c | ||
|
|
7de15ce5cf | ||
|
|
f792b0052f | ||
|
|
57d0b1d215 | ||
|
|
7691654cb8 | ||
|
|
c76e4b6b3c | ||
|
|
bda39cc6f6 | ||
|
|
060cdfea86 | ||
|
|
b1cc7b25ba | ||
|
|
1e0fe70dc3 | ||
|
|
8ed167c5fa | ||
|
|
dabf8414be | ||
|
|
a0eb64428e | ||
|
|
dd1beb1d91 | ||
|
|
bb35d71fdc | ||
|
|
42a7e86e51 | ||
|
|
2f3540dadc | ||
|
|
eb00641dfa | ||
|
|
bfe7bf2c11 | ||
|
|
e88c575d4a | ||
|
|
0de9c62675 | ||
|
|
9dc3847dbe | ||
|
|
9dc03c4f0f | ||
|
|
def21367a3 | ||
|
|
33fe1b6389 | ||
|
|
76cb5677b2 | ||
|
|
8c3b7f6417 | ||
|
|
e6c0f0f774 | ||
|
|
6bd5301828 | ||
|
|
73c0c4507a | ||
|
|
506b0806d6 | ||
|
|
054459d327 | ||
|
|
66ac4d6150 | ||
|
|
ab8e7897cc | ||
|
|
2b9133be90 | ||
|
|
56fece6216 | ||
|
|
d381836f01 | ||
|
|
c6efb588dc | ||
|
|
5404dfef08 | ||
|
|
cba12980f9 | ||
|
|
61700577d0 | ||
|
|
321f5d879d | ||
|
|
f98fdeab3f | ||
|
|
90179188b9 | ||
|
|
ccef155f7a | ||
|
|
f0a95032a5 | ||
|
|
c3ff5f2603 | ||
|
|
ee182ea684 | ||
|
|
7f73cc3085 | ||
|
|
dcf70b2847 | ||
|
|
cb5ba7edda | ||
|
|
7940ef24ab | ||
|
|
0f901b3728 | ||
|
|
09aba596ac | ||
|
|
b930ac7bf9 | ||
|
|
7f1bc4635a | ||
|
|
d4253d2025 | ||
|
|
b007fcb537 | ||
|
|
e6dd7d7684 | ||
|
|
128663d95b | ||
|
|
ef8b6d1a3d | ||
|
|
b4baebc230 | ||
|
|
b4581a7bbf | ||
|
|
a285dca39e | ||
|
|
00aa6d5ac3 | ||
|
|
027db285bc | ||
|
|
c3c9ba7e51 | ||
|
|
a1be63f890 | ||
|
|
f066f3f139 | ||
|
|
e17dcbb8eb | ||
|
|
1ae22c8606 | ||
|
|
d5569487a4 | ||
|
|
336e691dbc | ||
|
|
17a4d19beb | ||
|
|
74aa1ad71e | ||
|
|
f8c2f339a0 | ||
|
|
1dd66184a1 | ||
|
|
ddab8c1473 | ||
|
|
49d2c97ceb | ||
|
|
351a423337 | ||
|
|
07528be1e6 | ||
|
|
bc171f625a | ||
|
|
0f775e1e66 | ||
|
|
98fb874b29 | ||
|
|
cfd5c2a650 | ||
|
|
22a5b7faf6 | ||
|
|
fe262701c0 | ||
|
|
e1f71d3919 | ||
|
|
906cb95e67 | ||
|
|
f23c23f696 | ||
|
|
99c686e3e1 | ||
|
|
a144e35f84 | ||
|
|
5a5c5782a9 | ||
|
|
a2a5c30e60 | ||
|
|
3c4c466f8e | ||
|
|
6726826c17 | ||
|
|
e102cb1469 | ||
|
|
11671e85da | ||
|
|
b8614c60f9 | ||
|
|
269defa82d | ||
|
|
8bacc74d8b | ||
|
|
0c5efb935d | ||
|
|
a7f67c4bc9 | ||
|
|
edcaccba1f | ||
|
|
5ebecb4de3 | ||
|
|
9f3048c1dc | ||
|
|
2586268b81 | ||
|
|
280ddb4629 | ||
|
|
20889d7003 | ||
|
|
d4f4698c69 | ||
|
|
adcce61b52 | ||
|
|
17b913fb13 | ||
|
|
366ea1edc3 | ||
|
|
3a5a002be2 | ||
|
|
533fba8c70 | ||
|
|
7435bd7fb0 | ||
|
|
681b9b5ba3 | ||
|
|
600737c44f | ||
|
|
e5f3bed801 | ||
|
|
2fdc3169ce | ||
|
|
722264f634 | ||
|
|
a858ab5d0b | ||
|
|
63c1212ef1 | ||
|
|
2aa477176c | ||
|
|
6bb39451ea | ||
|
|
099a3c4642 | ||
|
|
9515520088 | ||
|
|
fe1a90bd39 | ||
|
|
65df137610 | ||
|
|
ced0c4d8f0 | ||
|
|
f3804429e4 | ||
|
|
a47981054f | ||
|
|
b9ad8bb700 | ||
|
|
47ad5ea98a | ||
|
|
840b42934b | ||
|
|
4527c03c0d | ||
|
|
89941a8e83 | ||
|
|
ebd4651ac2 | ||
|
|
861ab85ca1 | ||
|
|
f9154c4ed0 | ||
|
|
b91ebad8be | ||
|
|
e6baf8ef5b | ||
|
|
d326c7e3fa | ||
|
|
950126865e | ||
|
|
91f369a0b3 | ||
|
|
d1a9d3992b | ||
|
|
2dd2ad5cdb | ||
|
|
04c8c95634 | ||
|
|
8a56ede187 | ||
|
|
7425e80f05 | ||
|
|
97a9089ebf | ||
|
|
bee474f6e9 | ||
|
|
4740d44159 | ||
|
|
062b0b2165 | ||
|
|
8060cb7426 | ||
|
|
794e31505b | ||
|
|
50b120bc22 | ||
|
|
f0b2e445f6 | ||
|
|
782e70b171 | ||
|
|
9d2239291d | ||
|
|
a2891807f8 | ||
|
|
6a9556d42c | ||
|
|
724fe65d72 | ||
|
|
46612ef128 | ||
|
|
139ef5411a | ||
|
|
ac57000437 | ||
|
|
31234cb487 | ||
|
|
05e36a064f | ||
|
|
f88cbf3d4b | ||
|
|
7814ee0f7a | ||
|
|
9f4e5e4603 | ||
|
|
810fb45750 | ||
|
|
55e56a6788 | ||
|
|
ea7441ae77 | ||
|
|
f65e8824fb | ||
|
|
2868899d81 | ||
|
|
54dd05c556 | ||
|
|
6b25160e3f | ||
|
|
0ef3e19bc2 | ||
|
|
e89350d4b7 | ||
|
|
95399bef2b | ||
|
|
06c724df01 | ||
|
|
3325106837 | ||
|
|
9c72470c17 | ||
|
|
94cf307ae0 | ||
|
|
2cc1fde5e4 | ||
|
|
6796ac688a | ||
|
|
9551cfaf9b | ||
|
|
8ef9ec0567 | ||
|
|
af552fb4c0 | ||
|
|
ae7e5be5cd | ||
|
|
74b126f309 | ||
|
|
26e023058c | ||
|
|
6236590ca4 |
@@ -486,6 +486,9 @@ buildOpenAL() {
|
||||
-D CMAKE_INSTALL_PREFIX=$OPENAL_PATH \
|
||||
-D CMAKE_BUILD_TYPE=Release \
|
||||
-D LIBTYPE=STATIC \
|
||||
-D ALSOFT_EXAMPLES=OFF \
|
||||
-D ALSOFT_TESTS=OFF \
|
||||
-D ALSOFT_UTILS=OFF \
|
||||
..
|
||||
make $MAKE_ARGS
|
||||
sudo make install
|
||||
@@ -582,10 +585,10 @@ buildCustomQt() {
|
||||
info_msg "Downloading and building patched qt"
|
||||
|
||||
if [ -d "$EXTERNAL/qt${QT_VERSION}" ]; then
|
||||
rm -rf "$EXTERNAL/qt${QT_VERSION}"
|
||||
sudo rm -rf "$EXTERNAL/qt${QT_VERSION}"
|
||||
fi
|
||||
cd $QT_PATH
|
||||
rm -rf *
|
||||
sudo rm -rf *
|
||||
|
||||
cd "$EXTERNAL"
|
||||
git clone git://code.qt.io/qt/qt5.git qt${QT_VERSION}
|
||||
@@ -608,7 +611,7 @@ buildCustomQt() {
|
||||
./configure -prefix $QT_PATH -release -opensource -confirm-license -qt-zlib \
|
||||
-qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb \
|
||||
-qt-xkbcommon-x11 -no-opengl -no-gtkstyle -static \
|
||||
-nomake examples -nomake tests \
|
||||
-nomake examples -nomake tests -no-mirclient \
|
||||
-dbus-runtime -no-gstreamer -no-mtdev # <- Not sure about these
|
||||
make $MAKE_ARGS
|
||||
sudo make install
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Copyright (c) 2014-2018 John Preston, https://desktop.telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -15,27 +16,6 @@ GNU General Public License for more details.
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
More information about the Telegram project: https://telegram.org
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/flat_map.h"
|
||||
|
||||
namespace Dialogs {
|
||||
|
||||
class Row;
|
||||
using RowsByLetter = base::flat_map<QChar, Row*>;
|
||||
|
||||
enum class SortMode {
|
||||
Date = 0x00,
|
||||
Name = 0x01,
|
||||
Add = 0x02,
|
||||
};
|
||||
|
||||
enum class Mode {
|
||||
All = 0x00,
|
||||
Important = 0x01,
|
||||
};
|
||||
|
||||
} // namespace Dialogs
|
||||
1
LICENSE
@@ -4,6 +4,7 @@ version 3 with the addition of the following special exception:
|
||||
In addition, as a special exception, the copyright holders give
|
||||
permission to link the code of portions of this program with the OpenSSL
|
||||
library.
|
||||
|
||||
You must obey the GNU General Public License in all respects for all of
|
||||
the code used other than OpenSSL. If you modify file(s) with this
|
||||
exception, you may extend this exception to your version of the file(s),
|
||||
|
||||
@@ -15,7 +15,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
|
||||
* Windows XP - Windows 10 (**not** RT)
|
||||
* Mac OS X 10.8 - Mac OS X 10.11
|
||||
* Mac OS X 10.6 - Mac OS X 10.7 (separate build)
|
||||
* Ubuntu 12.04 - Ubuntu 16.04
|
||||
* Ubuntu 12.04 - Ubuntu 18.04
|
||||
* Fedora 22 - Fedora 24
|
||||
|
||||
## Third-party
|
||||
|
||||
107
Telegram/Patches/crashpad.diff
Normal file
@@ -0,0 +1,107 @@
|
||||
diff --git a/client/capture_context_mac_test.cc b/client/capture_context_mac_test.cc
|
||||
index 436ac5ad..8e14fb9c 100644
|
||||
--- a/client/capture_context_mac_test.cc
|
||||
+++ b/client/capture_context_mac_test.cc
|
||||
@@ -34,11 +34,11 @@ namespace {
|
||||
// gtest assertions.
|
||||
void SanityCheckContext(const NativeCPUContext& context) {
|
||||
#if defined(ARCH_CPU_X86)
|
||||
- ASSERT_EQ(x86_THREAD_STATE32, context.tsh.flavor);
|
||||
- ASSERT_EQ(implicit_cast<int>(x86_THREAD_STATE32_COUNT), context.tsh.count);
|
||||
+ ASSERT_EQ(implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32), implicit_cast<thread_state_flavor_t>(context.tsh.flavor));
|
||||
+ ASSERT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT), implicit_cast<uint32_t>(context.tsh.count));
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
- ASSERT_EQ(x86_THREAD_STATE64, context.tsh.flavor);
|
||||
- ASSERT_EQ(implicit_cast<int>(x86_THREAD_STATE64_COUNT), context.tsh.count);
|
||||
+ ASSERT_EQ(implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64), implicit_cast<thread_state_flavor_t>(context.tsh.flavor));
|
||||
+ ASSERT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT), implicit_cast<uint32_t>(context.tsh.count));
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
diff --git a/client/simulate_crash_mac.cc b/client/simulate_crash_mac.cc
|
||||
index 7e279015..27864388 100644
|
||||
--- a/client/simulate_crash_mac.cc
|
||||
+++ b/client/simulate_crash_mac.cc
|
||||
@@ -177,12 +177,12 @@ bool DeliverException(thread_t thread,
|
||||
|
||||
void SimulateCrash(const NativeCPUContext& cpu_context) {
|
||||
#if defined(ARCH_CPU_X86)
|
||||
- DCHECK_EQ(cpu_context.tsh.flavor,
|
||||
+ DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.tsh.flavor),
|
||||
implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32));
|
||||
DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count),
|
||||
x86_THREAD_STATE32_COUNT);
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
- DCHECK_EQ(cpu_context.tsh.flavor,
|
||||
+ DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.tsh.flavor),
|
||||
implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64));
|
||||
DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count),
|
||||
x86_THREAD_STATE64_COUNT);
|
||||
diff --git a/client/simulate_crash_mac_test.cc b/client/simulate_crash_mac_test.cc
|
||||
index 87c5f845..ca813e4c 100644
|
||||
--- a/client/simulate_crash_mac_test.cc
|
||||
+++ b/client/simulate_crash_mac_test.cc
|
||||
@@ -130,12 +130,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_thread_state*>(old_state);
|
||||
switch (state->tsh.flavor) {
|
||||
case x86_THREAD_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_THREAD_STATE32_COUNT),
|
||||
- state->tsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->tsh.count));
|
||||
break;
|
||||
case x86_THREAD_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_THREAD_STATE64_COUNT),
|
||||
- state->tsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->tsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected tsh.flavor " << state->tsh.flavor;
|
||||
@@ -149,12 +149,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_float_state*>(old_state);
|
||||
switch (state->fsh.flavor) {
|
||||
case x86_FLOAT_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_FLOAT_STATE32_COUNT),
|
||||
- state->fsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_FLOAT_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->fsh.count));
|
||||
break;
|
||||
case x86_FLOAT_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_FLOAT_STATE64_COUNT),
|
||||
- state->fsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_FLOAT_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->fsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected fsh.flavor " << state->fsh.flavor;
|
||||
@@ -168,12 +168,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_debug_state*>(old_state);
|
||||
switch (state->dsh.flavor) {
|
||||
case x86_DEBUG_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_DEBUG_STATE32_COUNT),
|
||||
- state->dsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_DEBUG_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->dsh.count));
|
||||
break;
|
||||
case x86_DEBUG_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_DEBUG_STATE64_COUNT),
|
||||
- state->dsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_DEBUG_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->dsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected dsh.flavor " << state->dsh.flavor;
|
||||
diff --git a/crashpad.gyp b/crashpad.gyp
|
||||
index 42fe0a26..d8af1bf1 100644
|
||||
--- a/crashpad.gyp
|
||||
+++ b/crashpad.gyp
|
||||
@@ -25,7 +25,7 @@
|
||||
'minidump/minidump.gyp:*',
|
||||
'minidump/minidump_test.gyp:*',
|
||||
'snapshot/snapshot.gyp:*',
|
||||
- 'snapshot/snapshot_test.gyp:*',
|
||||
+# 'snapshot/snapshot_test.gyp:*',
|
||||
'test/test.gyp:*',
|
||||
'test/test_test.gyp:*',
|
||||
'tools/tools.gyp:*',
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/build/crashpad.gypi b/build/crashpad.gypi
|
||||
index 027c7b6..4bfdfb5 100644
|
||||
index 027c7b68..4bfdfb5a 100644
|
||||
--- a/build/crashpad.gypi
|
||||
+++ b/build/crashpad.gypi
|
||||
@@ -25,5 +25,15 @@
|
||||
@@ -18,3 +18,110 @@ index 027c7b6..4bfdfb5 100644
|
||||
+ ],
|
||||
},
|
||||
}
|
||||
diff --git a/client/capture_context_mac_test.cc b/client/capture_context_mac_test.cc
|
||||
index 436ac5ad..8e14fb9c 100644
|
||||
--- a/client/capture_context_mac_test.cc
|
||||
+++ b/client/capture_context_mac_test.cc
|
||||
@@ -34,11 +34,11 @@ namespace {
|
||||
// gtest assertions.
|
||||
void SanityCheckContext(const NativeCPUContext& context) {
|
||||
#if defined(ARCH_CPU_X86)
|
||||
- ASSERT_EQ(x86_THREAD_STATE32, context.tsh.flavor);
|
||||
- ASSERT_EQ(implicit_cast<int>(x86_THREAD_STATE32_COUNT), context.tsh.count);
|
||||
+ ASSERT_EQ(implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32), implicit_cast<thread_state_flavor_t>(context.tsh.flavor));
|
||||
+ ASSERT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT), implicit_cast<uint32_t>(context.tsh.count));
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
- ASSERT_EQ(x86_THREAD_STATE64, context.tsh.flavor);
|
||||
- ASSERT_EQ(implicit_cast<int>(x86_THREAD_STATE64_COUNT), context.tsh.count);
|
||||
+ ASSERT_EQ(implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64), implicit_cast<thread_state_flavor_t>(context.tsh.flavor));
|
||||
+ ASSERT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT), implicit_cast<uint32_t>(context.tsh.count));
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_CPU_X86_FAMILY)
|
||||
diff --git a/client/simulate_crash_mac.cc b/client/simulate_crash_mac.cc
|
||||
index 7e279015..27864388 100644
|
||||
--- a/client/simulate_crash_mac.cc
|
||||
+++ b/client/simulate_crash_mac.cc
|
||||
@@ -177,12 +177,12 @@ bool DeliverException(thread_t thread,
|
||||
|
||||
void SimulateCrash(const NativeCPUContext& cpu_context) {
|
||||
#if defined(ARCH_CPU_X86)
|
||||
- DCHECK_EQ(cpu_context.tsh.flavor,
|
||||
+ DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.tsh.flavor),
|
||||
implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32));
|
||||
DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count),
|
||||
x86_THREAD_STATE32_COUNT);
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
- DCHECK_EQ(cpu_context.tsh.flavor,
|
||||
+ DCHECK_EQ(implicit_cast<thread_state_flavor_t>(cpu_context.tsh.flavor),
|
||||
implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64));
|
||||
DCHECK_EQ(implicit_cast<mach_msg_type_number_t>(cpu_context.tsh.count),
|
||||
x86_THREAD_STATE64_COUNT);
|
||||
diff --git a/client/simulate_crash_mac_test.cc b/client/simulate_crash_mac_test.cc
|
||||
index 87c5f845..ca813e4c 100644
|
||||
--- a/client/simulate_crash_mac_test.cc
|
||||
+++ b/client/simulate_crash_mac_test.cc
|
||||
@@ -130,12 +130,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_thread_state*>(old_state);
|
||||
switch (state->tsh.flavor) {
|
||||
case x86_THREAD_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_THREAD_STATE32_COUNT),
|
||||
- state->tsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->tsh.count));
|
||||
break;
|
||||
case x86_THREAD_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_THREAD_STATE64_COUNT),
|
||||
- state->tsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->tsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected tsh.flavor " << state->tsh.flavor;
|
||||
@@ -149,12 +149,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_float_state*>(old_state);
|
||||
switch (state->fsh.flavor) {
|
||||
case x86_FLOAT_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_FLOAT_STATE32_COUNT),
|
||||
- state->fsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_FLOAT_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->fsh.count));
|
||||
break;
|
||||
case x86_FLOAT_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_FLOAT_STATE64_COUNT),
|
||||
- state->fsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_FLOAT_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->fsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected fsh.flavor " << state->fsh.flavor;
|
||||
@@ -168,12 +168,12 @@ class TestSimulateCrashMac final : public MachMultiprocess,
|
||||
reinterpret_cast<const x86_debug_state*>(old_state);
|
||||
switch (state->dsh.flavor) {
|
||||
case x86_DEBUG_STATE32:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_DEBUG_STATE32_COUNT),
|
||||
- state->dsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_DEBUG_STATE32_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->dsh.count));
|
||||
break;
|
||||
case x86_DEBUG_STATE64:
|
||||
- EXPECT_EQ(implicit_cast<int>(x86_DEBUG_STATE64_COUNT),
|
||||
- state->dsh.count);
|
||||
+ EXPECT_EQ(implicit_cast<uint32_t>(x86_DEBUG_STATE64_COUNT),
|
||||
+ implicit_cast<uint32_t>(state->dsh.count));
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "unexpected dsh.flavor " << state->dsh.flavor;
|
||||
diff --git a/crashpad.gyp b/crashpad.gyp
|
||||
index 42fe0a26..d8af1bf1 100644
|
||||
--- a/crashpad.gyp
|
||||
+++ b/crashpad.gyp
|
||||
@@ -25,7 +25,7 @@
|
||||
'minidump/minidump.gyp:*',
|
||||
'minidump/minidump_test.gyp:*',
|
||||
'snapshot/snapshot.gyp:*',
|
||||
- 'snapshot/snapshot_test.gyp:*',
|
||||
+# 'snapshot/snapshot_test.gyp:*',
|
||||
'test/test.gyp:*',
|
||||
'test/test_test.gyp:*',
|
||||
'tools/tools.gyp:*',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/configure b/configure
|
||||
index cb8d78f..cadb3f0 100755
|
||||
index cb8d78fd3cb..cadb3f0a880 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -511,7 +511,8 @@ if [ "$BUILD_ON_MAC" = "yes" ]; then
|
||||
@@ -13,7 +13,7 @@ index cb8d78f..cadb3f0 100755
|
||||
echo " Xcode not set up properly. You may need to confirm the license" >&2
|
||||
echo " agreement by running /usr/bin/xcodebuild without arguments." >&2
|
||||
diff --git a/mkspecs/common/g++-macx.conf b/mkspecs/common/g++-macx.conf
|
||||
index 086510d..c485967 100644
|
||||
index 086510dd963..c485967863d 100644
|
||||
--- a/mkspecs/common/g++-macx.conf
|
||||
+++ b/mkspecs/common/g++-macx.conf
|
||||
@@ -14,7 +14,13 @@ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -gdwarf-2
|
||||
@@ -32,7 +32,7 @@ index 086510d..c485967 100644
|
||||
QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvmgcc42
|
||||
|
||||
diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf
|
||||
index 0cc8cd6..ca9725b 100644
|
||||
index 0cc8cd6dfdd..ca9725b7791 100644
|
||||
--- a/mkspecs/features/mac/default_pre.prf
|
||||
+++ b/mkspecs/features/mac/default_pre.prf
|
||||
@@ -12,7 +12,9 @@ isEmpty(QMAKE_XCODE_DEVELOPER_PATH) {
|
||||
@@ -47,7 +47,7 @@ index 0cc8cd6..ca9725b 100644
|
||||
}
|
||||
|
||||
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
|
||||
index bb79a13..5d595bc 100644
|
||||
index bb79a139b3c..5d595bc3b34 100644
|
||||
--- a/src/gui/image/qbmphandler.cpp
|
||||
+++ b/src/gui/image/qbmphandler.cpp
|
||||
@@ -220,6 +220,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
|
||||
@@ -74,7 +74,7 @@ index bb79a13..5d595bc 100644
|
||||
if (ncols > 0) { // read color table
|
||||
uchar rgb[4];
|
||||
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
|
||||
index ebff950..4300ca4 100644
|
||||
index ebff9509ab2..4300ca4c0f0 100644
|
||||
--- a/src/gui/painting/qpaintengine_p.h
|
||||
+++ b/src/gui/painting/qpaintengine_p.h
|
||||
@@ -87,8 +87,18 @@ public:
|
||||
@@ -98,7 +98,7 @@ index ebff950..4300ca4 100644
|
||||
|
||||
// Make sure we're inside the viewport.
|
||||
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
|
||||
index 4879ae5..56cdcba 100644
|
||||
index 4879ae51d7d..56cdcbaf01c 100644
|
||||
--- a/src/gui/text/qtextlayout.cpp
|
||||
+++ b/src/gui/text/qtextlayout.cpp
|
||||
@@ -654,6 +654,9 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
|
||||
@@ -175,7 +175,7 @@ index 4879ae5..56cdcba 100644
|
||||
|
||||
inline void resetRightBearing()
|
||||
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
|
||||
index cbe42c3..b273db7 100644
|
||||
index cbe42c38444..b273db7e78c 100644
|
||||
--- a/src/gui/text/qtextlayout.h
|
||||
+++ b/src/gui/text/qtextlayout.h
|
||||
@@ -194,6 +194,9 @@ private:
|
||||
@@ -188,8 +188,21 @@ index cbe42c3..b273db7 100644
|
||||
};
|
||||
|
||||
|
||||
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
|
||||
index 360f9722c70..f28f289ef6a 100644
|
||||
--- a/src/network/access/qhttpnetworkconnection.cpp
|
||||
+++ b/src/network/access/qhttpnetworkconnection.cpp
|
||||
@@ -118,6 +118,8 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
|
||||
{
|
||||
for (int i = 0; i < channelCount; ++i) {
|
||||
if (channels[i].socket) {
|
||||
+ // Patch: backport critical bugfix from '4f959b6b30' commit.
|
||||
+ QObject::disconnect(channels[i].socket, Q_NULLPTR, &channels[i], Q_NULLPTR);
|
||||
channels[i].socket->close();
|
||||
delete channels[i].socket;
|
||||
}
|
||||
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
index ca7afb7..25ae500 100644
|
||||
index ca7afb7d1b9..25ae50008db 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
|
||||
@@ -256,6 +256,13 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
|
||||
@@ -206,8 +219,22 @@ index ca7afb7..25ae500 100644
|
||||
fd->styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
|
||||
fd->weight = QFont::Normal;
|
||||
fd->style = QFont::StyleNormal;
|
||||
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
index 6e2c8a2a9af..3cace8abcbc 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
@@ -717,7 +717,8 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metric
|
||||
|
||||
QFixed QCoreTextFontEngine::emSquareSize() const
|
||||
{
|
||||
- return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
+ // Patch: Fix build for Xcode 9.3.1.
|
||||
+ return QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
}
|
||||
|
||||
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
index 92358ec..694fee7 100644
|
||||
index 92358ecc745..694fee73507 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
|
||||
@@ -213,7 +213,8 @@ static void cleanupCocoaApplicationDelegate()
|
||||
@@ -244,7 +271,7 @@ index 92358ec..694fee7 100644
|
||||
|
||||
- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
|
||||
index b81b9a0..4e59e83 100644
|
||||
index b81b9a0b1c2..4e59e833b1d 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
|
||||
@@ -81,7 +81,7 @@ void QCocoaCursor::setPos(const QPoint &position)
|
||||
@@ -256,8 +283,41 @@ index b81b9a0..4e59e83 100644
|
||||
CGEventPost(kCGHIDEventTap, e);
|
||||
CFRelease(e);
|
||||
}
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
|
||||
index 9850f83dea8..b2e1d3dfda7 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
|
||||
@@ -649,9 +649,10 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm
|
||||
// Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev)
|
||||
OSStatus err = noErr;
|
||||
|
||||
- require_action(inContext != NULL, InvalidContext, err = paramErr);
|
||||
- require_action(inBounds != NULL, InvalidBounds, err = paramErr);
|
||||
- require_action(inImage != NULL, InvalidImage, err = paramErr);
|
||||
+ // Patch: Fix build on latest Xcode.
|
||||
+ //require_action(inContext != NULL, InvalidContext, err = paramErr);
|
||||
+ //require_action(inBounds != NULL, InvalidBounds, err = paramErr);
|
||||
+ //require_action(inImage != NULL, InvalidImage, err = paramErr);
|
||||
|
||||
CGContextSaveGState( inContext );
|
||||
CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds));
|
||||
@@ -660,9 +661,11 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm
|
||||
CGContextDrawImage(inContext, *inBounds, inImage);
|
||||
|
||||
CGContextRestoreGState(inContext);
|
||||
-InvalidImage:
|
||||
-InvalidBounds:
|
||||
-InvalidContext:
|
||||
+
|
||||
+// Patch: Fix build on latest Xcode.
|
||||
+//InvalidImage:
|
||||
+//InvalidBounds:
|
||||
+//InvalidContext:
|
||||
return err;
|
||||
}
|
||||
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
|
||||
index 9fd05a6..dea6072 100644
|
||||
index 9fd05a65ee9..dea60720e78 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
|
||||
@@ -402,14 +402,24 @@ void QCocoaIntegration::updateScreens()
|
||||
@@ -288,7 +348,7 @@ index 9fd05a6..dea6072 100644
|
||||
|
||||
QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
|
||||
index e46eaff..c62db53 100644
|
||||
index e46eaff6be3..c62db534a2d 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
|
||||
@@ -382,6 +382,12 @@ bool QCocoaKeyMapper::updateKeyboard()
|
||||
@@ -315,7 +375,7 @@ index e46eaff..c62db53 100644
|
||||
}
|
||||
return ret;
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
index 83c960d..03ae969 100755
|
||||
index 83c960d9317..03ae9696afe 100755
|
||||
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
|
||||
@@ -102,7 +102,10 @@ QT_USE_NAMESPACE
|
||||
@@ -483,7 +543,7 @@ index 83c960d..03ae969 100755
|
||||
}
|
||||
@end
|
||||
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
index 4d0458a..3357a5e 100644
|
||||
index 4d0458a4aa2..3357a5ef817 100644
|
||||
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
|
||||
@@ -167,7 +167,8 @@ static bool isMouseEvent(NSEvent *ev)
|
||||
@@ -546,7 +606,7 @@ index 4d0458a..3357a5e 100644
|
||||
[iconButton setImage:image];
|
||||
[image release];
|
||||
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
|
||||
index a18ee7f..1f91feb 100644
|
||||
index a18ee7ff71d..1f91feb0ae8 100644
|
||||
--- a/src/plugins/platforms/cocoa/qnsview.mm
|
||||
+++ b/src/plugins/platforms/cocoa/qnsview.mm
|
||||
@@ -393,7 +393,9 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
||||
@@ -615,7 +675,7 @@ index a18ee7f..1f91feb 100644
|
||||
}
|
||||
return [super performKeyEquivalent:nsevent];
|
||||
diff --git a/src/tools/qlalr/lalr.cpp b/src/tools/qlalr/lalr.cpp
|
||||
index c680764..e2a7aaf 100644
|
||||
index c68076477f3..e2a7aafa586 100644
|
||||
--- a/src/tools/qlalr/lalr.cpp
|
||||
+++ b/src/tools/qlalr/lalr.cpp
|
||||
@@ -246,11 +246,13 @@ void Grammar::buildExtendedGrammar ()
|
||||
@@ -655,7 +715,7 @@ index c680764..e2a7aaf 100644
|
||||
continue;
|
||||
|
||||
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
|
||||
index 7396808..7178aec 100644
|
||||
index 7396808442e..7178aecf800 100644
|
||||
--- a/src/widgets/kernel/qwidget.cpp
|
||||
+++ b/src/widgets/kernel/qwidget.cpp
|
||||
@@ -4722,6 +4722,17 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
|
||||
@@ -708,7 +768,7 @@ index 7396808..7178aec 100644
|
||||
|| (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
|
||||
res = focusNextPrevChild(false);
|
||||
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
|
||||
index 0845a5e..5735cb6 100644
|
||||
index 0845a5eb02f..5735cb6b396 100644
|
||||
--- a/src/widgets/styles/qmacstyle_mac.mm
|
||||
+++ b/src/widgets/styles/qmacstyle_mac.mm
|
||||
@@ -3667,9 +3667,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
@@ -726,7 +786,7 @@ index 0845a5e..5735cb6 100644
|
||||
}
|
||||
|
||||
diff --git a/src/widgets/util/qsystemtrayicon_qpa.cpp b/src/widgets/util/qsystemtrayicon_qpa.cpp
|
||||
index f98aeaf..00c0734 100644
|
||||
index f98aeaf6782..00c0734129e 100644
|
||||
--- a/src/widgets/util/qsystemtrayicon_qpa.cpp
|
||||
+++ b/src/widgets/util/qsystemtrayicon_qpa.cpp
|
||||
@@ -99,13 +99,18 @@ void QSystemTrayIconPrivate::updateIcon_sys()
|
||||
@@ -755,7 +815,7 @@ index f98aeaf..00c0734 100644
|
||||
}
|
||||
|
||||
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
index 75f3059..980f2be 100644
|
||||
index 75f30599be4..980f2be1e93 100644
|
||||
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
|
||||
@@ -1867,7 +1867,8 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
|
||||
@@ -769,7 +829,7 @@ index 75f3059..980f2be 100644
|
||||
#ifndef QT_NO_COMPLETER
|
||||
complete(event->key());
|
||||
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
index 96438a0..b0b7206 100644
|
||||
index 96438a0bdf7..b0b72064056 100644
|
||||
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
|
||||
@@ -1342,7 +1342,8 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
|
||||
|
||||
@@ -221,6 +221,19 @@ index f74d4d4229..8ad672c9fe 100644
|
||||
};
|
||||
|
||||
|
||||
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
|
||||
index c4cb8e65c0..45793e364f 100644
|
||||
--- a/src/network/access/qhttpnetworkconnection.cpp
|
||||
+++ b/src/network/access/qhttpnetworkconnection.cpp
|
||||
@@ -110,6 +110,8 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
|
||||
{
|
||||
for (int i = 0; i < channelCount; ++i) {
|
||||
if (channels[i].socket) {
|
||||
+ // Patch: backport critical bugfix from '4f959b6b30' commit.
|
||||
+ QObject::disconnect(channels[i].socket, Q_NULLPTR, &channels[i], Q_NULLPTR);
|
||||
channels[i].socket->close();
|
||||
delete channels[i].socket;
|
||||
}
|
||||
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
|
||||
index 41834b21ae..8cdf4ab145 100644
|
||||
--- a/src/network/socket/qnativesocketengine_win.cpp
|
||||
@@ -417,6 +430,20 @@ index 566abf2126..5b9c714ffa 100644
|
||||
fd->styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
|
||||
fd->weight = QFont::Normal;
|
||||
fd->style = QFont::StyleNormal;
|
||||
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
index 7b459584ea..2ed2fd9b3b 100644
|
||||
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
|
||||
@@ -764,7 +764,8 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, gl
|
||||
|
||||
QFixed QCoreTextFontEngine::emSquareSize() const
|
||||
{
|
||||
- return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
+ // Patch: Fix build for Xcode 9.3.1.
|
||||
+ return QFixed(int(CTFontGetUnitsPerEm(ctfont)));
|
||||
}
|
||||
|
||||
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
|
||||
diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
|
||||
index 86bdd4729b..9b9c8ded08 100644
|
||||
--- a/src/plugins/platforminputcontexts/compose/compose.pro
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
using "colors.palette";
|
||||
|
||||
@@ -53,7 +40,7 @@ lineWidth: 1px;
|
||||
|
||||
defaultTextPalette: TextPalette {
|
||||
linkFg: windowActiveTextFg;
|
||||
monoFg: windowSubTextFg;
|
||||
monoFg: msgInMonoFg;
|
||||
selectBg: msgInBgSelected;
|
||||
selectFg: transparent; // use painter current pen instead
|
||||
selectLinkFg: historyLinkInFgSelected;
|
||||
@@ -185,6 +172,21 @@ inFwdTextPaletteSelected: TextPalette(defaultTextPalette) {
|
||||
outFwdTextPaletteSelected: TextPalette(defaultTextPalette) {
|
||||
linkFg: msgOutServiceFgSelected;
|
||||
}
|
||||
inReplyTextPalette: TextPalette(inTextPalette) {
|
||||
linkFg: msgInDateFg;
|
||||
}
|
||||
inReplyTextPaletteSelected: TextPalette(inTextPaletteSelected) {
|
||||
linkFg: msgInDateFgSelected;
|
||||
}
|
||||
outReplyTextPalette: TextPalette(outTextPalette) {
|
||||
linkFg: msgOutDateFg;
|
||||
}
|
||||
outReplyTextPaletteSelected: TextPalette(outTextPaletteSelected) {
|
||||
linkFg: msgOutDateFgSelected;
|
||||
}
|
||||
imgReplyTextPalette: TextPalette(defaultTextPalette) {
|
||||
linkFg: msgImgReplyBarColor;
|
||||
}
|
||||
inSemiboldPalette: TextPalette(inTextPalette) {
|
||||
linkFg: msgInServiceFg;
|
||||
selectFg: msgInServiceFgSelected;
|
||||
@@ -195,6 +197,9 @@ outSemiboldPalette: TextPalette(outTextPalette) {
|
||||
selectFg: msgOutServiceFgSelected;
|
||||
selectLinkFg: msgOutServiceFgSelected;
|
||||
}
|
||||
historyComposeAreaPalette: TextPalette(defaultTextPalette) {
|
||||
linkFg: historyComposeAreaFgService;
|
||||
}
|
||||
|
||||
mediaCaptionSkip: 5px;
|
||||
mediaInBubbleSkip: 5px;
|
||||
@@ -228,8 +233,6 @@ emojiReplaceHeight: 56px;
|
||||
emojiReplaceInnerHeight: 42px;
|
||||
emojiReplacePadding: 14px;
|
||||
|
||||
connectingPadding: margins(5px, 5px, 5px, 5px);
|
||||
|
||||
dragFont: font(28px semibold);
|
||||
dragSubfont: font(20px semibold);
|
||||
dragColor: windowSubTextFg;
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
// basic
|
||||
|
||||
BIN
Telegram/Resources/icons/connecting_body.png
Normal file
|
After Width: | Height: | Size: 95 B |
BIN
Telegram/Resources/icons/connecting_body@2x.png
Normal file
|
After Width: | Height: | Size: 112 B |
BIN
Telegram/Resources/icons/connecting_body_shadow.png
Normal file
|
After Width: | Height: | Size: 117 B |
BIN
Telegram/Resources/icons/connecting_body_shadow@2x.png
Normal file
|
After Width: | Height: | Size: 151 B |
BIN
Telegram/Resources/icons/connecting_left.png
Normal file
|
After Width: | Height: | Size: 357 B |
BIN
Telegram/Resources/icons/connecting_left@2x.png
Normal file
|
After Width: | Height: | Size: 717 B |
BIN
Telegram/Resources/icons/connecting_left_shadow.png
Normal file
|
After Width: | Height: | Size: 550 B |
BIN
Telegram/Resources/icons/connecting_left_shadow@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/connecting_right.png
Normal file
|
After Width: | Height: | Size: 347 B |
BIN
Telegram/Resources/icons/connecting_right@2x.png
Normal file
|
After Width: | Height: | Size: 679 B |
BIN
Telegram/Resources/icons/connecting_right_shadow.png
Normal file
|
After Width: | Height: | Size: 573 B |
BIN
Telegram/Resources/icons/connecting_right_shadow@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/dialogs_feed.png
Normal file
|
After Width: | Height: | Size: 328 B |
BIN
Telegram/Resources/icons/dialogs_feed@2x.png
Normal file
|
After Width: | Height: | Size: 626 B |
BIN
Telegram/Resources/icons/info_feed.png
Normal file
|
After Width: | Height: | Size: 748 B |
BIN
Telegram/Resources/icons/info_feed@2x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Telegram/Resources/icons/passport_authorize.png
Normal file
|
After Width: | Height: | Size: 362 B |
BIN
Telegram/Resources/icons/passport_authorize@2x.png
Normal file
|
After Width: | Height: | Size: 756 B |
BIN
Telegram/Resources/icons/passport_empty.png
Normal file
|
After Width: | Height: | Size: 346 B |
BIN
Telegram/Resources/icons/passport_empty@2x.png
Normal file
|
After Width: | Height: | Size: 688 B |
BIN
Telegram/Resources/icons/passport_password_setup.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
Telegram/Resources/icons/passport_password_setup@2x.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Telegram/Resources/icons/passport_ready.png
Normal file
|
After Width: | Height: | Size: 369 B |
BIN
Telegram/Resources/icons/passport_ready@2x.png
Normal file
|
After Width: | Height: | Size: 655 B |
BIN
Telegram/Resources/icons/proxy_off.png
Normal file
|
After Width: | Height: | Size: 529 B |
BIN
Telegram/Resources/icons/proxy_off@2x.png
Normal file
|
After Width: | Height: | Size: 1012 B |
BIN
Telegram/Resources/icons/proxy_on.png
Normal file
|
After Width: | Height: | Size: 584 B |
BIN
Telegram/Resources/icons/proxy_on@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/stickers_empty.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
Telegram/Resources/icons/stickers_empty@2x.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
Telegram/Resources/icons/stickers_search.png
Normal file
|
After Width: | Height: | Size: 493 B |
BIN
Telegram/Resources/icons/stickers_search@2x.png
Normal file
|
After Width: | Height: | Size: 926 B |
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "English";
|
||||
"lng_switch_to_this" = "Continue in English";
|
||||
@@ -36,6 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_quit_from_tray" = "Quit Telegram";
|
||||
"lng_tray_icon_text" = "Telegram is still running here,\nyou can change this from settings page.\nIf this icon disappears from tray menu,\nyou can drag it here from hidden icons.";
|
||||
|
||||
// For lng_month_year or plain month name.
|
||||
"lng_month1" = "January";
|
||||
"lng_month2" = "February";
|
||||
"lng_month3" = "March";
|
||||
@@ -49,6 +37,20 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_month11" = "November";
|
||||
"lng_month12" = "December";
|
||||
|
||||
// For lng_month_day and lng_month_day_year.
|
||||
"lng_month_day1" = "January";
|
||||
"lng_month_day2" = "February";
|
||||
"lng_month_day3" = "March";
|
||||
"lng_month_day4" = "April";
|
||||
"lng_month_day5" = "May";
|
||||
"lng_month_day6" = "June";
|
||||
"lng_month_day7" = "July";
|
||||
"lng_month_day8" = "August";
|
||||
"lng_month_day9" = "September";
|
||||
"lng_month_day10" = "October";
|
||||
"lng_month_day11" = "November";
|
||||
"lng_month_day12" = "December";
|
||||
|
||||
"lng_month1_small" = "Jan";
|
||||
"lng_month2_small" = "Feb";
|
||||
"lng_month3_small" = "Mar";
|
||||
@@ -136,6 +138,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_error_cant_add_admin_invite" = "Sorry, you can't add this user as an admin because they are not a member of this group and you are not allowed to invite them.";
|
||||
"lng_error_cant_add_admin_unban" = "Sorry, you can't add this user as an admin because they are in the blacklist and you can't unban them.";
|
||||
"lng_error_cant_ban_admin" = "Sorry, you can't ban this user because they are an admin in this group and you are not allowed to demote them.";
|
||||
"lng_error_admin_limit" = "Sorry, you've reached the maximum number of admins for this group.";
|
||||
"lng_error_admin_limit_channel" = "Sorry, you've reached the maximum number of admins for this channel.";
|
||||
"lng_sure_add_admin_invite" = "This user is not a member of this group. Add them to the group and promote them to admin?";
|
||||
"lng_sure_add_admin_invite_channel" = "This user is not a subscriber of this channel. Add them to the channel and promote them to admin?";
|
||||
"lng_sure_add_admin_unban" = "This user is currently restricted or banned. Are you sure you want to unban and promote them?";
|
||||
@@ -192,19 +196,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_signin_title" = "Cloud password check";
|
||||
"lng_signin_desc" = "Please enter your cloud password.";
|
||||
"lng_signin_recover_desc" = "Please enter the code from the e-mail\n{email}";
|
||||
"lng_signin_recover_desc" = "Please enter the code from the email\n{email}";
|
||||
"lng_signin_password" = "Your cloud password";
|
||||
"lng_signin_code" = "Code from e-mail";
|
||||
"lng_signin_code" = "Code from email";
|
||||
"lng_signin_recover" = "Forgot password?";
|
||||
"lng_signin_recover_title" = "Password reset";
|
||||
"lng_signin_hint" = "Hint: {password_hint}";
|
||||
"lng_signin_recover_hint" = "Code was sent to {recover_email}";
|
||||
"lng_signin_bad_password" = "You have entered a wrong password.";
|
||||
"lng_signin_wrong_code" = "You have entered an invalid code.";
|
||||
"lng_signin_try_password" = "Having trouble accessing your e-mail?";
|
||||
"lng_signin_try_password" = "Having trouble accessing your email?";
|
||||
"lng_signin_password_removed" = "Your cloud password was disabled.\nYou can set up a new one in Settings.";
|
||||
"lng_signin_no_email_forgot" = "Since you didn't provide a recovery e-mail when setting up your password, your remaining options are either to remember your password or to reset your account.";
|
||||
"lng_signin_cant_email_forgot" = "If you can't restore access to the e-mail, your remaining options are either to remember your password or to reset your account.";
|
||||
"lng_signin_no_email_forgot" = "Since you didn't provide a recovery email when setting up your password, your remaining options are either to remember your password or to reset your account.";
|
||||
"lng_signin_cant_email_forgot" = "If you can't restore access to the email, your remaining options are either to remember your password or to reset your account.";
|
||||
"lng_signin_reset_account" = "Reset your account";
|
||||
"lng_signin_sure_reset" = "Warning!\n\nYou will lose all your chats and messages, along with any media and files you shared!\n\nDo you want to reset your account?";
|
||||
"lng_signin_reset" = "Reset";
|
||||
@@ -309,6 +313,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_settings_section_chat_settings" = "Chat Settings";
|
||||
"lng_settings_replace_emojis" = "Replace emoji";
|
||||
"lng_settings_suggest_emoji" = "Suggest emoji replacements";
|
||||
"lng_settings_suggest_by_emoji" = "Suggest popular stickers by emoji";
|
||||
"lng_settings_view_emojis" = "View list";
|
||||
"lng_settings_send_enter" = "Send by Enter";
|
||||
"lng_settings_send_ctrlenter" = "Send by Ctrl+Enter";
|
||||
@@ -403,18 +409,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_cloud_password_hint" = "Enter password hint";
|
||||
"lng_cloud_password_change_hint" = "Enter new password hint";
|
||||
"lng_cloud_password_bad" = "Password and hint cannot be the same.";
|
||||
"lng_cloud_password_email" = "Enter recovery e-mail";
|
||||
"lng_cloud_password_bad_email" = "Incorrect e-mail, please try other.";
|
||||
"lng_cloud_password_email" = "Enter recovery email";
|
||||
"lng_cloud_password_bad_email" = "Incorrect email, please try other.";
|
||||
"lng_cloud_password_about" = "This password will be asked when you log in on a new device in addition to the SMS code.";
|
||||
"lng_cloud_password_about_recover" = "Warning! Are you sure you don't want to\nadd a password recovery e-mail?\n\nIf you forget your password, you will\nlose access to your Telegram account.";
|
||||
"lng_cloud_password_skip_email" = "Skip e-mail";
|
||||
"lng_cloud_password_almost" = "A confirmation link was sent to the\ne-mail you provided. Two-step verification will be enabled as soon as you follow that link.";
|
||||
"lng_cloud_password_about_recover" = "Warning! Are you sure you don't want to\nadd a password recovery email?\n\nIf you forget your password, you will\nlose access to your Telegram account.";
|
||||
"lng_cloud_password_skip_email" = "Skip email";
|
||||
"lng_cloud_password_almost" = "A confirmation link was sent to the\nemail you provided. Two-step verification will be enabled as soon as you follow that link.";
|
||||
"lng_cloud_password_was_set" = "Two-step verification enabled.";
|
||||
"lng_cloud_password_updated" = "Your cloud password was updated.";
|
||||
"lng_cloud_password_removed" = "Two-step verification was disabled.";
|
||||
"lng_cloud_password_differ" = "Passwords do not match";
|
||||
"lng_cloud_password_wrong" = "Wrong cloud password";
|
||||
"lng_cloud_password_is_same" = "Password was not changed";
|
||||
"lng_cloud_password_passport_losing" = "Warning! All data saved in your Telegram Passport will be lost!";
|
||||
|
||||
"lng_connection_type" = "Connection type:";
|
||||
"lng_connection_auto_connecting" = "Default (connecting...)";
|
||||
@@ -430,8 +437,33 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_connection_port_ph" = "Port";
|
||||
"lng_connection_user_ph" = "Username";
|
||||
"lng_connection_password_ph" = "Password";
|
||||
"lng_connection_proxy_secret_ph" = "Secret";
|
||||
"lng_connection_save" = "Save";
|
||||
|
||||
"lng_proxy_settings" = "Proxy settings";
|
||||
"lng_proxy_use" = "Use proxy";
|
||||
"lng_proxy_use_for_calls" = "Use proxy for calls";
|
||||
"lng_proxy_about" = "Proxy servers may be helpful in accessing Telegram if there is no connection in a specific region.";
|
||||
"lng_proxy_add" = "Add proxy";
|
||||
"lng_proxy_share" = "Share";
|
||||
"lng_proxy_online" = "connected";
|
||||
"lng_proxy_checking" = "checking";
|
||||
"lng_proxy_connecting" = "connecting";
|
||||
"lng_proxy_available" = "available, {ping} ms ping";
|
||||
"lng_proxy_unavailable" = "not available";
|
||||
"lng_proxy_edit" = "Edit proxy";
|
||||
"lng_proxy_menu_edit" = "Edit";
|
||||
"lng_proxy_menu_delete" = "Delete";
|
||||
"lng_proxy_menu_restore" = "Restore";
|
||||
"lng_proxy_edit_share" = "Share";
|
||||
"lng_proxy_address_label" = "Socket address";
|
||||
"lng_proxy_credentials_optional" = "Credentials (optional)";
|
||||
"lng_proxy_credentials" = "Credentials";
|
||||
"lng_proxy_description" = "Your saved proxy list will be here.";
|
||||
"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_settings_blocked_users" = "Blocked users";
|
||||
"lng_settings_last_seen_privacy" = "Last seen privacy";
|
||||
"lng_settings_calls_privacy" = "Phone calls privacy";
|
||||
@@ -541,6 +573,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_actions_section" = "Actions";
|
||||
"lng_profile_bot_settings" = "Bot Settings";
|
||||
"lng_profile_bot_help" = "Bot Help";
|
||||
"lng_profile_bot_privacy" = "Bot Privacy Policy";
|
||||
"lng_profile_invite_link_section" = "Invite link";
|
||||
"lng_profile_create_public_link" = "Create public link";
|
||||
"lng_profile_edit_public_link" = "Edit public link";
|
||||
@@ -680,6 +713,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_report_title" = "Report channel";
|
||||
"lng_report_group_title" = "Report group";
|
||||
"lng_report_bot_title" = "Report bot";
|
||||
"lng_report_message_title" = "Report message";
|
||||
"lng_report_reason_spam" = "Spam";
|
||||
"lng_report_reason_violence" = "Violence";
|
||||
"lng_report_reason_pornography" = "Pornography";
|
||||
@@ -806,6 +840,14 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_action_payment_done_for" = "You have just successfully transferred {amount} to {user} for {invoice}";
|
||||
"lng_action_took_screenshot" = "{from} took a screenshot!";
|
||||
"lng_action_you_took_screenshot" = "You took a screenshot!";
|
||||
"lng_action_bot_allowed_from_domain" = "You allowed this bot to message you when you logged in on {domain}.";
|
||||
"lng_action_secure_values_sent" = "{user} received the following documents: {documents}";
|
||||
"lng_action_secure_personal_details" = "personal details";
|
||||
"lng_action_secure_proof_of_identity" = "proof of identity";
|
||||
"lng_action_secure_address" = "address";
|
||||
"lng_action_secure_proof_of_address" = "proof of address";
|
||||
"lng_action_secure_phone" = "phone number";
|
||||
"lng_action_secure_email" = "email address";
|
||||
|
||||
"lng_ttl_photo_received" = "{from} sent you a self-destructing photo. Please view it on your mobile.";
|
||||
"lng_ttl_photo_sent" = "You sent a self-destructing photo.";
|
||||
@@ -831,6 +873,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_channel_not_accessible" = "Sorry, this channel is not accessible.";
|
||||
"lng_group_not_accessible" = "Sorry, this group is not accessible.";
|
||||
"lng_group_full" = "Sorry, this group is full.";
|
||||
|
||||
"lng_channels_too_much_public_about" = "Sorry, you have reserved too many public usernames. You can revoke the link from one of your older groups or channels.";
|
||||
"lng_channels_too_much_public_revoke_confirm_group" = "Are you sure you want to revoke the link {link}?\n\nThe group «{group}» will become private.";
|
||||
@@ -863,6 +906,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_edited" = "edited";
|
||||
"lng_edited_date" = "Edited: {date}";
|
||||
"lng_admin_badge" = "admin";
|
||||
"lng_fast_reply" = "Reply";
|
||||
"lng_cancel_edit_post_sure" = "Cancel editing?";
|
||||
"lng_cancel_edit_post_yes" = "Yes";
|
||||
"lng_cancel_edit_post_no" = "No";
|
||||
@@ -937,6 +981,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_stickers_remove_group_set" = "Remove group sticker set?";
|
||||
"lng_stickers_group_from_your" = "Choose from your stickers";
|
||||
"lng_stickers_group_from_featured" = "Choose from trending stickers";
|
||||
"lng_stickers_search_sets" = "Search sticker sets";
|
||||
"lng_stickers_nothing_found" = "No stickers found";
|
||||
"lng_stickers_remove_pack_confirm" = "Remove";
|
||||
|
||||
"lng_in_dlg_photo" = "Photo";
|
||||
"lng_in_dlg_album" = "Album";
|
||||
@@ -1036,6 +1083,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_user_action_upload_file" = "{user} is sending a file";
|
||||
"lng_unread_bar#one" = "{count} unread message";
|
||||
"lng_unread_bar#other" = "{count} unread messages";
|
||||
"lng_unread_bar_some" = "Unread messages";
|
||||
|
||||
"lng_maps_point" = "Location";
|
||||
"lng_save_photo" = "Save image";
|
||||
@@ -1054,6 +1102,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_context_view_profile" = "View profile";
|
||||
"lng_context_view_group" = "View group info";
|
||||
"lng_context_view_channel" = "View channel info";
|
||||
"lng_context_view_feed_info" = "View feed info";
|
||||
"lng_context_pin_to_top" = "Pin to top";
|
||||
"lng_context_unpin_from_top" = "Unpin from top";
|
||||
|
||||
@@ -1087,6 +1136,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_context_forward_msg" = "Forward Message";
|
||||
"lng_context_delete_msg" = "Delete Message";
|
||||
"lng_context_select_msg" = "Select Message";
|
||||
"lng_context_report_msg" = "Report Message";
|
||||
"lng_context_pin_msg" = "Pin Message";
|
||||
"lng_context_unpin_msg" = "Unpin Message";
|
||||
"lng_context_cancel_upload" = "Cancel Upload";
|
||||
@@ -1229,6 +1279,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_new_version_minor" = "— Bug fixes and other minor improvements";
|
||||
|
||||
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
||||
"lng_menu_formatting" = "Formatting";
|
||||
"lng_menu_formatting_bold" = "Bold";
|
||||
"lng_menu_formatting_italic" = "Italic";
|
||||
"lng_menu_formatting_monospace" = "Monospace";
|
||||
"lng_menu_formatting_link_create" = "Create link";
|
||||
"lng_menu_formatting_link_edit" = "Edit link";
|
||||
"lng_menu_formatting_clear" = "Plain text";
|
||||
"lng_formatting_link_create_title" = "Create link";
|
||||
"lng_formatting_link_edit_title" = "Create link";
|
||||
"lng_formatting_link_text" = "Text";
|
||||
"lng_formatting_link_url" = "URL";
|
||||
"lng_formatting_link_create" = "Create";
|
||||
|
||||
"lng_full_name" = "{first_name} {last_name}";
|
||||
|
||||
@@ -1427,6 +1489,170 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_admin_log_admin_pin_messages" = "Pin messages";
|
||||
"lng_admin_log_admin_add_admins" = "Add new admins";
|
||||
|
||||
"lng_feed_name" = "Feed";
|
||||
"lng_feed_show_next" = "Show Next";
|
||||
|
||||
"lng_feed_group" = "Group in feed";
|
||||
"lng_feed_ungroup" = "Ungroup from feed";
|
||||
"lng_feed_channel_added" = "Channel added to your feed.";
|
||||
"lng_feed_channel_removed" = "Channel removed from your feed.";
|
||||
"lng_feed_no_messages" = "No messages in this feed yet";
|
||||
"lng_feed_channels#one" = "{count} channel";
|
||||
"lng_feed_channels#other" = "{count} channels";
|
||||
"lng_feed_notifications" = "Feed notifications";
|
||||
"lng_feed_ungroup_all" = "Ungroup all channels";
|
||||
"lng_feed_sure_ungroup_all" = "Are you sure you want to ungroup all channels from this feed?";
|
||||
"lng_feed_ungroup_sure" = "Ungroup";
|
||||
"lng_feed_create_new" = "New feed";
|
||||
"lng_feed_too_few_channels#one" = "You need at least {count} channel to create a feed.";
|
||||
"lng_feed_too_few_channels#other" = "You need at least {count} channels to create a feed.";
|
||||
"lng_feed_select_more_channels#one" = "Select {count} channel or more.";
|
||||
"lng_feed_select_more_channels#other" = "Select {count} channels or more.";
|
||||
"lng_feed_create" = "Create";
|
||||
"lng_feed_edit_title" = "Edit feed";
|
||||
"lng_feed_channels_not_found" = "No channels found";
|
||||
|
||||
"lng_info_feed_title" = "Feed Info";
|
||||
"lng_info_feed_is_default" = "Group new channels";
|
||||
"lng_info_feed_channels" = "Channels";
|
||||
|
||||
"lng_terms_signup" = "By signing up,\nyou agree to the {link}.";
|
||||
"lng_terms_signup_link" = "Terms of Service";
|
||||
"lng_terms_header" = "Terms of Service";
|
||||
"lng_terms_age#one" = "I confirm that I am {count} or over";
|
||||
"lng_terms_age#other" = "I confirm that I am {count} or over";
|
||||
"lng_terms_agree" = "Agree & Continue";
|
||||
"lng_terms_decline" = "Decline";
|
||||
"lng_terms_signup_sorry" = "We're very sorry, but this means you can't sign up for Telegram.\n\nUnlike others, we don't use your data for ad targeting or other commercial purposes. Telegram only stores the information it needs to function as a feature-rich cloud service. You can adjust how we use your data in Privacy & Security settings.\n\nBut if you're generally not OK with Telegram's modest needs, it won't be possible for us to provide this service.";
|
||||
"lng_terms_update_sorry" = "We're very sorry, but this means we must part ways here. Unlike others, we don't use your data for ad targeting or other commercial purposes. Telegram only stores the information it needs to function as a feature-rich cloud service. You can adjust how we use your data in Privacy & Security settings.\n\nBut if you're generally not OK with Telegram's modest needs, it won't be possible for us to provide this service. You can deactivate your account now — or look around some more and deactivate it later if you feel you're not happy with the way we use your data. How does that sound?";
|
||||
"lng_terms_decline_and_delete" = "Decline & Delete";
|
||||
"lng_terms_back" = "Back";
|
||||
"lng_terms_delete_warning" = "Warning, this will irreversibly delete your Telegram account along with all the data you store in the Telegram cloud.\n\nWe will provide a tool to download your data before June, 23 – so you may want to wait a little before deleting.";
|
||||
"lng_terms_delete_now" = "Delete now";
|
||||
"lng_terms_agree_to_proceed" = "Please agree and proceed to {bot}.";
|
||||
|
||||
"lng_date_input_day" = "Day";
|
||||
"lng_date_input_month" = "Month";
|
||||
"lng_date_input_year" = "Year";
|
||||
|
||||
"lng_passport_title" = "Telegram passport";
|
||||
"lng_passport_request1" = "{bot} requests access to your personal data";
|
||||
"lng_passport_request2" = "to sign you up for their services";
|
||||
"lng_passport_create_password" = "Please create a password which will be used\nto encrypt your personal data.";
|
||||
"lng_passport_about_password" = "This password will also be required whenever\nyou log in to a new device.";
|
||||
"lng_passport_password_create" = "Create a password";
|
||||
"lng_passport_link_sent" = "A confirmation link was sent to your email\n{email}";
|
||||
"lng_passport_stop_password_sure" = "Are you sure you want to cancel setting up your password?";
|
||||
"lng_passport_password_placeholder" = "Your password";
|
||||
"lng_passport_next" = "Next";
|
||||
"lng_passport_password_wrong" = "The password you entered is not valid.";
|
||||
"lng_passport_header" = "Requested information";
|
||||
"lng_passport_identity_title" = "Identity document";
|
||||
"lng_passport_identity_description" = "Upload a scan of your passport or another ID";
|
||||
"lng_passport_identity_passport" = "Passport";
|
||||
"lng_passport_identity_passport_upload" = "Upload a scan of your passport";
|
||||
"lng_passport_identity_card" = "Identity card";
|
||||
"lng_passport_identity_card_upload" = "Upload a scan of your identity card";
|
||||
"lng_passport_identity_license" = "Driver's license";
|
||||
"lng_passport_identity_license_upload" = "Upload a scan of your driver's license";
|
||||
"lng_passport_identity_internal" = "Internal passport";
|
||||
"lng_passport_identity_internal_upload" = "Upload a scan of your internal passport";
|
||||
"lng_passport_identity_about" = "The document must contain your photograph, first and last name, date of birth, document number, country of issue, and expiry date.";
|
||||
"lng_passport_address_title" = "Residential address";
|
||||
"lng_passport_address_description" = "Upload a proof of your address";
|
||||
"lng_passport_address_bill" = "Utility bill";
|
||||
"lng_passport_address_bill_upload" = "Upload a scan of your utility bill";
|
||||
"lng_passport_address_statement" = "Bank statement";
|
||||
"lng_passport_address_statement_upload" = "Upload a scan of your bank statement";
|
||||
"lng_passport_address_agreement" = "Tenancy agreement";
|
||||
"lng_passport_address_agreement_upload" = "Upload a scan of your tenancy agreement";
|
||||
"lng_passport_address_registration" = "Passport registration";
|
||||
"lng_passport_address_registration_upload" = "Upload a scan of your passport registration";
|
||||
"lng_passport_address_temporary" = "Temporary registration";
|
||||
"lng_passport_address_temporary_upload" = "Upload a scan of your temporary registration";
|
||||
"lng_passport_address_about" = "To confirm your address, please upload a scan or photo of the selected document (all pages).";
|
||||
"lng_passport_document_type" = "Please choose the type of your document:";
|
||||
"lng_passport_upload_document" = "Upload document";
|
||||
"lng_passport_phone_title" = "Phone number";
|
||||
"lng_passport_phone_description" = "Enter your phone number";
|
||||
"lng_passport_email_title" = "Email";
|
||||
"lng_passport_email_description" = "Enter your email address";
|
||||
"lng_passport_accept_allow" = "You accept the {policy} and allow their {bot} to send you messages.";
|
||||
"lng_passport_allow" = "You allow {bot} to send you messages.";
|
||||
"lng_passport_policy" = "{bot} privacy policy";
|
||||
"lng_passport_authorize" = "Authorize";
|
||||
"lng_passport_form_error" = "Could not get authorization form.";
|
||||
"lng_passport_save_value" = "Save";
|
||||
"lng_passport_saving" = "Saving...";
|
||||
"lng_passport_uploading" = "Uploading...";
|
||||
"lng_passport_scan_index" = "Scan {index}";
|
||||
"lng_passport_upload_scans" = "Upload scans";
|
||||
"lng_passport_upload_more" = "Upload additional scans";
|
||||
"lng_passport_selfie_title" = "Selfie";
|
||||
"lng_passport_selfie_name" = "Photo";
|
||||
"lng_passport_selfie_description" = "Upload a photo of yourself holding your document. Make sure the ID and your face are clearly visible.";
|
||||
"lng_passport_upload_selfie" = "Upload selfie";
|
||||
"lng_passport_front_side_title" = "Front side";
|
||||
"lng_passport_front_side_name" = "Scan";
|
||||
"lng_passport_front_side_description" = "Upload front side of your document.";
|
||||
"lng_passport_upload_front_side" = "Upload front side scan";
|
||||
"lng_passport_reverse_side_title" = "Reverse side";
|
||||
"lng_passport_reverse_side_name" = "Scan";
|
||||
"lng_passport_reverse_side_description" = "Upload reverse side of your document.";
|
||||
"lng_passport_upload_reverse_side" = "Upload reverse side scan";
|
||||
"lng_passport_personal_details" = "Personal details";
|
||||
"lng_passport_personal_details_enter" = "Enter your personal details";
|
||||
"lng_passport_choose_image" = "Choose scan image";
|
||||
"lng_passport_delete_scan_undo" = "Undo";
|
||||
"lng_passport_scan_uploaded" = "Uploaded on {date}";
|
||||
"lng_passport_first_name" = "Name";
|
||||
"lng_passport_last_name" = "Surname";
|
||||
"lng_passport_birth_date" = "Date of birth";
|
||||
"lng_passport_gender" = "Gender";
|
||||
"lng_passport_gender_male" = "Male";
|
||||
"lng_passport_gender_female" = "Female";
|
||||
"lng_passport_country" = "Country";
|
||||
"lng_passport_residence_country" = "Residence";
|
||||
"lng_passport_country_choose" = "Choose country";
|
||||
"lng_passport_document_number" = "Card Number";
|
||||
"lng_passport_expiry_date" = "Expiry date";
|
||||
"lng_passport_address" = "Address";
|
||||
"lng_passport_address_enter" = "Enter your address";
|
||||
"lng_passport_street" = "Street";
|
||||
"lng_passport_city" = "City";
|
||||
"lng_passport_state" = "State";
|
||||
"lng_passport_postcode" = "Postcode";
|
||||
"lng_passport_use_existing" = "USE {existing}";
|
||||
"lng_passport_use_existing_phone" = "Use the same phone number as on Telegram.";
|
||||
"lng_passport_new_phone" = "Or enter a new phone number";
|
||||
"lng_passport_new_phone_code" = "Note: You will receive a confirmation code on the phone number you provide.";
|
||||
"lng_passport_use_existing_email" = "Use the same email address as on Telegram.";
|
||||
"lng_passport_new_email" = "Or enter a new email";
|
||||
"lng_passport_new_email_code" = "Note: You will receive a confirmation code to the email address you provide.";
|
||||
"lng_passport_confirm_phone" = "We've sent an SMS with a confirmation code to your phone {phone}.";
|
||||
"lng_passport_confirm_email" = "We've sent a confirmation code to your email {email}.";
|
||||
"lng_passport_sure_cancel" = "If you continue, your changes will be lost.";
|
||||
"lng_passport_scans_limit_reached" = "Sorry, that's too many scans for one document.";
|
||||
"lng_passport_delete_document" = "Delete document";
|
||||
"lng_passport_delete_document_sure" = "Are you sure you want to delete this document?";
|
||||
"lng_passport_delete_details" = "Delete personal details";
|
||||
"lng_passport_delete_details_sure" = "Are you sure you want to delete your personal details?";
|
||||
"lng_passport_delete_address" = "Delete address information";
|
||||
"lng_passport_delete_address_sure" = "Are you sure you want to delete your address information?";
|
||||
"lng_passport_delete_email" = "Delete email";
|
||||
"lng_passport_delete_email_sure" = "Are you sure you want to delete your email address?";
|
||||
"lng_passport_delete_phone" = "Delete phone number";
|
||||
"lng_passport_delete_phone_sure" = "Are you sure you want to delete your phone number?";
|
||||
"lng_passport_success" = "Authorization successfull!";
|
||||
"lng_passport_stop_sure" = "Are you sure you want to stop this authorization?";
|
||||
"lng_passport_stop" = "Stop";
|
||||
"lng_passport_restart_sure" = "An unexpected error has occurred. Perhaps some changes were made from a different Telegram application. Would you like to restart this authorization?";
|
||||
"lng_passport_restart" = "Restart";
|
||||
"lng_passport_error_too_large" = "This file is too large.";
|
||||
"lng_passport_error_bad_size" = "This image has bad dimensions.";
|
||||
"lng_passport_error_cant_read" = "Can't read this file. Please choose an image.";
|
||||
"lng_passport_bad_name" = "Use latin characters only.";
|
||||
|
||||
// Wnd specific
|
||||
|
||||
"lng_wnd_choose_program_menu" = "Choose Default Program...";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "Deutsch";
|
||||
"lng_switch_to_this" = "Auf Deutsch zurücksetzen";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "Español";
|
||||
"lng_switch_to_this" = "Cambiar a español";
|
||||
@@ -206,19 +193,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_signin_title" = "Contraseña";
|
||||
"lng_signin_desc" = "Por favor, pon tu contraseña.";
|
||||
"lng_signin_recover_desc" = "Por favor, pon el código desde el e-mail\n{email}";
|
||||
"lng_signin_recover_desc" = "Por favor, pon el código desde el email\n{email}";
|
||||
"lng_signin_password" = "Tu contraseña";
|
||||
"lng_signin_code" = "Código desde el e-mail";
|
||||
"lng_signin_code" = "Código desde el email";
|
||||
"lng_signin_recover" = "¿Olvidaste la contraseña?";
|
||||
"lng_signin_recover_title" = "Restablecer contraseña";
|
||||
"lng_signin_hint" = "Pista: {password_hint}";
|
||||
"lng_signin_recover_hint" = "El código fue enviado a {recover_email}";
|
||||
"lng_signin_bad_password" = "Pusiste la contraseña equivocada.";
|
||||
"lng_signin_wrong_code" = "Has ingresado un código inválido.";
|
||||
"lng_signin_try_password" = "¿Tienes problemas para acceder a tu e-mail?";
|
||||
"lng_signin_try_password" = "¿Tienes problemas para acceder a tu email?";
|
||||
"lng_signin_password_removed" = "Tu contraseña fue desactivada.\nPuedes configurar una nueva en Ajustes.";
|
||||
"lng_signin_no_email_forgot" = "Como no estableciste un e-mail de recuperación \ncuando configuraste tu contraseña, las opciones restantes son recordar tu contraseña o restablecer tu cuenta.";
|
||||
"lng_signin_cant_email_forgot" = "Si no puedes acceder a tu e-mail, las opciones restantes son recordar tu contraseña o restablecer tu cuenta.";
|
||||
"lng_signin_no_email_forgot" = "Como no estableciste un email de recuperación \ncuando configuraste tu contraseña, las opciones restantes son recordar tu contraseña o restablecer tu cuenta.";
|
||||
"lng_signin_cant_email_forgot" = "Si no puedes acceder a tu email, las opciones restantes son recordar tu contraseña o restablecer tu cuenta.";
|
||||
"lng_signin_reset_account" = "Restablecer tu cuenta";
|
||||
"lng_signin_sure_reset" = "¡Advertencia!\n\n¡Perderás todos tus chats y mensajes, junto con la multimedia y archivos compartidos!\n\n¿Quieres restablecer tu cuenta?";
|
||||
"lng_signin_reset" = "Restablecer";
|
||||
@@ -419,12 +406,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_cloud_password_hint" = "Pon una pista para la contraseña";
|
||||
"lng_cloud_password_change_hint" = "Pon una pista para la contraseña";
|
||||
"lng_cloud_password_bad" = "La contraseña y la pista no pueden ser iguales.";
|
||||
"lng_cloud_password_email" = "Pon un e-mail de recuperación";
|
||||
"lng_cloud_password_bad_email" = "E-mail incorrecto. Por favor, prueba otro.";
|
||||
"lng_cloud_password_email" = "Pon un email de recuperación";
|
||||
"lng_cloud_password_bad_email" = "email incorrecto. Por favor, prueba otro.";
|
||||
"lng_cloud_password_about" = "Necesitarás la contraseña al iniciar sesión, además del código de activación.";
|
||||
"lng_cloud_password_about_recover" = "¡Advertencia! ¿No quieres añadir un e-mail \nde recuperación para la contraseña?\n\nSi olvidas tu contraseña, perderás\nel acceso a tu cuenta de Telegram.";
|
||||
"lng_cloud_password_skip_email" = "Omitir e-mail";
|
||||
"lng_cloud_password_almost" = "Un enlace de confirmación fue enviado \nal e-mail que estableciste. La verificación en dos pasos se activará en cuanto sigas ese enlace.";
|
||||
"lng_cloud_password_about_recover" = "¡Advertencia! ¿No quieres añadir un email \nde recuperación para la contraseña?\n\nSi olvidas tu contraseña, perderás\nel acceso a tu cuenta de Telegram.";
|
||||
"lng_cloud_password_skip_email" = "Omitir email";
|
||||
"lng_cloud_password_almost" = "Un enlace de confirmación fue enviado \nal email que estableciste. La verificación en dos pasos se activará en cuanto sigas ese enlace.";
|
||||
"lng_cloud_password_was_set" = "Verificación en dos pasos activada.";
|
||||
"lng_cloud_password_updated" = "Tu contraseña fue actualizada.";
|
||||
"lng_cloud_password_removed" = "Verificación en dos pasos desactivada.";
|
||||
@@ -1057,7 +1044,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_context_copy_link" = "Copiar enlace";
|
||||
"lng_context_copy_post_link" = "Copiar enlace de la publicación";
|
||||
"lng_context_copy_email" = "Copiar e-mail";
|
||||
"lng_context_copy_email" = "Copiar email";
|
||||
"lng_context_copy_hashtag" = "Copiar hashtag";
|
||||
"lng_context_copy_mention" = "Copiar alias";
|
||||
"lng_context_save_image" = "Guardar como...";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "Italiano";
|
||||
"lng_switch_to_this" = "Passa all'Italiano";
|
||||
@@ -206,19 +193,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_signin_title" = "Verifica password";
|
||||
"lng_signin_desc" = "Per favore inserisci la tua password.";
|
||||
"lng_signin_recover_desc" = "Per favore inserisci il codice dall'e-mail\n{email}";
|
||||
"lng_signin_recover_desc" = "Per favore inserisci il codice dall'email\n{email}";
|
||||
"lng_signin_password" = "La tua password";
|
||||
"lng_signin_code" = "Codice dall'e-mail";
|
||||
"lng_signin_code" = "Codice dall'email";
|
||||
"lng_signin_recover" = "Password dimenticata?";
|
||||
"lng_signin_recover_title" = "Ripristino password";
|
||||
"lng_signin_hint" = "Suggerimento: {password_hint}";
|
||||
"lng_signin_recover_hint" = "Il codice è stato inviato a {recover_email}";
|
||||
"lng_signin_bad_password" = "Hai inserito una password errata.";
|
||||
"lng_signin_wrong_code" = "Hai inserito un codice non valido.";
|
||||
"lng_signin_try_password" = "Hai problemi ad accedere alla tua e-mail?";
|
||||
"lng_signin_try_password" = "Hai problemi ad accedere alla tua email?";
|
||||
"lng_signin_password_removed" = "La tua password è stata disattivata.\nNe puoi impostare una nuova dalle Impostazioni.";
|
||||
"lng_signin_no_email_forgot" = "Siccome non hai fornito un'email di recupero quando hai inserito la password, non ti resta che ricordarti la password o ripristinare il tuo account.";
|
||||
"lng_signin_cant_email_forgot" = "Se non puoi recuperare l'accesso all'e-mail, non ti resta che ricordarti la password o ripristinare il tuo account.";
|
||||
"lng_signin_cant_email_forgot" = "Se non puoi recuperare l'accesso all'email, non ti resta che ricordarti la password o ripristinare il tuo account.";
|
||||
"lng_signin_reset_account" = "Ripristina il tuo account";
|
||||
"lng_signin_sure_reset" = "Attenzione!\n\nPerderai tutte le chat e i messaggi, insieme a tutti i media e i file condivisi!\n\nVuoi ripristinare il tuo account?";
|
||||
"lng_signin_reset" = "Ripristina";
|
||||
@@ -420,11 +407,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_cloud_password_change_hint" = "Inserisci un nuovo suggerimento";
|
||||
"lng_cloud_password_bad" = "Password e suggerimento devono essere diversi.";
|
||||
"lng_cloud_password_email" = "Inserisci email di recupero";
|
||||
"lng_cloud_password_bad_email" = "E-mail non valida, riprova con un'altra.";
|
||||
"lng_cloud_password_bad_email" = "email non valida, riprova con un'altra.";
|
||||
"lng_cloud_password_about" = "La password sarà richiesta quando ti connetti da un nuovo dispositivo insieme al codice.";
|
||||
"lng_cloud_password_about_recover" = "Attenzione! Sicuro di non voler\naggiungere un'e-mail di recupero?\n\nSe dimentichi la tua password, perderai\nl'accesso al tuo account Telegram.";
|
||||
"lng_cloud_password_skip_email" = "Salta e-mail";
|
||||
"lng_cloud_password_almost" = "Abbiamo inviato un link di conferma\nall'e-mail che ci hai fornito. La verifica in due passaggi sarà attivata non appena aprirai quel link.";
|
||||
"lng_cloud_password_about_recover" = "Attenzione! Sicuro di non voler\naggiungere un'email di recupero?\n\nSe dimentichi la tua password, perderai\nl'accesso al tuo account Telegram.";
|
||||
"lng_cloud_password_skip_email" = "Salta email";
|
||||
"lng_cloud_password_almost" = "Abbiamo inviato un link di conferma\nall'email che ci hai fornito. La verifica in due passaggi sarà attivata non appena aprirai quel link.";
|
||||
"lng_cloud_password_was_set" = "Verifica in due passaggi abilitata.";
|
||||
"lng_cloud_password_updated" = "La tua password è stata aggiornata.";
|
||||
"lng_cloud_password_removed" = "La verifica in due passaggi è stata disattivata.";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "영어";
|
||||
"lng_switch_to_this" = "영어로 변경";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "Nederlands";
|
||||
"lng_switch_to_this" = "Overschakelen naar Nederlands";
|
||||
@@ -206,19 +193,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_signin_title" = "Cloud-wachtwoord:";
|
||||
"lng_signin_desc" = "Cloud-wachtwoord invoeren";
|
||||
"lng_signin_recover_desc" = "Voer de code uit de e-mail in\n{email}";
|
||||
"lng_signin_recover_desc" = "Voer de code uit de email in\n{email}";
|
||||
"lng_signin_password" = "Je cloud-wachtwoord";
|
||||
"lng_signin_code" = "Code uit de e-mail";
|
||||
"lng_signin_code" = "Code uit de email";
|
||||
"lng_signin_recover" = "Wachtwoord vergeten?";
|
||||
"lng_signin_recover_title" = "Wachtwoord reset";
|
||||
"lng_signin_hint" = "Hint: {password_hint}";
|
||||
"lng_signin_recover_hint" = "De code is verstuurd naar {recover_email}";
|
||||
"lng_signin_bad_password" = "Ongeldig wachtwoord.";
|
||||
"lng_signin_wrong_code" = "Je hebt een ongeldige code ingevoerd.";
|
||||
"lng_signin_try_password" = "Kun je je e-mail niet benaderen?";
|
||||
"lng_signin_try_password" = "Kun je je email niet benaderen?";
|
||||
"lng_signin_password_removed" = "Je cloud-wachtwoord is uitgeschakeld.\nVia instellingen kun je een nieuwe instellen.";
|
||||
"lng_signin_no_email_forgot" = "Omdat je geen herstel-e-mailadres hebt opgegeven voor je wachtwoord zul je bij verlies van je wachtwoord je account moeten resetten.";
|
||||
"lng_signin_cant_email_forgot" = "Als je geen toegang meer hebt tot je e-mail en je ingestelde wachtwoord zul je je account moeten resetten.";
|
||||
"lng_signin_no_email_forgot" = "Omdat je geen herstel-emailadres hebt opgegeven voor je wachtwoord zul je bij verlies van je wachtwoord je account moeten resetten.";
|
||||
"lng_signin_cant_email_forgot" = "Als je geen toegang meer hebt tot je email en je ingestelde wachtwoord zul je je account moeten resetten.";
|
||||
"lng_signin_reset_account" = "Account resetten";
|
||||
"lng_signin_sure_reset" = "Let op:\n\nAl je chats, berichten en alle andere data gaan verloren als je verder gaat!\n\nEcht je account resetten?";
|
||||
"lng_signin_reset" = "Reset";
|
||||
@@ -419,12 +406,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_cloud_password_hint" = "Wachtwoordhint invoeren";
|
||||
"lng_cloud_password_change_hint" = "Wachtwoordhint invoeren";
|
||||
"lng_cloud_password_bad" = "De hint moet anders zijn dan je wachtwoord.";
|
||||
"lng_cloud_password_email" = "Herstel-e-mailadres invoeren";
|
||||
"lng_cloud_password_bad_email" = "Ongeldig e-mailadres, probeer een andere.";
|
||||
"lng_cloud_password_email" = "Herstel-emailadres invoeren";
|
||||
"lng_cloud_password_bad_email" = "Ongeldig emailadres, probeer een andere.";
|
||||
"lng_cloud_password_about" = "Dit wachtwoord is nodig als je inlogt vanaf een nieuw apparaat, naast de SMS-code.";
|
||||
"lng_cloud_password_about_recover" = "Let op: Echt geen herstel-emailadres\nopgeven voor je wachtwoord?\n\nBij verlies van je wachtwoord ben je\nook de toegang tot Telegram kwijt.";
|
||||
"lng_cloud_password_skip_email" = "E-mail overslaan";
|
||||
"lng_cloud_password_almost" = "Een bevestigingslink is naar het e-mailadres verstuurd. \ntwee-staps-verificatie is actief na het klikken van de e-mail-link.";
|
||||
"lng_cloud_password_skip_email" = "email overslaan";
|
||||
"lng_cloud_password_almost" = "Een bevestigingslink is naar het emailadres verstuurd. \ntwee-staps-verificatie is actief na het klikken van de email-link.";
|
||||
"lng_cloud_password_was_set" = "Twee-staps-verificatie ingeschakeld.";
|
||||
"lng_cloud_password_updated" = "Je cloud-wachtwoord is gewijzigd.";
|
||||
"lng_cloud_password_removed" = "Twee-staps-verificatie uitgeschakeld.";
|
||||
@@ -1057,7 +1044,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_context_copy_link" = "Link kopiëren";
|
||||
"lng_context_copy_post_link" = "Berichtlink kopiëren";
|
||||
"lng_context_copy_email" = "E-mailadres kopiëren";
|
||||
"lng_context_copy_email" = "emailadres kopiëren";
|
||||
"lng_context_copy_hashtag" = "Hashtag kopiëren";
|
||||
"lng_context_copy_mention" = "Gebruikersnaam kopiëren";
|
||||
"lng_context_save_image" = "Afbeelding opslaan als...";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
"lng_language_name" = "Português (Brasil)";
|
||||
"lng_switch_to_this" = "Trocar para Português (Brasil)";
|
||||
@@ -206,19 +193,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_signin_title" = "Verificar senha";
|
||||
"lng_signin_desc" = "Por favor, insira sua senha.";
|
||||
"lng_signin_recover_desc" = "Por favor, insira o código de seu e-mail\n{email}";
|
||||
"lng_signin_recover_desc" = "Por favor, insira o código de seu email\n{email}";
|
||||
"lng_signin_password" = "Sua senha";
|
||||
"lng_signin_code" = "Código do e-mail";
|
||||
"lng_signin_code" = "Código do email";
|
||||
"lng_signin_recover" = "Esqueceu sua senha?";
|
||||
"lng_signin_recover_title" = "Redefinir senha";
|
||||
"lng_signin_hint" = "Dica: {password_hint}";
|
||||
"lng_signin_recover_hint" = "Código enviado para {recover_email}";
|
||||
"lng_signin_bad_password" = "Você colocou uma senha errada.";
|
||||
"lng_signin_wrong_code" = "Você inseriu um código inválido";
|
||||
"lng_signin_try_password" = "Problemas ao acessar seu e-mail?";
|
||||
"lng_signin_try_password" = "Problemas ao acessar seu email?";
|
||||
"lng_signin_password_removed" = "Sua senha da nuvem foi desativada.\nVocê pode definir uma nova em Configurações.";
|
||||
"lng_signin_no_email_forgot" = "Se você não providenciar um e-mail\nde recuperação ao configurar sua senha, suas opções restantes serão lembrar sua senha ou apagar sua conta.";
|
||||
"lng_signin_cant_email_forgot" = "Se você não pode restaurar o acesso ao e-mail, suas opções restantes serão lembrar sua senha ou apagar sua conta.";
|
||||
"lng_signin_no_email_forgot" = "Se você não providenciar um email\nde recuperação ao configurar sua senha, suas opções restantes serão lembrar sua senha ou apagar sua conta.";
|
||||
"lng_signin_cant_email_forgot" = "Se você não pode restaurar o acesso ao email, suas opções restantes serão lembrar sua senha ou apagar sua conta.";
|
||||
"lng_signin_reset_account" = "Apagar sua conta";
|
||||
"lng_signin_sure_reset" = "Atenção!\n\nVocê perderá todos seus chats e mensagens, juntamente com quaisquer mídias e arquivos!\n\nVocê deseja apagar sua conta?";
|
||||
"lng_signin_reset" = "Apagar";
|
||||
@@ -419,11 +406,11 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
"lng_cloud_password_hint" = "Insira uma dica de senha";
|
||||
"lng_cloud_password_change_hint" = "Insira uma dica de senha";
|
||||
"lng_cloud_password_bad" = "Senha e dica de senha não podem ser iguais.";
|
||||
"lng_cloud_password_email" = "E-mail de recuperação";
|
||||
"lng_cloud_password_bad_email" = "E-mail incorreto, por favor, tente outro.";
|
||||
"lng_cloud_password_email" = "email de recuperação";
|
||||
"lng_cloud_password_bad_email" = "email incorreto, por favor, tente outro.";
|
||||
"lng_cloud_password_about" = "Essa senha será requisitada quando você entrar em um novo dispositivo, após o seu PIN.";
|
||||
"lng_cloud_password_about_recover" = "Atenção! Você tem certeza que não quer\nadicionar um email para recuperação de senha?\n\nSe você esquecer sua senha, perderá\nseu acesso a sua conta no Telegram.";
|
||||
"lng_cloud_password_skip_email" = "Pular e-mail";
|
||||
"lng_cloud_password_skip_email" = "Pular email";
|
||||
"lng_cloud_password_almost" = "Link de confirmação enviado para\no email fornecido. A verificação em duas etapas será ativada assim que você abrir o link.";
|
||||
"lng_cloud_password_was_set" = "Verificação em duas etapas ativada.";
|
||||
"lng_cloud_password_updated" = "Sua senha da nuvem foi atualizada.";
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
387;BA;Bosnia & Herzegovina
|
||||
386;SI;Slovenia
|
||||
385;HR;Croatia
|
||||
383;XK;Kosovo;383 XXXX XXXX;11;
|
||||
382;ME;Montenegro
|
||||
381;RS;Serbia;381 XX XXX XXXX;12;
|
||||
380;UA;Ukraine;380 XX XXX XX XX;12;
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
resPQ#05162463 nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector<long> = ResPQ;
|
||||
|
||||
p_q_inner_data#83c95aec pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 = P_Q_inner_data;
|
||||
p_q_inner_data_dc#a9f55f95 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int = P_Q_inner_data;
|
||||
p_q_inner_data_temp#3c6a84d4 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 expires_in:int = P_Q_inner_data;
|
||||
p_q_inner_data_temp_dc#56fddf88 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int expires_in:int = P_Q_inner_data;
|
||||
|
||||
server_DH_params_fail#79cb045d nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params;
|
||||
server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params;
|
||||
@@ -54,6 +57,7 @@ destroy_auth_key_fail#ea109b13 = DestroyAuthKeyRes;
|
||||
---functions---
|
||||
|
||||
req_pq#60469778 nonce:int128 = ResPQ;
|
||||
req_pq_multi#be7e8ef1 nonce:int128 = ResPQ;
|
||||
|
||||
req_DH_params#d712e4be nonce:int128 server_nonce:int128 p:string q:string public_key_fingerprint:long encrypted_data:string = Server_DH_Params;
|
||||
|
||||
@@ -106,8 +110,13 @@ new_session_created#9ec20908 first_msg_id:long unique_id:long server_salt:long =
|
||||
|
||||
http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait;
|
||||
|
||||
ipPort ipv4:int port:int = IpPort;
|
||||
help.configSimple#d997c3c5 date:int expires:int dc_id:int ip_port_list:Vector<ipPort> = help.ConfigSimple;
|
||||
//ipPort ipv4:int port:int = IpPort;
|
||||
//help.configSimple#d997c3c5 date:int expires:int dc_id:int ip_port_list:Vector<ipPort> = help.ConfigSimple;
|
||||
|
||||
ipPort#d433ad73 ipv4:int port:int = IpPort;
|
||||
ipPortSecret#37982646 ipv4:int port:int secret:bytes = IpPort;
|
||||
accessPointRule#4679b65f phone_prefix_rules:string dc_id:int ips:vector<IpPort> = AccessPointRule;
|
||||
help.configSimple#5a592a6c date:int expires:int rules:vector<AccessPointRule> = help.ConfigSimple;
|
||||
|
||||
---functions---
|
||||
|
||||
@@ -155,16 +164,16 @@ inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile
|
||||
inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile;
|
||||
|
||||
inputMediaEmpty#9664f57f = InputMedia;
|
||||
inputMediaUploadedPhoto#2f37e231 flags:# file:InputFile caption:string stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
|
||||
inputMediaPhoto#81fa373a flags:# id:InputPhoto caption:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaUploadedPhoto#1e287d04 flags:# file:InputFile stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
|
||||
inputMediaPhoto#b3ba0635 flags:# id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
|
||||
inputMediaContact#a6e45987 phone_number:string first_name:string last_name:string = InputMedia;
|
||||
inputMediaUploadedDocument#e39621fd flags:# nosound_video:flags.3?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> caption:string stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
|
||||
inputMediaDocument#5acb668e flags:# id:InputDocument caption:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
|
||||
inputMediaDocument#23ab23d2 flags:# id:InputDocument ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia;
|
||||
inputMediaGifExternal#4843b0fd url:string q:string = InputMedia;
|
||||
inputMediaPhotoExternal#922aec1 flags:# url:string caption:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaDocumentExternal#b6f74335 flags:# url:string caption:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
||||
inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;
|
||||
inputMediaGeoLive#7b1a118f geo_point:InputGeoPoint period:int = InputMedia;
|
||||
@@ -182,6 +191,7 @@ inputPhoto#fb95c6c4 id:long access_hash:long = InputPhoto;
|
||||
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
|
||||
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
|
||||
inputDocumentFileLocation#430f0724 id:long access_hash:long version:int = InputFileLocation;
|
||||
inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
|
||||
|
||||
inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent;
|
||||
|
||||
@@ -219,7 +229,7 @@ userStatusLastMonth#77ebc742 = UserStatus;
|
||||
chatEmpty#9ba2d800 id:int = Chat;
|
||||
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
|
||||
chatForbidden#7328bdb id:int title:string = Chat;
|
||||
channel#450b7115 flags:# creator:flags.0?true left:flags.2?true editor:flags.3?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChannelAdminRights banned_rights:flags.15?ChannelBannedRights participants_count:flags.17?int = Chat;
|
||||
channel#c88974ac flags:# creator:flags.0?true left:flags.2?true editor:flags.3?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChannelAdminRights banned_rights:flags.15?ChannelBannedRights participants_count:flags.17?int = Chat;
|
||||
channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
|
||||
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
|
||||
@@ -240,11 +250,11 @@ message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:fl
|
||||
messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
messageMediaPhoto#b5223b0f flags:# photo:flags.0?Photo caption:flags.1?string ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
|
||||
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
|
||||
messageMediaUnsupported#9f84f49e = MessageMedia;
|
||||
messageMediaDocument#7c4414d3 flags:# document:flags.0?Document caption:flags.1?string ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaDocument#9cb070d7 flags:# document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
||||
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
|
||||
messageMediaGame#fdb19008 game:Game = MessageMedia;
|
||||
@@ -270,6 +280,9 @@ messageActionPaymentSent#40699cd0 currency:string total_amount:long = MessageAct
|
||||
messageActionPhoneCall#80e11a7f flags:# call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction;
|
||||
messageActionScreenshotTaken#4792929b = MessageAction;
|
||||
messageActionCustomAction#fae69f56 message:string = MessageAction;
|
||||
messageActionBotAllowed#abe9affe domain:string = MessageAction;
|
||||
messageActionSecureValuesSentMe#1b287353 values:Vector<SecureValue> credentials:SecureCredentialsEncrypted = MessageAction;
|
||||
messageActionSecureValuesSent#d95c6154 types:Vector<SecureValueType> = MessageAction;
|
||||
|
||||
dialog#e4def5db flags:# pinned:flags.2?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
|
||||
|
||||
@@ -285,7 +298,7 @@ geoPoint#2049d70c long:double lat:double = GeoPoint;
|
||||
|
||||
auth.checkedPhone#811ea28e phone_registered:Bool = auth.CheckedPhone;
|
||||
|
||||
auth.sentCode#5e002502 flags:# phone_registered:flags.0?true type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int = auth.SentCode;
|
||||
auth.sentCode#38faab5f flags:# phone_registered:flags.0?true type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int terms_of_service:flags.3?help.TermsOfService = auth.SentCode;
|
||||
|
||||
auth.authorization#cd050916 flags:# tmp_sessions:flags.0?int user:User = auth.Authorization;
|
||||
|
||||
@@ -294,18 +307,10 @@ auth.exportedAuthorization#df969c2d id:int bytes:bytes = auth.ExportedAuthorizat
|
||||
inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
|
||||
inputNotifyUsers#193b4417 = InputNotifyPeer;
|
||||
inputNotifyChats#4a95e84e = InputNotifyPeer;
|
||||
inputNotifyAll#a429b886 = InputNotifyPeer;
|
||||
|
||||
inputPeerNotifyEventsEmpty#f03064d8 = InputPeerNotifyEvents;
|
||||
inputPeerNotifyEventsAll#e86a2c74 = InputPeerNotifyEvents;
|
||||
inputPeerNotifySettings#9c3d198e flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = InputPeerNotifySettings;
|
||||
|
||||
inputPeerNotifySettings#38935eb2 flags:# show_previews:flags.0?true silent:flags.1?true mute_until:int sound:string = InputPeerNotifySettings;
|
||||
|
||||
peerNotifyEventsEmpty#add53cb3 = PeerNotifyEvents;
|
||||
peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents;
|
||||
|
||||
peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
|
||||
peerNotifySettings#9acda4c0 flags:# show_previews:flags.0?true silent:flags.1?true mute_until:int sound:string = PeerNotifySettings;
|
||||
peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = PeerNotifySettings;
|
||||
|
||||
peerSettings#818426cd flags:# report_spam:flags.0?true = PeerSettings;
|
||||
|
||||
@@ -422,8 +427,8 @@ updateRecentStickers#9a422c20 = Update;
|
||||
updateConfig#a229dd06 = Update;
|
||||
updatePtsChanged#3354678f = Update;
|
||||
updateChannelWebPage#40771900 channel_id:int webpage:WebPage pts:int pts_count:int = Update;
|
||||
updateDialogPinned#d711a2cc flags:# pinned:flags.0?true peer:Peer = Update;
|
||||
updatePinnedDialogs#d8caf68d flags:# order:flags.0?Vector<Peer> = Update;
|
||||
updateDialogPinned#19d27f3c flags:# pinned:flags.0?true peer:DialogPeer = Update;
|
||||
updatePinnedDialogs#ea4cb65b flags:# order:flags.0?Vector<DialogPeer> = Update;
|
||||
updateBotWebhookJSON#8317c0c3 data:DataJSON = Update;
|
||||
updateBotWebhookJSONQuery#9b9240a6 query_id:long data:DataJSON timeout:int = Update;
|
||||
updateBotShippingQuery#e0cdc940 query_id:long user_id:int payload:bytes shipping_address:PostAddress = Update;
|
||||
@@ -457,11 +462,11 @@ photos.photosSlice#15051f54 count:int photos:Vector<Photo> users:Vector<User> =
|
||||
photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
|
||||
|
||||
upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
|
||||
upload.fileCdnRedirect#ea52fe5a dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes cdn_file_hashes:Vector<CdnFileHash> = upload.File;
|
||||
upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes file_hashes:Vector<FileHash> = upload.File;
|
||||
|
||||
dcOption#5d8c6cc flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int = DcOption;
|
||||
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
|
||||
|
||||
config#9c840964 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int disabled_features:Vector<DisabledFeature> = Config;
|
||||
config#eb7bb160 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int = Config;
|
||||
|
||||
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
|
||||
|
||||
@@ -506,7 +511,6 @@ help.support#17c6b5f6 phone_number:string user:User = help.Support;
|
||||
notifyPeer#9fd40bd8 peer:Peer = NotifyPeer;
|
||||
notifyUsers#b4c83b4c = NotifyPeer;
|
||||
notifyChats#c007cec3 = NotifyPeer;
|
||||
notifyAll#74d07c60 = NotifyPeer;
|
||||
|
||||
sendMessageTypingAction#16bf744e = SendMessageAction;
|
||||
sendMessageCancelAction#fd5ec8f5 = SendMessageAction;
|
||||
@@ -522,7 +526,7 @@ sendMessageGamePlayAction#dd6a8f48 = SendMessageAction;
|
||||
sendMessageRecordRoundAction#88f27fbc = SendMessageAction;
|
||||
sendMessageUploadRoundAction#243e1c66 progress:int = SendMessageAction;
|
||||
|
||||
contacts.found#1aa1f784 results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
|
||||
contacts.found#b3134d9d my_results:Vector<Peer> results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
|
||||
|
||||
inputPrivacyKeyStatusTimestamp#4f96cb18 = InputPrivacyKey;
|
||||
inputPrivacyKeyChatInvite#bdfb0426 = InputPrivacyKey;
|
||||
@@ -553,21 +557,19 @@ accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
|
||||
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
|
||||
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
||||
documentAttributeSticker#6319d612 flags:# mask:flags.1?true alt:string stickerset:InputStickerSet mask_coords:flags.0?MaskCoords = DocumentAttribute;
|
||||
documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true duration:int w:int h:int = DocumentAttribute;
|
||||
documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true supports_streaming:flags.1?true duration:int w:int h:int = DocumentAttribute;
|
||||
documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute;
|
||||
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
|
||||
documentAttributeHasStickers#9801d2f7 = DocumentAttribute;
|
||||
|
||||
messages.stickersNotModified#f1749a22 = messages.Stickers;
|
||||
messages.stickers#8a8ecd32 hash:string stickers:Vector<Document> = messages.Stickers;
|
||||
messages.stickers#e4599bbd hash:int stickers:Vector<Document> = messages.Stickers;
|
||||
|
||||
stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
|
||||
|
||||
messages.allStickersNotModified#e86602c3 = messages.AllStickers;
|
||||
messages.allStickers#edfd405f hash:int sets:Vector<StickerSet> = messages.AllStickers;
|
||||
|
||||
disabledFeature#ae636f24 feature:string description:string = DisabledFeature;
|
||||
|
||||
messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages;
|
||||
|
||||
contactLinkUnknown#5f4f9247 = ContactLink;
|
||||
@@ -584,12 +586,12 @@ authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string s
|
||||
|
||||
account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations;
|
||||
|
||||
account.noPassword#96dabc18 new_salt:bytes email_unconfirmed_pattern:string = account.Password;
|
||||
account.password#7c18141c current_salt:bytes new_salt:bytes hint:string has_recovery:Bool email_unconfirmed_pattern:string = account.Password;
|
||||
account.noPassword#5ea182f6 new_salt:bytes new_secure_salt:bytes secure_random:bytes email_unconfirmed_pattern:string = account.Password;
|
||||
account.password#ca39b447 flags:# has_recovery:flags.0?true has_secure_values:flags.1?true current_salt:bytes new_salt:bytes new_secure_salt:bytes secure_random:bytes hint:string email_unconfirmed_pattern:string = account.Password;
|
||||
|
||||
account.passwordSettings#b7b72ab3 email:string = account.PasswordSettings;
|
||||
account.passwordSettings#7bd9c3f1 email:string secure_salt:bytes secure_secret:bytes secure_secret_id:long = account.PasswordSettings;
|
||||
|
||||
account.passwordInputSettings#86916deb flags:# new_salt:flags.0?bytes new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string = account.PasswordInputSettings;
|
||||
account.passwordInputSettings#21ffa60d flags:# new_salt:flags.0?bytes new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string new_secure_salt:flags.2?bytes new_secure_secret:flags.2?bytes new_secure_secret_id:flags.2?long = account.PasswordInputSettings;
|
||||
|
||||
auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery;
|
||||
|
||||
@@ -605,7 +607,7 @@ inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
||||
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
|
||||
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
|
||||
|
||||
stickerSet#cd303b41 flags:# installed:flags.0?true archived:flags.1?true official:flags.2?true masks:flags.3?true id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet;
|
||||
stickerSet#5585a139 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet;
|
||||
|
||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
||||
|
||||
@@ -642,6 +644,8 @@ messageEntityPre#73924be0 offset:int length:int language:string = MessageEntity;
|
||||
messageEntityTextUrl#76a6d327 offset:int length:int url:string = MessageEntity;
|
||||
messageEntityMentionName#352dca58 offset:int length:int user_id:int = MessageEntity;
|
||||
inputMessageEntityMentionName#208e68c9 offset:int length:int user_id:InputUser = MessageEntity;
|
||||
messageEntityPhone#9b69e34b offset:int length:int = MessageEntity;
|
||||
messageEntityCashtag#4c4e743f offset:int length:int = MessageEntity;
|
||||
|
||||
inputChannelEmpty#ee8c1e86 = InputChannel;
|
||||
inputChannel#afeb712e channel_id:int access_hash:long = InputChannel;
|
||||
@@ -675,7 +679,7 @@ channels.channelParticipantsNotModified#f0173fe9 = channels.ChannelParticipants;
|
||||
|
||||
channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector<User> = channels.ChannelParticipant;
|
||||
|
||||
help.termsOfService#f1ee3e90 text:string = help.TermsOfService;
|
||||
help.termsOfService#780a0310 flags:# popup:flags.0?true id:DataJSON text:string entities:Vector<MessageEntity> min_age_confirm:flags.1?int = help.TermsOfService;
|
||||
|
||||
foundGif#162ecc1f url:string thumb_url:string content_url:string content_type:string w:int h:int = FoundGif;
|
||||
foundGifCached#9c750409 url:string photo:Photo document:Document = FoundGif;
|
||||
@@ -685,30 +689,30 @@ messages.foundGifs#450a1c0a next_offset:int results:Vector<FoundGif> = messages.
|
||||
messages.savedGifsNotModified#e8025ca2 = messages.SavedGifs;
|
||||
messages.savedGifs#2e0709a5 hash:int gifs:Vector<Document> = messages.SavedGifs;
|
||||
|
||||
inputBotInlineMessageMediaAuto#292fed13 flags:# caption:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaAuto#3380c786 flags:# message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageText#3dcd7a87 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaGeo#c1b15d65 flags:# geo_point:InputGeoPoint period:int reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaVenue#aaafadc8 flags:# geo_point:InputGeoPoint title:string address:string provider:string venue_id:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaVenue#417bbf11 flags:# geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageMediaContact#2daf01a7 flags:# phone_number:string first_name:string last_name:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageGame#4b425864 flags:# reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
|
||||
inputBotInlineResult#2cbbe15a flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResult#88bf9319 flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?InputWebDocument content:flags.5?InputWebDocument send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResultPhoto#a8d864a7 id:string type:string photo:InputPhoto send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResultDocument#fff8fdc4 flags:# id:string type:string title:flags.1?string description:flags.2?string document:InputDocument send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResultGame#4fa417f2 id:string short_name:string send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
|
||||
botInlineMessageMediaAuto#a74b15b flags:# caption:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaAuto#764cf810 flags:# message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageText#8c7f65e2 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaGeo#b722de65 flags:# geo:GeoPoint period:int reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaVenue#4366232e flags:# geo:GeoPoint title:string address:string provider:string venue_id:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaVenue#8a86659c flags:# geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaContact#35edb4d4 flags:# phone_number:string first_name:string last_name:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
|
||||
botInlineResult#9bebaeb9 flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:BotInlineMessage = BotInlineResult;
|
||||
botInlineResult#11965f3a flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?WebDocument content:flags.5?WebDocument send_message:BotInlineMessage = BotInlineResult;
|
||||
botInlineMediaResult#17db940b flags:# id:string type:string photo:flags.0?Photo document:flags.1?Document title:flags.2?string description:flags.3?string send_message:BotInlineMessage = BotInlineResult;
|
||||
|
||||
messages.botResults#947ca848 flags:# gallery:flags.0?true query_id:long next_offset:flags.1?string switch_pm:flags.2?InlineBotSwitchPM results:Vector<BotInlineResult> cache_time:int users:Vector<User> = messages.BotResults;
|
||||
|
||||
exportedMessageLink#1f486803 link:string = ExportedMessageLink;
|
||||
exportedMessageLink#5dab1af4 link:string html:string = ExportedMessageLink;
|
||||
|
||||
messageFwdHeader#559ebe6d flags:# from_id:flags.0?int date:int channel_id:flags.1?int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int = MessageFwdHeader;
|
||||
|
||||
@@ -752,7 +756,7 @@ messages.featuredStickersNotModified#4ede3cf = messages.FeaturedStickers;
|
||||
messages.featuredStickers#f89d88e5 hash:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
|
||||
|
||||
messages.recentStickersNotModified#b17f890 = messages.RecentStickers;
|
||||
messages.recentStickers#5ce20970 hash:int stickers:Vector<Document> = messages.RecentStickers;
|
||||
messages.recentStickers#22f3afb3 hash:int packs:Vector<StickerPack> stickers:Vector<Document> dates:Vector<int> = messages.RecentStickers;
|
||||
|
||||
messages.archivedStickers#4fcba9c8 count:int sets:Vector<StickerSetCovered> = messages.ArchivedStickers;
|
||||
|
||||
@@ -834,10 +838,13 @@ paymentRequestedInfo#909c3f94 flags:# name:flags.0?string phone:flags.1?string e
|
||||
paymentSavedCredentialsCard#cdc27a1f id:string title:string = PaymentSavedCredentials;
|
||||
|
||||
webDocument#c61acbd8 url:string access_hash:long size:int mime_type:string attributes:Vector<DocumentAttribute> dc_id:int = WebDocument;
|
||||
webDocumentNoProxy#f9c8bcc6 url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = WebDocument;
|
||||
|
||||
inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = InputWebDocument;
|
||||
|
||||
inputWebFileLocation#c239d686 url:string access_hash:long = InputWebFileLocation;
|
||||
inputWebFileGeoPointLocation#66275a62 geo_point:InputGeoPoint w:int h:int zoom:int scale:int = InputWebFileLocation;
|
||||
inputWebFileGeoMessageLocation#553f32eb peer:InputPeer msg_id:int w:int h:int zoom:int scale:int = InputWebFileLocation;
|
||||
|
||||
upload.webFile#21e753bc size:int mime_type:string file_type:storage.FileType mtime:int bytes:bytes = upload.WebFile;
|
||||
|
||||
@@ -855,7 +862,7 @@ payments.savedInfo#fb8fe43c flags:# has_saved_credentials:flags.1?true saved_inf
|
||||
inputPaymentCredentialsSaved#c10eb2cf id:string tmp_password:bytes = InputPaymentCredentials;
|
||||
inputPaymentCredentials#3417d728 flags:# save:flags.0?true data:DataJSON = InputPaymentCredentials;
|
||||
inputPaymentCredentialsApplePay#aa1c39f payment_data:DataJSON = InputPaymentCredentials;
|
||||
inputPaymentCredentialsAndroidPay#795667a6 payment_token:DataJSON = InputPaymentCredentials;
|
||||
inputPaymentCredentialsAndroidPay#ca05d50e payment_token:DataJSON google_transaction_id:string = InputPaymentCredentials;
|
||||
|
||||
account.tmpPassword#db64fd34 tmp_password:bytes valid_until:int = account.TmpPassword;
|
||||
|
||||
@@ -893,7 +900,7 @@ langPackDifference#f385c1f6 lang_code:string from_version:int version:int string
|
||||
|
||||
langPackLanguage#117698f1 name:string native_name:string lang_code:string = LangPackLanguage;
|
||||
|
||||
channelAdminRights#5d7ceba5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true invite_link:flags.6?true pin_messages:flags.7?true add_admins:flags.9?true = ChannelAdminRights;
|
||||
channelAdminRights#5d7ceba5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true invite_link:flags.6?true pin_messages:flags.7?true add_admins:flags.9?true manage_call:flags.10?true = ChannelAdminRights;
|
||||
|
||||
channelBannedRights#58cf4249 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true until_date:int = ChannelBannedRights;
|
||||
|
||||
@@ -922,8 +929,6 @@ channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?tru
|
||||
|
||||
popularContact#5ce14175 client_id:long importers:int = PopularContact;
|
||||
|
||||
cdnFileHash#77eec38f offset:int limit:int hash:bytes = CdnFileHash;
|
||||
|
||||
messages.favedStickersNotModified#9e8fa6d3 = messages.FavedStickers;
|
||||
messages.favedStickers#f37f2f16 hash:int packs:Vector<StickerPack> stickers:Vector<Document> = messages.FavedStickers;
|
||||
|
||||
@@ -935,17 +940,88 @@ recentMeUrlStickerSet#bc0a57dc url:string set:StickerSetCovered = RecentMeUrl;
|
||||
|
||||
help.recentMeUrls#e0310d7 urls:Vector<RecentMeUrl> chats:Vector<Chat> users:Vector<User> = help.RecentMeUrls;
|
||||
|
||||
inputSingleMedia#5eaa7809 media:InputMedia random_id:long = InputSingleMedia;
|
||||
inputSingleMedia#1cc6e91f flags:# media:InputMedia random_id:long message:string entities:flags.0?Vector<MessageEntity> = InputSingleMedia;
|
||||
|
||||
webAuthorization#cac943f2 hash:long bot_id:int domain:string browser:string platform:string date_created:int date_active:int ip:string region:string = WebAuthorization;
|
||||
|
||||
account.webAuthorizations#ed56c9fc authorizations:Vector<WebAuthorization> users:Vector<User> = account.WebAuthorizations;
|
||||
|
||||
inputMessageID#a676a322 id:int = InputMessage;
|
||||
inputMessageReplyTo#bad88395 id:int = InputMessage;
|
||||
inputMessagePinned#86872538 = InputMessage;
|
||||
|
||||
inputDialogPeer#fcaafeb7 peer:InputPeer = InputDialogPeer;
|
||||
|
||||
dialogPeer#e56dbf05 peer:Peer = DialogPeer;
|
||||
|
||||
messages.foundStickerSetsNotModified#d54b65d = messages.FoundStickerSets;
|
||||
messages.foundStickerSets#5108d648 hash:int sets:Vector<StickerSetCovered> = messages.FoundStickerSets;
|
||||
|
||||
fileHash#6242c773 offset:int limit:int hash:bytes = FileHash;
|
||||
|
||||
inputClientProxy#75588b3f address:string port:int = InputClientProxy;
|
||||
|
||||
help.proxyDataEmpty#e09e1fb8 expires:int = help.ProxyData;
|
||||
help.proxyDataPromo#2bf7ee23 expires:int peer:Peer chats:Vector<Chat> users:Vector<User> = help.ProxyData;
|
||||
|
||||
help.termsOfServiceUpdateEmpty#e3309f7f expires:int = help.TermsOfServiceUpdate;
|
||||
help.termsOfServiceUpdate#28ecf961 expires:int terms_of_service:help.TermsOfService = help.TermsOfServiceUpdate;
|
||||
|
||||
inputSecureFileUploaded#3334b0f0 id:long parts:int md5_checksum:string file_hash:bytes secret:bytes = InputSecureFile;
|
||||
inputSecureFile#5367e5be id:long access_hash:long = InputSecureFile;
|
||||
|
||||
secureFileEmpty#64199744 = SecureFile;
|
||||
secureFile#e0277a62 id:long access_hash:long size:int dc_id:int date:int file_hash:bytes secret:bytes = SecureFile;
|
||||
|
||||
secureData#8aeabec3 data:bytes data_hash:bytes secret:bytes = SecureData;
|
||||
|
||||
securePlainPhone#7d6099dd phone:string = SecurePlainData;
|
||||
securePlainEmail#21ec5a5f email:string = SecurePlainData;
|
||||
|
||||
secureValueTypePersonalDetails#9d2a81e3 = SecureValueType;
|
||||
secureValueTypePassport#3dac6a00 = SecureValueType;
|
||||
secureValueTypeDriverLicense#6e425c4 = SecureValueType;
|
||||
secureValueTypeIdentityCard#a0d0744b = SecureValueType;
|
||||
secureValueTypeInternalPassport#99a48f23 = SecureValueType;
|
||||
secureValueTypeAddress#cbe31e26 = SecureValueType;
|
||||
secureValueTypeUtilityBill#fc36954e = SecureValueType;
|
||||
secureValueTypeBankStatement#89137c0d = SecureValueType;
|
||||
secureValueTypeRentalAgreement#8b883488 = SecureValueType;
|
||||
secureValueTypePassportRegistration#99e3806a = SecureValueType;
|
||||
secureValueTypeTemporaryRegistration#ea02ec33 = SecureValueType;
|
||||
secureValueTypePhone#b320aadb = SecureValueType;
|
||||
secureValueTypeEmail#8e3ca7ee = SecureValueType;
|
||||
|
||||
secureValue#b4b4b699 flags:# type:SecureValueType data:flags.0?SecureData front_side:flags.1?SecureFile reverse_side:flags.2?SecureFile selfie:flags.3?SecureFile files:flags.4?Vector<SecureFile> plain_data:flags.5?SecurePlainData hash:bytes = SecureValue;
|
||||
|
||||
inputSecureValue#67872e8 flags:# type:SecureValueType data:flags.0?SecureData front_side:flags.1?InputSecureFile reverse_side:flags.2?InputSecureFile selfie:flags.3?InputSecureFile files:flags.4?Vector<InputSecureFile> plain_data:flags.5?SecurePlainData = InputSecureValue;
|
||||
|
||||
secureValueHash#ed1ecdb0 type:SecureValueType hash:bytes = SecureValueHash;
|
||||
|
||||
secureValueErrorData#e8a40bd9 type:SecureValueType data_hash:bytes field:string text:string = SecureValueError;
|
||||
secureValueErrorFrontSide#be3dfa type:SecureValueType file_hash:bytes text:string = SecureValueError;
|
||||
secureValueErrorReverseSide#868a2aa5 type:SecureValueType file_hash:bytes text:string = SecureValueError;
|
||||
secureValueErrorSelfie#e537ced6 type:SecureValueType file_hash:bytes text:string = SecureValueError;
|
||||
secureValueErrorFile#7a700873 type:SecureValueType file_hash:bytes text:string = SecureValueError;
|
||||
secureValueErrorFiles#666220e9 type:SecureValueType file_hash:Vector<bytes> text:string = SecureValueError;
|
||||
|
||||
secureCredentialsEncrypted#33f0ea47 data:bytes hash:bytes secret:bytes = SecureCredentialsEncrypted;
|
||||
|
||||
account.authorizationForm#cb976d53 flags:# selfie_required:flags.1?true required_types:Vector<SecureValueType> values:Vector<SecureValue> errors:Vector<SecureValueError> users:Vector<User> privacy_policy_url:flags.0?string = account.AuthorizationForm;
|
||||
|
||||
account.sentEmailCode#811f854f email_pattern:string length:int = account.SentEmailCode;
|
||||
|
||||
help.deepLinkInfoEmpty#66afa166 = help.DeepLinkInfo;
|
||||
help.deepLinkInfo#6a4ee832 flags:# update_app:flags.0?true message:string entities:flags.1?Vector<MessageEntity> = help.DeepLinkInfo;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
|
||||
initConnection#c7481da6 {X:Type} api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string query:!X = X;
|
||||
initConnection#785188b8 {X:Type} flags:# api_id:int device_model:string system_version:string app_version:string system_lang_code:string lang_pack:string lang_code:string proxy:flags.0?InputClientProxy query:!X = X;
|
||||
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
|
||||
invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
|
||||
|
||||
auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
|
||||
auth.sendCode#86aef0ec flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool api_id:int api_hash:string = auth.SentCode;
|
||||
auth.signUp#1b067634 phone_number:string phone_code_hash:string phone_code:string first_name:string last_name:string = auth.Authorization;
|
||||
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
|
||||
@@ -963,8 +1039,8 @@ auth.resendCode#3ef1a9bf phone_number:string phone_code_hash:string = auth.SentC
|
||||
auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool;
|
||||
auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool;
|
||||
|
||||
account.registerDevice#637ea878 token_type:int token:string = Bool;
|
||||
account.unregisterDevice#65c55b40 token_type:int token:string = Bool;
|
||||
account.registerDevice#5cbea590 token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector<int> = Bool;
|
||||
account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector<int> = Bool;
|
||||
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
|
||||
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
||||
account.resetNotifySettings#db7e1747 = Bool;
|
||||
@@ -990,9 +1066,23 @@ account.updatePasswordSettings#fa7c4b86 current_password_hash:bytes new_settings
|
||||
account.sendConfirmPhoneCode#1516d7bd flags:# allow_flashcall:flags.0?true hash:string current_number:flags.0?Bool = auth.SentCode;
|
||||
account.confirmPhone#5f2178c3 phone_code_hash:string phone_code:string = Bool;
|
||||
account.getTmpPassword#4a82327e password_hash:bytes period:int = account.TmpPassword;
|
||||
account.getWebAuthorizations#182e6d6f = account.WebAuthorizations;
|
||||
account.resetWebAuthorization#2d01b9ef hash:long = Bool;
|
||||
account.resetWebAuthorizations#682d2594 = Bool;
|
||||
account.getAllSecureValues#b288bc7d = Vector<SecureValue>;
|
||||
account.getSecureValue#73665bc2 types:Vector<SecureValueType> = Vector<SecureValue>;
|
||||
account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long = SecureValue;
|
||||
account.deleteSecureValue#b880bc4b types:Vector<SecureValueType> = Bool;
|
||||
account.getAuthorizationForm#b86ba8e1 bot_id:int scope:string public_key:string = account.AuthorizationForm;
|
||||
account.acceptAuthorization#e7027c94 bot_id:int scope:string public_key:string value_hashes:Vector<SecureValueHash> credentials:SecureCredentialsEncrypted = Bool;
|
||||
account.sendVerifyPhoneCode#823380b4 flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode;
|
||||
account.verifyPhone#4dd3a7f6 phone_number:string phone_code_hash:string phone_code:string = Bool;
|
||||
account.sendVerifyEmailCode#7011509f email:string = account.SentEmailCode;
|
||||
account.verifyEmail#ecba39db email:string code:string = Bool;
|
||||
|
||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
|
||||
users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector<SecureValueError> = Bool;
|
||||
|
||||
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
|
||||
contacts.getContacts#c023849f hash:int = contacts.Contacts;
|
||||
@@ -1010,21 +1100,22 @@ contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.
|
||||
contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool;
|
||||
contacts.resetSaved#879537f1 = Bool;
|
||||
|
||||
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
|
||||
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
||||
messages.getDialogs#191ba9c5 flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int = messages.Dialogs;
|
||||
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.search#39e9ea0 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
messages.search#8614ef68 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
|
||||
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true peer:InputPeer max_id:int = messages.AffectedHistory;
|
||||
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
|
||||
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
||||
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
|
||||
messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
|
||||
messages.sendMedia#c8f16791 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
|
||||
messages.sendMedia#b8d1262b flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
|
||||
messages.forwardMessages#708e0195 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true grouped:flags.9?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer = Updates;
|
||||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||
messages.hideReportSpam#a8f1709b peer:InputPeer = Bool;
|
||||
messages.getPeerSettings#3672e09c peer:InputPeer = PeerSettings;
|
||||
messages.report#bd82b658 peer:InputPeer id:Vector<int> reason:ReportReason = Bool;
|
||||
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
||||
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
|
||||
messages.editChatTitle#dc452855 chat_id:int title:string = Updates;
|
||||
@@ -1032,7 +1123,6 @@ messages.editChatPhoto#ca4c79d8 chat_id:int photo:InputChatPhoto = Updates;
|
||||
messages.addChatUser#f9a0aa09 chat_id:int user_id:InputUser fwd_limit:int = Updates;
|
||||
messages.deleteChatUser#e0611f16 chat_id:int user_id:InputUser = Updates;
|
||||
messages.createChat#9cb126e users:Vector<InputUser> title:string = Updates;
|
||||
messages.forwardMessage#33963bf9 peer:InputPeer id:int random_id:long = Updates;
|
||||
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
|
||||
messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
|
||||
messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
|
||||
@@ -1045,8 +1135,9 @@ messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long da
|
||||
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
|
||||
messages.reportEncryptedSpam#4b0c8c0f peer:InputEncryptedChat = Bool;
|
||||
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
|
||||
messages.getStickers#43d4f2c emoticon:string hash:int = messages.Stickers;
|
||||
messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
|
||||
messages.getWebPagePreview#25223e24 message:string = MessageMedia;
|
||||
messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
|
||||
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
|
||||
messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
|
||||
messages.importChatInvite#6c50051c hash:string = Updates;
|
||||
@@ -1068,11 +1159,11 @@ messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_p
|
||||
messages.setInlineBotResults#eb5ea206 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM = Bool;
|
||||
messages.sendInlineBotResult#b16e06fe flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
|
||||
messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
|
||||
messages.editMessage#5d1b8dd flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true peer:InputPeer id:int message:flags.11?string reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Updates;
|
||||
messages.editInlineBotMessage#b0e08243 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true id:InputBotInlineMessageID message:flags.11?string reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Bool;
|
||||
messages.editMessage#c000e4c8 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Updates;
|
||||
messages.editInlineBotMessage#adc3e828 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Bool;
|
||||
messages.getBotCallbackAnswer#810a9fec flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes = messages.BotCallbackAnswer;
|
||||
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
|
||||
messages.getPeerDialogs#2d9776b9 peers:Vector<InputPeer> = messages.PeerDialogs;
|
||||
messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
|
||||
messages.saveDraft#bc39e14b flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int peer:InputPeer message:string entities:flags.3?Vector<MessageEntity> = Bool;
|
||||
messages.getAllDrafts#6a3f8d65 = Updates;
|
||||
messages.getFeaturedStickers#2dacca4f hash:int = messages.FeaturedStickers;
|
||||
@@ -1090,8 +1181,8 @@ messages.getInlineGameHighScores#f635e1b id:InputBotInlineMessageID user_id:Inpu
|
||||
messages.getCommonChats#d0a48c4 user_id:InputUser max_id:int limit:int = messages.Chats;
|
||||
messages.getAllChats#eba80ff0 except_ids:Vector<int> = messages.Chats;
|
||||
messages.getWebPage#32ca8f91 url:string hash:int = WebPage;
|
||||
messages.toggleDialogPin#3289be6a flags:# pinned:flags.0?true peer:InputPeer = Bool;
|
||||
messages.reorderPinnedDialogs#959ff644 flags:# force:flags.0?true order:Vector<InputPeer> = Bool;
|
||||
messages.toggleDialogPin#a731e257 flags:# pinned:flags.0?true peer:InputDialogPeer = Bool;
|
||||
messages.reorderPinnedDialogs#5b51d63f flags:# force:flags.0?true order:Vector<InputDialogPeer> = Bool;
|
||||
messages.getPinnedDialogs#e254d64e = messages.PeerDialogs;
|
||||
messages.setBotShippingResults#e5f672fa flags:# query_id:long error:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = Bool;
|
||||
messages.setBotPrecheckoutResults#9c2dd95 flags:# success:flags.1?true query_id:long error:flags.0?string = Bool;
|
||||
@@ -1101,9 +1192,10 @@ messages.getFavedStickers#21ce0b0e hash:int = messages.FavedStickers;
|
||||
messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
|
||||
messages.getUnreadMentions#46578472 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
messages.readMentions#f0189d3 peer:InputPeer = messages.AffectedHistory;
|
||||
messages.getRecentLocations#249431e2 peer:InputPeer limit:int = messages.Messages;
|
||||
messages.getRecentLocations#bbc45b09 peer:InputPeer limit:int hash:int = messages.Messages;
|
||||
messages.sendMultiMedia#2095512f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> = Updates;
|
||||
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
||||
messages.searchStickerSets#c2b7d08b flags:# exclude_featured:flags.0?true q:string hash:int = messages.FoundStickerSets;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
@@ -1119,8 +1211,9 @@ upload.getFile#e3a6cfb5 location:InputFileLocation offset:int limit:int = upload
|
||||
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
|
||||
upload.getWebFile#24e6818d location:InputWebFileLocation offset:int limit:int = upload.WebFile;
|
||||
upload.getCdnFile#2000bcc3 file_token:bytes offset:int limit:int = upload.CdnFile;
|
||||
upload.reuploadCdnFile#1af91c09 file_token:bytes request_token:bytes = Vector<CdnFileHash>;
|
||||
upload.getCdnFileHashes#f715c87b file_token:bytes offset:int = Vector<CdnFileHash>;
|
||||
upload.reuploadCdnFile#9b2754a8 file_token:bytes request_token:bytes = Vector<FileHash>;
|
||||
upload.getCdnFileHashes#4da54231 file_token:bytes offset:int = Vector<FileHash>;
|
||||
upload.getFileHashes#c7025931 location:InputFileLocation offset:int = Vector<FileHash>;
|
||||
|
||||
help.getConfig#c4f9186b = Config;
|
||||
help.getNearestDc#1fb33026 = NearestDc;
|
||||
@@ -1129,16 +1222,19 @@ help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
|
||||
help.getInviteText#4d392343 = help.InviteText;
|
||||
help.getSupport#9cdf08cd = help.Support;
|
||||
help.getAppChangelog#9010ef6f prev_app_version:string = Updates;
|
||||
help.getTermsOfService#350170f3 = help.TermsOfService;
|
||||
help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool;
|
||||
help.getCdnConfig#52029342 = CdnConfig;
|
||||
help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls;
|
||||
help.getProxyData#3d7758e1 = help.ProxyData;
|
||||
help.getTermsOfServiceUpdate#2ca51fd1 = help.TermsOfServiceUpdate;
|
||||
help.acceptTermsOfService#ee72f79a id:DataJSON = Bool;
|
||||
help.getDeepLinkInfo#3fedc75f path:string = help.DeepLinkInfo;
|
||||
|
||||
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
||||
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
||||
channels.deleteUserHistory#d10dd71b channel:InputChannel user_id:InputUser = messages.AffectedHistory;
|
||||
channels.reportSpam#fe087810 channel:InputChannel user_id:InputUser id:Vector<int> = Bool;
|
||||
channels.getMessages#93d7b347 channel:InputChannel id:Vector<int> = messages.Messages;
|
||||
channels.getMessages#ad8c9a23 channel:InputChannel id:Vector<InputMessage> = messages.Messages;
|
||||
channels.getParticipants#123e05e9 channel:InputChannel filter:ChannelParticipantsFilter offset:int limit:int hash:int = channels.ChannelParticipants;
|
||||
channels.getParticipant#546dd7a6 channel:InputChannel user_id:InputUser = channels.ChannelParticipant;
|
||||
channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;
|
||||
@@ -1156,7 +1252,7 @@ channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> =
|
||||
channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite;
|
||||
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
||||
channels.toggleInvites#49609307 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.exportMessageLink#c846d22d channel:InputChannel id:int = ExportedMessageLink;
|
||||
channels.exportMessageLink#ceb77163 channel:InputChannel id:int grouped:Bool = ExportedMessageLink;
|
||||
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
|
||||
channels.getAdminedPublicChannels#8d8d82d7 = messages.Chats;
|
||||
@@ -1196,4 +1292,4 @@ langpack.getStrings#2e1ee318 lang_code:string keys:Vector<string> = Vector<LangP
|
||||
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
|
||||
langpack.getLanguages#800fd57d = Vector<LangPackLanguage>;
|
||||
|
||||
// LAYER 73
|
||||
// LAYER 81
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="1.2.5.0" />
|
||||
Version="1.3.3.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||
|
||||
@@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,2,5,0
|
||||
PRODUCTVERSION 1,2,5,0
|
||||
FILEVERSION 1,3,3,0
|
||||
PRODUCTVERSION 1,3,3,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -52,10 +52,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||
VALUE "FileDescription", "Telegram Desktop"
|
||||
VALUE "FileVersion", "1.2.5.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2017"
|
||||
VALUE "FileVersion", "1.3.3.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2018"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "1.2.5.0"
|
||||
VALUE "ProductVersion", "1.3.3.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,2,5,0
|
||||
PRODUCTVERSION 1,2,5,0
|
||||
FILEVERSION 1,3,3,0
|
||||
PRODUCTVERSION 1,3,3,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -43,10 +43,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||
VALUE "FileDescription", "Telegram Desktop Updater"
|
||||
VALUE "FileVersion", "1.2.5.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2017"
|
||||
VALUE "FileVersion", "1.3.3.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2018"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "1.2.5.0"
|
||||
VALUE "ProductVersion", "1.3.3.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "packer.h"
|
||||
|
||||
@@ -493,7 +480,7 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString countBetaVersionSignature(quint64 version) { // duplicated in autoupdate.cpp
|
||||
QString countBetaVersionSignature(quint64 version) { // duplicated in autoupdater.cpp
|
||||
QByteArray cBetaPrivateKey(BetaPrivateKey);
|
||||
if (cBetaPrivateKey.isEmpty()) {
|
||||
cout << "Error: Trying to count beta version signature without beta private key!\n";
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -30,6 +17,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
extern "C" {
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
@@ -37,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/evp.h>
|
||||
} // extern "C"
|
||||
|
||||
#ifdef Q_OS_WIN // use Lzma SDK for win
|
||||
#include <LzmaLib.h>
|
||||
@@ -47,6 +36,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using std::cout;
|
||||
using std::cout;
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "updater.h"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include <cstdio>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@@ -267,7 +254,7 @@ int main(int argc, const char * argv[]) {
|
||||
forKey:NSWorkspaceLaunchConfigurationArguments]
|
||||
error:&error];
|
||||
if (!result) {
|
||||
writeLog([@"Could not run application, error: " stringByAppendingString:error ? [error localizedDescription] : @"(nil)"]);
|
||||
writeLog([[NSString stringWithFormat:@"Could not run application, error %ld: ", (long)[error code]] stringByAppendingString: error ? [error localizedDescription] : @"(nil)"]);
|
||||
}
|
||||
closeLog();
|
||||
return result ? 0 : -1;
|
||||
|
||||
@@ -1,45 +1,36 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <rpl/event_stream.h>
|
||||
#include "base/timer.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "base/flat_map.h"
|
||||
#include "base/flat_set.h"
|
||||
#include "core/single_timer.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "chat_helpers/stickers.h"
|
||||
#include "data/data_messages.h"
|
||||
|
||||
class TaskQueue;
|
||||
class AuthSession;
|
||||
enum class SparseIdsLoadDirection;
|
||||
struct MessageGroupId;
|
||||
struct SendingAlbum;
|
||||
enum class SendMediaType;
|
||||
|
||||
namespace Storage {
|
||||
enum class SharedMediaType : char;
|
||||
enum class SharedMediaType : signed char;
|
||||
struct PreparedList;
|
||||
} // namespace Storage
|
||||
|
||||
namespace Dialogs {
|
||||
class Key;
|
||||
} // namespace Dialogs
|
||||
|
||||
namespace Api {
|
||||
|
||||
inline const MTPVector<MTPChat> *getChatsFromMessagesChats(const MTPmessages_Chats &chats) {
|
||||
@@ -50,6 +41,16 @@ inline const MTPVector<MTPChat> *getChatsFromMessagesChats(const MTPmessages_Cha
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename IntRange>
|
||||
inline int32 CountHash(IntRange &&range) {
|
||||
uint32 acc = 0;
|
||||
for (auto value : range) {
|
||||
acc += (acc * 20261) + uint32(value);
|
||||
}
|
||||
return int32(acc & 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Api
|
||||
|
||||
class ApiWrap : private MTP::Sender, private base::Subscriber {
|
||||
@@ -58,8 +59,27 @@ public:
|
||||
|
||||
void applyUpdates(const MTPUpdates &updates, uint64 sentMessageRandomId = 0);
|
||||
|
||||
using RequestMessageDataCallback = base::lambda<void(ChannelData*, MsgId)>;
|
||||
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback);
|
||||
void savePinnedOrder();
|
||||
//void toggleChannelGrouping( // #feed
|
||||
// not_null<ChannelData*> channel,
|
||||
// bool group,
|
||||
// Fn<void()> callback);
|
||||
//void ungroupAllFromFeed(not_null<Data::Feed*> feed);
|
||||
|
||||
using RequestMessageDataCallback = Fn<void(ChannelData*, MsgId)>;
|
||||
void requestMessageData(
|
||||
ChannelData *channel,
|
||||
MsgId msgId,
|
||||
RequestMessageDataCallback callback);
|
||||
|
||||
void requestContacts();
|
||||
void requestDialogEntry(not_null<Data::Feed*> feed);
|
||||
//void requestFeedDialogsEntries(not_null<Data::Feed*> feed);
|
||||
void requestDialogEntry(not_null<History*> history);
|
||||
//void applyFeedSources(const MTPDchannels_feedSources &data); // #feed
|
||||
//void setFeedChannels(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// const std::vector<not_null<ChannelData*>> &channels);
|
||||
|
||||
void requestFullPeer(PeerData *peer);
|
||||
void requestPeer(PeerData *peer);
|
||||
@@ -68,17 +88,27 @@ public:
|
||||
void requestBots(not_null<ChannelData*> channel);
|
||||
void requestAdmins(not_null<ChannelData*> channel);
|
||||
void requestParticipantsCountDelayed(not_null<ChannelData*> channel);
|
||||
void requestChannelRangeDifference(not_null<History*> history);
|
||||
|
||||
void requestChangelog(
|
||||
const QString &sinceVersion,
|
||||
base::lambda<void(const MTPUpdates &result)> callback);
|
||||
Fn<void(const MTPUpdates &result)> callback);
|
||||
void refreshProxyPromotion();
|
||||
void requestDeepLinkInfo(
|
||||
const QString &path,
|
||||
Fn<void(const MTPDhelp_deepLinkInfo &result)> callback);
|
||||
void requestTermsUpdate();
|
||||
void acceptTerms(bytes::const_span termsId);
|
||||
|
||||
void requestChannelMembersForAdd(
|
||||
not_null<ChannelData*> channel,
|
||||
base::lambda<void(const MTPchannels_ChannelParticipants&)> callback);
|
||||
Fn<void(const MTPchannels_ChannelParticipants&)> callback);
|
||||
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
|
||||
void processFullPeer(UserData *user, const MTPUserFull &result);
|
||||
|
||||
void markMediaRead(const base::flat_set<not_null<HistoryItem*>> &items);
|
||||
void markMediaRead(not_null<HistoryItem*> item);
|
||||
|
||||
void requestSelfParticipant(ChannelData *channel);
|
||||
void kickParticipant(not_null<ChatData*> chat, not_null<UserData*> user);
|
||||
void kickParticipant(
|
||||
@@ -88,6 +118,9 @@ public:
|
||||
void unblockParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user);
|
||||
void deleteAllFromUser(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> from);
|
||||
|
||||
void requestWebPageDelayed(WebPageData *page);
|
||||
void clearWebPageRequest(WebPageData *page);
|
||||
@@ -95,20 +128,27 @@ public:
|
||||
|
||||
void scheduleStickerSetRequest(uint64 setId, uint64 access);
|
||||
void requestStickerSets();
|
||||
void saveStickerSets(const Stickers::Order &localOrder, const Stickers::Order &localRemoved);
|
||||
void saveStickerSets(
|
||||
const Stickers::Order &localOrder,
|
||||
const Stickers::Order &localRemoved);
|
||||
void updateStickers();
|
||||
void setGroupStickerSet(not_null<ChannelData*> megagroup, const MTPInputStickerSet &set);
|
||||
void requestRecentStickersForce();
|
||||
void setGroupStickerSet(
|
||||
not_null<ChannelData*> megagroup,
|
||||
const MTPInputStickerSet &set);
|
||||
std::vector<not_null<DocumentData*>> *stickersByEmoji(
|
||||
not_null<EmojiPtr> emoji);
|
||||
|
||||
void joinChannel(ChannelData *channel);
|
||||
void leaveChannel(ChannelData *channel);
|
||||
void joinChannel(not_null<ChannelData*> channel);
|
||||
void leaveChannel(not_null<ChannelData*> channel);
|
||||
|
||||
void blockUser(UserData *user);
|
||||
void unblockUser(UserData *user);
|
||||
void blockUser(not_null<UserData*> user);
|
||||
void unblockUser(not_null<UserData*> user);
|
||||
|
||||
void exportInviteLink(PeerData *peer);
|
||||
void requestNotifySetting(PeerData *peer);
|
||||
|
||||
void saveDraftToCloudDelayed(History *history);
|
||||
void exportInviteLink(not_null<PeerData*> peer);
|
||||
void requestNotifySettings(const MTPInputNotifyPeer &peer);
|
||||
void updateNotifySettingsDelayed(not_null<const PeerData*> peer);
|
||||
void saveDraftToCloudDelayed(not_null<History*> history);
|
||||
|
||||
void savePrivacy(const MTPInputPrivacyKey &key, QVector<MTPInputPrivacyRule> &&rules);
|
||||
void handlePrivacyChange(mtpTypeId keyTypeId, const MTPVector<MTPPrivacyRule> &rules);
|
||||
@@ -125,7 +165,7 @@ public:
|
||||
void applyUpdatesNoPtsCheck(const MTPUpdates &updates);
|
||||
void applyUpdateNoPtsCheck(const MTPUpdate &update);
|
||||
|
||||
void jumpToDate(not_null<PeerData*> peer, const QDate &date);
|
||||
void jumpToDate(Dialogs::Key chat, const QDate &date);
|
||||
|
||||
void preloadEnoughUnreadMentions(not_null<History*> history);
|
||||
void checkForUnreadMentions(const base::flat_set<MsgId> &possiblyReadMentions, ChannelData *channel = nullptr);
|
||||
@@ -135,7 +175,7 @@ public:
|
||||
bool adminsEnabled,
|
||||
base::flat_set<not_null<UserData*>> &&admins);
|
||||
|
||||
using SliceType = SparseIdsLoadDirection;
|
||||
using SliceType = Data::LoadDirection;
|
||||
void requestSharedMedia(
|
||||
not_null<PeerData*> peer,
|
||||
Storage::SharedMediaType type,
|
||||
@@ -149,6 +189,14 @@ public:
|
||||
not_null<UserData*> user,
|
||||
PhotoId afterId);
|
||||
|
||||
//void requestFeedChannels( // #feed
|
||||
// not_null<Data::Feed*> feed);
|
||||
//void requestFeedMessages(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// Data::MessagePosition messageId,
|
||||
// SliceType slice);
|
||||
//void saveDefaultFeedId(FeedId id, bool isDefaultFeedId);
|
||||
|
||||
void stickerSetInstalled(uint64 setId) {
|
||||
_stickerSetInstalled.fire_copy(setId);
|
||||
}
|
||||
@@ -160,17 +208,17 @@ public:
|
||||
void parseChannelParticipants(
|
||||
not_null<ChannelData*> channel,
|
||||
const MTPchannels_ChannelParticipants &result,
|
||||
base::lambda<void(
|
||||
Fn<void(
|
||||
int availableCount,
|
||||
const QVector<MTPChannelParticipant> &list)> callbackList,
|
||||
base::lambda<void()> callbackNotModified = nullptr);
|
||||
Fn<void()> callbackNotModified = nullptr);
|
||||
void parseRecentChannelParticipants(
|
||||
not_null<ChannelData*> channel,
|
||||
const MTPchannels_ChannelParticipants &result,
|
||||
base::lambda<void(
|
||||
Fn<void(
|
||||
int availableCount,
|
||||
const QVector<MTPChannelParticipant> &list)> callbackList,
|
||||
base::lambda<void()> callbackNotModified = nullptr);
|
||||
Fn<void()> callbackNotModified = nullptr);
|
||||
|
||||
struct SendOptions {
|
||||
SendOptions(not_null<History*> history) : history(history) {
|
||||
@@ -189,7 +237,7 @@ public:
|
||||
void forwardMessages(
|
||||
HistoryItemsList &&items,
|
||||
const SendOptions &options,
|
||||
base::lambda_once<void()> &&successCallback = nullptr);
|
||||
FnMut<void()> &&successCallback = nullptr);
|
||||
void shareContact(
|
||||
const QString &phone,
|
||||
const QString &firstName,
|
||||
@@ -198,6 +246,9 @@ public:
|
||||
void shareContact(not_null<UserData*> user, const SendOptions &options);
|
||||
void readServerHistory(not_null<History*> history);
|
||||
void readServerHistoryForce(not_null<History*> history);
|
||||
void readFeed(
|
||||
not_null<Data::Feed*> feed,
|
||||
Data::MessagePosition position);
|
||||
|
||||
void sendVoiceMessage(
|
||||
QByteArray result,
|
||||
@@ -207,7 +258,7 @@ public:
|
||||
void sendFiles(
|
||||
Storage::PreparedList &&list,
|
||||
SendMediaType type,
|
||||
QString caption,
|
||||
TextWithTags &&caption,
|
||||
std::shared_ptr<SendingAlbum> album,
|
||||
const SendOptions &options);
|
||||
void sendFile(
|
||||
@@ -237,6 +288,12 @@ private:
|
||||
using MessageDataRequests = QMap<MsgId, MessageDataRequest>;
|
||||
using SharedMediaType = Storage::SharedMediaType;
|
||||
|
||||
struct StickersByEmoji {
|
||||
std::vector<not_null<DocumentData*>> list;
|
||||
int32 hash = 0;
|
||||
TimeMs received = 0;
|
||||
};
|
||||
|
||||
void updatesReceived(const MTPUpdates &updates);
|
||||
void checkQuitPreventFinished();
|
||||
|
||||
@@ -248,8 +305,13 @@ private:
|
||||
ChannelData *channel,
|
||||
mtpRequestId requestId);
|
||||
|
||||
QVector<MTPint> collectMessageIds(const MessageDataRequests &requests);
|
||||
QVector<MTPInputMessage> collectMessageIds(const MessageDataRequests &requests);
|
||||
MessageDataRequests *messageDataRequests(ChannelData *channel, bool onlyExisting = false);
|
||||
void applyPeerDialogs(const MTPmessages_PeerDialogs &dialogs);
|
||||
void historyDialogEntryApplied(not_null<History*> history);
|
||||
void applyFeedDialogs(
|
||||
not_null<Data::Feed*> feed,
|
||||
const MTPmessages_Dialogs &dialogs);
|
||||
|
||||
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
|
||||
void gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req);
|
||||
@@ -266,16 +328,31 @@ private:
|
||||
int availableCount,
|
||||
const QVector<MTPChannelParticipant> &list);
|
||||
void resolveWebPages();
|
||||
void gotWebPages(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req);
|
||||
void gotWebPages(
|
||||
ChannelData *channel,
|
||||
const MTPmessages_Messages &result,
|
||||
mtpRequestId req);
|
||||
void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result);
|
||||
|
||||
PeerData *notifySettingReceived(MTPInputNotifyPeer peer, const MTPPeerNotifySettings &settings);
|
||||
void channelRangeDifferenceSend(
|
||||
not_null<ChannelData*> channel,
|
||||
MsgRange range,
|
||||
int32 pts);
|
||||
void channelRangeDifferenceDone(
|
||||
not_null<ChannelData*> channel,
|
||||
MsgRange range,
|
||||
const MTPupdates_ChannelDifference &result);
|
||||
|
||||
void notifySettingReceived(
|
||||
MTPInputNotifyPeer peer,
|
||||
const MTPPeerNotifySettings &settings);
|
||||
|
||||
void stickerSetDisenabled(mtpRequestId requestId);
|
||||
void stickersSaveOrder();
|
||||
|
||||
void requestStickers(TimeId now);
|
||||
void requestRecentStickers(TimeId now);
|
||||
void requestRecentStickersWithHash(int32 hash);
|
||||
void requestFavedStickers(TimeId now);
|
||||
void requestFeaturedStickers(TimeId now);
|
||||
void requestSavedGifs(TimeId now);
|
||||
@@ -288,11 +365,18 @@ private:
|
||||
not_null<ChannelData*> channel,
|
||||
const QVector<MTPChannelParticipant> &participants);
|
||||
|
||||
void jumpToHistoryDate(not_null<PeerData*> peer, const QDate &date);
|
||||
void jumpToFeedDate(not_null<Data::Feed*> feed, const QDate &date);
|
||||
template <typename Callback>
|
||||
void requestMessageAfterDate(
|
||||
not_null<PeerData*> peer,
|
||||
const QDate &date,
|
||||
Callback &&callback);
|
||||
template <typename Callback>
|
||||
void requestMessageAfterDate(
|
||||
not_null<Data::Feed*> feed,
|
||||
const QDate &date,
|
||||
Callback &&callback);
|
||||
|
||||
void sharedMediaDone(
|
||||
not_null<PeerData*> peer,
|
||||
@@ -306,6 +390,13 @@ private:
|
||||
PhotoId photoId,
|
||||
const MTPphotos_Photos &result);
|
||||
|
||||
//void feedChannelsDone(not_null<Data::Feed*> feed); // #feed
|
||||
//void feedMessagesDone(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// Data::MessagePosition messageId,
|
||||
// SliceType slice,
|
||||
// const MTPmessages_FeedMessages &result);
|
||||
|
||||
void sendSharedContact(
|
||||
const QString &phone,
|
||||
const QString &firstName,
|
||||
@@ -321,6 +412,11 @@ private:
|
||||
void applyAffectedMessages(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPmessages_AffectedMessages &result);
|
||||
|
||||
void deleteAllFromUserSend(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> from);
|
||||
|
||||
void sendMessageFail(const RPCError &error);
|
||||
void uploadAlbumMedia(
|
||||
not_null<HistoryItem*> item,
|
||||
@@ -344,6 +440,13 @@ private:
|
||||
bool silent,
|
||||
uint64 randomId);
|
||||
|
||||
void readFeeds();
|
||||
|
||||
void getProxyPromotionDelayed(TimeId now, TimeId next);
|
||||
void proxyPromotionDone(const MTPhelp_ProxyData &proxy);
|
||||
|
||||
void sendNotifySettingsUpdates();
|
||||
|
||||
not_null<AuthSession*> _session;
|
||||
|
||||
MessageDataRequests _messageDataRequests;
|
||||
@@ -361,7 +464,11 @@ private:
|
||||
|
||||
ChannelData *_channelMembersForAdd = nullptr;
|
||||
mtpRequestId _channelMembersForAddRequestId = 0;
|
||||
base::lambda<void(const MTPchannels_ChannelParticipants&)> _channelMembersForAddCallback;
|
||||
Fn<void(
|
||||
const MTPchannels_ChannelParticipants&)> _channelMembersForAddCallback;
|
||||
base::flat_map<
|
||||
not_null<ChannelData*>,
|
||||
std::pair<mtpRequestId,Fn<void()>>> _channelGroupingRequests;
|
||||
|
||||
using KickRequest = std::pair<
|
||||
not_null<ChannelData*>,
|
||||
@@ -370,18 +477,20 @@ private:
|
||||
|
||||
QMap<ChannelData*, mtpRequestId> _selfParticipantRequests;
|
||||
|
||||
base::flat_map<
|
||||
not_null<ChannelData*>,
|
||||
mtpRequestId> _rangeDifferenceRequests;
|
||||
|
||||
QMap<WebPageData*, mtpRequestId> _webPagesPending;
|
||||
base::Timer _webPagesTimer;
|
||||
|
||||
QMap<uint64, QPair<uint64, mtpRequestId> > _stickerSetRequests;
|
||||
|
||||
QMap<ChannelData*, mtpRequestId> _channelAmInRequests;
|
||||
QMap<UserData*, mtpRequestId> _blockRequests;
|
||||
QMap<PeerData*, mtpRequestId> _exportInviteRequests;
|
||||
|
||||
QMap<PeerData*, mtpRequestId> _notifySettingRequests;
|
||||
|
||||
QMap<History*, mtpRequestId> _draftsSaveRequestIds;
|
||||
base::flat_map<not_null<UserData*>, mtpRequestId> _blockRequests;
|
||||
base::flat_map<not_null<PeerData*>, mtpRequestId> _exportInviteRequests;
|
||||
base::flat_map<PeerId, mtpRequestId> _notifySettingRequests;
|
||||
base::flat_map<not_null<History*>, mtpRequestId> _draftsSaveRequestIds;
|
||||
base::Timer _draftsSaveTimer;
|
||||
|
||||
base::flat_set<mtpRequestId> _stickerSetDisenableRequests;
|
||||
@@ -398,9 +507,14 @@ private:
|
||||
base::Timer _featuredSetsReadTimer;
|
||||
base::flat_set<uint64> _featuredSetsRead;
|
||||
|
||||
QMap<mtpTypeId, mtpRequestId> _privacySaveRequests;
|
||||
base::flat_map<not_null<EmojiPtr>, StickersByEmoji> _stickersByEmoji;
|
||||
|
||||
base::flat_map<mtpTypeId, mtpRequestId> _privacySaveRequests;
|
||||
|
||||
mtpRequestId _contactsRequestId = 0;
|
||||
mtpRequestId _contactsStatusesRequestId = 0;
|
||||
base::flat_set<not_null<Data::Feed*>> _dialogFeedRequests;
|
||||
base::flat_set<not_null<History*>> _dialogRequests;
|
||||
|
||||
base::flat_map<not_null<History*>, mtpRequestId> _unreadMentionsRequests;
|
||||
|
||||
@@ -422,6 +536,20 @@ private:
|
||||
|
||||
base::flat_map<not_null<UserData*>, mtpRequestId> _userPhotosRequests;
|
||||
|
||||
base::flat_set<not_null<Data::Feed*>> _feedChannelsGetRequests;
|
||||
base::flat_map<
|
||||
not_null<Data::Feed*>,
|
||||
mtpRequestId> _feedChannelsSetRequests;
|
||||
base::flat_set<std::tuple<
|
||||
not_null<Data::Feed*>,
|
||||
Data::MessagePosition,
|
||||
SliceType>> _feedMessagesRequests;
|
||||
base::flat_set<std::tuple<
|
||||
not_null<Data::Feed*>,
|
||||
Data::MessagePosition,
|
||||
SliceType>> _feedMessagesRequestsPending;
|
||||
mtpRequestId _saveDefaultFeedIdRequest = 0;
|
||||
|
||||
rpl::event_stream<SendOptions> _sendActions;
|
||||
|
||||
struct ReadRequest {
|
||||
@@ -435,6 +563,7 @@ private:
|
||||
};
|
||||
base::flat_map<not_null<PeerData*>, ReadRequest> _readRequests;
|
||||
base::flat_map<not_null<PeerData*>, MsgId> _readRequestsPending;
|
||||
|
||||
std::unique_ptr<TaskQueue> _fileLoader;
|
||||
base::flat_map<uint64, std::shared_ptr<SendingAlbum>> _sendingAlbums;
|
||||
|
||||
@@ -442,4 +571,21 @@ private:
|
||||
|
||||
rpl::event_stream<uint64> _stickerSetInstalled;
|
||||
|
||||
base::flat_map<not_null<Data::Feed*>, TimeMs> _feedReadsDelayed;
|
||||
base::flat_map<not_null<Data::Feed*>, mtpRequestId> _feedReadRequests;
|
||||
base::Timer _feedReadTimer;
|
||||
|
||||
mtpRequestId _proxyPromotionRequestId = 0;
|
||||
std::pair<QString, uint32> _proxyPromotionKey;
|
||||
TimeId _proxyPromotionNextRequestTime = TimeId(0);
|
||||
base::Timer _proxyPromotionTimer;
|
||||
|
||||
base::flat_set<not_null<const PeerData*>> _updateNotifySettingsPeers;
|
||||
base::Timer _updateNotifySettingsTimer;
|
||||
|
||||
mtpRequestId _deepLinkInfoRequestId = 0;
|
||||
|
||||
TimeMs _termsUpdateSendAt = 0;
|
||||
mtpRequestId _termsUpdateRequestId = 0;
|
||||
|
||||
};
|
||||
|
||||
@@ -1,54 +1,71 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/basic_types.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "layout.h"
|
||||
#include "data/data_types.h"
|
||||
#include "data/data_peer.h"
|
||||
|
||||
enum NewMessageType : char;
|
||||
class Messenger;
|
||||
class MainWindow;
|
||||
class MainWidget;
|
||||
|
||||
using HistoryItemsMap = OrderedSet<HistoryItem*>;
|
||||
using PhotoItems = QHash<PhotoData*, HistoryItemsMap>;
|
||||
using DocumentItems = QHash<DocumentData*, HistoryItemsMap>;
|
||||
using WebPageItems = QHash<WebPageData*, HistoryItemsMap>;
|
||||
using GameItems = QHash<GameData*, HistoryItemsMap>;
|
||||
using SharedContactItems = QHash<int32, HistoryItemsMap>;
|
||||
using GifItems = QHash<Media::Clip::Reader*, HistoryItem*>;
|
||||
|
||||
using PhotosData = QHash<PhotoId, PhotoData*>;
|
||||
using DocumentsData = QHash<DocumentId, DocumentData*>;
|
||||
|
||||
class LocationCoords;
|
||||
struct LocationData;
|
||||
class HistoryItem;
|
||||
class History;
|
||||
class Histories;
|
||||
namespace HistoryView {
|
||||
class Element;
|
||||
} // namespace HistoryView
|
||||
|
||||
using HistoryItemsMap = base::flat_set<not_null<HistoryItem*>>;
|
||||
using GifItems = QHash<Media::Clip::Reader*, HistoryItem*>;
|
||||
|
||||
enum RoundCorners {
|
||||
SmallMaskCorners = 0x00, // for images
|
||||
LargeMaskCorners,
|
||||
|
||||
BoxCorners,
|
||||
MenuCorners,
|
||||
BotKbOverCorners,
|
||||
StickerCorners,
|
||||
StickerSelectedCorners,
|
||||
SelectedOverlaySmallCorners,
|
||||
SelectedOverlayLargeCorners,
|
||||
DateCorners,
|
||||
DateSelectedCorners,
|
||||
ForwardCorners,
|
||||
MediaviewSaveCorners,
|
||||
EmojiHoverCorners,
|
||||
StickerHoverCorners,
|
||||
BotKeyboardCorners,
|
||||
PhotoSelectOverlayCorners,
|
||||
|
||||
Doc1Corners,
|
||||
Doc2Corners,
|
||||
Doc3Corners,
|
||||
Doc4Corners,
|
||||
|
||||
InShadowCorners, // for photos without bg
|
||||
InSelectedShadowCorners,
|
||||
|
||||
MessageInCorners, // with shadow
|
||||
MessageInSelectedCorners,
|
||||
MessageOutCorners,
|
||||
MessageOutSelectedCorners,
|
||||
|
||||
RoundCornersCount
|
||||
};
|
||||
|
||||
namespace App {
|
||||
MainWindow *wnd();
|
||||
MainWidget *main();
|
||||
bool passcoded();
|
||||
|
||||
void logOut();
|
||||
|
||||
QString formatPhone(QString phone);
|
||||
|
||||
@@ -75,18 +92,6 @@ namespace App {
|
||||
|
||||
ImagePtr image(const MTPPhotoSize &size);
|
||||
|
||||
PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs);
|
||||
PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert = nullptr);
|
||||
PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert = nullptr);
|
||||
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb);
|
||||
DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert = nullptr);
|
||||
DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert = nullptr);
|
||||
WebPageData *feedWebPage(const MTPDwebPage &webpage, WebPageData *convert = nullptr);
|
||||
WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert = nullptr);
|
||||
WebPageData *feedWebPage(const MTPWebPage &webpage);
|
||||
WebPageData *feedWebPage(WebPageId webPageId, const QString &siteName, const TextWithEntities &content);
|
||||
GameData *feedGame(const MTPDgame &game, GameData *convert = nullptr);
|
||||
|
||||
PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded);
|
||||
inline UserData *user(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
|
||||
return asUser(peer(id, restriction));
|
||||
@@ -127,19 +132,14 @@ namespace App {
|
||||
inline ChannelData *channelLoaded(ChannelId channelId) {
|
||||
return channel(channelId, PeerData::FullLoaded);
|
||||
}
|
||||
void enumerateUsers(base::lambda<void(UserData*)> action);
|
||||
void enumerateUsers(Fn<void(not_null<UserData*>)> action);
|
||||
void enumerateChatsChannels(
|
||||
Fn<void(not_null<PeerData*>)> action);
|
||||
|
||||
UserData *self();
|
||||
PeerData *peerByName(const QString &username);
|
||||
QString peerName(const PeerData *peer, bool forDialogs = false);
|
||||
PhotoData *photo(const PhotoId &photo);
|
||||
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
|
||||
DocumentData *document(const DocumentId &document);
|
||||
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 version, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation);
|
||||
WebPageData *webPage(const WebPageId &webPage);
|
||||
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill);
|
||||
GameData *game(const GameId &game);
|
||||
GameData *gameSet(const GameId &game, GameData *convert, const uint64 &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc);
|
||||
|
||||
LocationData *location(const LocationCoords &coords);
|
||||
void forgetMedia();
|
||||
|
||||
@@ -147,7 +147,6 @@ namespace App {
|
||||
|
||||
Histories &histories();
|
||||
not_null<History*> history(const PeerId &peer);
|
||||
History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead, int32 maxOutboxRead);
|
||||
History *historyLoaded(const PeerId &peer);
|
||||
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
|
||||
inline not_null<History*> history(const PeerData *peer) {
|
||||
@@ -163,10 +162,9 @@ namespace App {
|
||||
inline HistoryItem *histItemById(const FullMsgId &msgId) {
|
||||
return histItemById(msgId.channel, msgId.msg);
|
||||
}
|
||||
void historyRegItem(HistoryItem *item);
|
||||
void historyItemDetached(HistoryItem *item);
|
||||
void historyUnregItem(HistoryItem *item);
|
||||
void historyUpdateDependent(HistoryItem *item);
|
||||
void historyRegItem(not_null<HistoryItem*> item);
|
||||
void historyUnregItem(not_null<HistoryItem*> item);
|
||||
void historyUpdateDependent(not_null<HistoryItem*> item);
|
||||
void historyClearMsgs();
|
||||
void historyClearItems();
|
||||
void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency);
|
||||
@@ -179,18 +177,16 @@ namespace App {
|
||||
void historyUnregSentData(uint64 randomId);
|
||||
void histSentDataByItem(uint64 randomId, PeerId &peerId, QString &text);
|
||||
|
||||
void hoveredItem(HistoryItem *item);
|
||||
HistoryItem *hoveredItem();
|
||||
void pressedItem(HistoryItem *item);
|
||||
HistoryItem *pressedItem();
|
||||
void hoveredLinkItem(HistoryItem *item);
|
||||
HistoryItem *hoveredLinkItem();
|
||||
void pressedLinkItem(HistoryItem *item);
|
||||
HistoryItem *pressedLinkItem();
|
||||
void contextItem(HistoryItem *item);
|
||||
HistoryItem *contextItem();
|
||||
void mousedItem(HistoryItem *item);
|
||||
HistoryItem *mousedItem();
|
||||
void hoveredItem(HistoryView::Element *item);
|
||||
HistoryView::Element *hoveredItem();
|
||||
void pressedItem(HistoryView::Element *item);
|
||||
HistoryView::Element *pressedItem();
|
||||
void hoveredLinkItem(HistoryView::Element *item);
|
||||
HistoryView::Element *hoveredLinkItem();
|
||||
void pressedLinkItem(HistoryView::Element *item);
|
||||
HistoryView::Element *pressedLinkItem();
|
||||
void mousedItem(HistoryView::Element *item);
|
||||
HistoryView::Element *mousedItem();
|
||||
void clearMousedItems();
|
||||
|
||||
const style::font &monofont();
|
||||
@@ -224,44 +220,6 @@ namespace App {
|
||||
QImage readImage(const QString &file, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr, QByteArray *content = 0);
|
||||
QPixmap pixmapFromImageInPlace(QImage &&image);
|
||||
|
||||
void regPhotoItem(PhotoData *data, HistoryItem *item);
|
||||
void unregPhotoItem(PhotoData *data, HistoryItem *item);
|
||||
const PhotoItems &photoItems();
|
||||
const PhotosData &photosData();
|
||||
|
||||
void regDocumentItem(DocumentData *data, HistoryItem *item);
|
||||
void unregDocumentItem(DocumentData *data, HistoryItem *item);
|
||||
const DocumentItems &documentItems();
|
||||
const DocumentsData &documentsData();
|
||||
|
||||
void regWebPageItem(WebPageData *data, HistoryItem *item);
|
||||
void unregWebPageItem(WebPageData *data, HistoryItem *item);
|
||||
const WebPageItems &webPageItems();
|
||||
|
||||
void regGameItem(GameData *data, HistoryItem *item);
|
||||
void unregGameItem(GameData *data, HistoryItem *item);
|
||||
const GameItems &gameItems();
|
||||
|
||||
void regSharedContactItem(int32 userId, HistoryItem *item);
|
||||
void unregSharedContactItem(int32 userId, HistoryItem *item);
|
||||
const SharedContactItems &sharedContactItems();
|
||||
QString phoneFromSharedContact(int32 userId);
|
||||
|
||||
void regGifItem(Media::Clip::Reader *reader, HistoryItem *item);
|
||||
void unregGifItem(Media::Clip::Reader *reader);
|
||||
void stopRoundVideoPlayback();
|
||||
void stopGifItems();
|
||||
|
||||
void regMuted(not_null<PeerData*> peer, TimeMs changeIn);
|
||||
void unregMuted(not_null<PeerData*> peer);
|
||||
void updateMuted();
|
||||
|
||||
void setProxySettings(QNetworkAccessManager &manager);
|
||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
QNetworkProxy getHttpProxySettings();
|
||||
#endif // !TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
void setProxySettings(QTcpSocket &socket);
|
||||
|
||||
void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
||||
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "application.h"
|
||||
|
||||
@@ -24,15 +11,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "autoupdater.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "core/crash_reports.h"
|
||||
#include "messenger.h"
|
||||
#include "base/timer.h"
|
||||
#include "base/qthelp_url.h"
|
||||
#include "base/qthelp_regex.h"
|
||||
#include "core/update_checker.h"
|
||||
#include "core/crash_report_window.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kEmptyPidForCommandResponse = 0ULL;
|
||||
|
||||
QChar _toHex(ushort v) {
|
||||
v = v & 0x000F;
|
||||
return QChar::fromLatin1((v >= 10) ? ('a' + (v - 10)) : ('0' + v));
|
||||
@@ -73,12 +64,37 @@ QString _escapeFrom7bit(const QString &str) {
|
||||
|
||||
} // namespace
|
||||
|
||||
bool StartUrlRequiresActivate(const QString &url) {
|
||||
const auto urlTrimmed = url.trimmed();
|
||||
if (!urlTrimmed.startsWith(qstr("tg://"), Qt::CaseInsensitive)
|
||||
|| Messenger::Instance().locked()) {
|
||||
return true;
|
||||
}
|
||||
const auto command = urlTrimmed.midRef(qstr("tg://").size());
|
||||
|
||||
using namespace qthelp;
|
||||
const auto matchOptions = RegExOption::CaseInsensitive;
|
||||
const auto authMatch = regex_match(
|
||||
qsl("^passport/?\\?(.+)(#|$)"),
|
||||
command,
|
||||
matchOptions);
|
||||
const auto authLegacyMatch = regex_match(
|
||||
qsl("^resolve/?\\?domain=telegrampassport&(.+)(#|$)"),
|
||||
command,
|
||||
matchOptions);
|
||||
return !authMatch->hasMatch() && !authLegacyMatch->hasMatch();
|
||||
}
|
||||
|
||||
Application::Application(
|
||||
not_null<Core::Launcher*> launcher,
|
||||
int &argc,
|
||||
char **argv)
|
||||
: QApplication(argc, argv)
|
||||
, _launcher(launcher) {
|
||||
, _launcher(launcher)
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
, _updateChecker(std::make_unique<Core::UpdateChecker>())
|
||||
#endif // TDESKTOP_DISABLE_AUTOUPDATE
|
||||
{
|
||||
const auto d = QFile::encodeName(QDir(cWorkingDir()).absolutePath());
|
||||
char h[33] = { 0 };
|
||||
hashMd5Hex(d.constData(), d.size(), h);
|
||||
@@ -99,13 +115,6 @@ Application::Application(
|
||||
QTimer::singleShot(0, this, SLOT(startApplication()));
|
||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication()));
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
_updateCheckTimer.create(this);
|
||||
connect(_updateCheckTimer, SIGNAL(timeout()), this, SLOT(updateCheck()));
|
||||
connect(this, SIGNAL(updateFailed()), this, SLOT(onUpdateFailed()));
|
||||
connect(this, SIGNAL(updateReady()), this, SLOT(onUpdateReady()));
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
if (cManyInstance()) {
|
||||
LOG(("Many instance allowed, starting..."));
|
||||
singleInstanceChecked();
|
||||
@@ -135,8 +144,9 @@ void Application::socketConnected() {
|
||||
}
|
||||
if (!cStartUrl().isEmpty()) {
|
||||
commands += qsl("OPEN:") + _escapeTo7bit(cStartUrl()) + ';';
|
||||
} else {
|
||||
commands += qsl("CMD:show;");
|
||||
}
|
||||
commands += qsl("CMD:show;");
|
||||
|
||||
DEBUG_LOG(("Application Info: writing commands %1").arg(commands));
|
||||
_localSocket.write(commands.toLatin1());
|
||||
@@ -161,7 +171,9 @@ void Application::socketReading() {
|
||||
_localSocketReadData.append(_localSocket.readAll());
|
||||
if (QRegularExpression("RES:(\\d+);").match(_localSocketReadData).hasMatch()) {
|
||||
uint64 pid = _localSocketReadData.mid(4, _localSocketReadData.length() - 5).toULongLong();
|
||||
psActivateProcess(pid);
|
||||
if (pid != kEmptyPidForCommandResponse) {
|
||||
psActivateProcess(pid);
|
||||
}
|
||||
LOG(("Show command response received, pid = %1, activating and quitting...").arg(pid));
|
||||
return App::quit();
|
||||
}
|
||||
@@ -193,7 +205,7 @@ void Application::socketError(QLocalSocket::LocalSocketError e) {
|
||||
#endif // !Q_OS_WINRT
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
if (!cNoStartUpdate() && checkReadyUpdate()) {
|
||||
if (!cNoStartUpdate() && Core::checkReadyUpdate()) {
|
||||
cSetRestartingUpdate(true);
|
||||
DEBUG_LOG(("Application Info: installing update instead of starting app..."));
|
||||
return App::quit();
|
||||
@@ -209,6 +221,7 @@ void Application::singleInstanceChecked() {
|
||||
}
|
||||
|
||||
Sandbox::start();
|
||||
refreshGlobalProxy();
|
||||
|
||||
if (!Logs::started() || (!cManyInstance() && !Logs::instanceChecked())) {
|
||||
new NotStartedWindow();
|
||||
@@ -261,16 +274,26 @@ void Application::readClients() {
|
||||
QStringRef cmd(&cmds, from, to - from);
|
||||
if (cmd.startsWith(qsl("CMD:"))) {
|
||||
Sandbox::execExternal(cmds.mid(from + 4, to - from - 4));
|
||||
QByteArray response(qsl("RES:%1;").arg(QCoreApplication::applicationPid()).toLatin1());
|
||||
const auto response = qsl("RES:%1;").arg(QCoreApplication::applicationPid()).toLatin1();
|
||||
i->first->write(response.data(), response.size());
|
||||
} else if (cmd.startsWith(qsl("SEND:"))) {
|
||||
if (cSendPaths().isEmpty()) {
|
||||
toSend.append(_escapeFrom7bit(cmds.mid(from + 5, to - from - 5)));
|
||||
}
|
||||
} else if (cmd.startsWith(qsl("OPEN:"))) {
|
||||
auto activateRequired = true;
|
||||
if (cStartUrl().isEmpty()) {
|
||||
startUrl = _escapeFrom7bit(cmds.mid(from + 5, to - from - 5)).mid(0, 8192);
|
||||
activateRequired = StartUrlRequiresActivate(startUrl);
|
||||
}
|
||||
if (activateRequired) {
|
||||
Sandbox::execExternal("show");
|
||||
}
|
||||
const auto responsePid = activateRequired
|
||||
? QCoreApplication::applicationPid()
|
||||
: kEmptyPidForCommandResponse;
|
||||
const auto response = qsl("RES:%1;").arg(responsePid).toLatin1();
|
||||
i->first->write(response.data(), response.size());
|
||||
} else {
|
||||
LOG(("Application Error: unknown command %1 passed in local socket").arg(QString(cmd.constData(), cmd.length())));
|
||||
}
|
||||
@@ -320,9 +343,30 @@ void Application::startApplication() {
|
||||
|
||||
void Application::createMessenger() {
|
||||
Expects(!App::quitting());
|
||||
|
||||
_messengerInstance = std::make_unique<Messenger>(_launcher);
|
||||
}
|
||||
|
||||
void Application::refreshGlobalProxy() {
|
||||
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
const auto proxy = [&] {
|
||||
if (Global::started()) {
|
||||
return Global::UseProxy()
|
||||
? Global::SelectedProxy()
|
||||
: ProxyData();
|
||||
}
|
||||
return Sandbox::PreLaunchProxy();
|
||||
}();
|
||||
if (proxy.type == ProxyData::Type::Socks5
|
||||
|| proxy.type == ProxyData::Type::Http) {
|
||||
QNetworkProxy::setApplicationProxy(
|
||||
ToNetworkProxy(ToDirectIpProxy(proxy)));
|
||||
} else {
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||
}
|
||||
#endif // TDESKTOP_DISABLE_NETWORK_PROXY
|
||||
}
|
||||
|
||||
void Application::closeApplication() {
|
||||
if (App::launchState() == App::QuitProcessed) return;
|
||||
App::setLaunchState(App::QuitProcessed);
|
||||
@@ -341,169 +385,10 @@ void Application::closeApplication() {
|
||||
_localSocket.close();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
delete _updateReply;
|
||||
_updateReply = 0;
|
||||
if (_updateChecker) _updateChecker->deleteLater();
|
||||
_updateChecker = 0;
|
||||
if (_updateThread) {
|
||||
_updateThread->quit();
|
||||
}
|
||||
_updateThread = 0;
|
||||
_updateChecker = nullptr;
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void Application::updateCheck() {
|
||||
startUpdateCheck(false);
|
||||
}
|
||||
|
||||
void Application::updateGotCurrent() {
|
||||
if (!_updateReply || _updateThread) return;
|
||||
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("^\\s*(\\d+)\\s*:\\s*([\\x21-\\x7f]+)\\s*$")).match(QString::fromLatin1(_updateReply->readAll()));
|
||||
if (m.hasMatch()) {
|
||||
uint64 currentVersion = m.captured(1).toULongLong();
|
||||
QString url = m.captured(2);
|
||||
bool betaVersion = false;
|
||||
if (url.startsWith(qstr("beta_"))) {
|
||||
betaVersion = true;
|
||||
url = url.mid(5) + '_' + countBetaVersionSignature(currentVersion);
|
||||
}
|
||||
if ((!betaVersion || cBetaVersion()) && currentVersion > (betaVersion ? cBetaVersion() : uint64(AppVersion))) {
|
||||
_updateThread = new QThread();
|
||||
connect(_updateThread, SIGNAL(finished()), _updateThread, SLOT(deleteLater()));
|
||||
_updateChecker = new UpdateChecker(_updateThread, url);
|
||||
_updateThread->start();
|
||||
}
|
||||
}
|
||||
if (_updateReply) _updateReply->deleteLater();
|
||||
_updateReply = 0;
|
||||
if (!_updateThread) {
|
||||
QDir updates(cWorkingDir() + "tupdates");
|
||||
if (updates.exists()) {
|
||||
QFileInfoList list = updates.entryInfoList(QDir::Files);
|
||||
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
|
||||
if (QRegularExpression("^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd)\\d+(_[a-z\\d]+)?$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
|
||||
QFile(i->absoluteFilePath()).remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
emit updateLatest();
|
||||
}
|
||||
startUpdateCheck(true);
|
||||
Local::writeSettings();
|
||||
}
|
||||
|
||||
void Application::updateFailedCurrent(QNetworkReply::NetworkError e) {
|
||||
LOG(("App Error: could not get current version (update check): %1").arg(e));
|
||||
if (_updateReply) _updateReply->deleteLater();
|
||||
_updateReply = 0;
|
||||
|
||||
emit updateFailed();
|
||||
startUpdateCheck(true);
|
||||
}
|
||||
|
||||
void Application::onUpdateReady() {
|
||||
if (_updateChecker) {
|
||||
_updateChecker->deleteLater();
|
||||
_updateChecker = nullptr;
|
||||
}
|
||||
_updateCheckTimer->stop();
|
||||
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
Local::writeSettings();
|
||||
}
|
||||
|
||||
void Application::onUpdateFailed() {
|
||||
if (_updateChecker) {
|
||||
_updateChecker->deleteLater();
|
||||
_updateChecker = 0;
|
||||
if (_updateThread) _updateThread->quit();
|
||||
_updateThread = 0;
|
||||
}
|
||||
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
Local::writeSettings();
|
||||
}
|
||||
|
||||
Application::UpdatingState Application::updatingState() {
|
||||
if (!_updateThread) return Application::UpdatingNone;
|
||||
if (!_updateChecker) return Application::UpdatingReady;
|
||||
return Application::UpdatingDownload;
|
||||
}
|
||||
|
||||
int32 Application::updatingSize() {
|
||||
if (!_updateChecker) return 0;
|
||||
return _updateChecker->size();
|
||||
}
|
||||
|
||||
int32 Application::updatingReady() {
|
||||
if (!_updateChecker) return 0;
|
||||
return _updateChecker->ready();
|
||||
}
|
||||
|
||||
void Application::stopUpdate() {
|
||||
if (_updateReply) {
|
||||
_updateReply->abort();
|
||||
_updateReply->deleteLater();
|
||||
_updateReply = 0;
|
||||
}
|
||||
if (_updateChecker) {
|
||||
_updateChecker->deleteLater();
|
||||
_updateChecker = 0;
|
||||
if (_updateThread) _updateThread->quit();
|
||||
_updateThread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::startUpdateCheck(bool forceWait) {
|
||||
if (!Sandbox::started()) return;
|
||||
|
||||
_updateCheckTimer->stop();
|
||||
if (_updateThread || _updateReply || !cAutoUpdate() || cExeName().isEmpty()) return;
|
||||
|
||||
int32 constDelay = cBetaVersion() ? 600 : UpdateDelayConstPart, randDelay = cBetaVersion() ? 300 : UpdateDelayRandPart;
|
||||
int32 updateInSecs = cLastUpdateCheck() + constDelay + int32(rand() % randDelay) - unixtime();
|
||||
bool sendRequest = (updateInSecs <= 0 || updateInSecs > (constDelay + randDelay));
|
||||
if (!sendRequest && !forceWait) {
|
||||
QDir updates(cWorkingDir() + "tupdates");
|
||||
if (updates.exists()) {
|
||||
QFileInfoList list = updates.entryInfoList(QDir::Files);
|
||||
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
|
||||
if (QRegularExpression("^(tupdate|tmacupd|tmac32upd|tlinuxupd|tlinux32upd)\\d+(_[a-z\\d]+)?$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
|
||||
sendRequest = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cManyInstance() && !cDebug()) return; // only main instance is updating
|
||||
|
||||
if (sendRequest) {
|
||||
QUrl url(cUpdateURL());
|
||||
if (cBetaVersion()) {
|
||||
url.setQuery(qsl("version=%1&beta=%2").arg(AppVersion).arg(cBetaVersion()));
|
||||
} else if (cAlphaVersion()) {
|
||||
url.setQuery(qsl("version=%1&alpha=1").arg(AppVersion));
|
||||
} else {
|
||||
url.setQuery(qsl("version=%1").arg(AppVersion));
|
||||
}
|
||||
QString u = url.toString();
|
||||
QNetworkRequest checkVersion(url);
|
||||
if (_updateReply) _updateReply->deleteLater();
|
||||
|
||||
App::setProxySettings(_updateManager);
|
||||
_updateReply = _updateManager.get(checkVersion);
|
||||
connect(_updateReply, SIGNAL(finished()), this, SLOT(updateGotCurrent()));
|
||||
connect(_updateReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(updateFailedCurrent(QNetworkReply::NetworkError)));
|
||||
emit updateChecking();
|
||||
} else {
|
||||
_updateCheckTimer->start((updateInSecs + 5) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
inline Application *application() {
|
||||
return qobject_cast<Application*>(QApplication::instance());
|
||||
}
|
||||
@@ -555,73 +440,6 @@ void adjustSingleTimers() {
|
||||
base::Timer::Adjust();
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
void startUpdateCheck() {
|
||||
if (auto a = application()) {
|
||||
return a->startUpdateCheck(false);
|
||||
}
|
||||
}
|
||||
|
||||
void stopUpdate() {
|
||||
if (auto a = application()) {
|
||||
return a->stopUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
Application::UpdatingState updatingState() {
|
||||
if (auto a = application()) {
|
||||
return a->updatingState();
|
||||
}
|
||||
return Application::UpdatingNone;
|
||||
}
|
||||
|
||||
int32 updatingSize() {
|
||||
if (auto a = application()) {
|
||||
return a->updatingSize();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 updatingReady() {
|
||||
if (auto a = application()) {
|
||||
return a->updatingReady();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void updateChecking() {
|
||||
if (auto a = application()) {
|
||||
emit a->updateChecking();
|
||||
}
|
||||
}
|
||||
|
||||
void updateLatest() {
|
||||
if (auto a = application()) {
|
||||
emit a->updateLatest();
|
||||
}
|
||||
}
|
||||
|
||||
void updateProgress(qint64 ready, qint64 total) {
|
||||
if (auto a = application()) {
|
||||
emit a->updateProgress(ready, total);
|
||||
}
|
||||
}
|
||||
|
||||
void updateFailed() {
|
||||
if (auto a = application()) {
|
||||
emit a->updateFailed();
|
||||
}
|
||||
}
|
||||
|
||||
void updateReady() {
|
||||
if (auto a = application()) {
|
||||
emit a->updateReady();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
void connect(const char *signal, QObject *object, const char *method) {
|
||||
if (auto a = application()) {
|
||||
a->connect(a, signal, object, method);
|
||||
@@ -661,4 +479,10 @@ void launch() {
|
||||
application()->createMessenger();
|
||||
}
|
||||
|
||||
void refreshGlobalProxy() {
|
||||
if (const auto instance = application()) {
|
||||
instance->refreshGlobalProxy();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Sandbox
|
||||
|
||||
@@ -1,31 +1,19 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class UpdateChecker;
|
||||
|
||||
namespace Core {
|
||||
class Launcher;
|
||||
class UpdateChecker;
|
||||
} // namespace Core
|
||||
|
||||
bool StartUrlRequiresActivate(const QString &url);
|
||||
|
||||
class Application : public QApplication {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -35,6 +23,7 @@ public:
|
||||
bool event(QEvent *e) override;
|
||||
|
||||
void createMessenger();
|
||||
void refreshGlobalProxy();
|
||||
|
||||
~Application();
|
||||
|
||||
@@ -71,46 +60,11 @@ private:
|
||||
|
||||
void singleInstanceChecked();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
// Autoupdating
|
||||
public:
|
||||
void startUpdateCheck(bool forceWait);
|
||||
void stopUpdate();
|
||||
|
||||
enum UpdatingState {
|
||||
UpdatingNone,
|
||||
UpdatingDownload,
|
||||
UpdatingReady,
|
||||
};
|
||||
UpdatingState updatingState();
|
||||
int32 updatingSize();
|
||||
int32 updatingReady();
|
||||
|
||||
signals:
|
||||
void updateChecking();
|
||||
void updateLatest();
|
||||
void updateProgress(qint64 ready, qint64 total);
|
||||
void updateReady();
|
||||
void updateFailed();
|
||||
|
||||
public slots:
|
||||
void updateCheck();
|
||||
|
||||
void updateGotCurrent();
|
||||
void updateFailedCurrent(QNetworkReply::NetworkError e);
|
||||
|
||||
void onUpdateReady();
|
||||
void onUpdateFailed();
|
||||
|
||||
private:
|
||||
object_ptr<SingleTimer> _updateCheckTimer = { nullptr };
|
||||
QNetworkReply *_updateReply = nullptr;
|
||||
QNetworkAccessManager _updateManager;
|
||||
QThread *_updateThread = nullptr;
|
||||
UpdateChecker *_updateChecker = nullptr;
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
std::unique_ptr<Core::UpdateChecker> _updateChecker;
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
};
|
||||
|
||||
namespace Sandbox {
|
||||
@@ -124,22 +78,7 @@ void execExternal(const QString &cmd);
|
||||
|
||||
void adjustSingleTimers();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
void startUpdateCheck();
|
||||
void stopUpdate();
|
||||
|
||||
Application::UpdatingState updatingState();
|
||||
int32 updatingSize();
|
||||
int32 updatingReady();
|
||||
|
||||
void updateChecking();
|
||||
void updateLatest();
|
||||
void updateProgress(qint64 ready, qint64 total);
|
||||
void updateFailed();
|
||||
void updateReady();
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void refreshGlobalProxy();
|
||||
|
||||
void connect(const char *signal, QObject *object, const char *method);
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "auth_session.h"
|
||||
|
||||
@@ -28,7 +15,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include "storage/localstorage.h"
|
||||
#include "storage/storage_facade.h"
|
||||
#include "storage/serialize_common.h"
|
||||
#include "history/history_item_components.h"
|
||||
#include "data/data_session.h"
|
||||
#include "window/notifications_manager.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "platform/platform_specific.h"
|
||||
@@ -43,14 +30,14 @@ constexpr auto kAutoLockTimeoutLateMs = TimeMs(3000);
|
||||
|
||||
} // namespace
|
||||
|
||||
AuthSessionData::Variables::Variables()
|
||||
AuthSessionSettings::Variables::Variables()
|
||||
: sendFilesWay(SendFilesWay::Album)
|
||||
, selectorTab(ChatHelpers::SelectorTab::Emoji)
|
||||
, floatPlayerColumn(Window::Column::Second)
|
||||
, floatPlayerCorner(RectPart::TopRight) {
|
||||
}
|
||||
|
||||
QByteArray AuthSessionData::serialize() const {
|
||||
QByteArray AuthSessionSettings::serialize() const {
|
||||
auto size = sizeof(qint32) * 10;
|
||||
for (auto i = _variables.soundOverrides.cbegin(), e = _variables.soundOverrides.cend(); i != e; ++i) {
|
||||
size += Serialize::stringSize(i.key()) + Serialize::stringSize(i.value());
|
||||
@@ -89,7 +76,7 @@ QByteArray AuthSessionData::serialize() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized) {
|
||||
if (serialized.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -159,7 +146,8 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
thirdSectionExtendedBy = value;
|
||||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("App Error: Bad data for AuthSessionData::constructFromSerialized()"));
|
||||
LOG(("App Error: "
|
||||
"Bad data for AuthSessionSettings::constructFromSerialized()"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,87 +191,7 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
|
||||
}
|
||||
}
|
||||
|
||||
void AuthSessionData::markItemLayoutChanged(not_null<const HistoryItem*> item) {
|
||||
_itemLayoutChanged.fire_copy(item);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const HistoryItem*>> AuthSessionData::itemLayoutChanged() const {
|
||||
return _itemLayoutChanged.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::requestItemRepaint(not_null<const HistoryItem*> item) {
|
||||
_itemRepaintRequest.fire_copy(item);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const HistoryItem*>> AuthSessionData::itemRepaintRequest() const {
|
||||
return _itemRepaintRequest.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::markItemRemoved(not_null<const HistoryItem*> item) {
|
||||
_itemRemoved.fire_copy(item);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const HistoryItem*>> AuthSessionData::itemRemoved() const {
|
||||
return _itemRemoved.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::markHistoryUnloaded(not_null<const History*> history) {
|
||||
_historyUnloaded.fire_copy(history);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const History*>> AuthSessionData::historyUnloaded() const {
|
||||
return _historyUnloaded.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::markHistoryCleared(not_null<const History*> history) {
|
||||
_historyCleared.fire_copy(history);
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const History*>> AuthSessionData::historyCleared() const {
|
||||
return _historyCleared.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::removeMegagroupParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user) {
|
||||
_megagroupParticipantRemoved.fire({ channel, user });
|
||||
}
|
||||
|
||||
auto AuthSessionData::megagroupParticipantRemoved() const -> rpl::producer<MegagroupParticipant> {
|
||||
return _megagroupParticipantRemoved.events();
|
||||
}
|
||||
|
||||
rpl::producer<not_null<UserData*>> AuthSessionData::megagroupParticipantRemoved(
|
||||
not_null<ChannelData*> channel) const {
|
||||
return megagroupParticipantRemoved(
|
||||
) | rpl::filter([channel](auto updateChannel, auto user) {
|
||||
return (updateChannel == channel);
|
||||
}) | rpl::map([](auto updateChannel, auto user) {
|
||||
return user;
|
||||
});
|
||||
}
|
||||
|
||||
void AuthSessionData::addNewMegagroupParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user) {
|
||||
_megagroupParticipantAdded.fire({ channel, user });
|
||||
}
|
||||
|
||||
auto AuthSessionData::megagroupParticipantAdded() const -> rpl::producer<MegagroupParticipant> {
|
||||
return _megagroupParticipantAdded.events();
|
||||
}
|
||||
|
||||
rpl::producer<not_null<UserData*>> AuthSessionData::megagroupParticipantAdded(
|
||||
not_null<ChannelData*> channel) const {
|
||||
return megagroupParticipantAdded(
|
||||
) | rpl::filter([channel](auto updateChannel, auto user) {
|
||||
return (updateChannel == channel);
|
||||
}) | rpl::map([](auto updateChannel, auto user) {
|
||||
return user;
|
||||
});
|
||||
}
|
||||
|
||||
void AuthSessionData::setTabbedSelectorSectionEnabled(bool enabled) {
|
||||
void AuthSessionSettings::setTabbedSelectorSectionEnabled(bool enabled) {
|
||||
_variables.tabbedSelectorSectionEnabled = enabled;
|
||||
if (enabled) {
|
||||
setThirdSectionInfoEnabled(false);
|
||||
@@ -291,12 +199,12 @@ void AuthSessionData::setTabbedSelectorSectionEnabled(bool enabled) {
|
||||
setTabbedReplacedWithInfo(false);
|
||||
}
|
||||
|
||||
rpl::producer<bool> AuthSessionData::tabbedReplacedWithInfoValue() const {
|
||||
rpl::producer<bool> AuthSessionSettings::tabbedReplacedWithInfoValue() const {
|
||||
return _tabbedReplacedWithInfoValue.events_starting_with(
|
||||
tabbedReplacedWithInfo());
|
||||
}
|
||||
|
||||
void AuthSessionData::setThirdSectionInfoEnabled(bool enabled) {
|
||||
void AuthSessionSettings::setThirdSectionInfoEnabled(bool enabled) {
|
||||
if (_variables.thirdSectionInfoEnabled != enabled) {
|
||||
_variables.thirdSectionInfoEnabled = enabled;
|
||||
if (enabled) {
|
||||
@@ -307,19 +215,19 @@ void AuthSessionData::setThirdSectionInfoEnabled(bool enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<bool> AuthSessionData::thirdSectionInfoEnabledValue() const {
|
||||
rpl::producer<bool> AuthSessionSettings::thirdSectionInfoEnabledValue() const {
|
||||
return _thirdSectionInfoEnabledValue.events_starting_with(
|
||||
thirdSectionInfoEnabled());
|
||||
}
|
||||
|
||||
void AuthSessionData::setTabbedReplacedWithInfo(bool enabled) {
|
||||
void AuthSessionSettings::setTabbedReplacedWithInfo(bool enabled) {
|
||||
if (_tabbedReplacedWithInfo != enabled) {
|
||||
_tabbedReplacedWithInfo = enabled;
|
||||
_tabbedReplacedWithInfoValue.fire_copy(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
QString AuthSessionData::getSoundPath(const QString &key) const {
|
||||
QString AuthSessionSettings::getSoundPath(const QString &key) const {
|
||||
auto it = _variables.soundOverrides.constFind(key);
|
||||
if (it != _variables.soundOverrides.end()) {
|
||||
return it.value();
|
||||
@@ -327,75 +235,30 @@ QString AuthSessionData::getSoundPath(const QString &key) const {
|
||||
return qsl(":/sounds/") + key + qsl(".mp3");
|
||||
}
|
||||
|
||||
void AuthSessionData::setDialogsWidthRatio(float64 ratio) {
|
||||
void AuthSessionSettings::setDialogsWidthRatio(float64 ratio) {
|
||||
_variables.dialogsWidthRatio = ratio;
|
||||
}
|
||||
|
||||
float64 AuthSessionData::dialogsWidthRatio() const {
|
||||
float64 AuthSessionSettings::dialogsWidthRatio() const {
|
||||
return _variables.dialogsWidthRatio.current();
|
||||
}
|
||||
|
||||
rpl::producer<float64> AuthSessionData::dialogsWidthRatioChanges() const {
|
||||
rpl::producer<float64> AuthSessionSettings::dialogsWidthRatioChanges() const {
|
||||
return _variables.dialogsWidthRatio.changes();
|
||||
}
|
||||
|
||||
void AuthSessionData::setThirdColumnWidth(int width) {
|
||||
void AuthSessionSettings::setThirdColumnWidth(int width) {
|
||||
_variables.thirdColumnWidth = width;
|
||||
}
|
||||
|
||||
int AuthSessionData::thirdColumnWidth() const {
|
||||
int AuthSessionSettings::thirdColumnWidth() const {
|
||||
return _variables.thirdColumnWidth.current();
|
||||
}
|
||||
|
||||
rpl::producer<int> AuthSessionData::thirdColumnWidthChanges() const {
|
||||
rpl::producer<int> AuthSessionSettings::thirdColumnWidthChanges() const {
|
||||
return _variables.thirdColumnWidth.changes();
|
||||
}
|
||||
|
||||
void AuthSessionData::markStickersUpdated() {
|
||||
_stickersUpdated.fire({});
|
||||
}
|
||||
|
||||
rpl::producer<> AuthSessionData::stickersUpdated() const {
|
||||
return _stickersUpdated.events();
|
||||
}
|
||||
|
||||
void AuthSessionData::markSavedGifsUpdated() {
|
||||
_savedGifsUpdated.fire({});
|
||||
}
|
||||
|
||||
rpl::producer<> AuthSessionData::savedGifsUpdated() const {
|
||||
return _savedGifsUpdated.events();
|
||||
}
|
||||
|
||||
HistoryItemsList AuthSessionData::idsToItems(
|
||||
const MessageIdsList &ids) const {
|
||||
return ranges::view::all(
|
||||
ids
|
||||
) | ranges::view::transform([](const FullMsgId &fullId) {
|
||||
return App::histItemById(fullId);
|
||||
}) | ranges::view::filter([](HistoryItem *item) {
|
||||
return item != nullptr;
|
||||
}) | ranges::view::transform([](HistoryItem *item) {
|
||||
return not_null<HistoryItem*>(item);
|
||||
}) | ranges::to_vector;
|
||||
}
|
||||
|
||||
MessageIdsList AuthSessionData::itemsToIds(
|
||||
const HistoryItemsList &items) const {
|
||||
return ranges::view::all(
|
||||
items
|
||||
) | ranges::view::transform([](not_null<HistoryItem*> item) {
|
||||
return item->fullId();
|
||||
}) | ranges::to_vector;
|
||||
}
|
||||
|
||||
MessageIdsList AuthSessionData::groupToIds(
|
||||
not_null<HistoryMessageGroup*> group) const {
|
||||
auto result = itemsToIds(group->others);
|
||||
result.push_back(group->leader->fullId());
|
||||
return result;
|
||||
}
|
||||
|
||||
AuthSession &Auth() {
|
||||
auto result = Messenger::Instance().authSession();
|
||||
Assert(result != nullptr);
|
||||
@@ -411,16 +274,27 @@ AuthSession::AuthSession(UserId userId)
|
||||
, _uploader(std::make_unique<Storage::Uploader>())
|
||||
, _storage(std::make_unique<Storage::Facade>())
|
||||
, _notifications(std::make_unique<Window::Notifications::System>(this))
|
||||
, _data(std::make_unique<Data::Session>(this))
|
||||
, _changelogs(Core::Changelogs::Create(this)) {
|
||||
Expects(_userId != 0);
|
||||
|
||||
_saveDataTimer.setCallback([this] {
|
||||
_saveDataTimer.setCallback([=] {
|
||||
Local::writeUserSettings();
|
||||
});
|
||||
subscribe(Messenger::Instance().passcodedChanged(), [this] {
|
||||
Messenger::Instance().passcodeLockChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
_shouldLockAt = 0;
|
||||
}, _lifetime);
|
||||
Messenger::Instance().lockChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
notifications().updateAll();
|
||||
}, _lifetime);
|
||||
subscribe(Global::RefConnectionTypeChanged(), [=] {
|
||||
_api->refreshProxyPromotion();
|
||||
});
|
||||
_api->refreshProxyPromotion();
|
||||
_api->requestTermsUpdate();
|
||||
|
||||
Window::Theme::Background()->start();
|
||||
}
|
||||
|
||||
@@ -440,30 +314,37 @@ base::Observable<void> &AuthSession::downloaderTaskFinished() {
|
||||
}
|
||||
|
||||
bool AuthSession::validateSelf(const MTPUser &user) {
|
||||
if (user.type() != mtpc_user || !user.c_user().is_self() || user.c_user().vid.v != userId()) {
|
||||
if (user.type() != mtpc_user || !user.c_user().is_self()) {
|
||||
LOG(("API Error: bad self user received."));
|
||||
return false;
|
||||
} else if (user.c_user().vid.v != userId()) {
|
||||
LOG(("Auth Error: wrong self user received."));
|
||||
App::logOutDelayed();
|
||||
crl::on_main(this, [] { Messenger::Instance().logOut(); });
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AuthSession::saveDataDelayed(TimeMs delay) {
|
||||
void AuthSession::saveSettingsDelayed(TimeMs delay) {
|
||||
Expects(this == &Auth());
|
||||
|
||||
_saveDataTimer.callOnce(delay);
|
||||
}
|
||||
|
||||
void AuthSession::checkAutoLock() {
|
||||
if (!Global::LocalPasscode() || App::passcoded()) return;
|
||||
if (!Global::LocalPasscode()
|
||||
|| Messenger::Instance().passcodeLocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Messenger::Instance().checkLocalTime();
|
||||
auto now = getms(true);
|
||||
auto shouldLockInMs = Global::AutoLock() * 1000LL;
|
||||
auto idleForMs = psIdleTime();
|
||||
auto notPlayingVideoForMs = now - data().lastTimeVideoPlayedAt();
|
||||
auto notPlayingVideoForMs = now - settings().lastTimeVideoPlayedAt();
|
||||
auto checkTimeMs = qMin(idleForMs, notPlayingVideoForMs);
|
||||
if (checkTimeMs >= shouldLockInMs || (_shouldLockAt > 0 && now > _shouldLockAt + kAutoLockTimeoutLateMs)) {
|
||||
Messenger::Instance().setupPasscode();
|
||||
Messenger::Instance().lockByPasscode();
|
||||
} else {
|
||||
_shouldLockAt = now + (shouldLockInMs - checkTimeMs);
|
||||
_autoLockTimer.callOnce(shouldLockInMs - checkTimeMs);
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -24,11 +11,14 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include <rpl/filter.h>
|
||||
#include <rpl/variable.h>
|
||||
#include "base/timer.h"
|
||||
#include "chat_helpers/stickers.h"
|
||||
|
||||
class ApiWrap;
|
||||
enum class SendFilesWay;
|
||||
|
||||
namespace Data {
|
||||
class Session;
|
||||
} // namespace Data
|
||||
|
||||
namespace Storage {
|
||||
class Downloader;
|
||||
class Uploader;
|
||||
@@ -54,65 +44,20 @@ namespace Core {
|
||||
class Changelogs;
|
||||
} // namespace Core
|
||||
|
||||
class AuthSessionData final {
|
||||
class AuthSessionSettings final {
|
||||
public:
|
||||
base::Variable<bool> &contactsLoaded() {
|
||||
return _contactsLoaded;
|
||||
}
|
||||
base::Variable<bool> &allChatsLoaded() {
|
||||
return _allChatsLoaded;
|
||||
}
|
||||
base::Observable<void> &moreChatsLoaded() {
|
||||
return _moreChatsLoaded;
|
||||
}
|
||||
base::Observable<void> &pendingHistoryResize() {
|
||||
return _pendingHistoryResize;
|
||||
}
|
||||
struct ItemVisibilityQuery {
|
||||
not_null<HistoryItem*> item;
|
||||
not_null<bool*> isVisible;
|
||||
};
|
||||
base::Observable<ItemVisibilityQuery> &queryItemVisibility() {
|
||||
return _queryItemVisibility;
|
||||
}
|
||||
void markItemLayoutChanged(not_null<const HistoryItem*> item);
|
||||
rpl::producer<not_null<const HistoryItem*>> itemLayoutChanged() const;
|
||||
void requestItemRepaint(not_null<const HistoryItem*> item);
|
||||
rpl::producer<not_null<const HistoryItem*>> itemRepaintRequest() const;
|
||||
void markItemRemoved(not_null<const HistoryItem*> item);
|
||||
rpl::producer<not_null<const HistoryItem*>> itemRemoved() const;
|
||||
void markHistoryUnloaded(not_null<const History*> history);
|
||||
rpl::producer<not_null<const History*>> historyUnloaded() const;
|
||||
void markHistoryCleared(not_null<const History*> history);
|
||||
rpl::producer<not_null<const History*>> historyCleared() const;
|
||||
using MegagroupParticipant = std::tuple<
|
||||
not_null<ChannelData*>,
|
||||
not_null<UserData*>>;
|
||||
void removeMegagroupParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user);
|
||||
rpl::producer<MegagroupParticipant> megagroupParticipantRemoved() const;
|
||||
rpl::producer<not_null<UserData*>> megagroupParticipantRemoved(
|
||||
not_null<ChannelData*> channel) const;
|
||||
void addNewMegagroupParticipant(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<UserData*> user);
|
||||
rpl::producer<MegagroupParticipant> megagroupParticipantAdded() const;
|
||||
rpl::producer<not_null<UserData*>> megagroupParticipantAdded(
|
||||
not_null<ChannelData*> channel) const;
|
||||
|
||||
void moveFrom(AuthSessionData &&other) {
|
||||
void moveFrom(AuthSessionSettings &&other) {
|
||||
_variables = std::move(other._variables);
|
||||
}
|
||||
QByteArray serialize() const;
|
||||
void constructFromSerialized(const QByteArray &serialized);
|
||||
|
||||
bool lastSeenWarningSeen() const {
|
||||
return _variables.lastSeenWarningSeen;
|
||||
}
|
||||
void setLastSeenWarningSeen(bool lastSeenWarningSeen) {
|
||||
_variables.lastSeenWarningSeen = lastSeenWarningSeen;
|
||||
}
|
||||
bool lastSeenWarningSeen() const {
|
||||
return _variables.lastSeenWarningSeen;
|
||||
}
|
||||
void setSendFilesWay(SendFilesWay way) {
|
||||
_variables.sendFilesWay = way;
|
||||
}
|
||||
@@ -189,10 +134,6 @@ public:
|
||||
int thirdColumnWidth() const;
|
||||
rpl::producer<int> thirdColumnWidthChanges() const;
|
||||
|
||||
void markStickersUpdated();
|
||||
rpl::producer<> stickersUpdated() const;
|
||||
void markSavedGifsUpdated();
|
||||
rpl::producer<> savedGifsUpdated() const;
|
||||
void setGroupStickersSectionHidden(PeerId peerId) {
|
||||
_variables.groupStickersSectionHidden.insert(peerId);
|
||||
}
|
||||
@@ -202,79 +143,6 @@ public:
|
||||
void removeGroupStickersSectionHidden(PeerId peerId) {
|
||||
_variables.groupStickersSectionHidden.remove(peerId);
|
||||
}
|
||||
bool stickersUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastStickersUpdate, now);
|
||||
}
|
||||
void setLastStickersUpdate(TimeMs update) {
|
||||
_lastStickersUpdate = update;
|
||||
}
|
||||
bool recentStickersUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastRecentStickersUpdate, now);
|
||||
}
|
||||
void setLastRecentStickersUpdate(TimeMs update) {
|
||||
_lastRecentStickersUpdate = update;
|
||||
}
|
||||
bool favedStickersUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastFavedStickersUpdate, now);
|
||||
}
|
||||
void setLastFavedStickersUpdate(TimeMs update) {
|
||||
_lastFavedStickersUpdate = update;
|
||||
}
|
||||
bool featuredStickersUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastFeaturedStickersUpdate, now);
|
||||
}
|
||||
void setLastFeaturedStickersUpdate(TimeMs update) {
|
||||
_lastFeaturedStickersUpdate = update;
|
||||
}
|
||||
bool savedGifsUpdateNeeded(TimeMs now) const {
|
||||
return stickersUpdateNeeded(_lastSavedGifsUpdate, now);
|
||||
}
|
||||
void setLastSavedGifsUpdate(TimeMs update) {
|
||||
_lastSavedGifsUpdate = update;
|
||||
}
|
||||
int featuredStickerSetsUnreadCount() const {
|
||||
return _featuredStickerSetsUnreadCount.current();
|
||||
}
|
||||
void setFeaturedStickerSetsUnreadCount(int count) {
|
||||
_featuredStickerSetsUnreadCount = count;
|
||||
}
|
||||
rpl::producer<int> featuredStickerSetsUnreadCountValue() const {
|
||||
return _featuredStickerSetsUnreadCount.value();
|
||||
}
|
||||
const Stickers::Sets &stickerSets() const {
|
||||
return _stickerSets;
|
||||
}
|
||||
Stickers::Sets &stickerSetsRef() {
|
||||
return _stickerSets;
|
||||
}
|
||||
const Stickers::Order &stickerSetsOrder() const {
|
||||
return _stickerSetsOrder;
|
||||
}
|
||||
Stickers::Order &stickerSetsOrderRef() {
|
||||
return _stickerSetsOrder;
|
||||
}
|
||||
const Stickers::Order &featuredStickerSetsOrder() const {
|
||||
return _featuredStickerSetsOrder;
|
||||
}
|
||||
Stickers::Order &featuredStickerSetsOrderRef() {
|
||||
return _featuredStickerSetsOrder;
|
||||
}
|
||||
const Stickers::Order &archivedStickerSetsOrder() const {
|
||||
return _archivedStickerSetsOrder;
|
||||
}
|
||||
Stickers::Order &archivedStickerSetsOrderRef() {
|
||||
return _archivedStickerSetsOrder;
|
||||
}
|
||||
const Stickers::SavedGifs &savedGifs() const {
|
||||
return _savedGifs;
|
||||
}
|
||||
Stickers::SavedGifs &savedGifsRef() {
|
||||
return _savedGifs;
|
||||
}
|
||||
|
||||
HistoryItemsList idsToItems(const MessageIdsList &ids) const;
|
||||
MessageIdsList itemsToIds(const HistoryItemsList &items) const;
|
||||
MessageIdsList groupToIds(not_null<HistoryMessageGroup*> group) const;
|
||||
|
||||
private:
|
||||
struct Variables {
|
||||
@@ -301,39 +169,6 @@ private:
|
||||
= kDefaultThirdColumnWidth; // per-window
|
||||
};
|
||||
|
||||
bool stickersUpdateNeeded(TimeMs lastUpdate, TimeMs now) const {
|
||||
constexpr auto kStickersUpdateTimeout = TimeMs(3600'000);
|
||||
return (lastUpdate == 0)
|
||||
|| (now >= lastUpdate + kStickersUpdateTimeout);
|
||||
}
|
||||
|
||||
base::Variable<bool> _contactsLoaded = { false };
|
||||
base::Variable<bool> _allChatsLoaded = { false };
|
||||
base::Observable<void> _moreChatsLoaded;
|
||||
base::Observable<void> _pendingHistoryResize;
|
||||
base::Observable<ItemVisibilityQuery> _queryItemVisibility;
|
||||
rpl::event_stream<not_null<const HistoryItem*>> _itemLayoutChanged;
|
||||
rpl::event_stream<not_null<const HistoryItem*>> _itemRepaintRequest;
|
||||
rpl::event_stream<not_null<const HistoryItem*>> _itemRemoved;
|
||||
rpl::event_stream<not_null<const History*>> _historyUnloaded;
|
||||
rpl::event_stream<not_null<const History*>> _historyCleared;
|
||||
rpl::event_stream<MegagroupParticipant> _megagroupParticipantRemoved;
|
||||
rpl::event_stream<MegagroupParticipant> _megagroupParticipantAdded;
|
||||
|
||||
rpl::event_stream<> _stickersUpdated;
|
||||
rpl::event_stream<> _savedGifsUpdated;
|
||||
TimeMs _lastStickersUpdate = 0;
|
||||
TimeMs _lastRecentStickersUpdate = 0;
|
||||
TimeMs _lastFavedStickersUpdate = 0;
|
||||
TimeMs _lastFeaturedStickersUpdate = 0;
|
||||
TimeMs _lastSavedGifsUpdate = 0;
|
||||
rpl::variable<int> _featuredStickerSetsUnreadCount = 0;
|
||||
Stickers::Sets _stickerSets;
|
||||
Stickers::Order _stickerSetsOrder;
|
||||
Stickers::Order _featuredStickerSetsOrder;
|
||||
Stickers::Order _archivedStickerSetsOrder;
|
||||
Stickers::SavedGifs _savedGifs;
|
||||
|
||||
rpl::event_stream<bool> _thirdSectionInfoEnabledValue;
|
||||
bool _tabbedReplacedWithInfo = false;
|
||||
rpl::event_stream<bool> _tabbedReplacedWithInfoValue;
|
||||
@@ -347,7 +182,9 @@ private:
|
||||
class AuthSession;
|
||||
AuthSession &Auth();
|
||||
|
||||
class AuthSession final : private base::Subscriber {
|
||||
class AuthSession final
|
||||
: public base::has_weak_ptr
|
||||
, private base::Subscriber {
|
||||
public:
|
||||
AuthSession(UserId userId);
|
||||
|
||||
@@ -381,10 +218,13 @@ public:
|
||||
return *_notifications;
|
||||
}
|
||||
|
||||
AuthSessionData &data() {
|
||||
return _data;
|
||||
Data::Session &data() {
|
||||
return *_data;
|
||||
}
|
||||
void saveDataDelayed(TimeMs delay = kDefaultSaveDelay);
|
||||
AuthSessionSettings &settings() {
|
||||
return _settings;
|
||||
}
|
||||
void saveSettingsDelayed(TimeMs delay = kDefaultSaveDelay);
|
||||
|
||||
ApiWrap &api() {
|
||||
return *_api;
|
||||
@@ -406,7 +246,7 @@ private:
|
||||
static constexpr auto kDefaultSaveDelay = TimeMs(1000);
|
||||
|
||||
const UserId _userId = 0;
|
||||
AuthSessionData _data;
|
||||
AuthSessionSettings _settings;
|
||||
base::Timer _saveDataTimer;
|
||||
|
||||
TimeMs _shouldLockAt = 0;
|
||||
@@ -418,6 +258,13 @@ private:
|
||||
const std::unique_ptr<Storage::Uploader> _uploader;
|
||||
const std::unique_ptr<Storage::Facade> _storage;
|
||||
const std::unique_ptr<Window::Notifications::System> _notifications;
|
||||
|
||||
// _data depends on _downloader / _uploader, including destructor.
|
||||
const std::unique_ptr<Data::Session> _data;
|
||||
|
||||
// _changelogs depends on _data, subscribes on chats loading event.
|
||||
const std::unique_ptr<Core::Changelogs> _changelogs;
|
||||
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
@@ -1,627 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
|
||||
#include "autoupdater.h"
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#ifdef Q_OS_WIN // use Lzma SDK for win
|
||||
#include <LzmaLib.h>
|
||||
#else // Q_OS_WIN
|
||||
#include <lzma.h>
|
||||
#endif // else of Q_OS_WIN
|
||||
|
||||
#include "application.h"
|
||||
#include "platform/platform_specific.h"
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
typedef DWORD VerInt;
|
||||
typedef WCHAR VerChar;
|
||||
#else // Q_OS_WIN
|
||||
typedef int VerInt;
|
||||
typedef wchar_t VerChar;
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
UpdateChecker::UpdateChecker(QThread *thread, const QString &url) : reply(0), already(0), full(0) {
|
||||
updateUrl = url;
|
||||
moveToThread(thread);
|
||||
manager.moveToThread(thread);
|
||||
App::setProxySettings(manager);
|
||||
|
||||
connect(thread, SIGNAL(started()), this, SLOT(start()));
|
||||
initOutput();
|
||||
}
|
||||
|
||||
void UpdateChecker::initOutput() {
|
||||
QString fileName;
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("/([^/\\?]+)(\\?|$)")).match(updateUrl);
|
||||
if (m.hasMatch()) {
|
||||
fileName = m.captured(1).replace(QRegularExpression(qsl("[^a-zA-Z0-9_\\-]")), QString());
|
||||
}
|
||||
if (fileName.isEmpty()) {
|
||||
fileName = qsl("tupdate-%1").arg(rand_value<uint32>() % 1000000);
|
||||
}
|
||||
QString dirStr = cWorkingDir() + qsl("tupdates/");
|
||||
fileName = dirStr + fileName;
|
||||
QFileInfo file(fileName);
|
||||
|
||||
QDir dir(dirStr);
|
||||
if (dir.exists()) {
|
||||
QFileInfoList all = dir.entryInfoList(QDir::Files);
|
||||
for (QFileInfoList::iterator i = all.begin(), e = all.end(); i != e; ++i) {
|
||||
if (i->absoluteFilePath() != file.absoluteFilePath()) {
|
||||
QFile::remove(i->absoluteFilePath());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dir.mkdir(dir.absolutePath());
|
||||
}
|
||||
outputFile.setFileName(fileName);
|
||||
if (file.exists()) {
|
||||
uint64 fullSize = file.size();
|
||||
if (fullSize < INT_MAX) {
|
||||
int32 goodSize = (int32)fullSize;
|
||||
if (goodSize % UpdateChunk) {
|
||||
goodSize = goodSize - (goodSize % UpdateChunk);
|
||||
if (goodSize) {
|
||||
if (outputFile.open(QIODevice::ReadOnly)) {
|
||||
QByteArray goodData = outputFile.readAll().mid(0, goodSize);
|
||||
outputFile.close();
|
||||
if (outputFile.open(QIODevice::WriteOnly)) {
|
||||
outputFile.write(goodData);
|
||||
outputFile.close();
|
||||
|
||||
QMutexLocker lock(&mutex);
|
||||
already = goodSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QMutexLocker lock(&mutex);
|
||||
already = goodSize;
|
||||
}
|
||||
}
|
||||
if (!already) {
|
||||
QFile::remove(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateChecker::start() {
|
||||
sendRequest();
|
||||
}
|
||||
|
||||
void UpdateChecker::sendRequest() {
|
||||
QNetworkRequest req(updateUrl);
|
||||
QByteArray rangeHeaderValue = "bytes=" + QByteArray::number(already) + "-";
|
||||
req.setRawHeader("Range", rangeHeaderValue);
|
||||
req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
|
||||
if (reply) reply->deleteLater();
|
||||
reply = manager.get(req);
|
||||
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(partFinished(qint64,qint64)));
|
||||
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(partFailed(QNetworkReply::NetworkError)));
|
||||
connect(reply, SIGNAL(metaDataChanged()), this, SLOT(partMetaGot()));
|
||||
}
|
||||
|
||||
void UpdateChecker::partMetaGot() {
|
||||
typedef QList<QNetworkReply::RawHeaderPair> Pairs;
|
||||
Pairs pairs = reply->rawHeaderPairs();
|
||||
for (Pairs::iterator i = pairs.begin(), e = pairs.end(); i != e; ++i) {
|
||||
if (QString::fromUtf8(i->first).toLower() == "content-range") {
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("/(\\d+)([^\\d]|$)")).match(QString::fromUtf8(i->second));
|
||||
if (m.hasMatch()) {
|
||||
{
|
||||
QMutexLocker lock(&mutex);
|
||||
full = m.captured(1).toInt();
|
||||
}
|
||||
|
||||
Sandbox::updateProgress(already, full);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32 UpdateChecker::ready() {
|
||||
QMutexLocker lock(&mutex);
|
||||
return already;
|
||||
}
|
||||
|
||||
int32 UpdateChecker::size() {
|
||||
QMutexLocker lock(&mutex);
|
||||
return full;
|
||||
}
|
||||
|
||||
void UpdateChecker::partFinished(qint64 got, qint64 total) {
|
||||
if (!reply) return;
|
||||
|
||||
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||
if (statusCode.isValid()) {
|
||||
int status = statusCode.toInt();
|
||||
if (status != 200 && status != 206 && status != 416) {
|
||||
LOG(("Update Error: Bad HTTP status received in partFinished(): %1").arg(status));
|
||||
return fatalFail();
|
||||
}
|
||||
}
|
||||
|
||||
if (!already && !full) {
|
||||
QMutexLocker lock(&mutex);
|
||||
full = total;
|
||||
}
|
||||
DEBUG_LOG(("Update Info: part %1 of %2").arg(got).arg(total));
|
||||
|
||||
if (!outputFile.isOpen()) {
|
||||
if (!outputFile.open(QIODevice::Append)) {
|
||||
LOG(("Update Error: Could not open output file '%1' for appending").arg(outputFile.fileName()));
|
||||
return fatalFail();
|
||||
}
|
||||
}
|
||||
QByteArray r = reply->readAll();
|
||||
if (!r.isEmpty()) {
|
||||
outputFile.write(r);
|
||||
|
||||
QMutexLocker lock(&mutex);
|
||||
already += r.size();
|
||||
}
|
||||
if (got >= total) {
|
||||
reply->deleteLater();
|
||||
reply = 0;
|
||||
outputFile.close();
|
||||
unpackUpdate();
|
||||
} else {
|
||||
Sandbox::updateProgress(already, full);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateChecker::partFailed(QNetworkReply::NetworkError e) {
|
||||
if (!reply) return;
|
||||
|
||||
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||
reply->deleteLater();
|
||||
reply = 0;
|
||||
if (statusCode.isValid()) {
|
||||
int status = statusCode.toInt();
|
||||
if (status == 416) { // Requested range not satisfiable
|
||||
outputFile.close();
|
||||
unpackUpdate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOG(("Update Error: failed to download part starting from %1, error %2").arg(already).arg(e));
|
||||
Sandbox::updateFailed();
|
||||
}
|
||||
|
||||
void UpdateChecker::fatalFail() {
|
||||
clearAll();
|
||||
Sandbox::updateFailed();
|
||||
}
|
||||
|
||||
void UpdateChecker::clearAll() {
|
||||
psDeleteDir(cWorkingDir() + qsl("tupdates"));
|
||||
}
|
||||
|
||||
//QString winapiErrorWrap() {
|
||||
// WCHAR errMsg[2048];
|
||||
// DWORD errorCode = GetLastError();
|
||||
// LPTSTR errorText = NULL, errorTextDefault = L"(Unknown error)";
|
||||
// FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errorText, 0, 0);
|
||||
// if (!errorText) {
|
||||
// errorText = errorTextDefault;
|
||||
// }
|
||||
// StringCbPrintf(errMsg, sizeof(errMsg), L"Error code: %d, error message: %s", errorCode, errorText);
|
||||
// if (errorText != errorTextDefault) {
|
||||
// LocalFree(errorText);
|
||||
// }
|
||||
// return QString::fromWCharArray(errMsg);
|
||||
//}
|
||||
|
||||
void UpdateChecker::unpackUpdate() {
|
||||
QByteArray packed;
|
||||
if (!outputFile.open(QIODevice::ReadOnly)) {
|
||||
LOG(("Update Error: cant read updates file!"));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN // use Lzma SDK for win
|
||||
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header
|
||||
#else // Q_OS_WIN
|
||||
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = 0, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hOriginalSizeLen; // header
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
QByteArray compressed = outputFile.readAll();
|
||||
int32 compressedLen = compressed.size() - hSize;
|
||||
if (compressedLen <= 0) {
|
||||
LOG(("Update Error: bad compressed size: %1").arg(compressed.size()));
|
||||
return fatalFail();
|
||||
}
|
||||
outputFile.close();
|
||||
|
||||
QString tempDirPath = cWorkingDir() + qsl("tupdates/temp"), readyFilePath = cWorkingDir() + qsl("tupdates/temp/ready");
|
||||
psDeleteDir(tempDirPath);
|
||||
|
||||
QDir tempDir(tempDirPath);
|
||||
if (tempDir.exists() || QFile(readyFilePath).exists()) {
|
||||
LOG(("Update Error: cant clear tupdates/temp dir!"));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
uchar sha1Buffer[20];
|
||||
bool goodSha1 = !memcmp(compressed.constData() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, compressedLen + hPropsLen + hOriginalSizeLen, sha1Buffer), hShaLen);
|
||||
if (!goodSha1) {
|
||||
LOG(("Update Error: bad SHA1 hash of update file!"));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(AppAlphaVersion ? UpdatesPublicAlphaKey : UpdatesPublicKey), -1), 0, 0, 0);
|
||||
if (!pbKey) {
|
||||
LOG(("Update Error: cant read public rsa key!"));
|
||||
return fatalFail();
|
||||
}
|
||||
if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
|
||||
RSA_free(pbKey);
|
||||
if (cAlphaVersion() || cBetaVersion()) { // try other public key, if we are in alpha or beta version
|
||||
pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(AppAlphaVersion ? UpdatesPublicKey : UpdatesPublicAlphaKey), -1), 0, 0, 0);
|
||||
if (!pbKey) {
|
||||
LOG(("Update Error: cant read public rsa key!"));
|
||||
return fatalFail();
|
||||
}
|
||||
if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), hSigLen, pbKey) != 1) { // verify signature
|
||||
RSA_free(pbKey);
|
||||
LOG(("Update Error: bad RSA signature of update file!"));
|
||||
return fatalFail();
|
||||
}
|
||||
} else {
|
||||
LOG(("Update Error: bad RSA signature of update file!"));
|
||||
return fatalFail();
|
||||
}
|
||||
}
|
||||
RSA_free(pbKey);
|
||||
|
||||
QByteArray uncompressed;
|
||||
|
||||
int32 uncompressedLen;
|
||||
memcpy(&uncompressedLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen);
|
||||
uncompressed.resize(uncompressedLen);
|
||||
|
||||
size_t resultLen = uncompressed.size();
|
||||
#ifdef Q_OS_WIN // use Lzma SDK for win
|
||||
SizeT srcLen = compressedLen;
|
||||
int uncompressRes = LzmaUncompress((uchar*)uncompressed.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
|
||||
if (uncompressRes != SZ_OK) {
|
||||
LOG(("Update Error: could not uncompress lzma, code: %1").arg(uncompressRes));
|
||||
return fatalFail();
|
||||
}
|
||||
#else // Q_OS_WIN
|
||||
lzma_stream stream = LZMA_STREAM_INIT;
|
||||
|
||||
lzma_ret ret = lzma_stream_decoder(&stream, UINT64_MAX, LZMA_CONCATENATED);
|
||||
if (ret != LZMA_OK) {
|
||||
const char *msg;
|
||||
switch (ret) {
|
||||
case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
|
||||
case LZMA_OPTIONS_ERROR: msg = "Specified preset is not supported"; break;
|
||||
case LZMA_UNSUPPORTED_CHECK: msg = "Specified integrity check is not supported"; break;
|
||||
default: msg = "Unknown error, possibly a bug"; break;
|
||||
}
|
||||
LOG(("Error initializing the decoder: %1 (error code %2)").arg(msg).arg(ret));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
stream.avail_in = compressedLen;
|
||||
stream.next_in = (uint8_t*)(compressed.constData() + hSize);
|
||||
stream.avail_out = resultLen;
|
||||
stream.next_out = (uint8_t*)uncompressed.data();
|
||||
|
||||
lzma_ret res = lzma_code(&stream, LZMA_FINISH);
|
||||
if (stream.avail_in) {
|
||||
LOG(("Error in decompression, %1 bytes left in _in of %2 whole.").arg(stream.avail_in).arg(compressedLen));
|
||||
return fatalFail();
|
||||
} else if (stream.avail_out) {
|
||||
LOG(("Error in decompression, %1 bytes free left in _out of %2 whole.").arg(stream.avail_out).arg(resultLen));
|
||||
return fatalFail();
|
||||
}
|
||||
lzma_end(&stream);
|
||||
if (res != LZMA_OK && res != LZMA_STREAM_END) {
|
||||
const char *msg;
|
||||
switch (res) {
|
||||
case LZMA_MEM_ERROR: msg = "Memory allocation failed"; break;
|
||||
case LZMA_FORMAT_ERROR: msg = "The input data is not in the .xz format"; break;
|
||||
case LZMA_OPTIONS_ERROR: msg = "Unsupported compression options"; break;
|
||||
case LZMA_DATA_ERROR: msg = "Compressed file is corrupt"; break;
|
||||
case LZMA_BUF_ERROR: msg = "Compressed data is truncated or otherwise corrupt"; break;
|
||||
default: msg = "Unknown error, possibly a bug"; break;
|
||||
}
|
||||
LOG(("Error in decompression: %1 (error code %2)").arg(msg).arg(res));
|
||||
return fatalFail();
|
||||
}
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
tempDir.mkdir(tempDir.absolutePath());
|
||||
|
||||
quint32 version;
|
||||
{
|
||||
QDataStream stream(uncompressed);
|
||||
stream.setVersion(QDataStream::Qt_5_1);
|
||||
|
||||
stream >> version;
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("Update Error: cant read version from downloaded stream, status: %1").arg(stream.status()));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
quint64 betaVersion = 0;
|
||||
if (version == 0x7FFFFFFF) { // beta version
|
||||
stream >> betaVersion;
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("Update Error: cant read beta version from downloaded stream, status: %1").arg(stream.status()));
|
||||
return fatalFail();
|
||||
}
|
||||
if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
|
||||
LOG(("Update Error: downloaded beta version %1 is not greater, than mine %2").arg(betaVersion).arg(cBetaVersion()));
|
||||
return fatalFail();
|
||||
}
|
||||
} else if (int32(version) <= AppVersion) {
|
||||
LOG(("Update Error: downloaded version %1 is not greater, than mine %2").arg(version).arg(AppVersion));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
quint32 filesCount;
|
||||
stream >> filesCount;
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("Update Error: cant read files count from downloaded stream, status: %1").arg(stream.status()));
|
||||
return fatalFail();
|
||||
}
|
||||
if (!filesCount) {
|
||||
LOG(("Update Error: update is empty!"));
|
||||
return fatalFail();
|
||||
}
|
||||
for (uint32 i = 0; i < filesCount; ++i) {
|
||||
QString relativeName;
|
||||
quint32 fileSize;
|
||||
QByteArray fileInnerData;
|
||||
bool executable = false;
|
||||
|
||||
stream >> relativeName >> fileSize >> fileInnerData;
|
||||
#if defined Q_OS_MAC || defined Q_OS_LINUX
|
||||
stream >> executable;
|
||||
#endif // Q_OS_MAC || Q_OS_LINUX
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
LOG(("Update Error: cant read file from downloaded stream, status: %1").arg(stream.status()));
|
||||
return fatalFail();
|
||||
}
|
||||
if (fileSize != quint32(fileInnerData.size())) {
|
||||
LOG(("Update Error: bad file size %1 not matching data size %2").arg(fileSize).arg(fileInnerData.size()));
|
||||
return fatalFail();
|
||||
}
|
||||
|
||||
QFile f(tempDirPath + '/' + relativeName);
|
||||
if (!QDir().mkpath(QFileInfo(f).absolutePath())) {
|
||||
LOG(("Update Error: cant mkpath for file '%1'").arg(tempDirPath + '/' + relativeName));
|
||||
return fatalFail();
|
||||
}
|
||||
if (!f.open(QIODevice::WriteOnly)) {
|
||||
LOG(("Update Error: cant open file '%1' for writing").arg(tempDirPath + '/' + relativeName));
|
||||
return fatalFail();
|
||||
}
|
||||
auto writtenBytes = f.write(fileInnerData);
|
||||
if (writtenBytes != fileSize) {
|
||||
f.close();
|
||||
LOG(("Update Error: cant write file '%1', desiredSize: %2, write result: %3").arg(tempDirPath + '/' + relativeName).arg(fileSize).arg(writtenBytes));
|
||||
return fatalFail();
|
||||
}
|
||||
f.close();
|
||||
if (executable) {
|
||||
QFileDevice::Permissions p = f.permissions();
|
||||
p |= QFileDevice::ExeOwner | QFileDevice::ExeUser | QFileDevice::ExeGroup | QFileDevice::ExeOther;
|
||||
f.setPermissions(p);
|
||||
}
|
||||
}
|
||||
|
||||
// create tdata/version file
|
||||
tempDir.mkdir(QDir(tempDirPath + qsl("/tdata")).absolutePath());
|
||||
std::wstring versionString = ((version % 1000) ? QString("%1.%2.%3").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000)).arg(int(version % 1000)) : QString("%1.%2").arg(int(version / 1000000)).arg(int((version % 1000000) / 1000))).toStdWString();
|
||||
|
||||
VerInt versionNum = VerInt(version), versionLen = VerInt(versionString.size() * sizeof(VerChar));
|
||||
VerChar versionStr[32];
|
||||
memcpy(versionStr, versionString.c_str(), versionLen);
|
||||
|
||||
QFile fVersion(tempDirPath + qsl("/tdata/version"));
|
||||
if (!fVersion.open(QIODevice::WriteOnly)) {
|
||||
LOG(("Update Error: cant write version file '%1'").arg(tempDirPath + qsl("/version")));
|
||||
return fatalFail();
|
||||
}
|
||||
fVersion.write((const char*)&versionNum, sizeof(VerInt));
|
||||
if (versionNum == 0x7FFFFFFF) { // beta version
|
||||
fVersion.write((const char*)&betaVersion, sizeof(quint64));
|
||||
} else {
|
||||
fVersion.write((const char*)&versionLen, sizeof(VerInt));
|
||||
fVersion.write((const char*)&versionStr[0], versionLen);
|
||||
}
|
||||
fVersion.close();
|
||||
}
|
||||
|
||||
QFile readyFile(readyFilePath);
|
||||
if (readyFile.open(QIODevice::WriteOnly)) {
|
||||
if (readyFile.write("1", 1)) {
|
||||
readyFile.close();
|
||||
} else {
|
||||
LOG(("Update Error: cant write ready file '%1'").arg(readyFilePath));
|
||||
return fatalFail();
|
||||
}
|
||||
} else {
|
||||
LOG(("Update Error: cant create ready file '%1'").arg(readyFilePath));
|
||||
return fatalFail();
|
||||
}
|
||||
outputFile.remove();
|
||||
|
||||
Sandbox::updateReady();
|
||||
}
|
||||
|
||||
UpdateChecker::~UpdateChecker() {
|
||||
delete reply;
|
||||
reply = 0;
|
||||
}
|
||||
|
||||
bool checkReadyUpdate() {
|
||||
QString readyFilePath = cWorkingDir() + qsl("tupdates/temp/ready"), readyPath = cWorkingDir() + qsl("tupdates/temp");
|
||||
if (!QFile(readyFilePath).exists() || cExeName().isEmpty()) {
|
||||
if (QDir(cWorkingDir() + qsl("tupdates/ready")).exists() || QDir(cWorkingDir() + qsl("tupdates/temp")).exists()) {
|
||||
UpdateChecker::clearAll();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// check ready version
|
||||
QString versionPath = readyPath + qsl("/tdata/version");
|
||||
{
|
||||
QFile fVersion(versionPath);
|
||||
if (!fVersion.open(QIODevice::ReadOnly)) {
|
||||
LOG(("Update Error: cant read version file '%1'").arg(versionPath));
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
VerInt versionNum;
|
||||
if (fVersion.read((char*)&versionNum, sizeof(VerInt)) != sizeof(VerInt)) {
|
||||
LOG(("Update Error: cant read version from file '%1'").arg(versionPath));
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
if (versionNum == 0x7FFFFFFF) { // beta version
|
||||
quint64 betaVersion = 0;
|
||||
if (fVersion.read((char*)&betaVersion, sizeof(quint64)) != sizeof(quint64)) {
|
||||
LOG(("Update Error: cant read beta version from file '%1'").arg(versionPath));
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
if (!cBetaVersion() || betaVersion <= cBetaVersion()) {
|
||||
LOG(("Update Error: cant install beta version %1 having beta version %2").arg(betaVersion).arg(cBetaVersion()));
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
} else if (versionNum <= AppVersion) {
|
||||
LOG(("Update Error: cant install version %1 having version %2").arg(versionNum).arg(AppVersion));
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
fVersion.close();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QString curUpdater = (cExeDir() + qsl("Updater.exe"));
|
||||
QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Updater.exe"));
|
||||
#elif defined Q_OS_MAC // Q_OS_WIN
|
||||
QString curUpdater = (cExeDir() + cExeName() + qsl("/Contents/Frameworks/Updater"));
|
||||
QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Telegram.app/Contents/Frameworks/Updater"));
|
||||
#elif defined Q_OS_LINUX // Q_OS_MAC
|
||||
QString curUpdater = (cExeDir() + qsl("Updater"));
|
||||
QFileInfo updater(cWorkingDir() + qsl("tupdates/temp/Updater"));
|
||||
#endif // Q_OS_LINUX
|
||||
if (!updater.exists()) {
|
||||
QFileInfo current(curUpdater);
|
||||
if (!current.exists()) {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
if (!QFile(current.absoluteFilePath()).copy(updater.absoluteFilePath())) {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#ifdef Q_OS_WIN
|
||||
if (CopyFile(updater.absoluteFilePath().toStdWString().c_str(), curUpdater.toStdWString().c_str(), FALSE) == FALSE) {
|
||||
DWORD errorCode = GetLastError();
|
||||
if (errorCode == ERROR_ACCESS_DENIED) { // we are in write-protected dir, like Program Files
|
||||
cSetWriteProtected(true);
|
||||
return true;
|
||||
} else {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (DeleteFile(updater.absoluteFilePath().toStdWString().c_str()) == FALSE) {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
#elif defined Q_OS_MAC // Q_OS_WIN
|
||||
QDir().mkpath(QFileInfo(curUpdater).absolutePath());
|
||||
DEBUG_LOG(("Update Info: moving %1 to %2...").arg(updater.absoluteFilePath()).arg(curUpdater));
|
||||
if (!objc_moveFile(updater.absoluteFilePath(), curUpdater)) {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
#elif defined Q_OS_LINUX // Q_OS_MAC
|
||||
if (!linuxMoveFile(QFile::encodeName(updater.absoluteFilePath()).constData(), QFile::encodeName(curUpdater).constData())) {
|
||||
UpdateChecker::clearAll();
|
||||
return false;
|
||||
}
|
||||
#endif // Q_OS_LINUX
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
QString countBetaVersionSignature(uint64 version) { // duplicated in packer.cpp
|
||||
if (cBetaPrivateKey().isEmpty()) {
|
||||
LOG(("Error: Trying to count beta version signature without beta private key!"));
|
||||
return QString();
|
||||
}
|
||||
|
||||
QByteArray signedData = (qstr("TelegramBeta_") + QString::number(version, 16).toLower()).toUtf8();
|
||||
|
||||
static const int32 shaSize = 20, keySize = 128;
|
||||
|
||||
uchar sha1Buffer[shaSize];
|
||||
hashSha1(signedData.constData(), signedData.size(), sha1Buffer); // count sha1
|
||||
|
||||
uint32 siglen = 0;
|
||||
|
||||
RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>(cBetaPrivateKey().constData()), -1), 0, 0, 0);
|
||||
if (!prKey) {
|
||||
LOG(("Error: Could not read beta private key!"));
|
||||
return QString();
|
||||
}
|
||||
if (RSA_size(prKey) != keySize) {
|
||||
LOG(("Error: Bad beta private key size: %1").arg(RSA_size(prKey)));
|
||||
RSA_free(prKey);
|
||||
return QString();
|
||||
}
|
||||
QByteArray signature;
|
||||
signature.resize(keySize);
|
||||
if (RSA_sign(NID_sha1, (const uchar*)(sha1Buffer), shaSize, (uchar*)(signature.data()), &siglen, prKey) != 1) { // count signature
|
||||
LOG(("Error: Counting beta version signature failed!"));
|
||||
RSA_free(prKey);
|
||||
return QString();
|
||||
}
|
||||
RSA_free(prKey);
|
||||
|
||||
if (siglen != keySize) {
|
||||
LOG(("Error: Bad beta version signature length: %1").arg(siglen));
|
||||
return QString();
|
||||
}
|
||||
|
||||
signature = signature.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||
signature = signature.replace('-', '8').replace('_', 'B');
|
||||
return QString::fromUtf8(signature.mid(19, 32));
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
|
||||
class UpdateChecker : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
UpdateChecker(QThread *thread, const QString &url);
|
||||
|
||||
void unpackUpdate();
|
||||
|
||||
int32 ready();
|
||||
int32 size();
|
||||
|
||||
static void clearAll();
|
||||
|
||||
~UpdateChecker();
|
||||
|
||||
public slots:
|
||||
|
||||
void start();
|
||||
void partMetaGot();
|
||||
void partFinished(qint64 got, qint64 total);
|
||||
void partFailed(QNetworkReply::NetworkError e);
|
||||
void sendRequest();
|
||||
|
||||
private:
|
||||
void initOutput();
|
||||
|
||||
void fatalFail();
|
||||
|
||||
QString updateUrl;
|
||||
QNetworkAccessManager manager;
|
||||
QNetworkReply *reply;
|
||||
int32 already, full;
|
||||
QFile outputFile;
|
||||
|
||||
QMutex mutex;
|
||||
|
||||
};
|
||||
|
||||
bool checkReadyUpdate();
|
||||
|
||||
#else // TDESKTOP_DISABLE_AUTOUPDATE
|
||||
class UpdateChecker : public QObject {
|
||||
Q_OBJECT
|
||||
};
|
||||
|
||||
#endif // TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
QString countBetaVersionSignature(uint64 version);
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -60,6 +47,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#define ARCH_CPU_X86_FAMILY 1
|
||||
#define ARCH_CPU_X86 1
|
||||
#define ARCH_CPU_32_BITS 1
|
||||
#elif defined(__aarch64__)
|
||||
#define ARCH_CPU_64_BITS 1
|
||||
#elif defined(_M_ARM) || defined(__arm__)
|
||||
#define ARCH_CPU_32_BITS 1
|
||||
#else
|
||||
#error Please add support for your architecture in base/build_config.h
|
||||
#endif
|
||||
|
||||
137
Telegram/SourceFiles/base/bytes.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
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 <gsl/gsl_byte>
|
||||
|
||||
namespace bytes {
|
||||
|
||||
using span = gsl::span<gsl::byte>;
|
||||
using const_span = gsl::span<const gsl::byte>;
|
||||
using vector = std::vector<gsl::byte>;
|
||||
|
||||
template <
|
||||
typename Container,
|
||||
typename = std::enable_if_t<!std::is_const_v<Container>>>
|
||||
inline span make_span(Container &container) {
|
||||
return gsl::as_writeable_bytes(gsl::make_span(container));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
inline const_span make_span(const Container &container) {
|
||||
return gsl::as_bytes(gsl::make_span(container));
|
||||
}
|
||||
|
||||
template <typename Type, std::ptrdiff_t Extent>
|
||||
inline span make_span(gsl::span<Type, Extent> container) {
|
||||
return gsl::as_writeable_bytes(container);
|
||||
}
|
||||
|
||||
template <typename Type, std::ptrdiff_t Extent>
|
||||
inline const_span make_span(gsl::span<const Type, Extent> container) {
|
||||
return gsl::as_bytes(container);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline span make_span(Type *value, std::size_t count) {
|
||||
return gsl::as_writeable_bytes(gsl::make_span(value, count));
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline const_span make_span(const Type *value, std::size_t count) {
|
||||
return gsl::as_bytes(gsl::make_span(value, count));
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
inline vector make_vector(const Container &container) {
|
||||
const auto buffer = bytes::make_span(container);
|
||||
return { buffer.begin(), buffer.end() };
|
||||
}
|
||||
|
||||
inline void copy(span destination, const_span source) {
|
||||
Expects(destination.size() >= source.size());
|
||||
|
||||
memcpy(destination.data(), source.data(), source.size());
|
||||
}
|
||||
|
||||
inline void move(span destination, const_span source) {
|
||||
Expects(destination.size() >= source.size());
|
||||
|
||||
memmove(destination.data(), source.data(), source.size());
|
||||
}
|
||||
|
||||
inline void set_with_const(span destination, gsl::byte value) {
|
||||
memset(
|
||||
destination.data(),
|
||||
gsl::to_integer<unsigned char>(value),
|
||||
destination.size());
|
||||
}
|
||||
|
||||
inline int compare(const_span a, const_span b) {
|
||||
const auto aSize = a.size(), bSize = b.size();
|
||||
return (aSize > bSize)
|
||||
? 1
|
||||
: (aSize < bSize)
|
||||
? -1
|
||||
: memcmp(a.data(), b.data(), aSize);
|
||||
}
|
||||
|
||||
namespace details {
|
||||
|
||||
template <typename Arg>
|
||||
std::size_t spansLength(Arg &&arg) {
|
||||
return bytes::make_span(arg).size();
|
||||
}
|
||||
|
||||
template <typename Arg, typename ...Args>
|
||||
std::size_t spansLength(Arg &&arg, Args &&...args) {
|
||||
return bytes::make_span(arg).size() + spansLength(args...);
|
||||
}
|
||||
|
||||
template <typename Arg>
|
||||
void spansAppend(span destination, Arg &&arg) {
|
||||
bytes::copy(destination, bytes::make_span(arg));
|
||||
}
|
||||
|
||||
template <typename Arg, typename ...Args>
|
||||
void spansAppend(span destination, Arg &&arg, Args &&...args) {
|
||||
const auto data = bytes::make_span(arg);
|
||||
bytes::copy(destination, data);
|
||||
spansAppend(destination.subspan(data.size()), args...);
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <
|
||||
typename ...Args,
|
||||
typename = std::enable_if_t<(sizeof...(Args) > 1)>>
|
||||
vector concatenate(Args &&...args) {
|
||||
const auto size = details::spansLength(args...);
|
||||
auto result = vector(size);
|
||||
details::spansAppend(make_span(result), args...);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <
|
||||
typename SpanRange>
|
||||
vector concatenate(SpanRange args) {
|
||||
auto size = std::size_t(0);
|
||||
for (const auto &arg : args) {
|
||||
size += bytes::make_span(arg).size();
|
||||
}
|
||||
auto result = vector(size);
|
||||
auto buffer = make_span(result);
|
||||
for (const auto &arg : args) {
|
||||
const auto part = bytes::make_span(arg);
|
||||
bytes::copy(buffer, part);
|
||||
buffer = buffer.subspan(part.size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace bytes
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -26,6 +13,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
namespace base {
|
||||
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
template <
|
||||
typename Key,
|
||||
typename Type,
|
||||
@@ -427,8 +417,9 @@ public:
|
||||
if (range.first == range.second) {
|
||||
return 0;
|
||||
}
|
||||
const auto result = (range.second - range.first);
|
||||
impl().erase(range.first, range.second);
|
||||
return (range.second - range.first);
|
||||
return result;
|
||||
}
|
||||
|
||||
iterator erase(const_iterator where) {
|
||||
@@ -437,6 +428,9 @@ public:
|
||||
iterator erase(const_iterator from, const_iterator till) {
|
||||
return impl().erase(from._impl, till._impl);
|
||||
}
|
||||
int erase(const Key &key) {
|
||||
return removeAll(key);
|
||||
}
|
||||
|
||||
iterator findFirst(const Key &key) {
|
||||
if (empty()
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -25,6 +12,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
|
||||
namespace base {
|
||||
|
||||
using std::begin;
|
||||
using std::end;
|
||||
|
||||
template <typename Type, typename Compare = std::less<>>
|
||||
class flat_set;
|
||||
|
||||
@@ -307,8 +297,9 @@ public:
|
||||
if (range.first == range.second) {
|
||||
return 0;
|
||||
}
|
||||
const auto result = (range.second - range.first);
|
||||
impl().erase(range.first, range.second);
|
||||
return (range.second - range.first);
|
||||
return result;
|
||||
}
|
||||
|
||||
iterator erase(const_iterator where) {
|
||||
@@ -317,6 +308,9 @@ public:
|
||||
iterator erase(const_iterator from, const_iterator till) {
|
||||
return impl().erase(from._impl, till._impl);
|
||||
}
|
||||
int erase(const Type &value) {
|
||||
return removeAll(value);
|
||||
}
|
||||
|
||||
iterator findFirst(const Type &value) {
|
||||
if (empty()
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,500 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifndef CUSTOM_LAMBDA_WRAP
|
||||
|
||||
#include <functional>
|
||||
#include "base/unique_function.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
template <typename Function>
|
||||
using lambda = std::function<Function>;
|
||||
|
||||
template <typename Function>
|
||||
using lambda_once = unique_function<Function>;
|
||||
|
||||
namespace lambda_internal {
|
||||
|
||||
template <typename Lambda>
|
||||
struct lambda_call_type {
|
||||
using type = decltype(&Lambda::operator());
|
||||
};
|
||||
|
||||
} // namespace lambda_internal
|
||||
|
||||
template <typename Lambda>
|
||||
using lambda_call_type_t
|
||||
= typename lambda_internal::lambda_call_type<Lambda>::type;
|
||||
|
||||
} // namespace base
|
||||
|
||||
#else // CUSTOM_LAMBDA_WRAP
|
||||
|
||||
#ifndef Assert
|
||||
#define LambdaAssertDefined
|
||||
#define Assert(v) ((v) ? ((void)0) : std::abort())
|
||||
#endif // Assert
|
||||
|
||||
#ifndef Unexpected
|
||||
#define LambdaUnexpectedDefined
|
||||
#define Unexpected(v) std::abort()
|
||||
#endif // Unexpected
|
||||
|
||||
namespace base {
|
||||
|
||||
template <typename Function> class lambda_once;
|
||||
template <typename Function> class lambda;
|
||||
|
||||
// Get lambda type from a lambda template parameter.
|
||||
|
||||
namespace lambda_internal {
|
||||
|
||||
template <typename FunctionType>
|
||||
struct type_resolver;
|
||||
|
||||
template <typename Lambda, typename R, typename ...Args>
|
||||
struct type_resolver<R(Lambda::*)(Args...) const> {
|
||||
using type = lambda<R(Args...)>;
|
||||
static constexpr auto is_mutable = false;
|
||||
};
|
||||
|
||||
template <typename Lambda, typename R, typename ...Args>
|
||||
struct type_resolver<R(Lambda::*)(Args...)> {
|
||||
using type = lambda_once<R(Args...)>;
|
||||
static constexpr auto is_mutable = true;
|
||||
};
|
||||
|
||||
template <typename Lambda>
|
||||
struct type_helper {
|
||||
using type = typename type_resolver<decltype(&Lambda::operator())>::type;
|
||||
static constexpr auto is_mutable = type_resolver<decltype(&Lambda::operator())>::is_mutable;
|
||||
};
|
||||
|
||||
} // namespace lambda_internal
|
||||
|
||||
template <typename Lambda>
|
||||
using lambda_type = typename lambda_internal::type_helper<std::decay_t<Lambda>>::type;
|
||||
|
||||
namespace lambda_internal {
|
||||
|
||||
constexpr auto kFullStorageSize = 32U;
|
||||
static_assert(kFullStorageSize % sizeof(void*) == 0, "Invalid pointer size!");
|
||||
|
||||
constexpr auto kStorageSize = kFullStorageSize - sizeof(void*);
|
||||
using alignment = std::max_align_t;
|
||||
|
||||
template <typename Lambda>
|
||||
constexpr bool is_large = (sizeof(std::decay_t<Lambda>) > kStorageSize);
|
||||
|
||||
[[noreturn]] inline void bad_construct_copy(void *lambda, const void *source) {
|
||||
Unexpected("base::lambda bad_construct_copy() called!");
|
||||
}
|
||||
|
||||
template <typename Return, typename ...Args>
|
||||
[[noreturn]] Return bad_const_call(const void *lambda, Args...) {
|
||||
Unexpected("base::lambda bad_const_call() called!");
|
||||
}
|
||||
|
||||
template <typename Return, typename ...Args>
|
||||
struct vtable_base {
|
||||
using construct_copy_other_type = void(*)(void *, const void *); // dst, src
|
||||
using construct_move_other_type = void(*)(void *, void *); // dst, src
|
||||
using const_call_type = Return(*)(const void *, Args...);
|
||||
using call_type = Return(*)(void *, Args...);
|
||||
using destruct_type = void(*)(const void *);
|
||||
|
||||
vtable_base() = delete;
|
||||
vtable_base(const vtable_base &other) = delete;
|
||||
vtable_base &operator=(const vtable_base &other) = delete;
|
||||
|
||||
vtable_base(
|
||||
construct_copy_other_type construct_copy_other,
|
||||
construct_move_other_type construct_move_other,
|
||||
const_call_type const_call,
|
||||
call_type call,
|
||||
destruct_type destruct)
|
||||
: construct_copy_other(construct_copy_other)
|
||||
, construct_move_other(construct_move_other)
|
||||
, const_call(const_call)
|
||||
, call(call)
|
||||
, destruct(destruct) {
|
||||
}
|
||||
|
||||
const construct_copy_other_type construct_copy_other;
|
||||
const construct_move_other_type construct_move_other;
|
||||
const const_call_type const_call;
|
||||
const call_type call;
|
||||
const destruct_type destruct;
|
||||
|
||||
};
|
||||
|
||||
template <typename Lambda, bool IsLarge, typename Return, typename ...Args> struct vtable_once_impl;
|
||||
|
||||
template <typename Lambda, typename Return, typename ...Args>
|
||||
struct vtable_once_impl<Lambda, true, Return, Args...> : public vtable_base<Return, Args...> {
|
||||
using JustLambda = std::decay_t<Lambda>;
|
||||
using LambdaPtr = std::unique_ptr<JustLambda>;
|
||||
using Parent = vtable_base<Return, Args...>;
|
||||
static void construct_move_other_method(void *storage, void *source) {
|
||||
auto source_lambda_ptr = static_cast<LambdaPtr*>(source);
|
||||
new (storage) LambdaPtr(std::move(*source_lambda_ptr));
|
||||
}
|
||||
static Return call_method(void *storage, Args... args) {
|
||||
return (**static_cast<LambdaPtr*>(storage))(std::forward<Args>(args)...);
|
||||
}
|
||||
static void destruct_method(const void *storage) {
|
||||
static_cast<const LambdaPtr*>(storage)->~LambdaPtr();
|
||||
}
|
||||
vtable_once_impl() : Parent(
|
||||
&bad_construct_copy,
|
||||
&vtable_once_impl::construct_move_other_method,
|
||||
&bad_const_call<Return, Args...>,
|
||||
&vtable_once_impl::call_method,
|
||||
&vtable_once_impl::destruct_method) {
|
||||
}
|
||||
|
||||
// Used directly.
|
||||
static void construct_move_lambda_method(void *storage, void *source) {
|
||||
auto source_lambda = static_cast<JustLambda*>(source);
|
||||
new (storage) LambdaPtr(std::make_unique<JustLambda>(static_cast<JustLambda&&>(*source_lambda)));
|
||||
}
|
||||
|
||||
protected:
|
||||
vtable_once_impl(
|
||||
typename Parent::construct_copy_other_type construct_copy_other,
|
||||
typename Parent::const_call_type const_call
|
||||
) : Parent(
|
||||
construct_copy_other,
|
||||
&vtable_once_impl::construct_move_other_method,
|
||||
const_call,
|
||||
&vtable_once_impl::call_method,
|
||||
&vtable_once_impl::destruct_method) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Lambda, typename Return, typename ...Args>
|
||||
struct vtable_once_impl<Lambda, false, Return, Args...> : public vtable_base<Return, Args...> {
|
||||
using JustLambda = std::decay_t<Lambda>;
|
||||
using Parent = vtable_base<Return, Args...>;
|
||||
static void construct_move_other_method(void *storage, void *source) {
|
||||
auto source_lambda = static_cast<JustLambda*>(source);
|
||||
new (storage) JustLambda(static_cast<JustLambda&&>(*source_lambda));
|
||||
}
|
||||
static Return call_method(void *storage, Args... args) {
|
||||
return (*static_cast<JustLambda*>(storage))(std::forward<Args>(args)...);
|
||||
}
|
||||
static void destruct_method(const void *storage) {
|
||||
static_cast<const JustLambda*>(storage)->~JustLambda();
|
||||
}
|
||||
vtable_once_impl() : Parent(
|
||||
&bad_construct_copy,
|
||||
&vtable_once_impl::construct_move_other_method,
|
||||
&bad_const_call<Return, Args...>,
|
||||
&vtable_once_impl::call_method,
|
||||
&vtable_once_impl::destruct_method) {
|
||||
}
|
||||
|
||||
// Used directly.
|
||||
static void construct_move_lambda_method(void *storage, void *source) {
|
||||
auto source_lambda = static_cast<JustLambda*>(source);
|
||||
new (storage) JustLambda(static_cast<JustLambda&&>(*source_lambda));
|
||||
}
|
||||
|
||||
protected:
|
||||
vtable_once_impl(
|
||||
typename Parent::construct_copy_other_type construct_copy_other,
|
||||
typename Parent::const_call_type const_call
|
||||
) : Parent(
|
||||
construct_copy_other,
|
||||
&vtable_once_impl::construct_move_other_method,
|
||||
const_call,
|
||||
&vtable_once_impl::call_method,
|
||||
&vtable_once_impl::destruct_method) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Lambda, typename Return, typename ...Args>
|
||||
struct vtable_once : public vtable_once_impl<Lambda, is_large<Lambda>, Return, Args...> {
|
||||
static const vtable_once instance;
|
||||
};
|
||||
|
||||
template <typename Lambda, typename Return, typename ...Args>
|
||||
const vtable_once<Lambda, Return, Args...> vtable_once<Lambda, Return, Args...>::instance = {};
|
||||
|
||||
template <typename Lambda, bool IsLarge, typename Return, typename ...Args> struct vtable_impl;
|
||||
|
||||
template <typename Lambda, typename Return, typename ...Args>
|
||||
struct vtable_impl<Lambda, true, Return, Args...> : public vtable_once_impl<Lambda, true, Return, Args...> {
|
||||
using JustLambda = std::decay_t<Lambda>;
|
||||
using LambdaPtr = std::unique_ptr<JustLambda>;
|
||||
using Parent = vtable_once_impl<Lambda, true, Return, Args...>;
|
||||
static void construct_copy_other_method(void *storage, const void *source) {
|
||||
auto source_lambda = static_cast<const LambdaPtr*>(source);
|
||||
new (storage) LambdaPtr(std::make_unique<JustLambda>(*source_lambda->get()));
|
||||
}
|
||||
static Return const_call_method(const void *storage, Args... args) {
|
||||
auto lambda_ptr = static_cast<const LambdaPtr*>(storage)->get();
|
||||
return (*static_cast<const JustLambda*>(lambda_ptr))(std::forward<Args>(args)...);
|
||||
}
|
||||
vtable_impl() : Parent(
|
||||
&vtable_impl::construct_copy_other_method,
|
||||
&vtable_impl::const_call_method
|
||||
) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Lambda, typename Return, typename ...Args>
|
||||
struct vtable_impl<Lambda, false, Return, Args...> : public vtable_once_impl<Lambda, false, Return, Args...> {
|
||||
using JustLambda = std::decay_t<Lambda>;
|
||||
using Parent = vtable_once_impl<Lambda, false, Return, Args...>;
|
||||
static void construct_copy_other_method(void *storage, const void *source) {
|
||||
auto source_lambda = static_cast<const JustLambda*>(source);
|
||||
new (storage) JustLambda(static_cast<const JustLambda &>(*source_lambda));
|
||||
}
|
||||
static Return const_call_method(const void *storage, Args... args) {
|
||||
return (*static_cast<const JustLambda*>(storage))(std::forward<Args>(args)...);
|
||||
}
|
||||
vtable_impl() : Parent(
|
||||
&vtable_impl::construct_copy_other_method,
|
||||
&vtable_impl::const_call_method
|
||||
) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Lambda, typename Return, typename ...Args>
|
||||
struct vtable : public vtable_impl<Lambda, is_large<Lambda>, Return, Args...> {
|
||||
static const vtable instance;
|
||||
};
|
||||
|
||||
template <typename Lambda, typename Return, typename ...Args>
|
||||
const vtable<Lambda, Return, Args...> vtable<Lambda, Return, Args...>::instance = {};
|
||||
|
||||
} // namespace lambda_internal
|
||||
|
||||
template <typename Return, typename ...Args>
|
||||
class lambda_once<Return(Args...)> {
|
||||
using VTable = lambda_internal::vtable_base<Return, Args...>;
|
||||
|
||||
public:
|
||||
using return_type = Return;
|
||||
|
||||
lambda_once() {
|
||||
data_.vtable = nullptr;
|
||||
}
|
||||
lambda_once(const lambda_once &other) = delete;
|
||||
lambda_once &operator=(const lambda_once &other) = delete;
|
||||
|
||||
// Move construct / assign from the same type.
|
||||
lambda_once(lambda_once &&other) {
|
||||
if ((data_.vtable = other.data_.vtable)) {
|
||||
data_.vtable->construct_move_other(data_.storage, other.data_.storage);
|
||||
}
|
||||
}
|
||||
lambda_once &operator=(lambda_once &&other) {
|
||||
if (this != &other) {
|
||||
if (data_.vtable) {
|
||||
data_.vtable->destruct(data_.storage);
|
||||
}
|
||||
if ((data_.vtable = other.data_.vtable)) {
|
||||
data_.vtable->construct_move_other(data_.storage, other.data_.storage);
|
||||
data_.vtable->destruct(other.data_.storage);
|
||||
other.data_.vtable = nullptr;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Move construct / assign from a derived type.
|
||||
lambda_once(lambda<Return(Args...)> &&other) {
|
||||
if ((data_.vtable = other.data_.vtable)) {
|
||||
data_.vtable->construct_move_other(data_.storage, other.data_.storage);
|
||||
data_.vtable->destruct(other.data_.storage);
|
||||
other.data_.vtable = nullptr;
|
||||
}
|
||||
}
|
||||
lambda_once &operator=(lambda<Return(Args...)> &&other) {
|
||||
if (this != &other) {
|
||||
if (data_.vtable) {
|
||||
data_.vtable->destruct(data_.storage);
|
||||
}
|
||||
if ((data_.vtable = other.data_.vtable)) {
|
||||
data_.vtable->construct_move_other(data_.storage, other.data_.storage);
|
||||
data_.vtable->destruct(other.data_.storage);
|
||||
other.data_.vtable = nullptr;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy construct / assign from a derived type.
|
||||
lambda_once(const lambda<Return(Args...)> &other) {
|
||||
if ((data_.vtable = other.data_.vtable)) {
|
||||
data_.vtable->construct_copy_other(data_.storage, other.data_.storage);
|
||||
}
|
||||
}
|
||||
lambda_once &operator=(const lambda<Return(Args...)> &other) {
|
||||
if (this != &other) {
|
||||
if (data_.vtable) {
|
||||
data_.vtable->destruct(data_.storage);
|
||||
}
|
||||
if ((data_.vtable = other.data_.vtable)) {
|
||||
data_.vtable->construct_copy_other(data_.storage, other.data_.storage);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy / move construct / assign from an arbitrary type.
|
||||
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<decltype(std::declval<Lambda>()(std::declval<Args>()...)),Return>::value>>
|
||||
lambda_once(Lambda other) {
|
||||
data_.vtable = &lambda_internal::vtable_once<Lambda, Return, Args...>::instance;
|
||||
lambda_internal::vtable_once<Lambda, Return, Args...>::construct_move_lambda_method(data_.storage, &other);
|
||||
}
|
||||
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<decltype(std::declval<Lambda>()(std::declval<Args>()...)),Return>::value>>
|
||||
lambda_once &operator=(Lambda other) {
|
||||
if (data_.vtable) {
|
||||
data_.vtable->destruct(data_.storage);
|
||||
}
|
||||
data_.vtable = &lambda_internal::vtable_once<Lambda, Return, Args...>::instance;
|
||||
lambda_internal::vtable_once<Lambda, Return, Args...>::construct_move_lambda_method(data_.storage, &other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(lambda_once &other) {
|
||||
if (this != &other) {
|
||||
std::swap(*this, other);
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename ...OtherArgs,
|
||||
typename = std::enable_if_t<(sizeof...(Args) == sizeof...(OtherArgs))>>
|
||||
inline Return operator()(OtherArgs&&... args) {
|
||||
Assert(data_.vtable != nullptr);
|
||||
return data_.vtable->call(
|
||||
data_.storage,
|
||||
std::forward<OtherArgs>(args)...);
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return (data_.vtable != nullptr);
|
||||
}
|
||||
|
||||
~lambda_once() {
|
||||
if (data_.vtable) {
|
||||
data_.vtable->destruct(data_.storage);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
struct Private {
|
||||
};
|
||||
lambda_once(const VTable *vtable, const Private &) {
|
||||
data_.vtable = vtable;
|
||||
}
|
||||
|
||||
struct Data {
|
||||
char storage[lambda_internal::kStorageSize];
|
||||
const VTable *vtable;
|
||||
};
|
||||
union {
|
||||
lambda_internal::alignment alignment_;
|
||||
char raw_[lambda_internal::kFullStorageSize];
|
||||
Data data_;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template <typename Return, typename ...Args>
|
||||
class lambda<Return(Args...)> final : public lambda_once<Return(Args...)> {
|
||||
using Parent = lambda_once<Return(Args...)>;
|
||||
|
||||
public:
|
||||
lambda() = default;
|
||||
|
||||
// Move construct / assign from the same type.
|
||||
lambda(lambda<Return(Args...)> &&other) : Parent(std::move(other)) {
|
||||
}
|
||||
lambda &operator=(lambda<Return(Args...)> &&other) {
|
||||
Parent::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy construct / assign from the same type.
|
||||
lambda(const lambda<Return(Args...)> &other) : Parent(other) {
|
||||
}
|
||||
lambda &operator=(const lambda<Return(Args...)> &other) {
|
||||
Parent::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy / move construct / assign from an arbitrary type.
|
||||
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<decltype(std::declval<Lambda>()(std::declval<Args>()...)),Return>::value>>
|
||||
lambda(Lambda other) : Parent(&lambda_internal::vtable<Lambda, Return, Args...>::instance, typename Parent::Private()) {
|
||||
lambda_internal::vtable<Lambda, Return, Args...>::construct_move_lambda_method(this->data_.storage, &other);
|
||||
}
|
||||
template <typename Lambda, typename = std::enable_if_t<std::is_convertible<decltype(std::declval<Lambda>()(std::declval<Args>()...)),Return>::value>>
|
||||
lambda &operator=(Lambda other) {
|
||||
if (this->data_.vtable) {
|
||||
this->data_.vtable->destruct(this->data_.storage);
|
||||
}
|
||||
this->data_.vtable = &lambda_internal::vtable<Lambda, Return, Args...>::instance;
|
||||
lambda_internal::vtable<Lambda, Return, Args...>::construct_move_lambda_method(this->data_.storage, &other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <
|
||||
typename ...OtherArgs,
|
||||
typename = std::enable_if_t<(sizeof...(Args) == sizeof...(OtherArgs))>>
|
||||
inline Return operator()(OtherArgs&&... args) const {
|
||||
Assert(this->data_.vtable != nullptr);
|
||||
return this->data_.vtable->const_call(
|
||||
this->data_.storage,
|
||||
std::forward<OtherArgs>(args)...);
|
||||
}
|
||||
|
||||
void swap(lambda &other) {
|
||||
if (this != &other) {
|
||||
std::swap(*this, other);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
||||
#ifdef LambdaAssertDefined
|
||||
#undef Assert
|
||||
#endif // LambdaAssertDefined
|
||||
|
||||
#ifdef LambdaUnexpectedDefined
|
||||
#undef Unexpected
|
||||
#endif // LambdaUnexpectedDefined
|
||||
|
||||
#endif // CUSTOM_LAMBDA_WRAP
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QPointer>
|
||||
#include "base/weak_ptr.h"
|
||||
|
||||
// Guard lambda call by QObject* or has_weak_ptr* pointers.
|
||||
|
||||
namespace base {
|
||||
namespace lambda_internal {
|
||||
|
||||
template <typename Lambda>
|
||||
class guard_with_QObject {
|
||||
public:
|
||||
template <typename OtherLambda>
|
||||
guard_with_QObject(const QObject *object, OtherLambda &&other)
|
||||
: _guard(object)
|
||||
, _callable(std::forward<OtherLambda>(other)) {
|
||||
}
|
||||
|
||||
template <
|
||||
typename ...OtherArgs,
|
||||
typename Return = decltype(std::declval<Lambda>()(std::declval<OtherArgs>()...))>
|
||||
Return operator()(OtherArgs &&...args) {
|
||||
return _guard
|
||||
? _callable(std::forward<OtherArgs>(args)...)
|
||||
: Return();
|
||||
}
|
||||
|
||||
template <
|
||||
typename ...OtherArgs,
|
||||
typename Return = decltype(std::declval<Lambda>()(std::declval<OtherArgs>()...))>
|
||||
Return operator()(OtherArgs &&...args) const {
|
||||
return _guard
|
||||
? _callable(std::forward<OtherArgs>(args)...)
|
||||
: Return();
|
||||
}
|
||||
|
||||
private:
|
||||
QPointer<const QObject> _guard;
|
||||
Lambda _callable;
|
||||
|
||||
};
|
||||
|
||||
template <typename Lambda>
|
||||
class guard_with_weak {
|
||||
public:
|
||||
template <typename OtherLambda>
|
||||
guard_with_weak(
|
||||
const base::has_weak_ptr *object,
|
||||
OtherLambda &&other)
|
||||
: _guard(base::make_weak(object))
|
||||
, _callable(std::forward<OtherLambda>(other)) {
|
||||
}
|
||||
|
||||
template <
|
||||
typename ...OtherArgs,
|
||||
typename Return = decltype(std::declval<Lambda>()(std::declval<OtherArgs>()...))>
|
||||
Return operator()(OtherArgs &&...args) {
|
||||
return _guard
|
||||
? _callable(std::forward<OtherArgs>(args)...)
|
||||
: Return();
|
||||
}
|
||||
|
||||
template <
|
||||
typename ...OtherArgs,
|
||||
typename Return = decltype(std::declval<Lambda>()(std::declval<OtherArgs>()...))>
|
||||
Return operator()(OtherArgs &&...args) const {
|
||||
return _guard
|
||||
? _callable(std::forward<OtherArgs>(args)...)
|
||||
: Return();
|
||||
}
|
||||
|
||||
private:
|
||||
base::weak_ptr<const base::has_weak_ptr> _guard;
|
||||
Lambda _callable;
|
||||
|
||||
};
|
||||
|
||||
template <typename Lambda>
|
||||
struct lambda_call_type<guard_with_QObject<Lambda>> {
|
||||
using type = lambda_call_type_t<Lambda>;
|
||||
};
|
||||
|
||||
template <typename Lambda>
|
||||
struct lambda_call_type<guard_with_weak<Lambda>> {
|
||||
using type = lambda_call_type_t<Lambda>;
|
||||
};
|
||||
|
||||
} // namespace lambda_internal
|
||||
|
||||
template <typename Lambda>
|
||||
inline auto lambda_guarded(const QObject *object, Lambda &&lambda) {
|
||||
using Guarded = lambda_internal::guard_with_QObject<
|
||||
std::decay_t<Lambda>>;
|
||||
return Guarded(object, std::forward<Lambda>(lambda));
|
||||
}
|
||||
|
||||
template <typename Lambda>
|
||||
inline auto lambda_guarded(
|
||||
const base::has_weak_ptr *object,
|
||||
Lambda &&lambda) {
|
||||
using Guarded = lambda_internal::guard_with_weak<
|
||||
std::decay_t<Lambda>>;
|
||||
return Guarded(object, std::forward<Lambda>(lambda));
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "base/observer.h"
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -28,19 +15,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
namespace base {
|
||||
namespace internal {
|
||||
|
||||
using ObservableCallHandlers = base::lambda<void()>;
|
||||
using ObservableCallHandlers = Fn<void()>;
|
||||
void RegisterPendingObservable(ObservableCallHandlers *handlers);
|
||||
void UnregisterActiveObservable(ObservableCallHandlers *handlers);
|
||||
void UnregisterObservable(ObservableCallHandlers *handlers);
|
||||
|
||||
template <typename EventType>
|
||||
struct SubscriptionHandlerHelper {
|
||||
using type = base::lambda<void(parameter_type<EventType>)>;
|
||||
using type = Fn<void(parameter_type<EventType>)>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct SubscriptionHandlerHelper<void> {
|
||||
using type = base::lambda<void()>;
|
||||
using type = Fn<void()>;
|
||||
};
|
||||
|
||||
template <typename EventType>
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/bytes.h"
|
||||
|
||||
extern "C" {
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/crypto.h>
|
||||
} // extern "C"
|
||||
|
||||
namespace openssl {
|
||||
|
||||
@@ -73,7 +66,7 @@ public:
|
||||
explicit BigNum(unsigned int word) : BigNum() {
|
||||
setWord(word);
|
||||
}
|
||||
explicit BigNum(base::const_byte_span bytes) : BigNum() {
|
||||
explicit BigNum(bytes::const_span bytes) : BigNum() {
|
||||
setBytes(bytes);
|
||||
}
|
||||
|
||||
@@ -82,7 +75,7 @@ public:
|
||||
_failed = true;
|
||||
}
|
||||
}
|
||||
void setBytes(base::const_byte_span bytes) {
|
||||
void setBytes(bytes::const_span bytes) {
|
||||
if (!BN_bin2bn(
|
||||
reinterpret_cast<const unsigned char*>(bytes.data()),
|
||||
bytes.size(),
|
||||
@@ -174,12 +167,12 @@ public:
|
||||
return failed() ? 0 : BN_num_bytes(raw());
|
||||
}
|
||||
|
||||
base::byte_vector getBytes() const {
|
||||
bytes::vector getBytes() const {
|
||||
if (failed()) {
|
||||
return base::byte_vector();
|
||||
return {};
|
||||
}
|
||||
auto length = BN_num_bytes(raw());
|
||||
auto result = base::byte_vector(length, gsl::byte());
|
||||
auto result = bytes::vector(length);
|
||||
auto resultSize = BN_bn2bin(
|
||||
raw(),
|
||||
reinterpret_cast<unsigned char*>(result.data()));
|
||||
@@ -219,20 +212,45 @@ inline BigNum operator-(const BigNum &a, const BigNum &b) {
|
||||
return result;
|
||||
}
|
||||
|
||||
inline base::byte_array<SHA256_DIGEST_LENGTH> Sha256(base::const_byte_span bytes) {
|
||||
auto result = base::byte_array<SHA256_DIGEST_LENGTH>();
|
||||
SHA256(reinterpret_cast<const unsigned char*>(bytes.data()), bytes.size(), reinterpret_cast<unsigned char*>(result.data()));
|
||||
inline bytes::vector Sha512(bytes::const_span data) {
|
||||
auto result = bytes::vector(SHA512_DIGEST_LENGTH);
|
||||
SHA512(
|
||||
reinterpret_cast<const unsigned char*>(data.data()),
|
||||
data.size(),
|
||||
reinterpret_cast<unsigned char*>(result.data()));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline base::byte_array<SHA_DIGEST_LENGTH> Sha1(base::const_byte_span bytes) {
|
||||
auto result = base::byte_array<SHA_DIGEST_LENGTH>();
|
||||
SHA1(reinterpret_cast<const unsigned char*>(bytes.data()), bytes.size(), reinterpret_cast<unsigned char*>(result.data()));
|
||||
inline bytes::vector Sha256(bytes::const_span data) {
|
||||
auto result = bytes::vector(SHA256_DIGEST_LENGTH);
|
||||
SHA256(
|
||||
reinterpret_cast<const unsigned char*>(data.data()),
|
||||
data.size(),
|
||||
reinterpret_cast<unsigned char*>(result.data()));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline int FillRandom(base::byte_span bytes) {
|
||||
return RAND_bytes(reinterpret_cast<unsigned char*>(bytes.data()), bytes.size());
|
||||
inline bytes::vector Sha1(bytes::const_span data) {
|
||||
auto result = bytes::vector(SHA_DIGEST_LENGTH);
|
||||
SHA1(
|
||||
reinterpret_cast<const unsigned char*>(data.data()),
|
||||
data.size(),
|
||||
reinterpret_cast<unsigned char*>(result.data()));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void AddRandomSeed(bytes::const_span data) {
|
||||
RAND_seed(data.data(), data.size());
|
||||
}
|
||||
|
||||
} // namespace openssl
|
||||
|
||||
namespace bytes {
|
||||
|
||||
inline void set_random(span destination) {
|
||||
RAND_bytes(
|
||||
reinterpret_cast<unsigned char*>(destination.data()),
|
||||
destination.size());
|
||||
}
|
||||
|
||||
} // namespace bytes
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -100,6 +87,15 @@ public:
|
||||
return _impl >= other._impl;
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
T &set(Args &&...args) {
|
||||
_impl.template set<T>(std::forward<Args>(args)...);
|
||||
return get_unchecked<T>();
|
||||
}
|
||||
void clear() {
|
||||
_impl.template set<none_type>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
decltype(auto) is() const {
|
||||
return _impl.template is<T>();
|
||||
@@ -159,28 +155,34 @@ using optional_chain_result_t = typename optional_chain_result<Type>::type;
|
||||
|
||||
template <typename Type>
|
||||
class optional : public optional_variant<Type> {
|
||||
using parent = optional_variant<Type>;
|
||||
|
||||
public:
|
||||
using optional_variant<Type>::optional_variant;
|
||||
using parent::parent;
|
||||
|
||||
Type &operator*() {
|
||||
auto result = get_if<Type>(this);
|
||||
Expects(result != nullptr);
|
||||
return *result;
|
||||
Expects(parent::template is<Type>());
|
||||
|
||||
return parent::template get_unchecked<Type>();
|
||||
}
|
||||
const Type &operator*() const {
|
||||
auto result = get_if<Type>(this);
|
||||
Expects(result != nullptr);
|
||||
return *result;
|
||||
Expects(parent::template is<Type>());
|
||||
|
||||
return parent::template get_unchecked<Type>();
|
||||
}
|
||||
Type *operator->() {
|
||||
auto result = get_if<Type>(this);
|
||||
Expects(result != nullptr);
|
||||
return result;
|
||||
Expects(parent::template is<Type>());
|
||||
|
||||
return std::addressof(parent::template get_unchecked<Type>());
|
||||
}
|
||||
const Type *operator->() const {
|
||||
auto result = get_if<Type>(this);
|
||||
Expects(result != nullptr);
|
||||
return result;
|
||||
Expects(parent::template is<Type>());
|
||||
|
||||
return std::addressof(parent::template get_unchecked<Type>());
|
||||
}
|
||||
template <typename ...Args>
|
||||
Type &emplace(Args &&...args) {
|
||||
return parent::template set<Type>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "base/parse_helper.h"
|
||||
|
||||
|
||||