Compare commits

..

505 Commits

Author SHA1 Message Date
John Preston
8fc35e45e4 Beta version 4.2.1: Fix build with GCC. 2022-09-22 22:44:28 +04:00
John Preston
2931e754c3 Beta version 4.2.1.
- Improve scaling / cropping for photos / video files.
- Improve touch support in channel comments.
- Nice animation for spoilers.
2022-09-22 20:15:55 +04:00
John Preston
4e7a5eeffb Use Python 3.10 and GYP supporting it. 2022-09-22 15:31:46 +04:00
John Preston
6fcafeff5b Don't repeat premium stickers in fake-pack. 2022-09-22 14:58:40 +04:00
Ilya Fedin
3165ef9f0b Implement target_compile_options_if_exists, target_link_options_if_exists 2022-09-22 12:58:07 +04:00
John Preston
ec992ae552 Fix reactions menu on Retina screens. 2022-09-22 12:33:48 +04:00
John Preston
f0a36d6460 Show only first row of colored default statuses. 2022-09-22 12:27:46 +04:00
John Preston
ffb024a5f7 Move Ui::Text::String to HistoryView::Element. 2022-09-22 11:07:48 +04:00
Ilya Fedin
140dcb033b Fix snap building on snapcraft 2022-09-20 10:20:07 +04:00
Ilya Fedin
06d9d04787 Remove explicit setting of paths for cmake in snapcraft.yaml
This is reported as fixed in snapcraft, thus these paths should be set automatically
2022-09-19 19:12:16 +04:00
John Preston
a7c29991db Hide toggle silent send in channels on msg edit. 2022-09-19 18:49:46 +04:00
John Preston
e3d79d46f7 Fix new format of direct post links in channels. 2022-09-19 18:28:53 +04:00
John Preston
476a864be2 Improve cropping for videos a bit.
Partially fixes #25061 for videos as well.
2022-09-19 18:05:03 +04:00
John Preston
fc3810fd7f Improve scaling / expanding for photos.
Fixes #25061.
2022-09-19 17:44:59 +04:00
John Preston
f5bff22bb8 Improve touch support in popup menus. 2022-09-19 17:29:28 +04:00
Ilya Fedin
157b4c43ee Update lib_ui 2022-09-19 14:23:27 +04:00
Ilya Fedin
f2d2826fc7 Make InstallLauncher accessible on any platform 2022-09-19 14:23:27 +04:00
Ilya Fedin
cfa12fb0cc Move AppRuntimeDirectory to private namespace 2022-09-19 14:23:27 +04:00
Ilya Fedin
d9318c9935 Move icon name getter to cross-platform header 2022-09-19 14:23:27 +04:00
Ilya Fedin
5132fd5010 Use KSandbox to check flatpak/snap environment 2022-09-19 14:23:27 +04:00
Ilya Fedin
89879e355d Replace EscapeShell with KShell::joinArgs 2022-09-19 14:20:02 +04:00
Ilya Fedin
278ab5ebaf Add support for AVIF, HEIF and JPEG XL (only on Linux yet) 2022-09-19 11:20:50 +04:00
John Preston
39294a7fe1 Use touch handling from HistoryInner in ListWidget.
Fixes #24880.
2022-09-19 11:16:09 +04:00
John Preston
7727cdff92 Fix build with Xcode. 2022-09-18 17:12:16 +04:00
John Preston
8bd0ff7925 Opimize spoiler revealing. 2022-09-18 16:52:31 +04:00
John Preston
4f948699c0 Correct spoiler selections. 2022-09-18 16:52:31 +04:00
John Preston
cd00d41cca Correct spoiler colors in fully selected messages. 2022-09-18 16:52:31 +04:00
John Preston
749fb52113 Implement animated spoilers. 2022-09-18 16:52:30 +04:00
Ilya Fedin
4975254cc1 Avoid building qttools
Removing po folder from kcoreaddons allows that
2022-09-18 15:55:56 +04:00
Ilya Fedin
b36063e086 Update kcoreaddons to 5.98.0
And patch to cache portal result
2022-09-17 06:23:05 +04:00
John Preston
645ae69220 Version 4.2.
- A new expandable reaction menu was added in private chats and groups.
- All users get access to dozens of new reactions,
including reactions previously reserved for Premium users.
- The reactions you use most frequently
will always be displayed at the top.
- Premium users can react to messages with thousands of custom emoji
and add up to 3 reactions to each message.
- Group admins can control whether
custom reactions are allowed in their groups.
- Premium users can add an animated emoji status next to their name
to display their current activity.
- To set a status, tap your Premium badge in the main menu or Settings.
- Popular suggestions for working, sleeping,
traveling and more will be shown at the top.
- To set a status for a specific duration like 1 hour or 2 days,
right click the emoji.
- A new format was supported for username links,
in addition to "t.me/username." You can now open Telegram accounts,
groups or channels using links like "username.t.me"
or "https://username.t.me."
- Improved support for long media captions.
2022-09-17 00:47:22 +04:00
John Preston
782c5c28a8 Support custom quick reaction in settings. 2022-09-16 11:16:59 +04:00
John Preston
fba683be8e Fix custom status remove on chat reopen. 2022-09-16 10:42:25 +04:00
Ilya Fedin
552d96df71 Update Qt to 6.4.0 rc1 2022-09-16 09:46:36 +04:00
John Preston
1043467eec Fix lib_ui build. 2022-09-15 22:00:20 +04:00
John Preston
9923cc9b31 Beta version 4.1.2: Fix build with Xcode. 2022-09-14 23:15:00 +04:00
23rd
47b32898f5 Fixed padding of TopBar in Premium Settings for user. 2022-09-14 23:10:31 +04:00
23rd
557a2e400e Fixed muting of peer forever. 2022-09-14 23:10:30 +04:00
23rd
84400f5912 Added strictly typed field to export JSON for text entities. 2022-09-14 23:10:28 +04:00
John Preston
b28140c4b0 Beta version 4.1.2.
- New reaction selector above the right click menu.
- Premium: Set any custom emoji reactions in private chats.
- Premium: Set any custom emoji as your profile status.
- Insert or copy custom emoji from pack preview.
2022-09-14 23:06:00 +04:00
John Preston
08321b8d8b Fix sending custom emoji based on Dice-type game emoji. 2022-09-14 20:41:24 +04:00
John Preston
bc340d75c4 Insert / Copy emoji from pack preview. 2022-09-14 14:45:23 +04:00
John Preston
cae18b3320 Use "Change Emoji Status" phrase. 2022-09-14 12:27:06 +04:00
John Preston
d81b2fbb69 Activate the chosen default folder on Escape. 2022-09-14 09:13:28 +04:00
John Preston
02daa2a04b Add new reaction menu to channel comments. 2022-09-13 07:53:20 +04:00
John Preston
1363faddbf Add "Reaction button in messages" setting. 2022-09-13 07:44:22 +04:00
John Preston
20a5950f99 Fix premium star / status in accounts list. 2022-09-12 18:56:03 +04:00
John Preston
40bdcd7ebc Short poll extended media. 2022-09-12 18:18:31 +04:00
John Preston
379736a7d1 Show extended preview inline keyboard button. 2022-09-12 16:40:19 +04:00
John Preston
d2234d88b6 Update extended media, hide inline keyboard. 2022-09-12 16:10:56 +04:00
John Preston
c2fd4ccd59 Skip custom reactions if premium isn't possible. 2022-09-12 10:07:07 +04:00
John Preston
26c79939e0 Fix custom status duration edit from Settings. 2022-09-12 09:51:55 +04:00
John Preston
ffaeb239f0 Don't show emoji tooltip in reactions / statuses. 2022-09-12 09:46:23 +04:00
John Preston
7c8d3452b5 Fix reaction icons in Who Reacted. 2022-09-12 09:38:18 +04:00
John Preston
e2bca0a7ff Fix media with caption in a narrow window. 2022-09-12 09:35:28 +04:00
John Preston
2e8a03dfd1 Correctly round spoiler animation in ExtendedMedia. 2022-09-12 09:06:26 +04:00
John Preston
a919978a37 Use spoiler animation for ExtendedMedia. 2022-09-12 09:06:26 +04:00
John Preston
20b5138e00 Initial implementation of ExtendedMedia. 2022-09-12 09:06:26 +04:00
John Preston
2523d6e8d8 Update API scheme to layer 146. 2022-09-12 09:06:26 +04:00
John Preston
03e90840de Closed alpha version 4.1.1.1: Fix build with GCC. 2022-09-10 11:07:08 +04:00
John Preston
4ab34e3727 Suggest only like and dislike reactions in groups by default. 2022-09-10 09:36:08 +04:00
John Preston
3129d9f0df Add a distinct "N seconds" key for the slowmode phrase. 2022-09-10 08:19:37 +04:00
John Preston
2b6b1d7611 Closed alpha version 4.1.1.1. 2022-09-10 08:12:35 +04:00
John Preston
6e9493c725 Ignore premium gradient keys when colorizing theme. 2022-09-10 08:11:58 +04:00
John Preston
746141a363 Update lib_ui to fix a crash on Linux. 2022-09-10 08:08:46 +04:00
John Preston
4942154a9c Make loading emoji set icons look nicer. 2022-09-10 07:23:20 +04:00
John Preston
d511f2bb90 Fix via @bot after name for premium users. 2022-09-09 09:35:36 +04:00
John Preston
460b4b2de5 Move around some sources in CMakeLists. 2022-09-08 13:16:39 +04:00
John Preston
ab25cf214c Fix FFmpeg frame generator ending. 2022-09-08 09:50:11 +04:00
John Preston
b0203af398 Fix no-bubble comments button resize. 2022-09-08 09:38:52 +04:00
John Preston
c00f2f96ec Replace phone number with "Set Emoji Status". 2022-09-07 20:39:57 +04:00
John Preston
2215500c9a Add emoji status icon to premium promo. 2022-09-07 20:36:06 +04:00
John Preston
5cc6275fc3 Fly + effects when choosing an emoji status. 2022-09-07 12:52:34 +04:00
John Preston
d4810713cb Fly-animate reactions from the new context menu. 2022-09-06 17:08:20 +04:00
John Preston
1877786707 Special phrase for a colored emoji status. 2022-09-06 12:32:33 +04:00
John Preston
06ec574543 Fix single-frame 60 fps lotties. 2022-09-06 12:07:09 +04:00
John Preston
f0955f2021 Add emoji-status disclaimer for unknown peers. 2022-09-06 11:20:55 +04:00
John Preston
400d4b793a Fix initial visibility of Who can send messages.
Fixes #25030.
2022-09-06 08:09:29 +04:00
John Preston
d6ba092697 Make GIFs and videos with captions larger. 2022-09-05 19:03:52 +04:00
John Preston
9ef2f370ac Handle only username subdomains for t.me domain. 2022-09-05 12:22:43 +04:00
Ilya Fedin
234c74a439 Update patches commit in Dockerfile 2022-09-05 11:57:46 +04:00
Ilya Fedin
88f1f8ff22 Move QGuiApplication::setDesktopFileName call to Platform::start
It depends on Core::UpdaterDisabled that is not initialized in Launcher::initHook yet
2022-09-05 08:24:48 +04:00
John Preston
00ee31ce2d Make photos with captions wider. 2022-09-04 08:18:50 +04:00
Alexander Kernozhitsky
a5bd4ef6f7 Fix code style 2022-09-04 08:04:02 +04:00
Alexander Kernozhitsky
c6c2a44e9d Patch the remaining uses or FFmpeg APIs 2022-09-04 08:04:02 +04:00
Alexander Kernozhitsky
21b0454461 Remove duplicate line
Co-authored-by: darkkeks <darkkeks@rambler.ru>
2022-09-04 08:04:02 +04:00
Alexander Kernozhitsky
ca4b5edf21 Correct FFmpeg API usage
FFmpeg docs say that you must return AVERROR_EOF from the read callback, not zero. Still, Telegram just propagates the return value from IODevice::read() call, which returns zero in case of EOF.

I don't know whether this commit has any effect on the upstream build, but it fixes a bug in Debian build of Telegram, which is using FFmpeg 5.1 instead of 4.4. Still, it's also useful in the upstream, as it makes work with FFmpeg more correct.
2022-09-04 08:04:02 +04:00
Ilya Fedin
9ac739c423 Update poetry installer URL 2022-09-04 08:02:43 +04:00
Ilya Fedin
bd7a880468 Increase operation limit of stale action to 1000 for it to operate normally 2022-09-04 08:01:51 +04:00
Ilya Fedin
807e63d9f2 Disable PR processing in stale bot explicitly
According to the documentation, it shouldn't procces them until stale-pr-message is set, but that doesn't seem to be true
2022-09-04 08:01:51 +04:00
Ilya Fedin
4cedf89e51 Migrate from stale app to stale action
It doesn't seem to work for multiple months
2022-09-03 09:30:20 +04:00
John Preston
a736ddb24e One more fix for GCC build. 2022-09-03 09:08:13 +04:00
Ilya Fedin
b48674d302 Avoid unneccesary QPA, again 2022-09-03 08:47:02 +04:00
GitHub Action
a6a9b16358 Update User-Agent for DNS to Chrome 104.0.5112.101. 2022-09-03 08:42:51 +04:00
Ilya Fedin
dfb40dd216 Handle PiP aspect ratio on Wayland synchronously
During testing with Qt 6.4 I now remember why I made a way complicated logic (yes, because the trivial one bugs with Qt 6.4)
This restores it, but uses event filters rather than hardware integration override
2022-09-03 08:41:49 +04:00
John Preston
85acf051c1 Try to fix build with GCC. 2022-09-03 06:51:02 +04:00
Ilya Fedin
86059f2b5e Update Qt to 6.4.0 beta4 on Linux 2022-09-02 21:27:41 +04:00
Ilya Fedin
4f261ced8e Ceil device pixel ratio
Qt 6.4 provides QT_WIDGETS_HIGHDPI_DOWNSCALE that allows widgets to draw at integer device pixel ratio by using the next integer. Ceiling this value makes tdesktop in sync with technique and provides sharp content.

Without QT_WIDGETS_HIGHDPI_DOWNSCALE, this doesn't makes the content sharp, but the quality is still better as Qt attempts to downscale those graphic rather than upscale.
2022-09-02 21:27:41 +04:00
Ilya Fedin
feb6107ce6 Qt 6.4 supports window activation with tray on Wayland 2022-09-02 21:27:41 +04:00
Ilya Fedin
eab41d272b Fix various spaces on end of lines 2022-09-02 21:27:41 +04:00
Ilya Fedin
38da0e086d Get rid of lib_waylandshells 2022-09-02 21:27:41 +04:00
Ilya Fedin
f874876b00 Update wayland to 1.21.0 2022-09-02 21:27:41 +04:00
Ilya Fedin
2065616592 Let Qt use Vulkan headers for Vulkan support 2022-09-02 21:27:41 +04:00
John Preston
898edad09b Show status duration menu only in status panel. 2022-09-02 21:14:34 +04:00
23rd
49773dde72 Attempted to fix rare non-elided text in bar of pinned bot messages. 2022-09-02 21:14:34 +04:00
23rd
fa6b4f9b52 Slightly improved style of Premium Settings. 2022-09-02 21:14:34 +04:00
23rd
fa4801ac94 Added ability to set emoji status for certain period of time. 2022-09-02 21:14:34 +04:00
John Preston
9bb2bb09b9 Update API scheme on layer 145.
Restrict send from channels to premium in line with API restrictions.
2022-09-02 21:14:34 +04:00
John Preston
e32031963b Colorize status in premium promo and pack preview. 2022-09-02 21:14:34 +04:00
John Preston
c13221a984 Menu reactions selector without enabled compositing. 2022-09-02 21:14:34 +04:00
John Preston
688cd70c91 Prepend colored default statuses in selector. 2022-09-02 21:14:34 +04:00
John Preston
a256eb4bc8 Add mini-copies animation for custom reactions. 2022-09-02 21:14:34 +04:00
John Preston
7d77e8a203 Play generic animations for custom reactions. 2022-09-02 21:14:34 +04:00
John Preston
47709884dd Allow 50% interface scale from command line. 2022-09-02 21:14:33 +04:00
John Preston
7658d1da3c Fix unsetting reaction in private chats. 2022-09-02 21:14:33 +04:00
John Preston
0a3077b9a5 Update API scheme on layer 145. 2022-09-02 21:14:33 +04:00
John Preston
e0513f7b7c Return old allowed reactions edit for channels. 2022-09-02 21:14:33 +04:00
23rd
7e7562fdad Fixed crash in RecoverBox from PasscodeBox with custom check callback. 2022-09-02 21:14:33 +04:00
23rd
15aefddab4 Added support of Webm custom emoji to Premium Settings. 2022-09-02 21:14:33 +04:00
23rd
e34b61d56b Moved out HistoryView::StickerPlayer implementations to separate file. 2022-09-02 21:14:33 +04:00
John Preston
010b5e3949 Support username.t.me links. 2022-09-02 21:14:33 +04:00
John Preston
5530df8f2d Play emoji status only twice in main menu. 2022-09-02 21:14:33 +04:00
John Preston
742b819c7e Always show reaction userpics in private chats. 2022-09-02 21:14:33 +04:00
John Preston
2618ee3d75 Paint two-loops of custom emoji statuses. 2022-09-02 21:14:33 +04:00
John Preston
da281c4d3d Fix build with Xcode. 2022-09-02 21:14:33 +04:00
John Preston
2d07539892 Support colored emoji statuses. 2022-09-02 21:14:33 +04:00
John Preston
923e725e18 Request default and recent emoji statuses. 2022-09-02 21:14:33 +04:00
23rd
b2d72e2541 Removed subscription options from Settings when there is only one. 2022-09-02 21:14:33 +04:00
23rd
7ed10eaacc Added gradient colors to radiobutton views in Premium Settings. 2022-09-02 21:14:33 +04:00
23rd
5505a566be Replaced gradient header in Premium Settings for dark themes. 2022-09-02 21:14:32 +04:00
23rd
35c59ad35a Moved out util function for contrast calculation between 2 colors. 2022-09-02 21:14:32 +04:00
John Preston
5e81c65ea6 Implement improved allowed reactions editing. 2022-09-02 21:14:32 +04:00
John Preston
021e275336 Update API scheme on layer 145. 2022-09-02 21:14:32 +04:00
John Preston
e540b8cbdc Read correct reactions limit from config. 2022-09-02 21:14:32 +04:00
John Preston
ebf6cea2f5 Correctly show premium promo for custom reactions. 2022-09-02 21:14:32 +04:00
John Preston
a3c110dafa Correctly show flying custom reactions. 2022-09-02 21:14:32 +04:00
John Preston
ad0c9ebb79 Fly-animate custom reactions. 2022-09-02 21:14:32 +04:00
John Preston
d5008fe7ac Sync custom emoji from strip to recent in the panel. 2022-09-02 21:14:32 +04:00
John Preston
7c3814cdcd Fix recent userpics display in reactions. 2022-09-02 21:14:32 +04:00
John Preston
ed3f246510 Use FrameGenerator-based AnimatedIcon for reactions. 2022-09-02 21:14:32 +04:00
John Preston
d9a6d5f508 Update API scheme on layer 145. 2022-09-02 21:14:32 +04:00
23rd
da6d580348 Fixed style of box for premium doubled limits. 2022-09-02 21:14:32 +04:00
23rd
0ffa88d0f3 Added shadow to small TopBar in Premium Settings for user. 2022-09-02 21:14:32 +04:00
23rd
149d92d224 Added ability to choose subscription option for Premium in Settings. 2022-09-02 21:14:32 +04:00
23rd
6f3d19914d Unified parsing of MTP gift and subscription options in separate file. 2022-09-02 21:14:32 +04:00
23rd
fc759ac688 Renamed GiftOption to SubscriptionOption. 2022-09-02 21:14:31 +04:00
23rd
e03eaaaa98 Fixed switching between sections of Premium Settings. 2022-09-02 21:14:31 +04:00
23rd
857f56d5b4 Added animation pause in TopBar in Premium Settings for user. 2022-09-02 21:14:31 +04:00
23rd
638cf237c4 Slightly improved design of Premium Settings. 2022-09-02 21:14:31 +04:00
23rd
01b50a8460 Added initial implementation of TopBar in Premium Settings for user. 2022-09-02 21:14:31 +04:00
23rd
b519b6bf4c Reduced minimum and maximum sizes of ministars. 2022-09-02 21:14:31 +04:00
23rd
b10bf0e12c Replaced svg file for premium star. 2022-09-02 21:14:31 +04:00
23rd
4d43830c3b Replaced ripple colors for top buttons in Premium Settings. 2022-09-02 21:14:31 +04:00
23rd
65ad8e6ac1 Moved out class for colored ministars to separate file. 2022-09-02 21:14:31 +04:00
23rd
56cbde93da Divided TopBar in Premium Settings into abstract and main classes. 2022-09-02 21:14:31 +04:00
23rd
90ef0e4969 Reformated serializing and parsing of ref data for Premium Settings. 2022-09-02 21:14:31 +04:00
John Preston
668a3308be Support custom emoji reactions in WhoReacted. 2022-09-02 21:14:31 +04:00
John Preston
ba83836922 Display custom emoji reactions under messages. 2022-09-02 21:14:31 +04:00
John Preston
14f937cb02 Show only some reactions in the bottom info.
Only in private chats with no premium users.
Only if nobody sent more than one reaction while was premium.
Only if nobody sent a custom emoji reaction while was premium.
2022-09-02 21:14:31 +04:00
John Preston
733cad798b Load emoji for reactions panel. 2022-09-02 21:14:31 +04:00
John Preston
8a6b3027f5 Support multiple reactions from one user. 2022-09-02 21:14:31 +04:00
John Preston
31db1804c8 Request top and recent reactions. 2022-09-02 21:14:31 +04:00
John Preston
f8c962712b Update API scheme on layer 145. 2022-09-02 21:14:31 +04:00
John Preston
a202174d12 Disable expand button in the inline reactions selector for now. 2022-09-02 21:14:31 +04:00
John Preston
3399397a76 Allow 1 year for session termination delay. 2022-09-02 21:14:30 +04:00
John Preston
c655f78780 Fix build with Xcode. 2022-09-02 21:14:30 +04:00
John Preston
73d8530c13 Fix jumping to premium promo from reactions panel. 2022-09-02 21:14:30 +04:00
John Preston
610c46e26f Make a nice selector for only-recent set. 2022-09-02 21:14:30 +04:00
John Preston
96805b62b2 Seamless switch from strip icons to custom emoji. 2022-09-02 21:14:30 +04:00
John Preston
4762c7a4fd Fix layout with a single available reaction. 2022-09-02 21:14:30 +04:00
John Preston
0277d765bb Nice reactions panel expanding. 2022-09-02 21:14:30 +04:00
John Preston
20d4d00634 Implement expanding of list / categories. 2022-09-02 21:14:30 +04:00
John Preston
c5fa4aae62 Support reaction dropdown based on EmojiListWidget. 2022-09-02 21:14:30 +04:00
John Preston
f72092a261 Update API scheme on layer 145. 2022-09-02 21:14:30 +04:00
John Preston
33b266175d Allow creating EmojiListWidget without SessionController. 2022-09-02 21:14:30 +04:00
John Preston
c9a98ae723 Expand reaction selection panel. 2022-09-02 21:14:30 +04:00
John Preston
bd42c23999 Implement reactions selector above the menu. 2022-09-02 21:14:30 +04:00
John Preston
f658cb7e99 Update API scheme on layer 145. 2022-09-02 21:14:30 +04:00
John Preston
fa26afaf9a Rename several HistoryView::Reactions modules. 2022-09-02 21:14:30 +04:00
John Preston
b648387e96 Fixed emoji packs menu item. 2022-09-02 21:14:29 +04:00
John Preston
8d2ebdbb99 Animate reactions strip appearance. 2022-09-02 21:14:29 +04:00
John Preston
a0d5456a4d PoC content outside of PopupMenu. 2022-09-02 21:14:29 +04:00
23rd
c20ed7c7a8 Enabled utf-8 mode for python while breakpad is building. 2022-09-02 21:14:29 +04:00
23rd
ef543d040e Replaced separate click handlers for each spoiler entry with single one. 2022-09-02 21:14:29 +04:00
John Preston
27063167ae Don't cut name / status unnecessary. 2022-09-02 21:14:29 +04:00
John Preston
8a1118d9bb Show how much message limit is exceeded when editing. 2022-09-02 21:14:29 +04:00
John Preston
1e2e007d38 Show custom emoji in private chat reactions. 2022-09-02 21:14:29 +04:00
John Preston
09124f6424 Implement PoC custom reaction selection. 2022-09-02 21:14:29 +04:00
John Preston
cece9cf09b Show in chats list EntityType::Pre like EntityType::Code. 2022-09-02 21:14:29 +04:00
John Preston
60cc232884 Update API scheme on layer 145. 2022-09-02 21:14:29 +04:00
John Preston
ba8673af5e Fix build with Xcode. 2022-09-02 21:14:29 +04:00
John Preston
77772caabb Update API scheme on layer 145. 2022-09-02 21:14:29 +04:00
John Preston
e22bb40dd1 Improve premium / emoji status badge styles. 2022-09-02 21:14:29 +04:00
John Preston
bd089f20a8 Emoji status selector in MainMenu/Settings. 2022-09-02 21:14:28 +04:00
John Preston
64bd4f0926 Make nice emoji status selector in profile. 2022-09-02 21:14:28 +04:00
John Preston
165d3143de Allow emoji status edit from self profile. 2022-09-02 21:14:28 +04:00
John Preston
21fd381778 Show emoji status in chats list / top bar. 2022-09-02 21:14:28 +04:00
John Preston
285ce81b7b Update API scheme to layer 145. 2022-09-02 21:14:28 +04:00
Ilya Fedin
e7f85f7255 Add missing include to settings_advanced 2022-09-02 18:46:31 +04:00
Ilya Fedin
12d8d193a1 Create QSystemTrayIcon even when tray is not supported
QSystemTrayIcon provides no public API to know when tray icon support appears, but can subscribe to native events internally

This should help for environments where a race condition between applications autostart and tray service autostart present in case Qt is subscribed internally
2022-09-02 17:29:57 +04:00
Ilya Fedin
c18313614b Use Core::Tray::has in settings_advanced 2022-09-02 17:29:57 +04:00
Ilya Fedin
f1092753fc Remove version from the .desktop file
Some desktop environments hide the launcher if they don't know the version
2022-09-01 13:53:53 +04:00
Ilya Fedin
5fc7caeec9 Provide old version to Platform::NewVersionLaunched 2022-09-01 13:53:53 +04:00
Ilya Fedin
e20840b4d4 Use KUrlMimeData for clipboard xdg-desktop-portal integration 2022-08-30 20:25:10 +04:00
Ilya Fedin
5f53dfda0e Move Qt version from configure.py to CMakeLists.txt 2022-08-30 20:25:10 +04:00
Joe Kappus
630e73fa23 Fix build with GCC 12. 2022-08-30 12:42:26 +04:00
John Preston
92a9ba2ba0 Use exact jom url instead of mirrored. 2022-08-29 09:12:09 +04:00
Ilya Fedin
4d4d75addf Install nuget and jom with prepare.py 2022-08-28 08:38:37 +04:00
Ilya Fedin
42fe80b5e2 Use perl, nasm, yasm and ninja from msys64 2022-08-28 08:38:37 +04:00
Ilya Fedin
96793179a3 Find nuget in the recommended directory automatically 2022-08-28 00:35:45 +04:00
Ilya Fedin
fc19ce5a9b Install msys64 with prepare.py 2022-08-28 00:35:45 +04:00
Ilya Fedin
31fa6d24f4 Use zlib built with cmake on Windows 2022-08-28 00:35:45 +04:00
John Preston
7b005c64e0 Workaround MSVC 17.3.2 ICE. 2022-08-26 09:47:03 +04:00
Yue Wu
82d68f5b98 Fix JSON output when exporting custom emojis
Fixes #24961
2022-08-23 12:21:58 +04:00
Ilya Fedin
2259f747f1 Add missing network-status permission
This should make webview working as well as auto-reconnection when system network changed
2022-08-22 17:23:02 +04:00
John Preston
c793537d96 Version 4.1.1.
- Fix editing media captions with animated emoji.
- Fix viewing animated emoji sets used in a message.
- Fix premium sticker tooltip auto-show in channel comments.
- Fix main window position and size restoring after relaunch.
- Other bug fixes and minor improvements.
2022-08-16 09:38:19 +03:00
23rd
e568f7ab01 Added ability to restrict voice messages in conversations for everyone. 2022-08-16 09:38:19 +03:00
John Preston
11b711c43f Fix realtime "Large emoji" applying to only-custom-emoji. 2022-08-16 09:29:02 +03:00
John Preston
d1a81a83b4 Fix crash in editing media captions. 2022-08-16 09:21:12 +03:00
John Preston
42ca06d33c Request up to 32 file parts at once for video downloads. 2022-08-16 08:57:36 +03:00
John Preston
184ebc865c Fix downloading videos of size > INT_MAX to disk. 2022-08-16 08:56:30 +03:00
John Preston
c8c3f43853 Fix editing media captions with custom emoji. 2022-08-16 08:27:55 +03:00
John Preston
9105677325 Add "View Profile" even with third column info. 2022-08-16 07:41:32 +03:00
John Preston
7c2d3a8855 Fix custom emoji in initial send files caption. 2022-08-15 19:10:38 +03:00
John Preston
888306c017 Fix custom emoji in reply bar in comments / scheduled. 2022-08-15 19:01:40 +03:00
John Preston
6ff30c643a Fix user links in Recent Actions. 2022-08-15 18:54:08 +03:00
John Preston
5f8fca0355 Don't allow custom emoji pseudo-links in EditLink. 2022-08-15 18:41:37 +03:00
John Preston
4933fbb74a Show out message timestamp always for > 3 custom emoji. 2022-08-15 17:54:45 +03:00
John Preston
51010e864c Fix premium sticker tooltip auto-show in comments. 2022-08-15 16:39:56 +03:00
John Preston
24ee944689 Improve reply info layout in narrow mode.
Fixes #24935.
2022-08-15 16:21:08 +03:00
John Preston
2c0a38d356 Don't unload emoji sets.
Fixes #24933.
2022-08-15 15:52:27 +03:00
John Preston
e05f570e1a Fix custom emoji copy from TextWithEntities to clipboard. 2022-08-15 15:13:46 +03:00
John Preston
2846b2f7a5 Fix stickers list footer last icon. 2022-08-15 14:23:07 +03:00
John Preston
c126a1e56e Simplify CustomEmojiId. 2022-08-15 13:17:24 +03:00
John Preston
f0f7318978 Better saved credentials processing. 2022-08-15 12:20:17 +03:00
John Preston
fede1ff173 Simplify stickers inner API. 2022-08-15 11:34:22 +03:00
John Preston
94e4a8981f Specify gift box sticker explicitly. 2022-08-15 10:42:06 +03:00
Ilya Fedin
1e7117dd67 Revert "Fix enlargening the window by shadow margin when resotring position"
This reverts commit e0ddaf9da1.
2022-08-14 11:51:13 +04:00
Ilya Fedin
65ddbec794 Set Qt version in configure.py 2022-08-14 11:51:13 +04:00
Ilya Fedin
8adec5fcfd Update lib_webview 2022-08-13 14:32:11 +04:00
Joe Kappus
f82089cbfe Fix build with GCC 12. 2022-08-13 14:18:13 +04:00
Ilya Fedin
23d9ca896e Update cmake_helpers 2022-08-13 12:10:07 +04:00
Ilya Fedin
5f3c957b1d Use COPY --link to consume less space when building Docker image 2022-08-13 12:10:07 +04:00
Ilya Fedin
b9181db407 Don't use QWindowSystemInterface in the PiP
It provides no difference, there was a mistake while testing the behavior
2022-08-12 19:51:04 +03:00
Ilya Fedin
be8d91055a Remove unused prepare.sh in centos_env 2022-08-12 19:47:03 +03:00
John Preston
df45294855 Version 4.1: Fix build with GCC. 2022-08-12 19:01:41 +03:00
John Preston
ef6d2b2c0b Version 4.1.
- Include animated emoji in messages and captions.
- Premium users unlock over 500 new emoji,
including custom packs with unique characters.
- All users can view any emoji,
and try them out in the Saved Messages chat.
- Control who can send you voice
and video messages with Telegram Premium.
- Send a Premium subscription to any user from their profile.
- Choose 3, 6, or 12 months - at a discount.
2022-08-12 16:46:57 +03:00
John Preston
60839bb8ac Update cmake_helpers. 2022-08-12 16:23:05 +03:00
John Preston
228a48c8bf Fix possible crash in main window destructor.
In platform window destructor it can send window state change signal.
2022-08-12 16:21:52 +03:00
John Preston
76a482317d Fix main menu name label refreshing. 2022-08-11 20:58:30 +03:00
John Preston
01f28b4d52 Use CustomEmoji instances for categories in the panel. 2022-08-11 20:56:33 +03:00
John Preston
655194c841 Return ApiWrap::requestPeerSettings method. 2022-08-11 09:59:18 +03:00
Ilya Fedin
8fe48f3ca2 Use cmake_dependent_option to better declare variables that relate on other variables 2022-08-11 09:07:15 +03:00
John Preston
54f467eb47 Don't rely on MTP* when sending photos. 2022-08-11 09:06:56 +03:00
John Preston
3698396677 Remove MTP from Polls::create interface. 2022-08-11 09:06:43 +03:00
John Preston
d2e1517e7a Correctly cancel username check request. 2022-08-11 09:06:30 +03:00
John Preston
7733e3350d Remove unused private fields in ApiWrap. 2022-08-11 09:06:16 +03:00
John Preston
566128c3eb Remove MTP from requestDeepLinkInfo interface. 2022-08-11 09:05:37 +03:00
John Preston
ab3d3a449b Remove MTP from requestWallPaper interface. 2022-08-11 09:05:23 +03:00
John Preston
e9fd249c5a Remove some unused ApiWrap methods. 2022-08-11 09:04:25 +03:00
John Preston
e7a3c5367a Make MTP* optional in ConfirmInviteBox. 2022-08-11 09:02:41 +03:00
John Preston
8bc807dc40 Set name / phone texts on-demand. 2022-08-09 14:12:19 +03:00
Ilya Fedin
ceb7d5f238 Use version-less Qt targets and functions whenever possible 2022-08-09 10:42:24 +04:00
John Preston
84b3260f38 Don't open group info on migration update. 2022-08-08 20:21:30 +03:00
Sergey A. Osokin
7a3452a18a Fix warnings by removing unused const variables
Telegram/SourceFiles/ui/text/custom_emoji_instance.cpp:23:16: warning: unused variable 'kMaxFrameDuration' [-Wunused-const-variable]
Telegram/SourceFiles/boxes/reactions_settings_box.cpp:46:16: warning: unused variable 'kVisibleButtonsCount' [-Wunused-const-variable]
Telegram/SourceFiles/boxes/premium_preview_box.cpp:53:16: warning: unused variable 'kShiftDuration' [-Wunused-const-variable]
Telegram/SourceFiles/settings/settings_premium.cpp:55:16: warning: unused variable 'kTitleAnimationPart' [-Wunused-const-variable]

Found by:	clang
2022-08-08 21:21:13 +04:00
John Preston
05edf00d40 Fix unwrapped media top skip. 2022-08-08 19:12:18 +03:00
John Preston
b67bfd0a8a Improve device model detection on macOS. 2022-08-08 19:12:08 +03:00
John Preston
90d2021f4d Jump to keyboard top on FullMsgId change. 2022-08-08 18:28:36 +03:00
John Preston
72ed3bfab9 Show leave confirmation when starting an RTMP stream. 2022-08-08 18:19:04 +03:00
John Preston
d8743ec0e6 Fix opening channel with active livestream in a new window. 2022-08-08 18:18:44 +03:00
John Preston
3a3341fef8 Fix RTMP livestream starting while in another call.
Fixes #24862.
2022-08-08 16:39:44 +03:00
John Preston
068eb3fcd1 Fix a click on "via @bot" of a sticker.
Fixes #24888.
2022-08-08 16:02:09 +03:00
John Preston
75ee74ff1f Fix paddings in unwrapped emoji messages. 2022-08-08 15:41:33 +03:00
John Preston
dfb3346096 Better replace many same emoji at once. 2022-08-08 15:34:04 +03:00
John Preston
a098abefd7 Replace many same emoji at once. 2022-08-08 15:24:11 +03:00
John Preston
f63984c9e3 Don't select first result on animated emoji suggestion. 2022-08-08 14:57:33 +03:00
John Preston
9509c88ef9 Fix possible crash in pinned messages destruction. 2022-08-08 14:32:16 +03:00
John Preston
819925fc72 Don't show premium effects on message previews. 2022-08-08 13:37:31 +03:00
John Preston
cf4b869c27 Don't always show timestamps on large custom-emoji-only messages. 2022-08-08 13:37:15 +03:00
John Preston
5c43a541d7 Show emoji promo only on Premium Emoji toast. 2022-08-08 13:25:22 +03:00
Ilya Fedin
68e0d155f9 Update submodules 2022-08-08 11:05:52 +04:00
Ilya Fedin
8c1bef929e A better way of PiP aspect ratio handling on Wayland 2022-08-08 11:05:52 +04:00
23rd
cde5e89e42 Fixed recording of voice messages in Saved Messages. 2022-08-08 09:34:55 +03:00
Ilya Fedin
e0ddaf9da1 Fix enlargening the window by shadow margin when resotring position 2022-08-08 08:54:14 +04:00
Vedant
aa208fb7d0 Update winget.yml 2022-08-05 18:49:28 +04:00
John Preston
b7cc2e9894 Don't pass redundant MTPUpdates arguments. 2022-08-05 13:37:41 +03:00
John Preston
d891a5344a Beta version 4.0.4: Fix build with GCC. 2022-08-05 10:12:48 +03:00
John Preston
11b62118d2 Beta version 4.0.4.
- Allow sending animated emoji to Saved Messages
even without Telegram Premium.
- Premium: Suggest animated emoji by regular emoji
(can be disabled in Settings).
- Premium: Show all suggested premium stickers
in a special section of the stickers panel.
- Premium: Allow hiding premium stickers special section
of the stickers panel.
- Fix a memory leak in RTMP livestreams.
- Fix some bot webview bugs on macOS.
- Fix forwarding of voice messages.
2022-08-04 21:05:44 +03:00
John Preston
7c284a9453 Drop custom emoji correctly in message edit preview. 2022-08-04 20:55:50 +03:00
John Preston
57b0ec0d7e Fix forwarded message with custom emoji preview. 2022-08-04 20:41:45 +03:00
Ilya Fedin
66d2c06eb4 Update minimum & maximum size in the PiP 2022-08-04 21:27:57 +04:00
John Preston
2f5038a792 Improve webview on macOS. 2022-08-04 19:33:56 +03:00
John Preston
5793241efc Improve webview popups design. 2022-08-04 18:26:12 +03:00
John Preston
9b92700c24 Add additional cloud premium stickers to fake-set. 2022-08-04 17:48:36 +03:00
John Preston
068d3caef5 Allow hiding Premium Stickers fake-sticker-set. 2022-08-04 17:29:49 +03:00
John Preston
4bdac53be2 Fix toast hiding on jump to Saved Messages. 2022-08-04 17:06:02 +03:00
John Preston
c8ec183c88 Fix custom emoji suggestions geometry. 2022-08-04 17:06:02 +03:00
Ilya Fedin
bf339de773 Always pass activation_token option
glib shows a warning about invalid GVariant and empty activation_token shouldn't hurt I believe
2022-08-04 17:12:07 +04:00
John Preston
e438cb57bc Show, send and receive interactions in single custom emoji. 2022-08-04 16:10:36 +03:00
Ilya Fedin
9e63fc5acd Let PiP have custom buffer size on Wayland 2022-08-04 16:41:25 +04:00
John Preston
543bfab24a Resolve custom emoji in OnlyCustomEmoji media. 2022-08-04 14:31:15 +03:00
John Preston
f8e22210e7 Move Webm sticker to UnwrappedMedia. 2022-08-04 13:35:34 +03:00
Aokromes
5b0d023a88 Update README.md 2022-08-03 21:46:04 +04:00
John Preston
7a88f9434e Support OnlyCustomEmoji unwrapped messages. 2022-08-03 20:43:26 +03:00
John Preston
8a91c949c2 Fix build with GCC and Clang. 2022-08-03 20:41:01 +03:00
Ilya Fedin
0921ae283b Send XDG_ACTIVATION_TOKEN to the first instance 2022-08-03 15:26:08 +04:00
Ilya Fedin
d500714242 Use xdg-activation to open URLs&files 2022-08-03 15:26:08 +04:00
John Preston
c5702f0887 Request small song thumbnails. 2022-08-03 11:43:30 +03:00
John Preston
f4b80d8714 Show premium emoji toast / send to Saved Messages. 2022-08-02 20:59:50 +03:00
John Preston
59903b0b1c Suggest animated emoji in Saved Messages. 2022-08-02 19:23:06 +03:00
John Preston
2319278c92 Suggest animated emoji by regular emoji. 2022-08-02 17:57:59 +03:00
23rd
e7b3416da8 Allowed to forward voice messages without full user info. 2022-08-02 16:51:11 +03:00
23rd
c47e951519 Added missed back button to premium narrow section without stack. 2022-08-02 16:51:00 +03:00
John Preston
5472654ac1 Show "You" in out voice messages player. 2022-08-02 16:48:47 +03:00
John Preston
4a5592e95d Show premium mark in suggested stickers. 2022-08-02 16:47:53 +03:00
John Preston
e3140a8a45 Implement premium sticker-by-emoji suggestions. 2022-08-02 13:20:38 +03:00
John Preston
1968fb5d95 Fix memory leak in RTMP streams.
Fixes #24849.
2022-08-02 13:20:38 +03:00
John Preston
4915ea8ad3 Add convenient appConfig().get<int>(..). 2022-08-02 13:20:38 +03:00
John Preston
b96e09534d Fix blocked list loading.
Fixes #24783.
2022-08-02 13:20:38 +03:00
John Preston
0ce7e402ed Mark premium stickers with a star. 2022-08-02 13:20:38 +03:00
John Preston
b42f2784ab Allow sending premium emoji to Saved Messages. 2022-08-02 13:20:38 +03:00
John Preston
087074fea4 Request song covers through MTProto. 2022-08-02 13:20:38 +03:00
Ilya Fedin
be133fce78 Follow TitleControlsLayout in the PiP 2022-08-01 13:53:50 +04:00
GitHub Action
07232e2520 Update User-Agent for DNS to Chrome 103.0.5060.134. 2022-08-01 13:53:11 +04:00
Ilya Fedin
66c9587650 Add fail callback to linux notifications exceptions handler 2022-07-31 12:21:24 +04:00
John Preston
730ee3ae16 Beta version 4.0.3: Fix build with Xcode. 2022-07-29 00:33:47 +03:00
John Preston
9ae7dc1cab Beta version 4.0.3.
- Animated emoji for messages.
- Premium: Privacy settings for voice messages.
- Premium: Gifting Telegram Premium to any user from their profile page.
2022-07-28 23:23:48 +03:00
John Preston
8bb3cd7e65 Push click handler context to Api::ActivateBotCommand. 2022-07-28 20:03:38 +03:00
Ilya Fedin
8e8a209aad Guard linux notification inhibition checks 2022-07-28 20:18:51 +04:00
Ilya Fedin
a79e979fb8 Fix Linux GitHub action 2022-07-28 20:18:06 +04:00
Ilya Fedin
bb8ffcac3a Default to Wayland on GNOME for new installs 2022-07-28 20:17:49 +04:00
John Preston
7a61693034 Limit attached emoji phrase to two lines. 2022-07-28 18:36:48 +03:00
John Preston
d80cf5d149 Download stickers for custom emoji in export. 2022-07-28 18:36:48 +03:00
23rd
d57e752ae9 Added ability to open context menu from inner media in service messages. 2022-07-28 02:49:07 +03:00
23rd
de7f983aeb Changed sort by DocumentId wit sort by index for gift sticker fallback. 2022-07-28 02:49:07 +03:00
23rd
c1fa39ac05 Equaled top and bottom padding for sticker in service gift message. 2022-07-28 02:49:07 +03:00
John Preston
3c19d7b302 Show shared link long URL tooltips. 2022-07-27 14:24:34 +03:00
John Preston
c8aacbdb9f Allow viewing emoji packs from comments / scheduled. 2022-07-27 14:02:41 +03:00
John Preston
85ec212220 Don't scroll large message menus. 2022-07-27 13:49:27 +03:00
23rd
2d75f9e752 Fixed build with Xcode. 2022-07-27 12:49:52 +03:00
23rd
7e208453c7 Fixed context menu for gift service actions. 2022-07-27 12:49:52 +03:00
23rd
3602155f68 Fixed display of gift service actions for gift senders. 2022-07-27 12:49:52 +03:00
John Preston
e64190fb64 Fix crash in attached emoji preview. 2022-07-27 12:26:22 +03:00
John Preston
4f39e723f9 Closed alpha version 4.0.2.4. 2022-07-26 20:12:14 +03:00
John Preston
a58c41be96 Fix scrolling of emoji categories. 2022-07-26 20:12:14 +03:00
John Preston
3c352cad40 Don't scroll outer categories through inner categories. 2022-07-26 20:12:14 +03:00
John Preston
80ebd943aa Fix popup menu with variable item height. 2022-07-26 20:12:14 +03:00
John Preston
4cf4b6a368 Optimize emoji / stickers update requests. 2022-07-26 20:12:14 +03:00
John Preston
4f7aa15416 Fix emoji panel footer updating. 2022-07-26 20:12:14 +03:00
John Preston
f7885da7dd Support additional saved payment methods. 2022-07-26 20:12:14 +03:00
John Preston
e492a18194 Add emoji subcategory icon color. 2022-07-26 20:12:14 +03:00
John Preston
4796594011 Fix crash in large animated emoji. 2022-07-26 20:12:14 +03:00
John Preston
73fc478a2d Allow removing sets from emoji set preview box. 2022-07-26 20:12:14 +03:00
John Preston
af54721f07 Disable attach bot share phone command for now. 2022-07-26 20:12:14 +03:00
John Preston
136eaee8d5 Fix crash on data share in attach bots. 2022-07-26 20:12:14 +03:00
John Preston
edfb7bb65a Support custom emoji in IsolatedEmoji. 2022-07-26 20:12:14 +03:00
John Preston
9b941bae97 Copy single selected message without author. 2022-07-26 20:12:14 +03:00
John Preston
813bbba8b7 Allow copying large-emoji message texts. 2022-07-26 20:12:13 +03:00
John Preston
2a4d269eca Use large image previews more. 2022-07-26 20:12:13 +03:00
John Preston
2d6008f6ca Fix custom emoji in edit caption / send files box. 2022-07-26 20:12:13 +03:00
John Preston
075ced2742 Remove emoji-set preview context menu. 2022-07-26 20:12:13 +03:00
John Preston
012ecb2dcc Limit animated emoji to 30 FPS. 2022-07-26 20:12:13 +03:00
John Preston
31bb08068b Use non-exact image previews if available. 2022-07-26 20:12:13 +03:00
John Preston
c51837cfdf Reuse SizeTag::Large emoji instances. 2022-07-26 20:12:13 +03:00
John Preston
076d5c756a Fix build with Xcode and GCC. 2022-07-26 20:12:13 +03:00
John Preston
b829ed3530 Build docker using poetry by ./build/prepare/linux.sh 2022-07-26 20:12:13 +03:00
John Preston
5624162194 Closed alpha version 4.0.2.3. 2022-07-26 20:12:13 +03:00
John Preston
bb8f8131e4 Improve premium preview from emoji panel. 2022-07-26 20:12:13 +03:00
John Preston
19f89b1d87 Collapse unavailable premium emoji sets in the panel. 2022-07-26 20:12:13 +03:00
John Preston
b0fab8c987 Show featured custom sets in the panel. 2022-07-26 20:12:13 +03:00
John Preston
ff55918da0 Parse link entities into Data::Invoice. 2022-07-26 20:12:13 +03:00
John Preston
9d7060c24a Pass secondary_bg_color to WebView-s. 2022-07-26 20:12:13 +03:00
John Preston
b4b55973b5 Request and cache featured emoji sets. 2022-07-26 20:12:13 +03:00
John Preston
b31a3ba5a3 Improve emoji set box design. 2022-07-26 20:12:13 +03:00
23rd
152bcb3570 Changed calculation of discount for premium gifts relative to smallest. 2022-07-26 20:12:13 +03:00
23rd
d2170232af Added toast to privacy setting for voice messages for non-premium users. 2022-07-26 20:12:13 +03:00
John Preston
4c45ddfde1 Fix slot machine stickers size. 2022-07-26 20:12:13 +03:00
John Preston
18a6f7d700 Make 8 column emoji picker by default. 2022-07-26 20:12:13 +03:00
John Preston
265bebb304 Closed alpha version 4.0.2.2. 2022-07-26 20:12:13 +03:00
John Preston
905137e421 Respect kSetVersion in default set cache key. 2022-07-26 20:12:12 +03:00
John Preston
b14b69272a Fix build with GCC. 2022-07-26 20:12:12 +03:00
John Preston
45b875f1a1 Closed alpha 4.0.2.1. 2022-07-26 20:12:12 +03:00
John Preston
1171c4b0b1 Fix build after rebase. 2022-07-26 20:12:12 +03:00
23rd
505e60545e Respected privacy setting for voice messages when they are forwarded. 2022-07-26 20:12:12 +03:00
John Preston
c9aec6a170 Update emoji to Unicode 14. 2022-07-26 20:12:12 +03:00
John Preston
bb29773090 In jump-to-date don't clear history stack. 2022-07-26 20:12:12 +03:00
John Preston
58fb14e292 Show Experimental settings in builds without autoupdates. 2022-07-26 20:12:12 +03:00
John Preston
bb251627a9 Support additional payment methods. 2022-07-26 20:12:12 +03:00
John Preston
de0eef8cc6 Update API scheme on layer 144. 2022-07-26 20:12:12 +03:00
John Preston
04d4fdbf9b Support suggestions of custom emoji. 2022-07-26 20:12:12 +03:00
John Preston
bf286cf175 Show "Unlock emoji" button for premium sets. 2022-07-26 20:12:12 +03:00
John Preston
bb7249f280 Allow viewing emoji sets used in a message. 2022-07-26 20:12:12 +03:00
John Preston
fce4452af5 Fix repainting of custom emoji in notifications. 2022-07-26 20:12:12 +03:00
John Preston
8a9549dca3 Fix custom emoji preview painting on Retina screen. 2022-07-26 20:12:12 +03:00
John Preston
8383caa2b5 Fix build with Xcode. 2022-07-26 20:12:12 +03:00
23rd
57ecd918f1 Added auto-unblocking of bot when it is auto-submitted. 2022-07-26 20:12:11 +03:00
23rd
2055fbc164 Added ability to hide sticker toast with right click. 2022-07-26 20:12:11 +03:00
23rd
31a683ab3d Added lock icon to buttons in privacy settings. 2022-07-26 20:12:11 +03:00
23rd
391082712a Added fallback sticker for pack for premium gifts even without order. 2022-07-26 20:12:11 +03:00
23rd
b7189556f8 Respected order from special pack for premium gifts. 2022-07-26 20:12:11 +03:00
John Preston
240b47da86 Check test/production DC in recent emoji. 2022-07-26 20:12:11 +03:00
John Preston
323c2a6aa5 Don't send custom emoji links to generate previews. 2022-07-26 20:12:11 +03:00
John Preston
5ce8ed80bf Show premium emoji tooltip on paste. 2022-07-26 20:12:11 +03:00
John Preston
4ca6af33d4 Support web_app_request_phone attach bot requests. 2022-07-26 20:12:11 +03:00
John Preston
2524b9a4c6 Show outline for premium emoji packs. 2022-07-26 20:12:11 +03:00
John Preston
3ccc567e04 Add animated emoji premium preview. 2022-07-26 20:12:11 +03:00
John Preston
66b2bdd656 Improve footer custom emoji sizes. 2022-07-26 20:12:11 +03:00
John Preston
ffe4babe89 Update API scheme on layer 144. 2022-07-26 20:12:11 +03:00
23rd
3fe83282a8 Slightly improved code style of controllers for privacy settings. 2022-07-26 20:12:11 +03:00
23rd
67195f3825 Added initial support of privacy setting for voice messages. 2022-07-26 20:12:11 +03:00
23rd
b295a9eeb1 Added support of service actions for premium gifts to export. 2022-07-26 20:12:11 +03:00
23rd
e84f5aaa3d Added support of service actions for premium gifts. 2022-07-26 20:12:11 +03:00
23rd
ef72c9f7ee Moved media above text in service messages. 2022-07-26 20:12:11 +03:00
23rd
89a3462824 Simplified extracting of data from some MTP* responses. 2022-07-26 20:12:11 +03:00
John Preston
44a7d11e4a Support mixed custom / default recent emoji. 2022-07-26 20:12:11 +03:00
John Preston
c0ec3a23bb Remove old emoji panel footer code. 2022-07-26 20:12:11 +03:00
John Preston
a821c3c31d Support thumb_document_id in emoji sets. 2022-07-26 20:12:10 +03:00
John Preston
64f25a6dae Fix sticker sets icons scrollMax. 2022-07-26 20:12:10 +03:00
John Preston
f1144965c0 Scroll expanded emoji category icons by wheel. 2022-07-26 20:12:10 +03:00
John Preston
007cb9d156 Allow dragging the expanded emoji categories. 2022-07-26 20:12:10 +03:00
John Preston
57d5ec4513 Handle clicks on expandable emoji category icons. 2022-07-26 20:12:10 +03:00
John Preston
38a69242ca Update API scheme on layer 144. 2022-07-26 20:12:10 +03:00
John Preston
3dfe48a407 Display selected emoji set in footer by background. 2022-07-26 20:12:10 +03:00
John Preston
0bd9d5f7ae Expand emoji categories in the footer. 2022-07-26 20:12:10 +03:00
John Preston
d3f62d971d Use unified StickersListFooter for emoji / stickers. 2022-07-26 20:12:10 +03:00
John Preston
25f4646cd8 Adapt emoji pack preview box. 2022-07-26 20:12:10 +03:00
John Preston
54d683171d Allow to open / remove sets from emoji panel. 2022-07-26 20:12:10 +03:00
John Preston
a7e295ae64 Fix build with Xcode. 2022-07-26 20:12:10 +03:00
John Preston
ddd5021966 Minimal emoji sets support. 2022-07-26 20:12:10 +03:00
John Preston
afc7b1da62 Update API scheme on layer 144. 2022-07-26 20:12:10 +03:00
John Preston
6e25a2fc12 Provide single-data generic TL accessor. 2022-07-26 20:12:10 +03:00
John Preston
9eaac98070 Fix build for Windows. 2022-07-26 20:12:10 +03:00
23rd
38322dc998 Fixed display of quiz solution in sections. 2022-07-26 20:12:10 +03:00
23rd
5fbbdd8a9e Added ability to choose to show recent group history for each new user.
Fixed #9864.
2022-07-26 20:12:10 +03:00
23rd
c14d9b18f7 Added ability to copy link from confirmation box on hidden url.
Fixed #17480.
2022-07-26 20:12:10 +03:00
23rd
df66743c61 Added right padding to text in top bar of sections. 2022-07-26 20:12:10 +03:00
23rd
1a6b6e6084 Fixed right padding of text in dialogs entries with unread reactions. 2022-07-26 20:12:10 +03:00
23rd
9f11c783eb Fixed scheduling of recorded voice messages. 2022-07-26 20:12:10 +03:00
23rd
bcdcd7ee70 Disabled animation for first showing of right button in pinned bar. 2022-07-26 20:12:10 +03:00
23rd
6cc0d4f7d5 Removed uppercase from admin log section. 2022-07-26 20:12:09 +03:00
23rd
6450c213e6 Fixed some global shortcuts with non-primary windows. 2022-07-26 20:12:09 +03:00
23rd
032372f150 Added stars animation to box for premium gifts. 2022-07-26 20:12:09 +03:00
23rd
c7c8ebed13 Added initial box for premium gifts. 2022-07-26 20:12:09 +03:00
23rd
2a3d72ad2e Added ability to provide custom text to subscribe button. 2022-07-26 20:12:09 +03:00
23rd
afb336ed41 Added list for options of premium gifts. 2022-07-26 20:12:09 +03:00
23rd
009ef829a0 Moved computing of premium gradient parts to separated class. 2022-07-26 20:12:09 +03:00
23rd
99676c4cf8 Moved some premium styles to separate file. 2022-07-26 20:12:09 +03:00
John Preston
0ed434cfaf Show all stickers as emoji after default categories. 2022-07-26 20:12:09 +03:00
John Preston
248e0d502c Revert "For testing insert stickers as custom emoji."
This reverts commit 17095983c546326223cd8eb69453f7f4c7dd8e78.
2022-07-26 20:12:09 +03:00
John Preston
4127b68675 Fix non-square video-emoji. 2022-07-26 20:12:09 +03:00
John Preston
11fbc8112f Fix monospace text color in chats list. 2022-07-26 20:12:09 +03:00
John Preston
c1e7e63677 Support custom popups in attach bots. 2022-07-26 20:12:09 +03:00
John Preston
e954871cb9 Make custom emoji size 12% larger. 2022-07-26 20:12:09 +03:00
John Preston
c1cdca36d2 Fix custom emoji before a newline. 2022-07-26 20:12:09 +03:00
John Preston
754371a295 Optimize custom emoji repaints in pinned bar / reply info. 2022-07-26 20:12:09 +03:00
John Preston
68ee753fc7 Fix sender name / media color in chats list previews. 2022-07-26 20:12:09 +03:00
John Preston
2a8e035f42 For testing insert stickers as custom emoji. 2022-07-26 20:12:09 +03:00
John Preston
b87fd601ab Update API scheme on layer 144. 2022-07-26 20:12:09 +03:00
John Preston
c01d9747e7 Fix inline via @bot click in additional windows
Fixes #24717.
2022-07-26 20:12:09 +03:00
John Preston
6d17226c7f Don't show bold markup in chats list previews. 2022-07-26 20:12:09 +03:00
John Preston
90cd4afb8c Remove empty icon space in Manage Group settings. 2022-07-26 20:12:09 +03:00
John Preston
15d6988511 Don't clear history stack on sendBotCommand. 2022-07-26 20:12:09 +03:00
John Preston
d00755100a Update API scheme on layer 144. 2022-07-26 20:12:09 +03:00
John Preston
3238cf2b4b Support custom emoji in reply / pinned / forward bars. 2022-07-26 20:12:08 +03:00
John Preston
2fc43a44a4 Don't paste custom emoji for non-premium users. 2022-07-26 20:12:08 +03:00
John Preston
b976aa0872 Support custom emoji in chats list entries. 2022-07-26 20:12:08 +03:00
John Preston
ee8d8171f7 Support custom emoji in custom notification replies. 2022-07-26 20:12:08 +03:00
John Preston
8c8cbbbc83 Display custom emoji in custom notifications. 2022-07-26 20:12:08 +03:00
John Preston
be36f07168 Fix custom emoji in service messages. 2022-07-26 20:12:08 +03:00
John Preston
289602528c Fix custom emoji pausing in captions. 2022-07-26 20:12:08 +03:00
John Preston
7a10d3d82c Support animated emoji in share box comment. 2022-07-26 20:12:08 +03:00
John Preston
806c5ddf29 Support animated emoji in caption edit fields. 2022-07-26 20:12:08 +03:00
John Preston
00d1828fbe Update API scheme on layer 144. 2022-07-26 20:12:08 +03:00
John Preston
2499955496 Support custom emoji in the message input field. 2022-07-26 20:12:08 +03:00
John Preston
cb32c3957b Add LZ4 caching for animated emoji. 2022-07-26 20:12:08 +03:00
John Preston
c4dd45689d Use src/dst prefixes instead of from/to. 2022-07-26 20:12:08 +03:00
John Preston
3c01bb5a4a Add support for static and webm custom emoji. 2022-07-26 20:12:08 +03:00
John Preston
8ed101cbbf Insert recent stickers as emoji for testing. 2022-07-26 20:12:08 +03:00
John Preston
c796dd142b Optimize many animated emoji repaint requests. 2022-07-26 20:12:08 +03:00
John Preston
6db3a0ec98 Support optimized lottie emoji. 2022-07-26 20:12:08 +03:00
John Preston
9d280da80b Start optimized custom emoji, show path thumbnail. 2022-07-26 20:12:08 +03:00
John Preston
2e6733e433 Proof-of-concept animated custom emoji. 2022-07-26 20:12:08 +03:00
John Preston
21aa1323ec Provide custom emoji factory through MarkedTextContext. 2022-07-26 20:12:08 +03:00
John Preston
bbfcac26c9 Update UiIntegration for custom emoji. 2022-07-26 20:12:08 +03:00
John Preston
368bc283a1 Don't use Ui::Text::String copy construct/assign. 2022-07-26 20:12:07 +03:00
Vedant
182c07db7f WinGet: Publish beta releases also 2022-07-26 21:11:45 +04:00
Ilya Fedin
9b8dcec26e Ensure notification manager is not null before first call to setManager in cross-platform code 2022-07-26 21:11:17 +04:00
Ilya Fedin
6718d238af Switch to the dummy notification manager when notification daemon is not running on Linux 2022-07-26 21:11:17 +04:00
Ilya Fedin
dd70a6f659 IsQualifiedDaemon -> ByDefault 2022-07-26 21:11:17 +04:00
Ilya Fedin
ff2bd86744 Have a central place for catch-based logging of linux native notifications 2022-07-26 21:11:17 +04:00
Ilya Fedin
d2e3c01c11 Get linux notification inhibition state asynchronously
This is the last sync request in the D-Bus notifications
2022-07-26 21:11:17 +04:00
Ilya Fedin
e9e5dedeed Update Hunspell to get rid of 'error: cannot open' 2022-07-26 21:09:46 +04:00
Ilya Fedin
e8477e5911 Get rid of 'paramtersCopy' in dbus code 2022-07-26 21:09:30 +04:00
GitHub Action
238a2f4477 Update User-Agent for DNS to Chrome 103.0.5060.53. 2022-07-19 19:35:36 +04:00
Ilya Fedin
9502ce8b32 Use templating with Dockerfile in order to have less rebuilds 2022-07-19 19:34:44 +04:00
nintendoit
653f17915e money-purchasing and money-advertising updated
Changed money-purchasing from 'none' to 'intense' as the in-app purchase of telegram premium is available.
Added money-advertising and set it to 'moderate' as telegram ads has been introduced.
2022-07-19 19:33:16 +04:00
Niklas Haas
6096116526 Use quasi-logarithmic volume controls
This commit significantly improves the usability of the volume controls
for controlling volume in a way that matches intuitively onto human
needs and loudness perception.

Using the third power of the volume is a good approximation of the
quasi-logarithmic psychoacoustic system, while being defined everywhere
and preserving the useful quality of 0% volume mapping onto gain 0.0.
The use of this exact mapping function is a prior art established by
e.g. PulseAudio, among many other programs.

Fixes #24488
2022-07-19 19:32:46 +04:00
Vedant
5c3f15af41 Update winget.yml 2022-07-01 19:15:41 +04:00
Vedant
ca37a727fc Update winget.yml 2022-07-01 19:15:41 +04:00
Begula
598a4b3922 Create winget.yml 2022-07-01 19:15:41 +04:00
Ilya Fedin
060cd0aab9 Don't trigger actions on build documentation change
Documentation is not sourced in actions since prepare.py invention
2022-06-29 08:21:16 +04:00
Ilya Fedin
463f437486 Update lib_ui 2022-06-28 09:49:45 +04:00
Ilya Fedin
0e97ef992e Build OpenSSL 1.1.1 in snap 2022-06-28 09:49:45 +04:00
Ilya Fedin
d09a591d1b Use *.so everywhere to exclude devlopment symlinks in snap 2022-06-28 09:49:45 +04:00
Ilya Fedin
aeddaf3dbd Update openal to 1.22.2 2022-06-28 09:49:45 +04:00
762 changed files with 30859 additions and 11129 deletions

21
.github/stale.yml vendored
View File

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

View File

@@ -24,9 +24,15 @@ jobs:
with:
submodules: recursive
- name: First set up.
run: curl -sSL https://install.python-poetry.org | python3 -
- name: Docker image build.
run: docker build -t $IMAGE_TAG --build-arg DEBUG= Telegram/build/docker/centos_env
run: |
cd Telegram/build/docker/centos_env
poetry install
DEBUG= poetry run gen_dockerfile | docker buildx build -t $IMAGE_TAG -
- name: Push the Docker image.
if: ${{ github.ref_name == github.event.repository.default_branch }}
run: |

View File

@@ -5,7 +5,6 @@ on:
paths-ignore:
- 'docs/**'
- '**.md'
- '!docs/building-linux.md'
- 'changelog.txt'
- 'LEGAL'
- 'LICENSE'
@@ -24,7 +23,6 @@ on:
paths-ignore:
- 'docs/**'
- '**.md'
- '!docs/building-linux.md'
- 'changelog.txt'
- 'LEGAL'
- 'LICENSE'
@@ -79,7 +77,7 @@ jobs:
- name: First set up.
run: |
gcc --version
ln -s $LibrariesPath Libraries
ln -s /usr/src/Libraries
- name: Telegram Desktop build.
run: |
@@ -99,7 +97,6 @@ jobs:
-D CMAKE_CXX_FLAGS="-Werror" \
-D CMAKE_EXE_LINKER_FLAGS="-s" \
-D TDESKTOP_API_TEST=ON \
-D DESKTOP_APP_USE_PACKAGED=OFF \
-D DESKTOP_APP_DISABLE_CRASH_REPORTS=OFF \
$DEFINE

View File

@@ -5,7 +5,6 @@ on:
paths-ignore:
- 'docs/**'
- '**.md'
- '!docs/building-mac.md'
- 'changelog.txt'
- 'LEGAL'
- 'LICENSE'
@@ -23,7 +22,6 @@ on:
paths-ignore:
- 'docs/**'
- '**.md'
- '!docs/building-mac.md'
- 'changelog.txt'
- 'LEGAL'
- 'LICENSE'
@@ -116,7 +114,6 @@ jobs:
-D CMAKE_C_FLAGS="-Werror" \
-D CMAKE_CXX_FLAGS="-Werror" \
-D TDESKTOP_API_TEST=ON \
-D DESKTOP_APP_USE_PACKAGED=OFF \
-D DESKTOP_APP_DISABLE_CRASH_REPORTS=OFF \
$DEFINE

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

@@ -0,0 +1,25 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v5
with:
stale-issue-message: |
Hey there!
This issue was inactive for a long time and will be automatically closed in 30 days if there isn't any further activity. We therefore assume that the user has lost interest or resolved the problem on their own.
Don't worry though; if this is an error, let us know with a comment and we'll be happy to reopen the issue.
Thanks!
stale-issue-label: 'stale'
exempt-issue-labels: 'enhancement'
days-before-stale: 180
days-before-close: 30
days-before-pr-stale: -1
operations-per-run: 1000

View File

@@ -5,7 +5,6 @@ on:
paths-ignore:
- 'docs/**'
- '**.md'
- '!docs/building-win.md'
- 'changelog.txt'
- 'LEGAL'
- 'LICENSE'
@@ -24,7 +23,6 @@ on:
paths-ignore:
- 'docs/**'
- '**.md'
- '!docs/building-win.md'
- 'changelog.txt'
- 'LEGAL'
- 'LICENSE'
@@ -81,23 +79,12 @@ jobs:
submodules: recursive
path: ${{ env.TBUILD }}\${{ env.REPO_NAME }}
- name: Choco installs.
run: |
choco install --no-progress -y nasm strawberryperl yasm jom ninja
py -m pip install pywin32
- name: Install msys64.
run: |
mkdir %TBUILD%\ThirdParty
xcopy /E /I C:\msys64 %TBUILD%\ThirdParty\msys64
- name: Python installs.
run: py -m pip install pywin32 six
- name: Set up environment paths.
shell: bash
run: |
echo "C:\\Strawberry\\perl\\bin\\" >> $GITHUB_PATH
echo "C:\\Program Files\\NASM\\" >> $GITHUB_PATH
echo "C:\\ProgramData\\chocolatey\\lib\\ninja\\tools\\" >> $GITHUB_PATH
echo "CACHE_KEY=$(sha256sum $TBUILD/$REPO_NAME/$PREPARE_PATH | awk '{ print $1 }')" >> $GITHUB_ENV
echo "Configurate git for cherry-picks."
@@ -151,7 +138,6 @@ jobs:
call configure.bat ^
${{ matrix.arch }} ^
-D TDESKTOP_API_TEST=ON ^
-D DESKTOP_APP_USE_PACKAGED=OFF ^
-D DESKTOP_APP_DISABLE_CRASH_REPORTS=OFF ^
-D DESKTOP_APP_NO_PDB=ON ^
%TDESKTOP_BUILD_DEFINE% ^

18
.github/workflows/winget.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: Publish to WinGet
on:
release:
types: [released, prereleased]
jobs:
publish:
runs-on: windows-latest # action can only be run on windows
steps:
- if: github.event.action == 'released'
uses: telegramdesktop/winget-releaser@main
with:
identifier: Telegram.TelegramDesktop
token: ${{ secrets.WINGET_TOKEN }}
- if: github.event.action == 'prereleased'
uses: telegramdesktop/winget-releaser@main
with:
identifier: Telegram.TelegramDesktop.Beta
token: ${{ secrets.WINGET_TOKEN }}

6
.gitmodules vendored
View File

@@ -79,9 +79,6 @@
[submodule "Telegram/lib_webview"]
path = Telegram/lib_webview
url = https://github.com/desktop-app/lib_webview.git
[submodule "Telegram/lib_waylandshells"]
path = Telegram/lib_waylandshells
url = https://github.com/desktop-app/lib_waylandshells.git
[submodule "Telegram/ThirdParty/jemalloc"]
path = Telegram/ThirdParty/jemalloc
url = https://github.com/jemalloc/jemalloc
@@ -94,3 +91,6 @@
[submodule "Telegram/ThirdParty/wayland-protocols"]
path = Telegram/ThirdParty/wayland-protocols
url = https://github.com/gitlab-freedesktop-mirrors/wayland-protocols.git
[submodule "Telegram/ThirdParty/kimageformats"]
path = Telegram/ThirdParty/kimageformats
url = https://github.com/KDE/kimageformats.git

View File

@@ -38,6 +38,8 @@ get_filename_component(cmake_helpers_loc "cmake" REALPATH)
include(cmake/variables.cmake)
include(cmake/nice_target_sources.cmake)
include(cmake/target_compile_options_if_exists.cmake)
include(cmake/target_link_options_if_exists.cmake)
include(cmake/target_link_static_libraries.cmake)
include(cmake/target_link_frameworks.cmake)
include(cmake/init_target.cmake)
@@ -48,6 +50,15 @@ include(cmake/target_prepare_qrc.cmake)
include(cmake/options.cmake)
if (NOT DESKTOP_APP_USE_PACKAGED)
if (WIN32)
set(qt_version 5.15.4)
elseif (APPLE)
set(qt_version 6.3.1)
else()
set(qt_version 6.4.0)
endif()
endif()
include(cmake/external/qt/package.cmake)
set(desktop_app_skip_libs

View File

@@ -1,6 +1,6 @@
# [Telegram Desktop][telegram_desktop] Official Messenger
This is the complete source code and the build instructions for the alpha version of the official desktop client for the [Telegram][telegram] messenger, based on the [Telegram API][telegram_api] and the [MTProto][telegram_proto] secure protocol.
This is the complete source code and the build instructions for the official [Telegram][telegram] messenger desktop client, based on the [Telegram API][telegram_api] and the [MTProto][telegram_proto] secure protocol.
[![Version](https://badge.fury.io/gh/telegramdesktop%2Ftdesktop.svg)](https://github.com/telegramdesktop/tdesktop/releases)
[![Build Status](https://github.com/telegramdesktop/tdesktop/workflows/Windows./badge.svg)](https://github.com/telegramdesktop/tdesktop/actions)

View File

@@ -18,9 +18,6 @@ endif()
add_subdirectory(lib_storage)
add_subdirectory(lib_lottie)
add_subdirectory(lib_qr)
if (LINUX AND NOT DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
add_subdirectory(lib_waylandshells)
endif()
add_subdirectory(lib_webrtc)
add_subdirectory(lib_webview)
add_subdirectory(codegen)
@@ -82,9 +79,9 @@ PRIVATE
desktop-app::lib_webview
desktop-app::lib_ffmpeg
desktop-app::lib_stripe
desktop-app::external_lz4
desktop-app::external_rlottie
desktop-app::external_zlib
desktop-app::external_kcoreaddons
desktop-app::external_qt_static_plugins
desktop-app::external_qt
desktop-app::external_qr_code_generator
@@ -139,6 +136,8 @@ PRIVATE
api/api_polls.h
api/api_premium.cpp
api/api_premium.h
api/api_premium_option.cpp
api/api_premium_option.h
api/api_report.cpp
api/api_report.h
api/api_ringtones.cpp
@@ -240,6 +239,8 @@ PRIVATE
boxes/edit_color_box.h
boxes/edit_privacy_box.cpp
boxes/edit_privacy_box.h
boxes/gift_premium_box.cpp
boxes/gift_premium_box.h
boxes/language_box.cpp
boxes/language_box.h
boxes/local_storage_box.cpp
@@ -366,8 +367,12 @@ PRIVATE
chat_helpers/stickers_emoji_image_loader.h
chat_helpers/stickers_emoji_pack.cpp
chat_helpers/stickers_emoji_pack.h
chat_helpers/stickers_gift_box_pack.cpp
chat_helpers/stickers_gift_box_pack.h
chat_helpers/stickers_dice_pack.cpp
chat_helpers/stickers_dice_pack.h
chat_helpers/stickers_list_footer.cpp
chat_helpers/stickers_list_footer.h
chat_helpers/stickers_list_widget.cpp
chat_helpers/stickers_list_widget.h
chat_helpers/stickers_lottie.cpp
@@ -419,6 +424,8 @@ PRIVATE
data/notify/data_notify_settings.h
data/notify/data_peer_notify_settings.cpp
data/notify/data_peer_notify_settings.h
data/stickers/data_custom_emoji.cpp
data/stickers/data_custom_emoji.h
data/stickers/data_stickers_set.cpp
data/stickers/data_stickers_set.h
data/stickers/data_stickers.cpp
@@ -456,6 +463,8 @@ PRIVATE
data/data_download_manager.h
data/data_drafts.cpp
data/data_drafts.h
data/data_emoji_statuses.cpp
data/data_emoji_statuses.h
data/data_folder.cpp
data/data_folder.h
data/data_file_click_handler.cpp
@@ -479,6 +488,8 @@ PRIVATE
data/data_media_types.h
# data/data_messages.cpp
# data/data_messages.h
data/data_message_reaction_id.cpp
data/data_message_reaction_id.h
data/data_message_reactions.cpp
data/data_message_reactions.h
data/data_msg_id.h
@@ -606,50 +617,69 @@ PRIVATE
history/view/controls/history_view_voice_record_bar.h
history/view/controls/history_view_voice_record_button.cpp
history/view/controls/history_view_voice_record_button.h
history/view/media/history_view_call.h
history/view/media/history_view_call.cpp
history/view/media/history_view_contact.h
history/view/media/history_view_call.h
history/view/media/history_view_contact.cpp
history/view/media/history_view_dice.h
history/view/media/history_view_contact.h
history/view/media/history_view_custom_emoji.cpp
history/view/media/history_view_custom_emoji.h
history/view/media/history_view_dice.cpp
history/view/media/history_view_document.h
history/view/media/history_view_dice.h
history/view/media/history_view_document.cpp
history/view/media/history_view_file.h
history/view/media/history_view_document.h
history/view/media/history_view_extended_preview.cpp
history/view/media/history_view_extended_preview.h
history/view/media/history_view_file.cpp
history/view/media/history_view_game.h
history/view/media/history_view_file.h
history/view/media/history_view_game.cpp
history/view/media/history_view_gif.h
history/view/media/history_view_game.h
history/view/media/history_view_gif.cpp
history/view/media/history_view_invoice.h
history/view/media/history_view_gif.h
history/view/media/history_view_invoice.cpp
history/view/media/history_view_large_emoji.h
history/view/media/history_view_invoice.h
history/view/media/history_view_large_emoji.cpp
history/view/media/history_view_location.h
history/view/media/history_view_large_emoji.h
history/view/media/history_view_location.cpp
history/view/media/history_view_media.h
history/view/media/history_view_location.h
history/view/media/history_view_media.cpp
history/view/media/history_view_media_common.h
history/view/media/history_view_media.h
history/view/media/history_view_media_common.cpp
history/view/media/history_view_media_grouped.h
history/view/media/history_view_media_common.h
history/view/media/history_view_media_grouped.cpp
history/view/media/history_view_media_unwrapped.h
history/view/media/history_view_media_grouped.h
history/view/media/history_view_media_unwrapped.cpp
history/view/media/history_view_photo.h
history/view/media/history_view_media_unwrapped.h
history/view/media/history_view_photo.cpp
history/view/media/history_view_poll.h
history/view/media/history_view_photo.h
history/view/media/history_view_poll.cpp
history/view/media/history_view_slot_machine.h
history/view/media/history_view_poll.h
history/view/media/history_view_service_media_gift.cpp
history/view/media/history_view_service_media_gift.h
history/view/media/history_view_slot_machine.cpp
history/view/media/history_view_sticker.h
history/view/media/history_view_slot_machine.h
history/view/media/history_view_sticker.cpp
history/view/media/history_view_theme_document.h
history/view/media/history_view_sticker.h
history/view/media/history_view_sticker_player.cpp
history/view/media/history_view_sticker_player.h
history/view/media/history_view_sticker_player_abstract.h
history/view/media/history_view_theme_document.cpp
history/view/media/history_view_web_page.h
history/view/media/history_view_theme_document.h
history/view/media/history_view_web_page.cpp
history/view/reactions/message_reactions_list.cpp
history/view/reactions/message_reactions_list.h
history/view/reactions/message_reactions_selector.cpp
history/view/reactions/message_reactions_selector.h
history/view/media/history_view_web_page.h
history/view/reactions/history_view_reactions.cpp
history/view/reactions/history_view_reactions.h
history/view/reactions/history_view_reactions_animation.cpp
history/view/reactions/history_view_reactions_animation.h
history/view/reactions/history_view_reactions_button.cpp
history/view/reactions/history_view_reactions_button.h
history/view/reactions/history_view_reactions_list.cpp
history/view/reactions/history_view_reactions_list.h
history/view/reactions/history_view_reactions_selector.cpp
history/view/reactions/history_view_reactions_selector.h
history/view/reactions/history_view_reactions_strip.cpp
history/view/reactions/history_view_reactions_strip.h
history/view/reactions/history_view_reactions_tabs.cpp
history/view/reactions/history_view_reactions_tabs.h
history/view/history_view_bottom_info.cpp
history/view/history_view_bottom_info.h
history/view/history_view_contact_status.cpp
@@ -680,12 +710,6 @@ PRIVATE
history/view/history_view_pinned_tracker.h
history/view/history_view_quick_action.cpp
history/view/history_view_quick_action.h
history/view/history_view_react_animation.cpp
history/view/history_view_react_animation.h
history/view/history_view_react_button.cpp
history/view/history_view_react_button.h
history/view/history_view_reactions.cpp
history/view/history_view_reactions.h
history/view/history_view_replies_section.cpp
history/view/history_view_replies_section.h
history/view/history_view_requests_bar.cpp
@@ -785,8 +809,12 @@ PRIVATE
info/polls/info_polls_results_widget.h
info/profile/info_profile_actions.cpp
info/profile/info_profile_actions.h
info/profile/info_profile_badge.cpp
info/profile/info_profile_badge.h
info/profile/info_profile_cover.cpp
info/profile/info_profile_cover.h
info/profile/info_profile_emoji_status_panel.cpp
info/profile/info_profile_emoji_status_panel.h
info/profile/info_profile_icon.cpp
info/profile/info_profile_icon.h
info/profile/info_profile_inner_widget.cpp
@@ -1167,8 +1195,6 @@ PRIVATE
storage/storage_account.h
storage/storage_cloud_blob.cpp
storage/storage_cloud_blob.h
storage/storage_cloud_song_cover.cpp
storage/storage_cloud_song_cover.h
storage/storage_domain.cpp
storage/storage_domain.h
storage/storage_facade.cpp
@@ -1442,18 +1468,13 @@ else()
endif()
if (NOT DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION)
if (DESKTOP_APP_QT6)
qt6_generate_wayland_protocol_client_sources(Telegram
FILES
${third_party_loc}/plasma-wayland-protocols/src/protocols/plasma-shell.xml
)
else()
message(FATAL_ERROR "This piece of cmake code is not ported to Qt 5")
endif()
qt_generate_wayland_protocol_client_sources(Telegram
FILES
${third_party_loc}/plasma-wayland-protocols/src/protocols/plasma-shell.xml
)
target_link_libraries(Telegram
PRIVATE
desktop-app::lib_waylandshells
desktop-app::external_wayland_client
)
endif()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 KiB

After

Width:  |  Height:  |  Size: 821 KiB

View File

@@ -52,6 +52,16 @@ function ShowMentionName() {
return false;
}
function ShowNotLoadedEmoji() {
ShowToast("This custom emoji is not included, change data exporting settings to download.");
return false;
}
function ShowNotAvailableEmoji() {
ShowToast("This custom emoji is not available.");
return false;
}
function ShowSpoiler(target) {
if (target.classList.contains("hidden")) {
target.classList.toggle("hidden");

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 882 B

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,9 +1 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" viewBox="0 0 76 73" xmlns="http://www.w3.org/2000/svg">
<title>Star</title>
<g fill="none" fill-rule="evenodd">
<g transform="translate(-5 -5)" fill="#fff">
<path d="m40.806 66.037-17.389 10.627c-1.5943 0.97436-3.6766 0.4718-4.651-1.1225-0.47558-0.77817-0.61685-1.7154-0.39178-2.5992l2.8114-11.039c0.91458-3.5913 3.3384-6.6111 6.6467-8.281l15.265-7.7056c0.84279-0.42542 1.1811-1.4535 0.7557-2.2963-0.3335-0.66067-1.0543-1.0317-1.7857-0.91925l-17.288 2.6578c-4.0448 0.62183-8.1617-0.52596-11.301-3.1508l-7.112-5.9459c-1.4335-1.1985-1.624-3.3321-0.42557-4.7656 0.58391-0.69842 1.4246-1.1321 2.3322-1.2029l20.357-1.5894c1.3848-0.10811 2.5919-0.98375 3.1246-2.2665l7.8535-18.913c0.71656-1.7256 2.6963-2.5436 4.4219-1.8271 0.82676 0.34331 1.4838 1.0003 1.8271 1.8271l7.8535 18.913c0.53267 1.2828 1.7398 2.1584 3.1246 2.2665l20.456 1.5971c1.8628 0.14544 3.255 1.7734 3.1096 3.6363-0.070088 0.89771-0.49515 1.7304-1.1811 2.3138l-15.589 13.259c-1.0616 0.90287-1.5248 2.3263-1.1979 3.681l4.7945 19.87c0.43827 1.8163-0.67888 3.6441-2.4952 4.0824-0.87218 0.21045-1.7922 0.065833-2.5578-0.40204l-17.515-10.704c-1.1827-0.72283-2.6706-0.72283-3.8533 0z"/>
</g>
</g>
</svg>
<svg width="84" height="81" viewBox="0 0 84 81" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-190.000000, -73.000000)" fill="#fff"><defs>gradientPlaceholder</defs><path d="M217.584175 95.7198452l10.102137-20.1302773C228.851735 73.2672578 231.669488 72.3342655 233.979937 73.5056713 234.886993 73.9655512 235.620771 74.7092927 236.070698 75.6248193l9.540513 19.41335C246.390574 96.6240434 247.914247 97.7068442 249.661599 97.9165844L269.640156 100.314675C272.352386 100.640233 274.288515 103.114133 273.96462 105.840286 273.831224 106.963049 273.321003 108.006556 272.518147 108.798619l-15.7911 15.578821C256.089452 125.006464 255.780497 125.898568 255.89167 126.789576L258.515919 147.821772C258.891602 150.832711 256.767771 153.579675 253.772209 153.957287 252.636962 154.100393 251.485656 153.881854 250.480518 153.332463L233.796907 144.21349C232.589892 143.553757 231.136827 143.534799 229.913183 144.162822l-17.2854 8.871545C210.195073 154.282929 207.215982 153.312865 205.973797 150.867667 205.509027 149.952785 205.337643 148.915649 205.483212 147.898872L206.864713 138.249309C207.540411 133.529666 210.458736 129.435705 214.68762 127.274973L233.885915 117.465678C234.398537 117.203755 234.602854 116.57373 234.342269 116.058476 234.140381 115.659283 233.708181 115.433429 233.267119 115.496635l-23.479483 3.364749C206.198378 119.375746 202.558336 118.361996 199.744254 116.064306L191.92377 109.678904C189.692048 107.856709 189.352516 104.561073 191.165405 102.317895 192.008458 101.274743 193.218498 100.597614 194.544752 100.426837L214.594132 97.8451554C215.880032 97.679575 217.000319 96.8832795 217.584175 95.7198452z"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -17,6 +17,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_menu_night_mode" = "Night Mode";
"lng_menu_add_account" = "Add Account";
"lng_menu_activate" = "Activate";
"lng_menu_set_status" = "Set Emoji Status";
"lng_menu_change_status" = "Change Emoji Status";
"lng_disable_notifications_from_tray" = "Disable notifications";
"lng_enable_notifications_from_tray" = "Enable notifications";
@@ -167,8 +169,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_channels_limit_title" = "Too Many Communities";
"lng_channels_limit1#one" = "You are a member of **{count}** groups and channels.";
"lng_channels_limit1#other" = "You are a member of **{count}** groups and channels.";
"lng_channels_limit2#one" = "Please leave some before joining a new one - or upgrade to **Telegram Premium** to doulbe the limit to **{count}** groups and channels.";
"lng_channels_limit2#other" = "Please leave some before joining a new one - or upgrade to **Telegram Premium** to doulbe the limit to **{count}** groups and channels.";
"lng_channels_limit2#one" = "Please leave some before joining a new one - or upgrade to **Telegram Premium** to double the limit to **{count}** groups and channels.";
"lng_channels_limit2#other" = "Please leave some before joining a new one - or upgrade to **Telegram Premium** to double the limit to **{count}** groups and channels.";
"lng_channels_limit2_final" = "Please leave some before joining a new one.";
"lng_channels_leave_title" = "Least active communities";
"lng_channels_leave_status" = "{type}, inactive {time}";
@@ -232,6 +234,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_sticker_premium_text" = "This pack contains premium stickers like this one.";
"lng_sticker_premium_view" = "View";
"lng_animated_emoji_text" = "Subscribe to **Telegram Premium** to unlock this emoji.";
"lng_animated_emoji_saved" = "Try sending these emoji in **Saved Messages** for free to test.";
"lng_animated_emoji_saved_open" = "Open";
"lng_reaction_premium_info" = "Click on the reaction to preview the animation.";
"lng_reaction_premium_no_group" = "Some reactions are restricted in this group.";
"lng_reaction_premium_no_channel" = "Some reactions are restricted in this channel.";
@@ -264,7 +269,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_proxy_unsupported" = "Your Telegram Desktop version doesn't support this proxy type or the proxy link is invalid. Please update Telegram Desktop to the latest version.";
"lng_edit_deleted" = "This message was deleted";
"lng_edit_too_long" = "Your message text is too long";
"lng_edit_limit_reached#one" = "You've reached the message text limit. Please make the text shorter by {count} character.";
"lng_edit_limit_reached#other" = "You've reached the message text limit. Please make the text shorter by {count} characters.";
"lng_edit_message" = "Edit message";
"lng_edit_message_text" = "New message text...";
"lng_deleted" = "Deleted Account";
@@ -498,6 +504,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_section_chat_settings" = "Chat Settings";
"lng_settings_replace_emojis" = "Replace emoji";
"lng_settings_suggest_emoji" = "Suggest emoji replacements";
"lng_settings_suggest_animated_emoji" = "Suggest animated emoji";
"lng_settings_suggest_by_emoji" = "Suggest popular stickers by emoji";
"lng_settings_loop_stickers" = "Loop animated stickers";
"lng_settings_large_emoji" = "Large emoji";
@@ -507,6 +514,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_send_cmdenter" = "Send by Cmd+Enter";
"lng_settings_chat_quick_action_reply" = "Reply with double click";
"lng_settings_chat_quick_action_react" = "Send reaction with double click";
"lng_settings_chat_corner_reaction" = "Reaction button on messages";
"lng_settings_chat_reactions_title" = "Quick Reaction";
"lng_settings_chat_reactions_subtitle" = "Choose your favorite reaction";
@@ -557,6 +565,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_phone_number_privacy" = "Phone number";
"lng_settings_forwards_privacy" = "Forwarded messages";
"lng_settings_profile_photo_privacy" = "Profile photo";
"lng_settings_voices_privacy" = "Voice messages";
"lng_settings_privacy_premium" = "Only subscribers of {link} can restrict receiving voice messages.";
"lng_settings_privacy_premium_link" = "Telegram Premium";
"lng_settings_sessions_about" = "Control your sessions on other devices.";
"lng_settings_passcode_disable" = "Disable Passcode";
"lng_settings_passcode_disable_sure" = "Are you sure you want to disable passcode?";
@@ -987,6 +998,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_privacy_profile_photo_always_title" = "Always allow";
"lng_edit_privacy_profile_photo_never_title" = "Never allow";
"lng_edit_privacy_voices_title" = "Voice messages settings";
"lng_edit_privacy_voices_header" = "Who can send me voice messages";
"lng_edit_privacy_voices_always_empty" = "Always allow";
"lng_edit_privacy_voices_never_empty" = "Never allow";
"lng_edit_privacy_voices_exceptions" = "These users will or will not be able to send voice and video messages to you regardless of the settings above.";
"lng_edit_privacy_voices_always_title" = "Always allow";
"lng_edit_privacy_voices_never_title" = "Never allow";
"lng_self_destruct_title" = "Account self-destruction";
"lng_self_destruct_description" = "If you don't come online at least once within this period, your account will be deleted along with all groups, messages and contacts.";
"lng_self_destruct_sessions_title" = "Session termination";
@@ -1140,6 +1159,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_unblock_user" = "Unblock user";
"lng_profile_export_chat" = "Export history";
"lng_profile_export_channel" = "Export history";
"lng_profile_gift_premium" = "Gift Premium";
"lng_media_selected_photo#one" = "{count} Photo";
"lng_media_selected_photo#other" = "{count} Photos";
"lng_media_selected_gif#one" = "{count} GIF";
@@ -1178,13 +1198,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_manage_peer_permissions" = "Permissions";
"lng_manage_peer_invite_links" = "Invite links";
"lng_manage_peer_reactions" = "Reactions";
"lng_manage_peer_reactions_on" = "All";
"lng_manage_peer_reactions_off" = "Off";
"lng_manage_peer_requests" = "Member Requests";
"lng_manage_peer_requests_channel" = "Subscriber Requests";
"lng_manage_peer_reactions_enable" = "Enable Reactions";
"lng_manage_peer_reactions_about" = "Allow members to react to group messages.";
"lng_manage_peer_reactions_about_channel" = "Allow subscribers to react to channel posts.";
"lng_manage_peer_reactions_all" = "All reactions";
"lng_manage_peer_reactions_all_about" = "Members of the group can use any emoji as reactions to messages.";
"lng_manage_peer_reactions_some" = "Some reactions";
"lng_manage_peer_reactions_some_about" = "You can select emoji that will allow members of your group to react to messages.";
"lng_manage_peer_reactions_none" = "No reactions";
"lng_manage_peer_reactions_none_about" = "Members of the group can't add any reactions to messages.";
"lng_manage_peer_reactions_some_title" = "Only allow these reactions";
"lng_manage_peer_reactions_available" = "Available reactions";
"lng_manage_peer_group_type" = "Group type";
@@ -1298,8 +1325,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_participant_filter" = "Search";
"lng_participant_invite" = "Invite";
"lng_participant_invite_history" = "Show the last 100 messages";
"lng_participant_invite_sure" = "Are you sure you want to add **{user}** to **{group}**?";
"lng_participant_invite_sure_many#one" = "Are you sure you want to add {count} member to **{group}**?";
"lng_participant_invite_sure_many#other" = "Are you sure you want to add {count} members to **{group}**?";
"lng_participant_invite_sorry#one" = "Sorry, you can only add the first {count} member to a channel personally.\n\nFrom now on, people will need to join via your invite link.";
"lng_participant_invite_sorry#other" = "Sorry, you can only add the first {count} members to a channel personally.\n\nFrom now on, people will need to join via your invite link.";
"lng_create_group_back" = "Back";
"lng_create_group_next" = "Next";
"lng_create_group_create" = "Create";
@@ -1446,10 +1478,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_you_theme_disabled" = "You disabled chat theme";
"lng_action_theme_disabled" = "{from} disabled chat theme";
"lng_action_proximity_distance_m#one" = "{count} meter";
"lng_action_proximity_distance_m#other" = "{count} metres";
"lng_action_proximity_distance_m#other" = "{count} meters";
"lng_action_proximity_distance_km#one" = "{count} km";
"lng_action_proximity_distance_km#other" = "{count} km";
"lng_action_webview_data_done" = "You have just successfully transferred data from the «{text}» button to the bot.";
"lng_action_gift_received" = "{user} sent you a gift for {cost}";
"lng_action_gift_received_me" = "You sent to {user} a gift for {cost}";
"lng_premium_gift_duration_months#one" = "for {count} month";
"lng_premium_gift_duration_months#other" = "for {count} months";
"lng_premium_gift_duration_years#one" = "for {count} year";
"lng_premium_gift_duration_years#other" = "for {count} years";
"lng_ttl_photo_received" = "{from} sent you a self-destructing photo. Please view it on your mobile.";
"lng_ttl_photo_sent" = "You sent a self-destructing photo.";
@@ -1671,24 +1710,49 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_premium_more_about" = "More About Telegram Premium";
"lng_premium_unlock_reactions" = "Unlock Premium Reactions";
"lng_premium_unlock_stickers" = "Unlock Premium Stickers";
"lng_premium_unlock_emoji" = "Unlock Animated Emoji";
"lng_premium_unlock_status" = "Unlock Emoji Status";
"lng_premium_subscribe_months_12" = "Annual";
"lng_premium_subscribe_months_6" = "Semiannual";
"lng_premium_subscribe_months_1" = "Monthly";
"lng_premium_subscribe_total" = "{cost} per year";
"lng_premium_subscribe_button" = "Subscribe for {cost} per month";
"lng_premium_emoji_status_title" = "{user} set this emoji from {link} as their current status.";
"lng_premium_emoji_status_title_colored" = "{user} set this emoji as their current status.";
"lng_premium_emoji_status_about" = "Emoji status is a premium feature. Other features included in **Telegram Premium**:";
"lng_premium_emoji_status_button" = "Unlock Emoji Status";
"lng_premium_summary_user_title" = "{user} is a subscriber of Telegram Premium.";
"lng_premium_summary_user_about" = "Owners of Telegram Premium accounts have exclusive access to multiple additional features.";
"lng_premium_summary_user_button" = "Learn More";
"lng_premium_summary_title" = "Telegram Premium";
"lng_premium_summary_top_about" = "Go **beyond the limits**, get **exclusive features** and support us by subscribing to **Telegram Premium**.";
"lng_premium_summary_title_subscribed" = "You are all set!";
"lng_premium_summary_subtitle_gift#one" = "{user} has gifted you a {count}-month subscription for Telegram Premium.";
"lng_premium_summary_subtitle_gift#other" = "{user} has gifted you a {count}-months subscription for Telegram Premium.";
"lng_premium_summary_subtitle_gift_me#one" = "You gifted {user} a {count}-month subscription for Telegram Premium.";
"lng_premium_summary_subtitle_gift_me#other" = "You gifted {user} a {count}-months subscription for Telegram Premium.";
"lng_premium_summary_subtitle_double_limits" = "Doubled Limits";
"lng_premium_summary_about_double_limits" = "Up to 1000 channels, 20 folders, 10 pins, 20 public links, 4 accounts and more.";
"lng_premium_summary_subtitle_more_upload" = "4Gb Upload Size";
"lng_premium_summary_about_more_upload" = "Increased upload size from 2Gb to 4Gb to per document, unlimited storage overall.";
"lng_premium_summary_about_more_upload" = "Increased upload size from 2Gb to 4Gb per document, unlimited storage overall.";
"lng_premium_summary_subtitle_faster_download" = "Faster Download Speed";
"lng_premium_summary_about_faster_download" = "No more limits on the speed with which media and documents are downloaded.";
"lng_premium_summary_subtitle_voice_to_text" = "Voice-to-Text Conversion";
"lng_premium_summary_about_voice_to_text" = "Ability to read the transcript of any incoming voice message.";
"lng_premium_summary_subtitle_no_ads" = "No Ads";
"lng_premium_summary_about_no_ads" = "No more ads in public channels where Telegram sometimes shows ads.";
"lng_premium_summary_subtitle_unique_reactions" = "Unique Reactions";
"lng_premium_summary_about_unique_reactions" = "Additional animated reactions on messages available only to the Premium subscribers.";
"lng_premium_summary_subtitle_emoji_status" = "Emoji Status";
"lng_premium_summary_about_emoji_status" = "Add any of thousands emoji next to your name to display current activity.";
"lng_premium_summary_subtitle_infinite_reactions" = "Infinite Reactions";
"lng_premium_summary_about_infinite_reactions" = "React with thousands of emoji — with multiple reactions per message.";
"lng_premium_summary_subtitle_premium_stickers" = "Premium Stickers";
"lng_premium_summary_about_premium_stickers" = "Exclusive enlarged stickers featuring additional effects, updated monthly.";
"lng_premium_summary_subtitle_animated_emoji" = "Animated Emoji";
"lng_premium_summary_about_animated_emoji" = "Include animated emoji from different emoji sets in any message you send.";
"lng_premium_summary_subtitle_advanced_chat_management" = "Advanced Chat Management";
"lng_premium_summary_about_advanced_chat_management" = "Tools to set default folder, auto-archive and hide new chats from non-contacts.";
"lng_premium_summary_subtitle_profile_badge" = "Profile Badge";
@@ -1742,11 +1806,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_premium_double_limits_about_accounts#other" = "Connect {count} accounts with different mobile numbers";
//
"lng_premium_gift_title" = "Gift Telegram Premium";
"lng_premium_gift_about" = "Let **{user}** enjoy exclusive features of Telegram with **Telegram Premium**.";
"lng_premium_gift_button" = "Gift Subscription for {cost}";
"lng_premium_gift_per" = "{cost} / month";
"lng_premium_gift_terms" = "You can review the list of features and terms of use for Telegram Premium {link}.";
"lng_premium_gift_terms_link" = "here";
"lng_accounts_limit_title" = "Limit Reached";
"lng_accounts_limit1#one" = "You have reached the limit of **{count}** connected accounts.";
"lng_accounts_limit1#other" = "You have reached the limit of **{count}** connected accounts.";
"lng_accounts_limit2" = "You can free one space by subscribing to **Telegram Premium** with one of these connected accounts:";
"lng_emoji_status_for_title" = "Set Status for...";
"lng_emoji_status_for_submit" = "Set Status";
"lng_emoji_status_menu_duration_any" = "Set Status for {duration}";
"lng_group_about_header" = "You have created a group.";
"lng_group_about_text" = "Groups can have:";
"lng_group_about1" = "Up to 100,000 members";
@@ -1759,6 +1834,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_switch_gifs" = "GIFs";
"lng_switch_masks" = "Masks";
"lng_stickers_featured_add" = "Add";
"lng_emoji_featured_unlock" = "Unlock";
"lng_emoji_premium_restore" = "Restore";
"lng_gifs_search" = "Search GIFs";
"lng_gifs_no_saved" = "You have no saved GIFs yet.";
@@ -1774,11 +1851,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stickers_remove_pack" = "Remove «{sticker_pack}»?";
"lng_stickers_add_pack" = "Add stickers";
"lng_stickers_add_masks" = "Add masks";
"lng_stickers_add_emoji" = "Add emoji";
"lng_stickers_share_pack" = "Share Stickers";
"lng_stickers_share_masks" = "Share Masks";
"lng_stickers_share_emoji" = "Share Emoji";
"lng_stickers_not_found" = "Sticker pack not found.";
"lng_stickers_packs_archived" = "Some of your unused stickers have been archived to make room for the sets you've activated.";
"lng_stickers_copied" = "Sticker pack link copied to clipboard.";
"lng_stickers_copied_emoji" = "Emoji pack link copied to clipboard.";
"lng_stickers_default_set" = "Great Minds";
"lng_stickers_you_have" = "Manage sticker packs";
"lng_stickers_return" = "Undo";
@@ -1786,7 +1866,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stickers_count#other" = "{count} stickers";
"lng_masks_count#one" = "{count} mask";
"lng_masks_count#other" = "{count} masks";
"lng_custom_emoji_count#one" = "{count} emoji";
"lng_custom_emoji_count#other" = "{count} emoji";
"lng_stickers_attached_sets" = "Sets of attached stickers";
"lng_custom_emoji_used_sets" = "Sets of used emoji";
"lng_custom_emoji_remove_pack_button" = "Remove Emoji";
"lng_stickers_group_set" = "Group sticker set";
"lng_stickers_remove_group_set" = "Remove group sticker set?";
"lng_stickers_group_from_your" = "Choose from your stickers";
@@ -1795,8 +1879,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stickers_nothing_found" = "No stickers found";
"lng_stickers_remove_pack_confirm" = "Remove";
"lng_stickers_archive_pack" = "Archive Stickers";
"lng_stickers_remove_pack_button" = "Remove Stickers";
"lng_stickers_has_been_archived" = "Sticker pack has been archived.";
"lng_masks_archive_pack" = "Archive Masks";
"lng_masks_remove_pack_button" = "Remove Masks";
"lng_masks_has_been_archived" = "Mask pack has been archived.";
"lng_masks_installed" = "Mask pack has been installed.";
@@ -1831,6 +1917,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_new_contact_unarchive" = "Unarchive";
"lng_new_contact_from_request_channel" = "{user} is an admin of {name}, a channel you requested to join.";
"lng_new_contact_from_request_group" = "{user} is an admin of {name}, a group you requested to join.";
"lng_new_contact_about_status" = "This account uses {emoji} as a custom status next to its\nname. Such emoji statuses are available to all\nsubscribers of {link}.";
"lng_new_contact_about_status_link" = "Telegram Premium";
"lng_from_request_title_channel" = "Chat with channel's admin";
"lng_from_request_title_group" = "Chat with group's admin";
"lng_from_request_body" = "You received this message because you requested to join {name} on {date}.";
@@ -1860,6 +1948,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_send_anonymous_ph" = "Send anonymously...";
"lng_send_as_title" = "Send message as...";
"lng_send_as_anonymous_admin" = "Anonymous admin";
"lng_send_as_premium_required" = "Subscribe to {link} to be able to comment on behalf of your channels in group chats.";
"lng_send_as_premium_required_link" = "Telegram Premium";
"lng_record_cancel" = "Release outside this field to cancel";
"lng_record_lock_cancel_sure" = "Are you sure you want to stop recording and discard your voice message?";
"lng_record_listen_cancel_sure" = "Are you sure you want to discard your recorded voice message?";
@@ -1970,6 +2060,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_bot_menu_not_supported" = "This bot isn't supported in the attach menu.";
"lng_bot_menu_already_added" = "This bot is already added in your attach menu.";
"lng_bot_menu_button" = "Menu";
"lng_bot_close_warning_title" = "Warning";
"lng_bot_close_warning" = "Changes that you made may not be saved.";
"lng_bot_close_warning_sure" = "Close anyway";
"lng_typing" = "typing";
"lng_user_typing" = "{user} is typing";
@@ -2109,6 +2202,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_delete_all_files" = "Delete all files";
"lng_context_save_custom_sound" = "Save for notifications";
"lng_context_animated_emoji" = "This message contains emoji from **{name} pack**.";
"lng_context_animated_emoji_many#one" = "This message contains emoji from **{count} pack**.";
"lng_context_animated_emoji_many#other" = "This message contains emoji from **{count} packs**.";
"lng_context_animated_reaction" = "This reaction is from **{name} pack**.";
"lng_context_animated_reactions" = "Reactions contain emoji from **{name} pack**.";
"lng_context_animated_reactions_many#one" = "Reactions contain emoji from **{count} pack**.";
"lng_context_animated_reactions_many#other" = "Reactions contain emoji from **{count} packs**.";
"lng_downloads_section" = "Downloads";
"lng_downloads_view_in_chat" = "View in chat";
"lng_downloads_view_in_section" = "View in downloads";
@@ -2345,7 +2446,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_theme_editor_menu_show" = "Show palette file";
"lng_payments_not_supported" = "Sorry, Telegram Desktop doesn't support payments yet. Please use one of our mobile apps to do this.";
"lng_payments_webview_no_card" = "Unfortunately, you can't add a new card with current system configuration.";
"lng_payments_webview_no_use" = "Unfortunately, you can't use payments with current system configuration.";
"lng_payments_webview_install_edge" = "Please install {link}.";
"lng_payments_webview_install_webkit" = "Please install WebKitGTK (webkit2gtk-5.0/webkit2gtk-4.1/webkit2gtk-4.0) using your package manager.";
@@ -2724,6 +2824,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_slowmode_enabled"= "Slow mode is enabled. You can send your next message in {left}.";
"lng_slowmode_no_many" = "Slow mode is enabled. You can't send more than one message at a time.";
"lng_slowmode_too_long" = "Sorry, this text is too long to send as one message.\n\nSlow mode is enabled. You can't send more than one message at a time.";
"lng_slowmode_seconds#one" = "{count} second";
"lng_slowmode_seconds#other" = "{count} seconds";
"lng_rights_gigagroup_title" = "Broadcast group";
"lng_rights_gigagroup_convert" = "Convert to Broadcast Group";
@@ -2812,6 +2914,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_restricted_send_public_polls" = "Sorry, public polls can't be forwarded to channels.";
"lng_restricted_send_voice_messages" = "{user} restricted sending of voice messages to them.";
"lng_restricted_send_video_messages" = "{user} restricted sending of video messages to them.";
"lng_exceptions_list_title" = "Exceptions";
"lng_removed_list_title" = "Removed users";
@@ -2929,6 +3034,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_admin_log_messages_ttl_removed" = "{from} disabled messages auto-deletion after {duration}";
"lng_admin_log_reactions_disabled" = "{from} disabled reactions";
"lng_admin_log_reactions_updated" = "{from} updated the list of allowed reactions to: {emoji}";
"lng_admin_log_reactions_allowed_all" = "{from} allowed all reactions";
"lng_admin_log_reactions_allowed_official" = "{from} allowed all official reactions";
"lng_admin_log_edited_invite_link" = "edited invite link {link}";
"lng_admin_log_invite_link_expire_date" = "Expire date: {previous} -> {limit}";
"lng_admin_log_invite_link_usage_limit" = "Usage limit: {previous} -> {limit}";

View File

@@ -68,7 +68,7 @@ inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string pro
inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
inputMediaInvoice#d9799874 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string = InputMedia;
inputMediaInvoice#8eb5a6d5 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia;
inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia;
inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> solution:flags.1?string solution_entities:flags.1?Vector<MessageEntity> = InputMedia;
inputMediaDice#e66fbf7b emoticon:string = InputMedia;
@@ -110,7 +110,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType;
storage.fileWebp#1081464c = storage.FileType;
userEmpty#d3bc4b7a id:long = User;
user#3ff6ecb0 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
user#5d99adee flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#82d1f706 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto;
@@ -128,8 +128,8 @@ chatForbidden#6592a1a7 id:long title:string = Chat;
channel#8261ac61 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
chatFull#d18ee226 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?Vector<string> = ChatFull;
channelFull#ea68a619 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?Vector<string> = ChatFull;
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions = ChatFull;
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
@@ -154,7 +154,7 @@ messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true document:flags.0?Do
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
messageMediaGame#fdb19008 game:Game = MessageMedia;
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
messageMediaInvoice#f6a548d3 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string extended_media:flags.4?MessageExtendedMedia = MessageMedia;
messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia;
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
@@ -191,6 +191,7 @@ messageActionSetChatTheme#aa786345 emoticon:string = MessageAction;
messageActionChatJoinedByRequest#ebbca3cb = MessageAction;
messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction;
messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction;
messageActionGiftPremium#aba0f5c6 currency:string amount:long months:int = MessageAction;
dialog#a8edd0f5 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
@@ -240,7 +241,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason;
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
userFull#8c72ea81 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true id:long about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights = UserFull;
userFull#c4b1fc3f flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true id:long about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> = UserFull;
contact#145ade0b user_id:long mutual:Bool = Contact;
@@ -322,8 +323,8 @@ updateDeleteChannelMessages#c32d5b12 channel_id:long messages:Vector<int> pts:in
updateChannelMessageViews#f226ac08 channel_id:long id:int views:int = Update;
updateChatParticipantAdmin#d7ca61a2 chat_id:long user_id:long is_admin:Bool version:int = Update;
updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update;
updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true order:Vector<long> = Update;
updateStickerSets#43ae3dec = Update;
updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true emojis:flags.1?true order:Vector<long> = Update;
updateStickerSets#31c24808 flags:# masks:flags.0?true emojis:flags.1?true = Update;
updateSavedGifs#9375341e = Update;
updateBotInlineQuery#496f379c flags:# query_id:long user_id:long query:string geo:flags.0?GeoPoint peer_type:flags.1?InlineQueryPeerType offset:string = Update;
updateBotInlineSend#12f12a07 flags:# user_id:long query:string geo:flags.0?GeoPoint id:string msg_id:flags.1?InputBotInlineMessageID = Update;
@@ -391,6 +392,12 @@ updateWebViewResultSent#1592b79d query_id:long = Update;
updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
updateSavedRingtones#74d8be99 = Update;
updateTranscribedAudio#84cd5a flags:# pending:flags.0?true peer:Peer msg_id:int transcription_id:long text:string = Update;
updateReadFeaturedEmojiStickers#fb4c496c = Update;
updateUserEmojiStatus#28373599 user_id:long emoji_status:EmojiStatus = Update;
updateRecentEmojiStatuses#30f443db = Update;
updateRecentReactions#6f7863f4 = Update;
updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update;
updateMessageExtendedMedia#5a73a98c peer:Peer msg_id:int extended_media:MessageExtendedMedia = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@@ -417,7 +424,7 @@ upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true this_port_only:flags.5?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
config#330b4067 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true force_try_ipv6:flags.14?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int pinned_infolder_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config;
config#232566ac flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true force_try_ipv6:flags.14?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int pinned_infolder_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int reactions_default:flags.15?Reaction = Config;
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
@@ -493,6 +500,7 @@ inputPrivacyKeyForwards#a4dd4c08 = InputPrivacyKey;
inputPrivacyKeyProfilePhoto#5719bacc = InputPrivacyKey;
inputPrivacyKeyPhoneNumber#352dafa = InputPrivacyKey;
inputPrivacyKeyAddedByPhone#d1219bdd = InputPrivacyKey;
inputPrivacyKeyVoiceMessages#aee69d68 = InputPrivacyKey;
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
privacyKeyChatInvite#500e6dfa = PrivacyKey;
@@ -502,6 +510,7 @@ privacyKeyForwards#69ec56a3 = PrivacyKey;
privacyKeyProfilePhoto#96151fed = PrivacyKey;
privacyKeyPhoneNumber#d19ae46d = PrivacyKey;
privacyKeyAddedByPhone#42ffd42b = PrivacyKey;
privacyKeyVoiceMessages#697f414 = PrivacyKey;
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
@@ -532,6 +541,7 @@ documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true supports_strea
documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute;
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
documentAttributeHasStickers#9801d2f7 = DocumentAttribute;
documentAttributeCustomEmoji#fd149899 flags:# free:flags.0?true alt:string stickerset:InputStickerSet = DocumentAttribute;
messages.stickersNotModified#f1749a22 = messages.Stickers;
messages.stickers#30a6ec7e hash:long stickers:Vector<Document> = messages.Stickers;
@@ -552,7 +562,7 @@ authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true pa
account.authorizations#4bff8ea0 authorization_ttl_days:int authorizations:Vector<Authorization> = account.Authorizations;
account.password#185b184f flags:# has_recovery:flags.0?true has_secure_values:flags.1?true has_password:flags.2?true current_algo:flags.2?PasswordKdfAlgo srp_B:flags.2?bytes srp_id:flags.2?long hint:flags.3?string email_unconfirmed_pattern:flags.4?string new_algo:PasswordKdfAlgo new_secure_algo:SecurePasswordKdfAlgo secure_random:bytes pending_reset_date:flags.5?int = account.Password;
account.password#957b50fb flags:# has_recovery:flags.0?true has_secure_values:flags.1?true has_password:flags.2?true current_algo:flags.2?PasswordKdfAlgo srp_B:flags.2?bytes srp_id:flags.2?long hint:flags.3?string email_unconfirmed_pattern:flags.4?string new_algo:PasswordKdfAlgo new_secure_algo:SecurePasswordKdfAlgo secure_random:bytes pending_reset_date:flags.5?int login_email_pattern:flags.6?string = account.Password;
account.passwordSettings#9a5c33e5 flags:# email:flags.0?string secure_settings:flags.1?SecureSecretSettings = account.PasswordSettings;
@@ -575,8 +585,11 @@ inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
inputStickerSetAnimatedEmoji#28703c8 = InputStickerSet;
inputStickerSetDice#e67f520e emoticon:string = InputStickerSet;
inputStickerSetAnimatedEmojiAnimations#cde3739 = InputStickerSet;
inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet;
inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet;
inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet;
stickerSet#d7df217a flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int count:int hash:int = StickerSet;
stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet;
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
@@ -628,6 +641,7 @@ messageEntityStrike#bf0693d4 offset:int length:int = MessageEntity;
messageEntityBlockquote#20df5d0 offset:int length:int = MessageEntity;
messageEntityBankCard#761e6af4 offset:int length:int = MessageEntity;
messageEntitySpoiler#32ca960f offset:int length:int = MessageEntity;
messageEntityCustomEmoji#c8cf05f8 offset:int length:int document_id:long = MessageEntity;
inputChannelEmpty#ee8c1e86 = InputChannel;
inputChannel#f35aec28 channel_id:long access_hash:long = InputChannel;
@@ -709,6 +723,8 @@ auth.sentCodeTypeSms#c000bba2 length:int = auth.SentCodeType;
auth.sentCodeTypeCall#5353e5a7 length:int = auth.SentCodeType;
auth.sentCodeTypeFlashCall#ab03c6d9 pattern:string = auth.SentCodeType;
auth.sentCodeTypeMissedCall#82006484 prefix:string length:int = auth.SentCodeType;
auth.sentCodeTypeEmailCode#5a159841 flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true email_pattern:string length:int next_phone_login_date:flags.2?int = auth.SentCodeType;
auth.sentCodeTypeSetUpEmailRequired#a5491dea flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true = auth.SentCodeType;
messages.botCallbackAnswer#36585ea4 flags:# alert:flags.1?true has_url:flags.3?true native_ui:flags.4?true message:flags.0?string url:flags.2?string cache_time:int = messages.BotCallbackAnswer;
@@ -742,7 +758,7 @@ draftMessageEmpty#1b0c841a flags:# date:flags.0?int = DraftMessage;
draftMessage#fd8e711f flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int message:string entities:flags.3?Vector<MessageEntity> date:int = DraftMessage;
messages.featuredStickersNotModified#c6dc0c66 count:int = messages.FeaturedStickers;
messages.featuredStickers#84c02310 hash:long count:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
messages.featuredStickers#be382906 flags:# premium:flags.0?true hash:long count:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
messages.recentStickersNotModified#b17f890 = messages.RecentStickers;
messages.recentStickers#88d37c56 hash:long packs:Vector<StickerPack> stickers:Vector<Document> dates:Vector<int> = messages.RecentStickers;
@@ -754,6 +770,7 @@ messages.stickerSetInstallResultArchive#35e410a8 sets:Vector<StickerSetCovered>
stickerSetCovered#6410a5d2 set:StickerSet cover:Document = StickerSetCovered;
stickerSetMultiCovered#3407e51b set:StickerSet covers:Vector<Document> = StickerSetCovered;
stickerSetFullCovered#1aed5ee5 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = StickerSetCovered;
maskCoords#aed6dbb2 n:int x:double y:double zoom:double = MaskCoords;
@@ -842,10 +859,11 @@ inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector
inputWebFileLocation#c239d686 url:string access_hash:long = InputWebFileLocation;
inputWebFileGeoPointLocation#9f2221c9 geo_point:InputGeoPoint access_hash:long w:int h:int zoom:int scale:int = InputWebFileLocation;
inputWebFileAudioAlbumThumbLocation#f46fe924 flags:# small:flags.2?true document:flags.0?InputDocument title:flags.1?string performer:flags.1?string = InputWebFileLocation;
upload.webFile#21e753bc size:int mime_type:string file_type:storage.FileType mtime:int bytes:bytes = upload.WebFile;
payments.paymentForm#b0133b37 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?PaymentSavedCredentials users:Vector<User> = payments.PaymentForm;
payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector<PaymentFormMethod> saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector<PaymentSavedCredentials> users:Vector<User> = payments.PaymentForm;
payments.validatedRequestedInfo#d1451883 flags:# id:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = payments.ValidatedRequestedInfo;
@@ -933,7 +951,7 @@ channelAdminLogEventActionChangeHistoryTTL#6e941a38 prev_value:int new_value:int
channelAdminLogEventActionParticipantJoinByRequest#afb6144a invite:ExportedChatInvite approved_by:long = ChannelAdminLogEventAction;
channelAdminLogEventActionToggleNoForwards#cb2ac766 new_value:Bool = ChannelAdminLogEventAction;
channelAdminLogEventActionSendMessage#278f2868 message:Message = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeAvailableReactions#9cf7f76a prev_value:Vector<string> new_value:Vector<string> = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeAvailableReactions#be4e0ef8 prev_value:ChatReactions new_value:ChatReactions = ChannelAdminLogEventAction;
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
@@ -1310,7 +1328,7 @@ searchResultPosition#7f648b67 msg_id:int date:int offset:int = SearchResultsPosi
messages.searchResultsPositions#53b22baf count:int positions:Vector<SearchResultsPosition> = messages.SearchResultsPositions;
channels.sendAsPeers#8356cda9 peers:Vector<Peer> chats:Vector<Chat> users:Vector<User> = channels.SendAsPeers;
channels.sendAsPeers#f496b0c6 peers:Vector<SendAsPeer> chats:Vector<Chat> users:Vector<User> = channels.SendAsPeers;
users.userFull#3b6d152e full_user:UserFull chats:Vector<Chat> users:Vector<User> = users.UserFull;
@@ -1318,7 +1336,7 @@ messages.peerSettings#6880b94d settings:PeerSettings chats:Vector<Chat> users:Ve
auth.loggedOut#c3a2835f flags:# future_auth_token:flags.0?bytes = auth.LoggedOut;
reactionCount#6fb250d1 flags:# chosen:flags.0?true reaction:string count:int = ReactionCount;
reactionCount#a3d1cb80 flags:# chosen_order:flags.0?int reaction:Reaction count:int = ReactionCount;
messageReactions#4f2b9479 flags:# min:flags.0?true can_see_list:flags.2?true results:Vector<ReactionCount> recent_reactions:flags.1?Vector<MessagePeerReaction> = MessageReactions;
@@ -1332,7 +1350,7 @@ messages.availableReactions#768e3aad hash:int reactions:Vector<AvailableReaction
messages.translateNoResult#67ca4737 = messages.TranslatedText;
messages.translateResultText#a214f7d0 text:string = messages.TranslatedText;
messagePeerReaction#51b67eff flags:# big:flags.0?true unread:flags.1?true peer_id:Peer reaction:string = MessagePeerReaction;
messagePeerReaction#b156fe9c flags:# big:flags.0?true unread:flags.1?true peer_id:Peer reaction:Reaction = MessagePeerReaction;
groupCallStreamChannel#80eb48af channel:int scale:int last_timestamp_ms:long = GroupCallStreamChannel;
@@ -1385,7 +1403,50 @@ payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
messages.transcribedAudio#93752c52 flags:# pending:flags.0?true transcription_id:long text:string = messages.TranscribedAudio;
help.premiumPromo#8a4f3c29 status_text:string status_entities:Vector<MessageEntity> video_sections:Vector<string> videos:Vector<Document> currency:string monthly_amount:long users:Vector<User> = help.PremiumPromo;
help.premiumPromo#5334759c status_text:string status_entities:Vector<MessageEntity> video_sections:Vector<string> videos:Vector<Document> period_options:Vector<PremiumSubscriptionOption> users:Vector<User> = help.PremiumPromo;
inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true = InputStorePaymentPurpose;
inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose;
premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption;
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
emojiStatusEmpty#2de11aae = EmojiStatus;
emojiStatus#929b619d document_id:long = EmojiStatus;
emojiStatusUntil#fa30a8c7 document_id:long until:int = EmojiStatus;
account.emojiStatusesNotModified#d08ce645 = account.EmojiStatuses;
account.emojiStatuses#90c467d1 hash:long statuses:Vector<EmojiStatus> = account.EmojiStatuses;
reactionEmpty#79f5d419 = Reaction;
reactionEmoji#1b2286b8 emoticon:string = Reaction;
reactionCustomEmoji#8935fc73 document_id:long = Reaction;
chatReactionsNone#eafc32bc = ChatReactions;
chatReactionsAll#52928bca flags:# allow_custom:flags.0?true = ChatReactions;
chatReactionsSome#661d4037 reactions:Vector<Reaction> = ChatReactions;
messages.reactionsNotModified#b06fdbdf = messages.Reactions;
messages.reactions#eafdf716 hash:long reactions:Vector<Reaction> = messages.Reactions;
emailVerifyPurposeLoginSetup#4345be73 phone_number:string phone_code_hash:string = EmailVerifyPurpose;
emailVerifyPurposeLoginChange#527d22eb = EmailVerifyPurpose;
emailVerifyPurposePassport#bbf51685 = EmailVerifyPurpose;
emailVerificationCode#922e55a9 code:string = EmailVerification;
emailVerificationGoogle#db909ec2 token:string = EmailVerification;
emailVerificationApple#96d074fd token:string = EmailVerification;
account.emailVerified#2b96cd1b email:string = account.EmailVerified;
account.emailVerifiedLogin#e1bb0d61 email:string sent_code:auth.SentCode = account.EmailVerified;
premiumSubscriptionOption#b6f11ebe flags:# current:flags.1?true can_purchase_upgrade:flags.2?true months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumSubscriptionOption;
sendAsPeer#b81c7034 flags:# premium_required:flags.0?true peer:Peer = SendAsPeer;
messageExtendedMediaPreview#ad628cc8 flags:# w:flags.0?int h:flags.0?int thumb:flags.1?PhotoSize video_duration:flags.2?int = MessageExtendedMedia;
messageExtendedMedia#ee479c64 media:MessageMedia = MessageExtendedMedia;
---functions---
@@ -1399,7 +1460,7 @@ invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
auth.signUp#80eee427 phone_number:string phone_code_hash:string first_name:string last_name:string = auth.Authorization;
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
auth.signIn#8d52a951 flags:# phone_number:string phone_code_hash:string phone_code:flags.0?string email_verification:flags.1?EmailVerification = auth.Authorization;
auth.logOut#3e72ba19 = auth.LoggedOut;
auth.resetAuthorizations#9fab0d1a = Bool;
auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
@@ -1430,7 +1491,7 @@ account.checkUsername#2714d86c username:string = Bool;
account.updateUsername#3e0bdd7c username:string = User;
account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules;
account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> = account.PrivacyRules;
account.deleteAccount#418d4e0b reason:string = Bool;
account.deleteAccount#a2c0cf74 flags:# reason:string password:flags.0?InputCheckPasswordSRP = Bool;
account.getAccountTTL#8fc711d = AccountDaysTTL;
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
account.sendChangePhoneCode#82574ae5 phone_number:string settings:CodeSettings = auth.SentCode;
@@ -1455,8 +1516,8 @@ account.getAuthorizationForm#a929597a bot_id:long scope:string public_key:string
account.acceptAuthorization#f3ed4c73 bot_id:long scope:string public_key:string value_hashes:Vector<SecureValueHash> credentials:SecureCredentialsEncrypted = Bool;
account.sendVerifyPhoneCode#a5a356f9 phone_number:string settings:CodeSettings = auth.SentCode;
account.verifyPhone#4dd3a7f6 phone_number:string phone_code_hash:string phone_code:string = Bool;
account.sendVerifyEmailCode#7011509f email:string = account.SentEmailCode;
account.verifyEmail#ecba39db email:string code:string = Bool;
account.sendVerifyEmailCode#98e037bb purpose:EmailVerifyPurpose email:string = account.SentEmailCode;
account.verifyEmail#32da4cf purpose:EmailVerifyPurpose verification:EmailVerification = account.EmailVerified;
account.initTakeoutSession#8ef3eab0 flags:# contacts:flags.0?true message_users:flags.1?true message_chats:flags.2?true message_megagroups:flags.3?true message_channels:flags.4?true files:flags.5?true file_max_size:flags.5?long = account.Takeout;
account.finishTakeoutSession#1d2652ee flags:# success:flags.0?true = Bool;
account.confirmPasswordEmail#8fdf1920 code:string = Bool;
@@ -1493,6 +1554,10 @@ account.changeAuthorizationSettings#40f48462 flags:# hash:long encrypted_request
account.getSavedRingtones#e1902288 hash:long = account.SavedRingtones;
account.saveRingtone#3dea5b03 id:InputDocument unsave:Bool = account.SavedRingtone;
account.uploadRingtone#831a83a2 file:InputFile file_name:string mime_type:string = Document;
account.updateEmojiStatus#fbd3de6b emoji_status:EmojiStatus = Bool;
account.getDefaultEmojiStatuses#d6753386 hash:long = account.EmojiStatuses;
account.getRecentEmojiStatuses#f578105 hash:long = account.EmojiStatuses;
account.clearRecentEmojiStatuses#18201aae = Bool;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
@@ -1529,8 +1594,8 @@ messages.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?t
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
messages.sendMessage#d9d75a4 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
messages.sendMessage#d9d75a4 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
messages.forwardMessages#cc30290b flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
messages.reportSpam#cf1592db peer:InputPeer = Bool;
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
@@ -1568,7 +1633,7 @@ messages.getMessagesViews#5784d3e1 peer:InputPeer id:Vector<int> increment:Bool
messages.editChatAdmin#a85bd1c2 chat_id:long user_id:InputUser is_admin:Bool = Bool;
messages.migrateChat#a2875319 chat_id:long = Updates;
messages.searchGlobal#4bc6589a flags:# folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
messages.reorderStickerSets#78337739 flags:# masks:flags.0?true order:Vector<long> = Bool;
messages.reorderStickerSets#78337739 flags:# masks:flags.0?true emojis:flags.1?true order:Vector<long> = Bool;
messages.getDocumentByHash#b1f2061f sha256:bytes size:long mime_type:string = Document;
messages.getSavedGifs#5cf09635 hash:long = messages.SavedGifs;
messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
@@ -1588,7 +1653,7 @@ messages.readFeaturedStickers#5b118126 id:Vector<long> = Bool;
messages.getRecentStickers#9da9403b flags:# attached:flags.0?true hash:long = messages.RecentStickers;
messages.saveRecentSticker#392718f8 flags:# attached:flags.0?true id:InputDocument unsave:Bool = Bool;
messages.clearRecentStickers#8999602d flags:# attached:flags.0?true = Bool;
messages.getArchivedStickers#57f17692 flags:# masks:flags.0?true offset_id:long limit:int = messages.ArchivedStickers;
messages.getArchivedStickers#57f17692 flags:# masks:flags.0?true emojis:flags.1?true offset_id:long limit:int = messages.ArchivedStickers;
messages.getMaskStickers#640f82b8 hash:long = messages.AllStickers;
messages.getAttachedStickers#cc5b67cc media:InputStickeredMedia = Vector<StickerSetCovered>;
messages.setGameScore#8ef8ecc0 flags:# edit_message:flags.0?true force:flags.1?true peer:InputPeer id:int user_id:InputUser score:int = Updates;
@@ -1610,7 +1675,7 @@ messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
messages.getUnreadMentions#46578472 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
messages.readMentions#f0189d3 peer:InputPeer = messages.AffectedHistory;
messages.getRecentLocations#702a40e0 peer:InputPeer limit:int hash:long = messages.Messages;
messages.sendMultiMedia#f803138f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
messages.sendMultiMedia#f803138f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
@@ -1669,12 +1734,12 @@ messages.hideChatJoinRequest#7fe7e815 flags:# approved:flags.0?true peer:InputPe
messages.hideAllChatJoinRequests#e085f4ea flags:# approved:flags.0?true peer:InputPeer link:flags.1?string = Updates;
messages.toggleNoForwards#b11eafa2 peer:InputPeer enabled:Bool = Updates;
messages.saveDefaultSendAs#ccfddf96 peer:InputPeer send_as:InputPeer = Bool;
messages.sendReaction#25690ce4 flags:# big:flags.1?true peer:InputPeer msg_id:int reaction:flags.0?string = Updates;
messages.sendReaction#d30d78d4 flags:# big:flags.1?true add_to_recent:flags.2?true peer:InputPeer msg_id:int reaction:flags.0?Vector<Reaction> = Updates;
messages.getMessagesReactions#8bba90e6 peer:InputPeer id:Vector<int> = Updates;
messages.getMessageReactionsList#e0ee6b77 flags:# peer:InputPeer id:int reaction:flags.0?string offset:flags.1?string limit:int = messages.MessageReactionsList;
messages.setChatAvailableReactions#14050ea6 peer:InputPeer available_reactions:Vector<string> = Updates;
messages.getMessageReactionsList#461b3f48 flags:# peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = messages.MessageReactionsList;
messages.setChatAvailableReactions#feb16771 peer:InputPeer available_reactions:ChatReactions = Updates;
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
messages.setDefaultReaction#d960c4d4 reaction:string = Bool;
messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool;
messages.translateText#24ce6dee flags:# peer:flags.0?InputPeer msg_id:flags.0?int text:flags.1?string from_lang:flags.2?string to_lang:string = messages.TranslatedText;
messages.getUnreadReactions#e85bae1a peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
messages.readReactions#82e251d7 peer:InputPeer = messages.AffectedHistory;
@@ -1682,13 +1747,21 @@ messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = mes
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
messages.requestWebView#91b15831 flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = WebViewResult;
messages.requestWebView#fc87a53c flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = WebViewResult;
messages.prolongWebView#ea5fbcce flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = Bool;
messages.requestSimpleWebView#6abb2f73 flags:# bot:InputUser url:string theme_params:flags.0?DataJSON = SimpleWebViewResult;
messages.requestSimpleWebView#299bec8e flags:# bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult;
messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent;
messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates;
messages.transcribeAudio#269e9a49 peer:InputPeer msg_id:int = messages.TranscribedAudio;
messages.rateTranscribedAudio#7f1d072f peer:InputPeer msg_id:int transcription_id:long good:Bool = Bool;
messages.getCustomEmojiDocuments#d9ab0f54 document_id:Vector<long> = Vector<Document>;
messages.getEmojiStickers#fbfca18f hash:long = messages.AllStickers;
messages.getFeaturedEmojiStickers#ecf6736 hash:long = messages.FeaturedStickers;
messages.reportReaction#3f64c076 peer:InputPeer id:int reaction_peer:InputPeer = Bool;
messages.getTopReactions#bb8125ba limit:int hash:long = messages.Reactions;
messages.getRecentReactions#39461db2 limit:int hash:long = messages.Reactions;
messages.clearRecentReactions#9dfeefb4 = Bool;
messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = Updates;
updates.getState#edd4882a = updates.State;
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
@@ -1792,11 +1865,9 @@ payments.getSavedInfo#227d824b = payments.SavedInfo;
payments.clearSavedInfo#d83d70c1 flags:# credentials:flags.0?true info:flags.1?true = Bool;
payments.getBankCardData#2e79d779 number:string = payments.BankCardData;
payments.exportInvoice#f91b065 invoice_media:InputMedia = payments.ExportedInvoice;
payments.assignAppStoreTransaction#fec13c6 flags:# restore:flags.0?true transaction_id:string receipt:bytes = Updates;
payments.assignPlayMarketTransaction#4faa4aed purchase_token:string = Updates;
payments.restorePlayMarketReceipt#d164e36a receipt:bytes = Updates;
payments.canPurchasePremium#aa6a90c8 = Bool;
payments.requestRecurringPayment#146e958d user_id:InputUser recurring_init_charge:string invoice_media:InputMedia = Updates;
payments.assignAppStoreTransaction#80ed747d receipt:bytes purpose:InputStorePaymentPurpose = Updates;
payments.assignPlayMarketTransaction#dffd50d3 receipt:DataJSON purpose:InputStorePaymentPurpose = Updates;
payments.canPurchasePremium#9fc19eb6 purpose:InputStorePaymentPurpose = Bool;
stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true animated:flags.1?true videos:flags.4?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
@@ -1853,4 +1924,4 @@ stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
// LAYER 143
// LAYER 146

View File

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

View File

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

View File

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

View File

@@ -41,23 +41,28 @@ void AttachedStickers::request(
return;
} else if (result.v.size() > 1) {
strongController->show(
Box<StickersBox>(strongController, result));
Box<StickersBox>(strongController, result.v));
return;
}
// Single attached sticker pack.
const auto setData = result.v.front().match([&](const auto &data) {
return data.vset().match([&](const MTPDstickerSet &data) {
return &data;
});
const auto data = result.v.front().match([&](const auto &data) {
return &data.vset().data();
});
const auto setId = (setData->vid().v && setData->vaccess_hash().v)
const auto setId = (data->vid().v && data->vaccess_hash().v)
? StickerSetIdentifier{
.id = setData->vid().v,
.accessHash = setData->vaccess_hash().v }
: StickerSetIdentifier{ .shortName = qs(setData->vshort_name()) };
.id = data->vid().v,
.accessHash = data->vaccess_hash().v }
: StickerSetIdentifier{ .shortName = qs(data->vshort_name()) };
strongController->show(
Box<StickerSetBox>(strongController, setId),
Box<StickerSetBox>(
strongController,
setId,
(data->is_emojis()
? Data::StickersType::Emoji
: data->is_masks()
? Data::StickersType::Masks
: Data::StickersType::Stickers)),
Ui::LayerOption::KeepOther);
}).fail([=] {
_requestId = 0;

View File

@@ -98,8 +98,11 @@ void BlockedPeers::block(not_null<PeerData*> peer) {
}
}
void BlockedPeers::unblock(not_null<PeerData*> peer, Fn<void()> onDone) {
if (!peer->isBlocked()) {
void BlockedPeers::unblock(
not_null<PeerData*> peer,
Fn<void()> onDone,
bool force) {
if (!force && !peer->isBlocked()) {
_session->changes().peerUpdated(
peer,
Data::PeerUpdate::Flag::IsBlocked);

View File

@@ -42,7 +42,10 @@ public:
void request(int offset, Fn<void(Slice)> onDone);
void block(not_null<PeerData*> peer);
void unblock(not_null<PeerData*> peer, Fn<void()> onDone = nullptr);
void unblock(
not_null<PeerData*> peer,
Fn<void()> onDone = nullptr,
bool force = false);
private:
const not_null<Main::Session*> _session;

View File

@@ -9,21 +9,29 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "api/api_cloud_password.h"
#include "core/core_cloud_password.h"
#include "api/api_send_progress.h"
#include "ui/boxes/confirm_box.h"
#include "boxes/share_box.h"
#include "boxes/passcode_box.h"
#include "boxes/url_auth_box.h"
#include "lang/lang_keys.h"
#include "core/core_cloud_password.h"
#include "core/click_handler_types.h"
#include "data/data_changes.h"
#include "data/data_peer.h"
#include "data/data_poll.h"
#include "data/data_user.h"
#include "data/data_session.h"
#include "history/history.h"
#include "history/history_item.h"
#include "history/history_item_components.h"
#include "inline_bots/bot_attach_web_view.h"
#include "payments/payments_checkout_process.h"
#include "main/main_session.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "window/window_session_controller.h"
#include "window/window_peer_menu.h"
#include "ui/boxes/confirm_box.h"
#include "ui/toast/toast.h"
#include "ui/layers/generic_box.h"
#include "ui/text/text_utilities.h"
@@ -36,7 +44,7 @@ void SendBotCallbackData(
not_null<HistoryItem*> item,
int row,
int column,
std::optional<Core::CloudPasswordResult> password = std::nullopt,
std::optional<Core::CloudPasswordResult> password,
Fn<void(const QString &)> handleError = nullptr) {
if (!item->isRegular()) {
return;
@@ -92,10 +100,7 @@ void SendBotCallbackData(
button->requestId = 0;
owner->requestItemRepaint(item);
}
const auto &data = result.match([](
const auto &data) -> const MTPDmessages_botCallbackAnswer& {
return data;
});
const auto &data = result.data();
const auto message = data.vmessage()
? qs(*data.vmessage())
: QString();
@@ -154,6 +159,14 @@ void SendBotCallbackData(
);
}
void HideSingleUseKeyboard(
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item) {
controller->content()->hideSingleUseKeyboard(
item->history()->peer,
item->id);
}
} // namespace
void SendBotCallbackData(
@@ -252,4 +265,193 @@ void SendBotCallbackDataWithPassword(
});
}
bool SwitchInlineBotButtonReceived(
not_null<Window::SessionController*> controller,
const QString &query,
UserData *samePeerBot,
MsgId samePeerReplyTo) {
return controller->content()->notify_switchInlineBotButtonReceived(
query,
samePeerBot,
samePeerReplyTo);
}
void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
const auto controller = context.sessionWindow.get();
if (!controller) {
return;
}
const auto item = controller->session().data().message(context.itemId);
if (!item) {
return;
}
const auto button = HistoryMessageMarkupButton::Get(
&item->history()->owner(),
item->fullId(),
row,
column);
if (!button) {
return;
}
using ButtonType = HistoryMessageMarkupButton::Type;
switch (button->type) {
case ButtonType::Default: {
// Copy string before passing it to the sending method
// because the original button can be destroyed inside.
const auto replyTo = item->isRegular() ? item->id : 0;
controller->content()->sendBotCommand({
.peer = item->history()->peer,
.command = QString(button->text),
.context = item->fullId(),
.replyTo = replyTo,
});
} break;
case ButtonType::Callback:
case ButtonType::Game: {
SendBotCallbackData(controller, item, row, column);
} break;
case ButtonType::CallbackWithPassword: {
SendBotCallbackDataWithPassword(controller, item, row, column);
} break;
case ButtonType::Buy: {
Payments::CheckoutProcess::Start(
item,
Payments::Mode::Payment,
crl::guard(controller, [=](auto) {
controller->widget()->activate();
}));
} break;
case ButtonType::Url: {
auto url = QString::fromUtf8(button->data);
auto skipConfirmation = false;
if (const auto bot = item->getMessageBot()) {
if (bot->isVerified()) {
skipConfirmation = true;
}
}
const auto variant = QVariant::fromValue(context);
if (skipConfirmation) {
UrlClickHandler::Open(url, variant);
} else {
HiddenUrlClickHandler::Open(url, variant);
}
} break;
case ButtonType::RequestLocation: {
HideSingleUseKeyboard(controller, item);
controller->show(
Ui::MakeInformBox(tr::lng_bot_share_location_unavailable()));
} break;
case ButtonType::RequestPhone: {
HideSingleUseKeyboard(controller, item);
const auto itemId = item->id;
const auto history = item->history();
controller->show(Ui::MakeConfirmBox({
.text = tr::lng_bot_share_phone(),
.confirmed = [=] {
controller->showPeerHistory(
history,
Window::SectionShow::Way::Forward,
ShowAtTheEndMsgId);
auto action = Api::SendAction(history);
action.clearDraft = false;
action.replyTo = itemId;
history->session().api().shareContact(
history->session().user(),
action);
},
.confirmText = tr::lng_bot_share_phone_confirm(),
}));
} break;
case ButtonType::RequestPoll: {
HideSingleUseKeyboard(controller, item);
auto chosen = PollData::Flags();
auto disabled = PollData::Flags();
if (!button->data.isEmpty()) {
disabled |= PollData::Flag::Quiz;
if (button->data[0]) {
chosen |= PollData::Flag::Quiz;
}
}
const auto replyToId = MsgId(0);
Window::PeerMenuCreatePoll(
controller,
item->history()->peer,
replyToId,
chosen,
disabled);
} break;
case ButtonType::SwitchInlineSame:
case ButtonType::SwitchInline: {
if (const auto bot = item->getMessageBot()) {
const auto fastSwitchDone = [&] {
const auto samePeer = (button->type
== ButtonType::SwitchInlineSame);
if (samePeer) {
SwitchInlineBotButtonReceived(
controller,
QString::fromUtf8(button->data),
bot,
item->id);
return true;
} else if (bot->isBot() && bot->botInfo->inlineReturnTo.key) {
const auto switched = SwitchInlineBotButtonReceived(
controller,
QString::fromUtf8(button->data));
if (switched) {
return true;
}
}
return false;
}();
if (!fastSwitchDone) {
controller->content()->inlineSwitchLayer('@'
+ bot->username
+ ' '
+ QString::fromUtf8(button->data));
}
}
} break;
case ButtonType::Auth:
UrlAuthBox::Activate(item, row, column);
break;
case ButtonType::UserProfile: {
const auto session = &item->history()->session();
const auto userId = UserId(button->data.toULongLong());
if (const auto user = session->data().userLoaded(userId)) {
controller->showPeerInfo(user);
}
} break;
case ButtonType::WebView: {
if (const auto bot = item->getMessageBot()) {
bot->session().attachWebView().request(
controller,
bot,
bot,
{ .text = button->text, .url = button->data });
}
} break;
case ButtonType::SimpleWebView: {
if (const auto bot = item->getMessageBot()) {
bot->session().attachWebView().requestSimple(
controller,
bot,
{ .text = button->text, .url = button->data });
}
} break;
}
}
} // namespace Api

View File

@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
struct ClickHandlerContext;
class HistoryItem;
namespace Window {
@@ -27,4 +28,12 @@ void SendBotCallbackDataWithPassword(
int row,
int column);
bool SwitchInlineBotButtonReceived(
not_null<Window::SessionController*> controller,
const QString &query,
UserData *samePeerBot = nullptr,
MsgId samePeerReplyTo = 0);
void ActivateBotCommand(ClickHandlerContext context, int row, int column);
} // namespace Api

View File

@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#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"
@@ -175,17 +176,28 @@ ConfirmInviteBox::ConfirmInviteBox(
const MTPDchatInvite &data,
ChannelData *invitePeekChannel,
Fn<void()> submit)
: ConfirmInviteBox(
session,
Parse(session, data),
invitePeekChannel,
std::move(submit)) {
}
ConfirmInviteBox::ConfirmInviteBox(
not_null<Main::Session*> session,
ChatInvite &&invite,
ChannelData *invitePeekChannel,
Fn<void()> submit)
: _session(session)
, _submit(std::move(submit))
, _title(this, st::confirmInviteTitle)
, _status(this, st::confirmInviteStatus)
, _about(this, st::confirmInviteAbout)
, _aboutRequests(this, st::confirmInviteStatus)
, _participants(GetParticipants(_session, data))
, _isChannel(data.is_channel() && !data.is_megagroup())
, _requestApprove(data.is_request_needed()) {
const auto title = qs(data.vtitle());
const auto count = data.vparticipants_count().v;
, _participants(std::move(invite.participants))
, _isChannel(invite.isChannel && !invite.isMegagroup)
, _requestApprove(invite.isRequestNeeded) {
const auto count = invite.participantsCount;
const auto status = [&] {
return invitePeekChannel
? tr::lng_channel_invite_private(tr::now)
@@ -202,10 +214,10 @@ ConfirmInviteBox::ConfirmInviteBox(
? tr::lng_channel_status(tr::now)
: tr::lng_group_status(tr::now);
}();
_title->setText(title);
_title->setText(invite.title);
_status->setText(status);
if (const auto v = qs(data.vabout().value_or_empty()); !v.isEmpty()) {
_about->setText(v);
if (!invite.about.isEmpty()) {
_about->setText(invite.about);
} else {
_about.destroy();
}
@@ -217,9 +229,8 @@ ConfirmInviteBox::ConfirmInviteBox(
_aboutRequests.destroy();
}
const auto photo = _session->data().processPhoto(data.vphoto());
if (!photo->isNull()) {
_photo = photo->createMediaView();
if (invite.photo) {
_photo = invite.photo->createMediaView();
_photo->wanted(Data::PhotoSize::Small, Data::FileOrigin());
if (!_photo->image(Data::PhotoSize::Small)) {
_session->downloaderTaskFinished(
@@ -230,29 +241,37 @@ ConfirmInviteBox::ConfirmInviteBox(
} else {
_photoEmpty = std::make_unique<Ui::EmptyUserpic>(
Data::PeerUserpicColor(0),
title);
invite.title);
}
}
ConfirmInviteBox::~ConfirmInviteBox() = default;
auto ConfirmInviteBox::GetParticipants(
not_null<Main::Session*> session,
const MTPDchatInvite &data)
-> std::vector<Participant> {
const auto participants = data.vparticipants();
if (!participants) {
return {};
}
const auto &v = participants->v;
auto result = std::vector<Participant>();
result.reserve(v.size());
for (const auto &participant : v) {
if (const auto user = session->data().processUser(participant)) {
result.push_back(Participant{ user });
ConfirmInviteBox::ChatInvite ConfirmInviteBox::Parse(
not_null<Main::Session*> session,
const MTPDchatInvite &data) {
auto participants = std::vector<Participant>();
if (const auto list = data.vparticipants()) {
participants.reserve(list->v.size());
for (const auto &participant : list->v) {
if (const auto user = session->data().processUser(participant)) {
participants.push_back(Participant{ user });
}
}
}
return result;
const auto photo = session->data().processPhoto(data.vphoto());
return {
.title = qs(data.vtitle()),
.about = data.vabout().value_or_empty(),
.photo = (photo->isNull() ? nullptr : photo.get()),
.participantsCount = data.vparticipants_count().v,
.participants = std::move(participants),
.isPublic = data.is_public(),
.isChannel = data.is_channel(),
.isMegagroup = data.is_megagroup(),
.isBroadcast = data.is_broadcast(),
.isRequestNeeded = data.is_request_needed(),
};
}
void ConfirmInviteBox::prepare() {
@@ -280,7 +299,7 @@ void ConfirmInviteBox::prepare() {
auto name = new Ui::FlatLabel(this, st::confirmInviteUserName);
name->resizeToWidth(st::confirmInviteUserPhotoSize + padding);
name->setText(participant.user->firstName.isEmpty()
? participant.user->name
? participant.user->name()
: participant.user->firstName);
name->moveToLeft(left + (padding / 2), st::confirmInviteUserNameTop);
left += _userWidth;

View File

@@ -59,10 +59,28 @@ private:
not_null<UserData*> user;
std::shared_ptr<Data::CloudImageView> userpic;
};
static std::vector<Participant> GetParticipants(
struct ChatInvite {
QString title;
QString about;
PhotoData *photo = nullptr;
int participantsCount = 0;
std::vector<Participant> participants;
bool isPublic = false;
bool isChannel = false;
bool isMegagroup = false;
bool isBroadcast = false;
bool isRequestNeeded = false;
};
[[nodiscard]] static ChatInvite Parse(
not_null<Main::Session*> session,
const MTPDchatInvite &data);
ConfirmInviteBox(
not_null<Main::Session*> session,
ChatInvite &&invite,
ChannelData *invitePeekChannel,
Fn<void()> submit);
const not_null<Main::Session*> _session;
Fn<void()> _submit;

View File

@@ -462,13 +462,14 @@ void ChatParticipants::requestCountDelayed(
void ChatParticipants::add(
not_null<PeerData*> peer,
const std::vector<not_null<UserData*>> &users,
bool passGroupHistory,
Fn<void(bool)> done) {
if (const auto chat = peer->asChat()) {
for (const auto &user : users) {
_api.request(MTPmessages_AddChatUser(
chat->inputChat,
user->inputUser,
MTP_int(kForwardMessagesOnAdd)
MTP_int(passGroupHistory ? kForwardMessagesOnAdd : 0)
)).done([=](const MTPUpdates &result) {
chat->session().api().applyUpdates(result);
if (done) done(true);

View File

@@ -95,6 +95,7 @@ public:
void add(
not_null<PeerData*> peer,
const std::vector<not_null<UserData*>> &users,
bool passGroupHistory = true,
Fn<void(bool)> done = nullptr);
void requestSelf(not_null<ChannelData*> channel);

View File

@@ -35,6 +35,10 @@ void ConfirmPhone::resolve(
_sendRequestId = 0;
result.match([&](const MTPDauth_sentCode &data) {
const auto bad = [](const char *type) {
LOG(("API Error: Should not be '%1'.").arg(type));
return 0;
};
const auto sentCodeLength = data.vtype().match([&](
const MTPDauth_sentCodeTypeApp &data) {
LOG(("Error: should not be in-app code!"));
@@ -43,12 +47,14 @@ void ConfirmPhone::resolve(
return data.vlength().v;
}, [&](const MTPDauth_sentCodeTypeCall &data) {
return data.vlength().v;
}, [&](const MTPDauth_sentCodeTypeFlashCall &data) {
LOG(("Error: should not be flashcall!"));
return 0;
}, [&](const MTPDauth_sentCodeTypeMissedCall &data) {
LOG(("Error: should not be missedcall!"));
return 0;
}, [&](const MTPDauth_sentCodeTypeFlashCall &) {
return bad("FlashCall");
}, [&](const MTPDauth_sentCodeTypeMissedCall &) {
return bad("MissedCall");
}, [&](const MTPDauth_sentCodeTypeEmailCode &) {
return bad("EmailCode");
}, [&](const MTPDauth_sentCodeTypeSetUpEmailRequired &) {
return bad("SetUpEmailRequired");
});
const auto phoneHash = qs(data.vphone_code_hash());
const auto timeout = [&]() -> std::optional<int> {

View File

@@ -27,13 +27,19 @@ using namespace rpl::details;
template <typename T>
constexpr auto WithId =
is_callable_plain_v<T, const MTPUpdates &, Fn<void()>, mtpRequestId>;
is_callable_plain_v<T, Fn<void()>, mtpRequestId>;
template <typename T>
constexpr auto WithoutId =
is_callable_plain_v<T, const MTPUpdates &, Fn<void()>>;
is_callable_plain_v<T, Fn<void()>>;
template <typename T>
constexpr auto WithoutCallback =
is_callable_plain_v<T, const MTPUpdates &>;
is_callable_plain_v<T>;
template <typename T>
constexpr auto ErrorWithId =
is_callable_plain_v<T, QString, mtpRequestId>;
template <typename T>
constexpr auto ErrorWithoutId =
is_callable_plain_v<T, QString>;
template <typename DoneCallback, typename FailCallback>
mtpRequestId EditMessage(
@@ -93,22 +99,30 @@ mtpRequestId EditMessage(
const auto apply = [=] { api->applyUpdates(result); };
if constexpr (WithId<DoneCallback>) {
done(result, apply, requestId);
done(apply, requestId);
} else if constexpr (WithoutId<DoneCallback>) {
done(result, apply);
done(apply);
} else if constexpr (WithoutCallback<DoneCallback>) {
done(result);
done();
apply();
} else {
apply();
t_bad_callback(done);
}
if (updateRecentStickers) {
api->requestRecentStickersForce(true);
}
}).fail(
fail
).send();
}).fail([=](const MTP::Error &error, mtpRequestId requestId) {
if constexpr (ErrorWithId<FailCallback>) {
fail(error.type(), requestId);
} else if constexpr (ErrorWithoutId<FailCallback>) {
fail(error.type());
} else if constexpr (WithoutCallback<FailCallback>) {
fail();
} else {
t_bad_callback(fail);
}
}).send();
}
template <typename DoneCallback, typename FailCallback>
@@ -132,7 +146,7 @@ void EditMessageWithUploadedMedia(
not_null<HistoryItem*> item,
SendOptions options,
MTPInputMedia media) {
const auto done = [=](const auto &result, Fn<void()> applyUpdates) {
const auto done = [=](Fn<void()> applyUpdates) {
if (item) {
item->clearSavedMedia();
item->setIsLocalUpdateMedia(true);
@@ -140,11 +154,10 @@ void EditMessageWithUploadedMedia(
item->setIsLocalUpdateMedia(false);
}
};
const auto fail = [=](const MTP::Error &error) {
const auto err = error.type();
const auto fail = [=](const QString &error) {
const auto session = &item->history()->session();
const auto notModified = (err == u"MESSAGE_NOT_MODIFIED"_q);
const auto mediaInvalid = (err == u"MEDIA_NEW_INVALID"_q);
const auto notModified = (error == u"MESSAGE_NOT_MODIFIED"_q);
const auto mediaInvalid = (error == u"MEDIA_NEW_INVALID"_q);
if (notModified || mediaInvalid) {
item->returnSavedMedia();
session->data().sendHistoryChangeNotifications();
@@ -200,8 +213,8 @@ mtpRequestId EditCaption(
not_null<HistoryItem*> item,
const TextWithEntities &caption,
SendOptions options,
Fn<void(const MTPUpdates &)> done,
Fn<void(const MTP::Error &)> fail) {
Fn<void()> done,
Fn<void(const QString &)> fail) {
return EditMessage(item, caption, options, done, fail);
}
@@ -209,17 +222,13 @@ mtpRequestId EditTextMessage(
not_null<HistoryItem*> item,
const TextWithEntities &caption,
SendOptions options,
Fn<void(const MTPUpdates &, mtpRequestId requestId)> done,
Fn<void(const MTP::Error &, mtpRequestId requestId)> fail) {
const auto callback = [=](
const auto &result,
Fn<void()> applyUpdates,
auto id) {
Fn<void(mtpRequestId requestId)> done,
Fn<void(const QString &, mtpRequestId requestId)> fail) {
const auto callback = [=](Fn<void()> applyUpdates, mtpRequestId id) {
applyUpdates();
done(result, id);
done(id);
};
return EditMessage(item, caption, options, callback, fail);
}
} // namespace Api

View File

@@ -42,14 +42,14 @@ mtpRequestId EditCaption(
not_null<HistoryItem*> item,
const TextWithEntities &caption,
SendOptions options,
Fn<void(const MTPUpdates &)> done,
Fn<void(const MTP::Error &)> fail);
Fn<void()> done,
Fn<void(const QString &)> fail);
mtpRequestId EditTextMessage(
not_null<HistoryItem*> item,
const TextWithEntities &caption,
SendOptions options,
Fn<void(const MTPUpdates &, mtpRequestId requestId)> done,
Fn<void(const MTP::Error &, mtpRequestId requestId)> fail);
Fn<void(mtpRequestId requestId)> done,
Fn<void(const QString &error, mtpRequestId requestId)> fail);
} // namespace Api

View File

@@ -60,6 +60,23 @@ namespace {
: 0;
}
[[nodiscard]] uint64 CountFeaturedHash(
not_null<Main::Session*> session,
const Data::StickersSetsOrder &order) {
auto result = HashInit();
const auto &sets = session->data().stickers().sets();
for (const auto setId : order) {
HashUpdate(result, setId);
const auto it = sets.find(setId);
if (it != sets.cend()
&& (it->second->flags & Data::StickersSetFlag::Unread)) {
HashUpdate(result, 1);
}
}
return HashFinalize(result);
}
} // namespace
uint64 CountStickersHash(
@@ -80,6 +97,15 @@ uint64 CountMasksHash(
checkOutdatedInfo);
}
uint64 CountCustomEmojiHash(
not_null<Main::Session*> session,
bool checkOutdatedInfo) {
return CountStickersOrderHash(
session,
session->data().stickers().emojiSetsOrder(),
checkOutdatedInfo);
}
uint64 CountRecentStickersHash(
not_null<Main::Session*> session,
bool attached) {
@@ -95,19 +121,15 @@ uint64 CountFavedStickersHash(not_null<Main::Session*> session) {
}
uint64 CountFeaturedStickersHash(not_null<Main::Session*> session) {
auto result = HashInit();
const auto &sets = session->data().stickers().sets();
const auto &featured = session->data().stickers().featuredSetsOrder();
for (const auto setId : featured) {
HashUpdate(result, setId);
return CountFeaturedHash(
session,
session->data().stickers().featuredSetsOrder());
}
const auto it = sets.find(setId);
if (it != sets.cend()
&& (it->second->flags & Data::StickersSetFlag::Unread)) {
HashUpdate(result, 1);
}
}
return HashFinalize(result);
uint64 CountFeaturedEmojiHash(not_null<Main::Session*> session) {
return CountFeaturedHash(
session,
session->data().stickers().featuredEmojiSetsOrder());
}
uint64 CountSavedGifsHash(not_null<Main::Session*> session) {

View File

@@ -19,12 +19,18 @@ namespace Api {
[[nodiscard]] uint64 CountMasksHash(
not_null<Main::Session*> session,
bool checkOutdatedInfo = false);
[[nodiscard]] uint64 CountCustomEmojiHash(
not_null<Main::Session*> session,
bool checkOutdatedInfo = false);
[[nodiscard]] uint64 CountRecentStickersHash(
not_null<Main::Session*> session,
bool attached = false);
[[nodiscard]] uint64 CountFavedStickersHash(not_null<Main::Session*> session);
[[nodiscard]] uint64 CountFavedStickersHash(
not_null<Main::Session*> session);
[[nodiscard]] uint64 CountFeaturedStickersHash(
not_null<Main::Session*> session);
[[nodiscard]] uint64 CountFeaturedEmojiHash(
not_null<Main::Session*> session);
[[nodiscard]] uint64 CountSavedGifsHash(not_null<Main::Session*> session);
[[nodiscard]] inline uint64 HashInit() {

View File

@@ -37,7 +37,7 @@ void Polls::create(
const PollData &data,
const SendAction &action,
Fn<void()> done,
Fn<void(const MTP::Error &error)> fail) {
Fn<void()> fail) {
_session->api().sendAction(action);
const auto history = action.history;
@@ -101,7 +101,7 @@ void Polls::create(
history->finishSavingCloudDraft(
UnixtimeFromMsgId(response.outerMsgId));
}
fail(error);
fail();
finish();
}).afterRequest(history->sendRequestId
).send();

View File

@@ -29,7 +29,7 @@ public:
const PollData &data,
const SendAction &action,
Fn<void()> done,
Fn<void(const MTP::Error &error)> fail);
Fn<void()> fail);
void sendVotes(
FullMsgId itemId,
const std::vector<QByteArray> &options);

View File

@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_premium.h"
#include "api/api_premium_option.h"
#include "api/api_text_entities.h"
#include "main/main_session.h"
#include "data/data_peer_values.h"
@@ -27,6 +28,9 @@ Premium::Premium(not_null<ApiWrap*> api)
_session
) | rpl::start_with_next([=] {
reload();
if (_session->premium()) {
reloadCloudSet();
}
}, _session->lifetime());
});
}
@@ -54,6 +58,15 @@ rpl::producer<> Premium::stickersUpdated() const {
return _stickersUpdated.events();
}
auto Premium::cloudSet() const
-> const std::vector<not_null<DocumentData*>> & {
return _cloudSet;
}
rpl::producer<> Premium::cloudSetUpdated() const {
return _cloudSetUpdated.events();
}
int64 Premium::monthlyAmount() const {
return _monthlyAmount;
}
@@ -74,37 +87,43 @@ void Premium::reloadPromo() {
_promoRequestId = _api.request(MTPhelp_GetPremiumPromo(
)).done([=](const MTPhelp_PremiumPromo &result) {
_promoRequestId = 0;
result.match([&](const MTPDhelp_premiumPromo &data) {
_session->data().processUsers(data.vusers());
_monthlyAmount = data.vmonthly_amount().v;
_monthlyCurrency = qs(data.vcurrency());
auto text = TextWithEntities{
qs(data.vstatus_text()),
EntitiesFromMTP(_session, data.vstatus_entities().v),
};
_statusText = text;
_statusTextUpdates.fire(std::move(text));
auto videos = base::flat_map<QString, not_null<DocumentData*>>();
const auto count = int(std::min(
data.vvideo_sections().v.size(),
data.vvideos().v.size()));
videos.reserve(count);
for (auto i = 0; i != count; ++i) {
const auto document = _session->data().processDocument(
data.vvideos().v[i]);
if ((!document->isVideoFile() && !document->isGifv())
|| !document->supportsStreaming()) {
document->forceIsStreamedAnimation();
}
videos.emplace(
qs(data.vvideo_sections().v[i]),
document);
const auto &data = result.data();
_session->data().processUsers(data.vusers());
_subscriptionOptions = SubscriptionOptionsFromTL(
data.vperiod_options().v);
for (const auto &option : data.vperiod_options().v) {
if (option.data().vmonths().v == 1) {
_monthlyAmount = option.data().vamount().v;
_monthlyCurrency = qs(option.data().vcurrency());
}
if (_videos != videos) {
_videos = std::move(videos);
_videosUpdated.fire({});
}
auto text = TextWithEntities{
qs(data.vstatus_text()),
EntitiesFromMTP(_session, data.vstatus_entities().v),
};
_statusText = text;
_statusTextUpdates.fire(std::move(text));
auto videos = base::flat_map<QString, not_null<DocumentData*>>();
const auto count = int(std::min(
data.vvideo_sections().v.size(),
data.vvideos().v.size()));
videos.reserve(count);
for (auto i = 0; i != count; ++i) {
const auto document = _session->data().processDocument(
data.vvideos().v[i]);
if ((!document->isVideoFile() && !document->isGifv())
|| !document->supportsStreaming()) {
document->forceIsStreamedAnimation();
}
});
videos.emplace(
qs(data.vvideo_sections().v[i]),
document);
}
if (_videos != videos) {
_videos = std::move(videos);
_videosUpdated.fire({});
}
}).fail([=] {
_promoRequestId = 0;
}).send();
@@ -137,4 +156,35 @@ void Premium::reloadStickers() {
}).send();
}
void Premium::reloadCloudSet() {
if (_cloudSetRequestId) {
return;
}
_cloudSetRequestId = _api.request(MTPmessages_GetStickers(
MTP_string("\xf0\x9f\x93\x82\xe2\xad\x90\xef\xb8\x8f"),
MTP_long(_cloudSetHash)
)).done([=](const MTPmessages_Stickers &result) {
_cloudSetRequestId = 0;
result.match([&](const MTPDmessages_stickersNotModified &) {
}, [&](const MTPDmessages_stickers &data) {
_cloudSetHash = data.vhash().v;
const auto owner = &_session->data();
_cloudSet.clear();
for (const auto &sticker : data.vstickers().v) {
const auto document = owner->processDocument(sticker);
if (document->isPremiumSticker()) {
_cloudSet.push_back(document);
}
}
_cloudSetUpdated.fire({});
});
}).fail([=] {
_cloudSetRequestId = 0;
}).send();
}
const Data::SubscriptionOptions &Premium::subscriptionOptions() const {
return _subscriptionOptions;
}
} // namespace Api

View File

@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/data_subscription_option.h"
#include "mtproto/sender.h"
class ApiWrap;
@@ -32,12 +33,20 @@ public:
-> const std::vector<not_null<DocumentData*>> &;
[[nodiscard]] rpl::producer<> stickersUpdated() const;
[[nodiscard]] auto cloudSet() const
-> const std::vector<not_null<DocumentData*>> &;
[[nodiscard]] rpl::producer<> cloudSetUpdated() const;
[[nodiscard]] int64 monthlyAmount() const;
[[nodiscard]] QString monthlyCurrency() const;
[[nodiscard]] auto subscriptionOptions() const
-> const Data::SubscriptionOptions &;
private:
void reloadPromo();
void reloadStickers();
void reloadCloudSet();
const not_null<Main::Session*> _session;
MTP::Sender _api;
@@ -54,9 +63,16 @@ private:
std::vector<not_null<DocumentData*>> _stickers;
rpl::event_stream<> _stickersUpdated;
mtpRequestId _cloudSetRequestId = 0;
uint64 _cloudSetHash = 0;
std::vector<not_null<DocumentData*>> _cloudSet;
rpl::event_stream<> _cloudSetUpdated;
int64 _monthlyAmount = 0;
QString _monthlyCurrency;
Data::SubscriptionOptions _subscriptionOptions;
};
} // namespace Api

View File

@@ -0,0 +1,40 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_premium_option.h"
#include "ui/text/format_values.h"
namespace Api {
constexpr auto kDiscountDivider = 5.;
Data::SubscriptionOption CreateSubscriptionOption(
int months,
int monthlyAmount,
int64 amount,
const QString &currency,
const QString &botUrl) {
const auto discount = [&] {
const auto percent = monthlyAmount * months / float64(amount) - 1.;
return std::round(percent * 100. / kDiscountDivider)
* kDiscountDivider;
}();
return {
.duration = Ui::FormatTTL(months * 86400 * 31),
.discount = discount
? QString::fromUtf8("\xe2\x88\x92%1%").arg(discount)
: QString(),
.costPerMonth = Ui::FillAmountAndCurrency(
amount / float64(months),
currency),
.costTotal = Ui::FillAmountAndCurrency(amount, currency),
.botUrl = botUrl,
};
}
} // namespace Api

View File

@@ -0,0 +1,50 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/data_subscription_option.h"
namespace Api {
[[nodiscard]] Data::SubscriptionOption CreateSubscriptionOption(
int months,
int monthlyAmount,
int64 amount,
const QString &currency,
const QString &botUrl);
template<typename Option>
[[nodiscard]] Data::SubscriptionOptions SubscriptionOptionsFromTL(
const QVector<Option> &tlOptions) {
auto result = Data::SubscriptionOptions();
const auto monthlyAmount = [&] {
const auto &min = ranges::min_element(
tlOptions,
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) {
const auto &option = tlOption.data();
const auto botUrl = qs(option.vbot_url());
const auto months = option.vmonths().v;
const auto amount = option.vamount().v;
const auto currency = qs(option.vcurrency());
result.push_back(CreateSubscriptionOption(
months,
monthlyAmount,
amount,
currency,
botUrl));
}
return result;
}
} // namespace Api

View File

@@ -192,21 +192,21 @@ void Ringtones::remove(DocumentId id) {
}
int64 Ringtones::maxSize() const {
return int64(base::SafeRound(_session->account().appConfig().get<double>(
return _session->account().appConfig().get<int>(
"ringtone_size_max",
100 * 1024)));
100 * 1024);
}
int Ringtones::maxSavedCount() const {
return int(base::SafeRound(_session->account().appConfig().get<double>(
return _session->account().appConfig().get<int>(
"ringtone_saved_count_max",
100)));
100);
}
int Ringtones::maxDuration() const {
return int(base::SafeRound(_session->account().appConfig().get<double>(
return _session->account().appConfig().get<int>(
"ringtone_duration_max",
5)));
5);
}
} // namespace Api

View File

@@ -103,7 +103,7 @@ void SendExistingMedia(
sendFlags |= MTPmessages_SendMedia::Flag::f_send_as;
}
const auto messagePostAuthor = peer->isBroadcast()
? session->user()->name
? session->user()->name()
: QString();
auto caption = TextWithEntities{
@@ -231,7 +231,8 @@ bool SendDice(MessageToSend &message) {
const auto full = QStringView(message.textWithTags.text).trimmed();
auto length = 0;
if (!Ui::Emoji::Find(full.data(), full.data() + full.size(), &length)
|| length != full.size()) {
|| length != full.size()
|| !message.textWithTags.tags.isEmpty()) {
return false;
}
auto &account = message.action.history->session().account();
@@ -290,7 +291,7 @@ bool SendDice(MessageToSend &message) {
sendFlags |= MTPmessages_SendMedia::Flag::f_send_as;
}
const auto messagePostAuthor = peer->isBroadcast()
? session->user()->name
? session->user()->name()
: QString();
const auto replyTo = message.action.replyTo;
@@ -423,7 +424,7 @@ void SendConfirmedFile(
? PeerId()
: session->userPeerId();
const auto messagePostAuthor = peer->isBroadcast()
? session->user()->name
? session->user()->name()
: QString();
const auto media = MTPMessageMedia([&] {

View File

@@ -8,7 +8,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_text_entities.h"
#include "main/main_session.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/stickers/data_stickers_set.h"
#include "data/data_session.h"
#include "data/data_document.h"
#include "data/data_user.h"
namespace Api {
@@ -16,6 +19,46 @@ namespace {
using namespace TextUtilities;
[[nodiscard]] QString CustomEmojiEntityData(
const MTPDmessageEntityCustomEmoji &data) {
return Data::SerializeCustomEmojiId({
.id = data.vdocument_id().v,
});
}
[[nodiscard]] std::optional<MTPMessageEntity> CustomEmojiEntity(
MTPint offset,
MTPint length,
const QString &data) {
const auto parsed = Data::ParseCustomEmojiData(data);
if (!parsed.id) {
return {};
}
return MTP_messageEntityCustomEmoji(
offset,
length,
MTP_long(parsed.id));
}
[[nodiscard]] std::optional<MTPMessageEntity> MentionNameEntity(
not_null<Main::Session*> session,
MTPint offset,
MTPint length,
const QString &data) {
const auto parsed = MentionNameDataToFields(data);
if (!parsed.userId || parsed.selfId != session->userId().bare) {
return {};
}
return MTP_inputMessageEntityMentionName(
offset,
length,
(parsed.userId == parsed.selfId
? MTP_inputUserSelf()
: MTP_inputUser(
MTP_long(parsed.userId),
MTP_long(parsed.accessHash))));
}
} // namespace
EntitiesInText EntitiesFromMTP(
@@ -33,34 +76,35 @@ EntitiesInText EntitiesFromMTP(
case mtpc_messageEntityCashtag: { auto &d = entity.c_messageEntityCashtag(); result.push_back({ EntityType::Cashtag, d.voffset().v, d.vlength().v }); } break;
case mtpc_messageEntityPhone: break; // Skipping phones.
case mtpc_messageEntityMention: { auto &d = entity.c_messageEntityMention(); result.push_back({ EntityType::Mention, d.voffset().v, d.vlength().v }); } break;
case mtpc_messageEntityMentionName: {
case mtpc_messageEntityMentionName: if (session) {
const auto &d = entity.c_messageEntityMentionName();
const auto userId = UserId(d.vuser_id());
const auto data = [&] {
if (session) {
if (const auto user = session->data().userLoaded(userId)) {
return MentionNameDataFromFields({
userId.bare,
user->accessHash()
});
}
}
return MentionNameDataFromFields(userId.bare);
}();
const auto user = session->data().userLoaded(userId);
const auto data = MentionNameDataFromFields({
.selfId = session->userId().bare,
.userId = userId.bare,
.accessHash = user ? user->accessHash() : 0,
});
result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data });
} break;
case mtpc_inputMessageEntityMentionName: {
case mtpc_inputMessageEntityMentionName: if (session) {
const auto &d = entity.c_inputMessageEntityMentionName();
const auto data = [&] {
if (session && d.vuser_id().type() == mtpc_inputUserSelf) {
return MentionNameDataFromFields(session->userId().bare);
} else if (d.vuser_id().type() == mtpc_inputUser) {
auto &user = d.vuser_id().c_inputUser();
const auto userId = UserId(user.vuser_id());
return MentionNameDataFromFields({ userId.bare, user.vaccess_hash().v });
}
const auto data = d.vuser_id().match([&](
const MTPDinputUserSelf &) {
return MentionNameDataFromFields({
.selfId = session->userId().bare,
.userId = session->userId().bare,
.accessHash = session->user()->accessHash(),
});
}, [&](const MTPDinputUser &data) {
return MentionNameDataFromFields({
.selfId = session->userId().bare,
.userId = UserId(data.vuser_id()).bare,
.accessHash = data.vaccess_hash().v,
});
}, [&](const auto &) {
return QString();
}();
});
if (!data.isEmpty()) {
result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data });
}
@@ -72,9 +116,12 @@ EntitiesInText EntitiesFromMTP(
case mtpc_messageEntityStrike: { auto &d = entity.c_messageEntityStrike(); result.push_back({ EntityType::StrikeOut, d.voffset().v, d.vlength().v }); } break;
case mtpc_messageEntityCode: { auto &d = entity.c_messageEntityCode(); result.push_back({ EntityType::Code, d.voffset().v, d.vlength().v }); } break;
case mtpc_messageEntityPre: { auto &d = entity.c_messageEntityPre(); result.push_back({ EntityType::Pre, d.voffset().v, d.vlength().v, qs(d.vlanguage()) }); } break;
case mtpc_messageEntityBankCard: break; // Skipping cards.
case mtpc_messageEntityBankCard: break; // Skipping cards. // #TODO entities
case mtpc_messageEntitySpoiler: { auto &d = entity.c_messageEntitySpoiler(); result.push_back({ EntityType::Spoiler, d.voffset().v, d.vlength().v }); } break;
// #TODO entities
case mtpc_messageEntityCustomEmoji: {
const auto &d = entity.c_messageEntityCustomEmoji();
result.push_back({ EntityType::CustomEmoji, d.voffset().v, d.vlength().v, CustomEmojiEntityData(d) });
} break;
}
}
}
@@ -99,7 +146,8 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(
&& entity.type() != EntityType::Pre
&& entity.type() != EntityType::Spoiler
&& entity.type() != EntityType::MentionName
&& entity.type() != EntityType::CustomUrl) {
&& entity.type() != EntityType::CustomUrl
&& entity.type() != EntityType::CustomEmoji) {
continue;
}
@@ -113,17 +161,8 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(
case EntityType::Cashtag: v.push_back(MTP_messageEntityCashtag(offset, length)); break;
case EntityType::Mention: v.push_back(MTP_messageEntityMention(offset, length)); break;
case EntityType::MentionName: {
auto inputUser = [&](const QString &data) -> MTPInputUser {
auto fields = MentionNameDataToFields(data);
if (session && fields.userId == session->userId().bare) {
return MTP_inputUserSelf();
} else if (fields.userId) {
return MTP_inputUser(MTP_long(fields.userId), MTP_long(fields.accessHash));
}
return MTP_inputUserEmpty();
}(entity.data());
if (inputUser.type() != mtpc_inputUserEmpty) {
v.push_back(MTP_inputMessageEntityMentionName(offset, length, inputUser));
if (const auto valid = MentionNameEntity(session, offset, length, entity.data())) {
v.push_back(*valid);
}
} break;
case EntityType::BotCommand: v.push_back(MTP_messageEntityBotCommand(offset, length)); break;
@@ -134,6 +173,11 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(
case EntityType::Code: v.push_back(MTP_messageEntityCode(offset, length)); break; // #TODO entities
case EntityType::Pre: v.push_back(MTP_messageEntityPre(offset, length, MTP_string(entity.data()))); break;
case EntityType::Spoiler: v.push_back(MTP_messageEntitySpoiler(offset, length)); break;
case EntityType::CustomEmoji: {
if (const auto valid = CustomEmojiEntity(offset, length, entity.data())) {
v.push_back(*valid);
}
} break;
}
}
return MTP_vector<MTPMessageEntity>(std::move(v));

View File

@@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel.h"
#include "data/data_chat_filters.h"
#include "data/data_cloud_themes.h"
#include "data/data_emoji_statuses.h"
#include "data/data_group_call.h"
#include "data/data_drafts.h"
#include "data/data_histories.h"
@@ -1649,6 +1650,15 @@ void Updates::feedUpdate(const MTPUpdate &update) {
}
} break;
case mtpc_updateMessageExtendedMedia: {
const auto &d = update.c_updateMessageExtendedMedia();
const auto peerId = peerFromMTP(d.vpeer());
const auto msgId = d.vmsg_id().v;
if (const auto item = session().data().message(peerId, msgId)) {
item->applyEdition(d.vextended_media());
}
} break;
// Messages being read.
case mtpc_updateReadHistoryInbox: {
auto &d = update.c_updateReadHistoryInbox();
@@ -2298,6 +2308,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateStickerSetsOrder: {
auto &d = update.c_updateStickerSetsOrder();
auto &stickers = session().data().stickers();
const auto isEmoji = d.is_emojis();
const auto isMasks = d.is_masks();
const auto &order = d.vorder().v;
const auto &sets = stickers.sets();
@@ -2308,11 +2319,16 @@ void Updates::feedUpdate(const MTPUpdate &update) {
}
result.push_back(item.v);
}
const auto localSize = isMasks
const auto localSize = isEmoji
? stickers.emojiSetsOrder().size()
: isMasks
? stickers.maskSetsOrder().size()
: stickers.setsOrder().size();
if ((result.size() != localSize) || (result.size() != order.size())) {
if (isMasks) {
if (isEmoji) {
stickers.setLastEmojiUpdate(0);
session().api().updateCustomEmoji();
} else if (isMasks) {
stickers.setLastMasksUpdate(0);
session().api().updateMasks();
} else {
@@ -2320,23 +2336,66 @@ void Updates::feedUpdate(const MTPUpdate &update) {
session().api().updateStickers();
}
} else {
if (isMasks) {
if (isEmoji) {
stickers.emojiSetsOrderRef() = std::move(result);
session().local().writeInstalledCustomEmoji();
} else if (isMasks) {
stickers.maskSetsOrderRef() = std::move(result);
session().local().writeInstalledMasks();
} else {
stickers.setsOrderRef() = std::move(result);
session().local().writeInstalledStickers();
}
stickers.notifyUpdated();
stickers.notifyUpdated(isEmoji
? Data::StickersType::Emoji
: isMasks
? Data::StickersType::Masks
: Data::StickersType::Stickers);
}
} break;
case mtpc_updateMoveStickerSetToTop: {
const auto &d = update.c_updateMoveStickerSetToTop();
auto &stickers = session().data().stickers();
const auto isEmoji = d.is_emojis();
const auto setId = d.vstickerset().v;
auto &order = isEmoji
? stickers.emojiSetsOrderRef()
: stickers.setsOrderRef();
const auto i = ranges::find(order, setId);
if (i == order.end()) {
if (isEmoji) {
stickers.setLastEmojiUpdate(0);
session().api().updateCustomEmoji();
} else {
stickers.setLastUpdate(0);
session().api().updateStickers();
}
} else if (i != order.begin()) {
std::rotate(order.begin(), i, i + 1);
if (isEmoji) {
session().local().writeInstalledCustomEmoji();
} else {
session().local().writeInstalledStickers();
}
stickers.notifyUpdated(isEmoji
? Data::StickersType::Emoji
: Data::StickersType::Stickers);
}
} break;
case mtpc_updateStickerSets: {
// Can't determine is it masks or stickers, so update both.
session().data().stickers().setLastUpdate(0);
session().api().updateStickers();
session().data().stickers().setLastMasksUpdate(0);
session().api().updateMasks();
const auto &d = update.c_updateStickerSets();
if (d.is_emojis()) {
session().data().stickers().setLastEmojiUpdate(0);
session().api().updateCustomEmoji();
} else if (d.is_masks()) {
session().data().stickers().setLastMasksUpdate(0);
session().api().updateMasks();
} else {
session().data().stickers().setLastUpdate(0);
session().api().updateStickers();
}
} break;
case mtpc_updateRecentStickers: {
@@ -2357,10 +2416,29 @@ void Updates::feedUpdate(const MTPUpdate &update) {
session().api().updateStickers();
} break;
case mtpc_updateReadFeaturedEmojiStickers: {
// We don't track read status of them for now.
} break;
case mtpc_updateUserEmojiStatus: {
const auto &d = update.c_updateUserEmojiStatus();
if (const auto user = session().data().userLoaded(d.vuser_id())) {
user->setEmojiStatus(d.vemoji_status());
}
} break;
case mtpc_updateRecentEmojiStatuses: {
session().data().emojiStatuses().refreshRecentDelayed();
} break;
case mtpc_updateRecentReactions: {
session().data().reactions().refreshRecentDelayed();
} break;
////// Cloud saved GIFs
case mtpc_updateSavedGifs: {
session().data().stickers().setLastSavedGifsUpdate(0);
session().api().updateStickers();
session().api().updateSavedGifs();
} break;
////// Cloud drafts

View File

@@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "data/data_user.h"
#include "main/main_session.h"
#include "settings/settings_premium.h" // Settings::ShowPremium.
namespace Api {
namespace {
@@ -186,6 +187,8 @@ MTPInputPrivacyKey KeyToTL(UserPrivacy::Key key) {
return MTP_inputPrivacyKeyForwards();
case Key::ProfilePhoto:
return MTP_inputPrivacyKeyProfilePhoto();
case Key::Voices:
return MTP_inputPrivacyKeyVoiceMessages();
}
Unexpected("Key in Api::UserPrivacy::KetToTL.");
}
@@ -209,6 +212,8 @@ std::optional<UserPrivacy::Key> TLToKey(mtpTypeId type) {
case mtpc_inputPrivacyKeyForwards: return Key::Forwards;
case mtpc_privacyKeyProfilePhoto:
case mtpc_inputPrivacyKeyProfilePhoto: return Key::ProfilePhoto;
case mtpc_privacyKeyVoiceMessages:
case mtpc_inputPrivacyKeyVoiceMessages: return Key::Voices;
}
return std::nullopt;
}
@@ -241,7 +246,11 @@ void UserPrivacy::save(
_privacySaveRequests.remove(keyTypeId);
apply(keyTypeId, data.vrules(), true);
});
}).fail([=] {
}).fail([=](const MTP::Error &error) {
const auto message = error.type();
if (message == u"PREMIUM_ACCOUNT_REQUIRED"_q) {
Settings::ShowPremium(_session, QString());
}
_privacySaveRequests.remove(keyTypeId);
}).send();

View File

@@ -28,6 +28,7 @@ public:
CallsPeer2Peer,
Forwards,
ProfilePhoto,
Voices,
};
enum class Option {
Everyone,

View File

@@ -20,13 +20,16 @@ namespace {
// Send channel views each second.
constexpr auto kSendViewsTimeout = crl::time(1000);
constexpr auto kPollExtendedMediaPeriod = 30 * crl::time(1000);
constexpr auto kMaxPollPerRequest = 100;
} // namespace
ViewsManager::ViewsManager(not_null<ApiWrap*> api)
: _session(&api->session())
, _api(&api->instance())
, _incrementTimer([=] { viewsIncrement(); }) {
, _incrementTimer([=] { viewsIncrement(); })
, _pollTimer([=] { sendPollRequests(); }) {
}
void ViewsManager::scheduleIncrement(not_null<HistoryItem*> item) {
@@ -52,6 +55,25 @@ void ViewsManager::removeIncremented(not_null<PeerData*> peer) {
_incremented.remove(peer);
}
void ViewsManager::pollExtendedMedia(not_null<HistoryItem*> item) {
if (!item->isRegular()) {
return;
}
const auto id = item->id;
const auto peer = item->history()->peer;
auto &request = _pollRequests[peer];
if (request.ids.contains(id) || request.sent.contains(id)) {
return;
}
request.ids.emplace(id);
if (!request.id && !request.when) {
request.when = crl::now() + kPollExtendedMediaPeriod;
}
if (!_pollTimer.isActive()) {
_pollTimer.callOnce(kPollExtendedMediaPeriod);
}
}
void ViewsManager::viewsIncrement() {
for (auto i = _toIncrement.begin(); i != _toIncrement.cend();) {
if (_incrementRequests.contains(i->first)) {
@@ -81,6 +103,88 @@ void ViewsManager::viewsIncrement() {
}
}
void ViewsManager::sendPollRequests() {
const auto now = crl::now();
auto toRequest = base::flat_map<not_null<PeerData*>, QVector<MTPint>>();
auto nearest = crl::time();
for (auto &[peer, request] : _pollRequests) {
if (request.id) {
continue;
} else if (request.when <= now) {
Assert(request.sent.empty());
auto &list = toRequest[peer];
const auto count = int(request.ids.size());
if (count < kMaxPollPerRequest) {
request.sent = base::take(request.ids);
} else {
const auto from = begin(request.ids);
const auto end = from + kMaxPollPerRequest;
request.sent = { from, end };
request.ids.erase(from, end);
}
list.reserve(request.sent.size());
for (const auto &id : request.sent) {
list.push_back(MTP_int(id.bare));
}
if (!request.ids.empty()) {
nearest = now;
}
} else if (!nearest || nearest > request.when) {
nearest = request.when;
}
}
sendPollRequests(toRequest);
if (nearest) {
_pollTimer.callOnce(std::max(nearest - now, crl::time(1)));
}
}
void ViewsManager::sendPollRequests(
const base::flat_map<
not_null<PeerData*>,
QVector<MTPint>> &batched) {
for (auto &[peer, list] : batched) {
const auto finish = [=, list = list](mtpRequestId id) {
const auto now = crl::now();
const auto owner = &_session->data();
for (auto i = begin(_pollRequests); i != end(_pollRequests);) {
if (i->second.id == id) {
const auto peer = i->first->id;
for (const auto &itemId : i->second.sent) {
if (const auto item = owner->message(peer, itemId)) {
owner->requestItemRepaint(item);
}
}
i->second.sent.clear();
i->second.id = 0;
if (i->second.ids.empty()) {
i = _pollRequests.erase(i);
} else {
i->second.when = now + kPollExtendedMediaPeriod;
if (!_pollTimer.isActive()) {
_pollTimer.callOnce(kPollExtendedMediaPeriod);
}
++i;
}
} else {
++i;
}
}
};
const auto requestId = _api.request(MTPmessages_GetExtendedMedia(
peer->input,
MTP_vector<MTPint>(list)
)).done([=](const MTPUpdates &result, mtpRequestId id) {
_session->api().applyUpdates(result);
finish(id);
}).fail([=](const MTP::Error &error, mtpRequestId id) {
finish(id);
}).send();
_pollRequests[peer].id = requestId;
}
}
void ViewsManager::done(
QVector<MTPint> ids,
const MTPmessages_MessageViews &result,

View File

@@ -26,8 +26,22 @@ public:
void scheduleIncrement(not_null<HistoryItem*> item);
void removeIncremented(not_null<PeerData*> peer);
void pollExtendedMedia(not_null<HistoryItem*> item);
private:
struct PollExtendedMediaRequest {
crl::time when = 0;
mtpRequestId id = 0;
base::flat_set<MsgId> ids;
base::flat_set<MsgId> sent;
};
void viewsIncrement();
void sendPollRequests();
void sendPollRequests(
const base::flat_map<
not_null<PeerData*>,
QVector<MTPint>> &prepared);
void done(
QVector<MTPint> ids,
@@ -44,6 +58,11 @@ private:
base::flat_map<mtpRequestId, not_null<PeerData*>> _incrementByRequest;
base::Timer _incrementTimer;
base::flat_map<
not_null<PeerData*>,
PollExtendedMediaRequest> _pollRequests;
base::Timer _pollTimer;
};
} // namespace Api

View File

@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item.h"
#include "history/history.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/data_peer.h"
#include "data/data_chat.h"
#include "data/data_channel.h"
@@ -17,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_changes.h"
#include "data/data_session.h"
#include "data/data_media_types.h"
#include "data/data_message_reaction_id.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
#include "main/main_account.h"
@@ -31,6 +33,8 @@ namespace {
constexpr auto kContextReactionsLimit = 50;
using Data::ReactionId;
struct Peers {
std::vector<PeerId> list;
bool unknown = false;
@@ -41,7 +45,7 @@ inline bool operator==(const Peers &a, const Peers &b) noexcept {
struct PeerWithReaction {
PeerId peer = 0;
QString reaction;
ReactionId reaction;
};
inline bool operator==(
const PeerWithReaction &a,
@@ -84,7 +88,7 @@ struct Context {
base::flat_map<not_null<HistoryItem*>, CachedRead> cachedRead;
base::flat_map<
not_null<HistoryItem*>,
base::flat_map<QString, CachedReacted>> cachedReacted;
base::flat_map<ReactionId, CachedReacted>> cachedReacted;
base::flat_map<not_null<Main::Session*>, rpl::lifetime> subscriptions;
[[nodiscard]] CachedRead &cacheRead(not_null<HistoryItem*> item) {
@@ -97,7 +101,7 @@ struct Context {
[[nodiscard]] CachedReacted &cacheReacted(
not_null<HistoryItem*> item,
const QString &reaction) {
const ReactionId &reaction) {
auto &map = cachedReacted[item];
const auto i = map.find(reaction);
if (i != end(map)) {
@@ -109,7 +113,7 @@ struct Context {
struct Userpic {
not_null<PeerData*> peer;
QString reaction;
QString customEntityData;
mutable std::shared_ptr<Data::CloudImageView> view;
mutable InMemoryKey uniqueKey;
};
@@ -249,7 +253,7 @@ struct State {
Peers &&peers) {
auto result = PeersWithReactions{
.list = peers.list | ranges::views::transform([](PeerId peer) {
return PeerWithReaction{.peer = peer };
return PeerWithReaction{ .peer = peer };
}) | ranges::to_vector,
.unknown = peers.unknown,
};
@@ -259,7 +263,7 @@ struct State {
[[nodiscard]] rpl::producer<PeersWithReactions> WhoReactedIds(
not_null<HistoryItem*> item,
const QString &reaction,
const ReactionId &reaction,
not_null<QWidget*> context) {
auto weak = QPointer<QWidget>(context.get());
const auto session = &item->history()->session();
@@ -273,12 +277,12 @@ struct State {
using Flag = MTPmessages_GetMessageReactionsList::Flag;
entry.requestId = session->api().request(
MTPmessages_GetMessageReactionsList(
MTP_flags(reaction.isEmpty()
MTP_flags(reaction.empty()
? Flag(0)
: Flag::f_reaction),
item->history()->peer->input,
MTP_int(item->id),
MTP_string(reaction),
ReactionToMTP(reaction),
MTPstring(), // offset
MTP_int(kContextReactionsLimit)
)
@@ -299,7 +303,8 @@ struct State {
vote.match([&](const auto &data) {
parsed.list.push_back(PeerWithReaction{
.peer = peerFromMTP(data.vpeer_id()),
.reaction = qs(data.vreaction()),
.reaction = Data::ReactionFromMTP(
data.vreaction()),
});
});
}
@@ -322,7 +327,7 @@ struct State {
not_null<QWidget*> context)
-> rpl::producer<PeersWithReactions> {
return rpl::combine(
WhoReactedIds(item, QString(), context),
WhoReactedIds(item, {}, context),
WhoReadIds(item, context)
) | rpl::map([=](PeersWithReactions &&reacted, Peers &&read) {
if (reacted.unknown || read.unknown) {
@@ -347,7 +352,7 @@ bool UpdateUserpics(
struct ResolvedPeer {
PeerData *peer = nullptr;
QString reaction;
ReactionId reaction;
};
const auto peers = ranges::views::all(
ids
@@ -373,17 +378,16 @@ bool UpdateUserpics(
auto now = std::vector<Userpic>();
for (const auto &resolved : peers) {
const auto peer = not_null{ resolved.peer };
if (ranges::contains(now, peer, &Userpic::peer)) {
continue;
}
const auto &data = ReactionEntityData(resolved.reaction);
const auto i = ranges::find(was, peer, &Userpic::peer);
if (i != end(was)) {
if (i != end(was) && i->view) {
now.push_back(std::move(*i));
now.back().customEntityData = data;
continue;
}
now.push_back(Userpic{
.peer = peer,
.reaction = resolved.reaction,
.customEntityData = data,
});
auto &userpic = now.back();
userpic.uniqueKey = peer->userpicUniqueKey(userpic.view);
@@ -426,13 +430,13 @@ void RegenerateParticipants(not_null<State*> state, int small, int large) {
const auto id = peer->id.value;
const auto was = ranges::find(old, id, &Ui::WhoReadParticipant::id);
if (was != end(old)) {
was->name = peer->name;
was->name = peer->name();
now.push_back(std::move(*was));
continue;
}
now.push_back({
.name = peer->name,
.reaction = userpic.reaction,
.name = peer->name(),
.customEntityData = userpic.customEntityData,
.userpicLarge = GenerateUserpic(userpic, large),
.userpicKey = userpic.uniqueKey,
.id = id,
@@ -446,7 +450,7 @@ void RegenerateParticipants(not_null<State*> state, int small, int large) {
rpl::producer<Ui::WhoReadContent> WhoReacted(
not_null<HistoryItem*> item,
const QString &reaction,
const ReactionId &reaction,
not_null<QWidget*> context,
const style::WhoRead &st,
std::shared_ptr<WhoReadList> whoReadIds) {
@@ -455,7 +459,7 @@ rpl::producer<Ui::WhoReadContent> WhoReacted(
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
const auto resolveWhoRead = reaction.isEmpty()
const auto resolveWhoRead = reaction.empty()
&& WhoReadExists(item);
const auto state = lifetime.make_state<State>();
@@ -463,7 +467,7 @@ rpl::producer<Ui::WhoReadContent> WhoReacted(
consumer.put_next_copy(state->current);
};
const auto resolveWhoReacted = !reaction.isEmpty()
const auto resolveWhoReacted = !reaction.empty()
|| item->canViewReactions();
auto idsWithReactions = (resolveWhoRead && resolveWhoReacted)
? WhoReadOrReactedIds(item, context)
@@ -475,22 +479,26 @@ rpl::producer<Ui::WhoReadContent> WhoReacted(
: Ui::WhoReadType::Reacted;
if (resolveWhoReacted) {
const auto &list = item->reactions();
state->current.fullReactionsCount = reaction.isEmpty()
? ranges::accumulate(
state->current.fullReactionsCount = [&] {
if (reaction.empty()) {
return ranges::accumulate(
list,
0,
ranges::plus{},
&Data::MessageReaction::count);
}
const auto i = ranges::find(
list,
0,
ranges::plus{},
[](const auto &pair) { return pair.second; })
: list.contains(reaction)
? list.find(reaction)->second
: 0;
// #TODO reactions
state->current.singleReaction = !reaction.isEmpty()
reaction,
&Data::MessageReaction::id);
return (i != end(list)) ? i->count : 0;
}();
state->current.singleCustomEntityData = ReactionEntityData(
!reaction.empty()
? reaction
: (list.size() == 1)
? list.front().first
: QString();
? list.front().id
: ReactionId());
}
std::move(
idsWithReactions
@@ -510,7 +518,7 @@ rpl::producer<Ui::WhoReadContent> WhoReacted(
if (whoReadIds) {
const auto reacted = peers.list.size() - ranges::count(
peers.list,
QString(),
ReactionId(),
&PeerWithReaction::reaction);
whoReadIds->list = (peers.read.size() > reacted)
? std::move(peers.read)
@@ -567,15 +575,15 @@ bool WhoReadExists(not_null<HistoryItem*> item) {
return false;
}
const auto &appConfig = peer->session().account().appConfig();
const auto expirePeriod = TimeId(appConfig.get<double>(
const auto expirePeriod = appConfig.get<int>(
"chat_read_mark_expire_period",
7 * 86400.));
if (item->date() + expirePeriod <= base::unixtime::now()) {
7 * 86400);
if (item->date() + int64(expirePeriod) <= int64(base::unixtime::now())) {
return false;
}
const auto maxCount = int(appConfig.get<double>(
const auto maxCount = appConfig.get<int>(
"chat_read_mark_size_threshold",
50));
50);
const auto count = megagroup ? megagroup->membersCount() : chat->count;
if (count <= 0 || count > maxCount) {
return false;
@@ -583,8 +591,13 @@ bool WhoReadExists(not_null<HistoryItem*> item) {
return true;
}
bool WhoReactedExists(not_null<HistoryItem*> item) {
return item->canViewReactions() || WhoReadExists(item);
bool WhoReactedExists(
not_null<HistoryItem*> item,
WhoReactedList list) {
if (item->canViewReactions() || WhoReadExists(item)) {
return true;
}
return (list == WhoReactedList::One) && item->history()->peer->isUser();
}
rpl::producer<Ui::WhoReadContent> WhoReacted(
@@ -592,12 +605,12 @@ rpl::producer<Ui::WhoReadContent> WhoReacted(
not_null<QWidget*> context,
const style::WhoRead &st,
std::shared_ptr<WhoReadList> whoReadIds) {
return WhoReacted(item, QString(), context, st, std::move(whoReadIds));
return WhoReacted(item, {}, context, st, std::move(whoReadIds));
}
rpl::producer<Ui::WhoReadContent> WhoReacted(
not_null<HistoryItem*> item,
const QString &reaction,
const Data::ReactionId &reaction,
not_null<QWidget*> context,
const style::WhoRead &st) {
return WhoReacted(item, reaction, context, st, nullptr);

View File

@@ -18,10 +18,21 @@ struct WhoReadContent;
enum class WhoReadType;
} // namespace Ui
namespace Data {
struct ReactionId;
} // namespace Data
namespace Api {
enum class WhoReactedList {
All,
One,
};
[[nodiscard]] bool WhoReadExists(not_null<HistoryItem*> item);
[[nodiscard]] bool WhoReactedExists(not_null<HistoryItem*> item);
[[nodiscard]] bool WhoReactedExists(
not_null<HistoryItem*> item,
WhoReactedList list);
struct WhoReadList {
std::vector<PeerId> list;
@@ -36,7 +47,7 @@ struct WhoReadList {
std::shared_ptr<WhoReadList> whoReadIds = nullptr);
[[nodiscard]] rpl::producer<Ui::WhoReadContent> WhoReacted(
not_null<HistoryItem*> item,
const QString &reaction,
const Data::ReactionId &reaction,
not_null<QWidget*> context, // Cache results for this lifetime.
const style::WhoRead &st);

View File

@@ -293,14 +293,20 @@ void ApiWrap::topPromotionDone(const MTPhelp_PromoData &proxy) {
void ApiWrap::requestDeepLinkInfo(
const QString &path,
Fn<void(const MTPDhelp_deepLinkInfo &result)> callback) {
Fn<void(TextWithEntities message, bool updateRequired)> callback) {
request(_deepLinkInfoRequestId).cancel();
_deepLinkInfoRequestId = request(MTPhelp_GetDeepLinkInfo(
MTP_string(path)
)).done([=](const MTPhelp_DeepLinkInfo &result) {
_deepLinkInfoRequestId = 0;
if (result.type() == mtpc_help_deepLinkInfo) {
callback(result.c_help_deepLinkInfo());
const auto &data = result.c_help_deepLinkInfo();
callback(TextWithEntities{
qs(data.vmessage()),
Api::EntitiesFromMTP(
_session,
data.ventities().value_or_empty())
}, data.is_update_app());
}
}).fail([=] {
_deepLinkInfoRequestId = 0;
@@ -438,14 +444,22 @@ void ApiWrap::sendMessageFail(
not_null<PeerData*> peer,
uint64 randomId,
FullMsgId itemId) {
sendMessageFail(error.type(), peer, randomId, itemId);
}
void ApiWrap::sendMessageFail(
const QString &error,
not_null<PeerData*> peer,
uint64 randomId,
FullMsgId itemId) {
const auto show = ShowForPeer(peer);
if (error.type() == qstr("PEER_FLOOD")) {
if (error == qstr("PEER_FLOOD")) {
show->showBox(
Ui::MakeInformBox(
PeerFloodErrorText(&session(), PeerFloodType::Send)),
Ui::LayerOption::CloseOther);
} else if (error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
} else if (error == qstr("USER_BANNED_IN_CHANNEL")) {
const auto link = Ui::Text::Link(
tr::lng_cant_more_info(tr::now),
session().createInternalLinkFull(qsl("spambot")));
@@ -457,9 +471,9 @@ void ApiWrap::sendMessageFail(
link,
Ui::Text::WithEntities)),
Ui::LayerOption::CloseOther);
} else if (error.type().startsWith(qstr("SLOWMODE_WAIT_"))) {
} else if (error.startsWith(qstr("SLOWMODE_WAIT_"))) {
const auto chop = qstr("SLOWMODE_WAIT_").size();
const auto left = base::StringViewMid(error.type(), chop).toInt();
const auto left = base::StringViewMid(error, chop).toInt();
if (const auto channel = peer->asChannel()) {
const auto seconds = channel->slowmodeSeconds();
if (seconds >= left) {
@@ -469,7 +483,7 @@ void ApiWrap::sendMessageFail(
requestFullPeer(peer);
}
}
} else if (error.type() == qstr("SCHEDULE_STATUS_PRIVATE")) {
} else if (error == qstr("SCHEDULE_STATUS_PRIVATE")) {
auto &scheduled = _session->data().scheduledMessages();
Assert(peer->isUser());
if (const auto item = scheduled.lookupItem(peer->id, itemId.msg)) {
@@ -478,7 +492,7 @@ void ApiWrap::sendMessageFail(
Ui::MakeInformBox(tr::lng_cant_do_this()),
Ui::LayerOption::CloseOther);
}
} else if (error.type() == qstr("CHAT_FORWARDS_RESTRICTED")) {
} else if (error == qstr("CHAT_FORWARDS_RESTRICTED")) {
if (show->valid()) {
Ui::ShowMultilineToast({
.parentOverride = show->toastParent(),
@@ -489,7 +503,7 @@ void ApiWrap::sendMessageFail(
.duration = kJoinErrorDuration
});
}
} else if (error.type() == qstr("PREMIUM_ACCOUNT_REQUIRED")) {
} else if (error == qstr("PREMIUM_ACCOUNT_REQUIRED")) {
Settings::ShowPremium(&session(), "premium_stickers");
}
if (const auto item = _session->data().message(itemId)) {
@@ -984,7 +998,7 @@ rpl::producer<bool> ApiWrap::dialogsLoadBlockedByDate() const {
void ApiWrap::requestWallPaper(
const QString &slug,
Fn<void(const Data::WallPaper &)> done,
Fn<void(const MTP::Error &)> fail) {
Fn<void()> fail) {
if (_wallPaperSlug != slug) {
_wallPaperSlug = slug;
if (_wallPaperRequestId) {
@@ -1006,13 +1020,13 @@ void ApiWrap::requestWallPaper(
done(*paper);
}
} else if (const auto fail = base::take(_wallPaperFail)) {
fail(MTP::Error::Local("BAD_DOCUMENT", "In a wallpaper."));
fail();
}
}).fail([=](const MTP::Error &error) {
_wallPaperRequestId = 0;
_wallPaperSlug = QString();
if (const auto fail = base::take(_wallPaperFail)) {
fail(error);
fail();
}
}).send();
}
@@ -1117,44 +1131,6 @@ void ApiWrap::gotUserFull(
Data::PeerUpdate::Flag::FullInfo);
}
void ApiWrap::requestPeer(not_null<PeerData*> peer) {
if (_fullPeerRequests.contains(peer) || _peerRequests.contains(peer)) {
return;
}
const auto requestId = [&] {
const auto failHandler = [=] {
_peerRequests.remove(peer);
};
const auto chatHandler = [=](const MTPmessages_Chats &result) {
_peerRequests.remove(peer);
const auto &chats = result.match([](const auto &data) {
return data.vchats();
});
_session->data().applyMaximumChatVersions(chats);
_session->data().processChats(chats);
};
if (const auto user = peer->asUser()) {
return request(MTPusers_GetUsers(
MTP_vector<MTPInputUser>(1, user->inputUser)
)).done([=](const MTPVector<MTPUser> &result) {
_peerRequests.remove(user);
_session->data().processUsers(result);
}).fail(failHandler).send();
} else if (const auto chat = peer->asChat()) {
return request(MTPmessages_GetChats(
MTP_vector<MTPlong>(1, chat->inputChat)
)).done(chatHandler).fail(failHandler).send();
} else if (const auto channel = peer->asChannel()) {
return request(MTPchannels_GetChannels(
MTP_vector<MTPInputChannel>(1, channel->inputChannel)
)).done(chatHandler).fail(failHandler).send();
}
Unexpected("Peer type in requestPeer.");
}();
_peerRequests.emplace(peer, requestId);
}
void ApiWrap::requestPeerSettings(not_null<PeerData*> peer) {
if (!_requestedPeerSettings.emplace(peer).second) {
return;
@@ -1311,51 +1287,6 @@ void ApiWrap::markContentsRead(not_null<HistoryItem*> item) {
}
}
void ApiWrap::requestPeers(const QList<PeerData*> &peers) {
QVector<MTPlong> chats;
QVector<MTPInputChannel> channels;
QVector<MTPInputUser> users;
chats.reserve(peers.size());
channels.reserve(peers.size());
users.reserve(peers.size());
for (const auto peer : peers) {
if (!peer
|| _fullPeerRequests.contains(peer)
|| _peerRequests.contains(peer)) {
continue;
}
if (const auto user = peer->asUser()) {
users.push_back(user->inputUser);
} else if (const auto chat = peer->asChat()) {
chats.push_back(chat->inputChat);
} else if (const auto channel = peer->asChannel()) {
channels.push_back(channel->inputChannel);
}
}
const auto handleChats = [=](const MTPmessages_Chats &result) {
_session->data().processChats(result.match([](const auto &data) {
return data.vchats();
}));
};
if (!chats.isEmpty()) {
request(MTPmessages_GetChats(
MTP_vector<MTPlong>(chats)
)).done(handleChats).send();
}
if (!channels.isEmpty()) {
request(MTPchannels_GetChannels(
MTP_vector<MTPInputChannel>(channels)
)).done(handleChats).send();
}
if (!users.isEmpty()) {
request(MTPusers_GetUsers(
MTP_vector<MTPInputUser>(users)
)).done([=](const MTPVector<MTPUser> &result) {
_session->data().processUsers(result);
}).send();
}
}
void ApiWrap::deleteAllFromParticipant(
not_null<ChannelData*> channel,
not_null<PeerData*> from) {
@@ -1419,12 +1350,16 @@ void ApiWrap::requestStickerSets() {
void ApiWrap::saveStickerSets(
const Data::StickersSetsOrder &localOrder,
const Data::StickersSetsOrder &localRemoved,
bool setsMasks) {
auto &setDisenableRequests = setsMasks
Data::StickersType type) {
auto &setDisenableRequests = (type == Data::StickersType::Emoji)
? _customEmojiSetDisenableRequests
: (type == Data::StickersType::Masks)
? _maskSetDisenableRequests
: _stickerSetDisenableRequests;
const auto reorderRequestId = [=]() -> mtpRequestId & {
return setsMasks
return (type == Data::StickersType::Emoji)
? _customEmojiReorderRequestId
: (type == Data::StickersType::Masks)
? _masksReorderRequestId
: _stickersReorderRequestId;
};
@@ -1445,9 +1380,12 @@ void ApiWrap::saveStickerSets(
mtpOrder.push_back(MTP_long(setId));
}
const auto flags = setsMasks
? MTPmessages_ReorderStickerSets::Flag::f_masks
: MTPmessages_ReorderStickerSets::Flags(0);
using Flag = MTPmessages_ReorderStickerSets::Flag;
const auto flags = (type == Data::StickersType::Emoji)
? Flag::f_emojis
: (type == Data::StickersType::Masks)
? Flag::f_masks
: Flag(0);
reorderRequestId() = request(MTPmessages_ReorderStickerSets(
MTP_flags(flags),
MTP_vector<MTPlong>(mtpOrder)
@@ -1455,7 +1393,10 @@ void ApiWrap::saveStickerSets(
reorderRequestId() = 0;
}).fail([=] {
reorderRequestId() = 0;
if (setsMasks) {
if (type == Data::StickersType::Emoji) {
_session->data().stickers().setLastEmojiUpdate(0);
updateCustomEmoji();
} else if (type == Data::StickersType::Masks) {
_session->data().stickers().setLastMasksUpdate(0);
updateMasks();
} else {
@@ -1466,7 +1407,9 @@ void ApiWrap::saveStickerSets(
};
const auto stickerSetDisenabled = [=](mtpRequestId requestId) {
auto &setDisenableRequests = setsMasks
auto &setDisenableRequests = (type == Data::StickersType::Emoji)
? _customEmojiSetDisenableRequests
: (type == Data::StickersType::Masks)
? _maskSetDisenableRequests
: _stickerSetDisenableRequests;
setDisenableRequests.remove(requestId);
@@ -1484,10 +1427,14 @@ void ApiWrap::saveStickerSets(
auto &recent = _session->data().stickers().getRecentPack();
auto &sets = _session->data().stickers().setsRef();
auto &order = setsMasks
auto &order = (type == Data::StickersType::Emoji)
? _session->data().stickers().emojiSetsOrder()
: (type == Data::StickersType::Masks)
? _session->data().stickers().maskSetsOrder()
: _session->data().stickers().setsOrder();
auto &orderRef = setsMasks
auto &orderRef = (type == Data::StickersType::Emoji)
? _session->data().stickers().emojiSetsOrderRef()
: (type == Data::StickersType::Masks)
? _session->data().stickers().maskSetsOrderRef()
: _session->data().stickers().setsOrderRef();
@@ -1543,6 +1490,8 @@ void ApiWrap::saveStickerSets(
if (!archived) {
const auto featured = !!(set->flags & Flag::Featured);
const auto special = !!(set->flags & Flag::Special);
const auto emoji = !!(set->flags & Flag::Emoji);
const auto locked = (set->locked > 0);
const auto setId = set->mtpInput();
auto requestId = request(MTPmessages_UninstallStickerSet(
@@ -1559,7 +1508,7 @@ void ApiWrap::saveStickerSets(
if (removeIndex >= 0) {
orderRef.removeAt(removeIndex);
}
if (!featured && !special) {
if (!featured && !special && !emoji && !locked) {
sets.erase(it);
} else {
if (archived) {
@@ -1575,8 +1524,12 @@ void ApiWrap::saveStickerSets(
// Clear all installed flags, set only for sets from order.
for (auto &[id, set] : sets) {
const auto archived = !!(set->flags & Flag::Archived);
const auto masks = !!(set->flags & Flag::Masks);
if (!archived && (setsMasks == masks)) {
const auto thatType = !!(set->flags & Flag::Emoji)
? Data::StickersType::Emoji
: !!(set->flags & Flag::Masks)
? Data::StickersType::Masks
: Data::StickersType::Stickers;
if (!archived && (type == thatType)) {
set->flags &= ~Flag::Installed;
}
}
@@ -1622,7 +1575,9 @@ void ApiWrap::saveStickerSets(
if ((set->flags & Flag::Featured)
|| (set->flags & Flag::Installed)
|| (set->flags & Flag::Archived)
|| (set->flags & Flag::Special)) {
|| (set->flags & Flag::Special)
|| (set->flags & Flag::Emoji)
|| (set->locked > 0)) {
++it;
} else {
it = sets.erase(it);
@@ -1630,17 +1585,21 @@ void ApiWrap::saveStickerSets(
}
auto &storage = local();
if (writeInstalled && !setsMasks) {
storage.writeInstalledStickers();
}
if (writeInstalled && setsMasks) {
storage.writeInstalledMasks();
if (writeInstalled) {
if (type == Data::StickersType::Emoji) {
storage.writeInstalledCustomEmoji();
} else if (type == Data::StickersType::Masks) {
storage.writeInstalledMasks();
} else {
storage.writeInstalledStickers();
}
}
if (writeRecent) {
session().saveSettings();
}
if (writeArchived) {
if (setsMasks) {
if (type == Data::StickersType::Emoji) {
} else if (type == Data::StickersType::Masks) {
storage.writeArchivedMasks();
} else {
storage.writeArchivedStickers();
@@ -1655,7 +1614,7 @@ void ApiWrap::saveStickerSets(
if (writeFaved) {
storage.writeFavedStickers();
}
_session->data().stickers().notifyUpdated();
_session->data().stickers().notifyUpdated(type);
if (setDisenableRequests.empty()) {
stickersSaveOrder();
@@ -2502,6 +2461,10 @@ void ApiWrap::updateStickers() {
requestRecentStickers(now);
requestFavedStickers(now);
requestFeaturedStickers(now);
}
void ApiWrap::updateSavedGifs() {
const auto now = crl::now();
requestSavedGifs(now);
}
@@ -2511,6 +2474,12 @@ void ApiWrap::updateMasks() {
requestRecentStickers(now, true);
}
void ApiWrap::updateCustomEmoji() {
const auto now = crl::now();
requestCustomEmoji(now);
requestFeaturedEmoji(now);
}
void ApiWrap::requestRecentStickersForce(bool attached) {
requestRecentStickersWithHash(0, attached);
}
@@ -2525,7 +2494,7 @@ void ApiWrap::setGroupStickerSet(
megagroup->inputChannel,
Data::InputStickerSet(set)
)).send();
_session->data().stickers().notifyUpdated();
_session->data().stickers().notifyUpdated(Data::StickersType::Stickers);
}
std::vector<not_null<DocumentData*>> *ApiWrap::stickersByEmoji(
@@ -2565,7 +2534,8 @@ std::vector<not_null<DocumentData*>> *ApiWrap::stickersByEmoji(
}
entry.hash = data.vhash().v;
entry.received = crl::now();
_session->data().stickers().notifyUpdated();
_session->data().stickers().notifyUpdated(
Data::StickersType::Stickers);
}).send();
}
if (it == _stickersByEmoji.end()) {
@@ -2624,6 +2594,30 @@ void ApiWrap::requestMasks(TimeId now) {
}).send();
}
void ApiWrap::requestCustomEmoji(TimeId now) {
if (!_session->data().stickers().emojiUpdateNeeded(now)
|| _customEmojiUpdateRequest) {
return;
}
const auto done = [=](const MTPmessages_AllStickers &result) {
_session->data().stickers().setLastEmojiUpdate(crl::now());
_customEmojiUpdateRequest = 0;
result.match([&](const MTPDmessages_allStickersNotModified&) {
}, [&](const MTPDmessages_allStickers &data) {
_session->data().stickers().emojiReceived(
data.vsets().v,
data.vhash().v);
});
};
_customEmojiUpdateRequest = request(MTPmessages_GetEmojiStickers(
MTP_long(Api::CountCustomEmojiHash(_session, true))
)).done(done).fail([=] {
LOG(("App Fail: Failed to get custom emoji!"));
done(MTP_messages_allStickersNotModified());
}).send();
}
void ApiWrap::requestRecentStickers(TimeId now, bool attached) {
const auto needed = attached
? _session->data().stickers().recentAttachedUpdateNeeded(now)
@@ -2725,28 +2719,33 @@ void ApiWrap::requestFeaturedStickers(TimeId now) {
_featuredStickersUpdateRequest = request(MTPmessages_GetFeaturedStickers(
MTP_long(Api::CountFeaturedStickersHash(_session))
)).done([=](const MTPmessages_FeaturedStickers &result) {
_session->data().stickers().setLastFeaturedUpdate(crl::now());
_featuredStickersUpdateRequest = 0;
switch (result.type()) {
case mtpc_messages_featuredStickersNotModified: return;
case mtpc_messages_featuredStickers: {
auto &d = result.c_messages_featuredStickers();
_session->data().stickers().featuredSetsReceived(
d.vsets().v,
d.vunread().v,
d.vhash().v);
} return;
default: Unexpected("Type in ApiWrap::featuredStickersDone()");
}
_session->data().stickers().featuredSetsReceived(result);
}).fail([=] {
_session->data().stickers().setLastFeaturedUpdate(crl::now());
_featuredStickersUpdateRequest = 0;
_session->data().stickers().setLastFeaturedUpdate(crl::now());
LOG(("App Fail: Failed to get featured stickers!"));
}).send();
}
void ApiWrap::requestFeaturedEmoji(TimeId now) {
if (!_session->data().stickers().featuredEmojiUpdateNeeded(now)
|| _featuredEmojiUpdateRequest) {
return;
}
_featuredEmojiUpdateRequest = request(
MTPmessages_GetFeaturedEmojiStickers(
MTP_long(Api::CountFeaturedStickersHash(_session)))
).done([=](const MTPmessages_FeaturedStickers &result) {
_featuredEmojiUpdateRequest = 0;
_session->data().stickers().featuredEmojiSetsReceived(result);
}).fail([=] {
_featuredEmojiUpdateRequest = 0;
_session->data().stickers().setLastFeaturedEmojiUpdate(crl::now());
LOG(("App Fail: Failed to get featured emoji!"));
}).send();
}
void ApiWrap::requestSavedGifs(TimeId now) {
if (!_session->data().stickers().savedGifsUpdateNeeded(now)
|| _savedGifsUpdateRequest) {
@@ -2805,16 +2804,20 @@ void ApiWrap::readFeaturedSets() {
MTP_vector<MTPlong>(wrappedIds));
request(std::move(requestData)).done([=] {
local().writeFeaturedStickers();
_session->data().stickers().notifyUpdated();
_session->data().stickers().notifyUpdated(
Data::StickersType::Stickers);
}).send();
_session->data().stickers().setFeaturedSetsUnreadCount(count);
}
}
void ApiWrap::jumpToDate(Dialogs::Key chat, const QDate &date) {
void ApiWrap::resolveJumpToDate(
Dialogs::Key chat,
const QDate &date,
Fn<void(not_null<PeerData*>, MsgId)> callback) {
if (const auto peer = chat.peer()) {
jumpToHistoryDate(peer, date);
resolveJumpToHistoryDate(peer, date, std::move(callback));
}
}
@@ -2886,20 +2889,22 @@ void ApiWrap::requestMessageAfterDate(
}).send();
}
void ApiWrap::jumpToHistoryDate(not_null<PeerData*> peer, const QDate &date) {
void ApiWrap::resolveJumpToHistoryDate(
not_null<PeerData*> peer,
const QDate &date,
Fn<void(not_null<PeerData*>, MsgId)> callback) {
if (const auto channel = peer->migrateTo()) {
jumpToHistoryDate(channel, date);
return;
return resolveJumpToHistoryDate(channel, date, std::move(callback));
}
const auto jumpToDateInPeer = [=] {
requestMessageAfterDate(peer, date, [=](MsgId resultId) {
Ui::showPeerHistory(peer, resultId);
callback(peer, resultId);
});
};
if (const auto chat = peer->migrateFrom()) {
requestMessageAfterDate(chat, date, [=](MsgId resultId) {
if (resultId) {
Ui::showPeerHistory(chat, resultId);
callback(chat, resultId);
} else {
jumpToDateInPeer();
}
@@ -3121,7 +3126,7 @@ void ApiWrap::forwardMessages(
? PeerId(0)
: self->id;
const auto messagePostAuthor = peer->isBroadcast()
? self->name
? self->name()
: QString();
history->addNewLocalMessage(
newId.msg,
@@ -3204,7 +3209,7 @@ void ApiWrap::sendSharedContact(
? PeerId()
: _session->userPeerId();
const auto messagePostAuthor = peer->isBroadcast()
? _session->user()->name
? _session->user()->name()
: QString();
const auto viaBotId = UserId();
const auto item = history->addNewLocalMessage(
@@ -3467,7 +3472,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
sendFlags |= MTPmessages_SendMessage::Flag::f_send_as;
}
const auto messagePostAuthor = peer->isBroadcast()
? _session->user()->name
? _session->user()->name()
: QString();
if (action.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled;
@@ -3615,7 +3620,7 @@ void ApiWrap::sendInlineResult(
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_send_as;
}
const auto messagePostAuthor = peer->isBroadcast()
? _session->user()->name
? _session->user()->name()
: QString();
_session->data().registerMessageRandomId(randomId, newId);

View File

@@ -31,6 +31,7 @@ struct UpdatedFileReferences;
class WallPaper;
struct ResolvedForwardDraft;
enum class DefaultNotify;
enum class StickersType : uchar;
} // namespace Data
namespace InlineBots {
@@ -170,11 +171,9 @@ public:
void requestWallPaper(
const QString &slug,
Fn<void(const Data::WallPaper &)> done,
Fn<void(const MTP::Error &)> fail);
Fn<void()> fail);
void requestFullPeer(not_null<PeerData*> peer);
void requestPeer(not_null<PeerData*> peer);
void requestPeers(const QList<PeerData*> &peers);
void requestPeerSettings(not_null<PeerData*> peer);
using UpdatedFileReferences = Data::UpdatedFileReferences;
@@ -194,7 +193,7 @@ public:
void refreshTopPromotion();
void requestDeepLinkInfo(
const QString &path,
Fn<void(const MTPDhelp_deepLinkInfo &result)> callback);
Fn<void(TextWithEntities message, bool updateRequired)> callback);
void requestTermsUpdate();
void acceptTerms(bytes::const_span termsId);
@@ -229,9 +228,11 @@ public:
void saveStickerSets(
const Data::StickersSetsOrder &localOrder,
const Data::StickersSetsOrder &localRemoved,
bool setsMasks);
Data::StickersType type);
void updateStickers();
void updateSavedGifs();
void updateMasks();
void updateCustomEmoji();
void requestRecentStickersForce(bool attached = false);
void setGroupStickerSet(
not_null<ChannelData*> megagroup,
@@ -256,7 +257,10 @@ public:
bool isQuitPrevent();
void jumpToDate(Dialogs::Key chat, const QDate &date);
void resolveJumpToDate(
Dialogs::Key chat,
const QDate &date,
Fn<void(not_null<PeerData*>, MsgId)> callback);
using SliceType = Data::LoadDirection;
void requestSharedMedia(
@@ -337,6 +341,11 @@ public:
not_null<PeerData*> peer,
uint64 randomId = 0,
FullMsgId itemId = FullMsgId());
void sendMessageFail(
const QString &error,
not_null<PeerData*> peer,
uint64 randomId = 0,
FullMsgId itemId = FullMsgId());
void reloadContactSignupSilent();
rpl::producer<bool> contactSignupSilent() const;
@@ -435,14 +444,19 @@ 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 requestFeaturedStickers(TimeId now);
void requestFeaturedEmoji(TimeId now);
void requestSavedGifs(TimeId now);
void readFeaturedSets();
void jumpToHistoryDate(not_null<PeerData*> peer, const QDate &date);
void resolveJumpToHistoryDate(
not_null<PeerData*> peer,
const QDate &date,
Fn<void(not_null<PeerData*>, MsgId)> callback);
template <typename Callback>
void requestMessageAfterDate(
not_null<PeerData*> peer,
@@ -522,7 +536,6 @@ private:
using PeerRequests = base::flat_map<PeerData*, mtpRequestId>;
PeerRequests _fullPeerRequests;
PeerRequests _peerRequests;
base::flat_set<not_null<PeerData*>> _requestedPeerSettings;
base::flat_map<
@@ -541,17 +554,21 @@ private:
base::flat_set<mtpRequestId> _stickerSetDisenableRequests;
base::flat_set<mtpRequestId> _maskSetDisenableRequests;
base::flat_set<mtpRequestId> _customEmojiSetDisenableRequests;
mtpRequestId _masksReorderRequestId = 0;
mtpRequestId _customEmojiReorderRequestId = 0;
mtpRequestId _stickersReorderRequestId = 0;
mtpRequestId _stickersClearRecentRequestId = 0;
mtpRequestId _stickersClearRecentAttachedRequestId = 0;
mtpRequestId _stickersUpdateRequest = 0;
mtpRequestId _masksUpdateRequest = 0;
mtpRequestId _customEmojiUpdateRequest = 0;
mtpRequestId _recentStickersUpdateRequest = 0;
mtpRequestId _recentAttachedStickersUpdateRequest = 0;
mtpRequestId _favedStickersUpdateRequest = 0;
mtpRequestId _featuredStickersUpdateRequest = 0;
mtpRequestId _featuredEmojiUpdateRequest = 0;
mtpRequestId _savedGifsUpdateRequest = 0;
base::Timer _featuredSetsReadTimer;
@@ -601,8 +618,6 @@ private:
mtpRequestId _termsUpdateRequestId = 0;
mtpRequestId _checkInviteRequestId = 0;
FnMut<void(const MTPChatInvite &result)> _checkInviteDone;
Fn<void(const MTP::Error &error)> _checkInviteFail;
struct MigrateCallbacks {
FnMut<void(not_null<ChannelData*>)> done;
@@ -612,8 +627,6 @@ private:
not_null<PeerData*>,
std::vector<MigrateCallbacks>> _migrateCallbacks;
std::vector<FnMut<void(const MTPUser &)>> _supportContactCallbacks;
struct {
mtpRequestId requestId = 0;
QString requestedText;
@@ -641,7 +654,7 @@ private:
mtpRequestId _wallPaperRequestId = 0;
QString _wallPaperSlug;
Fn<void(const Data::WallPaper &)> _wallPaperDone;
Fn<void(const MTP::Error &)> _wallPaperFail;
Fn<void()> _wallPaperFail;
mtpRequestId _contactSignupSilentRequestId = 0;
std::optional<bool> _contactSignupSilent;

View File

@@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text_utilities.h"
#include "ui/unread_badge.h"
#include "ui/ui_utility.h"
#include "ui/painter.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_user.h"
@@ -269,7 +270,7 @@ void AddContactBox::setInnerFocus() {
void AddContactBox::paintEvent(QPaintEvent *e) {
BoxContent::paintEvent(e);
Painter p(this);
auto p = QPainter(this);
if (_retrying) {
p.setPen(st::boxTextFg);
p.setFont(st::boxTextFont);
@@ -379,10 +380,7 @@ void AddContactBox::save() {
MTP_string(lastName)))
)).done(crl::guard(weak, [=](
const MTPcontacts_ImportedContacts &result) {
const auto &data = result.match([](
const auto &data) -> const MTPDcontacts_importedContacts& {
return data;
});
const auto &data = result.data();
session->data().processUsers(data.vusers());
if (!weak) {
return;
@@ -900,10 +898,10 @@ void SetupChannelBox::prepare() {
}
void SetupChannelBox::setInnerFocus() {
if (_link->isHidden()) {
setFocus();
} else {
if (!_link->isHidden()) {
_link->setFocusFast();
} else {
BoxContent::setInnerFocus();
}
}
@@ -1094,7 +1092,7 @@ void SetupChannelBox::save() {
MTP_string(_sentUsername)
)).done([=] {
_channel->setName(
TextUtilities::SingleLine(_channel->name),
TextUtilities::SingleLine(_channel->name()),
_sentUsername);
closeBox();
}).fail([=](const MTP::Error &error) {
@@ -1167,7 +1165,7 @@ void SetupChannelBox::handleChange() {
void SetupChannelBox::check() {
if (_checkRequestId) {
_channel->session().api().request(_checkRequestId).cancel();
_api.request(_checkRequestId).cancel();
}
const auto link = _link->text().trimmed();
if (link.size() >= Ui::EditPeer::kMinUsernameLength) {
@@ -1242,7 +1240,7 @@ void SetupChannelBox::updateFail(UsernameResult result) {
if ((result == UsernameResult::Ok)
|| (_sentUsername == _channel->username)) {
_channel->setName(
TextUtilities::SingleLine(_channel->name),
TextUtilities::SingleLine(_channel->name()),
TextUtilities::SingleLine(_sentUsername));
closeBox();
} else if (result == UsernameResult::Invalid) {

View File

@@ -111,7 +111,7 @@ private:
void requestPapers();
void sortPapers();
void paintPaper(
Painter &p,
QPainter &p,
const Paper &paper,
int column,
int row) const;
@@ -289,7 +289,7 @@ void BackgroundBox::Inner::resizeToContentAndPreload() {
void BackgroundBox::Inner::paintEvent(QPaintEvent *e) {
QRect r(e->rect());
Painter p(this);
auto p = QPainter(this);
if (_papers.empty()) {
p.setFont(st::noContactsFont);
@@ -361,7 +361,7 @@ void BackgroundBox::Inner::validatePaperThumbnail(
}
void BackgroundBox::Inner::paintPaper(
Painter &p,
QPainter &p,
const Paper &paper,
int column,
int row) const {

View File

@@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/toast/toast.h"
#include "ui/image/image.h"
#include "ui/widgets/checkbox.h"
#include "ui/painter.h"
#include "ui/ui_utility.h"
#include "history/history.h"
#include "history/history_message.h"
@@ -357,7 +358,8 @@ void BackgroundPreviewBox::paintTexts(Painter &p, crl::time ms) {
auto context = _controller->defaultChatTheme()->preparePaintContext(
_chatStyle.get(),
rect(),
rect());
rect(),
_controller->isGifPausedAtLeastFor(Window::GifPauseReason::Layer));
p.translate(0, textsTop());
paintDate(p);
@@ -552,7 +554,7 @@ bool BackgroundPreviewBox::Start(
controller->show(Box<BackgroundPreviewBox>(
controller,
result.withUrlParams(params)));
}), crl::guard(controller, [=](const MTP::Error &error) {
}), crl::guard(controller, [=] {
controller->show(Ui::MakeInformBox(tr::lng_background_bad_link()));
}));
return true;

View File

@@ -1078,40 +1078,6 @@ ringtonesBoxButton: SettingsButton(defaultSettingsButton) {
}
ringtonesBoxSkip: 7px;
premiumBubblePadding: margins(14px, 0px, 14px, 0px);
premiumBubblePenWidth: 6;
premiumBubbleHeight: 40px;
premiumBubbleSkip: 8px;
premiumBubbleWidthLimit: 80px;
premiumBubbleTextSkip: 3px;
premiumBubbleSlideDuration: 1000;
premiumBubbleTailSize: size(21px, 7px);
premiumBubbleFont: font(19px);
premiumLineTextSkip: 11px;
premiumInfographicPadding: margins(0px, 10px, 0px, 15px);
premiumIconChats: icon {{ "limits/chats", settingsIconFg }};
premiumIconFiles: icon {{ "limits/files", settingsIconFg }};
premiumIconFolders: icon {{ "limits/folders", settingsIconFg }};
premiumIconGroups: icon {{ "limits/groups", settingsIconFg }};
premiumIconLinks: icon {{ "limits/links", settingsIconFg }};
premiumIconPins: icon {{ "limits/pins", settingsIconFg }};
premiumIconAccounts: icon {{ "limits/accounts", settingsIconFg }};
premiumAccountsCheckbox: RoundImageCheckbox(defaultPeerListCheckbox) {
imageRadius: 27px;
imageSmallRadius: 23px;
check: RoundCheckbox(defaultRoundCheckbox) {
size: 0px;
}
}
premiumAccountsLabelSize: size(22px, 15px);
premiumAccountsLabelPadding: margins(2px, 2px, 2px, 2px);
premiumAccountsLabelRadius: 6;
premiumAccountsNameTop: 13px;
premiumAccountsPadding: margins(0px, 20px, 0px, 14px);
premiumAccountsHeight: 105px;
gradientButtonGlareDuration: 700;
gradientButtonGlareTimeout: 2000;
gradientButtonGlareWidth: 100px;

View File

@@ -215,6 +215,11 @@ void ChangePhone::EnterPhone::sendPhoneDone(
return data;
});
const auto bad = [&](const char *type) {
LOG(("API Error: Should not be '%1'.").arg(type));
showError(Lang::Hard::ServerError());
return false;
};
auto codeLength = 0;
const auto hasLength = data.vtype().match([&](
const MTPDauth_sentCodeTypeApp &typeData) {
@@ -227,14 +232,14 @@ void ChangePhone::EnterPhone::sendPhoneDone(
}, [&](const MTPDauth_sentCodeTypeCall &typeData) {
codeLength = typeData.vlength().v;
return true;
}, [&](const MTPDauth_sentCodeTypeFlashCall &typeData) {
LOG(("Error: should not be flashcall!"));
showError(Lang::Hard::ServerError());
return false;
}, [&](const MTPDauth_sentCodeTypeMissedCall &data) {
LOG(("Error: should not be missedcall!"));
showError(Lang::Hard::ServerError());
return false;
}, [&](const MTPDauth_sentCodeTypeFlashCall &) {
return bad("FlashCall");
}, [&](const MTPDauth_sentCodeTypeMissedCall &) {
return bad("MissedCall");
}, [&](const MTPDauth_sentCodeTypeEmailCode &) {
return bad("EmailCode");
}, [&](const MTPDauth_sentCodeTypeSetUpEmailRequired &) {
return bad("SetUpEmailRequired");
});
if (!hasLength) {
return;

View File

@@ -69,7 +69,7 @@ void ChangeFilterById(
MTP_flags(MTPmessages_UpdateDialogFilter::Flag::f_filter),
MTP_int(filter.id()),
filter.tl()
)).done([=, chat = history->peer->name, filterName = filter.title()] {
)).done([=, chat = history->peer->name(), name = filter.title()]{
// Since only the primary window has dialogs list,
// We can safely show toast there.
if (const auto controller = Core::App().primaryWindow()) {
@@ -80,7 +80,7 @@ void ChangeFilterById(
lt_chat,
Ui::Text::Bold(chat),
lt_folder,
Ui::Text::Bold(filterName),
Ui::Text::Bold(name),
Ui::Text::WithEntities);
Ui::Toast::Show(
Window::Show(controller).toastParent(),

View File

@@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text_options.h"
#include "ui/text/text_utilities.h"
#include "ui/basic_click_handlers.h"
#include "ui/painter.h"
#include "boxes/abstract_box.h" // Ui::show().
#include "styles/style_layers.h"
#include "styles/style_boxes.h"

View File

@@ -120,20 +120,29 @@ void DeleteMessagesBox::prepare() {
: peer->isSelf()
? tr::lng_sure_delete_saved_messages(tr::now)
: peer->isUser()
? tr::lng_sure_delete_history(tr::now, lt_contact, peer->name)
? tr::lng_sure_delete_history(
tr::now,
lt_contact,
peer->name())
: tr::lng_sure_delete_group_history(
tr::now,
lt_group,
peer->name);
peer->name());
details = Ui::Text::RichLangValue(details.text);
deleteStyle = &st::attentionBoxButton;
} else {
details.text = peer->isSelf()
? tr::lng_sure_delete_saved_messages(tr::now)
: peer->isUser()
? tr::lng_sure_delete_history(tr::now, lt_contact, peer->name)
? tr::lng_sure_delete_history(
tr::now,
lt_contact,
peer->name())
: peer->isChat()
? tr::lng_sure_delete_and_exit(tr::now, lt_group, peer->name)
? tr::lng_sure_delete_and_exit(
tr::now,
lt_group,
peer->name())
: peer->isMegagroup()
? tr::lng_sure_leave_group(tr::now)
: tr::lng_sure_leave_channel(tr::now);
@@ -189,7 +198,7 @@ void DeleteMessagesBox::prepare() {
tr::lng_delete_all_from_user(
tr::now,
lt_user,
Ui::Text::Bold(_moderateFrom->name),
Ui::Text::Bold(_moderateFrom->name()),
Ui::Text::WithEntities),
false,
st::defaultBoxCheckbox);

View File

@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "base/event_filter.h"
#include "boxes/premium_limits_box.h"
#include "boxes/premium_preview_box.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "chat_helpers/message_field.h"
#include "chat_helpers/tabbed_panel.h"
@@ -25,9 +26,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "data/data_user.h"
#include "data/data_premium_limits.h"
#include "data/stickers/data_stickers.h"
#include "data/stickers/data_custom_emoji.h"
#include "editor/photo_editor_layer_widget.h"
#include "history/history_drag_area.h"
#include "history/history_item.h"
#include "history/history.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "main/main_session_settings.h"
@@ -44,6 +48,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/scroll_content_shadow.h"
#include "ui/image/image.h"
#include "ui/toast/toast.h"
#include "ui/painter.h"
#include "ui/ui_utility.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/input_fields.h"
@@ -65,7 +70,7 @@ auto ListFromMimeData(not_null<const QMimeData*> data, bool premium) {
auto result = data->hasUrls()
? Storage::PrepareMediaList(
// When we edit media, we need only 1 file.
data->urls().mid(0, 1),
base::GetMimeUrls(data).mid(0, 1),
st::sendMediaPreviewSize,
premium)
: Ui::PreparedList(Error::EmptyFile, QString());
@@ -126,8 +131,7 @@ EditCaptionBox::EditCaptionBox(
this,
st::confirmCaptionArea,
Ui::InputField::Mode::MultiLine,
tr::lng_photo_caption(),
PrepareEditText(item)))
tr::lng_photo_caption()))
, _emojiToggle(base::make_unique_q<Ui::EmojiButton>(
this,
st::boxAttachEmoji)) {
@@ -151,6 +155,7 @@ void EditCaptionBox::prepare() {
setupField();
setupEmojiPanel();
setInitialText();
rebuildPreview();
setupEditEventHandler();
@@ -241,20 +246,25 @@ void EditCaptionBox::rebuildPreview() {
}
void EditCaptionBox::setupField() {
const auto show = std::make_shared<Window::Show>(_controller);
const auto session = &_controller->session();
const auto peer = _historyItem->history()->peer;
const auto allow = [=](const auto&) {
return Data::AllowEmojiWithoutPremium(peer);
};
InitMessageFieldHandlers(
_controller,
_field.get(),
Window::GifPauseReason::Layer,
allow);
Ui::Emoji::SuggestionsController::Init(
getDelegate()->outerContainer(),
_field,
&_controller->session(),
{ .suggestCustomEmoji = true, .allowCustomWithoutPremium = allow });
_field->setSubmitSettings(
Core::App().settings().sendSubmitWay());
_field->setInstantReplaces(Ui::InstantReplaces::Default());
_field->setInstantReplacesEnabled(
Core::App().settings().replaceEmojiValue());
_field->setMarkdownReplacesEnabled(rpl::single(true));
_field->setEditLinkCallback(
DefaultEditLinkCallback(show, session, _field));
_field->setMaxHeight(st::confirmCaptionArea.heightMax);
InitSpellchecker(show, session, _field);
connect(_field, &Ui::InputField::submitted, [=] { save(); });
connect(_field, &Ui::InputField::cancelled, [=] { closeBox(); });
connect(_field, &Ui::InputField::resized, [=] { captionResized(); });
@@ -273,11 +283,12 @@ void EditCaptionBox::setupField() {
}
Unexpected("Action in MimeData hook.");
});
Ui::Emoji::SuggestionsController::Init(
getDelegate()->outerContainer(),
_field,
&_controller->session());
}
void EditCaptionBox::setInitialText() {
_field->setTextWithTags(
PrepareEditText(_historyItem),
Ui::InputField::HistoryAction::Clear);
auto cursor = _field->textCursor();
cursor.movePosition(QTextCursor::End);
_field->setTextCursor(cursor);
@@ -478,21 +489,37 @@ void EditCaptionBox::setupDragArea() {
void EditCaptionBox::setupEmojiPanel() {
const auto container = getDelegate()->outerContainer();
using Selector = ChatHelpers::TabbedSelector;
_emojiPanel = base::make_unique_q<ChatHelpers::TabbedPanel>(
container,
_controller,
object_ptr<ChatHelpers::TabbedSelector>(
object_ptr<Selector>(
nullptr,
_controller,
ChatHelpers::TabbedSelector::Mode::EmojiOnly));
Window::GifPauseReason::Layer,
Selector::Mode::EmojiOnly));
_emojiPanel->setDesiredHeightValues(
1.,
st::emojiPanMinHeight / 2,
st::emojiPanMinHeight);
_emojiPanel->hide();
_emojiPanel->selector()->setCurrentPeer(_historyItem->history()->peer);
_emojiPanel->selector()->emojiChosen(
) | rpl::start_with_next([=](EmojiPtr emoji) {
Ui::InsertEmojiAtCursor(_field->textCursor(), emoji);
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
Ui::InsertEmojiAtCursor(_field->textCursor(), data.emoji);
}, lifetime());
_emojiPanel->selector()->customEmojiChosen(
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
const auto info = data.document->sticker();
if (info
&& info->setType == Data::StickersType::Emoji
&& !_controller->session().premium()) {
ShowPremiumPreviewBox(
_controller,
PremiumPreview::AnimatedEmoji);
} else {
Data::InsertCustomEmoji(_field.get(), data.document);
}
}, lifetime());
const auto filterCallback = [=](not_null<QEvent*> event) {
@@ -712,20 +739,19 @@ void EditCaptionBox::save() {
return;
}
const auto done = crl::guard(this, [=](const MTPUpdates &updates) {
const auto done = crl::guard(this, [=] {
_saveRequestId = 0;
closeBox();
});
const auto fail = crl::guard(this, [=](const MTP::Error &error) {
const auto fail = crl::guard(this, [=](const QString &error) {
_saveRequestId = 0;
const auto &type = error.type();
if (ranges::contains(Api::kDefaultEditMessagesErrors, type)) {
if (ranges::contains(Api::kDefaultEditMessagesErrors, error)) {
_error = tr::lng_edit_error(tr::now);
update();
} else if (type == u"MESSAGE_NOT_MODIFIED"_q) {
} else if (error == u"MESSAGE_NOT_MODIFIED"_q) {
closeBox();
} else if (type == u"MESSAGE_EMPTY"_q) {
} else if (error == u"MESSAGE_EMPTY"_q) {
_field->setFocus();
_field->showError();
update();

View File

@@ -52,6 +52,7 @@ private:
void setupPhotoEditorEventHandler();
void setupField();
void setupControls();
void setInitialText();
void updateBoxSize();
void captionResized();

View File

@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "ui/widgets/shadow.h"
#include "ui/widgets/input_fields.h"
#include "ui/painter.h"
#include "ui/ui_utility.h"
#include "base/platform/base_platform_info.h"
#include "styles/style_boxes.h"
@@ -72,7 +73,7 @@ QCursor EditColorBox::Picker::generateCursor() {
cursor.setDevicePixelRatio(cRetinaFactor());
cursor.fill(Qt::transparent);
{
Painter p(&cursor);
auto p = QPainter(&cursor);
PainterHighQualityEnabler hq(p);
p.setBrush(Qt::NoBrush);
@@ -102,7 +103,7 @@ EditColorBox::Picker::Picker(QWidget *parent, Mode mode, QColor color)
}
void EditColorBox::Picker::paintEvent(QPaintEvent *e) {
Painter p(this);
auto p = QPainter(this);
preparePalette();
@@ -360,7 +361,7 @@ void EditColorBox::Slider::prepareMinSize() {
}
void EditColorBox::Slider::paintEvent(QPaintEvent *e) {
Painter p(this);
auto p = QPainter(this);
auto to = rect().marginsRemoved(QMargins(st::colorSliderSkip, st::colorSliderSkip, st::colorSliderSkip, st::colorSliderSkip));
Ui::Shadow::paint(p, to, width(), st::defaultRoundShadow);
if (_type == Type::Opacity) {
@@ -573,7 +574,7 @@ public:
protected:
void correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) override;
void paintAdditionalPlaceholder(Painter &p) override;
void paintAdditionalPlaceholder(QPainter &p) override;
void wheelEvent(QWheelEvent *e) override;
void keyPressEvent(QKeyEvent *e) override;
@@ -632,7 +633,7 @@ void EditColorBox::Field::correctValue(const QString &was, int wasCursor, QStrin
}
}
void EditColorBox::Field::paintAdditionalPlaceholder(Painter &p) {
void EditColorBox::Field::paintAdditionalPlaceholder(QPainter &p) {
p.setFont(_st.font);
p.setPen(_st.placeholderFg);
auto inner = QRect(_st.textMargins.right(), _st.textMargins.top(), width() - 2 * _st.textMargins.right(), height() - _st.textMargins.top() - _st.textMargins.bottom());
@@ -696,7 +697,7 @@ public:
protected:
void correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) override;
void paintAdditionalPlaceholder(Painter &p) override;
void paintAdditionalPlaceholder(QPainter &p) override;
};
@@ -737,7 +738,7 @@ void EditColorBox::ResultField::correctValue(const QString &was, int wasCursor,
}
}
void EditColorBox::ResultField::paintAdditionalPlaceholder(Painter &p) {
void EditColorBox::ResultField::paintAdditionalPlaceholder(QPainter &p) {
p.setFont(_st.font);
p.setPen(_st.placeholderFg);
p.drawText(QRect(_st.textMargins.right(), _st.textMargins.top(), width(), height() - _st.textMargins.top() - _st.textMargins.bottom()), "#", style::al_topleft);

View File

@@ -112,7 +112,7 @@ std::unique_ptr<PrivacyExceptionsBoxController::Row> PrivacyExceptionsBoxControl
} // namespace
QString EditPrivacyController::optionLabel(Option option) {
QString EditPrivacyController::optionLabel(Option option) const {
switch (option) {
case Option::Everyone: return tr::lng_edit_privacy_everyone(tr::now);
case Option::Contacts: return tr::lng_edit_privacy_contacts(tr::now);

View File

@@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "boxes/abstract_box.h"
#include "ui/layers/box_content.h"
#include "mtproto/sender.h"
#include "api/api_user_privacy.h"
@@ -38,25 +38,25 @@ public:
Never,
};
[[nodiscard]] virtual Key key() = 0;
[[nodiscard]] virtual Key key() const = 0;
[[nodiscard]] virtual rpl::producer<QString> title() = 0;
[[nodiscard]] virtual bool hasOption(Option option) {
[[nodiscard]] virtual rpl::producer<QString> title() const = 0;
[[nodiscard]] virtual bool hasOption(Option option) const {
return true;
}
[[nodiscard]] virtual rpl::producer<QString> optionsTitleKey() = 0;
[[nodiscard]] virtual QString optionLabel(Option option);
[[nodiscard]] virtual rpl::producer<TextWithEntities> warning() {
[[nodiscard]] virtual rpl::producer<QString> optionsTitleKey() const = 0;
[[nodiscard]] virtual QString optionLabel(Option option) const;
[[nodiscard]] virtual rpl::producer<TextWithEntities> warning() const {
return nullptr;
}
virtual void prepareWarningLabel(not_null<Ui::FlatLabel*> warning) {
virtual void prepareWarningLabel(not_null<Ui::FlatLabel*> warning) const {
}
[[nodiscard]] virtual rpl::producer<QString> exceptionButtonTextKey(
Exception exception) = 0;
Exception exception) const = 0;
[[nodiscard]] virtual rpl::producer<QString> exceptionBoxTitle(
Exception exception) = 0;
Exception exception) const = 0;
[[nodiscard]] virtual auto exceptionsDescription()
-> rpl::producer<QString> = 0;
const -> rpl::producer<QString> = 0;
[[nodiscard]] virtual object_ptr<Ui::RpWidget> setupAboveWidget(
not_null<QWidget*> parent,
@@ -72,7 +72,7 @@ public:
}
[[nodiscard]] virtual object_ptr<Ui::RpWidget> setupBelowWidget(
not_null<Window::SessionController*> controller,
not_null<QWidget*> parent) {
not_null<QWidget*> parent) const {
return { nullptr };
}
@@ -87,7 +87,7 @@ public:
virtual ~EditPrivacyController() = default;
protected:
EditPrivacyBox *view() const {
[[nodiscard]] EditPrivacyBox *view() const {
return _view;
}
@@ -102,7 +102,7 @@ private:
};
class EditPrivacyBox : public Ui::BoxContent {
class EditPrivacyBox final : public Ui::BoxContent {
public:
using Value = Api::UserPrivacy::Rule;
using Option = Api::UserPrivacy::Option;

View File

@@ -11,11 +11,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "chat_helpers/emoji_suggestions_widget.h"
#include "ui/layers/generic_box.h"
#include "ui/text/text_utilities.h"
#include "ui/text/text_options.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/effects/panel_animation.h"
#include "ui/filter_icons.h"
#include "ui/filter_icon_panel.h"
#include "ui/painter.h"
#include "data/data_chat_filters.h"
#include "data/data_peer.h"
#include "data/data_peer_values.h" // Data::AmPremiumValue.
@@ -82,6 +84,7 @@ private:
struct PeerButton {
not_null<History*> history;
std::shared_ptr<Data::CloudImageView> userpic;
Ui::Text::String name;
Button button;
};
@@ -208,7 +211,7 @@ int FilterChatsPreview::resizeGetHeight(int newWidth) {
for (const auto &[flag, button] : _removeFlag) {
moveNextButton(button.get());
}
for (const auto &[history, userpic, button] : _removePeer) {
for (const auto &[history, userpic, name, button] : _removePeer) {
moveNextButton(button.get());
}
return top;
@@ -240,7 +243,7 @@ void FilterChatsPreview::paintEvent(QPaintEvent *e) {
FilterChatsTypeName(flag));
top += st.height;
}
for (auto &[history, userpic, button] : _removePeer) {
for (auto &[history, userpic, name, button] : _removePeer) {
const auto savedMessages = history->peer->isSelf();
const auto repliesMessages = history->peer->isRepliesChat();
if (savedMessages || repliesMessages) {
@@ -276,7 +279,13 @@ void FilterChatsPreview::paintEvent(QPaintEvent *e) {
width(),
st.photoSize);
p.setPen(st::contactsNameFg);
history->peer->nameText().drawLeftElided(
if (name.isEmpty()) {
name.setText(
st::msgNameStyle,
history->peer->name(),
Ui::NameTextOptions());
}
name.drawLeftElided(
p,
nameLeft,
top + nameTop,

View File

@@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "ui/widgets/labels.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/painter.h"
#include "main/main_app_config.h"
#include "main/main_account.h"
#include "main/main_session.h"
@@ -99,8 +100,8 @@ private:
[[nodiscard]] int Limit(
not_null<Main::Session*> session,
const QString &key,
double fallback) {
return session->account().appConfig().get<double>(key, fallback);
int fallback) {
return session->account().appConfig().get<int>(key, fallback);
}
[[nodiscard]] int Limit(not_null<Main::Session*> session) {
@@ -125,7 +126,7 @@ QString TypeRow::generateShortName() {
PaintRoundImageCallback TypeRow::generatePaintUserpicCallback() {
const auto flag = this->flag();
return [=](Painter &p, int x, int y, int outerWidth, int size) {
return [=](QPainter &p, int x, int y, int outerWidth, int size) {
PaintFilterChatsTypeIcon(p, flag, x, y, outerWidth, size);
};
}
@@ -241,7 +242,7 @@ auto TypeController::rowSelectionChanges() const
}
void PaintFilterChatsTypeIcon(
Painter &p,
QPainter &p,
Data::ChatFilter::Flag flag,
int x,
int y,

View File

@@ -28,7 +28,7 @@ class Painter;
[[nodiscard]] QString FilterChatsTypeName(Data::ChatFilter::Flag flag);
void PaintFilterChatsTypeIcon(
Painter &p,
QPainter &p,
Data::ChatFilter::Flag flag,
int x,
int y,

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