Compare commits

...

276 Commits

Author SHA1 Message Date
John Preston
dbbe4b9398 Version 6.3.8. (Linux only)
- Fix crash on older Linux.
2025-12-15 16:40:41 +04:00
John Preston
e0b0f00621 Version 6.3.7: Fix build with GCC. 2025-12-15 16:18:32 +04:00
John Preston
516d6cf11e Version 6.3.7.
- Fix login with passkey visibility on Windows.
- Improve gift upgrading experience.
2025-12-14 16:03:36 +04:00
Reza Bakhshi Laktasaraei
673db168ac Feat: Set accessibility name for Main menu toggle and add related strings. 2025-12-14 16:03:23 +04:00
John Preston
496e96d00a Fix currency icon in channel post offers. 2025-12-14 16:02:52 +04:00
John Preston
88fdc16070 Don't allow free buy gift offers. 2025-12-14 16:02:51 +04:00
23rd
df98cdb127 Fixed build on Windows and Linux. 2025-12-14 12:54:55 +03:00
23rd
68b245c3d6 Removed button from dialogs widget when dialogs are empty in archive. 2025-12-14 10:39:10 +03:00
John Preston
0248c8d8c0 Increase gift upgrade animation speed. 2025-12-13 14:05:50 +04:00
John Preston
3ac517b716 Fix build with GCC. 2025-12-13 14:03:02 +04:00
John Preston
8414c3e382 Put keyboard buttons above outside reactions. 2025-12-13 13:35:56 +04:00
23rd
9f8dc1d7d3 Fixed opening details of upgraded and transferred star gift. 2025-12-13 13:35:56 +04:00
23rd
56927d2780 Fixed string name and value matching in table during gift upgrade. 2025-12-13 13:35:56 +04:00
23rd
a027284826 Added voices to SMTC.
Fixed #28915.
2025-12-13 13:35:56 +04:00
23rd
e0159c32cc Returned display of button in box for passkey creation when unsupported. 2025-12-13 13:35:56 +04:00
23rd
9cc30741d9 Attempted once again to improve status color with dark theme in profile.
Previous related commit: 7a75c80b27.
2025-12-13 13:35:56 +04:00
23rd
863752e974 Added invalidation gift button background cache on palette changes. 2025-12-13 13:35:56 +04:00
23rd
cb76031165 Fixed fade color of animated attribute while upgrading gift. 2025-12-13 13:35:55 +04:00
23rd
c45cf07b06 Fixed text color of peer value in table on palette change. 2025-12-13 13:35:55 +04:00
23rd
d35d425918 Fixed display of ToS link to any box of gifts with empty credits. 2025-12-12 22:22:56 +04:00
23rd
d4a3a53484 Simplified ability to enable all reactions in channels. 2025-12-12 22:22:55 +04:00
John Preston
5d90b12a08 Fix blockquotes without skip block optimal size. 2025-12-12 21:40:08 +04:00
John Preston
e3ce190f4e Use real upgrade code instead of testing. 2025-12-12 21:09:22 +04:00
John Preston
ffd50c5582 Finish upgrading gifts animation. 2025-12-12 20:53:38 +04:00
John Preston
c758f05a7a Finish gift upgrade cover animation. 2025-12-12 17:43:21 +04:00
John Preston
9263c08068 Started the gift upgrade animation. 2025-12-12 14:59:44 +04:00
John Preston
703f77ac93 Upgrade gift while staying in the same box. 2025-12-11 22:25:43 +04:00
John Preston
32bdb5a519 Don't show gift value box twice. 2025-12-11 10:49:37 +04:00
John Preston
d8484a7b2b Update cmake_helpers. 2025-12-11 10:48:07 +04:00
23rd
eca8dfb0ec Renamed rpl::start_with_ with rpl::on_. 2025-12-10 21:28:33 +03:00
23rd
29b714dd5f Used fallback name for passkeys without name in list from settings. 2025-12-10 20:46:56 +03:00
23rd
3f3b2cb2ba Fixed display of passkey button in privacy settings section. 2025-12-10 20:46:56 +03:00
John Preston
c31d9ded27 No price decrease countdown for free upgrades. 2025-12-10 14:27:34 +04:00
John Preston
03df5b8546 rpl::type_erased() -> rpl::type_erased. 2025-12-10 14:27:05 +04:00
John Preston
03e1e5cca9 Fix login with passkey link display. 2025-12-10 14:26:09 +04:00
John Preston
10d5cc0d24 Fix appConfig refresh on DC change. 2025-12-10 14:10:55 +04:00
John Preston
506c8ff73c Don't show upgrade costs for free upgrades. 2025-12-10 13:38:54 +04:00
John Preston
924e9a21b5 Don't offer View Profile / Send Message in private chat. 2025-12-10 12:30:42 +04:00
John Preston
2f528a9853 Fix seconds phrase for auctions. 2025-12-10 12:09:06 +04:00
23rd
7f58650794 Added preview of reaction to posts on right click. 2025-12-10 09:47:48 +03:00
23rd
b9a109c146 Added ability to set custom animation duration for MediaPreviewWidget. 2025-12-10 09:47:48 +03:00
23rd
9fb4f4b556 Fixed display of original date with nearest days in self. 2025-12-10 09:47:48 +03:00
23rd
52d78ef724 Increased round radius for popup menu. 2025-12-10 09:47:48 +03:00
23rd
7ce7b88a40 Implemented adaptive drawing algorithm with smoothing in image editor.
- Adaptive point filtering - zoom-based minimum distance (3px / zoom)
  prevents point overflow during fast movements.

- Speed-based pressure simulation - exponential smoothing (decay 0.95)
  creates variable line thickness: pressure = clamp(1.0 - speed * 0.1).

- Two-pass
  weighted averaging - smoothed = current * 0.5 + neighbors * 0.25
  eliminates jagged lines while preserving initial direction.

- Incremental rendering with 3-point overlap - draws only new segments,
  reduces complexity from O(n^2) to O(n).

- QPainterPath with quadratic Bezier curves - single fillPath() call
  instead of multiple drawEllipse().
2025-12-10 09:47:48 +03:00
23rd
4a43dfd091 Added profile color support to calls panel. 2025-12-10 09:47:48 +03:00
23rd
52cc76636c Moved out verify details below app button when it is presented in info. 2025-12-10 09:47:48 +03:00
23rd
f0a3ddb184 Fixed phrase in menu item to share gift collection. 2025-12-10 09:47:48 +03:00
23rd
b172c9a3b2 Added check for empty proxy list before showing delete all menu item. 2025-12-10 09:47:48 +03:00
Ilya Fedin
6cfda1dd43 Use gi::object_cast 2025-12-10 10:43:28 +04:00
Ilya Fedin
2ae31f7285 Support crashpad_handler in packaged mode 2025-12-09 13:46:07 +04:00
Ilya Fedin
412c06160a Fix setting Breakpad framework path with non-Xcode generators 2025-12-09 13:45:31 +04:00
Ilya Fedin
c27c47dd52 Set M_ARENA_MAX earlier
It doesn't work properly with auto-updatable builds otherwise
2025-12-09 12:36:12 +04:00
Ilya Fedin
6ea30feb18 Attach malloc_trim lifetime to LinuxIntegration 2025-12-09 12:36:12 +04:00
Ilya Fedin
a7be550550 Fix packaged build with Updater on macOS 2025-12-09 12:35:51 +04:00
Ilya Fedin
a279f0a296 Attempt to fix cache key instability in macOS packaged and Linux actions 2025-12-09 12:33:21 +04:00
John Preston
1c4f663941 Version 6.3.6.
- Fix crash in media viewer.
- Fix crash in experimental settings.
2025-12-06 00:07:39 +04:00
John Preston
94f9321db9 Fix crash in experimental settings opening. 2025-12-06 00:05:31 +04:00
John Preston
ae70b10cea Fix crash in media viewer. 2025-12-05 23:58:08 +04:00
John Preston
4f685552e7 Version 6.3.5.
- Offer stars or TON for unique gifts.
- Preview gift auctions before they start.
- Support passkey login on Windows.
2025-12-05 23:11:53 +04:00
John Preston
e085a76165 Fix build with GCC. 2025-12-05 23:11:32 +04:00
23rd
30bd3ed013 Removed WebAuthn support from entitlements. 2025-12-05 23:11:32 +04:00
23rd
25edab4c94 Fixed build with Xcode. 2025-12-05 23:11:32 +04:00
23rd
3aa241d825 Removed WebAuthn support for macOS for now. 2025-12-05 23:11:32 +04:00
John Preston
9b867af7fd Use known gift number in some places. 2025-12-05 20:11:54 +04:00
John Preston
0df3be8630 Use better ratio stars/usd/ton. 2025-12-05 20:11:54 +04:00
John Preston
542326af8f Show offer value diff percent. 2025-12-05 20:11:54 +04:00
John Preston
ea5052e69e Add "Ban Users" channel admin right. 2025-12-05 20:11:54 +04:00
John Preston
2dd96b2269 Better phrases for upcoming auctions. 2025-12-05 20:11:54 +04:00
John Preston
627152e2a9 Nice gifts promo box. 2025-12-05 20:11:54 +04:00
John Preston
f01c93ed58 Update API scheme on layer 220. 2025-12-05 20:11:54 +04:00
John Preston
6fe61ed58a Add gifts premium promo. 2025-12-05 20:11:54 +04:00
John Preston
43347f671c Show rarity in gift variants preview. 2025-12-05 20:11:54 +04:00
John Preston
0b67fa65f2 Full upgradable variants preview. 2025-12-05 20:11:54 +04:00
John Preston
65b3a36984 Implement upcoming auction preview box. 2025-12-05 20:11:54 +04:00
John Preston
b08cf75f0b Start auction preview display. 2025-12-05 20:11:54 +04:00
John Preston
0cc21e5ca2 Update API scheme on layer 220. 2025-12-05 20:11:54 +04:00
John Preston
48f9a92cc3 Improve Checkbox / Button accessibility. 2025-12-05 20:11:54 +04:00
John Preston
939882ef68 Show profile design gift wear promo. 2025-12-05 20:11:54 +04:00
John Preston
52084cf0ae Apply correct min/max offer values. 2025-12-05 20:11:54 +04:00
John Preston
f06f654191 Confirm making an offer. 2025-12-05 20:11:53 +04:00
John Preston
356d20542e Use nice radius in offer with buttons. 2025-12-05 20:11:53 +04:00
John Preston
31ea4cfe80 Process offers with accept / reject. 2025-12-05 20:11:53 +04:00
John Preston
1e89ee4e50 Show Reject/Accept buttons for offers. 2025-12-05 20:11:53 +04:00
John Preston
6fccbf036c Rename HistoryMessage[SuggestedPost->Suggestion]. 2025-12-05 20:11:53 +04:00
John Preston
41d206e354 Rename SuggestPostOptions to SuggestOptions. 2025-12-05 20:11:53 +04:00
John Preston
23880ac6c1 Update API scheme to layer 220.
Allow offering to buy gifts.
2025-12-05 20:11:53 +04:00
John Preston
4439cbf553 Pass effect_id to forward message requests. 2025-12-05 20:11:53 +04:00
23rd
f506f1b830 Added read availability of passkeys from appConfig. 2025-12-05 20:11:53 +04:00
23rd
feb1ea6502 Wrapped text recognition on macOS with experimental toggle. 2025-12-05 20:11:53 +04:00
23rd
fea80b4919 Wrapped passkeys on macOS with experimental toggle due to instability. 2025-12-05 20:11:53 +04:00
23rd
373bb8d74c Improved display of ripple on release in buttons from subsection tabs. 2025-12-05 20:11:53 +04:00
23rd
3ddefd78ba Fixed display of tabbed selector on installed set for read-only peers. 2025-12-05 20:11:53 +04:00
23rd
d62e4da163 Added simple cache of recognized text to media view overlay. 2025-12-05 20:11:53 +04:00
23rd
8c60863e11 Added ability to copy recognized text from media view overlay. 2025-12-05 20:11:53 +04:00
23rd
d5be8c8989 Added initial ability to recognize text to media view overlay. 2025-12-05 20:11:53 +04:00
23rd
255b30e88a Added initial implementation of text recognition for macOS. 2025-12-05 20:11:53 +04:00
23rd
d2dd124be0 Added dummy platform files for text recognition. 2025-12-05 20:11:53 +04:00
23rd
1053b30a6d Added api support for max count of passkeys for accounts. 2025-12-05 18:15:54 +04:00
23rd
e7c1073e13 Added initial error handler to passkeys processing. 2025-12-05 18:15:54 +04:00
23rd
0480c6a4af Added initial ability to login with passkey. 2025-12-05 18:15:54 +04:00
23rd
c70a49c0f3 Added initial api support to login with passkey. 2025-12-05 18:15:54 +04:00
John Preston
7840fd481a Use correct icon for passkey in Settings. 2025-12-05 18:15:54 +04:00
23rd
2a8b491c95 Replaced pure text with Text::String in list of passkeys in settings. 2025-12-05 18:15:54 +04:00
23rd
39c4344047 Added divider with description to section of settings for passkeys. 2025-12-05 18:15:54 +04:00
23rd
cdb58e4ebd Added button for new passkeys to section of settings. 2025-12-05 18:15:54 +04:00
23rd
972325fb6d Added menu to simple list of passkeys in section of settings. 2025-12-05 18:15:54 +04:00
23rd
933b6bedc9 Added icons to simple list of passkeys in section of settings. 2025-12-05 18:15:54 +04:00
23rd
2db8a5d00a Added initial simple list of passkeys to section of settings. 2025-12-05 18:15:54 +04:00
23rd
be043ea349 Added initial api support to delete passkey. 2025-12-05 18:15:54 +04:00
23rd
e531abf31b Added header with lottie to section of settings for passkeys. 2025-12-05 18:15:54 +04:00
23rd
a6af680e59 Added initial entry point to section of settings for passkeys. 2025-12-05 18:15:54 +04:00
23rd
8292334c9b Moved out Settings::Passkeys class from header. 2025-12-05 18:15:54 +04:00
23rd
f20c5a1d3c Added initial box as entry point for passkey creation. 2025-12-05 18:15:53 +04:00
23rd
d1e2ec0309 Added initial api support to request of passkeys for account. 2025-12-05 18:15:53 +04:00
23rd
fe91cae8bc Added initial api support to register passkey. 2025-12-05 18:15:53 +04:00
23rd
7bb30bc4a8 Added initial dummy files for component of passkeys. 2025-12-05 18:15:53 +04:00
23rd
2d41d5903b Added initial dummy files for settings section of passkeys. 2025-12-05 18:15:53 +04:00
23rd
df672ffaf5 Added phrases for settings section of passkeys. 2025-12-05 18:15:53 +04:00
23rd
cb100623fb Added initial macOS API support for passkeys. 2025-12-05 18:15:53 +04:00
23rd
30ef7270b3 Added initial Win API support for passkeys. 2025-12-05 18:15:53 +04:00
23rd
91694a69eb Added initial implementation of deserialization data for passkeys. 2025-12-05 18:15:53 +04:00
23rd
cb07bcf0db Added initial dummy platform files for passkeys. 2025-12-05 18:15:53 +04:00
23rd
a31e384409 Added dummy files for credential data of passkeys. 2025-12-05 18:15:53 +04:00
John Preston
4829c6d028 Update API scheme to layer 219. 2025-12-05 18:15:53 +04:00
Ilya Fedin
ccf6a3fb97 Free more disk space in mac action 2025-12-05 09:58:57 +04:00
Ilya Fedin
2005814fca Actually free space in macOS action
Looks like the command was broken all the time but it was unnoticable due to `|| true`
2025-12-05 09:58:57 +04:00
Ilya Fedin
7319665bda Free more disk space in snap action 2025-12-05 09:58:57 +04:00
Ilya Fedin
d74074a21b Stop creating empty TCP log 2025-12-01 19:39:47 +04:00
John Preston
113115f58c Fix selecting gifts for a collection. 2025-12-01 12:20:33 +04:00
John Preston
e84799283d Simplify and fix link wrapping. 2025-12-01 12:20:33 +04:00
John Preston
71272ed2ec Improve view of finished auctions. 2025-12-01 11:38:35 +04:00
Ilya Fedin
6787c338ac Fix Russian bounds
No way it occupies 360° of latitude
2025-12-01 11:30:47 +04:00
Ilya Fedin
774a44ac7e Stop using geocode-glib
It doesn't seem to work properly anymore, it ignores the passed location doing reversed geocoding based on GeoIP only
2025-12-01 11:30:47 +04:00
23rd
29cdd358cc Added regional English/Portuguese spell check support for macOS. 2025-11-29 09:42:12 +03:00
23rd
b9b1bd5e58 Improved once again display of original date in self.
Related commits are 417d151f2c and cbc03d1e45.
2025-11-29 09:17:39 +03:00
23rd
59814aaeb0 Added ability to view stories anonymously from info stories section. 2025-11-29 09:04:42 +03:00
23rd
fd52b3c23b Fixed once again unwanted reset filter on creation of tabs strip.
Regression was introduced in c0bbb669e0.
2025-11-29 08:27:45 +03:00
John Preston
6e75a41ee6 Version 6.3.4: Fix build with Xcode. 2025-11-26 16:44:09 +04:00
John Preston
84266aef2c Version 6.3.4.
- Show active auctions above chats list.
- Add star sending effects in live stories.
- Fix back button in group member profile view.
- Export separate topics message history.
- Export audio files saved to profile.
- Many different crash fixes.
2025-11-26 14:58:32 +04:00
John Preston
40a7f8ea50 Try allowing only tab-focus for screen readers. 2025-11-26 14:57:35 +04:00
John Preston
7c4fcdd9cb Update emoji to Unicode 16. 2025-11-26 14:48:16 +04:00
John Preston
92e87852c1 Fix top bar title/subtitle in saved messages.
Fixes #30018.
2025-11-26 13:27:32 +04:00
John Preston
73c4da2b21 Show '+' to the right of all bids. 2025-11-26 13:01:15 +04:00
23rd
9f4da7e890 Added button for profile color to settings information section. 2025-11-26 05:37:09 +03:00
23rd
8b23457373 Fixed display of verified icon in box from web bot preview.
Regression was introduced in e7fa330215.
2025-11-26 05:30:38 +03:00
23rd
ab2fd7c749 Once again fixed position of tag preview in chats filter settings.
Previous related commit 512e6de39b.
2025-11-26 05:20:23 +03:00
John Preston
040a6ddf3a Fix build with MSVC. 2025-11-25 21:34:26 +04:00
John Preston
55afe0912f Add screen reader state logging. 2025-11-25 21:28:57 +04:00
23rd
ee48127094 Added send small button to box of entry from credits earn history. 2025-11-25 20:01:09 +03:00
23rd
445576d568 Added ToS link to any box of entry from credits earn history. 2025-11-25 18:59:47 +03:00
23rd
8f1d40892e Added info of limited gifts to box of entry from credits earn history. 2025-11-25 18:59:47 +03:00
23rd
766db9660c Swap name of sender and subtext for paid messages in earn history list. 2025-11-25 18:59:47 +03:00
23rd
68665ec1f2 Added phrase for paid reactions of live stories to credits earn history. 2025-11-25 18:59:47 +03:00
John Preston
b400964aa1 Don't allow admin to send stars in streams. 2025-11-25 19:37:26 +04:00
John Preston
317530cfa3 Attempt to fix audio cracks in streams. 2025-11-25 19:37:10 +04:00
John Preston
e8fba23b59 Don't allow sending stars from stream admin. 2025-11-25 19:05:55 +04:00
John Preston
ef749e695e Show nice layout of stars-only messages. 2025-11-25 18:30:09 +04:00
John Preston
712ef33d6b Submit custom bid with Enter. 2025-11-25 17:50:25 +04:00
John Preston
0441b7dbc3 Show star senders in live stories. 2025-11-25 17:50:25 +04:00
23rd
3ee0dcbacd Provided topic name to export controller for topic history. 2025-11-25 06:19:41 +03:00
23rd
57411b962f Added initial ability to export topic history. 2025-11-25 06:19:34 +03:00
23rd
4eee00d95e Added forwarded_from_id field to json export for forwarded messages. 2025-11-25 06:14:06 +03:00
23rd
957a08962f Added dark theme to exported html. 2025-11-25 06:14:06 +03:00
23rd
21c82f5fe1 Added ability to view stories anonymously from context menu. 2025-11-25 06:14:06 +03:00
23rd
27964993f6 Added safe guard to userpic in peer qr box. 2025-11-25 06:14:06 +03:00
John Preston
14e296e1f9 Improve layout of about auction box. 2025-11-24 22:06:55 +04:00
John Preston
23c0ff934f Skip premium badge for Saved Messages. 2025-11-24 22:01:56 +04:00
John Preston
c64ef1e20e Allow transfering gifts without premium. 2025-11-24 21:04:51 +04:00
John Preston
ed97619c6c Guard by widget instead of session. 2025-11-24 19:22:20 +04:00
23rd
924ec592b1 Improved paint with ready full peer before animation in profile top bar. 2025-11-24 18:18:13 +03:00
23rd
669c581701 Added dummy filler to PeerQrBox when result link is empty. 2025-11-24 17:46:49 +03:00
23rd
e97ae3d537 Fixed display of QR button in info profile when no usernames. 2025-11-24 17:46:49 +03:00
23rd
08800b68f4 Slightly improved subtext for topic link in info profile. 2025-11-24 17:46:49 +03:00
23rd
a59db6529c Added default guarded callback for simple QR box for peer username. 2025-11-24 17:46:49 +03:00
dependabot[bot]
02a54ceea6 Bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [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/v5...v6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 17:59:24 +04:00
John Preston
f0a7c547e8 Add safe check for strange click reports. 2025-11-24 17:51:42 +04:00
John Preston
ecfb343690 Fix crash in going from saved music to a chat. 2025-11-24 17:38:54 +04:00
John Preston
c65472c9b3 Add more assertions to find a problem. 2025-11-24 17:27:29 +04:00
John Preston
c42864d35e Fix crash in several video removed from video call. 2025-11-24 17:08:10 +04:00
John Preston
b02ce599e6 Fix possible crash in usernames order saving. 2025-11-24 14:47:14 +04:00
John Preston
1ae5495b91 Add some more assertions for subsection tabs. 2025-11-24 14:20:10 +04:00
John Preston
c4fbb8c199 Fix possible crash in group call box closing. 2025-11-24 14:19:37 +04:00
John Preston
313872dacc Fix crash in live location message destruction. 2025-11-24 12:23:13 +04:00
John Preston
ef15136a3b Fix possible crash in conference box closing. 2025-11-24 10:12:38 +04:00
John Preston
4342c8d761 Fix Live stories display without OpenGL. 2025-11-24 09:59:34 +04:00
23rd
644744ac9e Improved phrase of original date in self. 2025-11-23 18:29:01 +03:00
23rd
cbc03d1e45 Fixed display of original date in self when original sender is hidden. 2025-11-23 18:13:34 +03:00
23rd
7f56192b97 Fixed handler of login email in intro section.
This occurs both log in with setting up of login email
and log in by code from login email (set before).
2025-11-23 16:25:01 +03:00
23rd
6590f3b741 Added simple handle of EMAIL_NOT_SETUP error from email login section. 2025-11-23 16:25:01 +03:00
23rd
c0bbb669e0 Fixed unwanted switching to default filter on creation of tabs strip. 2025-11-23 16:25:01 +03:00
23rd
63014adfef Fixed rpl trigger for back button in profile top bar. 2025-11-23 16:25:01 +03:00
23rd
1ad055c8c8 Updated libiconv to v1.18. 2025-11-22 12:36:36 +03:00
John Preston
9b558564e9 Show my place correctly. 2025-11-21 21:26:44 +04:00
John Preston
476e66d027 Version 6.3.3: Fix build with Xcode. 2025-11-21 20:37:46 +04:00
John Preston
fc11d81673 Version 6.3.3.
- Some more improvements for gift auctions.
2025-11-21 19:07:31 +04:00
John Preston
629754a353 Correctly track emoji pausing in suggestions bar. 2025-11-21 19:05:02 +04:00
John Preston
147dbee051 Implement active auctions chats list bar. 2025-11-21 18:58:03 +04:00
John Preston
7204c3c25d Version 6.3.2: Fix build with GCC. 2025-11-20 23:58:26 +04:00
23rd
b412241d25 Added minimal threshold to emoji preview for reaction selector. 2025-11-20 22:39:01 +04:00
23rd
f9883afd61 Removed assertion from stats point details widget to avoid crash. 2025-11-20 22:39:01 +04:00
GitHub Action
181f811f18 Update User-Agent for DNS to Chrome 142.0.0.0. 2025-11-20 22:25:19 +04:00
dependabot[bot]
2f0bd3c085 Bump endersonmenezes/free-disk-space from 2.1.1 to 3.0.0
Bumps [endersonmenezes/free-disk-space](https://github.com/endersonmenezes/free-disk-space) from 2.1.1 to 3.0.0.
- [Release notes](https://github.com/endersonmenezes/free-disk-space/releases)
- [Commits](713d134e24...6c4664f433)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-20 22:25:03 +04:00
Ilya Fedin
a9d8332766 macos-15-intel -> macos-latest 2025-11-20 22:24:51 +04:00
John Preston
f5036171cf Add actions menu (about/copy/share) for auctions. 2025-11-20 22:24:16 +04:00
John Preston
cdc8b8e473 Show nice userpics in change recipient. 2025-11-20 21:53:35 +04:00
John Preston
ab404c5452 Fix possible crash in sticker preview. 2025-11-20 21:48:30 +04:00
John Preston
0585f9d667 Show correct value of gifted auction gift. 2025-11-20 21:12:20 +04:00
John Preston
19225c7dd3 Rebuild slider when relevant values change. 2025-11-20 20:47:56 +04:00
23rd
8c1844b1c0 Improved unloading heavy part from MediaGeneric for gift's backgrounds. 2025-11-20 19:25:44 +03:00
23rd
af63d86e24 Replaced timer with single-shot updates in auction from view web page. 2025-11-20 19:02:55 +03:00
23rd
1f2fd3ad96 Added support of auctions to history view web page. 2025-11-20 18:22:43 +03:00
23rd
f41fdcdb98 Added saved music to data export. 2025-11-20 15:43:21 +03:00
23rd
f78a9b4220 Removed display of empty menu from userpic in profile top bar. 2025-11-20 15:43:21 +03:00
23rd
06b3ce58ed Fixed stories mouse interaction after album switch in My Profile.
When switching between cached albums with equal story counts,
stories become unresponsive until scrolling occurs. This happens
because the list is recreated with zero visible top/bottom values.

Added deferred visible range update after album switching.
2025-11-20 15:43:20 +03:00
John Preston
7c70d8b1c2 Show some rounds info on details page. 2025-11-20 15:01:26 +04:00
John Preston
2b1e032a9b Show by color if you'll be winning the round. 2025-11-20 14:34:19 +04:00
23rd
4f5d6a2fd5 Replaced dependence from scroll events in flexible scroll with custom. 2025-11-20 14:15:56 +04:00
23rd
c3b90aa492 Improved calculation of filler height for flexible scroll. 2025-11-20 14:15:56 +04:00
23rd
bb2daac007 Added support of text color from emoji status in profile top bar. 2025-11-20 14:15:56 +04:00
23rd
bc2449c3f9 Fixed update of local state after reorder stories in albums. 2025-11-20 14:15:56 +04:00
23rd
0bf50de77a Fixed display of menu for actions in profile top bar for sublists. 2025-11-20 14:15:56 +04:00
23rd
473bc32b71 Fixed peer in info profile opened from sublist. 2025-11-20 14:15:55 +04:00
23rd
e5e143dcf8 Extended behavior of manage button in profile top bar to edit topic. 2025-11-20 14:15:55 +04:00
23rd
2de08746ac Added toast to topic icon in profile top bar. 2025-11-20 14:15:55 +04:00
23rd
ae6833b4d5 Added width checks to profile top bar to prevent redundant calls. 2025-11-20 14:15:55 +04:00
23rd
f1fe5f6a71 Fixed width of very long go-to-forum button in profile top bar. 2025-11-20 14:15:55 +04:00
23rd
5054d0615e Fixed events handler of self forwards tagger.
Regression was introduced in e62a4b065a.
2025-11-20 14:15:55 +04:00
John Preston
4f5007ea64 Use a separate lang key for reset photo button. 2025-11-20 14:14:08 +04:00
John Preston
233f6ed13b Improve bid information display. 2025-11-20 14:13:43 +04:00
John Preston
f15b883471 Support subtext in Stars Bubble in bids. 2025-11-20 13:29:19 +04:00
John Preston
312d5f0121 Improve auction gift display. 2025-11-20 11:39:22 +04:00
Ilya Fedin
75a1657c49 Log Linux notification daemon startup errors 2025-11-20 10:42:13 +04:00
Ilya Fedin
667d92100e Switch Linux notification service watcher to std::optional 2025-11-20 10:42:13 +04:00
Ilya Fedin
8ff4bc8cff Port IconButton back to setAccessibleName 2025-11-19 16:06:56 +04:00
John Preston
656b262648 Allow setting custom auction bid. 2025-11-19 15:00:06 +04:00
John Preston
c1769b9ba2 Correctly show/hide price selection. 2025-11-18 20:30:43 +04:00
John Preston
04c9d92b4a Fix couple of comments layout bugs. 2025-11-18 20:11:22 +04:00
John Preston
0babef5a09 Always show comments, send stars if disabled. 2025-11-18 19:44:24 +04:00
John Preston
cd52407723 Fix back button restore in new profile cover. 2025-11-18 18:24:16 +04:00
John Preston
68c0aa7fb9 Fix quadratic loop on many same custom emoji. 2025-11-18 17:57:00 +04:00
John Preston
f1622c40a4 Fix possible crash from accessibility text insertion. 2025-11-18 17:56:33 +04:00
John Preston
688e7316eb Version 6.3.1.
- Reorder saved music in My Profile.
- Fix new cover overlapping information in My Profile.
- Fix opening stories from My Profile.
- Fix media viewer breaking after viewing Live Stories.
- Fix several possible crashes.
2025-11-17 20:45:32 +04:00
23rd
ef5ec47797 Slightly improved code style of info media list section. 2025-11-17 18:30:36 +03:00
23rd
147ad4a773 Slightly improved code style of info media list widget. 2025-11-17 18:30:36 +03:00
23rd
9752145b49 Fixed userpic paint on new self upload in profile top bar. 2025-11-17 18:30:36 +03:00
23rd
662b862d2f Fixed edge skips in list of actions from info profile. 2025-11-17 18:30:36 +03:00
23rd
6d469509a4 Added tooltip to userpic in profile top bar. 2025-11-17 18:30:36 +03:00
23rd
0dfbb8a5ae Added ability to set group or channel photo from profile top bar. 2025-11-17 18:30:36 +03:00
23rd
1e12ecda70 Extended story outline support to channels in profile top bar. 2025-11-17 18:30:36 +03:00
23rd
035087987c Added icon for reorder to media list section with one column mode. 2025-11-17 18:30:36 +03:00
23rd
18422c4193 Added ability to get both item and section by point in layout overview. 2025-11-17 18:30:36 +03:00
John Preston
f1f9fe27a9 Provide better error on specific bad proxy links.
There are a lot of incorrect MTProxy links with secret in base64
starting with "EE" in base64 encoded format.
2025-11-17 19:26:06 +04:00
John Preston
10667e14e2 Fix crash in ShareBox scheduling.
Fixes #30012.
2025-11-17 18:36:43 +04:00
John Preston
b04c7efdf4 Fix last server message tracking in sublist/forum.
Fixes #30011.
2025-11-17 18:15:16 +04:00
John Preston
0119731360 Fix style of username input for a proxy. 2025-11-17 18:15:00 +04:00
John Preston
8f337684d5 Add close buttons to AuctionGotGiftsBox. 2025-11-17 13:58:19 +04:00
John Preston
dae93552f0 Show correct months count in premium gifts. 2025-11-17 13:57:18 +04:00
John Preston
351bbb240f Shorten bid amount for huge bids. 2025-11-17 13:44:16 +04:00
John Preston
5716de2e6e Fix LIVE badge translations. 2025-11-17 13:03:53 +04:00
John Preston
14295d59d1 Add some debug logs on app startup timing. 2025-11-17 12:55:44 +04:00
John Preston
df0849473c Fix possible crash in button accessibility. 2025-11-17 12:22:54 +04:00
John Preston
9736706894 Fix initial loading of My Profile with stories. 2025-11-17 12:19:23 +04:00
John Preston
12343a5c31 Less templates in Info::FlexibleScroll. 2025-11-17 12:02:42 +04:00
John Preston
a7f046a617 Fix incorrect GL texture deletion. 2025-11-17 11:23:40 +04:00
Ilya Fedin
67bf796f1e Split scheme check code in Linux launch maps implementation 2025-11-17 10:48:01 +04:00
John Preston
22d632abc3 Update hidden gift icon. 2025-11-17 10:47:07 +04:00
John Preston
25094c1ee6 Support paddings in icon parts. 2025-11-17 10:47:07 +04:00
John Preston
5b71ad0456 Fix build with MSVC. 2025-11-17 10:47:07 +04:00
John Preston
9146ba996f Force v143 toolset on Windows for now (win7). 2025-11-17 09:39:25 +04:00
23rd
42900787e1 Added initial ability to filter layout items for reordering. 2025-11-16 23:52:56 +03:00
23rd
ba10c10a94 Added initial ability to reorder tracks in saved music section. 2025-11-16 23:52:56 +03:00
23rd
3f37e9ca6f Added initial ability to reorder stories in albums. 2025-11-16 23:52:56 +03:00
23rd
c5ea86b474 Added initial implementation of reorder items in media layouts.
Except mosaic.
2025-11-16 23:52:56 +03:00
23rd
76720092a5 Added api support to reorder track from saved music. 2025-11-16 23:52:56 +03:00
23rd
7a75c80b27 Attempted to improve status color with darkest gifts in profile top bar. 2025-11-16 13:01:57 +03:00
23rd
b2dcbebb5b Added proper visibility forwarding to flexible scroll content widget. 2025-11-16 12:54:15 +03:00
860 changed files with 20647 additions and 7961 deletions

View File

@@ -60,7 +60,7 @@ rpl::lifetime &parentLifetime = /* ... get lifetime from context ... */;
To consume values from a producer, you start a pipeline using one of the `rpl::start_...` methods. These methods subscribe to the producer and execute callbacks for the events they handle.
The most common method is `rpl::start_with_next`:
The most common method is `rpl::on_next`:
```cpp
auto counter = /* ... */; // Type: rpl::producer<int>
@@ -69,20 +69,20 @@ rpl::lifetime lifetime;
// Counter is consumed here, use std::move if it's an l-value.
std::move(
counter
) | rpl::start_with_next([=]\(int nextValue) {
) | rpl::on_next([=]\(int nextValue) {
// Process the next integer value emitted by the producer.
qDebug() << "Received: " << nextValue;
}, lifetime); // Pass the lifetime to manage the subscription.
// Note: `counter` is now in a moved-from state and likely invalid.
// If you need to start the same producer multiple times, duplicate it:
// rpl::duplicate(counter) | rpl::start_with_next(...);
// rpl::duplicate(counter) | rpl::on_next(...);
// If you DON'T pass a lifetime to a start_... method:
auto counter2 = /* ... */; // Type: rpl::producer<int>
rpl::lifetime subscriptionLifetime = std::move(
counter2
) | rpl::start_with_next([=]\(int nextValue) { /* ... */ });
) | rpl::on_next([=]\(int nextValue) { /* ... */ });
// The returned lifetime MUST be stored. If it's discarded immediately,
// the subscription stops instantly.
// `counter2` is also moved-from here.
@@ -98,7 +98,7 @@ rpl::lifetime lifetime;
// If it's the only use, std::move(dataStream) would be preferred.
rpl::duplicate(
dataStream
) | rpl::start_with_error([=]\(Error &&error) {
) | rpl::on_error([=]\(Error &&error) {
// Handle the error signaled by the producer.
qDebug() << "Error: " << error.text();
}, lifetime);
@@ -106,7 +106,7 @@ rpl::duplicate(
// Using dataStream again, perhaps duplicated again or moved if last use.
rpl::duplicate(
dataStream
) | rpl::start_with_done([=] {
) | rpl::on_done([=] {
// Execute when the producer signals it's finished emitting values.
qDebug() << "Stream finished.";
}, lifetime);
@@ -114,7 +114,7 @@ rpl::duplicate(
// Last use of dataStream, so we move it.
std::move(
dataStream
) | rpl::start_with_next_error_done(
) | rpl::on_next_error_done(
[=]\(QString &&value) { /* handle next value */ },
[=]\(Error &&error) { /* handle error */ },
[=] { /* handle done */ },
@@ -169,7 +169,7 @@ You can combine multiple producers into one:
// The lambda receives unpacked arguments, not the tuple itself.
std::move(
combined
) | rpl::start_with_next([=]\(int count, const QString &text) {
) | rpl::on_next([=]\(int count, const QString &text) {
// No need for std::get<0>(latest), etc.
qDebug() << "Combined: Count=" << count << ", Text=" << text;
}, lifetime);
@@ -181,7 +181,7 @@ You can combine multiple producers into one:
return count > 0 && !text.isEmpty();
}) | rpl::map([=]\(int count, const QString &text) {
return text.repeated(count);
}) | rpl::start_with_next([=]\(const QString &result) {
}) | rpl::on_next([=]\(const QString &result) {
qDebug() << "Mapped & Filtered: " << result;
}, lifetime);
```
@@ -197,7 +197,7 @@ You can combine multiple producers into one:
// Starting the merged producer consumes it.
std::move(
merged
) | rpl::start_with_next([=]\(QString &&value) {
) | rpl::on_next([=]\(QString &&value) {
// Receives values from either sourceA or sourceB as they arrive.
qDebug() << "Merged value: " << value;
}, lifetime);

View File

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

View File

@@ -59,7 +59,7 @@ jobs:
steps:
- name: Clone.
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
submodules: recursive
@@ -71,6 +71,7 @@ jobs:
poetry install
DOCKERFILE=$(DEBUG= LTO= poetry run gen_dockerfile)
echo "$DOCKERFILE" > Dockerfile
rm -rf __pycache__
- name: Free up some disk space.
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be

View File

@@ -40,7 +40,7 @@ jobs:
macos:
name: MacOS
runs-on: macos-15-intel
runs-on: macos-latest
strategy:
matrix:
@@ -56,7 +56,7 @@ jobs:
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
- name: Clone.
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
submodules: recursive
path: ${{ env.REPO_NAME }}
@@ -74,6 +74,15 @@ jobs:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
- name: Free up some disk space.
uses: hugoalh/disk-space-optimizer-ghaction@271735125a1b35180620eae7e45c2e9d470c31b0
with:
general_include: ".+"
homebrew_prune: "True"
homebrew_clean: "True"
npm_prune: "True"
npm_clean: "True"
- name: ThirdParty cache.
id: cache-third-party
uses: actions/cache@v4
@@ -95,9 +104,7 @@ jobs:
./$REPO_NAME/Telegram/build/prepare/mac.sh skip-release silent
- name: Free up some disk space.
run: |
cd Libraries
find . -iname "*.dir" -exec rm -rf {} || true \;
run: find Libraries -iwholename "*.dir/*" -delete
- name: Telegram Desktop build.
if: env.ONLY_CACHE == 'false'

View File

@@ -60,7 +60,7 @@ jobs:
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
- name: Clone.
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
submodules: recursive
path: ${{ env.REPO_NAME }}
@@ -85,7 +85,7 @@ jobs:
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
echo "WEBRTC=`curl -sSL https://api.github.com/repos/desktop-app/tg_owt/git/refs/heads/master | jq -r .object.sha`" >> $GITHUB_ENV
- name: RNNoise.
run: |
@@ -103,7 +103,7 @@ jobs:
uses: actions/cache@v4
with:
path: ${{ env.LibrariesPath }}/tg_owt
key: ${{ runner.OS }}-webrtc-${{ env.CACHE_KEY }}-${{ hashFiles('**/tg_owt-version.json') }}
key: ${{ runner.OS }}-webrtc-${{ env.CACHE_KEY }}-${{ env.WEBRTC }}
- name: WebRTC.
if: steps.cache-webrtc.outputs.cache-hit != 'true'
run: |

View File

@@ -47,7 +47,7 @@ jobs:
steps:
- name: Clone.
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
submodules: recursive
@@ -61,16 +61,11 @@ jobs:
sudo lxd waitready
- name: Free up some disk space.
uses: endersonmenezes/free-disk-space@713d134e243b926eba4a5cce0cf608bfd1efb89a
uses: samueldr/more-space-action@97048bd0df83fb05b5257887bdbaffc848887673
with:
remove_android: true
remove_dotnet: true
remove_haskell: true
remove_tool_cache: true
remove_swap: true
remove_packages: "azure-cli google-cloud-cli microsoft-edge-stable google-chrome-stable firefox postgresql* temurin-* *llvm* mysql* dotnet-sdk-*"
remove_packages_one_command: true
remove_folders: "/usr/share/swift /usr/share/miniconda /usr/share/az* /usr/share/glade* /usr/local/lib/node_modules /usr/local/share/chromium /usr/local/share/powershell"
enable-remove-default-apt-patterns: false
enable-lvm-span: true
lvm-span-mountpoint: /var/snap/lxd/common/lxd/storage-pools/default/containers
- name: Telegram Desktop snap build.
run: sudo -u $USER snap run snapcraft --verbosity=debug

View File

@@ -72,7 +72,7 @@ jobs:
run: echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV
- name: Clone.
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
submodules: recursive
path: ${{ env.TBUILD }}\${{ env.REPO_NAME }}

View File

@@ -337,6 +337,8 @@ PRIVATE
boxes/star_gift_auction_box.h
boxes/star_gift_box.cpp
boxes/star_gift_box.h
boxes/star_gift_preview_box.cpp
boxes/star_gift_preview_box.h
boxes/star_gift_resale_box.cpp
boxes/star_gift_resale_box.h
boxes/sticker_set_box.cpp
@@ -405,6 +407,8 @@ PRIVATE
calls/calls_instance.h
calls/calls_panel.cpp
calls/calls_panel.h
calls/calls_panel_background.cpp
calls/calls_panel_background.h
calls/calls_signal_bars.cpp
calls/calls_signal_bars.h
calls/calls_top_bar.cpp
@@ -523,6 +527,8 @@ PRIVATE
data/components/gift_auctions.h
data/components/location_pickers.cpp
data/components/location_pickers.h
data/components/passkeys.cpp
data/components/passkeys.h
data/components/promo_suggestions.cpp
data/components/promo_suggestions.h
data/components/recent_peers.cpp
@@ -918,6 +924,8 @@ PRIVATE
history/view/history_view_pinned_tracker.h
history/view/history_view_quick_action.cpp
history/view/history_view_quick_action.h
history/view/history_view_reaction_preview.cpp
history/view/history_view_reaction_preview.h
history/view/history_view_reply.cpp
history/view/history_view_reply.h
history/view/history_view_requests_bar.cpp
@@ -1401,6 +1409,7 @@ PRIVATE
platform/linux/specific_linux.h
platform/linux/tray_linux.cpp
platform/linux/tray_linux.h
platform/linux/webauthn_linux.cpp
platform/mac/file_utilities_mac.mm
platform/mac/file_utilities_mac.h
platform/mac/launcher_mac.mm
@@ -1420,6 +1429,7 @@ PRIVATE
platform/mac/specific_mac_p.h
platform/mac/tray_mac.mm
platform/mac/tray_mac.h
platform/mac/webauthn_mac.mm
platform/mac/window_title_mac.mm
platform/mac/touchbar/items/mac_formatter_item.h
platform/mac/touchbar/items/mac_formatter_item.mm
@@ -1454,6 +1464,7 @@ PRIVATE
platform/win/specific_win.h
platform/win/tray_win.cpp
platform/win/tray_win.h
platform/win/webauthn_win.cpp
platform/win/windows_app_user_model_id.cpp
platform/win/windows_app_user_model_id.h
platform/win/windows_dlls.cpp
@@ -1472,6 +1483,7 @@ PRIVATE
platform/platform_overlay_widget.h
platform/platform_specific.h
platform/platform_tray.h
platform/platform_webauthn.h
platform/platform_window_title.h
profile/profile_back_button.cpp
profile/profile_back_button.h
@@ -1557,6 +1569,8 @@ PRIVATE
settings/settings_notifications.h
settings/settings_notifications_type.cpp
settings/settings_notifications_type.h
settings/settings_passkeys.cpp
settings/settings_passkeys.h
settings/settings_power_saving.cpp
settings/settings_power_saving.h
settings/settings_premium.cpp
@@ -1900,15 +1914,17 @@ elseif (APPLE)
COMMAND cp ${CMAKE_BINARY_DIR}/lib_spellcheck.rcc $<TARGET_FILE_DIR:Telegram>/../Resources
)
if (NOT build_macstore AND NOT DESKTOP_APP_DISABLE_CRASH_REPORTS)
if (DESKTOP_APP_MAC_ARCH STREQUAL "x86_64" OR DESKTOP_APP_MAC_ARCH STREQUAL "arm64")
set(crashpad_dir_part ".${DESKTOP_APP_MAC_ARCH}")
if (DESKTOP_APP_USE_PACKAGED)
find_program(CRASHPAD_HANDLER crashpad_handler REQUIRED)
elseif (DESKTOP_APP_MAC_ARCH STREQUAL "x86_64" OR DESKTOP_APP_MAC_ARCH STREQUAL "arm64")
set(CRASHPAD_HANDLER "${libs_loc}/crashpad/out/$<IF:$<CONFIG:Debug>,Debug,Release>.${DESKTOP_APP_MAC_ARCH}/crashpad_handler")
else()
set(crashpad_dir_part "")
set(CRASHPAD_HANDLER "${libs_loc}/crashpad/out/$<IF:$<CONFIG:Debug>,Debug,Release>/crashpad_handler")
endif()
add_custom_command(TARGET Telegram
PRE_LINK
COMMAND mkdir -p $<TARGET_FILE_DIR:Telegram>/../Helpers
COMMAND cp ${libs_loc}/crashpad/out/$<IF:$<CONFIG:Debug>,Debug,Release>${crashpad_dir_part}/crashpad_handler $<TARGET_FILE_DIR:Telegram>/../Helpers/
COMMAND cp ${CRASHPAD_HANDLER} $<TARGET_FILE_DIR:Telegram>/../Helpers/
)
endif()
else()
@@ -1928,8 +1944,9 @@ if (build_macstore)
set(bundle_identifier "org.telegram.desktop")
set(bundle_entitlements "Telegram Lite.entitlements")
set(output_name "Telegram Lite")
set_target_properties(Telegram PROPERTIES
XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${libs_loc}/breakpad/src/client/mac/build/Release
target_link_options(Telegram
PRIVATE
-F${libs_loc}/breakpad/src/client/mac/build/Release
)
target_link_frameworks(Telegram PRIVATE Breakpad)
add_custom_command(TARGET Telegram
@@ -2117,7 +2134,7 @@ if (NOT DESKTOP_APP_DISABLE_AUTOUPDATE AND NOT build_macstore AND NOT build_wins
endif()
elseif (APPLE)
add_custom_command(TARGET Updater
PRE_LINK
POST_BUILD
COMMAND mkdir -p $<TARGET_FILE_DIR:Telegram>/../Frameworks
COMMAND cp $<TARGET_FILE:Updater> $<TARGET_FILE_DIR:Telegram>/../Frameworks/
)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 935 KiB

After

Width:  |  Height:  |  Size: 938 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

After

Width:  |  Height:  |  Size: 250 KiB

View File

@@ -440,6 +440,9 @@ div.toast_shown {
.section.stories {
background-image: url(../images/section_stories.png);
}
.section.music {
background-image: url(../images/section_music.png);
}
.section.web {
background-image: url(../images/section_web.png);
}
@@ -481,6 +484,16 @@ div.toast_shown {
.media_video .fill {
background-image: url(../images/media_video.png)
}
.audio_icon {
width: 48px;
height: 48px;
border-radius: 50%;
background-color: #4f9cd9;
background-image: url(../images/media_music.png);
background-repeat: no-repeat;
background-position: 12px 12px;
background-size: 24px 24px;
}
@media only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) {
.section.calls {
@@ -504,6 +517,9 @@ div.toast_shown {
.section.stories {
background-image: url(../images/section_stories@2x.png);
}
.section.music {
background-image: url(../images/section_music@2x.png);
}
.section.web {
background-image: url(../images/section_web@2x.png);
}
@@ -545,6 +561,9 @@ div.toast_shown {
.media_video .fill {
background-image: url(../images/media_video@2x.png)
}
.audio_icon {
background-image: url(../images/media_music@2x.png);
}
}
.spoiler {
@@ -633,4 +652,101 @@ div.toast_shown {
.reactions .reaction .count {
margin-right: 8px;
line-height: 20px;
}
@media (prefers-color-scheme: dark) {
html, body {
background-color: #1a2026; /* groupCallBg */
margin: 0;
padding: 0;
}
.page_wrap {
background-color: #1a2026; /* groupCallBg */
color: #ffffff; /* groupCallMembersFg */
min-height: 100vh;
}
.page_wrap a {
color: #4db8ff; /* groupCallActiveFg */
}
.page_header {
background-color: #1a2026; /* groupCallBg */
border-bottom: 1px solid #2c333d; /* groupCallMembersBg */
}
.bold {
color: #ffffff; /* groupCallMembersFg */
}
.details {
color: #91979e; /* groupCallMemberNotJoinedStatus */
}
.page_body {
background-color: #1a2026; /* groupCallBg */
}
code {
color: #ff8aac; /* historyPeer6UserpicBg */
background-color: #2c333d; /* groupCallMembersBg */
}
pre {
color: #ffffff; /* groupCallMembersFg */
background-color: #2c333d; /* groupCallMembersBg */
border: 1px solid #323a45; /* groupCallMembersBgOver */
}
.with_divider {
border-top: 1px solid #2c333d; /* groupCallMembersBg */
}
a.block_link:hover {
background-color: #323a45; /* groupCallMembersBgOver */
}
.list_page .entry {
color: #ffffff; /* groupCallMembersFg */
}
.message {
color: #ffffff; /* groupCallMembersFg */
}
div.selected {
background-color: #323a45; /* groupCallMembersBgOver */
}
.default .from_name {
color: #4db8ff; /* groupCallActiveFg */
}
.default .media .description {
color: #ffffff; /* groupCallMembersFg */
}
msgInBg,
.historyComposeAreaBg {
background-color: #2c333d; /* groupCallMembersBg */
}
msgOutBg {
background-color: #323a45; /* groupCallMembersBgOver */
}
msgInBgSelected {
background-color: #39424f; /* groupCallMembersBgRipple */
}
msgOutBgSelected {
background-color: #39424f; /* groupCallMembersBgRipple */
}
.spoiler {
background: #323a45; /* groupCallMembersBgOver */
}
.spoiler.hidden {
background: #61c0ff; /* groupCallMemberInactiveStatus */
}
.bot_button {
background-color: #4db8ff40; /* groupCallActiveFg with opacity */
}
.reactions .reaction {
background-color: #2c333d; /* groupCallMembersBg */
color: #4db8ff; /* groupCallActiveFg */
}
.reactions .reaction.active {
background-color: #4db8ff; /* groupCallActiveFg */
color: #1a2026; /* groupCallBg */
}
.reactions .reaction.paid {
background-color: #323a45; /* groupCallMembersBgOver */
color: #febb5b; /* historyPeer8UserpicBg */
}
.reactions .reaction.active.paid {
background-color: #febb5b; /* historyPeer8UserpicBg */
color: #1a2026; /* groupCallBg */
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 840 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -22,7 +22,9 @@ 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_main_menu" = "Main menu";
"lng_filter_unread_chats#one" = "{text} ({count} unread chat)";
"lng_filter_unread_chats#other" = "{text} ({count} unread chats)";
"lng_disable_notifications_from_tray" = "Disable notifications";
"lng_enable_notifications_from_tray" = "Enable notifications";
@@ -328,6 +330,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_proxy_box_password" = "Password";
"lng_proxy_invalid" = "The proxy link is invalid.";
"lng_proxy_unsupported" = "Your Telegram Desktop version doesn't support this proxy type or the proxy link is invalid. Please update Telegram Desktop to the latest version.";
"lng_proxy_incorrect_secret" = "This proxy link uses invalid **secret** parameter. Please contact the proxy provider and ask him to update MTProxy source code and configure it with a correct **secret** value. Then let him provide a new link.";
"lng_edit_deleted" = "This message was deleted";
"lng_edit_limit_reached#one" = "You've reached the message text limit. Please make the text shorter by {count} character.";
@@ -377,6 +380,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_intro_qr_step2" = "Go to Settings > Devices > Link Desktop Device";
"lng_intro_qr_step3" = "Scan this image to Log In";
"lng_intro_qr_skip" = "Or log in using your phone number";
"lng_intro_qr_phone" = "Log in using phone number";
"lng_intro_qr_passkey" = "Log in using passkey";
"lng_intro_fragment_title" = "Enter code";
"lng_intro_fragment_about" = "Get the code for {phone_number} in the Anonymous Numbers section on Fragment.";
@@ -1251,6 +1256,28 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_restart_now" = "Restart";
"lng_settings_restart_later" = "Later";
"lng_settings_passkeys_title" = "Passkeys";
"lng_settings_passkeys_about" = "Manage your passkey, stored safely in the cloud service you choose.";
"lng_settings_passkeys_button" = "Add Passkey";
"lng_settings_passkeys_button_about" = "Your passkey is stored securely in your password manager. {link}";
"lng_settings_passkeys_delete_sure_title" = "Delete Passkey";
"lng_settings_passkeys_delete_sure_about" = "Once deleted, this passkey can't be used to log in.";
"lng_settings_passkeys_delete_sure_about2" = "Don't forget to remove it from your password manager too.";
"lng_settings_passkeys_none_title" = "Protect your account";
"lng_settings_passkeys_none_about" = "Log in safely and keep your account secure.";
"lng_settings_passkeys_none_info1_title" = "Create a Passkey";
"lng_settings_passkeys_none_info1_about" = "Make a passkey to sign in easily and safely.";
"lng_settings_passkeys_none_info2_title" = "Log in with face recognition";
"lng_settings_passkeys_none_info2_about" = "Use your face, fingerprint, or screen lock to sign in.";
"lng_settings_passkeys_none_info3_title" = "Store Passkey securely";
"lng_settings_passkeys_none_info3_about" = "Your passkey is stored safely in the cloud service you choose.";
"lng_settings_passkeys_none_button" = "Create Passkey";
"lng_settings_passkeys_none_button_unsupported" = "Unsupported";
"lng_settings_passkeys_created" = "Created {date}";
"lng_settings_passkeys_last_used" = "Last used {date}";
"lng_settings_passkeys_unsigned_error" = "Passkeys are not available in unsigned builds. Please use an official signed version of Telegram Desktop.";
"lng_settings_passkey_unknown" = "Passkey";
"lng_settings_quick_dialog_action_title" = "Chat list quick action";
"lng_settings_quick_dialog_action_about" = "Choose the action you want to perform when you middle-click or swipe left in the chat list.";
"lng_settings_quick_dialog_action_both" = "Swipe left and Middle-click";
@@ -1591,6 +1618,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_administrators#one" = "{count} administrator";
"lng_profile_administrators#other" = "{count} administrators";
"lng_profile_manage" = "Channel settings";
"lng_profile_topic_toast" = "This topic contains {name}";
"lng_invite_upgrade_title" = "Upgrade to Premium";
"lng_invite_upgrade_group_invite#one" = "{users} only accepts invitations to groups from Contacts and **Premium** users.";
@@ -1682,9 +1710,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_suggest_photo" = "Suggest Profile Photo";
"lng_profile_suggest_photo_from_clipboard" = "Suggest From Clipboard";
"lng_profile_set_photo_for" = "Set Profile Photo";
"lng_profile_set_photo_for_group" = "Set Group Photo";
"lng_profile_set_photo_for_channel" = "Set Channel 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_button" = "Reset";
"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.";
@@ -1730,6 +1761,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_block_user" = "Block user";
"lng_profile_unblock_user" = "Unblock user";
"lng_profile_export_chat" = "Export chat history";
"lng_profile_export_topic" = "Export topic history";
"lng_profile_gift_premium" = "Gift Premium";
"lng_media_selected_photo#one" = "{count} Photo";
"lng_media_selected_photo#other" = "{count} Photos";
@@ -2262,8 +2294,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_proximity_distance_km#other" = "{count} km";
"lng_action_webview_data_done" = "Data from the \"{text}\" button was transferred to the bot.";
"lng_action_gift_received" = "{user} sent you a gift for {cost}";
"lng_action_gift_received_sold" = "{user} sold you a gift for {cost}";
"lng_action_gift_unique_received" = "{user} sent you a unique collectible item";
"lng_action_gift_sent" = "You sent a gift for {cost}";
"lng_action_gift_sent_sold" = "You sold a gift for {cost}";
"lng_action_gift_unique_sent" = "You sent a unique collectible item";
"lng_action_gift_upgraded" = "{user} turned the gift from you into a unique collectible";
"lng_action_gift_upgraded_channel" = "{user} turned this gift to {channel} into a unique collectible";
@@ -2290,7 +2324,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_gift_sent_self_channel" = "You sent a gift to {name} for {cost}";
"lng_action_gift_self_bought" = "You bought a gift for {cost}";
"lng_action_gift_self_auction" = "You've successfully bought a gift in the auction for {cost}.";
"lng_action_gift_auction" = "You've successfully bought a gift for {name} in the auction for {cost}.";
"lng_action_gift_auction_won" = "You won the auction with a bid of {cost}.";
"lng_action_gift_self_subtitle" = "Saved Gift";
"lng_action_gift_self_about#one" = "Display this gift on your page or convert it to **{count}** Star.";
"lng_action_gift_self_about#other" = "Display this gift on your page or convert it to **{count}** Stars.";
@@ -2319,6 +2353,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_gift_premium_about" = "Subscription for exclusive Telegram features.";
"lng_action_gift_refunded" = "This gift was downgraded because a request to refund the payment related to this gift was made, and the money was returned.";
"lng_action_gift_got_ton" = "Use TON to suggest posts to channels.";
"lng_action_gift_offer" = "{user} offered you {cost} for {name}.";
"lng_action_gift_offer_you" = "You offered {cost} for {name}.";
"lng_action_gift_offer_state_expires" = "This offer expires in {time}.";
"lng_action_gift_offer_time_large" = "{hours} h";
"lng_action_gift_offer_time_medium" = "{hours} h {minutes} m";
"lng_action_gift_offer_time_small" = "{minutes} m";
"lng_action_gift_offer_state_accepted" = "This offer was accepted.";
"lng_action_gift_offer_state_rejected" = "This offer was rejected.";
"lng_action_gift_offer_state_expired" = "This offer has expired.";
"lng_action_gift_offer_sold" = "{user} sold {name} for {cost}.";
"lng_action_gift_offer_sold_you" = "You sold {name} for {cost}.";
"lng_action_gift_offer_decline" = "Reject";
"lng_action_gift_offer_accept" = "Accept";
"lng_action_gift_offer_expired" = "The offer from {user} to buy your {name} for {cost} has expired.";
"lng_action_gift_offer_expired_your" = "Your offer to buy {name} for {cost} has expired.";
"lng_action_gift_offer_declined" = "{user} rejected your offer to buy {name} for {cost}.";
"lng_action_gift_offer_declined_you" = "You rejected {user}'s offer to buy your {name} for {cost}.";
"lng_action_suggested_photo_me" = "You suggested this photo for {user}'s Telegram profile.";
"lng_action_suggested_photo" = "{user} suggests this photo for your Telegram profile.";
"lng_action_suggested_photo_button" = "View Photo";
@@ -2802,6 +2853,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"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_subtitle_gifts" = "Telegram Gifts";
"lng_premium_summary_about_gifts" = "Gifts are collectible items you can trade or showcase on your profile.";
"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";
@@ -2952,6 +3005,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_credits_summary_history_entry_inner_in" = "In-App Purchase";
"lng_credits_summary_balance" = "Balance";
"lng_credits_commission" = "{amount} commission";
"lng_credits_paid_messages_fee_live_reaction" = "Fee for Live Story Reaction";
"lng_credits_paid_messages_fee#one" = "Fee for {count} Message";
"lng_credits_paid_messages_fee#other" = "Fee for {count} Messages";
"lng_credits_paid_messages_fee_about" = "You receive {percent} of the price that you charge for each incoming message. {link}";
@@ -3089,6 +3143,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_credits_small_balance_for_message" = "Buy **Stars** to send messages to {user}.";
"lng_credits_small_balance_for_messages" = "Buy **Stars** to send messages.";
"lng_credits_small_balance_for_suggest" = "Buy **Stars** to suggest post to {channel}.";
"lng_credits_small_balance_for_offer" = "Buy **Stars** to offer for this gift.";
"lng_credits_small_balance_for_search" = "Buy **Stars** to search through public posts.";
"lng_credits_small_balance_fallback" = "Buy **Stars** to unlock content and services on Telegram.";
"lng_credits_purchase_blocked" = "Sorry, you can't purchase this item with Telegram Stars.";
@@ -3685,6 +3740,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_stars_premium" = "premium";
"lng_gift_stars_auction" = "auction";
"lng_gift_stars_auction_join" = "Join";
"lng_gift_stars_auction_view" = "View";
"lng_gift_stars_auction_soon" = "soon";
"lng_gift_stars_auction_upgraded" = "upgraded";
"lng_gift_stars_your_left#one" = "{count} left";
"lng_gift_stars_your_left#other" = "{count} left";
"lng_gift_stars_your_finished" = "none left";
@@ -3853,6 +3911,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"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_wearable_title" = "Wearable";
"lng_gift_upgrade_wearable_about" = "Display gifts on your page and set them as profile covers or statuses.";
"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}";
@@ -3905,6 +3965,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"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_offer_button" = "Offer to Buy";
"lng_gift_offer_title" = "Offer to Buy";
"lng_gift_offer_stars_about" = "Choose how many Stars you'd like to offer for {name}.";
"lng_gift_offer_ton_about" = "Choose how many TON you'd like to offer for {name}.";
"lng_gift_offer_duration" = "Offer Duration";
"lng_gift_offer_duration_about" = "Choose how long {user} can accept your offer. When the time expires, the amount will be refunded.";
"lng_gift_offer_cost_button" = "Offer {cost}";
"lng_gift_offer_reject_title" = "Reject Offer";
"lng_gift_offer_confirm_reject" = "Are you sure you want to reject the offer from {user}?";
"lng_gift_offer_confirm_accept" = "Do you want to sell {name} to {user} for {cost}?";
"lng_gift_offer_you_get" = "You will receive {cost} after fees.";
"lng_gift_offer_higher" = "The price you are offered is {percent} higher than the average price for {name}.";
"lng_gift_offer_lower" = "The price you are offered is {percent} lower than the average price for {name}.";
"lng_gift_offer_sell_for" = "Sell for {price}";
"lng_gift_offer_confirm_title" = "Confirm Offer";
"lng_gift_offer_confirm_text" = "Do you want to offer {cost} to {user} for {name}?";
"lng_gift_offer_table_offer" = "Offer";
"lng_gift_offer_table_fee" = "Fee";
"lng_gift_offer_table_duration" = "Duration";
"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";
@@ -3932,6 +4011,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_wear_badge_title" = "Radiant Badge";
"lng_gift_wear_badge_about" = "The glittering icon of this item will be displayed next to your name.";
"lng_gift_wear_badge_about_channel" = "The glittering icon of this item will be displayed next to channel's name.";
"lng_gift_wear_design_title" = "Unique Profile Design";
"lng_gift_wear_design_about" = "Your profile page will get the color and the symbol of this item.";
"lng_gift_wear_design_about_channel" = "Your channel page will get the color and the symbol of this item.";
"lng_gift_wear_proof_title" = "Proof of Ownership";
"lng_gift_wear_proof_about" = "Clicking the icon of this item next to your name will show its info and owner.";
"lng_gift_wear_proof_about_channel" = "Clicking the icon of this item next to channel's name will show its info and owner.";
@@ -3998,6 +4080,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_auction_about_top_bidders#other" = "top {count} bidders";
"lng_auction_about_top_about#one" = "{count} gift is dropped in {rounds} to the {bidders} by bid amount.";
"lng_auction_about_top_about#other" = "{count} gifts are dropped in {rounds} to the {bidders} by bid amount.";
"lng_auction_about_top_short#one" = "{count} gift is dropped to the {bidders} by bid amount. {link}";
"lng_auction_about_top_short#other" = "{count} gifts are dropped to the {bidders} by bid amount. {link}";
"lng_auction_about_bid_title" = "Bid Carryover";
"lng_auction_about_bid_about#one" = "If your bid leaves the top {count}, it will automatically join the next round.";
"lng_auction_about_bid_about#other" = "If your bid leaves the top {count}, it will automatically join the next round.";
@@ -4009,6 +4093,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_auction_text_link" = "Learn more {arrow}";
"lng_auction_text_ended" = "Auction ended.";
"lng_auction_start_label" = "Started";
"lng_auction_starts_label" = "Starts";
"lng_auction_rounds_label" = "Rounds";
"lng_auction_rounds_exact" = "Round {n}";
"lng_auction_rounds_range" = "Rounds {n}-{last}";
"lng_auction_rounds_seconds#one" = "{count} second each";
"lng_auction_rounds_seconds#other" = "{count} seconds each";
"lng_auction_rounds_minutes#one" = "{count} minute each";
"lng_auction_rounds_minutes#other" = "{count} minutes each";
"lng_auction_rounds_hours#one" = "{count} hour each";
"lng_auction_rounds_hours#other" = "{count} hours each";
"lng_auction_rounds_extended" = "{duration} + {increase} for late bids in top {n}";
"lng_auction_end_label" = "Ends";
"lng_auction_round_label" = "Current Round";
"lng_auction_round_value" = "{n} of {amount}";
@@ -4023,11 +4118,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_auction_join_time_left" = "{time} left";
"lng_auction_join_time_medium" = "{hours} h {minutes} m";
"lng_auction_join_time_small" = "{minutes} m";
"lng_auction_join_starts_in" = "starts in {time}";
"lng_auction_join_early_bid" = "Place an Early Bid";
"lng_auction_menu_about" = "About";
"lng_auction_menu_copy_link" = "Copy Link";
"lng_auction_menu_share" = "Share";
"lng_auction_bid_title" = "Place a Bid";
"lng_auction_bid_title_early" = "Place an Early Bid";
"lng_auction_bid_subtitle#one" = "Top {count} bidder will win";
"lng_auction_bid_subtitle#other" = "Top {count} bidders will win";
"lng_auction_bid_your" = "your bid";
"lng_auction_bid_custom" = "click to bid more";
"lng_auction_bid_threshold#one" = "TOP {count}";
"lng_auction_bid_threshold#other" = "TOP {count}";
"lng_auction_bid_minimal#one" = "minimum bid";
@@ -4035,6 +4136,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_auction_bid_until" = "until next round";
"lng_auction_bid_left#one" = "left";
"lng_auction_bid_left#other" = "left";
"lng_auction_bid_before_start" = "before start";
"lng_auction_bid_your_title" = "Your bid will be";
"lng_auction_bid_your_outbid" = "You've been outbid";
"lng_auction_bid_your_winning" = "You're winning";
@@ -4045,6 +4147,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_auction_bid_increased_title" = "Your bid has been increased";
"lng_auction_bid_done_text#one" = "If you fall below the **top {count}**, your bid will roll over to the next round.";
"lng_auction_bid_done_text#other" = "If you fall below the **top {count}**, your bid will roll over to the next round.";
"lng_auction_bid_custom_title" = "Custom Amount";
"lng_auction_preview_left#one" = "{count} left";
"lng_auction_preview_left#other" = "{count} left";
"lng_auction_preview_join" = "Join";
@@ -4070,13 +4173,34 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_auction_bought_title#other" = "{count} Items Bought";
"lng_auction_bought_date" = "Date";
"lng_auction_bought_bid" = "Accepted Bid";
"lng_auction_bought_round" = "Round #{n}";
"lng_auction_bought_in_round" = "{name} in round {n}";
"lng_auction_change_title" = "Change Recipient";
"lng_auction_change_button" = "Change";
"lng_auction_change_already" = "You've already placed a bid on this gift for {name}.";
"lng_auction_change_to" = "Do you want to raise your bid and change the recipient to {name}?";
"lng_auction_change_already_me" = "You've already placed a bid on this gift for yourself.";
"lng_auction_change_to_me" = "Do you want to raise your bid and change the recipient to yourself?";
"lng_auction_preview_name" = "Upcoming Auction";
"lng_auction_preview_learn_gifts" = "Learn more about Telegram Gifts {arrow}";
"lng_auction_preview_variants#one" = "View {emoji} {count} Variant {arrow}";
"lng_auction_preview_variants#other" = "View {emoji} {count} Variants {arrow}";
"lng_auction_preview_random" = "Random Traits";
"lng_auction_preview_selected" = "Selected Traits";
"lng_auction_preview_randomize" = "Randomize Traits";
"lng_auction_preview_model" = "model";
"lng_auction_preview_models#one" = "This collectible features **{count}** unique model.";
"lng_auction_preview_models#other" = "This collectible features **{count}** unique models.";
"lng_auction_preview_models_button" = "Models";
"lng_auction_preview_backdrop" = "backdrop";
"lng_auction_preview_backdrops#one" = "This collectible features **{count}** unique backdrop.";
"lng_auction_preview_backdrops#other" = "This collectible features **{count}** unique backdrops.";
"lng_auction_preview_backdrops_button" = "Backdrops";
"lng_auction_preview_symbol" = "symbol";
"lng_auction_preview_symbols#one" = "This collectible features **{count}** unique symbol.";
"lng_auction_preview_symbols#other" = "This collectible features **{count}** unique symbols.";
"lng_auction_preview_symbols_button" = "Symbols";
"lng_auction_preview_wear" = "More about wearing gifts {arrow}";
"lng_auction_preview_free_upgrade" = "You can upgrade your gift for free, sell it on the market, or set it as your profile cover.";
"lng_accounts_limit_title" = "Limit Reached";
"lng_accounts_limit1#one" = "You have reached the limit of **{count}** connected account.";
@@ -4779,6 +4903,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_paid_react_send" = "Send {price}";
"lng_paid_react_agree" = "By sending stars, you agree to the {link}.";
"lng_paid_react_agree_link" = "Terms of Service";
"lng_paid_react_admin_cant" = "You can't send Stars to your own Live Story.";
"lng_paid_react_toast#one" = "Star Sent!";
"lng_paid_react_toast#other" = "Stars Sent!";
"lng_paid_react_toast_anonymous#one" = "Star sent anonymously!";
@@ -4800,6 +4925,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_paid_reaction_title" = "React with Stars";
"lng_paid_reaction_about" = "Highlight and pin your message by sending Stars to {name}.";
"lng_paid_reaction_button" = "Send {stars}";
"lng_paid_admin_title" = "Receive Stars from Viewers";
"lng_paid_admin_about" = "Viewers can send you Star Reactions.";
"lng_sensitive_tag" = "18+";
"lng_sensitive_title" = "18+";
@@ -6293,12 +6420,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_export_option_contacts_about" = "If you allow access, contacts are continuously synced with Telegram. You can adjust this in Settings > Privacy & Security on mobile devices.";
"lng_export_option_stories" = "Story archive";
"lng_export_option_stories_about" = "All stories you posted from Telegram mobile apps.";
"lng_export_option_profile_music" = "Music on Profiles";
"lng_export_option_profile_music_about" = "All tracks you saved to your playlist.";
"lng_export_option_sessions" = "Active sessions";
"lng_export_option_sessions_about" = "We may store this to display your connected devices in Settings > Privacy & Security > Show all sessions.";
"lng_export_header_other" = "Other";
"lng_export_option_other" = "Miscellaneous data";
"lng_export_option_other_about" = "Other types of data not mentioned above (beta).";
"lng_export_header_chats" = "Chat export settings";
"lng_export_header_topic" = "Topic export settings";
"lng_export_option_personal_chats" = "Personal chats";
"lng_export_option_bot_chats" = "Bot chats";
"lng_export_option_private_groups" = "Private groups";
@@ -6793,6 +6923,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stories_my_name" = "My Story";
"lng_stories_archive" = "Hide Stories";
"lng_stories_unarchive" = "Unhide Stories";
"lng_stories_view_anonymously" = "View Anonymously";
"lng_stories_row_count#one" = "{count} Story";
"lng_stories_row_count#other" = "{count} Stories";
"lng_stories_views#one" = "{count} view";
@@ -6887,6 +7018,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stealth_mode_next_about" = "Hide my views for the next 25 minutes.";
"lng_stealth_mode_unlock" = "Unlock Stealth Mode";
"lng_stealth_mode_enable" = "Enable Stealth Mode";
"lng_stealth_mode_enable_and_open" = "Enable and open the story";
"lng_stealth_mode_cooldown_in" = "Available in {left}";
"lng_stealth_mode_cooldown_tip" = "Please wait until **Stealth Mode** is ready to use again.";
"lng_stealth_mode_enabled_tip_title" = "Stealth Mode On";

View File

@@ -50,6 +50,7 @@
<file alias="rtmp.tgs">../../animations/rtmp.tgs</file>
<file alias="show_or_premium_lastseen.tgs">../../animations/show_or_premium_lastseen.tgs</file>
<file alias="show_or_premium_readtime.tgs">../../animations/show_or_premium_readtime.tgs</file>
<file alias="passkeys.tgs">../../animations/passkeys.tgs</file>
<file alias="profile_muting.tgs">../../animations/profile/profile_muting.tgs</file>
<file alias="profile_unmuting.tgs">../../animations/profile/profile_unmuting.tgs</file>

View File

@@ -31,6 +31,8 @@
<file alias="images/section_contacts@2x.png">../../export_html/images/section_contacts@2x.png</file>
<file alias="images/section_frequent.png">../../export_html/images/section_frequent.png</file>
<file alias="images/section_frequent@2x.png">../../export_html/images/section_frequent@2x.png</file>
<file alias="images/section_music.png">../../export_html/images/section_music.png</file>
<file alias="images/section_music@2x.png">../../export_html/images/section_music@2x.png</file>
<file alias="images/section_other.png">../../export_html/images/section_other.png</file>
<file alias="images/section_other@2x.png">../../export_html/images/section_other@2x.png</file>
<file alias="images/section_photos.png">../../export_html/images/section_photos.png</file>

View File

@@ -10,7 +10,7 @@
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
ProcessorArchitecture="ARCHITECTURE"
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
Version="6.3.0.0" />
Version="6.3.8.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,3,0,0
PRODUCTVERSION 6,3,0,0
FILEVERSION 6,3,8,0
PRODUCTVERSION 6,3,8,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.3.0.0"
VALUE "FileVersion", "6.3.8.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2025"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "6.3.0.0"
VALUE "ProductVersion", "6.3.8.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 6,3,0,0
PRODUCTVERSION 6,3,0,0
FILEVERSION 6,3,8,0
PRODUCTVERSION 6,3,8,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.3.0.0"
VALUE "FileVersion", "6.3.8.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2025"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "6.3.0.0"
VALUE "ProductVersion", "6.3.8.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -100,7 +100,7 @@ Authorizations::Authorizations(not_null<ApiWrap*> api)
_unreviewed = api->session().settings().unreviewed();
crl::on_main(&api->session(), [=] { removeExpiredUnreviewed(); });
Core::App().settings().deviceModelChanges(
) | rpl::start_with_next([=](const QString &model) {
) | rpl::on_next([=](const QString &model) {
auto changed = false;
for (auto &entry : _list) {
if (!entry.hash) {

View File

@@ -204,7 +204,7 @@ auto BlockedPeers::slice() -> rpl::producer<BlockedPeers::Slice> {
}
return _slice
? _changes.events_starting_with_copy(*_slice)
: (_changes.events() | rpl::type_erased());
: (_changes.events() | rpl::type_erased);
}
void BlockedPeers::request(int offset, Fn<void(BlockedPeers::Slice)> done) {

View File

@@ -227,7 +227,7 @@ void SendBotCallbackDataWithPassword(
api->cloudPassword().state(
) | rpl::take(
1
) | rpl::start_with_next([=](const Core::CloudPasswordState &state) mutable {
) | rpl::on_next([=](const Core::CloudPasswordState &state) mutable {
if (lifetime) {
base::take(lifetime)->destroy();
}
@@ -400,7 +400,7 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
}
}
const auto replyTo = FullReplyTo();
const auto suggest = SuggestPostOptions();
const auto suggest = SuggestOptions();
Window::PeerMenuCreatePoll(
controller,
item->history()->peer,

View File

@@ -174,13 +174,13 @@ void InitFilterLinkHeader(
box->setAddedTopScrollSkip(max);
std::move(
header.wheelEvents
) | rpl::start_with_next([=](not_null<QWheelEvent*> e) {
) | rpl::on_next([=](not_null<QWheelEvent*> e) {
box->sendScrollViewportEvent(e);
}, widget->lifetime());
std::move(
header.closeRequests
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
box->closeBox();
}, widget->lifetime());
@@ -193,7 +193,7 @@ void InitFilterLinkHeader(
box->scrolls(
) | rpl::filter([=] {
return !state->processing;
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
state->processing = true;
const auto guard = gsl::finally([&] { state->processing = false; });
@@ -470,7 +470,7 @@ void ToggleChatsController::adjust(
void ToggleChatsController::setRealContentHeight(rpl::producer<int> value) {
std::move(
value
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
const auto desired = _desiredHeight.current();
if (height <= computeListSt().item.height) {
return;
@@ -644,7 +644,7 @@ void ProcessFilterInvite(
const auto button = owned.data();
box->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
const auto &padding = st::filterInviteBox.buttonPadding;
button->resizeToWidth(width
- padding.left()
@@ -662,7 +662,7 @@ void ProcessFilterInvite(
const auto state = box->lifetime().make_state<State>();
raw->selectedValue(
) | rpl::start_with_next([=](
) | rpl::on_next([=](
base::flat_set<not_null<PeerData*>> &&peers) {
button->setClickedCallback([=] {
if (peers.empty()) {
@@ -777,7 +777,7 @@ void CheckFilterInvite(
if (notLoaded) {
const auto lifetime = std::make_shared<rpl::lifetime>();
owner.chatsFilters().changed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
lifetime->destroy();
ProcessFilterInvite(
weak,
@@ -873,7 +873,7 @@ void ProcessFilterRemove(
const auto button = owned.data();
box->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
const auto &padding = st::filterInviteBox.buttonPadding;
button->resizeToWidth(width
- padding.left()
@@ -886,7 +886,7 @@ void ProcessFilterRemove(
HandleEnterInBox(box);
raw->selectedValue(
) | rpl::start_with_next([=](
) | rpl::on_next([=](
base::flat_set<not_null<PeerData*>> &&peers) {
button->setClickedCallback([=] {
done(peers | ranges::to_vector);

View File

@@ -159,7 +159,7 @@ void ConfirmSubscriptionBox(
state->frame.setDevicePixelRatio(style::DevicePixelRatio());
const auto options = Images::Option::RoundCircle;
userpic->paintRequest(
) | rpl::start_with_next([=, small = Data::PhotoSize::Small] {
) | rpl::on_next([=, small = Data::PhotoSize::Small] {
state->frame.fill(Qt::transparent);
{
auto p = QPainter(&state->frame);
@@ -194,7 +194,7 @@ void ConfirmSubscriptionBox(
state->photoMedia->wanted(Data::PhotoSize::Small, Data::FileOrigin());
if (!state->photoMedia->image(Data::PhotoSize::Small)) {
session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
userpic->update();
}, userpic->lifetime());
}
@@ -260,7 +260,7 @@ void ConfirmSubscriptionBox(
rpl::combine(
balance->sizeValue(),
content->sizeValue()
) | rpl::start_with_next([=](const QSize &, const QSize &) {
) | rpl::on_next([=](const QSize &, const QSize &) {
balance->moveToRight(
st::creditsHistoryRightSkip * 2,
st::creditsHistoryRightSkip);
@@ -408,7 +408,7 @@ void CheckChatInvite(
box->boxClosing(
) | rpl::filter([=] {
return !invitePeekChannel->amIn();
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
if (const auto strong = weak.get()) {
strong->clearSectionStack(Window::SectionShow(
Window::SectionShow::Way::ClearStack,
@@ -527,7 +527,7 @@ ConfirmInviteBox::ConfirmInviteBox(
_photo->wanted(Data::PhotoSize::Small, Data::FileOrigin());
if (!_photo->image(Data::PhotoSize::Small)) {
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
update();
}, lifetime());
}

View File

@@ -68,7 +68,7 @@ void CloudPassword::clearUnconfirmedPassword() {
rpl::producer<Core::CloudPasswordState> CloudPassword::state() const {
return _state
? _stateChanges.events_starting_with_copy(*_state)
: (_stateChanges.events() | rpl::type_erased());
: (_stateChanges.events() | rpl::type_erased);
}
auto CloudPassword::stateCurrent() const

View File

@@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Api {
MTPSuggestedPost SuggestToMTP(SuggestPostOptions suggest) {
MTPSuggestedPost SuggestToMTP(SuggestOptions suggest) {
using Flag = MTPDsuggestedPost::Flag;
return suggest.exists
? MTP_suggestedPost(

View File

@@ -19,7 +19,7 @@ namespace Api {
inline constexpr auto kScheduledUntilOnlineTimestamp = TimeId(0x7FFFFFFE);
[[nodiscard]] MTPSuggestedPost SuggestToMTP(SuggestPostOptions suggest);
[[nodiscard]] MTPSuggestedPost SuggestToMTP(SuggestOptions suggest);
struct SendOptions {
uint64 price = 0;
@@ -34,7 +34,7 @@ struct SendOptions {
bool invertCaption = false;
bool hideViaBot = false;
crl::time ttlSeconds = 0;
SuggestPostOptions suggest;
SuggestOptions suggest;
friend inline bool operator==(
const SendOptions &,

View File

@@ -95,7 +95,7 @@ void ConfirmPhone::resolve(
codeHandles->fire_copy(code);
});
box->resendRequests(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_api.request(MTPauth_ResendCode(
MTP_flags(0),
MTP_string(phone),
@@ -110,7 +110,7 @@ void ConfirmPhone::resolve(
rpl::merge(
codeHandles->events(),
box->checkRequests()
) | rpl::start_with_next([=](const QString &code) {
) | rpl::on_next([=](const QString &code) {
if (_checkRequestId) {
return;
}
@@ -142,7 +142,7 @@ void ConfirmPhone::resolve(
}).handleFloodErrors().send();
}, box->lifetime());
box->boxClosing(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
controller->session().account().setHandleLoginCode(nullptr);
}, box->lifetime());

View File

@@ -146,6 +146,8 @@ Data::CreditsHistoryEntry CreditsHistoryEntryFromTL(
? starrefAmount
: CreditsAmount()),
.paidMessagesCommission = paidMessagesCount ? starrefCommission : 0,
.limitedCount = parsedGift ? parsedGift->limitedCount : 0,
.limitedLeft = parsedGift ? parsedGift->limitedLeft : 0,
.starsConverted = int(nonUniqueGift
? nonUniqueGift->vconvert_stars().v
: 0),

View File

@@ -69,7 +69,7 @@ void HandleWithdrawalButton(
state->lifetime = session->api().cloudPassword().state(
) | rpl::take(
1
) | rpl::start_with_next([=](const Core::CloudPasswordState &pass) {
) | rpl::on_next([=](const Core::CloudPasswordState &pass) {
state->loading = false;
auto fields = PasscodeBox::CloudFields::From(pass);

View File

@@ -68,7 +68,7 @@ void GlobalPrivacy::reload(Fn<void()> callback) {
}).send();
_session->appConfig().value(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_showArchiveAndMute = _session->appConfig().get<bool>(
u"autoarchive_setting_available"_q,
false);

View File

@@ -36,7 +36,7 @@ MessagesSearchMerged::MessagesSearchMerged(not_null<History*> history)
};
_apiSearch.messagesFounds(
) | rpl::start_with_next([=](const FoundMessages &data) {
) | rpl::on_next([=](const FoundMessages &data) {
if (data.nextToken == _concatedFound.nextToken) {
addFound(data);
checkFull(data);
@@ -50,7 +50,7 @@ MessagesSearchMerged::MessagesSearchMerged(not_null<History*> history)
if (_migratedSearch) {
_migratedSearch->messagesFounds(
) | rpl::start_with_next([=](const FoundMessages &data) {
) | rpl::on_next([=](const FoundMessages &data) {
if (_isFull) {
addFound(data);
}

View File

@@ -153,7 +153,7 @@ PeerPhoto::PeerPhoto(not_null<ApiWrap*> api)
// You can't use _session->lifetime() in the constructor,
// only queued, because it is not constructed yet.
_session->uploader().photoReady(
) | rpl::start_with_next([=](const Storage::UploadedMedia &data) {
) | rpl::on_next([=](const Storage::UploadedMedia &data) {
ready(data.fullId, data.info.file, std::nullopt);
}, _session->lifetime());
});

View File

@@ -95,7 +95,7 @@ Premium::Premium(not_null<ApiWrap*> api)
// only queued, because it is not constructed yet.
Data::AmPremiumValue(
_session
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
reload();
if (_session->premium()) {
reloadCloudSet();
@@ -848,8 +848,22 @@ std::optional<Data::StarGift> FromTL(
const auto releasedBy = releasedById
? session->data().peer(releasedById).get()
: nullptr;
const auto background = [&] {
if (!data.vbackground()) {
return std::shared_ptr<Data::StarGiftBackground>();
}
const auto &fields = data.vbackground()->data();
using namespace Ui;
return std::make_shared<Data::StarGiftBackground>(
Data::StarGiftBackground{
.center = ColorFromSerialized(fields.vcenter_color()),
.edge = ColorFromSerialized(fields.vedge_color()),
.text = ColorFromSerialized(fields.vtext_color()),
});
};
return std::optional<Data::StarGift>(Data::StarGift{
.id = uint64(data.vid().v),
.background = background(),
.stars = int64(data.vstars().v),
.starsConverted = int64(data.vconvert_stars().v),
.starsToUpgrade = int64(data.vupgrade_stars().value_or_empty()),
@@ -860,10 +874,12 @@ std::optional<Data::StarGift> FromTL(
.resellCount = int(data.vavailability_resale().value_or_empty()),
.auctionSlug = qs(data.vauction_slug().value_or_empty()),
.auctionGiftsPerRound = data.vgifts_per_round().value_or_empty(),
.auctionStartDate = data.vauction_start_date().value_or_empty(),
.limitedLeft = remaining.value_or_empty(),
.limitedCount = total.value_or_empty(),
.perUserTotal = data.vper_user_total().value_or_empty(),
.perUserRemains = data.vper_user_remains().value_or_empty(),
.upgradeVariants = data.vupgrade_variants().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(),
@@ -930,6 +946,7 @@ std::optional<Data::StarGift> FromTL(
.themeUser = themeUser,
.nanoTonForResale = FindTonForResale(data.vresell_amount()),
.starsForResale = FindStarsForResale(data.vresell_amount()),
.starsMinOffer = data.voffer_min_stars().value_or(-1),
.number = data.vnum().v,
.onlyAcceptTon = data.is_resale_ton_only(),
.canBeTheme = data.is_theme_available(),
@@ -942,6 +959,8 @@ std::optional<Data::StarGift> FromTL(
data.vvalue_currency().value_or_empty()),
.valuePrice = int64(
data.vvalue_amount().value_or_empty()),
.valuePriceUsd = int64(
data.vvalue_usd_amount().value_or_empty()),
})
: nullptr),
.peerColor = colorCollectible,
@@ -963,7 +982,7 @@ std::optional<Data::StarGift> FromTL(
unique->originalDetails = FromTL(session, data);
});
}
return std::make_optional(result);
return std::make_optional(std::move(result));
});
}
@@ -1009,6 +1028,7 @@ std::optional<Data::SavedStarGift> FromTL(
? peerFromMTP(*data.vfrom_id())
: PeerId()),
.date = data.vdate().v,
.giftNum = data.vgift_num().value_or_empty(),
.upgradeSeparate = data.is_upgrade_separate(),
.upgradable = data.is_can_upgrade(),
.anonymous = data.is_name_hidden(),

View File

@@ -66,7 +66,7 @@ Ringtones::Ringtones(not_null<ApiWrap*> api)
// You can't use _session->lifetime() in the constructor,
// only queued, because it is not constructed yet.
_session->uploader().documentReady(
) | rpl::start_with_next([=](const Storage::UploadedMedia &data) {
) | rpl::on_next([=](const Storage::UploadedMedia &data) {
ready(data.fullId, data.info.file);
}, _session->lifetime());
});

View File

@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "base/unixtime.h"
#include "boxes/transfer_gift_box.h"
#include "chat_helpers/message_field.h"
#include "core/click_handler_types.h"
#include "data/components/credits.h"
@@ -44,7 +45,7 @@ void SendApproval(
not_null<HistoryItem*> item,
TimeId scheduleDate = 0) {
using Flag = MTPmessages_ToggleSuggestedPostApproval::Flag;
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (!suggestion
|| suggestion->accepted
|| suggestion->rejected
@@ -56,7 +57,7 @@ void SendApproval(
const auto session = &show->session();
const auto finish = [=] {
if (const auto item = session->data().message(id)) {
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (suggestion) {
suggestion->requestId = 0;
}
@@ -83,7 +84,7 @@ void ConfirmApproval(
not_null<HistoryItem*> item,
TimeId scheduleDate = 0,
Fn<void()> accepted = nullptr) {
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (!suggestion
|| suggestion->accepted
|| suggestion->rejected
@@ -244,7 +245,7 @@ void SendDecline(
not_null<HistoryItem*> item,
const QString &comment) {
using Flag = MTPmessages_ToggleSuggestedPostApproval::Flag;
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (!suggestion
|| suggestion->accepted
|| suggestion->rejected
@@ -256,7 +257,7 @@ void SendDecline(
const auto session = &show->session();
const auto finish = [=] {
if (const auto item = session->data().message(id)) {
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (suggestion) {
suggestion->requestId = 0;
}
@@ -350,7 +351,7 @@ void RequestDeclineComment(
}
};
reason->submits(
) | rpl::start_with_next([=](Qt::KeyboardModifiers modifiers) {
) | rpl::on_next([=](Qt::KeyboardModifiers modifiers) {
if (!(modifiers & Qt::ShiftModifier)) {
(*callback)();
}
@@ -365,10 +366,10 @@ void SendSuggest(
std::shared_ptr<Main::SessionShow> show,
not_null<HistoryItem*> item,
std::shared_ptr<SendSuggestState> state,
Fn<void(SuggestPostOptions&)> modify,
Fn<void(SuggestOptions&)> modify,
Fn<void()> done = nullptr,
int starsApproved = 0) {
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
const auto suggestion = item->Get<HistoryMessageSuggestion>();
const auto id = item->fullId();
const auto withPaymentApproved = [=](int stars) {
if (const auto item = show->session().data().message(id)) {
@@ -416,7 +417,7 @@ void SendSuggest(
void SuggestApprovalDate(
std::shared_ptr<Main::SessionShow> show,
not_null<HistoryItem*> item) {
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (!suggestion) {
return;
}
@@ -437,7 +438,7 @@ void SuggestApprovalDate(
show,
item,
state,
[=](SuggestPostOptions &options) { options.date = result; },
[=](SuggestOptions &options) { options.date = result; },
close);
};
using namespace HistoryView;
@@ -454,12 +455,12 @@ void SuggestApprovalDate(
void SuggestOfferForMessage(
std::shared_ptr<Main::SessionShow> show,
not_null<HistoryItem*> item,
SuggestPostOptions values,
SuggestOptions values,
HistoryView::SuggestMode mode) {
const auto id = item->fullId();
const auto state = std::make_shared<SendSuggestState>();
const auto weak = std::make_shared<base::weak_qptr<Ui::BoxContent>>();
const auto done = [=](SuggestPostOptions result) {
const auto done = [=](SuggestOptions result) {
const auto item = show->session().data().message(id);
if (!item) {
return;
@@ -473,7 +474,7 @@ void SuggestOfferForMessage(
show,
item,
state,
[=](SuggestPostOptions &options) { options = result; },
[=](SuggestOptions &options) { options = result; },
close);
};
using namespace HistoryView;
@@ -490,7 +491,7 @@ void SuggestOfferForMessage(
void SuggestApprovalPrice(
std::shared_ptr<Main::SessionShow> show,
not_null<HistoryItem*> item) {
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (!suggestion) {
return;
}
@@ -504,6 +505,20 @@ void SuggestApprovalPrice(
}, SuggestMode::Change);
}
void ConfirmGiftSaleAccept(
not_null<Window::SessionController*> window,
not_null<HistoryItem*> item,
not_null<HistoryMessageSuggestion*> suggestion) {
ShowGiftSaleAcceptBox(window, item, suggestion);
}
void ConfirmGiftSaleDecline(
not_null<Window::SessionController*> window,
not_null<HistoryItem*> item,
not_null<HistoryMessageSuggestion*> suggestion) {
ShowGiftSaleRejectBox(window, item, suggestion);
}
} // namespace
std::shared_ptr<ClickHandler> AcceptClickHandler(
@@ -521,9 +536,11 @@ std::shared_ptr<ClickHandler> AcceptClickHandler(
return;
}
const auto show = controller->uiShow();
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (!suggestion) {
return;
} else if (suggestion->gift) {
ConfirmGiftSaleAccept(controller, item, suggestion);
} else if (!suggestion->date) {
RequestApprovalDate(show, item);
} else {
@@ -546,7 +563,12 @@ std::shared_ptr<ClickHandler> DeclineClickHandler(
if (!item) {
return;
}
RequestDeclineComment(controller->uiShow(), item);
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (suggestion && suggestion->gift) {
ConfirmGiftSaleDecline(controller, item, suggestion);
} else {
RequestDeclineComment(controller->uiShow(), item);
}
});
}
@@ -573,7 +595,7 @@ std::shared_ptr<ClickHandler> SuggestChangesClickHandler(
if (!item) {
return;
}
const auto suggestion = item->Get<HistoryMessageSuggestedPost>();
const auto suggestion = item->Get<HistoryMessageSuggestion>();
if (!suggestion) {
return;
}
@@ -594,7 +616,7 @@ std::shared_ptr<ClickHandler> SuggestChangesClickHandler(
.messageId = FullMsgId(history->peer->id, item->id),
.monoforumPeerId = monoforumPeerId,
},
SuggestPostOptions{
SuggestOptions{
.exists = uint32(1),
.priceWhole = uint32(suggestion->price.whole()),
.priceNano = uint32(suggestion->price.nano()),

View File

@@ -24,7 +24,7 @@ void ToggleExistingMedia(
Data::FileOrigin origin,
ToggleRequestCallback toggleRequest,
DoneCallback &&done) {
const auto api = &document->owner().session().api();
const auto api = &document->session().api();
auto performRequest = [=](const auto &repeatRequest) -> void {
const auto usedFileReference = document->fileReference();

View File

@@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/notify/data_notify_settings.h"
#include "data/stickers/data_stickers.h"
#include "data/data_saved_messages.h"
#include "data/data_saved_sublist.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "data/data_chat.h"
@@ -43,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_histories.h"
#include "data/data_folder.h"
#include "data/data_forum.h"
#include "data/data_forum_topic.h"
#include "data/data_send_action.h"
#include "data/data_stories.h"
#include "data/data_message_reactions.h"
@@ -244,12 +246,12 @@ Updates::Updates(not_null<Main::Session*> session)
_ptsWaiter.setRequesting(true);
session->account().mtpUpdates(
) | rpl::start_with_next([=](const MTPUpdates &updates) {
) | rpl::on_next([=](const MTPUpdates &updates) {
mtpUpdateReceived(updates);
}, _lifetime);
session->account().mtpNewSessionCreated(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
mtpNewSessionCreated();
}, _lifetime);
@@ -263,7 +265,7 @@ Updates::Updates(not_null<Main::Session*> session)
Data::PeerUpdate::Flag::FullInfo
) | rpl::filter([](const Data::PeerUpdate &update) {
return update.peer->isChat() || update.peer->isMegagroup();
}) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
}) | rpl::on_next([=](const Data::PeerUpdate &update) {
const auto peer = update.peer;
if (const auto list = _pendingSpeakingCallParticipants.take(peer)) {
if (const auto call = peer->groupCall()) {
@@ -764,7 +766,7 @@ void Updates::addActiveChat(rpl::producer<PeerData*> chat) {
const auto key = _activeChats.empty() ? 0 : _activeChats.back().first + 1;
std::move(
chat
) | rpl::start_with_next_done([=](PeerData *peer) {
) | rpl::on_next_done([=](PeerData *peer) {
auto &active = _activeChats[key];
const auto was = active.peer;
if (was != peer) {
@@ -1701,7 +1703,13 @@ void Updates::feedUpdate(const MTPUpdate &update) {
local->history()->peer,
local->date());
}
local->setRealId(d.vid().v);
local->setRealId(newId);
if (const auto topic = local->topic()) {
topic->applyMaybeLast(local);
}
if (const auto sublist = local->savedSublist()) {
sublist->applyMaybeLast(local);
}
}
}
} else {

View File

@@ -251,7 +251,7 @@ void Usernames::requestToCache(not_null<PeerData*> peer) {
const auto lifetime = std::make_shared<rpl::lifetime>();
*lifetime = loadUsernames(
peer
) | rpl::start_with_next([=, id = peer->id](Data::Usernames usernames) {
) | rpl::on_next([=, id = peer->id](Data::Usernames usernames) {
_tinyCache = std::make_pair(id, std::move(usernames));
lifetime->destroy();
});

View File

@@ -174,7 +174,7 @@ struct State {
}
session->changes().messageUpdates(
Data::MessageUpdate::Flag::Destroyed
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
) | rpl::on_next([=](const Data::MessageUpdate &update) {
const auto i = context->cachedRead.find(update.item);
if (i != end(context->cachedRead)) {
session->api().request(i->second.requestId).cancel();
@@ -192,7 +192,7 @@ struct State {
session
) | rpl::skip(1) | rpl::filter(
rpl::mappers::_1
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
for (auto &[item, cache] : context->cachedRead) {
if (cache.data.current().state == Ui::WhoReadState::MyHidden) {
cache.data = Peers{ .state = Ui::WhoReadState::Unknown };
@@ -202,7 +202,7 @@ struct State {
session->api().globalPrivacy().hideReadTime(
) | rpl::skip(1) | rpl::filter(
!rpl::mappers::_1
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
for (auto &[item, cache] : context->cachedRead) {
if (cache.data.current().state == Ui::WhoReadState::MyHidden) {
cache.data = Peers{ .state = Ui::WhoReadState::Unknown };
@@ -590,7 +590,7 @@ rpl::producer<Ui::WhoReadContent> WhoReacted(
}
std::move(
idsWithReactions
) | rpl::start_with_next([=](PeersWithReactions &&peers) {
) | rpl::on_next([=](PeersWithReactions &&peers) {
if (peers.state == WhoReadState::Unknown) {
state->userpics.clear();
consumer.put_next(Ui::WhoReadContent{
@@ -624,7 +624,7 @@ rpl::producer<Ui::WhoReadContent> WhoReacted(
item->history()->session().downloaderTaskFinished(
) | rpl::filter([=] {
return state->someUserpicsNotLoaded && !state->scheduled;
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
for (const auto &userpic : state->userpics) {
if (userpic.peer->userpicUniqueKey(userpic.view)
!= userpic.uniqueKey) {

View File

@@ -199,7 +199,7 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
_session->data().chatsFilters().changed(
) | rpl::filter([=] {
return _session->data().chatsFilters().archiveNeeded();
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
requestMoreDialogsIfNeeded();
}, _session->lifetime());
@@ -248,7 +248,7 @@ void ApiWrap::setupSupportMode() {
}
_session->settings().supportChatsTimeSliceValue(
) | rpl::start_with_next([=](int seconds) {
) | rpl::on_next([=](int seconds) {
_dialogsLoadTill = seconds ? std::max(base::unixtime::now() - seconds, 0) : 0;
refreshDialogsLoadBlocked();
}, _session->lifetime());
@@ -1902,7 +1902,7 @@ void ApiWrap::updateNotifySettingsDelayed(
}
if (_updateNotifyTopics.emplace(topic).second) {
topic->destroyed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_updateNotifyTopics.remove(topic);
}, _updateNotifyQueueLifetime);
_updateNotifyTimer.callOnce(kNotifySettingSaveTimeout);
@@ -3483,6 +3483,9 @@ void ApiWrap::forwardMessages(
flags |= MessageFlag::ShortcutMessage;
sendFlags |= SendFlag::f_quick_reply_shortcut;
}
if (action.options.effectId) {
sendFlags |= SendFlag::f_effect;
}
if (draft.options != Data::ForwardOptions::PreserveInfo) {
sendFlags |= SendFlag::f_drop_author;
}
@@ -3548,6 +3551,7 @@ void ApiWrap::forwardMessages(
MTP_int(action.options.scheduleRepeatPeriod),
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
Data::ShortcutIdToMTP(_session, action.options.shortcutId),
MTP_long(action.options.effectId),
MTPint(), // video_timestamp
MTP_long(starsPaid),
Api::SuggestToMTP(action.options.suggest)
@@ -4772,7 +4776,7 @@ rpl::producer<bool> ApiWrap::contactSignupSilent() const {
return _contactSignupSilent
? _contactSignupSilentChanges.events_starting_with_copy(
*_contactSignupSilent)
: (_contactSignupSilentChanges.events() | rpl::type_erased());
: (_contactSignupSilentChanges.events() | rpl::type_erased);
}
std::optional<bool> ApiWrap::contactSignupSilentCurrent() const {

View File

@@ -186,7 +186,7 @@ void ArchiveHintBox(
owned->setNaturalWidth(rect.width());
const auto widget = box->addRow(std::move(owned), style::al_top);
widget->paintRequest(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
auto p = Painter(widget);
auto hq = PainterHighQualityEnabler(p);
p.setPen(Qt::NoPen);
@@ -263,13 +263,13 @@ void ArchiveHintBox(
const auto left = Ui::CreateChild<Ui::RpWidget>(
box->verticalLayout().get());
left->paintRequest(
) | rpl::start_with_next([=] {
) | rpl::on_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) {
) | rpl::on_next([=](const QRect &g) {
left->moveToLeft(
(g.left() - left->width()) / 2,
g.top() + st::channelEarnHistoryThreeSkip);

View File

@@ -42,7 +42,7 @@ void AboutSponsoredBox(not_null<Ui::GenericBox*> box) {
rpl::combine(
row->sizeValue(),
button->sizeValue()
) | rpl::start_with_next([=](
) | rpl::on_next([=](
const QSize &rowSize,
const QSize &buttonSize) {
button->moveToLeft(

View File

@@ -324,9 +324,9 @@ void AddContactBox::prepare() {
const auto submitted = [=] { submit(); };
_first->submits(
) | rpl::start_with_next(submitted, _first->lifetime());
) | rpl::on_next(submitted, _first->lifetime());
_last->submits(
) | rpl::start_with_next(submitted, _last->lifetime());
) | rpl::on_next(submitted, _last->lifetime());
connect(_phone, &Ui::PhoneInput::submitted, [=] { submit(); });
setDimensions(
@@ -598,13 +598,13 @@ void GroupInfoBox::prepare() {
Core::App().settings().sendSubmitWay());
_description->heightChanges(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
descriptionResized();
}, _description->lifetime());
_description->submits(
) | rpl::start_with_next([=] { submit(); }, _description->lifetime());
) | rpl::on_next([=] { submit(); }, _description->lifetime());
_description->cancelled(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
closeBox();
}, _description->lifetime());
@@ -614,7 +614,7 @@ void GroupInfoBox::prepare() {
&_navigation->session());
}
_title->submits(
) | rpl::start_with_next([=] { submitName(); }, _title->lifetime());
) | rpl::on_next([=] { submitName(); }, _title->lifetime());
addButton(
((_type != Type::Group || _canAddBot)
@@ -920,7 +920,7 @@ void GroupInfoBox::checkInviteLink() {
_createdChannel->session().changes().peerUpdates(
_createdChannel,
Data::PeerUpdate::Flag::FullInfo
) | rpl::take(1) | rpl::start_with_next([=] {
) | rpl::take(1) | rpl::on_next([=] {
checkInviteLink();
}, lifetime());
}
@@ -1063,11 +1063,11 @@ void SetupChannelBox::prepare() {
_channel->session().changes().peerUpdates(
_channel,
Data::PeerUpdate::Flag::InviteLinks
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
rtlupdate(_invitationLink);
}, lifetime());
boxClosing() | rpl::start_with_next([=] {
boxClosing() | rpl::on_next([=] {
if (!_mustBePublic) {
AddParticipantsBoxController::Start(_navigation, _channel);
}
@@ -1495,7 +1495,7 @@ void SetupChannelBox::showRevokePublicLinkBoxForEdit() {
Box(PublicLinksLimitBox, navigation, callback));
const auto session = &navigation->session();
revoker->boxClosing(
) | rpl::start_with_next(crl::guard(session, [=] {
) | rpl::on_next(crl::guard(session, [=] {
base::call_delayed(200, session, [=] {
if (*revoked) {
return;
@@ -1563,19 +1563,19 @@ void EditNameBox::prepare() {
_last->setMaxLength(Ui::EditPeer::kMaxUserFirstLastName);
_first->submits(
) | rpl::start_with_next([=] { submit(); }, _first->lifetime());
) | rpl::on_next([=] { submit(); }, _first->lifetime());
_last->submits(
) | rpl::start_with_next([=] { submit(); }, _last->lifetime());
) | rpl::on_next([=] { submit(); }, _last->lifetime());
_first->customTab(true);
_last->customTab(true);
_first->tabbed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_last->setFocus();
}, _first->lifetime());
_last->tabbed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_first->setFocus();
}, _last->lifetime());
}

View File

@@ -116,7 +116,7 @@ void AutoDownloadBox::setupContent() {
))->toggleOn(
rpl::single(value > 0)
)->toggledChanges(
) | rpl::start_with_next([=](bool enabled) {
) | rpl::on_next([=](bool enabled) {
(*values)[type] = enabled ? 1 : 0;
}, content->lifetime());
values->emplace(type, value);

View File

@@ -102,7 +102,7 @@ void AutoLockBox::prepare() {
};
timeInput->focuses(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
group->setValue(kCustom);
}, lifetime());
@@ -119,7 +119,7 @@ void AutoLockBox::prepare() {
[=] { return group->current() == kCustom; }
),
timeInput->submitRequests()
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
if (const auto result = collect()) {
durationChanged(result);
} else {

View File

@@ -211,12 +211,12 @@ void BackgroundBox::prepare() {
setInnerTopSkip(st::lineWidth);
_inner->chooseEvents(
) | rpl::start_with_next([=](const Data::WallPaper &paper) {
) | rpl::on_next([=](const Data::WallPaper &paper) {
chosen(paper);
}, _inner->lifetime());
_inner->removeRequests(
) | rpl::start_with_next([=](const Data::WallPaper &paper) {
) | rpl::on_next([=](const Data::WallPaper &paper) {
removePaper(paper);
}, _inner->lifetime());
}
@@ -396,30 +396,30 @@ BackgroundBox::Inner::Inner(
+ st::backgroundPadding));
Window::Theme::IsNightModeValue(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
updatePapers();
}, lifetime());
requestPapers();
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
update();
}, lifetime());
style::PaletteChanged(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_check->invalidateCache();
}, lifetime());
if (forChannel()) {
_session->data().cloudThemes().chatThemesUpdated(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
updatePapers();
}, lifetime());
} else {
using Update = Window::Theme::BackgroundUpdate;
Window::Theme::Background()->updates(
) | rpl::start_with_next([=](const Update &update) {
) | rpl::on_next([=](const Update &update) {
if (update.type == Update::Type::New) {
sortPapers();
requestPapers();

View File

@@ -225,18 +225,18 @@ BackgroundPreviewBox::BackgroundPreviewBox(
}
generateBackground();
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
update();
}, lifetime());
_appNightMode.changes(
) | rpl::start_with_next([=](bool night) {
) | rpl::on_next([=](bool night) {
_boxDarkMode = night;
update();
}, lifetime());
_boxDarkMode.changes(
) | rpl::start_with_next([=](bool dark) {
) | rpl::on_next([=](bool dark) {
applyDarkMode(dark);
}, lifetime());
@@ -373,7 +373,7 @@ void BackgroundPreviewBox::createDimmingSlider(bool dark) {
_dimmingContent->resize(inner->size());
_dimmingContent->paintRequest(
) | rpl::start_with_next([=](QRect clip) {
) | rpl::on_next([=](QRect clip) {
auto p = QPainter(_dimmingContent);
const auto palette = (dark ? _darkPalette : _lightPalette).get();
p.fillRect(clip, equals ? st::boxBg : palette->boxBg());
@@ -386,13 +386,13 @@ void BackgroundPreviewBox::createDimmingSlider(bool dark) {
heightValue(),
_dimmingWrap->heightValue(),
rpl::mappers::_1 - rpl::mappers::_2
) | rpl::start_with_next([=](int top) {
) | rpl::on_next([=](int top) {
_dimmingWrap->move(0, top);
}, _dimmingWrap->lifetime());
_dimmingWrap->toggle(dark, anim::type::instant);
_dimmingHeight = _dimmingWrap->heightValue();
_dimmingHeight.changes() | rpl::start_with_next([=] {
_dimmingHeight.changes() | rpl::on_next([=] {
update();
}, _dimmingWrap->lifetime());
}
@@ -554,7 +554,7 @@ void BackgroundPreviewBox::recreateBlurCheckbox() {
sizeValue(),
_blur->sizeValue(),
_dimmingHeight.value()
) | rpl::start_with_next([=](QSize outer, QSize inner, int dimming) {
) | rpl::on_next([=](QSize outer, QSize inner, int dimming) {
const auto bottom = st::historyPaddingBottom;
_blur->move(
(outer.width() - inner.width()) / 2,
@@ -562,7 +562,7 @@ void BackgroundPreviewBox::recreateBlurCheckbox() {
}, _blur->lifetime());
_blur->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
) | rpl::on_next([=](bool checked) {
checkBlurAnimationStart();
update();
}, _blur->lifetime());
@@ -607,7 +607,7 @@ void BackgroundPreviewBox::uploadForPeer(bool both) {
document->size);
session->uploader().documentProgress(
) | rpl::start_with_next([=](const FullMsgId &fullId) {
) | rpl::on_next([=](const FullMsgId &fullId) {
if (fullId != _uploadId) {
return;
}
@@ -619,7 +619,7 @@ void BackgroundPreviewBox::uploadForPeer(bool both) {
}, _uploadLifetime);
session->uploader().documentReady(
) | rpl::start_with_next([=](const Storage::UploadedMedia &data) {
) | rpl::on_next([=](const Storage::UploadedMedia &data) {
if (data.fullId != _uploadId) {
return;
}
@@ -742,13 +742,13 @@ void BackgroundPreviewBox::applyForPeer() {
object_ptr<Ui::RpWidget>(this));
const auto overlay = _forBothOverlay->entity();
sizeValue() | rpl::start_with_next([=](QSize size) {
sizeValue() | rpl::on_next([=](QSize size) {
_forBothOverlay->setGeometry({ QPoint(), size });
overlay->setGeometry({ QPoint(), size });
}, _forBothOverlay->lifetime());
overlay->paintRequest(
) | rpl::start_with_next([=](QRect clip) {
) | rpl::on_next([=](QRect clip) {
auto p = QPainter(overlay);
p.drawImage(0, 0, bg);
p.fillRect(clip, QColor(0, 0, 0, 64));
@@ -787,7 +787,7 @@ void BackgroundPreviewBox::applyForPeer() {
const auto raw = _forBothOverlay.release();
raw->shownValue() | rpl::filter(
!rpl::mappers::_1
) | rpl::take(1) | rpl::start_with_next(crl::guard(raw, [=] {
) | rpl::take(1) | rpl::on_next(crl::guard(raw, [=] {
delete raw;
}), raw->lifetime());
raw->toggle(false, anim::type::normal);
@@ -797,7 +797,7 @@ void BackgroundPreviewBox::applyForPeer() {
cancel->setTextTransform(RoundButton::TextTransform::NoTransform);
overlay->sizeValue(
) | rpl::start_with_next([=](QSize size) {
) | rpl::on_next([=](QSize size) {
const auto padding = st::backgroundConfirmPadding;
const auto width = size.width()
- padding.left()
@@ -1063,7 +1063,7 @@ void BackgroundPreviewBox::updateServiceBg(const std::vector<QColor> &bg) {
}
_serviceBgLifetime = _paletteServiceBg.value(
) | rpl::start_with_next([=](QColor color) {
) | rpl::on_next([=](QColor color) {
_serviceBg = Ui::ThemeAdjustedColor(
color,
QColor(red / count, green / count, blue / count));

View File

@@ -378,10 +378,8 @@ connectionPortInputField: InputField(defaultInputField) {
width: 55px;
}
connectionUserInputField: InputField(defaultInputField) {
width: 95px;
}
connectionPasswordInputField: InputField(defaultInputField) {
width: 120px;
}
connectionIPv6Skip: 11px;

View File

@@ -99,7 +99,8 @@ protected:
p.drawImage(
width()
- size.width()
- st::menuWithIcons.itemPadding.right(),
- st::menuWithIcons.itemPadding.right()
- st::popupMenuWithIcons.shadow.extend.right(),
(height() - size.height()) / 2,
_icon);
}
@@ -344,7 +345,7 @@ void FillChooseFilterMenu(
}
history->owner().chatsFilters().changed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
menu->hideMenu();
}, menu->lifetime());
}

View File

@@ -115,6 +115,7 @@ void AddProxyFromClipboard(
Success,
Failed,
Unsupported,
IncorrectSecret,
Invalid,
};
@@ -154,8 +155,11 @@ void AddProxyFromClipboard(
qthelp::UrlParamNameTransform::ToLower);
const auto proxy = ProxyDataFromFields(type, fields);
if (!proxy) {
return (proxy.status() == ProxyData::Status::Unsupported)
const auto status = proxy.status();
return (status == ProxyData::Status::Unsupported)
? Result::Unsupported
: (status == ProxyData::Status::IncorrectSecret)
? Result::IncorrectSecret
: Result::Invalid;
}
const auto contains = controller->contains(proxy);
@@ -189,9 +193,11 @@ void AddProxyFromClipboard(
tr::lng_proxy_add_from_clipboard_failed_toast(tr::now));
} else {
show->showBox(Ui::MakeInformBox(
(success == Result::Unsupported
? tr::lng_proxy_unsupported(tr::now)
: tr::lng_proxy_invalid(tr::now))));
((success == Result::IncorrectSecret)
? tr::lng_proxy_incorrect_secret(tr::now, tr::rich)
: (success == Result::Unsupported)
? tr::lng_proxy_unsupported(tr::now, tr::rich)
: tr::lng_proxy_invalid(tr::now, tr::rich))));
}
}
}
@@ -748,7 +754,7 @@ ProxiesBox::ProxiesBox(
, _settings(settings)
, _initialWrap(this) {
_controller->views(
) | rpl::start_with_next([=](View &&view) {
) | rpl::on_next([=](View &&view) {
applyView(std::move(view));
}, lifetime());
}
@@ -790,12 +796,14 @@ void ProxiesBox::setupTopButton() {
.handler = [=] { AddProxyFromClipboard(_controller, uiShow()); },
.icon = &st::menuIconImportTheme,
});
addAction({
.text = tr::lng_group_invite_context_delete_all(tr::now),
.handler = [=] { _controller->deleteItems(); },
.icon = &st::menuIconDeleteAttention,
.isAttention = true,
});
if (!_rows.empty()) {
addAction({
.text = tr::lng_group_invite_context_delete_all(tr::now),
.handler = [=] { _controller->deleteItems(); },
.icon = &st::menuIconDeleteAttention,
.isAttention = true,
});
}
(*menu)->popup(QCursor::pos());
return true;
});
@@ -875,17 +883,17 @@ void ProxiesBox::setupContent() {
refreshProxyForCalls();
});
_tryIPv6->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
) | rpl::on_next([=](bool checked) {
_controller->setTryIPv6(checked);
}, _tryIPv6->lifetime());
_controller->proxySettingsValue(
) | rpl::start_with_next([=](ProxyData::Settings value) {
) | rpl::on_next([=](ProxyData::Settings value) {
_proxySettings->setValue(value);
}, inner->lifetime());
_proxyForCalls->entity()->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
) | rpl::on_next([=](bool checked) {
_controller->setProxyForCalls(checked);
}, _proxyForCalls->lifetime());
@@ -922,7 +930,7 @@ void ProxiesBox::setupContent() {
+ 3 * rowHeight()),
st::boxMaxListHeight);
}) | rpl::distinct_until_changed(
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
setDimensions(st::boxWideWidth, height);
}, inner->lifetime());
}
@@ -997,7 +1005,7 @@ void ProxiesBox::createNoRowsLabel() {
tr::lng_proxy_description(tr::now),
st::proxyEmptyListLabel);
_noRows->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
label->resizeToWidth(width);
label->moveToLeft(0, 0);
}, label->lifetime());
@@ -1005,29 +1013,29 @@ void ProxiesBox::createNoRowsLabel() {
void ProxiesBox::setupButtons(int id, not_null<ProxyRow*> button) {
button->deleteClicks(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_controller->deleteItem(id);
}, button->lifetime());
button->restoreClicks(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_controller->restoreItem(id);
}, button->lifetime());
button->editClicks(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
getDelegate()->show(_controller->editItemBox(id));
}, button->lifetime());
rpl::merge(
button->shareClicks() | rpl::map_to(false),
button->showQrClicks() | rpl::map_to(true)
) | rpl::start_with_next([=](bool qr) {
) | rpl::on_next([=](bool qr) {
_controller->shareItem(id, qr);
}, button->lifetime());
button->clicks(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_controller->applyItem(id);
}, button->lifetime());
}
@@ -1063,7 +1071,7 @@ void ProxyBox::prepare() {
});
});
_port.data()->events(
) | rpl::start_with_next([=](not_null<QEvent*> e) {
) | rpl::on_next([=](not_null<QEvent*> e) {
if (e->type() == QEvent::KeyPress
&& (static_cast<QKeyEvent*>(e.get())->key() == Qt::Key_Backspace)
&& _port->cursorPosition() == 0) {
@@ -1173,7 +1181,7 @@ void ProxyBox::setupSocketAddress(const ProxyData &data) {
data.port ? QString::number(data.port) : QString(),
65535);
address->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
_port->moveToRight(0, 0);
_host->resize(
width - _port->width() - st::proxyEditSkip,
@@ -1183,7 +1191,7 @@ void ProxyBox::setupSocketAddress(const ProxyData &data) {
}
void ProxyBox::setupCredentials(const ProxyData &data) {
_credentials = _content->add(
_credentials = _content->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
_content,
object_ptr<Ui::VerticalLayout>(_content)));
@@ -1205,11 +1213,11 @@ void ProxyBox::setupCredentials(const ProxyData &data) {
(data.type == Type::Mtproto) ? QString() : data.password);
_password->move(0, 0);
_password->heightValue(
) | rpl::start_with_next([=, wrap = passwordWrap.data()](int height) {
) | rpl::on_next([=, wrap = passwordWrap.data()](int height) {
wrap->resize(wrap->width(), height);
}, _password->lifetime());
passwordWrap->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
_password->resize(width, _password->height());
}, _password->lifetime());
credentials->add(std::move(passwordWrap), st::proxyEditInputPadding);
@@ -1231,11 +1239,11 @@ void ProxyBox::setupMtprotoCredentials(const ProxyData &data) {
(data.type == Type::Mtproto) ? data.password : QString());
_secret->move(0, 0);
_secret->heightValue(
) | rpl::start_with_next([=, wrap = secretWrap.data()](int height) {
) | rpl::on_next([=, wrap = secretWrap.data()](int height) {
wrap->resize(wrap->width(), height);
}, _secret->lifetime());
secretWrap->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
_secret->resize(width, _secret->height());
}, _secret->lifetime());
mtproto->add(std::move(secretWrap), st::proxyEditInputPadding);
@@ -1297,7 +1305,7 @@ ProxiesBoxController::ProxiesBoxController(not_null<Main::Account*> account)
}) | ranges::to_vector;
_settings.connectionTypeChanges(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_proxySettingsChanges.fire_copy(_settings.settings());
const auto i = findByProxy(_settings.selected());
if (i != end(_list)) {
@@ -1316,10 +1324,13 @@ void ProxiesBoxController::ShowApplyConfirmation(
const QMap<QString, QString> &fields) {
const auto proxy = ProxyDataFromFields(type, fields);
if (!proxy) {
const auto status = proxy.status();
auto box = Ui::MakeInformBox(
(proxy.status() == ProxyData::Status::Unsupported
? tr::lng_proxy_unsupported(tr::now)
: tr::lng_proxy_invalid(tr::now)));
((status == ProxyData::Status::Unsupported)
? tr::lng_proxy_unsupported(tr::now, tr::rich)
: (status == ProxyData::Status::IncorrectSecret)
? tr::lng_proxy_incorrect_secret(tr::now, tr::rich)
: tr::lng_proxy_invalid(tr::now, tr::rich)));
if (controller) {
controller->uiShow()->showBox(std::move(box));
} else {

View File

@@ -198,7 +198,7 @@ not_null<Ui::FlatLabel*> CreateWarningLabel(
st::createPollWarning);
result->setAttribute(Qt::WA_TransparentForMouseEvents);
field->changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
Ui::PostponeCall(crl::guard(field, [=] {
const auto length = field->getLastText().size();
const auto value = valueLimit - length;
@@ -251,17 +251,17 @@ Options::Option::Option(
_wrap->hide(anim::type::instant);
_content->widthValue(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
updateFieldGeometry();
}, _field->lifetime());
_field->heightValue(
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
_content->resize(_content->width(), height);
}, _field->lifetime());
_field->changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
Ui::PostponeCall(crl::guard(_field, [=] {
if (_hasCorrect) {
_correct->toggle(isGood(), anim::type::normal);
@@ -293,7 +293,7 @@ void Options::Option::createShadow() {
_shadow.reset(Ui::CreateChild<Ui::PlainShadow>(field().get()));
_shadow->show();
field()->sizeValue(
) | rpl::start_with_next([=](QSize size) {
) | rpl::on_next([=](QSize size) {
const auto left = st::createPollFieldPadding.left();
_shadow->setGeometry(
left,
@@ -322,7 +322,7 @@ void Options::Option::createRemove() {
_removeAlways = lifetime.make_state<rpl::variable<bool>>(false);
field->changes(
) | rpl::start_with_next([field, toggle] {
) | rpl::on_next([field, toggle] {
// Don't capture 'this'! Because Option is a value type.
*toggle = !field->getLastText().isEmpty();
}, field->lifetime());
@@ -331,13 +331,13 @@ void Options::Option::createRemove() {
toggle->value(),
_removeAlways->value(),
_1 || _2
) | rpl::start_with_next([=](bool shown) {
) | rpl::on_next([=](bool shown) {
remove->toggle(shown, anim::type::normal);
}, remove->lifetime());
#endif
field->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
remove->moveToRight(
st::createPollOptionRemovePosition.x(),
st::createPollOptionRemovePosition.y(),
@@ -359,7 +359,7 @@ void Options::Option::createWarning() {
rpl::combine(
field->sizeValue(),
warning->sizeValue()
) | rpl::start_with_next([=](QSize size, QSize label) {
) | rpl::on_next([=](QSize size, QSize label) {
warning->moveToLeft(
(size.width()
- label.width()
@@ -431,7 +431,7 @@ void Options::Option::enableChooseCorrect(
button->entity()->height());
button->hide(anim::type::instant);
_content->sizeValue(
) | rpl::start_with_next([=](QSize size) {
) | rpl::on_next([=](QSize size) {
const auto left = st::createPollFieldPadding.left();
button->moveToLeft(
left,
@@ -688,19 +688,19 @@ void Options::addEmptyOption() {
QPoint(
-st::createPollOptionFieldPremium.textMargins.right(),
st::createPollOptionEmojiPositionSkip));
emojiToggle->shownValue() | rpl::start_with_next([=](bool shown) {
emojiToggle->shownValue() | rpl::on_next([=](bool shown) {
if (!shown) {
return;
}
_emojiPanelLifetime.destroy();
emojiPanel->selector()->emojiChosen(
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
) | rpl::on_next([=](ChatHelpers::EmojiChosen data) {
if (field->hasFocus()) {
Ui::InsertEmojiAtCursor(field->textCursor(), data.emoji);
}
}, _emojiPanelLifetime);
emojiPanel->selector()->customEmojiChosen(
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
) | rpl::on_next([=](ChatHelpers::FileChosen data) {
if (field->hasFocus()) {
Data::InsertCustomEmoji(field, data.document);
}
@@ -708,24 +708,24 @@ void Options::addEmptyOption() {
}, emojiToggle->lifetime());
}
field->submits(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
const auto index = findField(field);
if (_list[index]->isGood() && index + 1 < _list.size()) {
_list[index + 1]->setFocus();
}
}, field->lifetime());
field->changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
Ui::PostponeCall(crl::guard(field, [=] {
validateState();
}));
}, field->lifetime());
field->focusedChanges(
) | rpl::filter(rpl::mappers::_1) | rpl::start_with_next([=] {
) | rpl::filter(rpl::mappers::_1) | rpl::on_next([=] {
_scrollToWidget.fire_copy(field);
}, field->lifetime());
field->tabbed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
const auto index = findField(field);
if (index + 1 < _list.size()) {
_list[index + 1]->setFocus();
@@ -753,7 +753,7 @@ void Options::addEmptyOption() {
});
_list.back()->removeClicks(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
Ui::PostponeCall(crl::guard(field, [=] {
Expects(!_list.empty());
@@ -891,13 +891,13 @@ not_null<Ui::InputField*> CreatePollBox::setupQuestion(
emojiPanel,
st::createPollOptionFieldPremiumEmojiPosition);
emojiPanel->selector()->emojiChosen(
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
) | rpl::on_next([=](ChatHelpers::EmojiChosen data) {
if (question->hasFocus()) {
Ui::InsertEmojiAtCursor(question->textCursor(), data.emoji);
}
}, emojiToggle->lifetime());
emojiPanel->selector()->customEmojiChosen(
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
) | rpl::on_next([=](ChatHelpers::FileChosen data) {
if (question->hasFocus()) {
Data::InsertCustomEmoji(question, data.document);
}
@@ -912,7 +912,7 @@ not_null<Ui::InputField*> CreatePollBox::setupQuestion(
rpl::combine(
question->geometryValue(),
warning->sizeValue()
) | rpl::start_with_next([=](QRect geometry, QSize label) {
) | rpl::on_next([=](QRect geometry, QSize label) {
warning->moveToLeft(
(container->width()
- label.width()
@@ -978,7 +978,7 @@ not_null<Ui::InputField*> CreatePollBox::setupSolution(
rpl::combine(
solution->geometryValue(),
warning->sizeValue()
) | rpl::start_with_next([=](QRect geometry, QSize label) {
) | rpl::on_next([=](QRect geometry, QSize label) {
warning->moveToLeft(
(inner->width()
- label.width()
@@ -1048,7 +1048,7 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
st::createPollLimitPadding));
question->tabbed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
options->focusFirst();
}, question->lifetime());
@@ -1088,7 +1088,7 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
rpl::single(quiz->checked()) | rpl::then(quiz->checkedChanges()));
options->tabbed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
if (quiz->checked()) {
solution->setFocus();
} else {
@@ -1097,7 +1097,7 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
}, question->lifetime());
solution->tabbed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
question->setFocus();
}, solution->lifetime());
@@ -1109,14 +1109,14 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
) | rpl::filter([=](not_null<QEvent*> e) {
return (e->type() == QEvent::MouseButtonPress)
&& quiz->checked();
}) | rpl::start_with_next([show = uiShow()] {
}) | rpl::on_next([show = uiShow()] {
show->showToast(tr::lng_polls_create_one_answer(tr::now));
}, multiple->lifetime());
}
using namespace rpl::mappers;
quiz->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
) | rpl::on_next([=](bool checked) {
if (multiple) {
if (checked && multiple->checked()) {
multiple->setChecked(false);
@@ -1132,7 +1132,7 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
return !text.isEmpty() && (text.size() <= kQuestionLimit);
};
question->submits(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
if (isValidQuestion()) {
options->focusFirst();
}
@@ -1216,12 +1216,12 @@ object_ptr<Ui::RpWidget> CreatePollBox::setupContent() {
crl::guard(this, send));
options->scrollToWidget(
) | rpl::start_with_next([=](not_null<QWidget*> widget) {
) | rpl::on_next([=](not_null<QWidget*> widget) {
scrollToWidget(widget);
}, lifetime());
options->backspaceInFront(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
FocusAtEnd(question);
}, lifetime());

View File

@@ -164,7 +164,7 @@ void DeleteMessagesBox::prepare() {
appendDetails(std::move(revoke->description));
if (!peer->isUser() && !_wipeHistoryJustClear) {
_revoke->checkedValue(
) | rpl::start_with_next([=](bool revokeForAll) {
) | rpl::on_next([=](bool revokeForAll) {
*deleteText = revokeForAll
? tr::lng_box_delete()
: tr::lng_box_leave();
@@ -251,13 +251,13 @@ void DeleteMessagesBox::prepare() {
st::defaultBoxCheckbox));
_revokeRemember->hide(anim::type::instant);
_revoke->checkedValue(
) | rpl::start_with_next([=](bool checked) {
) | rpl::on_next([=](bool checked) {
_revokeRemember->toggle(
checked != revokeByDefault,
anim::type::normal);
}, _revokeRemember->lifetime());
_revokeRemember->heightValue(
) | rpl::start_with_next([=](int h) {
) | rpl::on_next([=](int h) {
setDimensions(st::boxWidth, _fullHeight + h);
}, lifetime());
appendDetails(std::move(revoke->description));
@@ -320,7 +320,7 @@ void DeleteMessagesBox::prepare() {
rpl::combine(
widthValue(),
_text->naturalWidthValue()
) | rpl::start_with_next([=](int full, int) {
) | rpl::on_next([=](int full, int) {
_text->resizeToNaturalWidth(full - padding.left() - padding.right());
auto fullHeight = st::boxPadding.top()

View File

@@ -143,7 +143,7 @@ auto AddButtonWithLoader(
std::move(
query
) | rpl::start_with_next([=](auto string) {
) | rpl::on_next([=](auto string) {
wrap->toggle(
ranges::any_of(indexList, [&](const QString &s) {
return s.startsWith(string, Qt::CaseInsensitive);
@@ -198,7 +198,7 @@ auto AddButtonWithLoader(
};
Spellchecker::GlobalLoaderChanged(
) | rpl::start_with_next([=](int langId) {
) | rpl::on_next([=](int langId) {
if (!langId && rawGlobalLoaderPtr()) {
setGlobalLoaderPtr(nullptr);
} else if (langId == id) {
@@ -215,14 +215,14 @@ auto AddButtonWithLoader(
rpl::combine(
button->widthValue(),
label->widthValue()
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
label->moveToLeft(
st::settingsUpdateStatePosition.x(),
st::settingsUpdateStatePosition.y());
}, label->lifetime());
buttonState->value(
) | rpl::start_with_next([=](const DictState &state) {
) | rpl::on_next([=](const DictState &state) {
const auto isToggledSet = v::is<Active>(state);
const auto toggled = isToggledSet ? 1. : 0.;
const auto over = !button->isDisabled()
@@ -279,7 +279,7 @@ auto AddButtonWithLoader(
});
button->toggledValue(
) | rpl::start_with_next([=](bool toggled) {
) | rpl::on_next([=](bool toggled) {
const auto &state = buttonState->current();
if (toggled && (v::is<Available>(state) || v::is<Failed>(state))) {
const auto weak = base::make_weak(button);
@@ -353,7 +353,7 @@ void Inner::setupContent(
ranges::contains(enabledDictionaries, id),
queryStream->events());
row->toggledValue(
) | rpl::start_with_next([=](auto enabled) {
) | rpl::on_next([=](auto enabled) {
if (enabled) {
_enabledRows.push_back(id);
} else {
@@ -420,7 +420,7 @@ void ManageDictionariesBox::prepare() {
});
addButton(tr::lng_close(), [=] { closeBox(); });
boxClosing() | rpl::start_with_next([=] {
boxClosing() | rpl::on_next([=] {
Core::App().settings().setDictionariesEnabled(
FilterEnabledDict(initialEnabledRows));
Core::App().saveSettingsDelayed();
@@ -434,7 +434,7 @@ void ManageDictionariesBox::prepare() {
inner->heightValue(),
multiSelect->heightValue(),
_1 + _2
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
using std::min;
accumulate_max(*max, height);
setDimensions(st::boxWidth, min(*max, st::boxMaxListHeight), true);

View File

@@ -232,7 +232,7 @@ EditCaptionBox::EditCaptionBox(
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item,
TextWithTags &&text,
SuggestPostOptions suggest,
SuggestOptions suggest,
bool spoilered,
bool invertCaption,
Ui::PreparedList &&list,
@@ -262,7 +262,7 @@ EditCaptionBox::EditCaptionBox(
_controller->session().data().itemRemoved(
_historyItem->fullId()
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
closeBox();
}, lifetime());
}
@@ -273,7 +273,7 @@ void EditCaptionBox::StartMediaReplace(
not_null<Window::SessionController*> controller,
FullMsgId itemId,
TextWithTags text,
SuggestPostOptions suggest,
SuggestOptions suggest,
bool spoilered,
bool invertCaption,
Fn<void()> saved) {
@@ -304,7 +304,7 @@ void EditCaptionBox::StartMediaReplace(
FullMsgId itemId,
Ui::PreparedList &&list,
TextWithTags text,
SuggestPostOptions suggest,
SuggestOptions suggest,
bool spoilered,
bool invertCaption,
Fn<void()> saved) {
@@ -353,7 +353,7 @@ void EditCaptionBox::StartPhotoEdit(
std::shared_ptr<Data::PhotoMedia> media,
FullMsgId itemId,
TextWithTags text,
SuggestPostOptions suggest,
SuggestOptions suggest,
bool spoilered,
bool invertCaption,
Fn<void()> saved) {
@@ -490,7 +490,7 @@ void EditCaptionBox::rebuildPreview() {
const auto withCheckbox = _isPhoto && CanBeCompressed(_albumType);
if (media && (!withCheckbox || !_asFile)) {
media->spoileredChanges(
) | rpl::start_with_next([=](bool spoilered) {
) | rpl::on_next([=](bool spoilered) {
_mediaEditManager.apply({ .type = spoilered
? SendMenu::ActionType::SpoilerOn
: SendMenu::ActionType::SpoilerOff
@@ -512,7 +512,7 @@ void EditCaptionBox::rebuildPreview() {
_footerHeight.value(),
rpl::single(st::boxPhotoPadding.top()),
rpl::mappers::_1 + rpl::mappers::_2 + rpl::mappers::_3
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
setDimensions(
st::boxWideWidth,
std::min(st::sendMediaPreviewHeightMax, height),
@@ -525,11 +525,11 @@ void EditCaptionBox::rebuildPreview() {
_content->modifyRequests(
) | rpl::start_to_stream(_photoEditorOpens, _content->lifetime());
_content->editCoverRequests() | rpl::start_with_next([=] {
_content->editCoverRequests() | rpl::on_next([=] {
setupEditCoverHandler();
}, _content->lifetime());
_content->clearCoverRequests() | rpl::start_with_next([=] {
_content->clearCoverRequests() | rpl::on_next([=] {
setupClearCoverHandler();
}, _content->lifetime());
@@ -566,13 +566,13 @@ void EditCaptionBox::setupField() {
_field->setMaxHeight(st::defaultComposeFiles.caption.heightMax);
_field->submits(
) | rpl::start_with_next([=] { save(); }, _field->lifetime());
) | rpl::on_next([=] { save(); }, _field->lifetime());
_field->cancelled(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
closeBox();
}, _field->lifetime());
_field->heightChanges(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
captionResized();
}, _field->lifetime());
_field->setMimeDataHook([=](
@@ -656,7 +656,7 @@ void EditCaptionBox::setInitialText() {
}
});
_field->changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
_checkChangedTimer.callOnce(kChangesDebounceTimeout);
setCloseByOutsideClick(false);
}, _field->lifetime());
@@ -696,7 +696,7 @@ void EditCaptionBox::setupControls() {
}),
anim::type::instant
)->entity()->checkedChanges(
) | rpl::start_with_next([&](bool checked) {
) | rpl::on_next([&](bool checked) {
applyChanges();
_asFile = !checked;
rebuildPreview();
@@ -707,7 +707,7 @@ void EditCaptionBox::setupControls() {
void EditCaptionBox::setupEditEventHandler() {
_editMediaClicks.events(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
ChooseReplacement(_controller, _albumType, crl::guard(this, [=](
Ui::PreparedList &&list) {
setPreparedList(std::move(list));
@@ -718,7 +718,7 @@ void EditCaptionBox::setupEditEventHandler() {
void EditCaptionBox::setupPhotoEditorEventHandler() {
const auto openedOnce = lifetime().make_state<bool>(false);
_photoEditorOpens.events(
) | rpl::start_with_next([=, controller = _controller] {
) | rpl::on_next([=, controller = _controller] {
if (_preparedList.files.empty()
&& (!_photoMedia
|| !_photoMedia->image(Data::PhotoSize::Large))) {
@@ -880,11 +880,11 @@ void EditCaptionBox::setupEmojiPanel() {
_emojiPanel->hide();
_emojiPanel->selector()->setCurrentPeer(_historyItem->history()->peer);
_emojiPanel->selector()->emojiChosen(
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
) | rpl::on_next([=](ChatHelpers::EmojiChosen data) {
Ui::InsertEmojiAtCursor(_field->textCursor(), data.emoji);
}, lifetime());
_emojiPanel->selector()->customEmojiChosen(
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
) | rpl::on_next([=](ChatHelpers::FileChosen data) {
const auto info = data.document->sticker();
if (info
&& info->setType == Data::StickersType::Emoji

View File

@@ -39,7 +39,7 @@ public:
not_null<Window::SessionController*> controller,
not_null<HistoryItem*> item,
TextWithTags &&text,
SuggestPostOptions suggest,
SuggestOptions suggest,
bool spoilered,
bool invertCaption,
Ui::PreparedList &&list,
@@ -50,7 +50,7 @@ public:
not_null<Window::SessionController*> controller,
FullMsgId itemId,
TextWithTags text,
SuggestPostOptions suggest,
SuggestOptions suggest,
bool spoilered,
bool invertCaption,
Fn<void()> saved);
@@ -59,7 +59,7 @@ public:
FullMsgId itemId,
Ui::PreparedList &&list,
TextWithTags text,
SuggestPostOptions suggest,
SuggestOptions suggest,
bool spoilered,
bool invertCaption,
Fn<void()> saved);
@@ -68,7 +68,7 @@ public:
std::shared_ptr<Data::PhotoMedia> media,
FullMsgId itemId,
TextWithTags text,
SuggestPostOptions suggest,
SuggestOptions suggest,
bool spoilered,
bool invertCaption,
Fn<void()> saved);
@@ -117,7 +117,7 @@ private:
const not_null<Window::SessionController*> _controller;
const not_null<HistoryItem*> _historyItem;
const SuggestPostOptions _suggest;
const SuggestOptions _suggest;
const bool _isAllowedEditMedia;
const Ui::AlbumType _albumType;

View File

@@ -111,11 +111,11 @@ void CreateRadiobuttonLock(
lock->resize(st::defaultRadio.diameter, st::defaultRadio.diameter);
widget->sizeValue(
) | rpl::start_with_next([=, &st](QSize size) {
) | rpl::on_next([=, &st](QSize size) {
lock->move(st.checkPosition);
}, lock->lifetime());
lock->paintRequest() | rpl::start_with_next([=] {
lock->paintRequest() | rpl::on_next([=] {
auto p = QPainter(lock);
auto hq = PainterHighQualityEnabler(p);
const auto &icon = st::messagePrivacyLock;
@@ -138,7 +138,7 @@ void AddPremiumRequiredRow(
const auto row = Ui::CreateChild<Ui::AbstractButton>(widget.get());
widget->sizeValue(
) | rpl::start_with_next([=](const QSize &s) {
) | rpl::on_next([=](const QSize &s) {
row->resize(s);
}, row->lifetime());
row->setClickedCallback(std::move(clickedCallback));
@@ -147,7 +147,7 @@ void AddPremiumRequiredRow(
Data::AmPremiumValue(
session
) | rpl::start_with_next([=](bool premium) {
) | rpl::on_next([=](bool premium) {
row->setVisible(!premium);
if (!premium) {
setDefaultOption();
@@ -382,7 +382,7 @@ auto PrivacyExceptionsBoxController::prepareSpecialRowList(
tr::lng_edit_privacy_users_and_groups()));
controller->specialChanges(
) | rpl::start_with_next([=](bool chosen) {
) | rpl::on_next([=](bool chosen) {
if (type == SpecialRowType::Premiums) {
_selected.premiums = chosen;
} else {
@@ -391,7 +391,7 @@ auto PrivacyExceptionsBoxController::prepareSpecialRowList(
}, lifetime);
controller->rowSelectionChanges(
) | rpl::start_with_next([=](RowSelectionChange update) {
) | rpl::on_next([=](RowSelectionChange update) {
this->delegate()->peerListSetForeignRowChecked(
update.row,
update.checked,
@@ -543,7 +543,7 @@ auto PrivacyExceptionsBoxController::createRow(not_null<History*> history)
updateByValue(value);
valueFinished(value);
};
style::PaletteChanged() | rpl::start_with_next([=] {
style::PaletteChanged() | rpl::on_next([=] {
min->setTextColorOverride(st::windowSubTextFg->c);
max->setTextColorOverride(st::windowSubTextFg->c);
}, raw->lifetime());
@@ -559,7 +559,7 @@ auto PrivacyExceptionsBoxController::createRow(not_null<History*> history)
state->indexMin);
slider->resize(slider->width(), sliderStyle->seekSize.height());
raw->widthValue() | rpl::start_with_next([=](int width) {
raw->widthValue() | rpl::on_next([=](int width) {
labels->resizeToWidth(width);
updateByIndex();
}, slider->lifetime());
@@ -939,7 +939,7 @@ void EditPrivacyBox::setupContent() {
+ st::settingsButtonNoIcon.padding.bottom();
widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
content->resizeToWidth(width);
}, content->lifetime());
@@ -947,7 +947,7 @@ void EditPrivacyBox::setupContent() {
) | rpl::map([=](int height) {
return height - always->height() - never->height() + 2 * linkHeight;
}) | rpl::distinct_until_changed(
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
setDimensions(st::boxWideWidth, height);
}, content->lifetime());
}
@@ -1076,7 +1076,7 @@ void EditMessagesPrivacyBox(
key
) | rpl::take(
1
) | rpl::start_with_next([=](const Api::UserPrivacy::Rule &value) {
) | rpl::on_next([=](const Api::UserPrivacy::Rule &value) {
EditNoPaidMessagesExceptions(controller, value);
});
});
@@ -1233,7 +1233,7 @@ rpl::producer<int> SetupChargeSlider(
const auto details = container->add(
object_ptr<Ui::VerticalLayout>(container));
state->stars.value() | rpl::start_with_next([=](int stars) {
state->stars.value() | rpl::on_next([=](int stars) {
while (details->count()) {
delete details->widgetAt(0);
}
@@ -1313,7 +1313,7 @@ void EditDirectMessagesPriceBox(
savedValue,
channel->session().appConfig().paidMessageChannelStarsDefault(),
true
) | rpl::start_with_next([=](int stars) {
) | rpl::on_next([=](int stars) {
*result = stars;
}, box->lifetime());
@@ -1358,7 +1358,7 @@ void EditDirectMessagesPriceBox(
label->take(),
st::inviteLinkFieldPadding);
label->clicks() | rpl::start_with_next(copyLink, label->lifetime());
label->clicks() | rpl::on_next(copyLink, label->lifetime());
Ui::AddSkip(inner);

View File

@@ -227,7 +227,7 @@ not_null<Ui::FlatLabel*> CreateWarningLabel(
st::createPollWarning);
result->setAttribute(Qt::WA_TransparentForMouseEvents);
field->changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
Ui::PostponeCall(crl::guard(field, [=] {
const auto length = field->getLastText().size();
const auto value = valueLimit - length;
@@ -310,12 +310,12 @@ Tasks::Task::Task(
_wrap->hide(anim::type::instant);
_content->widthValue(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
updateFieldGeometry();
}, _field->lifetime());
_field->heightValue(
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
_content->resize(_content->width(), height);
}, _field->lifetime());
@@ -340,7 +340,7 @@ void Tasks::Task::createShadow() {
_shadow.reset(Ui::CreateChild<Ui::PlainShadow>(field().get()));
_shadow->show();
field()->sizeValue(
) | rpl::start_with_next([=](QSize size) {
) | rpl::on_next([=](QSize size) {
const auto left = st::createPollFieldPadding.left();
_shadow->setGeometry(
left,
@@ -369,7 +369,7 @@ void Tasks::Task::createRemove() {
_removeAlways = lifetime.make_state<rpl::variable<bool>>(false);
field->changes(
) | rpl::start_with_next([field, toggle] {
) | rpl::on_next([field, toggle] {
// Don't capture 'this'! Because Option is a value type.
*toggle = !field->getLastText().isEmpty();
}, field->lifetime());
@@ -378,13 +378,13 @@ void Tasks::Task::createRemove() {
toggle->value(),
_removeAlways->value(),
_1 || _2
) | rpl::start_with_next([=](bool shown) {
) | rpl::on_next([=](bool shown) {
remove->toggle(shown, anim::type::normal);
}, remove->lifetime());
#endif
field->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
remove->moveToRight(
st::createPollOptionRemovePosition.x(),
st::createPollOptionRemovePosition.y(),
@@ -406,7 +406,7 @@ void Tasks::Task::createWarning() {
rpl::combine(
field->sizeValue(),
warning->sizeValue()
) | rpl::start_with_next([=](QSize size, QSize label) {
) | rpl::on_next([=](QSize size, QSize label) {
warning->moveToLeft(
(size.width()
- label.width()
@@ -717,19 +717,19 @@ void Tasks::initTaskField(not_null<Task*> task, TextWithEntities text) {
QPoint(
-st::createPollOptionFieldPremium.textMargins.right(),
st::createPollOptionEmojiPositionSkip));
emojiToggle->shownValue() | rpl::start_with_next([=](bool shown) {
emojiToggle->shownValue() | rpl::on_next([=](bool shown) {
if (!shown) {
return;
}
_emojiPanelLifetime.destroy();
emojiPanel->selector()->emojiChosen(
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
) | rpl::on_next([=](ChatHelpers::EmojiChosen data) {
if (field->hasFocus()) {
Ui::InsertEmojiAtCursor(field->textCursor(), data.emoji);
}
}, _emojiPanelLifetime);
emojiPanel->selector()->customEmojiChosen(
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
) | rpl::on_next([=](ChatHelpers::FileChosen data) {
if (field->hasFocus()) {
Data::InsertCustomEmoji(field, data.document);
}
@@ -741,14 +741,14 @@ void Tasks::initTaskField(not_null<Task*> task, TextWithEntities text) {
TextUtilities::ConvertEntitiesToTextTags(text.entities)
});
field->submits(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
const auto index = findField(field);
if (_list[index]->isGood() && index + 1 < _list.size()) {
_list[index + 1]->setFocus();
}
}, field->lifetime());
field->changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
auto list = ParsePastedList(field->getLastText());
if (!list.empty()) {
field->setText(list.front());
@@ -762,11 +762,11 @@ void Tasks::initTaskField(not_null<Task*> task, TextWithEntities text) {
}));
}, field->lifetime());
field->focusedChanges(
) | rpl::filter(rpl::mappers::_1) | rpl::start_with_next([=] {
) | rpl::filter(rpl::mappers::_1) | rpl::on_next([=] {
_scrollToWidget.fire_copy(field);
}, field->lifetime());
field->tabbed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
const auto index = findField(field);
if (index + 1 < _list.size()) {
_list[index + 1]->setFocus();
@@ -794,7 +794,7 @@ void Tasks::initTaskField(not_null<Task*> task, TextWithEntities text) {
});
task->removeClicks(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
Ui::PostponeCall(crl::guard(field, [=] {
Expects(!_list.empty());
@@ -895,7 +895,7 @@ EditTodoListBox::EditTodoListBox(
, _titleLimit(controller->session().appConfig().todoListTitleLimit()) {
_controller->session().changes().messageUpdates(
Data::MessageUpdate::Flag::Destroyed
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
) | rpl::on_next([=](const Data::MessageUpdate &update) {
if (update.item == item) {
closeBox();
}
@@ -946,13 +946,13 @@ not_null<Ui::InputField*> EditTodoListBox::setupTitle(
_emojiPanel.get(),
st::createPollOptionFieldPremiumEmojiPosition);
_emojiPanel->selector()->emojiChosen(
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
) | rpl::on_next([=](ChatHelpers::EmojiChosen data) {
if (title->hasFocus()) {
Ui::InsertEmojiAtCursor(title->textCursor(), data.emoji);
}
}, emojiToggle->lifetime());
_emojiPanel->selector()->customEmojiChosen(
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
) | rpl::on_next([=](ChatHelpers::FileChosen data) {
if (title->hasFocus()) {
Data::InsertCustomEmoji(title, data.document);
}
@@ -976,7 +976,7 @@ not_null<Ui::InputField*> EditTodoListBox::setupTitle(
rpl::combine(
title->geometryValue(),
warning->sizeValue()
) | rpl::start_with_next([=](QRect geometry, QSize label) {
) | rpl::on_next([=](QRect geometry, QSize label) {
warning->moveToLeft(
(container->width()
- label.width()
@@ -1044,7 +1044,7 @@ object_ptr<Ui::RpWidget> EditTodoListBox::setupContent() {
st::createPollLimitPadding));
title->tabbed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
tasks->focusFirst();
}, title->lifetime());
@@ -1067,7 +1067,7 @@ object_ptr<Ui::RpWidget> EditTodoListBox::setupContent() {
st::createPollCheckboxMargin);
tasks->tabbed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
title->setFocus();
}, title->lifetime());
@@ -1076,7 +1076,7 @@ object_ptr<Ui::RpWidget> EditTodoListBox::setupContent() {
return !text.isEmpty() && (text.size() <= _titleLimit);
};
title->submits(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
if (isValidTitle()) {
tasks->focusFirst();
}
@@ -1146,12 +1146,12 @@ object_ptr<Ui::RpWidget> EditTodoListBox::setupContent() {
crl::guard(this, send));
tasks->scrollToWidget(
) | rpl::start_with_next([=](not_null<QWidget*> widget) {
) | rpl::on_next([=](not_null<QWidget*> widget) {
scrollToWidget(widget);
}, lifetime());
tasks->backspaceInFront(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
FocusAtEnd(title);
}, lifetime());
@@ -1201,7 +1201,7 @@ AddTodoListTasksBox::AddTodoListTasksBox(
, _item(item) {
_controller->session().changes().messageUpdates(
Data::MessageUpdate::Flag::Destroyed
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
) | rpl::on_next([=](const Data::MessageUpdate &update) {
if (update.item == item) {
closeBox();
}
@@ -1266,7 +1266,7 @@ object_ptr<Ui::RpWidget> AddTodoListTasksBox::setupContent() {
};
tasks->scrollToWidget(
) | rpl::start_with_next([=](not_null<QWidget*> widget) {
) | rpl::on_next([=](not_null<QWidget*> widget) {
scrollToWidget(widget);
}, lifetime());

View File

@@ -94,7 +94,7 @@ not_null<FilterChatsPreview*> SetupChatsPreview(
(rules.*peers)()));
preview->flagRemoved(
) | rpl::start_with_next([=](Flag flag) {
) | rpl::on_next([=](Flag flag) {
const auto rules = data->current();
auto computed = Data::ChatFilter(
rules.id(),
@@ -110,7 +110,7 @@ not_null<FilterChatsPreview*> SetupChatsPreview(
}, preview->lifetime());
preview->peerRemoved(
) | rpl::start_with_next([=](not_null<History*> history) {
) | rpl::on_next([=](not_null<History*> history) {
const auto rules = data->current();
auto always = rules.always();
auto pinned = rules.pinned();
@@ -220,13 +220,13 @@ void CreateIconSelector(
data->value(
) | rpl::map([=](const Data::ChatFilter &filter) {
return Ui::ComputeFilterIcon(filter);
}) | rpl::start_with_next([=](Ui::FilterIcon icon) {
}) | rpl::on_next([=](Ui::FilterIcon icon) {
*type = icon;
toggle->update();
}, toggle->lifetime());
input->geometryValue(
) | rpl::start_with_next([=](QRect geometry) {
) | rpl::on_next([=](QRect geometry) {
const auto left = geometry.x() + geometry.width() - toggle->width();
const auto position = st::windowFilterIconTogglePosition;
toggle->move(
@@ -235,7 +235,7 @@ void CreateIconSelector(
}, toggle->lifetime());
toggle->paintRequest(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
auto p = QPainter(toggle);
const auto icons = Ui::LookupFilterIcon(*type);
icons.normal->paintInCenter(
@@ -253,7 +253,7 @@ void CreateIconSelector(
panel->chosen(
) | rpl::filter([=](Ui::FilterIcon icon) {
return icon != Ui::ComputeFilterIcon(data->current());
}) | rpl::start_with_next([=](Ui::FilterIcon icon) {
}) | rpl::on_next([=](Ui::FilterIcon icon) {
panel->hideAnimated();
const auto rules = data->current();
*data = Data::ChatFilter(
@@ -382,7 +382,7 @@ void EditFilterBox(
});
state->hasLinks.value() | rpl::filter(
_1
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
state->chatlist = true;
}, box->lifetime());
@@ -391,7 +391,7 @@ void EditFilterBox(
owner->chatsFilters().isChatlistChanged(
) | rpl::filter([=](FilterId id) {
return (id == data->current().id());
}) | rpl::start_with_next([=](FilterId id) {
}) | rpl::on_next([=](FilterId id) {
const auto filters = &owner->chatsFilters();
const auto &list = filters->list();
const auto i = ranges::find(list, id, &Data::ChatFilter::id);
@@ -414,7 +414,7 @@ void EditFilterBox(
const auto session = &window->session();
Data::AmPremiumValue(
session
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
box->closeBox();
}, box->lifetime());
@@ -458,7 +458,7 @@ void EditFilterBox(
staticTitle->setClickedCallback([=] {
state->staticTitle = !state->staticTitle.current();
});
state->staticTitle.value() | rpl::start_with_next([=](bool value) {
state->staticTitle.value() | rpl::on_next([=](bool value) {
staticTitle->setText(value
? tr::lng_filters_enable_animations(tr::now)
: tr::lng_filters_disable_animations(tr::now));
@@ -480,7 +480,7 @@ void EditFilterBox(
rpl::combine(
staticTitle->widthValue(),
name->widthValue()
) | rpl::start_with_next([=](int inner, int outer) {
) | rpl::on_next([=](int inner, int outer) {
staticTitle->moveToRight(
st::windowFilterStaticTitlePosition.x(),
st::windowFilterStaticTitlePosition.y(),
@@ -488,7 +488,7 @@ void EditFilterBox(
}, staticTitle->lifetime());
state->creating.value(
) | rpl::filter(!_1) | rpl::start_with_next([=] {
) | rpl::filter(!_1) | rpl::on_next([=] {
nameEditing->custom = true;
}, box->lifetime());
@@ -508,11 +508,11 @@ void EditFilterBox(
state->emojiPanel->hide();
state->emojiPanel->selector()->setCurrentPeer(window->session().user());
state->emojiPanel->selector()->emojiChosen(
) | rpl::start_with_next([=](ChatHelpers::EmojiChosen data) {
) | rpl::on_next([=](ChatHelpers::EmojiChosen data) {
Ui::InsertEmojiAtCursor(name->textCursor(), data.emoji);
}, name->lifetime());
state->emojiPanel->selector()->customEmojiChosen(
) | rpl::start_with_next([=](ChatHelpers::FileChosen data) {
) | rpl::on_next([=](ChatHelpers::FileChosen data) {
const auto info = data.document->sticker();
if (info
&& info->setType == Data::StickersType::Emoji
@@ -534,7 +534,7 @@ void EditFilterBox(
emojiButton->show();
name->changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
if (!nameEditing->settingDefault) {
nameEditing->custom = true;
}
@@ -558,7 +558,7 @@ void EditFilterBox(
};
state->title.value(
) | rpl::start_with_next([=](const TextWithEntities &value) {
) | rpl::on_next([=](const TextWithEntities &value) {
staticTitle->setVisible(!value.entities.isEmpty());
}, staticTitle->lifetime());
@@ -650,18 +650,31 @@ void EditFilterBox(
}),
anim::type::instant);
const auto &padding = st::defaultSubsectionTitlePadding;
const auto isPremium = session->premium();
const auto title = Ui::AddSubsectionTitle(
colors,
tr::lng_filters_tag_color_subtitle());
const auto preview = Ui::CreateChild<Ui::RpWidget>(colors);
title->geometryValue(
) | rpl::start_with_next([=](const QRect &r) {
const auto titleWrap = colors->add(
object_ptr<Ui::FixedHeightWidget>(
colors,
rect::m::sum::v(padding)
+ st::defaultSubsectionTitle.style.font->height));
const auto title = Ui::CreateChild<Ui::FlatLabel>(
titleWrap,
tr::lng_filters_tag_color_subtitle(),
st::defaultSubsectionTitle);
title->move(rect::m::pos::tl(padding));
const auto preview = Ui::CreateChild<Ui::RpWidget>(titleWrap);
rpl::combine(
title->sizeValue(),
titleWrap->widthValue()
) | rpl::on_next([=](const QSize &s, int w) {
const auto h = st::normalFont->height;
const auto left = padding.left()
+ s.width()
+ st::settingsFilterTagPreviewSkip;
preview->setGeometry(
rect::right(colors) - st::settingsFilterTagPreviewSkip,
r.y() + (r.height() - h) / 2 + st::lineWidth,
colors->width(),
left,
padding.top() + (s.height() - h) / 2,
w - left,
h);
}, preview->lifetime());
@@ -673,12 +686,16 @@ void EditFilterBox(
};
const auto tag = preview->lifetime().make_state<TagState>();
tag->context.textContext = Core::TextContext({ .session = session });
preview->paintRequest() | rpl::start_with_next([=] {
const auto shift = st::settingsFilterTagPreviewSkip / 2;
preview->paintRequest() | rpl::on_next([=] {
auto p = QPainter(preview);
p.setOpacity(tag->alpha);
const auto size = tag->frame.size() / style::DevicePixelRatio();
const auto rect = QRect(
preview->width() - size.width() - st::boxRowPadding.right(),
preview->width()
- size.width()
- st::boxRowPadding.right()
- shift,
(st::normalFont->height - size.height()) / 2,
size.width(),
size.height());
@@ -688,7 +705,7 @@ void EditFilterBox(
p.setFont(st::normalFont);
p.setPen(st::windowSubTextFg);
p.drawText(
preview->rect() - st::boxRowPadding,
preview->rect().translated(-shift, 0) - st::boxRowPadding,
tr::lng_filters_tag_color_no(tr::now),
style::al_right);
}
@@ -708,7 +725,7 @@ void EditFilterBox(
return value;
};
state->title.changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
tag->context.color = palette(state->colorIndex.current())->c;
tag->frame = Ui::ChatsFilterTag(
upperTitle(),
@@ -768,7 +785,7 @@ void EditFilterBox(
});
}
}
line->sizeValue() | rpl::start_with_next([=](const QSize &size) {
line->sizeValue() | rpl::on_next([=](const QSize &size) {
const auto totalWidth = buttons.size() * side;
const auto spacing = (size.width() - totalWidth)
/ (buttons.size() - 1);
@@ -782,7 +799,7 @@ void EditFilterBox(
const auto last = buttons.back();
const auto icon = Ui::CreateChild<Ui::RpWidget>(last);
icon->resize(side, side);
icon->paintRequest() | rpl::start_with_next([=] {
icon->paintRequest() | rpl::on_next([=] {
auto p = QPainter(icon);
(session->premium()
? st::windowFilterSmallRemove.icon
@@ -836,7 +853,7 @@ void EditFilterBox(
tr::lng_filters_link_has(),
tr::lng_filters_link()));
state->hasLinks.changes() | rpl::start_with_next([=] {
state->hasLinks.changes() | rpl::on_next([=] {
content->resizeToWidth(content->widthNoMargins());
}, content->lifetime());
@@ -869,7 +886,7 @@ void EditFilterBox(
addLink->clicks()
) | rpl::filter(
(rpl::mappers::_1 == Qt::LeftButton)
) | rpl::start_with_next([=](Qt::MouseButton button) {
) | rpl::on_next([=](Qt::MouseButton button) {
const auto result = collect();
if (!result || !GoodForExportFilterLink(window, *result)) {
return;

View File

@@ -384,7 +384,7 @@ object_ptr<Ui::RpWidget> CreatePeerListSectionSubtitle(
const auto raw = result.data();
raw->paintRequest(
) | rpl::start_with_next([=](QRect clip) {
) | rpl::on_next([=](QRect clip) {
auto p = QPainter(raw);
p.fillRect(clip, st::searchedBarBg);
}, raw->lifetime());
@@ -394,7 +394,7 @@ object_ptr<Ui::RpWidget> CreatePeerListSectionSubtitle(
std::move(text),
st::windowFilterChatsSectionSubtitle);
raw->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
const auto padding = st::windowFilterChatsSectionSubtitlePadding;
const auto available = width - padding.left() - padding.right();
label->resizeToNaturalWidth(available);
@@ -533,12 +533,12 @@ object_ptr<Ui::RpWidget> EditFilterChatsListController::prepareTypesList() {
tr::lng_filters_edit_chats()));
controller->selectedChanges(
) | rpl::start_with_next([=](Flags selected) {
) | rpl::on_next([=](Flags selected) {
_selected = selected;
}, _lifetime);
controller->rowSelectionChanges(
) | rpl::start_with_next([=](RowSelectionChange update) {
) | rpl::on_next([=](RowSelectionChange update) {
this->delegate()->peerListSetForeignRowChecked(
update.row,
update.checked,

View File

@@ -531,7 +531,7 @@ void LinkController::addHeader(not_null<Ui::VerticalLayout*> container) {
},
st::settingsFilterIconPadding);
_showFinished.events(
) | rpl::start_with_next([animate = std::move(icon.animate)] {
) | rpl::on_next([animate = std::move(icon.animate)] {
animate(anim::repeat::once);
}, verticalLayout->lifetime());
verticalLayout->add(std::move(icon.widget));
@@ -558,7 +558,7 @@ void LinkController::addHeader(not_null<Ui::VerticalLayout*> container) {
style::al_top)->setTryMakeSimilarLines(true);
verticalLayout->geometryValue(
) | rpl::start_with_next([=](const QRect &r) {
) | rpl::on_next([=](const QRect &r) {
divider->setGeometry(r);
}, divider->lifetime());
}
@@ -647,7 +647,7 @@ void LinkController::addLinkBlock(not_null<Ui::VerticalLayout*> container) {
st::inviteLinkFieldPadding);
label->clicks(
) | rpl::start_with_next(copyLink, label->lifetime());
) | rpl::on_next(copyLink, label->lifetime());
AddCopyShareLinkButtons(container, copyLink, shareLink);
@@ -785,7 +785,7 @@ void LinkController::setupAboveWidget() {
[=](bool select) { toggleAllSelected(select); });
// Fix label cutting on text change from smaller to longer.
_selected.changes() | rpl::start_with_next([=] {
_selected.changes() | rpl::on_next([=] {
container->resizeToWidth(container->widthNoMargins());
}, container->lifetime());
@@ -825,7 +825,7 @@ LinksController::LinksController(
, _currentFilter(std::move(currentFilter))
, _rows(std::move(content)) {
style::PaletteChanged(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
for (auto &image : _icons) {
image = QImage();
}
@@ -834,7 +834,7 @@ LinksController::LinksController(
void LinksController::prepare() {
_rows.value(
) | rpl::start_with_next([=](const std::vector<InviteLinkData> &rows) {
) | rpl::on_next([=](const std::vector<InviteLinkData> &rows) {
rebuild(rows);
}, _lifetime);
}
@@ -1078,7 +1078,7 @@ object_ptr<Ui::BoxContent> ShowLinkBox(
const auto saving = std::make_shared<bool>(false);
raw->hasChangesValue(
) | rpl::start_with_next([=](bool has) {
) | rpl::on_next([=](bool has) {
box->setCloseByOutsideClick(!has);
box->setCloseByEscape(!has);
box->clearButtons();
@@ -1182,7 +1182,7 @@ void AddFilterSubtitleWithToggles(
const auto canSelect = link->lifetime().make_state<rpl::variable<bool>>(
std::move(selectedCount) | rpl::map(_1 < selectableCount));
canSelect->value(
) | rpl::start_with_next([=](bool can) {
) | rpl::on_next([=](bool can) {
link->setText(can
? tr::lng_filters_by_link_select(tr::now)
: tr::lng_filters_by_link_deselect(tr::now));
@@ -1195,7 +1195,7 @@ void AddFilterSubtitleWithToggles(
container->widthValue(),
title->topValue(),
link->widthValue()
) | rpl::start_with_next([=](int outer, int y, int width) {
) | rpl::on_next([=](int outer, int y, int width) {
link->move(outer - st::boxRowPadding.right() - width, y);
}, link->lifetime());
}

View File

@@ -83,9 +83,12 @@ namespace {
constexpr auto kTooltipDuration = 3 * crl::time(1000);
constexpr auto kHorizontalBar = QChar(0x2015);
constexpr auto kSpinnerRows = 6;
constexpr auto kSpinDuration = crl::time(120);
using Ui::AddTableRow;
using Ui::TableRowTooltipData;
using SpinnerState = Data::GiftUpgradeSpinner::State;
[[nodiscard]] QString CreateMessageLink(
not_null<Main::Session*> session,
@@ -151,7 +154,7 @@ using Ui::TableRowTooltipData;
auto result = object_ptr<Ui::RpWidget>(parent);
const auto raw = result.data();
raw->paintRequest() | rpl::start_with_next([=] {
raw->paintRequest() | rpl::on_next([=] {
auto p = QPainter(raw);
const auto &icon = st::giveawayGiftCodeLinkCopy;
const auto left = (raw->width() - icon.width()) / 2;
@@ -276,10 +279,179 @@ using Ui::TableRowTooltipData;
return MakeValueWithSmallButton(table, label, std::move(text), handler);
}
[[nodiscard]] object_ptr<Ui::RpWidget> MakeAttributeValue(
not_null<Ui::TableLayout*> table,
const Data::UniqueGiftAttribute &attribute,
Fn<void(not_null<Ui::RpWidget*>, int)> showTooltip,
std::shared_ptr<Data::GiftUpgradeSpinner> spinner,
std::vector<Data::UniqueGiftAttribute> spinning,
SpinnerState finishedState) {
if (!spinner) {
return MakeAttributeValue(table, attribute, showTooltip);
}
auto result = object_ptr<Ui::RpWidget>(table);
const auto raw = result.get();
struct Row {
Data::UniqueGiftAttribute attribute;
object_ptr<Ui::RpWidget> widget;
QImage frame;
};
struct State {
int wasIndex = 0;
int nowIndex = 0;
std::vector<Row> rows;
Ui::Animations::Simple animation;
QImage fading;
Fn<void()> repaint;
bool finished = false;
};
const auto state = raw->lifetime().make_state<State>();
state->repaint = [=] { raw->update(); };
const auto margin = st::giveawayGiftCodeValueMargin;
const auto startWithin = [=] {
Expects(!state->rows.empty());
state->wasIndex = state->nowIndex;
state->nowIndex = (state->nowIndex + 1) % state->rows.size();
state->animation.start(state->repaint, 0., 1., kSpinDuration);
};
const auto startToTarget = [=] {
if (state->nowIndex != 0) {
state->wasIndex = state->nowIndex;
state->nowIndex = 0;
state->animation.start(
state->repaint,
0.,
1.,
kSpinDuration * 3,
anim::easeOutCubic);
}
};
const auto add = [&](const Data::UniqueGiftAttribute &value) {
if (state->rows.size() >= kSpinnerRows) {
return false;
}
const auto already = ranges::contains(
state->rows,
value,
&Row::attribute);
if (!already) {
state->rows.push_back(Row{
.attribute = value,
.widget = MakeAttributeValue(table, value, showTooltip),
});
const auto widget = state->rows.back().widget.get();
widget->setParent(raw);
widget->hide();
}
return true;
};
add(attribute);
for (const auto &item : spinning) {
if (!add(item)) {
break;
}
}
raw->widthValue() | rpl::on_next([=](int width) {
auto height = 0;
const auto inner = width - margin.left() - margin.right();
if (inner > 0) {
for (const auto &row : state->rows) {
row.widget->resizeToWidth(inner);
row.widget->move(margin.left(), margin.top());
height = std::max(height, row.widget->height());
}
}
raw->resize(width, margin.top() + height + margin.bottom());
crl::on_main(raw, [=] {
for (const auto &row : state->rows) {
Ui::SendPendingMoveResizeEvents(row.widget.get());
}
});
}, raw->lifetime());
style::PaletteChanged() | rpl::on_next([=] {
for (auto &row : state->rows) {
row.frame = QImage();
}
state->fading = QImage();
}, raw->lifetime());
raw->paintOn([=](QPainter &p) {
if (state->finished) {
return;
}
auto progress = state->animation.value(1.);
if (progress >= 1.) {
const auto ending = (spinner->state.current() >= finishedState);
if (ending) {
startToTarget();
} else {
startWithin();
}
progress = state->animation.value(1.);
if (ending && progress >= 1.) {
state->rows.front().widget->show();
state->finished = true;
return;
}
}
const auto ratio = style::DevicePixelRatio();
const auto h = raw->height();
if (state->fading.height() != h * ratio) {
state->fading = QImage(
QSize(1, h) * ratio,
QImage::Format_ARGB32_Premultiplied);
state->fading.setDevicePixelRatio(ratio);
state->fading.fill(Qt::transparent);
auto q = QPainter(&state->fading);
auto brush = QLinearGradient(0, 0, 0, margin.top());
brush.setStops({
{ 0., anim::with_alpha(st::boxBg->c, 1.) },
{ 1., anim::with_alpha(st::boxBg->c, 0.) },
});
q.fillRect(0, 0, 1, margin.top(), brush);
brush.setStart(0, h);
brush.setFinalStop(0, h - margin.bottom());
q.fillRect(0, h - margin.bottom(), 1, margin.bottom(), brush);
}
auto &was = state->rows[state->wasIndex];
auto &now = state->rows[state->nowIndex];
const auto validate = [&](Row &row) {
const auto size = row.widget->size();
if (row.frame.size() != size * ratio) {
row.frame = Ui::GrabWidgetToImage(row.widget.get());
}
};
validate(was);
validate(now);
const auto t = progress * (margin.top() + was.widget->height());
const auto b = progress * (now.widget->height() + margin.bottom());
p.drawImage(
margin.left(),
margin.top() - int(base::SafeRound(t)),
was.frame);
p.drawImage(
margin.left(),
raw->height() - int(base::SafeRound(b)),
now.frame);
p.drawImage(raw->rect(), state->fading);
});
startWithin();
return result;
}
void AddUniqueGiftPropertyRows(
not_null<Ui::RpWidget*> container,
not_null<Ui::TableLayout*> table,
not_null<Data::UniqueGift*> unique) {
not_null<Data::UniqueGift*> unique,
std::shared_ptr<Data::GiftUpgradeSpinner> spinner) {
const auto tooltip = std::make_shared<TableRowTooltipData>(
TableRowTooltipData{ .parent = container });
const auto showTooltip = [=](
@@ -296,18 +468,55 @@ void AddUniqueGiftPropertyRows(
rpl::single(TextWithEntities{ percent }),
Ui::Text::WithEntities));
};
const auto empty = std::vector<Data::UniqueGiftAttribute>();
const auto extract = [&](const auto &list) {
auto result = empty;
result.reserve(list.size());
for (const auto &item : list) {
result.push_back(item);
}
return result;
};
const auto attributes = spinner ? &spinner->attributes : nullptr;
const auto models = spinner ? extract(attributes->models) : empty;
const auto patterns = spinner ? extract(attributes->patterns) : empty;
const auto backdrops = spinner ? extract(attributes->backdrops) : empty;
const auto margin = spinner
? style::margins()
: st::giveawayGiftCodeValueMargin;
AddTableRow(
table,
tr::lng_gift_unique_model(),
MakeAttributeValue(table, unique->model, showRarity));
AddTableRow(
table,
tr::lng_gift_unique_backdrop(),
MakeAttributeValue(table, unique->backdrop, showRarity));
MakeAttributeValue(
table,
unique->model,
showRarity,
spinner,
models,
SpinnerState::FinishedModel),
margin);
AddTableRow(
table,
tr::lng_gift_unique_symbol(),
MakeAttributeValue(table, unique->pattern, showRarity));
MakeAttributeValue(
table,
unique->pattern,
showRarity,
spinner,
patterns,
SpinnerState::FinishedPattern),
margin);
AddTableRow(
table,
tr::lng_gift_unique_backdrop(),
MakeAttributeValue(
table,
unique->backdrop,
showRarity,
spinner,
backdrops,
SpinnerState::FinishedBackdrop),
margin);
}
[[nodiscard]] object_ptr<Ui::RpWidget> MakeStarGiftStarsValue(
@@ -316,8 +525,17 @@ void AddUniqueGiftPropertyRows(
const Data::CreditsHistoryEntry &entry,
Fn<void()> convertToStars) {
auto helper = Ui::Text::CustomEmojiHelper();
const auto addUpgradeToValue = !entry.credits.ton()
&& !entry.giftUpgradeGifted
&& !entry.giftUpgradeSeparate
&& entry.starsUpgradedBySender;
const auto amount = addUpgradeToValue
? CreditsAmount(
entry.credits.whole() + entry.starsUpgradedBySender,
entry.credits.nano())
: entry.credits;
const auto price = helper.paletteDependent(Ui::Earn::IconCreditsEmoji(
)).append(' ').append(Lang::FormatCreditsAmountDecimal(entry.credits));
)).append(' ').append(Lang::FormatCreditsAmountDecimal(amount));
auto label = object_ptr<Ui::FlatLabel>(
table,
rpl::single(price),
@@ -362,6 +580,7 @@ void AddUniqueGiftPropertyRows(
const auto handler = [=](not_null<Ui::RpWidget*> button) {
if (value->initialPriceStars) {
show->show(Box(Settings::UniqueGiftValueBox, show, entry, st));
return;
} else if (*loading) {
return;
}
@@ -450,7 +669,7 @@ void AddTable(
? tr::lng_gift_link_reason_giveaway
: tr::lng_gift_link_reason_unclaimed)(
Ui::Text::WithEntities
) | rpl::type_erased())
) | rpl::type_erased)
: tr::lng_gift_link_reason_chosen(Ui::Text::WithEntities)));
reason->setClickHandlerFilter([=](const auto &...) {
if (const auto window = show->resolveWindow()) {
@@ -631,7 +850,7 @@ void GiftCodeBox(
box->closeBox();
});
box->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
close->moveToRight(0, 0);
}, box->lifetime());
@@ -718,7 +937,7 @@ void GiftCodePendingBox(
spoiler->update();
})->start();
linkLabel->sizeValue(
) | rpl::start_with_next([=](const QSize &s) {
) | rpl::on_next([=](const QSize &s) {
spoiler->setGeometry(Rect(s));
}, spoiler->lifetime());
const auto spoilerCached = Ui::SpoilerMessCached(
@@ -726,7 +945,7 @@ void GiftCodePendingBox(
st::giveawayGiftCodeLink.textFg->c);
const auto textHeight = st::giveawayGiftCodeLink.style.font->height;
spoiler->paintRequest(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
auto p = QPainter(spoiler);
const auto rect = spoiler->rect();
const auto r = rect
@@ -760,7 +979,7 @@ void GiftCodePendingBox(
const auto closeCallback = [=] { box->closeBox(); };
close->setClickedCallback(closeCallback);
box->widthValue(
) | rpl::start_with_next([=](int width) {
) | rpl::on_next([=](int width) {
close->moveToRight(0, 0);
}, box->lifetime());
@@ -853,7 +1072,7 @@ void GiveawayInfoBox(
std::move(label),
QMargins(0, skip, 0, skip)),
style::al_justify);
result->paintRequest() | rpl::start_with_next([=] {
result->paintRequest() | rpl::on_next([=] {
auto p = QPainter(result);
p.setPen(Qt::NoPen);
p.setBrush(st::boxDividerBg);
@@ -1050,7 +1269,7 @@ void GiveawayInfoBox(
const auto bg = wrap->lifetime().make_state<Ui::RoundRect>(
st::boxRadius,
st::attentionBoxButton.textBgOver);
wrap->paintRequest() | rpl::start_with_next([=] {
wrap->paintRequest() | rpl::on_next([=] {
auto p = QPainter(wrap);
bg->paint(p, wrap->rect());
}, wrap->lifetime());
@@ -1132,7 +1351,7 @@ struct AddedUniqueDetails {
const auto icon = Ui::CreateChild<Ui::IconButton>(
raw,
st::giveawayGiftMessageRemove);
raw->widthValue() | rpl::start_with_next([=](int outer) {
raw->widthValue() | rpl::on_next([=](int outer) {
label->resizeToWidth(outer - icon->width());
const auto height = std::max(label->height(), icon->height());
@@ -1194,8 +1413,9 @@ void AddStarGiftTable(
not_null<Ui::VerticalLayout*> container,
Settings::CreditsEntryBoxStyleOverrides st,
const Data::CreditsHistoryEntry &entry,
std::shared_ptr<Data::GiftUpgradeSpinner> spinner,
Fn<void()> convertToStars,
Fn<void()> startUpgrade,
bool canStartUpgrade,
Fn<void(Fn<void()> removed)> removeDetails) {
const auto table = container->add(
object_ptr<Ui::TableLayout>(
@@ -1328,6 +1548,15 @@ void AddStarGiftTable(
PeerId(entry.bareEntryOwnerId)),
st::giveawayGiftCodePeerMargin);
}
} else if (entry.auction && entry.bareGiftOwnerId) {
AddTableRow(
table,
tr::lng_credits_box_history_entry_peer(),
MakePeerTableValue(
table,
show,
PeerId(entry.bareGiftOwnerId)),
st::giveawayGiftCodePeerMargin);
} else if (peerId && !giftToSelf) {
const auto user = session->data().peer(peerId)->asUser();
const auto withSendButton = entry.in && user && !user->isBot();
@@ -1370,7 +1599,7 @@ void AddStarGiftTable(
rpl::single(Ui::Text::WithEntities(langDateTime(entry.date))));
}
if (unique) {
AddUniqueGiftPropertyRows(container, table, unique);
AddUniqueGiftPropertyRows(container, table, unique, spinner);
} else {
AddTableRow(
table,
@@ -1407,7 +1636,7 @@ void AddStarGiftTable(
std::move(amount),
Ui::Text::WithEntities)));
}
if (!unique && !entry.soldOutInfo && startUpgrade) {
if (!unique && !entry.soldOutInfo && canStartUpgrade) {
AddTableRow(
table,
tr::lng_gift_unique_status(),
@@ -1517,7 +1746,7 @@ void AddTransferGiftTable(
container,
st::giveawayGiftCodeTable),
st::giveawayGiftCodeTableMargin);
AddUniqueGiftPropertyRows(container, table, unique.get());
AddUniqueGiftPropertyRows(container, table, unique.get(), nullptr);
if (const auto value = unique->value.get()) {
AddTableRow(
table,
@@ -1598,11 +1827,30 @@ void AddCreditsHistoryEntryTable(
: entry.giftUpgraded
? tr::lng_credits_box_history_entry_gift_from()
: tr::lng_credits_box_history_entry_peer();
const auto targetId = actorId ? actorId : peerId;
const auto isPeerDefault = !entry.starrefCommission
&& !entry.in
&& !entry.giftResale
&& !entry.giftUpgraded;
const auto user = isPeerDefault
? session->data().peer(targetId)->asUser()
: nullptr;
const auto withSendButton = user
&& !user->isInaccessible()
&& !user->isBot();
auto send = withSendButton ? tr::lng_gift_send_small() : nullptr;
auto handler = send
? Fn<void()>([=] {
if (const auto window = show->resolveWindow()) {
Ui::ShowStarGiftBox(window, user);
}
})
: nullptr;
AddTableRow(
table,
std::move(text),
show,
actorId ? actorId : peerId);
MakePeerTableValue(table, show, targetId, send, handler),
st::giveawayGiftCodePeerMargin);
}
if (const auto msgId = MsgId(peerId ? entry.bareMsgId : 0)) {
const auto peer = session->data().peer(peerId);
@@ -1762,6 +2010,19 @@ void AddCreditsHistoryEntryTable(
rpl::single(
Ui::Text::Link(entry.successLink, entry.successLink)));
}
if (entry.limitedCount > 0 && entry.limitedLeft >= 0) {
AddTableRow(
table,
tr::lng_gift_availability(),
tr::lng_gift_availability_left(
lt_count_decimal,
rpl::single(entry.limitedLeft) | tr::to_count(),
lt_amount,
rpl::single(TextWithEntities{
Lang::FormatCountDecimal(entry.limitedCount)
}),
Ui::Text::WithEntities));
}
}
void AddSubscriptionEntryTable(

View File

@@ -24,6 +24,7 @@ struct GiveawayStart;
struct GiveawayResults;
struct SubscriptionEntry;
struct UniqueGift;
struct GiftUpgradeSpinner;
} // namespace Data
namespace Main {
@@ -77,8 +78,9 @@ void AddStarGiftTable(
not_null<Ui::VerticalLayout*> container,
Settings::CreditsEntryBoxStyleOverrides st,
const Data::CreditsHistoryEntry &entry,
std::shared_ptr<Data::GiftUpgradeSpinner> spinner,
Fn<void()> convertToStars,
Fn<void()> startUpgrade,
bool canStartUpgrade,
Fn<void(Fn<void()> removed)> removeDetails);
void AddTransferGiftTable(
std::shared_ptr<ChatHelpers::Show> show,

View File

@@ -908,7 +908,7 @@ void Content::setupContent(
inner,
st::defaultBox.margin.top()));
rows->isEmpty() | rpl::start_with_next([=](bool empty) {
rows->isEmpty() | rpl::on_next([=](bool empty) {
wrap->toggle(!empty, anim::type::instant);
}, rows->lifetime());
@@ -931,7 +931,7 @@ void Content::setupContent(
tr::lng_languages_none(),
st::membersAbout);
empty->entity()->sizeValue(
) | rpl::start_with_next([=](QSize size) {
) | rpl::on_next([=](QSize size) {
label->move(
(size.width() - label->width()) / 2,
(size.height() - label->height()) / 2);
@@ -951,7 +951,7 @@ void Content::setupContent(
main->isEmpty(),
other->isEmpty(),
_1 || _2
) | rpl::start_with_next([=](bool empty) {
) | rpl::on_next([=](bool empty) {
divider->toggle(!empty, anim::type::instant);
}, divider->lifetime());
@@ -959,7 +959,7 @@ void Content::setupContent(
a->hasSelection(
) | rpl::filter(
_1
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
b->setSelected(-1);
}, a->lifetime());
};
@@ -1048,7 +1048,7 @@ void Content::setupContent(
};
_activations = [=] {
if (!main && !other) {
return rpl::never<Language>() | rpl::type_erased();
return rpl::never<Language>() | rpl::type_erased;
} else if (!main) {
return other->activations();
} else if (!other) {
@@ -1057,7 +1057,7 @@ void Content::setupContent(
return rpl::merge(
main->activations(),
other->activations()
) | rpl::type_erased();
) | rpl::type_erased;
};
_changeChosen = [=](const QString &chosen) {
if (main) {
@@ -1134,12 +1134,12 @@ void LanguageBox::prepare() {
inner->heightValue(),
topContainer->heightValue(),
_1 + _2
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
accumulate_max(*max, height);
setDimensions(st::boxWidth, qMin(*max, st::boxMaxListHeight));
}, inner->lifetime());
topContainer->heightValue(
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
setInnerTopSkip(height);
}, inner->lifetime());
@@ -1154,7 +1154,7 @@ void LanguageBox::prepare() {
});
inner->activations(
) | rpl::start_with_next([=](const Language &language) {
) | rpl::on_next([=](const Language &language) {
// "#custom" is applied each time it's passed to switchToLanguage().
// So we check that the language really has changed.
const auto currentId = [] {
@@ -1190,7 +1190,7 @@ void LanguageBox::setupTop(not_null<Ui::VerticalLayout*> container) {
translateEnabled->toggledValue(
) | rpl::filter([](bool checked) {
return (checked != Core::App().settings().translateButtonEnabled());
}) | rpl::start_with_next([=](bool checked) {
}) | rpl::on_next([=](bool checked) {
Core::App().settings().setTranslateButtonEnabled(checked);
Core::App().saveSettingsDelayed();
}, translateEnabled->lifetime());
@@ -1207,7 +1207,7 @@ void LanguageBox::setupTop(not_null<Ui::VerticalLayout*> container) {
rpl::duplicate(premium),
_1 && _2),
_translateChatTurnOff.events()));
std::move(premium) | rpl::start_with_next([=](bool value) {
std::move(premium) | rpl::on_next([=](bool value) {
translateChat->setToggleLocked(!value);
}, translateChat->lifetime());
@@ -1222,7 +1222,7 @@ void LanguageBox::setupTop(not_null<Ui::VerticalLayout*> container) {
}
return premium
&& (checked != Core::App().settings().translateChatEnabled());
}) | rpl::start_with_next([=](bool checked) {
}) | rpl::on_next([=](bool checked) {
Core::App().settings().setTranslateChatEnabled(checked);
Core::App().saveSettingsDelayed();
}, translateChat->lifetime());
@@ -1300,7 +1300,7 @@ base::binary_guard LanguageBox::Show(Window::SessionController *controller) {
manager.languageListChanged(
) | rpl::take(
1
) | rpl::start_with_next([=]() mutable {
) | rpl::on_next([=]() mutable {
const auto show = guard->alive();
if (lifetime) {
base::take(lifetime)->destroy();

View File

@@ -288,7 +288,7 @@ void LocalStorageBox::Show(not_null<Window::SessionController*> controller) {
rpl::combine(
controller->session().data().cache().statsOnMain(),
controller->session().data().cacheBigFile().statsOnMain()
) | rpl::start_with_next([=](
) | rpl::on_next([=](
Database::Stats &&stats,
Database::Stats &&statsBig) {
weak->update(std::move(stats), std::move(statsBig));
@@ -379,7 +379,7 @@ void LocalStorageBox::setupControls() {
const auto shown = (data.count && data.totalSize) || !tag;
result->toggle(shown, anim::type::instant);
result->entity()->clearRequests(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
clearByTag(tag);
}, result->lifetime());
_rows.emplace(tag, result);
@@ -431,7 +431,7 @@ void LocalStorageBox::setupControls() {
);
container->resizeToWidth(st::boxWidth);
container->heightValue(
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
setDimensions(st::boxWidth, height);
}, container->lifetime());
}

View File

@@ -77,7 +77,7 @@ void MaxInviteBox::prepare() {
_channel->session().changes().peerUpdates(
_channel,
Data::PeerUpdate::Flag::InviteLinks
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
rtlupdate(_invitationLink);
}, lifetime());
}

View File

@@ -118,7 +118,7 @@ ModerateOptions CalculateModerateOptions(const HistoryItemsList &items) {
const auto peer = from[state->index];
const auto peerId = peer->id;
state->apiLifetime = search->messagesFounds(
) | rpl::start_with_next([=](const Api::FoundMessages &found) {
) | rpl::on_next([=](const Api::FoundMessages &found) {
state->messagesCounts[peerId] = found.total;
state->index++;
repeat(repeat);
@@ -201,7 +201,7 @@ void CreateModerateMessagesBox(
not_null<Ui::Checkbox*> checkbox,
not_null<Controller*> controller,
Request request) {
confirms->events() | rpl::start_with_next([=] {
confirms->events() | rpl::on_next([=] {
if (checkbox->checked() && controller->collectRequests) {
sequentiallyRequest(request, controller->collectRequests());
}
@@ -354,7 +354,7 @@ void CreateModerateMessagesBox(
}
return float64(result);
})
) | rpl::start_with_next([=](const QString &text) {
) | rpl::on_next([=](const QString &text) {
title->setText(text);
title->resizeToWidth(inner->width()
- rect::m::sum::h(st::boxRowPadding));
@@ -386,7 +386,7 @@ void CreateModerateMessagesBox(
rpl::conditional(
(ownedWrap
? ownedWrap->toggledValue()
: rpl::single(false) | rpl::type_erased()),
: rpl::single(false) | rpl::type_erased),
tr::lng_restrict_user(
lt_count,
rpl::single(participants.size()) | tr::to_count()),
@@ -432,7 +432,7 @@ void CreateModerateMessagesBox(
}
wrap->toggle(!wrap->toggled(), anim::type::normal);
{
inner->heightValue() | rpl::start_with_next([=] {
inner->heightValue() | rpl::on_next([=] {
if (!wrap->animating()) {
scrollLifetime->destroy();
Ui::PostponeCall(crl::guard(box, [=] {
@@ -458,7 +458,7 @@ void CreateModerateMessagesBox(
rpl::single(toggled ? emojiUp : emojiDown),
Ui::Text::WithEntities);
}) | rpl::flatten_latest(
) | rpl::start_with_next([=](const TextWithEntities &text) {
) | rpl::on_next([=](const TextWithEntities &text) {
raw->setMarkedText(Ui::Text::Link(text, u"internal:"_q));
}, label->lifetime());
@@ -509,7 +509,7 @@ void CreateModerateMessagesBox(
disabledMessages,
{ .isForum = peer->isForum() });
computeRestrictions = getRestrictions;
std::move(changes) | rpl::start_with_next([=] {
std::move(changes) | rpl::on_next([=] {
ban->setChecked(true);
}, ban->lifetime());
Ui::AddSkip(container);
@@ -519,7 +519,7 @@ void CreateModerateMessagesBox(
}
// Handle confirmation manually.
confirms->events() | rpl::start_with_next([=] {
confirms->events() | rpl::on_next([=] {
if (ban->checked() && controller->collectRequests) {
const auto kick = !wrap || !wrap->toggled();
const auto restrictions = computeRestrictions
@@ -627,7 +627,7 @@ void DeleteChatBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
? tr::lng_profile_delete_conversation() | Ui::Text::ToBold()
: rpl::single(
userpicPeer->name()
) | Ui::Text::ToBold() | rpl::type_erased(),
) | Ui::Text::ToBold() | rpl::type_erased,
box->getDelegate()->style().title));
Ui::AddSkip(container);

View File

@@ -47,7 +47,7 @@ void SetCloudPassword(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session) {
session->api().cloudPassword().state(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
using namespace Settings;
const auto weak = base::make_weak(box);
if (CheckEditCloudPassword(session)) {
@@ -120,7 +120,7 @@ void StartPendingReset(
};
session->api().cloudPassword().resetPassword(
) | rpl::start_with_next_error_done([=](
) | rpl::on_next_error_done([=](
Api::CloudPassword::ResetRetryDate retryDate) {
constexpr auto kMinute = 60;
constexpr auto kHour = 3600;
@@ -309,11 +309,11 @@ void PasscodeBox::prepare() {
connect(_newPasscode, &Ui::MaskedInputField::changed, [=] { newChanged(); });
connect(_reenterPasscode, &Ui::MaskedInputField::changed, [=] { newChanged(); });
_passwordHint->changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
newChanged();
}, _passwordHint->lifetime());
_recoverEmail->changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
if (!_emailError.isEmpty()) {
_emailError = QString();
update();
@@ -325,9 +325,9 @@ void PasscodeBox::prepare() {
connect(_newPasscode, &Ui::MaskedInputField::submitted, fieldSubmit);
connect(_reenterPasscode, &Ui::MaskedInputField::submitted, fieldSubmit);
_passwordHint->submits(
) | rpl::start_with_next(fieldSubmit, _passwordHint->lifetime());
) | rpl::on_next(fieldSubmit, _passwordHint->lifetime());
_recoverEmail->submits(
) | rpl::start_with_next(fieldSubmit, _recoverEmail->lifetime());
) | rpl::on_next(fieldSubmit, _recoverEmail->lifetime());
_recover->addClickHandler([=] { recoverByEmail(); });
@@ -607,7 +607,7 @@ void PasscodeBox::validateEmail(
box->boxClosing(
) | rpl::filter([=] {
return !*set;
}) | start_with_next([=, weak = base::make_weak(this)] {
}) | on_next([=, weak = base::make_weak(this)] {
if (weak) {
weak->_clearUnconfirmedPassword.fire({});
}
@@ -1117,7 +1117,7 @@ void PasscodeBox::recover() {
) | rpl::start_to_stream(_newPasswordSet, lifetime());
box->recoveryExpired(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
recoverExpired();
}, lifetime());
@@ -1207,11 +1207,11 @@ void RecoverBox::prepare() {
updateHeight();
_recoverCode->changes(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
codeChanged();
}, _recoverCode->lifetime());
_recoverCode->submits(
) | rpl::start_with_next([=] { submit(); }, _recoverCode->lifetime());
) | rpl::on_next([=] { submit(); }, _recoverCode->lifetime());
}
void RecoverBox::paintEvent(QPaintEvent *e) {
@@ -1342,7 +1342,7 @@ void RecoverBox::proceedToChange(const QString &code) {
auto box = Box<PasscodeBox>(_session, fields);
box->boxClosing(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
const auto weak = base::make_weak(this);
if (const auto onstack = _closeParent) {
onstack();
@@ -1353,7 +1353,7 @@ void RecoverBox::proceedToChange(const QString &code) {
}, lifetime());
box->newPasswordSet(
) | rpl::start_with_next([=](QByteArray &&password) {
) | rpl::on_next([=](QByteArray &&password) {
_newPasswordSet.fire(std::move(password));
}, lifetime());

View File

@@ -113,7 +113,7 @@ void PeerListBox::createMultiSelect() {
tr::lng_participant_filter());
_select.create(this, std::move(entity));
_select->heightValue(
) | rpl::start_with_next(
) | rpl::on_next(
[this] { updateScrollSkips(); },
lifetime());
_select->entity()->setSubmittedCallback([=](Qt::KeyboardModifiers) {
@@ -191,7 +191,7 @@ void PeerListBox::prepare() {
_controller->setDelegate(this);
_controller->boxHeightValue(
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
setDimensions(_controller->contentWidth(), height);
}, lifetime());
@@ -203,7 +203,7 @@ void PeerListBox::prepare() {
}
content()->scrollToRequests(
) | rpl::start_with_next([this](Ui::ScrollToRequest request) {
) | rpl::on_next([this](Ui::ScrollToRequest request) {
scrollToY(request.ymin, request.ymax);
}, lifetime());
@@ -1002,14 +1002,14 @@ PeerListContent::PeerListContent(
, _controller(controller)
, _rowHeight(_st.item.height) {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
update();
}, lifetime());
using UpdateFlag = Data::PeerUpdate::Flag;
_controller->session().changes().peerUpdates(
UpdateFlag::Name | UpdateFlag::Photo | UpdateFlag::EmojiStatus
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
) | rpl::on_next([=](const Data::PeerUpdate &update) {
if (update.flags & UpdateFlag::Name) {
handleNameChanged(update.peer);
}
@@ -1019,7 +1019,7 @@ PeerListContent::PeerListContent(
}, lifetime());
style::PaletteChanged(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
invalidatePixmapsCache();
}, lifetime());
@@ -1387,10 +1387,10 @@ void PeerListContent::initDecorateWidget(Ui::RpWidget *widget) {
widget->events(
) | rpl::filter([=](not_null<QEvent*> e) {
return (e->type() == QEvent::Enter) && widget->isVisible();
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
mouseLeftGeometry();
}, widget->lifetime());
widget->heightValue() | rpl::skip(1) | rpl::start_with_next([=] {
widget->heightValue() | rpl::skip(1) | rpl::on_next([=] {
resizeToWidth(width());
}, widget->lifetime());
}

View File

@@ -117,7 +117,7 @@ object_ptr<Ui::BoxContent> PrepareContactsBox(
});
raw->setSortMode(Mode::Online);
raw->wheelClicks() | rpl::start_with_next([=](not_null<PeerData*> p) {
raw->wheelClicks() | rpl::on_next([=](not_null<PeerData*> p) {
sessionController->showInNewWindow(p);
}, box->lifetime());
};
@@ -385,7 +385,7 @@ void TrackMessageMoneyRestrictionsChanges(
rpl::merge(
Data::AmPremiumValue(session) | rpl::to_empty,
session->api().premium().someMessageMoneyRestrictionsResolved()
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
const auto st = &controller->computeListSt().item;
const auto delegate = controller->delegate();
const auto process = [&](not_null<PeerListRow*> raw) {
@@ -431,18 +431,18 @@ void ChatsListBoxController::prepare() {
session().data().chatsListLoadedEvents(
) | rpl::filter([=](Data::Folder *folder) {
return !folder;
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
checkForEmptyRows();
}, lifetime());
}
session().data().chatsListChanges(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
rebuildRows();
}, lifetime());
session().data().contactsLoaded().value(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
rebuildRows();
}, lifetime());
}
@@ -586,14 +586,14 @@ void PeerListStories::prepare(not_null<PeerListDelegate*> delegate) {
_delegate = delegate;
_unreadBrush = PeerListStoriesGradient(_controller->computeListSt());
style::PaletteChanged() | rpl::start_with_next([=] {
style::PaletteChanged() | rpl::on_next([=] {
_unreadBrush = PeerListStoriesGradient(_controller->computeListSt());
updateColors();
}, _lifetime);
_session->changes().peerUpdates(
Data::PeerUpdate::Flag::StoriesState
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
) | rpl::on_next([=](const Data::PeerUpdate &update) {
const auto id = update.peer->id.value;
if (const auto row = _delegate->peerListFindRow(id)) {
process(row);
@@ -601,7 +601,7 @@ void PeerListStories::prepare(not_null<PeerListDelegate*> delegate) {
}, _lifetime);
const auto stories = &_session->data().stories();
stories->sourceChanged() | rpl::start_with_next([=](PeerId id) {
stories->sourceChanged() | rpl::on_next([=](PeerId id) {
const auto source = stories->source(id);
const auto info = source
? source->info()
@@ -662,7 +662,7 @@ void ContactsBoxController::prepare() {
}
session().data().contactsLoaded().value(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
rebuildRows();
}, lifetime());
}
@@ -724,7 +724,7 @@ void ContactsBoxController::setSortMode(SortMode mode) {
) | rpl::filter([=](const Data::PeerUpdate &update) {
return !_sortByOnlineTimer.isActive()
&& delegate()->peerListFindRow(update.peer->id.value);
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
_sortByOnlineTimer.callOnce(kSortByOnlineThrottle);
}, _sortByOnlineLifetime);
} else {
@@ -874,7 +874,7 @@ void ChooseRecipientBoxController::rowClicked(not_null<PeerListRow*> row) {
});
forum->destroyed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
box->closeBox();
}, box->lifetime());
});
@@ -913,7 +913,7 @@ void ChooseRecipientBoxController::rowClicked(not_null<PeerListRow*> row) {
});
monoforum->destroyed(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
box->closeBox();
}, box->lifetime());
});
@@ -1098,12 +1098,12 @@ ChooseTopicBoxController::ChooseTopicBoxController(
setStyleOverrides(&st::chooseTopicList);
_forum->chatsListChanges(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
refreshRows();
}, lifetime());
_forum->topicDestroyed(
) | rpl::start_with_next([=](not_null<Data::ForumTopic*> topic) {
) | rpl::on_next([=](not_null<Data::ForumTopic*> topic) {
const auto id = PeerListRowId(topic->rootId().bare);
if (const auto row = delegate()->peerListFindRow(id)) {
delegate()->peerListRemoveRow(row);
@@ -1133,7 +1133,7 @@ void ChooseTopicBoxController::prepare() {
session().changes().entryUpdates(
Data::EntryUpdate::Flag::Repaint
) | rpl::start_with_next([=](const Data::EntryUpdate &update) {
) | rpl::on_next([=](const Data::EntryUpdate &update) {
if (const auto topic = update.entry->asTopic()) {
if (topic->forum() == _forum) {
const auto id = topic->rootId().bare;
@@ -1200,12 +1200,12 @@ ChooseSublistBoxController::ChooseSublistBoxController(
setStyleOverrides(&st::chooseTopicList);
_monoforum->chatsListChanges(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
refreshRows();
}, lifetime());
_monoforum->sublistDestroyed(
) | rpl::start_with_next([=](not_null<Data::SavedSublist*> sublist) {
) | rpl::on_next([=](not_null<Data::SavedSublist*> sublist) {
const auto id = sublist->sublistPeer()->id.value;
if (const auto row = delegate()->peerListFindRow(id)) {
delegate()->peerListRemoveRow(row);
@@ -1235,7 +1235,7 @@ void ChooseSublistBoxController::prepare() {
session().changes().entryUpdates(
Data::EntryUpdate::Flag::Repaint
) | rpl::start_with_next([=](const Data::EntryUpdate &update) {
) | rpl::on_next([=](const Data::EntryUpdate &update) {
if (const auto sublist = update.entry->asSublist()) {
if (sublist->parent() == _monoforum) {
const auto id = sublist->sublistPeer()->id.value;

View File

@@ -25,7 +25,7 @@ PeerListWidgets::PeerListWidgets(
, _controller(controller)
, _st(controller->computeListSt()) {
_content = base::make_unique_q<Ui::VerticalLayout>(this);
parent->sizeValue() | rpl::start_with_next([this](const QSize &size) {
parent->sizeValue() | rpl::on_next([this](const QSize &size) {
_content->resizeToWidth(size.width());
resize(size.width(), _content->height());
}, lifetime());
@@ -129,7 +129,7 @@ void PeerListWidgets::appendRow(std::unique_ptr<PeerListRow> row) {
st.button.ripple,
st.button.textBgOver)));
widget->resize(widget->width(), st.height);
widget->paintRequest() | rpl::start_with_next([=, this] {
widget->paintRequest() | rpl::on_next([=, this] {
auto p = Painter(widget);
const auto selected = widget->isOver() || widget->isDown();
paintRow(p, crl::now(), selected, raw);

View File

@@ -90,7 +90,7 @@ void PeerListsBox::createMultiSelect() {
tr::lng_participant_filter());
_select.create(this, std::move(entity));
_select->heightValue(
) | rpl::start_with_next(
) | rpl::on_next(
[this] { updateScrollSkips(); },
lifetime());
_select->entity()->setSubmittedCallback([=](Qt::KeyboardModifiers) {
@@ -158,7 +158,7 @@ void PeerListsBox::prepare() {
list.controller->setDelegate(list.delegate.get());
content->scrollToRequests(
) | rpl::start_with_next([=](Ui::ScrollToRequest request) {
) | rpl::on_next([=](Ui::ScrollToRequest request) {
const auto skip = content->y();
scrollToY(
skip + request.ymin,
@@ -168,7 +168,7 @@ void PeerListsBox::prepare() {
content->selectedIndexValue(
) | rpl::filter([=](int index) {
return (index >= 0);
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
for (const auto &list : _lists) {
if (list.content && list.content != content) {
list.content->clearSelection();

View File

@@ -65,7 +65,7 @@ Controller::Controller(
, _callback(std::move(callback)) {
std::move(
add
) | rpl::start_with_next([=](not_null<PeerData*> peer) {
) | rpl::on_next([=](not_null<PeerData*> peer) {
if (_prepared) {
addRow(peer);
} else {
@@ -359,7 +359,7 @@ object_ptr<Ui::RpWidget> AddBotToGroupBoxController::prepareAdminnedChats() {
delegate->setContent(content);
controller->setDelegate(delegate);
items.events() | rpl::take(1) | rpl::start_with_next([=] {
items.events() | rpl::take(1) | rpl::on_next([=] {
wrap->show(anim::type::instant);
}, inner->lifetime());
};
@@ -373,7 +373,7 @@ object_ptr<Ui::RpWidget> AddBotToGroupBoxController::prepareAdminnedChats() {
rpl::merge(
_groups.events(),
_channels.events()
) | rpl::take(1) | rpl::start_with_next([=] {
) | rpl::take(1) | rpl::on_next([=] {
container->add(CreatePeerListSectionSubtitle(
container,
tr::lng_bot_groups()));
@@ -403,7 +403,7 @@ void AddBotToGroupBoxController::prepareViewHook() {
session().data().chatsListLoadedEvents(
) | rpl::filter([=](Data::Folder *folder) {
return !folder;
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
updateLabels();
}, lifetime());
}

View File

@@ -273,7 +273,7 @@ void SimpleForbiddenBox(
Data::AmPremiumValue(
&peer->session()
) | rpl::skip(1) | rpl::start_with_next([=] {
) | rpl::skip(1) | rpl::on_next([=] {
box->closeBox();
}, box->lifetime());
}
@@ -555,7 +555,7 @@ void InviteForbiddenController::setComplexCover() {
void InviteForbiddenController::prepare() {
session().api().premium().someMessageMoneyRestrictionsResolved(
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
auto stars = 0;
const auto process = [&](not_null<PeerListRow*> raw) {
const auto row = static_cast<ForbiddenRow*>(raw.get());
@@ -667,7 +667,7 @@ void InviteForbiddenController::send(
if (!waiting.empty()) {
session().changes().peerUpdates(
Data::PeerUpdate::Flag::FullInfo
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
) | rpl::on_next([=](const Data::PeerUpdate &update) {
if (waiting.contains(update.peer)) {
withPaymentApproved(alreadyApproved);
}
@@ -677,7 +677,7 @@ void InviteForbiddenController::send(
session().credits().loadedValue(
) | rpl::filter(
rpl::mappers::_1
) | rpl::take(1) | rpl::start_with_next([=] {
) | rpl::take(1) | rpl::on_next([=] {
withPaymentApproved(alreadyApproved);
}, _paymentCheckLifetime);
}
@@ -750,7 +750,7 @@ void InviteForbiddenController::send(
_peer->session().changes().peerUpdates(
_peer,
Data::PeerUpdate::Flag::FullInfo
) | rpl::start_with_next([=] {
) | rpl::on_next([=] {
sendForFull();
}, lifetime());
}
@@ -926,7 +926,7 @@ void AddParticipantsBoxController::addInviteLinkButton() {
st::inviteViaLinkIcon,
QPoint());
button->entity()->heightValue(
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
icon->moveToLeft(
st::inviteViaLinkIconPosition.x(),
(height - st::inviteViaLinkIcon.height()) / 2);
@@ -938,7 +938,7 @@ void AddParticipantsBoxController::addInviteLinkButton() {
button->entity()->events(
) | rpl::filter([=](not_null<QEvent*> e) {
return (e->type() == QEvent::Enter);
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
delegate()->peerListMouseLeftGeometry();
}, button->lifetime());
delegate()->peerListSetAboveWidget(std::move(button));
@@ -1062,7 +1062,7 @@ void AddParticipantsBoxController::Start(
[=] { box->closeBox(); });
if (justCreated) {
const auto weak = base::make_weak(parent);
box->boxClosing() | rpl::start_with_next([=] {
box->boxClosing() | rpl::on_next([=] {
auto params = Window::SectionShow();
params.activation = anim::activation::background;
if (const auto strong = weak.get()) {
@@ -1145,7 +1145,7 @@ bool ChatInviteForbidden(
) | rpl::map(
rpl::mappers::_1 > 0
) | rpl::distinct_until_changed(
) | rpl::start_with_next([=](bool has) {
) | rpl::on_next([=](bool has) {
box->clearButtons();
if (has) {
const auto send = box->addButton(tr::lng_via_link_send(), [=] {
@@ -1165,7 +1165,7 @@ bool ChatInviteForbidden(
Data::AmPremiumValue(
&peer->session()
) | rpl::skip(1) | rpl::start_with_next([=] {
) | rpl::skip(1) | rpl::on_next([=] {
box->closeBox();
}, box->lifetime());
};
@@ -1272,7 +1272,7 @@ void AddSpecialBoxController::prepareChatRows(not_null<ChatData*> chat) {
chat->session().changes().peerUpdates(
chat,
UpdateFlag::Members | UpdateFlag::Admins
) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
) | rpl::on_next([=](const Data::PeerUpdate &update) {
_additional.fillFromPeer();
if (update.flags & UpdateFlag::Members) {
rebuildChatRows(chat);

View File

@@ -97,6 +97,7 @@ using RightsMap = std::vector<std::pair<ChatAdminRight, tr::phrase<>>>;
{ Flag::ManageCall, tr::lng_request_channel_manage_livestreams },
{ Flag::ManageDirect, tr::lng_request_channel_manage_direct },
{ Flag::AddAdmins, tr::lng_request_channel_add_admins },
{ Flag::BanUsers, tr::lng_request_group_ban_users },
};
}
@@ -372,7 +373,7 @@ void ChoosePeerBoxController::prepareRestrictions() {
st,
QPoint());
button->heightValue(
) | rpl::start_with_next([=](int height) {
) | rpl::on_next([=](int height) {
icon->moveToLeft(
st::choosePeerCreateIconLeft,
(height - st::inviteViaLinkIcon.height()) / 2);
@@ -386,7 +387,7 @@ void ChoosePeerBoxController::prepareRestrictions() {
button->events(
) | rpl::filter([=](not_null<QEvent*> e) {
return (e->type() == QEvent::Enter);
}) | rpl::start_with_next([=] {
}) | rpl::on_next([=] {
delegate()->peerListMouseLeftGeometry();
}, button->lifetime());
return button;
@@ -521,7 +522,7 @@ void ShowChoosePeerBox(
query,
std::move(callback));
auto initBox = [=, ptr = controller.get()](not_null<PeerListBox*> box) {
ptr->selectedCountValue() | rpl::start_with_next([=](int count) {
ptr->selectedCountValue() | rpl::on_next([=](int count) {
box->clearButtons();
if (limit > 1) {
box->setAdditionalTitle(rpl::single(u"%1 / %2"_q.arg(count).arg(limit)));

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