Compare commits

..

245 Commits

Author SHA1 Message Date
ZavaruKitsu 222a643ce3 feat: allow copying with background
chore: refactor a bit
2024-02-08 00:24:34 +03:00
ZavaruKitsu f583732688 fix: crash if deleted when taking shot 2024-02-07 23:40:40 +03:00
ZavaruKitsu 4e9443e200 feat: quick admins & recent actions
Co-authored-by: c0re100 <corehusky@gmail.com>
2024-02-07 23:25:02 +03:00
ZavaruKitsu a96f8d8ac3 chore: update copyright
fix: don't display date for big emoji
2024-02-04 21:19:42 +03:00
ZavaruKitsu d4a22a5110 chore: sync database schema & refactor & reformat 2024-02-04 20:41:21 +03:00
ZavaruKitsu adb5abf4fb chore: reformat & refactor & remove as not planned for now 2024-02-04 18:36:11 +03:00
ZavaruKitsu 4a6ae07409 feat: allow hiding message shot 2024-02-04 17:05:26 +03:00
ZavaruKitsu f6081db13f fix: hide comments for posts 2024-02-04 15:26:43 +03:00
ZavaruKitsu 33b6f5d207 feat: register url scheme in settings 2024-02-04 14:10:08 +03:00
ZavaruKitsu 84c62470bb feat: rework sendOfflinePacketAfterOnline 2024-02-04 04:00:24 +03:00
ZavaruKitsu a3f4185b45 fix: remove as not planned 2024-02-04 03:02:48 +03:00
ZavaruKitsu 2729fee0ac feat: show channel badge 2024-02-04 02:56:07 +03:00
ZavaruKitsu 964f9bd904 fix: some crashes 2024-02-04 00:46:27 +03:00
ZavaruKitsu cfa007de84 fix: make it compile 2024-02-04 00:46:03 +03:00
ZavaruKitsu 77d52bb1b3 Merge v4.14.13
# Conflicts:
#	Telegram/Resources/winrc/Telegram.rc
#	Telegram/Resources/winrc/Updater.rc
#	Telegram/SourceFiles/core/version.h
#	Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
#	Telegram/SourceFiles/history/view/media/history_view_photo.cpp
#	Telegram/SourceFiles/history/view/reactions/history_view_reactions_selector.cpp
#	Telegram/SourceFiles/mainwidget.cpp
#	Telegram/lib_ui
2024-02-03 23:57:25 +03:00
John Preston 2f0b50cb37 Version 4.14.13: Always send webpages optionally.
If the link cannot be displayed everywhere
(channel blocked in some countries) the
send request without `optional` flag fails.
2024-02-02 21:41:19 +04:00
John Preston 6185fa980d Version 4.14.13.
- Fix display of statistics for single posts.
- Allow editing tag name from search tags.
- Fix a crash in tags removal.
2024-02-02 21:38:23 +04:00
John Preston 1cce1e8a90 Fix a crash in tags removal. 2024-02-02 21:33:58 +04:00
23rd 237baf11df Fixed display of statistics for single posts. 2024-02-02 21:33:46 +04:00
Ilya Fedin 46023f4260 Update lib_webrtc 2024-02-02 20:46:54 +04:00
John Preston 8459c29073 Allow editing tag name from search tags. 2024-02-02 11:25:04 +04:00
John Preston f072173d7c Fix tags for just-sent Saved Messages. 2024-02-02 09:52:32 +04:00
John Preston bec34c34b1 Version 4.14.12: Fix build with GCC. 2024-02-01 21:13:07 +04:00
John Preston 04ab148b2e Version 4.14.12.
- Tags in Saved Messages.
- Audio output device selection for music and videos.
- Audio input device selection for voice messages recording.
- Default device changes should be applied instantly. (Windows / macOS)
2024-02-01 17:52:37 +04:00
John Preston e314abefb8 Fix build with Xcode. 2024-02-01 17:52:37 +04:00
John Preston cdaa23363f Allow reaction reports in public groups. 2024-02-01 17:52:37 +04:00
John Preston 5401d00548 Allow reporting / banning from reactions in groups. 2024-02-01 17:30:40 +04:00
John Preston c06699e8e7 Update API scheme on layer 173. 2024-02-01 12:47:52 +04:00
John Preston 2f40a44b5c Improve things for OpenAL devices management. 2024-02-01 12:37:34 +04:00
John Preston 0945e04f6b Allow filtering by tag on click in sublists. 2024-02-01 12:37:34 +04:00
John Preston db7c16f82b Fix about message reaction text color. 2024-02-01 12:37:34 +04:00
John Preston 30548c2859 Support tags search in sublists. 2024-02-01 12:37:34 +04:00
John Preston 0163938e00 Add shadow below tags list widget. 2024-02-01 12:37:34 +04:00
John Preston 3421b656db Fix saved tag click in separate window messages. 2024-02-01 12:37:34 +04:00
John Preston 39b80c98c7 Support tags in ComposeSearch. 2024-02-01 12:37:34 +04:00
John Preston 323500f6dd Improve design of locked tags. 2024-02-01 12:37:34 +04:00
John Preston 11cf0486cb Implement required paywalls in tags. 2024-02-01 12:37:34 +04:00
John Preston 46579ac84d Support about text above reactions strip. 2024-02-01 12:37:34 +04:00
John Preston f324c53440 New premium promo section about tags. 2024-02-01 12:37:34 +04:00
John Preston 87df90227e Remove legacy premium reactions code. 2024-02-01 12:37:34 +04:00
John Preston 6f57302562 Track tag counts in all sublists. 2024-02-01 12:37:34 +04:00
John Preston d116c8fea0 Allow editing tag names in Saved Messages. 2024-02-01 12:37:34 +04:00
John Preston 32462fca9b Show tag names in Saved Messages. 2024-02-01 12:37:34 +04:00
John Preston 55a174190e Fix reactions expanding. 2024-02-01 12:37:34 +04:00
John Preston 9f738cded2 Fix saved messages sublists pinning updates. 2024-02-01 12:37:34 +04:00
John Preston 87c1329490 Re-enable tags in Saved Messages. 2024-02-01 12:37:34 +04:00
John Preston ded2015dc2 Update API scheme to layer 173. 2024-02-01 12:37:34 +04:00
23rd 98a71cce89 Improved toast phrase for forwarded messages to self. 2024-02-01 12:37:34 +04:00
23rd a3ba1ba2a1 Fixed ability to create group without ttl even with ttl in settings. 2024-02-01 12:37:33 +04:00
23rd 42842619b0 Added external link to username field when it is available for purchase. 2024-02-01 12:37:33 +04:00
23rd 32d3b90cdc Replaced behavior of statistics info to wait all charts. 2024-02-01 12:37:33 +04:00
GitHub Action b182aeb51e Update User-Agent for DNS to Chrome 121.0.6167.85. 2024-02-01 12:37:25 +04:00
Ilya Fedin 7049929a59 Update libproxy 2024-01-31 23:27:41 +04:00
Ilya Fedin aa5413da4e Ensure cant reproduce label is not automatically removed 2024-01-31 11:04:04 +04:00
Zephyr Lykos 32dfe0f65e Update cppgir to fix nullptr dereference in glib 2.79 2024-01-31 11:03:36 +04:00
Ilya Fedin 5d33290218 Shorten socket paths on Linux 2024-01-29 11:46:12 +04:00
ZavaruKitsu e47ff9fd34 feat: copy phone on click 2024-01-28 22:55:38 +03:00
ZavaruKitsu 58e38c487a feat: use Sentry for crash reporting 2024-01-28 22:44:48 +03:00
Ilya Fedin 852196a013 Add cant reproduce label handling 2024-01-27 08:52:14 +04:00
Ilya Fedin 0ff3d4b2ed Add needs user action label handling 2024-01-27 08:52:14 +04:00
Ilya Fedin b843dab87a Get error message from the right object when copying log file 2024-01-27 07:17:24 +04:00
ZavaruKitsu 1e34bc6b30 fix: close confirmation box 2024-01-26 19:48:41 +03:00
ZavaruKitsu b3225af685 chore: update deps 2024-01-26 19:30:17 +03:00
ZavaruKitsu 59e44d4e96 feat: add scoop note
Co-authored-by: 1MoreRaiday <123898931+1MoreRaiday@users.noreply.github.com>
2024-01-26 19:11:28 +03:00
ZavaruKitsu 9321f22a9e fix: remove icon override with hideNotificationCounters 2024-01-26 18:55:07 +03:00
ZavaruKitsu 8718e0a045 feat: show user id instead of phone 2024-01-26 18:46:56 +03:00
ZavaruKitsu c4cf4325d6 feat: quick access to preferences
It's label useless so why not just replace with custom preferences.
2024-01-26 18:39:47 +03:00
ZavaruKitsu 9c71aba5d1 feat: message shot
feat: send image as sticker
fix: don't query author pack if ID == 0
fix: use predefined confirmation boxes
2024-01-26 18:25:03 +03:00
23rd 20bd7db4d9 Slightly improved display of top label in Premium Settings for user. 2024-01-25 19:28:31 +04:00
23rd 92f0358800 Fixed text insertion from menu bar on macOS when input field is hidden. 2024-01-25 19:28:30 +04:00
John Preston 0372f2be9c Beta version 4.14.11.
- Fix crash when accepting calls.
- Fix possible crash in loopback audio on Windows.
2024-01-25 19:26:55 +04:00
John Preston 7dfb93f7c2 Add some assertions for debugging a crash. 2024-01-25 18:30:21 +04:00
John Preston 3c150d9742 Fix possible crash in loopback audio on Windows. 2024-01-25 18:30:21 +04:00
John Preston 3c5cace175 Fix chats list bottom buttons skip. 2024-01-25 17:55:10 +04:00
John Preston 7e7fd6f1b4 Fix crash in accepting calls. 2024-01-25 17:54:31 +04:00
John Preston eebe7adbcb Beta version 4.14.10.
- Allow choosing audio device for music and video files.
- Allow choosing microphone device for voice recording.
- Allow pause and resume voice messages recording.
- Track audio device changes on Windows and macOS.
2024-01-25 11:57:58 +04:00
23rd 5561bdeb5e Fixed top of ttl button in voice record bar with float media player. 2024-01-25 11:57:58 +04:00
John Preston a670095294 Update patched OpenAL on macOS / Windows. 2024-01-25 11:57:58 +04:00
John Preston 104ba4db7c Fully migrate to Webrtc::Environment. 2024-01-25 11:57:58 +04:00
John Preston 9a6ab3b0f2 Improve call device migration. 2024-01-25 11:04:27 +04:00
John Preston e5b89b1572 Separate settings for calls. 2024-01-25 11:04:27 +04:00
John Preston 65a80766f4 Implement media device tracking on macOS. 2024-01-25 11:04:27 +04:00
John Preston 736b489eb7 Fix build of updated tgcalls on macOS. 2024-01-25 11:04:27 +04:00
John Preston d3778f92d2 Implement media devices tracking on Windows. 2024-01-25 11:04:27 +04:00
23rd 30e694420a Added icon to button for resuming of voice recording. 2024-01-25 11:04:27 +04:00
23rd 091c13bc23 Added initial ability to pause and resume voice recording. 2024-01-25 11:04:27 +04:00
23rd 5130c5df80 Replaced display of stop icon in voice record bar with pause icon. 2024-01-25 11:04:27 +04:00
23rd 7542f04010 Added specific phrases to chats list for voice messages with ttl. 2024-01-25 11:04:27 +04:00
23rd dff4191ac9 Added reward phrase to about label in gift box. 2024-01-25 11:04:27 +04:00
23rd 15e2874da8 Fixed display of loading progress in voice messages with ttl. 2024-01-25 11:04:27 +04:00
John Preston 8eb49d5efc Fix possible connection problem in calls. 2024-01-22 11:06:42 +04:00
John Preston 230761eb23 Version 4.14.9.
- Fix two possible crashes in messages history and group search.
- Fix local online status turning off. (once again)
2024-01-19 21:48:39 +04:00
John Preston bb0ab27244 Fix possible crash in service message update. 2024-01-19 21:46:56 +04:00
John Preston bdeaf4f27a Fix crash in search in group messages from user.
Fixes #27387.
2024-01-19 21:46:55 +04:00
John Preston 6d608bed98 Add DESKTOP_APP_ASAN CMake option on Windows. 2024-01-19 21:46:48 +04:00
John Preston 5a47acf1d2 Change reply-in-chat locally. 2024-01-19 16:24:50 +04:00
John Preston 02a306ba70 Fix get premium suggestion display. 2024-01-19 15:45:56 +04:00
John Preston 75e19235cd Improve get premium phrase. 2024-01-19 15:45:46 +04:00
John Preston 7d9b4e1e03 Fix local online status fadeout once again. 2024-01-19 11:44:33 +04:00
John Preston d0fff1611c Version 4.14.8.
- Fix initial position and size of secondary windows.
- Optimize messages loading. (load replies on demand)
- Fix local online status turning off.
2024-01-18 22:22:35 +04:00
John Preston e4ca8ae847 Fix several possible crashes. 2024-01-18 22:22:35 +04:00
John Preston f53b64bc72 Fix local online finishing. 2024-01-18 21:19:07 +04:00
John Preston 981909e567 Closed alpha version 4.14.7.1. 2024-01-18 19:26:32 +04:00
John Preston ce6fc19b84 Try to request dependent messages on demand. 2024-01-18 19:26:32 +04:00
John Preston a38f731265 Version 4.14.7: Fix build with Xcode 15.2. 2024-01-18 17:51:52 +04:00
John Preston d55dd7dffd Version 4.14.7: Fix build with GCC. 2024-01-18 17:50:37 +04:00
John Preston 37478d951a Fix initial geometry for secondary windows. 2024-01-18 17:27:30 +04:00
John Preston 814de17f28 Version 4.14.7.
- See when your message was read in private chat.
- Premium users can see other last seen times
if they weren't hidden explicitly.
- Premium users can allow new chats only from their contacts
and other Premium users.
2024-01-18 14:35:35 +04:00
John Preston 5f97d683df Count senders / captions count correctly in forwards. 2024-01-18 13:26:14 +04:00
John Preston 95d4e02ae1 Fix a glitch in search-in-separate-window. 2024-01-18 13:20:33 +04:00
John Preston abf9764640 Another attempt to fix TTL tooltip. 2024-01-18 12:44:35 +04:00
John Preston 80ee38f9fb Change taps to clicks in built-in phrases. 2024-01-18 12:43:47 +04:00
John Preston b4ab20bbe9 Fix media expiration from another client. 2024-01-18 12:23:47 +04:00
John Preston f6a95df550 Show toast on invite attempt to premium required. 2024-01-18 12:01:03 +04:00
John Preston f3f660a180 Show toast on share attempt to premium required. 2024-01-18 10:39:00 +04:00
ZavaruKitsu 0cf36db010 feat: add support for Spotify links
Open `open.spotify.com` links in the desktop application
2024-01-17 19:54:02 +03:00
ZavaruKitsu bfeb225bc2 feat: add custom emoji preview support 2024-01-17 18:18:48 +03:00
ZavaruKitsu 31d486c2e2 feat: support expiring voice/video
fix: incorrect size of burn icon
fix: read reactions and mentions after actions
2024-01-17 17:07:03 +03:00
John Preston eda7118df9 Show toast on forward attempt to premium required. 2024-01-17 16:43:25 +04:00
John Preston 7c468052e6 Fix premium-required info on first load. 2024-01-17 11:16:05 +04:00
John Preston 43eca490a7 Recreate webview on reload request after a crash. 2024-01-17 10:16:12 +04:00
John Preston 3710d61a09 Show "Hide read time" only on non-trivial privacy. 2024-01-17 09:39:05 +04:00
John Preston 5daa5a00f0 Correctly use contact_require_premium bit. 2024-01-17 09:39:05 +04:00
John Preston 6e31993777 Update API scheme on layer 172. 2024-01-17 09:39:05 +04:00
John Preston 1cfad14437 Show correct placeholder in require-premium story reply. 2024-01-17 09:39:05 +04:00
John Preston 3829ed5880 Fix build with Xcode. 2024-01-17 09:39:05 +04:00
John Preston e5cda0e2b1 Show "premium required" information in chat. 2024-01-17 09:39:05 +04:00
John Preston c765bee0cd Update API scheme on layer 172. 2024-01-17 09:39:05 +04:00
John Preston 16942d487a New "Messages" privacy option and box. 2024-01-17 09:39:05 +04:00
John Preston 5cb4cfef32 Improve geometry restore on secondary screen. 2024-01-17 09:39:05 +04:00
John Preston 4d86ced1e6 Improve "show" last seen button design. 2024-01-17 09:39:05 +04:00
John Preston ad03431b0a Improve "read time" context menu info design. 2024-01-17 09:39:05 +04:00
John Preston 474f1118b6 Proof-of-concept read time in private chats. 2024-01-17 09:39:05 +04:00
John Preston e63d573414 Proof-of-concept last seen hidden. 2024-01-17 09:39:04 +04:00
John Preston 33643ff7fc Add "show" button for last seen hidden. 2024-01-17 09:39:04 +04:00
John Preston ca25ad57b1 Update API scheme to layer 172. 2024-01-17 09:39:04 +04:00
ZavaruKitsu fc2cc6ce6b fix: don't read topics 2024-01-17 02:05:27 +03:00
ZavaruKitsu fe64dfeb1f fix: make it compile
fix: restore Quit shortcut for use in custom shortcuts file
2024-01-17 01:05:24 +03:00
ZavaruKitsu abf17407ea Merge tag 'v4.14.6' into dev
# Conflicts:
#	Telegram/Resources/winrc/Telegram.rc
#	Telegram/Resources/winrc/Updater.rc
#	Telegram/SourceFiles/core/version.h
#	Telegram/SourceFiles/dialogs/dialogs_widget.cpp
#	Telegram/SourceFiles/dialogs/dialogs_widget.h
#	Telegram/SourceFiles/history/history_item_helpers.cpp
#	Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp
#	Telegram/lib_ui
#	lib/xdg/org.telegram.desktop.metainfo.xml
#	snap/snapcraft.yaml
2024-01-16 23:44:24 +03:00
John Preston c364383cf0 Version 4.14.6.
- Fix one-time audio tooltip showing in wrong places.
- Fix media viewer showing above taskbar on Windows.
- Fix crash in one-time video message playback.
2024-01-16 21:44:56 +04:00
John Preston 5033b9ef0d Fix crash in ttl video, track editions. 2024-01-16 21:43:19 +04:00
John Preston 605b255e32 Fix media viewer non-full-screen-ness. 2024-01-16 21:12:06 +04:00
John Preston d3fdfe4b29 Fix crash in themes editor.
Fixes #27366.
2024-01-16 21:09:45 +04:00
John Preston c452694348 Pause infinite radial timer if anim::Disabled. 2024-01-16 20:31:44 +04:00
23rd 83fc19e143 Changed behavior in voice record bar to create ttl button on demand. 2024-01-16 20:31:25 +04:00
John Preston 6686fe110d Fix release script working from Linux. 2024-01-16 20:29:58 +04:00
John Preston ed027c23d0 Version 4.14.5: Fix build with GCC. 2024-01-16 20:29:37 +04:00
John Preston 2213bedc12 Version 4.14.5.
- Allow sending one-time voice messages.
- Improve playing one-time voice and video messages.
- Remove Ctrl+Shift+[1-6] shortcuts by default,
some are used in input methods.
- Some bugs and glitches fixed.
2024-01-16 13:14:36 +04:00
John Preston ac7958f335 Remove ctrl+shift+N shortcuts by default.
Those are used in some input methods, including Farsi.

You can always add such bindings in tdata/shortcuts-custom.json for
the "account1", "account2", etc commands.

Fixes #27334.
2024-01-16 13:03:44 +04:00
John Preston 3301d28615 Fix white glitch workaround on Windows. 2024-01-16 12:53:50 +04:00
John Preston 6033071e61 Fix new taskbar "Quit Telegram" icon generation. 2024-01-16 12:53:23 +04:00
John Preston 06775b5623 Optimize ttl media overlay a bit. 2024-01-16 11:56:28 +04:00
John Preston 93a734eecf Prepare ttl-media release. 2024-01-16 11:56:08 +04:00
John Preston 6f64fea0b1 Fix build with Xcode. 2024-01-16 11:21:04 +04:00
John Preston 6b910e11e5 Update lib_webview submodle. 2024-01-16 11:18:56 +04:00
John Preston b31bb6dd33 Fix sending single-time voice messages. 2024-01-16 11:18:56 +04:00
John Preston 104cf504ab Play ttl media horizontally where the message was. 2024-01-16 11:18:56 +04:00
John Preston b462d7627f Fix channels in poll results restoring. 2024-01-16 11:18:56 +04:00
23rd cb4781360a Added first shown tooltip to ttl button from voice record bar. 2024-01-16 11:18:56 +04:00
23rd 8895e49466 Fixed display of corner button in section with ttl button in record bar. 2024-01-16 11:18:56 +04:00
23rd d1f4463c2a Added simple tooltip to ttl button from voice record bar. 2024-01-16 11:18:56 +04:00
23rd f9b5789cf7 Fixed button position in voice record bar for ttl voice messages. 2024-01-16 11:18:56 +04:00
23rd 5273fbf57b Slightly improved progress radial for voice messages with ttl. 2024-01-16 11:18:56 +04:00
23rd ad6890e7dd Slightly improved progress radial for video messages with ttl. 2024-01-16 11:18:56 +04:00
23rd 46ddc7364c Fixed possible crash on deleting of media message with ttl. 2024-01-16 11:18:56 +04:00
23rd a2c0491ae0 Added phrases to ttl viewer widget for video messages. 2024-01-16 11:18:56 +04:00
23rd c686ac8603 Slightly improved style of ttl badge in voice messages. 2024-01-16 11:18:56 +04:00
23rd 268613e1db Slightly improved style of voice record bar. 2024-01-16 11:18:56 +04:00
23rd 5ba918d213 Added support of chat themes to viewer widget for messages with ttl. 2024-01-16 11:18:56 +04:00
23rd 21dcb7b13c Added initial ability to play video messages with ttl. 2024-01-16 11:18:56 +04:00
23rd 40ff71b2cd Added delay to button for media replacement in compose control. 2024-01-16 11:18:56 +04:00
23rd b017cc07ce Removed uppercase from phrase in calls top bar. 2024-01-16 11:18:55 +04:00
23rd fa773c3024 Fixed incorrect seeking of voice messages with transcribe button. 2024-01-16 11:18:55 +04:00
23rd a1369aaad0 Added references to structured bindings since Apple clang supports them. 2024-01-16 11:18:55 +04:00
23rd 6516c7aef3 Fixed display of ttl badges from voice messages with chat themes. 2024-01-16 11:18:55 +04:00
23rd c43dfecec6 Excluded media with ttl from shared media. 2024-01-16 11:18:55 +04:00
23rd 53e95a7f74 Fixed display of last frame of voice messages in media viewer with ttl. 2024-01-16 11:18:55 +04:00
23rd 2a81a617e1 Improved loop animation in voice messages with ttl. 2024-01-16 11:18:55 +04:00
23rd 37067f17e2 Added new viewer widget for voice messages with ttl. 2024-01-16 11:18:55 +04:00
John Preston f8caa02f10 Fix animating list->chat transition in single column. 2024-01-16 11:18:55 +04:00
John Preston fc2f41096f Attempt to fix initial window position on Windows. 2024-01-16 11:18:55 +04:00
John Preston 3eefaac885 Fix screen sharing source choose window. 2024-01-16 11:18:55 +04:00
John Preston 0dfe37f998 Mirror my outgoing video in video chats. 2024-01-16 11:18:55 +04:00
John Preston e2439984ae Pass whole point in mapFromGlobal(mapToGlobal).
Fixes #27237.
2024-01-16 11:18:55 +04:00
John Preston 9401e7cb51 Add "View reactions" phrase to the langpack. 2024-01-16 11:18:55 +04:00
John Preston 4471eb587d Fix possible crash in gift box sticker lookup. 2024-01-16 11:16:28 +04:00
John Preston 3c6037a798 Custom context menu for saved-tags reactions. 2024-01-16 11:16:28 +04:00
John Preston d1a0dfbb97 Search by tag on click in Saved Messages. 2024-01-16 11:16:28 +04:00
John Preston 94a542a1d1 Allow change account shortcuts in shortcuts_custom.json 2024-01-16 11:16:28 +04:00
John Preston f5fcfaba0c Add search in saved sublist. 2024-01-16 11:16:28 +04:00
John Preston 9c151ca151 Allow filtering Saved Messages search by tags. 2024-01-16 11:16:27 +04:00
John Preston e667436a98 Track my tags usages. 2024-01-16 11:16:27 +04:00
John Preston 9aacff8b54 Request correct saved/default reaction tags. 2024-01-16 11:16:27 +04:00
John Preston 9b43d204e2 Track and render reactions as tags in Saved Messages. 2024-01-16 11:16:27 +04:00
John Preston 0faf801de7 Update API scheme to layer 171. 2024-01-16 11:16:27 +04:00
dependabot[bot] dd1cca1a0a Bump jinja2 from 3.1.2 to 3.1.3 in /Telegram/build/docker/centos_env
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 01:48:01 -08:00
Ilya Fedin eca8c28dea Add missing QWindow includes 2024-01-12 19:59:18 -08:00
Ilya Fedin 333ef9b48a Hide connection widget when the window is not exposed 2024-01-11 23:40:18 -08:00
Ilya Fedin 1e98e19aaf Add installed packages to cache key for macOS packaged action 2024-01-10 02:40:21 -08:00
Ilya Fedin 308fdcf9cf Update submodules 2024-01-09 22:05:45 -08:00
Ilya Fedin d803b3ae7d Try to add mesa vulkan drivers to snap 2024-01-09 21:23:20 -08:00
Ilya Fedin aa121aa1de Get rid of architecture whitelist from snapcraft.yaml
So the Canonical builders build on new architectures as soon as they appear
2024-01-09 21:22:15 -08:00
Ilya Fedin 8138a26c2d Add information about provided mime-type and D-Bus service 2024-01-09 04:31:11 -08:00
Ilya Fedin 26fa3db66d Replace deprecated medium display length with a number 2024-01-09 04:31:11 -08:00
Klemens Nanni 7779d021b4 update cmake/ submodule to include cppgir BSD fixes 2024-01-08 18:49:28 -08:00
John Preston 6b44143f5b Version 4.14.4: Fix build with GCC. 2024-01-08 12:03:49 -08:00
John Preston 0f207faa3e Version 4.14.4.
- Switch between logged in accounts using Ctrl+Shift+[1-6] shortcuts.
- Add poll creation in groups to the attach menu, if exists.
- Another fix for payment card validation.
2024-01-08 17:47:03 +04:00
John Preston 28b43eff7c Make Ctrl+Shift+[1-6] jump through accounts. 2024-01-08 17:35:08 +04:00
John Preston c257b75a66 Add poll creation to the attach menu. 2024-01-08 17:35:02 +04:00
John Preston 893e14cc39 Fix payment field values formatting.
Regression was introduced in e6b9a07163.

Fixes #27318.
2024-01-08 17:34:08 +04:00
Ilya Fedin 30d5b7fd66 Update patches commit in Dockerfile 2024-01-08 04:40:20 -08:00
Ilya Fedin 2ef8136308 Update patches commit in Dockerfile 2024-01-06 13:30:58 +04:00
ZavaruKitsu 59c2cbaabc feat: don't destroy expiring voice messages 2024-01-05 17:28:19 +03:00
ZavaruKitsu 6d39a5f1d2 fix: accidental crash
fix: update submodules
2024-01-05 17:11:09 +03:00
ZavaruKitsu 4fd0b008ba Merge tag 'v4.14.3' into dev
# Conflicts:
#	Telegram/Resources/winrc/Telegram.rc
#	Telegram/Resources/winrc/Updater.rc
#	Telegram/SourceFiles/core/version.h
#	Telegram/SourceFiles/history/view/controls/history_view_voice_record_bar.cpp
#	Telegram/SourceFiles/history/view/history_view_element.cpp
#	Telegram/lib_ui
2024-01-05 16:19:32 +03:00
John Preston fccc93ca53 Version 4.14.3: Update Qt patch in the Dockerfile. 2024-01-04 20:39:24 +04:00
23rd 37d1940993 Version 4.14.3: Fixed ttl period for sending of voice messages with ttl. 2024-01-04 18:36:36 +03:00
John Preston f25638f492 Version 4.14.3: Fix submodule revert. 2024-01-04 19:04:06 +04:00
John Preston 6e6f15e711 Version 4.14.3.
- Allow sending single-time voice messages.
- Fix payments card validation.
- Fix crash when trying to join channels above the limit.
- Add "Quit Telegram" to the Taskbar context menu. (Windows)
- Fix opened windows list in the Dock icon context menu. (macOS)
2024-01-04 19:01:53 +04:00
John Preston b38e72dcd9 Fix typo in Dockerfile. 2024-01-04 18:55:27 +04:00
Ilya Fedin 9287af1752 Update patches commit in Dockerfile 2024-01-04 18:52:35 +04:00
John Preston 254ca57bf3 Fix webm emoji/stickers with unknown dimensions. 2024-01-04 18:50:47 +04:00
John Preston 52ef8e780a Update zlib/minizip.
Fixes #27313.
2024-01-04 18:50:47 +04:00
John Preston 16a2d4ec96 Fix wrong "Webview process crashed." message. 2024-01-04 18:50:47 +04:00
23rd 3b50bc71b3 Fixed possible rare crash from voice messages with ttl. 2024-01-04 17:48:53 +03:00
John Preston bb31357c58 More strict check for custom emoji dimensions. 2024-01-04 17:25:32 +04:00
John Preston 66afcbdae8 Backport windows list in Dock Menu from Qt 6.3.*. 2024-01-04 17:25:31 +04:00
John Preston 5a28e69f1a More cleaning in force-reconfiguration. 2024-01-04 17:25:22 +04:00
John Preston ce78074df7 Fix build on Windows. 2024-01-04 17:22:05 +04:00
John Preston 973f91b5e4 Add "Quit Telegram" taskbar menu item.
Fixes #1161.
2024-01-04 17:22:05 +04:00
John Preston d2246337a2 Fix crash in ChannelsLimitBox.
Fixes https://bugs.telegram.org/c/35214

Deleting `placeholder` in content->heightValue() resulted in `delete`
sometimes being called deep inside the layer->show() which already had
a reference to that `placeholder` saved and was accessed after -> crash.
2024-01-04 17:22:05 +04:00
23rd c7f11eb05a Updated Qt to 5.15.12 on Windows. 2024-01-04 17:22:05 +04:00
23rd 758219265a Updated Qt to 6.2.7 on macOS. 2024-01-04 17:22:04 +04:00
23rd d8d9441731 Slightly improved code style in HistoryView::Document. 2024-01-04 16:14:19 +03:00
23rd 098e797045 Fixed drawing of ttl circles with non-default scale. 2024-01-04 16:14:19 +03:00
23rd 69f8cb5951 Added ability to send voice message with ttl. 2024-01-03 22:44:01 +03:00
23rd ca86dce760 Added button to voice record bar for ttl voice messages. 2024-01-03 22:44:01 +03:00
23rd 5cf0b6b50e Slightly improved code style in voice record bar class. 2024-01-03 22:32:29 +03:00
23rd 7a139ecda7 Added ability to fast jump to replied message with right click on panel. 2024-01-03 12:34:02 +03:00
23rd e52fe9ddb0 Removed ability to save files with ttl. 2024-01-03 12:23:41 +03:00
23rd cee2961632 Fixed width of name text in replies with block quote icon. 2024-01-02 18:19:49 +03:00
John Preston 5933535c9b Fix loading more saved sublists. 2024-01-02 18:03:02 +04:00
23rd a3b91da66c Added silent info to tooltip of scheduled messages. 2024-01-02 14:31:59 +03:00
23rd 34d9a21aae Removed ability to reschedule message as silent as it's not supported. 2024-01-02 14:31:59 +03:00
23rd 233c6b18ed Fixed local flag for silent out messages. 2024-01-02 14:31:59 +03:00
482 changed files with 30095 additions and 16409 deletions
+57
View File
@@ -0,0 +1,57 @@
---
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignOperands: false
AlignTrailingComments: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: false
AfterEnum: true
AfterFunction: false
AfterNamespace: false
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: true
BeforeWhile: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBraces: Custom
ColumnLimit: 120
IncludeCategories:
- Regex: '^<.*'
Priority: 1
- Regex: '^".*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentWidth: 4
InsertNewlineAtEOF: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: false
SpaceInEmptyParentheses: false
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
TabWidth: 4
UseTab: Always
...
+1
View File
@@ -73,6 +73,7 @@ jobs:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcodebuild -version > CACHE_KEY.txt
brew list --versions >> CACHE_KEY.txt
echo $MANUAL_CACHING >> CACHE_KEY.txt
echo "$GITHUB_WORKSPACE" >> CACHE_KEY.txt
if [ "$AUTO_CACHING" = "1" ]; then
+29 -2
View File
@@ -9,11 +9,38 @@ on:
- cron: '0 0 * * *'
jobs:
noResponse:
waiting-for-answer:
runs-on: ubuntu-latest
steps:
- uses: lee-dohm/no-response@v0.5.0
with:
token: ${{ github.token }}
# Label requiring a response
responseRequiredLabel: waiting for answer
needs-user-action:
runs-on: ubuntu-latest
steps:
- uses: lee-dohm/no-response@v0.5.0
with:
token: ${{ github.token }}
responseRequiredLabel: needs user action
cant-reproduce:
if: github.event_name != 'issue_comment'
runs-on: ubuntu-latest
steps:
- uses: lee-dohm/no-response@v0.5.0
with:
token: ${{ github.token }}
responseRequiredLabel: cant reproduce
closeComment: >
This issue has been automatically closed because no developer succeeded to
reproduce the issue with the given reproduction steps. With only the
information that is currently in the issue, we don't have enough
information to take action. Please reach out if you find what's missing to
reproduce the issue so that we can investigate further.
Note that GitHub is a developer communication platform. If you're an ordinary
user seeking for help, get to support crew via `Settings -> Ask question` in
the application.
+2 -2
View File
@@ -60,9 +60,9 @@ include(cmake/options.cmake)
if (NOT DESKTOP_APP_USE_PACKAGED)
if (WIN32)
set(qt_version 5.15.11)
set(qt_version 5.15.12)
elseif (APPLE)
set(qt_version 6.2.6)
set(qt_version 6.2.7)
endif()
endif()
include(cmake/external/qt/package.cmake)
+11 -2
View File
@@ -25,9 +25,20 @@ And many more. Check out our [Documentation](https://docs.ayugram.one/desktop/).
### Windows
#### Official
You can download prebuilt Windows binary from [Releases tab](https://github.com/AyuGram/AyuGramDesktop/releases) or from
the [Telegram topic](https://t.me/ayugramchat/12788).
#### Scoop
```bash
scoop bucket add extras
scoop install ayugram
```
#### Self-built
Follow [official guide](https://github.com/AyuGram/AyuGramDesktop/blob/dev/docs/building-win-x64.md) if you want to
build by yourself.
@@ -65,8 +76,6 @@ Enjoy using **AyuGram**? Consider sending us a tip!
### Libraries used
- [JSON for Modern C++](https://github.com/nlohmann/json)
- [BitConverter](https://github.com/YanjieHe/BitConverter)
- [Not Enough Standards](https://github.com/Alairion/not-enough-standards)
- [SQLite](https://github.com/sqlite/sqlite)
- [sqlite_orm](https://github.com/fnc12/sqlite_orm)
+27 -26
View File
@@ -96,6 +96,8 @@ 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
@@ -114,10 +116,8 @@ PRIVATE
ayu/utils/telegram_helpers.h
ayu/utils/windows_utils.cpp
ayu/utils/windows_utils.h
ayu/ui/ayu_lottie.cpp
ayu/ui/ayu_lottie.h
ayu/ui/ayu_assets.cpp
ayu/ui/ayu_assets.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
@@ -134,39 +134,35 @@ PRIVATE
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/voice_confirmation_box.cpp
ayu/ui/boxes/voice_confirmation_box.h
ayu/ui/boxes/message_history_box.cpp
ayu/ui/boxes/message_history_box.h
ayu/ui/boxes/confirmation_box.cpp
ayu/ui/boxes/confirmation_box.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/sync/ayu_sync_controller.cpp
ayu/sync/ayu_sync_controller.h
ayu/sync/models.h
ayu/sync/utils/ayu_pipe_wrapper.cpp
ayu/sync/utils/ayu_pipe_wrapper.h
ayu/sync/utils/process_utils.hpp
ayu/messages/ayu_messages_controller.cpp
ayu/messages/ayu_messages_controller.h
ayu/libs/pipe.hpp
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/bit_converter.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/database/entities.h
ayu/database/ayu_database.cpp
ayu/database/ayu_database.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
api/api_attached_stickers.cpp
api/api_attached_stickers.h
@@ -478,6 +474,8 @@ PRIVATE
chat_helpers/tabbed_section.h
chat_helpers/tabbed_selector.cpp
chat_helpers/tabbed_selector.h
chat_helpers/ttl_media_layer_widget.cpp
chat_helpers/ttl_media_layer_widget.h
core/application.cpp
core/application.h
core/base_integration.cpp
@@ -585,6 +583,7 @@ PRIVATE
data/data_groups.h
data/data_histories.cpp
data/data_histories.h
data/data_lastseen_status.h
data/data_location.cpp
data/data_location.h
data/data_media_rotation.cpp
@@ -681,6 +680,8 @@ PRIVATE
dialogs/dialogs_row.h
dialogs/dialogs_search_from_controllers.cpp
dialogs/dialogs_search_from_controllers.h
dialogs/dialogs_search_tags.cpp
dialogs/dialogs_search_tags.h
dialogs/dialogs_widget.cpp
dialogs/dialogs_widget.h
dialogs/ui/dialogs_layout.cpp
@@ -820,6 +821,8 @@ PRIVATE
history/view/reactions/history_view_reactions_strip.h
history/view/reactions/history_view_reactions_tabs.cpp
history/view/reactions/history_view_reactions_tabs.h
history/view/history_view_about_view.cpp
history/view/history_view_about_view.h
history/view/history_view_bottom_info.cpp
history/view/history_view_bottom_info.h
history/view/history_view_contact_status.cpp
@@ -1084,6 +1087,7 @@ PRIVATE
media/audio/media_audio.h
media/audio/media_audio_capture.cpp
media/audio/media_audio_capture.h
media/audio/media_audio_capture_common.h
media/audio/media_audio_ffmpeg_loader.cpp
media/audio/media_audio_ffmpeg_loader.h
media/audio/media_audio_loader.cpp
@@ -1299,8 +1303,6 @@ PRIVATE
platform/mac/touchbar/mac_touchbar_manager.mm
platform/mac/touchbar/mac_touchbar_media_view.h
platform/mac/touchbar/mac_touchbar_media_view.mm
platform/win/audio_win.cpp
platform/win/audio_win.h
platform/win/file_utilities_win.cpp
platform/win/file_utilities_win.h
platform/win/launcher_win.cpp
@@ -1324,7 +1326,6 @@ PRIVATE
platform/win/windows_autostart_task.h
platform/win/windows_toast_activator.cpp
platform/win/windows_toast_activator.h
platform/platform_audio.h
platform/platform_file_utilities.h
platform/platform_launcher.h
platform/platform_integration.cpp
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg baseProfile="tiny" version="1.2" viewBox="0 0 72 72" xmlns="http://www.w3.org/2000/svg">
<path d="m27.57 30.79q0.77-0.44 1.14-1.28 4.38-9.86 4.67-24.25 0.03-1.64 1.63-1.54 1.14 0.07 1.9 0.65c14.45 10.9 28.35 31.97 18.06 50.37-9.55 17.08-32.38 15.75-41.59-0.69-5.25-9.37-0.83-23.06 4.26-32.03a2.13 2.12 43.5 0 1 3.64-0.09l5.53 8.68a0.57 0.56-31.3 0 0 0.76 0.18z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 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: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 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: 692 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: 614 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.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 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: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

+121 -5
View File
@@ -141,6 +141,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_status_last_week" = "last seen within a week";
"lng_status_last_month" = "last seen within a month";
"lng_status_lastseen_now" = "last seen just now";
"lng_status_lastseen_when" = "when?";
"lng_status_lastseen_minutes#one" = "last seen {count} minute ago";
"lng_status_lastseen_minutes#other" = "last seen {count} minutes ago";
"lng_status_lastseen_hours#one" = "last seen {count} hour ago";
@@ -168,6 +169,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_remember" = "Remember this choice";
"lng_lastseen_show_title" = "Show Your Last Seen";
"lng_lastseen_show_about" = "To see **{user}'s** Last Seen time, either start\nshowing your own Last Seen time...";
"lng_lastseen_show_button" = "Show My Last Seen";
"lng_lastseen_or" = "or";
"lng_lastseen_premium_title" = "Upgrade to Premium";
"lng_lastseen_premium_about" = "Subscription will let you see **{user}'s** Last Seen\nstatus without showing yours.";
"lng_lastseen_premium_button" = "Subscribe to Telegram Premium";
"lng_lastseen_shown_toast" = "Your last seen time is now visible.";
"lng_readtime_show_title" = "Show Your Read Date";
"lng_readtime_show_about" = "To see when **{user}** read the message,\neither start showing your own read time...";
"lng_readtime_show_button" = "Show My Read Time";
"lng_readtime_or" = "or";
"lng_readtime_premium_title" = "Upgrade to Premium";
"lng_readtime_premium_about" = "Subscription will let you see **{user}'s** read time\nwithout showing yours.";
"lng_readtime_premium_button" = "Subscribe to Telegram Premium";
"lng_readtime_shown_toast" = "Your read times are now visible.";
"lng_channels_limit_title" = "Too Many Communities";
"lng_channels_limit1#one" = "You are a member of **{count}** groups and channels.";
"lng_channels_limit1#other" = "You are a member of **{count}** groups and channels.";
@@ -414,7 +433,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_username_invalid" = "This username is invalid.";
"lng_username_occupied" = "This username is already occupied.";
"lng_username_too_short" = "This username is too short.";
"lng_username_purchase_available" = "Sorry, this link is occupied by someone. But it's available for purchase through\nofficial {link}.";
"lng_username_purchase_available" = "**This username is already taken.** However, it is currently available for purchase. {link}";
"lng_username_purchase_available_link" = "Learn more...";
"lng_username_bad_symbols" = "Only a-z, 0-9, and underscores allowed.";
"lng_username_available" = "This username is available.";
"lng_username_not_found" = "User @{user} not found.";
@@ -611,6 +631,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_call_accept_calls" = "Accept calls from this device";
"lng_settings_call_device_default" = "Same as the System";
"lng_settings_section_devices" = "Speakers and Camera";
"lng_settings_devices_calls" = "Calls and video chats";
"lng_settings_devices_calls_same" = "Use the same devices for calls";
"lng_settings_devices_inactive" = "Unavailable";
"lng_settings_language" = "Language";
"lng_settings_default_scale" = "Default interface scale";
"lng_settings_connection_type" = "Connection type";
@@ -624,6 +649,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_phone_number_privacy" = "Phone number";
"lng_settings_forwards_privacy" = "Forwarded messages";
"lng_settings_profile_photo_privacy" = "Profile photo";
"lng_settings_messages_privacy" = "Messages";
"lng_settings_voices_privacy" = "Voice messages";
"lng_settings_bio_privacy" = "Bio";
"lng_settings_privacy_premium" = "Only subscribers of {link} can restrict receiving voice messages.";
@@ -1060,6 +1086,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_privacy_contacts" = "My contacts";
"lng_edit_privacy_close_friends" = "Close friends";
"lng_edit_privacy_nobody" = "Nobody";
"lng_edit_privacy_premium" = "Premium users";
"lng_edit_privacy_exceptions" = "Add exceptions";
"lng_edit_privacy_exceptions_count#one" = "{count} user";
@@ -1086,6 +1113,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_privacy_lastseen_exceptions" = "These settings will override the values above.";
"lng_edit_privacy_lastseen_always_title" = "Always share with";
"lng_edit_privacy_lastseen_never_title" = "Never share with";
"lng_edit_lastseen_hide_read_time" = "Hide read time";
"lng_edit_lastseen_hide_read_time_about" = "Hide the time when you read messages from people who can't see your last seen. If you turn this on, their read time will also be hidden from you. This setting does not affect group chats.";
"lng_edit_lastseen_subscribe" = "Subscribe to Telegram Premium";
"lng_edit_lastseen_subscribe_about" = "If you subscribe to Premium, you will see other users' last seen and read time even if you hid yours from them (unless they specifically restricted it).";
"lng_edit_privacy_groups_title" = "Group invite settings";
"lng_edit_privacy_groups_header" = "Who can invite you to groups and channels";
@@ -1157,6 +1188,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_privacy_voices_always_title" = "Always allow";
"lng_edit_privacy_voices_never_title" = "Never allow";
"lng_messages_privacy_title" = "Messages";
"lng_messages_privacy_subtitle" = "Who can send me messages?";
"lng_messages_privacy_everyone" = "Everybody";
"lng_messages_privacy_restricted" = "My Contacts and Premium Users";
"lng_messages_privacy_about" = "You can restrict incoming messages to only contacts and Premium users.";
"lng_messages_privacy_premium_button" = "Subscribe to Telegram Premium";
"lng_messages_privacy_premium_about" = "Subscribe now to change this setting and get access to other exclusive features of Telegram Premium.";
"lng_messages_privacy_premium" = "Only subscribers of {link} can select this option.";
"lng_messages_privacy_premium_link" = "Telegram Premium";
"lng_self_destruct_title" = "Account self-destruction";
"lng_self_destruct_description" = "If you don't come online at least once within this period, your account will be deleted along with all groups, messages and contacts.";
"lng_self_destruct_sessions_title" = "Session termination";
@@ -1464,6 +1505,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_report_messages_none" = "Select Messages";
"lng_report_messages_count#one" = "Report {count} Message";
"lng_report_messages_count#other" = "Report {count} Messages";
"lng_report_reaction" = "Report reaction";
"lng_report_and_ban" = "Ban and report";
"lng_report_reaction_title" = "Report reaction";
"lng_report_reaction_about" = "Are you sure you want to report reactions from this user?";
"lng_report_and_ban_button" = "Ban user";
"lng_report_details_about" = "Please enter any additional details relevant to your report.";
"lng_report_details" = "Additional Details";
"lng_report_reason_spam" = "Spam";
@@ -1719,6 +1765,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_ttl_voice_expired" = "Voice message expired";
"lng_ttl_round_sent" = "You sent a self-destructing video message.";
"lng_ttl_round_expired" = "Round message expired";
"lng_ttl_voice_tooltip_in" = "This voice message can only be played once.";
"lng_ttl_voice_tooltip_out" = "This message will disappear once **{user}** plays it once.";
"lng_ttl_voice_close_in" = "Delete and close";
"lng_ttl_round_tooltip_in" = "This video message can only be played once.";
"lng_ttl_round_tooltip_out" = "This message will disappear once **{user}** plays it once.";
"lng_profile_add_more_after_create" = "You will be able to add more members after you create the group.";
"lng_profile_camera_title" = "Capture yourself";
@@ -1980,6 +2031,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_premium_summary_about_emoji_status" = "Add any of thousands emoji next to your name to display current activity.";
"lng_premium_summary_subtitle_infinite_reactions" = "Infinite Reactions";
"lng_premium_summary_about_infinite_reactions" = "React with thousands of emoji — with multiple reactions per message.";
"lng_premium_summary_subtitle_tags_for_messages" = "Tags for Messages";
"lng_premium_summary_about_tags_for_messages" = "Organize your Saved Messages with tags for quicker access.";
"lng_premium_summary_subtitle_premium_stickers" = "Premium Stickers";
"lng_premium_summary_about_premium_stickers" = "Exclusive enlarged stickers featuring additional effects, updated monthly.";
"lng_premium_summary_subtitle_animated_emoji" = "Animated Emoji";
@@ -2400,6 +2453,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_in_dlg_contact" = "Contact";
"lng_in_dlg_audio" = "Voice message";
"lng_in_dlg_video_message" = "Video message";
"lng_in_dlg_voice_message_ttl" = "One-time Voice Message";
"lng_in_dlg_video_message_ttl" = "One-time Video Message";
"lng_in_dlg_file" = "File";
"lng_in_dlg_sticker" = "Sticker";
"lng_in_dlg_sticker_emoji" = "{emoji} Sticker";
@@ -2487,6 +2542,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_record_listen_cancel_sure" = "Are you sure you want to discard your recorded voice message?";
"lng_record_lock_discard" = "Discard";
"lng_record_hold_tip" = "Please hold the mouse button pressed to record a voice message.";
"lng_record_once_first_tooltip" = "Click to set this message to **Play Once**.";
"lng_record_once_active_tooltip" = "The recipients will be able to listen to it only once.";
"lng_will_be_notified" = "Members will be notified when you post";
"lng_wont_be_notified" = "Members will not be notified when you post";
"lng_willbe_history" = "Please select a chat to start messaging";
@@ -2749,17 +2806,34 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_seen_reacted#other" = "{count} Reacted";
"lng_context_seen_reacted_none" = "Nobody Reacted";
"lng_context_seen_reacted_all" = "Show All Reactions";
"lng_context_set_as_quick" = "Set As Quick";
"lng_context_set_as_quick" = "Set as Quick";
"lng_context_filter_by_tag" = "Filter by Tag";
"lng_context_tag_add_name" = "Add Name";
"lng_context_tag_edit_name" = "Edit Name";
"lng_context_remove_tag" = "Remove Tag";
"lng_context_delete_from_disk" = "Delete from disk";
"lng_context_delete_all_files" = "Delete all files";
"lng_context_save_custom_sound" = "Save for notifications";
"lng_context_translate" = "Translate";
"lng_context_translate_selected" = "Translate Selected Text";
"lng_context_read_hidden" = "read";
"lng_context_read_show" = "show when";
"lng_add_tag_about" = "Tag this message with an emoji for quick search.";
"lng_subscribe_tag_about" = "Organize your Saved Messages with tags. {link}";
"lng_subscribe_tag_link" = "Learn More...";
"lng_edit_tag_about" = "You can label your emoji tag with a text name.";
"lng_edit_tag_name" = "Name";
"lng_add_tag_button" = "Add tags";
"lng_add_tag_phrase" = "to messages {arrow}";
"lng_add_tag_phrase_long" = "to your Saved Messages {arrow}";
"lng_unlock_tags" = "Unlock";
"lng_context_animated_emoji" = "This message contains emoji from **{name} pack**.";
"lng_context_animated_emoji_many#one" = "This message contains emoji from **{count} pack**.";
"lng_context_animated_emoji_many#other" = "This message contains emoji from **{count} packs**.";
"lng_context_animated_reaction" = "This reaction is from **{name} pack**.";
"lng_context_animated_tag" = "This tag is from **{name} pack**.";
"lng_context_animated_reactions" = "Reactions contain emoji from **{name} pack**.";
"lng_context_animated_reactions_many#one" = "Reactions contain emoji from **{count} pack**.";
"lng_context_animated_reactions_many#other" = "Reactions contain emoji from **{count} packs**.";
@@ -3397,7 +3471,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_group_call_rtmp_key_copy" = "Copy Stream Key";
"lng_group_call_rtmp_key_copied" = "Stream Key copied to clipboard.";
"lng_group_call_rtmp_key_warning" = "**Never share your Stream Key with anyone or show it on stream!**";
"lng_group_call_rtmp_info" = "To stream video with another app, enter these Server URL and Stream Key in your streaming app.\n\nOnce you start broadcasting in your streaming app, tap Start Streaming below.";
"lng_group_call_rtmp_info" = "To stream video with another app, enter these Server URL and Stream Key in your streaming app.\n\nOnce you start broadcasting in your streaming app, click Start Streaming below.";
"lng_group_call_rtmp_start" = "Start Streaming";
"lng_group_call_rtmp_revoke" = "Revoke Stream Key";
"lng_group_call_rtmp_revoke_sure" = "Are you sure you want to revoke your Server URL and Stream Key?";
@@ -3565,6 +3639,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_restricted_send_voice_messages" = "{user} restricted sending of voice messages to them.";
"lng_restricted_send_video_messages" = "{user} restricted sending of video messages to them.";
"lng_restricted_send_non_premium" = "Only Premium users can message {user}.";
"lng_restricted_send_non_premium_more" = "Learn more...";
"lng_send_non_premium_text" = "Subscribe to **Premium**\n to message {user}.";
"lng_send_non_premium_go" = "Get Premium";
"lng_send_non_premium_story" = "Replies restricted";
"lng_send_non_premium_unlock" = "unlock";
"lng_send_non_premium_message_toast" = "**{user}** only accepts messages from contacts and {link} subscribers.";
"lng_send_non_premium_message_toast_link" = "Telegram Premium";
"lng_exceptions_list_title" = "Exceptions";
"lng_removed_list_title" = "Removed users";
@@ -4232,7 +4315,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_sponsored_hide_ads" = "Hide";
"lng_sponsored_title" = "What are sponsored messages?";
"lng_sponsored_info_description1" = "Unlike other apps, Telegram never uses your private data to target ads. Sponsored messages on Telegram are based solely on the topic of the public channels in which they are shown. This means that no user data is mined or analyzed to display ads, and every user viewing a channel on Telegram sees the same sponsored messages.\n\nUnlike other apps, Telegram doesn't track whether you tapped on a sponsored message and doesn't profile you based on your activity. We also prevent external links in sponsored messages to ensure that third parties cant spy on our users. We believe that everyone has the right to privacy, and technological platforms should respect that.\n\nTelegram offers a free and unlimited service to hundreds of millions of users, which involves significant server and traffic costs. In order to remain independent and stay true to its values, Telegram developed a paid tool to promote messages with user privacy in mind. We welcome responsible advertisers at:";
"lng_sponsored_info_description1" = "Unlike other apps, Telegram never uses your private data to target ads. Sponsored messages on Telegram are based solely on the topic of the public channels in which they are shown. This means that no user data is mined or analyzed to display ads, and every user viewing a channel on Telegram sees the same sponsored messages.\n\nUnlike other apps, Telegram doesn't track whether you clicked on a sponsored message and doesn't profile you based on your activity. We also prevent external links in sponsored messages to ensure that third parties cant spy on our users. We believe that everyone has the right to privacy, and technological platforms should respect that.\n\nTelegram offers a free and unlimited service to hundreds of millions of users, which involves significant server and traffic costs. In order to remain independent and stay true to its values, Telegram developed a paid tool to promote messages with user privacy in mind. We welcome responsible advertisers at:";
"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}";
@@ -4346,6 +4429,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stories_views#one" = "{count} view";
"lng_stories_views#other" = "{count} views";
"lng_stories_no_views" = "No views";
"lng_stories_view_reactions" = "View reactions";
"lng_stories_unsupported" = "This story is not supported\nby your version of Telegram.";
"lng_stories_cant_reply" = "You can't reply to this story.";
"lng_stories_about_silent" = "This video has no sound.";
@@ -4400,6 +4484,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stories_channel_archive_done_many#one" = "{count} story is hidden from the channel page.";
"lng_stories_channel_archive_done_many#other" = "{count} stories are hidden from the channel page.";
"lng_stories_save_promo" = "Subscribe to {link} to download other people's unprotected stories to disk.";
"lng_stories_reaction_as_message" = "Send reaction as a private message";
"lng_stealth_mode_menu_item" = "Stealth Mode";
"lng_stealth_mode_title" = "Stealth Mode";
@@ -4648,6 +4733,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_ShowKllButtonInDrawer" = "Show kill app button";
"ayu_SettingsShowID" = "Show peer ID";
"ayu_SettingsShowID_Hide" = "Hide";
"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";
@@ -4661,7 +4747,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_DrawerElementsHeader" = "Drawer Elements";
"ayu_TrayElementsHeader" = "Tray Elements";
"ayu_RegexFilters" = "Message Filters";
"ayu_RegexFiltersAmount" = "filters";
"ayu_RegexFiltersAmount_zero" = "%1$d filters";
"ayu_RegexFiltersAmount_one" = "1 filter";
"ayu_RegexFiltersAmount_two" = "%1$d filters";
"ayu_RegexFiltersAmount_few" = "%1$d filters";
"ayu_RegexFiltersAmount_many" = "%1$d filters";
"ayu_RegexFiltersAmount_other" = "%1$d filters";
"ayu_RegexFiltersExcludedAmount_zero" = "%1$d excluded";
"ayu_RegexFiltersExcludedAmount_one" = "1 excluded";
"ayu_RegexFiltersExcludedAmount_two" = "%1$d excluded";
"ayu_RegexFiltersExcludedAmount_few" = "%1$d excluded";
"ayu_RegexFiltersExcludedAmount_many" = "%1$d excluded";
"ayu_RegexFiltersExcludedAmount_other" = "%1$d excluded";
"ayu_RegexFiltersHeader" = "Filters";
"ayu_RegexFiltersShared" = "Shared filters";
"ayu_RegexFiltersExcluded" = "Excluded filters";
@@ -4749,6 +4846,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_EditsHistoryMenuText" = "History";
"ayu_PeekOnlineMenuText" = "Peek Online";
"ayu_ClearDeletedMenuText" = "Clear Deleted";
"ayu_ViewDeletedMenuText" = "View Deleted";
"ayu_ViewFiltersMenuText" = "View Filters";
"ayu_PeekOnlineSuccess" = "Peeked via";
"ayu_OneViewTTL" = "one view";
@@ -4778,10 +4876,27 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_MonospaceFont" = "Monospace font";
"ayu_FontDefault" = "Default";
"ayu_CustomizeFontTitle" = "Customize font";
"ayu_MessageShotTopBarText" = "Shot";
"ayu_MessageShotPreview" = "Preview";
"ayu_MessageShotPreferences" = "Preferences";
"ayu_MessageShotCopy" = "Copy";
"ayu_MessageShotSave" = "Save";
"ayu_MessageShotTheme" = "Theme";
"ayu_MessageShotThemeDefault" = "Default";
"ayu_MessageShotThemeSelectTitle" = "Select message theme";
"ayu_MessageShotThemeApply" = "Apply";
"ayu_MessageShotShowBackground" = "Show background";
"ayu_MessageShotShowDate" = "Show date";
"ayu_MessageShotShowReactions" = "Show reactions";
"ayu_MessageShotShowColorfulReplies" = "Show colorful replies";
"ayu_SendAsSticker" = "Send as Sticker";
"ayu_AyuForwardStatusForwarding" = "Forwarding messages…";
"ayu_AyuForwardStatusLoadingMedia" = "Loading media…";
"ayu_AyuForwardForwardingDescription" = "Please keep this window open while AyuGram is forwarding your messages.";
"ayu_AyuForwardLoadingMediaDescription" = "Please keep this window open while AyuGram is downloading media from your messages.";
"ayu_ExpireMediaContextMenuText" = "Burn";
"ayu_ExpiringVoiceMessageNote" = "This voice message can be played as many times as you want.";
"ayu_ExpiringVideoMessageNote" = "This video message can be played as many times as you want.";
"ayu_UserNotFoundMessage" = "User not found.";
"ayu_DeleteDateMenuText" = "Delete Date";
"ayu_ReadDateMenuText" = "Read Date";
@@ -4795,6 +4910,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_IDCopiedToast" = "ID copied to clipboard.";
"ayu_ContextHideMessage" = "Hide";
"ayu_ContextCopyCallbackData" = "Copy Callback Data";
"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?";
@@ -26,6 +26,7 @@
<file alias="recording/info_audio.svg">../../art/recording/recording_info_audio.svg</file>
<file alias="recording/info_video_landscape.svg">../../art/recording/recording_info_video_landscape.svg</file>
<file alias="recording/info_video_portrait.svg">../../art/recording/recording_info_video_portrait.svg</file>
<file alias="ttl/video_message_icon.svg">../../art/ttl/video_message_icon.svg</file>
<file alias="icons/settings/dino.svg">../../icons/settings/dino.svg</file>
<file alias="icons/settings/star.svg">../../icons/settings/star.svg</file>
<file alias="icons/settings/starmini.svg">../../icons/settings/starmini.svg</file>
+1 -1
View File
@@ -10,7 +10,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="4.14.2.0" />
Version="4.14.13.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,14,2,0
PRODUCTVERSION 4,14,2,0
FILEVERSION 4,14,13,0
PRODUCTVERSION 4,14,13,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -62,10 +62,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Radolyn Labs"
VALUE "FileDescription", "AyuGram Desktop"
VALUE "FileVersion", "4.14.2.0"
VALUE "FileVersion", "4.14.13.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
VALUE "ProductName", "AyuGram Desktop"
VALUE "ProductVersion", "4.14.2.0"
VALUE "ProductVersion", "4.14.13.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,14,2,0
PRODUCTVERSION 4,14,2,0
FILEVERSION 4,14,13,0
PRODUCTVERSION 4,14,13,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.14.2.0"
VALUE "FileVersion", "4.14.13.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2024"
VALUE "ProductName", "AyuGram Desktop"
VALUE "ProductVersion", "4.14.2.0"
VALUE "ProductVersion", "4.14.13.0"
END
END
BLOCK "VarFileInfo"
+1
View File
@@ -25,6 +25,7 @@ struct SendOptions {
bool silent = false;
bool handleSupportSwitch = false;
bool hideViaBot = false;
crl::time ttlSeconds = 0;
};
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();
@@ -84,18 +84,61 @@ void GlobalPrivacy::dismissArchiveAndMuteSuggestion() {
u"AUTOARCHIVE_POPULAR"_q);
}
void GlobalPrivacy::updateHideReadTime(bool hide) {
update(
archiveAndMuteCurrent(),
unarchiveOnNewMessageCurrent(),
hide,
newRequirePremiumCurrent());
}
bool GlobalPrivacy::hideReadTimeCurrent() const {
return _hideReadTime.current();
}
rpl::producer<bool> GlobalPrivacy::hideReadTime() const {
return _hideReadTime.value();
}
void GlobalPrivacy::updateNewRequirePremium(bool value) {
update(
archiveAndMuteCurrent(),
unarchiveOnNewMessageCurrent(),
hideReadTimeCurrent(),
value);
}
bool GlobalPrivacy::newRequirePremiumCurrent() const {
return _newRequirePremium.current();
}
rpl::producer<bool> GlobalPrivacy::newRequirePremium() const {
return _newRequirePremium.value();
}
void GlobalPrivacy::updateArchiveAndMute(bool value) {
update(value, unarchiveOnNewMessageCurrent());
update(
value,
unarchiveOnNewMessageCurrent(),
hideReadTimeCurrent(),
newRequirePremiumCurrent());
}
void GlobalPrivacy::updateUnarchiveOnNewMessage(
UnarchiveOnNewMessage value) {
update(archiveAndMuteCurrent(), value);
update(
archiveAndMuteCurrent(),
value,
hideReadTimeCurrent(),
newRequirePremiumCurrent());
}
void GlobalPrivacy::update(
bool archiveAndMute,
UnarchiveOnNewMessage unarchiveOnNewMessage) {
UnarchiveOnNewMessage unarchiveOnNewMessage,
bool hideReadTime,
bool newRequirePremium) {
using Flag = MTPDglobalPrivacySettings::Flag;
_api.request(_requestId).cancel();
@@ -108,17 +151,26 @@ void GlobalPrivacy::update(
: Flag())
| (unarchiveOnNewMessage != UnarchiveOnNewMessage::AnyUnmuted
? Flag::f_keep_archived_folders
: Flag())
| (hideReadTime ? Flag::f_hide_read_marks : Flag())
| ((newRequirePremium && _session->premium())
? Flag::f_new_noncontact_peers_require_premium
: Flag());
_requestId = _api.request(MTPaccount_SetGlobalPrivacySettings(
MTP_globalPrivacySettings(MTP_flags(flags))
)).done([=](const MTPGlobalPrivacySettings &result) {
_requestId = 0;
apply(result);
}).fail([=] {
}).fail([=](const MTP::Error &error) {
_requestId = 0;
if (error.type() == u"PREMIUM_ACCOUNT_REQUIRED"_q) {
update(archiveAndMute, unarchiveOnNewMessage, hideReadTime, {});
}
}).send();
_archiveAndMute = archiveAndMute;
_unarchiveOnNewMessage = unarchiveOnNewMessage;
_hideReadTime = hideReadTime;
_newRequirePremium = newRequirePremium;
}
void GlobalPrivacy::apply(const MTPGlobalPrivacySettings &data) {
@@ -129,6 +181,8 @@ void GlobalPrivacy::apply(const MTPGlobalPrivacySettings &data) {
: data.is_keep_archived_folders()
? UnarchiveOnNewMessage::NotInFoldersUnmuted
: UnarchiveOnNewMessage::AnyUnmuted;
_hideReadTime = data.is_hide_read_marks();
_newRequirePremium = data.is_new_noncontact_peers_require_premium();
});
}
+13 -1
View File
@@ -41,12 +41,22 @@ public:
[[nodiscard]] rpl::producer<> suggestArchiveAndMute() const;
void dismissArchiveAndMuteSuggestion();
void updateHideReadTime(bool hide);
[[nodiscard]] bool hideReadTimeCurrent() const;
[[nodiscard]] rpl::producer<bool> hideReadTime() const;
void updateNewRequirePremium(bool value);
[[nodiscard]] bool newRequirePremiumCurrent() const;
[[nodiscard]] rpl::producer<bool> newRequirePremium() const;
private:
void apply(const MTPGlobalPrivacySettings &data);
void update(
bool archiveAndMute,
UnarchiveOnNewMessage unarchiveOnNewMessage);
UnarchiveOnNewMessage unarchiveOnNewMessage,
bool hideReadTime,
bool newRequirePremium);
const not_null<Main::Session*> _session;
MTP::Sender _api;
@@ -55,6 +65,8 @@ private:
rpl::variable<UnarchiveOnNewMessage> _unarchiveOnNewMessage
= UnarchiveOnNewMessage::None;
rpl::variable<bool> _showArchiveAndMute = false;
rpl::variable<bool> _hideReadTime = false;
rpl::variable<bool> _newRequirePremium = false;
std::vector<Fn<void()>> _callbacks;
};
+14 -8
View File
@@ -79,16 +79,19 @@ MTPInputMedia PrepareUploadedPhoto(
not_null<HistoryItem*> item,
RemoteFileInfo info) {
using Flag = MTPDinputMediaUploadedPhoto::Flag;
const auto spoiler = item->media()
&& item->media()->hasSpoiler();
const auto spoiler = item->media() && item->media()->hasSpoiler();
const auto ttlSeconds = item->media()
? item->media()->ttlSeconds()
: 0;
const auto flags = (spoiler ? Flag::f_spoiler : Flag())
| (info.attachedStickers.empty() ? Flag() : Flag::f_stickers);
| (info.attachedStickers.empty() ? Flag() : Flag::f_stickers)
| (ttlSeconds ? Flag::f_ttl_seconds : Flag());
return MTP_inputMediaUploadedPhoto(
MTP_flags(flags),
info.file,
MTP_vector<MTPInputDocument>(
ranges::to<QVector<MTPInputDocument>>(info.attachedStickers)),
MTP_int(0));
MTP_int(ttlSeconds));
}
MTPInputMedia PrepareUploadedDocument(
@@ -98,12 +101,15 @@ MTPInputMedia PrepareUploadedDocument(
return MTP_inputMediaEmpty();
}
using Flag = MTPDinputMediaUploadedDocument::Flag;
const auto spoiler = item->media()
&& item->media()->hasSpoiler();
const auto spoiler = item->media() && item->media()->hasSpoiler();
const auto ttlSeconds = item->media()
? item->media()->ttlSeconds()
: 0;
const auto flags = (spoiler ? Flag::f_spoiler : Flag())
| (info.thumb ? Flag::f_thumb : Flag())
| (item->groupId() ? Flag::f_nosound_video : Flag())
| (info.attachedStickers.empty() ? Flag::f_stickers : Flag());
| (info.attachedStickers.empty() ? Flag::f_stickers : Flag())
| (ttlSeconds ? Flag::f_ttl_seconds : Flag());
const auto document = item->media()->document();
return MTP_inputMediaUploadedDocument(
MTP_flags(flags),
@@ -113,7 +119,7 @@ MTPInputMedia PrepareUploadedDocument(
ComposeSendingDocumentAttributes(document),
MTP_vector<MTPInputDocument>(
ranges::to<QVector<MTPInputDocument>>(info.attachedStickers)),
MTP_int(0));
MTP_int(ttlSeconds));
}
bool HasAttachedStickers(MTPInputMedia media) {
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "data/data_channel.h"
#include "data/data_histories.h"
#include "data/data_message_reaction_id.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "history/history.h"
@@ -43,6 +44,23 @@ constexpr auto kSearchPerPage = 50;
return result;
}
[[nodiscard]] QString RequestToToken(
const MessagesSearch::Request &request) {
auto result = request.query;
if (request.from) {
result += '\n' + QString::number(request.from->id.value);
}
for (const auto &tag : request.tags) {
result += '\n';
if (const auto customId = tag.custom()) {
result += u"custom"_q + QString::number(customId);
} else {
result += u"emoji"_q + tag.emoji();
}
}
return result;
}
} // namespace
MessagesSearch::MessagesSearch(not_null<History*> history)
@@ -54,9 +72,8 @@ MessagesSearch::~MessagesSearch() {
base::take(_searchInHistoryRequest));
}
void MessagesSearch::searchMessages(const QString &query, PeerData *from) {
_query = query;
_from = from;
void MessagesSearch::searchMessages(Request request) {
_request = std::move(request);
_offsetId = {};
searchRequest();
}
@@ -69,8 +86,7 @@ void MessagesSearch::searchMore() {
}
void MessagesSearch::searchRequest() {
const auto nextToken = _query
+ QString::number(_from ? _from->id.value : 0);
const auto nextToken = RequestToToken(_request);
if (!_offsetId) {
const auto it = _cacheOfStartByToken.find(nextToken);
if (it != end(_cacheOfStartByToken)) {
@@ -80,17 +96,21 @@ void MessagesSearch::searchRequest() {
}
}
auto callback = [=](Fn<void()> finish) {
const auto flags = _from
? MTP_flags(MTPmessages_Search::Flag::f_from_id)
: MTP_flags(0);
using Flag = MTPmessages_Search::Flag;
const auto from = _request.from;
const auto fromPeer = _history->peer->isUser() ? nullptr : from;
const auto savedPeer = _history->peer->isSelf() ? from : nullptr;
_requestId = _history->session().api().request(MTPmessages_Search(
flags,
MTP_flags((fromPeer ? Flag::f_from_id : Flag())
| (savedPeer ? Flag::f_saved_peer_id : Flag())
| (_request.tags.empty() ? Flag() : Flag::f_saved_reaction)),
_history->peer->input,
MTP_string(_query),
(_from
? _from->input
: MTP_inputPeerEmpty()),
MTPInputPeer(), // saved_peer_id
MTP_string(_request.query),
(fromPeer ? fromPeer->input : MTP_inputPeerEmpty()),
(savedPeer ? savedPeer->input : MTP_inputPeerEmpty()),
MTP_vector_from_range(_request.tags | ranges::views::transform(
Data::ReactionToMTP
)),
MTPint(), // top_msg_id
MTP_inputMessagesFilterEmpty(),
MTP_int(0), // min_date
+22 -3
View File
@@ -7,10 +7,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "base/qt/qt_compare.h"
#include "data/data_message_reaction_id.h"
class HistoryItem;
class History;
class PeerData;
namespace Data {
struct ReactionId;
} // namespace Data
namespace Api {
struct FoundMessages {
@@ -21,10 +28,23 @@ struct FoundMessages {
class MessagesSearch final {
public:
struct Request {
QString query;
PeerData *from = nullptr;
std::vector<Data::ReactionId> tags;
friend inline bool operator==(
const Request &,
const Request &) = default;
friend inline auto operator<=>(
const Request &,
const Request &) = default;
};
explicit MessagesSearch(not_null<History*> history);
~MessagesSearch();
void searchMessages(const QString &query, PeerData *from);
void searchMessages(Request request);
void searchMore();
[[nodiscard]] rpl::producer<FoundMessages> messagesFounds() const;
@@ -41,8 +61,7 @@ private:
base::flat_map<QString, TLMessages> _cacheOfStartByToken;
QString _query;
PeerData *_from = nullptr;
Request _request;
MsgId _offsetId;
int _searchInHistoryRequest = 0; // Not real mtpRequestId.
@@ -11,12 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Api {
bool MessagesSearchMerged::RequestCompare::operator()(
const Request &a,
const Request &b) const {
return (a.query < b.query) && (a.from < b.from);
}
MessagesSearchMerged::MessagesSearchMerged(not_null<History*> history)
: _apiSearch(history) {
if (const auto migrated = history->migrateFrom()) {
@@ -88,9 +82,9 @@ void MessagesSearchMerged::clear() {
void MessagesSearchMerged::search(const Request &search) {
if (_migratedSearch) {
_waitingForTotal = true;
_migratedSearch->searchMessages(search.query, search.from);
_migratedSearch->searchMessages(search);
}
_apiSearch.searchMessages(search.query, search.from);
_apiSearch.searchMessages(search);
}
void MessagesSearchMerged::searchMore() {
@@ -12,19 +12,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class History;
class PeerData;
namespace Data {
struct ReactionId;
} // namespace Data
namespace Api {
// Search in both of history and migrated history, if it exists.
class MessagesSearchMerged final {
public:
struct Request {
QString query;
PeerData *from = nullptr;
};
struct RequestCompare {
bool operator()(const Request &a, const Request &b) const;
};
using CachedRequests = std::set<Request, RequestCompare>;
using Request = MessagesSearch::Request;
using CachedRequests = base::flat_set<Request>;
MessagesSearchMerged(not_null<History*> history);
+115
View File
@@ -15,6 +15,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_peer.h"
#include "data/data_peer_values.h"
#include "data/data_session.h"
#include "data/data_user.h"
#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"
@@ -334,6 +338,72 @@ const Data::SubscriptionOptions &Premium::subscriptionOptions() const {
return _subscriptionOptions;
}
rpl::producer<> Premium::somePremiumRequiredResolved() const {
return _somePremiumRequiredResolved.events();
}
void Premium::resolvePremiumRequired(not_null<UserData*> user) {
_resolvePremiumRequiredUsers.emplace(user);
if (!_premiumRequiredRequestScheduled
&& _resolvePremiumRequestedUsers.empty()) {
_premiumRequiredRequestScheduled = true;
crl::on_main(_session, [=] {
requestPremiumRequiredSlice();
});
}
}
void Premium::requestPremiumRequiredSlice() {
_premiumRequiredRequestScheduled = false;
if (!_resolvePremiumRequestedUsers.empty()
|| _resolvePremiumRequiredUsers.empty()) {
return;
}
constexpr auto kPerRequest = 100;
auto users = MTP_vector_from_range(_resolvePremiumRequiredUsers
| ranges::views::transform(&UserData::inputUser));
if (users.v.size() > kPerRequest) {
auto shortened = users.v;
shortened.resize(kPerRequest);
users = MTP_vector<MTPInputUser>(std::move(shortened));
const auto from = begin(_resolvePremiumRequiredUsers);
_resolvePremiumRequestedUsers = { from, from + kPerRequest };
_resolvePremiumRequiredUsers.erase(from, from + kPerRequest);
} else {
_resolvePremiumRequestedUsers
= base::take(_resolvePremiumRequiredUsers);
}
const auto finish = [=](const QVector<MTPBool> &list) {
constexpr auto me = UserDataFlag::MeRequiresPremiumToWrite;
constexpr auto known = UserDataFlag::RequirePremiumToWriteKnown;
constexpr auto mask = me | known;
auto index = 0;
for (const auto &user : base::take(_resolvePremiumRequestedUsers)) {
const auto require = (index < list.size())
&& mtpIsTrue(list[index++]);
user->setFlags((user->flags() & ~mask)
| known
| (require ? me : UserDataFlag()));
}
if (!_premiumRequiredRequestScheduled
&& !_resolvePremiumRequiredUsers.empty()) {
_premiumRequiredRequestScheduled = true;
crl::on_main(_session, [=] {
requestPremiumRequiredSlice();
});
}
_somePremiumRequiredResolved.fire({});
};
_session->api().request(
MTPusers_GetIsPremiumRequiredToContact(std::move(users))
).done([=](const MTPVector<MTPBool> &result) {
finish(result.v);
}).fail([=] {
finish({});
}).send();
}
PremiumGiftCodeOptions::PremiumGiftCodeOptions(not_null<PeerData*> peer)
: _peer(peer)
, _api(&peer->session().api().instance()) {
@@ -494,4 +564,49 @@ bool PremiumGiftCodeOptions::giveawayGiftsPurchaseAvailable() const {
false);
}
RequirePremiumState ResolveRequiresPremiumToWrite(
not_null<PeerData*> peer,
History *maybeHistory) {
const auto user = peer->asUser();
if (!user
|| !user->someRequirePremiumToWrite()
|| user->session().premium()) {
return RequirePremiumState::No;
} else if (user->requirePremiumToWriteKnown()) {
return user->meRequiresPremiumToWrite()
? RequirePremiumState::Yes
: RequirePremiumState::No;
} else if (user->flags() & UserDataFlag::MutualContact) {
return RequirePremiumState::No;
} else if (!maybeHistory) {
return RequirePremiumState::Unknown;
}
const auto update = [&](bool require) {
using Flag = UserDataFlag;
constexpr auto known = Flag::RequirePremiumToWriteKnown;
constexpr auto me = Flag::MeRequiresPremiumToWrite;
user->setFlags((user->flags() & ~me)
| known
| (require ? me : Flag()));
};
// We allow this potentially-heavy loop because in case we've opened
// the chat and have a lot of messages `requires_premium` will be known.
for (const auto &block : maybeHistory->blocks) {
for (const auto &view : block->messages) {
const auto item = view->data();
if (!item->out() && !item->isService()) {
update(false);
return RequirePremiumState::No;
}
}
}
if (user->isContact() // Here we know, that we're not in his contacts.
&& maybeHistory->loadedAtTop() // And no incoming messages.
&& maybeHistory->loadedAtBottom()) {
update(true);
}
return RequirePremiumState::Unknown;
}
} // namespace Api
+19
View File
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_subscription_option.h"
#include "mtproto/sender.h"
class History;
class ApiWrap;
namespace Main {
@@ -103,10 +104,14 @@ public:
[[nodiscard]] auto subscriptionOptions() const
-> const Data::SubscriptionOptions &;
[[nodiscard]] rpl::producer<> somePremiumRequiredResolved() const;
void resolvePremiumRequired(not_null<UserData*> user);
private:
void reloadPromo();
void reloadStickers();
void reloadCloudSet();
void requestPremiumRequiredSlice();
const not_null<Main::Session*> _session;
MTP::Sender _api;
@@ -143,6 +148,11 @@ private:
Data::SubscriptionOptions _subscriptionOptions;
rpl::event_stream<> _somePremiumRequiredResolved;
base::flat_set<not_null<UserData*>> _resolvePremiumRequiredUsers;
base::flat_set<not_null<UserData*>> _resolvePremiumRequestedUsers;
bool _premiumRequiredRequestScheduled = false;
};
class PremiumGiftCodeOptions final {
@@ -196,4 +206,13 @@ private:
};
enum class RequirePremiumState {
Unknown,
Yes,
No,
};
[[nodiscard]] RequirePremiumState ResolveRequiresPremiumToWrite(
not_null<PeerData*> peer,
History *maybeHistory);
} // namespace Api
@@ -174,14 +174,13 @@ bool SendProgressManager::skipRequest(const Key &key) const {
return true;
}
const auto recently = base::unixtime::now() - kSendTypingsToOfflineFor;
const auto online = user->onlineTill;
if (online == -2) { // last seen recently
const auto lastseen = user->lastseen();
if (lastseen.isRecently()) {
return false;
} else if (online < 0) {
return (-online < recently);
} else {
return (online < recently);
} else if (const auto value = lastseen.onlineTill()) {
return (value < recently);
}
return true;
}
void SendProgressManager::done(mtpRequestId requestId) {
+24 -6
View File
@@ -42,6 +42,9 @@ void InnerFillMessagePostFlags(
not_null<PeerData*> peer,
MessageFlags &flags) {
const auto anonymousPost = peer->amAnonymous();
if (ShouldSendSilent(peer, options)) {
flags |= MessageFlag::Silent;
}
if (!anonymousPost || options.sendAs) {
flags |= MessageFlag::HasFromId;
return;
@@ -399,11 +402,7 @@ void SendConfirmedFile(
flags |= MessageFlag::HasReplyInfo;
}
const auto anonymousPost = peer->amAnonymous();
const auto silentPost = ShouldSendSilent(peer, file->to.options);
FillMessagePostFlags(action, peer, flags);
if (silentPost) {
flags |= MessageFlag::Silent;
}
if (file->to.options.scheduled) {
flags |= MessageFlag::IsOrWasScheduled;
@@ -443,11 +442,30 @@ void SendConfirmedFile(
MTPDocument(), // alt_document
MTPint());
} else if (file->type == SendMediaType::Audio) {
const auto ttlSeconds = file->to.options.ttlSeconds;
const auto isVoice = [&] {
return file->document.match([](const MTPDdocumentEmpty &d) {
return false;
}, [](const MTPDdocument &d) {
return ranges::any_of(d.vattributes().v, [&](
const MTPDocumentAttribute &attribute) {
using Att = MTPDdocumentAttributeAudio;
return attribute.match([](const Att &data) -> bool {
return data.vflags().v & Att::Flag::f_voice;
}, [](const auto &) {
return false;
});
});
});
}();
using Flag = MTPDmessageMediaDocument::Flag;
return MTP_messageMediaDocument(
MTP_flags(MTPDmessageMediaDocument::Flag::f_document),
MTP_flags(Flag::f_document
| (isVoice ? Flag::f_voice : Flag())
| (ttlSeconds ? Flag::f_ttl_seconds : Flag())),
file->document,
MTPDocument(), // alt_document
MTPint());
MTP_int(ttlSeconds));
} else {
Unexpected("Type in sendFilesConfirmed.");
}
+14 -42
View File
@@ -914,12 +914,6 @@ void Updates::updateOnline(crl::time lastNonIdleTime, bool gotOtherOffline) {
bool isOnlineOrig = Core::App().hasActiveWindow(&session());
bool isOnline = settings->sendOnlinePackets && isOnlineOrig;
// AyuGram sendOfflinePacketAfterOnline
if (settings->sendOfflinePacketAfterOnline && _lastWasOnline)
{
isOnline = false;
}
int updateIn = config.onlineUpdatePeriod;
Assert(updateIn >= 0);
if (isOnline) {
@@ -958,7 +952,9 @@ void Updates::updateOnline(crl::time lastNonIdleTime, bool gotOtherOffline) {
}
const auto self = session().user();
self->onlineTill = base::unixtime::now() + (isOnline ? (config.onlineUpdatePeriod / 1000) : -1);
const auto onlineFor = (config.onlineUpdatePeriod / 1000);
self->updateLastseen(Data::LastseenStatus::OnlineTill(
base::unixtime::now() + (isOnline ? onlineFor : -1)));
session().changes().peerUpdated(
self,
Data::PeerUpdate::Flag::OnlineStatus);
@@ -972,24 +968,6 @@ void Updates::updateOnline(crl::time lastNonIdleTime, bool gotOtherOffline) {
updateIn = qMin(updateIn, int(_lastSetOnline + config.onlineUpdatePeriod - ms));
Assert(updateIn >= 0);
}
// AyuGram sendOfflinePacketAfterOnline
if (settings->sendOfflinePacketAfterOnline)
{
session().api().requestFullPeer(session().user());
if (session().user()->onlineTill > base::unixtime::now())
{
DEBUG_LOG(("[AyuGram] User likely appeared online"));
_onlineRequest = api().request(MTPaccount_UpdateStatus(
MTP_bool(true)
)).send();
}
DEBUG_LOG(("[AyuGram] Decreasing updateIn because of enabled features"));
updateIn = 1250;
}
_onlineTimer.callOnce(updateIn);
}
@@ -1243,8 +1221,8 @@ void Updates::applyUpdateNoPtsCheck(const MTPUpdate &update) {
if (user && !requestingDifference()) {
user->madeAction(base::unixtime::now());
}
ClearMediaAsExpired(item);
}
ClearMediaAsExpired(item);
}
} else {
// Perhaps it was an unread mention!
@@ -1882,23 +1860,13 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateUserStatus: {
auto &d = update.c_updateUserStatus();
if (auto user = session().data().userLoaded(d.vuser_id())) {
switch (d.vstatus().type()) {
case mtpc_userStatusEmpty: user->onlineTill = 0; break;
case mtpc_userStatusRecently:
if (user->onlineTill > -10) { // don't modify pseudo-online
user->onlineTill = -2;
}
break;
case mtpc_userStatusLastWeek: user->onlineTill = -3; break;
case mtpc_userStatusLastMonth: user->onlineTill = -4; break;
case mtpc_userStatusOffline: user->onlineTill = d.vstatus().c_userStatusOffline().vwas_online().v; break;
case mtpc_userStatusOnline: user->onlineTill = d.vstatus().c_userStatusOnline().vexpires().v; break;
if (const auto user = session().data().userLoaded(d.vuser_id())) {
const auto now = LastseenFromMTP(d.vstatus(), user->lastseen());
if (user->updateLastseen(now)) {
session().changes().peerUpdated(
user,
Data::PeerUpdate::Flag::OnlineStatus);
}
session().changes().peerUpdated(
user,
Data::PeerUpdate::Flag::OnlineStatus);
session().data().maybeStopWatchForOffline(user);
}
if (UserId(d.vuser_id()) == session().userId()) {
if (d.vstatus().type() == mtpc_userStatusOffline
@@ -2540,6 +2508,10 @@ void Updates::feedUpdate(const MTPUpdate &update) {
session().data().reactions().refreshRecentDelayed();
} break;
case mtpc_updateSavedReactionTags: {
session().data().reactions().refreshMyTagsDelayed();
} break;
////// Cloud saved GIFs
case mtpc_updateSavedGifs: {
session().data().stickers().setLastSavedGifsUpdate(0);
+89 -14
View File
@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_who_reacted.h"
#include "api/api_global_privacy.h"
#include "history/history_item.h"
#include "history/history.h"
#include "data/stickers/data_custom_emoji.h"
@@ -19,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "data/data_media_types.h"
#include "data/data_message_reaction_id.h"
#include "data/data_peer_values.h"
#include "lang/lang_keys.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
@@ -36,10 +38,11 @@ namespace {
constexpr auto kContextReactionsLimit = 50;
using Data::ReactionId;
using WhoReadState = Ui::WhoReadState;
struct Peers {
std::vector<WhoReadPeer> list;
bool unknown = false;
WhoReadState state = WhoReadState::Empty;
friend inline bool operator==(
const Peers &a,
@@ -59,7 +62,7 @@ struct PeersWithReactions {
std::vector<PeerWithReaction> list;
std::vector<WhoReadPeer> read;
int fullReactionsCount = 0;
bool unknown = false;
WhoReadState state = WhoReadState::Empty;
friend inline bool operator==(
const PeersWithReactions &a,
@@ -68,7 +71,7 @@ struct PeersWithReactions {
struct CachedRead {
CachedRead()
: data(Peers{ .unknown = true }) {
: data(Peers{ .state = WhoReadState::Unknown }) {
}
rpl::variable<Peers> data;
mtpRequestId requestId = 0;
@@ -76,7 +79,7 @@ struct CachedRead {
struct CachedReacted {
CachedReacted()
: data(PeersWithReactions{ .unknown = true }) {
: data(PeersWithReactions{ .state = WhoReadState::Unknown }) {
}
rpl::variable<PeersWithReactions> data;
mtpRequestId requestId = 0;
@@ -186,6 +189,27 @@ struct State {
context->cachedReacted.erase(j);
}
}, context->subscriptions[session]);
Data::AmPremiumValue(
session
) | rpl::skip(1) | rpl::filter(
rpl::mappers::_1
) | rpl::start_with_next([=] {
for (auto &[item, cache] : context->cachedRead) {
if (cache.data.current().state == Ui::WhoReadState::MyHidden) {
cache.data = Peers{ .state = Ui::WhoReadState::Unknown };
}
}
}, context->subscriptions[session]);
session->api().globalPrivacy().hideReadTime(
) | rpl::skip(1) | rpl::filter(
!rpl::mappers::_1
) | rpl::start_with_next([=] {
for (auto &[item, cache] : context->cachedRead) {
if (cache.data.current().state == Ui::WhoReadState::MyHidden) {
cache.data = Peers{ .state = Ui::WhoReadState::Unknown };
}
}
}, context->subscriptions[session]);
return context;
}
@@ -222,7 +246,38 @@ struct State {
}
const auto context = PreparedContextAt(weak.data(), session);
auto &entry = context->cacheRead(item);
if (!entry.requestId) {
if (entry.requestId) {
} else if (const auto user = item->history()->peer->asUser()) {
entry.requestId = session->api().request(
MTPmessages_GetOutboxReadDate(
user->input,
MTP_int(item->id)
)
).done([=](const MTPOutboxReadDate &result) {
const auto &data = result.data();
auto &entry = context->cacheRead(item);
entry.requestId = 0;
auto parsed = Peers();
parsed.list.push_back({
.peer = user->id,
.date = data.vdate().v,
});
entry.data = std::move(parsed);
}).fail([=](const MTP::Error &error) {
auto &entry = context->cacheRead(item);
entry.requestId = 0;
if (entry.data.current().state == WhoReadState::Unknown) {
const auto &text = error.type();
entry.data = (text == u"YOUR_PRIVACY_RESTRICTED"_q)
? Peers{ .state = WhoReadState::MyHidden }
: (text == u"USER_PRIVACY_RESTRICTED"_q)
? Peers{ .state = WhoReadState::HisHidden }
: (text == u"MESSAGE_TOO_OLD"_q)
? Peers{ .state = WhoReadState::TooOld }
: Peers{ .state = WhoReadState::Empty };
}
}).send();
} else {
entry.requestId = session->api().request(
MTPmessages_GetMessageReadParticipants(
item->history()->peer->input,
@@ -243,8 +298,8 @@ struct State {
}).fail([=] {
auto &entry = context->cacheRead(item);
entry.requestId = 0;
if (entry.data.current().unknown) {
entry.data = Peers();
if (entry.data.current().state == WhoReadState::Unknown) {
entry.data = Peers{ .state = WhoReadState::Empty };
}
}).send();
}
@@ -258,7 +313,7 @@ struct State {
.list = peers.list | ranges::views::transform([](WhoReadPeer peer) {
return PeerWithReaction{ .peerWithDate = peer };
}) | ranges::to_vector,
.unknown = peers.unknown,
.state = peers.state,
};
result.read = std::move(peers.list);
return result;
@@ -319,8 +374,10 @@ struct State {
}).fail([=] {
auto &entry = context->cacheReacted(item, reaction);
entry.requestId = 0;
if (entry.data.current().unknown) {
entry.data = PeersWithReactions();
if (entry.data.current().state == WhoReadState::Unknown) {
entry.data = PeersWithReactions{
.state = WhoReadState::Empty,
};
}
}).send();
}
@@ -336,8 +393,9 @@ struct State {
WhoReactedIds(item, {}, context),
WhoReadIds(item, context)
) | rpl::map([=](PeersWithReactions &&reacted, Peers &&read) {
if (reacted.unknown || read.unknown) {
return PeersWithReactions{ .unknown = true };
if (reacted.state == WhoReadState::Unknown
|| read.state == WhoReadState::Unknown) {
return PeersWithReactions{ .state = WhoReadState::Unknown};
}
auto &list = reacted.list;
for (const auto &peerWithDate : read.list) {
@@ -531,16 +589,17 @@ rpl::producer<Ui::WhoReadContent> WhoReacted(
std::move(
idsWithReactions
) | rpl::start_with_next([=](PeersWithReactions &&peers) {
if (peers.unknown) {
if (peers.state == WhoReadState::Unknown) {
state->userpics.clear();
consumer.put_next(Ui::WhoReadContent{
.type = state->current.type,
.fullReactionsCount = state->current.fullReactionsCount,
.fullReadCount = state->current.fullReadCount,
.unknown = true,
.state = WhoReadState::Unknown,
});
return;
}
state->current.state = peers.state;
state->current.fullReadCount = int(peers.read.size());
state->current.fullReactionsCount = peers.fullReactionsCount;
if (whoReadIds) {
@@ -631,6 +690,22 @@ bool WhoReadExists(not_null<HistoryItem*> item) {
}
const auto history = item->history();
const auto peer = history->peer;
if (const auto user = peer->asUser()) {
if (user->isSelf()
|| user->isBot()
|| user->isServiceUser()
|| user->readDatesPrivate()) {
return false;
}
const auto &appConfig = peer->session().account().appConfig();
const auto expirePeriod = appConfig.get<int>(
"pm_read_date_expire_period",
7 * 86400);
if (item->date() + int64(expirePeriod) <= int64(base::unixtime::now())) {
return false;
}
return true;
}
const auto chat = peer->asChat();
const auto megagroup = peer->asMegagroup();
if ((!chat && !megagroup)
+41 -55
View File
@@ -85,6 +85,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
// AyuGram includes
#include "ayu/ayu_settings.h"
#include "ayu/ayu_worker.h"
namespace {
@@ -1953,28 +1954,28 @@ void ApiWrap::saveDraftToCloudDelayed(not_null<Data::Thread*> thread) {
void ApiWrap::updatePrivacyLastSeens() {
const auto now = base::unixtime::now();
_session->data().enumerateUsers([&](UserData *user) {
if (user->isSelf() || !user->isLoaded()) {
return;
}
if (user->onlineTill <= 0) {
return;
}
if (!_session->premium()) {
_session->data().enumerateUsers([&](not_null<UserData*> user) {
if (user->isSelf()
|| !user->isLoaded()
|| user->lastseen().isHidden()) {
return;
}
if (user->onlineTill + 3 * 86400 >= now) {
user->onlineTill = -2; // recently
} else if (user->onlineTill + 7 * 86400 >= now) {
user->onlineTill = -3; // last week
} else if (user->onlineTill + 30 * 86400 >= now) {
user->onlineTill = -4; // last month
} else {
user->onlineTill = 0;
}
session().changes().peerUpdated(
user,
Data::PeerUpdate::Flag::OnlineStatus);
session().data().maybeStopWatchForOffline(user);
});
const auto till = user->lastseen().onlineTill();
user->updateLastseen((till + 3 * 86400 >= now)
? Data::LastseenStatus::Recently(true)
: (till + 7 * 86400 >= now)
? Data::LastseenStatus::WithinWeek(true)
: (till + 30 * 86400 >= now)
? Data::LastseenStatus::WithinMonth(true)
: Data::LastseenStatus::LongAgo(true));
session().changes().peerUpdated(
user,
Data::PeerUpdate::Flag::OnlineStatus);
session().data().maybeStopWatchForOffline(user);
});
}
if (_contactsStatusesRequestId) {
request(_contactsStatusesRequestId).cancel();
@@ -1982,20 +1983,17 @@ void ApiWrap::updatePrivacyLastSeens() {
_contactsStatusesRequestId = request(MTPcontacts_GetStatuses(
)).done([=](const MTPVector<MTPContactStatus> &result) {
_contactsStatusesRequestId = 0;
for (const auto &item : result.v) {
Assert(item.type() == mtpc_contactStatus);
auto &data = item.c_contactStatus();
if (auto user = _session->data().userLoaded(data.vuser_id())) {
auto oldOnlineTill = user->onlineTill;
auto newOnlineTill = OnlineTillFromStatus(
for (const auto &status : result.v) {
const auto &data = status.data();
const auto userId = UserId(data.vuser_id());
if (const auto user = _session->data().userLoaded(userId)) {
const auto status = LastseenFromMTP(
data.vstatus(),
oldOnlineTill);
if (oldOnlineTill != newOnlineTill) {
user->onlineTill = newOnlineTill;
user->lastseen());
if (user->updateLastseen(status)) {
session().changes().peerUpdated(
user,
Data::PeerUpdate::Flag::OnlineStatus);
session().data().maybeStopWatchForOffline(user);
}
}
}
@@ -2004,22 +2002,6 @@ void ApiWrap::updatePrivacyLastSeens() {
}).send();
}
int ApiWrap::OnlineTillFromStatus(
const MTPUserStatus &status,
int currentOnlineTill) {
switch (status.type()) {
case mtpc_userStatusEmpty: return 0;
case mtpc_userStatusRecently:
// Don't modify pseudo-online.
return (currentOnlineTill > -10) ? -2 : currentOnlineTill;
case mtpc_userStatusLastWeek: return -3;
case mtpc_userStatusLastMonth: return -4;
case mtpc_userStatusOffline: return status.c_userStatusOffline().vwas_online().v;
case mtpc_userStatusOnline: return status.c_userStatusOnline().vexpires().v;
}
Unexpected("Bad UserStatus type.");
}
void ApiWrap::clearHistory(not_null<PeerData*> peer, bool revoke) {
deleteHistory(peer, true, revoke);
}
@@ -3585,8 +3567,7 @@ void ApiWrap::sendUploadedPhoto(
if (const auto item = _session->data().message(localId)) {
// AyuGram useScheduledMessages
const auto settings = &AyuSettings::getInstance();
if (settings->useScheduledMessages && !options.scheduled)
{
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
@@ -3612,8 +3593,7 @@ void ApiWrap::sendUploadedDocument(
// AyuGram useScheduledMessages
const auto settings = &AyuSettings::getInstance();
if (settings->useScheduledMessages && !options.scheduled)
{
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...
@@ -3800,6 +3780,8 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
draftTopicRootId,
UnixtimeFromMsgId(response.outerMsgId));
}
AyuWorker::markAsOnline(_session);
};
const auto fail = [=](
const MTP::Error &error,
@@ -3893,6 +3875,8 @@ void ApiWrap::sendBotStart(
MTP_string(token)
)).done([=](const MTPUpdates &result) {
applyUpdates(result);
AyuWorker::markAsOnline(_session);
}).fail([=](const MTP::Error &error) {
if (chat) {
const auto type = error.type();
@@ -4092,8 +4076,7 @@ void ApiWrap::sendMediaWithRandomId(
Fn<void(bool)> done) {
// AyuGram useScheduledMessages
const auto settings = &AyuSettings::getInstance();
if (settings->useScheduledMessages && !options.scheduled)
{
if (settings->useScheduledMessages && !options.scheduled) {
DEBUG_LOG(("[AyuGram] Scheduling message"));
auto current = base::unixtime::now();
options.scheduled = current + 12;
@@ -4144,6 +4127,8 @@ void ApiWrap::sendMediaWithRandomId(
if (updateRecentStickers) {
requestRecentStickersForce(true);
}
AyuWorker::markAsOnline(_session);
}, [=](const MTP::Error &error, const MTP::Response &response) {
if (done) done(false);
sendMessageFail(error, peer, randomId, itemId);
@@ -4192,8 +4177,7 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
// AyuGram useScheduledMessages
const auto settings = &AyuSettings::getInstance();
if (settings->useScheduledMessages && !album->options.scheduled)
{
if (settings->useScheduledMessages && !album->options.scheduled) {
DEBUG_LOG(("[AyuGram] Scheduling message"));
auto current = base::unixtime::now();
album->options.scheduled = current + 12;
@@ -4249,6 +4233,8 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
(sendAs ? sendAs->input : MTP_inputPeerEmpty())
), [=](const MTPUpdates &result, const MTP::Response &response) {
_sendingAlbums.remove(groupId);
AyuWorker::markAsOnline(_session);
}, [=](const MTP::Error &error, const MTP::Response &response) {
if (const auto album = _sendingAlbums.take(groupId)) {
for (const auto &item : (*album)->items) {
-4
View File
@@ -258,10 +258,6 @@ public:
void updateNotifySettingsDelayed(Data::DefaultNotify type);
void saveDraftToCloudDelayed(not_null<Data::Thread*> thread);
static int OnlineTillFromStatus(
const MTPUserStatus &status,
int currentOnlineTill);
void clearHistory(not_null<PeerData*> peer, bool revoke);
void deleteConversation(not_null<PeerData*> peer, bool revoke);
+1 -4
View File
@@ -3,14 +3,11 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#pragma once
// https://github.com/AyuGram/AyuGram4AX/blob/rewrite/TMessagesProj/src/main/java/com/radolyn/ayugram/AyuConstants.java
constexpr int DOCUMENT_TYPE_NONE = 0;
constexpr int DOCUMENT_TYPE_PHOTO = 1;
constexpr int DOCUMENT_TYPE_STICKER = 2;
constexpr int DOCUMENT_TYPE_FILE = 3;
+22 -28
View File
@@ -3,21 +3,19 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#include "ayu_infra.h"
#include "ayu_lang.h"
#include "ayu/ayu_lottie.h"
#include "ayu/ui/ayu_lottie.h"
#include "ayu/database/ayu_database.h"
#include "lang/lang_instance.h"
#include "ayu_worker.h"
#include "ayu/ayu_fonts.h"
#include "ayu/ayu_settings.h"
#include "ayu/data/ayu_database.h"
#include "lang/lang_instance.h"
namespace AyuInfra
{
namespace AyuInfra {
void initLang()
{
void initLang() {
QString langPackBaseId = Lang::GetInstance().baseId();
QString langPackId = Lang::GetInstance().id();
if (langPackId.isEmpty()) {
@@ -28,30 +26,26 @@ void initLang()
CustomLangPack::currentInstance()->fetchCustomLangPack(langPackId, langPackBaseId);
}
void initLottie()
{
AyuUi::setLottieImpl(std::make_shared<AyuUi::AyuLottieImpl>());
}
void initDatabase()
{
AyuDatabase::initialize();
}
void initFonts()
{
void initFonts() {
auto settings = &AyuSettings::getInstance();
AyuFonts::setMainFont(settings->mainFont);
AyuFonts::setMonoFont(settings->monoFont);
}
void init()
{
initLang();
initLottie();
initFonts();
initDatabase();
void initDatabase() {
AyuDatabase::initialize();
}
}
void initWorker() {
AyuWorker::initialize();
}
void init() {
initLang();
initDatabase();
initFonts();
initWorker();
}
}
+2 -3
View File
@@ -3,11 +3,10 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#pragma once
namespace AyuInfra
{
namespace AyuInfra {
void init();
+15 -27
View File
@@ -3,7 +3,7 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#include "ayu_lang.h"
#include "qjsondocument.h"
@@ -24,26 +24,22 @@ CustomLangPack *CustomLangPack::instance = nullptr;
CustomLangPack::CustomLangPack() = default;
void CustomLangPack::initInstance()
{
if (!instance)
instance = new CustomLangPack;
void CustomLangPack::initInstance() {
if (!instance) instance = new CustomLangPack;
}
CustomLangPack *CustomLangPack::currentInstance()
{
CustomLangPack *CustomLangPack::currentInstance() {
return instance;
}
void CustomLangPack::fetchCustomLangPack(const QString &langPackId, const QString &langPackBaseId)
{
void CustomLangPack::fetchCustomLangPack(const QString &langPackId, const QString &langPackBaseId) {
LOG(("Current Language pack ID: %1, Base ID: %2").arg(langPackId, langPackBaseId));
auto finalLangPackId = langMapping.contains(langPackId) ? langMapping[langPackId] : langPackId;
const auto proxy = Core::App().settings().proxy().isEnabled()
? Core::App().settings().proxy().selected()
: MTP::ProxyData();
? Core::App().settings().proxy().selected()
: MTP::ProxyData();
if (proxy.type == MTP::ProxyData::Type::Socks5 || proxy.type == MTP::ProxyData::Type::Http) {
QNetworkProxy LocaleProxy = ToNetworkProxy(ToDirectIpProxy(proxy));
networkManager.setProxy(LocaleProxy);
@@ -55,8 +51,7 @@ void CustomLangPack::fetchCustomLangPack(const QString &langPackId, const QStrin
if (!finalLangPackId.isEmpty() && !langPackBaseId.isEmpty() && !needFallback) {
url.setUrl(qsl("https://cdn.jsdelivr.net/gh/AyuGram/Languages@l10n_main/values/langs/%1/Shared.json").arg(
finalLangPackId));
}
else {
} else {
url.setUrl(qsl("https://cdn.jsdelivr.net/gh/AyuGram/Languages@l10n_main/values/langs/%1/Shared.json").arg(
needFallback ? langPackBaseId : finalLangPackId));
}
@@ -67,8 +62,7 @@ void CustomLangPack::fetchCustomLangPack(const QString &langPackId, const QStrin
needFallback ? (langPackBaseId.isEmpty() ? finalLangPackId : langPackBaseId) : finalLangPackId));
}
void CustomLangPack::fetchFinished()
{
void CustomLangPack::fetchFinished() {
if (!_chkReply) return;
QString langPackBaseId = Lang::GetInstance().baseId();
@@ -80,15 +74,13 @@ void CustomLangPack::fetchFinished()
needFallback = true;
_chkReply->disconnect();
fetchCustomLangPack("", langPackBaseId);
}
else {
} else {
QByteArray result = _chkReply->readAll().trimmed();
QJsonParseError error{};
QJsonDocument str = QJsonDocument::fromJson(result, &error);
if (error.error == QJsonParseError::NoError) {
parseLangFile(str);
}
else {
} else {
LOG(("Incorrect JSON File. Fallback to default language: English..."));
loadDefaultLangFile();
}
@@ -97,8 +89,7 @@ void CustomLangPack::fetchFinished()
}
}
void CustomLangPack::fetchError(QNetworkReply::NetworkError e)
{
void CustomLangPack::fetchError(QNetworkReply::NetworkError e) {
LOG(("Network error: %1").arg(e));
if (e == QNetworkReply::NetworkError::ContentNotFoundError) {
@@ -110,8 +101,7 @@ void CustomLangPack::fetchError(QNetworkReply::NetworkError e)
needFallback = true;
_chkReply->disconnect();
fetchCustomLangPack("", langPackBaseId);
}
else {
} else {
LOG(("AyuGram Language pack not found! Fallback to default language: English..."));
loadDefaultLangFile();
_chkReply = nullptr;
@@ -119,8 +109,7 @@ void CustomLangPack::fetchError(QNetworkReply::NetworkError e)
}
}
void CustomLangPack::loadDefaultLangFile()
{
void CustomLangPack::loadDefaultLangFile() {
QFile file(":/localization/en.json");
if (file.open(QIODevice::ReadOnly)) {
QJsonDocument str = QJsonDocument::fromJson(file.readAll());
@@ -133,8 +122,7 @@ void CustomLangPack::loadDefaultLangFile()
}
}
void CustomLangPack::parseLangFile(QJsonDocument str)
{
void CustomLangPack::parseLangFile(QJsonDocument str) {
QJsonObject json = str.object();
for (const QString &brokenKey : json.keys()) {
auto key = qsl("ayu_") + brokenKey;
+2 -9
View File
@@ -3,7 +3,7 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#pragma once
#include <QtNetwork/QNetworkReply>
@@ -11,31 +11,24 @@
class CustomLangPack : public QObject
{
Q_OBJECT
Q_OBJECT
Q_DISABLE_COPY(CustomLangPack)
public:
static CustomLangPack *currentInstance();
static void initInstance();
static CustomLangPack *instance;
void fetchCustomLangPack(const QString &langPackId, const QString &langPackBaseId);
void loadDefaultLangFile();
void parseLangFile(QJsonDocument str);
public Q_SLOTS:
void fetchFinished();
void fetchError(QNetworkReply::NetworkError e);
private:
CustomLangPack();
~CustomLangPack() override = default;
QNetworkAccessManager networkManager;
+171 -137
View File
@@ -3,56 +3,56 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#include "ayu_settings.h"
#include "ayu/ui/ayu_logo.h"
#include "lang_auto.h"
#include "core/application.h"
#include "rpl/lifetime.h"
#include "rpl/producer.h"
#include "rpl/variable.h"
#include <fstream>
#include "ayu_worker.h"
#include "window/window_controller.h"
using json = nlohmann::json;
namespace AyuSettings
{
namespace AyuSettings {
const std::string filename = "tdata/ayu_settings.json";
std::optional<AyuGramSettings> settings = std::nullopt;
rpl::variable<bool> sendReadMessagesReactive;
rpl::variable<bool> sendReadStoriesReactive;
rpl::variable<bool> sendOnlinePacketsReactive;
rpl::variable<bool> sendUploadProgressReactive;
rpl::variable<bool> sendOfflinePacketAfterOnlineReactive;
rpl::variable<QString> deletedMarkReactive;
rpl::variable<bool> ghostModeEnabled;
rpl::variable<QString> deletedMarkReactive;
rpl::variable<QString> editedMarkReactive;
rpl::variable<int> showPeerIdReactive;
rpl::variable<bool> ghostModeEnabled;
rpl::lifetime lifetime = rpl::lifetime();
bool ghostModeEnabled_util(AyuGramSettings &settingsUtil)
{
bool ghostModeEnabled_util(const AyuGramSettings &settingsUtil) {
return
!settingsUtil.sendReadMessages
&& !settingsUtil.sendReadStories
&& !settingsUtil.sendOnlinePackets
&& !settingsUtil.sendUploadProgress
&& settingsUtil.sendOfflinePacketAfterOnline;
&& !settingsUtil.sendReadStories
&& !settingsUtil.sendOnlinePackets
&& !settingsUtil.sendUploadProgress
&& settingsUtil.sendOfflinePacketAfterOnline;
}
void initialize()
{
void initialize() {
if (settings.has_value()) {
return;
}
@@ -68,7 +68,8 @@ void initialize()
{
ghostModeEnabled =
ghostModeEnabled_util(settings.value());
}, lifetime);
},
lifetime);
// ..
sendReadStoriesReactive.value() | rpl::filter(
[=](bool val)
@@ -79,7 +80,8 @@ void initialize()
{
ghostModeEnabled =
ghostModeEnabled_util(settings.value());
}, lifetime);
},
lifetime);
// ..
sendOnlinePacketsReactive.value() | rpl::filter(
[=](bool val)
@@ -90,8 +92,9 @@ void initialize()
{
ghostModeEnabled =
ghostModeEnabled_util(settings
.value());
}, lifetime);
.value());
},
lifetime);
// ..
sendUploadProgressReactive.value() | rpl::filter(
[=](bool val)
@@ -102,8 +105,9 @@ void initialize()
{
ghostModeEnabled =
ghostModeEnabled_util(settings
.value());
}, lifetime);
.value());
},
lifetime);
// ..
sendOfflinePacketAfterOnlineReactive.value() | rpl::filter(
[=](bool val)
@@ -116,11 +120,11 @@ void initialize()
ghostModeEnabled =
ghostModeEnabled_util(
settings.value());
}, lifetime);
},
lifetime);
}
void postinitialize()
{
void postinitialize() {
sendReadMessagesReactive = settings->sendReadMessages;
sendReadStoriesReactive = settings->sendReadStories;
sendUploadProgressReactive = settings->sendUploadProgress;
@@ -134,14 +138,12 @@ void postinitialize()
ghostModeEnabled = ghostModeEnabled_util(settings.value());
}
AyuGramSettings &getInstance()
{
AyuGramSettings &getInstance() {
initialize();
return settings.value();
}
void load()
{
void load() {
std::ifstream file(filename);
if (!file.good()) {
return;
@@ -156,19 +158,16 @@ void load()
try {
settings = p.get<AyuGramSettings>();
}
catch (...) {
} catch (...) {
LOG(("AyuGramSettings: failed to parse settings file"));
}
}
catch (...) {
} catch (...) {
LOG(("AyuGramSettings: failed to read settings file (not json-like)"));
}
postinitialize();
}
void save()
{
void save() {
initialize();
json p = settings.value();
@@ -181,265 +180,300 @@ void save()
postinitialize();
}
void AyuGramSettings::set_sendReadMessages(bool val)
{
AyuGramSettings::AyuGramSettings() {
// ~ Ghost essentials
sendReadMessages = true;
sendReadStories = true;
sendOnlinePackets = true;
sendUploadProgress = true;
sendOfflinePacketAfterOnline = false;
markReadAfterSend = true;
markReadAfterReaction = true;
markReadAfterPoll = true;
useScheduledMessages = false;
// ~ Message edits & deletion history
saveDeletedMessages = false;
saveMessagesHistory = true;
// ~ QoL toggles
disableAds = true;
disableStories = false;
collapseSimilarChannels = true;
hideSimilarChannels = false;
uploadSpeedBoost = false;
disableNotificationsDelay = false;
localPremium = false;
copyUsernameAsLink = true;
// ~ Customization
appIcon = AyuAssets::DEFAULT_ICON;
simpleQuotesAndReplies = true;
deletedMark = "🧹";
editedMark = Core::IsAppLaunched() ? tr::lng_edited(tr::now) : QString("edited");
recentStickersCount = 50;
// context menu items
// 0 - hide
// 1 - show normally
// 2 - show with SHIFT or CTRL pressed
showReactionsPanelInContextMenu = 1;
showViewsPanelInContextMenu = 1;
showHideMessageInContextMenu = 0;
showUserMessagesInContextMenu = 2;
showMessageDetailsInContextMenu = 2;
showLReadToggleInDrawer = true;
showSReadToggleInDrawer = true;
showGhostToggleInDrawer = true;
showStreamerToggleInDrawer = false;
showGhostToggleInTray = true;
showStreamerToggleInTray = false;
mainFont = "";
monoFont = "";
hideNotificationCounters = false;
hideAllChatsFolder = false;
/*
* showPeerId = 0 means no ID shown
* showPeerId = 1 means ID shown as for Telegram API devs
* showPeerId = 2 means ID shown as for Bot API devs (-100)
*/
showPeerId = 2;
showMessageSeconds = false;
showMessageShot = true;
// ~ Confirmations
stickerConfirmation = false;
gifConfirmation = false;
voiceConfirmation = false;
}
void AyuGramSettings::set_sendReadMessages(bool val) {
sendReadMessages = val;
sendReadMessagesReactive = val;
}
void AyuGramSettings::set_sendReadStories(bool val)
{
void AyuGramSettings::set_sendReadStories(bool val) {
sendReadStories = val;
sendReadStoriesReactive = val;
}
void AyuGramSettings::set_sendOnlinePackets(bool val)
{
void AyuGramSettings::set_sendOnlinePackets(bool val) {
sendOnlinePackets = val;
sendOnlinePacketsReactive = val;
}
void AyuGramSettings::set_sendUploadProgress(bool val)
{
void AyuGramSettings::set_sendUploadProgress(bool val) {
sendUploadProgress = val;
sendUploadProgressReactive = val;
}
void AyuGramSettings::set_sendOfflinePacketAfterOnline(bool val)
{
void AyuGramSettings::set_sendOfflinePacketAfterOnline(bool val) {
sendOfflinePacketAfterOnline = val;
sendOfflinePacketAfterOnlineReactive = val;
}
void AyuGramSettings::set_ghostModeEnabled(bool val)
{
void AyuGramSettings::set_ghostModeEnabled(bool val) {
set_sendReadMessages(!val);
set_sendReadStories(!val);
set_sendOnlinePackets(!val);
set_sendUploadProgress(!val);
set_sendOfflinePacketAfterOnline(val);
if (const auto window = Core::App().activeWindow()) {
if (const auto session = window->maybeSession()) {
AyuWorker::markAsOnline(session); // mark as online to get offline instantly
}
}
}
void AyuGramSettings::set_markReadAfterSend(bool val)
{
void AyuGramSettings::set_markReadAfterSend(bool val) {
markReadAfterSend = val;
}
void AyuGramSettings::set_markReadAfterReaction(bool val)
{
void AyuGramSettings::set_markReadAfterReaction(bool val) {
markReadAfterReaction = val;
}
void AyuGramSettings::set_markReadAfterPoll(bool val)
{
void AyuGramSettings::set_markReadAfterPoll(bool val) {
markReadAfterPoll = val;
}
void AyuGramSettings::set_useScheduledMessages(bool val)
{
void AyuGramSettings::set_useScheduledMessages(bool val) {
useScheduledMessages = val;
}
void AyuGramSettings::set_saveDeletedMessages(bool val)
{
void AyuGramSettings::set_saveDeletedMessages(bool val) {
saveDeletedMessages = val;
}
void AyuGramSettings::set_saveMessagesHistory(bool val)
{
void AyuGramSettings::set_saveMessagesHistory(bool val) {
saveMessagesHistory = val;
}
void AyuGramSettings::set_disableAds(bool val)
{
void AyuGramSettings::set_disableAds(bool val) {
disableAds = val;
}
void AyuGramSettings::set_disableStories(bool val)
{
void AyuGramSettings::set_disableStories(bool val) {
disableStories = val;
}
void AyuGramSettings::set_collapseSimilarChannels(bool val)
{
void AyuGramSettings::set_collapseSimilarChannels(bool val) {
collapseSimilarChannels = val;
}
void AyuGramSettings::set_hideSimilarChannels(bool val)
{
void AyuGramSettings::set_hideSimilarChannels(bool val) {
hideSimilarChannels = val;
}
void AyuGramSettings::set_uploadSpeedBoost(bool val)
{
void AyuGramSettings::set_uploadSpeedBoost(bool val) {
uploadSpeedBoost = val;
}
void AyuGramSettings::set_disableNotificationsDelay(bool val)
{
void AyuGramSettings::set_disableNotificationsDelay(bool val) {
disableNotificationsDelay = val;
}
void AyuGramSettings::set_localPremium(bool val)
{
void AyuGramSettings::set_localPremium(bool val) {
localPremium = val;
}
void AyuGramSettings::set_copyUsernameAsLink(bool val)
{
void AyuGramSettings::set_copyUsernameAsLink(bool val) {
copyUsernameAsLink = val;
}
void AyuGramSettings::set_appIcon(QString val)
{
void AyuGramSettings::set_appIcon(QString val) {
appIcon = std::move(val);
}
void AyuGramSettings::set_simpleQuotesAndReplies(bool val)
{
void AyuGramSettings::set_simpleQuotesAndReplies(bool val) {
simpleQuotesAndReplies = val;
}
void AyuGramSettings::set_deletedMark(QString val)
{
void AyuGramSettings::set_deletedMark(QString val) {
deletedMark = std::move(val);
deletedMarkReactive = deletedMark;
}
void AyuGramSettings::set_editedMark(QString val)
{
void AyuGramSettings::set_editedMark(QString val) {
editedMark = std::move(val);
editedMarkReactive = editedMark;
}
void AyuGramSettings::set_recentStickersCount(int val)
{
void AyuGramSettings::set_recentStickersCount(int val) {
recentStickersCount = val;
}
void AyuGramSettings::set_showReactionsPanelInContextMenu(int val)
{
void AyuGramSettings::set_showReactionsPanelInContextMenu(int val) {
showReactionsPanelInContextMenu = val;
}
void AyuGramSettings::set_showViewsPanelInContextMenu(int val)
{
void AyuGramSettings::set_showViewsPanelInContextMenu(int val) {
showViewsPanelInContextMenu = val;
}
void AyuGramSettings::set_showHideMessageInContextMenu(int val)
{
void AyuGramSettings::set_showHideMessageInContextMenu(int val) {
showHideMessageInContextMenu = val;
}
void AyuGramSettings::set_showUserMessagesInContextMenu(int val)
{
void AyuGramSettings::set_showUserMessagesInContextMenu(int val) {
showUserMessagesInContextMenu = val;
}
void AyuGramSettings::set_showMessageDetailsInContextMenu(int val)
{
void AyuGramSettings::set_showMessageDetailsInContextMenu(int val) {
showMessageDetailsInContextMenu = val;
}
void AyuGramSettings::set_showLReadToggleInDrawer(bool val)
{
void AyuGramSettings::set_showLReadToggleInDrawer(bool val) {
showLReadToggleInDrawer = val;
}
void AyuGramSettings::set_showSReadToggleInDrawer(bool val)
{
void AyuGramSettings::set_showSReadToggleInDrawer(bool val) {
showSReadToggleInDrawer = val;
}
void AyuGramSettings::set_showGhostToggleInDrawer(bool val)
{
void AyuGramSettings::set_showGhostToggleInDrawer(bool val) {
showGhostToggleInDrawer = val;
}
void AyuGramSettings::set_showStreamerToggleInDrawer(bool val)
{
void AyuGramSettings::set_showStreamerToggleInDrawer(bool val) {
showStreamerToggleInDrawer = val;
}
void AyuGramSettings::set_showGhostToggleInTray(bool val)
{
void AyuGramSettings::set_showGhostToggleInTray(bool val) {
showGhostToggleInTray = val;
}
void AyuGramSettings::set_showStreamerToggleInTray(bool val)
{
void AyuGramSettings::set_showStreamerToggleInTray(bool val) {
showStreamerToggleInTray = val;
}
void AyuGramSettings::set_mainFont(QString val)
{
void AyuGramSettings::set_mainFont(QString val) {
mainFont = val;
}
void AyuGramSettings::set_monoFont(QString val)
{
void AyuGramSettings::set_monoFont(QString val) {
monoFont = val;
}
void AyuGramSettings::set_showPeerId(int val)
{
void AyuGramSettings::set_showPeerId(int val) {
showPeerId = val;
showPeerIdReactive = val;
}
void AyuGramSettings::set_hideNotificationCounters(bool val)
{
void AyuGramSettings::set_hideNotificationCounters(bool val) {
hideNotificationCounters = val;
}
void AyuGramSettings::set_hideAllChatsFolder(bool val)
{
void AyuGramSettings::set_hideAllChatsFolder(bool val) {
hideAllChatsFolder = val;
}
void AyuGramSettings::set_showMessageSeconds(bool val)
{
void AyuGramSettings::set_showMessageSeconds(bool val) {
showMessageSeconds = val;
}
void AyuGramSettings::set_stickerConfirmation(bool val)
{
void AyuGramSettings::set_showMessageShot(bool val) {
showMessageShot = val;
}
void AyuGramSettings::set_stickerConfirmation(bool val) {
stickerConfirmation = val;
}
void AyuGramSettings::set_gifConfirmation(bool val)
{
void AyuGramSettings::set_gifConfirmation(bool val) {
gifConfirmation = val;
}
void AyuGramSettings::set_voiceConfirmation(bool val)
{
void AyuGramSettings::set_voiceConfirmation(bool val) {
voiceConfirmation = val;
}
bool get_ghostModeEnabled()
{
bool get_ghostModeEnabled() {
return ghostModeEnabled.current();
}
rpl::producer<QString> get_deletedMarkReactive()
{
rpl::producer<QString> get_deletedMarkReactive() {
return deletedMarkReactive.value();
}
rpl::producer<QString> get_editedMarkReactive()
{
rpl::producer<QString> get_editedMarkReactive() {
return editedMarkReactive.value();
}
rpl::producer<int> get_showPeerIdReactive()
{
rpl::producer<int> get_showPeerIdReactive() {
return showPeerIdReactive.value();
}
rpl::producer<bool> get_ghostModeEnabledReactive()
{
rpl::producer<bool> get_ghostModeEnabledReactive() {
return ghostModeEnabled.value();
}
+6 -80
View File
@@ -3,95 +3,19 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#pragma once
#include "lang_auto.h"
#include "ayu/libs/json.hpp"
#include "ayu/libs/json_ext.hpp"
#include "ayu/ui/ayu_assets.h"
#include "rpl/producer.h"
namespace AyuSettings
{
namespace AyuSettings {
class AyuGramSettings
{
public:
AyuGramSettings()
{
// ~ Ghost essentials
sendReadMessages = true;
sendReadStories = true;
sendOnlinePackets = true;
sendUploadProgress = true;
sendOfflinePacketAfterOnline = false;
markReadAfterSend = true;
markReadAfterReaction = true;
markReadAfterPoll = true;
useScheduledMessages = false;
// ~ Message edits & deletion history
saveDeletedMessages = false;
saveMessagesHistory = true;
// ~ QoL toggles
disableAds = true;
disableStories = false;
collapseSimilarChannels = true;
hideSimilarChannels = false;
uploadSpeedBoost = false;
disableNotificationsDelay = false;
localPremium = false;
copyUsernameAsLink = true;
// ~ Customization
appIcon = AyuAssets::DEFAULT_ICON;
simpleQuotesAndReplies = true;
deletedMark = "🧹";
editedMark = tr::lng_edited(tr::now);
recentStickersCount = 50;
// context menu items
// 0 - hide
// 1 - show normally
// 2 - show with SHIFT or CTRL pressed
showReactionsPanelInContextMenu = 1;
showViewsPanelInContextMenu = 1;
showHideMessageInContextMenu = 0;
showUserMessagesInContextMenu = 2;
showMessageDetailsInContextMenu = 2;
showLReadToggleInDrawer = true;
showSReadToggleInDrawer = true;
showGhostToggleInDrawer = true;
showStreamerToggleInDrawer = false;
showGhostToggleInTray = true;
showStreamerToggleInTray = false;
mainFont = "";
monoFont = "";
hideNotificationCounters = false;
hideAllChatsFolder = false;
/*
* showPeerId = 0 means no ID shown
* showPeerId = 1 means ID shown as for Telegram API devs
* showPeerId = 2 means ID shown as for Bot API devs (-100)
*/
showPeerId = 2;
showMessageSeconds = false;
// ~ Confirmations
stickerConfirmation = false;
gifConfirmation = false;
voiceConfirmation = false;
}
AyuGramSettings();
bool sendReadMessages;
bool sendReadStories;
@@ -146,12 +70,12 @@ public:
int showPeerId;
bool showMessageSeconds;
bool showMessageShot;
bool stickerConfirmation;
bool gifConfirmation;
bool voiceConfirmation;
public:
void set_sendReadMessages(bool val);
void set_sendReadStories(bool val);
void set_sendOnlinePackets(bool val);
@@ -207,6 +131,7 @@ public:
void set_showPeerId(int val);
void set_showMessageSeconds(bool val);
void set_showMessageShot(bool val);
void set_stickerConfirmation(bool val);
void set_gifConfirmation(bool val);
@@ -256,6 +181,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(
hideAllChatsFolder,
showPeerId,
showMessageSeconds,
showMessageShot,
stickerConfirmation,
gifConfirmation,
voiceConfirmation
+8 -13
View File
@@ -3,35 +3,30 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#include "ayu_state.h"
namespace AyuState
{
namespace AyuState {
std::unordered_map<PeerId, std::unordered_set<MsgId>> hiddenMessages;
void hide(PeerId peerId, MsgId messageId)
{
void hide(PeerId peerId, MsgId messageId) {
hiddenMessages[peerId].insert(messageId);
}
void hide(not_null<HistoryItem *> item)
{
void hide(not_null<HistoryItem*> item) {
hide(item->history()->peer->id, item->id);
}
bool isHidden(PeerId peerId, MsgId messageId)
{
auto it = hiddenMessages.find(peerId);
bool isHidden(PeerId peerId, MsgId messageId) {
const auto it = hiddenMessages.find(peerId);
if (it != hiddenMessages.end()) {
return it->second.find(messageId) != it->second.end();
return it->second.contains(messageId);
}
return false;
}
bool isHidden(not_null<HistoryItem *> item)
{
bool isHidden(not_null<HistoryItem*> item) {
return isHidden(item->history()->peer->id, item->id);
}
+4 -7
View File
@@ -3,20 +3,17 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#pragma once
#include "ayu_settings.h"
#include "history/history.h"
#include "history/history_item.h"
namespace AyuState
{
namespace AyuState {
void hide(PeerId peerId, MsgId messageId);
void hide(not_null<HistoryItem *> item);
void hide(not_null<HistoryItem*> item);
bool isHidden(PeerId peerId, MsgId messageId);
bool isHidden(not_null<HistoryItem *> item);
bool isHidden(not_null<HistoryItem*> item);
}
+54 -18
View File
@@ -3,28 +3,30 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#include "ayu/ayu_url_handlers.h"
#include "base/qthelp_url.h"
#include "lang_auto.h"
#include "mainwindow.h"
#include "ui/boxes/confirm_box.h"
#include "ayu/utils/telegram_helpers.h"
#include "boxes/abstract_box.h"
#include "core/application.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "ui/boxes/confirm_box.h"
namespace AyuUrlHandlers
{
#include <QDesktopServices>
#include "main/main_session.h"
namespace AyuUrlHandlers {
bool ResolveUser(
Window::SessionController *controller,
const Match &match,
const QVariant &context)
{
const QVariant &context) {
if (!controller) {
return false;
}
@@ -41,16 +43,19 @@ bool ResolveUser(
return true;
}
searchById(userId, &controller->session(), false, [=](const QString &title, UserData *data)
{
if (data) {
controller->showPeerInfo(data);
return;
}
searchById(userId,
&controller->session(),
false,
[=](const QString &title, UserData *data)
{
if (data) {
controller->showPeerInfo(data);
return;
}
Core::App().hideMediaView();
Ui::show(Ui::MakeInformBox(tr::ayu_UserNotFoundMessage()));
});
Core::App().hideMediaView();
Ui::show(Ui::MakeInformBox(tr::ayu_UserNotFoundMessage()));
});
return true;
}
@@ -58,8 +63,7 @@ bool ResolveUser(
bool HandleAyu(
Window::SessionController *controller,
const Match &match,
const QVariant &context)
{
const QVariant &context) {
if (!controller) {
return false;
}
@@ -67,4 +71,36 @@ bool HandleAyu(
return true;
}
}
bool TryHandleSpotify(const QString &url) {
if (!url.contains("spotify.com")) {
return false;
}
// docs on their url scheme
// https://www.iana.org/assignments/uri-schemes/prov/spotify
using namespace qthelp;
const auto matchOptions = RegExOption::CaseInsensitive;
// https://regex101.com/r/l4Ogzf/2
const auto match = regex_match(
u"^(https?:\\/\\/)?([a-zA-Z0-9_]+)\\.spotify\\.com\\/(?<type>track|album|artist|user|playlist)\\/(?<identifier>[a-zA-Z0-9_\\/]+?)((\\?si=.+)?)$"_q,
url,
matchOptions);
if (match) {
const auto type = match->captured("type").toLower();
const auto identifier = match->captured("identifier").replace("/", ":");
// '/' -> ':' for links like:
// https://open.spotify.com/user/1185903410/playlist/6YAnJeVC7tgOiocOG23Dd
// so it'll look like
// spotify:user:1185903410:playlist:6YAnJeVC7tgOiocOG23Dd
const auto res = QString("spotify:%1:%2").arg(type).arg(identifier);
return QDesktopServices::openUrl(QUrl(res));
}
return false;
}
}
+6 -5
View File
@@ -3,14 +3,13 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#pragma once
#include "window/window_session_controller.h"
#include "base/qthelp_regex.h"
#include "window/window_session_controller.h"
namespace AyuUrlHandlers
{
namespace AyuUrlHandlers {
using Match = qthelp::RegularExpressionMatch;
@@ -24,4 +23,6 @@ bool HandleAyu(
const Match &match,
const QVariant &context);
}
bool TryHandleSpotify(const QString &url);
}
+84
View File
@@ -0,0 +1,84 @@
// This is the source code of AyuGram for Desktop.
//
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2024
#include "ayu_worker.h"
#include "apiwrap.h"
#include "ayu_settings.h"
#include "base/unixtime.h"
#include "core/application.h"
#include "data/data_user.h"
#include "data/entities.h"
#include "main/main_account.h"
#include "main/main_domain.h"
#include "main/main_session.h"
namespace AyuWorker {
std::unordered_map<ID, bool> state;
void markAsOnline(not_null<Main::Session*> session) {
state[session->userId().bare] = true;
}
void lateInit() {
for (const auto &[index, account] : Core::App().domain().accounts()) {
if (const auto session = account->maybeSession()) {
const auto id = session->userId().bare;
state[id] = true;
}
}
}
void runOnce() {
if (!Core::App().domain().started()) {
return;
}
if (state.empty()) {
lateInit();
}
const auto settings = &AyuSettings::getInstance();
if (!settings->sendOfflinePacketAfterOnline) {
return;
}
const auto t = base::unixtime::now();
const auto invalidateAll = cOtherOnline() >= t;
for (const auto &[index, account] : Core::App().domain().accounts()) {
if (const auto session = account->maybeSession()) {
const auto id = session->userId().bare;
if (!state.contains(id)) {
state[id] = true; // newly added account, I suppose
}
if (invalidateAll || state[id] || session->user()->lastseen().isOnline(t)) {
session->api().request(MTPaccount_UpdateStatus(
MTP_bool(true)
)).send();
state[id] = false;
LOG(("[AyuGram] Sent offline for account with uid %1, invalidate %2").arg(id).arg(invalidateAll));
}
}
}
}
[[noreturn]] void loop() {
while (true) {
runOnce();
std::this_thread::sleep_for(std::chrono::seconds(3));
}
}
void initialize() {
std::thread t(loop);
t.detach();
}
}
+16
View File
@@ -0,0 +1,16 @@
// This is the source code of AyuGram for Desktop.
//
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2024
#pragma once
#include "window/window_session_controller.h"
namespace AyuWorker {
void markAsOnline(not_null<Main::Session*> session);
void initialize();
}
@@ -0,0 +1,210 @@
// This is the source code of AyuGram for Desktop.
//
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2024
#include "ayu_database.h"
#include <ranges>
#include "entities.h"
#include "ayu/libs/sqlite/sqlite_orm.h"
#include "base/unixtime.h"
using namespace sqlite_orm;
auto storage = make_storage(
"./tdata/ayudata.db",
make_table(
"DeletedMessage",
make_column("fakeId", &DeletedMessage::fakeId, primary_key().autoincrement()),
make_column("userId", &DeletedMessage::userId),
make_column("dialogId", &DeletedMessage::dialogId),
make_column("groupedId", &DeletedMessage::groupedId),
make_column("peerId", &DeletedMessage::peerId),
make_column("fromId", &DeletedMessage::fromId),
make_column("topicId", &DeletedMessage::topicId),
make_column("messageId", &DeletedMessage::messageId),
make_column("date", &DeletedMessage::date),
make_column("flags", &DeletedMessage::flags),
make_column("editDate", &DeletedMessage::editDate),
make_column("views", &DeletedMessage::views),
make_column("fwdFlags", &DeletedMessage::fwdFlags),
make_column("fwdFromId", &DeletedMessage::fwdFromId),
make_column("fwdName", &DeletedMessage::fwdName),
make_column("fwdDate", &DeletedMessage::fwdDate),
make_column("fwdPostAuthor", &DeletedMessage::fwdPostAuthor),
make_column("replyFlags", &DeletedMessage::replyFlags),
make_column("replyMessageId", &DeletedMessage::replyMessageId),
make_column("replyPeerId", &DeletedMessage::replyPeerId),
make_column("replyTopId", &DeletedMessage::replyTopId),
make_column("replyForumTopic", &DeletedMessage::replyForumTopic),
make_column("replySerialized", &DeletedMessage::replySerialized),
make_column("entityCreateDate", &DeletedMessage::entityCreateDate),
make_column("text", &DeletedMessage::text),
make_column("textEntities", &DeletedMessage::textEntities),
make_column("mediaPath", &DeletedMessage::mediaPath),
make_column("hqThumbPath", &DeletedMessage::hqThumbPath),
make_column("documentType", &DeletedMessage::documentType),
make_column("documentSerialized", &DeletedMessage::documentSerialized),
make_column("thumbsSerialized", &DeletedMessage::thumbsSerialized),
make_column("documentAttributesSerialized", &DeletedMessage::documentAttributesSerialized),
make_column("mimeType", &DeletedMessage::mimeType)
),
make_table(
"EditedMessage",
make_column("fakeId", &EditedMessage::fakeId, primary_key().autoincrement()),
make_column("userId", &EditedMessage::userId),
make_column("dialogId", &EditedMessage::dialogId),
make_column("groupedId", &EditedMessage::groupedId),
make_column("peerId", &EditedMessage::peerId),
make_column("fromId", &EditedMessage::fromId),
make_column("topicId", &EditedMessage::topicId),
make_column("messageId", &EditedMessage::messageId),
make_column("date", &EditedMessage::date),
make_column("flags", &EditedMessage::flags),
make_column("editDate", &EditedMessage::editDate),
make_column("views", &EditedMessage::views),
make_column("fwdFlags", &EditedMessage::fwdFlags),
make_column("fwdFromId", &EditedMessage::fwdFromId),
make_column("fwdName", &EditedMessage::fwdName),
make_column("fwdDate", &EditedMessage::fwdDate),
make_column("fwdPostAuthor", &EditedMessage::fwdPostAuthor),
make_column("replyFlags", &EditedMessage::replyFlags),
make_column("replyMessageId", &EditedMessage::replyMessageId),
make_column("replyPeerId", &EditedMessage::replyPeerId),
make_column("replyTopId", &EditedMessage::replyTopId),
make_column("replyForumTopic", &EditedMessage::replyForumTopic),
make_column("replySerialized", &EditedMessage::replySerialized),
make_column("entityCreateDate", &EditedMessage::entityCreateDate),
make_column("text", &EditedMessage::text),
make_column("textEntities", &EditedMessage::textEntities),
make_column("mediaPath", &EditedMessage::mediaPath),
make_column("hqThumbPath", &EditedMessage::hqThumbPath),
make_column("documentType", &EditedMessage::documentType),
make_column("documentSerialized", &EditedMessage::documentSerialized),
make_column("thumbsSerialized", &EditedMessage::thumbsSerialized),
make_column("documentAttributesSerialized", &EditedMessage::documentAttributesSerialized),
make_column("mimeType", &EditedMessage::mimeType)
),
make_table(
"DeletedDialog",
make_column("fakeId", &DeletedDialog::fakeId, primary_key().autoincrement()),
make_column("userId", &DeletedDialog::userId),
make_column("dialogId", &DeletedDialog::dialogId),
make_column("peerId", &DeletedDialog::peerId),
make_column("folderId", &DeletedDialog::folderId),
make_column("topMessage", &DeletedDialog::topMessage),
make_column("lastMessageDate", &DeletedDialog::lastMessageDate),
make_column("flags", &DeletedDialog::flags),
make_column("entityCreateDate", &DeletedDialog::entityCreateDate)
),
make_table(
"RegexFilter",
make_column("id", &RegexFilter::id),
make_column("text", &RegexFilter::text),
make_column("enabled", &RegexFilter::enabled),
make_column("caseInsensitive", &RegexFilter::caseInsensitive),
make_column("dialogId", &RegexFilter::dialogId)
),
make_table(
"RegexFilterGlobalExclusion",
make_column("fakeId", &RegexFilterGlobalExclusion::fakeId, primary_key().autoincrement()),
make_column("dialogId", &RegexFilterGlobalExclusion::dialogId),
make_column("filterId", &RegexFilterGlobalExclusion::filterId)
),
make_table(
"SpyMessageRead",
make_column("fakeId", &SpyMessageRead::fakeId, primary_key().autoincrement()),
make_column("userId", &SpyMessageRead::userId),
make_column("dialogId", &SpyMessageRead::dialogId),
make_column("messageId", &SpyMessageRead::messageId),
make_column("entityCreateDate", &SpyMessageRead::entityCreateDate)
),
make_table(
"SpyMessageContentsRead",
make_column("fakeId", &SpyMessageContentsRead::fakeId, primary_key().autoincrement()),
make_column("userId", &SpyMessageContentsRead::userId),
make_column("dialogId", &SpyMessageContentsRead::dialogId),
make_column("messageId", &SpyMessageContentsRead::messageId),
make_column("entityCreateDate", &SpyMessageContentsRead::entityCreateDate)
)
);
namespace AyuDatabase {
void moveCurrentDatabase() {
auto time = base::unixtime::now();
if (std::filesystem::exists("./tdata/ayudata.db")) {
std::filesystem::rename("./tdata/ayudata.db", QString("./tdata/ayudata_%1.db").arg(time).toStdString());
}
if (std::filesystem::exists("./tdata/ayudata.db-shm")) {
std::filesystem::rename("./tdata/ayudata.db-shm",
QString("./tdata/ayudata_%1.db-shm").arg(time).toStdString());
}
if (std::filesystem::exists("./tdata/ayudata.db-wal")) {
std::filesystem::rename("./tdata/ayudata.db-wal",
QString("./tdata/ayudata_%1.db-wal").arg(time).toStdString());
}
}
void initialize() {
const auto res = storage.sync_schema_simulate(true);
auto movePrevious = false;
for (const auto val : res | std::views::values) {
if (val == sync_schema_result::dropped_and_recreated) {
movePrevious = true;
break;
}
}
if (movePrevious) {
moveCurrentDatabase();
}
try {
storage.sync_schema(true);
} catch (...) {
LOG(("Failed to sync database schema"));
LOG(("Moving current database just in case"));
moveCurrentDatabase();
storage.sync_schema();
}
storage.begin_transaction();
storage.commit();
}
void addEditedMessage(const EditedMessage &message) {
storage.begin_transaction();
storage.insert(message);
storage.commit();
}
std::vector<EditedMessage> getEditedMessages(ID userId, ID dialogId, ID messageId) {
return storage.get_all<EditedMessage>(
where(
c(&EditedMessage::userId) == userId and
c(&EditedMessage::dialogId) == dialogId and
c(&EditedMessage::messageId) == messageId
)
);
}
bool hasRevisions(ID userId, ID dialogId, ID messageId) {
return storage.count<EditedMessage>(
where(
c(&EditedMessage::userId) == userId and
c(&EditedMessage::dialogId) == dialogId and
c(&EditedMessage::messageId) == messageId
)
) > 0;
}
}
@@ -3,15 +3,12 @@
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
// Copyright @Radolyn, 2024
#pragma once
#include "entities.h"
#include "history/history.h"
#include "history/history_item.h"
namespace AyuDatabase
{
namespace AyuDatabase {
void initialize();

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