Compare commits

..

369 Commits

Author SHA1 Message Date
John Preston
cc48afac1c Beta version 2.4.11.
- Improve locked voice message recording.
- Fix main window closing to tray on Windows.
- Fix crash in bot command sending.
- Fix adding additional photos when sending an album
to a group with enabled slow mode.
2020-11-19 19:05:46 +03:00
23rd
0a0dcb9054 Delegated responsibility for clearing listen state to sections. 2020-11-19 18:41:13 +03:00
Ilya Fedin
b1b01385d0 Restore 16px tray icon size
Looks like there are support for this size since b703f4e555
2020-11-19 18:36:57 +03:00
23rd
a2e4403b28 Slightly refactored code for menu with send options. 2020-11-19 18:11:37 +03:00
23rd
e1017380ec Fixed filling menu with send options for inline bots and autocomplete. 2020-11-19 18:11:37 +03:00
23rd
a6e4ac679c Fixed reply stuck display at sending voice in Replies section. 2020-11-19 18:11:37 +03:00
23rd
f75fb33c29 Removed delay for voice lock widget appearing. 2020-11-19 18:11:37 +03:00
23rd
cbaca6382e Fixed unwanted flickering of record button when recorded data is empty. 2020-11-19 18:11:37 +03:00
23rd
1758f0fd8f Added send icon to VoiceRecordButton. 2020-11-19 18:11:37 +03:00
John Preston
e29ee439cf Improve media viewer hiding workaround on macOS. 2020-11-19 17:59:43 +03:00
John Preston
51f960442e Make caption area height bigger. 2020-11-19 17:42:57 +03:00
John Preston
fff2ee2758 Use 'Next' in send media box in Scheduled section. 2020-11-19 17:16:56 +03:00
John Preston
b1ed15447b Scroll to bottom when sending a poll. 2020-11-19 17:01:50 +03:00
John Preston
a086afb152 Fix legacy group service message in chats list. 2020-11-19 16:47:17 +03:00
John Preston
639e6d8e28 Fix sending albums in slowmode groups.
Fixes #9106.
2020-11-19 16:47:17 +03:00
John Preston
00504b61cd Allow all messages silent in support mode. 2020-11-19 16:23:57 +03:00
John Preston
1affb8172f Fix hime_qt build with -Werror. 2020-11-18 19:15:26 +03:00
John Preston
c98a3825a5 Fix sending bot commands from autocomplete. 2020-11-18 14:50:10 +03:00
Ilya Fedin
c3b0e6c503 Move -s to CMAKE_EXE_LINKER_FLAGS 2020-11-18 14:29:00 +03:00
Ilya Fedin
76a7cc9229 Don't set screen for media viewer on Wayland 2020-11-18 14:29:00 +03:00
John Preston
b2047c9558 Fix first media viewer open zoom. 2020-11-18 14:11:23 +03:00
John Preston
4a73bb7872 Fix main window on Windows.
Fixes #9089, fixes #9090.
2020-11-18 13:32:30 +03:00
John Preston
91b8ad171a Beta version 2.4.10.
- Use inline bots and sticker by emoji suggestions
in channel comments.
- Lock voice message recording,
listen to your voice message before sending.
2020-11-17 18:21:19 +03:00
John Preston
4f6f654e34 Check replies_pts before applying.
Fixes #9062.
2020-11-17 18:05:35 +03:00
John Preston
ed50aa0d8e Fix build with Qt < 5.14. 2020-11-17 17:14:21 +03:00
mid-kid
49480001f7 Move IsWayland() checks into WaylandIntegration 2020-11-17 16:23:54 +03:00
Ilya Fedin
4ed6918a5e Disable some static plugins when building without wayland 2020-11-17 16:23:54 +03:00
Ilya Fedin
0563e1f878 Have the wayland build-time toggle affect the native window title 2020-11-17 16:23:54 +03:00
mid-kid
17e8e0a7b0 Add workflow for DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION 2020-11-17 16:23:54 +03:00
mid-kid
96b2e26f42 Build wayland support optionally 2020-11-17 16:23:54 +03:00
Ilya Fedin
c0142726f8 Remove unneeded Xi and Xrender from docker build and add repo with new git 2020-11-17 15:49:50 +03:00
Newbyte
c52e914060 Fix WebRTC licence link 2020-11-17 15:49:02 +03:00
Ilya Fedin
985956e625 Update lib_base 2020-11-17 15:46:42 +03:00
Ilya Fedin
facbaecf30 Add -Werror to actions 2020-11-17 15:45:27 +03:00
23rd
04c068d8b3 Added filling send context menu to TabbedSelector from ComposeControls. 2020-11-17 12:58:08 +03:00
23rd
980ce9fba3 Replaced auto types with explicit types in VoiceRecordBar's lambdas. 2020-11-17 12:58:08 +03:00
23rd
024a35d770 Added ability to send recorded voice data from ComposeControls. 2020-11-17 12:58:08 +03:00
23rd
ab38ddc21d Added ability to fill send context menu in ComposeControls. 2020-11-17 12:58:08 +03:00
23rd
79cc4da626 Reduced block size for voice record lock. 2020-11-17 12:58:08 +03:00
23rd
92298316ab Added transform animation from lock to stop icon for recording voice. 2020-11-17 12:58:08 +03:00
23rd
c9314e5e5e Added ripple animation to stop recording voice button. 2020-11-17 12:58:07 +03:00
23rd
eadd952e66 Added animation for recorded voice data delete. 2020-11-17 12:58:07 +03:00
23rd
fb2924f2d6 Fixed size and position of lock/stop button at end of animation. 2020-11-17 12:58:07 +03:00
23rd
7dac42b523 Added ability to play/pause recorded voice data with Space key. 2020-11-17 12:58:07 +03:00
23rd
d2defabd4b Improved waveform display of recorded voice data. 2020-11-17 12:58:07 +03:00
23rd
e0cc3791ff Added edit message prevent when there is unsent recorded voice data. 2020-11-17 12:58:07 +03:00
23rd
6ecc446a8a Added ability to schedule and send without sound recorded voice data. 2020-11-17 12:58:07 +03:00
23rd
2668619758 Added ability to seek recorded voice data. 2020-11-17 12:58:07 +03:00
23rd
5eba680483 Added play button for recorded voice data. 2020-11-17 12:58:07 +03:00
23rd
7826d0246d Added duration display of recorded voice data.
const qptr
2020-11-17 12:58:07 +03:00
23rd
189c940710 Added waveform display of recorded voice data. 2020-11-17 12:58:07 +03:00
23rd
8b2bb722de Added ability to send and cancel recorded voice data with keys. 2020-11-17 12:58:07 +03:00
23rd
a19e3ca3dc Added initial ability to send recorded voice data from listen state. 2020-11-17 12:58:07 +03:00
23rd
647cbc5464 Added initial ability to delete recorded voice data. 2020-11-17 12:58:07 +03:00
23rd
131c2e1c56 Slightly refactored waveform paint in voice messages. 2020-11-17 12:58:07 +03:00
23rd
81723a5d19 Slightly improved voice lock design. 2020-11-17 12:58:07 +03:00
John Preston
b3eb7858e6 Save local drafts in scheduled / replies sections.
Fix inline bot switch inline in scheduled / replies sections.
2020-11-17 12:58:07 +03:00
John Preston
4a0efb9114 Remove Q_OBJECT from HistoryWidget. 2020-11-17 12:58:07 +03:00
John Preston
f04b3da76a Add return from bot switch_pm to Scheduled/Replies. 2020-11-17 12:58:06 +03:00
John Preston
4a8b59b788 Pass reply info to Window::PeerMenu. 2020-11-17 12:58:06 +03:00
John Preston
4f22171dd6 Add start bot command and handle via@ links. 2020-11-17 12:57:03 +03:00
John Preston
10adbecb9c Support creating polls in RepliesSection. 2020-11-17 12:56:51 +03:00
John Preston
a8564b166b Add inline bots to ComposeControls. 2020-11-17 12:56:51 +03:00
John Preston
cf6ca3b1ac Handle bot command clicks in Replies / Scheduled. 2020-11-17 12:56:51 +03:00
John Preston
ac02e2be9e Add FieldAutocomplete to ComposeControls. 2020-11-17 12:56:51 +03:00
23rd
5d2ffae215 Improved VoiceRecordButton colors. 2020-11-17 12:56:51 +03:00
23rd
1d120092cf Fixed previous values resetting in VoiceRecordButton. 2020-11-17 12:56:51 +03:00
23rd
2035392564 Removed bezier circle paint when animations are disabled. 2020-11-17 12:56:51 +03:00
23rd
c4897cec0a Replaced dummy lock icons with lock animation. 2020-11-17 12:56:51 +03:00
23rd
dd462eb8cf Slightly improved animation of bezier circle in VoiceRecordButton. 2020-11-17 12:56:51 +03:00
23rd
71e8bda7bb Replaced raw variables for animations in VoiceRecordButton. 2020-11-17 12:56:51 +03:00
23rd
ce1ae5ba12 Removed redundant code from VoiceRecordButton. 2020-11-17 12:56:51 +03:00
23rd
6ae15485ad Added show animation to VoiceRecordButton. 2020-11-17 12:56:51 +03:00
23rd
7a32d78689 Replaced record circle button with bezier circle. 2020-11-17 12:56:51 +03:00
23rd
cb84e70bdc Improved display management of voice record controls. 2020-11-17 12:56:51 +03:00
23rd
b3925a3bec Added touchbar hiding while recording voice message. 2020-11-17 12:56:51 +03:00
23rd
041d8571c2 Added delay for start recording voice message. 2020-11-17 12:56:50 +03:00
23rd
367b487a6c Prettified fast locking of voice record. 2020-11-17 12:56:50 +03:00
23rd
57eb4f8234 Disabled drag'n'drop area when user is recording voice message. 2020-11-17 12:56:50 +03:00
23rd
ad4bf9b5c8 Improved VoiceRecordBar support in ComposeControls. 2020-11-17 12:56:50 +03:00
23rd
6ed7615653 Removed redundant methods for record from SendButton. 2020-11-17 12:56:50 +03:00
23rd
cab22c07a5 Replaced recording animation with simple red circle animation. 2020-11-17 12:56:50 +03:00
23rd
ba3862e70f Added new send recorded voice button with recording animation. 2020-11-17 12:56:50 +03:00
23rd
4970740739 Fixed voice recording lock position on resizing. 2020-11-17 12:56:50 +03:00
23rd
cdb77d46b1 Slightly refactored text drawing in VoiceRecordBar. 2020-11-17 12:56:50 +03:00
23rd
b6743feec1 Added ability to send recording voice message with Enter key. 2020-11-17 12:56:50 +03:00
23rd
fe5242d6d2 Added ability to pass filter for Escape key to voice record bar. 2020-11-17 12:56:50 +03:00
23rd
914e40fb62 Added red coloring of record button. 2020-11-17 12:56:50 +03:00
23rd
326342420d Added animation of voice recording lock with dummy lock icons. 2020-11-17 12:56:50 +03:00
23rd
478f5f671c Added initial implementation of voice recording lock. 2020-11-17 12:56:50 +03:00
23rd
43635f6e4b Slightly optimized paint in VoiceRecordBar. 2020-11-17 12:56:50 +03:00
23rd
ebe1fa7408 Improved duration text paint in VoiceRecordBar. 2020-11-17 12:56:50 +03:00
23rd
5c006002b6 Added appearance animation to VoiceRecordBar. 2020-11-17 12:56:50 +03:00
23rd
e7454e3849 Removed redundant record methods from SendButton. 2020-11-17 12:56:50 +03:00
23rd
3e4866d3b7 Moved active animation processing from SendButton to VoiceRecordBar. 2020-11-17 12:56:50 +03:00
23rd
db564ca486 Replaced voice record processing with VoiceRecordBar in HistoryWidget. 2020-11-17 12:56:50 +03:00
23rd
fd76b44dbd Replaced voice record processing with VoiceRecordBar in ComposeControls. 2020-11-17 12:56:50 +03:00
23rd
112dea8594 Created voice record bar as separated history view class. 2020-11-17 12:56:50 +03:00
23rd
6d775d6f45 Moved structures of compose controls to separated header. 2020-11-17 12:56:50 +03:00
23rd
f7c6876e1b Moved history_view_compose_controls to controls folder. 2020-11-17 12:56:50 +03:00
23rd
8845652f77 Fixed macOS build. 2020-11-17 12:56:50 +03:00
Ilya Fedin
cd67cb1c62 Update media viewer geometry on showing and screen change 2020-11-17 12:49:05 +03:00
John Preston
b71f61dec3 Update submodules. 2020-11-16 19:37:29 +03:00
John Preston
e4d2a66f45 Revert "Re-check the screen media viewer appears on before adjusting geometry"
This reverts commit c3b638449a.

It doesn't work as it was supposed to :(
2020-11-16 19:31:34 +03:00
John Preston
02eea38724 Remove color space before sending in JPG. 2020-11-16 14:22:19 +03:00
John Preston
358228ce00 Update submodules. 2020-11-16 13:09:40 +03:00
John Preston
0089692b52 Fix build for Mac App Store. 2020-11-16 13:08:58 +03:00
Ilya Fedin
9d6e5f2a5b Adapt linux tray icon implementation to the new QIcon::pixmap behavior
More info: https://codereview.qt-project.org/c/qt/qtbase/+/314618
2020-11-16 13:03:43 +03:00
Ilya Fedin
c3b638449a Re-check the screen media viewer appears on before adjusting geometry 2020-11-16 12:39:16 +03:00
Ilya Fedin
2df7e4181f Add a comment about GTK_USE_PORTAL in snap 2020-11-16 12:37:42 +03:00
Ilya Fedin
b4cb47cf7f Prefer gtk3 headers 2020-11-16 12:37:42 +03:00
Ilya Fedin
e4b9900a06 Construct WindowControlsLayout without variable 2020-11-16 12:35:01 +03:00
Ilya Fedin
5c8a19b7f7 Use only really supported icon sizes 2020-11-16 12:34:19 +03:00
Ilya Fedin
620c596200 Remove the last workaround in tray implementation
Since tdesktop gets icon theme pretty well now, there's no need for any workaround.
2020-11-16 12:34:19 +03:00
Ilya Fedin
d7ef484aec Use QWindow::setFlag that doesn't hide the windw 2020-11-16 12:33:55 +03:00
Ilya Fedin
772bd81ea5 Fix typo in the installlauncher cheat code 2020-11-16 12:33:22 +03:00
Ilya Fedin
c8ce5dfa8b Fix escaping in scheme creation on Linux and set -workdir 2020-11-16 12:33:22 +03:00
Ilya Fedin
e64f6f7266 Since changing the ibus portal check, it is not compatible with snap anymore 2020-11-12 18:12:17 +03:00
Ilya Fedin
21133abe13 Fix 30s hang in case ibus portal couldn't be started 2020-11-12 15:51:00 +03:00
Ilya Fedin
8b0fcee6a6 Use docker build in linux action 2020-11-12 14:29:42 +03:00
zurg3
a768b65295 Updated FFmpeg version in GitHub Actions workflows 2020-11-10 16:23:37 +03:00
zurg3
a68d9b4522 Updated Qt version in GitHub Actions workflows 2020-11-10 16:23:37 +03:00
John Preston
8a9317f9e1 Download video avatars as .mp4 in media viewer.
Fixes #9017.
2020-11-09 15:05:36 +03:00
John Preston
db23485fa2 Fix quit from fullscreen on macOS. 2020-11-09 13:47:53 +03:00
John Preston
87e4bb1059 Fix scroll position restore with pinned bar. 2020-11-09 12:57:49 +03:00
John Preston
091b62bed4 Allow cancel search-in-chat and keep search query. 2020-11-09 12:41:59 +03:00
John Preston
167a73ef1b Add sent/read checks for some service messages. 2020-11-09 12:36:15 +03:00
Ilya Fedin
91a2ec225a Add support for open with on linux 2020-11-09 11:23:01 +03:00
Ilya Fedin
3a45957ceb Set parent window ID for portal autostart dialog 2020-11-09 11:19:03 +03:00
Ilya Fedin
acaf8e4931 Use g_filename_to_uri 2020-11-09 11:19:03 +03:00
Ilya Fedin
e0de4dbc5e Replace new #ifdef Q_OS_LINUX in main_window.cpp added a month ago 2020-11-09 11:19:03 +03:00
Ilya Fedin
876c57dcfb Fix getting FileChooser portal version 2020-11-09 11:19:03 +03:00
Ilya Fedin
f980cade39 Use static QFile methods in linux platform code 2020-11-09 11:19:03 +03:00
Ilya Fedin
3d18d28dc5 Use kIconName on icon creating 2020-11-09 11:19:03 +03:00
Ilya Fedin
e04598835b Move _monitorRect and _monitorLastGot to psDesktopRect method 2020-11-09 11:19:03 +03:00
Ilya Fedin
eee3049fdd Remove definitions of unused psLocalServerPrefix and psInitLogs 2020-11-09 11:19:03 +03:00
John Preston
d97dcaec62 Add possibility to build on Windows for x64. 2020-11-06 20:22:02 +03:00
John Preston
05f43cabdf Beta version 2.4.9.
- Fix crash in tray icon removing. (macOS only)
2020-11-06 17:24:30 +03:00
John Preston
65ba81f504 Beta version 2.4.8.
- Upgrade Qt to version 5.15.1.
- Upgrade FFmpeg to version 4.2.
- Upgrade OpenAL to version 1.20.1.
2020-11-06 11:21:34 +03:00
John Preston
71de246411 Disable Linux GLIBC wraps for special builds. 2020-11-06 11:21:34 +03:00
John Preston
547251f67c Fix deprecation warnings when building with FFmpeg 4.2. 2020-11-06 11:21:34 +03:00
John Preston
951bb22c38 Update docs/docker to use FFmpeg 4.2 / OpenAL 1.20.1. 2020-11-06 11:21:34 +03:00
John Preston
d9df82642d Patch FFmpeg asm objects for Xcode 12 linking. 2020-11-06 11:21:34 +03:00
John Preston
74d2313784 Build Linux version with Qt 5.15.1 in CentOS 7 docker. 2020-11-06 11:21:34 +03:00
John Preston
80c4ecb9bf Migrate CentOS docker file to Qt 5.15.1. 2020-11-06 11:21:34 +03:00
John Preston
b1e2beba2c Fix macOS tray icon on Big Sur & Qt 5.15.1. 2020-11-06 11:21:34 +03:00
John Preston
117de5a1f9 Build macOS version with Qt 5.15.1. 2020-11-06 11:21:34 +03:00
John Preston
9210cf6d36 Build Windows version with Qt 5.15.1. 2020-11-06 11:21:34 +03:00
Ilya Fedin
f7dcf6ce81 Hide IsXDGDesktopPortalPresent in a private namespace 2020-11-06 11:20:47 +03:00
Ilya Fedin
6c023084d9 Move the excluding portal checks to UseXDGDesktopPortal 2020-11-06 11:20:47 +03:00
Ilya Fedin
f521275acc Fix AreQtPluginsBundled to include static binary 2020-11-06 09:57:47 +03:00
Ilya Fedin
aec2b8df7e Fix choosing directories in snap and flatpak 2020-11-06 09:48:42 +03:00
Ilya Fedin
5c8820d5d8 Use QClipboard::supportsSelection instead of ifdefs 2020-11-06 08:56:50 +03:00
John Preston
620639ef83 Version 2.4.7.
- Fix playback display in albums of music files.
- Several crash fixes.
2020-11-05 17:54:49 +03:00
Ilya Fedin
9329ce9059 Pin tg_owt commit in snap and add -DBUILD_SHARED_LIBS=OFF 2020-11-05 17:53:09 +03:00
23rd
42d4fdb89f Fixed preview display of small media in SendFilesBox. 2020-11-05 17:51:28 +03:00
23rd
fad7996e63 Added delete prevent in SendFilesBox when it has single item. 2020-11-05 17:51:27 +03:00
John Preston
039cad21a5 Fix view refresh for album part messages.
Fixes #8974.
2020-11-05 17:50:58 +03:00
John Preston
3fdd6848c5 Fix possible crash on macOS wake. 2020-11-05 15:05:29 +03:00
John Preston
c0043d56ea Fix crash in search row select in privacy edition. 2020-11-05 14:58:46 +03:00
John Preston
ddbd36e446 Cancel search in chat doesn't reset search query. 2020-11-05 14:58:46 +03:00
John Preston
d09ece4203 Fix albums of music files. 2020-11-05 14:58:46 +03:00
Ilya Fedin
2b39da483b Fix IBus portal service name 2020-11-05 14:38:41 +03:00
Ilya Fedin
d9711f8ebd QDir::tempPath already has fallback to /tmp 2020-11-05 14:38:25 +03:00
Ilya Fedin
ede7ad1a4c Remove TDESKTOP_FORCE_PANEL_ICON variable since tdesktop gets current icon theme just fine now 2020-11-05 14:38:03 +03:00
Ilya Fedin
55167ea95b Handle snap icon problem in snapcraft.yaml rather than in code 2020-11-05 14:38:03 +03:00
John Preston
7dffc6e912 Version 2.4.6.
- Fix image compression option when sending files with drag-n-drop.
- Fix caption text selection in media albums.
- Fix drafts display in personal chats in the chats list.
- Bug fixes and other minor improvements.
2020-11-02 13:54:30 +03:00
John Preston
f2867df340 Fix sending of album with videos.
Fixes #8960.
2020-11-02 11:50:14 +03:00
John Preston
a21b6d7416 Fix restoring scroll state with a pinned bar. 2020-11-02 11:44:05 +03:00
John Preston
07f07c5eeb Fix selection in album captions.
Fixes #8950.
2020-11-02 11:26:40 +03:00
John Preston
b179e5332a Improve layout of file albums with views/replies. 2020-11-02 11:26:40 +03:00
John Preston
5cc1871f2f Fix caption/comment label in SendFilesBox. 2020-11-02 11:26:39 +03:00
John Preston
39777f6149 Fix compress images with drag-n-drop.
Fixes #8943.
2020-11-02 11:26:39 +03:00
John Preston
6660206e61 Fix poll results opening from pinned section.
Fixes #8942.
2020-11-02 11:26:39 +03:00
John Preston
9592e7dfc8 Highlight telegram/telegraph/telescope links. 2020-11-02 11:26:39 +03:00
John Preston
4432863612 Fix draft display in dialogs list. 2020-11-02 11:26:39 +03:00
Ilya Fedin
b8018f5a7f Split system drag to a separate method in PiP 2020-11-02 10:23:06 +03:00
Ilya Fedin
44c24f9fff Fix TDESKTOP_USE_PORTAL on gtk environments 2020-11-02 10:20:53 +03:00
Ilya Fedin
204a08df14 Add a cheat code to install launcher on Linux 2020-11-02 10:17:24 +03:00
Ilya Fedin
0881e5b20d Use new AL_SOFT_direct_channels_remix extension 2020-11-02 10:16:34 +03:00
Ilya Fedin
3bd34fcff0 Remove autodark cheat code since there are an UI setting for this 2020-11-02 10:16:34 +03:00
Crist Ye
60f91ebce4 Using MS/Apple official names for stores (#8959) 2020-11-02 11:14:57 +04:00
Ilya Fedin
12a77cffd8 Add flatpak and snap update URLs 2020-11-01 18:30:12 +03:00
Ilya Fedin
03c2fc2c48 Use ibus portal whenever it present 2020-11-01 18:28:52 +03:00
GitHub Action
b7d7ba82f8 Update User-Agent for DNS to Chrome 86.0.4240.111. 2020-11-01 18:28:05 +03:00
Ilya Fedin
ad54fc6459 Try to use portals for file dialog in snap, again 2020-11-01 18:27:31 +03:00
23rd
101ba05ce3 Updated doc for Windows. 2020-11-01 18:26:13 +03:00
John Preston
6ab31219ed Workaround crash in OpenAL library.
Fixes #8887.

See https://github.com/kcat/openal-soft/issues/486
2020-11-01 18:26:04 +03:00
John Preston
8afc245422 Try to workaround MSVC compiler bug. 2020-10-31 15:14:34 +03:00
John Preston
303684fef5 Version 2.4.5: Fix build on Xcode 12 and Linux. 2020-10-30 21:30:55 +03:00
John Preston
cc9fa178e6 Version 2.4.5.
- Pin several messages in any chat, including one-on-one chats.
- Jump between pinned messages or open them all on a separate page.
- Send several music tracks as a playlist.
- Send several files as an album in one chat bubble.
- Send a 🎰 emoji to any chat to see if you hit the jackpot.
- Hide Telegram taskbar icon on Linux in Settings > Advanced.
2020-10-30 21:29:59 +03:00
John Preston
e4e1f7f5d6 Try creating base dir in FileWriteDescriptor. 2020-10-30 18:32:22 +03:00
John Preston
99111cc1cc Fix links in photo captions. 2020-10-30 18:32:22 +03:00
John Preston
0687cea1ed Fix unpinning all messages. 2020-10-30 18:32:22 +03:00
John Preston
b7319c00b9 Fix go to original button in Pinned section. 2020-10-30 18:32:22 +03:00
23rd
9a2fcdde29 Fixed fast share button's display in section of pinned messages. 2020-10-30 18:32:22 +03:00
John Preston
de459fa1fe Improve slot machine animations. 2020-10-30 18:32:22 +03:00
John Preston
a532ae81b3 Fix cancel of album parts uploading. 2020-10-30 18:32:22 +03:00
John Preston
3febace163 Fix scroll through pinned items. 2020-10-30 18:32:22 +03:00
John Preston
324affb8b9 Fix go to original button in outgoing albums. 2020-10-30 18:32:22 +03:00
John Preston
c35b6e1209 Highlight internal links in Bio. 2020-10-30 18:32:22 +03:00
John Preston
600cf83c3f Custom enter from event loop in applicationDidBecomeActive. 2020-10-30 18:32:21 +03:00
John Preston
6e682643df Fix captions selection in column albums. 2020-10-30 18:32:21 +03:00
John Preston
6d9c529a65 Fix caption edit in column albums. 2020-10-30 18:32:21 +03:00
John Preston
78492386c4 Fix pinned bar consecutive animations. 2020-10-30 18:32:21 +03:00
John Preston
793ec84098 Fix pinned message of self-destruct media. 2020-10-30 18:32:21 +03:00
John Preston
06ee21041d Use RelWithDebInfo for OpenAL on Windows. 2020-10-30 18:32:21 +03:00
John Preston
48dad5f477 Improve typing status sending. 2020-10-30 18:32:21 +03:00
John Preston
53c308c24b Loop pinned messages in the top bar. 2020-10-30 18:32:21 +03:00
John Preston
08f7069370 Implement new choosing of shown pinned message. 2020-10-30 18:32:21 +03:00
John Preston
77fa29f8ce Pin/unpin first item of an album. 2020-10-30 18:32:21 +03:00
John Preston
1be064e2dc Don't pin for other by default. 2020-10-30 18:32:21 +03:00
John Preston
59e0717dac Show pin/unpin correctly in Recent Actions. 2020-10-30 18:32:21 +03:00
John Preston
75c420b9d7 Check items before deleting by 'Delete' key. 2020-10-30 18:32:21 +03:00
John Preston
e4f039b141 Improve pinned messages title. 2020-10-30 18:32:21 +03:00
John Preston
2233058ae0 Move pin icon to the right. 2020-10-30 18:32:21 +03:00
John Preston
ea6821aca2 Improve animation in pinned bar. 2020-10-30 18:32:21 +03:00
John Preston
c2753a9caf Add checkbox 'Pin also for {user}'. 2020-10-30 18:32:21 +03:00
John Preston
77894d1445 Fix sending files in scheduled messages. 2020-10-30 18:32:21 +03:00
John Preston
68041d2ffb Merge pinned list with migrated legacy group. 2020-10-30 18:32:20 +03:00
John Preston
18d218044c Fix crash when adding more files to SendFilesBox. 2020-10-30 18:32:20 +03:00
John Preston
12debce246 Show checks when sending file albums. 2020-10-30 18:32:20 +03:00
John Preston
3dbc131b98 Show pin icon in pinned messages. 2020-10-30 18:32:20 +03:00
John Preston
994e3d8da7 Add hide / unpin all button in pinned section. 2020-10-30 18:32:20 +03:00
John Preston
61d335469f Improve context menu in pinned section. 2020-10-30 18:32:20 +03:00
John Preston
ebbe75ac0a Fix scrolling to message in pinned section. 2020-10-30 18:32:20 +03:00
John Preston
cd5cad72bd Use only shared media code for pinned tracking. 2020-10-30 18:32:20 +03:00
John Preston
59b4c5dad9 Show winning top with three same values in slot machine. 2020-10-30 18:32:20 +03:00
John Preston
5f932a8828 Show 'View X Replies' in all groups. 2020-10-30 18:32:20 +03:00
John Preston
698c9fc4be Fix preloading of pinned messages. 2020-10-30 18:32:20 +03:00
John Preston
47f5a66350 Fix build on macOS. 2020-10-30 18:32:20 +03:00
John Preston
d742fa32de Add button to show all pinned messages. 2020-10-30 18:32:20 +03:00
John Preston
6b38b94db4 Don't capture 'this' in SendFilesBox::Block. 2020-10-30 18:32:20 +03:00
John Preston
fc92e3fadd Add pinned messages section. 2020-10-30 18:32:20 +03:00
John Preston
aefef948cd Improve multi-pinned message bar. 2020-10-30 18:32:20 +03:00
John Preston
a614ccad97 Correctly check media when editing files. 2020-10-30 18:32:19 +03:00
John Preston
c4af731b19 Wrap messageActionGeoProximityReached service message. 2020-10-30 18:32:19 +03:00
John Preston
263d6a30f2 Improve grouped files layout in chat. 2020-10-30 18:32:19 +03:00
John Preston
012ebdd15e Fix grouping of music files / just files. 2020-10-30 18:32:19 +03:00
John Preston
0d37949e74 Improve SendFilesBox previews layout. 2020-10-30 18:32:19 +03:00
John Preston
d7fe2948ac Add edit/remove buttons to Single[File|Media]Preview. 2020-10-30 18:32:19 +03:00
John Preston
5589f51369 Allow delete / replace items in SendFilesBox. 2020-10-30 18:32:19 +03:00
John Preston
bb4fdde616 Fix sending many files with a comment. 2020-10-30 18:32:19 +03:00
John Preston
85d08c8f52 Send files grouped in albums, show captions. 2020-10-30 18:32:19 +03:00
John Preston
86612f0a67 Allow dropping any amount of any files. 2020-10-30 18:32:19 +03:00
John Preston
843fba61ee Allow adding any amount of files in SendFilesBox. 2020-10-30 18:32:19 +03:00
John Preston
0539cc9448 Add a way to recreate SendFilesBox content. 2020-10-30 18:32:19 +03:00
John Preston
202534575b Allow many previews in SendFilesBox. 2020-10-30 18:32:19 +03:00
John Preston
8d2fa313b7 Add setting for grouping files. 2020-10-30 18:32:19 +03:00
John Preston
c2f0bcf933 Keep first game sticker frames inside the binary. 2020-10-30 18:32:19 +03:00
John Preston
7f956d32a6 Support slot machine game. 2020-10-30 18:32:18 +03:00
John Preston
3feea400af Fix build on macOS. 2020-10-30 18:32:18 +03:00
John Preston
64ac6b18bf Move SingleMediaPreview to td_ui. 2020-10-30 18:32:18 +03:00
John Preston
8b96f4c214 Move Media::Clip::Reader and FileLocation to td_ui. 2020-10-30 18:32:18 +03:00
John Preston
05eb549a3d Move App::roundRect to Ui::FillRoundRect. 2020-10-30 18:32:18 +03:00
John Preston
b3b11bd9e7 Move PreparedFile/PreparedList to td_ui. 2020-10-30 18:32:18 +03:00
John Preston
39cf51c066 Move SendButton/EmojiButton to td_ui. 2020-10-30 18:32:18 +03:00
John Preston
af1854e877 Use Ui::PinnedBar in Replies section. 2020-10-30 18:32:18 +03:00
John Preston
0873db58d0 Moved PinnedBar to Ui:: in td_ui. 2020-10-30 18:32:18 +03:00
John Preston
37fb94cbfb Load and show image previews in pinned bar. 2020-10-30 18:32:18 +03:00
John Preston
9b4b15ee6d Handle pinned bar clicks. 2020-10-30 18:32:18 +03:00
John Preston
91a0416037 Implement local pinned bar hiding. 2020-10-30 18:32:18 +03:00
John Preston
67290eed58 Use new message bar for pinned message. 2020-10-30 18:32:18 +03:00
John Preston
ae298818a8 Implement message bar with animations. 2020-10-30 18:32:17 +03:00
John Preston
b9f40e35cd Switch between pinned messages in chat. 2020-10-30 18:32:17 +03:00
John Preston
ec35e3f081 Track multiple pinned messages in MessagesList. 2020-10-30 18:32:17 +03:00
John Preston
399b03beb2 Implement multi-song albums display. 2020-10-30 18:32:17 +03:00
John Preston
cc28ba4284 Update API scheme to layer 120. 2020-10-30 18:32:17 +03:00
Ilya Fedin
eb27763cae Restore Ui::hideLayer call in ShowInFolder on Linux 2020-10-30 18:20:38 +03:00
Ilya Fedin
30f07280aa Add an action to test docker image build 2020-10-30 17:11:02 +03:00
Ilya Fedin
18fe87c0d4 Add MozJPEG to docker 2020-10-30 17:11:02 +03:00
Ilya Fedin
02818a8251 Use new tg_owt installation support in snap 2020-10-30 17:10:08 +03:00
23rd
943593526f Added ability to see attached stickers from sections. 2020-10-30 13:18:40 +03:00
23rd
8d424f6eaf Added ability to see attached stickers from admin log. 2020-10-30 13:18:40 +03:00
23rd
665e322fce Added ability to see attached stickers on documents.
Fixed #8927.
2020-10-30 13:18:40 +03:00
23rd
391ec8ac28 Moved public var indicating stickers presence to private in PhotoData. 2020-10-30 13:18:40 +03:00
23rd
1459e6f38e Moved request for attached stickers to separate file. 2020-10-30 13:18:40 +03:00
John Preston
98afc99a8f Update submodules and instructions. 2020-10-30 13:17:02 +03:00
Ilya Fedin
94d37509c1 Add $SNAPCRAFT_ARCH_TRIPLET to paths 2020-10-30 12:12:39 +03:00
Ilya Fedin
822d1718a9 Use MozJPEG 2020-10-30 12:12:39 +03:00
andry-dev
e31ffb699a Ignore additional video streams inside an audio file.
Fixes #5840, #5357 and #4327.
2020-10-30 11:57:57 +03:00
Ilya Fedin
bb94507af1 Use UrlClickHandler::Open instead of File::OpenUrl 2020-10-30 11:52:10 +03:00
Ilya Fedin
bbc59c1a99 Use Launcher::initHook on Linux 2020-10-30 11:52:10 +03:00
Ilya Fedin
9b99bb172a Make methods called from static methods private 2020-10-30 11:30:03 +03:00
Ilya Fedin
af6b07b780 Use crl::on_main in MainWindow::sniSignalEmitted 2020-10-30 11:30:03 +03:00
Ilya Fedin
d73d3cd43d Implement ShowWindowMenu for XCB 2020-10-30 11:29:02 +03:00
Ilya Fedin
8f5b136003 Implement possibility to hide taskbar icon on Linux 2020-10-30 11:27:42 +03:00
Ilya Fedin
49e96d857a Add drag distance for move-by-titlebar to process double click right 2020-10-30 10:56:57 +03:00
Ilya Fedin
a38b4f039a Use some methods from lib_base 2020-10-30 10:52:49 +03:00
23rd
df9c7f07a1 Fixed crashpad build on macOS. 2020-10-29 23:57:41 +03:00
Ilya Fedin
6e42d54632 Remove forgotten sws_scale check
It should been removed in 7d29f9ce17, but was forgotten
2020-10-29 17:40:36 +03:00
Ilya Fedin
9818724382 CentOS-based Docker build 2020-10-29 12:38:24 +03:00
John Preston
35c639e4b0 Revert 245d644cd7.
See https://github.com/telegramdesktop/tdesktop/issues/8914.
2020-10-28 10:07:00 +03:00
Ilya Fedin
92695f3ab0 Make stale bot more patient & change its message 2020-10-28 10:01:14 +03:00
Ilya Fedin
3742db2b91 Use portals via glib to open urls & files in snap 2020-10-28 09:57:46 +03:00
Ilya Fedin
152f1ef17f Use Core::UpdaterDisabled where a check is for installed or not 2020-10-28 09:57:10 +03:00
GitHub Action
fbacb6c0a4 Update User-Agent for DNS to Chrome 86.0.4240.75. 2020-10-27 20:46:52 +03:00
23rd
3883a268c7 Fixed warnings from Github CI. 2020-10-27 20:17:14 +03:00
23rd
1a2afda09c Changed behavior of user-agent updater to open pull requests. 2020-10-27 20:17:14 +03:00
23rd
bcc11d7850 Changed shortcut to open contacts to avoid conflict with formatting.
Fixed #8896.
2020-10-27 20:17:14 +03:00
John Preston
b814f320c6 Update lib_base submodule. 2020-10-27 18:31:00 +03:00
John Preston
08b513dd7e Update lib_base submodule. 2020-10-27 17:45:39 +03:00
Ilya Fedin
41e0e4fba7 Use glib to open files & urls 2020-10-27 17:39:37 +03:00
Ilya Fedin
9ab221d4c9 Remove Platform:: where is not needed in linux platform files
Fix lines length in notifications_manager_linux.cpp
2020-10-27 17:37:33 +03:00
Ilya Fedin
022fc9a779 Fix gtk dialog condition + make it more readable 2020-10-27 17:37:33 +03:00
Ilya Fedin
7ff99cdbf7 Use LONG_PTR with SetWindowLongPtr 2020-10-26 16:57:57 +03:00
Ilya Fedin
b0ce88395f Don't stream videos when external player is used
External player feature doesn't work otherwise
2020-10-26 14:58:39 +03:00
Ilya Fedin
f749647567 Check Qt version in runtime in CanOpenDirectoryWithPortal
It is not guaranteed that app is running with the same Qt version that was compiled
2020-10-26 14:58:06 +03:00
Ilya Fedin
77e1b9f156 Change socket path length condition to >=
Looks like 108 is the length including \0, therefore actual limit is 107
2020-10-24 09:10:16 +03:00
John Preston
9717a8b5fa Version 2.4.4.
- Fix application quit on call end with main window hidden in tray.
- Update OpenAL library on Windows.
- Several crash fixes.
2020-10-23 19:40:48 +03:00
John Preston
aff4f69b64 Don't quit on call end with window hidden in tray.
Fixes #8585.
2020-10-23 19:37:58 +03:00
John Preston
9de4c42555 Keep sending typings up to 30s after offline. 2020-10-23 18:25:55 +03:00
John Preston
1de144a48d Show transfer ownership button for non-anonymous admins. 2020-10-23 17:37:27 +03:00
John Preston
0690d14f1b Don't send typings to bots and offline users. 2020-10-23 17:28:11 +03:00
John Preston
53ac4c00ad Track deleted messages carefully.
Fixes #8855.
2020-10-23 16:35:43 +03:00
John Preston
f064692e57 Close media viewer when photo message is deleted. 2020-10-23 15:28:20 +03:00
John Preston
3d54a263b8 Stop playing documents when items are deleted. 2020-10-23 15:22:38 +03:00
23rd
47bb8ec687 Added Github Action that updates user-agent for DNS. 2020-10-23 15:13:20 +03:00
23rd
3a2b772a5d Added spellchecker to Replies / Scheduled messages sections.
Fixed #8793.
2020-10-23 13:32:44 +03:00
23rd
bc8f8bc68c Added auto-closing to some boxes which depend on certain message. 2020-10-23 13:32:44 +03:00
23rd
bc7975ece7 Fixed crash when user reschedules already sent message.
Fixed #8867.
2020-10-23 13:32:43 +03:00
23rd
52cca98144 Fixed replies button display in section of scheduled messages. 2020-10-23 13:32:43 +03:00
23rd
5540b0bb8b Fixed glitch for scheduled messages with elapsed date in channels. 2020-10-23 13:32:32 +03:00
23rd
7de9bcad03 Added ability to open contacts with shortcut.
Fixed #8775.
2020-10-23 13:31:24 +03:00
23rd
367b028094 Moved contacts box preparing to single place. 2020-10-23 13:31:24 +03:00
John Preston
8b27aa5331 Update cmake_helpers submodule. 2020-10-23 13:11:42 +03:00
John Preston
9697567b8d Add some more open file warnings. 2020-10-23 13:10:43 +03:00
Ilya Fedin
1fdfa94497 Remove explicit Opus clone step from macos action
Since no longer needed
2020-10-23 12:51:52 +03:00
John Preston
1373bd0af1 Use OpenAL 1.20.1 with bugfix backport on Windows. 2020-10-23 12:47:41 +03:00
Ilya Fedin
4f2b0531f8 Replace GDBusProxy with GDBusConnection in NotificationData 2020-10-23 11:29:35 +03:00
Ilya Fedin
ca67ac913f Check for KDE portal backend when using portals on KDE 2020-10-23 11:28:18 +03:00
Ilya Fedin
4033a091b5 Hide mark as read button in notifications when app is pass-code locked 2020-10-23 11:25:18 +03:00
Ilya Fedin
0179a2ca10 Rename InstallMainDesktopFile to InstallLauncher 2020-10-23 11:25:18 +03:00
Ilya Fedin
f58874572d Check actual socket path length rather than InSnap/InFlatpak 2020-10-23 11:25:18 +03:00
Ilya Fedin
143b9682a4 Get rid of lxqt-qtplugin
It is stil impossible to build it statically and it seems that reading icon theme from gtk is pretty enough
2020-10-23 11:24:37 +03:00
John Preston
00c962e557 Bump cmake_helpers submodule. 2020-10-23 11:24:02 +03:00
John Preston
1cabfaa6a4 Fix cancel / crash in sending album to scheduled messages.
Fixes #8788
2020-10-23 11:22:38 +03:00
Ilya Fedin
b788ae0ae4 Add stale bot configuration 2020-10-23 11:18:14 +03:00
Ilya Fedin
3f6399f13d Log getting GTK settings 2020-10-21 10:57:40 +03:00
Ilya Fedin
b6fc418d32 01org/libva -> intel/libva 2020-10-20 09:37:56 +03:00
Ilya Fedin
245d644cd7 Add always on top hint for media view window
To avoid overlapping by panels in KDE
2020-10-20 09:37:31 +03:00
Ilya Fedin
2aa0b674cd Use new XCB methods from lib_base 2020-10-16 16:12:38 +03:00
Ilya Fedin
654784ce9f Use external_xcb and external_glib 2020-10-16 16:12:38 +03:00
John Preston
744eccc51e Version 2.4.3: Fix build for OS X 10.10-10.11. 2020-10-07 18:18:58 +03:00
Ilya Fedin
ce49714533 Use FindALSA instead of pkg-config 2020-10-07 17:10:27 +03:00
John Preston
ae2c858dc9 Version 2.4.3: Update lib_ui submodule. 2020-10-07 15:10:31 +03:00
John Preston
f0b5dc42f9 Version 2.4.3.
- Fix sending voice messages in scheduled messages section.
- Fix deleting profile / group / channel photos.
- Several crash fixes.
2020-10-07 15:08:52 +03:00
John Preston
9c213bf1c0 Warn when launching .sh on Windows.
Fixes #8753.
2020-10-07 14:41:21 +03:00
John Preston
0c1175f9cd Fix broadcast field placeholder update. 2020-10-07 14:41:21 +03:00
23rd
0c1312419a Fixed crash when user schedules message with elapsed date.
Fixed #8764.
2020-10-07 14:30:29 +03:00
23rd
7e9695b213 Added missed *.mov extension to dialog files filter for album items. 2020-10-07 13:09:15 +03:00
Ilya Fedin
093fcc3821 Subscribe to StatusNotifierHostRegistered signal 2020-10-07 13:06:06 +03:00
Ilya Fedin
6f89598a7b Clean old attempts to register url scheme on scheme registration 2020-10-07 12:55:34 +03:00
John Preston
6ccd53689d Fix crash in shared media search message delete.
Fixes #8237.
2020-10-06 14:20:49 +03:00
John Preston
cd506dfff5 Fix reply_to_top_id in local sent stickers.
Fixes #8758.
2020-10-06 14:01:19 +03:00
John Preston
5a3733b5b6 Fix selecting stickers in Replies section. 2020-10-06 13:46:19 +03:00
John Preston
22a85016e3 Show rank in anonymous outgoing messages. 2020-10-06 10:23:58 +03:00
John Preston
26c7a95a9f Use network-manager-observe in snap version. 2020-10-06 10:15:22 +03:00
John Preston
9acf617c9f Show full cached song as downloaded. 2020-10-06 10:10:22 +03:00
John Preston
72af170484 Force call panel to be a separate window.
I hope this fixes #8715.
2020-10-05 18:30:08 +03:00
John Preston
4db2505f5d Fix deleting profile photos.
Fixes #8720.
2020-10-05 18:26:29 +03:00
23rd
4d40336be0 Fixed voice recording cancel. 2020-10-05 17:08:52 +03:00
John Preston
616531b0d0 Fix author signature in discussion posts. 2020-10-05 16:21:34 +03:00
John Preston
473803edb8 Fix comments button getState / remove. 2020-10-05 16:21:34 +03:00
Ilya Fedin
a33ca97298 Find taskbar window on the same monitor 2020-10-05 13:50:03 +03:00
John Preston
a711c89409 Fix crash on wrong server response.
Fixes #8724.
2020-10-05 12:58:12 +03:00
John Preston
24ec0e0866 Fix recording stop in voice messages. 2020-10-05 12:58:12 +03:00
John Preston
e6df927e30 Correctly use alcGetIntegerv. 2020-10-05 12:58:12 +03:00
Ilya Fedin
638ea3111f Fallback to D-Bus methods if XCB-based LastUserInputTime failed 2020-10-05 10:10:40 +03:00
490 changed files with 21952 additions and 11485 deletions

21
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 180
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 30
# Issues with these labels will never be considered stale
exemptLabels: []
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: |
Hey there!
This issue was inactive for a long time and will be automatically closed in 30 days if there isn't any further activity. We therefore assume that the user has lost interest or resolved the problem on their own.
Don't worry though; if this is an error, let us know with a comment and we'll be happy to reopen the issue.
Thanks!
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
# Process only issues
only: issues

25
.github/workflows/docker.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: Docker.
on:
push:
paths:
- '.github/workflows/docker.yml'
- 'Telegram/build/docker/centos_env/**'
pull_request:
paths:
- '.github/workflows/docker.yml'
- 'Telegram/build/docker/centos_env/**'
jobs:
docker:
name: Ubuntu
runs-on: ubuntu-latest
steps:
- name: Clone.
uses: actions/checkout@v2
with:
submodules: recursive
- name: Docker image build.
run: docker build -t telegram_desktop Telegram/build/docker/centos_env

View File

@@ -12,7 +12,7 @@ jobs:
run: |
tag=$(git ls-remote --tags git://github.com/$GITHUB_REPOSITORY | cut -f 2 | tail -n1)
echo $tag
echo ::set-env name=LATEST_TAG::$tag
echo "LATEST_TAG=$tag" >> $GITHUB_ENV
- name: Get the latest macOS version.
shell: python
@@ -28,7 +28,7 @@ jobs:
ver = itemlist[0].attributes['sparkle:shortVersionString'].value;
print(ver);
subprocess.check_call("echo ::set-env name=%s::%s" % ("LATEST_MACOS", ver), shell=True);
open(os.environ['GITHUB_ENV'], "a").write("LATEST_MACOS=" + ver);
- name: Check a version from an issue.
uses: actions/github-script@0.4.0

View File

@@ -45,71 +45,38 @@ on:
jobs:
linux:
name: Ubuntu 14.04
name: CentOS 7
runs-on: ubuntu-latest
container: ubuntu:trusty
container:
image: docker.pkg.github.com/telegramdesktop/tdesktop/centos_env
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
defaults:
run:
shell: scl enable devtoolset-8 -- bash --noprofile --norc -eo pipefail {0}
strategy:
matrix:
defines:
- ""
- "DESKTOP_APP_DISABLE_DBUS_INTEGRATION"
- "DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION"
- "TDESKTOP_DISABLE_GTK_INTEGRATION"
env:
GIT: "https://github.com"
QT: "5_12_8"
QT_PREFIX: "/usr/local/desktop-app/Qt-5.12.8"
OPENSSL_VER: "1_1_1"
OPENSSL_PREFIX: "/usr/local/desktop-app/openssl-1.1.1"
CMAKE_VER: "3.17.0"
UPLOAD_ARTIFACT: "false"
ONLY_CACHE: "false"
MANUAL_CACHING: "6"
DOC_PATH: "docs/building-cmake.md"
AUTO_CACHING: "1"
steps:
- name: Get repository name.
run: echo ::set-env name=REPO_NAME::${GITHUB_REPOSITORY##*/}
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
- name: Disable man for further package installs.
- name: Yum install.
run: |
cfgFile="/etc/dpkg/dpkg.cfg.d/no_man"
sudo touch $cfgFile
p() {
sudo echo "path-exclude=/usr/share/$1/*" >> $cfgFile
}
p man
p locale
p doc
- name: Apt install.
shell: bash
run: |
sudo apt-get update
sudo apt-get install software-properties-common -y && \
sudo add-apt-repository ppa:git-core/ppa -y && \
sudo apt-get update && \
sudo apt-get install git libexif-dev liblzma-dev libz-dev libssl-dev \
libgtk2.0-dev libice-dev libsm-dev libicu-dev libdrm-dev dh-autoreconf \
autoconf automake build-essential libxml2-dev libass-dev libfreetype6-dev \
libgpac-dev libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev \
libvorbis-dev libxcb1-dev libxcb-image0-dev libxcb-shm0-dev \
libxcb-screensaver0-dev libjpeg-dev ninja-build \
libxcb-xfixes0-dev libxcb-keysyms1-dev libxcb-icccm4-dev libatspi2.0-dev \
libxcb-render-util0-dev libxcb-util0-dev libxcb-xkb-dev libxrender-dev \
libasound-dev libpulse-dev libxcb-sync0-dev libxcb-randr0-dev libegl1-mesa-dev \
libx11-xcb-dev libffi-dev libncurses5-dev pkg-config texi2html bison yasm \
zlib1g-dev xutils-dev python-xcbgen chrpath gperf wget -y --force-yes && \
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
sudo apt-get update && \
sudo apt-get install gcc-8 g++-8 -y && \
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 60 && \
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 60 && \
sudo update-alternatives --config gcc && \
sudo add-apt-repository --remove ppa:ubuntu-toolchain-r/test -y
yum -y autoremove git
yum -y install https://packages.endpoint.com/rhel/7/os/x86_64/endpoint-repo-1.7-1.x86_64.rpm
yum -y install git
- name: Clone.
uses: actions/checkout@v2
@@ -118,437 +85,11 @@ jobs:
path: ${{ env.REPO_NAME }}
- name: First set up.
shell: bash
run: |
gcc --version
gcc --version > CACHE_KEY.txt
echo $MANUAL_CACHING >> CACHE_KEY.txt
if [ "$AUTO_CACHING" == "1" ]; then
thisFile=$REPO_NAME/.github/workflows/linux.yml
echo `md5sum $thisFile | cut -c -32` >> CACHE_KEY.txt
fi
md5cache=$(md5sum CACHE_KEY.txt | cut -c -32)
echo ::set-env name=CACHE_KEY::$md5cache
mkdir -p Libraries
cd Libraries
echo ::set-env name=LibrariesPath::`pwd`
- name: Patches.
run: |
echo "Find necessary commit from doc."
checkoutCommit=$(grep -A 1 "cd patches" $REPO_NAME/$DOC_PATH | sed -n 2p)
cd $LibrariesPath
git clone $GIT/desktop-app/patches.git
cd patches
eval $checkoutCommit
- name: CMake.
run: |
cd $LibrariesPath
file=cmake-$CMAKE_VER-Linux-x86_64.sh
wget $GIT/Kitware/CMake/releases/download/v$CMAKE_VER/$file
sudo mkdir /opt/cmake
sudo sh $file --prefix=/opt/cmake --skip-license
sudo ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
rm $file
cmake --version
- name: Opus cache.
id: cache-opus
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/opus
key: ${{ runner.OS }}-opus-${{ env.CACHE_KEY }}
- name: Opus.
if: steps.cache-opus.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
git clone -b v1.3 --depth=1 $GIT/xiph/opus
cd opus
./autogen.sh
./configure
make -j$(nproc)
- name: Opus install.
run: |
cd $LibrariesPath/opus
sudo make install
- name: Libva.
run: |
cd $LibrariesPath
git clone $GIT/01org/libva.git
cd libva
./autogen.sh --enable-static
make -j$(nproc)
sudo make install
cd ..
rm -rf libva
- name: Libvdpau.
run: |
cd $LibrariesPath
git clone -b libvdpau-1.2 --depth=1 https://gitlab.freedesktop.org/vdpau/libvdpau.git
cd libvdpau
./autogen.sh --enable-static
make -j$(nproc)
sudo make install
cd ..
rm -rf libvdpau
- name: FFmpeg cache.
id: cache-ffmpeg
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/ffmpeg-cache
key: ${{ runner.OS }}-ffmpeg-${{ env.CACHE_KEY }}
- name: FFmpeg build.
if: steps.cache-ffmpeg.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
git clone --branch release/3.4 $GIT/FFmpeg/FFmpeg ffmpeg
cd ffmpeg
./configure \
--disable-debug \
--disable-programs \
--disable-doc \
--disable-network \
--disable-autodetect \
--disable-everything \
--disable-alsa \
--disable-iconv \
--enable-libopus \
--enable-vaapi \
--enable-vdpau \
--enable-protocol=file \
--enable-hwaccel=h264_vaapi \
--enable-hwaccel=h264_vdpau \
--enable-hwaccel=mpeg4_vaapi \
--enable-hwaccel=mpeg4_vdpau \
--enable-decoder=aac \
--enable-decoder=aac_fixed \
--enable-decoder=aac_latm \
--enable-decoder=aasc \
--enable-decoder=alac \
--enable-decoder=flac \
--enable-decoder=gif \
--enable-decoder=h264 \
--enable-decoder=h264_vdpau \
--enable-decoder=hevc \
--enable-decoder=mp1 \
--enable-decoder=mp1float \
--enable-decoder=mp2 \
--enable-decoder=mp2float \
--enable-decoder=mp3 \
--enable-decoder=mp3adu \
--enable-decoder=mp3adufloat \
--enable-decoder=mp3float \
--enable-decoder=mp3on4 \
--enable-decoder=mp3on4float \
--enable-decoder=mpeg4 \
--enable-decoder=mpeg4_vdpau \
--enable-decoder=msmpeg4v2 \
--enable-decoder=msmpeg4v3 \
--enable-decoder=opus \
--enable-decoder=pcm_alaw \
--enable-decoder=pcm_f32be \
--enable-decoder=pcm_f32le \
--enable-decoder=pcm_f64be \
--enable-decoder=pcm_f64le \
--enable-decoder=pcm_lxf \
--enable-decoder=pcm_mulaw \
--enable-decoder=pcm_s16be \
--enable-decoder=pcm_s16be_planar \
--enable-decoder=pcm_s16le \
--enable-decoder=pcm_s16le_planar \
--enable-decoder=pcm_s24be \
--enable-decoder=pcm_s24daud \
--enable-decoder=pcm_s24le \
--enable-decoder=pcm_s24le_planar \
--enable-decoder=pcm_s32be \
--enable-decoder=pcm_s32le \
--enable-decoder=pcm_s32le_planar \
--enable-decoder=pcm_s64be \
--enable-decoder=pcm_s64le \
--enable-decoder=pcm_s8 \
--enable-decoder=pcm_s8_planar \
--enable-decoder=pcm_u16be \
--enable-decoder=pcm_u16le \
--enable-decoder=pcm_u24be \
--enable-decoder=pcm_u24le \
--enable-decoder=pcm_u32be \
--enable-decoder=pcm_u32le \
--enable-decoder=pcm_u8 \
--enable-decoder=pcm_zork \
--enable-decoder=vorbis \
--enable-decoder=wavpack \
--enable-decoder=wmalossless \
--enable-decoder=wmapro \
--enable-decoder=wmav1 \
--enable-decoder=wmav2 \
--enable-decoder=wmavoice \
--enable-encoder=libopus \
--enable-parser=aac \
--enable-parser=aac_latm \
--enable-parser=flac \
--enable-parser=h264 \
--enable-parser=hevc \
--enable-parser=mpeg4video \
--enable-parser=mpegaudio \
--enable-parser=opus \
--enable-parser=vorbis \
--enable-demuxer=aac \
--enable-demuxer=flac \
--enable-demuxer=gif \
--enable-demuxer=h264 \
--enable-demuxer=hevc \
--enable-demuxer=m4v \
--enable-demuxer=mov \
--enable-demuxer=mp3 \
--enable-demuxer=ogg \
--enable-demuxer=wav \
--enable-muxer=ogg \
--enable-muxer=opus
make -j$(nproc)
sudo make DESTDIR="$LibrariesPath/ffmpeg-cache" install
cd ..
rm -rf ffmpeg
- name: FFmpeg install.
run: |
cd $LibrariesPath
#List of files from cmake/external/ffmpeg/CMakeLists.txt.
copyLib() {
mkdir -p ffmpeg/$1
yes | cp -i ffmpeg-cache/usr/local/lib/$1.a ffmpeg/$1/$1.a
}
copyLib libavformat
copyLib libavcodec
copyLib libswresample
copyLib libswscale
copyLib libavutil
sudo cp -R ffmpeg-cache/. /
- name: OpenAL Soft.
run: |
cd $LibrariesPath
git clone -b openal-soft-1.20.1 --depth=1 $GIT/kcat/openal-soft.git
cd openal-soft/build
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DLIBTYPE:STRING=STATIC \
-DALSOFT_EXAMPLES=OFF \
-DALSOFT_TESTS=OFF \
-DALSOFT_UTILS=OFF \
-DALSOFT_CONFIG=OFF
make -j$(nproc)
sudo make install
cd -
rm -rf openal-soft
- name: OpenSSL cache.
id: cache-openssl
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/openssl-cache
key: ${{ runner.OS }}-${{ env.OPENSSL_VER }}-${{ env.CACHE_KEY }}
- name: OpenSSL build.
if: steps.cache-openssl.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
opensslDir=openssl_${OPENSSL_VER}
git clone -b OpenSSL_${OPENSSL_VER}-stable --depth=1 \
$GIT/openssl/openssl $opensslDir
cd $opensslDir
./config --prefix="$OPENSSL_PREFIX" no-tests
make -j$(nproc)
sudo make DESTDIR="$LibrariesPath/openssl-cache" install_sw
cd ..
# rm -rf $opensslDir # Keep this folder for WebRTC.
- name: OpenSSL install.
run: |
cd $LibrariesPath
sudo cp -R openssl-cache/. /
- name: Libwayland.
run: |
cd $LibrariesPath
git clone -b 1.18.0 https://gitlab.freedesktop.org/wayland/wayland
cd wayland
./autogen.sh \
--enable-static \
--disable-documentation \
--disable-dtd-validation
make -j$(nproc)
sudo make install
cd ..
rm -rf wayland
- name: Libxkbcommon.
run: |
cd $LibrariesPath
git clone -b xkbcommon-0.8.4 --depth=1 $GIT/xkbcommon/libxkbcommon.git
cd libxkbcommon
./autogen.sh \
--disable-docs \
--disable-wayland \
--with-xkb-config-root=/usr/share/X11/xkb \
--with-x-locale-root=/usr/share/X11/locale
make -j$(nproc)
sudo make install
cd ..
rm -rf libxkbcommon
- name: Qt 5.12.8 cache.
id: cache-qt
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/qt-cache
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qt*_5_12_8/*') }}
- name: Qt 5.12.8 build.
if: steps.cache-qt.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
git clone -b v5.12.8 --depth=1 git://code.qt.io/qt/qt5.git qt_${QT}
cd qt_${QT}
perl init-repository --module-subset=qtbase,qtwayland,qtimageformats,qtsvg
git submodule update qtbase qtwayland qtimageformats qtsvg
cd qtbase
find ../../patches/qtbase_${QT} -type f -print0 | sort -z | xargs -r0 git apply
cd ..
cd qtwayland
find ../../patches/qtwayland_${QT} -type f -print0 | sort -z | xargs -r0 git apply
cd ..
./configure -prefix "$QT_PREFIX" \
-release \
-opensource \
-confirm-license \
-qt-zlib \
-qt-libpng \
-qt-libjpeg \
-qt-harfbuzz \
-qt-pcre \
-qt-xcb \
-no-icu \
-no-gtk \
-static \
-dbus-runtime \
-openssl-linked \
-I "$OPENSSL_PREFIX/include" OPENSSL_LIBS="$OPENSSL_PREFIX/lib/libssl.a $OPENSSL_PREFIX/lib/libcrypto.a -ldl -lpthread" \
-nomake examples \
-nomake tests
make -j$(nproc)
sudo make INSTALL_ROOT="$LibrariesPath/qt-cache" install
cd ..
rm -rf qt_${QT}
- name: Qt 5.12.8 install.
run: |
cd $LibrariesPath
sudo cp -R qt-cache/. /
- name: Breakpad cache.
id: cache-breakpad
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/breakpad-cache
key: ${{ runner.OS }}-breakpad-${{ env.CACHE_KEY }}
- name: Breakpad clone.
run: |
cd $LibrariesPath
git clone https://chromium.googlesource.com/breakpad/breakpad
cd breakpad
git checkout bc8fb886
git clone https://chromium.googlesource.com/linux-syscall-support src/third_party/lss
cd src/third_party/lss
git checkout a91633d1
- name: Breakpad build.
if: steps.cache-breakpad.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
BreakpadCache=$LibrariesPath/breakpad-cache
git clone https://chromium.googlesource.com/external/gyp
cd gyp
git checkout 9f2a7bb1
git apply ../patches/gyp.diff
cd ..
cd breakpad
./configure
make -j$(nproc)
sudo make DESTDIR="$BreakpadCache" install
cd src
rm -r testing
git clone $GIT/google/googletest testing
cd tools
sed -i 's/minidump_upload.m/minidump_upload.cc/' linux/tools_linux.gypi
../../../gyp/gyp --depth=. --generator-output=.. -Goutput_dir=../out tools.gyp --format=cmake
cd ../../out/Default
cmake .
make -j$(nproc) dump_syms
mv dump_syms $BreakpadCache/
cd ..
rm -rf gyp breakpad
- name: Breakpad install.
run: |
cd $LibrariesPath
sudo cp -R breakpad-cache/. /
mkdir -p breakpad/out/Default/
cp breakpad-cache/dump_syms breakpad/out/Default/dump_syms
- name: WebRTC cache.
id: cache-webrtc
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/tg_owt
key: ${{ runner.OS }}-webrtc-${{ env.CACHE_KEY }}
- name: WebRTC.
if: steps.cache-webrtc.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
git clone $GIT/desktop-app/tg_owt.git
mkdir -p tg_owt/out/Debug
cd tg_owt/out/Debug
cmake -G Ninja \
-DCMAKE_BUILD_TYPE=Debug \
-DTG_OWT_SPECIAL_TARGET=linux \
-DTG_OWT_LIBJPEG_INCLUDE_PATH=`pwd`/../../../qt_$QT/qtbase/src/3rdparty/libjpeg \
-DTG_OWT_OPENSSL_INCLUDE_PATH=$OPENSSL_PREFIX/include \
-DTG_OWT_OPUS_INCLUDE_PATH=/usr/local/include/opus \
-DTG_OWT_FFMPEG_INCLUDE_PATH=/usr/local/include \
../..
ninja
# Cleanup.
cd $LibrariesPath/tg_owt
mv out/Debug/libtg_owt.a libtg_owt.a
rm -rf out
mkdir -p out/Debug
mv libtg_owt.a out/Debug/libtg_owt.a
rm -rf $LibrariesPath/openssl_${OPENSSL_VER}
ln -s $LibrariesPath Libraries
- name: Telegram Desktop build.
if: env.ONLY_CACHE == 'false'
run: |
cd $REPO_NAME/Telegram
@@ -556,13 +97,15 @@ jobs:
if [ -n "${{ matrix.defines }}" ]; then
DEFINE="-D ${{ matrix.defines }}=ON"
echo Define from matrix: $DEFINE
echo ::set-env name=ARTIFACT_NAME::Telegram_${{ matrix.defines }}
echo "ARTIFACT_NAME=Telegram_${{ matrix.defines }}" >> $GITHUB_ENV
else
echo ::set-env name=ARTIFACT_NAME::Telegram
echo "ARTIFACT_NAME=Telegram" >> $GITHUB_ENV
fi
./configure.sh \
-D CMAKE_CXX_FLAGS="-s" \
-D CMAKE_C_FLAGS="-Werror" \
-D CMAKE_CXX_FLAGS="-Werror" \
-D CMAKE_EXE_LINKER_FLAGS="-s" \
-D TDESKTOP_API_TEST=ON \
-D DESKTOP_APP_USE_PACKAGED=OFF \
-D DESKTOP_APP_DISABLE_CRASH_REPORTS=OFF \
@@ -572,7 +115,6 @@ jobs:
make -j$(nproc)
- name: Check.
if: env.ONLY_CACHE == 'false'
run: |
filePath="$REPO_NAME/out/Debug/bin/Telegram"
if test -f "$filePath"; then

View File

@@ -57,9 +57,9 @@ jobs:
PREFIX: "/usr/local/macos"
MACOSX_DEPLOYMENT_TARGET: "10.12"
XZ: "xz-5.2.4"
QT: "5_12_8"
QT: "5_15_1"
OPENSSL_VER: "1_1_1"
QT_PREFIX: "/usr/local/desktop-app/Qt-5.12.8"
QT_PREFIX: "/usr/local/desktop-app/Qt-5.15.1"
LIBICONV_VER: "libiconv-1.16"
UPLOAD_ARTIFACT: "false"
ONLY_CACHE: "false"
@@ -69,7 +69,7 @@ jobs:
steps:
- name: Get repository name.
run: echo ::set-env name=REPO_NAME::${GITHUB_REPOSITORY##*/}
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
- name: Clone.
uses: actions/checkout@v2
@@ -94,13 +94,13 @@ jobs:
thisFile=$REPO_NAME/.github/workflows/mac.yml
echo `md5 -q $thisFile` >> CACHE_KEY.txt
fi
echo ::set-env name=CACHE_KEY::`md5 -q CACHE_KEY.txt`
echo "CACHE_KEY=`md5 -q CACHE_KEY.txt`" >> $GITHUB_ENV
echo ::add-path::$PWD/Libraries/depot_tools
echo "$PWD/Libraries/depot_tools" >> $GITHUB_PATH
mkdir -p Libraries/macos
cd Libraries/macos
echo ::set-env name=LibrariesPath::`pwd`
echo "LibrariesPath=`pwd`" >> $GITHUB_ENV
- name: Patches.
run: |
@@ -132,6 +132,20 @@ jobs:
make -j$(nproc)
sudo make install
- name: MozJPEG.
run: |
cd $LibrariesPath
git clone -b v4.0.1-rc2 $GIT/mozilla/mozjpeg.git
cd mozjpeg
cmake -B build . \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local/macos \
-DWITH_JPEG8=ON \
-DPNG_SUPPORTED=OFF
cmake --build build -j$(nproc)
sudo cmake --install build
- name: OpenSSL cache.
id: cache-openssl
uses: actions/cache@v2
@@ -169,17 +183,14 @@ jobs:
with:
path: ${{ env.LibrariesPath }}/opus-cache
key: ${{ runner.OS }}-opus-${{ env.CACHE_KEY }}
- name: Opus clone.
run: |
cd $LibrariesPath
git clone -b v1.3 --depth=1 $GIT/xiph/opus
- name: Opus build.
- name: Opus.
if: steps.cache-opus.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
git clone $GIT/xiph/opus
cd opus
git checkout v1.3
./autogen.sh
CFLAGS="$MIN_MAC $UNGUARDED" CPPFLAGS="$MIN_MAC $UNGUARDED" LDFLAGS="$MIN_MAC" ./configure --prefix=$PREFIX
make -j$(nproc)
@@ -224,7 +235,7 @@ jobs:
git clone $GIT/FFmpeg/FFmpeg.git ffmpeg
cd ffmpeg
git checkout release/3.4
git checkout release/4.2
CFLAGS=`freetype-config --cflags`
LDFLAGS=`freetype-config --libs`
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig:/usr/X11/lib/pkgconfig
@@ -233,7 +244,9 @@ jobs:
--extra-cflags="$MIN_MAC $UNGUARDED" \
--extra-cxxflags="$MIN_MAC $UNGUARDED" \
--extra-ldflags="$MIN_MAC" \
--enable-protocol=file --enable-libopus \
--x86asmexe=`pwd`/macos_yasm_wrap.sh \
--enable-protocol=file \
--enable-libopus \
--disable-programs \
--disable-doc \
--disable-network \
@@ -353,9 +366,9 @@ jobs:
run: |
cd $LibrariesPath
git clone $GIT/kcat/openal-soft.git
git clone https://github.com/telegramdesktop/openal-soft.git
cd openal-soft
git checkout openal-soft-1.19.1
git checkout fix_mono
cd build
CFLAGS="$UNGUARDED" CPPFLAGS="$UNGUARDED" cmake \
@@ -406,20 +419,20 @@ jobs:
build/gyp_crashpad.py -Dmac_deployment_target=10.10
ninja -C out/Debug
- name: Qt 5.12.8 cache.
- name: Qt 5.15.1 cache.
id: cache-qt
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/qt-cache
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_8/*') }}
- name: Use cached Qt 5.12.8.
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_15_1/*') }}
- name: Use cached Qt 5.15.1.
if: steps.cache-qt.outputs.cache-hit == 'true'
run: |
cd $LibrariesPath
mv qt-cache Qt-5.12.8
mv qt-cache Qt-5.15.1
sudo mkdir -p $QT_PREFIX
sudo mv -f Qt-5.12.8 "$(dirname "$QT_PREFIX")"/
- name: Qt 5.12.8 build.
sudo mv -f Qt-5.15.1 "$(dirname "$QT_PREFIX")"/
- name: Qt 5.15.1 build.
if: steps.cache-qt.outputs.cache-hit != 'true'
run: |
cd $LibrariesPath
@@ -427,7 +440,7 @@ jobs:
git clone git://code.qt.io/qt/qt5.git qt_$QT
cd qt_$QT
perl init-repository --module-subset=qtbase,qtimageformats
git checkout v5.12.8
git checkout v5.15.1
git submodule update qtbase
git submodule update qtimageformats
cd qtbase
@@ -446,7 +459,10 @@ jobs:
-securetransport \
-nomake examples \
-nomake tests \
-platform macx-clang
-platform macx-clang \
-I "/usr/local/macos/include" \
LIBJPEG_LIBS="/usr/local/macos/lib/libjpeg.a" \
ZLIB_LIBS="/usr/local/macos/lib/libz.a"
make -j$(nproc)
sudo make install
@@ -470,7 +486,7 @@ jobs:
cd tg_owt/out/Debug
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug \
-DTG_OWT_SPECIAL_TARGET=mac \
-DTG_OWT_LIBJPEG_INCLUDE_PATH=`pwd`/../../../qt_$QT/qtbase/src/3rdparty/libjpeg \
-DTG_OWT_LIBJPEG_INCLUDE_PATH=/usr/local/macos/include \
-DTG_OWT_OPENSSL_INCLUDE_PATH=`pwd`/../../../openssl_$OPENSSL_VER/include \
-DTG_OWT_OPUS_INCLUDE_PATH=$PREFIX/include/opus \
-DTG_OWT_FFMPEG_INCLUDE_PATH=/usr/local/include \
@@ -493,12 +509,14 @@ jobs:
if [ -n "${{ matrix.defines }}" ]; then
DEFINE="-D ${{ matrix.defines }}=ON"
echo Define from matrix: $DEFINE
echo ::set-env name=ARTIFACT_NAME::Telegram_${{ matrix.defines }}
echo "ARTIFACT_NAME=Telegram_${{ matrix.defines }}" >> $GITHUB_ENV
else
echo ::set-env name=ARTIFACT_NAME::Telegram
echo "ARTIFACT_NAME=Telegram" >> $GITHUB_ENV
fi
./configure.sh \
-D CMAKE_C_FLAGS="-Werror" \
-D CMAKE_CXX_FLAGS="-Werror" \
-D TDESKTOP_API_TEST=ON \
-D DESKTOP_APP_USE_PACKAGED=OFF \
-D DESKTOP_APP_DISABLE_CRASH_REPORTS=OFF \

View File

@@ -76,7 +76,7 @@ jobs:
if: env.UPLOAD_ARTIFACT == 'true'
run: |
artifact_name=$(echo telegram-desktop_*.snap)
echo ::set-env name=ARTIFACT_NAME::$artifact_name
echo "ARTIFACT_NAME=$artifact_name" >> $GITHUB_ENV
mkdir artifact
mv $artifact_name artifact

154
.github/workflows/user_agent_updater.yml vendored Normal file
View File

@@ -0,0 +1,154 @@
name: User-agent updater.
on:
repository_dispatch:
types: ["Restart user_agent_updater workflow."]
schedule:
# At 00:00 on day-of-month 1.
- cron: '0 0 1 * *'
pull_request_target:
types: [closed]
jobs:
User-agent:
runs-on: ubuntu-latest
env:
codeFile: "Telegram/SourceFiles/mtproto/details/mtproto_domain_resolver.cpp"
headBranchPrefix: "chrome_"
baseBranch: "dev"
isPull: "0"
steps:
- name: Set env.
if: startsWith(github.event_name, 'pull_request')
run: |
echo "isPull=1" >> $GITHUB_ENV
- name: Clone.
uses: actions/checkout@v2
- name: Set up git.
run: |
token=${{ secrets.TOKEN_FOR_MASTER_UPDATER }}
if [ -z "${token}" ]; then
echo "Token is unset. Nothing to do."
exit 1
fi
url=https://x-access-token:$token@github.com/$GITHUB_REPOSITORY
git config --global user.email "action@github.com"
git config --global user.name "GitHub Action"
git remote set-url origin $url
- name: Delete branch.
if: |
env.isPull == '1'
&& github.event.action == 'closed'
&& startsWith(github.head_ref, env.headBranchPrefix)
run: |
git push origin --delete ${{ github.head_ref }}
- name: Write a new version of Google Chrome to the user-agent for DNS.
if: env.isPull == '0'
shell: python
run: |
import subprocess, os, re;
regExpVersion = "[0-9]+.[0-9]+.[0-9]+.[0-9]+";
chrome = "Chrome/";
def newVersion():
output = subprocess.check_output(["google-chrome", "--version"]);
version = re.search(regExpVersion, output);
if not version:
print("Can't find a Chrome version.");
exit();
return version.group(0);
newChromeVersion = newVersion();
print(newChromeVersion);
def setEnv(value):
open(os.environ['GITHUB_ENV'], "a").write(value);
def writeUserAgent():
p = os.environ['codeFile'];
w = open(p, "r");
content = w.read();
w.close();
regExpChrome = chrome + regExpVersion;
version = re.search(regExpChrome, content);
if not version:
print("Can't find an user-agent in the code.");
exit();
content = re.sub(regExpChrome, chrome + newChromeVersion, content);
w = open(p, "w");
w.write(content);
setEnv("ChromeVersion=" + newChromeVersion);
writeUserAgent();
- name: Push to a new branch.
if: env.isPull == '0' && env.ChromeVersion != ''
run: |
git diff > git_diff.txt
if [[ ! -s git_diff.txt ]]; then
echo "Nothing to commit."
exit 0
fi
git checkout -b $headBranchPrefix$ChromeVersion
git add $codeFile
git commit -m "Update User-Agent for DNS to Chrome $ChromeVersion."
git push origin $headBranchPrefix$ChromeVersion
echo "Done!"
- name: Close previous pull requests.
if: env.isPull == '0' && env.ChromeVersion != ''
uses: actions/github-script@0.4.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const common = {
owner: context.repo.owner,
repo: context.repo.repo,
};
github.pulls.list(common).then(response => {
response.data.forEach((item, _) => {
if (item.head.ref.startsWith(process.env.headBranchPrefix)) {
console.log(`Close ${item.title} #${item.number}.`);
github.pulls.update({
pull_number: item.number,
state: "closed",
...common
});
}
});
});
- name: Create a new pull request.
if: env.isPull == '0' && env.ChromeVersion != ''
uses: actions/github-script@0.4.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const version = process.env.ChromeVersion;
const title = `Update User-Agent for DNS to Chrome ${version}.`;
github.pulls.create({
title: title,
body: "",
head: `${process.env.headBranchPrefix}${version}`,
base: process.env.baseBranch,
owner: context.repo.owner,
repo: context.repo.repo,
});

View File

@@ -59,8 +59,8 @@ jobs:
SDK: "10.0.18362.0"
VC: "call vcvars32.bat && cd Libraries"
GIT: "https://github.com"
QT: "5_12_8"
QT_VER: "5.12.8"
QT: "5_15_1"
QT_VER: "5.15.1"
OPENSSL_VER: "1_1_1"
UPLOAD_ARTIFACT: "false"
ONLY_CACHE: "false"
@@ -68,10 +68,31 @@ jobs:
DOC_PATH: "docs/building-msvc.md"
AUTO_CACHING: "1"
defaults:
run:
shell: cmd
steps:
- name: Get repository name.
shell: bash
run: echo ::set-env name=REPO_NAME::${GITHUB_REPOSITORY##*/}
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
- name: Set up environment paths.
shell: bash
run: |
echo "C:\\Strawberry\\perl\\bin\\" >> $GITHUB_PATH
echo "C:\\Program Files\\NASM\\" >> $GITHUB_PATH
echo "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC\\Auxiliary\\Build\\" >> $GITHUB_PATH
mkdir Libraries && cd Libraries
echo "Convert unix path to win path."
p=`pwd | sed 's#^/[d]#d:#g' |sed 's#/#\\\\#g'`
echo "LibrariesPath=$p" >> $GITHUB_ENV
- name: Save msbuild version.
run: |
call vcvars32.bat
msbuild -version > CACHE_KEY.txt
- name: Clone.
uses: actions/checkout@v2
@@ -79,38 +100,18 @@ jobs:
submodules: recursive
path: ${{ env.REPO_NAME }}
- name: Set up environment variables.
shell: cmd
run: |
echo ::add-path::C:\Strawberry\perl\bin\
echo ::add-path::"%programfiles%\NASM"
C:
cd "%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\"
echo ::add-path::%cd%
call vcvars32.bat
D:
cd %GITHUB_WORKSPACE%
msbuild -version > CACHE_KEY.txt
echo %MANUAL_CACHING% >> CACHE_KEY.txt
mkdir Libraries
cd Libraries
echo ::set-env name=LibrariesPath::%cd%
- name: Generate cache key.
shell: bash
run: |
echo $MANUAL_CACHING >> CACHE_KEY.txt
if [ "$AUTO_CACHING" == "1" ]; then
thisFile=$REPO_NAME/.github/workflows/win.yml
echo `md5sum $thisFile | awk '{ print $1 }'` >> CACHE_KEY.txt
fi
echo ::set-env name=CACHE_KEY::`md5sum CACHE_KEY.txt | awk '{ print $1 }'`
echo "CACHE_KEY=`md5sum CACHE_KEY.txt | awk '{ print $1 }'`" >> $GITHUB_ENV
- name: Choco installs.
run: |
choco install --no-progress -y nasm yasm jom ninja
run: choco install --no-progress -y nasm yasm jom ninja
- name: Patches.
shell: bash
@@ -123,21 +124,18 @@ jobs:
eval $checkoutCommit
- name: Find any version of Python 2.
shell: cmd
shell: bash
run: |
echo Find any version of Python 2.
for /D %%a in (C:\hostedtoolcache\windows\Python\2.*) do (
SET PY2=%%a\x64
)
if [%PY2%] == [] (
echo Python 2 is not found.
echo "Find any version of Python 2."
p=`ls /c/hostedtoolcache/windows/python | grep 2 | tail -1`
if [ -z "$p" ]; then
echo "Python 2 is not found."
exit 1
)
echo Found %PY2%.
echo ::set-env name=PY2::%PY2%
fi
echo "PY2=C:\\hostedtoolcache\\windows\\Python\\$p\\x64" >> $GITHUB_ENV
echo "Found $p."
- name: LZMA.
shell: cmd
run: |
%VC%
@@ -154,7 +152,6 @@ jobs:
key: ${{ runner.OS }}-${{ env.CACHE_KEY }}-${{ env.OPENSSL_VER }}
- name: OpenSSL.
if: steps.cache-openssl.outputs.cache-hit != 'true'
shell: cmd
run: |
%VC%
@@ -180,7 +177,6 @@ jobs:
rmdir /S /Q .git
- name: Zlib.
shell: cmd
run: |
%VC%
@@ -190,6 +186,20 @@ jobs:
cd contrib\vstudio\vc14
msbuild -m zlibstat.vcxproj /property:Configuration=Debug
- name: MozJPEG.
shell: cmd
run: |
%VC%
git clone -b v4.0.1-rc2 %GIT%/mozilla/mozjpeg.git
cd mozjpeg
cmake . ^
-G "Visual Studio 16 2019" ^
-A Win32 ^
-DWITH_JPEG8=ON ^
-DPNG_SUPPORTED=OFF
cmake --build . --config Debug
- name: OpenAL Soft cache.
id: cache-openal
uses: actions/cache@v2
@@ -197,7 +207,6 @@ jobs:
path: ${{ env.LibrariesPath }}/openal-soft
key: ${{ runner.OS }}-openal-soft-${{ env.CACHE_KEY }}
- name: OpenAL Soft.
shell: cmd
if: steps.cache-openal.outputs.cache-hit != 'true'
run: |
%VC%
@@ -225,7 +234,6 @@ jobs:
env:
GYP_MSVS_OVERRIDE_PATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\'
GYP_MSVS_VERSION: 2019
shell: cmd
if: steps.cache-breakpad.outputs.cache-hit != 'true'
run: |
cd %LibrariesPath%
@@ -262,7 +270,6 @@ jobs:
key: ${{ runner.OS }}-opus-${{ env.CACHE_KEY }}
- name: Opus.
if: steps.cache-opus.outputs.cache-hit != 'true'
shell: cmd
run: |
%VC%
@@ -281,29 +288,27 @@ jobs:
key: ${{ runner.OS }}-ffmpeg-${{ env.CACHE_KEY }}-2-${{ hashFiles('**/build_ffmpeg_win.sh') }}
- name: FFmpeg.
if: steps.cache-ffmpeg.outputs.cache-hit != 'true'
shell: cmd
run: |
%VC%
choco install --no-progress -y msys2
git clone %GIT%/FFmpeg/FFmpeg.git ffmpeg
cd ffmpeg
git checkout release/3.4
git checkout release/4.2
set CHERE_INVOKING=enabled_from_arguments
set MSYS2_PATH_TYPE=inherit
call c:\tools\msys64\usr\bin\bash --login ../../%REPO_NAME%/Telegram/Patches/build_ffmpeg_win.sh
call c:\tools\msys64\usr\bin\bash --login ../patches/build_ffmpeg_win.sh
rmdir /S /Q .git
- name: Qt 5.12.8 cache.
- name: Qt 5.15.1 cache.
id: cache-qt
uses: actions/cache@v2
with:
path: ${{ env.LibrariesPath }}/Qt-${{ env.QT_VER }}
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_12_8/*') }}
- name: Configure Qt 5.12.8.
key: ${{ runner.OS }}-qt-${{ env.CACHE_KEY }}-${{ hashFiles('**/qtbase_5_15_1/*') }}
- name: Configure Qt 5.15.1.
if: steps.cache-qt.outputs.cache-hit != 'true'
shell: cmd
run: |
%VC%
@@ -335,10 +340,12 @@ jobs:
-mp ^
-nomake examples ^
-nomake tests ^
-platform win32-msvc
- name: Qt 5.12.8 build.
-platform win32-msvc ^
-I "%LibrariesPath%\mozjpeg" ^
LIBJPEG_LIBS_DEBUG="%LibrariesPath%\mozjpeg\Debug\jpeg-static.lib" ^
LIBJPEG_LIBS_RELEASE="%LibrariesPath%\mozjpeg\Release\jpeg-static.lib"
- name: Qt 5.15.1 build.
if: steps.cache-qt.outputs.cache-hit != 'true'
shell: cmd
run: |
%VC%
cd qt_%QT%
@@ -357,32 +364,16 @@ jobs:
key: ${{ runner.OS }}-webrtc-${{ env.CACHE_KEY }}
- name: WebRTC.
if: steps.cache-webrtc.outputs.cache-hit != 'true'
shell: cmd
run: |
%VC%
:: Qt libjpeg.
mkdir qt_%QT%
cd qt_%QT%
git clone -b %QT_VER% https://github.com/qt/qtbase
move qtbase\src\3rdparty\libjpeg ..
cd ..
dir
rmdir /S /Q qt_%QT%
mkdir qt_%QT%\qtbase\src\3rdparty\
move libjpeg qt_%QT%\qtbase\src\3rdparty\
:: WebRTC.
cd %LibrariesPath%
git clone %GIT%/desktop-app/tg_owt.git
mkdir tg_owt\out\Debug
cd tg_owt\out\Debug
cmake -G Ninja ^
-DCMAKE_BUILD_TYPE=Debug ^
-DTG_OWT_SPECIAL_TARGET=win ^
-DTG_OWT_LIBJPEG_INCLUDE_PATH=%cd%/../../../qt_%QT%/qtbase/src/3rdparty/libjpeg ^
-DTG_OWT_LIBJPEG_INCLUDE_PATH=%cd%/../../../mozjpeg ^
-DTG_OWT_OPENSSL_INCLUDE_PATH=%cd%/../../../openssl_%OPENSSL_VER%/include ^
-DTG_OWT_OPUS_INCLUDE_PATH=%cd%/../../../opus/include ^
-DTG_OWT_FFMPEG_INCLUDE_PATH=%cd%/../../../ffmpeg ^
@@ -397,9 +388,6 @@ jobs:
mkdir out\Debug
move tg_owt.lib out\Debug\tg_owt.lib
cd %LibrariesPath%
rmdir /S /Q qt_%QT%
- name: Read defines.
shell: bash
run: |
@@ -407,15 +395,14 @@ jobs:
if [ -n "${{ matrix.defines }}" ]; then
DEFINE="-D ${{ matrix.defines }}=ON"
echo Define from matrix: $DEFINE
echo ::set-env name=ARTIFACT_NAME::Telegram_${{ matrix.defines }}
echo "ARTIFACT_NAME=Telegram_${{ matrix.defines }}" >> $GITHUB_ENV
else
echo ::set-env name=ARTIFACT_NAME::Telegram
echo "ARTIFACT_NAME=Telegram" >> $GITHUB_ENV
fi
echo "::set-env name=TDESKTOP_BUILD_DEFINE::$DEFINE"
echo "TDESKTOP_BUILD_DEFINE=$DEFINE" >> $GITHUB_ENV
- name: Telegram Desktop build.
if: env.ONLY_CACHE == 'false'
shell: cmd
run: |
cd %REPO_NAME%\Telegram
@@ -432,7 +419,6 @@ jobs:
- name: Move artifact.
if: env.UPLOAD_ARTIFACT == 'true'
shell: cmd
run: |
cd %REPO_NAME%\out\Debug
mkdir artifact

6
.gitmodules vendored
View File

@@ -82,12 +82,6 @@
[submodule "Telegram/ThirdParty/qt5ct"]
path = Telegram/ThirdParty/qt5ct
url = https://github.com/desktop-app/qt5ct.git
[submodule "Telegram/ThirdParty/lxqt-qtplugin"]
path = Telegram/ThirdParty/lxqt-qtplugin
url = https://github.com/lxqt/lxqt-qtplugin.git
[submodule "Telegram/ThirdParty/libqtxdg"]
path = Telegram/ThirdParty/libqtxdg
url = https://github.com/lxqt/libqtxdg.git
[submodule "Telegram/ThirdParty/fcitx5-qt"]
path = Telegram/ThirdParty/fcitx5-qt
url = https://github.com/fcitx/fcitx5-qt.git

View File

@@ -34,7 +34,7 @@ Version **1.8.15** was the last that supports older systems
* Qt 5.12.8, 5.6.2 and 5.3.2 slightly patched ([LGPL](http://doc.qt.io/qt-5/lgpl.html))
* OpenSSL 1.1.1 and 1.0.1 ([OpenSSL License](https://www.openssl.org/source/license.html))
* WebRTC ([New BSD License](https://github.com/desktop-app/tg_owt/blob/master/src/LICENSE))
* WebRTC ([New BSD License](https://github.com/desktop-app/tg_owt/blob/master/LICENSE))
* zlib 1.2.11 ([zlib License](http://www.zlib.net/zlib_license.html))
* LZMA SDK 9.20 ([public domain](http://www.7-zip.org/sdk.html))
* liblzma ([public domain](http://tukaani.org/xz/))
@@ -59,7 +59,7 @@ Version **1.8.15** was the last that supports older systems
## Build instructions
* [Visual Studio 2019][msvc]
* [Xcode 11][xcode]
* [Xcode 12][xcode]
* [CMake on GNU/Linux][cmake]
[//]: # (LINKS)

View File

@@ -21,9 +21,6 @@ add_subdirectory(lib_qr)
add_subdirectory(lib_webrtc)
add_subdirectory(codegen)
include(lib_ui/cmake/generate_styles.cmake)
include(cmake/generate_numbers.cmake)
get_filename_component(src_loc SourceFiles REALPATH)
get_filename_component(res_loc Resources REALPATH)
@@ -37,36 +34,6 @@ include(cmake/td_lang.cmake)
include(cmake/td_scheme.cmake)
include(cmake/td_ui.cmake)
set(style_files
boxes/boxes.style
calls/calls.style
chat_helpers/chat_helpers.style
dialogs/dialogs.style
export/view/export.style
history/history.style
info/info.style
intro/intro.style
media/view/media_view.style
media/player/media_player.style
overview/overview.style
passport/passport.style
profile/profile.style
settings/settings.style
ui/filter_icons.style
window/window.style
)
set(dependent_style_files
${submodules_loc}/lib_ui/ui/colors.palette
${submodules_loc}/lib_ui/ui/basic.style
${submodules_loc}/lib_ui/ui/layers/layers.style
${submodules_loc}/lib_ui/ui/widgets/widgets.style
${src_loc}/ui/td_common.style
)
generate_styles(Telegram ${src_loc} "${style_files}" "${dependent_style_files}")
generate_numbers(Telegram ${res_loc}/numbers.txt)
set_target_properties(Telegram PROPERTIES AUTOMOC ON AUTORCC ON)
target_link_libraries(Telegram
@@ -103,20 +70,14 @@ PRIVATE
if (LINUX)
target_link_libraries(Telegram
PRIVATE
desktop-app::external_materialdecoration
desktop-app::external_nimf_qt5
desktop-app::external_qt5ct_support
desktop-app::external_xcb_screensaver
desktop-app::external_xcb
desktop-app::external_glib
)
if (NOT DESKTOP_APP_DISABLE_DBUS_INTEGRATION)
# conflicts with Qt static link
if (DESKTOP_APP_USE_PACKAGED_LAZY_PLATFORMTHEMES)
target_link_libraries(Telegram
PRIVATE
desktop-app::external_lxqt_qtplugin
)
endif()
target_link_libraries(Telegram
PRIVATE
desktop-app::external_statusnotifieritem
@@ -127,45 +88,24 @@ if (LINUX)
)
endif()
if (DESKTOP_APP_USE_PACKAGED AND Qt5WaylandClient_VERSION VERSION_LESS 5.13.0)
find_package(PkgConfig REQUIRED)
pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
target_include_directories(Telegram
PRIVATE
${WAYLAND_CLIENT_INCLUDE_DIRS}
)
endif()
if (DESKTOP_APP_USE_PACKAGED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(XCB_SCREENSAVER REQUIRED IMPORTED_TARGET xcb-screensaver)
pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb)
if (NOT DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
target_link_libraries(Telegram
PRIVATE
PkgConfig::XCB_SCREENSAVER
PkgConfig::XCB
desktop-app::external_materialdecoration
)
else()
target_link_static_libraries(Telegram PRIVATE xcb-screensaver)
target_link_libraries(Telegram PRIVATE xcb)
if (DESKTOP_APP_USE_PACKAGED
AND Qt5WaylandClient_VERSION VERSION_LESS 5.13.0)
find_package(PkgConfig REQUIRED)
pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
target_include_directories(Telegram
PRIVATE
${WAYLAND_CLIENT_INCLUDE_DIRS}
)
endif()
endif()
find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB2 REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(GOBJECT REQUIRED IMPORTED_TARGET gobject-2.0)
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
target_link_libraries(Telegram
PRIVATE
PkgConfig::GLIB2
PkgConfig::GOBJECT
PkgConfig::GIO
)
target_compile_definitions(Telegram PRIVATE G_LOG_DOMAIN="Telegram")
if (NOT TDESKTOP_DISABLE_GTK_INTEGRATION)
find_package(PkgConfig REQUIRED)
@@ -179,7 +119,7 @@ if (LINUX)
PkgConfig::X11
)
else()
pkg_search_module(GTK REQUIRED gtk+-2.0 gtk+-3.0)
pkg_search_module(GTK REQUIRED gtk+-3.0 gtk+-2.0)
target_include_directories(Telegram PRIVATE ${GTK_INCLUDE_DIRS})
target_link_libraries(Telegram PRIVATE X11)
endif()
@@ -191,6 +131,8 @@ nice_target_sources(Telegram ${src_loc}
PRIVATE
${style_files}
api/api_attached_stickers.cpp
api/api_attached_stickers.h
api/api_authorizations.cpp
api/api_authorizations.h
api/api_bot.cpp
@@ -394,8 +336,6 @@ PRIVATE
core/launcher.h
core/local_url_handlers.cpp
core/local_url_handlers.h
core/mime_type.cpp
core/mime_type.h
core/sandbox.cpp
core/sandbox.h
core/shortcuts.cpp
@@ -541,6 +481,13 @@ PRIVATE
history/admin_log/history_admin_log_section.h
# history/feed/history_feed_section.cpp
# history/feed/history_feed_section.h
history/view/controls/compose_controls_common.h
history/view/controls/history_view_compose_controls.cpp
history/view/controls/history_view_compose_controls.h
history/view/controls/history_view_voice_record_bar.cpp
history/view/controls/history_view_voice_record_bar.h
history/view/controls/history_view_voice_record_button.cpp
history/view/controls/history_view_voice_record_button.h
history/view/media/history_view_call.h
history/view/media/history_view_call.cpp
history/view/media/history_view_contact.h
@@ -573,14 +520,14 @@ PRIVATE
history/view/media/history_view_photo.cpp
history/view/media/history_view_poll.h
history/view/media/history_view_poll.cpp
history/view/media/history_view_slot_machine.h
history/view/media/history_view_slot_machine.cpp
history/view/media/history_view_sticker.h
history/view/media/history_view_sticker.cpp
history/view/media/history_view_theme_document.h
history/view/media/history_view_theme_document.cpp
history/view/media/history_view_web_page.h
history/view/media/history_view_web_page.cpp
history/view/history_view_compose_controls.cpp
history/view/history_view_compose_controls.h
history/view/history_view_contact_status.cpp
history/view/history_view_contact_status.h
history/view/history_view_context_menu.cpp
@@ -594,6 +541,12 @@ PRIVATE
history/view/history_view_message.cpp
history/view/history_view_message.h
history/view/history_view_object.h
history/view/history_view_pinned_bar.cpp
history/view/history_view_pinned_bar.h
history/view/history_view_pinned_section.cpp
history/view/history_view_pinned_section.h
history/view/history_view_pinned_tracker.cpp
history/view/history_view_pinned_tracker.h
history/view/history_view_replies_section.cpp
history/view/history_view_replies_section.h
history/view/history_view_schedule_box.cpp
@@ -701,6 +654,8 @@ PRIVATE
inline_bots/inline_bot_result.h
inline_bots/inline_bot_send_data.cpp
inline_bots/inline_bot_send_data.h
inline_bots/inline_results_inner.cpp
inline_bots/inline_results_inner.h
inline_bots/inline_results_widget.cpp
inline_bots/inline_results_widget.h
intro/intro_code.cpp
@@ -753,14 +708,6 @@ PRIVATE
media/audio/media_child_ffmpeg_loader.h
media/audio/media_openal_functions.cpp
media/audio/media_openal_functions.h
media/clip/media_clip_check_streaming.cpp
media/clip/media_clip_check_streaming.h
media/clip/media_clip_ffmpeg.cpp
media/clip/media_clip_ffmpeg.h
media/clip/media_clip_implementation.cpp
media/clip/media_clip_implementation.h
media/clip/media_clip_reader.cpp
media/clip/media_clip_reader.h
media/player/media_player_button.cpp
media/player/media_player_button.h
media/player/media_player_float.cpp
@@ -863,6 +810,8 @@ PRIVATE
platform/linux/linux_gdk_helper.h
platform/linux/linux_libs.cpp
platform/linux/linux_libs.h
platform/linux/linux_wayland_integration.cpp
platform/linux/linux_wayland_integration.h
platform/linux/linux_xlib_helper.cpp
platform/linux/linux_xlib_helper.h
platform/linux/file_utilities_linux.cpp
@@ -875,6 +824,7 @@ PRIVATE
platform/linux/notifications_manager_linux.h
platform/linux/specific_linux.cpp
platform/linux/specific_linux.h
platform/linux/window_title_linux.cpp
platform/linux/window_title_linux.h
platform/mac/file_utilities_mac.mm
platform/mac/file_utilities_mac.h
@@ -1052,8 +1002,8 @@ PRIVATE
ui/filter_icons.h
ui/filter_icon_panel.cpp
ui/filter_icon_panel.h
ui/grouped_layout.cpp
ui/grouped_layout.h
ui/item_text_options.cpp
ui/item_text_options.h
ui/resize_area.h
ui/search_field_controller.cpp
ui/search_field_controller.h
@@ -1061,8 +1011,6 @@ PRIVATE
ui/special_buttons.h
ui/special_fields.cpp
ui/special_fields.h
ui/text_options.cpp
ui/text_options.h
ui/unread_badge.cpp
ui/unread_badge.h
window/main_window.cpp
@@ -1150,6 +1098,11 @@ if (NOT LINUX)
)
endif()
if (LINUX AND DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
remove_target_sources(Telegram ${src_loc} platform/linux/linux_wayland_integration.cpp)
nice_target_sources(Telegram ${src_loc} PRIVATE platform/linux/linux_wayland_integration_dummy.cpp)
endif()
if (NOT DESKTOP_APP_USE_PACKAGED)
nice_target_sources(Telegram ${src_loc} PRIVATE platform/mac/mac_iconv_helper.c)
endif()
@@ -1290,6 +1243,7 @@ target_compile_definitions(Telegram
PRIVATE
TDESKTOP_API_ID=${TDESKTOP_API_ID}
TDESKTOP_API_HASH=${TDESKTOP_API_HASH}
G_LOG_DOMAIN="Telegram"
)
if (APPLE OR NOT CMAKE_EXECUTABLE_SUFFIX STREQUAL "" OR NOT "${output_name}" STREQUAL "Telegram")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

View File

@@ -161,17 +161,30 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_deleted" = "Deleted Account";
"lng_deleted_message" = "Deleted message";
"lng_pinned_message" = "Pinned message";
"lng_pinned_previous" = "Previous message";
"lng_pinned_poll" = "Pinned poll";
"lng_pinned_quiz" = "Pinned quiz";
"lng_pinned_unpin_sure" = "Would you like to unpin this message?";
"lng_pinned_pin_sure" = "Would you like to pin this message?";
"lng_pinned_pin_sure_group" = "Do you want to pin this message for all members in the group?";
"lng_pinned_pin_old_sure" = "Do you want to pin an older message while leaving a more recent one pinned?";
"lng_pinned_pin" = "Pin";
"lng_pinned_unpin" = "Unpin";
"lng_pinned_notify" = "Notify all members";
"lng_pinned_also_for_other" = "Also pin for {user}";
"lng_pinned_messages_title#one" = "{count} pinned message";
"lng_pinned_messages_title#other" = "{count} pinned messages";
"lng_pinned_hide_all" = "Don't show pinned messages";
"lng_pinned_unpin_all#one" = "Unpin {count} message";
"lng_pinned_unpin_all#other" = "Unpin all {count} messages";
"lng_pinned_unpin_all_sure" = "Do you want to unpin all messages?";
"lng_pinned_hide_all_sure" = "Do you want to hide the pinned messages bar? It will stay hidden until a new message is pinned.";
"lng_pinned_hide_all_hide" = "Hide";
"lng_edit_media_album_error" = "This file cannot be saved as a part of an album.";
"lng_edit_media_invalid_file" = "Sorry, no way to use this file.";
"lng_edit_caption_attach" = "Sorry, you can't attach a new media while you're editing your message.";
"lng_edit_caption_voice" = "Sorry, you can't edit your message while you're having an unsent voice message.";
"lng_intro_about" = "Welcome to the official Telegram Desktop app.\nIt's fast and secure.";
"lng_start_msgs" = "START MESSAGING";
@@ -1103,6 +1116,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_secure_proof_of_address" = "proof of address";
"lng_action_secure_phone" = "phone number";
"lng_action_secure_email" = "email address";
"lng_action_proximity_reached" = "{from} is now within {distance} from {user}";
"lng_action_proximity_reached_you" = "{from} is now within {distance} from you";
"lng_action_you_proximity_reached" = "You are now within {distance} from {user}";
"lng_action_proximity_distance_m#one" = "{count} meter";
"lng_action_proximity_distance_m#other" = "{count} metres";
"lng_action_proximity_distance_km#one" = "{count} km";
"lng_action_proximity_distance_km#other" = "{count} km";
"lng_ttl_photo_received" = "{from} sent you a self-destructing photo. Please view it on your mobile.";
"lng_ttl_photo_sent" = "You sent a self-destructing photo.";
@@ -1322,6 +1342,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_broadcast_silent_ph" = "Silent broadcast...";
"lng_send_anonymous_ph" = "Send anonymously...";
"lng_record_cancel" = "Release outside this field to cancel";
"lng_record_lock_cancel" = "Click outside of circle to cancel";
"lng_record_lock_cancel_sure" = "Are you sure you want to stop recording and discard your voice message?";
"lng_record_lock_discard" = "Discard";
"lng_will_be_notified" = "Members will be notified when you post";
"lng_wont_be_notified" = "Members will not be notified when you post";
"lng_willbe_history" = "Please select a chat to start messaging";
@@ -1523,9 +1546,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_send_files_selected#other" = "{count} files selected";
"lng_send_files#one" = "Send {count} file";
"lng_send_files#other" = "Send {count} files";
"lng_send_album" = "Send as an album";
"lng_send_photo" = "Send as a photo";
"lng_send_file" = "Send as a file";
"lng_send_grouped" = "Group items";
"lng_send_compressed" = "Compress images";
"lng_send_media_invalid_files" = "Sorry, no valid files found.";
"lng_forward_choose" = "Choose recipient...";
@@ -2271,6 +2293,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_language_not_ready_link" = "translations platform";
"lng_launch_exe_warning" = "This file has a {extension} extension.\nAre you sure you want to run it?";
"lng_launch_svg_warning" = "Opening this file can potentially expose your IP address to its sender. Continue?";
"lng_launch_exe_sure" = "Run";
"lng_launch_exe_dont_ask" = "Don't ask me again";

View File

@@ -49,6 +49,13 @@
<file alias="art/sunrise.jpg">../../art/sunrise.jpg</file>
<file alias="art/dice_idle.tgs">../../art/dice_idle.tgs</file>
<file alias="art/dart_idle.tgs">../../art/dart_idle.tgs</file>
<file alias="art/bball_idle.tgs">../../art/bball_idle.tgs</file>
<file alias="art/fball_idle.tgs">../../art/fball_idle.tgs</file>
<file alias="art/slot_0_idle.tgs">../../art/slot_0_idle.tgs</file>
<file alias="art/slot_1_idle.tgs">../../art/slot_1_idle.tgs</file>
<file alias="art/slot_2_idle.tgs">../../art/slot_2_idle.tgs</file>
<file alias="art/slot_back.tgs">../../art/slot_back.tgs</file>
<file alias="art/slot_pull.tgs">../../art/slot_pull.tgs</file>
<file alias="day-blue.tdesktop-theme">../../day-blue.tdesktop-theme</file>
<file alias="night.tdesktop-theme">../../night.tdesktop-theme</file>
<file alias="night-green.tdesktop-theme">../../night-green.tdesktop-theme</file>

View File

@@ -69,7 +69,7 @@ inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = In
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;
inputMediaGeoLive#ce4e82fd flags:# stopped:flags.0?true geo_point:InputGeoPoint period:flags.1?int = InputMedia;
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
@@ -78,7 +78,7 @@ inputChatUploadedPhoto#c642724e flags:# file:flags.0?InputFile video:flags.1?Inp
inputChatPhoto#8953ad37 id:InputPhoto = InputChatPhoto;
inputGeoPointEmpty#e4c123d6 = InputGeoPoint;
inputGeoPoint#f3b7acc9 lat:double long:double = InputGeoPoint;
inputGeoPoint#48222faf flags:# lat:double long:double accuracy_radius:flags.0?int = InputGeoPoint;
inputPhotoEmpty#1cd7bf0d = InputPhoto;
inputPhoto#3bb3b94a id:long access_hash:long file_reference:bytes = InputPhoto;
@@ -141,7 +141,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#d20b9f3c flags:# has_video:flags.0?true photo_small:FileLocation photo_big:FileLocation dc_id:int = ChatPhoto;
messageEmpty#83e5de54 id:int = Message;
message#58ae39c9 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> = Message;
message#58ae39c9 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> = Message;
messageService#286fa604 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
@@ -154,7 +154,7 @@ messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
messageMediaGame#fdb19008 game:Game = MessageMedia;
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
messageMediaGeoLive#7c3c2609 geo:GeoPoint period:int = MessageMedia;
messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia;
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
@@ -181,6 +181,7 @@ messageActionBotAllowed#abe9affe domain:string = MessageAction;
messageActionSecureValuesSentMe#1b287353 values:Vector<SecureValue> credentials:SecureCredentialsEncrypted = MessageAction;
messageActionSecureValuesSent#d95c6154 types:Vector<SecureValueType> = MessageAction;
messageActionContactSignUp#f3f25f76 = MessageAction;
messageActionGeoProximityReached#98e0d697 from_id:Peer to_id:Peer distance:int = MessageAction;
dialog#2c171f72 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
@@ -195,7 +196,7 @@ photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize;
photoSizeProgressive#5aa86a51 type:string location:FileLocation w:int h:int sizes:Vector<int> = PhotoSize;
geoPointEmpty#1117dd5f = GeoPoint;
geoPoint#296f104 long:double lat:double access_hash:long = GeoPoint;
geoPoint#b2a2f663 flags:# long:double lat:double access_hash:long accuracy_radius:flags.0?int = GeoPoint;
auth.sentCode#5e002502 flags:# type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int = auth.SentCode;
@@ -247,8 +248,8 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
messages.dialogsNotModified#f0e3e596 count:int = messages.Dialogs;
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#c8edce1e flags:# inexact:flags.1?true count:int next_rate:flags.0?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.channelMessages#99262e37 flags:# inexact:flags.1?true pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#3a54685e flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.channelMessages#64479808 flags:# inexact:flags.1?true pts:int count:int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesNotModified#74535f21 count:int = messages.Messages;
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
@@ -274,6 +275,7 @@ inputMessagesFilterRoundVideo#b549da53 = MessagesFilter;
inputMessagesFilterMyMentions#c1f8e69a = MessagesFilter;
inputMessagesFilterGeo#e7026d0d = MessagesFilter;
inputMessagesFilterContacts#e062db83 = MessagesFilter;
inputMessagesFilterPinned#1bb00451 = MessagesFilter;
updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
updateMessageID#4e90bfd6 id:int random_id:long = Update;
@@ -313,7 +315,6 @@ updateSavedGifs#9375341e = Update;
updateBotInlineQuery#54826690 flags:# query_id:long user_id:int query:string geo:flags.0?GeoPoint offset:string = Update;
updateBotInlineSend#e48f964 flags:# user_id:int query:string geo:flags.0?GeoPoint id:string msg_id:flags.1?InputBotInlineMessageID = Update;
updateEditChannelMessage#1b3f4df7 message:Message pts:int pts_count:int = Update;
updateChannelPinnedMessage#98592475 channel_id:int id:int = Update;
updateBotCallbackQuery#e73547e1 flags:# query_id:long user_id:int peer:Peer msg_id:int chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
updateInlineBotCallbackQuery#f9d27a5a flags:# query_id:long user_id:int msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
@@ -338,8 +339,6 @@ updateChannelReadMessagesContents#89893b45 channel_id:int messages:Vector<int> =
updateContactsReset#7084a7be = Update;
updateChannelAvailableMessages#70db6837 channel_id:int available_min_id:int = Update;
updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
updateUserPinnedMessage#4c43da18 user_id:int id:int = Update;
updateChatPinnedMessage#e10db349 chat_id:int id:int version:int = Update;
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
updateFolderPeers#19360dc0 folder_peers:Vector<FolderPeer> pts:int pts_count:int = Update;
@@ -361,6 +360,8 @@ updateReadChannelDiscussionInbox#1cc7de54 flags:# channel_id:int top_msg_id:int
updateReadChannelDiscussionOutbox#4638a26c channel_id:int top_msg_id:int read_max_id:int = Update;
updatePeerBlocked#246a4b22 peer_id:Peer blocked:Bool = Update;
updateChannelUserTyping#ff2abe9f flags:# channel_id:int top_msg_id:flags.0?int user_id:int action:SendMessageAction = Update;
updatePinnedMessages#ed85eab5 flags:# pinned:flags.0?true peer:Peer messages:Vector<int> pts:int pts_count:int = Update;
updatePinnedChannelMessages#8588878b flags:# pinned:flags.0?true channel_id:int messages:Vector<int> pts:int pts_count:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@@ -607,6 +608,7 @@ channelParticipantSelf#a3289a6d user_id:int inviter_id:int date:int = ChannelPar
channelParticipantCreator#447dca4b flags:# user_id:int admin_rights:ChatAdminRights rank:flags.0?string = ChannelParticipant;
channelParticipantAdmin#ccbebbaf flags:# can_edit:flags.0?true self:flags.1?true user_id:int inviter_id:flags.1?int promoted_by:int date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant;
channelParticipantBanned#1c0facaf flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant;
channelParticipantLeft#c3c6796b user_id:int = ChannelParticipant;
channelParticipantsRecent#de3f3c79 = ChannelParticipantsFilter;
channelParticipantsAdmins#b4608969 = ChannelParticipantsFilter;
@@ -615,6 +617,7 @@ channelParticipantsBots#b0d1865b = ChannelParticipantsFilter;
channelParticipantsBanned#1427a5e1 q:string = ChannelParticipantsFilter;
channelParticipantsSearch#656ac4b q:string = ChannelParticipantsFilter;
channelParticipantsContacts#bb6ae88d q:string = ChannelParticipantsFilter;
channelParticipantsMentions#e04b5ceb flags:# q:flags.0?string top_msg_id:flags.1?int = ChannelParticipantsFilter;
channels.channelParticipants#f56ee2a8 count:int participants:Vector<ChannelParticipant> users:Vector<User> = channels.ChannelParticipants;
channels.channelParticipantsNotModified#f0173fe9 = channels.ChannelParticipants;
@@ -628,7 +631,7 @@ messages.savedGifs#2e0709a5 hash:int gifs:Vector<Document> = messages.SavedGifs;
inputBotInlineMessageMediaAuto#3380c786 flags:# message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
inputBotInlineMessageText#3dcd7a87 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
inputBotInlineMessageMediaGeo#c1b15d65 flags:# geo_point:InputGeoPoint period:int reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
inputBotInlineMessageMediaGeo#96929a85 flags:# geo_point:InputGeoPoint heading:flags.0?int period:flags.1?int proximity_notification_radius:flags.3?int reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
inputBotInlineMessageMediaVenue#417bbf11 flags:# geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
inputBotInlineMessageMediaContact#a6edbffd flags:# phone_number:string first_name:string last_name:string vcard:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
inputBotInlineMessageGame#4b425864 flags:# reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
@@ -640,7 +643,7 @@ inputBotInlineResultGame#4fa417f2 id:string short_name:string send_message:Input
botInlineMessageMediaAuto#764cf810 flags:# message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
botInlineMessageText#8c7f65e2 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector<MessageEntity> reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
botInlineMessageMediaGeo#b722de65 flags:# geo:GeoPoint period:int reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
botInlineMessageMediaGeo#51846fd flags:# geo:GeoPoint heading:flags.0?int period:flags.1?int proximity_notification_radius:flags.3?int reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
botInlineMessageMediaVenue#8a86659c flags:# geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
botInlineMessageMediaContact#18d1cdc2 flags:# phone_number:string first_name:string last_name:string vcard:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
@@ -1164,8 +1167,6 @@ messageViews#455b853d flags:# views:flags.0?int forwards:flags.1?int replies:fla
messages.messageViews#b6c4f543 views:Vector<MessageViews> chats:Vector<Chat> users:Vector<User> = messages.MessageViews;
stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats;
messages.discussionMessage#f5dd8f9d flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
messageReplyHeader#a6d57763 flags:# reply_to_msg_id:int reply_to_peer_id:flags.0?Peer reply_to_top_id:flags.1?int = MessageReplyHeader;
@@ -1174,6 +1175,8 @@ messageReplies#4128faac flags:# comments:flags.0?true replies:int replies_pts:in
peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked;
stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@@ -1299,7 +1302,7 @@ contacts.blockFromReplies#29a8962c flags:# delete_message:flags.0?true delete_hi
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
messages.search#4e17810b flags:# peer:InputPeer q:string from_id:flags.0?InputUser top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
messages.search#c352eec flags:# peer:InputPeer q:string from_id:flags.0?InputPeer top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int = messages.AffectedHistory;
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
@@ -1393,7 +1396,7 @@ messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
messages.markDialogUnread#c286d98f flags:# unread:flags.0?true peer:InputDialogPeer = Bool;
messages.getDialogUnreadMarks#22e24e22 = Vector<DialogPeer>;
messages.clearAllDrafts#7e58ee9c = Bool;
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true peer:InputPeer id:int = Updates;
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true unpin:flags.1?true pm_oneside:flags.2?true peer:InputPeer id:int = Updates;
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
messages.getPollResults#73bb643b peer:InputPeer msg_id:int = Updates;
messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines;
@@ -1422,6 +1425,7 @@ messages.getOldFeaturedStickers#5fe7025b offset:int limit:int hash:int = message
messages.getReplies#24b581ba peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
messages.getDiscussionMessage#446972fd peer:InputPeer msg_id:int = messages.DiscussionMessage;
messages.readDiscussion#f731a9f4 peer:InputPeer msg_id:int read_max_id:int = Bool;
messages.unpinAllMessages#f025bc8b peer:InputPeer = messages.AffectedHistory;
updates.getState#edd4882a = updates.State;
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
@@ -1543,4 +1547,4 @@ stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
// LAYER 119
// LAYER 120

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,82 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_attached_stickers.h"
#include "apiwrap.h"
#include "boxes/confirm_box.h"
#include "boxes/sticker_set_box.h"
#include "boxes/stickers_box.h"
#include "data/data_document.h"
#include "data/data_photo.h"
#include "lang/lang_keys.h"
#include "window/window_session_controller.h"
namespace Api {
AttachedStickers::AttachedStickers(not_null<ApiWrap*> api)
: _api(&api->instance()) {
}
void AttachedStickers::request(
not_null<Window::SessionController*> controller,
MTPmessages_GetAttachedStickers &&mtpRequest) {
const auto weak = base::make_weak(controller.get());
_api.request(_requestId).cancel();
_requestId = _api.request(
std::move(mtpRequest)
).done([=](const MTPVector<MTPStickerSetCovered> &result) {
_requestId = 0;
const auto strongController = weak.get();
if (!strongController) {
return;
}
if (result.v.isEmpty()) {
Ui::show(Box<InformBox>(tr::lng_stickers_not_found(tr::now)));
return;
} else if (result.v.size() > 1) {
Ui::show(Box<StickersBox>(strongController, result));
return;
}
// Single attached sticker pack.
const auto setData = result.v.front().match([&](const auto &data) {
return data.vset().match([&](const MTPDstickerSet &data) {
return &data;
});
});
const auto setId = (setData->vid().v && setData->vaccess_hash().v)
? MTP_inputStickerSetID(setData->vid(), setData->vaccess_hash())
: MTP_inputStickerSetShortName(setData->vshort_name());
Ui::show(
Box<StickerSetBox>(strongController, setId),
Ui::LayerOption::KeepOther);
}).fail([=](const RPCError &error) {
_requestId = 0;
Ui::show(Box<InformBox>(tr::lng_stickers_not_found(tr::now)));
}).send();
}
void AttachedStickers::requestAttachedStickerSets(
not_null<Window::SessionController*> controller,
not_null<PhotoData*> photo) {
request(
controller,
MTPmessages_GetAttachedStickers(
MTP_inputStickeredMediaPhoto(photo->mtpInput())));
}
void AttachedStickers::requestAttachedStickerSets(
not_null<Window::SessionController*> controller,
not_null<DocumentData*> document) {
request(
controller,
MTPmessages_GetAttachedStickers(
MTP_inputStickeredMediaDocument(document->mtpInput())));
}
} // namespace Api

View File

@@ -0,0 +1,44 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "mtproto/sender.h"
class ApiWrap;
class DocumentData;
class PhotoData;
namespace Window {
class SessionController;
} // namespace Window
namespace Api {
class AttachedStickers final {
public:
explicit AttachedStickers(not_null<ApiWrap*> api);
void requestAttachedStickerSets(
not_null<Window::SessionController*> controller,
not_null<PhotoData*> photo);
void requestAttachedStickerSets(
not_null<Window::SessionController*> controller,
not_null<DocumentData*> document);
private:
void request(
not_null<Window::SessionController*> controller,
MTPmessages_GetAttachedStickers &&mtpRequest);
MTP::Sender _api;
mtpRequestId _requestId = 0;
};
} // namespace Api

View File

@@ -10,6 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "history/history.h"
#include "data/data_peer.h"
#include "data/data_user.h"
#include "base/unixtime.h"
#include "data/data_peer_values.h"
#include "apiwrap.h"
namespace Api {
@@ -17,6 +20,7 @@ namespace {
constexpr auto kCancelTypingActionTimeout = crl::time(5000);
constexpr auto kSetMyActionForMs = 10 * crl::time(1000);
constexpr auto kSendTypingsToOfflineFor = TimeId(30);
} // namespace
@@ -98,6 +102,9 @@ bool SendProgressManager::updated(const Key &key, bool doing) {
}
void SendProgressManager::send(const Key &key, int progress) {
if (skipRequest(key)) {
return;
}
using Type = SendProgressType;
const auto action = [&]() -> MTPsendMessageAction {
const auto p = MTP_int(progress);
@@ -135,6 +142,26 @@ void SendProgressManager::send(const Key &key, int progress) {
}
}
bool SendProgressManager::skipRequest(const Key &key) const {
const auto user = key.history->peer->asUser();
if (!user) {
return false;
} else if (user->isSelf()) {
return true;
} else if (user->isBot() && !user->isSupport()) {
return true;
}
const auto recently = base::unixtime::now() - kSendTypingsToOfflineFor;
const auto online = user->onlineTill;
if (online == -2) { // last seen recently
return false;
} else if (online < 0) {
return (-online < recently);
} else {
return (online < recently);
}
}
void SendProgressManager::done(
const MTPBool &result,
mtpRequestId requestId) {

View File

@@ -90,6 +90,8 @@ private:
void send(const Key &key, int progress);
void done(const MTPBool &result, mtpRequestId requestId);
[[nodiscard]] bool skipRequest(const Key &key) const;
const not_null<Main::Session*> _session;
base::flat_map<Key, mtpRequestId> _requests;
base::flat_map<Key, crl::time> _updated;

View File

@@ -21,8 +21,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h"
#include "history/history_message.h" // NewMessageFlags.
#include "chat_helpers/message_field.h" // ConvertTextTagsToEntities.
#include "chat_helpers/stickers_dice_pack.h" // DicePacks::kDiceString.
#include "ui/text/text_entity.h" // TextWithEntities.
#include "ui/text_options.h" // Ui::ItemTextOptions.
#include "ui/item_text_options.h" // Ui::ItemTextOptions.
#include "main/main_session.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
@@ -85,8 +86,7 @@ void SendExistingMedia(
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
}
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = message.action.options.silent
|| (peer->isBroadcast() && session->data().notifySilentPosts(peer));
const auto silentPost = ShouldSendSilent(peer, message.action.options);
InnerFillMessagePostFlags(message.action.options, peer, flags);
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
@@ -221,8 +221,12 @@ bool SendDice(Api::MessageToSend &message) {
auto &account = message.action.history->session().account();
auto &config = account.appConfig();
static const auto hardcoded = std::vector<QString>{
QString::fromUtf8("\xF0\x9F\x8E\xB2"),
QString::fromUtf8("\xF0\x9F\x8E\xAF")
Stickers::DicePacks::kDiceString,
Stickers::DicePacks::kDartString,
Stickers::DicePacks::kSlotString,
Stickers::DicePacks::kFballString,
Stickers::DicePacks::kFballString + QChar(0xFE0F),
Stickers::DicePacks::kBballString,
};
const auto list = config.get<std::vector<QString>>(
"emojies_send_dice",
@@ -256,8 +260,7 @@ bool SendDice(Api::MessageToSend &message) {
}
const auto replyHeader = NewMessageReplyHeader(message.action);
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = message.action.options.silent
|| (peer->isBroadcast() && session->data().notifySilentPosts(peer));
const auto silentPost = ShouldSendSilent(peer, message.action.options);
InnerFillMessagePostFlags(message.action.options, peer, flags);
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
@@ -398,7 +401,7 @@ void SendConfirmedFile(
}
const auto replyHeader = NewMessageReplyHeader(action);
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = file->to.options.silent;
const auto silentPost = ShouldSendSilent(peer, file->to.options);
Api::FillMessagePostFlags(action, peer, flags);
if (silentPost) {
flags |= MTPDmessage::Flag::f_silent;

View File

@@ -63,6 +63,22 @@ enum class DataIsLoadedResult {
Ok = 3,
};
void ProcessScheduledMessageWithElapsedTime(
not_null<Main::Session*> session,
bool needToAdd,
const MTPDmessage &data) {
if (needToAdd && !data.is_from_scheduled()) {
// If we still need to add a new message,
// we should first check if this message is in
// the list of scheduled messages.
// This is necessary to correctly update the file reference.
// Note that when a message is scheduled until online
// while the recipient is already online, the server sends
// an ordinary new message with skipped "from_scheduled" flag.
session->data().scheduledMessages().checkEntitiesAndUpdate(data);
}
}
bool IsForceLogoutNotification(const MTPDupdateServiceNotification &data) {
return qs(data.vtype()).startsWith(qstr("AUTH_KEY_DROP_"));
}
@@ -775,6 +791,10 @@ void Updates::mtpUpdateReceived(const MTPUpdates &updates) {
}
}
int32 Updates::pts() const {
return _ptsWaiter.current();
}
void Updates::updateOnline() {
updateOnline(false);
}
@@ -958,17 +978,7 @@ void Updates::applyUpdateNoPtsCheck(const MTPUpdate &update) {
LOG(("Skipping message, because it is already in blocks!"));
needToAdd = false;
}
if (needToAdd && !data.is_from_scheduled()) {
// If we still need to add a new message,
// we should first check if this message is in
// the list of scheduled messages.
// This is necessary to correctly update the file reference.
// Note that when a message is scheduled until online
// while the recipient is already online, the server sends
// an ordinary new message with skipped "from_scheduled" flag.
_session->data().scheduledMessages().checkEntitiesAndUpdate(
data);
}
ProcessScheduledMessageWithElapsedTime(_session, needToAdd, data);
}
if (needToAdd) {
_session->data().addNewMessage(
@@ -1057,10 +1067,12 @@ void Updates::applyUpdateNoPtsCheck(const MTPUpdate &update) {
auto &d = update.c_updateNewChannelMessage();
auto needToAdd = true;
if (d.vmessage().type() == mtpc_message) { // index forwarded messages to links _overview
if (_session->data().checkEntitiesAndViewsUpdate(d.vmessage().c_message())) { // already in blocks
const auto &data = d.vmessage().c_message();
if (_session->data().checkEntitiesAndViewsUpdate(data)) { // already in blocks
LOG(("Skipping message, because it is already in blocks!"));
needToAdd = false;
}
ProcessScheduledMessageWithElapsedTime(_session, needToAdd, data);
}
if (needToAdd) {
_session->data().addNewMessage(
@@ -1075,6 +1087,17 @@ void Updates::applyUpdateNoPtsCheck(const MTPUpdate &update) {
_session->data().updateEditedMessage(d.vmessage());
} break;
case mtpc_updatePinnedChannelMessages: {
const auto &d = update.c_updatePinnedChannelMessages();
const auto channelId = d.vchannel_id().v;
for (const auto &msgId : d.vmessages().v) {
const auto item = session().data().message(channelId, msgId.v);
if (item) {
item->setIsPinned(d.is_pinned());
}
}
} break;
case mtpc_updateEditMessage: {
auto &d = update.c_updateEditMessage();
_session->data().updateEditedMessage(d.vmessage());
@@ -1090,6 +1113,17 @@ void Updates::applyUpdateNoPtsCheck(const MTPUpdate &update) {
_session->data().processMessagesDeleted(d.vchannel_id().v, d.vmessages().v);
} break;
case mtpc_updatePinnedMessages: {
const auto &d = update.c_updatePinnedMessages();
const auto peerId = peerFromMTP(d.vpeer());
for (const auto &msgId : d.vmessages().v) {
const auto item = session().data().message(0, msgId.v);
if (item) {
item->setIsPinned(d.is_pinned());
}
}
} break;
default: Unexpected("Type in applyUpdateNoPtsCheck()");
}
}
@@ -1385,6 +1419,21 @@ void Updates::feedUpdate(const MTPUpdate &update) {
}
} break;
case mtpc_updatePinnedChannelMessages: {
auto &d = update.c_updatePinnedChannelMessages();
auto channel = session().data().channelLoaded(d.vchannel_id().v);
if (channel && !_handlingChannelDifference) {
if (channel->ptsRequesting()) { // skip global updates while getting channel difference
return;
} else {
channel->ptsUpdateAndApply(d.vpts().v, d.vpts_count().v, update);
}
} else {
applyUpdateNoPtsCheck(update);
}
} break;
// Messages being read.
case mtpc_updateReadHistoryInbox: {
auto &d = update.c_updateReadHistoryInbox();
@@ -1991,28 +2040,9 @@ void Updates::feedUpdate(const MTPUpdate &update) {
} break;
// Pinned message.
case mtpc_updateUserPinnedMessage: {
const auto &d = update.c_updateUserPinnedMessage();
if (const auto user = session().data().userLoaded(d.vuser_id().v)) {
user->setPinnedMessageId(d.vid().v);
}
} break;
case mtpc_updateChatPinnedMessage: {
const auto &d = update.c_updateChatPinnedMessage();
if (const auto chat = session().data().chatLoaded(d.vchat_id().v)) {
const auto status = chat->applyUpdateVersion(d.vversion().v);
if (status == ChatData::UpdateStatus::Good) {
chat->setPinnedMessageId(d.vid().v);
}
}
} break;
case mtpc_updateChannelPinnedMessage: {
const auto &d = update.c_updateChannelPinnedMessage();
if (const auto channel = session().data().channelLoaded(d.vchannel_id().v)) {
channel->setPinnedMessageId(d.vid().v);
}
case mtpc_updatePinnedMessages: {
const auto &d = update.c_updatePinnedMessages();
updateAndApply(d.vpts().v, d.vpts_count().v, update);
} break;
////// Cloud sticker sets

View File

@@ -33,6 +33,8 @@ public:
void applyUpdatesNoPtsCheck(const MTPUpdates &updates);
void applyUpdateNoPtsCheck(const MTPUpdate &update);
[[nodiscard]] int32 pts() const;
void updateOnline();
[[nodiscard]] bool isIdle() const;
void checkIdleFinish();

View File

@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "api/api_authorizations.h"
#include "api/api_attached_stickers.h"
#include "api/api_hash.h"
#include "api/api_media.h"
#include "api/api_sending.h"
@@ -41,6 +42,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/application.h"
#include "base/openssl_help.h"
#include "base/unixtime.h"
#include "base/qt_adapters.h"
#include "base/call_delayed.h"
#include "lang/lang_keys.h"
#include "mainwindow.h"
@@ -63,8 +65,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/themes/window_theme.h"
#include "inline_bots/inline_bot_result.h"
#include "chat_helpers/message_field.h"
#include "ui/text_options.h"
#include "ui/item_text_options.h"
#include "ui/emoji_config.h"
#include "ui/chat/attach/attach_prepare.h"
#include "support/support_helper.h"
#include "storage/localimageloader.h"
#include "storage/download_manager_mtproto.h"
@@ -188,6 +191,7 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
, _topPromotionTimer([=] { refreshTopPromotion(); })
, _updateNotifySettingsTimer([=] { sendNotifySettingsUpdates(); })
, _authorizations(std::make_unique<Api::Authorizations>(this))
, _attachedStickers(std::make_unique<Api::AttachedStickers>(this))
, _selfDestruct(std::make_unique<Api::SelfDestruct>(this))
, _sensitiveContent(std::make_unique<Api::SensitiveContent>(this))
, _globalPrivacy(std::make_unique<Api::GlobalPrivacy>(this)) {
@@ -1690,6 +1694,9 @@ void ApiWrap::requestSelfParticipant(not_null<ChannelData*> channel) {
}, [&](const MTPDchannelParticipant &data) {
LOG(("API Error: Got self regular participant."));
finalize(-1, 0);
}, [&](const MTPDchannelParticipantLeft &data) {
LOG(("API Error: Got self left participant."));
finalize(-1, 0);
});
});
}).fail([=](const RPCError &error) {
@@ -2434,16 +2441,14 @@ void ApiWrap::saveCurrentDraftToCloud() {
Core::App().saveCurrentDraftsToHistories();
for (const auto controller : _session->windows()) {
if (const auto peer = controller->activeChatCurrent().peer()) {
if (const auto history = _session->data().historyLoaded(peer)) {
_session->local().writeDrafts(history);
if (const auto history = controller->activeChatCurrent().history()) {
_session->local().writeDrafts(history);
const auto localDraft = history->localDraft();
const auto cloudDraft = history->cloudDraft();
if (!Data::draftsAreEqual(localDraft, cloudDraft)
&& !_session->supportMode()) {
saveDraftToCloudDelayed(history);
}
const auto localDraft = history->localDraft();
const auto cloudDraft = history->cloudDraft();
if (!Data::draftsAreEqual(localDraft, cloudDraft)
&& !_session->supportMode()) {
saveDraftToCloudDelayed(history);
}
}
}
@@ -3271,7 +3276,7 @@ void ApiWrap::requestMessageAfterDate(
// So we request a message with offset_date = desired_date - 1 and add_offset = -1.
// This should give us the first message with date >= desired_date.
auto offsetId = 0;
auto offsetDate = static_cast<int>(QDateTime(date).toTime_t()) - 1;
auto offsetDate = static_cast<int>(base::QDateToDateTime(date).toTime_t()) - 1;
auto addOffset = -1;
auto limit = 1;
auto maxId = 0;
@@ -3359,7 +3364,7 @@ void ApiWrap::jumpToHistoryDate(not_null<PeerData*> peer, const QDate &date) {
// const QDate &date,
// Callback &&callback) {
// const auto offsetId = 0;
// const auto offsetDate = static_cast<TimeId>(QDateTime(date).toTime_t());
// const auto offsetDate = static_cast<TimeId>(base::QDateToDateTime(date).toTime_t());
// const auto addOffset = -2;
// const auto limit = 1;
// const auto hash = 0;
@@ -3564,6 +3569,9 @@ void ApiWrap::sharedMediaDone(
parsed.noSkipRange,
parsed.fullCount
));
if (type == SharedMediaType::Pinned && !parsed.messageIds.empty()) {
peer->setHasPinnedMessages(true);
}
}
void ApiWrap::requestUserPhotos(
@@ -3947,8 +3955,7 @@ void ApiWrap::forwardMessages(
histories.readInbox(history);
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = action.options.silent
|| (peer->isBroadcast() && _session->data().notifySilentPosts(peer));
const auto silentPost = ShouldSendSilent(peer, action.options);
auto flags = MTPDmessage::Flags(0);
auto clientFlags = MTPDmessage_ClientFlags();
@@ -4147,11 +4154,7 @@ void ApiWrap::sendSharedContact(
MTP_string(firstName),
MTP_string(lastName),
MTP_string(vcard));
auto options = action.options;
if (_session->data().notifySilentPosts(peer)) {
options.silent = true;
}
sendMedia(item, media, options);
sendMedia(item, media, action.options);
_session->data().sendHistoryChangeNotifications();
_session->changes().historyUpdated(
@@ -4178,7 +4181,7 @@ void ApiWrap::sendVoiceMessage(
}
void ApiWrap::editMedia(
Storage::PreparedList &&list,
Ui::PreparedList &&list,
SendMediaType type,
TextWithTags &&caption,
const SendAction &action,
@@ -4200,21 +4203,18 @@ void ApiWrap::editMedia(
}
void ApiWrap::sendFiles(
Storage::PreparedList &&list,
Ui::PreparedList &&list,
SendMediaType type,
TextWithTags &&caption,
std::shared_ptr<SendingAlbum> album,
const SendAction &action) {
const auto haveCaption = !caption.text.isEmpty();
const auto isAlbum = (album != nullptr);
const auto compressImages = (type == SendMediaType::Photo);
if (haveCaption && !list.canAddCaption(isAlbum, compressImages)) {
if (haveCaption && !list.canAddCaption(album != nullptr)) {
auto message = MessageToSend(action.history);
message.textWithTags = std::move(caption);
message.textWithTags = base::take(caption);
message.action = action;
message.action.clearDraft = false;
sendMessage(std::move(message));
caption = TextWithTags();
}
const auto to = fileLoadTaskOptions(action);
@@ -4224,23 +4224,18 @@ void ApiWrap::sendFiles(
auto tasks = std::vector<std::unique_ptr<Task>>();
tasks.reserve(list.files.size());
for (auto &file : list.files) {
if (album) {
switch (file.type) {
case Storage::PreparedFile::AlbumType::Photo:
type = SendMediaType::Photo;
break;
case Storage::PreparedFile::AlbumType::Video:
type = SendMediaType::File;
break;
default: Unexpected("AlbumType in uploadFilesAfterConfirmation");
}
}
const auto uploadWithType = !album
? type
: (file.type == Ui::PreparedFile::Type::Photo
&& type != SendMediaType::File)
? SendMediaType::Photo
: SendMediaType::File;
tasks.push_back(std::make_unique<FileLoadTask>(
&session(),
file.path,
file.content,
std::move(file.information),
type,
uploadWithType,
to,
caption,
album));
@@ -4374,8 +4369,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
flags |= MTPDmessage::Flag::f_media;
}
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = action.options.silent
|| (peer->isBroadcast() && _session->data().notifySilentPosts(peer));
const auto silentPost = ShouldSendSilent(peer, action.options);
FillMessagePostFlags(action, peer, flags);
if (silentPost) {
sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
@@ -4516,8 +4510,7 @@ void ApiWrap::sendInlineResult(
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_reply_to_msg_id;
}
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = action.options.silent
|| (peer->isBroadcast() && _session->data().notifySilentPosts(peer));
const auto silentPost = ShouldSendSilent(peer, action.options);
FillMessagePostFlags(action, peer, flags);
if (silentPost) {
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_silent;
@@ -4683,7 +4676,7 @@ void ApiWrap::sendMediaWithRandomId(
| (replyTo
? MTPmessages_SendMedia::Flag::f_reply_to_msg_id
: MTPmessages_SendMedia::Flag(0))
| (options.silent
| (ShouldSendSilent(history->peer, options)
? MTPmessages_SendMedia::Flag::f_silent
: MTPmessages_SendMedia::Flag(0))
| (!sentEntities.v.isEmpty()
@@ -4790,7 +4783,7 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
| (replyTo
? MTPmessages_SendMultiMedia::Flag::f_reply_to_msg_id
: MTPmessages_SendMultiMedia::Flag(0))
| (album->options.silent
| (ShouldSendSilent(history->peer, album->options)
? MTPmessages_SendMultiMedia::Flag::f_silent
: MTPmessages_SendMultiMedia::Flag(0))
| (album->options.scheduled
@@ -4828,10 +4821,6 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
FileLoadTo ApiWrap::fileLoadTaskOptions(const SendAction &action) const {
const auto peer = action.history->peer;
auto options = action.options;
if (_session->data().notifySilentPosts(peer)) {
options.silent = true;
}
return FileLoadTo(peer->id, action.options, action.replyTo);
}
@@ -5227,6 +5216,10 @@ Api::Authorizations &ApiWrap::authorizations() {
return *_authorizations;
}
Api::AttachedStickers &ApiWrap::attachedStickers() {
return *_attachedStickers;
}
Api::SelfDestruct &ApiWrap::selfDestruct() {
return *_selfDestruct;
}
@@ -5257,8 +5250,7 @@ void ApiWrap::createPoll(
history->clearLocalDraft();
history->clearCloudDraft();
}
const auto silentPost = action.options.silent
|| (peer->isBroadcast() && _session->data().notifySilentPosts(peer));
const auto silentPost = ShouldSendSilent(peer, action.options);
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
@@ -5281,6 +5273,11 @@ void ApiWrap::createPoll(
MTP_int(action.options.scheduled)
)).done([=](const MTPUpdates &result) mutable {
applyUpdates(result);
_session->changes().historyUpdated(
history,
(action.options.scheduled
? Data::HistoryUpdate::Flag::ScheduledSent
: Data::HistoryUpdate::Flag::MessageSent));
done();
finish();
}).fail([=](const RPCError &error) mutable {

View File

@@ -36,7 +36,6 @@ class Result;
namespace Storage {
enum class SharedMediaType : signed char;
struct PreparedList;
class DownloadMtprotoTask;
class Account;
} // namespace Storage
@@ -49,10 +48,15 @@ namespace Core {
struct CloudPasswordState;
} // namespace Core
namespace Ui {
struct PreparedList;
} // namespace Ui
namespace Api {
class Updates;
class Authorizations;
class AttachedStickers;
class SelfDestruct;
class SensitiveContent;
class GlobalPrivacy;
@@ -392,7 +396,7 @@ public:
int duration,
const SendAction &action);
void sendFiles(
Storage::PreparedList &&list,
Ui::PreparedList &&list,
SendMediaType type,
TextWithTags &&caption,
std::shared_ptr<SendingAlbum> album,
@@ -403,7 +407,7 @@ public:
const SendAction &action);
void editMedia(
Storage::PreparedList &&list,
Ui::PreparedList &&list,
SendMediaType type,
TextWithTags &&caption,
const SendAction &action,
@@ -455,6 +459,7 @@ public:
rpl::producer<BlockedPeersSlice> blockedPeersSlice();
[[nodiscard]] Api::Authorizations &authorizations();
[[nodiscard]] Api::AttachedStickers &attachedStickers();
[[nodiscard]] Api::SelfDestruct &selfDestruct();
[[nodiscard]] Api::SensitiveContent &sensitiveContent();
[[nodiscard]] Api::GlobalPrivacy &globalPrivacy();
@@ -818,6 +823,7 @@ private:
rpl::event_stream<BlockedPeersSlice> _blockedPeersChanges;
const std::unique_ptr<Api::Authorizations> _authorizations;
const std::unique_ptr<Api::AttachedStickers> _attachedStickers;
const std::unique_ptr<Api::SelfDestruct> _selfDestruct;
const std::unique_ptr<Api::SensitiveContent> _sensitiveContent;
const std::unique_ptr<Api::GlobalPrivacy> _globalPrivacy;

View File

@@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_service_message.h"
#include "media/audio/media_audio.h"
#include "ui/image/image.h"
#include "ui/cached_round_corners.h"
#include "inline_bots/inline_bot_layout_item.h"
#include "core/crash_reports.h"
#include "core/update_checker.h"
@@ -44,7 +45,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_overview.h"
#include "styles/style_media_view.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_history.h"
#include "styles/style_chat.h"
#include "styles/style_layers.h"
#include <QtCore/QBuffer>
@@ -66,14 +67,6 @@ HistoryView::Element *hoveredItem = nullptr,
*pressedLinkItem = nullptr,
*mousedItem = nullptr;
struct CornersPixmaps {
QPixmap p[4];
};
QVector<CornersPixmaps> corners;
using CornersMap = QMap<uint32, CornersPixmaps>;
CornersMap cornersMap;
QImage cornersMaskLarge[4], cornersMaskSmall[4];
} // namespace
namespace App {
@@ -104,114 +97,12 @@ namespace App {
return result;
}
void prepareCorners(RoundCorners index, int32 radius, const QBrush &brush, const style::color *shadow = nullptr, QImage *cors = nullptr) {
Expects(::corners.size() > index);
int32 r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor();
QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4];
{
Painter p(&rect);
PainterHighQualityEnabler hq(p);
p.setCompositionMode(QPainter::CompositionMode_Source);
p.fillRect(QRect(0, 0, rect.width(), rect.height()), Qt::transparent);
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
p.setPen(Qt::NoPen);
if (shadow) {
p.setBrush((*shadow)->b);
p.drawRoundedRect(0, s, r * 3, r * 3, r, r);
}
p.setBrush(brush);
p.drawRoundedRect(0, 0, r * 3, r * 3, r, r);
}
if (!cors) cors = localCors;
cors[0] = rect.copy(0, 0, r, r);
cors[1] = rect.copy(r * 2, 0, r, r);
cors[2] = rect.copy(0, r * 2, r, r + (shadow ? s : 0));
cors[3] = rect.copy(r * 2, r * 2, r, r + (shadow ? s : 0));
if (index != SmallMaskCorners && index != LargeMaskCorners) {
for (int i = 0; i < 4; ++i) {
::corners[index].p[i] = pixmapFromImageInPlace(std::move(cors[i]));
::corners[index].p[i].setDevicePixelRatio(cRetinaFactor());
}
}
}
void createMaskCorners() {
QImage mask[4];
prepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask);
for (int i = 0; i < 4; ++i) {
::cornersMaskSmall[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied);
::cornersMaskSmall[i].setDevicePixelRatio(cRetinaFactor());
}
prepareCorners(LargeMaskCorners, st::historyMessageRadius, QColor(255, 255, 255), nullptr, mask);
for (int i = 0; i < 4; ++i) {
::cornersMaskLarge[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied);
::cornersMaskLarge[i].setDevicePixelRatio(cRetinaFactor());
}
}
void createPaletteCorners() {
prepareCorners(MenuCorners, st::buttonRadius, st::menuBg);
prepareCorners(BoxCorners, st::boxRadius, st::boxBg);
prepareCorners(BotKbOverCorners, st::dateRadius, st::msgBotKbOverBgAdd);
prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg);
prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected);
prepareCorners(SelectedOverlaySmallCorners, st::buttonRadius, st::msgSelectOverlay);
prepareCorners(SelectedOverlayLargeCorners, st::historyMessageRadius, st::msgSelectOverlay);
prepareCorners(DateCorners, st::dateRadius, st::msgDateImgBg);
prepareCorners(DateSelectedCorners, st::dateRadius, st::msgDateImgBgSelected);
prepareCorners(OverviewVideoCorners, st::overviewVideoStatusRadius, st::msgDateImgBg);
prepareCorners(OverviewVideoSelectedCorners, st::overviewVideoStatusRadius, st::msgDateImgBgSelected);
prepareCorners(InShadowCorners, st::historyMessageRadius, st::msgInShadow);
prepareCorners(InSelectedShadowCorners, st::historyMessageRadius, st::msgInShadowSelected);
prepareCorners(ForwardCorners, st::historyMessageRadius, st::historyForwardChooseBg);
prepareCorners(MediaviewSaveCorners, st::mediaviewControllerRadius, st::mediaviewSaveMsgBg);
prepareCorners(EmojiHoverCorners, st::buttonRadius, st::emojiPanHover);
prepareCorners(StickerHoverCorners, st::buttonRadius, st::emojiPanHover);
prepareCorners(BotKeyboardCorners, st::buttonRadius, st::botKbBg);
prepareCorners(PhotoSelectOverlayCorners, st::buttonRadius, st::overviewPhotoSelectOverlay);
prepareCorners(Doc1Corners, st::buttonRadius, st::msgFile1Bg);
prepareCorners(Doc2Corners, st::buttonRadius, st::msgFile2Bg);
prepareCorners(Doc3Corners, st::buttonRadius, st::msgFile3Bg);
prepareCorners(Doc4Corners, st::buttonRadius, st::msgFile4Bg);
prepareCorners(MessageInCorners, st::historyMessageRadius, st::msgInBg, &st::msgInShadow);
prepareCorners(MessageInSelectedCorners, st::historyMessageRadius, st::msgInBgSelected, &st::msgInShadowSelected);
prepareCorners(MessageOutCorners, st::historyMessageRadius, st::msgOutBg, &st::msgOutShadow);
prepareCorners(MessageOutSelectedCorners, st::historyMessageRadius, st::msgOutBgSelected, &st::msgOutShadowSelected);
prepareCorners(SendFilesBoxAlbumGroupCorners, st::sendBoxAlbumGroupRadius, st::callFingerprintBg);
}
void createCorners() {
::corners.resize(RoundCornersCount);
createMaskCorners();
createPaletteCorners();
}
void clearCorners() {
::corners.clear();
::cornersMap.clear();
}
void initMedia() {
createCorners();
Ui::StartCachedCorners();
using Update = Window::Theme::BackgroundUpdate;
static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) {
if (update.paletteChanged()) {
createPaletteCorners();
if (const auto m = App::main()) { // multi good
m->updateScrollColors();
}
HistoryView::serviceColorsUpdated();
} else if (update.type == Update::Type::New) {
prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg);
prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected);
if (const auto m = App::main()) { // multi good
m->updateScrollColors();
}
@@ -221,8 +112,7 @@ namespace App {
}
void deinitMedia() {
clearCorners();
Ui::FinishCachedCorners();
Data::clearGlobalStructures();
}
@@ -396,132 +286,4 @@ namespace App {
return QPixmap::fromImage(std::move(image), Qt::ColorOnly);
}
void rectWithCorners(Painter &p, QRect rect, const style::color &bg, RoundCorners index, RectParts corners) {
auto parts = RectPart::Top
| RectPart::NoTopBottom
| RectPart::Bottom
| corners;
roundRect(p, rect, bg, index, nullptr, parts);
if ((corners & RectPart::AllCorners) != RectPart::AllCorners) {
const auto size = ::corners[index].p[0].width() / cIntRetinaFactor();
if (!(corners & RectPart::TopLeft)) {
p.fillRect(rect.x(), rect.y(), size, size, bg);
}
if (!(corners & RectPart::TopRight)) {
p.fillRect(rect.x() + rect.width() - size, rect.y(), size, size, bg);
}
if (!(corners & RectPart::BottomLeft)) {
p.fillRect(rect.x(), rect.y() + rect.height() - size, size, size, bg);
}
if (!(corners & RectPart::BottomRight)) {
p.fillRect(rect.x() + rect.width() - size, rect.y() + rect.height() - size, size, size, bg);
}
}
}
void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners) {
if (radius == ImageRoundRadius::Ellipse) {
PainterHighQualityEnabler hq(p);
p.setPen(Qt::NoPen);
p.setBrush(p.textPalette().selectOverlay);
p.drawEllipse(rect);
} else {
auto overlayCorners = (radius == ImageRoundRadius::Small)
? SelectedOverlaySmallCorners
: SelectedOverlayLargeCorners;
const auto bg = p.textPalette().selectOverlay;
rectWithCorners(p, rect, bg, overlayCorners, corners);
}
}
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners) {
rectWithCorners(p, rect, st::msgInBg, MessageInCorners, corners);
}
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) {
auto cornerWidth = corner.p[0].width() / cIntRetinaFactor();
auto cornerHeight = corner.p[0].height() / cIntRetinaFactor();
if (w < 2 * cornerWidth || h < 2 * cornerHeight) return;
if (w > 2 * cornerWidth) {
if (parts & RectPart::Top) {
p.fillRect(x + cornerWidth, y, w - 2 * cornerWidth, cornerHeight, bg);
}
if (parts & RectPart::Bottom) {
p.fillRect(x + cornerWidth, y + h - cornerHeight, w - 2 * cornerWidth, cornerHeight, bg);
if (shadow) {
p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, *shadow);
}
}
}
if (h > 2 * cornerHeight) {
if ((parts & RectPart::NoTopBottom) == RectPart::NoTopBottom) {
p.fillRect(x, y + cornerHeight, w, h - 2 * cornerHeight, bg);
} else {
if (parts & RectPart::Left) {
p.fillRect(x, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg);
}
if ((parts & RectPart::Center) && w > 2 * cornerWidth) {
p.fillRect(x + cornerWidth, y + cornerHeight, w - 2 * cornerWidth, h - 2 * cornerHeight, bg);
}
if (parts & RectPart::Right) {
p.fillRect(x + w - cornerWidth, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg);
}
}
}
if (parts & RectPart::TopLeft) {
p.drawPixmap(x, y, corner.p[0]);
}
if (parts & RectPart::TopRight) {
p.drawPixmap(x + w - cornerWidth, y, corner.p[1]);
}
if (parts & RectPart::BottomLeft) {
p.drawPixmap(x, y + h - cornerHeight, corner.p[2]);
}
if (parts & RectPart::BottomRight) {
p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight, corner.p[3]);
}
}
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow, RectParts parts) {
roundRect(p, x, y, w, h, bg, ::corners[index], shadow, parts);
}
void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, RoundCorners index, RectParts parts) {
auto &corner = ::corners[index];
auto cornerWidth = corner.p[0].width() / cIntRetinaFactor();
auto cornerHeight = corner.p[0].height() / cIntRetinaFactor();
if (parts & RectPart::Bottom) {
p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, shadow);
}
if (parts & RectPart::BottomLeft) {
p.fillRect(x, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow);
p.drawPixmap(x, y + h - cornerHeight + st::msgShadow, corner.p[2]);
}
if (parts & RectPart::BottomRight) {
p.fillRect(x + w - cornerWidth, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow);
p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight + st::msgShadow, corner.p[3]);
}
}
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts) {
auto colorKey = ((uint32(bg->c.alpha()) & 0xFF) << 24) | ((uint32(bg->c.red()) & 0xFF) << 16) | ((uint32(bg->c.green()) & 0xFF) << 8) | ((uint32(bg->c.blue()) & 0xFF) << 24);
auto i = cornersMap.find(colorKey);
if (i == cornersMap.cend()) {
QImage images[4];
switch (radius) {
case ImageRoundRadius::Small: prepareCorners(SmallMaskCorners, st::buttonRadius, bg, nullptr, images); break;
case ImageRoundRadius::Large: prepareCorners(LargeMaskCorners, st::historyMessageRadius, bg, nullptr, images); break;
default: p.fillRect(x, y, w, h, bg); return;
}
CornersPixmaps pixmaps;
for (int j = 0; j < 4; ++j) {
pixmaps.p[j] = pixmapFromImageInPlace(std::move(images[j]));
pixmaps.p[j].setDevicePixelRatio(cRetinaFactor());
}
i = cornersMap.insert(colorKey, pixmaps);
}
roundRect(p, x, y, w, h, bg, i.value(), nullptr, parts);
}
}

View File

@@ -8,54 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "data/data_types.h"
#include "ui/rect_part.h"
enum class ImageRoundRadius;
namespace HistoryView {
class Element;
} // namespace HistoryView
enum RoundCorners : int {
SmallMaskCorners = 0x00, // for images
LargeMaskCorners,
BoxCorners,
MenuCorners,
BotKbOverCorners,
StickerCorners,
StickerSelectedCorners,
SelectedOverlaySmallCorners,
SelectedOverlayLargeCorners,
DateCorners,
DateSelectedCorners,
OverviewVideoCorners,
OverviewVideoSelectedCorners,
ForwardCorners,
MediaviewSaveCorners,
EmojiHoverCorners,
StickerHoverCorners,
BotKeyboardCorners,
PhotoSelectOverlayCorners,
Doc1Corners,
Doc2Corners,
Doc3Corners,
Doc4Corners,
InShadowCorners, // for photos without bg
InSelectedShadowCorners,
MessageInCorners, // with shadow
MessageInSelectedCorners,
MessageOutCorners,
MessageOutSelectedCorners,
SendFilesBoxAlbumGroupCorners,
RoundCornersCount
};
namespace App {
QString formatPhone(QString phone);
@@ -90,20 +47,4 @@ namespace App {
QImage readImage(const QString &file, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr, QByteArray *content = 0);
QPixmap pixmapFromImageInPlace(QImage &&image);
void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
inline void roundRect(Painter &p, const QRect &rect, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
}
void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full);
inline void roundShadow(Painter &p, const QRect &rect, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full) {
return roundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index, parts);
}
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full);
inline void roundRect(Painter &p, const QRect &rect, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
}
};

View File

@@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
#include "ui/text/text_utilities.h"
#include "core/file_utilities.h"
#include "base/platform/base_platform_info.h"
#include "core/click_handler_types.h"
#include "core/update_checker.h"
@@ -108,7 +107,7 @@ void AboutBox::showVersionHistory() {
Ui::show(Box<InformBox>("The link to the current private alpha version of Telegram Desktop was copied to the clipboard."));
} else {
File::OpenUrl(qsl("https://desktop.telegram.org/changelog"));
UrlClickHandler::Open(qsl("https://desktop.telegram.org/changelog"));
}
}

View File

@@ -27,7 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/toast/toast.h"
#include "ui/special_buttons.h"
#include "ui/special_fields.h"
#include "ui/text_options.h"
#include "ui/text/text_options.h"
#include "ui/unread_badge.h"
#include "ui/ui_utility.h"
#include "data/data_channel.h"

View File

@@ -29,7 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/background_preview_box.h"
#include "window/window_session_controller.h"
#include "app.h"
#include "styles/style_history.h"
#include "styles/style_chat.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"

View File

@@ -446,7 +446,7 @@ autoDownloadLimitPadding: margins(22px, 8px, 22px, 8px);
confirmCaptionArea: InputField(defaultInputField) {
textMargins: margins(1px, 26px, 31px, 4px);
heightMax: 78px;
heightMax: 158px;
}
confirmBg: windowBgOver;
confirmMaxHeight: 245px;
@@ -489,7 +489,7 @@ backgroundScroll: ScrollArea(boxScroll) {
deltab: 10px;
}
editMediaButtonSize: 29px;
editMediaButtonSize: 28px;
editMediaButtonSkip: 8px;
editMediaButtonFileSkipRight: 1px;
editMediaButtonFileSkipTop: 7px;
@@ -508,25 +508,33 @@ editMediaButton: IconButton {
// SendFilesBox
sendBoxAlbumGroupEditInternalSkip: 9px;
sendBoxAlbumGroupEditInternalSkip: 8px;
sendBoxAlbumGroupSkipRight: 6px;
sendBoxAlbumGroupSkipTop: 6px;
sendBoxAlbumGroupRadius: 12px;
sendBoxAlbumGroupHeight: 25px;
sendBoxAlbumGroupRadius: 13px;
sendBoxAlbumGroupHeight: 26px;
sendBoxAlbumGroupEditButtonIcon: editMediaButtonIconPhoto;
sendBoxAlbumGroupEditButtonIconPosition: point(4px, -1px);
sendBoxFileGroupSkipTop: 2px;
sendBoxFileGroupSkipRight: 8px;
sendBoxFileGroupEditInternalSkip: -1px;
sendBoxAlbumGroupButtonFile: IconButton(editMediaButton) {
ripple: RippleAnimation(defaultRippleAnimation) {
color: windowBgRipple;
}
}
sendBoxAlbumGroupDeleteButtonIconPosition: point(-3px, 0px);
sendBoxAlbumGroupDeleteButtonIcon: icon {{ "history_file_cancel", msgServiceFg}};
sendBoxAlbumGroupEditButtonIconFile: editMediaButtonIconFile;
sendBoxAlbumGroupDeleteButtonIconFile: icon {{ "history_file_cancel", menuIconFg, point(6px, 6px) }};
sendBoxAlbumGroupButtonMediaEdit: icon {{ "settings_edit", msgServiceFg, point(3px, -2px) }};
sendBoxAlbumGroupButtonMediaDelete: icon {{ "history_file_cancel", msgServiceFg, point(2px, 5px) }};
sendBoxAlbumGroupButtonMedia: IconButton {
width: sendBoxAlbumGroupHeight;
height: sendBoxAlbumGroupHeight;
icon: sendBoxAlbumGroupButtonMediaEdit;
}
// End of SendFilesBox
calendarTitleHeight: boxTitleHeight;
@@ -705,11 +713,7 @@ groupStickersSubTitleHeight: 36px;
sendMediaPreviewSize: 308px;
sendMediaPreviewHeightMax: 1280;
sendMediaPreviewPhotoSkip: 10px;
sendMediaFileThumbSize: 64px;
sendMediaFileThumbSkip: 10px;
sendMediaFileNameTop: 7px;
sendMediaFileStatusTop: 37px;
sendMediaRowSkip: 10px;
proxyUsePadding: margins(22px, 6px, 22px, 5px);
proxyTryIPv6Padding: margins(22px, 8px, 22px, 5px);

View File

@@ -69,6 +69,21 @@ TextParseOptions kMarkedTextBoxOptions = {
Qt::LayoutDirectionAuto, // dir
};
[[nodiscard]] bool IsOldForPin(MsgId id, not_null<PeerData*> peer) {
const auto normal = peer->migrateToOrMe();
const auto migrated = normal->migrateFrom();
const auto top = Data::ResolveTopPinnedId(normal, migrated);
if (!top) {
return false;
} else if (peer == migrated) {
return top.channel || (id < top.msg);
} else if (migrated) {
return top.channel && (id < top.msg);
} else {
return (id < top.msg);
}
}
} // namespace
ConfirmBox::ConfirmBox(
@@ -444,20 +459,43 @@ PinMessageBox::PinMessageBox(
: _peer(peer)
, _api(&peer->session().mtp())
, _msgId(msgId)
, _text(this, tr::lng_pinned_pin_sure(tr::now), st::boxLabel) {
, _pinningOld(IsOldForPin(msgId, peer))
, _text(
this,
(_pinningOld
? tr::lng_pinned_pin_old_sure(tr::now)
: (peer->isChat() || peer->isMegagroup())
? tr::lng_pinned_pin_sure_group(tr::now)
: tr::lng_pinned_pin_sure(tr::now)),
st::boxLabel) {
}
void PinMessageBox::prepare() {
addButton(tr::lng_pinned_pin(), [this] { pinMessage(); });
addButton(tr::lng_cancel(), [this] { closeBox(); });
if (_peer->isChat() || _peer->isMegagroup()) {
_notify.create(this, tr::lng_pinned_notify(tr::now), true, st::defaultBoxCheckbox);
if (_peer->isUser() && !_peer->isSelf()) {
_pinForPeer.create(
this,
tr::lng_pinned_also_for_other(
tr::now,
lt_user,
_peer->shortName()),
false,
st::defaultBoxCheckbox);
_checkbox = _pinForPeer;
} else if (!_pinningOld && (_peer->isChat() || _peer->isMegagroup())) {
_notify.create(
this,
tr::lng_pinned_notify(tr::now),
true,
st::defaultBoxCheckbox);
_checkbox = _notify;
}
auto height = st::boxPadding.top() + _text->height() + st::boxPadding.bottom();
if (_notify) {
height += st::boxMediumSkip + _notify->heightNoMargins();
if (_checkbox) {
height += st::boxMediumSkip + _checkbox->heightNoMargins();
}
setDimensions(st::boxWidth, height);
}
@@ -465,8 +503,8 @@ void PinMessageBox::prepare() {
void PinMessageBox::resizeEvent(QResizeEvent *e) {
BoxContent::resizeEvent(e);
_text->moveToLeft(st::boxPadding.left(), st::boxPadding.top());
if (_notify) {
_notify->moveToLeft(st::boxPadding.left(), _text->y() + _text->height() + st::boxMediumSkip);
if (_checkbox) {
_checkbox->moveToLeft(st::boxPadding.left(), _text->y() + _text->height() + st::boxMediumSkip);
}
}
@@ -485,6 +523,9 @@ void PinMessageBox::pinMessage() {
if (_notify && !_notify->checked()) {
flags |= MTPmessages_UpdatePinnedMessage::Flag::f_silent;
}
if (_pinForPeer && !_pinForPeer->checked()) {
flags |= MTPmessages_UpdatePinnedMessage::Flag::f_pm_oneside;
}
_requestId = _api.request(MTPmessages_UpdatePinnedMessage(
MTP_flags(flags),
_peer->input,

View File

@@ -183,10 +183,13 @@ private:
const not_null<PeerData*> _peer;
MTP::Sender _api;
MsgId _msgId;
MsgId _msgId = 0;
bool _pinningOld = false;
object_ptr<Ui::FlatLabel> _text;
object_ptr<Ui::Checkbox> _notify = { nullptr };
object_ptr<Ui::Checkbox> _pinForPeer = { nullptr };
QPointer<Ui::Checkbox> _checkbox;
mtpRequestId _requestId = 0;

View File

@@ -25,7 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/toast/toast.h"
#include "ui/effects/animations.h"
#include "ui/effects/radial_animation.h"
#include "ui/text_options.h"
#include "ui/text/text_options.h"
#include "facades.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"

View File

@@ -47,17 +47,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/checkbox.h"
#include "ui/widgets/checkbox.h"
#include "ui/text/format_values.h"
#include "ui/special_buttons.h"
#include "ui/text_options.h"
#include "ui/text/text_options.h"
#include "ui/chat/attach/attach_prepare.h"
#include "ui/controls/emoji_button.h"
#include "ui/toast/toast.h"
#include "ui/cached_round_corners.h"
#include "window/window_session_controller.h"
#include "confirm_box.h"
#include "apiwrap.h"
#include "app.h" // App::pixmapFromImageInPlace.
#include "facades.h" // App::LambdaDelayed.
#include "app.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_history.h"
#include "styles/style_chat.h"
#include <QtCore/QMimeData>
@@ -67,13 +70,13 @@ using namespace ::Media::Streaming;
using Data::PhotoSize;
auto ListFromMimeData(not_null<const QMimeData*> data) {
using Error = Storage::PreparedList::Error;
using Error = Ui::PreparedList::Error;
auto result = data->hasUrls()
? Storage::PrepareMediaList(
// When we edit media, we need only 1 file.
data->urls().mid(0, 1),
st::sendMediaPreviewSize)
: Storage::PreparedList(Error::EmptyFile, QString());
: Ui::PreparedList(Error::EmptyFile, QString());
if (result.error == Error::None) {
return result;
} else if (data->hasImage()) {
@@ -103,10 +106,23 @@ EditCaptionBox::EditCaptionBox(
Expects(item->media()->allowsEditCaption());
_isAllowedEditMedia = item->media()->allowsEditMedia();
_isAlbum = !item->groupId().empty();
auto dimensions = QSize();
const auto media = item->media();
if (!item->groupId().empty()) {
if (media->photo()) {
_albumType = Ui::AlbumType::PhotoVideo;
} else if (const auto document = media->document()) {
if (document->isVideoFile()) {
_albumType = Ui::AlbumType::PhotoVideo;
} else if (document->isSong()) {
_albumType = Ui::AlbumType::Music;
} else {
_albumType = Ui::AlbumType::File;
}
}
}
if (const auto photo = media->photo()) {
_photoMedia = photo->createMediaView();
_photoMedia->wanted(PhotoSize::Large, _msgId);
@@ -155,11 +171,12 @@ EditCaptionBox::EditCaptionBox(
_thumbw = 0;
_thumbnailImageLoaded = true;
} else {
const auto thumbSize = st::msgFileThumbLayout.thumbSize;
const auto tw = dimensions.width(), th = dimensions.height();
if (tw > th) {
_thumbw = (tw * st::msgFileThumbSize) / th;
_thumbw = (tw * thumbSize) / th;
} else {
_thumbw = st::msgFileThumbSize;
_thumbw = thumbSize;
}
_refreshThumbnail = [=] {
const auto image = computeImage();
@@ -177,8 +194,8 @@ EditCaptionBox::EditCaptionBox(
_thumbw * cIntRetinaFactor(),
0,
options,
st::msgFileThumbSize,
st::msgFileThumbSize));
thumbSize,
thumbSize));
_thumbnailImageLoaded = true;
};
_refreshThumbnail();
@@ -352,8 +369,8 @@ EditCaptionBox::EditCaptionBox(
this,
object_ptr<Ui::Checkbox>(
this,
tr::lng_send_file(tr::now),
false,
tr::lng_send_compressed(tr::now),
true,
st::defaultBoxCheckbox),
st::editMediaCheckboxMargins);
_wayWrap = r.data();
@@ -361,8 +378,14 @@ EditCaptionBox::EditCaptionBox(
r->entity()->checkedChanges(
) | rpl::start_with_next([&](bool checked) {
_asFile = checked;
_asFile = !checked;
}, _wayWrap->lifetime());
_controller->session().data().itemRemoved(
_msgId
) | rpl::start_with_next([=] {
closeBox();
}, lifetime());
}
EditCaptionBox::~EditCaptionBox() = default;
@@ -469,7 +492,7 @@ void EditCaptionBox::streamingReady(Information &&info) {
}
void EditCaptionBox::updateEditPreview() {
using Info = FileMediaInformation;
using Info = Ui::PreparedFileInformation;
const auto file = &_preparedList.files.front();
const auto fileMedia = &file->information->media;
@@ -477,7 +500,8 @@ void EditCaptionBox::updateEditPreview() {
const auto fileinfo = QFileInfo(file->path);
const auto filename = fileinfo.fileName();
_isImage = fileIsImage(filename, file->mime);
const auto mime = file->information->filemime;
_isImage = Core::FileIsImage(filename, mime);
_isAudio = false;
_animated = false;
_photo = false;
@@ -490,9 +514,10 @@ void EditCaptionBox::updateEditPreview() {
auto shouldAsDoc = true;
auto docPhotoSize = QSize();
if (const auto image = std::get_if<Info::Image>(fileMedia)) {
shouldAsDoc = !Storage::ValidateThumbDimensions(
shouldAsDoc = !Ui::ValidateThumbDimensions(
image->data.width(),
image->data.height());
image->data.height()
) || (_albumType == Ui::AlbumType::File);
if (shouldAsDoc) {
docPhotoSize.setWidth(image->data.width());
docPhotoSize.setHeight(image->data.height());
@@ -509,7 +534,7 @@ void EditCaptionBox::updateEditPreview() {
if (shouldAsDoc) {
auto nameString = filename;
if (const auto song = std::get_if<Info::Song>(fileMedia)) {
nameString = DocumentData::ComposeNameString(
nameString = Ui::ComposeNameString(
filename,
song->title,
song->performer);
@@ -517,7 +542,7 @@ void EditCaptionBox::updateEditPreview() {
}
const auto getExt = [&] {
auto patterns = Core::MimeTypeForName(file->mime).globPatterns();
auto patterns = Core::MimeTypeForName(mime).globPatterns();
if (!patterns.isEmpty()) {
return patterns.front().replace('*', QString());
}
@@ -543,7 +568,7 @@ void EditCaptionBox::updateEditPreview() {
_doc = true;
}
const auto showCheckbox = _photo && !_isAlbum;
const auto showCheckbox = _photo && (_albumType == Ui::AlbumType::None);
_wayWrap->toggle(showCheckbox, anim::type::instant);
if (!_doc) {
@@ -580,25 +605,40 @@ void EditCaptionBox::updateEditMediaButton() {
void EditCaptionBox::createEditMediaButton() {
const auto callback = [=](FileDialog::OpenResult &&result) {
auto showBoxErrorCallback = [](tr::phrase<> t) {
Ui::show(Box<InformBox>(t(tr::now)), Ui::LayerOption::KeepOther);
auto showError = [](tr::phrase<> t) {
Ui::Toast::Show(t(tr::now));
};
auto list = Storage::PreparedList::PreparedFileFromFilesDialog(
const auto checkResult = [=](const Ui::PreparedList &list) {
if (list.files.size() != 1) {
return false;
}
const auto &file = list.files.front();
const auto mime = file.information->filemime;
if (Core::IsMimeSticker(mime)) {
showError(tr::lng_edit_media_invalid_file);
return false;
} else if (_albumType != Ui::AlbumType::None
&& !file.canBeInAlbumType(_albumType)) {
showError(tr::lng_edit_media_album_error);
return false;
}
return true;
};
auto list = Storage::PreparedFileFromFilesDialog(
std::move(result),
_isAlbum,
std::move(showBoxErrorCallback),
checkResult,
showError,
st::sendMediaPreviewSize);
if (list) {
_preparedList = std::move(*list);
updateEditPreview();
setPreparedList(std::move(*list));
}
};
const auto buttonCallback = [=] {
const auto filters = _isAlbum
? FileDialog::AlbumFilesFilter()
const auto filters = (_albumType == Ui::AlbumType::PhotoVideo)
? FileDialog::PhotoVideoFilesFilter()
: FileDialog::AllFilesFilter();
FileDialog::GetOpenPath(
this,
@@ -616,9 +656,10 @@ void EditCaptionBox::createEditMediaButton() {
_editMedia.create(this, st::editMediaButton);
updateEditMediaButton();
_editMedia->setClickedCallback(
App::LambdaDelayed(st::historyAttach.ripple.hideDuration, this, [=] {
buttonCallback();
}));
App::LambdaDelayed(
st::historyAttach.ripple.hideDuration,
this,
buttonCallback));
}
void EditCaptionBox::prepare() {
@@ -644,7 +685,7 @@ void EditCaptionBox::prepare() {
if (action == Ui::InputField::MimeAction::Check) {
if (!data->hasText() && !_isAllowedEditMedia) {
return false;
} else if (Storage::ValidateDragData(data, _isAlbum)) {
} else if (Storage::ValidateEditMediaDragData(data, _albumType)) {
return true;
}
return data->hasText();
@@ -668,38 +709,32 @@ void EditCaptionBox::prepare() {
}
bool EditCaptionBox::fileFromClipboard(not_null<const QMimeData*> data) {
return setPreparedList(ListFromMimeData(data));
}
bool EditCaptionBox::setPreparedList(Ui::PreparedList &&list) {
if (!_isAllowedEditMedia) {
return false;
}
using Error = Storage::PreparedList::Error;
using AlbumType = Storage::PreparedFile::AlbumType;
auto list = ListFromMimeData(data);
using Error = Ui::PreparedList::Error;
using Type = Ui::PreparedFile::Type;
if (list.error != Error::None || list.files.empty()) {
return false;
}
const auto file = &list.files.front();
if (_isAlbum && (file->type == AlbumType::None)) {
const auto imageAsDoc = [&] {
using Info = FileMediaInformation;
const auto fileMedia = &file->information->media;
if (const auto image = std::get_if<Info::Image>(fileMedia)) {
return !Storage::ValidateThumbDimensions(
image->data.width(),
image->data.height());
}
return false;
}();
if (!data->hasText() || imageAsDoc) {
Ui::show(
Box<InformBox>(tr::lng_edit_media_album_error(tr::now)),
Ui::LayerOption::KeepOther);
auto file = &list.files.front();
const auto invalidForAlbum = (_albumType != Ui::AlbumType::None)
&& !file->canBeInAlbumType(_albumType);
if (_albumType == Ui::AlbumType::PhotoVideo) {
using Video = Ui::PreparedFileInformation::Video;
if (const auto video = std::get_if<Video>(&file->information->media)) {
video->isGifv = false;
}
}
if (invalidForAlbum) {
Ui::Toast::Show(tr::lng_edit_media_album_error(tr::now));
return false;
}
_photo = _isImage = (file->type == AlbumType::Photo);
_photo = _isImage = (file->type == Type::Photo);
_preparedList = std::move(list);
updateEditPreview();
return true;
@@ -749,7 +784,7 @@ void EditCaptionBox::setupDragArea() {
auto enterFilter = [=](not_null<const QMimeData*> data) {
return !_isAllowedEditMedia
? false
: Storage::ValidateDragData(data, _isAlbum);
: Storage::ValidateEditMediaDragData(data, _albumType);
};
// Avoid both drag areas appearing at one time.
auto computeState = [=](const QMimeData *data) {
@@ -780,12 +815,11 @@ void EditCaptionBox::updateBoxSize() {
if (_photo) {
newHeight += _wayWrap->height() / 2;
}
const auto &st = _thumbw ? st::msgFileThumbLayout : st::msgFileLayout;
if (_photo || _animated) {
newHeight += std::max(_thumbh, _gifh);
} else if (_thumbw) {
newHeight += 0 + st::msgFileThumbSize + 0;
} else if (_doc) {
newHeight += 0 + st::msgFileSize + 0;
} else if (_thumbw || _doc) {
newHeight += 0 + st.thumbSize + 0;
} else {
newHeight += st::boxTitleFont->height;
}
@@ -854,7 +888,8 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) {
p.drawPixmap(_thumbx, st::boxPhotoPadding.top() + offset, _thumb);
}
if (_animated && !_streamed) {
QRect inner(_thumbx + (_thumbw - st::msgFileSize) / 2, st::boxPhotoPadding.top() + (th - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
const auto &st = st::msgFileLayout;
QRect inner(_thumbx + (_thumbw - st.thumbSize) / 2, st::boxPhotoPadding.top() + (th - st.thumbSize) / 2, st.thumbSize, st.thumbSize);
p.setPen(Qt::NoPen);
p.setBrush(st::msgDateImgBg);
@@ -867,43 +902,35 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) {
icon->paintInCenter(p, inner);
}
} else if (_doc) {
const auto &st = _thumbw ? st::msgFileThumbLayout : st::msgFileLayout;
const auto w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
const auto h = _thumbw ? (0 + st::msgFileThumbSize + 0) : (0 + st::msgFileSize + 0);
auto nameleft = 0, nametop = 0, nameright = 0, statustop = 0;
if (_thumbw) {
nameleft = 0 + st::msgFileThumbSize + st::msgFileThumbPadding.right();
nametop = st::msgFileThumbNameTop - st::msgFileThumbPadding.top();
nameright = 0;
statustop = st::msgFileThumbStatusTop - st::msgFileThumbPadding.top();
} else {
nameleft = 0 + st::msgFileSize + st::msgFilePadding.right();
nametop = st::msgFileNameTop - st::msgFilePadding.top();
nameright = 0;
statustop = st::msgFileStatusTop - st::msgFilePadding.top();
}
const auto h = 0 + st.thumbSize + 0;
const auto nameleft = 0 + st.thumbSize + st.padding.right();
const auto nametop = st.nameTop - st.padding.top();
const auto nameright = 0;
const auto statustop = st.statusTop - st.padding.top();
const auto editButton = _isAllowedEditMedia
? _editMedia->width() + st::editMediaButtonSkip
: 0;
const auto namewidth = w - nameleft - editButton;
const auto x = (width() - w) / 2, y = st::boxPhotoPadding.top();
// App::roundRect(p, x, y, w, h, st::msgInBg, MessageInCorners, &st::msgInShadow);
// Ui::FillRoundCorner(p, x, y, w, h, st::msgInBg, Ui::MessageInCorners, &st::msgInShadow);
const auto rthumb = style::rtlrect(x + 0, y + 0, st.thumbSize, st.thumbSize, width());
if (_thumbw) {
QRect rthumb(style::rtlrect(x + 0, y + 0, st::msgFileThumbSize, st::msgFileThumbSize, width()));
p.drawPixmap(rthumb.topLeft(), _thumb);
} else {
const QRect inner(style::rtlrect(x + 0, y + 0, st::msgFileSize, st::msgFileSize, width()));
p.setPen(Qt::NoPen);
p.setBrush(st::msgFileInBg);
{
PainterHighQualityEnabler hq(p);
p.drawEllipse(inner);
p.drawEllipse(rthumb);
}
const auto icon = &(_isAudio ? st::historyFileInPlay : _isImage ? st::historyFileInImage : st::historyFileInDocument);
icon->paintInCenter(p, inner);
icon->paintInCenter(p, rthumb);
}
p.setFont(st::semiboldFont);
p.setPen(st::historyFileNameInFg);

View File

@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/abstract_box.h"
#include "storage/storage_media_prepare.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/chat/attach/attach_prepare.h"
class Image;
@@ -32,6 +33,7 @@ class InputField;
class EmojiButton;
class IconButton;
class Checkbox;
enum class AlbumType;
} // namespace Ui
namespace Window {
@@ -92,6 +94,7 @@ private:
int errorTopSkip() const;
void createEditMediaButton();
bool setPreparedList(Ui::PreparedList &&list);
inline QString getNewMediaPath() {
return _preparedList.files.empty()
@@ -130,15 +133,15 @@ private:
int _gifh = 0;
int _gifx = 0;
Storage::PreparedList _preparedList;
Ui::PreparedList _preparedList;
mtpRequestId _saveRequestId = 0;
object_ptr<Ui::IconButton> _editMedia = nullptr;
Ui::SlideWrap<Ui::RpWidget> *_wayWrap = nullptr;
QString _newMediaPath;
Ui::AlbumType _albumType = Ui::AlbumType();
bool _isAllowedEditMedia = false;
bool _isAlbum = false;
bool _asFile = false;
rpl::event_stream<> _editMediaClicks;

View File

@@ -77,8 +77,12 @@ std::vector<not_null<PeerData*>> PrivacyExceptionsBoxController::getResult() con
}
void PrivacyExceptionsBoxController::rowClicked(not_null<PeerListRow*> row) {
const auto peer = row->peer();
// This call may delete row, if it was a search result row.
delegate()->peerListSetRowChecked(row, !row->checked());
if (const auto channel = row->peer()->asChannel()) {
if (const auto channel = peer->asChannel()) {
if (!channel->membersCountKnown()) {
channel->updateFull();
}

View File

@@ -20,7 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/slide_wrap.h"
#include "ui/effects/ripple_animation.h"
#include "ui/toast/toast.h"
#include "ui/text_options.h"
#include "ui/text/text_options.h"
#include "storage/localstorage.h"
#include "boxes/confirm_box.h"
#include "mainwidget.h"

View File

@@ -17,7 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/ripple_animation.h"
#include "ui/empty_userpic.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/text_options.h"
#include "ui/text/text_options.h"
#include "lang/lang_keys.h"
#include "storage/file_download.h"
#include "data/data_peer_values.h"
@@ -178,7 +178,7 @@ void PeerListBox::resizeEvent(QResizeEvent *e) {
void PeerListBox::paintEvent(QPaintEvent *e) {
Painter p(this);
for (auto rect : e->region().rects()) {
for (const auto rect : e->region()) {
p.fillRect(rect, st::contactsBg);
}
}

View File

@@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_histories.h"
#include "apiwrap.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "lang/lang_keys.h"
#include "history/history.h"
#include "dialogs/dialogs_main_list.h"
@@ -104,6 +105,20 @@ void AddBotToGroup(not_null<UserData*> bot, not_null<PeerData*> chat) {
// return mapFromGlobal(QCursor::pos()) - _st.rippleAreaPosition;
//}
object_ptr<Ui::BoxContent> PrepareContactsBox(
not_null<Window::SessionController*> sessionController) {
const auto controller = sessionController;
auto delegate = [=](not_null<PeerListBox*> box) {
box->addButton(tr::lng_close(), [=] { box->closeBox(); });
box->addLeftButton(
tr::lng_profile_add_contact(),
[=] { controller->widget()->onShowAddContact(); });
};
return Box<PeerListBox>(
std::make_unique<ContactsBoxController>(controller),
std::move(delegate));
}
void PeerListRowWithLink::setActionLink(const QString &action) {
_action = action;
refreshActionLink();

View File

@@ -31,9 +31,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class History;
namespace Window {
class SessionController;
class SessionNavigation;
} // namespace Window
[[nodiscard]] object_ptr<Ui::BoxContent> PrepareContactsBox(
not_null<Window::SessionController*> sessionController);
class PeerListRowWithLink : public PeerListRow {
public:
using PeerListRow::PeerListRow;

View File

@@ -86,6 +86,9 @@ public:
AdminDoneCallback adminDoneCallback,
BannedDoneCallback bannedDoneCallback);
[[nodiscard]] not_null<PeerData*> peer() const {
return _peer;
}
[[nodiscard]] Main::Session &session() const override;
void prepare() override;
void rowClicked(not_null<PeerListRow*> row) override;

View File

@@ -19,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/layers/generic_box.h"
#include "ui/toast/toast.h"
#include "ui/text/text_utilities.h"
#include "ui/text_options.h"
#include "ui/text/text_options.h"
#include "ui/special_buttons.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "settings/settings_privacy_security.h"
@@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h"
#include "core/core_cloud_password.h"
#include "base/unixtime.h"
#include "base/qt_adapters.h"
#include "apiwrap.h"
#include "main/main_session.h"
#include "styles/style_layers.h"
@@ -308,7 +309,7 @@ void EditAdminBox::prepare() {
}, lifetime());
if (canTransferOwnership()) {
const auto allFlags = FullAdminRights(isGroup);
const auto allFlags = AdminRightsForOwnershipTransfer(isGroup);
setupTransferButton(
isGroup
)->toggleOn(rpl::duplicate(
@@ -694,7 +695,7 @@ void EditRestrictedBox::showRestrictUntil() {
highlighted,
[this](const QDate &date) {
setRestrictUntil(
static_cast<int>(QDateTime(date).toTime_t()));
static_cast<int>(base::QDateToDateTime(date).toTime_t()));
}),
Ui::LayerOption::KeepOther);
_restrictUntilBox->setMaxDate(

View File

@@ -557,6 +557,8 @@ UserData *ParticipantsAdditionalData::applyParticipant(
return logBad();
}
return applyBanned(data);
}, [&](const MTPDchannelParticipantLeft &data) {
return logBad();
});
}

View File

@@ -298,10 +298,12 @@ ChatRestrictions FixDependentRestrictions(ChatRestrictions restrictions) {
return restrictions;
}
ChatAdminRights FullAdminRights(bool isGroup) {
ChatAdminRights AdminRightsForOwnershipTransfer(bool isGroup) {
auto result = ChatAdminRights();
for (const auto &[flag, label] : AdminRightLabels(isGroup, true)) {
result |= flag;
if (!(flag & ChatAdminRight::f_anonymous)) {
result |= flag;
}
}
return result;
}

View File

@@ -71,4 +71,4 @@ EditFlagsControl<MTPDchatAdminRights::Flags> CreateEditAdminRights(
ChatAdminRights DisabledByDefaultRestrictions(not_null<PeerData*> peer);
ChatRestrictions FixDependentRestrictions(ChatRestrictions restrictions);
ChatAdminRights FullAdminRights(bool isGroup);
ChatAdminRights AdminRightsForOwnershipTransfer(bool isGroup);

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <rpl/variable.h>
#include "boxes/abstract_box.h"
#include "ui/chat/attach/attach_prepare.h"
#include "ui/chat/attach/attach_send_files_way.h"
#include "storage/localimageloader.h"
#include "storage/storage_media_prepare.h"
@@ -26,14 +28,13 @@ class TabbedPanel;
} // namespace ChatHelpers
namespace Ui {
template <typename Enum>
class Radioenum;
template <typename Enum>
class RadioenumGroup;
class Checkbox;
class RoundButton;
class InputField;
struct GroupMediaLayout;
class EmojiButton;
class AlbumPreview;
class VerticalLayout;
} // namespace Ui
namespace Window {
@@ -44,12 +45,6 @@ namespace SendMenu {
enum class Type;
} // namespace SendMenu
enum class SendFilesWay {
Album,
Photos,
Files,
};
class SendFilesBox : public Ui::BoxContent {
public:
enum class SendLimit {
@@ -59,17 +54,16 @@ public:
SendFilesBox(
QWidget*,
not_null<Window::SessionController*> controller,
Storage::PreparedList &&list,
Ui::PreparedList &&list,
const TextWithTags &caption,
CompressConfirm compressed,
SendLimit limit,
Api::SendType sendType,
SendMenu::Type sendMenuType);
void setConfirmedCallback(
Fn<void(
Storage::PreparedList &&list,
SendFilesWay way,
Ui::PreparedList &&list,
Ui::SendFilesWay way,
TextWithTags &&caption,
Api::SendOptions options,
bool ctrlShiftEnter)> callback) {
@@ -90,65 +84,92 @@ protected:
void resizeEvent(QResizeEvent *e) override;
private:
class AlbumPreview;
class Block final {
public:
Block(
not_null<QWidget*> parent,
not_null<std::vector<Ui::PreparedFile>*> items,
int from,
int till,
Fn<bool()> gifPaused,
Ui::SendFilesWay way);
Block(Block &&other) = default;
Block &operator=(Block &&other) = default;
[[nodiscard]] int fromIndex() const;
[[nodiscard]] int tillIndex() const;
[[nodiscard]] object_ptr<Ui::RpWidget> takeWidget();
[[nodiscard]] rpl::producer<int> itemDeleteRequest() const;
[[nodiscard]] rpl::producer<int> itemReplaceRequest() const;
void setSendWay(Ui::SendFilesWay way);
void applyAlbumOrder();
private:
base::unique_qptr<Ui::RpWidget> _preview;
not_null<std::vector<Ui::PreparedFile>*> _items;
int _from = 0;
int _till = 0;
bool _isAlbum = false;
bool _isSingleMedia = false;
};
void initSendWay();
void initPreview(rpl::producer<int> desiredPreviewHeight);
void initPreview();
void setupControls();
void refreshControls();
void setupSendWayControls();
void setupCaption();
void setupShadows(
not_null<Ui::ScrollArea*> wrap,
not_null<AlbumPreview*> content);
void setupShadows();
void setupEmojiPanel();
void updateSendWayControlsVisibility();
void updateEmojiPanelGeometry();
void emojiFilterForGeometry(not_null<QEvent*> event);
void refreshAlbumMediaCount();
void preparePreview();
void prepareSingleFilePreview();
void prepareAlbumPreview();
void applyAlbumOrder();
void generatePreviewFrom(int fromBlock);
void send(Api::SendOptions options, bool ctrlShiftEnter = false);
void sendSilent();
void sendScheduled();
void captionResized();
void saveSendWaySettings();
void setupDragArea();
void setupTitleText();
void refreshTitleText();
void updateBoxSize();
void updateControlsGeometry();
void updateCaptionPlaceholder();
void addThumbButtonHandlers(not_null<Ui::ScrollArea*> wrap);
bool canAddFiles(not_null<const QMimeData*> data) const;
bool addFiles(not_null<const QMimeData*> data);
bool addFiles(Storage::PreparedList list);
bool addFiles(Ui::PreparedList list);
void addFile(Ui::PreparedFile &&file);
void pushBlock(int from, int till);
void openDialogToAddFileToAlbum();
void updateLeftButtonVisibility();
void refreshAllAfterAlbumChanges();
void refreshAllAfterChanges(int fromItem);
void enqueueNextPrepare();
void addPreparedAsyncFile(Ui::PreparedFile &&file);
const not_null<Window::SessionController*> _controller;
const Api::SendType _sendType = Api::SendType();
QString _titleText;
int _titleHeight = 0;
rpl::variable<int> _titleHeight = 0;
Storage::PreparedList _list;
Ui::PreparedList _list;
std::optional<int> _removingIndex;
CompressConfirm _compressConfirmInitial = CompressConfirm::None;
CompressConfirm _compressConfirm = CompressConfirm::None;
SendLimit _sendLimit = SendLimit::Many;
SendMenu::Type _sendMenuType = SendMenu::Type();
Fn<void(
Storage::PreparedList &&list,
SendFilesWay way,
Ui::PreparedList &&list,
Ui::SendFilesWay way,
TextWithTags &&caption,
Api::SendOptions options,
bool ctrlShiftEnter)> _confirmedCallback;
@@ -160,22 +181,20 @@ private:
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
base::unique_qptr<QObject> _emojiFilter;
object_ptr<Ui::Radioenum<SendFilesWay>> _sendAlbum = { nullptr };
object_ptr<Ui::Radioenum<SendFilesWay>> _sendPhotos = { nullptr };
object_ptr<Ui::Radioenum<SendFilesWay>> _sendFiles = { nullptr };
std::shared_ptr<Ui::RadioenumGroup<SendFilesWay>> _sendWay;
object_ptr<Ui::Checkbox> _groupFiles = { nullptr };
object_ptr<Ui::Checkbox> _sendImagesAsPhotos = { nullptr };
rpl::variable<Ui::SendFilesWay> _sendWay = Ui::SendFilesWay();
rpl::variable<int> _footerHeight = 0;
rpl::event_stream<> _albumChanged;
rpl::lifetime _dimensionsLifetime;
QWidget *_preview = nullptr;
AlbumPreview *_albumPreview = nullptr;
int _albumVideosCount = 0;
int _albumPhotosCount = 0;
int _lastScrollTop = 0;
object_ptr<Ui::ScrollArea> _scroll;
QPointer<Ui::VerticalLayout> _inner;
std::vector<Block> _blocks;
Fn<void()> _whenReadySend;
bool _preparing = false;
QPointer<Ui::RoundButton> _send;
QPointer<Ui::RoundButton> _addFileToAlbum;
QPointer<Ui::RoundButton> _addFile;
};

View File

@@ -21,7 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/input_fields.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/text_options.h"
#include "ui/text/text_options.h"
#include "chat_helpers/message_field.h"
#include "chat_helpers/send_context_menu.h"
#include "history/history.h"
@@ -40,7 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/application.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_history.h"
#include "styles/style_chat.h"
class ShareBox::Inner final : public Ui::RpWidget, private base::Subscriber {
public:

View File

@@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/emoji_config.h"
#include "ui/toast/toast.h"
#include "ui/widgets/popup_menu.h"
#include "ui/cached_round_corners.h"
#include "lottie/lottie_multi_player.h"
#include "lottie/lottie_animation.h"
#include "chat_helpers/stickers_lottie.h"
@@ -35,7 +36,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "app.h"
#include "styles/style_layers.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_info.h"
@@ -661,7 +661,7 @@ void StickerSetBox::Inner::paintSticker(
p.setOpacity(over);
auto tl = position;
if (rtl()) tl.setX(width() - tl.x() - st::stickersSize.width());
App::roundRect(p, QRect(tl, st::stickersSize), st::emojiPanHover, StickerHoverCorners);
Ui::FillRoundRect(p, QRect(tl, st::stickersSize), st::emojiPanHover, Ui::StickerHoverCorners);
p.setOpacity(1);
}

View File

@@ -33,9 +33,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/discrete_sliders.h"
#include "ui/widgets/input_fields.h"
#include "ui/image/image.h"
#include "ui/cached_round_corners.h"
#include "window/window_session_controller.h"
#include "main/main_session.h"
#include "app.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_chat_helpers.h"
@@ -1129,7 +1129,7 @@ void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> row, int index) {
Ui::Shadow::paint(p, rect, width(), st::boxRoundShadow);
p.setOpacity(1);
App::roundRect(p, rect, st::boxBg, BoxCorners);
Ui::FillRoundRect(p, rect, st::boxBg, Ui::BoxCorners);
p.setOpacity(1. - current);
paintFakeButton(p, row, index);
@@ -1318,7 +1318,7 @@ void StickersBox::Inner::paintFakeButton(Painter &p, not_null<Row*> row, int ind
auto textWidth = (_section == Section::Installed) ? _undoWidth : _addWidth;
auto &text = (_section == Section::Installed) ? _undoText : _addText;
auto &textBg = selected ? st.textBgOver : st.textBg;
App::roundRect(p, myrtlrect(rect), textBg, ImageRoundRadius::Small);
Ui::FillRoundRect(p, myrtlrect(rect), textBg, ImageRoundRadius::Small);
if (row->ripple) {
row->ripple->paint(p, rect.x(), rect.y(), width());
if (row->ripple->empty()) {

View File

@@ -296,7 +296,7 @@ void BoxController::loadMoreRows() {
MTP_flags(0),
MTP_inputPeerEmpty(),
MTP_string(),
MTP_inputUserEmpty(),
MTP_inputPeerEmpty(),
MTPint(), // top_msg_id
MTP_inputMessagesFilterPhoneCalls(MTP_flags(0)),
MTP_int(0),

View File

@@ -42,7 +42,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "app.h"
#include "webrtc/webrtc_video_track.h"
#include "styles/style_calls.h"
#include "styles/style_history.h"
#include "styles/style_chat.h"
#ifdef Q_OS_WIN
#include "ui/platform/win/ui_window_title_win.h"
@@ -981,7 +981,7 @@ void Panel::paint(QRect clip) {
if (!_incoming->isHidden()) {
region = region.subtracted(QRegion(_incoming->geometry()));
}
for (const auto rect : region.rects()) {
for (const auto rect : region) {
p.fillRect(rect, st::callBgOpaque);
}
if (_incoming && _incoming->isHidden()) {

View File

@@ -12,10 +12,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h"
#include "data/data_session.h"
#include "main/main_session.h"
#include "ui/cached_round_corners.h"
#include "facades.h"
#include "app.h"
#include "styles/style_widgets.h"
#include "styles/style_history.h"
#include "styles/style_chat.h"
namespace {
@@ -76,7 +76,7 @@ void Style::paintButtonBg(
Painter &p,
const QRect &rect,
float64 howMuchOver) const {
App::roundRect(p, rect, st::botKbBg, BotKeyboardCorners);
Ui::FillRoundRect(p, rect, st::botKbBg, Ui::BotKeyboardCorners);
}
void Style::paintButtonIcon(

View File

@@ -278,3 +278,6 @@ manageEmojiPreviewPadding: margins(22px, 9px, 19px, 9px);
manageEmojiMarginRight: 21px;
manageEmojiNameTop: 3px;
manageEmojiStatusTop: 25px;
inlineRadialSize: 44px;
inlineFileSize: 44px;

View File

@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/shadow.h"
#include "ui/emoji_config.h"
#include "ui/ui_utility.h"
#include "ui/cached_round_corners.h"
#include "lang/lang_keys.h"
#include "emoji_suggestions_data.h"
#include "emoji_suggestions_helper.h"
@@ -20,7 +21,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/application.h"
#include "window/window_session_controller.h"
#include "facades.h"
#include "app.h"
#include "styles/style_chat_helpers.h"
namespace ChatHelpers {
@@ -211,7 +211,7 @@ void EmojiColorPicker::paintEvent(QPaintEvent *e) {
return;
}
Ui::Shadow::paint(p, inner, width(), st::defaultRoundShadow);
App::roundRect(p, inner, st::boxBg, BoxCorners);
Ui::FillRoundRect(p, inner, st::boxBg, Ui::BoxCorners);
auto x = st::emojiPanMargins.left() + 2 * st::emojiColorsPadding + _singleSize.width();
if (rtl()) x = width() - x - st::emojiColorsSep;
@@ -372,7 +372,7 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
if (variant == _selected) {
QPoint tl(w);
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
App::roundRect(p, QRect(tl, _singleSize), st::emojiPanHover, StickerHoverCorners);
Ui::FillRoundRect(p, QRect(tl, _singleSize), st::emojiPanHover, Ui::StickerHoverCorners);
}
const auto esize = Ui::Emoji::GetSizeLarge();
Ui::Emoji::Draw(
@@ -558,7 +558,7 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
if (selected) {
auto tl = w;
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
App::roundRect(p, QRect(tl, _singleSize), st::emojiPanHover, StickerHoverCorners);
Ui::FillRoundRect(p, QRect(tl, _singleSize), st::emojiPanHover, Ui::StickerHoverCorners);
}
Ui::Emoji::Draw(
p,

View File

@@ -17,11 +17,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/input_fields.h"
#include "ui/emoji_config.h"
#include "ui/ui_utility.h"
#include "ui/cached_round_corners.h"
#include "platform/platform_specific.h"
#include "core/application.h"
#include "base/event_filter.h"
#include "main/main_session.h"
#include "app.h"
#include "styles/style_chat_helpers.h"
#include <QtWidgets/QApplication>
@@ -171,10 +171,8 @@ bool SuggestionsWidget::eventHook(QEvent *e) {
}
void SuggestionsWidget::scrollByWheelEvent(not_null<QWheelEvent*> e) {
const auto horizontal = (e->angleDelta().x() != 0)
|| (e->orientation() == Qt::Horizontal);
const auto vertical = (e->angleDelta().y() != 0)
|| (e->orientation() == Qt::Vertical);
const auto horizontal = (e->angleDelta().x() != 0);
const auto vertical = (e->angleDelta().y() != 0);
const auto current = scrollCurrent();
const auto scroll = [&] {
if (horizontal) {
@@ -218,11 +216,11 @@ void SuggestionsWidget::paintEvent(QPaintEvent *e) {
? _pressed
: _selectedAnimation.value(_selected);
if (selected > -1.) {
App::roundRect(
Ui::FillRoundRect(
p,
QRect(selected * _oneWidth, 0, _oneWidth, _oneWidth),
st::emojiPanHover,
StickerHoverCorners);
Ui::StickerHoverCorners);
}
for (auto i = from; i != till; ++i) {

View File

@@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/stickers/data_stickers.h"
#include "chat_helpers/send_context_menu.h" // SendMenu::FillSendMenu
#include "chat_helpers/stickers_lottie.h"
#include "chat_helpers/message_field.h" // PrepareMentionTag.
#include "mainwindow.h"
#include "apiwrap.h"
#include "main/main_session.h"
@@ -27,27 +28,121 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lottie/lottie_single_player.h"
#include "ui/widgets/popup_menu.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/input_fields.h"
#include "ui/image/image.h"
#include "ui/ui_utility.h"
#include "ui/cached_round_corners.h"
#include "base/unixtime.h"
#include "window/window_session_controller.h"
#include "facades.h"
#include "app.h"
#include "styles/style_history.h"
#include "styles/style_chat.h"
#include "styles/style_widgets.h"
#include "styles/style_chat_helpers.h"
#include <QtWidgets/QApplication>
class FieldAutocomplete::Inner final
: public Ui::RpWidget
, private base::Subscriber {
public:
struct ScrollTo {
int top;
int bottom;
};
Inner(
not_null<Window::SessionController*> controller,
not_null<FieldAutocomplete*> parent,
not_null<MentionRows*> mrows,
not_null<HashtagRows*> hrows,
not_null<BotCommandRows*> brows,
not_null<StickerRows*> srows);
void clearSel(bool hidden = false);
bool moveSel(int key);
bool chooseSelected(FieldAutocomplete::ChooseMethod method) const;
bool chooseAtIndex(
FieldAutocomplete::ChooseMethod method,
int index,
Api::SendOptions options = Api::SendOptions()) const;
void setRecentInlineBotsInRows(int32 bots);
void setSendMenuType(Fn<SendMenu::Type()> &&callback);
void rowsUpdated();
rpl::producer<FieldAutocomplete::MentionChosen> mentionChosen() const;
rpl::producer<FieldAutocomplete::HashtagChosen> hashtagChosen() const;
rpl::producer<FieldAutocomplete::BotCommandChosen>
botCommandChosen() const;
rpl::producer<FieldAutocomplete::StickerChosen> stickerChosen() const;
rpl::producer<ScrollTo> scrollToRequested() const;
void onParentGeometryChanged();
private:
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void enterEventHook(QEvent *e) override;
void leaveEventHook(QEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void contextMenuEvent(QContextMenuEvent *e) override;
void updateSelectedRow();
void setSel(int sel, bool scroll = false);
void showPreview();
void selectByMouse(QPoint global);
QSize stickerBoundingBox() const;
void setupLottie(StickerSuggestion &suggestion);
void repaintSticker(not_null<DocumentData*> document);
std::shared_ptr<Lottie::FrameRenderer> getLottieRenderer();
const not_null<Window::SessionController*> _controller;
const not_null<FieldAutocomplete*> _parent;
const not_null<MentionRows*> _mrows;
const not_null<HashtagRows*> _hrows;
const not_null<BotCommandRows*> _brows;
const not_null<StickerRows*> _srows;
rpl::lifetime _stickersLifetime;
std::weak_ptr<Lottie::FrameRenderer> _lottieRenderer;
base::unique_qptr<Ui::PopupMenu> _menu;
int _stickersPerRow = 1;
int _recentInlineBotsInRows = 0;
int _sel = -1;
int _down = -1;
std::optional<QPoint> _lastMousePosition;
bool _mouseSelection = false;
bool _overDelete = false;
bool _previewShown = false;
Fn<SendMenu::Type()> _sendMenuType;
rpl::event_stream<FieldAutocomplete::MentionChosen> _mentionChosen;
rpl::event_stream<FieldAutocomplete::HashtagChosen> _hashtagChosen;
rpl::event_stream<FieldAutocomplete::BotCommandChosen> _botCommandChosen;
rpl::event_stream<FieldAutocomplete::StickerChosen> _stickerChosen;
rpl::event_stream<ScrollTo> _scrollToRequested;
base::Timer _previewTimer;
};
FieldAutocomplete::FieldAutocomplete(
QWidget *parent,
not_null<Window::SessionController*> controller)
: RpWidget(parent)
, _controller(controller)
, _scroll(this, st::mentionScroll) {
_scroll->setGeometry(rect());
hide();
using Inner = internal::FieldAutocompleteInner;
_scroll->setGeometry(rect());
_inner = _scroll->setOwnedWidget(
object_ptr<Inner>(
@@ -76,6 +171,10 @@ FieldAutocomplete::FieldAutocomplete(
&Inner::onParentGeometryChanged);
}
not_null<Window::SessionController*> FieldAutocomplete::controller() const {
return _controller;
}
auto FieldAutocomplete::mentionChosen() const
-> rpl::producer<FieldAutocomplete::MentionChosen> {
return _inner->mentionChosen();
@@ -125,9 +224,9 @@ void FieldAutocomplete::showFiltered(
if (query.isEmpty()) {
_type = Type::Mentions;
rowsUpdated(
internal::MentionRows(),
internal::HashtagRows(),
internal::BotCommandRows(),
MentionRows(),
HashtagRows(),
BotCommandRows(),
base::take(_srows),
false);
return;
@@ -171,7 +270,7 @@ void FieldAutocomplete::showStickers(EmojiPtr emoji) {
base::take(_mrows),
base::take(_hrows),
base::take(_brows),
internal::StickerRows(),
StickerRows(),
false);
return;
}
@@ -203,7 +302,7 @@ inline int indexOfInFirstN(const T &v, const U &elem, int last) {
}
}
internal::StickerRows FieldAutocomplete::getStickerSuggestions() {
FieldAutocomplete::StickerRows FieldAutocomplete::getStickerSuggestions() {
const auto list = _controller->session().data().stickers().getListByEmoji(
_emoji,
_stickersSeed
@@ -211,7 +310,7 @@ internal::StickerRows FieldAutocomplete::getStickerSuggestions() {
auto result = ranges::view::all(
list
) | ranges::view::transform([](not_null<DocumentData*> sticker) {
return internal::StickerSuggestion{
return StickerSuggestion{
sticker,
sticker->createMediaView()
};
@@ -223,7 +322,7 @@ internal::StickerRows FieldAutocomplete::getStickerSuggestions() {
const auto i = ranges::find(
result,
suggestion.document,
&internal::StickerSuggestion::document);
&StickerSuggestion::document);
if (i != end(result)) {
i->animated = std::move(suggestion.animated);
}
@@ -233,10 +332,10 @@ internal::StickerRows FieldAutocomplete::getStickerSuggestions() {
void FieldAutocomplete::updateFiltered(bool resetScroll) {
int32 now = base::unixtime::now(), recentInlineBots = 0;
internal::MentionRows mrows;
internal::HashtagRows hrows;
internal::BotCommandRows brows;
internal::StickerRows srows;
MentionRows mrows;
HashtagRows hrows;
BotCommandRows brows;
StickerRows srows;
if (_emoji) {
srows = getStickerSuggestions();
} else if (_type == Type::Mentions) {
@@ -435,10 +534,10 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
}
void FieldAutocomplete::rowsUpdated(
internal::MentionRows &&mrows,
internal::HashtagRows &&hrows,
internal::BotCommandRows &&brows,
internal::StickerRows &&srows,
MentionRows &&mrows,
HashtagRows &&hrows,
BotCommandRows &&brows,
StickerRows &&srows,
bool resetScroll) {
if (mrows.empty() && hrows.empty() && brows.empty() && srows.empty()) {
if (!isHidden()) {
@@ -590,6 +689,10 @@ bool FieldAutocomplete::chooseSelected(ChooseMethod method) const {
return _inner->chooseSelected(method);
}
void FieldAutocomplete::setSendMenuType(Fn<SendMenu::Type()> &&callback) {
_inner->setSendMenuType(std::move(callback));
}
bool FieldAutocomplete::eventFilter(QObject *obj, QEvent *e) {
auto hidden = isHidden();
auto moderate = Core::App().settings().moderateModeEnabled();
@@ -620,9 +723,7 @@ bool FieldAutocomplete::eventFilter(QObject *obj, QEvent *e) {
return QWidget::eventFilter(obj, e);
}
namespace internal {
FieldAutocompleteInner::FieldAutocompleteInner(
FieldAutocomplete::Inner::Inner(
not_null<Window::SessionController*> controller,
not_null<FieldAutocomplete*> parent,
not_null<MentionRows*> mrows,
@@ -642,7 +743,7 @@ FieldAutocompleteInner::FieldAutocompleteInner(
}, lifetime());
}
void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) {
Painter p(this);
QRect r(e->rect());
@@ -686,7 +787,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
if (_sel == index) {
QPoint tl(pos);
if (rtl()) tl.setX(width() - tl.x() - st::stickerPanSize.width());
App::roundRect(p, QRect(tl, st::stickerPanSize), st::emojiPanHover, StickerHoverCorners);
Ui::FillRoundRect(p, QRect(tl, st::stickerPanSize), st::emojiPanHover, Ui::StickerHoverCorners);
}
media->checkStickerSmall();
@@ -841,11 +942,11 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
p.fillRect(Adaptive::OneColumn() ? 0 : st::lineWidth, _parent->innerTop(), width() - (Adaptive::OneColumn() ? 0 : st::lineWidth), st::lineWidth, st::shadowFg);
}
void FieldAutocompleteInner::resizeEvent(QResizeEvent *e) {
void FieldAutocomplete::Inner::resizeEvent(QResizeEvent *e) {
_stickersPerRow = qMax(1, int32(width() - 2 * st::stickerPanPadding) / int32(st::stickerPanSize.width()));
}
void FieldAutocompleteInner::mouseMoveEvent(QMouseEvent *e) {
void FieldAutocomplete::Inner::mouseMoveEvent(QMouseEvent *e) {
const auto globalPosition = e->globalPos();
if (!_lastMousePosition) {
_lastMousePosition = globalPosition;
@@ -857,7 +958,7 @@ void FieldAutocompleteInner::mouseMoveEvent(QMouseEvent *e) {
selectByMouse(globalPosition);
}
void FieldAutocompleteInner::clearSel(bool hidden) {
void FieldAutocomplete::Inner::clearSel(bool hidden) {
_overDelete = false;
_mouseSelection = false;
_lastMousePosition = std::nullopt;
@@ -868,7 +969,7 @@ void FieldAutocompleteInner::clearSel(bool hidden) {
}
}
bool FieldAutocompleteInner::moveSel(int key) {
bool FieldAutocomplete::Inner::moveSel(int key) {
_mouseSelection = false;
_lastMousePosition = std::nullopt;
@@ -903,12 +1004,12 @@ bool FieldAutocompleteInner::moveSel(int key) {
return true;
}
bool FieldAutocompleteInner::chooseSelected(
bool FieldAutocomplete::Inner::chooseSelected(
FieldAutocomplete::ChooseMethod method) const {
return chooseAtIndex(method, _sel);
}
bool FieldAutocompleteInner::chooseAtIndex(
bool FieldAutocomplete::Inner::chooseAtIndex(
FieldAutocomplete::ChooseMethod method,
int index,
Api::SendOptions options) const {
@@ -955,11 +1056,11 @@ bool FieldAutocompleteInner::chooseAtIndex(
return false;
}
void FieldAutocompleteInner::setRecentInlineBotsInRows(int32 bots) {
void FieldAutocomplete::Inner::setRecentInlineBotsInRows(int32 bots) {
_recentInlineBotsInRows = bots;
}
void FieldAutocompleteInner::mousePressEvent(QMouseEvent *e) {
void FieldAutocomplete::Inner::mousePressEvent(QMouseEvent *e) {
selectByMouse(e->globalPos());
if (e->button() == Qt::LeftButton) {
if (_overDelete && _sel >= 0 && _sel < (_mrows->empty() ? _hrows->size() : _recentInlineBotsInRows)) {
@@ -999,7 +1100,7 @@ void FieldAutocompleteInner::mousePressEvent(QMouseEvent *e) {
}
}
void FieldAutocompleteInner::mouseReleaseEvent(QMouseEvent *e) {
void FieldAutocomplete::Inner::mouseReleaseEvent(QMouseEvent *e) {
_previewTimer.cancel();
int32 pressed = _down;
@@ -1017,12 +1118,14 @@ void FieldAutocompleteInner::mouseReleaseEvent(QMouseEvent *e) {
chooseSelected(FieldAutocomplete::ChooseMethod::ByClick);
}
void FieldAutocompleteInner::contextMenuEvent(QContextMenuEvent *e) {
void FieldAutocomplete::Inner::contextMenuEvent(QContextMenuEvent *e) {
if (_sel < 0 || _srows->empty() || _down >= 0) {
return;
}
const auto index = _sel;
const auto type = SendMenu::Type::Scheduled;
const auto type = _sendMenuType
? _sendMenuType()
: SendMenu::Type::Disabled;
const auto method = FieldAutocomplete::ChooseMethod::ByClick;
_menu = base::make_unique_q<Ui::PopupMenu>(this);
@@ -1031,7 +1134,7 @@ void FieldAutocompleteInner::contextMenuEvent(QContextMenuEvent *e) {
};
SendMenu::FillSendMenu(
_menu,
[&] { return type; },
type,
SendMenu::DefaultSilentCallback(send),
SendMenu::DefaultScheduleCallback(this, type, send));
@@ -1040,11 +1143,11 @@ void FieldAutocompleteInner::contextMenuEvent(QContextMenuEvent *e) {
}
}
void FieldAutocompleteInner::enterEventHook(QEvent *e) {
void FieldAutocomplete::Inner::enterEventHook(QEvent *e) {
setMouseTracking(true);
}
void FieldAutocompleteInner::leaveEventHook(QEvent *e) {
void FieldAutocomplete::Inner::leaveEventHook(QEvent *e) {
setMouseTracking(false);
if (_mouseSelection) {
setSel(-1);
@@ -1053,7 +1156,7 @@ void FieldAutocompleteInner::leaveEventHook(QEvent *e) {
}
}
void FieldAutocompleteInner::updateSelectedRow() {
void FieldAutocomplete::Inner::updateSelectedRow() {
if (_sel >= 0) {
if (_srows->empty()) {
update(0, _sel * st::mentionHeight, width(), st::mentionHeight);
@@ -1064,7 +1167,7 @@ void FieldAutocompleteInner::updateSelectedRow() {
}
}
void FieldAutocompleteInner::setSel(int sel, bool scroll) {
void FieldAutocomplete::Inner::setSel(int sel, bool scroll) {
updateSelectedRow();
_sel = sel;
updateSelectedRow();
@@ -1084,13 +1187,13 @@ void FieldAutocompleteInner::setSel(int sel, bool scroll) {
}
}
void FieldAutocompleteInner::rowsUpdated() {
void FieldAutocomplete::Inner::rowsUpdated() {
if (_srows->empty()) {
_stickersLifetime.destroy();
}
}
auto FieldAutocompleteInner::getLottieRenderer()
auto FieldAutocomplete::Inner::getLottieRenderer()
-> std::shared_ptr<Lottie::FrameRenderer> {
if (auto result = _lottieRenderer.lock()) {
return result;
@@ -1100,7 +1203,7 @@ auto FieldAutocompleteInner::getLottieRenderer()
return result;
}
void FieldAutocompleteInner::setupLottie(StickerSuggestion &suggestion) {
void FieldAutocomplete::Inner::setupLottie(StickerSuggestion &suggestion) {
const auto document = suggestion.document;
suggestion.animated = ChatHelpers::LottiePlayerFromDocument(
suggestion.documentMedia.get(),
@@ -1115,13 +1218,13 @@ void FieldAutocompleteInner::setupLottie(StickerSuggestion &suggestion) {
}, _stickersLifetime);
}
QSize FieldAutocompleteInner::stickerBoundingBox() const {
QSize FieldAutocomplete::Inner::stickerBoundingBox() const {
return QSize(
st::stickerPanSize.width() - st::buttonRadius * 2,
st::stickerPanSize.height() - st::buttonRadius * 2);
}
void FieldAutocompleteInner::repaintSticker(
void FieldAutocomplete::Inner::repaintSticker(
not_null<DocumentData*> document) {
const auto i = ranges::find(
*_srows,
@@ -1140,7 +1243,7 @@ void FieldAutocompleteInner::repaintSticker(
st::stickerPanSize.height());
}
void FieldAutocompleteInner::selectByMouse(QPoint globalPosition) {
void FieldAutocomplete::Inner::selectByMouse(QPoint globalPosition) {
_mouseSelection = true;
_lastMousePosition = globalPosition;
const auto mouse = mapFromGlobal(globalPosition);
@@ -1186,7 +1289,7 @@ void FieldAutocompleteInner::selectByMouse(QPoint globalPosition) {
}
}
void FieldAutocompleteInner::onParentGeometryChanged() {
void FieldAutocomplete::Inner::onParentGeometryChanged() {
const auto globalPosition = QCursor::pos();
if (rect().contains(mapFromGlobal(globalPosition))) {
setMouseTracking(true);
@@ -1196,7 +1299,7 @@ void FieldAutocompleteInner::onParentGeometryChanged() {
}
}
void FieldAutocompleteInner::showPreview() {
void FieldAutocomplete::Inner::showPreview() {
if (_down >= 0 && _down < _srows->size()) {
if (const auto w = App::wnd()) {
w->showMediaPreview(
@@ -1207,29 +1310,32 @@ void FieldAutocompleteInner::showPreview() {
}
}
auto FieldAutocompleteInner::mentionChosen() const
void FieldAutocomplete::Inner::setSendMenuType(
Fn<SendMenu::Type()> &&callback) {
_sendMenuType = std::move(callback);
}
auto FieldAutocomplete::Inner::mentionChosen() const
-> rpl::producer<FieldAutocomplete::MentionChosen> {
return _mentionChosen.events();
}
auto FieldAutocompleteInner::hashtagChosen() const
auto FieldAutocomplete::Inner::hashtagChosen() const
-> rpl::producer<FieldAutocomplete::HashtagChosen> {
return _hashtagChosen.events();
}
auto FieldAutocompleteInner::botCommandChosen() const
auto FieldAutocomplete::Inner::botCommandChosen() const
-> rpl::producer<FieldAutocomplete::BotCommandChosen> {
return _botCommandChosen.events();
}
auto FieldAutocompleteInner::stickerChosen() const
auto FieldAutocomplete::Inner::stickerChosen() const
-> rpl::producer<FieldAutocomplete::StickerChosen> {
return _stickerChosen.events();
}
auto FieldAutocompleteInner::scrollToRequested() const
auto FieldAutocomplete::Inner::scrollToRequested() const
-> rpl::producer<ScrollTo> {
return _scrollToRequested.events();
}
} // namespace internal

View File

@@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui {
class PopupMenu;
class ScrollArea;
class InputField;
} // namespace Ui
namespace Lottie {
@@ -32,42 +33,20 @@ class DocumentMedia;
class CloudImageView;
} // namespace Data
namespace internal {
namespace SendMenu {
enum class Type;
} // namespace SendMenu
struct StickerSuggestion {
not_null<DocumentData*> document;
std::shared_ptr<Data::DocumentMedia> documentMedia;
std::unique_ptr<Lottie::SinglePlayer> animated;
};
struct MentionRow {
not_null<UserData*> user;
std::shared_ptr<Data::CloudImageView> userpic;
};
struct BotCommandRow {
not_null<UserData*> user;
not_null<const BotCommand*> command;
std::shared_ptr<Data::CloudImageView> userpic;
};
using HashtagRows = std::vector<QString>;
using BotCommandRows = std::vector<BotCommandRow>;
using StickerRows = std::vector<StickerSuggestion>;
using MentionRows = std::vector<MentionRow>;
class FieldAutocompleteInner;
} // namespace internal
class FieldAutocomplete final : public Ui::RpWidget {
public:
FieldAutocomplete(
QWidget *parent,
not_null<Window::SessionController*> controller);
~FieldAutocomplete();
[[nodiscard]] not_null<Window::SessionController*> controller() const;
bool clearFilteredBotCommands();
void showFiltered(
not_null<PeerData*> peer,
@@ -124,6 +103,7 @@ public:
void setModerateKeyActivateCallback(Fn<bool(int)> callback) {
_moderateKeyActivateCallback = std::move(callback);
}
void setSendMenuType(Fn<SendMenu::Type()> &&callback);
void hideFast();
@@ -140,29 +120,54 @@ protected:
void paintEvent(QPaintEvent *e) override;
private:
class Inner;
friend class Inner;
struct StickerSuggestion {
not_null<DocumentData*> document;
std::shared_ptr<Data::DocumentMedia> documentMedia;
std::unique_ptr<Lottie::SinglePlayer> animated;
};
struct MentionRow {
not_null<UserData*> user;
std::shared_ptr<Data::CloudImageView> userpic;
};
struct BotCommandRow {
not_null<UserData*> user;
not_null<const BotCommand*> command;
std::shared_ptr<Data::CloudImageView> userpic;
};
using HashtagRows = std::vector<QString>;
using BotCommandRows = std::vector<BotCommandRow>;
using StickerRows = std::vector<StickerSuggestion>;
using MentionRows = std::vector<MentionRow>;
void animationCallback();
void hideFinish();
void updateFiltered(bool resetScroll = false);
void recount(bool resetScroll = false);
internal::StickerRows getStickerSuggestions();
StickerRows getStickerSuggestions();
const not_null<Window::SessionController*> _controller;
QPixmap _cache;
internal::MentionRows _mrows;
internal::HashtagRows _hrows;
internal::BotCommandRows _brows;
internal::StickerRows _srows;
MentionRows _mrows;
HashtagRows _hrows;
BotCommandRows _brows;
StickerRows _srows;
void rowsUpdated(
internal::MentionRows &&mrows,
internal::HashtagRows &&hrows,
internal::BotCommandRows &&brows,
internal::StickerRows &&srows,
MentionRows &&mrows,
HashtagRows &&hrows,
BotCommandRows &&brows,
StickerRows &&srows,
bool resetScroll);
object_ptr<Ui::ScrollArea> _scroll;
QPointer<internal::FieldAutocompleteInner> _inner;
QPointer<Inner> _inner;
ChatData *_chat = nullptr;
UserData *_user = nullptr;
@@ -186,100 +191,4 @@ private:
Fn<bool(int)> _moderateKeyActivateCallback;
friend class internal::FieldAutocompleteInner;
};
namespace internal {
class FieldAutocompleteInner final
: public Ui::RpWidget
, private base::Subscriber {
public:
struct ScrollTo {
int top;
int bottom;
};
FieldAutocompleteInner(
not_null<Window::SessionController*> controller,
not_null<FieldAutocomplete*> parent,
not_null<MentionRows*> mrows,
not_null<HashtagRows*> hrows,
not_null<BotCommandRows*> brows,
not_null<StickerRows*> srows);
void clearSel(bool hidden = false);
bool moveSel(int key);
bool chooseSelected(FieldAutocomplete::ChooseMethod method) const;
bool chooseAtIndex(
FieldAutocomplete::ChooseMethod method,
int index,
Api::SendOptions options = Api::SendOptions()) const;
void setRecentInlineBotsInRows(int32 bots);
void rowsUpdated();
rpl::producer<FieldAutocomplete::MentionChosen> mentionChosen() const;
rpl::producer<FieldAutocomplete::HashtagChosen> hashtagChosen() const;
rpl::producer<FieldAutocomplete::BotCommandChosen>
botCommandChosen() const;
rpl::producer<FieldAutocomplete::StickerChosen> stickerChosen() const;
rpl::producer<ScrollTo> scrollToRequested() const;
void onParentGeometryChanged();
private:
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void enterEventHook(QEvent *e) override;
void leaveEventHook(QEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void contextMenuEvent(QContextMenuEvent *e) override;
void updateSelectedRow();
void setSel(int sel, bool scroll = false);
void showPreview();
void selectByMouse(QPoint global);
QSize stickerBoundingBox() const;
void setupLottie(StickerSuggestion &suggestion);
void repaintSticker(not_null<DocumentData*> document);
std::shared_ptr<Lottie::FrameRenderer> getLottieRenderer();
const not_null<Window::SessionController*> _controller;
const not_null<FieldAutocomplete*> _parent;
const not_null<MentionRows*> _mrows;
const not_null<HashtagRows*> _hrows;
const not_null<BotCommandRows*> _brows;
const not_null<StickerRows*> _srows;
rpl::lifetime _stickersLifetime;
std::weak_ptr<Lottie::FrameRenderer> _lottieRenderer;
base::unique_qptr<Ui::PopupMenu> _menu;
int _stickersPerRow = 1;
int _recentInlineBotsInRows = 0;
int _sel = -1;
int _down = -1;
std::optional<QPoint> _lastMousePosition;
bool _mouseSelection = false;
bool _overDelete = false;
bool _previewShown = false;
rpl::event_stream<FieldAutocomplete::MentionChosen> _mentionChosen;
rpl::event_stream<FieldAutocomplete::HashtagChosen> _hashtagChosen;
rpl::event_stream<FieldAutocomplete::BotCommandChosen> _botCommandChosen;
rpl::event_stream<FieldAutocomplete::StickerChosen> _stickerChosen;
rpl::event_stream<ScrollTo> _scrollToRequested;
base::Timer _previewTimer;
};
} // namespace internal

View File

@@ -377,7 +377,7 @@ void GifsListWidget::fillContextMenu(
};
SendMenu::FillSendMenu(
menu,
[&] { return type; },
type,
SendMenu::DefaultSilentCallback(send),
SendMenu::DefaultScheduleCallback(this, type, send));

View File

@@ -29,7 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_history.h"
#include "styles/style_chat.h"
#include <QtCore/QMimeData>
#include <QtCore/QStack>

View File

@@ -40,13 +40,13 @@ Fn<void()> DefaultScheduleCallback(
FillMenuResult FillSendMenu(
not_null<Ui::PopupMenu*> menu,
Fn<Type()> type,
Type type,
Fn<void()> silent,
Fn<void()> schedule) {
if (!silent && !schedule) {
return FillMenuResult::None;
}
const auto now = type();
const auto now = type;
if (now == Type::Disabled
|| (!silent && now == Type::SilentOnly)) {
return FillMenuResult::None;
@@ -76,7 +76,7 @@ void SetupMenuAndShortcuts(
const auto menu = std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
const auto showMenu = [=] {
*menu = base::make_unique_q<Ui::PopupMenu>(button);
const auto result = FillSendMenu(*menu, type, silent, schedule);
const auto result = FillSendMenu(*menu, type(), silent, schedule);
const auto success = (result == FillMenuResult::Success);
if (success) {
(*menu)->popup(QCursor::pos());

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