Compare commits

...

686 Commits

Author SHA1 Message Date
John Preston
8f26a24f78 Beta version 6.2.5.
- New profile pages design.
- Qt 6.10 on Linux.
2025-10-29 14:34:51 +04:00
John Preston
6abd4bae58 Fix build with Qt 6 on Windows. 2025-10-29 14:34:51 +04:00
John Preston
f8844750f5 Fix build with Xcode. 2025-10-29 14:34:51 +04:00
John Preston
de984d44ac Fix build on Windows. 2025-10-29 14:34:51 +04:00
23rd
babcefeb23 Returned button for reaction reporting to profile info. 2025-10-29 13:15:05 +03:00
23rd
71a55290ab Removed display of empty placeholder for gifts when gifts are loaded. 2025-10-28 20:38:26 +03:00
23rd
8ef0b88633 Slightly improved position of status in profile top bar. 2025-10-28 14:08:11 +03:00
23rd
f9c3415aa7 Added handler of pinned gifts order event to profile top bar. 2025-10-28 13:53:41 +03:00
23rd
deb7d5914f Fixed api ability to toggle pinned star gifts. 2025-10-28 13:53:41 +03:00
23rd
469e4394bd Attempted to improve flexible scroll in some cases. 2025-10-28 13:53:41 +03:00
23rd
1bcf9dda0a Added placeholder for empty list of self gifts to edit peer color box. 2025-10-28 13:53:41 +03:00
23rd
02fafde09d Added correspond premium feature premium box in edit peer color box. 2025-10-28 13:53:41 +03:00
23rd
de5e1b3452 Added boost hint below preview in edit peer color box for groups. 2025-10-28 13:53:41 +03:00
23rd
4381db691b Slightly improved color of action buttons in profile top bar. 2025-10-28 13:53:41 +03:00
23rd
bd879262c2 Added limit for count of actions to profile top bar. 2025-10-28 13:53:41 +03:00
23rd
da88b4c475 Centered status with all elements as unified group in profile top bar. 2025-10-28 13:53:41 +03:00
23rd
276a18cddd Returned close button to profile top bar in Side wrap. 2025-10-28 13:53:41 +03:00
23rd
6eb54e55a5 Improved style of verified check in profile top bar. 2025-10-28 13:53:41 +03:00
23rd
e7fa330215 Split verified check icon. 2025-10-28 13:53:41 +03:00
23rd
27ed160a40 Added handler for palette changed event to profile top bar. 2025-10-28 13:53:40 +03:00
23rd
180b614c86 Improved foreground of pattern emoji in profile top bar. 2025-10-28 13:53:40 +03:00
23rd
e2e6b64632 Improved z-order of main button in edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
be46aacbe5 Moved up button for emoji status in edit peer color box for channels. 2025-10-28 13:53:40 +03:00
23rd
3bd46f3415 Added about labels about profile colors to edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
7e6e2960bd Added ability to edit profile color to edit peer color box for channels. 2025-10-28 13:53:40 +03:00
23rd
9df4377450 Improved ability set emoji status locally in profile top bar. 2025-10-28 13:53:40 +03:00
23rd
294ab035f0 Moved out function for tabs in edit peer color box to anon namespace. 2025-10-28 13:53:40 +03:00
23rd
f96554e271 Moved out top bar preview creation to function in edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
2c1fdbe55b Added ability to retrieve required boost level for peer colors to api. 2025-10-28 13:53:40 +03:00
23rd
b5bce29514 Added about text for profile to edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
97557b85d9 Added ability to apply profile style to edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
8a5cc70d9b Added ability to set unique gift from edit peer color box for profile. 2025-10-28 13:53:40 +03:00
23rd
d5075891b2 Added ability to wear unique gift locally to profile top bar. 2025-10-28 13:53:40 +03:00
23rd
4df778f4e9 Added always display of story outline while preview to profile top bar. 2025-10-28 13:53:40 +03:00
23rd
3cda66f1f3 Added reset button for profile to edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
e0991d9376 Added simple emoji pattern selector for profile to edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
8c94742070 Added ability to set emoji pattern locally to profile top bar. 2025-10-28 13:53:40 +03:00
23rd
419b2b02bc Added ability to set bg locally to profile top bar. 2025-10-28 13:53:40 +03:00
23rd
b4998527dd Added simple profile top bar preview to edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
8ac8598b20 Replaced controller in descriptor for profile top bar. 2025-10-28 13:53:40 +03:00
23rd
f7ddf8b024 Added ability to provide custom wrap value to profile top bar. 2025-10-28 13:53:40 +03:00
23rd
18f1563829 Added ability to provide custom key to profile top bar. 2025-10-28 13:53:40 +03:00
23rd
20ba35c0a7 Added simple color selector for profile to edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
de4764c1c7 Added simple mode for profiles to color selector. 2025-10-28 13:53:40 +03:00
23rd
31bb8a3ac5 Extracted ColorSelector class to td_ui. 2025-10-28 13:53:40 +03:00
23rd
e0156abe7c Added ability to use color sample for peer profile color. 2025-10-28 13:53:40 +03:00
23rd
7d02e92843 Extracted ColorSample class to td_ui. 2025-10-28 13:53:40 +03:00
23rd
80aef75ea5 Added ability to retrieve color data from index for profile to api. 2025-10-28 13:53:40 +03:00
23rd
c940062787 Added initial sections for tabs to edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
4b3b9ad140 Added simple tab selector to edit peer color box. 2025-10-28 13:53:40 +03:00
23rd
1bb2efc346 Split logic of box for edit peer color and inner of box. 2025-10-28 13:53:40 +03:00
23rd
0b699b45b1 Centered title with all badges as unified group in profile top bar. 2025-10-28 13:53:40 +03:00
23rd
3c0487db81 Fixed status position on change in profile top bar. 2025-10-28 13:53:40 +03:00
23rd
f62869e4df Fixed link color for status with profile color in profile top bar. 2025-10-28 13:53:40 +03:00
23rd
fce459f612 Added initial support of solo pattern emoji to profile top bar. 2025-10-28 13:53:40 +03:00
23rd
6a003114db Added single-loop mode for gift animations to top bar in Side wrap. 2025-10-28 13:53:40 +03:00
23rd
39ed5cab0d Added recreation of action buttons in profile top bar on full receiving. 2025-10-28 13:53:40 +03:00
23rd
4b67c8f4bb Set fixed position of mute menu in profile top bar. 2025-10-28 13:53:40 +03:00
23rd
65604add65 Removed action buttons for notification user from profile top bar. 2025-10-28 13:53:40 +03:00
23rd
3e69f65d1c Moved menu toggle from top to action button in profile top bar. 2025-10-28 13:53:40 +03:00
23rd
0b26dbbc9e Added middle elision to action buttons in profile top bar. 2025-10-28 13:53:40 +03:00
23rd
152d943f3d Fixed overridden colors for lottie icon in action buttons from top bar. 2025-10-28 13:53:40 +03:00
23rd
7fffd1d318 Added support of profile color to profile top bar for badges. 2025-10-28 13:53:40 +03:00
23rd
5d875341f4 Added support of profile color to profile top bar for stories outline. 2025-10-28 13:53:40 +03:00
23rd
61dbd4c4c2 Fixed possible crash from profile top bar in groups. 2025-10-28 13:53:40 +03:00
23rd
5f42011c7b Added support of profile color to top bar for gradient backgrounds. 2025-10-28 13:53:40 +03:00
23rd
7e56174ba9 Added support of profile color to profile top bar for solid backgrounds. 2025-10-28 13:53:40 +03:00
23rd
0a83b3f58c Added convenient method to resolve profile color by peer. 2025-10-28 13:53:40 +03:00
23rd
71fec23311 Added applying of profile colors to peers. 2025-10-28 13:53:40 +03:00
23rd
2ba3035a13 Added new data change flag for profile colors. 2025-10-28 13:53:40 +03:00
23rd
7a653a8e1b Added initial support of profile colors to peers. 2025-10-28 13:53:40 +03:00
23rd
a93b32fb53 Added initial api support of profile colors. 2025-10-28 13:53:40 +03:00
23rd
d82cc350c0 Added initial data structures for profile colors. 2025-10-28 13:53:39 +03:00
23rd
5997a7d48a Replaced color calculation from int with single function. 2025-10-28 13:53:39 +03:00
23rd
7641fb6712 Converted ABGR to RGB in fireworks module. 2025-10-28 13:53:39 +03:00
23rd
dfaf9b9d43 Fixed position of right sublabel for notes in profile section. 2025-10-28 13:53:39 +03:00
23rd
6147b0eec0 Removed main buttons from profile sections. 2025-10-28 13:53:39 +03:00
23rd
2eefef3649 Reduced left padding for info labels in profile section. 2025-10-28 13:53:39 +03:00
23rd
1905a67e6c Removed mute toggle from profile section. 2025-10-28 13:53:39 +03:00
23rd
38ab18f6fb Moved verification label under info in profile. 2025-10-28 13:53:39 +03:00
23rd
ddcc20c8a7 Removed actions button from profile top bar in section for stories. 2025-10-28 13:53:39 +03:00
23rd
f3c6763058 Removed additional divider after profile top bar. 2025-10-28 13:53:39 +03:00
23rd
91a11d2e74 Moved out some calculations from paint event in music button. 2025-10-28 13:53:39 +03:00
23rd
fb880481a4 Replaced custom music data formatting with common song name formatter. 2025-10-28 13:53:39 +03:00
23rd
9e6703f02f Slightly improved style of top bar in profile. 2025-10-28 13:53:39 +03:00
23rd
da5435d1cb Added leave button to action buttons in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
db0726364b Added report button to action buttons in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
944b2de852 Added join button to action buttons in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
53927502af Added gift button to action buttons in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
828d8ea051 Added discuss button to action buttons in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
f2e345b39f Added edit button to profile top bar for stories section. 2025-10-28 13:53:39 +03:00
23rd
6f625a899c Added profile top bar to self stories section. 2025-10-28 13:53:39 +03:00
23rd
28bc8c3bf3 Moved out creation of flexible scroll into info content widget. 2025-10-28 13:53:39 +03:00
23rd
ef30949943 Moved out creation of smooth scroll for info profile top bar to helper. 2025-10-28 13:53:39 +03:00
23rd
4f888bc418 Added ability to click on pinned gifts from profile top bar. 2025-10-28 13:53:39 +03:00
23rd
34caf6967e Slightly optimized calculating of userpic geometry in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
a728c783d9 Removed music button from cover. 2025-10-28 13:53:39 +03:00
23rd
934d232653 Added ability to set custom bg color to music button in profile. 2025-10-28 13:53:39 +03:00
23rd
4fbc7771c9 Removed cover from profile. 2025-10-28 13:53:39 +03:00
23rd
571ab422bf Moved out music button from cover to inner widget for profile. 2025-10-28 13:53:39 +03:00
23rd
9592f4de6e Added center alignment to music button in profile. 2025-10-28 13:53:39 +03:00
23rd
c126d99fd0 Fixed colorized online text in status from profile top bar. 2025-10-28 13:53:39 +03:00
23rd
11c8a272ec Improved processing of hiding all collectible things in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
f7170b8c50 Added initial hiding animation for gifts in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
9ce28f4cb7 Added offset to background in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
522a457d98 Fixed background in profile top bar on width resizing. 2025-10-28 13:53:39 +03:00
23rd
9e9ffaa27b Added menu to userpic when stories are presented in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
9ab4a8ab6e Added stories support to profile top bar. 2025-10-28 13:53:39 +03:00
23rd
5c784081c2 Replaced top call button with action button in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
9c84c0afe9 Improved adaptive colors in top buttons from profile top bar. 2025-10-28 13:53:39 +03:00
23rd
accc5e8b10 Added adaptive color to stars rating in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
1e0c71a411 Added simple appearing animation to pinned gifts in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
663687884b Added adaptive color to badges in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
ade2bdcafd Added ability to set overridden style to profile badges. 2025-10-28 13:53:39 +03:00
23rd
9e01e64f63 Fixed possible crash from profile badge tooltip. 2025-10-28 13:53:39 +03:00
23rd
7cc0fd879d Added adaptive color to top buttons in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
42bd835800 Added adaptive background color to action buttons in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
ef7b5cb8e7 Added initial few action buttons to profile top bar. 2025-10-28 13:53:39 +03:00
23rd
2651d79b63 Added ability to convert action button to toggle in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
ddc12c3f71 Added ability to pass static icon to action button in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
9c3c2e9fa7 Divided scrolling process of profile top bar on different steps. 2025-10-28 13:53:39 +03:00
23rd
564f9ac38d Added action button for profile top bar as separated class. 2025-10-28 13:53:39 +03:00
23rd
1b49bd0843 Adjusted some styles for profile top bar. 2025-10-28 13:53:39 +03:00
23rd
831d79d912 Added simple container that fits within certain width. 2025-10-28 13:53:39 +03:00
23rd
d61f809cca Added gradient background to recent gifts in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
130176fd7e Replaced raw DocumentId with full star gift data in api recent gifts. 2025-10-28 13:53:39 +03:00
23rd
1ea9be9877 Fixed labels position in profile top bar with back button. 2025-10-28 13:53:39 +03:00
23rd
e3b56aa05b Added initial support of pinned gifts in profile top bar. 2025-10-28 13:53:39 +03:00
23rd
4f4195c88a Added ability to api request of last pinned gifts for peer profile. 2025-10-28 13:53:39 +03:00
23rd
1d9a8af174 Added animated emoji pattern to profile top bar. 2025-10-28 13:53:39 +03:00
23rd
8b1e7e1fa9 Added initial static emoji pattern to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
eeb0b62bfa Moved out pattern points draw for unique gifts to separated class. 2025-10-28 13:53:38 +03:00
23rd
0a114bbe4a Added initial support of collectible background to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
474458e4c3 Moved out gradient for unique gifts to separated class. 2025-10-28 13:53:38 +03:00
23rd
c6b73631d8 Added support of topic icons to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
bce318c48e Added support of video userpic to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
9e4ac1c835 Created simple class for video userpic processing. 2025-10-28 13:53:38 +03:00
23rd
53933db077 Added userpic for monoforum broadcasts to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
4156d8e908 Added ability to open peer photo to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
6491d83085 Added members click callback to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
6259d30e2b Added online members count to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
3ee7a0dc16 Added badge gift tooltip to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
43d8723e35 Moved out badge gift tooltip from info profile cover to separated class. 2025-10-28 13:53:38 +03:00
23rd
d59ab17ac5 Added last seen button and rating to status in profile top bar. 2025-10-28 13:53:38 +03:00
23rd
d26cda097f Added ability to set opacity to stars rating from info profile cover. 2025-10-28 13:53:38 +03:00
23rd
6daa58b596 Improved width processing of title in profile top bar. 2025-10-28 13:53:38 +03:00
23rd
d0920d9eb9 Added calls button to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
fbd353501b Added toggle menu button to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
9876aa64e0 Moved out close and back buttons within profile top bar class. 2025-10-28 13:53:38 +03:00
23rd
b8ccf7b3d4 Replaced args for profile top bar with descriptor. 2025-10-28 13:53:38 +03:00
23rd
c15b5914b2 Added simple userpic to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
73aebb8890 Added initial implementation of smooth scroll to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
f9270710be Added initial position processing of title in profile top bar. 2025-10-28 13:53:38 +03:00
23rd
0b63abf5b4 Added initial status to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
51ae4af83e Extracted peer status label logic into separate StatusLabel class. 2025-10-28 13:53:38 +03:00
23rd
4832982988 Added initial title to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
b4d49715dc Provided peer to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
0de7b4eb39 Added back button to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
3e88451ea8 Added close button to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
5468fde492 Set profile top bar as flexible. 2025-10-28 13:53:38 +03:00
23rd
f17e13cad0 Added ability to paint round edges to profile top bar. 2025-10-28 13:53:38 +03:00
23rd
f511449273 Added dummy new class for top bar within info profile. 2025-10-28 13:53:38 +03:00
23rd
bbe65e212a Added initial ability to create pinned widgets to info profile. 2025-10-28 13:53:38 +03:00
ilya-fedin
5ebd0df15f Update patches on Linux 2025-10-25 20:56:56 +04:00
Ilya Fedin
66a34bcb89 Fix Docker image build 2025-10-24 15:53:58 +04:00
Sv. Lockal
acad1d4175 Fix compilation with Clang-21 + libstdc++-16
.emplace() can only be used on constructible objects, while private
nested struct is not considered as constructible due to access control.

Closes #29939

Signed-off-by: Sv. Lockal <lockalsash@gmail.com>
2025-10-24 07:15:19 +04:00
Ilya Fedin
716fade52a Remove unused yasm dependency from macOS packaged action
It's not used since openh264 is not built as part of tg_owt
2025-10-23 11:41:39 +04:00
Ilya Fedin
3b9312d9ac Install only really needed parts of Qt in macOS packaged action 2025-10-23 11:41:39 +04:00
Ilya Fedin
f87d072c79 Force bundled abseil-cpp for WebRTC in macOS packaged action
It fails to build with the one from brew due to a change in the API of new abseil-cpp versions
2025-10-23 11:08:21 +04:00
John Preston
b61724019a Update patches revision in snapcraft. 2025-10-23 10:56:01 +04:00
John Preston
3ffdb1ee56 Fix build on Linux. 2025-10-23 10:29:24 +04:00
Ilya Fedin
5fbf280e4a Combine startUrls and sendPaths
This commit allows to handle multiple URLs of all types as positional arguments simultaneously:
* tg:// links
* tonsite:// links
* interpret:// file paths
* generic file paths (to share files)

This allows to Drag'n'Drop files to the Telegram shortcut/binary.
2025-10-23 10:23:53 +04:00
Ilya Fedin
f787e0fa1d Allow to pass URLs without --
This allows to make tdesktop as a URL handler with generic file dialog in e.g. Firefox (previously the window was opening but no URL handled)
2025-10-23 10:23:53 +04:00
23rd
0d33b92d24 Added ability to edit cover for videos from edit caption box. 2025-10-23 10:09:08 +04:00
John Preston
8e5d0c66db Revert downgrade of xdg-desktop-portal. 2025-10-23 10:06:04 +04:00
Ilya Fedin
6e8ac60399 Actually share files with Drag'n'Drop to shortcut on macOS
The code supported this since 4.8.3 (6aef6d7f4e) for Linux but wasn't actually allowed on macOS via plist.
2025-10-22 22:02:37 +04:00
John Preston
f8bd80109c Update lib_base submodule. 2025-10-22 22:02:02 +04:00
Ilya Fedin
de89d349ad Implement launching maps on Linux 2025-10-22 22:01:45 +04:00
Ilya Fedin
dbc9beaa19 Make psLaunchMaps async 2025-10-22 22:01:45 +04:00
Ilya Fedin
1f171c4ed1 Remove unused includes from specific_linux.cpp 2025-10-22 22:01:45 +04:00
John Preston
2e03888505 Update patches revision. 2025-10-22 22:00:42 +04:00
Ilya Fedin
ab5eafbe68 Update Qt to 6.10.0 2025-10-22 21:59:38 +04:00
Ilya Fedin
73014a33fe Fix build with Qt 6.10 2025-10-22 21:59:38 +04:00
Ilya Fedin
7bdbe0ef77 Examples and tests don't get built by default with Qt 6 2025-10-22 21:59:38 +04:00
Ilya Fedin
d4dbad4649 Remove -no-sbom
Following 7d78de0673
2025-10-22 21:59:38 +04:00
Ilya Fedin
24b23bbb5a Don't hardcode Qt version in the action 2025-10-22 21:59:38 +04:00
John Preston
abab44a02b Adapt latest lib_ui changes for accessibility. 2025-10-22 21:56:41 +04:00
Reza Bakhshi Laktasaraei
b9c07e644f Setting accessibleName and accessibleRole for objects 2025-10-22 20:40:08 +04:00
Reza Bakhshi Laktasaraei
ce9c3b4ef8 enable clicking on country chooser by pressing space bar and enter key 2025-10-22 20:40:08 +04:00
Reza Bakhshi Laktasaraei
13862bd561 adding the entry poin for enabling accessibility 2025-10-22 20:40:08 +04:00
John Preston
856d38df49 Fix crash in stories volume control destructor. 2025-10-22 17:32:17 +04:00
John Preston
27a5e13107 Fix glitch in forum row switch from/to. 2025-10-22 17:31:43 +04:00
John Preston
a71c24f803 Version 6.2.4.
- Highlight links in contact notes.
- Show menu with screen share controls in wide group call mode.
- Fix possible crash in saved music removing.
- Fix crash in theme editor.
2025-10-22 12:54:20 +04:00
John Preston
758ec52b91 Fix build. 2025-10-22 12:54:20 +04:00
Ilya Fedin
96418bb9f1 Make QFileOpenEvent timeout immediate 2025-10-22 12:48:33 +04:00
23rd
f750d94b2d Fixed processing of recent self forwards from share box for non-premium. 2025-10-22 12:30:54 +04:00
23rd
6eb9695e1e Added links support to user notes. 2025-10-22 12:23:40 +04:00
John Preston
33bbad8053 Fix possible crash in saved music removing. 2025-10-22 12:18:12 +04:00
John Preston
3ea34461b2 Fix typing animation in chats list updates. 2025-10-22 12:18:12 +04:00
John Preston
b6a202b721 Fix error display in webview box. 2025-10-22 12:18:12 +04:00
John Preston
4d8cb022c5 Make screen share controls available. 2025-10-22 12:18:12 +04:00
John Preston
3046318de5 Update submodules. 2025-10-22 12:18:12 +04:00
John Preston
c351598f13 Simplify OpenGL surface renderer interface. 2025-10-22 12:18:12 +04:00
John Preston
02084be583 Fix crash in theme editor. 2025-10-13 16:43:13 +04:00
John Preston
e117d08b2c Version 6.2.3.
- Fix crash when viewing messages with hidden senders.
- Fix possible crash when editing contacts.
- Fix layout of character count warning in contact notes.
- Fix icons when editing contacts.
- Fix color of sending messages animation in complex themes.
- Fix crash in chat open on Flatpak build.
2025-10-12 12:06:00 +04:00
John Preston
58783170cd Fix a crash with Qt 6.10. 2025-10-12 12:04:13 +04:00
John Preston
9ba2426c02 Fix crash in messages with hidden senders. 2025-10-12 11:59:11 +04:00
23rd
2cbaa7b03d Removed ability to suggest things for contacts with paid messages. 2025-10-12 11:58:57 +04:00
23rd
836a0f3a73 Removed photo buttons in edit contact box when adding new contact. 2025-10-12 11:58:57 +04:00
23rd
e9977f551f Moved info profile text file to td_ui. 2025-10-12 11:58:57 +04:00
23rd
78abe362cd Disabled simple sending animation of text messages when window is wide. 2025-10-11 20:30:45 +03:00
23rd
47c2922d55 Fixed possible crash in edit contact box. 2025-10-11 17:04:02 +03:00
23rd
690f3fecbb Fixed stuck box on resetting contact photo to original. 2025-10-11 17:04:02 +03:00
23rd
d9242db7b3 Fixed display of animated icons in edit contact box on non-retina. 2025-10-11 16:29:21 +03:00
23rd
a9b5e22b37 Slightly improved behavior of visibility for chars limit in notes. 2025-10-11 14:00:44 +03:00
23rd
7b8f1704dc Applied easeOutQuint on X axis for simple sending animation for text. 2025-10-11 12:21:42 +03:00
23rd
de88ddf42b Fixed color of bubbles while simple sending animation in complex themes. 2025-10-11 12:21:42 +03:00
John Preston
b1e707c346 Version 6.2.2.
- Fix layer.
2025-10-10 23:12:58 +04:00
John Preston
36b7b3a7cd Version 6.2.1.
- Fix sending gifts.
- Fix possible crash on Linux.
2025-10-10 23:12:22 +04:00
John Preston
d44349d612 Fix possible crash on Linux. 2025-10-10 21:58:35 +04:00
23rd
53919be913 Slightly improved mouse processing for gift buttons. 2025-10-10 21:58:29 +04:00
23rd
8dd7d04fff Removed duplicated callback on press on gift in gifts list section. 2025-10-10 21:58:29 +04:00
23rd
384f6d9a31 Added logging of api updates when deleted message is unknown. 2025-10-10 21:58:29 +04:00
John Preston
d51195a537 Version 6.2.
- Comments and reactions in group calls.
- Notes for contacts.
- Suggested birthdays.
- Threads for AI bots.
- Reorder gifts collections and stories albums.
- Reorder gifts inside collections.
- Apply tags instantly when forwarding to Saved Messages.
- Choose which screen to show notifications on.
- Nice text message sending animation.
2025-10-10 20:40:33 +04:00
23rd
10bedad9bf Fixed title phrase in credits settings.
Fixed #29831.
2025-10-10 16:42:54 +03:00
23rd
4027d3c07f Replaced easeOutCirc with easeOutQuint for message revealing animation. 2025-10-10 16:21:58 +03:00
23rd
ec78d3b83b Added processing of recent self forwards to share box. 2025-10-10 11:29:09 +03:00
23rd
acf61c24bd Moved out api processing of recent self forwards to single place. 2025-10-10 11:29:09 +03:00
23rd
338183e647 Added toast after successfully tagging of recent forwards to self. 2025-10-10 11:29:09 +03:00
23rd
59e0de85e3 Added label for test dc to intro widget. 2025-10-10 11:29:09 +03:00
23rd
2e6941c23f Improved ability to edit caption of latest uploading media with Up. 2025-10-10 11:29:03 +03:00
23rd
e1c33aa87b Extracted default paint callback for VerticalDrumPicker to single place. 2025-10-10 11:28:42 +03:00
23rd
70d8cede9b Added month and year picker to calendar box by clicking on title. 2025-10-10 11:28:42 +03:00
23rd
7587bbd4bc Disabled mouse tracking after chosen emoji in tagger instantly. 2025-10-10 11:28:20 +03:00
23rd
668f0498ed Removed sending animation for texts that don't fit into input field. 2025-10-10 11:28:17 +03:00
23rd
32ff331744 Removed simple sending animation for emoji-only messages. 2025-10-10 11:28:13 +03:00
23rd
bc90463893 Removed unused variable in macOS file utilities to fix compiler warning. 2025-10-10 11:26:45 +03:00
23rd
7fb486d8d2 Removed unused variable from touchbar item on macOS. 2025-10-10 11:26:42 +03:00
23rd
538df0e67c Added simple sending animation for text messages to chat section. 2025-10-10 11:24:15 +03:00
23rd
60bb93170e Fixed opacity of pattern bubble with chat theme while sending animation. 2025-10-10 11:24:15 +03:00
23rd
766370221b Fixed incorrect drawing of sending animation bubble with custom themes. 2025-10-10 11:24:15 +03:00
23rd
8007e6d354 Decomposed drawing of text and bubble for sending animation. 2025-10-10 11:24:15 +03:00
23rd
443053b927 Added simple sending animation for text messages to history widget. 2025-10-10 11:24:15 +03:00
23rd
b6000bc1a8 Added ability to pass optional local message id to sendMessage method. 2025-10-10 11:24:15 +03:00
23rd
8bdf8d42d9 Adapted retrieving displays name for Windows from Qt6.6.0.
6136b92f54
2025-10-10 11:24:07 +03:00
Ilya Fedin
c084396f8f Show display manufacturer and model on Linux 2025-10-10 11:24:07 +03:00
Ilya Fedin
b29877554c Make experimental option for non-native notifications cross-platform 2025-10-10 11:24:07 +03:00
23rd
a2d17f6f3f Added ability to choose display for notifications to settings. 2025-10-10 11:24:07 +03:00
23rd
54018aec90 Added experimental option for non-native notifications on macOS. 2025-10-10 11:24:07 +03:00
23rd
2699f9bcf6 Added icon to menu item for adding gift to collection. 2025-10-10 09:27:02 +04:00
23rd
094890622a Added text about to selector of tag for recent forwards to self. 2025-10-10 09:27:02 +04:00
23rd
bee4ec5ddf Added ability to filter new tagger for self forwards with opened chat. 2025-10-10 09:27:02 +04:00
23rd
29f533b170 Added info about origin peer to data about recent forwards. 2025-10-10 09:27:01 +04:00
23rd
296c2a7b5b Added ability to tag recent forwarded messages to self in chat section. 2025-10-10 09:27:01 +04:00
23rd
c4decce7f0 Added ability to tag with emoji recent forwarded messages to self. 2025-10-10 09:27:01 +04:00
23rd
a396f507f8 Slightly improved share message phrase factory to be more flexible. 2025-10-10 09:27:01 +04:00
23rd
eb96fd1b97 Added ability to paint bubble on top in reactions selector. 2025-10-10 09:27:01 +04:00
23rd
8cc7d80121 Added ability to notify about successful forwarded messages to self. 2025-10-10 09:27:01 +04:00
23rd
d59139202d Added ability to add gift to collection with context menu. 2025-10-10 09:27:01 +04:00
23rd
a3cd4a55de Added ability to remove gift from collection with context menu. 2025-10-10 09:27:01 +04:00
23rd
0cb7388ee0 Added menu item icon for reorder. 2025-10-10 09:27:01 +04:00
23rd
2700e9b326 Added contact notes to peer short info box. 2025-10-10 09:27:01 +04:00
23rd
d36d5b2980 Added new Changes flag for user notes. 2025-10-10 09:27:01 +04:00
John Preston
028437549d Fix build on macOS. 2025-10-10 09:27:01 +04:00
John Preston
1f17551bf4 Improve new thread icon for threaded bots. 2025-10-10 09:27:01 +04:00
23rd
cd301c9df2 Updated pinned intervals for sub tabs in gifts and stories on change. 2025-10-10 09:27:01 +04:00
John Preston
ce43aab4cd Handle sender links and spoilers in messages. 2025-10-10 09:27:01 +04:00
John Preston
86d1ab00e0 Support disabling messages in conferences. 2025-10-10 09:27:01 +04:00
John Preston
93b2a52f34 Support enabling/disabling messages. 2025-10-10 09:27:01 +04:00
John Preston
d3da830ef8 Support 3/4/5 buttons in group call layout. 2025-10-10 09:27:01 +04:00
John Preston
ec4deb87c6 Support hosted unique gifts. 2025-10-10 09:27:01 +04:00
John Preston
d832a0a186 Show better preview of gift-based reply-color. 2025-10-10 09:27:01 +04:00
John Preston
65800e17a5 Fix export gift on blockchain flow. 2025-10-10 09:27:01 +04:00
23rd
9c5dd452dd Added ability to reorder stories albums. 2025-10-10 09:27:01 +04:00
23rd
78940413a0 Removed instant stop of shifting animations in gifts while reordering. 2025-10-10 09:27:01 +04:00
23rd
cc2f459f26 Added scroll support while dragging gift in gifts section. 2025-10-10 09:27:01 +04:00
23rd
d1c98eb22a Improved mouse processing for dragged view in gifts section. 2025-10-10 09:27:01 +04:00
23rd
1fe9a0ee5a Improved previous state of dragged view in gifts section. 2025-10-10 09:27:01 +04:00
23rd
80a87f963a Preserved dragged gift during scroll gifts list to prevent recreation. 2025-10-10 09:27:01 +04:00
23rd
2c0051b083 Updated show of first star gift in collection after reorder in subtabs. 2025-10-10 09:27:01 +04:00
23rd
4a938170e1 Added initial ability to reorder star gifts within collection. 2025-10-10 09:27:01 +04:00
23rd
f3a27c4fcb Removed other menu items while reordering sub tabs for gifts collection. 2025-10-10 09:27:01 +04:00
23rd
f43b11fd6a Changed reorder of sub tabs for gifts collection only when finished. 2025-10-10 09:27:01 +04:00
23rd
93d382c416 Slightly simplified shake animation in sub tabs for gifts collection. 2025-10-10 09:27:01 +04:00
23rd
48e4060d62 Added scroll support to sub tabs for star gifts collection. 2025-10-10 09:27:01 +04:00
23rd
bbc7ef100c Added api support for reordering of star gifts collections. 2025-10-10 09:27:00 +04:00
23rd
c22468c943 Added initial ability to reorder sub tabs for gifts collection. 2025-10-10 09:27:00 +04:00
23rd
7d538ea080 Added ability to set pinned intervals to sub tabs for gifts collection. 2025-10-10 09:27:00 +04:00
23rd
aad1ff95be Added simple animation to sub tabs for gifts collection while reorder. 2025-10-10 09:27:00 +04:00
23rd
72f0fb6892 Added menu item to sub tabs for star gifts collections for reordering. 2025-10-10 09:27:00 +04:00
John Preston
a0baad4942 Fix build with Xcode. 2025-10-10 09:27:00 +04:00
John Preston
5e40d60e34 Update API scheme on layer 216. 2025-10-10 09:27:00 +04:00
John Preston
314f787042 Improve selection design for gifts. 2025-10-10 09:27:00 +04:00
John Preston
7f340da0ec Fix upgrade gift button text. 2025-10-10 09:27:00 +04:00
John Preston
acafa2bcad Allow buy-and-set color from collectible. 2025-10-10 09:27:00 +04:00
John Preston
404d8da1a3 Mostly finish collectible colors implementation. 2025-10-10 09:27:00 +04:00
John Preston
26be7840b4 Display collectible-based user reply bars. 2025-10-10 09:27:00 +04:00
23rd
520b84f967 Replaced icon for birthday suggestion in edit contact box. 2025-10-10 09:27:00 +04:00
23rd
e7f6a8a476 Added ability to edit contact note with context menu. 2025-10-10 09:27:00 +04:00
23rd
0f3ef4b35c Added ability to delete contact note with context menu. 2025-10-10 09:27:00 +04:00
23rd
60d88693ec Removed irrelevant menu item for birthday suggestion service message. 2025-10-10 09:27:00 +04:00
23rd
ff6e2b6d31 Fixed pinned count for subsection tabs when chat itself is pinned. 2025-10-10 09:27:00 +04:00
23rd
bc52ad7bf2 Added nice lottie icons to suggest and set photo in edit contact box. 2025-10-10 09:27:00 +04:00
23rd
daa24de171 Added toast when limit for note length is reached. 2025-10-10 09:27:00 +04:00
23rd
68f0e25227 Wrapped buttons in edit contact box. 2025-10-10 09:27:00 +04:00
23rd
320f2bea7b Added QDebug support for MTP::Error. 2025-10-10 09:27:00 +04:00
23rd
666692e341 Added ability to toggle editable username for owned bots. 2025-10-10 09:27:00 +04:00
John Preston
304cc33b76 Update API scheme on layer 216. 2025-10-10 09:27:00 +04:00
John Preston
e0f4aca336 Display reply/link area style from collectibles. 2025-10-10 09:27:00 +04:00
John Preston
ccdff5baef Support birthday suggestion view/process. 2025-10-10 09:27:00 +04:00
John Preston
16fe056c99 Read messages limit/ttl from appConfig. 2025-10-10 09:27:00 +04:00
John Preston
fb5c155f7e Fix message text clipping. 2025-10-10 09:26:59 +04:00
John Preston
eccbb0df7a Add reaction selector widget. 2025-10-10 09:26:59 +04:00
John Preston
0bcfcb4ea4 Show reaction animations in messages. 2025-10-10 09:26:59 +04:00
John Preston
b6b4d5c387 Remove test-case failed sending. 2025-10-10 09:26:59 +04:00
John Preston
bb7bfe95e5 Fix build on Windows. 2025-10-10 09:26:59 +04:00
23rd
ac1e5a08d8 Fix building with Qt 6. 2025-10-10 09:26:59 +04:00
23rd
4a05f0fd05 Added ability to suggest birthday from edit contact box. 2025-10-10 09:26:59 +04:00
23rd
f1dff4d0b7 Added ability to delete contact from edit contact box. 2025-10-10 09:26:59 +04:00
23rd
96343603cd Added user notes to user profile. 2025-10-10 09:26:59 +04:00
23rd
9dccab915d Added api ability to save contact notes. 2025-10-10 09:26:59 +04:00
23rd
0decf928f0 Added ability to manage contact photo in edit contact box. 2025-10-10 09:26:59 +04:00
23rd
44faef3027 Added ability to provide special markdown set to input field for notes. 2025-10-10 09:26:59 +04:00
23rd
52a590334c Added input field for notes to edit contact box. 2025-10-10 09:26:59 +04:00
23rd
8ea9709305 Added api support to handle notes into users. 2025-10-10 09:26:59 +04:00
23rd
751c7e05f9 Added support of limit for notes about contacts. 2025-10-10 09:26:59 +04:00
23rd
ebe0aa27e4 Added ability to pass optional margins to CharactersLimitLabel. 2025-10-10 09:26:59 +04:00
23rd
4ef7f0dd24 Added ability to display non-negative numbers in CharactersLimitLabel. 2025-10-10 09:26:59 +04:00
John Preston
4779c036f5 Update API scheme on layer 216. 2025-10-10 09:26:59 +04:00
John Preston
1480a4e270 Fix spoilers display. 2025-10-10 09:26:59 +04:00
John Preston
6a167a4b0f Allow custom emoji only from premium users. 2025-10-10 09:26:59 +04:00
John Preston
9b43f57dfa Support e2e encrypted conference messages. 2025-10-10 09:26:59 +04:00
John Preston
fc74840b55 Apply tags filtering and length limit. 2025-10-10 09:26:59 +04:00
John Preston
f408b1bb11 Scroll to bottom on message send. 2025-10-10 09:26:59 +04:00
John Preston
7a3e16b92f Escape hides message field, nice fade-shadows. 2025-10-10 09:26:59 +04:00
John Preston
939045d606 Update API scheme on layer 216. 2025-10-10 09:26:59 +04:00
John Preston
b3ee80e495 Fade call messages on top and bottom. 2025-10-10 09:26:59 +04:00
John Preston
1c17a76b80 Animate message field show/hide. 2025-10-10 09:26:59 +04:00
John Preston
08a55721bf Replace ScrollArea with ElasticScroll in messages. 2025-10-10 09:26:59 +04:00
John Preston
42991bfa2c Hide scrollbar in messages. 2025-10-10 09:26:59 +04:00
John Preston
46897689d3 Support scroll of messages without mouse input. 2025-10-10 09:26:59 +04:00
John Preston
9b3acf7162 Make messages nicer, sending animation. 2025-10-10 09:26:59 +04:00
John Preston
4436e3ba69 Implement initial messages display. 2025-10-10 09:26:59 +04:00
John Preston
78b3f21e7a Update API scheme on layer 216. 2025-10-10 09:26:59 +04:00
John Preston
e2ae0a7a4f Send / receive messages in group calls. 2025-10-10 09:26:58 +04:00
John Preston
5ed8f0baa5 Show sending message field in group chats. 2025-10-10 09:26:58 +04:00
John Preston
f1d4e48c59 Show message button in group calls. 2025-10-10 09:26:58 +04:00
23rd
48ac431134 Fixed refreshing of pinned on unpin within subsection slider. 2025-10-10 09:26:58 +04:00
23rd
d6a27c04b9 Fixed ability start recording of voice with shortcut in channels.
Fixed #29805.
2025-10-10 09:26:58 +04:00
23rd
388e9cec09 Respected admin rights in subsections slider for reordering. 2025-10-10 09:26:58 +04:00
23rd
b01f70176b Added scroll support to subsections slider for reordering. 2025-10-10 09:26:58 +04:00
23rd
e7b4a5db61 Fixed desired clicked callback for reordered tabs in subsection slider. 2025-10-10 09:26:58 +04:00
23rd
d5a1d28779 Added recalculation of pinned state while reordering in subsection tabs. 2025-10-10 09:26:58 +04:00
23rd
e0da4159ae Added api ability to reorder topics in forums with subsection tabs. 2025-10-10 09:26:58 +04:00
23rd
0eef766ea1 Added ui ability to reorder tabs in subsection slider. 2025-10-10 09:26:58 +04:00
23rd
aebd53363c Added initial implementation of reorder class for subsection slider. 2025-10-10 09:26:58 +04:00
23rd
f18bb1c780 Prepared subsection slider for reorder support. 2025-10-10 09:26:58 +04:00
23rd
eecb7c0622 Added nice ripple mask for pinned group of buttons in subsection tabs. 2025-10-10 09:26:58 +04:00
23rd
84c0b46266 Added initial icon to pinned group of buttons in subsection tabs. 2025-10-10 09:26:58 +04:00
23rd
fb030b3520 Added filling of fixed and pinned counts to subsection tabs. 2025-10-10 09:26:58 +04:00
23rd
42aac81fd8 Added initial style of pinned group of buttons in subsection tabs. 2025-10-10 09:26:58 +04:00
John Preston
09175d2b6b Allow removing unique gift details. 2025-10-10 09:26:58 +04:00
John Preston
46f64f75c7 Simplify gift tabs when sending. 2025-10-10 09:26:58 +04:00
John Preston
9b5425de14 Support 5-second slow mode. 2025-10-10 09:26:58 +04:00
John Preston
7b1135ecd4 Update API scheme on layer 216. 2025-10-10 09:26:58 +04:00
John Preston
2ca63ae324 Show upgrade price decrease information. 2025-10-10 09:26:58 +04:00
John Preston
5b02323487 Update API scheme on layer 216. 2025-10-10 09:26:58 +04:00
John Preston
cf99eef9c9 Mark general topic as deleted in bot forums. 2025-10-10 09:26:58 +04:00
John Preston
c54e05d220 Fix threads list opening for bots. 2025-10-10 09:26:58 +04:00
John Preston
a651853534 Add thread phrases instead of topic. 2025-10-10 09:26:58 +04:00
John Preston
a1a81b812a Improve bot new thread info panel. 2025-10-10 09:26:58 +04:00
John Preston
e74d0ef4e2 Start new bot thread on send in All. 2025-10-10 09:26:58 +04:00
John Preston
ca4caec819 Improve bot with forum opening. 2025-10-10 09:26:57 +04:00
John Preston
900c12d1d0 Fix draft-typings in topics. 2025-10-10 09:26:57 +04:00
John Preston
4d61701790 Clear out streamed drafts by messages/timeout. 2025-10-10 09:26:57 +04:00
John Preston
4fd0e734ea Initial support for streamed bot responses. 2025-10-10 09:26:57 +04:00
John Preston
b4d1ba07a6 Initial forum support in bots data classes. 2025-10-10 09:26:57 +04:00
John Preston
6974c511ea Update API scheme to layer 216. 2025-10-10 09:26:57 +04:00
John Preston
d30dd7450f Update API scheme to layer 215. 2025-10-10 09:26:57 +04:00
23rd
f877e653e9 Fixed useless animation from mini premium stars if not painting. 2025-10-09 18:26:54 +03:00
23rd
699ffc8b50 Returned unreadBadge/Muted but keep unreadWithMentionsBadge/Muted. 2025-10-09 19:06:03 +04:00
John Preston
135b81bbb4 Fallback to any h264 encoder in video messages. 2025-10-09 19:02:06 +04:00
John Preston
d9f5c2d16e Fix possible crash when video message encoding fails. 2025-10-09 19:02:06 +04:00
John Preston
2e0f04ce93 Fix alignment of "Top Senders" label. 2025-10-09 19:02:06 +04:00
John Preston
8ebb084f0f Remove incorrect "sender hidden" from unique gifts. 2025-10-09 19:02:06 +04:00
John Preston
f2bc07458d Fix links clickability in forums. 2025-10-09 19:02:06 +04:00
John Preston
b4daca860f Fix channel direct messages links. 2025-10-09 19:02:06 +04:00
John Preston
ac6919680a Fix crash in messages containing unsupported story. 2025-10-09 19:02:06 +04:00
John Preston
c6749f2d5c Stop CollectibleEmoji animation if not painting. 2025-10-09 19:02:06 +04:00
John Preston
47fd936306 Fix recording of video messages.
Fixes #29860.
2025-10-09 19:02:05 +04:00
Ilya Fedin
147439ad34 Add missed ConnectionState member variable to operator== 2025-10-06 21:05:19 +04:00
John Preston
1a3eb0f209 Version 6.1.4.
- Allow add to folder from recent / top chats.
- Fix clear history of group chats.
- Fix several crashes.
2025-10-06 13:53:57 +04:00
John Preston
acd2c514ce Fix build with GCC. 2025-10-06 13:53:57 +04:00
John Preston
fccff0c03a Fix build with Xcode. 2025-10-06 13:19:26 +04:00
Ilya Fedin
7cf8483f9a Get rid of AppData mentions
They renamed the extension from appdata to metainfo long time ago and the right name is "AppStream metadata"
2025-10-06 11:54:27 +04:00
Ilya Fedin
63bad22ac4 Remove some ffmpeg version conditionals
The previous commit uses a FFmpeg 6.1+ API making all those conditionals broken
2025-10-06 11:37:40 +04:00
Lukas Fleischer
b009f06375 Fix compatibility with ffmpeg 8
Fixes #29713.
2025-10-06 11:37:09 +04:00
John Preston
8aa5ebf621 Fix build on Windows. 2025-10-06 11:23:54 +04:00
John Preston
53ac770772 Do links disabling in groups as well. 2025-10-06 11:23:54 +04:00
John Preston
fbfe47528b Fix saved music page-after-page loading. 2025-10-06 11:23:54 +04:00
23rd
71443f7def Slightly improved style of text in credits rating icons. 2025-10-06 11:23:54 +04:00
23rd
a1b1165039 Cleared sponsored messages on premium just in case. 2025-10-06 11:23:54 +04:00
23rd
c060243201 Respected system-wide preference for disabling swipe-to-back on macOS. 2025-10-06 11:23:54 +04:00
23rd
93f84e2b65 Reversed gifts sort in section of shared media from info profile. 2025-10-06 11:23:54 +04:00
23rd
9cd971a53f Fixed userpic scale in short info box while scrolling. 2025-10-06 11:23:54 +04:00
23rd
b22b819683 Added ability to short info for peer from menu with pressed Ctrl. 2025-10-06 11:23:54 +04:00
John Preston
8779ac3ec3 Hide links in chats with Report Spam. 2025-10-06 11:23:54 +04:00
John Preston
16ec935feb Paint correct direct userpic in recent/top peers. 2025-10-06 11:23:54 +04:00
John Preston
e59d229097 Remove direct chats that were cleared. 2025-10-06 11:23:54 +04:00
John Preston
9028d9a339 Check support mode on full self load. 2025-10-06 11:23:54 +04:00
John Preston
6999a1b5e4 Allow add to folder from recent / top peers. 2025-10-06 11:23:54 +04:00
John Preston
7ef6d33ea9 Use correct phrase for bot noforwards. 2025-10-06 11:23:54 +04:00
John Preston
3824f19ce5 Fix chat preview for channel direct messages.
Fixes #29802.
2025-10-06 11:23:54 +04:00
23rd
930268ed0d Improved style of text badge in dialogs for retina displays. 2025-10-06 11:23:54 +04:00
23rd
cb0a3fdb6e Disabled field for input while recording voice.
Fixed #29818.
2025-10-06 11:23:53 +04:00
23rd
4c0a2b1d3d Added initial support of swipe-to-back to settings premium and credits. 2025-10-06 11:23:53 +04:00
23rd
6fd34dee5a Fixed giveaway bubble height calculation for narrow widths. 2025-10-06 11:23:53 +04:00
23rd
1c56c4dfe5 Moved out common big unread counter formatting logic to single place. 2025-10-06 11:23:53 +04:00
23rd
53321160c4 Changed emoji for to-do list in notification text. 2025-10-06 11:23:53 +04:00
23rd
5b29d3bb72 Returned missed item back to to-do list for editing. 2025-10-06 11:23:53 +04:00
23rd
4796a3116a Slightly improved style of bottom label in to-do list. 2025-10-06 11:23:53 +04:00
23rd
6183569dc2 Slightly improved phrases in subtitle of to-do list. 2025-10-06 11:23:53 +04:00
John Preston
3296a2addb Increase .pdb page size for 32 bit build. 2025-10-06 11:23:53 +04:00
John Preston
235cb0c574 Revert "Add a hack to delete .pdb before link."
This reverts commit 0a8316138e7bb7b22ad82e0c232321dc089666d6.
2025-10-06 11:23:53 +04:00
John Preston
570fbd9a00 Allow empty query in switch inline in webview bots. 2025-10-06 11:23:53 +04:00
John Preston
e205b521fd Fix parsing checklist pasting of multiline. 2025-10-06 11:23:53 +04:00
23rd
ce15754575 Hid emoji status from profile cover in edit contact box as well. 2025-10-06 11:23:53 +04:00
23rd
18085bae70 Hid unused properties from profile cover in edit contact box. 2025-10-06 11:23:53 +04:00
John Preston
61536b42c9 Improve layout of transfer gift box. 2025-10-06 11:23:53 +04:00
John Preston
532f166b22 Remove NEW badge for Posts search. 2025-10-06 11:23:53 +04:00
John Preston
c1d3a78316 Fix possible crash in moderate messages box. 2025-10-06 11:23:53 +04:00
John Preston
e524d9694d Fix possible crash in SavedSublist. 2025-10-06 11:23:53 +04:00
John Preston
1efa889913 Fix possible crash in fast action in chats list. 2025-10-06 11:23:53 +04:00
John Preston
c73788da24 Try not forcing OpenGL for main window on macOS. 2025-10-06 11:23:53 +04:00
John Preston
5ec277b2ed Show "N left" badge on limited gifts. 2025-10-06 11:23:52 +04:00
John Preston
e327e1bc9c Fix crash in subsection tabs mode changing. 2025-10-06 11:23:52 +04:00
23rd
37c5c1dc98 Delayed clearing up of expired unreviewed sessions on startup. 2025-10-03 14:01:34 +04:00
Ilya Fedin
156e1a00d3 macos-13 -> macos-15-intel 2025-10-03 11:53:22 +04:00
Ilya Fedin
3aa9a2f2c0 Allow webview without embedding on Linux 2025-10-03 11:37:51 +04:00
Ilya Fedin
e1f5b57fd3 Revert "Add error message for webview without OpenGL"
This reverts commit 20fb73b626.
2025-10-03 11:37:51 +04:00
Ilya Fedin
cf757b6c7b Revert "Add error message for webview unsupported display server"
This reverts commit b0933b96ef.
2025-10-03 11:37:51 +04:00
Ilya Fedin
bd2da8d632 Update submodules 2025-10-01 15:59:53 +04:00
GitHub Action
01b7e387eb Update User-Agent for DNS to Chrome 140.0.0.0. 2025-10-01 10:24:02 +04:00
John Preston
60bf6b1f70 Improve gifts display. 2025-10-01 10:21:20 +04:00
John Preston
7839c6294c Add a hack to delete .pdb before link. 2025-10-01 10:21:19 +04:00
23rd
20cadfad29 Added experimental option to hide reply button from native notification. 2025-09-29 15:12:51 +03:00
23rd
2b93362a57 Added fetching "Mark as read" translation based on macOS language. 2025-09-29 15:12:51 +03:00
23rd
5476f297e1 Added ability to get value of phrase for specific language. 2025-09-29 15:12:51 +03:00
23rd
b79fbe2123 Added "Mark as read" action to macOS notifications. 2025-09-29 15:12:51 +03:00
23rd
d9a76fdd9a Removed version of zlib from readme. 2025-09-29 15:12:51 +03:00
23rd
721a69f2b1 Slightly improved code style of MediaPreviewWidget. 2025-09-29 15:12:51 +03:00
23rd
a49b3e67d0 Added ability to provide data to emoji list for preview via descriptor. 2025-09-29 15:12:51 +03:00
23rd
297600ca6d Added ability to set blind corners for MediaPreviewWidget. 2025-09-29 15:12:51 +03:00
23rd
15019051c0 Added QDebug operator support for Data::UnreadState. 2025-09-29 15:12:51 +03:00
23rd
2b7e8bf449 Fixed display of name of caller to fit within call panel. 2025-09-29 15:12:51 +03:00
23rd
928798dc16 Added initial ability to edit caption of latest uploading media with Up. 2025-09-29 15:12:51 +03:00
23rd
1a01ec17d6 Respected limitations of caption length for media in caption boxes. 2025-09-29 15:12:51 +03:00
23rd
69da4d749b Replaced multi-purpose callShadow with specific one for media view PiP. 2025-09-29 15:12:50 +03:00
23rd
b1fc95b1d9 Added decimal separators to credits in charge slider for direct message. 2025-09-29 15:12:50 +03:00
23rd
0b7f104c95 Added ability to preview emoji within reactions emoji pan. 2025-09-29 15:12:34 +03:00
23rd
912974cb80 Added ability to set padding and margins for MediaPreviewWidget. 2025-09-29 15:12:34 +03:00
23rd
9bbb8ef31c Replaced unreadBadge/Muted with unreadWithMentionsBadge/Muted. 2025-09-29 15:12:34 +03:00
23rd
e01f53a58c Fixed ability to clear history for groups and megagroups. 2025-09-29 15:12:34 +03:00
Ilya Fedin
82c69a03ef Explicitly disable documentation build for libheif 2025-09-24 10:53:31 +04:00
Ilya Fedin
f8aa79aaf5 Update msys2 2025-09-24 10:53:31 +04:00
Ilya Fedin
700ae79b93 Revert "Switch macOS packaged action to latest ffmpeg"
This reverts commit 2cb20fe342.
2025-09-24 10:53:31 +04:00
Ilya Fedin
8dd8ab6366 Set deployment target in macOS packaged action 2025-09-24 10:53:31 +04:00
Ilya Fedin
28d19a99e1 Fix build with Qt 6.10 2025-09-24 08:30:48 +04:00
dependabot[bot]
6627de6460 Bump actions/stale from 9 to 10
Bumps [actions/stale](https://github.com/actions/stale) from 9 to 10.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v9...v10)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: '10'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 17:00:15 +04:00
Ilya Fedin
795d452493 Update submodules 2025-09-15 16:42:36 +04:00
Ilya Fedin
2d7f52972d Add ASAN flag to Dockerfile generator 2025-09-15 16:42:36 +04:00
John Preston
6229c0020c Version 6.1.3.
- Fix dead keys / alt combinations / input methods issues.
2025-09-07 08:46:44 +04:00
23rd
8db1bf9052 Added ability to share link for monoforum of owned channels. 2025-09-07 08:46:44 +04:00
23rd
2740c5db23 Extracted URL protocol stripping to Ui::Text::StripUrlProtocol. 2025-09-07 08:46:44 +04:00
23rd
512e6de39b Fixed position of tag preview in chats filter settings.
Fixed #29750.
2025-09-07 08:46:44 +04:00
23rd
e3c328c7e3 Reverted "Removed ability to clear history from replies chat.".
This reverts commit 86daf2a9dc.
2025-09-07 08:46:44 +04:00
John Preston
9eb5ea599e Fix build with MSVC. 2025-09-06 19:09:21 +03:00
Ilya Fedin
929032d598 Add GStreamer H264, H265, AAC and VA-API plugins to snap 2025-09-06 20:05:21 +04:00
Ilya Fedin
09fb42291d Revert "Self-build openh264 in snap for lesser package size"
This reverts commit a8430d8ecf.
2025-09-06 20:05:21 +04:00
Ilya Fedin
e6665a8305 Fix playing audio files via webkitgtk in snap 2025-09-06 20:04:48 +04:00
John Preston
a785d83791 Don't cancel special KeyPress events (key = 0).
I hope this fixes #29747, #29745, #29744, #29743, #29741.
2025-09-06 08:39:51 +04:00
23rd
08a64f0dc0 Fixed color of lottie icon from transcribe voices while loading. 2025-09-04 13:05:37 +03:00
John Preston
0babad837d Remove legacy "quicklaunchicon" InnoSetup task. 2025-09-04 13:03:25 +04:00
John Preston
fb1f70f5de Version 6.1.2.
- Close selected chat in Ctrl+Tab chat switch by 'Q'.
- Auto-split pasted multiple lines to checklist task creation.
- Fix color picker in userpic builder.
2025-09-04 12:03:07 +04:00
John Preston
d4dd1b7ba0 Fix build with GCC. 2025-09-04 12:03:07 +04:00
John Preston
82c921d739 Fix build with Xcode. 2025-09-04 12:00:49 +04:00
John Preston
180a570f99 Handle robustly Ctrl+Q/Ctrl+Arrows in Ctrl+Tab chat switch. 2025-09-04 12:00:35 +04:00
John Preston
9960a7a7e4 Remove unneeded openssl/engine.h include. 2025-09-04 11:43:59 +04:00
John Preston
2164d08c3c Fixed a crash in gifts section closing.
Fixes #29737.
2025-09-04 11:28:21 +04:00
John Preston
4b2d0d1a67 Allow a bit more theme previews. 2025-09-02 21:36:08 +04:00
John Preston
d0341d191b Close selected chat in switch by Q. 2025-09-02 19:22:19 +04:00
John Preston
10237a2d90 Correct gift symbol sizes and rotations. 2025-09-02 17:28:38 +04:00
John Preston
59390ddaa1 Support pasting multi-line as multi-tasks. 2025-09-02 13:54:42 +04:00
John Preston
312c94f386 Fill suggested prices for gifts between stars/TON. 2025-09-02 12:04:47 +04:00
John Preston
d697677fab Fix time input colon. 2025-09-02 08:38:10 +04:00
John Preston
bf484b5518 Update lib_webview. 2025-09-02 08:33:15 +04:00
John Preston
74b530259d Fix color picker in userpic builder again. 2025-09-02 08:26:04 +04:00
John Preston
4052c3d101 Fix color picker in userpic builder. 2025-09-02 08:17:29 +04:00
John Preston
86262333a4 Version 6.1.1.
- Ctrl+Tab / Ctrl+Shift+Tab collect chats on every launch.
- Fix Ctrl+Tab / Ctrl+Shift+Tab shortcut override.
- Fix possible crashes in saved music.
- Fix webview error label alignment.
2025-09-01 17:53:59 +04:00
John Preston
3419b49381 Hide gift value details tooltips on click. 2025-09-01 17:52:15 +04:00
John Preston
ec5725d8de Fix finalizing intersecting quotes. 2025-09-01 17:34:27 +04:00
John Preston
9df98352a8 Show correct error on gift limit reaching. 2025-09-01 17:14:55 +04:00
John Preston
c0c5ad21b6 Don't push recent peers to chat switch. 2025-09-01 16:03:30 +04:00
John Preston
4a23da6ce1 Fix build with GCC. 2025-09-01 12:42:29 +04:00
John Preston
6d1e5243d8 Fix possible crash in recent chat switches. 2025-09-01 11:58:05 +04:00
John Preston
c52a31384e Fix couple of possible crashes in saved music. 2025-09-01 11:57:19 +04:00
John Preston
36447eb1e3 Try fixing macOS action build. 2025-09-01 11:28:52 +04:00
John Preston
811dfee42c Separately bought upgrade doesn't auto-add details. 2025-09-01 11:23:33 +04:00
John Preston
b075bb9f4e Fix checkbox in background settings. 2025-09-01 10:59:54 +04:00
John Preston
00919f3232 Support arrows in chat switch. 2025-09-01 10:27:55 +04:00
John Preston
6dcd52deb5 Support all userpic types in Switch. 2025-09-01 10:27:55 +04:00
John Preston
edc70e9acb Improve phrases for currency switching. 2025-09-01 10:27:55 +04:00
John Preston
4ad12b6862 Fix alignment of webview crashed error. 2025-09-01 10:27:55 +04:00
John Preston
d63f3b6da1 Fix ctrl+tab/ctrl+shift+tab as overriden shortcuts. 2025-09-01 10:27:55 +04:00
John Preston
84c70a0905 Suggest upgrading next gift. 2025-09-01 10:27:55 +04:00
GitHub Action
8f65a7ac19 Update User-Agent for DNS to Chrome 139.0.0.0. 2025-09-01 10:26:56 +04:00
dependabot[bot]
c78262be91 Bump endersonmenezes/free-disk-space from 2.1.0 to 2.1.1
Bumps [endersonmenezes/free-disk-space](https://github.com/endersonmenezes/free-disk-space) from 2.1.0 to 2.1.1.
- [Release notes](https://github.com/endersonmenezes/free-disk-space/releases)
- [Commits](dd13eb48e7...713d134e24)

---
updated-dependencies:
- dependency-name: endersonmenezes/free-disk-space
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 10:26:29 +04:00
dependabot[bot]
cb51238bfc Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 10:26:03 +04:00
John Preston
87f873c8b6 Version 6.1.
- Music on Profiles.
- Gift Themes.
- Gift Value Information.
- Upgrading Gifts for Other Users.
2025-09-01 00:05:29 +04:00
John Preston
a37528b377 Fix crash in premium preview. 2025-09-01 00:05:29 +04:00
John Preston
51a58182ee Use saved music as is for now. 2025-09-01 00:05:29 +04:00
John Preston
cc4b768f54 Implement nice gift theme message layout. 2025-08-31 23:04:49 +04:00
John Preston
b016be6eb5 Fix emoji repaint crashing. 2025-08-31 22:18:17 +04:00
John Preston
881d73d4ab Fix build with MSVC. 2025-08-31 22:18:17 +04:00
John Preston
8859e352f9 Fix crash with widget double delete. 2025-08-31 22:06:04 +04:00
John Preston
5b0fc5b97b Fix build with Xcode. 2025-08-31 20:53:24 +04:00
John Preston
76cc59acab Show gift sticker in the background. 2025-08-31 20:53:12 +04:00
John Preston
e792088ceb Insert gift pattern symbols in background. 2025-08-31 20:53:12 +04:00
John Preston
1dc70d5a8d Load gift themes while scrolling. 2025-08-31 20:53:12 +04:00
John Preston
e876a0f6bd Set gift as theme from gift view. 2025-08-31 20:53:12 +04:00
John Preston
50450de3e4 Confirm transfer gift theme. 2025-08-31 20:53:12 +04:00
John Preston
c8abc84c3c Put gift themes in beginning. 2025-08-31 20:53:12 +04:00
John Preston
1f3996032c Fix theme preview pattern loading. 2025-08-31 20:53:12 +04:00
John Preston
b868cfdca9 Fix pattern caching on themed chat open. 2025-08-31 20:53:12 +04:00
John Preston
d51944e6a5 Update API scheme on layer 214. 2025-08-31 20:53:12 +04:00
John Preston
4419ba55e8 Start gift theme background parsing. 2025-08-31 20:53:12 +04:00
John Preston
9e8ae54821 Update API scheme to layer 214. Start themes. 2025-08-31 20:53:12 +04:00
John Preston
4ed266780a Fix emoji status texts. 2025-08-31 20:53:12 +04:00
John Preston
46886b4dcc Support channel direct messages links. 2025-08-31 20:53:12 +04:00
John Preston
1e2531f0b1 Support locked gifts. 2025-08-31 20:53:12 +04:00
John Preston
0e43fd4d00 Update API scheme on layer 213. 2025-08-31 20:53:12 +04:00
John Preston
10448bcc3d Support fileref refresh in saved music. 2025-08-31 20:53:12 +04:00
John Preston
4f1c2788b8 Improve phrasing for saved music. 2025-08-31 20:53:11 +04:00
John Preston
dbaa7b5e67 Allow forward / delete saved music. 2025-08-31 20:53:11 +04:00
John Preston
6211b7733d Support saved music playlist. 2025-08-31 20:53:11 +04:00
John Preston
0d6ea0845e Make nice music button in profile. 2025-08-31 20:53:11 +04:00
John Preston
b8e10fb34b Proof-of-concept saved music API support. 2025-08-31 20:53:11 +04:00
John Preston
b9c6e595d7 Update API scheme on layer 213. 2025-08-31 20:53:11 +04:00
John Preston
7d701d3e9c Fix upgrading of gifts with gifted upgrade. 2025-08-31 20:53:11 +04:00
John Preston
92d9c3c92b Finish gift value display. 2025-08-31 20:53:11 +04:00
John Preston
7007977891 Reuse some table values in gift table. 2025-08-31 20:53:11 +04:00
John Preston
9f5d24bbc9 Start gift value information display. 2025-08-31 20:53:11 +04:00
John Preston
2834a83eec Update API scheme on layer 212. 2025-08-31 20:53:11 +04:00
John Preston
eb82473395 Update API scheme on layer 212, gift upgrades. 2025-08-31 20:53:11 +04:00
John Preston
4a33d3227e Suggest upgrading next gift. 2025-08-31 20:53:11 +04:00
John Preston
235456e18e Update API scheme to layer 212. 2025-08-31 20:53:11 +04:00
23rd
1f9e532fbc Added link to info to box about sponsored messages. 2025-08-31 00:34:07 +03:00
23rd
8bc2d3184a Added lottie icon to transcribe voices while loading. 2025-08-30 23:39:36 +03:00
23rd
9ef54d1218 Added LottieCustomEmoji. 2025-08-30 23:39:36 +03:00
23rd
7e48cb97b0 Fixed first frame animation of opening schedule section for send button. 2025-08-30 23:19:40 +03:00
23rd
a226f0b58c Added toasts after review of unconfirmed authorizations. 2025-08-30 23:19:40 +03:00
23rd
65fd47a082 Fixed handle of dialogs resize for unconfirmed authorizations. 2025-08-30 23:19:40 +03:00
23rd
600b7d1d54 Slightly improved generation of stars in low credits balance list. 2025-08-30 23:19:40 +03:00
23rd
b8f4d4877e Added loading animation to list of options for low credits balance. 2025-08-30 23:19:40 +03:00
23rd
6a114e1275 Added ability to provide to loading text element style::TextStyle. 2025-08-30 23:19:40 +03:00
23rd
5d3d8640e3 Added unconfirmed authorizations to top bar suggestions in dialogs. 2025-08-30 23:19:40 +03:00
23rd
f09d2d22eb Added api support of new unconfirmed authorizations. 2025-08-30 23:19:40 +03:00
23rd
94ccd8f8b6 Added ability to store unconfirmed authorizations. 2025-08-30 23:19:40 +03:00
23rd
c96ce890d6 Added initial struct data for unreviewed authorizations. 2025-08-30 23:19:40 +03:00
23rd
de55be397b Improved style of withdrawal button in credits settings. 2025-08-30 23:19:40 +03:00
23rd
1420714cae Fixed display of "Show more" button in channel currency earn list. 2025-08-30 23:19:40 +03:00
23rd
b15305bc69 Respected localized number format in statistics. 2025-08-30 23:19:40 +03:00
23rd
db25b111e0 Fixed display of currency minor part from earn stats in some cases. 2025-08-30 23:19:40 +03:00
23rd
eeea9932ed Removed simple colorizing of query of hash or cashtag in found messages. 2025-08-30 23:19:40 +03:00
23rd
c710e9a54d Fixed display of label in self destruction box.
Fixed #29694.
2025-08-30 23:19:40 +03:00
23rd
62613e7da1 Added support of custom brush to loading element for peer list. 2025-08-30 23:19:40 +03:00
23rd
946b597471 Added support of custom bg to loading element for peer list. 2025-08-30 23:19:40 +03:00
23rd
691c55bedd Simplified master branch updater Github Action. 2025-08-30 23:19:40 +03:00
23rd
8387969467 Removed unused trigger for Github CI that updates user-agent for DNS. 2025-08-30 23:19:40 +03:00
23rd
90d21375c8 Removed ability to create todo lists in replies chat. 2025-08-30 23:19:40 +03:00
23rd
86daf2a9dc Removed ability to clear history from replies chat. 2025-08-30 23:19:40 +03:00
23rd
90473957cb Added process of error when collectible info can't be revealed. 2025-08-30 23:19:40 +03:00
23rd
3549c00141 Added ability to forward to Saved Messages on fast action with Ctrl. 2025-08-30 23:19:40 +03:00
23rd
1c1d13545b Added special check of balance on channel earn out just in case. 2025-08-30 23:19:40 +03:00
23rd
f1b3db89fb Fixed hover rect of entry item in channel earn history. 2025-08-30 23:19:40 +03:00
23rd
8c77baca6f Fixed wrong focus while recording voice in sections. 2025-08-30 23:19:40 +03:00
Ilya Fedin
36a40d97a7 Update submodules 2025-08-30 17:50:39 +04:00
Ilya Fedin
1eb9b40607 Update Qt to 6.9.2 2025-08-30 17:50:39 +04:00
Ilya Fedin
05c10e3f57 Switch patches to nil plugin in snap 2025-08-30 16:04:57 +04:00
Ilya Fedin
0cf3325655 Fix macOS action 2025-08-26 07:48:17 +04:00
Ilya Fedin
48525de714 Restore icon key in snapcraft.yaml
Looks like it didn't help with themed icon after all and snapcraft chooses a 64x64 icon without it which looks blurry with HiDPI
2025-08-23 19:58:56 -07:00
John Preston
7e15722eab Beta version 6.0.3.
- Ctrl+Tab / Ctrl+Shift+Tab for last opened chats switching.
- New topic dividers for groups with topics and tabs.
- Adjust volume of notification sounds.
- Show stars required for the next rating level.
- IV support on Linux (in case WebView works).
2025-08-22 21:17:48 +04:00
John Preston
719c209c7b Fix build with Xcode. 2025-08-22 21:17:48 +04:00
John Preston
d05ad44b84 Fix build with GCC. 2025-08-22 21:15:53 +04:00
Ilya Fedin
b352c97479 Switch from custom URI scheme to local HTTP server for webview on Linux 2025-08-22 18:05:11 +04:00
Ilya Fedin
063085a6bb Format Linux webview socket path using std::format 2025-08-22 18:05:11 +04:00
Ilya Fedin
b4bca16109 Get rid of wayland-scanner downgrade 2025-08-22 17:48:43 +04:00
John Preston
03770c52fe Support floating topic bars in forums. 2025-08-22 13:13:20 +04:00
John Preston
10fe5cdd5d Keep recent peers userpics in memory. 2025-08-22 13:06:04 +04:00
John Preston
57d459b917 Show nice topic/sublist userpics. 2025-08-22 13:06:03 +04:00
John Preston
fe26594f12 Improve Ctrl+Tab switch design. 2025-08-22 13:05:27 +04:00
John Preston
0d8065fc1f First attempt of Ctrl+Tab/Ctrl+Shift+Tab UI. 2025-08-22 13:05:26 +04:00
John Preston
a3cdae1e94 Fix refreshing story file reference. 2025-08-22 13:05:26 +04:00
John Preston
29d77b649b Nice selection of gifts for a collection. 2025-08-22 13:05:26 +04:00
John Preston
9e190cee81 Show next-level stars in rating. 2025-08-22 13:05:26 +04:00
John Preston
687bfd0f17 Remove some FixedHeightWidget-s. 2025-08-22 13:01:49 +04:00
23rd
7d7df4f749 Fixed display of about text in low credits balance box in some cases. 2025-08-20 12:40:16 +03:00
23rd
958dede319 Fixed active color of recording voice button. 2025-08-19 20:51:32 +03:00
23rd
76e814944d Added shortcuts to start recording of voice or round message.
Fixed #29633.
2025-08-19 16:52:48 +03:00
23rd
fbc1d75e9a Added ability to start and lock voice recording immediately. 2025-08-19 16:43:47 +03:00
23rd
b3c7ce05dc Added ability to send recording voice with submit key. 2025-08-19 16:43:47 +03:00
23rd
feea881e09 Slightly improved position of tooltip for voice record bar. 2025-08-19 13:21:51 +03:00
23rd
b978bc4876 Added ability to bottom scroll in HistoryView::Chat section with submit.
Fixed #29662.
2025-08-19 12:34:46 +03:00
23rd
f84181e7a5 Added event for scrolling to bottom to compose controls. 2025-08-19 12:33:38 +03:00
John Preston
313ae0f86c Remove CenterWrap layout. 2025-08-18 17:55:20 +04:00
John Preston
a39c018359 Scroll to top on global posts search. 2025-08-18 17:25:31 +04:00
John Preston
a09f57d908 Fix natural width for LabelWithNumbers. 2025-08-18 17:25:31 +04:00
John Preston
596828cf78 Fix webview blocking popups. 2025-08-18 17:25:31 +04:00
23rd
44843aa9cd Added hint about archive and its features. 2025-08-18 13:26:26 +03:00
23rd
5f930cc4d1 Added initial ability to rate voice transcriptions. 2025-08-18 13:26:23 +03:00
23rd
7defad5d95 Added ability to clear history for channels and megagroups.
Fixed #28778.
2025-08-17 14:47:49 +03:00
23rd
707af8a295 Got rid Ui::CreateLabelWithCustomEmoji. 2025-08-17 14:47:49 +03:00
23rd
e0fb9ffbb0 Added support of setting up of login email from intro. 2025-08-17 14:47:49 +03:00
23rd
d614de6f5e Fixed display of error in cloud password section with new naturalWidth. 2025-08-17 14:47:49 +03:00
Ilya Fedin
86b94b4723 Change notification volume visibility on support change
Cross platform VolumeSupported wrapper
2025-08-17 14:47:49 +03:00
23rd
5070300050 Added ability to test on place volume of notifications. 2025-08-17 14:47:49 +03:00
23rd
1919546441 Added ability to change volume of specific notifications from settings. 2025-08-17 14:47:49 +03:00
23rd
1c3cd8d44b Added ability to change master volume of notifications from settings. 2025-08-17 14:47:49 +03:00
23rd
292296266f Added convenient utils to pass and change notifications volume from ui. 2025-08-17 14:47:49 +03:00
23rd
a3e8848bc8 Added ability to check if OS has support of notifications volume. 2025-08-17 14:47:49 +03:00
23rd
ced146fc63 Added session-specific settings for volume of notifications for peers. 2025-08-17 14:47:49 +03:00
23rd
6ed79f6a0d Added global settings for master volume of notifications. 2025-08-17 14:47:49 +03:00
23rd
15e4d86e92 Added ability to override volume in media audio tracks. 2025-08-17 14:47:49 +03:00
23rd
5a29a7d2a3 Moved out DefaultNotify to data_peer_notify_settings. 2025-08-17 14:47:49 +03:00
23rd
034740ce46 Removed unused PeerListWidget. 2025-08-17 14:47:49 +03:00
23rd
a2847246e6 Replaced custom GroupMembersWidget with PeerList. 2025-08-17 14:47:49 +03:00
23rd
04479ad660 Moved out GroupMembersWidget to correspond file and namespace. 2025-08-17 14:47:49 +03:00
23rd
35d2fff593 Added initial support of highlighting for found query in quotes. 2025-08-17 14:47:49 +03:00
23rd
2b93fe9a30 Added simple colorizing of query in found messages from compose search. 2025-08-17 14:47:49 +03:00
23rd
5c33a2bd5c Added simple colorizing of query in found messages. 2025-08-17 14:47:49 +03:00
23rd
a28f113105 Moved FindSearchQueryHighlight to use as util. 2025-08-17 14:47:49 +03:00
23rd
eb7976a2ef Replaced alignment of title bar with left side for macOS 26. 2025-08-17 14:47:49 +03:00
23rd
15db1c0c30 Added ability to withdrawal personal currency balance. 2025-08-17 14:47:49 +03:00
23rd
2b83c95869 Moved out ui util for channel earn list to static function. 2025-08-17 14:47:49 +03:00
dependabot[bot]
273d5596d7 Bump endersonmenezes/free-disk-space
Bumps [endersonmenezes/free-disk-space](https://github.com/endersonmenezes/free-disk-space) from 4cae28d0d8e716a770938d92630f23db5184f61f to dd13eb48e709830a7ec4e50692e841be6b400d90.
- [Release notes](https://github.com/endersonmenezes/free-disk-space/releases)
- [Commits](4cae28d0d8...dd13eb48e7)

---
updated-dependencies:
- dependency-name: endersonmenezes/free-disk-space
  dependency-version: dd13eb48e709830a7ec4e50692e841be6b400d90
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-15 17:21:13 +04:00
Ilya Fedin
b423dab152 Fix Windows action execution on SDK update 2025-08-15 17:20:47 +04:00
Ilya Fedin
1b104bcf29 Update Windows SDK version 2025-08-15 17:20:47 +04:00
John Preston
5cad9a8c44 Fix build on layer 211. 2025-08-15 09:32:40 +04:00
John Preston
ec8a475a2c Fix top bar selection label resizing. 2025-08-14 18:45:52 +04:00
John Preston
e656cb8118 Fix vertical layout once again. 2025-08-14 18:30:17 +04:00
John Preston
7f2a0b6630 Scroll a bit further when switching tabs. 2025-08-14 18:30:01 +04:00
John Preston
f9bf40a771 Fix crash in forum removal with new tabs. 2025-08-14 18:30:01 +04:00
John Preston
96360619e1 Add some asserts in stats. 2025-08-14 18:30:01 +04:00
John Preston
4cefc21819 Close forum when searching in different chat. 2025-08-14 18:30:01 +04:00
Ilya Fedin
192a56ee15 Shorter notifications proxy check for Linux notifications 2025-08-13 11:19:38 +04:00
John Preston
cf16472dd0 Fix user profiles. 2025-08-13 11:18:34 +04:00
John Preston
b2fb2d5821 Attempt to fix the naturalWidth feature. 2025-08-13 11:18:34 +04:00
John Preston
c939eda7bb Hide "Use for calls" in Socks5 while not supported. 2025-08-13 11:18:34 +04:00
John Preston
428e059895 Write unknown cons to mtproto logs. 2025-08-13 11:18:34 +04:00
John Preston
1b4ea2e9c6 Use Api::ParseTextWithEntities more. 2025-08-13 11:18:34 +04:00
John Preston
d60bfa238f Merge TWidget* into Ui::RpWidget*. 2025-08-11 13:55:16 +04:00
John Preston
cc98f7da36 Fix topic unread count badges. 2025-08-11 10:36:26 +04:00
John Preston
87cdc22990 Fix marking read in new forum layout. 2025-08-11 10:36:26 +04:00
John Preston
60f6ea3252 Show informative empty posts search. 2025-08-11 10:29:11 +04:00
John Preston
86cffae001 Remove unused function. 2025-08-11 10:29:11 +04:00
John Preston
77cec0e338 Make big Upgrade button for gifts. 2025-08-11 10:29:11 +04:00
John Preston
ee85bb9a1b Improve rating layout. 2025-08-11 10:29:11 +04:00
John Preston
bf0b85afd1 Improve posts search transaction entry view. 2025-08-11 10:29:11 +04:00
John Preston
5473696491 Fix dice-type game display. 2025-08-11 10:29:11 +04:00
Ilya Fedin
0bc59a82ba Use symbolic links for icons in snap 2025-08-09 15:44:08 +04:00
Ilya Fedin
a8430d8ecf Self-build openh264 in snap for lesser package size 2025-08-09 15:44:08 +04:00
Ilya Fedin
9672b2ec23 Use double dash consistently in snap ldflags 2025-08-09 15:44:08 +04:00
Ilya Fedin
60447f073f Partially revert "Move packages to a separate snap part"
This partially reverts commit ef2e9406c7 restoring per-part build packages so changes to them don't lead to rebuild of all parts.
2025-08-09 10:39:48 +04:00
Ilya Fedin
62329c104c Fix accidentally broken CMAKE_INSTALL_PREFIX in snap
Regression was introduced in a6a8363527
2025-08-09 10:39:48 +04:00
John Preston
536884bb46 Fix build with new Xcode. 2025-08-08 11:26:39 +04:00
John Preston
efb213fb9f Fix build with latest Xcode. 2025-08-08 09:52:57 +04:00
Ilya Fedin
02b43c9375 Remove systemd-detect-virt from snap
It could be used from the core snap since hardware-observe plug was connected
2025-08-08 09:08:05 +04:00
Ilya Fedin
9a2679efaa Remove unity7 plug from snap
Looks like the desktop plug has everything needed since snapd 2.67
2025-08-08 09:07:53 +04:00
Ilya Fedin
00a396c3e7 Fix stage paths in snap 2025-08-06 07:43:33 +04:00
John Preston
b4272c306d Get rid of registerImageEmoji/registerInternalEmoji. 2025-08-04 22:27:08 +04:00
John Preston
b876605e93 Remove per-star options in giveaway creation. 2025-08-04 16:02:01 +04:00
John Preston
7f896a9f40 Use better ton icon in strings. 2025-08-04 12:50:24 +04:00
John Preston
a96874ac55 Allow '@' in search posts queries. 2025-08-04 11:51:42 +04:00
John Preston
1f8d3ed911 Fix incorrect filesize check.
Fixes #29630.
2025-08-04 11:46:19 +04:00
23rd
56be0ef4be Fixed incorrect state of disabled calls for account in notifications. 2025-08-04 11:15:44 +04:00
John Preston
67079545b3 Ease filtering on posts search queries. 2025-08-04 11:15:09 +04:00
689 changed files with 32993 additions and 8682 deletions

View File

@@ -17,7 +17,7 @@ jobs:
steps:
- name: Clone.
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive

View File

@@ -59,7 +59,7 @@ jobs:
steps:
- name: Clone.
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive

View File

@@ -40,7 +40,7 @@ jobs:
macos:
name: MacOS
runs-on: macos-13
runs-on: macos-15-intel
strategy:
matrix:
@@ -56,7 +56,7 @@ jobs:
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
- name: Clone.
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive
path: ${{ env.REPO_NAME }}

View File

@@ -60,7 +60,7 @@ jobs:
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
- name: Clone.
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive
path: ${{ env.REPO_NAME }}
@@ -69,7 +69,7 @@ jobs:
run: |
brew update
brew upgrade || true
brew install ada-url autoconf automake boost cmake ffmpeg jpeg-xl libavif libheif libtool openal-soft openh264 openssl opus ninja pkg-config python qt yasm xz
brew install ada-url autoconf automake boost cmake ffmpeg@6 jpeg-xl libavif libheif libtool openal-soft openh264 openssl opus ninja pkg-config python qtbase qtimageformats qtsvg xz
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcodebuild -version > CACHE_KEY.txt
@@ -82,6 +82,7 @@ jobs:
fi
echo "CACHE_KEY=`md5 -q CACHE_KEY.txt`" >> $GITHUB_ENV
echo "MACOSX_DEPLOYMENT_TARGET=$(grep 'set(QT_SUPPORTED_MIN_MACOS_VERSION' /opt/homebrew/Cellar/qtbase/*/lib/cmake/Qt6/Qt6ConfigExtras.cmake | sed -E 's/^.*"(.*)"\)$/\1/')" >> $GITHUB_ENV
echo "LibrariesPath=`pwd`" >> $GITHUB_ENV
curl -o tg_owt-version.json https://api.github.com/repos/desktop-app/tg_owt/git/refs/heads/master
@@ -114,7 +115,8 @@ jobs:
cmake -Bbuild -GNinja . \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_C_FLAGS_DEBUG="" \
-DCMAKE_CXX_FLAGS_DEBUG=""
-DCMAKE_CXX_FLAGS_DEBUG="" \
-DCMAKE_DISABLE_FIND_PACKAGE_absl=ON
cmake --build build --parallel

View File

@@ -5,33 +5,9 @@ on:
types: released
jobs:
updater:
User-agent:
runs-on: ubuntu-latest
env:
SKIP: "0"
to_branch: "master"
steps:
- uses: actions/checkout@v4
- uses: desktop-app/action_code_updater@master
with:
fetch-depth: 0
if: env.SKIP == '0'
- name: Push the code to the master branch.
if: env.SKIP == '0'
run: |
token=${{ secrets.TOKEN_FOR_MASTER_UPDATER }}
if [ -z "${token}" ]; then
echo "Token is unset. Nothing to do."
exit 0
fi
url=https://x-access-token:$token@github.com/$GITHUB_REPOSITORY
latest_tag=$(git describe --tags --abbrev=0)
echo "Latest tag: $latest_tag"
git remote set-url origin $url
git remote -v
git checkout master
git merge $latest_tag
git push origin HEAD:refs/heads/$to_branch
echo "Done!"
type: "dev-to-master"

View File

@@ -47,7 +47,7 @@ jobs:
steps:
- name: Clone.
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
fetch-depth: 0
submodules: recursive
@@ -61,7 +61,7 @@ jobs:
sudo lxd waitready
- name: Free up some disk space.
uses: endersonmenezes/free-disk-space@4cae28d0d8e716a770938d92630f23db5184f61f
uses: endersonmenezes/free-disk-space@713d134e243b926eba4a5cce0cf608bfd1efb89a
with:
remove_android: true
remove_dotnet: true

View File

@@ -7,7 +7,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
stale-issue-message: |
Hey there!

View File

@@ -6,8 +6,6 @@ on:
schedule:
# At 00:00 on day-of-month 1.
- cron: "0 0 1 * *"
pull_request_target:
types: [closed]
jobs:
User-agent:

View File

@@ -4,8 +4,8 @@ on:
push:
paths-ignore:
- 'docs/**'
- '!docs/building-win*.md'
- '**.md'
- '!docs/building-win*.md'
- 'changelog.txt'
- 'LEGAL'
- 'LICENSE'
@@ -23,8 +23,8 @@ on:
pull_request:
paths-ignore:
- 'docs/**'
- '!docs/building-win*.md'
- '**.md'
- '!docs/building-win*.md'
- 'changelog.txt'
- 'LEGAL'
- 'LICENSE'
@@ -72,7 +72,7 @@ jobs:
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
- name: Clone.
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive
path: ${{ env.TBUILD }}\${{ env.REPO_NAME }}

View File

@@ -45,7 +45,7 @@ Version **1.8.15** was the last that supports older systems
* Qt 6 ([LGPL](http://doc.qt.io/qt-6/lgpl.html)) and Qt 5.15 ([LGPL](http://doc.qt.io/qt-5/lgpl.html)) slightly patched
* OpenSSL 3.2.1 ([Apache License 2.0](https://www.openssl.org/source/apache-license-2.0.txt))
* WebRTC ([New BSD License](https://github.com/desktop-app/tg_owt/blob/master/LICENSE))
* zlib 1.2.11 ([zlib License](http://www.zlib.net/zlib_license.html))
* zlib ([zlib License](http://www.zlib.net/zlib_license.html))
* LZMA SDK 9.20 ([public domain](http://www.7-zip.org/sdk.html))
* liblzma ([public domain](http://tukaani.org/xz/))
* Google Breakpad ([License](https://chromium.googlesource.com/breakpad/breakpad/+/master/LICENSE))

View File

@@ -35,7 +35,7 @@ include(cmake/td_mtproto.cmake)
include(cmake/td_scheme.cmake)
include(cmake/td_tde2e.cmake)
include(cmake/td_ui.cmake)
include(cmake/generate_appdata_changelog.cmake)
include(cmake/generate_appstream_changelog.cmake)
if (DESKTOP_APP_TEST_APPS)
include(cmake/tests.cmake)
@@ -363,6 +363,14 @@ PRIVATE
calls/group/calls_group_members_row.h
calls/group/calls_group_menu.cpp
calls/group/calls_group_menu.h
calls/group/calls_group_message_encryption.cpp
calls/group/calls_group_message_encryption.h
calls/group/calls_group_message_field.cpp
calls/group/calls_group_message_field.h
calls/group/calls_group_messages.cpp
calls/group/calls_group_messages.h
calls/group/calls_group_messages_ui.cpp
calls/group/calls_group_messages_ui.h
calls/group/calls_group_panel.cpp
calls/group/calls_group_panel.h
calls/group/calls_group_rtmp.cpp
@@ -523,6 +531,8 @@ PRIVATE
data/notify/data_notify_settings.h
data/notify/data_peer_notify_settings.cpp
data/notify/data_peer_notify_settings.h
data/notify/data_peer_notify_volume.cpp
data/notify/data_peer_notify_volume.h
data/stickers/data_custom_emoji.cpp
data/stickers/data_custom_emoji.h
data/stickers/data_stickers_set.cpp
@@ -634,6 +644,8 @@ PRIVATE
data/data_report.h
data/data_saved_messages.cpp
data/data_saved_messages.h
data/data_saved_music.cpp
data/data_saved_music.h
data/data_saved_sublist.cpp
data/data_saved_sublist.h
data/data_search_controller.cpp
@@ -771,6 +783,8 @@ PRIVATE
history/view/controls/history_view_voice_record_bar.h
history/view/controls/history_view_webpage_processor.cpp
history/view/controls/history_view_webpage_processor.h
history/view/media/history_view_birthday_suggestion.cpp
history/view/media/history_view_birthday_suggestion.h
history/view/media/history_view_call.cpp
history/view/media/history_view_call.h
history/view/media/history_view_contact.cpp
@@ -813,6 +827,8 @@ PRIVATE
history/view/media/history_view_poll.h
history/view/media/history_view_premium_gift.cpp
history/view/media/history_view_premium_gift.h
history/view/media/history_view_save_document_action.cpp
history/view/media/history_view_save_document_action.h
history/view/media/history_view_service_box.cpp
history/view/media/history_view_service_box.h
history/view/media/history_view_similar_channels.cpp
@@ -876,6 +892,8 @@ PRIVATE
history/view/history_view_fake_items.h
history/view/history_view_group_call_bar.cpp
history/view/history_view_group_call_bar.h
history/view/history_view_group_members_widget.cpp
history/view/history_view_group_members_widget.h
history/view/history_view_item_preview.h
history/view/history_view_list_widget.cpp
history/view/history_view_list_widget.h
@@ -900,6 +918,8 @@ PRIVATE
history/view/history_view_schedule_box.h
history/view/history_view_scheduled_section.cpp
history/view/history_view_scheduled_section.h
history/view/history_view_self_forwards_tagger.cpp
history/view/history_view_self_forwards_tagger.h
history/view/history_view_send_action.cpp
history/view/history_view_send_action.h
history/view/history_view_service_message.cpp
@@ -944,6 +964,8 @@ PRIVATE
history/history_inner_widget.h
history/history_location_manager.cpp
history/history_location_manager.h
history/history_streamed_drafts.cpp
history/history_streamed_drafts.h
history/history_translation.cpp
history/history_translation.h
history/history_unread_things.cpp
@@ -1022,6 +1044,8 @@ PRIVATE
info/polls/info_polls_results_widget.h
info/profile/info_profile_actions.cpp
info/profile/info_profile_actions.h
info/profile/info_profile_badge_tooltip.cpp
info/profile/info_profile_badge_tooltip.h
info/profile/info_profile_badge.cpp
info/profile/info_profile_badge.h
info/profile/info_profile_cover.cpp
@@ -1036,8 +1060,10 @@ PRIVATE
info/profile/info_profile_members_controllers.h
info/profile/info_profile_phone_menu.cpp
info/profile/info_profile_phone_menu.h
info/profile/info_profile_text.cpp
info/profile/info_profile_text.h
info/profile/info_profile_status_label.cpp
info/profile/info_profile_status_label.h
info/profile/info_profile_top_bar.cpp
info/profile/info_profile_top_bar.h
info/profile/info_profile_values.cpp
info/profile/info_profile_values.h
info/profile/info_profile_widget.cpp
@@ -1046,6 +1072,11 @@ PRIVATE
info/reactions_list/info_reactions_list_widget.h
info/requests_list/info_requests_list_widget.cpp
info/requests_list/info_requests_list_widget.h
info/saved/info_saved_music_common.h
info/saved/info_saved_music_provider.cpp
info/saved/info_saved_music_provider.h
info/saved/info_saved_music_widget.cpp
info/saved/info_saved_music_widget.h
info/saved/info_saved_sublists_widget.cpp
info/saved/info_saved_sublists_widget.h
info/settings/info_settings_widget.cpp
@@ -1119,6 +1150,8 @@ PRIVATE
inline_bots/inline_results_widget.h
intro/intro_code.cpp
intro/intro_code.h
intro/intro_email.cpp
intro/intro_email.h
intro/intro_password_check.cpp
intro/intro_password_check.h
intro/intro_phone.cpp
@@ -1274,6 +1307,8 @@ PRIVATE
menu/menu_antispam_validator.h
menu/menu_item_download_files.cpp
menu/menu_item_download_files.h
menu/menu_item_rate_transcribe_session.cpp
menu/menu_item_rate_transcribe_session.h
menu/menu_mute.cpp
menu/menu_mute.h
menu/menu_send.cpp
@@ -1307,6 +1342,8 @@ PRIVATE
mtproto/special_config_request.cpp
mtproto/special_config_request.h
mtproto/type_utils.h
overview/overview_checkbox.cpp
overview/overview_checkbox.h
overview/overview_layout.cpp
overview/overview_layout.h
overview/overview_layout_delegate.h
@@ -1427,10 +1464,6 @@ PRIVATE
platform/platform_window_title.h
profile/profile_back_button.cpp
profile/profile_back_button.h
profile/profile_block_group_members.cpp
profile/profile_block_group_members.h
profile/profile_block_peer_list.cpp
profile/profile_block_peer_list.h
profile/profile_block_widget.cpp
profile/profile_block_widget.h
profile/profile_cover_drop_area.cpp
@@ -1625,8 +1658,6 @@ PRIVATE
ui/text/format_song_document_name.h
ui/widgets/expandable_peer_list.cpp
ui/widgets/expandable_peer_list.h
ui/widgets/label_with_custom_emoji.cpp
ui/widgets/label_with_custom_emoji.h
ui/widgets/chat_filters_tabs_strip.cpp
ui/widgets/chat_filters_tabs_strip.h
ui/widgets/peer_bubble.cpp
@@ -1642,8 +1673,12 @@ PRIVATE
ui/item_text_options.cpp
ui/item_text_options.h
ui/resize_area.h
ui/top_background_gradient.cpp
ui/top_background_gradient.h
ui/unread_badge.cpp
ui/unread_badge.h
ui/peer/video_userpic_player.cpp
ui/peer/video_userpic_player.h
window/main_window.cpp
window/main_window.h
window/notifications_manager.cpp
@@ -1659,6 +1694,8 @@ PRIVATE
window/window_adaptive.h
window/window_chat_preview.cpp
window/window_chat_preview.h
window/window_chat_switch_process.cpp
window/window_chat_switch_process.h
window/window_connecting_widget.cpp
window/window_connecting_widget.h
window/window_controller.cpp
@@ -1780,6 +1817,8 @@ if (WIN32)
if (QT_VERSION LESS 6)
target_link_libraries(Telegram PRIVATE desktop-app::win_directx_helper)
endif()
target_link_options(Telegram PRIVATE /PDBPAGESIZE:8192)
elseif (APPLE)
if (NOT DESKTOP_APP_USE_PACKAGED)
target_link_libraries(Telegram PRIVATE desktop-app::external_iconv)
@@ -2115,7 +2154,7 @@ if (LINUX AND DESKTOP_APP_USE_PACKAGED)
include(GNUInstallDirs)
configure_file("../lib/xdg/org.telegram.desktop.service" "${CMAKE_CURRENT_BINARY_DIR}/org.telegram.desktop.service" @ONLY)
configure_file("../lib/xdg/org.telegram.desktop.metainfo.xml" "${CMAKE_CURRENT_BINARY_DIR}/org.telegram.desktop.metainfo.xml" @ONLY)
generate_appdata_changelog(Telegram "${CMAKE_SOURCE_DIR}/changelog.txt" "${CMAKE_CURRENT_BINARY_DIR}/org.telegram.desktop.metainfo.xml")
generate_appstream_changelog(Telegram "${CMAKE_SOURCE_DIR}/changelog.txt" "${CMAKE_CURRENT_BINARY_DIR}/org.telegram.desktop.metainfo.xml")
install(TARGETS Telegram RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(FILES "Resources/art/icon16.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/16x16/apps" RENAME "org.telegram.desktop.png")
install(FILES "Resources/art/icon32.png" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/32x32/apps" RENAME "org.telegram.desktop.png")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Icon / Mini / mini_ton_bold</title>
<g id="Icon-/-Mini-/-mini_ton_bold" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M12.5980305,2.7875 C13.2201476,2.7875 13.7244732,3.29182558 13.7244732,3.9139427 C13.7244732,4.11165014 13.6724374,4.30587532 13.5735947,4.47710133 L9.21676388,12.0244744 C8.80179975,12.7433201 7.88266529,12.9896647 7.16381961,12.5747006 C6.92829269,12.4387393 6.73407151,12.2414175 6.60185728,12.0037668 L2.40584723,4.46158062 C2.10339516,3.91793325 2.29892259,3.23203413 2.84256996,2.92958206 C3.01005587,2.83640316 3.19854713,2.7875 3.39020787,2.7875 L12.5980305,2.7875 Z M7.24956057,4.2875 L4.025,4.2875 L7.24956057,10.0835 L7.24956057,4.2875 Z M11.95,4.2875 L8.74956057,4.2875 L8.74956057,9.8255 L11.95,4.2875 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Icon / Menu / new_topic</title>
<g id="Icon-/-Menu-/-new_topic" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M12,3.15416667 C12.3865993,3.15416667 12.7,3.46756734 12.7,3.85416667 C12.7,4.24076599 12.3865993,4.55416667 12,4.55416667 L7.24826389,4.55416667 C5.76035508,4.55416667 4.55416667,5.76035508 4.55416667,7.24826389 L4.55416667,16.7517361 C4.55416667,18.2396449 5.76035508,19.4458333 7.24826389,19.4458333 L16.7517361,19.4458333 C18.2396449,19.4458333 19.4458333,18.2396449 19.4458333,16.7517361 L19.4458333,12 C19.4458333,11.6134007 19.759234,11.3 20.1458333,11.3 C20.5324327,11.3 20.8458333,11.6134007 20.8458333,12 L20.8458333,16.7517361 C20.8458333,19.0128436 19.0128436,20.8458333 16.7517361,20.8458333 L7.24826389,20.8458333 C4.98715643,20.8458333 3.15416667,19.0128436 3.15416667,16.7517361 L3.15416667,7.24826389 C3.15416667,4.98715643 4.98715643,3.15416667 7.24826389,3.15416667 L12,3.15416667 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M19.3511597,5.34872828 C20.2469248,6.24449337 20.2469248,7.69681554 19.3511597,8.59258064 L12.7489306,15.1948097 C12.4577752,15.4859651 12.0995331,15.7011118 11.7057162,15.8213249 L10.029497,16.3329929 C9.10119412,16.6163585 8.11894274,16.0935336 7.83557714,15.1652307 C7.71876473,14.7825544 7.73602986,14.3714738 7.88451862,13.99994 L8.70227653,11.9538276 C8.8286621,11.6375983 9.01800726,11.3503585 9.2588125,11.1095532 L15.5634724,4.80489335 C16.4592375,3.90912826 17.9115597,3.90912826 18.8073247,4.80489335 L19.3511597,5.34872828 Z M18.3612102,6.33867777 L17.8173753,5.79484285 C17.4683442,5.44581176 16.902453,5.44581176 16.5534219,5.79484285 L10.248762,12.0995027 C10.1421189,12.2061458 10.0582655,12.3333529 10.0022944,12.4733983 L9.18453646,14.5195106 C9.15433809,14.59507 9.15082685,14.678672 9.17458316,14.7564974 C9.23221162,14.9452877 9.43197346,15.0516153 9.62076372,14.9939869 L11.296983,14.4823189 C11.4713888,14.4290813 11.63004,14.3338014 11.7589811,14.2048602 L18.3612102,7.60263114 C18.7102413,7.25360006 18.7102413,6.68770886 18.3612102,6.33867777 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
<polygon id="Path" fill="#FFFFFF" fill-rule="nonzero" points="15.5907211 6.54669192 17.5755336 8.53150439 16.5855841 9.52145388 14.6007716 7.53664141"></polygon>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="48px" height="48px" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Mini / mini_gift_lock</title>
<g id="Mini-/-mini_gift_lock" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M34.6666667,26.3333333 C40.1895142,26.3333333 44.6666667,30.8104858 44.6666667,36.3333333 C44.6666667,41.8561808 40.1895142,46.3333333 34.6666667,46.3333333 C29.1438192,46.3333333 24.6666667,41.8561808 24.6666667,36.3333333 C24.6666667,30.8104858 29.1438192,26.3333333 34.6666667,26.3333333 Z M22,3.06666667 C27.8542183,3.06666667 32.6,7.81244832 32.6,13.6666667 L32.5999548,19.4672746 C34.7232323,19.9235567 36.4292218,21.5034006 37.0650949,23.5539779 C36.287246,23.4090943 35.4858038,23.3333333 34.6666667,23.3333333 C27.4869649,23.3333333 21.6666667,29.1536316 21.6666667,36.3333333 C21.6666667,38.3649522 22.1326999,40.2877232 22.9636948,42.0005746 L12.6666667,42 C9.35295817,42 6.66666667,39.3137085 6.66666667,36 L6.66666667,25.3333333 C6.66666667,22.454169 8.69461762,20.048658 11.4000452,19.4672746 L11.4,13.6666667 C11.4,7.81244832 16.1457817,3.06666667 22,3.06666667 Z M34.6666667,29.3061633 C33.7052821,29.3061633 32.9259259,30.0855195 32.9259259,31.0469041 L32.9259259,36.9308449 C32.9259259,37.7182476 33.2996271,38.4589206 33.9329602,38.9267797 L37.3333333,41.3922119 C38.1066056,41.9634476 39.1965447,41.7996646 39.7677804,41.0263923 L39.8381314,40.9238035 C40.323622,40.1593232 40.1416125,39.1383445 39.4019608,38.5919452 L36.4074074,36.4264726 L36.4074074,31.0469041 C36.4074074,30.0855195 35.6280512,29.3061633 34.6666667,29.3061633 Z M22,7.6 C18.6494725,7.6 15.9333333,10.3161392 15.9333333,13.6666667 L15.9326667,19.3326667 L28.0666667,19.3326667 L28.0666667,13.6666667 C28.0666667,10.3161392 25.3505275,7.6 22,7.6 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Icon / Menu / reorder</title>
<g id="Icon-/-Menu-/-reorder" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M20.4060728,15.0078431 C21.2543281,15.0078431 21.9419748,15.6954899 21.9419748,16.5437451 L21.9419748,19.064098 C21.9419748,19.9123532 21.2543281,20.6 20.4060728,20.6 L17.9103341,20.6 C17.0620789,20.6 16.3744321,19.9123532 16.3744321,19.064098 L16.3744321,16.5437451 C16.3744321,15.6954899 17.0620789,15.0078431 17.9103341,15.0078431 L20.4060728,15.0078431 Z M16.6624648,3.4 C18.1998993,3.4 19.4462362,4.64633689 19.4462362,6.18377135 L19.446,10.561 L21.5745455,8.42203928 C21.782239,8.21317523 22.105482,8.18912467 22.339778,8.35046222 L22.4230702,8.41965499 C22.6580423,8.65331023 22.6591098,9.03320772 22.4254545,9.26817977 L19.3380547,12.3729793 C19.0636746,12.6458372 18.6245193,12.6446032 18.3544177,12.3729793 L15.2670178,9.26817977 C15.0333625,9.03320772 15.03443,8.65331023 15.2694021,8.41965499 C15.5043741,8.18599974 15.8842716,8.18706723 16.1179268,8.42203928 L18.246,10.563 L18.2462362,6.18377135 C18.2462362,5.30907859 17.5371576,4.6 16.6624648,4.6 L6.36754271,4.6 C5.49284994,4.6 4.78377135,5.30907859 4.78377135,6.18377135 L4.783,15.007 L5.4316407,15.0078431 C6.27989595,15.0078431 6.96754271,15.6954899 6.96754271,16.5437451 L6.96754271,19.064098 C6.96754271,19.9123532 6.27989595,20.6 5.4316407,20.6 L2.93590201,20.6 C2.08764675,20.6 1.4,19.9123532 1.4,19.064098 L1.4,16.5437451 C1.4,15.6954899 2.08764675,15.0078431 2.93590201,15.0078431 L3.583,15.007 L3.58377135,6.18377135 C3.58377135,4.64633689 4.83010824,3.4 6.36754271,3.4 L16.6624648,3.4 Z M12.9188568,15.0078431 C13.767112,15.0078431 14.4547588,15.6954899 14.4547588,16.5437451 L14.4547588,19.064098 C14.4547588,19.9123532 13.767112,20.6 12.9188568,20.6 L10.4231181,20.6 C9.57486282,20.6 8.88721607,19.9123532 8.88721607,19.064098 L8.88721607,16.5437451 C8.88721607,15.6954899 9.57486282,15.0078431 10.4231181,15.0078431 L12.9188568,15.0078431 Z M20.4060728,16.2078431 L17.9103341,16.2078431 C17.7248206,16.2078431 17.5744321,16.3582316 17.5744321,16.5437451 L17.5744321,19.064098 C17.5744321,19.2496115 17.7248206,19.4 17.9103341,19.4 L20.4060728,19.4 C20.5915864,19.4 20.7419748,19.2496115 20.7419748,19.064098 L20.7419748,16.5437451 C20.7419748,16.3582316 20.5915864,16.2078431 20.4060728,16.2078431 Z M5.4316407,16.2078431 L2.93590201,16.2078431 C2.75038845,16.2078431 2.6,16.3582316 2.6,16.5437451 L2.6,19.064098 C2.6,19.2496115 2.75038845,19.4 2.93590201,19.4 L5.4316407,19.4 C5.61715425,19.4 5.76754271,19.2496115 5.76754271,19.064098 L5.76754271,16.5437451 C5.76754271,16.3582316 5.61715425,16.2078431 5.4316407,16.2078431 Z M12.9188568,16.2078431 L10.4231181,16.2078431 C10.2376045,16.2078431 10.0872161,16.3582316 10.0872161,16.5437451 L10.0872161,19.064098 C10.0872161,19.2496115 10.2376045,19.4 10.4231181,19.4 L12.9188568,19.4 C13.1043703,19.4 13.2547588,19.2496115 13.2547588,19.064098 L13.2547588,16.5437451 C13.2547588,16.3582316 13.1043703,16.2078431 12.9188568,16.2078431 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M19.035,15.184L16.561,14.901C15.786,14.771 14.725,15.259 13.376,16.365C13.315,16.416 13.142,16.533 12.95,16.54C12.764,16.547 12.56,16.444 12.493,16.408C10.162,15.134 8.734,13.687 7.467,11.306C7.435,11.247 7.356,11.086 7.38,10.938C7.402,10.802 7.524,10.676 7.567,10.624C8.595,9.364 9.108,8.299 9.108,7.429L8.826,4.974C8.709,3.99 7.881,3.25 6.887,3.25L5.202,3.25C4.101,3.25 3.185,4.166 3.254,5.267C3.77,13.586 10.424,20.23 18.733,20.746C19.834,20.815 20.75,19.899 20.75,18.798L20.75,17.113C20.76,16.129 20.019,15.301 19.035,15.184Z" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 649 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M11.157,13.843L11.157,21.158L7.506,21.158C6.265,21.158 5.26,20.152 5.26,18.911L5.26,13.843L11.157,13.843ZM18.741,13.829L18.74,18.911C18.74,20.152 17.735,21.158 16.494,21.158L12.842,21.158L12.842,13.843L18.6,13.843C18.648,13.843 18.695,13.838 18.741,13.829ZM14.727,3.208C15.308,3.208 15.832,3.33 16.301,3.575C16.77,3.819 17.144,4.158 17.423,4.591C17.702,5.025 17.841,5.519 17.841,6.075C17.841,6.454 17.768,6.802 17.622,7.119C17.492,7.402 17.319,7.652 17.104,7.871L17.037,7.935L19.302,7.935C19.923,7.935 20.426,8.438 20.426,9.058L20.426,11.313C20.426,11.933 19.923,12.436 19.302,12.436L18.74,12.436L18.741,12.45C18.695,12.441 18.648,12.436 18.6,12.436L12.842,12.436L12.842,7.951L11.16,7.951L11.16,6.729C11.16,6.118 10.977,5.631 10.611,5.268C10.245,4.905 9.804,4.723 9.287,4.723C8.8,4.723 8.403,4.853 8.097,5.114C7.79,5.375 7.637,5.736 7.637,6.197C7.637,6.668 7.827,7.078 8.207,7.427C8.521,7.715 8.94,7.885 9.464,7.935L11.157,7.935L11.157,12.436L4.698,12.436C4.077,12.436 3.574,11.933 3.574,11.313L3.574,9.058C3.574,8.438 4.077,7.935 4.698,7.935L6.849,7.935C6.603,7.702 6.408,7.43 6.265,7.119C6.119,6.802 6.046,6.454 6.046,6.075C6.046,5.519 6.185,5.025 6.464,4.591C6.743,4.158 7.118,3.819 7.59,3.575C8.061,3.33 8.585,3.208 9.16,3.208C9.8,3.208 10.369,3.371 10.868,3.698C11.367,4.025 11.727,4.487 11.948,5.085C12.169,4.487 12.527,4.025 13.023,3.698C13.519,3.371 14.087,3.208 14.727,3.208ZM14.608,4.723C14.087,4.723 13.643,4.905 13.276,5.268C12.91,5.631 12.843,6.118 12.843,6.729L12.842,7.935L14.423,7.935C14.909,7.888 15.305,7.739 15.61,7.487L15.679,7.427C16.059,7.078 16.249,6.668 16.249,6.197C16.249,5.736 16.096,5.375 15.79,5.114C15.484,4.853 15.09,4.723 14.608,4.723Z" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M17.176,12.972C19.682,12.972 21.713,15.004 21.713,17.509C21.713,20.015 19.682,22.046 17.176,22.046C14.67,22.046 12.639,20.015 12.639,17.509C12.639,15.004 14.67,12.972 17.176,12.972ZM11.343,12.729C11.998,12.729 12.619,12.78 13.209,12.881C11.869,14.011 11.019,15.701 11.019,17.59C11.019,18.624 11.273,19.598 11.723,20.453L5.218,20.453C4.358,20.453 3.759,20.317 3.422,20.046C3.085,19.774 2.917,19.391 2.917,18.895C2.917,18.245 3.113,17.562 3.505,16.845C3.897,16.128 4.462,15.459 5.2,14.836C5.938,14.214 6.824,13.707 7.86,13.316C8.895,12.925 10.056,12.729 11.343,12.729ZM17.176,14.593C16.848,14.593 16.582,14.858 16.582,15.186L16.582,16.915L14.853,16.915C14.525,16.915 14.259,17.181 14.259,17.509C14.259,17.837 14.525,18.103 14.853,18.103L16.582,18.103L16.582,19.832C16.582,20.16 16.848,20.426 17.176,20.426C17.504,20.426 17.77,20.16 17.77,19.832L17.77,18.103L19.499,18.103C19.827,18.103 20.093,17.837 20.093,17.509C20.093,17.181 19.827,16.915 19.499,16.915L17.77,16.915L17.77,15.186C17.77,14.858 17.504,14.593 17.176,14.593ZM11.343,10.974C12.117,10.974 12.822,10.784 13.459,10.405C14.096,10.025 14.605,9.514 14.985,8.872C15.365,8.229 15.556,7.507 15.556,6.706C15.556,5.934 15.364,5.233 14.98,4.605C14.596,3.976 14.085,3.476 13.446,3.105C12.807,2.733 12.106,2.548 11.343,2.548C10.579,2.548 9.878,2.735 9.239,3.111C8.601,3.486 8.089,3.989 7.705,4.621C7.322,5.253 7.13,5.953 7.13,6.722C7.133,7.513 7.325,8.229 7.705,8.872C8.085,9.514 8.595,10.025 9.234,10.405C9.873,10.784 10.576,10.974 11.343,10.974Z" fill="#FFFFFF" fill-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M12.329,3.574C13.94,3.574 15.245,4.88 15.245,6.491L15.245,7.463C15.245,8 14.81,8.435 14.273,8.435C13.736,8.435 13.301,8 13.301,7.463L13.301,6.491C13.301,5.954 12.866,5.519 12.329,5.519L6.171,5.519C5.634,5.519 5.199,5.954 5.199,6.491L5.199,17.509C5.199,18.046 5.634,18.481 6.171,18.481L12.329,18.481C12.866,18.481 13.301,18.046 13.301,17.509L13.301,16.537C13.301,16 13.736,15.565 14.273,15.565C14.81,15.565 15.245,16 15.245,16.537L15.245,17.509C15.245,19.12 13.94,20.426 12.329,20.426L6.171,20.426C4.56,20.426 3.255,19.12 3.255,17.509L3.255,6.491C3.255,4.88 4.56,3.574 6.171,3.574L12.329,3.574ZM19.045,7.945L21.927,11.13C22.374,11.624 22.374,12.376 21.927,12.87L19.045,16.055C18.685,16.453 18.07,16.484 17.672,16.124C17.274,15.763 17.243,15.149 17.603,14.751L19.212,12.972L10.06,12.972C9.523,12.972 9.088,12.537 9.088,12C9.088,11.463 9.523,11.028 10.06,11.028L19.212,11.028L17.603,9.249C17.257,8.867 17.272,8.285 17.626,7.921L17.672,7.876C18.07,7.516 18.685,7.547 19.045,7.945Z" fill="#FFFFFF" fill-rule="nonzero"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M12.009,2.759C17.307,2.759 21.602,6.688 21.602,11.533C21.602,16.379 17.307,20.307 12.009,20.307C10.566,20.307 9.197,20.016 7.969,19.494C7.602,19.784 7.273,20.004 6.98,20.154C6.092,20.609 5.496,20.772 4.144,20.914C3.778,20.952 3.534,20.625 3.819,20.34C4.452,19.708 4.793,18.577 4.966,17.49C3.384,15.925 2.417,13.833 2.417,11.533C2.417,6.688 6.711,2.759 12.009,2.759Z" fill="#FFFFFF" fill-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 505 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M11.922,2.528C12.663,2.528 13.264,3.129 13.264,3.87L13.264,4.492C16.232,5.216 18.32,7.681 18.32,10.805L18.32,14.987C18.32,15.133 18.373,15.273 18.47,15.382L19.678,16.735C20.342,17.382 19.668,18.491 18.731,18.491L5.261,18.491C4.324,18.491 3.661,17.382 4.324,16.735L5.532,15.382C5.629,15.273 5.682,15.133 5.682,14.987L5.682,10.805C5.682,7.735 7.675,5.317 10.556,4.538L10.556,3.87C10.556,3.151 11.121,2.564 11.831,2.529L11.922,2.528ZM12.001,21.472C13.159,21.472 14.107,20.558 14.107,19.525L9.895,19.525C9.895,20.558 10.832,21.472 12.001,21.472Z" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 661 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M12,2.833C17.063,2.833 21.167,6.937 21.167,12C21.167,17.063 17.063,21.167 12,21.167C6.937,21.167 2.833,17.063 2.833,12C2.833,6.937 6.937,2.833 12,2.833ZM12,14.444C11.347,14.444 10.813,14.957 10.779,15.602L10.778,15.689C10.778,16.364 11.325,16.911 12,16.911C12.653,16.911 13.187,16.398 13.221,15.754L13.222,15.667C13.222,14.992 12.675,14.444 12,14.444ZM12,7.111C11.404,7.111 10.922,7.594 10.922,8.19L10.922,11.995C10.922,12.591 11.404,13.074 12,13.074C12.596,13.074 13.078,12.591 13.078,11.995L13.078,8.19C13.078,7.594 12.596,7.111 12,7.111Z" fill="#FFFFFF" fill-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 680 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M14.107,19.525C14.107,20.558 13.159,21.472 12.001,21.472C10.832,21.472 9.895,20.558 9.895,19.525L14.107,19.525ZM3.505,3.471L20.618,19.654C20.962,19.979 20.977,20.52 20.652,20.864C20.327,21.207 19.786,21.222 19.443,20.898L2.329,4.714C1.986,4.389 1.971,3.848 2.295,3.505C2.62,3.161 3.162,3.146 3.505,3.471ZM5.718,10.105L14.585,18.491L5.261,18.491C4.324,18.491 3.661,17.382 4.324,16.735L5.532,15.382C5.629,15.273 5.682,15.133 5.682,14.987L5.682,10.805C5.682,10.568 5.694,10.334 5.718,10.105ZM11.922,2.528C12.663,2.528 13.264,3.129 13.264,3.87L13.264,4.492C16.232,5.216 18.32,7.681 18.32,10.805L18.32,14.987C18.32,15.133 18.373,15.273 18.47,15.382L18.781,15.73L8.174,5.699C8.862,5.176 9.666,4.779 10.556,4.538L10.556,3.87C10.556,3.151 11.121,2.564 11.831,2.529L11.922,2.528Z" fill="#FFFFFF" fill-rule="nonzero"/>
</svg>

After

Width:  |  Height:  |  Size: 910 B

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Icon / Menu / birthday_add</title>
<g id="Icon-/-Menu-/-birthday_add" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M19.4857266,16.2888889 C19.8170975,16.2888889 20.0857266,16.557518 20.0857266,16.8888889 L20.0856667,18.7328889 L21.9305556,18.7333333 C22.2287893,18.7333333 22.4762023,18.9509229 22.5227026,19.2360102 L22.5305556,19.3333333 C22.5305556,19.6647042 22.2619264,19.9333333 21.9305556,19.9333333 L20.0856667,19.9328889 L20.0857266,21.7777778 C20.0857266,22.0760115 19.868137,22.3234245 19.5830498,22.3699248 L19.4857266,22.3777778 C19.1543558,22.3777778 18.8857266,22.1091486 18.8857266,21.7777778 L18.8856667,19.9328889 L17.0416667,19.9333333 C16.7434329,19.9333333 16.4960199,19.7157437 16.4495197,19.4306564 L16.4416667,19.3333333 C16.4416667,19.0019625 16.7102958,18.7333333 17.0416667,18.7333333 L18.8856667,18.7328889 L18.8857266,16.8888889 C18.8857266,16.5906551 19.1033163,16.3432421 19.3884035,16.2967419 L19.4857266,16.2888889 Z M8.41204757,10.3213892 C8.4968615,10.6417222 8.30593555,10.9701587 7.98560254,11.0549726 C6.00141779,11.5803212 4.96111111,12.4866846 4.96111111,13.4472478 C4.96111111,13.5837542 4.98907974,13.7199344 5.04305686,13.8546242 C5.05815315,13.8780132 5.06968916,13.9034625 5.07949993,13.9299664 C5.67337842,15.1862671 8.51737301,16.291625 12,16.291625 C15.9250424,16.291625 19.0388889,14.8875907 19.0388889,13.4472478 C19.0388889,12.5127848 18.0774561,11.638341 16.2036879,11.1068602 C15.8848931,11.0164364 15.6997618,10.684699 15.7901857,10.3659042 C15.8806095,10.0471093 16.2123468,9.86197804 16.5311417,9.95240189 C18.8627692,10.6137512 20.2388889,11.8653615 20.2388889,13.4472478 C20.2388889,13.979393 20.0501074,14.4768826 19.7060685,14.9283577 C19.6140075,14.9115452 19.5205276,14.9027778 19.425,14.9027778 C18.6281077,14.9027778 17.9737164,15.5128973 17.9034658,16.2914966 L17.9034247,16.3114033 C16.4008483,17.0540936 14.3028164,17.491625 12,17.491625 C9.47842329,17.491625 7.20238688,16.967017 5.68481102,16.0915954 L6.42111111,18.7214444 L6.44,18.7222222 L6.44511111,18.8074444 L6.45530551,18.8430624 L6.4709096,18.9292533 C6.76328017,19.9158038 9.09544378,20.8722222 12,20.8722222 C13.262879,20.8722222 14.4175503,20.6914166 15.3434009,20.4059417 C15.6196573,20.6869274 16.004765,20.8611111 16.4305556,20.8611111 L17.2836209,20.8606349 C16.0386964,21.6207641 14.1238391,22.0722222 12,22.0722222 C8.52835644,22.0722222 5.61510021,20.8659524 5.27347003,19.0770457 L3.95558458,14.3602924 C3.82830877,14.0698882 3.76111111,13.7647359 3.76111111,13.4472478 C3.76111111,11.8222874 5.22885268,10.5435228 7.67846416,9.89494413 C7.99879717,9.81013021 8.32723365,10.0010562 8.41204757,10.3213892 Z M12.4583333,7.42777778 C13.380342,7.42777778 14.1277778,8.17521351 14.1277778,9.09722222 L14.1277778,13.0694444 C14.1277778,13.9914532 13.380342,14.7388889 12.4583333,14.7388889 L11.8472222,14.7388889 C10.9252135,14.7388889 10.1777778,13.9914532 10.1777778,13.0694444 L10.1777778,9.09722222 C10.1777778,8.17521351 10.9252135,7.42777778 11.8472222,7.42777778 L12.4583333,7.42777778 Z M12.4583333,8.62777778 L11.8472222,8.62777778 C11.5879552,8.62777778 11.3777778,8.83795521 11.3777778,9.09722222 L11.3777778,13.0694444 C11.3777778,13.3287115 11.5879552,13.5388889 11.8472222,13.5388889 L12.4583333,13.5388889 C12.7176003,13.5388889 12.9277778,13.3287115 12.9277778,13.0694444 L12.9277778,9.09722222 C12.9277778,8.83795521 12.7176003,8.62777778 12.4583333,8.62777778 Z M12.0207549,1.46944444 C12.8988738,1.46944444 14.1277778,3.40600437 14.1277778,4.64408449 C14.1277778,6.06372135 13.4385567,6.82401696 12,6.82401696 C10.3912998,6.82401696 9.40287158,5.20228362 10.2271046,3.79129771 L10.3125678,3.6554701 C10.6068441,3.21972221 11.1748869,2.01278865 11.1599792,2.03824823 C11.3659094,1.68655903 11.6259528,1.46944444 12.0207549,1.46944444 Z M12.1011111,2.85144444 L12.0713457,2.91751396 L11.8811707,3.30172279 L11.6899023,3.66987931 C11.557639,3.91763569 11.4205876,4.1589191 11.3070312,4.32706715 C10.8867233,4.94943561 11.2769618,5.62401696 12,5.62401696 C12.7481114,5.62401696 12.9277778,5.42582286 12.9277778,4.64408449 C12.9277778,4.29594473 12.7310746,3.77237759 12.4219529,3.28525029 C12.3528553,3.1763634 12.281237,3.07447531 12.2108288,2.98385177 L12.1011111,2.85144444 Z" id="Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_menu_my_stories" = "My Stories";
"lng_menu_my_groups" = "My Groups";
"lng_menu_my_channels" = "My Channels";
"lng_open_menu" = "Open navigation menu";
"lng_disable_notifications_from_tray" = "Disable notifications";
"lng_enable_notifications_from_tray" = "Enable notifications";
@@ -127,6 +128,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_cancel" = "Cancel";
"lng_continue" = "Continue";
"lng_close" = "Close";
"lng_minimize_window" = "Minimize";
"lng_maximize_window" = "Maximize";
"lng_restore_window" = "Restore";
"lng_go_back" = "Go back";
"lng_connecting" = "Connecting...";
"lng_reconnecting#one" = "Reconnect in {count} s...";
"lng_reconnecting#other" = "Reconnect in {count} s...";
@@ -377,6 +382,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_intro_fragment_about" = "Get the code for {phone_number} in the Anonymous Numbers section on Fragment.";
"lng_intro_fragment_button" = "Open Fragment";
"lng_intro_email_setup_title" = "Choose a login email";
"lng_intro_email_confirm_subtitle" = "Please check your email {email} (don't forget the spam folder) and enter the code we just sent you.";
"lng_phone_title" = "Your Phone Number";
"lng_phone_desc" = "Please confirm your country code\nand enter your phone number.";
"lng_phone_to_qr" = "Quick log in using QR code";
@@ -385,6 +393,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_country_ph" = "Search";
"lng_country_none" = "Country not found";
"lng_country_select" = "Select Country";
"lng_phone_number" = "Phone number";
"lng_code_ph" = "Code";
"lng_code_desc" = "We've sent an activation code to your phone.\nPlease enter it below.";
@@ -512,12 +521,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_notify_global" = "Global settings";
"lng_settings_notify_title" = "Notifications for chats";
"lng_settings_desktop_notify" = "Desktop notifications";
"lng_settings_master_volume_notifications" = "Volume";
"lng_settings_native_title" = "System integration";
"lng_settings_use_windows" = "Use Windows notifications";
"lng_settings_skip_in_focus" = "Respect system Focus mode";
"lng_settings_use_native_notifications" = "Use native notifications";
"lng_settings_notifications_position" = "Location on the screen";
"lng_settings_notifications_count" = "Notifications count";
"lng_settings_notifications_display" = "Display for notifications";
"lng_settings_notifications_display_default" = "Default";
"lng_settings_sound_allowed" = "Allow sound";
"lng_settings_alert_windows" = "Flash the taskbar icon";
"lng_settings_alert_mac" = "Bounce the Dock icon";
@@ -552,12 +564,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_notification_title_private_chats" = "Notifications for private chats";
"lng_notification_about_private_chats#one" = "Please note that **{count} chat** is listed as an exception and won't be affected by this change.";
"lng_notification_about_private_chats#other" = "Please note that **{count} chats** are listed as exceptions and won't be affected by this change.";
"lng_notification_volume_private_chats" = "Notifications volume for private chats";
"lng_notification_title_groups" = "Notifications for groups";
"lng_notification_about_groups#one" = "Please note that **{count} group** is listed as an exception and won't be affected by this change.";
"lng_notification_about_groups#other" = "Please note that **{count} groups** are listed as exceptions and won't be affected by this change.";
"lng_notification_volume_groups" = "Notifications volume for groups";
"lng_notification_title_channels" = "Notifications for channels";
"lng_notification_about_channels#one" = "Please note that **{count} channel** is listed as an exception and won't be affected by this change.";
"lng_notification_about_channels#other" = "Please note that **{count} channels** are listed as exceptions and won't be affected by this change.";
"lng_notification_volume_channel" = "Notifications volume for channels";
"lng_notification_exceptions_view" = "View exceptions";
"lng_notification_enable" = "Enable notifications";
"lng_notification_sound" = "Sound";
@@ -687,6 +702,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_shortcuts_media_fullscreen" = "Toggle video fullscreen";
"lng_shortcuts_show_chat_menu" = "Show chat menu";
"lng_shortcuts_show_chat_preview" = "Show chat preview";
"lng_shortcuts_record_voice_message" = "Record Voice Message";
"lng_shortcuts_record_round_message" = "Record Round Message";
"lng_settings_chat_reactions_title" = "Quick Reaction";
"lng_settings_chat_reactions_subtitle" = "Choose your favorite reaction";
@@ -768,6 +785,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_birthday_contacts" = "Only your contacts can see your birthday. {link}";
"lng_settings_birthday_contacts_link" = "Change >";
"lng_settings_birthday_saved" = "Your date of birth was updated.";
"lng_settings_birthday_suggested" = "Date of birth was suggested to {user}";
"lng_settings_birthday_reset" = "Remove";
"lng_settings_channel_label" = "Personal channel";
"lng_settings_channel_add" = "Add";
@@ -958,6 +976,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_font_family" = "Font family";
"lng_settings_color_title" = "Color preview";
"lng_settings_color_tab_profile" = "Profile";
"lng_settings_color_tab_name" = "Name";
"lng_settings_color_reply" = "Reply to your message";
"lng_settings_color_reply_channel" = "Reply to your channel message";
"lng_settings_color_text" = "Your name and replies to your messages will be shown in the selected color.";
@@ -972,9 +992,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_color_emoji_off" = "Off";
"lng_settings_color_emoji_about" = "Make replies to your messages stand out by adding custom patterns to them.";
"lng_settings_color_emoji_about_channel" = "Select an icon to create a custom pattern for replies to your messages.";
"lng_settings_color_subscribe" = "Subscribe to {link} to choose a custom color for your name.";
"lng_settings_color_changed" = "Your name color has been updated!";
"lng_settings_color_changed_channel" = "Your channel color has been updated!";
"lng_settings_color_changed_profile" = "Your profile style has been updated!";
"lng_settings_color_changed_profile_channel" = "Your channel profile style has been updated!";
"lng_settings_color_apply" = "Apply Style";
"lng_settings_color_profile_emoji" = "Add icons to Profile";
"lng_settings_color_profile_emoji_channel" = "Profile Logo";
"lng_settings_color_reset" = "Reset Profile Color";
"lng_settings_color_profile_about" = "You can change the color of your name and customize replies to you. {link}";
"lng_settings_color_profile_about_link" = "Change {emoji}";
"lng_settings_color_choose_channel" = "Choose a color and a logo for your channel's profile";
"lng_settings_color_choose_group" = "Choose a color and a logo for the group's profile";
"lng_settings_color_group_boost_footer#one" = "The group has **{count}** boost. {link}";
"lng_settings_color_group_boost_footer#other" = "The group has **{count}** boosts. {link}";
"lng_settings_color_group_boost_footer_link" = "What are boosts?";
"lng_suggest_hide_new_title" = "Hide new chats?";
"lng_suggest_hide_new_about" = "You are receiving lots of new chats from users who are not in your Contact List.\n\nDo you want to have such chats **automatically muted** and **archived**?";
@@ -1238,6 +1270,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_quick_dialog_action_toast_archive_success" = "The chat has been archived.";
"lng_quick_dialog_action_toast_unarchive_success" = "The chat has been unarchived.";
"lng_archive_hint_title" = "This is your Archive";
"lng_archive_hint_about" = "Archived chats will remain in the Archive when you receive a new message. {link}";
"lng_archive_hint_about_unmuted" = "When you receive a new message, muted chats will remain in the Archive, while unmuted chats will be moved to Chats. {link}";
"lng_archive_hint_about_link" = "Tap to change {emoji}";
"lng_archive_hint_section_1" = "Archived Chats";
"lng_archive_hint_section_1_info" = "Move any chat into your Archive and back by swiping on it.";
"lng_archive_hint_section_2" = "Hiding Archive";
"lng_archive_hint_section_2_info" = "Hide the Archive from your Main screen by swiping on it.";
"lng_archive_hint_section_3" = "Stories";
"lng_archive_hint_section_3_info" = "Archive Stories from your contacts separately from chats with them.";
"lng_archive_hint_button" = "Got it";
"lng_settings_generic_subscribe" = "Subscribe to {link} to use this setting.";
"lng_settings_generic_subscribe_link" = "Telegram Premium";
@@ -1581,6 +1625,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_info_birthday_today_years#other" = "{date}\n({count} years old)";
"lng_info_birthday_today_label" = "Birthday today";
"lng_info_birthday_today" = "{emoji} {date}";
"lng_info_notes_label" = "Notes";
"lng_info_notes_private" = "only visible to you";
"lng_edit_note" = "Edit Note";
"lng_delete_note" = "Delete Note";
"lng_info_bio_label" = "Bio";
"lng_info_link_label" = "Link";
"lng_info_location_label" = "Location";
@@ -1604,12 +1652,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_info_group_title" = "Group Info";
"lng_info_channel_title" = "Channel Info";
"lng_info_topic_title" = "Topic Info";
"lng_info_thread_title" = "Thread Info";
"lng_profile_enable_notifications" = "Notifications";
"lng_profile_send_message" = "Send Message";
"lng_profile_open_app" = "Open App";
"lng_profile_open_app_short" = "Open";
"lng_profile_open_app_about" = "By launching this mini app, you agree to the {terms}.";
"lng_profile_open_app_terms" = "Terms of Service for Mini Apps";
"lng_profile_open_photo" = "Open Photo";
"lng_profile_bot_permissions_title" = "Allow access to";
"lng_profile_bot_emoji_status_access" = "Emoji Status";
"lng_info_add_as_contact" = "Add to contacts";
@@ -1618,7 +1668,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_suggest_photo_from_clipboard" = "Suggest From Clipboard";
"lng_profile_set_photo_for" = "Set Profile Photo";
"lng_profile_set_photo_for_from_clipboard" = "Set From Clipboard";
"lng_profile_set_photo_for_about" = "You can replace {user}'s photo with another photo that only you will see.";
"lng_profile_photo_reset" = "Reset to Original";
"lng_profile_photo_reset_sure" = "Are you sure you want to reset {user}'s photo to the original?";
"lng_profile_photo_from_clipboard" = "From clipboard";
"lng_profile_suggest_sure" = "You can suggest {user} to set this photo for their Telegram profile.";
"lng_profile_suggest_button" = "Suggest";
@@ -1630,6 +1682,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_changed_photo_title" = "Photo updated";
"lng_profile_changed_photo_about" = "You can change it in {link}.";
"lng_profile_changed_photo_link" = "Settings";
"lng_profile_action_short_message" = "Message";
"lng_profile_action_short_mute" = "Mute";
"lng_profile_action_short_unmute" = "Unmute";
"lng_profile_action_short_call" = "Call";
"lng_profile_action_short_discuss" = "Discuss";
"lng_profile_action_short_gift" = "Gift";
"lng_profile_action_short_join" = "Join";
"lng_profile_action_short_report" = "Report";
"lng_profile_action_short_leave" = "Leave";
"lng_profile_action_short_more" = "More";
"lng_media_type_photos" = "Photos";
"lng_media_type_gifs" = "GIFs";
"lng_media_type_videos" = "Videos";
@@ -1638,6 +1702,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_media_type_audios" = "Voice messages";
"lng_media_type_links" = "Shared links";
"lng_media_type_rounds" = "Video messages";
"lng_media_saved_music_your" = "Your playlist";
"lng_media_saved_music_title" = "Playlist";
"lng_profile_common_groups_section" = "Groups in common";
"lng_info_edit_contact" = "Edit contact";
"lng_info_delete_contact" = "Delete contact";
@@ -1927,6 +1993,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_manage_monoforum_price" = "Price for each message";
"lng_manage_monoforum_about" = "Allow users to send messages to your channel, with the option to charge a fee for each message.";
"lng_manage_monoforum_price_about" = "Your channel will receive {percent} of the selected fee ({amount}) for each incoming message.";
"lng_manage_monoforum_link_subtitle" = "Link to direct messages";
"lng_manage_history_visibility_title" = "Chat history for new members";
"lng_manage_history_visibility_shown" = "Visible";
@@ -2055,6 +2122,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_sure_delete_contact" = "Are you sure you want to delete {contact} from your contact list?";
"lng_sure_delete_history" = "Are you sure you want to delete all message history with {contact}?\n\nThis action cannot be undone.";
"lng_sure_delete_group_history" = "Are you sure you want to delete all messages in \"{group}\"?\n\nThis action cannot be undone.";
"lng_sure_delete_channel_history" = "Are you sure you want to delete all messages in \"{channel}\"?\n\n**This action cannot be undone.**";
"lng_sure_delete_and_exit" = "Are you sure you want to delete all message history and leave «{group}»?\n\nThis action cannot be undone.";
"lng_sure_leave_channel" = "Are you sure you want to leave\nthis channel?";
"lng_sure_delete_channel" = "Are you sure you want to delete this channel? All subscribers will be removed and all messages will be lost.";
@@ -2167,6 +2235,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_you_proximity_reached" = "You are now within {distance} from {user}";
"lng_action_you_theme_changed" = "You changed the chat theme to {emoji}";
"lng_action_theme_changed" = "{from} changed the chat theme to {emoji}";
"lng_action_you_gift_theme_changed" = "You set {name} as a new theme for this chat.";
"lng_action_gift_theme_changed" = "{from} set {name} as a new theme for this chat.";
"lng_action_you_theme_disabled" = "You disabled the chat theme";
"lng_action_theme_disabled" = "{from} disabled the chat theme";
"lng_action_proximity_distance_m#one" = "{count} meter";
@@ -2183,11 +2253,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_gift_upgraded_self_channel" = "You turned this gift to {channel} into a unique collectible";
"lng_action_gift_upgraded_mine" = "You turned the gift from {user} into a unique collectible";
"lng_action_gift_upgraded_self" = "You turned this gift into a unique collectible";
"lng_action_gift_sent_upgrade_other" = "{from} sent an upgrade worth {cost} for the gift you received from {user}.";
"lng_action_gift_sent_upgrade_self_other" = "You sent an upgrade worth {cost} for the gift {name} received from {user}.";
"lng_action_gift_sent_upgrade" = "{from} sent an upgrade worth {cost} for your gift.";
"lng_action_gift_sent_upgrade_self" = "You sent an upgrade worth {cost} for this gift.";
"lng_action_gift_sent_upgrade_self_channel" = "You sent an upgrade worth {cost} for your gift to {name}.";
"lng_action_gift_upgraded_helped" = "{user} unpacked the gift that you helped to upgrade.";
"lng_action_gift_upgraded_helped_self" = "You unpacked the gift that {user} helped to upgrade.";
"lng_action_gift_transferred" = "{user} transferred you a gift";
"lng_action_gift_transferred_channel" = "{user} transferred a gift to {channel}";
"lng_action_gift_transferred_unknown" = "Someone transferred you a gift";
"lng_action_gift_transferred_unknown_channel" = "Someone transferred a gift to {channel}";
"lng_action_gift_transferred_self" = "You transferred a unique collectible";
"lng_action_gift_displayed_self" = "You've started displaying {name} on your Telegram profile page.";
"lng_action_gift_transferred_self_channel" = "You transferred a gift to {channel}";
"lng_action_gift_transferred_mine" = "You transferred a gift to {user}";
"lng_action_gift_received_anonymous" = "Unknown user sent you a gift for {cost}";
@@ -2228,6 +2306,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_suggested_video_me" = "You suggested this photo for {user}'s Telegram profile.";
"lng_action_suggested_video" = "{user} suggests this photo for your Telegram profile.";
"lng_action_suggested_video_button" = "View Photo";
"lng_action_suggested_birthday_me" = "You suggest {user} add a date of birth:";
"lng_action_suggested_birthday" = "{user} suggests you add your date of birth:";
"lng_action_suggested_birtday_button" = "View";
"lng_action_attach_menu_bot_allowed" = "You allowed this bot to message you when you added it to your attachment menu.";
"lng_action_webapp_bot_allowed" = "You allowed this bot to message you in its web-app.";
"lng_action_set_wallpaper_me" = "You set a new wallpaper for this chat";
@@ -2248,6 +2329,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_topic_hidden" = "\"{topic}\" was hidden";
"lng_action_topic_unhidden" = "\"{topic}\" was unhidden";
"lng_action_topic_placeholder" = "topic";
"lng_action_topic_bot_thread" = "thread";
"lng_action_topic_renamed" = "{from} renamed the {link} to \"{title}\"";
"lng_action_topic_icon_changed" = "{from} changed the {link} icon to {emoji}";
"lng_action_topic_icon_removed" = "{from} removed the {link} icon";
@@ -2339,6 +2421,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_peer_gifts_filter_by_value" = "Sort by Value";
"lng_peer_gifts_filter_by_date" = "Sort by Date";
"lng_peer_gifts_filter_unlimited" = "Unlimited";
"lng_peer_gifts_filter_upgradable" = "Upgradeable";
"lng_peer_gifts_filter_limited" = "Limited";
"lng_peer_gifts_filter_unique" = "Unique";
"lng_peer_gifts_filter_saved" = "Displayed";
@@ -2544,6 +2627,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_bot_allow_write_title" = "Allow messaging";
"lng_bot_allow_write" = "Do you want to allow this bot to send you messages?";
"lng_bot_allow_write_confirm" = "Allow";
"lng_bot_new_chat" = "New Chat";
"lng_bot_new_thread_title" = "New Thread";
"lng_bot_new_thread_about" = "Type any message to create a new thread.";
"lng_bot_show_threads_list" = "Show Threads List";
"lng_attach_failed" = "Failed";
"lng_attach_file" = "File";
@@ -2681,6 +2768,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_premium_summary_about_filter_tags" = "Display folder names for each chat in the chat list.";
"lng_premium_summary_subtitle_todo_lists" = "Checklists";
"lng_premium_summary_about_todo_lists" = "Plan, assign, and complete tasks - seamlessly and efficiently.";
"lng_premium_summary_subtitle_peer_colors" = "Name and Profile Colors";
"lng_premium_summary_about_peer_colors" = "Choose a color and logo for your profile and replies to your messages.";
"lng_premium_summary_bottom_subtitle" = "About Telegram Premium";
"lng_premium_summary_bottom_about" = "While the free version of Telegram already gives its users more than any other messaging application, **Telegram Premium** pushes its capabilities even further.\n\n**Telegram Premium** is a paid option, because most Premium Features require additional expenses from Telegram to third parties such as data center providers and server manufacturers. Contributions from **Telegram Premium** users allow us to cover such costs and also help Telegram stay free for everyone.";
"lng_premium_summary_button" = "Subscribe for {cost} per month";
@@ -2902,6 +2991,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_credits_box_history_entry_ads" = "Ads Platform";
"lng_credits_box_history_entry_premium_bot" = "Stars Top-Up";
"lng_credits_box_history_entry_currency_in" = "TON Top-Up";
"lng_credits_box_history_entry_posts_search" = "Posts Search";
"lng_credits_box_history_entry_api" = "Paid Broadcast";
"lng_credits_box_history_entry_floodskip_about#one" = "{count} Message";
"lng_credits_box_history_entry_floodskip_about#other" = "{count} Messages";
@@ -3547,17 +3637,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_premium_by_stars" = "or {amount}";
"lng_gift_stars_subtitle" = "Gift Stars";
"lng_gift_stars_about" = "Give {name} gifts that can be kept on your profile or converted to Stars. {link}";
"lng_gift_stars_about_collectibles" = "Collectible gifts are unique digital items you can exchange or sell. {link}";
"lng_gift_stars_link" = "What are Stars >";
"lng_gift_stars_limited" = "limited";
"lng_gift_stars_sold_out" = "sold out";
"lng_gift_stars_resale" = "resale";
"lng_gift_stars_on_sale" = "on sale";
"lng_gift_stars_premium" = "premium";
"lng_gift_stars_your_left#one" = "{count} left";
"lng_gift_stars_your_left#other" = "{count} left";
"lng_gift_stars_your_finished" = "none left";
"lng_gift_stars_tabs_all" = "All Gifts";
"lng_gift_stars_tabs_my" = "My Gifts";
"lng_gift_stars_tabs_limited" = "Limited";
"lng_gift_stars_tabs_in_stock" = "In Stock";
"lng_gift_stars_tabs_resale" = "Resale";
"lng_gift_stars_tabs_my_empty" = "You don't have any gifts you can use as a profile cover.";
"lng_gift_stars_tabs_my_empty_next" = "Browse gifts available for purchase {emoji}";
"lng_gift_stars_tabs_collectibles" = "Collectibles";
"lng_gift_send_title" = "Send a Gift";
"lng_gift_send_message" = "Enter Message";
"lng_gift_send_anonymous" = "Hide My Name";
@@ -3610,8 +3704,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_hidden_hint_channel" = "This gift is hidden from visitors of your channel.";
"lng_gift_visible_hint_channel" = "This gift is visible in your channel's Gifts.";
"lng_gift_in_blockchain" = "This gift is in TON blockchain. {link}";
"lng_gift_in_blockchain_link" = "View >";
"lng_gift_visible_hide" = "Hide >";
"lng_gift_in_blockchain_link_arrow" = "View {arrow}";
"lng_gift_visible_hide_arrow" = "Hide {arrow}";
"lng_gift_visible_show_arrow" = "Show {arrow}";
"lng_gift_show_on_page" = "Display on my Page";
"lng_gift_show_on_channel" = "Display in channel's Gifts";
"lng_gift_availability" = "Availability";
@@ -3625,12 +3720,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_self_about" = "Buy yourself a gift to display on your page or reserve for later.\n\nLimited-edition gifts upgraded to collectibles can be gifted to others later.";
"lng_gift_channel_title" = "Send a Gift";
"lng_gift_channel_about" = "Select a gift to show appreciation for {name}.";
"lng_gift_released_by" = "Released by {name}";
"lng_gift_released_by" = "released by {name}";
"lng_gift_unique_owner" = "Owner";
"lng_gift_unique_address_copied" = "Address copied to clipboard.";
"lng_gift_unique_telegram" = "Telegram";
"lng_gift_unique_status" = "Status";
"lng_gift_unique_status_non" = "Non-Unique";
"lng_gift_unique_status_upgrade" = "upgrade";
"lng_gift_unique_upgrade" = "Upgrade";
"lng_gift_unique_upgrade_next" = "Upgrade Next Gift";
"lng_gift_unique_gift_upgrade" = "Gift an Upgrade";
"lng_gift_unique_number" = "Collectible #{index}";
"lng_gift_unique_number_by" = "Collectible #{index} by {name}";
"lng_gift_unique_model" = "Model";
@@ -3640,14 +3738,35 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_unique_availability_label" = "Quantity";
"lng_gift_unique_availability#one" = "{count} of {amount} issued";
"lng_gift_unique_availability#other" = "{count} of {amount} issued";
"lng_gift_unique_value" = "Value";
"lng_gift_unique_value_learn_more" = "learn more";
"lng_gift_unique_info" = "Gifted to {recipient} on {date}.";
"lng_gift_unique_info_sender" = "Gifted by {from} to {recipient} on {date}.";
"lng_gift_unique_info_sender_comment" = "Gifted by {from} to {recipient} on {date} with the comment \"{text}\".";
"lng_gift_unique_info_reciever" = "Gifted to {recipient} on {date}.";
"lng_gift_unique_info_reciever_comment" = "Gifted to {recipient} on {date} with the comment \"{text}\".";
"lng_gift_unique_info_remove_title" = "Remove Description";
"lng_gift_unique_info_remove_text" = "Do you want to permanently remove this description from your gift?";
"lng_gift_unique_info_remove_confirm" = "Remove for {cost}";
"lng_gift_unique_info_removed" = "Removed {name}'s Description!";
"lng_gift_availability_left#one" = "{count} of {amount} left";
"lng_gift_availability_left#other" = "{count} of {amount} left";
"lng_gift_availability_none" = "None of {amount} left";
"lng_gift_value_about_average" = "This is the average sale price of {gift} gifts on Telegram and Fragment over the past month.";
"lng_gift_value_about_last" = "This is the price at which {gift} was last sold on {platform}.";
"lng_gift_value_initial_sale" = "Initial Sale";
"lng_gift_value_initial_price" = "Initial Price";
"lng_gift_value_initial_price_value" = "{stars} ({amount})";
"lng_gift_value_last_sale" = "Last Sale";
"lng_gift_value_last_price" = "Last Price";
"lng_gift_value_minimum_price" = "Minimum Price";
"lng_gift_value_minimum_price_tooltip" = "{amount} is the floor price for {gift} gifts listed on Telegram and Fragment.";
"lng_gift_vlaue_average_price" = "Average Price";
"lng_gift_value_average_price_tooltip" = "{amount} is the average sale price of {gift} gifts on Telegram and Fragment over the past month.";
"lng_gift_value_availability#one" = "{count} {emoji} for sale on {platform} {arrow}";
"lng_gift_value_availability#other" = "{count} {emoji} for sale on {platform} {arrow}";
"lng_gift_value_telegram" = "Telegram";
"lng_gift_value_fragment" = "Fragment";
"lng_gift_convert_to_stars#one" = "Convert to {count} Star";
"lng_gift_convert_to_stars#other" = "Convert to {count} Stars";
"lng_gift_convert_sure_title" = "Convert Gift to Stars";
@@ -3683,11 +3802,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_upgrade_preview_about_channel" = "Let the admins of {name} turn your gift into a unique collectible.";
"lng_gift_upgrade_unique_title" = "Unique";
"lng_gift_upgrade_unique_about" = "Get a unique number, model, backdrop and symbol for your gift.";
"lng_gift_upgrade_unique_about_user" = "{name} will get a unique number, model, backdrop and symbol for your gift.";
"lng_gift_upgrade_unique_about_channel" = "Admins of {name} will get a unique number, model, backdrop and symbol for your gift.";
"lng_gift_upgrade_transferable_title" = "Transferable";
"lng_gift_upgrade_transferable_about" = "Send your upgraded gift to any of your friends on Telegram.";
"lng_gift_upgrade_transferable_about_user" = "{name} will be able to send the gift to anyone on Telegram.";
"lng_gift_upgrade_transferable_about_channel" = "Admins of {name} will be able to send the gift to anyone on Telegram.";
"lng_gift_upgrade_tradable_title" = "Tradable";
"lng_gift_upgrade_tradable_about" = "Sell or auction your gift on third-party NFT marketplaces.";
"lng_gift_upgrade_tradable_about_user" = "{name} will be able to sell the gift on Telegram and NFT marketplaces.";
"lng_gift_upgrade_tradable_about_channel" = "Admins of {name} will be able to sell the gift on Telegram and NFT marketplaces.";
"lng_gift_upgrade_button" = "Upgrade for {price}";
"lng_gift_upgrade_decreases" = "Price decreases in {time}";
"lng_gift_upgrade_see_table" = "See how this price will decrease {arrow}";
"lng_gift_upgrade_prices_about" = "Upgrade cost drops every minute.";
"lng_gift_upgrade_prices_title" = "Upgrade Cost";
"lng_gift_upgrade_prices_subtitle" = "Users who upgrade their gifts first get collectibles with shorter numbers.";
"lng_gift_upgrade_free" = "Upgrade for Free";
"lng_gift_upgrade_confirm" = "Confirm";
"lng_gift_upgrade_add_my" = "Add my name to the gift";
@@ -3696,6 +3826,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_upgrade_add_comment" = "Add sender's name and comment";
"lng_gift_upgraded_title" = "Gift Upgraded";
"lng_gift_upgraded_about" = "Your gift {name} now has unique attributes and can be transferred to others";
"lng_gift_upgrade_gifted_title" = "Upgrade Gifted";
"lng_gift_upgrade_gifted_about" = "Now {name} can turn your gift into a unique collectible.";
"lng_gift_upgrade_gifted_about_channel" = "Now the admins of {name} can turn your gift into a unique collectible.";
"lng_gift_transferred_title" = "Gift Transferred";
"lng_gift_transferred_about" = "{name} was successfully transferred to {recipient}.";
"lng_gift_transfer_title" = "Transfer {name}";
@@ -3722,11 +3855,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_transfer_sure_for" = "Do you want to transfer ownership of {name} to {recipient} for {price}?";
"lng_gift_transfer_button" = "Transfer";
"lng_gift_transfer_button_for" = "Transfer for {price}";
"lng_gift_transfer_set_theme" = "Set as Theme in...";
"lng_gift_transfer_choose" = "Choose Chat";
"lng_gift_transfer_wear" = "Wear";
"lng_gift_transfer_take_off" = "Take Off";
"lng_gift_transfer_sell" = "Sell";
"lng_gift_transfer_update" = "Change Price";
"lng_gift_transfer_unlist" = "Unlist";
"lng_gift_transfer_locked_title" = "Action Locked";
"lng_gift_transfer_locked_text" = "Transfer this gift to your Telegram account on Fragment to unlock this action.";
"lng_gift_sell_unlist_title" = "Unlist {name}";
"lng_gift_sell_unlist_sure" = "Are you sure you want to unlist your gift?";
"lng_gift_sell_title" = "Price in Stars";
@@ -3781,7 +3918,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_resale_symbol" = "Symbol";
"lng_gift_resale_symbols#one" = "{count} Symbol";
"lng_gift_resale_symbols#other" = "{count} Symbols";
"lng_gift_resale_switch_to" = "Switch to {currency}";
"lng_gift_resale_switch_to_ton" = "Switch to Ton";
"lng_gift_resale_switch_to_stars" = "Switch to Stars";
"lng_gift_resale_early" = "You will be able to resell this gift in {duration}.";
"lng_gift_transfer_early" = "You will be able to transfer this gift in {duration}.";
"lng_gift_resale_transfer_early_title" = "Try Later";
@@ -3804,6 +3942,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_collection_delete_sure" = "Are you sure you want to delete this collection?";
"lng_gift_collection_delete_button" = "Delete";
"lng_gift_collection_add_to" = "Add to Collection";
"lng_gift_collection_reorder" = "Reorder";
"lng_gift_collection_reorder_exit" = "Apply Reorder";
"lng_gift_collection_remove_from" = "Remove from Collection";
"lng_gift_locked_title" = "Gift Locked";
"lng_accounts_limit_title" = "Limit Reached";
"lng_accounts_limit1#one" = "You have reached the limit of **{count}** connected account.";
@@ -4122,6 +4264,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_dialogs_suggestions_credits_sub_low_title#other" = "{emoji} {count} Stars needed for {channels}";
"lng_dialogs_suggestions_credits_sub_low_about" = "Insufficient funds to cover your subscription.";
"lng_unconfirmed_auth_title" = "Someone just got access to your messages!";
"lng_unconfirmed_auth_confirm" = "Yes, its me";
"lng_unconfirmed_auth_deny" = "No, its not me!";
"lng_unconfirmed_auth_single" = "We detected a new login to your account from {from}, {country}. Is it you?";
"lng_unconfirmed_auth_multiple#one" = "We detected new {count} login to your account. Is it you?";
"lng_unconfirmed_auth_multiple#other" = "We detected new {count} logins to your account. Is it you?";
"lng_unconfirmed_auth_multiple_from#one" = "We detected new {count} login to your account from {country}. Is it you?";
"lng_unconfirmed_auth_multiple_from#other" = "We detected new {count} logins to your account from {country}. Is it you?";
"lng_unconfirmed_auth_denied_title#one" = "New Login Prevented";
"lng_unconfirmed_auth_denied_title#other" = "New Logins Prevented";
"lng_unconfirmed_auth_denied_single" = "We have terminated the login attempt from {country}.";
"lng_unconfirmed_auth_denied_multiple" = "We have terminated the login attempts from: {country}";
"lng_unconfirmed_auth_denied_warning" = "Never send your login code to anyone or you can lose your Telegram account!";
"lng_unconfirmed_auth_confirmed" = "New Login Allowed";
"lng_unconfirmed_auth_confirmed_message" = "You can check the list of your active logins in {link}.";
"lng_about_random" = "Send a {emoji} emoji to any chat to try your luck.";
"lng_about_random_send" = "Send";
@@ -4272,6 +4430,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_view_group" = "View group info";
"lng_context_view_channel" = "View channel info";
"lng_context_view_topic" = "View topic info";
"lng_context_view_thread" = "View thread info";
"lng_context_hide_psa" = "Hide this announcement";
"lng_context_pin_to_top" = "Pin";
"lng_context_unpin_from_top" = "Unpin";
@@ -4289,6 +4448,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_archive_to_list" = "Move to chat list";
"lng_context_archive_to_menu_info" = "Archive moved to the main menu!\nRight click the archive button to return the Archive to your chat list.";
"lng_context_archive_settings" = "Archive settings";
"lng_context_archive_how_does_it_work" = "How does it work?";
"lng_context_mute" = "Mute notifications";
"lng_context_unmute" = "Unmute";
@@ -4300,6 +4460,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_remove_from_group" = "Remove from group";
"lng_context_add_to_group" = "Add to group";
"lng_context_rate_transcription" = "Rate transcription";
"lng_toast_sent_rate_transcription" = "Thank you for your feedback!";
"lng_context_copy_link" = "Copy Link";
"lng_context_copy_message_link" = "Copy Message Link";
"lng_context_copy_post_link" = "Copy Post Link";
@@ -4319,6 +4482,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_pack_info" = "View Sticker Set";
"lng_context_pack_add" = "Add Stickers";
"lng_context_save_file" = "Save As...";
"lng_context_save_music_to" = "Save to...";
"lng_context_save_music_profile" = "... Profile";
"lng_context_save_music_saved" = "... Saved Messages";
"lng_context_save_music_folder" = "... Downloads";
"lng_context_save_music_about" = "Choose where you want this audio to be saved.";
"lng_context_copy_text" = "Copy Text";
"lng_context_open_gif" = "Open GIF";
"lng_context_save_gif" = "Add to GIFs";
@@ -4399,6 +4567,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_add_tag_phrase" = "to messages {arrow}";
"lng_add_tag_phrase_long" = "to your Saved Messages {arrow}";
"lng_unlock_tags" = "Unlock";
"lng_add_tag_selector#one" = "You can add a tag to the message";
"lng_add_tag_selector#other" = "You can add a tag to the messages";
"lng_message_tagged_with" = "Message tagged with {emoji}";
"lng_tagged_view_saved" = "View";
"lng_context_animated_emoji" = "This message contains emoji from **{name} pack**.";
"lng_context_animated_emoji_many#one" = "This message contains emoji from **{count} pack**.";
@@ -4680,6 +4852,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_contact_phone_after" = "Phone number will be visible once {user} adds you as a contact.";
"lng_contact_share_phone" = "Share my phone number";
"lng_contact_phone_will_be_shared" = "You can make your phone visible to {user}.";
"lng_contact_add_notes" = "Note";
"lng_contact_add_notes_about" = "Notes are only visible to you.";
"lng_contact_notes_limit_reached#one" = "You've reached the contact note limit. Please make the note shorter by {count} character.";
"lng_contact_notes_limit_reached#other" = "You've reached the contact note limit. Please make the note shorter by {count} characters.";
"lng_suggest_photo_for" = "Suggest Photo for {user}";
"lng_suggest_birthday" = "Suggest Date of Birth";
"lng_suggest_birthday_box_title" = "{user}'s Date of Birth";
"lng_suggest_birthday_box_confirm" = "Suggest";
"lng_set_photo_for_user" = "Set Photo for {user}";
"lng_contact_photo_replace_info" = "You can replace {user}'s photo with another photo that only you will see.";
"lng_edit_contact_title" = "Edit contact";
"lng_edit_channel_title" = "Edit channel";
"lng_edit_bot_title" = "Edit bot";
@@ -4733,6 +4915,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_selected_delete_sure_this" = "Do you want to delete this message?";
"lng_selected_delete_sure#one" = "Do you want to delete {count} message?";
"lng_selected_delete_sure#other" = "Do you want to delete {count} messages?";
"lng_selected_remove_saved_music" = "Do you want to remove this file from your profile?";
"lng_saved_music_added" = "Audio added to your Profile.";
"lng_saved_music_removed" = "Audio removed from your Profile.";
"lng_delete_photo_sure" = "Do you want to delete this photo?";
"lng_delete_for_everyone_hint#one" = "This will delete it for everyone in this chat.";
"lng_delete_for_everyone_hint#other" = "This will delete them for everyone in this chat.";
@@ -4912,8 +5097,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_payments_webview_no_use" = "Unfortunately, you can't use payments with current system configuration.";
"lng_payments_webview_install_edge" = "Please install {link}.";
"lng_payments_webview_install_webkit" = "Please install WebKitGTK (webkit2gtk-4.1/webkit2gtk-4.0) using your package manager.";
"lng_payments_webview_enable_opengl" = "Please enable OpenGL in application settings.";
"lng_payments_webview_switch_x11" = "Unsupported display server. Please switch to X11.";
"lng_payments_webview_update_windows" = "Please update your system to Windows 8.1 or later.";
"lng_payments_sure_close" = "Are you sure you want to close this payment form? The changes you made will be lost.";
"lng_payments_receipt_label" = "Receipt";
@@ -5064,6 +5247,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_group_call_raised_hand_status" = "wants to speak";
"lng_group_call_settings" = "Settings";
"lng_group_call_video" = "Video";
"lng_group_call_message" = "Message";
"lng_group_call_screen_share_start" = "Share Screen";
"lng_group_call_screen_share_stop" = "Stop Sharing";
"lng_group_call_screen_title" = "Screen {index}";
@@ -5125,6 +5309,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_group_call_invite_search_results" = "Search results";
"lng_group_call_invite_limit" = "This is currently the maximum allowed number of participants.";
"lng_group_call_new_muted" = "Mute new participants";
"lng_group_call_enable_messages" = "Enable messages";
"lng_group_call_speakers" = "Speakers";
"lng_group_call_microphone" = "Microphone";
"lng_group_call_push_to_talk" = "Push-to-Talk Shortcut";
@@ -6078,6 +6263,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_todo_title" = "Checklist";
"lng_todo_title_group" = "Group Checklist";
"lng_todo_title_user" = "Checklist";
"lng_todo_completed#one" = "{count} of {total} completed";
"lng_todo_completed#other" = "{count} of {total} completed";
"lng_todo_completed_none" = "None of {total} completed";
@@ -6258,6 +6444,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_chat_theme_change_wallpaper" = "Change Wallpaper";
"lng_chat_theme_title" = "Select theme";
"lng_chat_theme_cant_voice" = "Sorry, you can't change the chat theme while you have an unsent voice message.";
"lng_chat_theme_gift_replace" = "This gift is already your theme in the chat with {name}. Remove it there and use it here instead?";
"lng_photo_editor_menu_delete" = "Delete";
"lng_photo_editor_menu_flip" = "Flip";
@@ -6295,7 +6482,9 @@ 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_linked" = "Unlike other apps, Telegram never uses your private data to target ads. {link}\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 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_link" = "Learn more in the Privacy Policy";
"lng_sponsored_info_description1_url" = "https://telegram.org/privacy#5-6-no-ads-based-on-user-data";
"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" = "Advertiser info";
"lng_sponsored_info_submenu" = "Advertiser: {text}";
@@ -6332,6 +6521,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_ringtones_box_title" = "Notification Sound";
"lng_ringtones_box_cloud_subtitle" = "Choose your tone";
"lng_ringtones_box_volume" = "Volume";
"lng_ringtones_box_upload_choose" = "Choose a tone";
"lng_ringtones_box_upload_button" = "Upload Sound";
"lng_ringtones_box_about" = "Right click on any short voice note or MP3 file in chat and select \"Save for Notifications\". It will appear here.";
@@ -6341,6 +6531,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_ringtones_error_max_size" = "Sorry, but your file is too big. The maximum size for ringtones is {size}.";
"lng_ringtones_error_max_duration" = "Sorry, but your file is too long. The maximum duration for ringtones is {duration}.";
"lng_bot_thread_edit" = "Edit Thread";
"lng_bot_thread_title" = "Thread Name";
"lng_bot_thread_choose_title_and_icon" = "Choose a thread name and icon";
"lng_forum_topic_new" = "New Topic";
"lng_forum_topic_edit" = "Edit Topic";
"lng_forum_topic_title" = "Topic Name";

View File

@@ -51,8 +51,8 @@ var LocationPicker = {
},
init: function (params) {
mapboxgl.accessToken = params.token;
if (params.protocol) {
mapboxgl.config.API_URL = params.protocol + '://domain/api.mapbox.com';
if (location.hostname != 'desktop-app-resource') {
mapboxgl.config.API_URL = location.protocol + '//' + location.host + '/api.mapbox.com';
}
var options = { container: 'map', config: {

View File

@@ -39,6 +39,16 @@
<file alias="topics_list.tgs">../../animations/edit_peers/topics_list.tgs</file>
<file alias="direct_messages.tgs">../../animations/edit_peers/direct_messages.tgs</file>
<file alias="no_chats.tgs">../../animations/no_chats.tgs</file>
<file alias="transcribe_loading.tgs">../../animations/transcribe_loading.tgs</file>
<file alias="cake.tgs">../../animations/cake.tgs</file>
<file alias="camera_outline.tgs">../../animations/camera_outline.tgs</file>
<file alias="photo_suggest_icon.tgs">../../animations/photo_suggest_icon.tgs</file>
<file alias="toast/saved_messages.tgs">../../animations/toast/saved_messages.tgs</file>
<file alias="toast/tagged.tgs">../../animations/toast/tagged.tgs</file>
<file alias="my_gifts_empty.tgs">../../animations/my_gifts_empty.tgs</file>
<file alias="profile_muting.tgs">../../animations/profile/profile_muting.tgs</file>
<file alias="profile_unmuting.tgs">../../animations/profile/profile_unmuting.tgs</file>
<file alias="dice_idle.tgs">../../animations/dice/dice_idle.tgs</file>
<file alias="dart_idle.tgs">../../animations/dice/dart_idle.tgs</file>

View File

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

View File

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

View File

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

View File

@@ -9,10 +9,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "base/unixtime.h"
#include "core/changelogs.h"
#include "core/application.h"
#include "core/changelogs.h"
#include "core/core_settings.h"
#include "lang/lang_keys.h"
#include "main/main_app_config.h"
#include "main/main_session_settings.h"
#include "main/main_session.h"
namespace Api {
namespace {
@@ -83,7 +86,19 @@ Authorizations::Entry ParseEntry(const MTPDauthorization &data) {
} // namespace
Authorizations::Authorizations(not_null<ApiWrap*> api)
: _api(&api->instance()) {
: _api(&api->instance())
, _autoconfirmPeriod([=] {
constexpr auto kFallbackCount = 604800;
return api->session().appConfig().get<int>(
u"authorization_autoconfirm_period"_q,
kFallbackCount);
})
, _saveUnreviewed([=] {
api->session().settings().setUnreviewed(_unreviewed);
api->session().saveSettingsDelayed();
}) {
_unreviewed = api->session().settings().unreviewed();
crl::on_main(&api->session(), [=] { removeExpiredUnreviewed(); });
Core::App().settings().deviceModelChanges(
) | rpl::start_with_next([=](const QString &model) {
auto changed = false;
@@ -119,6 +134,7 @@ void Authorizations::reload() {
) | ranges::views::transform([](const MTPAuthorization &auth) {
return ParseEntry(auth.data());
}) | ranges::to<List>;
removeExpiredUnreviewed();
refreshCallsDisabledHereFromCloud();
_listChanges.fire({});
}).fail([=] {
@@ -217,11 +233,7 @@ void Authorizations::toggleCallsDisabled(uint64 hash, bool disabled) {
MTP_bool(disabled)
)).done([=] {
_toggleCallsDisabledRequests.remove(hash);
}).fail([=](const MTP::Error &error) {
LOG(("API Error: toggle calls %1. Hash: %2. %3.")
.arg(disabled ? u"disabled"_q : u"enabled"_q)
.arg(hash)
.arg(error.type()));
}).fail([=] {
_toggleCallsDisabledRequests.remove(hash);
}).send();
_toggleCallsDisabledRequests.emplace(hash, id);
@@ -265,4 +277,129 @@ crl::time Authorizations::lastReceivedTime() {
return _lastReceived;
}
const std::vector<Data::UnreviewedAuth> &Authorizations::unreviewed() {
removeExpiredUnreviewed();
return _unreviewed;
}
void Authorizations::removeExpiredUnreviewed() {
const auto now = base::unixtime::now();
const auto period = _autoconfirmPeriod();
const auto oldSize = _unreviewed.size();
_unreviewed.erase(
std::remove_if(_unreviewed.begin(), _unreviewed.end(),
[=](const auto &auth) {
return (now - auth.date) >= period;
}),
_unreviewed.end());
if (_unreviewed.size() != oldSize) {
_saveUnreviewed();
}
}
void Authorizations::review(const std::vector<uint64> &hashes, bool confirm) {
for (const auto hash : hashes) {
if (const auto sent = _reviewRequests.take(hash)) {
_api.request(*sent).cancel();
}
}
const auto checkComplete = [=] {
if (_reviewRequests.empty()) {
_saveUnreviewed();
_unreviewedChanges.fire({});
}
};
for (const auto hash : hashes) {
const auto removeFromUnreviewed = [=] {
_unreviewed.erase(
std::remove_if(_unreviewed.begin(), _unreviewed.end(),
[hash](const auto &auth) { return auth.hash == hash; }),
_unreviewed.end());
_reviewRequests.remove(hash);
checkComplete();
};
if (confirm) {
using Flag = MTPaccount_ChangeAuthorizationSettings::Flag;
const auto id = _api.request(MTPaccount_ChangeAuthorizationSettings(
MTP_flags(Flag::f_confirmed),
MTP_long(hash),
MTPBool(), // encrypted_requests_disabled
MTPBool() // call_requests_disabled
)).done([=] {
removeFromUnreviewed();
}).fail([=] {
removeFromUnreviewed();
}).send();
_reviewRequests.emplace(hash, id);
} else {
const auto id = _api.request(MTPaccount_ResetAuthorization(
MTP_long(hash)
)).done([=](const MTPBool &result) {
if (mtpIsTrue(result)) {
_list.erase(
ranges::remove(_list, hash, &Entry::hash),
end(_list));
_listChanges.fire({});
}
removeFromUnreviewed();
}).fail([=] {
removeFromUnreviewed();
}).send();
_reviewRequests.emplace(hash, id);
}
}
}
rpl::producer<> Authorizations::unreviewedChanges() const {
return _unreviewedChanges.events();
}
void Authorizations::apply(const MTPUpdate &update) {
removeExpiredUnreviewed();
update.match([&](const MTPDupdateNewAuthorization &data) {
auto unreviewed = Data::UnreviewedAuth{
.hash = data.vhash().v,
.unconfirmed = data.is_unconfirmed(),
.date = data.vdate().value_or_empty(),
.device = qs(data.vdevice().value_or_empty()),
.location = qs(data.vlocation().value_or_empty())
};
if (!unreviewed.unconfirmed) {
const auto hash = unreviewed.hash;
const auto was = _unreviewed.size();
_unreviewed.erase(
std::remove_if(
_unreviewed.begin(),
_unreviewed.end(),
[hash](const auto &auth) { return auth.hash == hash; }),
_unreviewed.end());
if (was != _unreviewed.size()) {
_saveUnreviewed();
_unreviewedChanges.fire({});
}
return;
}
for (auto &auth : _unreviewed) {
if (auth.hash == unreviewed.hash) {
auth = std::move(unreviewed);
_saveUnreviewed();
_unreviewedChanges.fire({});
return;
}
}
_unreviewed.push_back(std::move(unreviewed));
_saveUnreviewed();
_unreviewedChanges.fire({});
}, [](auto&&) {
Unexpected("Update in Authorizations::apply.");
});
}
} // namespace Api

View File

@@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/data_authorization.h"
#include "mtproto/sender.h"
class ApiWrap;
@@ -35,6 +36,8 @@ public:
Fn<void(const MTP::Error &error)> &&fail,
std::optional<uint64> hash = std::nullopt);
void apply(const MTPUpdate &update);
[[nodiscard]] crl::time lastReceivedTime();
[[nodiscard]] List list() const;
@@ -42,6 +45,11 @@ public:
[[nodiscard]] int total() const;
[[nodiscard]] rpl::producer<int> totalValue() const;
[[nodiscard]] const std::vector<Data::UnreviewedAuth> &unreviewed();
[[nodiscard]] rpl::producer<> unreviewedChanges() const;
void review(const std::vector<uint64> &hashes, bool confirm);
void updateTTL(int days);
[[nodiscard]] rpl::producer<int> ttlDays() const;
@@ -57,6 +65,7 @@ public:
private:
void refreshCallsDisabledHereFromCloud();
void removeExpiredUnreviewed();
MTP::Sender _api;
mtpRequestId _requestId = 0;
@@ -64,10 +73,16 @@ private:
List _list;
rpl::event_stream<> _listChanges;
Fn<int()> _autoconfirmPeriod;
std::vector<Data::UnreviewedAuth> _unreviewed;
rpl::event_stream<> _unreviewedChanges;
Fn<void()> _saveUnreviewed;
mtpRequestId _ttlRequestId = 0;
rpl::variable<int> _ttlDays = 0;
base::flat_map<uint64, mtpRequestId> _toggleCallsDisabledRequests;
base::flat_map<uint64, mtpRequestId> _reviewRequests;
rpl::variable<bool> _callsDisabledHere;
crl::time _lastReceived = 0;

View File

@@ -142,13 +142,12 @@ void ConfirmSubscriptionBox(
const auto content = box->verticalLayout();
Ui::AddSkip(content, st::confirmInvitePhotoTop);
const auto userpicWrap = content->add(
object_ptr<Ui::CenterWrap<>>(
content,
object_ptr<Ui::RpWidget>(content)));
const auto userpic = userpicWrap->entity();
const auto userpic = content->add(
object_ptr<Ui::RpWidget>(content),
style::al_top);
const auto photoSize = st::confirmInvitePhotoSize;
userpic->resize(Size(photoSize));
userpic->setNaturalWidth(photoSize);
const auto creditsIconSize = photoSize / 3;
const auto creditsIconCallback =
Ui::PaintOutlinedColoredCreditsIconCallback(
@@ -188,8 +187,8 @@ void ConfirmSubscriptionBox(
}
auto p = QPainter(userpic);
p.drawImage(0, 0, state->frame);
}, userpicWrap->lifetime());
userpicWrap->setAttribute(Qt::WA_TransparentForMouseEvents);
}, userpic->lifetime());
userpic->setAttribute(Qt::WA_TransparentForMouseEvents);
if (photo) {
state->photoMedia = photo->createMediaView();
state->photoMedia->wanted(Data::PhotoSize::Small, Data::FileOrigin());
@@ -197,7 +196,7 @@ void ConfirmSubscriptionBox(
session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
userpic->update();
}, userpicWrap->entity()->lifetime());
}, userpic->lifetime());
}
} else {
state->photoEmpty = std::make_unique<Ui::EmptyUserpic>(
@@ -215,43 +214,40 @@ void ConfirmSubscriptionBox(
2.);
box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
object_ptr<Ui::FlatLabel>(
box,
object_ptr<Ui::FlatLabel>(
box,
tr::lng_channel_invite_subscription_title(),
st::inviteLinkSubscribeBoxTitle)));
tr::lng_channel_invite_subscription_title(),
st::inviteLinkSubscribeBoxTitle),
style::al_top);
box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
object_ptr<Ui::FlatLabel>(
box,
object_ptr<Ui::FlatLabel>(
box,
tr::lng_channel_invite_subscription_about(
lt_channel,
rpl::single(Ui::Text::Bold(name)),
lt_price,
tr::lng_credits_summary_options_credits(
lt_count,
rpl::single(amount) | tr::to_count(),
Ui::Text::Bold),
Ui::Text::WithEntities),
st::inviteLinkSubscribeBoxAbout)));
tr::lng_channel_invite_subscription_about(
lt_channel,
rpl::single(Ui::Text::Bold(name)),
lt_price,
tr::lng_credits_summary_options_credits(
lt_count,
rpl::single(amount) | tr::to_count(),
Ui::Text::Bold),
Ui::Text::WithEntities),
st::inviteLinkSubscribeBoxAbout),
style::al_top);
Ui::AddSkip(content);
box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
object_ptr<Ui::FlatLabel>(
box,
object_ptr<Ui::FlatLabel>(
box,
tr::lng_channel_invite_subscription_terms(
lt_link,
rpl::combine(
tr::lng_paid_react_agree_link(),
tr::lng_group_invite_subscription_about_url()
) | rpl::map([](const QString &text, const QString &url) {
return Ui::Text::Link(text, url);
}),
Ui::Text::RichLangValue),
st::inviteLinkSubscribeBoxTerms)));
tr::lng_channel_invite_subscription_terms(
lt_link,
rpl::combine(
tr::lng_paid_react_agree_link(),
tr::lng_group_invite_subscription_about_url()
) | rpl::map([](const QString &text, const QString &url) {
return Ui::Text::Link(text, url);
}),
Ui::Text::RichLangValue),
st::inviteLinkSubscribeBoxTerms),
style::al_top);
{
const auto balance = Settings::AddBalanceWidget(

View File

@@ -153,6 +153,7 @@ Data::CreditsHistoryEntry CreditsHistoryEntryFromTL(
.floodSkip = int(tl.data().vfloodskip_number().value_or(0)),
.converted = stargift && incoming,
.stargift = stargift.has_value(),
.postsSearch = tl.data().is_posts_search(),
.giftUpgraded = tl.data().is_stargift_upgrade(),
.giftResale = tl.data().is_stargift_resale(),
.reaction = tl.data().is_reaction(),

View File

@@ -159,6 +159,7 @@ void MessagesSearch::searchReceived(
// Don't apply cached data!
owner.processUsers(data.vusers());
owner.processChats(data.vchats());
_history->peer->processTopics(data.vtopics());
}
auto items = HistoryItemsFromTL(&owner, data.vmessages().v);
const auto total = int(data.vmessages().v.size());
@@ -168,6 +169,7 @@ void MessagesSearch::searchReceived(
// Don't apply cached data!
owner.processUsers(data.vusers());
owner.processChats(data.vchats());
_history->peer->processTopics(data.vtopics());
}
auto items = HistoryItemsFromTL(&owner, data.vmessages().v);
// data.vnext_rate() is used only in global search.
@@ -178,17 +180,14 @@ void MessagesSearch::searchReceived(
// Don't apply cached data!
owner.processUsers(data.vusers());
owner.processChats(data.vchats());
}
if (const auto channel = _history->peer->asChannel()) {
channel->ptsReceived(data.vpts().v);
if (_requestId != 0) {
// Don't apply cached data!
channel->processTopics(data.vtopics());
if (const auto channel = _history->peer->asChannel()) {
channel->ptsReceived(data.vpts().v);
} else {
LOG(("API Error: "
"received messages.channelMessages when no channel "
"was passed!"));
}
} else {
LOG(("API Error: "
"received messages.channelMessages when no channel "
"was passed!"));
_history->peer->processTopics(data.vtopics());
}
auto items = HistoryItemsFromTL(&owner, data.vmessages().v);
const auto total = int(data.vcount().v);

View File

@@ -9,7 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "data/data_peer.h"
#include "window/themes/window_theme.h"
#include "ui/chat/chat_style.h"
#include "ui/color_int_conversion.h"
namespace Api {
namespace {
@@ -20,8 +22,9 @@ constexpr auto kRequestEach = 3600 * crl::time(1000);
PeerColors::PeerColors(not_null<ApiWrap*> api)
: _api(&api->instance())
, _timer([=] { request(); }) {
, _timer([=] { request(); requestProfile(); }) {
request();
requestProfile();
_timer.callEach(kRequestEach);
}
@@ -45,6 +48,24 @@ void PeerColors::request() {
}).send();
}
void PeerColors::requestProfile() {
if (_profileRequestId) {
return;
}
_profileRequestId = _api.request(MTPhelp_GetPeerProfileColors(
MTP_int(_profileHash)
)).done([=](const MTPhelp_PeerColors &result) {
_profileRequestId = 0;
result.match([&](const MTPDhelp_peerColors &data) {
_profileHash = data.vhash().v;
applyProfile(data);
}, [](const MTPDhelp_peerColorsNotModified &) {
});
}).fail([=] {
_profileRequestId = 0;
}).send();
}
std::vector<uint8> PeerColors::suggested() const {
return _suggested.current();
}
@@ -76,21 +97,27 @@ const base::flat_map<uint8, int> &PeerColors::requiredLevelsChannel() const {
return _requiredLevelsChannel;
}
int PeerColors::requiredGroupLevelFor(PeerId channel, uint8 index) const {
int PeerColors::requiredLevelFor(
PeerId channel,
uint8 index,
bool isMegagroup,
bool profile) const {
if (Data::DecideColorIndex(channel) == index) {
return 0;
} else if (const auto i = _requiredLevelsGroup.find(index)
; i != end(_requiredLevelsGroup)) {
return i->second;
}
return 1;
}
int PeerColors::requiredChannelLevelFor(PeerId channel, uint8 index) const {
if (Data::DecideColorIndex(channel) == index) {
return 0;
} else if (const auto i = _requiredLevelsChannel.find(index)
; i != end(_requiredLevelsChannel)) {
if (profile) {
const auto it = _profileColors.find(index);
if (it != end(_profileColors)) {
return isMegagroup
? it->second.requiredLevelsGroup
: it->second.requiredLevelsChannel;
}
return 1;
}
const auto &levels = isMegagroup
? _requiredLevelsGroup
: _requiredLevelsChannel;
if (const auto i = levels.find(index); i != end(levels)) {
return i->second;
}
return 1;
@@ -165,4 +192,87 @@ void PeerColors::apply(const MTPDhelp_peerColors &data) {
_suggested = std::move(suggested);
}
void PeerColors::applyProfile(const MTPDhelp_peerColors &data) {
const auto parseColors = [](const MTPhelp_PeerColorSet &set) {
const auto toUint = [](const MTPint &c) {
return (uint32(1) << 24) | uint32(c.v);
};
return set.match([&](const MTPDhelp_peerColorSet &) {
LOG(("API Error: peerColorSet in profile colors result!"));
return Data::ColorProfileSet();
}, [&](const MTPDhelp_peerColorProfileSet &data) {
auto set = Data::ColorProfileSet();
set.palette.reserve(data.vpalette_colors().v.size());
set.bg.reserve(data.vbg_colors().v.size());
set.story.reserve(data.vstory_colors().v.size());
for (const auto &c : data.vpalette_colors().v) {
set.palette.push_back(Ui::ColorFromSerialized(toUint(c)));
}
for (const auto &c : data.vbg_colors().v) {
set.bg.push_back(Ui::ColorFromSerialized(toUint(c)));
}
for (const auto &c : data.vstory_colors().v) {
set.story.push_back(Ui::ColorFromSerialized(toUint(c)));
}
return set;
});
};
auto suggested = std::vector<Data::ColorProfileData>();
const auto &list = data.vcolors().v;
suggested.reserve(list.size());
for (const auto &color : list) {
const auto &data = color.data();
const auto colorIndexBare = data.vcolor_id().v;
if (colorIndexBare < 0 || colorIndexBare >= Ui::kColorIndexCount) {
LOG(("API Error: Bad color index: %1").arg(colorIndexBare));
continue;
}
const auto colorIndex = uint8(colorIndexBare);
auto result = ProfileColorOption();
result.isHidden = data.is_hidden();
if (const auto min = data.vgroup_min_level()) {
result.requiredLevelsGroup = min->v;
}
if (const auto min = data.vchannel_min_level()) {
result.requiredLevelsChannel = min->v;
}
if (const auto light = data.vcolors()) {
result.data.light = parseColors(*light);
}
if (const auto dark = data.vdark_colors()) {
result.data.dark = parseColors(*dark);
}
_profileColors[colorIndex] = std::move(result);
}
}
std::optional<Data::ColorProfileSet> PeerColors::colorProfileFor(
not_null<PeerData*> peer) const {
if (const auto colorProfileIndex = peer->colorProfileIndex()) {
return colorProfileFor(*colorProfileIndex);
}
return std::nullopt;
}
std::optional<Data::ColorProfileSet> PeerColors::colorProfileFor(
uint8 index) const {
const auto i = _profileColors.find(index);
if (i != end(_profileColors)) {
return Window::Theme::IsNightMode()
? i->second.data.dark
: i->second.data.light;
}
return std::nullopt;
}
std::vector<uint8> PeerColors::profileColorIndices() const {
auto result = std::vector<uint8>();
result.reserve(_profileColors.size());
for (const auto &[index, option] : _profileColors) {
result.push_back(index);
}
return result;
}
} // namespace Api

View File

@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "base/timer.h"
#include "data/data_peer_colors.h"
#include "mtproto/sender.h"
class ApiWrap;
@@ -34,27 +35,45 @@ public:
[[nodiscard]] auto requiredLevelsChannel() const
-> const base::flat_map<uint8, int> &;
[[nodiscard]] int requiredGroupLevelFor(
PeerId channel,
uint8 index) const;
[[nodiscard]] int requiredChannelLevelFor(
[[nodiscard]] int requiredLevelFor(
PeerId channel,
uint8 index,
bool isMegagroup,
bool profile) const;
[[nodiscard]] std::optional<Data::ColorProfileSet> colorProfileFor(
not_null<PeerData*> peer) const;
[[nodiscard]] std::optional<Data::ColorProfileSet> colorProfileFor(
uint8 index) const;
[[nodiscard]] std::vector<uint8> profileColorIndices() const;
private:
struct ProfileColorOption {
Data::ColorProfileData data;
int requiredLevelsChannel = 0;
int requiredLevelsGroup = 0;
bool isHidden = false;
};
void request();
void requestProfile();
void apply(const MTPDhelp_peerColors &data);
void applyProfile(const MTPDhelp_peerColors &data);
MTP::Sender _api;
int32 _hash = 0;
int32 _profileHash = 0;
mtpRequestId _requestId = 0;
mtpRequestId _profileRequestId = 0;
base::Timer _timer;
rpl::variable<std::vector<uint8>> _suggested;
base::flat_map<uint8, int> _requiredLevelsGroup;
base::flat_map<uint8, int> _requiredLevelsChannel;
rpl::event_stream<> _colorIndicesChanged;
std::unique_ptr<Ui::ColorIndicesCompressed> _colorIndicesCurrent;
base::flat_map<uint8, ProfileColorOption> _profileColors;
};

View File

@@ -22,13 +22,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
namespace Api {
namespace {
[[nodiscard]] TimeId UnixtimeFromMsgId(mtpMsgId msgId) {
return TimeId(msgId >> 32);
}
} // namespace
Polls::Polls(not_null<ApiWrap*> api)
: _session(&api->session())

View File

@@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_app_config.h"
#include "main/main_session.h"
#include "payments/payments_form.h"
#include "ui/chat/chat_style.h" // ColorCollectible
#include "ui/text/format_values.h"
namespace Api {
@@ -45,15 +46,17 @@ namespace {
auto options = PremiumSubscriptionOptionsFromTL(tlOptions);
for (auto i = 0; i < options.size(); i++) {
const auto &tlOption = tlOptions[i].data();
const auto currency = qs(tlOption.vcurrency());
const auto perUserText = Ui::FillAmountAndCurrency(
tlOption.vamount().v / float64(tlOption.vusers().v),
qs(tlOption.vcurrency()),
currency,
false);
options[i].costPerMonth = perUserText
+ ' '
+ QChar(0x00D7)
+ ' '
+ QString::number(tlOption.vusers().v);
options[i].currency = currency;
}
return options;
}
@@ -613,24 +616,32 @@ std::vector<GiftOptionData> PremiumGiftCodeOptions::optionsForPeer() const {
return result;
}
Data::PremiumSubscriptionOptions PremiumGiftCodeOptions::options(int amount) {
const auto it = _subscriptionOptions.find(amount);
Data::PremiumSubscriptionOptions PremiumGiftCodeOptions::optionsForGiveaway(
int usersCount) {
const auto skipForStars = [&](Data::PremiumSubscriptionOptions options) {
const auto proj = &Data::PremiumSubscriptionOption::currency;
options.erase(
ranges::remove(options, Ui::kCreditsCurrency, proj),
end(options));
return options;
};
const auto it = _subscriptionOptions.find(usersCount);
if (it != end(_subscriptionOptions)) {
return it->second;
return skipForStars(it->second);
} else {
auto tlOptions = QVector<MTPPremiumGiftCodeOption>();
for (auto i = 0; i < _optionsForOnePerson.months.size(); i++) {
tlOptions.push_back(MTP_premiumGiftCodeOption(
MTP_flags(MTPDpremiumGiftCodeOption::Flags(0)),
MTP_int(amount),
MTP_int(usersCount),
MTP_int(_optionsForOnePerson.months[i]),
MTPstring(),
MTPint(),
MTP_string(_optionsForOnePerson.currencies[i]),
MTP_long(_optionsForOnePerson.totalCosts[i] * amount)));
MTP_long(_optionsForOnePerson.totalCosts[i] * usersCount)));
}
_subscriptionOptions[amount] = GiftCodesFromTL(tlOptions);
return _subscriptionOptions[amount];
_subscriptionOptions[usersCount] = GiftCodesFromTL(tlOptions);
return skipForStars(_subscriptionOptions[usersCount]);
}
}
@@ -853,7 +864,9 @@ std::optional<Data::StarGift> FromTL(
.perUserRemains = data.vper_user_remains().value_or_empty(),
.firstSaleDate = data.vfirst_sale_date().value_or_empty(),
.lastSaleDate = data.vlast_sale_date().value_or_empty(),
.lockedUntilDate = data.vlocked_until_date().value_or_empty(),
.requirePremium = data.is_require_premium(),
.peerColorAvailable = data.is_peer_color_available(),
.upgradable = data.vupgrade_stars().has_value(),
.birthday = data.is_birthday(),
.soldOut = data.is_sold_out(),
@@ -880,27 +893,56 @@ std::optional<Data::StarGift> FromTL(
const auto releasedById = data.vreleased_by()
? peerFromMTP(*data.vreleased_by())
: PeerId();
const auto themeUserId = data.vtheme_peer()
? peerFromMTP(*data.vtheme_peer())
: PeerId();
const auto releasedBy = releasedById
? session->data().peer(releasedById).get()
: nullptr;
const auto themeUser = themeUserId
? session->data().peer(themeUserId).get()
: nullptr;
const auto colorCollectible = (data.vpeer_color()
&& data.vpeer_color()->type() == mtpc_peerColorCollectible)
? std::make_shared<Ui::ColorCollectible>(
Data::ParseColorCollectible(
data.vpeer_color()->c_peerColorCollectible()))
: nullptr;
auto result = Data::StarGift{
.id = uint64(data.vid().v),
.id = data.vid().v,
.unique = std::make_shared<Data::UniqueGift>(Data::UniqueGift{
.id = data.vid().v,
.initialGiftId = data.vgift_id().v,
.slug = qs(data.vslug()),
.title = qs(data.vtitle()),
.giftAddress = qs(data.vgift_address().value_or_empty()),
.ownerAddress = qs(data.vowner_address().value_or_empty()),
.ownerName = qs(data.vowner_name().value_or_empty()),
.ownerId = (data.vowner_id()
? peerFromMTP(*data.vowner_id())
: PeerId()),
.hostId = (data.vhost_id()
? peerFromMTP(*data.vhost_id())
: PeerId()),
.releasedBy = releasedBy,
.themeUser = themeUser,
.nanoTonForResale = FindTonForResale(data.vresell_amount()),
.starsForResale = FindStarsForResale(data.vresell_amount()),
.number = data.vnum().v,
.onlyAcceptTon = data.is_resale_ton_only(),
.canBeTheme = data.is_theme_available(),
.model = *model,
.pattern = *pattern,
.value = (data.vvalue_amount()
? std::make_shared<Data::UniqueGiftValue>(
Data::UniqueGiftValue{
.currency = qs(
data.vvalue_currency().value_or_empty()),
.valuePrice = int64(
data.vvalue_amount().value_or_empty()),
})
: nullptr),
.peerColor = colorCollectible,
}),
.document = model->document,
.releasedBy = releasedBy,
@@ -950,20 +992,22 @@ std::optional<Data::SavedStarGift> FromTL(
| ranges::to_vector)
: std::vector<int>()),
.message = (data.vmessage()
? TextWithEntities{
.text = qs(data.vmessage()->data().vtext()),
.entities = Api::EntitiesFromMTP(
session,
data.vmessage()->data().ventities().v),
}
? Api::ParseTextWithEntities(
session,
*data.vmessage())
: TextWithEntities()),
.starsConverted = int64(data.vconvert_stars().value_or_empty()),
.starsUpgradedBySender = int64(
data.vupgrade_stars().value_or_empty()),
.starsForDetailsRemove = int64(
data.vdrop_original_details_stars().value_or_empty()),
.giftPrepayUpgradeHash = qs(
data.vprepaid_upgrade_hash().value_or_empty()),
.fromId = (data.vfrom_id()
? peerFromMTP(*data.vfrom_id())
: PeerId()),
.date = data.vdate().v,
.upgradeSeparate = data.is_upgrade_separate(),
.upgradable = data.is_can_upgrade(),
.anonymous = data.is_name_hidden(),
.pinned = data.is_pinned_to_top() && hasUnique,

View File

@@ -180,7 +180,8 @@ public:
[[nodiscard]] rpl::producer<rpl::no_value, QString> request();
[[nodiscard]] std::vector<GiftOptionData> optionsForPeer() const;
[[nodiscard]] Data::PremiumSubscriptionOptions options(int amount);
[[nodiscard]] Data::PremiumSubscriptionOptions optionsForGiveaway(
int usersCount);
[[nodiscard]] const std::vector<int> &availablePresets() const;
[[nodiscard]] int monthsFromPreset(int monthsIndex);
[[nodiscard]] Payments::InvoicePremiumGiftCode invoice(

View File

@@ -25,10 +25,6 @@ namespace {
constexpr auto kSendTogglesDelay = 3 * crl::time(1000);
[[nodiscard]] TimeId UnixtimeFromMsgId(mtpMsgId msgId) {
return TimeId(msgId >> 32);
}
} // namespace
TodoLists::TodoLists(not_null<ApiWrap*> api)

View File

@@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item_helpers.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
#include "main/main_session_settings.h"
namespace Api {
@@ -25,6 +26,32 @@ Transcribes::Transcribes(not_null<ApiWrap*> api)
, _api(&api->instance()) {
}
bool Transcribes::isRated(not_null<HistoryItem*> item) const {
const auto fullId = item->fullId();
for (const auto &[transcribeId, id] : _ids) {
if (id == fullId) {
return _session->settings().isTranscriptionRated(transcribeId);
}
}
return false;
}
void Transcribes::rate(not_null<HistoryItem*> item, bool isGood) {
const auto fullId = item->fullId();
for (const auto &[transcribeId, id] : _ids) {
if (id == fullId) {
_api.request(MTPmessages_RateTranscribedAudio(
item->history()->peer->input,
MTP_int(item->id),
MTP_long(transcribeId),
MTP_bool(isGood))).send();
_session->settings().markTranscriptionAsRated(transcribeId);
_session->saveSettings();
return;
}
}
}
bool Transcribes::freeFor(not_null<HistoryItem*> item) const {
if (const auto channel = item->history()->peer->asMegagroup()) {
const auto owner = &channel->owner();

View File

@@ -37,6 +37,8 @@ public:
void apply(const MTPDupdateTranscribedAudio &update);
[[nodiscard]] bool freeFor(not_null<HistoryItem*> item) const;
[[nodiscard]] bool isRated(not_null<HistoryItem*> item) const;
void rate(not_null<HistoryItem*> item, bool isGood);
[[nodiscard]] bool trialsSupport();
[[nodiscard]] TimeId trialsRefreshAt();

View File

@@ -51,6 +51,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h"
#include "history/history_item.h"
#include "history/history_item_helpers.h"
#include "history/history_streamed_drafts.h"
#include "history/history_unread_things.h"
#include "core/application.h"
#include "storage/storage_account.h"
@@ -1096,6 +1097,9 @@ void Updates::handleSendActionUpdate(
const auto from = (fromId == session().userPeerId())
? session().user().get()
: session().data().peerLoaded(fromId);
const auto when = requestingDifference()
? 0
: base::unixtime::now();
if (action.type() == mtpc_speakingInGroupCallAction) {
handleSpeakingInCall(peer, fromId, from);
}
@@ -1108,10 +1112,11 @@ void Updates::handleSendActionUpdate(
const auto &data = action.c_sendMessageEmojiInteractionSeen();
handleEmojiInteraction(peer, qs(data.vemoticon()));
return;
} else if (action.type() == mtpc_sendMessageTextDraftAction) {
const auto &data = action.c_sendMessageTextDraftAction();
history->streamedDrafts().apply(rootId, fromId, when, data);
return;
}
const auto when = requestingDifference()
? 0
: base::unixtime::now();
session().data().sendActionManager().registerFor(
history,
rootId,
@@ -1622,6 +1627,17 @@ void Updates::feedUpdate(const MTPUpdate &update) {
auto &d = update.c_updateNewChannelMessage();
auto channel = session().data().channelLoaded(peerToChannel(PeerFromMessage(d.vmessage())));
const auto isDataLoaded = AllDataLoadedForMessage(&session(), d.vmessage());
{
// Todo delete.
const auto messageId = IdFromMessage(d.vmessage());
if (const auto history = channel ? session().data().historyLoaded(channel) : nullptr) {
if (history->isUnknownMessageDeleted(messageId)) {
LOG(("Unknown message deleted detected for channel %1, message %2")
.arg(channel->id.value & PeerId::kChatTypeMask)
.arg(messageId.bare));
}
}
}
if (!requestingDifference() && (!channel || isDataLoaded != DataIsLoadedResult::Ok)) {
MTP_LOG(0, ("getDifference "
"{ good - after not all data loaded in updateNewChannelMessage }%1"
@@ -1951,7 +1967,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
auto &d = update.c_updateUserTyping();
handleSendActionUpdate(
peerFromUser(d.vuser_id()),
0,
d.vtop_msg_id().value_or_empty(),
peerFromUser(d.vuser_id()),
d.vaction());
} break;
@@ -2123,7 +2139,9 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateGroupCallParticipants:
case mtpc_updateGroupCallChainBlocks:
case mtpc_updateGroupCallConnection:
case mtpc_updateGroupCall: {
case mtpc_updateGroupCall:
case mtpc_updateGroupCallMessage:
case mtpc_updateGroupCallEncryptedMessage: {
Core::App().calls().handleUpdate(&session(), update);
} break;
@@ -2213,6 +2231,10 @@ void Updates::feedUpdate(const MTPUpdate &update) {
}
} break;
case mtpc_updateNewAuthorization: {
session().api().authorizations().apply(update);
} break;
case mtpc_updateServiceNotification: {
const auto &d = update.c_updateServiceNotification();
const auto text = TextWithEntities {
@@ -2480,9 +2502,9 @@ void Updates::feedUpdate(const MTPUpdate &update) {
}
} break;
case mtpc_updateChannelPinnedTopic: {
const auto &d = update.c_updateChannelPinnedTopic();
const auto peerId = peerFromChannel(d.vchannel_id());
case mtpc_updatePinnedForumTopic: {
const auto &d = update.c_updatePinnedForumTopic();
const auto peerId = peerFromMTP(d.vpeer());
if (const auto peer = session().data().peerLoaded(peerId)) {
const auto rootId = d.vtopic_id().v;
if (const auto topic = peer->forumTopicFor(rootId)) {
@@ -2493,9 +2515,9 @@ void Updates::feedUpdate(const MTPUpdate &update) {
}
} break;
case mtpc_updateChannelPinnedTopics: {
const auto &d = update.c_updateChannelPinnedTopics();
const auto peerId = peerFromChannel(d.vchannel_id());
case mtpc_updatePinnedForumTopics: {
const auto &d = update.c_updatePinnedForumTopics();
const auto peerId = peerFromMTP(d.vpeer());
if (const auto peer = session().data().peerLoaded(peerId)) {
if (const auto forum = peer->forum()) {
const auto done = [&] {

View File

@@ -134,7 +134,7 @@ rpl::producer<rpl::no_value, Usernames::Error> Usernames::toggle(
if (list.empty()) {
if (error == Error::Unknown) {
it->second.done.fire_done();
} else if (error == Error::TooMuch) {
} else {
it->second.done.fire_error_copy(error);
}
_toggleRequests.remove(peerId);
@@ -149,6 +149,8 @@ rpl::producer<rpl::no_value, Usernames::Error> Usernames::toggle(
const auto type = error.type();
if (type == u"USERNAMES_ACTIVE_TOO_MUCH"_q) {
pop(Error::TooMuch);
} else if (type.startsWith(u"FLOOD_WAIT_"_q)) {
pop(Error::Flood);
} else {
pop(Error::Unknown);
}
@@ -158,19 +160,19 @@ rpl::producer<rpl::no_value, Usernames::Error> Usernames::toggle(
_api.request(MTPaccount_ToggleUsername(
MTP_string(username),
MTP_bool(active)
)).done(done).fail(fail).send();
)).done(done).fail(fail).handleFloodErrors().send();
} else if (const auto channel = peer->asChannel()) {
_api.request(MTPchannels_ToggleUsername(
channel->inputChannel,
MTP_string(username),
MTP_bool(active)
)).done(done).fail(fail).send();
)).done(done).fail(fail).handleFloodErrors().send();
} else if (const auto botUserInput = BotUserInput(peer)) {
_api.request(MTPbots_ToggleUsername(
*botUserInput,
MTP_string(username),
MTP_bool(active)
)).done(done).fail(fail).send();
)).done(done).fail(fail).handleFloodErrors().send();
} else {
return rpl::never<rpl::no_value, Error>();
}

View File

@@ -23,6 +23,7 @@ class Usernames final {
public:
enum class Error {
TooMuch,
Flood,
Unknown,
};

View File

@@ -44,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_forum_topic.h"
#include "data/data_forum.h"
#include "data/data_saved_messages.h"
#include "data/data_saved_music.h"
#include "data/data_saved_sublist.h"
#include "data/data_search_controller.h"
#include "data/data_session.h"
@@ -106,10 +107,6 @@ using PhotoFileLocationId = Data::PhotoFileLocationId;
using DocumentFileLocationId = Data::DocumentFileLocationId;
using UpdatedFileReferences = Data::UpdatedFileReferences;
[[nodiscard]] TimeId UnixtimeFromMsgId(mtpMsgId msgId) {
return TimeId(msgId >> 32);
}
[[nodiscard]] std::shared_ptr<ChatHelpers::Show> ShowForPeer(
not_null<PeerData*> peer) {
if (const auto window = Core::App().windowFor(peer)) {
@@ -154,6 +151,14 @@ void ShowChannelsLimitBox(not_null<PeerData*> peer) {
} // namespace
namespace Api {
TimeId UnixtimeFromMsgId(mtpMsgId msgId) {
return TimeId(msgId >> 32);
}
} // namespace Api
ApiWrap::ApiWrap(not_null<Main::Session*> session)
: MTP::Sender(&session->account().mtp())
, _session(session)
@@ -204,6 +209,27 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
ApiWrap::~ApiWrap() = default;
void ApiWrap::ProcessRecentSelfForwards(
not_null<Main::Session*> session,
const MTPUpdates &updates,
PeerId targetPeerId,
PeerId fromPeerId) {
auto newIds = MessageIdsList();
updates.match([&](const MTPDupdates &data) {
for (const auto &update : data.vupdates().v) {
update.match([&](const MTPDupdateMessageID &d) {
newIds.push_back(FullMsgId(targetPeerId, d.vid().v));
}, [](const auto &) {});
}
}, [](const auto &) {});
if (!newIds.empty()) {
session->data().addRecentSelfForwards({
.fromPeerId = fromPeerId,
.ids = newIds,
});
}
}
Main::Session &ApiWrap::session() const {
return *_session;
}
@@ -374,9 +400,9 @@ void ApiWrap::savePinnedOrder(not_null<Data::Forum*> forum) {
order,
ranges::back_inserter(topics),
input);
request(MTPchannels_ReorderPinnedForumTopics(
MTP_flags(MTPchannels_ReorderPinnedForumTopics::Flag::f_force),
forum->channel()->inputChannel,
request(MTPmessages_ReorderPinnedForumTopics(
MTP_flags(MTPmessages_ReorderPinnedForumTopics::Flag::f_force),
forum->peer()->input,
MTP_vector(topics)
)).done([=](const MTPUpdates &result) {
applyUpdates(result);
@@ -1088,6 +1114,8 @@ void ApiWrap::requestWallPaper(
void ApiWrap::requestFullPeer(not_null<PeerData*> peer) {
if (_fullPeerRequests.contains(peer)) {
return;
} else if (!peer->isUser() && !peer->barSettings().has_value()) {
requestPeerSettings(peer);
}
const auto requestId = [&] {
@@ -1886,7 +1914,7 @@ void ApiWrap::sendNotifySettingsUpdates() {
for (const auto topic : base::take(_updateNotifyTopics)) {
request(MTPaccount_UpdateNotifySettings(
MTP_inputNotifyForumTopic(
topic->channel()->input,
topic->peer()->input,
MTP_int(topic->rootId())),
topic->notify().serialize()
)).afterDelay(kSmallDelayMs).send();
@@ -2179,7 +2207,7 @@ void ApiWrap::saveDraftsToCloud() {
history->finishSavingCloudDraft(
topicRootId,
monoforumPeerId,
UnixtimeFromMsgId(response.outerMsgId));
Api::UnixtimeFromMsgId(response.outerMsgId));
const auto cloudDraft = history->cloudDraft(
topicRootId,
monoforumPeerId);
@@ -2200,7 +2228,7 @@ void ApiWrap::saveDraftsToCloud() {
history->finishSavingCloudDraft(
topicRootId,
monoforumPeerId,
UnixtimeFromMsgId(response.outerMsgId));
Api::UnixtimeFromMsgId(response.outerMsgId));
const auto cloudDraft = history->cloudDraft(
topicRootId,
monoforumPeerId);
@@ -2458,7 +2486,17 @@ void ApiWrap::refreshFileReference(
v::match(origin.data, [&](Data::FileOriginMessage data) {
if (const auto item = _session->data().message(data)) {
const auto media = item->media();
const auto storyId = media ? media->storyId() : FullStoryId();
const auto mediaStory = media ? media->storyId() : FullStoryId();
const auto storyId = mediaStory
? mediaStory
: FullStoryId{
(IsStoryMsgId(item->id)
? item->history()->peer->id
: PeerId()),
(IsStoryMsgId(item->id)
? StoryIdFromMsgId(item->id)
: StoryId())
};
if (storyId) {
request(MTPstories_GetStoriesByID(
_session->data().peer(storyId.peer)->input,
@@ -2469,6 +2507,17 @@ void ApiWrap::refreshFileReference(
request(MTPmessages_GetScheduledMessages(
item->history()->peer->input,
MTP_vector<MTPint>(1, MTP_int(realId))));
} else if (item->isSavedMusicItem()) {
const auto user = item->history()->peer->asUser();
const auto media = item->media();
const auto document = media ? media->document() : nullptr;
if (user && document) {
request(MTPusers_GetSavedMusicByID(
user->inputUser,
MTP_vector<MTPInputDocument>(1, document->mtpInput())));
} else {
fail();
}
} else if (item->isBusinessShortcut()) {
const auto &shortcuts = _session->data().shortcutMessages();
const auto realId = shortcuts.lookupId(item);
@@ -3030,18 +3079,20 @@ void ApiWrap::requestMessageAfterDate(
return &messages.vmessages().v;
};
const auto list = result.match([&](
const MTPDmessages_messages &data) {
const MTPDmessages_messages &data) {
peer->processTopics(data.vtopics());
return handleMessages(data);
}, [&](const MTPDmessages_messagesSlice &data) {
peer->processTopics(data.vtopics());
return handleMessages(data);
}, [&](const MTPDmessages_channelMessages &data) {
if (const auto channel = peer->asChannel()) {
channel->ptsReceived(data.vpts().v);
channel->processTopics(data.vtopics());
} else {
LOG(("API Error: received messages.channelMessages when "
"no channel was passed! (ApiWrap::jumpToDate)"));
}
peer->processTopics(data.vtopics());
return handleMessages(data);
}, [&](const MTPDmessages_messagesNotModified &) {
LOG(("API Error: received messages.messagesNotModified! "
@@ -3340,8 +3391,8 @@ void ApiWrap::finishForwarding(const SendAction &action) {
return;
}
forwardMessages(std::move(toForward), action);
history->setForwardDraft(topicRootId, monoforumPeerId, {});
forwardMessages(std::move(toForward), action);
}
_session->data().sendHistoryChangeNotifications();
@@ -3362,6 +3413,22 @@ void ApiWrap::forwardMessages(
auto &histories = _session->data().histories();
for (auto i = begin(draft.items); i != end(draft.items);) {
const auto item = *i;
if (item->isSavedMusicItem()) {
SendExistingDocument(MessageToSend(action), item->media()->document());
i = draft.items.erase(i);
} else {
++i;
}
}
if (draft.items.empty()) {
if (successCallback) {
successCallback();
}
return;
}
struct SharedCallback {
int requestsLeft = 0;
FnMut<void()> callback;
@@ -3477,6 +3544,13 @@ void ApiWrap::forwardMessages(
shared->callback();
}
finish();
if (peer->isSelf() && session().premium()) {
ProcessRecentSelfForwards(
_session,
result,
peer->id,
forwardFrom->id);
}
}).fail([=](const MTP::Error &error) {
if (idsCopy) {
for (const auto &[randomId, itemId] : *idsCopy) {
@@ -3841,7 +3915,9 @@ void ApiWrap::sendShortcutMessages(
}).send();
}
void ApiWrap::sendMessage(MessageToSend &&message) {
void ApiWrap::sendMessage(
MessageToSend &&message,
std::optional<MsgId> localMessageId) {
const auto history = message.action.history;
const auto peer = history->peer;
auto &textWithTags = message.textWithTags;
@@ -3891,7 +3967,9 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
auto newId = FullMsgId(
peer->id,
_session->data().nextLocalMessageId());
localMessageId
? std::exchange(localMessageId, std::nullopt).value()
: _session->data().nextLocalMessageId());
auto randomId = base::RandomValue<uint64>();
TextUtilities::Trim(sending);
@@ -4017,7 +4095,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
history->finishSavingCloudDraft(
draftTopicRootId,
draftMonoforumPeerId,
UnixtimeFromMsgId(response.outerMsgId));
Api::UnixtimeFromMsgId(response.outerMsgId));
}
};
const auto fail = [=](
@@ -4032,7 +4110,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
history->finishSavingCloudDraft(
draftTopicRootId,
draftMonoforumPeerId,
UnixtimeFromMsgId(response.outerMsgId));
Api::UnixtimeFromMsgId(response.outerMsgId));
}
};
const auto mtpShortcut = Data::ShortcutIdToMTP(
@@ -4228,7 +4306,7 @@ void ApiWrap::sendInlineResult(
history->finishSavingCloudDraft(
topicRootId,
monoforumPeerId,
UnixtimeFromMsgId(response.outerMsgId));
Api::UnixtimeFromMsgId(response.outerMsgId));
if (done) {
done(true);
}
@@ -4237,7 +4315,7 @@ void ApiWrap::sendInlineResult(
history->finishSavingCloudDraft(
topicRootId,
monoforumPeerId,
UnixtimeFromMsgId(response.outerMsgId));
Api::UnixtimeFromMsgId(response.outerMsgId));
if (done) {
done(false);
}

View File

@@ -28,7 +28,7 @@ namespace Data {
struct UpdatedFileReferences;
class WallPaper;
struct ResolvedForwardDraft;
enum class DefaultNotify;
enum class DefaultNotify : uint8_t;
enum class StickersType : uchar;
class Forum;
class ForumTopic;
@@ -129,6 +129,8 @@ QString RequestKey(Types &&...values) {
return result;
}
[[nodiscard]] TimeId UnixtimeFromMsgId(mtpMsgId msgId);
} // namespace Api
class ApiWrap final : public MTP::Sender {
@@ -363,7 +365,9 @@ public:
void sendShortcutMessages(
not_null<PeerData*> peer,
BusinessShortcutId id);
void sendMessage(MessageToSend &&message);
void sendMessage(
MessageToSend &&message,
std::optional<MsgId> localMessageId = std::nullopt);
void sendBotStart(
std::shared_ptr<Ui::Show> show,
not_null<UserData*> bot,
@@ -428,6 +432,12 @@ public:
static constexpr auto kJoinErrorDuration = 5 * crl::time(1000);
static void ProcessRecentSelfForwards(
not_null<Main::Session*> session,
const MTPUpdates &updates,
PeerId targetPeerId,
PeerId fromPeerId);
private:
struct MessageDataRequest {
using Callbacks = std::vector<Fn<void()>>;

View File

@@ -13,12 +13,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/update_checker.h"
#include "lang/lang_keys.h"
#include "ui/boxes/confirm_box.h"
#include "ui/painter.h"
#include "ui/rect.h"
#include "ui/text/text_utilities.h"
#include "ui/vertical_list.h"
#include "ui/widgets/buttons.h"
#include "ui/wrap/vertical_layout.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
#include "styles/style_channel_earn.h"
#include "styles/style_chat.h"
#include "styles/style_dialogs.h"
#include "styles/style_menu_icons.h"
#include "styles/style_premium.h"
#include "styles/style_settings.h"
#include <QtGui/QGuiApplication>
#include <QtGui/QClipboard>
@@ -158,3 +166,151 @@ QString currentVersionText() {
#endif
return result;
}
void ArchiveHintBox(
not_null<Ui::GenericBox*> box,
bool unarchiveOnNewMessage,
Fn<void()> onUnarchive) {
box->setNoContentMargin(true);
const auto content = box->verticalLayout().get();
Ui::AddSkip(content);
Ui::AddSkip(content);
Ui::AddSkip(content);
{
const auto &icon = st::dialogsArchiveUserpic;
const auto rect = Rect(icon.size() * 2);
auto owned = object_ptr<Ui::RpWidget>(content);
owned->resize(rect.size());
owned->setNaturalWidth(rect.width());
const auto widget = box->addRow(std::move(owned), style::al_top);
widget->paintRequest(
) | rpl::start_with_next([=] {
auto p = Painter(widget);
auto hq = PainterHighQualityEnabler(p);
p.setPen(Qt::NoPen);
p.setBrush(st::activeButtonBg);
p.drawEllipse(rect);
icon.paintInCenter(p, rect);
}, widget->lifetime());
}
Ui::AddSkip(content);
Ui::AddSkip(content);
box->addRow(
object_ptr<Ui::FlatLabel>(
content,
tr::lng_archive_hint_title(),
st::boxTitle),
style::al_top);
Ui::AddSkip(content);
Ui::AddSkip(content);
{
const auto label = box->addRow(
object_ptr<Ui::FlatLabel>(
content,
(unarchiveOnNewMessage
? tr::lng_archive_hint_about_unmuted
: tr::lng_archive_hint_about)(
lt_link,
tr::lng_archive_hint_about_link(
lt_emoji,
rpl::single(
Ui::Text::IconEmoji(&st::textMoreIconEmoji)),
Ui::Text::RichLangValue
) | rpl::map([](TextWithEntities text) {
return Ui::Text::Link(std::move(text), 1);
}),
Ui::Text::RichLangValue),
st::channelEarnHistoryRecipientLabel));
label->resizeToWidth(box->width()
- rect::m::sum::h(st::boxRowPadding));
label->setLink(
1,
std::make_shared<GenericClickHandler>([=](ClickContext context) {
if (context.button == Qt::LeftButton) {
onUnarchive();
}
}));
}
Ui::AddSkip(content);
Ui::AddSkip(content);
Ui::AddSkip(content);
Ui::AddSkip(content);
{
const auto padding = QMargins(
st::settingsButton.padding.left(),
st::boxRowPadding.top(),
st::boxRowPadding.right(),
st::boxRowPadding.bottom());
const auto addEntry = [&](
rpl::producer<QString> title,
rpl::producer<QString> about,
const style::icon &icon) {
const auto top = content->add(
object_ptr<Ui::FlatLabel>(
content,
std::move(title),
st::channelEarnSemiboldLabel),
padding);
Ui::AddSkip(content, st::channelEarnHistoryThreeSkip);
content->add(
object_ptr<Ui::FlatLabel>(
content,
std::move(about),
st::channelEarnHistoryRecipientLabel),
padding);
const auto left = Ui::CreateChild<Ui::RpWidget>(
box->verticalLayout().get());
left->paintRequest(
) | rpl::start_with_next([=] {
auto p = Painter(left);
icon.paint(p, 0, 0, left->width());
}, left->lifetime());
left->resize(icon.size());
top->geometryValue(
) | rpl::start_with_next([=](const QRect &g) {
left->moveToLeft(
(g.left() - left->width()) / 2,
g.top() + st::channelEarnHistoryThreeSkip);
}, left->lifetime());
};
addEntry(
tr::lng_archive_hint_section_1(),
tr::lng_archive_hint_section_1_info(),
st::menuIconArchive);
Ui::AddSkip(content);
Ui::AddSkip(content);
addEntry(
tr::lng_archive_hint_section_2(),
tr::lng_archive_hint_section_2_info(),
st::menuIconStealth);
Ui::AddSkip(content);
Ui::AddSkip(content);
addEntry(
tr::lng_archive_hint_section_3(),
tr::lng_archive_hint_section_3_info(),
st::menuIconStoriesSavedSection);
Ui::AddSkip(content);
Ui::AddSkip(content);
}
Ui::AddSkip(content);
Ui::AddSkip(content);
Ui::AddSkip(content);
{
const auto &st = st::premiumPreviewDoubledLimitsBox;
box->setStyle(st);
auto button = object_ptr<Ui::RoundButton>(
box,
tr::lng_archive_hint_button(),
st::defaultActiveButton);
button->setTextTransform(
Ui::RoundButton::TextTransform::NoTransform);
button->resizeToWidth(box->width()
- st.buttonPadding.left()
- st.buttonPadding.left());
button->setClickedCallback([=] { box->closeBox(); });
box->addButton(std::move(button));
}
}

View File

@@ -10,6 +10,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/layers/generic_box.h"
void AboutBox(not_null<Ui::GenericBox*> box);
void ArchiveHintBox(
not_null<Ui::GenericBox*> box,
bool unarchiveOnNewMessage,
Fn<void()> onUnarchive);
QString telegramFaqLink();
QString currentVersionText();

View File

@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/file_utilities.h"
#include "lang/lang_keys.h"
#include "ui/layers/generic_box.h"
#include "ui/text/text_utilities.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
#include "styles/style_boxes.h"
@@ -18,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui {
namespace {
constexpr auto kUrl = "https://promote.telegram.org"_cs;
constexpr auto kUrl = "https://ads.telegram.org"_cs;
} // namespace
@@ -54,8 +55,16 @@ void AboutSponsoredBox(not_null<Ui::GenericBox*> box) {
};
const auto &stLabel = st::aboutLabel;
const auto info1 = box->addRow(object_ptr<FlatLabel>(box, stLabel));
info1->setText(tr::lng_sponsored_info_description1(tr::now));
auto text1 = tr::lng_sponsored_info_description1_linked(
lt_link,
rpl::combine(
tr::lng_sponsored_info_description1_link(),
tr::lng_sponsored_info_description1_url()
) | rpl::map([](const QString &text, const QString &url) {
return Ui::Text::Link(text, url);
}),
Ui::Text::RichLangValue);
box->addRow(object_ptr<FlatLabel>(box, std::move(text1), stLabel));
box->addSkip(st::sponsoredUrlButtonSkip);
addUrl();

View File

@@ -451,12 +451,12 @@ auto BackgroundBox::Inner::resolveResetCustomPaper() const
return {};
}
const auto nonCustom = Window::Theme::Background()->paper();
const auto themeEmoji = _forPeer->themeEmoji();
if (forChannel() || themeEmoji.isEmpty()) {
const auto themeToken = _forPeer->themeToken();
if (forChannel() || themeToken.isEmpty()) {
return nonCustom;
}
const auto &themes = _forPeer->owner().cloudThemes();
const auto theme = themes.themeForEmoji(themeEmoji);
const auto theme = themes.themeForToken(themeToken);
if (!theme) {
return nonCustom;
}

View File

@@ -161,7 +161,7 @@ constexpr auto kMaxWallPaperSlugLength = 255;
return paper;
}
const auto &themes = session->data().cloudThemes();
if (const auto theme = themes.themeForEmoji(paper.emojiId())) {
if (const auto theme = themes.themeForToken(paper.emojiId())) {
using Type = Data::CloudThemeType;
const auto type = dark ? Type::Dark : Type::Light;
const auto i = theme->settings.find(type);

View File

@@ -754,11 +754,17 @@ createPollFieldTitlePadding: margins(22px, 7px, 10px, 6px);
sendGifWithCaptionEmojiPosition: point(-30px, 23px);
notesFieldWithEmoji: InputField(defaultInputField) {
textMargins: margins(0px, 28px, 30px, 4px);
// border: 0px;
// borderActive: 0px;
}
backgroundCheckbox: Checkbox(defaultCheckbox) {
textFg: msgServiceFg;
textFgActive: msgServiceFg;
width: -50px;
width: -10px;
margin: margins(0px, 0px, 0px, 0px);
textPosition: point(0px, 6px);
@@ -807,6 +813,7 @@ urlAuthCheckbox: Checkbox(defaultBoxCheckbox) {
addContactFieldMargin: margins(19px, 0px, 19px, 10px);
addContactWarningMargin: margins(19px, 10px, 19px, 5px);
editContactSuggestBirthday: icon{{ "settings/birthday_add-22x22", lightButtonFg }};
blockUserConfirmation: FlatLabel(boxLabel) {
minWidth: 240px;
}
@@ -1116,8 +1123,16 @@ moderateBoxExpandInnerSkip: 2px;
moderateBoxExpandFont: font(11px);
moderateBoxExpandToggleSize: 4px;
moderateBoxExpandToggleFourStrokes: 3px;
moderateBoxExpandIcon: icon{{ "info/edit/expand_arrow_small-flip_vertical", windowActiveTextFg }};
moderateBoxExpandIconDown: icon{{ "info/edit/expand_arrow_small", windowActiveTextFg }};
moderateBoxExpandIcon: IconEmoji{
icon: icon{{ "info/edit/expand_arrow_small-flip_vertical", windowActiveTextFg }};
padding: margins(-2px, -1px, 0px, 0px);
useIconColor: true;
}
moderateBoxExpandIconDown: IconEmoji{
icon: icon{{ "info/edit/expand_arrow_small", windowActiveTextFg }};
padding: margins(-2px, -1px, 0px, 0px);
useIconColor: true;
}
moderateBoxDividerLabel: FlatLabel(boxDividerLabel) {
palette: TextPalette(defaultTextPalette) {
selectLinkFg: windowActiveTextFg;

View File

@@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/labels.h"
#include "ui/rect.h"
#include "ui/wrap/slide_wrap.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
@@ -111,16 +112,13 @@ void DeleteMessagesBox::prepare() {
Ui::Text::RichLangValue);
deleteStyle = &st::attentionBoxButton;
} else if (_wipeHistoryJustClear) {
const auto isChannel = peer->isBroadcast();
const auto isPublicGroup = peer->isMegagroup()
&& peer->asChannel()->isPublic();
if (isChannel || isPublicGroup) {
canDelete = false;
}
const auto isChannel = peer->isChannel() && !peer->isMegagroup();
_revokeJustClearForChannel = isChannel;
details.text = isChannel
? tr::lng_no_clear_history_channel(tr::now)
: isPublicGroup
? tr::lng_no_clear_history_group(tr::now)
? tr::lng_sure_delete_channel_history(
tr::now,
lt_channel,
peer->name())
: peer->isSelf()
? tr::lng_sure_delete_saved_messages(tr::now)
: peer->isUser()
@@ -156,7 +154,8 @@ void DeleteMessagesBox::prepare() {
}
deleteStyle = &st::attentionBoxButton;
}
if (auto revoke = revokeText(peer)) {
if (_revokeJustClearForChannel) {
} else if (auto revoke = revokeText(peer)) {
_revoke.create(
this,
revoke->checkbox,
@@ -226,12 +225,14 @@ void DeleteMessagesBox::prepare() {
search->searchMessages({ .from = _moderateFrom });
}
} else {
details.text = (_ids.size() == 1)
details.text = hasSavedMusicMessages()
? tr::lng_selected_remove_saved_music(tr::now)
: (_ids.size() == 1)
? tr::lng_selected_delete_sure_this(tr::now)
: tr::lng_selected_delete_sure(tr::now, lt_count, _ids.size());
if (const auto peer = checkFromSinglePeer()) {
auto count = int(_ids.size());
if (hasScheduledMessages()) {
if (hasScheduledMessages() || hasSavedMusicMessages()) {
} else if (auto revoke = revokeText(peer)) {
const auto &settings = Core::App().settings();
const auto revokeByDefault
@@ -285,6 +286,7 @@ void DeleteMessagesBox::prepare() {
}
}
_text.create(this, rpl::single(std::move(details)), st::boxLabel);
_text->resizeToWidth(st::boxWidth - rect::m::sum::h(st::boxPadding));
if (_wipeHistoryJustClear && _wipeHistoryPeer) {
const auto validator = TTLMenu::TTLValidator(
@@ -314,28 +316,36 @@ void DeleteMessagesBox::prepare() {
addButton(tr::lng_about_done(), [=] { closeBox(); });
}
auto fullHeight = st::boxPadding.top()
+ _text->height()
+ st::boxPadding.bottom();
if (_moderateFrom) {
fullHeight += st::boxMediumSkip;
if (_banUser) {
fullHeight += _banUser->heightNoMargins() + st::boxLittleSkip;
const auto &padding = st::boxPadding;
rpl::combine(
widthValue(),
_text->naturalWidthValue()
) | rpl::start_with_next([=](int full, int) {
_text->resizeToNaturalWidth(full - padding.left() - padding.right());
auto fullHeight = st::boxPadding.top()
+ _text->height()
+ st::boxPadding.bottom();
if (_moderateFrom) {
fullHeight += st::boxMediumSkip;
if (_banUser) {
fullHeight += _banUser->heightNoMargins() + st::boxLittleSkip;
}
fullHeight += _reportSpam->heightNoMargins();
if (_deleteAll) {
fullHeight += st::boxLittleSkip + _deleteAll->heightNoMargins();
}
} else if (_revoke) {
fullHeight += st::boxMediumSkip + _revoke->heightNoMargins();
}
fullHeight += _reportSpam->heightNoMargins();
if (_deleteAll) {
fullHeight += st::boxLittleSkip + _deleteAll->heightNoMargins();
if (_autoDeleteSettings) {
fullHeight += st::boxMediumSkip
+ _autoDeleteSettings->height()
+ st::boxLittleSkip;
}
} else if (_revoke) {
fullHeight += st::boxMediumSkip + _revoke->heightNoMargins();
}
if (_autoDeleteSettings) {
fullHeight += st::boxMediumSkip
+ _autoDeleteSettings->height()
+ st::boxLittleSkip;
}
setDimensions(st::boxWidth, fullHeight);
_fullHeight = fullHeight;
setDimensions(st::boxWidth, fullHeight);
_fullHeight = fullHeight;
}, lifetime());
}
bool DeleteMessagesBox::hasScheduledMessages() const {
@@ -349,6 +359,17 @@ bool DeleteMessagesBox::hasScheduledMessages() const {
return false;
}
bool DeleteMessagesBox::hasSavedMusicMessages() const {
for (const auto &fullId : _ids) {
if (const auto item = _session->data().message(fullId)) {
if (item->isSavedMusicItem()) {
return true;
}
}
}
return false;
}
PeerData *DeleteMessagesBox::checkFromSinglePeer() const {
auto result = (PeerData*)nullptr;
for (const auto &fullId : _ids) {
@@ -554,12 +575,17 @@ void DeleteMessagesBox::deleteAndClear() {
!_revoke->checked());
Core::App().saveSettingsDelayed();
}
const auto revoke = _revoke ? _revoke->checked() : _revokeForBot;
const auto revoke = _revoke
? _revoke->checked()
: (_revokeForBot || _revokeJustClearForChannel);
const auto session = _session;
const auto invokeCallbackAndClose = [&] {
// deleteMessages can initiate closing of the current section,
// which will cause this box to be destroyed.
const auto weak = base::make_weak(this);
if (hasSavedMusicMessages()) {
uiShow()->showToast(tr::lng_saved_music_removed(tr::now));
}
if (const auto callback = _deleteConfirmedCallback) {
callback();
}

View File

@@ -58,6 +58,7 @@ private:
void deleteAndClear();
[[nodiscard]] PeerData *checkFromSinglePeer() const;
[[nodiscard]] bool hasScheduledMessages() const;
[[nodiscard]] bool hasSavedMusicMessages() const;
[[nodiscard]] std::optional<RevokeConfig> revokeText(
not_null<PeerData*> peer) const;
[[nodiscard]] PaidPostType paidPostType() const;
@@ -75,6 +76,7 @@ private:
bool _moderateDeleteAll = false;
bool _revokeForBot = false;
bool _revokeJustClearForChannel = false;
object_ptr<Ui::FlatLabel> _text = { nullptr };
object_ptr<Ui::Checkbox> _revoke = { nullptr };

View File

@@ -525,6 +525,14 @@ void EditCaptionBox::rebuildPreview() {
_content->modifyRequests(
) | rpl::start_to_stream(_photoEditorOpens, _content->lifetime());
_content->editCoverRequests() | rpl::start_with_next([=] {
setupEditCoverHandler();
}, _content->lifetime());
_content->clearCoverRequests() | rpl::start_with_next([=] {
setupClearCoverHandler();
}, _content->lifetime());
_content->heightValue(
) | rpl::start_to_stream(_contentHeight, _content->lifetime());
@@ -740,6 +748,89 @@ void EditCaptionBox::setupPhotoEditorEventHandler() {
}, lifetime());
}
void EditCaptionBox::setupEditCoverHandler() {
if (_preparedList.files.empty()) {
return;
}
const auto &file = _preparedList.files.front();
if (!file.isVideoFile()) {
return;
}
const auto show = _controller->uiShow();
const auto replace = [=](Ui::PreparedList list) {
if (list.files.empty()) {
return;
}
auto &entry = _preparedList.files.front();
const auto video = entry.information
? std::get_if<Ui::PreparedFileInformation::Video>(
&entry.information->media)
: nullptr;
if (!video) {
return;
}
auto old = std::shared_ptr<Ui::PreparedFile>(
std::move(entry.videoCover));
entry.videoCover = std::make_unique<Ui::PreparedFile>(
std::move(list.files.front()));
Editor::OpenWithPreparedFile(
this,
show,
entry.videoCover.get(),
st::sendMediaPreviewSize,
crl::guard(this, [=](bool ok) {
if (!ok) {
_preparedList.files.front().videoCover = old
? std::make_unique<Ui::PreparedFile>(
std::move(*old))
: nullptr;
}
rebuildPreview();
}),
video->thumbnail.size());
};
const auto checkResult = [=](const Ui::PreparedList &list) {
if (list.files.empty()) {
return true;
}
if (list.files.front().type != Ui::PreparedFile::Type::Photo) {
show->showToast(tr::lng_choose_cover_bad(tr::now));
return false;
}
return true;
};
const auto callback = [=](FileDialog::OpenResult &&result) {
const auto premium = show->session().premium();
const auto showError = [=](tr::phrase<> t) {
show->showToast(t(tr::now));
};
auto list = Storage::PreparedFileFromFilesDialog(
std::move(result),
checkResult,
showError,
st::sendMediaPreviewSize,
premium);
if (list) {
replace(std::move(*list));
}
};
FileDialog::GetOpenPath(
this,
tr::lng_choose_cover(tr::now),
FileDialog::ImagesFilter(),
crl::guard(this, callback));
}
void EditCaptionBox::setupClearCoverHandler() {
if (_preparedList.files.empty()) {
return;
}
auto &entry = _preparedList.files.front();
entry.videoCover = nullptr;
rebuildPreview();
}
void EditCaptionBox::setupDragArea() {
auto enterFilter = [=](not_null<const QMimeData*> data) {
return !_isAllowedEditMedia

View File

@@ -87,6 +87,8 @@ private:
void rebuildPreview();
void setupEditEventHandler();
void setupPhotoEditorEventHandler();
void setupEditCoverHandler();
void setupClearCoverHandler();
void setupField();
void setupFieldAutocomplete();
void setupControls();

View File

@@ -8,37 +8,42 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/edit_privacy_box.h"
#include "api/api_global_privacy.h"
#include "apiwrap.h"
#include "boxes/filters/edit_filter_chats_list.h"
#include "ui/effects/premium_graphics.h"
#include "ui/layers/generic_box.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/continuous_sliders.h"
#include "ui/widgets/shadow.h"
#include "ui/text/format_values.h"
#include "ui/text/text_utilities.h"
#include "ui/toast/toast.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/painter.h"
#include "ui/vertical_list.h"
#include "boxes/peers/edit_peer_invite_link.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_peer_values.h"
#include "data/data_user.h"
#include "history/history.h"
#include "boxes/peer_list_controllers.h"
#include "lang/lang_keys.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
#include "settings/settings_premium.h"
#include "settings/settings_privacy_controllers.h"
#include "settings/settings_privacy_security.h"
#include "calls/calls_instance.h"
#include "lang/lang_keys.h"
#include "apiwrap.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
#include "data/data_user.h"
#include "data/data_chat.h"
#include "data/data_channel.h"
#include "data/data_peer_values.h"
#include "ui/boxes/peer_qr_box.h"
#include "ui/controls/invite_link_buttons.h"
#include "ui/controls/invite_link_label.h"
#include "ui/effects/premium_graphics.h"
#include "ui/layers/generic_box.h"
#include "ui/painter.h"
#include "ui/text/format_values.h"
#include "ui/text/text_utilities.h"
#include "ui/toast/toast.h"
#include "ui/vertical_list.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/continuous_sliders.h"
#include "ui/widgets/popup_menu.h"
#include "ui/widgets/shadow.h"
#include "ui/wrap/slide_wrap.h"
#include "window/window_session_controller.h"
#include "styles/style_boxes.h"
#include "styles/style_settings.h"
#include "styles/style_info.h"
#include "styles/style_layers.h"
#include "styles/style_menu_icons.h"
#include "styles/style_settings.h"
#include "styles/style_window.h"
namespace {
@@ -473,15 +478,15 @@ auto PrivacyExceptionsBoxController::createRow(not_null<History*> history)
const auto labels = raw->add(object_ptr<Ui::RpWidget>(raw));
const auto min = Ui::CreateChild<Ui::FlatLabel>(
raw,
QString::number(minValue),
Lang::FormatCountDecimal(minValue),
*labelStyle);
const auto max = Ui::CreateChild<Ui::FlatLabel>(
raw,
QString::number(maxValue),
Lang::FormatCountDecimal(maxValue),
*labelStyle);
const auto current = Ui::CreateChild<Ui::FlatLabel>(
raw,
QString::number(value),
Lang::FormatCountDecimal(value),
*labelStyle);
min->setTextColorOverride(st::windowSubTextFg->c);
max->setTextColorOverride(st::windowSubTextFg->c);
@@ -511,7 +516,7 @@ auto PrivacyExceptionsBoxController::createRow(not_null<History*> history)
};
const auto updateByValue = [=](int value) {
current->setText(value > 0
? tr::lng_action_gift_for_stars(tr::now, lt_count, value)
? tr::lng_action_gift_for_stars(tr::now, lt_count_decimal, value)
: tr::lng_manage_monoforum_free(tr::now));
state->index = 0;
@@ -1293,7 +1298,7 @@ void EditDirectMessagesPriceBox(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
box,
object_ptr<Ui::VerticalLayout>(box)),
{});
style::margins());
wrap->toggle(savedValue.has_value(), anim::type::instant);
wrap->toggleOn(toggle->toggledChanges());
@@ -1312,6 +1317,58 @@ void EditDirectMessagesPriceBox(
*result = stars;
}, box->lifetime());
if (const auto username = channel->username(); !username.isEmpty()) {
Ui::AddSkip(inner);
Ui::AddSubsectionTitle(
inner,
tr::lng_manage_monoforum_link_subtitle());
constexpr auto kDirectParam = "?direct"_cs;
const auto link = channel->session().createInternalLinkFull(username)
+ kDirectParam.utf8();
const auto copyLink = [=] {
TextUtilities::SetClipboardText(TextForMimeData::Simple(link));
box->uiShow()->showToast(tr::lng_group_invite_copied(tr::now));
};
const auto shareLink = [=] {
box->uiShow()->showBox(ShareInviteLinkBox(channel, link));
};
const auto createMenu = [=] {
auto result = base::make_unique_q<Ui::PopupMenu>(
inner,
st::popupMenuWithIcons);
result->addAction(
tr::lng_group_invite_context_qr(tr::now),
[=] {
box->uiShow()->showBox(Box([=](
not_null<Ui::GenericBox*> qrBox) {
Ui::FillPeerQrBox(qrBox, channel, link, nullptr);
}));
},
&st::menuIconQrCode);
return result;
};
auto linkText = Ui::Text::StripUrlProtocol(link);
const auto label = inner->lifetime().make_state<Ui::InviteLinkLabel>(
inner,
rpl::single(std::move(linkText)),
createMenu);
inner->add(
label->take(),
st::inviteLinkFieldPadding);
label->clicks() | rpl::start_with_next(copyLink, label->lifetime());
Ui::AddSkip(inner);
AddCopyShareLinkButtons(inner, copyLink, shareLink);
Ui::AddSkip(inner);
Ui::AddSkip(inner);
Ui::AddDivider(inner);
}
box->addButton(tr::lng_settings_save(), [=] {
const auto weak = base::make_weak(box);
callback(toggle->toggled() ? *result : std::optional<int>());

View File

@@ -143,6 +143,11 @@ private:
int id,
TextWithEntities text,
anim::type animated);
void insertTask(
int beforeIndex,
int id,
TextWithEntities text,
anim::type animated);
void initTaskField(not_null<Task*> task, TextWithEntities text);
void checkLastTask();
void validateState();
@@ -150,6 +155,9 @@ private:
void destroy(std::unique_ptr<Task> task);
void removeDestroyed(not_null<Task*> field);
int findField(not_null<Ui::InputField*> field) const;
void handlePaste(
not_null<Ui::InputField*> field,
const QStringList &list);
not_null<Ui::BoxContent*> _box;
not_null<Ui::VerticalLayout*> _container;
@@ -187,6 +195,27 @@ void InitField(
options);
}
[[nodiscard]] QStringList ParsePastedList(const QString &text) {
auto list = QStringView(text).split('\n');
for (auto i = list.begin(); i != list.end();) {
auto text = i->trimmed();
if (text.isEmpty() && (i + 1 != list.end())) {
i = list.erase(i);
} else {
*i++ = text;
}
}
if (list.size() < 2) {
return {};
}
auto result = QStringList();
result.reserve(list.size());
for (const auto &view : list) {
result.push_back(view.toString());
}
return result;
}
not_null<Ui::FlatLabel*> CreateWarningLabel(
not_null<QWidget*> parent,
not_null<Ui::InputField*> field,
@@ -263,11 +292,14 @@ Tasks::Task::Task(
session->user()->isPremium()
? st::createPollOptionFieldPremium
: st::createPollOptionField,
Ui::InputField::Mode::NoNewlines,
Ui::InputField::Mode::MultiLine,
tr::lng_todo_create_list_add()))
, _limit(session->appConfig().todoListItemTextLimit()) {
InitField(outer, _field, session);
_field->setMaxLength(_limit + kErrorLimit);
// Don't limit max length, because user can paste long list of items.
//_field->setMaxLength(_limit + kErrorLimit);
_field->show();
if (locked) {
_field->setDisabled(true);
@@ -629,24 +661,35 @@ void Tasks::addTask(
int id,
TextWithEntities text,
anim::type animated) {
insertTask(_list.size(), id, std::move(text), animated);
}
void Tasks::insertTask(
int beforeIndex,
int id,
TextWithEntities text,
anim::type animated) {
if (full()) {
return;
}
Assert(beforeIndex >= 0 && beforeIndex <= _list.size());
if (_list.size() > 1) {
(*(_list.end() - 2))->removePlaceholder();
(*(_list.end() - 2))->toggleRemoveAlways(true);
}
const auto locked = id && _existingLocked;
_list.push_back(std::make_unique<Task>(
_box,
_container,
&_controller->session(),
id,
_position + _list.size() + _destroyed.size(),
locked));
const auto field = _list.back()->field();
const auto i = _list.insert(
begin(_list) + beforeIndex,
std::make_unique<Task>(
_box,
_container,
&_controller->session(),
id,
_position + beforeIndex + _destroyed.size(),
locked));
const auto field = i->get()->field();
if (!locked) {
initTaskField(_list.back().get(), std::move(text));
initTaskField(i->get(), std::move(text));
} else {
InitMessageFieldHandlers(
_controller,
@@ -659,7 +702,7 @@ void Tasks::addTask(
});
}
field->finishAnimating();
_list.back()->show(animated);
i->get()->show(animated);
fixShadows();
}
@@ -706,6 +749,14 @@ void Tasks::initTaskField(not_null<Task*> task, TextWithEntities text) {
}, field->lifetime());
field->changes(
) | rpl::start_with_next([=] {
auto list = ParsePastedList(field->getLastText());
if (!list.empty()) {
field->setText(list.front());
field->forceProcessContentsChanges();
list.pop_front();
handlePaste(field, list);
}
Ui::PostponeCall(crl::guard(field, [=] {
validateState();
}));
@@ -793,6 +844,27 @@ int Tasks::findField(not_null<Ui::InputField*> field) const {
return result;
}
void Tasks::handlePaste(
not_null<Ui::InputField*> field,
const QStringList &list) {
const auto index = findField(field);
for (auto i = 0, count = int(list.size()); i != count; ++i) {
insertTask(
index + 1 + i,
0, // id
TextWithEntities{ list[i] },
anim::type::instant);
}
const auto last = std::min(
int(index + list.size()),
int(_list.size()) - 1);
const auto add = _list[last]->field();
crl::on_main(add, [=] {
add->setCursorPosition(add->getLastText().size());
add->setFocus();
});
}
void Tasks::checkLastTask() {
removeEmptyTail();
addEmptyTask();

View File

@@ -40,6 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/filter_icons.h"
#include "ui/layers/generic_box.h"
#include "ui/painter.h"
#include "ui/rect.h"
#include "ui/power_saving.h"
#include "ui/vertical_list.h"
#include "ui/widgets/buttons.h"
@@ -593,7 +594,7 @@ void EditFilterBox(
) | rpl::start_with_next([=](const QRect &r) {
const auto h = st::normalFont->height;
preview->setGeometry(
colors->x(),
rect::right(colors) - st::settingsFilterTagPreviewSkip,
r.y() + (r.height() - h) / 2 + st::lineWidth,
colors->width(),
h);

View File

@@ -538,25 +538,24 @@ void LinkController::addHeader(not_null<Ui::VerticalLayout*> container) {
const auto isStatic = _filterTitle.isStatic;
verticalLayout->add(
object_ptr<Ui::CenterWrap<>>(
object_ptr<Ui::FlatLabel>(
verticalLayout,
object_ptr<Ui::FlatLabel>(
verticalLayout,
(_data.url.isEmpty()
? tr::lng_filters_link_no_about(Ui::Text::WithEntities)
: tr::lng_filters_link_share_about(
lt_folder,
rpl::single(Ui::Text::Wrapped(
_filterTitle.text,
EntityType::Bold)),
Ui::Text::WithEntities)),
st::settingsFilterDividerLabel,
st::defaultPopupMenu,
Core::TextContext({
.session = &_window->session(),
.customEmojiLoopLimit = isStatic ? -1 : 0,
}))),
st::filterLinkDividerLabelPadding);
(_data.url.isEmpty()
? tr::lng_filters_link_no_about(Ui::Text::WithEntities)
: tr::lng_filters_link_share_about(
lt_folder,
rpl::single(Ui::Text::Wrapped(
_filterTitle.text,
EntityType::Bold)),
Ui::Text::WithEntities)),
st::settingsFilterDividerLabel,
st::defaultPopupMenu,
Core::TextContext({
.session = &_window->session(),
.customEmojiLoopLimit = isStatic ? -1 : 0,
})),
st::filterLinkDividerLabelPadding,
style::al_top)->setTryMakeSimilarLines(true);
verticalLayout->geometryValue(
) | rpl::start_with_next([=](const QRect &r) {

View File

@@ -24,7 +24,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/rect.h"
#include "ui/text/text_utilities.h"
#include "ui/vertical_list.h"
#include "ui/widgets/label_with_custom_emoji.h"
#include "window/window_session_controller.h"
#include "styles/style_boxes.h"
#include "styles/style_channel_earn.h"
@@ -53,9 +52,8 @@ void GiftCreditsBox(
Ui::AddSkip(content);
const auto &stUser = st::premiumGiftsUserpicButton;
const auto userpicWrap = content->add(
object_ptr<Ui::CenterWrap<>>(
content,
object_ptr<Ui::UserpicButton>(content, peer, stUser)));
object_ptr<Ui::UserpicButton>(content, peer, stUser),
style::al_top);
userpicWrap->setAttribute(Qt::WA_TransparentForMouseEvents);
Ui::AddSkip(content);
Ui::AddSkip(content);
@@ -78,19 +76,17 @@ void GiftCreditsBox(
u"internal:stars_examples"_q);
});
content->add(
object_ptr<Ui::CenterWrap<>>(
object_ptr<Ui::FlatLabel>(
content,
Ui::CreateLabelWithCustomEmoji(
content,
tr::lng_credits_box_history_entry_gift_out_about(
lt_user,
rpl::single(TextWithEntities{ peer->shortName() }),
lt_link,
std::move(link),
Ui::Text::RichLangValue),
Core::TextContext({ .session = &peer->session() }),
st::creditsBoxAbout)),
st::boxRowPadding);
tr::lng_credits_box_history_entry_gift_out_about(
lt_user,
rpl::single(TextWithEntities{ peer->shortName() }),
lt_link,
std::move(link),
Ui::Text::RichLangValue),
st::creditsBoxAbout),
st::boxRowPadding,
style::al_top);
}
Ui::AddSkip(content);
Ui::AddSkip(box->verticalLayout());
@@ -101,6 +97,7 @@ void GiftCreditsBox(
peer,
CreditsAmount(),
[=] { gifted(); box->uiShow()->hideLayer(); },
box->showFinishes(),
tr::lng_credits_summary_options_subtitle(),
{});

File diff suppressed because it is too large Load Diff

View File

@@ -23,6 +23,7 @@ struct CreditsHistoryEntry;
struct GiveawayStart;
struct GiveawayResults;
struct SubscriptionEntry;
struct UniqueGift;
} // namespace Data
namespace Main {
@@ -77,7 +78,12 @@ void AddStarGiftTable(
Settings::CreditsEntryBoxStyleOverrides st,
const Data::CreditsHistoryEntry &entry,
Fn<void()> convertToStars,
Fn<void()> startUpgrade);
Fn<void()> startUpgrade,
Fn<void(Fn<void()> removed)> removeDetails);
void AddTransferGiftTable(
std::shared_ptr<ChatHelpers::Show> show,
not_null<Ui::VerticalLayout*> container,
std::shared_ptr<Data::UniqueGift> unique);
void AddCreditsHistoryEntryTable(
std::shared_ptr<ChatHelpers::Show> show,
not_null<Ui::VerticalLayout*> container,
@@ -106,3 +112,9 @@ void AddChannelEarnTable(
std::shared_ptr<Ui::Show> show,
not_null<Ui::VerticalLayout*> container,
const Data::CreditsHistoryEntry &entry);
void AddUniqueGiftValueTable(
std::shared_ptr<ChatHelpers::Show> show,
not_null<Ui::VerticalLayout*> container,
Settings::CreditsEntryBoxStyleOverrides st,
const Data::CreditsHistoryEntry &entry);

View File

@@ -138,6 +138,8 @@ void CreateModerateMessagesBox(
not_null<Ui::GenericBox*> box,
const HistoryItemsList &items,
Fn<void()> confirmed) {
Expects(!items.empty());
using Controller = Ui::ExpandablePeerListController;
const auto [allCanBan, allCanDelete, participants]
@@ -158,8 +160,12 @@ void CreateModerateMessagesBox(
participants.size()).width(),
0);
const auto session = &items.front()->history()->session();
const auto historyPeerId = items.front()->history()->peer->id;
const auto itemsCount = int(items.size());
const auto firstItem = items.front();
const auto history = firstItem->history();
const auto session = &history->session();
const auto historyPeerId = history->peer->id;
const auto ids = session->data().itemsToIds(items);
using Request = Fn<void(not_null<PeerData*>, not_null<ChannelData*>)>;
const auto sequentiallyRequest = [=](
@@ -242,11 +248,11 @@ void CreateModerateMessagesBox(
const auto title = box->addRow(
object_ptr<Ui::FlatLabel>(
box,
(items.size() == 1)
(itemsCount == 1)
? tr::lng_selected_delete_sure_this()
: tr::lng_selected_delete_sure(
lt_count,
rpl::single(items.size()) | tr::to_count()),
rpl::single(itemsCount) | tr::to_count()),
st::boxLabel));
Ui::AddSkip(inner);
Ui::AddSkip(inner);
@@ -264,7 +270,6 @@ void CreateModerateMessagesBox(
Ui::AddExpandablePeerList(report, controller, inner);
handleSubmition(report);
const auto ids = items.front()->from()->owner().itemsToIds(items);
handleConfirmation(report, controller, [=](
not_null<PeerData*> p,
not_null<ChannelData*> c) {
@@ -296,12 +301,11 @@ void CreateModerateMessagesBox(
: tr::lng_delete_all_from_user(
tr::now,
lt_user,
Ui::Text::Bold(items.front()->from()->name()),
Ui::Text::Bold(firstItem->from()->name()),
Ui::Text::WithEntities),
false,
st::defaultBoxCheckbox),
st::boxRowPadding + buttonPadding);
const auto history = items.front()->history();
auto messagesCounts = MessagesCountValue(history, participants);
const auto controller = box->lifetime().make_state<Controller>(
@@ -311,6 +315,10 @@ void CreateModerateMessagesBox(
});
Ui::AddExpandablePeerList(deleteAll, controller, inner);
{
auto itemFromIds = items | ranges::views::transform([](
const auto &item) {
return item->from()->id;
}) | ranges::to_vector;
tr::lng_selected_delete_sure(
lt_count,
rpl::combine(
@@ -320,7 +328,7 @@ void CreateModerateMessagesBox(
: rpl::merge(
controller->toggleRequestsFromInner.events(),
controller->checkAllRequests.events())
) | rpl::map([=, s = items.size()](const auto &map, bool c) {
) | rpl::map([=](const auto &map, bool c) {
const auto checked = (isSingle && !c)
? Participants()
: controller->collectRequests
@@ -335,9 +343,9 @@ void CreateModerateMessagesBox(
}
}
}
for (const auto &item : items) {
for (const auto &fromId : itemFromIds) {
for (const auto &peer : checked) {
if (peer->id == item->from()->id) {
if (peer->id == fromId) {
result--;
break;
}
@@ -403,22 +411,10 @@ void CreateModerateMessagesBox(
const auto container = wrap->entity();
wrap->toggle(false, anim::type::instant);
const auto session = &participants.front()->session();
const auto emojiMargin = QMargins(
-st::moderateBoxExpandInnerSkip,
-st::moderateBoxExpandInnerSkip / 2,
0,
0);
const auto emojiUp = Ui::Text::SingleCustomEmoji(
session->data().customEmojiManager().registerInternalEmoji(
st::moderateBoxExpandIcon,
emojiMargin,
false));
const auto emojiDown = Ui::Text::SingleCustomEmoji(
session->data().customEmojiManager().registerInternalEmoji(
st::moderateBoxExpandIconDown,
emojiMargin,
false));
const auto emojiUp = Ui::Text::IconEmoji(
&st::moderateBoxExpandIcon);
const auto emojiDown = Ui::Text::IconEmoji(
&st::moderateBoxExpandIconDown);
auto label = object_ptr<Ui::FlatLabel>(
inner,
@@ -463,9 +459,7 @@ void CreateModerateMessagesBox(
Ui::Text::WithEntities);
}) | rpl::flatten_latest(
) | rpl::start_with_next([=](const TextWithEntities &text) {
raw->setMarkedText(
Ui::Text::Link(text, u"internal:"_q),
Core::TextContext({ .session = session }));
raw->setMarkedText(Ui::Text::Link(text, u"internal:"_q));
}, label->lifetime());
Ui::AddSkip(inner);

View File

@@ -728,8 +728,8 @@ QString PeerListRow::generateShortName() {
}
Ui::PeerUserpicView &PeerListRow::ensureUserpicView() {
if (!_userpic.cloud && peer()->userpicPaintingPeer()->hasUserpic()) {
_userpic = peer()->userpicPaintingPeer()->createUserpicView();
if (!_userpic.cloud && peer()->hasUserpic()) {
_userpic = peer()->createUserpicView();
}
return _userpic;
}
@@ -738,9 +738,9 @@ PaintRoundImageCallback PeerListRow::generatePaintUserpicCallback(
bool forceRound) {
const auto saved = !_savedMessagesStatus.isEmpty();
const auto replies = _isRepliesMessagesChat;
const auto peer = this->peer()->userpicPaintingPeer();
const auto peer = this->peer();
auto userpic = saved ? Ui::PeerUserpicView() : ensureUserpicView();
if (forceRound && peer->isForum()) {
if (forceRound && (peer->isForum() || peer->isMonoforum())) {
return ForceRoundUserpicCallback(peer);
}
return [=](Painter &p, int x, int y, int outerWidth, int size) mutable {
@@ -1460,7 +1460,8 @@ void PeerListContent::setSearchMode(PeerListSearchMode mode) {
_loadingAnimation = Ui::CreateLoadingPeerListItemWidget(
this,
_st.item,
2);
2,
_controller->computeListSt().bg->c);
}
}
} else {

View File

@@ -981,9 +981,9 @@ void ChooseTopicSearchController::searchQuery(const QString &query) {
}
void ChooseTopicSearchController::searchOnServer() {
_requestId = _api.request(MTPchannels_GetForumTopics(
MTP_flags(MTPchannels_GetForumTopics::Flag::f_q),
_forum->channel()->inputChannel,
_requestId = _api.request(MTPmessages_GetForumTopics(
MTP_flags(MTPmessages_GetForumTopics::Flag::f_q),
_forum->peer()->input,
MTP_string(_query),
MTP_int(_offsetDate),
MTP_int(_offsetId),

View File

@@ -233,7 +233,8 @@ void FillUpgradeToPremiumCover(
container,
rpl::single(text),
st::inviteForbiddenInfo),
st::inviteForbiddenInfoPadding);
st::inviteForbiddenInfoPadding,
style::al_top);
}
void SimpleForbiddenBox(
@@ -511,7 +512,8 @@ void InviteForbiddenController::setComplexCover() {
if (_can) {
container->add(
MakeShowOrLabel(container, tr::lng_invite_upgrade_or()),
st::inviteForbiddenOrLabelPadding);
st::inviteForbiddenOrLabelPadding,
style::al_justify);
}
container->add(
object_ptr<Ui::FlatLabel>(
@@ -520,7 +522,8 @@ void InviteForbiddenController::setComplexCover() {
? tr::lng_invite_upgrade_via_title()
: tr::lng_via_link_cant()),
st::inviteForbiddenTitle),
st::inviteForbiddenTitlePadding);
st::inviteForbiddenTitlePadding,
style::al_top);
const auto about = _can
? (_peer->isBroadcast()
@@ -544,7 +547,8 @@ void InviteForbiddenController::setComplexCover() {
container,
rpl::single(about),
st::inviteForbiddenInfo),
st::inviteForbiddenInfoPadding);
st::inviteForbiddenInfoPadding,
style::al_top);
}
delegate()->peerListSetAboveWidget(std::move(cover));
}

View File

@@ -7,28 +7,70 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/peers/edit_contact_box.h"
#include "data/data_user.h"
#include "data/data_session.h"
#include "api/api_peer_photo.h"
#include "api/api_text_entities.h"
#include "apiwrap.h"
#include "base/call_delayed.h"
#include "boxes/peers/edit_peer_common.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/widgets/labels.h"
#include "boxes/premium_preview_box.h"
#include "chat_helpers/tabbed_panel.h"
#include "chat_helpers/tabbed_selector.h"
#include "core/application.h"
#include "core/click_handler_types.h"
#include "core/ui_integration.h"
#include "data/data_changes.h"
#include "data/data_document.h"
#include "data/data_premium_limits.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/stickers/data_stickers.h"
#include "editor/photo_editor_common.h"
#include "editor/photo_editor_layer_widget.h"
#include "history/view/controls/history_view_characters_limit.h"
#include "info/profile/info_profile_cover.h"
#include "info/userpic/info_userpic_emoji_builder_common.h"
#include "info/userpic/info_userpic_emoji_builder_menu_item.h"
#include "lang/lang_keys.h"
#include "lottie/lottie_common.h"
#include "lottie/lottie_frame_generator.h"
#include "main/main_session.h"
#include "settings/settings_common.h"
#include "ui/animated_icon.h"
#include "ui/controls/emoji_button_factory.h"
#include "ui/controls/emoji_button.h"
#include "ui/controls/userpic_button.h"
#include "ui/boxes/confirm_box.h"
#include "ui/text/format_values.h" // Ui::FormatPhone
#include "ui/text/text_entity.h"
#include "ui/text/text_utilities.h"
#include "ui/toast/toast.h"
#include "ui/vertical_list.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/fields/input_field.h"
#include "ui/text/format_values.h" // Ui::FormatPhone
#include "ui/text/text_utilities.h"
#include "info/profile/info_profile_cover.h"
#include "lang/lang_keys.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/popup_menu.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/painter.h"
#include "window/window_controller.h"
#include "ui/toast/toast.h"
#include "main/main_session.h"
#include "apiwrap.h"
#include "api/api_peer_photo.h"
#include "styles/style_layers.h"
#include "window/window_session_controller.h"
#include "styles/style_boxes.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_info.h"
#include "styles/style_layers.h"
#include "styles/style_menu_icons.h"
#include "styles/style_settings.h"
#include "styles/style_widgets.h"
#include <QtGui/QClipboard>
#include <QtGui/QGuiApplication>
namespace {
constexpr auto kAnimationStartFrame = 0;
constexpr auto kAnimationEndFrame = 21;
QString UserPhone(not_null<UserData*> user) {
const auto phone = user->phone();
return phone.isEmpty()
@@ -43,17 +85,22 @@ void SendRequest(
const QString &first,
const QString &last,
const QString &phone,
const TextWithEntities &note,
Fn<void()> done) {
const auto wasContact = user->isContact();
using Flag = MTPcontacts_AddContact::Flag;
user->session().api().request(MTPcontacts_AddContact(
MTP_flags(sharePhone
? Flag::f_add_phone_privacy_exception
: Flag(0)),
MTP_flags(Flag::f_note
| (sharePhone ? Flag::f_add_phone_privacy_exception : Flag(0))),
user->inputUser,
MTP_string(first),
MTP_string(last),
MTP_string(phone)
MTP_string(phone),
note.text.isEmpty()
? MTPTextWithEntities()
: MTP_textWithEntities(
MTP_string(note.text),
Api::EntitiesToMTP(&user->session(), note.entities))
)).done([=](const MTPUpdates &result) {
user->setName(
first,
@@ -83,7 +130,8 @@ public:
Controller(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> window,
not_null<UserData*> user);
not_null<UserData*> user,
bool focusOnNotes = false);
void prepare();
@@ -91,17 +139,40 @@ private:
void setupContent();
void setupCover();
void setupNameFields();
void setupNotesField();
void setupPhotoButtons();
void setupDeleteContactButton();
void setupWarning();
void setupSharePhoneNumber();
void initNameFields(
not_null<Ui::InputField*> first,
not_null<Ui::InputField*> last,
bool inverted);
void showPhotoMenu(bool suggest);
void choosePhotoFile(bool suggest);
void processChosenPhoto(QImage &&image, bool suggest);
void processChosenPhotoWithMarkup(
UserpicBuilder::Result &&data,
bool suggest);
void executeWithDelay(
Fn<void()> callback,
bool suggest,
bool startAnimation = true);
void finishIconAnimation(bool suggest);
not_null<Ui::GenericBox*> _box;
not_null<Window::SessionController*> _window;
not_null<UserData*> _user;
bool _focusOnNotes = false;
Ui::Checkbox *_sharePhone = nullptr;
Ui::InputField *_notesField = nullptr;
Ui::InputField *_firstNameField = nullptr;
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
base::unique_qptr<Ui::PopupMenu> _photoMenu;
std::unique_ptr<Ui::AnimatedIcon> _suggestIcon;
std::unique_ptr<Ui::AnimatedIcon> _cameraIcon;
Ui::RpWidget *_suggestIconWidget = nullptr;
Ui::RpWidget *_cameraIconWidget = nullptr;
QString _phone;
Fn<void()> _focus;
Fn<void()> _save;
@@ -112,10 +183,12 @@ private:
Controller::Controller(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> window,
not_null<UserData*> user)
not_null<UserData*> user,
bool focusOnNotes)
: _box(box)
, _window(window)
, _user(user)
, _focusOnNotes(focusOnNotes)
, _phone(UserPhone(user)) {
}
@@ -134,6 +207,9 @@ void Controller::prepare() {
void Controller::setupContent() {
setupCover();
setupNameFields();
setupNotesField();
setupPhotoButtons();
setupDeleteContactButton();
setupWarning();
setupSharePhoneNumber();
}
@@ -154,13 +230,14 @@ void Controller::setupCover() {
void Controller::setupNameFields() {
const auto inverted = langFirstNameGoesSecond();
const auto first = _box->addRow(
_firstNameField = _box->addRow(
object_ptr<Ui::InputField>(
_box,
st::defaultInputField,
tr::lng_signup_firstname(),
_user->firstName),
st::addContactFieldMargin);
const auto first = _firstNameField;
auto preparedLast = object_ptr<Ui::InputField>(
_box,
st::defaultInputField,
@@ -188,6 +265,11 @@ void Controller::initNameFields(
_box->setTabOrder(last, first);
}
_focus = [=] {
if (_focusOnNotes && _notesField) {
_notesField->setFocusFast();
_notesField->setCursorPosition(_notesField->getLastText().size());
return;
}
const auto firstValue = getValue(first);
const auto lastValue = getValue(last);
const auto empty = firstValue.isEmpty() && lastValue.isEmpty();
@@ -203,6 +285,22 @@ void Controller::initNameFields(
(inverted ? last : first)->showError();
return;
}
if (_notesField) {
const auto limit = Data::PremiumLimits(
&_user->session()).contactNoteLengthCurrent();
const auto remove = Ui::ComputeFieldCharacterCount(_notesField)
- limit;
if (remove > 0) {
_box->showToast(tr::lng_contact_notes_limit_reached(
tr::now,
lt_count,
remove));
_notesField->setFocus();
return;
}
}
const auto user = _user;
const auto personal = _updatedPersonalPhoto
? _updatedPersonalPhoto()
@@ -218,6 +316,16 @@ void Controller::initNameFields(
}
}
};
const auto noteValue = _notesField
? [&] {
auto textWithTags = _notesField->getTextWithAppliedMarkdown();
return TextWithEntities{
base::take(textWithTags.text),
TextUtilities::ConvertTextTagsToEntities(
base::take(textWithTags.tags)),
};
}()
: TextWithEntities();
SendRequest(
base::make_weak(_box),
user,
@@ -225,6 +333,7 @@ void Controller::initNameFields(
firstValue,
lastValue,
_phone,
noteValue,
done);
};
const auto submit = [=] {
@@ -257,6 +366,344 @@ void Controller::setupWarning() {
st::addContactWarningMargin);
}
void Controller::setupNotesField() {
Ui::AddSkip(_box->verticalLayout());
Ui::AddDivider(_box->verticalLayout());
Ui::AddSkip(_box->verticalLayout());
_notesField = _box->addRow(
object_ptr<Ui::InputField>(
_box,
st::notesFieldWithEmoji,
Ui::InputField::Mode::MultiLine,
tr::lng_contact_add_notes(),
QString()),
st::addContactFieldMargin);
_notesField->setMarkdownSet(Ui::MarkdownSet::Notes);
_notesField->setCustomTextContext(Core::TextContext({
.session = &_user->session()
}));
_notesField->setTextWithTags({
_user->note().text,
TextUtilities::ConvertEntitiesToTextTags(_user->note().entities)
});
_notesField->setMarkdownReplacesEnabled(rpl::single(
Ui::MarkdownEnabledState{
Ui::MarkdownEnabled{
{
Ui::InputField::kTagBold,
Ui::InputField::kTagItalic,
Ui::InputField::kTagUnderline,
Ui::InputField::kTagStrikeOut,
Ui::InputField::kTagSpoiler
}
}
}
));
const auto container = _box->getDelegate()->outerContainer();
using Selector = ChatHelpers::TabbedSelector;
_emojiPanel = base::make_unique_q<ChatHelpers::TabbedPanel>(
container,
_window,
object_ptr<Selector>(
nullptr,
_window->uiShow(),
Window::GifPauseReason::Layer,
Selector::Mode::EmojiOnly));
_emojiPanel->setDesiredHeightValues(
1.,
st::emojiPanMinHeight / 2,
st::emojiPanMinHeight);
_emojiPanel->hide();
_emojiPanel->selector()->setCurrentPeer(_window->session().user());
_emojiPanel->selector()->emojiChosen(
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
Ui::InsertEmojiAtCursor(_notesField->textCursor(), data.emoji);
}, _notesField->lifetime());
_emojiPanel->selector()->customEmojiChosen(
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
const auto info = data.document->sticker();
if (info
&& info->setType == Data::StickersType::Emoji
&& !_window->session().premium()) {
ShowPremiumPreviewBox(
_window,
PremiumFeature::AnimatedEmoji);
} else {
Data::InsertCustomEmoji(_notesField, data.document);
}
}, _notesField->lifetime());
const auto emojiButton = Ui::AddEmojiToggleToField(
_notesField,
_box,
_window,
_emojiPanel.get(),
st::sendGifWithCaptionEmojiPosition);
emojiButton->show();
using Limit = HistoryView::Controls::CharactersLimitLabel;
struct LimitState {
base::unique_qptr<Limit> charsLimitation;
};
const auto limitState = _notesField->lifetime().make_state<LimitState>();
const auto checkCharsLimitation = [=, w = _notesField->window()] {
const auto limit = Data::PremiumLimits(
&_user->session()).contactNoteLengthCurrent();
const auto remove = Ui::ComputeFieldCharacterCount(_notesField)
- limit;
if (!limitState->charsLimitation) {
const auto border = _notesField->st().borderActive;
limitState->charsLimitation = base::make_unique_q<Limit>(
_box->verticalLayout(),
emojiButton,
style::al_top,
QMargins{ 0, -border - _notesField->st().border, 0, 0 });
rpl::combine(
limitState->charsLimitation->geometryValue(),
_notesField->geometryValue()
) | rpl::start_with_next([=](QRect limit, QRect field) {
limitState->charsLimitation->setVisible(
(w->mapToGlobal(limit.bottomLeft()).y() - border)
< w->mapToGlobal(field.bottomLeft()).y());
limitState->charsLimitation->raise();
}, limitState->charsLimitation->lifetime());
}
limitState->charsLimitation->setLeft(remove);
};
_notesField->changes() | rpl::start_with_next([=] {
checkCharsLimitation();
}, _notesField->lifetime());
Ui::AddDividerText(
_box->verticalLayout(),
tr::lng_contact_add_notes_about());
}
void Controller::setupPhotoButtons() {
if (!_user->isContact()) {
return;
}
const auto iconPlaceholder = st::restoreUserpicIcon.size * 2;
auto nameValue = _firstNameField
? rpl::merge(
rpl::single(_firstNameField->getLastText().trimmed()),
_firstNameField->changes() | rpl::map([=] {
return _firstNameField->getLastText().trimmed();
})) | rpl::map([=](const QString &text) {
return text.isEmpty() ? Ui::kQEllipsis : text;
})
: rpl::single(_user->shortName()) | rpl::type_erased();
const auto inner = _box->verticalLayout();
Ui::AddSkip(inner);
const auto suggestBirthdayWrap = inner->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
inner,
object_ptr<Ui::VerticalLayout>(inner)));
const auto suggestBirthdayButton = Settings::AddButtonWithIcon(
suggestBirthdayWrap->entity(),
tr::lng_suggest_birthday(),
st::settingsButtonLight,
{ &st::editContactSuggestBirthday });
suggestBirthdayButton->setClickedCallback([=] {
Core::App().openInternalUrl(
u"internal:edit_birthday:suggest:%1"_q.arg(
peerToUser(_user->id).bare),
QVariant::fromValue(ClickHandlerContext{
.sessionWindow = base::make_weak(_window),
}));
});
suggestBirthdayWrap->toggleOn(rpl::single(!_user->birthday().valid()
&& !_user->starsPerMessageChecked()));
_suggestIcon = Ui::MakeAnimatedIcon({
.generator = [] {
return std::make_unique<Lottie::FrameGenerator>(
Lottie::ReadContent(
QByteArray(),
u":/animations/photo_suggest_icon.tgs"_q));
},
.sizeOverride = iconPlaceholder,
.colorized = true,
});
_cameraIcon = Ui::MakeAnimatedIcon({
.generator = [] {
return std::make_unique<Lottie::FrameGenerator>(
Lottie::ReadContent(
QByteArray(),
u":/animations/camera_outline.tgs"_q));
},
.sizeOverride = iconPlaceholder,
.colorized = true,
});
const auto suggestButtonWrap = inner->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
inner,
object_ptr<Ui::VerticalLayout>(inner)));
suggestButtonWrap->toggleOn(
rpl::single(!_user->starsPerMessageChecked()));
const auto suggestButton = Settings::AddButtonWithIcon(
suggestButtonWrap->entity(),
tr::lng_suggest_photo_for(lt_user, rpl::duplicate(nameValue)),
st::settingsButtonLight,
{ nullptr });
_suggestIconWidget = Ui::CreateChild<Ui::RpWidget>(suggestButton);
_suggestIconWidget->resize(iconPlaceholder);
_suggestIconWidget->paintRequest() | rpl::start_with_next([=] {
if (_suggestIcon && _suggestIcon->valid()) {
auto p = QPainter(_suggestIconWidget);
const auto frame = _suggestIcon->frame(st::lightButtonFg->c);
p.drawImage(_suggestIconWidget->rect(), frame);
}
}, _suggestIconWidget->lifetime());
suggestButton->sizeValue() | rpl::start_with_next([=](QSize size) {
_suggestIconWidget->move(
st::settingsButtonLight.iconLeft - iconPlaceholder.width() / 4,
(size.height() - _suggestIconWidget->height()) / 2);
}, _suggestIconWidget->lifetime());
suggestButton->setClickedCallback([=] {
if (_suggestIcon && _suggestIcon->valid()) {
_suggestIcon->setCustomStartFrame(kAnimationStartFrame);
_suggestIcon->setCustomEndFrame(kAnimationEndFrame);
_suggestIcon->jumpToStart([=] { _suggestIconWidget->update(); });
_suggestIcon->animate([=] { _suggestIconWidget->update(); });
}
showPhotoMenu(true);
});
const auto setButton = Settings::AddButtonWithIcon(
inner,
tr::lng_set_photo_for_user(lt_user, rpl::duplicate(nameValue)),
st::settingsButtonLight,
{ nullptr });
_cameraIconWidget = Ui::CreateChild<Ui::RpWidget>(setButton);
_cameraIconWidget->resize(iconPlaceholder);
_cameraIconWidget->paintRequest() | rpl::start_with_next([=] {
if (_cameraIcon && _cameraIcon->valid()) {
auto p = QPainter(_cameraIconWidget);
const auto frame = _cameraIcon->frame(st::lightButtonFg->c);
p.drawImage(_cameraIconWidget->rect(), frame);
}
}, _cameraIconWidget->lifetime());
setButton->sizeValue() | rpl::start_with_next([=](QSize size) {
_cameraIconWidget->move(
st::settingsButtonLight.iconLeft - iconPlaceholder.width() / 4,
(size.height() - _cameraIconWidget->height()) / 2);
}, _cameraIconWidget->lifetime());
setButton->setClickedCallback([=] {
if (_cameraIcon && _cameraIcon->valid()) {
_cameraIcon->setCustomStartFrame(kAnimationStartFrame);
_cameraIcon->setCustomEndFrame(kAnimationEndFrame);
_cameraIcon->jumpToStart([=] { _cameraIconWidget->update(); });
_cameraIcon->animate([=] { _cameraIconWidget->update(); });
}
showPhotoMenu(false);
});
const auto resetButtonWrap = inner->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
inner,
object_ptr<Ui::VerticalLayout>(inner)));
const auto resetButton = Settings::AddButtonWithIcon(
resetButtonWrap->entity(),
tr::lng_profile_photo_reset(),
st::settingsButtonLight,
{ nullptr });
const auto userpicButton = Ui::CreateChild<Ui::UserpicButton>(
resetButton,
_window,
_user,
Ui::UserpicButton::Role::Custom,
Ui::UserpicButton::Source::NonPersonalIfHasPersonal,
st::restoreUserpicIcon);
userpicButton->setAttribute(Qt::WA_TransparentForMouseEvents);
resetButton->sizeValue(
) | rpl::start_with_next([=](QSize size) {
userpicButton->move(
st::settingsButtonLight.iconLeft,
(size.height() - userpicButton->height()) / 2);
}, userpicButton->lifetime());
resetButtonWrap->toggleOn(
_user->session().changes().peerFlagsValue(
_user,
Data::PeerUpdate::Flag::FullInfo | Data::PeerUpdate::Flag::Photo
) | rpl::map([=] {
return _user->hasPersonalPhoto();
}) | rpl::distinct_until_changed());
resetButton->setClickedCallback([=] {
_window->show(Ui::MakeConfirmBox({
.text = tr::lng_profile_photo_reset_sure(
tr::now,
lt_user,
_user->shortName()),
.confirmed = [=](Fn<void()> close) {
_window->session().api().peerPhoto().clearPersonal(_user);
close();
},
.confirmText = tr::lng_profile_photo_reset(tr::now),
}));
});
Ui::AddSkip(inner);
Ui::AddDividerText(
inner,
tr::lng_contact_photo_replace_info(lt_user, std::move(nameValue)));
Ui::AddSkip(inner);
}
void Controller::setupDeleteContactButton() {
if (!_user->isContact()) {
return;
}
const auto inner = _box->verticalLayout();
const auto deleteButton = Settings::AddButtonWithIcon(
inner,
tr::lng_info_delete_contact(),
st::settingsAttentionButton,
{ nullptr });
deleteButton->setClickedCallback([=] {
const auto text = tr::lng_sure_delete_contact(
tr::now,
lt_contact,
_user->name());
const auto deleteSure = [=](Fn<void()> &&close) {
close();
_user->session().api().request(MTPcontacts_DeleteContacts(
MTP_vector<MTPInputUser>(1, _user->inputUser)
)).done([=](const MTPUpdates &result) {
_user->session().api().applyUpdates(result);
_box->closeBox();
}).send();
};
_window->show(Ui::MakeConfirmBox({
.text = text,
.confirmed = deleteSure,
.confirmText = tr::lng_box_delete(),
.confirmStyle = &st::attentionBoxButton,
}));
});
Ui::AddSkip(inner);
}
void Controller::setupSharePhoneNumber() {
const auto settings = _user->barSettings();
if (!settings
@@ -279,11 +726,174 @@ void Controller::setupSharePhoneNumber() {
}
void Controller::showPhotoMenu(bool suggest) {
_photoMenu = base::make_unique_q<Ui::PopupMenu>(
_box,
st::popupMenuWithIcons);
QObject::connect(_photoMenu.get(), &QObject::destroyed, [=] {
finishIconAnimation(suggest);
});
_photoMenu->addAction(
tr::lng_attach_photo(tr::now),
[=] { executeWithDelay([=] { choosePhotoFile(suggest); }, suggest); },
&st::menuIconPhoto);
if (const auto data = QGuiApplication::clipboard()->mimeData()) {
if (data->hasImage()) {
auto callback = [=] {
Editor::PrepareProfilePhoto(
_box,
&_window->window(),
Editor::EditorData{
.about = (suggest
? tr::lng_profile_suggest_sure(
tr::now,
lt_user,
Ui::Text::Bold(_user->shortName()),
Ui::Text::WithEntities)
: tr::lng_profile_set_personal_sure(
tr::now,
lt_user,
Ui::Text::Bold(_user->shortName()),
Ui::Text::WithEntities)),
.confirm = (suggest
? tr::lng_profile_suggest_button(tr::now)
: tr::lng_profile_set_photo_button(tr::now)),
.cropType = Editor::EditorData::CropType::Ellipse,
.keepAspectRatio = true,
},
[=](QImage &&editedImage) {
processChosenPhoto(std::move(editedImage), suggest);
},
qvariant_cast<QImage>(data->imageData()));
};
_photoMenu->addAction(
tr::lng_profile_photo_from_clipboard(tr::now),
[=] { executeWithDelay(callback, suggest); },
&st::menuIconPhoto);
}
}
UserpicBuilder::AddEmojiBuilderAction(
_window,
_photoMenu.get(),
_window->session().api().peerPhoto().emojiListValue(
Api::PeerPhoto::EmojiListType::Profile),
[=](UserpicBuilder::Result data) {
processChosenPhotoWithMarkup(std::move(data), suggest);
},
false);
_photoMenu->popup(QCursor::pos());
}
void Controller::choosePhotoFile(bool suggest) {
Editor::PrepareProfilePhotoFromFile(
_box,
&_window->window(),
Editor::EditorData{
.about = (suggest
? tr::lng_profile_suggest_sure(
tr::now,
lt_user,
Ui::Text::Bold(_user->shortName()),
Ui::Text::WithEntities)
: tr::lng_profile_set_personal_sure(
tr::now,
lt_user,
Ui::Text::Bold(_user->shortName()),
Ui::Text::WithEntities)),
.confirm = (suggest
? tr::lng_profile_suggest_button(tr::now)
: tr::lng_profile_set_photo_button(tr::now)),
.cropType = Editor::EditorData::CropType::Ellipse,
.keepAspectRatio = true,
},
[=](QImage &&image) {
processChosenPhoto(std::move(image), suggest);
});
}
void Controller::processChosenPhoto(QImage &&image, bool suggest) {
Api::PeerPhoto::UserPhoto photo{
.image = base::duplicate(image),
};
if (suggest) {
_window->session().api().peerPhoto().suggest(_user, std::move(photo));
_window->showPeerHistory(_user->id);
} else {
_window->session().api().peerPhoto().upload(_user, std::move(photo));
}
}
void Controller::processChosenPhotoWithMarkup(
UserpicBuilder::Result &&data,
bool suggest) {
Api::PeerPhoto::UserPhoto photo{
.image = std::move(data.image),
.markupDocumentId = data.id,
.markupColors = std::move(data.colors),
};
if (suggest) {
_window->session().api().peerPhoto().suggest(_user, std::move(photo));
_window->showPeerHistory(_user->id);
} else {
_window->session().api().peerPhoto().upload(_user, std::move(photo));
}
}
void Controller::finishIconAnimation(bool suggest) {
const auto icon = suggest ? _suggestIcon.get() : _cameraIcon.get();
const auto widget = suggest ? _suggestIconWidget : _cameraIconWidget;
if (icon && icon->valid()) {
icon->setCustomStartFrame(icon->frameIndex());
icon->setCustomEndFrame(-1);
icon->animate([=] { widget->update(); });
}
}
void Controller::executeWithDelay(
Fn<void()> callback,
bool suggest,
bool startAnimation) {
const auto icon = suggest ? _suggestIcon.get() : _cameraIcon.get();
const auto widget = suggest ? _suggestIconWidget : _cameraIconWidget;
if (startAnimation && icon && icon->valid()) {
icon->setCustomStartFrame(icon->frameIndex());
icon->setCustomEndFrame(-1);
icon->animate([=] { widget->update(); });
}
if (icon && icon->valid() && icon->animating()) {
base::call_delayed(50, [=] {
executeWithDelay(callback, suggest, false);
});
} else {
callback();
}
}
} // namespace
void EditContactBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> window,
not_null<UserData*> user) {
box->setWidth(st::boxWideWidth);
box->lifetime().make_state<Controller>(box, window, user)->prepare();
}
void EditContactNoteBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> window,
not_null<UserData*> user) {
box->setWidth(st::boxWideWidth);
box->lifetime().make_state<Controller>(
box,
window,
user,
true)->prepare();
}

View File

@@ -19,3 +19,8 @@ void EditContactBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> window,
not_null<UserData*> user);
void EditContactNoteBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> window,
not_null<UserData*> user);

View File

@@ -12,7 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/emoji_fly_animation.h"
#include "ui/abstract_button.h"
#include "ui/vertical_list.h"
#include "data/data_channel.h"
#include "data/data_document.h"
#include "data/data_forum.h"
#include "data/data_forum_icons.h"
@@ -77,7 +76,9 @@ DefaultIconEmoji::DefaultIconEmoji(
std::move(value) | rpl::start_with_next([=](DefaultIcon value) {
_icon = value;
_image = QImage();
repaint();
if (repaint) {
repaint();
}
}, _lifetime);
}
@@ -409,9 +410,12 @@ void EditForumTopicBox(
const auto topic = (!creating && forum->peer->forum())
? forum->peer->forum()->topicFor(rootId)
: nullptr;
const auto bot = forum->peer->isBot();
const auto created = topic && !topic->creating();
box->setTitle(creating
? tr::lng_forum_topic_new()
: bot
? tr::lng_bot_thread_edit()
: tr::lng_forum_topic_edit());
box->setMaxHeight(st::editTopicMaxHeight);
@@ -439,7 +443,9 @@ void EditForumTopicBox(
object_ptr<Ui::InputField>(
box,
st::defaultInputField,
tr::lng_forum_topic_title(),
(bot
? tr::lng_bot_thread_title()
: tr::lng_forum_topic_title()),
topic ? topic->title() : QString()),
st::editTopicTitleMargin);
box->setFocusCallback([=] {
@@ -491,7 +497,9 @@ void EditForumTopicBox(
}, title->lifetime());
if (!topic || !topic->isGeneral()) {
Ui::AddDividerText(top, tr::lng_forum_choose_title_and_icon());
Ui::AddDividerText(top, bot
? tr::lng_bot_thread_choose_title_and_icon()
: tr::lng_forum_choose_title_and_icon());
box->setScrollStyle(st::reactPanelScroll);
@@ -513,8 +521,7 @@ void EditForumTopicBox(
}
const auto create = [=] {
const auto channel = forum->peer->asChannel();
if (!channel || !channel->isForum()) {
if (!forum->peer->isForum()) {
box->closeBox();
return;
} else if (title->getLastText().trimmed().isEmpty()) {
@@ -525,7 +532,7 @@ void EditForumTopicBox(
controller->showSection(
std::make_shared<ChatMemento>(ChatViewId{
.history = forum,
.repliesRootId = channel->forum()->reserveCreatingId(
.repliesRootId = forum->peer->forum()->reserveCreatingId(
title->getLastText().trimmed(),
state->defaultIcon.current().colorId,
state->iconId.current()),
@@ -552,13 +559,13 @@ void EditForumTopicBox(
topic->applyIconId(state->iconId.current());
box->closeBox();
} else {
using Flag = MTPchannels_EditForumTopic::Flag;
using Flag = MTPmessages_EditForumTopic::Flag;
const auto api = &forum->session().api();
const auto weak = base::make_weak(box);
state->requestId = api->request(MTPchannels_EditForumTopic(
state->requestId = api->request(MTPmessages_EditForumTopic(
MTP_flags(Flag::f_title
| (topic->isGeneral() ? Flag() : Flag::f_icon_emoji_id)),
topic->channel()->inputChannel,
topic->peer()->input,
MTP_int(rootId),
MTP_string(title->getLastText().trimmed()),
MTP_long(state->iconId.current()),

File diff suppressed because it is too large Load Diff

View File

@@ -1135,7 +1135,7 @@ void Controller::fillForumButton() {
_forumSavedValue = _peer->isForum();
_forumTabsSavedValue = !_peer->isChannel()
|| !_peer->isForum()
|| _peer->asChannel()->useSubsectionTabs();
|| _peer->useSubsectionTabs();
const auto changes = std::make_shared<rpl::event_stream<>>();
const auto label = [=] {
@@ -1257,7 +1257,7 @@ void Controller::fillAutoTranslateButton() {
_navigation->uiShow(),
_peer,
[=](int level) {
if (const auto strong = weak.get()) {
if (weak.get()) {
state->isLocked = (level < requiredLevel);
}
return (level < requiredLevel)

View File

@@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h"
#include "history/history_item_helpers.h" // GetErrorForSending.
#include "history/view/history_view_group_call_bar.h" // GenerateUserpics...
#include "info/channel_statistics/earn/earn_icons.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "qr/qr_generate.h"
@@ -42,6 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/controls/userpic_button.h"
#include "ui/painter.h"
#include "ui/rect.h"
#include "ui/text/custom_emoji_helper.h"
#include "ui/text/format_values.h"
#include "ui/text/text_utilities.h"
#include "ui/toast/toast.h"
@@ -247,6 +249,9 @@ private:
const Role _role = Role::Joined;
rpl::variable<LinkData> _data;
Ui::Text::CustomEmojiHelper _emojiHelper;
TextWithEntities _creditsEmoji;
base::unique_qptr<Ui::PopupMenu> _menu;
rpl::event_stream<Processed> _processed;
@@ -408,6 +413,8 @@ Controller::Controller(
const auto current = _data.current();
_link = current.link;
_revoked = current.revoked;
_creditsEmoji = _emojiHelper.paletteDependent(
Ui::Earn::IconCreditsEmoji());
}
rpl::producer<LinkData> Controller::dataValue() const {
@@ -725,7 +732,7 @@ void Controller::setupAboveJoinedWidget() {
? tr::lng_group_invite_subscription_info_title(
tr::now,
lt_emoji,
session().data().customEmojiManager().creditsEmoji(),
_creditsEmoji,
lt_price,
{ QString::number(current.subscription.credits) },
lt_multiplier,
@@ -736,15 +743,12 @@ void Controller::setupAboveJoinedWidget() {
: tr::lng_group_invite_subscription_info_title_none(
tr::now,
lt_emoji,
session().data().customEmojiManager().creditsEmoji(),
_creditsEmoji,
lt_price,
{ QString::number(current.subscription.credits) },
Ui::Text::WithEntities),
kMarkupTextOptions,
Core::TextContext({
.session = &session(),
.repaint = [=] { widget->update(); },
}));
_emojiHelper.context([=] { widget->update(); }));
auto &lifetime = widget->lifetime();
const auto rateValue = lifetime.make_state<rpl::variable<float64>>(
session().credits().rateValue(_peer));
@@ -965,43 +969,41 @@ void Controller::rowClicked(not_null<PeerListRow*> row) {
const auto photoSize = st::boostReplaceUserpic.photoSize;
const auto session = &row->peer()->session();
content->add(object_ptr<Ui::CenterWrap<>>(
content,
Settings::SubscriptionUserpic(content, channel, photoSize)));
content->add(
Settings::SubscriptionUserpic(content, channel, photoSize),
style::al_top);
Ui::AddSkip(content);
Ui::AddSkip(content);
box->addRow(object_ptr<Ui::CenterWrap<>>(
box,
box->addRow(
object_ptr<Ui::FlatLabel>(
box,
tr::lng_credits_box_subscription_title(),
st::creditsBoxAboutTitle)));
st::creditsBoxAboutTitle),
style::al_top);
Ui::AddSkip(content);
const auto subtitle1 = box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
object_ptr<Ui::FlatLabel>(
box,
object_ptr<Ui::FlatLabel>(
box,
st::creditsTopupPrice)))->entity();
st::creditsTopupPrice),
style::al_top);
subtitle1->setMarkedText(
tr::lng_credits_subscription_subtitle(
tr::now,
lt_emoji,
session->data().customEmojiManager().creditsEmoji(),
_creditsEmoji,
lt_cost,
{ QString::number(data.subscription.credits) },
Ui::Text::WithEntities),
Core::TextContext({ .session = session }));
_emojiHelper.context());
const auto subtitle2 = box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
object_ptr<Ui::FlatLabel>(
box,
object_ptr<Ui::FlatLabel>(
box,
st::creditsTopupPrice)))->entity();
st::creditsTopupPrice),
style::al_top);
session->credits().rateValue(
channel
) | rpl::start_with_next([=, currency = u"USD"_q](float64 rate) {
@@ -1023,8 +1025,7 @@ void Controller::rowClicked(not_null<PeerListRow*> row) {
Ui::AddSkip(content);
Ui::AddSkip(content);
box->addRow(object_ptr<Ui::CenterWrap<>>(
box,
box->addRow(
object_ptr<Ui::FlatLabel>(
box,
tr::lng_credits_box_out_about(
@@ -1033,18 +1034,12 @@ void Controller::rowClicked(not_null<PeerListRow*> row) {
) | Ui::Text::ToLink(
tr::lng_credits_box_out_about_link(tr::now)),
Ui::Text::WithEntities),
st::creditsBoxAboutDivider)));
st::creditsBoxAboutDivider),
style::al_top);
const auto button = box->addButton(tr::lng_box_ok(), [=] {
box->addButton(tr::lng_box_ok(), [=] {
box->closeBox();
});
const auto buttonWidth = st::boxWidth
- rect::m::sum::h(st::giveawayGiftCodeBox.buttonPadding);
button->widthValue() | rpl::filter([=] {
return (button->widthNoMargins() != buttonWidth);
}) | rpl::start_with_next([=] {
button->resizeToWidth(buttonWidth);
}, button->lifetime());
}));
}

View File

@@ -50,7 +50,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace {
constexpr auto kSlowmodeValues = 7;
constexpr auto kSlowmodeValues = 8;
constexpr auto kBoostsUnrestrictValues = 5;
constexpr auto kForceDisableTooltipDuration = 3 * crl::time(1000);
constexpr auto kDefaultChargeStars = 10;
@@ -188,12 +188,13 @@ int SlowmodeDelayByIndex(int index) {
switch (index) {
case 0: return 0;
case 1: return 10;
case 2: return 30;
case 3: return 60;
case 4: return 5 * 60;
case 5: return 15 * 60;
case 6: return 60 * 60;
case 1: return 5;
case 2: return 10;
case 3: return 30;
case 4: return 60;
case 5: return 5 * 60;
case 6: return 15 * 60;
case 7: return 60 * 60;
}
Unexpected("Index in SlowmodeDelayByIndex.");
}
@@ -886,32 +887,18 @@ rpl::producer<int> AddSlowmodeSlider(
return secondsCount->value();
}
void AddBoostsUnrestrictLabels(
not_null<Ui::VerticalLayout*> container,
not_null<Main::Session*> session) {
void AddBoostsUnrestrictLabels(not_null<Ui::VerticalLayout*> container) {
const auto labels = container->add(
object_ptr<Ui::FixedHeightWidget>(container, st::normalFont->height),
st::slowmodeLabelsMargin);
const auto manager = &session->data().customEmojiManager();
const auto one = Ui::Text::SingleCustomEmoji(
manager->registerInternalEmoji(
st::boostMessageIcon,
st::boostMessageIconPadding));
const auto many = Ui::Text::SingleCustomEmoji(
manager->registerInternalEmoji(
st::boostsMessageIcon,
st::boostsMessageIconPadding));
const auto context = Core::TextContext({
.session = session,
.customEmojiLoopLimit = 1,
});
const auto one = Ui::Text::IconEmoji(&st::boostMessageIcon);
const auto many = Ui::Text::IconEmoji(&st::boostsMessageIcon);
for (auto i = 0; i != kBoostsUnrestrictValues; ++i) {
const auto label = Ui::CreateChild<Ui::FlatLabel>(
labels,
st::boostsUnrestrictLabel);
label->setMarkedText(
TextWithEntities(i ? many : one).append(QString::number(i + 1)),
context);
TextWithEntities(i ? many : one).append(QString::number(i + 1)));
rpl::combine(
labels->widthValue(),
label->widthValue()
@@ -977,7 +964,7 @@ rpl::producer<int> AddBoostsUnrestrictSlider(
const auto inner = outer->entity();
AddBoostsUnrestrictLabels(inner, &peer->session());
AddBoostsUnrestrictLabels(inner);
const auto slider = inner->add(
object_ptr<Ui::MediaSlider>(inner, st::localStorageLimitSlider),

View File

@@ -7,23 +7,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "boxes/peers/edit_peer_usernames_list.h"
#include "api/api_filter_updates.h"
#include "api/api_user_names.h"
#include "apiwrap.h"
#include "base/event_filter.h"
#include "data/data_changes.h"
#include "data/data_peer.h"
#include "data/data_user.h"
#include "info/profile/info_profile_values.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "ui/boxes/confirm_box.h"
#include "ui/layers/show.h"
#include "ui/painter.h"
#include "ui/vertical_list.h"
#include "ui/text/text_utilities.h" // Ui::Text::RichLangValue.
#include "ui/toast/toast.h"
#include "ui/ui_utility.h"
#include "ui/vertical_list.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/popup_menu.h"
#include "ui/wrap/vertical_layout_reorder.h"
#include "ui/ui_utility.h"
#include "styles/style_boxes.h" // contactsStatusFont.
#include "styles/style_info.h"
#include "styles/style_layers.h"
@@ -208,6 +211,17 @@ UsernamesList::UsernamesList(
}
}
load();
rpl::merge(
peer->session().changes().peerFlagsValue(
peer,
Data::PeerUpdate::Flag::Username),
peer->session().changes().peerFlagsValue(
peer,
Data::PeerUpdate::Flag::Usernames)
) | rpl::start_with_next([=] {
load();
}, lifetime());
}
void UsernamesList::load() {
@@ -250,6 +264,8 @@ void UsernamesList::rebuild(const Data::Usernames &usernames) {
username.username);
const auto status = (username.editable && _focusCallback)
? tr::lng_usernames_edit(tr::now)
: (username.editable && !username.active)
? tr::lng_usernames_non_active(tr::now)
: username.active
? tr::lng_usernames_active(tr::now)
: tr::lng_usernames_non_active(tr::now);
@@ -265,8 +281,20 @@ void UsernamesList::rebuild(const Data::Usernames &usernames) {
if (username.editable) {
if (_focusCallback) {
_focusCallback();
return;
}
if (_isBot) {
const auto hasActiveAuction = ranges::any_of(
usernames,
[](const Data::Username &u) {
return !u.editable && u.active;
});
if (!hasActiveAuction && username.active) {
return;
}
} else {
return;
}
return;
}
auto text = _peer->isSelf()
@@ -309,10 +337,13 @@ void UsernamesList::rebuild(const Data::Usernames &usernames) {
rpl::single(kMaxUsernames),
Ui::Text::RichLangValue)));
}
if (error == Api::Usernames::Error::Flood) {
_show->showToast(
tr::lng_flood_error(tr::now));
}
load();
_toggleLifetime.destroy();
}, [=] {
load();
_toggleLifetime.destroy();
});
});

View File

@@ -230,9 +230,13 @@ void PeerShortInfoCover::paintCoverImage(QPainter &p, const QImage &image) {
if (fill > 0) {
const auto t = roundedHeight + _scrollTop;
p.drawImage(
QRect(0, t, roundedWidth * factor, (roundedWidth - t) * factor),
QRect(0, t, roundedWidth, roundedWidth - t),
image,
QRect(0, t, roundedWidth * factor, (roundedWidth - t) * factor));
QRect(
0,
t * factor,
roundedWidth * factor,
(roundedWidth - t) * factor));
}
if (covered <= 0) {
return;
@@ -241,9 +245,9 @@ void PeerShortInfoCover::paintCoverImage(QPainter &p, const QImage &image) {
const auto from = top - rounded;
auto q = QPainter(&_roundedTopImage);
q.drawImage(
QRect(0, 0, roundedWidth * factor, rounded * factor),
QRect(0, 0, roundedWidth, rounded),
image,
QRect(0, _scrollTop, roundedWidth * factor, rounded * factor));
QRect(0, _scrollTop * factor, roundedWidth * factor, rounded * factor));
q.end();
_roundedTopImage = Images::Round(
std::move(_roundedTopImage),
@@ -811,6 +815,10 @@ void PeerShortInfoBox::prepareRows() {
birthdayLabel(),
birthdayValue() | Ui::Text::ToWithEntities(),
tr::lng_mediaview_copy(tr::now));
addInfoLine(
tr::lng_info_notes_label(),
noteValue(),
_st.labeled);
}
void PeerShortInfoBox::resizeEvent(QResizeEvent *e) {
@@ -917,3 +925,9 @@ rpl::producer<TextWithEntities> PeerShortInfoBox::aboutValue() const {
return fields.about;
}) | rpl::distinct_until_changed();
}
rpl::producer<TextWithEntities> PeerShortInfoBox::noteValue() const {
return _fields.value() | rpl::map([](const PeerShortInfoFields &fields) {
return fields.note;
}) | rpl::distinct_until_changed();
}

View File

@@ -48,6 +48,7 @@ struct PeerShortInfoFields {
TextWithEntities about;
QString username;
Data::Birthday birthday;
TextWithEntities note;
bool isBio = false;
};
@@ -188,6 +189,7 @@ private:
[[nodiscard]] rpl::producer<QString> birthdayLabel() const;
[[nodiscard]] rpl::producer<QString> birthdayValue() const;
[[nodiscard]] rpl::producer<TextWithEntities> aboutValue() const;
[[nodiscard]] rpl::producer<TextWithEntities> noteValue() const;
const style::ShortInfoBox &_st;
const PeerShortInfoType _type = PeerShortInfoType::User;

View File

@@ -210,7 +210,8 @@ void ProcessFullPhoto(
| UpdateFlag::PhoneNumber
| UpdateFlag::Username
| UpdateFlag::About
| UpdateFlag::Birthday)
| UpdateFlag::Birthday
| UpdateFlag::ContactNote)
) | rpl::map([=] {
const auto user = peer->asUser();
const auto username = peer->username();
@@ -237,6 +238,7 @@ void ProcessFullPhoto(
? ('@' + username)
: QString()),
.birthday = user ? user->birthday() : Data::Birthday(),
.note = user ? user->note() : TextWithEntities(),
.isBio = (user && !user->isBot()),
};
});

View File

@@ -11,8 +11,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "base/event_filter.h"
#include "base/unixtime.h"
#include "data/data_premium_limits.h"
#include "boxes/peer_list_box.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/data_premium_limits.h"
#include "data/data_channel.h"
#include "data/data_cloud_themes.h"
#include "data/data_session.h"
@@ -32,8 +33,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/padding_wrap.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/empty_userpic.h"
#include "ui/dynamic_image.h"
#include "ui/painter.h"
#include "ui/top_background_gradient.h"
#include "styles/style_boxes.h"
#include "styles/style_credits.h"
#include "styles/style_premium.h"
namespace {
@@ -221,7 +225,8 @@ void Controller::prepare() {
Ui::Text::RichLangValue),
Ui::Text::RichLangValue),
st::boostReassignText),
st::boxRowPadding);
st::boxRowPadding,
style::al_top);
delegate()->peerListSetAboveWidget(std::move(above));
const auto now = base::unixtime::now();
@@ -832,3 +837,174 @@ object_ptr<Ui::RpWidget> CreateUserpicsWithMoreBadge(
}, overlay->lifetime());
return result;
}
class UniqueGiftBackground final : public Ui::DynamicImage {
public:
UniqueGiftBackground(
not_null<Main::Session*> session,
std::shared_ptr<Data::UniqueGift> unique)
: _session(session)
, _unique(std::move(unique)) {
}
std::shared_ptr<Ui::DynamicImage> clone() override {
return std::make_shared<UniqueGiftBackground>(_session, _unique);
}
void subscribeToUpdates(Fn<void()> callback) override {
_repaint = std::move(callback);
if (!_repaint) {
_patternEmoji = nullptr;
}
}
QImage image(int size) override {
if (!_patternEmoji) {
_patternEmoji = _session->data().customEmojiManager().create(
_unique->pattern.document,
[=] { ready(); },
Data::CustomEmojiSizeTag::Large);
[[maybe_unused]] const auto preload = _patternEmoji->ready();
}
const auto inner = QRect(0, 0, size, size);
const auto ratio = style::DevicePixelRatio();
if (_backgroundCache.size() != inner.size() * ratio) {
_backgroundCache = QImage(
inner.size() * ratio,
QImage::Format_ARGB32_Premultiplied);
_backgroundCache.fill(Qt::transparent);
_backgroundCache.setDevicePixelRatio(ratio);
const auto radius = st::giftBoxGiftRadius;
auto p = QPainter(&_backgroundCache);
auto hq = PainterHighQualityEnabler(p);
auto gradient = QRadialGradient(
inner.center(),
inner.width() / 2);
gradient.setStops({
{ 0., _unique->backdrop.centerColor },
{ 1., _unique->backdrop.edgeColor },
});
p.setBrush(gradient);
p.setPen(Qt::NoPen);
p.drawRoundedRect(inner, radius, radius);
_backroundPatterned = false;
}
if (!_backroundPatterned && _patternEmoji->ready()) {
_backroundPatterned = true;
auto p = QPainter(&_backgroundCache);
p.setClipRect(inner);
const auto skip = inner.width() / 3;
Ui::PaintBgPoints(
p,
Ui::PatternBgPointsSmall(),
_patternCache,
_patternEmoji.get(),
*_unique,
QRect(-skip, 0, inner.width() + 2 * skip, inner.height()));
}
return _backgroundCache;
}
private:
void ready() {
if (!_backroundPatterned && _repaint) {
_repaint();
}
}
const not_null<Main::Session*> _session;
const std::shared_ptr<Data::UniqueGift> _unique;
Fn<void()> _repaint;
std::unique_ptr<Ui::Text::CustomEmoji> _patternEmoji;
QImage _backgroundCache;
base::flat_map<float64, QImage> _patternCache;
bool _backroundPatterned = false;
};
object_ptr<Ui::RpWidget> CreateGiftTransfer(
not_null<Ui::RpWidget*> parent,
std::shared_ptr<Data::UniqueGift> unique,
not_null<PeerData*> to) {
struct State {
QImage layer;
QPoint giftPosition;
std::shared_ptr<UniqueGiftBackground> bg;
std::shared_ptr<Ui::Text::CustomEmoji> sticker;
};
const auto st = &st::boostReplaceUserpicsRow;
const auto full = st->button.size.height()
+ st::boostReplaceIconAdd.y()
+ st::lineWidth;
auto result = object_ptr<Ui::FixedHeightWidget>(parent, full);
const auto raw = result.data();
const auto right = CreateChild<Ui::UserpicButton>(raw, to, st->button);
const auto overlay = CreateChild<Ui::RpWidget>(raw);
const auto state = raw->lifetime().make_state<State>();
state->bg = std::make_shared<UniqueGiftBackground>(
&to->session(),
unique);
state->bg->subscribeToUpdates([=] {
overlay->update();
});
const auto tag = Data::CustomEmojiSizeTag::Isolated;
state->sticker = to->owner().customEmojiManager().create(
unique->model.document,
[=] { overlay->update(); },
tag);
overlay->update();
raw->widthValue(
) | rpl::start_with_next([=](int width) {
const auto skip = st::boostReplaceUserpicsSkip;
const auto total = right->width() + skip + right->width();
auto x = (width - total) / 2;
state->giftPosition = QPoint(x, 0);
x += right->width() + skip;
right->moveToLeft(x, 0);
overlay->setGeometry(QRect(0, 0, width, raw->height()));
}, raw->lifetime());
overlay->paintRequest(
) | rpl::start_with_next([=] {
const auto outerw = overlay->width();
const auto ratio = style::DevicePixelRatio();
if (state->layer.size() != QSize(outerw, full) * ratio) {
state->layer = QImage(
QSize(outerw, full) * ratio,
QImage::Format_ARGB32_Premultiplied);
state->layer.setDevicePixelRatio(ratio);
}
state->layer.fill(Qt::transparent);
auto q = QPainter(&state->layer);
auto hq = PainterHighQualityEnabler(q);
const auto from = QRect(state->giftPosition, right->size());
const auto esize = Data::FrameSizeFromTag(tag) / ratio;
q.drawImage(from, state->bg->image(from.width()));
state->sticker->paint(q, {
.textColor = st::windowFg->c,
.now = crl::now(),
.position = from.topLeft() + QPoint(
(from.width() - esize) / 2,
(from.height() - esize) / 2),
});
const auto size = st::boostReplaceArrow.size();
st::boostReplaceArrow.paint(
q,
(state->giftPosition.x()
+ right->width()
+ (st::boostReplaceUserpicsSkip - size.width()) / 2),
(right->height() - size.height()) / 2,
outerw);
q.end();
auto p = QPainter(overlay);
p.drawImage(0, 0, state->layer);
}, overlay->lifetime());
return result;
}

View File

@@ -15,6 +15,10 @@ struct UserpicsRow;
class ChannelData;
namespace Data {
struct UniqueGift;
} // namespace Data
namespace Main {
class Session;
} // namespace Main
@@ -72,3 +76,8 @@ enum class UserpicsTransferType {
rpl::producer<std::vector<not_null<PeerData*>>> peers,
const style::UserpicsRow &st,
int limit);
[[nodiscard]] object_ptr<Ui::RpWidget> CreateGiftTransfer(
not_null<Ui::RpWidget*> parent,
std::shared_ptr<Data::UniqueGift> unique,
not_null<PeerData*> to);

View File

@@ -188,7 +188,7 @@ void Controller::confirmAdd(not_null<PeerData*> peer) {
}, field->lifetime());
field->setMaxLength(limit * 2);
Ui::AddLengthLimitLabel(field, limit, std::nullopt);
Ui::AddLengthLimitLabel(field, limit);
Ui::AddDividerText(box->verticalLayout(), phrases.about());
}));

View File

@@ -585,14 +585,14 @@ void ChannelsLimitBox(
const auto content = box->addRow(
object_ptr<PeerListContent>(box, controller),
{});
style::margins());
delegate->setContent(content);
controller->setDelegate(delegate);
const auto count = 100;
const auto placeholder = box->addRow(
object_ptr<PeerListDummy>(box, count, st::defaultPeerList),
{});
style::margins());
using namespace rpl::mappers;
controller->countValue(
@@ -676,14 +676,14 @@ void PublicLinksLimitBox(
const auto content = box->addRow(
object_ptr<PeerListContent>(box, controller),
{});
style::margins());
delegate->setContent(content);
controller->setDelegate(delegate);
const auto count = defaultLimit;
const auto placeholder = box->addRow(
object_ptr<PeerListDummy>(box, count, st::defaultPeerList),
{});
style::margins());
using namespace rpl::mappers;
controller->countValue(

View File

@@ -135,6 +135,8 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
return tr::lng_premium_summary_subtitle_effects();
case PremiumFeature::TodoLists:
return tr::lng_premium_summary_subtitle_todo_lists();
case PremiumFeature::PeerColors:
return tr::lng_premium_summary_subtitle_peer_colors();
case PremiumFeature::BusinessLocation:
return tr::lng_business_subtitle_location();
@@ -202,6 +204,8 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
return tr::lng_premium_summary_about_effects();
case PremiumFeature::TodoLists:
return tr::lng_premium_summary_about_todo_lists();
case PremiumFeature::PeerColors:
return tr::lng_premium_summary_about_peer_colors();
case PremiumFeature::BusinessLocation:
return tr::lng_business_about_location();
@@ -543,6 +547,7 @@ struct VideoPreviewDocument {
case PremiumFeature::MessagePrivacy: return "message_privacy";
case PremiumFeature::Effects: return "effects";
case PremiumFeature::TodoLists: return "todo";
case PremiumFeature::PeerColors: return "peer_colors";
case PremiumFeature::BusinessLocation: return "business_location";
case PremiumFeature::BusinessHours: return "business_hours";
@@ -902,7 +907,7 @@ void PreviewBox(
const auto outer = box->addRow(
ChatBackPreview(box, size.height(), back),
{});
style::margins());
struct Hiding {
not_null<Ui::RpWidget*> widget;
@@ -1079,26 +1084,21 @@ void PreviewBox(
auto text = state->selected.value(
) | rpl::map(SectionAbout) | rpl::flatten_latest();
const auto padding = st::premiumPreviewAboutPadding;
const auto available = size.width() - padding.left() - padding.right();
auto titleLabel = object_ptr<Ui::FlatLabel>(
box,
std::move(title),
st::premiumPreviewAboutTitle);
titleLabel->resizeToWidth(available);
box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
object_ptr<Ui::FlatLabel>(
box,
std::move(titleLabel)),
st::premiumPreviewAboutTitlePadding);
auto textLabel = object_ptr<Ui::FlatLabel>(
box,
std::move(text),
st::premiumPreviewAbout);
textLabel->resizeToWidth(available);
std::move(title),
st::premiumPreviewAboutTitle),
st::premiumPreviewAboutTitlePadding,
style::al_top);
box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(box, std::move(textLabel)),
padding);
object_ptr<Ui::FlatLabel>(
box,
std::move(text),
st::premiumPreviewAbout),
st::premiumPreviewAboutPadding,
style::al_top
)->setTryMakeSimilarLines(true);
box->addRow(
CreateSwitch(box->verticalLayout(), &state->selected, state->order),
st::premiumDotsMargin);

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