Compare commits

..

190 Commits

Author SHA1 Message Date
John Preston
a82d1e863e Version 2.7.1: Fix channels ban in admin log. 2021-03-20 18:19:31 +04:00
John Preston
26d97a3636 Version 2.7.1.
- Fix editing 'Manage Voice Chats' rights for channel admins.
- Fix verification check display in voice chat participants list.
- Allow removing and blocking channels from voice chats.
2021-03-20 16:23:41 +04:00
John Preston
7b8e421996 Allow markup in some voice chat toasts. 2021-03-20 16:23:41 +04:00
John Preston
2bc2a0e459 Fix possible integer overflow. 2021-03-20 16:03:58 +04:00
John Preston
7cb4b4f8ab Don't try to use WebRTC built-in audio backends. 2021-03-20 15:43:35 +04:00
John Preston
b439ecce16 Allow all toasts to be multiline in voice chats. 2021-03-20 15:43:35 +04:00
John Preston
a33a4c0589 Fix maximize/restore voice chat title bar button. 2021-03-20 15:43:35 +04:00
John Preston
5278e2201f Make red 'Remove' in voice chat participant menu. 2021-03-20 15:43:35 +04:00
John Preston
3bd6b2268f Allow blocking channels in voice chats. 2021-03-20 15:43:35 +04:00
John Preston
a0a13c3b86 Update API scheme to layer 126. 2021-03-20 15:43:35 +04:00
John Preston
0052c7938f Fix verified icon in voice chat participants list. 2021-03-20 15:43:35 +04:00
John Preston
a14db3e492 Allow editing 'Manage Voice Chats' admin right in channels. 2021-03-20 15:43:35 +04:00
Ilya Fedin
7979b3b6c8 Fix devtoolset version in linux action 2021-03-20 14:33:02 +03:00
Ilya Fedin
3f25e92afd Add build options for libtgvoip backends
libtgvoip has options to disbale some backends, but they never were exposed via tdesktop's cmake

Since libtgvoip autoconf build system doesn't work anymore, it's worth to have these options in tdesktop's cmake.
2021-03-20 14:33:02 +03:00
Ilya Fedin
3d1cddaca5 Add a way to change default handler in snap 2021-03-20 14:20:09 +03:00
John Preston
eeecc42c25 Version 2.7.
- Start limitless Voice Chats in Groups and Channels.
- Host discussions that can be listened to
by millions of people simultaneously.
- Record voice chats to share or publish in Channels later.
- See that a chat is being recorded
from the red dot next to its title.
- See user bio texts right from the list of participants.
- Raise your hand to show admins you want to speak.
- Create separate Voice Chat Invite Links for listeners or speakers.
- Change the title of your Voice Chat
to give people an idea of the current topic.
- Join Voice Chats as one of your Channels
to hide your personal account.
2021-03-19 14:15:26 +04:00
John Preston
e22ecafc1d Add confirmation on create / anonymous admin join. 2021-03-19 14:10:02 +04:00
John Preston
ba41da7b28 Fix discarded group call handle. 2021-03-19 00:57:16 +04:00
John Preston
9cfbccf9e7 Beta version 2.6.8.
- Fix connecting and getting allowed to speak on voice chats.
- MPRIS support on Linux.
2021-03-18 22:56:42 +04:00
John Preston
2b6f50e114 Fix joining / unmuting. 2021-03-18 22:56:42 +04:00
Ilya Fedin
d2f57b72c3 Add mpris permission for snap 2021-03-18 21:55:06 +03:00
Ilya Fedin
85ac983a27 Add MPRIS support 2021-03-18 21:55:06 +03:00
John Preston
ac397e6e19 Beta version 2.6.7.
- Improve voice chat participants list updating.
2021-03-18 18:05:43 +04:00
John Preston
38e15c9bdb Fix saving legacy chat admins without migration.
Fixes #10558.
2021-03-18 17:27:33 +04:00
John Preston
00d65fa978 Request one participants slice on voice chat reload. 2021-03-18 16:58:05 +04:00
John Preston
3fea9cca08 Subscribe to channel updates in voice chat. 2021-03-18 15:54:28 +04:00
John Preston
b390e0766b Apply all queued updates on reload. 2021-03-18 15:30:58 +04:00
John Preston
2f75e6bbe2 Add some logging for voice chat updates. 2021-03-18 15:22:55 +04:00
Ilya Fedin
decbbb9a73 Check for openal fork updates in Dockerfile 2021-03-18 07:51:57 +03:00
Ilya Fedin
b4b80822c8 Set glib's application name and prgname 2021-03-18 07:51:57 +03:00
John Preston
bc82cdc3b3 Call dump_syms and strip outside of docker. 2021-03-18 02:33:29 +04:00
John Preston
ebc67d25f0 Migrate docker build to GCC 9. 2021-03-18 00:30:12 +04:00
John Preston
348b4d54ba Revert "Workaround build issues on GCC."
This reverts commit 3defb06783.
2021-03-18 00:30:12 +04:00
John Preston
6f86ce595b Beta version 2.6.6.
- Fix joining popular voice chats.
2021-03-18 00:26:53 +04:00
John Preston
8c53a3c19e Don't skip updateGroupCallParticipants while in getDifference. 2021-03-18 00:25:53 +04:00
John Preston
67623072d6 Fix joining a voice chat. 2021-03-18 00:24:36 +04:00
John Preston
1291f1c80d Beta version 2.6.5.
- Improvements and fixes in new voice chat features.
2021-03-17 21:16:55 +04:00
John Preston
0684db9bd8 Improve participants sorting in voice chats. 2021-03-17 20:37:55 +04:00
John Preston
db7b61a77b Rewrite voice chat members list management. 2021-03-17 20:37:55 +04:00
John Preston
d392633b90 Send speaking typings in channels. 2021-03-17 20:37:55 +04:00
John Preston
76e08af26a Apply updateGroupCallParticipants before updateGroupCall. 2021-03-17 20:37:55 +04:00
John Preston
b23f16e6e4 Don't show 'allowed to speak' on first join. 2021-03-17 20:37:54 +04:00
23rd
23156d523c Fixed Github CI Windows build. 2021-03-17 18:59:20 +03:00
Ilya Fedin
04b0e2e9e6 Update submodules 2021-03-17 18:58:02 +03:00
Ilya Fedin
ace5740125 Use QProcess::startDetached for xdg-open
Since it may running continously
2021-03-17 15:39:26 +03:00
John Preston
bc67b79023 Beta version 2.6.4: 110% UI scale on macOS Retina. 2021-03-17 00:07:08 +04:00
John Preston
528c98af67 Beta version 2.6.4.
- Fix freeze in voice chats.
2021-03-17 00:02:05 +04:00
John Preston
311a2f2753 Fix freeze in voice chats. 2021-03-16 23:54:58 +04:00
John Preston
3defb06783 Workaround build issues on GCC. 2021-03-16 22:26:58 +04:00
John Preston
5708b5e849 Fix confirmation when joining by link. 2021-03-16 21:06:36 +04:00
John Preston
1db1328a91 Beta version 2.6.3.
- Fix audio device selection in voice chats.
- Fix blinking self profile photo
in case the profile photo privacy is used.
- Fix voice chat admin menu on macOS.
2021-03-16 19:13:15 +04:00
John Preston
2e9d6d73c3 Fix invalid 'You can speak' notification. 2021-03-16 19:09:23 +04:00
John Preston
38dd5ab837 Fix 'join as' userpic button display. 2021-03-16 18:58:10 +04:00
John Preston
83ab670c50 Remove 'wants to speak' status in three seconds. 2021-03-16 18:51:38 +04:00
John Preston
5621e41529 Limit voice chat title to 40 characters. 2021-03-16 18:51:11 +04:00
John Preston
056cab6268 Don't apply private userpic 'min' updates. 2021-03-16 18:15:19 +04:00
John Preston
61d0d240aa Add 'rejoin as' and 'change title' toast notifications. 2021-03-16 18:13:51 +04:00
John Preston
33ae4c2802 Improve layout of voice chat channel choosing. 2021-03-16 17:16:56 +04:00
John Preston
2c806b11d7 Always join voice chats by link with confirmation. 2021-03-16 17:16:01 +04:00
John Preston
199434c7a2 Add recording mark animation. 2021-03-16 14:48:12 +04:00
John Preston
c65c554d88 Don't ask joinAs for voice chats each time. 2021-03-16 14:33:11 +04:00
John Preston
5d16359a5a Fix voice chat three-dot menu on macOS. 2021-03-16 13:50:40 +04:00
John Preston
fd9ad04d15 Vazir Without-Latin instead of Without-Latin-UI.
Fixes #10536.
2021-03-16 13:29:46 +04:00
Ilya Fedin
0c8febce9c Avoid allocations for case-insensetive compare 2021-03-16 12:20:48 +03:00
John Preston
4659cc50f2 Allow inviting members in channel voice chats. 2021-03-15 22:40:59 +04:00
John Preston
2fddeb478b Fix long texts in invite link error toasts. 2021-03-15 20:49:38 +04:00
Ilya Fedin
4ffe1d3acc Use base::flat_map for pointer keys 2021-03-15 19:49:06 +03:00
Ilya Fedin
cdf0512515 Remove unused variable in mainwidget 2021-03-15 19:49:06 +03:00
Ilya Fedin
971e188063 Replace remaining QFileInfo::exists 2021-03-15 19:49:06 +03:00
John Preston
a909c1a813 Make default UI scale 120% on macOS Retina. 2021-03-15 20:33:41 +04:00
John Preston
4fc2b1f1a3 Append x64 to app_version on Windows. 2021-03-15 20:14:39 +04:00
John Preston
fb04f33ae8 Fix long voice chat title elision on macOS. 2021-03-15 19:34:58 +04:00
John Preston
b2c87e7a73 Fix three-dot toggle in voice chats. 2021-03-15 19:19:29 +04:00
John Preston
86a33ceea1 Fix audio device selection in voice chats. 2021-03-15 19:00:58 +04:00
John Preston
a5d8d7a550 Add some validation for GroupThumbs. 2021-03-15 19:00:32 +04:00
Ilya Fedin
11723aedff Get rid of empty QStringLiterals 2021-03-15 17:19:59 +03:00
Ilya Fedin
fe5de8f009 Fix non-working UniqueConnection in gtk file dialog 2021-03-15 17:19:44 +03:00
Ilya Fedin
6b68d001ae Get rid of deprecated ranges::action 2021-03-15 11:41:29 +03:00
Ilya Fedin
ae0b9141dd Trying to get rid of unused variables... 2021-03-15 11:40:44 +03:00
Ilya Fedin
12e306dd7b Replace remaining multi-args 2021-03-15 11:21:05 +03:00
Ilya Fedin
508762cd2c Use static QFileInfo::exists 2021-03-15 11:21:05 +03:00
John Preston
9a73c99935 Beta version 2.6.2: Fix build. 2021-03-13 21:05:53 +04:00
John Preston
ab2c99acf3 Beta version 2.6.2.
- Fix text disappearing because of cloud drafts sync.
2021-03-13 20:16:23 +04:00
Ilya Fedin
a506e9b9eb Update submodules 2021-03-13 19:14:58 +03:00
Ilya Fedin
c0c10689a1 Get rid of deprecated ranges::view usage 2021-03-13 19:14:58 +03:00
Ilya Fedin
c4dcf064d5 Avoid multiple .arg usage as suggested by clazy 2021-03-13 19:08:33 +03:00
John Preston
d9771d0f88 Fix voice chat lottie animation on Retina screens. 2021-03-13 20:05:17 +04:00
Ilya Fedin
f25b2a2094 Apply autofixes from clazy 2021-03-13 15:25:47 +03:00
John Preston
c9934c142d Fix drafts time tracking. 2021-03-13 16:07:59 +04:00
John Preston
fb7a8cae33 Improve voice chat lottie animations. 2021-03-13 15:27:25 +04:00
John Preston
ae5c7b19f6 Fix refreshing MainWindow::desktopRect. 2021-03-13 14:37:58 +04:00
23rd
a5abe3d813 Added ability to Save / Delete GIFs from menu for inline bots.
Fixed #10511.
2021-03-13 12:59:12 +03:00
23rd
b373a9ed22 Fixed filling menu for inline bots and autocomplete in HistoryWidget.
Regression was introduced in e1017380ec.
2021-03-13 12:59:12 +03:00
23rd
09966fb291 Removed Q_OBJECT from Storage::Uploader. 2021-03-13 12:59:11 +03:00
23rd
d4bb62d055 Slightly refactored uploading of edit media. 2021-03-13 12:59:11 +03:00
John Preston
bbeb9d3950 Add error display on link sharing. 2021-03-12 22:38:30 +04:00
John Preston
ce84d9c84d Improve phrases in share voice chat link box. 2021-03-12 22:23:26 +04:00
John Preston
ed4dea2b0e Show and play 'allowed to speak' notification. 2021-03-12 21:51:39 +04:00
John Preston
4d4a349f09 Support sharing only listener invite link. 2021-03-12 20:20:19 +04:00
John Preston
7430fbacfd Allow remove raised hand from context menu. 2021-03-12 20:20:03 +04:00
John Preston
d624e2ef65 Fix build on macOS and Linux. 2021-03-12 19:21:35 +04:00
John Preston
0e72dc3974 Closed alpha version 2.6.1.1. 2021-03-12 17:31:10 +04:00
John Preston
68b0a85369 Rename RPCError to MTP::Error. 2021-03-12 16:58:26 +04:00
John Preston
5794679277 Don't accept drafts older than last saved.
I hope it finally fixes #4922, partially fixes #10001.

The rest of #10001 like RAM usage / crashes are unrelated to drafts.
2021-03-12 16:58:26 +04:00
John Preston
74c21039b3 Pass correct response timestamp to tgcalls. 2021-03-12 16:58:26 +04:00
John Preston
267e5fd9e0 Allow getting outer_msg_id in MTProto handlers. 2021-03-12 16:58:26 +04:00
John Preston
e681b0d95a Support new url-auth auto-logins in links. 2021-03-12 16:58:26 +04:00
John Preston
a2695ea0d7 Add CallMuteButton with lottie animations. 2021-03-12 16:58:26 +04:00
John Preston
c0df6f7bca Join voice chats by invite links. 2021-03-12 16:58:26 +04:00
John Preston
c587335ae1 Adapt share voice chat link box styles. 2021-03-12 16:58:26 +04:00
John Preston
16e1c740ce Support sharing speaker/listener link. 2021-03-12 16:58:26 +04:00
John Preston
6786d44b69 Start voice chat link sharing. 2021-03-12 16:58:26 +04:00
John Preston
cd8c9a58df Show 'about' in voice chats for everyone. 2021-03-12 16:58:26 +04:00
John Preston
ecbbdd5e74 Make custom 'Join As' menu item. 2021-03-12 16:58:26 +04:00
John Preston
a8a85b2acf Show correct tooltip on stopping recording. 2021-03-12 16:58:26 +04:00
John Preston
8ba77defeb Custom menu items for recording / leaving. 2021-03-12 16:58:26 +04:00
John Preston
84e8053cd0 Move group call menu to a separate module. 2021-03-12 16:58:26 +04:00
John Preston
506cd8c7ad Improve 'Join As' selector design. 2021-03-12 16:58:26 +04:00
John Preston
f8783c3bfc Move actions from Settings to Three-Dot-Menu. 2021-03-12 16:58:26 +04:00
John Preston
b24e5ce809 Update API scheme with voice chat links. 2021-03-12 16:58:26 +04:00
John Preston
18901a4dc7 Update tgcalls for better stream->rtc upgrade. 2021-03-12 16:58:26 +04:00
John Preston
81e08599dc Raising hands reorder participants only for admins. 2021-03-12 16:58:26 +04:00
John Preston
7edc91e29e Show recording indicator. 2021-03-12 16:58:26 +04:00
John Preston
50265afe93 Respect raise_hand_rating in participants list. 2021-03-12 16:58:26 +04:00
John Preston
4d8ac05d28 Improve mute/raise_hand saving. 2021-03-12 16:58:26 +04:00
John Preston
22aa57ad6f Add recording start/stop to Settings. 2021-03-12 16:58:26 +04:00
John Preston
5bea88fd66 Update tgcalls to use ffmpeg instead of opusfile. 2021-03-12 16:58:26 +04:00
John Preston
361e3565d4 Add raised hand display in participants list. 2021-03-12 16:58:26 +04:00
John Preston
fb579f1c10 Add ability to Raise Hand in ForceMuted state. 2021-03-12 16:58:26 +04:00
John Preston
f66d7088ef Support broadcast mode in voice chats. 2021-03-12 16:58:26 +04:00
John Preston
ccd440ea0b Update API scheme. 2021-03-12 16:58:26 +04:00
John Preston
f41abe0a28 Update tgcalls. 2021-03-12 16:58:26 +04:00
John Preston
cfd16c6f67 Ignore version in groupCall updates.
Otherwise we may skip participants update that changes the version.
2021-03-12 16:58:26 +04:00
John Preston
ef1d98f3cf Show about in voice chat channels. 2021-03-12 16:58:26 +04:00
John Preston
bc43168ca7 Add edit voice chat title. 2021-03-12 16:58:26 +04:00
John Preston
b670ca2a51 Allow to rejoin with changing of 'join_as'. 2021-03-12 16:58:26 +04:00
John Preston
4d093f78e2 Update self as channel in voice chats. 2021-03-12 16:58:26 +04:00
John Preston
02e9b8fd18 Support joining to voice chats as a channel. 2021-03-12 16:58:26 +04:00
John Preston
02517f7221 Update API scheme to layer 125. 2021-03-12 16:58:26 +04:00
John Preston
2734cab3f2 Add webkitgtk4-devel to Dockerfile. 2021-03-12 16:28:56 +04:00
John Preston
2509f05e28 Fix clearing of album thumbnails cache.
I hope it fixes #7361.
2021-03-12 16:09:58 +04:00
Ilya Fedin
8fee156d21 Restore collecting Qt debug info on Linux 2021-03-12 16:09:13 +04:00
Ilya Fedin
e493ab12dc Get rid of GetLauncherFilename
Use QGuiApplication::desktopFileName directly instead
2021-03-12 15:44:37 +04:00
Sprite
4d9c9bbd6f Add a comment to the header inclusion
Co-authored-by: 23rd <23rd@vivaldi.net>
2021-03-12 15:42:20 +04:00
Sprite
c7c145b226 Complete report action callback 2021-03-12 15:42:20 +04:00
23rd
504f5ee5d7 Improved text resizing in playback speed item. 2021-03-11 12:29:17 +03:00
Ilya Fedin
3d54192681 Update lib_base 2021-03-11 11:31:26 +04:00
Ilya Fedin
db0da70de6 Fix space on end of a g_warning 2021-03-11 11:19:26 +04:00
Ilya Fedin
59e6fd9989 Fallback to plain xdg-open as a last resort
Even though QDesktopServices::openUrl calls xdg-open, it doesn't fallback to xdg-open in confined environments.
This is useful in snap where portals aren't guaranteed to be present.
2021-03-11 11:19:26 +04:00
Ilya Fedin
b24cba99e2 Catch ListActivatableNames errors 2021-03-10 11:22:14 +04:00
Ilya Fedin
d6848c49e8 Fire reject signal on exceptions in XDP file dialog 2021-03-10 09:47:30 +04:00
Ilya Fedin
5d1601d9c9 Move Platform::FileDialog::Gtk::Supported to private namespace 2021-03-10 09:46:13 +04:00
Ilya Fedin
2c6a9614b2 Fix saving filename compatibility with xdg-desktop-portal-gtk 2021-03-10 09:46:13 +04:00
Ilya Fedin
cc736158a6 Get rid of QByteArray in djbStringHash 2021-03-10 09:46:13 +04:00
Ilya Fedin
817610ddd7 Get rid of RunShellCommand 2021-03-10 09:46:13 +04:00
Ilya Fedin
77c8ca76b7 Remove duplicate ifndef DESKTOP_APP_DISABLE_DBUS_INTEGRATION in includes 2021-03-10 09:46:13 +04:00
Ilya Fedin
67cbe61879 Check if portal backend is present by absence of errors when getting portal version 2021-03-10 09:46:13 +04:00
Ilya Fedin
67eba93e29 Use gsl::finally in PortalAutostart 2021-03-10 09:46:13 +04:00
Ilya Fedin
b918170464 Add portal-based open with dialog implementation 2021-03-10 09:46:13 +04:00
Ilya Fedin
a27a54798c Update lib_ui 2021-03-10 08:57:16 +04:00
Ilya Fedin
5f1d56fbc2 Move gtk settings connections to getters 2021-03-10 08:57:16 +04:00
Ilya Fedin
1fc24398a0 React to moveEvent in media viewer 2021-03-06 12:08:20 +04:00
Ilya Fedin
99b7f051c7 Restore mouse button release hack in title widget event filter 2021-03-06 12:07:39 +04:00
23rd
658671089e Added timestamp highlighting in voice captions. 2021-03-05 13:36:39 +03:00
Ilya Fedin
092b6e7c18 Fix spaces on ends of lines 2021-03-05 13:31:56 +04:00
Ilya Fedin
23272430b4 Build with QT_NO_KEYWORDS 2021-03-04 12:07:54 +04:00
Ilya Fedin
a29ff093f6 Fix some lines length in specific_linux 2021-03-04 12:07:54 +04:00
Ilya Fedin
37a8afaddf Move remaining usage of dbus to glibmm in notifications_manager_linux 2021-03-04 12:07:54 +04:00
Ilya Fedin
b08c33cf8a Move remaining usage of dbus to glibmm in main_window_linux 2021-03-04 12:07:54 +04:00
Ilya Fedin
a2f8546033 Move remaining usage of dbus to glibmm in specific_linux 2021-03-04 12:07:54 +04:00
Ilya Fedin
580a12ad7f Wait for response in PortalAutostart 2021-03-04 12:07:54 +04:00
Ilya Fedin
d77df9905f Move NotificationServiceWatcher to glibmm 2021-03-04 12:07:54 +04:00
Ilya Fedin
82f92cffd3 Port XDPFileDialog to gdbus 2021-03-04 12:07:54 +04:00
Ilya Fedin
8042a83fd2 Move glib usage to glibmm 2021-03-04 12:07:54 +04:00
John Preston
b38d6667c4 Fix build on macOS. 2021-03-04 11:55:20 +04:00
Ilya Fedin
72704b2426 Move from lock-threads app to lock-threads action
lock-threads app seems to be deprecated
2021-03-03 23:14:13 +04:00
Daniil
3e379f3171 Expand moderating mode
Add additional moderating options.
2021-03-03 22:57:14 +04:00
GitHub Action
54685155b0 Update User-Agent for DNS to Chrome 88.0.4324.182. 2021-03-03 20:19:57 +04:00
John Preston
54f06740d5 Remove some App::wnd() calls. 2021-03-03 11:29:26 +04:00
John Preston
204dd0a869 Revert "Use custom method to focus main window on X11"
This reverts commit f9bba75395.

See #10441.
2021-03-01 11:47:59 +04:00
John Preston
8142acc709 Remove legacy #feed code. 2021-02-25 17:03:51 +04:00
23rd
df70fd3081 Fixed Github CI macOS build. 2021-02-25 08:42:16 +03:00
John Preston
97d8ee75d5 Version 2.6.1.
- Fix time formatting in links.
- Fix copy QR code in night mode.
- Fix invite link sharing without a comment.
- Fix crash in link editing on Linux.
2021-02-24 21:41:37 +04:00
Ilya Fedin
f9bba75395 Use custom method to focus main window on X11 2021-02-24 21:41:14 +04:00
Ilya Fedin
9b88f816d6 Use new Platform::IsX11 2021-02-24 21:41:14 +04:00
John Preston
28c918a36a Update submodules. 2021-02-24 21:40:40 +04:00
John Preston
b638650b41 Fix invite link sharing without a comment. 2021-02-24 19:17:48 +04:00
John Preston
2d8e6f9745 Fix crash in EditLinkBox destruction.
Fixes #10432.
2021-02-24 19:07:49 +04:00
John Preston
627426f604 Fix copy QR code in night mode. 2021-02-24 15:10:19 +04:00
John Preston
7b80514986 Fix time formatting in links. 2021-02-24 15:10:06 +04:00
448 changed files with 12015 additions and 10251 deletions

21
.github/lock.yml vendored
View File

@@ -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

View File

@@ -55,7 +55,7 @@ jobs:
defaults:
run:
shell: scl enable devtoolset-8 -- bash --noprofile --norc -eo pipefail {0}
shell: scl enable devtoolset-9 -- bash --noprofile --norc -eo pipefail {0}
strategy:
matrix:
@@ -65,6 +65,8 @@ jobs:
- "DESKTOP_APP_DISABLE_X11_INTEGRATION"
- "DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION"
- "DESKTOP_APP_DISABLE_GTK_INTEGRATION"
- "LIBTGVOIP_DISABLE_ALSA"
- "LIBTGVOIP_DISABLE_PULSEAUDIO"
env:
UPLOAD_ARTIFACT: "false"

23
.github/workflows/lock.yml vendored Normal file
View 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.

View File

@@ -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

View File

@@ -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%

View File

@@ -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,18 @@ 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_mpris_support.cpp
platform/linux/linux_mpris_support.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 +969,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
@@ -1124,10 +1115,14 @@ if (DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
remove_target_sources(Telegram ${src_loc}
platform/linux/linux_gsd_media_keys.cpp
platform/linux/linux_gsd_media_keys.h
platform/linux/linux_mpris_support.cpp
platform/linux/linux_mpris_support.h
platform/linux/linux_notification_service_watcher.cpp
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 +1145,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}

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1923,18 +1923,24 @@ 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";
"lng_group_call_leave_sure" = "Are you sure you want to leave this voice chat?";
"lng_group_call_leave_to_other_sure" = "Do you want to leave your active voice chat and join a voice chat in this group?";
"lng_group_call_create_sure" = "Do you really want to start a voice chat in this group?";
"lng_group_call_create_sure_channel" = "Are you sure you want to start a voice chat in this channel as your personal account?";
"lng_group_call_join_sure_personal" = "Are you sure you want to join this voice chat as your personal account?";
"lng_group_call_also_end" = "End voice chat";
"lng_group_call_settings_title" = "Settings";
"lng_group_call_invite" = "Invite Member";
@@ -1947,7 +1953,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 +1963,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,8 +1979,11 @@ 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_context_remove" = "Remove";
"lng_group_call_remove_channel" = "Remove {channel} from the voice chat?";
"lng_group_call_duration_days#one" = "{count} day";
"lng_group_call_duration_days#other" = "{count} days";
"lng_group_call_duration_hours#one" = "{count} hour";
@@ -1984,6 +1997,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}";
@@ -2190,6 +2226,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_admin_log_stopped_poll" = "{from} stopped poll:";
"lng_admin_log_invited" = "invited {user}";
"lng_admin_log_banned" = "banned {user}";
"lng_admin_log_unbanned" = "unbanned {user}";
"lng_admin_log_restricted" = "changed restrictions for {user} {until}";
"lng_admin_log_promoted" = "changed privileges for {user}";
"lng_admin_log_transferred" = "transferred ownership to {user}";
@@ -2238,34 +2275,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";

View File

@@ -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>

View File

@@ -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>

Binary file not shown.

View 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;
@@ -619,8 +620,8 @@ channelParticipant#15ebac1d user_id:int date:int = ChannelParticipant;
channelParticipantSelf#a3289a6d user_id:int inviter_id:int date:int = ChannelParticipant;
channelParticipantCreator#447dca4b flags:# user_id:int admin_rights:ChatAdminRights rank:flags.0?string = ChannelParticipant;
channelParticipantAdmin#ccbebbaf flags:# can_edit:flags.0?true self:flags.1?true user_id:int inviter_id:flags.1?int promoted_by:int date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant;
channelParticipantBanned#1c0facaf flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant;
channelParticipantLeft#c3c6796b user_id:int = ChannelParticipant;
channelParticipantBanned#50a1dfd6 flags:# left:flags.0?true peer:Peer kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant;
channelParticipantLeft#1b03f006 peer:Peer = ChannelParticipant;
channelParticipantsRecent#de3f3c79 = ChannelParticipantsFilter;
channelParticipantsAdmins#b4608969 = ChannelParticipantsFilter;
@@ -631,10 +632,10 @@ channelParticipantsSearch#656ac4b q:string = ChannelParticipantsFilter;
channelParticipantsContacts#bb6ae88d q:string = ChannelParticipantsFilter;
channelParticipantsMentions#e04b5ceb flags:# q:flags.0?string top_msg_id:flags.1?int = ChannelParticipantsFilter;
channels.channelParticipants#f56ee2a8 count:int participants:Vector<ChannelParticipant> users:Vector<User> = channels.ChannelParticipants;
channels.channelParticipants#9ab0feaf count:int participants:Vector<ChannelParticipant> chats:Vector<Chat> users:Vector<User> = channels.ChannelParticipants;
channels.channelParticipantsNotModified#f0173fe9 = channels.ChannelParticipants;
channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector<User> = channels.ChannelParticipant;
channels.channelParticipant#dfb80317 participant:ChannelParticipant chats:Vector<Chat> users:Vector<User> = channels.ChannelParticipant;
help.termsOfService#780a0310 flags:# popup:flags.0?true id:DataJSON text:string entities:Vector<MessageEntity> min_age_confirm:flags.1?int = help.TermsOfService;
@@ -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;
@@ -1548,7 +1557,7 @@ channels.deleteUserHistory#d10dd71b channel:InputChannel user_id:InputUser = mes
channels.reportSpam#fe087810 channel:InputChannel user_id:InputUser id:Vector<int> = Bool;
channels.getMessages#ad8c9a23 channel:InputChannel id:Vector<InputMessage> = messages.Messages;
channels.getParticipants#123e05e9 channel:InputChannel filter:ChannelParticipantsFilter offset:int limit:int hash:int = channels.ChannelParticipants;
channels.getParticipant#546dd7a6 channel:InputChannel user_id:InputUser = channels.ChannelParticipant;
channels.getParticipant#a0ab6cc6 channel:InputChannel participant:InputPeer = channels.ChannelParticipant;
channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;
channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull;
channels.createChannel#3d5fb10f flags:# broadcast:flags.0?true megagroup:flags.1?true for_import:flags.3?true title:string about:string geo_point:flags.2?InputGeoPoint address:flags.2?string = Updates;
@@ -1564,7 +1573,7 @@ channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
channels.exportMessageLink#e63fadeb flags:# grouped:flags.0?true thread:flags.1?true channel:InputChannel id:int = ExportedMessageLink;
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true = messages.Chats;
channels.editBanned#72796912 channel:InputChannel user_id:InputUser banned_rights:ChatBannedRights = Updates;
channels.editBanned#96e6cd81 channel:InputChannel participant:InputPeer banned_rights:ChatBannedRights = Updates;
channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector<InputUser> max_id:long min_id:long limit:int = channels.AdminLogResults;
channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet = Bool;
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
@@ -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 126

View File

@@ -9,7 +9,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="2.6.0.0" />
Version="2.7.1.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>

View File

@@ -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,7,1,0
PRODUCTVERSION 2,7,1,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.7.1.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.6.0.0"
VALUE "ProductVersion", "2.7.1.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -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,7,1,0
PRODUCTVERSION 2,7,1,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.7.1.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.6.0.0"
VALUE "ProductVersion", "2.7.1.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -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();

View File

@@ -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(

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -75,7 +75,7 @@ void CheckChatInvite(
}
}
});
}, [=](const RPCError &error) {
}, [=](const MTP::Error &error) {
if (error.code() != 400) {
return;
}

View File

@@ -33,6 +33,7 @@ struct SendAction {
MsgId replyTo = 0;
bool clearDraft = true;
bool generateLocal = true;
MsgId replaceMediaOf = 0;
};
struct MessageToSend {

View File

@@ -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,

View File

@@ -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

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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();

View File

@@ -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) {

View File

@@ -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));
}
}
}
@@ -277,12 +277,32 @@ 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) {
SkipUpdatePolicy policy) {
auto list = updates.v;
const auto hasGroupCallParticipantUpdates = ranges::contains(
list,
mtpc_updateGroupCallParticipants,
&MTPUpdate::type);
if (hasGroupCallParticipantUpdates) {
ranges::stable_sort(list, std::less<>(), [](const MTPUpdate &entry) {
if (entry.type() == mtpc_updateGroupCallParticipants) {
return 0;
} else {
return 1;
}
});
} else if (policy == SkipUpdatePolicy::SkipExceptGroupCallParticipants) {
return;
}
for (const auto &entry : std::as_const(list)) {
const auto type = entry.type();
if ((policy == SkipUpdatePolicy::SkipMessageIds
&& type == mtpc_updateMessageID)
|| (policy == SkipUpdatePolicy::SkipExceptGroupCallParticipants
&& type != mtpc_updateGroupCallParticipants)) {
continue;
}
feedUpdate(update);
feedUpdate(entry);
}
session().data().sendHistoryChangeNotifications();
}
@@ -392,17 +412,19 @@ void Updates::feedChannelDifference(
session().data().processMessages(
data.vnew_messages(),
NewMessageType::Unread);
feedUpdateVector(data.vother_updates(), true);
feedUpdateVector(
data.vother_updates(),
SkipUpdatePolicy::SkipMessageIds);
_handlingChannelDifference = false;
}
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);
}
@@ -553,14 +575,14 @@ void Updates::feedDifference(
session().data().processChats(chats);
feedMessageIds(other);
session().data().processMessages(msgs, NewMessageType::Unread);
feedUpdateVector(other, true);
feedUpdateVector(other, SkipUpdatePolicy::SkipMessageIds);
}
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 +665,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 +700,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 +764,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);
@@ -810,9 +832,32 @@ void Updates::mtpUpdateReceived(const MTPUpdates &updates) {
if (!requestingDifference()
|| HasForceLogoutNotification(updates)) {
applyUpdates(updates);
} else {
applyGroupCallParticipantUpdates(updates);
}
}
void Updates::applyGroupCallParticipantUpdates(const MTPUpdates &updates) {
updates.match([&](const MTPDupdates &data) {
session().data().processUsers(data.vusers());
session().data().processChats(data.vchats());
feedUpdateVector(
data.vupdates(),
SkipUpdatePolicy::SkipExceptGroupCallParticipants);
}, [&](const MTPDupdatesCombined &data) {
session().data().processUsers(data.vusers());
session().data().processChats(data.vchats());
feedUpdateVector(
data.vupdates(),
SkipUpdatePolicy::SkipExceptGroupCallParticipants);
}, [&](const MTPDupdateShort &data) {
if (data.vupdate().type() == mtpc_updateGroupCallParticipants) {
feedUpdate(data.vupdate());
}
}, [](const auto &) {
});
}
int32 Updates::pts() const {
return _ptsWaiter.current();
}
@@ -862,7 +907,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 +960,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 +980,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 +990,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 +1007,7 @@ void Updates::handleSendActionUpdate(
session().data().registerSendAction(
history,
rootId,
user,
from->asUser(),
action,
when);
}
@@ -1539,22 +1586,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 +1689,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 +2036,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);
}

View File

@@ -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
@@ -63,6 +66,12 @@ private:
AfterFail,
};
enum class SkipUpdatePolicy {
SkipNone,
SkipMessageIds,
SkipExceptGroupCallParticipants,
};
struct ActiveChatTracker {
PeerData *peer = nullptr;
rpl::lifetime lifetime;
@@ -89,7 +98,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 +111,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);
@@ -110,12 +119,14 @@ private:
void mtpNewSessionCreated();
void feedUpdateVector(
const MTPVector<MTPUpdate> &updates,
bool skipMessageIds = false);
SkipUpdatePolicy policy = SkipUpdatePolicy::SkipNone);
// Doesn't call sendHistoryChangeNotifications itself.
void feedMessageIds(const MTPVector<MTPUpdate> &updates);
// Doesn't call sendHistoryChangeNotifications itself.
void feedUpdate(const MTPUpdate &update);
void applyGroupCallParticipantUpdates(const MTPUpdates &updates);
bool whenGetDiffChanged(
ChannelData *channel,
int32 ms,
@@ -125,7 +136,7 @@ private:
void handleSendActionUpdate(
PeerId peerId,
MsgId rootId,
UserId userId,
PeerId fromId,
const MTPSendMessageAction &action);
const not_null<Main::Session*> _session;
@@ -168,7 +179,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;

File diff suppressed because it is too large Load Diff

View File

@@ -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,20 +243,22 @@ 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);
void requestSelfParticipant(not_null<ChannelData*> channel);
void kickParticipant(not_null<ChatData*> chat, not_null<UserData*> user);
void kickParticipant(
not_null<ChatData*> chat,
not_null<PeerData*> participant);
void kickParticipant(
not_null<ChannelData*> channel,
not_null<UserData*> user,
not_null<PeerData*> participant,
const MTPChatBannedRights &currentRights);
void unblockParticipant(
not_null<ChannelData*> channel,
not_null<UserData*> user);
not_null<PeerData*> participant);
void deleteAllFromUser(
not_null<ChannelData*> channel,
not_null<UserData*> from);
@@ -334,14 +330,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 +372,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 +396,7 @@ public:
Ui::PreparedList &&list,
SendMediaType type,
TextWithTags &&caption,
const SendAction &action,
MsgId msgIdToEdit);
const SendAction &action);
void sendUploadedPhoto(
FullMsgId localId,
@@ -433,7 +417,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 +454,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 +549,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 +567,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 +607,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 +629,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;
@@ -690,7 +659,7 @@ private:
using KickRequest = std::pair<
not_null<ChannelData*>,
not_null<UserData*>>;
not_null<PeerData*>>;
base::flat_map<KickRequest, mtpRequestId> _kickRequests;
base::flat_set<not_null<ChannelData*>> _selfParticipantRequests;
@@ -737,20 +706,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 +724,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 +743,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 +787,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;

View File

@@ -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());

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;

View File

@@ -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));

View File

@@ -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);
@@ -900,7 +900,7 @@ void DeleteMessagesBox::deleteAndClear() {
_moderateInChannel->session().api().kickParticipant(
_moderateInChannel,
_moderateFrom,
MTP_chatBannedRights(MTP_flags(0), MTP_int(0)));
ChannelData::EmptyRestrictedRights(_moderateFrom));
}
if (_reportSpam->checked()) {
_moderateInChannel->session().api().request(

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;

View File

@@ -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();

View File

@@ -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)) {

View File

@@ -668,7 +668,7 @@ void EditColorBox::Field::changeValue(int delta) {
setText(QString::number(newValue));
setFocus();
selectAll();
emit changed();
changed();
}
}

View File

@@ -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*>>{

View File

@@ -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); });
}

View File

@@ -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 = [&] {

View File

@@ -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);

View File

@@ -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)

View File

@@ -169,6 +169,7 @@ public:
}
setCheckedInternal(checked, animated);
}
void finishCheckedAnimation();
void invalidatePixmapsCache();
template <typename UpdateCallback>

View File

@@ -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();

View File

@@ -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());
@@ -421,6 +421,7 @@ void AddSpecialBoxController::rebuildChatRows(not_null<ChatData*> chat) {
auto count = delegate()->peerListFullRowsCount();
for (auto i = 0; i != count;) {
auto row = delegate()->peerListRowAt(i);
Assert(row->peer()->isUser());
auto user = row->peer()->asUser();
if (participants.contains(user)) {
++i;
@@ -467,8 +468,9 @@ void AddSpecialBoxController::loadMoreRows() {
int availableCount,
const QVector<MTPChannelParticipant> &list) {
for (const auto &data : list) {
if (const auto user = _additional.applyParticipant(data)) {
appendRow(user);
if (const auto participant = _additional.applyParticipant(
data)) {
appendRow(participant);
}
}
if (const auto size = list.size()) {
@@ -485,26 +487,31 @@ 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();
}
void AddSpecialBoxController::rowClicked(not_null<PeerListRow*> row) {
auto user = row->peer()->asUser();
const auto participant = row->peer();
const auto user = participant->asUser();
switch (_role) {
case Role::Admins: return showAdmin(user);
case Role::Restricted: return showRestricted(user);
case Role::Kicked: return kickUser(user);
case Role::Admins:
Assert(user != nullptr);
return showAdmin(user);
case Role::Restricted:
Assert(user != nullptr);
return showRestricted(user);
case Role::Kicked: return kickUser(participant);
}
Unexpected("Role in AddSpecialBoxController::rowClicked()");
}
template <typename Callback>
bool AddSpecialBoxController::checkInfoLoaded(
not_null<UserData*> user,
not_null<PeerData*> participant,
Callback callback) {
if (_additional.infoLoaded(user)) {
if (_additional.infoLoaded(participant)) {
return true;
}
@@ -512,16 +519,15 @@ bool AddSpecialBoxController::checkInfoLoaded(
const auto channel = _peer->asChannel();
_api.request(MTPchannels_GetParticipant(
channel->inputChannel,
user->inputUser
participant->input
)).done([=](const MTPchannels_ChannelParticipant &result) {
Expects(result.type() == mtpc_channels_channelParticipant);
const auto &participant = result.c_channels_channelParticipant();
channel->owner().processUsers(participant.vusers());
_additional.applyParticipant(participant.vparticipant());
result.match([&](const MTPDchannels_channelParticipant &data) {
channel->owner().processUsers(data.vusers());
_additional.applyParticipant(data.vparticipant());
});
callback();
}).fail([=](const RPCError &error) {
_additional.setExternal(user);
}).fail([=](const MTP::Error &error) {
_additional.setExternal(participant);
callback();
}).send();
return false;
@@ -724,15 +730,13 @@ void AddSpecialBoxController::showRestricted(
// Finally edit the restricted.
const auto currentRights = restrictedRights
? *restrictedRights
: MTPChatBannedRights(MTP_chatBannedRights(
MTP_flags(0),
MTP_int(0)));
: ChannelData::EmptyRestrictedRights(user);
auto box = Box<EditRestrictedBox>(
_peer,
user,
_additional.adminRights(user).has_value(),
currentRights);
if (_additional.canRestrictUser(user)) {
if (_additional.canRestrictParticipant(user)) {
const auto done = crl::guard(this, [=](
const MTPChatBannedRights &newRights) {
editRestrictedDone(user, newRights);
@@ -749,50 +753,61 @@ void AddSpecialBoxController::showRestricted(
}
void AddSpecialBoxController::editRestrictedDone(
not_null<UserData*> user,
not_null<PeerData*> participant,
const MTPChatBannedRights &rights) {
if (_editParticipantBox) {
_editParticipantBox->closeBox();
}
const auto date = base::unixtime::now(); // Incorrect, but ignored.
if (rights.c_chatBannedRights().vflags().v == 0) {
_additional.applyParticipant(MTP_channelParticipant(
MTP_int(user->bareId()),
MTP_int(date)));
if (Data::ChatBannedRightsFlags(rights) == 0) {
if (const auto user = participant->asUser()) {
_additional.applyParticipant(MTP_channelParticipant(
MTP_int(user->bareId()),
MTP_int(date)));
} else {
_additional.setExternal(participant);
}
} else {
const auto kicked = rights.c_chatBannedRights().is_view_messages();
const auto alreadyRestrictedBy = _additional.restrictedBy(user);
const auto kicked = Data::ChatBannedRightsFlags(rights)
& ChatRestriction::f_view_messages;
const auto alreadyRestrictedBy = _additional.restrictedBy(
participant);
_additional.applyParticipant(MTP_channelParticipantBanned(
MTP_flags(kicked
? MTPDchannelParticipantBanned::Flag::f_left
: MTPDchannelParticipantBanned::Flag(0)),
MTP_int(user->bareId()),
(participant->isUser()
? MTP_peerUser(MTP_int(participant->bareId()))
: participant->isChat()
? MTP_peerChat(MTP_int(participant->bareId()))
: MTP_peerChannel(MTP_int(participant->bareId()))),
MTP_int(alreadyRestrictedBy
? alreadyRestrictedBy->bareId()
: user->session().userId()),
: participant->session().userId()),
MTP_int(date),
rights));
}
if (const auto callback = _bannedDoneCallback) {
callback(user, rights);
callback(participant, rights);
}
}
void AddSpecialBoxController::kickUser(
not_null<UserData*> user,
not_null<PeerData*> participant,
bool sure) {
if (!checkInfoLoaded(user, [=] { kickUser(user); })) {
if (!checkInfoLoaded(participant, [=] { kickUser(participant); })) {
return;
}
const auto kickUserSure = crl::guard(this, [=] {
kickUser(user, true);
kickUser(participant, true);
});
// Check restrictions.
if (_additional.adminRights(user).has_value()
|| _additional.isCreator(user)) {
const auto user = participant->asUser();
if (user && (_additional.adminRights(user).has_value()
|| (_additional.isCreator(user)))) {
// The user is an admin or creator.
if (!_additional.isCreator(user) && _additional.canEditAdmin(user)) {
if (!sure) {
@@ -818,37 +833,39 @@ void AddSpecialBoxController::kickUser(
: tr::lng_profile_sure_kick_channel)(
tr::now,
lt_user,
user->name);
participant->name);
_editBox = Ui::show(
Box<ConfirmBox>(text, kickUserSure),
Ui::LayerOption::KeepOther);
return;
}
const auto restrictedRights = _additional.restrictedRights(user);
const auto restrictedRights = _additional.restrictedRights(participant);
const auto currentRights = restrictedRights
? *restrictedRights
: MTPChatBannedRights(MTP_chatBannedRights(
MTP_flags(0),
MTP_int(0)));
: ChannelData::EmptyRestrictedRights(participant);
const auto done = crl::guard(this, [=](
const MTPChatBannedRights &newRights) {
editRestrictedDone(user, newRights);
editRestrictedDone(participant, newRights);
});
const auto fail = crl::guard(this, [=] {
_editBox = nullptr;
});
const auto callback = SaveRestrictedCallback(_peer, user, done, fail);
callback(currentRights, ChannelData::KickedRestrictedRights());
const auto callback = SaveRestrictedCallback(
_peer,
participant,
done,
fail);
callback(currentRights, ChannelData::KickedRestrictedRights(participant));
}
bool AddSpecialBoxController::appendRow(not_null<UserData*> user) {
if (delegate()->peerListFindRow(user->id)
|| (_excludeSelf && user->isSelf())) {
bool AddSpecialBoxController::appendRow(not_null<PeerData*> participant) {
if (delegate()->peerListFindRow(participant->id)
|| (_excludeSelf && participant->isSelf())) {
return false;
}
delegate()->peerListAppendRow(createRow(user));
delegate()->peerListAppendRow(createRow(participant));
return true;
}
@@ -861,8 +878,8 @@ bool AddSpecialBoxController::prependRow(not_null<UserData*> user) {
}
std::unique_ptr<PeerListRow> AddSpecialBoxController::createRow(
not_null<UserData*> user) const {
return std::make_unique<PeerListRow>(user);
not_null<PeerData*> participant) const {
return std::make_unique<PeerListRow>(participant);
}
AddSpecialBoxSearchController::AddSpecialBoxSearchController(
@@ -976,7 +993,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 +1076,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;

View File

@@ -80,7 +80,7 @@ public:
const MTPChatAdminRights &adminRights,
const QString &rank)>;
using BannedDoneCallback = Fn<void(
not_null<UserData*> user,
not_null<PeerData*> participant,
const MTPChatBannedRights &bannedRights)>;
AddSpecialBoxController(
not_null<PeerData*> peer,
@@ -101,7 +101,7 @@ public:
private:
template <typename Callback>
bool checkInfoLoaded(not_null<UserData*> user, Callback callback);
bool checkInfoLoaded(not_null<PeerData*> participant, Callback callback);
void prepareChatRows(not_null<ChatData*> chat);
void rebuildChatRows(not_null<ChatData*> chat);
@@ -113,12 +113,13 @@ private:
const QString &rank);
void showRestricted(not_null<UserData*> user, bool sure = false);
void editRestrictedDone(
not_null<UserData*> user,
not_null<PeerData*> participant,
const MTPChatBannedRights &rights);
void kickUser(not_null<UserData*> user, bool sure = false);
bool appendRow(not_null<UserData*> user);
void kickUser(not_null<PeerData*> participant, bool sure = false);
bool appendRow(not_null<PeerData*> participant);
bool prependRow(not_null<UserData*> user);
std::unique_ptr<PeerListRow> createRow(not_null<UserData*> user) const;
std::unique_ptr<PeerListRow> createRow(
not_null<PeerData*> participant) const;
void subscribeToMigration();
void migrate(not_null<ChatData*> chat, not_null<ChannelData*> channel);

View File

@@ -75,7 +75,7 @@ void SendRequest(
lt_user,
first));
}
}).fail([=](const RPCError &error) {
}).fail([=](const MTP::Error &error) {
}).send();
}

View File

@@ -222,7 +222,8 @@ MTPChatAdminRights EditAdminBox::defaultRights() const {
| Flag::f_post_messages
| Flag::f_edit_messages
| Flag::f_delete_messages
| Flag::f_invite_users);
| Flag::f_invite_users
| Flag::f_manage_call);
return MTP_chatAdminRights(MTP_flags(flags));
}
@@ -444,7 +445,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 +462,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 +534,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;
}
@@ -611,11 +612,11 @@ void EditRestrictedBox::prepare() {
const auto defaultRestrictions = chat
? chat->defaultRestrictions()
: channel->defaultRestrictions();
const auto prepareRights = _oldRights.c_chatBannedRights().vflags().v
const auto prepareRights = Data::ChatBannedRightsFlags(_oldRights)
? _oldRights
: defaultRights();
const auto prepareFlags = FixDependentRestrictions(
prepareRights.c_chatBannedRights().vflags().v
Data::ChatBannedRightsFlags(prepareRights)
| defaultRestrictions
| ((channel && channel->isPublic())
? (Flag::f_change_info | Flag::f_pin_messages)
@@ -646,7 +647,7 @@ void EditRestrictedBox::prepare() {
disabledMessages);
addControl(std::move(checkboxes), QMargins());
_until = prepareRights.c_chatBannedRights().vuntil_date().v;
_until = Data::ChatBannedRightsUntilDate(prepareRights);
addControl(object_ptr<Ui::BoxContentDivider>(this), st::rightsUntilMargin);
addControl(
object_ptr<Ui::FlatLabel>(
@@ -766,7 +767,7 @@ void EditRestrictedBox::createUntilVariants() {
}
};
auto addCurrentVariant = [&](TimeId from, TimeId to) {
auto oldUntil = _oldRights.c_chatBannedRights().vuntil_date().v;
auto oldUntil = Data::ChatBannedRightsUntilDate(_oldRights);
if (oldUntil < _until) {
addCustomVariant(oldUntil, from, to);
}

View File

@@ -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,

View File

@@ -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();
@@ -146,22 +146,22 @@ void SaveChannelAdmin(
void SaveChannelRestriction(
not_null<ChannelData*> channel,
not_null<UserData*> user,
not_null<PeerData*> participant,
const MTPChatBannedRights &oldRights,
const MTPChatBannedRights &newRights,
Fn<void()> onDone,
Fn<void()> onFail) {
channel->session().api().request(MTPchannels_EditBanned(
channel->inputChannel,
user->inputUser,
participant->input,
newRights
)).done([=](const MTPUpdates &result) {
channel->session().api().applyUpdates(result);
channel->applyEditBanned(user, oldRights, newRights);
channel->applyEditBanned(participant, oldRights, newRights);
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();
}
@@ -243,7 +243,7 @@ Fn<void(
const MTPChatBannedRights &oldRights,
const MTPChatBannedRights &newRights)> SaveRestrictedCallback(
not_null<PeerData*> peer,
not_null<UserData*> user,
not_null<PeerData*> participant,
Fn<void(const MTPChatBannedRights &newRights)> onDone,
Fn<void()> onFail) {
return [=](
@@ -253,19 +253,21 @@ Fn<void(
const auto saveForChannel = [=](not_null<ChannelData*> channel) {
SaveChannelRestriction(
channel,
user,
participant,
oldRights,
newRights,
done,
onFail);
};
if (const auto chat = peer->asChatNotMigrated()) {
const auto flags = newRights.match([](
const MTPDchatBannedRights &data) {
return data.vflags().v;
});
if (flags & MTPDchatBannedRights::Flag::f_view_messages) {
SaveChatParticipantKick(chat, user, done, onFail);
const auto flags = Data::ChatBannedRightsFlags(newRights);
if (participant->isUser()
&& (flags & MTPDchatBannedRights::Flag::f_view_messages)) {
SaveChatParticipantKick(
chat,
participant->asUser(),
done,
onFail);
} else if (!flags) {
done();
} else {
@@ -313,9 +315,9 @@ ParticipantsAdditionalData::ParticipantsAdditionalData(
}
bool ParticipantsAdditionalData::infoLoaded(
not_null<UserData*> user) const {
not_null<PeerData*> participant) const {
return _peer->isChat()
|| (_infoNotLoaded.find(user) == end(_infoNotLoaded));
|| (_infoNotLoaded.find(participant) == end(_infoNotLoaded));
}
bool ParticipantsAdditionalData::canEditAdmin(
@@ -342,24 +344,27 @@ bool ParticipantsAdditionalData::canAddOrEditAdmin(
Unexpected("Peer in ParticipantsAdditionalData::canAddOrEditAdmin.");
}
bool ParticipantsAdditionalData::canRestrictUser(
not_null<UserData*> user) const {
if (!canEditAdmin(user) || user->isSelf()) {
bool ParticipantsAdditionalData::canRestrictParticipant(
not_null<PeerData*> participant) const {
const auto user = participant->asUser();
if (user && (!canEditAdmin(user) || user->isSelf())) {
return false;
} else if (const auto chat = _peer->asChat()) {
return chat->canBanMembers();
} else if (const auto channel = _peer->asChannel()) {
return channel->canBanMembers();
}
Unexpected("Peer in ParticipantsAdditionalData::canRestrictUser.");
Unexpected("Peer in ParticipantsAdditionalData::canRestrictParticipant.");
}
bool ParticipantsAdditionalData::canRemoveUser(
not_null<UserData*> user) const {
if (canRestrictUser(user)) {
bool ParticipantsAdditionalData::canRemoveParticipant(
not_null<PeerData*> participant) const {
const auto user = participant->asUser();
if (canRestrictParticipant(participant)) {
return true;
} else if (const auto chat = _peer->asChat()) {
return !user->isSelf()
return user
&& !user->isSelf()
&& chat->invitedByMe.contains(user)
&& (chat->amCreator() || !_admins.contains(user));
}
@@ -388,12 +393,12 @@ QString ParticipantsAdditionalData::adminRank(
}
auto ParticipantsAdditionalData::restrictedRights(
not_null<UserData*> user) const
not_null<PeerData*> participant) const
-> std::optional<MTPChatBannedRights> {
if (_peer->isChat()) {
return std::nullopt;
}
const auto i = _restrictedRights.find(user);
const auto i = _restrictedRights.find(participant);
return (i != end(_restrictedRights))
? std::make_optional(i->second)
: std::nullopt;
@@ -404,16 +409,18 @@ bool ParticipantsAdditionalData::isCreator(not_null<UserData*> user) const {
}
bool ParticipantsAdditionalData::isExternal(
not_null<UserData*> user) const {
not_null<PeerData*> participant) const {
return _peer->isChat()
? !_members.contains(user)
: _external.find(user) != end(_external);
? (participant->isUser()
&& !_members.contains(participant->asUser()))
: _external.find(participant) != end(_external);
}
bool ParticipantsAdditionalData::isKicked(not_null<UserData*> user) const {
bool ParticipantsAdditionalData::isKicked(
not_null<PeerData*> participant) const {
return _peer->isChat()
? false
: _kicked.find(user) != end(_kicked);
: _kicked.find(participant) != end(_kicked);
}
UserData *ParticipantsAdditionalData::adminPromotedBy(
@@ -426,29 +433,41 @@ UserData *ParticipantsAdditionalData::adminPromotedBy(
}
UserData *ParticipantsAdditionalData::restrictedBy(
not_null<UserData*> user) const {
not_null<PeerData*> participant) const {
if (_peer->isChat()) {
return nullptr;
}
const auto i = _restrictedBy.find(user);
const auto i = _restrictedBy.find(participant);
return (i != end(_restrictedBy)) ? i->second.get() : nullptr;
}
void ParticipantsAdditionalData::setExternal(not_null<UserData*> user) {
_infoNotLoaded.erase(user);
_external.emplace(user);
void ParticipantsAdditionalData::setExternal(
not_null<PeerData*> participant) {
if (const auto user = participant->asUser()) {
_adminRights.erase(user);
_adminCanEdit.erase(user);
_adminPromotedBy.erase(user);
_admins.erase(user);
}
_restrictedRights.erase(participant);
_kicked.erase(participant);
_restrictedBy.erase(participant);
_infoNotLoaded.erase(participant);
_external.emplace(participant);
}
void ParticipantsAdditionalData::checkForLoaded(not_null<UserData*> user) {
void ParticipantsAdditionalData::checkForLoaded(
not_null<PeerData*> participant) {
const auto contains = [](const auto &map, const auto &value) {
return map.find(value) != map.end();
};
if (_creator != user
&& !contains(_adminRights, user)
&& !contains(_restrictedRights, user)
&& !contains(_external, user)
&& !contains(_kicked, user)) {
_infoNotLoaded.emplace(user);
const auto user = participant->asUser();
if (!(user && _creator == user)
&& !(user && contains(_adminRights, user))
&& !contains(_restrictedRights, participant)
&& !contains(_external, participant)
&& !contains(_kicked, participant)) {
_infoNotLoaded.emplace(participant);
}
}
@@ -510,15 +529,15 @@ void ParticipantsAdditionalData::fillFromChannel(
}
}
UserData *ParticipantsAdditionalData::applyParticipant(
PeerData *ParticipantsAdditionalData::applyParticipant(
const MTPChannelParticipant &data) {
return applyParticipant(data, _role);
}
UserData *ParticipantsAdditionalData::applyParticipant(
PeerData *ParticipantsAdditionalData::applyParticipant(
const MTPChannelParticipant &data,
Role overrideRole) {
const auto logBad = [&]() -> UserData* {
const auto logBad = [&]() -> PeerData* {
LOG(("API Error: Bad participant type %1 got "
"while requesting for participants, role: %2"
).arg(data.type()
@@ -526,27 +545,28 @@ UserData *ParticipantsAdditionalData::applyParticipant(
return nullptr;
};
return data.match([&](const MTPDchannelParticipantCreator &data) {
return data.match([&](
const MTPDchannelParticipantCreator &data) -> PeerData* {
if (overrideRole != Role::Profile
&& overrideRole != Role::Members
&& overrideRole != Role::Admins) {
return logBad();
}
return applyCreator(data);
}, [&](const MTPDchannelParticipantAdmin &data) {
}, [&](const MTPDchannelParticipantAdmin &data) -> PeerData* {
if (overrideRole != Role::Profile
&& overrideRole != Role::Members
&& overrideRole != Role::Admins) {
return logBad();
}
return applyAdmin(data);
}, [&](const MTPDchannelParticipantSelf &data) {
}, [&](const MTPDchannelParticipantSelf &data) -> PeerData* {
if (overrideRole != Role::Profile
&& overrideRole != Role::Members) {
return logBad();
}
return applyRegular(data.vuser_id());
}, [&](const MTPDchannelParticipant &data) {
}, [&](const MTPDchannelParticipant &data) -> PeerData* {
if (overrideRole != Role::Profile
&& overrideRole != Role::Members) {
return logBad();
@@ -645,32 +665,35 @@ UserData *ParticipantsAdditionalData::applyRegular(MTPint userId) {
return user;
}
UserData *ParticipantsAdditionalData::applyBanned(
PeerData *ParticipantsAdditionalData::applyBanned(
const MTPDchannelParticipantBanned &data) {
const auto user = _peer->owner().userLoaded(data.vuser_id().v);
if (!user) {
const auto participant = _peer->owner().peerLoaded(
peerFromMTP(data.vpeer()));
if (!participant) {
return nullptr;
}
_infoNotLoaded.erase(user);
_adminRights.erase(user);
_adminCanEdit.erase(user);
_adminPromotedBy.erase(user);
if (data.is_left()) {
_kicked.emplace(user);
} else {
_kicked.erase(user);
_infoNotLoaded.erase(participant);
if (const auto user = participant->asUser()) {
_adminRights.erase(user);
_adminCanEdit.erase(user);
_adminPromotedBy.erase(user);
}
_restrictedRights[user] = data.vbanned_rights();
if (data.is_left()) {
_kicked.emplace(participant);
} else {
_kicked.erase(participant);
}
_restrictedRights[participant] = data.vbanned_rights();
if (const auto by = _peer->owner().userLoaded(data.vkicked_by().v)) {
const auto i = _restrictedBy.find(user);
const auto i = _restrictedBy.find(participant);
if (i == _restrictedBy.end()) {
_restrictedBy.emplace(user, by);
_restrictedBy.emplace(participant, by);
} else {
i->second = by;
}
}
return user;
return participant;
}
void ParticipantsAdditionalData::migrate(
@@ -922,9 +945,9 @@ void ParticipantsBoxController::addNewItem() {
editAdminDone(user, rights, rank);
});
const auto restrictedDone = crl::guard(this, [=](
not_null<UserData*> user,
not_null<PeerData*> participant,
const MTPChatBannedRights &rights) {
editRestrictedDone(user, rights);
editRestrictedDone(participant, rights);
});
const auto initBox = [](not_null<PeerListBox*> box) {
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
@@ -955,8 +978,10 @@ void ParticipantsBoxController::addNewParticipants() {
auto already = std::vector<not_null<UserData*>>();
already.reserve(count);
for (auto i = 0; i != count; ++i) {
already.emplace_back(
delegate()->peerListRowAt(i)->peer()->asUser());
const auto participant = delegate()->peerListRowAt(i)->peer();
if (const auto user = participant->asUser()) {
already.emplace_back(user);
}
}
AddParticipantsBoxController::Start(
_navigation,
@@ -1165,6 +1190,7 @@ void ParticipantsBoxController::rebuildChatParticipants(
auto count = delegate()->peerListFullRowsCount();
for (auto i = 0; i != count;) {
auto row = delegate()->peerListRowAt(i);
Assert(row->peer()->isUser());
auto user = row->peer()->asUser();
if (participants.contains(user)) {
++i;
@@ -1196,7 +1222,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);
}
@@ -1316,8 +1342,9 @@ void ParticipantsBoxController::loadMoreRows() {
int availableCount,
const QVector<MTPChannelParticipant> &list) {
for (const auto &data : list) {
if (const auto user = _additional.applyParticipant(data)) {
appendRow(user);
if (const auto participant = _additional.applyParticipant(
data)) {
appendRow(participant);
}
}
if (const auto size = list.size()) {
@@ -1336,7 +1363,7 @@ void ParticipantsBoxController::loadMoreRows() {
_onlineSorter->sort();
}
delegate()->peerListRefreshRows();
}).fail([this](const RPCError &error) {
}).fail([this](const MTP::Error &error) {
_loadRequestId = 0;
}).send();
}
@@ -1398,31 +1425,32 @@ bool ParticipantsBoxController::feedMegagroupLastParticipants() {
}
void ParticipantsBoxController::rowClicked(not_null<PeerListRow*> row) {
Expects(row->peer()->isUser());
const auto user = row->peer()->asUser();
const auto participant = row->peer();
const auto user = participant->asUser();
if (_role == Role::Admins) {
Assert(user != nullptr);
showAdmin(user);
} else if (_role == Role::Restricted
&& (_peer->isChat() || _peer->isMegagroup())) {
&& (_peer->isChat() || _peer->isMegagroup())
&& user) {
showRestricted(user);
} else {
Assert(_navigation != nullptr);
_navigation->showPeerInfo(user);
_navigation->showPeerInfo(participant);
}
}
void ParticipantsBoxController::rowActionClicked(
not_null<PeerListRow*> row) {
Expects(row->peer()->isUser());
const auto user = row->peer()->asUser();
const auto participant = row->peer();
const auto user = participant->asUser();
if (_role == Role::Members || _role == Role::Profile) {
kickMember(user);
kickParticipant(participant);
} else if (_role == Role::Admins) {
Assert(user != nullptr);
removeAdmin(user);
} else {
removeKicked(row, user);
removeKicked(row, participant);
}
}
@@ -1433,28 +1461,30 @@ base::unique_qptr<Ui::PopupMenu> ParticipantsBoxController::rowContextMenu(
const auto chat = _peer->asChat();
const auto channel = _peer->asChannel();
const auto user = row->peer()->asUser();
const auto participant = row->peer();
const auto user = participant->asUser();
auto result = base::make_unique_q<Ui::PopupMenu>(parent);
if (_navigation) {
result->addAction(
tr::lng_context_view_profile(tr::now),
crl::guard(this, [=] { _navigation->showPeerInfo(user); }));
crl::guard(this, [=] {
_navigation->showPeerInfo(participant); }));
}
if (_role == Role::Kicked) {
if (_peer->isMegagroup()
&& _additional.canRestrictUser(user)) {
if (channel->canAddMembers()) {
&& _additional.canRestrictParticipant(participant)) {
if (user && channel->canAddMembers()) {
result->addAction(
tr::lng_context_add_to_group(tr::now),
crl::guard(this, [=] { unkickMember(user); }));
crl::guard(this, [=] { unkickParticipant(user); }));
}
result->addAction(
tr::lng_profile_delete_removed(tr::now),
crl::guard(this, [=] { removeKickedWithRow(user); }));
crl::guard(this, [=] { removeKickedWithRow(participant); }));
}
return result;
}
if (_additional.canAddOrEditAdmin(user)) {
if (user && _additional.canAddOrEditAdmin(user)) {
const auto isAdmin = _additional.isCreator(user)
|| _additional.adminRights(user).has_value();
result->addAction(
@@ -1463,7 +1493,7 @@ base::unique_qptr<Ui::PopupMenu> ParticipantsBoxController::rowContextMenu(
: tr::lng_context_promote_admin)(tr::now),
crl::guard(this, [=] { showAdmin(user); }));
}
if (_additional.canRestrictUser(user)) {
if (_additional.canRestrictParticipant(participant)) {
const auto canRestrictWithoutKick = [&] {
if (const auto chat = _peer->asChat()) {
return chat->amCreator();
@@ -1476,14 +1506,14 @@ base::unique_qptr<Ui::PopupMenu> ParticipantsBoxController::rowContextMenu(
crl::guard(this, [=] { showRestricted(user); }));
}
}
if (_additional.canRemoveUser(user)) {
if (!_additional.isKicked(user)) {
if (_additional.canRemoveParticipant(participant)) {
if (!_additional.isKicked(participant)) {
const auto isGroup = _peer->isChat() || _peer->isMegagroup();
result->addAction(
(isGroup
? tr::lng_context_remove_from_group
: tr::lng_profile_kick)(tr::now),
crl::guard(this, [=] { kickMember(user); }));
crl::guard(this, [=] { kickParticipant(user); }));
}
}
return result;
@@ -1569,9 +1599,7 @@ void ParticipantsBoxController::showRestricted(not_null<UserData*> user) {
const auto restrictedRights = _additional.restrictedRights(user);
const auto currentRights = restrictedRights
? *restrictedRights
: MTPChatBannedRights(MTP_chatBannedRights(
MTP_flags(0),
MTP_int(0)));
: ChannelData::EmptyRestrictedRights(user);
const auto hasAdminRights = _additional.adminRights(user).has_value();
auto box = Box<EditRestrictedBox>(
_peer,
@@ -1580,7 +1608,7 @@ void ParticipantsBoxController::showRestricted(not_null<UserData*> user) {
currentRights);
const auto chat = _peer->asChat();
const auto channel = _peer->asChannel();
if (_additional.canRestrictUser(user)) {
if (_additional.canRestrictParticipant(user)) {
const auto done = crl::guard(this, [=](
const MTPChatBannedRights &newRights) {
editRestrictedDone(user, newRights);
@@ -1597,72 +1625,84 @@ void ParticipantsBoxController::showRestricted(not_null<UserData*> user) {
}
void ParticipantsBoxController::editRestrictedDone(
not_null<UserData*> user,
not_null<PeerData*> participant,
const MTPChatBannedRights &rights) {
_addBox = nullptr;
if (_editParticipantBox) {
_editParticipantBox->closeBox();
}
const auto user = participant->asUser();
const auto date = base::unixtime::now(); // Incorrect, but ignored.
if (rights.c_chatBannedRights().vflags().v == 0) {
_additional.applyParticipant(MTP_channelParticipant(
MTP_int(user->bareId()),
MTP_int(date)));
if (Data::ChatBannedRightsFlags(rights) == 0) {
if (user) {
_additional.applyParticipant(MTP_channelParticipant(
MTP_int(user->bareId()),
MTP_int(date)));
} else {
_additional.setExternal(participant);
}
if (_role == Role::Kicked || _role == Role::Restricted) {
removeRow(user);
removeRow(participant);
}
} else {
const auto kicked = rights.c_chatBannedRights().is_view_messages();
const auto alreadyRestrictedBy = _additional.restrictedBy(user);
const auto kicked = Data::ChatBannedRightsFlags(rights)
& ChatRestriction::f_view_messages;
const auto alreadyRestrictedBy = _additional.restrictedBy(
participant);
_additional.applyParticipant(MTP_channelParticipantBanned(
MTP_flags(kicked
? MTPDchannelParticipantBanned::Flag::f_left
: MTPDchannelParticipantBanned::Flag(0)),
MTP_int(user->bareId()),
(participant->isUser()
? MTP_peerUser(MTP_int(participant->bareId()))
: participant->isChat()
? MTP_peerChat(MTP_int(participant->bareId()))
: MTP_peerChannel(MTP_int(participant->bareId()))),
MTP_int(alreadyRestrictedBy
? alreadyRestrictedBy->bareId()
: user->session().userId()),
: participant->session().userId()),
MTP_int(date),
rights));
if (kicked) {
if (_role == Role::Kicked) {
prependRow(user);
prependRow(participant);
} else if (_role == Role::Admins
|| _role == Role::Restricted
|| _role == Role::Members) {
removeRow(user);
removeRow(participant);
}
} else {
if (_role == Role::Restricted) {
prependRow(user);
prependRow(participant);
} else if (_role == Role::Kicked
|| _role == Role::Admins
|| _role == Role::Members) {
removeRow(user);
removeRow(participant);
}
}
}
recomputeTypeFor(user);
recomputeTypeFor(participant);
delegate()->peerListRefreshRows();
}
void ParticipantsBoxController::kickMember(not_null<UserData*> user) {
void ParticipantsBoxController::kickParticipant(not_null<PeerData*> participant) {
const auto user = participant->asUser();
const auto text = ((_peer->isChat() || _peer->isMegagroup())
? tr::lng_profile_sure_kick
: tr::lng_profile_sure_kick_channel)(
tr::now,
lt_user,
user->firstName);
user ? user->firstName : participant->name);
_editBox = Ui::show(
Box<ConfirmBox>(
text,
tr::lng_box_remove(tr::now),
crl::guard(this, [=] { kickMemberSure(user); })),
crl::guard(this, [=] { kickParticipantSure(participant); })),
Ui::LayerOption::KeepOther);
}
void ParticipantsBoxController::unkickMember(not_null<UserData*> user) {
void ParticipantsBoxController::unkickParticipant(not_null<UserData*> user) {
_editBox = nullptr;
if (const auto row = delegate()->peerListFindRow(user->id)) {
delegate()->peerListRemoveRow(row);
@@ -1671,25 +1711,24 @@ void ParticipantsBoxController::unkickMember(not_null<UserData*> user) {
_peer->session().api().addChatParticipants(_peer, { 1, user });
}
void ParticipantsBoxController::kickMemberSure(not_null<UserData*> user) {
void ParticipantsBoxController::kickParticipantSure(
not_null<PeerData*> participant) {
_editBox = nullptr;
const auto restrictedRights = _additional.restrictedRights(user);
const auto restrictedRights = _additional.restrictedRights(participant);
const auto currentRights = restrictedRights
? *restrictedRights
: MTPChatBannedRights(MTP_chatBannedRights(
MTP_flags(0),
MTP_int(0)));
: ChannelData::EmptyRestrictedRights(participant);
if (const auto row = delegate()->peerListFindRow(user->id)) {
if (const auto row = delegate()->peerListFindRow(participant->id)) {
delegate()->peerListRemoveRow(row);
delegate()->peerListRefreshRows();
}
auto &session = _peer->session();
if (const auto chat = _peer->asChat()) {
session.api().kickParticipant(chat, user);
session.api().kickParticipant(chat, participant);
} else if (const auto channel = _peer->asChannel()) {
session.api().kickParticipant(channel, user, currentRights);
session.api().kickParticipant(channel, participant, currentRights);
}
}
@@ -1730,36 +1769,37 @@ void ParticipantsBoxController::removeAdminSure(not_null<UserData*> user) {
}
void ParticipantsBoxController::removeKickedWithRow(
not_null<UserData*> user) {
if (const auto row = delegate()->peerListFindRow(user->id)) {
removeKicked(row, user);
not_null<PeerData*> participant) {
if (const auto row = delegate()->peerListFindRow(participant->id)) {
removeKicked(row, participant);
} else {
removeKicked(user);
removeKicked(participant);
}
}
void ParticipantsBoxController::removeKicked(not_null<UserData*> user) {
void ParticipantsBoxController::removeKicked(
not_null<PeerData*> participant) {
if (const auto channel = _peer->asChannel()) {
channel->session().api().unblockParticipant(channel, user);
channel->session().api().unblockParticipant(channel, participant);
}
}
void ParticipantsBoxController::removeKicked(
not_null<PeerListRow*> row,
not_null<UserData*> user) {
not_null<PeerData*> participant) {
delegate()->peerListRemoveRow(row);
if (_role != Role::Kicked
&& !delegate()->peerListFullRowsCount()) {
setDescriptionText(tr::lng_blocked_list_not_found(tr::now));
}
delegate()->peerListRefreshRows();
removeKicked(user);
removeKicked(participant);
}
bool ParticipantsBoxController::appendRow(not_null<UserData*> user) {
if (delegate()->peerListFindRow(user->id)) {
recomputeTypeFor(user);
bool ParticipantsBoxController::appendRow(not_null<PeerData*> participant) {
if (delegate()->peerListFindRow(participant->id)) {
recomputeTypeFor(participant);
return false;
} else if (auto row = createRow(user)) {
} else if (auto row = createRow(participant)) {
delegate()->peerListAppendRow(std::move(row));
if (_role != Role::Kicked) {
setDescriptionText(QString());
@@ -1769,16 +1809,16 @@ bool ParticipantsBoxController::appendRow(not_null<UserData*> user) {
return false;
}
bool ParticipantsBoxController::prependRow(not_null<UserData*> user) {
if (const auto row = delegate()->peerListFindRow(user->id)) {
recomputeTypeFor(user);
bool ParticipantsBoxController::prependRow(not_null<PeerData*> participant) {
if (const auto row = delegate()->peerListFindRow(participant->id)) {
recomputeTypeFor(participant);
refreshCustomStatus(row);
if (_role == Role::Admins) {
// Perhaps we've added a new admin from search.
delegate()->peerListPrependRowFromSearchResult(row);
}
return false;
} else if (auto row = createRow(user)) {
} else if (auto row = createRow(participant)) {
delegate()->peerListPrependRow(std::move(row));
if (_role != Role::Kicked) {
setDescriptionText(QString());
@@ -1788,8 +1828,8 @@ bool ParticipantsBoxController::prependRow(not_null<UserData*> user) {
return false;
}
bool ParticipantsBoxController::removeRow(not_null<UserData*> user) {
if (auto row = delegate()->peerListFindRow(user->id)) {
bool ParticipantsBoxController::removeRow(not_null<PeerData*> participant) {
if (auto row = delegate()->peerListFindRow(participant->id)) {
if (_role == Role::Admins) {
// Perhaps we are removing an admin from search results.
row->setCustomStatus(tr::lng_channel_admin_status_not_admin(tr::now));
@@ -1807,24 +1847,28 @@ bool ParticipantsBoxController::removeRow(not_null<UserData*> user) {
}
std::unique_ptr<PeerListRow> ParticipantsBoxController::createRow(
not_null<UserData*> user) const {
not_null<PeerData*> participant) const {
const auto user = participant->asUser();
if (_role == Role::Profile) {
Assert(user != nullptr);
return std::make_unique<Row>(user, computeType(user));
}
const auto chat = _peer->asChat();
const auto channel = _peer->asChannel();
auto row = std::make_unique<PeerListRowWithLink>(user);
auto row = std::make_unique<PeerListRowWithLink>(participant);
refreshCustomStatus(row.get());
if (_role == Role::Admins
&& user
&& !_additional.isCreator(user)
&& _additional.adminRights(user).has_value()
&& _additional.canEditAdmin(user)) {
row->setActionLink(tr::lng_profile_kick(tr::now));
} else if (_role == Role::Kicked || _role == Role::Restricted) {
if (_additional.canRestrictUser(user)) {
if (_additional.canRestrictParticipant(participant)) {
row->setActionLink(tr::lng_profile_delete_removed(tr::now));
}
} else if (_role == Role::Members) {
Assert(user != nullptr);
if ((chat ? chat->canBanMembers() : channel->canBanMembers())
&& !_additional.isCreator(user)
&& (!_additional.adminRights(user)
@@ -1842,31 +1886,34 @@ std::unique_ptr<PeerListRow> ParticipantsBoxController::createRow(
}
auto ParticipantsBoxController::computeType(
not_null<UserData*> user) const -> Type {
not_null<PeerData*> participant) const -> Type {
const auto user = participant->asUser();
auto result = Type();
result.rights = _additional.isCreator(user)
result.rights = (user && _additional.isCreator(user))
? Rights::Creator
: _additional.adminRights(user).has_value()
: (user && _additional.adminRights(user).has_value())
? Rights::Admin
: Rights::Normal;
result.canRemove = _additional.canRemoveUser(user);
result.canRemove = _additional.canRemoveParticipant(participant);
return result;
}
void ParticipantsBoxController::recomputeTypeFor(
not_null<UserData*> user) {
not_null<PeerData*> participant) {
if (_role != Role::Profile) {
return;
}
if (const auto row = delegate()->peerListFindRow(user->id)) {
static_cast<Row*>(row)->setType(computeType(user));
if (const auto row = delegate()->peerListFindRow(participant->id)) {
static_cast<Row*>(row)->setType(computeType(participant));
}
}
void ParticipantsBoxController::refreshCustomStatus(
not_null<PeerListRow*> row) const {
const auto user = row->peer()->asUser();
const auto participant = row->peer();
const auto user = participant->asUser();
if (_role == Role::Admins) {
Assert(user != nullptr);
if (const auto by = _additional.adminPromotedBy(user)) {
row->setCustomStatus(tr::lng_channel_admin_status_promoted_by(
tr::now,
@@ -1882,7 +1929,7 @@ void ParticipantsBoxController::refreshCustomStatus(
}
}
} else if (_role == Role::Kicked || _role == Role::Restricted) {
const auto by = _additional.restrictedBy(user);
const auto by = _additional.restrictedBy(participant);
row->setCustomStatus((_role == Role::Kicked
? tr::lng_channel_banned_status_removed_by
: tr::lng_channel_banned_status_restricted_by)(
@@ -2071,7 +2118,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;

View File

@@ -33,7 +33,7 @@ Fn<void(
const MTPChatBannedRights &oldRights,
const MTPChatBannedRights &newRights)> SaveRestrictedCallback(
not_null<PeerData*> peer,
not_null<UserData*> user,
not_null<PeerData*> participant,
Fn<void(const MTPChatBannedRights &newRights)> onDone,
Fn<void()> onFail);
@@ -77,29 +77,31 @@ public:
ParticipantsAdditionalData(not_null<PeerData*> peer, Role role);
UserData *applyParticipant(const MTPChannelParticipant &data);
UserData *applyParticipant(
PeerData *applyParticipant(const MTPChannelParticipant &data);
PeerData *applyParticipant(
const MTPChannelParticipant &data,
Role overrideRole);
void setExternal(not_null<UserData*> user);
void checkForLoaded(not_null<UserData*> user);
void setExternal(not_null<PeerData*> participant);
void checkForLoaded(not_null<PeerData*> participant);
void fillFromPeer();
[[nodiscard]] bool infoLoaded(not_null<UserData*> user) const;
[[nodiscard]] bool infoLoaded(not_null<PeerData*> participant) const;
[[nodiscard]] bool canEditAdmin(not_null<UserData*> user) const;
[[nodiscard]] bool canAddOrEditAdmin(not_null<UserData*> user) const;
[[nodiscard]] bool canRestrictUser(not_null<UserData*> user) const;
[[nodiscard]] bool canRemoveUser(not_null<UserData*> user) const;
[[nodiscard]] bool canRestrictParticipant(
not_null<PeerData*> participant) const;
[[nodiscard]] bool canRemoveParticipant(
not_null<PeerData*> participant) const;
[[nodiscard]] std::optional<MTPChatAdminRights> adminRights(
not_null<UserData*> user) const;
QString adminRank(not_null<UserData*> user) const;
[[nodiscard]] std::optional<MTPChatBannedRights> restrictedRights(
not_null<UserData*> user) const;
not_null<PeerData*> participant) const;
[[nodiscard]] bool isCreator(not_null<UserData*> user) const;
[[nodiscard]] bool isExternal(not_null<UserData*> user) const;
[[nodiscard]] bool isKicked(not_null<UserData*> user) const;
[[nodiscard]] bool isExternal(not_null<PeerData*> participant) const;
[[nodiscard]] bool isKicked(not_null<PeerData*> participant) const;
[[nodiscard]] UserData *adminPromotedBy(not_null<UserData*> user) const;
[[nodiscard]] UserData *restrictedBy(not_null<UserData*> user) const;
[[nodiscard]] UserData *restrictedBy(not_null<PeerData*> participant) const;
void migrate(not_null<ChatData*> chat, not_null<ChannelData*> channel);
@@ -107,7 +109,7 @@ private:
UserData *applyCreator(const MTPDchannelParticipantCreator &data);
UserData *applyAdmin(const MTPDchannelParticipantAdmin &data);
UserData *applyRegular(MTPint userId);
UserData *applyBanned(const MTPDchannelParticipantBanned &data);
PeerData *applyBanned(const MTPDchannelParticipantBanned &data);
void fillFromChat(not_null<ChatData*> chat);
void fillFromChannel(not_null<ChannelData*> channel);
@@ -124,11 +126,11 @@ private:
base::flat_map<not_null<UserData*>, QString> _adminRanks;
base::flat_set<not_null<UserData*>> _adminCanEdit;
base::flat_map<not_null<UserData*>, not_null<UserData*>> _adminPromotedBy;
std::map<not_null<UserData*>, MTPChatBannedRights> _restrictedRights;
std::set<not_null<UserData*>> _kicked;
std::map<not_null<UserData*>, not_null<UserData*>> _restrictedBy;
std::set<not_null<UserData*>> _external;
std::set<not_null<UserData*>> _infoNotLoaded;
std::map<not_null<PeerData*>, MTPChatBannedRights> _restrictedRights;
std::set<not_null<PeerData*>> _kicked;
std::map<not_null<PeerData*>, not_null<UserData*>> _restrictedBy;
std::set<not_null<PeerData*>> _external;
std::set<not_null<PeerData*>> _infoNotLoaded;
};
@@ -181,7 +183,7 @@ protected:
Role role);
virtual std::unique_ptr<PeerListRow> createRow(
not_null<UserData*> user) const;
not_null<PeerData*> participant) const;
private:
using Row = Info::Profile::MemberListRow;
@@ -223,23 +225,25 @@ private:
const QString &rank);
void showRestricted(not_null<UserData*> user);
void editRestrictedDone(
not_null<UserData*> user,
not_null<PeerData*> participant,
const MTPChatBannedRights &rights);
void removeKicked(not_null<PeerListRow*> row, not_null<UserData*> user);
void removeKickedWithRow(not_null<UserData*> user);
void removeKicked(not_null<UserData*> user);
void kickMember(not_null<UserData*> user);
void kickMemberSure(not_null<UserData*> user);
void unkickMember(not_null<UserData*> user);
void removeKicked(
not_null<PeerListRow*> row,
not_null<PeerData*> participant);
void removeKickedWithRow(not_null<PeerData*> participant);
void removeKicked(not_null<PeerData*> participant);
void kickParticipant(not_null<PeerData*> participant);
void kickParticipantSure(not_null<PeerData*> participant);
void unkickParticipant(not_null<UserData*> user);
void removeAdmin(not_null<UserData*> user);
void removeAdminSure(not_null<UserData*> user);
bool appendRow(not_null<UserData*> user);
bool prependRow(not_null<UserData*> user);
bool removeRow(not_null<UserData*> user);
bool appendRow(not_null<PeerData*> participant);
bool prependRow(not_null<PeerData*> participant);
bool removeRow(not_null<PeerData*> participant);
void refreshCustomStatus(not_null<PeerListRow*> row) const;
bool feedMegagroupLastParticipants();
Type computeType(not_null<UserData*> user) const;
void recomputeTypeFor(not_null<UserData*> user);
Type computeType(not_null<PeerData*> participant) const;
void recomputeTypeFor(not_null<PeerData*> participant);
void subscribeToMigration();
void migrate(not_null<ChatData*> chat, not_null<ChannelData*> channel);

View File

@@ -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)));
// }

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -151,6 +151,7 @@ std::vector<std::pair<ChatAdminRights, QString>> AdminRightLabels(
{ Flag::f_edit_messages, tr::lng_rights_channel_edit(tr::now) },
{ Flag::f_delete_messages, tr::lng_rights_channel_delete(tr::now) },
{ Flag::f_invite_users, tr::lng_rights_group_invite(tr::now) },
{ Flag::f_manage_call, tr::lng_rights_group_manage_calls(tr::now) },
{ Flag::f_add_admins, tr::lng_rights_add_admins(tr::now) }
};
}
@@ -327,7 +328,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();
};

View File

@@ -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;

View File

@@ -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() {

View File

@@ -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(),

View File

@@ -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));

View File

@@ -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 &&copyCallback,
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);
}

View File

@@ -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 &&copyCallback,
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;

View File

@@ -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,

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();
}

View File

@@ -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,

View File

@@ -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")) {

View File

@@ -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();

View File

@@ -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 }};

View File

@@ -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();
}

View File

@@ -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")) {

View File

@@ -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,

View File

@@ -0,0 +1,342 @@
/*
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(); });
}
[[nodiscard]] TextWithEntities CreateOrJoinConfirmation(
not_null<PeerData*> peer,
ChooseJoinAsProcess::Context context,
bool joinAsAlreadyUsed) {
const auto existing = peer->groupCall();
if (!existing) {
return { peer->isBroadcast()
? tr::lng_group_call_create_sure_channel(tr::now)
: tr::lng_group_call_create_sure(tr::now) };
}
const auto channel = peer->asChannel();
const auto anonymouseAdmin = channel
&& ((channel->isMegagroup() && channel->amAnonymous())
|| (channel->isBroadcast()
&& (channel->amCreator()
|| channel->hasAdminRights())));
if (anonymouseAdmin && !joinAsAlreadyUsed) {
return { tr::lng_group_call_join_sure_personal(tr::now) };
} else if (context != ChooseJoinAsProcess::Context::JoinWithConfirm) {
return {};
}
const auto name = !existing->title().isEmpty()
? existing->title()
: peer->name;
return tr::lng_group_call_join_confirm(
tr::now,
lt_chat,
Ui::Text::Bold(name),
Ui::Text::WithEntities);
}
} // 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);
// We already joined this voice chat, just rejoin with the same.
const auto byAlreadyUsed = selectedId
&& (info.joinAs->id == selectedId)
&& (peer->groupCall() != nullptr);
if (!changingJoinAsFrom && (onlyByMe || byAlreadyUsed)) {
const auto confirmation = CreateOrJoinConfirmation(
peer,
context,
byAlreadyUsed);
if (confirmation.text.isEmpty()) {
finish(info);
return;
}
auto box = Box<::ConfirmBox>(
confirmation,
(peer->groupCall()
? tr::lng_group_call_join(tr::now)
: tr::lng_create_group_create(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

Some files were not shown because too many files have changed in this diff Show More