Compare commits
360 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08fa6a9815 | ||
|
|
a7cf4027ea | ||
|
|
646c7ecceb | ||
|
|
3cbbe3d3c2 | ||
|
|
0af26dd353 | ||
|
|
159e366122 | ||
|
|
b9081c26ba | ||
|
|
9933c6ba59 | ||
|
|
eb0642f569 | ||
|
|
1cce35a5a5 | ||
|
|
aeb71e089a | ||
|
|
b962efeca3 | ||
|
|
eb6c350e72 | ||
|
|
d496d41e7e | ||
|
|
19aa4f4acc | ||
|
|
19350e3846 | ||
|
|
741b524d71 | ||
|
|
84288112fc | ||
|
|
7c537cd787 | ||
|
|
c56977cbc1 | ||
|
|
2afa2cd9ab | ||
|
|
442d0da5c1 | ||
|
|
db6bdf36af | ||
|
|
b246328dcf | ||
|
|
a27ea35edd | ||
|
|
a7c4aea9ff | ||
|
|
1ba870a655 | ||
|
|
5bc3cf56fd | ||
|
|
3c4cf2862b | ||
|
|
af69a7a01f | ||
|
|
b9f7a501f5 | ||
|
|
322a085b70 | ||
|
|
6c4dc34441 | ||
|
|
efa287b786 | ||
|
|
23e1c6128b | ||
|
|
bc71a2619a | ||
|
|
4f3510c47c | ||
|
|
2adc20f07f | ||
|
|
b6ade7ce19 | ||
|
|
cabed9587b | ||
|
|
0ce01410a1 | ||
|
|
d02819db13 | ||
|
|
46bae9ed74 | ||
|
|
693ff3398e | ||
|
|
567216f41f | ||
|
|
1ef0791bc6 | ||
|
|
ef5e39f680 | ||
|
|
27228480a8 | ||
|
|
eebe1f4c11 | ||
|
|
5d5e4cbdff | ||
|
|
7e9920b5ea | ||
|
|
297fd0f0c8 | ||
|
|
0eec470387 | ||
|
|
7a64725045 | ||
|
|
1acfe441e1 | ||
|
|
80e932a083 | ||
|
|
698d32db57 | ||
|
|
2ee7cc784f | ||
|
|
071411c8b9 | ||
|
|
43671e2b47 | ||
|
|
1666683dbb | ||
|
|
c134861cd9 | ||
|
|
a1a5ef9d39 | ||
|
|
7e98e9ecf2 | ||
|
|
cad6faa790 | ||
|
|
13ad39dfc2 | ||
|
|
aa8ca28f77 | ||
|
|
d424a8b039 | ||
|
|
9896855789 | ||
|
|
613d4932ca | ||
|
|
44f79b8331 | ||
|
|
aa1117a714 | ||
|
|
8748265b00 | ||
|
|
be8aeb0d96 | ||
|
|
599cc35e57 | ||
|
|
bd367da1bd | ||
|
|
62b50a41c8 | ||
|
|
a3caecbc07 | ||
|
|
71354d1611 | ||
|
|
232fceeee6 | ||
|
|
19c4130a1d | ||
|
|
dc5abf8ddd | ||
|
|
b334a1f4fd | ||
|
|
17f40d6a1f | ||
|
|
77078f704c | ||
|
|
df8176d671 | ||
|
|
cad8a85497 | ||
|
|
66093f0cb5 | ||
|
|
9633f93690 | ||
|
|
1b8352f878 | ||
|
|
27bcd35832 | ||
|
|
b401f0bfea | ||
|
|
36391617d7 | ||
|
|
5bf46c0e90 | ||
|
|
690e1013cf | ||
|
|
63c2db30f2 | ||
|
|
bf388d8a37 | ||
|
|
b4571b80d6 | ||
|
|
2cbd2725e5 | ||
|
|
7f969e5102 | ||
|
|
e878ccccb4 | ||
|
|
11bb4ec615 | ||
|
|
168cdaf350 | ||
|
|
0ae819397a | ||
|
|
627eba1c5a | ||
|
|
673eb1090f | ||
|
|
43f0da683f | ||
|
|
1bb6b07515 | ||
|
|
aacb720664 | ||
|
|
12dd72bddf | ||
|
|
891559b3d9 | ||
|
|
b43f8fcff7 | ||
|
|
ce40ecc7f9 | ||
|
|
d6c188d642 | ||
|
|
bd490421e8 | ||
|
|
b9b6d4dba1 | ||
|
|
349fbeeb23 | ||
|
|
68b1b595a5 | ||
|
|
cf4dfa55da | ||
|
|
8296d72923 | ||
|
|
2364b0ad4e | ||
|
|
076f0e0800 | ||
|
|
191ea6f0f4 | ||
|
|
7cf3babcbd | ||
|
|
98af2d3006 | ||
|
|
b3858d5d97 | ||
|
|
1d7ad701b4 | ||
|
|
9513aaa768 | ||
|
|
446f0f1653 | ||
|
|
7d9b999cb0 | ||
|
|
c647afec02 | ||
|
|
4c181b6d08 | ||
|
|
a4d3c694bc | ||
|
|
721b2ebe8a | ||
|
|
b135a09e00 | ||
|
|
6327d5ea38 | ||
|
|
2a99046bbd | ||
|
|
a3a48a38c8 | ||
|
|
4518067f9c | ||
|
|
54a12aa74f | ||
|
|
1dd83f3d34 | ||
|
|
c7c652a277 | ||
|
|
faf6c48f25 | ||
|
|
14f113266f | ||
|
|
5ebea97ded | ||
|
|
af350e2daa | ||
|
|
b0a24238e8 | ||
|
|
2ce8094932 | ||
|
|
ca0b34dcf0 | ||
|
|
833a259234 | ||
|
|
1ab8830ba8 | ||
|
|
40443b7547 | ||
|
|
ca1c826c5c | ||
|
|
bd1d7f4d96 | ||
|
|
5bee6310c0 | ||
|
|
3a38497c4c | ||
|
|
ae3659d15b | ||
|
|
25746d195c | ||
|
|
ae819eb1a6 | ||
|
|
48cf0a4382 | ||
|
|
5fe9c93cb6 | ||
|
|
cb99d611f3 | ||
|
|
0e93693856 | ||
|
|
9e93ecc154 | ||
|
|
2cf579426b | ||
|
|
6118ced862 | ||
|
|
8db8bc466e | ||
|
|
994d789c60 | ||
|
|
a043e22622 | ||
|
|
ccb3bbea15 | ||
|
|
1b73b34810 | ||
|
|
36de2e98d4 | ||
|
|
9fba9048af | ||
|
|
95b29f5f35 | ||
|
|
13eeddf479 | ||
|
|
3991be752c | ||
|
|
0f3ec7893d | ||
|
|
351a2eee08 | ||
|
|
6ff2c08764 | ||
|
|
d163135117 | ||
|
|
ecd217a79f | ||
|
|
4aa9c1fea3 | ||
|
|
2e60b28612 | ||
|
|
2bbe511a6f | ||
|
|
5cbdc2f739 | ||
|
|
6f88e46938 | ||
|
|
8209602cbd | ||
|
|
b3e547f4dd | ||
|
|
5289810b81 | ||
|
|
3cb333d323 | ||
|
|
2565b948d9 | ||
|
|
5101ea2a96 | ||
|
|
23150d4e2a | ||
|
|
66926ba25e | ||
|
|
b4a7d98fa0 | ||
|
|
620f6657ae | ||
|
|
577f4b6271 | ||
|
|
9c27271571 | ||
|
|
cad87f6818 | ||
|
|
a9a69c7d14 | ||
|
|
5990b0fabf | ||
|
|
6986430f37 | ||
|
|
04eff72ce8 | ||
|
|
985f557adf | ||
|
|
77b2572854 | ||
|
|
993b501996 | ||
|
|
bba45293da | ||
|
|
58fe2d7ecc | ||
|
|
cfddca8f58 | ||
|
|
6f50906952 | ||
|
|
1f39d16a35 | ||
|
|
54f697eba1 | ||
|
|
02e2fb1258 | ||
|
|
d01969ff1e | ||
|
|
e4d8a06cf9 | ||
|
|
8ec64f4167 | ||
|
|
06ea927095 | ||
|
|
14e4524776 | ||
|
|
7dc9d5c37f | ||
|
|
d827045199 | ||
|
|
76d44172f1 | ||
|
|
afc9eb7cef | ||
|
|
b0bb8b05fd | ||
|
|
6e75668e45 | ||
|
|
f86afc9539 | ||
|
|
74ecd44294 | ||
|
|
273a2809cf | ||
|
|
ebb6b4ab63 | ||
|
|
a8106aa38d | ||
|
|
6abfdd20fa | ||
|
|
4dd1f95fbf | ||
|
|
a1faee285c | ||
|
|
8937d732f6 | ||
|
|
589556442c | ||
|
|
0e6b333bde | ||
|
|
9328f31a65 | ||
|
|
d5c145b707 | ||
|
|
3649cb41e2 | ||
|
|
cd85c4911c | ||
|
|
4db2b83c9b | ||
|
|
a1de77e8d2 | ||
|
|
6bd2be0aee | ||
|
|
1b364f2621 | ||
|
|
0310d9902c | ||
|
|
d55d383627 | ||
|
|
84de08cad6 | ||
|
|
cc0b1b1d54 | ||
|
|
e2205c7251 | ||
|
|
2d6bac5a28 | ||
|
|
7ad26a0fca | ||
|
|
48148a8cc3 | ||
|
|
1be37a10b3 | ||
|
|
4937cea38f | ||
|
|
b775d577a4 | ||
|
|
cb653df0f6 | ||
|
|
2407ac50bc | ||
|
|
fbf3168317 | ||
|
|
fe9cf7ddad | ||
|
|
88b555e907 | ||
|
|
234fdbed4a | ||
|
|
6cb0834d19 | ||
|
|
e26dd4e418 | ||
|
|
a8c230aba3 | ||
|
|
b81868eeba | ||
|
|
b2e9c4ab75 | ||
|
|
a458c89810 | ||
|
|
5df0b08a42 | ||
|
|
c8d273c2a3 | ||
|
|
badebb261b | ||
|
|
beb062dd64 | ||
|
|
33c0c79593 | ||
|
|
1a9c6749ae | ||
|
|
587715a966 | ||
|
|
b5cb2bc9f0 | ||
|
|
a4e4681835 | ||
|
|
8281990bb8 | ||
|
|
2c1e7bfcb6 | ||
|
|
bd8e7fdddd | ||
|
|
037f2bcce2 | ||
|
|
819e1602ef | ||
|
|
fe6ad54836 | ||
|
|
92756f418b | ||
|
|
cbbbcd877c | ||
|
|
34f0aae418 | ||
|
|
f0b8ccbd71 | ||
|
|
c200263f2e | ||
|
|
1ff53eb585 | ||
|
|
32491ead5e | ||
|
|
468d01fc1a | ||
|
|
1c44121db7 | ||
|
|
b561705528 | ||
|
|
eed706f917 | ||
|
|
4bd2091e6e | ||
|
|
22f45bc1fb | ||
|
|
1cc3440fcc | ||
|
|
1cd4cb3baa | ||
|
|
11165abc09 | ||
|
|
f8a17bd9c9 | ||
|
|
47bb04b019 | ||
|
|
8bcb30e84d | ||
|
|
81c48e1b09 | ||
|
|
377ee7df06 | ||
|
|
4fabb3f2a2 | ||
|
|
ad3f8e72a0 | ||
|
|
01139e1b04 | ||
|
|
eaed91263e | ||
|
|
188c6ba64a | ||
|
|
823bbb1b77 | ||
|
|
f324017299 | ||
|
|
76837c6f44 | ||
|
|
5e6a4d9e8d | ||
|
|
01773e5bb1 | ||
|
|
5d8a2bc7b7 | ||
|
|
beaea9c57d | ||
|
|
3c799a5cc1 | ||
|
|
5e20c15c20 | ||
|
|
d0ae07f3c2 | ||
|
|
97fa92de0b | ||
|
|
c481d48865 | ||
|
|
545cf93d82 | ||
|
|
6ff29b8902 | ||
|
|
623176e901 | ||
|
|
03b35457fa | ||
|
|
01748d8aba | ||
|
|
7866013ab6 | ||
|
|
ac3834bfdb | ||
|
|
57af221d39 | ||
|
|
8cd5105813 | ||
|
|
d89573bab5 | ||
|
|
39f9fee22f | ||
|
|
6695d7d503 | ||
|
|
3fdb807a1e | ||
|
|
2acedca6b7 | ||
|
|
22dc7023fc | ||
|
|
9946fbbd89 | ||
|
|
fec7febc8e | ||
|
|
0b86caef67 | ||
|
|
c39b9e9635 | ||
|
|
05524c3f6c | ||
|
|
b9a766387c | ||
|
|
54a0f443b4 | ||
|
|
04a8a9b7ee | ||
|
|
c77f07239f | ||
|
|
b383dad6ac | ||
|
|
f18bf46fb1 | ||
|
|
2bda3c4e2b | ||
|
|
4484edd212 | ||
|
|
ace363f432 | ||
|
|
d6ed23b3dd | ||
|
|
51cd07945b | ||
|
|
9ee4ad95d0 | ||
|
|
4ade80905f | ||
|
|
70b039a6e4 | ||
|
|
4bde87cda4 | ||
|
|
94b4809cdf | ||
|
|
109f6614f0 | ||
|
|
88b0ea70b3 | ||
|
|
c7583e3106 | ||
|
|
b9003202bf | ||
|
|
53c4b511f8 |
8
.github/ISSUE_TEMPLATE/QUESTION.md
vendored
@@ -1,8 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask a question.
|
||||
title: "[Question] "
|
||||
labels: 'question'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
11
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: API issue
|
||||
url: https://bugs.telegram.org
|
||||
about: Any bug report or feature request affecting more than only Telegram Desktop.
|
||||
- name: Issue of other client
|
||||
url: https://bugs.telegram.org
|
||||
about: Any bug report or feature request not about Telegram Desktop.
|
||||
- name: Question
|
||||
url: https://t.me/TelegramDesktopTalk
|
||||
about: Ask a question.
|
||||
2
.github/workflows/docker.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
run: |
|
||||
cd Telegram/build/docker/centos_env
|
||||
poetry install
|
||||
DEBUG= LTO= poetry run gen_dockerfile | docker buildx build -t $IMAGE_TAG -
|
||||
DEBUG= LTO= poetry run gen_dockerfile | DOCKER_BUILDKIT=1 docker build -t $IMAGE_TAG -
|
||||
|
||||
- name: Push the Docker image.
|
||||
if: ${{ github.ref_name == github.event.repository.default_branch }}
|
||||
|
||||
2
.github/workflows/linux.yml
vendored
@@ -93,6 +93,8 @@ jobs:
|
||||
fi
|
||||
|
||||
./configure.sh \
|
||||
-D CMAKE_C_FLAGS_DEBUG="" \
|
||||
-D CMAKE_CXX_FLAGS_DEBUG="" \
|
||||
-D CMAKE_C_FLAGS="-Werror" \
|
||||
-D CMAKE_CXX_FLAGS="-Werror" \
|
||||
-D CMAKE_EXE_LINKER_FLAGS="-s" \
|
||||
|
||||
2
.github/workflows/mac.yml
vendored
@@ -119,7 +119,7 @@ jobs:
|
||||
|
||||
cd ../out
|
||||
|
||||
xcoderun='xcodebuild build -project Telegram.xcodeproj -scheme Telegram -destination "platform=macOS,arch=x86_64" -configuration Debug'
|
||||
xcoderun='xcodebuild build -project Telegram.xcodeproj -scheme Telegram -destination "platform=macOS,arch=x86_64" -configuration Debug CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO'
|
||||
bash -c "$xcoderun" || bash -c "$xcoderun" || bash -c "$xcoderun"
|
||||
|
||||
- name: Move artifact.
|
||||
|
||||
1
.github/workflows/snap.yml
vendored
@@ -54,6 +54,7 @@ jobs:
|
||||
|
||||
- name: First set up.
|
||||
run: |
|
||||
sudo iptables -P FORWARD ACCEPT
|
||||
sudo snap install --classic snapcraft
|
||||
sudo usermod -aG lxd $USER
|
||||
sudo snap run lxd init --auto
|
||||
|
||||
18
.github/workflows/win.yml
vendored
@@ -82,9 +82,6 @@ jobs:
|
||||
submodules: recursive
|
||||
path: ${{ env.TBUILD }}\${{ env.REPO_NAME }}
|
||||
|
||||
- name: Python installs.
|
||||
run: pip3 install --upgrade pywin32 six
|
||||
|
||||
- name: Set up environment paths.
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -119,13 +116,20 @@ jobs:
|
||||
DEFINE=""
|
||||
if [ -n "${{ matrix.defines }}" ]; then
|
||||
DEFINE="-D ${{ matrix.defines }}=ON"
|
||||
echo Define from matrix: $DEFINE
|
||||
echo "Define from matrix: $DEFINE"
|
||||
echo "ARTIFACT_NAME=Telegram_${{ matrix.arch }}_${{ matrix.defines }}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "ARTIFACT_NAME=Telegram_${{ matrix.arch }}" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "TDESKTOP_BUILD_DEFINE=$DEFINE" >> $GITHUB_ENV
|
||||
|
||||
API="-D TDESKTOP_API_TEST=ON"
|
||||
if [ ${{ github.ref == 'refs/heads/nightly' }} ]; then
|
||||
echo "Use the open credentials."
|
||||
API="-D TDESKTOP_API_ID=611335 -D TDESKTOP_API_HASH=d524b414d21f4d37f08684c1df41ac9c"
|
||||
fi
|
||||
echo "TDESKTOP_BUILD_API=$API" >> $GITHUB_ENV
|
||||
|
||||
- name: Free up some disk space.
|
||||
run: |
|
||||
del /S Libraries\*.pdb
|
||||
@@ -139,7 +143,7 @@ jobs:
|
||||
|
||||
call configure.bat ^
|
||||
${{ matrix.arch }} ^
|
||||
-D TDESKTOP_API_TEST=ON ^
|
||||
%TDESKTOP_BUILD_API% ^
|
||||
-D DESKTOP_APP_DISABLE_CRASH_REPORTS=OFF ^
|
||||
-D DESKTOP_APP_NO_PDB=ON ^
|
||||
%TDESKTOP_BUILD_DEFINE% ^
|
||||
@@ -149,13 +153,13 @@ jobs:
|
||||
msbuild -m Telegram.sln /p:Configuration=Debug,Platform=${{ matrix.arch }},DebugSymbols=false,DebugType=none
|
||||
|
||||
- name: Move artifact.
|
||||
if: env.UPLOAD_ARTIFACT == 'true'
|
||||
if: (env.UPLOAD_ARTIFACT == 'true') || ${{ github.ref == 'refs/heads/nightly' }}
|
||||
run: |
|
||||
mkdir artifact
|
||||
move %TBUILD%\%REPO_NAME%\out\Debug\Telegram.exe artifact/
|
||||
- uses: actions/upload-artifact@master
|
||||
name: Upload artifact.
|
||||
if: env.UPLOAD_ARTIFACT == 'true'
|
||||
if: (env.UPLOAD_ARTIFACT == 'true') || ${{ github.ref == 'refs/heads/nightly' }}
|
||||
with:
|
||||
name: ${{ env.ARTIFACT_NAME }}
|
||||
path: artifact\
|
||||
|
||||
@@ -36,6 +36,10 @@ get_filename_component(third_party_loc "Telegram/ThirdParty" REALPATH)
|
||||
get_filename_component(submodules_loc "Telegram" REALPATH)
|
||||
get_filename_component(cmake_helpers_loc "cmake" REALPATH)
|
||||
|
||||
if (NOT DESKTOP_APP_USE_PACKAGED AND WIN32)
|
||||
set(Python_EXECUTABLE ${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/python/Scripts/python)
|
||||
endif()
|
||||
|
||||
include(cmake/variables.cmake)
|
||||
include(cmake/nice_target_sources.cmake)
|
||||
include(cmake/target_compile_options_if_exists.cmake)
|
||||
@@ -52,11 +56,11 @@ include(cmake/options.cmake)
|
||||
|
||||
if (NOT DESKTOP_APP_USE_PACKAGED)
|
||||
if (WIN32)
|
||||
set(qt_version 5.15.4)
|
||||
set(qt_version 5.15.7)
|
||||
elseif (APPLE)
|
||||
set(qt_version 6.3.1)
|
||||
set(qt_version 6.3.2)
|
||||
else()
|
||||
set(qt_version 6.4.1)
|
||||
set(qt_version 6.4.2)
|
||||
endif()
|
||||
endif()
|
||||
include(cmake/external/qt/package.cmake)
|
||||
|
||||
2
LEGAL
@@ -1,7 +1,7 @@
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
Copyright (c) 2014-2022 The Telegram Desktop Authors.
|
||||
Copyright (c) 2014-2023 The Telegram Desktop Authors.
|
||||
|
||||
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
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
add_executable(Telegram WIN32 MACOSX_BUNDLE)
|
||||
init_non_host_target(Telegram)
|
||||
init_non_host_target(Telegram ltcg)
|
||||
|
||||
add_subdirectory(lib_rpl)
|
||||
add_subdirectory(lib_crl)
|
||||
@@ -184,6 +184,8 @@ PRIVATE
|
||||
boxes/peers/edit_forum_topic_box.h
|
||||
boxes/peers/edit_linked_chat_box.cpp
|
||||
boxes/peers/edit_linked_chat_box.h
|
||||
boxes/peers/edit_members_visible.cpp
|
||||
boxes/peers/edit_members_visible.h
|
||||
boxes/peers/edit_participant_box.cpp
|
||||
boxes/peers/edit_participant_box.h
|
||||
boxes/peers/edit_participants_box.cpp
|
||||
@@ -667,14 +669,18 @@ PRIVATE
|
||||
history/view/media/history_view_media_common.h
|
||||
history/view/media/history_view_media_grouped.cpp
|
||||
history/view/media/history_view_media_grouped.h
|
||||
history/view/media/history_view_media_spoiler.cpp
|
||||
history/view/media/history_view_media_spoiler.h
|
||||
history/view/media/history_view_media_unwrapped.cpp
|
||||
history/view/media/history_view_media_unwrapped.h
|
||||
history/view/media/history_view_photo.cpp
|
||||
history/view/media/history_view_photo.h
|
||||
history/view/media/history_view_poll.cpp
|
||||
history/view/media/history_view_poll.h
|
||||
history/view/media/history_view_service_media_gift.cpp
|
||||
history/view/media/history_view_service_media_gift.h
|
||||
history/view/media/history_view_premium_gift.cpp
|
||||
history/view/media/history_view_premium_gift.h
|
||||
history/view/media/history_view_service_box.cpp
|
||||
history/view/media/history_view_service_box.h
|
||||
history/view/media/history_view_slot_machine.cpp
|
||||
history/view/media/history_view_slot_machine.h
|
||||
history/view/media/history_view_sticker.cpp
|
||||
@@ -684,6 +690,8 @@ PRIVATE
|
||||
history/view/media/history_view_sticker_player_abstract.h
|
||||
history/view/media/history_view_theme_document.cpp
|
||||
history/view/media/history_view_theme_document.h
|
||||
history/view/media/history_view_userpic_suggestion.cpp
|
||||
history/view/media/history_view_userpic_suggestion.h
|
||||
history/view/media/history_view_web_page.cpp
|
||||
history/view/media/history_view_web_page.h
|
||||
history/view/reactions/history_view_reactions.cpp
|
||||
@@ -764,6 +772,8 @@ PRIVATE
|
||||
history/history_item_components.h
|
||||
history/history_item_edition.cpp
|
||||
history/history_item_edition.h
|
||||
history/history_item_helpers.cpp
|
||||
history/history_item_helpers.h
|
||||
history/history_item_reply_markup.cpp
|
||||
history/history_item_reply_markup.h
|
||||
history/history_item_text.cpp
|
||||
@@ -772,10 +782,6 @@ PRIVATE
|
||||
history/history_inner_widget.h
|
||||
history/history_location_manager.cpp
|
||||
history/history_location_manager.h
|
||||
history/history_message.cpp
|
||||
history/history_message.h
|
||||
history/history_service.cpp
|
||||
history/history_service.h
|
||||
history/history_unread_things.cpp
|
||||
history/history_unread_things.h
|
||||
history/history_view_highlight_manager.cpp
|
||||
@@ -843,6 +849,8 @@ PRIVATE
|
||||
info/profile/info_profile_members.h
|
||||
info/profile/info_profile_members_controllers.cpp
|
||||
info/profile/info_profile_members_controllers.h
|
||||
info/profile/info_profile_phone_menu.cpp
|
||||
info/profile/info_profile_phone_menu.h
|
||||
info/profile/info_profile_text.cpp
|
||||
info/profile/info_profile_text.h
|
||||
info/profile/info_profile_values.cpp
|
||||
@@ -980,6 +988,8 @@ PRIVATE
|
||||
media/view/media_view_playback_progress.cpp
|
||||
media/view/media_view_playback_progress.h
|
||||
media/view/media_view_open_common.h
|
||||
menu/menu_antispam_validator.cpp
|
||||
menu/menu_antispam_validator.h
|
||||
menu/menu_item_download_files.cpp
|
||||
menu/menu_item_download_files.h
|
||||
menu/menu_mute.cpp
|
||||
@@ -1173,6 +1183,8 @@ PRIVATE
|
||||
settings/settings_experimental.h
|
||||
settings/settings_folders.cpp
|
||||
settings/settings_folders.h
|
||||
settings/settings_global_ttl.cpp
|
||||
settings/settings_global_ttl.h
|
||||
settings/settings_information.cpp
|
||||
settings/settings_information.h
|
||||
settings/settings_intro.cpp
|
||||
@@ -1250,6 +1262,10 @@ PRIVATE
|
||||
ui/chat/choose_send_as.h
|
||||
ui/chat/choose_theme_controller.cpp
|
||||
ui/chat/choose_theme_controller.h
|
||||
ui/controls/silent_toggle.cpp
|
||||
ui/controls/silent_toggle.h
|
||||
ui/controls/userpic_button.cpp
|
||||
ui/controls/userpic_button.h
|
||||
ui/effects/emoji_fly_animation.cpp
|
||||
ui/effects/emoji_fly_animation.h
|
||||
ui/effects/message_sending_animation_common.h
|
||||
@@ -1269,8 +1285,6 @@ PRIVATE
|
||||
ui/widgets/level_meter.h
|
||||
ui/countryinput.cpp
|
||||
ui/countryinput.h
|
||||
ui/empty_userpic.cpp
|
||||
ui/empty_userpic.h
|
||||
ui/filter_icons.cpp
|
||||
ui/filter_icons.h
|
||||
ui/filter_icon_panel.cpp
|
||||
@@ -1280,8 +1294,6 @@ PRIVATE
|
||||
ui/resize_area.h
|
||||
ui/search_field_controller.cpp
|
||||
ui/search_field_controller.h
|
||||
ui/special_buttons.cpp
|
||||
ui/special_buttons.h
|
||||
ui/text/format_song_document_name.cpp
|
||||
ui/text/format_song_document_name.h
|
||||
ui/unread_badge.cpp
|
||||
@@ -1342,8 +1354,6 @@ PRIVATE
|
||||
apiwrap.cpp
|
||||
apiwrap.h
|
||||
config.h
|
||||
facades.cpp
|
||||
facades.h
|
||||
logs.cpp
|
||||
logs.h
|
||||
main.cpp
|
||||
@@ -1685,6 +1695,7 @@ endif()
|
||||
|
||||
if (LINUX AND DESKTOP_APP_USE_PACKAGED)
|
||||
include(GNUInstallDirs)
|
||||
configure_file("../lib/xdg/org.telegram.desktop.desktop" "${CMAKE_CURRENT_BINARY_DIR}/org.telegram.desktop.desktop" @ONLY)
|
||||
configure_file("../lib/xdg/org.telegram.desktop.metainfo.xml" "${CMAKE_CURRENT_BINARY_DIR}/org.telegram.desktop.metainfo.xml" @ONLY)
|
||||
generate_appdata_changelog(Telegram "${CMAKE_SOURCE_DIR}/changelog.txt" "${CMAKE_CURRENT_BINARY_DIR}/org.telegram.desktop.metainfo.xml")
|
||||
install(TARGETS Telegram RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
@@ -1695,6 +1706,6 @@ if (LINUX AND DESKTOP_APP_USE_PACKAGED)
|
||||
install(FILES "Resources/art/icon128.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/128x128/apps" RENAME "telegram.png")
|
||||
install(FILES "Resources/art/icon256.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps" RENAME "telegram.png")
|
||||
install(FILES "Resources/art/icon512.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/512x512/apps" RENAME "telegram.png")
|
||||
install(FILES "../lib/xdg/org.telegram.desktop.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/org.telegram.desktop.desktop" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/org.telegram.desktop.metainfo.xml" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo")
|
||||
endif()
|
||||
|
||||
BIN
Telegram/Resources/animations/ttl.tgs
Normal file
7
Telegram/Resources/art/topic_icons/general.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>general</title>
|
||||
<g id="general" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<path d="M14.4576257,1.02558449 C15.189053,1.1696007 15.6657078,1.88165413 15.5222641,2.61600035 L14.8818905,5.62412405 L16.6504058,5.62421139 C17.3957661,5.62421139 18,6.23085664 18,6.97919149 C18,7.72752633 17.3957661,8.33417159 16.6504058,8.33417159 L14.3525674,8.33397488 L13.6850637,11.7513347 L15.3008116,11.7515071 C16.0461719,11.7515071 16.6504058,12.3581524 16.6504058,13.1064872 C16.6504058,13.8548221 16.0461719,14.4614673 15.3008116,14.4614673 L13.1557407,14.4614328 L12.4307242,17.9055215 C12.2872804,18.6398677 11.5780573,19.1184247 10.84663,18.9744085 C10.1152028,18.8303923 9.63854794,18.1183389 9.7819917,17.3839927 L10.4051821,14.4614328 L7.75733538,14.4614328 L7.03234733,17.9055215 C6.90989534,18.5324024 6.37514133,18.9728813 5.76623746,18.9987859 L5.71387199,19 C5.62631985,19.0002755 5.53745163,18.9919715 5.44825318,18.9744085 C4.71682589,18.8303923 4.24017107,18.1183389 4.38361482,17.3839927 L5.00702313,14.4614328 L3.34959422,14.4614673 C2.60423391,14.4614673 2,13.8548221 2,13.1064872 C2,12.3581524 2.60423391,11.7515071 3.34959422,11.7515071 L5.53634616,11.7513347 L6.20384986,8.33397488 L4.69918844,8.33417159 C3.95382813,8.33417159 3.34959422,7.72752633 3.34959422,6.97919149 C3.34959422,6.23085664 3.95382813,5.62421139 4.69918844,5.62421139 L6.73317289,5.62412405 L7.4751547,2.09447154 C7.60110532,1.44967974 8.16325465,1.00209364 8.79363004,1 L8.84631136,1.00087004 C8.91674267,1.00340951 8.98789009,1.01153413 9.05924885,1.02558449 C9.79067614,1.1696007 10.267331,1.88165413 10.1238872,2.61600035 L9.48348515,5.62412405 L12.1315782,5.62412405 L12.8735316,2.09447154 C13.0169753,1.36012532 13.7261984,0.881568286 14.4576257,1.02558449 Z M10.9345052,11.7513347 L11.6020089,8.33397488 L8.95416211,8.33397488 L8.28665842,11.7513347 L10.9345052,11.7513347 Z" id="Combined-Shape-Copy-6" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
BIN
Telegram/Resources/icons/fragment.png
Normal file
|
After Width: | Height: | Size: 525 B |
BIN
Telegram/Resources/icons/fragment@2x.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
Telegram/Resources/icons/fragment@3x.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
Telegram/Resources/icons/info/edit/antispam.png
Normal file
|
After Width: | Height: | Size: 552 B |
BIN
Telegram/Resources/icons/info/edit/antispam@2x.png
Normal file
|
After Width: | Height: | Size: 986 B |
BIN
Telegram/Resources/icons/info/edit/antispam@3x.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/Resources/icons/info/edit/hidden_members.png
Normal file
|
After Width: | Height: | Size: 461 B |
BIN
Telegram/Resources/icons/info/edit/hidden_members@2x.png
Normal file
|
After Width: | Height: | Size: 810 B |
BIN
Telegram/Resources/icons/info/edit/hidden_members@3x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/menu/false_positive.png
Normal file
|
After Width: | Height: | Size: 670 B |
BIN
Telegram/Resources/icons/menu/false_positive@2x.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/Resources/icons/menu/false_positive@3x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
Telegram/Resources/icons/menu/photo_set.png
Normal file
|
After Width: | Height: | Size: 722 B |
BIN
Telegram/Resources/icons/menu/photo_set@2x.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Telegram/Resources/icons/menu/photo_set@3x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
Telegram/Resources/icons/menu/photo_suggest.png
Normal file
|
After Width: | Height: | Size: 768 B |
BIN
Telegram/Resources/icons/menu/photo_suggest@2x.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
Telegram/Resources/icons/menu/photo_suggest@3x.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
Telegram/Resources/icons/menu/spoiler_off.png
Normal file
|
After Width: | Height: | Size: 797 B |
BIN
Telegram/Resources/icons/menu/spoiler_off@2x.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/Resources/icons/menu/spoiler_off@3x.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
Telegram/Resources/icons/menu/spoiler_on.png
Normal file
|
After Width: | Height: | Size: 713 B |
BIN
Telegram/Resources/icons/menu/spoiler_on@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/menu/spoiler_on@3x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
Telegram/Resources/icons/settings/ttl.png
Normal file
|
After Width: | Height: | Size: 591 B |
BIN
Telegram/Resources/icons/settings/ttl/autodelete_off.png
Normal file
|
After Width: | Height: | Size: 454 B |
BIN
Telegram/Resources/icons/settings/ttl/autodelete_off@2x.png
Normal file
|
After Width: | Height: | Size: 757 B |
BIN
Telegram/Resources/icons/settings/ttl/autodelete_off@3x.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
Telegram/Resources/icons/settings/ttl/autodelete_on.png
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
Telegram/Resources/icons/settings/ttl/autodelete_on@2x.png
Normal file
|
After Width: | Height: | Size: 670 B |
BIN
Telegram/Resources/icons/settings/ttl/autodelete_on@3x.png
Normal file
|
After Width: | Height: | Size: 966 B |
BIN
Telegram/Resources/icons/settings/ttl@2x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/settings/ttl@3x.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
@@ -166,6 +166,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_scam_badge" = "SCAM";
|
||||
"lng_fake_badge" = "FAKE";
|
||||
|
||||
"lng_remember" = "Remember this choice";
|
||||
|
||||
"lng_channels_limit_title" = "Too Many Communities";
|
||||
"lng_channels_limit1#one" = "You are a member of **{count}** groups and channels.";
|
||||
"lng_channels_limit1#other" = "You are a member of **{count}** groups and channels.";
|
||||
@@ -306,21 +308,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_edit_caption_voice" = "Sorry, you can't edit your message while you're having an unsent voice message.";
|
||||
|
||||
"lng_intro_about" = "Welcome to the official Telegram Desktop app.\nIt's fast and secure.";
|
||||
"lng_start_msgs" = "START MESSAGING";
|
||||
"lng_start_msgs" = "Start messaging";
|
||||
|
||||
"lng_intro_next" = "NEXT";
|
||||
"lng_intro_finish" = "SIGN UP";
|
||||
"lng_intro_submit" = "SUBMIT";
|
||||
"lng_intro_next" = "Next";
|
||||
"lng_intro_finish" = "Sign up";
|
||||
"lng_intro_submit" = "Submit";
|
||||
|
||||
"lng_photo_caption" = "Caption";
|
||||
"lng_photos_comment" = "Comment";
|
||||
|
||||
"lng_intro_qr_title" = "Scan From Mobile Telegram";
|
||||
"lng_intro_qr_step1" = "Open Telegram on your phone";
|
||||
"lng_intro_qr_step2" = "Go to Settings > Devices > Scan QR Code";
|
||||
"lng_intro_qr_step2" = "Go to Settings > Devices > Link Desktop";
|
||||
"lng_intro_qr_step3" = "Scan this image to Log In";
|
||||
"lng_intro_qr_skip" = "Or log in using your phone number";
|
||||
|
||||
"lng_intro_fragment_title" = "Enter code";
|
||||
"lng_intro_fragment_about" = "Get the code for {phone_number} in the Anonymous Numbers section on Fragment.";
|
||||
"lng_intro_fragment_button" = "Open Fragment";
|
||||
|
||||
"lng_phone_title" = "Your Phone Number";
|
||||
"lng_phone_desc" = "Please confirm your country code and\nenter your mobile phone number.";
|
||||
"lng_phone_to_qr" = "Quick log in using QR code";
|
||||
@@ -391,8 +397,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
"lng_settings_save" = "Save";
|
||||
"lng_settings_upload" = "Set Profile Photo";
|
||||
"lng_settings_crop_profile" = "Select an area for your profile photo";
|
||||
"lng_settings_uploading_photo" = "Uploading photo...";
|
||||
"lng_settings_edit" = "Edit";
|
||||
"lng_settings_drop_area_subtitle" = "to set it as your photo";
|
||||
|
||||
@@ -402,6 +406,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_username_invalid" = "This username is invalid.";
|
||||
"lng_username_occupied" = "This username is already occupied.";
|
||||
"lng_username_too_short" = "This username is too short.";
|
||||
"lng_username_purchase_available" = "Sorry, this link is occupied by someone. But it's available for purchase through\nofficial {link}.";
|
||||
"lng_username_bad_symbols" = "Only a-z, 0-9, and underscores allowed.";
|
||||
"lng_username_available" = "This username is available.";
|
||||
"lng_username_not_found" = "User @{user} not found.";
|
||||
@@ -492,6 +497,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_change_lang" = "Change language";
|
||||
"lng_languages" = "Languages";
|
||||
"lng_languages_none" = "No languages found.";
|
||||
"lng_languages_count#one" = "{count} language";
|
||||
"lng_languages_count#other" = "{count} languages";
|
||||
"lng_sure_save_language" = "Telegram will restart in order to change language";
|
||||
"lng_settings_update_automatically" = "Update automatically";
|
||||
"lng_settings_install_beta" = "Install beta versions";
|
||||
@@ -666,6 +673,38 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_settings_cloud_password_email_confirm" = "Confirm and Finish";
|
||||
"lng_settings_cloud_password_reset_in" = "You can reset your password in {duration}.";
|
||||
|
||||
"lng_settings_ttl_title" = "Auto-Delete Messages";
|
||||
"lng_settings_ttl_about" = "Automatically delete messages for everyone after a period of time in all new chats you start.";
|
||||
"lng_settings_ttl_after" = "After {after_duration}";
|
||||
"lng_settings_ttl_after_hours#one" = "{count} hour";
|
||||
"lng_settings_ttl_after_hours#other" = "{count} hours";
|
||||
"lng_settings_ttl_after_days#one" = "{count} day";
|
||||
"lng_settings_ttl_after_days#other" = "{count} days";
|
||||
"lng_settings_ttl_after_weeks#one" = "{count} week";
|
||||
"lng_settings_ttl_after_weeks#other" = "{count} weeks";
|
||||
"lng_settings_ttl_after_months#one" = "{count} month";
|
||||
"lng_settings_ttl_after_months#other" = "{count} months";
|
||||
"lng_settings_ttl_after_years#one" = "{count} year";
|
||||
"lng_settings_ttl_after_years#other" = "{count} years";
|
||||
"lng_settings_ttl_after_off" = "Off";
|
||||
"lng_settings_ttl_after_custom" = "Set Custom Time";
|
||||
"lng_settings_ttl_after_about" = "If enabled, all new messages in chats you start will be automatically deleted for everyone at some point after they have been sent. You can also {link}.";
|
||||
"lng_settings_ttl_after_about_link" = "apply this setting for your existing chats";
|
||||
"lng_settings_ttl_after_subtitle" = "Self-destruct timer";
|
||||
"lng_settings_ttl_after_sure" = "Are you sure you want all messages in new chats started by you to be automatically deleted for everyone {after_duration} after they have been sent?";
|
||||
"lng_settings_ttl_after_toast" = "Messages in all new chats you start will be automatically deleted after {after_duration}.";
|
||||
|
||||
"lng_settings_ttl_select_chats_title" = "Select Chats";
|
||||
"lng_settings_ttl_select_chats_subtitle" = "to apply the self-destruct timer";
|
||||
"lng_settings_ttl_select_chats_subtitle_chosen" = "will have the self-destruct timer";
|
||||
"lng_settings_ttl_select_chats_sorry" = "Sorry, you can't set self-destruct timer for this chat.";
|
||||
"lng_settings_ttl_select_chats_status" = "auto-delete after {after_duration}";
|
||||
"lng_settings_ttl_select_chats_status_disabled" = "auto-deletion disabled";
|
||||
"lng_settings_ttl_select_chats_toast#one" = "Self-destruct timer for {duration} has been enabled in {count} selected chat.";
|
||||
"lng_settings_ttl_select_chats_toast#other" = "Self-destruct timer for {duration} has been enabled in {count} selected chats.";
|
||||
"lng_settings_ttl_select_chats_disabled_toast#one" = "Self-destruct timer has been disabled in {count} selected chat.";
|
||||
"lng_settings_ttl_select_chats_disabled_toast#other" = "Self-destruct timer has been disabled in {count} selected chats.";
|
||||
|
||||
"lng_clear_payment_info_title" = "Clear payment info";
|
||||
"lng_clear_payment_info_sure" = "Are you sure you want to clear your payment and shipping info?";
|
||||
"lng_clear_payment_info_shipping" = "Shipping info";
|
||||
@@ -716,6 +755,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_download_path" = "Download path";
|
||||
"lng_download_path_temp" = "Temp folder";
|
||||
"lng_download_path_default" = "Default folder";
|
||||
"lng_download_path_unset" = "Unset";
|
||||
"lng_download_path_clear" = "Clear all";
|
||||
"lng_download_path_header" = "Choose download path";
|
||||
"lng_download_path_default_radio" = "Telegram folder in system «Downloads»";
|
||||
@@ -1004,6 +1044,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_edit_privacy_forwards_always_empty" = "Always allow";
|
||||
"lng_edit_privacy_forwards_never_empty" = "Never allow";
|
||||
"lng_edit_privacy_forwards_exceptions" = "These settings will override the values above.";
|
||||
"lng_edit_privacy_forwards_exceptions_everyone" = "You can add users or entire groups which will not see your profile photo.";
|
||||
"lng_edit_privacy_forwards_exceptions_nobody" = "Add users or entire groups which will still see your profile photo.";
|
||||
"lng_edit_privacy_forwards_always_title" = "Always allow";
|
||||
"lng_edit_privacy_forwards_never_title" = "Never allow";
|
||||
"lng_edit_privacy_forwards_sample_message" = "Reinhardt, we need to find you some new tunes 🎶";
|
||||
@@ -1018,6 +1060,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_edit_privacy_profile_photo_exceptions" = "These settings will override the values above.";
|
||||
"lng_edit_privacy_profile_photo_always_title" = "Always allow";
|
||||
"lng_edit_privacy_profile_photo_never_title" = "Never allow";
|
||||
"lng_edit_privacy_profile_photo_public_set" = "Set Public Photo";
|
||||
"lng_edit_privacy_profile_photo_public_update" = "Update Public Photo";
|
||||
"lng_edit_privacy_profile_photo_public_remove" = "Remove Public Photo";
|
||||
"lng_edit_privacy_profile_photo_public_about" = "You can upload a public photo for those who are restricted from viewing your real profile photo.";
|
||||
"lng_edit_privacy_profile_photo_public_toast" = "This photo is now set for those who are restricted from viewing your main photo.";
|
||||
|
||||
"lng_edit_privacy_voices_title" = "Voice messages settings";
|
||||
"lng_edit_privacy_voices_header" = "Who can send me voice messages";
|
||||
@@ -1104,6 +1151,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_profile_set_group_photo" = "Set Photo";
|
||||
"lng_profile_add_participant" = "Add Members";
|
||||
"lng_profile_add_via_link" = "Invite via Link";
|
||||
"lng_profile_hide_participants" = "Hide Members";
|
||||
"lng_profile_hide_participants_about" = "Switch this on to hide the list of members in this group. Admins will remain visible.";
|
||||
"lng_profile_view_channel" = "View Channel";
|
||||
"lng_profile_view_discussion" = "View discussion";
|
||||
"lng_profile_join_channel" = "Join Channel";
|
||||
@@ -1146,7 +1195,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
"lng_profile_info_section" = "Info";
|
||||
"lng_info_tab_media" = "Media";
|
||||
"lng_info_public_photo" = "public photo";
|
||||
"lng_info_mobile_label" = "Mobile";
|
||||
"lng_info_mobile_context_menu_fragment_about" = "This number is not tied to a SIM card and was acquired on {link}.";
|
||||
"lng_info_mobile_context_menu_fragment_about_link" = "Fragment";
|
||||
"lng_info_mobile_hidden" = "Hidden";
|
||||
"lng_info_username_label" = "Username";
|
||||
"lng_info_usernames_label" = "also";
|
||||
@@ -1163,6 +1215,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_profile_send_message" = "Send Message";
|
||||
"lng_info_add_as_contact" = "Add to contacts";
|
||||
"lng_profile_shared_media" = "Shared media";
|
||||
"lng_profile_suggest_photo" = "Suggest Profile Photo";
|
||||
"lng_profile_set_photo_for" = "Set Profile Photo";
|
||||
"lng_profile_photo_reset" = "Reset to Original";
|
||||
"lng_profile_set_for_done" = "You will now always see this photo for {user}'s account.";
|
||||
"lng_profile_suggest_sure" = "You can suggest {user} to set this photo for their page.";
|
||||
"lng_profile_suggest_button" = "Suggest";
|
||||
"lng_profile_set_personal_sure" = "Only you will see this photo and it will replace any photo {user} sets for themselves.";
|
||||
"lng_profile_accept_photo_sure" = "{user} suggests you to use this profile photo for your Telegram account.";
|
||||
"lng_profile_set_photo_button" = "Set Photo";
|
||||
"lng_profile_accept_video_sure" = "{user} suggests you to use this profile video for your Telegram account.";
|
||||
"lng_profile_set_video_button" = "Set Video";
|
||||
"lng_profile_changed_photo_title" = "Photo updated";
|
||||
"lng_profile_changed_photo_about" = "You can change it in {link}.";
|
||||
"lng_profile_changed_photo_link" = "Settings";
|
||||
"lng_media_type_photos" = "Photos";
|
||||
"lng_media_type_gifs" = "GIFs";
|
||||
"lng_media_type_videos" = "Videos";
|
||||
@@ -1237,6 +1303,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_manage_peer_reactions_some_title" = "Only allow these reactions";
|
||||
"lng_manage_peer_reactions_available" = "Available reactions";
|
||||
|
||||
"lng_manage_peer_antispam" = "Aggressive Anti-Spam";
|
||||
"lng_manage_peer_antispam_about" = "Telegram will filter more spam but may occasionally affect ordinary messages. You can report False Positives in Recent Actions.";
|
||||
"lng_manage_peer_antispam_not_enough#one" = "Aggressive filtering can be enabled only in groups with more than **{count} member**.";
|
||||
"lng_manage_peer_antispam_not_enough#other" = "Aggressive filtering can be enabled only in groups with more than **{count} members**.";
|
||||
|
||||
"lng_manage_peer_group_type" = "Group type";
|
||||
"lng_manage_peer_channel_type" = "Channel type";
|
||||
"lng_manage_peer_link_type" = "Link type";
|
||||
@@ -1296,6 +1367,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_ttl_edit_about" = "Automatically delete new messages after a certain period of time for you and {user}.";
|
||||
"lng_ttl_edit_about_group" = "Automatically delete new messages sent in this chat after a certain period of time.";
|
||||
"lng_ttl_edit_about_channel" = "Automatically delete new messages sent in this channel after a certain period of time.";
|
||||
"lng_ttl_edit_about2" = "You can also set your default {link} for all chats in Settings.";
|
||||
"lng_ttl_edit_about2_link" = "self-destruct timer";
|
||||
"lng_ttl_edit_save" = "Confirm";
|
||||
"lng_ttl_about_tooltip" = "New messages in this chat will be automatically deleted in {duration}.";
|
||||
"lng_ttl_about_tooltip_channel" = "New messages in this chat will be automatically deleted in {duration}.";
|
||||
@@ -1363,6 +1436,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_create_group_next" = "Next";
|
||||
"lng_create_group_create" = "Create";
|
||||
"lng_create_group_title" = "New Group";
|
||||
"lng_create_group_ttl_about" = "Automatically delete messages in this group for everyone after a period of time.";
|
||||
"lng_create_channel_title" = "New Channel";
|
||||
"lng_create_public_channel_title" = "Public Channel";
|
||||
"lng_create_public_channel_about" = "Anyone can find the channel in search and join";
|
||||
@@ -1385,11 +1459,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_create_channel_link_too_short" = "Sorry, this link is too short";
|
||||
"lng_create_channel_link_bad_symbols" = "Only 0-9, a-z, and underscores allowed.";
|
||||
"lng_create_channel_link_available" = "This link is available";
|
||||
"lng_create_channel_link_pending" = "Checking name...";
|
||||
"lng_create_channel_link_copied" = "Link copied to clipboard";
|
||||
|
||||
"lng_create_group_crop" = "Select an area for group photo";
|
||||
"lng_create_channel_crop" = "Select an area for channel photo";
|
||||
|
||||
"lng_failed_add_participant" = "Could not add user. Please try again later.";
|
||||
"lng_failed_add_not_mutual" = "Sorry, if a person leaves a group, only a mutual contact can bring them back (they need to have your phone number, and you need theirs).";
|
||||
"lng_failed_add_not_mutual_channel" = "Sorry, if a person leaves a channel, only a mutual contact can bring them back (they need to have your phone number, and you need theirs).";
|
||||
@@ -1456,6 +1528,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_action_ttl_changed" = "{from} has set messages to auto-delete in {duration}";
|
||||
"lng_action_ttl_changed_you" = "You set messages to auto-delete in {duration}";
|
||||
"lng_action_ttl_changed_channel" = "New messages will auto-delete in {duration}";
|
||||
"lng_action_ttl_global" = "{from} uses a self-destruct timer for all chats. All new messages in this chat will be automatically deleted after {duration} they've been sent.";
|
||||
"lng_action_ttl_removed" = "{from} has set messages not to auto-delete";
|
||||
"lng_action_ttl_removed_you" = "You disabled the auto-delete timer";
|
||||
"lng_action_ttl_removed_channel" = "New messages will not auto-delete";
|
||||
@@ -1511,12 +1584,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_action_webview_data_done" = "You have just successfully transferred data from the «{text}» button to the bot.";
|
||||
"lng_action_gift_received" = "{user} sent you a gift for {cost}";
|
||||
"lng_action_gift_received_me" = "You sent to {user} a gift for {cost}";
|
||||
"lng_action_suggested_photo_me" = "You suggested {user} to use this profile photo.";
|
||||
"lng_action_suggested_photo" = "{user} suggests you to use this profile photo.";
|
||||
"lng_action_suggested_photo_button" = "View Photo";
|
||||
"lng_action_suggested_video_me" = "You suggested {user} to use this profile video.";
|
||||
"lng_action_suggested_video" = "{user} suggests you to use this profile video.";
|
||||
"lng_action_suggested_video_button" = "View Video";
|
||||
"lng_action_attach_menu_bot_allowed" = "You allowed this bot to message you when you added it in the attachment menu.";
|
||||
"lng_action_topic_created_inside" = "Topic created";
|
||||
"lng_action_topic_closed_inside" = "Topic closed";
|
||||
"lng_action_topic_reopened_inside" = "Topic reopened";
|
||||
"lng_action_topic_hidden_inside" = "Topic hidden";
|
||||
"lng_action_topic_unhidden_inside" = "Topic unhidden";
|
||||
"lng_action_topic_created" = "«{topic}» was created";
|
||||
"lng_action_topic_closed" = "«{topic}» was closed";
|
||||
"lng_action_topic_reopened" = "«{topic}» was reopened";
|
||||
"lng_action_topic_hidden" = "«{topic}» was hidden";
|
||||
"lng_action_topic_unhidden" = "«{topic}» was unhidden";
|
||||
"lng_action_topic_placeholder" = "topic";
|
||||
"lng_action_topic_renamed" = "{from} renamed the {link} to «{title}»";
|
||||
"lng_action_topic_icon_changed" = "{from} changed the {link} icon to {emoji}";
|
||||
@@ -2199,6 +2283,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_context_copy_link" = "Copy Link";
|
||||
"lng_context_copy_message_link" = "Copy Message Link";
|
||||
"lng_context_copy_post_link" = "Copy Post Link";
|
||||
"lng_context_copy_topic_link" = "Copy Topic Link";
|
||||
"lng_context_copy_email" = "Copy Email Address";
|
||||
"lng_context_copy_hashtag" = "Copy Hashtag";
|
||||
"lng_context_copy_mention" = "Copy Username";
|
||||
@@ -2269,6 +2354,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_context_animated_reactions_many#one" = "Reactions contain emoji from **{count} pack**.";
|
||||
"lng_context_animated_reactions_many#other" = "Reactions contain emoji from **{count} packs**.";
|
||||
|
||||
"lng_context_spoiler_effect" = "Hide with Spoiler";
|
||||
"lng_context_disable_spoiler" = "Remove Spoiler";
|
||||
|
||||
"lng_downloads_section" = "Downloads";
|
||||
"lng_downloads_view_in_chat" = "View in chat";
|
||||
"lng_downloads_view_in_section" = "View in downloads";
|
||||
@@ -2282,17 +2370,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_send_image_empty" = "Could not send an empty file: {name}";
|
||||
"lng_send_images_selected#one" = "{count} image selected";
|
||||
"lng_send_images_selected#other" = "{count} images selected";
|
||||
"lng_send_photos#one" = "Send {count} photo";
|
||||
"lng_send_photos#other" = "Send {count} photos";
|
||||
"lng_send_separate_photos" = "Send as separate photos";
|
||||
"lng_send_separate_photos_videos" = "Send as separate media";
|
||||
"lng_send_files_selected#one" = "{count} file selected";
|
||||
"lng_send_files_selected#other" = "{count} files selected";
|
||||
"lng_send_files#one" = "Send {count} file";
|
||||
"lng_send_files#other" = "Send {count} files";
|
||||
"lng_send_grouped" = "Group items";
|
||||
"lng_send_compressed_one" = "Compress the image";
|
||||
"lng_send_compressed" = "Compress images";
|
||||
"lng_send_media_invalid_files" = "Sorry, no valid files found.";
|
||||
"lng_send_image" = "Send an image";
|
||||
"lng_send_file" = "Send a file";
|
||||
"lng_send_video" = "Send a video file";
|
||||
|
||||
"lng_forward_choose" = "Choose recipient...";
|
||||
"lng_forward_cant" = "Sorry, no way to forward here :(";
|
||||
@@ -2411,6 +2497,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_mediaview_group_photo" = "Group Photo";
|
||||
"lng_mediaview_channel_photo" = "Channel Photo";
|
||||
"lng_mediaview_profile_photo" = "Profile Photo";
|
||||
"lng_mediaview_profile_public_photo" = "Public Photo";
|
||||
"lng_mediaview_file_n_of_amount" = "{file} {n} of {amount}";
|
||||
"lng_mediaview_n_of_amount" = "Photo {n} of {amount}";
|
||||
"lng_mediaview_doc_image" = "File";
|
||||
@@ -3059,6 +3146,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_admin_log_participant_joined_by_link_channel" = "{from} joined the channel via {link}";
|
||||
"lng_admin_log_participant_approved_by_link" = "{from} was approved to join the group via {link} by {user}";
|
||||
"lng_admin_log_participant_approved_by_link_channel" = "{from} was approved to join the channel via {link} by {user}";
|
||||
"lng_admin_log_participant_approved_by_request" = "{from} joined to the group via public request, approved by {user}";
|
||||
"lng_admin_log_participant_approved_by_request_channel" = "{from} joined to the channel via public request, approved by {user}";
|
||||
"lng_admin_log_revoke_invite_link" = "{from} revoked invite link {link}";
|
||||
"lng_admin_log_delete_invite_link" = "{from} deleted invite link {link}";
|
||||
"lng_admin_log_participant_left" = "{from} left the group";
|
||||
@@ -3096,6 +3185,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_admin_log_disallowed_unmute_self_channel" = "{from} started muting new live stream members";
|
||||
"lng_admin_log_participant_volume" = "{from} changed voice chat volume for {user} to {percent}";
|
||||
"lng_admin_log_participant_volume_channel" = "{from} changed live stream volume for {user} to {percent}";
|
||||
"lng_admin_log_antispam_enabled" = "{from} enabled aggressive anti-spam";
|
||||
"lng_admin_log_antispam_disabled" = "{from} disabled aggressive anti-spam";
|
||||
"lng_admin_log_user_with_username" = "{name} ({mention})";
|
||||
"lng_admin_log_messages_ttl_set" = "{from} enabled messages auto-delete after {duration}";
|
||||
"lng_admin_log_messages_ttl_changed" = "{from} changed messages auto-delete period from {previous} to {duration}";
|
||||
@@ -3116,6 +3207,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_admin_log_topics_changed" = "{from} changed topic {topic} to {new_topic}";
|
||||
"lng_admin_log_topics_closed" = "{from} closed topic {topic}";
|
||||
"lng_admin_log_topics_reopened" = "{from} reopened topic {topic}";
|
||||
"lng_admin_log_topics_hidden" = "{from} hid topic {topic}";
|
||||
"lng_admin_log_topics_unhidden" = "{from} unhid topic {topic}";
|
||||
"lng_admin_log_topics_deleted" = "{from} deleted topic {topic}";
|
||||
"lng_admin_log_topics_pinned" = "{from} pinned topic {topic}";
|
||||
"lng_admin_log_topics_unpinned" = "{from} unpinned topic {topic}";
|
||||
@@ -3141,6 +3234,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_admin_log_admin_manage_calls_channel" = "Manage live streams";
|
||||
"lng_admin_log_admin_add_admins" = "Add new admins";
|
||||
|
||||
"lng_admin_log_antispam_menu_report" = "Report False Positive";
|
||||
"lng_admin_log_antispam_menu_report_toast" = "You can manage anti-spam settings in {link}.";
|
||||
"lng_admin_log_antispam_menu_report_toast_link" = "Group Info > Administrators";
|
||||
|
||||
"lng_terms_signup" = "By signing up,\nyou agree to the {link}.";
|
||||
"lng_terms_signup_link" = "Terms of Service";
|
||||
"lng_terms_header" = "Terms of Service";
|
||||
|
||||
@@ -8,5 +8,6 @@
|
||||
<file alias="cloud_password/password_input.tgs">../../animations/cloud_password/password_input.tgs</file>
|
||||
<file alias="cloud_password/hint.tgs">../../animations/cloud_password/hint.tgs</file>
|
||||
<file alias="cloud_password/email.tgs">../../animations/cloud_password/email.tgs</file>
|
||||
<file alias="ttl.tgs">../../animations/ttl.tgs</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<file alias="topic_icons/rose.svg">../../art/topic_icons/rose.svg</file>
|
||||
<file alias="topic_icons/red.svg">../../art/topic_icons/red.svg</file>
|
||||
<file alias="topic_icons/gray.svg">../../art/topic_icons/gray.svg</file>
|
||||
<file alias="topic_icons/general.svg">../../art/topic_icons/general.svg</file>
|
||||
</qresource>
|
||||
<qresource prefix="/icons">
|
||||
<file alias="calls/hands.lottie">../../icons/calls/hands.lottie</file>
|
||||
|
||||
@@ -58,15 +58,15 @@ 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#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;
|
||||
inputMediaUploadedPhoto#1e287d04 flags:# spoiler:flags.2?true file:InputFile stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
|
||||
inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
|
||||
inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia;
|
||||
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true force_file:flags.4?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#33473058 flags:# id:InputDocument ttl_seconds:flags.0?int query:flags.1?string = InputMedia;
|
||||
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?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#33473058 flags:# spoiler:flags.2?true id:InputDocument ttl_seconds:flags.0?int query:flags.1?string = InputMedia;
|
||||
inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia;
|
||||
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaDocumentExternal#fb52dc99 flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia;
|
||||
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
|
||||
inputMediaInvoice#8eb5a6d5 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;
|
||||
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
|
||||
@@ -113,7 +113,7 @@ userEmpty#d3bc4b7a id:long = User;
|
||||
user#8f97c628 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector<Username> = User;
|
||||
|
||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
||||
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true personal:flags.2?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
|
||||
|
||||
userStatusEmpty#9d05049 = UserStatus;
|
||||
userStatusOnline#edb93949 expires:int = UserStatus;
|
||||
@@ -129,7 +129,7 @@ channel#83259464 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.
|
||||
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
|
||||
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
|
||||
channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions = ChatFull;
|
||||
channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions = ChatFull;
|
||||
|
||||
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
|
||||
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
|
||||
@@ -146,11 +146,11 @@ message#38116ee0 flags:# out:flags.1?true mentioned:flags.4?true media_unread:fl
|
||||
messageService#2b085862 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction ttl_period:flags.25?int = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaPhoto#695150d7 flags:# spoiler:flags.3?true photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
|
||||
messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia;
|
||||
messageMediaUnsupported#9f84f49e = MessageMedia;
|
||||
messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia;
|
||||
messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true spoiler:flags.4?true 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;
|
||||
@@ -185,7 +185,7 @@ messageActionContactSignUp#f3f25f76 = MessageAction;
|
||||
messageActionGeoProximityReached#98e0d697 from_id:Peer to_id:Peer distance:int = MessageAction;
|
||||
messageActionGroupCall#7a0d7f42 flags:# call:InputGroupCall duration:flags.0?int = MessageAction;
|
||||
messageActionInviteToGroupCall#502f92f7 call:InputGroupCall users:Vector<long> = MessageAction;
|
||||
messageActionSetMessagesTTL#aa1afbfd period:int = MessageAction;
|
||||
messageActionSetMessagesTTL#3c134d7b flags:# period:int auto_setting_from:flags.0?long = MessageAction;
|
||||
messageActionGroupCallScheduled#b3a07661 call:InputGroupCall schedule_date:int = MessageAction;
|
||||
messageActionSetChatTheme#aa786345 emoticon:string = MessageAction;
|
||||
messageActionChatJoinedByRequest#ebbca3cb = MessageAction;
|
||||
@@ -193,9 +193,11 @@ messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction;
|
||||
messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction;
|
||||
messageActionGiftPremium#aba0f5c6 currency:string amount:long months:int = MessageAction;
|
||||
messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction;
|
||||
messageActionTopicEdit#b18a431c flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool = MessageAction;
|
||||
messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction;
|
||||
messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
|
||||
messageActionAttachMenuBotAllowed#e7e75f97 = MessageAction;
|
||||
|
||||
dialog#a8edd0f5 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
|
||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||
|
||||
photoEmpty#2331b22d id:long = Photo;
|
||||
@@ -244,7 +246,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason;
|
||||
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
|
||||
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
|
||||
|
||||
userFull#c4b1fc3f flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true id:long about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> = UserFull;
|
||||
userFull#f8d32aed flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> = UserFull;
|
||||
|
||||
contact#145ade0b user_id:long mutual:Bool = Contact;
|
||||
|
||||
@@ -302,7 +304,6 @@ updateChatUserTyping#83487af0 chat_id:long from_id:Peer action:SendMessageAction
|
||||
updateChatParticipants#7761198 participants:ChatParticipants = Update;
|
||||
updateUserStatus#e5bdf8de user_id:long status:UserStatus = Update;
|
||||
updateUserName#a7848924 user_id:long first_name:string last_name:string usernames:Vector<Username> = Update;
|
||||
updateUserPhoto#f227868c user_id:long date:int photo:UserProfilePhoto previous:Bool = Update;
|
||||
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
|
||||
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
|
||||
updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
|
||||
@@ -403,6 +404,7 @@ updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?tru
|
||||
updateMessageExtendedMedia#5a73a98c peer:Peer msg_id:int extended_media:MessageExtendedMedia = Update;
|
||||
updateChannelPinnedTopic#192efbe3 flags:# pinned:flags.0?true channel_id:long topic_id:int = Update;
|
||||
updateChannelPinnedTopics#fe198602 flags:# channel_id:long order:flags.0?Vector<int> = Update;
|
||||
updateUser#20529438 user_id:long = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
@@ -547,7 +549,7 @@ documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true supports_strea
|
||||
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;
|
||||
documentAttributeCustomEmoji#fd149899 flags:# free:flags.0?true alt:string stickerset:InputStickerSet = DocumentAttribute;
|
||||
documentAttributeCustomEmoji#fd149899 flags:# free:flags.0?true text_color:flags.1?true alt:string stickerset:InputStickerSet = DocumentAttribute;
|
||||
|
||||
messages.stickersNotModified#f1749a22 = messages.Stickers;
|
||||
messages.stickers#30a6ec7e hash:long stickers:Vector<Document> = messages.Stickers;
|
||||
@@ -625,7 +627,7 @@ keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
|
||||
|
||||
replyKeyboardHide#a03e5b85 flags:# selective:flags.2?true = ReplyMarkup;
|
||||
replyKeyboardForceReply#86b40b08 flags:# single_use:flags.1?true selective:flags.2?true placeholder:flags.3?string = ReplyMarkup;
|
||||
replyKeyboardMarkup#85dd99d1 flags:# resize:flags.0?true single_use:flags.1?true selective:flags.2?true rows:Vector<KeyboardButtonRow> placeholder:flags.3?string = ReplyMarkup;
|
||||
replyKeyboardMarkup#85dd99d1 flags:# resize:flags.0?true single_use:flags.1?true selective:flags.2?true persistent:flags.4?true rows:Vector<KeyboardButtonRow> placeholder:flags.3?string = ReplyMarkup;
|
||||
replyInlineMarkup#48a30254 rows:Vector<KeyboardButtonRow> = ReplyMarkup;
|
||||
|
||||
messageEntityUnknown#bb92ba95 offset:int length:int = MessageEntity;
|
||||
@@ -724,6 +726,7 @@ auth.codeTypeSms#72a3158c = auth.CodeType;
|
||||
auth.codeTypeCall#741cd3e3 = auth.CodeType;
|
||||
auth.codeTypeFlashCall#226ccefb = auth.CodeType;
|
||||
auth.codeTypeMissedCall#d61ad6ee = auth.CodeType;
|
||||
auth.codeTypeFragmentSms#6ed998c = auth.CodeType;
|
||||
|
||||
auth.sentCodeTypeApp#3dbb5986 length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeSms#c000bba2 length:int = auth.SentCodeType;
|
||||
@@ -732,6 +735,7 @@ auth.sentCodeTypeFlashCall#ab03c6d9 pattern:string = auth.SentCodeType;
|
||||
auth.sentCodeTypeMissedCall#82006484 prefix:string length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeEmailCode#5a159841 flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true email_pattern:string length:int next_phone_login_date:flags.2?int = auth.SentCodeType;
|
||||
auth.sentCodeTypeSetUpEmailRequired#a5491dea flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true = auth.SentCodeType;
|
||||
auth.sentCodeTypeFragmentSms#d9565c39 url:string length:int = auth.SentCodeType;
|
||||
|
||||
messages.botCallbackAnswer#36585ea4 flags:# alert:flags.1?true has_url:flags.3?true native_ui:flags.4?true message:flags.0?string url:flags.2?string cache_time:int = messages.BotCallbackAnswer;
|
||||
|
||||
@@ -778,6 +782,7 @@ messages.stickerSetInstallResultArchive#35e410a8 sets:Vector<StickerSetCovered>
|
||||
stickerSetCovered#6410a5d2 set:StickerSet cover:Document = StickerSetCovered;
|
||||
stickerSetMultiCovered#3407e51b set:StickerSet covers:Vector<Document> = StickerSetCovered;
|
||||
stickerSetFullCovered#40d13c0e set:StickerSet packs:Vector<StickerPack> keywords:Vector<StickerKeyword> documents:Vector<Document> = StickerSetCovered;
|
||||
stickerSetNoCovered#77b15d1c set:StickerSet = StickerSetCovered;
|
||||
|
||||
maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords;
|
||||
|
||||
@@ -965,6 +970,7 @@ channelAdminLogEventActionCreateTopic#58707d28 topic:ForumTopic = ChannelAdminLo
|
||||
channelAdminLogEventActionEditTopic#f06fe208 prev_topic:ForumTopic new_topic:ForumTopic = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionDeleteTopic#ae168909 topic:ForumTopic = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionPinTopic#5d8d353b flags:# prev_topic:flags.0?ForumTopic new_topic:flags.1?ForumTopic = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionToggleAntiSpam#64f36dfc new_value:Bool = ChannelAdminLogEventAction;
|
||||
|
||||
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||
|
||||
@@ -1376,7 +1382,7 @@ attachMenuBotIconColor#4576f3f0 name:string color:int = AttachMenuBotIconColor;
|
||||
|
||||
attachMenuBotIcon#b2a7386b flags:# name:string icon:Document colors:flags.0?Vector<AttachMenuBotIconColor> = AttachMenuBotIcon;
|
||||
|
||||
attachMenuBot#c8aa2cd2 flags:# inactive:flags.0?true has_settings:flags.1?true bot_id:long short_name:string peer_types:Vector<AttachMenuPeerType> icons:Vector<AttachMenuBotIcon> = AttachMenuBot;
|
||||
attachMenuBot#c8aa2cd2 flags:# inactive:flags.0?true has_settings:flags.1?true request_write_access:flags.2?true bot_id:long short_name:string peer_types:Vector<AttachMenuPeerType> icons:Vector<AttachMenuBotIcon> = AttachMenuBot;
|
||||
|
||||
attachMenuBotsNotModified#f1d88a5c = AttachMenuBots;
|
||||
attachMenuBots#3c4301c0 hash:long bots:Vector<AttachMenuBot> users:Vector<User> = AttachMenuBots;
|
||||
@@ -1467,10 +1473,14 @@ stickerKeyword#fcfeb29c document_id:long keyword:Vector<string> = StickerKeyword
|
||||
username#b4073647 flags:# editable:flags.0?true active:flags.1?true username:string = Username;
|
||||
|
||||
forumTopicDeleted#23f109b id:int = ForumTopic;
|
||||
forumTopic#71701da9 flags:# my:flags.1?true closed:flags.2?true pinned:flags.3?true short:flags.5?true id:int date:int title:string icon_color:int icon_emoji_id:flags.0?long top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int from_id:Peer notify_settings:PeerNotifySettings draft:flags.4?DraftMessage = ForumTopic;
|
||||
forumTopic#71701da9 flags:# my:flags.1?true closed:flags.2?true pinned:flags.3?true short:flags.5?true hidden:flags.6?true id:int date:int title:string icon_color:int icon_emoji_id:flags.0?long top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int from_id:Peer notify_settings:PeerNotifySettings draft:flags.4?DraftMessage = ForumTopic;
|
||||
|
||||
messages.forumTopics#367617d3 flags:# order_by_create_date:flags.0?true count:int topics:Vector<ForumTopic> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int = messages.ForumTopics;
|
||||
|
||||
defaultHistoryTTL#43b46b20 period:int = DefaultHistoryTTL;
|
||||
|
||||
exportedContactToken#41bf109b url:string expires:int = ExportedContactToken;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@@ -1500,6 +1510,7 @@ auth.exportLoginToken#b7e085fe api_id:int api_hash:string except_ids:Vector<long
|
||||
auth.importLoginToken#95ac5ce4 token:bytes = auth.LoginToken;
|
||||
auth.acceptLoginToken#e894ad4d token:bytes = Authorization;
|
||||
auth.checkRecoveryPassword#d36bf79 code:string = Bool;
|
||||
auth.importWebTokenAuthorization#2db873a9 api_id:int api_hash:string web_auth_token:string = auth.Authorization;
|
||||
|
||||
account.registerDevice#ec86017a flags:# no_muted:flags.0?true token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector<long> = Bool;
|
||||
account.unregisterDevice#6a0d3206 token_type:int token:string other_uids:Vector<long> = Bool;
|
||||
@@ -1609,6 +1620,8 @@ contacts.acceptContact#f831a20f id:InputUser = Updates;
|
||||
contacts.getLocated#d348bc44 flags:# background:flags.1?true geo_point:InputGeoPoint self_expires:flags.0?int = Updates;
|
||||
contacts.blockFromReplies#29a8962c flags:# delete_message:flags.0?true delete_history:flags.1?true report_spam:flags.2?true msg_id:int = Updates;
|
||||
contacts.resolvePhone#8af94344 phone:string = contacts.ResolvedPeer;
|
||||
contacts.exportContactToken#f8654027 = ExportedContactToken;
|
||||
contacts.importContactToken#13005788 token:string = User;
|
||||
|
||||
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
||||
messages.getDialogs#a0f4cb4f flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.Dialogs;
|
||||
@@ -1631,7 +1644,7 @@ messages.editChatTitle#73783ffd chat_id:long title:string = Updates;
|
||||
messages.editChatPhoto#35ddd674 chat_id:long photo:InputChatPhoto = Updates;
|
||||
messages.addChatUser#f24753e3 chat_id:long user_id:InputUser fwd_limit:int = Updates;
|
||||
messages.deleteChatUser#a2185cab flags:# revoke_history:flags.0?true chat_id:long user_id:InputUser = Updates;
|
||||
messages.createChat#9cb126e users:Vector<InputUser> title:string = Updates;
|
||||
messages.createChat#34a818 flags:# users:Vector<InputUser> title:string ttl_period:flags.0?int = 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;
|
||||
@@ -1771,7 +1784,7 @@ messages.readReactions#54aa7f8e flags:# peer:InputPeer top_msg_id:flags.0?int =
|
||||
messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = messages.Messages;
|
||||
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
|
||||
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
|
||||
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
|
||||
messages.toggleBotInAttachMenu#69f59d69 flags:# write_allowed:flags.0?true bot:InputUser enabled:Bool = Bool;
|
||||
messages.requestWebView#178b480b flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = WebViewResult;
|
||||
messages.prolongWebView#7ff34309 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = Bool;
|
||||
messages.requestSimpleWebView#299bec8e flags:# bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult;
|
||||
@@ -1787,15 +1800,18 @@ messages.getTopReactions#bb8125ba limit:int hash:long = messages.Reactions;
|
||||
messages.getRecentReactions#39461db2 limit:int hash:long = messages.Reactions;
|
||||
messages.clearRecentReactions#9dfeefb4 = Bool;
|
||||
messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = Updates;
|
||||
messages.setDefaultHistoryTTL#9eb51445 period:int = Bool;
|
||||
messages.getDefaultHistoryTTL#658b7188 = DefaultHistoryTTL;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
|
||||
|
||||
photos.updateProfilePhoto#72d4742c id:InputPhoto = photos.Photo;
|
||||
photos.uploadProfilePhoto#89f30f69 flags:# file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double = photos.Photo;
|
||||
photos.updateProfilePhoto#1c3d5956 flags:# fallback:flags.0?true id:InputPhoto = photos.Photo;
|
||||
photos.uploadProfilePhoto#89f30f69 flags:# fallback:flags.3?true file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double = photos.Photo;
|
||||
photos.deletePhotos#87cf7f2f id:Vector<InputPhoto> = Vector<long>;
|
||||
photos.getUserPhotos#91cd32a8 user_id:InputUser offset:int max_id:long limit:int = photos.Photos;
|
||||
photos.uploadContactProfilePhoto#b91a83bf flags:# suggest:flags.3?true save:flags.4?true user_id:InputUser file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double = photos.Photo;
|
||||
|
||||
upload.saveFilePart#b304a621 file_id:long file_part:int bytes:bytes = Bool;
|
||||
upload.getFile#be5335be flags:# precise:flags.0?true cdn_supported:flags.1?true location:InputFileLocation offset:long limit:int = upload.File;
|
||||
@@ -1838,7 +1854,7 @@ channels.getParticipants#77ced9d0 channel:InputChannel filter:ChannelParticipant
|
||||
channels.getParticipant#a0ab6cc6 channel:InputChannel participant:InputPeer = channels.ChannelParticipant;
|
||||
channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;
|
||||
channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull;
|
||||
channels.createChannel#3d5fb10f flags:# broadcast:flags.0?true megagroup:flags.1?true for_import:flags.3?true title:string about:string geo_point:flags.2?InputGeoPoint address:flags.2?string = Updates;
|
||||
channels.createChannel#91006707 flags:# broadcast:flags.0?true megagroup:flags.1?true for_import:flags.3?true title:string about:string geo_point:flags.2?InputGeoPoint address:flags.2?string ttl_period:flags.4?int = Updates;
|
||||
channels.editAdmin#d33c8902 channel:InputChannel user_id:InputUser admin_rights:ChatAdminRights rank:string = Updates;
|
||||
channels.editTitle#566decd0 channel:InputChannel title:string = Updates;
|
||||
channels.editPhoto#f12e57c9 channel:InputChannel photo:InputChatPhoto = Updates;
|
||||
@@ -1878,10 +1894,13 @@ channels.toggleForum#a4298b29 channel:InputChannel enabled:Bool = Updates;
|
||||
channels.createForumTopic#f40c0224 flags:# channel:InputChannel title:string icon_color:flags.0?int icon_emoji_id:flags.3?long random_id:long send_as:flags.2?InputPeer = Updates;
|
||||
channels.getForumTopics#de560d1 flags:# channel:InputChannel q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics;
|
||||
channels.getForumTopicsByID#b0831eb9 channel:InputChannel topics:Vector<int> = messages.ForumTopics;
|
||||
channels.editForumTopic#6c883e2d flags:# channel:InputChannel topic_id:int title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool = Updates;
|
||||
channels.editForumTopic#f4dfa185 flags:# channel:InputChannel topic_id:int title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = Updates;
|
||||
channels.updatePinnedForumTopic#6c2d9026 channel:InputChannel topic_id:int pinned:Bool = Updates;
|
||||
channels.deleteTopicHistory#34435f2d channel:InputChannel top_msg_id:int = messages.AffectedHistory;
|
||||
channels.reorderPinnedForumTopics#2950a18f flags:# force:flags.0?true channel:InputChannel order:Vector<int> = Updates;
|
||||
channels.toggleAntiSpam#68f3e4eb channel:InputChannel enabled:Bool = Updates;
|
||||
channels.reportAntiSpamFalsePositive#a850a693 channel:InputChannel msg_id:int = Bool;
|
||||
channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates;
|
||||
|
||||
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
||||
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
||||
@@ -1960,4 +1979,4 @@ stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel
|
||||
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
|
||||
|
||||
// LAYER 149
|
||||
// LAYER 151
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="4.3.4.0" />
|
||||
Version="4.5.3.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||
|
||||
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,3,4,0
|
||||
PRODUCTVERSION 4,3,4,0
|
||||
FILEVERSION 4,5,3,0
|
||||
PRODUCTVERSION 4,5,3,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -62,10 +62,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||
VALUE "FileDescription", "Telegram Desktop"
|
||||
VALUE "FileVersion", "4.3.4.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2022"
|
||||
VALUE "FileVersion", "4.5.3.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2023"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "4.3.4.0"
|
||||
VALUE "ProductVersion", "4.5.3.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,3,4,0
|
||||
PRODUCTVERSION 4,3,4,0
|
||||
FILEVERSION 4,5,3,0
|
||||
PRODUCTVERSION 4,5,3,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -53,10 +53,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||
VALUE "FileDescription", "Telegram Desktop Updater"
|
||||
VALUE "FileVersion", "4.3.4.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2022"
|
||||
VALUE "FileVersion", "4.5.3.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2023"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "4.3.4.0"
|
||||
VALUE "ProductVersion", "4.5.3.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -34,8 +34,8 @@ Authorizations::Entry ParseEntry(const MTPDauthorization &data) {
|
||||
|| isTest;
|
||||
|
||||
const auto appName = isDesktop
|
||||
? QString("Telegram Desktop%1").arg(isTest ? " (GitHub)" : QString())
|
||||
: qs(data.vapp_name());// +qsl(" for ") + qs(d.vplatform());
|
||||
? u"Telegram Desktop%1"_q.arg(isTest ? " (GitHub)" : QString())
|
||||
: qs(data.vapp_name());// + u" for "_q + qs(d.vplatform());
|
||||
const auto appVer = [&] {
|
||||
const auto version = qs(data.vapp_version());
|
||||
if (isDesktop) {
|
||||
@@ -79,12 +79,16 @@ Authorizations::Entry ParseEntry(const MTPDauthorization &data) {
|
||||
const auto nowDate = now.date();
|
||||
const auto lastDate = lastTime.date();
|
||||
if (lastDate == nowDate) {
|
||||
result.active = QLocale().toString(lastTime, cTimeFormat());
|
||||
result.active = QLocale().toString(
|
||||
lastTime.time(),
|
||||
QLocale::ShortFormat);
|
||||
} else if (lastDate.year() == nowDate.year()
|
||||
&& lastDate.weekNumber() == nowDate.weekNumber()) {
|
||||
result.active = langDayOfWeek(lastDate);
|
||||
} else {
|
||||
result.active = QLocale().toString(lastDate, cDateFormat());
|
||||
result.active = QLocale().toString(
|
||||
lastDate,
|
||||
QLocale::ShortFormat);
|
||||
}
|
||||
}
|
||||
result.location = country;
|
||||
|
||||
@@ -110,7 +110,9 @@ void SendBotCallbackData(
|
||||
const auto showAlert = data.is_alert();
|
||||
|
||||
if (!message.isEmpty()) {
|
||||
if (showAlert) {
|
||||
if (!show->valid()) {
|
||||
return;
|
||||
} else if (showAlert) {
|
||||
show->showBox(Ui::MakeInformBox(message));
|
||||
} else {
|
||||
if (withPassword) {
|
||||
@@ -426,10 +428,19 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
|
||||
return false;
|
||||
}();
|
||||
if (!fastSwitchDone) {
|
||||
controller->content()->inlineSwitchLayer('@'
|
||||
const auto botAndQuery = '@'
|
||||
+ bot->username()
|
||||
+ ' '
|
||||
+ QString::fromUtf8(button->data));
|
||||
+ QString::fromUtf8(button->data);
|
||||
const auto chosen = [=](not_null<Data::Thread*> thread) {
|
||||
return controller->content()->inlineSwitchChosen(
|
||||
thread,
|
||||
botAndQuery);
|
||||
};
|
||||
Window::ShowChooseRecipientBox(
|
||||
controller,
|
||||
chosen,
|
||||
tr::lng_inline_switch_choose());
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -81,6 +81,7 @@ void SubmitChatInvite(
|
||||
} else if (type == u"CHANNELS_TOO_MUCH"_q) {
|
||||
strongController->show(
|
||||
Box(ChannelsLimitBox, &strongController->session()));
|
||||
return;
|
||||
}
|
||||
|
||||
strongController->hideLayer();
|
||||
@@ -116,14 +117,11 @@ void CheckChatInvite(
|
||||
}
|
||||
Core::App().hideMediaView();
|
||||
const auto show = [&](not_null<PeerData*> chat) {
|
||||
const auto way = Window::SectionShow::Way::Forward;
|
||||
if (const auto forum = chat->forum()) {
|
||||
strong->openForum(
|
||||
forum->channel(),
|
||||
Window::SectionShow::Way::Forward);
|
||||
strong->showForum(forum, way);
|
||||
} else {
|
||||
strong->showPeerHistory(
|
||||
chat,
|
||||
Window::SectionShow::Way::Forward);
|
||||
strong->showPeerHistory(chat, way);
|
||||
}
|
||||
};
|
||||
result.match([=](const MTPDchatInvite &data) {
|
||||
@@ -174,6 +172,11 @@ void CheckChatInvite(
|
||||
|
||||
} // namespace Api
|
||||
|
||||
struct ConfirmInviteBox::Participant {
|
||||
not_null<UserData*> user;
|
||||
Ui::PeerUserpicView userpic;
|
||||
};
|
||||
|
||||
ConfirmInviteBox::ConfirmInviteBox(
|
||||
QWidget*,
|
||||
not_null<Main::Session*> session,
|
||||
@@ -244,7 +247,7 @@ ConfirmInviteBox::ConfirmInviteBox(
|
||||
}
|
||||
} else {
|
||||
_photoEmpty = std::make_unique<Ui::EmptyUserpic>(
|
||||
Data::PeerUserpicColor(0),
|
||||
Ui::EmptyUserpic::UserpicColor(0),
|
||||
invite.title);
|
||||
}
|
||||
}
|
||||
@@ -359,7 +362,7 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) {
|
||||
{ .options = Images::Option::RoundCircle }));
|
||||
}
|
||||
} else if (_photoEmpty) {
|
||||
_photoEmpty->paint(
|
||||
_photoEmpty->paintCircle(
|
||||
p,
|
||||
(width() - st::confirmInvitePhotoSize) / 2,
|
||||
st::confirmInvitePhotoTop,
|
||||
|
||||
@@ -21,7 +21,6 @@ class SessionController;
|
||||
} // namespace Window
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
class PhotoMedia;
|
||||
} // namespace Data
|
||||
|
||||
@@ -55,10 +54,7 @@ protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
private:
|
||||
struct Participant {
|
||||
not_null<UserData*> user;
|
||||
std::shared_ptr<Data::CloudImageView> userpic;
|
||||
};
|
||||
struct Participant;
|
||||
struct ChatInvite {
|
||||
QString title;
|
||||
QString about;
|
||||
|
||||
@@ -365,6 +365,7 @@ void ChatParticipants::requestForAdd(
|
||||
|
||||
void ChatParticipants::requestLast(not_null<ChannelData*> channel) {
|
||||
if (!channel->isMegagroup()
|
||||
|| !channel->canViewMembers()
|
||||
|| _participantsRequests.contains(channel)) {
|
||||
return;
|
||||
}
|
||||
@@ -532,6 +533,7 @@ ChatParticipants::Parsed ChatParticipants::ParseRecent(
|
||||
const TLMembers &data) {
|
||||
const auto result = Parse(channel, data);
|
||||
const auto applyLast = channel->isMegagroup()
|
||||
&& channel->canViewMembers()
|
||||
&& (channel->mgInfo->lastParticipants.size() <= result.list.size());
|
||||
if (applyLast) {
|
||||
ApplyLastList(channel, result.availableCount, result.list);
|
||||
@@ -598,7 +600,7 @@ void ChatParticipants::requestSelf(not_null<ChannelData*> channel) {
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_selfParticipantRequests.erase(channel);
|
||||
if (error.type() == qstr("CHANNEL_PRIVATE")) {
|
||||
if (error.type() == u"CHANNEL_PRIVATE"_q) {
|
||||
channel->privateErrorReceived();
|
||||
}
|
||||
finalize();
|
||||
|
||||
@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_session.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/boxes/confirm_phone_box.h"
|
||||
@@ -45,6 +46,8 @@ void ConfirmPhone::resolve(
|
||||
return 0;
|
||||
}, [&](const MTPDauth_sentCodeTypeSms &data) {
|
||||
return data.vlength().v;
|
||||
}, [&](const MTPDauth_sentCodeTypeFragmentSms &data) {
|
||||
return data.vlength().v;
|
||||
}, [&](const MTPDauth_sentCodeTypeCall &data) {
|
||||
return data.vlength().v;
|
||||
}, [&](const MTPDauth_sentCodeTypeFlashCall &) {
|
||||
@@ -56,6 +59,10 @@ void ConfirmPhone::resolve(
|
||||
}, [&](const MTPDauth_sentCodeTypeSetUpEmailRequired &) {
|
||||
return bad("SetUpEmailRequired");
|
||||
});
|
||||
const auto fragmentUrl = data.vtype().match([](
|
||||
const MTPDauth_sentCodeTypeFragmentSms &data) {
|
||||
return qs(data.vurl());
|
||||
}, [](const auto &) { return QString(); });
|
||||
const auto phoneHash = qs(data.vphone_code_hash());
|
||||
const auto timeout = [&]() -> std::optional<int> {
|
||||
if (const auto nextType = data.vnext_type()) {
|
||||
@@ -68,8 +75,15 @@ void ConfirmPhone::resolve(
|
||||
auto box = Box<Ui::ConfirmPhoneBox>(
|
||||
phone,
|
||||
sentCodeLength,
|
||||
fragmentUrl,
|
||||
timeout);
|
||||
const auto boxWeak = Ui::MakeWeak(box.data());
|
||||
using LoginCode = rpl::event_stream<QString>;
|
||||
const auto codeHandles = box->lifetime().make_state<LoginCode>();
|
||||
controller->session().account().setHandleLoginCode([=](
|
||||
const QString &code) {
|
||||
codeHandles->fire_copy(code);
|
||||
});
|
||||
box->resendRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
_api.request(MTPauth_ResendCode(
|
||||
@@ -81,7 +95,9 @@ void ConfirmPhone::resolve(
|
||||
}
|
||||
}).send();
|
||||
}, box->lifetime());
|
||||
box->checkRequests(
|
||||
rpl::merge(
|
||||
codeHandles->events(),
|
||||
box->checkRequests()
|
||||
) | rpl::start_with_next([=](const QString &code) {
|
||||
if (_checkRequestId) {
|
||||
return;
|
||||
@@ -113,6 +129,10 @@ void ConfirmPhone::resolve(
|
||||
boxWeak->showServerError(errorText);
|
||||
}).handleFloodErrors().send();
|
||||
}, box->lifetime());
|
||||
box->boxClosing(
|
||||
) | rpl::start_with_next([=] {
|
||||
controller->session().account().setHandleLoginCode(nullptr);
|
||||
}, box->lifetime());
|
||||
|
||||
controller->show(std::move(box), Ui::LayerOption::CloseOther);
|
||||
});
|
||||
|
||||
@@ -206,7 +206,7 @@ void EditMessageWithUploadedPhoto(
|
||||
EditMessageWithUploadedMedia(
|
||||
item,
|
||||
options,
|
||||
PrepareUploadedPhoto(std::move(info)));
|
||||
PrepareUploadedPhoto(item, std::move(info)));
|
||||
}
|
||||
|
||||
mtpRequestId EditCaption(
|
||||
|
||||
@@ -23,7 +23,7 @@ MTPVector<MTPDocumentAttribute> ComposeSendingDocumentAttributes(
|
||||
auto attributes = QVector<MTPDocumentAttribute>(1, filenameAttribute);
|
||||
if (dimensions.width() > 0 && dimensions.height() > 0) {
|
||||
const auto duration = document->getDuration();
|
||||
if (duration >= 0 && !document->hasMimeType(qstr("image/gif"))) {
|
||||
if (duration >= 0 && !document->hasMimeType(u"image/gif"_q)) {
|
||||
auto flags = MTPDdocumentAttributeVideo::Flags(0);
|
||||
using VideoFlag = MTPDdocumentAttributeVideo::Flag;
|
||||
if (document->isVideoMessage()) {
|
||||
@@ -75,10 +75,14 @@ MTPVector<MTPDocumentAttribute> ComposeSendingDocumentAttributes(
|
||||
|
||||
} // namespace
|
||||
|
||||
MTPInputMedia PrepareUploadedPhoto(RemoteFileInfo info) {
|
||||
const auto flags = info.attachedStickers.empty()
|
||||
? MTPDinputMediaUploadedPhoto::Flags(0)
|
||||
: MTPDinputMediaUploadedPhoto::Flag::f_stickers;
|
||||
MTPInputMedia PrepareUploadedPhoto(
|
||||
not_null<HistoryItem*> item,
|
||||
RemoteFileInfo info) {
|
||||
using Flag = MTPDinputMediaUploadedPhoto::Flag;
|
||||
const auto spoiler = item->media()
|
||||
&& item->media()->hasSpoiler();
|
||||
const auto flags = (spoiler ? Flag::f_spoiler : Flag())
|
||||
| (info.attachedStickers.empty() ? Flag() : Flag::f_stickers);
|
||||
return MTP_inputMediaUploadedPhoto(
|
||||
MTP_flags(flags),
|
||||
info.file,
|
||||
@@ -93,12 +97,13 @@ MTPInputMedia PrepareUploadedDocument(
|
||||
if (!item || !item->media() || !item->media()->document()) {
|
||||
return MTP_inputMediaEmpty();
|
||||
}
|
||||
const auto emptyFlag = MTPDinputMediaUploadedDocument::Flags(0);
|
||||
using DocFlags = MTPDinputMediaUploadedDocument::Flag;
|
||||
const auto flags = emptyFlag
|
||||
| (info.thumb ? DocFlags::f_thumb : emptyFlag)
|
||||
| (item->groupId() ? DocFlags::f_nosound_video : emptyFlag)
|
||||
| (info.attachedStickers.empty() ? DocFlags::f_stickers : emptyFlag);
|
||||
using Flag = MTPDinputMediaUploadedDocument::Flag;
|
||||
const auto spoiler = item->media()
|
||||
&& item->media()->hasSpoiler();
|
||||
const auto flags = (spoiler ? Flag::f_spoiler : Flag())
|
||||
| (info.thumb ? Flag::f_thumb : Flag())
|
||||
| (item->groupId() ? Flag::f_nosound_video : Flag())
|
||||
| (info.attachedStickers.empty() ? Flag::f_stickers : Flag());
|
||||
const auto document = item->media()->document();
|
||||
return MTP_inputMediaUploadedDocument(
|
||||
MTP_flags(flags),
|
||||
|
||||
@@ -13,7 +13,9 @@ namespace Api {
|
||||
|
||||
struct RemoteFileInfo;
|
||||
|
||||
MTPInputMedia PrepareUploadedPhoto(RemoteFileInfo info);
|
||||
MTPInputMedia PrepareUploadedPhoto(
|
||||
not_null<HistoryItem*> item,
|
||||
RemoteFileInfo info);
|
||||
|
||||
MTPInputMedia PrepareUploadedDocument(
|
||||
not_null<HistoryItem*> item,
|
||||
|
||||
@@ -13,10 +13,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "base/unixtime.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_user_photos.h"
|
||||
#include "history/history.h"
|
||||
#include "main/main_session.h"
|
||||
#include "storage/file_upload.h"
|
||||
@@ -112,7 +114,54 @@ PeerPhoto::PeerPhoto(not_null<ApiWrap*> api)
|
||||
});
|
||||
}
|
||||
|
||||
void PeerPhoto::upload(not_null<PeerData*> peer, QImage &&image) {
|
||||
void PeerPhoto::upload(
|
||||
not_null<PeerData*> peer,
|
||||
QImage &&image,
|
||||
Fn<void()> done) {
|
||||
upload(peer, std::move(image), UploadType::Default, std::move(done));
|
||||
}
|
||||
|
||||
void PeerPhoto::uploadFallback(not_null<PeerData*> peer, QImage &&image) {
|
||||
upload(peer, std::move(image), UploadType::Fallback, nullptr);
|
||||
}
|
||||
|
||||
void PeerPhoto::updateSelf(
|
||||
not_null<PhotoData*> photo,
|
||||
Data::FileOrigin origin,
|
||||
Fn<void()> done) {
|
||||
const auto send = [=](auto resend) -> void {
|
||||
const auto usedFileReference = photo->fileReference();
|
||||
_api.request(MTPphotos_UpdateProfilePhoto(
|
||||
MTP_flags(0),
|
||||
photo->mtpInput()
|
||||
)).done([=](const MTPphotos_Photo &result) {
|
||||
result.match([&](const MTPDphotos_photo &data) {
|
||||
_session->data().processPhoto(data.vphoto());
|
||||
_session->data().processUsers(data.vusers());
|
||||
});
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (error.code() == 400
|
||||
&& error.type().startsWith(u"FILE_REFERENCE_"_q)) {
|
||||
photo->session().api().refreshFileReference(origin, [=](
|
||||
const auto &) {
|
||||
if (photo->fileReference() != usedFileReference) {
|
||||
resend(resend);
|
||||
}
|
||||
});
|
||||
}
|
||||
}).send();
|
||||
};
|
||||
send(send);
|
||||
}
|
||||
|
||||
void PeerPhoto::upload(
|
||||
not_null<PeerData*> peer,
|
||||
QImage &&image,
|
||||
UploadType type,
|
||||
Fn<void()> done) {
|
||||
peer = peer->migrateToOrMe();
|
||||
const auto ready = PreparePeerPhoto(
|
||||
_api.instance().mainDcId(),
|
||||
@@ -125,19 +174,26 @@ void PeerPhoto::upload(not_null<PeerData*> peer, QImage &&image) {
|
||||
const auto already = ranges::find(
|
||||
_uploads,
|
||||
peer,
|
||||
[](const auto &pair) { return pair.second; });
|
||||
[](const auto &pair) { return pair.second.peer; });
|
||||
if (already != end(_uploads)) {
|
||||
_session->uploader().cancel(already->first);
|
||||
_uploads.erase(already);
|
||||
}
|
||||
_uploads.emplace(fakeId, peer);
|
||||
_uploads.emplace(
|
||||
fakeId,
|
||||
UploadValue{ peer, type, std::move(done) });
|
||||
_session->uploader().uploadMedia(fakeId, ready);
|
||||
}
|
||||
|
||||
void PeerPhoto::suggest(not_null<PeerData*> peer, QImage &&image) {
|
||||
upload(peer, std::move(image), UploadType::Suggestion, nullptr);
|
||||
}
|
||||
|
||||
void PeerPhoto::clear(not_null<PhotoData*> photo) {
|
||||
const auto self = _session->user();
|
||||
if (self->userpicPhotoId() == photo->id) {
|
||||
_api.request(MTPphotos_UpdateProfilePhoto(
|
||||
MTP_flags(0),
|
||||
MTP_inputPhotoEmpty()
|
||||
)).done([=](const MTPphotos_Photo &result) {
|
||||
self->setPhoto(MTP_userProfilePhotoEmpty());
|
||||
@@ -158,12 +214,44 @@ void PeerPhoto::clear(not_null<PhotoData*> photo) {
|
||||
)).done(applier).send();
|
||||
}
|
||||
} else {
|
||||
_api.request(MTPphotos_DeletePhotos(
|
||||
MTP_vector<MTPInputPhoto>(1, photo->mtpInput())
|
||||
)).send();
|
||||
const auto fallbackPhotoId = SyncUserFallbackPhotoViewer(self);
|
||||
if (fallbackPhotoId && (*fallbackPhotoId) == photo->id) {
|
||||
_api.request(MTPphotos_UpdateProfilePhoto(
|
||||
MTP_flags(MTPphotos_UpdateProfilePhoto::Flag::f_fallback),
|
||||
MTP_inputPhotoEmpty()
|
||||
)).send();
|
||||
_session->storage().add(Storage::UserPhotosSetBack(
|
||||
peerToUser(self->id),
|
||||
PhotoId()));
|
||||
} else {
|
||||
_api.request(MTPphotos_DeletePhotos(
|
||||
MTP_vector<MTPInputPhoto>(1, photo->mtpInput())
|
||||
)).send();
|
||||
_session->storage().remove(Storage::UserPhotosRemoveOne(
|
||||
peerToUser(self->id),
|
||||
photo->id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeerPhoto::clearPersonal(not_null<UserData*> user) {
|
||||
_api.request(MTPphotos_UploadContactProfilePhoto(
|
||||
MTP_flags(MTPphotos_UploadContactProfilePhoto::Flag::f_save),
|
||||
user->inputUser,
|
||||
MTPInputFile(),
|
||||
MTPInputFile(), // video
|
||||
MTPdouble() // video_start_ts
|
||||
)).done([=](const MTPphotos_Photo &result) {
|
||||
result.match([&](const MTPDphotos_photo &data) {
|
||||
_session->data().processPhoto(data.vphoto());
|
||||
_session->data().processUsers(data.vusers());
|
||||
});
|
||||
}).send();
|
||||
|
||||
if (!user->userpicPhotoUnknown() && user->hasPersonalPhoto()) {
|
||||
_session->storage().remove(Storage::UserPhotosRemoveOne(
|
||||
peerToUser(self->id),
|
||||
photo->id));
|
||||
peerToUser(user->id),
|
||||
user->userpicPhotoId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +261,7 @@ void PeerPhoto::set(not_null<PeerData*> peer, not_null<PhotoData*> photo) {
|
||||
}
|
||||
if (peer == _session->user()) {
|
||||
_api.request(MTPphotos_UpdateProfilePhoto(
|
||||
MTP_flags(0),
|
||||
photo->mtpInput()
|
||||
)).done([=](const MTPphotos_Photo &result) {
|
||||
result.match([&](const MTPDphotos_photo &data) {
|
||||
@@ -199,25 +288,40 @@ void PeerPhoto::set(not_null<PeerData*> peer, not_null<PhotoData*> photo) {
|
||||
}
|
||||
|
||||
void PeerPhoto::ready(const FullMsgId &msgId, const MTPInputFile &file) {
|
||||
const auto maybePeer = _uploads.take(msgId);
|
||||
if (!maybePeer) {
|
||||
const auto maybeUploadValue = _uploads.take(msgId);
|
||||
if (!maybeUploadValue) {
|
||||
return;
|
||||
}
|
||||
const auto peer = *maybePeer;
|
||||
const auto peer = maybeUploadValue->peer;
|
||||
const auto type = maybeUploadValue->type;
|
||||
const auto done = maybeUploadValue->done;
|
||||
const auto applier = [=](const MTPUpdates &result) {
|
||||
_session->updates().applyUpdates(result);
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
};
|
||||
if (peer->isSelf()) {
|
||||
_api.request(MTPphotos_UploadProfilePhoto(
|
||||
MTP_flags(MTPphotos_UploadProfilePhoto::Flag::f_file),
|
||||
MTP_flags(MTPphotos_UploadProfilePhoto::Flag::f_file
|
||||
| ((type == UploadType::Fallback)
|
||||
? MTPphotos_UploadProfilePhoto::Flag::f_fallback
|
||||
: MTPphotos_UploadProfilePhoto::Flags(0))),
|
||||
file,
|
||||
MTPInputFile(), // video
|
||||
MTPdouble() // video_start_ts
|
||||
)).done([=](const MTPphotos_Photo &result) {
|
||||
result.match([&](const MTPDphotos_photo &data) {
|
||||
_session->data().processPhoto(data.vphoto());
|
||||
_session->data().processUsers(data.vusers());
|
||||
});
|
||||
const auto photoId = _session->data().processPhoto(
|
||||
result.data().vphoto())->id;
|
||||
_session->data().processUsers(result.data().vusers());
|
||||
if (type == UploadType::Fallback) {
|
||||
_session->storage().add(Storage::UserPhotosSetBack(
|
||||
peerToUser(peer->id),
|
||||
photoId));
|
||||
}
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
}).send();
|
||||
} else if (const auto chat = peer->asChat()) {
|
||||
const auto history = _session->data().history(chat);
|
||||
@@ -239,6 +343,29 @@ void PeerPhoto::ready(const FullMsgId &msgId, const MTPInputFile &file) {
|
||||
MTPInputFile(), // video
|
||||
MTPdouble()) // video_start_ts
|
||||
)).done(applier).afterRequest(history->sendRequestId).send();
|
||||
} else if (const auto user = peer->asUser()) {
|
||||
using Flag = MTPphotos_UploadContactProfilePhoto::Flag;
|
||||
_api.request(MTPphotos_UploadContactProfilePhoto(
|
||||
MTP_flags(Flag::f_file
|
||||
| ((type == UploadType::Suggestion)
|
||||
? Flag::f_suggest
|
||||
: Flag::f_save)),
|
||||
user->inputUser,
|
||||
file,
|
||||
MTPInputFile(), // video
|
||||
MTPdouble() // video_start_ts
|
||||
)).done([=](const MTPphotos_Photo &result) {
|
||||
result.match([&](const MTPDphotos_photo &data) {
|
||||
_session->data().processPhoto(data.vphoto());
|
||||
_session->data().processUsers(data.vusers());
|
||||
});
|
||||
if (type != UploadType::Suggestion) {
|
||||
user->updateFullForced();
|
||||
}
|
||||
if (done) {
|
||||
done();
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,26 +384,34 @@ void PeerPhoto::requestUserPhotos(
|
||||
)).done([this, user](const MTPphotos_Photos &result) {
|
||||
_userPhotosRequests.remove(user);
|
||||
|
||||
const auto fullCount = result.match([](const MTPDphotos_photos &d) {
|
||||
auto fullCount = result.match([](const MTPDphotos_photos &d) {
|
||||
return int(d.vphotos().v.size());
|
||||
}, [](const MTPDphotos_photosSlice &d) {
|
||||
return d.vcount().v;
|
||||
});
|
||||
|
||||
auto &owner = _session->data();
|
||||
auto photoIds = result.match([&](const auto &data) {
|
||||
auto &owner = _session->data();
|
||||
owner.processUsers(data.vusers());
|
||||
|
||||
auto photoIds = std::vector<PhotoId>();
|
||||
photoIds.reserve(data.vphotos().v.size());
|
||||
|
||||
for (const auto &photo : data.vphotos().v) {
|
||||
if (const auto photoData = owner.processPhoto(photo)) {
|
||||
photoIds.push_back(photoData->id);
|
||||
for (const auto &single : data.vphotos().v) {
|
||||
const auto photo = owner.processPhoto(single);
|
||||
if (!photo->isNull()) {
|
||||
photoIds.push_back(photo->id);
|
||||
}
|
||||
}
|
||||
return photoIds;
|
||||
});
|
||||
if (!user->userpicPhotoUnknown() && user->hasPersonalPhoto()) {
|
||||
const auto photo = owner.photo(user->userpicPhotoId());
|
||||
if (!photo->isNull()) {
|
||||
++fullCount;
|
||||
photoIds.insert(begin(photoIds), photo->id);
|
||||
}
|
||||
}
|
||||
|
||||
_session->storage().add(Storage::UserPhotosAddSlice(
|
||||
peerToUser(user->id),
|
||||
@@ -289,4 +424,21 @@ void PeerPhoto::requestUserPhotos(
|
||||
_userPhotosRequests.emplace(user, requestId);
|
||||
}
|
||||
|
||||
// Non-personal photo in case a personal photo is set.
|
||||
void PeerPhoto::registerNonPersonalPhoto(
|
||||
not_null<UserData*> user,
|
||||
not_null<PhotoData*> photo) {
|
||||
_nonPersonalPhotos.emplace_or_assign(user, photo);
|
||||
}
|
||||
|
||||
void PeerPhoto::unregisterNonPersonalPhoto(not_null<UserData*> user) {
|
||||
_nonPersonalPhotos.erase(user);
|
||||
}
|
||||
|
||||
PhotoData *PeerPhoto::nonPersonalPhoto(
|
||||
not_null<UserData*> user) const {
|
||||
const auto i = _nonPersonalPhotos.find(user);
|
||||
return (i != end(_nonPersonalPhotos)) ? i->second.get() : nullptr;
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -13,6 +13,10 @@ class ApiWrap;
|
||||
class PeerData;
|
||||
class UserData;
|
||||
|
||||
namespace Data {
|
||||
struct FileOrigin;
|
||||
} // namespace Data
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
@@ -24,22 +28,61 @@ public:
|
||||
using UserPhotoId = PhotoId;
|
||||
explicit PeerPhoto(not_null<ApiWrap*> api);
|
||||
|
||||
void upload(not_null<PeerData*> peer, QImage &&image);
|
||||
void upload(
|
||||
not_null<PeerData*> peer,
|
||||
QImage &&image,
|
||||
Fn<void()> done = nullptr);
|
||||
void uploadFallback(not_null<PeerData*> peer, QImage &&image);
|
||||
void updateSelf(
|
||||
not_null<PhotoData*> photo,
|
||||
Data::FileOrigin origin,
|
||||
Fn<void()> done = nullptr);
|
||||
void suggest(not_null<PeerData*> peer, QImage &&image);
|
||||
void clear(not_null<PhotoData*> photo);
|
||||
void clearPersonal(not_null<UserData*> user);
|
||||
void set(not_null<PeerData*> peer, not_null<PhotoData*> photo);
|
||||
|
||||
void requestUserPhotos(not_null<UserData*> user, UserPhotoId afterId);
|
||||
|
||||
// Non-personal photo in case a personal photo is set.
|
||||
void registerNonPersonalPhoto(
|
||||
not_null<UserData*> user,
|
||||
not_null<PhotoData*> photo);
|
||||
void unregisterNonPersonalPhoto(not_null<UserData*> user);
|
||||
[[nodiscard]] PhotoData *nonPersonalPhoto(
|
||||
not_null<UserData*> user) const;
|
||||
|
||||
private:
|
||||
enum class UploadType {
|
||||
Default,
|
||||
Suggestion,
|
||||
Fallback,
|
||||
};
|
||||
|
||||
void ready(const FullMsgId &msgId, const MTPInputFile &file);
|
||||
void upload(
|
||||
not_null<PeerData*> peer,
|
||||
QImage &&image,
|
||||
UploadType type,
|
||||
Fn<void()> done);
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
MTP::Sender _api;
|
||||
|
||||
base::flat_map<FullMsgId, not_null<PeerData*>> _uploads;
|
||||
struct UploadValue {
|
||||
not_null<PeerData*> peer;
|
||||
UploadType type = UploadType::Default;
|
||||
Fn<void()> done;
|
||||
};
|
||||
|
||||
base::flat_map<FullMsgId, UploadValue> _uploads;
|
||||
|
||||
base::flat_map<not_null<UserData*>, mtpRequestId> _userPhotosRequests;
|
||||
|
||||
base::flat_map<
|
||||
not_null<UserData*>,
|
||||
not_null<PhotoData*>> _nonPersonalPhotos;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -16,7 +16,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_poll.h"
|
||||
#include "data/data_session.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_message.h" // ShouldSendSilent
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_item_helpers.h" // ShouldSendSilent
|
||||
#include "main/main_session.h"
|
||||
|
||||
namespace Api {
|
||||
|
||||
@@ -44,9 +44,10 @@ void SendReport(
|
||||
Ui::ReportReason reason,
|
||||
const QString &comment,
|
||||
std::variant<v::null_t, MessageIdsList, not_null<PhotoData*>> data) {
|
||||
auto done = [=] {
|
||||
auto weak = Ui::MakeWeak(toastParent.get());
|
||||
auto done = crl::guard(toastParent, [=] {
|
||||
Ui::Toast::Show(toastParent, tr::lng_report_thanks(tr::now));
|
||||
};
|
||||
});
|
||||
v::match(data, [&](v::null_t) {
|
||||
peer->session().api().request(MTPaccount_ReportPeer(
|
||||
peer->input,
|
||||
|
||||
@@ -16,36 +16,61 @@ SelfDestruct::SelfDestruct(not_null<ApiWrap*> api)
|
||||
}
|
||||
|
||||
void SelfDestruct::reload() {
|
||||
if (_requestId) {
|
||||
return;
|
||||
if (!_accountTTL.requestId) {
|
||||
_accountTTL.requestId = _api.request(MTPaccount_GetAccountTTL(
|
||||
)).done([=](const MTPAccountDaysTTL &result) {
|
||||
_accountTTL.requestId = 0;
|
||||
_accountTTL.days = result.data().vdays().v;
|
||||
}).fail([=] {
|
||||
_accountTTL.requestId = 0;
|
||||
}).send();
|
||||
}
|
||||
if (!_defaultHistoryTTL.requestId) {
|
||||
_defaultHistoryTTL.requestId = _api.request(
|
||||
MTPmessages_GetDefaultHistoryTTL()
|
||||
).done([=](const MTPDefaultHistoryTTL &result) {
|
||||
_defaultHistoryTTL.requestId = 0;
|
||||
_defaultHistoryTTL.period = result.data().vperiod().v;
|
||||
}).fail([=] {
|
||||
_defaultHistoryTTL.requestId = 0;
|
||||
}).send();
|
||||
}
|
||||
_requestId = _api.request(MTPaccount_GetAccountTTL(
|
||||
)).done([=](const MTPAccountDaysTTL &result) {
|
||||
_requestId = 0;
|
||||
result.match([&](const MTPDaccountDaysTTL &data) {
|
||||
_days = data.vdays().v;
|
||||
});
|
||||
}).fail([=] {
|
||||
_requestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
||||
rpl::producer<int> SelfDestruct::days() const {
|
||||
using namespace rpl::mappers;
|
||||
|
||||
return _days.value() | rpl::filter(_1 != 0);
|
||||
rpl::producer<int> SelfDestruct::daysAccountTTL() const {
|
||||
return _accountTTL.days.value() | rpl::filter(rpl::mappers::_1 != 0);
|
||||
}
|
||||
|
||||
void SelfDestruct::update(int days) {
|
||||
_api.request(_requestId).cancel();
|
||||
_requestId = _api.request(MTPaccount_SetAccountTTL(
|
||||
rpl::producer<TimeId> SelfDestruct::periodDefaultHistoryTTL() const {
|
||||
return _defaultHistoryTTL.period.value();
|
||||
}
|
||||
|
||||
TimeId SelfDestruct::periodDefaultHistoryTTLCurrent() const {
|
||||
return _defaultHistoryTTL.period.current();
|
||||
}
|
||||
|
||||
void SelfDestruct::updateAccountTTL(int days) {
|
||||
_api.request(_accountTTL.requestId).cancel();
|
||||
_accountTTL.requestId = _api.request(MTPaccount_SetAccountTTL(
|
||||
MTP_accountDaysTTL(MTP_int(days))
|
||||
)).done([=] {
|
||||
_requestId = 0;
|
||||
_accountTTL.requestId = 0;
|
||||
}).fail([=] {
|
||||
_requestId = 0;
|
||||
_accountTTL.requestId = 0;
|
||||
}).send();
|
||||
_days = days;
|
||||
_accountTTL.days = days;
|
||||
}
|
||||
|
||||
void SelfDestruct::updateDefaultHistoryTTL(TimeId period) {
|
||||
_api.request(_defaultHistoryTTL.requestId).cancel();
|
||||
_defaultHistoryTTL.requestId = _api.request(
|
||||
MTPmessages_SetDefaultHistoryTTL(MTP_int(period))
|
||||
).done([=] {
|
||||
_defaultHistoryTTL.requestId = 0;
|
||||
}).fail([=] {
|
||||
_defaultHistoryTTL.requestId = 0;
|
||||
}).send();
|
||||
_defaultHistoryTTL.period = period;
|
||||
}
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -18,14 +18,24 @@ public:
|
||||
explicit SelfDestruct(not_null<ApiWrap*> api);
|
||||
|
||||
void reload();
|
||||
void update(int days);
|
||||
void updateAccountTTL(int days);
|
||||
void updateDefaultHistoryTTL(TimeId period);
|
||||
|
||||
rpl::producer<int> days() const;
|
||||
[[nodiscard]] rpl::producer<int> daysAccountTTL() const;
|
||||
[[nodiscard]] rpl::producer<TimeId> periodDefaultHistoryTTL() const;
|
||||
[[nodiscard]] TimeId periodDefaultHistoryTTLCurrent() const;
|
||||
|
||||
private:
|
||||
MTP::Sender _api;
|
||||
mtpRequestId _requestId = 0;
|
||||
rpl::variable<int> _days = 0;
|
||||
struct {
|
||||
mtpRequestId requestId = 0;
|
||||
rpl::variable<int> days = 0;
|
||||
} _accountTTL;
|
||||
|
||||
struct {
|
||||
mtpRequestId requestId = 0;
|
||||
rpl::variable<TimeId> period = 0;
|
||||
} _defaultHistoryTTL;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_changes.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_message.h" // NewMessageFlags.
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_item_helpers.h" // NewMessageFlags.
|
||||
#include "chat_helpers/message_field.h" // ConvertTextTagsToEntities.
|
||||
#include "chat_helpers/stickers_dice_pack.h" // DicePacks::kDiceString.
|
||||
#include "ui/text/text_entity.h" // TextWithEntities.
|
||||
@@ -166,7 +167,7 @@ void SendExistingMedia(
|
||||
), [=](const MTPUpdates &result, const MTP::Response &response) {
|
||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||
if (error.code() == 400
|
||||
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
|
||||
&& error.type().startsWith(u"FILE_REFERENCE_"_q)) {
|
||||
api->refreshFileReference(origin, [=](const auto &result) {
|
||||
if (media->fileReference() != usedFileReference) {
|
||||
repeatRequest(repeatRequest);
|
||||
@@ -392,6 +393,7 @@ void SendConfirmedFile(
|
||||
action.replyTo = file->to.replyTo;
|
||||
action.topicRootId = file->to.topicRootId;
|
||||
action.generateLocal = true;
|
||||
action.replaceMediaOf = file->to.replaceMediaOf;
|
||||
session->api().sendAction(action);
|
||||
|
||||
auto caption = TextWithEntities{
|
||||
@@ -439,13 +441,17 @@ void SendConfirmedFile(
|
||||
|
||||
const auto media = MTPMessageMedia([&] {
|
||||
if (file->type == SendMediaType::Photo) {
|
||||
using Flag = MTPDmessageMediaPhoto::Flag;
|
||||
return MTP_messageMediaPhoto(
|
||||
MTP_flags(MTPDmessageMediaPhoto::Flag::f_photo),
|
||||
MTP_flags(Flag::f_photo
|
||||
| (file->spoiler ? Flag::f_spoiler : Flag())),
|
||||
file->photo,
|
||||
MTPint());
|
||||
} else if (file->type == SendMediaType::File) {
|
||||
using Flag = MTPDmessageMediaDocument::Flag;
|
||||
return MTP_messageMediaDocument(
|
||||
MTP_flags(MTPDmessageMediaDocument::Flag::f_document),
|
||||
MTP_flags(Flag::f_document
|
||||
| (file->spoiler ? Flag::f_spoiler : Flag())),
|
||||
file->document,
|
||||
MTPint());
|
||||
} else if (file->type == SendMediaType::Audio) {
|
||||
|
||||
@@ -33,12 +33,12 @@ Key ExtractKey(const QString &query) {
|
||||
qthelp::UrlParamNameTransform::ToLower)
|
||||
: QMap<QString, QString>();
|
||||
};
|
||||
if (check.startsWith(qstr("tg://privatepost"), Qt::CaseInsensitive)) {
|
||||
if (check.startsWith(u"tg://privatepost"_q, Qt::CaseInsensitive)) {
|
||||
const auto params = parse();
|
||||
const auto channel = params.value("channel");
|
||||
const auto post = params.value("post").toInt();
|
||||
return (channel.toULongLong() && post) ? Key{ channel, post } : Key();
|
||||
} else if (check.startsWith(qstr("tg://resolve"), Qt::CaseInsensitive)) {
|
||||
} else if (check.startsWith(u"tg://resolve"_q, Qt::CaseInsensitive)) {
|
||||
const auto params = parse();
|
||||
const auto domain = params.value("domain");
|
||||
const auto post = params.value("post").toInt();
|
||||
@@ -220,7 +220,7 @@ QString ConvertPeerSearchQuery(const QString &query) {
|
||||
const auto trimmed = query.trimmed();
|
||||
const auto local = Core::TryConvertUrlToLocal(trimmed);
|
||||
const auto check = local.isEmpty() ? trimmed : local;
|
||||
if (!check.startsWith(qstr("tg://resolve"), Qt::CaseInsensitive)) {
|
||||
if (!check.startsWith(u"tg://resolve"_q, Qt::CaseInsensitive)) {
|
||||
return query;
|
||||
}
|
||||
const auto delimeter = check.indexOf('?');
|
||||
|
||||
@@ -36,7 +36,7 @@ bool UnreadThings::trackMentions(Data::Thread *thread) const {
|
||||
|
||||
bool UnreadThings::trackReactions(Data::Thread *thread) const {
|
||||
const auto peer = thread ? thread->peer().get() : nullptr;
|
||||
return peer && (peer->isChat() || peer->isMegagroup());
|
||||
return peer && (peer->isUser() || peer->isChat() || peer->isMegagroup());
|
||||
}
|
||||
|
||||
void UnreadThings::preloadEnough(Data::Thread *thread) {
|
||||
|
||||
@@ -95,7 +95,7 @@ void ProcessScheduledMessageWithElapsedTime(
|
||||
}
|
||||
|
||||
bool IsForceLogoutNotification(const MTPDupdateServiceNotification &data) {
|
||||
return qs(data.vtype()).startsWith(qstr("AUTH_KEY_DROP_"));
|
||||
return qs(data.vtype()).startsWith(u"AUTH_KEY_DROP_"_q);
|
||||
}
|
||||
|
||||
bool HasForceLogoutNotification(const MTPUpdates &updates) {
|
||||
@@ -1513,7 +1513,8 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
// Request last active supergroup participants if the 'from' user was not loaded yet.
|
||||
// This will optimize similar getDifference() calls for almost all next messages.
|
||||
if (isDataLoaded == DataIsLoadedResult::FromNotLoaded && channel && channel->isMegagroup()) {
|
||||
if (channel->mgInfo->lastParticipants.size() < _session->serverConfig().chatSizeMax
|
||||
if (channel->canViewMembers()
|
||||
&& channel->mgInfo->lastParticipants.size() < _session->serverConfig().chatSizeMax
|
||||
&& (channel->mgInfo->lastParticipants.empty()
|
||||
|| channel->mgInfo->lastParticipants.size() < channel->membersCount())) {
|
||||
session().api().chatParticipants().requestLast(channel);
|
||||
@@ -1895,26 +1896,12 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateUserPhoto: {
|
||||
auto &d = update.c_updateUserPhoto();
|
||||
if (auto user = session().data().userLoaded(d.vuser_id())) {
|
||||
user->setPhoto(d.vphoto());
|
||||
user->loadUserpic();
|
||||
// After that update we don't have enough information to
|
||||
// create a 'photo' with all necessary fields. So if
|
||||
// we receive second such update we end up with a 'photo_id'
|
||||
// in user_photos list without a loaded 'photo'.
|
||||
// It fails to show in media overview if you try to open it.
|
||||
//
|
||||
//if (mtpIsTrue(d.vprevious()) || !user->userpicPhotoId()) {
|
||||
session().storage().remove(Storage::UserPhotosRemoveAfter(
|
||||
peerToUser(user->id),
|
||||
user->userpicPhotoId()));
|
||||
//} else {
|
||||
// session().storage().add(Storage::UserPhotosAddNew(
|
||||
// peerToUser(user->id),
|
||||
// user->userpicPhotoId()));
|
||||
//}
|
||||
case mtpc_updateUser: {
|
||||
auto &d = update.c_updateUser();
|
||||
if (const auto user = session().data().userLoaded(d.vuser_id())) {
|
||||
if (user->wasFullUpdated()) {
|
||||
user->updateFullForced();
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -2213,7 +2200,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
history->requestChatListMessage();
|
||||
if (!history->folderKnown()
|
||||
|| (!history->unreadCountKnown()
|
||||
&& !history->peer->isForum())) {
|
||||
&& !history->isForum())) {
|
||||
history->owner().histories().requestDialogEntry(history);
|
||||
}
|
||||
if (!channel->amCreator()) {
|
||||
|
||||
@@ -114,7 +114,7 @@ struct Context {
|
||||
struct Userpic {
|
||||
not_null<PeerData*> peer;
|
||||
QString customEntityData;
|
||||
mutable std::shared_ptr<Data::CloudImageView> view;
|
||||
mutable Ui::PeerUserpicView view;
|
||||
mutable InMemoryKey uniqueKey;
|
||||
};
|
||||
|
||||
@@ -380,7 +380,7 @@ bool UpdateUserpics(
|
||||
const auto peer = not_null{ resolved.peer };
|
||||
const auto &data = ReactionEntityData(resolved.reaction);
|
||||
const auto i = ranges::find(was, peer, &Userpic::peer);
|
||||
if (i != end(was) && i->view) {
|
||||
if (i != end(was) && i->view.cloud) {
|
||||
now.push_back(std::move(*i));
|
||||
now.back().customEntityData = data;
|
||||
continue;
|
||||
@@ -571,7 +571,10 @@ bool WhoReadExists(not_null<HistoryItem*> item) {
|
||||
const auto peer = history->peer;
|
||||
const auto chat = peer->asChat();
|
||||
const auto megagroup = peer->asMegagroup();
|
||||
if ((!chat && !megagroup) || peer->isForum()) {
|
||||
if ((!chat && !megagroup)
|
||||
|| peer->isForum()
|
||||
|| (megagroup
|
||||
&& (megagroup->flags() & ChannelDataFlag::ParticipantsHidden))) {
|
||||
return false;
|
||||
}
|
||||
const auto &appConfig = peer->session().account().appConfig();
|
||||
|
||||
@@ -67,8 +67,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/add_contact_box.h"
|
||||
#include "mtproto/mtproto_config.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_message.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_item_components.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_session_settings.h"
|
||||
#include "main/main_account.h"
|
||||
@@ -96,7 +97,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "storage/storage_shared_media.h"
|
||||
#include "storage/storage_media_prepare.h"
|
||||
#include "storage/storage_account.h"
|
||||
#include "facades.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -479,15 +479,15 @@ void ApiWrap::sendMessageFail(
|
||||
FullMsgId itemId) {
|
||||
const auto show = ShowForPeer(peer);
|
||||
|
||||
if (error == qstr("PEER_FLOOD")) {
|
||||
if (error == u"PEER_FLOOD"_q) {
|
||||
show->showBox(
|
||||
Ui::MakeInformBox(
|
||||
PeerFloodErrorText(&session(), PeerFloodType::Send)),
|
||||
Ui::LayerOption::CloseOther);
|
||||
} else if (error == qstr("USER_BANNED_IN_CHANNEL")) {
|
||||
} else if (error == u"USER_BANNED_IN_CHANNEL"_q) {
|
||||
const auto link = Ui::Text::Link(
|
||||
tr::lng_cant_more_info(tr::now),
|
||||
session().createInternalLinkFull(qsl("spambot")));
|
||||
session().createInternalLinkFull(u"spambot"_q));
|
||||
show->showBox(
|
||||
Ui::MakeInformBox(
|
||||
tr::lng_error_public_groups_denied(
|
||||
@@ -496,8 +496,8 @@ void ApiWrap::sendMessageFail(
|
||||
link,
|
||||
Ui::Text::WithEntities)),
|
||||
Ui::LayerOption::CloseOther);
|
||||
} else if (error.startsWith(qstr("SLOWMODE_WAIT_"))) {
|
||||
const auto chop = qstr("SLOWMODE_WAIT_").size();
|
||||
} else if (error.startsWith(u"SLOWMODE_WAIT_"_q)) {
|
||||
const auto chop = u"SLOWMODE_WAIT_"_q.size();
|
||||
const auto left = base::StringViewMid(error, chop).toInt();
|
||||
if (const auto channel = peer->asChannel()) {
|
||||
const auto seconds = channel->slowmodeSeconds();
|
||||
@@ -508,7 +508,7 @@ void ApiWrap::sendMessageFail(
|
||||
requestFullPeer(peer);
|
||||
}
|
||||
}
|
||||
} else if (error == qstr("SCHEDULE_STATUS_PRIVATE")) {
|
||||
} else if (error == u"SCHEDULE_STATUS_PRIVATE"_q) {
|
||||
auto &scheduled = _session->data().scheduledMessages();
|
||||
Assert(peer->isUser());
|
||||
if (const auto item = scheduled.lookupItem(peer->id, itemId.msg)) {
|
||||
@@ -517,7 +517,7 @@ void ApiWrap::sendMessageFail(
|
||||
Ui::MakeInformBox(tr::lng_cant_do_this()),
|
||||
Ui::LayerOption::CloseOther);
|
||||
}
|
||||
} else if (error == qstr("CHAT_FORWARDS_RESTRICTED")) {
|
||||
} else if (error == u"CHAT_FORWARDS_RESTRICTED"_q) {
|
||||
if (show->valid()) {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = show->toastParent(),
|
||||
@@ -528,7 +528,7 @@ void ApiWrap::sendMessageFail(
|
||||
.duration = kJoinErrorDuration
|
||||
});
|
||||
}
|
||||
} else if (error == qstr("PREMIUM_ACCOUNT_REQUIRED")) {
|
||||
} else if (error == u"PREMIUM_ACCOUNT_REQUIRED"_q) {
|
||||
Settings::ShowPremium(&session(), "premium_stickers");
|
||||
}
|
||||
if (const auto item = _session->data().message(itemId)) {
|
||||
@@ -689,9 +689,13 @@ QString ApiWrap::exportDirectMessageLink(
|
||||
auto linkItemId = item->id;
|
||||
auto linkCommentId = MsgId();
|
||||
auto linkThreadId = MsgId();
|
||||
//auto linkThreadIsTopic = false;
|
||||
auto linkThreadIsTopic = false;
|
||||
if (inRepliesContext) {
|
||||
if (const auto rootId = item->replyToTop()) {
|
||||
linkThreadIsTopic = item->history()->isForum();
|
||||
const auto rootId = linkThreadIsTopic
|
||||
? item->topicRootId()
|
||||
: item->replyToTop();
|
||||
if (rootId) {
|
||||
const auto root = item->history()->owner().message(
|
||||
channel->id,
|
||||
rootId);
|
||||
@@ -711,7 +715,6 @@ QString ApiWrap::exportDirectMessageLink(
|
||||
} else {
|
||||
// Reply in a thread, maybe comment in a private channel.
|
||||
linkThreadId = rootId;
|
||||
//linkThreadIsTopic = (item->topicRootId() == rootId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -723,7 +726,7 @@ QString ApiWrap::exportDirectMessageLink(
|
||||
+ '/'
|
||||
+ (linkCommentId
|
||||
? (post + "?comment=" + QString::number(linkCommentId.bare))
|
||||
: (linkThreadId/* && !linkThreadIsTopic*/)
|
||||
: (linkThreadId && !linkThreadIsTopic)
|
||||
? (post + "?thread=" + QString::number(linkThreadId.bare))
|
||||
: linkThreadId
|
||||
? (QString::number(linkThreadId.bare) + '/' + post)
|
||||
@@ -735,7 +738,7 @@ QString ApiWrap::exportDirectMessageLink(
|
||||
if (const auto media = item->media()) {
|
||||
if (const auto document = media->document()) {
|
||||
if (document->isVideoMessage()) {
|
||||
return qsl("https://telesco.pe/") + query;
|
||||
return u"https://telesco.pe/"_q + query;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2415,6 +2418,12 @@ void ApiWrap::refreshFileReference(
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}, [&](Data::FileOriginFullUser data) {
|
||||
if (const auto user = _session->data().user(data.userId)) {
|
||||
request(MTPusers_GetFullUser(user->inputUser));
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}, [&](Data::FileOriginPeerPhoto data) {
|
||||
fail();
|
||||
}, [&](Data::FileOriginStickerSet data) {
|
||||
@@ -3055,7 +3064,7 @@ void ApiWrap::sharedMediaDone(
|
||||
}
|
||||
|
||||
void ApiWrap::sendAction(const SendAction &action) {
|
||||
if (!action.options.scheduled) {
|
||||
if (!action.options.scheduled && !action.replaceMediaOf) {
|
||||
const auto topic = action.topicRootId
|
||||
? action.history->peer->forumTopicFor(action.topicRootId)
|
||||
: nullptr;
|
||||
@@ -3147,7 +3156,11 @@ void ApiWrap::forwardMessages(
|
||||
if (sendAs) {
|
||||
sendFlags |= MTPmessages_ForwardMessages::Flag::f_send_as;
|
||||
}
|
||||
if (action.topicRootId) {
|
||||
const auto kGeneralId = Data::ForumTopic::kGeneralId;
|
||||
const auto topMsgId = (action.topicRootId == kGeneralId)
|
||||
? MsgId(0)
|
||||
: action.topicRootId;
|
||||
if (topMsgId) {
|
||||
sendFlags |= MTPmessages_ForwardMessages::Flag::f_top_msg_id;
|
||||
}
|
||||
|
||||
@@ -3169,7 +3182,7 @@ void ApiWrap::forwardMessages(
|
||||
MTP_vector<MTPint>(ids),
|
||||
MTP_vector<MTPlong>(randomIds),
|
||||
peer->input,
|
||||
MTP_int(action.topicRootId),
|
||||
MTP_int(topMsgId),
|
||||
MTP_int(action.options.scheduled),
|
||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty())
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
@@ -3222,7 +3235,7 @@ void ApiWrap::forwardMessages(
|
||||
messageFromId,
|
||||
messagePostAuthor,
|
||||
item,
|
||||
action.topicRootId);
|
||||
topMsgId);
|
||||
_session->data().registerMessageRandomId(randomId, newId);
|
||||
if (!localIds) {
|
||||
localIds = std::make_shared<base::flat_map<uint64, FullMsgId>>();
|
||||
@@ -3364,7 +3377,8 @@ void ApiWrap::editMedia(
|
||||
std::move(file.information),
|
||||
type,
|
||||
to,
|
||||
caption));
|
||||
caption,
|
||||
file.spoiler));
|
||||
}
|
||||
|
||||
void ApiWrap::sendFiles(
|
||||
@@ -3405,6 +3419,7 @@ void ApiWrap::sendFiles(
|
||||
uploadWithType,
|
||||
to,
|
||||
caption,
|
||||
file.spoiler,
|
||||
album));
|
||||
caption = TextWithTags();
|
||||
}
|
||||
@@ -3424,14 +3439,17 @@ void ApiWrap::sendFile(
|
||||
const SendAction &action) {
|
||||
const auto to = fileLoadTaskOptions(action);
|
||||
auto caption = TextWithTags();
|
||||
const auto spoiler = false;
|
||||
const auto information = nullptr;
|
||||
_fileLoader->addTask(std::make_unique<FileLoadTask>(
|
||||
&session(),
|
||||
QString(),
|
||||
fileContent,
|
||||
nullptr,
|
||||
information,
|
||||
type,
|
||||
to,
|
||||
caption));
|
||||
caption,
|
||||
spoiler));
|
||||
}
|
||||
|
||||
void ApiWrap::sendUploadedPhoto(
|
||||
@@ -3439,7 +3457,7 @@ void ApiWrap::sendUploadedPhoto(
|
||||
Api::RemoteFileInfo info,
|
||||
Api::SendOptions options) {
|
||||
if (const auto item = _session->data().message(localId)) {
|
||||
const auto media = Api::PrepareUploadedPhoto(std::move(info));
|
||||
const auto media = Api::PrepareUploadedPhoto(item, std::move(info));
|
||||
if (const auto groupId = item->groupId()) {
|
||||
uploadAlbumMedia(item, groupId, media);
|
||||
} else {
|
||||
@@ -3489,10 +3507,12 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
const auto replyTo = replyToId
|
||||
? peer->owner().message(peer, replyToId)
|
||||
: nullptr;
|
||||
const auto topicRootId = replyTo ? replyTo->topicRootId() : replyToId;
|
||||
const auto topic = topicRootId
|
||||
? peer->forumTopicFor(topicRootId)
|
||||
: nullptr;
|
||||
const auto topicRootId = replyTo
|
||||
? replyTo->topicRootId()
|
||||
: action.topicRootId
|
||||
? action.topicRootId
|
||||
: Data::ForumTopic::kGeneralId;
|
||||
const auto topic = peer->forumTopicFor(topicRootId);
|
||||
if (!(topic ? topic->canWrite() : peer->canWrite())
|
||||
|| Api::SendDice(message)) {
|
||||
return;
|
||||
@@ -3616,7 +3636,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
UnixtimeFromMsgId(response.outerMsgId));
|
||||
}
|
||||
}, [=](const MTP::Error &error, const MTP::Response &response) {
|
||||
if (error.type() == qstr("MESSAGE_EMPTY")) {
|
||||
if (error.type() == u"MESSAGE_EMPTY"_q) {
|
||||
lastMessage->destroy();
|
||||
} else {
|
||||
sendMessageFail(error, peer, randomId, newId);
|
||||
@@ -3788,7 +3808,9 @@ void ApiWrap::uploadAlbumMedia(
|
||||
failed();
|
||||
return;
|
||||
}
|
||||
auto spoiler = false;
|
||||
if (const auto media = item->media()) {
|
||||
spoiler = media->hasSpoiler();
|
||||
if (const auto photo = media->photo()) {
|
||||
photo->setWaitingForAlbum();
|
||||
} else if (const auto document = media->document()) {
|
||||
@@ -3805,10 +3827,10 @@ void ApiWrap::uploadAlbumMedia(
|
||||
return;
|
||||
}
|
||||
const auto &fields = photo->c_photo();
|
||||
const auto flags = MTPDinputMediaPhoto::Flags(0)
|
||||
| (data.vttl_seconds()
|
||||
? MTPDinputMediaPhoto::Flag::f_ttl_seconds
|
||||
: MTPDinputMediaPhoto::Flag(0));
|
||||
using Flag = MTPDinputMediaPhoto::Flag;
|
||||
const auto flags = Flag()
|
||||
| (data.vttl_seconds() ? Flag::f_ttl_seconds : Flag())
|
||||
| (spoiler ? Flag::f_spoiler : Flag());
|
||||
const auto media = MTP_inputMediaPhoto(
|
||||
MTP_flags(flags),
|
||||
MTP_inputPhoto(
|
||||
@@ -3827,10 +3849,10 @@ void ApiWrap::uploadAlbumMedia(
|
||||
return;
|
||||
}
|
||||
const auto &fields = document->c_document();
|
||||
const auto flags = MTPDinputMediaDocument::Flags(0)
|
||||
| (data.vttl_seconds()
|
||||
? MTPDinputMediaDocument::Flag::f_ttl_seconds
|
||||
: MTPDinputMediaDocument::Flag(0));
|
||||
using Flag = MTPDinputMediaDocument::Flag;
|
||||
const auto flags = Flag()
|
||||
| (data.vttl_seconds() ? Flag::f_ttl_seconds : Flag())
|
||||
| (spoiler ? Flag::f_spoiler : Flag());
|
||||
const auto media = MTP_inputMediaDocument(
|
||||
MTP_flags(flags),
|
||||
MTP_inputDocument(
|
||||
|
||||
@@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "base/platform/base_platform_info.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "core/update_checker.h"
|
||||
#include "core/application.h"
|
||||
@@ -64,7 +65,7 @@ AboutBox::AboutBox(QWidget *parent)
|
||||
}
|
||||
|
||||
void AboutBox::prepare() {
|
||||
setTitle(rpl::single(qsl("Telegram Desktop")));
|
||||
setTitle(rpl::single(u"Telegram Desktop"_q));
|
||||
|
||||
addButton(tr::lng_close(), [this] { closeBox(); });
|
||||
|
||||
@@ -94,19 +95,19 @@ void AboutBox::resizeEvent(QResizeEvent *e) {
|
||||
|
||||
void AboutBox::showVersionHistory() {
|
||||
if (cRealAlphaVersion()) {
|
||||
auto url = qsl("https://tdesktop.com/");
|
||||
auto url = u"https://tdesktop.com/"_q;
|
||||
if (Platform::IsWindows32Bit()) {
|
||||
url += qsl("win/%1.zip");
|
||||
url += u"win/%1.zip"_q;
|
||||
} else if (Platform::IsWindows64Bit()) {
|
||||
url += qsl("win64/%1.zip");
|
||||
url += u"win64/%1.zip"_q;
|
||||
} else if (Platform::IsMac()) {
|
||||
url += qsl("mac/%1.zip");
|
||||
url += u"mac/%1.zip"_q;
|
||||
} else if (Platform::IsLinux()) {
|
||||
url += qsl("linux/%1.tar.xz");
|
||||
url += u"linux/%1.tar.xz"_q;
|
||||
} else {
|
||||
Unexpected("Platform value.");
|
||||
}
|
||||
url = url.arg(qsl("talpha%1_%2").arg(cRealAlphaVersion()).arg(Core::countAlphaVersionSignature(cRealAlphaVersion())));
|
||||
url = url.arg(u"talpha%1_%2"_q.arg(cRealAlphaVersion()).arg(Core::countAlphaVersionSignature(cRealAlphaVersion())));
|
||||
|
||||
QGuiApplication::clipboard()->setText(url);
|
||||
|
||||
@@ -116,7 +117,7 @@ void AboutBox::showVersionHistory() {
|
||||
"version of Telegram Desktop was copied to the clipboard."),
|
||||
Ui::LayerOption::CloseOther);
|
||||
} else {
|
||||
UrlClickHandler::Open(Core::App().changelogLink());
|
||||
File::OpenUrl(Core::App().changelogLink());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +130,7 @@ void AboutBox::keyPressEvent(QKeyEvent *e) {
|
||||
}
|
||||
|
||||
QString telegramFaqLink() {
|
||||
const auto result = qsl("https://telegram.org/faq");
|
||||
const auto result = u"https://telegram.org/faq"_q;
|
||||
const auto langpacked = [&](const char *language) {
|
||||
return result + '/' + language;
|
||||
};
|
||||
@@ -139,7 +140,7 @@ QString telegramFaqLink() {
|
||||
return langpacked(language);
|
||||
}
|
||||
}
|
||||
if (current.startsWith(qstr("pt-br"))) {
|
||||
if (current.startsWith(u"pt-br"_q)) {
|
||||
return langpacked("br");
|
||||
}
|
||||
return result;
|
||||
@@ -148,7 +149,7 @@ QString telegramFaqLink() {
|
||||
QString currentVersionText() {
|
||||
auto result = QString::fromLatin1(AppVersionStr);
|
||||
if (cAlphaVersion()) {
|
||||
result += qsl(" alpha %1").arg(cAlphaVersion() % 1000);
|
||||
result += u" alpha %1"_q.arg(cAlphaVersion() % 1000);
|
||||
} else if (AppBetaVersion) {
|
||||
result += " beta";
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "boxes/about_sponsored_box.h"
|
||||
|
||||
#include "core/file_utilities.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
@@ -14,8 +15,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
#include <QtGui/QDesktopServices>
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
@@ -50,7 +49,7 @@ void AboutSponsoredBox(not_null<Ui::GenericBox*> box) {
|
||||
(rowSize.height() - buttonSize.height()) / 2);
|
||||
}, row->lifetime());
|
||||
button->addClickHandler([=] {
|
||||
QDesktopServices::openUrl({ kUrl.utf8() });
|
||||
File::OpenUrl(kUrl.utf8());
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
#include "core/application.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
@@ -17,25 +19,30 @@ void showBox(
|
||||
object_ptr<BoxContent> content,
|
||||
LayerOptions options,
|
||||
anim::type animated) {
|
||||
if (auto w = App::wnd()) {
|
||||
w->ui_showBox(std::move(content), options, animated);
|
||||
const auto window = Core::IsAppLaunched()
|
||||
? Core::App().primaryWindow()
|
||||
: nullptr;
|
||||
if (window) {
|
||||
window->show(std::move(content), options, animated);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
void hideLayer(anim::type animated) {
|
||||
if (auto w = App::wnd()) {
|
||||
w->ui_showBox(
|
||||
{ nullptr },
|
||||
LayerOption::CloseOther,
|
||||
animated);
|
||||
const auto window = Core::IsAppLaunched()
|
||||
? Core::App().primaryWindow()
|
||||
: nullptr;
|
||||
if (window) {
|
||||
window->hideLayer(animated);
|
||||
}
|
||||
}
|
||||
|
||||
bool isLayerShown() {
|
||||
if (auto w = App::wnd()) return w->ui_isLayerShown();
|
||||
return false;
|
||||
const auto window = Core::IsAppLaunched()
|
||||
? Core::App().primaryWindow()
|
||||
: nullptr;
|
||||
return window && window->isLayerShown();
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
||||
@@ -47,6 +47,5 @@ QPointer<BoxType> show(
|
||||
}
|
||||
|
||||
void hideLayer(anim::type animated = anim::type::normal);
|
||||
bool isLayerShown();
|
||||
|
||||
} // namespace Ui
|
||||
|
||||
@@ -21,12 +21,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||
#include "countries/countries_instance.h" // Countries::ExtractPhoneCode.
|
||||
#include "window/window_session_controller.h"
|
||||
#include "menu/menu_ttl.h"
|
||||
#include "ui/controls/userpic_button.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/widgets/fields/special_fields.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/unread_badge.h"
|
||||
@@ -42,8 +45,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_invite_links.h"
|
||||
#include "api/api_peer_photo.h"
|
||||
#include "main/main_session.h"
|
||||
#include "facades.h"
|
||||
#include "styles/style_info.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_widgets.h"
|
||||
@@ -54,19 +58,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
namespace {
|
||||
|
||||
bool IsValidPhone(QString phone) {
|
||||
phone = phone.replace(QRegularExpression(qsl("[^\\d]")), QString());
|
||||
phone = phone.replace(QRegularExpression(u"[^\\d]"_q), QString());
|
||||
return (phone.length() >= 8)
|
||||
|| (phone == qsl("333"))
|
||||
|| (phone.startsWith(qsl("42"))
|
||||
|| (phone == u"333"_q)
|
||||
|| (phone.startsWith(u"42"_q)
|
||||
&& (phone.length() == 2
|
||||
|| phone.length() == 5
|
||||
|| phone.length() == 6
|
||||
|| phone == qsl("4242")));
|
||||
|| phone == u"4242"_q));
|
||||
}
|
||||
|
||||
void ChatCreateDone(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
QImage image,
|
||||
TimeId ttlPeriod,
|
||||
const MTPUpdates &updates) {
|
||||
navigation->session().api().applyUpdates(updates);
|
||||
|
||||
@@ -98,7 +103,10 @@ void ChatCreateDone(
|
||||
chat,
|
||||
std::move(image));
|
||||
}
|
||||
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
|
||||
if (ttlPeriod) {
|
||||
chat->setMessagesTTL(ttlPeriod);
|
||||
}
|
||||
navigation->showPeerHistory(chat);
|
||||
};
|
||||
if (!success) {
|
||||
LOG(("API Error: chat not found in updates "
|
||||
@@ -113,7 +121,7 @@ TextWithEntities PeerFloodErrorText(
|
||||
PeerFloodType type) {
|
||||
const auto link = Ui::Text::Link(
|
||||
tr::lng_cant_more_info(tr::now),
|
||||
session->createInternalLinkFull(qsl("spambot")));
|
||||
session->createInternalLinkFull(u"spambot"_q));
|
||||
return ((type == PeerFloodType::InviteGroup)
|
||||
? tr::lng_cant_invite_not_contact
|
||||
: tr::lng_cant_send_to_not_contact)(
|
||||
@@ -398,7 +406,9 @@ void AddContactBox::save() {
|
||||
: extractUser(list.front());
|
||||
if (user) {
|
||||
if (user->isContact() || user->session().supportMode()) {
|
||||
Ui::showPeerHistory(user, ShowAtTheEndMsgId);
|
||||
if (const auto window = user->session().tryResolveWindow()) {
|
||||
window->showPeerHistory(user);
|
||||
}
|
||||
}
|
||||
if (weak) { // showPeerHistory could close the box.
|
||||
getDelegate()->hideLayer();
|
||||
@@ -455,11 +465,9 @@ void GroupInfoBox::prepare() {
|
||||
_photo.create(
|
||||
this,
|
||||
&_navigation->parentController()->window(),
|
||||
((_type == Type::Channel)
|
||||
? tr::lng_create_channel_crop
|
||||
: tr::lng_create_group_crop)(tr::now),
|
||||
Ui::UserpicButton::Role::ChangePhoto,
|
||||
Ui::UserpicButton::Role::ChoosePhoto,
|
||||
st::defaultUserpicButton);
|
||||
_photo->showCustomOnChosen();
|
||||
_title.create(
|
||||
this,
|
||||
st::defaultInputField,
|
||||
@@ -515,6 +523,39 @@ void GroupInfoBox::prepare() {
|
||||
[=] { submit(); });
|
||||
addButton(tr::lng_cancel(), [this] { closeBox(); });
|
||||
|
||||
if (_type == Type::Group) {
|
||||
const auto top = addTopButton(st::infoTopBarMenu);
|
||||
const auto menu =
|
||||
top->lifetime().make_state<base::unique_qptr<Ui::PopupMenu>>();
|
||||
top->setClickedCallback([=] {
|
||||
*menu = base::make_unique_q<Ui::PopupMenu>(
|
||||
top,
|
||||
st::popupMenuWithIcons);
|
||||
|
||||
const auto text = tr::lng_manage_messages_ttl_menu(tr::now)
|
||||
+ (_ttlPeriod
|
||||
? ('\t' + Ui::FormatTTLTiny(_ttlPeriod))
|
||||
: QString());
|
||||
(*menu)->addAction(
|
||||
text,
|
||||
[=, show = std::make_shared<Ui::BoxShow>(this)] {
|
||||
show->showBox(Box(TTLMenu::TTLBox, TTLMenu::Args{
|
||||
.show = show,
|
||||
.startTtl = _ttlPeriod,
|
||||
.about = nullptr,
|
||||
.callback = crl::guard(this, [=](
|
||||
TimeId t,
|
||||
Fn<void()> close) {
|
||||
_ttlPeriod = t;
|
||||
close();
|
||||
}),
|
||||
}));
|
||||
}, &st::menuIconTTL);
|
||||
(*menu)->popup(QCursor::pos());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
updateMaxHeight();
|
||||
}
|
||||
|
||||
@@ -592,14 +633,19 @@ void GroupInfoBox::createGroup(
|
||||
return;
|
||||
}
|
||||
_creationRequestId = _api.request(MTPmessages_CreateChat(
|
||||
MTP_flags(_ttlPeriod
|
||||
? MTPmessages_CreateChat::Flag::f_ttl_period
|
||||
: MTPmessages_CreateChat::Flags(0)),
|
||||
MTP_vector<TLUsers>(inputs),
|
||||
MTP_string(title)
|
||||
MTP_string(title),
|
||||
MTP_int(_ttlPeriod)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
auto image = _photo->takeResultImage();
|
||||
const auto period = _ttlPeriod;
|
||||
const auto navigation = _navigation;
|
||||
|
||||
getDelegate()->hideLayer(); // Destroys 'this'.
|
||||
ChatCreateDone(navigation, std::move(image), result);
|
||||
ChatCreateDone(navigation, std::move(image), period, result);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto &type = error.type();
|
||||
_creationRequestId = 0;
|
||||
@@ -675,15 +721,19 @@ void GroupInfoBox::createChannel(
|
||||
const QString &description) {
|
||||
Expects(!_creationRequestId);
|
||||
|
||||
const auto flags = (_type == Type::Megagroup)
|
||||
? MTPchannels_CreateChannel::Flag::f_megagroup
|
||||
: MTPchannels_CreateChannel::Flag::f_broadcast;
|
||||
const auto flags = ((_type == Type::Megagroup)
|
||||
? MTPchannels_CreateChannel::Flag::f_megagroup
|
||||
: MTPchannels_CreateChannel::Flag::f_broadcast)
|
||||
| (_ttlPeriod
|
||||
? MTPchannels_CreateChannel::Flag::f_ttl_period
|
||||
: MTPchannels_CreateChannel::Flags(0));
|
||||
_creationRequestId = _api.request(MTPchannels_CreateChannel(
|
||||
MTP_flags(flags),
|
||||
MTP_string(title),
|
||||
MTP_string(description),
|
||||
MTPInputGeoPoint(), // geo_point
|
||||
MTPstring() // address
|
||||
MTPstring(), // address
|
||||
MTP_int((_type == Type::Megagroup) ? _ttlPeriod : 0)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
_navigation->session().api().applyUpdates(result);
|
||||
|
||||
@@ -716,6 +766,9 @@ void GroupInfoBox::createChannel(
|
||||
channel,
|
||||
std::move(image));
|
||||
}
|
||||
if (_ttlPeriod && channel->isMegagroup()) {
|
||||
channel->setMessagesTTL(_ttlPeriod);
|
||||
}
|
||||
channel->session().api().requestFullPeer(channel);
|
||||
_createdChannel = channel;
|
||||
checkInviteLink();
|
||||
@@ -1225,6 +1278,8 @@ SetupChannelBox::UsernameResult SetupChannelBox::parseError(
|
||||
return UsernameResult::Invalid;
|
||||
} else if (error == u"USERNAME_OCCUPIED"_q) {
|
||||
return UsernameResult::Occupied;
|
||||
} else if (error == u"USERNAME_PURCHASE_AVAILABLE"_q) {
|
||||
return UsernameResult::Occupied;
|
||||
} else if (error == u"USERNAMES_UNAVAILABLE"_q) {
|
||||
return UsernameResult::Occupied;
|
||||
} else if (error == u"CHANNEL_PUBLIC_GROUP_NA"_q) {
|
||||
|
||||
@@ -139,6 +139,7 @@ private:
|
||||
mtpRequestId _creationRequestId = 0;
|
||||
bool _creatingInviteLink = false;
|
||||
ChannelData *_createdChannel = nullptr;
|
||||
TimeId _ttlPeriod = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/painter.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_message.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/view/history_view_message.h"
|
||||
#include "main/main_session.h"
|
||||
#include "apiwrap.h"
|
||||
|
||||
@@ -62,6 +62,18 @@ defaultUserpicButton: UserpicButton {
|
||||
uploadIcon: defaultUploadUserpicIcon;
|
||||
uploadIconPosition: point(-1px, 1px);
|
||||
}
|
||||
uploadUserpicSize: 32px;
|
||||
uploadUserpicButton: UserpicButton(defaultUserpicButton) {
|
||||
size: size(uploadUserpicSize, uploadUserpicSize);
|
||||
photoSize: uploadUserpicSize;
|
||||
changeIcon: icon {{ "settings/photo", activeButtonFg }};
|
||||
changeIconPosition: point(4px, 4px);
|
||||
}
|
||||
uploadUserpicButtonBorder: 2px;
|
||||
restoreUserpicIcon: UserpicButton(defaultUserpicButton) {
|
||||
size: size(22px, 22px);
|
||||
photoSize: 22px;
|
||||
}
|
||||
|
||||
confirmInviteTitle: FlatLabel(defaultFlatLabel) {
|
||||
align: align(center);
|
||||
@@ -273,7 +285,7 @@ notificationsSampleMargin: 2px;
|
||||
notificationSampleOpacity: 0.5;
|
||||
notificationSampleSize: size(64px, 16px);
|
||||
|
||||
membersAboutLimitPadding: margins(0px, 12px, 0px, 12px);
|
||||
membersAboutLimitPadding: margins(0px, 16px, 0px, 16px);
|
||||
membersAbout: FlatLabel(defaultFlatLabel) {
|
||||
minWidth: 240px;
|
||||
textFg: membersAboutLimitFg;
|
||||
@@ -281,6 +293,10 @@ membersAbout: FlatLabel(defaultFlatLabel) {
|
||||
style: boxLabelStyle;
|
||||
}
|
||||
|
||||
fragmentBoxButton: RoundButton(introFragmentButton) {
|
||||
width: 256px;
|
||||
}
|
||||
|
||||
passcodeHeaderFont: font(19px);
|
||||
passcodeHeaderHeight: 80px;
|
||||
passcodeInput: InputField(introPhone) {
|
||||
@@ -565,9 +581,6 @@ colorResultInput: InputField(colorValueInput) {
|
||||
|
||||
changePhoneButton: RoundButton(defaultActiveButton) {
|
||||
width: 256px;
|
||||
height: 42px;
|
||||
textTop: 11px;
|
||||
font: boxButtonFont;
|
||||
}
|
||||
changePhoneButtonPadding: margins(0px, 32px, 0px, 44px);
|
||||
changePhoneTitle: FlatLabel(boxTitle) {
|
||||
|
||||
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "boxes/change_phone_box.h"
|
||||
|
||||
#include "core/file_utilities.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/sent_code_field.h"
|
||||
@@ -19,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "boxes/phone_banned_box.h"
|
||||
#include "countries/countries_instance.h" // Countries::ExtractPhoneCode.
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_session.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
@@ -67,6 +69,10 @@ void CreateErrorLabel(
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] int ErrorSkip() {
|
||||
return st::boxLittleSkip + st::changePhoneError.style.font->height;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace Settings {
|
||||
@@ -109,6 +115,7 @@ public:
|
||||
not_null<Window::SessionController*> controller,
|
||||
const QString &phone,
|
||||
const QString &hash,
|
||||
const QString &openUrl,
|
||||
int codeLength,
|
||||
int callTimeout);
|
||||
|
||||
@@ -120,7 +127,7 @@ protected:
|
||||
void prepare() override;
|
||||
|
||||
private:
|
||||
void submit();
|
||||
void submit(const QString &code);
|
||||
void sendCall();
|
||||
void updateCall();
|
||||
void sendCodeFail(const MTP::Error &error);
|
||||
@@ -128,18 +135,20 @@ private:
|
||||
void hideError() {
|
||||
showError(QString());
|
||||
}
|
||||
int countHeight();
|
||||
[[nodiscard]] int countHeight() const;
|
||||
|
||||
const not_null<Window::SessionController*> _controller;
|
||||
MTP::Sender _api;
|
||||
|
||||
QString _phone;
|
||||
QString _hash;
|
||||
QString _openUrl;
|
||||
int _codeLength = 0;
|
||||
int _callTimeout = 0;
|
||||
object_ptr<Ui::SentCodeField> _code = { nullptr };
|
||||
object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _error = { nullptr };
|
||||
object_ptr<Ui::FlatLabel> _callLabel = { nullptr };
|
||||
object_ptr<Ui::RoundButton> _fragment = { nullptr };
|
||||
mtpRequestId _requestId = 0;
|
||||
Ui::SentCodeCall _call;
|
||||
|
||||
@@ -174,11 +183,9 @@ void ChangePhone::EnterPhone::prepare() {
|
||||
this,
|
||||
tr::lng_change_phone_new_description(tr::now),
|
||||
st::changePhoneLabel);
|
||||
const auto errorSkip = st::boxLittleSkip
|
||||
+ st::changePhoneError.style.font->height;
|
||||
description->moveToLeft(
|
||||
st::boxPadding.left(),
|
||||
_phone->y() + _phone->height() + errorSkip + st::boxLittleSkip);
|
||||
_phone->y() + _phone->height() + ErrorSkip() + st::boxLittleSkip);
|
||||
|
||||
setDimensions(
|
||||
st::boxWidth,
|
||||
@@ -221,6 +228,7 @@ void ChangePhone::EnterPhone::sendPhoneDone(
|
||||
return false;
|
||||
};
|
||||
auto codeLength = 0;
|
||||
auto codeByFragmentUrl = QString();
|
||||
const auto hasLength = data.vtype().match([&](
|
||||
const MTPDauth_sentCodeTypeApp &typeData) {
|
||||
LOG(("Error: should not be in-app code!"));
|
||||
@@ -229,6 +237,10 @@ void ChangePhone::EnterPhone::sendPhoneDone(
|
||||
}, [&](const MTPDauth_sentCodeTypeSms &typeData) {
|
||||
codeLength = typeData.vlength().v;
|
||||
return true;
|
||||
}, [&](const MTPDauth_sentCodeTypeFragmentSms &typeData) {
|
||||
codeLength = typeData.vlength().v;
|
||||
codeByFragmentUrl = qs(typeData.vurl());
|
||||
return true;
|
||||
}, [&](const MTPDauth_sentCodeTypeCall &typeData) {
|
||||
codeLength = typeData.vlength().v;
|
||||
return true;
|
||||
@@ -260,6 +272,7 @@ void ChangePhone::EnterPhone::sendPhoneDone(
|
||||
_controller,
|
||||
phoneNumber,
|
||||
phoneCodeHash,
|
||||
codeByFragmentUrl,
|
||||
codeLength,
|
||||
callTimeout),
|
||||
Ui::LayerOption::KeepOther);
|
||||
@@ -270,11 +283,11 @@ void ChangePhone::EnterPhone::sendPhoneFail(
|
||||
const QString &phoneNumber) {
|
||||
if (MTP::IsFloodError(error)) {
|
||||
showError(tr::lng_flood_error(tr::now));
|
||||
} else if (error.type() == qstr("PHONE_NUMBER_INVALID")) {
|
||||
} else if (error.type() == u"PHONE_NUMBER_INVALID"_q) {
|
||||
showError(tr::lng_bad_phone(tr::now));
|
||||
} else if (error.type() == qstr("PHONE_NUMBER_BANNED")) {
|
||||
} else if (error.type() == u"PHONE_NUMBER_BANNED"_q) {
|
||||
Ui::ShowPhoneBannedError(&_controller->window(), phoneNumber);
|
||||
} else if (error.type() == qstr("PHONE_NUMBER_OCCUPIED")) {
|
||||
} else if (error.type() == u"PHONE_NUMBER_OCCUPIED"_q) {
|
||||
_controller->show(
|
||||
Ui::MakeInformBox(
|
||||
tr::lng_change_phone_occupied(
|
||||
@@ -304,18 +317,21 @@ ChangePhone::EnterCode::EnterCode(
|
||||
not_null<Window::SessionController*> controller,
|
||||
const QString &phone,
|
||||
const QString &hash,
|
||||
const QString &openUrl,
|
||||
int codeLength,
|
||||
int callTimeout)
|
||||
: _controller(controller)
|
||||
, _api(&controller->session().mtp())
|
||||
, _phone(phone)
|
||||
, _hash(hash)
|
||||
, _openUrl(openUrl)
|
||||
, _codeLength(codeLength)
|
||||
, _callTimeout(callTimeout)
|
||||
, _call([this] { sendCall(); }, [this] { updateCall(); }) {
|
||||
}
|
||||
|
||||
void ChangePhone::EnterCode::prepare() {
|
||||
const auto width = st::boxWidth;
|
||||
setTitle(tr::lng_change_phone_title());
|
||||
|
||||
const auto descriptionText = tr::lng_change_phone_code_description(
|
||||
@@ -329,44 +345,69 @@ void ChangePhone::EnterCode::prepare() {
|
||||
st::changePhoneLabel);
|
||||
description->moveToLeft(st::boxPadding.left(), 0);
|
||||
|
||||
const auto submitInput = [=] { submit(_code->getDigitsOnly()); };
|
||||
|
||||
const auto phoneValue = QString();
|
||||
_code.create(
|
||||
this,
|
||||
st::defaultInputField,
|
||||
tr::lng_change_phone_code_title(),
|
||||
phoneValue);
|
||||
_code->setAutoSubmit(_codeLength, [=] { submit(); });
|
||||
_code->setAutoSubmit(_codeLength, submitInput);
|
||||
_code->setChangedCallback([=] { hideError(); });
|
||||
|
||||
_code->resize(st::boxWidth - 2 * st::boxPadding.left(), _code->height());
|
||||
_code->resize(width - 2 * st::boxPadding.left(), _code->height());
|
||||
_code->moveToLeft(st::boxPadding.left(), description->bottomNoMargins());
|
||||
connect(_code, &Ui::InputField::submitted, [=] { submit(); });
|
||||
connect(_code, &Ui::InputField::submitted, submitInput);
|
||||
|
||||
setDimensions(st::boxWidth, countHeight());
|
||||
if (!_openUrl.isEmpty()) {
|
||||
_fragment.create(
|
||||
this,
|
||||
tr::lng_intro_fragment_button(),
|
||||
st::fragmentBoxButton);
|
||||
_fragment->setClickedCallback([=] { File::OpenUrl(_openUrl); });
|
||||
_fragment->setTextTransform(
|
||||
Ui::RoundButton::TextTransform::NoTransform);
|
||||
const auto codeBottom = _code->y() + _code->height();
|
||||
_fragment->setFullWidth(_code->width());
|
||||
_fragment->moveToLeft(
|
||||
(width - _fragment->width()) / 2,
|
||||
codeBottom + ErrorSkip() + st::boxLittleSkip);
|
||||
}
|
||||
|
||||
_controller->session().account().setHandleLoginCode([=](QString code) {
|
||||
submit(code);
|
||||
});
|
||||
boxClosing(
|
||||
) | rpl::start_with_next([controller = _controller] {
|
||||
controller->session().account().setHandleLoginCode(nullptr);
|
||||
}, lifetime());
|
||||
|
||||
setDimensions(width, countHeight());
|
||||
|
||||
if (_callTimeout > 0) {
|
||||
_call.setStatus({ Ui::SentCodeCall::State::Waiting, _callTimeout });
|
||||
updateCall();
|
||||
}
|
||||
|
||||
addButton(tr::lng_change_phone_new_submit(), [=] { submit(); });
|
||||
addButton(tr::lng_change_phone_new_submit(), submitInput);
|
||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||
}
|
||||
|
||||
int ChangePhone::EnterCode::countHeight() {
|
||||
const auto errorSkip = st::boxLittleSkip
|
||||
+ st::changePhoneError.style.font->height;
|
||||
return _code->bottomNoMargins() + errorSkip + 3 * st::boxLittleSkip;
|
||||
int ChangePhone::EnterCode::countHeight() const {
|
||||
return _code->bottomNoMargins()
|
||||
+ ErrorSkip()
|
||||
+ 3 * st::boxLittleSkip
|
||||
+ (_fragment ? _fragment->height() : 0);
|
||||
}
|
||||
|
||||
void ChangePhone::EnterCode::submit() {
|
||||
void ChangePhone::EnterCode::submit(const QString &code) {
|
||||
if (_requestId) {
|
||||
return;
|
||||
}
|
||||
hideError();
|
||||
|
||||
const auto session = &_controller->session();
|
||||
const auto code = _code->getDigitsOnly();
|
||||
const auto weak = Ui::MakeWeak(this);
|
||||
_requestId = session->api().request(MTPaccount_ChangePhone(
|
||||
MTP_string(_phone),
|
||||
@@ -428,13 +469,13 @@ void ChangePhone::EnterCode::showError(const QString &text) {
|
||||
void ChangePhone::EnterCode::sendCodeFail(const MTP::Error &error) {
|
||||
if (MTP::IsFloodError(error)) {
|
||||
showError(tr::lng_flood_error(tr::now));
|
||||
} else if (error.type() == qstr("PHONE_CODE_EMPTY")
|
||||
|| error.type() == qstr("PHONE_CODE_INVALID")) {
|
||||
} else if (error.type() == u"PHONE_CODE_EMPTY"_q
|
||||
|| error.type() == u"PHONE_CODE_INVALID"_q) {
|
||||
showError(tr::lng_bad_code(tr::now));
|
||||
} else if (error.type() == qstr("PHONE_CODE_EXPIRED")
|
||||
|| error.type() == qstr("PHONE_NUMBER_BANNED")) {
|
||||
} else if (error.type() == u"PHONE_CODE_EXPIRED"_q
|
||||
|| error.type() == u"PHONE_NUMBER_BANNED"_q) {
|
||||
closeBox(); // Go back to phone input.
|
||||
} else if (error.type() == qstr("PHONE_NUMBER_INVALID")) {
|
||||
} else if (error.type() == u"PHONE_NUMBER_INVALID"_q) {
|
||||
showError(tr::lng_bad_phone(tr::now));
|
||||
} else {
|
||||
showError(Lang::Hard::ServerError());
|
||||
|
||||
@@ -1092,17 +1092,17 @@ ProxiesBoxController::ProxiesBoxController(not_null<Main::Account*> account)
|
||||
void ProxiesBoxController::ShowApplyConfirmation(
|
||||
Type type,
|
||||
const QMap<QString, QString> &fields) {
|
||||
const auto server = fields.value(qsl("server"));
|
||||
const auto port = fields.value(qsl("port")).toUInt();
|
||||
const auto server = fields.value(u"server"_q);
|
||||
const auto port = fields.value(u"port"_q).toUInt();
|
||||
auto proxy = ProxyData();
|
||||
proxy.type = type;
|
||||
proxy.host = server;
|
||||
proxy.port = port;
|
||||
if (type == Type::Socks5) {
|
||||
proxy.user = fields.value(qsl("user"));
|
||||
proxy.password = fields.value(qsl("pass"));
|
||||
proxy.user = fields.value(u"user"_q);
|
||||
proxy.password = fields.value(u"pass"_q);
|
||||
} else if (type == Type::Mtproto) {
|
||||
proxy.password = fields.value(qsl("secret"));
|
||||
proxy.password = fields.value(u"secret"_q);
|
||||
}
|
||||
if (proxy) {
|
||||
const auto displayed = "https://" + server + "/";
|
||||
@@ -1504,12 +1504,9 @@ void ProxiesBoxController::updateView(const Item &item) {
|
||||
const auto deleted = item.deleted;
|
||||
const auto type = [&] {
|
||||
switch (item.data.type) {
|
||||
case Type::Http:
|
||||
return qsl("HTTP");
|
||||
case Type::Socks5:
|
||||
return qsl("SOCKS5");
|
||||
case Type::Mtproto:
|
||||
return qsl("MTPROTO");
|
||||
case Type::Http: return u"HTTP"_q;
|
||||
case Type::Socks5: return u"SOCKS5"_q;
|
||||
case Type::Mtproto: return u"MTPROTO"_q;
|
||||
}
|
||||
Unexpected("Proxy type in ProxiesBoxController::updateView.");
|
||||
}();
|
||||
@@ -1541,7 +1538,7 @@ void ProxiesBoxController::share(const ProxyData &proxy) {
|
||||
if (proxy.type == Type::Http) {
|
||||
return;
|
||||
}
|
||||
const auto link = qsl("https://t.me/")
|
||||
const auto link = u"https://t.me/"_q
|
||||
+ (proxy.type == Type::Socks5 ? "socks" : "proxy")
|
||||
+ "?server=" + proxy.host + "&port=" + QString::number(proxy.port)
|
||||
+ ((proxy.type == Type::Socks5 && !proxy.user.isEmpty())
|
||||
|
||||
@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "api/api_messages_search.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "core/application.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_histories.h"
|
||||
@@ -27,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
@@ -79,7 +81,7 @@ DeleteMessagesBox::DeleteMessagesBox(
|
||||
void DeleteMessagesBox::prepare() {
|
||||
auto details = TextWithEntities();
|
||||
const auto appendDetails = [&](TextWithEntities &&text) {
|
||||
details.append(qstr("\n\n")).append(std::move(text));
|
||||
details.append(u"\n\n"_q).append(std::move(text));
|
||||
};
|
||||
auto deleteText = lifetime().make_state<rpl::variable<QString>>();
|
||||
*deleteText = tr::lng_box_delete();
|
||||
@@ -229,11 +231,32 @@ void DeleteMessagesBox::prepare() {
|
||||
auto count = int(_ids.size());
|
||||
if (hasScheduledMessages()) {
|
||||
} else if (auto revoke = revokeText(peer)) {
|
||||
const auto &settings = Core::App().settings();
|
||||
const auto revokeByDefault =
|
||||
!settings.rememberedDeleteMessageOnlyForYou();
|
||||
_revoke.create(
|
||||
this,
|
||||
revoke->checkbox,
|
||||
true,
|
||||
revokeByDefault,
|
||||
st::defaultBoxCheckbox);
|
||||
_revokeRemember.create(
|
||||
this,
|
||||
object_ptr<Ui::Checkbox>(
|
||||
this,
|
||||
tr::lng_remember(),
|
||||
false,
|
||||
st::defaultBoxCheckbox));
|
||||
_revokeRemember->hide(anim::type::instant);
|
||||
_revoke->checkedValue(
|
||||
) | rpl::start_with_next([=](bool checked) {
|
||||
_revokeRemember->toggle(
|
||||
checked != revokeByDefault,
|
||||
anim::type::normal);
|
||||
}, _revokeRemember->lifetime());
|
||||
_revokeRemember->heightValue(
|
||||
) | rpl::start_with_next([=](int h) {
|
||||
setDimensions(st::boxWidth, _fullHeight + h);
|
||||
}, lifetime());
|
||||
appendDetails(std::move(revoke->description));
|
||||
} else if (peer->isChannel()) {
|
||||
if (peer->isMegagroup()) {
|
||||
@@ -309,6 +332,7 @@ void DeleteMessagesBox::prepare() {
|
||||
+ st::boxLittleSkip;
|
||||
}
|
||||
setDimensions(st::boxWidth, fullHeight);
|
||||
_fullHeight = fullHeight;
|
||||
}
|
||||
|
||||
bool DeleteMessagesBox::hasScheduledMessages() const {
|
||||
@@ -450,6 +474,11 @@ void DeleteMessagesBox::resizeEvent(QResizeEvent *e) {
|
||||
_revoke->resizeToNaturalWidth(availableWidth);
|
||||
_revoke->moveToLeft(padding.left(), top);
|
||||
top += _revoke->heightNoMargins() + st::boxLittleSkip;
|
||||
if (_revokeRemember) {
|
||||
_revokeRemember->resizeToNaturalWidth(availableWidth);
|
||||
_revokeRemember->moveToLeft(padding.left(),top);
|
||||
top += _revokeRemember->heightNoMargins();
|
||||
}
|
||||
}
|
||||
if (_autoDeleteSettings) {
|
||||
top += st::boxMediumSkip - st::boxLittleSkip;
|
||||
@@ -469,6 +498,14 @@ void DeleteMessagesBox::keyPressEvent(QKeyEvent *e) {
|
||||
}
|
||||
|
||||
void DeleteMessagesBox::deleteAndClear() {
|
||||
if (_revoke
|
||||
&& _revokeRemember
|
||||
&& _revokeRemember->toggled()
|
||||
&& _revokeRemember->entity()->checked()) {
|
||||
Core::App().settings().setRememberedDeleteMessageOnlyForYou(
|
||||
!_revoke->checked());
|
||||
Core::App().saveSettingsDelayed();
|
||||
}
|
||||
const auto revoke = _revoke ? _revoke->checked() : _revokeForBot;
|
||||
const auto session = _session;
|
||||
const auto invokeCallbackAndClose = [&] {
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace Ui {
|
||||
class Checkbox;
|
||||
class FlatLabel;
|
||||
class LinkButton;
|
||||
template <typename Widget>
|
||||
class SlideWrap;
|
||||
} // namespace Ui
|
||||
|
||||
class DeleteMessagesBox final : public Ui::BoxContent {
|
||||
@@ -73,11 +75,14 @@ private:
|
||||
|
||||
object_ptr<Ui::FlatLabel> _text = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _revoke = { nullptr };
|
||||
object_ptr<Ui::SlideWrap<Ui::Checkbox>> _revokeRemember = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _banUser = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _reportSpam = { nullptr };
|
||||
object_ptr<Ui::Checkbox> _deleteAll = { nullptr };
|
||||
object_ptr<Ui::LinkButton> _autoDeleteSettings = { nullptr };
|
||||
|
||||
int _fullHeight = 0;
|
||||
|
||||
Fn<void()> _deleteConfirmedCallback;
|
||||
|
||||
};
|
||||
|
||||
@@ -25,7 +25,14 @@ DownloadPathBox::DownloadPathBox(
|
||||
, _path(Core::App().settings().downloadPath())
|
||||
, _pathBookmark(Core::App().settings().downloadPathBookmark())
|
||||
, _group(std::make_shared<Ui::RadioenumGroup<Directory>>(typeFromPath(_path)))
|
||||
, _default(this, _group, Directory::Downloads, tr::lng_download_path_default_radio(tr::now), st::defaultBoxCheckbox)
|
||||
, _default(Core::App().canReadDefaultDownloadPath(true)
|
||||
? object_ptr<Ui::Radioenum<Directory>>(
|
||||
this,
|
||||
_group,
|
||||
Directory::Downloads,
|
||||
tr::lng_download_path_default_radio(tr::now),
|
||||
st::defaultBoxCheckbox)
|
||||
: nullptr)
|
||||
, _temp(this, _group, Directory::Temp, tr::lng_download_path_temp_radio(tr::now), st::defaultBoxCheckbox)
|
||||
, _dir(this, _group, Directory::Custom, tr::lng_download_path_dir_radio(tr::now), st::defaultBoxCheckbox)
|
||||
, _pathLink(this, QString(), st::boxLinkButton) {
|
||||
@@ -40,7 +47,7 @@ void DownloadPathBox::prepare() {
|
||||
_group->setChangedCallback([this](Directory value) { radioChanged(value); });
|
||||
|
||||
_pathLink->addClickHandler([=] { editPath(); });
|
||||
if (!_path.isEmpty() && _path != qsl("tmp")) {
|
||||
if (!_path.isEmpty() && _path != FileDialog::Tmp()) {
|
||||
setPathText(QDir::toNativeSeparators(_path));
|
||||
}
|
||||
updateControlsVisibility();
|
||||
@@ -50,7 +57,7 @@ void DownloadPathBox::updateControlsVisibility() {
|
||||
auto custom = (_group->value() == Directory::Custom);
|
||||
_pathLink->setVisible(custom);
|
||||
|
||||
auto newHeight = st::boxOptionListPadding.top() + _default->getMargins().top() + _default->heightNoMargins() + st::boxOptionListSkip + _temp->heightNoMargins() + st::boxOptionListSkip + _dir->heightNoMargins();
|
||||
auto newHeight = st::boxOptionListPadding.top() + (_default ? _default->getMargins().top() + _default->heightNoMargins() : 0) + st::boxOptionListSkip + _temp->heightNoMargins() + st::boxOptionListSkip + _dir->heightNoMargins();
|
||||
if (custom) {
|
||||
newHeight += st::downloadPathSkip + _pathLink->height();
|
||||
}
|
||||
@@ -62,8 +69,10 @@ void DownloadPathBox::updateControlsVisibility() {
|
||||
void DownloadPathBox::resizeEvent(QResizeEvent *e) {
|
||||
BoxContent::resizeEvent(e);
|
||||
|
||||
_default->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), st::boxOptionListPadding.top() + _default->getMargins().top());
|
||||
_temp->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _default->bottomNoMargins() + st::boxOptionListSkip);
|
||||
if (_default) {
|
||||
_default->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), st::boxOptionListPadding.top() + _default->getMargins().top());
|
||||
}
|
||||
_temp->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), (_default ? _default->bottomNoMargins() : 0) + st::boxOptionListSkip);
|
||||
_dir->moveToLeft(st::boxPadding.left() + st::boxOptionListPadding.left(), _temp->bottomNoMargins() + st::boxOptionListSkip);
|
||||
auto inputx = st::boxPadding.left() + st::boxOptionListPadding.left() + st::defaultCheck.diameter + st::defaultBoxCheckbox.textPosition.x();
|
||||
auto inputy = _dir->bottomNoMargins() + st::downloadPathSkip;
|
||||
@@ -73,14 +82,14 @@ void DownloadPathBox::resizeEvent(QResizeEvent *e) {
|
||||
|
||||
void DownloadPathBox::radioChanged(Directory value) {
|
||||
if (value == Directory::Custom) {
|
||||
if (_path.isEmpty() || _path == qsl("tmp")) {
|
||||
if (_path.isEmpty() || _path == FileDialog::Tmp()) {
|
||||
_group->setValue(_path.isEmpty() ? Directory::Downloads : Directory::Temp);
|
||||
editPath();
|
||||
} else {
|
||||
setPathText(QDir::toNativeSeparators(_path));
|
||||
}
|
||||
} else if (value == Directory::Temp) {
|
||||
_path = qsl("tmp");
|
||||
_path = FileDialog::Tmp();
|
||||
} else {
|
||||
_path = QString();
|
||||
}
|
||||
@@ -91,7 +100,7 @@ void DownloadPathBox::radioChanged(Directory value) {
|
||||
void DownloadPathBox::editPath() {
|
||||
const auto initialPath = [] {
|
||||
const auto path = Core::App().settings().downloadPath();
|
||||
if (!path.isEmpty() && path != qstr("tmp")) {
|
||||
if (!path.isEmpty() && path != FileDialog::Tmp()) {
|
||||
return path.left(path.size() - (path.endsWith('/') ? 1 : 0));
|
||||
}
|
||||
return QString();
|
||||
@@ -118,7 +127,7 @@ void DownloadPathBox::save() {
|
||||
if (value == Directory::Custom) {
|
||||
return _path;
|
||||
} else if (value == Directory::Temp) {
|
||||
return qsl("tmp");
|
||||
return FileDialog::Tmp();
|
||||
}
|
||||
return QString();
|
||||
};
|
||||
@@ -134,3 +143,13 @@ void DownloadPathBox::setPathText(const QString &text) {
|
||||
auto availw = st::boxWideWidth - st::boxPadding.left() - st::defaultCheck.diameter - st::defaultBoxCheckbox.textPosition.x() - st::boxPadding.right();
|
||||
_pathLink->setText(st::boxTextFont->elided(text, availw));
|
||||
}
|
||||
|
||||
DownloadPathBox::Directory DownloadPathBox::typeFromPath(
|
||||
const QString &path) {
|
||||
if (path.isEmpty()) {
|
||||
return Directory::Downloads;
|
||||
} else if (path == FileDialog::Tmp()) {
|
||||
return Directory::Temp;
|
||||
}
|
||||
return Directory::Custom;
|
||||
}
|
||||
|
||||
@@ -39,14 +39,7 @@ private:
|
||||
Custom,
|
||||
};
|
||||
void radioChanged(Directory value);
|
||||
Directory typeFromPath(const QString &path) {
|
||||
if (path.isEmpty()) {
|
||||
return Directory::Downloads;
|
||||
} else if (path == qsl("tmp")) {
|
||||
return Directory::Temp;
|
||||
}
|
||||
return Directory::Custom;
|
||||
}
|
||||
Directory typeFromPath(const QString &path);
|
||||
|
||||
void save();
|
||||
void updateControlsVisibility();
|
||||
|
||||
@@ -28,6 +28,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_premium_limits.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "editor/editor_layer_widget.h"
|
||||
#include "editor/photo_editor.h"
|
||||
#include "editor/photo_editor_layer_widget.h"
|
||||
#include "history/history_drag_area.h"
|
||||
#include "history/history_item.h"
|
||||
@@ -175,12 +177,15 @@ void EditCaptionBox::rebuildPreview() {
|
||||
Window::GifPauseReason::Layer);
|
||||
};
|
||||
|
||||
applyChanges();
|
||||
|
||||
_previewHasSpoiler = nullptr;
|
||||
if (_preparedList.files.empty()) {
|
||||
const auto media = _historyItem->media();
|
||||
const auto photo = media->photo();
|
||||
const auto document = media->document();
|
||||
_isPhoto = (photo != nullptr);
|
||||
if (photo || document->isVideoFile() || document->isAnimation()) {
|
||||
_isPhoto = (photo != nullptr);
|
||||
const auto media = Ui::CreateChild<Ui::ItemSingleMediaPreview>(
|
||||
this,
|
||||
gifPaused,
|
||||
@@ -189,7 +194,6 @@ void EditCaptionBox::rebuildPreview() {
|
||||
_photoMedia = media->sharedPhotoMedia();
|
||||
_content.reset(media);
|
||||
} else {
|
||||
_isPhoto = false;
|
||||
_content.reset(Ui::CreateChild<Ui::ItemSingleFilePreview>(
|
||||
this,
|
||||
_historyItem,
|
||||
@@ -203,11 +207,12 @@ void EditCaptionBox::rebuildPreview() {
|
||||
gifPaused,
|
||||
file,
|
||||
Ui::AttachControls::Type::EditOnly);
|
||||
if (media) {
|
||||
_isPhoto = media->isPhoto();
|
||||
_isPhoto = (media && media->isPhoto());
|
||||
const auto withCheckbox = _isPhoto && CanBeCompressed(_albumType);
|
||||
if (media && (!withCheckbox || !_asFile)) {
|
||||
_previewHasSpoiler = [media] { return media->hasSpoiler(); };
|
||||
_content.reset(media);
|
||||
} else {
|
||||
_isPhoto = false;
|
||||
_content.reset(Ui::CreateChild<Ui::SingleFilePreview>(
|
||||
this,
|
||||
file,
|
||||
@@ -299,7 +304,7 @@ void EditCaptionBox::setupControls() {
|
||||
{}
|
||||
) | rpl::map([=] {
|
||||
return _controller->session().settings().photoEditorHintShown()
|
||||
? _isPhoto
|
||||
? (_isPhoto && !_asFile)
|
||||
: false;
|
||||
});
|
||||
|
||||
@@ -316,7 +321,7 @@ void EditCaptionBox::setupControls() {
|
||||
this,
|
||||
object_ptr<Ui::Checkbox>(
|
||||
this,
|
||||
tr::lng_send_compressed(tr::now),
|
||||
tr::lng_send_compressed_one(tr::now),
|
||||
true,
|
||||
st::defaultBoxCheckbox),
|
||||
st::editMediaCheckboxMargins)
|
||||
@@ -329,7 +334,9 @@ void EditCaptionBox::setupControls() {
|
||||
anim::type::instant
|
||||
)->entity()->checkedChanges(
|
||||
) | rpl::start_with_next([&](bool checked) {
|
||||
applyChanges();
|
||||
_asFile = !checked;
|
||||
rebuildPreview();
|
||||
}, _controls->lifetime());
|
||||
|
||||
_controls->resizeToWidth(st::sendMediaPreviewSize);
|
||||
@@ -430,6 +437,8 @@ void EditCaptionBox::setupPhotoEditorEventHandler() {
|
||||
return;
|
||||
}
|
||||
auto copy = large->original();
|
||||
const auto wasSpoiler = hasSpoiler();
|
||||
|
||||
_preparedList = Storage::PrepareMediaFromImage(
|
||||
std::move(copy),
|
||||
QByteArray(),
|
||||
@@ -437,21 +446,28 @@ void EditCaptionBox::setupPhotoEditorEventHandler() {
|
||||
|
||||
using ImageInfo = Ui::PreparedFileInformation::Image;
|
||||
auto &file = _preparedList.files.front();
|
||||
file.spoiler = wasSpoiler;
|
||||
const auto image = std::get_if<ImageInfo>(
|
||||
&file.information->media);
|
||||
|
||||
image->modifications = mods;
|
||||
Storage::UpdateImageDetails(file, previewWidth);
|
||||
const auto sideLimit = PhotoSideLimit();
|
||||
Storage::UpdateImageDetails(file, previewWidth, sideLimit);
|
||||
rebuildPreview();
|
||||
};
|
||||
const auto fileImage = std::make_shared<Image>(*large);
|
||||
auto editor = base::make_unique_q<Editor::PhotoEditor>(
|
||||
this,
|
||||
&controller->window(),
|
||||
fileImage,
|
||||
Editor::PhotoModifications());
|
||||
const auto raw = editor.get();
|
||||
auto layer = std::make_unique<Editor::LayerWidget>(
|
||||
this,
|
||||
std::move(editor));
|
||||
Editor::InitEditorLayer(layer.get(), raw, std::move(callback));
|
||||
controller->showLayer(
|
||||
std::make_unique<Editor::LayerWidget>(
|
||||
this,
|
||||
&controller->window(),
|
||||
fileImage,
|
||||
Editor::PhotoModifications(),
|
||||
std::move(callback)),
|
||||
std::move(layer),
|
||||
Ui::LayerOption::KeepOther);
|
||||
}
|
||||
}, lifetime());
|
||||
@@ -581,11 +597,20 @@ bool EditCaptionBox::setPreparedList(Ui::PreparedList &&list) {
|
||||
tr::lng_edit_media_album_error(tr::now));
|
||||
return false;
|
||||
}
|
||||
const auto wasSpoiler = hasSpoiler();
|
||||
_preparedList = std::move(list);
|
||||
_preparedList.files.front().spoiler = wasSpoiler;
|
||||
rebuildPreview();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditCaptionBox::hasSpoiler() const {
|
||||
return _preparedList.files.empty()
|
||||
? (_historyItem->media()
|
||||
&& _historyItem->media()->hasSpoiler())
|
||||
: _preparedList.files.front().spoiler;
|
||||
}
|
||||
|
||||
void EditCaptionBox::captionResized() {
|
||||
updateBoxSize();
|
||||
resizeEvent(0);
|
||||
@@ -690,6 +715,12 @@ bool EditCaptionBox::validateLength(const QString &text) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void EditCaptionBox::applyChanges() {
|
||||
if (!_preparedList.files.empty() && _previewHasSpoiler) {
|
||||
_preparedList.files.front().spoiler = _previewHasSpoiler();
|
||||
}
|
||||
}
|
||||
|
||||
void EditCaptionBox::save() {
|
||||
if (_saveRequestId) {
|
||||
return;
|
||||
@@ -727,10 +758,14 @@ void EditCaptionBox::save() {
|
||||
action.replaceMediaOf = item->fullId().msg;
|
||||
|
||||
Storage::ApplyModifications(_preparedList);
|
||||
if (!_preparedList.files.empty()) {
|
||||
_preparedList.files.front().spoiler = false;
|
||||
applyChanges();
|
||||
}
|
||||
|
||||
_controller->session().api().editMedia(
|
||||
std::move(_preparedList),
|
||||
(!_asFile && _isPhoto && CanBeCompressed(_albumType))
|
||||
(_isPhoto && !_asFile && CanBeCompressed(_albumType))
|
||||
? SendMediaType::Photo
|
||||
: SendMediaType::File,
|
||||
_field->getTextWithAppliedMarkdown(),
|
||||
|
||||
@@ -64,11 +64,13 @@ private:
|
||||
void setupDragArea();
|
||||
|
||||
bool validateLength(const QString &text) const;
|
||||
void applyChanges();
|
||||
void save();
|
||||
|
||||
bool fileFromClipboard(not_null<const QMimeData*> data);
|
||||
|
||||
int errorTopSkip() const;
|
||||
[[nodiscard]] int errorTopSkip() const;
|
||||
[[nodiscard]] bool hasSpoiler() const;
|
||||
|
||||
bool setPreparedList(Ui::PreparedList &&list);
|
||||
|
||||
@@ -83,6 +85,7 @@ private:
|
||||
const base::unique_qptr<Ui::EmojiButton> _emojiToggle;
|
||||
|
||||
base::unique_qptr<Ui::AbstractSinglePreview> _content;
|
||||
Fn<bool()> _previewHasSpoiler;
|
||||
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
|
||||
base::unique_qptr<QObject> _emojiFilter;
|
||||
|
||||
|
||||
@@ -276,6 +276,11 @@ void EditPrivacyBox::setupContent() {
|
||||
? tr::lng_edit_privacy_exceptions_count(tr::now, lt_count, count)
|
||||
: tr::lng_edit_privacy_exceptions_add(tr::now);
|
||||
});
|
||||
_controller->handleExceptionsChange(
|
||||
exception,
|
||||
update->events_starting_with({}) | rpl::map([=] {
|
||||
return Settings::ExceptionUsersCount(exceptions(exception));
|
||||
}));
|
||||
auto text = _controller->exceptionButtonTextKey(exception);
|
||||
const auto always = (exception == Exception::Always);
|
||||
const auto button = content->add(
|
||||
|
||||
@@ -57,6 +57,10 @@ public:
|
||||
Exception exception) const = 0;
|
||||
[[nodiscard]] virtual auto exceptionsDescription()
|
||||
const -> rpl::producer<QString> = 0;
|
||||
virtual void handleExceptionsChange(
|
||||
Exception exception,
|
||||
rpl::producer<int> value) {
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual object_ptr<Ui::RpWidget> setupAboveWidget(
|
||||
not_null<QWidget*> parent,
|
||||
@@ -72,7 +76,7 @@ public:
|
||||
}
|
||||
[[nodiscard]] virtual object_ptr<Ui::RpWidget> setupBelowWidget(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<QWidget*> parent) const {
|
||||
not_null<QWidget*> parent) {
|
||||
return { nullptr };
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ private:
|
||||
};
|
||||
struct PeerButton {
|
||||
not_null<History*> history;
|
||||
std::shared_ptr<Data::CloudImageView> userpic;
|
||||
Ui::PeerUserpicView userpic;
|
||||
Ui::Text::String name;
|
||||
Button button;
|
||||
};
|
||||
|
||||
@@ -49,7 +49,8 @@ public:
|
||||
|
||||
QString generateName() override;
|
||||
QString generateShortName() override;
|
||||
PaintRoundImageCallback generatePaintUserpicCallback() override;
|
||||
PaintRoundImageCallback generatePaintUserpicCallback(
|
||||
bool forceRound) override;
|
||||
|
||||
private:
|
||||
[[nodiscard]] Flag flag() const;
|
||||
@@ -62,7 +63,8 @@ public:
|
||||
|
||||
QString generateName() override;
|
||||
QString generateShortName() override;
|
||||
PaintRoundImageCallback generatePaintUserpicCallback() override;
|
||||
PaintRoundImageCallback generatePaintUserpicCallback(
|
||||
bool forceRound) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -124,7 +126,8 @@ QString TypeRow::generateShortName() {
|
||||
return generateName();
|
||||
}
|
||||
|
||||
PaintRoundImageCallback TypeRow::generatePaintUserpicCallback() {
|
||||
PaintRoundImageCallback TypeRow::generatePaintUserpicCallback(
|
||||
bool forceRound) {
|
||||
const auto flag = this->flag();
|
||||
return [=](QPainter &p, int x, int y, int outerWidth, int size) {
|
||||
PaintFilterChatsTypeIcon(p, flag, x, y, outerWidth, size);
|
||||
@@ -153,11 +156,15 @@ QString ExceptionRow::generateShortName() {
|
||||
return generateName();
|
||||
}
|
||||
|
||||
PaintRoundImageCallback ExceptionRow::generatePaintUserpicCallback() {
|
||||
PaintRoundImageCallback ExceptionRow::generatePaintUserpicCallback(
|
||||
bool forceRound) {
|
||||
const auto peer = this->peer();
|
||||
const auto saved = peer->isSelf();
|
||||
const auto replies = peer->isRepliesChat();
|
||||
auto userpic = saved ? nullptr : ensureUserpicView();
|
||||
auto userpic = saved ? Ui::PeerUserpicView() : ensureUserpicView();
|
||||
if (forceRound && peer->isForum()) {
|
||||
return ForceRoundUserpicCallback(peer);
|
||||
}
|
||||
return [=](Painter &p, int x, int y, int outerWidth, int size) mutable {
|
||||
if (saved) {
|
||||
Ui::EmptyUserpic::PaintSavedMessages(p, x, y, outerWidth, size);
|
||||
@@ -248,7 +255,7 @@ void PaintFilterChatsTypeIcon(
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size) {
|
||||
const auto &color = [&]() -> const style::color& {
|
||||
const auto &color1 = [&]() -> const style::color& {
|
||||
switch (flag) {
|
||||
case Flag::Contacts: return st::historyPeer4UserpicBg;
|
||||
case Flag::NonContacts: return st::historyPeer7UserpicBg;
|
||||
@@ -261,6 +268,19 @@ void PaintFilterChatsTypeIcon(
|
||||
}
|
||||
Unexpected("Flag in color paintFlagIcon.");
|
||||
}();
|
||||
const auto &color2 = [&]() -> const style::color& {
|
||||
switch (flag) {
|
||||
case Flag::Contacts: return st::historyPeer4UserpicBg2;
|
||||
case Flag::NonContacts: return st::historyPeer7UserpicBg2;
|
||||
case Flag::Groups: return st::historyPeer2UserpicBg2;
|
||||
case Flag::Channels: return st::historyPeer1UserpicBg2;
|
||||
case Flag::Bots: return st::historyPeer6UserpicBg2;
|
||||
case Flag::NoMuted: return st::historyPeer6UserpicBg2;
|
||||
case Flag::NoArchived: return st::historyPeer4UserpicBg2;
|
||||
case Flag::NoRead: return st::historyPeer7UserpicBg2;
|
||||
}
|
||||
Unexpected("Flag in color paintFlagIcon.");
|
||||
}();
|
||||
const auto &icon = [&]() -> const style::icon& {
|
||||
switch (flag) {
|
||||
case Flag::Contacts: return st::windowFilterTypeContacts;
|
||||
@@ -276,7 +296,9 @@ void PaintFilterChatsTypeIcon(
|
||||
}();
|
||||
const auto rect = style::rtlrect(x, y, size, size, outerWidth);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setBrush(color->b);
|
||||
auto bg = QLinearGradient(x, y, x, y + size);
|
||||
bg.setStops({ { 0., color1->c }, { 1., color2->c } });
|
||||
p.setBrush(bg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(rect);
|
||||
icon.paintInCenter(p, rect);
|
||||
@@ -463,6 +485,6 @@ auto EditFilterChatsListController::createRow(not_null<History*> history)
|
||||
void EditFilterChatsListController::updateTitle() {
|
||||
const auto count = delegate()->peerListSelectedRowsCount()
|
||||
- selectedTypesCount();
|
||||
const auto additional = qsl("%1 / %2").arg(count).arg(_limit);
|
||||
const auto additional = u"%1 / %2"_q.arg(count).arg(_limit);
|
||||
delegate()->peerListSetAdditionalTitle(rpl::single(additional));
|
||||
}
|
||||
|
||||
@@ -19,10 +19,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "main/main_session.h"
|
||||
#include "settings/settings_premium.h"
|
||||
#include "ui/basic_click_handlers.h" // UrlClickHandler::Open.
|
||||
#include "ui/controls/userpic_button.h"
|
||||
#include "ui/effects/premium_graphics.h"
|
||||
#include "ui/effects/premium_stars_colored.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
@@ -86,7 +86,6 @@ void GiftBox(
|
||||
const auto userpic = Ui::CreateChild<Ui::UserpicButton>(
|
||||
top,
|
||||
user,
|
||||
Ui::UserpicButton::Role::Custom,
|
||||
st::defaultUserpicButton);
|
||||
userpic->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
top->widthValue(
|
||||
|
||||
@@ -416,7 +416,7 @@ bool Rows::hasMenu(not_null<const Row*> row) const {
|
||||
}
|
||||
|
||||
void Rows::share(not_null<const Row*> row) const {
|
||||
const auto link = qsl("https://t.me/setlanguage/") + row->data.id;
|
||||
const auto link = u"https://t.me/setlanguage/"_q + row->data.id;
|
||||
QGuiApplication::clipboard()->setText(link);
|
||||
Ui::Toast::Show(tr::lng_username_copied(tr::now));
|
||||
}
|
||||
@@ -1117,34 +1117,40 @@ void LanguageBox::prepare() {
|
||||
Core::App().saveSettingsDelayed();
|
||||
}, translateEnabled->lifetime());
|
||||
|
||||
const auto label = lifetime().make_state<rpl::event_stream<QLocale>>();
|
||||
using Locales = std::vector<QLocale>;
|
||||
const auto label = lifetime().make_state<rpl::event_stream<Locales>>();
|
||||
const auto translateSkipWrap = topContainer->add(
|
||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
topContainer,
|
||||
object_ptr<Ui::VerticalLayout>(topContainer)));
|
||||
translateSkipWrap->toggle(
|
||||
translateEnabled->toggled(),
|
||||
anim::type::normal);
|
||||
translateSkipWrap->toggleOn(translateEnabled->toggledValue());
|
||||
const auto translateSkip = Settings::AddButtonWithLabel(
|
||||
topContainer,
|
||||
translateSkipWrap->entity(),
|
||||
tr::lng_translate_settings_choose(),
|
||||
label->events() | rpl::map(Ui::LanguageName),
|
||||
label->events(
|
||||
) | rpl::map([](const Locales &locales) {
|
||||
return (locales.size() > 1)
|
||||
? tr::lng_languages_count(tr::now, lt_count, locales.size())
|
||||
: Ui::LanguageName(locales.front());
|
||||
}),
|
||||
st::settingsButtonNoIcon);
|
||||
|
||||
{
|
||||
const auto settingsLang =
|
||||
Core::App().settings().skipTranslationForLanguage();
|
||||
const auto locale = (settingsLang == QLocale::English)
|
||||
? QLocale(Lang::LanguageIdOrDefault(Lang::Id()))
|
||||
: (settingsLang == QLocale::C)
|
||||
? QLocale(QLocale::English)
|
||||
: QLocale(settingsLang);
|
||||
label->fire_copy(locale);
|
||||
}
|
||||
label->fire(Ui::Translate::LocalesFromSettings());
|
||||
translateSkip->setClickedCallback([=] {
|
||||
Ui::BoxShow(this).showBox(
|
||||
Box(Ui::ChooseLanguageBox, [=](QLocale locale) {
|
||||
label->fire_copy(locale);
|
||||
const auto result = (locale.language() == QLocale::English)
|
||||
? QLocale::c()
|
||||
: locale;
|
||||
Core::App().settings().setSkipTranslationForLanguage(
|
||||
result.language());
|
||||
Box(Ui::ChooseLanguageBox, [=](std::vector<QLocale> locales) {
|
||||
label->fire_copy(locales);
|
||||
const auto result = ranges::views::all(
|
||||
locales
|
||||
) | ranges::views::transform([](const QLocale &l) {
|
||||
return int(l.language());
|
||||
}) | ranges::to_vector;
|
||||
Core::App().settings().setSkipTranslationForLanguages(result);
|
||||
Core::App().saveSettingsDelayed();
|
||||
}),
|
||||
}, Ui::Translate::LocalesFromSettings()),
|
||||
Ui::LayerOption::KeepOther);
|
||||
});
|
||||
Settings::AddSkip(topContainer);
|
||||
@@ -1177,6 +1183,10 @@ void LanguageBox::prepare() {
|
||||
accumulate_max(*max, height);
|
||||
setDimensions(st::boxWidth, qMin(*max, st::boxMaxListHeight));
|
||||
}, inner->lifetime());
|
||||
topContainer->heightValue(
|
||||
) | rpl::start_with_next([=](int height) {
|
||||
setInnerTopSkip(height);
|
||||
}, inner->lifetime());
|
||||
|
||||
select->setSubmittedCallback([=](Qt::KeyboardModifiers) {
|
||||
inner->activateBySubmit();
|
||||
|
||||