Compare commits

...

224 Commits

Author SHA1 Message Date
John Preston
daf545a72a Version 4.10.2: Try fixing Snap action. 2023-09-29 19:29:53 +04:00
John Preston
771869e945 Version 4.10.2: Fix build with GCC. 2023-09-29 09:36:10 +04:00
John Preston
ac1fe2cfee Update submodules. 2023-09-29 09:04:43 +04:00
John Preston
ed064ee13c Version 4.10.2.
- Bug fixes and other minor improvements.
2023-09-29 00:15:19 +04:00
John Preston
9fcdec4166 Update libvpx revision. 2023-09-29 00:15:19 +04:00
John Preston
bd4cf82405 Don't highlight links in non-premium stories. 2023-09-28 23:51:30 +04:00
John Preston
3653a6f011 Improve confirm box text padding. 2023-09-28 23:51:30 +04:00
John Preston
adc6930ac6 Skip irrelevant message on changelog story hiding. 2023-09-28 23:51:30 +04:00
John Preston
7305d542ba Fix possible crash in message context menu. 2023-09-28 23:51:30 +04:00
John Preston
874c84ad4e Fix file reference refresh in story forward. 2023-09-28 23:51:29 +04:00
John Preston
4edb11f128 Show channel stories in chats list. 2023-09-28 23:51:29 +04:00
John Preston
785014f7b7 Extract premium layer top bar widget. 2023-09-28 23:51:29 +04:00
John Preston
4cb5bea69b Update API scheme to layer 165. 2023-09-28 23:51:29 +04:00
Ilya Fedin
07bc84d425 Update submodules 2023-09-27 10:32:24 +04:00
Ilya Fedin
9019a2cb08 Remove an unneeded intermediate variable 2023-09-27 10:32:24 +04:00
Ilya Fedin
716cc6ef9e Workaround a crash in snap 2023-09-27 10:32:24 +04:00
Ilya Fedin
a509be99b0 Update Qt to 6.6.0-rc1 on Linux 2023-09-26 14:12:26 +04:00
Ilya Fedin
618ce15b21 Revert "Workaround Wayland popup menu bug."
This reverts commit 51027a0bc2.
2023-09-26 12:26:18 +04:00
Ilya Fedin
d2b5651c3b Patch Qt for better open url UX on Linux 2023-09-26 12:22:24 +04:00
Ilya Fedin
51ff484913 Update Qt to 6.6.0-beta4 on Linux 2023-09-26 12:15:33 +04:00
John Preston
547a5a14df Correct stories count in the Info title. 2023-09-26 12:12:43 +04:00
John Preston
5179d9a03f Workaround Xcode 15 linker bugs with -Wl,-ld_classic. 2023-09-25 21:37:34 +04:00
John Preston
26e84dbab2 Fix drag starting item. 2023-09-25 21:37:00 +04:00
John Preston
013c8ebeb4 Allow reactions for changelog stories. 2023-09-25 21:36:51 +04:00
John Preston
846e96579d Fix direct story links for channels. 2023-09-25 17:53:02 +04:00
John Preston
eaa491518e Remove changelog stories on archive attempt. 2023-09-25 17:39:18 +04:00
John Preston
4df7761e9d Allow deleting selected messages by backspace. 2023-09-25 12:55:29 +04:00
John Preston
6cdc8f9dbc Fix libvpx pkg-config generation on Windows.
Fixes #26849.
2023-09-25 12:41:34 +04:00
John Preston
95e4abd784 Extract system-specific parts of prepare env. 2023-09-25 12:41:34 +04:00
John Preston
6f9a540a61 Fix crash when libvpx decoder is absent.
Fixes #26849.
2023-09-25 12:41:34 +04:00
John Preston
137fca73bd Fix premium counter bubble with disabled animations. 2023-09-25 12:41:34 +04:00
John Preston
2159307643 Accept https://t.me/boost/channelusername links. 2023-09-25 12:41:34 +04:00
23rd
ded570a480 Fixed display of bulk download menu item on restricted content. 2023-09-25 06:27:08 +03:00
John Preston
4fd68d97d5 Merge remote-tracking branch into dev 2023-09-23 21:24:20 +04:00
John Preston
edfe998811 Fix build of minidump_stackwalk. 2023-09-23 21:23:51 +04:00
John Preston
116ae04f54 Add missing OpenGL resource deinitialization in viewer 2023-09-23 20:38:10 +04:00
Ilya Fedin
ce8e42bcc2 Support Wayland display reconnection 2023-09-23 20:38:10 +04:00
John Preston
ea9386f0aa Version 4.10.1: Rebuild macOS with older Xcode. 2023-09-23 19:25:24 +04:00
Ilya Fedin
58451aed91 Fix debug build on Linux 2023-09-23 06:29:10 +04:00
John Preston
a6df03d990 Version 4.10: Fix channel stories phrases. 2023-09-22 20:59:37 +04:00
John Preston
16b1881268 Version 4.10: Fix spawning args on Linux. 2023-09-22 20:16:22 +04:00
John Preston
0d25b154d9 Version 4.10.
- Stories for Channels.
- Reaction Stickers in Stories.
2023-09-22 18:12:35 +04:00
John Preston
89fac88677 Beta version 4.9.10: Fix after-update relaunch. 2023-09-22 16:08:41 +04:00
John Preston
9604a3bd80 Beta version 4.9.10: Remove legacy checks. 2023-09-22 11:51:47 +04:00
John Preston
5b3ffc778d Merge remote-tracking branch 'origin/dev' into dev 2023-09-22 11:50:47 +04:00
John Preston
c6c06c149d Check AppUserModelId better. 2023-09-22 11:50:41 +04:00
John Preston
a37f7077b0 Beta version 4.9.10: Fix build with GCC. 2023-09-22 11:06:03 +04:00
John Preston
5514ab0ccf Fix warnings after Xcode 15 / target 10.13 update. 2023-09-22 11:01:46 +04:00
John Preston
63a753d35c Beta version 4.9.10.
- Update Qt to 6.2.5 on macOS.
- Update minimum target to macOS 10.13 and toolchain to Xcode 15.
- Update Linux build host from CentOS 7 to Rocky Linux 8.
- Update Linux toolchain to GCC 12.
2023-09-22 09:43:32 +04:00
John Preston
4e82b7973f Suppress warning in libtgvoip json11. 2023-09-22 09:43:32 +04:00
John Preston
09094affed Improve boosted channel replacement design. 2023-09-22 09:43:32 +04:00
John Preston
c5634580f6 Add view button to channel boost link previews. 2023-09-22 09:43:32 +04:00
John Preston
7828a92f08 Implement views/reactions polling in channels. 2023-09-22 09:43:32 +04:00
John Preston
e60e65f574 Toggle suggested reaction counter animated. 2023-09-22 09:43:32 +04:00
John Preston
7a25d70240 Support all cases for BoostBox. 2023-09-22 09:43:32 +04:00
John Preston
01428572b0 Add shadow for white suggested reactions. 2023-09-22 09:43:32 +04:00
John Preston
a43a5ce6c5 Improve reaction selector position. 2023-09-22 09:43:32 +04:00
John Preston
d4ba01bad0 Suggested reaction effect around the widget. 2023-09-22 09:43:32 +04:00
John Preston
5d5cae7860 Implement suggested reaction count. 2023-09-22 09:43:32 +04:00
John Preston
f3db7e636b Implement channel stories views / reactions. 2023-09-22 09:43:32 +04:00
John Preston
1c2951598b Handle t.me/channel?boost links. 2023-09-22 09:43:32 +04:00
John Preston
39f8394f98 Enable story actions in channels. 2023-09-22 09:43:31 +04:00
John Preston
29c5f6b706 Support channel stories archive. 2023-09-22 09:43:31 +04:00
John Preston
b2c9a92c3e Hide reply field in channel stories. 2023-09-22 09:43:31 +04:00
John Preston
f3647d7f8c Show saved stories / current stories in channels. 2023-09-22 09:43:31 +04:00
John Preston
f3e65181cd Initial suggested reaction implementation. 2023-09-22 09:43:31 +04:00
John Preston
d5b429e910 Update API scheme to layer 164. 2023-09-22 09:43:31 +04:00
Ilya Fedin
1bde096417 Minimize amount of code to rebuild when switching options 2023-09-22 09:14:01 +04:00
John Preston
3db0b11a6b Bump minimum macOS deployment target to 10.13. 2023-09-22 09:03:12 +04:00
John Preston
8d00d93949 Fix uninitialized warning in build with GCC. 2023-09-22 09:03:00 +04:00
Ilya Fedin
277fe540dc Update Qt to 6.2.5 on macOS 2023-09-22 08:49:53 +04:00
Ilya Fedin
1683dccb50 Always set AppUserModelID on Windows 2023-09-21 13:39:26 +04:00
Ilya Fedin
47195e316f Don't load SetCurrentProcessExplicitAppUserModelID dynamically
It's supported since Windows 7
2023-09-21 13:39:26 +04:00
Ilya Fedin
8c9014fcf6 Update all third party submodules 2023-09-21 12:53:07 +04:00
Ilya Fedin
2d7675ace0 Update all dependencies in snap 2023-09-21 12:53:07 +04:00
Ilya Fedin
61cc7efc2a Update all dependencies in Dockerfile 2023-09-21 12:53:07 +04:00
Ilya Fedin
0464a558f0 Add Qt window frame string for Wayland 2023-09-21 12:49:45 +04:00
Ilya Fedin
ff9321e971 Main thread deadlock detector for debug mode 2023-09-21 12:23:23 +04:00
John Preston
d10b7e8402 Update tg_owt+libyuv/libvpx to chromium revisions. 2023-09-21 11:10:44 +04:00
Ilya Fedin
71f3f67fe3 Update submodules & patches on Linux 2023-09-21 10:30:09 +04:00
Ilya Fedin
47983d59fb Use -fno-omit-frame-pointer for better backtraces 2023-09-20 22:32:35 +04:00
Ilya Fedin
df29af5aea CentOS 7 -> Rocky Linux 8 2023-09-20 22:32:35 +04:00
Ilya Fedin
27b443b24d Use QStandardPaths to find the externalupdater config
That should be more convenient for everyone and cross-platform...
2023-09-20 18:05:45 +04:00
Ilya Fedin
7b4a542890 Always wait for updater to exit on Linux 2023-09-20 18:05:45 +04:00
Ilya Fedin
db6c69fa5f Move writeprotected to global updater variables on Linux 2023-09-20 18:05:45 +04:00
Ilya Fedin
7dfeea3f4e Get rid of workingDirChosen variable
It's set in every codepath where cWorkingDir is non-empty.
2023-09-20 18:05:45 +04:00
Ilya Fedin
92a41c881d Consolidate cForceWorkingDir(psAppDataPath()) 2023-09-20 18:05:45 +04:00
Ilya Fedin
3d769a6dce Get rid of cForceWorkingDir(cWorkingDir())
It has no sense as no code sets working directory directly to the variable anymore.
2023-09-20 18:05:45 +04:00
Ilya Fedin
330dfaa4d9 Consolidate MoveOldDataFiles path determinition 2023-09-20 18:05:45 +04:00
Ilya Fedin
b35fff01b0 Restore initial working directory on restart
So executable path computation still works for the new instance on systems deducing it by argv0
2023-09-20 18:05:45 +04:00
Ilya Fedin
cc19928977 Fix logging initial working directory when TelegramForcePortable exists 2023-09-20 18:05:45 +04:00
Ilya Fedin
c5424d0a9a Get rid of unneeded + '/' for cForceWorkingDir
It does the same on its own
2023-09-20 18:05:45 +04:00
Ilya Fedin
f3572e52ac Don't create a QDir instance for its static setCurrent method 2023-09-20 18:05:45 +04:00
Ilya Fedin
949c486cac Use a higher-level API for restarts/updates on Linux
This gets rid of the custom arguments container
2023-09-20 18:05:45 +04:00
Ilya Fedin
082b5ba782 Get rid of sandboxed paths workaround
This is fixed in xdg-desktop-portal 1.17.

There's no way to check xdg-desktop-portal version so it's either not having support for passing last used path at all in sandbox or encountering the bug on old systems.
2023-09-20 17:58:41 +04:00
Ilya Fedin
0f86968afd Use ServerInformation without std::optional 2023-09-20 17:52:39 +04:00
Ilya Fedin
90f52d80d7 Avoid global copying in Linux native notifications 2023-09-20 17:52:39 +04:00
Ilya Fedin
4e97599e9d Use Glib::ustring in Linux notification globals 2023-09-20 17:52:39 +04:00
Ilya Fedin
e0b3e69351 Update range-v3 to 0.18.0 2023-09-20 17:52:39 +04:00
Ilya Fedin
e0b4d1edce Avoid unneeded std::string casts in exception handling 2023-09-20 17:45:37 +04:00
John Preston
a54bc449e4 Version 4.9.9: Add support for Emoji 15. 2023-09-18 23:38:59 +04:00
Ilya Fedin
ea41aab713 Make use of templated XDP::ReadSetting 2023-09-18 19:52:48 +04:00
John Preston
fd00450f44 Version 4.9.9.
- Several crash fixes.
2023-09-18 12:45:55 +04:00
John Preston
e22aed55b0 Update submodules. 2023-09-18 12:44:20 +04:00
Ilya Fedin
cb838e6e52 Make use of the new XDP::SettingWatcher constructor 2023-09-18 12:44:20 +04:00
John Preston
3c931b11d6 Clear CacheHelper::waiting mutex in time.
I hope this fixes crashes in streaming semaphore usage.

CacheHelper::waiting points to Context::_semaphore, so it
should be cleared before Context is destroyed, not later.
2023-09-18 12:40:02 +04:00
John Preston
a14dbffb65 Fix possible crash in pinned message deletion. 2023-09-18 12:40:02 +04:00
John Preston
64dcae3174 Destroy volume dropdown after volume toggle.
This fixes https://bugs.telegram.org/c/31989

When destroying the dropdown first, the volume toggle receives an Enter
event and tries to show the dropdown (that is being destroyed).
2023-09-18 12:40:02 +04:00
John Preston
6af527ac76 Set dynamic box name to crash annotations. 2023-09-18 12:40:01 +04:00
John Preston
e1624e5d22 Fix a possible crash in translations. 2023-09-18 12:40:01 +04:00
Ilya Fedin
21857450f3 Update lib_base 2023-09-17 19:54:54 +04:00
Ilya Fedin
8ea4f26e31 Simplify some using-s 2023-09-17 19:54:54 +04:00
John Preston
76ac6c3be7 Version 4.9.8.
- Fix t.me/botname?startapp=token deeplinks.
- Fix a possible crash in media viewer on Wayland.
2023-09-16 07:55:02 +04:00
John Preston
c4c5036ec0 Update submodules. 2023-09-16 07:39:28 +04:00
Ilya Fedin
ad87c2a15e Re-use the Wayland AutoDestroyer's lifetime in WaylandIntegration::Private 2023-09-16 06:26:51 +04:00
Ilya Fedin
7dbf331e18 Fix org_kde_plasma_surface destroyer lambda leak 2023-09-16 06:26:51 +04:00
John Preston
ab53b4eab7 Fix build of Packer. 2023-09-15 21:48:23 +04:00
John Preston
7d678e5fa7 Fix ringtones downloaded to disk. 2023-09-15 21:18:14 +04:00
John Preston
6adb3e7200 Fix build on macOS. 2023-09-15 20:42:23 +04:00
Ilya Fedin
7906be37b6 Change #if-ery to be more in line with cmake logic (LINUX = NOT WIN32 AND NOT APPLE) 2023-09-15 19:52:22 +04:00
John Preston
c12743925e Support ?startapp=value start_param passing. 2023-09-15 15:36:09 +04:00
John Preston
b17b806d91 Add hide-chats-list-in-forums setting. 2023-09-15 15:36:09 +04:00
John Preston
98ab91a56a More correct way of applying min stories. 2023-09-14 10:58:29 +04:00
John Preston
0f8d9e885a Re-update lib_base submodule. 2023-09-14 10:15:22 +04:00
John Preston
bc891ca55e Don't build too much in libwebp. 2023-09-14 10:10:54 +04:00
Ilya Fedin
9653cfdd56 Update lib_base 2023-09-14 09:27:13 +04:00
Ilya Fedin
0b4a255acc Use SNAP_INSTANCE_NAME in SingleInstanceLocalServerName
That's what snapd's apparmor profiles use
2023-09-14 09:27:13 +04:00
John Preston
94feb953aa Version 4.9.7.
- Fix direct bot web app links handling.
- Close main menu when opening a web app.
- Bump libwebp revision.
2023-09-13 21:16:03 +04:00
John Preston
7b65c9174f Link system libwebp instead of Qt-s. 2023-09-13 21:07:24 +04:00
John Preston
e74021fbc9 Show "Open Bot" button for main menu apps. 2023-09-13 20:51:01 +04:00
John Preston
e6a474d720 Close main menu on a web app opening. 2023-09-13 20:51:01 +04:00
23rd
976c696004 Slightly improved style of mini icons in dialogs list for replies story. 2023-09-13 12:09:16 +03:00
John Preston
c057c88d30 Try title overscroll colors only on macOS. 2023-09-13 09:04:29 +04:00
John Preston
674bab69f5 Send viewport updates in web-apps. 2023-09-13 09:04:28 +04:00
John Preston
97d93b23dc Fix direct bot app links. 2023-09-13 08:24:38 +04:00
23rd
d363a6ea84 Replaced url click handler in view buttons with external sponsored link. 2023-09-13 00:34:00 +03:00
John Preston
da7e8a8dc3 Version 4.9.6: Fix build. 2023-09-12 21:14:01 +04:00
John Preston
4296f93e1a Version 4.9.6.
- Some bot web-app improvements.
- Bug fixes and other minor improvements.
2023-09-12 21:02:22 +04:00
John Preston
d0b16ce05b Fix macOS webview transparent background. 2023-09-12 21:01:12 +04:00
John Preston
c3340fd016 Don't destroy by timer single-view media. 2023-09-12 21:01:12 +04:00
John Preston
36f1a18b3b Show terms on attach bot direct link app. 2023-09-12 21:01:12 +04:00
John Preston
ef969df86e Improve main menu bots disclaimer acceptance. 2023-09-12 21:01:12 +04:00
John Preston
229f7a2c15 Handle background / title colors in web-apps. 2023-09-12 21:01:12 +04:00
John Preston
fbd8abc1c6 Start main menu bots. 2023-09-12 21:01:12 +04:00
John Preston
73f3110403 Update API scheme to layer 163. 2023-09-12 21:01:11 +04:00
Ilya Fedin
dfa5386a27 Ensure closing is supported for running in background 2023-09-12 19:49:48 +04:00
John Preston
e5227a7e05 Improve OpenGL windows on macOS.
Fix #26268 by adding a workaround for incorrect FBO size.
Fix #26166 by forcing sRGB color scheme on all app windows.
2023-09-12 11:41:31 +04:00
John Preston
a6b844408a Add verified/fake/scam badge to ConfirmInviteBox. 2023-09-12 11:40:33 +04:00
John Preston
dbd4aecc56 Don't show message bottom info in bot about. 2023-09-12 11:40:33 +04:00
23rd
3332f012cf Added tooltip and ability to copy external link to sponsored messages. 2023-09-12 11:40:33 +04:00
23rd
456f4d7b8a Fixed api id and hash in Github Action on Windows for nightly builds. 2023-09-12 11:40:33 +04:00
Ilya Fedin
0b4ef3214e Leverage QImage's CoW in Linux native notifications 2023-09-12 10:29:29 +04:00
Ilya Fedin
e946bf5338 Run in background on Linux when minimization is not supported 2023-09-12 10:27:13 +04:00
Ilya Fedin
e8a1fc0300 Add a method to check whether to run in background instead of checking for macOS 2023-09-12 10:27:13 +04:00
Ilya Fedin
0bf0fb29d2 Add nodiscard for a bunch of platform specific methods 2023-09-12 10:27:13 +04:00
Ilya Fedin
566f2dd670 Switch XDP open with dialog to QWaylandWindow::requestXdgActivationToken 2023-09-11 11:12:08 +04:00
Ilya Fedin
e52e1672e8 Make PortalAutostart asynchronous 2023-09-11 11:11:40 +04:00
Ilya Fedin
bf255c0e00 Don't use crl::on_main unnecessarily in Linux native notifications code
All those dbus methods call callbacks on the same thread
2023-09-11 11:11:04 +04:00
Ilya Fedin
55fb3405e5 Move feature warnings to the relevant code 2023-09-11 11:05:05 +04:00
23rd
adbe5e9605 Slightly improved style of mini icons in dialogs list. 2023-09-08 11:40:18 +03:00
23rd
29bfe43386 Added ability to export chat for html and json formats simultaneously. 2023-09-08 11:40:18 +03:00
23rd
ca30c35c2b Added initial export writer for both html and json formats. 2023-09-08 11:40:18 +03:00
23rd
d4ad5d9f13 Removed uppercase from some phrases in export. 2023-09-08 11:40:18 +03:00
23rd
fd79973509 Fixed crash when importing custom theme with duplicated entries. 2023-09-08 11:40:18 +03:00
23rd
d2bd109169 Removed uppercase from some phrases in theme editor. 2023-09-08 11:40:18 +03:00
23rd
1b5b9f46d2 Allowed to save not loaded photos from bulk download menu item. 2023-09-08 11:40:18 +03:00
23rd
ed345e0823 Allowed to select loaded documents for bulk download menu item. 2023-09-08 11:40:18 +03:00
23rd
90adc2d97c Fixed misaligned line in expanded reaction menu with disabled animation.
Fixed #26748.
2023-09-08 11:40:18 +03:00
23rd
787ed443f4 Increased clickable area to change forward options in sections. 2023-09-08 11:40:18 +03:00
23rd
7ffb341597 Removed some unwanted include directives of styles in header files. 2023-09-08 11:40:18 +03:00
Ilya Fedin
483909854a Use brackets include for QtWaylandScanner-generated headers 2023-09-08 07:28:13 +04:00
Ilya Fedin
289257dd0f Update submodules 2023-09-08 07:10:53 +04:00
Ilya Fedin
547a39d835 Update tg_owt in snap 2023-09-07 07:40:52 +04:00
John Preston
eef3cdd31b Update mini_forward/mini_reply_story icons. 2023-09-05 21:33:04 +04:00
John Preston
4bfe40d02e Don't close ShareBox by outside click. 2023-09-05 21:33:04 +04:00
John Preston
107b72f442 Fix possible crash in AddBotToGroupBox. 2023-09-05 21:33:04 +04:00
John Preston
8adbbe6885 Don't expect itemId from shareContact. 2023-09-05 19:30:29 +04:00
John Preston
191f832e52 Use notarytool instead of altool for notarization. 2023-09-05 16:42:12 +04:00
John Preston
9f0a756f71 Version 4.9.5: Fix build with GCC. 2023-09-05 13:10:03 +04:00
Ilya Fedin
0079a18e97 Call D-Bus ReloadConfig asynchronously 2023-09-04 18:11:25 +04:00
John Preston
876a803e0e Version 4.9.5.
- Several new bot web-app features.
- Bug fixes and other minor improvements.
2023-09-04 17:54:11 +04:00
John Preston
7009e967d0 Fix build with MSVC. 2023-09-04 17:38:02 +04:00
John Preston
076aa9452e Unblock the bot before sharing phone number. 2023-09-04 17:36:55 +04:00
John Preston
d77c7a70ab Implement new bot web-app methods. 2023-09-04 17:36:55 +04:00
John Preston
8255de1ba8 Update API scheme to layer 162. 2023-09-04 17:36:55 +04:00
23rd
aad1296829 Fixed overlapping right badges on ellipsis in dialogs list. 2023-09-04 17:36:54 +04:00
23rd
738aff9c4f Fixed paint of mini icon in dialogs list even there is no space for it. 2023-09-04 17:36:54 +04:00
23rd
7740780eeb Respected presence of plain link in preview text for mini icons. 2023-09-04 17:36:54 +04:00
23rd
9edbb9762a Fixed some cases when peer may not be removed from filter from menu. 2023-09-04 17:36:54 +04:00
23rd
98bb520f47 Adjusted code for refactor of input fields in lib_ui. 2023-09-04 17:36:54 +04:00
23rd
ae2182c1e5 Removed document's requirement when it's unavailable in userpic builder. 2023-09-04 17:36:54 +04:00
Ilya Fedin
4807244682 Don't use crl::on_main unnecessarily with XDP::SettingWatcher
g_dbus_connection_signal_subscribe calls the callback on the same thread
2023-09-04 16:21:58 +04:00
John Preston
119f7e757d Don't show yourself in notification exceptions. 2023-09-01 12:00:25 +04:00
GitHub Action
e34e640dbb Update User-Agent for DNS to Chrome 116.0.5845.96. 2023-09-01 11:08:21 +04:00
Ilya Fedin
e755851237 Update lib_base 2023-08-31 22:46:54 +04:00
John Preston
dff168c62e Version 4.9.4: Workaround MSVC optimization bug.
When adding some de-optimizing code, like logging etc,
the issue disappears. This volatile workaround looks like it works.
2023-08-31 22:43:26 +04:00
John Preston
b39bf11d9e Fix build with GCC. 2023-08-31 22:37:29 +04:00
John Preston
d8f53d5f60 Version 4.9.4.
- Default private chats / groups / channels notification settings.
- Forwarded / reply-to-a-story icon in chats list message preview.
- Bug fixes and other minor improvements.
2023-08-30 23:33:40 +04:00
John Preston
f10da51517 Improve phrases in SendFilesBox drag areas. 2023-08-30 23:32:17 +04:00
23rd
3dc0e3818b Fixed redundant peer adding to always/never lists in filter from menu. 2023-08-30 18:14:14 +03:00
23rd
1493b23574 Added mini icon to messages with reply to story. 2023-08-30 18:14:14 +03:00
23rd
70e298cfe4 Added icon for replies to stories in dialogs list. 2023-08-30 18:14:14 +03:00
23rd
9d4b8bb9b0 Introduced new struct to dialogs style for icons. 2023-08-30 16:46:19 +03:00
23rd
089432be5e Added icon for forwarded messages in dialogs list. 2023-08-30 14:50:00 +03:00
23rd
4b503ad7ed Slightly refactored include directives in some source files. 2023-08-30 14:50:00 +03:00
23rd
aeb593dd77 Slightly refactored StickersBox class. 2023-08-30 14:50:00 +03:00
23rd
0d4a83ea47 Added ability to remove sticker set from tab of featured sticker sets. 2023-08-30 14:50:00 +03:00
John Preston
95b26911e0 Use inline image/path expanding from lib_ui. 2023-08-30 08:55:46 +04:00
Ilya Fedin
4c2be58dd3 Update Qt patches on Linux 2023-08-30 05:13:21 +02:00
Ilya Fedin
374e95de31 Update kimageformats 2023-08-30 05:13:21 +02:00
Ilya Fedin
cfe3285e68 Update cmake_helpers 2023-08-29 15:53:49 +02:00
John Preston
7b184e553b Fix build with Xcode. 2023-08-29 17:02:23 +04:00
Ilya Fedin
02e37ab2f2 Update submodules 2023-08-29 08:29:10 +02:00
Ilya Fedin
48206bcf95 Re-use base_linux_library 2023-08-29 08:08:03 +02:00
Ilya Fedin
d0eb7ec522 Fix window extents terminology
Extents is a synonym of size but we're setting not window size.
2023-08-29 08:02:00 +02:00
Ilya Fedin
77c2e12ebc Use non-throwing directory_iterator 2023-08-26 00:14:01 +02:00
Ilya Fedin
a479fcd55c Update cmake_helpers 2023-08-25 10:21:25 +02:00
Ilya Fedin
396635fa1d Make use of the new window-less base::Platform::XDP::ParentWindowID 2023-08-25 10:21:25 +02:00
Ilya Fedin
4755be4ace Add missing returns to skip taskbar Linux abstraction 2023-08-24 11:44:06 +02:00
John Preston
1148a2e144 Show information about default notifications toggle. 2023-08-23 19:43:35 +02:00
John Preston
827e755552 Allow customizing default notifications. 2023-08-23 19:29:56 +02:00
John Preston
b80f5f9706 Manage notifications exceptions in Settings. 2023-08-23 18:09:32 +02:00
John Preston
518f0e22cd Improve small blocklist layout, fix heightMin. 2023-08-23 11:23:28 +02:00
John Preston
610e0e7913 Start default notification settings. 2023-08-22 19:43:13 +02:00
394 changed files with 9657 additions and 4845 deletions

View File

@@ -41,7 +41,7 @@ on:
jobs:
linux:
name: CentOS 7
name: Rocky Linux 8
runs-on: ubuntu-latest
container:
image: ghcr.io/${{ github.repository }}/centos_env
@@ -51,7 +51,7 @@ jobs:
defaults:
run:
shell: scl enable rh-python38 -- scl enable llvm-toolset-7.0 -- scl enable devtoolset-10 -- bash --noprofile --norc -eo pipefail {0}
shell: scl enable gcc-toolset-12 -- bash --noprofile --norc -eo pipefail {0}
strategy:
matrix:

View File

@@ -61,7 +61,7 @@ jobs:
sudo snap run lxd waitready
- name: Free up some disk space.
uses: jlumbroso/free-disk-space@76866dbe54312617f00798d1762df7f43def6e5c
uses: jlumbroso/free-disk-space@f68fdb76e2ea636224182cfb7377ff9a1708f9b8
- name: Telegram Desktop snap build.
run: sg lxd -c 'snap run snapcraft -v'

View File

@@ -123,7 +123,7 @@ jobs:
echo "TDESKTOP_BUILD_DEFINE=$DEFINE" >> $GITHUB_ENV
API="-D TDESKTOP_API_TEST=ON"
if [ ${{ github.ref == 'refs/heads/nightly' }} ]; then
if [ $GITHUB_REF == 'refs/heads/nightly' ]; then
echo "Use the open credentials."
API="-D TDESKTOP_API_ID=611335 -D TDESKTOP_API_HASH=d524b414d21f4d37f08684c1df41ac9c"
fi

3
.gitmodules vendored
View File

@@ -58,9 +58,6 @@
[submodule "Telegram/ThirdParty/range-v3"]
path = Telegram/ThirdParty/range-v3
url = https://github.com/ericniebler/range-v3.git
[submodule "Telegram/ThirdParty/fcitx-qt5"]
path = Telegram/ThirdParty/fcitx-qt5
url = https://github.com/fcitx/fcitx-qt5.git
[submodule "Telegram/ThirdParty/nimf"]
path = Telegram/ThirdParty/nimf
url = https://github.com/hamonikr/nimf.git

View File

@@ -61,7 +61,7 @@ if (NOT DESKTOP_APP_USE_PACKAGED)
if (WIN32)
set(qt_version 5.15.10)
elseif (APPLE)
set(qt_version 6.3.2)
set(qt_version 6.2.5)
endif()
endif()
include(cmake/external/qt/package.cmake)

View File

@@ -17,13 +17,18 @@ The latest version is available for
* [Windows 7 and above (64 bit)](https://telegram.org/dl/desktop/win64) ([portable](https://telegram.org/dl/desktop/win64_portable))
* [Windows 7 and above (32 bit)](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)
* [macOS 10.13 and above](https://telegram.org/dl/desktop/mac)
* [Linux static build for 64 bit](https://telegram.org/dl/desktop/linux)
* [Snap](https://snapcraft.io/telegram-desktop)
* [Flatpak](https://flathub.org/apps/details/org.telegram.desktop)
## Old system versions
Version **4.9.9** was the last that supports older systems
* [macOS 10.12](https://updates.tdesktop.com/tmac/tsetup.4.9.9.dmg)
* [Linux with glibc < 2.28 static build](https://updates.tdesktop.com/tlinux/tsetup.4.9.9.tar.xz)
Version **2.4.4** was the last that supports older systems
* [OS X 10.10 and 10.11](https://updates.tdesktop.com/tosx/tsetup-osx.2.4.4.dmg)

View File

@@ -413,6 +413,7 @@ PRIVATE
core/crash_report_window.h
core/crash_reports.cpp
core/crash_reports.h
core/deadlock_detector.h
core/file_utilities.cpp
core/file_utilities.h
core/launcher.cpp
@@ -1261,6 +1262,8 @@ PRIVATE
settings/settings_main.h
settings/settings_notifications.cpp
settings/settings_notifications.h
settings/settings_notifications_type.cpp
settings/settings_notifications_type.h
settings/settings_power_saving.cpp
settings/settings_power_saving.h
settings/settings_premium.cpp
@@ -1472,6 +1475,7 @@ PRIVATE
qrc/emoji_5.qrc
qrc/emoji_6.qrc
qrc/emoji_7.qrc
qrc/emoji_8.qrc
qrc/emoji_preview.qrc
qrc/telegram/animations.qrc
qrc/telegram/export.qrc

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 821 KiB

After

Width:  |  Height:  |  Size: 832 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 B

View File

@@ -451,6 +451,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_show_from" = "Show notifications from";
"lng_settings_notify_all" = "All accounts";
"lng_settings_notify_all_about" = "Turn this off if you want to receive notifications only from the account you are currently using.";
"lng_settings_notify_global" = "Global settings";
"lng_settings_notify_title" = "Notifications for chats";
"lng_settings_desktop_notify" = "Desktop notifications";
"lng_settings_native_title" = "Native notifications";
@@ -458,8 +459,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_use_native_notifications" = "Use native notifications";
"lng_settings_notifications_position" = "Location on the screen";
"lng_settings_notifications_count" = "Notifications count";
"lng_settings_sound_notify" = "Play sound";
"lng_settings_sound_notify_off" = "Off";
"lng_settings_sound_allowed" = "Allow 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";
@@ -480,6 +480,36 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_notification_hide_all" = "Hide all";
"lng_notification_sample" = "This is a sample notification";
"lng_notification_reminder" = "Reminder";
"lng_notification_private_chats" = "Private chats";
"lng_notification_groups" = "Groups";
"lng_notification_channels" = "Channels";
"lng_notification_click_to_change" = "Click here to change";
"lng_notification_on" = "On, {exceptions}";
"lng_notification_off" = "Off, {exceptions}";
"lng_notification_exceptions#one" = "{count} exception";
"lng_notification_exceptions#other" = "{count} exceptions";
"lng_notification_exceptions_title" = "Exceptions";
"lng_notification_title_private_chats" = "Notifications for private chats";
"lng_notification_about_private_chats#one" = "Please note that **{count} chat** is listed as an exception and won't be affected by this change.";
"lng_notification_about_private_chats#other" = "Please note that **{count} chats** are listed as exceptions and won't be affected by this change.";
"lng_notification_title_groups" = "Notifications for groups";
"lng_notification_about_groups#one" = "Please note that **{count} group** is listed as an exception and won't be affected by this change.";
"lng_notification_about_groups#other" = "Please note that **{count} groups** are listed as exceptions and won't be affected by this change.";
"lng_notification_title_channels" = "Notifications for channels";
"lng_notification_about_channels#one" = "Please note that **{count} channel** is listed as an exception and won't be affected by this change.";
"lng_notification_about_channels#other" = "Please note that **{count} channels** are listed as exceptions and won't be affected by this change.";
"lng_notification_exceptions_view" = "View exceptions";
"lng_notification_enable" = "Enable notifications";
"lng_notification_sound" = "Sound";
"lng_notification_tone" = "Notification tone";
"lng_notification_exceptions_muted" = "Muted";
"lng_notification_exceptions_unmuted" = "Unmuted";
"lng_notification_exceptions_add" = "Add an exception";
"lng_notification_exceptions_clear" = "Delete all exceptions";
"lng_notification_exceptions_clear_sure" = "Are you sure you want to delete all exceptions?";
"lng_notification_exceptions_clear_button" = "Delete";
"lng_notification_exceptions_remove" = "Remove";
"lng_notification_context_remove" = "Remove exception";
"lng_reaction_text" = "{reaction} to your «{text}»";
"lng_reaction_notext" = "{reaction} to your message";
@@ -518,6 +548,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_title_account_name" = "Show active account";
"lng_settings_title_total_count" = "Total unread count";
"lng_settings_native_frame" = "Use system window frame";
"lng_settings_qt_frame" = "Use Qt window frame";
"lng_settings_auto_start" = "Launch Telegram when system starts";
"lng_settings_start_min" = "Launch minimized";
"lng_settings_auto_start_disabled_uwp" = "Starting with the system was disabled in Windows Settings.\n\nPlease enable Telegram Desktop in the Startup Apps Settings.";
@@ -1152,6 +1183,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_loading" = "Loading...";
"lng_profile_saved_stories#one" = "{count} saved story";
"lng_profile_saved_stories#other" = "{count} saved stories";
"lng_profile_posts#one" = "{count} post";
"lng_profile_posts#other" = "{count} posts";
"lng_profile_photos#one" = "{count} photo";
"lng_profile_photos#other" = "{count} photos";
"lng_profile_gifs#one" = "{count} GIF";
@@ -1581,6 +1614,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_suggested_video" = "{user} suggests you to use this profile video.";
"lng_action_suggested_video_button" = "View Video";
"lng_action_attach_menu_bot_allowed" = "You allowed this bot to message you when you added it in the attachment menu.";
"lng_action_webapp_bot_allowed" = "You allowed this bot to message you in his web-app.";
"lng_action_set_wallpaper_me" = "You set a new wallpaper for this chat";
"lng_action_set_wallpaper" = "{user} set a new wallpaper for this chat";
"lng_action_set_wallpaper_button" = "View Wallpaper";
@@ -1769,6 +1803,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_bot_share_location_unavailable" = "Sorry, location sharing is currently unavailable in Telegram Desktop.";
"lng_bot_share_phone" = "Do you want to share your phone number with this bot?";
"lng_bot_share_phone_confirm" = "Share";
"lng_bot_allow_write_title" = "Allow messaging";
"lng_bot_allow_write" = "Do you want to allow this bot writing you?";
"lng_bot_allow_write_confirm" = "Allow";
"lng_attach_failed" = "Failed";
"lng_attach_file" = "File";
@@ -1965,6 +2002,38 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_premium_gift_terms" = "You can review the list of features and terms of use for Telegram Premium {link}.";
"lng_premium_gift_terms_link" = "here";
"lng_boost_channel_button" = "Boost Channel";
"lng_boost_level#one" = "Level {count}";
"lng_boost_level#other" = "Level {count}";
"lng_boost_channel_title_first" = "Enable stories for channel";
"lng_boost_channel_needs_first#one" = "{channel} needs **{count}** more boost to enable posting stories. Help make it possible!";
"lng_boost_channel_needs_first#other" = "{channel} needs **{count}** more boosts to enable posting stories. Help make it possible!";
"lng_boost_channel_title_more" = "Help upgrade channel";
"lng_boost_channel_needs_more#one" = "{channel} needs **{count}** more boost to be able to {post}.";
"lng_boost_channel_needs_more#other" = "{channel} needs **{count}** more boosts to be able to {post}.";
"lng_boost_channel_title_max" = "Maximum level reached";
"lng_boost_channel_you_title" = "You boosted {channel}!";
"lng_boost_channel_you_first#one" = "This channel needs **{count}** more boost\nto enable stories.";
"lng_boost_channel_you_first#other" = "This channel needs **{count}** more boosts\nto enable stories.";
"lng_boost_channel_you_more#one" = "This channel needs **{count}** more boost\nto be able to {post}.";
"lng_boost_channel_you_more#other" = "This channel needs **{count}** more boosts\nto be able to {post}.";
"lng_boost_channel_reached_first" = "This channel reached **Level 1** and can now post stories.";
"lng_boost_channel_reached_more#one" = "This channel reached **Level {count}** and can now {post}.";
"lng_boost_channel_reached_more#other" = "This channel reached **Level {count}** and can now {post}.";
"lng_boost_channel_post_stories#one" = "post **{count} story** per day";
"lng_boost_channel_post_stories#other" = "post **{count} stories** per day";
"lng_boost_error_gifted_title" = "Can't boost with gifted Premium!";
"lng_boost_error_gifted_text" = "Because your **Telegram Premium** subscription was gifted to you, you can't use it to boost channels.";
"lng_boost_error_already_title" = "Already Boosted!";
"lng_boost_error_already_text" = "You are already boosting this channel.";
"lng_boost_error_premium_title" = "Premium needed!";
"lng_boost_error_premium_text" = "Only **Telegram Premium** subscribers can boost channels. Do you want to subscribe to **Telegram Premium**?";
"lng_boost_error_premium_yes" = "Yes";
"lng_boost_error_flood_title" = "Can't boost too often!";
"lng_boost_error_flood_text" = "You can change the channel you boost only once a day. Next time you can boost is in {left}.";
"lng_boost_now_instead" = "You currently boost {channel}. Do you want to boost {other} instead?";
"lng_boost_now_replace" = "Replace";
"lng_accounts_limit_title" = "Limit Reached";
"lng_accounts_limit1#one" = "You have reached the limit of **{count}** connected accounts.";
"lng_accounts_limit1#other" = "You have reached the limit of **{count}** connected accounts.";
@@ -2226,17 +2295,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_bot_remove_from_menu" = "Remove From Menu";
"lng_bot_remove_from_menu_sure" = "Remove {bot} from the attachment menu?";
"lng_bot_remove_from_menu_done" = "Bot removed from the menu.";
"lng_bot_remove_from_side_menu" = "Remove From Menu";
"lng_bot_remove_from_side_menu_sure" = "Remove {bot} from the main menu?";
"lng_bot_remove_from_side_menu_done" = "Bot removed from the main menu.";
"lng_bot_settings" = "Settings";
"lng_bot_open" = "Open Bot";
"lng_bot_reload_page" = "Reload Page";
"lng_bot_add_to_menu" = "{bot} asks your permission to be added as an option to your attachments menu so you can access it from any chat.";
"lng_bot_add_to_menu_done" = "Bot added to the menu.";
"lng_bot_will_be_added" = "{bot} shortcuts will be added to the attachment options and the main menu.";
"lng_bot_side_menu_new" = "NEW";
"lng_bot_menu_not_supported" = "This bot isn't supported in the attach menu.";
"lng_bot_menu_already_added" = "This bot is already added in your attach menu.";
"lng_bot_menu_button" = "Menu";
"lng_bot_close_warning_title" = "Warning";
"lng_bot_close_warning" = "Changes that you made may not be saved.";
"lng_bot_close_warning_sure" = "Close anyway";
"lng_bot_add_to_side_menu" = "{bot} asks your permission to be added as an option to your main menu so you can access it any time.";
"lng_bot_add_to_side_menu_done" = "Bot added to the main menu.";
"lng_typing" = "typing";
"lng_user_typing" = "{user} is typing";
@@ -2340,6 +2416,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_open_gif" = "Open GIF";
"lng_context_save_gif" = "Save GIF";
"lng_context_delete_gif" = "Delete GIF";
"lng_context_open_channel" = "Open Channel";
"lng_context_attached_stickers" = "Attached Stickers";
"lng_context_to_msg" = "Go To Message";
"lng_context_reply_msg" = "Reply";
@@ -2717,6 +2794,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_payments_terms_title" = "Terms of Service";
"lng_payments_terms_text" = "Subscribe and accept terms of service of {bot}?";
"lng_payments_terms_text_once" = "Are you accepting terms of service of {bot}?";
"lng_payments_terms_agree" = "I agree to {link}";
"lng_payments_terms_link" = "Terms of Service";
"lng_payments_terms_accept" = "Accept";
@@ -3049,9 +3127,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gigagroup_suggest_more" = "Learn more";
"lng_rights_channel_info" = "Change channel info";
"lng_rights_channel_manage" = "Manage messages";
"lng_rights_channel_post" = "Post messages";
"lng_rights_channel_edit" = "Edit messages of others";
"lng_rights_channel_delete" = "Delete messages of others";
"lng_rights_channel_manage_stories" = "Manage stories";
"lng_rights_channel_post_stories" = "Post stories";
"lng_rights_channel_edit_stories" = "Edit stories of others";
"lng_rights_channel_delete_stories" = "Delete stories of others";
"lng_rights_channel_manage_calls" = "Manage live streams";
"lng_rights_group_info" = "Change group info";
"lng_rights_group_ban" = "Ban users";
@@ -3310,6 +3393,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_admin_log_admin_post_messages" = "Post messages";
"lng_admin_log_admin_edit_messages" = "Edit messages";
"lng_admin_log_admin_delete_messages" = "Delete messages";
"lng_admin_log_admin_post_stories" = "Post stories";
"lng_admin_log_admin_edit_stories" = "Edit stories";
"lng_admin_log_admin_delete_stories" = "Delete stories";
"lng_admin_log_admin_remain_anonymous" = "Remain anonymous";
"lng_admin_log_admin_ban_users" = "Ban users";
"lng_admin_log_admin_invite_users" = "Add members";
@@ -3525,6 +3611,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_export_option_choose_format" = "Choose export format";
"lng_export_option_html" = "Human-readable HTML";
"lng_export_option_json" = "Machine-readable JSON";
"lng_export_option_html_and_json" = "Both";
"lng_export_limits" = "From: {from}, to: {till}";
"lng_export_beginning" = "the oldest message";
"lng_export_end" = "present";
@@ -3789,6 +3876,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_view_button_voice_chat_channel" = "Live stream";
"lng_view_button_request_join" = "Request to Join";
"lng_view_button_external_link" = "Open link";
"lng_view_button_boost" = "Boost";
"lng_sponsored_hide_ads" = "Hide";
"lng_sponsored_title" = "What are sponsored messages?";
@@ -3799,6 +3887,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_telegram_features_url" = "https://t.me/TelegramTips";
"lng_mini_apps_disclaimer_title" = "Warning";
"lng_mini_apps_disclaimer_text" = "You are about to use a mini app operated by an independent party **not affiliated with Telegram**. You must agree to the Terms of Use of mini apps to continue.";
"lng_mini_apps_disclaimer_button" = "I agree to the {link}";
"lng_mini_apps_disclaimer_link" = "Terms of Use";
"lng_mini_apps_tos_url" = "https://telegram.org/tos/mini-apps";
"lng_ringtones_box_title" = "Notification Sound";
"lng_ringtones_box_cloud_subtitle" = "Choose your tone";
"lng_ringtones_box_upload_choose" = "Choose ringtone";
@@ -3916,6 +4010,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stories_recent_button" = "Recent Stories";
"lng_stories_archive_title" = "Stories Archive";
"lng_stories_archive_about" = "Only you can see archived stories unless you choose to save them to your profile.";
"lng_stories_channel_archive_about" = "Only admins of the channel can see archived stories unless they are saved to the channel page.";
"lng_stories_reply_sent" = "Message Sent";
"lng_stories_hidden_to_contacts" = "Stories from {user} will now be shown in **Archived Chats**.";
"lng_stories_shown_in_chats" = "Stories from {user} will now be shown in the **Chats List**.";
@@ -3935,6 +4030,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stories_archive_done" = "This story is hidden from your profile.";
"lng_stories_archive_done_many#one" = "{count} story is hidden from your profile.";
"lng_stories_archive_done_many#other" = "{count} stories are hidden from your profile.";
"lng_stories_channel_save_sure" = "Do you want to save this story to the channel page?";
"lng_stories_channel_save_sure_many#one" = "Do you want to save {count} story to the channel page?";
"lng_stories_channel_save_sure_many#other" = "Do you want to save {count} stories to the channel page?";
"lng_stories_channel_save_done" = "This story is saved to the channel page.";
"lng_stories_channel_save_done_many#one" = "{count} story is saved to the channel page.";
"lng_stories_channel_save_done_many#other" = "{count} stories are saved to the channel page.";
"lng_stories_channel_save_done_about" = "Saved stories can be viewed by others on the channel page until they are removed.";
"lng_stories_channel_archive_sure" = "Do you want to hide this story from the channel page?";
"lng_stories_channel_archive_sure_many#one" = "Do you want to hide {count} story from the channel page?";
"lng_stories_channel_archive_sure_many#other" = "Do you want to hide {count} stories from the channel page?";
"lng_stories_channel_archive_done" = "This story is hidden from the channel page.";
"lng_stories_channel_archive_done_many#one" = "{count} story is hidden from the channel page.";
"lng_stories_channel_archive_done_many#other" = "{count} stories are hidden from the channel page.";
"lng_stories_save_promo" = "Subscribe to {link} to download other people's unprotected stories to disk.";
"lng_stealth_mode_menu_item" = "Stealth Mode";

View File

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

View File

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

View File

@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,9,3,0
PRODUCTVERSION 4,9,3,0
FILEVERSION 4,10,2,0
PRODUCTVERSION 4,10,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop"
VALUE "FileVersion", "4.9.3.0"
VALUE "FileVersion", "4.10.2.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2023"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "4.9.3.0"
VALUE "ProductVersion", "4.10.2.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,9,3,0
PRODUCTVERSION 4,9,3,0
FILEVERSION 4,10,2,0
PRODUCTVERSION 4,10,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram FZ-LLC"
VALUE "FileDescription", "Telegram Desktop Updater"
VALUE "FileVersion", "4.9.3.0"
VALUE "FileVersion", "4.10.2.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2023"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "4.9.3.0"
VALUE "ProductVersion", "4.10.2.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -267,7 +267,7 @@ int main(int argc, char *argv[])
}
QByteArray inner = f.readAll();
stream << name << quint32(inner.size()) << inner;
#ifdef Q_OS_UNIX
#ifndef Q_OS_WIN
stream << (QFileInfo(fullName).isExecutable() ? true : false);
#endif
}
@@ -281,7 +281,7 @@ int main(int argc, char *argv[])
cout << "Compression start, size: " << resultSize << "\n";
QByteArray compressed, resultCheck;
#if defined Q_OS_WIN && !defined DESKTOP_APP_USE_PACKAGED // use Lzma SDK for win
#if defined Q_OS_WIN && !defined TDESKTOP_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
@@ -496,10 +496,8 @@ int main(int argc, char *argv[])
QString outName((targetwin64 ? QString("tx64upd%1") : QString("tupdate%1")).arg(AlphaVersion ? AlphaVersion : version));
#elif defined Q_OS_MAC
QString outName((targetarmac ? QString("tarmacupd%1") : QString("tmacupd%1")).arg(AlphaVersion ? AlphaVersion : version));
#elif defined Q_OS_UNIX
QString outName(QString("tlinuxupd%1").arg(AlphaVersion ? AlphaVersion : version));
#else
#error Unknown platform!
QString outName(QString("tlinuxupd%1").arg(AlphaVersion ? AlphaVersion : version));
#endif
if (AlphaVersion) {
outName += "_" + AlphaSignature;

View File

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

View File

@@ -41,6 +41,7 @@ bool do_mkdir(const char *path) { // from http://stackoverflow.com/questions/675
}
bool _debug = false;
bool writeprotected = false;
string updaterDir;
string updaterName;
string workDir;
@@ -88,7 +89,7 @@ void writeLog(const char *format, ...) {
va_end(args);
}
bool copyFile(const char *from, const char *to, bool writeprotected) {
bool copyFile(const char *from, const char *to) {
FILE *ffrom = fopen(from, "rb"), *fto = fopen(to, "wb");
if (!ffrom) {
if (fto) fclose(fto);
@@ -211,7 +212,7 @@ void delFolder() {
rmdir(delFolder.c_str());
}
bool update(bool writeprotected) {
bool update() {
writeLog("Update started..");
string updDir = workDir + "tupdates/temp", readyFilePath = workDir + "tupdates/temp/ready", tdataDir = workDir + "tupdates/temp/tdata";
@@ -324,7 +325,7 @@ bool update(bool writeprotected) {
writeLog("Copying file '%s' to '%s'..", fname.c_str(), tofname.c_str());
int copyTries = 0, triesLimit = 30;
do {
if (!copyFile(fname.c_str(), tofname.c_str(), writeprotected)) {
if (!copyFile(fname.c_str(), tofname.c_str())) {
++copyTries;
usleep(100000);
} else {
@@ -359,10 +360,10 @@ int main(int argc, char *argv[]) {
bool needupdate = true;
bool autostart = false;
bool debug = false;
bool writeprotected = false;
bool tosettings = false;
bool startintray = false;
bool customWorkingDir = false;
bool justUpdate = false;
char *key = 0;
char *workdir = 0;
@@ -381,6 +382,9 @@ int main(int argc, char *argv[]) {
customWorkingDir = true;
} else if (equal(argv[i], "-writeprotected")) {
writeprotected = true;
justUpdate = true;
} else if (equal(argv[i], "-justupdate")) {
justUpdate = true;
} else if (equal(argv[i], "-key") && ++i < argc) {
key = argv[i];
} else if (equal(argv[i], "-workpath") && ++i < argc) {
@@ -455,7 +459,7 @@ int main(int argc, char *argv[]) {
} else {
writeLog("Passed workpath is '%s'", workDir.c_str());
}
update(writeprotected);
update();
}
} else {
writeLog("Error: bad exe name!");
@@ -464,36 +468,38 @@ int main(int argc, char *argv[]) {
writeLog("Error: short exe name!");
}
const auto fullBinaryPath = exePath + exeName;
auto values = vector<string>();
const auto push = [&](string arg) {
// Force null-terminated .data() call result.
values.push_back(arg + char(0));
};
push(!argv0.empty() ? argv0 : fullBinaryPath);
push("-noupdate");
if (autostart) push("-autostart");
if (debug) push("-debug");
if (startintray) push("-startintray");
if (tosettings) push("-tosettings");
if (key) {
push("-key");
push(key);
}
if (customWorkingDir && workdir) {
push("-workdir");
push(workdir);
}
auto args = vector<char*>();
for (auto &arg : values) {
args.push_back(arg.data());
}
args.push_back(nullptr);
// let the parent launch instead
if (!writeprotected) {
if (justUpdate) {
writeLog("Closing log and quitting..");
} else {
const auto fullBinaryPath = exePath + exeName;
auto values = vector<string>();
const auto push = [&](string arg) {
// Force null-terminated .data() call result.
values.push_back(arg + char(0));
};
push(!argv0.empty() ? argv0 : fullBinaryPath);
push("-noupdate");
if (autostart) push("-autostart");
if (debug) push("-debug");
if (startintray) push("-startintray");
if (tosettings) push("-tosettings");
if (key) {
push("-key");
push(key);
}
if (customWorkingDir && workdir) {
push("-workdir");
push(workdir);
}
auto args = vector<char*>();
for (auto &arg : values) {
args.push_back(arg.data());
}
args.push_back(nullptr);
pid_t pid = fork();
switch (pid) {
case -1:
@@ -503,9 +509,10 @@ int main(int argc, char *argv[]) {
execv(fullBinaryPath.c_str(), args.data());
return 1;
}
writeLog("Executed Telegram, closing log and quitting..");
}
writeLog("Executed Telegram, closing log and quitting..");
closeLog();
return 0;

View File

@@ -77,45 +77,59 @@ void BlockedPeers::block(not_null<PeerData*> peer) {
_session->changes().peerUpdated(
peer,
Data::PeerUpdate::Flag::IsBlocked);
} else if (_blockRequests.find(peer) == end(_blockRequests)) {
const auto requestId = _api.request(MTPcontacts_Block(
MTP_flags(0),
peer->input
)).done([=] {
_blockRequests.erase(peer);
peer->setIsBlocked(true);
if (_slice) {
_slice->list.insert(
_slice->list.begin(),
{ peer->id, base::unixtime::now() });
++_slice->total;
_changes.fire_copy(*_slice);
}
}).fail([=] {
_blockRequests.erase(peer);
}).send();
_blockRequests.emplace(peer, requestId);
return;
} else if (blockAlreadySent(peer, true)) {
return;
}
const auto requestId = _api.request(MTPcontacts_Block(
MTP_flags(0),
peer->input
)).done([=] {
const auto data = _blockRequests.take(peer);
peer->setIsBlocked(true);
if (_slice) {
_slice->list.insert(
_slice->list.begin(),
{ peer->id, base::unixtime::now() });
++_slice->total;
_changes.fire_copy(*_slice);
}
if (data) {
for (const auto &callback : data->callbacks) {
callback(false);
}
}
}).fail([=] {
if (const auto data = _blockRequests.take(peer)) {
for (const auto &callback : data->callbacks) {
callback(false);
}
}
}).send();
_blockRequests.emplace(peer, Request{
.requestId = requestId,
.blocking = true,
});
}
void BlockedPeers::unblock(
not_null<PeerData*> peer,
Fn<void()> onDone,
Fn<void(bool success)> done,
bool force) {
if (!force && !peer->isBlocked()) {
_session->changes().peerUpdated(
peer,
Data::PeerUpdate::Flag::IsBlocked);
return;
} else if (_blockRequests.find(peer) != end(_blockRequests)) {
} else if (blockAlreadySent(peer, false, done)) {
return;
}
const auto requestId = _api.request(MTPcontacts_Unblock(
MTP_flags(0),
peer->input
)).done([=] {
_blockRequests.erase(peer);
const auto data = _blockRequests.take(peer);
peer->setIsBlocked(false);
if (_slice) {
auto &list = _slice->list;
@@ -130,13 +144,46 @@ void BlockedPeers::unblock(
}
_changes.fire_copy(*_slice);
}
if (onDone) {
onDone();
if (data) {
for (const auto &callback : data->callbacks) {
callback(true);
}
}
}).fail([=] {
_blockRequests.erase(peer);
if (const auto data = _blockRequests.take(peer)) {
for (const auto &callback : data->callbacks) {
callback(false);
}
}
}).send();
_blockRequests.emplace(peer, requestId);
const auto i = _blockRequests.emplace(peer, Request{
.requestId = requestId,
.blocking = false,
}).first;
if (done) {
i->second.callbacks.push_back(std::move(done));
}
}
bool BlockedPeers::blockAlreadySent(
not_null<PeerData*> peer,
bool blocking,
Fn<void(bool success)> done) {
const auto i = _blockRequests.find(peer);
if (i == end(_blockRequests)) {
return false;
} else if (i->second.blocking == blocking) {
if (done) {
i->second.callbacks.push_back(std::move(done));
}
return true;
}
const auto callbacks = base::take(i->second.callbacks);
_blockRequests.erase(i);
for (const auto &callback : callbacks) {
callback(false);
}
return false;
}
void BlockedPeers::reload() {
@@ -160,7 +207,7 @@ auto BlockedPeers::slice() -> rpl::producer<BlockedPeers::Slice> {
: (_changes.events() | rpl::type_erased());
}
void BlockedPeers::request(int offset, Fn<void(BlockedPeers::Slice)> onDone) {
void BlockedPeers::request(int offset, Fn<void(BlockedPeers::Slice)> done) {
if (_requestId) {
return;
}
@@ -170,7 +217,7 @@ void BlockedPeers::request(int offset, Fn<void(BlockedPeers::Slice)> onDone) {
MTP_int(offset ? kBlockedPerPage : kBlockedFirstSlice)
)).done([=](const MTPcontacts_Blocked &result) {
_requestId = 0;
onDone(TLToSlice(result, _session->data()));
done(TLToSlice(result, _session->data()));
}).fail([=] {
_requestId = 0;
}).send();

View File

@@ -39,20 +39,31 @@ public:
void reload();
rpl::producer<Slice> slice();
void request(int offset, Fn<void(Slice)> onDone);
void request(int offset, Fn<void(Slice)> done);
void block(not_null<PeerData*> peer);
void unblock(
not_null<PeerData*> peer,
Fn<void()> onDone = nullptr,
Fn<void(bool success)> done = nullptr,
bool force = false);
private:
struct Request {
std::vector<Fn<void(bool success)>> callbacks;
mtpRequestId requestId = 0;
bool blocking = false;
};
[[nodiscard]] bool blockAlreadySent(
not_null<PeerData*> peer,
bool blocking,
Fn<void(bool success)> done = nullptr);
const not_null<Main::Session*> _session;
MTP::Sender _api;
base::flat_map<not_null<PeerData*>, mtpRequestId> _blockRequests;
base::flat_map<not_null<PeerData*>, Request> _blockRequests;
mtpRequestId _requestId = 0;
std::optional<Slice> _slice;
rpl::event_stream<Slice> _changes;

View File

@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "window/window_session_controller.h"
#include "info/profile/info_profile_badge.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "ui/empty_userpic.h"
@@ -25,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/toast/toast.h"
#include "boxes/premium_limits_box.h"
#include "styles/style_boxes.h"
#include "styles/style_info.h"
#include "styles/style_layers.h"
namespace Api {
@@ -195,6 +197,13 @@ ConfirmInviteBox::ConfirmInviteBox(
: _session(session)
, _submit(std::move(submit))
, _title(this, st::confirmInviteTitle)
, _badge(std::make_unique<Info::Profile::Badge>(
this,
st::infoPeerBadge,
_session,
rpl::single(Info::Profile::Badge::Content{ BadgeForInvite(invite) }),
nullptr,
[=] { return false; }))
, _status(this, st::confirmInviteStatus)
, _about(this, st::confirmInviteAbout)
, _aboutRequests(this, st::confirmInviteStatus)
@@ -275,9 +284,24 @@ ConfirmInviteBox::ChatInvite ConfirmInviteBox::Parse(
.isMegagroup = data.is_megagroup(),
.isBroadcast = data.is_broadcast(),
.isRequestNeeded = data.is_request_needed(),
.isFake = data.is_fake(),
.isScam = data.is_scam(),
.isVerified = data.is_verified(),
};
}
[[nodiscard]] Info::Profile::BadgeType ConfirmInviteBox::BadgeForInvite(
const ChatInvite &invite) {
using Type = Info::Profile::BadgeType;
return invite.isVerified
? Type::Verified
: invite.isScam
? Type::Scam
: invite.isFake
? Type::Fake
: Type::None;
}
void ConfirmInviteBox::prepare() {
addButton(
(_requestApprove
@@ -326,8 +350,26 @@ void ConfirmInviteBox::prepare() {
void ConfirmInviteBox::resizeEvent(QResizeEvent *e) {
BoxContent::resizeEvent(e);
_title->move((width() - _title->width()) / 2, st::confirmInviteTitleTop);
_status->move((width() - _status->width()) / 2, st::confirmInviteStatusTop);
const auto padding = st::boxRowPadding;
auto nameWidth = width() - padding.left() - padding.right();
auto badgeWidth = 0;
if (const auto widget = _badge->widget()) {
badgeWidth = st::infoVerifiedCheckPosition.x() + widget->width();
nameWidth -= badgeWidth;
}
_title->resizeToWidth(std::min(nameWidth, _title->textMaxWidth()));
_title->moveToLeft(
(width() - _title->width() - badgeWidth) / 2,
st::confirmInviteTitleTop);
const auto badgeLeft = _title->x() + _title->width();
const auto badgeTop = _title->y();
const auto badgeBottom = _title->y() + _title->height();
_badge->move(badgeLeft, badgeTop, badgeBottom);
_status->move(
(width() - _status->width()) / 2,
st::confirmInviteStatusTop);
auto bottom = _status->y()
+ _status->height()
+ st::boxPadding.bottom()

View File

@@ -12,6 +12,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class UserData;
class ChannelData;
namespace Info::Profile {
class Badge;
enum class BadgeType;
} // namespace Info::Profile
namespace Main {
class Session;
} // namespace Main
@@ -66,10 +71,15 @@ private:
bool isMegagroup = false;
bool isBroadcast = false;
bool isRequestNeeded = false;
bool isFake = false;
bool isScam = false;
bool isVerified = false;
};
[[nodiscard]] static ChatInvite Parse(
not_null<Main::Session*> session,
const MTPDchatInvite &data);
[[nodiscard]] Info::Profile::BadgeType BadgeForInvite(
const ChatInvite &invite);
ConfirmInviteBox(
not_null<Main::Session*> session,
@@ -81,12 +91,14 @@ private:
Fn<void()> _submit;
object_ptr<Ui::FlatLabel> _title;
std::unique_ptr<Info::Profile::Badge> _badge;
object_ptr<Ui::FlatLabel> _status;
object_ptr<Ui::FlatLabel> _about;
object_ptr<Ui::FlatLabel> _aboutRequests;
std::shared_ptr<Data::PhotoMedia> _photo;
std::unique_ptr<Ui::EmptyUserpic> _photoEmpty;
std::vector<Participant> _participants;
bool _isChannel = false;
bool _requestApprove = false;

View File

@@ -78,12 +78,8 @@ void SendReport(
MTP_string(comment)
)).done(std::move(done)).send();
}, [&](StoryId id) {
const auto user = peer->asUser();
if (!user) {
return;
}
peer->session().api().request(MTPstories_Report(
user->inputUser,
peer->input,
MTP_vector<MTPint>(1, MTP_int(id)),
ReasonToTL(reason),
MTP_string(comment)

View File

@@ -17,11 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Api {
namespace {
constexpr auto TestApiId = 17349;
constexpr auto SnapApiId = 611335;
constexpr auto DesktopApiId = 2040;
Websites::Entry ParseEntry(
[[nodiscard]] Websites::Entry ParseEntry(
not_null<Data::Session*> owner,
const MTPDwebAuthorization &data) {
auto result = Websites::Entry{

View File

@@ -776,10 +776,9 @@ QString ApiWrap::exportDirectMessageLink(
QString ApiWrap::exportDirectStoryLink(not_null<Data::Story*> story) {
const auto storyId = story->fullId();
const auto user = story->peer()->asUser();
Assert(user != nullptr);
const auto peer = story->peer();
const auto fallback = [&] {
const auto base = user->username();
const auto base = peer->userName();
const auto story = QString::number(storyId.story);
const auto query = base + "/s/" + story;
return session().createInternalLinkFull(query);
@@ -789,7 +788,7 @@ QString ApiWrap::exportDirectStoryLink(not_null<Data::Story*> story) {
? i->second
: fallback();
request(MTPstories_ExportStoryLink(
story->peer()->asUser()->inputUser,
peer->input,
MTP_int(story->id())
)).done([=](const MTPExportedStoryLink &result) {
const auto link = qs(result.data().vlink());
@@ -1887,17 +1886,8 @@ void ApiWrap::sendNotifySettingsUpdates() {
}
const auto &settings = session().data().notifySettings();
for (const auto type : base::take(_updateNotifyDefaults)) {
const auto input = [&] {
switch (type) {
case Data::DefaultNotify::User: return MTP_inputNotifyUsers();
case Data::DefaultNotify::Group: return MTP_inputNotifyChats();
case Data::DefaultNotify::Broadcast:
return MTP_inputNotifyBroadcasts();
}
Unexpected("Default notify type in sendNotifySettingsUpdates");
}();
request(MTPaccount_UpdateNotifySettings(
input,
Data::DefaultNotifyToMTP(type),
settings.defaultSettings(type).serialize()
)).afterDelay(kSmallDelayMs).send();
}
@@ -2445,7 +2435,13 @@ void ApiWrap::refreshFileReference(
};
v::match(origin.data, [&](Data::FileOriginMessage data) {
if (const auto item = _session->data().message(data)) {
if (item->isScheduled()) {
const auto media = item->media();
const auto storyId = media ? media->storyId() : FullStoryId();
if (storyId) {
request(MTPstories_GetStoriesByID(
_session->data().peer(storyId.peer)->input,
MTP_vector<MTPint>(1, MTP_int(storyId.story))));
} else if (item->isScheduled()) {
const auto &scheduled = _session->data().scheduledMessages();
const auto realId = scheduled.lookupId(item);
request(MTPmessages_GetScheduledMessages(
@@ -2542,14 +2538,9 @@ void ApiWrap::refreshFileReference(
}, [&](Data::FileOriginPremiumPreviews data) {
request(MTPhelp_GetPremiumPromo());
}, [&](Data::FileOriginStory data) {
const auto user = _session->data().peer(data.peerId)->asUser();
if (user) {
request(MTPstories_GetStoriesByID(
user->inputUser,
MTP_vector<MTPint>(1, MTP_int(data.storyId))));
} else {
fail();
}
request(MTPstories_GetStoriesByID(
_session->data().peer(data.peerId)->input,
MTP_vector<MTPint>(1, MTP_int(data.storyId))));
}, [&](v::null_t) {
fail();
});
@@ -3329,25 +3320,37 @@ void ApiWrap::shareContact(
const QString &phone,
const QString &firstName,
const QString &lastName,
const SendAction &action) {
const SendAction &action,
Fn<void(bool)> done) {
const auto userId = UserId(0);
sendSharedContact(phone, firstName, lastName, userId, action);
sendSharedContact(
phone,
firstName,
lastName,
userId,
action,
std::move(done));
}
void ApiWrap::shareContact(
not_null<UserData*> user,
const SendAction &action) {
const SendAction &action,
Fn<void(bool)> done) {
const auto userId = peerToUser(user->id);
const auto phone = _session->data().findContactPhone(user);
if (phone.isEmpty()) {
if (done) {
done(false);
}
return;
}
sendSharedContact(
return sendSharedContact(
phone,
user->firstName,
user->lastName,
userId,
action);
action,
std::move(done));
}
void ApiWrap::sendSharedContact(
@@ -3355,7 +3358,8 @@ void ApiWrap::sendSharedContact(
const QString &firstName,
const QString &lastName,
UserId userId,
const SendAction &action) {
const SendAction &action,
Fn<void(bool)> done) {
sendAction(action);
const auto history = action.history;
@@ -3406,7 +3410,7 @@ void ApiWrap::sendSharedContact(
MTP_string(firstName),
MTP_string(lastName),
MTP_string()); // vcard
sendMedia(item, media, action.options);
sendMedia(item, media, action.options, std::move(done));
_session->data().sendHistoryChangeNotifications();
_session->changes().historyUpdated(
@@ -3937,18 +3941,20 @@ void ApiWrap::uploadAlbumMedia(
void ApiWrap::sendMedia(
not_null<HistoryItem*> item,
const MTPInputMedia &media,
Api::SendOptions options) {
Api::SendOptions options,
Fn<void(bool)> done) {
const auto randomId = base::RandomValue<uint64>();
_session->data().registerMessageRandomId(randomId, item->fullId());
sendMediaWithRandomId(item, media, options, randomId);
sendMediaWithRandomId(item, media, options, randomId, std::move(done));
}
void ApiWrap::sendMediaWithRandomId(
not_null<HistoryItem*> item,
const MTPInputMedia &media,
Api::SendOptions options,
uint64 randomId) {
uint64 randomId,
Fn<void(bool)> done) {
const auto history = item->history();
const auto replyTo = item->replyTo();
@@ -3990,10 +3996,12 @@ void ApiWrap::sendMediaWithRandomId(
MTP_int(options.scheduled),
(options.sendAs ? options.sendAs->input : MTP_inputPeerEmpty())
), [=](const MTPUpdates &result, const MTP::Response &response) {
if (done) done(true);
if (updateRecentStickers) {
requestRecentStickersForce(true);
}
}, [=](const MTP::Error &error, const MTP::Response &response) {
if (done) done(false);
sendMessageFail(error, peer, randomId, itemId);
});
}

View File

@@ -294,8 +294,12 @@ public:
const QString &phone,
const QString &firstName,
const QString &lastName,
const SendAction &action);
void shareContact(not_null<UserData*> user, const SendAction &action);
const SendAction &action,
Fn<void(bool)> done = nullptr);
void shareContact(
not_null<UserData*> user,
const SendAction &action,
Fn<void(bool)> done = nullptr);
void applyAffectedMessages(
not_null<PeerData*> peer,
const MTPmessages_AffectedMessages &result);
@@ -489,7 +493,8 @@ private:
const QString &firstName,
const QString &lastName,
UserId userId,
const SendAction &action);
const SendAction &action,
Fn<void(bool)> done);
void deleteHistory(
not_null<PeerData*> peer,
@@ -516,12 +521,14 @@ private:
void sendMedia(
not_null<HistoryItem*> item,
const MTPInputMedia &media,
Api::SendOptions options);
Api::SendOptions options,
Fn<void(bool)> done = nullptr);
void sendMediaWithRandomId(
not_null<HistoryItem*> item,
const MTPInputMedia &media,
Api::SendOptions options,
uint64 randomId);
uint64 randomId,
Fn<void(bool)> done = nullptr);
FileLoadTo fileLoadTaskOptions(const SendAction &action) const;
void getTopPromotionDelayed(TimeId now, TimeId next);

View File

@@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
#include "ui/toast/toast.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/fields/special_fields.h"
#include "ui/widgets/popup_menu.h"
#include "ui/text/format_values.h"
@@ -297,8 +298,11 @@ void AddContactBox::prepare() {
: tr::lng_enter_contact_data());
updateButtons();
connect(_first, &Ui::InputField::submitted, [=] { submit(); });
connect(_last, &Ui::InputField::submitted, [=] { submit(); });
const auto submitted = [=] { submit(); };
_first->submits(
) | rpl::start_with_next(submitted, _first->lifetime());
_last->submits(
) | rpl::start_with_next(submitted, _last->lifetime());
connect(_phone, &Ui::PhoneInput::submitted, [=] { submit(); });
setDimensions(
@@ -567,23 +571,24 @@ void GroupInfoBox::prepare() {
_description->setSubmitSettings(
Core::App().settings().sendSubmitWay());
connect(_description, &Ui::InputField::resized, [=] {
_description->heightChanges(
) | rpl::start_with_next([=] {
descriptionResized();
});
connect(_description, &Ui::InputField::submitted, [=] {
submit();
});
connect(_description, &Ui::InputField::cancelled, [=] {
}, _description->lifetime());
_description->submits(
) | rpl::start_with_next([=] { submit(); }, _description->lifetime());
_description->cancelled(
) | rpl::start_with_next([=] {
closeBox();
});
}, _description->lifetime());
Ui::Emoji::SuggestionsController::Init(
getDelegate()->outerContainer(),
_description,
&_navigation->session());
}
connect(_title, &Ui::InputField::submitted, [=] { submitName(); });
_title->submits(
) | rpl::start_with_next([=] { submitName(); }, _title->lifetime());
addButton(
((_type != Type::Group || _canAddBot)
@@ -1522,20 +1527,22 @@ void EditNameBox::prepare() {
_first->setMaxLength(Ui::EditPeer::kMaxUserFirstLastName);
_last->setMaxLength(Ui::EditPeer::kMaxUserFirstLastName);
connect(_first, &Ui::InputField::submitted, [=] { submit(); });
connect(_last, &Ui::InputField::submitted, [=] { submit(); });
_first->submits(
) | rpl::start_with_next([=] { submit(); }, _first->lifetime());
_last->submits(
) | rpl::start_with_next([=] { submit(); }, _last->lifetime());
_first->customTab(true);
_last->customTab(true);
QObject::connect(
_first,
&Ui::InputField::tabbed,
[=] { _last->setFocus(); });
QObject::connect(
_last,
&Ui::InputField::tabbed,
[=] { _first->setFocus(); });
_first->tabbed(
) | rpl::start_with_next([=] {
_last->setFocus();
}, _first->lifetime());
_last->tabbed(
) | rpl::start_with_next([=] {
_first->setFocus();
}, _last->lifetime());
}
void EditNameBox::setInnerFocus() {

View File

@@ -15,14 +15,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "ui/filter_icons.h"
#include "ui/text/text_utilities.h" // Ui::Text::Bold
#include "ui/widgets/buttons.h"
#include "ui/widgets/popup_menu.h"
#include "window/window_controller.h"
#include "window/window_session_controller.h"
#include "styles/style_settings.h"
#include "styles/style_payments.h" // paymentsSectionButton
#include "styles/style_media_player.h" // mediaPlayerMenuCheck
namespace {
@@ -32,14 +29,28 @@ Data::ChatFilter ChangedFilter(
not_null<History*> history,
bool add) {
auto always = base::duplicate(filter.always());
if (add) {
always.insert(history);
} else {
always.remove(history);
}
auto never = base::duplicate(filter.never());
if (add) {
never.remove(history);
} else {
always.remove(history);
}
const auto result = Data::ChatFilter(
filter.id(),
filter.title(),
filter.iconEmoji(),
filter.flags(),
std::move(always),
filter.pinned(),
std::move(never));
const auto in = result.contains(history);
if (in == add) {
return result;
}
always = base::duplicate(result.always());
never = base::duplicate(result.never());
if (add) {
always.insert(history);
} else {
never.insert(history);
}

View File

@@ -18,7 +18,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/facade.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/fields/number_input.h"
#include "ui/widgets/fields/password_input.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/dropdown_menu.h"
#include "ui/wrap/slide_wrap.h"

View File

@@ -13,7 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/vertical_layout.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/wrap/fade_wrap.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/shadow.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h"
@@ -184,7 +184,8 @@ not_null<Ui::FlatLabel*> CreateWarningLabel(
QString(),
st::createPollWarning);
result->setAttribute(Qt::WA_TransparentForMouseEvents);
QObject::connect(field, &Ui::InputField::changed, [=] {
field->changes(
) | rpl::start_with_next([=] {
Ui::PostponeCall(crl::guard(field, [=] {
const auto length = field->getLastText().size();
const auto value = valueLimit - length;
@@ -198,7 +199,7 @@ not_null<Ui::FlatLabel*> CreateWarningLabel(
}
result->setVisible(shown);
}));
});
}, field->lifetime());
return result;
}
@@ -243,13 +244,14 @@ Options::Option::Option(
_content->resize(_content->width(), height);
}, _field->lifetime());
QObject::connect(_field, &Ui::InputField::changed, [=] {
_field->changes(
) | rpl::start_with_next([=] {
Ui::PostponeCall(crl::guard(_field, [=] {
if (_hasCorrect) {
_correct->toggle(isGood(), anim::type::normal);
}
}));
});
}, _field->lifetime());
createShadow();
createRemove();
@@ -303,10 +305,11 @@ void Options::Option::createRemove() {
const auto toggle = lifetime.make_state<rpl::variable<bool>>(false);
_removeAlways = lifetime.make_state<rpl::variable<bool>>(false);
QObject::connect(field, &Ui::InputField::changed, [=] {
field->changes(
) | rpl::start_with_next([field, toggle] {
// Don't capture 'this'! Because Option is a value type.
*toggle = !field->getLastText().isEmpty();
});
}, field->lifetime());
rpl::combine(
toggle->value(),
_removeAlways->value(),
@@ -649,28 +652,32 @@ void Options::addEmptyOption() {
_position + _list.size() + _destroyed.size(),
_chooseCorrectGroup));
const auto field = _list.back()->field();
QObject::connect(field, &Ui::InputField::submitted, [=] {
field->submits(
) | rpl::start_with_next([=] {
const auto index = findField(field);
if (_list[index]->isGood() && index + 1 < _list.size()) {
_list[index + 1]->setFocus();
}
});
QObject::connect(field, &Ui::InputField::changed, [=] {
}, field->lifetime());
field->changes(
) | rpl::start_with_next([=] {
Ui::PostponeCall(crl::guard(field, [=] {
validateState();
}));
});
QObject::connect(field, &Ui::InputField::focused, [=] {
}, field->lifetime());
field->focusedChanges(
) | rpl::filter(rpl::mappers::_1) | rpl::start_with_next([=] {
_scrollToWidget.fire_copy(field);
});
QObject::connect(field, &Ui::InputField::tabbed, [=] {
}, field->lifetime());
field->tabbed(
) | rpl::start_with_next([=] {
const auto index = findField(field);
if (index + 1 < _list.size()) {
_list[index + 1]->setFocus();
} else {
_tabbed.fire({});
}
});
}, field->lifetime());
base::install_event_filter(field, [=](not_null<QEvent*> event) {
if (event->type() != QEvent::KeyPress
|| !field->getLastText().isEmpty()) {
@@ -927,9 +934,10 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
st::boxDividerLabel),
st::createPollLimitPadding));
connect(question, &Ui::InputField::tabbed, [=] {
question->tabbed(
) | rpl::start_with_next([=] {
options->focusFirst();
});
}, question->lifetime());
AddSkip(container);
AddSubsectionTitle(container, tr::lng_polls_create_settings());
@@ -975,9 +983,10 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
}
}, question->lifetime());
connect(solution, &Ui::InputField::tabbed, [=] {
solution->tabbed(
) | rpl::start_with_next([=] {
question->setFocus();
});
}, solution->lifetime());
quiz->setDisabled(_disabled & PollData::Flag::Quiz);
if (multiple) {
@@ -1009,12 +1018,12 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
const auto text = question->getLastText().trimmed();
return !text.isEmpty() && (text.size() <= kQuestionLimit);
};
connect(question, &Ui::InputField::submitted, [=] {
question->submits(
) | rpl::start_with_next([=] {
if (isValidQuestion()) {
options->focusFirst();
}
});
}, question->lifetime());
_setInnerFocus = [=] {
question->setFocusFast();

View File

@@ -54,7 +54,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/painter.h"
#include "ui/ui_utility.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/scroll_area.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/wrap/vertical_layout.h"
@@ -488,9 +488,16 @@ void EditCaptionBox::setupField() {
Core::App().settings().sendSubmitWay());
_field->setMaxHeight(st::defaultComposeFiles.caption.heightMax);
connect(_field, &Ui::InputField::submitted, [=] { save(); });
connect(_field, &Ui::InputField::cancelled, [=] { closeBox(); });
connect(_field, &Ui::InputField::resized, [=] { captionResized(); });
_field->submits(
) | rpl::start_with_next([=] { save(); }, _field->lifetime());
_field->cancelled(
) | rpl::start_with_next([=] {
closeBox();
}, _field->lifetime());
_field->heightChanges(
) | rpl::start_with_next([=] {
captionResized();
}, _field->lifetime());
_field->setMimeDataHook([=](
not_null<const QMimeData*> data,
Ui::InputField::MimeAction action) {
@@ -522,10 +529,11 @@ void EditCaptionBox::setInitialText() {
setCloseByOutsideClick(true);
}
});
connect(_field, &Ui::InputField::changed, [=] {
_field->changes(
) | rpl::start_with_next([=] {
_checkChangedTimer.callOnce(kChangesDebounceTimeout);
setCloseByOutsideClick(false);
});
}, _field->lifetime());
}
void EditCaptionBox::setupControls() {
@@ -622,9 +630,10 @@ void EditCaptionBox::setupDragArea() {
};
// Avoid both drag areas appearing at one time.
auto computeState = [=](const QMimeData *data) {
using DragState = Storage::MimeDataState;
const auto state = Storage::ComputeMimeDataState(data);
return (state == Storage::MimeDataState::PhotoFiles)
? Storage::MimeDataState::Image
return (state == DragState::PhotoFiles || state == DragState::Image)
? (_asFile ? DragState::Files : DragState::Image)
: state;
};
const auto areas = DragArea::SetupDragAreaToContainer(

View File

@@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text_utilities.h"
#include "ui/text/text_options.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/effects/panel_animation.h"
#include "ui/filter_icons.h"
@@ -619,11 +619,12 @@ void EditFilterBox(
nameEditing->custom = true;
}, box->lifetime());
QObject::connect(name, &Ui::InputField::changed, [=] {
name->changes(
) | rpl::start_with_next([=] {
if (!nameEditing->settingDefault) {
nameEditing->custom = true;
}
});
}, name->lifetime());
const auto updateDefaultTitle = [=](const Data::ChatFilter &filter) {
if (nameEditing->custom) {
return;

View File

@@ -26,7 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/controls/invite_link_label.h"
#include "ui/text/text_utilities.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/popup_menu.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/wrap/slide_wrap.h"

View File

@@ -21,10 +21,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/layers/generic_box.h"
#include "ui/text/text_utilities.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/fields/password_input.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/sent_code_field.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/wrap/fade_wrap.h"
#include "ui/painter.h"
#include "passport/passport_encryption.h"
@@ -306,15 +305,26 @@ void PasscodeBox::prepare() {
connect(_oldPasscode, &Ui::MaskedInputField::changed, [=] { oldChanged(); });
connect(_newPasscode, &Ui::MaskedInputField::changed, [=] { newChanged(); });
connect(_reenterPasscode, &Ui::MaskedInputField::changed, [=] { newChanged(); });
connect(_passwordHint, &Ui::InputField::changed, [=] { newChanged(); });
connect(_recoverEmail, &Ui::InputField::changed, [=] { emailChanged(); });
_passwordHint->changes(
) | rpl::start_with_next([=] {
newChanged();
}, _passwordHint->lifetime());
_recoverEmail->changes(
) | rpl::start_with_next([=] {
if (!_emailError.isEmpty()) {
_emailError = QString();
update();
}
}, _recoverEmail->lifetime());
const auto fieldSubmit = [=] { submit(); };
connect(_oldPasscode, &Ui::MaskedInputField::submitted, fieldSubmit);
connect(_newPasscode, &Ui::MaskedInputField::submitted, fieldSubmit);
connect(_reenterPasscode, &Ui::MaskedInputField::submitted, fieldSubmit);
connect(_passwordHint, &Ui::InputField::submitted, fieldSubmit);
connect(_recoverEmail, &Ui::InputField::submitted, fieldSubmit);
_passwordHint->submits(
) | rpl::start_with_next(fieldSubmit, _passwordHint->lifetime());
_recoverEmail->submits(
) | rpl::start_with_next(fieldSubmit, _recoverEmail->lifetime());
_recover->addClickHandler([=] { recoverByEmail(); });
@@ -1061,13 +1071,6 @@ void PasscodeBox::newChanged() {
}
}
void PasscodeBox::emailChanged() {
if (!_emailError.isEmpty()) {
_emailError = QString();
update();
}
}
void PasscodeBox::recoverByEmail() {
if (!_cloudFields.hasRecovery) {
Assert(_session != nullptr);
@@ -1189,8 +1192,12 @@ void RecoverBox::prepare() {
+ _recoverCode->height()
+ st::passcodeTextLine));
connect(_recoverCode, &Ui::InputField::changed, [=] { codeChanged(); });
connect(_recoverCode, &Ui::InputField::submitted, [=] { submit(); });
_recoverCode->changes(
) | rpl::start_with_next([=] {
codeChanged();
}, _recoverCode->lifetime());
_recoverCode->submits(
) | rpl::start_with_next([=] { submit(); }, _recoverCode->lifetime());
}
void RecoverBox::paintEvent(QPaintEvent *e) {

View File

@@ -90,7 +90,6 @@ private:
void closeReplacedBy();
void oldChanged();
void newChanged();
void emailChanged();
void save(bool force = false);
void badOldPasscode();
void recoverByEmail();

View File

@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/peer_list_box.h"
#include "history/history.h" // chatListNameSortKey.
#include "main/session/session_show.h"
#include "main/main_session.h"
#include "mainwidget.h"
@@ -396,6 +397,27 @@ void PeerListController::setSearchNoResultsText(const QString &text) {
}
}
void PeerListController::sortByName() {
auto keys = base::flat_map<PeerListRowId, QString>();
keys.reserve(delegate()->peerListFullRowsCount());
const auto key = [&](const PeerListRow &row) {
const auto id = row.id();
const auto i = keys.find(id);
if (i != end(keys)) {
return i->second;
}
const auto peer = row.peer();
const auto history = peer->owner().history(peer);
return keys.emplace(
id,
history->chatListNameSortKey()).first->second;
};
const auto predicate = [&](const PeerListRow &a, const PeerListRow &b) {
return (key(a).compare(key(b)) < 0);
};
delegate()->peerListSortRows(predicate);
}
base::unique_qptr<Ui::PopupMenu> PeerListController::rowContextMenu(
QWidget *parent,
not_null<PeerListRow*> row) {
@@ -741,8 +763,8 @@ int PeerListRow::paintNameIconGetWidth(
? st::dialogsVerifiedIconOver
: st::dialogsVerifiedIcon),
.premium = &(selected
? st::dialogsPremiumIconOver
: st::dialogsPremiumIcon),
? st::dialogsPremiumIcon.over
: st::dialogsPremiumIcon.icon),
.scam = &(selected ? st::dialogsScamFgOver : st::dialogsScamFg),
.premiumFg = &(selected
? st::dialogsVerifiedIconBgOver

View File

@@ -560,6 +560,8 @@ protected:
delegate()->peerListSetSearchNoResults(std::move(noResults));
}
void sortByName();
private:
PeerListDelegate *_delegate = nullptr;
std::unique_ptr<PeerListSearchController> _searchController = nullptr;

View File

@@ -594,25 +594,6 @@ void ContactsBoxController::sort() {
}
}
void ContactsBoxController::sortByName() {
auto keys = base::flat_map<PeerListRowId, QString>();
keys.reserve(delegate()->peerListFullRowsCount());
const auto key = [&](const PeerListRow &row) {
const auto id = row.id();
const auto i = keys.find(id);
if (i != end(keys)) {
return i->second;
}
const auto peer = row.peer();
const auto history = peer->owner().history(peer);
return keys.emplace(id, history->chatListNameSortKey()).first->second;
};
const auto predicate = [&](const PeerListRow &a, const PeerListRow &b) {
return (key(a).compare(key(b)) < 0);
};
delegate()->peerListSortRows(predicate);
}
void ContactsBoxController::sortByOnline() {
const auto now = base::unixtime::now();
const auto key = [&](const PeerListRow &row) {

View File

@@ -192,7 +192,6 @@ protected:
private:
void sort();
void sortByName();
void sortByOnline();
void rebuildRows();
void checkForEmptyRows();

View File

@@ -13,7 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/vertical_layout.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/text/format_values.h" // Ui::FormatPhone
#include "ui/text/text_utilities.h"
#include "info/profile/info_profile_cover.h"
@@ -239,8 +239,8 @@ void Controller::initNameFields(
_save();
}
};
QObject::connect(first, &Ui::InputField::submitted, submit);
QObject::connect(last, &Ui::InputField::submitted, submit);
first->submits() | rpl::start_with_next(submit, first->lifetime());
last->submits() | rpl::start_with_next(submit, last->lifetime());
first->setMaxLength(Ui::EditPeer::kMaxUserFirstLastName);
first->setMaxLength(Ui::EditPeer::kMaxUserFirstLastName);
}

View File

@@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/peers/edit_forum_topic_box.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/shadow.h"
#include "ui/effects/emoji_fly_animation.h"
#include "ui/abstract_button.h"
@@ -465,15 +465,13 @@ void EditForumTopicBox(
ChooseNextColorId(current.colorId, state->otherColorIds),
};
});
base::qt_signal_producer(
title,
&Ui::InputField::changed
title->changes(
) | rpl::start_with_next([=] {
state->defaultIcon = DefaultIcon{
title->getLastText().trimmed(),
state->defaultIcon.current().colorId,
};
}, box->lifetime());
}, title->lifetime());
if (!topic || !topic->isGeneral()) {
Settings::AddDividerText(

View File

@@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/checkbox.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/box_content_divider.h"
#include "ui/layers/generic_box.h"
#include "ui/toast/toast.h"
@@ -384,8 +384,11 @@ void EditAdminBox::prepare() {
if (!_saveCallback) {
return;
} else if (_addAsAdmin && !_addAsAdmin->checked()) {
const auto weak = Ui::MakeWeak(this);
AddBotToGroup(user(), peer(), _addingBot->token);
getDelegate()->hideLayer();
if (const auto strong = weak.data()) {
strong->closeBox();
}
return;
} else if (_addingBot && !_addingBot->existing) {
const auto phrase = peer()->isBroadcast()
@@ -461,13 +464,14 @@ not_null<Ui::InputField*> EditAdminBox::addRankInput(
st::rightsAboutMargin);
result->setMaxLength(kAdminRoleLimit);
result->setInstantReplaces(Ui::InstantReplaces::TextOnly());
connect(result, &Ui::InputField::changed, [=] {
result->changes(
) | rpl::start_with_next([=] {
const auto text = result->getLastText();
const auto removed = TextUtilities::RemoveEmoji(text);
if (removed != text) {
result->setText(removed);
}
});
}, result->lifetime());
container->add(
object_ptr<Ui::FlatLabel>(

View File

@@ -51,7 +51,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text_utilities.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/box_content_divider.h"
#include "ui/wrap/padding_wrap.h"
@@ -519,10 +519,10 @@ object_ptr<Ui::RpWidget> Controller::createTitleEdit() {
result->entity(),
&_peer->session());
QObject::connect(
result->entity(),
&Ui::InputField::submitted,
[=] { submitTitle(); });
result->entity()->submits(
) | rpl::start_with_next([=] {
submitTitle();
}, result->entity()->lifetime());
_controls.title = result->entity();
return result;
@@ -555,10 +555,10 @@ object_ptr<Ui::RpWidget> Controller::createDescriptionEdit() {
result->entity(),
&_peer->session());
QObject::connect(
result->entity(),
&Ui::InputField::submitted,
[=] { submitDescription(); });
result->entity()->submits(
) | rpl::start_with_next([=] {
submitDescription();
}, result->entity()->lifetime());
_controls.description = result->entity();
return result;

View File

@@ -51,13 +51,14 @@ constexpr auto kForceDisableTooltipDuration = 3 * crl::time(1000);
}
[[nodiscard]] auto NestedRestrictionLabelsList(
Data::RestrictionsSetOptions options) {
Data::RestrictionsSetOptions options)
-> std::vector<NestedEditFlagsLabels<ChatRestrictions>> {
using Flag = ChatRestriction;
auto first = std::vector<RestrictionLabel>{
{ Flag::SendOther, tr::lng_rights_chat_send_text(tr::now) },
};
auto inner = std::vector<RestrictionLabel>{
auto media = std::vector<RestrictionLabel>{
{ Flag::SendPhotos, tr::lng_rights_chat_photos(tr::now) },
{ Flag::SendVideos, tr::lng_rights_chat_videos(tr::now) },
{ Flag::SendVideoMessages, tr::lng_rights_chat_video_messages(tr::now) },
@@ -85,9 +86,64 @@ constexpr auto kForceDisableTooltipDuration = 3 * crl::time(1000);
&RestrictionLabel::flags),
end(second));
}
return std::vector<NestedEditFlagsLabels<ChatRestrictions>>{
return {
{ std::nullopt, std::move(first) },
{ tr::lng_rights_chat_send_media(), std::move(inner) },
{ tr::lng_rights_chat_send_media(), std::move(media) },
{ std::nullopt, std::move(second) },
};
}
[[nodiscard]] auto NestedAdminRightLabels(
Data::AdminRightsSetOptions options)
-> std::vector<NestedEditFlagsLabels<ChatAdminRights>> {
using Flag = ChatAdminRight;
if (options.isGroup) {
auto result = std::vector<AdminRightLabel>{
{ Flag::ChangeInfo, tr::lng_rights_group_info(tr::now) },
{ Flag::DeleteMessages, tr::lng_rights_group_delete(tr::now) },
{ Flag::BanUsers, tr::lng_rights_group_ban(tr::now) },
{ Flag::InviteByLinkOrAdd, options.anyoneCanAddMembers
? tr::lng_rights_group_invite_link(tr::now)
: tr::lng_rights_group_invite(tr::now) },
{ Flag::ManageTopics, tr::lng_rights_group_topics(tr::now) },
{ Flag::PinMessages, tr::lng_rights_group_pin(tr::now) },
{ Flag::ManageCall, tr::lng_rights_group_manage_calls(tr::now) },
{ Flag::Anonymous, tr::lng_rights_group_anonymous(tr::now) },
{ Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) },
};
if (!options.isForum) {
result.erase(
ranges::remove(
result,
Flag::ManageTopics | Flag(),
&AdminRightLabel::flags),
end(result));
}
return { { std::nullopt, std::move(result) } };
}
auto first = std::vector<AdminRightLabel>{
{ Flag::ChangeInfo, tr::lng_rights_channel_info(tr::now) },
};
auto messages = std::vector<AdminRightLabel>{
{ Flag::PostMessages, tr::lng_rights_channel_post(tr::now) },
{ Flag::EditMessages, tr::lng_rights_channel_edit(tr::now) },
{ Flag::DeleteMessages, tr::lng_rights_channel_delete(tr::now) },
};
auto stories = std::vector<AdminRightLabel>{
{ Flag::PostStories, tr::lng_rights_channel_post_stories(tr::now) },
{ Flag::EditStories, tr::lng_rights_channel_edit_stories(tr::now) },
{ Flag::DeleteStories, tr::lng_rights_channel_delete_stories(tr::now) },
};
auto second = std::vector<AdminRightLabel>{
{ Flag::InviteByLinkOrAdd, tr::lng_rights_group_invite(tr::now) },
{ Flag::ManageCall, tr::lng_rights_channel_manage_calls(tr::now) },
{ Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) },
};
return {
{ std::nullopt, std::move(first) },
{ tr::lng_rights_channel_manage(), std::move(messages) },
{ tr::lng_rights_channel_manage_stories(), std::move(stories) },
{ std::nullopt, std::move(second) },
};
}
@@ -319,16 +375,15 @@ not_null<Ui::RpWidget*> AddInnerToggle(
button->geometryValue(
) | rpl::start_with_next([=](const QRect &r) {
const auto w = st::rightsButtonToggleWidth;
constexpr auto kLineWidth = int(1);
toggleButton->setGeometry(
r.x() + r.width() - w,
r.y(),
w,
r.height());
separator->setGeometry(
toggleButton->x() - kLineWidth,
toggleButton->x() - st::lineWidth,
r.y() + (r.height() - separatorHeight) / 2,
kLineWidth,
st::lineWidth,
separatorHeight);
}, toggleButton->lifetime());
@@ -1032,42 +1087,11 @@ std::vector<RestrictionLabel> RestrictionLabels(
std::vector<AdminRightLabel> AdminRightLabels(
Data::AdminRightsSetOptions options) {
using Flag = ChatAdminRight;
if (options.isGroup) {
auto result = std::vector<AdminRightLabel>{
{ Flag::ChangeInfo, tr::lng_rights_group_info(tr::now) },
{ Flag::DeleteMessages, tr::lng_rights_group_delete(tr::now) },
{ Flag::BanUsers, tr::lng_rights_group_ban(tr::now) },
{ Flag::InviteByLinkOrAdd, options.anyoneCanAddMembers
? tr::lng_rights_group_invite_link(tr::now)
: tr::lng_rights_group_invite(tr::now) },
{ Flag::ManageTopics, tr::lng_rights_group_topics(tr::now) },
{ Flag::PinMessages, tr::lng_rights_group_pin(tr::now) },
{ Flag::ManageCall, tr::lng_rights_group_manage_calls(tr::now) },
{ Flag::Anonymous, tr::lng_rights_group_anonymous(tr::now) },
{ Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) },
};
if (!options.isForum) {
result.erase(
ranges::remove(
result,
Flag::ManageTopics | Flag(),
&AdminRightLabel::flags),
end(result));
}
return result;
} else {
return {
{ Flag::ChangeInfo, tr::lng_rights_channel_info(tr::now) },
{ Flag::PostMessages, tr::lng_rights_channel_post(tr::now) },
{ Flag::EditMessages, tr::lng_rights_channel_edit(tr::now) },
{ Flag::DeleteMessages, tr::lng_rights_channel_delete(tr::now) },
{ Flag::InviteByLinkOrAdd, tr::lng_rights_group_invite(tr::now) },
{ Flag::ManageCall, tr::lng_rights_channel_manage_calls(tr::now) },
{ Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) }
};
auto result = std::vector<AdminRightLabel>();
for (const auto &[_, r] : NestedAdminRightLabels(options)) {
result.insert(result.end(), r.begin(), r.end());
}
return result;
}
EditFlagsControl<ChatRestrictions> CreateEditRestrictions(
@@ -1108,7 +1132,7 @@ EditFlagsControl<ChatAdminRights> CreateEditAdminRights(
rights,
{
.header = std::move(header),
.labels = { { std::nullopt, AdminRightLabels(options) } },
.labels = NestedAdminRightLabels(options),
.disabledMessages = std::move(disabledMessages),
});
result.widget = std::move(widget);

View File

@@ -32,7 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/controls/userpic_button.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/box_content_divider.h"
#include "ui/wrap/padding_wrap.h"

View File

@@ -48,19 +48,6 @@ struct InfographicDescriptor {
bool complexRatio = false;
};
[[nodiscard]] rpl::producer<> BoxShowFinishes(not_null<Ui::GenericBox*> box) {
const auto singleShot = box->lifetime().make_state<rpl::lifetime>();
const auto showFinishes = singleShot->make_state<rpl::event_stream<>>();
box->setShowFinishedCallback([=] {
showFinishes->fire({});
singleShot->destroy();
box->setShowFinishedCallback(nullptr);
});
return showFinishes->events();
}
void AddSubsectionTitle(
not_null<Ui::VerticalLayout*> container,
rpl::producer<QString> text) {
@@ -423,8 +410,9 @@ void SimpleLimitBox(
Settings::AddSkip(top, st::premiumInfographicPadding.top());
Ui::Premium::AddBubbleRow(
top,
st::defaultPremiumBubble,
BoxShowFinishes(box),
descriptor.defaultLimit,
0,
descriptor.current,
descriptor.premiumLimit,
premiumPossible,
@@ -783,16 +771,18 @@ void FilterLinksLimitBox(
void FiltersLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session) {
not_null<Main::Session*> session,
std::optional<int> filtersCountOverride) {
const auto premium = session->premium();
const auto premiumPossible = session->premiumPossible();
const auto limits = Data::PremiumLimits(session);
const auto defaultLimit = float64(limits.dialogFiltersDefault());
const auto premiumLimit = float64(limits.dialogFiltersPremium());
const auto current = float64(ranges::count_if(
const auto cloud = int(ranges::count_if(
session->data().chatsFilters().list(),
[](const Data::ChatFilter &f) { return f.id() != FilterId(); }));
const auto current = float64(filtersCountOverride.value_or(cloud));
auto text = rpl::combine(
tr::lng_filters_limit1(
@@ -1092,6 +1082,7 @@ void AccountsLimitBox(
Settings::AddSkip(top, st::premiumInfographicPadding.top());
Ui::Premium::AddBubbleRow(
top,
st::defaultPremiumBubble,
BoxShowFinishes(box),
0,
current,

View File

@@ -42,7 +42,8 @@ void FilterLinksLimitBox(
not_null<Main::Session*> session);
void FiltersLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session);
not_null<Main::Session*> session,
std::optional<int> filtersCountOverride);
void ShareableFiltersLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session);

View File

@@ -28,12 +28,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/call_delayed.h"
#include "boxes/premium_limits_box.h"
#include "boxes/premium_preview_box.h"
#include "ui/boxes/confirm_box.h"
#include "ui/effects/animations.h"
#include "ui/effects/scroll_content_shadow.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/popup_menu.h"
#include "ui/wrap/vertical_layout.h"
@@ -42,9 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/chat/attach/attach_album_preview.h"
#include "ui/chat/attach/attach_single_file_preview.h"
#include "ui/chat/attach/attach_single_media_preview.h"
#include "ui/text/format_values.h"
#include "ui/grouped_layout.h"
#include "ui/text/text_options.h"
#include "ui/toast/toast.h"
#include "ui/controls/emoji_button.h"
#include "ui/painter.h"
@@ -54,16 +50,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_premium_limits.h"
#include "data/stickers/data_stickers.h"
#include "data/stickers/data_custom_emoji.h"
#include "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 "styles/style_chat.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_info.h"
#include "styles/style_menu_icons.h"
#include <QtCore/QMimeData>
@@ -74,10 +67,14 @@ constexpr auto kMaxMessageLength = 4096;
using Ui::SendFilesWay;
inline bool CanAddUrls(const QList<QUrl> &urls) {
[[nodiscard]] inline bool CanAddUrls(const QList<QUrl> &urls) {
return !urls.isEmpty() && ranges::all_of(urls, &QUrl::isLocalFile);
}
[[nodiscard]] bool CanAddFiles(not_null<const QMimeData*> data) {
return data->hasImage() || CanAddUrls(Core::ReadMimeUrls(data));
}
void FileDialogCallback(
FileDialog::OpenResult &&result,
Fn<bool(const Ui::PreparedList&)> checkResult,
@@ -445,13 +442,15 @@ void SendFilesBox::setupDragArea() {
auto computeState = [=](const QMimeData *data) {
using DragState = Storage::MimeDataState;
const auto state = Storage::ComputeMimeDataState(data);
return (state == DragState::PhotoFiles)
? DragState::Image
return (state == DragState::PhotoFiles || state == DragState::Image)
? (_sendWay.current().sendImagesAsPhotos()
? DragState::Image
: DragState::Files)
: state;
};
const auto areas = DragArea::SetupDragAreaToContainer(
this,
[=](not_null<const QMimeData*> d) { return canAddFiles(d); },
CanAddFiles,
[=](bool f) { _caption->setAcceptDrops(f); },
[=] { updateControlsGeometry(); },
std::move(computeState));
@@ -1031,22 +1030,26 @@ void SendFilesBox::setupCaption() {
Core::App().settings().sendSubmitWay());
_caption->setMaxLength(kMaxMessageLength);
connect(_caption, &Ui::InputField::resized, [=] {
_caption->heightChanges(
) | rpl::start_with_next([=] {
captionResized();
});
connect(_caption, &Ui::InputField::submitted, [=](
Qt::KeyboardModifiers modifiers) {
}, _caption->lifetime());
_caption->submits(
) | rpl::start_with_next([=](Qt::KeyboardModifiers modifiers) {
const auto ctrlShiftEnter = modifiers.testFlag(Qt::ShiftModifier)
&& (modifiers.testFlag(Qt::ControlModifier)
|| modifiers.testFlag(Qt::MetaModifier));
send({}, ctrlShiftEnter);
});
connect(_caption, &Ui::InputField::cancelled, [=] { closeBox(); });
}, _caption->lifetime());
_caption->cancelled(
) | rpl::start_with_next([=] {
closeBox();
}, _caption->lifetime());
_caption->setMimeDataHook([=](
not_null<const QMimeData*> data,
Ui::InputField::MimeAction action) {
if (action == Ui::InputField::MimeAction::Check) {
return canAddFiles(data);
return CanAddFiles(data);
} else if (action == Ui::InputField::MimeAction::Insert) {
return addFiles(data);
}
@@ -1142,10 +1145,6 @@ void SendFilesBox::captionResized() {
update();
}
bool SendFilesBox::canAddFiles(not_null<const QMimeData*> data) const {
return data->hasImage() || CanAddUrls(Core::ReadMimeUrls(data));
}
bool SendFilesBox::addFiles(not_null<const QMimeData*> data) {
const auto premium = _show->session().premium();
auto list = [&] {

View File

@@ -213,7 +213,6 @@ private:
void updateControlsGeometry();
void updateCaptionPlaceholder();
bool canAddFiles(not_null<const QMimeData*> data) const;
bool addFiles(not_null<const QMimeData*> data);
bool addFiles(Ui::PreparedList list);
void addFile(Ui::PreparedFile &&file);

View File

@@ -19,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/scroll_area.h"
#include "ui/wrap/slide_wrap.h"
@@ -144,7 +144,7 @@ void RenameBox(not_null<Ui::GenericBox*> box) {
Core::App().settings().setCustomDeviceModel(result);
Core::App().saveSettingsDelayed();
};
QObject::connect(name, &Ui::InputField::submitted, submit);
name->submits() | rpl::start_with_next(submit, name->lifetime());
box->addButton(tr::lng_settings_save(), submit);
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
}

View File

@@ -18,9 +18,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/toast/toast.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/multi_select.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/popup_menu.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/text/text_options.h"
@@ -227,9 +226,8 @@ void ShareBox::prepareCommentField() {
const auto field = _comment->entity();
connect(field, &Ui::InputField::submitted, [=] {
submit({});
});
field->submits(
) | rpl::start_with_next([=] { submit({}); }, field->lifetime());
if (const auto show = uiShow(); show->valid()) {
InitMessageFieldHandlers(
_descriptor.session,
@@ -250,6 +248,8 @@ void ShareBox::prepareCommentField() {
void ShareBox::prepare() {
prepareCommentField();
setCloseByOutsideClick(false);
_select->resizeToWidth(st::boxWideWidth);
Ui::SendPendingMoveResizeEvents(_select);
@@ -602,7 +602,7 @@ void ShareBox::submitWhenOnline() {
submit(Api::DefaultSendWhenOnlineOptions());
}
void ShareBox::copyLink() {
void ShareBox::copyLink() const {
if (const auto onstack = _descriptor.copyCallback) {
onstack();
}

View File

@@ -119,7 +119,7 @@ private:
void submitSilent();
void submitScheduled();
void submitWhenOnline();
void copyLink();
void copyLink() const;
bool searchByUsername(bool useCache = false);
SendMenu::Type sendMenuType() const;

View File

@@ -31,7 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/ripple_animation.h"
#include "ui/effects/slide_animation.h"
#include "ui/widgets/discrete_sliders.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/image/image.h"
#include "ui/cached_round_corners.h"
#include "ui/painter.h"
@@ -53,6 +53,22 @@ constexpr auto kArchivedLimitFirstRequest = 10;
constexpr auto kArchivedLimitPerPage = 30;
constexpr auto kHandleMegagroupSetAddressChangeTimeout = crl::time(1000);
[[nodiscard]] QString FillSetTitle(
not_null<StickersSet*> set,
int maxNameWidth,
int *outTitleWidth) {
auto result = set->title;
auto titleWidth = st::contactsNameStyle.font->width(result);
if (titleWidth > maxNameWidth) {
result = st::contactsNameStyle.font->elided(result, maxNameWidth);
titleWidth = st::contactsNameStyle.font->width(result);
}
if (outTitleWidth) {
*outTitleWidth = titleWidth;
}
return result;
}
} // namespace
class StickersBox::CounterWidget : public Ui::RpWidget {
@@ -98,22 +114,25 @@ public:
void updateRows(); // refresh only pack cover stickers
bool appendSet(not_null<StickersSet*> set);
StickersSetsOrder getOrder() const;
StickersSetsOrder getFullOrder() const;
StickersSetsOrder getRemovedSets() const;
StickersSetsOrder order() const;
StickersSetsOrder fullOrder() const;
StickersSetsOrder removedSets() const;
void setFullOrder(const StickersSetsOrder &order);
void setRemovedSets(const StickersSetsOrder &removed);
void setRowRemovedBySetId(uint64 setId, bool removed);
void setInstallSetCallback(Fn<void(uint64 setId)> callback) {
_installSetCallback = std::move(callback);
}
void setRemoveSetCallback(Fn<void(uint64 setId)> callback) {
_removeSetCallback = std::move(callback);
}
void setLoadMoreCallback(Fn<void()> callback) {
_loadMoreCallback = std::move(callback);
}
void setMinHeight(int newWidth, int minHeight);
int getVisibleTop() const {
return _visibleTop;
}
@@ -151,13 +170,13 @@ private:
int32 pixh);
~Row();
bool isRecentSet() const;
bool isMasksSet() const;
bool isEmojiSet() const;
bool isWebm() const;
bool isInstalled() const;
bool isUnread() const;
bool isArchived() const;
[[nodiscard]] bool isRecentSet() const;
[[nodiscard]] bool isMasksSet() const;
[[nodiscard]] bool isEmojiSet() const;
[[nodiscard]] bool isWebm() const;
[[nodiscard]] bool isInstalled() const;
[[nodiscard]] bool isUnread() const;
[[nodiscard]] bool isArchived() const;
const not_null<StickersSet*> set;
DocumentData *sticker = nullptr;
@@ -212,7 +231,11 @@ private:
void setPressed(SelectedRow pressed);
void setup();
QRect relativeButtonRect(bool removeButton, bool installedSet) const;
void ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton);
void ensureRipple(
const style::RippleAnimation &st,
QImage mask,
bool removeButton,
bool installedSet);
bool shiftingAnimationCallback(crl::time now);
void paintRow(Painter &p, not_null<Row*> row, int index);
@@ -237,10 +260,6 @@ private:
void rebuildAppendSet(not_null<StickersSet*> set);
void fillSetCover(not_null<StickersSet*> set, DocumentData **outSticker, int *outWidth, int *outHeight) const;
int fillSetCount(not_null<StickersSet*> set) const;
[[nodiscard]] QString fillSetTitle(
not_null<StickersSet*> set,
int maxNameWidth,
int *outTitleWidth) const;
[[nodiscard]] Data::StickersSetFlags fillSetFlags(
not_null<StickersSet*> set) const;
void rebuildMegagroupSet();
@@ -270,6 +289,7 @@ private:
Ui::Animations::Basic _shiftingAnimation;
Fn<void(uint64 setId)> _installSetCallback;
Fn<void(uint64 setId)> _removeSetCallback;
Fn<void()> _loadMoreCallback;
int _visibleTop = 0;
@@ -598,17 +618,43 @@ void StickersBox::prepare() {
_attached.widget()->hide();
}
const auto installCallback = [=](uint64 setId) { installSet(setId); };
if (_featured.widget()) {
_featured.widget()->setInstallSetCallback(installCallback);
}
if (_archived.widget()) {
_archived.widget()->setInstallSetCallback(installCallback);
_archived.widget()->setLoadMoreCallback([=] { loadMoreArchived(); });
}
if (_attached.widget()) {
_attached.widget()->setInstallSetCallback(installCallback);
_attached.widget()->setLoadMoreCallback([=] { showAttachedStickers(); });
{
const auto installCallback = [=](uint64 setId) { installSet(setId); };
const auto markAsInstalledCallback = [=](uint64 setId) {
if (_installed.widget()) {
_installed.widget()->setRowRemovedBySetId(setId, false);
}
if (_featured.widget()) {
_featured.widget()->setRowRemovedBySetId(setId, false);
}
};
const auto markAsRemovedCallback = [=](uint64 setId) {
if (_installed.widget()) {
_installed.widget()->setRowRemovedBySetId(setId, true);
}
if (_featured.widget()) {
_featured.widget()->setRowRemovedBySetId(setId, true);
}
};
if (const auto installed = _installed.widget()) {
installed->setInstallSetCallback(markAsInstalledCallback);
installed->setRemoveSetCallback(markAsRemovedCallback);
}
if (const auto featured = _featured.widget()) {
featured->setInstallSetCallback([=](uint64 setId) {
markAsInstalledCallback(setId);
installCallback(setId);
});
featured->setRemoveSetCallback(markAsRemovedCallback);
}
if (const auto archived = _archived.widget()) {
archived->setInstallSetCallback(installCallback);
archived->setLoadMoreCallback([=] { loadMoreArchived(); });
}
if (const auto attached = _attached.widget()) {
attached->setInstallSetCallback(installCallback);
attached->setLoadMoreCallback([=] { showAttachedStickers(); });
}
}
if (_megagroupSet) {
@@ -634,7 +680,7 @@ void StickersBox::prepare() {
} else { // _section == Section::Featured
_tab = &_featured;
}
setInnerWidget(_tab->takeWidget(), getTopSkip());
setInnerWidget(_tab->takeWidget(), topSkip());
setDimensions(st::boxWideWidth, st::boxMaxListHeight);
session().data().stickers().updated(_isEmoji
@@ -757,7 +803,7 @@ void StickersBox::paintEvent(QPaintEvent *e) {
Painter p(this);
if (_slideAnimation) {
_slideAnimation->paintFrame(p, 0, getTopSkip(), width());
_slideAnimation->paintFrame(p, 0, topSkip(), width());
if (!_slideAnimation->animating()) {
_slideAnimation.reset();
setInnerVisible(true);
@@ -774,7 +820,7 @@ void StickersBox::updateTabsGeometry() {
_tabs->resizeToWidth(_tabIndices.size() * width() / maxTabs);
_unreadBadge->setVisible(_tabIndices.contains(Section::Featured));
setInnerTopSkip(getTopSkip());
setInnerTopSkip(topSkip());
auto featuredLeft = width() / maxTabs;
auto featuredRight = 2 * width() / maxTabs;
@@ -790,7 +836,7 @@ void StickersBox::updateTabsGeometry() {
_tabs->moveToLeft(0, 0);
}
int StickersBox::getTopSkip() const {
int StickersBox::topSkip() const {
return _tabs ? (_tabs->height() - st::lineWidth) : 0;
}
@@ -819,8 +865,8 @@ void StickersBox::switchTab() {
}
if (_tab == &_installed) {
_localOrder = _tab->widget()->getFullOrder();
_localRemoved = _tab->widget()->getRemovedSets();
_localOrder = _tab->widget()->fullOrder();
_localRemoved = _tab->widget()->removedSets();
}
auto wasCache = grabContentCache();
auto wasIndex = _tab->index();
@@ -831,12 +877,12 @@ void StickersBox::switchTab() {
_tab->returnWidget(std::move(widget));
_tab = newTab;
_section = newSection;
setInnerWidget(_tab->takeWidget(), getTopSkip());
setInnerWidget(_tab->takeWidget(), topSkip());
_tabs->raise();
_unreadBadge->raise();
_tab->widget()->show();
rebuildList();
scrollToY(_tab->getScrollTop());
scrollToY(_tab->scrollTop());
setInnerVisible(true);
auto nowCache = grabContentCache();
auto nowIndex = _tab->index();
@@ -901,7 +947,7 @@ void StickersBox::installSet(uint64 setId) {
}
void StickersBox::installDone(
const MTPmessages_StickerSetInstallResult &result) {
const MTPmessages_StickerSetInstallResult &result) const {
if (result.type() == mtpc_messages_stickerSetInstallResultArchive) {
session().data().stickers().applyArchivedResult(
result.c_messages_stickerSetInstallResultArchive());
@@ -998,12 +1044,12 @@ void StickersBox::rebuildList(Tab *tab) {
tab = _tab;
}
if ((tab == &_installed) || (tab == &_masks)) {
_localOrder = tab->widget()->getFullOrder();
_localRemoved = tab->widget()->getRemovedSets();
if ((tab == &_installed) || (tab == &_masks) || (_tab == &_featured)) {
_localOrder = tab->widget()->fullOrder();
_localRemoved = tab->widget()->removedSets();
}
tab->widget()->rebuild(_isMasks);
if ((tab == &_installed) || (tab == &_masks)) {
if ((tab == &_installed) || (tab == &_masks) || (_tab == &_featured)) {
tab->widget()->setFullOrder(_localOrder);
}
tab->widget()->setRemovedSets(_localRemoved);
@@ -1030,14 +1076,14 @@ void StickersBox::saveChanges() {
}
if (installed) {
session().api().saveStickerSets(
installed->getOrder(),
installed->getRemovedSets(),
installed->order(),
installed->removedSets(),
Data::StickersType::Stickers);
}
if (masks) {
session().api().saveStickerSets(
masks->getOrder(),
masks->getRemovedSets(),
masks->order(),
masks->removedSets(),
Data::StickersType::Masks);
}
}
@@ -1056,7 +1102,7 @@ const Data::StickersSetsOrder &StickersBox::archivedSetsOrder() const {
: session().data().stickers().archivedMaskSetsOrder();
}
Data::StickersSetsOrder &StickersBox::archivedSetsOrderRef() {
Data::StickersSetsOrder &StickersBox::archivedSetsOrderRef() const {
return !_isMasks
? session().data().stickers().archivedSetsOrderRef()
: session().data().stickers().archivedMaskSetsOrderRef();
@@ -1594,6 +1640,12 @@ void StickersBox::Inner::paintFakeButton(Painter &p, not_null<Row*> row, int ind
const auto textWidth = _installedWidth;
const auto &text = _installedText;
_inactiveButtonBg.paint(p, myrtlrect(rect));
if (row->ripple) {
row->ripple->paint(p, rect.x(), rect.y(), width());
if (row->ripple->empty()) {
row->ripple.reset();
}
}
p.setFont(st.font);
p.setPen(st.textFg);
p.drawTextLeft(rect.x() - (st.width / 2), rect.y() + st.textTop, width(), text, textWidth);
@@ -1673,16 +1725,27 @@ void StickersBox::Inner::setActionDown(int newActionDown) {
if (row->removed) {
auto rippleSize = QSize(_undoWidth - st::stickersUndoRemove.width, st::stickersUndoRemove.height);
auto rippleMask = Ui::RippleAnimation::RoundRectMask(rippleSize, st::roundRadiusLarge);
ensureRipple(st::stickersUndoRemove.ripple, std::move(rippleMask), removeButton);
ensureRipple(st::stickersUndoRemove.ripple, std::move(rippleMask), removeButton, false);
} else {
auto rippleSize = st::stickersRemove.rippleAreaSize;
auto rippleMask = Ui::RippleAnimation::EllipseMask(QSize(rippleSize, rippleSize));
ensureRipple(st::stickersRemove.ripple, std::move(rippleMask), removeButton);
ensureRipple(st::stickersRemove.ripple, std::move(rippleMask), removeButton, false);
}
} else if (!row->isInstalled() || row->isArchived() || row->removed) {
auto rippleSize = QSize(_addWidth - st::stickersTrendingAdd.width, st::stickersTrendingAdd.height);
auto rippleMask = Ui::RippleAnimation::RoundRectMask(rippleSize, st::roundRadiusLarge);
ensureRipple(st::stickersTrendingAdd.ripple, std::move(rippleMask), removeButton);
} else {
const auto installedSet = row->isInstalled()
&& !row->isArchived()
&& !row->removed;
const auto &st = installedSet
? st::stickersTrendingInstalled
: st::stickersTrendingAdd;
auto rippleMask = Ui::RippleAnimation::RoundRectMask(
QSize(_addWidth - st.width, st.height),
st::roundRadiusLarge);
ensureRipple(
st.ripple,
std::move(rippleMask),
removeButton,
installedSet);
}
}
if (row->ripple) {
@@ -1747,9 +1810,14 @@ void StickersBox::Inner::setPressed(SelectedRow pressed) {
}
}
void StickersBox::Inner::ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton) {
_rows[_actionDown]->ripple = std::make_unique<Ui::RippleAnimation>(st, std::move(mask), [this, index = _actionDown, removeButton] {
update(myrtlrect(relativeButtonRect(removeButton, false).translated(0, _itemsTop + index * _rowHeight)));
void StickersBox::Inner::ensureRipple(
const style::RippleAnimation &st,
QImage mask,
bool removeButton,
bool installedSet) {
const auto dy = _itemsTop + _actionDown * _rowHeight;
_rows[_actionDown]->ripple = std::make_unique<Ui::RippleAnimation>(st, std::move(mask), [=] {
update(myrtlrect(relativeButtonRect(removeButton, installedSet).translated(0, dy)));
});
}
@@ -1812,7 +1880,7 @@ void StickersBox::Inner::updateSelected() {
selected = selectedIndex;
local.setY(local.y() - _itemsTop - selectedIndex * _rowHeight);
const auto row = _rows[selectedIndex].get();
if (!_megagroupSet && (_isInstalledTab || !row->isInstalled() || row->isArchived() || row->removed)) {
if (!_megagroupSet && (_isInstalledTab || (_section == Section::Featured) || !row->isInstalled() || row->isArchived() || row->removed)) {
auto removeButton = (_isInstalledTab && !row->removed);
auto rect = myrtlrect(relativeButtonRect(removeButton, false));
actionSel = rect.contains(local) ? selectedIndex : -1;
@@ -1857,7 +1925,7 @@ float64 StickersBox::Inner::aboveShadowOpacity() const {
auto dx = 0;
auto dy = qAbs(_above * _rowHeight + qRound(_rows[_above]->yadd.current()) - _started * _rowHeight);
return qMin((dx + dy) * 2. / _rowHeight, 1.);
return qMin((dx + dy) * 2. / _rowHeight, 1.);
}
void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
@@ -1868,10 +1936,11 @@ void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
_mouse = e->globalPos();
updateSelected();
if (_actionDown == _actionSel && _actionSel >= 0) {
if (_isInstalledTab) {
setRowRemoved(_actionDown, !_rows[_actionDown]->removed);
} else if (_installSetCallback) {
_installSetCallback(_rows[_actionDown]->set->id);
const auto callback = _rows[_actionDown]->removed
? _installSetCallback
: _removeSetCallback;
if (callback) {
callback(_rows[_actionDown]->set->id);
}
} else if (_dragging >= 0) {
_rows[_dragging]->yadd.start(0.);
@@ -1921,6 +1990,13 @@ void StickersBox::Inner::saveGroupSet() {
}
}
void StickersBox::Inner::setRowRemovedBySetId(uint64 setId, bool removed) {
const auto index = getRowIndex(setId);
if (index >= 0) {
setRowRemoved(index, removed);
}
}
void StickersBox::Inner::setRowRemoved(int index, bool removed) {
auto &row = _rows[index];
if (row->removed != removed) {
@@ -2114,7 +2190,7 @@ void StickersBox::Inner::rebuildMegagroupSet() {
auto removed = false;
auto maxNameWidth = countMaxNameWidth(!_isInstalledTab);
auto titleWidth = 0;
auto title = fillSetTitle(set, maxNameWidth, &titleWidth);
auto title = FillSetTitle(set, maxNameWidth, &titleWidth);
if (!_megagroupSelectedSet
|| _megagroupSelectedSet->set->id != set->id) {
_megagroupSetField->setText(set->shortName);
@@ -2217,11 +2293,6 @@ void StickersBox::Inner::setMegagroupSelectedSet(
updateSelected();
}
void StickersBox::Inner::setMinHeight(int newWidth, int minHeight) {
_minHeight = minHeight;
updateSize(newWidth);
}
void StickersBox::Inner::updateSize(int newWidth) {
auto naturalHeight = _itemsTop + int(_rows.size()) * _rowHeight + st::membersMarginBottom;
resize(newWidth ? newWidth : width(), qMax(_minHeight, naturalHeight));
@@ -2269,7 +2340,7 @@ void StickersBox::Inner::updateRows() {
&& row->isInstalled()
&& !row->isArchived()
&& !row->removed);
row->title = fillSetTitle(
row->title = FillSetTitle(
set,
installedSet ? maxNameWidthInstalled : maxNameWidth,
&row->titleWidth);
@@ -2331,7 +2402,7 @@ void StickersBox::Inner::rebuildAppendSet(not_null<StickersSet*> set) {
&& !(flagsOverride & SetFlag::Archived)
&& !removed);
int titleWidth = 0;
QString title = fillSetTitle(set, maxNameWidth, &titleWidth);
QString title = FillSetTitle(set, maxNameWidth, &titleWidth);
int count = fillSetCount(set);
const auto existing = [&]{
@@ -2458,22 +2529,6 @@ int StickersBox::Inner::fillSetCount(not_null<StickersSet*> set) const {
return result + added;
}
QString StickersBox::Inner::fillSetTitle(
not_null<StickersSet*> set,
int maxNameWidth,
int *outTitleWidth) const {
auto result = set->title;
int titleWidth = st::contactsNameStyle.font->width(result);
if (titleWidth > maxNameWidth) {
result = st::contactsNameStyle.font->elided(result, maxNameWidth);
titleWidth = st::contactsNameStyle.font->width(result);
}
if (outTitleWidth) {
*outTitleWidth = titleWidth;
}
return result;
}
Data::StickersSetFlags StickersBox::Inner::fillSetFlags(
not_null<StickersSet*> set) const {
const auto result = set->flags;
@@ -2494,19 +2549,19 @@ StickersSetsOrder StickersBox::Inner::collectSets(Check check) const {
return result;
}
StickersSetsOrder StickersBox::Inner::getOrder() const {
StickersSetsOrder StickersBox::Inner::order() const {
return collectSets([](Row *row) {
return !row->isArchived() && !row->removed && !row->isRecentSet();
});
}
StickersSetsOrder StickersBox::Inner::getFullOrder() const {
StickersSetsOrder StickersBox::Inner::fullOrder() const {
return collectSets([](Row *row) {
return !row->isRecentSet();
});
}
StickersSetsOrder StickersBox::Inner::getRemovedSets() const {
StickersSetsOrder StickersBox::Inner::removedSets() const {
return collectSets([](Row *row) {
return row->removed;
});

View File

@@ -104,7 +104,7 @@ private:
[[nodiscard]] int index() const;
void saveScrollTop();
int getScrollTop() const {
int scrollTop() const {
return _scrollTop;
}
@@ -122,12 +122,12 @@ private:
void updateTabsGeometry();
void switchTab();
void installSet(uint64 setId);
int getTopSkip() const;
int topSkip() const;
void saveChanges();
QPixmap grabContentCache();
void installDone(const MTPmessages_StickerSetInstallResult &result);
void installDone(const MTPmessages_StickerSetInstallResult &result) const;
void installFail(const MTP::Error &error, uint64 setId);
void preloadArchivedSets();
@@ -139,7 +139,7 @@ private:
void showAttachedStickers();
const Data::StickersSetsOrder &archivedSetsOrder() const;
Data::StickersSetsOrder &archivedSetsOrderRef();
Data::StickersSetsOrder &archivedSetsOrderRef() const;
std::array<Inner*, 5> widgets() const;

View File

@@ -19,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/menu/menu_action.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/effects/ripple_animation.h"
#include "ui/layers/generic_box.h"
#include "ui/painter.h"

View File

@@ -23,7 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/call_button.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/dropdown_menu.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/tooltip.h"
#include "ui/widgets/rp_window.h"
#include "ui/chat/group_call_bar.h"

View File

@@ -16,7 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/continuous_sliders.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/popup_menu.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/text/text_utilities.h"

View File

@@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/image/image_prepare.h"
#include "ui/layers/generic_box.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/labels.h"
#include "styles/style_calls.h"
#include "styles/style_layers.h"
@@ -287,7 +287,7 @@ void EditGroupCallTitleBox(
box->closeBox();
done(result);
};
QObject::connect(input, &Ui::InputField::submitted, submit);
input->submits() | rpl::start_with_next(submit, input->lifetime());
box->addButton(tr::lng_settings_save(), submit);
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
}
@@ -346,7 +346,7 @@ void AddTitleGroupCallRecordingBox(
box->closeBox();
done(result);
};
QObject::connect(input, &Ui::InputField::submitted, submit);
input->submits() | rpl::start_with_next(submit, input->lifetime());
box->addButton(tr::lng_group_call_recording_start_button(), submit);
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
}

View File

@@ -294,8 +294,11 @@ stickersTrendingAdd: RoundButton(defaultActiveButton) {
stickersTrendingInstalled: RoundButton(stickersTrendingAdd) {
textFg: activeButtonBg;
textFgOver: activeButtonBgOver;
textBg: activeButtonSecondaryFg;
textBgOver: activeButtonSecondaryFgOver;
textBg: lightButtonBgOver;
textBgOver: lightButtonBgOver;
ripple: RippleAnimation(defaultRippleAnimation) {
color: activeButtonSecondaryFg;
}
}
stickersRemove: IconButton(defaultIconButton) {
width: 40px;

View File

@@ -41,9 +41,9 @@ inline auto PreviewPath(int i) {
const auto kSets = {
Set{ { 0, 0, 0, "Mac" }, PreviewPath(0) },
Set{ { 1, 1392, 8'184'590, "Android" }, PreviewPath(1) },
Set{ { 2, 1393, 5'413'219, "Twemoji" }, PreviewPath(2) },
Set{ { 3, 1394, 6'967'218, "JoyPixels" }, PreviewPath(3) },
Set{ { 1, 1804, 8'115'639, "Android" }, PreviewPath(1) },
Set{ { 2, 1805, 5'481'197, "Twemoji" }, PreviewPath(2) },
Set{ { 3, 1806, 7'047'594, "JoyPixels" }, PreviewPath(3) },
};
using Loading = MTP::DedicatedLoader::Progress;

View File

@@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/ripple_animation.h"
#include "ui/widgets/shadow.h"
#include "ui/widgets/inner_dropdown.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/emoji_config.h"
#include "ui/ui_utility.h"
#include "ui/cached_round_corners.h"

View File

@@ -31,7 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/clip/media_clip_reader.h"
#include "ui/widgets/popup_menu.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/text/text_options.h"
#include "ui/image/image.h"
#include "ui/effects/path_shift_gradient.h"

View File

@@ -24,7 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/click_handler_types.h"
#include "ui/controls/tabbed_search.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/popup_menu.h"
#include "ui/effects/ripple_animation.h"
#include "ui/image/image.h"

View File

@@ -190,16 +190,18 @@ void EditLinkBox(
}
};
QObject::connect(text, &Ui::InputField::submitted, [=] {
text->submits(
) | rpl::start_with_next([=] {
url->setFocusFast();
});
QObject::connect(url, &Ui::InputField::submitted, [=] {
}, text->lifetime());
url->submits(
) | rpl::start_with_next([=] {
if (text->getLastText().isEmpty()) {
text->setFocusFast();
} else {
submit();
}
});
}, url->lifetime());
box->setTitle(url->getLastText().isEmpty()
? tr::lng_formatting_link_create_title()
@@ -223,8 +225,14 @@ void EditLinkBox(
url->customTab(true);
text->customTab(true);
QObject::connect(url, &Ui::InputField::tabbed, [=] { text->setFocus(); });
QObject::connect(text, &Ui::InputField::tabbed, [=] { url->setFocus(); });
url->tabbed(
) | rpl::start_with_next([=] {
text->setFocus();
}, url->lifetime());
text->tabbed(
) | rpl::start_with_next([=] {
url->setFocus();
}, text->lifetime());
}
TextWithEntities StripSupportHashtag(TextWithEntities text) {
@@ -590,7 +598,8 @@ AutocompleteQuery ParseMentionHashtagBotCommandQuery(
MessageLinksParser::MessageLinksParser(not_null<Ui::InputField*> field)
: _field(field)
, _timer([=] { parse(); }) {
_connection = QObject::connect(_field, &Ui::InputField::changed, [=] {
_lifetime = _field->changes(
) | rpl::start_with_next([=] {
const auto length = _field->getTextWithTags().text.size();
const auto timeout = (std::abs(length - _lastLength) > 2)
? 0

View File

@@ -7,9 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "base/timer.h"
#include "base/qt_connection.h"
#include "chat_helpers/compose/compose_features.h"
#ifndef TDESKTOP_DISABLE_SPELLCHECK
@@ -132,7 +131,7 @@ private:
int _lastLength = 0;
bool _disabled = false;
base::Timer _timer;
base::qt_connection _connection;
rpl::lifetime _lifetime;
};

View File

@@ -26,7 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lottie/lottie_single_player.h"
#include "ui/dpr/dpr_icon.h"
#include "ui/dpr/dpr_image.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/widgets/buttons.h"
#include "ui/painter.h"
#include "ui/rect_part.h"

View File

@@ -22,110 +22,6 @@ namespace {
std::map<int, const char*> BetaLogs() {
return {
{
4005004,
"- Allow wide range of interface scale options.\n"
"- Show opened chat name in the window title.\n"
"- Bug fixes and other minor improvements.\n"
"- Fix updating on macOS older than 10.14.\n"
},
{
4005006,
"- Try enabling non-fractional scale "
"High DPI support on Windows and Linux.\n"
"- Experimental setting for fractional scale "
"High DPI support on Windows and Linux.\n"
"- Fix navigation to bottom problems in groups you didn't join.\n"
"- Fix a crash in chat export settings changes.\n"
"- Fix a crash in sending some of JPEG images.\n"
"- Fix CJK fonts on Windows.\n"
},
{
4005007,
"- Fix glitches after moving window to another screen.\n",
},
{
4005008,
"- Allow opening another account in a new window "
"(see Settings > Advanced > Experimental Settings).\n"
"- A lot of bugfixes for working with more than one window.\n"
},
{
4006004,
"- Allow media viewer to exit fullscreen and become a normal window."
},
{
4006006,
"- Confirmation window before starting a call.\n"
"- New \"Battery and Animations\" settings section.\n"
"- \"Save Power on Low Battery\" option for laptops.\n"
"- Improved windowed mode support for media viewer.\n"
"- Hardware accelerated video playback fix on macOS.\n"
"- New application icon on macOS following the system guidelines.\n"
},
{
4006007,
"- Fix crash when accepting incoming calls.\n"
"- Remove sound when cancelling an unconfirmed call.\n"
},
{
4006008,
"- Improve quality of voice messages with changed playback speed.\n"
"- Show when your message was read in small groups.\n"
"- Fix pasting images from Firefox on Windows.\n"
"- Improve memory usage for custom emoji.\n"
},
{
4006010,
"- Suggest sending an invite link if user forbids "
"inviting him to groups.\n"
"- Show when a reaction was left on your message in small groups.\n"
"- Fix a crash in video chats on Windows.\n"
"- Fix a crash in audio speed change.\n"
},
{
4006011,
"- Allow larger interface scale values on high-dpi screens.\n"
"- Implement new voice and video speed change interface (up to 2.5x).\n"
"- Support global Fn+F shortcut to toggle fullscreen on macOS.\n"
"- Silent notification sound in Focus Mode on macOS.\n"
"- Fix media viewer on macOS with several screens.\n"
"- Fix a crash in connection type box.\n"
"- Fix possible crash on quit.\n"
},
{
4006012,
"- Fix several possible crashes.\n"
"- Deprecate macOS 10.12, Ubuntu 18.04 and CentOS 7 in July.\n"
},
{
4008011,
"- Fix initial video playback speed.\n"

View File

@@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/send_files_box.h"
#include "history/view/history_view_quick_action.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/fields/input_field.h"
#include "storage/serialize_common.h"
#include "window/section_widget.h"
#include "base/platform/base_platform_info.h"

View File

@@ -15,7 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <new>
#include <mutex>
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
#ifdef Q_OS_WIN
#include <new.h>
@@ -25,7 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <client/windows/handler/exception_handler.h>
#pragma warning(pop)
#elif defined Q_OS_UNIX // Q_OS_WIN
#else // Q_OS_WIN
#include <execinfo.h>
#include <sys/syscall.h>
@@ -48,7 +48,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#endif // Q_OS_MAC
#endif // Q_OS_WIN
#endif // !DESKTOP_APP_DISABLE_CRASH_REPORTS
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
namespace CrashReports {
namespace {
@@ -59,7 +59,7 @@ using AnnotationRefs = std::map<std::string, const QString*>;
Annotations ProcessAnnotations;
AnnotationRefs ProcessAnnotationRefs;
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
QString ReportPath;
FILE *ReportFile = nullptr;
@@ -197,13 +197,15 @@ const int HandledSignals[] = {
SIGABRT,
SIGFPE,
SIGILL,
#ifdef Q_OS_UNIX
#ifndef Q_OS_WIN
SIGBUS,
SIGTRAP,
#endif // Q_OS_UNIX
#endif // !Q_OS_WIN
};
#ifdef Q_OS_UNIX
#ifdef Q_OS_WIN
void SignalHandler(int signum) {
#else // Q_OS_WIN
struct sigaction OldSigActions[32]/* = { 0 }*/;
void RestoreSignalHandlers() {
@@ -229,9 +231,7 @@ void InvokeOldSignalHandler(int signum, siginfo_t *info, void *ucontext) {
void SignalHandler(int signum, siginfo_t *info, void *ucontext) {
RestoreSignalHandlers();
#else // Q_OS_UNIX
void SignalHandler(int signum) {
#endif // else for Q_OS_UNIX
#endif // else for Q_OS_WIN
const char* name = 0;
switch (signum) {
@@ -253,9 +253,9 @@ void SignalHandler(int signum) {
ReportingThreadId = nullptr;
}
#ifdef Q_OS_UNIX
#ifndef Q_OS_WIN
InvokeOldSignalHandler(signum, info, ucontext);
#endif // Q_OS_UNIX
#endif // !Q_OS_WIN
}
bool SetSignalHandlers = true;
@@ -267,9 +267,9 @@ google_breakpad::ExceptionHandler* BreakpadExceptionHandler = 0;
bool DumpCallback(const wchar_t* _dump_dir, const wchar_t* _minidump_id, void* context, EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion, bool success)
#elif defined Q_OS_MAC // Q_OS_WIN
bool DumpCallback(const char* _dump_dir, const char* _minidump_id, void *context, bool success)
#elif defined Q_OS_UNIX // Q_OS_MAC
#else // Q_OS_MAC
bool DumpCallback(const google_breakpad::MinidumpDescriptor &md, void *context, bool success)
#endif // Q_OS_UNIX
#endif // else for Q_OS_WIN || Q_OS_MAC
{
if (CrashLogged) return success;
CrashLogged = true;
@@ -290,7 +290,7 @@ bool DumpCallback(const google_breakpad::MinidumpDescriptor &md, void *context,
}
#endif // !Q_OS_MAC || MAC_USE_BREAKPAD
#endif // !DESKTOP_APP_DISABLE_CRASH_REPORTS
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
} // namespace
@@ -314,7 +314,7 @@ QString PlatformString() {
}
void StartCatching() {
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
ProcessAnnotations["Binary"] = cExeName().toUtf8().constData();
ProcessAnnotations["ApiId"] = QString::number(ApiId).toUtf8().constData();
ProcessAnnotations["Version"] = (cAlphaVersion()
@@ -370,7 +370,7 @@ void StartCatching() {
false)) { // asynchronous_start
}
#endif // else for MAC_USE_BREAKPAD
#elif defined Q_OS_UNIX
#else
BreakpadExceptionHandler = new google_breakpad::ExceptionHandler(
google_breakpad::MinidumpDescriptor(QFile::encodeName(dumpspath).toStdString()),
/*FilterCallback*/ 0,
@@ -379,22 +379,22 @@ void StartCatching() {
true,
-1
);
#endif // Q_OS_UNIX
#endif // !DESKTOP_APP_DISABLE_CRASH_REPORTS
#endif // else for Q_OS_WIN || Q_OS_MAC
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
}
void FinishCatching() {
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
#if !defined Q_OS_MAC || defined MAC_USE_BREAKPAD
delete base::take(BreakpadExceptionHandler);
#endif // !Q_OS_MAC || MAC_USE_BREAKPAD
#endif // !DESKTOP_APP_DISABLE_CRASH_REPORTS
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
}
StartResult Start() {
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
ReportPath = cWorkingDir() + u"tdata/working"_q;
#ifdef Q_OS_WIN
@@ -420,12 +420,12 @@ StartResult Start() {
return lastdump;
}
#endif // !DESKTOP_APP_DISABLE_CRASH_REPORTS
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
return Restart();
}
Status Restart() {
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
if (ReportFile) {
return Started;
}
@@ -470,13 +470,13 @@ Status Restart() {
LOG(("FATAL: Could not open '%1' for writing!").arg(ReportPath));
return CantOpen;
#else // !DESKTOP_APP_DISABLE_CRASH_REPORTS
#else // !TDESKTOP_DISABLE_CRASH_REPORTS
return Started;
#endif // else for !DESKTOP_APP_DISABLE_CRASH_REPORTS
#endif // else for !TDESKTOP_DISABLE_CRASH_REPORTS
}
void Finish() {
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
FinishCatching();
if (ReportFile) {
@@ -489,7 +489,7 @@ void Finish() {
unlink(ReportPath.toUtf8().constData());
#endif // else for Q_OS_WIN
}
#endif // !DESKTOP_APP_DISABLE_CRASH_REPORTS
#endif // !TDESKTOP_DISABLE_CRASH_REPORTS
}
void SetAnnotation(const std::string &key, const QString &value) {
@@ -539,7 +539,7 @@ void SetAnnotationRef(const std::string &key, const QString *valuePtr) {
}
}
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
dump::~dump() {
if (ReportFile) {
@@ -604,6 +604,6 @@ const dump &operator<<(const dump &stream, double num) {
return stream;
}
#endif // DESKTOP_APP_DISABLE_CRASH_REPORTS
#endif // TDESKTOP_DISABLE_CRASH_REPORTS
} // namespace CrashReports

View File

@@ -11,7 +11,7 @@ namespace CrashReports {
QString PlatformString();
#ifndef DESKTOP_APP_DISABLE_CRASH_REPORTS
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
struct dump {
~dump();
@@ -24,7 +24,7 @@ const dump &operator<<(const dump &stream, unsigned long num);
const dump &operator<<(const dump &stream, unsigned long long num);
const dump &operator<<(const dump &stream, double num);
#endif // DESKTOP_APP_DISABLE_CRASH_REPORTS
#endif // TDESKTOP_DISABLE_CRASH_REPORTS
enum Status {
CantOpen,

View File

@@ -0,0 +1,83 @@
/*
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
namespace Core::DeadlockDetector {
class PingPongEvent : public QEvent {
public:
static auto Type() {
static const auto Result = QEvent::Type(QEvent::registerEventType());
return Result;
}
PingPongEvent(not_null<QObject*> sender)
: QEvent(Type())
, _sender(sender) {
}
[[nodiscard]] not_null<QObject*> sender() const {
return _sender;
}
private:
not_null<QObject*> _sender;
};
class Pinger : public QObject {
public:
Pinger(not_null<QObject*> receiver)
: _receiver(receiver)
, _abortTimer([] { Unexpected("Deadlock found!"); }) {
const auto callback = [=] {
QCoreApplication::postEvent(_receiver, new PingPongEvent(this));
_abortTimer.callOnce(30000);
};
_pingTimer.setCallback(callback);
_pingTimer.callEach(60000);
callback();
}
protected:
bool event(QEvent *e) override {
if (e->type() == PingPongEvent::Type()
&& static_cast<PingPongEvent*>(e)->sender() == _receiver) {
_abortTimer.cancel();
}
return QObject::event(e);
}
private:
not_null<QObject*> _receiver;
base::Timer _pingTimer;
base::Timer _abortTimer;
};
class PingThread : public QThread {
public:
PingThread(not_null<QObject*> parent)
: QThread(parent) {
start();
}
~PingThread() {
quit();
wait();
}
protected:
void run() override {
Pinger pinger(parent());
QThread::run();
}
};
} // namespace Core::DeadlockDetector

View File

@@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/options.h"
#include <QtCore/QLoggingCategory>
#include <QtCore/QStandardPaths>
namespace Core {
namespace {
@@ -115,16 +116,26 @@ void ComputeDebugMode() {
}
void ComputeExternalUpdater() {
QFile file(u"/etc/tdesktop/externalupdater"_q);
if (file.exists() && file.open(QIODevice::ReadOnly)) {
QTextStream fileStream(&file);
while (!fileStream.atEnd()) {
const auto path = fileStream.readLine();
if (path == (cExeDir() + cExeName())) {
SetUpdaterDisabledAtStartup();
return;
auto locations = QStandardPaths::standardLocations(
QStandardPaths::AppDataLocation);
if (locations.isEmpty()) {
locations << QString();
}
locations[0] = QDir::cleanPath(cWorkingDir());
locations << QDir::cleanPath(cExeDir());
for (const auto &location : locations) {
const auto dir = location + u"/externalupdater.d"_q;
for (const auto &info : QDir(dir).entryInfoList(QDir::Files)) {
QFile file(info.absoluteFilePath());
if (file.open(QIODevice::ReadOnly)) {
QTextStream fileStream(&file);
while (!fileStream.atEnd()) {
const auto path = fileStream.readLine();
if (path == (cExeDir() + cExeName())) {
SetUpdaterDisabledAtStartup();
return;
}
}
}
}
}
@@ -223,7 +234,7 @@ bool CheckPortableVersionFolder() {
if (cAlphaVersion()) {
Assert(*AlphaPrivateKey != 0);
cForceWorkingDir(portable + '/');
cForceWorkingDir(portable);
QDir().mkpath(cWorkingDir() + u"tdata"_q);
cSetAlphaPrivateKey(QByteArray(AlphaPrivateKey));
if (!key.open(QIODevice::WriteOnly)) {
@@ -239,7 +250,7 @@ bool CheckPortableVersionFolder() {
if (!QDir(portable).exists()) {
return true;
}
cForceWorkingDir(portable + '/');
cForceWorkingDir(portable);
if (!key.exists()) {
return true;
}
@@ -291,7 +302,8 @@ Launcher::Launcher(int argc, char *argv[])
: _argc(argc)
, _argv(argv)
, _arguments(readArguments(_argc, _argv))
, _baseIntegration(_argc, _argv) {
, _baseIntegration(_argc, _argv)
, _initialWorkingDir(QDir::currentPath() + '/') {
crl::toggle_fp_exceptions(true);
base::Integration::Set(&_baseIntegration);
@@ -446,6 +458,10 @@ const QStringList &Launcher::arguments() const {
return _arguments;
}
QString Launcher::initialWorkingDir() const {
return _initialWorkingDir;
}
bool Launcher::customWorkingDir() const {
return !_customWorkingDir.isEmpty();
}

View File

@@ -29,6 +29,7 @@ public:
virtual int exec();
const QStringList &arguments() const;
QString initialWorkingDir() const;
bool customWorkingDir() const;
uint64 installationTag() const;
@@ -84,6 +85,7 @@ private:
QStringList _arguments;
BaseIntegration _baseIntegration;
QString _initialWorkingDir;
QString _customWorkingDir;
};

View File

@@ -378,6 +378,8 @@ bool ResolveUsernameOrPhone(
startToken = params.value(u"startgroup"_q);
} else if (params.contains(u"startchannel"_q)) {
resolveType = ResolveType::AddToChannel;
} else if (params.contains(u"boost"_q)) {
resolveType = ResolveType::Boost;
}
auto post = ShowAtUnreadMsgId;
auto adminRights = ChatAdminRights();
@@ -392,7 +394,6 @@ bool ResolveUsernameOrPhone(
const auto storyParam = params.value(u"story"_q);
const auto storyId = storyParam.toInt();
const auto appname = webChannelPreviewLink ? QString() : appnameParam;
const auto appstart = params.value(u"startapp"_q);
const auto commentParam = params.value(u"comment"_q);
const auto commentId = commentParam.toInt();
const auto topicParam = params.value(u"topic"_q);
@@ -404,11 +405,11 @@ bool ResolveUsernameOrPhone(
startToken = gameParam;
resolveType = ResolveType::ShareGame;
}
if (startToken.isEmpty() && params.contains(u"startapp"_q)) {
startToken = params.value(u"startapp"_q);
}
if (!appname.isEmpty()) {
resolveType = ResolveType::BotApp;
if (startToken.isEmpty() && params.contains(u"startapp"_q)) {
startToken = params.value(u"startapp"_q);
}
}
const auto myContext = context.value<ClickHandlerContext>();
using Navigation = Window::SessionNavigation;
@@ -436,7 +437,11 @@ bool ResolveUsernameOrPhone(
.attachBotUsername = params.value(u"attach"_q),
.attachBotToggleCommand = (params.contains(u"startattach"_q)
? params.value(u"startattach"_q)
: (appname.isEmpty() && params.contains(u"startapp"_q))
? params.value(u"startapp"_q)
: std::optional<QString>()),
.attachBotMenuOpen = (appname.isEmpty()
&& params.contains(u"startapp"_q)),
.attachBotChooseTypes = InlineBots::ParseChooseTypes(
params.value(u"choose"_q)),
.voicechatHash = (params.contains(u"livestream"_q)
@@ -839,6 +844,34 @@ bool ResolveLoginCode(
return true;
}
bool ResolveBoost(
Window::SessionController *controller,
const Match &match,
const QVariant &context) {
if (!controller) {
return false;
}
const auto params = url_parse_params(
match->captured(1),
qthelp::UrlParamNameTransform::ToLower);
const auto domainParam = params.value(u"domain"_q);
const auto channelParam = params.contains(u"c"_q)
? params.value(u"c"_q)
: params.value(u"channel"_q);
const auto myContext = context.value<ClickHandlerContext>();
using Navigation = Window::SessionNavigation;
controller->window().activate();
controller->showPeerByLink(Navigation::PeerByLinkInfo{
.usernameOrId = (!domainParam.isEmpty()
? std::variant<QString, ChannelId>(domainParam)
: ChannelId(BareId(channelParam.toULongLong()))),
.resolveType = Window::ResolveType::Boost,
.clickFromMessageId = myContext.itemId,
});
return true;
}
} // namespace
const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
@@ -919,6 +952,10 @@ const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
u"^login/?(\\?code=([0-9]+))(&|$)"_q,
ResolveLoginCode
},
{
u"^boost/?\\?(.+)(#|$)"_q,
ResolveBoost,
},
{
u"^([^\\?]+)(\\?|#|$)"_q,
HandleUnknown
@@ -1022,8 +1059,13 @@ QString TryConvertUrlToLocal(QString url) {
"/\\d+/?(\\?|$)|"
"/\\d+/\\d+/?(\\?|$)"
")"_q, query, matchOptions)) {
const auto channel = privateMatch->captured(1);
const auto params = query.mid(privateMatch->captured(0).size()).toString();
const auto base = u"tg://privatepost?channel="_q + privateMatch->captured(1);
if (params.indexOf("boost", 0, Qt::CaseInsensitive) >= 0
&& params.toLower().split('&').contains(u"boost"_q)) {
return u"tg://boost?channel="_q + channel;
}
const auto base = u"tg://privatepost?channel="_q + channel;
auto added = QString();
if (const auto threadPostMatch = regex_match(u"^/(\\d+)/(\\d+)(/?\\?|/?$)"_q, privateMatch->captured(2))) {
added = u"&topic=%1&post=%2"_q.arg(threadPostMatch->captured(1)).arg(threadPostMatch->captured(2));
@@ -1041,7 +1083,18 @@ QString TryConvertUrlToLocal(QString url) {
"/s/\\d+/?(\\?|$)|"
"/\\d+/\\d+/?(\\?|$)"
")"_q, query, matchOptions)) {
const auto domain = usernameMatch->captured(1);
const auto params = query.mid(usernameMatch->captured(0).size()).toString();
if (params.indexOf("boost", 0, Qt::CaseInsensitive) >= 0
&& params.toLower().split('&').contains(u"boost"_q)) {
return u"tg://boost?domain="_q + domain;
} else if (domain == u"boost"_q) {
if (const auto domainMatch = regex_match(u"^/([a-zA-Z0-9\\.\\_]+)(/?\\?|/?$)"_q, usernameMatch->captured(2))) {
return u"tg://boost?domain="_q + domainMatch->captured(1);
} else if (params.indexOf("c=", 0, Qt::CaseInsensitive) >= 0) {
return u"tg://boost?"_q + params;
}
}
const auto base = u"tg://resolve?domain="_q + url_encode(usernameMatch->captured(1));
auto added = QString();
if (const auto threadPostMatch = regex_match(u"^/(\\d+)/(\\d+)(/?\\?|/?$)"_q, usernameMatch->captured(2))) {

View File

@@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/launcher.h"
#include "core/local_url_handlers.h"
#include "core/update_checker.h"
#include "core/deadlock_detector.h"
#include "base/timer.h"
#include "base/concurrent_timer.h"
#include "base/invoke_queued.h"
@@ -27,7 +28,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/qthelp_regex.h"
#include "ui/ui_utility.h"
#include "ui/effects/animations.h"
#include "ui/platform/ui_platform_utility.h"
#include <QtCore/QLockFile>
#include <QtGui/QSessionManager>
@@ -198,6 +198,13 @@ void Sandbox::launchApplication() {
}
setupScreenScale();
#ifndef _DEBUG
if (Logs::DebugEnabled()) {
using DeadlockDetector::PingThread;
_deadlockDetector = std::make_unique<PingThread>(this);
}
#endif // !_DEBUG
_application = std::make_unique<Application>();
// Ideally this should go to constructor.
@@ -267,6 +274,10 @@ bool Sandbox::event(QEvent *e) {
return false;
} else if (e->type() == QEvent::Close) {
Quit();
} else if (e->type() == DeadlockDetector::PingPongEvent::Type()) {
postEvent(
static_cast<DeadlockDetector::PingPongEvent*>(e)->sender(),
new DeadlockDetector::PingPongEvent(this));
}
return QApplication::event(e);
}
@@ -581,18 +592,9 @@ void Sandbox::registerEnterFromEventLoop() {
}
bool Sandbox::notifyOrInvoke(QObject *receiver, QEvent *e) {
const auto type = e->type();
if (type == base::InvokeQueuedEvent::Type()) {
if (e->type() == base::InvokeQueuedEvent::Type()) {
static_cast<base::InvokeQueuedEvent*>(e)->invoke();
return true;
} else if (receiver == this) {
if (type == QEvent::ApplicationDeactivate) {
if (Ui::Platform::SkipApplicationDeactivateEvent()) {
return true;
}
} else if (type == QEvent::ApplicationActivate) {
Ui::Platform::GotApplicationActivateEvent();
}
}
return QApplication::notify(receiver, e);
}

View File

@@ -131,6 +131,8 @@ private:
rpl::event_stream<> _widgetUpdateRequests;
std::unique_ptr<QThread> _deadlockDetector;
};
} // namespace Core

View File

@@ -370,7 +370,6 @@ QString UiIntegration::phrasePanelCloseAnyway() {
return tr::lng_bot_close_warning_sure(tr::now);
}
#if 0 // disabled for now
QString UiIntegration::phraseBotSharePhone() {
return tr::lng_bot_share_phone(tr::now);
}
@@ -382,7 +381,18 @@ QString UiIntegration::phraseBotSharePhoneTitle() {
QString UiIntegration::phraseBotSharePhoneConfirm() {
return tr::lng_bot_share_phone_confirm(tr::now);
}
#endif
QString UiIntegration::phraseBotAllowWrite() {
return tr::lng_bot_allow_write(tr::now);
}
QString UiIntegration::phraseBotAllowWriteTitle() {
return tr::lng_bot_allow_write_title(tr::now);
}
QString UiIntegration::phraseBotAllowWriteConfirm() {
return tr::lng_bot_allow_write_confirm(tr::now);
}
bool OpenGLLastCheckFailed() {
return QFile::exists(OpenGLCheckFilePath());

View File

@@ -84,11 +84,12 @@ public:
QString phrasePanelCloseWarning() override;
QString phrasePanelCloseUnsaved() override;
QString phrasePanelCloseAnyway() override;
#if 0 // disabled for now
QString phraseBotSharePhone() override;
QString phraseBotSharePhoneTitle() override;
QString phraseBotSharePhoneConfirm() override;
#endif
QString phraseBotAllowWrite() override;
QString phraseBotAllowWriteTitle() override;
QString phraseBotAllowWriteConfirm() override;
};

View File

@@ -42,16 +42,16 @@ extern "C" {
} // extern "C"
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
#if defined Q_OS_WIN && !defined DESKTOP_APP_USE_PACKAGED // use Lzma SDK for win
#if defined Q_OS_WIN && !defined TDESKTOP_USE_PACKAGED // use Lzma SDK for win
#include <LzmaLib.h>
#else // Q_OS_WIN && !DESKTOP_APP_USE_PACKAGED
#else // Q_OS_WIN && !TDESKTOP_USE_PACKAGED
#include <lzma.h>
#endif // else of Q_OS_WIN && !DESKTOP_APP_USE_PACKAGED
#endif // else of Q_OS_WIN && !TDESKTOP_USE_PACKAGED
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
#ifdef Q_OS_UNIX
#ifndef Q_OS_WIN
#include <unistd.h>
#endif // Q_OS_UNIX
#endif // !Q_OS_WIN
namespace Core {
namespace {
@@ -275,11 +275,11 @@ bool UnpackUpdate(const QString &filepath) {
return false;
}
#if defined Q_OS_WIN && !defined DESKTOP_APP_USE_PACKAGED // use Lzma SDK for win
#if defined Q_OS_WIN && !defined TDESKTOP_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
#else // Q_OS_WIN && !DESKTOP_APP_USE_PACKAGED
#else // Q_OS_WIN && !TDESKTOP_USE_PACKAGED
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = 0, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hOriginalSizeLen; // header
#endif // Q_OS_WIN && !DESKTOP_APP_USE_PACKAGED
#endif // Q_OS_WIN && !TDESKTOP_USE_PACKAGED
QByteArray compressed = input.readAll();
int32 compressedLen = compressed.size() - hSize;
@@ -350,14 +350,14 @@ bool UnpackUpdate(const QString &filepath) {
uncompressed.resize(uncompressedLen);
size_t resultLen = uncompressed.size();
#if defined Q_OS_WIN && !defined DESKTOP_APP_USE_PACKAGED // use Lzma SDK for win
#if defined Q_OS_WIN && !defined TDESKTOP_USE_PACKAGED // use Lzma SDK for win
SizeT srcLen = compressedLen;
int uncompressRes = LzmaUncompress((uchar*)uncompressed.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
if (uncompressRes != SZ_OK) {
LOG(("Update Error: could not uncompress lzma, code: %1").arg(uncompressRes));
return false;
}
#else // Q_OS_WIN && !DESKTOP_APP_USE_PACKAGED
#else // Q_OS_WIN && !TDESKTOP_USE_PACKAGED
lzma_stream stream = LZMA_STREAM_INIT;
lzma_ret ret = lzma_stream_decoder(&stream, UINT64_MAX, LZMA_CONCATENATED);
@@ -400,7 +400,7 @@ bool UnpackUpdate(const QString &filepath) {
LOG(("Error in decompression: %1 (error code %2)").arg(msg).arg(res));
return false;
}
#endif // Q_OS_WIN && !DESKTOP_APP_USE_PACKAGED
#endif // Q_OS_WIN && !TDESKTOP_USE_PACKAGED
tempDir.mkdir(tempDir.absolutePath());
@@ -448,9 +448,9 @@ bool UnpackUpdate(const QString &filepath) {
bool executable = false;
stream >> relativeName >> fileSize >> fileInnerData;
#ifdef Q_OS_UNIX
#ifndef Q_OS_WIN
stream >> executable;
#endif // Q_OS_UNIX
#endif // !Q_OS_WIN
if (stream.status() != QDataStream::Ok) {
LOG(("Update Error: cant read file from downloaded stream, status: %1").arg(stream.status()));
return false;
@@ -1554,10 +1554,10 @@ bool checkReadyUpdate() {
#elif defined Q_OS_MAC // Q_OS_WIN
QString curUpdater = (cExeDir() + cExeName() + u"/Contents/Frameworks/Updater"_q);
QFileInfo updater(cWorkingDir() + u"tupdates/temp/Telegram.app/Contents/Frameworks/Updater"_q);
#elif defined Q_OS_UNIX // Q_OS_MAC
#else // Q_OS_MAC
QString curUpdater = (cExeDir() + u"Updater"_q);
QFileInfo updater(cWorkingDir() + u"tupdates/temp/Updater"_q);
#endif // Q_OS_UNIX
#endif // else for Q_OS_WIN || Q_OS_MAC
if (!updater.exists()) {
QFileInfo current(curUpdater);
if (!current.exists()) {
@@ -1591,7 +1591,7 @@ bool checkReadyUpdate() {
ClearAll();
return false;
}
#elif defined Q_OS_UNIX // Q_OS_MAC
#else // Q_OS_MAC
// if the files in the directory are owned by user, while the directory is not,
// update will still fail since it's not possible to remove files
if (QFile::exists(curUpdater)
@@ -1619,7 +1619,7 @@ bool checkReadyUpdate() {
return false;
}
}
#endif // Q_OS_UNIX
#endif // else for Q_OS_WIN || Q_OS_MAC
#ifdef Q_OS_MAC
base::Platform::RemoveQuarantine(QFileInfo(curUpdater).absolutePath());

View File

@@ -45,12 +45,9 @@ inline QString IconName() {
inline bool CanReadDirectory(const QString &path) {
#ifndef Q_OS_MAC // directory_iterator since 10.15
try {
std::filesystem::directory_iterator(path.toStdString());
return true;
} catch (...) {
return false;
}
std::error_code error;
std::filesystem::directory_iterator(path.toStdString(), error);
return !error;
#else
Unexpected("Not implemented.");
#endif

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