Compare commits

...

377 Commits

Author SHA1 Message Date
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
John Preston
9d1a4cdbfe Beta version 2.1.8: Fix build on 64 bit systems. 2020-06-03 16:18:03 +04:00
John Preston
383e6dec43 Beta version 2.1.8.
- Add support for full group message history export.
- Allow export of a single chat message history in JSON format.
2020-06-03 15:51:27 +04:00
John Preston
85904e3022 Update submodules. 2020-06-03 15:51:15 +04:00
John Preston
f88b97553e Fix crash in destructor of Data::CloudFile. 2020-06-03 13:48:11 +04:00
John Preston
63c6a1db82 Allow removing users invited by me. 2020-06-03 12:57:36 +04:00
John Preston
ca97e3c375 Add more warnings for suspicious urls. 2020-06-03 12:44:46 +04:00
John Preston
ef30c776bf Fix visual glitch in filter change from archived chat. 2020-06-03 12:31:15 +04:00
Ilya Fedin
d45e74619d Use Platform::IsWayland from lib_base 2020-06-03 11:43:55 +04:00
Ilya Fedin
d92b5eebcc Restore X error handler just like qgtk3 2020-06-03 11:31:34 +04:00
Ilya Fedin
5c6b4d95b0 Suppress warning about transient parent when opening gtk file dialog 2020-06-03 11:31:34 +04:00
Ilya Fedin
0fbec5eba1 Use QVersionNumber to compare version in native notifications 2020-06-03 11:31:34 +04:00
Ilya Fedin
ab13d9bdaf Skip empty parts in QT_QPA_PLATFORMTHEME 2020-06-03 11:31:34 +04:00
Ilya Fedin
0165e31ca7 Never use custom code for portal detecting in flatpak 2020-06-03 11:31:34 +04:00
Ilya Fedin
f1e75d809a Separate patches 2020-06-03 11:31:34 +04:00
Ilya Fedin
c776f81dc7 Add support for choosing directories via xdg-desktop-portal 2020-06-03 11:31:34 +04:00
John Preston
9fd62d3892 Add more deprecated system versions. 2020-06-02 22:26:59 +04:00
John Preston
793906ca9a Fix build on Windows. 2020-06-02 12:26:58 +04:00
23rd
35e575c2d7 Fixed build for macOS. 2020-06-01 19:28:19 +03:00
23rd
f5e84220eb Fixed crash in context menu for uploading scheduled messages. 2020-06-01 17:55:22 +03:00
Ilya Fedin
1d622fb3c0 Add patches with the fix for https://github.com/telegramdesktop/tdesktop/issues/6645 2020-06-01 18:43:42 +04:00
Nicholas Guriev
d8d3dda2f3 Fix little typo in theme names generator 2020-06-01 18:26:16 +04:00
Ilya Fedin
e098922a4b Add Platform::AutostartSupported 2020-06-01 18:25:21 +04:00
Ilya Fedin
413ddf285e Fix crash in gtk file dialog on Wayland 2020-06-01 18:22:53 +04:00
Ilya Fedin
7ac78be984 Load gtk2 even on Wayland 2020-06-01 18:22:53 +04:00
Ilya Fedin
4c546156da Remove duplicate log line 2020-06-01 18:22:53 +04:00
Ilya Fedin
db528b39e1 Fix macOS cache validating
macOS action has runner version in the workdir path, it should be a part of the cache key
2020-06-01 18:21:52 +04:00
Ilya Fedin
586744c112 Apply sway fixes to the PiP and export windows too 2020-06-01 18:21:30 +04:00
Ilya Fedin
7b106761be Remove cache from snap action since it works not so good 2020-06-01 18:19:34 +04:00
Ilya Fedin
8fb7f0fc73 Use TDESKTOP_USE_GTK_FILE_DIALOG in snap 2020-06-01 18:19:34 +04:00
Ilya Fedin
10b169f9f6 Make not supported errors static 2020-06-01 18:19:34 +04:00
Ilya Fedin
c83b8d4043 Fix naming of static variables 2020-06-01 18:19:34 +04:00
Ilya Fedin
1fc2b19c94 Add Cinnamon sound settings command 2020-06-01 18:19:34 +04:00
Ilya Fedin
fb97940cac Rename SandboxAutostart to PortalAutostart 2020-06-01 18:19:34 +04:00
Ilya Fedin
16c38b54e2 Rename InSandbox to InFlatpak 2020-06-01 18:19:34 +04:00
Ilya Fedin
7f29f57c3d Use custom gtk file dialog only on gtk-based DEs 2020-06-01 18:19:34 +04:00
Ilya Fedin
1fb1d57a27 Get system icon theme on gtk-based DEs 2020-06-01 18:19:34 +04:00
Ilya Fedin
47d7bd95ae Add a method to check if gtk integration is forced 2020-06-01 18:19:34 +04:00
John Preston
368eeaf754 Improve single chat export progress display. 2020-06-01 18:09:34 +04:00
John Preston
1686eb394d Add support for JSON single-chat export. 2020-06-01 18:09:34 +04:00
John Preston
02586ebe4b Allow export of just-converted supergroup. 2020-06-01 18:09:34 +04:00
John Preston
8f80c19ae1 Merge old group with supergroup history in export. 2020-06-01 18:09:34 +04:00
John Preston
1598165e2b Closed alpha version 2.1.7.4. 2020-06-01 18:09:34 +04:00
John Preston
f4cd84c313 Fix crash in stickers. 2020-06-01 18:09:34 +04:00
John Preston
9b574e497d Closed alpha version 2.1.7.3. 2020-06-01 18:09:34 +04:00
John Preston
6660338ccc Fix crash in sticker sets without a thumbnail. 2020-06-01 18:09:34 +04:00
John Preston
423ea5b499 Fix crash on invalid image data. 2020-06-01 18:09:34 +04:00
John Preston
4695ebae6e Fix crash in sticker set parsing. 2020-06-01 18:09:34 +04:00
John Preston
aaa4db7b27 Fix a crash in custom notifications. 2020-06-01 18:09:34 +04:00
John Preston
0965b06fa3 Closed alpha version 2.1.7.2. 2020-06-01 18:09:34 +04:00
Ilya Fedin
be96bf2812 Set parent for dialogs only on Wayland 2020-06-01 18:09:34 +04:00
John Preston
b7aa60bedf Fix build for Linux. 2020-06-01 18:09:34 +04:00
John Preston
d5b3fa017b Fix build for macOS. 2020-06-01 18:09:34 +04:00
John Preston
36fbdfb380 Simplify Image, remove ImageSource. 2020-06-01 18:09:33 +04:00
John Preston
d0c78eaddd Leave only one image source type. 2020-06-01 18:09:33 +04:00
John Preston
6513422e40 Remove legacy image-related code. 2020-06-01 18:09:33 +04:00
John Preston
f066e0f05a Use Data::CloudImage for userpics. 2020-06-01 18:09:33 +04:00
John Preston
249f7813c1 Don't hold session pointer in Data::CloudImage. 2020-06-01 18:09:33 +04:00
John Preston
29a498b959 Use Data::CloudImage for location thumbnails. 2020-06-01 18:09:33 +04:00
John Preston
ae9ed820ee Fix sticker set icons display. 2020-06-01 18:09:33 +04:00
John Preston
803593cd8d Change Stickers::Set from value to object type. 2020-06-01 18:09:33 +04:00
John Preston
897e432f40 Use CloudImageView in the inline bot thumbnails. 2020-06-01 18:09:33 +04:00
John Preston
50e0c3ee4d Fix preloading in media viewer. 2020-06-01 18:09:33 +04:00
John Preston
056945d9f5 Remove legacy image creation methods. 2020-06-01 18:09:32 +04:00
John Preston
a9b70a7d63 Closed alpha 2.1.7.1: Fix build for Xcode. 2020-06-01 18:09:32 +04:00
John Preston
6dabd87df3 Closed alpha version 2.1.7.1. 2020-06-01 18:09:32 +04:00
John Preston
b35b6c4449 Fix saving cache from InMemoryLocation. 2020-06-01 18:09:32 +04:00
John Preston
74ef8104a7 Fix photo edit caption box, remove 's' size. 2020-06-01 18:09:32 +04:00
John Preston
af0eebb6f1 Remove debug inline bot results marks. 2020-06-01 18:09:32 +04:00
John Preston
dbb46ce9b0 Let [Photo|Document]Media outlive message view. 2020-06-01 18:09:32 +04:00
John Preston
700d3db4cc Correctly unload heavy parts on quit. 2020-06-01 18:09:32 +04:00
John Preston
64cf0e1a44 Fix caching of sent photos and document previews. 2020-06-01 18:09:32 +04:00
John Preston
7ad660a0e7 Allow photos not have some of the thumbnails. 2020-06-01 18:09:32 +04:00
John Preston
e27d2bc2d5 Move photo data to Data::PhotoMedia. 2020-06-01 18:09:32 +04:00
John Preston
24fed8105c Fix stickers panel on Retina screens. 2020-06-01 18:09:32 +04:00
John Preston
9ce59730ff Collect local DocumentMedia data. 2020-06-01 18:09:32 +04:00
John Preston
3f26fc9f55 Allow WebDocument video thumbnails. 2020-06-01 18:09:32 +04:00
John Preston
0834920db8 Fix sending of video-thumbed GIFs from panel. 2020-06-01 18:09:32 +04:00
John Preston
f4ed2c26ba Save video thumbnail location to local storage. 2020-06-01 18:09:32 +04:00
John Preston
c63e2c01ac Use video thumbnail in media preview. 2020-06-01 18:09:31 +04:00
John Preston
c61f3a0aba Fix sending of thumbnailed inline result GIFs. 2020-06-01 18:09:31 +04:00
John Preston
3c9ca2eb94 Load and show video thumbnails in the panel. 2020-06-01 18:09:31 +04:00
John Preston
33c1c48ad9 Update API scheme to layer 114. 2020-06-01 18:09:31 +04:00
John Preston
a27aea3887 Allow retrying of updates build preparing. 2020-06-01 18:09:31 +04:00
John Preston
ea4044e38c Use TgVoip interface instead of VoIPController. 2020-06-01 18:09:31 +04:00
John Preston
c967a72dcb Save frame in GIFs panel. 2020-06-01 18:09:31 +04:00
John Preston
7d386b164b Save a frame in stickers panel. 2020-06-01 18:09:31 +04:00
John Preston
ccbbf6f5f3 Always download GIFs in the panel.
Fixes #6981.
2020-06-01 18:09:31 +04:00
John Preston
9725d4272e Clear DocumentMedia in sticker panel. 2020-06-01 18:09:31 +04:00
John Preston
eb75859dc0 Cache last frame of stickers panel footer icons. 2020-06-01 18:09:31 +04:00
John Preston
ad5507f2c8 Clear DocumentMedia in media overview. 2020-06-01 18:09:31 +04:00
John Preston
58f82620e0 Simplify media overview layouts. 2020-06-01 18:09:31 +04:00
John Preston
053eace154 Prepare overview layouts for media clearing. 2020-06-01 18:09:31 +04:00
John Preston
d64014c995 Clear DocumentMedia in ReplyPreview. 2020-06-01 18:09:31 +04:00
John Preston
44ec55b6a8 Clear DocumentMedia in links overview. 2020-06-01 18:09:31 +04:00
John Preston
9dba723643 Better DocumentMedia management in BackgroundBox. 2020-06-01 18:09:31 +04:00
John Preston
97a82762ef Fix build with MSVC 16.6.0. 2020-06-01 18:09:31 +04:00
John Preston
1542311d89 Preload documents in media viewer. 2020-06-01 18:09:31 +04:00
John Preston
fb322b5fc5 Use empty Storage::Cache::Key as nullopt. 2020-06-01 18:09:31 +04:00
John Preston
581a21dbd9 Use Media::Streaming in EditCaptionBox. 2020-06-01 18:09:31 +04:00
John Preston
3d431a27cb Improve inline thumbnail usage in PiP player. 2020-06-01 18:09:31 +04:00
John Preston
cbb9657044 Fix download task finalizing. 2020-06-01 18:09:30 +04:00
John Preston
3797753d16 Support different location types for thumbnails. 2020-06-01 18:09:30 +04:00
John Preston
37aabc0da9 Add generic DownloadLocation and ImageLocation. 2020-06-01 18:09:30 +04:00
John Preston
956c3af0ae Start DocumentData::thumbnail move to DocumentMedia. 2020-06-01 18:09:30 +04:00
John Preston
1329870c8e Fix build on macOS. 2020-06-01 18:09:30 +04:00
John Preston
ff6365ec72 Fix crash in still downloaded ~DocumentData. 2020-06-01 18:09:30 +04:00
John Preston
1e9c79ca85 Move automaticLoad() to DocumentMedia. 2020-06-01 18:09:30 +04:00
John Preston
40f12a2584 Keep document byte data only in DocumentMedia. 2020-06-01 18:09:30 +04:00
John Preston
97bab388ea Use rpl for file download progress notifications. 2020-06-01 18:09:30 +04:00
John Preston
bf616036b3 Check loaded status through DocumentMedia if possible. 2020-06-01 18:09:30 +04:00
John Preston
669b79588e Remove FilePathResolve::SaveFromData. 2020-06-01 18:09:30 +04:00
John Preston
33f4946242 Start using document bytes from DocumentMedia. 2020-06-01 18:09:30 +04:00
John Preston
888e42df34 Remove data_document_good_thumbnail module. 2020-06-01 18:09:30 +04:00
John Preston
70c79eb6bd Move sticker image to DocumentMedia. 2020-06-01 18:09:30 +04:00
John Preston
bdd3c51ab8 Move inline thumbnail image to DocumentMedia. 2020-06-01 18:09:30 +04:00
John Preston
6ca43153bb Improve clearing of DocumentMedia. 2020-06-01 18:09:29 +04:00
John Preston
7db53599e8 Use Data::DocumentMedia to store good thumbnails. 2020-06-01 18:09:29 +04:00
John Preston
61647275e8 Optimize image destruction.
No need to call _source->unload(), it leads to saving to PNG.
2020-06-01 18:09:29 +04:00
Ilya Fedin
a37138aa52 Fix signature key errors in snap action 2020-06-01 15:24:35 +04:00
Ilya Fedin
1504136828 Don't spam logs if there are no dbus 2020-05-26 07:24:18 +04:00
Ilya Fedin
c12356a032 Disable unneeded alsa dependency in ffmpeg 2020-05-25 10:34:12 +04:00
Ilya Fedin
126ed6e6e3 Fix path to compose file 2020-05-25 10:34:12 +04:00
Ilya Fedin
fa4236e9ea Add support for DESKTOP_APP_USE_PACKAGED on macOS 2020-05-25 10:29:40 +04:00
Ilya Fedin
b19dcf0653 Add possibility to control external upater flag with a config in /etc 2020-05-25 10:27:48 +04:00
Ilya Fedin
77d1f64e0e Disable fallback session management 2020-05-25 09:31:52 +04:00
Ilya Fedin
3479a4ec59 Add parent, minimum and maximum size to notifications 2020-05-25 09:29:15 +04:00
Ilya Fedin
bdf28370f9 Fix call window size on Sway 2020-05-25 09:29:15 +04:00
Ilya Fedin
cd81fc6727 Don't lose -freetype argument on restart 2020-05-25 09:26:49 +04:00
John Preston
7351641034 Version 2.1.7.
- Fix the Fcitx input method plugin.
2020-05-24 11:59:19 +04:00
Ilya Fedin
e0669e222d Update fcitx5-qt 2020-05-24 11:09:34 +04:00
Ilya Fedin
4c1f83daca Add a check for bundled Qt plugins 2020-05-24 10:57:37 +04:00
Ilya Fedin
ced2652deb OpenAL returns device names with UTF-8 2020-05-24 10:56:29 +04:00
23rd
8d1db85a28 Fixed album items selection in section of scheduled messages.
This bug relates only to albums with captions.
2020-05-20 12:00:44 +03:00
John Preston
97305c8cb5 Fix build. 2020-05-20 12:49:41 +04:00
23rd
1ef5d81270 Added ability to change months in calendar with mouse wheel. 2020-05-20 12:42:03 +04:00
23rd
9ff427afad Fixed indefinitely bouncing of dock icon. 2020-05-20 12:41:44 +04:00
23rd
1c5eadcd79 Fixed context menu for caption of scheduled album.
Fixed #6523.
2020-05-20 12:41:44 +04:00
23rd
bc6c01de7f Added Esc shortcut to clear selection in section of scheduled messages. 2020-05-20 12:41:44 +04:00
23rd
41255cab44 Removed display views and author for sent scheduled messages.
Moved filling of post flags to a single place.
2020-05-20 12:41:44 +04:00
23rd
ccbc63cd6e Added ability to paste data in section of scheduled messages.
Fixed #6702.
Fixed #6539.
2020-05-20 12:41:44 +04:00
23rd
97446ae783 Added ability to reschedule scheduled messages. 2020-05-20 12:41:44 +04:00
23rd
5a75dd2b6f Added handling of updates for rescheduled messages. 2020-05-20 12:41:43 +04:00
Wei Cheng
6559e83e83 fix: obtain doNotDisturb value correctly 2020-05-15 11:44:06 +04:00
John Preston
d679703bbf Version 2.1.6.
- Fix automatic downloads on Windows by clean rebuild.
2020-05-14 01:16:13 +04:00
John Preston
66a3e36024 Version 2.1.5.
- Disable the taskbar icon flash or the dock icon bounce
in Settings > Notifications.
- View messages containing long monospace texts in wide bubbles.
- Bug fixes and other minor improvements.
2020-05-13 18:22:05 +04:00
John Preston
31e38e1690 Fix layout of community transfer error box. 2020-05-13 18:19:09 +04:00
John Preston
da10059f45 Update lib_lottie, hide rlottie dependency. 2020-05-13 17:07:26 +04:00
John Preston
cb5863177f Apply edition updates to search result previews. 2020-05-12 20:29:18 +04:00
John Preston
84399286c1 Update build instructions. 2020-05-12 19:43:39 +04:00
John Preston
2e92441b3a Add input method field text edit workaround. 2020-05-12 19:26:50 +04:00
John Preston
7883f97c94 Use precise sync of the server unixtime. 2020-05-12 17:33:06 +04:00
Ilya Fedin
297b5d6a76 Update submodules 2020-05-12 17:32:40 +04:00
Ilya Fedin
492dc2568c Add DESKTOP_APP_USE_PACKAGED support for Windows 2020-05-12 17:32:40 +04:00
John Preston
547c657b1a Don't reset search results on dialogs re-open. 2020-05-12 16:30:31 +04:00
John Preston
c478d96385 Add debug logs for chats reading requests. 2020-05-12 16:18:19 +04:00
John Preston
2ede53e0ee Always try to open new provided URL.
Fixes #6941.
2020-05-12 16:15:22 +04:00
John Preston
6f760d513e Add a checkbox to disable taskbar flash.
Also add ability to set urgent flag for the window on Linux.

Fixes #223, fixes #897, fixes #906.
2020-05-12 14:16:24 +04:00
John Preston
f4f6550d66 Clear fake-unread status when switching folders. 2020-05-12 12:18:52 +04:00
John Preston
c7878f9d21 Pause by-emoji stickers on sticker preview. 2020-05-12 12:18:31 +04:00
John Preston
cd75a45673 Disable create polls in support accounts. 2020-05-12 11:26:47 +04:00
John Preston
07e3671ca8 Allow monospace blocks to extend bubble width.
This partially fixes #2060 instead of additional settings from #7822.
2020-05-12 11:07:41 +04:00
23rd
295aa644bf Fixed master branch updater Github Action. 2020-05-12 09:55:36 +04:00
John Preston
b5b78c0ade Update submodules. 2020-05-12 09:44:24 +04:00
John Preston
f5c0e5d31d Remove unnecessary include. 2020-05-12 09:43:54 +04:00
root
246ed43046 Remove replyTo from switchInlineBotButton in same peer 2020-05-12 09:29:30 +04:00
Ilya Fedin
701e1d7b4d Add fcitx5 support 2020-05-12 09:26:04 +04:00
Ilya Fedin
9cbe899688 Fix call window hiding when compositing is not supported 2020-05-12 09:17:27 +04:00
Ilya Fedin
7409d615a3 Add a cheat code to enable freetype on Windows and macOS 2020-05-10 17:09:59 +04:00
John Preston
c9553c2d4c Version 2.1.4.
- Improve bold font selection.
2020-05-08 20:34:00 +04:00
John Preston
bedefaee4d Version 2.1.3.
- Added support for new emoji.
- Channels to which you can't post will no longer be suggested when forwarding.
- Improved font selection and bold font support for CJK and Farsi.
2020-05-08 16:48:56 +04:00
John Preston
5d3b8f02fc Add Vazir font as a fallback for Farsi. 2020-05-08 13:38:23 +04:00
John Preston
5120d3ef2c Skip channels without write access in forward box. 2020-05-08 13:35:16 +04:00
John Preston
82a372873f Add two local urls to open language selection box.
tg://setlanguage and tg://settings/language

Fixes #7831.
2020-05-08 13:03:49 +04:00
Ilya Fedin
d1d1f83881 Remove outdated LIBGL_ALWAYS_INDIRECT hack 2020-05-08 12:54:21 +04:00
Ilya Fedin
78c3c86fe6 Check only if at least one audio device is exist on startup
This makes https://github.com/telegramdesktop/tdesktop/issues/1548 don't affect on startup, but only when capture feature is used
2020-05-08 12:50:25 +04:00
Ilya Fedin
447d4e6c47 Remove Portaudio from building instructions
Since it loaded at runtime with dlopen anyway and headers from the system package are OK
2020-05-08 12:49:21 +04:00
John Preston
d0e3d15e8e Update supported systems information. 2020-05-08 12:27:55 +04:00
John Preston
0251f58bf2 Use Semibold in names, use Bold in messages.
Fixes #7813, fixes #7823.
2020-05-08 12:12:47 +04:00
John Preston
36997f084a Automatically load and apply old emoji set by id. 2020-05-08 11:22:22 +04:00
John Preston
942fcb9aae Add new emoji sets file ids. 2020-05-07 19:05:57 +04:00
John Preston
6232dce1a3 Update emoji in the built-in data and sprites. 2020-05-06 19:29:02 +04:00
23rd
0c0fc46b90 Added Github Action that updates code in master branch. 2020-05-06 13:29:17 +04:00
23rd
dcf737bebe Fixed Linux build instruction. 2020-05-06 00:36:48 +03:00
23rd
919834093e Added TG for macOS version check to issue closer. 2020-05-05 18:22:54 +04:00
John Preston
99ccd49e13 Version 2.1.2: Update patches revision in docs. 2020-05-05 18:14:38 +04:00
John Preston
29896b2efd Version 2.1.2: Update Mac App Store build script. 2020-05-05 17:35:42 +04:00
673 changed files with 37356 additions and 28451 deletions

View File

@@ -14,6 +14,22 @@ jobs:
echo $tag
echo ::set-env name=LATEST_TAG::$tag
- name: Get the latest macOS version.
shell: python
run: |
import subprocess;
from xml.dom import minidom;
url = "https://osx.telegram.org/updates/versions.xml";
subprocess.check_call("wget %s" % url, shell=True);
xmldoc = minidom.parse('versions.xml');
itemlist = xmldoc.getElementsByTagName('enclosure');
ver = itemlist[0].attributes['sparkle:shortVersionString'].value;
print(ver);
subprocess.check_call("echo ::set-env name=%s::%s" % ("LATEST_MACOS", ver), shell=True);
- name: Check a version from an issue.
uses: actions/github-script@0.4.0
with:
@@ -75,10 +91,20 @@ jobs:
let issueNum = firstNum(issueVer);
let latestNum = firstNum(latestVer);
if (issueNum <= latestNum && issueNum < 5) {
let macos_ver = process.env.LATEST_MACOS;
console.log("Telegram for MacOS version from website: " + macos_ver);
if (issueNum <= latestNum && issueNum < macos_ver) {
console.log("Seems the version of this issue is fine!");
return;
}
if (issueNum > macos_ver) {
let message = `Seems like it's neither the Telegram Desktop\
nor the Telegram for macOS version.
`;
console.log(message);
return;
}
let message = `
Sorry, but according to the version you specify in this issue, \
@@ -87,7 +113,7 @@ jobs:
You can report your issue to [the group](https://t.me/macswift) \
or to [the repository of Telegram for macOS](https://github.com/overtake/TelegramSwift).
If I made a mistake and closed your issue wrongly, please reopen it. Thanks!
**If I made a mistake and closed your issue wrongly, please reopen it. Thanks!**
`;
let params = {

View File

@@ -221,6 +221,7 @@ jobs:
--disable-autodetect \
--disable-everything \
--disable-neon \
--disable-alsa \
--disable-iconv \
--enable-libopus \
--enable-vaapi \
@@ -335,19 +336,6 @@ jobs:
sudo cp -R ffmpeg-cache/. /
- name: PortAudio.
run: |
cd $LibrariesPath
git clone https://git.assembla.com/portaudio.git
cd portaudio
git checkout 396fe4b669
./configure
make -j$(nproc)
sudo make install
cd ..
rm -rf portaudio
- name: OpenAL Soft.
run: |
cd $LibrariesPath
@@ -391,36 +379,43 @@ jobs:
cd $LibrariesPath
sudo cp -R openssl-cache/. /
- name: Libwayland.
run: |
cd $LibrariesPath
git clone -b 1.18.0 https://gitlab.freedesktop.org/wayland/wayland
cd wayland
./autogen.sh \
--enable-static \
--disable-documentation \
--disable-dtd-validation
make -j$(nproc)
sudo make install
cd ..
rm -rf wayland
- name: Libxkbcommon.
run: |
cd $LibrariesPath
git clone -b xkbcommon-0.8.4 --depth=1 $GIT/xkbcommon/libxkbcommon.git
cd libxkbcommon
./autogen.sh
./autogen.sh \
--disable-docs \
--disable-wayland \
--with-xkb-config-root=/usr/share/X11/xkb \
--with-x-locale-root=/usr/share/X11/locale
make -j$(nproc)
sudo make install
cd ..
rm -rf libxkbcommon
- name: Libwayland.
run: |
cd $LibrariesPath
git clone -b 1.16 https://gitlab.freedesktop.org/wayland/wayland
cd wayland
./autogen.sh --enable-static --disable-documentation --disable-dtd-validation
make -j$(nproc)
sudo make install
cd ..
rm -rf wayland
- name: Qt 5.12.8 cache.
id: cache-qt
uses: actions/cache@v1
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('**/qt*_5_12_8/*') }}
- name: Qt 5.12.8 build.
if: steps.cache-qt.outputs.cache-hit != 'true'
run: |
@@ -428,11 +423,14 @@ jobs:
git clone -b v5.12.8 --depth=1 git://code.qt.io/qt/qt5.git qt_${QT}
cd qt_${QT}
perl init-repository --module-subset=qtbase,qtwayland,qtimageformats,qtsvg
git submodule update qtbase qtwayland qtimageformats qtsvg
perl init-repository --module-subset=qtbase,qtwayland,qtimageformats,qtsvg,qtx11extras
git submodule update qtbase qtwayland qtimageformats qtsvg qtx11extras
cd qtbase
git apply ../../patches/qtbase_${QT}.diff
cd ../
find ../../patches/qtbase_${QT} -type f -print0 | sort -z | xargs -r0 git apply
cd ..
cd qtwayland
find ../../patches/qtwayland_${QT} -type f -print0 | sort -z | xargs -r0 git apply
cd ..
./configure -prefix "$QT_PREFIX" \
-release \

View File

@@ -88,6 +88,7 @@ jobs:
echo $MIN_MAC >> CACHE_KEY.txt
echo $PREFIX >> CACHE_KEY.txt
echo $MANUAL_CACHING >> CACHE_KEY.txt
echo "$GITHUB_WORKSPACE" >> CACHE_KEY.txt
if [ "$AUTO_CACHING" == "1" ]; then
thisFile=$REPO_NAME/.github/workflows/mac.yml
echo `md5 -q $thisFile` >> CACHE_KEY.txt
@@ -403,7 +404,7 @@ jobs:
uses: actions/cache@v1
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: |
@@ -423,7 +424,7 @@ jobs:
git submodule update qtbase
git submodule update qtimageformats
cd qtbase
git apply ../../patches/qtbase_$QT.diff
find ../../patches/qtbase_$QT -type f -print0 | sort -z | xargs -0 git apply
cd ..
./configure \

35
.github/workflows/master_updater.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
name: Master branch updater.
on:
release:
types: released
jobs:
updater:
runs-on: ubuntu-latest
env:
SKIP: "0"
to_branch: "master"
steps:
- uses: actions/checkout@v1
if: env.SKIP == '0'
- name: Push the code to the master branch.
if: env.SKIP == '0'
run: |
token=${{ secrets.TOKEN_FOR_MASTER_UPDATER }}
if [ -z "${token}" ]; then
echo "Token is unset. Nothing to do."
exit 0
fi
url=https://x-access-token:$token@github.com/$GITHUB_REPOSITORY
latest_tag=$(git describe --tags --abbrev=0)
echo "Latest tag: $latest_tag"
git remote set-url origin $url
git remote -v
git checkout master
git merge $latest_tag
git push origin HEAD:refs/heads/$to_branch
echo "Done!"

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,13 +41,11 @@ 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"
ONLY_CACHE: "false"
MANUAL_CACHING: "5"
steps:
- name: Clone.
@@ -59,56 +55,17 @@ jobs:
- name: First set up.
run: |
# Workaround for permanent problems with third-party repository keys
sudo rm -rf /etc/apt/sources.list.d/*
sudo apt-get update
sudo apt-get install gcc-8 g++-8 -y
sudo snap install --classic snapcraft
# Workaround for snapcraft
# See https://forum.snapcraft.io/t/13258
sudo chown root:root /
md5() {
md5cache=$(md5sum $1.txt | cut -c -32)
echo ::set-env name=$1::$md5cache
}
keyFor() {
keyName="${1^^}_CACHE_KEY"
awk -v RS="" -v ORS="\n\n" '/^ '"$1"':/' snap/snapcraft.yaml > $keyName.txt
md5 $keyName
}
snap run snapcraft --version > CACHE_KEY.txt
gcc-8 --version >> CACHE_KEY.txt
echo $MANUAL_CACHING >> CACHE_KEY.txt
md5 CACHE_KEY
keyFor cmake
keyFor ffmpeg
- name: CMake cache.
id: cache-cmake
uses: actions/cache@v1
with:
path: parts/cmake
key: ${{ runner.OS }}-cmake-${{ env.CACHE_KEY }}-${{ env.CMAKE_CACHE_KEY }}
- name: CMake build.
if: steps.cache-cmake.outputs.cache-hit != 'true'
run: sudo snap run snapcraft build --destructive-mode cmake
- name: FFmpeg cache.
id: cache-ffmpeg
uses: actions/cache@v1
with:
path: parts/ffmpeg
key: ${{ runner.OS }}-ffmpeg-${{ env.CACHE_KEY }}-${{ env.FFMPEG_CACHE_KEY }}
- name: FFmpeg build.
if: steps.cache-ffmpeg.outputs.cache-hit != 'true'
run: sudo snap run snapcraft build --destructive-mode ffmpeg
- name: Telegram Desktop snap build.
if: env.ONLY_CACHE == 'false'
run: sudo snap run snapcraft --destructive-mode
- name: Move artifact.
@@ -126,8 +83,3 @@ jobs:
with:
name: ${{ env.ARTIFACT_NAME }}
path: artifact
- name: Remove unneeded directories for cache.
run: |
sudo rm -rf parts/*/{build,src,ubuntu}
sudo rm -rf parts/*/state/{stage,prime}

View File

@@ -294,7 +294,7 @@ jobs:
uses: actions/cache@v1
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
@@ -308,7 +308,7 @@ jobs:
git submodule update qtbase
git submodule update qtimageformats
cd qtbase
git apply ../../patches/qtbase_%QT%.diff
for /r %%i in (..\..\patches\qtbase_%QT%\*) do git apply %%i
cd ..
SET SSL=%LibrariesPath%\openssl_1_1_1
@@ -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'

5
.gitmodules vendored
View File

@@ -3,7 +3,7 @@
url = https://github.com/telegramdesktop/libtgvoip
[submodule "Telegram/ThirdParty/variant"]
path = Telegram/ThirdParty/variant
url = https://github.com/mapbox/variant
url = https://github.com/desktop-app/variant.git
[submodule "Telegram/ThirdParty/GSL"]
path = Telegram/ThirdParty/GSL
url = https://github.com/Microsoft/GSL.git
@@ -91,3 +91,6 @@
[submodule "Telegram/ThirdParty/libqtxdg"]
path = Telegram/ThirdParty/libqtxdg
url = https://github.com/lxqt/libqtxdg.git
[submodule "Telegram/ThirdParty/fcitx5-qt"]
path = Telegram/ThirdParty/fcitx5-qt
url = https://github.com/fcitx/fcitx5-qt.git

View File

@@ -13,18 +13,27 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
## Supported systems
* Windows XP - Windows 10 (**not** RT)
* Mac OS X 10.8 - Mac OS X 10.15
* Mac OS X 10.6 - Mac OS X 10.7 (separate build)
* Ubuntu 12.04 - Ubuntu 20.04
* Fedora 22 - Fedora 31
* [Snappy](https://snapcraft.io/telegram-desktop)
* [Flathub](https://flathub.org/apps/details/org.telegram.desktop)
The latest version is available for
* [Windows 7 and above](https://telegram.org/dl/desktop/win) ([portable](https://telegram.org/dl/desktop/win_portable))
* [macOS 10.12 and above](https://telegram.org/dl/desktop/mac)
* [OS X 10.10 and 10.11](https://telegram.org/dl/desktop/osx)
* [Linux static build for 64 bit](https://telegram.org/dl/desktop/linux) ([32 bit](https://telegram.org/dl/desktop/linux32))
* [Snap](https://snapcraft.io/telegram-desktop)
* [Flatpak](https://flathub.org/apps/details/org.telegram.desktop)
## Old system versions
Version **1.8.15** was the last that supports older systems
* [Windows XP and Vista](https://updates.tdesktop.com/tsetup/tsetup.1.8.15.exe) ([portable](https://updates.tdesktop.com/tsetup/tportable.1.8.15.zip))
* [OS X 10.8 and 10.9](https://updates.tdesktop.com/tmac/tsetup.1.8.15.dmg)
* [OS X 10.6 and 10.7](https://updates.tdesktop.com/tmac32/tsetup32.1.8.15.dmg)
## Third-party
* Qt 5.12.8 and 5.6.2, slightly patched ([LGPL](http://doc.qt.io/qt-5/lgpl.html))
* OpenSSL 1.1.1 ([OpenSSL License](https://www.openssl.org/source/license.html))
* Qt 5.12.8, 5.6.2 and 5.3.2 slightly patched ([LGPL](http://doc.qt.io/qt-5/lgpl.html))
* OpenSSL 1.1.1 and 1.0.1 ([OpenSSL License](https://www.openssl.org/source/license.html))
* zlib 1.2.11 ([zlib License](http://www.zlib.net/zlib_license.html))
* LZMA SDK 9.20 ([public domain](http://www.7-zip.org/sdk.html))
* liblzma ([public domain](http://tukaani.org/xz/))
@@ -39,6 +48,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
* Mapbox Variant ([BSD License](https://github.com/mapbox/variant/blob/master/LICENSE))
* Range-v3 ([Boost License](https://github.com/ericniebler/range-v3/blob/master/LICENSE.txt))
* Open Sans font ([Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html))
* Vazir font ([License](https://github.com/rastikerdar/vazir-font/blob/master/LICENSE))
* Emoji alpha codes ([MIT License](https://github.com/emojione/emojione/blob/master/extras/alpha-codes/LICENSE.md))
* Catch test framework ([Boost License](https://github.com/philsquared/Catch/blob/master/LICENSE.txt))
* xxHash ([BSD License](https://github.com/Cyan4973/xxHash/blob/dev/LICENSE))

View File

@@ -91,6 +91,7 @@ if (LINUX)
desktop-app::external_statusnotifieritem
desktop-app::external_dbusmenu_qt
desktop-app::external_fcitx_qt5
desktop-app::external_fcitx5_qt5
desktop-app::external_hime_qt
)
endif()
@@ -126,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>
@@ -138,7 +168,7 @@ endif()
if (DESKTOP_APP_USE_PACKAGED)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads)
find_package(Threads REQUIRED)
target_link_libraries(Telegram
PRIVATE
@@ -154,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
@@ -165,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
@@ -263,6 +296,9 @@ PRIVATE
calls/calls_box_controller.h
calls/calls_call.cpp
calls/calls_call.h
calls/calls_controller.cpp
calls/calls_controller.h
calls/calls_controller_tgvoip.h
calls/calls_emoji_fingerprint.cpp
calls/calls_emoji_fingerprint.h
calls/calls_instance.cpp
@@ -289,14 +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_lottie.cpp
chat_helpers/stickers_lottie.h
chat_helpers/tabbed_panel.cpp
chat_helpers/tabbed_panel.h
chat_helpers/tabbed_section.cpp
@@ -325,7 +363,6 @@ PRIVATE
core/launcher.h
core/local_url_handlers.cpp
core/local_url_handlers.h
core/media_active_cache.h
core/mime_type.cpp
core/mime_type.h
core/sandbox.cpp
@@ -339,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
@@ -347,18 +388,22 @@ 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
data/data_channel_admins.h
data/data_cloud_file.cpp
data/data_cloud_file.h
data/data_cloud_themes.cpp
data/data_cloud_themes.h
data/data_countries.cpp
data/data_countries.h
data/data_document.cpp
data/data_document.h
data/data_document_good_thumbnail.cpp
data/data_document_good_thumbnail.h
data/data_document_media.cpp
data/data_document_media.h
data/data_drafts.cpp
data/data_drafts.h
data/data_folder.cpp
@@ -389,10 +434,14 @@ PRIVATE
data/data_peer_values.h
data/data_photo.cpp
data/data_photo.h
data/data_photo_media.cpp
data/data_photo_media.h
data/data_poll.cpp
data/data_poll.h
data/data_pts_waiter.cpp
data/data_pts_waiter.h
data/data_reply_preview.cpp
data/data_reply_preview.h
data/data_search_controller.cpp
data/data_search_controller.h
data/data_session.cpp
@@ -437,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
@@ -652,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
@@ -735,8 +788,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
@@ -753,6 +804,7 @@ PRIVATE
mtproto/type_utils.h
overview/overview_layout.cpp
overview/overview_layout.h
overview/overview_layout_delegate.h
passport/passport_encryption.cpp
passport/passport_encryption.h
passport/passport_form_controller.cpp
@@ -791,11 +843,11 @@ 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
platform/mac/launcher_mac.h
platform/mac/mac_iconv_helper.c
platform/mac/main_window_mac.mm
platform/mac/main_window_mac.h
platform/mac/notifications_manager_mac.mm
@@ -870,6 +922,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
@@ -888,8 +944,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
@@ -922,8 +984,8 @@ PRIVATE
ui/image/image.h
ui/image/image_location.cpp
ui/image/image_location.h
ui/image/image_source.cpp
ui/image/image_source.h
ui/image/image_location_factory.cpp
ui/image/image_location_factory.h
ui/widgets/continuous_sliders.cpp
ui/widgets/continuous_sliders.h
ui/widgets/discrete_sliders.cpp
@@ -988,6 +1050,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
@@ -1024,15 +1088,22 @@ 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()
nice_target_sources(Telegram ${src_loc} PRIVATE platform/mac/mac_iconv_helper.c)
endif()
nice_target_sources(Telegram ${res_loc}
@@ -1042,6 +1113,8 @@ PRIVATE
qrc/emoji_3.qrc
qrc/emoji_4.qrc
qrc/emoji_5.qrc
qrc/emoji_6.qrc
qrc/emoji_7.qrc
qrc/emoji_preview.qrc
qrc/telegram/telegram.qrc
qrc/telegram/sounds.qrc
@@ -1066,11 +1139,11 @@ if (WIN32)
# $<IF:${release},"Appending compatibility manifest.","Finalizing build.">
# )
elseif (APPLE)
target_link_libraries(Telegram
PRIVATE
desktop-app::external_sp_media_key_tap
desktop-app::external_iconv
)
target_link_libraries(Telegram PRIVATE desktop-app::external_sp_media_key_tap)
if (NOT DESKTOP_APP_USE_PACKAGED)
target_link_libraries(Telegram PRIVATE desktop-app::external_iconv)
endif()
set(icons_path ${CMAKE_CURRENT_SOURCE_DIR}/Telegram/Images.xcassets)
set_target_properties(Telegram PROPERTIES RESOURCE ${icons_path})
@@ -1109,19 +1182,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)
@@ -1194,7 +1254,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)
@@ -1210,6 +1270,10 @@ if ((NOT DESKTOP_APP_DISABLE_AUTOUPDATE OR NOT LINUX) AND NOT build_macstore AND
set_target_properties(Updater PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${output_folder})
if (WIN32 AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
target_link_options(Updater PRIVATE -municode)
endif()
if (LINUX)
target_link_options(Updater PRIVATE -static-libstdc++)
endif()

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.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

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,7 @@ 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_disable_notifications_from_tray" = "Disable notifications";
"lng_enable_notifications_from_tray" = "Enable notifications";
@@ -300,6 +301,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_notifications_position" = "Location on the screen";
"lng_settings_notifications_count" = "Notifications count";
"lng_settings_sound_notify" = "Play sound";
"lng_settings_alert_windows" = "Flash the taskbar icon";
"lng_settings_alert_mac" = "Bounce the dock icon";
"lng_settings_alert_linux" = "Draw attention to the window";
"lng_settings_badge_title" = "Badge counter";
"lng_settings_include_muted" = "Include muted chats in unread count";
"lng_settings_count_unread" = "Count unread messages";
@@ -1451,6 +1455,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_edit_msg" = "Edit";
"lng_context_forward_msg" = "Forward Message";
"lng_context_send_now_msg" = "Send now";
"lng_context_reschedule" = "Reschedule";
"lng_context_delete_msg" = "Delete Message";
"lng_context_select_msg" = "Select Message";
"lng_context_report_msg" = "Report Message";
@@ -2146,6 +2151,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_export_option_size_limit" = "Size limit: {size}";
"lng_export_header_format" = "Location and format";
"lng_export_option_location" = "Download path: {path}";
"lng_export_option_format_location" = "Format: {format}, Path: {path}";
"lng_export_option_choose_format" = "Choose export format";
"lng_export_option_html" = "Human-readable HTML";
"lng_export_option_json" = "Machine-readable JSON";
"lng_export_limits" = "From: {from}, to: {till}";
@@ -2245,6 +2252,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_polls_votes_collapse" = "Collapse";
"lng_outdated_title" = "PLEASE UPDATE YOUR OPERATING SYSTEM.";
"lng_outdated_title_bits" = "PLEASE SWITCH TO 64 BIT OPERATING SYSTEM.";
"lng_outdated_soon" = "Otherwise, Telegram Desktop will stop updating on {date}.";
"lng_outdated_now" = "So that Telegram Desktop can update to newer versions.";

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/gui">
<file alias="emoji/emoji_6.webp">../emoji/emoji_6.webp</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/gui">
<file alias="emoji/emoji_7.webp">../emoji/emoji_7.webp</file>
</qresource>
</RCC>

View File

@@ -357,6 +357,7 @@ updateMessagePollVote#42f88f2c poll_id:long user_id:int options:Vector<bytes> =
updateDialogFilter#26ffde7d flags:# id:int filter:flags.0?DialogFilter = Update;
updateDialogFilterOrder#a5d72105 order:Vector<int> = Update;
updateDialogFilters#3504914f = Update;
updatePhoneCallSignalingData#2661bf09 phone_call_id:long data:bytes = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@@ -421,7 +422,7 @@ inputDocumentEmpty#72f0eaae = InputDocument;
inputDocument#1abfb575 id:long access_hash:long file_reference:bytes = InputDocument;
documentEmpty#36f8c871 id:long = Document;
document#9ba29cc1 flags:# id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumbs:flags.0?Vector<PhotoSize> dc_id:int attributes:Vector<DocumentAttribute> = Document;
document#1e87342b flags:# id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumbs:flags.0?Vector<PhotoSize> video_thumbs:flags.1?Vector<VideoSize> dc_id:int attributes:Vector<DocumentAttribute> = Document;
help.support#17c6b5f6 phone_number:string user:User = help.Support;
@@ -1140,6 +1141,8 @@ stats.broadcastStats#bdf78394 period:StatsDateRangeDays followers:StatsAbsValueA
help.promoDataEmpty#98f6ac75 expires:int = help.PromoData;
help.promoData#8c39793f flags:# proxy:flags.0?true expires:int peer:Peer chats:Vector<Chat> users:Vector<User> psa_type:flags.1?string psa_message:flags.2?string = help.PromoData;
videoSize#435bb987 type:string location:FileLocation w:int h:int size:int = VideoSize;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@@ -1485,6 +1488,7 @@ phone.receivedCall#17d54f61 peer:InputPhoneCall = Bool;
phone.discardCall#b2cbc1c0 flags:# video:flags.0?true peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates;
phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhoneCall rating:int comment:string = Updates;
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
phone.sendSignalingData#ff7a9383 peer:InputPhoneCall data:bytes = Bool;
langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference;
langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector<string> = Vector<LangPackString>;
@@ -1498,4 +1502,4 @@ folders.deleteFolder#1c295881 folder_id:int = Updates;
stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats;
stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph;
// LAYER 113
// LAYER 114

View File

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

View File

@@ -6,7 +6,18 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
#if defined(__MINGW64__) || defined(__MINGW32__)
// MinGW-w64, MinGW
#if defined(__has_include) && __has_include(<winres.h>)
#include <winres.h>
#else
#include <afxres.h>
#include <winresrc.h>
#endif
#else
// MSVC, Windows SDK
#include <winres.h>
#endif
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
@@ -33,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,1,2,0
PRODUCTVERSION 2,1,2,0
FILEVERSION 2,1,14,0
PRODUCTVERSION 2,1,14,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -51,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop"
VALUE "FileVersion", "2.1.2.0"
VALUE "FileVersion", "2.1.14.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.1.2.0"
VALUE "ProductVersion", "2.1.14.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -6,7 +6,18 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
#if defined(__MINGW64__) || defined(__MINGW32__)
// MinGW-w64, MinGW
#if defined(__has_include) && __has_include(<winres.h>)
#include <winres.h>
#else
#include <afxres.h>
#include <winresrc.h>
#endif
#else
// MSVC, Windows SDK
#include <winres.h>
#endif
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
@@ -24,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,1,2,0
PRODUCTVERSION 2,1,2,0
FILEVERSION 2,1,14,0
PRODUCTVERSION 2,1,14,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -42,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop Updater"
VALUE "FileVersion", "2.1.2.0"
VALUE "FileVersion", "2.1.14.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2020"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "2.1.2.0"
VALUE "ProductVersion", "2.1.14.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
}
@@ -268,7 +268,7 @@ int main(int argc, char *argv[])
cout << "Compression start, size: " << resultSize << "\n";
QByteArray compressed, resultCheck;
#ifdef Q_OS_WIN // use Lzma SDK for win
#if defined Q_OS_WIN && !defined DESKTOP_APP_USE_PACKAGED // use Lzma SDK for win
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header
compressed.resize(hSize + resultSize + 1024 * 1024); // rsa signature + sha1 + lzma props + max compressed size
@@ -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

@@ -27,7 +27,7 @@ extern "C" {
#include <openssl/evp.h>
} // extern "C"
#ifdef Q_OS_WIN // use Lzma SDK for win
#if defined Q_OS_WIN && !defined DESKTOP_APP_USE_PACKAGED // use Lzma SDK for win
#include <LzmaLib.h>
#else
#include <lzma.h>

View File

@@ -90,7 +90,7 @@ int main(int argc, const char * argv[]) {
openLog();
pid_t procId = 0;
BOOL update = YES, toSettings = NO, autoStart = NO, startInTray = NO, testMode = NO, externalUpdater = NO;
BOOL update = YES, toSettings = NO, autoStart = NO, startInTray = NO, testMode = NO, freeType = NO, externalUpdater = NO;
BOOL customWorkingDir = NO;
NSString *key = nil;
for (int i = 0; i < argc; ++i) {
@@ -116,6 +116,8 @@ int main(int argc, const char * argv[]) {
startInTray = YES;
} else if ([@"-testmode" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
testMode = YES;
} else if ([@"-freetype" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
freeType = YES;
} else if ([@"-externalupdater" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
externalUpdater = YES;
} else if ([@"-workdir_custom" isEqualToString:[NSString stringWithUTF8String:argv[i]]]) {
@@ -255,6 +257,7 @@ int main(int argc, const char * argv[]) {
if (_debug) [args addObject:@"-debug"];
if (startInTray) [args addObject:@"-startintray"];
if (testMode) [args addObject:@"-testmode"];
if (freeType) [args addObject:@"-freetype"];
if (externalUpdater) [args addObject:@"-externalupdater"];
if (autoStart) [args addObject:@"-autostart"];
if (key) {

View File

@@ -339,7 +339,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdPara
LPWSTR *args;
int argsCount;
bool needupdate = false, autostart = false, debug = false, writeprotected = false, startintray = false, testmode = false, externalupdater = false;
bool needupdate = false, autostart = false, debug = false, writeprotected = false, startintray = false, testmode = false, freetype = false, externalupdater = false;
args = CommandLineToArgvW(GetCommandLine(), &argsCount);
if (args) {
for (int i = 1; i < argsCount; ++i) {
@@ -355,6 +355,8 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdPara
startintray = true;
} else if (equal(args[i], L"-testmode")) {
testmode = true;
} else if (equal(args[i], L"-freetype")) {
freetype = true;
} else if (equal(args[i], L"-externalupdater")) {
externalupdater = true;
} else if (equal(args[i], L"-writeprotected") && ++i < argsCount) {
@@ -427,6 +429,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPWSTR cmdPara
if (debug) targs += L" -debug";
if (startintray) targs += L" -startintray";
if (testmode) targs += L" -testmode";
if (freetype) targs += L" -freetype";
if (externalupdater) targs += L" -externalupdater";
if (!customWorkingDir.empty()) {
targs += L" -workdir \"" + customWorkingDir + L"\"";

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"
@@ -30,6 +35,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Api {
namespace {
void InnerFillMessagePostFlags(
const Api::SendOptions &options,
not_null<PeerData*> peer,
MTPDmessage::Flags &flags) {
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
if (!channelPost) {
flags |= MTPDmessage::Flag::f_from_id;
return;
}
flags |= MTPDmessage::Flag::f_post;
// Don't display views and author of a new post when it's scheduled.
if (options.scheduled) {
return;
}
flags |= MTPDmessage::Flag::f_views;
if (peer->asChannel()->addsSignature()) {
flags |= MTPDmessage::Flag::f_post_author;
}
}
template <typename MediaData>
void SendExistingMedia(
Api::MessageToSend &&message,
@@ -60,15 +85,7 @@ void SendExistingMedia(
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
const auto silentPost = message.action.options.silent
|| (channelPost && session->data().notifySilentPosts(peer));
if (channelPost) {
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (!channelPost) {
flags |= MTPDmessage::Flag::f_from_id;
} else if (peer->asChannel()->addsSignature()) {
flags |= MTPDmessage::Flag::f_post_author;
}
InnerFillMessagePostFlags(message.action.options, peer, flags);
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
@@ -81,6 +98,7 @@ void SendExistingMedia(
};
TextUtilities::Trim(caption);
auto sentEntities = EntitiesToMTP(
session,
caption.entities,
ConvertOption::SkipLocal);
if (!sentEntities.v.isEmpty()) {
@@ -154,9 +172,7 @@ void SendExistingMedia(
};
performRequest();
if (const auto main = App::main()) {
main->finishForwarding(message.action);
}
api->finishForwarding(message.action);
}
} // namespace
@@ -177,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);
}
}
@@ -246,15 +259,7 @@ bool SendDice(Api::MessageToSend &message) {
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
const auto silentPost = message.action.options.silent
|| (channelPost && session->data().notifySilentPosts(peer));
if (channelPost) {
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (!channelPost) {
flags |= MTPDmessage::Flag::f_from_id;
} else if (peer->asChannel()->addsSignature()) {
flags |= MTPDmessage::Flag::f_post_author;
}
InnerFillMessagePostFlags(message.action.options, peer, flags);
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
@@ -317,7 +322,214 @@ bool SendDice(Api::MessageToSend &message) {
).send();
return history->sendRequestId;
});
api->finishForwarding(message.action);
return true;
}
void FillMessagePostFlags(
const Api::SendAction &action,
not_null<PeerData*> peer,
MTPDmessage::Flags &flags) {
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 {
@@ -25,4 +26,14 @@ void SendExistingPhoto(
bool SendDice(Api::MessageToSend &message);
void FillMessagePostFlags(
const SendAction &action,
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,14 +78,16 @@ 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
//&& entity.type() != EntityType::Semibold // Not in API.
&& entity.type() != EntityType::Italic
&& entity.type() != EntityType::Underline
&& entity.type() != EntityType::StrikeOut
@@ -102,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.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);
@@ -371,6 +373,7 @@ public:
return _sendActions.events();
}
void sendAction(const SendAction &action);
void finishForwarding(const SendAction &action);
void forwardMessages(
HistoryItemsList &&items,
const SendAction &action,
@@ -476,6 +479,10 @@ public:
void closePoll(not_null<HistoryItem*> item);
void reloadPollResults(not_null<HistoryItem*> item);
void rescheduleMessage(
not_null<HistoryItem*> item,
Api::SendOptions options);
private:
struct MessageDataRequest {
using Callbacks = QList<RequestMessageDataCallback>;
@@ -548,15 +555,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();
@@ -703,10 +701,6 @@ private:
base::flat_set<not_null<ChannelData*>> _selfParticipantRequests;
base::flat_map<
not_null<ChannelData*>,
mtpRequestId> _rangeDifferenceRequests;
QMap<WebPageData*, mtpRequestId> _webPagesPending;
base::Timer _webPagesTimer;
@@ -720,7 +714,7 @@ private:
base::Timer _draftsSaveTimer;
base::flat_set<mtpRequestId> _stickerSetDisenableRequests;
Stickers::Order _stickersOrder;
Data::StickersSetsOrder _stickersOrder;
mtpRequestId _stickersReorderRequestId = 0;
mtpRequestId _stickersClearRecentRequestId = 0;
@@ -852,8 +846,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();
}
@@ -227,8 +226,6 @@ namespace App {
clearCorners();
Data::clearGlobalStructures();
Images::ClearAll();
}
void hoveredItem(HistoryView::Element *item) {
@@ -322,6 +319,9 @@ namespace App {
}
QImage readImage(QByteArray data, QByteArray *format, bool opaque, bool *animated) {
if (data.isEmpty()) {
return QImage();
}
QByteArray tmpFormat;
QImage result;
QBuffer buffer(&data);

View File

@@ -11,23 +11,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/rect_part.h"
enum class ImageRoundRadius;
class MainWindow;
class MainWidget;
class HistoryItem;
class History;
namespace HistoryView {
class Element;
} // namespace HistoryView
namespace Media {
namespace Clip {
class Reader;
} // namespace Clip
} // namespace Media
using HistoryItemsMap = base::flat_set<not_null<HistoryItem*>>;
using GifItems = QHash<Media::Clip::Reader*, HistoryItem*>;
enum RoundCorners : int {
SmallMaskCorners = 0x00, // for images
LargeMaskCorners,

View File

@@ -34,10 +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"
@@ -117,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);
@@ -169,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);
@@ -189,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
@@ -222,6 +224,7 @@ private:
}
not_null<PeerData*> peer;
mutable std::shared_ptr<Data::CloudImageView> userpic;
Ui::Text::String name, status;
};
void paintChat(Painter &p, const ChatRow &row, bool selected) const;
@@ -451,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)) {
@@ -477,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,
@@ -493,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(); });
@@ -596,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(
@@ -748,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))
@@ -787,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() {
@@ -795,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(
@@ -814,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) {
@@ -948,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();
}
@@ -964,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);
}
}
@@ -1008,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();
}
}
@@ -1051,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();
@@ -1093,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();
@@ -1108,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() {
@@ -1140,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();
@@ -1155,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()) {
@@ -1246,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) {
@@ -1261,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(
@@ -1290,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)) {
@@ -1318,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));
@@ -1399,7 +1410,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);
@@ -1438,7 +1449,7 @@ void RevokePublicLinkBox::resizeEvent(QResizeEvent *e) {
void RevokePublicLinkBox::Inner::paintChat(Painter &p, const ChatRow &row, bool selected) const {
auto peer = row.peer;
peer->paintUserpicLeft(p, st::contactsPadding.left(), st::contactsPadding.top(), width(), st::contactsPhotoSize);
peer->paintUserpicLeft(p, row.userpic, st::contactsPadding.left(), st::contactsPadding.top(), width(), st::contactsPhotoSize);
p.setPen(st::contactsNameFg);

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

@@ -16,8 +16,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/sender.h"
#include "data/data_session.h"
#include "data/data_file_origin.h"
#include "data/data_document.h"
#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"
@@ -53,28 +56,33 @@ QImage TakeMiddleSample(QImage original, QSize size) {
} // namespace
class BackgroundBox::Inner : public Ui::RpWidget, private base::Subscriber {
class BackgroundBox::Inner final
: public Ui::RpWidget
, private base::Subscriber {
public:
Inner(
QWidget *parent,
not_null<Main::Session*> session);
~Inner();
rpl::producer<Data::WallPaper> chooseEvents() const;
rpl::producer<Data::WallPaper> removeRequests() const;
void removePaper(const Data::WallPaper &data);
~Inner();
protected:
private:
void paintEvent(QPaintEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
private:
void visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) override;
struct Paper {
Data::WallPaper data;
mutable std::shared_ptr<Data::DocumentMedia> dataMedia;
mutable QPixmap thumbnail;
};
struct Selected {
@@ -124,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() {
@@ -136,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());
@@ -154,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();
@@ -164,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();
@@ -183,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()) {
@@ -252,11 +262,19 @@ void BackgroundBox::Inner::resizeToContentAndPreload() {
const auto rows = (count / kBackgroundsInRow)
+ (count % kBackgroundsInRow ? 1 : 0);
resize(st::boxWideWidth, rows * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding);
resize(
st::boxWideWidth,
(rows * (st::backgroundSize.height() + st::backgroundPadding)
+ st::backgroundPadding));
const auto preload = kBackgroundsInRow * 3;
for (const auto &paper : _papers | ranges::view::take(preload)) {
paper.data.loadThumbnail();
if (!paper.data.localThumbnail() && !paper.dataMedia) {
if (const auto document = paper.data.document()) {
paper.dataMedia = document->createMediaView();
paper.dataMedia->thumbnailWanted(paper.data.fileOrigin());
}
}
}
update();
}
@@ -292,15 +310,24 @@ void BackgroundBox::Inner::paintEvent(QPaintEvent *e) {
void BackgroundBox::Inner::validatePaperThumbnail(
const Paper &paper) const {
Expects(paper.data.thumbnail() != nullptr);
const auto thumbnail = paper.data.thumbnail();
if (!paper.thumbnail.isNull()) {
return;
} else if (!thumbnail->loaded()) {
thumbnail->load(paper.data.fileOrigin());
return;
}
const auto localThumbnail = paper.data.localThumbnail();
if (!localThumbnail) {
if (const auto document = paper.data.document()) {
if (!paper.dataMedia) {
paper.dataMedia = document->createMediaView();
paper.dataMedia->thumbnailWanted(paper.data.fileOrigin());
}
}
if (!paper.dataMedia || !paper.dataMedia->thumbnail()) {
return;
}
}
const auto thumbnail = localThumbnail
? localThumbnail
: paper.dataMedia->thumbnail();
auto original = thumbnail->original();
if (paper.data.isPattern()) {
const auto color = *paper.data.backgroundColor();
@@ -428,7 +455,14 @@ void BackgroundBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
if (base::get_if<DeleteSelected>(&_over)) {
_backgroundRemove.fire_copy(_papers[index].data);
} else if (base::get_if<Selected>(&_over)) {
_backgroundChosen.fire_copy(_papers[index].data);
auto &paper = _papers[index];
if (!paper.dataMedia) {
if (const auto document = paper.data.document()) {
// Keep it alive while it is on the screen.
paper.dataMedia = document->createMediaView();
}
}
_backgroundChosen.fire_copy(paper.data);
}
}
} else if (!_over.has_value()) {
@@ -436,6 +470,22 @@ void BackgroundBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
}
}
void BackgroundBox::Inner::visibleTopBottomUpdated(
int visibleTop,
int visibleBottom) {
for (auto i = 0, count = int(_papers.size()); i != count; ++i) {
const auto row = (i / kBackgroundsInRow);
const auto height = st::backgroundSize.height();
const auto skip = st::backgroundPadding;
const auto top = skip + row * (height + skip);
const auto bottom = top + height;
if ((bottom <= visibleTop || top >= visibleBottom)
&& !_papers[i].thumbnail.isNull()) {
_papers[i].dataMedia = nullptr;
}
}
}
rpl::producer<Data::WallPaper> BackgroundBox::Inner::chooseEvents() const {
return _backgroundChosen.events();
}

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

@@ -22,9 +22,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "data/data_user.h"
#include "data/data_document.h"
#include "data/data_document_media.h"
#include "data/data_file_origin.h"
#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"
@@ -268,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(
@@ -394,24 +397,31 @@ 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))
, _paper(paper)
, _media(_paper.document() ? _paper.document()->createMediaView() : nullptr)
, _radial([=](crl::time now) { radialAnimationCallback(now); }) {
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
if (_media) {
_media->thumbnailWanted(_paper.fileOrigin());
}
subscribe(_controller->session().downloaderTaskFinished(), [=] {
update();
});
}
not_null<HistoryView::ElementDelegate*> BackgroundPreviewBox::delegate() {
@@ -428,12 +438,14 @@ void BackgroundPreviewBox::prepare() {
}
updateServiceBg(_paper.backgroundColor());
_paper.loadThumbnail();
_paper.loadDocument();
if (_paper.document() && _paper.document()->loading()) {
_radial.start(_paper.document()->progress());
const auto document = _paper.document();
if (document && document->loading()) {
_radial.start(_media->progress());
}
if (_paper.thumbnail() && !_paper.isPattern()) {
if (!_paper.isPattern()
&& (_paper.localThumbnail()
|| (document && document->hasThumbnail()))) {
createBlurCheckbox();
}
setScaledFromThumb();
@@ -492,10 +504,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();
}
@@ -503,7 +515,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));
}
@@ -634,7 +647,7 @@ void BackgroundPreviewBox::radialAnimationCallback(crl::time now) {
const auto document = _paper.document();
const auto wasAnimating = _radial.animating();
const auto updated = _radial.update(
document->progress(),
_media->progress(),
!document->loading(),
now);
if ((wasAnimating || _radial.animating())
@@ -645,8 +658,13 @@ void BackgroundPreviewBox::radialAnimationCallback(crl::time now) {
}
bool BackgroundPreviewBox::setScaledFromThumb() {
const auto thumbnail = _paper.thumbnail();
if (!thumbnail || !thumbnail->loaded()) {
const auto localThumbnail = _paper.localThumbnail();
const auto thumbnail = localThumbnail
? localThumbnail
: _media
? _media->thumbnail()
: nullptr;
if (!thumbnail) {
return false;
} else if (_paper.isPattern() && _paper.document() != nullptr) {
return false;
@@ -710,7 +728,7 @@ void BackgroundPreviewBox::checkLoadedDocument() {
const auto document = _paper.document();
if (!_full.isNull()
|| !document
|| !document->loaded(DocumentData::FilePathResolve::Checked)
|| !_media->loaded(true)
|| _generating) {
return;
}
@@ -744,18 +762,18 @@ void BackgroundPreviewBox::checkLoadedDocument() {
});
};
_generating = Data::ReadImageAsync(
document,
_media.get(),
Window::Theme::ProcessBackgroundImage,
generateCallback);
}
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;
}
@@ -763,9 +781,10 @@ 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, [=](
const Data::WallPaper &result) {
Ui::show(Box<BackgroundPreviewBox>(
session,
controller,
result.withUrlParams(params)));
}, [](const RPCError &error) {
Ui::show(Box<InformBox>(tr::lng_background_bad_link(tr::now)));

View File

@@ -15,9 +15,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/animations.h"
#include "ui/effects/radial_animation.h"
namespace Main {
class Session;
} // namespace Main
namespace Data {
class DocumentMedia;
} // namespace Data
namespace Window {
class SessionController;
} // namespace Window
namespace Ui {
class Checkbox;
@@ -30,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);
@@ -67,10 +71,11 @@ 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;
std::shared_ptr<Data::DocumentMedia> _media;
QImage _full;
QPixmap _scaled, _blurred, _fadeOutThumbnail;
Ui::Animations::Simple _fadeIn;

View File

@@ -915,7 +915,7 @@ blockUserConfirmation: FlatLabel(boxLabel) {
minWidth: 240px;
}
transferCheckWidth: 300px;
transferCheckWidth: 320px;
slowmodeLabelsMargin: margins(0px, 5px, 0px, 0px);
slowmodeLabel: LabelSimple(defaultLabelSimple) {

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,
@@ -599,4 +598,19 @@ void CalendarBox::keyPressEvent(QKeyEvent *e) {
}
}
void CalendarBox::wheelEvent(QWheelEvent *e) {
// Only a mouse wheel is accepted.
constexpr auto step = static_cast<int>(QWheelEvent::DefaultDeltasPerStep);
const auto delta = e->angleDelta().y();
if (std::abs(delta) != step) {
return;
}
if (delta < 0) {
goPreviousMonth();
} else {
goNextMonth();
}
}
CalendarBox::~CalendarBox() = default;

View File

@@ -46,6 +46,7 @@ protected:
void keyPressEvent(QKeyEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void wheelEvent(QWheelEvent *e) override;
private:
void monthChanged(QDate month);

View File

@@ -19,6 +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/sender.h"
#include "apiwrap.h"
#include "app.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
@@ -75,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 };
@@ -111,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());
@@ -119,6 +122,7 @@ private:
int countHeight();
const not_null<Main::Session*> _session;
MTP::Sender _api;
QString _phone;
QString _hash;
@@ -135,7 +139,8 @@ private:
ChangePhoneBox::EnterPhone::EnterPhone(
QWidget*,
not_null<Main::Session*> session)
: _session(session) {
: _session(session)
, _api(&session->mtp()) {
}
void ChangePhoneBox::EnterPhone::prepare() {
@@ -170,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;
@@ -218,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(
@@ -237,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) {
@@ -260,6 +257,7 @@ ChangePhoneBox::EnterCode::EnterCode(
int codeLength,
int callTimeout)
: _session(session)
, _api(&session->mtp())
, _phone(phone)
, _hash(hash)
, _codeLength(codeLength)
@@ -312,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() {
@@ -353,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

@@ -32,10 +32,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h"
#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"
@@ -350,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()
@@ -366,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) {
@@ -431,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) {
}
@@ -473,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(
@@ -682,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
@@ -774,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.
@@ -846,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();
}
@@ -894,12 +888,12 @@ ConfirmInviteBox::ConfirmInviteBox(
const auto photo = _session->data().processPhoto(data.vphoto());
if (!photo->isNull()) {
_photo = photo->thumbnail();
if (!_photo->loaded()) {
_photo = photo->createMediaView();
_photo->wanted(Data::PhotoSize::Small, Data::FileOrigin());
if (!_photo->image(Data::PhotoSize::Small)) {
subscribe(_session->downloaderTaskFinished(), [=] {
update();
});
_photo->load(Data::FileOrigin());
}
} else {
_photoEmpty = std::make_unique<Ui::EmptyUserpic>(
@@ -908,19 +902,20 @@ ConfirmInviteBox::ConfirmInviteBox(
}
}
std::vector<not_null<UserData*>> ConfirmInviteBox::GetParticipants(
not_null<Main::Session*> session,
const MTPDchatInvite &data) {
auto ConfirmInviteBox::GetParticipants(
not_null<Main::Session*> session,
const MTPDchatInvite &data)
-> std::vector<Participant> {
const auto participants = data.vparticipants();
if (!participants) {
return {};
}
const auto &v = participants->v;
auto result = std::vector<not_null<UserData*>>();
auto result = std::vector<Participant>();
result.reserve(v.size());
for (const auto &participant : v) {
if (const auto user = session->data().processUser(participant)) {
result.push_back(user);
result.push_back(Participant{ user });
}
}
return result;
@@ -945,12 +940,12 @@ void ConfirmInviteBox::prepare() {
_userWidth = (st::confirmInviteUserPhotoSize + 2 * padding);
int sumWidth = _participants.size() * _userWidth;
int left = (st::boxWideWidth - sumWidth) / 2;
for (const auto user : _participants) {
for (const auto &participant : _participants) {
auto name = new Ui::FlatLabel(this, st::confirmInviteUserName);
name->resizeToWidth(st::confirmInviteUserPhotoSize + padding);
name->setText(user->firstName.isEmpty()
? user->name
: user->firstName);
name->setText(participant.user->firstName.isEmpty()
? participant.user->name
: participant.user->firstName);
name->moveToLeft(left + (padding / 2), st::confirmInviteUserNameTop);
left += _userWidth;
}
@@ -972,14 +967,15 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) {
Painter p(this);
if (_photo) {
p.drawPixmap(
(width() - st::confirmInvitePhotoSize) / 2,
st::confirmInvitePhotoTop,
_photo->pixCircled(
Data::FileOrigin(),
st::confirmInvitePhotoSize,
st::confirmInvitePhotoSize));
} else {
if (const auto image = _photo->image(Data::PhotoSize::Small)) {
p.drawPixmap(
(width() - st::confirmInvitePhotoSize) / 2,
st::confirmInvitePhotoTop,
image->pixCircled(
st::confirmInvitePhotoSize,
st::confirmInvitePhotoSize));
}
} else if (_photoEmpty) {
_photoEmpty->paint(
p,
(width() - st::confirmInvitePhotoSize) / 2,
@@ -990,9 +986,10 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) {
int sumWidth = _participants.size() * _userWidth;
int left = (width() - sumWidth) / 2;
for_const (auto user, _participants) {
user->paintUserpicLeft(
for (auto &participant : _participants) {
participant.user->paintUserpicLeft(
p,
participant.userpic,
left + (_userWidth - st::confirmInviteUserPhotoSize) / 2,
st::confirmInviteUserPhotoTop,
width(),

View File

@@ -8,7 +8,12 @@ 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;
class CloudImageView;
} // namespace Data
namespace Main {
class Session;
@@ -124,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);
@@ -136,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;
@@ -149,7 +153,7 @@ private:
};
class DeleteMessagesBox : public Ui::BoxContent, public RPCSender {
class DeleteMessagesBox final : public Ui::BoxContent {
public:
DeleteMessagesBox(
QWidget*,
@@ -202,9 +206,8 @@ private:
};
class ConfirmInviteBox
class ConfirmInviteBox final
: public Ui::BoxContent
, public RPCSender
, private base::Subscriber {
public:
ConfirmInviteBox(
@@ -221,7 +224,11 @@ protected:
void paintEvent(QPaintEvent *e) override;
private:
static std::vector<not_null<UserData*>> GetParticipants(
struct Participant {
not_null<UserData*> user;
std::shared_ptr<Data::CloudImageView> userpic;
};
static std::vector<Participant> GetParticipants(
not_null<Main::Session*> session,
const MTPDchatInvite &data);
@@ -230,9 +237,9 @@ private:
Fn<void()> _submit;
object_ptr<Ui::FlatLabel> _title;
object_ptr<Ui::FlatLabel> _status;
Image *_photo = nullptr;
std::shared_ptr<Data::PhotoMedia> _photo;
std::unique_ptr<Ui::EmptyUserpic> _photoEmpty;
std::vector<not_null<UserData*>> _participants;
std::vector<Participant> _participants;
bool _isChannel = false;
int _userWidth = 0;

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

@@ -978,8 +978,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 +1028,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 +1059,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 +1082,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 +1143,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 +1374,7 @@ void ProxiesBoxController::setTryIPv6(bool enabled) {
return;
}
Global::SetTryIPv6(enabled);
MTP::restart();
_account->mtp().restart();
Global::RefConnectionTypeChanged().notify();
saveDelayed();
}
@@ -1404,7 +1406,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"
@@ -83,7 +86,7 @@ private:
void show(anim::type animated);
void destroy(FnMut<void()> done);
[[nodisacrd]] bool hasShadow() const;
[[nodiscard]] bool hasShadow() const;
void createShadow();
void destroyShadow();
@@ -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,22 +246,15 @@ 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)
)
)
);
@@ -267,10 +268,7 @@ auto AddButtonWithLoader(
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"
@@ -22,13 +24,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_photo.h"
#include "data/data_user.h"
#include "data/data_session.h"
#include "data/data_streaming.h"
#include "data/data_file_origin.h"
#include "data/data_photo_media.h"
#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/clip/media_clip_reader.h"
#include "media/streaming/media_streaming_instance.h"
#include "media/streaming/media_streaming_player.h"
#include "media/streaming/media_streaming_document.h"
#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"
@@ -37,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"
@@ -46,11 +58,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtCore/QMimeData>
namespace {
using namespace ::Media::Streaming;
using Data::PhotoSize;
} // namespace
EditCaptionBox::EditCaptionBox(
QWidget*,
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());
@@ -58,45 +78,67 @@ EditCaptionBox::EditCaptionBox(
_isAllowedEditMedia = item->media()->allowsEditMedia();
_isAlbum = !item->groupId().empty();
QSize dimensions;
auto image = (Image*)nullptr;
DocumentData *doc = nullptr;
auto dimensions = QSize();
const auto media = item->media();
if (const auto photo = media->photo()) {
_photoMedia = photo->createMediaView();
_photoMedia->wanted(PhotoSize::Large, _msgId);
dimensions = _photoMedia->size(PhotoSize::Large);
if (dimensions.isEmpty()) {
dimensions = QSize(1, 1);
}
_photo = true;
dimensions = QSize(photo->width(), photo->height());
image = photo->large();
} else if (const auto document = media->document()) {
image = document->thumbnail();
dimensions = image
? image->size()
_documentMedia = document->createMediaView();
_documentMedia->thumbnailWanted(_msgId);
dimensions = _documentMedia->thumbnail()
? _documentMedia->thumbnail()->size()
: document->dimensions;
if (document->isAnimation()) {
_gifw = document->dimensions.width();
_gifh = document->dimensions.height();
_gifw = style::ConvertScale(document->dimensions.width());
_gifh = style::ConvertScale(document->dimensions.height());
_animated = true;
} else if (document->isVideoFile()) {
_animated = true;
} else {
_doc = true;
}
doc = document;
} else {
Unexpected("Photo or document should be set.");
}
const auto editData = PrepareEditText(item);
if (!_animated && (dimensions.isEmpty() || doc || !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
@@ -104,30 +146,28 @@ EditCaptionBox::EditCaptionBox(
| Images::Option::RoundedBottomLeft
| Images::Option::RoundedBottomRight;
_thumb = App::pixmapFromImageInPlace(Images::prepare(
image->pix(_msgId).toImage(),
image->original(),
_thumbw * cIntRetinaFactor(),
0,
options,
st::msgFileThumbSize,
st::msgFileThumbSize));
_thumbnailImageLoaded = true;
};
}
if (doc) {
const auto nameString = doc->isVoiceMessage()
? tr::lng_media_audio(tr::now)
: doc->composeNameString();
setName(nameString, doc->size);
_isImage = doc->isImage();
_isAudio = (doc->isVoiceMessage() || doc->isAudioFile());
}
if (_refreshThumbnail) {
_refreshThumbnail();
}
} else {
if (!image) {
image = Image::BlankMedia();
if (_documentMedia) {
const auto document = _documentMedia->owner();
const auto nameString = document->isVoiceMessage()
? tr::lng_media_audio(tr::now)
: document->composeNameString();
setName(nameString, document->size);
_isImage = document->isImage();
_isAudio = document->isVoiceMessage()
|| document->isAudioFile();
}
} else {
auto maxW = 0, maxH = 0;
const auto limitW = st::sendMediaPreviewSize;
auto limitH = std::min(st::confirmMaxHeight, _gifh ? _gifh : INT_MAX);
@@ -145,29 +185,41 @@ 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(
_msgId,
_thumb = use->pixNoCache(
maxW * cIntRetinaFactor(),
maxH * cIntRetinaFactor(),
options,
maxW,
maxH);
_thumbnailImageLoaded = true;
};
prepareGifPreview(doc);
} else {
Assert(_photoMedia != nullptr);
maxW = dimensions.width();
maxH = dimensions.height();
_thumbnailImage = image;
_refreshThumbnail = [=] {
_thumb = image->pixNoCache(
_msgId,
const auto image = computeImage();
const auto photo = _photoMedia->image(Data::PhotoSize::Large);
const auto use = photo
? photo
: image
? image
: Image::BlankMedia().get();
const auto options = Images::Option::Smooth
| (photo
? Images::Option(0)
: Images::Option::Blurred);
_thumbnailImageLoaded = (photo != nullptr);
_thumb = use->pixNoCache(
maxW * cIntRetinaFactor(),
maxH * cIntRetinaFactor(),
Images::Option::Smooth,
options,
maxW,
maxH);
};
@@ -205,7 +257,7 @@ EditCaptionBox::EditCaptionBox(
thumbX = (st::boxWideWidth - thumbWidth) / 2;
};
if (doc && doc->isAnimation()) {
if (_documentMedia && _documentMedia->owner()->isAnimation()) {
resizeDimensions(_gifw, _gifh, _gifx);
}
limitH = std::min(st::confirmMaxHeight, _gifh ? _gifh : INT_MAX);
@@ -236,39 +288,37 @@ EditCaptionBox::EditCaptionBox(
scaleThumbDown();
}
Assert(_animated || _photo || _doc);
Assert(_thumbnailImageLoaded || _refreshThumbnail);
_thumbnailImageLoaded = _thumbnailImage
? _thumbnailImage->loaded()
: true;
subscribe(_controller->session().downloaderTaskFinished(), [=] {
if (!_thumbnailImageLoaded
&& _thumbnailImage
&& _thumbnailImage->loaded()) {
_thumbnailImageLoaded = true;
if (!_thumbnailImageLoaded) {
subscribe(_controller->session().downloaderTaskFinished(), [=] {
if (_thumbnailImageLoaded
|| (_photoMedia && !_photoMedia->image(PhotoSize::Large))
|| (_documentMedia && !_documentMedia->thumbnail())) {
return;
}
_refreshThumbnail();
update();
}
if (doc && doc->isAnimation() && doc->loaded() && !_gifPreview) {
prepareGifPreview(doc);
}
});
});
}
_field.create(
this,
st::confirmCaptionArea,
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,
@@ -287,6 +337,8 @@ EditCaptionBox::EditCaptionBox(
}, _wayWrap->lifetime());
}
EditCaptionBox::~EditCaptionBox() = default;
void EditCaptionBox::emojiFilterForGeometry(not_null<QEvent*> event) {
const auto type = event->type();
if (type == QEvent::Move || type == QEvent::Resize) {
@@ -305,74 +357,86 @@ void EditCaptionBox::updateEmojiPanelGeometry() {
local.x() + _emojiToggle->width() * 3);
}
void EditCaptionBox::prepareGifPreview(DocumentData* document) {
void EditCaptionBox::prepareStreamedPreview() {
const auto isListEmpty = _preparedList.files.empty();
if (_gifPreview) {
if (_streamed) {
return;
} else if (!document && isListEmpty) {
} else if (!_documentMedia && isListEmpty) {
return;
}
const auto callback = [=](Media::Clip::Notification notification) {
clipCallback(notification);
};
if (document && document->isAnimation() && document->loaded()) {
_gifPreview = Media::Clip::MakeReader(
document,
_msgId,
callback);
const auto document = _documentMedia
? _documentMedia->owner().get()
: nullptr;
if (document && document->isAnimation()) {
setupStreamedPreview(
document->owner().streaming().sharedDocument(
document,
_msgId));
} else if (!isListEmpty) {
const auto file = &_preparedList.files.front();
if (file->path.isEmpty()) {
_gifPreview = Media::Clip::MakeReader(
file->content,
callback);
} else {
_gifPreview = Media::Clip::MakeReader(
file->path,
callback);
}
auto loader = file->path.isEmpty()
? MakeBytesLoader(file->content)
: MakeFileLoader(file->path);
setupStreamedPreview(std::make_shared<Document>(std::move(loader)));
}
if (_gifPreview) _gifPreview->setAutoplay();
}
void EditCaptionBox::clipCallback(Media::Clip::Notification notification) {
using namespace Media::Clip;
switch (notification) {
case NotificationReinit: {
if (_gifPreview && _gifPreview->state() == State::Error) {
_gifPreview.setBad();
}
void EditCaptionBox::setupStreamedPreview(std::shared_ptr<Document> shared) {
if (!shared) {
return;
}
_streamed = std::make_unique<Instance>(
std::move(shared),
[=] { update(); });
_streamed->lockPlayer();
_streamed->player().updates(
) | rpl::start_with_next_error([=](Update &&update) {
handleStreamingUpdate(std::move(update));
}, [=](Error &&error) {
handleStreamingError(std::move(error));
}, _streamed->lifetime());
if (_gifPreview && _gifPreview->ready() && !_gifPreview->started()) {
const auto calculateGifDimensions = [&]() {
const auto scaled = QSize(
_gifPreview->width(),
_gifPreview->height()).scaled(
st::sendMediaPreviewSize * cIntRetinaFactor(),
st::confirmMaxHeight * cIntRetinaFactor(),
Qt::KeepAspectRatio);
_thumbw = _gifw = scaled.width();
_thumbh = _gifh = scaled.height();
_thumbx = _gifx = (st::boxWideWidth - _gifw) / 2;
updateBoxSize();
};
// If gif file is not mp4,
// Its dimension values will be known only after reading.
if (_gifw <= 0 || _gifh <= 0) {
calculateGifDimensions();
}
const auto s = QSize(_gifw, _gifh);
_gifPreview->start(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, RectPart::None);
}
if (_streamed->ready()) {
streamingReady(base::duplicate(_streamed->info()));
}
checkStreamedIsStarted();
}
update();
} break;
void EditCaptionBox::handleStreamingUpdate(Update &&update) {
update.data.match([&](Information &update) {
streamingReady(std::move(update));
}, [&](const PreloadedVideo &update) {
}, [&](const UpdateVideo &update) {
this->update();
}, [&](const PreloadedAudio &update) {
}, [&](const UpdateAudio &update) {
}, [&](const WaitingForData &update) {
}, [&](MutedByOther) {
}, [&](Finished) {
});
}
case NotificationRepaint: {
if (_gifPreview && !_gifPreview->currentDisplayed()) {
update();
}
} break;
void EditCaptionBox::handleStreamingError(Error &&error) {
}
void EditCaptionBox::streamingReady(Information &&info) {
const auto calculateGifDimensions = [&]() {
const auto scaled = QSize(
info.video.size.width(),
info.video.size.height()
).scaled(
st::sendMediaPreviewSize * cIntRetinaFactor(),
st::confirmMaxHeight * cIntRetinaFactor(),
Qt::KeepAspectRatio);
_thumbw = _gifw = scaled.width();
_thumbh = _gifh = scaled.height();
_thumbx = _gifx = (st::boxWideWidth - _gifw) / 2;
updateBoxSize();
};
// If gif file is not mp4,
// Its dimension values will be known only after reading.
if (_gifw <= 0 || _gifh <= 0) {
calculateGifDimensions();
}
}
@@ -390,7 +454,7 @@ void EditCaptionBox::updateEditPreview() {
_animated = false;
_photo = false;
_doc = false;
_gifPreview = nullptr;
_streamed = nullptr;
_thumbw = _thumbh = _thumbx = 0;
_gifw = _gifh = _gifx = 0;
@@ -469,7 +533,7 @@ void EditCaptionBox::updateEditPreview() {
_gifw = _thumbw;
_gifh = _thumbh;
_gifx = _thumbx;
prepareGifPreview();
prepareStreamedPreview();
}
}
updateEditMediaButton();
@@ -530,6 +594,10 @@ void EditCaptionBox::createEditMediaButton() {
}
void EditCaptionBox::prepare() {
if (_animated) {
prepareStreamedPreview();
}
addButton(tr::lng_settings_save(), [this] { save(); });
if (_isAllowedEditMedia) {
createEditMediaButton();
@@ -551,10 +619,7 @@ void EditCaptionBox::prepare() {
} else if (data->hasImage()) {
return true;
} else if (const auto urls = data->urls(); !urls.empty()) {
if (ranges::find_if(
urls,
[](const QUrl &url) { return !url.isLocalFile(); }
) == urls.end()) {
if (ranges::all_of(urls, &QUrl::isLocalFile)) {
return true;
}
}
@@ -599,7 +664,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;
@@ -687,6 +755,31 @@ int EditCaptionBox::errorTopSkip() const {
return (st::defaultBox.buttonPadding.top() / 2);
}
void EditCaptionBox::checkStreamedIsStarted() {
if (!_streamed) {
return;
}
if (_streamed->paused()) {
_streamed->resume();
}
if (!_streamed->active() && !_streamed->failed()) {
startStreamedPlayer();
}
}
void EditCaptionBox::startStreamedPlayer() {
auto options = ::Media::Streaming::PlaybackOptions();
options.audioId = _documentMedia
? AudioMsgId(_documentMedia->owner(), _msgId)
: AudioMsgId();
options.waitForMarkAsShown = true;
//if (!_streamed->withSound) {
options.mode = ::Media::Streaming::Mode::Video;
options.loop = true;
//}
_streamed->play(options);
}
void EditCaptionBox::paintEvent(QPaintEvent *e) {
BoxContent::paintEvent(e);
@@ -700,16 +793,27 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) {
if (_thumbx + _thumbw < width() - st::boxPhotoPadding.right()) {
p.fillRect(_thumbx + _thumbw, st::boxPhotoPadding.top(), width() - st::boxPhotoPadding.right() - _thumbx - _thumbw, th, st::confirmBg);
}
if (_gifPreview && _gifPreview->started()) {
checkStreamedIsStarted();
if (_streamed
&& _streamed->player().ready()
&& !_streamed->player().videoSize().isEmpty()) {
const auto s = QSize(_gifw, _gifh);
const auto paused = _controller->isGifPausedAtLeastFor(Window::GifPauseReason::Layer);
const auto frame = _gifPreview->current(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None, RectPart::None, paused ? 0 : crl::now());
p.drawPixmap(_gifx, st::boxPhotoPadding.top(), frame);
auto request = ::Media::Streaming::FrameRequest();
request.outer = s * cIntRetinaFactor();
request.resize = s * cIntRetinaFactor();
p.drawImage(
QRect(_gifx, st::boxPhotoPadding.top(), _gifw, _gifh),
_streamed->frame(request));
if (!paused) {
_streamed->markFrameShown();
}
} else {
const auto offset = _gifh ? ((_gifh - _thumbh) / 2) : 0;
p.drawPixmap(_thumbx, st::boxPhotoPadding.top() + offset, _thumb);
}
if (_animated && !_gifPreview) {
if (_animated && !_streamed) {
QRect inner(_thumbx + (_thumbw - st::msgFileSize) / 2, st::boxPhotoPadding.top() + (th - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
p.setPen(Qt::NoPen);
p.setBrush(st::msgDateImgBg);
@@ -841,6 +945,7 @@ void EditCaptionBox::save() {
TextUtilities::Trim(sending);
const auto sentEntities = Api::EntitiesToMTP(
&item->history()->session(),
sending.entities,
Api::ConvertOption::SkipLocal);
if (!sentEntities.v.isEmpty()) {
@@ -865,18 +970,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) {
@@ -886,26 +993,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,8 +10,9 @@ 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 "media/clip/media_clip_reader.h"
#include "mtproto/mtproto_rpc_sender.h"
#include "mtproto/sender.h"
class Image;
namespace ChatHelpers {
class TabbedPanel;
@@ -23,6 +24,8 @@ class SessionController;
namespace Data {
class Media;
class PhotoMedia;
class DocumentMedia;
} // namespace Data
namespace Ui {
@@ -36,15 +39,23 @@ namespace Window {
class SessionController;
} // namespace Window
class EditCaptionBox
: public Ui::BoxContent
, public RPCSender
, private base::Subscriber {
namespace Media {
namespace Streaming {
class Instance;
class Document;
struct Update;
enum class Error;
struct Information;
} // namespace Streaming
} // namespace Media
class EditCaptionBox final : public Ui::BoxContent, private base::Subscriber {
public:
EditCaptionBox(
QWidget*,
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item);
~EditCaptionBox();
protected:
void prepare() override;
@@ -56,8 +67,14 @@ protected:
private:
void updateBoxSize();
void prepareGifPreview(DocumentData* document = nullptr);
void clipCallback(Media::Clip::Notification notification);
void prepareStreamedPreview();
void checkStreamedIsStarted();
void setupStreamedPreview(
std::shared_ptr<::Media::Streaming::Document> shared);
void handleStreamingUpdate(::Media::Streaming::Update &&update);
void handleStreamingError(::Media::Streaming::Error &&error);
void streamingReady(::Media::Streaming::Information &&info);
void startStreamedPlayer();
void setupEmojiPanel();
void updateEmojiPanelGeometry();
@@ -67,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);
@@ -84,9 +101,12 @@ private:
: _preparedList.files.front().path;
}
not_null<Window::SessionController*> _controller;
const not_null<Window::SessionController*> _controller;
MTP::Sender _api;
FullMsgId _msgId;
Image *_thumbnailImage = nullptr;
std::shared_ptr<Data::PhotoMedia> _photoMedia;
std::shared_ptr<Data::DocumentMedia> _documentMedia;
bool _thumbnailImageLoaded = false;
Fn<void()> _refreshThumbnail;
bool _animated = false;
@@ -94,7 +114,7 @@ private:
bool _doc = false;
QPixmap _thumb;
Media::Clip::ReaderPointer _gifPreview;
std::unique_ptr<::Media::Streaming::Instance> _streamed;
object_ptr<Ui::InputField> _field = { nullptr };
object_ptr<Ui::EmojiButton> _emojiToggle = { nullptr };

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"
@@ -78,6 +80,7 @@ private:
};
struct PeerButton {
not_null<History*> history;
std::shared_ptr<Data::CloudImageView> userpic;
Button button;
};
@@ -184,9 +187,10 @@ void FilterChatsPreview::updateData(
}
}
for (const auto history : peers) {
_removePeer.push_back({
history,
makeButton([=] { removePeer(history); }) });
_removePeer.push_back(PeerButton{
.history = history,
.button = makeButton([=] { removePeer(history); })
});
}
refresh();
}
@@ -203,7 +207,7 @@ int FilterChatsPreview::resizeGetHeight(int newWidth) {
for (const auto &[flag, button] : _removeFlag) {
moveNextButton(button.get());
}
for (const auto &[history, button] : _removePeer) {
for (const auto &[history, userpic, button] : _removePeer) {
moveNextButton(button.get());
}
return top;
@@ -235,7 +239,7 @@ void FilterChatsPreview::paintEvent(QPaintEvent *e) {
FilterChatsTypeName(flag));
top += st.height;
}
for (const auto &[history, button] : _removePeer) {
for (auto &[history, userpic, button] : _removePeer) {
const auto savedMessages = history->peer->isSelf();
if (savedMessages) {
Ui::EmptyUserpic::PaintSavedMessages(
@@ -253,6 +257,7 @@ void FilterChatsPreview::paintEvent(QPaintEvent *e) {
} else {
history->peer->paintUserpicLeft(
p,
userpic,
iconLeft,
top + iconTop,
width(),
@@ -497,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

@@ -180,11 +180,12 @@ QString ExceptionRow::generateShortName() {
PaintRoundImageCallback ExceptionRow::generatePaintUserpicCallback() {
const auto peer = this->peer();
const auto saved = peer->isSelf();
return [=](Painter &p, int x, int y, int outerWidth, int size) {
auto userpic = saved ? nullptr : ensureUserpicView();
return [=](Painter &p, int x, int y, int outerWidth, int size) mutable {
if (saved) {
Ui::EmptyUserpic::PaintSavedMessages(p, x, y, outerWidth, size);
} else {
peer->paintUserpicLeft(p, x, y, outerWidth, size);
peer->paintUserpicLeft(p, userpic, x, y, outerWidth, size);
}
};
}

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"
@@ -41,8 +41,9 @@ PaintRoundImageCallback PaintUserpicCallback(
Ui::EmptyUserpic::PaintSavedMessages(p, x, y, outerWidth, size);
};
}
return [=](Painter &p, int x, int y, int outerWidth, int size) {
peer->paintUserpicLeft(p, x, y, outerWidth, size);
auto userpic = std::shared_ptr<Data::CloudImageView>();
return [=](Painter &p, int x, int y, int outerWidth, int size) mutable {
peer->paintUserpicLeft(p, userpic, x, y, outerWidth, size);
};
}
@@ -483,14 +484,22 @@ QString PeerListRow::generateShortName() {
: peer()->shortName();
}
std::shared_ptr<Data::CloudImageView> PeerListRow::ensureUserpicView() {
if (!_userpic) {
_userpic = peer()->createUserpicView();
}
return _userpic;
}
PaintRoundImageCallback PeerListRow::generatePaintUserpicCallback() {
const auto saved = _isSavedMessagesChat;
const auto peer = this->peer();
return [=](Painter &p, int x, int y, int outerWidth, int size) {
auto userpic = saved ? nullptr : ensureUserpicView();
return [=](Painter &p, int x, int y, int outerWidth, int size) mutable {
if (saved) {
Ui::EmptyUserpic::PaintSavedMessages(p, x, y, outerWidth, size);
} else {
peer->paintUserpicLeft(p, x, y, outerWidth, size);
peer->paintUserpicLeft(p, userpic, x, y, outerWidth, size);
}
};
}
@@ -595,7 +604,7 @@ void PeerListRow::paintDisabledCheckUserpic(
if (_isSavedMessagesChat) {
Ui::EmptyUserpic::PaintSavedMessages(p, userpicLeft, userpicTop, outerWidth, userpicRadius * 2);
} else {
peer()->paintUserpicLeft(p, userpicLeft, userpicTop, outerWidth, userpicRadius * 2);
peer()->paintUserpicLeft(p, _userpic, userpicLeft, userpicTop, outerWidth, userpicRadius * 2);
}
{
@@ -657,15 +666,18 @@ PeerListContent::PeerListContent(
update();
});
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();
@@ -1708,8 +1720,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

@@ -7,11 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <rpl/event_stream.h>
#include "ui/rp_widget.h"
#include "ui/empty_userpic.h"
#include "boxes/abstract_box.h"
#include "mtproto/sender.h"
#include "data/data_cloud_file.h"
#include "base/timer.h"
namespace style {
@@ -34,10 +34,6 @@ struct ScrollToRequest;
class PopupMenu;
} // namespace Ui
namespace Notify {
struct PeerUpdate;
} // namespace Notify
using PaintRoundImageCallback = Fn<void(
Painter &p,
int x,
@@ -85,6 +81,8 @@ public:
return _id;
}
[[nodiscard]] std::shared_ptr<Data::CloudImageView> ensureUserpicView();
[[nodiscard]] virtual QString generateName();
[[nodiscard]] virtual QString generateShortName();
[[nodiscard]] virtual auto generatePaintUserpicCallback()
@@ -223,6 +221,7 @@ private:
PeerListRowId _id = 0;
PeerData *_peer = nullptr;
mutable std::shared_ptr<Data::CloudImageView> _userpic;
std::unique_ptr<Ui::RippleAnimation> _ripple;
std::unique_ptr<Ui::RoundImageCheckbox> _checkbox;
Ui::Text::String _name;
@@ -548,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(); });
}
@@ -584,5 +583,9 @@ void ChooseRecipientBoxController::rowClicked(not_null<PeerListRow*> row) {
auto ChooseRecipientBoxController::createRow(
not_null<History*> history) -> std::unique_ptr<Row> {
return std::make_unique<Row>(history);
const auto peer = history->peer;
const auto skip = peer->isChannel()
&& !peer->isMegagroup()
&& !peer->canWrite();
return skip ? nullptr : std::make_unique<Row>(history);
}

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);
}
}
}
@@ -354,6 +353,16 @@ bool ParticipantsAdditionalData::canRestrictUser(
Unexpected("Peer in ParticipantsAdditionalData::canRestrictUser.");
}
bool ParticipantsAdditionalData::canRemoveUser(
not_null<UserData*> user) const {
if (canRestrictUser(user)) {
return true;
} else if (const auto chat = _peer->asChat()) {
return chat->invitedByMe.contains(user);
}
return false;
}
auto ParticipantsAdditionalData::adminRights(
not_null<UserData*> user) const
-> std::optional<MTPChatAdminRights> {
@@ -676,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();
}
@@ -700,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;
}
@@ -745,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();
@@ -837,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()
@@ -917,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);
@@ -975,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()) {
@@ -1094,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) {
@@ -1436,6 +1443,8 @@ base::unique_qptr<Ui::PopupMenu> ParticipantsBoxController::rowContextMenu(
tr::lng_context_restrict_user(tr::now),
crl::guard(this, [=] { showRestricted(user); }));
}
}
if (_additional.canRemoveUser(user)) {
if (!_additional.isKicked(user)) {
const auto isGroup = _peer->isChat() || _peer->isMegagroup();
result->addAction(
@@ -1806,7 +1815,7 @@ auto ParticipantsBoxController::computeType(
: _additional.adminRights(user).has_value()
? Rights::Admin
: Rights::Normal;
result.canRemove = _additional.canRestrictUser(user);
result.canRemove = _additional.canRemoveUser(user);
return result;
}
@@ -1881,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()) {
@@ -1916,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;
};
@@ -88,6 +89,7 @@ public:
[[nodiscard]] bool canEditAdmin(not_null<UserData*> user) const;
[[nodiscard]] bool canAddOrEditAdmin(not_null<UserData*> user) const;
[[nodiscard]] bool canRestrictUser(not_null<UserData*> user) const;
[[nodiscard]] bool canRemoveUser(not_null<UserData*> user) const;
[[nodiscard]] std::optional<MTPChatAdminRights> adminRights(
not_null<UserData*> user) const;
QString adminRank(not_null<UserData*> user) const;

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) {
@@ -888,7 +890,6 @@ void SingleMediaPreview::prepareAnimatedPreview(
_gifPreview = Media::Clip::MakeReader(
animatedPreviewPath,
std::move(callback));
if (_gifPreview) _gifPreview->setAutoplay();
}
}
@@ -1832,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,
@@ -1854,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();
}));
@@ -1915,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) {
@@ -2046,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();
});
@@ -2071,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();
@@ -2174,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),
@@ -2341,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)
@@ -2349,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,11 +557,19 @@ 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);
}));
_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());
subscribe(_navigation->session().downloaderTaskFinished(), [=] {
update();
});
@@ -619,16 +623,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 +1095,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 +1131,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;

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