Compare commits

...

248 Commits

Author SHA1 Message Date
John Preston
f887bf3b6a Beta version 2.1.17.
- Fix messages editing in a non-active account.
- Fix large animated emoji messages editing.
- Fix high definition GIF animations opening in media viewer.
- Multiple crash fixes.
2020-07-02 22:11:53 +04:00
John Preston
dfa4a9990d Show accounts in main menu when added. 2020-07-02 22:11:45 +04:00
John Preston
7f55fd2cad Use a safer way to load system libraries. 2020-07-02 21:01:25 +04:00
John Preston
822c0434e8 Fix editing animated emoji messages. 2020-07-02 14:44:12 +04:00
John Preston
76596f42c7 Open too large GIFs in fullscreen viewer. 2020-07-02 13:43:39 +04:00
John Preston
f2577265ee Refresh main message view for inactive accounts. 2020-07-02 13:35:07 +04:00
John Preston
895c65d518 Fix visual glitch on profile opening. 2020-07-02 12:15:21 +04:00
Ilya Fedin
d8cc7a9b50 Pass Qt::Edges to updateCursor and startResize 2020-07-02 11:33:58 +04:00
Sean Wei
212944d89c Fix format 2020-07-02 11:32:17 +04:00
Ilya Fedin
2b5df331bd Install Qt log handler 2020-07-02 11:31:51 +04:00
Ilya Fedin
7ebebc2bc3 Detect OpenAL effects at runtime 2020-07-02 11:30:13 +04:00
John Preston
120ce27894 Fix possible crash in global search requests. 2020-07-02 11:13:50 +04:00
John Preston
17312a1eec Fix possible crash in intro widget. 2020-07-02 10:42:09 +04:00
John Preston
f1b4a82015 Fix crash in password submit. 2020-07-02 10:25:12 +04:00
John Preston
a6c76382e3 Fix possible crash in top bar widget init. 2020-07-02 10:10:09 +04:00
John Preston
370ad0aa44 Fix critical memory leak on macOS. 2020-07-01 22:34:42 +04:00
John Preston
b1554782fb Add one more moderate hotkey. 2020-07-01 22:33:19 +04:00
John Preston
90c6ff3e41 Fix Settings layout. 2020-07-01 22:33:13 +04:00
John Preston
432ce4caa4 Fix crash in migration with corrupted settings. 2020-07-01 14:16:36 +04:00
John Preston
eb1845e33b Fix crash in session destruction.
Also use rpl::event_stream for downloaderTaskFinished.
2020-07-01 12:26:29 +04:00
John Preston
0981335ca7 Beta version 2.1.16.
- Crash fix.
2020-07-01 00:42:21 +04:00
John Preston
1a69627102 Fix crash in reading saved peers. 2020-07-01 00:41:21 +04:00
Nicholas Guriev
3c0694280f Fix -Wredundant-move 2020-07-01 00:17:05 +04:00
John Preston
e050055c1e Beta version 2.1.15.
- Receive notifications only from the active account
in Settings > Notifications.
- Fix saving chats list width between application relaunches.
- Multiple crash fixes.
2020-06-30 22:17:36 +04:00
Ilya Fedin
e7c598e533 Reset cursor on window leave 2020-06-30 22:14:15 +04:00
Ilya Fedin
dd76d54aeb Fix build with TDESKTOP_DISABLE_GTK_INTEGRATION 2020-06-30 22:13:36 +04:00
John Preston
1dc31c7f2f Allow turning off inactive accounts notifications. 2020-06-30 22:11:54 +04:00
John Preston
5cc7c2b6c6 Add account from settings three-dot menu. 2020-06-30 21:16:05 +04:00
John Preston
dd0e0a10cd Add Activate/Logout context menu in accounts list. 2020-06-30 21:15:35 +04:00
John Preston
9fb12b6093 Set correct username to crash annotations. 2020-06-30 20:41:25 +04:00
John Preston
5ea5d3c60d Fix empty web page preview removing. 2020-06-30 20:22:47 +04:00
John Preston
20ea3af2f0 Fix crash in edited and replied message destruction. 2020-06-30 20:01:17 +04:00
John Preston
41f2cc6d81 Fix crash in notifications clearing. 2020-06-30 19:33:22 +04:00
John Preston
d529c60081 Fix crash in MainMenu hiding on external logout. 2020-06-30 19:13:57 +04:00
John Preston
7d0eb3ba8e Fix crash in MainWidget setup with audio player. 2020-06-30 19:05:12 +04:00
John Preston
3c028590b1 Fix crash in StickersListWidget. 2020-06-30 19:04:52 +04:00
John Preston
47c8b852b8 Fix possible crash in Dialogs::Widget. 2020-06-30 18:34:38 +04:00
John Preston
c15019dee6 Fix crashes in MainWidget and ApiWrap. 2020-06-30 18:26:44 +04:00
John Preston
09aff23ac9 Fix crashes in HistoryWidget. 2020-06-30 18:14:05 +04:00
John Preston
b7707a8a89 Fix event loop tracking crash. 2020-06-30 17:41:58 +04:00
John Preston
10ced19841 Fix crash in redundant checkStartUrl call. 2020-06-30 17:23:21 +04:00
John Preston
2ef47222f4 Fix crash in update online on logout. 2020-06-30 17:17:07 +04:00
John Preston
a95b756111 Fix settings saving.
Regression was introduced in 5d6a494934.

Fixes #8168.
2020-06-30 13:49:22 +04:00
23rd
d2615dda63 Updated Github Actions Cache version. 2020-06-30 12:28:13 +03:00
John Preston
e6f3cd1d56 Refresh appconfig after login. 2020-06-30 13:01:59 +04:00
John Preston
5d32ba5867 Accept IPv4:port in proxy host input field. 2020-06-30 12:56:06 +04:00
John Preston
4b1e9e3b9d Fix proxies list box. 2020-06-30 12:25:06 +04:00
John Preston
06c9e55c26 Fix notification receiver name. 2020-06-30 12:03:42 +04:00
John Preston
613a2f358a Fix clearing session notifications. 2020-06-30 11:52:59 +04:00
John Preston
c3fa300b5c Create notifications manager after reading settings. 2020-06-30 11:44:32 +04:00
John Preston
0db6fc4ffb Toggle accounts by userpic in Main Menu. 2020-06-30 11:34:02 +04:00
John Preston
9211b4d421 Remove duplicate accounts toggle subscription. 2020-06-30 11:31:52 +04:00
John Preston
ab33af3f73 Save preloaded filters info. 2020-06-30 11:18:35 +04:00
John Preston
dfc1712043 Fix loading locally stored self data. 2020-06-30 11:16:47 +04:00
John Preston
87eaab15b5 Load filters before creating session on log in. 2020-06-30 11:02:44 +04:00
Ilya Fedin
90af3d295b Always fallback to gtk icon theme
To inherit icon theme even on WM-based environments
2020-06-30 10:23:07 +04:00
John Preston
107dea085c Fix build for OS X 10.10-10.11. 2020-06-30 00:05:27 +04:00
John Preston
a9eedf0024 Beta version 2.1.14: Fix nearest dc resolve. 2020-06-29 22:25:36 +04:00
John Preston
db435aa9b1 Fix language switch in not-authed window. 2020-06-29 22:25:35 +04:00
John Preston
711fcc2e11 Remove change language link for secondary account. 2020-06-29 22:25:35 +04:00
John Preston
90f7f482ee Take main DC and phone prefix from active account. 2020-06-29 22:14:24 +04:00
John Preston
eff340deaf Fix touchbar destruction with Window. 2020-06-29 22:12:40 +04:00
John Preston
a8d0b80baa Beta version 2.1.14.
- Support for multiple accounts.
2020-06-29 21:51:06 +04:00
John Preston
c777f51427 Fix new settings saving. 2020-06-29 21:49:58 +04:00
John Preston
1a07a388d0 Build window_title_qt only on Linux. 2020-06-29 21:37:56 +04:00
John Preston
cbad993bba Fix app start without data. 2020-06-29 21:37:56 +04:00
John Preston
40971d6da6 Fix quit-by-closing non-authed window. 2020-06-29 21:37:56 +04:00
John Preston
52eef22273 Fix build. 2020-06-29 21:37:55 +04:00
John Preston
44e81269a3 Fix assertion violation in event loop tracking. 2020-06-29 21:29:20 +04:00
Ilya Fedin
0ede4bba72 Unity doesn't support _NET_WM_MOVERESIZE 2020-06-29 19:17:06 +04:00
Ilya Fedin
5e8e654324 Add cross-platform TitleWidget implementation based on startSystemMove/startSystemResize 2020-06-29 17:04:05 +04:00
Ilya Fedin
916601a52c Don't request IsStatusNotifierHostRegistered when SNI become available
To avoid situations when StatusNotifierItem registers icon, but tdesktop assumes that there are still no SNI
2020-06-29 16:58:00 +04:00
Ilya Fedin
a726c6411b Don't use custom notificaions on Wayland even with TDESKTOP_DISABLE_DBUS_INTEGRATION 2020-06-29 16:53:50 +04:00
John Preston
a33c9479a5 Revert pausing in processQueuedPackets. 2020-06-29 16:44:48 +04:00
Ilya Fedin
73b0153a66 Use startSystemMove in export window 2020-06-29 16:44:02 +04:00
Ilya Fedin
bb8f9a1b7f Link to gtk3 without QLibrary if DESKTOP_APP_USE_PACKAGED is defined 2020-06-29 16:27:45 +04:00
Ilya Fedin
4922768086 Don't use QLibrary for glib 2020-06-29 16:27:45 +04:00
Ilya Fedin
806f2e0b50 Check for all needed gtk functions for gtk clipboard 2020-06-29 16:27:45 +04:00
Ilya Fedin
d319c85c57 Don't load another gtk version if gtk_init_check was called 2020-06-29 16:27:45 +04:00
Magnus Groß
f697abe9a1 Do not open non-images as image
QImageReader might report PDF as a viable image type, if Qt is
dynamically linked and QtWebEngine is installed.

Fixed by additionally checking the mime type.

Fixes #8102
2020-06-29 16:22:15 +04:00
RadRussianRus
ae31bdcd1b Fix patches revision 2020-06-29 16:20:01 +04:00
Ilya Fedin
aaf71b34b5 Find alsa and pulse for libtgvoip 2020-06-29 16:18:47 +04:00
John Preston
5f9dae1b72 Run main menu hide animation on account switch. 2020-06-29 16:11:38 +04:00
John Preston
1757dd856b Fix 125% scale active account check. 2020-06-29 15:07:42 +04:00
John Preston
5689154ec5 Clear MessageUpdate changes on item destruction. 2020-06-29 13:23:51 +04:00
John Preston
57249c6ea0 Fix a case of huge memory consumption in streaming. 2020-06-29 12:42:56 +04:00
John Preston
1bd0b03e8e Return Saved Messages button to the main menu. 2020-06-29 09:55:19 +04:00
23rd
0227b5f2fa Removed Notify::inlineKeyboardMoved as completely unused code. 2020-06-29 06:26:09 +04:00
23rd
b629e0c43a Replaced Notify::replyMarkupUpdated with Data::MessageUpdate. 2020-06-29 06:26:02 +04:00
23rd
6507007086 Added fade animation for total unread count badge in main menu. 2020-06-29 06:25:36 +04:00
John Preston
a389a1e468 Fix couple of crashes in main window. 2020-06-29 06:25:20 +04:00
John Preston
4e57ce8dbb Fix crash in filters update. 2020-06-26 21:50:36 +04:00
John Preston
b6ac4a0233 Closed alpha version 2.1.13.1: Multiaccount. 2020-06-26 17:09:39 +04:00
23rd
f8dca0ae88 Fixed couple of issues with passcode lock support in touchbar. 2020-06-26 15:57:09 +03:00
23rd
ef6fab7f2a Improved unread badges in touchbar. 2020-06-26 15:05:08 +03:00
23rd
c8c7497d75 Removed from touchbar unused code of old panel of pinned dialogs. 2020-06-26 15:05:08 +03:00
23rd
4f062788d2 Wrapped Pins in touchbar to shared_ptr. 2020-06-26 15:05:08 +03:00
23rd
25ab88d87a Added animated online dots to panel of pinned dialogs in touchbar. 2020-06-26 15:05:08 +03:00
23rd
e5732cba97 Added ability to reorder pins in new panel in touchbar. 2020-06-26 15:05:08 +03:00
23rd
0e794d53cd Reimplemented panel of pinned dialogs for touchbar. 2020-06-26 15:05:08 +03:00
23rd
68badc6682 Slightly optimized drawing stickers in touchbar. 2020-06-26 15:05:08 +03:00
23rd
27c799ce3d Fixed size ratios of stickers in touchbar. 2020-06-26 15:05:08 +03:00
John Preston
044c281cf7 Fix closing float player over Intro. 2020-06-26 16:01:37 +04:00
John Preston
3f0078cfbf Fix crash in float player over Intro. 2020-06-26 15:48:38 +04:00
John Preston
6068dc418d More auto-switching between accounts. 2020-06-26 15:48:28 +04:00
John Preston
6960e4808a Don't change dc after qr request / phone submit. 2020-06-26 15:28:06 +04:00
John Preston
793e8c102e Fix adjustable colors in default theme. 2020-06-26 14:37:07 +04:00
John Preston
31c745cb07 Destroy non-authed account on deactivate. 2020-06-26 14:36:52 +04:00
John Preston
c8efb77520 Fix local storage clearing on logout. 2020-06-26 14:36:22 +04:00
John Preston
76593b0f3d Fix migrating background image. 2020-06-26 13:23:10 +04:00
John Preston
9703f7460a Fix build on Linux. 2020-06-26 12:27:54 +04:00
John Preston
325840703e Fix launching with a passcode on macOS. 2020-06-26 11:51:05 +04:00
John Preston
70fdc4eb39 Improve quit prevent management. 2020-06-26 11:22:53 +04:00
John Preston
79a361ba43 Move call management to Core::App. 2020-06-25 21:57:36 +04:00
John Preston
8c4d3a86e7 Fix notifications on macOS. 2020-06-25 19:13:02 +04:00
John Preston
2b5d3b022d Fix player closing on logout. 2020-06-25 19:01:10 +04:00
John Preston
bf7aae5fc6 Allow float video player across accounts. 2020-06-25 18:17:37 +04:00
23rd
8171ed6c12 Fixed online status stuck when switching between accounts. 2020-06-25 16:06:02 +03:00
John Preston
5d6a494934 Move some more settings to Core::App. 2020-06-25 16:25:53 +04:00
John Preston
90a9cb4f8d Fix playing music from a different account. 2020-06-25 15:12:50 +04:00
John Preston
c60b9cfa4d Allow PiP from another account. 2020-06-25 14:28:02 +04:00
John Preston
8fec04ba7a Track session better in media viewer. 2020-06-25 13:42:30 +04:00
John Preston
c19c0afe60 Fix export bar in accounts toggle. 2020-06-25 13:02:02 +04:00
John Preston
8ad1e8aed9 Fix saving of main menu accounts state. 2020-06-25 13:01:17 +04:00
John Preston
65050bf9dd Move export management to Core::App. 2020-06-25 11:14:05 +04:00
John Preston
28cafb129e Load local stickers / gifs in Session(). 2020-06-24 16:52:06 +04:00
John Preston
0bc2bfe630 Don't allow two same accounts being logged in. 2020-06-24 13:32:07 +04:00
John Preston
d8a2b391a3 Use Main::Session::uniqueId in notifications. 2020-06-24 13:05:56 +04:00
John Preston
e38d39656d Activate account before showing a peer. 2020-06-24 12:28:46 +04:00
John Preston
99bf61ac8c Pass correct context to setMarkedText. 2020-06-24 12:22:27 +04:00
John Preston
e7b8a52278 Move terms lock from Core::App to Session. 2020-06-24 11:56:16 +04:00
John Preston
30c82bb2e0 Remove some MainWindow::sessionController() calls. 2020-06-23 21:53:44 +04:00
John Preston
4d65df6ca2 Remove legacy temp download folder. 2020-06-23 21:53:44 +04:00
John Preston
4add6234b6 Fix reading background before style init. 2020-06-23 21:53:44 +04:00
John Preston
55ec4ebf86 Allow returning from new account setup. 2020-06-23 21:53:44 +04:00
John Preston
c92c15883d Improve badges in accounts list. 2020-06-23 21:53:44 +04:00
John Preston
7b0a32b607 Add unread unmuted counter to main menu cover. 2020-06-23 21:53:44 +04:00
John Preston
34ef54e40b Display check on the active account. 2020-06-23 21:53:43 +04:00
John Preston
51c2bc7349 Create only one EmojiImageLoader to fix a crash. 2020-06-23 21:53:43 +04:00
23rd
2e7a89d9c4 Added support of switching accounts to touchbar. 2020-06-23 21:53:43 +04:00
John Preston
1248cef86b Add an arrow to the expand accounts button. 2020-06-23 21:53:43 +04:00
23rd
0696a2d5c0 Replaced mapping to rpl::empty_value with rpl::to_empty. 2020-06-23 21:53:43 +04:00
23rd
e318a7d65f Simplified ranges::find_if with ranges::any_of and ranges::none_of. 2020-06-23 21:53:43 +04:00
John Preston
5f238a71f9 Allow switching accounts from the main menu. 2020-06-23 21:53:43 +04:00
John Preston
f129b6b90d Fix invalid cache settings being read. 2020-06-23 21:53:43 +04:00
John Preston
bc3719038f Fix crash in session destruction. 2020-06-23 21:53:43 +04:00
John Preston
1705a1aa4a Fix filters in non-active accounts. 2020-06-23 21:53:43 +04:00
John Preston
a45d088ee4 Fix create group box. 2020-06-23 21:53:43 +04:00
John Preston
28570b45e3 Fix working with settings before Domain::started. 2020-06-23 21:53:43 +04:00
John Preston
4a8d297df3 Use username in notifications if available. 2020-06-23 21:53:43 +04:00
John Preston
3bb352e0e5 Fix build and working on macOS. 2020-06-23 21:53:42 +04:00
23rd
b49a8e6dc1 Fixed crash on pinning dialog from context menu.
Regression was introduced in 3a147305b7.
2020-06-23 21:53:42 +04:00
John Preston
0824d2da20 Reset some settings on full logout. 2020-06-23 21:53:42 +04:00
John Preston
2635ca33f8 Move background to global settings. 2020-06-23 21:53:42 +04:00
John Preston
5433c16244 Add target account name to notifications. 2020-06-23 21:53:42 +04:00
John Preston
997913be25 One Window::Notifications system for all sessions. 2020-06-23 21:53:42 +04:00
John Preston
83538675ce Move a lot of settings to Core::Settings. 2020-06-23 21:53:42 +04:00
John Preston
4d6cc58f0d Move session settings to main_session_settings. 2020-06-23 21:53:42 +04:00
John Preston
3a5ede534e Count all accounts in Core::App().unreadBadge. 2020-06-23 21:53:41 +04:00
John Preston
357caf8007 Keep separate MTP::Config's for separate accounts. 2020-06-23 21:53:41 +04:00
John Preston
63cdda2df7 Fix launching with autoupdates disabled. 2020-06-23 21:53:41 +04:00
23rd
3ef45f5431 Fixed starting with touchbar. 2020-06-23 21:53:41 +04:00
John Preston
c83659f0c7 Fix logouting from the passcode. 2020-06-23 21:53:41 +04:00
John Preston
ba103fdd40 Fix starting with a passcode. 2020-06-23 21:53:41 +04:00
John Preston
bc144377c0 Support logout of a secondary account. 2020-06-23 21:53:41 +04:00
John Preston
5e045ec02c Fix first main window appearance. 2020-06-23 21:53:41 +04:00
John Preston
ab5796c117 Several working accounts together. 2020-06-23 21:53:40 +04:00
John Preston
6fc5e22882 Allow several accounts in Core::App. 2020-06-23 21:53:40 +04:00
23rd
815e26eea5 Added missed handler for MTPupdates_GetState. 2020-06-23 21:53:40 +04:00
23rd
9faf15943a Fixed build for macOS. 2020-06-23 21:53:40 +04:00
John Preston
dddd355f6c Fix language and theme writing / reading. 2020-06-23 21:53:40 +04:00
John Preston
f450f81215 Remove non-UI calls to App::main. 2020-06-23 21:53:40 +04:00
John Preston
3c4e959468 Replace observer_peer with rpl interface. 2020-06-23 21:53:40 +04:00
John Preston
b0f9ad71dd Check some more App::main()s. 2020-06-23 21:53:40 +04:00
John Preston
0ad7dcaef9 Remove MTP::MainInstance() global access point. 2020-06-23 21:53:40 +04:00
John Preston
7f09da9e32 Use MTP::Sender in Intro. 2020-06-23 21:53:39 +04:00
John Preston
0b028b959b Move updates handling MainWidget -> Api::Updates. 2020-06-23 21:53:39 +04:00
John Preston
ee43027bea Remove some usages of App::main(). 2020-06-23 21:53:39 +04:00
John Preston
ea86433be5 Remove some activeAccount() calls. 2020-06-23 21:53:39 +04:00
John Preston
598fb67cdf Remove Session::Exists() global access point. 2020-06-23 21:53:39 +04:00
John Preston
5f8d22f1f2 Remove Auth() global access point. 2020-06-23 21:53:39 +04:00
John Preston
7892ba97e6 Fix clearing storage_account files on logout. 2020-06-23 21:53:39 +04:00
John Preston
ad4afe9293 Move session data localstorage -> storage_account. 2020-06-23 21:53:39 +04:00
23rd
739a3ebe97 Removed all Auth() calls from touchbar. 2020-06-23 21:53:39 +04:00
John Preston
03dec15e8e Pass Main::Session to click handler creators. 2020-06-23 21:53:38 +04:00
John Preston
fc174f742a Move stickers code to Data::Stickers class. 2020-06-23 21:53:38 +04:00
John Preston
27af83267e Move autolock checking to Core::Application. 2020-06-23 21:53:38 +04:00
John Preston
4b354b0928 Use Main::Session in download/upload. 2020-06-23 21:53:38 +04:00
John Preston
3878a1b212 Remove some more Auth() calls. 2020-06-23 21:53:38 +04:00
John Preston
bede709f6b Fix file origin in media viewer photo preloading.
It never worked correctly, but before somehow it got worked around.

Fixes #8043.
2020-06-23 21:53:38 +04:00
John Preston
f6150d4d3e Version 2.1.13.
- Fix photos loading.
- Fix Picture-in-Picture window movement on Wayland in Linux.
2020-06-23 21:52:59 +04:00
John Preston
7624e74c8b Be sure to set correct PiP maximum size. 2020-06-23 21:50:20 +04:00
Ilya Fedin
5ac628ee4d Use startSystemMove/startSystemResize in PiP window on Wayland
Since startSystemMove is the only way to move a window on Wayland

And since custom resize works bad due to the lack of moving (resize with left and top corners works just like resize with right and bottom corners)
2020-06-23 21:45:39 +04:00
23rd
beb2e7dc19 Fixed ability to open more than one calendar in schedule box. 2020-06-23 21:39:33 +04:00
23rd
50ab655af9 Added ability to change date in schedule box with wheel. 2020-06-23 21:39:33 +04:00
23rd
425423e113 Added ability to change time in schedule box with wheel. 2020-06-23 21:39:33 +04:00
Ilya Fedin
2743aee614 Disable restart on session start explicitly 2020-06-23 21:30:44 +04:00
Ilya Fedin
06a4480520 Drop unneeded GTK methods 2020-06-23 21:29:18 +04:00
Ilya Fedin
384a71930d Don't try to focus the window when clicking on tray icon on Wayland 2020-06-23 21:28:46 +04:00
Ilya Fedin
68fde210c6 Platform::IsWayland could be used on any platform now 2020-06-23 21:24:44 +04:00
Ilya Fedin
9a65481e9d Unset QT_STYLE_OVERRIDE instead of forcing Fusion
To don't break styling on KDE
2020-06-23 21:23:47 +04:00
Ilya Fedin
0b939e72c1 Fix CI 2020-06-19 06:28:01 +04:00
Ilya Fedin
1beada6e4a Hide notification position in settings on Wayland 2020-06-19 06:28:01 +04:00
Ilya Fedin
a416debc2f core20 doesn't support i386 2020-06-18 06:46:11 +04:00
Ilya Fedin
6c52b4630c Update ffmpeg to 4.3 in snap 2020-06-18 06:46:11 +04:00
John Preston
a56ecfebeb Version 2.1.12: Fix build on macOS. 2020-06-17 22:36:53 +04:00
John Preston
3681a5559e Version 2.1.12: Update submodule. 2020-06-17 21:21:02 +04:00
John Preston
f07e4a8e5e Version 2.1.12.
- Fix sticker and video results in inline bots.
- Fix clipboard issues in Linux.
- Fix several crashes.
2020-06-17 20:38:41 +04:00
Ilya Fedin
3a91003eea Use gtk clipboard when available to avoid https://bugreports.qt.io/browse/QTBUG-56595 2020-06-17 20:34:47 +04:00
Ilya Fedin
a70cc9b956 Fix patches cache on windows and macos actions 2020-06-17 20:33:46 +04:00
Ilya Fedin
fde51018ca Update libwayland 2020-06-17 20:33:46 +04:00
Ilya Fedin
70acebc1ef Windows build can be built without updater too 2020-06-17 20:33:23 +04:00
Ilya Fedin
dbad9fa73a Use Q_OS_UNIX instead of Q_OS_LINUX since linux-specific code can be used also on *BSD/Haiku 2020-06-17 20:33:23 +04:00
Ilya Fedin
56de3194ef Never use custom notifications on Wayland since there are no positioning API 2020-06-17 20:32:50 +04:00
23rd
2559a3590d Fixed wrong Z-order of drag areas that were under schedule button. 2020-06-16 20:06:37 +03:00
John Preston
099482574e Fix sending stickers from inline bots.
Fixes #8020.
2020-06-16 20:53:44 +04:00
John Preston
1024f38944 Fix inline bot video results without documents.
Fixes #8060.
2020-06-16 19:54:23 +04:00
John Preston
99704e973b Always keep current self-userpic loaded. 2020-06-16 19:40:43 +04:00
John Preston
571a15bf92 Fix sending image from clipboard as file. 2020-06-16 19:31:50 +04:00
John Preston
cdc295c1d7 Fix build with updated submodules. 2020-06-16 19:10:39 +04:00
Zhiming Deng
b412b2141e update 2020-06-14 11:07:48 +04:00
Zhiming Deng
c18edf2f30 doc 2020-06-14 11:07:48 +04:00
Ilya Fedin
e009ac026d Update snap to core20 2020-06-09 19:01:35 +04:00
John Preston
ef08b52597 Version 2.1.11 (Linux only).
- Fix launch on old Linux systems.

Degrade OpenAL back to 1.19.1 so that it will still work on old systems.

Fixes #8005.
2020-06-08 12:23:27 +04:00
John Preston
9f6fc3a4c8 Ignore observables notification after ~Application. 2020-06-08 12:20:51 +04:00
John Preston
7757cad839 Fix crash in media viewer refresh in showPhoto. 2020-06-08 12:09:07 +04:00
John Preston
bdbcd8e540 Use Main::Session in entities parsing. 2020-06-08 12:05:17 +04:00
John Preston
7a5f4e8a01 Fix crashes in EditCaptionBox and dropdown. 2020-06-08 12:02:43 +04:00
23rd
cf40f92cd5 Fixed crash in rescheduling of scheduled until online messages.
Fixed #8016.
2020-06-08 09:56:09 +03:00
Ilya Fedin
ccce5f081d Fix running snap with XEmbed trays 2020-06-08 10:33:45 +04:00
John Preston
f50fdd0236 Version 2.1.10.
- Improve memory usage.
- Add support for full group message history export.
- Allow export of a single chat message history in JSON format.
2020-06-05 20:04:22 +04:00
23rd
d4f2b8dd0e Fixed ability to edit media with sticker.
Regression was introduced in efa4deef6a.
2020-06-05 19:46:34 +04:00
23rd
f4042d5ad5 Fixed ability to see empty header in HistoryWidget.
The problem occurs by pressing the left side of the header
when there is no second layer.
2020-06-05 19:46:33 +04:00
23rd
1c77b9c16f Changed button names in SendFilesBox.
Fixed #7988.
2020-06-05 19:46:32 +04:00
John Preston
06629ad171 Fix crash in PiP with bad video files. 2020-06-05 14:26:42 +04:00
John Preston
05df4f832b Fix crash in theme editor closing. 2020-06-05 14:00:06 +04:00
John Preston
6c2a29b83f Fix possible crash in EditCaptionBox. 2020-06-05 13:17:53 +04:00
John Preston
a586b18dfb Fix pending web pages applying.
Fixes #7091.
2020-06-05 13:03:45 +04:00
John Preston
d0994019ca Beta version 2.1.9: Fix 'edited' field export.
Export 'edited' only if the message was edited.
2020-06-04 18:17:50 +04:00
John Preston
23f94c61a4 Beta version 2.1.9.
- Several crash fixes.
2020-06-04 17:32:10 +04:00
John Preston
2b9e4a8ddf Simplify playing video tracking (and fix a crash). 2020-06-04 17:26:11 +04:00
John Preston
e1d36cfd50 Fix crash in the EditCaptionBox. 2020-06-04 17:26:11 +04:00
John Preston
fbb2bae99f Fix crash in OS X 10.10 / 10.11. 2020-06-04 13:24:38 +04:00
John Preston
6bc7fa9ef4 Fix crash in saving of a document. 2020-06-04 12:22:37 +04:00
John Preston
bf06d4d545 Fix crash in stickers box. 2020-06-04 12:16:56 +04:00
John Preston
bfafdd5b38 Fix crash in streaming+loading of a document. 2020-06-04 12:16:44 +04:00
John Preston
f581a15b6e Fix crash in PiP window. 2020-06-04 11:00:59 +04:00
John Preston
c868cd6036 Update lib_ui. 2020-06-04 10:53:59 +04:00
568 changed files with 26374 additions and 19981 deletions

View File

@@ -157,7 +157,7 @@ jobs:
- name: Opus cache.
id: cache-opus
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/opus
key: ${{ runner.OS }}-opus-${{ env.CACHE_KEY }}
@@ -202,7 +202,7 @@ jobs:
- name: FFmpeg cache.
id: cache-ffmpeg
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/ffmpeg-cache
key: ${{ runner.OS }}-ffmpeg-${{ env.CACHE_KEY }}
@@ -356,7 +356,7 @@ jobs:
- name: OpenSSL cache.
id: cache-openssl
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/openssl-cache
key: ${{ runner.OS }}-${{ env.OPENSSL_VER }}-${{ env.CACHE_KEY }}
@@ -383,7 +383,7 @@ jobs:
run: |
cd $LibrariesPath
git clone -b 1.16 https://gitlab.freedesktop.org/wayland/wayland
git clone -b 1.18.0 https://gitlab.freedesktop.org/wayland/wayland
cd wayland
./autogen.sh \
--enable-static \
@@ -412,7 +412,7 @@ jobs:
- name: Qt 5.12.8 cache.
id: cache-qt
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/qt-cache
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qt*_5_12_8/*') }}
@@ -461,7 +461,7 @@ jobs:
- name: Breakpad cache.
id: cache-breakpad
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/breakpad-cache
key: ${{ runner.OS }}-breakpad-${{ env.CACHE_KEY }}

View File

@@ -133,7 +133,7 @@ jobs:
- name: OpenSSL cache.
id: cache-openssl
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/openssl_${{ env.OPENSSL_VER }}
key: ${{ runner.OS }}-${{ env.OPENSSL_VER }}-${{ env.CACHE_KEY }}
@@ -163,7 +163,7 @@ jobs:
- name: Opus cache.
id: cache-opus
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/opus
key: ${{ runner.OS }}-opus-${{ env.CACHE_KEY }}
@@ -185,7 +185,7 @@ jobs:
- name: Libiconv cache.
id: cache-libiconv
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/${{ env.LIBICONV_VER }}
key: ${{ runner.OS }}-${{ env.LIBICONV_VER }}-${{ env.CACHE_KEY }}
@@ -206,7 +206,7 @@ jobs:
- name: FFmpeg cache.
id: cache-ffmpeg
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/ffmpeg-cache
key: ${{ runner.OS }}-ffmpeg-${{ env.CACHE_KEY }}
@@ -362,7 +362,7 @@ jobs:
- name: Crashpad cache.
id: cache-crashpad
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/crashpad
key: ${{ runner.OS }}-crashpad-${{ env.CACHE_KEY }}-${{ hashFiles('**/crashpad.diff') }}-${{ hashFiles('**/mini_chromium.diff') }}
@@ -401,10 +401,10 @@ jobs:
- name: Qt 5.12.8 cache.
id: cache-qt
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/qt-cache
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_8.diff') }}
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_8/*') }}
- name: Use cached Qt 5.12.8.
if: steps.cache-qt.outputs.cache-hit == 'true'
run: |

View File

@@ -12,7 +12,6 @@ on:
- '!.github/workflows/snap.yml'
- 'Telegram/build/**'
- 'Telegram/Patches/**'
- '!Telegram/Patches/ffmpeg.diff'
- 'Telegram/Resources/uwp/**'
- 'Telegram/Resources/winrc/**'
- 'Telegram/SourceFiles/platform/win/**'
@@ -31,7 +30,6 @@ on:
- '!.github/workflows/snap.yml'
- 'Telegram/build/**'
- 'Telegram/Patches/**'
- '!Telegram/Patches/ffmpeg.diff'
- 'Telegram/Resources/uwp/**'
- 'Telegram/Resources/winrc/**'
- 'Telegram/SourceFiles/platform/win/**'
@@ -43,8 +41,8 @@ on:
jobs:
linux:
name: Ubuntu 18.04
runs-on: ubuntu-18.04
name: Ubuntu 20.04
runs-on: ubuntu-20.04
env:
UPLOAD_ARTIFACT: "false"

View File

@@ -133,7 +133,7 @@ jobs:
- name: OpenSSL cache.
id: cache-openssl
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/openssl_${{ env.OPENSSL_VER }}
key: ${{ runner.OS }}-${{ env.CACHE_KEY }}-${{ env.OPENSSL_VER }}
@@ -177,7 +177,7 @@ jobs:
- name: OpenAL Soft cache.
id: cache-openal
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/openal-soft
key: ${{ runner.OS }}-openal-soft-${{ env.CACHE_KEY }}
@@ -201,7 +201,7 @@ jobs:
- name: Breakpad cache.
id: cache-breakpad
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/breakpad
key: ${{ runner.OS }}-breakpad-${{ env.CACHE_KEY }}-${{ hashFiles('**/breakpad.diff') }}
@@ -250,7 +250,7 @@ jobs:
- name: Opus cache.
id: cache-opus
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/opus
key: ${{ runner.OS }}-opus-${{ env.CACHE_KEY }}
@@ -269,7 +269,7 @@ jobs:
- name: FFmpeg cache.
id: cache-ffmpeg
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/ffmpeg
key: ${{ runner.OS }}-ffmpeg-${{ env.CACHE_KEY }}-2-${{ hashFiles('**/build_ffmpeg_win.sh') }}
@@ -291,10 +291,10 @@ jobs:
- name: Qt 5.12.8 cache.
id: cache-qt
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/Qt-5.12.8
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_8.diff') }}
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_8/*') }}
- name: Configure Qt 5.12.8.
if: steps.cache-qt.outputs.cache-hit != 'true'
shell: cmd
@@ -379,7 +379,6 @@ jobs:
cd %REPO_NAME%\out\Debug
mkdir artifact
move Telegram.exe artifact/
move Updater.exe artifact/
- uses: actions/upload-artifact@master
name: Upload artifact.
if: env.UPLOAD_ARTIFACT == 'true'

View File

@@ -127,6 +127,35 @@ PRIVATE
desktop-app::external_openal
)
if (LINUX AND NOT TDESKTOP_DISABLE_GTK_INTEGRATION)
find_package(PkgConfig REQUIRED)
target_compile_options(Telegram PRIVATE -Wno-register)
if (DESKTOP_APP_USE_PACKAGED AND NOT DESKTOP_APP_USE_PACKAGED_LAZY)
pkg_check_modules(X11 REQUIRED IMPORTED_TARGET x11)
pkg_check_modules(GOBJECT2 REQUIRED IMPORTED_TARGET gobject-2.0)
pkg_check_modules(GLIB2 REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(GTK3 REQUIRED IMPORTED_TARGET gtk+-3.0)
target_link_libraries(Telegram
PRIVATE
PkgConfig::X11
PkgConfig::GOBJECT2
PkgConfig::GLIB2
PkgConfig::GTK3
)
else()
pkg_search_module(GTK REQUIRED gtk+-2.0 gtk+-3.0)
target_link_libraries(Telegram
PRIVATE
X11
gobject-2.0
glib-2.0
)
target_include_directories(Telegram PRIVATE ${GTK_INCLUDE_DIRS})
endif()
endif()
# Telegram uses long atomic types, so on some architectures libatomic is needed.
check_cxx_source_compiles("
#include <atomic>
@@ -155,6 +184,7 @@ PRIVATE
api/api_chat_filters.cpp
api/api_chat_filters.h
api/api_common.h
api/api_hash.cpp
api/api_hash.h
api/api_self_destruct.cpp
api/api_self_destruct.h
@@ -166,6 +196,8 @@ PRIVATE
api/api_single_message_search.h
api/api_text_entities.cpp
api/api_text_entities.h
api/api_updates.cpp
api/api_updates.h
boxes/filters/edit_filter_box.cpp
boxes/filters/edit_filter_box.h
boxes/filters/edit_filter_chats_list.cpp
@@ -293,16 +325,16 @@ PRIVATE
chat_helpers/message_field.h
chat_helpers/spellchecker_common.cpp
chat_helpers/spellchecker_common.h
chat_helpers/stickers.cpp
chat_helpers/stickers.h
chat_helpers/stickers_emoji_image_loader.cpp
chat_helpers/stickers_emoji_image_loader.h
chat_helpers/stickers_emoji_pack.cpp
chat_helpers/stickers_emoji_pack.h
chat_helpers/stickers_dice_pack.cpp
chat_helpers/stickers_dice_pack.h
chat_helpers/stickers_list_widget.cpp
chat_helpers/stickers_list_widget.h
chat_helpers/stickers_set.cpp
chat_helpers/stickers_set.h
chat_helpers/stickers_lottie.cpp
chat_helpers/stickers_lottie.h
chat_helpers/tabbed_panel.cpp
chat_helpers/tabbed_panel.h
chat_helpers/tabbed_section.cpp
@@ -344,6 +376,10 @@ PRIVATE
core/utils.cpp
core/utils.h
core/version.h
data/stickers/data_stickers_set.cpp
data/stickers/data_stickers_set.h
data/stickers/data_stickers.cpp
data/stickers/data_stickers.h
data/data_abstract_structure.cpp
data/data_abstract_structure.h
data/data_auto_download.cpp
@@ -352,6 +388,8 @@ PRIVATE
data/data_chat.h
data/data_chat_filters.cpp
data/data_chat_filters.h
data/data_changes.cpp
data/data_changes.h
data/data_channel.cpp
data/data_channel.h
data/data_channel_admins.cpp
@@ -448,6 +486,8 @@ PRIVATE
dialogs/dialogs_search_from_controllers.h
dialogs/dialogs_widget.cpp
dialogs/dialogs_widget.h
export/export_manager.cpp
export/export_manager.h
export/view/export_view_content.cpp
export/view/export_view_content.h
export/view/export_view_panel_controller.cpp
@@ -663,10 +703,12 @@ PRIVATE
main/main_account.h
main/main_app_config.cpp
main/main_app_config.h
main/main_domain.cpp
main/main_domain.h
main/main_session.cpp
main/main_session.h
main/main_settings.cpp
main/main_settings.h
main/main_session_settings.cpp
main/main_session_settings.h
media/audio/media_audio.cpp
media/audio/media_audio.h
media/audio/media_audio_capture.cpp
@@ -681,6 +723,8 @@ PRIVATE
media/audio/media_audio_track.h
media/audio/media_child_ffmpeg_loader.cpp
media/audio/media_child_ffmpeg_loader.h
media/audio/media_openal_functions.cpp
media/audio/media_openal_functions.h
media/clip/media_clip_check_streaming.cpp
media/clip/media_clip_check_streaming.h
media/clip/media_clip_ffmpeg.cpp
@@ -746,8 +790,6 @@ PRIVATE
mtproto/connection_tcp.cpp
mtproto/connection_tcp.h
mtproto/core_types.h
mtproto/dc_options.cpp
mtproto/dc_options.h
mtproto/dedicated_file_loader.cpp
mtproto/dedicated_file_loader.h
mtproto/facade.cpp
@@ -803,6 +845,7 @@ PRIVATE
platform/linux/notifications_manager_linux.h
platform/linux/specific_linux.cpp
platform/linux/specific_linux.h
platform/linux/window_title_linux.h
platform/mac/file_utilities_mac.mm
platform/mac/file_utilities_mac.h
platform/mac/launcher_mac.mm
@@ -881,6 +924,10 @@ PRIVATE
settings/settings_privacy_controllers.h
settings/settings_privacy_security.cpp
settings/settings_privacy_security.h
storage/details/storage_file_utilities.cpp
storage/details/storage_file_utilities.h
storage/details/storage_settings_scheme.cpp
storage/details/storage_settings_scheme.h
storage/download_manager_mtproto.cpp
storage/download_manager_mtproto.h
storage/file_download.cpp
@@ -899,8 +946,14 @@ PRIVATE
storage/serialize_common.h
storage/serialize_document.cpp
storage/serialize_document.h
storage/serialize_peer.cpp
storage/serialize_peer.h
storage/storage_account.cpp
storage/storage_account.h
storage/storage_cloud_blob.cpp
storage/storage_cloud_blob.h
storage/storage_domain.cpp
storage/storage_domain.h
storage/storage_facade.cpp
storage/storage_facade.h
# storage/storage_feed_messages.cpp
@@ -999,6 +1052,8 @@ PRIVATE
window/window_session_controller.h
window/window_slide_animation.cpp
window/window_slide_animation.h
window/window_title_qt.cpp
window/window_title_qt.h
window/window_title.h
window/window_top_bar_wrap.h
window/themes/window_theme.cpp
@@ -1035,13 +1090,18 @@ PRIVATE
mainwidget.h
mainwindow.cpp
mainwindow.h
observer_peer.cpp
observer_peer.h
qt_static_plugins.cpp
settings.cpp
settings.h
)
if (NOT LINUX)
remove_target_sources(Telegram ${src_loc}
window/window_title_qt.cpp
window/window_title_qt.h
)
endif()
if (DESKTOP_APP_USE_PACKAGED)
nice_target_sources(Telegram ${src_loc} PRIVATE qt_functions.cpp)
else()
@@ -1124,19 +1184,6 @@ elseif (APPLE)
)
endif()
endif()
elseif (LINUX)
if (NOT TDESKTOP_DISABLE_GTK_INTEGRATION)
find_package(PkgConfig REQUIRED)
pkg_search_module(GTK REQUIRED gtk+-2.0 gtk+-3.0)
target_include_directories(Telegram PRIVATE ${GTK_INCLUDE_DIRS})
target_compile_options(Telegram PRIVATE -Wno-register)
if (DESKTOP_APP_USE_PACKAGED)
find_library(X11_LIBRARY X11)
target_link_libraries(Telegram PRIVATE ${X11_LIBRARY})
endif()
endif()
endif()
if (build_macstore)
@@ -1209,7 +1256,7 @@ endif()
set_target_properties(Telegram PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${output_folder})
if ((NOT DESKTOP_APP_DISABLE_AUTOUPDATE OR NOT LINUX) AND NOT build_macstore AND NOT build_winstore)
if ((NOT DESKTOP_APP_DISABLE_AUTOUPDATE OR APPLE) AND NOT build_macstore AND NOT build_winstore)
add_executable(Updater WIN32)
init_target(Updater)

View File

@@ -1,225 +0,0 @@
diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile
index 00f93bf59f..52da7036f3 100644
--- a/libavcodec/aarch64/Makefile
+++ b/libavcodec/aarch64/Makefile
@@ -6,6 +6,7 @@ OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_init_aarch64.o
OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_init.o
OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_init_aarch64.o
OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_init_aarch64.o
+OBJS-$(CONFIG_IDCTDSP) += aarch64/idctdsp_init_aarch64.o
OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_init.o
OBJS-$(CONFIG_NEON_CLOBBER_TEST) += aarch64/neontest.o
OBJS-$(CONFIG_VIDEODSP) += aarch64/videodsp_init.o
@@ -21,6 +22,7 @@ OBJS-$(CONFIG_VC1DSP) += aarch64/vc1dsp_init_aarch64.o
OBJS-$(CONFIG_VORBIS_DECODER) += aarch64/vorbisdsp_init.o
OBJS-$(CONFIG_VP9_DECODER) += aarch64/vp9dsp_init_10bpp_aarch64.o \
aarch64/vp9dsp_init_12bpp_aarch64.o \
+ aarch64/vp9mc_aarch64.o \
aarch64/vp9dsp_init_aarch64.o
# ARMv8 optimizations
@@ -41,8 +43,7 @@ NEON-OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_neon.o
NEON-OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_neon.o \
aarch64/hpeldsp_neon.o
NEON-OBJS-$(CONFIG_HPELDSP) += aarch64/hpeldsp_neon.o
-NEON-OBJS-$(CONFIG_IDCTDSP) += aarch64/idctdsp_init_aarch64.o \
- aarch64/simple_idct_neon.o
+NEON-OBJS-$(CONFIG_IDCTDSP) += aarch64/simple_idct_neon.o
NEON-OBJS-$(CONFIG_MDCT) += aarch64/mdct_neon.o
NEON-OBJS-$(CONFIG_MPEGAUDIODSP) += aarch64/mpegaudiodsp_neon.o
NEON-OBJS-$(CONFIG_VP8DSP) += aarch64/vp8dsp_neon.o
diff --git a/libavcodec/aarch64/idctdsp_init_aarch64.c b/libavcodec/aarch64/idctdsp_init_aarch64.c
index 0406e60830..742a3372e3 100644
--- a/libavcodec/aarch64/idctdsp_init_aarch64.c
+++ b/libavcodec/aarch64/idctdsp_init_aarch64.c
@@ -21,6 +21,8 @@
*/
#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/arm/cpu.h"
#include "libavcodec/avcodec.h"
#include "libavcodec/idctdsp.h"
#include "idct.h"
@@ -28,7 +30,9 @@
av_cold void ff_idctdsp_init_aarch64(IDCTDSPContext *c, AVCodecContext *avctx,
unsigned high_bit_depth)
{
- if (!avctx->lowres && !high_bit_depth) {
+ int cpu_flags = av_get_cpu_flags();
+
+ if (have_neon(cpu_flags) && !avctx->lowres && !high_bit_depth) {
if (avctx->idct_algo == FF_IDCT_AUTO ||
avctx->idct_algo == FF_IDCT_SIMPLEAUTO ||
avctx->idct_algo == FF_IDCT_SIMPLENEON) {
diff --git a/libavcodec/aarch64/vp9mc_16bpp_neon.S b/libavcodec/aarch64/vp9mc_16bpp_neon.S
index cac6428709..53b372c262 100644
--- a/libavcodec/aarch64/vp9mc_16bpp_neon.S
+++ b/libavcodec/aarch64/vp9mc_16bpp_neon.S
@@ -25,31 +25,6 @@
// const uint8_t *ref, ptrdiff_t ref_stride,
// int h, int mx, int my);
-function ff_vp9_copy128_aarch64, export=1
-1:
- ldp x5, x6, [x2]
- ldp x7, x8, [x2, #16]
- stp x5, x6, [x0]
- ldp x9, x10, [x2, #32]
- stp x7, x8, [x0, #16]
- subs w4, w4, #1
- ldp x11, x12, [x2, #48]
- stp x9, x10, [x0, #32]
- stp x11, x12, [x0, #48]
- ldp x5, x6, [x2, #64]
- ldp x7, x8, [x2, #80]
- stp x5, x6, [x0, #64]
- ldp x9, x10, [x2, #96]
- stp x7, x8, [x0, #80]
- ldp x11, x12, [x2, #112]
- stp x9, x10, [x0, #96]
- stp x11, x12, [x0, #112]
- add x2, x2, x3
- add x0, x0, x1
- b.ne 1b
- ret
-endfunc
-
function ff_vp9_avg64_16_neon, export=1
mov x5, x0
sub x1, x1, #64
diff --git a/libavcodec/aarch64/vp9mc_aarch64.S b/libavcodec/aarch64/vp9mc_aarch64.S
new file mode 100644
index 0000000000..f17a8cf04a
--- /dev/null
+++ b/libavcodec/aarch64/vp9mc_aarch64.S
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Google Inc.
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/aarch64/asm.S"
+
+// All public functions in this file have the following signature:
+// typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride,
+// const uint8_t *ref, ptrdiff_t ref_stride,
+// int h, int mx, int my);
+
+function ff_vp9_copy128_aarch64, export=1
+1:
+ ldp x5, x6, [x2]
+ ldp x7, x8, [x2, #16]
+ stp x5, x6, [x0]
+ ldp x9, x10, [x2, #32]
+ stp x7, x8, [x0, #16]
+ subs w4, w4, #1
+ ldp x11, x12, [x2, #48]
+ stp x9, x10, [x0, #32]
+ stp x11, x12, [x0, #48]
+ ldp x5, x6, [x2, #64]
+ ldp x7, x8, [x2, #80]
+ stp x5, x6, [x0, #64]
+ ldp x9, x10, [x2, #96]
+ stp x7, x8, [x0, #80]
+ ldp x11, x12, [x2, #112]
+ stp x9, x10, [x0, #96]
+ stp x11, x12, [x0, #112]
+ add x2, x2, x3
+ add x0, x0, x1
+ b.ne 1b
+ ret
+endfunc
+
+function ff_vp9_copy64_aarch64, export=1
+1:
+ ldp x5, x6, [x2]
+ ldp x7, x8, [x2, #16]
+ stp x5, x6, [x0]
+ ldp x9, x10, [x2, #32]
+ stp x7, x8, [x0, #16]
+ subs w4, w4, #1
+ ldp x11, x12, [x2, #48]
+ stp x9, x10, [x0, #32]
+ stp x11, x12, [x0, #48]
+ add x2, x2, x3
+ add x0, x0, x1
+ b.ne 1b
+ ret
+endfunc
+
+function ff_vp9_copy32_aarch64, export=1
+1:
+ ldp x5, x6, [x2]
+ ldp x7, x8, [x2, #16]
+ stp x5, x6, [x0]
+ subs w4, w4, #1
+ stp x7, x8, [x0, #16]
+ add x2, x2, x3
+ add x0, x0, x1
+ b.ne 1b
+ ret
+endfunc
diff --git a/libavcodec/aarch64/vp9mc_neon.S b/libavcodec/aarch64/vp9mc_neon.S
index f67624ca04..abf2bae9db 100644
--- a/libavcodec/aarch64/vp9mc_neon.S
+++ b/libavcodec/aarch64/vp9mc_neon.S
@@ -25,23 +25,6 @@
// const uint8_t *ref, ptrdiff_t ref_stride,
// int h, int mx, int my);
-function ff_vp9_copy64_aarch64, export=1
-1:
- ldp x5, x6, [x2]
- ldp x7, x8, [x2, #16]
- stp x5, x6, [x0]
- ldp x9, x10, [x2, #32]
- stp x7, x8, [x0, #16]
- subs w4, w4, #1
- ldp x11, x12, [x2, #48]
- stp x9, x10, [x0, #32]
- stp x11, x12, [x0, #48]
- add x2, x2, x3
- add x0, x0, x1
- b.ne 1b
- ret
-endfunc
-
function ff_vp9_avg64_neon, export=1
mov x5, x0
1:
@@ -64,19 +47,6 @@ function ff_vp9_avg64_neon, export=1
ret
endfunc
-function ff_vp9_copy32_aarch64, export=1
-1:
- ldp x5, x6, [x2]
- ldp x7, x8, [x2, #16]
- stp x5, x6, [x0]
- subs w4, w4, #1
- stp x7, x8, [x0, #16]
- add x2, x2, x3
- add x0, x0, x1
- b.ne 1b
- ret
-endfunc
-
function ff_vp9_avg32_neon, export=1
1:
ld1 {v2.16b, v3.16b}, [x2], x3

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -15,6 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_menu_update" = "Update";
"lng_menu_back" = "Back";
"lng_menu_night_mode" = "Night Mode";
"lng_menu_add_account" = "Add Account";
"lng_menu_activate" = "Activate";
"lng_disable_notifications_from_tray" = "Disable notifications";
"lng_enable_notifications_from_tray" = "Enable notifications";
@@ -290,6 +292,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_empty_bio" = "None";
"lng_settings_section_notify" = "Notifications";
"lng_settings_show_from" = "Show notifications from";
"lng_settings_notify_all" = "All accounts";
"lng_settings_notify_all_about" = "Turn this off if you want to receive notifications only from the account you are currently using.";
"lng_settings_notify_title" = "Notifications for chats";
"lng_settings_desktop_notify" = "Desktop notifications";
"lng_settings_show_name" = "Show sender's name";

View File

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

View File

@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,1,8,0
PRODUCTVERSION 2,1,8,0
FILEVERSION 2,1,17,0
PRODUCTVERSION 2,1,17,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.1.8.0"
VALUE "FileVersion", "2.1.17.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.1.8.0"
VALUE "ProductVersion", "2.1.17.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,1,8,0
PRODUCTVERSION 2,1,8,0
FILEVERSION 2,1,17,0
PRODUCTVERSION 2,1,17,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.1.8.0"
VALUE "FileVersion", "2.1.17.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.1.8.0"
VALUE "ProductVersion", "2.1.17.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -254,7 +254,7 @@ int main(int argc, char *argv[])
}
QByteArray inner = f.readAll();
stream << name << quint32(inner.size()) << inner;
#if defined Q_OS_MAC || defined Q_OS_LINUX
#ifdef Q_OS_UNIX
stream << (QFileInfo(fullName).isExecutable() ? true : false);
#endif
}
@@ -467,10 +467,12 @@ int main(int argc, char *argv[])
QString outName(QString("tupdate%1").arg(AlphaVersion ? AlphaVersion : version));
#elif defined Q_OS_MAC
QString outName((targetosx ? QString("tosxupd%1") : QString("tmacupd%1")).arg(AlphaVersion ? AlphaVersion : version));
#elif defined Q_OS_LINUX32
#elif defined Q_OS_UNIX
#ifndef _LP64
QString outName(QString("tlinux32upd%1").arg(AlphaVersion ? AlphaVersion : version));
#elif defined Q_OS_LINUX64
#else
QString outName(QString("tlinuxupd%1").arg(AlphaVersion ? AlphaVersion : version));
#endif
#else
#error Unknown platform!
#endif

View File

@@ -0,0 +1,94 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_hash.h"
#include "data/data_document.h"
#include "data/data_session.h"
#include "data/stickers/data_stickers.h"
#include "main/main_session.h"
namespace Api {
namespace {
[[nodiscard]] int32 CountDocumentVectorHash(
const QVector<DocumentData*> vector) {
auto result = HashInit();
for (const auto document : vector) {
HashUpdate(result, document->id);
}
return HashFinalize(result);
}
[[nodiscard]] int32 CountSpecialStickerSetHash(
not_null<Main::Session*> session,
uint64 setId) {
const auto &sets = session->data().stickers().sets();
const auto it = sets.find(setId);
if (it != sets.cend()) {
return CountDocumentVectorHash(it->second->stickers);
}
return 0;
}
} // namespace
int32 CountStickersHash(
not_null<Main::Session*> session,
bool checkOutdatedInfo) {
auto result = HashInit();
bool foundOutdated = false;
const auto &sets = session->data().stickers().sets();
const auto &order = session->data().stickers().setsOrder();
for (auto i = order.cbegin(), e = order.cend(); i != e; ++i) {
auto it = sets.find(*i);
if (it != sets.cend()) {
const auto set = it->second.get();
if (set->id == Data::Stickers::DefaultSetId) {
foundOutdated = true;
} else if (!(set->flags & MTPDstickerSet_ClientFlag::f_special)
&& !(set->flags & MTPDstickerSet::Flag::f_archived)) {
HashUpdate(result, set->hash);
}
}
}
return (!checkOutdatedInfo || !foundOutdated)
? HashFinalize(result)
: 0;
}
int32 CountRecentStickersHash(not_null<Main::Session*> session) {
return CountSpecialStickerSetHash(
session,
Data::Stickers::CloudRecentSetId);
}
int32 CountFavedStickersHash(not_null<Main::Session*> session) {
return CountSpecialStickerSetHash(session, Data::Stickers::FavedSetId);
}
int32 CountFeaturedStickersHash(not_null<Main::Session*> session) {
auto result = HashInit();
const auto &sets = session->data().stickers().sets();
const auto &featured = session->data().stickers().featuredSetsOrder();
for (const auto setId : featured) {
HashUpdate(result, setId);
const auto it = sets.find(setId);
if (it != sets.cend()
&& (it->second->flags & MTPDstickerSet_ClientFlag::f_unread)) {
HashUpdate(result, 1);
}
}
return HashFinalize(result);
}
int32 CountSavedGifsHash(not_null<Main::Session*> session) {
return CountDocumentVectorHash(session->data().stickers().savedGifs());
}
} // namespace Api

View File

@@ -7,8 +7,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Main {
class Session;
} // namespace Main
namespace Api {
[[nodiscard]] int32 CountStickersHash(
not_null<Main::Session*> session,
bool checkOutdatedInfo = false);
[[nodiscard]] int32 CountRecentStickersHash(
not_null<Main::Session*> session);
[[nodiscard]] int32 CountFavedStickersHash(not_null<Main::Session*> session);
[[nodiscard]] int32 CountFeaturedStickersHash(
not_null<Main::Session*> session);
[[nodiscard]] int32 CountSavedGifsHash(not_null<Main::Session*> session);
[[nodiscard]] inline uint32 HashInit() {
return 0;
}

View File

@@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Api {
SelfDestruct::SelfDestruct(not_null<ApiWrap*> api)
: _api(api->instance()) {
: _api(&api->instance()) {
}
void SelfDestruct::reload() {

View File

@@ -16,13 +16,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "data/data_file_origin.h"
#include "data/data_histories.h"
#include "data/data_changes.h"
#include "data/stickers/data_stickers.h"
#include "history/history.h"
#include "history/history_message.h" // NewMessageFlags.
#include "chat_helpers/message_field.h" // ConvertTextTagsToEntities.
#include "ui/text/text_entity.h" // TextWithEntities.
#include "ui/text_options.h" // Ui::ItemTextOptions.
#include "main/main_session.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
#include "storage/localimageloader.h"
#include "storage/file_upload.h"
#include "mainwidget.h"
#include "apiwrap.h"
#include "app.h"
@@ -93,6 +98,7 @@ void SendExistingMedia(
};
TextUtilities::Trim(caption);
auto sentEntities = EntitiesToMTP(
session,
caption.entities,
ConvertOption::SkipLocal);
if (!sentEntities.v.isEmpty()) {
@@ -166,9 +172,7 @@ void SendExistingMedia(
};
performRequest();
if (const auto main = App::main()) {
main->finishForwarding(message.action);
}
api->finishForwarding(message.action);
}
} // namespace
@@ -189,10 +193,7 @@ void SendExistingDocument(
document->stickerOrGifOrigin());
if (document->sticker()) {
if (const auto main = App::main()) {
main->incrementSticker(document);
document->owner().notifyRecentStickersUpdated();
}
document->owner().stickers().incrementSticker(document);
}
}
@@ -321,6 +322,7 @@ bool SendDice(Api::MessageToSend &message) {
).send();
return history->sendRequestId;
});
api->finishForwarding(message.action);
return true;
}
@@ -331,4 +333,203 @@ void FillMessagePostFlags(
InnerFillMessagePostFlags(action.options, peer, flags);
}
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 auto channelId = peerToChannel(file->to.peer);
const auto newId = oldId.value_or(
FullMsgId(channelId, session->data().nextLocalMessageId()));
auto groupId = file->album ? file->album->groupId : uint64(0);
if (file->album) {
const auto proj = [](const SendingAlbum::Item &item) {
return item.taskId;
};
const auto it = ranges::find(file->album->items, file->taskId, proj);
Assert(it != file->album->items.end());
it->msgId = newId;
}
file->edit = isEditing;
session->uploader().upload(newId, file);
const auto itemToEdit = isEditing
? session->data().message(newId)
: nullptr;
const auto history = session->data().history(file->to.peer);
const auto peer = history->peer;
auto action = Api::SendAction(history);
action.options = file->to.options;
action.clearDraft = false;
action.replyTo = file->to.replyTo;
action.generateLocal = true;
session->api().sendAction(action);
auto caption = TextWithEntities{
file->caption.text,
TextUtilities::ConvertTextTagsToEntities(file->caption.tags)
};
const auto prepareFlags = Ui::ItemTextOptions(
history,
session->user()).flags;
TextUtilities::PrepareForSending(caption, prepareFlags);
TextUtilities::Trim(caption);
auto localEntities = Api::EntitiesToMTP(session, caption.entities);
if (itemToEdit) {
if (const auto id = itemToEdit->groupId()) {
groupId = id.value;
}
}
auto flags = (isEditing ? MTPDmessage::Flags() : NewMessageFlags(peer))
| MTPDmessage::Flag::f_entities
| MTPDmessage::Flag::f_media;
auto clientFlags = NewMessageClientFlags();
if (file->to.replyTo) {
flags |= MTPDmessage::Flag::f_reply_to_msg_id;
}
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
const auto silentPost = file->to.options.silent;
Api::FillMessagePostFlags(action, peer, flags);
if (silentPost) {
flags |= MTPDmessage::Flag::f_silent;
}
if (groupId) {
flags |= MTPDmessage::Flag::f_grouped_id;
}
if (file->to.options.scheduled) {
flags |= MTPDmessage::Flag::f_from_scheduled;
} else {
clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry;
}
const auto messageFromId = channelPost ? 0 : session->userId();
const auto messagePostAuthor = channelPost
? session->user()->name
: QString();
if (file->type == SendMediaType::Photo) {
const auto photoFlags = MTPDmessageMediaPhoto::Flag::f_photo | 0;
const auto photo = MTP_messageMediaPhoto(
MTP_flags(photoFlags),
file->photo,
MTPint());
const auto mtpMessage = MTP_message(
MTP_flags(flags),
MTP_int(newId.msg),
MTP_int(messageFromId),
peerToMTP(file->to.peer),
MTPMessageFwdHeader(),
MTPint(),
MTP_int(file->to.replyTo),
MTP_int(HistoryItem::NewMessageDate(file->to.options.scheduled)),
MTP_string(caption.text),
photo,
MTPReplyMarkup(),
localEntities,
MTP_int(1),
MTPint(),
MTP_string(messagePostAuthor),
MTP_long(groupId),
//MTPMessageReactions(),
MTPVector<MTPRestrictionReason>());
if (itemToEdit) {
itemToEdit->savePreviousMedia();
itemToEdit->applyEdition(mtpMessage.c_message());
} else {
history->addNewMessage(
mtpMessage,
clientFlags,
NewMessageType::Unread);
}
} else if (file->type == SendMediaType::File) {
const auto documentFlags = MTPDmessageMediaDocument::Flag::f_document | 0;
const auto document = MTP_messageMediaDocument(
MTP_flags(documentFlags),
file->document,
MTPint());
const auto mtpMessage = MTP_message(
MTP_flags(flags),
MTP_int(newId.msg),
MTP_int(messageFromId),
peerToMTP(file->to.peer),
MTPMessageFwdHeader(),
MTPint(),
MTP_int(file->to.replyTo),
MTP_int(HistoryItem::NewMessageDate(file->to.options.scheduled)),
MTP_string(caption.text),
document,
MTPReplyMarkup(),
localEntities,
MTP_int(1),
MTPint(),
MTP_string(messagePostAuthor),
MTP_long(groupId),
//MTPMessageReactions(),
MTPVector<MTPRestrictionReason>());
if (itemToEdit) {
itemToEdit->savePreviousMedia();
itemToEdit->applyEdition(mtpMessage.c_message());
} else {
history->addNewMessage(
mtpMessage,
clientFlags,
NewMessageType::Unread);
}
} else if (file->type == SendMediaType::Audio) {
if (!peer->isChannel() || peer->isMegagroup()) {
flags |= MTPDmessage::Flag::f_media_unread;
}
const auto documentFlags = MTPDmessageMediaDocument::Flag::f_document | 0;
const auto document = MTP_messageMediaDocument(
MTP_flags(documentFlags),
file->document,
MTPint());
history->addNewMessage(
MTP_message(
MTP_flags(flags),
MTP_int(newId.msg),
MTP_int(messageFromId),
peerToMTP(file->to.peer),
MTPMessageFwdHeader(),
MTPint(),
MTP_int(file->to.replyTo),
MTP_int(
HistoryItem::NewMessageDate(file->to.options.scheduled)),
MTP_string(caption.text),
document,
MTPReplyMarkup(),
localEntities,
MTP_int(1),
MTPint(),
MTP_string(messagePostAuthor),
MTP_long(groupId),
//MTPMessageReactions(),
MTPVector<MTPRestrictionReason>()),
clientFlags,
NewMessageType::Unread);
// Voices can't be edited.
} else {
Unexpected("Type in sendFilesConfirmed.");
}
if (isEditing) {
return;
}
session->data().sendHistoryChangeNotifications();
session->changes().historyUpdated(
history,
Data::HistoryUpdate::Flag::MessageSent);
}
} // namespace Api

View File

@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class History;
class PhotoData;
class DocumentData;
struct FileLoadResult;
namespace Api {
@@ -30,4 +31,9 @@ void FillMessagePostFlags(
not_null<PeerData*> peer,
MTPDmessage::Flags &flags);
void SendConfirmedFile(
not_null<Main::Session*> session,
const std::shared_ptr<FileLoadResult> &file,
const std::optional<FullMsgId> &oldId);
} // namespace Api

View File

@@ -21,7 +21,7 @@ constexpr auto kRefreshAppConfigTimeout = 3 * crl::time(1000);
SensitiveContent::SensitiveContent(not_null<ApiWrap*> api)
: _session(&api->session())
, _api(api->instance())
, _api(&api->instance())
, _appConfigReloadTimer([=] { _session->account().appConfig().refresh(); }) {
}

View File

@@ -18,11 +18,13 @@ using namespace TextUtilities;
} // namespace
EntitiesInText EntitiesFromMTP(const QVector<MTPMessageEntity> &entities) {
EntitiesInText EntitiesFromMTP(
Main::Session *session,
const QVector<MTPMessageEntity> &entities) {
auto result = EntitiesInText();
if (!entities.isEmpty()) {
result.reserve(entities.size());
for_const (auto &entity, entities) {
for (const auto &entity : entities) {
switch (entity.type()) {
case mtpc_messageEntityUrl: { auto &d = entity.c_messageEntityUrl(); result.push_back({ EntityType::Url, d.voffset().v, d.vlength().v }); } break;
case mtpc_messageEntityTextUrl: { auto &d = entity.c_messageEntityTextUrl(); result.push_back({ EntityType::CustomUrl, d.voffset().v, d.vlength().v, Clean(qs(d.vurl())) }); } break;
@@ -32,28 +34,30 @@ EntitiesInText EntitiesFromMTP(const QVector<MTPMessageEntity> &entities) {
case mtpc_messageEntityPhone: break; // Skipping phones.
case mtpc_messageEntityMention: { auto &d = entity.c_messageEntityMention(); result.push_back({ EntityType::Mention, d.voffset().v, d.vlength().v }); } break;
case mtpc_messageEntityMentionName: {
auto &d = entity.c_messageEntityMentionName();
auto data = [&d] {
if (auto user = Auth().data().userLoaded(d.vuser_id().v)) {
return MentionNameDataFromFields({
d.vuser_id().v,
user->accessHash() });
const auto &d = entity.c_messageEntityMentionName();
const auto data = [&] {
if (session) {
if (const auto user = session->data().userLoaded(d.vuser_id().v)) {
return MentionNameDataFromFields({
d.vuser_id().v,
user->accessHash() });
}
}
return MentionNameDataFromFields(d.vuser_id().v);
};
result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data() });
}();
result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data });
} break;
case mtpc_inputMessageEntityMentionName: {
auto &d = entity.c_inputMessageEntityMentionName();
auto data = ([&d]() -> QString {
if (d.vuser_id().type() == mtpc_inputUserSelf) {
return MentionNameDataFromFields(Auth().userId());
const auto &d = entity.c_inputMessageEntityMentionName();
const auto data = [&] {
if (session && d.vuser_id().type() == mtpc_inputUserSelf) {
return MentionNameDataFromFields(session->userId());
} else if (d.vuser_id().type() == mtpc_inputUser) {
auto &user = d.vuser_id().c_inputUser();
return MentionNameDataFromFields({ user.vuser_id().v, user.vaccess_hash().v });
}
return QString();
})();
}();
if (!data.isEmpty()) {
result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data });
}
@@ -74,11 +78,12 @@ EntitiesInText EntitiesFromMTP(const QVector<MTPMessageEntity> &entities) {
}
MTPVector<MTPMessageEntity> EntitiesToMTP(
not_null<Main::Session*> session,
const EntitiesInText &entities,
ConvertOption option) {
auto v = QVector<MTPMessageEntity>();
v.reserve(entities.size());
for_const (auto &entity, entities) {
for (const auto &entity : entities) {
if (entity.length() <= 0) continue;
if (option == ConvertOption::SkipLocal
&& entity.type() != EntityType::Bold
@@ -103,15 +108,15 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(
case EntityType::Cashtag: v.push_back(MTP_messageEntityCashtag(offset, length)); break;
case EntityType::Mention: v.push_back(MTP_messageEntityMention(offset, length)); break;
case EntityType::MentionName: {
auto inputUser = ([](const QString &data) -> MTPInputUser {
auto inputUser = [&](const QString &data) -> MTPInputUser {
auto fields = MentionNameDataToFields(data);
if (fields.userId == Auth().userId()) {
if (session && fields.userId == session->userId()) {
return MTP_inputUserSelf();
} else if (fields.userId) {
return MTP_inputUser(MTP_int(fields.userId), MTP_long(fields.accessHash));
}
return MTP_inputUserEmpty();
})(entity.data());
}(entity.data());
if (inputUser.type() != mtpc_inputUserEmpty) {
v.push_back(MTP_inputMessageEntityMentionName(offset, length, inputUser));
}

View File

@@ -9,14 +9,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text_entity.h"
namespace Main {
class Session;
} // namespace Main
namespace Api {
EntitiesInText EntitiesFromMTP(const QVector<MTPMessageEntity> &entities);
enum class ConvertOption {
WithLocal,
SkipLocal,
};
MTPVector<MTPMessageEntity> EntitiesToMTP(
[[nodiscard]] EntitiesInText EntitiesFromMTP(
Main::Session *session,
const QVector<MTPMessageEntity> &entities);
[[nodiscard]] MTPVector<MTPMessageEntity> EntitiesToMTP(
not_null<Main::Session*> session,
const EntitiesInText &entities,
ConvertOption option = ConvertOption::WithLocal);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,172 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/data_pts_waiter.h"
#include "base/timer.h"
class RPCError;
class ApiWrap;
class History;
namespace Main {
class Session;
} // namespace Main
namespace Api {
class Updates final {
public:
explicit Updates(not_null<Main::Session*> session);
[[nodiscard]] Main::Session &session() const;
[[nodiscard]] ApiWrap &api() const;
void applyUpdates(
const MTPUpdates &updates,
uint64 sentMessageRandomId = 0);
void applyUpdatesNoPtsCheck(const MTPUpdates &updates);
void applyUpdateNoPtsCheck(const MTPUpdate &update);
void updateOnline();
[[nodiscard]] bool isIdle() const;
void checkIdleFinish();
bool lastWasOnline() const;
crl::time lastSetOnline() const;
bool isQuitPrevent();
bool updateAndApply(int32 pts, int32 ptsCount, const MTPUpdates &updates);
bool updateAndApply(int32 pts, int32 ptsCount, const MTPUpdate &update);
bool updateAndApply(int32 pts, int32 ptsCount);
void checkLastUpdate(bool afterSleep);
// ms <= 0 - stop timer
void ptsWaiterStartTimerFor(ChannelData *channel, crl::time ms);
void getDifference();
void requestChannelRangeDifference(not_null<History*> history);
void addActiveChat(rpl::producer<PeerData*> chat);
private:
enum class ChannelDifferenceRequest {
Unknown,
PtsGapOrShortPoll,
AfterFail,
};
struct ActiveChatTracker {
PeerData *peer = nullptr;
rpl::lifetime lifetime;
};
void channelRangeDifferenceSend(
not_null<ChannelData*> channel,
MsgRange range,
int32 pts);
void channelRangeDifferenceDone(
not_null<ChannelData*> channel,
MsgRange range,
const MTPupdates_ChannelDifference &result);
void updateOnline(bool gotOtherOffline);
void sendPing();
void getDifferenceByPts();
void getDifferenceAfterFail();
[[nodiscard]] bool requestingDifference() const {
return _ptsWaiter.requesting();
}
void getChannelDifference(
not_null<ChannelData*> channel,
ChannelDifferenceRequest from = ChannelDifferenceRequest::Unknown);
void differenceDone(const MTPupdates_Difference &result);
void differenceFail(const RPCError &error);
void feedDifference(
const MTPVector<MTPUser> &users,
const MTPVector<MTPChat> &chats,
const MTPVector<MTPMessage> &msgs,
const MTPVector<MTPUpdate> &other);
void stateDone(const MTPupdates_State &state);
void setState(int32 pts, int32 date, int32 qts, int32 seq);
void channelDifferenceDone(
not_null<ChannelData*> channel,
const MTPupdates_ChannelDifference &diff);
void channelDifferenceFail(
not_null<ChannelData*> channel,
const RPCError &error);
void failDifferenceStartTimerFor(ChannelData *channel);
void feedChannelDifference(const MTPDupdates_channelDifference &data);
void mtpUpdateReceived(const MTPUpdates &updates);
void mtpNewSessionCreated();
void feedUpdateVector(
const MTPVector<MTPUpdate> &updates,
bool skipMessageIds = false);
// Doesn't call sendHistoryChangeNotifications itself.
void feedMessageIds(const MTPVector<MTPUpdate> &updates);
// Doesn't call sendHistoryChangeNotifications itself.
void feedUpdate(const MTPUpdate &update);
bool whenGetDiffChanged(
ChannelData *channel,
int32 ms,
base::flat_map<not_null<ChannelData*>, crl::time> &whenMap,
crl::time &curTime);
const not_null<Main::Session*> _session;
int32 _updatesDate = 0;
int32 _updatesQts = -1;
int32 _updatesSeq = 0;
base::Timer _noUpdatesTimer;
base::Timer _onlineTimer;
PtsWaiter _ptsWaiter;
base::flat_map<not_null<ChannelData*>, crl::time> _whenGetDiffByPts;
base::flat_map<not_null<ChannelData*>, crl::time> _whenGetDiffAfterFail;
crl::time _getDifferenceTimeByPts = 0;
crl::time _getDifferenceTimeAfterFail = 0;
base::Timer _byPtsTimer;
base::flat_map<int32, MTPUpdates> _bySeqUpdates;
base::Timer _bySeqTimer;
base::Timer _byMinChannelTimer;
// growing timeout for getDifference calls, if it fails
crl::time _failDifferenceTimeout = 1;
// growing timeout for getChannelDifference calls, if it fails
base::flat_map<
not_null<ChannelData*>,
crl::time> _channelFailDifferenceTimeout;
base::Timer _failDifferenceTimer;
base::flat_map<
not_null<ChannelData*>,
mtpRequestId> _rangeDifferenceRequests;
crl::time _lastUpdateTime = 0;
bool _handlingChannelDifference = false;
base::flat_map<int, ActiveChatTracker> _activeChats;
mtpRequestId _onlineRequest = 0;
base::Timer _idleFinishTimer;
crl::time _lastSetOnline = 0;
bool _lastWasOnline = false;
bool _isIdle = false;
rpl::lifetime _lifetime;
};
} // namespace Api

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/flat_map.h"
#include "base/flat_set.h"
#include "mtproto/sender.h"
#include "chat_helpers/stickers_set.h"
#include "data/stickers/data_stickers_set.h"
#include "data/data_messages.h"
class TaskQueue;
@@ -38,6 +38,7 @@ namespace Storage {
enum class SharedMediaType : signed char;
struct PreparedList;
class DownloadMtprotoTask;
class Account;
} // namespace Storage
namespace Dialogs {
@@ -65,6 +66,8 @@ inline QString ToString(uint64 value) {
} // namespace details
class Updates;
template <
typename ...Types,
typename = std::enable_if_t<(sizeof...(Types) > 0)>>
@@ -136,7 +139,9 @@ public:
explicit ApiWrap(not_null<Main::Session*> session);
~ApiWrap();
Main::Session &session() const;
[[nodiscard]] Main::Session &session() const;
[[nodiscard]] Storage::Account &local() const;
[[nodiscard]] Api::Updates &updates() const;
void applyUpdates(
const MTPUpdates &updates,
@@ -152,6 +157,8 @@ public:
MTPInputNotifyPeer peer,
const MTPPeerNotifySettings &settings);
void saveCurrentDraftToCloud();
void savePinnedOrder(Data::Folder *folder);
void toggleHistoryArchived(
not_null<History*> history,
@@ -192,7 +199,6 @@ public:
void requestBots(not_null<ChannelData*> channel);
void requestAdmins(not_null<ChannelData*> channel);
void requestParticipantsCountDelayed(not_null<ChannelData*> channel);
void requestChannelRangeDifference(not_null<History*> history);
using UpdatedFileReferences = Data::UpdatedFileReferences;
using FileReferencesHandler = FnMut<void(const UpdatedFileReferences&)>;
@@ -256,12 +262,11 @@ public:
void clearWebPageRequest(WebPageData *page);
void clearWebPageRequests();
void requestAttachedStickerSets(not_null<PhotoData*> photo);
void scheduleStickerSetRequest(uint64 setId, uint64 access);
void requestStickerSets();
void saveStickerSets(
const Stickers::Order &localOrder,
const Stickers::Order &localRemoved);
const Data::StickersSetsOrder &localOrder,
const Data::StickersSetsOrder &localRemoved);
void updateStickers();
void requestRecentStickersForce();
void setGroupStickerSet(
@@ -308,9 +313,6 @@ public:
bool isQuitPrevent();
void applyUpdatesNoPtsCheck(const MTPUpdates &updates);
void applyUpdateNoPtsCheck(const MTPUpdate &update);
void jumpToDate(Dialogs::Key chat, const QDate &date);
void preloadEnoughUnreadMentions(not_null<History*> history);
@@ -366,11 +368,11 @@ public:
not_null<PeerData*> peer,
const std::vector<not_null<UserData*>> &users);
rpl::producer<SendAction> sendActions() const {
return _sendActions.events();
}
void sendAction(const SendAction &action);
void finishForwarding(const SendAction &action);
void forwardMessages(
HistoryItemsList &&items,
const SendAction &action,
@@ -552,15 +554,6 @@ private:
mtpRequestId req);
void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result);
void channelRangeDifferenceSend(
not_null<ChannelData*> channel,
MsgRange range,
int32 pts);
void channelRangeDifferenceDone(
not_null<ChannelData*> channel,
MsgRange range,
const MTPupdates_ChannelDifference &result);
void stickerSetDisenabled(mtpRequestId requestId);
void stickersSaveOrder();
@@ -707,10 +700,6 @@ private:
base::flat_set<not_null<ChannelData*>> _selfParticipantRequests;
base::flat_map<
not_null<ChannelData*>,
mtpRequestId> _rangeDifferenceRequests;
QMap<WebPageData*, mtpRequestId> _webPagesPending;
base::Timer _webPagesTimer;
@@ -724,7 +713,7 @@ private:
base::Timer _draftsSaveTimer;
base::flat_set<mtpRequestId> _stickerSetDisenableRequests;
Stickers::Order _stickersOrder;
Data::StickersSetsOrder _stickersOrder;
mtpRequestId _stickersReorderRequestId = 0;
mtpRequestId _stickersClearRecentRequestId = 0;
@@ -856,8 +845,6 @@ private:
std::optional<bool> _contactSignupSilent;
rpl::event_stream<bool> _contactSignupSilentChanges;
mtpRequestId _attachedStickerSetsRequestId = 0;
base::flat_map<FullMsgId, QString> _unlikelyMessageLinks;
};

View File

@@ -39,7 +39,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwidget.h"
#include "apiwrap.h"
#include "numbers.h"
#include "observer_peer.h"
#include "main/main_session.h"
#include "styles/style_boxes.h"
#include "styles/style_overview.h"
@@ -207,16 +206,16 @@ namespace App {
if (update.paletteChanged()) {
createPaletteCorners();
if (App::main()) {
App::main()->updateScrollColors();
if (const auto m = App::main()) { // multi good
m->updateScrollColors();
}
HistoryView::serviceColorsUpdated();
} else if (update.type == Update::Type::New) {
prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg);
prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected);
if (App::main()) {
App::main()->updateScrollColors();
if (const auto m = App::main()) { // multi good
m->updateScrollColors();
}
HistoryView::serviceColorsUpdated();
}

View File

@@ -34,11 +34,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat.h"
#include "data/data_user.h"
#include "data/data_session.h"
#include "data/data_changes.h"
#include "data/data_cloud_file.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "apiwrap.h"
#include "observer_peer.h"
#include "main/main_session.h"
#include "facades.h"
#include "styles/style_layers.h"
@@ -118,9 +118,11 @@ style::InputField CreateBioFieldStyle() {
return result;
}
QString PeerFloodErrorText(PeerFloodType type) {
auto link = textcmdLink(
Core::App().createInternalLinkFull(qsl("spambot")),
QString PeerFloodErrorText(
not_null<Main::Session*> session,
PeerFloodType type) {
const auto link = textcmdLink(
session->createInternalLinkFull(qsl("spambot")),
tr::lng_cant_more_info(tr::now));
if (type == PeerFloodType::InviteGroup) {
return tr::lng_cant_invite_not_contact(tr::now, lt_more_info, link);
@@ -170,8 +172,7 @@ void ShowAddParticipantsError(
return;
}
}
const auto bot = ranges::find_if(users, &UserData::isBot);
const auto hasBot = (bot != end(users));
const auto hasBot = ranges::any_of(users, &UserData::isBot);
const auto text = [&] {
if (error == qstr("USER_BOT")) {
return tr::lng_cant_invite_bot_to_channel(tr::now);
@@ -190,10 +191,10 @@ void ShowAddParticipantsError(
} else if (error == qstr("BOT_GROUPS_BLOCKED")) {
return tr::lng_error_cant_add_bot(tr::now);
} else if (error == qstr("PEER_FLOOD")) {
const auto isGroup = (chat->isChat() || chat->isMegagroup());
return PeerFloodErrorText(isGroup
const auto type = (chat->isChat() || chat->isMegagroup())
? PeerFloodType::InviteGroup
: PeerFloodType::InviteChannel);
: PeerFloodType::InviteChannel;
return PeerFloodErrorText(&chat->session(), type);
} else if (error == qstr("ADMINS_TOO_MUCH")) {
return ((chat->isChat() || chat->isMegagroup())
? tr::lng_error_admin_limit
@@ -453,7 +454,7 @@ GroupInfoBox::GroupInfoBox(
const QString &title,
Fn<void(not_null<ChannelData*>)> channelDone)
: _navigation(navigation)
, _api(_navigation->session().api().instance())
, _api(&_navigation->session().mtp())
, _type(type)
, _initialTitle(title)
, _channelDone(std::move(channelDone)) {
@@ -479,7 +480,7 @@ void GroupInfoBox::prepare() {
_title->setMaxLength(kMaxGroupChannelTitle);
_title->setInstantReplaces(Ui::InstantReplaces::Default());
_title->setInstantReplacesEnabled(
_navigation->session().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue());
Ui::Emoji::SuggestionsController::Init(
getDelegate()->outerContainer(),
_title,
@@ -495,8 +496,9 @@ void GroupInfoBox::prepare() {
_description->setMaxLength(kMaxChannelDescription);
_description->setInstantReplaces(Ui::InstantReplaces::Default());
_description->setInstantReplacesEnabled(
_navigation->session().settings().replaceEmojiValue());
_description->setSubmitSettings(_navigation->session().settings().sendSubmitWay());
Core::App().settings().replaceEmojiValue());
_description->setSubmitSettings(
Core::App().settings().sendSubmitWay());
connect(_description, &Ui::InputField::resized, [=] { descriptionResized(); });
connect(_description, &Ui::InputField::submitted, [=] { submit(); });
@@ -598,7 +600,9 @@ void GroupInfoBox::createGroup(
} else if (error.type() == qstr("PEER_FLOOD")) {
Ui::show(
Box<InformBox>(
PeerFloodErrorText(PeerFloodType::InviteGroup)),
PeerFloodErrorText(
&_navigation->session(),
PeerFloodType::InviteGroup)),
Ui::LayerOption::KeepOther);
} else if (error.type() == qstr("USER_RESTRICTED")) {
Ui::show(
@@ -750,6 +754,7 @@ SetupChannelBox::SetupChannelBox(
bool existing)
: _navigation(navigation)
, _channel(channel)
, _api(&_channel->session().mtp())
, _existing(existing)
, _privacyGroup(
std::make_shared<Ui::RadioenumGroup<Privacy>>(Privacy::Public))
@@ -789,7 +794,12 @@ SetupChannelBox::SetupChannelBox(
: tr::lng_create_private_channel_about)(tr::now),
_defaultOptions,
_aboutPublicWidth)
, _link(this, st::setupChannelLink, nullptr, channel->username, true) {
, _link(
this,
st::setupChannelLink,
nullptr,
channel->username,
channel->session().createInternalLink(QString())) {
}
void SetupChannelBox::prepare() {
@@ -797,12 +807,12 @@ void SetupChannelBox::prepare() {
setMouseTracking(true);
_checkRequestId = MTP::send(
MTPchannels_CheckUsername(
_channel->inputChannel,
MTP_string("preston")),
RPCDoneHandlerPtr(),
rpcFail(&SetupChannelBox::onFirstCheckFail));
_checkRequestId = _api.request(MTPchannels_CheckUsername(
_channel->inputChannel,
MTP_string("preston")
)).fail([=](const RPCError &error) {
firstCheckFail(error);
}).send();
addButton(tr::lng_settings_save(), [=] { save(); });
addButton(
@@ -816,11 +826,13 @@ void SetupChannelBox::prepare() {
connect(&_checkTimer, &QTimer::timeout, [=] { check(); });
_privacyGroup->setChangedCallback([this](Privacy value) { privacyChanged(value); });
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::InviteLinkChanged, [this](const Notify::PeerUpdate &update) {
if (update.peer == _channel) {
rtlupdate(_invitationLink);
}
}));
_channel->session().changes().peerUpdates(
_channel,
Data::PeerUpdate::Flag::InviteLink
) | rpl::start_with_next([=] {
rtlupdate(_invitationLink);
}, lifetime());
boxClosing() | rpl::start_with_next([=] {
if (!_existing) {
@@ -950,12 +962,22 @@ void SetupChannelBox::updateSelected(const QPoint &cursorGlobalPosition) {
}
void SetupChannelBox::save() {
const auto saveUsername = [&](const QString &link) {
_sentUsername = link;
_saveRequestId = _api.request(MTPchannels_UpdateUsername(
_channel->inputChannel,
MTP_string(_sentUsername)
)).done([=](const MTPBool &result) {
updateDone(result);
}).fail([=](const RPCError &error) {
updateFail(error);
}).send();
};
if (_saveRequestId) {
return;
} else if (_privacyGroup->value() == Privacy::Private) {
if (_existing) {
_sentUsername = QString();
_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
saveUsername(QString());
} else {
closeBox();
}
@@ -966,8 +988,7 @@ void SetupChannelBox::save() {
_link->showError();
return;
}
_sentUsername = link;
_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
saveUsername(link);
}
}
@@ -1010,17 +1031,19 @@ void SetupChannelBox::handleChange() {
void SetupChannelBox::check() {
if (_checkRequestId) {
MTP::cancel(_checkRequestId);
_channel->session().api().request(_checkRequestId).cancel();
}
QString link = _link->text().trimmed();
if (link.size() >= kMinUsernameLength) {
_checkUsername = link;
_checkRequestId = MTP::send(
MTPchannels_CheckUsername(
_channel->inputChannel,
MTP_string(link)),
rpcDone(&SetupChannelBox::onCheckDone),
rpcFail(&SetupChannelBox::onCheckFail));
_checkRequestId = _api.request(MTPchannels_CheckUsername(
_channel->inputChannel,
MTP_string(link)
)).done([=](const MTPBool &result) {
checkDone(result);
}).fail([=](const RPCError &error) {
checkFail(error);
}).send();
}
}
@@ -1053,38 +1076,36 @@ void SetupChannelBox::privacyChanged(Privacy value) {
update();
}
void SetupChannelBox::onUpdateDone(const MTPBool &result) {
void SetupChannelBox::updateDone(const MTPBool &result) {
_channel->setName(TextUtilities::SingleLine(_channel->name), _sentUsername);
closeBox();
}
bool SetupChannelBox::onUpdateFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
void SetupChannelBox::updateFail(const RPCError &error) {
_saveRequestId = 0;
QString err(error.type());
if (err == "USERNAME_NOT_MODIFIED" || _sentUsername == _channel->username) {
_channel->setName(TextUtilities::SingleLine(_channel->name), TextUtilities::SingleLine(_sentUsername));
if (err == "USERNAME_NOT_MODIFIED"
|| _sentUsername == _channel->username) {
_channel->setName(
TextUtilities::SingleLine(_channel->name),
TextUtilities::SingleLine(_sentUsername));
closeBox();
return true;
} else if (err == "USERNAME_INVALID") {
_link->setFocus();
_link->showError();
_errorText = tr::lng_create_channel_link_invalid(tr::now);
update();
return true;
} else if (err == "USERNAME_OCCUPIED" || err == "USERNAMES_UNAVAILABLE") {
_link->setFocus();
_link->showError();
_errorText = tr::lng_create_channel_link_occupied(tr::now);
update();
return true;
} else {
_link->setFocus();
}
_link->setFocus();
return true;
}
void SetupChannelBox::onCheckDone(const MTPBool &result) {
void SetupChannelBox::checkDone(const MTPBool &result) {
_checkRequestId = 0;
QString newError = (mtpIsTrue(result) || _checkUsername == _channel->username) ? QString() : tr::lng_create_channel_link_occupied(tr::now);
QString newGood = newError.isEmpty() ? tr::lng_create_channel_link_available(tr::now) : QString();
@@ -1095,14 +1116,11 @@ void SetupChannelBox::onCheckDone(const MTPBool &result) {
}
}
bool SetupChannelBox::onCheckFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
void SetupChannelBox::checkFail(const RPCError &error) {
_checkRequestId = 0;
QString err(error.type());
if (err == qstr("CHANNEL_PUBLIC_GROUP_NA")) {
Ui::hideLayer();
return true;
} else if (err == qstr("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) {
if (_existing) {
showRevokePublicLinkBoxForEdit();
@@ -1110,19 +1128,16 @@ bool SetupChannelBox::onCheckFail(const RPCError &error) {
_tooMuchUsernames = true;
_privacyGroup->setValue(Privacy::Private);
}
return true;
} else if (err == qstr("USERNAME_INVALID")) {
_errorText = tr::lng_create_channel_link_invalid(tr::now);
update();
return true;
} else if (err == qstr("USERNAME_OCCUPIED") && _checkUsername != _channel->username) {
_errorText = tr::lng_create_channel_link_occupied(tr::now);
update();
return true;
} else {
_goodText = QString();
_link->setFocus();
}
_goodText = QString();
_link->setFocus();
return true;
}
void SetupChannelBox::showRevokePublicLinkBoxForEdit() {
@@ -1142,14 +1157,11 @@ void SetupChannelBox::showRevokePublicLinkBoxForEdit() {
Ui::LayerOption::KeepOther);
}
bool SetupChannelBox::onFirstCheckFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
void SetupChannelBox::firstCheckFail(const RPCError &error) {
_checkRequestId = 0;
const auto &type = error.type();
if (type == qstr("CHANNEL_PUBLIC_GROUP_NA")) {
Ui::hideLayer();
return true;
} else if (type == qstr("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) {
if (_existing) {
showRevokePublicLinkBoxForEdit();
@@ -1157,15 +1169,15 @@ bool SetupChannelBox::onFirstCheckFail(const RPCError &error) {
_tooMuchUsernames = true;
_privacyGroup->setValue(Privacy::Private);
}
return true;
} else {
_goodText = QString();
_link->setFocus();
}
_goodText = QString();
_link->setFocus();
return true;
}
EditNameBox::EditNameBox(QWidget*, not_null<UserData*> user)
: _user(user)
, _api(&_user->session().mtp())
, _first(this, st::defaultInputField, tr::lng_signup_firstname(), _user->firstName)
, _last(this, st::defaultInputField, tr::lng_signup_lastname(), _user->lastName)
, _invertOrder(langFirstNameGoesSecond()) {
@@ -1248,14 +1260,16 @@ void EditNameBox::save() {
_sentName = first;
auto flags = MTPaccount_UpdateProfile::Flag::f_first_name
| MTPaccount_UpdateProfile::Flag::f_last_name;
_requestId = MTP::send(
MTPaccount_UpdateProfile(
MTP_flags(flags),
MTP_string(first),
MTP_string(last),
MTPstring()),
rpcDone(&EditNameBox::saveSelfDone),
rpcFail(&EditNameBox::saveSelfFail));
_requestId = _api.request(MTPaccount_UpdateProfile(
MTP_flags(flags),
MTP_string(first),
MTP_string(last),
MTPstring()
)).done([=](const MTPUser &result) {
saveSelfDone(result);
}).fail([=](const RPCError &error) {
saveSelfFail(error);
}).send();
}
void EditNameBox::saveSelfDone(const MTPUser &user) {
@@ -1263,27 +1277,22 @@ void EditNameBox::saveSelfDone(const MTPUser &user) {
closeBox();
}
bool EditNameBox::saveSelfFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
void EditNameBox::saveSelfFail(const RPCError &error) {
auto err = error.type();
auto first = TextUtilities::SingleLine(_first->getLastText().trimmed());
auto last = TextUtilities::SingleLine(_last->getLastText().trimmed());
if (err == "NAME_NOT_MODIFIED") {
_user->setName(first, last, QString(), TextUtilities::SingleLine(_user->username));
closeBox();
return true;
} else if (err == "FIRSTNAME_INVALID") {
_first->setFocus();
_first->showError();
return true;
} else if (err == "LASTNAME_INVALID") {
_last->setFocus();
_last->showError();
return true;
} else {
_first->setFocus();
}
_first->setFocus();
return true;
}
RevokePublicLinkBox::Inner::Inner(
@@ -1292,7 +1301,7 @@ RevokePublicLinkBox::Inner::Inner(
Fn<void()> revokeCallback)
: TWidget(parent)
, _session(session)
, _api(_session->api().instance())
, _api(&_session->mtp())
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _revokeWidth(st::normalFont->width(tr::lng_channels_too_much_public_revoke(tr::now)))
, _revokeCallback(std::move(revokeCallback)) {
@@ -1320,7 +1329,7 @@ RevokePublicLinkBox::Inner::Inner(
Ui::NameTextOptions());
row.status.setText(
st::defaultTextStyle,
Core::App().createInternalLink(
_session->createInternalLink(
textcmdLink(1, peer->userName())),
Ui::DialogTextOptions());
_rows.push_back(std::move(row));
@@ -1355,7 +1364,10 @@ void RevokePublicLinkBox::prepare() {
addButton(tr::lng_cancel(), [=] { closeBox(); });
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
_inner->resizeToWidth(st::boxWideWidth);
setDimensions(st::boxWideWidth, _innerTop + _inner->height());
@@ -1401,7 +1413,7 @@ void RevokePublicLinkBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
auto text = text_method(
tr::now,
lt_link,
Core::App().createInternalLink(pressed->userName()),
_session->createInternalLink(pressed->userName()),
lt_group,
pressed->name);
auto confirmText = tr::lng_channels_too_much_public_revoke(tr::now);

View File

@@ -46,9 +46,11 @@ enum class PeerFloodType {
InviteChannel,
};
style::InputField CreateBioFieldStyle();
[[nodiscard]] style::InputField CreateBioFieldStyle();
QString PeerFloodErrorText(PeerFloodType type);
[[nodiscard]] QString PeerFloodErrorText(
not_null<Main::Session*> session,
PeerFloodType type);
void ShowAddParticipantsError(
const QString &error,
not_null<PeerData*> chat,
@@ -140,9 +142,8 @@ private:
};
class SetupChannelBox
class SetupChannelBox final
: public Ui::BoxContent
, public RPCSender
, private base::Subscriber {
public:
SetupChannelBox(
@@ -174,12 +175,12 @@ private:
void check();
void save();
void onUpdateDone(const MTPBool &result);
bool onUpdateFail(const RPCError &error);
void updateDone(const MTPBool &result);
void updateFail(const RPCError &error);
void onCheckDone(const MTPBool &result);
bool onCheckFail(const RPCError &error);
bool onFirstCheckFail(const RPCError &error);
void checkDone(const MTPBool &result);
void checkFail(const RPCError &error);
void firstCheckFail(const RPCError &error);
void updateMaxHeight();
@@ -187,6 +188,7 @@ private:
const not_null<Window::SessionNavigation*> _navigation;
const not_null<ChannelData*> _channel;
MTP::Sender _api;
bool _existing = false;
@@ -210,7 +212,7 @@ private:
};
class EditNameBox : public Ui::BoxContent, public RPCSender {
class EditNameBox : public Ui::BoxContent {
public:
EditNameBox(QWidget*, not_null<UserData*> user);
@@ -224,9 +226,10 @@ private:
void submit();
void save();
void saveSelfDone(const MTPUser &user);
bool saveSelfFail(const RPCError &error);
void saveSelfFail(const RPCError &error);
not_null<UserData*> _user;
const not_null<UserData*> _user;
MTP::Sender _api;
object_ptr<Ui::InputField> _first;
object_ptr<Ui::InputField> _last;
@@ -238,9 +241,8 @@ private:
};
class RevokePublicLinkBox
class RevokePublicLinkBox final
: public Ui::BoxContent
, public RPCSender
, private base::Subscriber {
public:
RevokePublicLinkBox(

View File

@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "main/main_session_settings.h"
#include "data/data_session.h"
#include "data/data_auto_download.h"
#include "ui/widgets/continuous_sliders.h"
@@ -171,26 +172,26 @@ void AutoDownloadBox::setupContent() {
}) | ranges::view::transform([](Pair pair) {
return pair.first;
});
const auto less = ranges::find_if(*autoPlayValues, [&](Pair pair) {
const auto less = ranges::any_of(*autoPlayValues, [&](Pair pair) {
const auto [type, enabled] = pair;
const auto value = enabled ? limitByType(type) : 0;
return value < settings->bytesLimit(_source, type);
}) != end(*autoPlayValues);
});
const auto allowMoreTypes = base::flat_set<Type>(
allowMore.begin(),
allowMore.end());
const auto changed = ranges::find_if(values, [&](Pair pair) {
const auto changed = ranges::any_of(values, [&](Pair pair) {
const auto [type, enabled] = pair;
const auto value = enabled ? limitByType(type) : 0;
return value != settings->bytesLimit(_source, type);
}) != end(values);
});
const auto &kHidden = kStreamedTypes;
const auto hiddenChanged = ranges::find_if(kHidden, [&](Type type) {
const auto hiddenChanged = ranges::any_of(kHidden, [&](Type type) {
const auto now = settings->bytesLimit(_source, type);
return (now > 0) && (now != limitByType(type));
}) != end(kHidden);
});
if (changed) {
for (const auto [type, enabled] : values) {
@@ -210,17 +211,16 @@ void AutoDownloadBox::setupContent() {
}
}
if (changed || hiddenChanged) {
Local::writeUserSettings();
_session->saveSettingsDelayed();
}
if (allowMoreTypes.contains(Type::Photo)) {
_session->data().photoLoadSettingsChanged();
}
if (ranges::find_if(allowMoreTypes, _1 != Type::Photo)
!= allowMoreTypes.end()) {
if (ranges::any_of(allowMoreTypes, _1 != Type::Photo)) {
_session->data().documentLoadSettingsChanged();
}
if (less) {
_session->data().checkPlayingVideoFiles();
_session->data().checkPlayingAnimations();
}
closeBox();
});

View File

@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "storage/localstorage.h"
#include "core/application.h"
#include "mainwindow.h"
#include "ui/widgets/checkbox.h"
#include "facades.h"
@@ -26,7 +27,8 @@ void AutoLockBox::prepare() {
auto options = { 60, 300, 3600, 18000 };
auto group = std::make_shared<Ui::RadiobuttonGroup>(Global::AutoLock());
auto group = std::make_shared<Ui::RadiobuttonGroup>(
Core::App().settings().autoLock());
auto y = st::boxOptionListPadding.top() + st::autolockButton.margin.top();
auto count = int(options.size());
_options.reserve(count);
@@ -41,10 +43,10 @@ void AutoLockBox::prepare() {
}
void AutoLockBox::durationChanged(int seconds) {
Global::SetAutoLock(seconds);
Local::writeUserSettings();
Core::App().settings().setAutoLock(seconds);
Core::App().saveSettingsDelayed();
Global::RefLocalPasscodeChanged().notify();
_session->checkAutoLock();
Core::App().checkAutoLock();
closeBox();
}

View File

@@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document_media.h"
#include "boxes/background_preview_box.h"
#include "boxes/confirm_box.h"
#include "window/window_session_controller.h"
#include "app.h"
#include "styles/style_overview.h"
#include "styles/style_layers.h"
@@ -131,8 +132,10 @@ private:
};
BackgroundBox::BackgroundBox(QWidget*, not_null<Main::Session*> session)
: _session(session) {
BackgroundBox::BackgroundBox(
QWidget*,
not_null<Window::SessionController*> controller)
: _controller(controller) {
}
void BackgroundBox::prepare() {
@@ -143,13 +146,13 @@ void BackgroundBox::prepare() {
setDimensions(st::boxWideWidth, st::boxMaxListHeight);
_inner = setInnerWidget(
object_ptr<Inner>(this, _session),
object_ptr<Inner>(this, &_controller->session()),
st::backgroundScroll);
_inner->chooseEvents(
) | rpl::start_with_next([=](const Data::WallPaper &paper) {
Ui::show(
Box<BackgroundPreviewBox>(_session, paper),
Box<BackgroundPreviewBox>(_controller, paper),
Ui::LayerOption::KeepOther);
}, _inner->lifetime());
@@ -161,7 +164,7 @@ void BackgroundBox::prepare() {
void BackgroundBox::removePaper(const Data::WallPaper &paper) {
const auto box = std::make_shared<QPointer<Ui::BoxContent>>();
const auto session = _session;
const auto session = &_controller->session();
const auto remove = [=, weak = Ui::MakeWeak(this)]{
if (*box) {
(*box)->closeBox();
@@ -171,7 +174,7 @@ void BackgroundBox::removePaper(const Data::WallPaper &paper) {
}
session->data().removeWallpaper(paper);
session->api().request(MTPaccount_SaveWallPaper(
paper.mtpInput(),
paper.mtpInput(session),
MTP_bool(true),
paper.mtpSettings()
)).send();
@@ -190,7 +193,7 @@ BackgroundBox::Inner::Inner(
not_null<Main::Session*> session)
: RpWidget(parent)
, _session(session)
, _api(_session->api().instance())
, _api(&_session->mtp())
, _check(std::make_unique<Ui::RoundCheckbox>(st::overviewCheck, [=] { update(); })) {
_check->setChecked(true, anim::type::instant);
if (_session->data().wallpapers().empty()) {
@@ -200,7 +203,10 @@ BackgroundBox::Inner::Inner(
}
requestPapers();
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
using Update = Window::Theme::BackgroundUpdate;
subscribe(Window::Theme::Background(), [=](const Update &update) {
if (update.paletteChanged()) {

View File

@@ -9,9 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h"
namespace Main {
class Session;
} // namespace Main
namespace Window {
class SessionController;
} // namespace Window
namespace Data {
class WallPaper;
@@ -19,7 +19,7 @@ class WallPaper;
class BackgroundBox : public Ui::BoxContent {
public:
BackgroundBox(QWidget*, not_null<Main::Session*> session);
BackgroundBox(QWidget*, not_null<Window::SessionController*> controller);
protected:
void prepare() override;
@@ -29,7 +29,7 @@ private:
void removePaper(const Data::WallPaper &paper);
const not_null<Main::Session*> _session;
const not_null<Window::SessionController*> _controller;
QPointer<Inner> _inner;

View File

@@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unixtime.h"
#include "boxes/confirm_box.h"
#include "boxes/background_preview_box.h"
#include "window/window_session_controller.h"
#include "app.h"
#include "styles/style_history.h"
#include "styles/style_layers.h"
@@ -270,14 +271,14 @@ bool ServiceCheck::checkRippleStartPosition(QPoint position) const {
if (slug.isEmpty() || slug.size() > kMaxWallPaperSlugLength) {
return false;
}
return ranges::find_if(slug, [](QChar ch) {
return ranges::none_of(slug, [](QChar ch) {
return (ch != '.')
&& (ch != '_')
&& (ch != '-')
&& (ch < '0' || ch > '9')
&& (ch < 'a' || ch > 'z')
&& (ch < 'A' || ch > 'Z');
}) == slug.end();
});
}
AdminLog::OwnedItem GenerateTextItem(
@@ -396,18 +397,19 @@ QImage PrepareScaledFromFull(
BackgroundPreviewBox::BackgroundPreviewBox(
QWidget*,
not_null<Main::Session*> session,
not_null<Window::SessionController*> controller,
const Data::WallPaper &paper)
: _session(session)
: SimpleElementDelegate(controller)
, _controller(controller)
, _text1(GenerateTextItem(
delegate(),
_session->data().history(
_controller->session().data().history(
peerFromUser(PeerData::kServiceNotificationsId)),
tr::lng_background_text1(tr::now),
false))
, _text2(GenerateTextItem(
delegate(),
_session->data().history(
_controller->session().data().history(
peerFromUser(PeerData::kServiceNotificationsId)),
tr::lng_background_text2(tr::now),
true))
@@ -417,7 +419,10 @@ BackgroundPreviewBox::BackgroundPreviewBox(
if (_media) {
_media->thumbnailWanted(_paper.fileOrigin());
}
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
}
not_null<HistoryView::ElementDelegate*> BackgroundPreviewBox::delegate() {
@@ -500,10 +505,10 @@ void BackgroundPreviewBox::createBlurCheckbox() {
void BackgroundPreviewBox::apply() {
const auto install = (_paper.id() != Window::Theme::Background()->id())
&& Data::IsCloudWallPaper(_paper);
App::main()->setChatBackground(_paper, std::move(_full));
_controller->content()->setChatBackground(_paper, std::move(_full));
if (install) {
_session->api().request(MTPaccount_InstallWallPaper(
_paper.mtpInput(),
_controller->session().api().request(MTPaccount_InstallWallPaper(
_paper.mtpInput(&_controller->session()),
_paper.mtpSettings()
)).send();
}
@@ -511,7 +516,8 @@ void BackgroundPreviewBox::apply() {
}
void BackgroundPreviewBox::share() {
QGuiApplication::clipboard()->setText(_paper.shareUrl());
QGuiApplication::clipboard()->setText(
_paper.shareUrl(&_controller->session()));
Ui::Toast::Show(tr::lng_background_link_copied(tr::now));
}
@@ -763,12 +769,12 @@ void BackgroundPreviewBox::checkLoadedDocument() {
}
bool BackgroundPreviewBox::Start(
not_null<Main::Session*> session,
not_null<Window::SessionController*> controller,
const QString &slug,
const QMap<QString, QString> &params) {
if (const auto paper = Data::WallPaper::FromColorSlug(slug)) {
Ui::show(Box<BackgroundPreviewBox>(
session,
controller,
paper->withUrlParams(params)));
return true;
}
@@ -776,11 +782,12 @@ bool BackgroundPreviewBox::Start(
Ui::show(Box<InformBox>(tr::lng_background_bad_link(tr::now)));
return false;
}
session->api().requestWallPaper(slug, [=](const Data::WallPaper &result) {
controller->session().api().requestWallPaper(slug, crl::guard(controller, [=](
const Data::WallPaper &result) {
Ui::show(Box<BackgroundPreviewBox>(
session,
controller,
result.withUrlParams(params)));
}, [](const RPCError &error) {
}), [](const RPCError &error) {
Ui::show(Box<InformBox>(tr::lng_background_bad_link(tr::now)));
});
return true;

View File

@@ -19,9 +19,9 @@ namespace Data {
class DocumentMedia;
} // namespace Data
namespace Main {
class Session;
} // namespace Main
namespace Window {
class SessionController;
} // namespace Window
namespace Ui {
class Checkbox;
@@ -34,11 +34,11 @@ class BackgroundPreviewBox
public:
BackgroundPreviewBox(
QWidget*,
not_null<Main::Session*> session,
not_null<Window::SessionController*> controller,
const Data::WallPaper &paper);
static bool Start(
not_null<Main::Session*> session,
not_null<Window::SessionController*> controller,
const QString &slug,
const QMap<QString, QString> &params);
@@ -71,7 +71,7 @@ private:
void startFadeInFrom(QPixmap previous);
void checkBlurAnimationStart();
const not_null<Main::Session*> _session;
const not_null<Window::SessionController*> _controller;
AdminLog::OwnedItem _text1;
AdminLog::OwnedItem _text2;
Data::WallPaper _paper;

View File

@@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/calendar_box.h"
#include "mtproto/mtproto_rpc_sender.h"
#include "ui/widgets/buttons.h"
#include "lang/lang_keys.h"
#include "ui/effects/ripple_animation.h"
@@ -199,7 +198,7 @@ QString CalendarBox::Context::labelFromIndex(int index) const {
return QString::number(day());
}
class CalendarBox::Inner : public TWidget, public RPCSender, private base::Subscriber {
class CalendarBox::Inner : public TWidget, private base::Subscriber {
public:
Inner(
QWidget *parent,

View File

@@ -19,7 +19,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "mtproto/facade.h"
#include "mtproto/sender.h"
#include "apiwrap.h"
#include "app.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
@@ -76,14 +77,15 @@ protected:
private:
void submit();
void sendPhoneDone(const QString &phoneNumber, const MTPauth_SentCode &result);
bool sendPhoneFail(const QString &phoneNumber, const RPCError &error);
void sendPhoneDone(const MTPauth_SentCode &result, const QString &phoneNumber);
void sendPhoneFail(const RPCError &error, const QString &phoneNumber);
void showError(const QString &text);
void hideError() {
showError(QString());
}
const not_null<Main::Session*> _session;
MTP::Sender _api;
object_ptr<Ui::PhoneInput> _phone = { nullptr };
object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _error = { nullptr };
@@ -112,7 +114,7 @@ private:
void submit();
void sendCall();
void updateCall();
bool sendCodeFail(const RPCError &error);
void sendCodeFail(const RPCError &error);
void showError(const QString &text);
void hideError() {
showError(QString());
@@ -120,6 +122,7 @@ private:
int countHeight();
const not_null<Main::Session*> _session;
MTP::Sender _api;
QString _phone;
QString _hash;
@@ -136,7 +139,8 @@ private:
ChangePhoneBox::EnterPhone::EnterPhone(
QWidget*,
not_null<Main::Session*> session)
: _session(session) {
: _session(session)
, _api(&session->mtp()) {
}
void ChangePhoneBox::EnterPhone::prepare() {
@@ -171,20 +175,19 @@ void ChangePhoneBox::EnterPhone::submit() {
hideError();
auto phoneNumber = _phone->getLastText().trimmed();
_requestId = MTP::send(
MTPaccount_SendChangePhoneCode(
MTP_string(phoneNumber),
MTP_codeSettings(MTP_flags(0))),
rpcDone(crl::guard(this, [=](
const MTPauth_SentCode &result) {
return sendPhoneDone(phoneNumber, result);
})), rpcFail(crl::guard(this, [=](
const RPCError &error) {
return sendPhoneFail(phoneNumber, error);
})));
_requestId = _api.request(MTPaccount_SendChangePhoneCode(
MTP_string(phoneNumber),
MTP_codeSettings(MTP_flags(0))
)).done([=](const MTPauth_SentCode &result) {
sendPhoneDone(result, phoneNumber);
}).fail([=](const RPCError &error) {
sendPhoneFail(error, phoneNumber);
}).handleFloodErrors().send();
}
void ChangePhoneBox::EnterPhone::sendPhoneDone(const QString &phoneNumber, const MTPauth_SentCode &result) {
void ChangePhoneBox::EnterPhone::sendPhoneDone(
const MTPauth_SentCode &result,
const QString &phoneNumber) {
Expects(result.type() == mtpc_auth_sentCode);
_requestId = 0;
@@ -219,18 +222,14 @@ void ChangePhoneBox::EnterPhone::sendPhoneDone(const QString &phoneNumber, const
Ui::LayerOption::KeepOther);
}
bool ChangePhoneBox::EnterPhone::sendPhoneFail(const QString &phoneNumber, const RPCError &error) {
auto errorText = Lang::Hard::ServerError();
void ChangePhoneBox::EnterPhone::sendPhoneFail(const RPCError &error, const QString &phoneNumber) {
_requestId = 0;
if (MTP::isFloodError(error)) {
errorText = tr::lng_flood_error(tr::now);
} else if (MTP::isDefaultHandledError(error)) {
return false;
showError(tr::lng_flood_error(tr::now));
} else if (error.type() == qstr("PHONE_NUMBER_INVALID")) {
errorText = tr::lng_bad_phone(tr::now);
showError(tr::lng_bad_phone(tr::now));
} else if (error.type() == qstr("PHONE_NUMBER_BANNED")) {
ShowPhoneBannedError(phoneNumber);
_requestId = 0;
return true;
} else if (error.type() == qstr("PHONE_NUMBER_OCCUPIED")) {
Ui::show(Box<InformBox>(
tr::lng_change_phone_occupied(
@@ -238,12 +237,9 @@ bool ChangePhoneBox::EnterPhone::sendPhoneFail(const QString &phoneNumber, const
lt_phone,
App::formatPhone(phoneNumber)),
tr::lng_box_ok(tr::now)));
_requestId = 0;
return true;
} else {
showError(Lang::Hard::ServerError());
}
showError(errorText);
_requestId = 0;
return true;
}
void ChangePhoneBox::EnterPhone::showError(const QString &text) {
@@ -261,6 +257,7 @@ ChangePhoneBox::EnterCode::EnterCode(
int codeLength,
int callTimeout)
: _session(session)
, _api(&session->mtp())
, _phone(phone)
, _hash(hash)
, _codeLength(codeLength)
@@ -313,25 +310,28 @@ void ChangePhoneBox::EnterCode::submit() {
const auto session = _session;
const auto code = _code->getDigitsOnly();
const auto weak = Ui::MakeWeak(this);
_requestId = MTP::send(MTPaccount_ChangePhone(
_requestId = session->api().request(MTPaccount_ChangePhone(
MTP_string(_phone),
MTP_string(_hash),
MTP_string(code)
), rpcDone([=](const MTPUser &result) {
)).done([=](const MTPUser &result) {
session->data().processUser(result);
if (weak) {
Ui::hideLayer();
}
Ui::Toast::Show(tr::lng_change_phone_success(tr::now));
}), rpcFail(crl::guard(this, [this](const RPCError &error) {
return sendCodeFail(error);
})));
}).fail(crl::guard(this, [=](const RPCError &error) {
sendCodeFail(error);
})).handleFloodErrors().send();
}
void ChangePhoneBox::EnterCode::sendCall() {
MTP::send(MTPauth_ResendCode(MTP_string(_phone), MTP_string(_hash)), rpcDone(crl::guard(this, [this] {
_api.request(MTPauth_ResendCode(
MTP_string(_phone),
MTP_string(_hash)
)).done([=](const MTPauth_SentCode &result) {
_call.callDone();
})));
}).send();
}
void ChangePhoneBox::EnterCode::updateCall() {
@@ -354,25 +354,20 @@ void ChangePhoneBox::EnterCode::showError(const QString &text) {
}
}
bool ChangePhoneBox::EnterCode::sendCodeFail(const RPCError &error) {
auto errorText = Lang::Hard::ServerError();
void ChangePhoneBox::EnterCode::sendCodeFail(const RPCError &error) {
_requestId = 0;
if (MTP::isFloodError(error)) {
errorText = tr::lng_flood_error(tr::now);
} else if (MTP::isDefaultHandledError(error)) {
return false;
showError(tr::lng_flood_error(tr::now));
} else if (error.type() == qstr("PHONE_CODE_EMPTY") || error.type() == qstr("PHONE_CODE_INVALID")) {
errorText = tr::lng_bad_code(tr::now);
showError(tr::lng_bad_code(tr::now));
} else if (error.type() == qstr("PHONE_CODE_EXPIRED")
|| error.type() == qstr("PHONE_NUMBER_BANNED")) {
closeBox(); // Go back to phone input.
_requestId = 0;
return true;
} else if (error.type() == qstr("PHONE_NUMBER_INVALID")) {
errorText = tr::lng_bad_phone(tr::now);
showError(tr::lng_bad_phone(tr::now));
} else {
showError(Lang::Hard::ServerError());
}
_requestId = 0;
showError(errorText);
return true;
}
ChangePhoneBox::ChangePhoneBox(QWidget*, not_null<Main::Session*> session)

View File

@@ -33,10 +33,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_file_origin.h"
#include "data/data_histories.h"
#include "data/data_photo_media.h"
#include "data/data_changes.h"
#include "base/unixtime.h"
#include "main/main_session.h"
#include "observer_peer.h"
#include "facades.h"
#include "mtproto/mtproto_config.h"
#include "facades.h" // Ui::showChatsList
#include "app.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
@@ -351,7 +352,7 @@ MaxInviteBox::MaxInviteBox(QWidget*, not_null<ChannelData*> channel) : BoxConten
tr::lng_participant_invite_sorry(
tr::now,
lt_count,
Global::ChatSizeMax()),
channel->session().serverConfig().chatSizeMax),
kInformBoxTextOptions,
(st::boxWidth
- st::boxPadding.left()
@@ -367,11 +368,12 @@ void MaxInviteBox::prepare() {
_textHeight = qMin(_text.countHeight(_textWidth), 16 * st::boxLabelStyle.lineHeight);
setDimensions(st::boxWidth, st::boxPadding.top() + _textHeight + st::boxTextFont->height + st::boxTextFont->height * 2 + st::newGroupLinkPadding.bottom());
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::InviteLinkChanged, [this](const Notify::PeerUpdate &update) {
if (update.peer == _channel) {
rtlupdate(_invitationLink);
}
}));
_channel->session().changes().peerUpdates(
_channel,
Data::PeerUpdate::Flag::InviteLink
) | rpl::start_with_next([=] {
rtlupdate(_invitationLink);
}, lifetime());
}
void MaxInviteBox::mouseMoveEvent(QMouseEvent *e) {
@@ -432,6 +434,7 @@ PinMessageBox::PinMessageBox(
not_null<PeerData*> peer,
MsgId msgId)
: _peer(peer)
, _api(&peer->session().mtp())
, _msgId(msgId)
, _text(this, tr::lng_pinned_pin_sure(tr::now), st::boxLabel) {
}
@@ -474,24 +477,16 @@ void PinMessageBox::pinMessage() {
if (_notify && !_notify->checked()) {
flags |= MTPmessages_UpdatePinnedMessage::Flag::f_silent;
}
_requestId = MTP::send(
MTPmessages_UpdatePinnedMessage(
MTP_flags(flags),
_peer->input,
MTP_int(_msgId)),
rpcDone(&PinMessageBox::pinDone),
rpcFail(&PinMessageBox::pinFail));
}
void PinMessageBox::pinDone(const MTPUpdates &updates) {
_peer->session().api().applyUpdates(updates);
Ui::hideLayer();
}
bool PinMessageBox::pinFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
Ui::hideLayer();
return true;
_requestId = _api.request(MTPmessages_UpdatePinnedMessage(
MTP_flags(flags),
_peer->input,
MTP_int(_msgId)
)).done([=](const MTPUpdates &result) {
_peer->session().api().applyUpdates(result);
Ui::hideLayer();
}).fail([=](const RPCError &error) {
Ui::hideLayer();
}).send();
}
DeleteMessagesBox::DeleteMessagesBox(
@@ -683,10 +678,7 @@ auto DeleteMessagesBox::revokeText(not_null<PeerData*> peer) const
const auto cannotRevoke = [&](HistoryItem *item) {
return !item->canDeleteForEveryone(now);
};
const auto canRevokeAll = ranges::find_if(
items,
cannotRevoke
) == end(items);
const auto canRevokeAll = ranges::none_of(items, cannotRevoke);
auto outgoing = items | ranges::view::filter(&HistoryItem::out);
const auto canRevokeOutgoingCount = canRevokeAll
? -1
@@ -775,9 +767,10 @@ void DeleteMessagesBox::deleteAndClear() {
if (justClear) {
peer->session().api().clearHistory(peer, revoke);
} else {
const auto controller = App::wnd()->sessionController();
if (controller->activeChatCurrent().peer() == peer) {
Ui::showChatsList();
for (const auto controller : peer->session().windows()) {
if (controller->activeChatCurrent().peer() == peer) {
Ui::showChatsList(&peer->session());
}
}
// Don't delete old history by default,
// because Android app doesn't.
@@ -847,8 +840,8 @@ void DeleteMessagesBox::deleteAndClear() {
peer->session().api().request(MTPmessages_DeleteScheduledMessages(
peer->input,
MTP_vector<MTPint>(ids)
)).done([=, peer=peer](const MTPUpdates &updates) {
peer->session().api().applyUpdates(updates);
)).done([peer=peer](const MTPUpdates &result) {
peer->session().api().applyUpdates(result);
}).send();
}
@@ -898,9 +891,10 @@ ConfirmInviteBox::ConfirmInviteBox(
_photo = photo->createMediaView();
_photo->wanted(Data::PhotoSize::Small, Data::FileOrigin());
if (!_photo->image(Data::PhotoSize::Small)) {
subscribe(_session->downloaderTaskFinished(), [=] {
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
}
} else {
_photoEmpty = std::make_unique<Ui::EmptyUserpic>(

View File

@@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "boxes/abstract_box.h"
#include "mtproto/mtproto_rpc_sender.h"
#include "mtproto/sender.h"
namespace Data {
class PhotoMedia;
@@ -129,7 +129,7 @@ private:
};
class PinMessageBox : public Ui::BoxContent, public RPCSender {
class PinMessageBox final : public Ui::BoxContent {
public:
PinMessageBox(QWidget*, not_null<PeerData*> peer, MsgId msgId);
@@ -141,10 +141,9 @@ protected:
private:
void pinMessage();
void pinDone(const MTPUpdates &updates);
bool pinFail(const RPCError &error);
not_null<PeerData*> _peer;
const not_null<PeerData*> _peer;
MTP::Sender _api;
MsgId _msgId;
object_ptr<Ui::FlatLabel> _text;
@@ -154,7 +153,7 @@ private:
};
class DeleteMessagesBox : public Ui::BoxContent, public RPCSender {
class DeleteMessagesBox final : public Ui::BoxContent {
public:
DeleteMessagesBox(
QWidget*,
@@ -207,9 +206,8 @@ private:
};
class ConfirmInviteBox
class ConfirmInviteBox final
: public Ui::BoxContent
, public RPCSender
, private base::Subscriber {
public:
ConfirmInviteBox(

View File

@@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/click_handler_types.h" // UrlClickHandler
#include "base/qthelp_url.h" // qthelp::url_encode
#include "base/platform/base_platform_info.h"
#include "main/main_session.h"
#include "mainwidget.h"
#include "numbers.h"
#include "app.h"
@@ -203,36 +204,54 @@ QString SentCodeCall::getText() const {
return QString();
}
void ConfirmPhoneBox::start(const QString &phone, const QString &hash) {
if (CurrentConfirmPhoneBox && CurrentConfirmPhoneBox->getPhone() != phone) {
void ConfirmPhoneBox::Start(
not_null<Main::Session*> session,
const QString &phone,
const QString &hash) {
if (CurrentConfirmPhoneBox
&& (CurrentConfirmPhoneBox->getPhone() != phone
|| &CurrentConfirmPhoneBox->session() != session)) {
CurrentConfirmPhoneBox.destroyDelayed();
}
if (!CurrentConfirmPhoneBox) {
CurrentConfirmPhoneBox = Box<ConfirmPhoneBox>(phone, hash);
CurrentConfirmPhoneBox = Box<ConfirmPhoneBox>(session, phone, hash);
}
CurrentConfirmPhoneBox->checkPhoneAndHash();
}
ConfirmPhoneBox::ConfirmPhoneBox(QWidget*, const QString &phone, const QString &hash)
: _phone(phone)
ConfirmPhoneBox::ConfirmPhoneBox(
QWidget*,
not_null<Main::Session*> session,
const QString &phone,
const QString &hash)
: _session(session)
, _api(&session->mtp())
, _phone(phone)
, _hash(hash)
, _call([this] { sendCall(); }, [this] { update(); }) {
}
void ConfirmPhoneBox::sendCall() {
MTP::send(MTPauth_ResendCode(MTP_string(_phone), MTP_string(_phoneHash)), rpcDone(&ConfirmPhoneBox::callDone));
_api.request(MTPauth_ResendCode(
MTP_string(_phone),
MTP_string(_phoneHash)
)).done([=](const MTPauth_SentCode &result) {
callDone(result);
}).send();
}
void ConfirmPhoneBox::checkPhoneAndHash() {
if (_sendCodeRequestId) {
return;
}
_sendCodeRequestId = MTP::send(
MTPaccount_SendConfirmPhoneCode(
MTP_string(_hash),
MTP_codeSettings(MTP_flags(0))),
rpcDone(&ConfirmPhoneBox::sendCodeDone),
rpcFail(&ConfirmPhoneBox::sendCodeFail));
_sendCodeRequestId = _api.request(MTPaccount_SendConfirmPhoneCode(
MTP_string(_hash),
MTP_codeSettings(MTP_flags(0))
)).done([=](const MTPauth_SentCode &result) {
sendCodeDone(result);
}).fail([=](const RPCError &error) {
sendCodeFail(error);
}).handleFloodErrors().send();
}
void ConfirmPhoneBox::sendCodeDone(const MTPauth_SentCode &result) {
@@ -259,12 +278,10 @@ void ConfirmPhoneBox::sendCodeDone(const MTPauth_SentCode &result) {
});
}
bool ConfirmPhoneBox::sendCodeFail(const RPCError &error) {
void ConfirmPhoneBox::sendCodeFail(const RPCError &error) {
auto errorText = Lang::Hard::ServerError();
if (MTP::isFloodError(error)) {
errorText = tr::lng_flood_error(tr::now);
} else if (MTP::isDefaultHandledError(error)) {
return false;
} else if (error.code() == 400) {
errorText = tr::lng_confirm_phone_link_invalid(tr::now);
}
@@ -275,7 +292,6 @@ bool ConfirmPhoneBox::sendCodeFail(const RPCError &error) {
} else {
deleteLater();
}
return true;
}
void ConfirmPhoneBox::launch() {
@@ -327,10 +343,14 @@ void ConfirmPhoneBox::sendCode() {
showError(QString());
_sendCodeRequestId = MTP::send(
MTPaccount_ConfirmPhone(MTP_string(_phoneHash), MTP_string(code)),
rpcDone(&ConfirmPhoneBox::confirmDone),
rpcFail(&ConfirmPhoneBox::confirmFail));
_sendCodeRequestId = _api.request(MTPaccount_ConfirmPhone(
MTP_string(_phoneHash),
MTP_string(code)
)).done([=](const MTPBool &result) {
confirmDone(result);
}).fail([=](const RPCError &error) {
confirmFail(error);
}).handleFloodErrors().send();
}
void ConfirmPhoneBox::confirmDone(const MTPBool &result) {
@@ -338,12 +358,10 @@ void ConfirmPhoneBox::confirmDone(const MTPBool &result) {
Ui::show(Box<InformBox>(tr::lng_confirm_phone_success(tr::now, lt_phone, App::formatPhone(_phone))));
}
bool ConfirmPhoneBox::confirmFail(const RPCError &error) {
void ConfirmPhoneBox::confirmFail(const RPCError &error) {
auto errorText = Lang::Hard::ServerError();
if (MTP::isFloodError(error)) {
errorText = tr::lng_flood_error(tr::now);
} else if (MTP::isDefaultHandledError(error)) {
return false;
} else {
auto &errorType = error.type();
if (errorType == qstr("PHONE_CODE_EMPTY") || errorType == qstr("PHONE_CODE_INVALID")) {
@@ -354,7 +372,6 @@ bool ConfirmPhoneBox::confirmFail(const RPCError &error) {
_code->setDisabled(false);
_code->setFocus();
showError(errorText);
return true;
}
void ConfirmPhoneBox::showError(const QString &error) {
@@ -406,9 +423,3 @@ void ConfirmPhoneBox::resizeEvent(QResizeEvent *e) {
void ConfirmPhoneBox::setInnerFocus() {
_code->setFocusFast();
}
ConfirmPhoneBox::~ConfirmPhoneBox() {
if (_sendCodeRequestId) {
MTP::cancel(_sendCodeRequestId);
}
}

View File

@@ -10,13 +10,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h"
#include "base/timer.h"
#include "ui/widgets/input_fields.h"
#include "mtproto/mtproto_rpc_sender.h"
#include "mtproto/sender.h"
namespace Ui {
class InputField;
class FlatLabel;
} // namespace Ui
namespace Main {
class Session;
} // namespace Main
void ShowPhoneBannedError(const QString &phone);
[[nodiscard]] QString ExtractPhonePrefix(const QString &phone);
@@ -86,11 +90,16 @@ private:
};
class ConfirmPhoneBox : public Ui::BoxContent, public RPCSender {
class ConfirmPhoneBox final : public Ui::BoxContent {
public:
static void start(const QString &phone, const QString &hash);
static void Start(
not_null<Main::Session*> session,
const QString &phone,
const QString &hash);
~ConfirmPhoneBox();
[[nodiscard]] Main::Session &session() const {
return *_session;
}
protected:
void prepare() override;
@@ -100,7 +109,11 @@ protected:
void resizeEvent(QResizeEvent *e) override;
private:
ConfirmPhoneBox(QWidget*, const QString &phone, const QString &hash);
ConfirmPhoneBox(
QWidget*,
not_null<Main::Session*> session,
const QString &phone,
const QString &hash);
friend class object_ptr<ConfirmPhoneBox>;
void sendCode();
@@ -108,12 +121,12 @@ private:
void checkPhoneAndHash();
void sendCodeDone(const MTPauth_SentCode &result);
bool sendCodeFail(const RPCError &error);
void sendCodeFail(const RPCError &error);
void callDone(const MTPauth_SentCode &result);
void confirmDone(const MTPBool &result);
bool confirmFail(const RPCError &error);
void confirmFail(const RPCError &error);
QString getPhone() const {
return _phone;
@@ -122,6 +135,8 @@ private:
void showError(const QString &error);
const not_null<Main::Session*> _session;
MTP::Sender _api;
mtpRequestId _sendCodeRequestId = 0;
// _hash from the link for account.sendConfirmPhoneCode call.

View File

@@ -171,7 +171,7 @@ private:
};
class ProxyBox : public Ui::BoxContent {
class ProxyBox final : public Ui::BoxContent {
public:
ProxyBox(
QWidget*,
@@ -179,12 +179,14 @@ public:
Fn<void(ProxyData)> callback,
Fn<void(ProxyData)> shareCallback);
protected:
void prepare() override;
private:
using Type = ProxyData::Type;
void prepare() override;
void setInnerFocus() override {
_host->setFocusFast();
}
void refreshButtons();
ProxyData collectData();
void save();
@@ -693,8 +695,8 @@ void ProxiesBox::applyView(View &&view) {
setupButtons(id, i->second.get());
if (_noRows) {
_noRows.reset();
wrap->resizeToWidth(width());
}
wrap->resizeToWidth(width());
} else if (view.host.isEmpty()) {
_rows.erase(i);
} else {
@@ -765,6 +767,31 @@ ProxyBox::ProxyBox(
void ProxyBox::prepare() {
setTitle(tr::lng_proxy_edit());
connect(_host.data(), &Ui::InputField::changed, [=] {
Ui::PostponeCall(_host, [=] {
const auto host = _host->getLastText().trimmed();
static const auto mask = u"^\\d+\\.\\d+\\.\\d+\\.\\d+:(\\d*)$"_q;
const auto match = QRegularExpression(mask).match(host);
if (_host->textCursor().position() == host.size()
&& match.hasMatch()) {
const auto port = match.captured(1);
_port->setText(port);
_port->setCursorPosition(port.size());
_port->setFocus();
_host->setText(host.mid(0, host.size() - port.size() - 1));
}
});
});
_port.data()->events(
) | rpl::start_with_next([=](not_null<QEvent*> e) {
if (e->type() == QEvent::KeyPress
&& (static_cast<QKeyEvent*>(e.get())->key() == Qt::Key_Backspace)
&& _port->cursorPosition() == 0) {
_host->setCursorPosition(_host->getLastText().size());
_host->setFocus();
}
}, _port->lifetime());
refreshButtons();
setDimensionsToContent(st::boxWideWidth, _content);
}
@@ -978,8 +1005,9 @@ void ProxyBox::addLabel(
} // namespace
ProxiesBoxController::ProxiesBoxController()
: _saveTimer([] { Local::writeSettings(); }) {
ProxiesBoxController::ProxiesBoxController(not_null<Main::Account*> account)
: _account(account)
, _saveTimer([] { Local::writeSettings(); }) {
_list = ranges::view::all(
Global::ProxiesList()
) | ranges::view::transform([&](const ProxyData &proxy) {
@@ -1027,7 +1055,7 @@ void ProxiesBoxController::ShowApplyConfirmation(
: QString());
*box = Ui::show(Box<ConfirmBox>(text, tr::lng_sure_enable(tr::now), [=] {
auto &proxies = Global::RefProxiesList();
if (ranges::find(proxies, proxy) == end(proxies)) {
if (!ranges::contains(proxies, proxy)) {
proxies.push_back(proxy);
}
Core::App().setCurrentProxy(
@@ -1058,7 +1086,7 @@ void ProxiesBoxController::refreshChecker(Item &item) {
const auto type = (item.data.type == Type::Http)
? Variants::Http
: Variants::Tcp;
const auto mtproto = Core::App().activeAccount().mtp();
const auto mtproto = &_account->mtp();
const auto dcId = mtproto->mainDcId();
item.state = ItemState::Checking;
@@ -1081,7 +1109,7 @@ void ProxiesBoxController::refreshChecker(Item &item) {
dcId);
item.checkerv6 = nullptr;
} else {
const auto options = mtproto->dcOptions()->lookup(
const auto options = mtproto->dcOptions().lookup(
dcId,
MTP::DcType::Regular,
true);
@@ -1142,8 +1170,9 @@ void ProxiesBoxController::setupChecker(int id, const Checker &checker) {
pointer->connect(pointer, &Connection::error, failed);
}
object_ptr<Ui::BoxContent> ProxiesBoxController::CreateOwningBox() {
auto controller = std::make_unique<ProxiesBoxController>();
object_ptr<Ui::BoxContent> ProxiesBoxController::CreateOwningBox(
not_null<Main::Account*> account) {
auto controller = std::make_unique<ProxiesBoxController>(account);
auto box = controller->create();
Ui::AttachAsChild(box, std::move(controller));
return box;
@@ -1372,7 +1401,7 @@ void ProxiesBoxController::setTryIPv6(bool enabled) {
return;
}
Global::SetTryIPv6(enabled);
MTP::restart();
_account->mtp().restart();
Global::RefConnectionTypeChanged().notify();
saveDelayed();
}
@@ -1404,7 +1433,7 @@ void ProxiesBoxController::updateView(const Item &item) {
if (!selected
|| (Global::ProxySettings() != ProxyData::Settings::Enabled)) {
return item.state;
} else if (MTP::dcstate() == MTP::ConnectedState) {
} else if (_account->mtp().dcstate() == MTP::ConnectedState) {
return ItemState::Online;
}
return ItemState::Connecting;

View File

@@ -24,18 +24,23 @@ template <typename Enum>
class Radioenum;
} // namespace Ui
namespace Main {
class Account;
} // namespace Main
class ProxiesBoxController : public base::Subscriber {
public:
using ProxyData = MTP::ProxyData;
using Type = ProxyData::Type;
ProxiesBoxController();
explicit ProxiesBoxController(not_null<Main::Account*> account);
static void ShowApplyConfirmation(
Type type,
const QMap<QString, QString> &fields);
static object_ptr<Ui::BoxContent> CreateOwningBox();
static object_ptr<Ui::BoxContent> CreateOwningBox(
not_null<Main::Account*> account);
object_ptr<Ui::BoxContent> create();
enum class ItemState {
@@ -104,6 +109,7 @@ private:
const ProxyData &proxy);
void addNewItem(const ProxyData &proxy);
const not_null<Main::Account*> _account;
int _idCounter = 0;
std::vector<Item> _list;
rpl::event_stream<ItemView> _views;

View File

@@ -20,6 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/checkbox.h"
#include "ui/toast/toast.h"
#include "main/main_session.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "chat_helpers/message_field.h"
#include "history/view/history_view_schedule_box.h"
@@ -27,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unique_qptr.h"
#include "base/event_filter.h"
#include "base/call_delayed.h"
#include "window/window_session_controller.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_settings.h"
@@ -159,7 +162,7 @@ void InitField(
not_null<Main::Session*> session) {
field->setInstantReplaces(Ui::InstantReplaces::Default());
field->setInstantReplacesEnabled(
session->settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue());
auto options = Ui::Emoji::SuggestionsController::Options();
options.suggestExactFirstWord = false;
Ui::Emoji::SuggestionsController::Init(
@@ -721,9 +724,8 @@ void Options::removeDestroyed(not_null<Option*> option) {
void Options::validateState() {
checkLastOption();
_hasOptions = (ranges::count_if(_list, &Option::isGood) > 1);
_isValid = _hasOptions
&& (ranges::find_if(_list, &Option::isTooLong) == end(_list));
_hasCorrect = ranges::find_if(_list, &Option::isCorrect) != end(_list);
_isValid = _hasOptions && ranges::none_of(_list, &Option::isTooLong);
_hasCorrect = ranges::any_of(_list, &Option::isCorrect);
const auto lastEmpty = !_list.empty() && _list.back()->isEmpty();
_usedCount = _list.size() - (lastEmpty ? 1 : 0);
@@ -748,11 +750,11 @@ void Options::checkLastOption() {
CreatePollBox::CreatePollBox(
QWidget*,
not_null<Main::Session*> session,
not_null<Window::SessionController*> controller,
PollData::Flags chosen,
PollData::Flags disabled,
Api::SendType sendType)
: _session(session)
: _controller(controller)
, _chosen(chosen)
, _disabled(disabled)
, _sendType(sendType) {
@@ -774,6 +776,7 @@ not_null<Ui::InputField*> CreatePollBox::setupQuestion(
not_null<Ui::VerticalLayout*> container) {
using namespace Settings;
const auto session = &_controller->session();
AddSubsectionTitle(container, tr::lng_polls_create_question());
const auto question = container->add(
object_ptr<Ui::InputField>(
@@ -782,7 +785,7 @@ not_null<Ui::InputField*> CreatePollBox::setupQuestion(
Ui::InputField::Mode::MultiLine,
tr::lng_polls_create_question_placeholder()),
st::createPollFieldPadding);
InitField(getDelegate()->outerContainer(), question, _session);
InitField(getDelegate()->outerContainer(), question, session);
question->setMaxLength(kQuestionLimit + kErrorLimit);
question->setSubmitSettings(Ui::InputField::SubmitSettings::Both);
question->customTab(true);
@@ -824,6 +827,7 @@ not_null<Ui::InputField*> CreatePollBox::setupSolution(
)->setDuration(0)->toggleOn(std::move(shown));
const auto inner = outer->entity();
const auto session = &_controller->session();
AddSkip(inner);
AddSubsectionTitle(inner, tr::lng_polls_solution_title());
const auto solution = inner->add(
@@ -833,14 +837,14 @@ not_null<Ui::InputField*> CreatePollBox::setupSolution(
Ui::InputField::Mode::MultiLine,
tr::lng_polls_solution_placeholder()),
st::createPollFieldPadding);
InitField(getDelegate()->outerContainer(), solution, _session);
InitField(getDelegate()->outerContainer(), solution, session);
solution->setMaxLength(kSolutionLimit + kErrorLimit);
solution->setInstantReplaces(Ui::InstantReplaces::Default());
solution->setInstantReplacesEnabled(
_session->settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue());
solution->setMarkdownReplacesEnabled(rpl::single(true));
solution->setEditLinkCallback(
DefaultEditLinkCallback(_session, solution));
DefaultEditLinkCallback(_controller, solution));
solution->customTab(true);
const auto warning = CreateWarningLabel(
@@ -896,7 +900,7 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
const auto options = lifetime().make_state<Options>(
getDelegate()->outerContainer(),
container,
_session,
&_controller->session(),
(_chosen & PollData::Flag::Quiz));
auto limit = options->usedCount() | rpl::after_next([=](int count) {
setCloseByEscape(!count);
@@ -1011,7 +1015,7 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
const auto collectResult = [=] {
using Flag = PollData::Flag;
auto result = PollData(&_session->data(), id);
auto result = PollData(&_controller->session().data(), id);
result.question = question->getLastText().trimmed();
result.answers = options->toPollAnswers();
const auto solutionWithTags = quiz->checked()

View File

@@ -18,9 +18,9 @@ namespace Ui {
class VerticalLayout;
} // namespace Ui
namespace Main {
class Session;
} // namespace Main
namespace Window {
class SessionController;
} // namespace Window
class CreatePollBox : public Ui::BoxContent {
public:
@@ -31,7 +31,7 @@ public:
CreatePollBox(
QWidget*,
not_null<Main::Session*> session,
not_null<Window::SessionController*> controller,
PollData::Flags chosen,
PollData::Flags disabled,
Api::SendType sendType);
@@ -62,7 +62,7 @@ private:
not_null<Ui::VerticalLayout*> container,
rpl::producer<bool> shown);
const not_null<Main::Session*> _session;
const not_null<Window::SessionController*> _controller;
const PollData::Flags _chosen = PollData::Flags();
const PollData::Flags _disabled = PollData::Flags();
const Api::SendType _sendType = Api::SendType();

View File

@@ -13,7 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "chat_helpers/spellchecker_common.h"
#include "core/application.h"
#include "main/main_account.h"
#include "main/main_session.h"
#include "mainwidget.h"
#include "mtproto/dedicated_file_loader.h"
#include "spellcheck/spellcheck_utils.h"
@@ -27,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/popup_menu.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/effects/animations.h"
#include "window/window_session_controller.h"
namespace Ui {
namespace {
@@ -46,13 +46,18 @@ using QStringView = QString;
class Inner : public Ui::RpWidget {
public:
Inner(QWidget *parent, Dictionaries enabledDictionaries);
Inner(
QWidget *parent,
not_null<Window::SessionController*> controller,
Dictionaries enabledDictionaries);
Dictionaries enabledRows() const;
QueryCallback queryCallback() const;
private:
void setupContent(Dictionaries enabledDictionaries);
void setupContent(
not_null<Window::SessionController*> controller,
Dictionaries enabledDictionaries);
Dictionaries _enabledRows;
QueryCallback _queryCallback;
@@ -96,8 +101,10 @@ auto CreateMultiSelect(QWidget *parent) {
Inner::Inner(
QWidget *parent,
Dictionaries enabledDictionaries) : RpWidget(parent) {
setupContent(std::move(enabledDictionaries));
not_null<Window::SessionController*> controller,
Dictionaries enabledDictionaries)
: RpWidget(parent) {
setupContent(controller, std::move(enabledDictionaries));
}
QueryCallback Inner::queryCallback() const {
@@ -110,6 +117,7 @@ Dictionaries Inner::enabledRows() const {
auto AddButtonWithLoader(
not_null<Ui::VerticalLayout*> content,
not_null<Window::SessionController*> controller,
const Spellchecker::Dict &dict,
bool buttonEnabled,
rpl::producer<QStringView> query) {
@@ -238,39 +246,29 @@ auto AddButtonWithLoader(
) | rpl::then(
rpl::merge(
// Events to toggle on.
dictionaryFromGlobalLoader->events(
) | rpl::map([] {
return true;
}),
dictionaryFromGlobalLoader->events() | rpl::map_to(true),
// Events to toggle off.
rpl::merge(
dictionaryRemoved->events(),
buttonState->value(
) | rpl::filter([](const DictState &state) {
return state.is<Failed>();
}) | rpl::map([] {
return rpl::empty_value();
})
) | rpl::map([] {
return false;
})
}) | rpl::to_empty
) | rpl::map_to(false)
)
)
);
*buttonState = localLoaderValues->events_starting_with(
rawGlobalLoaderPtr() ? rawGlobalLoaderPtr() : localLoader->get()
) | rpl::map([=](Loader *loader) {
*buttonState = localLoaderValues->events_starting_with(
rawGlobalLoaderPtr() ? rawGlobalLoaderPtr() : localLoader->get()
) | rpl::map([=](Loader *loader) {
return (loader && loader->id() == id)
? loader->state()
: rpl::single(
buttonEnabled
) | rpl::then(
rpl::merge(
dictionaryRemoved->events(
) | rpl::map([] {
return false;
}),
dictionaryRemoved->events() | rpl::map_to(false),
button->toggledValue()
)
) | rpl::map([=](auto enabled) {
@@ -287,7 +285,8 @@ auto AddButtonWithLoader(
if (toggled && (state.is<Available>() || state.is<Failed>())) {
const auto weak = Ui::MakeWeak(button);
setLocalLoader(base::make_unique_q<Loader>(
App::main(),
QCoreApplication::instance(),
&controller->session(),
id,
Spellchecker::GetDownloadLocation(id),
Spellchecker::DictPathByLangId(id),
@@ -336,7 +335,9 @@ auto AddButtonWithLoader(
return button;
}
void Inner::setupContent(Dictionaries enabledDictionaries) {
void Inner::setupContent(
not_null<Window::SessionController*> controller,
Dictionaries enabledDictionaries) {
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
const auto queryStream = content->lifetime()
@@ -346,6 +347,7 @@ void Inner::setupContent(Dictionaries enabledDictionaries) {
const auto id = dict.id;
const auto row = AddButtonWithLoader(
content,
controller,
dict,
ranges::contains(enabledDictionaries, id),
queryStream->events());
@@ -375,8 +377,8 @@ void Inner::setupContent(Dictionaries enabledDictionaries) {
ManageDictionariesBox::ManageDictionariesBox(
QWidget*,
not_null<Main::Session*> session)
: _session(session) {
not_null<Window::SessionController*> controller)
: _controller(controller) {
}
void ManageDictionariesBox::setInnerFocus() {
@@ -386,10 +388,12 @@ void ManageDictionariesBox::setInnerFocus() {
void ManageDictionariesBox::prepare() {
const auto multiSelect = CreateMultiSelect(this);
const auto session = &_controller->session();
const auto inner = setInnerWidget(
object_ptr<Inner>(
this,
_session->settings().dictionariesEnabled()),
_controller,
Core::App().settings().dictionariesEnabled()),
st::boxScroll,
multiSelect->height()
);
@@ -407,9 +411,9 @@ void ManageDictionariesBox::prepare() {
setTitle(tr::lng_settings_manage_dictionaries());
addButton(tr::lng_settings_save(), [=] {
_session->settings().setDictionariesEnabled(
Core::App().settings().setDictionariesEnabled(
FilterEnabledDict(inner->enabledRows()));
_session->saveSettingsDelayed();
Core::App().saveSettingsDelayed();
// Ignore boxClosing() when the Save button was pressed.
lifetime().destroy();
closeBox();
@@ -417,9 +421,9 @@ void ManageDictionariesBox::prepare() {
addButton(tr::lng_close(), [=] { closeBox(); });
boxClosing() | rpl::start_with_next([=] {
_session->settings().setDictionariesEnabled(
Core::App().settings().setDictionariesEnabled(
FilterEnabledDict(initialEnabledRows));
_session->saveSettingsDelayed();
Core::App().saveSettingsDelayed();
}, lifetime());
setDimensionsToContent(st::boxWidth, inner);

View File

@@ -11,9 +11,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h"
namespace Main {
class Session;
} // namespace Main
namespace Window {
class SessionController;
} // namespace Window
namespace Ui {
@@ -21,14 +21,14 @@ class ManageDictionariesBox : public Ui::BoxContent {
public:
ManageDictionariesBox(
QWidget*,
not_null<Main::Session*> session);
not_null<Window::SessionController*> controller);
protected:
void prepare() override;
void setInnerFocus() override;
private:
const not_null<Main::Session*> _session;
const not_null<Window::SessionController*> _controller;
Fn<void()> _setInnerFocus;
};

View File

@@ -8,18 +8,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/download_path_box.h"
#include "lang/lang_keys.h"
#include "storage/localstorage.h"
#include "core/file_utilities.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/buttons.h"
#include "platform/platform_specific.h"
#include "facades.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "storage/storage_account.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
DownloadPathBox::DownloadPathBox(QWidget *parent)
: _path(Global::DownloadPath())
, _pathBookmark(Global::DownloadPathBookmark())
DownloadPathBox::DownloadPathBox(
QWidget *parent,
not_null<Window::SessionController*> controller)
: _controller(controller)
, _path(Core::App().settings().downloadPath())
, _pathBookmark(Core::App().settings().downloadPathBookmark())
, _group(std::make_shared<Ui::RadioenumGroup<Directory>>(typeFromPath(_path)))
, _default(this, _group, Directory::Downloads, tr::lng_download_path_default_radio(tr::now), st::defaultBoxCheckbox)
, _temp(this, _group, Directory::Temp, tr::lng_download_path_temp_radio(tr::now), st::defaultBoxCheckbox)
@@ -86,8 +90,9 @@ void DownloadPathBox::radioChanged(Directory value) {
void DownloadPathBox::editPath() {
const auto initialPath = [] {
if (!Global::DownloadPath().isEmpty() && Global::DownloadPath() != qstr("tmp")) {
return Global::DownloadPath().left(Global::DownloadPath().size() - (Global::DownloadPath().endsWith('/') ? 1 : 0));
const auto path = Core::App().settings().downloadPath();
if (!path.isEmpty() && path != qstr("tmp")) {
return path.left(path.size() - (path.endsWith('/') ? 1 : 0));
}
return QString();
}();
@@ -117,10 +122,10 @@ void DownloadPathBox::save() {
}
return QString();
};
Global::SetDownloadPath(computePath());
Global::SetDownloadPathBookmark((value == Directory::Custom) ? _pathBookmark : QByteArray());
Local::writeUserSettings();
Global::RefDownloadPathChanged().notify();
Core::App().settings().setDownloadPathBookmark(
(value == Directory::Custom) ? _pathBookmark : QByteArray());
Core::App().settings().setDownloadPath(computePath());
Core::App().saveSettings();
closeBox();
#endif // OS_WIN_STORE
}

View File

@@ -18,9 +18,15 @@ class Radioenum;
class LinkButton;
} // namespace Ui
namespace Window {
class SessionController;
} // namespace Window
class DownloadPathBox : public Ui::BoxContent {
public:
DownloadPathBox(QWidget *parent);
DownloadPathBox(
QWidget *parent,
not_null<Window::SessionController*> controller);
protected:
void prepare() override;
@@ -48,6 +54,7 @@ private:
void setPathText(const QString &text);
void editPath();
const not_null<Window::SessionController*> _controller;
QString _path;
QByteArray _pathBookmark;

View File

@@ -15,6 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "chat_helpers/tabbed_panel.h"
#include "chat_helpers/tabbed_selector.h"
#include "base/event_filter.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "core/file_utilities.h"
#include "core/mime_type.h"
#include "data/data_document.h"
@@ -28,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document_media.h"
#include "history/history.h"
#include "history/history_item.h"
#include "platform/platform_specific.h"
#include "lang/lang_keys.h"
#include "layout.h"
#include "media/streaming/media_streaming_instance.h"
@@ -36,6 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/streaming/media_streaming_loader_local.h"
#include "storage/localimageloader.h"
#include "storage/storage_media_prepare.h"
#include "mtproto/mtproto_config.h"
#include "ui/image/image.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/checkbox.h"
@@ -44,7 +48,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text_options.h"
#include "window/window_session_controller.h"
#include "confirm_box.h"
#include "facades.h"
#include "apiwrap.h"
#include "facades.h" // App::LambdaDelayed.
#include "app.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
@@ -65,6 +70,7 @@ EditCaptionBox::EditCaptionBox(
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item)
: _controller(controller)
, _api(&controller->session().mtp())
, _msgId(item->fullId()) {
Expects(item->media() != nullptr);
Expects(item->media()->allowsEditCaption());
@@ -72,31 +78,21 @@ EditCaptionBox::EditCaptionBox(
_isAllowedEditMedia = item->media()->allowsEditMedia();
_isAlbum = !item->groupId().empty();
QSize dimensions;
auto image = (Image*)nullptr;
auto dimensions = QSize();
const auto media = item->media();
if (const auto photo = media->photo()) {
_photoMedia = photo->createMediaView();
_photoMedia->wanted(PhotoSize::Large, _msgId);
image = _photoMedia->image(PhotoSize::Large);
if (!image) {
image = _photoMedia->image(PhotoSize::Thumbnail);
if (!image) {
image = _photoMedia->image(PhotoSize::Small);
if (!image) {
image = _photoMedia->thumbnailInline();
}
}
}
dimensions = _photoMedia->size(PhotoSize::Large);
if (dimensions.isEmpty()) {
dimensions = QSize(1, 1);
}
_photo = true;
} else if (const auto document = media->document()) {
_documentMedia = document->createMediaView();
_documentMedia->thumbnailWanted(_msgId);
image = _documentMedia->thumbnail();
dimensions = image
? image->size()
dimensions = _documentMedia->thumbnail()
? _documentMedia->thumbnail()->size()
: document->dimensions;
if (document->isAnimation()) {
_gifw = style::ConvertScale(document->dimensions.width());
@@ -107,24 +103,42 @@ EditCaptionBox::EditCaptionBox(
} else {
_doc = true;
}
} else {
Unexpected("Photo or document should be set.");
}
const auto editData = PrepareEditText(item);
if (!_animated
&& (dimensions.isEmpty()
|| _documentMedia
|| (!_photoMedia && !image))) {
if (!image) {
_thumbw = 0;
const auto computeImage = [=] {
if (_documentMedia) {
return _documentMedia->thumbnail();
} else if (const auto large = _photoMedia->image(PhotoSize::Large)) {
return large;
} else if (const auto thumbnail = _photoMedia->image(
PhotoSize::Thumbnail)) {
return thumbnail;
} else if (const auto small = _photoMedia->image(PhotoSize::Small)) {
return small;
} else {
const auto tw = image->width(), th = image->height();
return _photoMedia->thumbnailInline();
}
};
if (!_animated && _documentMedia) {
if (dimensions.isEmpty()) {
_thumbw = 0;
_thumbnailImageLoaded = true;
} else {
const auto tw = dimensions.width(), th = dimensions.height();
if (tw > th) {
_thumbw = (tw * st::msgFileThumbSize) / th;
} else {
_thumbw = st::msgFileThumbSize;
}
_thumbnailImage = image;
_refreshThumbnail = [=] {
const auto image = computeImage();
if (!image) {
return;
}
const auto options = Images::Option::Smooth
| Images::Option::RoundedSmall
| Images::Option::RoundedTopLeft
@@ -138,7 +152,9 @@ EditCaptionBox::EditCaptionBox(
options,
st::msgFileThumbSize,
st::msgFileThumbSize));
_thumbnailImageLoaded = true;
};
_refreshThumbnail();
}
if (_documentMedia) {
@@ -151,13 +167,7 @@ EditCaptionBox::EditCaptionBox(
_isAudio = document->isVoiceMessage()
|| document->isAudioFile();
}
if (_refreshThumbnail) {
_refreshThumbnail();
}
} else {
if (!image && !_photoMedia) {
image = Image::BlankMedia();
}
auto maxW = 0, maxH = 0;
const auto limitW = st::sendMediaPreviewSize;
auto limitH = std::min(st::confirmMaxHeight, _gifh ? _gifh : INT_MAX);
@@ -175,35 +185,37 @@ EditCaptionBox::EditCaptionBox(
maxH = limitH;
}
}
_thumbnailImage = image;
_refreshThumbnail = [=] {
const auto image = computeImage();
const auto use = image ? image : Image::BlankMedia().get();
const auto options = Images::Option::Smooth
| Images::Option::Blurred;
_thumb = image->pixNoCache(
_thumb = use->pixNoCache(
maxW * cIntRetinaFactor(),
maxH * cIntRetinaFactor(),
options,
maxW,
maxH);
_thumbnailImageLoaded = true;
};
prepareStreamedPreview();
} else {
Assert(_photoMedia != nullptr);
maxW = dimensions.width();
maxH = dimensions.height();
_thumbnailImage = image;
_refreshThumbnail = [=] {
const auto photo = _photoMedia
? _photoMedia->image(Data::PhotoSize::Large)
: nullptr;
const auto image = computeImage();
const auto photo = _photoMedia->image(Data::PhotoSize::Large);
const auto use = photo
? photo
: _thumbnailImage
? _thumbnailImage
: image
? image
: Image::BlankMedia().get();
const auto options = Images::Option::Smooth
| ((_photoMedia && !photo)
? Images::Option::Blurred
: Images::Option(0));
| (photo
? Images::Option(0)
: Images::Option::Blurred);
_thumbnailImageLoaded = (photo != nullptr);
_thumb = use->pixNoCache(
maxW * cIntRetinaFactor(),
maxH * cIntRetinaFactor(),
@@ -276,36 +288,19 @@ EditCaptionBox::EditCaptionBox(
scaleThumbDown();
}
Assert(_animated || _photo || _doc);
Assert(_thumbnailImageLoaded || _refreshThumbnail);
_thumbnailImageLoaded = _photoMedia
? (_photoMedia->image(Data::PhotoSize::Large) != nullptr)
: _thumbnailImage
? true
: _documentMedia
? !_documentMedia->owner()->hasThumbnail()
: true;
if (!_thumbnailImageLoaded) {
subscribe(_controller->session().downloaderTaskFinished(), [=] {
if (_thumbnailImageLoaded) {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (_thumbnailImageLoaded
|| (_photoMedia && !_photoMedia->image(PhotoSize::Large))
|| (_documentMedia && !_documentMedia->thumbnail())) {
return;
} else if (!_thumbnailImage
&& _photoMedia
&& _photoMedia->image(PhotoSize::Large)) {
_thumbnailImage = _photoMedia->image(PhotoSize::Large);
} else if (!_thumbnailImage
&& _documentMedia
&& _documentMedia->owner()->hasThumbnail()) {
_thumbnailImage = _documentMedia->thumbnail();
}
if (_thumbnailImage) {
_thumbnailImageLoaded = !_photoMedia
|| _photoMedia->image(PhotoSize::Large);
if (_thumbnailImageLoaded) {
_refreshThumbnail();
update();
}
}
});
_refreshThumbnail();
update();
}, lifetime());
}
_field.create(
this,
@@ -313,16 +308,18 @@ EditCaptionBox::EditCaptionBox(
Ui::InputField::Mode::MultiLine,
tr::lng_photo_caption(),
editData);
_field->setMaxLength(Global::CaptionLengthMax());
_field->setSubmitSettings(_controller->session().settings().sendSubmitWay());
_field->setMaxLength(
_controller->session().serverConfig().captionLengthMax);
_field->setSubmitSettings(
Core::App().settings().sendSubmitWay());
_field->setInstantReplaces(Ui::InstantReplaces::Default());
_field->setInstantReplacesEnabled(
_controller->session().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue());
_field->setMarkdownReplacesEnabled(rpl::single(true));
_field->setEditLinkCallback(
DefaultEditLinkCallback(&_controller->session(), _field));
DefaultEditLinkCallback(_controller, _field));
InitSpellchecker(&_controller->session(), _field);
InitSpellchecker(_controller, _field);
auto r = object_ptr<Ui::SlideWrap<Ui::Checkbox>>(
this,
@@ -598,6 +595,10 @@ void EditCaptionBox::createEditMediaButton() {
}
void EditCaptionBox::prepare() {
if (_animated) {
prepareStreamedPreview();
}
addButton(tr::lng_settings_save(), [this] { save(); });
if (_isAllowedEditMedia) {
createEditMediaButton();
@@ -664,7 +665,10 @@ bool EditCaptionBox::fileFromClipboard(not_null<const QMimeData*> data) {
if (result.error == Error::None) {
return result;
} else if (data->hasImage()) {
auto image = qvariant_cast<QImage>(data->imageData());
auto image = Platform::GetImageFromClipboard();
if (image.isNull()) {
image = qvariant_cast<QImage>(data->imageData());
}
if (!image.isNull()) {
_isImage = true;
_photo = true;
@@ -942,6 +946,7 @@ void EditCaptionBox::save() {
TextUtilities::Trim(sending);
const auto sentEntities = Api::EntitiesToMTP(
&item->history()->session(),
sending.entities,
Api::ConvertOption::SkipLocal);
if (!sentEntities.v.isEmpty()) {
@@ -966,18 +971,20 @@ void EditCaptionBox::save() {
return;
}
_saveRequestId = MTP::send(
MTPmessages_EditMessage(
MTP_flags(flags),
item->history()->peer->input,
MTP_int(item->id),
MTP_string(sending.text),
MTPInputMedia(),
MTPReplyMarkup(),
sentEntities,
MTP_int(0)), // schedule_date
rpcDone(&EditCaptionBox::saveDone),
rpcFail(&EditCaptionBox::saveFail));
_saveRequestId = _api.request(MTPmessages_EditMessage(
MTP_flags(flags),
item->history()->peer->input,
MTP_int(item->id),
MTP_string(sending.text),
MTPInputMedia(),
MTPReplyMarkup(),
sentEntities,
MTP_int(0)
)).done([=](const MTPUpdates &result) {
saveDone(result);
}).fail([=](const RPCError &error) {
saveFail(error);
}).send();
}
void EditCaptionBox::saveDone(const MTPUpdates &updates) {
@@ -987,26 +994,24 @@ void EditCaptionBox::saveDone(const MTPUpdates &updates) {
controller->session().api().applyUpdates(updates);
}
bool EditCaptionBox::saveFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
void EditCaptionBox::saveFail(const RPCError &error) {
_saveRequestId = 0;
const auto &type = error.type();
if (type == qstr("MESSAGE_ID_INVALID")
|| type == qstr("CHAT_ADMIN_REQUIRED")
|| type == qstr("MESSAGE_EDIT_TIME_EXPIRED")) {
_error = tr::lng_edit_error(tr::now);
update();
} else if (type == qstr("MESSAGE_NOT_MODIFIED")) {
closeBox();
return true;
} else if (type == qstr("MESSAGE_EMPTY")) {
_field->setFocus();
_field->showError();
update();
} else {
_error = tr::lng_edit_error(tr::now);
update();
}
update();
return true;
}
void EditCaptionBox::setName(QString nameString, qint64 size) {

View File

@@ -10,7 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h"
#include "storage/storage_media_prepare.h"
#include "ui/wrap/slide_wrap.h"
#include "mtproto/mtproto_rpc_sender.h"
#include "mtproto/sender.h"
class Image;
@@ -49,10 +49,7 @@ struct Information;
} // namespace Streaming
} // namespace Media
class EditCaptionBox
: public Ui::BoxContent
, public RPCSender
, private base::Subscriber {
class EditCaptionBox final : public Ui::BoxContent, private base::Subscriber {
public:
EditCaptionBox(
QWidget*,
@@ -87,7 +84,7 @@ private:
void captionResized();
void saveDone(const MTPUpdates &updates);
bool saveFail(const RPCError &error);
void saveFail(const RPCError &error);
void setName(QString nameString, qint64 size);
bool fileFromClipboard(not_null<const QMimeData*> data);
@@ -104,11 +101,12 @@ private:
: _preparedList.files.front().path;
}
not_null<Window::SessionController*> _controller;
const not_null<Window::SessionController*> _controller;
MTP::Sender _api;
FullMsgId _msgId;
std::shared_ptr<Data::PhotoMedia> _photoMedia;
std::shared_ptr<Data::DocumentMedia> _documentMedia;
Image *_thumbnailImage = nullptr;
bool _thumbnailImageLoaded = false;
Fn<void()> _refreshThumbnail;
bool _animated = false;

View File

@@ -19,6 +19,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat_filters.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "settings/settings_common.h"
#include "base/event_filter.h"
#include "lang/lang_keys.h"
@@ -500,7 +502,7 @@ void EditFilterBox(
name->setMaxLength(kMaxFilterTitleLength);
name->setInstantReplaces(Ui::InstantReplaces::Default());
name->setInstantReplacesEnabled(
window->session().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue());
Ui::Emoji::SuggestionsController::Init(
box->getDelegate()->outerContainer(),
name,

View File

@@ -1100,10 +1100,13 @@ void LanguageBox::prepare() {
) | rpl::start_with_next([=](const Language &language) {
// "#custom" is applied each time it's passed to switchToLanguage().
// So we check that the language really has changed.
if (language.id != Lang::Current().id()) {
const auto currentId = [] {
return Lang::LanguageIdOrDefault(Lang::Current().id());
};
if (language.id != currentId()) {
Lang::CurrentCloudManager().switchToLanguage(language);
if (inner) {
inner->changeChosen(Lang::Current().id());
inner->changeChosen(currentId());
}
}
}, inner->lifetime());

View File

@@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/continuous_sliders.h"
#include "ui/effects/radial_animation.h"
#include "ui/emoji_config.h"
#include "storage/localstorage.h"
#include "storage/storage_account.h"
#include "storage/cache/storage_cache_database.h"
#include "data/data_session.h"
#include "lang/lang_keys.h"
@@ -206,7 +206,7 @@ void LocalStorageBox::Row::radialAnimationCallback() {
}
rpl::producer<> LocalStorageBox::Row::clearRequests() const {
return _clear->clicks() | rpl::map([] { return rpl::empty_value(); });
return _clear->clicks() | rpl::to_empty;
}
int LocalStorageBox::Row::resizeGetHeight(int newWidth) {
@@ -271,8 +271,8 @@ LocalStorageBox::LocalStorageBox(
: _session(session)
, _db(&session->data().cache())
, _dbBig(&session->data().cacheBigFile()) {
const auto &settings = Local::cacheSettings();
const auto &settingsBig = Local::cacheBigFileSettings();
const auto &settings = session->local().cacheSettings();
const auto &settingsBig = session->local().cacheBigFileSettings();
_totalSizeLimit = settings.totalSizeLimit + settingsBig.totalSizeLimit;
_mediaSizeLimit = settingsBig.totalSizeLimit;
_timeLimit = settings.totalTimeLimit;
@@ -560,8 +560,8 @@ void LocalStorageBox::setupLimits(not_null<Ui::VerticalLayout*> container) {
}
void LocalStorageBox::limitsChanged() {
const auto &settings = Local::cacheSettings();
const auto &settingsBig = Local::cacheBigFileSettings();
const auto &settings = _session->local().cacheSettings();
const auto &settingsBig = _session->local().cacheBigFileSettings();
const auto sizeLimit = _totalSizeLimit - _mediaSizeLimit;
const auto changed = (settings.totalSizeLimit != sizeLimit)
|| (settingsBig.totalSizeLimit != _mediaSizeLimit)
@@ -590,7 +590,7 @@ void LocalStorageBox::save() {
auto updateBig = Storage::Cache::Database::SettingsUpdate();
updateBig.totalSizeLimit = _mediaSizeLimit;
updateBig.totalTimeLimit = _timeLimit;
Local::updateCacheSettings(update, updateBig);
_session->local().updateCacheSettings(update, updateBig);
_session->data().cache().updateSettings(update);
closeBox();
}

View File

@@ -14,7 +14,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwindow.h"
#include "apiwrap.h"
#include "main/main_session.h"
#include "storage/localstorage.h"
#include "main/main_domain.h"
#include "core/application.h"
#include "storage/storage_domain.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/labels.h"
@@ -48,7 +50,7 @@ PasscodeBox::PasscodeBox(
not_null<Main::Session*> session,
bool turningOff)
: _session(session)
, _api(_session->api().instance())
, _api(&_session->mtp())
, _turningOff(turningOff)
, _about(st::boxWidth - st::boxPadding.left() * 1.5)
, _oldPasscode(this, st::defaultInputField, tr::lng_passcode_enter_old())
@@ -64,7 +66,7 @@ PasscodeBox::PasscodeBox(
not_null<Main::Session*> session,
const CloudFields &fields)
: _session(session)
, _api(_session->api().instance())
, _api(&_session->mtp())
, _turningOff(fields.turningOff)
, _cloudPwd(true)
, _cloudFields(fields)
@@ -450,7 +452,7 @@ void PasscodeBox::save(bool force) {
return;
}
if (Local::checkPasscode(old.toUtf8())) {
if (Core::App().domain().local().checkPasscode(old.toUtf8())) {
cSetPasscodeBadTries(0);
if (_turningOff) pwd = conf = QString();
} else {
@@ -518,8 +520,8 @@ void PasscodeBox::save(bool force) {
closeReplacedBy();
const auto weak = Ui::MakeWeak(this);
cSetPasscodeBadTries(0);
Local::setPasscode(pwd.toUtf8());
_session->localPasscodeChanged();
Core::App().domain().local().setPasscode(pwd.toUtf8());
Core::App().localPasscodeChanged();
if (weak) {
closeBox();
}
@@ -683,7 +685,7 @@ void PasscodeBox::setNewCloudPassword(const QString &newPassword) {
setPasswordDone(newPasswordBytes);
}).fail([=](const RPCError &error) {
setPasswordFail(newPasswordBytes, email, error);
}).send();
}).handleFloodErrors().send();
}
void PasscodeBox::changeCloudPassword(
@@ -736,9 +738,9 @@ void PasscodeBox::changeCloudPassword(
sendChangeCloudPassword(check, newPassword, secureSecret);
});
}
}).handleFloodErrors().fail([=](const RPCError &error) {
}).fail([=](const RPCError &error) {
setPasswordFail(error);
}).send();
}).handleFloodErrors().send();
}
void PasscodeBox::suggestSecretReset(const QString &newPassword) {
@@ -831,9 +833,9 @@ void PasscodeBox::sendChangeCloudPassword(
MTP_long(newSecureSecretId)))
)).done([=](const MTPBool &result) {
setPasswordDone(newPasswordBytes);
}).handleFloodErrors().fail([=](const RPCError &error) {
}).fail([=](const RPCError &error) {
setPasswordFail(newPasswordBytes, QString(), error);
}).send();
}).handleFloodErrors().send();
}
void PasscodeBox::badOldPasscode() {
@@ -895,13 +897,14 @@ void PasscodeBox::recover() {
if (_pattern == "-") return;
const auto box = getDelegate()->show(Box<RecoverBox>(
_session,
_pattern,
_cloudFields.notEmptyPassport));
box->passwordCleared(
) | rpl::map([] {
return QByteArray();
}) | rpl::start_to_stream(_newPasswordSet, lifetime());
) | rpl::map_to(
QByteArray()
) | rpl::start_to_stream(_newPasswordSet, lifetime());
box->recoveryExpired(
) | rpl::start_with_next([=] {
@@ -923,9 +926,11 @@ void PasscodeBox::recoverStartFail(const RPCError &error) {
RecoverBox::RecoverBox(
QWidget*,
not_null<Main::Session*> session,
const QString &pattern,
bool notEmptyPassport)
: _pattern(st::normalFont->elided(tr::lng_signin_recover_hint(tr::now, lt_recover_email, pattern), st::boxWidth - st::boxPadding.left() * 1.5))
: _api(&session->mtp())
, _pattern(st::normalFont->elided(tr::lng_signin_recover_hint(tr::now, lt_recover_email, pattern), st::boxWidth - st::boxPadding.left() * 1.5))
, _notEmptyPassport(notEmptyPassport)
, _recoverCode(this, st::defaultInputField, tr::lng_signin_code()) {
}
@@ -988,10 +993,13 @@ void RecoverBox::submit() {
}
const auto send = crl::guard(this, [=] {
_submitRequest = MTP::send(
MTPauth_RecoverPassword(MTP_string(code)),
rpcDone(&RecoverBox::codeSubmitDone, true),
rpcFail(&RecoverBox::codeSubmitFail));
_submitRequest = _api.request(MTPauth_RecoverPassword(
MTP_string(code)
)).done([=](const MTPauth_Authorization &result) {
codeSubmitDone(result);
}).fail([=](const RPCError &error) {
codeSubmitFail(error);
}).handleFloodErrors().send();
});
if (_notEmptyPassport) {
const auto box = std::make_shared<QPointer<Ui::BoxContent>>();
@@ -1015,9 +1023,7 @@ void RecoverBox::codeChanged() {
update();
}
void RecoverBox::codeSubmitDone(
bool recover,
const MTPauth_Authorization &result) {
void RecoverBox::codeSubmitDone(const MTPauth_Authorization &result) {
_submitRequest = 0;
_passwordCleared.fire({});
@@ -1026,16 +1032,14 @@ void RecoverBox::codeSubmitDone(
Ui::LayerOption::CloseOther);
}
bool RecoverBox::codeSubmitFail(const RPCError &error) {
void RecoverBox::codeSubmitFail(const RPCError &error) {
if (MTP::isFloodError(error)) {
_submitRequest = 0;
_error = tr::lng_flood_error(tr::now);
update();
_recoverCode->showError();
return true;
return;
}
if (MTP::isDefaultHandledError(error)) return false;
_submitRequest = 0;
const QString &err = error.type();
@@ -1044,33 +1048,31 @@ bool RecoverBox::codeSubmitFail(const RPCError &error) {
getDelegate()->show(
Box<InformBox>(tr::lng_cloud_password_removed(tr::now)),
Ui::LayerOption::CloseOther);
return true;
} else if (err == qstr("PASSWORD_RECOVERY_NA")) {
closeBox();
return true;
} else if (err == qstr("PASSWORD_RECOVERY_EXPIRED")) {
_recoveryExpired.fire({});
closeBox();
return true;
} else if (err == qstr("CODE_INVALID")) {
_error = tr::lng_signin_wrong_code(tr::now);
update();
_recoverCode->selectAll();
_recoverCode->setFocus();
_recoverCode->showError();
return true;
}
if (Logs::DebugEnabled()) { // internal server error
_error = err + ": " + error.description();
} else {
_error = Lang::Hard::ServerError();
if (Logs::DebugEnabled()) { // internal server error
_error = err + ": " + error.description();
} else {
_error = Lang::Hard::ServerError();
}
update();
_recoverCode->setFocus();
}
update();
_recoverCode->setFocus();
return false;
}
RecoveryEmailValidation ConfirmRecoveryEmail(const QString &pattern) {
RecoveryEmailValidation ConfirmRecoveryEmail(
not_null<Main::Session*> session,
const QString &pattern) {
const auto errors = std::make_shared<rpl::event_stream<QString>>();
const auto resent = std::make_shared<rpl::event_stream<QString>>();
const auto requestId = std::make_shared<mtpRequestId>(0);
@@ -1082,7 +1084,9 @@ RecoveryEmailValidation ConfirmRecoveryEmail(const QString &pattern) {
if (*requestId) {
return;
}
const auto done = [=](const MTPBool &result) {
*requestId = session->api().request(MTPaccount_ConfirmPasswordEmail(
MTP_string(code)
)).done([=](const MTPBool &result) {
*requestId = 0;
reloads->fire({});
if (*weak) {
@@ -1090,13 +1094,7 @@ RecoveryEmailValidation ConfirmRecoveryEmail(const QString &pattern) {
Box<InformBox>(tr::lng_cloud_password_was_set(tr::now)),
Ui::LayerOption::CloseOther);
}
};
const auto fail = [=](const RPCError &error) {
const auto skip = MTP::isDefaultHandledError(error)
&& !MTP::isFloodError(error);
if (skip) {
return false;
}
}).fail([=](const RPCError &error) {
*requestId = 0;
if (MTP::isFloodError(error)) {
errors->fire(tr::lng_flood_error(tr::now));
@@ -1114,26 +1112,20 @@ RecoveryEmailValidation ConfirmRecoveryEmail(const QString &pattern) {
} else {
errors->fire(Lang::Hard::ServerError());
}
return true;
};
*requestId = MTP::send(
MTPaccount_ConfirmPasswordEmail(MTP_string(code)),
rpcDone(done),
rpcFail(fail));
}).handleFloodErrors().send();
};
const auto resend = [=] {
if (*requestId) {
return;
}
*requestId = MTP::send(MTPaccount_ResendPasswordEmail(
), rpcDone([=](const MTPBool &result) {
*requestId = session->api().request(MTPaccount_ResendPasswordEmail(
)).done([=](const MTPBool &result) {
*requestId = 0;
resent->fire(tr::lng_cloud_password_resent(tr::now));
}), rpcFail([=](const RPCError &error) {
}).fail([=](const RPCError &error) {
*requestId = 0;
errors->fire(Lang::Hard::ServerError());
return true;
}));
}).send();
};
auto box = Passport::VerifyEmailBox(

View File

@@ -164,9 +164,13 @@ private:
};
class RecoverBox : public Ui::BoxContent, public RPCSender {
class RecoverBox final : public Ui::BoxContent {
public:
RecoverBox(QWidget*, const QString &pattern, bool notEmptyPassport);
RecoverBox(
QWidget*,
not_null<Main::Session*> session,
const QString &pattern,
bool notEmptyPassport);
rpl::producer<> passwordCleared() const;
rpl::producer<> recoveryExpired() const;
@@ -184,9 +188,10 @@ protected:
private:
void submit();
void codeChanged();
void codeSubmitDone(bool recover, const MTPauth_Authorization &result);
bool codeSubmitFail(const RPCError &error);
void codeSubmitDone(const MTPauth_Authorization &result);
void codeSubmitFail(const RPCError &error);
MTP::Sender _api;
mtpRequestId _submitRequest = 0;
QString _pattern;
@@ -206,4 +211,6 @@ struct RecoveryEmailValidation {
rpl::producer<> reloadRequests;
rpl::producer<> cancelRequests;
};
RecoveryEmailValidation ConfirmRecoveryEmail(const QString &pattern);
[[nodiscard]] RecoveryEmailValidation ConfirmRecoveryEmail(
not_null<Main::Session*> session,
const QString &pattern);

View File

@@ -19,11 +19,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/slide_wrap.h"
#include "ui/text_options.h"
#include "lang/lang_keys.h"
#include "observer_peer.h"
#include "storage/file_download.h"
#include "data/data_peer_values.h"
#include "data/data_chat.h"
#include "data/data_session.h"
#include "data/data_changes.h"
#include "base/unixtime.h"
#include "window/themes/window_theme.h"
#include "styles/style_layers.h"
@@ -662,19 +662,23 @@ PeerListContent::PeerListContent(
, _st(st)
, _controller(controller)
, _rowHeight(_st.item.height) {
subscribe(_controller->session().downloaderTaskFinished(), [=] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
using UpdateFlag = Notify::PeerUpdate::Flag;
auto changes = UpdateFlag::NameChanged | UpdateFlag::PhotoChanged;
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(changes, [this](const Notify::PeerUpdate &update) {
if (update.flags & UpdateFlag::PhotoChanged) {
this->update();
} else if (update.flags & UpdateFlag::NameChanged) {
handleNameChanged(update);
using UpdateFlag = Data::PeerUpdate::Flag;
_controller->session().changes().peerUpdates(
UpdateFlag::Name | UpdateFlag::Photo
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
if (update.flags & UpdateFlag::Name) {
handleNameChanged(update.peer);
}
}));
if (update.flags & UpdateFlag::Photo) {
this->update();
}
}, lifetime());
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
if (update.paletteChanged()) {
invalidatePixmapsCache();
@@ -1717,8 +1721,8 @@ PeerListContent::RowIndex PeerListContent::findRowIndex(
return result;
}
void PeerListContent::handleNameChanged(const Notify::PeerUpdate &update) {
auto byPeer = _rowsByPeer.find(update.peer);
void PeerListContent::handleNameChanged(not_null<PeerData*> peer) {
auto byPeer = _rowsByPeer.find(peer);
if (byPeer != _rowsByPeer.cend()) {
for (auto row : byPeer->second) {
if (addingToSearchIndex()) {

View File

@@ -34,10 +34,6 @@ struct ScrollToRequest;
class PopupMenu;
} // namespace Ui
namespace Notify {
struct PeerUpdate;
} // namespace Notify
using PaintRoundImageCallback = Fn<void(
Painter &p,
int x,
@@ -551,7 +547,7 @@ protected:
private:
void refreshIndices();
void removeRowAtIndex(std::vector<std::unique_ptr<PeerListRow>> &from, int index);
void handleNameChanged(const Notify::PeerUpdate &update);
void handleNameChanged(not_null<PeerData*> peer);
void invalidatePixmapsCache();

View File

@@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/peer_list_controllers.h"
#include "boxes/confirm_box.h"
#include "observer_peer.h"
#include "ui/widgets/checkbox.h"
#include "ui/ui_utility.h"
#include "main/main_session.h"
@@ -147,7 +146,7 @@ void PeerListRowWithLink::paintAction(
PeerListGlobalSearchController::PeerListGlobalSearchController(
not_null<Window::SessionNavigation*> navigation)
: _navigation(navigation)
, _api(_navigation->session().api().instance()) {
, _api(&_navigation->session().mtp()) {
_timer.setCallback([this] { searchOnServer(); });
}

View File

@@ -15,16 +15,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h"
#include "data/data_session.h"
#include "data/data_folder.h"
#include "data/data_changes.h"
#include "history/history.h"
#include "dialogs/dialogs_indexed_list.h"
#include "base/unixtime.h"
#include "main/main_session.h"
#include "mtproto/mtproto_config.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "window/window_session_controller.h"
#include "apiwrap.h"
#include "observer_peer.h"
#include "facades.h"
#include "facades.h" // Ui::showPeerHistory
#include "app.h"
namespace {
@@ -87,10 +88,11 @@ void AddParticipantsBoxController::subscribeToMigration() {
}
void AddParticipantsBoxController::rowClicked(not_null<PeerListRow*> row) {
const auto &serverConfig = session().serverConfig();
auto count = fullCount();
auto limit = _peer && (_peer->isChat() || _peer->isMegagroup())
? Global::MegagroupSizeMax()
: Global::ChatSizeMax();
? serverConfig.megagroupSizeMax
: serverConfig.chatSizeMax;
if (count < limit || row->checked()) {
delegate()->peerListSetRowChecked(row, !row->checked());
updateTitle();
@@ -100,8 +102,8 @@ void AddParticipantsBoxController::rowClicked(not_null<PeerListRow*> row) {
Box<MaxInviteBox>(_peer->asChannel()),
Ui::LayerOption::KeepOther);
}
} else if (count >= Global::ChatSizeMax()
&& count < Global::MegagroupSizeMax()) {
} else if (count >= serverConfig.chatSizeMax
&& count < serverConfig.megagroupSizeMax) {
Ui::show(
Box<InformBox>(tr::lng_profile_add_more_after_create(tr::now)),
Ui::LayerOption::KeepOther);
@@ -166,7 +168,9 @@ void AddParticipantsBoxController::updateTitle() {
&& _peer->isChannel()
&& !_peer->isMegagroup())
? QString()
: qsl("%1 / %2").arg(fullCount()).arg(Global::MegagroupSizeMax());
: qsl("%1 / %2"
).arg(fullCount()
).arg(session().serverConfig().megagroupSizeMax);
delegate()->peerListSetTitle(tr::lng_profile_add_participant());
delegate()->peerListSetAdditionalTitle(rpl::single(additional));
}
@@ -240,7 +244,7 @@ void AddParticipantsBoxController::Start(
box->boxClosing() | rpl::start_with_next([=] {
auto params = Window::SectionShow();
params.activation = anim::activation::background;
App::wnd()->sessionController()->showPeerHistory(
navigation->parentController()->showPeerHistory(
channel,
params,
ShowAtTheEndMsgId);
@@ -276,7 +280,7 @@ AddSpecialBoxController::AddSpecialBoxController(
peer,
&_additional))
, _peer(peer)
, _api(_peer->session().api().instance())
, _api(&_peer->session().mtp())
, _role(role)
, _additional(peer, Role::Members)
, _adminDoneCallback(std::move(adminDoneCallback))
@@ -348,17 +352,16 @@ void AddSpecialBoxController::prepareChatRows(not_null<ChatData*> chat) {
chat->updateFullForced();
}
using UpdateFlag = Notify::PeerUpdate::Flag;
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(
UpdateFlag::MembersChanged | UpdateFlag::AdminsChanged,
[=](const Notify::PeerUpdate &update) {
if (update.peer == chat) {
_additional.fillFromPeer();
if (update.flags & UpdateFlag::MembersChanged) {
rebuildChatRows(chat);
}
}
}));
using UpdateFlag = Data::PeerUpdate::Flag;
chat->session().changes().peerUpdates(
chat,
UpdateFlag::Members | UpdateFlag::Admins
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
_additional.fillFromPeer();
if (update.flags & UpdateFlag::Members) {
rebuildChatRows(chat);
}
}, lifetime());
}
void AddSpecialBoxController::rebuildChatRows(not_null<ChatData*> chat) {
@@ -830,7 +833,7 @@ AddSpecialBoxSearchController::AddSpecialBoxSearchController(
not_null<ParticipantsAdditionalData*> additional)
: _peer(peer)
, _additional(additional)
, _api(_peer->session().api().instance())
, _api(&_peer->session().mtp())
, _timer([=] { searchOnServer(); }) {
subscribeToMigration();
}

View File

@@ -83,7 +83,7 @@ class Controller {
public:
Controller(
not_null<Ui::GenericBox*> box,
not_null<Window::Controller*> window,
not_null<Window::SessionController*> window,
not_null<UserData*> user);
void prepare();
@@ -100,7 +100,7 @@ private:
bool inverted);
not_null<Ui::GenericBox*> _box;
not_null<Window::Controller*> _window;
not_null<Window::SessionController*> _window;
not_null<UserData*> _user;
Ui::Checkbox *_sharePhone = nullptr;
QString _phone;
@@ -111,7 +111,7 @@ private:
Controller::Controller(
not_null<Ui::GenericBox*> box,
not_null<Window::Controller*> window,
not_null<Window::SessionController*> window,
not_null<UserData*> user)
: _box(box)
, _window(window)
@@ -143,7 +143,7 @@ void Controller::setupCover() {
object_ptr<Info::Profile::Cover>(
_box,
_user,
_window->sessionController(),
_window,
(_phone.isEmpty()
? tr::lng_contact_mobile_hidden()
: rpl::single(App::formatPhone(_phone)))),
@@ -266,7 +266,7 @@ void Controller::setupSharePhoneNumber() {
void EditContactBox(
not_null<Ui::GenericBox*> box,
not_null<Window::Controller*> window,
not_null<Window::SessionController*> window,
not_null<UserData*> user) {
box->lifetime().make_state<Controller>(box, window, user)->prepare();
}

View File

@@ -12,10 +12,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class UserData;
namespace Window {
class Controller;
class SessionController;
} // namespace Window
void EditContactBox(
not_null<Ui::GenericBox*> box,
not_null<Window::Controller*> window,
not_null<Window::SessionController*> window,
not_null<UserData*> user);

View File

@@ -35,7 +35,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/core_cloud_password.h"
#include "base/unixtime.h"
#include "apiwrap.h"
#include "facades.h"
#include "main/main_session.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"

View File

@@ -13,22 +13,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/confirm_box.h"
#include "boxes/add_contact_box.h"
#include "main/main_session.h"
#include "mtproto/mtproto_config.h"
#include "apiwrap.h"
#include "lang/lang_keys.h"
#include "mainwidget.h"
#include "observer_peer.h"
#include "dialogs/dialogs_indexed_list.h"
#include "data/data_peer_values.h"
#include "data/data_session.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_user.h"
#include "data/data_changes.h"
#include "base/unixtime.h"
#include "ui/widgets/popup_menu.h"
#include "ui/ui_utility.h"
#include "window/window_session_controller.h"
#include "history/history.h"
#include "facades.h"
namespace {
@@ -286,20 +286,19 @@ void SubscribeToMigration(
if (const auto channel = peer->migrateTo()) {
migrate(channel);
} else if (!chat->isDeactivated()) {
const auto alive = lifetime.make_state<base::Subscription>();
const auto handler = [=](const Notify::PeerUpdate &update) {
if (update.peer == peer) {
if (const auto channel = peer->migrateTo()) {
const auto onstack = base::duplicate(migrate);
*alive = base::Subscription();
onstack(channel);
}
}
};
*alive = Notify::PeerUpdated().add_subscription(
Notify::PeerUpdatedHandler(
Notify::PeerUpdate::Flag::MigrationChanged,
handler));
chat->session().changes().peerUpdates(
peer,
Data::PeerUpdate::Flag::Migration
) | rpl::map([](const Data::PeerUpdate &update) {
return update.peer->migrateTo();
}) | rpl::filter([](ChannelData *channel) {
return (channel != nullptr);
}) | rpl::take(
1
) | rpl::start_with_next([=](not_null<ChannelData*> channel) {
const auto onstack = base::duplicate(migrate);
onstack(channel);
}, lifetime);
}
}
}
@@ -686,17 +685,15 @@ ParticipantsOnlineSorter::ParticipantsOnlineSorter(
: _peer(peer)
, _delegate(delegate)
, _sortByOnlineTimer([=] { sort(); }) {
const auto handleUpdate = [=](const Notify::PeerUpdate &update) {
peer->session().changes().peerUpdates(
Data::PeerUpdate::Flag::OnlineStatus
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
const auto peerId = update.peer->id;
if (const auto row = _delegate->peerListFindRow(peerId)) {
row->refreshStatus();
sortDelayed();
}
};
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(
Notify::PeerUpdate::Flag::UserOnlineChanged,
handleUpdate));
}, _lifetime);
sort();
}
@@ -710,7 +707,8 @@ void ParticipantsOnlineSorter::sort() {
const auto channel = _peer->asChannel();
if (channel
&& (!channel->isMegagroup()
|| channel->membersCount() > Global::ChatSizeMax())) {
|| (channel->membersCount()
> channel->session().serverConfig().chatSizeMax))) {
_onlineCount = 0;
return;
}
@@ -755,7 +753,7 @@ ParticipantsBoxController::ParticipantsBoxController(
: PeerListController(CreateSearchController(peer, role, &_additional))
, _navigation(navigation)
, _peer(peer)
, _api(_peer->session().api().instance())
, _api(&_peer->session().mtp())
, _role(role)
, _additional(peer, _role) {
subscribeToMigration();
@@ -847,8 +845,9 @@ void ParticipantsBoxController::Start(
return chat
? chat->canAddMembers()
: (channel->canAddMembers()
&& (channel->membersCount() < Global::ChatSizeMax()
|| channel->isMegagroup()));
&& (channel->isMegagroup()
|| (channel->membersCount()
< channel->session().serverConfig().chatSizeMax)));
case Role::Admins:
return chat
? chat->canAddAdmins()
@@ -927,7 +926,8 @@ void ParticipantsBoxController::addNewParticipants() {
if (chat) {
AddParticipantsBoxController::Start(_navigation, chat);
} else if (channel->isMegagroup()
|| channel->membersCount() < Global::ChatSizeMax()) {
|| (channel->membersCount()
< channel->session().serverConfig().chatSizeMax)) {
const auto count = delegate()->peerListFullRowsCount();
auto already = std::vector<not_null<UserData*>>();
already.reserve(count);
@@ -985,10 +985,10 @@ auto ParticipantsBoxController::saveState() const
const auto weak = result.get();
if (const auto chat = _peer->asChat()) {
Notify::PeerUpdateViewer(
chat->session().changes().peerUpdates(
chat,
Notify::PeerUpdate::Flag::MembersChanged
) | rpl::start_with_next([=](const Notify::PeerUpdate &) {
Data::PeerUpdate::Flag::Members
) | rpl::start_with_next([=] {
weak->controllerState = nullptr;
}, my->lifetime);
} else if (const auto channel = _peer->asMegagroup()) {
@@ -1104,23 +1104,20 @@ void ParticipantsBoxController::prepareChatRows(not_null<ChatData*> chat) {
chat->updateFullForced();
}
using UpdateFlag = Notify::PeerUpdate::Flag;
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(
UpdateFlag::MembersChanged
| UpdateFlag::AdminsChanged,
[=](const Notify::PeerUpdate &update) {
if (update.peer != chat) {
return;
}
_additional.fillFromPeer();
if ((update.flags & UpdateFlag::MembersChanged)
|| (_role == Role::Admins)) {
rebuildChatRows(chat);
}
if (update.flags & UpdateFlag::AdminsChanged) {
rebuildRowTypes();
}
}));
using UpdateFlag = Data::PeerUpdate::Flag;
chat->session().changes().peerUpdates(
chat,
UpdateFlag::Members | UpdateFlag::Admins
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
_additional.fillFromPeer();
if ((update.flags & UpdateFlag::Members)
|| (_role == Role::Admins)) {
rebuildChatRows(chat);
}
if (update.flags & UpdateFlag::Admins) {
rebuildRowTypes();
}
}, lifetime());
}
void ParticipantsBoxController::rebuildChatRows(not_null<ChatData*> chat) {
@@ -1893,7 +1890,7 @@ void ParticipantsBoxController::subscribeToCreatorChange(
channel->inputChannel,
MTP_channelParticipantsRecent(),
MTP_int(0),
MTP_int(Global::ChatSizeMax()),
MTP_int(channel->session().serverConfig().chatSizeMax),
MTP_int(0)
)).done([=](const MTPchannels_ChannelParticipants &result) {
if (channel->amCreator()) {
@@ -1928,7 +1925,7 @@ ParticipantsBoxSearchController::ParticipantsBoxSearchController(
: _channel(channel)
, _role(role)
, _additional(additional)
, _api(_channel->session().api().instance()) {
, _api(&_channel->session().mtp()) {
_timer.setCallback([=] { searchOnServer(); });
}

View File

@@ -50,7 +50,7 @@ enum class ParticipantsRole {
Kicked,
};
class ParticipantsOnlineSorter : private base::Subscriber {
class ParticipantsOnlineSorter {
public:
ParticipantsOnlineSorter(
not_null<PeerData*> peer,
@@ -63,10 +63,11 @@ private:
void sortDelayed();
void refreshOnlineCount();
not_null<PeerData*> _peer;
not_null<PeerListDelegate*> _delegate;
const not_null<PeerData*> _peer;
const not_null<PeerListDelegate*> _delegate;
base::Timer _sortByOnlineTimer;
rpl::variable<int> _onlineCount = 0;
rpl::lifetime _lifetime;
};

View File

@@ -19,6 +19,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/peers/edit_linked_chat_box.h"
#include "boxes/stickers_box.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_peer.h"
@@ -29,7 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwidget.h"
#include "mainwindow.h"
#include "mtproto/sender.h"
#include "observer_peer.h"
#include "ui/rp_widget.h"
#include "ui/special_buttons.h"
#include "ui/toast/toast.h"
@@ -192,9 +193,11 @@ void SaveSlowmodeSeconds(
api->registerModifyRequest(key, requestId);
}
void ShowEditPermissions(not_null<PeerData*> peer) {
void ShowEditPermissions(
not_null<Window::SessionNavigation*> navigation,
not_null<PeerData*> peer) {
const auto box = Ui::show(
Box<EditPeerPermissionsBox>(peer),
Box<EditPeerPermissionsBox>(navigation, peer),
Ui::LayerOption::KeepOther);
const auto saving = box->lifetime().make_state<int>(0);
const auto save = [=](
@@ -356,7 +359,7 @@ Controller::Controller(
: _navigation(navigation)
, _box(box)
, _peer(peer)
, _api(_peer->session().api().instance())
, _api(&_peer->session().mtp())
, _isGroup(_peer->isChat() || _peer->isMegagroup()) {
_box->setTitle(_isGroup
? tr::lng_edit_group()
@@ -465,7 +468,7 @@ object_ptr<Ui::RpWidget> Controller::createTitleEdit() {
result->entity()->setMaxLength(kMaxGroupChannelTitle);
result->entity()->setInstantReplaces(Ui::InstantReplaces::Default());
result->entity()->setInstantReplacesEnabled(
_peer->session().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue());
Ui::Emoji::SuggestionsController::Init(
_wrap->window(),
result->entity(),
@@ -499,8 +502,8 @@ object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
result->entity()->setMaxLength(kMaxChannelDescription);
result->entity()->setInstantReplaces(Ui::InstantReplaces::Default());
result->entity()->setInstantReplacesEnabled(
_peer->session().settings().replaceEmojiValue());
result->entity()->setSubmitSettings(_peer->session().settings().sendSubmitWay());
Core::App().settings().replaceEmojiValue());
result->entity()->setSubmitSettings(Core::App().settings().sendSubmitWay());
Ui::Emoji::SuggestionsController::Init(
_wrap->window(),
result->entity(),
@@ -561,7 +564,9 @@ object_ptr<Ui::RpWidget> Controller::createStickersEdit() {
tr::lng_group_stickers_add(tr::now),
st::editPeerInviteLinkButton)
)->addClickHandler([=] {
Ui::show(Box<StickersBox>(channel), Ui::LayerOption::KeepOther);
Ui::show(
Box<StickersBox>(_navigation->parentController(), channel),
Ui::LayerOption::KeepOther);
});
return result;
@@ -830,8 +835,6 @@ void Controller::fillHistoryVisibilityButton() {
void Controller::fillManageSection() {
Expects(_controls.buttonsLayout != nullptr);
const auto navigation = App::wnd()->sessionController();
const auto chat = _peer->asChat();
const auto channel = _peer->asChannel();
const auto isChannel = (!chat);
@@ -943,7 +946,7 @@ void Controller::fillManageSection() {
Info::Profile::RestrictionsCountValue
) | rpl::flatten_latest(
) | ToPositiveNumberStringRestrictions(),
[=] { ShowEditPermissions(_peer); },
[=] { ShowEditPermissions(_navigation, _peer); },
st::infoIconPermissions);
}
if (canViewAdmins) {
@@ -958,7 +961,7 @@ void Controller::fillManageSection() {
) | ToPositiveNumberString(),
[=] {
ParticipantsBoxController::Start(
navigation,
_navigation,
_peer,
ParticipantsBoxController::Role::Admins);
},
@@ -976,7 +979,7 @@ void Controller::fillManageSection() {
) | ToPositiveNumberString(),
[=] {
ParticipantsBoxController::Start(
navigation,
_navigation,
_peer,
ParticipantsBoxController::Role::Members);
},
@@ -990,7 +993,7 @@ void Controller::fillManageSection() {
| ToPositiveNumberString(),
[=] {
ParticipantsBoxController::Start(
navigation,
_navigation,
_peer,
ParticipantsBoxController::Role::Kicked);
},
@@ -1002,7 +1005,7 @@ void Controller::fillManageSection() {
tr::lng_manage_peer_recent_actions(),
rpl::single(QString()), //Empty count.
[=] {
navigation->showSection(AdminLog::SectionMemento(channel));
_navigation->showSection(AdminLog::SectionMemento(channel));
},
st::infoIconRecentActions);
}
@@ -1440,15 +1443,22 @@ void Controller::deleteChannel() {
const auto channel = _peer->asChannel();
const auto chat = channel->migrateFrom();
const auto session = &_peer->session();
Ui::hideLayer();
Ui::showChatsList();
Ui::showChatsList(session);
if (chat) {
chat->session().api().deleteConversation(chat, false);
session->api().deleteConversation(chat, false);
}
MTP::send(
MTPchannels_DeleteChannel(channel->inputChannel),
App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
App::main()->rpcFail(&MainWidget::deleteChannelFailed));
session->api().request(MTPchannels_DeleteChannel(
channel->inputChannel
)).done([=](const MTPUpdates &result) {
session->api().applyUpdates(result);
//}).fail([=](const RPCError &error) {
// if (error.type() == qstr("CHANNEL_TOO_LARGE")) {
// Ui::show(Box<InformBox>(tr::lng_cant_delete_channel(tr::now)));
// }
}).send();
}
} // namespace

View File

@@ -307,8 +307,10 @@ ChatAdminRights FullAdminRights(bool isGroup) {
EditPeerPermissionsBox::EditPeerPermissionsBox(
QWidget*,
not_null<Window::SessionNavigation*> navigation,
not_null<PeerData*> peer)
: _peer(peer->migrateToOrMe()) {
: _navigation(navigation)
, _peer(peer->migrateToOrMe()) {
}
auto EditPeerPermissionsBox::saveEvents() const -> rpl::producer<Result> {
@@ -522,8 +524,6 @@ void EditPeerPermissionsBox::addBannedButtons(
}
}
const auto channel = _peer->asChannel();
const auto navigation = App::wnd()->sessionController();
container->add(EditPeerInfoBox::CreateButton(
container,
tr::lng_manage_peer_exceptions(),
@@ -532,7 +532,7 @@ void EditPeerPermissionsBox::addBannedButtons(
: rpl::single(0)) | ToPositiveNumberString(),
[=] {
ParticipantsBoxController::Start(
navigation,
_navigation,
_peer,
ParticipantsBoxController::Role::Restricted);
},
@@ -545,7 +545,7 @@ void EditPeerPermissionsBox::addBannedButtons(
| ToPositiveNumberString(),
[=] {
ParticipantsBoxController::Start(
navigation,
_navigation,
_peer,
ParticipantsBoxController::Role::Kicked);
},

View File

@@ -15,9 +15,16 @@ class RoundButton;
class VerticalLayout;
} // namespace Ui
namespace Window {
class SessionNavigation;
} // namespace Window
class EditPeerPermissionsBox : public Ui::BoxContent {
public:
EditPeerPermissionsBox(QWidget*, not_null<PeerData*> peer);
EditPeerPermissionsBox(
QWidget*,
not_null<Window::SessionNavigation*> navigation,
not_null<PeerData*> peer);
struct Result {
MTPDchatBannedRights::Flags rights;
@@ -34,7 +41,8 @@ private:
void addSlowmodeLabels(not_null<Ui::VerticalLayout*> container);
void addBannedButtons(not_null<Ui::VerticalLayout*> container);
not_null<PeerData*> _peer;
const not_null<Window::SessionNavigation*> _navigation;
const not_null<PeerData*> _peer;
Ui::RoundButton *_save = nullptr;
Fn<Result()> _value;

View File

@@ -19,11 +19,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "data/data_changes.h"
#include "info/profile/info_profile_values.h"
#include "lang/lang_keys.h"
#include "mainwindow.h"
#include "mtproto/sender.h"
#include "observer_peer.h"
#include "ui/rp_widget.h"
#include "ui/special_buttons.h"
#include "ui/toast/toast.h"
@@ -168,7 +168,7 @@ Controller::Controller(
std::optional<Privacy> privacySavedValue,
std::optional<QString> usernameSavedValue)
: _peer(peer)
, _api(_peer->session().api().instance())
, _api(&_peer->session().mtp())
, _privacySavedValue(privacySavedValue)
, _usernameSavedValue(usernameSavedValue)
, _useLocationPhrases(useLocationPhrases)
@@ -335,7 +335,7 @@ object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
st::setupChannelLink,
nullptr,
username,
true));
_peer->session().createInternalLink(QString())));
_controls.usernameInput->heightValue(
) | rpl::start_with_next([placeholder](int height) {
placeholder->resize(placeholder->width(), height);
@@ -485,12 +485,12 @@ void Controller::usernameChanged() {
_checkUsernameTimer.cancel();
return;
}
const auto bad = ranges::find_if(username, [](QChar ch) {
const auto bad = ranges::any_of(username, [](QChar ch) {
return (ch < 'A' || ch > 'Z')
&& (ch < 'a' || ch > 'z')
&& (ch < '0' || ch > '9')
&& (ch != '_');
}) != username.end();
});
if (bad) {
showUsernameError(tr::lng_create_channel_link_bad_symbols());
} else if (username.size() < kMinUsernameLength) {
@@ -574,9 +574,9 @@ void Controller::observeInviteLink() {
if (!_controls.editInviteLinkWrap) {
return;
}
Notify::PeerUpdateValue(
_peer->session().changes().peerFlagsValue(
_peer,
Notify::PeerUpdate::Flag::InviteLinkChanged
Data::PeerUpdate::Flag::InviteLink
) | rpl::start_with_next([=] {
refreshCreateInviteLink();
refreshEditInviteLink();

View File

@@ -14,6 +14,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/input_fields.h"
#include "mainwindow.h"
#include "main/main_session.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "apiwrap.h"
#include "styles/style_layers.h"
#include "styles/style_calls.h"
@@ -31,7 +33,7 @@ RateCallBox::RateCallBox(
uint64 callId,
uint64 callAccessHash)
: _session(session)
, _api(_session->api().instance())
, _api(&_session->mtp())
, _callId(callId)
, _callAccessHash(callAccessHash) {
}
@@ -85,7 +87,7 @@ void RateCallBox::ratingChanged(int value) {
Ui::InputField::Mode::MultiLine,
tr::lng_call_rate_comment());
_comment->show();
_comment->setSubmitSettings(_session->settings().sendSubmitWay());
_comment->setSubmitSettings(Core::App().settings().sendSubmitWay());
_comment->setMaxLength(kRateCallCommentLengthMax);
_comment->resize(width() - (st::callRatingPadding.left() + st::callRatingPadding.right()), _comment->height());

View File

@@ -15,8 +15,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/toast/toast.h"
#include "mtproto/facade.h"
#include "mainwindow.h"
#include "core/core_settings.h"
#include "core/application.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_profile.h"
@@ -28,11 +29,13 @@ constexpr auto kReportReasonLengthMax = 200;
} // namespace
ReportBox::ReportBox(QWidget*, not_null<PeerData*> peer)
: _peer(peer) {
: _peer(peer)
, _api(&_peer->session().mtp()) {
}
ReportBox::ReportBox(QWidget*, not_null<PeerData*> peer, MessageIdsList ids)
: _peer(peer)
, _api(&_peer->session().mtp())
, _ids(std::move(ids)) {
}
@@ -107,7 +110,7 @@ void ReportBox::reasonChanged(Reason reason) {
Ui::InputField::Mode::MultiLine,
tr::lng_report_reason_description());
_reasonOtherText->show();
_reasonOtherText->setSubmitSettings(_peer->session().settings().sendSubmitWay());
_reasonOtherText->setSubmitSettings(Core::App().settings().sendSubmitWay());
_reasonOtherText->setMaxLength(kReportReasonLengthMax);
_reasonOtherText->resize(width() - (st::boxPadding.left() + st::boxOptionListPadding.left() + st::boxPadding.right()), _reasonOtherText->height());
@@ -137,7 +140,9 @@ void ReportBox::reasonResized() {
}
void ReportBox::report() {
if (_requestId) return;
if (_requestId) {
return;
}
if (_reasonOtherText && _reasonOtherText->getLastText().trimmed().isEmpty()) {
_reasonOtherText->showError();
@@ -159,18 +164,24 @@ void ReportBox::report() {
for (const auto &fullId : *_ids) {
ids.push_back(MTP_int(fullId.msg));
}
_requestId = MTP::send(
MTPmessages_Report(
_peer->input,
MTP_vector<MTPint>(ids),
reason),
rpcDone(&ReportBox::reportDone),
rpcFail(&ReportBox::reportFail));
_requestId = _api.request(MTPmessages_Report(
_peer->input,
MTP_vector<MTPint>(ids),
reason
)).done([=](const MTPBool &result) {
reportDone(result);
}).fail([=](const RPCError &error) {
reportFail(error);
}).send();
} else {
_requestId = MTP::send(
MTPaccount_ReportPeer(_peer->input, reason),
rpcDone(&ReportBox::reportDone),
rpcFail(&ReportBox::reportFail));
_requestId = _api.request(MTPaccount_ReportPeer(
_peer->input,
reason
)).done([=](const MTPBool &result) {
reportDone(result);
}).fail([=](const RPCError &error) {
reportFail(error);
}).send();
}
}
@@ -180,16 +191,11 @@ void ReportBox::reportDone(const MTPBool &result) {
closeBox();
}
bool ReportBox::reportFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) {
return false;
}
void ReportBox::reportFail(const RPCError &error) {
_requestId = 0;
if (_reasonOtherText) {
_reasonOtherText->showError();
}
return true;
}
void ReportBox::updateMaxHeight() {

View File

@@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "boxes/abstract_box.h"
#include "mtproto/mtproto_rpc_sender.h"
#include "mtproto/sender.h"
namespace Ui {
template <typename Enum>
@@ -18,7 +18,7 @@ class Radioenum;
class InputField;
} // namespace Ui
class ReportBox : public Ui::BoxContent, public RPCSender {
class ReportBox final : public Ui::BoxContent {
public:
ReportBox(QWidget*, not_null<PeerData*> peer);
ReportBox(QWidget*, not_null<PeerData*> peer, MessageIdsList ids);
@@ -43,9 +43,10 @@ private:
void report();
void reportDone(const MTPBool &result);
bool reportFail(const RPCError &error);
void reportFail(const RPCError &error);
not_null<PeerData*> _peer;
const not_null<PeerData*> _peer;
MTP::Sender _api;
std::optional<MessageIdsList> _ids;
std::shared_ptr<Ui::RadioenumGroup<Reason>> _reasonGroup;

View File

@@ -7,10 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/send_files_box.h"
#include "platform/platform_specific.h"
#include "lang/lang_keys.h"
#include "storage/localstorage.h"
#include "storage/storage_media_prepare.h"
#include "mainwidget.h"
#include "main/main_session.h"
#include "mtproto/mtproto_config.h"
#include "chat_helpers/message_field.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "chat_helpers/tabbed_panel.h"
@@ -34,8 +37,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/clip/media_clip_reader.h"
#include "api/api_common.h"
#include "window/window_session_controller.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "layout.h"
#include "facades.h"
#include "facades.h" // App::LambdaDelayed.
#include "app.h"
#include "styles/style_history.h"
#include "styles/style_layers.h"
@@ -57,10 +62,7 @@ enum class ButtonType {
};
inline bool CanAddUrls(const QList<QUrl> &urls) {
return !urls.isEmpty() && ranges::find_if(
urls,
[](const QUrl &url) { return !url.isLocalFile(); }
) == urls.end();
return !urls.isEmpty() && ranges::all_of(urls, &QUrl::isLocalFile);
}
inline bool IsFirstAlbumItem(const Storage::PreparedList &list) {
@@ -1831,11 +1833,7 @@ void SendFilesBox::setupShadows(
}
void SendFilesBox::prepare() {
_send = addButton(
(_sendType == Api::SendType::Normal
? tr::lng_send_button()
: tr::lng_schedule_button()),
[=] { send({}); });
_send = addButton(tr::lng_send_button(), [=] { send({}); });
if (_sendType == Api::SendType::Normal) {
SetupSendMenuAndShortcuts(
_send,
@@ -1853,9 +1851,8 @@ void SendFilesBox::prepare() {
}
}, lifetime());
const auto title = tr::lng_stickers_featured_add(tr::now) + qsl("...");
_addFileToAlbum = addLeftButton(
rpl::single(title),
tr::lng_stickers_featured_add(),
App::LambdaDelayed(st::historyAttach.ripple.hideDuration, this, [=] {
openDialogToAddFileToAlbum();
}));
@@ -1914,7 +1911,7 @@ void SendFilesBox::initSendWay() {
? SendFilesWay::Album
: SendFilesWay::Photos;
}
const auto way = _controller->session().settings().sendFilesWay();
const auto way = Core::App().settings().sendFilesWay();
if (way == SendFilesWay::Files) {
return way;
} else if (way == SendFilesWay::Album) {
@@ -2045,8 +2042,10 @@ void SendFilesBox::applyAlbumOrder() {
}
void SendFilesBox::setupCaption() {
_caption->setMaxLength(Global::CaptionLengthMax());
_caption->setSubmitSettings(_controller->session().settings().sendSubmitWay());
_caption->setMaxLength(
_controller->session().serverConfig().captionLengthMax);
_caption->setSubmitSettings(
Core::App().settings().sendSubmitWay());
connect(_caption, &Ui::InputField::resized, [=] {
captionResized();
});
@@ -2070,16 +2069,16 @@ void SendFilesBox::setupCaption() {
});
_caption->setInstantReplaces(Ui::InstantReplaces::Default());
_caption->setInstantReplacesEnabled(
_controller->session().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue());
_caption->setMarkdownReplacesEnabled(rpl::single(true));
_caption->setEditLinkCallback(
DefaultEditLinkCallback(&_controller->session(), _caption));
DefaultEditLinkCallback(_controller, _caption));
Ui::Emoji::SuggestionsController::Init(
getDelegate()->outerContainer(),
_caption,
&_controller->session());
InitSpellchecker(&_controller->session(), _caption);
InitSpellchecker(_controller, _caption);
updateCaptionPlaceholder();
setupEmojiPanel();
@@ -2173,7 +2172,10 @@ bool SendFilesBox::addFiles(not_null<const QMimeData*> data) {
if (result.error == Storage::PreparedList::Error::None) {
return result;
} else if (data->hasImage()) {
auto image = qvariant_cast<QImage>(data->imageData());
auto image = Platform::GetImageFromClipboard();
if (image.isNull()) {
image = qvariant_cast<QImage>(data->imageData());
}
if (!image.isNull()) {
return Storage::PrepareMediaFromImage(
std::move(image),
@@ -2340,7 +2342,7 @@ void SendFilesBox::send(
const auto way = _sendWay ? _sendWay->value() : Way::Files;
if (_compressConfirm == CompressConfirm::Auto) {
const auto oldWay = _controller->session().settings().sendFilesWay();
const auto oldWay = Core::App().settings().sendFilesWay();
if (way != oldWay) {
// Check if the user _could_ use the old value, but didn't.
if ((oldWay == Way::Album && _sendAlbum)
@@ -2348,8 +2350,8 @@ void SendFilesBox::send(
|| (oldWay == Way::Files && _sendFiles)
|| (way == Way::Files && (_sendAlbum || _sendPhotos))) {
// And in that case save it to settings.
_controller->session().settings().setSendFilesWay(way);
_controller->session().saveSettingsDelayed();
Core::App().settings().setSendFilesWay(way);
Core::App().saveSettingsDelayed();
}
}
}

View File

@@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "apiwrap.h"
#include "main/main_session.h"
#include "data/data_session.h"
#include "base/unixtime.h"
@@ -78,7 +77,7 @@ private:
SessionsBox::SessionsBox(QWidget*, not_null<Main::Session*> session)
: _session(session)
, _api(_session->api().instance())
, _api(&_session->mtp())
, _shortPollTimer([=] { shortPollSessions(); }) {
}
@@ -426,9 +425,7 @@ void SessionsBox::Inner::showData(const Full &data) {
}
rpl::producer<> SessionsBox::Inner::terminateAll() const {
return _terminateAll->clicks() | rpl::map([] {
return rpl::empty_value();
});
return _terminateAll->clicks() | rpl::to_empty;
}
rpl::producer<uint64> SessionsBox::Inner::terminateOne() const {

View File

@@ -8,12 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/share_box.h"
#include "dialogs/dialogs_indexed_list.h"
#include "observer_peer.h"
#include "lang/lang_keys.h"
#include "mainwindow.h"
#include "mainwidget.h"
#include "base/qthelp_url.h"
#include "storage/localstorage.h"
#include "storage/storage_account.h"
#include "boxes/confirm_box.h"
#include "apiwrap.h"
#include "ui/toast/toast.h"
@@ -35,16 +34,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h"
#include "data/data_session.h"
#include "data/data_folder.h"
#include "data/data_changes.h"
#include "main/main_session.h"
#include "core/application.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_history.h"
class ShareBox::Inner
: public Ui::RpWidget
, public RPCSender
, private base::Subscriber {
class ShareBox::Inner final : public Ui::RpWidget, private base::Subscriber {
public:
Inner(
QWidget *parent,
@@ -94,7 +91,6 @@ private:
Ui::Animations::Simple nameActive;
};
void notifyPeerUpdated(const Notify::PeerUpdate &update);
void invalidateCache();
int displayedChatsCount() const;
@@ -163,6 +159,7 @@ ShareBox::ShareBox(
SubmitCallback &&submitCallback,
FilterCallback &&filterCallback)
: _navigation(navigation)
, _api(&_navigation->session().mtp())
, _copyCallback(std::move(copyCallback))
, _submitCallback(std::move(submitCallback))
, _filterCallback(std::move(filterCallback))
@@ -202,13 +199,13 @@ void ShareBox::prepareCommentField() {
field->setInstantReplaces(Ui::InstantReplaces::Default());
field->setInstantReplacesEnabled(
_navigation->session().settings().replaceEmojiValue());
Core::App().settings().replaceEmojiValue());
field->setMarkdownReplacesEnabled(rpl::single(true));
field->setEditLinkCallback(
DefaultEditLinkCallback(&_navigation->session(), field));
field->setSubmitSettings(_navigation->session().settings().sendSubmitWay());
DefaultEditLinkCallback(_navigation->parentController(), field));
field->setSubmitSettings(Core::App().settings().sendSubmitWay());
InitSpellchecker(&_navigation->session(), field);
InitSpellchecker(_navigation->parentController(), field);
Ui::SendPendingMoveResizeEvents(_comment);
}
@@ -309,18 +306,20 @@ bool ShareBox::searchByUsername(bool searchCache) {
if (i != _peopleCache.cend()) {
_peopleQuery = query;
_peopleRequest = 0;
peopleReceived(i.value(), 0);
peopleDone(i.value(), 0);
return true;
}
} else if (_peopleQuery != query) {
_peopleQuery = query;
_peopleFull = false;
_peopleRequest = MTP::send(
MTPcontacts_Search(
MTP_string(_peopleQuery),
MTP_int(SearchPeopleLimit)),
rpcDone(&ShareBox::peopleReceived),
rpcFail(&ShareBox::peopleFailed));
_peopleRequest = _api.request(MTPcontacts_Search(
MTP_string(_peopleQuery),
MTP_int(SearchPeopleLimit)
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {
peopleDone(result, requestId);
}).fail([=](const RPCError &error, mtpRequestId requestId) {
peopleFail(error, requestId);
}).send();
_peopleQueries.insert(_peopleRequest, _peopleQuery);
}
}
@@ -333,7 +332,7 @@ void ShareBox::needSearchByUsername() {
}
}
void ShareBox::peopleReceived(
void ShareBox::peopleDone(
const MTPcontacts_Found &result,
mtpRequestId requestId) {
Expects(result.type() == mtpc_contacts_found);
@@ -364,14 +363,11 @@ void ShareBox::peopleReceived(
}
}
bool ShareBox::peopleFailed(const RPCError &error, mtpRequestId requestId) {
if (MTP::isDefaultHandledError(error)) return false;
void ShareBox::peopleFail(const RPCError &error, mtpRequestId requestId) {
if (_peopleRequest == requestId) {
_peopleRequest = 0;
_peopleFull = true;
}
return true;
}
void ShareBox::setInnerFocus() {
@@ -561,14 +557,23 @@ ShareBox::Inner::Inner(
_filter = qsl("a");
updateFilter();
using UpdateFlag = Notify::PeerUpdate::Flag;
auto observeEvents = UpdateFlag::NameChanged | UpdateFlag::PhotoChanged;
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
notifyPeerUpdated(update);
}));
subscribe(_navigation->session().downloaderTaskFinished(), [=] {
_navigation->session().changes().peerUpdates(
Data::PeerUpdate::Flag::Photo
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
updateChat(update.peer);
}, lifetime());
_navigation->session().changes().realtimeNameUpdates(
) | rpl::start_with_next([=](const Data::NameUpdate &update) {
_chatsIndexed->peerNameChanged(
update.peer,
update.oldFirstLetters);
}, lifetime());
_navigation->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
if (update.paletteChanged()) {
@@ -619,16 +624,6 @@ void ShareBox::Inner::activateSkipPage(int pageHeight, int direction) {
activateSkipRow(direction * (pageHeight / _rowHeight));
}
void ShareBox::Inner::notifyPeerUpdated(const Notify::PeerUpdate &update) {
if (update.flags & Notify::PeerUpdate::Flag::NameChanged) {
_chatsIndexed->peerNameChanged(
update.peer,
update.oldNameFirstLetters);
}
updateChat(update.peer);
}
void ShareBox::Inner::updateChat(not_null<PeerData*> peer) {
if (const auto i = _dataMap.find(peer); i != end(_dataMap)) {
updateChatName(i->second.get(), peer);
@@ -1101,7 +1096,7 @@ QString AppendShareGameScoreUrl(
*reinterpret_cast<uint64*>(shareHashEncrypted.data()) ^= *reinterpret_cast<uint64*>(channelAccessHashInts);
// Encrypt data.
if (!Local::encrypt(shareHashData.constData(), shareHashEncrypted.data() + key128Size, shareHashData.size(), shareHashEncrypted.constData())) {
if (!session->local().encrypt(shareHashData.constData(), shareHashEncrypted.data() + key128Size, shareHashData.size(), shareHashEncrypted.constData())) {
return url;
}
@@ -1137,7 +1132,7 @@ void ShareGameScoreByHash(
// Decrypt data.
auto hashData = QByteArray(hashEncrypted.size() - key128Size, Qt::Uninitialized);
if (!Local::decrypt(hashEncrypted.constData() + key128Size, hashData.data(), hashEncrypted.size() - key128Size, hashEncrypted.constData())) {
if (!session->local().decrypt(hashEncrypted.constData() + key128Size, hashData.data(), hashEncrypted.size() - key128Size, hashEncrypted.constData())) {
return;
}

View File

@@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/timer.h"
#include "ui/effects/animations.h"
#include "ui/effects/round_checkbox.h"
#include "mtproto/mtproto_rpc_sender.h"
#include "mtproto/sender.h"
enum class SendMenuType;
@@ -33,10 +33,6 @@ class Row;
class IndexedList;
} // namespace Dialogs
namespace Notify {
struct PeerUpdate;
} // namespace Notify
namespace Ui {
class MultiSelect;
class InputField;
@@ -53,7 +49,7 @@ void ShareGameScoreByHash(
not_null<Main::Session*> session,
const QString &hash);
class ShareBox : public Ui::BoxContent, public RPCSender {
class ShareBox final : public Ui::BoxContent {
public:
using CopyCallback = Fn<void()>;
using SubmitCallback = Fn<void(
@@ -101,12 +97,13 @@ private:
void addPeerToMultiSelect(PeerData *peer, bool skipAnimation = false);
void innerSelectedChanged(PeerData *peer, bool checked);
void peopleReceived(
void peopleDone(
const MTPcontacts_Found &result,
mtpRequestId requestId);
bool peopleFailed(const RPCError &error, mtpRequestId requestId);
void peopleFail(const RPCError &error, mtpRequestId requestId);
const not_null<Window::SessionNavigation*> _navigation;
MTP::Sender _api;
CopyCallback _copyCallback;
SubmitCallback _submitCallback;

View File

@@ -11,12 +11,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "data/data_file_origin.h"
#include "data/data_document_media.h"
#include "data/stickers/data_stickers.h"
#include "lang/lang_keys.h"
#include "chat_helpers/stickers.h"
#include "boxes/confirm_box.h"
#include "core/application.h"
#include "mtproto/sender.h"
#include "storage/localstorage.h"
#include "storage/storage_account.h"
#include "dialogs/dialogs_layout.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/scroll_area.h"
@@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/emoji_config.h"
#include "lottie/lottie_multi_player.h"
#include "lottie/lottie_animation.h"
#include "chat_helpers/stickers_lottie.h"
#include "window/window_session_controller.h"
#include "base/unixtime.h"
#include "main/main_session.h"
@@ -43,6 +44,10 @@ namespace {
constexpr auto kStickersPanelPerRow = 5;
using Data::StickersSet;
using Data::StickersPack;
using Data::StickersByEmojiMap;
} // namespace
class StickerSetBox::Inner : public Ui::RpWidget, private base::Subscriber {
@@ -106,8 +111,8 @@ private:
MTP::Sender _api;
std::vector<Element> _elements;
std::unique_ptr<Lottie::MultiPlayer> _lottiePlayer;
Stickers::Pack _pack;
Stickers::ByEmojiMap _emoji;
StickersPack _pack;
StickersByEmojiMap _emoji;
bool _loaded = false;
uint64 _setId = 0;
uint64 _setAccess = 0;
@@ -159,7 +164,7 @@ void StickerSetBox::prepare() {
_inner = setInnerWidget(
object_ptr<Inner>(this, _controller, _set),
st::stickersScroll);
_controller->session().data().stickersUpdated(
_controller->session().data().stickers().updated(
) | rpl::start_with_next([=] {
updateButtons();
}, lifetime());
@@ -185,7 +190,8 @@ void StickerSetBox::addStickers() {
}
void StickerSetBox::shareStickers() {
auto url = Core::App().createInternalLinkFull(qsl("addstickers/") + _inner->shortName());
const auto url = _controller->session().createInternalLinkFull(
qsl("addstickers/") + _inner->shortName());
QGuiApplication::clipboard()->setText(url);
Ui::show(Box<InformBox>(tr::lng_stickers_copied(tr::now)));
}
@@ -224,7 +230,7 @@ StickerSetBox::Inner::Inner(
const MTPInputStickerSet &set)
: RpWidget(parent)
, _controller(controller)
, _api(_controller->session().api().instance())
, _api(&_controller->session().mtp())
, _input(set)
, _previewTimer([=] { showPreview(); }) {
set.match([&](const MTPDinputStickerSetID &data) {
@@ -248,7 +254,10 @@ StickerSetBox::Inner::Inner(
_controller->session().api().updateStickers();
subscribe(_controller->session().downloaderTaskFinished(), [this] { update(); });
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
setMouseTracking(true);
}
@@ -278,7 +287,7 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) {
const auto original = emoji->original();
auto &stickers = pack.vdocuments().v;
auto p = Stickers::Pack();
auto p = StickersPack();
p.reserve(stickers.size());
for (auto j = 0, c = stickers.size(); j != c; ++j) {
auto doc = _controller->session().data().document(stickers[j].v);
@@ -291,7 +300,8 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) {
});
}
data.vset().match([&](const MTPDstickerSet &set) {
_setTitle = Stickers::GetSetTitle(set);
_setTitle = _controller->session().data().stickers().getSetTitle(
set);
_setShortName = qs(set.vshort_name());
_setId = set.vid().v;
_setAccess = set.vaccess_hash().v;
@@ -307,7 +317,7 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) {
} else {
_setThumbnail = ImageWithLocation();
}
const auto &sets = _controller->session().data().stickerSets();
const auto &sets = _controller->session().data().stickers().sets();
const auto it = sets.find(_setId);
if (it != sets.cend()) {
const auto set = it->second.get();
@@ -350,13 +360,13 @@ rpl::producer<> StickerSetBox::Inner::updateControls() const {
void StickerSetBox::Inner::installDone(
const MTPmessages_StickerSetInstallResult &result) {
auto &sets = _controller->session().data().stickerSetsRef();
auto &sets = _controller->session().data().stickers().setsRef();
bool wasArchived = (_setFlags & MTPDstickerSet::Flag::f_archived);
if (wasArchived) {
auto index = _controller->session().data().archivedStickerSetsOrderRef().indexOf(_setId);
auto index = _controller->session().data().stickers().archivedSetsOrderRef().indexOf(_setId);
if (index >= 0) {
_controller->session().data().archivedStickerSetsOrderRef().removeAt(index);
_controller->session().data().stickers().archivedSetsOrderRef().removeAt(index);
}
}
_setInstallDate = base::unixtime::now();
@@ -366,7 +376,7 @@ void StickerSetBox::Inner::installDone(
if (it == sets.cend()) {
it = sets.emplace(
_setId,
std::make_unique<Stickers::Set>(
std::make_unique<StickersSet>(
&_controller->session().data(),
_setId,
_setAccess,
@@ -385,7 +395,7 @@ void StickerSetBox::Inner::installDone(
set->stickers = _pack;
set->emoji = _emoji;
auto &order = _controller->session().data().stickerSetsOrderRef();
auto &order = _controller->session().data().stickers().setsOrderRef();
int insertAtIndex = 0, currentIndex = order.indexOf(_setId);
if (currentIndex != insertAtIndex) {
if (currentIndex > 0) {
@@ -394,7 +404,7 @@ void StickerSetBox::Inner::installDone(
order.insert(insertAtIndex, _setId);
}
const auto customIt = sets.find(Stickers::CustomSetId);
const auto customIt = sets.find(Data::Stickers::CustomSetId);
if (customIt != sets.cend()) {
const auto custom = customIt->second.get();
for (const auto sticker : std::as_const(_pack)) {
@@ -407,13 +417,14 @@ void StickerSetBox::Inner::installDone(
}
if (result.type() == mtpc_messages_stickerSetInstallResultArchive) {
Stickers::ApplyArchivedResult(result.c_messages_stickerSetInstallResultArchive());
_controller->session().data().stickers().applyArchivedResult(
result.c_messages_stickerSetInstallResultArchive());
} else {
if (wasArchived) {
Local::writeArchivedStickers();
_controller->session().local().writeArchivedStickers();
}
Local::writeInstalledStickers();
_controller->session().data().notifyStickersUpdated();
_controller->session().local().writeInstalledStickers();
_controller->session().data().stickers().notifyUpdated();
}
_setInstalled.fire_copy(_setId);
}
@@ -454,8 +465,8 @@ void StickerSetBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
const auto index = stickerFromGlobalPos(e->globalPos());
if (index >= 0 && index < _pack.size() && !isMasksSet()) {
const auto sticker = _pack[index];
Ui::PostponeCall(crl::guard(App::main(), [=] {
if (App::main()->onSendSticker(sticker)) {
Ui::PostponeCall(crl::guard(_controller, [=] {
if (_controller->content()->sendExistingDocument(sticker)) {
Ui::hideSettingsAndLayer();
}
}));
@@ -610,10 +621,10 @@ void StickerSetBox::Inner::setupLottie(int index) {
auto &element = _elements[index];
const auto document = element.document;
element.animated = Stickers::LottieAnimationFromDocument(
element.animated = ChatHelpers::LottieAnimationFromDocument(
getLottiePlayer(),
element.documentMedia.get(),
Stickers::LottieSize::StickerSet,
ChatHelpers::StickerLottieSize::StickerSet,
boundingBoxSize() * cIntRetinaFactor());
}
@@ -677,7 +688,7 @@ bool StickerSetBox::Inner::notInstalled() const {
if (!_loaded) {
return false;
}
const auto &sets = _controller->session().data().stickerSets();
const auto &sets = _controller->session().data().stickers().sets();
const auto it = sets.find(_setId);
if ((it == sets.cend())
|| !(it->second->flags & MTPDstickerSet::Flag::f_installed_date)

View File

@@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h"
#include "base/timer.h"
#include "chat_helpers/stickers.h"
#include "data/stickers/data_stickers.h"
class ConfirmBox;
@@ -21,7 +21,7 @@ namespace Ui {
class PlainShadow;
} // namespace Ui
class StickerSetBox : public Ui::BoxContent, public RPCSender {
class StickerSetBox final : public Ui::BoxContent {
public:
StickerSetBox(
QWidget*,
@@ -43,7 +43,7 @@ private:
void addStickers();
void shareStickers();
not_null<Window::SessionController*> _controller;
const not_null<Window::SessionController*> _controller;
MTPInputStickerSet _set;
class Inner;

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h"
#include "base/timer.h"
#include "mtproto/sender.h"
#include "chat_helpers/stickers_set.h"
#include "data/stickers/data_stickers_set.h"
#include "ui/effects/animations.h"
#include "ui/special_fields.h"
@@ -29,6 +29,10 @@ class CrossButton;
class BoxContentDivider;
} // namespace Ui
namespace Window {
class SessionController;
} // namespace Window
namespace Main {
class Session;
} // namespace Main
@@ -45,10 +49,7 @@ namespace Stickers {
class Set;
} // namespace Stickers
class StickersBox final
: public Ui::BoxContent
, public RPCSender
, private base::Subscriber {
class StickersBox final : public Ui::BoxContent, private base::Subscriber {
public:
enum class Section {
Installed,
@@ -59,18 +60,22 @@ public:
StickersBox(
QWidget*,
not_null<Main::Session*> session,
not_null<Window::SessionController*> controller,
Section section);
StickersBox(QWidget*, not_null<ChannelData*> megagroup);
StickersBox(
QWidget*,
not_null<Main::Session*> session,
not_null<Window::SessionController*> controller,
not_null<ChannelData*> megagroup);
StickersBox(
QWidget*,
not_null<Window::SessionController*> controller,
const MTPVector<MTPStickerSetCovered> &attachedSets);
~StickersBox();
[[nodiscard]] Main::Session &session() const;
void setInnerFocus() override;
~StickersBox();
protected:
void prepare() override;
@@ -89,12 +94,8 @@ private:
object_ptr<Inner> takeWidget();
void returnWidget(object_ptr<Inner> widget);
Inner *widget() {
return _weak;
}
int index() const {
return _index;
}
[[nodiscard]] Inner *widget();
[[nodiscard]] int index() const;
void saveScrollTop();
int getScrollTop() const {
@@ -121,15 +122,18 @@ private:
QPixmap grabContentCache();
void installDone(const MTPmessages_StickerSetInstallResult &result);
bool installFail(uint64 setId, const RPCError &error);
void installFail(const RPCError &error, uint64 setId);
void preloadArchivedSets();
void requestArchivedSets();
void loadMoreArchived();
void getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result);
void getArchivedDone(
const MTPmessages_ArchivedStickers &result,
uint64 offsetId);
void showAttachedStickers();
const not_null<Main::Session*> _session;
const not_null<Window::SessionController*> _controller;
MTP::Sender _api;
object_ptr<Ui::SettingsSlider> _tabs = { nullptr };
QList<Section> _tabIndices;
@@ -157,228 +161,7 @@ private:
bool _allArchivedLoaded = false;
bool _someArchivedLoaded = false;
Stickers::Order _localOrder;
Stickers::Order _localRemoved;
};
// This class is hold in header because it requires Qt preprocessing.
class StickersBox::Inner
: public Ui::RpWidget
, private base::Subscriber {
Q_OBJECT
public:
using Section = StickersBox::Section;
Inner(
QWidget *parent,
not_null<Main::Session*> session,
Section section);
Inner(QWidget *parent, not_null<ChannelData*> megagroup);
base::Observable<int> scrollToY;
void setInnerFocus();
void saveGroupSet();
void rebuild();
void updateSize(int newWidth = 0);
void updateRows(); // refresh only pack cover stickers
bool appendSet(not_null<Stickers::Set*> set);
Stickers::Order getOrder() const;
Stickers::Order getFullOrder() const;
Stickers::Order getRemovedSets() const;
void setFullOrder(const Stickers::Order &order);
void setRemovedSets(const Stickers::Order &removed);
void setInstallSetCallback(Fn<void(uint64 setId)> callback) {
_installSetCallback = std::move(callback);
}
void setLoadMoreCallback(Fn<void()> callback) {
_loadMoreCallback = std::move(callback);
}
void setMinHeight(int newWidth, int minHeight);
int getVisibleTop() const {
return _visibleTop;
}
~Inner();
protected:
void visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) override;
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void leaveEventHook(QEvent *e) override;
void leaveToChildEvent(QEvent *e, QWidget *child) override;
signals:
void draggingScrollDelta(int delta);
public slots:
void onUpdateSelected();
private:
struct Row {
Row(
not_null<Stickers::Set*> set,
DocumentData *sticker,
int32 count,
const QString &title,
int titleWidth,
bool installed,
bool official,
bool unread,
bool archived,
bool removed,
int32 pixw,
int32 pixh);
~Row();
bool isRecentSet() const;
const not_null<Stickers::Set*> set;
DocumentData *sticker = nullptr;
std::shared_ptr<Data::DocumentMedia> stickerMedia;
std::shared_ptr<Stickers::SetThumbnailView> thumbnailMedia;
int32 count = 0;
QString title;
int titleWidth = 0;
bool installed = false;
bool official = false;
bool unread = false;
bool archived = false;
bool removed = false;
int32 pixw = 0;
int32 pixh = 0;
anim::value yadd;
std::unique_ptr<Ui::RippleAnimation> ripple;
std::unique_ptr<Lottie::SinglePlayer> lottie;
};
struct MegagroupSet {
inline bool operator==(const MegagroupSet &other) const {
return true;
}
inline bool operator!=(const MegagroupSet &other) const {
return false;
}
};
using SelectedRow = base::optional_variant<MegagroupSet, int>;
class AddressField : public Ui::UsernameInput {
public:
using UsernameInput::UsernameInput;
protected:
void correctValue(
const QString &was,
int wasCursor,
QString &now,
int &nowCursor) override;
};
template <typename Check>
Stickers::Order collectSets(Check check) const;
void checkLoadMore();
void updateScrollbarWidth();
int getRowIndex(uint64 setId) const;
void setRowRemoved(int index, bool removed);
void setSelected(SelectedRow selected);
void setActionDown(int newActionDown);
void setPressed(SelectedRow pressed);
void setup();
QRect relativeButtonRect(bool removeButton) const;
void ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton);
bool shiftingAnimationCallback(crl::time now);
void paintRow(Painter &p, not_null<Row*> row, int index);
void paintRowThumbnail(Painter &p, not_null<Row*> row, int left);
void paintFakeButton(Painter &p, not_null<Row*> row, int index);
void clear();
void updateCursor();
void setActionSel(int32 actionSel);
float64 aboveShadowOpacity() const;
void validateLottieAnimation(not_null<Row*> row);
void updateRowThumbnail(not_null<Row*> row);
void readVisibleSets();
void updateControlsGeometry();
void rebuildAppendSet(not_null<Stickers::Set*> set, int maxNameWidth);
void fillSetCover(not_null<Stickers::Set*> set, DocumentData **outSticker, int *outWidth, int *outHeight) const;
int fillSetCount(not_null<Stickers::Set*> set) const;
QString fillSetTitle(not_null<Stickers::Set*> set, int maxNameWidth, int *outTitleWidth) const;
void fillSetFlags(not_null<Stickers::Set*> set, bool *outInstalled, bool *outOfficial, bool *outUnread, bool *outArchived);
void rebuildMegagroupSet();
void fixupMegagroupSetAddress();
void handleMegagroupSetAddressChange();
void setMegagroupSelectedSet(const MTPInputStickerSet &set);
int countMaxNameWidth() const;
const not_null<Main::Session*> _session;
MTP::Sender _api;
Section _section;
int32 _rowHeight;
std::vector<std::unique_ptr<Row>> _rows;
std::vector<crl::time> _shiftingStartTimes;
crl::time _aboveShadowFadeStart = 0;
anim::value _aboveShadowFadeOpacity;
Ui::Animations::Basic _shiftingAnimation;
Fn<void(uint64 setId)> _installSetCallback;
Fn<void()> _loadMoreCallback;
int _visibleTop = 0;
int _visibleBottom = 0;
int _itemsTop = 0;
int _actionSel = -1;
int _actionDown = -1;
QString _addText;
int _addWidth = 0;
QString _undoText;
int _undoWidth = 0;
int _buttonHeight = 0;
QPoint _mouse;
bool _inDragArea = false;
SelectedRow _selected;
SelectedRow _pressed;
QPoint _dragStart;
int _started = -1;
int _dragging = -1;
int _above = -1;
int _minHeight = 0;
int _scrollbar = 0;
ChannelData *_megagroupSet = nullptr;
MTPInputStickerSet _megagroupSetInput = MTP_inputStickerSetEmpty();
std::unique_ptr<Row> _megagroupSelectedSet;
object_ptr<AddressField> _megagroupSetField = { nullptr };
object_ptr<Ui::PlainShadow> _megagroupSelectedShadow = { nullptr };
object_ptr<Ui::CrossButton> _megagroupSelectedRemove = { nullptr };
object_ptr<Ui::BoxContentDivider> _megagroupDivider = { nullptr };
object_ptr<Ui::FlatLabel> _megagroupSubTitle = { nullptr };
base::Timer _megagroupSetAddressChangedTimer;
mtpRequestId _megagroupSetRequestId = 0;
Data::StickersSetsOrder _localOrder;
Data::StickersSetsOrder _localRemoved;
};

View File

@@ -28,7 +28,11 @@ void UrlAuthBox::Activate(
int row,
int column) {
const auto itemId = message->fullId();
const auto button = HistoryMessageMarkupButton::Get(itemId, row, column);
const auto button = HistoryMessageMarkupButton::Get(
&message->history()->owner(),
itemId,
row,
column);
if (button->requestId || !IsServerMsgId(itemId.msg)) {
return;
}
@@ -43,10 +47,13 @@ void UrlAuthBox::Activate(
MTP_int(buttonId)
)).done([=](const MTPUrlAuthResult &result) {
const auto button = HistoryMessageMarkupButton::Get(
&session->data(),
itemId,
row,
column);
if (!button) return;
if (!button) {
return;
}
button->requestId = 0;
result.match([&](const MTPDurlAuthResultAccepted &data) {
@@ -58,6 +65,7 @@ void UrlAuthBox::Activate(
});
}).fail([=](const RPCError &error) {
const auto button = HistoryMessageMarkupButton::Get(
&session->data(),
itemId,
row,
column);
@@ -74,7 +82,11 @@ void UrlAuthBox::Request(
int row,
int column) {
const auto itemId = message->fullId();
const auto button = HistoryMessageMarkupButton::Get(itemId, row, column);
const auto button = HistoryMessageMarkupButton::Get(
&message->history()->owner(),
itemId,
row,
column);
if (button->requestId || !IsServerMsgId(itemId.msg)) {
return;
}

View File

@@ -17,7 +17,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "mtproto/facade.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
@@ -32,12 +31,13 @@ constexpr auto kMinUsernameLength = 5;
UsernameBox::UsernameBox(QWidget*, not_null<Main::Session*> session)
: _session(session)
, _api(&_session->mtp())
, _username(
this,
st::defaultInputField,
rpl::single(qsl("@username")),
session->user()->username,
false)
QString())
, _link(this, QString(), st::boxLinkButton)
, _about(st::boxWidth - st::usernamePadding.left())
, _checkTimer(this) {
@@ -94,7 +94,8 @@ void UsernameBox::paintEvent(QPaintEvent *e) {
if (_link->isHidden()) {
p.drawTextLeft(st::usernamePadding.left(), linky, width(), tr::lng_username_link_willbe(tr::now));
p.setPen(st::usernameDefaultFg);
p.drawTextLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2), width(), Core::App().createInternalLinkFull(qsl("username")));
const auto link = _session->createInternalLinkFull(qsl("username"));
p.drawTextLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2), width(), link);
} else {
p.drawTextLeft(st::usernamePadding.left(), linky, width(), tr::lng_username_link(tr::now));
}
@@ -115,21 +116,28 @@ void UsernameBox::save() {
if (_saveRequestId) return;
_sentUsername = getName();
_saveRequestId = MTP::send(MTPaccount_UpdateUsername(MTP_string(_sentUsername)), rpcDone(&UsernameBox::onUpdateDone), rpcFail(&UsernameBox::onUpdateFail));
_saveRequestId = _api.request(MTPaccount_UpdateUsername(
MTP_string(_sentUsername)
)).done([=](const MTPUser &result) {
updateDone(result);
}).fail([=](const RPCError &error) {
updateFail(error);
}).send();
}
void UsernameBox::check() {
if (_checkRequestId) {
MTP::cancel(_checkRequestId);
}
_api.request(base::take(_checkRequestId)).cancel();
QString name = getName();
if (name.size() >= kMinUsernameLength) {
_checkUsername = name;
_checkRequestId = MTP::send(
MTPaccount_CheckUsername(
MTP_string(name)),
rpcDone(&UsernameBox::onCheckDone),
rpcFail(&UsernameBox::onCheckFail));
_checkRequestId = _api.request(MTPaccount_CheckUsername(
MTP_string(name)
)).done([=](const MTPBool &result) {
checkDone(result);
}).fail([=](const RPCError &error) {
checkFail(error);
}).send();
}
}
@@ -172,18 +180,17 @@ void UsernameBox::changed() {
}
void UsernameBox::linkClick() {
QGuiApplication::clipboard()->setText(Core::App().createInternalLinkFull(getName()));
QGuiApplication::clipboard()->setText(
_session->createInternalLinkFull(getName()));
Ui::Toast::Show(tr::lng_username_copied(tr::now));
}
void UsernameBox::onUpdateDone(const MTPUser &user) {
void UsernameBox::updateDone(const MTPUser &user) {
_session->data().processUser(user);
closeBox();
}
bool UsernameBox::onUpdateFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
void UsernameBox::updateFail(const RPCError &error) {
_saveRequestId = 0;
const auto self = _session->user();
const auto &err = error.type();
@@ -194,25 +201,22 @@ bool UsernameBox::onUpdateFail(const RPCError &error) {
TextUtilities::SingleLine(self->nameOrPhone),
TextUtilities::SingleLine(_sentUsername));
closeBox();
return true;
} else if (err == qstr("USERNAME_INVALID")) {
_username->setFocus();
_username->showError();
_errorText = tr::lng_username_invalid(tr::now);
update();
return true;
} else if (err == qstr("USERNAME_OCCUPIED") || err == qstr("USERNAMES_UNAVAILABLE")) {
_username->setFocus();
_username->showError();
_errorText = tr::lng_username_occupied(tr::now);
update();
return true;
} else {
_username->setFocus();
}
_username->setFocus();
return true;
}
void UsernameBox::onCheckDone(const MTPBool &result) {
void UsernameBox::checkDone(const MTPBool &result) {
_checkRequestId = 0;
const auto newError = (mtpIsTrue(result)
|| _checkUsername == _session->user()->username)
@@ -228,23 +232,19 @@ void UsernameBox::onCheckDone(const MTPBool &result) {
}
}
bool UsernameBox::onCheckFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
void UsernameBox::checkFail(const RPCError &error) {
_checkRequestId = 0;
QString err(error.type());
if (err == qstr("USERNAME_INVALID")) {
_errorText = tr::lng_username_invalid(tr::now);
update();
return true;
} else if (err == qstr("USERNAME_OCCUPIED") && _checkUsername != _session->user()->username) {
_errorText = tr::lng_username_occupied(tr::now);
update();
return true;
} else {
_goodText = QString();
_username->setFocus();
}
_goodText = QString();
_username->setFocus();
return true;
}
QString UsernameBox::getName() const {
@@ -253,7 +253,7 @@ QString UsernameBox::getName() const {
void UsernameBox::updateLinkText() {
QString uname = getName();
_link->setText(st::boxTextFont->elided(Core::App().createInternalLinkFull(uname), st::boxWidth - st::usernamePadding.left() - st::usernamePadding.right()));
_link->setText(st::boxTextFont->elided(_session->createInternalLinkFull(uname), st::boxWidth - st::usernamePadding.left() - st::usernamePadding.right()));
if (uname.isEmpty()) {
if (!_link->isHidden()) {
_link->hide();

View File

@@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "boxes/abstract_box.h"
#include "mtproto/mtproto_rpc_sender.h"
#include "mtproto/sender.h"
namespace Ui {
class UsernameInput;
@@ -19,7 +19,7 @@ namespace Main {
class Session;
} // namespace Main
class UsernameBox : public Ui::BoxContent, public RPCSender {
class UsernameBox : public Ui::BoxContent {
public:
UsernameBox(QWidget*, not_null<Main::Session*> session);
@@ -31,11 +31,11 @@ protected:
void resizeEvent(QResizeEvent *e) override;
private:
void onUpdateDone(const MTPUser &result);
bool onUpdateFail(const RPCError &error);
void updateDone(const MTPUser &result);
void updateFail(const RPCError &error);
void onCheckDone(const MTPBool &result);
bool onCheckFail(const RPCError &error);
void checkDone(const MTPBool &result);
void checkFail(const RPCError &error);
void save();
@@ -48,6 +48,7 @@ private:
void updateLinkText();
const not_null<Main::Session*> _session;
MTP::Sender _api;
object_ptr<Ui::UsernameInput> _username;
object_ptr<Ui::LinkButton> _link;

View File

@@ -10,8 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_calls.h"
#include "styles/style_boxes.h"
#include "lang/lang_keys.h"
#include "observer_peer.h"
#include "ui/effects/ripple_animation.h"
#include "core/application.h"
#include "calls/calls_instance.h"
#include "history/history.h"
#include "history/history_item.h"
@@ -19,10 +19,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_session_controller.h"
#include "main/main_session.h"
#include "data/data_session.h"
#include "data/data_changes.h"
#include "data/data_media_types.h"
#include "data/data_user.h"
#include "apiwrap.h"
#include "facades.h"
#include "app.h"
namespace Calls {
@@ -218,7 +217,7 @@ void BoxController::Row::stopLastActionRipple() {
BoxController::BoxController(not_null<Window::SessionController*> window)
: _window(window)
, _api(_window->session().api().instance()) {
, _api(&_window->session().mtp()) {
}
Main::Session &BoxController::session() const {
@@ -240,11 +239,11 @@ void BoxController::prepare() {
}
}, lifetime());
subscribe(session().calls().newServiceMessage(), [=](FullMsgId msgId) {
if (const auto item = session().data().message(msgId)) {
insertRow(item, InsertWay::Prepend);
}
});
session().changes().messageUpdates(
Data::MessageUpdate::Flag::CallAdded
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
insertRow(update.item, InsertWay::Prepend);
}, lifetime());
delegate()->peerListSetTitle(tr::lng_call_box_title());
setDescriptionText(tr::lng_contacts_loading(tr::now));
@@ -303,10 +302,14 @@ void BoxController::refreshAbout() {
}
void BoxController::rowClicked(not_null<PeerListRow*> row) {
auto itemsRow = static_cast<Row*>(row.get());
auto itemId = itemsRow->maxItemId();
InvokeQueued(App::main(), [peerId = row->peer()->id, itemId] {
Ui::showPeerHistory(peerId, itemId);
const auto itemsRow = static_cast<Row*>(row.get());
const auto itemId = itemsRow->maxItemId();
const auto window = _window;
crl::on_main(window, [=, peer = row->peer()] {
window->showPeerHistory(
peer,
Window::SectionShow::Way::ClearStack,
itemId);
});
}
@@ -314,7 +317,7 @@ void BoxController::rowActionClicked(not_null<PeerListRow*> row) {
auto user = row->peer()->asUser();
Assert(user != nullptr);
user->session().calls().startOutgoingCall(user);
Core::App().calls().startOutgoingCall(user);
}
void BoxController::receivedCalls(const QVector<MTPMessage> &result) {

View File

@@ -15,6 +15,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "calls/calls_instance.h"
#include "base/openssl_help.h"
#include "mtproto/mtproto_dh_utils.h"
#include "mtproto/mtproto_config.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "media/audio/media_audio_track.h"
#include "base/platform/base_platform_info.h"
#include "calls/calls_panel.h"
@@ -96,7 +99,7 @@ Call::Call(
Type type)
: _delegate(delegate)
, _user(user)
, _api(_user->session().api().instance())
, _api(&_user->session().mtp())
, _type(type) {
_discardByTimeoutTimer.setCallback([this] { hangup(); });
@@ -128,7 +131,8 @@ bool Call::isIncomingWaiting() const {
if (type() != Call::Type::Incoming) {
return false;
}
return (_state == State::Starting) || (_state == State::WaitingIncoming);
return (state() == State::Starting)
|| (state() == State::WaitingIncoming);
}
void Call::start(bytes::const_span random) {
@@ -139,13 +143,14 @@ void Call::start(bytes::const_span random) {
Assert(!_dhConfig.p.empty());
generateModExpFirst(random);
if (_state == State::Starting || _state == State::Requesting) {
const auto state = _state.current();
if (state == State::Starting || state == State::Requesting) {
if (_type == Type::Outgoing) {
startOutgoing();
} else {
startIncoming();
}
} else if (_state == State::ExchangingKeys
} else if (state == State::ExchangingKeys
&& _answerAfterDhConfigReceived) {
answer();
}
@@ -153,7 +158,7 @@ void Call::start(bytes::const_span random) {
void Call::startOutgoing() {
Expects(_type == Type::Outgoing);
Expects(_state == State::Requesting);
Expects(_state.current() == State::Requesting);
Expects(_gaHash.size() == kSha256Size);
_api.request(MTPphone_RequestCall(
@@ -193,7 +198,8 @@ void Call::startOutgoing() {
return;
}
_discardByTimeoutTimer.callOnce(Global::CallReceiveTimeoutMs());
const auto &config = _user->session().serverConfig();
_discardByTimeoutTimer.callOnce(config.callReceiveTimeoutMs);
handleUpdate(phoneCall);
}).fail([this](const RPCError &error) {
handleRequestError(error);
@@ -202,12 +208,12 @@ void Call::startOutgoing() {
void Call::startIncoming() {
Expects(_type == Type::Incoming);
Expects(_state == State::Starting);
Expects(_state.current() == State::Starting);
_api.request(MTPphone_ReceivedCall(
MTP_inputPhoneCall(MTP_long(_id), MTP_long(_accessHash))
)).done([=](const MTPBool &result) {
if (_state == State::Starting) {
if (_state.current() == State::Starting) {
setState(State::WaitingIncoming);
}
}).fail([=](const RPCError &error) {
@@ -224,8 +230,9 @@ void Call::answer() {
void Call::actuallyAnswer() {
Expects(_type == Type::Incoming);
if (_state != State::Starting && _state != State::WaitingIncoming) {
if (_state != State::ExchangingKeys
const auto state = _state.current();
if (state != State::Starting && state != State::WaitingIncoming) {
if (state != State::ExchangingKeys
|| !_answerAfterDhConfigReceived) {
return;
}
@@ -276,10 +283,11 @@ crl::time Call::getDurationMs() const {
}
void Call::hangup() {
if (_state == State::Busy) {
const auto state = _state.current();
if (state == State::Busy) {
_delegate->callFinished(this);
} else {
auto missed = (_state == State::Ringing || (_state == State::Waiting && _type == Type::Outgoing));
auto missed = (state == State::Ringing || (state == State::Waiting && _type == Type::Outgoing));
auto declined = isIncomingWaiting();
auto reason = missed ? MTP_phoneCallDiscardReasonMissed() :
declined ? MTP_phoneCallDiscardReasonBusy() : MTP_phoneCallDiscardReasonHangup();
@@ -288,7 +296,7 @@ void Call::hangup() {
}
void Call::redial() {
if (_state != State::Busy) {
if (_state.current() != State::Busy) {
return;
}
Assert(_controller == nullptr);
@@ -305,7 +313,7 @@ QString Call::getDebugLog() const {
void Call::startWaitingTrack() {
_waitingTrack = Media::Audio::Current().createTrack();
auto trackFileName = _user->session().settings().getSoundPath(
auto trackFileName = Core::App().settings().getSoundPath(
(_type == Type::Outgoing)
? qsl("call_outgoing")
: qsl("call_incoming"));
@@ -380,9 +388,10 @@ bool Call::handleUpdate(const MTPPhoneCall &call) {
return false;
}
if (_type == Type::Outgoing
&& _state == State::Waiting
&& _state.current() == State::Waiting
&& data.vreceive_date().value_or_empty() != 0) {
_discardByTimeoutTimer.callOnce(Global::CallRingTimeoutMs());
const auto &config = _user->session().serverConfig();
_discardByTimeoutTimer.callOnce(config.callRingTimeoutMs);
setState(State::Ringing);
startWaitingTrack();
}
@@ -394,7 +403,7 @@ bool Call::handleUpdate(const MTPPhoneCall &call) {
return false;
}
if (_type == Type::Incoming
&& _state == State::ExchangingKeys
&& _state.current() == State::ExchangingKeys
&& !_controller) {
startConfirmedCall(data);
}
@@ -410,12 +419,12 @@ bool Call::handleUpdate(const MTPPhoneCall &call) {
? _controller->getDebugInfo()
: std::string();
if (!debugLog.empty()) {
MTP::send(
MTPphone_SaveCallDebug(
MTP_inputPhoneCall(
MTP_long(_id),
MTP_long(_accessHash)),
MTP_dataJSON(MTP_string(debugLog))));
user()->session().api().request(MTPphone_SaveCallDebug(
MTP_inputPhoneCall(
MTP_long(_id),
MTP_long(_accessHash)),
MTP_dataJSON(MTP_string(debugLog))
)).send();
}
}
if (data.is_need_rating() && _id && _accessHash) {
@@ -427,7 +436,8 @@ bool Call::handleUpdate(const MTPPhoneCall &call) {
}
if (reason && reason->type() == mtpc_phoneCallDiscardReasonBusy) {
setState(State::Busy);
} else if (_type == Type::Outgoing || _state == State::HangingUp) {
} else if (_type == Type::Outgoing
|| _state.current() == State::HangingUp) {
setState(State::Ended);
} else {
setState(State::EndedByOtherDevice);
@@ -455,7 +465,7 @@ bool Call::handleUpdate(const MTPPhoneCall &call) {
void Call::confirmAcceptedCall(const MTPDphoneCallAccepted &call) {
Expects(_type == Type::Outgoing);
if (_state == State::ExchangingKeys
if (_state.current() == State::ExchangingKeys
|| _controller) {
LOG(("Call Warning: Unexpected confirmAcceptedCall."));
return;
@@ -534,6 +544,7 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
}
const auto &protocol = call.vprotocol().c_phoneCallProtocol();
const auto &serverConfig = _user->session().serverConfig();
TgVoipConfig config;
config.dataSaving = TgVoipDataSaving::Never;
@@ -541,8 +552,8 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
config.enableNS = true;
config.enableAGC = true;
config.enableVolumeControl = true;
config.initializationTimeout = Global::CallConnectTimeoutMs() / 1000.;
config.receiveTimeout = Global::CallPacketTimeoutMs() / 1000.;
config.initializationTimeout = serverConfig.callConnectTimeoutMs / 1000.;
config.receiveTimeout = serverConfig.callPacketTimeoutMs / 1000.;
config.enableP2P = call.is_p2p_allowed();
config.maxApiLayer = protocol.vmax_layer().v;
if (Logs::DebugEnabled()) {
@@ -605,13 +616,14 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
if (_mute) {
raw->setMuteMicrophone(_mute);
}
const auto &settings = Core::App().settings();
raw->setAudioOutputDevice(
Global::CallOutputDeviceID().toStdString());
settings.callOutputDeviceID().toStdString());
raw->setAudioInputDevice(
Global::CallInputDeviceID().toStdString());
raw->setOutputVolume(Global::CallOutputVolume() / 100.0f);
raw->setInputVolume(Global::CallInputVolume() / 100.0f);
raw->setAudioOutputDuckingEnabled(Global::CallAudioDuckingEnabled());
settings.callInputDeviceID().toStdString());
raw->setOutputVolume(settings.callOutputVolume() / 100.0f);
raw->setInputVolume(settings.callInputVolume() / 100.0f);
raw->setAudioOutputDuckingEnabled(settings.callAudioDuckingEnabled());
}
void Call::handleControllerStateChange(
@@ -703,34 +715,33 @@ bool Call::checkCallFields(const MTPDphoneCallAccepted &call) {
}
void Call::setState(State state) {
if (_state == State::Failed) {
if (_state.current() == State::Failed) {
return;
}
if (_state == State::FailedHangingUp && state != State::Failed) {
if (_state.current() == State::FailedHangingUp && state != State::Failed) {
return;
}
if (_state != state) {
if (_state.current() != state) {
_state = state;
_stateChanged.notify(state, true);
if (true
&& _state != State::Starting
&& _state != State::Requesting
&& _state != State::Waiting
&& _state != State::WaitingIncoming
&& _state != State::Ringing) {
&& state != State::Starting
&& state != State::Requesting
&& state != State::Waiting
&& state != State::WaitingIncoming
&& state != State::Ringing) {
_waitingTrack.reset();
}
if (false
|| _state == State::Ended
|| _state == State::EndedByOtherDevice
|| _state == State::Failed
|| _state == State::Busy) {
|| state == State::Ended
|| state == State::EndedByOtherDevice
|| state == State::Failed
|| state == State::Busy) {
// Destroy controller before destroying Call Panel,
// so that the panel hide animation is smooth.
destroyController();
}
switch (_state) {
switch (state) {
case State::Established:
_startTime = crl::now();
break;
@@ -787,16 +798,17 @@ void Call::finish(FinishType type, const MTPPhoneCallDiscardReason &reason) {
auto finalState = (type == FinishType::Ended) ? State::Ended : State::Failed;
auto hangupState = (type == FinishType::Ended) ? State::HangingUp : State::FailedHangingUp;
if (_state == State::Requesting) {
const auto state = _state.current();
if (state == State::Requesting) {
_finishByTimeoutTimer.call(kHangupTimeoutMs, [this, finalState] { setState(finalState); });
_finishAfterRequestingCall = type;
return;
}
if (_state == State::HangingUp
|| _state == State::FailedHangingUp
|| _state == State::EndedByOtherDevice
|| _state == State::Ended
|| _state == State::Failed) {
if (state == State::HangingUp
|| state == State::FailedHangingUp
|| state == State::EndedByOtherDevice
|| state == State::Ended
|| state == State::Failed) {
return;
}
if (!_id) {

View File

@@ -60,13 +60,13 @@ public:
};
Call(not_null<Delegate*> delegate, not_null<UserData*> user, Type type);
Type type() const {
[[nodiscard]] Type type() const {
return _type;
}
not_null<UserData*> user() const {
[[nodiscard]] not_null<UserData*> user() const {
return _user;
}
bool isIncomingWaiting() const;
[[nodiscard]] bool isIncomingWaiting() const;
void start(bytes::const_span random);
bool handleUpdate(const MTPPhoneCall &call);
@@ -89,10 +89,10 @@ public:
Busy,
};
State state() const {
return _state;
return _state.current();
}
base::Observable<State> &stateChanged() {
return _stateChanged;
rpl::producer<State> stateValue() const {
return _state.value();
}
static constexpr auto kSignalBarStarting = -1;
@@ -126,6 +126,10 @@ public:
void setAudioVolume(bool input, float level);
void setAudioDuckingEnabled(bool enabled);
[[nodiscard]] rpl::lifetime &lifetime() {
return _lifetime;
}
~Call();
private:
@@ -166,10 +170,9 @@ private:
not_null<UserData*> _user;
MTP::Sender _api;
Type _type = Type::Outgoing;
State _state = State::Starting;
rpl::variable<State> _state = State::Starting;
FinishType _finishAfterRequestingCall = FinishType::None;
bool _answerAfterDhConfigReceived = false;
base::Observable<State> _stateChanged;
int _signalBarCount = kSignalBarStarting;
base::Observable<int> _signalBarCountChanged;
crl::time _startTime = 0;
@@ -195,6 +198,8 @@ private:
std::unique_ptr<Media::Audio::Track> _waitingTrack;
rpl::lifetime _lifetime;
};
void UpdateConfig(const std::string &data);

View File

@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/mtproto_dh_utils.h"
#include "core/application.h"
#include "main/main_session.h"
#include "main/main_account.h"
#include "apiwrap.h"
#include "lang/lang_keys.h"
#include "boxes/confirm_box.h"
@@ -21,8 +22,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/platform_specific.h"
#include "base/unixtime.h"
#include "mainwidget.h"
#include "mtproto/mtproto_config.h"
#include "boxes/rate_call_box.h"
#include "facades.h"
#include "app.h"
namespace Calls {
@@ -32,9 +33,14 @@ constexpr auto kServerConfigUpdateTimeoutMs = 24 * 3600 * crl::time(1000);
} // namespace
Instance::Instance(not_null<Main::Session*> session)
: _session(session)
, _api(_session->api().instance()) {
Instance::Instance() = default;
Instance::~Instance() {
for (const auto panel : _pendingPanels) {
if (panel) {
delete panel;
}
}
}
void Instance::startOutgoingCall(not_null<UserData*> user) {
@@ -44,8 +50,9 @@ void Instance::startOutgoingCall(not_null<UserData*> user) {
}
if (user->callsStatus() == UserData::CallsStatus::Private) {
// Request full user once more to refresh the setting in case it was changed.
_session->api().requestFullPeer(user);
Ui::show(Box<InformBox>(tr::lng_call_error_not_available(tr::now, lt_user, user->name)));
user->session().api().requestFullPeer(user);
Ui::show(Box<InformBox>(
tr::lng_call_error_not_available(tr::now, lt_user, user->name)));
return;
}
requestMicrophonePermissionOrFail(crl::guard(this, [=] {
@@ -73,7 +80,7 @@ void Instance::playSound(Sound sound) {
if (!_callBusyTrack) {
_callBusyTrack = Media::Audio::Current().createTrack();
_callBusyTrack->fillFromFile(
_session->settings().getSoundPath(qsl("call_busy")));
Core::App().settings().getSoundPath(qsl("call_busy")));
}
_callBusyTrack->playOnce();
} break;
@@ -82,7 +89,7 @@ void Instance::playSound(Sound sound) {
if (!_callEndedTrack) {
_callEndedTrack = Media::Audio::Current().createTrack();
_callEndedTrack->fillFromFile(
_session->settings().getSoundPath(qsl("call_end")));
Core::App().settings().getSoundPath(qsl("call_end")));
}
_callEndedTrack->playOnce();
} break;
@@ -91,7 +98,7 @@ void Instance::playSound(Sound sound) {
if (!_callConnectingTrack) {
_callConnectingTrack = Media::Audio::Current().createTrack();
_callConnectingTrack->fillFromFile(
_session->settings().getSoundPath(qsl("call_connect")));
Core::App().settings().getSoundPath(qsl("call_connect")));
}
_callConnectingTrack->playOnce();
} break;
@@ -101,8 +108,9 @@ void Instance::playSound(Sound sound) {
void Instance::destroyCall(not_null<Call*> call) {
if (_currentCall.get() == call) {
destroyCurrentPanel();
_currentCall.reset();
_currentCallChanged.notify(nullptr, true);
auto taken = base::take(_currentCall);
_currentCallChanges.fire(nullptr);
taken.reset();
if (App::quitting()) {
LOG(("Calls::Instance doesn't prevent quit any more."));
@@ -123,17 +131,24 @@ void Instance::destroyCurrentPanel() {
}
void Instance::createCall(not_null<UserData*> user, Call::Type type) {
auto call = std::make_unique<Call>(getCallDelegate(), user, type);;
auto call = std::make_unique<Call>(getCallDelegate(), user, type);
const auto raw = call.get();
user->session().account().sessionChanges(
) | rpl::start_with_next([=] {
destroyCall(raw);
}, raw->lifetime());
if (_currentCall) {
_currentCallPanel->replaceCall(call.get());
_currentCallPanel->replaceCall(raw);
std::swap(_currentCall, call);
call->hangup();
} else {
_currentCallPanel = std::make_unique<Panel>(call.get());
_currentCallPanel = std::make_unique<Panel>(raw);
_currentCall = std::move(call);
}
_currentCallChanged.notify(_currentCall.get(), true);
refreshServerConfig();
_currentCallChanges.fire_copy(raw);
refreshServerConfig(&user->session());
refreshDhConfig();
}
@@ -141,7 +156,7 @@ void Instance::refreshDhConfig() {
Expects(_currentCall != nullptr);
const auto weak = base::make_weak(_currentCall);
_api.request(MTPmessages_GetDhConfig(
_currentCall->user()->session().api().request(MTPmessages_GetDhConfig(
MTP_int(_dhConfig.version),
MTP_int(MTP::ModExpFirst::kRandomPowerSize)
)).done([=](const MTPmessages_DhConfig &result) {
@@ -198,27 +213,32 @@ bytes::const_span Instance::updateDhConfig(
});
}
void Instance::refreshServerConfig() {
if (_serverConfigRequestId) {
void Instance::refreshServerConfig(not_null<Main::Session*> session) {
if (_serverConfigRequestSession) {
return;
}
if (_lastServerConfigUpdateTime && (crl::now() - _lastServerConfigUpdateTime) < kServerConfigUpdateTimeoutMs) {
if (_lastServerConfigUpdateTime
&& ((crl::now() - _lastServerConfigUpdateTime)
< kServerConfigUpdateTimeoutMs)) {
return;
}
_serverConfigRequestId = _api.request(MTPphone_GetCallConfig(
_serverConfigRequestSession = session;
session->api().request(MTPphone_GetCallConfig(
)).done([=](const MTPDataJSON &result) {
_serverConfigRequestId = 0;
_serverConfigRequestSession = nullptr;
_lastServerConfigUpdateTime = crl::now();
const auto &json = result.c_dataJSON().vdata().v;
UpdateConfig(std::string(json.data(), json.size()));
}).fail([=](const RPCError &error) {
_serverConfigRequestId = 0;
}).send();
_serverConfigRequestSession = nullptr;
}).send();
}
void Instance::handleUpdate(const MTPDupdatePhoneCall& update) {
handleCallUpdate(update.vphone_call());
void Instance::handleUpdate(
not_null<Main::Session*> session,
const MTPDupdatePhoneCall& update) {
handleCallUpdate(session, update.vphone_call());
}
void Instance::showInfoPanel(not_null<Call*> call) {
@@ -239,24 +259,27 @@ bool Instance::isQuitPrevent() {
return true;
}
void Instance::handleCallUpdate(const MTPPhoneCall &call) {
void Instance::handleCallUpdate(
not_null<Main::Session*> session,
const MTPPhoneCall &call) {
if (call.type() == mtpc_phoneCallRequested) {
auto &phoneCall = call.c_phoneCallRequested();
auto user = _session->data().userLoaded(phoneCall.vadmin_id().v);
auto user = session->data().userLoaded(phoneCall.vadmin_id().v);
if (!user) {
LOG(("API Error: User not loaded for phoneCallRequested."));
} else if (user->isSelf()) {
LOG(("API Error: Self found in phoneCallRequested."));
}
const auto &config = session->serverConfig();
if (alreadyInCall() || !user || user->isSelf()) {
_api.request(MTPphone_DiscardCall(
session->api().request(MTPphone_DiscardCall(
MTP_flags(0),
MTP_inputPhoneCall(phoneCall.vid(), phoneCall.vaccess_hash()),
MTP_int(0),
MTP_phoneCallDiscardReasonBusy(),
MTP_long(0)
)).send();
} else if (phoneCall.vdate().v + (Global::CallRingTimeoutMs() / 1000)
} else if (phoneCall.vdate().v + (config.callRingTimeoutMs / 1000)
< base::unixtime::now()) {
LOG(("Ignoring too old call."));
} else {
@@ -272,10 +295,14 @@ bool Instance::alreadyInCall() {
return (_currentCall && _currentCall->state() != Call::State::Busy);
}
Call *Instance::currentCall() {
Call *Instance::currentCall() const {
return _currentCall.get();
}
rpl::producer<Call*> Instance::currentCallValue() const {
return _currentCallChanges.events_starting_with(currentCall());
}
void Instance::requestMicrophonePermissionOrFail(Fn<void()> onSuccess) {
Platform::PermissionStatus status=Platform::GetPermissionStatus(Platform::PermissionType::Microphone);
if (status==Platform::PermissionStatus::Granted) {
@@ -301,12 +328,4 @@ void Instance::requestMicrophonePermissionOrFail(Fn<void()> onSuccess) {
}
}
Instance::~Instance() {
for (auto panel : _pendingPanels) {
if (panel) {
delete panel;
}
}
}
} // namespace Calls

View File

@@ -29,24 +29,18 @@ class Instance
, private base::Subscriber
, public base::has_weak_ptr {
public:
explicit Instance(not_null<Main::Session*> session);
Instance();
~Instance();
void startOutgoingCall(not_null<UserData*> user);
void handleUpdate(const MTPDupdatePhoneCall &update);
void handleUpdate(
not_null<Main::Session*> session,
const MTPDupdatePhoneCall &update);
void showInfoPanel(not_null<Call*> call);
Call* currentCall();
[[nodiscard]] Call *currentCall() const;
[[nodiscard]] rpl::producer<Call*> currentCallValue() const;
base::Observable<Call*> &currentCallChanged() {
return _currentCallChanged;
}
base::Observable<FullMsgId> &newServiceMessage() {
return _newServiceMessage;
}
bool isQuitPrevent();
~Instance();
[[nodiscard]] bool isQuitPrevent();
private:
not_null<Call::Delegate*> getCallDelegate() {
@@ -66,21 +60,21 @@ private:
void requestMicrophonePermissionOrFail(Fn<void()> onSuccess) override;
void refreshDhConfig();
void refreshServerConfig();
void refreshServerConfig(not_null<Main::Session*> session);
bytes::const_span updateDhConfig(const MTPmessages_DhConfig &data);
bool alreadyInCall();
void handleCallUpdate(const MTPPhoneCall &call);
const not_null<Main::Session*> _session;
MTP::Sender _api;
void handleCallUpdate(
not_null<Main::Session*> session,
const MTPPhoneCall &call);
DhConfig _dhConfig;
crl::time _lastServerConfigUpdateTime = 0;
mtpRequestId _serverConfigRequestId = 0;
base::weak_ptr<Main::Session> _serverConfigRequestSession;
std::unique_ptr<Call> _currentCall;
rpl::event_stream<Call*> _currentCallChanges;
std::unique_ptr<Panel> _currentCallPanel;
base::Observable<Call*> _currentCallChanged;
base::Observable<FullMsgId> _newServiceMessage;

View File

@@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_file_origin.h"
#include "data/data_photo_media.h"
#include "data/data_cloud_file.h"
#include "data/data_changes.h"
#include "calls/calls_emoji_fingerprint.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
@@ -28,7 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "apiwrap.h"
#include "observer_peer.h"
#include "platform/platform_specific.h"
#include "window/main_window.h"
#include "layout.h"
@@ -315,7 +315,7 @@ Panel::Panel(not_null<Call*> call)
_cancel->setDuration(st::callPanelDuration);
setMouseTracking(true);
setWindowIcon(Window::CreateIcon(&_user->account()));
setWindowIcon(Window::CreateIcon(&_user->session()));
initControls();
initLayout();
showAndActivate();
@@ -361,13 +361,7 @@ void Panel::initControls() {
subscribe(_call->muteChanged(), [this](bool mute) {
_mute->setIconOverride(mute ? &st::callUnmuteIcon : nullptr);
});
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::NameChanged, [this](const Notify::PeerUpdate &update) {
if (!_call || update.peer != _call->user()) {
return;
}
_name->setText(_call->user()->name);
updateControlsGeometry();
}));
_updateDurationTimer.setCallback([this] {
if (_call) {
updateStatusText(_call->state());
@@ -411,11 +405,11 @@ void Panel::initControls() {
void Panel::reinitControls() {
Expects(_call != nullptr);
unsubscribe(base::take(_stateChangedSubscription));
_stateChangedSubscription = subscribe(
_call->stateChanged(),
[=](State state) { stateChanged(state); });
stateChanged(_call->state());
_stateLifetime.destroy();
_call->stateValue(
) | rpl::start_with_next([=](State state) {
stateChanged(state);
}, _stateLifetime);
_signalBars.create(
this,
@@ -423,7 +417,7 @@ void Panel::reinitControls() {
st::callPanelSignalBars,
[=] { rtlupdate(signalBarsRect()); });
_name->setText(_call->user()->name);
_name->setText(_user->name);
updateStatusText(_call->state());
}
@@ -435,16 +429,27 @@ void Panel::initLayout() {
initGeometry();
Notify::PeerUpdateValue(
_user,
Notify::PeerUpdate::Flag::PhotoChanged
) | rpl::start_with_next(
[this] { processUserPhoto(); },
lifetime());
using UpdateFlag = Data::PeerUpdate::Flag;
_user->session().changes().peerUpdates(
UpdateFlag::Name | UpdateFlag::Photo
) | rpl::filter([=](const Data::PeerUpdate &update) {
// _user may change for the same Panel.
return (_call != nullptr) && (update.peer == _user);
}) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
if (update.flags & UpdateFlag::Name) {
_name->setText(_call->user()->name);
updateControlsGeometry();
}
if (update.flags & UpdateFlag::Photo) {
processUserPhoto();
}
}, lifetime());
processUserPhoto();
subscribe(_user->session().downloaderTaskFinished(), [=] {
_user->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
refreshUserPhoto();
});
}, lifetime());
createDefaultCacheImage();
Ui::Platform::InitOnTopPanel(this);

View File

@@ -130,7 +130,7 @@ private:
QPoint _dragStartMousePosition;
QPoint _dragStartMyPosition;
int _stateChangedSubscription = 0;
rpl::lifetime _stateLifetime;
class Button;
object_ptr<Button> _answerHangupRedial;

View File

@@ -11,12 +11,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/labels.h"
#include "ui/wrap/padding_wrap.h"
#include "lang/lang_keys.h"
#include "core/application.h"
#include "calls/calls_call.h"
#include "calls/calls_instance.h"
#include "calls/calls_panel.h"
#include "data/data_user.h"
#include "data/data_changes.h"
#include "main/main_session.h"
#include "observer_peer.h"
#include "boxes/abstract_box.h"
#include "base/timer.h"
#include "layout.h"
@@ -101,13 +102,16 @@ void TopBar::initControls() {
setMuted(mute);
update();
});
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::NameChanged, [this](const Notify::PeerUpdate &update) {
if (auto call = _call.get()) {
if (update.peer == call->user()) {
updateInfoLabels();
}
}
}));
_call->user()->session().changes().peerUpdates(
Data::PeerUpdate::Flag::Name
) | rpl::filter([=](const Data::PeerUpdate &update) {
// _user may change for the same Panel.
return (_call != nullptr) && (update.peer == _call->user());
}) | rpl::start_with_next([=] {
updateInfoLabels();
}, lifetime());
setInfoLabels();
_info->setClickedCallback([=] {
if (const auto call = _call.get()) {
@@ -115,7 +119,7 @@ void TopBar::initControls() {
&& (_info->clickModifiers() & Qt::ControlModifier)) {
Ui::show(Box<DebugInfoBox>(_call));
} else {
call->user()->session().calls().showInfoPanel(call);
Core::App().calls().showInfoPanel(call);
}
}
});

View File

@@ -98,7 +98,9 @@ int Style::minButtonWidth(HistoryMessageMarkupButton::Type type) const {
} // namespace
BotKeyboard::BotKeyboard(QWidget *parent) : TWidget(parent)
BotKeyboard::BotKeyboard(not_null<Main::Session*> session, QWidget *parent)
: TWidget(parent)
, _session(session)
, _st(&st::botKbButton) {
setGeometry(0, 0, _st->margin, st::botKbScroll.deltat);
_height = st::botKbScroll.deltat;
@@ -149,7 +151,7 @@ void BotKeyboard::leaveEventHook(QEvent *e) {
}
bool BotKeyboard::moderateKeyActivate(int key) {
if (const auto item = Auth().data().message(_wasForMsgId)) {
if (const auto item = _session->data().message(_wasForMsgId)) {
if (const auto markup = item->Get<HistoryMessageReplyMarkup>()) {
if (key >= Qt::Key_1 && key <= Qt::Key_9) {
const auto index = int(key - Qt::Key_1);
@@ -159,12 +161,14 @@ bool BotKeyboard::moderateKeyActivate(int key) {
App::activateBotCommand(item, 0, index);
return true;
}
} else if (key == Qt::Key_Q) {
if (const auto user = item->history()->peer->asUser()) {
if (user->isBot() && item->from() == user) {
} else if (const auto user = item->history()->peer->asUser()) {
if (user->isBot() && item->from() == user) {
if (key == Qt::Key_Q) {
App::sendBotCommand(user, user, qsl("/translate"));
return true;
} else if (key == Qt::Key_W) {
App::sendBotCommand(user, user, qsl("/eng"));
}
return true;
}
}
}

View File

@@ -9,18 +9,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/tooltip.h"
class ReplyKeyboard;
namespace style {
struct BotKeyboardButton;
} // namespace style
class ReplyKeyboard;
namespace Main {
class Session;
} // namespace Main
class BotKeyboard
: public TWidget
, public Ui::AbstractTooltipShower
, public ClickHandlerHost {
public:
BotKeyboard(QWidget *parent);
BotKeyboard(not_null<Main::Session*> session, QWidget *parent);
bool moderateKeyActivate(int index);
@@ -70,6 +74,7 @@ private:
void updateStyle(int newWidth);
void clearSelection();
const not_null<Main::Session*> _session;
FullMsgId _wasForMsgId;
int _height = 0;
int _maxOuterHeight = 0;

View File

@@ -13,7 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/application.h"
#include "base/platform/base_platform_info.h"
#include "ui/emoji_config.h"
#include "main/main_account.h"
#include "main/main_domain.h"
#include "main/main_session.h"
#include "apiwrap.h"
@@ -205,7 +205,7 @@ void AppendLegacySuggestions(
&& (ch != '-')
&& (ch != '+');
};
if (ranges::find_if(query, badSuggestionChar) != query.end()) {
if (ranges::any_of(query, badSuggestionChar)) {
return;
}
@@ -516,7 +516,7 @@ void EmojiKeywords::langPackRefreshed() {
}
void EmojiKeywords::handleSessionChanges() {
Core::App().activeAccount().sessionValue(
Core::App().domain().activeSessionValue( // #TODO multi someSessionValue
) | rpl::map([](Main::Session *session) {
return session ? &session->api() : nullptr;
}) | rpl::start_with_next([=](ApiWrap *api) {
@@ -527,7 +527,7 @@ void EmojiKeywords::handleSessionChanges() {
void EmojiKeywords::apiChanged(ApiWrap *api) {
_api = api;
if (_api) {
crl::on_main(&Auth(), crl::guard(&_guard, [=] {
crl::on_main(&_api->session(), crl::guard(&_guard, [=] {
base::ObservableViewer(
Lang::CurrentCloudManager().firstLanguageSuggestion()
) | rpl::filter([=] {
@@ -557,7 +557,7 @@ void EmojiKeywords::refresh() {
}
std::vector<QString> EmojiKeywords::languages() {
if (!Main::Session::Exists()) {
if (!_api) {
return {};
}
refreshInputLanguages();

View File

@@ -15,6 +15,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "emoji_suggestions_data.h"
#include "emoji_suggestions_helper.h"
#include "main/main_session.h"
#include "core/core_settings.h"
#include "core/application.h"
#include "window/window_session_controller.h"
#include "facades.h"
#include "app.h"
@@ -698,7 +701,7 @@ void EmojiListWidget::colorChosen(EmojiPtr emoji) {
cRefEmojiVariants().insert(
emoji->nonColoredId(),
emoji->variantIndex(emoji));
Auth().saveSettingsDelayed();
controller()->session().saveSettingsDelayed();
}
if (_pickerSel >= 0) {
auto section = (_pickerSel / MatrixRowShift);
@@ -835,8 +838,7 @@ void EmojiListWidget::setSelected(int newSelected) {
_selected = newSelected;
updateSelected();
if (_selected >= 0
&& controller()->session().settings().suggestEmoji()) {
if (_selected >= 0 && Core::App().settings().suggestEmoji()) {
Ui::Tooltip::Show(1000, this);
}

View File

@@ -51,7 +51,7 @@ using SetState = BlobState;
class Loader final : public BlobLoader {
public:
Loader(
QObject *parent,
not_null<Main::Session*> session,
int id,
MTP::DedicatedLoader::Location location,
const QString &folder,
@@ -67,16 +67,18 @@ private:
class Inner : public Ui::RpWidget {
public:
Inner(QWidget *parent);
Inner(QWidget *parent, not_null<Main::Session*> session);
private:
void setupContent();
const not_null<Main::Session*> _session;
};
class Row : public Ui::RippleButton {
public:
Row(QWidget *widget, const Set &set);
Row(QWidget *widget, not_null<Main::Session*> session, const Set &set);
protected:
void paintEvent(QPaintEvent *e) override;
@@ -98,6 +100,7 @@ private:
void radialAnimationCallback(crl::time now);
void updateLoadingToFinished();
const not_null<Main::Session*> _session;
int _id = 0;
bool _switching = false;
rpl::variable<SetState> _state;
@@ -160,12 +163,12 @@ bool UnpackSet(const QString &path, const QString &folder) {
Loader::Loader(
QObject *parent,
not_null<Main::Session*> session,
int id,
MTP::DedicatedLoader::Location location,
const QString &folder,
int size)
: BlobLoader(parent, id, location, folder, size) {
: BlobLoader(nullptr, session, id, location, folder, size) {
}
void Loader::unpack(const QString &path) {
@@ -200,7 +203,9 @@ void Loader::fail() {
BlobLoader::fail();
}
Inner::Inner(QWidget *parent) : RpWidget(parent) {
Inner::Inner(QWidget *parent, not_null<Main::Session*> session)
: RpWidget(parent)
, _session(session) {
setupContent();
}
@@ -208,15 +213,16 @@ void Inner::setupContent() {
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
for (const auto &set : kSets) {
content->add(object_ptr<Row>(content, set));
content->add(object_ptr<Row>(content, _session, set));
}
content->resizeToWidth(st::boxWidth);
Ui::ResizeFitChild(this, content);
}
Row::Row(QWidget *widget, const Set &set)
Row::Row(QWidget *widget, not_null<Main::Session*> session, const Set &set)
: RippleButton(widget, st::contactsRipple)
, _session(session)
, _id(set.id)
, _state(Available{ set.size }) {
setupContent(set);
@@ -411,7 +417,7 @@ void Row::setupHandler() {
}
void Row::load() {
LoadAndSwitchTo(_id);
LoadAndSwitchTo(_session, _id);
}
void Row::setupLabels(const Set &set) {
@@ -530,11 +536,12 @@ void Row::setupAnimation() {
} // namespace
ManageSetsBox::ManageSetsBox(QWidget*) {
ManageSetsBox::ManageSetsBox(QWidget*, not_null<Main::Session*> session)
: _session(session) {
}
void ManageSetsBox::prepare() {
const auto inner = setInnerWidget(object_ptr<Inner>(this));
const auto inner = setInnerWidget(object_ptr<Inner>(this, _session));
setTitle(tr::lng_emoji_manage_sets());
@@ -543,15 +550,13 @@ void ManageSetsBox::prepare() {
setDimensionsToContent(st::boxWidth, inner);
}
void LoadAndSwitchTo(int id) {
Expects(App::main() != nullptr);
void LoadAndSwitchTo(not_null<Main::Session*> session, int id) {
if (!ranges::contains(kSets, id, &Set::id)) {
ClearNeedSwitchToId();
return;
}
SetGlobalLoader(base::make_unique_q<Loader>(
App::main(),
session,
id,
GetDownloadLocation(id),
internal::SetDataPath(id),

View File

@@ -9,19 +9,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h"
namespace Main {
class Session;
} // namespace Main
namespace Ui {
namespace Emoji {
class ManageSetsBox : public Ui::BoxContent {
class ManageSetsBox final : public Ui::BoxContent {
public:
explicit ManageSetsBox(QWidget*);
ManageSetsBox(QWidget*, not_null<Main::Session*> session);
protected:
private:
void prepare() override;
const not_null<Main::Session*> _session;
};
void LoadAndSwitchTo(int id);
void LoadAndSwitchTo(not_null<Main::Session*> session, int id);
} // namespace Emoji
} // namespace Ui

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