Compare commits

..

251 Commits

Author SHA1 Message Date
AlexeyZavar cc494fee22 fix: less with upload boost 2024-04-02 18:02:38 +03:00
AlexeyZavar d0f793c06d chore: sync linux doc 2024-04-02 17:51:33 +03:00
AlexeyZavar fc447bfd51 fix: enable by default since it's stable 2024-04-02 17:34:59 +03:00
AlexeyZavar fe463ab8fb feat: implement useScheduleMessages fully 2024-04-02 17:34:06 +03:00
AlexeyZavar 6fd0fb9704 feat: simplify markReadAfterAction 2024-04-02 16:37:16 +03:00
AlexeyZavar ce00b3d950 chore: sync strings 2024-04-02 16:17:11 +03:00
AlexeyZavar a87fb9160c fix: message shot crashes 2024-04-02 02:57:01 +03:00
AlexeyZavar 132caa18c9 fix: move out AyuGram files for consistency
fix: compiler warning
2024-04-02 02:13:32 +03:00
AlexeyZavar 6257e990a1 fix: make it build 2024-04-02 01:56:53 +03:00
AlexeyZavar c6b42e2940 Merge tag 'v4.16.0' into dev
# Conflicts:
#	README.md
#	Telegram/Resources/winrc/Telegram.rc
#	Telegram/Resources/winrc/Updater.rc
#	Telegram/SourceFiles/calls/calls_call.cpp
#	Telegram/SourceFiles/core/local_url_handlers.cpp
#	Telegram/SourceFiles/core/version.h
#	Telegram/SourceFiles/history/view/media/history_view_giveaway.cpp
#	Telegram/SourceFiles/history/view/media/history_view_sticker.cpp
#	Telegram/lib_ui
#	snap/snapcraft.yaml
2024-04-01 23:56:12 +03:00
John Preston 707146daed Version 4.16.
- Instant View on Windows 10+ and macOS.
- Allow scheduling messages in topics.
- Telegram Business: Links to Chats.
- Telegram Business: Custom Intro.
- Telegram Business: Chatbots.
- Sharing Revenue with Channel Owners.
2024-04-01 23:27:35 +04:00
John Preston c0117e72ad Support complex invite-users responses. 2024-04-01 22:44:26 +04:00
John Preston 3cdb528dfe Use "Downloads/Telegram Lite" in MacAppStore version. 2024-04-01 22:44:26 +04:00
John Preston d2164dc0d0 Suggest premiums in privacy. 2024-04-01 22:44:26 +04:00
John Preston 87acc921c3 Pass Ui::Show to all add participant handlers. 2024-04-01 22:44:26 +04:00
John Preston 5741bd9cca Support "premiums and ..." privacy editing. 2024-04-01 22:44:25 +04:00
John Preston 1e6fb202f0 Re-apply "Disable system proxy support on Linux".
This reverts commit c71c24a6bc.
2024-04-01 22:44:25 +04:00
John Preston 8cbb1abff2 Fix wrong non-album image size in send preview.
Regression was introduced in 84288112fc.
2024-04-01 22:44:25 +04:00
John Preston d21418cf04 Handle already-premium state in gift link usage. 2024-04-01 22:44:25 +04:00
John Preston d35c8232d2 Fix send-messages privacy phrase. 2024-04-01 22:44:25 +04:00
John Preston 139d1a9aa3 Allow saving just the sticker in custom intro. 2024-04-01 22:44:25 +04:00
John Preston f95817861a Fix build on Windows. 2024-04-01 22:44:25 +04:00
23rd 3e968aecc8 Added link for learn more about currency from channel earn section. 2024-04-01 22:44:25 +04:00
23rd 2795af8c7f Slightly improved style of channel earn info section. 2024-04-01 22:44:25 +04:00
23rd bb438880e3 Added ability to view all of user's own groups. 2024-04-01 22:44:25 +04:00
23rd 8492b7144f Replaced emoji with icon for currency in earn section. 2024-04-01 22:44:25 +04:00
23rd 5dd974f2ab Added line with converted currency amount to point details widget. 2024-04-01 22:44:25 +04:00
23rd d3cd3bb0a4 Slightly improved style of box for reporting of sponsored messages. 2024-04-01 22:44:25 +04:00
23rd 04acf08d34 Limited list of data for non-owners of channel in earn section. 2024-04-01 22:44:25 +04:00
23rd 4db885d8b4 Replaced exported data of callbacks from markup replies with base64. 2024-04-01 22:44:25 +04:00
23rd 8718d94e7d Added sub-button to top of sponsored messages that can be reported. 2024-04-01 22:44:25 +04:00
23rd 24c1151101 Fixed incorrect handling of error from channel ownership request. 2024-04-01 22:44:25 +04:00
23rd 0b22e5928c Fixed bottom fade effect for input message fields in compose controls. 2024-04-01 22:44:25 +04:00
23rd 3311a50750 Added second rulers to currency chart in channel earn info section. 2024-04-01 22:44:25 +04:00
23rd 1563a85fea Improved style for right action of forwarded messages. 2024-04-01 22:44:25 +04:00
23rd 586983eb9b Added divider text to box for reporting of sponsored messages. 2024-04-01 22:44:25 +04:00
23rd 1a7a906ced Added ability to review history entry in channel earn info section. 2024-04-01 22:44:25 +04:00
23rd 496247c1d8 Added ability to load chunked history transactions in earn info section. 2024-04-01 22:44:25 +04:00
23rd 2f07bb3973 Added initial support of withdraw button in channel earn info section. 2024-04-01 22:44:25 +04:00
23rd 9b0f3bedff Added entry point for channel earn info section. 2024-04-01 22:44:25 +04:00
23rd c66b5b2490 Added support of permission to manage channel earn. 2024-04-01 22:44:25 +04:00
23rd a1264a6088 Slightly improved style of learn more box in channel earn info section. 2024-04-01 22:44:24 +04:00
23rd 4e0d770d05 Removed cpm configuration. 2024-04-01 22:44:24 +04:00
23rd 508119a127 Added ability to report sponsored messages. 2024-04-01 22:44:24 +04:00
23rd 341b9e4a29 Added menu with about box to sponsored messages that can be reported. 2024-04-01 22:44:24 +04:00
23rd 57789c1272 Added second button to sponsored right. 2024-04-01 22:44:24 +04:00
23rd 3845a87f2e Added fade animation to center label of slider in earn channel section. 2024-04-01 22:44:24 +04:00
23rd 3c266b6dc4 Moved out data structures for channel earn to td_ui. 2024-04-01 22:44:24 +04:00
23rd 32a3952524 Added initial support of channel cpm from earn channel api. 2024-04-01 22:44:24 +04:00
23rd 9c52f245ac Added initial support of statistical charts in earn channel section. 2024-04-01 22:44:24 +04:00
23rd 393d9e9f1f Slightly improved style of channel earn info section. 2024-04-01 22:44:24 +04:00
23rd f28f498467 Added support of level of boosts for restriction of sponsored messages. 2024-04-01 22:44:24 +04:00
23rd b5a7a351f6 Added initial support for integer format of channel earn amount data. 2024-04-01 22:44:24 +04:00
23rd a14c0f5253 Added initial support of channel earn data in appropriate info section. 2024-04-01 22:44:24 +04:00
23rd a278aa0f89 Added initial api support for channel earn statistics. 2024-04-01 22:44:24 +04:00
23rd 479bb2a1d6 Added focus to input field in channel earn info section. 2024-04-01 22:44:24 +04:00
23rd 538934a88a Added learn more box to channel earn info section. 2024-04-01 22:44:24 +04:00
23rd 5d2726036f Slightly improved style of channel earn info section. 2024-04-01 22:44:24 +04:00
23rd 778317e1b2 Added initial slider for earn settings to channel earn info section. 2024-04-01 22:44:24 +04:00
23rd 99dd5507bf Added initial transfer subsection to channel earn info section. 2024-04-01 22:44:24 +04:00
23rd 490d9bc3ec Added initial box for every history entry to channel earn info section. 2024-04-01 22:44:24 +04:00
23rd 796e09bf13 Added initial subsection for history to channel earn info section. 2024-04-01 22:44:24 +04:00
23rd 588624e7a9 Added initial overview subsection to channel earn info section. 2024-04-01 22:44:24 +04:00
23rd a45a9e6515 Added initial learn about as divider text to channel earn info section. 2024-04-01 22:44:24 +04:00
23rd a7df074b8f Added dummy files for channel earn info section. 2024-04-01 22:44:24 +04:00
23rd 9941a46769 Added some phrases for channel earn info section. 2024-04-01 22:44:24 +04:00
23rd b0565f2188 Moved files for boosts to nested folder. 2024-04-01 22:44:24 +04:00
John Preston 8fb3e39881 Simple promo box for Telegram Business. 2024-04-01 22:44:23 +04:00
John Preston d788f5afac Handle today-birthday click in profile. 2024-04-01 22:44:22 +04:00
John Preston 20123fca7f Mark the Chatbots section as NEW. 2024-04-01 22:44:22 +04:00
John Preston 7c7b962c6d Improve couple of Telegram Business icons. 2024-04-01 22:44:22 +04:00
John Preston 68ded1a6e0 Allow newRequirePremium for free if server allows. 2024-04-01 22:44:22 +04:00
John Preston da7a796edb Add session->appConfig() shortcut. 2024-04-01 22:44:22 +04:00
John Preston 3b5814edae Handle empty channels list. 2024-04-01 22:44:22 +04:00
John Preston f439443fe5 Show personal channel in users profile. 2024-04-01 22:44:22 +04:00
John Preston 280d69d346 Implement personal channel selector. 2024-04-01 22:44:21 +04:00
John Preston ab74ed0fa7 Handle flood errors in birthday changes. 2024-04-01 22:44:21 +04:00
John Preston 0d740c21a2 Check if bot supports Telegram Business. 2024-04-01 22:44:21 +04:00
John Preston f65bc7c0bd Suggest premium on transfer speed limiting. 2024-04-01 22:44:21 +04:00
John Preston 0dd1a4973a Handle the new FLOOD_PREMIUM_WAIT errors. 2024-04-01 22:44:21 +04:00
John Preston 05a5e62327 Update API scheme on layer 177. 2024-04-01 22:44:21 +04:00
John Preston 66a47137a0 Copy chat link by left click in footer. 2024-04-01 22:44:21 +04:00
John Preston f240cbbda6 Handle chat link clicks. 2024-04-01 22:44:21 +04:00
John Preston 3d54f8ec49 Initial chat links edition implementation. 2024-04-01 22:44:21 +04:00
John Preston 6fe0c60204 Fix build with Xcode. 2024-04-01 22:44:21 +04:00
John Preston f7d04d668b Hide captions in IV slideshows. 2024-04-01 22:44:21 +04:00
John Preston 57bd0d2674 Update API scheme on layer 177. 2024-04-01 22:44:21 +04:00
John Preston 08ee25deb2 Display date of birth in user profiles. 2024-04-01 22:44:21 +04:00
John Preston c82d7bd909 Implement birthday info / privacy edit boxes. 2024-04-01 22:44:21 +04:00
John Preston 59663d6661 Track birthdays, edit birthday privacy. 2024-04-01 22:44:21 +04:00
John Preston 5e68dace9f Remove description in intro settings preview. 2024-04-01 22:44:21 +04:00
John Preston fcc9e0b2db Update API scheme on layer 177. 2024-04-01 22:44:21 +04:00
John Preston 3a5b3ff3bd Show description about custom chat intro. 2024-04-01 22:44:21 +04:00
John Preston 1e1a48865f Extract history/view/media/history_view_media_generic module. 2024-04-01 22:44:21 +04:00
John Preston b31c30b9b6 Wait for full user info before intro creation. 2024-04-01 22:44:21 +04:00
John Preston 7886a2179f Fix giveaway messages layout. 2024-04-01 22:44:21 +04:00
John Preston d1a995a863 Allow sending the sticker from the intro. 2024-04-01 22:44:21 +04:00
John Preston 85554d19e4 Show chat intro in an empty chat. 2024-04-01 22:44:21 +04:00
John Preston 7f4d13c54a Fix chat intro sticker aspect ratio. 2024-04-01 22:44:20 +04:00
John Preston 9f67b9ba2f Reload chatbot rules after adding an exception. 2024-04-01 22:44:20 +04:00
John Preston 5381fe5a1a Use MediaInBubble for chat intro fake-message. 2024-04-01 22:44:20 +04:00
John Preston 0887348611 Show length limit in chat intro fields. 2024-04-01 22:44:20 +04:00
John Preston 98ce91df39 Fix intro hello sticker playback in editing. 2024-04-01 22:44:20 +04:00
John Preston 191c35914f Start editing chat intro in Telegram Business. 2024-04-01 22:44:20 +04:00
John Preston cf1d0677d1 Support business bot state in chat. 2024-04-01 22:44:20 +04:00
John Preston 3d97ea6f96 Track chat business bot state. 2024-04-01 22:44:20 +04:00
John Preston caa4c5428a Show via_business_bot name in signature. 2024-04-01 22:44:20 +04:00
John Preston 90e572c8b1 Improve mixed stickerpacks support. 2024-04-01 22:44:20 +04:00
John Preston b1795f8c5a Update API scheme to layer 177. 2024-04-01 22:44:20 +04:00
John Preston 962c64b33c Beta version 4.15.7: Linux fix test. 2024-04-01 11:58:24 +04:00
GitHub Action bd827d844b Update User-Agent for DNS to Chrome 123.0.0.0. 2024-04-01 10:20:57 +04:00
wention ed70675e1d Fix build Qt error on non-english windows os 2024-04-01 10:08:16 +04:00
Ilya Fedin e07d53725c Strip notification service start error 2024-04-01 09:59:19 +04:00
Ilya Fedin 1b589a35cf Don't check the count when it's not going to painted 2024-04-01 09:50:20 +04:00
Ilya Fedin 439f8d0914 Implement monochrome icon setting on Linux 2024-04-01 09:50:20 +04:00
Ilya Fedin 1d7dbc4d17 Update patches & lib_base 2024-03-29 14:12:52 +04:00
Ilya Fedin 001b055ee8 Let Wayland to use QGuiApplication::screenAt
Looks like it works correctly nowadays
2024-03-28 10:54:34 +04:00
John Preston 8534d6d7d7 Fix build on Windows. 2024-03-27 18:32:44 +04:00
Ilya Fedin e7a7c2d267 Get rid of XDG_CURRENT_DESKTOP dependent logic
Just try all the commands and use the one that works first
2024-03-26 09:31:58 +04:00
Ilya Fedin 8803dfcee6 Add Plasma 6 sound settings support 2024-03-26 09:31:58 +04:00
Ilya Fedin 887f10059d Update Qt to 6.7.0-rc2 in snap 2024-03-25 22:17:59 +04:00
Ilya Fedin d3db52ce9c Update cmake_helpers 2024-03-25 22:17:59 +04:00
Ilya Fedin 5fa89c22bd Use default Qt prefix on Linux 2024-03-25 22:17:59 +04:00
Ilya Fedin ea42f9545f Move OpenSSL to system directories on Linux 2024-03-25 22:17:59 +04:00
John Preston 8830fb70a4 Beta version 4.15.6: OpenSSL 3.2.1. 2024-03-25 17:47:53 +04:00
Ilya Fedin 0edf14f3a9 Update Qt to 6.7.0-rc2 on Linux 2024-03-25 17:47:25 +04:00
John Preston 89c6bb163e Beta version 4.15.6: Fix build with GCC. 2024-03-25 11:19:31 +04:00
John Preston 8708598daa Beta version 4.15.6.
- Save the Instant View window geometry.
- Fix jump to anchors with accents in the Instant View.
- Fix possible crash in the ElasticScroll destructor.
2024-03-25 10:26:23 +04:00
John Preston c71c24a6bc Re-revert "Disable system proxy support on Linux".
This reverts commit 55b2b04e2e.
2024-03-25 10:25:34 +04:00
John Preston 386fb07017 Update lib_base submodule. 2024-03-25 10:16:12 +04:00
23rd aad2961646 Added all unused shortcuts to json of default shortcuts. 2024-03-25 10:15:42 +04:00
23rd 00a89883fd Added ability to set shortcut to archive chat from dialogs list. 2024-03-25 10:15:42 +04:00
23rd 5509c1810b Added ability to set shortcut to open section with scheduled messages. 2024-03-25 10:15:42 +04:00
23rd 24498bc95f Changed behavior to hide field buttons in HistoryWidget with typed text. 2024-03-25 10:15:42 +04:00
Sergey A. Osokin 58caec8d05 Fix build on FreeBSD 2024-03-25 10:14:17 +04:00
John Preston ebe331a7e4 Fix build on Windows. 2024-03-24 10:24:26 +04:00
John Preston d481008fdb Fix possible crash in ElasticScroll destructor. 2024-03-24 10:24:22 +04:00
John Preston b97d243978 Fix jump to hash with accents in IV. 2024-03-24 10:05:55 +04:00
John Preston fd833dff35 Save IV window geometry. 2024-03-24 10:05:52 +04:00
John Preston d9ed3a7d3f Remove for-development-only save document action.
Regression was introduced in 205479fccc.
2024-03-24 10:05:37 +04:00
John Preston b8ce79467f Fix crash on "History cleared" delete in Saved Messages. 2024-03-24 10:05:04 +04:00
John Preston 9d0457d208 Add "Terms of Use" menu item to all miniapps. 2024-03-24 10:04:54 +04:00
23rd fa02e521f9 Added ability to view all of user's own channels. 2024-03-24 07:10:07 +03:00
23rd d03d50ef0d Removed cIntRetinaFactor and cRetinaFactor. 2024-03-24 07:10:07 +03:00
23rd 58fcedab64 Moved out Window::SlideAnimation to td_ui. 2024-03-24 07:01:08 +03:00
23rd 5e11c43f84 Moved out Stickers::EmojiImageLoader to td_ui. 2024-03-24 07:01:08 +03:00
Ilya Fedin 4b4de9d5aa Don't mark as read when unexposed
There's a yet another another visility state called "exposed" and the window could be unexposed while being not hidden and not minimized.

When the window is unexposed, Qt doesn't draw and the user can't see changes for sure.
2024-03-23 10:36:43 +04:00
23rd f135676d36 Added support for sending state of low level of battery. 2024-03-22 00:12:57 +03:00
23rd cb9adad660 Added label to call panel when recipient has low level of battery. 2024-03-21 23:48:51 +03:00
23rd 88dab47d2c Changed behavior to open section with scheduled messages at top. 2024-03-21 20:20:06 +03:00
Daniel Novomeský d6e4613144 Upgrade dav1d, libavif, libde265, libheif on Linux 2024-03-20 20:00:33 +04:00
23rd 893c09c848 Fixed showing of rate call box in appropriate window. 2024-03-20 11:20:22 +04:00
Ilya Fedin a0e0fd5b98 Don't build libheif tests
That would save some build time
2024-03-19 20:14:28 +04:00
John Preston 98abb3aa00 Fix possible crash in join channel toast. 2024-03-19 11:04:40 +04:00
John Preston 8982a49192 Fix repetitive phone formatting. 2024-03-19 11:04:21 +04:00
John Preston 529eb4e954 Fix window shadow on Linux. 2024-03-19 11:03:39 +04:00
Ilya Fedin 846a6d8717 Update scudo to 18.1.1 2024-03-18 19:53:36 +04:00
Ilya Fedin 07ab875655 Update lib_base 2024-03-18 09:59:47 +04:00
Ilya Fedin 602b0b5d9b Use the File::OpenUrl routine in IV 2024-03-18 09:59:47 +04:00
John Preston 0e428aebdb Update patches in Linux build. 2024-03-17 20:34:02 +04:00
Daniel Novomeský 4abc68ab1c Upgrade dav1d, libavif, libde265, libheif 2024-03-17 19:35:00 +04:00
23rd 2638ee2926 Improved message edition with pre-selected text. 2024-03-17 11:16:07 +03:00
Ilya Fedin ddaf78828a Fix media viewer geometry restoration 2024-03-17 09:28:46 +04:00
Ilya Fedin 6d5347472d Fix media viewer geometry logging
It has regressed after c64e953174
2024-03-17 09:28:46 +04:00
John Preston 82fda96ed8 Beta version 4.15.5.
- Fix a crash in Instant View article parsing.
- Support AirPods Mute/Unmute toggle in calls on macOS.
- Disable system proxy on Linux to check if it fixes crashes.
2024-03-16 09:59:23 +04:00
John Preston 55b2b04e2e Reapply "Disable system proxy support on Linux"
This reverts commit 202a4064a4.
2024-03-16 09:54:07 +04:00
23rd 393f330d15 Added ability to go to message from Calls box. 2024-03-16 04:40:56 +03:00
23rd f4ecfeaddd Added ability to perform bulk selection from menu in HistoryWidget. 2024-03-16 04:40:56 +03:00
Ilya Fedin ad101dc8a0 A way to initialize GLib::VariantIter without gi::wrap is found 2024-03-15 23:10:43 +04:00
John Preston 24e9a3ea59 Bot close confirm closes only by Close button. 2024-03-15 20:28:11 +04:00
John Preston f1d8135e30 Fix crash in IV parsing. 2024-03-15 20:26:50 +04:00
23rd a1a415de82 Fixed crash in non-stack bar chart view when hide selected point. 2024-03-15 17:08:17 +03:00
John Preston 77dc234b2d Support AirPods Mute/Unmute toggle. 2024-03-15 14:43:41 +04:00
23rd c3ca8c6258 Fixed emoji drawing in statuses of group call participants. 2024-03-15 14:43:29 +04:00
23rd 9e18236b55 Added ability to open account in new window with middle click. 2024-03-15 14:43:29 +04:00
23rd ded7aada52 Slightly improved filter for choosing users requested by bot. 2024-03-15 14:43:29 +04:00
Dubzer a117c1ebf2 Add new Segoe UI to IV css 2024-03-15 09:24:12 +04:00
Ilya Fedin d3715cc362 Get rid of glibmm 2024-03-15 00:00:24 +04:00
Ilya Fedin 3689e7dfbc Use cppgir compatible XDP utilities API 2024-03-15 00:00:24 +04:00
Ilya Fedin 59e53c1edf Port NotificationId conversion to cppgir 2024-03-15 00:00:24 +04:00
John Preston f2a54e3cbb Beta version 4.15.4: Fix build with Xcode. 2024-03-14 22:30:52 +04:00
John Preston 20db635366 Beta version 4.15.4: Update Qt patches in snap. 2024-03-14 21:58:56 +04:00
John Preston b955d32970 Beta version 4.15.14.
- Fix initial text color in dark mode Instant View on macOS.
- Fix non-English symbols encoding in Instant View on macOS.
- Fix sharing from Instant View on macOS.
- Fix crash with long messages on Linux.
2024-03-14 21:55:16 +04:00
John Preston 5a5d89c32c Fix crashing regression in Qt 6.7.0. 2024-03-14 21:55:05 +04:00
23rd 1f0ed3bb31 Fixed links in service message about requested peers from bot. 2024-03-14 20:36:19 +03:00
23rd 6c083e88a3 Changed behavior of bot menu button to decrease size to first emoji. 2024-03-14 20:19:09 +03:00
John Preston 2e7323d484 Fix a glitch in IV sharing on Windows. 2024-03-14 19:03:46 +04:00
John Preston 461aebd7f3 Hide IV when sharing on macOS, fixes sharing. 2024-03-14 18:36:17 +04:00
John Preston 73ca78215f Set window title in IV. 2024-03-14 18:35:57 +04:00
John Preston 200bb31e08 Fix theming in code blocks. 2024-03-14 15:01:03 +04:00
John Preston 396f52b8ca Fix title updating on IV menu show. 2024-03-14 14:27:46 +04:00
John Preston a118d3d848 Close IV when opening URL in the browser. 2024-03-14 14:26:00 +04:00
John Preston f6b9702b52 Unminimize IV when opening another one. 2024-03-14 12:51:34 +04:00
John Preston d92418dc6d Disable media context menus in IV. 2024-03-14 12:50:55 +04:00
23rd fe4b853393 Improved section of scheduled messages when forum opened in flat mode. 2024-03-14 11:43:46 +04:00
John Preston 782556495a Improve joined channels tracking in IV. 2024-03-14 11:39:17 +04:00
John Preston 5c32423597 Integrate IV menu hiding by click inside WebView. 2024-03-14 11:39:17 +04:00
John Preston 5c8e6c3012 Fix page encoding in IV on macOS. 2024-03-14 11:39:17 +04:00
John Preston 5133f74f67 Fix IV theming on macOS because of broken HTML. 2024-03-14 11:39:17 +04:00
John Preston d5b23b5bde Use a separate lang key for IV channel join button. 2024-03-14 11:39:17 +04:00
kukuruzka bf4b4ae936 full support for ukrainian transliteration 2024-03-14 11:23:13 +04:00
kukuruzka 458b990b8c Improve transliteration 2024-03-14 11:23:13 +04:00
Ilya Fedin e044753934 Fix macOS GH action 2024-03-14 10:45:42 +04:00
Ilya Fedin c0b612c457 Update cppgir 2024-03-14 09:29:10 +04:00
Eric Kotato 9414ef5709 Using system font stack for Instant View 2024-03-14 09:18:24 +04:00
Ilya Fedin c9e566f8aa Fix snap build
Qt has removed support for kernels less than 4.11 by removing the -no-feature-statx flag. Remove the usage all the related flags.
2024-03-14 09:17:01 +04:00
Eric Kotato 40bd37315a Use %NUMBER_OF_PROCESSORS% for jom 2024-03-14 08:33:07 +04:00
John Preston 0410d05913 Beta version 4.15.3: Fix build with GCC. 2024-03-13 22:27:25 +04:00
John Preston a888b8d846 Beta version 4.15.3.
- Instant View on Windows (with WebView2) and macOS.
- Allow scheduling messages in topics.
- Fix system proxy support on Linux.
2024-03-13 21:58:45 +04:00
John Preston eac5c39a96 Don't show IV button for album links. 2024-03-13 21:58:27 +04:00
John Preston 202a4064a4 Revert "Disable system proxy support on Linux"
This reverts commit 3af646a584.
2024-03-13 21:20:31 +04:00
John Preston ddf2369774 Allow more parts for macOS IV streaming. 2024-03-13 21:20:30 +04:00
John Preston 48f70a8552 Fix videos management on macOS. 2024-03-13 21:20:30 +04:00
John Preston 4685b889c2 Update Qt to 5.15.13 on Windows. 2024-03-13 21:20:30 +04:00
John Preston 3e373200b1 Dynamically create / destroy videos. 2024-03-13 21:20:30 +04:00
John Preston 7913d2a82d Fix initial scroll on macOS. 2024-03-13 21:20:30 +04:00
John Preston e20770e256 Show IV button only if supported. 2024-03-13 21:20:30 +04:00
John Preston d43f0be0da Add IV icon to the button. 2024-03-13 21:20:30 +04:00
John Preston 7b4adc2e60 Escape data from API in IV html. 2024-03-13 21:20:30 +04:00
John Preston 1eeba65ddb Fix build on macOS. 2024-03-13 21:20:30 +04:00
John Preston 1252accef7 Support file reference refresh in IV. 2024-03-13 21:20:30 +04:00
John Preston 5f7c3ae20e Remove some test code. 2024-03-13 21:20:30 +04:00
John Preston e1b55b560a New top bar, sharing, internal IV links style. 2024-03-13 21:20:30 +04:00
John Preston 315859bf7b Load full webpage and update in IV. 2024-03-13 21:20:30 +04:00
John Preston 0a87dbea68 Fix focusing IV content. 2024-03-13 21:20:30 +04:00
John Preston 5f3c380d56 Fix navigation on macOS. 2024-03-13 21:20:30 +04:00
John Preston 8b62c37c34 Support complex history and anchors. 2024-03-13 21:20:30 +04:00
John Preston fae10cfa6b Support slideshow layout. 2024-03-13 21:20:30 +04:00
John Preston f9069144e5 Support albums layout. 2024-03-13 21:20:30 +04:00
John Preston 7755b70317 Add top dropdown menu. 2024-03-13 21:20:30 +04:00
John Preston c46f34c677 Load non-streamable documents. 2024-03-13 21:20:30 +04:00
John Preston 5c428ca502 Support anchor jumps. 2024-03-13 21:20:30 +04:00
John Preston 51d5b7bab6 Support channel link / channel join. 2024-03-13 21:20:30 +04:00
John Preston f508ad5e75 Implement title and in-IV buttons. 2024-03-13 21:20:30 +04:00
John Preston f9299eee2a Apply app color scheme, test dynamic header. 2024-03-13 21:20:30 +04:00
John Preston 212259aae3 Handle shortcuts in IV. 2024-03-13 21:20:30 +04:00
John Preston 6d733bb566 Proof-of-concept custom scheme in WKWebView. 2024-03-13 21:20:30 +04:00
John Preston 125f856e67 Proof-of-concept (WebView2 / Local) iv. 2024-03-13 21:20:30 +04:00
23rd 672ad64e53 Added initial ability to send and receive scheduled messages in forums. 2024-03-13 19:57:07 +03:00
23rd cd59f1d576 Removed redundant constructor from HistoryView::ComposeControls. 2024-03-13 19:57:07 +03:00
John Preston c4fc43ccc0 Fix rounding in boost features box. 2024-03-13 20:50:19 +04:00
John Preston b20b3142a2 Update submodules and patches commit. 2024-03-13 20:49:24 +04:00
Ilya Fedin d67f25d726 Update Qt to 6.7.0 on Linux 2024-03-13 20:46:54 +04:00
Ilya Fedin d881019c3b Update submodules 2024-03-13 20:46:34 +04:00
Ilya Fedin abdfa4f785 Remove not really needed notification capability checks
If the notification daemon doesn't support any of the hints, it will just ignore them
2024-03-13 20:46:34 +04:00
Ilya Fedin 5394717ddc Log only GError message 2024-03-13 20:46:34 +04:00
Ilya Fedin c9d58d4259 Use HasCapability directly as an argument to ranges::all_of 2024-03-13 20:46:34 +04:00
Ilya Fedin dba9cada83 Don't check whether specification version is null
We log specification version anyway
2024-03-13 20:46:34 +04:00
Ilya Fedin 0ec5181566 Pre-normalize notification daemon versions 2024-03-13 20:46:34 +04:00
Ilya Fedin 886847f457 Port notifications_manager_linux to cppgir 2024-03-13 20:46:34 +04:00
AlexeyZavar 79d6df2c01 fix: mute exception 2024-03-13 17:25:32 +03:00
525 changed files with 21679 additions and 5147 deletions
+4 -1
View File
@@ -64,7 +64,10 @@ jobs:
- name: First set up.
run: |
sudo chown -R `whoami`:admin /usr/local/share
brew install automake ninja pkg-config nasm meson
brew update
brew upgrade || true
brew install automake meson nasm ninja pkg-config
# Disable spotlight.
sudo mdutil -a -i off
+2 -1
View File
@@ -60,7 +60,7 @@ include(cmake/options.cmake)
if (NOT DESKTOP_APP_USE_PACKAGED)
if (WIN32)
set(qt_version 5.15.12)
set(qt_version 5.15.13)
elseif (APPLE)
set(qt_version 6.2.7)
endif()
@@ -68,6 +68,7 @@ endif()
include(cmake/external/qt/package.cmake)
set(desktop_app_skip_libs
glibmm
variant
)
+105 -89
View File
@@ -30,8 +30,9 @@ 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_iv.cmake)
include(cmake/td_lang.cmake)
include(cmake/td_mtproto.cmake)
include(cmake/td_scheme.cmake)
include(cmake/td_ui.cmake)
include(cmake/generate_appdata_changelog.cmake)
@@ -62,8 +63,9 @@ PRIVATE
desktop-app::external_minizip
tdesktop::td_export
tdesktop::td_mtproto
tdesktop::td_iv
tdesktop::td_lang
tdesktop::td_mtproto
tdesktop::td_scheme
tdesktop::td_ui
desktop-app::lib_webrtc
@@ -91,78 +93,81 @@ PRIVATE
desktop-app::external_xxhash
)
set(ayugram_files
ayu/ayu_worker.cpp
ayu/ayu_worker.h
ayu/ayu_url_handlers.cpp
ayu/ayu_url_handlers.h
ayu/ayu_state.cpp
ayu/ayu_state.h
ayu/ayu_settings.cpp
ayu/ayu_settings.h
ayu/ayu_lang.cpp
ayu/ayu_lang.h
ayu/ayu_infra.cpp
ayu/ayu_infra.h
ayu/ayu_constants.h
ayu/utils/ayu_mapper.cpp
ayu/utils/ayu_mapper.h
ayu/utils/qt_key_modifiers_extended.h
ayu/utils/telegram_helpers.cpp
ayu/utils/telegram_helpers.h
ayu/utils/windows_utils.cpp
ayu/utils/windows_utils.h
ayu/ui/ayu_logo.cpp
ayu/ui/ayu_logo.h
ayu/ui/utils/ayu_profile_values.cpp
ayu/ui/utils/ayu_profile_values.h
ayu/ui/settings/icon_picker.cpp
ayu/ui/settings/icon_picker.h
ayu/ui/settings/settings_ayu.cpp
ayu/ui/settings/settings_ayu.h
ayu/ui/context_menu/context_menu.cpp
ayu/ui/context_menu/context_menu.h
ayu/ui/context_menu/menu_item_subtext.cpp
ayu/ui/context_menu/menu_item_subtext.h
ayu/ui/sections/edited/edited_log_inner.cpp
ayu/ui/sections/edited/edited_log_inner.h
ayu/ui/sections/edited/edited_log_item.cpp
ayu/ui/sections/edited/edited_log_item.h
ayu/ui/sections/edited/edited_log_section.cpp
ayu/ui/sections/edited/edited_log_section.h
ayu/ui/boxes/server_read_confirmation_box.cpp
ayu/ui/boxes/server_read_confirmation_box.h
ayu/ui/boxes/edit_deleted_mark.cpp
ayu/ui/boxes/edit_deleted_mark.h
ayu/ui/boxes/edit_edited_mark.cpp
ayu/ui/boxes/edit_edited_mark.h
ayu/ui/boxes/font_selector.cpp
ayu/ui/boxes/font_selector.h
ayu/ui/boxes/theme_selector_box.cpp
ayu/ui/boxes/theme_selector_box.h
ayu/ui/boxes/message_shot_box.cpp
ayu/ui/boxes/message_shot_box.h
ayu/ui/components/image_view.cpp
ayu/ui/components/image_view.h
ayu/libs/json.hpp
ayu/libs/json_ext.hpp
ayu/libs/sqlite/sqlite3.c
ayu/libs/sqlite/sqlite3.h
ayu/libs/sqlite/sqlite_orm.h
ayu/features/streamer_mode/streamer_mode_windows.cpp
ayu/features/streamer_mode/streamer_mode_linux.cpp
ayu/features/streamer_mode/streamer_mode.h
ayu/features/messageshot/message_shot.cpp
ayu/features/messageshot/message_shot.h
ayu/data/messages_storage.cpp
ayu/data/messages_storage.h
ayu/data/entities.h
ayu/data/ayu_database.cpp
ayu/data/ayu_database.h
)
target_precompile_headers(Telegram PRIVATE $<$<COMPILE_LANGUAGE:CXX,OBJCXX>:${src_loc}/stdafx.h>)
nice_target_sources(Telegram ${src_loc}
PRIVATE
${style_files}
ayu/ayu_worker.cpp
ayu/ayu_worker.h
ayu/ayu_url_handlers.cpp
ayu/ayu_url_handlers.h
ayu/ayu_state.cpp
ayu/ayu_state.h
ayu/ayu_settings.cpp
ayu/ayu_settings.h
ayu/ayu_lang.cpp
ayu/ayu_lang.h
ayu/ayu_infra.cpp
ayu/ayu_infra.h
ayu/ayu_constants.h
ayu/utils/ayu_mapper.cpp
ayu/utils/ayu_mapper.h
ayu/utils/qt_key_modifiers_extended.h
ayu/utils/telegram_helpers.cpp
ayu/utils/telegram_helpers.h
ayu/utils/windows_utils.cpp
ayu/utils/windows_utils.h
ayu/ui/ayu_logo.cpp
ayu/ui/ayu_logo.h
ayu/ui/utils/ayu_profile_values.cpp
ayu/ui/utils/ayu_profile_values.h
ayu/ui/settings/icon_picker.cpp
ayu/ui/settings/icon_picker.h
ayu/ui/settings/settings_ayu.cpp
ayu/ui/settings/settings_ayu.h
ayu/ui/context_menu/context_menu.cpp
ayu/ui/context_menu/context_menu.h
ayu/ui/context_menu/menu_item_subtext.cpp
ayu/ui/context_menu/menu_item_subtext.h
ayu/ui/sections/edited/edited_log_inner.cpp
ayu/ui/sections/edited/edited_log_inner.h
ayu/ui/sections/edited/edited_log_item.cpp
ayu/ui/sections/edited/edited_log_item.h
ayu/ui/sections/edited/edited_log_section.cpp
ayu/ui/sections/edited/edited_log_section.h
ayu/ui/boxes/server_read_confirmation_box.cpp
ayu/ui/boxes/server_read_confirmation_box.h
ayu/ui/boxes/edit_deleted_mark.cpp
ayu/ui/boxes/edit_deleted_mark.h
ayu/ui/boxes/edit_edited_mark.cpp
ayu/ui/boxes/edit_edited_mark.h
ayu/ui/boxes/font_selector.cpp
ayu/ui/boxes/font_selector.h
ayu/ui/boxes/theme_selector_box.cpp
ayu/ui/boxes/theme_selector_box.h
ayu/ui/boxes/message_shot_box.cpp
ayu/ui/boxes/message_shot_box.h
ayu/ui/components/image_view.cpp
ayu/ui/components/image_view.h
ayu/libs/json.hpp
ayu/libs/json_ext.hpp
ayu/libs/sqlite/sqlite3.c
ayu/libs/sqlite/sqlite3.h
ayu/libs/sqlite/sqlite_orm.h
ayu/features/streamer_mode/streamer_mode_windows.cpp
ayu/features/streamer_mode/streamer_mode_linux.cpp
ayu/features/streamer_mode/streamer_mode.h
ayu/features/messageshot/message_shot.cpp
ayu/features/messageshot/message_shot.h
ayu/data/messages_storage.cpp
ayu/data/messages_storage.h
ayu/data/entities.h
ayu/data/ayu_database.cpp
ayu/data/ayu_database.h
${ayugram_files}
api/api_attached_stickers.cpp
api/api_attached_stickers.h
@@ -176,6 +181,8 @@ PRIVATE
api/api_chat_filters.h
api/api_chat_invite.cpp
api/api_chat_invite.h
api/api_chat_links.cpp
api/api_chat_links.h
api/api_chat_participants.cpp
api/api_chat_participants.h
api/api_cloud_password.cpp
@@ -184,6 +191,8 @@ PRIVATE
api/api_common.h
api/api_confirm_phone.cpp
api/api_confirm_phone.h
api/api_earn.cpp
api/api_earn.h
api/api_editing.cpp
api/api_editing.h
api/api_global_privacy.cpp
@@ -458,8 +467,6 @@ PRIVATE
chat_helpers/spellchecker_common.h
chat_helpers/stickers_dice_pack.cpp
chat_helpers/stickers_dice_pack.h
chat_helpers/stickers_emoji_image_loader.cpp
chat_helpers/stickers_emoji_image_loader.h
chat_helpers/stickers_emoji_pack.cpp
chat_helpers/stickers_emoji_pack.h
chat_helpers/stickers_gift_box_pack.cpp
@@ -786,6 +793,8 @@ PRIVATE
history/view/media/history_view_media.h
history/view/media/history_view_media_common.cpp
history/view/media/history_view_media_common.h
history/view/media/history_view_media_generic.cpp
history/view/media/history_view_media_generic.h
history/view/media/history_view_media_grouped.cpp
history/view/media/history_view_media_grouped.h
history/view/media/history_view_media_spoiler.cpp
@@ -925,14 +934,18 @@ PRIVATE
history/history_view_highlight_manager.h
history/history_widget.cpp
history/history_widget.h
info/boosts/giveaway/giveaway_list_controllers.cpp
info/boosts/giveaway/giveaway_list_controllers.h
info/boosts/create_giveaway_box.cpp
info/boosts/create_giveaway_box.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/channel_statistics/boosts/create_giveaway_box.cpp
info/channel_statistics/boosts/create_giveaway_box.h
info/channel_statistics/boosts/giveaway/giveaway_list_controllers.cpp
info/channel_statistics/boosts/giveaway/giveaway_list_controllers.h
info/channel_statistics/boosts/info_boosts_inner_widget.cpp
info/channel_statistics/boosts/info_boosts_inner_widget.h
info/channel_statistics/boosts/info_boosts_widget.cpp
info/channel_statistics/boosts/info_boosts_widget.h
info/channel_statistics/earn/info_earn_inner_widget.cpp
info/channel_statistics/earn/info_earn_inner_widget.h
info/channel_statistics/earn/info_earn_widget.cpp
info/channel_statistics/earn/info_earn_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
@@ -1063,6 +1076,10 @@ PRIVATE
intro/intro_step.h
intro/intro_widget.cpp
intro/intro_widget.h
iv/iv_delegate_impl.cpp
iv/iv_delegate_impl.h
iv/iv_instance.cpp
iv/iv_instance.h
lang/lang_cloud_manager.cpp
lang/lang_cloud_manager.h
lang/lang_instance.cpp
@@ -1197,6 +1214,8 @@ PRIVATE
menu/menu_mute.h
menu/menu_send.cpp
menu/menu_send.h
menu/menu_sponsored.cpp
menu/menu_sponsored.h
menu/menu_ttl_validator.cpp
menu/menu_ttl_validator.h
mtproto/config_loader.cpp
@@ -1251,8 +1270,6 @@ PRIVATE
payments/payments_checkout_process.h
payments/payments_form.cpp
payments/payments_form.h
platform/linux/linux_desktop_environment.cpp
platform/linux/linux_desktop_environment.h
platform/linux/linux_wayland_integration_dummy.cpp
platform/linux/linux_wayland_integration.cpp
platform/linux/linux_wayland_integration.h
@@ -1359,6 +1376,10 @@ PRIVATE
settings/business/settings_away_message.h
settings/business/settings_shortcut_messages.cpp
settings/business/settings_shortcut_messages.h
settings/business/settings_chat_intro.cpp
settings/business/settings_chat_intro.h
settings/business/settings_chat_links.cpp
settings/business/settings_chat_links.h
settings/business/settings_chatbots.cpp
settings/business/settings_chatbots.h
settings/business/settings_greeting.cpp
@@ -1561,8 +1582,6 @@ PRIVATE
window/window_session_controller.cpp
window/window_session_controller.h
window/window_session_controller_link_info.h
window/window_slide_animation.cpp
window/window_slide_animation.h
window/window_top_bar_wrap.h
window/themes/window_theme.cpp
window/themes/window_theme.h
@@ -1637,6 +1656,7 @@ PRIVATE
qrc/emoji_preview.qrc
qrc/telegram/animations.qrc
qrc/telegram/export.qrc
qrc/telegram/iv.qrc
qrc/telegram/telegram.qrc
qrc/telegram/sounds.qrc
winrc/Telegram.rc
@@ -1744,13 +1764,9 @@ elseif (APPLE)
)
endif()
else()
target_link_libraries(Telegram
PRIVATE
desktop-app::external_glibmm
)
include(${cmake_helpers_loc}/external/glib/generate_dbus.cmake)
generate_dbus(Telegram org.freedesktop.portal. XdpBackground ${third_party_loc}/xdg-desktop-portal/data/org.freedesktop.portal.Background.xml)
generate_dbus(Telegram org.freedesktop. XdgNotifications ${src_loc}/platform/linux/org.freedesktop.Notifications.xml)
if (NOT DESKTOP_APP_DISABLE_X11_INTEGRATION)
target_link_libraries(Telegram
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 596 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: 568 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 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: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 940 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 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: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 651 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 893 B

@@ -0,0 +1 @@
.hljs{display:block;overflow-x:auto;padding:0.5em;background:#F0F0F0}.hljs,.hljs-subst{color:#444}.hljs-comment{color:#888888}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-selector-pseudo{color:#BC6060}.hljs-literal{color:#78A960}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+657
View File
@@ -0,0 +1,657 @@
var IV = {
notify: function(message) {
if (window.external && window.external.invoke) {
window.external.invoke(JSON.stringify(message));
}
},
frameClickHandler: function(e) {
var target = e.target;
var context = '';
while (target) {
if (target.id == 'menu_page_blocker') {
IV.notify({ event: 'menu_page_blocker_click' });
IV.menuShown(false);
return;
}
if (target.tagName == 'AUDIO' || target.tagName == 'VIDEO') {
return;
}
if (context === ''
&& target.hasAttribute
&& target.hasAttribute('data-context')) {
context = String(target.getAttribute('data-context'));
}
if (target.tagName == 'A') {
break;
}
target = target.parentNode;
}
if (!target || !target.hasAttribute('href')) {
return;
}
var base = document.createElement('A');
base.href = window.location.href;
if (base.origin != target.origin
|| base.pathname != target.pathname
|| base.search != target.search) {
IV.notify({
event: 'link_click',
url: target.href,
context: context,
});
} else if (target.hash.length < 2) {
IV.jumpToHash('');
} else {
IV.jumpToHash(decodeURIComponent(target.hash.substr(1)));
}
e.preventDefault();
},
getElementTop: function (element) {
var top = 0;
while (element && !element.classList.contains('page-scroll')) {
top += element.offsetTop;
element = element.offsetParent;
}
return top;
},
jumpToHash: function (hash, instant) {
var current = IV.computeCurrentState();
current.hash = hash;
window.history.replaceState(
current,
'',
'page' + IV.index + '.html');
if (hash == '') {
IV.scrollTo(0, instant);
return;
}
var element = document.getElementsByName(hash)[0];
if (element) {
IV.scrollTo(IV.getElementTop(element), instant);
}
},
frameKeyDown: function (e) {
const keyW = (e.key === 'w')
|| (e.code === 'KeyW')
|| (e.keyCode === 87);
const keyQ = (e.key === 'q')
|| (e.code === 'KeyQ')
|| (e.keyCode === 81);
const keyM = (e.key === 'm')
|| (e.code === 'KeyM')
|| (e.keyCode === 77);
if ((e.metaKey || e.ctrlKey) && (keyW || keyQ || keyM)) {
e.preventDefault();
IV.notify({
event: 'keydown',
modifier: e.ctrlKey ? 'ctrl' : 'cmd',
key: keyW ? 'w' : keyQ ? 'q' : 'm',
});
} else if (e.key === 'Escape' || e.keyCode === 27) {
e.preventDefault();
if (IV.position) {
window.history.back();
} else {
IV.notify({
event: 'keydown',
key: 'escape',
});
}
}
},
frameMouseEnter: function (e) {
IV.notify({ event: 'mouseenter' });
},
frameMouseUp: function (e) {
IV.notify({ event: 'mouseup' });
},
lastScrollTop: 0,
frameScrolled: function (e) {
const was = IV.lastScrollTop;
IV.lastScrollTop = IV.findPageScroll().scrollTop;
IV.updateJumpToTop(was < IV.lastScrollTop);
IV.checkVideos();
},
updateJumpToTop: function (scrolledDown) {
if (IV.lastScrollTop < 100) {
document.getElementById('bottom_up').classList.add('hidden');
} else if (scrolledDown && IV.lastScrollTop > 200) {
document.getElementById('bottom_up').classList.remove('hidden');
}
},
updateStyles: function (styles) {
if (IV.styles !== styles) {
IV.styles = styles;
document.getElementsByTagName('html')[0].style = styles;
}
},
toggleChannelJoined: function (id, joined) {
IV.channelsJoined['channel' + id] = joined;
IV.checkChannelButtons();
},
checkChannelButtons: function() {
const channels = document.getElementsByClassName('channel');
for (var i = 0; i < channels.length; ++i) {
const channel = channels[i];
const full = String(channel.getAttribute('data-context'));
const value = IV.channelsJoined[full];
if (value !== undefined) {
channel.classList.toggle('joined', value);
}
}
},
slideshowSlide: function(el, delta) {
var dir = window.getComputedStyle(el, null).direction || 'ltr';
var marginProp = dir == 'rtl' ? 'marginRight' : 'marginLeft';
if (delta) {
var form = el.parentNode.firstChild;
var s = form.s;
const next = +s.value + delta;
s.value = (next == s.length) ? 0 : (next == -1) ? (s.length - 1) : next;
form.nextSibling.firstChild.style[marginProp] = (-100 * s.value) + '%';
} else {
el.form.nextSibling.firstChild.style[marginProp] = (-100 * el.value) + '%';
}
return false;
},
initPreBlocks: function() {
if (!hljs) {
return;
}
var pres = document.getElementsByTagName('pre');
for (var i = 0; i < pres.length; i++) {
if (pres[i].hasAttribute('data-language')) {
hljs.highlightBlock(pres[i]);
}
}
},
initEmbedBlocks: function() {
var iframes = document.getElementsByTagName('iframe');
for (var i = 0; i < iframes.length; i++) {
(function(iframe) {
window.addEventListener('message', function(event) {
if (event.source !== iframe.contentWindow ||
event.origin != window.origin) {
return;
}
try {
var data = JSON.parse(event.data);
} catch(e) {
var data = {};
}
if (data.eventType == 'resize_frame') {
if (data.eventData.height) {
iframe.style.height = data.eventData.height + 'px';
}
}
}, false);
})(iframes[i]);
}
},
addRipple: function (button, x, y) {
const ripple = document.createElement('span');
ripple.classList.add('ripple');
const inner = document.createElement('span');
inner.classList.add('inner');
x -= button.offsetLeft;
y -= button.offsetTop;
const mx = button.clientWidth - x;
const my = button.clientHeight - y;
const sq1 = x * x + y * y;
const sq2 = mx * mx + y * y;
const sq3 = x * x + my * my;
const sq4 = mx * mx + my * my;
const radius = Math.sqrt(Math.max(sq1, sq2, sq3, sq4));
inner.style.width = inner.style.height = `${2 * radius}px`;
inner.style.left = `${x - radius}px`;
inner.style.top = `${y - radius}px`;
inner.classList.add('inner');
ripple.addEventListener('animationend', function (e) {
if (e.animationName === 'fadeOut') {
ripple.remove();
}
});
ripple.appendChild(inner);
button.appendChild(ripple);
},
stopRipples: function (button) {
const id = button.id ? button.id : button;
button = document.getElementById(id);
const ripples = button.getElementsByClassName('ripple');
for (var i = 0; i < ripples.length; ++i) {
const ripple = ripples[i];
if (!ripple.classList.contains('hiding')) {
ripple.classList.add('hiding');
}
}
},
init: function () {
var current = IV.computeCurrentState();
window.history.replaceState(current, '', IV.pageUrl(0));
IV.jumpToHash(current.hash, true);
IV.lastScrollTop = window.history.state.scroll;
IV.findPageScroll().onscroll = IV.frameScrolled;
const buttons = document.getElementsByClassName('fixed_button');
for (let i = 0; i < buttons.length; ++i) {
const button = buttons[i];
button.addEventListener('mousedown', function (e) {
IV.addRipple(e.currentTarget, e.clientX, e.clientY);
});
button.addEventListener('mouseup', function (e) {
const id = e.currentTarget.id;
setTimeout(function () {
IV.stopRipples(id);
}, 0);
});
button.addEventListener('mouseleave', function (e) {
IV.stopRipples(e.currentTarget);
});
}
IV.initMedia();
IV.notify({ event: 'ready' });
IV.forceScrollFocus();
IV.frameScrolled();
},
initMedia: function () {
var scroll = IV.findPageScroll();
const photos = scroll.getElementsByClassName('photo');
for (let i = 0; i < photos.length; ++i) {
const photo = photos[i];
if (photo.classList.contains('loaded')) {
continue;
}
const url = photo.style.backgroundImage;
if (!url || url.length < 7) {
continue;
}
var img = new Image();
img.onload = function () {
photo.classList.add('loaded');
}
img.src = url.substr(5, url.length - 7);
if (img.complete) {
photo.classList.add('loaded');
IV.stopAnimations(photo);
}
}
IV.videos = [];
const videos = scroll.getElementsByClassName('video');
for (let i = 0; i < videos.length; ++i) {
const element = videos[i];
IV.videos.push({
element: element,
src: String(element.getAttribute('data-src')),
autoplay: (element.getAttribute('data-autoplay') == '1'),
loop: (element.getAttribute('data-loop') == '1'),
small: (element.getAttribute('data-small') == '1'),
filled: (element.firstChild
&& element.firstChild.tagName == 'VIDEO'),
});
}
},
checkVideos: function () {
const visibleTop = IV.lastScrollTop;
const visibleBottom = visibleTop + IV.findPageScroll().offsetHeight;
const videos = IV.videos;
for (let i = 0; i < videos.length; ++i) {
const video = videos[i];
const element = video.element;
const wrap = element.offsetParent; // video-wrap
const top = IV.getElementTop(wrap);
const bottom = top + wrap.offsetHeight;
if (top < visibleBottom && bottom > visibleTop) {
if (!video.created) {
video.created = new Date();
video.loaded = false;
element.innerHTML = '<video muted class="'
+ (video.small ? 'video-small' : '')
+ '"'
+ (video.autoplay
? ' preload="auto" autoplay'
: (video.small
? ''
: ' controls'))
+ (video.loop ? ' loop' : '')
+ ' oncanplay="IV.checkVideos();"'
+ ' onloadeddata="IV.checkVideos();">'
+ '<source src="'
+ video.src
+ '" type="video/mp4" />'
+ '</video>';
var media = element.firstChild;
media.oncontextmenu = function () { return false; };
media.oncanplay = IV.checkVideos;
media.onloadeddata = IV.checkVideos;
}
} else if (video.created && video.autoplay) {
video.created = false;
element.innerHTML = '';
}
if (video.created && !video.loaded) {
var media = element.firstChild;
const HAVE_CURRENT_DATA = 2;
if (media && media.readyState >= HAVE_CURRENT_DATA) {
video.loaded = true;
media.classList.add('loaded');
if ((new Date() - video.created) < 100) {
IV.stopAnimations(media);
}
}
}
}
},
showTooltip: function (text) {
var toast = document.createElement('div');
toast.classList.add('toast');
toast.textContent = text;
document.body.appendChild(toast);
setTimeout(function () {
toast.classList.add('hiding');
}, 2000);
setTimeout(function () {
document.body.removeChild(toast);
}, 3000);
},
scrollTo: function (y, instant) {
if (y < 200) {
document.getElementById('bottom_up').classList.add('hidden');
}
IV.findPageScroll().scrollTo({
top: y || 0,
behavior: instant ? 'instant' : 'smooth'
});
},
computeCurrentState: function () {
var now = IV.findPageScroll();
return {
position: IV.position,
index: IV.index,
hash: ((!window.history.state
|| window.history.state.hash === undefined)
? window.location.hash.substr(1)
: window.history.state.hash),
scroll: now ? now.scrollTop : 0
};
},
pageUrl: function (index, hash) {
var result = 'page' + index + '.html';
if (hash) {
result += '#' + hash;
}
return result;
},
navigateTo: function (index, hash) {
if (!index && !IV.index) {
IV.navigateToDOM(IV.index, hash);
return;
}
IV.pending = [index, hash];
if (!IV.cache[index]) {
IV.loadPage(index);
} else if (IV.cache[index].dom) {
IV.navigateToDOM(index, hash);
} else if (IV.cache[index].content) {
IV.navigateToLoaded(index, hash);
}
},
applyUpdatedContent: function (index) {
if (IV.index != index) {
IV.cache[index].contentUpdated = (IV.cache[index].dom !== undefined);
return;
}
var data = JSON.parse(IV.cache[index].content);
var article = function (el) {
return el.getElementsByTagName('article')[0];
};
var from = article(IV.findPageScroll());
var to = article(IV.makeScrolledContent(data.html));
morphdom(from, to, {
onBeforeElUpdated: function (fromEl, toEl) {
if (fromEl.classList.contains('video')
&& toEl.classList.contains('video')
&& fromEl.hasAttribute('data-src')
&& toEl.hasAttribute('data-src')
&& (fromEl.getAttribute('data-src')
== toEl.getAttribute('data-src'))) {
return false;
} else if (fromEl.tagName == 'SECTION'
&& fromEl.classList.contains('channel')
&& fromEl.hasAttribute('data-context')
&& toEl.tagName == 'SECTION'
&& toEl.classList.contains('channel')
&& toEl.hasAttribute('data-context')
&& (String(fromEl.getAttribute('data-context'))
== String(toEl.getAttribute('data-context')))) {
return false;
} else if (fromEl.classList.contains('loaded')) {
toEl.classList.add('loaded');
}
return !fromEl.isEqualNode(toEl);
}
});
IV.initMedia();
eval(data.js);
},
loadPage: function (index) {
if (!IV.cache[index]) {
IV.cache[index] = {};
}
IV.cache[index].loading = true;
let xhr = new XMLHttpRequest();
xhr.onload = function () {
IV.cache[index].loading = false;
IV.cache[index].content = xhr.responseText;
IV.applyUpdatedContent(index);
if (IV.pending && IV.pending[0] == index) {
IV.navigateToLoaded(index, IV.pending[1]);
}
if (IV.cache[index].reloadPending) {
IV.cache[index].reloadPending = false;
IV.reloadPage(index);
}
}
xhr.open('GET', 'page' + index + '.json');
xhr.send();
},
reloadPage: function (index) {
if (IV.cache[index] && IV.cache[index].loading) {
IV.cache[index].reloadPending = true;
return;
}
IV.loadPage(index);
},
makeScrolledContent: function (html) {
var result = document.createElement('div');
result.className = 'page-scroll';
result.tabIndex = '-1';
result.innerHTML = '<div class="page-slide"><article>'
+ html
+ '</article></div>';
result.onscroll = IV.frameScrolled;
return result;
},
navigateToLoaded: function (index, hash) {
if (IV.cache[index].dom) {
IV.navigateToDOM(index, hash);
} else {
var data = JSON.parse(IV.cache[index].content);
IV.cache[index].dom = IV.makeScrolledContent(data.html);
IV.navigateToDOM(index, hash);
eval(data.js);
}
},
navigateToDOM: function (index, hash) {
IV.pending = null;
if (IV.index == index) {
IV.jumpToHash(hash);
IV.forceScrollFocus();
return;
}
window.history.replaceState(
IV.computeCurrentState(),
'',
IV.pageUrl(IV.index));
IV.position = IV.position + 1;
window.history.pushState(
{ position: IV.position, index: index, hash: hash },
'',
IV.pageUrl(index));
IV.showDOM(index, hash);
},
findPageScroll: function () {
var all = document.getElementsByClassName('page-scroll');
for (i = 0; i < all.length; ++i) {
if (!all[i].classList.contains('hidden-left')
&& !all[i].classList.contains('hidden-right')) {
return all[i];
}
}
return null;
},
showDOM: function (index, hash, scroll) {
IV.pending = null;
if (IV.index != index) {
var initial = !window.history.state
|| window.history.state.position === undefined;
var back = initial
|| IV.position > window.history.state.position;
IV.position = initial ? 0 : window.history.state.position;
var now = IV.cache[index].dom;
var was = IV.findPageScroll();
if (!IV.cache[IV.index]) {
IV.cache[IV.index] = {};
}
IV.cache[IV.index].dom = was;
was.parentNode.appendChild(now);
if (scroll !== undefined) {
now.scrollTop = scroll;
setTimeout(function () {
// When returning by history.back to an URL with a hash
// for the first time browser forces the scroll to the
// hash instead of the saved scroll position.
//
// This workaround prevents incorrect scroll position.
now.scrollTop = scroll;
}, 0);
}
now.classList.add(back ? 'hidden-left' : 'hidden-right');
now.classList.remove(back ? 'hidden-right' : 'hidden-left');
IV.stopAnimations(now.firstChild);
if (!was.listening) {
was.listening = true;
was.firstChild.addEventListener('transitionend', function (e) {
if (was.classList.contains('hidden-left')
|| was.classList.contains('hidden-right')) {
if (was.parentNode) {
was.parentNode.removeChild(was);
var videos = was.getElementsByClassName('video');
for (var i = 0; i < videos.length; ++i) {
videos[i].innerHTML = '';
}
}
}
});
}
was.classList.add(back ? 'hidden-right' : 'hidden-left');
now.classList.remove(back ? 'hidden-left' : 'hidden-right');
IV.index = index;
IV.notify({
event: 'location_change',
index: IV.index,
position: IV.position,
hash: IV.computeCurrentState().hash,
});
if (IV.cache[index].contentUpdated) {
IV.cache[index].contentUpdated = false;
IV.applyUpdatedContent(index);
} else {
IV.initMedia();
}
IV.checkChannelButtons();
if (scroll === undefined) {
IV.jumpToHash(hash, true);
} else {
IV.lastScrollTop = scroll;
IV.updateJumpToTop(true);
}
} else if (scroll !== undefined) {
IV.scrollTo(scroll);
IV.lastScrollTop = scroll;
IV.updateJumpToTop(true);
} else {
IV.jumpToHash(hash);
}
IV.forceScrollFocus();
IV.frameScrolled();
},
forceScrollFocus: function () {
IV.findPageScroll().focus();
setTimeout(function () {
// Doesn't work on #hash-ed pages in Windows WebView2 otherwise.
IV.findPageScroll().focus();
}, 100);
},
stopAnimations: function (element) {
element.getAnimations().forEach(
(animation) => animation.finish());
},
back: function () {
window.history.back();
},
menuShown: function (shown) {
var already = document.getElementById('menu_page_blocker');
if (already && shown) {
return;
} else if (already) {
document.body.removeChild(already);
return;
} else if (!shown) {
return;
}
var blocker = document.createElement('div');
blocker.id = 'menu_page_blocker';
document.body.appendChild(blocker);
},
videos: {},
videosPlaying: {},
cache: {},
channelsJoined: {},
index: 0,
position: 0
};
document.onclick = IV.frameClickHandler;
document.onkeydown = IV.frameKeyDown;
document.onmouseenter = IV.frameMouseEnter;
document.onmouseup = IV.frameMouseUp;
document.onresize = IV.checkVideos;
window.onmessage = IV.postMessageHandler;
window.addEventListener('popstate', function (e) {
if (e.state) {
IV.showDOM(e.state.index, e.state.hash, e.state.scroll);
}
});
document.addEventListener("DOMContentLoaded", IV.forceScrollFocus);
+342 -89
View File
@@ -652,6 +652,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_messages_privacy" = "Messages";
"lng_settings_voices_privacy" = "Voice messages";
"lng_settings_bio_privacy" = "Bio";
"lng_settings_birthday_privacy" = "Date of Birth";
"lng_settings_privacy_premium" = "Only subscribers of {link} can restrict receiving voice messages.";
"lng_settings_privacy_premium_link" = "Telegram Premium";
"lng_settings_passcode_disable" = "Disable Passcode";
@@ -664,6 +665,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_phone_label" = "Phone number";
"lng_settings_username_add" = "Add username";
"lng_settings_username_about" = "Username lets people contact you on Telegram without needing your phone number.";
"lng_settings_birthday_label" = "Date of Birth";
"lng_settings_birthday_add" = "Add";
"lng_settings_birthday_about" = "Choose who can see your birthday in {link}.";
"lng_settings_birthday_about_link" = "Settings";
"lng_settings_birthday_contacts" = "Only your contacts can see your birthday. {link}";
"lng_settings_birthday_contacts_link" = "Change >";
"lng_settings_birthday_saved" = "Your date of birth was updated.";
"lng_settings_birthday_reset" = "Remove";
"lng_settings_channel_label" = "Personal channel";
"lng_settings_channel_add" = "Add";
"lng_settings_channel_remove" = "Remove";
"lng_settings_channel_no_yet" = "You don't have any public channels yet.";
"lng_settings_channel_start" = "Start a Channel";
"lng_settings_channel_saved" = "Your personal channel was updated.";
"lng_settings_channel_removed" = "Your personal channel was removed.";
"lng_settings_add_account_about" = "You can add up to four accounts with different phone numbers.";
"lng_settings_peer_to_peer_about" = "Disabling peer-to-peer will relay all calls through Telegram servers to avoid revealing your IP address, but may slightly decrease audio quality.";
"lng_settings_advanced" = "Advanced";
@@ -1087,12 +1103,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_privacy_everyone" = "Everybody";
"lng_edit_privacy_contacts" = "My contacts";
"lng_edit_privacy_close_friends" = "Close friends";
"lng_edit_privacy_contacts_and_premium" = "Contacts & Premium";
"lng_edit_privacy_nobody" = "Nobody";
"lng_edit_privacy_premium" = "Premium users";
"lng_edit_privacy_exceptions" = "Add exceptions";
"lng_edit_privacy_user_types" = "User types";
"lng_edit_privacy_users_and_groups" = "Users and groups";
"lng_edit_privacy_premium_status" = "all Telegram Premium subscribers";
"lng_edit_privacy_exceptions_count#one" = "{count} user";
"lng_edit_privacy_exceptions_count#other" = "{count} users";
"lng_edit_privacy_exceptions_premium_and" = "Premium & {users}";
"lng_edit_privacy_exceptions_add" = "Add users or groups";
"lng_edit_privacy_phone_number_title" = "Phone number privacy";
@@ -1136,6 +1157,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_privacy_about_always_title" = "Always allow";
"lng_edit_privacy_about_never_title" = "Never allow";
"lng_edit_privacy_birthday_title" = "Date of birth privacy";
"lng_edit_privacy_birthday_header" = "Who can see my date of birth";
"lng_edit_privacy_birthday_always_empty" = "Always allow";
"lng_edit_privacy_birthday_never_empty" = "Never allow";
"lng_edit_privacy_birthday_exceptions" = "These users will or will not be able to see your date of birth regardless of the settings above.";
"lng_edit_privacy_birthday_always_title" = "Always allow";
"lng_edit_privacy_birthday_never_title" = "Never allow";
"lng_edit_privacy_birthday_yet" = "You haven't entered your date of birth yet.\n{link}";
"lng_edit_privacy_birthday_yet_link" = "Add my birthday >";
"lng_edit_privacy_calls_title" = "Voice calls privacy";
"lng_edit_privacy_calls_header" = "Who can call you";
"lng_edit_privacy_calls_always_empty" = "Always allow";
@@ -1288,6 +1319,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_photo_by_you" = "photo set by you";
"lng_profile_public_photo" = "public photo";
"lng_invite_upgrade_title" = "Upgrade to Premium";
"lng_invite_upgrade_group_invite#one" = "{users} only accepts invitations to groups from Contacts and **Premium** users.";
"lng_invite_upgrade_group_invite#other" = "{users} only accept invitations to groups from Contacts and **Premium** users.";
"lng_invite_upgrade_group_write#one" = "{users} only accepts messages and invitations to groups from Contacts and **Premium** users.";
"lng_invite_upgrade_group_write#other" = "{users} only accept messages and invitations to groups from Contacts and **Premium** users.";
"lng_invite_upgrade_channel_invite#one" = "{users} only accepts invitations to channels from Contacts and **Premium** users.";
"lng_invite_upgrade_channel_invite#other" = "{users} only accept invitations to channels from Contacts and **Premium** users.";
"lng_invite_upgrade_channel_write#one" = "{users} only accepts messages and invitations to channels from Contacts and **Premium** users.";
"lng_invite_upgrade_channel_write#other" = "{users} only accept messages and invitations to channels from Contacts and **Premium** users.";
"lng_invite_upgrade_users_few" = "{users} and {last}";
"lng_invite_upgrade_users_many#one" = "{users} and **{count}** more person";
"lng_invite_upgrade_users_many#other" = "{users} and **{count}** more people";
"lng_invite_upgrade_or" = "or";
"lng_invite_upgrade_via_title" = "Invite via Link";
"lng_invite_upgrade_via_group_about" = "You can send an invite link to the group in a private message instead.";
"lng_invite_upgrade_via_channel_about" = "You can send an invite link to the channel in a private message instead.";
"lng_invite_status_disabled" = "available only to Premium users";
"lng_via_link_group_one" = "**{user}** restricts adding them to groups.\nYou can send them an invite link as message instead.";
"lng_via_link_group_many#one" = "**{count} user** restricts adding them to groups.\nYou can send them an invite link as message instead.";
"lng_via_link_group_many#other" = "**{count} users** restrict adding them to groups.\nYou can send them an invite link as message instead.";
@@ -1303,12 +1352,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_via_link_shared_many#one" = "Link shared with **{count} user**.";
"lng_via_link_shared_many#other" = "Link shared with **{count} users**.";
"lng_info_personal_channel_label" = "Channel";
"lng_info_mobile_label" = "Mobile";
"lng_info_mobile_context_menu_fragment_about" = "This number is not tied to a SIM card and was acquired on {link}.";
"lng_info_mobile_context_menu_fragment_about_link" = "Fragment";
"lng_info_mobile_hidden" = "Hidden";
"lng_info_username_label" = "Username";
"lng_info_usernames_label" = "also";
"lng_info_birthday_label" = "Date of birth";
"lng_info_birthday_years#one" = "{date} ({count} year old)";
"lng_info_birthday_years#other" = "{date} ({count} years old)";
"lng_info_birthday_today_years#one" = "{date}\n({count} year old)";
"lng_info_birthday_today_years#other" = "{date}\n({count} years old)";
"lng_info_birthday_today_label" = "Birthday today";
"lng_info_birthday_today" = "{emoji} {date}";
"lng_info_bio_label" = "Bio";
"lng_info_link_label" = "Link";
"lng_info_location_label" = "Location";
@@ -1540,6 +1597,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_report_button" = "Report";
"lng_report_thanks" = "Thank you! Your report will be reviewed by our team very soon.";
"lng_report_sponsored_hidden" = "Sponsored messages will be hidden.";
"lng_report_sponsored_reported" = "We will review this ad to ensure it matches out {link}.";
"lng_report_sponsored_reported_link" = "Ad Policies and Guidelines";
"lng_report_sponsored_reported_learn" = "Learn more about our {link}.";
"lng_channel_add_members" = "Add members";
"lng_channel_add_users" = "Add users";
"lng_channel_add_removed" = "Remove user";
@@ -1760,6 +1822,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_giveaway_results_none" = "No winners of the giveaway could be selected.";
"lng_action_boost_apply#one" = "{from} boosted the group";
"lng_action_boost_apply#other" = "{from} boosted the group {count} times";
"lng_action_set_chat_intro" = "{from} added the message below for all empty chats. How?";
"lng_similar_channels_title" = "Similar channels";
"lng_similar_channels_view_all" = "View all";
@@ -1919,6 +1982,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_forwarded_imported" = "This message was imported from another app. It may not be real.";
"lng_signed_author" = "Author: {user}";
"lng_sponsored_message_title" = "Sponsored";
"lng_sponsored_message_revenue_button" = "what's this?";
"lng_recommended_message_title" = "Recommended";
"lng_edited" = "edited";
"lng_commented" = "commented";
@@ -2185,6 +2249,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_business_about_away_messages" = "Define messages that are automatically sent when you are off.";
"lng_business_subtitle_chatbots" = "Chatbots";
"lng_business_about_chatbots" = "Add any third party chatbots that will process customer interactions.";
"lng_business_subtitle_chat_intro" = "Custom Intro";
"lng_business_about_chat_intro" = "Customize the message people see before they start a chat with you.";
"lng_business_subtitle_chat_links" = "Links to Chat";
"lng_business_about_chat_links" = "Create links that start a chat with you, suggesting the first message.";
"lng_location_title" = "Location";
"lng_location_about" = "Display the location of your business on your account.";
@@ -2286,8 +2354,52 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_chatbots_reply_about" = "The bot will be able to view all new incoming messages, but not the messages that had been sent before you added the bot.";
"lng_chatbots_remove" = "Remove Bot";
"lng_chatbots_not_found" = "Chatbot not found.";
"lng_chatbots_not_supported" = "This bot doesn't support Telegram Business yet.";
"lng_chatbots_add" = "Add";
"lng_chatbots_info_url" = "https://telegram.org/privacy";
"lng_chatbot_status_can_reply" = "bot manages this chat";
"lng_chatbot_status_paused" = "bot stopped";
"lng_chatbot_status_views" = "bot has access to this chat";
"lng_chatbot_button_pause" = "Stop";
"lng_chatbot_button_resume" = "Start";
"lng_chatbot_menu_manage" = "Manage bot";
"lng_chatbot_menu_remove" = "Remove bot from this chat";
"lng_chatbot_menu_revoke" = "Revoke access to this chat";
"lng_chat_intro_title" = "Custom Intro";
"lng_chat_intro_subtitle" = "Customize your intro";
"lng_chat_intro_default_title" = "No messages here yet...";
"lng_chat_intro_default_message" = "Send a message or click on the greeting below";
"lng_chat_intro_enter_title" = "Enter Title";
"lng_chat_intro_enter_message" = "Enter Message";
"lng_chat_intro_choose_sticker" = "Choose Sticker";
"lng_chat_intro_random_sticker" = "Random";
"lng_chat_intro_about" = "You can customize the message people see before they start a chat with you.";
"lng_chat_intro_reset" = "Reset to Default";
"lng_chat_links_title" = "Links to Chat";
"lng_chat_links_about" = "Give your customers short links that start a chat with you and suggest the first message from them to you.";
"lng_chat_links_create_link" = "Create a Link to Chat";
"lng_chat_links_footer" = "You can also use a simple link for a chat with you {links}";
"lng_chat_links_footer_both" = "{username} or {link}";
"lng_chat_links_no_clicks" = "no clicks";
"lng_chat_links_clicks#one" = "{count} click";
"lng_chat_links_clicks#other" = "{count} clicks";
"lng_chat_link_new_title" = "New Link";
"lng_chat_link_edit_title" = "Edit Link";
"lng_chat_link_description" = "Add a message that will be entered in the message field for anyone who starts a chat with you using this link.";
"lng_chat_link_placeholder" = "Add Preset Message";
"lng_chat_link_saved" = "Chat link saved.";
"lng_chat_link_copy" = "Copy";
"lng_chat_link_share" = "Share";
"lng_chat_link_rename" = "Rename";
"lng_chat_link_delete" = "Delete";
"lng_chat_link_name" = "Link Name (optional)";
"lng_chat_link_name_about" = "Add a name for this link that only you will see.";
"lng_chat_link_delete_sure" = "Are you sure you want to delete this chat link?";
"lng_chat_link_qr_title" = "Chat Link QR Code";
"lng_chat_link_qr_about" = "Everyone on Telegram can scan this code to contact you.";
"lng_chat_link_copied" = "Chat link copied to clipboard.";
"lng_boost_channel_button" = "Boost Channel";
"lng_boost_group_button" = "Boost Group";
@@ -2387,6 +2499,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_boost_channel_needs_level_reactions#one" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as a reaction.";
"lng_boost_channel_needs_level_reactions#other" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as reactions.";
"lng_boost_channel_title_cpm" = "Boost Channel";
"lng_boost_channel_needs_level_cpm#one" = "Your channel needs to reach **Level {count}** to switch off ads.";
"lng_boost_channel_needs_level_cpm#other" = "Your channel needs to reach **Level {count}** to switch off ads.";
"lng_boost_group_title_emoji" = "Enable emoji pack";
"lng_boost_group_needs_level_emoji#one" = "Your group needs to reach **Level {count}** to set emoji pack.";
"lng_boost_group_needs_level_emoji#other" = "Your group needs to reach **Level {count}** to set emoji pack.";
@@ -2593,6 +2709,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"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_already_title" = "You already have Telegram Premium";
"lng_gift_link_already_about" = "You can activate this link after {date} or {link} to a friend.";
"lng_gift_link_already_link" = "send the 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}.";
@@ -2883,6 +3002,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_bot_remove_from_side_menu_done" = "Bot removed from the main menu.";
"lng_bot_settings" = "Settings";
"lng_bot_open" = "Open Bot";
"lng_bot_terms" = "Terms of Use";
"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.";
@@ -3013,6 +3133,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_delete_msg" = "Delete Message";
"lng_context_auto_delete_in" = "auto-delete in {duration}";
"lng_context_select_msg" = "Select Message";
"lng_context_select_msg_bulk" = "Select up to this message";
"lng_context_report_msg" = "Report Message";
"lng_context_pin_msg" = "Pin Message";
"lng_context_unpin_msg" = "Unpin Message";
@@ -3511,6 +3632,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_call_cancel" = "Cancel";
"lng_call_microphone_off" = "{user}'s microphone is off";
"lng_call_battery_level_low" = "{user}'s battery level is low";
"lng_group_call_title" = "Voice Chat";
"lng_group_call_title_channel" = "Live Stream";
@@ -4561,6 +4683,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_view_button_external_link" = "Open link";
"lng_view_button_boost" = "Boost";
"lng_view_button_giftcode" = "Open";
"lng_view_button_iv" = "Instant View";
"lng_sponsored_hide_ads" = "Hide";
"lng_sponsored_title" = "What are sponsored messages?";
@@ -4568,6 +4691,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_sponsored_info_description2" = "Sponsored Messages are currently in test mode. Once they are fully launched and allow Telegram to cover its basic costs, we will start sharing ad revenue with the owners of public channels in which sponsored messages are displayed.\n\nOnline ads should no longer be synonymous with abuse of user privacy. Let us redefine how a tech company should operate together.";
"lng_sponsored_info_menu" = "About this ad";
"lng_sponsored_info_submenu" = "Advertiser: {text}";
"lng_sponsored_menu_revenued_about" = "About These Ads";
"lng_sponsored_menu_revenued_report" = "Report Ad";
"lng_sponsored_revenued_subtitle" = "Telegram Ads are very different from ads on other platforms. Ads such as this one:";
"lng_sponsored_revenued_info1_title" = "Respect Your Privacy";
"lng_sponsored_revenued_info1_description" = "Ads on Telegram do not use your personal information and are abased on the channel in which you see them.";
"lng_sponsored_revenued_info2_title" = "Help the Channel Creator";
"lng_sponsored_revenued_info2_description" = "50% of the revenue from Telegram Ads goes to the owner of the channel where they are displayed.";
"lng_sponsored_revenued_info3_title" = "Can Be Removed";
"lng_sponsored_revenued_info3_description#one" = "You can turn off ads by subscribing to {link}, and Level {count} channels can remove them for their subscribers.";
"lng_sponsored_revenued_info3_description#other" = "You can turn off ads by subscribing to {link}, and Level {count} channels can remove them for their subscribers.";
"lng_sponsored_revenued_footer_title" = "Can I Launch an Ad?";
"lng_sponsored_revenued_footer_description" = "Anyone can create an ad to display in this channel — with minimal budgets. Check out the **Telegram Ad Platform** for details. {link}";
"lng_telegram_features_url" = "https://t.me/TelegramTips";
@@ -4863,9 +4998,74 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_boosts_prepaid_giveaway_status#one" = "{count} subscription {duration}";
"lng_boosts_prepaid_giveaway_status#other" = "{count} subscriptions {duration}";
"lng_channel_earn_title" = "Monetization";
"lng_channel_earn_about" = "Telegram shares 50% of the revenue from ads displayed in your channel. {link}";
"lng_channel_earn_about_link" = "Learn more {emoji}";
"lng_channel_earn_overview_title" = "Proceeds overview";
"lng_channel_earn_available" = "Balance available to withdraw";
"lng_channel_earn_reward" = "Proceeds since last withdrawal";
"lng_channel_earn_total" = "Total lifetime proceeds";
"lng_channel_earn_balance_title" = "Available balance";
"lng_channel_earn_balance_button" = "Withdraw";
"lng_channel_earn_balance_password_title" = "Two-step verification";
"lng_channel_earn_balance_password_description" = "Please enter your password to withdraw.";
"lng_channel_earn_balance_about" = "Collect your reward using Fragment, a third-party platform used by the advertiser to pay for the ad. {link}";
"lng_channel_earn_balance_about_temp" = "In the coming weeks you will be able to collect your reward using Fragment, a third-party platform used by advertisers to pay ads. {link}";
"lng_channel_earn_transfer_sure_about1" = "Check the address of the recipient:";
"lng_channel_earn_transfer_sure_about2" = "This action can not be undone. If the address above is incorrect you will lose your TON.";
"lng_channel_earn_history_title" = "Transaction history";
"lng_channel_earn_history_in" = "Proceeds from ads";
"lng_channel_earn_history_in_about" = "Proceeds from ads displayed in";
"lng_channel_earn_history_out" = "Withdrawal";
"lng_channel_earn_history_out_failed" = "Not Completed";
"lng_channel_earn_history_out_about_failed" = "Withdrawal failed";
"lng_channel_earn_history_out_button" = "View in Blockchain Explorer";
"lng_channel_earn_history_return" = "Refund";
"lng_channel_earn_history_return_about" = "Refunded back";
"lng_channel_earn_history_pending" = "Pending";
"lng_channel_earn_history_show_more#one" = "Show {count} More Transaction";
"lng_channel_earn_history_show_more#other" = "Show {count} More Transactions";
"lng_channel_earn_off" = "Switch Off Ads";
"lng_channel_earn_off_about" = "You will not be eligible for any rewards if you switch off ads.";
"lng_channel_earn_cpm_min" = "No Ads";
"lng_channel_earn_cpm#one" = "{emoji} {count} CPM";
"lng_channel_earn_cpm#other" = "{emoji} {count} CPM";
"lng_channel_earn_learn_title" = "Earn From Your Channel";
"lng_channel_earn_learn_in_subtitle" = "Telegram Ads";
"lng_channel_earn_learn_in_about" = "Telegram can display ads in your channel.";
"lng_channel_earn_learn_split_subtitle" = "50:50 revenue split";
"lng_channel_earn_learn_split_about" = "You can receive 50% of the ad revenue in TON.";
"lng_channel_earn_learn_out_subtitle" = "Flexible withdrawals";
"lng_channel_earn_learn_out_about" = "You can withdraw your TON any time.";
"lng_channel_earn_learn_coin_title" = "What is {emoji} TON?";
"lng_channel_earn_learn_coin_about" = "TON is a blockchain platform and cryptocurrency that Telegram uses for its high speed and low commissions on transactions. {link}";
"lng_channel_earn_learn_close" = "Got it";
"lng_channel_earn_chart_top_hours" = "Ad impressions";
"lng_channel_earn_chart_revenue" = "Ad revenue";
"lng_channel_earn_chart_overriden_detail_currency" = "Revenue in TON";
"lng_channel_earn_chart_overriden_detail_usd" = "Revenue in USD";
"lng_contact_add" = "Add";
"lng_contact_send_message" = "message";
"lng_iv_open_in_browser" = "Open in Browser";
"lng_iv_share" = "Share";
"lng_iv_join_channel" = "Join";
"lng_iv_window_title" = "Instant View";
"lng_limit_download_title" = "Download speed limited";
"lng_limit_download_subscribe" = "Subscribe to {link} and increase download speed {increase}.";
"lng_limit_download_increase_times#one" = "**{count}** time";
"lng_limit_download_increase_times#other" = "**{count}** times";
"lng_limit_download_increase_speed" = "by **{percent}**";
"lng_limit_download_subscribe_link" = "Telegram Premium";
"lng_limit_upload_title" = "Upload speed limited";
"lng_limit_upload_subscribe" = "Subscribe to {link} and increase upload speed {increase}.";
"lng_limit_upload_increase_times#one" = "**{count}** time";
"lng_limit_upload_increase_times#other" = "**{count}** times";
"lng_limit_upload_increase_speed" = "by **{percent}**";
"lng_limit_upload_subscribe_link" = "Telegram Premium";
// Wnd specific
"lng_wnd_choose_program_menu" = "Choose Default Program...";
@@ -4937,27 +5137,33 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_AyuPreferences" = "AyuGram Preferences";
"ayu_DocsText" = "Documentation";
"ayu_CategoryGhostMode" = "Ghost Mode";
"ayu_CategorySpy" = "Spy";
"ayu_CategoryFilters" = "Filters";
"ayu_CategoryCustomization" = "Customization";
"ayu_GhostEssentialsHeader" = "Ghost essentials";
"ayu_DontReadMessages" = "Don't read messages";
"ayu_DontReadStories" = "Don't read stories";
"ayu_DontSendOnlinePackets" = "Don't send online";
"ayu_DontSendUploadProgress" = "Don't send typing";
"ayu_SendOfflinePacketAfterOnline" = "Immediate offline after online";
"ayu_MarkReadAfterAction" = "Mark read after actions";
"ayu_DontReadMessages" = "Don't Read Messages";
"ayu_DontReadStories" = "Don't Read Stories";
"ayu_DontSendOnlinePackets" = "Don't Send Online";
"ayu_DontSendUploadProgress" = "Don't Send Typing";
"ayu_SendOfflinePacketAfterOnline" = "Go Offline Automatically";
"ayu_MarkReadAfterAction" = "Read on Interact";
"ayu_MarkReadAfterActionDescription" = "Automatically reads message when you send a new one or tap a reaction.";
"ayu_MarkReadAfterSend" = "Send";
"ayu_MarkReadAfterReaction" = "Reaction";
"ayu_MarkReadAfterPoll" = "Poll";
"ayu_UseScheduledMessages" = "Schedule messages";
"ayu_SuggestGhostModeBeforeViewingStory" = "Alert before opening story";
"ayu_UseScheduledMessages" = "Schedule Messages";
"ayu_UseScheduledMessagesDescription" = "Automatically schedules outgoing messages for ~12 seconds, and more for media. Don't use on bad networks.";
"ayu_SendWithoutSoundByDefault" = "Send without Sound";
"ayu_SendWithoutSoundByDefaultDescription" = "Automatically sends outgoing messages without sound.";
"ayu_SuggestGhostModeBeforeViewingStory" = "Story Ghost Mode Alert";
"ayu_SuggestGhostModeBeforeViewingStoryDescription" = "Shows an alert before opening the story, suggesting to turn on Ghost Mode.";
"ayu_SpyEssentialsHeader" = "Spy essentials";
"ayu_SaveDeletedMessages" = "Save deleted messages";
"ayu_SaveMessagesHistory" = "Save edits history";
"ayu_SaveDeletedMessages" = "Save Deleted Messages";
"ayu_SaveMessagesHistory" = "Save Edits History";
"ayu_MessageSavingActionBarHeader" = "Message Saving Preferences";
"ayu_MessageSavingBtn" = "Preferences";
"ayu_MessageSavingSubTitle" = "Configure media & per dialog saving";
"ayu_MessageSavingMediaHeader" = "Media";
"ayu_MessageSavingSaveMedia" = "Save media";
"ayu_MessageSavingSaveMediaHint" = "Click for more";
"ayu_MessageSavingSaveMedia" = "Save Media";
"ayu_MessageSavingSaveMediaHint" = "Click for More";
"ayu_MessageSavingSaveMediaInPrivateChats" = "…in private chats";
"ayu_MessageSavingSaveMediaInPublicChannels" = "…in public channels";
"ayu_MessageSavingSaveMediaInPrivateChannels" = "…in private channels";
@@ -4967,47 +5173,57 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_MaximumMediaSizeWiFi" = "Media size limit (WiFi)";
"ayu_MessageSavingOtherHeader" = "Other";
"ayu_MessageSavingSaveReactions" = "Save reactions";
"ayu_MessageSavingSaveForBots" = "Save in bot dialogs";
"ayu_MessageSavingSavePath" = "Attachments folder";
"ayu_MessageSavingSaveForBots" = "Save in Bot Dialogs";
"ayu_MessageSavingSavePath" = "Attachments Folder";
"ayu_MessageSavingSavePathTitle" = "Choose folder";
"ayu_SpyAllToggle" = "Spy on people";
"ayu_SpySaveReadMarks" = "Save read date";
"ayu_SpySaveLastActivity" = "Save last activity";
"ayu_SpySaveReadMarks" = "Save Read Date";
"ayu_SpySaveReadMarksDescription" = "Locally saves data about reading messages. This will be shown if Telegram does not provide read date.";
"ayu_QoLTogglesHeader" = "Useful features";
"ayu_KeepAliveService" = "AyuGram Push Service";
"ayu_DisableAds" = "Disable ads";
"ayu_DisableStories" = "Disable stories";
"ayu_DisableCustomBackgrounds" = "Disable custom backgrounds";
"ayu_DisableNotificationsDelay" = "Disable notify delay";
"ayu_DisableAds" = "Disable Ads";
"ayu_DisableStories" = "Disable Stories";
"ayu_DisableCustomBackgrounds" = "Disable Custom Backgrounds";
"ayu_DisableNotificationsDelay" = "Disable Notify Delay";
"ayu_LocalPremium" = "Local Telegram Premium";
"ayu_CopyUsernameAsLink" = "Copy username as link";
"ayu_CopyUsernameAsLink" = "Copy Username as Link";
"ayu_CustomizationHeader" = "Customization";
"ayu_DeletedMarkText" = "Deleted mark";
"ayu_DeletedMarkText" = "Deleted Mark";
"ayu_DeletedMarkNothing" = "Nothing";
"ayu_DeletedMarkTrashBin" = "Trash Bin";
"ayu_DeletedMarkCross" = "Cross";
"ayu_DeletedMarkEyeCrossed" = "Eye crossed";
"ayu_EditedMarkText" = "Edited mark";
"ayu_SemiTransparentDeletedMessages" = "Semi-transparent deleted messages";
"ayu_HideNotificationCounters" = "Hide notification counters";
"ayu_HideAllChats" = "Hide \"All chats\" folder";
"ayu_ShowGhostToggleInDrawer" = "Show ghost mode toggle";
"ayu_ShowKllButtonInDrawer" = "Show kill app button";
"ayu_SettingsShowID" = "Show peer ID";
"ayu_DeletedMarkEyeCrossed" = "Eye Crossed";
"ayu_EditedMarkText" = "Edited Mark";
"ayu_SemiTransparentDeletedMessages" = "Translucent Deleted Messages";
"ayu_HideNotificationCounters" = "Hide Notification Counters";
"ayu_HideAllChats" = "Hide \"All Chats\" Tab";
"ayu_SettingsShowID" = "Show Peer ID";
"ayu_SettingsShowID_Hide" = "Hide";
"ayu_SettingsShowMessageShot" = "Show message shot";
"ayu_SettingsRecentStickersCount" = "Recent stickers count";
"ayu_SettingsShowMessageShot" = "Show Message Shot";
"ayu_SettingsRecentStickersCount" = "Recent Stickers Count";
"ayu_SettingsCustomizationHint" = "After making changes to the \"Customization\" section, you must restart the application.";
"ayu_SettingsContextMenuTitle" = "Select item show type";
"ayu_SettingsContextMenuTitle" = "Choose when to show the item";
"ayu_SettingsContextMenuDescription" = "Extended menu items will be displayed if you hold CTRL or SHIFT while right-clicking on the message.";
"ayu_SettingsContextMenuItemHidden" = "Hidden";
"ayu_SettingsContextMenuItemShown" = "Shown";
"ayu_SettingsContextMenuItemExtended" = "Extended menu";
"ayu_SettingsContextMenuItemExtended" = "Extended Menu";
"ayu_SettingsContextMenuReactionsPanel" = "Reactions Panel";
"ayu_SettingsContextMenuViewsPanel" = "Views Panel";
"ayu_ContextMenuElementsHeader" = "Context Menu Elements";
"ayu_DrawerElementsHeader" = "Drawer Elements";
"ayu_TrayElementsHeader" = "Tray Elements";
"ayu_ExportDataTitle" = "Export AyuGram Database?";
"ayu_ExportDataDescription" = "It will be exported to the public folder, to Saved Attachments.";
"ayu_ExportDataConfirm" = "Yes, export";
"ayu_ExportDataCancel" = "No, close window";
"ayu_ExportDataSuccess" = "Database exported successfully.";
"ayu_ExportDataFailure" = "Failed to export database.";
"ayu_ImportDataNotFound" = "No database to import.";
"ayu_ImportDataTitle" = "Import AyuGram Database?";
"ayu_ImportDataDescription" = "It will replace the current database.";
"ayu_ImportDataConfirm" = "Yes, replace existing";
"ayu_ImportDataCancel" = "No, close window";
"ayu_ImportDataSuccess" = "Database imported successfully.";
"ayu_ImportDataFailure" = "Failed to import database.";
"ayu_RegexFilters" = "Message Filters";
"ayu_RegexFiltersAmount_zero" = "%1$d filters";
"ayu_RegexFiltersAmount_one" = "1 filter";
@@ -5022,40 +5238,78 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_RegexFiltersExcludedAmount_many" = "%1$d excluded";
"ayu_RegexFiltersExcludedAmount_other" = "%1$d excluded";
"ayu_RegexFiltersHeader" = "Filters";
"ayu_RegexFiltersShared" = "Shared filters";
"ayu_RegexFiltersExcluded" = "Excluded filters";
"ayu_FiltersHideFromBlocked" = "Hide from blocked users";
"ayu_RegexFiltersShared" = "Shared Filters";
"ayu_RegexFiltersExcluded" = "Excluded Filters";
"ayu_RegexFiltersEnable" = "Enable Filters";
"ayu_FiltersHideFromBlocked" = "Hide from Blocked Users";
"ayu_FiltersHideFromBlockedNote" = "Message filters were enabled.";
"ayu_RegexFiltersEnableSharedInChats" = "Enable shared filters in chats";
"ayu_RegexFiltersAdd" = "Add filter";
"ayu_RegexFiltersEdit" = "Edit filter";
"ayu_RegexFiltersEnableSharedInChats" = "Enable Shared Filters in Chats";
"ayu_RegexFiltersAdd" = "Add Filter";
"ayu_RegexFiltersEdit" = "Edit Filter";
"ayu_RegexFiltersPlaceholder" = "Expression";
"ayu_EnableExpression" = "Enable expression";
"ayu_CaseInsensitiveExpression" = "Case insensitive expression";
"ayu_RegexFiltersAddError" = "Regex syntax error";
"ayu_RegexFilterQuickAdd" = "Add filter";
"ayu_RegexFilterQuickAdd" = "Add Filter";
"ayu_RegexFilterBulletinText" = "Filter added to the **Shared filters**.";
"ayu_RegexFilterBulletinAction" = "Move to current chat";
"ayu_AyuSyncHeader" = "AyuSync";
"ayu_AyuSyncStatusTitle" = "Sync status";
"ayu_AyuSyncStatusOk" = "connected";
"ayu_AyuSyncStatusErrorDisconnected" = "disconnected";
"ayu_AyuSyncStatusErrorNoToken" = "no token";
"ayu_AyuSyncStatusErrorInvalidToken" = "invalid token";
"ayu_AyuSyncServerURL" = "Server URL";
"ayu_AyuSyncServerToken" = "Access token";
"ayu_AyuSyncEnable" = "Enable synchronization";
"ayu_AyuSyncVisitProfile" = "Visit profile";
"ayu_AyuSyncForceSync" = "Force sync clients";
"ayu_AyuSyncDeviceIdentifier" = "Device ID";
"ayu_AyuSyncLastEventSent" = "Last sent event";
"ayu_AyuSyncLastEventReceived" = "Last received event";
"ayu_AyuSyncLastEventNever" = "never";
"ayu_AyuSyncUseSecureConnection" = "Use HTTPS & WSS";
"ayu_AyuSyncIdentifierCopied" = "Identifier copied to clipboard.";
"ayu_AyuSyncRegisterStatusCode" = "Register status code";
"ayu_AyuSyncOpenPreferences" = "Open preferences";
"ayu_AyuSyncDownloadAgent" = "Download agent";
"ayu_RegexFilterBulletinAction" = "To Current Chat";
"ayu_FiltersMenuSelectChat" = "Select Chat";
"ayu_FiltersMenuImport" = "Import";
"ayu_FiltersMenuExport" = "Export";
"ayu_FiltersMenuClear" = "Clear";
"ayu_FiltersImportTitle" = "Select a way to import filters";
"ayu_FiltersImportClipboard" = "Paste from Clipboard";
"ayu_FiltersImportURL" = "Import from URL";
"ayu_FiltersImportAction" = "Import";
"ayu_FiltersExportTitle" = "Select a way to export filters";
"ayu_FiltersExportClipboard" = "Copy to Clipboard";
"ayu_FiltersExportURL" = "Publish on dpaste.com";
"ayu_FiltersToastFailPublish" = "Failed to publish filters.";
"ayu_FiltersToastFailFetch" = "Failed to fetch filters.";
"ayu_FiltersToastFailImport" = "Failed to import filters.";
"ayu_FiltersToastFailNoChanges" = "Filters are the same as current.";
"ayu_FiltersToastSuccess" = "Filters successfully imported.";
"ayu_FiltersSheetTitle" = "Apply filter changes?";
"ayu_FiltersSheetNewFilters_zero" = "**%1$d** new filters";
"ayu_FiltersSheetNewFilters_one" = "**1** new filter";
"ayu_FiltersSheetNewFilters_two" = "**%1$d** new filters";
"ayu_FiltersSheetNewFilters_few" = "**%1$d** new filters";
"ayu_FiltersSheetNewFilters_many" = "**%1$d** new filters";
"ayu_FiltersSheetNewFilters_other" = "**%1$d** new filters";
"ayu_FiltersSheetRemovedFilters_zero" = "**%1$d** removed filters";
"ayu_FiltersSheetRemovedFilters_one" = "**1** removed filter";
"ayu_FiltersSheetRemovedFilters_two" = "**%1$d** removed filters";
"ayu_FiltersSheetRemovedFilters_few" = "**%1$d** removed filters";
"ayu_FiltersSheetRemovedFilters_many" = "**%1$d** removed filters";
"ayu_FiltersSheetRemovedFilters_other" = "**%1$d** removed filters";
"ayu_FiltersSheetUpdatedFilters_zero" = "**%1$d** updated filters";
"ayu_FiltersSheetUpdatedFilters_one" = "**1** updated filter";
"ayu_FiltersSheetUpdatedFilters_two" = "**%1$d** updated filters";
"ayu_FiltersSheetUpdatedFilters_few" = "**%1$d** updated filters";
"ayu_FiltersSheetUpdatedFilters_many" = "**%1$d** updated filters";
"ayu_FiltersSheetUpdatedFilters_other" = "**%1$d** updated filters";
"ayu_FiltersSheetNewExclusions_zero" = "**%1$d** new exclusions";
"ayu_FiltersSheetNewExclusions_one" = "**1** new exclusion";
"ayu_FiltersSheetNewExclusions_two" = "**%1$d** new exclusions";
"ayu_FiltersSheetNewExclusions_few" = "**%1$d** new exclusions";
"ayu_FiltersSheetNewExclusions_many" = "**%1$d** new exclusions";
"ayu_FiltersSheetNewExclusions_other" = "**%1$d** new exclusions";
"ayu_FiltersSheetRemovedExclusions_zero" = "**%1$d** removed exclusions";
"ayu_FiltersSheetRemovedExclusions_one" = "**1** removed exclusion";
"ayu_FiltersSheetRemovedExclusions_two" = "**%1$d** removed exclusions";
"ayu_FiltersSheetRemovedExclusions_few" = "**%1$d** removed exclusions";
"ayu_FiltersSheetRemovedExclusions_many" = "**%1$d** removed exclusions";
"ayu_FiltersSheetRemovedExclusions_other" = "**%1$d** removed exclusions";
"ayu_FiltersSheetDialogsToResolve_zero" = "**%1$d** dialogs to resolve";
"ayu_FiltersSheetDialogsToResolve_one" = "**1** dialog to resolve";
"ayu_FiltersSheetDialogsToResolve_two" = "**%1$d** dialogs to resolve";
"ayu_FiltersSheetDialogsToResolve_few" = "**%1$d** dialogs to resolve";
"ayu_FiltersSheetDialogsToResolve_many" = "**%1$d** dialogs to resolve";
"ayu_FiltersSheetDialogsToResolve_other" = "**%1$d** dialogs to resolve";
"ayu_FiltersClearPopupTitle" = "Clear filters";
"ayu_FiltersClearPopupText" = "Are you sure you want to clear all filters?";
"ayu_FiltersClearPopupActionText" = "Clear";
"ayu_FiltersClearPopupAltActionText" = "Clear unknown";
"ayu_IconDefault" = "Default";
"ayu_IconAlternative" = "AyuGram Alt";
"ayu_IconDiscord" = "Discord";
@@ -5066,15 +5320,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_IconYaPlus" = "Yandex Plus";
"ayu_WALMode" = "Enable WAL mode";
"ayu_PushNotificationCount" = "FCM notifications received";
"ayu_ClearAyuDatabase" = "Clear Ayu Database";
"ayu_ClearAyuDatabaseNotification" = "AyuGram database cleared";
"ayu_ClearAyuAttachments" = "Clear Ayu Attachments";
"ayu_ClearAyuDatabase" = "Clear Messages Database";
"ayu_ClearAyuAttachmentsNotification" = "AyuGram attachments folder cleared";
"ayu_EraseLocalDatabase" = "Erase Local Database";
"ayu_ClearTelegramDatabase" = "Clear Telegram Database";
"ayu_ClearAyuDatabaseNotification" = "AyuGram database cleared";
"ayu_ClearAyuAttachments" = "Clear Attachments Folder";
"ayu_ConfirmationsTitle" = "Confirmations";
"ayu_StickerConfirmation" = "For stickers";
"ayu_StickerConfirmation" = "For Stickers";
"ayu_GIFConfirmation" = "For GIFs";
"ayu_VoiceConfirmation" = "For voice messages";
"ayu_VoiceConfirmation" = "For Voice Messages";
"ayu_MessageDetailsPC" = "Details";
"ayu_MessageDetailsViewsPC" = "Views";
"ayu_MessageDetailsSharesPC" = "Shares";
@@ -5099,12 +5353,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_DisableGhostMode" = "Disable Ghost";
"ayu_EnableGhostModeTray" = "Enable Ghost Mode";
"ayu_DisableGhostModeTray" = "Disable Ghost Mode";
"ayu_GhostModeEnabled" = "Ghost mode turned on";
"ayu_GhostModeDisabled" = "Ghost mode turned off";
"ayu_GhostModeEnabled" = "Ghost Mode turned on";
"ayu_GhostModeDisabled" = "Ghost Mode turned off";
"ayu_StreamerModeToggle" = "Streamer Mode";
"ayu_EnableStreamerModeTray" = "Enable Streamer Mode";
"ayu_DisableStreamerModeTray" = "Disable Streamer Mode";
"ayu_EditsHistoryTitle" = "Edits history";
"ayu_EditsHistoryTitle" = "Edits History";
"ayu_EditsHistoryMenuText" = "History";
"ayu_PeekOnlineMenuText" = "Peek Online";
"ayu_ClearDeletedMenuText" = "Clear Deleted";
@@ -5129,15 +5383,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_HideNextViewsDescriptionAyu" = "Hide my views forever, until Ghost Mode disabled.";
"ayu_EnableGhostModeStories" = "Enable Ghost Mode";
"ayu_GhostModeIsActive" = "Ghost Mode Is Active";
"ayu_SimpleQuotesAndReplies" = "Disable colorful replies";
"ayu_DisableSimilarChannels" = "Disable similar channels";
"ayu_CollapseSimilarChannels" = "Collapse similar channels";
"ayu_HideSimilarChannelsTab" = "Hide similar channels tab";
"ayu_UploadSpeedBoostPC" = "Upload speed boost";
"ayu_MainFont" = "Application font";
"ayu_MonospaceFont" = "Monospace font";
"ayu_SimpleQuotesAndReplies" = "Disable Colorful Replies";
"ayu_DisableSimilarChannels" = "Disable Similar Channels";
"ayu_CollapseSimilarChannels" = "Collapse Similar Channels";
"ayu_HideSimilarChannelsTab" = "Hide Similar Channels Tab";
"ayu_UploadSpeedBoostPC" = "Upload Speed Boost";
"ayu_MainFont" = "Application Font";
"ayu_MonospaceFont" = "Monospace Font";
"ayu_FontDefault" = "Default";
"ayu_CustomizeFontTitle" = "Customize font";
"ayu_CustomizeFontTitle" = "Customize Font";
"ayu_MessageShotTopBarText" = "Shot";
"ayu_MessageShotPreview" = "Preview";
"ayu_MessageShotPreferences" = "Preferences";
@@ -5163,22 +5417,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_DeleteDateMenuText" = "Delete Date";
"ayu_ReadDateMenuText" = "Read Date";
"ayu_ContentsReadDateMenuText" = "Contents Read Date";
"ayu_ForwardableMenuText" = "Forwardable";
"ayu_ForwardableMenuTextNo" = "No";
"ayu_UnforwardableContextMenuText" = "Plain forwarding is not allowed.";
"ayu_LikelyOfflineStatus" = "offline ?";
"ayu_GhostModeShortcut" = "Enter with Ghost";
"ayu_SettingsShowMessageSeconds" = "Show message seconds";
"ayu_SettingsShowMessageSeconds" = "Show Message Seconds";
"ayu_ContextCopyID" = "Copy ID";
"ayu_IDCopiedToast" = "ID copied to clipboard.";
"ayu_ContextHideMessage" = "Hide";
"ayu_ContextCopyCallbackData" = "Copy Callback Data";
"ayu_RegisterURLScheme" = "Register URL scheme";
"ayu_RegisterURLScheme" = "Register URL Scheme";
"ayu_LocalPremiumNotice" = "You're using **local** Telegram Premium.\nIt **won't** give you any benefits, except translator.\n**Enjoy the star near your nickname!**";
"ayu_SettingsWatermark" = "AyuGram developed and maintained by Radolyn Labs.";
"ayu_ConfirmationSticker" = "Do you want to send this sticker?";
"ayu_ConfirmationGIF" = "Do you want to send this GIF?";
"ayu_ConfirmationVoice" = "Do you want to send this voice message?";
"ayu_IntroAbout" = "Welcome to the AyuGram Desktop.\nIt's cool and looks less ugly.";
"ayu_AboutText1" = "Just a cool Telegram client based on {api_link}.";
"ayu_IntroAbout" = "Welcome to the AyuGram Desktop.\nMake Telegram your own.";
"ayu_AboutText1" = "ToS breaking Telegram client based on {api_link}.";
"ayu_UpdateAyuGram" = "Update AyuGram";
"ayu_UtilityRestartRequired" = "App will close in 5 seconds.";
@@ -21,5 +21,6 @@
<file alias="writing.tgs">../../animations/writing.tgs</file>
<file alias="hours.tgs">../../animations/hours.tgs</file>
<file alias="phone.tgs">../../animations/phone.tgs</file>
<file alias="chat_link.tgs">../../animations/chat_link.tgs</file>
</qresource>
</RCC>
+9
View File
@@ -0,0 +1,9 @@
<RCC>
<qresource prefix="/iv">
<file alias="page.css">../../iv_html/page.css</file>
<file alias="page.js">../../iv_html/page.js</file>
<file alias="highlight.css">../../iv_html/highlight.9.12.0.css</file>
<file alias="highlight.js">../../iv_html/highlight.9.12.0.js</file>
<file alias="morphdom.js">../../iv_html/morphdom-umd.min.2.7.2.js</file>
</qresource>
</RCC>
+1 -1
View File
@@ -10,7 +10,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="4.15.2.0" />
Version="4.16.0.0" />
<Properties>
<DisplayName>Telegram Desktop</DisplayName>
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
+4 -4
View File
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,15,2,0
PRODUCTVERSION 4,15,2,0
FILEVERSION 4,16,0,0
PRODUCTVERSION 4,16,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop"
VALUE "FileVersion", "4.15.2.0"
VALUE "FileVersion", "4.16.0.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
VALUE "ProductName", "AyuGram Desktop"
VALUE "ProductVersion", "4.15.2.0"
VALUE "ProductVersion", "4.16.0.0"
END
END
BLOCK "VarFileInfo"
+4 -4
View File
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,15,2,0
PRODUCTVERSION 4,15,2,0
FILEVERSION 4,16,0,0
PRODUCTVERSION 4,16,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -53,10 +53,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop Updater"
VALUE "FileVersion", "4.15.2.0"
VALUE "FileVersion", "4.16.0.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
VALUE "ProductName", "AyuGram Desktop"
VALUE "ProductVersion", "4.15.2.0"
VALUE "ProductVersion", "4.16.0.0"
END
END
BLOCK "VarFileInfo"
+4 -4
View File
@@ -421,10 +421,10 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
MTP_int(itemId),
MTP_int(id),
MTP_vector_from_range(
result
| ranges::views::transform([](
not_null<PeerData*> peer) {
return MTPInputPeer(peer->input); }))
result | ranges::views::transform([](
not_null<PeerData*> peer) {
return MTPInputPeer(peer->input);
}))
)).done([=](const MTPUpdates &result) {
peer->session().api().applyUpdates(result);
}).send();
+170
View File
@@ -0,0 +1,170 @@
/*
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_chat_links.h"
#include "api/api_text_entities.h"
#include "apiwrap.h"
#include "data/data_session.h"
#include "main/main_session.h"
namespace Api {
namespace {
[[nodiscard]] ChatLink FromMTP(
not_null<Main::Session*> session,
const MTPBusinessChatLink &link) {
const auto &data = link.data();
return {
.link = qs(data.vlink()),
.title = qs(data.vtitle().value_or_empty()),
.message = {
qs(data.vmessage()),
EntitiesFromMTP(
session,
data.ventities().value_or_empty())
},
.clicks = data.vviews().v,
};
}
[[nodiscard]] MTPInputBusinessChatLink ToMTP(
not_null<Main::Session*> session,
const QString &title,
const TextWithEntities &message) {
auto entities = EntitiesToMTP(
session,
message.entities,
ConvertOption::SkipLocal);
using Flag = MTPDinputBusinessChatLink::Flag;
const auto flags = (title.isEmpty() ? Flag() : Flag::f_title)
| (entities.v.isEmpty() ? Flag() : Flag::f_entities);
return MTP_inputBusinessChatLink(
MTP_flags(flags),
MTP_string(message.text),
std::move(entities),
MTP_string(title));
}
} // namespace
ChatLinks::ChatLinks(not_null<ApiWrap*> api) : _api(api) {
}
void ChatLinks::create(
const QString &title,
const TextWithEntities &message,
Fn<void(Link)> done) {
const auto session = &_api->session();
_api->request(MTPaccount_CreateBusinessChatLink(
ToMTP(session, title, message)
)).done([=](const MTPBusinessChatLink &result) {
const auto link = FromMTP(session, result);
_list.push_back(link);
_updates.fire({ .was = QString(), .now = link });
if (done) done(link);
}).fail([=](const MTP::Error &error) {
const auto type = error.type();
if (done) done(Link());
}).send();
}
void ChatLinks::edit(
const QString &link,
const QString &title,
const TextWithEntities &message,
Fn<void(Link)> done) {
const auto session = &_api->session();
_api->request(MTPaccount_EditBusinessChatLink(
MTP_string(link),
ToMTP(session, title, message)
)).done([=](const MTPBusinessChatLink &result) {
const auto parsed = FromMTP(session, result);
if (parsed.link != link) {
LOG(("API Error: EditBusinessChatLink changed the link."));
if (done) done(Link());
return;
}
const auto i = ranges::find(_list, link, &Link::link);
if (i != end(_list)) {
*i = parsed;
_updates.fire({ .was = link, .now = parsed });
if (done) done(parsed);
} else {
LOG(("API Error: EditBusinessChatLink link not found."));
if (done) done(Link());
}
}).fail([=](const MTP::Error &error) {
const auto type = error.type();
if (done) done(Link());
}).send();
}
void ChatLinks::destroy(
const QString &link,
Fn<void()> done) {
_api->request(MTPaccount_DeleteBusinessChatLink(
MTP_string(link)
)).done([=] {
const auto i = ranges::find(_list, link, &Link::link);
if (i != end(_list)) {
_list.erase(i);
_updates.fire({ .was = link });
if (done) done();
} else {
LOG(("API Error: DeleteBusinessChatLink link not found."));
if (done) done();
}
}).fail([=](const MTP::Error &error) {
const auto type = error.type();
if (done) done();
}).send();
}
void ChatLinks::preload() {
if (_loaded || _requestId) {
return;
}
_requestId = _api->request(MTPaccount_GetBusinessChatLinks(
)).done([=](const MTPaccount_BusinessChatLinks &result) {
const auto &data = result.data();
const auto session = &_api->session();
const auto owner = &session->data();
owner->processUsers(data.vusers());
owner->processChats(data.vchats());
auto links = std::vector<Link>();
links.reserve(data.vlinks().v.size());
for (const auto &link : data.vlinks().v) {
links.push_back(FromMTP(session, link));
}
_list = std::move(links);
_loaded = true;
_loadedUpdates.fire({});
}).fail([=] {
_requestId = 0;
_loaded = true;
_loadedUpdates.fire({});
}).send();
}
const std::vector<ChatLink> &ChatLinks::list() const {
return _list;
}
bool ChatLinks::loaded() const {
return _loaded;
}
rpl::producer<> ChatLinks::loadedUpdates() const {
return _loadedUpdates.events();
}
rpl::producer<ChatLinks::Update> ChatLinks::updates() const {
return _updates.events();
}
} // namespace Api
+64
View File
@@ -0,0 +1,64 @@
/*
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
class ApiWrap;
namespace Api {
struct ChatLink {
QString link;
QString title;
TextWithEntities message;
int clicks = 0;
};
struct ChatLinkUpdate {
QString was;
std::optional<ChatLink> now;
};
class ChatLinks final {
public:
explicit ChatLinks(not_null<ApiWrap*> api);
using Link = ChatLink;
using Update = ChatLinkUpdate;
void create(
const QString &title,
const TextWithEntities &message,
Fn<void(Link)> done = nullptr);
void edit(
const QString &link,
const QString &title,
const TextWithEntities &message,
Fn<void(Link)> done = nullptr);
void destroy(
const QString &link,
Fn<void()> done = nullptr);
void preload();
[[nodiscard]] const std::vector<ChatLink> &list() const;
[[nodiscard]] bool loaded() const;
[[nodiscard]] rpl::producer<> loadedUpdates() const;
[[nodiscard]] rpl::producer<Update> updates() const;
private:
const not_null<ApiWrap*> _api;
std::vector<Link> _list;
rpl::event_stream<> _loadedUpdates;
mtpRequestId _requestId = 0;
bool _loaded = false;
rpl::event_stream<Update> _updates;
};
} // namespace Api
@@ -487,9 +487,9 @@ void ChatParticipants::requestCountDelayed(
}
void ChatParticipants::add(
std::shared_ptr<Ui::Show> show,
not_null<PeerData*> peer,
const std::vector<not_null<UserData*>> &users,
std::shared_ptr<Ui::Show> show,
bool passGroupHistory,
Fn<void(bool)> done) {
if (const auto chat = peer->asChat()) {
@@ -498,19 +498,28 @@ void ChatParticipants::add(
chat->inputChat,
user->inputUser,
MTP_int(passGroupHistory ? kForwardMessagesOnAdd : 0)
)).done([=](const MTPUpdates &result) {
chat->session().api().applyUpdates(result);
)).done([=](const MTPmessages_InvitedUsers &result) {
const auto &data = result.data();
chat->session().api().applyUpdates(data.vupdates());
if (done) done(true);
ChatInviteForbidden(
show,
chat,
CollectForbiddenUsers(&chat->session(), result));
}).fail([=](const MTP::Error &error) {
const auto type = error.type();
ShowAddParticipantsError(type, peer, { 1, user }, show);
ShowAddParticipantsError(show, type, peer, user);
if (done) done(false);
}).afterDelay(kSmallDelayMs).send();
}
} else if (const auto channel = peer->asChannel()) {
const auto hasBot = ranges::any_of(users, &UserData::isBot);
if (!peer->isMegagroup() && hasBot) {
ShowAddParticipantsError("USER_BOT", peer, users, show);
ShowAddParticipantsError(
show,
u"USER_BOT"_q,
peer,
{ .users = users });
return;
}
auto list = QVector<MTPInputUser>();
@@ -520,8 +529,9 @@ void ChatParticipants::add(
_api.request(MTPchannels_InviteToChannel(
channel->inputChannel,
MTP_vector<MTPInputUser>(list)
)).done([=](const MTPUpdates &result) {
channel->session().api().applyUpdates(result);
)).done([=](const MTPmessages_InvitedUsers &result) {
const auto &data = result.data();
channel->session().api().applyUpdates(data.vupdates());
requestCountDelayed(channel);
if (callback) callback(true);
ChatInviteForbidden(
@@ -529,7 +539,9 @@ void ChatParticipants::add(
channel,
CollectForbiddenUsers(&channel->session(), result));
}).fail([=](const MTP::Error &error) {
ShowAddParticipantsError(error.type(), peer, users, show);
ShowAddParticipantsError(show, error.type(), peer, {
.users = users,
});
if (callback) callback(false);
}).afterDelay(kSmallDelayMs).send();
};
@@ -97,9 +97,9 @@ public:
not_null<ChannelData*> channel,
const TLMembers &data);
void add(
std::shared_ptr<Ui::Show> show,
not_null<PeerData*> peer,
const std::vector<not_null<UserData*>> &users,
std::shared_ptr<Ui::Show> show = nullptr,
bool passGroupHistory = true,
Fn<void(bool)> done = nullptr);
+88
View File
@@ -0,0 +1,88 @@
/*
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_earn.h"
#include "api/api_cloud_password.h"
#include "apiwrap.h"
#include "boxes/passcode_box.h"
#include "data/data_channel.h"
#include "data/data_session.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "ui/basic_click_handlers.h"
#include "ui/widgets/buttons.h"
namespace Api {
void RestrictSponsored(
not_null<ChannelData*> channel,
bool restricted,
Fn<void(QString)> failed) {
channel->session().api().request(MTPchannels_RestrictSponsoredMessages(
channel->inputChannel,
MTP_bool(restricted))
).done([=](const MTPUpdates &updates) {
channel->session().api().applyUpdates(updates);
}).fail([=](const MTP::Error &error) {
failed(error.type());
}).send();
}
void HandleWithdrawalButton(
not_null<ChannelData*> channel,
not_null<Ui::RippleButton*> button,
std::shared_ptr<Ui::Show> show) {
struct State {
rpl::lifetime lifetime;
bool loading = false;
};
const auto state = button->lifetime().make_state<State>();
const auto session = &channel->session();
session->api().cloudPassword().reload();
button->setClickedCallback([=] {
if (state->loading) {
return;
}
state->loading = true;
state->lifetime = session->api().cloudPassword().state(
) | rpl::take(
1
) | rpl::start_with_next([=](const Core::CloudPasswordState &pass) {
state->loading = false;
auto fields = PasscodeBox::CloudFields::From(pass);
fields.customTitle =
tr::lng_channel_earn_balance_password_title();
fields.customDescription =
tr::lng_channel_earn_balance_password_description(tr::now);
fields.customSubmitButton = tr::lng_passcode_submit();
fields.customCheckCallback = crl::guard(button, [=](
const Core::CloudPasswordResult &result) {
session->api().request(
MTPstats_GetBroadcastRevenueWithdrawalUrl(
channel->inputChannel,
result.result
)).done([=](const MTPstats_BroadcastRevenueWithdrawalUrl &r) {
const auto url = qs(r.data().vurl());
if (!url.isEmpty()) {
UrlClickHandler::Open(url);
}
}).fail([=](const MTP::Error &error) {
show->showToast(error.type());
}).send();
});
show->show(Box<PasscodeBox>(session, fields));
});
});
}
} // namespace Api
+29
View File
@@ -0,0 +1,29 @@
/*
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
class ChannelData;
namespace Ui {
class RippleButton;
class Show;
} // namespace Ui
namespace Api {
void RestrictSponsored(
not_null<ChannelData*> channel,
bool restricted,
Fn<void(QString)> failed);
void HandleWithdrawalButton(
not_null<ChannelData*> channel,
not_null<Ui::RippleButton*> button,
std::shared_ptr<Ui::Show> show);
} // namespace Api
@@ -9,7 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "main/main_session.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
namespace Api {
@@ -40,9 +39,9 @@ void GlobalPrivacy::reload(Fn<void()> callback) {
}
}).send();
_session->account().appConfig().value(
_session->appConfig().value(
) | rpl::start_with_next([=] {
_showArchiveAndMute = _session->account().appConfig().get<bool>(
_showArchiveAndMute = _session->appConfig().get<bool>(
u"autoarchive_setting_available"_q,
false);
}, _session->lifetime());
@@ -75,12 +74,12 @@ rpl::producer<bool> GlobalPrivacy::showArchiveAndMute() const {
}
rpl::producer<> GlobalPrivacy::suggestArchiveAndMute() const {
return _session->account().appConfig().suggestionRequested(
return _session->appConfig().suggestionRequested(
u"AUTOARCHIVE_POPULAR"_q);
}
void GlobalPrivacy::dismissArchiveAndMuteSuggestion() {
_session->account().appConfig().dismissSuggestion(
_session->appConfig().dismissSuggestion(
u"AUTOARCHIVE_POPULAR"_q);
}
@@ -142,6 +141,8 @@ void GlobalPrivacy::update(
using Flag = MTPDglobalPrivacySettings::Flag;
_api.request(_requestId).cancel();
const auto newRequirePremiumAllowed = _session->premium()
|| _session->appConfig().newRequirePremiumFree();
const auto flags = Flag()
| (archiveAndMute
? Flag::f_archive_and_mute_new_noncontact_peers
@@ -153,7 +154,7 @@ void GlobalPrivacy::update(
? Flag::f_keep_archived_folders
: Flag())
| (hideReadTime ? Flag::f_hide_read_marks : Flag())
| ((newRequirePremium && _session->premium())
| ((newRequirePremium && newRequirePremiumAllowed)
? Flag::f_new_noncontact_peers_require_premium
: Flag());
_requestId = _api.request(MTPaccount_SetGlobalPrivacySettings(
+1 -1
View File
@@ -160,7 +160,7 @@ void Polls::sendVotes(
_session->updates().applyUpdates(result);
const auto settings = &AyuSettings::getInstance();
if (!settings->sendReadMessages && settings->markReadAfterPoll && item)
if (!settings->sendReadMessages && settings->markReadAfterAction && item)
{
readHistory(item);
}
+64 -6
View File
@@ -19,7 +19,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_element.h"
#include "history/history.h"
#include "history/history_item.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
#include "payments/payments_form.h"
@@ -109,6 +108,18 @@ rpl::producer<> Premium::cloudSetUpdated() const {
return _cloudSetUpdated.events();
}
auto Premium::helloStickers() const
-> const std::vector<not_null<DocumentData*>> & {
if (_helloStickers.empty()) {
const_cast<Premium*>(this)->reloadHelloStickers();
}
return _helloStickers;
}
rpl::producer<> Premium::helloStickersUpdated() const {
return _helloStickersUpdated.events();
}
int64 Premium::monthlyAmount() const {
return _monthlyAmount;
}
@@ -225,6 +236,33 @@ void Premium::reloadCloudSet() {
}).send();
}
void Premium::reloadHelloStickers() {
if (_helloStickersRequestId) {
return;
}
_helloStickersRequestId = _api.request(MTPmessages_GetStickers(
MTP_string("\xf0\x9f\x91\x8b\xe2\xad\x90\xef\xb8\x8f"),
MTP_long(_helloStickersHash)
)).done([=](const MTPmessages_Stickers &result) {
_helloStickersRequestId = 0;
result.match([&](const MTPDmessages_stickersNotModified &) {
}, [&](const MTPDmessages_stickers &data) {
_helloStickersHash = data.vhash().v;
const auto owner = &_session->data();
_helloStickers.clear();
for (const auto &sticker : data.vstickers().v) {
const auto document = owner->processDocument(sticker);
if (document->sticker()) {
_helloStickers.push_back(document);
}
}
_helloStickersUpdated.fire({});
});
}).fail([=] {
_helloStickersRequestId = 0;
}).send();
}
void Premium::checkGiftCode(
const QString &slug,
Fn<void(GiftCode)> done) {
@@ -532,34 +570,34 @@ Data::SubscriptionOptions PremiumGiftCodeOptions::options(int amount) {
int PremiumGiftCodeOptions::giveawayBoostsPerPremium() const {
constexpr auto kFallbackCount = 4;
return _peer->session().account().appConfig().get<int>(
return _peer->session().appConfig().get<int>(
u"giveaway_boosts_per_premium"_q,
kFallbackCount);
}
int PremiumGiftCodeOptions::giveawayCountriesMax() const {
constexpr auto kFallbackCount = 10;
return _peer->session().account().appConfig().get<int>(
return _peer->session().appConfig().get<int>(
u"giveaway_countries_max"_q,
kFallbackCount);
}
int PremiumGiftCodeOptions::giveawayAddPeersMax() const {
constexpr auto kFallbackCount = 10;
return _peer->session().account().appConfig().get<int>(
return _peer->session().appConfig().get<int>(
u"giveaway_add_peers_max"_q,
kFallbackCount);
}
int PremiumGiftCodeOptions::giveawayPeriodMax() const {
constexpr auto kFallbackCount = 3600 * 24 * 7;
return _peer->session().account().appConfig().get<int>(
return _peer->session().appConfig().get<int>(
u"giveaway_period_max"_q,
kFallbackCount);
}
bool PremiumGiftCodeOptions::giveawayGiftsPurchaseAvailable() const {
return _peer->session().account().appConfig().get<bool>(
return _peer->session().appConfig().get<bool>(
u"giveaway_gifts_purchase_available"_q,
false);
}
@@ -609,4 +647,24 @@ RequirePremiumState ResolveRequiresPremiumToWrite(
return RequirePremiumState::Unknown;
}
rpl::producer<DocumentData*> RandomHelloStickerValue(
not_null<Main::Session*> session) {
const auto premium = &session->api().premium();
const auto random = [=] {
const auto &v = premium->helloStickers();
Assert(!v.empty());
return v[base::RandomIndex(v.size())].get();
};
const auto &v = premium->helloStickers();
if (!v.empty()) {
return rpl::single(random());
}
return rpl::single<DocumentData*>(
nullptr
) | rpl::then(premium->helloStickersUpdated(
) | rpl::filter([=] {
return !premium->helloStickers().empty();
}) | rpl::take(1) | rpl::map(random));
}
} // namespace Api
+13
View File
@@ -85,6 +85,10 @@ public:
-> const std::vector<not_null<DocumentData*>> &;
[[nodiscard]] rpl::producer<> cloudSetUpdated() const;
[[nodiscard]] auto helloStickers() const
-> const std::vector<not_null<DocumentData*>> &;
[[nodiscard]] rpl::producer<> helloStickersUpdated() const;
[[nodiscard]] int64 monthlyAmount() const;
[[nodiscard]] QString monthlyCurrency() const;
@@ -111,6 +115,7 @@ private:
void reloadPromo();
void reloadStickers();
void reloadCloudSet();
void reloadHelloStickers();
void requestPremiumRequiredSlice();
const not_null<Main::Session*> _session;
@@ -133,6 +138,11 @@ private:
std::vector<not_null<DocumentData*>> _cloudSet;
rpl::event_stream<> _cloudSetUpdated;
mtpRequestId _helloStickersRequestId = 0;
uint64 _helloStickersHash = 0;
std::vector<not_null<DocumentData*>> _helloStickers;
rpl::event_stream<> _helloStickersUpdated;
int64 _monthlyAmount = 0;
QString _monthlyCurrency;
@@ -215,4 +225,7 @@ enum class RequirePremiumState {
not_null<PeerData*> peer,
History *maybeHistory);
[[nodiscard]] rpl::producer<DocumentData*> RandomHelloStickerValue(
not_null<Main::Session*> session);
} // namespace Api
+6 -7
View File
@@ -16,7 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_file_origin.h"
#include "data/data_session.h"
#include "data/notify/data_notify_settings.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
#include "storage/file_upload.h"
@@ -191,20 +190,20 @@ void Ringtones::remove(DocumentId id) {
}
int64 Ringtones::maxSize() const {
return _session->account().appConfig().get<int>(
"ringtone_size_max",
return _session->appConfig().get<int>(
u"ringtone_size_max"_q,
100 * 1024);
}
int Ringtones::maxSavedCount() const {
return _session->account().appConfig().get<int>(
"ringtone_saved_count_max",
return _session->appConfig().get<int>(
u"ringtone_saved_count_max"_q,
100);
}
crl::time Ringtones::maxDuration() const {
return crl::time(1000) * _session->account().appConfig().get<int>(
"ringtone_duration_max",
return crl::time(1000) * _session->appConfig().get<int>(
u"ringtone_duration_max"_q,
5);
}
+1 -3
View File
@@ -28,7 +28,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text_entity.h" // TextWithEntities.
#include "ui/item_text_options.h" // Ui::ItemTextOptions.
#include "main/main_session.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
#include "storage/localimageloader.h"
#include "storage/file_upload.h"
@@ -239,8 +238,7 @@ bool SendDice(MessageToSend &message) {
|| !message.textWithTags.tags.isEmpty()) {
return false;
}
auto &account = message.action.history->session().account();
auto &config = account.appConfig();
auto &config = message.action.history->session().appConfig();
static const auto hardcoded = std::vector<QString>{
Stickers::DicePacks::kDiceString,
Stickers::DicePacks::kDartString,
@@ -9,7 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "main/main_session.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
namespace Api {
@@ -22,7 +21,7 @@ constexpr auto kRefreshAppConfigTimeout = 3 * crl::time(1000);
SensitiveContent::SensitiveContent(not_null<ApiWrap*> api)
: _session(&api->session())
, _api(&api->instance())
, _appConfigReloadTimer([=] { _session->account().appConfig().refresh(); }) {
, _appConfigReloadTimer([=] { _session->appConfig().refresh(); }) {
}
void SensitiveContent::reload() {
+122
View File
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_statistics.h"
#include "apiwrap.h"
#include "base/unixtime.h"
#include "data/data_channel.h"
#include "data/data_session.h"
#include "data/data_stories.h"
@@ -746,4 +747,125 @@ Data::BoostStatus Boosts::boostStatus() const {
return _boostStatus;
}
EarnStatistics::EarnStatistics(not_null<ChannelData*> channel)
: StatisticsRequestSender(channel) {
}
rpl::producer<rpl::no_value, QString> EarnStatistics::request() {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
makeRequest(MTPstats_GetBroadcastRevenueStats(
MTP_flags(0),
channel()->inputChannel
)).done([=](const MTPstats_BroadcastRevenueStats &result) {
const auto &data = result.data();
_data = Data::EarnStatistics{
.topHoursGraph = StatisticalGraphFromTL(
data.vtop_hours_graph()),
.revenueGraph = StatisticalGraphFromTL(data.vrevenue_graph()),
.currentBalance = data.vcurrent_balance().v,
.availableBalance = data.vavailable_balance().v,
.overallRevenue = data.voverall_revenue().v,
.usdRate = data.vusd_rate().v,
};
requestHistory({}, [=](Data::EarnHistorySlice &&slice) {
_data.firstHistorySlice = std::move(slice);
api().request(
MTPchannels_GetFullChannel(channel()->inputChannel)
).done([=](const MTPmessages_ChatFull &result) {
result.data().vfull_chat().match([&](
const MTPDchannelFull &d) {
_data.switchedOff = d.is_restricted_sponsored();
}, [](const auto &) {
});
consumer.put_done();
}).fail([=](const MTP::Error &error) {
consumer.put_error_copy(error.type());
}).send();
});
}).fail([=](const MTP::Error &error) {
consumer.put_error_copy(error.type());
}).send();
return lifetime;
};
}
void EarnStatistics::requestHistory(
const Data::EarnHistorySlice::OffsetToken &token,
Fn<void(Data::EarnHistorySlice)> done) {
if (_requestId) {
return;
}
constexpr auto kTlFirstSlice = tl::make_int(kFirstSlice);
constexpr auto kTlLimit = tl::make_int(kLimit);
_requestId = api().request(MTPstats_GetBroadcastRevenueTransactions(
channel()->inputChannel,
MTP_int(token),
(!token) ? kTlFirstSlice : kTlLimit
)).done([=](const MTPstats_BroadcastRevenueTransactions &result) {
_requestId = 0;
const auto &tlTransactions = result.data().vtransactions().v;
auto list = std::vector<Data::EarnHistoryEntry>();
list.reserve(tlTransactions.size());
for (const auto &tlTransaction : tlTransactions) {
list.push_back(tlTransaction.match([&](
const MTPDbroadcastRevenueTransactionProceeds &d) {
return Data::EarnHistoryEntry{
.type = Data::EarnHistoryEntry::Type::In,
.amount = d.vamount().v,
.date = base::unixtime::parse(d.vfrom_date().v),
.dateTo = base::unixtime::parse(d.vto_date().v),
};
}, [&](const MTPDbroadcastRevenueTransactionWithdrawal &d) {
return Data::EarnHistoryEntry{
.type = Data::EarnHistoryEntry::Type::Out,
.status = d.is_pending()
? Data::EarnHistoryEntry::Status::Pending
: d.is_failed()
? Data::EarnHistoryEntry::Status::Failed
: Data::EarnHistoryEntry::Status::Success,
.amount = (std::numeric_limits<Data::EarnInt>::max()
- d.vamount().v
+ 1),
.date = base::unixtime::parse(d.vdate().v),
// .provider = qs(d.vprovider()),
.successDate = d.vtransaction_date()
? base::unixtime::parse(d.vtransaction_date()->v)
: QDateTime(),
.successLink = d.vtransaction_url()
? qs(*d.vtransaction_url())
: QString(),
};
}, [&](const MTPDbroadcastRevenueTransactionRefund &d) {
return Data::EarnHistoryEntry{
.type = Data::EarnHistoryEntry::Type::Return,
.amount = d.vamount().v,
.date = base::unixtime::parse(d.vdate().v),
// .provider = qs(d.vprovider()),
};
}));
}
const auto nextToken = token + tlTransactions.size();
done(Data::EarnHistorySlice{
.list = std::move(list),
.total = result.data().vcount().v,
.allLoaded = (result.data().vcount().v == nextToken),
.token = Data::EarnHistorySlice::OffsetToken(nextToken),
});
}).fail([=] {
_requestId = 0;
}).send();
}
Data::EarnStatistics EarnStatistics::data() const {
return _data;
}
} // namespace Api
+22
View File
@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/timer.h"
#include "data/data_boosts.h"
#include "data/data_channel_earn.h"
#include "data/data_statistics.h"
#include "mtproto/sender.h"
@@ -107,6 +108,27 @@ private:
};
class EarnStatistics final : public StatisticsRequestSender {
public:
explicit EarnStatistics(not_null<ChannelData*> channel);
[[nodiscard]] rpl::producer<rpl::no_value, QString> request();
void requestHistory(
const Data::EarnHistorySlice::OffsetToken &token,
Fn<void(Data::EarnHistorySlice)> done);
[[nodiscard]] Data::EarnStatistics data() const;
static constexpr auto kFirstSlice = int(5);
static constexpr auto kLimit = int(10);
private:
Data::EarnStatistics _data;
mtpRequestId _requestId = 0;
};
class Boosts final {
public:
explicit Boosts(not_null<PeerData*> peer);
+5 -6
View File
@@ -15,7 +15,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h"
#include "history/history_item.h"
#include "history/history_item_helpers.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
@@ -36,10 +35,10 @@ bool Transcribes::freeFor(not_null<HistoryItem*> item) const {
bool Transcribes::trialsSupport() {
if (!_trialsSupport) {
const auto count = _session->account().appConfig().get<int>(
const auto count = _session->appConfig().get<int>(
u"transcribe_audio_trial_weekly_number"_q,
0);
const auto until = _session->account().appConfig().get<int>(
const auto until = _session->appConfig().get<int>(
u"transcribe_audio_trial_cooldown_until"_q,
0);
_trialsSupport = (count > 0) || (until > 0);
@@ -49,7 +48,7 @@ bool Transcribes::trialsSupport() {
TimeId Transcribes::trialsRefreshAt() {
if (_trialsRefreshAt < 0) {
_trialsRefreshAt = _session->account().appConfig().get<int>(
_trialsRefreshAt = _session->appConfig().get<int>(
u"transcribe_audio_trial_cooldown_until"_q,
0);
}
@@ -58,7 +57,7 @@ TimeId Transcribes::trialsRefreshAt() {
int Transcribes::trialsCount() {
if (_trialsCount < 0) {
_trialsCount = _session->account().appConfig().get<int>(
_trialsCount = _session->appConfig().get<int>(
u"transcribe_audio_trial_weekly_number"_q,
-1);
return std::max(_trialsCount, 0);
@@ -67,7 +66,7 @@ int Transcribes::trialsCount() {
}
crl::time Transcribes::trialsMaxLengthMs() const {
return 1000 * _session->account().appConfig().get<int>(
return 1000 * _session->appConfig().get<int>(
u"transcribe_audio_trial_duration_max"_q,
300);
}
+3 -1
View File
@@ -1128,6 +1128,7 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
MTPPeer(), // saved_peer_id
d.vfwd_from() ? *d.vfwd_from() : MTPMessageFwdHeader(),
MTP_long(d.vvia_bot_id().value_or_empty()),
MTPlong(), // via_business_bot_id
d.vreply_to() ? *d.vreply_to() : MTPMessageReplyHeader(),
d.vdate(),
d.vmessage(),
@@ -1162,6 +1163,7 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
MTPPeer(), // saved_peer_id
d.vfwd_from() ? *d.vfwd_from() : MTPMessageFwdHeader(),
MTP_long(d.vvia_bot_id().value_or_empty()),
MTPlong(), // via_business_bot_id
d.vreply_to() ? *d.vreply_to() : MTPMessageReplyHeader(),
d.vdate(),
d.vmessage(),
@@ -1949,7 +1951,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
const auto &d = update.c_updatePeerSettings();
const auto peerId = peerFromMTP(d.vpeer());
if (const auto peer = session().data().peerLoaded(peerId)) {
peer->setSettings(d.vsettings());
peer->setBarSettings(d.vsettings());
}
} break;
+19 -6
View File
@@ -26,7 +26,9 @@ using TLInputRules = MTPVector<MTPInputPrivacyRule>;
using TLRules = MTPVector<MTPPrivacyRule>;
TLInputRules RulesToTL(const UserPrivacy::Rule &rule) {
const auto collectInputUsers = [](const auto &peers) {
using Exceptions = UserPrivacy::Exceptions;
const auto collectInputUsers = [](const Exceptions &exceptions) {
const auto &peers = exceptions.peers;
auto result = QVector<MTPInputUser>();
result.reserve(peers.size());
for (const auto &peer : peers) {
@@ -36,7 +38,8 @@ TLInputRules RulesToTL(const UserPrivacy::Rule &rule) {
}
return result;
};
const auto collectInputChats = [](const auto &peers) {
const auto collectInputChats = [](const Exceptions &exceptions) {
const auto &peers = exceptions.peers;
auto result = QVector<MTPlong>();
result.reserve(peers.size());
for (const auto &peer : peers) {
@@ -47,6 +50,7 @@ TLInputRules RulesToTL(const UserPrivacy::Rule &rule) {
return result;
};
using Option = UserPrivacy::Option;
auto result = QVector<MTPInputPrivacyRule>();
result.reserve(kMaxRules);
if (!rule.ignoreAlways) {
@@ -62,6 +66,9 @@ TLInputRules RulesToTL(const UserPrivacy::Rule &rule) {
MTP_inputPrivacyValueAllowChatParticipants(
MTP_vector<MTPlong>(chats)));
}
if (rule.always.premiums && (rule.option != Option::Everyone)) {
result.push_back(MTP_inputPrivacyValueAllowPremium());
}
}
if (!rule.ignoreNever) {
const auto users = collectInputUsers(rule.never);
@@ -78,7 +85,6 @@ TLInputRules RulesToTL(const UserPrivacy::Rule &rule) {
}
}
result.push_back([&] {
using Option = UserPrivacy::Option;
switch (rule.option) {
case Option::Everyone: return MTP_inputPrivacyValueAllowAll();
case Option::Contacts: return MTP_inputPrivacyValueAllowContacts();
@@ -101,12 +107,14 @@ UserPrivacy::Rule TLToRules(const TLRules &rules, Data::Session &owner) {
auto result = UserPrivacy::Rule();
auto optionSet = false;
const auto setOption = [&](Option option) {
if (optionSet) return;
if (optionSet) {
return;
}
optionSet = true;
result.option = option;
};
auto &always = result.always;
auto &never = result.never;
auto &always = result.always.peers;
auto &never = result.never.peers;
const auto feed = [&](const MTPPrivacyRule &rule) {
rule.match([&](const MTPDprivacyValueAllowAll &) {
setOption(Option::Everyone);
@@ -114,6 +122,8 @@ UserPrivacy::Rule TLToRules(const TLRules &rules, Data::Session &owner) {
setOption(Option::Contacts);
}, [&](const MTPDprivacyValueAllowCloseFriends &) {
setOption(Option::CloseFriends);
}, [&](const MTPDprivacyValueAllowPremium &) {
result.always.premiums = true;
}, [&](const MTPDprivacyValueAllowUsers &data) {
const auto &users = data.vusers().v;
always.reserve(always.size() + users.size());
@@ -188,6 +198,7 @@ MTPInputPrivacyKey KeyToTL(UserPrivacy::Key key) {
case Key::ProfilePhoto: return MTP_inputPrivacyKeyProfilePhoto();
case Key::Voices: return MTP_inputPrivacyKeyVoiceMessages();
case Key::About: return MTP_inputPrivacyKeyAbout();
case Key::Birthday: return MTP_inputPrivacyKeyBirthday();
}
Unexpected("Key in Api::UserPrivacy::KetToTL.");
}
@@ -215,6 +226,8 @@ std::optional<UserPrivacy::Key> TLToKey(mtpTypeId type) {
case mtpc_inputPrivacyKeyVoiceMessages: return Key::Voices;
case mtpc_privacyKeyAbout:
case mtpc_inputPrivacyKeyAbout: return Key::About;
case mtpc_privacyKeyBirthday:
case mtpc_inputPrivacyKeyBirthday: return Key::Birthday;
}
return std::nullopt;
}
+7 -2
View File
@@ -30,6 +30,7 @@ public:
ProfilePhoto,
Voices,
About,
Birthday,
};
enum class Option {
Everyone,
@@ -37,10 +38,14 @@ public:
CloseFriends,
Nobody,
};
struct Exceptions {
std::vector<not_null<PeerData*>> peers;
bool premiums = false;
};
struct Rule {
Option option = Option::Everyone;
std::vector<not_null<PeerData*>> always;
std::vector<not_null<PeerData*>> never;
Exceptions always;
Exceptions never;
bool ignoreAlways = false;
bool ignoreNever = false;
};
+2 -3
View File
@@ -24,7 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
#include "main/main_account.h"
#include "base/unixtime.h"
#include "base/weak_ptr.h"
#include "ui/controls/who_reacted_context_action.h"
@@ -697,7 +696,7 @@ bool WhoReadExists(not_null<HistoryItem*> item) {
|| user->readDatesPrivate()) {
return false;
}
const auto &appConfig = peer->session().account().appConfig();
const auto &appConfig = peer->session().appConfig();
const auto expirePeriod = appConfig.get<int>(
"pm_read_date_expire_period",
7 * 86400);
@@ -713,7 +712,7 @@ bool WhoReadExists(not_null<HistoryItem*> item) {
&& (megagroup->flags() & ChannelDataFlag::ParticipantsHidden))) {
return false;
}
const auto &appConfig = peer->session().account().appConfig();
const auto &appConfig = peer->session().appConfig();
const auto expirePeriod = appConfig.get<int>(
"chat_read_mark_expire_period",
7 * 86400);
+34 -20
View File
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_authorizations.h"
#include "api/api_attached_stickers.h"
#include "api/api_blocked_peers.h"
#include "api/api_chat_links.h"
#include "api/api_chat_participants.h"
#include "api/api_cloud_password.h"
#include "api/api_hash.h"
@@ -169,6 +170,7 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
, _globalPrivacy(std::make_unique<Api::GlobalPrivacy>(this))
, _userPrivacy(std::make_unique<Api::UserPrivacy>(this))
, _inviteLinks(std::make_unique<Api::InviteLinks>(this))
, _chatLinks(std::make_unique<Api::ChatLinks>(this))
, _views(std::make_unique<Api::ViewsManager>(this))
, _confirmPhone(std::make_unique<Api::ConfirmPhone>(this))
, _peerPhoto(std::make_unique<Api::PeerPhoto>(this))
@@ -1246,7 +1248,7 @@ void ApiWrap::requestPeerSettings(not_null<PeerData*> peer) {
result.match([&](const MTPDmessages_peerSettings &data) {
_session->data().processUsers(data.vusers());
_session->data().processChats(data.vchats());
peer->setSettings(data.vsettings());
peer->setBarSettings(data.vsettings());
_requestedPeerSettings.erase(peer);
});
}).fail([=] {
@@ -1775,7 +1777,7 @@ void ApiWrap::joinChannel(not_null<ChannelData*> channel) {
}
return QString();
}();
if (!text.isEmpty()) {
if (show && !text.isEmpty()) {
show->showToast(text, kJoinErrorDuration);
}
}
@@ -2581,6 +2583,10 @@ void ApiWrap::refreshFileReference(
request(MTPaccount_GetSavedRingtones(MTP_long(0)));
}, [&](Data::FileOriginPremiumPreviews data) {
request(MTPhelp_GetPremiumPromo());
}, [&](Data::FileOriginWebPage data) {
request(MTPmessages_GetWebPage(
MTP_string(data.url),
MTP_int(0)));
}, [&](Data::FileOriginStory data) {
request(MTPstories_GetStoriesByID(
_session->data().peer(data.peer)->input,
@@ -3325,7 +3331,7 @@ void ApiWrap::forwardMessages(
}
const auto settings = &AyuSettings::getInstance();
if (!settings->sendReadMessages && settings->markReadAfterPoll && history->lastMessage())
if (!settings->sendReadMessages && settings->markReadAfterAction && history->lastMessage())
{
readHistory(history->lastMessage());
}
@@ -3613,9 +3619,8 @@ void ApiWrap::sendUploadedPhoto(
// AyuGram useScheduledMessages
const auto settings = &AyuSettings::getInstance();
if (settings->useScheduledMessages && !options.scheduled) {
DEBUG_LOG(("[AyuGram] Scheduling message"));
auto current = base::unixtime::now();
options.scheduled = current + 18; // using 18 seconds because photo can be big
options.scheduled = current + 12;
}
const auto media = Api::PrepareUploadedPhoto(item, std::move(info));
@@ -3639,9 +3644,8 @@ void ApiWrap::sendUploadedDocument(
// AyuGram useScheduledMessages
const auto settings = &AyuSettings::getInstance();
if (settings->useScheduledMessages && !options.scheduled) {
DEBUG_LOG(("[AyuGram] Scheduling message"));
auto current = base::unixtime::now();
options.scheduled = current + 60; // well, a document can be really big...
options.scheduled = current + 12;
}
const auto media = Api::PrepareUploadedDocument(
@@ -3667,11 +3671,16 @@ void ApiWrap::cancelLocalItem(not_null<HistoryItem*> item) {
void ApiWrap::sendShortcutMessages(
not_null<PeerData*> peer,
BusinessShortcutId id) {
auto ids = QVector<MTPint>();
auto randomIds = QVector<MTPlong>();
request(MTPmessages_SendQuickReplyMessages(
peer->input,
MTP_int(id)
MTP_int(id),
MTP_vector<MTPint>(ids),
MTP_vector<MTPlong>(randomIds)
)).done([=](const MTPUpdates &result) {
applyUpdates(result);
}).fail([=](const MTP::Error &error) {
}).send();
}
@@ -3903,13 +3912,14 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
}
void ApiWrap::sendBotStart(
std::shared_ptr<Ui::Show> show,
not_null<UserData*> bot,
PeerData *chat,
const QString &startTokenForChat) {
Expects(bot->isBot());
if (chat && chat->isChannel() && !chat->isMegagroup()) {
ShowAddParticipantsError("USER_BOT", chat, { 1, bot });
ShowAddParticipantsError(show, "USER_BOT", chat, bot);
return;
}
@@ -3943,7 +3953,7 @@ void ApiWrap::sendBotStart(
}).fail([=](const MTP::Error &error) {
if (chat) {
const auto type = error.type();
ShowAddParticipantsError(type, chat, { 1, bot });
ShowAddParticipantsError(show, type, chat, bot);
}
}).send();
}
@@ -4059,6 +4069,8 @@ void ApiWrap::uploadAlbumMedia(
};
request(MTPmessages_UploadMedia(
MTP_flags(0),
MTPstring(), // business_connection_id
item->history()->peer->input,
media
)).done([=](const MTPMessageMedia &result) {
@@ -4148,7 +4160,6 @@ void ApiWrap::sendMediaWithRandomId(
// AyuGram useScheduledMessages
const auto settings = &AyuSettings::getInstance();
if (settings->useScheduledMessages && !options.scheduled) {
DEBUG_LOG(("[AyuGram] Scheduling message"));
auto current = base::unixtime::now();
options.scheduled = current + 12;
}
@@ -4247,15 +4258,6 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
_sendingAlbums.remove(groupId);
return;
}
// AyuGram useScheduledMessages
const auto settings = &AyuSettings::getInstance();
if (settings->useScheduledMessages && !album->options.scheduled) {
DEBUG_LOG(("[AyuGram] Scheduling message"));
auto current = base::unixtime::now();
album->options.scheduled = current + 12;
}
auto sample = (HistoryItem*)nullptr;
auto medias = QVector<MTPInputSingleMedia>();
medias.reserve(album->items.size());
@@ -4280,6 +4282,14 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
_sendingAlbums.remove(groupId);
return;
}
// AyuGram useScheduledMessages
const auto settings = &AyuSettings::getInstance();
if (settings->useScheduledMessages && !album->options.scheduled) {
auto current = base::unixtime::now();
album->options.scheduled = current + 12;
}
const auto history = sample->history();
const auto replyTo = sample->replyTo();
const auto sendAs = album->options.sendAs;
@@ -4495,6 +4505,10 @@ Api::InviteLinks &ApiWrap::inviteLinks() {
return *_inviteLinks;
}
Api::ChatLinks &ApiWrap::chatLinks() {
return *_chatLinks;
}
Api::ViewsManager &ApiWrap::views() {
return *_views;
}
+5
View File
@@ -53,6 +53,7 @@ class Key;
namespace Ui {
struct PreparedList;
class Show;
} // namespace Ui
namespace Api {
@@ -69,6 +70,7 @@ class SensitiveContent;
class GlobalPrivacy;
class UserPrivacy;
class InviteLinks;
class ChatLinks;
class ViewsManager;
class ConfirmPhone;
class PeerPhoto;
@@ -342,6 +344,7 @@ public:
BusinessShortcutId id);
void sendMessage(MessageToSend &&message);
void sendBotStart(
std::shared_ptr<Ui::Show> show,
not_null<UserData*> bot,
PeerData *chat = nullptr,
const QString &startTokenForChat = QString());
@@ -384,6 +387,7 @@ public:
[[nodiscard]] Api::GlobalPrivacy &globalPrivacy();
[[nodiscard]] Api::UserPrivacy &userPrivacy();
[[nodiscard]] Api::InviteLinks &inviteLinks();
[[nodiscard]] Api::ChatLinks &chatLinks();
[[nodiscard]] Api::ViewsManager &views();
[[nodiscard]] Api::ConfirmPhone &confirmPhone();
[[nodiscard]] Api::PeerPhoto &peerPhoto();
@@ -703,6 +707,7 @@ private:
const std::unique_ptr<Api::GlobalPrivacy> _globalPrivacy;
const std::unique_ptr<Api::UserPrivacy> _userPrivacy;
const std::unique_ptr<Api::InviteLinks> _inviteLinks;
const std::unique_ptr<Api::ChatLinks> _chatLinks;
const std::unique_ptr<Api::ViewsManager> _views;
const std::unique_ptr<Api::ConfirmPhone> _confirmPhone;
const std::unique_ptr<Api::PeerPhoto> _peerPhoto;
+4 -14
View File
@@ -188,13 +188,11 @@ AyuGramSettings::AyuGramSettings() {
sendUploadProgress = true;
sendOfflinePacketAfterOnline = false;
markReadAfterSend = true;
markReadAfterReaction = true;
markReadAfterPoll = true;
markReadAfterAction = true;
useScheduledMessages = false;
// ~ Message edits & deletion history
saveDeletedMessages = false;
saveDeletedMessages = true;
saveMessagesHistory = true;
// ~ QoL toggles
@@ -295,16 +293,8 @@ void AyuGramSettings::set_ghostModeEnabled(bool val) {
}
}
void AyuGramSettings::set_markReadAfterSend(bool val) {
markReadAfterSend = val;
}
void AyuGramSettings::set_markReadAfterReaction(bool val) {
markReadAfterReaction = val;
}
void AyuGramSettings::set_markReadAfterPoll(bool val) {
markReadAfterPoll = val;
void AyuGramSettings::set_markReadAfterAction(bool val) {
markReadAfterAction = val;
}
void AyuGramSettings::set_useScheduledMessages(bool val) {
+3 -9
View File
@@ -23,9 +23,7 @@ public:
bool sendUploadProgress;
bool sendOfflinePacketAfterOnline;
bool markReadAfterSend;
bool markReadAfterReaction;
bool markReadAfterPoll;
bool markReadAfterAction;
bool useScheduledMessages;
bool saveDeletedMessages;
@@ -85,9 +83,7 @@ public:
void set_ghostModeEnabled(bool val);
void set_markReadAfterSend(bool val);
void set_markReadAfterReaction(bool val);
void set_markReadAfterPoll(bool val);
void set_markReadAfterAction(bool val);
void set_useScheduledMessages(bool val);
void set_saveDeletedMessages(bool val);
@@ -147,9 +143,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
sendOnlinePackets,
sendUploadProgress,
sendOfflinePacketAfterOnline,
markReadAfterSend,
markReadAfterReaction,
markReadAfterPoll,
markReadAfterAction,
useScheduledMessages,
saveDeletedMessages,
saveMessagesHistory,

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