Compare commits

...

629 Commits

Author SHA1 Message Date
John Preston 9e10a80e00 Version 4.11.3.
- Fix adding a link to media captions in scheduled / comments.
- Fix crash in link preview options saving.
- Fix possible crash in statistics.
2023-11-02 20:31:53 +04:00
John Preston 01d9864036 Workaround crash in statistics. 2023-11-02 20:30:48 +04:00
John Preston 8927a1b9a2 Fix media caption adding link in replies/scheduled. 2023-11-02 20:30:48 +04:00
John Preston b41c94be29 Fix crash in link preview edit. 2023-11-02 20:30:48 +04:00
John Preston 8ebf329cd9 Display group / channel id in profile. 2023-11-02 20:30:48 +04:00
John Preston d031046edb Version 4.11.2: Fix build with GCC. 2023-11-02 00:06:42 +04:00
John Preston 7808cc6d41 Version 4.11.2: Fix build with Xcode. 2023-11-01 22:57:36 +04:00
John Preston a7b60c43b5 Version 4.11.2.
- Highlight quoted parts in jump-to-message from replies.
- Ctrl+Click on message field reply bar to jump to message.
- Fix empty link preview displaying when generation failed.
- Fix external replies in topic groups.
- Allow enabling legacy tray icon on Windows.
2023-11-01 22:26:15 +04:00
John Preston a8b959826c Don't activate main window in case of visible call window.
Fixes #27017.
2023-11-01 22:24:09 +04:00
John Preston 42f96f3c43 Fix build with Xcode. 2023-11-01 22:24:09 +04:00
John Preston cc97093c5a Instantly jump-to-message on reply bar ctrl+click. 2023-11-01 22:13:21 +04:00
John Preston 7d5d086ade Allow messages when accepting miniapp terms. 2023-11-01 21:04:25 +04:00
John Preston 3da44eb5dd Fix attach menu suggested bot launch. 2023-11-01 21:04:25 +04:00
John Preston 4955cdcdce Wait for main menu bot icon to load. 2023-11-01 21:04:25 +04:00
23rd 597195a2e2 Replaced Session Controller with Navigation for resolving of giftcodes. 2023-11-01 17:01:25 +03:00
23rd 5966c74a27 Added ability to go to message from message preview in statistics info. 2023-11-01 17:00:26 +03:00
John Preston caa1ae4436 Fix inline bots with secondary usernames. 2023-11-01 16:39:46 +04:00
John Preston af5ad84e72 Fix crashpad_handler linking workaround.
Fixes #26873.
2023-11-01 09:27:06 +04:00
John Preston 728ed02a1c Allow selecting text in webpage previews. 2023-11-01 09:17:08 +04:00
John Preston 8e369a4aa5 Fix moved up link preview with long text. 2023-11-01 08:44:25 +04:00
John Preston 35e457c924 Fix quote create in RepliesWidget. 2023-10-31 23:41:41 +04:00
John Preston 097c3c4a5a Allow changing album quote before sending. 2023-10-31 23:25:26 +04:00
John Preston 10022a3c6d Highlight quotes in replies to file albums. 2023-10-31 23:06:21 +04:00
John Preston 0dbb195106 Highlight quotes in replies to albums. 2023-10-31 22:37:59 +04:00
23rd 6493cb9ed8 Fixed mouse wheel handling in vertical drum picker without animation. 2023-10-31 13:11:01 +03:00
John Preston 1cfda38345 Fix reply in topic after creation. 2023-10-31 13:20:30 +04:00
John Preston bf20dbe3bc Fix external replies to different topic groups. 2023-10-31 13:13:31 +04:00
John Preston 46d3f232af Don't drop reply info on empty message submit. 2023-10-31 13:08:32 +04:00
John Preston ade97fd2d2 Fix unwrapped reply to monospace. 2023-10-31 13:00:03 +04:00
John Preston 39614aab3f Fix unwrapped reply overlapping timestamp. 2023-10-31 12:59:52 +04:00
John Preston 6bab2b4df6 Improve quotes composing. 2023-10-31 12:59:32 +04:00
John Preston b4c7272351 Keep external replies in forwards. 2023-10-31 12:21:07 +04:00
John Preston d831775e2f Fix replying in the same history. 2023-10-31 11:19:57 +04:00
John Preston bde39970a0 Fix boost reassign. 2023-10-31 11:17:55 +04:00
John Preston 076291b98f Fix reply invalidation on message removal. 2023-10-31 10:53:20 +04:00
John Preston 1341907cfd Disable external replies for non-forwardable. 2023-10-31 10:50:17 +04:00
John Preston b793c06759 Fix external replies in topic groups. 2023-10-31 10:39:54 +04:00
John Preston 475b2ac739 Fix external quote-reply to topic message. 2023-10-31 09:01:20 +04:00
John Preston d1c310de00 Highlight reply quote in original message. 2023-10-31 09:01:20 +04:00
John Preston 8615a25cd1 Fix empty preview if sent while failing generating.
Fixes #27004.
2023-10-31 09:01:20 +04:00
Ilya Fedin de4eb1e59b Disable glib tests and introspection generation in snap 2023-10-31 08:16:05 +04:00
Ilya Fedin 8e8f6f905f Build newer meson in snap 2023-10-31 08:16:05 +04:00
John Preston a57eecd420 Add option to use old tray icon.
New monochrome icon is default for the new installations.

Fixes #26983, fixes #26988, fixes #26989, fixes #26991, fixes #27005.
2023-10-30 11:16:17 +04:00
John Preston f306b11676 Add id-s only when displayed in profile. 2023-10-30 10:51:11 +04:00
John Preston 745ad45d47 Version 4.11.1: Update message text padding. 2023-10-29 12:31:56 +04:00
John Preston 5fee0a7a73 Don't allow replying to local messages. 2023-10-29 12:31:56 +04:00
John Preston 096ddcad6d Version 4.11.1.
- Fix crash in emoji status select.
- Fix crash in language change.
- Suggest shrinking only photos in webpage previews.
- Fix opening video files in webpage previews in-app.
- Fix sending links and markup with customized webpage previews.
- Show "Saved Messages" as a first row when replying in another chat.
- Fix selecting words by double-click with webpage previews.
- Fix delayed webpage preview generation in preview options.
- Add "show-peer-id-below-about" experimental option.
2023-10-29 12:15:20 +04:00
John Preston 3b7448ccab Version 4.12.
- Fix crash in emoji status select.
- Fix crash in language change.
- Suggest shrinking only photos in webpage previews.
- Fix opening video files in webpage previews in-app.
- Fix sending links and markup with customized webpage previews.
- Show "Saved Messages" as a first row when replying in another chat.
- Fix selecting words by double-click with webpage previews.
- Fix delayed webpage preview generation in preview options.
- Add "show-peer-id-below-about" experimental option.
2023-10-29 11:36:06 +04:00
John Preston 478c6c4d36 Fix pending link previews in preview options box. 2023-10-29 10:57:07 +04:00
John Preston e2ea27cbef Fix select-by-words with link previews. 2023-10-29 10:25:52 +04:00
John Preston 625ae87eea Add "show-peer-id-below-about" option. 2023-10-29 10:12:48 +04:00
John Preston 597816db09 Show Saved Messages in Reply in another chat. 2023-10-29 09:52:42 +04:00
John Preston ec3fc8c749 Send entities with customized webpage preview.
Fixes #26981.
2023-10-29 08:55:30 +04:00
John Preston e64a096dca Don't suggest shrinking media of direct photo links. 2023-10-29 08:51:42 +04:00
John Preston eaf30d58be Open documents-in-web-previews in-app. 2023-10-29 08:48:45 +04:00
John Preston 94ac9f93fa Don't shrink non-photo media. 2023-10-29 07:54:39 +04:00
John Preston 04f040c9c5 Fix a crash in emoji status set. 2023-10-29 07:09:42 +04:00
John Preston af0e87c569 Fix a crash on languages box open. 2023-10-29 07:09:42 +04:00
John Preston 1a503e5f1d Version 4.11: Fix build with GCC. 2023-10-29 00:33:54 +04:00
John Preston c46b659aa5 Version 4.11.
- View full statistics in your channels and group chats.
- Choose which link preview in added to the message.
- Choose if link preview is above or below the text.
- Choose if link preview has large or small image.
- Quote parts of text in replies.
- Add quote formatting.
- Reply in another chat.
- Add nice looking code blocks with syntax highlighting.
- Copy full code block by click on its header.
- Send a highlighted code block using ```language syntax.
- Change your name color in Chat Settings.
- Customize quotes, link previews and replies to your messages.
2023-10-28 23:39:31 +04:00
John Preston 7a754f8b00 Update reply preview in scale / themes. 2023-10-28 23:12:37 +04:00
John Preston 29fb263495 Use lang-packed "copy" instead of "code". 2023-10-28 22:34:08 +04:00
John Preston c8660b5385 Improve color/emoji admin log events. 2023-10-28 22:27:30 +04:00
John Preston d47b99b0b5 Don't set box show crash annotation (GenericBox). 2023-10-28 21:51:37 +04:00
John Preston 88e3c87cd9 Crash on assertion instead of stack overflow. 2023-10-28 21:41:00 +04:00
John Preston fe0e526b79 Support phrases for unclaimed giveaway prizes. 2023-10-28 21:40:39 +04:00
John Preston c480ab1a3b Fix possible crash in non-cancelled request. 2023-10-28 21:13:52 +04:00
John Preston 49bc8ccd6a Don't gray out background emoji reset icon. 2023-10-28 20:49:20 +04:00
John Preston b180070ba3 Improve very small quote areas with icons. 2023-10-28 20:49:20 +04:00
John Preston b40f30ca98 Update Implib.so. 2023-10-28 20:29:01 +04:00
John Preston c2a1817400 Always use first color as the main one. 2023-10-28 20:19:09 +04:00
John Preston cb6698cf4a Implement background emoji selector. 2023-10-28 18:06:17 +04:00
John Preston bcdb1bdfd2 Name color changing for me / channels. 2023-10-27 23:27:10 +04:00
John Preston effc9873c9 Remove test data in giveaways. 2023-10-27 17:49:31 +04:00
John Preston 9561026cd4 Add change color button with color sample. 2023-10-27 12:26:42 +04:00
John Preston 5d335341ab Support server-side colors by index, up to three. 2023-10-27 09:55:09 +04:00
John Preston cc8408d11c Fix draft options edit, add to topics/replies. 2023-10-26 21:02:15 +04:00
John Preston a197ed9e95 Allow choosing the link for the preview. 2023-10-26 14:08:52 +04:00
John Preston 3b91e2dee4 Improve editing messages with webpage previews. 2023-10-26 14:08:44 +04:00
John Preston c035ec6917 Allow sending just webpage preview. 2023-10-26 14:08:44 +04:00
John Preston 041ec1157f Respect invert_media in service notifications. 2023-10-26 14:08:44 +04:00
John Preston 17578be4b9 Edit reply / webpage options together. 2023-10-26 14:08:43 +04:00
John Preston 1409d38ac3 Improve reply options edit design. 2023-10-26 14:08:43 +04:00
John Preston b463c76eca Allow quote selection only in captions. 2023-10-26 14:08:43 +04:00
John Preston d62fb5786d Support selecting quote in reply info edit. 2023-10-26 14:08:43 +04:00
John Preston aad157cf56 Open link on webpreview attach click. 2023-10-26 14:08:43 +04:00
John Preston 2d3e2b1ef8 Fix drafts in topics. 2023-10-26 14:08:43 +04:00
John Preston 91ab82c9da Fix unread counter in General topic. 2023-10-26 14:08:43 +04:00
John Preston 9c23de7f1a Display reply background emoji. 2023-10-26 14:08:43 +04:00
John Preston 60fb5fdaf0 Update color index caches on palette change. 2023-10-26 14:08:43 +04:00
John Preston 4709e11e46 Support two-color quote outlines. 2023-10-26 14:08:43 +04:00
John Preston 8c28ce4c99 [stats] Fix build on layer 166. 2023-10-26 14:08:43 +04:00
John Preston 20c63b98c7 Fix build with Xcode. 2023-10-26 14:08:43 +04:00
John Preston 8b42161898 Allow sending custom webpage previews. 2023-10-26 14:08:43 +04:00
John Preston b1823d981b Update API scheme, rich preview drafts. 2023-10-26 14:08:42 +04:00
John Preston b2e8e0431e Start customizable webpages. 2023-10-26 14:08:42 +04:00
John Preston 486d5b63d3 Add countries to giveaway messages. 2023-10-26 14:08:42 +04:00
John Preston 84a1fec7b1 Add flag emoji by country iso2 method. 2023-10-26 14:08:41 +04:00
John Preston 3a84c6afdd Redesign webpage/giveaway/ads bottom button. 2023-10-26 14:08:41 +04:00
John Preston 16d18b437d Update API scheme on layer 166. 2023-10-26 14:08:41 +04:00
John Preston 12fab565a4 Fix Release build with Xcode. 2023-10-26 14:08:41 +04:00
John Preston f8d5a8a203 Redesign web pages preview. 2023-10-26 14:08:41 +04:00
John Preston b9af4f3cb0 Show nice replies with quotes. 2023-10-26 14:08:41 +04:00
John Preston 4b6107fa56 Use color index from API. 2023-10-26 14:08:41 +04:00
John Preston f90a010b84 Update API scheme on layer 166. 2023-10-26 14:08:41 +04:00
John Preston ef0539c9fc Allow replying with quoting message part. 2023-10-26 14:08:41 +04:00
John Preston 00db325e91 Fix view giveaway details button in forwards. 2023-10-26 14:08:41 +04:00
John Preston d5429e769f Allow sharing gift code link. 2023-10-26 14:08:41 +04:00
John Preston 714dae054a Jump to giveaway link from gift code box. 2023-10-26 14:08:41 +04:00
John Preston 981babf302 Support giveaway information box. 2023-10-26 14:08:41 +04:00
John Preston 0926bb1288 Update API scheme on layer 166. 2023-10-26 14:08:40 +04:00
John Preston e13768ea50 Fix build with Xcode. 2023-10-26 14:08:40 +04:00
John Preston 6c19274eac Support external reply to channel posts. 2023-10-26 14:08:40 +04:00
John Preston 394883b986 Support replying to a different chat. 2023-10-26 14:08:40 +04:00
John Preston 4240568ea5 Pass FullReplyTo everywhere. 2023-10-26 14:08:40 +04:00
John Preston a77131dfd6 Add giveaway prize service message layout. 2023-10-26 14:08:40 +04:00
John Preston caca679336 Add quantity badge to giveaway message. 2023-10-26 14:08:40 +04:00
John Preston b08869abdb Support giveaway message layout. 2023-10-26 14:08:40 +04:00
John Preston d5147c9d28 Partially (italic+colored) support blockquotes. 2023-10-26 14:08:40 +04:00
John Preston 859e41f95a Use webview bots window size like on mobiles. 2023-10-26 14:08:40 +04:00
John Preston 0e45f3ebd9 Provide more theme keys to webview bots. 2023-10-26 14:08:40 +04:00
John Preston 7f9461820b Don't close webview after 'web_app_open_tg_link'. 2023-10-26 14:08:40 +04:00
John Preston e59a60b3b5 Handle new 'web_app_setup_settings_button' event. 2023-10-26 14:08:40 +04:00
John Preston 926aae6847 Update API scheme on layer 166. 2023-10-26 14:08:40 +04:00
John Preston 744c1b925e Handle GiftCode links, show Gift Link box. 2023-10-26 14:08:40 +04:00
John Preston 3fc9ed0ccb Update API scheme to layer 166. 2023-10-26 14:08:39 +04:00
John Preston 0b7d544615 Move Boost.regex definitions to cmake_helpers. 2023-10-26 14:08:39 +04:00
23rd d19baeace2 Fixed show finishing of info layers. 2023-10-26 14:08:39 +04:00
Ilya Fedin cd0f58fa65 Implement monochrome tray icon on Windows 2023-10-25 14:23:50 +04:00
John Preston 1f25301283 Beta version 4.10.5.
- Fix crash in replies to messages with spoilers.
- Enter boosts stats from three-dot menu.
2023-10-23 20:20:31 +04:00
23rd 0788f3d7b0 Increased size of arrow in chart point details widget. 2023-10-23 20:19:17 +04:00
23rd f93b7a60f8 Fixed display of button to show more boosts when boosts are too few. 2023-10-23 20:19:17 +04:00
23rd d0875a1178 Fixed sliders in footer in statistics info while restoring state. 2023-10-23 20:19:17 +04:00
23rd 29f8493a82 Removed error toast for async graphs. 2023-10-23 20:19:17 +04:00
23rd d4db838d43 Added message preview to message statistics. 2023-10-23 20:19:17 +04:00
23rd 0be2e8b672 Fixed statistics overview of old messages. 2023-10-23 20:19:17 +04:00
23rd 0aa1031402 Added ability to open message statistics from context menu. 2023-10-23 20:19:17 +04:00
23rd 53c73accd0 Fixed typo in custom shortcut for full screen in media viewer. 2023-10-23 20:19:17 +04:00
23rd be38800a70 Moved entry point for boosts statistic to channel context menu. 2023-10-23 20:19:17 +04:00
John Preston f2fa1cd70d Fix crash in non-clickable spoilers. 2023-10-23 08:59:29 +04:00
Ilya Fedin 5dfce5f7b2 Fix direct include of third-party library 2023-10-22 22:20:52 +04:00
Ilya Fedin 2b10e1e595 Update lib_base 2023-10-22 22:20:52 +04:00
Ilya Fedin eb1ef6d2a7 Fix getting the screen of viewer/pip
We need to workaround getting the actual screen for the parent by getting its position yet we need to get the setted screen for the widget itself as that's the screen used to compute the geometry
2023-10-22 22:20:52 +04:00
John Preston fde63ccb21 Beta version 4.10.4: Fix build with GCC. 2023-10-21 22:28:23 +04:00
John Preston b209683c8e Beta version 4.10.4.
- Statistics in channels and group chats.
- Nice looking code blocks with syntax highlight.
- Copy full code block by click on its header.
- Send a highlighted code block using ```language syntax.
2023-10-21 20:54:47 +04:00
23rd b6be799938 Fixed processing of error on chart zooming. 2023-10-21 11:42:04 +03:00
23rd ec8c634e9c Fixed display of arrow on point details widget when no values there. 2023-10-21 11:34:54 +03:00
23rd b7a9aa9a0e Fixed processing of empty chart on message statistic. 2023-10-21 11:34:08 +03:00
23rd 2ca489b2fb Added initial ability to save and restore state for boosts info. 2023-10-21 09:37:30 +04:00
23rd daf76c1bc2 Improved style of boosts info. 2023-10-21 09:37:30 +04:00
23rd d3aa0664a7 Moved boost limits content to divider. 2023-10-21 09:37:30 +04:00
23rd f61c22b065 Added initial boosts list to boost info. 2023-10-21 09:37:30 +04:00
23rd 8041941565 Added share label and buttons to boost info. 2023-10-21 09:37:30 +04:00
23rd 0aa1cd0b52 Removed three dots button from invite link label when menu is disabled. 2023-10-21 09:37:30 +04:00
23rd 1bbac5784b Added overview of boost info. 2023-10-21 09:37:30 +04:00
23rd f925a9e961 Added initial boosts info to layer. 2023-10-21 09:37:30 +04:00
23rd 8b6d475882 Added initial entry point for boosts statistic. 2023-10-21 09:37:30 +04:00
23rd d82c422ea1 Moved out boost limits content from boost box. 2023-10-21 09:37:30 +04:00
23rd d7e57e42d8 Added API support for boost status and boosts list. 2023-10-21 09:37:30 +04:00
23rd 7ee2ec13f0 Added Data class for boosts. 2023-10-21 09:37:30 +04:00
23rd a6e13a9f9e Added dummy layer class for boosts. 2023-10-21 09:37:30 +04:00
John Preston 66f73a5a64 Copy code blocks on header click. 2023-10-20 18:07:16 +04:00
John Preston 575684670c Improve quotes / code blocks geometries. 2023-10-20 17:59:34 +04:00
John Preston 9661bac876 Show blockquote icon. 2023-10-13 16:24:01 +04:00
John Preston 4b618a3578 Fix build with GCC. 2023-10-13 10:10:11 +04:00
John Preston 0e79bd3d12 Show nice padded code blocks. 2023-10-13 10:08:29 +04:00
John Preston dd692f2d26 Use simplified TextStyle. 2023-10-13 10:08:29 +04:00
23rd cba8387589 Fixed value types in struct data for drawing of charts. 2023-10-13 05:16:30 +03:00
23rd 01c2ade501 Fixed display of widget for point details on charts on retina. 2023-10-13 03:19:50 +03:00
23rd b9fa14139a Fixed possible wrong range of clamp in footer of chart widget. 2023-10-13 03:19:50 +03:00
23rd a8cb5419d6 Fixed available width for text in widget for details on pie charts. 2023-10-12 16:54:24 +03:00
23rd f775670938 Moved out some classes for widgets in statistical info to directory. 2023-10-12 16:51:13 +03:00
23rd c035a25aaa Added lottie icon to report box. 2023-10-12 04:42:27 +03:00
23rd 6cae088d1f Added ability to customize shortcut for full screen in media viewer. 2023-10-12 04:20:35 +03:00
23rd bee0534052 Added emoji to poll preview. 2023-10-12 03:50:59 +03:00
John Preston 3e11d44cac Closed alpha version 4.10.3.1. 2023-10-11 22:12:35 +04:00
23rd 4d269f6e97 Added animation to pie chart while changing its parts. 2023-10-11 22:12:35 +04:00
23rd e9496fb612 Improved concurrent API requests of async statistical charts. 2023-10-11 22:12:35 +04:00
23rd c9c82446cb Added support of weekly range of days to chart views. 2023-10-11 22:12:35 +04:00
23rd 0dec803177 Fixed incorrect position of sliders in chart footer in some cases. 2023-10-11 22:12:35 +04:00
23rd 2dc45ac907 Added ability to restore first public forwards in statistical info. 2023-10-11 22:12:35 +04:00
23rd a3d8db4ac0 Added ability to save state for recent posts in statistical info. 2023-10-11 22:12:35 +04:00
23rd aee6b6e224 Fixed possible crash in loading of recent posts for statistical info. 2023-10-11 22:12:35 +04:00
23rd 736efd4692 Added ability to cache loaded chart data of async graphs. 2023-10-11 22:12:34 +04:00
23rd ec5e846374 Added initial ability to save and restore state of statistical info. 2023-10-11 22:12:34 +04:00
23rd caf32cccd3 Moved out inner widget of statistical info to separate class. 2023-10-11 22:12:34 +04:00
23rd 594b2bc8f2 Improved style of recent posts in statistical info. 2023-10-11 22:12:34 +04:00
23rd d1ba270a8c Renamed file of utils for statistical lists. 2023-10-11 22:12:34 +04:00
23rd 2c1abd32bf Added list of members to statistical info of supergroups. 2023-10-11 22:12:34 +04:00
23rd 79662dffa4 Guarded cases when min and max values of charts are equal. 2023-10-11 22:12:34 +04:00
23rd a79e025151 Slightly refactored code for info of statistic for single message. 2023-10-11 22:12:34 +04:00
23rd 3fa168cee0 Added API class for requesting full statistic of single message. 2023-10-11 22:12:34 +04:00
23rd 9c1ef76e49 Added overview info to statistic for single message. 2023-10-11 22:12:34 +04:00
23rd 8497b83f7c Added list of public forwards to statistics of single message. 2023-10-11 22:12:34 +04:00
23rd 393c23ad12 Added initial ability to open statistics for single message. 2023-10-11 22:12:34 +04:00
23rd 01821cd779 Added second type of info layer for statistics. 2023-10-11 22:12:34 +04:00
23rd 3da733520d Added API support to request list of public forwards for single message. 2023-10-11 22:12:34 +04:00
23rd a605275157 Added icon to entry point for statistics. 2023-10-11 22:12:34 +04:00
23rd 8564e4d727 Added initial support of recent posts to statistical info. 2023-10-11 22:12:34 +04:00
23rd fc3acff5d6 Added support of percentages display to details widget. 2023-10-11 22:12:34 +04:00
23rd 515850ec9b Decreased height of header for charts without dates. 2023-10-11 22:12:34 +04:00
23rd 837b256778 Added support of dark theme to statistical charts. 2023-10-11 22:12:34 +04:00
23rd d16cab30d4 Fixed paint of rulers for stack chart view. 2023-10-11 22:12:34 +04:00
23rd fcdd7ecd61 Fixed paint glitch of selected bar on stack chart view. 2023-10-11 22:12:34 +04:00
23rd da9720530a Added ability to filter out lines from chart on demand from backend. 2023-10-11 22:12:34 +04:00
23rd 4a10d86a29 Fixed state losing in filter buttons on resize of statistics layer. 2023-10-11 22:12:34 +04:00
23rd 3b5a007db5 Added ability to hide footer of chart on demand from backend. 2023-10-11 22:12:34 +04:00
23rd 2479b56c3b Added ability to hide part of info on chart ruler when line is filtered. 2023-10-11 22:12:34 +04:00
23rd 0909e8bd08 Reduced line width in footer of charts. 2023-10-11 22:12:34 +04:00
23rd 6109ec70b8 Slightly improved format of dates on charts. 2023-10-11 22:12:34 +04:00
23rd c20bd17029 Moved zoom out button to right side above chart. 2023-10-11 22:12:34 +04:00
23rd 10e3115c39 Improved style of line filter buttons under charts. 2023-10-11 22:12:34 +04:00
23rd 3425b40746 Improved style of widget for details of selected points on chart. 2023-10-11 22:12:34 +04:00
23rd 42fc4fbb31 Improved style of sliders in footer from charts. 2023-10-11 22:12:34 +04:00
23rd f081917cd0 Improved style of rulers on charts in statistics. 2023-10-11 22:12:34 +04:00
23rd bdfb0ffe04 Improved style of statistic overview. 2023-10-11 22:12:34 +04:00
23rd 2b282c8d7d Improved header style for charts. 2023-10-11 22:12:33 +04:00
23rd 77d23ad182 Replaced statistics box with info layer widget. 2023-10-11 22:12:33 +04:00
23rd 79442fde97 Fixed incorrect search of index by value in statistical chart data. 2023-10-11 22:12:33 +04:00
23rd f8e80bc266 Improved limits of zoomed in slider in footer for stack linear chart. 2023-10-11 22:12:33 +04:00
23rd cb4c629178 Slightly refactored code for statistical charts. 2023-10-11 22:12:33 +04:00
23rd af0e11a1aa Moved out to td_ui all classes related to statistics. 2023-10-11 22:12:33 +04:00
23rd 8ac6aca315 Split out data for statistics and for charts. 2023-10-11 22:12:33 +04:00
23rd 2638e54181 Fixed available width for text in widget for point details on charts. 2023-10-11 22:12:33 +04:00
23rd db97db4aba Fixed crash on closing statistics with locally zoomed in chart. 2023-10-11 22:12:33 +04:00
23rd ded3f135bb Improved casting of limits for std::distance in stack linear chart view. 2023-10-11 22:12:33 +04:00
23rd be82df72e6 Fixed possible crash in stack linear chart view. 2023-10-11 22:12:33 +04:00
23rd 3fa6335b24 Added API support to request statistical graph for single message. 2023-10-11 22:12:33 +04:00
23rd 23868bf9cc Added ability to hide charts without data in statistics box. 2023-10-11 22:12:33 +04:00
23rd 5b67f4ac9b Added overview info to statistic of supergroup. 2023-10-11 22:12:33 +04:00
23rd 17fdef7d9e Added chart widgets for statistic of supergroups. 2023-10-11 22:12:33 +04:00
23rd cf82e12bf4 Added serialization from TL to statistics data for supergroups. 2023-10-11 22:12:33 +04:00
23rd 6f27aeef10 Added overview info to statistic of channels. 2023-10-11 22:12:33 +04:00
23rd df53ddf837 Added all chart widgets for statistic of channels. 2023-10-11 22:12:33 +04:00
23rd a3fd4f3fac Added label to box for statistic while loading. 2023-10-11 22:12:33 +04:00
23rd 24c0624704 Added support of default zoom to statistical charts. 2023-10-11 22:12:33 +04:00
23rd 33724be6ea Added support of theme colors for lines on statistical charts. 2023-10-11 22:12:33 +04:00
23rd 4624d34f68 Fixed display of outer points on linear chart. 2023-10-11 22:12:33 +04:00
23rd aeee016dc9 Fixed animation of line filtering in stack linear chart view. 2023-10-11 22:12:33 +04:00
23rd 8ded88baf5 Moved out control of animations for line filtering to separated class. 2023-10-11 22:12:33 +04:00
23rd bdd35a6e2b Added ability to handle mouse move to chart views. 2023-10-11 22:12:31 +04:00
23rd d9a08bb6a6 Fixed smooth paint of stack linear chart on move of footer slider. 2023-10-11 22:12:31 +04:00
23rd cee833f102 Fixed paint of selected X index in stack linear chart view. 2023-10-11 22:12:31 +04:00
23rd c19a527872 Fixed position of zoomed in slider in footer for stack linear chart. 2023-10-11 22:12:31 +04:00
23rd 6995fcafb5 Fixed mouse selection of pie chart with single part. 2023-10-11 22:12:31 +04:00
23rd b261d23645 Fixed display of zoomed days in pie chart view. 2023-10-11 22:12:31 +04:00
23rd 21c1ba7607 Fixed display of selected days in zoomed stack linear chart view. 2023-10-11 22:12:31 +04:00
23rd 5a2b8d06e3 Fixed paint of zoomed footer in stack linear chart view. 2023-10-11 22:12:31 +04:00
23rd 9046daa1a6 Fixed limit of days for zoom in stack linear chart view. 2023-10-11 22:12:31 +04:00
23rd 65ccb4059e Changed range of slider in footer from chart widget. 2023-10-11 22:12:31 +04:00
23rd d2578e9e47 Added minimal size of pie part for text on pie chart view. 2023-10-11 22:12:31 +04:00
23rd be17e2b919 Slightly refactored variables in stack linear chart view. 2023-10-11 22:12:31 +04:00
23rd 26c2e7f245 Improved round of percentages in pie chart view. 2023-10-11 22:12:31 +04:00
23rd 9051716172 Added initial support of sync zoom to chart widget. 2023-10-11 22:12:31 +04:00
23rd 71b6a58683 Added initial support of sync zoom of charts to stack linear chart view. 2023-10-11 22:12:31 +04:00
23rd 32cd454554 Moved out chart header to separated files. 2023-10-11 22:12:30 +04:00
23rd 6ffe555f6a Fixed animation processing after selecting part of pie chart. 2023-10-11 22:12:30 +04:00
23rd 7ac9ab3a51 Added support to hide chart elements with opacity from chart view. 2023-10-11 22:12:30 +04:00
23rd a9b0464726 Moved out context for chart paint to separated structure. 2023-10-11 22:12:30 +04:00
23rd e4e85e5a39 Added ability to move slider in chart widget footer from outside. 2023-10-11 22:12:30 +04:00
23rd c5f294a1ac Added paint of footer for zoomed stack linear chart. 2023-10-11 22:12:30 +04:00
23rd 5dc078a3f8 Removed selection of last enabled part on pie chart. 2023-10-11 22:12:30 +04:00
23rd 83753343cb Added details popup to selected part of pie chart. 2023-10-11 22:12:30 +04:00
23rd 42215343cf Added ability to select part of pie chart. 2023-10-11 22:12:30 +04:00
23rd bedefee1d1 Added initial appear animation of text to pie chart. 2023-10-11 22:12:30 +04:00
23rd 788eb014d4 Added ability to paint pie chart as zoomed stack linear chart. 2023-10-11 22:12:30 +04:00
23rd 13b7a07d2e Added initial transition animation to stack linear chart. 2023-10-11 22:12:30 +04:00
23rd f026271436 Added initial implementation of stack linear chart. 2023-10-11 22:12:30 +04:00
23rd d13fe39629 Added ability to paint horizontal lines for double linear charts. 2023-10-11 22:12:30 +04:00
23rd 62b3b60c45 Added initial support of double linear chart to view. 2023-10-11 22:12:30 +04:00
23rd 74313d23f3 Added new type of chart view for double linear charts. 2023-10-11 22:12:30 +04:00
23rd 646390141a Moved out paint of horizontal lines for charts to separated view class. 2023-10-11 22:12:30 +04:00
23rd 83cf12b475 Slightly reduced size of buttons in container to filter chart lines. 2023-10-11 22:12:30 +04:00
23rd a0226f9789 Added support of different chart types in chart widget. 2023-10-11 22:12:30 +04:00
23rd 54fecd497e Added icon to widget for point details on chart when zoom is enabled. 2023-10-11 22:12:30 +04:00
23rd 2106747496 Decreased size of widget for point details on chart. 2023-10-11 22:12:30 +04:00
23rd ecce9dbaaa Added ability to hide point details on chart by second click. 2023-10-11 22:12:30 +04:00
23rd b606a7b21d Added initial animation and selection to stack chart view. 2023-10-11 22:12:30 +04:00
23rd 35ff45971f Added support of async charts for main graphs. 2023-10-11 22:12:30 +04:00
23rd 7a436f32dd Moved out search of clicked index on chart to chart view. 2023-10-11 22:12:30 +04:00
23rd 54d5358b75 Fixed position of selected X in linear chart animations. 2023-10-11 22:12:30 +04:00
23rd 20c2250abb Added initial implementation of painting of stack chart. 2023-10-11 22:12:30 +04:00
23rd 2ddc1ee2e1 Implemented calculation of chart height in stack chart view. 2023-10-11 22:12:30 +04:00
23rd b55d2008c0 Added dummy class for stack chart view. 2023-10-11 22:12:30 +04:00
23rd 11b932707c Moved out calculation of height limits to abstract chart view class. 2023-10-11 22:12:30 +04:00
23rd d50aca0d33 Created abstract chart view class. 2023-10-11 22:12:30 +04:00
23rd 671e81033c Moved files of linear chart view class to directory. 2023-10-11 22:12:30 +04:00
23rd 361d269bf3 Added support of custom header in chart widget with zoomed chart. 2023-10-11 22:12:30 +04:00
23rd ae81373cff Slightly improved display management of delayed widgets in chart widget. 2023-10-11 22:12:30 +04:00
23rd 160794b26c Added support of chart titles to Data and API classes for statistics. 2023-10-11 22:12:30 +04:00
23rd 1dc57afbe1 Added some phrases for chart titles in chart widget. 2023-10-11 22:12:30 +04:00
23rd d9f397ea3f Added display of toast with potential human-readable errors from server. 2023-10-11 22:12:30 +04:00
23rd c9a976bf87 Added initial support of zooming single chart to chart widget. 2023-10-11 22:12:30 +04:00
23rd 7b921dea3b Replaced bad sizeValue with intended resizeGetHeight in chart widget. 2023-10-11 22:12:30 +04:00
23rd fcc6aaed91 Added mouse click support to point details widget. 2023-10-11 22:12:30 +04:00
23rd eb0ab9609f Added API support for request of async zoom single chart. 2023-10-11 22:12:30 +04:00
23rd bb359f6493 Fixed crash in charts with equal minimum and maximum values. 2023-10-11 22:12:30 +04:00
23rd b24be50afe Improved format of timestamp in point details widget. 2023-10-11 22:12:30 +04:00
23rd 3e55380eed Returned support of detail dots to linear chart view class. 2023-10-11 22:12:30 +04:00
23rd 25c97a3ee8 Cached both main and footer charts in single linear chart view. 2023-10-11 22:12:30 +04:00
23rd 2055cc70d1 Removed chart line view context. 2023-10-11 22:12:30 +04:00
23rd 788a81df6c Removed some duplicated code from chart line view context. 2023-10-11 22:12:30 +04:00
23rd 1209bd35c5 Replaced static function for linear chart paint with dedicated class. 2023-10-11 22:12:30 +04:00
23rd f473a1a804 Attempted to increase performance of chart paint by caching every frame. 2023-10-11 22:12:30 +04:00
23rd c8e95f7297 Improved y-axis animation again to look much better. 2023-10-11 22:12:30 +04:00
23rd b1ed8cd1b1 Fixed bug of display for y-axis captions with instant delivered data. 2023-10-11 22:12:30 +04:00
23rd 64bb818fe9 Added initial display of footer while chart lines are filtering. 2023-10-11 22:12:29 +04:00
23rd ee172d951d Added support to hide name and value of line in PointDetailsWidget. 2023-10-11 22:12:29 +04:00
23rd 41bc47eb6f Faded out detail dot of filtered chart line. 2023-10-11 22:12:29 +04:00
23rd 423d2293f9 Kept point details widget while chart lines are filtering. 2023-10-11 22:12:29 +04:00
23rd e6559276c0 Added class to calculate context state while chart lines are filtering. 2023-10-11 22:12:29 +04:00
23rd 13959ca36c Added buttons container to filter chart line to chart widget. 2023-10-11 22:12:29 +04:00
23rd 520989a7e6 Added initial ability to filter chart lines. 2023-10-11 22:12:29 +04:00
23rd 4c02d19a51 Added implementation of buttons container to filter chart lines. 2023-10-11 22:12:29 +04:00
23rd 734e1166ad Removed from display point details widget with invalid index. 2023-10-11 22:12:29 +04:00
23rd 94fd3e32dd Added own value of height for chart widget. 2023-10-11 22:12:29 +04:00
23rd 367adaa44d Attempted to increase performance when paint complicated charts. 2023-10-11 22:12:29 +04:00
23rd 73b4621121 Cached current x-axis indices to reduce redundant calculations. 2023-10-11 22:12:29 +04:00
23rd 8256a4c686 Completely replaced widgets in footer with nice path paint. 2023-10-11 22:12:29 +04:00
23rd b6b6673214 Initially replaced buttons in footer with cached arrows. 2023-10-11 22:12:29 +04:00
23rd 8ba2e95e6c Added paint of inactive area in footer in chart widget. 2023-10-11 22:12:29 +04:00
23rd 40ab042fb5 Added support of very large values in PointDetailsWidget. 2023-10-11 22:12:29 +04:00
23rd 25f401c22e Changed color of axis captions to grey. 2023-10-11 22:12:29 +04:00
23rd d8566f770f Removed chart paint below bottom line in chart widget. 2023-10-11 22:12:29 +04:00
23rd f76f69b5cd Moved out details dots above horizontal line captions. 2023-10-11 22:12:29 +04:00
23rd 487dd27ca1 Added padding to y-axis captions in chart widget. 2023-10-11 22:12:29 +04:00
23rd 32df03f08d Fixed text overlap on y-axis captions when mouse drag is really fast. 2023-10-11 22:12:29 +04:00
23rd 658db59aaf Replace Simple with Basic for animation of chart y-axis captions. 2023-10-11 22:12:29 +04:00
23rd 695542cfd2 Added initial animation of chart y-axis captions. 2023-10-11 22:12:29 +04:00
23rd 07cd35b1a8 Added fade animation to details widget on charts. 2023-10-11 22:12:29 +04:00
23rd 74aae29b64 Added point details widget to chart widget. 2023-10-11 22:12:29 +04:00
23rd 70713d5f62 Moved paint of chart to inner widget within chart widget. 2023-10-11 22:12:29 +04:00
23rd dd1b006d8a Created RpMouseWidget class for easier mouse processing. 2023-10-11 22:12:29 +04:00
23rd ec8d604db7 Added initial widget implementation of point details in charts. 2023-10-11 22:12:29 +04:00
23rd 9e8d60065b Slightly improved code style in PaintLinearChartView. 2023-10-11 22:12:29 +04:00
23rd d603f4de51 Reduced redundant calculations of animation in chart widget. 2023-10-11 22:12:29 +04:00
23rd 77695091b3 Slightly clarified name of y-axis animation in chart widget. 2023-10-11 22:12:29 +04:00
23rd 20e81177a6 Fixed first show of chart widget with new data. 2023-10-11 22:12:29 +04:00
23rd ce3ad95950 Removed useless processing for changing drag direction. 2023-10-11 22:12:29 +04:00
23rd c5684e768a Slightly optimized footer in chart widget. 2023-10-11 22:12:29 +04:00
23rd c8d5a60c74 Moved out processing of chart animation to separate class. 2023-10-11 22:12:29 +04:00
23rd 4dad0a215a Removed some unused data chart widget. 2023-10-11 22:12:29 +04:00
23rd 15698fd6f0 Tried to fix animation bug when mouse drag is really fast. 2023-10-11 22:12:29 +04:00
23rd cd4654dfd2 Tried to fix some bugs with alpha of horizontal lines in chart widget. 2023-10-11 22:12:29 +04:00
23rd 3a3d4480cc Added acceleration to y-axis animation in chart widget. 2023-10-11 22:12:29 +04:00
23rd 5c3748db56 Added tools to test animation for left and right edges with same speed. 2023-10-11 22:12:29 +04:00
23rd 7dfdcc7be0 Added some work in progress to improve horizontal line animation. 2023-10-11 22:12:29 +04:00
23rd d1f2950167 Added initial animation of horizontal lines in chart widget.
The animation is only top-down for now.
2023-10-11 22:12:29 +04:00
23rd 59f61586a9 Improved code style in chart widget. 2023-10-11 22:12:29 +04:00
23rd 629dd6f9de Added dirty implementation of chart animation with both axes. 2023-10-11 22:12:29 +04:00
23rd f4fc8ec2c4 Added initial chart y-axis animation without x-axis. 2023-10-11 22:12:29 +04:00
23rd e8aa55d4d8 Added initial support of static zoom for chart widget. 2023-10-11 22:12:29 +04:00
23rd 26b17325aa Added initial implementation of footer in statistic chart widget. 2023-10-11 22:12:29 +04:00
23rd c71f35778d Added API support of channel flag for channel statistics. 2023-10-11 22:12:29 +04:00
23rd c9eb9a3ee0 Added initial widget with full zoom static linear chart. 2023-10-11 22:12:29 +04:00
23rd 06948ad15e Added Data class for horizontal lines on statistic charts. 2023-10-11 22:12:29 +04:00
23rd 029e0c9488 Added deserialization from JSON to statistics data to API. 2023-10-11 22:12:29 +04:00
23rd c0219cb95d Added deserialization from JSON to statistics data. 2023-10-11 22:12:29 +04:00
23rd 78e553b724 Added usage of segment tree in Data class for statistics. 2023-10-11 22:12:28 +04:00
23rd b5b70beea0 Added implementation of class for segment tree. 2023-10-11 22:12:28 +04:00
23rd 177a7eaf43 Added initial serialization from TL data to statistics data. 2023-10-11 22:12:28 +04:00
23rd ca863bfb5b Added dummy Data class for statistics. 2023-10-11 22:12:28 +04:00
23rd c45025c6e5 Added dummy API class for statistics. 2023-10-11 22:12:28 +04:00
23rd 10968d0da2 Added dummy box class for statistics. 2023-10-11 22:12:28 +04:00
23rd b0a65885c9 Added initial entry point for channel statistics. 2023-10-11 22:12:28 +04:00
John Preston ad8f8513c3 Link crashpad_handler with Xcode bug workaround. 2023-10-11 22:12:28 +04:00
23rd f457a9d109 Added ability to fast change forward options with right click on panel. 2023-10-11 21:10:56 +03:00
Ilya Fedin 830fb3ccc2 Update submodules 2023-10-11 21:54:42 +04:00
Ilya Fedin 9116328f29 Update to Qt 6.6.0 release on Linux 2023-10-11 21:54:42 +04:00
John Preston aa7575dec4 Highlight more languages. 2023-10-11 08:45:50 +04:00
John Preston bfe272e39f Fix highlighting of the closing bracket. 2023-10-11 08:45:50 +04:00
23rd a7ca15657b Fixed master branch updater Github Action. 2023-10-11 06:06:03 +03:00
23rd 41dada2c06 Fixed shadows in userpic builder with non-default scale. 2023-10-11 06:06:03 +03:00
John Preston 501784cd15 Attempt to fix Snap build. 2023-10-08 07:02:40 +04:00
Ilya Fedin ac699ccf80 Update submodules 2023-10-07 07:08:21 +04:00
Ilya Fedin aadaf47569 Add boost-regex to snap 2023-10-07 07:08:21 +04:00
Ilya Fedin 6bc0179919 Work with GLIB_VERSION_MAX_ALLOWED 2023-10-07 07:08:21 +04:00
Ilya Fedin 93fbad50bc Downgrade qtwayland to 6.5.3 2023-10-07 07:08:21 +04:00
Ilya Fedin a5ec616382 Downgrade qtsvg to 6.5.3 in snap
As a better crash workaround
2023-10-07 07:08:21 +04:00
John Preston bf3f474195 Fix label position in peer editing. 2023-10-06 17:49:34 +04:00
John Preston 14f68c2f33 Fix webview on Windows & macOS. 2023-10-06 17:49:34 +04:00
John Preston 92fadd2652 Fix build with GCC 12. 2023-10-06 16:28:45 +04:00
John Preston b68a7c7f04 Update submodules. 2023-10-06 09:03:28 +04:00
John Preston 50097e1a81 Show spellcheck suggestions on Ctrl+Space.
Fixes #26892.
2023-10-05 10:36:30 +04:00
John Preston 2414e927bd Add initial code syntax highlighting.
Thanks PrismJS and Fela for porting it to C++.
2023-10-04 22:29:16 +04:00
John Preston da768ac1d1 Add libprisma from Fela for syntax highlighting. 2023-10-04 22:28:47 +04:00
John Preston 396c229a4d Improve Ui::Text::String features. 2023-10-04 22:24:25 +04:00
23rd 2b3f17e982 Removed call button from history with service user. 2023-10-04 20:38:14 +04:00
John Preston 5ef48cac9c Use shared_ptr<Factory> as settings section id. 2023-10-04 20:38:14 +04:00
John Preston 6ba922d7b0 Fix channel stories open from chats list. 2023-10-04 20:38:14 +04:00
Ilya Fedin f881192dd0 Don't enter settings after update 2023-10-04 12:10:33 +04:00
Ilya Fedin ef2a0bb05e Add libnvidia-egl-wayland1 to snap 2023-10-04 12:10:19 +04:00
Ilya Fedin 54efa2353e Update submodules 2023-10-04 12:07:36 +04:00
Ilya Fedin 2878533078 Re-throw original exception in Linux notification's StartServiceAsync 2023-10-04 12:07:36 +04:00
Sergey A. Osokin ac520b314d Fix build on FreeBSD 2023-10-02 18:47:10 +04:00
John Preston 871fef2c4a Version 4.10.3.
- Fix crash on external link opening. (Linux only)
2023-10-02 17:56:10 +04:00
John Preston 99f4b93745 Attempt to fix build with Clang on Linux. 2023-10-02 17:56:10 +04:00
Ilya Fedin a757e07c3a Line length clean up in notifications_manager_linux 2023-10-02 16:11:02 +04:00
Ilya Fedin 5c4f006550 Avoid Windows-specific hack to ruin initial main window geometry on Linux 2023-10-02 07:05:21 +04:00
John Preston 9ad38b9638 Update lib_base submodule. 2023-10-01 21:54:44 +04:00
Ilya Fedin fe8ebc1659 Update patches on Linux 2023-10-01 07:25:58 +04:00
Ilya Fedin a732d8f5e7 Disable vfork in Qt on Linux 2023-10-01 07:25:58 +04:00
Ilya Fedin 7ddcc47fcd Make UnsafeShowOpenWith inline on Linux 2023-10-01 06:54:39 +04:00
Ilya Fedin 70f22293cf Get rid of last non-standard piece in Linux FileDialog getter 2023-10-01 06:54:39 +04:00
John Preston 90fb59348c Try fixing Docker action. 2023-09-29 20:38:21 +04:00
John Preston daf545a72a Version 4.10.2: Try fixing Snap action. 2023-09-29 19:29:53 +04:00
John Preston 771869e945 Version 4.10.2: Fix build with GCC. 2023-09-29 09:36:10 +04:00
John Preston ac1fe2cfee Update submodules. 2023-09-29 09:04:43 +04:00
John Preston ed064ee13c Version 4.10.2.
- Bug fixes and other minor improvements.
2023-09-29 00:15:19 +04:00
John Preston 9fcdec4166 Update libvpx revision. 2023-09-29 00:15:19 +04:00
John Preston bd4cf82405 Don't highlight links in non-premium stories. 2023-09-28 23:51:30 +04:00
John Preston 3653a6f011 Improve confirm box text padding. 2023-09-28 23:51:30 +04:00
John Preston adc6930ac6 Skip irrelevant message on changelog story hiding. 2023-09-28 23:51:30 +04:00
John Preston 7305d542ba Fix possible crash in message context menu. 2023-09-28 23:51:30 +04:00
John Preston 874c84ad4e Fix file reference refresh in story forward. 2023-09-28 23:51:29 +04:00
John Preston 4edb11f128 Show channel stories in chats list. 2023-09-28 23:51:29 +04:00
John Preston 785014f7b7 Extract premium layer top bar widget. 2023-09-28 23:51:29 +04:00
John Preston 4cb5bea69b Update API scheme to layer 165. 2023-09-28 23:51:29 +04:00
Ilya Fedin 07bc84d425 Update submodules 2023-09-27 10:32:24 +04:00
Ilya Fedin 9019a2cb08 Remove an unneeded intermediate variable 2023-09-27 10:32:24 +04:00
Ilya Fedin 716cc6ef9e Workaround a crash in snap 2023-09-27 10:32:24 +04:00
Ilya Fedin a509be99b0 Update Qt to 6.6.0-rc1 on Linux 2023-09-26 14:12:26 +04:00
Ilya Fedin 618ce15b21 Revert "Workaround Wayland popup menu bug."
This reverts commit 51027a0bc2.
2023-09-26 12:26:18 +04:00
Ilya Fedin d2b5651c3b Patch Qt for better open url UX on Linux 2023-09-26 12:22:24 +04:00
Ilya Fedin 51ff484913 Update Qt to 6.6.0-beta4 on Linux 2023-09-26 12:15:33 +04:00
John Preston 547a5a14df Correct stories count in the Info title. 2023-09-26 12:12:43 +04:00
John Preston 5179d9a03f Workaround Xcode 15 linker bugs with -Wl,-ld_classic. 2023-09-25 21:37:34 +04:00
John Preston 26e84dbab2 Fix drag starting item. 2023-09-25 21:37:00 +04:00
John Preston 013c8ebeb4 Allow reactions for changelog stories. 2023-09-25 21:36:51 +04:00
John Preston 846e96579d Fix direct story links for channels. 2023-09-25 17:53:02 +04:00
John Preston eaa491518e Remove changelog stories on archive attempt. 2023-09-25 17:39:18 +04:00
John Preston 4df7761e9d Allow deleting selected messages by backspace. 2023-09-25 12:55:29 +04:00
John Preston 6cdc8f9dbc Fix libvpx pkg-config generation on Windows.
Fixes #26849.
2023-09-25 12:41:34 +04:00
John Preston 95e4abd784 Extract system-specific parts of prepare env. 2023-09-25 12:41:34 +04:00
John Preston 6f9a540a61 Fix crash when libvpx decoder is absent.
Fixes #26849.
2023-09-25 12:41:34 +04:00
John Preston 137fca73bd Fix premium counter bubble with disabled animations. 2023-09-25 12:41:34 +04:00
John Preston 2159307643 Accept https://t.me/boost/channelusername links. 2023-09-25 12:41:34 +04:00
23rd ded570a480 Fixed display of bulk download menu item on restricted content. 2023-09-25 06:27:08 +03:00
John Preston 4fd68d97d5 Merge remote-tracking branch into dev 2023-09-23 21:24:20 +04:00
John Preston edfe998811 Fix build of minidump_stackwalk. 2023-09-23 21:23:51 +04:00
John Preston 116ae04f54 Add missing OpenGL resource deinitialization in viewer 2023-09-23 20:38:10 +04:00
Ilya Fedin ce8e42bcc2 Support Wayland display reconnection 2023-09-23 20:38:10 +04:00
John Preston ea9386f0aa Version 4.10.1: Rebuild macOS with older Xcode. 2023-09-23 19:25:24 +04:00
Ilya Fedin 58451aed91 Fix debug build on Linux 2023-09-23 06:29:10 +04:00
John Preston a6df03d990 Version 4.10: Fix channel stories phrases. 2023-09-22 20:59:37 +04:00
John Preston 16b1881268 Version 4.10: Fix spawning args on Linux. 2023-09-22 20:16:22 +04:00
John Preston 0d25b154d9 Version 4.10.
- Stories for Channels.
- Reaction Stickers in Stories.
2023-09-22 18:12:35 +04:00
John Preston 89fac88677 Beta version 4.9.10: Fix after-update relaunch. 2023-09-22 16:08:41 +04:00
John Preston 9604a3bd80 Beta version 4.9.10: Remove legacy checks. 2023-09-22 11:51:47 +04:00
John Preston 5b3ffc778d Merge remote-tracking branch 'origin/dev' into dev 2023-09-22 11:50:47 +04:00
John Preston c6c06c149d Check AppUserModelId better. 2023-09-22 11:50:41 +04:00
John Preston a37f7077b0 Beta version 4.9.10: Fix build with GCC. 2023-09-22 11:06:03 +04:00
John Preston 5514ab0ccf Fix warnings after Xcode 15 / target 10.13 update. 2023-09-22 11:01:46 +04:00
John Preston 63a753d35c Beta version 4.9.10.
- Update Qt to 6.2.5 on macOS.
- Update minimum target to macOS 10.13 and toolchain to Xcode 15.
- Update Linux build host from CentOS 7 to Rocky Linux 8.
- Update Linux toolchain to GCC 12.
2023-09-22 09:43:32 +04:00
John Preston 4e82b7973f Suppress warning in libtgvoip json11. 2023-09-22 09:43:32 +04:00
John Preston 09094affed Improve boosted channel replacement design. 2023-09-22 09:43:32 +04:00
John Preston c5634580f6 Add view button to channel boost link previews. 2023-09-22 09:43:32 +04:00
John Preston 7828a92f08 Implement views/reactions polling in channels. 2023-09-22 09:43:32 +04:00
John Preston e60e65f574 Toggle suggested reaction counter animated. 2023-09-22 09:43:32 +04:00
John Preston 7a25d70240 Support all cases for BoostBox. 2023-09-22 09:43:32 +04:00
John Preston 01428572b0 Add shadow for white suggested reactions. 2023-09-22 09:43:32 +04:00
John Preston a43a5ce6c5 Improve reaction selector position. 2023-09-22 09:43:32 +04:00
John Preston d4ba01bad0 Suggested reaction effect around the widget. 2023-09-22 09:43:32 +04:00
John Preston 5d5cae7860 Implement suggested reaction count. 2023-09-22 09:43:32 +04:00
John Preston f3db7e636b Implement channel stories views / reactions. 2023-09-22 09:43:32 +04:00
John Preston 1c2951598b Handle t.me/channel?boost links. 2023-09-22 09:43:32 +04:00
John Preston 39f8394f98 Enable story actions in channels. 2023-09-22 09:43:31 +04:00
John Preston 29c5f6b706 Support channel stories archive. 2023-09-22 09:43:31 +04:00
John Preston b2c9a92c3e Hide reply field in channel stories. 2023-09-22 09:43:31 +04:00
John Preston f3647d7f8c Show saved stories / current stories in channels. 2023-09-22 09:43:31 +04:00
John Preston f3e65181cd Initial suggested reaction implementation. 2023-09-22 09:43:31 +04:00
John Preston d5b429e910 Update API scheme to layer 164. 2023-09-22 09:43:31 +04:00
Ilya Fedin 1bde096417 Minimize amount of code to rebuild when switching options 2023-09-22 09:14:01 +04:00
John Preston 3db0b11a6b Bump minimum macOS deployment target to 10.13. 2023-09-22 09:03:12 +04:00
John Preston 8d00d93949 Fix uninitialized warning in build with GCC. 2023-09-22 09:03:00 +04:00
Ilya Fedin 277fe540dc Update Qt to 6.2.5 on macOS 2023-09-22 08:49:53 +04:00
Ilya Fedin 1683dccb50 Always set AppUserModelID on Windows 2023-09-21 13:39:26 +04:00
Ilya Fedin 47195e316f Don't load SetCurrentProcessExplicitAppUserModelID dynamically
It's supported since Windows 7
2023-09-21 13:39:26 +04:00
Ilya Fedin 8c9014fcf6 Update all third party submodules 2023-09-21 12:53:07 +04:00
Ilya Fedin 2d7675ace0 Update all dependencies in snap 2023-09-21 12:53:07 +04:00
Ilya Fedin 61cc7efc2a Update all dependencies in Dockerfile 2023-09-21 12:53:07 +04:00
Ilya Fedin 0464a558f0 Add Qt window frame string for Wayland 2023-09-21 12:49:45 +04:00
Ilya Fedin ff9321e971 Main thread deadlock detector for debug mode 2023-09-21 12:23:23 +04:00
John Preston d10b7e8402 Update tg_owt+libyuv/libvpx to chromium revisions. 2023-09-21 11:10:44 +04:00
Ilya Fedin 71f3f67fe3 Update submodules & patches on Linux 2023-09-21 10:30:09 +04:00
Ilya Fedin 47983d59fb Use -fno-omit-frame-pointer for better backtraces 2023-09-20 22:32:35 +04:00
Ilya Fedin df29af5aea CentOS 7 -> Rocky Linux 8 2023-09-20 22:32:35 +04:00
Ilya Fedin 27b443b24d Use QStandardPaths to find the externalupdater config
That should be more convenient for everyone and cross-platform...
2023-09-20 18:05:45 +04:00
Ilya Fedin 7b4a542890 Always wait for updater to exit on Linux 2023-09-20 18:05:45 +04:00
Ilya Fedin db6c69fa5f Move writeprotected to global updater variables on Linux 2023-09-20 18:05:45 +04:00
Ilya Fedin 7dfeea3f4e Get rid of workingDirChosen variable
It's set in every codepath where cWorkingDir is non-empty.
2023-09-20 18:05:45 +04:00
Ilya Fedin 92a41c881d Consolidate cForceWorkingDir(psAppDataPath()) 2023-09-20 18:05:45 +04:00
Ilya Fedin 3d769a6dce Get rid of cForceWorkingDir(cWorkingDir())
It has no sense as no code sets working directory directly to the variable anymore.
2023-09-20 18:05:45 +04:00
Ilya Fedin 330dfaa4d9 Consolidate MoveOldDataFiles path determinition 2023-09-20 18:05:45 +04:00
Ilya Fedin b35fff01b0 Restore initial working directory on restart
So executable path computation still works for the new instance on systems deducing it by argv0
2023-09-20 18:05:45 +04:00
Ilya Fedin cc19928977 Fix logging initial working directory when TelegramForcePortable exists 2023-09-20 18:05:45 +04:00
Ilya Fedin c5424d0a9a Get rid of unneeded `+ '/'` for cForceWorkingDir
It does the same on its own
2023-09-20 18:05:45 +04:00
Ilya Fedin f3572e52ac Don't create a QDir instance for its static setCurrent method 2023-09-20 18:05:45 +04:00
Ilya Fedin 949c486cac Use a higher-level API for restarts/updates on Linux
This gets rid of the custom arguments container
2023-09-20 18:05:45 +04:00
Ilya Fedin 082b5ba782 Get rid of sandboxed paths workaround
This is fixed in xdg-desktop-portal 1.17.

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

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

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

View File

@ -30,7 +30,7 @@ jobs:
curl -sSL https://install.python-poetry.org | python3 -
- name: Free up some disk space.
uses: jlumbroso/free-disk-space@76866dbe54312617f00798d1762df7f43def6e5c
uses: jlumbroso/free-disk-space@f68fdb76e2ea636224182cfb7377ff9a1708f9b8
- name: Docker image build.
run: |

View File

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

View File

@ -11,7 +11,9 @@ jobs:
SKIP: "0"
to_branch: "master"
steps:
- uses: actions/checkout@v3.1.0
- uses: actions/checkout@v4.1.0
with:
fetch-depth: 0
if: env.SKIP == '0'
- name: Push the code to the master branch.
if: env.SKIP == '0'

View File

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

View File

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

6
.gitmodules vendored
View File

@ -58,9 +58,6 @@
[submodule "Telegram/ThirdParty/range-v3"]
path = Telegram/ThirdParty/range-v3
url = https://github.com/ericniebler/range-v3.git
[submodule "Telegram/ThirdParty/fcitx-qt5"]
path = Telegram/ThirdParty/fcitx-qt5
url = https://github.com/fcitx/fcitx-qt5.git
[submodule "Telegram/ThirdParty/nimf"]
path = Telegram/ThirdParty/nimf
url = https://github.com/hamonikr/nimf.git
@ -103,3 +100,6 @@
[submodule "Telegram/ThirdParty/wayland"]
path = Telegram/ThirdParty/wayland
url = https://github.com/gitlab-freedesktop-mirrors/wayland.git
[submodule "Telegram/ThirdParty/libprisma"]
path = Telegram/ThirdParty/libprisma
url = https://github.com/desktop-app/libprisma.git

View File

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

View File

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

View File

@ -28,6 +28,7 @@ include(cmake/lib_ffmpeg.cmake)
include(cmake/lib_stripe.cmake)
include(cmake/lib_tgvoip.cmake)
include(cmake/lib_tgcalls.cmake)
include(cmake/lib_prisma.cmake)
include(cmake/td_export.cmake)
include(cmake/td_mtproto.cmake)
include(cmake/td_lang.cmake)
@ -151,6 +152,8 @@ PRIVATE
api/api_sensitive_content.h
api/api_single_message_search.cpp
api/api_single_message_search.h
api/api_statistics.cpp
api/api_statistics.h
api/api_text_entities.cpp
api/api_text_entities.h
api/api_toggling_media.cpp
@ -195,6 +198,8 @@ PRIVATE
boxes/peers/edit_participant_box.h
boxes/peers/edit_participants_box.cpp
boxes/peers/edit_participants_box.h
boxes/peers/edit_peer_color_box.cpp
boxes/peers/edit_peer_color_box.h
boxes/peers/edit_peer_common.h
boxes/peers/edit_peer_info_box.cpp
boxes/peers/edit_peer_info_box.h
@ -413,6 +418,7 @@ PRIVATE
core/crash_report_window.h
core/crash_reports.cpp
core/crash_reports.h
core/deadlock_detector.h
core/file_utilities.cpp
core/file_utilities.h
core/launcher.cpp
@ -449,6 +455,7 @@ PRIVATE
data/data_audio_msg_id.h
data/data_auto_download.cpp
data/data_auto_download.h
data/data_boosts.h
data/data_bot_app.cpp
data/data_bot_app.h
data/data_chat.cpp
@ -551,6 +558,7 @@ PRIVATE
data/data_sparse_ids.h
data/data_sponsored_messages.cpp
data/data_sponsored_messages.h
data/data_statistics.h
data/data_stories.cpp
data/data_stories.h
data/data_stories_ids.cpp
@ -645,6 +653,8 @@ PRIVATE
history/view/controls/history_view_compose_controls.h
history/view/controls/history_view_compose_search.cpp
history/view/controls/history_view_compose_search.h
history/view/controls/history_view_draft_options.cpp
history/view/controls/history_view_draft_options.h
history/view/controls/history_view_forward_panel.cpp
history/view/controls/history_view_forward_panel.h
history/view/controls/history_view_ttl_button.cpp
@ -653,6 +663,8 @@ 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/controls/history_view_webpage_processor.cpp
history/view/controls/history_view_webpage_processor.h
history/view/media/history_view_call.cpp
history/view/media/history_view_call.h
history/view/media/history_view_contact.cpp
@ -671,6 +683,8 @@ PRIVATE
history/view/media/history_view_game.h
history/view/media/history_view_gif.cpp
history/view/media/history_view_gif.h
history/view/media/history_view_giveaway.cpp
history/view/media/history_view_giveaway.h
history/view/media/history_view_invoice.cpp
history/view/media/history_view_invoice.h
history/view/media/history_view_large_emoji.cpp
@ -810,20 +824,10 @@ PRIVATE
history/history_view_highlight_manager.h
history/history_widget.cpp
history/history_widget.h
info/info_content_widget.cpp
info/info_content_widget.h
info/info_controller.cpp
info/info_controller.h
info/info_layer_widget.cpp
info/info_layer_widget.h
info/info_memento.cpp
info/info_memento.h
info/info_section_widget.cpp
info/info_section_widget.h
info/info_top_bar.cpp
info/info_top_bar.h
info/info_wrap_widget.cpp
info/info_wrap_widget.h
info/boosts/info_boosts_inner_widget.cpp
info/boosts/info_boosts_inner_widget.h
info/boosts/info_boosts_widget.cpp
info/boosts/info_boosts_widget.h
info/common_groups/info_common_groups_inner_widget.cpp
info/common_groups/info_common_groups_inner_widget.h
info/common_groups/info_common_groups_widget.cpp
@ -879,6 +883,15 @@ PRIVATE
info/profile/info_profile_widget.h
info/settings/info_settings_widget.cpp
info/settings/info_settings_widget.h
info/statistics/info_statistics_common.h
info/statistics/info_statistics_inner_widget.cpp
info/statistics/info_statistics_inner_widget.h
info/statistics/info_statistics_list_controllers.cpp
info/statistics/info_statistics_list_controllers.h
info/statistics/info_statistics_recent_message.cpp
info/statistics/info_statistics_recent_message.h
info/statistics/info_statistics_widget.cpp
info/statistics/info_statistics_widget.h
info/stories/info_stories_inner_widget.cpp
info/stories/info_stories_inner_widget.h
info/stories/info_stories_provider.cpp
@ -897,6 +910,20 @@ PRIVATE
info/userpic/info_userpic_emoji_builder_preview.h
info/userpic/info_userpic_emoji_builder_widget.cpp
info/userpic/info_userpic_emoji_builder_widget.h
info/info_content_widget.cpp
info/info_content_widget.h
info/info_controller.cpp
info/info_controller.h
info/info_layer_widget.cpp
info/info_layer_widget.h
info/info_memento.cpp
info/info_memento.h
info/info_section_widget.cpp
info/info_section_widget.h
info/info_top_bar.cpp
info/info_top_bar.h
info/info_wrap_widget.cpp
info/info_wrap_widget.h
inline_bots/bot_attach_web_view.cpp
inline_bots/bot_attach_web_view.h
inline_bots/inline_bot_layout_internal.cpp
@ -1261,6 +1288,8 @@ PRIVATE
settings/settings_main.h
settings/settings_notifications.cpp
settings/settings_notifications.h
settings/settings_notifications_type.cpp
settings/settings_notifications_type.h
settings/settings_power_saving.cpp
settings/settings_power_saving.h
settings/settings_premium.cpp
@ -1472,6 +1501,7 @@ PRIVATE
qrc/emoji_5.qrc
qrc/emoji_6.qrc
qrc/emoji_7.qrc
qrc/emoji_8.qrc
qrc/emoji_preview.qrc
qrc/telegram/animations.qrc
qrc/telegram/export.qrc
@ -1535,6 +1565,7 @@ elseif (APPLE)
PRE_LINK
COMMAND mkdir -p $<TARGET_FILE_DIR:Telegram>/../Resources
COMMAND cp ${CMAKE_BINARY_DIR}/lib_ui.rcc $<TARGET_FILE_DIR:Telegram>/../Resources
COMMAND cp ${CMAKE_BINARY_DIR}/lib_spellcheck.rcc $<TARGET_FILE_DIR:Telegram>/../Resources
)
if (NOT build_macstore)
add_custom_command(TARGET Telegram

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 821 KiB

After

Width:  |  Height:  |  Size: 832 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1017 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 B

View File

@ -129,6 +129,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_reconnecting#other" = "Reconnect in {count} s...";
"lng_reconnecting_try_now" = "Try now";
"lng_code_block_header_copy" = "copy";
"lng_status_service_notifications" = "service notifications";
"lng_status_support" = "support";
"lng_status_bot" = "bot";
@ -402,6 +404,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_dlg_search_from" = "From: {user}";
"lng_settings_save" = "Save";
"lng_settings_apply" = "Apply";
"lng_username_title" = "Username";
"lng_username_description1" = "You can choose a username on Telegram. If you do, other people will be able to find you by this username and contact you without knowing your phone number.";
@ -451,6 +454,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_show_from" = "Show notifications from";
"lng_settings_notify_all" = "All accounts";
"lng_settings_notify_all_about" = "Turn this off if you want to receive notifications only from the account you are currently using.";
"lng_settings_notify_global" = "Global settings";
"lng_settings_notify_title" = "Notifications for chats";
"lng_settings_desktop_notify" = "Desktop notifications";
"lng_settings_native_title" = "Native notifications";
@ -458,8 +462,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_use_native_notifications" = "Use native notifications";
"lng_settings_notifications_position" = "Location on the screen";
"lng_settings_notifications_count" = "Notifications count";
"lng_settings_sound_notify" = "Play sound";
"lng_settings_sound_notify_off" = "Off";
"lng_settings_sound_allowed" = "Allow sound";
"lng_settings_alert_windows" = "Flash the taskbar icon";
"lng_settings_alert_mac" = "Bounce the dock icon";
"lng_settings_alert_linux" = "Draw attention to the window";
@ -480,6 +483,36 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_notification_hide_all" = "Hide all";
"lng_notification_sample" = "This is a sample notification";
"lng_notification_reminder" = "Reminder";
"lng_notification_private_chats" = "Private chats";
"lng_notification_groups" = "Groups";
"lng_notification_channels" = "Channels";
"lng_notification_click_to_change" = "Click here to change";
"lng_notification_on" = "On, {exceptions}";
"lng_notification_off" = "Off, {exceptions}";
"lng_notification_exceptions#one" = "{count} exception";
"lng_notification_exceptions#other" = "{count} exceptions";
"lng_notification_exceptions_title" = "Exceptions";
"lng_notification_title_private_chats" = "Notifications for private chats";
"lng_notification_about_private_chats#one" = "Please note that **{count} chat** is listed as an exception and won't be affected by this change.";
"lng_notification_about_private_chats#other" = "Please note that **{count} chats** are listed as exceptions and won't be affected by this change.";
"lng_notification_title_groups" = "Notifications for groups";
"lng_notification_about_groups#one" = "Please note that **{count} group** is listed as an exception and won't be affected by this change.";
"lng_notification_about_groups#other" = "Please note that **{count} groups** are listed as exceptions and won't be affected by this change.";
"lng_notification_title_channels" = "Notifications for channels";
"lng_notification_about_channels#one" = "Please note that **{count} channel** is listed as an exception and won't be affected by this change.";
"lng_notification_about_channels#other" = "Please note that **{count} channels** are listed as exceptions and won't be affected by this change.";
"lng_notification_exceptions_view" = "View exceptions";
"lng_notification_enable" = "Enable notifications";
"lng_notification_sound" = "Sound";
"lng_notification_tone" = "Notification tone";
"lng_notification_exceptions_muted" = "Muted";
"lng_notification_exceptions_unmuted" = "Unmuted";
"lng_notification_exceptions_add" = "Add an exception";
"lng_notification_exceptions_clear" = "Delete all exceptions";
"lng_notification_exceptions_clear_sure" = "Are you sure you want to delete all exceptions?";
"lng_notification_exceptions_clear_button" = "Delete";
"lng_notification_exceptions_remove" = "Remove";
"lng_notification_context_remove" = "Remove exception";
"lng_reaction_text" = "{reaction} to your «{text}»";
"lng_reaction_notext" = "{reaction} to your message";
@ -513,11 +546,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_workmode_tray" = "Show tray icon";
"lng_settings_workmode_window" = "Show taskbar icon";
"lng_settings_close_to_taskbar" = "Close to taskbar";
"lng_settings_monochrome_icon" = "Use monochrome icon";
"lng_settings_window_system" = "Window title";
"lng_settings_title_chat_name" = "Show chat name";
"lng_settings_title_account_name" = "Show active account";
"lng_settings_title_total_count" = "Total unread count";
"lng_settings_native_frame" = "Use system window frame";
"lng_settings_qt_frame" = "Use Qt window frame";
"lng_settings_auto_start" = "Launch Telegram when system starts";
"lng_settings_start_min" = "Launch minimized";
"lng_settings_auto_start_disabled_uwp" = "Starting with the system was disabled in Windows Settings.\n\nPlease enable Telegram Desktop in the Startup Apps Settings.";
@ -739,11 +774,33 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_clear_payment_info_clear" = "Clear";
"lng_clear_payment_info_confirm" = "Delete your shipping info and instruct all payment providers to remove your saved credit cards? Note that Telegram never stores your credit card data.";
"lng_settings_theme_settings" = "Theme settings";
"lng_settings_theme_name_color" = "Your name color";
"lng_settings_auto_night_mode" = "Auto-Night mode";
"lng_settings_auto_night_enabled" = "Match the system settings";
"lng_settings_auto_night_mode_off" = "Off";
"lng_settings_auto_night_mode_on" = "System";
"lng_settings_auto_night_warning" = "You have enabled auto-night mode. If you want to change the dark mode settings, you'll need to disable it first.";
"lng_settings_auto_night_disable" = "Disable";
"lng_settings_color_title" = "Color preview";
"lng_settings_color_reply" = "Reply to your message";
"lng_settings_color_reply_channel" = "Reply to your channel message";
"lng_settings_color_text" = "Your name and replies to your messages will be shown in the selected color.";
"lng_settings_color_text_channel" = "The name of the channel and replies to its messages will be shown in the selected color.";
"lng_settings_color_link_name" = "Telegram";
"lng_settings_color_link_title" = "Link Preview";
"lng_settings_color_link_description" = "Your selected color will also tint the link preview.";
"lng_settings_color_about" = "You can choose a color to tint your name, the links you send, and replies to your messages.";
"lng_settings_color_about_channel" = "You can choose a color to tint your channel's name, the links it sends, and replies to its messages.";
"lng_settings_color_emoji" = "Add icons to replies";
"lng_settings_color_emoji_remove" = "Remove icon";
"lng_settings_color_emoji_off" = "Off";
"lng_settings_color_emoji_about" = "Make replies to your messages stand out by adding custom patterns to them.";
"lng_settings_color_emoji_about_channel" = "Make replies to your channel's messages stand out by adding custom patterns to them.";
"lng_settings_color_subscribe" = "Subscribe to {link} to choose a custom color for your name.";
"lng_settings_color_changed" = "Your name color has been updated!";
"lng_settings_color_changed_channel" = "Your channel color has been updated!";
"lng_suggest_hide_new_title" = "Hide new chats?";
"lng_suggest_hide_new_about" = "You are receiving lots of new chats from users who are not in your Contact List.\n\nDo you want to have such chats **automatically muted** and **archived**?";
"lng_suggest_hide_new_to_settings" = "Go to Settings";
@ -771,7 +828,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_background_text1" = "Ah, you kids today with techno music! You should enjoy the classics, like Hasselhoff!";
"lng_background_text2" = "I can't even take you seriously right now.";
"lng_background_bad_link" = "This background link appears to be invalid.";
"lng_background_apply" = "Apply";
"lng_background_share" = "Share";
"lng_background_link_copied" = "Link copied to clipboard";
"lng_background_blur" = "Blurred";
@ -1111,6 +1167,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_mute_box_title" = "Mute notifications for...";
"lng_preview_loading" = "Getting Link Info...";
"lng_preview_cant" = "Could not generate preview for this link.";
"lng_profile_settings_section" = "Settings";
"lng_profile_bot_settings" = "Bot Settings";
@ -1152,6 +1209,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_loading" = "Loading...";
"lng_profile_saved_stories#one" = "{count} saved story";
"lng_profile_saved_stories#other" = "{count} saved stories";
"lng_profile_posts#one" = "{count} post";
"lng_profile_posts#other" = "{count} posts";
"lng_profile_photos#one" = "{count} photo";
"lng_profile_photos#other" = "{count} photos";
"lng_profile_gifs#one" = "{count} GIF";
@ -1581,6 +1640,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_suggested_video" = "{user} suggests you to use this profile video.";
"lng_action_suggested_video_button" = "View Video";
"lng_action_attach_menu_bot_allowed" = "You allowed this bot to message you when you added it in the attachment menu.";
"lng_action_webapp_bot_allowed" = "You allowed this bot to message you in his web-app.";
"lng_action_set_wallpaper_me" = "You set a new wallpaper for this chat";
"lng_action_set_wallpaper" = "{user} set a new wallpaper for this chat";
"lng_action_set_wallpaper_button" = "View Wallpaper";
@ -1606,6 +1666,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_story_mention_button" = "View Story";
"lng_action_story_mention_me_unavailable" = "The story where you mentioned {user} is no longer available.";
"lng_action_story_mention_unavailable" = "The story where {user} mentioned you is no longer available.";
"lng_action_giveaway_started" = "{from} just started a giveaway of Telegram Premium subscriptions to its followers.";
"lng_premium_gift_duration_months#one" = "for {count} month";
"lng_premium_gift_duration_months#other" = "for {count} months";
@ -1769,6 +1830,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_bot_share_location_unavailable" = "Sorry, location sharing is currently unavailable in Telegram Desktop.";
"lng_bot_share_phone" = "Do you want to share your phone number with this bot?";
"lng_bot_share_phone_confirm" = "Share";
"lng_bot_allow_write_title" = "Allow messaging";
"lng_bot_allow_write" = "Do you want to allow this bot writing you?";
"lng_bot_allow_write_confirm" = "Allow";
"lng_attach_failed" = "Failed";
"lng_attach_file" = "File";
@ -1965,6 +2029,161 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_premium_gift_terms" = "You can review the list of features and terms of use for Telegram Premium {link}.";
"lng_premium_gift_terms_link" = "here";
"lng_boost_channel_button" = "Boost Channel";
"lng_boost_level#one" = "Level {count}";
"lng_boost_level#other" = "Level {count}";
"lng_boost_channel_title_first" = "Enable stories for channel";
"lng_boost_channel_needs_first#one" = "{channel} needs **{count}** more boost to enable posting stories. Help make it possible!";
"lng_boost_channel_needs_first#other" = "{channel} needs **{count}** more boosts to enable posting stories. Help make it possible!";
"lng_boost_channel_title_more" = "Help upgrade channel";
"lng_boost_channel_needs_more#one" = "{channel} needs **{count}** more boost to be able to {post}.";
"lng_boost_channel_needs_more#other" = "{channel} needs **{count}** more boosts to be able to {post}.";
"lng_boost_channel_title_max" = "Maximum level reached";
"lng_boost_channel_you_title" = "You boosted {channel}!";
"lng_boost_channel_you_first#one" = "This channel needs **{count}** more boost\nto enable stories.";
"lng_boost_channel_you_first#other" = "This channel needs **{count}** more boosts\nto enable stories.";
"lng_boost_channel_you_more#one" = "This channel needs **{count}** more boost\nto be able to {post}.";
"lng_boost_channel_you_more#other" = "This channel needs **{count}** more boosts\nto be able to {post}.";
"lng_boost_channel_reached_first" = "This channel reached **Level 1** and can now post stories.";
"lng_boost_channel_reached_more#one" = "This channel reached **Level {count}** and can now {post}.";
"lng_boost_channel_reached_more#other" = "This channel reached **Level {count}** and can now {post}.";
"lng_boost_channel_post_stories#one" = "post **{count} story** per day";
"lng_boost_channel_post_stories#other" = "post **{count} stories** per day";
"lng_boost_error_gifted_title" = "Can't boost with gifted Premium!";
"lng_boost_error_gifted_text" = "Because your **Telegram Premium** subscription was gifted to you, you can't use it to boost channels.";
"lng_boost_error_already_title" = "Already Boosted!";
"lng_boost_error_already_text" = "You are already boosting this channel.";
"lng_boost_error_premium_title" = "Premium needed!";
"lng_boost_error_premium_text" = "Only **Telegram Premium** subscribers can boost channels. Do you want to subscribe to **Telegram Premium**?";
"lng_boost_error_premium_yes" = "Yes";
"lng_boost_error_flood_title" = "Can't boost too often!";
"lng_boost_error_flood_text" = "You can change the channel you boost only once a day. Next time you can boost is in {left}.";
"lng_boost_now_instead" = "You currently boost {channel}. Do you want to boost {other} instead?";
"lng_boost_now_replace" = "Replace";
"lng_boost_channel_title_color" = "Enable colors";
"lng_boost_channel_needs_level_color#one" = "Your channel needs to reach **Level {count}** to change channel color.";
"lng_boost_channel_needs_level_color#other" = "Your channel needs to reach **Level {count}** to change channel color.";
"lng_boost_channel_ask" = "Ask your **Premium** subscribers to boost your channel with this link:";
"lng_boost_channel_ask_button" = "Copy Link";
"lng_boost_channel_or" = "or";
"lng_boost_channel_gifting" = "Boost your channel by gifting your subscribers Telegram Premium. {link}";
"lng_boost_channel_gifting_link" = "Get boosts >";
"lng_giveaway_new_title" = "Boosts via Gifts";
"lng_giveaway_new_about" = "Get more boosts for your channel by gifting Premium to your subscribers.";
"lng_giveaway_create_option" = "Create Giveaway";
"lng_giveaway_create_subtitle" = "winners are chosen randomly";
"lng_giveaway_award_option" = "Award Specific Users";
"lng_giveaway_award_subtitle" = "Select recipients >";
"lng_giveaway_award_chosen#one" = "{count} recipient >";
"lng_giveaway_award_chosen#other" = "{count} recipients >";
"lng_giveaway_quantity_title" = "Quantity of prizes / boosts";
"lng_giveaway_quantity#one" = "{count} Subscription / Boost";
"lng_giveaway_quantity#other" = "{count} Subscriptions / Boosts";
"lng_giveaway_quantity_about" = "Choose how many Premium subscriptions to give away and boosts to receive.";
"lng_giveaway_channels_title" = "Channels included in the giveaway";
"lng_giveaway_channels_this#one" = "this channel will receive {count} boost";
"lng_giveaway_channels_this#other" = "this channel will receive {count} boosts";
"lng_giveaway_channels_add" = "Add Channel";
"lng_giveaway_channels_about" = "Choose the channels the users need to join to take part in the giveaway.";
"lng_giveaway_users_title" = "Users eligible for the giveaway";
"lng_giveaway_users_all" = "All subscribers";
"lng_giveaway_users_new" = "Only new subscribers";
"lng_giveaway_users_about" = "Choose if you want to limit the giveaway only to the newly joined subscribers.";
"lng_giveaway_start" = "Start Giveaway";
"lng_giveaway_award" = "Gift Premium";
"lng_giveaway_date_title" = "Date when giveaway ends";
"lng_giveaway_date" = "Date and Time";
"lng_giveaway_date_about#one" = "Choose when {count} subscriber of your channel will be randomly selected to receive Telegram Premium.";
"lng_giveaway_date_about#other" = "Choose when {count} subscribers of your channel will be randomly selected to receive Telegram Premium.";
"lng_giveaway_duration_title#one" = "Duration of Premium subscription";
"lng_giveaway_duration_title#other" = "Duration of Premium subscriptions";
"lng_giveaway_duration_price" = "{price} x {amount}";
"lng_giveaway_duration_about" = "You can review the list of features and terms of use for Telegram Premium {link}.";
"lng_giveaway_duration_about_link" = "here";
"lng_giveaway_date_select" = "Select Date and Time";
"lng_giveaway_date_confirm" = "Confirm";
"lng_giveaway_channels_select#one" = "Select up to {count} channel";
"lng_giveaway_channels_select#other" = "Select up to {count} channels";
"lng_giveaway_recipients_save" = "Save Recipients";
"lng_giveaway_recipients_deselect" = "Deselect All";
"lng_prize_title" = "Congratulations!";
"lng_prize_about" = "You won a prize in a giveaway organized by {channel}.";
"lng_prize_duration" = "Your prize is a **Telegram Premium** subscription {duration}.";
"lng_prize_gift_about" = "You've received a gift from {channel}.";
"lng_prize_gift_duration" = "Your gift is a **Telegram Premium** subscription {duration}.";
"lng_prize_open" = "Open Gift Link";
"lng_prize_unclaimed_title" = "Unclaimed Prize";
"lng_prize_unclaimed_about" = "You have an unclaimed prize from a giveaway by {channel}.";
"lng_prize_unclaimed_duration" = "This prize is a **Telegram Premium** subscription {duration}.";
"lng_prizes_title#one" = "Giveaway Prize";
"lng_prizes_title#other" = "Giveaway Prizes";
"lng_prizes_about#one" = "**{count}** Telegram Premium Subscription {duration}.";
"lng_prizes_about#other" = "**{count}** Telegram Premium Subscriptions {duration}.";
"lng_prizes_participants" = "Participants";
"lng_prizes_participants_all#one" = "All subscribers of the channel:";
"lng_prizes_participants_all#other" = "All subscribers of the channels:";
"lng_prizes_participants_new#one" = "All users who joined the channel below after this date:";
"lng_prizes_participants_new#other" = "All users who joined the channels below after this date:";
"lng_prizes_countries" = "from {countries}";
"lng_prizes_countries_and_one" = "{countries}, {country}";
"lng_prizes_countries_and_last" = "{countries} and {country}";
"lng_prizes_date" = "Winners Selection Date";
"lng_prizes_how_works" = "Learn more";
"lng_prizes_how_title" = "About this giveaway";
"lng_prizes_end_title" = "Giveaway ended";
"lng_prizes_how_text" = "This giveaway is sponsored by {admins}.";
"lng_prizes_end_text" = "This giveaway was sponsored by {admins}.";
"lng_prizes_admins#one" = "the admins of {channel}, who aquired **{count} Telegram Premium** subscription {duration} for its followers";
"lng_prizes_admins#other" = "the admins of {channel}, who aquired **{count} Telegram Premium** subscriptions {duration} for its followers.";
"lng_prizes_how_when_finish" = "On {date}, Telegram will automatically select {winners}.";
"lng_prizes_end_when_finish" = "On {date}, Telegram automatically selected {winners}.";
"lng_prizes_end_activated#one" = "**{count}** of the winners already used their gift link.";
"lng_prizes_end_activated#other" = "**{count}** of the winners already used their gift links.";
"lng_prizes_winners_all_of_one#one" = "{count} random subscribers of {channel}.";
"lng_prizes_winners_all_of_one#other" = "{count} random subscribers of {channel}.";
"lng_prizes_winners_all_of_many#one" = "{count} random subscribers of {channel} and other listed channels.";
"lng_prizes_winners_all_of_many#other" = "{count} random subscribers of {channel} and other listed channels.";
"lng_prizes_winners_new_of_one#one" = "{count} random user that joined {channel} after {start_date}";
"lng_prizes_winners_new_of_one#other" = "{count} random users that joined {channel} after {start_date}";
"lng_prizes_winners_new_of_many#one" = "{count} random user that joined {channel} and other listed channels after {start_date}";
"lng_prizes_winners_new_of_many#other" = "{count} random users that joined {channel} and other listed channels after {start_date}";
"lng_prizes_how_participate_one" = "To take part in this giveaway please join channel {channel} before {date}.";
"lng_prizes_how_participate_many" = "To take part in this giveaway please join channel {channel} and other listed channels before {date}.";
"lng_prizes_how_no_admin" = "You are not eligible to participate in this giveaway, because you are an admin of participating channel ({channel}).";
"lng_prizes_how_no_joined" = "You are not eligible to participate in this giveaway, because you joined this channel on {date}, which is before the contest started.";
"lng_prizes_how_no_country" = "You are not eligible to participate in this giveaway, because your country is not included in the terms of the giveaway.";
"lng_prizes_how_yes_joined_one" = "You are participating in this giveaway, because you have joined channel {channel}.";
"lng_prizes_how_yes_joined_many" = "You are participating in this giveaway, because you have joined channel {channel} (and other listed channels).";
"lng_prizes_you_won" = "You won a prize in this giveaway {cup}";
"lng_prizes_view_prize" = "View my prize";
"lng_prizes_you_didnt" = "You didn't win a prize in this giveaway.";
"lng_prizes_cancelled" = "The channel cancelled the prizes by reversing the payment for them.";
"lng_prizes_badge" = "x{amount}";
"lng_gift_link_title" = "Gift Link";
"lng_gift_link_about" = "This link allows you to activate\na **Telegram Premium** subscription.";
"lng_gift_link_label_from" = "From";
"lng_gift_link_label_to" = "To";
"lng_gift_link_label_to_unclaimed" = "No recipient";
"lng_gift_link_label_gift" = "Gift";
"lng_gift_link_gift_premium" = "Telegram Premium {duration}";
"lng_gift_link_label_reason" = "Reason";
"lng_gift_link_reason_giveaway" = "Giveaway";
"lng_gift_link_reason_unclaimed" = "Incomplete Giveaway";
"lng_gift_link_reason_chosen" = "You were selected by the channel";
"lng_gift_link_label_date" = "Date";
"lng_gift_link_also_send" = "You can also {link} to a friend as a gift.";
"lng_gift_link_also_send_link" = "send this link";
"lng_gift_link_use" = "Use Link";
"lng_gift_link_used_title" = "Used Gift Link";
"lng_gift_link_used_about" = "This link was used to activate\na **Telegram Premium** subscription.";
"lng_gift_link_used_footer" = "This link was used on {date}.";
"lng_gift_link_expired" = "Gift code link expired";
"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.";
@ -2144,6 +2363,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_saved_messages" = "Saved Messages";
"lng_saved_short" = "Save";
"lng_saved_forward_here" = "Forward messages here for quick access";
"lng_saved_quote_here" = "Quote here to save";
"lng_scheduled_messages" = "Scheduled Messages";
"lng_scheduled_messages_empty" = "No scheduled messages here yet...";
@ -2226,17 +2446,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_bot_remove_from_menu" = "Remove From Menu";
"lng_bot_remove_from_menu_sure" = "Remove {bot} from the attachment menu?";
"lng_bot_remove_from_menu_done" = "Bot removed from the menu.";
"lng_bot_remove_from_side_menu" = "Remove From Menu";
"lng_bot_remove_from_side_menu_sure" = "Remove {bot} from the main menu?";
"lng_bot_remove_from_side_menu_done" = "Bot removed from the main menu.";
"lng_bot_settings" = "Settings";
"lng_bot_open" = "Open Bot";
"lng_bot_reload_page" = "Reload Page";
"lng_bot_add_to_menu" = "{bot} asks your permission to be added as an option to your attachments menu so you can access it from any chat.";
"lng_bot_add_to_menu_done" = "Bot added to the menu.";
"lng_bot_will_be_added" = "{bot} shortcuts will be added to the attachment options and the main menu.";
"lng_bot_side_menu_new" = "NEW";
"lng_bot_menu_not_supported" = "This bot isn't supported in the attach menu.";
"lng_bot_menu_already_added" = "This bot is already added in your attach menu.";
"lng_bot_menu_button" = "Menu";
"lng_bot_close_warning_title" = "Warning";
"lng_bot_close_warning" = "Changes that you made may not be saved.";
"lng_bot_close_warning_sure" = "Close anyway";
"lng_bot_add_to_side_menu" = "{bot} asks your permission to be added as an option to your main menu so you can access it any time.";
"lng_bot_add_to_side_menu_done" = "Bot added to the main menu.";
"lng_typing" = "typing";
"lng_user_typing" = "{user} is typing";
@ -2340,9 +2567,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_open_gif" = "Open GIF";
"lng_context_save_gif" = "Save GIF";
"lng_context_delete_gif" = "Delete GIF";
"lng_context_open_channel" = "Open Channel";
"lng_context_attached_stickers" = "Attached Stickers";
"lng_context_to_msg" = "Go To Message";
"lng_context_reply_msg" = "Reply";
"lng_context_quote_and_reply" = "Quote & Reply";
"lng_context_edit_msg" = "Edit";
"lng_context_forward_msg" = "Forward Message";
"lng_context_send_now_msg" = "Send now";
@ -2447,6 +2676,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_inline_switch_choose" = "Choose conversation...";
"lng_inline_switch_cant" = "Sorry, no way to write here :(";
"lng_reply_in_another_title" = "Reply in...";
"lng_reply_in_another_chat" = "Reply in Another Chat";
"lng_reply_show_in_chat" = "Show in Chat";
"lng_reply_remove" = "Do Not Reply";
"lng_reply_about_quote" = "You can select specific part to quote.";
"lng_reply_options_header" = "Reply to Message";
"lng_reply_options_quote" = "Update Quote";
"lng_reply_header_short" = "Reply";
"lng_reply_quote_selected" = "Quote Selected";
"lng_reply_from_private_chat" = "This reply is from a private chat.";
"lng_link_options_header" = "Link Preview Settings";
"lng_link_header_short" = "Link";
"lng_link_move_up" = "Move Up";
"lng_link_move_down" = "Move Down";
"lng_link_shrink_photo" = "Shrink Photo";
"lng_link_enlarge_photo" = "Enlarge Photo";
"lng_link_remove" = "Do Not Preview";
"lng_link_about_choose" = "Click on a link to generate its preview.";
"lng_share_cant" = "Sorry, no way to share here :(";
"lng_reply_cant" = "Sorry, no way to reply to an old message in supergroup :(";
"lng_reply_cant_forward" = "Sorry, you can't reply to a message that was sent before the group was upgraded to a supergroup. Do you wish to forward it and add your comment?";
@ -2469,6 +2717,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_bot_title" = "Edit bot";
"lng_edit_sign_messages" = "Sign messages";
"lng_edit_group" = "Edit group";
"lng_edit_channel_color" = "Change name color";
"lng_edit_self_title" = "Edit your name";
"lng_confirm_contact_data" = "New Contact";
"lng_add_contact" = "Create";
@ -2597,6 +2846,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_menu_formatting_italic" = "Italic";
"lng_menu_formatting_underline" = "Underline";
"lng_menu_formatting_strike_out" = "Strike-through";
"lng_menu_formatting_blockquote" = "Quote";
"lng_menu_formatting_monospace" = "Monospace";
"lng_menu_formatting_spoiler" = "Spoiler";
"lng_menu_formatting_link_create" = "Create link";
@ -2609,6 +2859,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_formatting_link_create" = "Create";
"lng_text_copied" = "Text copied to clipboard.";
"lng_code_copied" = "Block copied to clipboard.";
"lng_spellchecker_submenu" = "Spelling";
"lng_spellchecker_add" = "Add to Dictionary";
@ -2717,6 +2968,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_payments_terms_title" = "Terms of Service";
"lng_payments_terms_text" = "Subscribe and accept terms of service of {bot}?";
"lng_payments_terms_text_once" = "Are you accepting terms of service of {bot}?";
"lng_payments_terms_agree" = "I agree to {link}";
"lng_payments_terms_link" = "Terms of Service";
"lng_payments_terms_accept" = "Accept";
@ -3049,9 +3301,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gigagroup_suggest_more" = "Learn more";
"lng_rights_channel_info" = "Change channel info";
"lng_rights_channel_manage" = "Manage messages";
"lng_rights_channel_post" = "Post messages";
"lng_rights_channel_edit" = "Edit messages of others";
"lng_rights_channel_delete" = "Delete messages of others";
"lng_rights_channel_manage_stories" = "Manage stories";
"lng_rights_channel_post_stories" = "Post stories";
"lng_rights_channel_edit_stories" = "Edit stories of others";
"lng_rights_channel_delete_stories" = "Delete stories of others";
"lng_rights_channel_manage_calls" = "Manage live streams";
"lng_rights_group_info" = "Change group info";
"lng_rights_group_ban" = "Ban users";
@ -3268,6 +3525,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_admin_log_participant_volume_channel" = "{from} changed live stream volume for {user} to {percent}";
"lng_admin_log_antispam_enabled" = "{from} enabled aggressive anti-spam";
"lng_admin_log_antispam_disabled" = "{from} disabled aggressive anti-spam";
"lng_admin_log_change_color" = "{from} changed channel color from {previous} to {color}";
"lng_admin_log_set_background_emoji" = "{from} set channel background emoji to {emoji}";
"lng_admin_log_change_background_emoji" = "{from} changed channel background emoji from {previous} to {emoji}";
"lng_admin_log_removed_background_emoji" = "{from} removed channel background emoji {emoji}";
"lng_admin_log_user_with_username" = "{name} ({mention})";
"lng_admin_log_messages_ttl_set" = "{from} enabled messages auto-delete after {duration}";
"lng_admin_log_messages_ttl_changed" = "{from} changed messages auto-delete period from {previous} to {duration}";
@ -3310,6 +3571,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_admin_log_admin_post_messages" = "Post messages";
"lng_admin_log_admin_edit_messages" = "Edit messages";
"lng_admin_log_admin_delete_messages" = "Delete messages";
"lng_admin_log_admin_post_stories" = "Post stories";
"lng_admin_log_admin_edit_stories" = "Edit stories";
"lng_admin_log_admin_delete_stories" = "Delete stories";
"lng_admin_log_admin_remain_anonymous" = "Remain anonymous";
"lng_admin_log_admin_ban_users" = "Ban users";
"lng_admin_log_admin_invite_users" = "Add members";
@ -3525,6 +3789,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_export_option_choose_format" = "Choose export format";
"lng_export_option_html" = "Human-readable HTML";
"lng_export_option_json" = "Machine-readable JSON";
"lng_export_option_html_and_json" = "Both";
"lng_export_limits" = "From: {from}, to: {till}";
"lng_export_beginning" = "the oldest message";
"lng_export_end" = "present";
@ -3789,6 +4054,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_view_button_voice_chat_channel" = "Live stream";
"lng_view_button_request_join" = "Request to Join";
"lng_view_button_external_link" = "Open link";
"lng_view_button_boost" = "Boost";
"lng_sponsored_hide_ads" = "Hide";
"lng_sponsored_title" = "What are sponsored messages?";
@ -3799,6 +4065,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_telegram_features_url" = "https://t.me/TelegramTips";
"lng_mini_apps_disclaimer_title" = "Warning";
"lng_mini_apps_disclaimer_text" = "You are about to use a mini app operated by an independent party **not affiliated with Telegram**. You must agree to the Terms of Use of mini apps to continue.";
"lng_mini_apps_disclaimer_button" = "I agree to the {link}";
"lng_mini_apps_disclaimer_link" = "Terms of Use";
"lng_mini_apps_tos_url" = "https://telegram.org/tos/mini-apps";
"lng_ringtones_box_title" = "Notification Sound";
"lng_ringtones_box_cloud_subtitle" = "Choose your tone";
"lng_ringtones_box_upload_choose" = "Choose ringtone";
@ -3916,6 +4188,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stories_recent_button" = "Recent Stories";
"lng_stories_archive_title" = "Stories Archive";
"lng_stories_archive_about" = "Only you can see archived stories unless you choose to save them to your profile.";
"lng_stories_channel_archive_about" = "Only admins of the channel can see archived stories unless they are saved to the channel page.";
"lng_stories_reply_sent" = "Message Sent";
"lng_stories_hidden_to_contacts" = "Stories from {user} will now be shown in **Archived Chats**.";
"lng_stories_shown_in_chats" = "Stories from {user} will now be shown in the **Chats List**.";
@ -3935,6 +4208,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stories_archive_done" = "This story is hidden from your profile.";
"lng_stories_archive_done_many#one" = "{count} story is hidden from your profile.";
"lng_stories_archive_done_many#other" = "{count} stories are hidden from your profile.";
"lng_stories_channel_save_sure" = "Do you want to save this story to the channel page?";
"lng_stories_channel_save_sure_many#one" = "Do you want to save {count} story to the channel page?";
"lng_stories_channel_save_sure_many#other" = "Do you want to save {count} stories to the channel page?";
"lng_stories_channel_save_done" = "This story is saved to the channel page.";
"lng_stories_channel_save_done_many#one" = "{count} story is saved to the channel page.";
"lng_stories_channel_save_done_many#other" = "{count} stories are saved to the channel page.";
"lng_stories_channel_save_done_about" = "Saved stories can be viewed by others on the channel page until they are removed.";
"lng_stories_channel_archive_sure" = "Do you want to hide this story from the channel page?";
"lng_stories_channel_archive_sure_many#one" = "Do you want to hide {count} story from the channel page?";
"lng_stories_channel_archive_sure_many#other" = "Do you want to hide {count} stories from the channel page?";
"lng_stories_channel_archive_done" = "This story is hidden from the channel page.";
"lng_stories_channel_archive_done_many#one" = "{count} story is hidden from the channel page.";
"lng_stories_channel_archive_done_many#other" = "{count} stories are hidden from the channel page.";
"lng_stories_save_promo" = "Subscribe to {link} to download other people's unprotected stories to disk.";
"lng_stealth_mode_menu_item" = "Stealth Mode";
@ -3957,6 +4243,80 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stories_link_invalid" = "This link is broken or has expired.";
"lng_stats_title" = "Statistics";
"lng_stats_message_title" = "Message Statistic";
"lng_stats_zoom_out" = "Zoom Out";
"lng_stats_overview_title" = "Overview";
"lng_stats_overview_member_count" = "Followers";
"lng_stats_overview_mean_view_count" = "Views Per Post";
"lng_stats_overview_mean_share_count" = "Shared Per Post";
"lng_stats_overview_enabled_notifications" = "Enabled Notifications";
"lng_stats_overview_messages" = "Messages";
"lng_stats_overview_group_mean_view_count" = "Viewing Members";
"lng_stats_overview_group_mean_post_count" = "Posting Members";
"lng_stats_overview_message_private_shares" = "Private Shares";
"lng_stats_overview_message_public_shares" = "Public Shares";
"lng_stats_overview_message_views" = "Views";
"lng_stats_overview_message_public_share#one" = "{count} public share";
"lng_stats_overview_message_public_share#other" = "{count} public shares";
"lng_stats_members_title" = "Top members";
"lng_stats_admins_title" = "Top admins";
"lng_stats_inviters_title" = "Top inviters";
"lng_stats_member_messages#one" = "{count} message";
"lng_stats_member_messages#other" = "{count} messages";
"lng_stats_member_characters#one" = "{count} symbol per message";
"lng_stats_member_characters#other" = "{count} symbols per message";
"lng_stats_member_deletions#one" = "{count} deletions";
"lng_stats_member_deletions#other" = "{count} deletions";
"lng_stats_member_bans#one" = "{count} ban";
"lng_stats_member_bans#other" = "{count} bans";
"lng_stats_member_restrictions#one" = "{count} restriction";
"lng_stats_member_restrictions#other" = "{count} restrictions";
"lng_stats_member_invitations#one" = "{count} invitation";
"lng_stats_member_invitations#other" = "{count} invitations";
"lng_stats_recent_messages_title" = "Recent posts";
"lng_stats_recent_messages_views#one" = "{count} view";
"lng_stats_recent_messages_views#other" = "{count} views";
"lng_stats_recent_messages_shares#one" = "{count} share";
"lng_stats_recent_messages_shares#other" = "{count} shares";
"lng_stats_loading" = "Loading stats...";
"lng_stats_loading_subtext" = "Please wait a few moments while we generate your stats.";
"lng_chart_title_member_count" = "Growth";
"lng_chart_title_join" = "Followers";
"lng_chart_title_mute" = "Notifications";
"lng_chart_title_view_count_by_hour" = "Views by hours";
"lng_chart_title_view_count_by_source" = "Views by source";
"lng_chart_title_join_by_source" = "New followers by source";
"lng_chart_title_language" = "Languages";
"lng_chart_title_message_interaction" = "Interactions";
"lng_chart_title_instant_view_interaction" = "IV Interactions";
"lng_chart_title_group_join" = "Group members";
"lng_chart_title_group_join_by_source" = "New members by source";
"lng_chart_title_group_language" = "Members's primary language";
"lng_chart_title_group_message_content" = "Messages";
"lng_chart_title_group_action" = "Actions";
"lng_chart_title_group_day" = "Views by hours";
"lng_chart_title_group_week" = "Top days of week";
"lng_boosts_title" = "Boosts";
"lng_boosts_level" = "Level";
"lng_boosts_existing" = "Existing boosts";
"lng_boosts_premium_audience" = "Premium subscribers";
"lng_boosts_next_level" = "Boosts to level up";
"lng_boosts_list_title#one" = "{count} booster";
"lng_boosts_list_title#other" = "{count} boosters";
"lng_boosts_list_subtext" = "Your channel is currently boosted by these users.";
"lng_boosts_show_more" = "Show More Boosts";
"lng_boosts_list_status" = "boost expires on {date}";
"lng_boosts_link_title" = "Link for boosting";
"lng_boosts_link_subtext" = "Share this link with your subscribers to get more boosts.";
// Wnd specific
"lng_wnd_choose_program_menu" = "Choose Default Program...";

View File

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

View File

@ -10,5 +10,6 @@
<file alias="cloud_password/email.tgs">../../animations/cloud_password/email.tgs</file>
<file alias="ttl.tgs">../../animations/ttl.tgs</file>
<file alias="discussion.tgs">../../animations/discussion.tgs</file>
<file alias="stats.tgs">../../animations/stats.tgs</file>
</qresource>
</RCC>

View File

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

View File

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

View File

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

View File

@ -267,7 +267,7 @@ int main(int argc, char *argv[])
}
QByteArray inner = f.readAll();
stream << name << quint32(inner.size()) << inner;
#ifdef Q_OS_UNIX
#ifndef Q_OS_WIN
stream << (QFileInfo(fullName).isExecutable() ? true : false);
#endif
}
@ -281,7 +281,7 @@ int main(int argc, char *argv[])
cout << "Compression start, size: " << resultSize << "\n";
QByteArray compressed, resultCheck;
#if defined Q_OS_WIN && !defined DESKTOP_APP_USE_PACKAGED // use Lzma SDK for win
#if defined Q_OS_WIN && !defined TDESKTOP_USE_PACKAGED // use Lzma SDK for win
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header
compressed.resize(hSize + resultSize + 1024 * 1024); // rsa signature + sha1 + lzma props + max compressed size
@ -496,10 +496,8 @@ int main(int argc, char *argv[])
QString outName((targetwin64 ? QString("tx64upd%1") : QString("tupdate%1")).arg(AlphaVersion ? AlphaVersion : version));
#elif defined Q_OS_MAC
QString outName((targetarmac ? QString("tarmacupd%1") : QString("tmacupd%1")).arg(AlphaVersion ? AlphaVersion : version));
#elif defined Q_OS_UNIX
QString outName(QString("tlinuxupd%1").arg(AlphaVersion ? AlphaVersion : version));
#else
#error Unknown platform!
QString outName(QString("tlinuxupd%1").arg(AlphaVersion ? AlphaVersion : version));
#endif
if (AlphaVersion) {
outName += "_" + AlphaSignature;

View File

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

View File

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

View File

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

View File

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

View File

@ -169,9 +169,7 @@ void SendBotCallbackData(
void HideSingleUseKeyboard(
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item) {
controller->content()->hideSingleUseKeyboard(
item->history()->peer,
item->id);
controller->content()->hideSingleUseKeyboard(item->fullId());
}
} // namespace
@ -312,12 +310,14 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
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;
const auto replyTo = item->isRegular()
? item->fullId()
: FullMsgId();
controller->content()->sendBotCommand({
.peer = item->history()->peer,
.command = QString(button->text),
.context = item->fullId(),
.replyTo = replyTo,
.replyTo = { replyTo },
});
} break;
@ -363,7 +363,7 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
case ButtonType::RequestPhone: {
HideSingleUseKeyboard(controller, item);
const auto itemId = item->id;
const auto itemId = item->fullId();
const auto topicRootId = item->topicRootId();
const auto history = item->history();
controller->show(Ui::MakeConfirmBox({
@ -376,7 +376,7 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
auto action = Api::SendAction(history);
action.clearDraft = false;
action.replyTo = {
.msgId = itemId,
.messageId = itemId,
.topicRootId = topicRootId,
};
history->session().api().shareContact(
@ -397,13 +397,11 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
chosen |= PollData::Flag::Quiz;
}
}
const auto replyToId = MsgId(0);
const auto topicRootId = MsgId(0);
const auto replyTo = FullReplyTo();
Window::PeerMenuCreatePoll(
controller,
item->history()->peer,
replyToId,
topicRootId,
replyTo,
chosen,
disabled);
} break;

View File

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

View File

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

View File

@ -19,8 +19,8 @@ SendAction::SendAction(
SendOptions options)
: history(thread->owningHistory())
, options(options)
, replyTo({ .msgId = thread->topicRootId() }) {
replyTo.topicRootId = replyTo.msgId;
, replyTo({ .messageId = { history->peer->id, thread->topicRootId() } }) {
replyTo.topicRootId = replyTo.messageId.msg;
}
SendOptions DefaultSendWhenOnlineOptions() {
@ -31,7 +31,7 @@ SendOptions DefaultSendWhenOnlineOptions() {
}
MTPInputReplyTo SendAction::mtpReplyTo() const {
return Data::ReplyToForMTP(&history->owner(), replyTo);
return Data::ReplyToForMTP(history, replyTo);
}
} // namespace Api

View File

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/data_drafts.h"
class History;
namespace Data {
@ -22,7 +24,6 @@ struct SendOptions {
TimeId scheduled = 0;
bool silent = false;
bool handleSupportSwitch = false;
bool removeWebPageId = false;
bool hideViaBot = false;
};
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();
@ -54,7 +55,7 @@ struct MessageToSend {
SendAction action;
TextWithTags textWithTags;
WebPageId webPageId = 0;
Data::WebPageDraft webPage;
};
struct RemoteFileInfo {

View File

@ -11,8 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_media.h"
#include "api/api_text_entities.h"
#include "ui/boxes/confirm_box.h"
#include "data/data_histories.h"
#include "data/data_scheduled_messages.h"
#include "data/data_session.h"
#include "data/data_web_page.h"
#include "history/history.h"
#include "history/history_item.h"
#include "lang/lang_keys.h"
@ -45,6 +47,7 @@ template <typename DoneCallback, typename FailCallback>
mtpRequestId EditMessage(
not_null<HistoryItem*> item,
const TextWithEntities &textWithEntities,
Data::WebPageDraft webpage,
SendOptions options,
DoneCallback &&done,
FailCallback &&fail,
@ -65,15 +68,21 @@ mtpRequestId EditMessage(
const auto emptyFlag = MTPmessages_EditMessage::Flag(0);
const auto flags = emptyFlag
| (!text.isEmpty() || media
| ((!text.isEmpty() || media)
? MTPmessages_EditMessage::Flag::f_message
: emptyFlag)
| ((media && inputMedia.has_value())
? MTPmessages_EditMessage::Flag::f_media
: emptyFlag)
| (options.removeWebPageId
| (webpage.removed
? MTPmessages_EditMessage::Flag::f_no_webpage
: emptyFlag)
| ((!webpage.removed && !webpage.url.isEmpty())
? MTPmessages_EditMessage::Flag::f_media
: emptyFlag)
| ((!webpage.removed && !webpage.url.isEmpty() && webpage.invert)
? MTPmessages_EditMessage::Flag::f_invert_media
: emptyFlag)
| (!sentEntities.v.isEmpty()
? MTPmessages_EditMessage::Flag::f_entities
: emptyFlag)
@ -89,7 +98,7 @@ mtpRequestId EditMessage(
item->history()->peer->input,
MTP_int(id),
MTP_string(text),
inputMedia.value_or(MTPInputMedia()),
inputMedia.value_or(Data::WebPageForMTP(webpage, text.isEmpty())),
MTPReplyMarkup(),
sentEntities,
MTP_int(options.scheduled)
@ -133,9 +142,15 @@ mtpRequestId EditMessage(
FailCallback &&fail,
std::optional<MTPInputMedia> inputMedia = std::nullopt) {
const auto &text = item->originalText();
const auto webpage = (!item->media() || !item->media()->webpage())
? Data::WebPageDraft{ .removed = true }
: Data::WebPageDraft{
.id = item->media()->webpage()->id,
};
return EditMessage(
item,
text,
webpage,
options,
std::forward<DoneCallback>(done),
std::forward<FailCallback>(fail),
@ -216,12 +231,19 @@ mtpRequestId EditCaption(
SendOptions options,
Fn<void()> done,
Fn<void(const QString &)> fail) {
return EditMessage(item, caption, options, done, fail);
return EditMessage(
item,
caption,
Data::WebPageDraft(),
options,
done,
fail);
}
mtpRequestId EditTextMessage(
not_null<HistoryItem*> item,
const TextWithEntities &caption,
Data::WebPageDraft webpage,
SendOptions options,
Fn<void(mtpRequestId requestId)> done,
Fn<void(const QString &, mtpRequestId requestId)> fail) {
@ -229,7 +251,7 @@ mtpRequestId EditTextMessage(
applyUpdates();
done(id);
};
return EditMessage(item, caption, options, callback, fail);
return EditMessage(item, caption, webpage, options, callback, fail);
}
} // namespace Api

View File

@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class HistoryItem;
namespace Data {
struct WebPageDraft;
} // namespace Data
namespace MTP {
class Error;
} // namespace MTP
@ -48,6 +52,7 @@ mtpRequestId EditCaption(
mtpRequestId EditTextMessage(
not_null<HistoryItem*> item,
const TextWithEntities &caption,
Data::WebPageDraft webpage,
SendOptions options,
Fn<void(mtpRequestId requestId)> done,
Fn<void(const QString &error, mtpRequestId requestId)> fail);

View File

@ -510,40 +510,57 @@ void PeerPhoto::requestUserPhotos(
_userPhotosRequests.emplace(user, requestId);
}
auto PeerPhoto::emojiList(EmojiListType type) -> EmojiListData & {
switch (type) {
case EmojiListType::Profile: return _profileEmojiList;
case EmojiListType::Group: return _groupEmojiList;
case EmojiListType::Background: return _backgroundEmojiList;
}
Unexpected("Type in PeerPhoto::emojiList.");
}
auto PeerPhoto::emojiList(EmojiListType type) const
-> const EmojiListData & {
return const_cast<PeerPhoto*>(this)->emojiList(type);
}
void PeerPhoto::requestEmojiList(EmojiListType type) {
if (_requestIdEmojiList) {
auto &list = emojiList(type);
if (list.requestId) {
return;
}
const auto isGroup = (type == EmojiListType::Group);
const auto d = [=](const MTPEmojiList &result) {
_requestIdEmojiList = 0;
result.match([](const MTPDemojiListNotModified &data) {
}, [&](const MTPDemojiList &data) {
auto &list = isGroup ? _profileEmojiList : _groupEmojiList;
list = ranges::views::all(
data.vdocument_id().v
) | ranges::views::transform(&MTPlong::v) | ranges::to_vector;
});
const auto send = [&](auto &&request) {
return _api.request(
std::move(request)
).done([=](const MTPEmojiList &result) {
auto &list = emojiList(type);
list.requestId = 0;
result.match([](const MTPDemojiListNotModified &data) {
}, [&](const MTPDemojiList &data) {
list.list = ranges::views::all(
data.vdocument_id().v
) | ranges::views::transform(
&MTPlong::v
) | ranges::to_vector;
});
}).fail([=] {
emojiList(type).requestId = 0;
}).send();
};
const auto f = [=] { _requestIdEmojiList = 0; };
_requestIdEmojiList = isGroup
? _api.request(
MTPaccount_GetDefaultGroupPhotoEmojis()
).done(d).fail(f).send()
: _api.request(
MTPaccount_GetDefaultProfilePhotoEmojis()
).done(d).fail(f).send();
list.requestId = (type == EmojiListType::Profile)
? send(MTPaccount_GetDefaultProfilePhotoEmojis())
: (type == EmojiListType::Group)
? send(MTPaccount_GetDefaultGroupPhotoEmojis())
: send(MTPaccount_GetDefaultBackgroundEmojis());
}
rpl::producer<PeerPhoto::EmojiList> PeerPhoto::emojiListValue(
EmojiListType type) {
auto &list = (type == EmojiListType::Group)
? _profileEmojiList
: _groupEmojiList;
if (list.current().empty() && !_requestIdEmojiList) {
auto &list = emojiList(type);
if (list.list.current().empty() && !list.requestId) {
requestEmojiList(type);
}
return list.value();
return list.list.value();
}
// Non-personal photo in case a personal photo is set.

View File

@ -31,6 +31,7 @@ public:
enum class EmojiListType {
Profile,
Group,
Background,
};
struct UserPhoto {
@ -73,6 +74,10 @@ private:
Suggestion,
Fallback,
};
struct EmojiListData {
rpl::variable<EmojiList> list;
mtpRequestId requestId = 0;
};
void ready(
const FullMsgId &msgId,
@ -84,6 +89,9 @@ private:
UploadType type,
Fn<void()> done);
[[nodiscard]] EmojiListData &emojiList(EmojiListType type);
[[nodiscard]] const EmojiListData &emojiList(EmojiListType type) const;
const not_null<Main::Session*> _session;
MTP::Sender _api;
@ -101,9 +109,9 @@ private:
not_null<UserData*>,
not_null<PhotoData*>> _nonPersonalPhotos;
mtpRequestId _requestIdEmojiList = 0;
rpl::variable<EmojiList> _profileEmojiList;
rpl::variable<EmojiList> _groupEmojiList;
EmojiListData _profileEmojiList;
EmojiListData _groupEmojiList;
EmojiListData _backgroundEmojiList;
};

View File

@ -43,7 +43,7 @@ void Polls::create(
const auto history = action.history;
const auto peer = history->peer;
const auto topicRootId = action.replyTo.msgId
const auto topicRootId = action.replyTo.messageId
? action.replyTo.topicRootId
: 0;
auto sendFlags = MTPmessages_SendMedia::Flags(0);

View File

@ -17,6 +17,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
namespace Api {
namespace {
[[nodiscard]] GiftCode Parse(const MTPDpayments_checkedGiftCode &data) {
return {
.from = peerFromMTP(data.vfrom_id()),
.to = data.vto_id() ? peerFromUser(*data.vto_id()) : PeerId(),
.giveawayId = data.vgiveaway_msg_id().value_or_empty(),
.date = data.vdate().v,
.used = data.vused_date().value_or_empty(),
.months = data.vmonths().v,
.giveaway = data.is_via_giveaway(),
};
}
} // namespace
Premium::Premium(not_null<ApiWrap*> api)
: _session(&api->session())
@ -183,6 +198,115 @@ void Premium::reloadCloudSet() {
}).send();
}
void Premium::checkGiftCode(
const QString &slug,
Fn<void(GiftCode)> done) {
if (_giftCodeRequestId) {
if (_giftCodeSlug == slug) {
return;
}
_api.request(_giftCodeRequestId).cancel();
}
_giftCodeSlug = slug;
_giftCodeRequestId = _api.request(MTPpayments_CheckGiftCode(
MTP_string(slug)
)).done([=](const MTPpayments_CheckedGiftCode &result) {
_giftCodeRequestId = 0;
const auto &data = result.data();
_session->data().processUsers(data.vusers());
_session->data().processChats(data.vchats());
done(updateGiftCode(slug, Parse(data)));
}).fail([=](const MTP::Error &error) {
_giftCodeRequestId = 0;
done(updateGiftCode(slug, {}));
}).send();
}
GiftCode Premium::updateGiftCode(
const QString &slug,
const GiftCode &code) {
auto &now = _giftCodes[slug];
if (now != code) {
now = code;
_giftCodeUpdated.fire_copy(slug);
}
return code;
}
rpl::producer<GiftCode> Premium::giftCodeValue(const QString &slug) const {
return _giftCodeUpdated.events_starting_with_copy(
slug
) | rpl::filter(rpl::mappers::_1 == slug) | rpl::map([=] {
const auto i = _giftCodes.find(slug);
return (i != end(_giftCodes)) ? i->second : GiftCode();
});
}
void Premium::applyGiftCode(const QString &slug, Fn<void(QString)> done) {
_api.request(MTPpayments_ApplyGiftCode(
MTP_string(slug)
)).done([=](const MTPUpdates &result) {
_session->api().applyUpdates(result);
done({});
}).fail([=](const MTP::Error &error) {
done(error.type());
}).send();
}
void Premium::resolveGiveawayInfo(
not_null<PeerData*> peer,
MsgId messageId,
Fn<void(GiveawayInfo)> done) {
Expects(done != nullptr);
_giveawayInfoDone = std::move(done);
if (_giveawayInfoRequestId) {
if (_giveawayInfoPeer == peer
&& _giveawayInfoMessageId == messageId) {
return;
}
_api.request(_giveawayInfoRequestId).cancel();
}
_giveawayInfoPeer = peer;
_giveawayInfoMessageId = messageId;
_giveawayInfoRequestId = _api.request(MTPpayments_GetGiveawayInfo(
_giveawayInfoPeer->input,
MTP_int(_giveawayInfoMessageId.bare)
)).done([=](const MTPpayments_GiveawayInfo &result) {
_giveawayInfoRequestId = 0;
auto info = GiveawayInfo();
result.match([&](const MTPDpayments_giveawayInfo &data) {
info.participating = data.is_participating();
info.state = data.is_preparing_results()
? GiveawayState::Preparing
: GiveawayState::Running;
info.adminChannelId = data.vadmin_disallowed_chat_id()
? ChannelId(*data.vadmin_disallowed_chat_id())
: ChannelId();
info.disallowedCountry = qs(
data.vdisallowed_country().value_or_empty());
info.tooEarlyDate
= data.vjoined_too_early_date().value_or_empty();
info.startDate = data.vstart_date().v;
}, [&](const MTPDpayments_giveawayInfoResults &data) {
info.state = data.is_refunded()
? GiveawayState::Refunded
: GiveawayState::Finished;
info.giftCode = qs(data.vgift_code_slug().value_or_empty());
info.activatedCount = data.vactivated_count().v;
info.finishDate = data.vfinish_date().v;
info.startDate = data.vstart_date().v;
});
_giveawayInfoDone(std::move(info));
}).fail([=] {
_giveawayInfoRequestId = 0;
_giveawayInfoDone({});
}).send();
}
const Data::SubscriptionOptions &Premium::subscriptionOptions() const {
return _subscriptionOptions;
}

View File

@ -18,6 +18,49 @@ class Session;
namespace Api {
struct GiftCode {
PeerId from = 0;
PeerId to = 0;
MsgId giveawayId = 0;
TimeId date = 0;
TimeId used = 0; // 0 if not used.
int months = 0;
bool giveaway = false;
explicit operator bool() const {
return months != 0;
}
friend inline bool operator==(
const GiftCode&,
const GiftCode&) = default;
};
enum class GiveawayState {
Invalid,
Running,
Preparing,
Finished,
Refunded,
};
struct GiveawayInfo {
QString giftCode;
QString disallowedCountry;
ChannelId adminChannelId = 0;
GiveawayState state = GiveawayState::Invalid;
TimeId tooEarlyDate = 0;
TimeId finishDate = 0;
TimeId startDate = 0;
int winnersCount = 0;
int activatedCount = 0;
bool participating = false;
explicit operator bool() const {
return state != GiveawayState::Invalid;
}
};
class Premium final {
public:
explicit Premium(not_null<ApiWrap*> api);
@ -40,6 +83,19 @@ public:
[[nodiscard]] int64 monthlyAmount() const;
[[nodiscard]] QString monthlyCurrency() const;
void checkGiftCode(
const QString &slug,
Fn<void(GiftCode)> done);
GiftCode updateGiftCode(const QString &slug, const GiftCode &code);
[[nodiscard]] rpl::producer<GiftCode> giftCodeValue(
const QString &slug) const;
void applyGiftCode(const QString &slug, Fn<void(QString)> done);
void resolveGiveawayInfo(
not_null<PeerData*> peer,
MsgId messageId,
Fn<void(GiveawayInfo)> done);
[[nodiscard]] auto subscriptionOptions() const
-> const Data::SubscriptionOptions &;
@ -71,6 +127,16 @@ private:
int64 _monthlyAmount = 0;
QString _monthlyCurrency;
mtpRequestId _giftCodeRequestId = 0;
QString _giftCodeSlug;
base::flat_map<QString, GiftCode> _giftCodes;
rpl::event_stream<QString> _giftCodeUpdated;
mtpRequestId _giveawayInfoRequestId = 0;
PeerData *_giveawayInfoPeer = nullptr;
MsgId _giveawayInfoMessageId = 0;
Fn<void(GiveawayInfo)> _giveawayInfoDone;
Data::SubscriptionOptions _subscriptionOptions;
};

View File

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

View File

@ -270,7 +270,6 @@ bool SendDice(MessageToSend &message) {
flags |= MessageFlag::HasReplyInfo;
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
}
const auto replyHeader = NewMessageReplyHeader(message.action);
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, message.action.options);
InnerFillMessagePostFlags(message.action.options, peer, flags);
@ -368,9 +367,9 @@ void SendConfirmedFile(
if (!isEditing) {
const auto histories = &session->data().histories();
file->to.replyTo.msgId = histories->convertTopicReplyToId(
file->to.replyTo.messageId = histories->convertTopicReplyToId(
history,
file->to.replyTo.msgId);
file->to.replyTo.messageId);
file->to.replyTo.topicRootId = histories->convertTopicReplyToId(
history,
file->to.replyTo.topicRootId);
@ -399,7 +398,6 @@ void SendConfirmedFile(
if (file->to.replyTo) {
flags |= MessageFlag::HasReplyInfo;
}
const auto replyHeader = NewMessageReplyHeader(action);
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, file->to.options);
FillMessagePostFlags(action, peer, flags);

View File

@ -0,0 +1,594 @@
/*
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_statistics.h"
#include "apiwrap.h"
#include "data/data_channel.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "history/history.h"
#include "main/main_session.h"
#include "statistics/statistics_data_deserialize.h"
namespace Api {
namespace {
[[nodiscard]] Data::StatisticalGraph StatisticalGraphFromTL(
const MTPStatsGraph &tl) {
return tl.match([&](const MTPDstatsGraph &d) {
using namespace Statistic;
const auto zoomToken = d.vzoom_token().has_value()
? qs(*d.vzoom_token()).toUtf8()
: QByteArray();
return Data::StatisticalGraph{
StatisticalChartFromJSON(qs(d.vjson().data().vdata()).toUtf8()),
zoomToken,
};
}, [&](const MTPDstatsGraphAsync &data) {
return Data::StatisticalGraph{
.zoomToken = qs(data.vtoken()).toUtf8(),
};
}, [&](const MTPDstatsGraphError &data) {
return Data::StatisticalGraph{ .error = qs(data.verror()) };
});
}
[[nodiscard]] Data::StatisticalValue StatisticalValueFromTL(
const MTPStatsAbsValueAndPrev &tl) {
const auto current = tl.data().vcurrent().v;
const auto previous = tl.data().vprevious().v;
return Data::StatisticalValue{
.value = current,
.previousValue = previous,
.growthRatePercentage = previous
? std::abs((current - previous) / float64(previous) * 100.)
: 0,
};
}
[[nodiscard]] Data::ChannelStatistics ChannelStatisticsFromTL(
const MTPDstats_broadcastStats &data) {
const auto &tlUnmuted = data.venabled_notifications().data();
const auto unmuted = (!tlUnmuted.vtotal().v)
? 0.
: std::clamp(
tlUnmuted.vpart().v / tlUnmuted.vtotal().v * 100.,
0.,
100.);
using Recent = MTPMessageInteractionCounters;
auto recentMessages = ranges::views::all(
data.vrecent_message_interactions().v
) | ranges::views::transform([&](const Recent &tl) {
return Data::StatisticsMessageInteractionInfo{
.messageId = tl.data().vmsg_id().v,
.viewsCount = tl.data().vviews().v,
.forwardsCount = tl.data().vforwards().v,
};
}) | ranges::to_vector;
return {
.startDate = data.vperiod().data().vmin_date().v,
.endDate = data.vperiod().data().vmax_date().v,
.memberCount = StatisticalValueFromTL(data.vfollowers()),
.meanViewCount = StatisticalValueFromTL(data.vviews_per_post()),
.meanShareCount = StatisticalValueFromTL(data.vshares_per_post()),
.enabledNotificationsPercentage = unmuted,
.memberCountGraph = StatisticalGraphFromTL(
data.vgrowth_graph()),
.joinGraph = StatisticalGraphFromTL(
data.vfollowers_graph()),
.muteGraph = StatisticalGraphFromTL(
data.vmute_graph()),
.viewCountByHourGraph = StatisticalGraphFromTL(
data.vtop_hours_graph()),
.viewCountBySourceGraph = StatisticalGraphFromTL(
data.vviews_by_source_graph()),
.joinBySourceGraph = StatisticalGraphFromTL(
data.vnew_followers_by_source_graph()),
.languageGraph = StatisticalGraphFromTL(
data.vlanguages_graph()),
.messageInteractionGraph = StatisticalGraphFromTL(
data.vinteractions_graph()),
.instantViewInteractionGraph = StatisticalGraphFromTL(
data.viv_interactions_graph()),
.recentMessageInteractions = std::move(recentMessages),
};
}
[[nodiscard]] Data::SupergroupStatistics SupergroupStatisticsFromTL(
const MTPDstats_megagroupStats &data) {
using Senders = MTPStatsGroupTopPoster;
using Administrators = MTPStatsGroupTopAdmin;
using Inviters = MTPStatsGroupTopInviter;
auto topSenders = ranges::views::all(
data.vtop_posters().v
) | ranges::views::transform([&](const Senders &tl) {
return Data::StatisticsMessageSenderInfo{
.userId = UserId(tl.data().vuser_id().v),
.sentMessageCount = tl.data().vmessages().v,
.averageCharacterCount = tl.data().vavg_chars().v,
};
}) | ranges::to_vector;
auto topAdministrators = ranges::views::all(
data.vtop_admins().v
) | ranges::views::transform([&](const Administrators &tl) {
return Data::StatisticsAdministratorActionsInfo{
.userId = UserId(tl.data().vuser_id().v),
.deletedMessageCount = tl.data().vdeleted().v,
.bannedUserCount = tl.data().vkicked().v,
.restrictedUserCount = tl.data().vbanned().v,
};
}) | ranges::to_vector;
auto topInviters = ranges::views::all(
data.vtop_inviters().v
) | ranges::views::transform([&](const Inviters &tl) {
return Data::StatisticsInviterInfo{
.userId = UserId(tl.data().vuser_id().v),
.addedMemberCount = tl.data().vinvitations().v,
};
}) | ranges::to_vector;
return {
.startDate = data.vperiod().data().vmin_date().v,
.endDate = data.vperiod().data().vmax_date().v,
.memberCount = StatisticalValueFromTL(data.vmembers()),
.messageCount = StatisticalValueFromTL(data.vmessages()),
.viewerCount = StatisticalValueFromTL(data.vviewers()),
.senderCount = StatisticalValueFromTL(data.vposters()),
.memberCountGraph = StatisticalGraphFromTL(
data.vgrowth_graph()),
.joinGraph = StatisticalGraphFromTL(
data.vmembers_graph()),
.joinBySourceGraph = StatisticalGraphFromTL(
data.vnew_members_by_source_graph()),
.languageGraph = StatisticalGraphFromTL(
data.vlanguages_graph()),
.messageContentGraph = StatisticalGraphFromTL(
data.vmessages_graph()),
.actionGraph = StatisticalGraphFromTL(
data.vactions_graph()),
.dayGraph = StatisticalGraphFromTL(
data.vtop_hours_graph()),
.weekGraph = StatisticalGraphFromTL(
data.vweekdays_graph()),
.topSenders = std::move(topSenders),
.topAdministrators = std::move(topAdministrators),
.topInviters = std::move(topInviters),
};
}
} // namespace
Statistics::Statistics(not_null<ApiWrap*> api)
: _api(&api->instance()) {
}
rpl::producer<rpl::no_value, QString> Statistics::request(
not_null<PeerData*> peer) {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
const auto channel = peer->asChannel();
if (!channel) {
return lifetime;
}
if (!channel->isMegagroup()) {
_api.request(MTPstats_GetBroadcastStats(
MTP_flags(MTPstats_GetBroadcastStats::Flags(0)),
channel->inputChannel
)).done([=](const MTPstats_BroadcastStats &result) {
_channelStats = ChannelStatisticsFromTL(result.data());
consumer.put_done();
}).fail([=](const MTP::Error &error) {
consumer.put_error_copy(error.type());
}).send();
} else {
_api.request(MTPstats_GetMegagroupStats(
MTP_flags(MTPstats_GetMegagroupStats::Flags(0)),
channel->inputChannel
)).done([=](const MTPstats_MegagroupStats &result) {
_supergroupStats = SupergroupStatisticsFromTL(result.data());
peer->owner().processUsers(result.data().vusers());
consumer.put_done();
}).fail([=](const MTP::Error &error) {
consumer.put_error_copy(error.type());
}).send();
}
return lifetime;
};
}
Statistics::GraphResult Statistics::requestZoom(
not_null<PeerData*> peer,
const QString &token,
float64 x) {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
const auto channel = peer->asChannel();
if (!channel) {
return lifetime;
}
const auto wasEmpty = _zoomDeque.empty();
_zoomDeque.push_back([=] {
_api.request(MTPstats_LoadAsyncGraph(
MTP_flags(x
? MTPstats_LoadAsyncGraph::Flag::f_x
: MTPstats_LoadAsyncGraph::Flag(0)),
MTP_string(token),
MTP_long(x)
)).done([=](const MTPStatsGraph &result) {
consumer.put_next(StatisticalGraphFromTL(result));
consumer.put_done();
if (!_zoomDeque.empty()) {
_zoomDeque.pop_front();
if (!_zoomDeque.empty()) {
_zoomDeque.front()();
}
}
}).fail([=](const MTP::Error &error) {
consumer.put_error_copy(error.type());
}).send();
});
if (wasEmpty) {
_zoomDeque.front()();
}
return lifetime;
};
}
Statistics::GraphResult Statistics::requestMessage(
not_null<PeerData*> peer,
MsgId msgId) {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
const auto channel = peer->asChannel();
if (!channel) {
return lifetime;
}
_api.request(MTPstats_GetMessageStats(
MTP_flags(MTPstats_GetMessageStats::Flags(0)),
channel->inputChannel,
MTP_int(msgId.bare)
)).done([=](const MTPstats_MessageStats &result) {
consumer.put_next(
StatisticalGraphFromTL(result.data().vviews_graph()));
consumer.put_done();
}).fail([=](const MTP::Error &error) {
consumer.put_error_copy(error.type());
}).send();
return lifetime;
};
}
Data::ChannelStatistics Statistics::channelStats() const {
return _channelStats;
}
Data::SupergroupStatistics Statistics::supergroupStats() const {
return _supergroupStats;
}
PublicForwards::PublicForwards(
not_null<ChannelData*> channel,
FullMsgId fullId)
: _channel(channel)
, _fullId(fullId)
, _api(&channel->session().api().instance()) {
}
void PublicForwards::request(
const Data::PublicForwardsSlice::OffsetToken &token,
Fn<void(Data::PublicForwardsSlice)> done) {
if (_requestId) {
return;
}
const auto offsetPeer = _channel->owner().peer(token.fullId.peer);
const auto tlOffsetPeer = offsetPeer
? offsetPeer->input
: MTP_inputPeerEmpty();
constexpr auto kLimit = tl::make_int(100);
_requestId = _api.request(MTPstats_GetMessagePublicForwards(
_channel->inputChannel,
MTP_int(_fullId.msg),
MTP_int(token.rate),
tlOffsetPeer,
MTP_int(token.fullId.msg),
kLimit
)).done([=, channel = _channel](const MTPmessages_Messages &result) {
using Messages = QVector<FullMsgId>;
_requestId = 0;
auto nextToken = Data::PublicForwardsSlice::OffsetToken();
const auto process = [&](const MTPVector<MTPMessage> &messages) {
auto result = Messages();
for (const auto &message : messages.v) {
const auto msgId = IdFromMessage(message);
const auto peerId = PeerFromMessage(message);
const auto lastDate = DateFromMessage(message);
if (const auto peer = channel->owner().peerLoaded(peerId)) {
if (lastDate) {
channel->owner().addNewMessage(
message,
MessageFlags(),
NewMessageType::Existing);
nextToken.fullId = { peerId, msgId };
result.push_back(nextToken.fullId);
}
}
}
return result;
};
auto allLoaded = false;
auto fullCount = 0;
auto messages = result.match([&](const MTPDmessages_messages &data) {
channel->owner().processUsers(data.vusers());
channel->owner().processChats(data.vchats());
auto list = process(data.vmessages());
allLoaded = true;
fullCount = list.size();
return list;
}, [&](const MTPDmessages_messagesSlice &data) {
channel->owner().processUsers(data.vusers());
channel->owner().processChats(data.vchats());
auto list = process(data.vmessages());
if (const auto nextRate = data.vnext_rate()) {
const auto rateUpdated = (nextRate->v != token.rate);
if (rateUpdated) {
nextToken.rate = nextRate->v;
} else {
allLoaded = true;
}
}
fullCount = data.vcount().v;
return list;
}, [&](const MTPDmessages_channelMessages &data) {
channel->owner().processUsers(data.vusers());
channel->owner().processChats(data.vchats());
auto list = process(data.vmessages());
allLoaded = true;
fullCount = data.vcount().v;
return list;
}, [&](const MTPDmessages_messagesNotModified &) {
allLoaded = true;
return Messages();
});
_lastTotal = std::max(_lastTotal, fullCount);
done({
.list = std::move(messages),
.total = _lastTotal,
.allLoaded = allLoaded,
.token = nextToken,
});
}).fail([=] {
_requestId = 0;
}).send();
}
MessageStatistics::MessageStatistics(
not_null<ChannelData*> channel,
FullMsgId fullId)
: _publicForwards(channel, fullId)
, _channel(channel)
, _fullId(fullId)
, _api(&channel->session().api().instance()) {
}
Data::PublicForwardsSlice MessageStatistics::firstSlice() const {
return _firstSlice;
}
void MessageStatistics::request(Fn<void(Data::MessageStatistics)> done) {
if (_channel->isMegagroup()) {
return;
}
const auto requestFirstPublicForwards = [=](
const Data::StatisticalGraph &messageGraph,
const Data::StatisticsMessageInteractionInfo &info) {
_publicForwards.request({}, [=](Data::PublicForwardsSlice slice) {
const auto total = slice.total;
_firstSlice = std::move(slice);
done({
.messageInteractionGraph = messageGraph,
.publicForwards = total,
.privateForwards = info.forwardsCount - total,
.views = info.viewsCount,
});
});
};
const auto requestPrivateForwards = [=](
const Data::StatisticalGraph &messageGraph) {
_api.request(MTPchannels_GetMessages(
_channel->inputChannel,
MTP_vector<MTPInputMessage>(
1,
MTP_inputMessageID(MTP_int(_fullId.msg))))
).done([=](const MTPmessages_Messages &result) {
const auto process = [&](const MTPVector<MTPMessage> &messages) {
const auto &message = messages.v.front();
return message.match([&](const MTPDmessage &data) {
return Data::StatisticsMessageInteractionInfo{
.messageId = IdFromMessage(message),
.viewsCount = data.vviews()
? data.vviews()->v
: 0,
.forwardsCount = data.vforwards()
? data.vforwards()->v
: 0,
};
}, [](const MTPDmessageEmpty &) {
return Data::StatisticsMessageInteractionInfo();
}, [](const MTPDmessageService &) {
return Data::StatisticsMessageInteractionInfo();
});
};
auto info = result.match([&](const MTPDmessages_messages &data) {
return process(data.vmessages());
}, [&](const MTPDmessages_messagesSlice &data) {
return process(data.vmessages());
}, [&](const MTPDmessages_channelMessages &data) {
return process(data.vmessages());
}, [](const MTPDmessages_messagesNotModified &) {
return Data::StatisticsMessageInteractionInfo();
});
requestFirstPublicForwards(messageGraph, std::move(info));
}).fail([=](const MTP::Error &error) {
requestFirstPublicForwards(messageGraph, {});
}).send();
};
_api.request(MTPstats_GetMessageStats(
MTP_flags(MTPstats_GetMessageStats::Flags(0)),
_channel->inputChannel,
MTP_int(_fullId.msg.bare)
)).done([=](const MTPstats_MessageStats &result) {
requestPrivateForwards(
StatisticalGraphFromTL(result.data().vviews_graph()));
}).fail([=](const MTP::Error &error) {
requestPrivateForwards({});
}).send();
}
Boosts::Boosts(not_null<PeerData*> peer)
: _peer(peer)
, _api(&peer->session().api().instance()) {
}
rpl::producer<rpl::no_value, QString> Boosts::request() {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
const auto channel = _peer->asChannel();
if (!channel || channel->isMegagroup()) {
return lifetime;
}
_api.request(MTPpremium_GetBoostsStatus(
_peer->input
)).done([=](const MTPpremium_BoostsStatus &result) {
const auto &data = result.data();
const auto hasPremium = !!data.vpremium_audience();
const auto premiumMemberCount = hasPremium
? std::max(0, int(data.vpremium_audience()->data().vpart().v))
: 0;
const auto participantCount = hasPremium
? std::max(
int(data.vpremium_audience()->data().vtotal().v),
premiumMemberCount)
: 0;
const auto premiumMemberPercentage = (participantCount > 0)
? (100. * premiumMemberCount / participantCount)
: 0;
_boostStatus.overview = Data::BoostsOverview{
.isBoosted = data.is_my_boost(),
.level = std::max(data.vlevel().v, 0),
.boostCount = std::max(
data.vboosts().v,
data.vcurrent_level_boosts().v),
.currentLevelBoostCount = data.vcurrent_level_boosts().v,
.nextLevelBoostCount = data.vnext_level_boosts()
? data.vnext_level_boosts()->v
: 0,
.premiumMemberCount = premiumMemberCount,
.premiumMemberPercentage = premiumMemberPercentage,
};
_boostStatus.link = qs(data.vboost_url());
requestBoosts({}, [=](Data::BoostsListSlice &&slice) {
_boostStatus.firstSlice = std::move(slice);
consumer.put_done();
});
}).fail([=](const MTP::Error &error) {
consumer.put_error_copy(error.type());
}).send();
return lifetime;
};
}
void Boosts::requestBoosts(
const Data::BoostsListSlice::OffsetToken &token,
Fn<void(Data::BoostsListSlice)> done) {
if (_requestId) {
return;
}
constexpr auto kTlFirstSlice = tl::make_int(kFirstSlice);
constexpr auto kTlLimit = tl::make_int(kLimit);
_requestId = _api.request(MTPpremium_GetBoostsList(
MTP_flags(0),
_peer->input,
MTP_string(token.next),
token.next.isEmpty() ? kTlFirstSlice : kTlLimit
)).done([=](const MTPpremium_BoostsList &result) {
_requestId = 0;
const auto &data = result.data();
_peer->owner().processUsers(data.vusers());
auto list = std::vector<Data::Boost>();
list.reserve(data.vboosts().v.size());
for (const auto &boost : data.vboosts().v) {
list.push_back({
boost.data().vuser_id().value_or_empty(),
QDateTime::fromSecsSinceEpoch(boost.data().vexpires().v),
});
}
done(Data::BoostsListSlice{
.list = std::move(list),
.total = data.vcount().v,
.allLoaded = (data.vcount().v == data.vboosts().v.size()),
.token = Data::BoostsListSlice::OffsetToken{
data.vnext_offset()
? qs(*data.vnext_offset())
: QString()
},
});
}).fail([=] {
_requestId = 0;
}).send();
}
Data::BoostStatus Boosts::boostStatus() const {
return _boostStatus;
}
} // namespace Api

View File

@ -0,0 +1,110 @@
/*
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_boosts.h"
#include "data/data_statistics.h"
#include "mtproto/sender.h"
class ApiWrap;
class ChannelData;
class PeerData;
namespace Api {
class Statistics final {
public:
explicit Statistics(not_null<ApiWrap*> api);
[[nodiscard]] rpl::producer<rpl::no_value, QString> request(
not_null<PeerData*> peer);
using GraphResult = rpl::producer<Data::StatisticalGraph, QString>;
[[nodiscard]] GraphResult requestZoom(
not_null<PeerData*> peer,
const QString &token,
float64 x);
[[nodiscard]] GraphResult requestMessage(
not_null<PeerData*> peer,
MsgId msgId);
[[nodiscard]] Data::ChannelStatistics channelStats() const;
[[nodiscard]] Data::SupergroupStatistics supergroupStats() const;
private:
Data::ChannelStatistics _channelStats;
Data::SupergroupStatistics _supergroupStats;
MTP::Sender _api;
std::deque<Fn<void()>> _zoomDeque;
};
class PublicForwards final {
public:
explicit PublicForwards(not_null<ChannelData*> channel, FullMsgId fullId);
void request(
const Data::PublicForwardsSlice::OffsetToken &token,
Fn<void(Data::PublicForwardsSlice)> done);
private:
const not_null<ChannelData*> _channel;
const FullMsgId _fullId;
mtpRequestId _requestId = 0;
int _lastTotal = 0;
MTP::Sender _api;
};
class MessageStatistics final {
public:
explicit MessageStatistics(
not_null<ChannelData*> channel,
FullMsgId fullId);
void request(Fn<void(Data::MessageStatistics)> done);
[[nodiscard]] Data::PublicForwardsSlice firstSlice() const;
private:
PublicForwards _publicForwards;
const not_null<ChannelData*> _channel;
const FullMsgId _fullId;
Data::PublicForwardsSlice _firstSlice;
mtpRequestId _requestId = 0;
MTP::Sender _api;
};
class Boosts final {
public:
explicit Boosts(not_null<PeerData*> peer);
[[nodiscard]] rpl::producer<rpl::no_value, QString> request();
void requestBoosts(
const Data::BoostsListSlice::OffsetToken &token,
Fn<void(Data::BoostsListSlice)> done);
[[nodiscard]] Data::BoostStatus boostStatus() const;
static constexpr auto kFirstSlice = int(10);
static constexpr auto kLimit = int(40);
private:
const not_null<PeerData*> _peer;
Data::BoostStatus _boostStatus;
MTP::Sender _api;
mtpRequestId _requestId = 0;
};
} // namespace Api

View File

@ -114,6 +114,7 @@ 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_messageEntityBlockquote: { auto &d = entity.c_messageEntityBlockquote(); result.push_back({ EntityType::Blockquote, d.voffset().v, d.vlength().v }); } break;
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;
case mtpc_messageEntityCustomEmoji: {
@ -142,6 +143,7 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(
&& entity.type() != EntityType::StrikeOut
&& entity.type() != EntityType::Code // #TODO entities
&& entity.type() != EntityType::Pre
&& entity.type() != EntityType::Blockquote
&& entity.type() != EntityType::Spoiler
&& entity.type() != EntityType::MentionName
&& entity.type() != EntityType::CustomUrl
@ -170,6 +172,7 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(
case EntityType::StrikeOut: v.push_back(MTP_messageEntityStrike(offset, length)); break;
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::Blockquote: v.push_back(MTP_messageEntityBlockquote(offset, length)); break;
case EntityType::Spoiler: v.push_back(MTP_messageEntitySpoiler(offset, length)); break;
case EntityType::CustomEmoji: {
if (const auto valid = CustomEmojiEntity(offset, length, entity.data())) {

View File

@ -2071,7 +2071,10 @@ void Updates::feedUpdate(const MTPUpdate &update) {
windows.front()->window().show(Ui::MakeInformBox(text));
}
} else {
session().data().serviceNotification(text, d.vmedia());
session().data().serviceNotification(
text,
d.vmedia(),
d.is_invert_media());
session().api().authorizations().reload();
}
} break;

View File

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

View File

@ -776,10 +776,9 @@ QString ApiWrap::exportDirectMessageLink(
QString ApiWrap::exportDirectStoryLink(not_null<Data::Story*> story) {
const auto storyId = story->fullId();
const auto user = story->peer()->asUser();
Assert(user != nullptr);
const auto peer = story->peer();
const auto fallback = [&] {
const auto base = user->username();
const auto base = peer->userName();
const auto story = QString::number(storyId.story);
const auto query = base + "/s/" + story;
return session().createInternalLinkFull(query);
@ -789,7 +788,7 @@ QString ApiWrap::exportDirectStoryLink(not_null<Data::Story*> story) {
? i->second
: fallback();
request(MTPstories_ExportStoryLink(
story->peer()->asUser()->inputUser,
peer->input,
MTP_int(story->id())
)).done([=](const MTPExportedStoryLink &result) {
const auto link = qs(result.data().vlink());
@ -1887,17 +1886,8 @@ void ApiWrap::sendNotifySettingsUpdates() {
}
const auto &settings = session().data().notifySettings();
for (const auto type : base::take(_updateNotifyDefaults)) {
const auto input = [&] {
switch (type) {
case Data::DefaultNotify::User: return MTP_inputNotifyUsers();
case Data::DefaultNotify::Group: return MTP_inputNotifyChats();
case Data::DefaultNotify::Broadcast:
return MTP_inputNotifyBroadcasts();
}
Unexpected("Default notify type in sendNotifySettingsUpdates");
}();
request(MTPaccount_UpdateNotifySettings(
input,
Data::DefaultNotifyToMTP(type),
settings.defaultSettings(type).serialize()
)).afterDelay(kSmallDelayMs).send();
}
@ -2145,14 +2135,13 @@ void ApiWrap::saveDraftsToCloud() {
auto flags = MTPmessages_SaveDraft::Flags(0);
auto &textWithTags = cloudDraft->textWithTags;
if (cloudDraft->previewState != Data::PreviewState::Allowed) {
if (cloudDraft->webpage.removed) {
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
} else if (!cloudDraft->webpage.url.isEmpty()) {
flags |= MTPmessages_SaveDraft::Flag::f_media;
}
if (cloudDraft->msgId) {
flags |= MTPmessages_SaveDraft::Flag::f_reply_to_msg_id;
}
if (cloudDraft->topicRootId) {
flags |= MTPmessages_SaveDraft::Flag::f_top_msg_id;
if (cloudDraft->reply.messageId || cloudDraft->reply.topicRootId) {
flags |= MTPmessages_SaveDraft::Flag::f_reply_to;
}
if (!textWithTags.tags.isEmpty()) {
flags |= MTPmessages_SaveDraft::Flag::f_entities;
@ -2165,11 +2154,13 @@ void ApiWrap::saveDraftsToCloud() {
history->startSavingCloudDraft(topicRootId);
cloudDraft->saveRequestId = request(MTPmessages_SaveDraft(
MTP_flags(flags),
MTP_int(cloudDraft->msgId),
MTP_int(cloudDraft->topicRootId),
ReplyToForMTP(history, cloudDraft->reply),
history->peer->input,
MTP_string(textWithTags.text),
entities
entities,
Data::WebPageForMTP(
cloudDraft->webpage,
textWithTags.text.isEmpty())
)).done([=](const MTPBool &result, const MTP::Response &response) {
const auto requestId = response.requestId;
history->finishSavingCloudDraft(
@ -2256,7 +2247,7 @@ void ApiWrap::gotStickerSet(
}
void ApiWrap::requestWebPageDelayed(not_null<WebPageData*> page) {
if (page->pendingTill <= 0) {
if (page->failed || !page->pendingTill) {
return;
}
_webPagesPending.emplace(page, 0);
@ -2445,7 +2436,13 @@ void ApiWrap::refreshFileReference(
};
v::match(origin.data, [&](Data::FileOriginMessage data) {
if (const auto item = _session->data().message(data)) {
if (item->isScheduled()) {
const auto media = item->media();
const auto storyId = media ? media->storyId() : FullStoryId();
if (storyId) {
request(MTPstories_GetStoriesByID(
_session->data().peer(storyId.peer)->input,
MTP_vector<MTPint>(1, MTP_int(storyId.story))));
} else if (item->isScheduled()) {
const auto &scheduled = _session->data().scheduledMessages();
const auto realId = scheduled.lookupId(item);
request(MTPmessages_GetScheduledMessages(
@ -2542,14 +2539,9 @@ void ApiWrap::refreshFileReference(
}, [&](Data::FileOriginPremiumPreviews data) {
request(MTPhelp_GetPremiumPromo());
}, [&](Data::FileOriginStory data) {
const auto user = _session->data().peer(data.peerId)->asUser();
if (user) {
request(MTPstories_GetStoriesByID(
user->inputUser,
MTP_vector<MTPint>(1, MTP_int(data.storyId))));
} else {
fail();
}
request(MTPstories_GetStoriesByID(
_session->data().peer(data.peerId)->input,
MTP_vector<MTPint>(1, MTP_int(data.storyId))));
}, [&](v::null_t) {
fail();
});
@ -2560,7 +2552,8 @@ void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &resu
for (auto i = _webPagesPending.begin(); i != _webPagesPending.cend();) {
if (i->second == req) {
if (i->first->pendingTill > 0) {
i->first->pendingTill = -1;
i->first->pendingTill = 0;
i->first->failed = 1;
_session->data().notifyWebPageUpdateDelayed(i->first);
}
i = _webPagesPending.erase(i);
@ -3329,25 +3322,37 @@ void ApiWrap::shareContact(
const QString &phone,
const QString &firstName,
const QString &lastName,
const SendAction &action) {
const SendAction &action,
Fn<void(bool)> done) {
const auto userId = UserId(0);
sendSharedContact(phone, firstName, lastName, userId, action);
sendSharedContact(
phone,
firstName,
lastName,
userId,
action,
std::move(done));
}
void ApiWrap::shareContact(
not_null<UserData*> user,
const SendAction &action) {
const SendAction &action,
Fn<void(bool)> done) {
const auto userId = peerToUser(user->id);
const auto phone = _session->data().findContactPhone(user);
if (phone.isEmpty()) {
if (done) {
done(false);
}
return;
}
sendSharedContact(
return sendSharedContact(
phone,
user->firstName,
user->lastName,
userId,
action);
action,
std::move(done));
}
void ApiWrap::sendSharedContact(
@ -3355,7 +3360,8 @@ void ApiWrap::sendSharedContact(
const QString &firstName,
const QString &lastName,
UserId userId,
const SendAction &action) {
const SendAction &action,
Fn<void(bool)> done) {
sendAction(action);
const auto history = action.history;
@ -3370,7 +3376,6 @@ void ApiWrap::sendSharedContact(
if (action.replyTo) {
flags |= MessageFlag::HasReplyInfo;
}
const auto replyHeader = NewMessageReplyHeader(action);
FillMessagePostFlags(action, peer, flags);
if (action.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled;
@ -3406,7 +3411,7 @@ void ApiWrap::sendSharedContact(
MTP_string(firstName),
MTP_string(lastName),
MTP_string()); // vcard
sendMedia(item, media, action.options);
sendMedia(item, media, action.options, std::move(done));
_session->data().sendHistoryChangeNotifications();
_session->changes().historyUpdated(
@ -3574,15 +3579,8 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
action.generateLocal = true;
sendAction(action);
const auto replyToId = action.replyTo.msgId;
const auto replyTo = replyToId
? peer->owner().message(peer, replyToId)
: nullptr;
const auto topicRootId = replyTo
? replyTo->topicRootId()
: action.replyTo.topicRootId
? action.replyTo.topicRootId
: Data::ForumTopic::kGeneralId;
const auto clearCloudDraft = action.clearDraft;
const auto topicRootId = action.replyTo.topicRootId;
const auto topic = peer->forumTopicFor(topicRootId);
if (!(topic ? Data::CanSendTexts(topic) : Data::CanSendTexts(peer))
|| Api::SendDice(message)) {
@ -3604,7 +3602,13 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
auto &histories = history->owner().histories();
while (TextUtilities::CutPart(sending, left, MaxMessageSize)) {
const auto exactWebPage = !message.webPage.url.isEmpty();
auto isFirst = true;
while (TextUtilities::CutPart(sending, left, MaxMessageSize)
|| (isFirst && exactWebPage)) {
TextUtilities::Trim(left);
const auto isLast = left.empty();
auto newId = FullMsgId(
peer->id,
_session->data().nextLocalMessageId());
@ -3618,26 +3622,51 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
MTPstring msgText(MTP_string(sending.text));
auto flags = NewMessageFlags(peer);
auto sendFlags = MTPmessages_SendMessage::Flags(0);
auto mediaFlags = MTPmessages_SendMedia::Flags(0);
if (action.replyTo) {
flags |= MessageFlag::HasReplyInfo;
sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to;
mediaFlags |= MTPmessages_SendMedia::Flag::f_reply_to;
}
const auto replyHeader = NewMessageReplyHeader(action);
const auto ignoreWebPage = message.webPage.removed
|| (exactWebPage && !isLast);
const auto manualWebPage = exactWebPage
&& !ignoreWebPage
&& (message.webPage.manual || (isLast && !isFirst));
MTPMessageMedia media = MTP_messageMediaEmpty();
if (message.webPageId == CancelledWebPageId) {
if (ignoreWebPage) {
sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage;
} else if (message.webPageId) {
auto page = _session->data().webpage(message.webPageId);
} else if (exactWebPage) {
using PageFlag = MTPDmessageMediaWebPage::Flag;
using PendingFlag = MTPDwebPagePending::Flag;
const auto &fields = message.webPage;
const auto page = _session->data().webpage(fields.id);
media = MTP_messageMediaWebPage(
MTP_flags(PageFlag()
| (manualWebPage ? PageFlag::f_manual : PageFlag())
| (fields.forceLargeMedia
? PageFlag::f_force_large_media
: PageFlag())
| (fields.forceSmallMedia
? PageFlag::f_force_small_media
: PageFlag())),
MTP_webPagePending(
MTP_long(page->id),
MTP_flags(PendingFlag::f_url),
MTP_long(fields.id),
MTP_string(fields.url),
MTP_int(page->pendingTill)));
}
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, action.options);
FillMessagePostFlags(action, peer, flags);
if (exactWebPage && !ignoreWebPage && message.webPage.invert) {
flags |= MessageFlag::InvertMedia;
sendFlags |= MTPmessages_SendMessage::Flag::f_invert_media;
mediaFlags |= MTPmessages_SendMedia::Flag::f_invert_media;
}
if (silentPost) {
sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
mediaFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
const auto sentEntities = Api::EntitiesToMTP(
_session,
@ -3645,11 +3674,11 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
Api::ConvertOption::SkipLocal);
if (!sentEntities.v.isEmpty()) {
sendFlags |= MTPmessages_SendMessage::Flag::f_entities;
mediaFlags |= MTPmessages_SendMedia::Flag::f_entities;
}
const auto clearCloudDraft = action.clearDraft;
const auto topicRootId = action.replyTo.topicRootId;
if (clearCloudDraft) {
sendFlags |= MTPmessages_SendMessage::Flag::f_clear_draft;
mediaFlags |= MTPmessages_SendMedia::Flag::f_clear_draft;
history->clearCloudDraft(topicRootId);
history->startSavingCloudDraft(topicRootId);
}
@ -3661,6 +3690,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
: _session->userPeerId();
if (sendAs) {
sendFlags |= MTPmessages_SendMessage::Flag::f_send_as;
mediaFlags |= MTPmessages_SendMedia::Flag::f_send_as;
}
const auto messagePostAuthor = peer->isBroadcast()
? _session->user()->name()
@ -3668,6 +3698,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
if (action.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled;
sendFlags |= MTPmessages_SendMessage::Flag::f_schedule_date;
mediaFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
}
const auto viaBotId = UserId();
lastMessage = history->addNewLocalMessage(
@ -3681,27 +3712,18 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
sending,
media,
HistoryMessageMarkupData());
histories.sendPreparedMessage(
history,
action.replyTo,
randomId,
Data::Histories::PrepareMessage<MTPmessages_SendMessage>(
MTP_flags(sendFlags),
peer->input,
Data::Histories::ReplyToPlaceholder(),
msgText,
MTP_long(randomId),
MTPReplyMarkup(),
sentEntities,
MTP_int(action.options.scheduled),
(sendAs ? sendAs->input : MTP_inputPeerEmpty())
), [=](const MTPUpdates &result, const MTP::Response &response) {
const auto done = [=](
const MTPUpdates &result,
const MTP::Response &response) {
if (clearCloudDraft) {
history->finishSavingCloudDraft(
topicRootId,
UnixtimeFromMsgId(response.outerMsgId));
}
}, [=](const MTP::Error &error, const MTP::Response &response) {
};
const auto fail = [=](
const MTP::Error &error,
const MTP::Response &response) {
if (error.type() == u"MESSAGE_EMPTY"_q) {
lastMessage->destroy();
} else {
@ -3712,7 +3734,44 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
topicRootId,
UnixtimeFromMsgId(response.outerMsgId));
}
});
};
if (exactWebPage
&& !ignoreWebPage
&& (manualWebPage || sending.empty())) {
histories.sendPreparedMessage(
history,
action.replyTo,
randomId,
Data::Histories::PrepareMessage<MTPmessages_SendMedia>(
MTP_flags(mediaFlags),
peer->input,
Data::Histories::ReplyToPlaceholder(),
Data::WebPageForMTP(message.webPage, true),
msgText,
MTP_long(randomId),
MTPReplyMarkup(),
sentEntities,
MTP_int(message.action.options.scheduled),
(sendAs ? sendAs->input : MTP_inputPeerEmpty())
), done, fail);
} else {
histories.sendPreparedMessage(
history,
action.replyTo,
randomId,
Data::Histories::PrepareMessage<MTPmessages_SendMessage>(
MTP_flags(sendFlags),
peer->input,
Data::Histories::ReplyToPlaceholder(),
msgText,
MTP_long(randomId),
MTPReplyMarkup(),
sentEntities,
MTP_int(action.options.scheduled),
(sendAs ? sendAs->input : MTP_inputPeerEmpty())
), done, fail);
}
isFirst = false;
}
finishForwarding(action);
@ -3777,7 +3836,7 @@ void ApiWrap::sendInlineResult(
? (*localMessageId)
: _session->data().nextLocalMessageId());
const auto randomId = base::RandomValue<uint64>();
const auto topicRootId = action.replyTo.msgId
const auto topicRootId = action.replyTo.messageId
? action.replyTo.topicRootId
: 0;
@ -3937,18 +3996,20 @@ void ApiWrap::uploadAlbumMedia(
void ApiWrap::sendMedia(
not_null<HistoryItem*> item,
const MTPInputMedia &media,
Api::SendOptions options) {
Api::SendOptions options,
Fn<void(bool)> done) {
const auto randomId = base::RandomValue<uint64>();
_session->data().registerMessageRandomId(randomId, item->fullId());
sendMediaWithRandomId(item, media, options, randomId);
sendMediaWithRandomId(item, media, options, randomId, std::move(done));
}
void ApiWrap::sendMediaWithRandomId(
not_null<HistoryItem*> item,
const MTPInputMedia &media,
Api::SendOptions options,
uint64 randomId) {
uint64 randomId,
Fn<void(bool)> done) {
const auto history = item->history();
const auto replyTo = item->replyTo();
@ -3990,10 +4051,12 @@ void ApiWrap::sendMediaWithRandomId(
MTP_int(options.scheduled),
(options.sendAs ? options.sendAs->input : MTP_inputPeerEmpty())
), [=](const MTPUpdates &result, const MTP::Response &response) {
if (done) done(true);
if (updateRecentStickers) {
requestRecentStickersForce(true);
}
}, [=](const MTP::Error &error, const MTP::Response &response) {
if (done) done(false);
sendMessageFail(error, peer, randomId, itemId);
});
}

View File

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

View File

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

View File

@ -175,7 +175,8 @@ BackgroundPreviewBox::BackgroundPreviewBox(
, _controller(controller)
, _forPeer(args.forPeer)
, _fromMessageId(args.fromMessageId)
, _chatStyle(std::make_unique<Ui::ChatStyle>())
, _chatStyle(std::make_unique<Ui::ChatStyle>(
controller->session().colorIndicesValue()))
, _serviceHistory(_controller->session().data().history(
PeerData::kServiceNotificationsId))
, _service(nullptr)
@ -434,7 +435,7 @@ void BackgroundPreviewBox::rebuildButtons(bool dark) {
clearButtons();
addButton(_forPeer
? tr::lng_background_apply_button()
: tr::lng_background_apply(), [=] { apply(); });
: tr::lng_settings_apply(), [=] { apply(); });
addButton(tr::lng_cancel(), [=] { closeBox(); });
if (!_forPeer && _paper.hasShareUrl()) {
addLeftButton(tr::lng_background_share(), [=] { share(); });

View File

@ -85,8 +85,6 @@ confirmInviteTitle: FlatLabel(defaultFlatLabel) {
textFg: windowBoldFg;
style: TextStyle(defaultTextStyle) {
font: font(18px semibold);
linkFont: font(18px semibold);
linkFontOver: font(18px semibold underline);
}
}
confirmInviteAbout: FlatLabel(boxLabel) {
@ -143,8 +141,6 @@ contactsPadding: margins(16px, 7px, 16px, 7px);
contactsNameTop: 2px;
contactsNameStyle: TextStyle(defaultTextStyle) {
font: semiboldFont;
linkFont: semiboldFont;
linkFontOver: semiboldFont;
}
contactsStatusTop: 23px;
contactsStatusFont: font(fsize);
@ -199,8 +195,6 @@ localStorageRowTitle: FlatLabel(defaultFlatLabel) {
maxHeight: 20px;
style: TextStyle(defaultTextStyle) {
font: font(14px semibold);
linkFont: font(14px semibold);
linkFontOver: font(14px semibold);
}
}
localStorageRowSize: FlatLabel(defaultFlatLabel) {
@ -208,8 +202,6 @@ localStorageRowSize: FlatLabel(defaultFlatLabel) {
maxHeight: 20px;
style: TextStyle(defaultTextStyle) {
font: font(14px);
linkFont: font(14px);
linkFontOver: font(14px);
}
}
localStorageClear: defaultBoxButton;
@ -228,8 +220,6 @@ sharePhotoTop: 6px;
shareBoxListItem: PeerListItem(defaultPeerListItem) {
nameStyle: TextStyle(defaultTextStyle) {
font: font(11px);
linkFont: font(11px);
linkFontOver: font(11px);
}
nameFg: windowFg;
nameFgChecked: windowActiveTextFg;
@ -537,8 +527,6 @@ adminLogFilterLittleSkip: 16px;
adminLogFilterCheckbox: Checkbox(defaultBoxCheckbox) {
style: TextStyle(boxTextStyle) {
font: font(boxFontSize semibold);
linkFont: font(boxFontSize semibold);
linkFontOver: font(boxFontSize semibold underline);
}
}
adminLogFilterSkip: 32px;
@ -580,16 +568,12 @@ rightsPhotoButton: UserpicButton(defaultUserpicButton) {
rightsPhotoMargin: margins(20px, 0px, 15px, 18px);
rightsNameStyle: TextStyle(semiboldTextStyle) {
font: font(15px semibold);
linkFont: font(15px semibold);
linkFontOver: font(15px semibold underline);
}
rightsNameTop: 8px;
rightsStatusTop: 32px;
rightsHeaderLabel: FlatLabel(boxLabel) {
style: TextStyle(semiboldTextStyle) {
font: font(boxFontSize semibold);
linkFont: font(boxFontSize semibold);
linkFontOver: font(boxFontSize semibold underline);
}
textFg: windowActiveTextFg;
}
@ -623,8 +607,6 @@ proxyRowTitlePalette: TextPalette(defaultTextPalette) {
}
proxyRowTitleStyle: TextStyle(defaultTextStyle) {
font: semiboldFont;
linkFont: normalFont;
linkFontOver: normalFont;
}
proxyRowStatusFg: windowSubTextFg;
proxyRowStatusFgOnline: windowActiveTextFg;
@ -807,8 +789,6 @@ pollResultsQuestion: FlatLabel(defaultFlatLabel) {
textFg: windowBoldFg;
style: TextStyle(defaultTextStyle) {
font: font(16px semibold);
linkFont: font(16px semibold);
linkFontOver: font(16px semibold underline);
}
}
pollResultsVotesCount: FlatLabel(defaultFlatLabel) {
@ -837,8 +817,6 @@ inviteViaLinkButton: SettingsButton(defaultSettingsButton) {
style: TextStyle(defaultTextStyle) {
font: font(14px semibold);
linkFont: font(14px semibold);
linkFontOver: font(14px semibold underline);
}
height: 20px;

View File

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

View File

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

View File

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

View File

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

View File

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

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