Compare commits
154 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1291f1c80d | ||
|
|
0684db9bd8 | ||
|
|
db7b61a77b | ||
|
|
d392633b90 | ||
|
|
76e08af26a | ||
|
|
b23f16e6e4 | ||
|
|
23156d523c | ||
|
|
04b0e2e9e6 | ||
|
|
ace5740125 | ||
|
|
bc67b79023 | ||
|
|
528c98af67 | ||
|
|
311a2f2753 | ||
|
|
3defb06783 | ||
|
|
5708b5e849 | ||
|
|
1db1328a91 | ||
|
|
2e9d6d73c3 | ||
|
|
38dd5ab837 | ||
|
|
83ab670c50 | ||
|
|
5621e41529 | ||
|
|
056cab6268 | ||
|
|
61d0d240aa | ||
|
|
33ae4c2802 | ||
|
|
2c806b11d7 | ||
|
|
199434c7a2 | ||
|
|
c65c554d88 | ||
|
|
5d16359a5a | ||
|
|
fd9ad04d15 | ||
|
|
0c8febce9c | ||
|
|
4659cc50f2 | ||
|
|
2fddeb478b | ||
|
|
4ffe1d3acc | ||
|
|
cdf0512515 | ||
|
|
971e188063 | ||
|
|
a909c1a813 | ||
|
|
4fc2b1f1a3 | ||
|
|
fb04f33ae8 | ||
|
|
b2c87e7a73 | ||
|
|
86a33ceea1 | ||
|
|
a5d8d7a550 | ||
|
|
11723aedff | ||
|
|
fe5de8f009 | ||
|
|
6b68d001ae | ||
|
|
ae0b9141dd | ||
|
|
12e306dd7b | ||
|
|
508762cd2c | ||
|
|
9a73c99935 | ||
|
|
ab2c99acf3 | ||
|
|
a506e9b9eb | ||
|
|
c0c10689a1 | ||
|
|
c4dcf064d5 | ||
|
|
d9771d0f88 | ||
|
|
f25b2a2094 | ||
|
|
c9934c142d | ||
|
|
fb7a8cae33 | ||
|
|
ae5c7b19f6 | ||
|
|
a5abe3d813 | ||
|
|
b373a9ed22 | ||
|
|
09966fb291 | ||
|
|
d4bb62d055 | ||
|
|
bbeb9d3950 | ||
|
|
ce84d9c84d | ||
|
|
ed4dea2b0e | ||
|
|
4d4a349f09 | ||
|
|
7430fbacfd | ||
|
|
d624e2ef65 | ||
|
|
0e72dc3974 | ||
|
|
68b0a85369 | ||
|
|
5794679277 | ||
|
|
74c21039b3 | ||
|
|
267e5fd9e0 | ||
|
|
e681b0d95a | ||
|
|
a2695ea0d7 | ||
|
|
c0df6f7bca | ||
|
|
c587335ae1 | ||
|
|
16e1c740ce | ||
|
|
6786d44b69 | ||
|
|
cd8c9a58df | ||
|
|
ecbbdd5e74 | ||
|
|
a8a85b2acf | ||
|
|
8ba77defeb | ||
|
|
84e8053cd0 | ||
|
|
506cd8c7ad | ||
|
|
f8783c3bfc | ||
|
|
b24e5ce809 | ||
|
|
18901a4dc7 | ||
|
|
81e08599dc | ||
|
|
7edc91e29e | ||
|
|
50265afe93 | ||
|
|
4d8ac05d28 | ||
|
|
22aa57ad6f | ||
|
|
5bea88fd66 | ||
|
|
361e3565d4 | ||
|
|
fb579f1c10 | ||
|
|
f66d7088ef | ||
|
|
ccd440ea0b | ||
|
|
f41abe0a28 | ||
|
|
cfd16c6f67 | ||
|
|
ef1d98f3cf | ||
|
|
bc43168ca7 | ||
|
|
b670ca2a51 | ||
|
|
4d093f78e2 | ||
|
|
02e9b8fd18 | ||
|
|
02517f7221 | ||
|
|
2734cab3f2 | ||
|
|
2509f05e28 | ||
|
|
8fee156d21 | ||
|
|
e493ab12dc | ||
|
|
4d9c9bbd6f | ||
|
|
c7c145b226 | ||
|
|
504f5ee5d7 | ||
|
|
3d54192681 | ||
|
|
db0da70de6 | ||
|
|
59e6fd9989 | ||
|
|
b24cba99e2 | ||
|
|
d6848c49e8 | ||
|
|
5d1601d9c9 | ||
|
|
2c6a9614b2 | ||
|
|
cc736158a6 | ||
|
|
817610ddd7 | ||
|
|
77c8ca76b7 | ||
|
|
67cbe61879 | ||
|
|
67eba93e29 | ||
|
|
b918170464 | ||
|
|
a27a54798c | ||
|
|
5f1d56fbc2 | ||
|
|
1fc24398a0 | ||
|
|
99b7f051c7 | ||
|
|
658671089e | ||
|
|
092b6e7c18 | ||
|
|
23272430b4 | ||
|
|
a29ff093f6 | ||
|
|
37a8afaddf | ||
|
|
b08c33cf8a | ||
|
|
a2f8546033 | ||
|
|
580a12ad7f | ||
|
|
d77df9905f | ||
|
|
82f92cffd3 | ||
|
|
8042a83fd2 | ||
|
|
b38d6667c4 | ||
|
|
72704b2426 | ||
|
|
3e379f3171 | ||
|
|
54685155b0 | ||
|
|
54f06740d5 | ||
|
|
204dd0a869 | ||
|
|
8142acc709 | ||
|
|
df70fd3081 | ||
|
|
97d8ee75d5 | ||
|
|
f9bba75395 | ||
|
|
9b88f816d6 | ||
|
|
28c918a36a | ||
|
|
b638650b41 | ||
|
|
2d8e6f9745 | ||
|
|
627426f604 | ||
|
|
7b80514986 |
21
.github/lock.yml
vendored
@@ -1,21 +0,0 @@
|
||||
# Number of days of inactivity before a closed issue or pull request is locked
|
||||
daysUntilLock: 45
|
||||
|
||||
# Skip issues and pull requests created before a given timestamp. Timestamp must
|
||||
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
|
||||
skipCreatedBefore: false
|
||||
|
||||
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
|
||||
exemptLabels: []
|
||||
|
||||
# Label to add before locking, such as `outdated`. Set to `false` to disable
|
||||
lockLabel: false
|
||||
|
||||
# Comment to post before locking. Set to `false` to disable
|
||||
lockComment: >
|
||||
This thread has been automatically locked since there has not been
|
||||
any recent activity after it was closed. Please open a new issue for
|
||||
related bugs.
|
||||
|
||||
# Assign `resolved` as the reason for locking. Set to `false` to disable
|
||||
setLockReason: true
|
||||
23
.github/workflows/lock.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: 'Lock Threads'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 * * * *'
|
||||
|
||||
jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v2
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-lock-inactive-days: 45
|
||||
pr-lock-inactive-days: 45
|
||||
issue-lock-comment: >
|
||||
This issue has been automatically locked since there
|
||||
has not been any recent activity after it was closed.
|
||||
Please open a new issue for related bugs.
|
||||
pr-lock-comment: >
|
||||
This pull request has been automatically locked since there
|
||||
has not been any recent activity after it was closed.
|
||||
Please open a new issue for related bugs.
|
||||
30
.github/workflows/mac.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
||||
GIT: "https://github.com"
|
||||
PREFIX: "/usr/local/macos"
|
||||
MACOSX_DEPLOYMENT_TARGET: "10.12"
|
||||
XZ: "xz-5.2.4"
|
||||
XZ: "xz-5.2.5"
|
||||
QT: "5_15_2"
|
||||
OPENSSL_VER: "1_1_1"
|
||||
QT_PREFIX: "/usr/local/desktop-app/Qt-5.15.2"
|
||||
@@ -83,6 +83,9 @@ jobs:
|
||||
brew install automake fdk-aac lame libass libtool libvorbis libvpx \
|
||||
ninja opus sdl shtool texi2html theora x264 xvid yasm pkg-config
|
||||
|
||||
# Disable spotlight.
|
||||
sudo mdutil -a -i off
|
||||
|
||||
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
|
||||
|
||||
xcodebuild -version > CACHE_KEY.txt
|
||||
@@ -142,7 +145,7 @@ jobs:
|
||||
cd mozjpeg
|
||||
cmake -B build . \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr/local/macos \
|
||||
-DCMAKE_INSTALL_PREFIX=$PREFIX \
|
||||
-DWITH_JPEG8=ON \
|
||||
-DPNG_SUPPORTED=OFF
|
||||
cmake --build build -j$(nproc)
|
||||
@@ -350,7 +353,7 @@ jobs:
|
||||
- name: FFmpeg install.
|
||||
run: |
|
||||
cd $LibrariesPath
|
||||
#List of files from cmake/external/ffmpeg/CMakeLists.txt.
|
||||
# List of files from cmake/external/ffmpeg/CMakeLists.txt.
|
||||
copyLib() {
|
||||
mkdir -p ffmpeg/$1
|
||||
\cp -fR ffmpeg-cache/lib/$1.a ffmpeg/$1/$1.a
|
||||
@@ -361,17 +364,15 @@ jobs:
|
||||
copyLib libswscale
|
||||
copyLib libavutil
|
||||
|
||||
sudo cp -R ffmpeg-cache/. /usr/local/
|
||||
sudo cp -R ffmpeg-cache/. $PREFIX
|
||||
sudo cp -R ffmpeg-cache/include/. ffmpeg/
|
||||
|
||||
- name: OpenAL Soft.
|
||||
run: |
|
||||
cd $LibrariesPath
|
||||
|
||||
git clone $GIT/kcat/openal-soft.git
|
||||
cd openal-soft
|
||||
git checkout 3970252da9
|
||||
cd build
|
||||
git clone --branch capture_with_webrtc $GIT/telegramdesktop/openal-soft.git
|
||||
cd openal-soft/build
|
||||
|
||||
CFLAGS="$UNGUARDED" CPPFLAGS="$UNGUARDED" cmake \
|
||||
-D CMAKE_INSTALL_PREFIX:PATH=$PREFIX \
|
||||
@@ -462,9 +463,9 @@ jobs:
|
||||
-nomake examples \
|
||||
-nomake tests \
|
||||
-platform macx-clang \
|
||||
-I "/usr/local/macos/include" \
|
||||
LIBJPEG_LIBS="/usr/local/macos/lib/libjpeg.a" \
|
||||
ZLIB_LIBS="/usr/local/macos/lib/libz.a"
|
||||
-I "$PREFIX/include" \
|
||||
LIBJPEG_LIBS="$PREFIX/lib/libjpeg.a" \
|
||||
ZLIB_LIBS="$PREFIX/lib/libz.a"
|
||||
|
||||
make -j$(nproc)
|
||||
sudo make install
|
||||
@@ -486,12 +487,13 @@ jobs:
|
||||
git clone --recursive $GIT/desktop-app/tg_owt.git
|
||||
mkdir -p tg_owt/out/Debug
|
||||
cd tg_owt/out/Debug
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug \
|
||||
cmake -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DTG_OWT_SPECIAL_TARGET=mac \
|
||||
-DTG_OWT_LIBJPEG_INCLUDE_PATH=/usr/local/macos/include \
|
||||
-DTG_OWT_LIBJPEG_INCLUDE_PATH=$PREFIX/include \
|
||||
-DTG_OWT_OPENSSL_INCLUDE_PATH=`pwd`/../../../openssl_$OPENSSL_VER/include \
|
||||
-DTG_OWT_OPUS_INCLUDE_PATH=$PREFIX/include/opus \
|
||||
-DTG_OWT_FFMPEG_INCLUDE_PATH=/usr/local/include \
|
||||
-DTG_OWT_FFMPEG_INCLUDE_PATH=$PREFIX/include \
|
||||
../..
|
||||
ninja
|
||||
|
||||
|
||||
3
.github/workflows/win.yml
vendored
@@ -128,7 +128,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Find any version of Python 2."
|
||||
p=`ls /c/hostedtoolcache/windows/python | grep 2 | tail -1`
|
||||
p=`ls /c/hostedtoolcache/windows/python | grep "^2" | tail -1`
|
||||
if [ -z "$p" ]; then
|
||||
echo "Python 2 is not found."
|
||||
exit 1
|
||||
@@ -409,6 +409,7 @@ jobs:
|
||||
-D TDESKTOP_API_TEST=ON ^
|
||||
-D DESKTOP_APP_USE_PACKAGED=OFF ^
|
||||
-D DESKTOP_APP_DISABLE_CRASH_REPORTS=OFF ^
|
||||
-D DESKTOP_APP_NO_PDB=ON ^
|
||||
%TDESKTOP_BUILD_DEFINE% ^
|
||||
-DCMAKE_SYSTEM_VERSION=%SDK%
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ PRIVATE
|
||||
if (LINUX)
|
||||
target_link_libraries(Telegram
|
||||
PRIVATE
|
||||
desktop-app::external_glibmm
|
||||
desktop-app::external_glib
|
||||
)
|
||||
|
||||
@@ -262,11 +263,15 @@ PRIVATE
|
||||
calls/calls_box_controller.h
|
||||
calls/calls_call.cpp
|
||||
calls/calls_call.h
|
||||
calls/calls_choose_join_as.cpp
|
||||
calls/calls_choose_join_as.h
|
||||
calls/calls_group_call.cpp
|
||||
calls/calls_group_call.h
|
||||
calls/calls_group_common.h
|
||||
calls/calls_group_members.cpp
|
||||
calls/calls_group_members.h
|
||||
calls/calls_group_menu.cpp
|
||||
calls/calls_group_menu.h
|
||||
calls/calls_group_panel.cpp
|
||||
calls/calls_group_panel.h
|
||||
calls/calls_group_settings.cpp
|
||||
@@ -388,8 +393,6 @@ PRIVATE
|
||||
data/data_drafts.h
|
||||
data/data_folder.cpp
|
||||
data/data_folder.h
|
||||
# data/data_feed_messages.cpp
|
||||
# data/data_feed_messages.h
|
||||
data/data_file_origin.cpp
|
||||
data/data_file_origin.h
|
||||
data/data_flags.h
|
||||
@@ -490,8 +493,6 @@ PRIVATE
|
||||
history/admin_log/history_admin_log_item.h
|
||||
history/admin_log/history_admin_log_section.cpp
|
||||
history/admin_log/history_admin_log_section.h
|
||||
# history/feed/history_feed_section.cpp
|
||||
# history/feed/history_feed_section.h
|
||||
history/view/controls/compose_controls_common.h
|
||||
history/view/controls/history_view_compose_controls.cpp
|
||||
history/view/controls/history_view_compose_controls.h
|
||||
@@ -610,22 +611,10 @@ PRIVATE
|
||||
info/info_top_bar.h
|
||||
info/info_wrap_widget.cpp
|
||||
info/info_wrap_widget.h
|
||||
# info/channels/info_channels_widget.cpp
|
||||
# info/channels/info_channels_widget.h
|
||||
info/common_groups/info_common_groups_inner_widget.cpp
|
||||
info/common_groups/info_common_groups_inner_widget.h
|
||||
info/common_groups/info_common_groups_widget.cpp
|
||||
info/common_groups/info_common_groups_widget.h
|
||||
# info/feed/info_feed_channels.cpp
|
||||
# info/feed/info_feed_channels.h
|
||||
# info/feed/info_feed_channels_controllers.cpp
|
||||
# info/feed/info_feed_channels_controllers.h
|
||||
# info/feed/info_feed_cover.cpp
|
||||
# info/feed/info_feed_cover.h
|
||||
# info/feed/info_feed_profile_inner_widget.cpp
|
||||
# info/feed/info_feed_profile_inner_widget.h
|
||||
# info/feed/info_feed_profile_widget.cpp
|
||||
# info/feed/info_feed_profile_widget.h
|
||||
info/media/info_media_buttons.h
|
||||
info/media/info_media_empty_widget.cpp
|
||||
info/media/info_media_empty_widget.h
|
||||
@@ -830,14 +819,16 @@ PRIVATE
|
||||
platform/linux/linux_gtk_integration_p.h
|
||||
platform/linux/linux_gtk_integration.cpp
|
||||
platform/linux/linux_gtk_integration.h
|
||||
platform/linux/linux_gtk_open_with_dialog.cpp
|
||||
platform/linux/linux_gtk_open_with_dialog.h
|
||||
platform/linux/linux_notification_service_watcher.cpp
|
||||
platform/linux/linux_notification_service_watcher.h
|
||||
platform/linux/linux_open_with_dialog.cpp
|
||||
platform/linux/linux_open_with_dialog.h
|
||||
platform/linux/linux_wayland_integration.cpp
|
||||
platform/linux/linux_wayland_integration.h
|
||||
platform/linux/linux_xdp_file_dialog.cpp
|
||||
platform/linux/linux_xdp_file_dialog.h
|
||||
platform/linux/linux_xdp_open_with_dialog.cpp
|
||||
platform/linux/linux_xdp_open_with_dialog.h
|
||||
platform/linux/file_utilities_linux.cpp
|
||||
platform/linux/file_utilities_linux.h
|
||||
platform/linux/launcher_linux.cpp
|
||||
@@ -976,8 +967,6 @@ PRIVATE
|
||||
storage/storage_domain.h
|
||||
storage/storage_facade.cpp
|
||||
storage/storage_facade.h
|
||||
# storage/storage_feed_messages.cpp
|
||||
# storage/storage_feed_messages.h
|
||||
storage/storage_media_prepare.cpp
|
||||
storage/storage_media_prepare.h
|
||||
storage/storage_shared_media.cpp
|
||||
@@ -1128,6 +1117,8 @@ if (DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
|
||||
platform/linux/linux_notification_service_watcher.h
|
||||
platform/linux/linux_xdp_file_dialog.cpp
|
||||
platform/linux/linux_xdp_file_dialog.h
|
||||
platform/linux/linux_xdp_open_with_dialog.cpp
|
||||
platform/linux/linux_xdp_open_with_dialog.h
|
||||
platform/linux/notifications_manager_linux.cpp
|
||||
)
|
||||
|
||||
@@ -1150,8 +1141,8 @@ if (DESKTOP_APP_DISABLE_GTK_INTEGRATION)
|
||||
platform/linux/linux_gtk_file_dialog.h
|
||||
platform/linux/linux_gtk_integration_p.h
|
||||
platform/linux/linux_gtk_integration.cpp
|
||||
platform/linux/linux_open_with_dialog.cpp
|
||||
platform/linux/linux_open_with_dialog.h
|
||||
platform/linux/linux_gtk_open_with_dialog.cpp
|
||||
platform/linux/linux_gtk_open_with_dialog.h
|
||||
)
|
||||
|
||||
nice_target_sources(Telegram ${src_loc}
|
||||
|
||||
1
Telegram/Resources/icons/calls/active_hand.json
Normal file
|
Before Width: | Height: | Size: 718 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
BIN
Telegram/Resources/icons/calls/group_calls_raised_hand.png
Normal file
|
After Width: | Height: | Size: 1008 B |
BIN
Telegram/Resources/icons/calls/group_calls_raised_hand@2x.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
Telegram/Resources/icons/calls/group_calls_raised_hand@3x.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
1
Telegram/Resources/icons/calls/hand_muted_active.json
Normal file
1
Telegram/Resources/icons/calls/raised_hand.json
Normal file
|
Before Width: | Height: | Size: 328 B |
|
Before Width: | Height: | Size: 626 B |
|
Before Width: | Height: | Size: 841 B |
|
Before Width: | Height: | Size: 748 B |
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1923,12 +1923,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_group_call_title" = "Voice Chat";
|
||||
"lng_group_call_active" = "speaking";
|
||||
"lng_group_call_inactive" = "listening";
|
||||
"lng_group_call_raised_hand_status" = "wants to speak";
|
||||
"lng_group_call_settings" = "Settings";
|
||||
"lng_group_call_unmute" = "Unmute";
|
||||
"lng_group_call_unmute_sub" = "or hold spacebar to talk";
|
||||
"lng_group_call_you_are_live" = "You are Live";
|
||||
"lng_group_call_force_muted" = "Muted by admin";
|
||||
"lng_group_call_force_muted_sub" = "You are in Listen Only mode";
|
||||
"lng_group_call_raise_hand_tip" = "Click if you want to speak";
|
||||
"lng_group_call_raised_hand" = "You asked to speak";
|
||||
"lng_group_call_raised_hand_sub" = "We let the speakers know";
|
||||
"lng_group_call_connecting" = "Connecting...";
|
||||
"lng_group_call_leave" = "Leave";
|
||||
"lng_group_call_leave_title" = "Leave voice chat";
|
||||
@@ -1947,7 +1951,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_group_call_add_to_group_all" = "Those users aren't members of «{group}» yet. Add them to the group?";
|
||||
"lng_group_call_invite_members" = "Group members";
|
||||
"lng_group_call_invite_search_results" = "Search results";
|
||||
"lng_group_call_new_muted" = "Mute new members";
|
||||
"lng_group_call_new_muted" = "Mute new participants";
|
||||
"lng_group_call_speakers" = "Speakers";
|
||||
"lng_group_call_microphone" = "Microphone";
|
||||
"lng_group_call_push_to_talk" = "Push to Talk Shortcut";
|
||||
@@ -1957,8 +1961,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_group_call_ptt_delay_s" = "{amount}s";
|
||||
"lng_group_call_ptt_delay" = "Push to Talk release delay: {delay}";
|
||||
"lng_group_call_share" = "Share Invite Link";
|
||||
"lng_group_call_share_speaker" = "Users with this link can speak";
|
||||
"lng_group_call_copy_speaker_link" = "Copy Speaker Link";
|
||||
"lng_group_call_copy_listener_link" = "Copy Listener Link";
|
||||
"lng_group_call_end" = "End Voice Chat";
|
||||
"lng_group_call_join" = "Join";
|
||||
"lng_group_call_join_confirm" = "Do you want to join the voice chat {chat}?";
|
||||
"lng_group_call_invite_done_user" = "You invited {user} to the voice chat.";
|
||||
"lng_group_call_invite_done_many#one" = "You invited **{count} member** to the voice chat.";
|
||||
"lng_group_call_invite_done_many#other" = "You invited **{count} members** to the voice chat.";
|
||||
@@ -1969,6 +1977,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_group_call_too_many" = "Sorry, there are too many members in this voice chat. Please try again later.";
|
||||
"lng_group_call_context_mute" = "Mute";
|
||||
"lng_group_call_context_unmute" = "Allow to speak";
|
||||
"lng_group_call_context_remove_hand" = "Cancel request to speak";
|
||||
"lng_group_call_context_mute_for_me" = "Mute for me";
|
||||
"lng_group_call_context_unmute_for_me" = "Unmute for me";
|
||||
"lng_group_call_duration_days#one" = "{count} day";
|
||||
@@ -1984,6 +1993,29 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_group_call_mac_accessibility" = "Please allow **Accessibility** for Telegram in Privacy Settings.\n\nApp restart may be required.";
|
||||
"lng_group_call_mac_settings" = "Open Settings";
|
||||
|
||||
"lng_group_call_start_as_header" = "Start Voice Chat as...";
|
||||
"lng_group_call_join_as_header" = "Join Voice Chat as...";
|
||||
"lng_group_call_display_as_header" = "Display me as...";
|
||||
"lng_group_call_join_as_about" = "Choose whether you want to be displayed as your personal account or as your channel.";
|
||||
"lng_group_call_join_as_personal" = "personal account";
|
||||
"lng_group_call_edit_title" = "Edit voice chat title";
|
||||
"lng_group_call_switch_done" = "Members of this voice chat will now see you as **{user}**";
|
||||
"lng_group_call_edit_title_header" = "Voice chat title";
|
||||
"lng_group_call_recording_start" = "Start recording";
|
||||
"lng_group_call_recording_stop" = "Stop recording";
|
||||
"lng_group_call_recording_started" = "Voice chat recording started.";
|
||||
"lng_group_call_recording_stopped" = "Voice chat recording stopped.";
|
||||
"lng_group_call_recording_saved" = "Audio saved to Saved Messages.";
|
||||
"lng_group_call_recording_start_sure" = "Do you want to start recording this chat and save the result into an audio file?\n\nOther members will see the chat is being recorded.";
|
||||
"lng_group_call_recording_stop_sure" = "Do you want to stop recording this chat?";
|
||||
"lng_group_call_recording_start_field" = "Recording Title";
|
||||
"lng_group_call_recording_start_button" = "Start";
|
||||
"lng_group_call_is_recorded" = "Voice chat is being recorded.";
|
||||
"lng_group_call_can_speak_here" = "You can now speak.";
|
||||
"lng_group_call_can_speak" = "You can now speak in {chat}.";
|
||||
"lng_group_call_title_changed" = "Voice chat title changed to {title}";
|
||||
"lng_group_call_join_as_changed" = "Members of this voice chat will now see you as {name}";
|
||||
|
||||
"lng_no_mic_permission" = "Telegram needs access to your microphone so that you can make calls and record voice messages.";
|
||||
|
||||
"lng_player_message_today" = "Today at {time}";
|
||||
@@ -2238,34 +2270,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_admin_log_admin_manage_calls" = "Manage voice chats";
|
||||
"lng_admin_log_admin_add_admins" = "Add new admins";
|
||||
|
||||
// #feed
|
||||
//"lng_feed_name" = "Feed";
|
||||
//"lng_feed_show_next" = "Show Next";
|
||||
|
||||
//"lng_feed_group" = "Group in feed";
|
||||
//"lng_feed_ungroup" = "Ungroup from feed";
|
||||
//"lng_feed_channel_added" = "Channel added to your feed.";
|
||||
//"lng_feed_channel_removed" = "Channel removed from your feed.";
|
||||
//"lng_feed_no_messages" = "No messages in this feed yet";
|
||||
//"lng_feed_channels#one" = "{count} channel";
|
||||
//"lng_feed_channels#other" = "{count} channels";
|
||||
//"lng_feed_notifications" = "Feed notifications";
|
||||
//"lng_feed_ungroup_all" = "Ungroup all channels";
|
||||
//"lng_feed_sure_ungroup_all" = "Are you sure you want to ungroup all channels from this feed?";
|
||||
//"lng_feed_ungroup_sure" = "Ungroup";
|
||||
//"lng_feed_create_new" = "New feed";
|
||||
//"lng_feed_too_few_channels#one" = "You need at least {count} channel to create a feed.";
|
||||
//"lng_feed_too_few_channels#other" = "You need at least {count} channels to create a feed.";
|
||||
//"lng_feed_select_more_channels#one" = "Select {count} channel or more.";
|
||||
//"lng_feed_select_more_channels#other" = "Select {count} channels or more.";
|
||||
//"lng_feed_create" = "Create";
|
||||
//"lng_feed_edit_title" = "Edit feed";
|
||||
//"lng_feed_channels_not_found" = "No channels found";
|
||||
|
||||
//"lng_info_feed_title" = "Feed Info";
|
||||
//"lng_info_feed_is_default" = "Group new channels";
|
||||
//"lng_info_feed_channels" = "Channels";
|
||||
|
||||
"lng_terms_signup" = "By signing up,\nyou agree to the {link}.";
|
||||
"lng_terms_signup_link" = "Terms of Service";
|
||||
"lng_terms_header" = "Terms of Service";
|
||||
|
||||
@@ -9,5 +9,6 @@
|
||||
<file alias="group_call_start.mp3">../../sounds/group_call_start.mp3</file>
|
||||
<file alias="group_call_connect.mp3">../../sounds/group_call_connect.mp3</file>
|
||||
<file alias="group_call_end.mp3">../../sounds/group_call_end.mp3</file>
|
||||
<file alias="group_call_allowed.mp3">../../sounds/group_call_allowed.mp3</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -59,6 +59,9 @@
|
||||
<file alias="day-blue.tdesktop-theme">../../day-blue.tdesktop-theme</file>
|
||||
<file alias="night.tdesktop-theme">../../night.tdesktop-theme</file>
|
||||
<file alias="night-green.tdesktop-theme">../../night-green.tdesktop-theme</file>
|
||||
<file alias="icons/calls/active_hand.json">../../icons/calls/active_hand.json</file>
|
||||
<file alias="icons/calls/hand_muted_active.json">../../icons/calls/hand_muted_active.json</file>
|
||||
<file alias="icons/calls/raised_hand.json">../../icons/calls/raised_hand.json</file>
|
||||
</qresource>
|
||||
<qresource prefix="/qt-project.org">
|
||||
<file>../qmime/freedesktop.org.xml</file>
|
||||
|
||||
BIN
Telegram/Resources/sounds/group_call_allowed.mp3
Normal file
@@ -92,6 +92,7 @@ inputPhotoFileLocation#40181ffe id:long access_hash:long file_reference:bytes th
|
||||
inputPhotoLegacyFileLocation#d83466f3 id:long access_hash:long file_reference:bytes volume_id:long local_id:int secret:long = InputFileLocation;
|
||||
inputPeerPhotoFileLocation#27d69997 flags:# big:flags.0?true peer:InputPeer volume_id:long local_id:int = InputFileLocation;
|
||||
inputStickerSetThumb#dbaeae9 stickerset:InputStickerSet volume_id:long local_id:int = InputFileLocation;
|
||||
inputGroupCallStream#bba51639 call:InputGroupCall time_ms:long scale:int = InputFileLocation;
|
||||
|
||||
peerUser#9db1bc6d user_id:int = Peer;
|
||||
peerChat#bad0e5bb chat_id:int = Peer;
|
||||
@@ -127,8 +128,8 @@ chatForbidden#7328bdb id:int title:string = Chat;
|
||||
channel#d31a961e flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
|
||||
channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
|
||||
chatFull#f06c4018 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:int 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 = ChatFull;
|
||||
channelFull#2548c037 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 id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?int 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> = ChatFull;
|
||||
chatFull#8a1e2983 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:int 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 = ChatFull;
|
||||
channelFull#548c3f93 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 id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?int 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 = ChatFull;
|
||||
|
||||
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
|
||||
chatParticipantCreator#da13538a user_id:int = ChatParticipant;
|
||||
@@ -286,7 +287,7 @@ updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
|
||||
updateMessageID#4e90bfd6 id:int random_id:long = Update;
|
||||
updateDeleteMessages#a20db0e5 messages:Vector<int> pts:int pts_count:int = Update;
|
||||
updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
|
||||
updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update;
|
||||
updateChatUserTyping#86cadb6c chat_id:int from_id:Peer action:SendMessageAction = Update;
|
||||
updateChatParticipants#7761198 participants:ChatParticipants = Update;
|
||||
updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
|
||||
updateUserName#a7332b73 user_id:int first_name:string last_name:string username:string = Update;
|
||||
@@ -363,16 +364,16 @@ updateChannelMessageForwards#6e8a84df channel_id:int id:int forwards:int = Updat
|
||||
updateReadChannelDiscussionInbox#1cc7de54 flags:# channel_id:int top_msg_id:int read_max_id:int broadcast_id:flags.0?int broadcast_post:flags.0?int = Update;
|
||||
updateReadChannelDiscussionOutbox#4638a26c channel_id:int top_msg_id:int read_max_id:int = Update;
|
||||
updatePeerBlocked#246a4b22 peer_id:Peer blocked:Bool = Update;
|
||||
updateChannelUserTyping#ff2abe9f flags:# channel_id:int top_msg_id:flags.0?int user_id:int action:SendMessageAction = Update;
|
||||
updateChannelUserTyping#6b171718 flags:# channel_id:int top_msg_id:flags.0?int from_id:Peer action:SendMessageAction = Update;
|
||||
updatePinnedMessages#ed85eab5 flags:# pinned:flags.0?true peer:Peer messages:Vector<int> pts:int pts_count:int = Update;
|
||||
updatePinnedChannelMessages#8588878b flags:# pinned:flags.0?true channel_id:int messages:Vector<int> pts:int pts_count:int = Update;
|
||||
updateChat#1330a196 chat_id:int = Update;
|
||||
updateGroupCallParticipants#f2ebdb4e call:InputGroupCall participants:Vector<GroupCallParticipant> version:int = Update;
|
||||
updateGroupCall#a45eb99b chat_id:int call:GroupCall = Update;
|
||||
updatePeerHistoryTTL#bb9bb9a5 flags:# peer:Peer ttl_period:flags.0?int = Update;
|
||||
updateChatParticipant#609a6ed4 flags:# chat_id:int date:int user_id:int prev_participant:flags.0?ChatParticipant new_participant:flags.1?ChatParticipant qts:int = Update;
|
||||
updateChannelParticipant#65d2b464 flags:# channel_id:int date:int user_id:int prev_participant:flags.0?ChannelParticipant new_participant:flags.1?ChannelParticipant qts:int = Update;
|
||||
updateBotStopped#30ec6ebc user_id:int stopped:Bool qts:int = Update;
|
||||
updateChatParticipant#f3b3781f flags:# chat_id:int date:int actor_id:int user_id:int prev_participant:flags.0?ChatParticipant new_participant:flags.1?ChatParticipant invite:flags.2?ExportedChatInvite qts:int = Update;
|
||||
updateChannelParticipant#7fecb1ec flags:# channel_id:int date:int actor_id:int user_id:int prev_participant:flags.0?ChannelParticipant new_participant:flags.1?ChannelParticipant invite:flags.2?ExportedChatInvite qts:int = Update;
|
||||
updateBotStopped#7f9488a user_id:int date:int stopped:Bool qts:int = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
@@ -1202,15 +1203,15 @@ peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked;
|
||||
stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats;
|
||||
|
||||
groupCallDiscarded#7780bcb4 id:long access_hash:long duration:int = GroupCall;
|
||||
groupCall#55903081 flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true id:long access_hash:long participants_count:int params:flags.0?DataJSON version:int = GroupCall;
|
||||
groupCall#c0c2052e flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true id:long access_hash:long participants_count:int params:flags.0?DataJSON title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int version:int = GroupCall;
|
||||
|
||||
inputGroupCall#d8aa840f id:long access_hash:long = InputGroupCall;
|
||||
|
||||
groupCallParticipant#64c62a15 flags:# muted:flags.0?true left:flags.1?true can_self_unmute:flags.2?true just_joined:flags.4?true versioned:flags.5?true min:flags.8?true muted_by_you:flags.9?true volume_by_admin:flags.10?true user_id:int date:int active_date:flags.3?int source:int volume:flags.7?int = GroupCallParticipant;
|
||||
groupCallParticipant#19adba89 flags:# muted:flags.0?true left:flags.1?true can_self_unmute:flags.2?true just_joined:flags.4?true versioned:flags.5?true min:flags.8?true muted_by_you:flags.9?true volume_by_admin:flags.10?true self:flags.12?true peer:Peer date:int active_date:flags.3?int source:int volume:flags.7?int about:flags.11?string raise_hand_rating:flags.13?long = GroupCallParticipant;
|
||||
|
||||
phone.groupCall#66ab0bfc call:GroupCall participants:Vector<GroupCallParticipant> participants_next_offset:string users:Vector<User> = phone.GroupCall;
|
||||
phone.groupCall#9e727aad call:GroupCall participants:Vector<GroupCallParticipant> participants_next_offset:string chats:Vector<Chat> users:Vector<User> = phone.GroupCall;
|
||||
|
||||
phone.groupParticipants#9cfeb92d count:int participants:Vector<GroupCallParticipant> next_offset:string users:Vector<User> version:int = phone.GroupParticipants;
|
||||
phone.groupParticipants#f47751b6 count:int participants:Vector<GroupCallParticipant> next_offset:string chats:Vector<Chat> users:Vector<User> version:int = phone.GroupParticipants;
|
||||
|
||||
inlineQueryPeerTypeSameBotPM#3081ed9d = InlineQueryPeerType;
|
||||
inlineQueryPeerTypePM#833c0fac = InlineQueryPeerType;
|
||||
@@ -1237,6 +1238,12 @@ chatAdminWithInvites#dfd2330f admin_id:int invites_count:int revoked_invites_cou
|
||||
|
||||
messages.chatAdminsWithInvites#b69b72d7 admins:Vector<ChatAdminWithInvites> users:Vector<User> = messages.ChatAdminsWithInvites;
|
||||
|
||||
messages.checkedHistoryImportPeer#a24de717 confirm_text:string = messages.CheckedHistoryImportPeer;
|
||||
|
||||
phone.joinAsPeers#afe5623f peers:Vector<Peer> chats:Vector<Chat> users:Vector<User> = phone.JoinAsPeers;
|
||||
|
||||
phone.exportedGroupCallInvite#204bd158 link:string = phone.ExportedGroupCallInvite;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@@ -1469,8 +1476,8 @@ messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int =
|
||||
messages.getEmojiKeywordsLanguages#4e9963b2 lang_codes:Vector<string> = Vector<EmojiLanguage>;
|
||||
messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL;
|
||||
messages.getSearchCounters#732eef00 peer:InputPeer filters:Vector<MessagesFilter> = Vector<messages.SearchCounter>;
|
||||
messages.requestUrlAuth#e33f5613 peer:InputPeer msg_id:int button_id:int = UrlAuthResult;
|
||||
messages.acceptUrlAuth#f729ea98 flags:# write_allowed:flags.0?true peer:InputPeer msg_id:int button_id:int = UrlAuthResult;
|
||||
messages.requestUrlAuth#198fb446 flags:# peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult;
|
||||
messages.acceptUrlAuth#b12c7125 flags:# write_allowed:flags.0?true peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult;
|
||||
messages.hidePeerSettingsBar#4facb138 peer:InputPeer = Bool;
|
||||
messages.getScheduledHistory#e2c2685b peer:InputPeer hash:int = messages.Messages;
|
||||
messages.getScheduledMessages#bdbb0464 peer:InputPeer id:Vector<int> = messages.Messages;
|
||||
@@ -1494,12 +1501,14 @@ messages.initHistoryImport#34090c3b peer:InputPeer file:InputFile media_count:in
|
||||
messages.uploadImportedMedia#2a862092 peer:InputPeer import_id:long file_name:string media:InputMedia = MessageMedia;
|
||||
messages.startHistoryImport#b43df344 peer:InputPeer import_id:long = Bool;
|
||||
messages.getExportedChatInvites#a2b5a3f6 flags:# revoked:flags.3?true peer:InputPeer admin_id:InputUser offset_date:flags.2?int offset_link:flags.2?string limit:int = messages.ExportedChatInvites;
|
||||
messages.getExportedChatInvite#73746f5c peer:InputPeer link:string = messages.ExportedChatInvite;
|
||||
messages.editExportedChatInvite#2e4ffbe flags:# revoked:flags.2?true peer:InputPeer link:string expire_date:flags.0?int usage_limit:flags.1?int = messages.ExportedChatInvite;
|
||||
messages.deleteRevokedExportedChatInvites#56987bd5 peer:InputPeer admin_id:InputUser = Bool;
|
||||
messages.deleteExportedChatInvite#d464a42b peer:InputPeer link:string = Bool;
|
||||
messages.getAdminsWithInvites#3920e6ef peer:InputPeer = messages.ChatAdminsWithInvites;
|
||||
messages.getChatInviteImporters#26fb7289 peer:InputPeer link:string offset_date:int offset_user:InputUser limit:int = messages.ChatInviteImporters;
|
||||
messages.setHistoryTTL#b80e5fe4 peer:InputPeer period:int = Updates;
|
||||
messages.checkHistoryImportPeer#5dc60f03 peer:InputPeer = messages.CheckedHistoryImportPeer;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
@@ -1607,15 +1616,19 @@ phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhon
|
||||
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
|
||||
phone.sendSignalingData#ff7a9383 peer:InputPhoneCall data:bytes = Bool;
|
||||
phone.createGroupCall#bd3dabe0 peer:InputPeer random_id:int = Updates;
|
||||
phone.joinGroupCall#5f9c8e62 flags:# muted:flags.0?true call:InputGroupCall params:DataJSON = Updates;
|
||||
phone.joinGroupCall#b132ff7b flags:# muted:flags.0?true call:InputGroupCall join_as:InputPeer invite_hash:flags.1?string params:DataJSON = Updates;
|
||||
phone.leaveGroupCall#500377f9 call:InputGroupCall source:int = Updates;
|
||||
phone.editGroupCallMember#a5e76cd8 flags:# muted:flags.0?true call:InputGroupCall user_id:InputUser volume:flags.1?int = Updates;
|
||||
phone.inviteToGroupCall#7b393160 call:InputGroupCall users:Vector<InputUser> = Updates;
|
||||
phone.discardGroupCall#7a777135 call:InputGroupCall = Updates;
|
||||
phone.toggleGroupCallSettings#74bbb43d flags:# call:InputGroupCall join_muted:flags.0?Bool = Updates;
|
||||
phone.toggleGroupCallSettings#74bbb43d flags:# reset_invite_hash:flags.1?true call:InputGroupCall join_muted:flags.0?Bool = Updates;
|
||||
phone.getGroupCall#c7cb017 call:InputGroupCall = phone.GroupCall;
|
||||
phone.getGroupParticipants#c9f1d285 call:InputGroupCall ids:Vector<int> sources:Vector<int> offset:string limit:int = phone.GroupParticipants;
|
||||
phone.getGroupParticipants#c558d8ab call:InputGroupCall ids:Vector<InputPeer> sources:Vector<int> offset:string limit:int = phone.GroupParticipants;
|
||||
phone.checkGroupCall#b74a7bea call:InputGroupCall source:int = Bool;
|
||||
phone.toggleGroupCallRecord#c02a66d7 flags:# start:flags.0?true call:InputGroupCall title:flags.1?string = Updates;
|
||||
phone.editGroupCallParticipant#d975eb80 flags:# muted:flags.0?true call:InputGroupCall participant:InputPeer volume:flags.1?int raise_hand:flags.2?Bool = Updates;
|
||||
phone.editGroupCallTitle#1ca6ac0a call:InputGroupCall title:string = Updates;
|
||||
phone.getGroupCallJoinAs#ef7c213a peer:InputPeer = phone.JoinAsPeers;
|
||||
phone.exportGroupCallInvite#e6aa647f flags:# can_self_unmute:flags.0?true call:InputGroupCall = phone.ExportedGroupCallInvite;
|
||||
|
||||
langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference;
|
||||
langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector<string> = Vector<LangPackString>;
|
||||
@@ -1632,4 +1645,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 124
|
||||
// LAYER 125
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="2.6.0.0" />
|
||||
Version="2.6.5.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 2,6,0,0
|
||||
PRODUCTVERSION 2,6,0,0
|
||||
FILEVERSION 2,6,5,0
|
||||
PRODUCTVERSION 2,6,5,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -62,10 +62,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||
VALUE "FileDescription", "Telegram Desktop"
|
||||
VALUE "FileVersion", "2.6.0.0"
|
||||
VALUE "FileVersion", "2.6.5.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "2.6.0.0"
|
||||
VALUE "ProductVersion", "2.6.5.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,6,0,0
|
||||
PRODUCTVERSION 2,6,0,0
|
||||
FILEVERSION 2,6,5,0
|
||||
PRODUCTVERSION 2,6,5,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", "2.6.0.0"
|
||||
VALUE "FileVersion", "2.6.5.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "2.6.0.0"
|
||||
VALUE "ProductVersion", "2.6.5.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -55,7 +55,7 @@ void AttachedStickers::request(
|
||||
Ui::show(
|
||||
Box<StickerSetBox>(strongController, setId),
|
||||
Ui::LayerOption::KeepOther);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
Ui::show(Box<InformBox>(tr::lng_stickers_not_found(tr::now)));
|
||||
}).send();
|
||||
|
||||
@@ -46,9 +46,9 @@ Authorizations::Entry ParseEntry(const MTPDauthorization &data) {
|
||||
return version;
|
||||
}();
|
||||
|
||||
result.name = QString("%1%2")
|
||||
.arg(appName)
|
||||
.arg(appVer.isEmpty() ? QString() : (' ' + appVer));
|
||||
result.name = QString("%1%2").arg(
|
||||
appName,
|
||||
appVer.isEmpty() ? QString() : (' ' + appVer));
|
||||
|
||||
const auto country = qs(data.vcountry());
|
||||
const auto platform = qs(data.vplatform());
|
||||
@@ -61,10 +61,10 @@ Authorizations::Entry ParseEntry(const MTPDauthorization &data) {
|
||||
result.activeTime = data.vdate_active().v
|
||||
? data.vdate_active().v
|
||||
: data.vdate_created().v;
|
||||
result.info = QString("%1, %2%3")
|
||||
.arg(qs(data.vdevice_model()))
|
||||
.arg(platform.isEmpty() ? QString() : platform + ' ')
|
||||
.arg(qs(data.vsystem_version()));
|
||||
result.info = QString("%1, %2%3").arg(
|
||||
qs(data.vdevice_model()),
|
||||
platform.isEmpty() ? QString() : platform + ' ',
|
||||
qs(data.vsystem_version()));
|
||||
result.ip = qs(data.vip())
|
||||
+ (country.isEmpty()
|
||||
? QString()
|
||||
@@ -107,12 +107,12 @@ void Authorizations::reload() {
|
||||
result.match([&](const MTPDaccount_authorizations &auths) {
|
||||
_list = (
|
||||
auths.vauthorizations().v
|
||||
) | ranges::view::transform([](const MTPAuthorization &d) {
|
||||
) | ranges::views::transform([](const MTPAuthorization &d) {
|
||||
return ParseEntry(d.c_authorization());
|
||||
}) | ranges::to<List>;
|
||||
_listChanges.fire({});
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
}).send();
|
||||
}
|
||||
@@ -123,7 +123,7 @@ void Authorizations::cancelCurrentRequest() {
|
||||
|
||||
void Authorizations::requestTerminate(
|
||||
Fn<void(const MTPBool &result)> &&done,
|
||||
Fn<void(const RPCError &error)> &&fail,
|
||||
Fn<void(const MTP::Error &error)> &&fail,
|
||||
std::optional<uint64> hash) {
|
||||
const auto send = [&](auto request) {
|
||||
_api.request(
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
void cancelCurrentRequest();
|
||||
void requestTerminate(
|
||||
Fn<void(const MTPBool &result)> &&done,
|
||||
Fn<void(const RPCError &error)> &&fail,
|
||||
Fn<void(const MTP::Error &error)> &&fail,
|
||||
std::optional<uint64> hash = std::nullopt);
|
||||
|
||||
[[nodiscard]] crl::time lastReceivedTime();
|
||||
|
||||
@@ -34,7 +34,7 @@ void SendBotCallbackData(
|
||||
int row,
|
||||
int column,
|
||||
std::optional<MTPInputCheckPasswordSRP> password = std::nullopt,
|
||||
Fn<void(const RPCError &)> handleError = nullptr) {
|
||||
Fn<void(const MTP::Error &)> handleError = nullptr) {
|
||||
if (!IsServerMsgId(item->id)) {
|
||||
return;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ void SendBotCallbackData(
|
||||
Ui::hideLayer();
|
||||
}
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto item = owner->message(fullId);
|
||||
if (!item) {
|
||||
return;
|
||||
@@ -170,7 +170,7 @@ void SendBotCallbackDataWithPassword(
|
||||
return;
|
||||
}
|
||||
api->reloadPasswordState();
|
||||
SendBotCallbackData(item, row, column, MTP_inputCheckPasswordEmpty(), [=](const RPCError &error) {
|
||||
SendBotCallbackData(item, row, column, MTP_inputCheckPasswordEmpty(), [=](const MTP::Error &error) {
|
||||
auto box = PrePasswordErrorBox(
|
||||
error,
|
||||
session,
|
||||
@@ -212,7 +212,7 @@ void SendBotCallbackDataWithPassword(
|
||||
return;
|
||||
}
|
||||
if (const auto item = owner->message(fullId)) {
|
||||
SendBotCallbackData(item, row, column, result.result, [=](const RPCError &error) {
|
||||
SendBotCallbackData(item, row, column, result.result, [=](const MTP::Error &error) {
|
||||
if (*box) {
|
||||
(*box)->handleCustomCheckError(error);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ void CheckChatInvite(
|
||||
}
|
||||
}
|
||||
});
|
||||
}, [=](const RPCError &error) {
|
||||
}, [=](const MTP::Error &error) {
|
||||
if (error.code() != 400) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ struct SendAction {
|
||||
MsgId replyTo = 0;
|
||||
bool clearDraft = true;
|
||||
bool generateLocal = true;
|
||||
MsgId replaceMediaOf = 0;
|
||||
};
|
||||
|
||||
struct MessageToSend {
|
||||
|
||||
@@ -17,7 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history_item.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "mtproto/mtproto_rpc_sender.h"
|
||||
#include "mtproto/mtproto_response.h"
|
||||
|
||||
namespace Api {
|
||||
namespace {
|
||||
@@ -131,7 +131,7 @@ void EditMessageWithUploadedMedia(
|
||||
item->setIsLocalUpdateMedia(false);
|
||||
}
|
||||
};
|
||||
const auto fail = [=](const RPCError &error) {
|
||||
const auto fail = [=](const MTP::Error &error) {
|
||||
const auto err = error.type();
|
||||
const auto session = &item->history()->session();
|
||||
const auto notModified = (err == u"MESSAGE_NOT_MODIFIED"_q);
|
||||
@@ -157,7 +157,7 @@ void EditMessageWithUploadedMedia(
|
||||
void RescheduleMessage(
|
||||
not_null<HistoryItem*> item,
|
||||
SendOptions options) {
|
||||
const auto empty = [](const auto &r) {};
|
||||
const auto empty = [] {};
|
||||
EditMessage(item, options, empty, empty);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ mtpRequestId EditCaption(
|
||||
const TextWithEntities &caption,
|
||||
SendOptions options,
|
||||
Fn<void(const MTPUpdates &)> done,
|
||||
Fn<void(const RPCError &)> fail) {
|
||||
Fn<void(const MTP::Error &)> fail) {
|
||||
return EditMessage(item, caption, options, done, fail);
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ mtpRequestId EditTextMessage(
|
||||
const TextWithEntities &caption,
|
||||
SendOptions options,
|
||||
Fn<void(const MTPUpdates &, mtpRequestId requestId)> done,
|
||||
Fn<void(const RPCError &, mtpRequestId requestId)> fail) {
|
||||
Fn<void(const MTP::Error &, mtpRequestId requestId)> fail) {
|
||||
const auto callback = [=](
|
||||
const auto &result,
|
||||
Fn<void()> applyUpdates,
|
||||
|
||||
@@ -8,7 +8,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#pragma once
|
||||
|
||||
class HistoryItem;
|
||||
class RPCError;
|
||||
|
||||
namespace MTP {
|
||||
class Error;
|
||||
} // namespace MTP
|
||||
|
||||
namespace Api {
|
||||
|
||||
@@ -40,13 +43,13 @@ mtpRequestId EditCaption(
|
||||
const TextWithEntities &caption,
|
||||
SendOptions options,
|
||||
Fn<void(const MTPUpdates &)> done,
|
||||
Fn<void(const RPCError &)> fail);
|
||||
Fn<void(const MTP::Error &)> fail);
|
||||
|
||||
mtpRequestId EditTextMessage(
|
||||
not_null<HistoryItem*> item,
|
||||
const TextWithEntities &caption,
|
||||
SendOptions options,
|
||||
Fn<void(const MTPUpdates &, mtpRequestId requestId)> done,
|
||||
Fn<void(const RPCError &, mtpRequestId requestId)> fail);
|
||||
Fn<void(const MTP::Error &, mtpRequestId requestId)> fail);
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -33,7 +33,7 @@ void GlobalPrivacy::reload(Fn<void()> callback) {
|
||||
for (const auto &callback : base::take(_callbacks)) {
|
||||
callback();
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
for (const auto &callback : base::take(_callbacks)) {
|
||||
callback();
|
||||
@@ -86,7 +86,7 @@ void GlobalPrivacy::update(bool archiveAndMute) {
|
||||
)).done([=](const MTPGlobalPrivacySettings &result) {
|
||||
_requestId = 0;
|
||||
apply(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
}).send();
|
||||
_archiveAndMute = archiveAndMute;
|
||||
|
||||
@@ -51,7 +51,7 @@ JoinedByLinkSlice ParseJoinedByLinkSlice(
|
||||
owner.processUsers(data.vusers());
|
||||
result.count = data.vcount().v;
|
||||
result.users.reserve(data.vimporters().v.size());
|
||||
for (const auto importer : data.vimporters().v) {
|
||||
for (const auto &importer : data.vimporters().v) {
|
||||
importer.match([&](const MTPDchatInviteImporter &data) {
|
||||
result.users.push_back({
|
||||
.user = owner.user(data.vuser_id().v),
|
||||
@@ -110,7 +110,7 @@ void InviteLinks::performCreate(
|
||||
callback(link);
|
||||
}
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_createCallbacks.erase(peer);
|
||||
}).send();
|
||||
}
|
||||
@@ -282,7 +282,7 @@ void InviteLinks::performEdit(
|
||||
prepend(peer, admin, data.vnew_invite());
|
||||
}
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_editCallbacks.erase(key);
|
||||
}).send();
|
||||
}
|
||||
@@ -344,7 +344,7 @@ void InviteLinks::destroy(
|
||||
.admin = admin,
|
||||
.was = key.link,
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_deleteCallbacks.erase(key);
|
||||
}).send();
|
||||
}
|
||||
@@ -374,7 +374,7 @@ void InviteLinks::destroyAllRevoked(
|
||||
}
|
||||
}
|
||||
_allRevokedDestroyed.fire({ peer, admin });
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
}).send();
|
||||
}
|
||||
|
||||
@@ -415,7 +415,7 @@ void InviteLinks::requestMyLinks(not_null<PeerData*> peer) {
|
||||
i->second.count = std::max(slice.count, int(existing.size()));
|
||||
}
|
||||
notify(peer);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_firstSliceRequests.remove(peer);
|
||||
}).send();
|
||||
_firstSliceRequests.emplace(peer, requestId);
|
||||
@@ -493,7 +493,7 @@ void InviteLinks::requestJoinedFirstSlice(LinkKey key) {
|
||||
_firstJoinedRequests.remove(key);
|
||||
_firstJoined[key] = ParseJoinedByLinkSlice(key.peer, result);
|
||||
_joinedFirstSliceLoaded.fire_copy(key);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_firstJoinedRequests.remove(key);
|
||||
}).send();
|
||||
_firstJoinedRequests.emplace(key, requestId);
|
||||
@@ -653,7 +653,7 @@ void InviteLinks::requestMoreLinks(
|
||||
MTP_int(kPerPage)
|
||||
)).done([=](const MTPmessages_ExportedChatInvites &result) {
|
||||
done(parseSlice(peer, result));
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
done(Links());
|
||||
}).send();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ void SelfDestruct::reload() {
|
||||
result.match([&](const MTPDaccountDaysTTL &data) {
|
||||
_days = data.vdays().v;
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
}).send();
|
||||
}
|
||||
@@ -42,7 +42,7 @@ void SelfDestruct::update(int days) {
|
||||
MTP_accountDaysTTL(MTP_int(days))
|
||||
)).done([=](const MTPBool &result) {
|
||||
_requestId = 0;
|
||||
}).fail([=](const RPCError &result) {
|
||||
}).fail([=](const MTP::Error &result) {
|
||||
_requestId = 0;
|
||||
}).send();
|
||||
_days = days;
|
||||
|
||||
@@ -65,7 +65,10 @@ void SendProgressManager::update(
|
||||
SendProgressType type,
|
||||
int progress) {
|
||||
const auto peer = history->peer;
|
||||
if (peer->isSelf() || (peer->isChannel() && !peer->isMegagroup())) {
|
||||
if (peer->isSelf()
|
||||
|| (peer->isChannel()
|
||||
&& !peer->isMegagroup()
|
||||
&& type != SendProgressType::Speaking)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ void SendExistingMedia(
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
api->applyUpdates(result, randomId);
|
||||
finish();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (error.code() == 400
|
||||
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
|
||||
api->refreshFileReference(origin, [=](const auto &result) {
|
||||
@@ -324,7 +324,7 @@ bool SendDice(Api::MessageToSend &message) {
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
api->applyUpdates(result, randomId);
|
||||
finish();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
api->sendMessageFail(error, peer, randomId, newId);
|
||||
finish();
|
||||
}).afterRequest(history->sendRequestId
|
||||
@@ -344,13 +344,15 @@ void FillMessagePostFlags(
|
||||
|
||||
void SendConfirmedFile(
|
||||
not_null<Main::Session*> session,
|
||||
const std::shared_ptr<FileLoadResult> &file,
|
||||
const std::optional<FullMsgId> &oldId) {
|
||||
const auto isEditing = oldId.has_value();
|
||||
const std::shared_ptr<FileLoadResult> &file) {
|
||||
const auto isEditing = file->to.replaceMediaOf != 0;
|
||||
const auto channelId = peerToChannel(file->to.peer);
|
||||
|
||||
const auto newId = oldId.value_or(
|
||||
FullMsgId(channelId, session->data().nextLocalMessageId()));
|
||||
const auto newId = FullMsgId(
|
||||
channelId,
|
||||
isEditing
|
||||
? file->to.replaceMediaOf
|
||||
: session->data().nextLocalMessageId());
|
||||
auto groupId = file->album ? file->album->groupId : uint64(0);
|
||||
if (file->album) {
|
||||
const auto proj = [](const SendingAlbum::Item &item) {
|
||||
@@ -361,7 +363,6 @@ void SendConfirmedFile(
|
||||
|
||||
it->msgId = newId;
|
||||
}
|
||||
file->edit = isEditing;
|
||||
session->uploader().upload(newId, file);
|
||||
|
||||
const auto itemToEdit = isEditing
|
||||
|
||||
@@ -34,7 +34,6 @@ void FillMessagePostFlags(
|
||||
|
||||
void SendConfirmedFile(
|
||||
not_null<Main::Session*> session,
|
||||
const std::shared_ptr<FileLoadResult> &file,
|
||||
const std::optional<FullMsgId> &oldId);
|
||||
const std::shared_ptr<FileLoadResult> &file);
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -36,7 +36,7 @@ void SensitiveContent::reload() {
|
||||
_enabled = data.is_sensitive_enabled();
|
||||
_canChange = data.is_sensitive_can_change();
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
}).send();
|
||||
}
|
||||
@@ -63,7 +63,7 @@ void SensitiveContent::update(bool enabled) {
|
||||
MTP_flags(enabled ? Flag::f_sensitive_enabled : Flag(0))
|
||||
)).done([=](const MTPBool &result) {
|
||||
_requestId = 0;
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
}).send();
|
||||
_enabled = enabled;
|
||||
|
||||
@@ -117,7 +117,7 @@ std::optional<HistoryItem*> SingleMessageSearch::performLookupByChannel(
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
fail();
|
||||
}).send();
|
||||
|
||||
@@ -154,7 +154,7 @@ std::optional<HistoryItem*> SingleMessageSearch::performLookupById(
|
||||
fail();
|
||||
}
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
fail();
|
||||
}).send();
|
||||
|
||||
@@ -198,7 +198,7 @@ std::optional<HistoryItem*> SingleMessageSearch::performLookupByUsername(
|
||||
fail();
|
||||
}
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
fail();
|
||||
}).send();
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ void ToggleExistingMedia(
|
||||
if (mtpIsTrue(result)) {
|
||||
done();
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (error.code() == 400
|
||||
&& error.type().startsWith(u"FILE_REFERENCE_"_q)) {
|
||||
auto refreshed = [=](const Data::UpdatedFileReferences &d) {
|
||||
|
||||
@@ -240,16 +240,16 @@ Updates::Updates(not_null<Main::Session*> session)
|
||||
) | rpl::filter([](not_null<PeerData*> peer) {
|
||||
return peer->isChat() || peer->isMegagroup();
|
||||
}) | rpl::start_with_next([=](not_null<PeerData*> peer) {
|
||||
if (const auto users = _pendingSpeakingCallMembers.take(peer)) {
|
||||
if (const auto list = _pendingSpeakingCallParticipants.take(peer)) {
|
||||
if (const auto call = peer->groupCall()) {
|
||||
for (const auto [userId, when] : *users) {
|
||||
for (const auto &[participantPeerId, when] : *list) {
|
||||
call->applyActiveUpdate(
|
||||
userId,
|
||||
participantPeerId,
|
||||
Data::LastSpokeTimes{
|
||||
.anything = when,
|
||||
.voice = when
|
||||
},
|
||||
peer->owner().userLoaded(userId));
|
||||
peer->owner().peerLoaded(participantPeerId));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,11 +278,25 @@ void Updates::checkLastUpdate(bool afterSleep) {
|
||||
void Updates::feedUpdateVector(
|
||||
const MTPVector<MTPUpdate> &updates,
|
||||
bool skipMessageIds) {
|
||||
for (const auto &update : updates.v) {
|
||||
if (skipMessageIds && update.type() == mtpc_updateMessageID) {
|
||||
auto list = updates.v;
|
||||
const auto needsSorting = ranges::contains(
|
||||
list,
|
||||
mtpc_updateGroupCallParticipants,
|
||||
&MTPUpdate::type);
|
||||
if (needsSorting) {
|
||||
ranges::stable_sort(list, std::less<>(), [](const MTPUpdate &entry) {
|
||||
if (entry.type() == mtpc_updateGroupCallParticipants) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
for (const auto &entry : std::as_const(list)) {
|
||||
if (skipMessageIds && entry.type() == mtpc_updateMessageID) {
|
||||
continue;
|
||||
}
|
||||
feedUpdate(update);
|
||||
feedUpdate(entry);
|
||||
}
|
||||
session().data().sendHistoryChangeNotifications();
|
||||
}
|
||||
@@ -398,11 +412,11 @@ void Updates::feedChannelDifference(
|
||||
|
||||
void Updates::channelDifferenceFail(
|
||||
not_null<ChannelData*> channel,
|
||||
const RPCError &error) {
|
||||
LOG(("RPC Error in getChannelDifference: %1 %2: %3"
|
||||
).arg(error.code()
|
||||
).arg(error.type()
|
||||
).arg(error.description()));
|
||||
const MTP::Error &error) {
|
||||
LOG(("RPC Error in getChannelDifference: %1 %2: %3").arg(
|
||||
QString::number(error.code()),
|
||||
error.type(),
|
||||
error.description()));
|
||||
failDifferenceStartTimerFor(channel);
|
||||
}
|
||||
|
||||
@@ -556,11 +570,11 @@ void Updates::feedDifference(
|
||||
feedUpdateVector(other, true);
|
||||
}
|
||||
|
||||
void Updates::differenceFail(const RPCError &error) {
|
||||
LOG(("RPC Error in getDifference: %1 %2: %3"
|
||||
).arg(error.code()
|
||||
).arg(error.type()
|
||||
).arg(error.description()));
|
||||
void Updates::differenceFail(const MTP::Error &error) {
|
||||
LOG(("RPC Error in getDifference: %1 %2: %3").arg(
|
||||
QString::number(error.code()),
|
||||
error.type(),
|
||||
error.description()));
|
||||
failDifferenceStartTimerFor(nullptr);
|
||||
}
|
||||
|
||||
@@ -643,7 +657,7 @@ void Updates::getDifference() {
|
||||
MTP_int(_updatesQts)
|
||||
)).done([=](const MTPupdates_Difference &result) {
|
||||
differenceDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
differenceFail(error);
|
||||
}).send();
|
||||
}
|
||||
@@ -678,7 +692,7 @@ void Updates::getChannelDifference(
|
||||
MTP_int(kChannelGetDifferenceLimit)
|
||||
)).done([=](const MTPupdates_ChannelDifference &result) {
|
||||
channelDifferenceDone(channel, result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
channelDifferenceFail(channel, error);
|
||||
}).send();
|
||||
}
|
||||
@@ -742,7 +756,7 @@ void Updates::channelRangeDifferenceSend(
|
||||
)).done([=](const MTPupdates_ChannelDifference &result) {
|
||||
_rangeDifferenceRequests.remove(channel);
|
||||
channelRangeDifferenceDone(channel, range, result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_rangeDifferenceRequests.remove(channel);
|
||||
}).send();
|
||||
_rangeDifferenceRequests.emplace(channel, requestId);
|
||||
@@ -862,7 +876,7 @@ void Updates::updateOnline(bool gotOtherOffline) {
|
||||
MTP_bool(!isOnline)
|
||||
)).done([=](const MTPBool &result) {
|
||||
Core::App().quitPreventFinished();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
Core::App().quitPreventFinished();
|
||||
}).send();
|
||||
}
|
||||
@@ -915,16 +929,16 @@ bool Updates::isQuitPrevent() {
|
||||
void Updates::handleSendActionUpdate(
|
||||
PeerId peerId,
|
||||
MsgId rootId,
|
||||
UserId userId,
|
||||
PeerId fromId,
|
||||
const MTPSendMessageAction &action) {
|
||||
const auto history = session().data().historyLoaded(peerId);
|
||||
if (!history) {
|
||||
return;
|
||||
}
|
||||
const auto peer = history->peer;
|
||||
const auto user = (userId == session().userId())
|
||||
const auto from = (fromId == session().userPeerId())
|
||||
? session().user().get()
|
||||
: session().data().userLoaded(userId);
|
||||
: session().data().peerLoaded(fromId);
|
||||
const auto isSpeakingInCall = (action.type()
|
||||
== mtpc_speakingInGroupCallAction);
|
||||
if (isSpeakingInCall) {
|
||||
@@ -935,9 +949,9 @@ void Updates::handleSendActionUpdate(
|
||||
const auto now = crl::now();
|
||||
if (call) {
|
||||
call->applyActiveUpdate(
|
||||
userId,
|
||||
fromId,
|
||||
Data::LastSpokeTimes{ .anything = now, .voice = now },
|
||||
user);
|
||||
from);
|
||||
} else {
|
||||
const auto chat = peer->asChat();
|
||||
const auto channel = peer->asChannel();
|
||||
@@ -945,13 +959,15 @@ void Updates::handleSendActionUpdate(
|
||||
? (chat->flags() & MTPDchat::Flag::f_call_active)
|
||||
: (channel->flags() & MTPDchannel::Flag::f_call_active);
|
||||
if (active) {
|
||||
_pendingSpeakingCallMembers.emplace(
|
||||
peer).first->second[userId] = now;
|
||||
session().api().requestFullPeer(peer);
|
||||
_pendingSpeakingCallParticipants.emplace(
|
||||
peer).first->second[fromId] = now;
|
||||
if (peerIsUser(fromId)) {
|
||||
session().api().requestFullPeer(peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!user || user->isSelf()) {
|
||||
if (!from || !from->isUser() || from->isSelf()) {
|
||||
return;
|
||||
}
|
||||
const auto when = requestingDifference()
|
||||
@@ -960,7 +976,7 @@ void Updates::handleSendActionUpdate(
|
||||
session().data().registerSendAction(
|
||||
history,
|
||||
rootId,
|
||||
user,
|
||||
from->asUser(),
|
||||
action,
|
||||
when);
|
||||
}
|
||||
@@ -1539,22 +1555,6 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
}
|
||||
} break;
|
||||
|
||||
//case mtpc_updateReadFeed: { // #feed
|
||||
// const auto &d = update.c_updateReadFeed();
|
||||
// const auto feedId = d.vfeed_id().v;
|
||||
// if (const auto feed = session().data().feedLoaded(feedId)) {
|
||||
// feed->setUnreadPosition(
|
||||
// Data::FeedPositionFromMTP(d.vmax_position()));
|
||||
// if (d.vunread_count() && d.vunread_muted_count()) {
|
||||
// feed->setUnreadCounts(
|
||||
// d.vunread_count()->v,
|
||||
// d.vunread_muted_count()->v);
|
||||
// } else {
|
||||
// session().data().histories().requestDialogEntry(feed);
|
||||
// }
|
||||
// }
|
||||
//} break;
|
||||
|
||||
case mtpc_updateDialogUnreadMark: {
|
||||
const auto &data = update.c_updateDialogUnreadMark();
|
||||
data.vpeer().match(
|
||||
@@ -1658,19 +1658,21 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updateChatUserTyping: {
|
||||
auto &d = update.c_updateChatUserTyping();
|
||||
const auto fromId = peerFromMTP(d.vfrom_id());
|
||||
handleSendActionUpdate(
|
||||
peerFromChat(d.vchat_id()),
|
||||
0,
|
||||
d.vuser_id().v,
|
||||
fromId,
|
||||
d.vaction());
|
||||
} break;
|
||||
|
||||
case mtpc_updateChannelUserTyping: {
|
||||
const auto &d = update.c_updateChannelUserTyping();
|
||||
const auto fromId = peerFromMTP(d.vfrom_id());
|
||||
handleSendActionUpdate(
|
||||
peerFromChannel(d.vchannel_id()),
|
||||
d.vtop_msg_id().value_or_empty(),
|
||||
d.vuser_id().v,
|
||||
fromId,
|
||||
d.vaction());
|
||||
} break;
|
||||
|
||||
@@ -2003,17 +2005,10 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
channel->updateFullForced();
|
||||
}
|
||||
const auto history = channel->owner().history(channel);
|
||||
//if (const auto feed = channel->feed()) { // #feed
|
||||
// feed->requestChatListMessage();
|
||||
// if (!feed->unreadCountKnown()) {
|
||||
// feed->owner().histories().requestDialogEntry(feed);
|
||||
// }
|
||||
//} else {
|
||||
history->requestChatListMessage();
|
||||
if (!history->unreadCountKnown()) {
|
||||
history->owner().histories().requestDialogEntry(history);
|
||||
}
|
||||
//}
|
||||
history->requestChatListMessage();
|
||||
if (!history->unreadCountKnown()) {
|
||||
history->owner().histories().requestDialogEntry(history);
|
||||
}
|
||||
if (!channel->amCreator()) {
|
||||
session().api().requestSelfParticipant(channel);
|
||||
}
|
||||
|
||||
@@ -10,10 +10,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_pts_waiter.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
class RPCError;
|
||||
class ApiWrap;
|
||||
class History;
|
||||
|
||||
namespace MTP {
|
||||
class Error;
|
||||
} // namespace MTP
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
@@ -89,7 +92,7 @@ private:
|
||||
not_null<ChannelData*> channel,
|
||||
ChannelDifferenceRequest from = ChannelDifferenceRequest::Unknown);
|
||||
void differenceDone(const MTPupdates_Difference &result);
|
||||
void differenceFail(const RPCError &error);
|
||||
void differenceFail(const MTP::Error &error);
|
||||
void feedDifference(
|
||||
const MTPVector<MTPUser> &users,
|
||||
const MTPVector<MTPChat> &chats,
|
||||
@@ -102,7 +105,7 @@ private:
|
||||
const MTPupdates_ChannelDifference &diff);
|
||||
void channelDifferenceFail(
|
||||
not_null<ChannelData*> channel,
|
||||
const RPCError &error);
|
||||
const MTP::Error &error);
|
||||
void failDifferenceStartTimerFor(ChannelData *channel);
|
||||
void feedChannelDifference(const MTPDupdates_channelDifference &data);
|
||||
|
||||
@@ -125,7 +128,7 @@ private:
|
||||
void handleSendActionUpdate(
|
||||
PeerId peerId,
|
||||
MsgId rootId,
|
||||
UserId userId,
|
||||
PeerId fromId,
|
||||
const MTPSendMessageAction &action);
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
@@ -168,7 +171,7 @@ private:
|
||||
base::flat_map<int, ActiveChatTracker> _activeChats;
|
||||
base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
base::flat_map<UserId, crl::time>> _pendingSpeakingCallMembers;
|
||||
base::flat_map<PeerId, crl::time>> _pendingSpeakingCallParticipants;
|
||||
|
||||
mtpRequestId _onlineRequest = 0;
|
||||
base::Timer _idleFinishTimer;
|
||||
|
||||
@@ -171,7 +171,6 @@ public:
|
||||
not_null<History*> history,
|
||||
bool archived,
|
||||
Fn<void()> callback);
|
||||
//void ungroupAllFromFeed(not_null<Data::Feed*> feed); // #feed
|
||||
|
||||
using RequestMessageDataCallback = Fn<void(ChannelData*, MsgId)>;
|
||||
void requestMessageData(
|
||||
@@ -190,15 +189,10 @@ public:
|
||||
rpl::producer<bool> dialogsLoadMayBlockByDate() const;
|
||||
rpl::producer<bool> dialogsLoadBlockedByDate() const;
|
||||
|
||||
//void applyFeedSources(const MTPDchannels_feedSources &data); // #feed
|
||||
//void setFeedChannels(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// const std::vector<not_null<ChannelData*>> &channels);
|
||||
|
||||
void requestWallPaper(
|
||||
const QString &slug,
|
||||
Fn<void(const Data::WallPaper &)> done,
|
||||
Fn<void(const RPCError &)> fail);
|
||||
Fn<void(const MTP::Error &)> fail);
|
||||
|
||||
void requestFullPeer(not_null<PeerData*> peer);
|
||||
void requestPeer(not_null<PeerData*> peer);
|
||||
@@ -233,7 +227,7 @@ public:
|
||||
void checkChatInvite(
|
||||
const QString &hash,
|
||||
FnMut<void(const MTPChatInvite &)> done,
|
||||
FnMut<void(const RPCError &)> fail);
|
||||
Fn<void(const MTP::Error &)> fail);
|
||||
void importChatInvite(const QString &hash);
|
||||
|
||||
void requestChannelMembersForAdd(
|
||||
@@ -249,7 +243,7 @@ public:
|
||||
void migrateChat(
|
||||
not_null<ChatData*> chat,
|
||||
FnMut<void(not_null<ChannelData*>)> done,
|
||||
FnMut<void(const RPCError &)> fail = nullptr);
|
||||
Fn<void(const MTP::Error &)> fail = nullptr);
|
||||
|
||||
void markMediaRead(const base::flat_set<not_null<HistoryItem*>> &items);
|
||||
void markMediaRead(not_null<HistoryItem*> item);
|
||||
@@ -334,14 +328,6 @@ public:
|
||||
not_null<UserData*> user,
|
||||
PhotoId afterId);
|
||||
|
||||
//void requestFeedChannels( // #feed
|
||||
// not_null<Data::Feed*> feed);
|
||||
//void requestFeedMessages(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// Data::MessagePosition messageId,
|
||||
// SliceType slice);
|
||||
//void saveDefaultFeedId(FeedId id, bool isDefaultFeedId);
|
||||
|
||||
void stickerSetInstalled(uint64 setId) {
|
||||
_stickerSetInstalled.fire_copy(setId);
|
||||
}
|
||||
@@ -384,9 +370,6 @@ public:
|
||||
const QString &lastName,
|
||||
const SendAction &action);
|
||||
void shareContact(not_null<UserData*> user, const SendAction &action);
|
||||
//void readFeed( // #feed
|
||||
// not_null<Data::Feed*> feed,
|
||||
// Data::MessagePosition position);
|
||||
void applyAffectedMessages(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPmessages_AffectedMessages &result);
|
||||
@@ -411,8 +394,7 @@ public:
|
||||
Ui::PreparedList &&list,
|
||||
SendMediaType type,
|
||||
TextWithTags &&caption,
|
||||
const SendAction &action,
|
||||
MsgId msgIdToEdit);
|
||||
const SendAction &action);
|
||||
|
||||
void sendUploadedPhoto(
|
||||
FullMsgId localId,
|
||||
@@ -433,7 +415,7 @@ public:
|
||||
not_null<InlineBots::Result*> data,
|
||||
const SendAction &action);
|
||||
void sendMessageFail(
|
||||
const RPCError &error,
|
||||
const MTP::Error &error,
|
||||
not_null<PeerData*> peer,
|
||||
uint64 randomId = 0,
|
||||
FullMsgId itemId = FullMsgId());
|
||||
@@ -470,7 +452,7 @@ public:
|
||||
const PollData &data,
|
||||
const SendAction &action,
|
||||
Fn<void()> done,
|
||||
Fn<void(const RPCError &error)> fail);
|
||||
Fn<void(const MTP::Error &error)> fail);
|
||||
void sendPollVotes(
|
||||
FullMsgId itemId,
|
||||
const std::vector<QByteArray> &options);
|
||||
@@ -565,17 +547,11 @@ private:
|
||||
const QVector<MTPChannelParticipant> &participants);
|
||||
|
||||
void jumpToHistoryDate(not_null<PeerData*> peer, const QDate &date);
|
||||
//void jumpToFeedDate(not_null<Data::Feed*> feed, const QDate &date); // #feed
|
||||
template <typename Callback>
|
||||
void requestMessageAfterDate(
|
||||
not_null<PeerData*> peer,
|
||||
const QDate &date,
|
||||
Callback &&callback);
|
||||
//template <typename Callback> // #feed
|
||||
//void requestMessageAfterDate(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// const QDate &date,
|
||||
// Callback &&callback);
|
||||
|
||||
void sharedMediaDone(
|
||||
not_null<PeerData*> peer,
|
||||
@@ -589,13 +565,6 @@ private:
|
||||
PhotoId photoId,
|
||||
const MTPphotos_Photos &result);
|
||||
|
||||
//void feedChannelsDone(not_null<Data::Feed*> feed); // #feed
|
||||
//void feedMessagesDone(
|
||||
// not_null<Data::Feed*> feed,
|
||||
// Data::MessagePosition messageId,
|
||||
// SliceType slice,
|
||||
// const MTPmessages_FeedMessages &result);
|
||||
|
||||
void sendSharedContact(
|
||||
const QString &phone,
|
||||
const QString &firstName,
|
||||
@@ -636,8 +605,6 @@ private:
|
||||
uint64 randomId);
|
||||
FileLoadTo fileLoadTaskOptions(const SendAction &action) const;
|
||||
|
||||
//void readFeeds(); // #feed
|
||||
|
||||
void getTopPromotionDelayed(TimeId now, TimeId next);
|
||||
void topPromotionDone(const MTPhelp_PromoData &proxy);
|
||||
|
||||
@@ -660,7 +627,7 @@ private:
|
||||
void migrateDone(
|
||||
not_null<PeerData*> peer,
|
||||
not_null<ChannelData*> channel);
|
||||
void migrateFail(not_null<PeerData*> peer, const RPCError &error);
|
||||
void migrateFail(not_null<PeerData*> peer, const MTP::Error &error);
|
||||
|
||||
not_null<Main::Session*> _session;
|
||||
|
||||
@@ -737,20 +704,6 @@ private:
|
||||
|
||||
base::flat_map<not_null<UserData*>, mtpRequestId> _userPhotosRequests;
|
||||
|
||||
//base::flat_set<not_null<Data::Feed*>> _feedChannelsGetRequests; // #feed
|
||||
//base::flat_map<
|
||||
// not_null<Data::Feed*>,
|
||||
// mtpRequestId> _feedChannelsSetRequests;
|
||||
//base::flat_set<std::tuple<
|
||||
// not_null<Data::Feed*>,
|
||||
// Data::MessagePosition,
|
||||
// SliceType>> _feedMessagesRequests;
|
||||
//base::flat_set<std::tuple<
|
||||
// not_null<Data::Feed*>,
|
||||
// Data::MessagePosition,
|
||||
// SliceType>> _feedMessagesRequestsPending;
|
||||
//mtpRequestId _saveDefaultFeedIdRequest = 0;
|
||||
|
||||
std::unique_ptr<DialogsLoadState> _dialogsLoadState;
|
||||
TimeId _dialogsLoadTill = 0;
|
||||
rpl::variable<bool> _dialogsLoadMayBlockByDate = false;
|
||||
@@ -769,11 +722,6 @@ private:
|
||||
|
||||
rpl::event_stream<uint64> _stickerSetInstalled;
|
||||
|
||||
// #feed
|
||||
//base::flat_map<not_null<Data::Feed*>, crl::time> _feedReadsDelayed;
|
||||
//base::flat_map<not_null<Data::Feed*>, mtpRequestId> _feedReadRequests;
|
||||
//base::Timer _feedReadTimer;
|
||||
|
||||
mtpRequestId _topPromotionRequestId = 0;
|
||||
std::pair<QString, uint32> _topPromotionKey;
|
||||
TimeId _topPromotionNextRequestTime = TimeId(0);
|
||||
@@ -793,11 +741,11 @@ private:
|
||||
|
||||
mtpRequestId _checkInviteRequestId = 0;
|
||||
FnMut<void(const MTPChatInvite &result)> _checkInviteDone;
|
||||
FnMut<void(const RPCError &error)> _checkInviteFail;
|
||||
Fn<void(const MTP::Error &error)> _checkInviteFail;
|
||||
|
||||
struct MigrateCallbacks {
|
||||
FnMut<void(not_null<ChannelData*>)> done;
|
||||
FnMut<void(const RPCError&)> fail;
|
||||
Fn<void(const MTP::Error&)> fail;
|
||||
};
|
||||
base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
@@ -837,7 +785,7 @@ private:
|
||||
mtpRequestId _wallPaperRequestId = 0;
|
||||
QString _wallPaperSlug;
|
||||
Fn<void(const Data::WallPaper &)> _wallPaperDone;
|
||||
Fn<void(const RPCError &)> _wallPaperFail;
|
||||
Fn<void(const MTP::Error &)> _wallPaperFail;
|
||||
|
||||
mtpRequestId _contactSignupSilentRequestId = 0;
|
||||
std::optional<bool> _contactSignupSilent;
|
||||
|
||||
@@ -586,7 +586,7 @@ void GroupInfoBox::createGroup(
|
||||
|
||||
Ui::hideLayer(); // Destroys 'this'.
|
||||
ChatCreateDone(navigation, std::move(image), result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_creationRequestId = 0;
|
||||
if (error.type() == qstr("NO_CHAT_TITLE")) {
|
||||
auto weak = Ui::MakeWeak(this);
|
||||
@@ -703,7 +703,7 @@ void GroupInfoBox::createChannel(const QString &title, const QString &descriptio
|
||||
LOG(("API Error: channel not found in updates (GroupInfoBox::creationDone)"));
|
||||
closeBox();
|
||||
}
|
||||
}).fail([this](const RPCError &error) {
|
||||
}).fail([this](const MTP::Error &error) {
|
||||
_creationRequestId = 0;
|
||||
if (error.type() == "NO_CHAT_TITLE") {
|
||||
_title->setFocus();
|
||||
@@ -824,7 +824,7 @@ void SetupChannelBox::prepare() {
|
||||
_checkRequestId = _api.request(MTPchannels_CheckUsername(
|
||||
_channel->inputChannel,
|
||||
MTP_string("preston")
|
||||
)).fail([=](const RPCError &error) {
|
||||
)).fail([=](const MTP::Error &error) {
|
||||
firstCheckFail(error);
|
||||
}).send();
|
||||
|
||||
@@ -983,7 +983,7 @@ void SetupChannelBox::save() {
|
||||
MTP_string(_sentUsername)
|
||||
)).done([=](const MTPBool &result) {
|
||||
updateDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
updateFail(error);
|
||||
}).send();
|
||||
};
|
||||
@@ -1055,7 +1055,7 @@ void SetupChannelBox::check() {
|
||||
MTP_string(link)
|
||||
)).done([=](const MTPBool &result) {
|
||||
checkDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
checkFail(error);
|
||||
}).send();
|
||||
}
|
||||
@@ -1095,7 +1095,7 @@ void SetupChannelBox::updateDone(const MTPBool &result) {
|
||||
closeBox();
|
||||
}
|
||||
|
||||
void SetupChannelBox::updateFail(const RPCError &error) {
|
||||
void SetupChannelBox::updateFail(const MTP::Error &error) {
|
||||
_saveRequestId = 0;
|
||||
QString err(error.type());
|
||||
if (err == "USERNAME_NOT_MODIFIED"
|
||||
@@ -1130,7 +1130,7 @@ void SetupChannelBox::checkDone(const MTPBool &result) {
|
||||
}
|
||||
}
|
||||
|
||||
void SetupChannelBox::checkFail(const RPCError &error) {
|
||||
void SetupChannelBox::checkFail(const MTP::Error &error) {
|
||||
_checkRequestId = 0;
|
||||
QString err(error.type());
|
||||
if (err == qstr("CHANNEL_PUBLIC_GROUP_NA")) {
|
||||
@@ -1171,7 +1171,7 @@ void SetupChannelBox::showRevokePublicLinkBoxForEdit() {
|
||||
Ui::LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
void SetupChannelBox::firstCheckFail(const RPCError &error) {
|
||||
void SetupChannelBox::firstCheckFail(const MTP::Error &error) {
|
||||
_checkRequestId = 0;
|
||||
const auto &type = error.type();
|
||||
if (type == qstr("CHANNEL_PUBLIC_GROUP_NA")) {
|
||||
@@ -1281,7 +1281,7 @@ void EditNameBox::save() {
|
||||
MTPstring()
|
||||
)).done([=](const MTPUser &result) {
|
||||
saveSelfDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
saveSelfFail(error);
|
||||
}).send();
|
||||
}
|
||||
@@ -1291,7 +1291,7 @@ void EditNameBox::saveSelfDone(const MTPUser &user) {
|
||||
closeBox();
|
||||
}
|
||||
|
||||
void EditNameBox::saveSelfFail(const RPCError &error) {
|
||||
void EditNameBox::saveSelfFail(const MTP::Error &error) {
|
||||
auto err = error.type();
|
||||
auto first = TextUtilities::SingleLine(_first->getLastText().trimmed());
|
||||
auto last = TextUtilities::SingleLine(_last->getLastText().trimmed());
|
||||
|
||||
@@ -179,11 +179,11 @@ private:
|
||||
void save();
|
||||
|
||||
void updateDone(const MTPBool &result);
|
||||
void updateFail(const RPCError &error);
|
||||
void updateFail(const MTP::Error &error);
|
||||
|
||||
void checkDone(const MTPBool &result);
|
||||
void checkFail(const RPCError &error);
|
||||
void firstCheckFail(const RPCError &error);
|
||||
void checkFail(const MTP::Error &error);
|
||||
void firstCheckFail(const MTP::Error &error);
|
||||
|
||||
void updateMaxHeight();
|
||||
|
||||
@@ -229,7 +229,7 @@ private:
|
||||
void submit();
|
||||
void save();
|
||||
void saveSelfDone(const MTPUser &user);
|
||||
void saveSelfFail(const RPCError &error);
|
||||
void saveSelfFail(const MTP::Error &error);
|
||||
|
||||
const not_null<UserData*> _user;
|
||||
MTP::Sender _api;
|
||||
|
||||
@@ -158,15 +158,15 @@ void AutoDownloadBox::setupContent() {
|
||||
};
|
||||
|
||||
addButton(tr::lng_connection_save(), [=] {
|
||||
auto &&values = ranges::view::concat(
|
||||
auto &&values = ranges::views::concat(
|
||||
*downloadValues,
|
||||
*autoPlayValues);
|
||||
auto allowMore = values | ranges::view::filter([&](Pair pair) {
|
||||
auto allowMore = values | ranges::views::filter([&](Pair pair) {
|
||||
const auto [type, enabled] = pair;
|
||||
const auto value = enabled ? limitByType(type) : 0;
|
||||
const auto old = settings->bytesLimit(_source, type);
|
||||
return (old < value);
|
||||
}) | ranges::view::transform([](Pair pair) {
|
||||
}) | ranges::views::transform([](Pair pair) {
|
||||
return pair.first;
|
||||
});
|
||||
const auto less = ranges::any_of(*autoPlayValues, [&](Pair pair) {
|
||||
@@ -191,7 +191,7 @@ void AutoDownloadBox::setupContent() {
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
for (const auto [type, enabled] : values) {
|
||||
for (const auto &[type, enabled] : values) {
|
||||
const auto value = enabled ? limitByType(type) : 0;
|
||||
settings->setBytesLimit(_source, type, value);
|
||||
}
|
||||
|
||||
@@ -248,9 +248,9 @@ void BackgroundBox::Inner::updatePapers() {
|
||||
_over = _overDown = Selection();
|
||||
|
||||
_papers = _session->data().wallpapers(
|
||||
) | ranges::view::filter([](const Data::WallPaper &paper) {
|
||||
) | ranges::views::filter([](const Data::WallPaper &paper) {
|
||||
return !paper.isPattern() || paper.backgroundColor().has_value();
|
||||
}) | ranges::view::transform([](const Data::WallPaper &paper) {
|
||||
}) | ranges::views::transform([](const Data::WallPaper &paper) {
|
||||
return Paper{ paper };
|
||||
}) | ranges::to_vector;
|
||||
sortPapers();
|
||||
@@ -268,7 +268,7 @@ void BackgroundBox::Inner::resizeToContentAndPreload() {
|
||||
+ st::backgroundPadding));
|
||||
|
||||
const auto preload = kBackgroundsInRow * 3;
|
||||
for (const auto &paper : _papers | ranges::view::take(preload)) {
|
||||
for (const auto &paper : _papers | ranges::views::take(preload)) {
|
||||
if (!paper.data.localThumbnail() && !paper.dataMedia) {
|
||||
if (const auto document = paper.data.document()) {
|
||||
paper.dataMedia = document->createMediaView();
|
||||
|
||||
@@ -785,7 +785,7 @@ bool BackgroundPreviewBox::Start(
|
||||
Ui::show(Box<BackgroundPreviewBox>(
|
||||
controller,
|
||||
result.withUrlParams(params)));
|
||||
}), [](const RPCError &error) {
|
||||
}), [](const MTP::Error &error) {
|
||||
Ui::show(Box<InformBox>(tr::lng_background_bad_link(tr::now)));
|
||||
});
|
||||
return true;
|
||||
|
||||
@@ -111,7 +111,7 @@ confirmInviteUserName: FlatLabel(defaultFlatLabel) {
|
||||
confirmInviteUserNameTop: 227px;
|
||||
|
||||
confirmPhoneAboutLabel: FlatLabel(defaultFlatLabel) {
|
||||
minWidth: 282px;
|
||||
minWidth: 272px;
|
||||
}
|
||||
confirmPhoneCodeField: InputField(defaultInputField) {
|
||||
}
|
||||
@@ -158,27 +158,28 @@ contactsMarginBottom: 4px;
|
||||
membersMarginTop: 10px;
|
||||
membersMarginBottom: 10px;
|
||||
|
||||
peerListBoxItem: PeerListItem(defaultPeerListItem) {
|
||||
height: 56px;
|
||||
photoSize: contactsPhotoSize;
|
||||
photoPosition: point(16px, 7px);
|
||||
namePosition: point(74px, 9px);
|
||||
statusPosition: point(74px, 30px);
|
||||
button: OutlineButton(defaultPeerListButton) {
|
||||
textBg: contactsBg;
|
||||
textBgOver: contactsBgOver;
|
||||
ripple: defaultRippleAnimation;
|
||||
}
|
||||
statusFg: contactsStatusFg;
|
||||
statusFgOver: contactsStatusFgOver;
|
||||
statusFgActive: contactsStatusFgOnline;
|
||||
}
|
||||
peerListBox: PeerList(defaultPeerList) {
|
||||
padding: margins(
|
||||
0px,
|
||||
membersMarginTop,
|
||||
0px,
|
||||
membersMarginBottom);
|
||||
item: PeerListItem(defaultPeerListItem) {
|
||||
height: 56px;
|
||||
photoSize: contactsPhotoSize;
|
||||
photoPosition: point(16px, 7px);
|
||||
namePosition: point(74px, 9px);
|
||||
statusPosition: point(74px, 30px);
|
||||
button: OutlineButton(defaultPeerListButton) {
|
||||
textBg: contactsBg;
|
||||
textBgOver: contactsBgOver;
|
||||
ripple: defaultRippleAnimation;
|
||||
}
|
||||
statusFg: contactsStatusFg;
|
||||
statusFgOver: contactsStatusFgOver;
|
||||
statusFgActive: contactsStatusFgOnline;
|
||||
}
|
||||
item: peerListBoxItem;
|
||||
}
|
||||
|
||||
localStorageRowHeight: 50px;
|
||||
@@ -214,17 +215,23 @@ localStorageLimitMargin: margins(22px, 5px, 20px, 10px);
|
||||
shareRowsTop: 12px;
|
||||
shareRowHeight: 108px;
|
||||
sharePhotoTop: 6px;
|
||||
sharePhotoCheckbox: RoundImageCheckbox(defaultPeerListCheckbox) {
|
||||
imageRadius: 28px;
|
||||
imageSmallRadius: 24px;
|
||||
shareBoxListItem: PeerListItem(defaultPeerListItem) {
|
||||
nameStyle: TextStyle(defaultTextStyle) {
|
||||
font: font(11px);
|
||||
linkFont: font(11px);
|
||||
linkFontOver: font(11px);
|
||||
}
|
||||
nameFg: windowFg;
|
||||
nameFgChecked: windowActiveTextFg;
|
||||
checkbox: RoundImageCheckbox(defaultPeerListCheckbox) {
|
||||
imageRadius: 28px;
|
||||
imageSmallRadius: 24px;
|
||||
}
|
||||
}
|
||||
shareNameStyle: TextStyle(defaultTextStyle) {
|
||||
font: font(11px);
|
||||
linkFont: font(11px);
|
||||
linkFontOver: font(11px);
|
||||
shareBoxList: PeerList(defaultPeerList) {
|
||||
bg: boxBg;
|
||||
item: shareBoxListItem;
|
||||
}
|
||||
shareNameFg: windowFg;
|
||||
shareNameActiveFg: windowActiveTextFg;
|
||||
shareNameTop: 6px;
|
||||
shareColumnSkip: 6px;
|
||||
shareActivateDuration: 150;
|
||||
|
||||
@@ -78,7 +78,7 @@ protected:
|
||||
private:
|
||||
void submit();
|
||||
void sendPhoneDone(const MTPauth_SentCode &result, const QString &phoneNumber);
|
||||
void sendPhoneFail(const RPCError &error, const QString &phoneNumber);
|
||||
void sendPhoneFail(const MTP::Error &error, const QString &phoneNumber);
|
||||
void showError(const QString &text);
|
||||
void hideError() {
|
||||
showError(QString());
|
||||
@@ -114,7 +114,7 @@ private:
|
||||
void submit();
|
||||
void sendCall();
|
||||
void updateCall();
|
||||
void sendCodeFail(const RPCError &error);
|
||||
void sendCodeFail(const MTP::Error &error);
|
||||
void showError(const QString &text);
|
||||
void hideError() {
|
||||
showError(QString());
|
||||
@@ -180,7 +180,7 @@ void ChangePhoneBox::EnterPhone::submit() {
|
||||
MTP_codeSettings(MTP_flags(0))
|
||||
)).done([=](const MTPauth_SentCode &result) {
|
||||
sendPhoneDone(result, phoneNumber);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
sendPhoneFail(error, phoneNumber);
|
||||
}).handleFloodErrors().send();
|
||||
}
|
||||
@@ -222,9 +222,9 @@ void ChangePhoneBox::EnterPhone::sendPhoneDone(
|
||||
Ui::LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
void ChangePhoneBox::EnterPhone::sendPhoneFail(const RPCError &error, const QString &phoneNumber) {
|
||||
void ChangePhoneBox::EnterPhone::sendPhoneFail(const MTP::Error &error, const QString &phoneNumber) {
|
||||
_requestId = 0;
|
||||
if (MTP::isFloodError(error)) {
|
||||
if (MTP::IsFloodError(error)) {
|
||||
showError(tr::lng_flood_error(tr::now));
|
||||
} else if (error.type() == qstr("PHONE_NUMBER_INVALID")) {
|
||||
showError(tr::lng_bad_phone(tr::now));
|
||||
@@ -320,7 +320,7 @@ void ChangePhoneBox::EnterCode::submit() {
|
||||
Ui::hideLayer();
|
||||
}
|
||||
Ui::Toast::Show(tr::lng_change_phone_success(tr::now));
|
||||
}).fail(crl::guard(this, [=](const RPCError &error) {
|
||||
}).fail(crl::guard(this, [=](const MTP::Error &error) {
|
||||
sendCodeFail(error);
|
||||
})).handleFloodErrors().send();
|
||||
}
|
||||
@@ -354,9 +354,9 @@ void ChangePhoneBox::EnterCode::showError(const QString &text) {
|
||||
}
|
||||
}
|
||||
|
||||
void ChangePhoneBox::EnterCode::sendCodeFail(const RPCError &error) {
|
||||
void ChangePhoneBox::EnterCode::sendCodeFail(const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
if (MTP::isFloodError(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")) {
|
||||
showError(tr::lng_bad_code(tr::now));
|
||||
|
||||
@@ -536,7 +536,7 @@ void PinMessageBox::pinMessage() {
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
_peer->session().api().applyUpdates(result);
|
||||
Ui::hideLayer();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
Ui::hideLayer();
|
||||
}).send();
|
||||
}
|
||||
@@ -762,11 +762,11 @@ auto DeleteMessagesBox::revokeText(not_null<PeerData*> peer) const
|
||||
return result;
|
||||
}
|
||||
|
||||
const auto items = ranges::view::all(
|
||||
const auto items = ranges::views::all(
|
||||
_ids
|
||||
) | ranges::view::transform([&](FullMsgId id) {
|
||||
) | ranges::views::transform([&](FullMsgId id) {
|
||||
return peer->owner().message(id);
|
||||
}) | ranges::view::filter([](HistoryItem *item) {
|
||||
}) | ranges::views::filter([](HistoryItem *item) {
|
||||
return (item != nullptr);
|
||||
}) | ranges::to_vector;
|
||||
|
||||
@@ -783,7 +783,7 @@ auto DeleteMessagesBox::revokeText(not_null<PeerData*> peer) const
|
||||
return !item->canDeleteForEveryone(now);
|
||||
};
|
||||
const auto canRevokeAll = ranges::none_of(items, cannotRevoke);
|
||||
auto outgoing = items | ranges::view::filter(&HistoryItem::out);
|
||||
auto outgoing = items | ranges::views::filter(&HistoryItem::out);
|
||||
const auto canRevokeOutgoingCount = canRevokeAll
|
||||
? -1
|
||||
: ranges::count_if(outgoing, canRevoke);
|
||||
|
||||
@@ -249,7 +249,7 @@ void ConfirmPhoneBox::checkPhoneAndHash() {
|
||||
MTP_codeSettings(MTP_flags(0))
|
||||
)).done([=](const MTPauth_SentCode &result) {
|
||||
sendCodeDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
sendCodeFail(error);
|
||||
}).handleFloodErrors().send();
|
||||
}
|
||||
@@ -278,9 +278,9 @@ void ConfirmPhoneBox::sendCodeDone(const MTPauth_SentCode &result) {
|
||||
});
|
||||
}
|
||||
|
||||
void ConfirmPhoneBox::sendCodeFail(const RPCError &error) {
|
||||
void ConfirmPhoneBox::sendCodeFail(const MTP::Error &error) {
|
||||
auto errorText = Lang::Hard::ServerError();
|
||||
if (MTP::isFloodError(error)) {
|
||||
if (MTP::IsFloodError(error)) {
|
||||
errorText = tr::lng_flood_error(tr::now);
|
||||
} else if (error.code() == 400) {
|
||||
errorText = tr::lng_confirm_phone_link_invalid(tr::now);
|
||||
@@ -348,7 +348,7 @@ void ConfirmPhoneBox::sendCode() {
|
||||
MTP_string(code)
|
||||
)).done([=](const MTPBool &result) {
|
||||
confirmDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
confirmFail(error);
|
||||
}).handleFloodErrors().send();
|
||||
}
|
||||
@@ -358,9 +358,9 @@ void ConfirmPhoneBox::confirmDone(const MTPBool &result) {
|
||||
Ui::show(Box<InformBox>(tr::lng_confirm_phone_success(tr::now, lt_phone, App::formatPhone(_phone))));
|
||||
}
|
||||
|
||||
void ConfirmPhoneBox::confirmFail(const RPCError &error) {
|
||||
void ConfirmPhoneBox::confirmFail(const MTP::Error &error) {
|
||||
auto errorText = Lang::Hard::ServerError();
|
||||
if (MTP::isFloodError(error)) {
|
||||
if (MTP::IsFloodError(error)) {
|
||||
errorText = tr::lng_flood_error(tr::now);
|
||||
} else {
|
||||
auto &errorType = error.type();
|
||||
|
||||
@@ -121,12 +121,12 @@ private:
|
||||
void checkPhoneAndHash();
|
||||
|
||||
void sendCodeDone(const MTPauth_SentCode &result);
|
||||
void sendCodeFail(const RPCError &error);
|
||||
void sendCodeFail(const MTP::Error &error);
|
||||
|
||||
void callDone(const MTPauth_SentCode &result);
|
||||
|
||||
void confirmDone(const MTPBool &result);
|
||||
void confirmFail(const RPCError &error);
|
||||
void confirmFail(const MTP::Error &error);
|
||||
|
||||
QString getPhone() const {
|
||||
return _phone;
|
||||
|
||||
@@ -896,7 +896,7 @@ void ProxyBox::setupTypes() {
|
||||
{ Type::Socks5, "SOCKS5" },
|
||||
{ Type::Mtproto, "MTPROTO" },
|
||||
};
|
||||
for (const auto [type, label] : types) {
|
||||
for (const auto &[type, label] : types) {
|
||||
_content->add(
|
||||
object_ptr<Ui::Radioenum<Type>>(
|
||||
_content,
|
||||
@@ -1051,9 +1051,9 @@ void ProxyBox::addLabel(
|
||||
ProxiesBoxController::ProxiesBoxController(not_null<Main::Account*> account)
|
||||
: _account(account)
|
||||
, _saveTimer([] { Local::writeSettings(); }) {
|
||||
_list = ranges::view::all(
|
||||
_list = ranges::views::all(
|
||||
Global::ProxiesList()
|
||||
) | ranges::view::transform([&](const ProxyData &proxy) {
|
||||
) | ranges::views::transform([&](const ProxyData &proxy) {
|
||||
return Item{ ++_idCounter, proxy };
|
||||
}) | ranges::to_vector;
|
||||
|
||||
|
||||
@@ -536,8 +536,8 @@ std::vector<PollAnswer> Options::toPollAnswers() const {
|
||||
};
|
||||
ranges::copy(
|
||||
_list
|
||||
| ranges::view::filter(&Option::isGood)
|
||||
| ranges::view::transform(makeAnswer),
|
||||
| ranges::views::filter(&Option::isGood)
|
||||
| ranges::views::transform(makeAnswer),
|
||||
ranges::back_inserter(result));
|
||||
return result;
|
||||
}
|
||||
@@ -593,7 +593,7 @@ void Options::removeEmptyTail() {
|
||||
_list,
|
||||
&Option::hasFocus);
|
||||
const auto end = _list.end();
|
||||
const auto reversed = ranges::view::reverse(_list);
|
||||
const auto reversed = ranges::views::reverse(_list);
|
||||
const auto emptyItem = ranges::find_if(
|
||||
reversed,
|
||||
ranges::not_fn(&Option::isEmpty)).base();
|
||||
|
||||
@@ -1045,13 +1045,13 @@ void EditCaptionBox::save() {
|
||||
if (!_preparedList.files.empty()) {
|
||||
auto action = Api::SendAction(item->history());
|
||||
action.options = options;
|
||||
action.replaceMediaOf = item->fullId().msg;
|
||||
|
||||
_controller->session().api().editMedia(
|
||||
std::move(_preparedList),
|
||||
(!_asFile && _photo) ? SendMediaType::Photo : SendMediaType::File,
|
||||
_field->getTextWithAppliedMarkdown(),
|
||||
action,
|
||||
item->fullId().msg);
|
||||
action);
|
||||
closeBox();
|
||||
return;
|
||||
}
|
||||
@@ -1061,7 +1061,7 @@ void EditCaptionBox::save() {
|
||||
closeBox();
|
||||
});
|
||||
|
||||
const auto fail = crl::guard(this, [=](const RPCError &error) {
|
||||
const auto fail = crl::guard(this, [=](const MTP::Error &error) {
|
||||
_saveRequestId = 0;
|
||||
const auto &type = error.type();
|
||||
if (ranges::contains(Api::kDefaultEditMessagesErrors, type)) {
|
||||
|
||||
@@ -668,7 +668,7 @@ void EditColorBox::Field::changeValue(int delta) {
|
||||
setText(QString::number(newValue));
|
||||
setFocus();
|
||||
selectAll();
|
||||
emit changed();
|
||||
changed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -333,9 +333,9 @@ void EditExceptions(
|
||||
box->addButton(tr::lng_settings_save(), crl::guard(context, [=] {
|
||||
const auto peers = box->collectSelectedRows();
|
||||
const auto rules = data->current();
|
||||
auto &&histories = ranges::view::all(
|
||||
auto &&histories = ranges::views::all(
|
||||
peers
|
||||
) | ranges::view::transform([=](not_null<PeerData*> peer) {
|
||||
) | ranges::views::transform([=](not_null<PeerData*> peer) {
|
||||
return window->session().data().history(peer);
|
||||
});
|
||||
auto changed = base::flat_set<not_null<History*>>{
|
||||
|
||||
@@ -424,11 +424,11 @@ void Rows::remove(not_null<Row*> row) {
|
||||
|
||||
void Rows::restore(not_null<Row*> row) {
|
||||
row->removed = false;
|
||||
Local::saveRecentLanguages(ranges::view::all(
|
||||
Local::saveRecentLanguages(ranges::views::all(
|
||||
_rows
|
||||
) | ranges::view::filter([](const Row &row) {
|
||||
) | ranges::views::filter([](const Row &row) {
|
||||
return !row.removed;
|
||||
}) | ranges::view::transform([](const Row &row) {
|
||||
}) | ranges::views::transform([](const Row &row) {
|
||||
return row.data;
|
||||
}) | ranges::to_vector);
|
||||
}
|
||||
@@ -464,7 +464,6 @@ void Rows::showMenu(int index) {
|
||||
Fn<void()> callback) {
|
||||
return _menu->addAction(text, std::move(callback));
|
||||
};
|
||||
const auto id = row->data.id;
|
||||
if (canShare(row)) {
|
||||
addAction(tr::lng_proxy_edit_share(tr::now), [=] { share(row); });
|
||||
}
|
||||
|
||||
@@ -360,8 +360,8 @@ void PasscodeBox::closeReplacedBy() {
|
||||
}
|
||||
}
|
||||
|
||||
void PasscodeBox::setPasswordFail(const RPCError &error) {
|
||||
if (MTP::isFloodError(error)) {
|
||||
void PasscodeBox::setPasswordFail(const MTP::Error &error) {
|
||||
if (MTP::IsFloodError(error)) {
|
||||
closeReplacedBy();
|
||||
_setRequest = 0;
|
||||
|
||||
@@ -402,10 +402,10 @@ void PasscodeBox::setPasswordFail(const RPCError &error) {
|
||||
void PasscodeBox::setPasswordFail(
|
||||
const QByteArray &newPasswordBytes,
|
||||
const QString &email,
|
||||
const RPCError &error) {
|
||||
const MTP::Error &error) {
|
||||
const auto prefix = qstr("EMAIL_UNCONFIRMED_");
|
||||
if (error.type().startsWith(prefix)) {
|
||||
const auto codeLength = error.type().mid(prefix.size()).toInt();
|
||||
const auto codeLength = error.type().midRef(prefix.size()).toInt();
|
||||
|
||||
closeReplacedBy();
|
||||
_setRequest = 0;
|
||||
@@ -432,9 +432,9 @@ void PasscodeBox::validateEmail(
|
||||
)).done([=](const MTPBool &result) {
|
||||
*set = true;
|
||||
setPasswordDone(newPasswordBytes);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_setRequest = 0;
|
||||
if (MTP::isFloodError(error)) {
|
||||
if (MTP::IsFloodError(error)) {
|
||||
errors->fire(tr::lng_flood_error(tr::now));
|
||||
} else if (error.type() == qstr("CODE_INVALID")) {
|
||||
errors->fire(tr::lng_signin_wrong_code(tr::now));
|
||||
@@ -461,7 +461,7 @@ void PasscodeBox::validateEmail(
|
||||
)).done([=](const MTPBool &result) {
|
||||
_setRequest = 0;
|
||||
resent->fire(tr::lng_cloud_password_resent(tr::now));
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_setRequest = 0;
|
||||
errors->fire(Lang::Hard::ServerError());
|
||||
}).send();
|
||||
@@ -681,9 +681,9 @@ void PasscodeBox::serverError() {
|
||||
closeBox();
|
||||
}
|
||||
|
||||
bool PasscodeBox::handleCustomCheckError(const RPCError &error) {
|
||||
bool PasscodeBox::handleCustomCheckError(const MTP::Error &error) {
|
||||
const auto &type = error.type();
|
||||
if (MTP::isFloodError(error)
|
||||
if (MTP::IsFloodError(error)
|
||||
|| type == qstr("PASSWORD_HASH_INVALID")
|
||||
|| type == qstr("SRP_PASSWORD_CHANGED")
|
||||
|| type == qstr("SRP_ID_INVALID")) {
|
||||
@@ -695,8 +695,6 @@ bool PasscodeBox::handleCustomCheckError(const RPCError &error) {
|
||||
|
||||
void PasscodeBox::sendClearCloudPassword(
|
||||
const Core::CloudPasswordResult &check) {
|
||||
const auto newPasswordData = QByteArray();
|
||||
const auto newPasswordHash = QByteArray();
|
||||
const auto hint = QString();
|
||||
const auto email = QString();
|
||||
const auto flags = MTPDaccount_passwordInputSettings::Flag::f_new_algo
|
||||
@@ -714,7 +712,7 @@ void PasscodeBox::sendClearCloudPassword(
|
||||
MTPSecureSecretSettings())
|
||||
)).done([=](const MTPBool &result) {
|
||||
setPasswordDone({});
|
||||
}).fail([=](const RPCError &error) mutable {
|
||||
}).fail([=](const MTP::Error &error) mutable {
|
||||
setPasswordFail({}, QString(), error);
|
||||
}).handleFloodErrors().send();
|
||||
}
|
||||
@@ -745,7 +743,7 @@ void PasscodeBox::setNewCloudPassword(const QString &newPassword) {
|
||||
MTPSecureSecretSettings())
|
||||
)).done([=](const MTPBool &result) {
|
||||
setPasswordDone(newPasswordBytes);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
setPasswordFail(newPasswordBytes, email, error);
|
||||
}).handleFloodErrors().send();
|
||||
}
|
||||
@@ -800,7 +798,7 @@ void PasscodeBox::changeCloudPassword(
|
||||
sendChangeCloudPassword(check, newPassword, secureSecret);
|
||||
});
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
setPasswordFail(error);
|
||||
}).handleFloodErrors().send();
|
||||
}
|
||||
@@ -842,7 +840,7 @@ void PasscodeBox::resetSecret(
|
||||
const auto empty = QByteArray();
|
||||
sendChangeCloudPassword(check, newPassword, empty);
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_setRequest = 0;
|
||||
if (error.type() == qstr("SRP_ID_INVALID")) {
|
||||
handleSrpIdInvalid();
|
||||
@@ -891,7 +889,7 @@ void PasscodeBox::sendChangeCloudPassword(
|
||||
MTP_long(newSecureSecretId)))
|
||||
)).done([=](const MTPBool &result) {
|
||||
setPasswordDone(newPasswordBytes);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
setPasswordFail(newPasswordBytes, QString(), error);
|
||||
}).handleFloodErrors().send();
|
||||
}
|
||||
@@ -939,7 +937,7 @@ void PasscodeBox::recoverByEmail() {
|
||||
_api.request(MTPauth_RequestPasswordRecovery(
|
||||
)).done([=](const MTPauth_PasswordRecovery &result) {
|
||||
recoverStarted(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
recoverStartFail(error);
|
||||
}).send();
|
||||
} else {
|
||||
@@ -977,7 +975,7 @@ void PasscodeBox::recoverStarted(const MTPauth_PasswordRecovery &result) {
|
||||
recover();
|
||||
}
|
||||
|
||||
void PasscodeBox::recoverStartFail(const RPCError &error) {
|
||||
void PasscodeBox::recoverStartFail(const MTP::Error &error) {
|
||||
_pattern = QString();
|
||||
closeBox();
|
||||
}
|
||||
@@ -1055,7 +1053,7 @@ void RecoverBox::submit() {
|
||||
MTP_string(code)
|
||||
)).done([=](const MTPauth_Authorization &result) {
|
||||
codeSubmitDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
codeSubmitFail(error);
|
||||
}).handleFloodErrors().send();
|
||||
});
|
||||
@@ -1087,8 +1085,8 @@ void RecoverBox::codeSubmitDone(const MTPauth_Authorization &result) {
|
||||
Ui::LayerOption::CloseOther);
|
||||
}
|
||||
|
||||
void RecoverBox::codeSubmitFail(const RPCError &error) {
|
||||
if (MTP::isFloodError(error)) {
|
||||
void RecoverBox::codeSubmitFail(const MTP::Error &error) {
|
||||
if (MTP::IsFloodError(error)) {
|
||||
_submitRequest = 0;
|
||||
_error = tr::lng_flood_error(tr::now);
|
||||
update();
|
||||
@@ -1149,9 +1147,9 @@ RecoveryEmailValidation ConfirmRecoveryEmail(
|
||||
Box<InformBox>(tr::lng_cloud_password_was_set(tr::now)),
|
||||
Ui::LayerOption::CloseOther);
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
*requestId = 0;
|
||||
if (MTP::isFloodError(error)) {
|
||||
if (MTP::IsFloodError(error)) {
|
||||
errors->fire(tr::lng_flood_error(tr::now));
|
||||
} else if (error.type() == qstr("CODE_INVALID")) {
|
||||
errors->fire(tr::lng_signin_wrong_code(tr::now));
|
||||
@@ -1177,7 +1175,7 @@ RecoveryEmailValidation ConfirmRecoveryEmail(
|
||||
)).done([=](const MTPBool &result) {
|
||||
*requestId = 0;
|
||||
resent->fire(tr::lng_cloud_password_resent(tr::now));
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
*requestId = 0;
|
||||
errors->fire(Lang::Hard::ServerError());
|
||||
}).send();
|
||||
@@ -1196,7 +1194,7 @@ RecoveryEmailValidation ConfirmRecoveryEmail(
|
||||
}
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::GenericBox> PrePasswordErrorBox(
|
||||
const RPCError &error,
|
||||
const MTP::Error &error,
|
||||
not_null<Main::Session*> session,
|
||||
TextWithEntities &&about) {
|
||||
const auto type = [&] {
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
rpl::producer<> passwordReloadNeeded() const;
|
||||
rpl::producer<> clearUnconfirmedPassword() const;
|
||||
|
||||
bool handleCustomCheckError(const RPCError &error);
|
||||
bool handleCustomCheckError(const MTP::Error &error);
|
||||
|
||||
protected:
|
||||
void prepare() override;
|
||||
@@ -81,18 +81,18 @@ private:
|
||||
bool onlyCheckCurrent() const;
|
||||
|
||||
void setPasswordDone(const QByteArray &newPasswordBytes);
|
||||
void setPasswordFail(const RPCError &error);
|
||||
void setPasswordFail(const MTP::Error &error);
|
||||
void setPasswordFail(
|
||||
const QByteArray &newPasswordBytes,
|
||||
const QString &email,
|
||||
const RPCError &error);
|
||||
const MTP::Error &error);
|
||||
void validateEmail(
|
||||
const QString &email,
|
||||
int codeLength,
|
||||
const QByteArray &newPasswordBytes);
|
||||
|
||||
void recoverStarted(const MTPauth_PasswordRecovery &result);
|
||||
void recoverStartFail(const RPCError &error);
|
||||
void recoverStartFail(const MTP::Error &error);
|
||||
|
||||
void recover();
|
||||
void submitOnlyCheckCloudPassword(const QString &oldPassword);
|
||||
@@ -189,7 +189,7 @@ private:
|
||||
void submit();
|
||||
void codeChanged();
|
||||
void codeSubmitDone(const MTPauth_Authorization &result);
|
||||
void codeSubmitFail(const RPCError &error);
|
||||
void codeSubmitFail(const MTP::Error &error);
|
||||
|
||||
MTP::Sender _api;
|
||||
mtpRequestId _submitRequest = 0;
|
||||
@@ -216,6 +216,6 @@ struct RecoveryEmailValidation {
|
||||
const QString &pattern);
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::GenericBox> PrePasswordErrorBox(
|
||||
const RPCError &error,
|
||||
const MTP::Error &error,
|
||||
not_null<Main::Session*> session,
|
||||
TextWithEntities &&about);
|
||||
|
||||
@@ -705,6 +705,10 @@ void PeerListRow::setCheckedInternal(bool checked, anim::type animated) {
|
||||
_checkbox->setChecked(checked, animated);
|
||||
}
|
||||
|
||||
void PeerListRow::finishCheckedAnimation() {
|
||||
_checkbox->setChecked(_checkbox->checked(), anim::type::instant);
|
||||
}
|
||||
|
||||
PeerListContent::PeerListContent(
|
||||
QWidget *parent,
|
||||
not_null<PeerListController*> controller)
|
||||
|
||||
@@ -169,6 +169,7 @@ public:
|
||||
}
|
||||
setCheckedInternal(checked, animated);
|
||||
}
|
||||
void finishCheckedAnimation();
|
||||
void invalidatePixmapsCache();
|
||||
|
||||
template <typename UpdateCallback>
|
||||
|
||||
@@ -54,7 +54,7 @@ void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
api->applyUpdates(result, randomId);
|
||||
finish();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
api->sendMessageFail(error, chat);
|
||||
finish();
|
||||
}).afterRequest(
|
||||
@@ -195,7 +195,7 @@ void PeerListGlobalSearchController::searchOnServer() {
|
||||
MTP_int(SearchPeopleLimit)
|
||||
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {
|
||||
searchDone(result, requestId);
|
||||
}).fail([=](const RPCError &error, mtpRequestId requestId) {
|
||||
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
|
||||
if (_requestId == requestId) {
|
||||
_requestId = 0;
|
||||
delegate()->peerListSearchRefreshRows();
|
||||
|
||||
@@ -219,9 +219,9 @@ bool AddParticipantsBoxController::inviteSelectedUsers(
|
||||
Expects(_peer != nullptr);
|
||||
|
||||
const auto rows = box->collectSelectedRows();
|
||||
const auto users = ranges::view::all(
|
||||
const auto users = ranges::views::all(
|
||||
rows
|
||||
) | ranges::view::transform([](not_null<PeerData*> peer) {
|
||||
) | ranges::views::transform([](not_null<PeerData*> peer) {
|
||||
Expects(peer->isUser());
|
||||
Expects(!peer->isSelf());
|
||||
|
||||
@@ -485,7 +485,7 @@ void AddSpecialBoxController::loadMoreRows() {
|
||||
setDescriptionText(tr::lng_blocked_list_not_found(tr::now));
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
}).fail([this](const RPCError &error) {
|
||||
}).fail([this](const MTP::Error &error) {
|
||||
_loadRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
@@ -520,7 +520,7 @@ bool AddSpecialBoxController::checkInfoLoaded(
|
||||
channel->owner().processUsers(participant.vusers());
|
||||
_additional.applyParticipant(participant.vparticipant());
|
||||
callback();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_additional.setExternal(user);
|
||||
callback();
|
||||
}).send();
|
||||
@@ -976,7 +976,7 @@ void AddSpecialBoxSearchController::requestParticipants() {
|
||||
const MTPchannels_ChannelParticipants &result,
|
||||
mtpRequestId requestId) {
|
||||
searchParticipantsDone(requestId, result, perPage);
|
||||
}).fail([=](const RPCError &error, mtpRequestId requestId) {
|
||||
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
|
||||
if (_requestId == requestId) {
|
||||
_requestId = 0;
|
||||
_participantsLoaded = true;
|
||||
@@ -1059,7 +1059,7 @@ void AddSpecialBoxSearchController::requestGlobal() {
|
||||
MTP_int(perPage)
|
||||
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {
|
||||
searchGlobalDone(requestId, result);
|
||||
}).fail([=](const RPCError &error, mtpRequestId requestId) {
|
||||
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
|
||||
if (_requestId == requestId) {
|
||||
_requestId = 0;
|
||||
_globalLoaded = true;
|
||||
|
||||
@@ -75,7 +75,7 @@ void SendRequest(
|
||||
lt_user,
|
||||
first));
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
}).send();
|
||||
}
|
||||
|
||||
|
||||
@@ -444,7 +444,7 @@ void EditAdminBox::transferOwnership() {
|
||||
channel,
|
||||
MTP_inputUserEmpty(),
|
||||
MTP_inputCheckPasswordEmpty()
|
||||
)).fail([=](const RPCError &error) {
|
||||
)).fail([=](const MTP::Error &error) {
|
||||
_checkTransferRequestId = 0;
|
||||
if (!handleTransferPasswordError(error)) {
|
||||
getDelegate()->show(Box<ConfirmBox>(
|
||||
@@ -461,7 +461,7 @@ void EditAdminBox::transferOwnership() {
|
||||
}).send();
|
||||
}
|
||||
|
||||
bool EditAdminBox::handleTransferPasswordError(const RPCError &error) {
|
||||
bool EditAdminBox::handleTransferPasswordError(const MTP::Error &error) {
|
||||
const auto session = &user()->session();
|
||||
auto about = tr::lng_rights_transfer_check_about(
|
||||
tr::now,
|
||||
@@ -533,7 +533,7 @@ void EditAdminBox::sendTransferRequestFrom(
|
||||
lt_user,
|
||||
user->shortName()));
|
||||
Ui::hideLayer();
|
||||
}).fail(crl::guard(this, [=](const RPCError &error) {
|
||||
}).fail(crl::guard(this, [=](const MTP::Error &error) {
|
||||
if (weak) {
|
||||
_transferRequestId = 0;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/abstract_box.h"
|
||||
#include "base/unique_qptr.h"
|
||||
|
||||
class RPCError;
|
||||
namespace MTP {
|
||||
class Error;
|
||||
} // namespace MTP
|
||||
|
||||
namespace Ui {
|
||||
class FlatLabel;
|
||||
@@ -94,7 +96,7 @@ private:
|
||||
not_null<Ui::InputField*> addRankInput();
|
||||
void transferOwnership();
|
||||
void transferOwnershipChecked();
|
||||
bool handleTransferPasswordError(const RPCError &error);
|
||||
bool handleTransferPasswordError(const MTP::Error &error);
|
||||
void requestTransferPassword(not_null<ChannelData*> channel);
|
||||
void sendTransferRequestFrom(
|
||||
QPointer<PasscodeBox> box,
|
||||
|
||||
@@ -58,7 +58,7 @@ void RemoveAdmin(
|
||||
if (onDone) {
|
||||
onDone();
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (onFail) {
|
||||
onFail();
|
||||
}
|
||||
@@ -79,7 +79,7 @@ void AddChatParticipant(
|
||||
if (onDone) {
|
||||
onDone();
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
ShowAddParticipantsError(error.type(), chat, { 1, user });
|
||||
if (onFail) {
|
||||
onFail();
|
||||
@@ -103,7 +103,7 @@ void SaveChatAdmin(
|
||||
if (onDone) {
|
||||
onDone();
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto &type = error.type();
|
||||
if (retryOnNotParticipant
|
||||
&& isAdmin
|
||||
@@ -136,7 +136,7 @@ void SaveChannelAdmin(
|
||||
if (onDone) {
|
||||
onDone();
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
ShowAddParticipantsError(error.type(), channel, { 1, user });
|
||||
if (onFail) {
|
||||
onFail();
|
||||
@@ -161,7 +161,7 @@ void SaveChannelRestriction(
|
||||
if (onDone) {
|
||||
onDone();
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (onFail) {
|
||||
onFail();
|
||||
}
|
||||
@@ -182,7 +182,7 @@ void SaveChatParticipantKick(
|
||||
if (onDone) {
|
||||
onDone();
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (onFail) {
|
||||
onFail();
|
||||
}
|
||||
@@ -1196,7 +1196,7 @@ void ParticipantsBoxController::rebuildChatAdmins(
|
||||
return;
|
||||
}
|
||||
|
||||
auto list = ranges::view::all(chat->admins) | ranges::to_vector;
|
||||
auto list = ranges::views::all(chat->admins) | ranges::to_vector;
|
||||
if (const auto creator = chat->owner().userLoaded(chat->creator)) {
|
||||
list.emplace_back(creator);
|
||||
}
|
||||
@@ -1336,7 +1336,7 @@ void ParticipantsBoxController::loadMoreRows() {
|
||||
_onlineSorter->sort();
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
}).fail([this](const RPCError &error) {
|
||||
}).fail([this](const MTP::Error &error) {
|
||||
_loadRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
@@ -2071,7 +2071,7 @@ bool ParticipantsBoxSearchController::loadMoreRows() {
|
||||
const MTPchannels_ChannelParticipants &result,
|
||||
mtpRequestId requestId) {
|
||||
searchDone(requestId, result, perPage);
|
||||
}).fail([=](const RPCError &error, mtpRequestId requestId) {
|
||||
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
|
||||
if (_requestId == requestId) {
|
||||
_requestId = 0;
|
||||
_allLoaded = true;
|
||||
|
||||
@@ -153,7 +153,7 @@ void SaveDefaultRestrictions(
|
||||
api->clearModifyRequest(key);
|
||||
api->applyUpdates(result);
|
||||
done();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
api->clearModifyRequest(key);
|
||||
if (error.type() != qstr("CHAT_NOT_MODIFIED")) {
|
||||
return;
|
||||
@@ -186,7 +186,7 @@ void SaveSlowmodeSeconds(
|
||||
api->applyUpdates(result);
|
||||
channel->setSlowmodeSeconds(seconds);
|
||||
done();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
api->clearModifyRequest(key);
|
||||
if (error.type() != qstr("CHAT_NOT_MODIFIED")) {
|
||||
return;
|
||||
@@ -235,7 +235,7 @@ void ShowEditPermissions(
|
||||
const auto api = &peer->session().api();
|
||||
api->migrateChat(chat, [=](not_null<ChannelData*> channel) {
|
||||
save(channel, result);
|
||||
}, [=](const RPCError &error) {
|
||||
}, [=](const MTP::Error &error) {
|
||||
*saving = false;
|
||||
});
|
||||
}, box->lifetime());
|
||||
@@ -278,7 +278,7 @@ void ShowEditInviteLinks(
|
||||
const auto api = &peer->session().api();
|
||||
api->migrateChat(chat, [=](not_null<ChannelData*> channel) {
|
||||
save(channel, result);
|
||||
}, [=](const RPCError &error) {
|
||||
}, [=](const MTP::Error &error) {
|
||||
*saving = false;
|
||||
});
|
||||
}, box->lifetime());
|
||||
@@ -716,7 +716,7 @@ void Controller::showEditLinkedChatBox() {
|
||||
std::move(chats),
|
||||
callback),
|
||||
Ui::LayerOption::KeepOther);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_linkedChatsRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
@@ -1290,7 +1290,7 @@ void Controller::saveUsername() {
|
||||
TextUtilities::SingleLine(channel->name),
|
||||
*_savingData.username);
|
||||
continueSave();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto &type = error.type();
|
||||
if (type == qstr("USERNAME_NOT_MODIFIED")) {
|
||||
channel->setName(
|
||||
@@ -1343,7 +1343,7 @@ void Controller::saveLinkedChat() {
|
||||
)).done([=](const MTPBool &result) {
|
||||
channel->setLinkedChat(*_savingData.linkedChat);
|
||||
continueSave();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto &type = error.type();
|
||||
cancelSave();
|
||||
}).send();
|
||||
@@ -1358,7 +1358,7 @@ void Controller::saveTitle() {
|
||||
_peer->session().api().applyUpdates(result);
|
||||
continueSave();
|
||||
};
|
||||
const auto onFail = [=](const RPCError &error) {
|
||||
const auto onFail = [=](const MTP::Error &error) {
|
||||
const auto &type = error.type();
|
||||
if (type == qstr("CHAT_NOT_MODIFIED")
|
||||
|| type == qstr("CHAT_TITLE_NOT_MODIFIED")) {
|
||||
@@ -1411,7 +1411,7 @@ void Controller::saveDescription() {
|
||||
MTP_string(*_savingData.description)
|
||||
)).done([=](const MTPBool &result) {
|
||||
successCallback();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto &type = error.type();
|
||||
if (type == qstr("CHAT_ABOUT_NOT_MODIFIED")) {
|
||||
successCallback();
|
||||
@@ -1469,7 +1469,7 @@ void Controller::togglePreHistoryHidden(
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
channel->session().api().applyUpdates(result);
|
||||
apply();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (error.type() == qstr("CHAT_NOT_MODIFIED")) {
|
||||
apply();
|
||||
} else {
|
||||
@@ -1491,7 +1491,7 @@ void Controller::saveSignatures() {
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
channel->session().api().applyUpdates(result);
|
||||
continueSave();
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (error.type() == qstr("CHAT_NOT_MODIFIED")) {
|
||||
continueSave();
|
||||
} else {
|
||||
@@ -1546,7 +1546,7 @@ void Controller::deleteChannel() {
|
||||
channel->inputChannel
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
session->api().applyUpdates(result);
|
||||
//}).fail([=](const RPCError &error) {
|
||||
//}).fail([=](const MTP::Error &error) {
|
||||
// if (error.type() == qstr("CHANNEL_TOO_LARGE")) {
|
||||
// Ui::show(Box<InformBox>(tr::lng_cant_delete_channel(tr::now)));
|
||||
// }
|
||||
|
||||
@@ -118,7 +118,7 @@ private:
|
||||
return updated.link.isEmpty() || (!revoked && updated.revoked);
|
||||
}
|
||||
|
||||
QImage QrExact(const Qr::Data &data, int pixel) {
|
||||
QImage QrExact(const Qr::Data &data, int pixel, QColor color) {
|
||||
const auto image = [](int size) {
|
||||
auto result = QImage(
|
||||
size,
|
||||
@@ -141,7 +141,7 @@ QImage QrExact(const Qr::Data &data, int pixel) {
|
||||
return result;
|
||||
};
|
||||
return Qr::ReplaceCenter(
|
||||
Qr::Generate(data, pixel, st::windowFg->c),
|
||||
Qr::Generate(data, pixel, color),
|
||||
image(Qr::ReplaceSize(data, pixel)));
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ QImage Qr(const Qr::Data &data, int pixel, int max = 0) {
|
||||
if (max > 0 && data.size * pixel > max) {
|
||||
pixel = std::max(max / data.size, 1);
|
||||
}
|
||||
return QrExact(data, pixel * style::DevicePixelRatio());
|
||||
return QrExact(data, pixel * style::DevicePixelRatio(), st::windowFg->c);
|
||||
}
|
||||
|
||||
QImage Qr(const QString &text, int pixel, int max) {
|
||||
@@ -161,7 +161,7 @@ QImage Qr(const QString &text, int pixel, int max) {
|
||||
QImage QrForShare(const QString &text) {
|
||||
const auto data = Qr::Encode(text);
|
||||
const auto size = (kShareQrSize - 2 * kShareQrPadding);
|
||||
const auto image = QrExact(data, size / data.size);
|
||||
const auto image = QrExact(data, size / data.size, Qt::black);
|
||||
auto result = QImage(
|
||||
kShareQrPadding * 2 + image.width(),
|
||||
kShareQrPadding * 2 + image.height(),
|
||||
@@ -260,9 +260,9 @@ void Controller::addHeaderBlock(not_null<Ui::VerticalLayout*> container) {
|
||||
const auto editLink = crl::guard(weak, [=] {
|
||||
EditLink(_peer, _data.current());
|
||||
});
|
||||
const auto deleteLink = [=] {
|
||||
const auto deleteLink = crl::guard(weak, [=] {
|
||||
DeleteLink(_peer, admin, link);
|
||||
};
|
||||
});
|
||||
|
||||
const auto createMenu = [=] {
|
||||
auto result = base::make_unique_q<Ui::PopupMenu>(container);
|
||||
@@ -525,7 +525,7 @@ void Controller::loadMoreRows() {
|
||||
auto slice = Api::ParseJoinedByLinkSlice(_peer, result);
|
||||
_allLoaded = slice.users.empty();
|
||||
appendSlice(slice);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_requestId = 0;
|
||||
_allLoaded = true;
|
||||
}).send();
|
||||
@@ -881,6 +881,8 @@ void ShareInviteLinkBox(not_null<PeerData*> peer, const QString &link) {
|
||||
for (auto &tag : comment.tags) {
|
||||
tag.offset += add;
|
||||
}
|
||||
} else {
|
||||
comment.text = link;
|
||||
}
|
||||
const auto owner = &peer->owner();
|
||||
auto &api = peer->session().api();
|
||||
@@ -903,11 +905,12 @@ void ShareInviteLinkBox(not_null<PeerData*> peer, const QString &link) {
|
||||
return peer->canWrite();
|
||||
};
|
||||
*box = Ui::show(
|
||||
Box<ShareBox>(
|
||||
App::wnd()->sessionController(),
|
||||
std::move(copyCallback),
|
||||
std::move(submitCallback),
|
||||
std::move(filterCallback)),
|
||||
Box<ShareBox>(ShareBox::Descriptor{
|
||||
.session = &peer->session(),
|
||||
.copyCallback = std::move(copyCallback),
|
||||
.submitCallback = std::move(submitCallback),
|
||||
.filterCallback = [](auto peer) { return peer->canWrite(); },
|
||||
.navigation = App::wnd()->sessionController() }),
|
||||
Ui::LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ private:
|
||||
link.usageLimit)
|
||||
: tr::lng_group_invite_no_joined(tr::now);
|
||||
const auto add = [&](const QString &text) {
|
||||
result += QString::fromUtf8(" \xE2\xB8\xB1 ") + text;
|
||||
result += QString::fromUtf8(" \xE2\x80\xA2 ") + text;
|
||||
};
|
||||
if (revoked) {
|
||||
return result;
|
||||
@@ -189,8 +189,7 @@ private:
|
||||
left / 86400));
|
||||
} else {
|
||||
const auto time = base::unixtime::parse(link.expireDate).time();
|
||||
add(time.toString(QLocale::system().dateTimeFormat(
|
||||
QLocale::LongFormat)));
|
||||
add(QLocale::system().toString(time, QLocale::LongFormat));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -327,7 +327,7 @@ Fn<void()> AboutGigagroupCallback(not_null<ChannelData*> channel) {
|
||||
channel->session().api().applyUpdates(result);
|
||||
Ui::hideSettingsAndLayer();
|
||||
Ui::Toast::Show(tr::lng_gigagroup_done(tr::now));
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
*converting = false;
|
||||
}).send();
|
||||
};
|
||||
|
||||
@@ -452,7 +452,7 @@ void Controller::checkUsernameAvailability() {
|
||||
} else {
|
||||
showUsernameGood();
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_checkUsernameRequestId = 0;
|
||||
const auto &type = error.type();
|
||||
_usernameState = UsernameState::Normal;
|
||||
|
||||
@@ -131,7 +131,7 @@ void RateCallBox::send() {
|
||||
)).done([=](const MTPUpdates &updates) {
|
||||
_session->api().applyUpdates(updates);
|
||||
closeBox();
|
||||
}).fail([=](const RPCError &error) { closeBox(); }).send();
|
||||
}).fail([=](const MTP::Error &error) { closeBox(); }).send();
|
||||
}
|
||||
|
||||
void RateCallBox::updateMaxHeight() {
|
||||
|
||||
@@ -920,7 +920,7 @@ void SendFilesBox::updateControlsGeometry() {
|
||||
_groupFiles.data(),
|
||||
_sendImagesAsPhotos.data(),
|
||||
};
|
||||
for (const auto pointer : ranges::view::reverse(pointers)) {
|
||||
for (const auto pointer : ranges::views::reverse(pointers)) {
|
||||
if (pointer && !pointer->isHidden()) {
|
||||
pointer->moveToLeft(
|
||||
st::boxPhotoPadding.left(),
|
||||
|
||||
@@ -275,7 +275,7 @@ void SessionsContent::terminateOne(uint64 hash) {
|
||||
removeByHash(_data.list);
|
||||
_inner->showData(_data);
|
||||
});
|
||||
auto fail = crl::guard(weak, [=](const RPCError &error) {
|
||||
auto fail = crl::guard(weak, [=](const MTP::Error &error) {
|
||||
_inner->terminatingOne(hash, false);
|
||||
});
|
||||
_authorizations->requestTerminate(
|
||||
@@ -296,7 +296,7 @@ void SessionsContent::terminateAll() {
|
||||
});
|
||||
_authorizations->requestTerminate(
|
||||
[=](const MTPBool &result) { reset(); },
|
||||
[=](const RPCError &result) { reset(); });
|
||||
[=](const MTP::Error &result) { reset(); });
|
||||
_loading = true;
|
||||
};
|
||||
terminate(std::move(callback), tr::lng_settings_reset_sure(tr::now));
|
||||
|
||||
@@ -44,10 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
class ShareBox::Inner final : public Ui::RpWidget, private base::Subscriber {
|
||||
public:
|
||||
Inner(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
ShareBox::FilterCallback &&filterCallback);
|
||||
Inner(QWidget *parent, const Descriptor &descriptor);
|
||||
|
||||
void setPeerSelectedChangedCallback(
|
||||
Fn<void(PeerData *peer, bool selected)> callback);
|
||||
@@ -84,7 +81,10 @@ protected:
|
||||
|
||||
private:
|
||||
struct Chat {
|
||||
Chat(PeerData *peer, Fn<void()> updateCallback);
|
||||
Chat(
|
||||
PeerData *peer,
|
||||
const style::PeerListItem &st,
|
||||
Fn<void()> updateCallback);
|
||||
|
||||
PeerData *peer;
|
||||
Ui::RoundImageCheckbox checkbox;
|
||||
@@ -121,7 +121,8 @@ private:
|
||||
|
||||
void refresh();
|
||||
|
||||
const not_null<Window::SessionNavigation*> _navigation;
|
||||
const Descriptor &_descriptor;
|
||||
const style::PeerList &_st;
|
||||
|
||||
float64 _columnSkip = 0.;
|
||||
float64 _rowWidthReal = 0.;
|
||||
@@ -133,7 +134,6 @@ private:
|
||||
int _active = -1;
|
||||
int _upon = -1;
|
||||
|
||||
ShareBox::FilterCallback _filterCallback;
|
||||
std::unique_ptr<Dialogs::IndexedList> _chatsIndexed;
|
||||
QString _filter;
|
||||
std::vector<not_null<Dialogs::Row*>> _filtered;
|
||||
@@ -153,30 +153,35 @@ private:
|
||||
|
||||
};
|
||||
|
||||
ShareBox::ShareBox(
|
||||
QWidget*,
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
CopyCallback &©Callback,
|
||||
SubmitCallback &&submitCallback,
|
||||
FilterCallback &&filterCallback)
|
||||
: _navigation(navigation)
|
||||
, _api(&_navigation->session().mtp())
|
||||
, _copyCallback(std::move(copyCallback))
|
||||
, _submitCallback(std::move(submitCallback))
|
||||
, _filterCallback(std::move(filterCallback))
|
||||
ShareBox::ShareBox(QWidget*, Descriptor &&descriptor)
|
||||
: _descriptor(std::move(descriptor))
|
||||
, _api(&_descriptor.session->mtp())
|
||||
, _select(
|
||||
this,
|
||||
st::defaultMultiSelect,
|
||||
(_descriptor.stMultiSelect
|
||||
? *_descriptor.stMultiSelect
|
||||
: st::defaultMultiSelect),
|
||||
tr::lng_participant_filter())
|
||||
, _comment(
|
||||
this,
|
||||
object_ptr<Ui::InputField>(
|
||||
this,
|
||||
st::shareComment,
|
||||
(_descriptor.stComment
|
||||
? *_descriptor.stComment
|
||||
: st::shareComment),
|
||||
Ui::InputField::Mode::MultiLine,
|
||||
tr::lng_photos_comment()),
|
||||
st::shareCommentPadding)
|
||||
, _bottomWidget(std::move(_descriptor.bottomWidget))
|
||||
, _copyLinkText(_descriptor.copyLinkText
|
||||
? std::move(_descriptor.copyLinkText)
|
||||
: tr::lng_share_copy_link())
|
||||
, _searchTimer([=] { searchByUsername(); }) {
|
||||
if (_bottomWidget) {
|
||||
_bottomWidget->setParent(this);
|
||||
_bottomWidget->resizeToWidth(st::boxWideWidth);
|
||||
_bottomWidget->show();
|
||||
}
|
||||
}
|
||||
|
||||
void ShareBox::prepareCommentField() {
|
||||
@@ -187,9 +192,14 @@ void ShareBox::prepareCommentField() {
|
||||
rpl::combine(
|
||||
heightValue(),
|
||||
_comment->heightValue(),
|
||||
_1 - _2
|
||||
) | rpl::start_with_next([=](int top) {
|
||||
_comment->moveToLeft(0, top);
|
||||
(_bottomWidget
|
||||
? _bottomWidget->heightValue()
|
||||
: (rpl::single(0) | rpl::type_erased()))
|
||||
) | rpl::start_with_next([=](int height, int comment, int bottom) {
|
||||
_comment->moveToLeft(0, height - bottom - comment);
|
||||
if (_bottomWidget) {
|
||||
_bottomWidget->moveToLeft(0, height - bottom);
|
||||
}
|
||||
}, _comment->lifetime());
|
||||
|
||||
const auto field = _comment->entity();
|
||||
@@ -202,12 +212,25 @@ void ShareBox::prepareCommentField() {
|
||||
field->setInstantReplacesEnabled(
|
||||
Core::App().settings().replaceEmojiValue());
|
||||
field->setMarkdownReplacesEnabled(rpl::single(true));
|
||||
field->setEditLinkCallback(
|
||||
DefaultEditLinkCallback(_navigation->parentController(), field));
|
||||
if (_descriptor.initEditLink) {
|
||||
_descriptor.initEditLink(field);
|
||||
} else if (_descriptor.navigation) {
|
||||
field->setEditLinkCallback(
|
||||
DefaultEditLinkCallback(
|
||||
_descriptor.navigation->parentController(),
|
||||
field));
|
||||
}
|
||||
field->setSubmitSettings(Core::App().settings().sendSubmitWay());
|
||||
|
||||
InitSpellchecker(_navigation->parentController(), field);
|
||||
if (_descriptor.initSpellchecker) {
|
||||
_descriptor.initSpellchecker(field);
|
||||
} else if (_descriptor.navigation) {
|
||||
InitSpellchecker(_descriptor.navigation->parentController(), field);
|
||||
}
|
||||
Ui::SendPendingMoveResizeEvents(_comment);
|
||||
if (_bottomWidget) {
|
||||
Ui::SendPendingMoveResizeEvents(_bottomWidget);
|
||||
}
|
||||
}
|
||||
|
||||
void ShareBox::prepare() {
|
||||
@@ -219,10 +242,7 @@ void ShareBox::prepare() {
|
||||
setTitle(tr::lng_share_title());
|
||||
|
||||
_inner = setInnerWidget(
|
||||
object_ptr<Inner>(
|
||||
this,
|
||||
_navigation,
|
||||
std::move(_filterCallback)),
|
||||
object_ptr<Inner>(this, _descriptor),
|
||||
getTopScrollSkip(),
|
||||
getBottomScrollSkip());
|
||||
|
||||
@@ -234,7 +254,7 @@ void ShareBox::prepare() {
|
||||
applyFilterUpdate(query);
|
||||
});
|
||||
_select->setItemRemovedCallback([=](uint64 itemId) {
|
||||
if (const auto peer = _navigation->session().data().peerLoaded(itemId)) {
|
||||
if (const auto peer = _descriptor.session->data().peerLoaded(itemId)) {
|
||||
_inner->peerUnselected(peer);
|
||||
selectedChanged();
|
||||
update();
|
||||
@@ -249,7 +269,11 @@ void ShareBox::prepare() {
|
||||
_inner->selectActive();
|
||||
}
|
||||
});
|
||||
_comment->heightValue(
|
||||
rpl::combine(
|
||||
_comment->heightValue(),
|
||||
(_bottomWidget
|
||||
? _bottomWidget->heightValue()
|
||||
: rpl::single(0) | rpl::type_erased())
|
||||
) | rpl::start_with_next([=] {
|
||||
updateScrollSkips();
|
||||
}, _comment->lifetime());
|
||||
@@ -271,7 +295,7 @@ void ShareBox::prepare() {
|
||||
Ui::Emoji::SuggestionsController::Init(
|
||||
getDelegate()->outerContainer(),
|
||||
_comment->entity(),
|
||||
&_navigation->session());
|
||||
_descriptor.session);
|
||||
|
||||
_select->raise();
|
||||
}
|
||||
@@ -281,7 +305,8 @@ int ShareBox::getTopScrollSkip() const {
|
||||
}
|
||||
|
||||
int ShareBox::getBottomScrollSkip() const {
|
||||
return _comment->isHidden() ? 0 : _comment->height();
|
||||
return (_comment->isHidden() ? 0 : _comment->height())
|
||||
+ (_bottomWidget ? _bottomWidget->height() : 0);
|
||||
}
|
||||
|
||||
int ShareBox::contentHeight() const {
|
||||
@@ -318,7 +343,7 @@ bool ShareBox::searchByUsername(bool searchCache) {
|
||||
MTP_int(SearchPeopleLimit)
|
||||
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {
|
||||
peopleDone(result, requestId);
|
||||
}).fail([=](const RPCError &error, mtpRequestId requestId) {
|
||||
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
|
||||
peopleFail(error, requestId);
|
||||
}).send();
|
||||
_peopleQueries.insert(_peopleRequest, _peopleQuery);
|
||||
@@ -351,8 +376,8 @@ void ShareBox::peopleDone(
|
||||
switch (result.type()) {
|
||||
case mtpc_contacts_found: {
|
||||
auto &found = result.c_contacts_found();
|
||||
_navigation->session().data().processUsers(found.vusers());
|
||||
_navigation->session().data().processChats(found.vchats());
|
||||
_descriptor.session->data().processUsers(found.vusers());
|
||||
_descriptor.session->data().processChats(found.vchats());
|
||||
_inner->peopleReceived(
|
||||
query,
|
||||
found.vmy_results().v,
|
||||
@@ -364,7 +389,7 @@ void ShareBox::peopleDone(
|
||||
}
|
||||
}
|
||||
|
||||
void ShareBox::peopleFail(const RPCError &error, mtpRequestId requestId) {
|
||||
void ShareBox::peopleFail(const MTP::Error &error, mtpRequestId requestId) {
|
||||
if (_peopleRequest == requestId) {
|
||||
_peopleRequest = 0;
|
||||
_peopleFull = true;
|
||||
@@ -429,8 +454,8 @@ void ShareBox::createButtons() {
|
||||
[=] { return sendMenuType(); },
|
||||
[=] { submitSilent(); },
|
||||
[=] { submitScheduled(); });
|
||||
} else if (_copyCallback) {
|
||||
addButton(tr::lng_share_copy_link(), [=] { copyLink(); });
|
||||
} else if (_descriptor.copyCallback) {
|
||||
addButton(_copyLinkText.value(), [=] { copyLink(); });
|
||||
}
|
||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||
}
|
||||
@@ -463,8 +488,8 @@ void ShareBox::innerSelectedChanged(PeerData *peer, bool checked) {
|
||||
}
|
||||
|
||||
void ShareBox::submit(Api::SendOptions options) {
|
||||
if (_submitCallback) {
|
||||
_submitCallback(
|
||||
if (const auto onstack = _descriptor.submitCallback) {
|
||||
onstack(
|
||||
_inner->selected(),
|
||||
_comment->entity()->getTextWithAppliedMarkdown(),
|
||||
options);
|
||||
@@ -485,8 +510,8 @@ void ShareBox::submitScheduled() {
|
||||
}
|
||||
|
||||
void ShareBox::copyLink() {
|
||||
if (_copyCallback) {
|
||||
_copyCallback();
|
||||
if (const auto onstack = _descriptor.copyCallback) {
|
||||
onstack();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,13 +545,10 @@ void ShareBox::scrollAnimationCallback() {
|
||||
//scrollArea()->scrollToY(scrollTop);
|
||||
}
|
||||
|
||||
ShareBox::Inner::Inner(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
ShareBox::FilterCallback &&filterCallback)
|
||||
ShareBox::Inner::Inner(QWidget *parent, const Descriptor &descriptor)
|
||||
: RpWidget(parent)
|
||||
, _navigation(navigation)
|
||||
, _filterCallback(std::move(filterCallback))
|
||||
, _descriptor(descriptor)
|
||||
, _st(_descriptor.st ? *_descriptor.st : st::shareBoxList)
|
||||
, _chatsIndexed(
|
||||
std::make_unique<Dialogs::IndexedList>(
|
||||
Dialogs::SortMode::Add)) {
|
||||
@@ -534,44 +556,44 @@ ShareBox::Inner::Inner(
|
||||
_rowHeight = st::shareRowHeight;
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
||||
const auto self = _navigation->session().user();
|
||||
if (_filterCallback(self)) {
|
||||
const auto self = _descriptor.session->user();
|
||||
if (_descriptor.filterCallback(self)) {
|
||||
_chatsIndexed->addToEnd(self->owner().history(self));
|
||||
}
|
||||
const auto addList = [&](not_null<Dialogs::IndexedList*> list) {
|
||||
for (const auto row : list->all()) {
|
||||
if (const auto history = row->history()) {
|
||||
if (!history->peer->isSelf()
|
||||
&& _filterCallback(history->peer)) {
|
||||
&& _descriptor.filterCallback(history->peer)) {
|
||||
_chatsIndexed->addToEnd(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
addList(_navigation->session().data().chatsList()->indexed());
|
||||
addList(_descriptor.session->data().chatsList()->indexed());
|
||||
const auto id = Data::Folder::kId;
|
||||
if (const auto folder = _navigation->session().data().folderLoaded(id)) {
|
||||
if (const auto folder = _descriptor.session->data().folderLoaded(id)) {
|
||||
addList(folder->chatsList()->indexed());
|
||||
}
|
||||
addList(_navigation->session().data().contactsNoChatsList());
|
||||
addList(_descriptor.session->data().contactsNoChatsList());
|
||||
|
||||
_filter = qsl("a");
|
||||
updateFilter();
|
||||
|
||||
_navigation->session().changes().peerUpdates(
|
||||
_descriptor.session->changes().peerUpdates(
|
||||
Data::PeerUpdate::Flag::Photo
|
||||
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
|
||||
updateChat(update.peer);
|
||||
}, lifetime());
|
||||
|
||||
_navigation->session().changes().realtimeNameUpdates(
|
||||
_descriptor.session->changes().realtimeNameUpdates(
|
||||
) | rpl::start_with_next([=](const Data::NameUpdate &update) {
|
||||
_chatsIndexed->peerNameChanged(
|
||||
update.peer,
|
||||
update.oldFirstLetters);
|
||||
}, lifetime());
|
||||
|
||||
_navigation->session().downloaderTaskFinished(
|
||||
_descriptor.session->downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
@@ -640,7 +662,7 @@ void ShareBox::Inner::updateChatName(
|
||||
: peer->isRepliesChat()
|
||||
? tr::lng_replies_messages(tr::now)
|
||||
: peer->name;
|
||||
chat->name.setText(st::shareNameStyle, text, Ui::NameTextOptions());
|
||||
chat->name.setText(_st.item.nameStyle, text, Ui::NameTextOptions());
|
||||
}
|
||||
|
||||
void ShareBox::Inner::repaintChatAtIndex(int index) {
|
||||
@@ -763,7 +785,7 @@ auto ShareBox::Inner::getChat(not_null<Dialogs::Row*> row)
|
||||
}
|
||||
const auto [i, ok] = _dataMap.emplace(
|
||||
peer,
|
||||
std::make_unique<Chat>(peer, [=] { repaintChat(peer); }));
|
||||
std::make_unique<Chat>(peer, _st.item, [=] { repaintChat(peer); }));
|
||||
updateChatName(i->second.get(), peer);
|
||||
row->attached = i->second.get();
|
||||
return i->second.get();
|
||||
@@ -794,23 +816,26 @@ void ShareBox::Inner::paintChat(
|
||||
auto y = _rowsTop + (index / _columnCount) * _rowHeight;
|
||||
|
||||
auto outerWidth = width();
|
||||
auto photoLeft = (_rowWidth - (st::sharePhotoCheckbox.imageRadius * 2)) / 2;
|
||||
auto photoLeft = (_rowWidth - (_st.item.checkbox.imageRadius * 2)) / 2;
|
||||
auto photoTop = st::sharePhotoTop;
|
||||
chat->checkbox.paint(p, x + photoLeft, y + photoTop, outerWidth);
|
||||
|
||||
auto nameActive = chat->nameActive.value((index == _active) ? 1. : 0.);
|
||||
p.setPen(anim::pen(st::shareNameFg, st::shareNameActiveFg, nameActive));
|
||||
p.setPen(anim::pen(_st.item.nameFg, _st.item.nameFgChecked, nameActive));
|
||||
|
||||
auto nameWidth = (_rowWidth - st::shareColumnSkip);
|
||||
auto nameLeft = st::shareColumnSkip / 2;
|
||||
auto nameTop = photoTop + st::sharePhotoCheckbox.imageRadius * 2 + st::shareNameTop;
|
||||
auto nameTop = photoTop + _st.item.checkbox.imageRadius * 2 + st::shareNameTop;
|
||||
chat->name.drawLeftElided(p, x + nameLeft, y + nameTop, nameWidth, outerWidth, 2, style::al_top, 0, -1, 0, true);
|
||||
}
|
||||
|
||||
ShareBox::Inner::Chat::Chat(PeerData *peer, Fn<void()> updateCallback)
|
||||
ShareBox::Inner::Chat::Chat(
|
||||
PeerData *peer,
|
||||
const style::PeerListItem &st,
|
||||
Fn<void()> updateCallback)
|
||||
: peer(peer)
|
||||
, checkbox(st::sharePhotoCheckbox, updateCallback, PaintUserpicCallback(peer, true))
|
||||
, name(st::sharePhotoCheckbox.imageRadius * 2) {
|
||||
, checkbox(st.checkbox, updateCallback, PaintUserpicCallback(peer, true))
|
||||
, name(st.checkbox.imageRadius * 2) {
|
||||
}
|
||||
|
||||
void ShareBox::Inner::paintEvent(QPaintEvent *e) {
|
||||
@@ -818,7 +843,7 @@ void ShareBox::Inner::paintEvent(QPaintEvent *e) {
|
||||
|
||||
auto r = e->rect();
|
||||
p.setClipRect(r);
|
||||
p.fillRect(r, st::boxBg);
|
||||
p.fillRect(r, _st.bg);
|
||||
auto yFrom = r.y(), yTo = r.y() + r.height();
|
||||
auto rowFrom = yFrom / _rowHeight;
|
||||
auto rowTo = (yTo + _rowHeight - 1) / _rowHeight;
|
||||
@@ -836,7 +861,7 @@ void ShareBox::Inner::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
} else {
|
||||
p.setFont(st::noContactsFont);
|
||||
p.setPen(st::noContactsColor);
|
||||
p.setPen(_st.about.textFg);
|
||||
p.drawText(
|
||||
rect().marginsRemoved(st::boxPadding),
|
||||
tr::lng_bot_no_chats(tr::now),
|
||||
@@ -847,7 +872,7 @@ void ShareBox::Inner::paintEvent(QPaintEvent *e) {
|
||||
&& _byUsernameFiltered.empty()
|
||||
&& !_searching) {
|
||||
p.setFont(st::noContactsFont);
|
||||
p.setPen(st::noContactsColor);
|
||||
p.setPen(_st.about.textFg);
|
||||
p.drawText(
|
||||
rect().marginsRemoved(st::boxPadding),
|
||||
tr::lng_bot_chats_not_found(tr::now),
|
||||
@@ -903,7 +928,7 @@ void ShareBox::Inner::updateUpon(const QPoint &pos) {
|
||||
auto left = _rowsLeft + qFloor(column * _rowWidthReal) + st::shareColumnSkip / 2;
|
||||
auto top = _rowsTop + row * _rowHeight + st::sharePhotoTop;
|
||||
auto xupon = (x >= left) && (x < left + (_rowWidth - st::shareColumnSkip));
|
||||
auto yupon = (y >= top) && (y < top + st::sharePhotoCheckbox.imageRadius * 2 + st::shareNameTop + st::shareNameStyle.font->height * 2);
|
||||
auto yupon = (y >= top) && (y < top + _st.item.checkbox.imageRadius * 2 + st::shareNameTop + _st.item.nameStyle.font->height * 2);
|
||||
auto upon = (xupon && yupon) ? (row * _columnCount + column) : -1;
|
||||
if (upon >= displayedChatsCount()) {
|
||||
upon = -1;
|
||||
@@ -923,8 +948,8 @@ void ShareBox::Inner::selectActive() {
|
||||
}
|
||||
|
||||
void ShareBox::Inner::resizeEvent(QResizeEvent *e) {
|
||||
_columnSkip = (width() - _columnCount * st::sharePhotoCheckbox.imageRadius * 2) / float64(_columnCount + 1);
|
||||
_rowWidthReal = st::sharePhotoCheckbox.imageRadius * 2 + _columnSkip;
|
||||
_columnSkip = (width() - _columnCount * _st.item.checkbox.imageRadius * 2) / float64(_columnCount + 1);
|
||||
_rowWidthReal = _st.item.checkbox.imageRadius * 2 + _columnSkip;
|
||||
_rowsLeft = qFloor(_columnSkip / 2);
|
||||
_rowWidth = qFloor(_rowWidthReal);
|
||||
update();
|
||||
@@ -1030,9 +1055,10 @@ void ShareBox::Inner::peopleReceived(
|
||||
d_byUsernameFiltered.reserve(already + my.size() + people.size());
|
||||
const auto feedList = [&](const QVector<MTPPeer> &list) {
|
||||
for (const auto &data : list) {
|
||||
if (const auto peer = _navigation->session().data().peerLoaded(peerFromMTP(data))) {
|
||||
const auto history = _navigation->session().data().historyLoaded(peer);
|
||||
if (!_filterCallback(peer)) {
|
||||
if (const auto peer = _descriptor.session->data().peerLoaded(
|
||||
peerFromMTP(data))) {
|
||||
const auto history = _descriptor.session->data().historyLoaded(peer);
|
||||
if (!_descriptor.filterCallback(peer)) {
|
||||
continue;
|
||||
} else if (history && _chatsIndexed->getRow(history)) {
|
||||
continue;
|
||||
@@ -1042,6 +1068,7 @@ void ShareBox::Inner::peopleReceived(
|
||||
_byUsernameFiltered.push_back(peer);
|
||||
d_byUsernameFiltered.push_back(std::make_unique<Chat>(
|
||||
peer,
|
||||
_st.item,
|
||||
[=] { repaintChat(peer); }));
|
||||
updateChatName(d_byUsernameFiltered.back().get(), peer);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/effects/round_checkbox.h"
|
||||
#include "mtproto/sender.h"
|
||||
|
||||
namespace style {
|
||||
struct MultiSelect;
|
||||
struct InputField;
|
||||
struct PeerList;
|
||||
} // namespace style
|
||||
|
||||
namespace SendMenu {
|
||||
enum class Type;
|
||||
} // namespace SendMenu
|
||||
@@ -60,12 +66,21 @@ public:
|
||||
Api::SendOptions)>;
|
||||
using FilterCallback = Fn<bool(PeerData*)>;
|
||||
|
||||
ShareBox(
|
||||
QWidget*,
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
CopyCallback &©Callback,
|
||||
SubmitCallback &&submitCallback,
|
||||
FilterCallback &&filterCallback);
|
||||
struct Descriptor {
|
||||
not_null<Main::Session*> session;
|
||||
CopyCallback copyCallback;
|
||||
SubmitCallback submitCallback;
|
||||
FilterCallback filterCallback;
|
||||
Window::SessionNavigation *navigation = nullptr;
|
||||
Fn<void(not_null<Ui::InputField*>)> initSpellchecker;
|
||||
Fn<void(not_null<Ui::InputField*>)> initEditLink;
|
||||
object_ptr<Ui::RpWidget> bottomWidget = { nullptr };
|
||||
rpl::producer<QString> copyLinkText;
|
||||
const style::MultiSelect *stMultiSelect = nullptr;
|
||||
const style::InputField *stComment = nullptr;
|
||||
const style::PeerList *st = nullptr;
|
||||
};
|
||||
ShareBox(QWidget*, Descriptor &&descriptor);
|
||||
|
||||
protected:
|
||||
void prepare() override;
|
||||
@@ -102,22 +117,20 @@ private:
|
||||
void peopleDone(
|
||||
const MTPcontacts_Found &result,
|
||||
mtpRequestId requestId);
|
||||
void peopleFail(const RPCError &error, mtpRequestId requestId);
|
||||
void peopleFail(const MTP::Error &error, mtpRequestId requestId);
|
||||
|
||||
const not_null<Window::SessionNavigation*> _navigation;
|
||||
Descriptor _descriptor;
|
||||
MTP::Sender _api;
|
||||
|
||||
CopyCallback _copyCallback;
|
||||
SubmitCallback _submitCallback;
|
||||
FilterCallback _filterCallback;
|
||||
|
||||
object_ptr<Ui::MultiSelect> _select;
|
||||
object_ptr<Ui::SlideWrap<Ui::InputField>> _comment;
|
||||
object_ptr<Ui::RpWidget> _bottomWidget;
|
||||
|
||||
class Inner;
|
||||
QPointer<Inner> _inner;
|
||||
|
||||
bool _hasSelected = false;
|
||||
rpl::variable<QString> _copyLinkText;
|
||||
|
||||
base::Timer _searchTimer;
|
||||
QString _peopleQuery;
|
||||
|
||||
@@ -30,8 +30,8 @@ void SingleChoiceBox(
|
||||
layout->add(object_ptr<Ui::FixedHeightWidget>(
|
||||
layout,
|
||||
st::boxOptionListPadding.top() + st::autolockButton.margin.top()));
|
||||
auto &&ints = ranges::view::ints(0, ranges::unreachable);
|
||||
for (const auto &[i, text] : ranges::view::zip(ints, args.options)) {
|
||||
auto &&ints = ranges::views::ints(0, ranges::unreachable);
|
||||
for (const auto &[i, text] : ranges::views::zip(ints, args.options)) {
|
||||
layout->add(
|
||||
object_ptr<Ui::Radiobutton>(
|
||||
layout,
|
||||
|
||||
@@ -272,7 +272,7 @@ StickerSetBox::Inner::Inner(
|
||||
_input
|
||||
)).done([=](const MTPmessages_StickerSet &result) {
|
||||
gotSet(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_loaded = true;
|
||||
Ui::show(Box<InformBox>(tr::lng_stickers_not_found(tr::now)));
|
||||
}).send();
|
||||
@@ -566,7 +566,6 @@ int32 StickerSetBox::Inner::stickerFromGlobalPos(const QPoint &p) const {
|
||||
}
|
||||
|
||||
void StickerSetBox::Inner::paintEvent(QPaintEvent *e) {
|
||||
QRect r(e->rect());
|
||||
Painter p(this);
|
||||
|
||||
if (_elements.empty()) {
|
||||
@@ -758,7 +757,7 @@ void StickerSetBox::Inner::install() {
|
||||
MTP_bool(false)
|
||||
)).done([=](const MTPmessages_StickerSetInstallResult &result) {
|
||||
installDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
Ui::show(Box<InformBox>(tr::lng_stickers_not_found(tr::now)));
|
||||
}).send();
|
||||
}
|
||||
|
||||
@@ -778,7 +778,7 @@ void StickersBox::installSet(uint64 setId) {
|
||||
MTP_boolFalse()
|
||||
)).done([=](const MTPmessages_StickerSetInstallResult &result) {
|
||||
installDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
installFail(error, setId);
|
||||
}).send();
|
||||
|
||||
@@ -793,7 +793,7 @@ void StickersBox::installDone(const MTPmessages_StickerSetInstallResult &result)
|
||||
}
|
||||
}
|
||||
|
||||
void StickersBox::installFail(const RPCError &error, uint64 setId) {
|
||||
void StickersBox::installFail(const MTP::Error &error, uint64 setId) {
|
||||
const auto &sets = session().data().stickers().sets();
|
||||
const auto it = sets.find(setId);
|
||||
if (it == sets.cend()) {
|
||||
@@ -1765,7 +1765,7 @@ void StickersBox::Inner::handleMegagroupSetAddressChange() {
|
||||
setMegagroupSelectedSet(MTP_inputStickerSetID(
|
||||
MTP_long(set->id),
|
||||
MTP_long(set->access)));
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_megagroupSetRequestId = 0;
|
||||
setMegagroupSelectedSet(MTP_inputStickerSetEmpty());
|
||||
}).send();
|
||||
|
||||
@@ -122,7 +122,7 @@ private:
|
||||
QPixmap grabContentCache();
|
||||
|
||||
void installDone(const MTPmessages_StickerSetInstallResult &result);
|
||||
void installFail(const RPCError &error, uint64 setId);
|
||||
void installFail(const MTP::Error &error, uint64 setId);
|
||||
|
||||
void preloadArchivedSets();
|
||||
void requestArchivedSets();
|
||||
|
||||
@@ -41,10 +41,13 @@ void UrlAuthBox::Activate(
|
||||
const auto buttonId = button->buttonId;
|
||||
const auto url = QString::fromUtf8(button->data);
|
||||
|
||||
using Flag = MTPmessages_RequestUrlAuth::Flag;
|
||||
button->requestId = session->api().request(MTPmessages_RequestUrlAuth(
|
||||
MTP_flags(Flag::f_peer | Flag::f_msg_id | Flag::f_button_id),
|
||||
inputPeer,
|
||||
MTP_int(itemId.msg),
|
||||
MTP_int(buttonId)
|
||||
MTP_int(buttonId),
|
||||
MTPstring() // #TODO auth url
|
||||
)).done([=](const MTPUrlAuthResult &result) {
|
||||
const auto button = HistoryMessageMarkupButton::Get(
|
||||
&session->data(),
|
||||
@@ -61,9 +64,11 @@ void UrlAuthBox::Activate(
|
||||
}, [&](const MTPDurlAuthResultDefault &data) {
|
||||
HiddenUrlClickHandler::Open(url);
|
||||
}, [&](const MTPDurlAuthResultRequest &data) {
|
||||
Request(data, session->data().message(itemId), row, column);
|
||||
if (const auto item = session->data().message(itemId)) {
|
||||
Request(data, item, row, column);
|
||||
}
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
const auto button = HistoryMessageMarkupButton::Get(
|
||||
&session->data(),
|
||||
itemId,
|
||||
@@ -76,6 +81,36 @@ void UrlAuthBox::Activate(
|
||||
}).send();
|
||||
}
|
||||
|
||||
void UrlAuthBox::Activate(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &url,
|
||||
QVariant context) {
|
||||
context = QVariant::fromValue([&] {
|
||||
auto result = context.value<ClickHandlerContext>();
|
||||
result.skipBotAutoLogin = true;
|
||||
return result;
|
||||
}());
|
||||
|
||||
using Flag = MTPmessages_RequestUrlAuth::Flag;
|
||||
session->api().request(MTPmessages_RequestUrlAuth(
|
||||
MTP_flags(Flag::f_url),
|
||||
MTPInputPeer(),
|
||||
MTPint(), // msg_id
|
||||
MTPint(), // button_id
|
||||
MTP_string(url)
|
||||
)).done([=](const MTPUrlAuthResult &result) {
|
||||
result.match([&](const MTPDurlAuthResultAccepted &data) {
|
||||
UrlClickHandler::Open(qs(data.vurl()), context);
|
||||
}, [&](const MTPDurlAuthResultDefault &data) {
|
||||
HiddenUrlClickHandler::Open(url, context);
|
||||
}, [&](const MTPDurlAuthResultRequest &data) {
|
||||
Request(data, session, url, context);
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
HiddenUrlClickHandler::Open(url, context);
|
||||
}).send();
|
||||
}
|
||||
|
||||
void UrlAuthBox::Request(
|
||||
const MTPDurlAuthResultRequest &request,
|
||||
not_null<const HistoryItem*> message,
|
||||
@@ -111,11 +146,14 @@ void UrlAuthBox::Request(
|
||||
} else if (const auto msg = session->data().message(itemId)) {
|
||||
const auto allowWrite = (result == Result::AuthAndAllowWrite);
|
||||
using Flag = MTPmessages_AcceptUrlAuth::Flag;
|
||||
const auto flags = (allowWrite ? Flag::f_write_allowed : Flag(0))
|
||||
| (Flag::f_peer | Flag::f_msg_id | Flag::f_button_id);
|
||||
session->api().request(MTPmessages_AcceptUrlAuth(
|
||||
MTP_flags(allowWrite ? Flag::f_write_allowed : Flag(0)),
|
||||
MTP_flags(flags),
|
||||
inputPeer,
|
||||
MTP_int(itemId.msg),
|
||||
MTP_int(buttonId)
|
||||
MTP_int(buttonId),
|
||||
MTPstring() // #TODO auth url
|
||||
)).done([=](const MTPUrlAuthResult &result) {
|
||||
const auto to = result.match(
|
||||
[&](const MTPDurlAuthResultAccepted &data) {
|
||||
@@ -128,7 +166,58 @@ void UrlAuthBox::Request(
|
||||
return url;
|
||||
});
|
||||
finishWithUrl(to);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
finishWithUrl(url);
|
||||
}).send();
|
||||
}
|
||||
};
|
||||
*box = Ui::show(
|
||||
Box<UrlAuthBox>(session, url, qs(request.vdomain()), bot, callback),
|
||||
Ui::LayerOption::KeepOther);
|
||||
}
|
||||
|
||||
void UrlAuthBox::Request(
|
||||
const MTPDurlAuthResultRequest &request,
|
||||
not_null<Main::Session*> session,
|
||||
const QString &url,
|
||||
QVariant context) {
|
||||
const auto bot = request.is_request_write_access()
|
||||
? session->data().processUser(request.vbot()).get()
|
||||
: nullptr;
|
||||
const auto box = std::make_shared<QPointer<Ui::BoxContent>>();
|
||||
const auto finishWithUrl = [=](const QString &url) {
|
||||
if (*box) {
|
||||
(*box)->closeBox();
|
||||
}
|
||||
UrlClickHandler::Open(url, context);
|
||||
};
|
||||
const auto callback = [=](Result result) {
|
||||
if (result == Result::None) {
|
||||
finishWithUrl(url);
|
||||
} else {
|
||||
const auto allowWrite = (result == Result::AuthAndAllowWrite);
|
||||
using Flag = MTPmessages_AcceptUrlAuth::Flag;
|
||||
const auto flags = (allowWrite ? Flag::f_write_allowed : Flag(0))
|
||||
| Flag::f_url;
|
||||
session->api().request(MTPmessages_AcceptUrlAuth(
|
||||
MTP_flags(flags),
|
||||
MTPInputPeer(),
|
||||
MTPint(), // msg_id
|
||||
MTPint(), // button_id
|
||||
MTP_string(url)
|
||||
)).done([=](const MTPUrlAuthResult &result) {
|
||||
const auto to = result.match(
|
||||
[&](const MTPDurlAuthResultAccepted &data) {
|
||||
return qs(data.vurl());
|
||||
}, [&](const MTPDurlAuthResultDefault &data) {
|
||||
return url;
|
||||
}, [&](const MTPDurlAuthResultRequest &data) {
|
||||
LOG(("API Error: "
|
||||
"got urlAuthResultRequest after acceptUrlAuth."));
|
||||
return url;
|
||||
});
|
||||
finishWithUrl(to);
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
finishWithUrl(url);
|
||||
}).send();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ public:
|
||||
not_null<const HistoryItem*> message,
|
||||
int row,
|
||||
int column);
|
||||
static void Activate(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &url,
|
||||
QVariant context);
|
||||
|
||||
protected:
|
||||
void prepare() override;
|
||||
@@ -32,6 +36,11 @@ private:
|
||||
not_null<const HistoryItem*> message,
|
||||
int row,
|
||||
int column);
|
||||
static void Request(
|
||||
const MTPDurlAuthResultRequest &request,
|
||||
not_null<Main::Session*> session,
|
||||
const QString &url,
|
||||
QVariant context);
|
||||
|
||||
enum class Result {
|
||||
None,
|
||||
|
||||
@@ -120,7 +120,7 @@ void UsernameBox::save() {
|
||||
MTP_string(_sentUsername)
|
||||
)).done([=](const MTPUser &result) {
|
||||
updateDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
updateFail(error);
|
||||
}).send();
|
||||
}
|
||||
@@ -135,7 +135,7 @@ void UsernameBox::check() {
|
||||
MTP_string(name)
|
||||
)).done([=](const MTPBool &result) {
|
||||
checkDone(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
checkFail(error);
|
||||
}).send();
|
||||
}
|
||||
@@ -190,7 +190,7 @@ void UsernameBox::updateDone(const MTPUser &user) {
|
||||
closeBox();
|
||||
}
|
||||
|
||||
void UsernameBox::updateFail(const RPCError &error) {
|
||||
void UsernameBox::updateFail(const MTP::Error &error) {
|
||||
_saveRequestId = 0;
|
||||
const auto self = _session->user();
|
||||
const auto &err = error.type();
|
||||
@@ -232,7 +232,7 @@ void UsernameBox::checkDone(const MTPBool &result) {
|
||||
}
|
||||
}
|
||||
|
||||
void UsernameBox::checkFail(const RPCError &error) {
|
||||
void UsernameBox::checkFail(const MTP::Error &error) {
|
||||
_checkRequestId = 0;
|
||||
QString err(error.type());
|
||||
if (err == qstr("USERNAME_INVALID")) {
|
||||
|
||||
@@ -32,10 +32,10 @@ protected:
|
||||
|
||||
private:
|
||||
void updateDone(const MTPUser &result);
|
||||
void updateFail(const RPCError &error);
|
||||
void updateFail(const MTP::Error &error);
|
||||
|
||||
void checkDone(const MTPBool &result);
|
||||
void checkFail(const RPCError &error);
|
||||
void checkFail(const MTP::Error &error);
|
||||
|
||||
void save();
|
||||
|
||||
|
||||
@@ -393,6 +393,8 @@ callErrorToast: Toast(defaultToast) {
|
||||
groupCallWidth: 380px;
|
||||
groupCallHeight: 580px;
|
||||
|
||||
groupCallMuteButtonIconSize: size(55px, 55px);
|
||||
groupCallMuteButtonIconTop: 42px;
|
||||
groupCallRipple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: groupCallMembersBgRipple;
|
||||
}
|
||||
@@ -407,7 +409,7 @@ groupCallMenu: Menu(defaultMenu) {
|
||||
itemFgShortcutOver: groupCallMemberNotJoinedStatus;
|
||||
itemFgShortcutDisabled: groupCallMemberNotJoinedStatus;
|
||||
|
||||
separatorFg: groupCallMemberNotJoinedStatus;
|
||||
separatorFg: groupCallMenuBgOver;
|
||||
|
||||
arrow: icon {{ "dropdown_submenu_arrow", groupCallMemberNotJoinedStatus }};
|
||||
|
||||
@@ -415,6 +417,10 @@ groupCallMenu: Menu(defaultMenu) {
|
||||
color: groupCallMenuBgRipple;
|
||||
}
|
||||
}
|
||||
groupCallFinishMenu: Menu(groupCallMenu) {
|
||||
itemFg: groupCallMemberMutedIcon;
|
||||
itemFgOver: groupCallMemberMutedIcon;
|
||||
}
|
||||
groupCallMenuShadow: Shadow(defaultEmptyShadow) {
|
||||
fallback: groupCallMenuBg;
|
||||
}
|
||||
@@ -428,6 +434,29 @@ groupCallPopupMenu: PopupMenu(defaultPopupMenu) {
|
||||
animation: groupCallPanelAnimation;
|
||||
}
|
||||
|
||||
groupCallRecordingTimerPadding: margins(0px, 4px, 0px, 4px);
|
||||
groupCallRecordingTimerFont: font(12px);
|
||||
|
||||
groupCallInnerDropdown: InnerDropdown(defaultInnerDropdown) {
|
||||
shadow: groupCallMenuShadow;
|
||||
animation: groupCallPanelAnimation;
|
||||
bg: groupCallMenuBg;
|
||||
scroll: defaultSolidScroll;
|
||||
scrollPadding: margins(0px, 4px, 0px, 4px);
|
||||
}
|
||||
groupCallDropdownMenu: DropdownMenu(defaultDropdownMenu) {
|
||||
wrap: groupCallInnerDropdown;
|
||||
menu: groupCallMenu;
|
||||
}
|
||||
groupCallMembersListCheck: RoundCheckbox(defaultPeerListCheck) {
|
||||
border: groupCallMembersBg;
|
||||
bgActive: groupCallActiveFg;
|
||||
check: icon {{ "default_checkbox_check", groupCallMembersFg, point(3px, 6px) }};
|
||||
}
|
||||
groupCallMembersListCheckbox: RoundImageCheckbox(defaultPeerListCheckbox) {
|
||||
selectFg: groupCallActiveFg;
|
||||
check: groupCallMembersListCheck;
|
||||
}
|
||||
groupCallMembersListItem: PeerListItem(defaultPeerListItem) {
|
||||
button: OutlineButton(defaultPeerListButton) {
|
||||
textBg: groupCallMembersBg;
|
||||
@@ -442,14 +471,7 @@ groupCallMembersListItem: PeerListItem(defaultPeerListItem) {
|
||||
ripple: groupCallRipple;
|
||||
}
|
||||
disabledCheckFg: groupCallMemberNotJoinedStatus;
|
||||
checkbox: RoundImageCheckbox(defaultPeerListCheckbox) {
|
||||
selectFg: groupCallActiveFg;
|
||||
check: RoundCheckbox(defaultPeerListCheck) {
|
||||
border: groupCallMembersBg;
|
||||
bgActive: groupCallActiveFg;
|
||||
check: icon {{ "default_checkbox_check", groupCallMembersFg, point(3px, 6px) }};
|
||||
}
|
||||
}
|
||||
checkbox: groupCallMembersListCheckbox;
|
||||
height: 52px;
|
||||
photoPosition: point(12px, 6px);
|
||||
namePosition: point(63px, 7px);
|
||||
@@ -472,13 +494,46 @@ groupCallInviteDividerLabel: FlatLabel(defaultFlatLabel) {
|
||||
textFg: groupCallMemberNotJoinedStatus;
|
||||
}
|
||||
groupCallInviteDividerPadding: margins(17px, 7px, 17px, 7px);
|
||||
|
||||
groupCallInviteMembersListItem: PeerListItem(groupCallMembersListItem) {
|
||||
statusFg: groupCallMemberNotJoinedStatus;
|
||||
statusFgOver: groupCallMemberNotJoinedStatus;
|
||||
statusFgActive: groupCallMemberInactiveStatus;
|
||||
}
|
||||
groupCallInviteMembersList: PeerList(groupCallMembersList) {
|
||||
padding: margins(0px, 10px, 0px, 10px);
|
||||
item: PeerListItem(groupCallMembersListItem) {
|
||||
statusFg: groupCallMemberNotJoinedStatus;
|
||||
statusFgOver: groupCallMemberNotJoinedStatus;
|
||||
statusFgActive: groupCallMemberInactiveStatus;
|
||||
item: groupCallInviteMembersListItem;
|
||||
}
|
||||
groupCallJoinAsList: PeerList(groupCallInviteMembersList) {
|
||||
item: PeerListItem(groupCallInviteMembersListItem) {
|
||||
height: 56px;
|
||||
checkbox: RoundImageCheckbox(groupCallMembersListCheckbox) {
|
||||
check: RoundCheckbox(groupCallMembersListCheck) {
|
||||
size: 0px;
|
||||
}
|
||||
imageRadius: 19px;
|
||||
imageSmallRadius: 15px;
|
||||
selectFg: groupCallMemberInactiveStatus;
|
||||
}
|
||||
photoSize: 38px;
|
||||
photoPosition: point(24px, 9px);
|
||||
namePosition: point(73px, 9px);
|
||||
statusPosition: point(73px, 28px);
|
||||
}
|
||||
}
|
||||
peerListJoinAsList: PeerList(peerListBox) {
|
||||
item: PeerListItem(peerListBoxItem) {
|
||||
height: 56px;
|
||||
checkbox: RoundImageCheckbox(defaultPeerListCheckbox) {
|
||||
check: RoundCheckbox(defaultRoundCheckbox) {
|
||||
size: 0px;
|
||||
}
|
||||
imageRadius: 19px;
|
||||
imageSmallRadius: 15px;
|
||||
}
|
||||
photoSize: 38px;
|
||||
photoPosition: point(24px, 9px);
|
||||
namePosition: point(73px, 9px);
|
||||
statusPosition: point(73px, 28px);
|
||||
}
|
||||
}
|
||||
groupCallMultiSelect: MultiSelect(defaultMultiSelect) {
|
||||
@@ -504,10 +559,46 @@ groupCallMultiSelect: MultiSelect(defaultMultiSelect) {
|
||||
ripple: groupCallRipple;
|
||||
}
|
||||
}
|
||||
groupCallField: InputField(defaultInputField) {
|
||||
textMargins: margins(2px, 7px, 2px, 0px);
|
||||
|
||||
groupCallMembersTop: 62px;
|
||||
groupCallTitleTop: 14px;
|
||||
groupCallSubtitleTop: 33px;
|
||||
textBg: transparent;
|
||||
textFg: groupCallMembersFg;
|
||||
|
||||
placeholderFg: groupCallMemberNotJoinedStatus;
|
||||
placeholderFgActive: groupCallMemberNotJoinedStatus;
|
||||
placeholderFgError: groupCallMemberNotJoinedStatus;
|
||||
placeholderMargins: margins(0px, 0px, 0px, 0px);
|
||||
placeholderScale: 0.;
|
||||
placeholderFont: normalFont;
|
||||
heightMin: 32px;
|
||||
|
||||
borderFg: inputBorderFg;
|
||||
borderFgActive: groupCallMemberInactiveStatus;
|
||||
borderFgError: activeLineFgError;
|
||||
|
||||
menu: groupCallPopupMenu;
|
||||
}
|
||||
groupCallShareBoxComment: InputField(groupCallField) {
|
||||
textMargins: margins(8px, 8px, 8px, 6px);
|
||||
heightMin: 36px;
|
||||
heightMax: 72px;
|
||||
placeholderMargins: margins(2px, 0px, 2px, 0px);
|
||||
border: 0px;
|
||||
borderActive: 0px;
|
||||
}
|
||||
groupCallShareBoxList: PeerList(groupCallMembersList) {
|
||||
item: PeerListItem(groupCallMembersListItem) {
|
||||
checkbox: RoundImageCheckbox(groupCallMembersListCheckbox) {
|
||||
imageRadius: 28px;
|
||||
imageSmallRadius: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
groupCallMembersTop: 51px;
|
||||
groupCallTitleTop: 8px;
|
||||
groupCallSubtitleTop: 26px;
|
||||
|
||||
groupCallMembersMargin: margins(16px, 16px, 16px, 28px);
|
||||
groupCallAddMember: SettingsButton(defaultSettingsButton) {
|
||||
@@ -539,6 +630,31 @@ groupCallTitleLabel: FlatLabel(groupCallSubtitleLabel) {
|
||||
}
|
||||
groupCallAddButtonPosition: point(10px, 7px);
|
||||
groupCallMembersWidthMax: 360px;
|
||||
groupCallRecordingMark: 6px;
|
||||
groupCallRecordingMarkSkip: 4px;
|
||||
groupCallRecordingMarkTop: 8px;
|
||||
|
||||
groupCallMenuTogglePosition: point(13px, 8px);
|
||||
groupCallMenuToggle: IconButton {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
|
||||
icon: icon {{ "info/edit/dotsmini", groupCallMemberInactiveIcon }};
|
||||
iconOver: icon {{ "info/edit/dotsmini", groupCallMemberInactiveIcon }};
|
||||
iconPosition: point(6px, 6px);
|
||||
|
||||
rippleAreaPosition: point(3px, 3px);
|
||||
rippleAreaSize: 30px;
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: groupCallMembersBg;
|
||||
}
|
||||
}
|
||||
groupCallJoinAsToggle: UserpicButton(defaultUserpicButton) {
|
||||
size: size(36px, 36px);
|
||||
photoSize: 30px;
|
||||
photoPosition: point(3px, 3px);
|
||||
}
|
||||
groupCallMenuPosition: point(-1px, 29px);
|
||||
|
||||
groupCallActiveButton: IconButton {
|
||||
width: 36px;
|
||||
@@ -567,11 +683,12 @@ groupCallMemberColoredCrossLine: CrossLineAnimation(groupCallMemberInactiveCross
|
||||
}
|
||||
groupCallMemberInvited: icon {{ "calls/group_calls_invited", groupCallMemberInactiveIcon }};
|
||||
groupCallMemberInvitedPosition: point(2px, 12px);
|
||||
groupCallMemberRaisedHand: icon {{ "calls/group_calls_raised_hand", groupCallMemberInactiveStatus }};
|
||||
|
||||
groupCallSettings: CallButton(callMicrophoneMute) {
|
||||
button: IconButton(callButton) {
|
||||
iconPosition: point(-1px, 22px);
|
||||
icon: icon {{ "calls/call_settings", callIconFg }};
|
||||
icon: icon {{ "calls/call_settings", groupCallIconFg }};
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: callMuteRipple;
|
||||
}
|
||||
@@ -579,7 +696,7 @@ groupCallSettings: CallButton(callMicrophoneMute) {
|
||||
}
|
||||
groupCallHangup: CallButton(callHangup) {
|
||||
button: IconButton(callButton) {
|
||||
icon: icon {{ "calls/call_discard", callIconFg }};
|
||||
icon: icon {{ "calls/call_discard", groupCallIconFg }};
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: groupCallLeaveBgRipple;
|
||||
}
|
||||
@@ -674,6 +791,15 @@ groupCallSettingsAttentionButton: SettingsButton(groupCallSettingsButton) {
|
||||
groupCallBoxLabel: FlatLabel(boxLabel) {
|
||||
textFg: groupCallMembersFg;
|
||||
}
|
||||
groupCallJoinAsLabel: FlatLabel(defaultFlatLabel) {
|
||||
minWidth: 272px;
|
||||
textFg: groupCallMembersFg;
|
||||
}
|
||||
groupCallJoinAsWidth: 330px;
|
||||
groupCallJoinAsTextTop: 4px;
|
||||
groupCallJoinAsNameTop: 23px;
|
||||
groupCallJoinAsPadding: margins(12px, 8px, 12px, 7px);
|
||||
groupCallJoinAsPhotoSize: 30px;
|
||||
|
||||
groupCallRowBlobMinRadius: 27px;
|
||||
groupCallRowBlobMaxRadius: 29px;
|
||||
@@ -730,8 +856,8 @@ groupCallTitleCloseIconOver: icon {
|
||||
};
|
||||
groupCallTitle: WindowTitle(defaultWindowTitle) {
|
||||
height: 0px;
|
||||
bg: transparent;
|
||||
bgActive: transparent;
|
||||
bg: groupCallBg;
|
||||
bgActive: groupCallBg;
|
||||
fg: transparent;
|
||||
fgActive: transparent;
|
||||
minimize: IconButton(groupCallTitleButton) {
|
||||
@@ -805,6 +931,8 @@ groupCallStatusSpeakerArcsAnimation: ArcsAnimation(groupCallSpeakerArcsAnimation
|
||||
startHeight: 1px;
|
||||
}
|
||||
|
||||
groupCallShareMutedMargin: margins(16px, 16px, 16px, 8px);
|
||||
|
||||
callTopBarMuteCrossLine: CrossLineAnimation {
|
||||
fg: callBarFg;
|
||||
icon: icon {{ "calls/call_record_active", callBarFg }};
|
||||
|
||||
@@ -343,7 +343,7 @@ void BoxController::loadMoreRows() {
|
||||
} break;
|
||||
default: Unexpected("Type of messages.Messages (Calls::BoxController::preloadRows)");
|
||||
}
|
||||
}).fail([this](const RPCError &error) {
|
||||
}).fail([this](const MTP::Error &error) {
|
||||
_loadRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include <tgcalls/Instance.h>
|
||||
#include <tgcalls/VideoCaptureInterface.h>
|
||||
#include <tgcalls/StaticThreads.h>
|
||||
|
||||
namespace tgcalls {
|
||||
class InstanceImpl;
|
||||
@@ -141,7 +142,7 @@ uint64 ComputeFingerprint(bytes::const_span authKey) {
|
||||
}
|
||||
|
||||
[[nodiscard]] QVector<MTPstring> CollectVersionsForApi() {
|
||||
return WrapVersions(tgcalls::Meta::Versions() | ranges::action::reverse);
|
||||
return WrapVersions(tgcalls::Meta::Versions() | ranges::actions::reverse);
|
||||
}
|
||||
|
||||
[[nodiscard]] Webrtc::VideoState StartVideoState(bool enabled) {
|
||||
@@ -266,7 +267,7 @@ void Call::startOutgoing() {
|
||||
const auto &config = _user->session().serverConfig();
|
||||
_discardByTimeoutTimer.callOnce(config.callReceiveTimeoutMs);
|
||||
handleUpdate(phoneCall);
|
||||
}).fail([this](const RPCError &error) {
|
||||
}).fail([this](const MTP::Error &error) {
|
||||
handleRequestError(error);
|
||||
}).send();
|
||||
}
|
||||
@@ -281,7 +282,7 @@ void Call::startIncoming() {
|
||||
if (_state.current() == State::Starting) {
|
||||
setState(State::WaitingIncoming);
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
handleRequestError(error);
|
||||
}).send();
|
||||
}
|
||||
@@ -340,7 +341,7 @@ void Call::actuallyAnswer() {
|
||||
}
|
||||
|
||||
handleUpdate(call.vphone_call());
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
handleRequestError(error);
|
||||
}).send();
|
||||
}
|
||||
@@ -456,7 +457,7 @@ void Call::sendSignalingData(const QByteArray &data) {
|
||||
if (!mtpIsTrue(result)) {
|
||||
finish(FinishType::Failed);
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
handleRequestError(error);
|
||||
}).send();
|
||||
}
|
||||
@@ -631,9 +632,9 @@ bool Call::handleSignalingData(
|
||||
if (data.vphone_call_id().v != _id || !_instance) {
|
||||
return false;
|
||||
}
|
||||
auto prepared = ranges::view::all(
|
||||
auto prepared = ranges::views::all(
|
||||
data.vdata().v
|
||||
) | ranges::view::transform([](char byte) {
|
||||
) | ranges::views::transform([](char byte) {
|
||||
return static_cast<uint8_t>(byte);
|
||||
}) | ranges::to_vector;
|
||||
_instance->receiveSignalingData(std::move(prepared));
|
||||
@@ -686,7 +687,7 @@ void Call::confirmAcceptedCall(const MTPDphoneCallAccepted &call) {
|
||||
}
|
||||
|
||||
createAndStartController(call.vphone_call().c_phoneCall());
|
||||
}).fail([=](const RPCError &error) {
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
handleRequestError(error);
|
||||
}).send();
|
||||
}
|
||||
@@ -818,9 +819,9 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
|
||||
return data.vlibrary_versions().v;
|
||||
}).value(0, MTP_bytes(kDefaultVersion)).v;
|
||||
|
||||
LOG(("Call Info: Creating instance with version '%1', allowP2P: %2"
|
||||
).arg(QString::fromUtf8(version)
|
||||
).arg(Logs::b(descriptor.config.enableP2P)));
|
||||
LOG(("Call Info: Creating instance with version '%1', allowP2P: %2").arg(
|
||||
QString::fromUtf8(version),
|
||||
Logs::b(descriptor.config.enableP2P)));
|
||||
_instance = tgcalls::Meta::Create(
|
||||
version.toStdString(),
|
||||
std::move(descriptor));
|
||||
@@ -1052,7 +1053,7 @@ void Call::finish(FinishType type, const MTPPhoneCallDiscardReason &reason) {
|
||||
// updates being handled, but in a guarded way.
|
||||
crl::on_main(weak, [=] { setState(finalState); });
|
||||
session->api().applyUpdates(result);
|
||||
}).fail(crl::guard(weak, [this, finalState](const RPCError &error) {
|
||||
}).fail(crl::guard(weak, [this, finalState](const MTP::Error &error) {
|
||||
setState(finalState);
|
||||
})).send();
|
||||
}
|
||||
@@ -1069,7 +1070,7 @@ void Call::setFailedQueued(const QString &error) {
|
||||
});
|
||||
}
|
||||
|
||||
void Call::handleRequestError(const RPCError &error) {
|
||||
void Call::handleRequestError(const MTP::Error &error) {
|
||||
if (error.type() == qstr("USER_PRIVACY_RESTRICTED")) {
|
||||
Ui::show(Box<InformBox>(tr::lng_call_error_not_available(tr::now, lt_user, _user->name)));
|
||||
} else if (error.type() == qstr("PARTICIPANT_VERSION_OUTDATED")) {
|
||||
|
||||
@@ -196,7 +196,7 @@ private:
|
||||
Failed,
|
||||
};
|
||||
|
||||
void handleRequestError(const RPCError &error);
|
||||
void handleRequestError(const MTP::Error &error);
|
||||
void handleControllerError(const QString &error);
|
||||
void finish(
|
||||
FinishType type,
|
||||
|
||||
315
Telegram/SourceFiles/calls/calls_choose_join_as.cpp
Normal file
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "calls/calls_choose_join_as.h"
|
||||
|
||||
#include "calls/calls_group_common.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_group_call.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_account.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "apiwrap.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "boxes/peer_list_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_calls.h"
|
||||
|
||||
namespace Calls::Group {
|
||||
namespace {
|
||||
|
||||
using Context = ChooseJoinAsProcess::Context;
|
||||
|
||||
class ListController : public PeerListController {
|
||||
public:
|
||||
ListController(
|
||||
std::vector<not_null<PeerData*>> list,
|
||||
not_null<PeerData*> selected);
|
||||
|
||||
Main::Session &session() const override;
|
||||
void prepare() override;
|
||||
void rowClicked(not_null<PeerListRow*> row) override;
|
||||
|
||||
[[nodiscard]] not_null<PeerData*> selected() const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<PeerListRow> createRow(not_null<PeerData*> peer);
|
||||
|
||||
std::vector<not_null<PeerData*>> _list;
|
||||
not_null<PeerData*> _selected;
|
||||
|
||||
};
|
||||
|
||||
ListController::ListController(
|
||||
std::vector<not_null<PeerData*>> list,
|
||||
not_null<PeerData*> selected)
|
||||
: PeerListController()
|
||||
, _list(std::move(list))
|
||||
, _selected(selected) {
|
||||
}
|
||||
|
||||
Main::Session &ListController::session() const {
|
||||
return _selected->session();
|
||||
}
|
||||
|
||||
std::unique_ptr<PeerListRow> ListController::createRow(
|
||||
not_null<PeerData*> peer) {
|
||||
auto result = std::make_unique<PeerListRow>(peer);
|
||||
if (peer->isSelf()) {
|
||||
result->setCustomStatus(
|
||||
tr::lng_group_call_join_as_personal(tr::now));
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
result->setCustomStatus(
|
||||
(channel->isMegagroup()
|
||||
? tr::lng_chat_status_members
|
||||
: tr::lng_chat_status_subscribers)(
|
||||
tr::now,
|
||||
lt_count,
|
||||
channel->membersCount()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ListController::prepare() {
|
||||
delegate()->peerListSetSearchMode(PeerListSearchMode::Disabled);
|
||||
for (const auto &peer : _list) {
|
||||
auto row = createRow(peer);
|
||||
const auto raw = row.get();
|
||||
delegate()->peerListAppendRow(std::move(row));
|
||||
if (peer == _selected) {
|
||||
delegate()->peerListSetRowChecked(raw, true);
|
||||
raw->finishCheckedAnimation();
|
||||
}
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
}
|
||||
|
||||
void ListController::rowClicked(not_null<PeerListRow*> row) {
|
||||
const auto peer = row->peer();
|
||||
if (peer == _selected) {
|
||||
return;
|
||||
}
|
||||
const auto previous = delegate()->peerListFindRow(_selected->id);
|
||||
Assert(previous != nullptr);
|
||||
delegate()->peerListSetRowChecked(previous, false);
|
||||
delegate()->peerListSetRowChecked(row, true);
|
||||
_selected = peer;
|
||||
}
|
||||
|
||||
not_null<PeerData*> ListController::selected() const {
|
||||
return _selected;
|
||||
}
|
||||
|
||||
void ChooseJoinAsBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
Context context,
|
||||
JoinInfo info,
|
||||
Fn<void(JoinInfo)> done) {
|
||||
box->setWidth(st::groupCallJoinAsWidth);
|
||||
box->setTitle([&] {
|
||||
switch (context) {
|
||||
case Context::Create: return tr::lng_group_call_start_as_header();
|
||||
case Context::Join:
|
||||
case Context::JoinWithConfirm: return tr::lng_group_call_join_as_header();
|
||||
case Context::Switch: return tr::lng_group_call_display_as_header();
|
||||
}
|
||||
Unexpected("Context in ChooseJoinAsBox.");
|
||||
}());
|
||||
box->addRow(object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_group_call_join_as_about(),
|
||||
(context == Context::Switch
|
||||
? st::groupCallJoinAsLabel
|
||||
: st::confirmPhoneAboutLabel)));
|
||||
|
||||
auto &lifetime = box->lifetime();
|
||||
const auto delegate = lifetime.make_state<
|
||||
PeerListContentDelegateSimple
|
||||
>();
|
||||
const auto controller = lifetime.make_state<ListController>(
|
||||
info.possibleJoinAs,
|
||||
info.joinAs);
|
||||
if (context == Context::Switch) {
|
||||
controller->setStyleOverrides(
|
||||
&st::groupCallJoinAsList,
|
||||
&st::groupCallMultiSelect);
|
||||
} else {
|
||||
controller->setStyleOverrides(
|
||||
&st::peerListJoinAsList,
|
||||
nullptr);
|
||||
}
|
||||
const auto content = box->addRow(
|
||||
object_ptr<PeerListContent>(box, controller),
|
||||
style::margins());
|
||||
delegate->setContent(content);
|
||||
controller->setDelegate(delegate);
|
||||
auto next = (context == Context::Switch)
|
||||
? tr::lng_settings_save()
|
||||
: tr::lng_continue();
|
||||
box->addButton(std::move(next), [=] {
|
||||
auto copy = info;
|
||||
copy.joinAs = controller->selected();
|
||||
done(std::move(copy));
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ChooseJoinAsProcess::~ChooseJoinAsProcess() {
|
||||
if (_request) {
|
||||
_request->peer->session().api().request(_request->id).cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void ChooseJoinAsProcess::start(
|
||||
not_null<PeerData*> peer,
|
||||
Context context,
|
||||
Fn<void(object_ptr<Ui::BoxContent>)> showBox,
|
||||
Fn<void(QString)> showToast,
|
||||
Fn<void(JoinInfo)> done,
|
||||
PeerData *changingJoinAsFrom) {
|
||||
Expects(done != nullptr);
|
||||
|
||||
const auto session = &peer->session();
|
||||
if (_request) {
|
||||
if (_request->peer == peer) {
|
||||
_request->context = context;
|
||||
_request->showBox = std::move(showBox);
|
||||
_request->showToast = std::move(showToast);
|
||||
_request->done = std::move(done);
|
||||
return;
|
||||
}
|
||||
session->api().request(_request->id).cancel();
|
||||
_request = nullptr;
|
||||
}
|
||||
_request = std::make_unique<ChannelsListRequest>(
|
||||
ChannelsListRequest{
|
||||
.peer = peer,
|
||||
.showBox = std::move(showBox),
|
||||
.showToast = std::move(showToast),
|
||||
.done = std::move(done),
|
||||
.context = context });
|
||||
session->account().sessionChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
_request = nullptr;
|
||||
}, _request->lifetime);
|
||||
|
||||
const auto finish = [=](JoinInfo info) {
|
||||
const auto peer = _request->peer;
|
||||
const auto done = std::move(_request->done);
|
||||
const auto box = _request->box;
|
||||
_request = nullptr;
|
||||
done(std::move(info));
|
||||
if (const auto strong = box.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
};
|
||||
_request->id = session->api().request(MTPphone_GetGroupCallJoinAs(
|
||||
_request->peer->input
|
||||
)).done([=](const MTPphone_JoinAsPeers &result) {
|
||||
const auto peer = _request->peer;
|
||||
const auto self = peer->session().user();
|
||||
auto info = JoinInfo{ .peer = peer, .joinAs = self };
|
||||
auto list = result.match([&](const MTPDphone_joinAsPeers &data) {
|
||||
session->data().processUsers(data.vusers());
|
||||
session->data().processChats(data.vchats());
|
||||
const auto &peers = data.vpeers().v;
|
||||
auto list = std::vector<not_null<PeerData*>>();
|
||||
list.reserve(peers.size());
|
||||
for (const auto &peer : peers) {
|
||||
const auto peerId = peerFromMTP(peer);
|
||||
if (const auto peer = session->data().peerLoaded(peerId)) {
|
||||
if (!ranges::contains(list, not_null{ peer })) {
|
||||
list.push_back(peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
});
|
||||
const auto selectedId = peer->groupCallDefaultJoinAs();
|
||||
if (list.empty()) {
|
||||
_request->showToast(Lang::Hard::ServerError());
|
||||
return;
|
||||
}
|
||||
info.joinAs = [&]() -> not_null<PeerData*> {
|
||||
const auto loaded = selectedId
|
||||
? session->data().peerLoaded(selectedId)
|
||||
: nullptr;
|
||||
return (changingJoinAsFrom
|
||||
&& ranges::contains(list, not_null{ changingJoinAsFrom }))
|
||||
? not_null(changingJoinAsFrom)
|
||||
: (loaded && ranges::contains(list, not_null{ loaded }))
|
||||
? not_null(loaded)
|
||||
: ranges::contains(list, self)
|
||||
? self
|
||||
: list.front();
|
||||
}();
|
||||
info.possibleJoinAs = std::move(list);
|
||||
|
||||
const auto onlyByMe = (info.possibleJoinAs.size() == 1)
|
||||
&& (info.possibleJoinAs.front() == self)
|
||||
&& (!peer->isChannel()
|
||||
|| !peer->asChannel()->amAnonymous()
|
||||
|| (peer->isBroadcast() && !peer->canWrite()));
|
||||
|
||||
// We already joined this voice chat, just rejoin with the same.
|
||||
const auto byAlreadyUsed = selectedId
|
||||
&& (info.joinAs->id == selectedId);
|
||||
|
||||
if (!changingJoinAsFrom && (onlyByMe || byAlreadyUsed)) {
|
||||
if (context != Context::JoinWithConfirm) {
|
||||
finish(info);
|
||||
return;
|
||||
}
|
||||
const auto real = peer->groupCall();
|
||||
const auto name = (real && !real->title().isEmpty())
|
||||
? real->title()
|
||||
: peer->name;
|
||||
auto box = Box<::ConfirmBox>(
|
||||
tr::lng_group_call_join_confirm(
|
||||
tr::now,
|
||||
lt_chat,
|
||||
Ui::Text::Bold(name),
|
||||
Ui::Text::WithEntities),
|
||||
tr::lng_group_call_join(tr::now),
|
||||
crl::guard(&_request->guard, [=] { finish(info); }));
|
||||
box->boxClosing(
|
||||
) | rpl::start_with_next([=] {
|
||||
_request = nullptr;
|
||||
}, _request->lifetime);
|
||||
|
||||
_request->box = box.data();
|
||||
_request->showBox(std::move(box));
|
||||
return;
|
||||
}
|
||||
auto box = Box(
|
||||
ChooseJoinAsBox,
|
||||
context,
|
||||
std::move(info),
|
||||
crl::guard(&_request->guard, finish));
|
||||
box->boxClosing(
|
||||
) | rpl::start_with_next([=] {
|
||||
_request = nullptr;
|
||||
}, _request->lifetime);
|
||||
|
||||
_request->box = box.data();
|
||||
_request->showBox(std::move(box));
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
finish({
|
||||
.peer = _request->peer,
|
||||
.joinAs = _request->peer->session().user(),
|
||||
});
|
||||
}).send();
|
||||
}
|
||||
|
||||
} // namespace Calls::Group
|
||||
59
Telegram/SourceFiles/calls/calls_choose_join_as.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/weak_ptr.h"
|
||||
#include "base/object_ptr.h"
|
||||
|
||||
class PeerData;
|
||||
|
||||
namespace Ui {
|
||||
class BoxContent;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Calls::Group {
|
||||
|
||||
struct JoinInfo;
|
||||
|
||||
class ChooseJoinAsProcess final {
|
||||
public:
|
||||
ChooseJoinAsProcess() = default;
|
||||
~ChooseJoinAsProcess();
|
||||
|
||||
enum class Context {
|
||||
Create,
|
||||
Join,
|
||||
JoinWithConfirm,
|
||||
Switch,
|
||||
};
|
||||
|
||||
void start(
|
||||
not_null<PeerData*> peer,
|
||||
Context context,
|
||||
Fn<void(object_ptr<Ui::BoxContent>)> showBox,
|
||||
Fn<void(QString)> showToast,
|
||||
Fn<void(JoinInfo)> done,
|
||||
PeerData *changingJoinAsFrom = nullptr);
|
||||
|
||||
private:
|
||||
struct ChannelsListRequest {
|
||||
not_null<PeerData*> peer;
|
||||
Fn<void(object_ptr<Ui::BoxContent>)> showBox;
|
||||
Fn<void(QString)> showToast;
|
||||
Fn<void(JoinInfo)> done;
|
||||
base::has_weak_ptr guard;
|
||||
QPointer<Ui::BoxContent> box;
|
||||
rpl::lifetime lifetime;
|
||||
Context context = Context();
|
||||
mtpRequestId id = 0;
|
||||
};
|
||||
std::unique_ptr<ChannelsListRequest> _request;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Calls::Group
|
||||
@@ -51,9 +51,9 @@ using namespace Webrtc;
|
||||
encryptionKey.value.size()),
|
||||
.outgoing = encryptionKey.isOutgoing,
|
||||
.primary = ConvertEndpoint(endpoints.front()),
|
||||
.alternatives = endpoints | ranges::view::drop(
|
||||
.alternatives = endpoints | ranges::views::drop(
|
||||
1
|
||||
) | ranges::view::transform(ConvertEndpoint) | ranges::to_vector,
|
||||
) | ranges::views::transform(ConvertEndpoint) | ranges::to_vector,
|
||||
.maxLayer = config.maxApiLayer,
|
||||
.allowP2P = config.enableP2P,
|
||||
.sendSignalingData = std::move(sendSignalingData),
|
||||
|
||||