Compare commits

...

490 Commits

Author SHA1 Message Date
John Preston
dab107cf90 Version 5.5.3.
- Fix custom emoji sending.
- Add mention link QR code sharing.
- Fix sending files from network drives. (Windows)
2024-09-10 15:07:14 +04:00
23rd
d1d1aa3d21 Moved premium gradient in box for share of QR code to first place. 2024-09-10 13:51:23 +03:00
23rd
d0536cc31f Replaced boxes for QR code of invite links with box for share QR code. 2024-09-10 13:51:23 +03:00
23rd
c47f5e9995 Added ability to create box for share QR code without peer. 2024-09-10 13:51:23 +03:00
23rd
0916836ff9 Added ability to provide description and custom link to FillPeerQrBox. 2024-09-10 13:51:23 +03:00
John Preston
5dd9ff1062 Accept only CF_HDROP for uri-list mime.
Additional types lead to such problem: some programs, like JetBrains
IDEs, like PyCharm, copy "file://[ip-address]/file" as an URI in
uri-list, that way you can't paste it in the messenger, because it
will make a request to that address and reveal clients IP address.
2024-09-10 14:19:37 +04:00
John Preston
d1e3b9f15d Revert "Check for local URLs more strictly."
This reverts commit c3fda41224.
2024-09-10 14:19:37 +04:00
John Preston
ca3c179b75 Use full available width for text in some places.
Fixes #28384.
2024-09-10 14:19:37 +04:00
John Preston
c2d5924508 Fix build with MSVC. 2024-09-10 14:19:37 +04:00
John Preston
016d0395c3 Fix custom emoji sending. 2024-09-10 14:17:32 +04:00
23rd
925c9239bd Added ability to share QR code from channels. 2024-09-10 11:34:55 +03:00
23rd
fdcbe3cf3a Fixed width of username label with right button in profile section. 2024-09-10 11:08:42 +03:00
23rd
f6b9cc5ce1 Improved padding in box for share QR box on different scales. 2024-09-10 10:56:02 +03:00
23rd
8c915e6dc3 Renamed FillProfileQrBox to FillPeerQrBox. 2024-09-10 03:26:15 +03:00
23rd
1db426da2e Added ability to choose quality in box for share of QR code. 2024-09-10 03:26:15 +03:00
23rd
d9be363962 Added ability to hide userpic from box for share of QR code. 2024-09-10 02:00:26 +03:00
23rd
88daa37e34 Added ability to generate QR code independently from ui scale. 2024-09-10 02:00:26 +03:00
23rd
931fa01337 Added premium gradient to box for share of QR code. 2024-09-10 02:00:26 +03:00
23rd
8e1595eb29 Adapted display of longest usernames in box for share of QR code. 2024-09-10 02:00:26 +03:00
23rd
29e97232d8 Added initial ability to share QR code from user profile. 2024-09-10 02:00:26 +03:00
John Preston
f05191e668 Version 5.5.2: Fix build. 2024-09-09 21:30:15 +04:00
John Preston
1ba189e59d Version 5.5.2.
- Support two bottom buttons in web apps.
- Fix text layout outside of the message bubble glitch.
- Don't stop video when dragging media viewer in window mode.
2024-09-09 21:12:33 +04:00
23rd
c40ca70aa6 Added date of admin promotional to EditAdminBox. 2024-09-09 17:20:52 +03:00
23rd
521f991167 Replaced float labels with text in dividers in EditAdminBox. 2024-09-09 17:20:52 +03:00
23rd
edf1417bbb Added date of restriction to EditRestrictedBox. 2024-09-09 17:20:52 +03:00
23rd
686e9643ad Replaced channel participant parsing with modern way in admin log. 2024-09-09 17:20:52 +03:00
23rd
975460d268 Added api support for dates of chat participant data. 2024-09-09 17:20:52 +03:00
23rd
6b0c606d25 Switched type of subscription date from Qt to TimeId. 2024-09-09 17:20:52 +03:00
23rd
93ff0bdcff Slightly improved style of box for sending GIF with caption. 2024-09-09 17:20:52 +03:00
23rd
bf9d90ca4e Fixed emoji display in header of link for dialog filters. 2024-09-09 17:20:52 +03:00
23rd
d6e5e1e8f7 Added handle of flood errors in request of join to chatlist. 2024-09-09 17:20:52 +03:00
23rd
d3ae2ef9ea Synced local English phrases with server. 2024-09-09 17:20:52 +03:00
John Preston
40b0854704 Don't pause video on viewer drag. 2024-09-09 17:54:16 +04:00
John Preston
9aec6b6496 Set min width for field collapsed quotes. 2024-09-09 17:24:15 +04:00
John Preston
d01f977960 Don't offer hello-sticker to user you've blocked. 2024-09-09 16:42:02 +04:00
John Preston
1444009ee2 Update submodules. 2024-09-09 14:58:40 +04:00
John Preston
14ee9bee26 Fix quotes starting with custom urls. 2024-09-09 14:58:40 +04:00
Ilya Fedin
93587ddc3c Allow scale preview in separate window on Wayland 2024-09-09 14:49:44 +04:00
John Preston
0c4d03477e Fix text layout in some cases. 2024-09-09 14:28:37 +04:00
John Preston
a35092f012 Support second button in web apps. 2024-09-09 13:29:00 +04:00
John Preston
49ee7ee52b Version 5.5.1: Update cmake_helpers. 2024-09-07 00:25:47 +04:00
John Preston
52c77a1970 Version 5.5.1.
- Fix crash in peer short info box.
2024-09-06 23:30:32 +04:00
John Preston
e4269ae7fb Fix crash in PeerShortInfoBox. 2024-09-06 23:28:43 +04:00
John Preston
bd6011c524 Version 5.5.
- Star Giveaways.
- Swipe-to-Reply.
- Audio device selection in one-on-one calls.
- Text selection in collapsed / expanded quotes.
2024-09-06 21:57:47 +04:00
23rd
46cb3ec103 Added box for boosts with credits. 2024-09-06 21:57:47 +04:00
23rd
0241129948 Added support of admin log filter for extended subscriptions. 2024-09-06 21:57:47 +04:00
23rd
e44aca06cb Added support of admin log event of extended subscriptions. 2024-09-06 21:57:47 +04:00
23rd
19d386f977 Added support of credits to giveaway info results. 2024-09-06 21:57:47 +04:00
John Preston
a67fdda913 Fix the Release build for macOS. 2024-09-06 21:57:47 +04:00
John Preston
5286c7b1c3 Allow selecting text in collapsed quotes. 2024-09-06 21:57:47 +04:00
23rd
d9d96d0a6f Fixed display of custom badge in selected messages for giveaways. 2024-09-06 21:57:47 +04:00
23rd
13353bb615 Improved phrases in service message for giveaway results with credits. 2024-09-06 21:57:47 +04:00
23rd
d78348fd16 Fixed crash in box for giveaway create when winners number is constant. 2024-09-06 21:57:46 +04:00
23rd
1e8e660133 Improved phrases in top bar from box for giveaway creation with credits. 2024-09-06 21:57:46 +04:00
23rd
5196982c98 Improved phrases in box for information of giveaway with credits. 2024-09-06 21:57:46 +04:00
23rd
99f857fbf6 Improved phrases in service message for started giveaway with credits. 2024-09-06 21:57:46 +04:00
23rd
0982aa166a Added support of prepaid giveaway with credits. 2024-09-06 21:57:46 +04:00
23rd
3ae9f86097 Slightly improved display of credits in boosts from statistics list. 2024-09-06 21:57:46 +04:00
23rd
9efd9b0d68 Slightly improved timestamp parsing in Api::Boosts. 2024-09-06 21:57:46 +04:00
John Preston
267a73f355 Update API scheme on layer 187. 2024-09-06 21:57:46 +04:00
John Preston
437d8ea890 Fix build with MSVC. 2024-09-06 21:57:46 +04:00
23rd
7ed92ec402 Added credits icon to boosts in statistics list. 2024-09-06 21:57:46 +04:00
23rd
678d9ffbf9 Added support of giveaway prize action messages to export to JSON. 2024-09-06 21:57:46 +04:00
23rd
bc4b427ed1 Added support of giveaway prize action messages to export to HTML. 2024-09-06 21:57:46 +04:00
23rd
36141a9df9 Added support of giveaway results messages to export to JSON. 2024-09-06 21:57:46 +04:00
23rd
d68ba75457 Improved process of giveaway messages for export to JSON. 2024-09-06 21:57:46 +04:00
23rd
00ad32c5f4 Added support of giveaway results messages to export to HTML. 2024-09-06 21:57:46 +04:00
23rd
064bab60ff Improved process of giveaway messages for export to HTML. 2024-09-06 21:57:46 +04:00
23rd
5b146217c0 Added support for credits in messages of prize in giveaways. 2024-09-06 21:57:46 +04:00
23rd
202c81b2e5 Added support for credits in messages for starting and ending giveaways. 2024-09-06 21:57:46 +04:00
23rd
4520480604 Added support of credits giveaway to ReceiptCreditsBox. 2024-09-06 21:57:46 +04:00
23rd
aea87bb5cb United buttons for premium giveaway and premium gifts to single button. 2024-09-06 21:57:46 +04:00
23rd
19492f7e7b Improved prize description for credits in box for giveaway creation. 2024-09-06 21:57:46 +04:00
23rd
51030e3c45 Added list of options to box for giveaway creation with credits. 2024-09-06 21:57:46 +04:00
23rd
e6b8b4be18 Added initial payment support for credits giveaway. 2024-09-06 21:36:03 +04:00
23rd
6ac13b7f80 Added button for credits giveaway to box for giveaway creation. 2024-09-06 21:36:03 +04:00
23rd
7e5e6003a9 Added initial api support for credits giveaway options. 2024-09-06 21:36:03 +04:00
23rd
f445440995 Added initial data structure for credits giveaway options. 2024-09-06 21:36:03 +04:00
John Preston
d81547f091 Support cloud-saved paid reaction privacy. 2024-09-06 21:36:03 +04:00
John Preston
2b185d491b Update API scheme to layer 187. 2024-09-06 21:36:03 +04:00
John Preston
ca47440950 Don't treat .gif as "small image". 2024-09-06 21:07:17 +04:00
John Preston
5e32602f4a Add elastic overscroll to swipe-to-reply. 2024-09-06 21:07:02 +04:00
23rd
1f4516028c Fixed desync of repaint of userpics and messages while swipe-on-reply. 2024-09-06 19:52:29 +03:00
23rd
7f29d269a3 Changed swipe-on-reply detection only when scroll has began. 2024-09-06 17:11:16 +03:00
23rd
62c3374911 Disabled swipe-to-reply for channels. 2024-09-06 12:04:42 +03:00
23rd
2116e04af5 Allowed to swipe-to-reply only with started initial of touches. 2024-09-06 11:56:21 +03:00
John Preston
a97d5e80c7 Fix custom reaction as a quick one. 2024-09-05 19:13:52 +04:00
John Preston
b5098038d0 Add two-year ttl time for account. 2024-09-05 17:05:09 +04:00
John Preston
6fce718252 Add jump-to-end button to chat preview. 2024-09-05 14:50:38 +04:00
John Preston
40cf96202d Add 1.5 years account ttl value. 2024-09-05 14:11:41 +04:00
John Preston
c18e59218e Show internal list of apps as Stars Examples. 2024-09-05 13:14:07 +04:00
John Preston
216865a20d Fix file albums with inline keyboard buttons. 2024-09-05 12:01:43 +04:00
John Preston
6c5036ee8d Fix typo in swipe-to-reply through QWheelEvent. 2024-09-05 11:52:25 +04:00
Viliansh
dc2f59ca24 Added org.telegram as developer_id in the flatpak metainfo.xml
Co-authored-by: ilya-fedin <fedin-ilja2010@ya.ru>
2024-09-05 09:47:43 +02:00
Viliansh
6f6457137e removed update_contact from flatpak metainfo.xml 2024-09-05 09:47:43 +02:00
Viliansh
bc5cb6e2a2 Changed dev name in org.telegram.desktop.metainfo.xml
In flathub, and it's front-ends like KDE's Discover or GNOME Software, Telegram shows "By John Preston", and some users were hesitant to install it afraid that was "fake", so i changed it to Telegram, this would also make it consistent with snap, thanks!
2024-09-05 09:47:43 +02:00
John Preston
16825fff41 Use QWheelEvent::inverted() in swipe gesture. 2024-09-05 11:30:37 +04:00
John Preston
5024f1db8c Beta version 5.4.6.
- Add Swipe-To-Reply for modern touchpads and touchscreens.
- Add text selection in collapsed and expanded blockquotes.
- Fix text rendering in 100% interface scale on Windows.
2024-09-04 18:39:16 +04:00
23rd
a60385fc3d Removed QGraphicsOpacityEffect usage from media view overlay widget. 2024-09-04 18:39:16 +04:00
23rd
b20e2c37c1 Fixed build on Qt6. 2024-09-04 18:39:16 +04:00
John Preston
acd40cbeb6 Apply invert_media flag on message send finish. 2024-09-04 18:32:48 +04:00
23rd
6a45a862dd Removed wheel events from scale slider in section of main settings. 2024-09-04 16:01:55 +02:00
23rd
5bd45e9a20 Fixed updating of left userpic with offset from swipe-on-reply. 2024-09-04 16:01:55 +02:00
23rd
52e42f23ab Improved animation speed on release of swipe-on-reply with various x. 2024-09-04 16:01:54 +02:00
23rd
96b7755cde Fixed updating of message on bounce animation of swipe-on-reply icon. 2024-09-04 16:01:54 +02:00
23rd
c589ee1ca5 Fixed overlap of reply icon on left swipe of message with right action. 2024-09-04 16:01:54 +02:00
23rd
18c9ee093b Fixed unwanted top offset of dialogs widget when float player opened. 2024-09-04 16:01:54 +02:00
John Preston
b82fa3112c Improve touchscreen swipt-to-reply. 2024-09-04 16:01:20 +02:00
John Preston
8d0f66d562 Fix touchscreen history scrolling. 2024-09-04 14:06:11 +02:00
John Preston
20a5e0ba73 Fix controls layout after adding a bot to a group.
Fixes https://bugs.telegram.org/c/19451
2024-09-04 14:56:50 +04:00
John Preston
5a2667c71e Fix reply previews to blockquotes / codeblocks. 2024-09-04 14:45:35 +04:00
John Preston
1f4a8d7eb6 Fix build with MSVC. 2024-09-04 14:45:07 +04:00
John Preston
4430bd0328 Improve lottie icon layout in group calls. 2024-09-04 14:14:12 +04:00
John Preston
ab2e7f4c03 Fix media viewer create on non-primary screen. 2024-09-04 14:14:12 +04:00
John Preston
54e5c06b4d Revert updated Harfbuzz-NG in Qt 5.15.15.
This fixes the regression with text rendering in 100% scale.

Fixes #28340.
2024-09-04 14:14:12 +04:00
23rd
add5a6a0be Added debug util to ensure end of life of objects. 2024-09-04 14:14:12 +04:00
23rd
89c2ba4293 Weakened gesture orientation check within swipe-to-reply. 2024-09-04 14:14:12 +04:00
23rd
dd100fb709 Fixed back gesture responsiveness for swipe-to-reply on macOS. 2024-09-04 14:14:12 +04:00
John Preston
e8dd2b9e7b Use only integer translations in reply swipe. 2024-09-04 14:14:12 +04:00
23rd
71e3cd227c Added initial swipe-to-reply to section for replies. 2024-09-04 14:14:12 +04:00
23rd
1648c31a22 Moved out swipe-to-reply setup to inner method in HistoryInner. 2024-09-04 14:14:12 +04:00
23rd
f8c820f319 Fixed swipe-to-reply on macOS. 2024-09-04 14:14:12 +04:00
John Preston
300f35e78f Implement both touch and wheel swipe-to-reply. 2024-09-04 14:14:12 +04:00
23rd
2aa5849997 Improved horizontal animation for reply icon on left swipe. 2024-09-04 14:14:12 +04:00
23rd
fb1b845211 Improved process of message repaint on swipe to reply. 2024-09-04 14:14:11 +04:00
23rd
3d2af9db8e Improved distance of reply icon on left swipe. 2024-09-04 14:14:11 +04:00
23rd
6129e5a1cf Added bounce animation on finish of replying with left swipe. 2024-09-04 14:14:11 +04:00
23rd
7f70ee1227 Added initial ability to reply with left swipe. 2024-09-04 14:14:11 +04:00
23rd
c9f7da6e82 Added ability to paint icons in center of QRectF. 2024-09-04 10:33:28 +03:00
23rd
f956c0f227 Added experimental option to disable touch bar on macOS. 2024-09-04 10:12:08 +03:00
23rd
df935e0477 Improved code style of gifMaxStatusWidth static function. 2024-09-04 10:11:57 +03:00
23rd
841f1afe1e Improved subtitle space in permissions and restrictions edit boxes. 2024-09-04 10:11:54 +03:00
23rd
fb8b88557e Added ability to kick participants from section of admin log. 2024-09-04 10:11:49 +03:00
23rd
2b502b22b9 Replaced PeerData::generateUserpicImage with static function. 2024-09-04 10:11:44 +03:00
23rd
5ac80d2655 Fixed text clipping at bottom in settings section for cloud password. 2024-09-04 10:11:41 +03:00
23rd
8aa7499e63 Fixed width of stats PointDetailsWidget for charts with currency. 2024-09-04 10:11:36 +03:00
23rd
8cd5e51982 Added missed handler of server error when try to reset cloud password. 2024-09-04 10:11:31 +03:00
23rd
e5c2133446 Disabled Qt build on Windows without successful applied patches. 2024-09-04 10:11:17 +03:00
John Preston
3dccdf2f05 Beta version 5.4.5.
- Fix possible crash in text rendering.
2024-09-01 10:19:39 +04:00
John Preston
8a708c6655 Update Qt to 5.15.15 on Windows. 2024-09-01 10:19:39 +04:00
Ilya Fedin
9e1d9eee4b Fix snap build 2024-08-31 20:09:36 +02:00
Ilya Fedin
f30aabc365 Update Qt 6.7.2 -> 6.8.0 2024-08-31 19:54:58 +02:00
John Preston
a5546d016f Fix possible crash in long-word texts. 2024-08-31 21:48:52 +04:00
John Preston
f79d70d112 Use Ui::Text::String in Ui::RoundButton. 2024-08-31 21:48:52 +04:00
John Preston
ec28f258fb Use full bubble width in message text rendering.
Fixes #28331.
2024-08-31 21:48:52 +04:00
John Preston
08f3a6fb40 Fix local group sent-as display. 2024-08-31 21:48:52 +04:00
John Preston
8823d5256f Fix indentation. 2024-08-31 21:48:52 +04:00
23rd
60e7aa90d2 Added ability to report profile photo from peer info section. 2024-08-31 12:34:50 +03:00
John Preston
71357a9546 Fix archive chats list bidi support. 2024-08-29 17:48:06 +04:00
John Preston
a5b06e9c56 Fix possible crash in text elision. 2024-08-29 17:41:15 +04:00
23rd
0f94419f6d Improved fix of crash in video messages playback.
Regression was introduced in ad3e447f08.
2024-08-29 17:37:55 +04:00
John Preston
94e7aabea5 Fix spaces after emoji in text rendering. 2024-08-29 17:19:28 +04:00
John Preston
f6c816cafe Beta version 5.4.4.
- Fix wrong layout and crashes in text shaping.
- Fix crashes in voice / video messages playback.
2024-08-29 13:01:06 +04:00
John Preston
4cf160e8dc Fix UB in text shaping. 2024-08-29 12:54:52 +04:00
John Preston
9252be5e8c Fix crash in video messages playback.
Regression was introduced in ad3e447f08.
2024-08-29 12:13:51 +04:00
John Preston
ed342eea64 Beta version 5.4.3. (Windows only)
- Fix working on Windows 7.
2024-08-29 10:32:53 +04:00
John Preston
e6405bc455 Beta version 5.4.2.
- Select audio devices from one-on-one call window.
- Bug fixes and other minor improvements.
- New text layout testing.
2024-08-28 21:50:05 +04:00
John Preston
fed09461ce Fix spaces after newline rendering. 2024-08-28 19:16:55 +04:00
John Preston
6e1ddef4fe Fix strings for group profile colors. 2024-08-28 17:45:29 +04:00
John Preston
76be4a3eb9 Fix build on Windows. 2024-08-28 17:45:18 +04:00
John Preston
997a9e2fe3 Fix text elision under spoiler. 2024-08-28 17:29:43 +04:00
23rd
03790f3da0 Removed include directive for ui_utility from rp_widget header. 2024-08-28 15:15:58 +03:00
23rd
e46a703c7d Removed include directive for ui/integration from ui_utility header. 2024-08-28 14:39:05 +03:00
23rd
ae17acdfd4 Removed include directive for ui_utility from rp_widget header. 2024-08-28 14:38:33 +03:00
23rd
2422c9ce9e Moved out Ui::MakeWeak to separate file. 2024-08-28 14:37:56 +03:00
23rd
7f75d7082a Moved out Ui::CreateChild to separate file. 2024-08-28 14:37:07 +03:00
23rd
4749ab175e Fixed build with Apple clang. 2024-08-28 14:37:07 +03:00
John Preston
e651699e1d Fix thumbnailed document layout. 2024-08-28 14:58:21 +04:00
John Preston
3f4157bab2 Fix crash in unlock with chat in separate window.
Fixes #28306, fixes #28319.
2024-08-28 14:58:21 +04:00
John Preston
a98f559066 Add test_text test app. 2024-08-28 14:58:09 +04:00
John Preston
ffd54c452c Support DirectManipulation in chat preview. 2024-08-28 14:58:02 +04:00
John Preston
61424eeab9 Fix build with Qt 5. 2024-08-28 14:57:49 +04:00
John Preston
c131d6637d Don't force LTR direction on texts. 2024-08-28 14:57:42 +04:00
John Preston
24b0b33f1d Wrap names in LRM/RLM for correct layout. 2024-08-28 14:55:41 +04:00
23rd
675198d361 Fixed gradient in Ui::Premium::BubbleWidget with large ui scale. 2024-08-28 12:38:07 +03:00
23rd
ed667a42ad Moved out MainWidget::clearBotStartToken to static function. 2024-08-28 09:49:53 +03:00
23rd
920484d540 Fixed update of submit way in all opened windows. 2024-08-28 09:32:39 +03:00
23rd
07c5e6542b Replaced Info::Controller with navigation in box for giveaway creation. 2024-08-28 09:10:10 +03:00
23rd
6a43f2e508 Fixed display of round edges in box for giveaway creation. 2024-08-28 09:06:44 +03:00
23rd
ad3e447f08 Added ability to player to go to message for songs from another session. 2024-08-28 08:50:28 +03:00
23rd
1840da1d68 Moved out creation of button for paging of stats lists to single place. 2024-08-27 18:48:19 +03:00
23rd
c82b86cea3 Added ability to convert scale float values. 2024-08-27 18:48:19 +03:00
23rd
0fb383c466 Added ability to block bot from moderate box. 2024-08-27 18:27:15 +03:00
23rd
69fc2f48bf Removed unused include directives from MainWidget. 2024-08-27 18:27:15 +03:00
23rd
7c604fc86a Added ability to send GIF with caption. 2024-08-27 18:27:15 +03:00
23rd
ec7fbb8952 Added ability to provide text with tags when send existing document. 2024-08-22 17:10:17 +03:00
23rd
679350e23d Removed unused simple sendExistingDocument methods from sections. 2024-08-22 17:10:12 +03:00
23rd
f0209c9d6e Removed unused MainWidget::sendExistingDocument. 2024-08-22 17:10:06 +03:00
23rd
5020aec6ec Moved out AddEmojiToggleToField to separate file. 2024-08-22 17:08:25 +03:00
23rd
13737577e7 Fixed updating over state in history widget when edit spoiler of media. 2024-08-21 20:00:48 +03:00
23rd
4ee7d46d78 Improved static infinite radial animation in panel of webview bot. 2024-08-21 19:25:58 +03:00
23rd
d143e32022 Fixed loading of credits history list with offset. 2024-08-21 18:26:24 +03:00
23rd
0a0dab74a1 Added ability to rejoin to subscribed channel after left. 2024-08-21 17:46:36 +03:00
23rd
c6ea91e671 Replaced AdminLog::FilterBox with GenericBox. 2024-08-21 17:18:12 +03:00
23rd
8011adb219 Replaced bool with std::optional in AdminLog::FilterValue. 2024-08-21 17:18:12 +03:00
23rd
6ba5d5f16b Removed old AdminLog::FilterBox. 2024-08-21 17:18:12 +03:00
23rd
d5774830d8 Added ability to provide data to Ui::ExpandablePeerListController. 2024-08-21 17:18:12 +03:00
23rd
eb268102fc Moved out functions to create expandable moderate list to separate file. 2024-08-21 17:18:12 +03:00
23rd
b364c4f23a Moved out graphic of button for expandable moderate list to view. 2024-08-21 17:18:12 +03:00
23rd
91b9266a91 Moved out lambdas to create expandable moderate list to functions. 2024-08-21 17:18:12 +03:00
23rd
1e6236a987 Wrapped filter value labels with EditFlagsControl. 2024-08-21 17:18:12 +03:00
23rd
10ebd7e6ef Moved out AdminLog::FilterValue to separate file. 2024-08-21 17:18:12 +03:00
John Preston
6b83c52c7c Improve top senders rebuild.
Fixes #28296.
2024-08-21 10:54:30 +02:00
John Preston
46304c7a2d Fix build in Release. 2024-08-21 09:35:46 +02:00
John Preston
c3fda41224 Check for local URLs more strictly. 2024-08-21 09:35:46 +02:00
John Preston
a4017e930e Add device selectors to one-on-one calls. 2024-08-21 09:35:46 +02:00
John Preston
95bdb925d5 Fix paddings in text messages disabler. 2024-08-20 16:10:27 +02:00
23rd
a26bae70c7 Added Enter shortcut to EditForumTopicBox for confirmation. 2024-08-19 12:53:42 +03:00
23rd
a38dcb6ee5 Improved color of topic icon in TopicIconView. 2024-08-19 12:02:12 +03:00
23rd
eb27c12117 Added icon and name of contact to deletion confirmation box. 2024-08-18 21:53:12 +03:00
23rd
c03fcf9a23 Added icon and name of topic to deletion confirmation box. 2024-08-18 21:44:34 +03:00
23rd
71f83b5993 Made creation of title with userpic more generic. 2024-08-18 21:44:23 +03:00
23rd
fd2d12d6b1 Removed time shift when reschedule history item. 2024-08-18 20:32:21 +03:00
23rd
50f9f36c3d Fixed padding for history entries in channel earn section. 2024-08-18 13:02:39 +03:00
23rd
f650c679e0 Improved text padding in ShowOrPremiumBox. 2024-08-18 12:41:00 +03:00
23rd
8349cb0dd4 Removed currency column from channel earn section when it's empty. 2024-08-18 12:29:56 +03:00
John Preston
2c1788a63a Version 5.4.1.
- Fix crash when sending Star Reaction in comments.
- Fix loading "Send As" channels in a channel.
- Place Star Reaction always first in list.
- Removed paid Invite Links in groups.
2024-08-17 18:14:54 +02:00
John Preston
eec59611ef Fix leaving forum glitch. 2024-08-17 17:09:49 +02:00
23rd
bfbdf1b935 Removed currency stat from channel earn section when it's not available. 2024-08-16 14:07:55 +03:00
John Preston
f2ea0edc95 Fix link confirmation box in media viewer. 2024-08-16 11:16:35 +02:00
John Preston
754b3a5ae8 Fix bottom text and info layout in albums. 2024-08-16 11:16:18 +02:00
John Preston
62a20ba975 Fix incorrect window activation on message jump.
Fixes #28275.
2024-08-16 10:57:30 +02:00
John Preston
f3dca6efb7 Show correct signature in send-as channel posts. 2024-08-16 10:54:02 +02:00
John Preston
dc1df14a71 Fix send_as appearance in channels. 2024-08-16 09:45:17 +02:00
John Preston
73c018667d Place star reaction always first. 2024-08-16 09:11:25 +02:00
23rd
3905fc7c38 Slightly improved input of credits with large numbers for invite links. 2024-08-15 16:18:33 +03:00
23rd
0c3cabf4ac Removed interface for subscription links from mega groups. 2024-08-15 16:18:33 +03:00
23rd
838d5669ed Replaced api for credits rate. 2024-08-15 16:18:33 +03:00
John Preston
3a7a485dd0 Fix switching profiles in a channel. 2024-08-15 10:45:55 +02:00
John Preston
a4ac00acbd Allow sending star reactions to discussion roots. 2024-08-15 10:14:30 +02:00
John Preston
7d52c13625 Fix focus search on topic open. 2024-08-15 09:48:59 +02:00
John Preston
520de600a0 Fix manifest for Windows Store version. 2024-08-15 08:19:18 +02:00
23rd
4f8e914d53 Added button to media viewer for photo from sponsored messages. 2024-08-15 00:46:58 +03:00
John Preston
79c8c5ec5d Version 5.4.
- Super Channels with post authors' profiles.
- Support favorite channels with Star Reactions.
- Channel Subscriptions with Stars monthly payments.
2024-08-14 23:32:55 +03:00
John Preston
3548aba652 Fix build with GCC. 2024-08-14 23:32:55 +03:00
John Preston
5d1812efc8 Fix build on Windows. 2024-08-14 19:57:38 +02:00
23rd
0477d43fbb Added button to media viewer for media from sponsored messages. 2024-08-14 20:51:01 +03:00
John Preston
73609fe5b2 Fix build on macOS. 2024-08-14 19:02:31 +02:00
John Preston
e027196c8a Don't ask to download CMake on Windows.
The one from Visual Studio works just fine now.
2024-08-14 18:42:52 +02:00
23rd
6d00165e5a Fixed text state of media in sponsored messages. 2024-08-14 18:17:53 +02:00
John Preston
693eaf9262 Allow tonsite:// custom links. 2024-08-14 18:17:53 +02:00
John Preston
3549349ffb Improve layout for the first star reaction. 2024-08-14 18:17:53 +02:00
John Preston
fac20e436d Nice top-up / star sent toasts. 2024-08-14 18:17:53 +02:00
John Preston
63f0feaf04 Change shown top senders only on amount change. 2024-08-14 18:17:52 +02:00
John Preston
3001464f6b Show error on webapp share-to-story. 2024-08-14 18:17:52 +02:00
John Preston
eec9c8a46b Support tg://stars_topup links. 2024-08-14 18:17:52 +02:00
John Preston
80b3754be1 Fix build on Windows. 2024-08-14 18:17:52 +02:00
John Preston
6d61caea4e Update cmake_helpers. 2024-08-14 18:17:52 +02:00
John Preston
b9de12fedb Support 18+/restrictions for messages. 2024-08-14 18:17:52 +02:00
23rd
074dbf41e0 Replaced menu in media viewer with menu for sponsored messages. 2024-08-14 18:17:52 +02:00
23rd
e51b2c0c91 Improved Menu::ShowSponsored to be more generic. 2024-08-14 18:17:52 +02:00
23rd
e4538947c3 Added ability to open media from sponsored messages. 2024-08-14 18:17:52 +02:00
23rd
624e068f2f Added initial ability to display media in sponsored messages. 2024-08-14 18:17:52 +02:00
23rd
30077133d4 Fixed drawing online badge.
Regression was introduced in 66cd27a23e.
2024-08-14 18:17:52 +02:00
John Preston
b0fece2fd0 Provide privacy policy in mini-app. 2024-08-14 18:17:52 +02:00
John Preston
5f8c007a0c Always show Bot Privacy Policy button. 2024-08-14 18:17:52 +02:00
John Preston
a2785867b2 Support correct paid-media-from-bot phrases. 2024-08-14 18:17:52 +02:00
John Preston
9ea495f59d Support group-like channels. 2024-08-14 18:17:52 +02:00
John Preston
24a7e48b75 Fix reactions layout under a media. 2024-08-14 18:17:52 +02:00
John Preston
7ef44fb621 Fix channel reactions list editing. 2024-08-14 18:17:51 +02:00
John Preston
0a1ddddd81 Allow paid reaction even after limit is reached. 2024-08-14 18:17:51 +02:00
John Preston
284f1a5210 Support anonymous paid reactions. 2024-08-14 18:17:51 +02:00
John Preston
37283a7a35 Fix shortcut messages incorrect processing. 2024-08-14 18:17:51 +02:00
John Preston
7f4b540aad Fix crash in poll results collapsing. 2024-08-14 18:17:51 +02:00
John Preston
83f4c53766 Provide unavailable reasons for messages. 2024-08-14 18:17:51 +02:00
John Preston
155f4ea252 Fix build on Windows. 2024-08-14 18:17:51 +02:00
John Preston
f6c071bd18 Fix crash in paid media preview. 2024-08-14 18:17:51 +02:00
John Preston
56959398e2 Update API scheme on layer 186. 2024-08-14 18:17:51 +02:00
23rd
d34d3a796d Added initial graphic of badge to dialog row for subscribed channels. 2024-08-14 18:17:51 +02:00
23rd
dca61541d6 Added ability to emplace badge in dialog row for subscribed channels. 2024-08-14 18:17:51 +02:00
23rd
81a79e2895 Added subscription price info to list of invite links. 2024-08-14 18:17:51 +02:00
23rd
d6541d777f Added box of channel subscriber. 2024-08-14 18:17:51 +02:00
23rd
457301493f Moved out drawing of label for subscription rows to single place. 2024-08-14 18:17:51 +02:00
23rd
4f7364b798 Added ability to cancel and renew subscription from settings section. 2024-08-14 18:17:51 +02:00
23rd
32e8ed93e2 Added ability to display subscription info in ReceiptCreditsBox. 2024-08-14 18:17:51 +02:00
23rd
4760337958 Removed redundant argument from ReceiptCreditsBox. 2024-08-14 18:17:51 +02:00
23rd
f2f85a9083 Replaced icon with custom emoji in list of credits history entries. 2024-08-14 18:17:50 +02:00
23rd
70d5dd8b71 Added initial list of subscriptions to credits settings section. 2024-08-14 18:17:50 +02:00
23rd
ec93a91db2 Added api support for subscriptions list. 2024-08-14 18:17:50 +02:00
23rd
cc3baad377 Added subscription date to credits history entries. 2024-08-14 18:17:50 +02:00
John Preston
d1313f38eb Show right icon in top reactors. 2024-08-14 18:17:50 +02:00
John Preston
49e6c4f552 Don't allow setting star as quick reaction. 2024-08-14 18:17:50 +02:00
John Preston
fb252bb644 Update API scheme on layer 186. 2024-08-14 18:17:50 +02:00
John Preston
78e09f2605 Fix build on Windows. 2024-08-14 18:17:50 +02:00
John Preston
ba4c521d7a Send scheduled paid reactions on quit. 2024-08-14 18:17:50 +02:00
23rd
92f70a0ebb Added handler to subscribe box when balance is too small. 2024-08-14 18:17:50 +02:00
23rd
a13f0cb11e Added ability to subscribe to channel via invite link. 2024-08-14 18:17:50 +02:00
23rd
617ad38a68 Added subscription info to box for details of invite link. 2024-08-14 18:17:50 +02:00
23rd
fb66c85567 Added initial ability to request rate of credits from Credits component. 2024-08-14 18:17:50 +02:00
23rd
05fa2c381a Added initial ability to use credits icon as emoji. 2024-08-14 18:17:50 +02:00
23rd
ae18b4c851 Added special icon to list for invite links with subscription. 2024-08-14 18:17:50 +02:00
23rd
7ed715b01c Added ability to edit invite links with subscription. 2024-08-14 18:17:50 +02:00
23rd
8158c52e82 Added ability to create invite links with subscription. 2024-08-14 18:17:50 +02:00
23rd
44c1109798 Slightly improved include directives in files for invite links. 2024-08-14 18:17:50 +02:00
23rd
ba6bbf54e6 Added initial api support to create invite links with subscription. 2024-08-14 18:17:50 +02:00
23rd
75b26b1a85 Moved bunch of arguments for creation of invite links to structure. 2024-08-14 18:17:50 +02:00
23rd
c8a3b0ab80 Renamed SubscriptionOption with PremiumSubscriptionOption. 2024-08-14 18:17:49 +02:00
John Preston
52a199a362 Make nice paid reaction toast. 2024-08-14 18:17:49 +02:00
John Preston
e89f2b55e8 Support arbitrary content in toasts. 2024-08-14 18:17:49 +02:00
John Preston
ac92e1c99e Start paid reaction toast notification. 2024-08-14 18:17:49 +02:00
John Preston
02610de010 Improve paid reactions box design. 2024-08-14 18:17:49 +02:00
John Preston
273e041935 Update currencies list and rules. 2024-08-14 18:17:49 +02:00
John Preston
474c0838d1 Show "Star Reaction" in stars statistics. 2024-08-14 18:17:49 +02:00
John Preston
afe30da9f4 Add top reactors to paid reaction details. 2024-08-14 18:17:49 +02:00
John Preston
9bb1fa8782 Allow sending paid reactions. 2024-08-14 18:17:49 +02:00
John Preston
bb3fc17489 Allow enabling paid reactions. 2024-08-14 18:17:49 +02:00
John Preston
126fd89bb7 Remove accidentally added files from git. 2024-08-14 18:17:49 +02:00
John Preston
fb8f3ad26c Update API scheme to layer 186. 2024-08-14 18:17:48 +02:00
23rd
cedf161e44 Removed inappropriate phrase from photo editor for profile bot photo. 2024-08-14 18:17:48 +02:00
23rd
89dc18aaea Added mode animations to loading screen from different stats. 2024-08-14 18:17:48 +02:00
23rd
ba99706e75 Fixed indents in qrc file. 2024-08-14 18:17:48 +02:00
23rd
efc8417ab1 Improved text size in list of credits options. 2024-08-14 18:17:48 +02:00
23rd
c4f45c4b7c Fixed resizing of label in section of profile info. 2024-08-14 18:17:48 +02:00
23rd
c985b77a48 Removed event filter from input field in edit peer info box on close. 2024-08-14 18:17:48 +02:00
Ilya Fedin
6148fb9474 Use CMAKE_CXX_COMPILER_FRONTEND_VARIANT 2024-08-14 18:43:27 +04:00
Ilya Fedin
fe86f5d050 Check IV support early 2024-08-13 17:09:15 +04:00
Ilya Fedin
916926bfa6 Fix default export directory in flatpak 2024-08-13 08:45:55 +04:00
Ilya Fedin
9eb15f7b17 Move ada snap part to maintain alphabetical order 2024-08-04 12:16:10 +04:00
Ilya Fedin
2d1b1fbd44 Ensure tdesktop builds after ada in snap 2024-08-04 12:16:10 +04:00
Ilya Fedin
1301c42afa Add ada to macOS packaged action 2024-08-04 12:16:10 +04:00
John Preston
0de5080874 Version 5.3.2.
- Fix crash on launch by focing non-LTO jemalloc build.

Fixes #28213, fixes #28221.
2024-08-02 18:14:03 +03:00
John Preston
a982560a62 Fix build on Linux. 2024-08-02 05:31:59 +03:00
John Preston
4a5d8046d5 Version 5.3.1.
- Open normal links from tonsite-s in system browser.
- Fix unicode tonsite:// links.
- Fix crash on Linux X11.
2024-08-01 17:21:06 +02:00
23rd
65a14bcab4 Removed placeholder from input field in box for renaming sticker set. 2024-08-01 17:21:01 +02:00
John Preston
e9bb6f65e3 Update submodules. 2024-08-01 17:14:26 +02:00
John Preston
74f7fa80b7 Fix opening .ton links. 2024-08-01 17:14:26 +02:00
John Preston
2ff0ed50be Encode/Decode tonsite:// punycode correctly. 2024-08-01 17:14:26 +02:00
John Preston
281ad01b85 Add ada library. 2024-08-01 17:14:26 +02:00
John Preston
4864a6996f Open links from tonsite:// externally. 2024-08-01 14:47:33 +02:00
John Preston
0af3028cd6 Allow opening tonsite:// from web apps. 2024-08-01 14:47:16 +02:00
John Preston
11c91c1a42 Don't show recent apps in popular apps. 2024-08-01 14:13:27 +02:00
John Preston
7f3dc27aa9 Allow removing mini apps from recents. 2024-08-01 13:28:25 +02:00
John Preston
51fc104c60 Show bot active users count in status. 2024-08-01 13:28:03 +02:00
John Preston
6b96466c5e Fix possible crash in forward preview. 2024-08-01 12:55:34 +02:00
John Preston
7c1510b611 Fix crash on empty gift receivers list. 2024-08-01 12:55:23 +02:00
Ilya Fedin
993c0ee648 Ensure fake modal widget is a window 2024-08-01 08:58:16 +04:00
John Preston
503c3c7b00 Version 5.3: Update cmake_helpers submodule. 2024-08-01 00:20:34 +03:00
John Preston
b7c14f17a7 Version 5.3: Fix build with Xcode. 2024-07-31 23:06:39 +02:00
John Preston
0b6bd7075a Version 5.3.
- View recent and popular web apps in chats search.
- Open several web apps in different windows.
- Gift Telegram Stars to your friends.
- Send location marks and venues.
- Open tonsite:// links in webview.
- Edit order of stickers in your packs.
2024-07-31 19:06:47 +02:00
John Preston
148690d8b1 Open .ton as a tonsite. 2024-07-31 18:59:31 +02:00
John Preston
a422aec99a Fix cancel of bot app confirm. 2024-07-31 18:59:24 +02:00
John Preston
813d0501da Fix build on Windows. 2024-07-31 18:58:44 +02:00
John Preston
db80096e6b Use corporate sign certificate identity. 2024-07-31 17:03:56 +02:00
John Preston
cf896aeb13 Improve focusing of shown layers. 2024-07-31 17:03:56 +02:00
John Preston
76314e3c03 Close additional windows on passcode lock. 2024-07-31 17:03:56 +02:00
John Preston
8959679b3c Make IV internal links bg semi-transparent. 2024-07-31 17:03:56 +02:00
John Preston
bb6c94ef4f Handle tonsite:// links from the system. 2024-07-31 17:03:56 +02:00
John Preston
fb9ce6d3a8 Provide canGo[Back|Forward] for tonsite-s. 2024-07-31 17:03:56 +02:00
John Preston
dac4389e37 Fix build on Linux. 2024-07-31 17:03:55 +02:00
John Preston
a25b2e9700 Show webview error in Iv::Controller. 2024-07-31 17:03:55 +02:00
John Preston
699a7bdc58 Fix possible crash in message field.
Fixes #28203.
2024-07-31 17:03:55 +02:00
John Preston
4108debca0 Fix possible crash in web apps. 2024-07-31 17:03:55 +02:00
John Preston
8b2bbfba6a Navigate back/forward in tonsite pages. 2024-07-31 17:03:55 +02:00
John Preston
4f37343e8b Use special webview storage for tonsite. 2024-07-31 17:03:55 +02:00
John Preston
2dcf40817e Initial tonsite:// show in IV window. 2024-07-31 17:03:55 +02:00
John Preston
3eeb01be61 Save Celsius/Fahrenheit in Settings. 2024-07-31 17:03:55 +02:00
John Preston
6a8a85e395 Implement recent/popular apps list. 2024-07-31 17:03:55 +02:00
John Preston
031233ea98 Remove some code duplication. 2024-07-31 17:03:54 +02:00
John Preston
4b09050061 Implement Stars gift view from service messages. 2024-07-31 17:03:54 +02:00
John Preston
992c876930 Show correct presents in Stars gifts. 2024-07-31 17:03:54 +02:00
John Preston
a5ffd8b7cf Request new main web app. 2024-07-31 17:03:54 +02:00
John Preston
5fdd4eba80 Implement weather area in stories. 2024-07-31 17:03:54 +02:00
John Preston
54ce85f8e6 Show nice star in stars payments. 2024-07-31 17:03:54 +02:00
23rd
0bfb0fd045 Added initial ability to gift credits to users. 2024-07-31 17:03:54 +02:00
23rd
8ad2d3d39a Added api support to create invoice for credit gifts. 2024-07-31 17:03:54 +02:00
23rd
b8a19b56b6 Removed window session controller usage from list of credit options. 2024-07-31 17:03:54 +02:00
23rd
24b93a5eff Added support for credits gift options to list of credit options. 2024-07-31 17:03:53 +02:00
23rd
127f651d5e Added api support to get credits gift options. 2024-07-31 17:03:53 +02:00
23rd
e760a0983f Added gift sticker to ReceiptCreditsBox for gifts. 2024-07-31 17:03:53 +02:00
23rd
3f2cb8f8c9 Added file origin to sticker pack for gifts. 2024-07-31 17:03:53 +02:00
23rd
bcb6e9e1af Removed unused include directives from settings_common_session. 2024-07-31 17:03:53 +02:00
23rd
847d66c973 Added initial support of received gifts in list of credits history. 2024-07-31 17:03:53 +02:00
John Preston
5c797d1f31 Update API scheme to layer 185. 2024-07-31 17:03:53 +02:00
23rd
f749616dd8 Added additional request of special sticker pack on failing view pack. 2024-07-31 16:50:48 +03:00
23rd
3cc92e01fe Added ability to force request favorite stickers. 2024-07-31 16:50:04 +03:00
23rd
06f2b23687 Added badge to header for owned sticker sets in stickers list. 2024-07-31 13:05:29 +03:00
23rd
6a167b33f5 Added ability to delete sticker from sticker set box. 2024-07-31 11:57:19 +03:00
23rd
850155b3be Added shake animation while reordering to sticker set box. 2024-07-31 11:57:19 +03:00
23rd
358e586801 Added api support to reorder stickers from sticker set box. 2024-07-31 11:57:19 +03:00
23rd
54214ff2ad Added initial ability to drag stickers in sticker set box. 2024-07-30 13:52:32 +03:00
23rd
06fc813e95 Added loading state to box for renaming of stickers set. 2024-07-30 13:52:32 +03:00
23rd
0046bae53f Added ability to change name of sticker set from sticker set box. 2024-07-30 13:52:32 +03:00
23rd
aeb5e57061 Fixed profile opening of group call participant in separate windows. 2024-07-30 13:52:27 +03:00
23rd
a32b781e49 Improved Controller::invokeForSessionController for separate windows. 2024-07-30 13:52:27 +03:00
23rd
caef698e54 Fixed recursive invoking of Application::windowFor. 2024-07-30 13:52:27 +03:00
23rd
e9650385ad Added ability to provide custom style to widget with infinite animation. 2024-07-30 10:54:38 +03:00
23rd
f55584b160 Fixed position of click handler for via bot header in message view. 2024-07-30 10:54:38 +03:00
John Preston
b0981ea8e3 Beta version 5.2.6.
- Fix launching on X11. (Linux)
2024-07-29 11:02:25 +03:00
Ilya Fedin
a141d01a23 Fix macOS packaged action 2024-07-27 22:59:48 +02:00
John Preston
6a000207ee Beta version 5.2.5.
- Fix media viewer context menu.
- Fix blockquotes layout in messages.
2024-07-27 07:48:35 +02:00
John Preston
ee6edf9caa Force venue icon format. 2024-07-27 07:45:59 +02:00
John Preston
37907636e6 Fix build with Xcode. 2024-07-27 07:44:51 +02:00
John Preston
3f0f3a3c11 Focus existing location picker. 2024-07-26 17:28:04 +02:00
John Preston
db0856f71c Support t.me/username?profile links. 2024-07-26 17:28:03 +02:00
John Preston
86cdda2277 Fix text with blockquotes geometry counting. 2024-07-26 17:28:03 +02:00
John Preston
3888e8084a Update tg_owt, lib_webrtc and patches. 2024-07-26 13:02:38 +02:00
Ilya Fedin
517b456670 Add hit test for window context menu 2024-07-26 10:19:55 +02:00
John Preston
77d6e19214 Beta version 5.2.4.
- Allow opening several web apps.
- Send location marks and venues.
2024-07-25 10:33:57 +03:00
John Preston
fb64452495 Fix build on Linux. 2024-07-25 10:33:57 +03:00
John Preston
24fabf2590 Fix build on Windows. 2024-07-24 18:43:18 +02:00
John Preston
9b2847a11d Update submodules. 2024-07-24 18:15:28 +02:00
Ilya Fedin
c18e8fd777 Enable exceptions for C on Linux 2024-07-24 18:12:30 +02:00
Ilya Fedin
f4afa762d8 Replace -fstack-protector-all with -fstack-protector-strong to avoid slowdown of functions not using stack 2024-07-24 18:12:30 +02:00
Ilya Fedin
5e1fb6ebbf Add -fasynchronous-unwind-tables and -mno-omit-leaf-frame-pointer for better debugging on Linux 2024-07-24 18:12:30 +02:00
Ilya Fedin
2c7922ce7b Get release CFLAGS from Dockerfile on Linux 2024-07-24 18:12:30 +02:00
Ilya Fedin
ac78ae823c Reduce portal autostart dialog modality to parent window 2024-07-24 18:10:56 +02:00
John Preston
1ef6f462f6 Preserve link preview settings on reschedule. 2024-07-24 18:06:08 +02:00
John Preston
c81f406759 Use xz repository from GitHub.
Fixes #28189.
2024-07-24 18:06:07 +02:00
John Preston
889ec0c731 Replace \r\n with \n on paste.
Fixes #28181.
2024-07-24 18:25:33 +03:00
John Preston
677fbdd84e Fix webrtc camera usage on Linux. 2024-07-24 17:56:47 +03:00
John Preston
1ebe3255e0 Fix share focus in IV. 2024-07-24 16:09:04 +02:00
John Preston
c70866a995 Fix child native window focus. 2024-07-24 16:09:04 +02:00
John Preston
fd982b90db Implement separate instances for web apps. 2024-07-24 13:46:22 +02:00
John Preston
9461095c88 Fix build with GCC. 2024-07-19 13:01:08 +03:00
John Preston
a2fa1a52e2 Pass VideoCaptureOptions on Linux. 2024-07-19 11:58:26 +02:00
John Preston
a847969e9c Attempt to fix bad input field layout on Qt 6. 2024-07-19 11:58:26 +02:00
John Preston
4d647e64b7 Fix chat links with '-' in slug.
Fixes https://bugs.telegram.org/c/41902.
2024-07-19 11:58:26 +02:00
John Preston
f8b756d447 Improve bot checkout error messages. 2024-07-19 11:58:26 +02:00
John Preston
484c647b5b Fix bot about text layout on wide windows. 2024-07-19 11:58:26 +02:00
John Preston
730c968b1e Use always 1:1 ratio in limits boxes.
Otherwise "Free" label doesn't fit in 2:20 shareable folders.
2024-07-19 11:58:26 +02:00
John Preston
8a6a749296 Show error on attempt to scan QR in bot app.
Fixes #26886.
2024-07-19 11:58:26 +02:00
John Preston
2f22a8f46b Add Windows on ARM to build scripts. 2024-07-19 11:58:26 +02:00
John Preston
f123a9e16c Add openh264 to Dockerfile. 2024-07-19 11:58:20 +02:00
John Preston
11c45b0342 Update submodules. 2024-07-19 11:57:44 +02:00
John Preston
2cd6bfef06 Fix H265 in webrtc. 2024-07-19 11:57:41 +02:00
John Preston
61ca619db4 Fix build on macOS. 2024-07-19 11:56:57 +02:00
John Preston
675ee9088f Fix build on Windows. 2024-07-19 11:56:57 +02:00
John Preston
28a6aa45b9 Update msys2 and patches. 2024-07-19 11:56:57 +02:00
John Preston
08ec9e6bfd Fix build on macOS with new dependencies. 2024-07-19 11:56:54 +02:00
John Preston
ee9f99a754 Add some Windows on ARM special cases. 2024-07-19 11:56:34 +02:00
John Preston
2412183b83 Build most dependencies for Windows on ARM. 2024-07-19 11:56:34 +02:00
John Preston
e83704982f Set initial location correctly. 2024-07-19 11:56:34 +02:00
John Preston
6f86acf712 Use system reverse geocoding on macOS. 2024-07-19 11:56:34 +02:00
John Preston
c22698084f Location search cancel by X button. 2024-07-19 11:56:34 +02:00
John Preston
8c55364afa Allow editing business location in Settings. 2024-07-19 11:56:34 +02:00
John Preston
2c3ef13b01 Update tg_owt to M123. 2024-07-19 11:56:25 +02:00
John Preston
03454ca3b4 Fix sticker quote reply layout. 2024-07-19 11:20:54 +02:00
John Preston
8a92c89f39 Add fsqr promo footer. 2024-07-19 11:20:54 +02:00
John Preston
b83b403b75 Pass correct peer to venue search. 2024-07-19 11:20:54 +02:00
John Preston
8aac07b3c0 Show empty venue search states. 2024-07-19 11:20:54 +02:00
John Preston
b4dfc25df5 Implement venues search. 2024-07-19 11:20:54 +02:00
John Preston
917d1841c1 Try better webview focusing. 2024-07-19 11:20:54 +02:00
John Preston
8ce10d5503 Send chosen venues. 2024-07-19 11:20:54 +02:00
John Preston
a130bb1be6 Search for venues by location. 2024-07-19 11:20:54 +02:00
John Preston
de52ac6b28 Resolve different addresses. 2024-07-19 11:20:54 +02:00
John Preston
310837c9e1 Add venues list and chosen place name. 2024-07-19 11:20:54 +02:00
John Preston
8e6d7bb190 Improve location picker design. 2024-07-19 11:20:53 +02:00
John Preston
025ab40687 Implement location sending on macOS. 2024-07-19 11:20:53 +02:00
John Preston
2a5071b66c Initial location sending on Windows. 2024-07-19 11:20:53 +02:00
23rd
2a63496054 Extended conditions to ability to view channel message statistics. 2024-07-18 01:54:05 +03:00
23rd
a52d4eb4e8 Fixed peer in list of credits history entries. 2024-07-17 18:11:22 +03:00
23rd
4f7a124f3e Added phrases to credits history entries when peer type is premium bot. 2024-07-17 10:04:14 +02:00
23rd
4b9eb37bd5 Added phrases for single winner of giveaway in channels. 2024-07-17 10:04:14 +02:00
23rd
1d5e4040f4 Added api support of flag to view credits stats from full channel. 2024-07-17 10:04:13 +02:00
23rd
6818b8d8dc Fixed row name in table for credits history entries in earn box. 2024-07-17 10:04:13 +02:00
23rd
3f0b962ae5 Fixed color reset for chat filters on saving. 2024-07-17 10:04:13 +02:00
23rd
8ac1ad3484 Updated Qt to 6.2.9 on macOS. 2024-07-17 10:04:13 +02:00
John Preston
c6e1cf639e Update API scheme to layer 184. 2024-07-17 10:04:13 +02:00
Ilya Fedin
5b9278eced Switch Docker to distro-provided cmake 2024-07-15 09:21:47 +02:00
John Preston
03d4dd00d4 Delete selection on Ctrl+Backspace.
Fixes #28143.
2024-07-12 10:32:59 +02:00
John Preston
f7d698b9ff Fix last seen within week/month. 2024-07-12 08:45:45 +02:00
John Preston
46b69a938b Revert "Register tg:// scheme on initial launch."
This reverts commit 8cbeadc68a.
2024-07-12 08:45:45 +02:00
John Preston
ebba58217c Don't set focus to shown third section.
I hope it fixes #28142.
2024-07-12 08:45:45 +02:00
John Preston
94ad8f9bc3 Don't register collapsed row click as userpic.
Fixes #28149.
2024-07-12 08:45:44 +02:00
John Preston
6effac7915 Migrate games to AttachWebView. 2024-07-12 08:45:44 +02:00
John Preston
78093173a9 Version 5.2.3.
- Fix crash in bot star stats page.
- Bug fixes and other minor improvements.
2024-07-07 09:01:58 +04:00
John Preston
a01d48f063 Update submodules. 2024-07-06 22:21:04 +04:00
John Preston
149c69c9f5 Use a separate string for Your Stars in Settings. 2024-07-06 22:13:44 +04:00
John Preston
df277b366b Fix build on Windows. 2024-07-06 13:31:44 +04:00
John Preston
f20475f07e Show forbidden icon on disabled webview button. 2024-07-06 13:31:27 +04:00
John Preston
b6664625ea Fix assigning text after formatted text.
Fixes #28115.
2024-07-06 13:31:27 +04:00
John Preston
1028219276 Allow chats list preview for narrow photos. 2024-07-06 11:08:42 +04:00
John Preston
219671a3bc Fix archive in Main Menu context menu. 2024-07-06 11:08:42 +04:00
John Preston
8c97e915ec Create .mm source blanks for macOS modules. 2024-07-06 11:08:42 +04:00
John Preston
b648548001 Don't insert "data:image.." after image paste cancel. 2024-07-06 11:08:42 +04:00
23rd
b377c02ad3 Added support of min boost level for channel ads to feature list. 2024-07-06 11:08:41 +04:00
23rd
66d6b461f3 Fixed support type of credits history entry for ads in earn section. 2024-07-06 11:08:41 +04:00
John Preston
054a6db3ae Fix warnings on Windows in submodules. 2024-07-06 11:08:36 +04:00
Ilya Fedin
bf7042df44 Enable warnings as errors on Windows 2024-07-06 11:05:28 +04:00
Ilya Fedin
aa140b2919 Fix warnings on Windows 2024-07-06 11:05:28 +04:00
Ilya Fedin
8d0d9bb0bd Delay clearing transient parent until the pip window is really exposed 2024-07-06 09:17:04 +04:00
Daniel Novomeský
9ca9904732 Upgrade libjxl to v0.10.3 2024-07-05 21:30:00 +04:00
Daniel Novomeský
e6e1b9446d Upgrade libjxl on Linux to 0.10.3 2024-07-03 20:04:32 +04:00
John Preston
a507d28b49 Version 5.2.2.
- Fix topics search in topic groups.
- Fix Instant View pages content updating.
2024-07-02 19:03:07 +04:00
John Preston
ec2faca145 Fix couple of crashes in secondary windows. 2024-07-02 18:08:24 +04:00
John Preston
17bb430006 Register tg:// scheme on first launch.
Also, allow disabling tg:// re-registration on update.
2024-07-02 13:34:52 +04:00
John Preston
8cbeadc68a Register tg:// scheme on initial launch. 2024-07-02 13:22:33 +04:00
John Preston
3947056654 Use cached views count from not modified page. 2024-07-02 10:40:39 +04:00
John Preston
ad7d1fddf0 Reload IV on each open, take hash into account.
Fixes #28111.
2024-07-02 10:27:26 +04:00
John Preston
ab20f8eb31 Fix topics search in topic groups.
Fixes #28110.
2024-07-02 09:53:56 +04:00
623 changed files with 26125 additions and 9348 deletions

View File

@@ -69,7 +69,7 @@ jobs:
run: |
brew update
brew upgrade || true
brew install autoconf automake boost cmake ffmpeg@6 openal-soft openssl opus ninja pkg-config python qt yasm xz
brew install ada-url autoconf automake boost cmake ffmpeg@6 openal-soft openh264 openssl opus ninja pkg-config python qt yasm xz
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcodebuild -version > CACHE_KEY.txt
@@ -108,7 +108,7 @@ jobs:
run: |
cd $LibrariesPath
git clone --recursive --depth=1 $GIT/desktop-app/tg_owt.git
git clone --depth=1 --recursive --shallow-submodules $GIT/desktop-app/tg_owt.git
cd tg_owt
cmake -B build . -GNinja -DCMAKE_BUILD_TYPE=Debug

View File

@@ -169,6 +169,8 @@ jobs:
%TDESKTOP_BUILD_GENERATOR% ^
%TDESKTOP_BUILD_ARCH% ^
%TDESKTOP_BUILD_API% ^
-D CMAKE_C_FLAGS="/WX" ^
-D CMAKE_CXX_FLAGS="/WX" ^
-D DESKTOP_APP_DISABLE_AUTOUPDATE=OFF ^
-D DESKTOP_APP_DISABLE_CRASH_REPORTS=OFF ^
-D DESKTOP_APP_NO_PDB=ON ^

View File

@@ -37,6 +37,10 @@ include(cmake/td_scheme.cmake)
include(cmake/td_ui.cmake)
include(cmake/generate_appdata_changelog.cmake)
if (DESKTOP_APP_TEST_APPS)
include(cmake/tests.cmake)
endif()
if (WIN32)
include(cmake/generate_midl.cmake)
generate_midl(Telegram ${src_loc}
@@ -272,6 +276,8 @@ PRIVATE
boxes/edit_caption_box.h
boxes/edit_privacy_box.cpp
boxes/edit_privacy_box.h
boxes/gift_credits_box.cpp
boxes/gift_credits_box.h
boxes/gift_premium_box.cpp
boxes/gift_premium_box.h
boxes/language_box.cpp
@@ -308,6 +314,8 @@ PRIVATE
boxes/self_destruction_box.h
boxes/send_credits_box.cpp
boxes/send_credits_box.h
boxes/send_gif_with_caption_box.cpp
boxes/send_gif_with_caption_box.h
boxes/send_files_box.cpp
boxes/send_files_box.h
boxes/sessions_box.cpp
@@ -473,8 +481,12 @@ PRIVATE
data/business/data_business_info.h
data/business/data_shortcut_messages.cpp
data/business/data_shortcut_messages.h
data/components/credits.cpp
data/components/credits.h
data/components/factchecks.cpp
data/components/factchecks.h
data/components/location_pickers.cpp
data/components/location_pickers.h
data/components/recent_peers.cpp
data/components/recent_peers.h
data/components/scheduled_messages.cpp
@@ -820,6 +832,8 @@ PRIVATE
history/view/history_view_message.cpp
history/view/history_view_message.h
history/view/history_view_object.h
history/view/history_view_paid_reaction_toast.cpp
history/view/history_view_paid_reaction_toast.h
history/view/history_view_pinned_bar.cpp
history/view/history_view_pinned_bar.h
history/view/history_view_pinned_section.cpp
@@ -1232,6 +1246,8 @@ PRIVATE
payments/payments_form.h
payments/payments_non_panel_process.cpp
payments/payments_non_panel_process.h
payments/payments_reaction_process.cpp
payments/payments_reaction_process.h
platform/linux/file_utilities_linux.cpp
platform/linux/file_utilities_linux.h
platform/linux/launcher_linux.cpp
@@ -1464,6 +1480,10 @@ PRIVATE
support/support_preload.h
support/support_templates.cpp
support/support_templates.h
ui/boxes/edit_invite_link_session.cpp
ui/boxes/edit_invite_link_session.h
ui/boxes/peer_qr_box.cpp
ui/boxes/peer_qr_box.h
ui/chat/attach/attach_item_single_file_preview.cpp
ui/chat/attach/attach_item_single_file_preview.h
ui/chat/attach/attach_item_single_media_preview.cpp
@@ -1472,6 +1492,10 @@ PRIVATE
ui/chat/choose_send_as.h
ui/chat/choose_theme_controller.cpp
ui/chat/choose_theme_controller.h
ui/controls/emoji_button_factory.cpp
ui/controls/emoji_button_factory.h
ui/controls/location_picker.cpp
ui/controls/location_picker.h
ui/controls/silent_toggle.cpp
ui/controls/silent_toggle.h
ui/controls/userpic_button.cpp
@@ -1493,6 +1517,12 @@ PRIVATE
ui/image/image_location.h
ui/image/image_location_factory.cpp
ui/image/image_location_factory.h
ui/text/format_song_document_name.cpp
ui/text/format_song_document_name.h
ui/widgets/expandable_peer_list.cpp
ui/widgets/expandable_peer_list.h
ui/widgets/label_with_custom_emoji.cpp
ui/widgets/label_with_custom_emoji.h
ui/countryinput.cpp
ui/countryinput.h
ui/dynamic_thumbnails.cpp
@@ -1506,10 +1536,6 @@ PRIVATE
ui/resize_area.h
ui/search_field_controller.cpp
ui/search_field_controller.h
ui/text/format_song_document_name.cpp
ui/text/format_song_document_name.h
ui/widgets/label_with_custom_emoji.cpp
ui/widgets/label_with_custom_emoji.h
ui/unread_badge.cpp
ui/unread_badge.h
window/main_window.cpp
@@ -1614,6 +1640,7 @@ PRIVATE
qrc/telegram/animations.qrc
qrc/telegram/export.qrc
qrc/telegram/iv.qrc
qrc/telegram/picker.qrc
qrc/telegram/telegram.qrc
qrc/telegram/sounds.qrc
winrc/Telegram.rc
@@ -1813,7 +1840,7 @@ endif()
set_target_properties(Telegram PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${output_folder})
if (WIN32)
if (WIN32 AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
target_link_libraries(Telegram
PRIVATE
delayimp
@@ -1844,9 +1871,14 @@ if (WIN32)
/DELAYLOAD:propsys.dll
)
if (QT_VERSION GREATER 6)
if (NOT build_winarm)
target_link_options(Telegram PRIVATE
/DELAYLOAD:API-MS-Win-EventLog-Legacy-l1-1-0.dll
)
endif()
target_link_options(Telegram
PRIVATE
/DELAYLOAD:API-MS-Win-EventLog-Legacy-l1-1-0.dll
/DELAYLOAD:API-MS-Win-Core-Console-l1-1-0.dll
/DELAYLOAD:API-MS-Win-Core-Fibers-l2-1-0.dll
/DELAYLOAD:API-MS-Win-Core-Fibers-l2-1-1.dll
@@ -1863,7 +1895,7 @@ if (WIN32)
/DELAYLOAD:API-MS-Win-Core-WinRT-Error-l1-1-0.dll
/DELAYLOAD:API-MS-Win-Core-WinRT-String-l1-1-0.dll
/DELAYLOAD:API-MS-Win-Security-CryptoAPI-l1-1-0.dll
/DELAYLOAD:API-MS-Win-Shcore-Scaling-l1-1-1.dll
# /DELAYLOAD:API-MS-Win-Shcore-Scaling-l1-1-1.dll # We shadowed GetDpiForMonitor
/DELAYLOAD:authz.dll # Authz.lib
/DELAYLOAD:comdlg32.dll
/DELAYLOAD:dwrite.dll # DWrite.lib
@@ -1905,7 +1937,7 @@ if (NOT DESKTOP_APP_DISABLE_AUTOUPDATE AND NOT build_macstore AND NOT build_wins
base/platform/win/base_windows_safe_library.h
)
target_include_directories(Updater PRIVATE ${lib_base_loc})
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
target_link_libraries(Updater
PRIVATE
delayimp

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.

Before

Width:  |  Height:  |  Size: 214 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 912 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 987 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 B

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>General / menu_incomes</title>
<defs>
<rect id="path-1" x="0" y="0" width="72" height="37"></rect>
<rect id="path-3" x="0" y="0" width="72" height="42"></rect>
</defs>
<g id="General-/-menu_incomes" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-2">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Rectangle"></g>
<g id="Group" mask="url(#mask-2)" stroke="#FFFFFF" stroke-linecap="round" stroke-width="5.4">
<g transform="translate(35.056529, 35.872413) rotate(66.000000) translate(-35.056529, -35.872413) translate(5.056529, 5.872413)" id="Path">
<path d="M7.74068421e-14,27 C7.74068421e-14,27.6514434 0.0207638485,31.2980371 0.0616658298,31.9391554 C1.06104802,47.603977 14.0829009,60 30,60 C46.5685425,60 60,46.5685425 60,30 C60,13.4314575 46.5685425,-1.34265911e-13 30,-1.34265911e-13 C20.9122281,-1.34265911e-13 12.7682399,4.04081874 7.26674545,10.4237463" transform="translate(30.000000, 30.000000) rotate(90.000000) translate(-30.000000, -30.000000) "></path>
</g>
</g>
</g>
<g id="Group-2-Copy" transform="translate(0.000000, 28.000000)">
<mask id="mask-4" fill="white">
<use xlink:href="#path-3"></use>
</mask>
<g id="Rectangle"></g>
<g id="Group" mask="url(#mask-4)" stroke="#FFFFFF" stroke-dasharray="5,14" stroke-linecap="round" stroke-width="5.4">
<g transform="translate(35.056529, 7.872413) rotate(66.000000) translate(-35.056529, -7.872413) translate(-2.745677, -29.929792)" id="Path">
<path d="M7.80220532,34.8022053 C7.80220532,35.4536487 7.82296917,39.1002424 7.86387115,39.7413607 C8.86325334,55.4061823 21.8851062,67.8022053 37.8022053,67.8022053 C54.3707478,67.8022053 67.8022053,54.3707478 67.8022053,37.8022053 C67.8022053,21.2336628 54.3707478,7.80220532 37.8022053,7.80220532 C28.7144334,7.80220532 20.5704452,11.8430241 15.0689508,18.2259516" transform="translate(37.802205, 37.802205) rotate(72.000000) translate(-37.802205, -37.802205) "></path>
</g>
</g>
</g>
<g id="$" transform="translate(23.000000, 16.000000)" fill="#FFFFFF" fill-rule="nonzero">
<path d="M12.034384,39.8 C13.0659026,39.8 14.182808,39.2321492 14.182808,37.869307 L14.182808,35.752184 C20.3489971,35.093477 24,31.5046593 24,26.280431 C24,21.7830518 21.2722063,19.0573675 15.6103152,17.8308096 L10.9570201,16.7859639 C8.04584527,16.1499709 6.62464183,14.8325568 6.62464183,12.9018637 C6.62464183,10.585032 8.64183381,8.90419336 11.8051576,8.90419336 C14.3724928,8.90419336 16.1604585,9.76732673 18.1547278,11.9705882 C19.1633238,13.0154339 19.9426934,13.4015725 20.9971347,13.4015725 C22.2808023,13.4015725 23.2664756,12.5157251 23.2664756,11.198311 C23.2664756,9.92632499 22.5100287,8.54076878 21.226361,7.2914968 C19.530086,5.70151427 17.1653295,4.65666861 14.3,4.29324403 L14.3,1.907979 C14.3,0.56785087 13.2034384,0 12.1489971,0 C11.1174785,0 10,0.545136833 10,1.907979 L10,4.22510192 C4.06303725,4.77023879 0.481375358,8.29091439 0.481375358,13.3334304 C0.481375358,17.7399534 3.20916905,20.6700641 8.43553009,21.8284799 L13.0888252,22.8960396 C16.4813754,23.6910309 17.8796562,24.8721607 17.8796562,26.8709959 C17.8796562,29.460396 15.8395415,31.0958066 12.1948424,31.0958066 C9.46704871,31.0958066 7.19770774,30.073675 5.13467049,27.8704135 C3.96561605,26.7119977 3.32378223,26.4621433 2.45272206,26.4621433 C1.05444126,26.4621433 0,27.3479907 0,28.8698311 C0,30.2099592 0.779369628,31.5955154 2.17765043,32.7993593 C4.01146132,34.457484 6.67679058,35.4796156 9.863037,35.7748981 L9.863037,37.869307 C9.863037,39.2321492 10.9799427,39.8 12.034384,39.8 Z" id="Path"></path>
</g>
<path d="M66.2217021,28.4347599 L72.4528242,38.8199633 C72.7823745,39.3692138 72.6042723,40.0816225 72.0550218,40.4111728 C71.8747737,40.5193217 71.668522,40.5764501 71.4583183,40.5764501 L57.5551143,40.5764501 C56.9145837,40.5764501 56.3953311,40.0571975 56.3953311,39.4166669 C56.3953311,39.2064632 56.4524595,39.0002115 56.5606084,38.8199633 L62.7917304,28.4347599 C63.3600268,27.4875994 64.5885473,27.1804692 65.5357078,27.7487655 C65.817207,27.9176651 66.0528026,28.1532607 66.2217021,28.4347599 Z" id="Triangle" fill="#FFFFFF" transform="translate(64.506716, 33.076450) rotate(168.000000) translate(-64.506716, -33.076450) "></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1 @@
<svg width="1000px" height="1000px" viewBox="0 0 1000 1000" version="1.1" xmlns="http://www.w3.org/2000/svg"><g id="Artboard" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><path d="M226.328419,494.722069 C372.088573,431.216685 469.284839,389.350049 517.917216,369.122161 C656.772535,311.36743 685.625481,301.334815 704.431427,301.003532 C708.567621,300.93067 717.815839,301.955743 723.806446,306.816707 C728.864797,310.92121 730.256552,316.46581 730.922551,320.357329 C731.588551,324.248848 732.417879,333.113828 731.758626,340.040666 C724.234007,419.102486 691.675104,610.964674 675.110982,699.515267 C668.10208,736.984342 654.301336,749.547532 640.940618,750.777006 C611.904684,753.448938 589.856115,731.588035 561.733393,713.153237 C517.726886,684.306416 492.866009,666.349181 450.150074,638.200013 C400.78442,605.66878 432.786119,587.789048 460.919462,558.568563 C468.282091,550.921423 596.21508,434.556479 598.691227,424.000355 C599.00091,422.680135 599.288312,417.758981 596.36474,415.160431 C593.441168,412.561881 589.126229,413.450484 586.012448,414.157198 C581.598758,415.158943 511.297793,461.625274 375.109553,553.556189 C355.154858,567.258623 337.080515,573.934908 320.886524,573.585046 C303.033948,573.199351 268.692754,563.490928 243.163606,555.192408 C211.851067,545.013936 186.964484,539.632504 189.131547,522.346309 C190.260287,513.342589 202.659244,504.134509 226.328419,494.722069 Z" id="Path-3" fill="#FFFFFF"></path></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -618,9 +618,6 @@ var IV = {
element.getAnimations().forEach(
(animation) => animation.finish());
},
back: function () {
window.history.back();
},
menuShown: function (shown) {
var already = document.getElementById('menu_page_blocker');
if (already && shown) {

View File

@@ -11,6 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"cloud_lng_forwarded_psa_covid" = "COVID-19 Notification from {channel}";
"cloud_lng_tooltip_psa_covid" = "This message provides you with a public service announcement in relation to the ongoing COVID-19 pandemic. Learn more about this initiative at https://telegram.org/blog/coronavirus";
"cloud_lng_topup_purpose_subs" = "Buy **Stars** to keep your channel subscriptions.";
"cloud_lng_passport_in_ar" = "Arabic";
"cloud_lng_passport_in_az" = "Azerbaijani";
"cloud_lng_passport_in_bg" = "Bulgarian";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,120 @@
:root {
--font-sans: -apple-system, BlinkMacSystemFont, avenir next, avenir, Segoe UI Variable Text, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, tahoma, arial, sans-serif;
}
html {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
body {
font-family: var(--font-sans);
width: 100%;
height: 100%;
padding: 0;
margin: 0;
background-color: var(--td-window-bg);
color: var(--td-window-fg);
}
html.custom_scroll ::-webkit-scrollbar {
border-radius: 5px !important;
border: 3px solid transparent !important;
background-color: var(--td-scroll-bg) !important;
background-clip: content-box !important;
width: 10px !important;
}
html.custom_scroll ::-webkit-scrollbar:hover {
background-color: var(--td-scroll-bg-over) !important;
}
html.custom_scroll ::-webkit-scrollbar-thumb {
border-radius: 5px !important;
border: 3px solid transparent !important;
background-color: var(--td-scroll-bar-bg) !important;
background-clip: content-box !important;
}
html.custom_scroll ::-webkit-scrollbar-thumb:hover {
background-color: var(--td-scroll-bar-bg-over) !important;
}
#map {
position: relative;
width: 100%;
height: 100%;
}
#marker {
pointer-events: none;
display: none;
z-index: 2;
position: absolute;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
}
#marker_drop {
margin-bottom: 0px;
transition: margin 160ms ease-in-out;
}
#marker_drop.moving {
margin-bottom: 24px;
}
#marker_shadow {
position: absolute;
}
#search_venues {
position: absolute;
left: 50%;
transform: translateX(-50%);
z-index: 2;
top: -30px;
transition: top 200ms ease-in-out;
}
#search_venues.shown {
top: 6px;
}
#search_venues_inner {
position: relative;
overflow: hidden;
font-size: 13px;
font-weight: 500;
background: var(--td-window-bg);
color: var(--td-window-active-text-fg);
cursor: pointer;
border-radius: 14px;
padding: 5px 12px 6px;
box-shadow: 0 0 3px 0px var(--td-history-to-down-shadow);
}
#search_venues_inner:hover {
background: var(--td-window-bg-over);
}
#search_venues_content {
position: relative;
z-index: 2;
}
#search_venues_content:before {
content: var(--td-lng-maps-places-in-area);
}
#search_venues_inner .ripple .inner {
position: absolute;
border-radius: 50%;
transform: scale(0);
opacity: 1;
animation: ripple 650ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
background-color: var(--td-window-bg-ripple);
}
#search_venues_inner .ripple.hiding {
animation: fadeOut 200ms linear forwards;
}
@keyframes ripple {
to {
transform: scale(2);
}
}
@keyframes fadeOut {
to {
opacity: 0;
}
}

View File

@@ -0,0 +1,199 @@
var LocationPicker = {
startZoom: 14,
flySpeed: 2.4,
notify: function(message) {
if (window.external && window.external.invoke) {
window.external.invoke(JSON.stringify(message));
}
},
frameKeyDown: function (e) {
const keyW = (e.key === 'w')
|| (e.code === 'KeyW')
|| (e.keyCode === 87);
const keyQ = (e.key === 'q')
|| (e.code === 'KeyQ')
|| (e.keyCode === 81);
const keyM = (e.key === 'm')
|| (e.code === 'KeyM')
|| (e.keyCode === 77);
if ((e.metaKey || e.ctrlKey) && (keyW || keyQ || keyM)) {
e.preventDefault();
LocationPicker.notify({
event: 'keydown',
modifier: e.ctrlKey ? 'ctrl' : 'cmd',
key: keyW ? 'w' : keyQ ? 'q' : 'm',
});
} else if (e.key === 'Escape' || e.keyCode === 27) {
e.preventDefault();
LocationPicker.notify({
event: 'keydown',
key: 'escape',
});
}
},
isNight: function() {
var html = document.getElementsByTagName('html')[0];
return html.style.getPropertyValue('--td-night') == '1';
},
lightPreset: function() {
return LocationPicker.isNight() ? 'night' : 'day';
},
updateStyles: function (styles) {
if (LocationPicker.styles !== styles) {
LocationPicker.styles = styles;
document.getElementsByTagName('html')[0].style = styles;
LocationPicker.map.setConfigProperty(
'basemap',
'lightPreset',
LocationPicker.lightPreset());
}
},
init: function (params) {
mapboxgl.accessToken = params.token;
if (params.protocol) {
mapboxgl.config.API_URL = params.protocol + '://domain/api.mapbox.com';
}
var options = { container: 'map', config: {
basemap: { lightPreset: LocationPicker.lightPreset() }
} };
var center = params.center;
if (center) {
center = [center[1], center[0]];
options.center = center;
options.zoom = LocationPicker.startZoom;
} else if (params.bounds) {
options.bounds = params.bounds;
center = new mapboxgl.LngLatBounds(params.bounds).getCenter();
} else {
center = [0, 0];
}
LocationPicker.map = new mapboxgl.Map(options);
LocationPicker.createMarker(center);
LocationPicker.trackMovement();
LocationPicker.initSearchVenueRipple();
},
marker: function() {
return document.getElementById('marker_drop');
},
createMarker: function(center) {
document.getElementById('marker').style.display = 'flex';
},
clearMovingTimer: function() {
if (LocationPicker.clearMovingTimeoutId) {
clearTimeout(LocationPicker.clearMovingTimeoutId);
LocationPicker.clearMovingTimeoutId = 0;
}
},
startMovingTimer: function(done) {
LocationPicker.clearMovingTimer();
LocationPicker.clearMovingTimeoutId = setTimeout(done, 500);
},
trackMovement: function() {
LocationPicker.map.on('movestart', function() {
LocationPicker.marker().classList.add('moving');
LocationPicker.clearMovingTimer();
LocationPicker.toggleSearchVenues(false);
LocationPicker.notify({ event: 'move_start' });
});
LocationPicker.map.on('moveend', function() {
LocationPicker.startMovingTimer(function() {
LocationPicker.marker().classList.remove('moving');
LocationPicker.notify({
event: 'move_end',
latitude: LocationPicker.map.getCenter().lat,
longitude: LocationPicker.map.getCenter().lng
});
});
});
},
narrowTo: function (point) {
LocationPicker.map.flyTo({
center: [point[1], point[0]],
zoom: LocationPicker.startZoom,
speed: LocationPicker.flySpeed,
});
},
send: function () {
LocationPicker.notify({
event: 'send',
latitude: LocationPicker.map.getCenter().lat,
longitude: LocationPicker.map.getCenter().lng
});
},
addRipple: function (button, x, y) {
const ripple = document.createElement('span');
ripple.classList.add('ripple');
const inner = document.createElement('span');
inner.classList.add('inner');
var rect = button.getBoundingClientRect();
x -= rect.x;
y -= rect.y;
const mx = button.clientWidth - x;
const my = button.clientHeight - y;
const sq1 = x * x + y * y;
const sq2 = mx * mx + y * y;
const sq3 = x * x + my * my;
const sq4 = mx * mx + my * my;
const radius = Math.sqrt(Math.max(sq1, sq2, sq3, sq4));
inner.style.width = inner.style.height = `${2 * radius}px`;
inner.style.left = `${x - radius}px`;
inner.style.top = `${y - radius}px`;
inner.classList.add('inner');
ripple.addEventListener('animationend', function (e) {
if (e.animationName === 'fadeOut') {
ripple.remove();
}
});
ripple.appendChild(inner);
button.appendChild(ripple);
},
stopRipples: function (button) {
const id = button.id ? button.id : button;
button = document.getElementById(id);
const ripples = button.getElementsByClassName('ripple');
for (var i = 0; i < ripples.length; ++i) {
const ripple = ripples[i];
if (!ripple.classList.contains('hiding')) {
ripple.classList.add('hiding');
}
}
},
initSearchVenueRipple: function() {
var button = document.getElementById('search_venues_inner');
button.addEventListener('mousedown', function (e) {
LocationPicker.addRipple(e.currentTarget, e.clientX, e.clientY);
LocationPicker.searchVenuesPressed = true;
});
button.addEventListener('mouseup', function (e) {
const id = e.currentTarget.id;
setTimeout(function () {
LocationPicker.stopRipples(id);
}, 0);
if (LocationPicker.searchVenuesPressed) {
LocationPicker.searchVenuesPressed = false;
LocationPicker.toggleSearchVenues(false);
LocationPicker.notify({
event: 'search_venues',
latitude: LocationPicker.map.getCenter().lat,
longitude: LocationPicker.map.getCenter().lng
});
}
});
button.addEventListener('mouseleave', function (e) {
LocationPicker.stopRipples(e.currentTarget);
LocationPicker.searchVenuesPressed = false;
});
},
toggleSearchVenues: function(shown) {
var button = document.getElementById('search_venues');
button.classList.toggle('shown', shown);
},
};

View File

@@ -11,20 +11,41 @@
<file alias="ttl.tgs">../../animations/ttl.tgs</file>
<file alias="discussion.tgs">../../animations/discussion.tgs</file>
<file alias="stats.tgs">../../animations/stats.tgs</file>
<file alias="stats_boosts.tgs">../../animations/stats_boosts.tgs</file>
<file alias="stats_earn.tgs">../../animations/stats_earn.tgs</file>
<file alias="voice_ttl_idle.tgs">../../animations/voice_ttl_idle.tgs</file>
<file alias="voice_ttl_start.tgs">../../animations/voice_ttl_start.tgs</file>
<file alias="palette.tgs">../../animations/palette.tgs</file>
<file alias="sleep.tgs">../../animations/sleep.tgs</file>
<file alias="greeting.tgs">../../animations/greeting.tgs</file>
<file alias="location.tgs">../../animations/location.tgs</file>
<file alias="robot.tgs">../../animations/robot.tgs</file>
<file alias="writing.tgs">../../animations/writing.tgs</file>
<file alias="hours.tgs">../../animations/hours.tgs</file>
<file alias="phone.tgs">../../animations/phone.tgs</file>
<file alias="greeting.tgs">../../animations/greeting.tgs</file>
<file alias="location.tgs">../../animations/location.tgs</file>
<file alias="robot.tgs">../../animations/robot.tgs</file>
<file alias="writing.tgs">../../animations/writing.tgs</file>
<file alias="hours.tgs">../../animations/hours.tgs</file>
<file alias="phone.tgs">../../animations/phone.tgs</file>
<file alias="chat_link.tgs">../../animations/chat_link.tgs</file>
<file alias="collectible_username.tgs">../../animations/collectible_username.tgs</file>
<file alias="collectible_phone.tgs">../../animations/collectible_phone.tgs</file>
<file alias="search.tgs">../../animations/search.tgs</file>
<file alias="noresults.tgs">../../animations/noresults.tgs</file>
<file alias="dice_idle.tgs">../../animations/dice/dice_idle.tgs</file>
<file alias="dart_idle.tgs">../../animations/dice/dart_idle.tgs</file>
<file alias="bball_idle.tgs">../../animations/dice/bball_idle.tgs</file>
<file alias="fball_idle.tgs">../../animations/dice/fball_idle.tgs</file>
<file alias="slot_0_idle.tgs">../../animations/dice/slot_0_idle.tgs</file>
<file alias="slot_1_idle.tgs">../../animations/dice/slot_1_idle.tgs</file>
<file alias="slot_2_idle.tgs">../../animations/dice/slot_2_idle.tgs</file>
<file alias="slot_back.tgs">../../animations/dice/slot_back.tgs</file>
<file alias="slot_pull.tgs">../../animations/dice/slot_pull.tgs</file>
<file alias="winners.tgs">../../animations/dice/winners.tgs</file>
<file alias="star_reaction_appear.tgs">../../animations/star_reaction/appear.tgs</file>
<file alias="star_reaction_center.tgs">../../animations/star_reaction/center.tgs</file>
<file alias="star_reaction_select.tgs">../../animations/star_reaction/select.tgs</file>
<file alias="star_reaction_toast.tgs">../../animations/star_reaction/toast.tgs</file>
<file alias="star_reaction_effect1.tgs">../../animations/star_reaction/effect1.tgs</file>
<file alias="star_reaction_effect2.tgs">../../animations/star_reaction/effect2.tgs</file>
<file alias="star_reaction_effect3.tgs">../../animations/star_reaction/effect3.tgs</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/picker">
<file alias="picker.css">../../picker_html/picker.css</file>
<file alias="picker.js">../../picker_html/picker.js</file>
</qresource>
</RCC>

View File

@@ -7,16 +7,6 @@
<file alias="art/logo_256.png">../../art/logo_256.png</file>
<file alias="art/logo_256_no_margin.png">../../art/logo_256_no_margin.png</file>
<file alias="art/themeimage.jpg">../../art/themeimage.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="art/winners.tgs">../../art/winners.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>
@@ -40,6 +30,8 @@
<file alias="topic_icons/red.svg">../../art/topic_icons/red.svg</file>
<file alias="topic_icons/gray.svg">../../art/topic_icons/gray.svg</file>
<file alias="topic_icons/general.svg">../../art/topic_icons/general.svg</file>
<file alias="links_subscription.svg">../../icons/info/edit/links_subscription.svg</file>
<file alias="plane_white.svg">../../icons/plane_white.svg</file>
</qresource>
<qresource prefix="/icons">
<file alias="calls/hands.lottie">../../icons/calls/hands.lottie</file>

View File

@@ -10,7 +10,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="5.2.1.0" />
Version="5.5.3.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
@@ -38,6 +38,9 @@
<uap3:Extension Category="windows.protocol">
<uap3:Protocol Name="tg" Parameters="-- &quot;%1&quot;" />
</uap3:Extension>
<uap3:Extension Category="windows.protocol">
<uap3:Protocol Name="tonsite" Parameters="-- &quot;%1&quot;" />
</uap3:Extension>
<desktop:Extension
Category="windows.startupTask"
Executable="StartupTask.exe"

View File

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

View File

@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 5,2,1,0
PRODUCTVERSION 5,2,1,0
FILEVERSION 5,5,3,0
PRODUCTVERSION 5,5,3,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", "5.2.1.0"
VALUE "FileVersion", "5.5.3.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "5.2.1.0"
VALUE "ProductVersion", "5.5.3.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -155,6 +155,7 @@ int main(int argc, char *argv[])
QString remove;
int version = 0;
[[maybe_unused]] bool targetwin64 = false;
[[maybe_unused]] bool targetwinarm = false;
[[maybe_unused]] bool targetarmac = false;
QFileInfoList files;
for (int i = 0; i < argc; ++i) {
@@ -165,6 +166,7 @@ int main(int argc, char *argv[])
if (remove.isEmpty()) remove = info.canonicalPath() + "/";
} else if (string("-target") == argv[i] && i + 1 < argc) {
targetwin64 = (string("win64") == argv[i + 1]);
targetwinarm = (string("winarm") == argv[i + 1]);
} else if (string("-arch") == argv[i] && i + 1 < argc) {
targetarmac = (string("arm64") == argv[i + 1]);
if (!targetarmac && string("x86_64") != argv[i + 1]) {
@@ -493,7 +495,7 @@ int main(int argc, char *argv[])
cout << "Signature verified!\n";
RSA_free(pbKey);
#ifdef Q_OS_WIN
QString outName((targetwin64 ? QString("tx64upd%1") : QString("tupdate%1")).arg(AlphaVersion ? AlphaVersion : version));
QString outName((targetwinarm ? QString("tarm64upd%1") : targetwin64 ? QString("tx64upd%1") : QString("tupdate%1")).arg(AlphaVersion ? AlphaVersion : version));
#elif defined Q_OS_MAC
QString outName((targetarmac ? QString("tarmacupd%1") : QString("tmacupd%1")).arg(AlphaVersion ? AlphaVersion : version));
#else

View File

@@ -571,8 +571,8 @@ void _generateDump(EXCEPTION_POINTERS* pExceptionPointers) {
}
if (!hDumpFile || hDumpFile == INVALID_HANDLE_VALUE) {
WCHAR wstrPath[maxFileLen];
DWORD wstrPathLen;
if (wstrPathLen = GetEnvironmentVariable(L"APPDATA", wstrPath, maxFileLen)) {
DWORD wstrPathLen = GetEnvironmentVariable(L"APPDATA", wstrPath, maxFileLen);
if (wstrPathLen) {
wsprintf(wstrPath + wstrPathLen, L"\\%s\\", _programName);
hDumpFile = _generateDumpFileAtPath(wstrPath);
}

View File

@@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/url_auth_box.h"
#include "boxes/peers/choose_peer_box.h"
#include "lang/lang_keys.h"
#include "chat_helpers/bot_command.h"
#include "core/core_cloud_password.h"
#include "core/click_handler_types.h"
#include "data/data_changes.h"
@@ -127,11 +128,7 @@ void SendBotCallbackData(
UrlClickHandler::Open(link);
return;
}
const auto scoreLink = AppendShareGameScoreUrl(
session,
link,
item->fullId());
BotGameUrlClickHandler(bot, scoreLink).onClick({
BotGameUrlClickHandler(bot, link).onClick({
Qt::LeftButton,
QVariant::fromValue(ClickHandlerContext{
.itemId = item->fullId(),
@@ -492,20 +489,23 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
case ButtonType::WebView: {
if (const auto bot = item->getMessageBot()) {
bot->session().attachWebView().request(
controller,
Api::SendAction(bot->owner().history(bot)),
bot,
{ .text = button->text, .url = button->data });
bot->session().attachWebView().open({
.bot = bot,
.context = { .controller = controller },
.button = { .text = button->text, .url = button->data },
.source = InlineBots::WebViewSourceButton{ .simple = false },
});
}
} break;
case ButtonType::SimpleWebView: {
if (const auto bot = item->getMessageBot()) {
bot->session().attachWebView().requestSimple(
controller,
bot,
{ .text = button->text, .url = button->data });
bot->session().attachWebView().open({
.bot = bot,
.context = { .controller = controller },
.button = {.text = button->text, .url = button->data },
.source = InlineBots::WebViewSourceButton{ .simple = true },
});
}
} break;
}

View File

@@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h"
#include "ui/filter_icons.h"
#include "ui/vertical_list.h"
#include "ui/ui_utility.h"
#include "window/window_session_controller.h"
#include "styles/style_filter_icons.h"
#include "styles/style_layers.h"
@@ -231,12 +232,12 @@ void ImportInvite(
api->request(MTPchatlists_JoinChatlistInvite(
MTP_string(slug),
MTP_vector<MTPInputPeer>(std::move(inputs))
)).done(callback).fail(error).send();
)).done(callback).fail(error).handleFloodErrors().send();
} else {
api->request(MTPchatlists_JoinChatlistUpdates(
MTP_inputChatlistDialogFilter(MTP_int(filterId)),
MTP_vector<MTPInputPeer>(std::move(inputs))
)).done(callback).fail(error).send();
)).done(callback).fail(error).handleFloodErrors().send();
}
}
@@ -516,6 +517,8 @@ void ShowImportError(
} else {
window->showToast((error == u"INVITE_SLUG_EXPIRED"_q)
? tr::lng_group_invite_bad_link(tr::now)
: error.startsWith(u"FLOOD_WAIT_"_q)
? tr::lng_flood_error(tr::now)
: error);
}
}

View File

@@ -8,26 +8,39 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_chat_invite.h"
#include "apiwrap.h"
#include "window/window_session_controller.h"
#include "boxes/premium_limits_box.h"
#include "core/application.h"
#include "data/components/credits.h"
#include "data/data_channel.h"
#include "data/data_file_origin.h"
#include "data/data_forum.h"
#include "data/data_photo.h"
#include "data/data_photo_media.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "info/channel_statistics/boosts/giveaway/boost_badge.h"
#include "info/profile/info_profile_badge.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "ui/empty_userpic.h"
#include "ui/painter.h"
#include "core/application.h"
#include "data/data_session.h"
#include "data/data_photo.h"
#include "data/data_photo_media.h"
#include "data/data_channel.h"
#include "data/data_forum.h"
#include "data/data_user.h"
#include "data/data_file_origin.h"
#include "settings/settings_credits_graphics.h"
#include "ui/boxes/confirm_box.h"
#include "ui/controls/userpic_button.h"
#include "ui/effects/premium_graphics.h"
#include "ui/effects/premium_stars_colored.h"
#include "ui/empty_userpic.h"
#include "ui/layers/generic_box.h"
#include "ui/painter.h"
#include "ui/rect.h"
#include "ui/text/text_utilities.h"
#include "ui/toast/toast.h"
#include "boxes/premium_limits_box.h"
#include "ui/vertical_list.h"
#include "window/window_session_controller.h"
#include "styles/style_boxes.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_credits.h"
#include "styles/style_info.h"
#include "styles/style_layers.h"
#include "styles/style_premium.h"
namespace Api {
@@ -101,12 +114,237 @@ void SubmitChatInvite(
}).send();
}
void ConfirmSubscriptionBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session,
const QString &hash,
const MTPDchatInvite *data) {
box->setWidth(st::boxWideWidth);
const auto amount = data->vsubscription_pricing()->data().vamount().v;
const auto formId = data->vsubscription_form_id()->v;
const auto name = qs(data->vtitle());
const auto maybePhoto = session->data().processPhoto(data->vphoto());
const auto photo = maybePhoto->isNull() ? nullptr : maybePhoto.get();
struct State final {
std::shared_ptr<Data::PhotoMedia> photoMedia;
std::unique_ptr<Ui::EmptyUserpic> photoEmpty;
std::optional<MTP::Sender> api;
Ui::RpWidget* saveButton = nullptr;
rpl::variable<bool> loading;
};
const auto state = box->lifetime().make_state<State>();
const auto content = box->verticalLayout();
Ui::AddSkip(content, st::confirmInvitePhotoTop);
const auto userpicWrap = content->add(
object_ptr<Ui::CenterWrap<>>(
content,
object_ptr<Ui::RpWidget>(content)));
const auto userpic = userpicWrap->entity();
const auto photoSize = st::confirmInvitePhotoSize;
userpic->resize(Size(photoSize));
const auto options = Images::Option::RoundCircle;
userpic->paintRequest(
) | rpl::start_with_next([=, small = Data::PhotoSize::Small] {
auto p = QPainter(userpic);
if (state->photoMedia) {
if (const auto image = state->photoMedia->image(small)) {
p.drawPixmap(
0,
0,
image->pix(Size(photoSize), { .options = options }));
}
} else if (state->photoEmpty) {
state->photoEmpty->paintCircle(
p,
0,
0,
userpic->width(),
photoSize);
}
}, userpicWrap->lifetime());
userpicWrap->setAttribute(Qt::WA_TransparentForMouseEvents);
if (photo) {
state->photoMedia = photo->createMediaView();
state->photoMedia->wanted(Data::PhotoSize::Small, Data::FileOrigin());
if (!state->photoMedia->image(Data::PhotoSize::Small)) {
session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
userpic->update();
}, userpicWrap->entity()->lifetime());
}
} else {
state->photoEmpty = std::make_unique<Ui::EmptyUserpic>(
Ui::EmptyUserpic::UserpicColor(0),
name);
}
Ui::AddSkip(content);
Ui::AddSkip(content);
{
const auto widget = Ui::CreateChild<Ui::RpWidget>(content);
using ColoredMiniStars = Ui::Premium::ColoredMiniStars;
const auto stars = widget->lifetime().make_state<ColoredMiniStars>(
widget,
false,
Ui::Premium::MiniStars::Type::BiStars);
stars->setColorOverride(Ui::Premium::CreditsIconGradientStops());
widget->resize(
st::boxWideWidth - photoSize,
photoSize * 2);
content->sizeValue(
) | rpl::start_with_next([=](const QSize &size) {
widget->moveToLeft(photoSize / 2, 0);
const auto starsRect = Rect(widget->size());
stars->setPosition(starsRect.topLeft());
stars->setSize(starsRect.size());
widget->lower();
}, widget->lifetime());
widget->paintRequest(
) | rpl::start_with_next([=](const QRect &r) {
auto p = QPainter(widget);
p.fillRect(r, Qt::transparent);
stars->paint(p);
}, widget->lifetime());
}
box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
box,
object_ptr<Ui::FlatLabel>(
box,
tr::lng_channel_invite_subscription_title(),
st::inviteLinkSubscribeBoxTitle)));
box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
box,
object_ptr<Ui::FlatLabel>(
box,
tr::lng_channel_invite_subscription_about(
lt_channel,
rpl::single(Ui::Text::Bold(name)),
lt_price,
tr::lng_credits_summary_options_credits(
lt_count,
rpl::single(amount) | tr::to_count(),
Ui::Text::Bold),
Ui::Text::WithEntities),
st::inviteLinkSubscribeBoxAbout)));
Ui::AddSkip(content);
box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
box,
object_ptr<Ui::FlatLabel>(
box,
tr::lng_channel_invite_subscription_terms(
lt_link,
rpl::combine(
tr::lng_paid_react_agree_link(),
tr::lng_group_invite_subscription_about_url()
) | rpl::map([](const QString &text, const QString &url) {
return Ui::Text::Link(text, url);
}),
Ui::Text::RichLangValue),
st::inviteLinkSubscribeBoxTerms)));
{
const auto balance = Settings::AddBalanceWidget(
content,
session->credits().balanceValue(),
true);
session->credits().load(true);
rpl::combine(
balance->sizeValue(),
content->sizeValue()
) | rpl::start_with_next([=](const QSize &, const QSize &) {
balance->moveToRight(
st::creditsHistoryRightSkip * 2,
st::creditsHistoryRightSkip);
balance->update();
}, balance->lifetime());
}
const auto sendCredits = [=, weak = Ui::MakeWeak(box)] {
const auto show = box->uiShow();
const auto buttonWidth = state->saveButton
? state->saveButton->width()
: 0;
state->api->request(
MTPpayments_SendStarsForm(
MTP_flags(0),
MTP_long(formId),
MTP_inputInvoiceChatInviteSubscription(MTP_string(hash)))
).done([=](const MTPpayments_PaymentResult &result) {
state->api = std::nullopt;
state->loading.force_assign(false);
result.match([&](const MTPDpayments_paymentResult &data) {
session->api().applyUpdates(data.vupdates());
}, [](const MTPDpayments_paymentVerificationNeeded &data) {
});
if (weak) {
box->closeBox();
}
}).fail([=](const MTP::Error &error) {
const auto id = error.type();
if (weak) {
state->api = std::nullopt;
}
show->showToast(id);
state->loading.force_assign(false);
}).send();
if (state->saveButton) {
state->saveButton->resizeToWidth(buttonWidth);
}
};
auto confirmText = tr::lng_channel_invite_subscription_button();
state->saveButton = box->addButton(std::move(confirmText), [=] {
if (state->api) {
return;
}
state->api.emplace(&session->mtp());
state->loading.force_assign(true);
const auto done = [=](Settings::SmallBalanceResult result) {
if (result == Settings::SmallBalanceResult::Success
|| result == Settings::SmallBalanceResult::Already) {
sendCredits();
} else {
state->api = std::nullopt;
state->loading.force_assign(false);
}
};
Settings::MaybeRequestBalanceIncrease(
Main::MakeSessionShow(box->uiShow(), session),
amount,
Settings::SmallBalanceSubscription{ .name = name },
done);
});
if (const auto saveButton = state->saveButton) {
using namespace Info::Statistics;
const auto loadingAnimation = InfiniteRadialAnimationWidget(
saveButton,
saveButton->height() / 2,
&st::editStickerSetNameLoading);
AddChildToWidgetCenter(saveButton, loadingAnimation);
loadingAnimation->showOn(
state->loading.value() | rpl::map(rpl::mappers::_1));
}
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
}
} // namespace
void CheckChatInvite(
not_null<Window::SessionController*> controller,
const QString &hash,
ChannelData *invitePeekChannel) {
ChannelData *invitePeekChannel,
Fn<void()> loaded) {
const auto session = &controller->session();
const auto weak = base::make_weak(controller);
session->api().checkChatInvite(hash, [=](const MTPChatInvite &result) {
@@ -114,6 +352,9 @@ void CheckChatInvite(
if (!strong) {
return;
}
if (loaded) {
loaded();
}
Core::App().hideMediaView();
const auto show = [&](not_null<PeerData*> chat) {
const auto way = Window::SectionShow::Way::Forward;
@@ -125,11 +366,26 @@ void CheckChatInvite(
};
result.match([=](const MTPDchatInvite &data) {
const auto isGroup = !data.is_broadcast();
const auto box = strong->show(Box<ConfirmInviteBox>(
session,
data,
invitePeekChannel,
[=] { SubmitChatInvite(weak, session, hash, isGroup); }));
const auto hasPricing = !!data.vsubscription_pricing();
const auto canRefulfill = data.is_can_refulfill_subscription();
if (hasPricing
&& !canRefulfill
&& !data.vsubscription_form_id()) {
strong->uiShow()->showToast(
tr::lng_confirm_phone_link_invalid(tr::now));
return;
}
const auto box = (hasPricing && !canRefulfill)
? strong->show(Box(
ConfirmSubscriptionBox,
session,
hash,
&data))
: strong->show(Box<ConfirmInviteBox>(
session,
data,
invitePeekChannel,
[=] { SubmitChatInvite(weak, session, hash, isGroup); }));
if (invitePeekChannel) {
box->boxClosing(
) | rpl::filter([=] {

View File

@@ -38,7 +38,8 @@ namespace Api {
void CheckChatInvite(
not_null<Window::SessionController*> controller,
const QString &hash,
ChannelData *invitePeekChannel = nullptr);
ChannelData *invitePeekChannel = nullptr,
Fn<void()> loaded = nullptr);
} // namespace Api

View File

@@ -264,14 +264,24 @@ ChatParticipant::ChatParticipant(
_rank = qs(data.vrank().value_or_empty());
_rights = ChatAdminRightsInfo(data.vadmin_rights());
_by = peerToUser(peerFromUser(data.vpromoted_by()));
_date = data.vdate().v;
}, [&](const MTPDchannelParticipantSelf &data) {
_type = Type::Member;
_date = data.vdate().v;
_by = peerToUser(peerFromUser(data.vinviter_id()));
if (data.vsubscription_until_date()) {
_subscriptionDate = data.vsubscription_until_date()->v;
}
}, [&](const MTPDchannelParticipant &data) {
_type = Type::Member;
_date = data.vdate().v;
if (data.vsubscription_until_date()) {
_subscriptionDate = data.vsubscription_until_date()->v;
}
}, [&](const MTPDchannelParticipantBanned &data) {
_restrictions = ChatRestrictionsInfo(data.vbanned_rights());
_by = peerToUser(peerFromUser(data.vkicked_by()));
_date = data.vdate().v;
_type = (_restrictions.flags & ChatRestriction::ViewMessages)
? Type::Banned
@@ -348,6 +358,24 @@ ChatAdminRightsInfo ChatParticipant::rights() const {
return _rights;
}
TimeId ChatParticipant::subscriptionDate() const {
return _subscriptionDate;
}
TimeId ChatParticipant::promotedSince() const {
return (_type == Type::Admin) ? _date : TimeId(0);
}
TimeId ChatParticipant::restrictedSince() const {
return (_type == Type::Restricted || _type == Type::Banned)
? _date
: TimeId(0);
}
TimeId ChatParticipant::memberSince() const {
return (_type == Type::Member) ? _date : TimeId(0);
}
ChatParticipant::Type ChatParticipant::type() const {
return _type;
}

View File

@@ -60,6 +60,11 @@ public:
ChatRestrictionsInfo restrictions() const;
ChatAdminRightsInfo rights() const;
TimeId subscriptionDate() const;
TimeId promotedSince() const;
TimeId restrictedSince() const;
TimeId memberSince() const;
Type type() const;
QString rank() const;
@@ -73,6 +78,8 @@ private:
bool _canBeEdited = false;
QString _rank;
TimeId _subscriptionDate = 0;
TimeId _date = 0;
ChatRestrictionsInfo _restrictions;
ChatAdminRightsInfo _rights;

View File

@@ -12,6 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/core_cloud_password.h"
#include "passport/passport_encryption.h"
#include "base/unixtime.h"
#include "base/call_delayed.h"
namespace Api {
namespace {

View File

@@ -30,6 +30,10 @@ struct SendOptions {
bool invertCaption = false;
bool hideViaBot = false;
crl::time ttlSeconds = 0;
friend inline bool operator==(
const SendOptions &,
const SendOptions &) = default;
};
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();
@@ -52,6 +56,10 @@ struct SendAction {
MsgId replaceMediaOf = 0;
[[nodiscard]] MTPInputReplyTo mtpReplyTo() const;
friend inline bool operator==(
const SendAction &,
const SendAction &) = default;
};
struct MessageToSend {

View File

@@ -79,6 +79,8 @@ constexpr auto kTransactionsLimit = 100;
.credits = tl.data().vstars().v,
.bareMsgId = uint64(tl.data().vmsg_id().value_or_empty()),
.barePeerId = barePeerId,
.bareGiveawayMsgId = uint64(
tl.data().vgiveaway_post_id().value_or_empty()),
.peerType = tl.data().vpeer().match([](const HistoryPeerTL &) {
return Data::CreditsHistoryEntry::PeerType::Peer;
}, [](const MTPDstarsTransactionPeerPlayMarket &) {
@@ -94,31 +96,70 @@ constexpr auto kTransactionsLimit = 100;
}, [](const MTPDstarsTransactionPeerAds &) {
return Data::CreditsHistoryEntry::PeerType::Ads;
}),
.refunded = tl.data().is_refund(),
.pending = tl.data().is_pending(),
.failed = tl.data().is_failed(),
.subscriptionUntil = tl.data().vsubscription_period()
? base::unixtime::parse(base::unixtime::now()
+ tl.data().vsubscription_period()->v)
: QDateTime(),
.successDate = tl.data().vtransaction_date()
? base::unixtime::parse(tl.data().vtransaction_date()->v)
: QDateTime(),
.successLink = qs(tl.data().vtransaction_url().value_or_empty()),
.reaction = tl.data().is_reaction(),
.refunded = tl.data().is_refund(),
.pending = tl.data().is_pending(),
.failed = tl.data().is_failed(),
.in = (int64(tl.data().vstars().v) >= 0),
.gift = tl.data().is_gift(),
};
}
[[nodiscard]] Data::SubscriptionEntry SubscriptionFromTL(
const MTPStarsSubscription &tl) {
return Data::SubscriptionEntry{
.id = qs(tl.data().vid()),
.inviteHash = qs(tl.data().vchat_invite_hash().value_or_empty()),
.until = base::unixtime::parse(tl.data().vuntil_date().v),
.subscription = Data::PeerSubscription{
.credits = tl.data().vpricing().data().vamount().v,
.period = tl.data().vpricing().data().vperiod().v,
},
.barePeerId = peerFromMTP(tl.data().vpeer()).value,
.cancelled = tl.data().is_canceled(),
.expired = (base::unixtime::now() > tl.data().vuntil_date().v),
.canRefulfill = tl.data().is_can_refulfill(),
};
}
[[nodiscard]] Data::CreditsStatusSlice StatusFromTL(
const MTPpayments_StarsStatus &status,
not_null<PeerData*> peer) {
peer->owner().processUsers(status.data().vusers());
peer->owner().processChats(status.data().vchats());
const auto &data = status.data();
peer->owner().processUsers(data.vusers());
peer->owner().processChats(data.vchats());
auto entries = std::vector<Data::CreditsHistoryEntry>();
if (const auto history = data.vhistory()) {
entries.reserve(history->v.size());
for (const auto &tl : history->v) {
entries.push_back(HistoryFromTL(tl, peer));
}
}
auto subscriptions = std::vector<Data::SubscriptionEntry>();
if (const auto history = data.vsubscriptions()) {
subscriptions.reserve(history->v.size());
for (const auto &tl : history->v) {
subscriptions.push_back(SubscriptionFromTL(tl));
}
}
return Data::CreditsStatusSlice{
.list = ranges::views::all(
status.data().vhistory().v
) | ranges::views::transform([&](const MTPStarsTransaction &tl) {
return HistoryFromTL(tl, peer);
}) | ranges::to_vector,
.list = std::move(entries),
.subscriptions = std::move(subscriptions),
.balance = status.data().vbalance().v,
.subscriptionsMissingBalance
= status.data().vsubscriptions_missing_balance().value_or_empty(),
.allLoaded = !status.data().vnext_offset().has_value(),
.token = qs(status.data().vnext_offset().value_or_empty()),
.tokenSubscriptions = qs(
status.data().vsubscriptions_next_offset().value_or_empty()),
};
}
@@ -133,12 +174,12 @@ rpl::producer<rpl::no_value, QString> CreditsTopupOptions::request() {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
using TLOption = MTPStarsTopupOption;
_api.request(MTPpayments_GetStarsTopupOptions(
)).done([=](const MTPVector<TLOption> &result) {
_options = ranges::views::all(
result.v
) | ranges::views::transform([](const TLOption &option) {
const auto giftBarePeerId = !_peer->isSelf() ? _peer->id.value : 0;
const auto optionsFromTL = [giftBarePeerId](const auto &options) {
return ranges::views::all(
options
) | ranges::views::transform([=](const auto &option) {
return Data::CreditTopupOption{
.credits = option.data().vstars().v,
.product = qs(
@@ -146,17 +187,40 @@ rpl::producer<rpl::no_value, QString> CreditsTopupOptions::request() {
.currency = qs(option.data().vcurrency()),
.amount = option.data().vamount().v,
.extended = option.data().is_extended(),
.giftBarePeerId = giftBarePeerId,
};
}) | ranges::to_vector;
consumer.put_done();
}).fail([=](const MTP::Error &error) {
};
const auto fail = [=](const MTP::Error &error) {
consumer.put_error_copy(error.type());
}).send();
};
if (_peer->isSelf()) {
using TLOption = MTPStarsTopupOption;
_api.request(MTPpayments_GetStarsTopupOptions(
)).done([=](const MTPVector<TLOption> &result) {
_options = optionsFromTL(result.v);
consumer.put_done();
}).fail(fail).send();
} else if (const auto user = _peer->asUser()) {
using TLOption = MTPStarsGiftOption;
_api.request(MTPpayments_GetStarsGiftOptions(
MTP_flags(MTPpayments_GetStarsGiftOptions::Flag::f_user_id),
user->inputUser
)).done([=](const MTPVector<TLOption> &result) {
_options = optionsFromTL(result.v);
consumer.put_done();
}).fail(fail).send();
}
return lifetime;
};
}
Data::CreditTopupOptions CreditsTopupOptions::options() const {
return _options;
}
CreditsStatus::CreditsStatus(not_null<PeerData*> peer)
: _peer(peer)
, _api(&peer->session().api().instance()) {
@@ -175,10 +239,14 @@ void CreditsStatus::request(
_peer->isSelf() ? MTP_inputPeerSelf() : _peer->input
)).done([=](const TLResult &result) {
_requestId = 0;
done(StatusFromTL(result, _peer));
if (const auto onstack = done) {
onstack(StatusFromTL(result, _peer));
}
}).fail([=] {
_requestId = 0;
done({});
if (const auto onstack = done) {
onstack({});
}
}).send();
}
@@ -200,6 +268,7 @@ void CreditsHistory::request(
}
_requestId = _api.request(MTPpayments_GetStarsTransactions(
MTP_flags(_flags),
MTPstring(), // subscription_id
_peer->isSelf() ? MTP_inputPeerSelf() : _peer->input,
MTP_string(token),
MTP_int(kTransactionsLimit)
@@ -212,8 +281,23 @@ void CreditsHistory::request(
}).send();
}
Data::CreditTopupOptions CreditsTopupOptions::options() const {
return _options;
void CreditsHistory::requestSubscriptions(
const Data::CreditsStatusSlice::OffsetToken &token,
Fn<void(Data::CreditsStatusSlice)> done) {
if (_requestId) {
return;
}
_requestId = _api.request(MTPpayments_GetStarsSubscriptions(
MTP_flags(0),
_peer->isSelf() ? MTP_inputPeerSelf() : _peer->input,
MTP_string(token)
)).done([=](const MTPpayments_StarsStatus &result) {
_requestId = 0;
done(StatusFromTL(result, _peer));
}).fail([=] {
_requestId = 0;
done({});
}).send();
}
rpl::producer<not_null<PeerData*>> PremiumPeerBot(
@@ -303,4 +387,58 @@ Data::CreditsEarnStatistics CreditsEarnStatistics::data() const {
return _data;
}
CreditsGiveawayOptions::CreditsGiveawayOptions(not_null<PeerData*> peer)
: _peer(peer)
, _api(&peer->session().api().instance()) {
}
rpl::producer<rpl::no_value, QString> CreditsGiveawayOptions::request() {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
using TLOption = MTPStarsGiveawayOption;
const auto optionsFromTL = [=](const auto &options) {
return ranges::views::all(
options
) | ranges::views::transform([=](const auto &option) {
return Data::CreditsGiveawayOption{
.winners = ranges::views::all(
option.data().vwinners().v
) | ranges::views::transform([](const auto &winner) {
return Data::CreditsGiveawayOption::Winner{
.users = winner.data().vusers().v,
.perUserStars = winner.data().vper_user_stars().v,
.isDefault = winner.data().is_default(),
};
}) | ranges::to_vector,
.storeProduct = qs(
option.data().vstore_product().value_or_empty()),
.currency = qs(option.data().vcurrency()),
.amount = option.data().vamount().v,
.credits = option.data().vstars().v,
.yearlyBoosts = option.data().vyearly_boosts().v,
.isExtended = option.data().is_extended(),
.isDefault = option.data().is_default(),
};
}) | ranges::to_vector;
};
const auto fail = [=](const MTP::Error &error) {
consumer.put_error_copy(error.type());
};
_api.request(MTPpayments_GetStarsGiveawayOptions(
)).done([=](const MTPVector<TLOption> &result) {
_options = optionsFromTL(result.v);
consumer.put_done();
}).fail(fail).send();
return lifetime;
};
}
Data::CreditsGiveawayOptions CreditsGiveawayOptions::options() const {
return _options;
}
} // namespace Api

View File

@@ -36,6 +36,22 @@ private:
};
class CreditsGiveawayOptions final {
public:
CreditsGiveawayOptions(not_null<PeerData*> peer);
[[nodiscard]] rpl::producer<rpl::no_value, QString> request();
[[nodiscard]] Data::CreditsGiveawayOptions options() const;
private:
const not_null<PeerData*> _peer;
Data::CreditsGiveawayOptions _options;
MTP::Sender _api;
};
class CreditsStatus final {
public:
CreditsStatus(not_null<PeerData*> peer);
@@ -60,6 +76,9 @@ public:
void request(
const Data::CreditsStatusSlice::OffsetToken &token,
Fn<void(Data::CreditsStatusSlice)> done);
void requestSubscriptions(
const Data::CreditsStatusSlice::OffsetToken &token,
Fn<void(Data::CreditsStatusSlice)> done);
private:
using HistoryTL = MTPpayments_GetStarsTransactions;

View File

@@ -128,7 +128,7 @@ mtpRequestId EditMessage(
}
if (updateRecentStickers) {
api->requestRecentStickersForce(true);
api->requestSpecialStickersForce(false, false, true);
}
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
if constexpr (ErrorWithId<FailCallback>) {
@@ -153,9 +153,7 @@ mtpRequestId EditMessage(
const auto &text = item->originalText();
const auto webpage = (!item->media() || !item->media()->webpage())
? Data::WebPageDraft{ .removed = true }
: Data::WebPageDraft{
.id = item->media()->webpage()->id,
};
: Data::WebPageDraft::FromItem(item);
return EditMessage(
item,
text,

View File

@@ -115,6 +115,28 @@ rpl::producer<bool> GlobalPrivacy::newRequirePremium() const {
return _newRequirePremium.value();
}
void GlobalPrivacy::loadPaidReactionAnonymous() {
if (_paidReactionAnonymousLoaded) {
return;
}
_paidReactionAnonymousLoaded = true;
_api.request(MTPmessages_GetPaidReactionPrivacy(
)).done([=](const MTPUpdates &result) {
_session->api().applyUpdates(result);
}).send();
}
void GlobalPrivacy::updatePaidReactionAnonymous(bool value) {
_paidReactionAnonymous = value;
}
bool GlobalPrivacy::paidReactionAnonymousCurrent() const {
return _paidReactionAnonymous.current();
}
rpl::producer<bool> GlobalPrivacy::paidReactionAnonymous() const {
return _paidReactionAnonymous.value();
}
void GlobalPrivacy::updateArchiveAndMute(bool value) {
update(

View File

@@ -49,6 +49,11 @@ public:
[[nodiscard]] bool newRequirePremiumCurrent() const;
[[nodiscard]] rpl::producer<bool> newRequirePremium() const;
void loadPaidReactionAnonymous();
void updatePaidReactionAnonymous(bool value);
[[nodiscard]] bool paidReactionAnonymousCurrent() const;
[[nodiscard]] rpl::producer<bool> paidReactionAnonymous() const;
private:
void apply(const MTPGlobalPrivacySettings &data);
@@ -67,7 +72,9 @@ private:
rpl::variable<bool> _showArchiveAndMute = false;
rpl::variable<bool> _hideReadTime = false;
rpl::variable<bool> _newRequirePremium = false;
rpl::variable<bool> _paidReactionAnonymous = false;
std::vector<Fn<void()>> _callbacks;
bool _paidReactionAnonymousLoaded = false;
};

View File

@@ -8,12 +8,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_invite_links.h"
#include "api/api_chat_participants.h"
#include "data/data_peer.h"
#include "data/data_user.h"
#include "data/data_chat.h"
#include "data/data_channel.h"
#include "data/data_session.h"
#include "data/data_changes.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "main/main_session.h"
#include "base/unixtime.h"
#include "apiwrap.h"
@@ -69,59 +69,46 @@ JoinedByLinkSlice ParseJoinedByLinkSlice(
InviteLinks::InviteLinks(not_null<ApiWrap*> api) : _api(api) {
}
void InviteLinks::create(
not_null<PeerData*> peer,
Fn<void(Link)> done,
const QString &label,
TimeId expireDate,
int usageLimit,
bool requestApproval) {
performCreate(
peer,
std::move(done),
false,
label,
expireDate,
usageLimit,
requestApproval);
void InviteLinks::create(const CreateInviteLinkArgs &args) {
performCreate(args, false);
}
void InviteLinks::performCreate(
not_null<PeerData*> peer,
Fn<void(Link)> done,
bool revokeLegacyPermanent,
const QString &label,
TimeId expireDate,
int usageLimit,
bool requestApproval) {
if (const auto i = _createCallbacks.find(peer)
const CreateInviteLinkArgs &args,
bool revokeLegacyPermanent) {
if (const auto i = _createCallbacks.find(args.peer)
; i != end(_createCallbacks)) {
if (done) {
i->second.push_back(std::move(done));
if (args.done) {
i->second.push_back(std::move(args.done));
}
return;
}
auto &callbacks = _createCallbacks[peer];
if (done) {
callbacks.push_back(std::move(done));
auto &callbacks = _createCallbacks[args.peer];
if (args.done) {
callbacks.push_back(std::move(args.done));
}
const auto requestApproval = !args.subscription && args.requestApproval;
using Flag = MTPmessages_ExportChatInvite::Flag;
_api->request(MTPmessages_ExportChatInvite(
MTP_flags((revokeLegacyPermanent
? Flag::f_legacy_revoke_permanent
: Flag(0))
| (!label.isEmpty() ? Flag::f_title : Flag(0))
| (expireDate ? Flag::f_expire_date : Flag(0))
| ((!requestApproval && usageLimit)
| (!args.label.isEmpty() ? Flag::f_title : Flag(0))
| (args.expireDate ? Flag::f_expire_date : Flag(0))
| ((!requestApproval && args.usageLimit)
? Flag::f_usage_limit
: Flag(0))
| (requestApproval ? Flag::f_request_needed : Flag(0))),
peer->input,
MTP_int(expireDate),
MTP_int(usageLimit),
MTP_string(label)
)).done([=](const MTPExportedChatInvite &result) {
| (requestApproval ? Flag::f_request_needed : Flag(0))
| (args.subscription ? Flag::f_subscription_pricing : Flag(0))),
args.peer->input,
MTP_int(args.expireDate),
MTP_int(args.usageLimit),
MTP_string(args.label),
MTP_starsSubscriptionPricing(
MTP_int(args.subscription.period),
MTP_long(args.subscription.credits))
)).done([=, peer = args.peer](const MTPExportedChatInvite &result) {
const auto callbacks = _createCallbacks.take(peer);
const auto link = prepend(peer, peer->session().user(), result);
if (link && callbacks) {
@@ -129,7 +116,7 @@ void InviteLinks::performCreate(
callback(*link);
}
}
}).fail([=] {
}).fail([=, peer = args.peer] {
_createCallbacks.erase(peer);
}).send();
}
@@ -238,6 +225,15 @@ void InviteLinks::edit(
requestApproval);
}
void InviteLinks::editTitle(
not_null<PeerData*> peer,
not_null<UserData*> admin,
const QString &link,
const QString &label,
Fn<void(Link)> done) {
performEdit(peer, admin, link, done, false, label, 0, 0, false, true);
}
void InviteLinks::performEdit(
not_null<PeerData*> peer,
not_null<UserData*> admin,
@@ -247,7 +243,8 @@ void InviteLinks::performEdit(
const QString &label,
TimeId expireDate,
int usageLimit,
bool requestApproval) {
bool requestApproval,
bool editOnlyTitle) {
const auto key = LinkKey{ peer, link };
if (_deleteCallbacks.contains(key)) {
return;
@@ -272,7 +269,7 @@ void InviteLinks::performEdit(
? Flag::f_request_needed
: Flag(0));
_api->request(MTPmessages_EditExportedChatInvite(
MTP_flags(flags),
MTP_flags(editOnlyTitle ? Flag::f_title : flags),
peer->input,
MTP_string(link),
MTP_int(expireDate),
@@ -344,7 +341,7 @@ void InviteLinks::revokePermanent(
} else if (!admin->isSelf()) {
crl::on_main(&peer->session(), done);
} else {
performCreate(peer, callback, true);
performCreate({ peer, callback }, true);
}
}
@@ -750,6 +747,12 @@ auto InviteLinks::parse(
return std::optional<Link>(Link{
.link = qs(data.vlink()),
.label = qs(data.vtitle().value_or_empty()),
.subscription = data.vsubscription_pricing()
? Data::PeerSubscription{
data.vsubscription_pricing()->data().vamount().v,
data.vsubscription_pricing()->data().vperiod().v,
}
: Data::PeerSubscription(),
.admin = peer->session().data().user(data.vadmin_id()),
.date = data.vdate().v,
.startDate = data.vstart_date().value_or_empty(),

View File

@@ -9,11 +9,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class ApiWrap;
#include "data/data_subscriptions.h"
namespace Api {
struct InviteLink {
QString link;
QString label;
Data::PeerSubscription subscription;
not_null<UserData*> admin;
TimeId date = 0;
TimeId startDate = 0;
@@ -53,6 +56,16 @@ struct InviteLinkUpdate {
not_null<PeerData*> peer,
const MTPmessages_ChatInviteImporters &slice);
struct CreateInviteLinkArgs {
not_null<PeerData*> peer;
Fn<void(InviteLink)> done = nullptr;
QString label;
TimeId expireDate = 0;
int usageLimit = 0;
bool requestApproval = false;
Data::PeerSubscription subscription;
};
class InviteLinks final {
public:
explicit InviteLinks(not_null<ApiWrap*> api);
@@ -61,13 +74,7 @@ public:
using Links = PeerInviteLinks;
using Update = InviteLinkUpdate;
void create(
not_null<PeerData*> peer,
Fn<void(Link)> done = nullptr,
const QString &label = QString(),
TimeId expireDate = 0,
int usageLimit = 0,
bool requestApproval = false);
void create(const CreateInviteLinkArgs &args);
void edit(
not_null<PeerData*> peer,
not_null<UserData*> admin,
@@ -77,6 +84,12 @@ public:
int usageLimit,
bool requestApproval,
Fn<void(Link)> done = nullptr);
void editTitle(
not_null<PeerData*> peer,
not_null<UserData*> admin,
const QString &link,
const QString &label,
Fn<void(Link)> done = nullptr);
void revoke(
not_null<PeerData*> peer,
not_null<UserData*> admin,
@@ -187,15 +200,11 @@ private:
const QString &label = QString(),
TimeId expireDate = 0,
int usageLimit = 0,
bool requestApproval = false);
bool requestApproval = false,
bool editOnlyTitle = false);
void performCreate(
not_null<PeerData*> peer,
Fn<void(Link)> done,
bool revokeLegacyPermanent,
const QString &label = QString(),
TimeId expireDate = 0,
int usageLimit = 0,
bool requestApproval = false);
const CreateInviteLinkArgs &args,
bool revokeLegacyPermanent);
void requestJoinedFirstSlice(LinkKey key);
[[nodiscard]] std::optional<JoinedByLinkSlice> lookupJoinedFirstSlice(

View File

@@ -36,7 +36,8 @@ MTPVector<MTPDocumentAttribute> ComposeSendingDocumentAttributes(
MTP_double(document->duration() / 1000.),
MTP_int(dimensions.width()),
MTP_int(dimensions.height()),
MTPint())); // preload_prefix_size
MTPint(), // preload_prefix_size
MTPdouble())); // video_start_ts
} else {
attributes.push_back(MTP_documentAttributeImageSize(
MTP_int(dimensions.width()),

View File

@@ -39,9 +39,9 @@ namespace {
};
}
[[nodiscard]] Data::SubscriptionOptions GiftCodesFromTL(
[[nodiscard]] Data::PremiumSubscriptionOptions GiftCodesFromTL(
const QVector<MTPPremiumGiftCodeOption> &tlOptions) {
auto options = SubscriptionOptionsFromTL(tlOptions);
auto options = PremiumSubscriptionOptionsFromTL(tlOptions);
for (auto i = 0; i < options.size(); i++) {
const auto &tlOption = tlOptions[i].data();
const auto perUserText = Ui::FillAmountAndCurrency(
@@ -143,7 +143,7 @@ void Premium::reloadPromo() {
const auto &data = result.data();
_session->data().processUsers(data.vusers());
_subscriptionOptions = SubscriptionOptionsFromTL(
_subscriptionOptions = PremiumSubscriptionOptionsFromTL(
data.vperiod_options().v);
for (const auto &option : data.vperiod_options().v) {
if (option.data().vmonths().v == 1) {
@@ -361,9 +361,10 @@ void Premium::resolveGiveawayInfo(
? GiveawayState::Refunded
: GiveawayState::Finished;
info.giftCode = qs(data.vgift_code_slug().value_or_empty());
info.activatedCount = data.vactivated_count().v;
info.activatedCount = data.vactivated_count().value_or_empty();
info.finishDate = data.vfinish_date().v;
info.startDate = data.vstart_date().v;
info.credits = data.vstars_prize().value_or_empty();
});
_giveawayInfoDone(std::move(info));
}).fail([=] {
@@ -372,7 +373,7 @@ void Premium::resolveGiveawayInfo(
}).send();
}
const Data::SubscriptionOptions &Premium::subscriptionOptions() const {
const Data::PremiumSubscriptionOptions &Premium::subscriptionOptions() const {
return _subscriptionOptions;
}
@@ -508,7 +509,9 @@ rpl::producer<rpl::no_value, QString> PremiumGiftCodeOptions::applyPrepaid(
_api.request(MTPpayments_LaunchPrepaidGiveaway(
_peer->input,
MTP_long(prepaidId),
Payments::InvoicePremiumGiftCodeGiveawayToTL(invoice)
invoice.creditsAmount
? Payments::InvoiceCreditsGiveawayToTL(invoice)
: Payments::InvoicePremiumGiftCodeGiveawayToTL(invoice)
)).done([=](const MTPUpdates &result) {
_peer->session().api().applyUpdates(result);
consumer.put_done();
@@ -537,17 +540,17 @@ Payments::InvoicePremiumGiftCode PremiumGiftCodeOptions::invoice(
const auto token = Token{ users, months };
const auto &store = _stores[token];
return Payments::InvoicePremiumGiftCode{
.randomId = randomId,
.currency = _optionsForOnePerson.currency,
.amount = store.amount,
.storeProduct = store.product,
.randomId = randomId,
.amount = store.amount,
.storeQuantity = store.quantity,
.users = token.users,
.months = token.months,
};
}
Data::SubscriptionOptions PremiumGiftCodeOptions::options(int amount) {
Data::PremiumSubscriptionOptions PremiumGiftCodeOptions::options(int amount) {
const auto it = _subscriptionOptions.find(amount);
if (it != end(_subscriptionOptions)) {
return it->second;

View File

@@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/data_subscription_option.h"
#include "data/data_premium_subscription_option.h"
#include "mtproto/sender.h"
class History;
@@ -57,6 +57,7 @@ struct GiveawayInfo {
TimeId tooEarlyDate = 0;
TimeId finishDate = 0;
TimeId startDate = 0;
uint64 credits = 0;
int winnersCount = 0;
int activatedCount = 0;
bool participating = false;
@@ -106,7 +107,7 @@ public:
Fn<void(GiveawayInfo)> done);
[[nodiscard]] auto subscriptionOptions() const
-> const Data::SubscriptionOptions &;
-> const Data::PremiumSubscriptionOptions &;
[[nodiscard]] rpl::producer<> somePremiumRequiredResolved() const;
void resolvePremiumRequired(not_null<UserData*> user);
@@ -156,7 +157,7 @@ private:
MsgId _giveawayInfoMessageId = 0;
Fn<void(GiveawayInfo)> _giveawayInfoDone;
Data::SubscriptionOptions _subscriptionOptions;
Data::PremiumSubscriptionOptions _subscriptionOptions;
rpl::event_stream<> _somePremiumRequiredResolved;
base::flat_set<not_null<UserData*>> _resolvePremiumRequiredUsers;
@@ -170,7 +171,7 @@ public:
PremiumGiftCodeOptions(not_null<PeerData*> peer);
[[nodiscard]] rpl::producer<rpl::no_value, QString> request();
[[nodiscard]] Data::SubscriptionOptions options(int amount);
[[nodiscard]] Data::PremiumSubscriptionOptions options(int amount);
[[nodiscard]] const std::vector<int> &availablePresets() const;
[[nodiscard]] int monthsFromPreset(int monthsIndex);
[[nodiscard]] Payments::InvoicePremiumGiftCode invoice(
@@ -200,8 +201,9 @@ private:
int quantity = 0;
};
using Amount = int;
using PremiumSubscriptionOptions = Data::PremiumSubscriptionOptions;
const not_null<PeerData*> _peer;
base::flat_map<Amount, Data::SubscriptionOptions> _subscriptionOptions;
base::flat_map<Amount, PremiumSubscriptionOptions> _subscriptionOptions;
struct {
std::vector<int> months;
std::vector<float64> totalCosts;

View File

@@ -13,7 +13,7 @@ namespace Api {
constexpr auto kDiscountDivider = 1.;
Data::SubscriptionOption CreateSubscriptionOption(
Data::PremiumSubscriptionOption CreateSubscriptionOption(
int months,
int monthlyAmount,
int64 amount,

View File

@@ -7,11 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/data_subscription_option.h"
#include "data/data_premium_subscription_option.h"
namespace Api {
[[nodiscard]] Data::SubscriptionOption CreateSubscriptionOption(
[[nodiscard]] Data::PremiumSubscriptionOption CreateSubscriptionOption(
int months,
int monthlyAmount,
int64 amount,
@@ -19,22 +19,22 @@ namespace Api {
const QString &botUrl);
template<typename Option>
[[nodiscard]] Data::SubscriptionOptions SubscriptionOptionsFromTL(
const QVector<Option> &tlOptions) {
if (tlOptions.isEmpty()) {
[[nodiscard]] auto PremiumSubscriptionOptionsFromTL(
const QVector<Option> &tlOpts) -> Data::PremiumSubscriptionOptions {
if (tlOpts.isEmpty()) {
return {};
}
auto result = Data::SubscriptionOptions();
auto result = Data::PremiumSubscriptionOptions();
const auto monthlyAmount = [&] {
const auto &min = ranges::min_element(
tlOptions,
tlOpts,
ranges::less(),
[](const Option &o) { return o.data().vamount().v; }
)->data();
return min.vamount().v / float64(min.vmonths().v);
}();
result.reserve(tlOptions.size());
for (const auto &tlOption : tlOptions) {
result.reserve(tlOpts.size());
for (const auto &tlOption : tlOpts) {
const auto &option = tlOption.data();
auto botUrl = QString();
if constexpr (!std::is_same_v<Option, MTPPremiumGiftCodeOption>) {

View File

@@ -41,14 +41,17 @@ void InnerFillMessagePostFlags(
const SendOptions &options,
not_null<PeerData*> peer,
MessageFlags &flags) {
const auto anonymousPost = peer->amAnonymous();
if (ShouldSendSilent(peer, options)) {
flags |= MessageFlag::Silent;
}
if (!anonymousPost || options.sendAs) {
if (!peer->amAnonymous()
|| (!peer->isBroadcast()
&& options.sendAs
&& options.sendAs != peer)) {
flags |= MessageFlag::HasFromId;
return;
} else if (peer->asMegagroup()) {
}
const auto channel = peer->asBroadcast();
if (!channel) {
return;
}
flags |= MessageFlag::Post;
@@ -57,11 +60,84 @@ void InnerFillMessagePostFlags(
return;
}
flags |= MessageFlag::HasViews;
if (peer->asChannel()->addsSignature()) {
if (channel->addsSignature()) {
flags |= MessageFlag::HasPostAuthor;
}
}
void SendSimpleMedia(SendAction action, MTPInputMedia inputMedia) {
const auto history = action.history;
const auto peer = history->peer;
const auto session = &history->session();
const auto api = &session->api();
action.clearDraft = false;
action.generateLocal = false;
api->sendAction(action);
const auto randomId = base::RandomValue<uint64>();
auto flags = NewMessageFlags(peer);
auto sendFlags = MTPmessages_SendMedia::Flags(0);
if (action.replyTo) {
flags |= MessageFlag::HasReplyInfo;
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
}
const auto silentPost = ShouldSendSilent(peer, action.options);
InnerFillMessagePostFlags(action.options, peer, flags);
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
const auto sendAs = action.options.sendAs;
if (sendAs) {
sendFlags |= MTPmessages_SendMedia::Flag::f_send_as;
}
const auto messagePostAuthor = peer->isBroadcast()
? session->user()->name()
: QString();
if (action.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled;
sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
}
if (action.options.shortcutId) {
flags |= MessageFlag::ShortcutMessage;
sendFlags |= MTPmessages_SendMedia::Flag::f_quick_reply_shortcut;
}
if (action.options.effectId) {
sendFlags |= MTPmessages_SendMedia::Flag::f_effect;
}
if (action.options.invertCaption) {
flags |= MessageFlag::InvertMedia;
sendFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
}
auto &histories = history->owner().histories();
histories.sendPreparedMessage(
history,
action.replyTo,
randomId,
Data::Histories::PrepareMessage<MTPmessages_SendMedia>(
MTP_flags(sendFlags),
peer->input,
Data::Histories::ReplyToPlaceholder(),
std::move(inputMedia),
MTPstring(),
MTP_long(randomId),
MTPReplyMarkup(),
MTPvector<MTPMessageEntity>(),
MTP_int(action.options.scheduled),
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
Data::ShortcutIdToMTP(session, action.options.shortcutId),
MTP_long(action.options.effectId)
), [=](const MTPUpdates &result, const MTP::Response &response) {
}, [=](const MTP::Error &error, const MTP::Response &response) {
api->sendMessageFail(error, peer, randomId);
});
api->finishForwarding(action);
}
template <typename MediaData>
void SendExistingMedia(
MessageToSend &&message,
@@ -92,25 +168,15 @@ void SendExistingMedia(
flags |= MessageFlag::HasReplyInfo;
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
}
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, action.options);
InnerFillMessagePostFlags(action.options, peer, flags);
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
const auto sendAs = action.options.sendAs;
const auto messageFromId = sendAs
? sendAs->id
: anonymousPost
? 0
: session->userPeerId();
if (sendAs) {
sendFlags |= MTPmessages_SendMedia::Flag::f_send_as;
}
const auto messagePostAuthor = peer->isBroadcast()
? session->user()->name()
: QString();
auto caption = TextWithEntities{
message.textWithTags.text,
TextUtilities::ConvertTextTagsToEntities(message.textWithTags.tags)
@@ -146,11 +212,11 @@ void SendExistingMedia(
history->addNewLocalMessage({
.id = newId.msg,
.flags = flags,
.from = messageFromId,
.from = NewMessageFromId(action),
.replyTo = action.replyTo,
.date = HistoryItem::NewMessageDate(action.options),
.date = NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.postAuthor = messagePostAuthor,
.postAuthor = NewMessagePostAuthor(action),
.effectId = action.options.effectId,
}, media, caption);
@@ -288,25 +354,15 @@ bool SendDice(MessageToSend &message) {
flags |= MessageFlag::HasReplyInfo;
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
}
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, action.options);
InnerFillMessagePostFlags(action.options, peer, flags);
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
const auto sendAs = action.options.sendAs;
const auto messageFromId = sendAs
? sendAs->id
: anonymousPost
? 0
: session->userPeerId();
if (sendAs) {
sendFlags |= MTPmessages_SendMedia::Flag::f_send_as;
}
const auto messagePostAuthor = peer->isBroadcast()
? session->user()->name()
: QString();
if (action.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled;
sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
@@ -328,11 +384,11 @@ bool SendDice(MessageToSend &message) {
history->addNewLocalMessage({
.id = newId.msg,
.flags = flags,
.from = messageFromId,
.from = NewMessageFromId(action),
.replyTo = action.replyTo,
.date = HistoryItem::NewMessageDate(action.options),
.date = NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.postAuthor = messagePostAuthor,
.postAuthor = NewMessagePostAuthor(action),
.effectId = action.options.effectId,
}, TextWithEntities(), MTP_messageMediaDice(
MTP_int(0),
@@ -362,6 +418,33 @@ bool SendDice(MessageToSend &message) {
return true;
}
void SendLocation(SendAction action, float64 lat, float64 lon) {
SendSimpleMedia(
action,
MTP_inputMediaGeoPoint(
MTP_inputGeoPoint(
MTP_flags(0),
MTP_double(lat),
MTP_double(lon),
MTPint()))); // accuracy_radius
}
void SendVenue(SendAction action, Data::InputVenue venue) {
SendSimpleMedia(
action,
MTP_inputMediaVenue(
MTP_inputGeoPoint(
MTP_flags(0),
MTP_double(venue.lat),
MTP_double(venue.lon),
MTPint()), // accuracy_radius
MTP_string(venue.title),
MTP_string(venue.address),
MTP_string(venue.provider),
MTP_string(venue.id),
MTP_string(venue.venueType)));
}
void FillMessagePostFlags(
const SendAction &action,
not_null<PeerData*> peer,
@@ -429,7 +512,6 @@ void SendConfirmedFile(
if (file->to.replyTo) {
flags |= MessageFlag::HasReplyInfo;
}
const auto anonymousPost = peer->amAnonymous();
FillMessagePostFlags(action, peer, flags);
if (file->to.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled;
@@ -451,16 +533,6 @@ void SendConfirmedFile(
if (file->to.options.invertCaption) {
flags |= MessageFlag::InvertMedia;
}
const auto messageFromId = file->to.options.sendAs
? file->to.options.sendAs->id
: anonymousPost
? PeerId()
: session->userPeerId();
const auto messagePostAuthor = peer->isBroadcast()
? session->user()->name()
: QString();
const auto media = MTPMessageMedia([&] {
if (file->type == SendMediaType::Photo) {
using Flag = MTPDmessageMediaPhoto::Flag;
@@ -526,11 +598,11 @@ void SendConfirmedFile(
history->addNewLocalMessage({
.id = newId.msg,
.flags = flags,
.from = messageFromId,
.from = NewMessageFromId(action),
.replyTo = file->to.replyTo,
.date = HistoryItem::NewMessageDate(file->to.options),
.date = NewMessageDate(file->to.options),
.shortcutId = file->to.options.shortcutId,
.postAuthor = messagePostAuthor,
.postAuthor = NewMessagePostAuthor(action),
.groupedId = groupId,
.effectId = file->to.options.effectId,
}, caption, media);

View File

@@ -7,15 +7,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Main {
class Session;
} // namespace Main
class History;
class PhotoData;
class DocumentData;
struct FilePrepareResult;
namespace Data {
struct InputVenue;
} // namespace Data
namespace Main {
class Session;
} // namespace Main
namespace Api {
struct MessageToSend;
@@ -33,6 +37,13 @@ void SendExistingPhoto(
bool SendDice(MessageToSend &message);
// We can't create Data::LocationPoint() and use it
// for a local sending message, because we can't request
// map thumbnail in messages history without access hash.
void SendLocation(SendAction action, float64 lat, float64 lon);
void SendVenue(SendAction action, Data::InputVenue venue);
void FillMessagePostFlags(
const SendAction &action,
not_null<PeerData*> peer,

View File

@@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Api {
namespace {
constexpr auto kRefreshAppConfigTimeout = 3 * crl::time(1000);
constexpr auto kRefreshAppConfigTimeout = crl::time(1);
} // namespace
@@ -24,19 +24,40 @@ SensitiveContent::SensitiveContent(not_null<ApiWrap*> api)
, _appConfigReloadTimer([=] { _session->appConfig().refresh(); }) {
}
void SensitiveContent::reload() {
if (_requestId) {
void SensitiveContent::preload() {
if (!_loaded) {
reload();
}
}
void SensitiveContent::reload(bool force) {
if (_loadRequestId) {
if (force) {
_loadPending = true;
}
return;
}
_requestId = _api.request(MTPaccount_GetContentSettings(
_loaded = true;
_loadRequestId = _api.request(MTPaccount_GetContentSettings(
)).done([=](const MTPaccount_ContentSettings &result) {
_requestId = 0;
result.match([&](const MTPDaccount_contentSettings &data) {
_enabled = data.is_sensitive_enabled();
_canChange = data.is_sensitive_can_change();
});
_loadRequestId = 0;
const auto &data = result.data();
const auto enabled = data.is_sensitive_enabled();
const auto canChange = data.is_sensitive_can_change();
const auto changed = (_enabled.current() != enabled)
|| (_canChange.current() != canChange);
if (changed) {
_enabled = enabled;
_canChange = canChange;
}
if (base::take(_appConfigReloadForce) || changed) {
_appConfigReloadTimer.callOnce(kRefreshAppConfigTimeout);
}
if (base::take(_loadPending)) {
reload();
}
}).fail([=] {
_requestId = 0;
_loadRequestId = 0;
}).send();
}
@@ -57,17 +78,24 @@ void SensitiveContent::update(bool enabled) {
return;
}
using Flag = MTPaccount_SetContentSettings::Flag;
_api.request(_requestId).cancel();
_requestId = _api.request(MTPaccount_SetContentSettings(
_api.request(_saveRequestId).cancel();
if (const auto load = base::take(_loadRequestId)) {
_api.request(load).cancel();
_loadPending = true;
}
const auto finish = [=] {
_saveRequestId = 0;
if (base::take(_loadPending)) {
_appConfigReloadForce = true;
reload(true);
} else {
_appConfigReloadTimer.callOnce(kRefreshAppConfigTimeout);
}
};
_saveRequestId = _api.request(MTPaccount_SetContentSettings(
MTP_flags(enabled ? Flag::f_sensitive_enabled : Flag(0))
)).done([=] {
_requestId = 0;
}).fail([=] {
_requestId = 0;
}).send();
)).done(finish).fail(finish).send();
_enabled = enabled;
_appConfigReloadTimer.callOnce(kRefreshAppConfigTimeout);
}
} // namespace Api

View File

@@ -22,7 +22,8 @@ class SensitiveContent final {
public:
explicit SensitiveContent(not_null<ApiWrap*> api);
void reload();
void preload();
void reload(bool force = false);
void update(bool enabled);
[[nodiscard]] bool enabledCurrent() const;
@@ -32,10 +33,14 @@ public:
private:
const not_null<Main::Session*> _session;
MTP::Sender _api;
mtpRequestId _requestId = 0;
mtpRequestId _loadRequestId = 0;
mtpRequestId _saveRequestId = 0;
rpl::variable<bool> _enabled = false;
rpl::variable<bool> _canChange = false;
base::Timer _appConfigReloadTimer;
bool _appConfigReloadForce = false;
bool _loadPending = false;
bool _loaded = false;
};

View File

@@ -571,13 +571,22 @@ rpl::producer<rpl::no_value, QString> Boosts::request() {
_boostStatus.prepaidGiveaway = ranges::views::all(
data.vprepaid_giveaways()->v
) | ranges::views::transform([](const MTPPrepaidGiveaway &r) {
return Data::BoostPrepaidGiveaway{
.months = r.data().vmonths().v,
.id = r.data().vid().v,
.quantity = r.data().vquantity().v,
.date = QDateTime::fromSecsSinceEpoch(
r.data().vdate().v),
};
return r.match([&](const MTPDprepaidGiveaway &data) {
return Data::BoostPrepaidGiveaway{
.date = base::unixtime::parse(data.vdate().v),
.id = data.vid().v,
.months = data.vmonths().v,
.quantity = data.vquantity().v,
};
}, [&](const MTPDprepaidStarsGiveaway &data) {
return Data::BoostPrepaidGiveaway{
.date = base::unixtime::parse(data.vdate().v),
.id = data.vid().v,
.credits = data.vstars().v,
.quantity = data.vquantity().v,
.boosts = data.vboosts().v,
};
});
}) | ranges::to_vector;
}
@@ -635,19 +644,21 @@ void Boosts::requestBoosts(
}
: Data::GiftCodeLink();
list.push_back({
data.is_gift(),
data.is_giveaway(),
data.is_unclaimed(),
qs(data.vid()),
data.vuser_id().value_or_empty(),
data.vgiveaway_msg_id()
.id = qs(data.vid()),
.userId = UserId(data.vuser_id().value_or_empty()),
.giveawayMessage = data.vgiveaway_msg_id()
? FullMsgId{ _peer->id, data.vgiveaway_msg_id()->v }
: FullMsgId(),
QDateTime::fromSecsSinceEpoch(data.vdate().v),
QDateTime::fromSecsSinceEpoch(data.vexpires().v),
(data.vexpires().v - data.vdate().v) / kMonthsDivider,
std::move(giftCodeLink),
data.vmultiplier().value_or_empty(),
.date = base::unixtime::parse(data.vdate().v),
.expiresAt = base::unixtime::parse(data.vexpires().v),
.expiresAfterMonths = ((data.vexpires().v - data.vdate().v)
/ kMonthsDivider),
.giftCodeLink = std::move(giftCodeLink),
.multiplier = data.vmultiplier().value_or_empty(),
.credits = data.vstars().value_or_empty(),
.isGift = data.is_gift(),
.isGiveaway = data.is_giveaway(),
.isUnclaimed = data.is_unclaimed(),
});
}
done(Data::BoostsListSlice{

View File

@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_authorizations.h"
#include "api/api_user_names.h"
#include "api/api_chat_participants.h"
#include "api/api_global_privacy.h"
#include "api/api_ringtones.h"
#include "api/api_text_entities.h"
#include "api/api_user_privacy.h"
@@ -21,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/mtproto_config.h"
#include "mtproto/mtproto_dc_options.h"
#include "data/business/data_shortcut_messages.h"
#include "data/components/credits.h"
#include "data/components/scheduled_messages.h"
#include "data/components/top_peers.h"
#include "data/notify/data_notify_settings.h"
@@ -2618,7 +2620,13 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateStarsBalance: {
const auto &data = update.c_updateStarsBalance();
_session->setCredits(data.vbalance().v);
_session->credits().apply(data);
} break;
case mtpc_updatePaidReactionPrivacy: {
const auto &data = update.c_updatePaidReactionPrivacy();
_session->api().globalPrivacy().updatePaidReactionAnonymous(
mtpIsTrue(data.vprivate()));
} break;
}

View File

@@ -214,7 +214,10 @@ struct State {
[[nodiscard]] QImage GenerateUserpic(Userpic &userpic, int size) {
size *= style::DevicePixelRatio();
auto result = userpic.peer->generateUserpicImage(userpic.view, size);
auto result = PeerData::GenerateUserpicImage(
userpic.peer,
userpic.view,
size);
result.setDevicePixelRatio(style::DevicePixelRatio());
return result;
}

View File

@@ -2585,7 +2585,7 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &resu
void ApiWrap::updateStickers() {
const auto now = crl::now();
requestStickers(now);
requestRecentStickers(now);
requestRecentStickers(now, false);
requestFavedStickers(now);
requestFeaturedStickers(now);
}
@@ -2607,8 +2607,15 @@ void ApiWrap::updateCustomEmoji() {
requestFeaturedEmoji(now);
}
void ApiWrap::requestRecentStickersForce(bool attached) {
requestRecentStickersWithHash(0, attached);
void ApiWrap::requestSpecialStickersForce(
bool faved,
bool recent,
bool attached) {
if (faved) {
requestFavedStickers(std::nullopt);
} else if (recent || attached) {
requestRecentStickers(std::nullopt, attached);
}
}
void ApiWrap::setGroupStickerSet(
@@ -2761,18 +2768,17 @@ void ApiWrap::requestCustomEmoji(TimeId now) {
}).send();
}
void ApiWrap::requestRecentStickers(TimeId now, bool attached) {
const auto needed = attached
? _session->data().stickers().recentAttachedUpdateNeeded(now)
: _session->data().stickers().recentUpdateNeeded(now);
void ApiWrap::requestRecentStickers(
std::optional<TimeId> now,
bool attached) {
const auto needed = !now
? true
: attached
? _session->data().stickers().recentAttachedUpdateNeeded(*now)
: _session->data().stickers().recentUpdateNeeded(*now);
if (!needed) {
return;
}
requestRecentStickersWithHash(
Api::CountRecentStickersHash(_session, attached), attached);
}
void ApiWrap::requestRecentStickersWithHash(uint64 hash, bool attached) {
const auto requestId = [=]() -> mtpRequestId & {
return attached
? _recentAttachedStickersUpdateRequest
@@ -2795,7 +2801,7 @@ void ApiWrap::requestRecentStickersWithHash(uint64 hash, bool attached) {
: MTPmessages_getRecentStickers::Flags(0);
requestId() = request(MTPmessages_GetRecentStickers(
MTP_flags(flags),
MTP_long(hash)
MTP_long(now ? Api::CountRecentStickersHash(_session, attached) : 0)
)).done([=](const MTPmessages_RecentStickers &result) {
finish();
@@ -2822,13 +2828,15 @@ void ApiWrap::requestRecentStickersWithHash(uint64 hash, bool attached) {
}).send();
}
void ApiWrap::requestFavedStickers(TimeId now) {
if (!_session->data().stickers().favedUpdateNeeded(now)
|| _favedStickersUpdateRequest) {
return;
void ApiWrap::requestFavedStickers(std::optional<TimeId> now) {
if (now) {
if (!_session->data().stickers().favedUpdateNeeded(*now)
|| _favedStickersUpdateRequest) {
return;
}
}
_favedStickersUpdateRequest = request(MTPmessages_GetFavedStickers(
MTP_long(Api::CountFavedStickersHash(_session))
MTP_long(now ? Api::CountFavedStickersHash(_session) : 0)
)).done([=](const MTPmessages_FavedStickers &result) {
_session->data().stickers().setLastFavedUpdate(crl::now());
_favedStickersUpdateRequest = 0;
@@ -3274,9 +3282,8 @@ void ApiWrap::forwardMessages(
if (!action.options.scheduled && !action.options.shortcutId) {
histories.readInbox(history);
}
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, action.options);
const auto sendAs = action.options.sendAs;
const auto silentPost = ShouldSendSilent(peer, action.options);
using SendFlag = MTPmessages_ForwardMessages::Flag;
auto flags = MessageFlags();
@@ -3367,23 +3374,14 @@ void ApiWrap::forwardMessages(
const auto newId = FullMsgId(
peer->id,
_session->data().nextLocalMessageId());
const auto self = _session->user();
const auto messageFromId = sendAs
? sendAs->id
: anonymousPost
? PeerId(0)
: self->id;
const auto messagePostAuthor = peer->isBroadcast()
? self->name()
: QString();
history->addNewLocalMessage({
.id = newId.msg,
.flags = flags,
.from = messageFromId,
.from = NewMessageFromId(action),
.replyTo = { .topicRootId = topMsgId },
.date = HistoryItem::NewMessageDate(action.options),
.date = NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.postAuthor = messagePostAuthor,
.postAuthor = NewMessagePostAuthor(action),
// forwarded messages don't have effects
//.effectId = action.options.effectId,
@@ -3458,8 +3456,6 @@ void ApiWrap::sendSharedContact(
const auto newId = FullMsgId(
peer->id,
_session->data().nextLocalMessageId());
const auto anonymousPost = peer->amAnonymous();
auto flags = NewMessageFlags(peer);
if (action.replyTo) {
flags |= MessageFlag::HasReplyInfo;
@@ -3471,22 +3467,14 @@ void ApiWrap::sendSharedContact(
if (action.options.shortcutId) {
flags |= MessageFlag::ShortcutMessage;
}
const auto messageFromId = action.options.sendAs
? action.options.sendAs->id
: anonymousPost
? PeerId()
: _session->userPeerId();
const auto messagePostAuthor = peer->isBroadcast()
? _session->user()->name()
: QString();
const auto item = history->addNewLocalMessage({
.id = newId.msg,
.flags = flags,
.from = messageFromId,
.from = NewMessageFromId(action),
.replyTo = action.replyTo,
.date = HistoryItem::NewMessageDate(action.options),
.date = NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.postAuthor = messagePostAuthor,
.postAuthor = NewMessagePostAuthor(action),
.effectId = action.options.effectId,
}, TextWithEntities(), MTP_messageMediaContact(
MTP_string(phone),
@@ -3772,7 +3760,6 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
MTP_string(fields.url),
MTP_int(page->pendingTill)));
}
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, action.options);
FillMessagePostFlags(action, peer, flags);
if ((exactWebPage && !ignoreWebPage && message.webPage.invert)
@@ -3800,18 +3787,10 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
history->startSavingCloudDraft(draftTopicRootId);
}
const auto sendAs = action.options.sendAs;
const auto messageFromId = sendAs
? sendAs->id
: anonymousPost
? PeerId()
: _session->userPeerId();
if (sendAs) {
sendFlags |= MTPmessages_SendMessage::Flag::f_send_as;
mediaFlags |= MTPmessages_SendMedia::Flag::f_send_as;
}
const auto messagePostAuthor = peer->isBroadcast()
? _session->user()->name()
: QString();
if (action.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled;
sendFlags |= MTPmessages_SendMessage::Flag::f_schedule_date;
@@ -3829,11 +3808,11 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
lastMessage = history->addNewLocalMessage({
.id = newId.msg,
.flags = flags,
.from = messageFromId,
.from = NewMessageFromId(action),
.replyTo = action.replyTo,
.date = HistoryItem::NewMessageDate(action.options),
.date = NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.postAuthor = messagePostAuthor,
.postAuthor = NewMessagePostAuthor(action),
.effectId = action.options.effectId,
}, sending, media);
const auto done = [=](
@@ -3979,7 +3958,6 @@ void ApiWrap::sendInlineResult(
flags |= MessageFlag::HasReplyInfo;
sendFlags |= SendFlag::f_reply_to;
}
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, action.options);
FillMessagePostFlags(action, peer, flags);
if (silentPost) {
@@ -3998,30 +3976,22 @@ void ApiWrap::sendInlineResult(
}
const auto sendAs = action.options.sendAs;
const auto messageFromId = sendAs
? sendAs->id
: anonymousPost ? PeerId()
: _session->userPeerId();
if (sendAs) {
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_send_as;
}
const auto messagePostAuthor = peer->isBroadcast()
? _session->user()->name()
: QString();
_session->data().registerMessageRandomId(randomId, newId);
data->addToHistory(history, {
.id = newId.msg,
.flags = flags,
.from = messageFromId,
.from = NewMessageFromId(action),
.replyTo = action.replyTo,
.date = HistoryItem::NewMessageDate(action.options),
.date = NewMessageDate(action.options),
.shortcutId = action.options.shortcutId,
.viaBotId = ((bot && !action.options.hideViaBot)
? peerToUser(bot->id)
: UserId()),
.postAuthor = messagePostAuthor,
.postAuthor = NewMessagePostAuthor(action),
});
history->clearCloudDraft(topicRootId);
@@ -4190,8 +4160,10 @@ void ApiWrap::sendMediaWithRandomId(
Data::Histories::ReplyToPlaceholder(),
(options.price
? MTPInputMedia(MTP_inputMediaPaidMedia(
MTP_flags(0),
MTP_long(options.price),
MTP_vector<MTPInputMedia>(1, media)))
MTP_vector<MTPInputMedia>(1, media),
MTPstring()))
: media),
MTP_string(caption.text),
MTP_long(randomId),
@@ -4204,7 +4176,7 @@ void ApiWrap::sendMediaWithRandomId(
), [=](const MTPUpdates &result, const MTP::Response &response) {
if (done) done(true);
if (updateRecentStickers) {
requestRecentStickersForce(true);
requestRecentStickers(std::nullopt, true);
}
}, [=](const MTP::Error &error, const MTP::Response &response) {
if (done) done(false);
@@ -4262,8 +4234,10 @@ void ApiWrap::sendMultiPaidMedia(
peer->input,
Data::Histories::ReplyToPlaceholder(),
MTP_inputMediaPaidMedia(
MTP_flags(0),
MTP_long(options.price),
MTP_vector<MTPInputMedia>(std::move(medias))),
MTP_vector<MTPInputMedia>(std::move(medias)),
MTPstring()),
MTP_string(caption.text),
MTP_long(randomId),
MTPReplyMarkup(),

View File

@@ -244,7 +244,10 @@ public:
void updateSavedGifs();
void updateMasks();
void updateCustomEmoji();
void requestRecentStickersForce(bool attached = false);
void requestSpecialStickersForce(
bool faved,
bool recent,
bool attached);
void setGroupStickerSet(
not_null<ChannelData*> megagroup,
const StickerSetIdentifier &set);
@@ -477,9 +480,10 @@ private:
void requestStickers(TimeId now);
void requestMasks(TimeId now);
void requestCustomEmoji(TimeId now);
void requestRecentStickers(TimeId now, bool attached = false);
void requestRecentStickersWithHash(uint64 hash, bool attached = false);
void requestFavedStickers(TimeId now);
void requestRecentStickers(
std::optional<TimeId> now,
bool attached);
void requestFavedStickers(std::optional<TimeId> now);
void requestFeaturedStickers(TimeId now);
void requestFeaturedEmoji(TimeId now);
void requestSavedGifs(TimeId now);

View File

@@ -100,6 +100,8 @@ void AboutBox::showVersionHistory() {
url += u"win/%1.zip"_q;
} else if (Platform::IsWindows64Bit()) {
url += u"win64/%1.zip"_q;
} else if (Platform::IsWindowsARM64()) {
url += u"winarm/%1.zip"_q;
} else if (Platform::IsMac()) {
url += u"mac/%1.zip"_q;
} else if (Platform::IsLinux()) {
@@ -155,6 +157,8 @@ QString currentVersionText() {
}
if (Platform::IsWindows64Bit()) {
result += " x64";
} else if (Platform::IsWindowsARM64()) {
result += " arm64";
}
return result;
}

View File

@@ -217,7 +217,9 @@ void ShowAddParticipantsError(
channel,
user,
ChatAdminRightsInfo(),
QString());
QString(),
0,
nullptr);
box->setSaveCallback(saveCallback);
*weak = box.data();
show->showBox(std::move(box));
@@ -898,9 +900,10 @@ void GroupInfoBox::checkInviteLink() {
channelReady();
} else if (_createdChannel->isFullLoaded() && !_creatingInviteLink) {
_creatingInviteLink = true;
_createdChannel->session().api().inviteLinks().create(
_createdChannel->session().api().inviteLinks().create({
_createdChannel,
crl::guard(this, [=](auto&&) { channelReady(); }));
crl::guard(this, [=](auto&&) { channelReady(); }),
});
} else {
_createdChannel->session().changes().peerUpdates(
_createdChannel,
@@ -1243,7 +1246,7 @@ void SetupChannelBox::mousePressEvent(QMouseEvent *e) {
showToast(tr::lng_create_channel_link_copied(tr::now));
} else if (_channel->isFullLoaded() && !_creatingInviteLink) {
_creatingInviteLink = true;
_channel->session().api().inviteLinks().create(_channel);
_channel->session().api().inviteLinks().create({ _channel });
}
}

View File

@@ -597,8 +597,6 @@ rightsHeaderLabel: FlatLabel(boxLabel) {
}
textFg: windowActiveTextFg;
}
rightsUntilMargin: margins(0px, 8px, 0px, 20px);
rightsRankMargin: margins(0px, 7px, 0px, 20px);
groupStickersRemove: defaultMultiSelectSearchCancel;
groupStickersRemovePosition: point(6px, 6px);
@@ -756,6 +754,8 @@ createPollWarningPosition: point(16px, 6px);
createPollCheckboxMargin: margins(22px, 10px, 22px, 10px);
createPollFieldTitlePadding: margins(22px, 7px, 10px, 6px);
sendGifWithCaptionEmojiPosition: point(-30px, 23px);
backgroundCheckbox: Checkbox(defaultCheckbox) {
textFg: msgServiceFg;
textFgActive: msgServiceFg;
@@ -785,7 +785,7 @@ backgroundConfirmPadding: margins(24px, 16px, 24px, 16px);
backgroundConfirm: RoundButton(defaultActiveButton) {
height: 44px;
textTop: 12px;
font: font(13px semibold);
style: semiboldTextStyle;
}
backgroundConfirmCancel: RoundButton(backgroundConfirm) {
textFg: mediaviewSaveMsgFg;
@@ -797,7 +797,7 @@ backgroundConfirmCancel: RoundButton(backgroundConfirm) {
height: 44px;
textTop: 12px;
font: font(13px semibold);
style: semiboldTextStyle;
ripple: RippleAnimation(defaultRippleAnimation) {
color: shadowFg;
@@ -949,7 +949,7 @@ sponsoredUrlButton: RoundButton(defaultActiveButton) {
textFg: historyLinkInFg;
textFgOver: historyLinkInFg;
textTop: 7px;
font: normalFont;
style: defaultTextStyle;
ripple: RippleAnimation(defaultRippleAnimation) {
color: windowBgOver;
@@ -1120,3 +1120,10 @@ moderateBoxDividerLabel: FlatLabel(boxDividerLabel) {
selectLinkFg: windowActiveTextFg;
}
}
profileQrFont: font(fsize bold);
profileQrCenterSize: 34px;
profileQrBackgroundRadius: 12px;
profileQrIcon: icon{{ "qr_mini", windowActiveTextFg }};
profileQrBackgroundMargins: margins(36px, 12px, 36px, 12px);
profileQrBackgroundPadding: margins(0px, 24px, 0px, 24px);

View File

@@ -39,6 +39,7 @@ Data::ChatFilter ChangedFilter(
filter.id(),
filter.title(),
filter.iconEmoji(),
filter.colorIndex(),
filter.flags(),
std::move(always),
filter.pinned(),
@@ -58,6 +59,7 @@ Data::ChatFilter ChangedFilter(
filter.id(),
filter.title(),
filter.iconEmoji(),
filter.colorIndex(),
filter.flags(),
std::move(always),
filter.pinned(),

View File

@@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/slide_wrap.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/vertical_list.h"
#include "ui/ui_utility.h"
#include "boxes/abstract_box.h" // Ui::show().
#include "window/window_session_controller.h"
#include "styles/style_layers.h"

View File

@@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "menu/menu_send.h"
#include "ui/controls/emoji_button.h"
#include "ui/controls/emoji_button_factory.h"
#include "ui/rect.h"
#include "ui/text/text_utilities.h"
#include "ui/toast/toast.h"
@@ -37,6 +38,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/fade_wrap.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/ui_utility.h"
#include "window/window_session_controller.h"
#include "styles/style_boxes.h"
#include "styles/style_chat_helpers.h" // defaultComposeFiles.
@@ -54,100 +56,6 @@ constexpr auto kSolutionLimit = 200;
constexpr auto kWarnSolutionLimit = 60;
constexpr auto kErrorLimit = 99;
[[nodiscard]] not_null<Ui::EmojiButton*> AddEmojiToggleToField(
not_null<Ui::InputField*> field,
not_null<Ui::BoxContent*> box,
not_null<Window::SessionController*> controller,
not_null<ChatHelpers::TabbedPanel*> emojiPanel,
QPoint shift) {
const auto emojiToggle = Ui::CreateChild<Ui::EmojiButton>(
field->parentWidget(),
st::defaultComposeFiles.emoji);
const auto fade = Ui::CreateChild<Ui::FadeAnimation>(
emojiToggle,
emojiToggle,
0.5);
{
const auto fadeTarget = Ui::CreateChild<Ui::RpWidget>(emojiToggle);
fadeTarget->resize(emojiToggle->size());
fadeTarget->paintRequest(
) | rpl::start_with_next([=](const QRect &rect) {
auto p = QPainter(fadeTarget);
if (fade->animating()) {
p.fillRect(fadeTarget->rect(), st::boxBg);
}
fade->paint(p);
}, fadeTarget->lifetime());
rpl::single(false) | rpl::then(
field->focusedChanges()
) | rpl::start_with_next([=](bool shown) {
if (shown) {
fade->fadeIn(st::universalDuration);
} else {
fade->fadeOut(st::universalDuration);
}
}, emojiToggle->lifetime());
fade->fadeOut(1);
fade->finish();
}
const auto outer = box->getDelegate()->outerContainer();
const auto allow = [](not_null<DocumentData*>) { return true; };
InitMessageFieldHandlers(
controller,
field,
Window::GifPauseReason::Layer,
allow);
Ui::Emoji::SuggestionsController::Init(
outer,
field,
&controller->session(),
Ui::Emoji::SuggestionsController::Options{
.suggestCustomEmoji = true,
.allowCustomWithoutPremium = allow,
});
const auto updateEmojiPanelGeometry = [=] {
const auto parent = emojiPanel->parentWidget();
const auto global = emojiToggle->mapToGlobal({ 0, 0 });
const auto local = parent->mapFromGlobal(global);
const auto right = local.x() + emojiToggle->width() * 3;
const auto isDropDown = local.y() < parent->height() / 2;
emojiPanel->setDropDown(isDropDown);
if (isDropDown) {
emojiPanel->moveTopRight(
local.y() + emojiToggle->height(),
right);
} else {
emojiPanel->moveBottomRight(local.y(), right);
}
};
rpl::combine(
box->sizeValue(),
field->geometryValue()
) | rpl::start_with_next([=](QSize outer, QRect inner) {
emojiToggle->moveToLeft(
rect::right(inner) + shift.x(),
inner.y() + shift.y());
emojiToggle->update();
}, emojiToggle->lifetime());
emojiToggle->installEventFilter(emojiPanel);
emojiToggle->addClickHandler([=] {
updateEmojiPanelGeometry();
emojiPanel->toggleAnimated();
});
const auto filterCallback = [=](not_null<QEvent*> event) {
if (event->type() == QEvent::Enter) {
updateEmojiPanelGeometry();
}
return base::EventFilterResult::Continue;
};
base::install_event_filter(emojiToggle, filterCallback);
return emojiToggle;
}
class Options {
public:
Options(
@@ -770,7 +678,7 @@ void Options::addEmptyOption() {
_chooseCorrectGroup));
const auto field = _list.back()->field();
if (const auto emojiPanel = _emojiPanel) {
const auto emojiToggle = AddEmojiToggleToField(
const auto emojiToggle = Ui::AddEmojiToggleToField(
field,
_box,
_controller,
@@ -972,7 +880,7 @@ not_null<Ui::InputField*> CreatePollBox::setupQuestion(
emojiPanel->hide();
emojiPanel->selector()->setCurrentPeer(session->user());
const auto emojiToggle = AddEmojiToggleToField(
const auto emojiToggle = Ui::AddEmojiToggleToField(
question,
this,
_controller,

View File

@@ -25,7 +25,7 @@ DownloadPathBox::DownloadPathBox(
, _path(Core::App().settings().downloadPath())
, _pathBookmark(Core::App().settings().downloadPathBookmark())
, _group(std::make_shared<Ui::RadioenumGroup<Directory>>(typeFromPath(_path)))
, _default(Core::App().canReadDefaultDownloadPath(true)
, _default(Core::App().canReadDefaultDownloadPath()
? object_ptr<Ui::Radioenum<Directory>>(
this,
_group,
@@ -149,7 +149,7 @@ void DownloadPathBox::setPathText(const QString &text) {
DownloadPathBox::Directory DownloadPathBox::typeFromPath(
const QString &path) {
if (path.isEmpty()) {
return Core::App().canReadDefaultDownloadPath(true)
return Core::App().canReadDefaultDownloadPath()
? Directory::Downloads
: Directory::Temp;
} else if (path == FileDialog::Tmp()) {

View File

@@ -195,7 +195,7 @@ PaintRoundImageCallback PremiumsRow::generatePaintUserpicCallback(
const auto radius = size * Ui::ForumUserpicRadiusMultiplier();
p.drawRoundedRect(x, y, size, size, radius, radius);
}
st::settingsPrivacyPremium.paintInCenter(p, { x, y, size, size });
st::settingsPrivacyPremium.paintInCenter(p, QRect(x, y, size, size));
};
}
@@ -763,9 +763,6 @@ void EditMessagesPrivacyBox(
lt_link,
link,
Ui::Text::WithEntities),
.st = &st::defaultMultilineToast,
.duration = Ui::Toast::kDefaultDuration * 2,
.multiline = true,
.filter = crl::guard(&controller->session(), [=](
const ClickHandlerPtr &,
Qt::MouseButton button) {

View File

@@ -83,6 +83,7 @@ not_null<FilterChatsPreview*> SetupChatsPreview(
rules.id(),
rules.title(),
rules.iconEmoji(),
rules.colorIndex(),
(rules.flags() & ~flag),
rules.always(),
rules.pinned(),
@@ -104,6 +105,7 @@ not_null<FilterChatsPreview*> SetupChatsPreview(
rules.id(),
rules.title(),
rules.iconEmoji(),
rules.colorIndex(),
rules.flags(),
std::move(always),
std::move(pinned),
@@ -170,6 +172,7 @@ void EditExceptions(
rules.id(),
rules.title(),
rules.iconEmoji(),
rules.colorIndex(),
((rules.flags() & ~options)
| rawController->chosenOptions()),
include ? std::move(changed) : std::move(removeFrom),
@@ -240,6 +243,7 @@ void CreateIconSelector(
rules.id(),
rules.title(),
Ui::LookupFilterIcon(icon).emoji,
rules.colorIndex(),
rules.flags(),
rules.always(),
rules.pinned(),

View File

@@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/vertical_layout.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/painter.h"
#include "ui/rect.h"
#include "ui/vertical_list.h"
#include "window/window_session_controller.h"
#include "styles/style_info.h"
@@ -581,6 +582,7 @@ void LinkController::addLinkBlock(not_null<Ui::VerticalLayout*> container) {
});
const auto getLinkQr = crl::guard(weak, [=] {
delegate()->peerListUiShow()->showBox(InviteLinkQrBox(
nullptr,
link,
tr::lng_group_invite_qr_title(),
tr::lng_filters_link_qr_about()));
@@ -889,6 +891,7 @@ base::unique_qptr<Ui::PopupMenu> LinksController::createRowContextMenu(
};
const auto getLinkQr = [=] {
delegate()->peerListUiShow()->showBox(InviteLinkQrBox(
nullptr,
link,
tr::lng_group_invite_qr_title(),
tr::lng_filters_link_qr_about()));
@@ -965,9 +968,9 @@ void LinksController::rowPaintIcon(
p.setBrush(*bg);
{
auto hq = PainterHighQualityEnabler(p);
p.drawEllipse(QRect(0, 0, inner, inner));
p.drawEllipse(Rect(Size(inner)));
}
st::inviteLinkIcon.paintInCenter(p, { 0, 0, inner, inner });
st::inviteLinkIcon.paintInCenter(p, Rect(Size(inner)));
}
p.drawImage(x + skip, y + skip, icon);
}
@@ -1113,7 +1116,7 @@ QString FilterChatStatusText(not_null<PeerData*> peer) {
? tr::lng_chat_status_subscribers
: tr::lng_chat_status_members)(
tr::now,
lt_count,
lt_count_decimal,
channel->membersCount());
}
}

View File

@@ -0,0 +1,181 @@
/*
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 "boxes/gift_credits_box.h"
#include "api/api_credits.h"
#include "boxes/peer_list_controllers.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "data/stickers/data_custom_emoji.h"
#include "lang/lang_keys.h"
#include "main/session/session_show.h"
#include "settings/settings_credits_graphics.h"
#include "ui/controls/userpic_button.h"
#include "ui/effects/premium_graphics.h"
#include "ui/effects/premium_stars_colored.h"
#include "ui/layers/generic_box.h"
#include "ui/rect.h"
#include "ui/text/text_utilities.h"
#include "ui/vertical_list.h"
#include "ui/widgets/label_with_custom_emoji.h"
#include "window/window_session_controller.h"
#include "styles/style_boxes.h"
#include "styles/style_channel_earn.h"
#include "styles/style_chat.h"
#include "styles/style_credits.h"
#include "styles/style_giveaway.h"
#include "styles/style_layers.h"
#include "styles/style_premium.h"
namespace Ui {
void GiftCreditsBox(
not_null<Ui::GenericBox*> box,
not_null<PeerData*> peer,
Fn<void()> gifted) {
box->setWidth(st::boxWideWidth);
box->setStyle(st::creditsGiftBox);
box->setNoContentMargin(true);
box->addButton(tr::lng_create_group_back(), [=] { box->closeBox(); });
const auto content = box->setPinnedToTopContent(
object_ptr<Ui::VerticalLayout>(box));
Ui::AddSkip(content);
Ui::AddSkip(content);
const auto &stUser = st::premiumGiftsUserpicButton;
const auto userpicWrap = content->add(
object_ptr<Ui::CenterWrap<>>(
content,
object_ptr<Ui::UserpicButton>(content, peer, stUser)));
userpicWrap->setAttribute(Qt::WA_TransparentForMouseEvents);
Ui::AddSkip(content);
Ui::AddSkip(content);
{
const auto widget = Ui::CreateChild<Ui::RpWidget>(content);
using ColoredMiniStars = Ui::Premium::ColoredMiniStars;
const auto stars = widget->lifetime().make_state<ColoredMiniStars>(
widget,
false,
Ui::Premium::MiniStars::Type::BiStars);
stars->setColorOverride(Ui::Premium::CreditsIconGradientStops());
widget->resize(
st::boxWidth - stUser.photoSize,
stUser.photoSize * 2);
content->sizeValue(
) | rpl::start_with_next([=](const QSize &size) {
widget->moveToLeft(stUser.photoSize / 2, 0);
const auto starsRect = Rect(widget->size());
stars->setPosition(starsRect.topLeft());
stars->setSize(starsRect.size());
widget->lower();
}, widget->lifetime());
widget->paintRequest(
) | rpl::start_with_next([=](const QRect &r) {
auto p = QPainter(widget);
p.fillRect(r, Qt::transparent);
stars->paint(p);
}, widget->lifetime());
}
{
Ui::AddSkip(content);
const auto arrow = Ui::Text::SingleCustomEmoji(
peer->owner().customEmojiManager().registerInternalEmoji(
st::topicButtonArrow,
st::channelEarnLearnArrowMargins,
false));
auto link = tr::lng_credits_box_history_entry_gift_about_link(
lt_emoji,
rpl::single(arrow),
Ui::Text::RichLangValue
) | rpl::map([](TextWithEntities text) {
return Ui::Text::Link(
std::move(text),
u"internal:stars_examples"_q);
});
content->add(
object_ptr<Ui::CenterWrap<>>(
content,
Ui::CreateLabelWithCustomEmoji(
content,
tr::lng_credits_box_history_entry_gift_out_about(
lt_user,
rpl::single(TextWithEntities{ peer->shortName() }),
lt_link,
std::move(link),
Ui::Text::RichLangValue),
{ .session = &peer->session() },
st::creditsBoxAbout)),
st::boxRowPadding);
}
Ui::AddSkip(content);
Ui::AddSkip(box->verticalLayout());
Settings::FillCreditOptions(
Main::MakeSessionShow(box->uiShow(), &peer->session()),
box->verticalLayout(),
peer,
0,
[=] { gifted(); box->uiShow()->hideLayer(); });
box->setPinnedToBottomContent(
object_ptr<Ui::VerticalLayout>(box));
}
void ShowGiftCreditsBox(
not_null<Window::SessionController*> controller,
Fn<void()> gifted) {
class Controller final : public ContactsBoxController {
public:
Controller(
not_null<Main::Session*> session,
Fn<void(not_null<PeerData*>)> choose)
: ContactsBoxController(session)
, _choose(std::move(choose)) {
}
protected:
std::unique_ptr<PeerListRow> createRow(
not_null<UserData*> user) override {
if (user->isSelf()
|| user->isBot()
|| user->isServiceUser()
|| user->isInaccessible()) {
return nullptr;
}
return ContactsBoxController::createRow(user);
}
void rowClicked(not_null<PeerListRow*> row) override {
_choose(row->peer());
}
private:
const Fn<void(not_null<PeerData*>)> _choose;
};
auto initBox = [=](not_null<PeerListBox*> peersBox) {
peersBox->setTitle(tr::lng_credits_gift_title());
peersBox->addButton(tr::lng_cancel(), [=] { peersBox->closeBox(); });
};
const auto show = controller->uiShow();
auto listController = std::make_unique<Controller>(
&controller->session(),
[=](not_null<PeerData*> peer) {
show->showBox(Box(GiftCreditsBox, peer, gifted));
});
show->showBox(
Box<PeerListBox>(std::move(listController), std::move(initBox)),
Ui::LayerOption::KeepOther);
}
} // namespace Ui

View File

@@ -0,0 +1,20 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Window {
class SessionController;
} // namespace Window
namespace Ui {
void ShowGiftCreditsBox(
not_null<Window::SessionController*> controller,
Fn<void()> gifted);
} // namespace Ui

View File

@@ -23,7 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_media_types.h" // Data::GiveawayStart.
#include "data/data_peer_values.h" // Data::PeerPremiumValue.
#include "data/data_session.h"
#include "data/data_subscription_option.h"
#include "data/data_premium_subscription_option.h"
#include "data/data_user.h"
#include "data/stickers/data_custom_emoji.h"
#include "info/channel_statistics/boosts/giveaway/boost_badge.h" // InfiniteRadialAnimationWidget.
@@ -66,8 +66,26 @@ namespace {
constexpr auto kUserpicsMax = size_t(3);
using GiftOption = Data::SubscriptionOption;
using GiftOptions = Data::SubscriptionOptions;
using GiftOption = Data::PremiumSubscriptionOption;
using GiftOptions = Data::PremiumSubscriptionOptions;
[[nodiscard]] QString CreateMessageLink(
not_null<Main::Session*> session,
PeerId peerId,
uint64 messageId) {
if (const auto msgId = MsgId(peerId ? messageId : 0)) {
const auto peer = session->data().peer(peerId);
if (const auto channel = peer->asBroadcast()) {
const auto username = channel->username();
const auto base = username.isEmpty()
? u"c/%1"_q.arg(peerToChannel(channel->id).bare)
: username;
const auto query = base + '/' + QString::number(msgId.bare);
return session->createInternalLink(query);
}
}
return QString();
};
GiftOptions GiftOptionFromTL(const MTPDuserFull &data) {
auto result = GiftOptions();
@@ -75,7 +93,7 @@ GiftOptions GiftOptionFromTL(const MTPDuserFull &data) {
if (!gifts) {
return result;
}
result = Api::SubscriptionOptionsFromTL(gifts->v);
result = Api::PremiumSubscriptionOptionsFromTL(gifts->v);
for (auto &option : result) {
option.costPerMonth = tr::lng_premium_gift_per(
tr::now,
@@ -932,8 +950,8 @@ void ShowAlreadyPremiumToast(
Ui::Text::Link(
Ui::Text::Bold(tr::lng_gift_link_already_link(tr::now))),
Ui::Text::WithEntities),
.duration = 6 * crl::time(1000),
.filter = crl::guard(navigation, shareLink),
.duration = 6 * crl::time(1000),
});
}
@@ -1014,6 +1032,7 @@ void GiftPremiumValidator::showChoosePeerBox(const QString &ref) {
if (users.empty()) {
show->showToast(
tr::lng_settings_gift_premium_choose(tr::now));
return;
}
const auto giftBox = show->show(
Box(GiftsBox, _controller, users, api, ref));
@@ -1418,21 +1437,56 @@ void GiveawayInfoBox(
: !start->channels.empty()
? start->channels.front()->name()
: u"channel"_q;
auto text = TextWithEntities();
if (!info.giftCode.isEmpty()) {
text.append("\n\n");
text.append(Ui::Text::Bold(tr::lng_prizes_you_won(
tr::now,
auto resultText = (!info.giftCode.isEmpty())
? tr::lng_prizes_you_won(
lt_cup,
QString::fromUtf8("\xf0\x9f\x8f\x86"))));
text.append("\n\n");
} else if (info.state == State::Finished) {
text.append("\n\n");
text.append(Ui::Text::Bold(tr::lng_prizes_you_didnt(tr::now)));
text.append("\n\n");
rpl::single(
TextWithEntities{ QString::fromUtf8("\xf0\x9f\x8f\x86") }),
Ui::Text::WithEntities)
: (info.credits)
? tr::lng_prizes_you_won_credits(
lt_amount,
tr::lng_prizes_you_won_credits_amount(
lt_count,
rpl::single(float64(info.credits)),
Ui::Text::Bold),
lt_cup,
rpl::single(
TextWithEntities{ QString::fromUtf8("\xf0\x9f\x8f\x86") }),
Ui::Text::WithEntities)
: (info.state == State::Finished)
? tr::lng_prizes_you_didnt(Ui::Text::WithEntities)
: (rpl::producer<TextWithEntities>)(nullptr);
if (resultText) {
const auto &st = st::changePhoneDescription;
const auto skip = st.style.font->height * 0.5;
auto label = object_ptr<Ui::FlatLabel>(
box.get(),
std::move(resultText),
st);
if ((!info.giftCode.isEmpty()) || info.credits) {
label->setTextColorOverride(st::windowActiveTextFg->c);
}
const auto result = box->addRow(
object_ptr<Ui::PaddingWrap<Ui::CenterWrap<Ui::FlatLabel>>>(
box.get(),
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
box.get(),
std::move(label)),
QMargins(0, skip, 0, skip)));
result->paintRequest() | rpl::start_with_next([=] {
auto p = QPainter(result);
p.setPen(Qt::NoPen);
p.setBrush(st::boxDividerBg);
p.drawRoundedRect(result->rect(), st::boxRadius, st::boxRadius);
}, result->lifetime());
Ui::AddSkip(box->verticalLayout());
}
auto text = TextWithEntities();
const auto quantity = start
? start->quantity
: (results->winnersCount + results->unclaimedCount);
@@ -1441,22 +1495,39 @@ void GiveawayInfoBox(
? results->channel->isMegagroup()
: (!start->channels.empty()
&& start->channels.front()->isMegagroup());
const auto credits = start
? start->credits
: (results ? results->credits : 0);
text.append((finished
? tr::lng_prizes_end_text
: tr::lng_prizes_how_text)(
tr::now,
lt_admins,
(group
? tr::lng_prizes_admins_group
: tr::lng_prizes_admins)(
tr::now,
lt_count,
quantity,
lt_channel,
Ui::Text::Bold(first),
lt_duration,
TextWithEntities{ GiftDuration(months) },
Ui::Text::RichLangValue),
credits
? (group
? tr::lng_prizes_credits_admins_group
: tr::lng_prizes_credits_admins)(
tr::now,
lt_channel,
Ui::Text::Bold(first),
lt_amount,
tr::lng_prizes_credits_admins_amount(
tr::now,
lt_count_decimal,
float64(credits),
Ui::Text::Bold),
Ui::Text::RichLangValue)
: (group
? tr::lng_prizes_admins_group
: tr::lng_prizes_admins)(
tr::now,
lt_count,
quantity,
lt_channel,
Ui::Text::Bold(first),
lt_duration,
TextWithEntities{ GiftDuration(months) },
Ui::Text::RichLangValue),
Ui::Text::RichLangValue));
const auto many = start
? (start->channels.size() > 1)
@@ -1641,26 +1712,29 @@ void AddCreditsHistoryEntryTable(
not_null<Window::SessionNavigation*> controller,
not_null<Ui::VerticalLayout*> container,
const Data::CreditsHistoryEntry &entry) {
if (!entry) {
return;
}
auto table = container->add(
object_ptr<Ui::TableLayout>(
container,
st::giveawayGiftCodeTable),
st::giveawayGiftCodeTableMargin);
const auto peerId = PeerId(entry.barePeerId);
const auto session = &controller->session();
if (peerId) {
auto text = tr::lng_credits_box_history_entry_peer();
auto text = entry.in
? tr::lng_credits_box_history_entry_peer_in()
: tr::lng_credits_box_history_entry_peer();
AddTableRow(table, std::move(text), controller, peerId);
}
if (const auto msgId = MsgId(peerId ? entry.bareMsgId : 0)) {
const auto session = &controller->session();
const auto peer = session->data().peer(peerId);
if (const auto channel = peer->asBroadcast()) {
const auto username = channel->username();
const auto base = username.isEmpty()
? u"c/%1"_q.arg(peerToChannel(channel->id).bare)
: username;
const auto query = base + '/' + QString::number(msgId.bare);
const auto link = session->createInternalLink(query);
const auto link = CreateMessageLink(
session,
peerId,
entry.bareMsgId);
auto label = object_ptr<Ui::FlatLabel>(
table,
rpl::single(Ui::Text::Link(link)),
@@ -1692,14 +1766,55 @@ void AddCreditsHistoryEntryTable(
} else if (entry.peerType == Type::Fragment) {
AddTableRow(
table,
tr::lng_credits_box_history_entry_via(),
tr::lng_credits_box_history_entry_fragment(
Ui::Text::RichLangValue));
(entry.gift
? tr::lng_credits_box_history_entry_peer_in
: tr::lng_credits_box_history_entry_via)(),
(entry.gift
? tr::lng_credits_box_history_entry_anonymous
: tr::lng_credits_box_history_entry_fragment)(
Ui::Text::RichLangValue));
} else if (entry.peerType == Type::Ads) {
AddTableRow(
table,
tr::lng_credits_box_history_entry_via(),
tr::lng_credits_box_history_entry_ads(Ui::Text::RichLangValue));
} else if (entry.peerType == Type::PremiumBot) {
AddTableRow(
table,
tr::lng_credits_box_history_entry_via(),
tr::lng_credits_box_history_entry_via_premium_bot(
Ui::Text::RichLangValue));
}
if (entry.bareGiveawayMsgId) {
AddTableRow(
table,
tr::lng_gift_link_label_to(),
controller,
controller->session().userId());
}
if (entry.bareGiveawayMsgId && entry.credits) {
AddTableRow(
table,
tr::lng_gift_link_label_gift(),
tr::lng_gift_stars_title(
lt_count,
rpl::single(float64(entry.credits)),
Ui::Text::RichLangValue));
}
{
const auto link = CreateMessageLink(
session,
peerId,
entry.bareGiveawayMsgId);
if (!link.isEmpty()) {
AddTableRow(
table,
tr::lng_gift_link_label_reason(),
tr::lng_gift_link_reason_giveaway(
) | rpl::map([link](const QString &text) {
return Ui::Text::Link(text, link);
}));
}
}
if (!entry.id.isEmpty()) {
constexpr auto kOneLineCount = 18;
@@ -1744,3 +1859,113 @@ void AddCreditsHistoryEntryTable(
Ui::Text::Link(entry.successLink, entry.successLink)));
}
}
void AddSubscriptionEntryTable(
not_null<Window::SessionNavigation*> controller,
not_null<Ui::VerticalLayout*> container,
const Data::SubscriptionEntry &s) {
if (!s) {
return;
}
auto table = container->add(
object_ptr<Ui::TableLayout>(
container,
st::giveawayGiftCodeTable),
st::giveawayGiftCodeTableMargin);
const auto peerId = PeerId(s.barePeerId);
AddTableRow(
table,
tr::lng_credits_subscription_row_to(),
controller,
peerId);
if (!s.until.isNull()) {
AddTableRow(
table,
s.expired
? tr::lng_credits_subscription_row_next_none()
: s.cancelled
? tr::lng_credits_subscription_row_next_off()
: tr::lng_credits_subscription_row_next_on(),
rpl::single(Ui::Text::WithEntities(langDateTime(s.until))));
}
}
void AddSubscriberEntryTable(
not_null<Window::SessionNavigation*> controller,
not_null<Ui::VerticalLayout*> container,
not_null<PeerData*> peer,
TimeId date) {
auto table = container->add(
object_ptr<Ui::TableLayout>(
container,
st::giveawayGiftCodeTable),
st::giveawayGiftCodeTableMargin);
AddTableRow(
table,
tr::lng_group_invite_joined_row_subscriber(),
controller,
peer->id);
if (const auto d = base::unixtime::parse(date); !d.isNull()) {
AddTableRow(
table,
tr::lng_group_invite_joined_row_date(),
rpl::single(Ui::Text::WithEntities(langDateTime(d))));
}
}
void AddCreditsBoostTable(
not_null<Window::SessionNavigation*> controller,
not_null<Ui::VerticalLayout*> container,
const Data::Boost &b) {
auto table = container->add(
object_ptr<Ui::TableLayout>(
container,
st::giveawayGiftCodeTable),
st::giveawayGiftCodeTableMargin);
const auto peerId = b.giveawayMessage.peer;
if (!peerId) {
return;
}
const auto from = controller->session().data().peer(peerId);
AddTableRow(
table,
tr::lng_credits_box_history_entry_peer_in(),
controller,
from->id);
if (b.credits) {
AddTableRow(
table,
tr::lng_gift_link_label_gift(),
tr::lng_gift_stars_title(
lt_count,
rpl::single(float64(b.credits)),
Ui::Text::RichLangValue));
}
{
const auto link = CreateMessageLink(
&controller->session(),
peerId,
b.giveawayMessage.msg.bare);
if (!link.isEmpty()) {
AddTableRow(
table,
tr::lng_gift_link_label_reason(),
tr::lng_gift_link_reason_giveaway(
) | rpl::map([link](const QString &text) {
return Ui::Text::Link(text, link);
}));
}
}
if (!b.date.isNull()) {
AddTableRow(
table,
tr::lng_gift_link_label_date(),
rpl::single(Ui::Text::WithEntities(langDateTime(b.date))));
}
if (!b.expiresAt.isNull()) {
AddTableRow(
table,
tr::lng_gift_until(),
rpl::single(Ui::Text::WithEntities(langDateTime(b.expiresAt))));
}
}

View File

@@ -16,9 +16,11 @@ struct GiftCode;
} // namespace Api
namespace Data {
struct Boost;
struct CreditsHistoryEntry;
struct GiveawayStart;
struct GiveawayResults;
struct SubscriptionEntry;
} // namespace Data
namespace Ui {
@@ -78,3 +80,18 @@ void AddCreditsHistoryEntryTable(
not_null<Window::SessionNavigation*> controller,
not_null<Ui::VerticalLayout*> container,
const Data::CreditsHistoryEntry &entry);
void AddSubscriptionEntryTable(
not_null<Window::SessionNavigation*> controller,
not_null<Ui::VerticalLayout*> container,
const Data::SubscriptionEntry &s);
void AddSubscriberEntryTable(
not_null<Window::SessionNavigation*> controller,
not_null<Ui::VerticalLayout*> container,
not_null<PeerData*> peer,
TimeId date);
void AddCreditsBoostTable(
not_null<Window::SessionNavigation*> controller,
not_null<Ui::VerticalLayout*> container,
const Data::Boost &boost);

View File

@@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text_options.h"
#include "ui/painter.h"
#include "ui/vertical_list.h"
#include "ui/ui_utility.h"
#include "storage/localstorage.h"
#include "boxes/abstract_box.h"
#include "boxes/premium_preview_box.h"

View File

@@ -94,7 +94,7 @@ void MaxInviteBox::mousePressEvent(QMouseEvent *e) {
showToast(tr::lng_create_channel_link_copied(tr::now));
} else if (_channel->isFullLoaded() && !_creatingInviteLink) {
_creatingInviteLink = true;
_channel->session().api().inviteLinks().create(_channel);
_channel->session().api().inviteLinks().create({ _channel });
}
}
}

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