Compare commits

...

663 Commits

Author SHA1 Message Date
John Preston
0b5500fe75 Version 1.6.2.
- Delete any message on both ends in any private chat, anytime.
- Control whether your forwarded messages link back to your account.
- Control who may see your profile picture.
- Enjoy the new streamlined group management screen.
2019-03-24 18:53:06 +04:00
John Preston
2845f48430 Closed alpha version 1.6.1.1. 2019-03-24 12:12:45 +04:00
John Preston
4ba959e6e1 Use sticker set thumbnails in StickersBox. 2019-03-24 12:12:45 +04:00
John Preston
72d9ac508a Use sticker set thumbnails in the panel. 2019-03-24 12:12:45 +04:00
John Preston
386600baf9 Save and load sticker set thumbnails. 2019-03-24 12:12:44 +04:00
John Preston
eb1825defd Add revoking of full history. 2019-03-24 12:12:44 +04:00
John Preston
33069739ee Improve revoke phrases. 2019-03-24 12:12:44 +04:00
John Preston
dd8c526fb7 Prepare code for revoking of full history. 2019-03-24 12:12:43 +04:00
John Preston
2701e63406 Allow revoking only sent messages. 2019-03-24 12:12:43 +04:00
John Preston
b972da059a Show explaining preview of forwards privacy. 2019-03-24 12:12:42 +04:00
John Preston
81862215b4 Add forwards and profile photo privacy settings. 2019-03-24 12:12:42 +04:00
John Preston
a34e998c42 Handle fwd_from without a link to the account. 2019-03-24 12:12:42 +04:00
John Preston
6d1193a751 Update API scheme to layer 97. 2019-03-24 12:12:41 +04:00
John Preston
0cd7399dc9 Update API scheme to layer 96. 2019-03-24 12:12:41 +04:00
John Preston
f1b0b60340 Fix possible crash in MainWindow destructor. 2019-03-24 12:12:41 +04:00
John Preston
d1cf43f9a4 Fix streaming receivedTill reporting.
It was incorrect in case audio and video had different durations.
2019-03-24 12:12:40 +04:00
John Preston
a0b3b1affd Fix fade in widget animation.
Fixes #5812.
2019-03-24 12:12:40 +04:00
John Preston
2a7fdfc832 Fix call icon position in single column info page. 2019-03-24 12:12:40 +04:00
John Preston
672070e618 Fix icon position in EditPeerInfoBox. 2019-03-24 12:12:39 +04:00
John Preston
6a2b1bb48d Fix HTML export wrapper. 2019-03-24 12:12:39 +04:00
John Preston
db121c0839 Take album caption from any album item. 2019-03-22 14:22:49 +04:00
23rd
ca9db9fd3f Refactored code.
- Removed std::optional from EditPeerHistoryVisibilityBox.
 - Added std::optional for savedCallback in EditPeerTypeBox.
 - Guarded boxCallbacks.
2019-03-22 13:40:23 +04:00
23rd
ecccf673a9 Deleted unused code of Delete Button. 2019-03-22 13:40:23 +04:00
John Preston
e0d7cae3fe Fix build for macOS. 2019-03-22 13:40:23 +04:00
John Preston
241526f127 Improve code style a bit. 2019-03-22 13:40:22 +04:00
23rd
4148099115 Redesigned Delete Button in EditPeerInfoBox. 2019-03-22 13:40:22 +04:00
23rd
5edf200157 Fixed focus in EditPeerTypeBox. Slightly refactored code. 2019-03-22 13:40:22 +04:00
23rd
bd7ba3acb1 Refactored code.
- Slightly improved design.
 - Added "const" in EditPeerTypeBox & EditPeerInfoBox.
2019-03-22 13:40:22 +04:00
23rd
e024d9bbb0 Added opening EditPeerTypeBox when error of saving username was handled. 2019-03-22 13:40:22 +04:00
23rd
3d7b8b3162 Added Invite Link button. Refactored code.
- Removed unused includes.
 - Improved design for boxes.
 - Draw buttons for EditPeerInfoBox in single place.
 - Simplified conditions for all buttons.
 - Made AddSkip more flexible.
2019-03-22 13:40:22 +04:00
23rd
8887272577 Refactored code. Removed unused code.
- Deleted manage_peer_box from sources.
2019-03-22 13:40:22 +04:00
23rd
c86257568f Fixed issue when "Too much usernames" box appearing only after typing. 2019-03-22 13:40:22 +04:00
23rd
ae25538706 Added opening of EditPeerInfoBox in new way. 2019-03-22 13:40:22 +04:00
23rd
21e417433b Added waiting for full data update of peer to open EditPeerInfoBox. 2019-03-22 13:40:22 +04:00
23rd
cb272be805 Refactored code. Slightly improved animations and design. 2019-03-22 13:40:22 +04:00
23rd
b79d8d6c82 Removed Checkbox for Sign Messages and added Toggle Button.
- That is how it looks in mobile clients.
2019-03-22 13:40:22 +04:00
23rd
be8aed6a95 Added GroupTypeBox with Controller. 2019-03-22 13:40:22 +04:00
23rd
d06337dddc Added HistoryVisibilityBox. 2019-03-22 13:40:22 +04:00
23rd
0f3ec47074 Begin of EditPeerBox redesigning.
- Moved buttons from ManageGroupBox to EditPeerBox.
 - Added counting of permissions.
2019-03-22 13:40:21 +04:00
23rd
3a5bad4b7a Fixed incorrect display of uploaded video's thumbnail in edited message.
- After uploading a video the data_document changes a source of the 
 good thumbnail and loses an information about it (e.g. width, height, 
 bytesSize).
2019-03-22 13:39:12 +04:00
23rd
2aecd1035e Removed "Export history" from context menu for empty chats. 2019-03-22 13:38:09 +04:00
23rd
5d04842a80 Refactored edit_caption_box. 2019-03-22 13:36:47 +04:00
23rd
59c73a4814 Fixed drawing of custom thumbnails in edit_caption_box. 2019-03-22 13:36:47 +04:00
John Preston
25affe5484 Version 1.6.1.
- Bug fixes and other minor improvements.
2019-03-20 14:32:34 +04:00
John Preston
399aed4087 Remove setting for Mac App Store version. 2019-03-20 14:31:32 +04:00
John Preston
31dbe2278e Fix possible crash in local file streaming.
Cache file size instead of requesting it from file system each time.
2019-03-20 14:21:50 +04:00
John Preston
9ed064b7fc Fix crash in streaming parts loading. 2019-03-20 13:41:13 +04:00
John Preston
a59353df9f Fix possible crash in DomainResolver.
App::CallDelayed() could be queued twice for a single key, if before
the delayed call we cleared entry in _attempts and created it again.
2019-03-20 13:23:16 +04:00
John Preston
8acd47bf2f Fix pre-history visibility rights check. 2019-03-20 13:22:58 +04:00
John Preston
be53cb027c Possibly fix a crash in microphone testing. 2019-03-20 13:00:38 +04:00
John Preston
6ff8c1de05 Fix possible crash in layers destruction.
clearClosingLayers could've called itself from layer->setClosing.
2019-03-20 11:41:10 +04:00
John Preston
2ebbf062d0 Show webpage with embed_url as a video. 2019-03-19 13:21:13 +04:00
John Preston
fd538bc6c8 Version 1.6.
- Play video files and listen to music
without waiting for them to fully download.
- Press CTRL+0 (CMD+0 on macOS) to jump to your Saved Messages.
2019-03-18 12:24:03 +04:00
John Preston
c0959ceaeb Start video when moving to it in media viewer.
Fixes #5796.
2019-03-18 11:44:49 +04:00
John Preston
6c382c647c Fix caching of first slice in header. 2019-03-18 11:00:11 +04:00
John Preston
8f9bed0443 Fix document caption in media viewer.
Regression was introduced in 5cae57601a.

Fixes #5799, fixes #5802, fixes #5804.
2019-03-17 23:00:09 +04:00
John Preston
dc3996c077 Beta version 1.5.18: Update libtgvoip. 2019-03-15 16:57:18 +04:00
John Preston
5bfd5e4495 Beta version 1.5.18.
- Bug fixes and other minor improvements.
2019-03-15 16:11:55 +04:00
John Preston
d646de7184 Add button to download audio files. 2019-03-15 16:09:05 +04:00
John Preston
bc2b0f8392 Add button to download video files.
Fixes #5781.
2019-03-15 14:15:04 +04:00
John Preston
f2a7cf5c64 Improve shared videos design. 2019-03-15 12:09:48 +04:00
John Preston
0df628dc7a Fix notifications hiding on Linux.
Regression was introduced in 3372dfcd3e.

Only when platform-specific code can give us the global time of the
last user input event we rely on idle time for notifications hiding.

Fixes #5791.
2019-03-14 21:59:10 +04:00
John Preston
a5d1fbff98 Fix removing photo in webpage preview. 2019-03-14 17:14:18 +04:00
John Preston
5cae57601a Allow video download from media viewer. 2019-03-14 16:03:02 +04:00
John Preston
2b7fb7a9a6 Pause music only when video playback starts. 2019-03-14 14:45:08 +04:00
John Preston
feb238c5d9 Fix crash if asked to read more than 64MB at once. 2019-03-14 14:14:24 +04:00
John Preston
0d888eea85 Fix local cache time limit setting storing.
Fixes #5611.
2019-03-14 13:22:42 +04:00
John Preston
bfb6ecbac7 Fail streaming on error in any stream. 2019-03-14 12:47:18 +04:00
John Preston
2152fe6a79 Beta version 1.5.17: Improve large file streaming.
Allow header for streaming up to 8 MB.
2019-03-13 20:56:04 +04:00
John Preston
b113696fe6 Beta version 1.5.17.
- Bug fixes and other minor improvements.
2019-03-13 19:02:53 +04:00
John Preston
b65a24df96 Allow streaming videos with unknown duration.
When you stream image/gif as a soundless video the total duration is
unknown, so we accumulate packet->pts + packet->duration as duration.
2019-03-13 18:58:50 +04:00
John Preston
c655bf852f Fix crash in video player seek. 2019-03-13 16:28:07 +04:00
John Preston
be495c17bc Fix seek to video end. 2019-03-13 16:21:07 +04:00
John Preston
9785ff4be6 Add more checks in streaming. 2019-03-13 15:11:54 +04:00
John Preston
5ec37e9112 Use separate click handler for OpenWith. 2019-03-13 13:35:47 +04:00
John Preston
f9f84fd407 Fix idle time checking in MainWidget.
Regression was introduced in 78d00bcf22.

Fixes #5779, fixes #5780.
2019-03-13 11:21:56 +04:00
John Preston
ed93669693 Beta version 1.5.16: Update libtgvoip. 2019-03-12 19:04:22 +04:00
John Preston
e79ddf2459 Beta version 1.5.16: Fix audio stucking. 2019-03-12 18:57:48 +04:00
John Preston
5efe47cfb6 Beta version 1.5.16: Remove streaming logs. 2019-03-12 18:56:35 +04:00
John Preston
b8045cbcc7 Beta version 1.5.16.
- Play video files and listen to received music
without waiting for them to download.
- Press CTRL+0 (CMD+0 on macOS) to jump to your Saved Messages.
2019-03-12 17:05:11 +04:00
John Preston
aa1090a585 Fix text disappearing in support mode. 2019-03-12 16:54:15 +04:00
John Preston
0a5589f869 Remove deleted chats with users from list. 2019-03-12 16:08:41 +04:00
John Preston
383b29dbd8 Fix possible crash in calls.
Fixes #5732.
2019-03-12 15:26:29 +04:00
John Preston
13a9b967e9 Use user phrases for support accounts. 2019-03-12 14:38:59 +04:00
John Preston
b798654ca7 Set focus to intro widget.
Fixes #5705.
2019-03-12 14:38:59 +04:00
John Preston
a5e6890b77 Fix icon pixmap sizes on Retina with scaling. 2019-03-12 14:27:22 +04:00
John Preston
2a3a38531b Fix photo inline result sending.
Fixes #5594.
2019-03-12 13:49:16 +04:00
John Preston
4ebf6ebb6f Use the same poll option values as others. 2019-03-12 13:15:08 +04:00
23rd
6fe736c9fc Added Shortcut to jump to the Saved Messages. 2019-03-12 13:03:23 +04:00
John Preston
ef682e7023 Fix photos in overview with disabled autodownload.
Fixes #5599, fixes #5747.
2019-03-12 12:55:26 +04:00
John Preston
5c3f667fc3 Fix background reset on language change. 2019-03-12 12:55:26 +04:00
John Preston
a95a055acd After update try relaunching for 1 second on macOS. 2019-03-12 09:35:53 +04:00
John Preston
846499a4fb Fix volume saving to settings. 2019-03-12 09:09:53 +04:00
John Preston
6afb3f70bb Closed alpha version 1.5.15.6. 2019-03-11 21:03:26 +04:00
John Preston
c063d94aa5 Remove DocumentData::actionOnLoad. Fix GIF open. 2019-03-11 19:07:35 +04:00
John Preston
261720c941 Fix radial animations on macOS.
QOpenGLWidget doesn't draw antialiased ellipses and arcs,
so we use a software rasterizer and then draw the resulting image.
2019-03-11 13:51:15 +04:00
John Preston
7b3c452316 Change direction of infinite radial animation. 2019-03-11 13:19:38 +04:00
John Preston
aa00f9bd34 Fix new animations engine restarts. 2019-03-11 12:08:21 +04:00
John Preston
b0ff443eac Fix sending of saved GIFs. 2019-03-11 12:08:21 +04:00
John Preston
a886c598c1 Fix non-streamable videos layout. 2019-03-11 12:08:20 +04:00
John Preston
2ce4abfdfe Fix crash in media caching. 2019-03-11 12:08:20 +04:00
John Preston
18c42954ae Fix sparse frame painting on macOS. 2019-03-11 12:08:20 +04:00
John Preston
b57b4fa0f8 Fix reading first slice for good header cache. 2019-03-11 12:08:20 +04:00
John Preston
e66cde398a Closed alpha version 1.5.15.5. 2019-03-11 12:08:19 +04:00
John Preston
3706be77ea Fix macOS media viewer controls hiding. 2019-03-11 12:08:19 +04:00
John Preston
f481f1e142 Make videos larger, fix playback animation. 2019-03-11 12:08:19 +04:00
John Preston
84b09795f3 Store first slice in the header cache key. 2019-03-11 12:08:19 +04:00
John Preston
95954c4b1f Closed alpha version 1.5.15.4. 2019-03-11 12:08:18 +04:00
John Preston
a56a12a1ef Optimized video frame pushing. 2019-03-11 12:08:18 +04:00
John Preston
5c4b459f57 Use new animations in video viewer. 2019-03-11 12:08:18 +04:00
John Preston
9a616edf2a Add new animations engine. 2019-03-11 12:08:17 +04:00
John Preston
92332b45ea Don't reset zoom on video seek. 2019-03-11 12:08:17 +04:00
John Preston
5a7fcc3a22 Don't show fast share for own messages. 2019-03-11 12:08:17 +04:00
John Preston
6c441353c4 Closed alpha version 1.5.15.3. 2019-03-11 12:08:17 +04:00
John Preston
b742c95516 Support streamed video rotation. 2019-03-11 12:08:16 +04:00
John Preston
a59c3da3d0 Cache small files in one value. 2019-03-11 12:08:16 +04:00
John Preston
8399f4189f Don't show receivedTill for local loaders. 2019-03-11 12:08:16 +04:00
John Preston
67b9fe846b Improve video frame position checks. 2019-03-11 12:08:16 +04:00
John Preston
0f4ccce0e1 Update ffmpeg. 2019-03-11 12:08:15 +04:00
John Preston
01d763eed1 Use DocumentData::getDuration for all types. 2019-03-11 12:08:15 +04:00
John Preston
41c60419f1 Enable voice messages streaming. 2019-03-11 12:08:15 +04:00
John Preston
195164d9d4 Fix display / download of video messages. 2019-03-11 12:08:14 +04:00
John Preston
518d1da736 Fail streaming if no codec for a stream. 2019-03-11 12:08:14 +04:00
John Preston
aade3d4f27 Allow streaming video from overview. 2019-03-11 12:08:14 +04:00
John Preston
22356eb01c Fix initial video duration display. 2019-03-11 12:08:14 +04:00
John Preston
b5eb88a32f Closed alpha version 1.5.15.2. 2019-03-11 12:08:13 +04:00
John Preston
6887993f92 Report streaming failed. 2019-03-11 12:08:13 +04:00
John Preston
71b733a018 Display receivedTill in video player controls. 2019-03-11 12:08:13 +04:00
John Preston
e2eb9cea00 Apply sample_aspect_ratio in streaming. 2019-03-11 12:08:12 +04:00
John Preston
99e96a5b13 Allow looping video without audio in streaming. 2019-03-11 12:08:12 +04:00
John Preston
7093254b66 Fix crash in empty sticker set box. 2019-03-11 12:08:12 +04:00
John Preston
f4544b0964 Fix crash in passcode setup. 2019-03-11 12:08:12 +04:00
John Preston
c27456277e Support streaming of local files. 2019-03-11 12:08:11 +04:00
John Preston
2e824ace00 Fix video messages inline playback. 2019-03-11 12:08:11 +04:00
John Preston
dafa286b18 Show option to download on streaming error. 2019-03-11 12:08:11 +04:00
John Preston
003d01206f Allow .opus playback. 2019-03-11 12:08:10 +04:00
John Preston
f0963a332a Fix crash on failed streaming. 2019-03-11 12:08:10 +04:00
John Preston
91bdb66f0d Fix call icon position for the Info layer. 2019-03-11 12:08:10 +04:00
John Preston
ffb48c42b0 Closed alpha version 1.5.15.1. 2019-03-11 12:08:10 +04:00
John Preston
8171828c2a Fix build on GCC. 2019-03-11 12:08:09 +04:00
John Preston
a8aa66d191 Check frame format before sws_getCachedContext. 2019-03-11 12:08:09 +04:00
John Preston
e631d98230 Implement media cache management. 2019-03-11 12:08:09 +04:00
John Preston
1940c67a09 Disable music / video autodownload. 2019-03-11 12:08:09 +04:00
John Preston
c574119718 Implement file reference update in streaming. 2019-03-11 12:08:08 +04:00
John Preston
648cd44ddd Display correct video / music state. 2019-03-11 12:08:08 +04:00
John Preston
fde8dd9607 Play streaming audio in player. 2019-03-11 12:08:08 +04:00
John Preston
f1e0cd6c1d Play streaming video in mediaview. 2019-03-11 11:52:11 +04:00
John Preston
44df10d6cb Improve working with cache in streaming. 2019-03-11 11:49:54 +04:00
John Preston
b6a757842a Pause loading if loaded for 1 minute. 2019-03-11 11:49:54 +04:00
John Preston
4636c74586 Remove from memory old file slices. 2019-03-11 11:49:54 +04:00
John Preston
2208621050 First version of caching in media streaming. 2019-03-11 11:49:54 +04:00
John Preston
f133dd396c Return pair<iterator,bool> from flat_set::emplace. 2019-03-11 11:49:54 +04:00
John Preston
ccd04b98b9 Fix sync video to audio. 2019-03-11 11:49:54 +04:00
John Preston
d37b65e624 If stuck wait for three seconds of packets. 2019-03-11 11:49:54 +04:00
John Preston
3e9b811875 Implement precise seek in streaming. 2019-03-11 11:49:54 +04:00
John Preston
44c562d8ba Fix streaming seek, display progress. 2019-03-11 11:49:53 +04:00
John Preston
93c548c013 Support streaming speed changing. 2019-03-11 11:49:53 +04:00
John Preston
a7d9281768 Implement pause / resume in streaming. 2019-03-11 11:49:53 +04:00
John Preston
3b369fc98e Buffer audio when waiting data in streaming. 2019-03-11 11:49:53 +04:00
John Preston
e5cd7e6d40 Fix streaming from the middle of the file. 2019-03-11 11:49:53 +04:00
John Preston
99d05ba967 Sync video stream to audio stream. 2019-03-11 11:49:53 +04:00
John Preston
ec9512899e Support streaming playback speed 0.5 - 2. 2019-03-11 11:49:22 +04:00
John Preston
26ea6c4e63 Provide receivedTill for streamed tracks. 2019-03-11 11:49:22 +04:00
John Preston
8e44a7f5c4 Basic code for video streaming + testing on video. 2019-03-11 11:49:22 +04:00
John Preston
a093cb6274 Move some logic to Media::Streaming::Player. 2019-03-11 11:49:21 +04:00
John Preston
64f2f330f6 Render first frame when starting streaming. 2019-03-11 11:49:21 +04:00
John Preston
473e30e594 Basic code for media streaming + testing on music. 2019-03-11 11:49:21 +04:00
23rd
dc95756ec9 Fixed infrequent separation of grouped notifications. 2019-03-11 00:00:02 +04:00
23rd
2a935868a8 Added grouping of album files into a single notification.
- Added display of "Album" in inDialogsText().
2019-03-11 00:00:02 +04:00
23rd
f48d8538c0 Added ability to see attached stickers on photos. 2019-03-10 22:10:36 +04:00
23rd
3372dfcd3e Refactored checking of last input while notifications are displayed.
- Removed condition for Windows platform only.
 - Added smooth hiding of notifications in case video is watched or voice message is recorded.
 - psUserActionDone() was completely replaced with Core::App().updateNonIdle().
2019-03-10 22:02:58 +04:00
23rd
78d00bcf22 Refactored counting idle time.
- psIdleTime() was replaced with Platform::LastUserInputTime().
 - _lastTimeVideoPlayedAt was moved to Application as _lastNonIdleTime.
 - Call of updateNonIdle() was added while voice is recording.
 - Fixed #5695.
 - Thanks Preston. =)
2019-03-10 22:02:58 +04:00
23rd
9dc9e019f6 Added Search Shortcut in Shared Media.
- Works for Documents, Audio files and Shared links.
2019-03-10 10:58:05 +04:00
John Zimmermann
178c0078c1 docs: Fix setting the gcc-7 alternative with apt
#5766
2019-03-10 10:56:48 +04:00
Martin Delille
8478abe378 Add brew install cmake ninja 2019-03-10 10:29:37 +04:00
23rd
bfc9e43eb4 Added a handler for "MESSAGE_EMPTY" error to delete a local message.
- Added a determination of the zero-width-space as the space.
 - Fixes #3145.
2019-03-10 10:26:40 +04:00
John Preston
e174025a92 Fix travis build. 2019-03-09 15:27:36 +04:00
23rd
89f4408029 Added forwarded info in tooltip of sticker. 2019-03-09 15:24:35 +04:00
23rd
d7dc277003 Added author of channel post in tooltip.
- Added "const" to vars within HistoryMessageSigned::refresh().
2019-03-09 15:01:08 +04:00
23rd
32bc723745 Added scroll animation in dialogs list when it scrolls to top. 2019-03-09 13:56:33 +04:00
23rd
c2ad765424 Fixed extra space in a name of the post author after forwarding message. 2019-03-09 13:41:39 +04:00
23rd
9799afa064 Updated libvdpau to 1.2. 2019-03-06 14:41:04 +04:00
23rd
e880c14d61 Fixed crash in window resizing when layer is opened.
Regression was introduced in 26f1ade5ba.
2019-03-05 13:38:58 +04:00
23rd
e70465c633 Removed unnecessary calling of saveDraftToCloud() method when quit. 2019-02-20 11:46:37 +04:00
23rd
4ed1835d32 Fixed Ctrl + F shortcut for full screen toggle in media view. 2019-02-20 11:43:50 +04:00
23rd
19bbccd1a7 Improved "Create link" box title display. 2019-02-20 11:42:10 +04:00
23rd
9d8b80cbce Fixed Travis build.
Regression was introduced in 771a51224e.
2019-02-20 11:41:13 +04:00
John Preston
dec8264625 Fix extensive CPU usage on macOS when audio is played.
Regression was introduced in 91c85ec86b

The openal-soft version 1.19.1 tried to use semaphores created by sem_init,
which are not supported on macOS, so they just didn't work at all. This was
leading to an event loop thread spin-waiting instead of a normal sem_wait.

In the v1.19 upstream branch GCD semaphores are used on macOS.
2019-02-20 11:37:38 +04:00
John Preston
fe618bd652 Use crl::time/now instead of TimeMs/getms. 2019-02-19 11:06:33 +04:00
John Preston
d208236994 Accept binary_guard in crl::guard(). 2019-02-17 15:56:07 +04:00
John Preston
4d987f7278 Fix index_based_iterator for const containers. 2019-02-17 15:56:07 +04:00
23rd
193e454fd4 Fixed sending polls as reply to other messages.
Fixes #5550.
2019-02-17 15:55:44 +04:00
John Preston
bdfb9b4143 Ignore actions from other chats in HistoryWidget.
This should fix an issue that was noticed in #5701.
2019-02-17 15:09:02 +04:00
John Preston
c9716f3c72 Make crl::object_on_queue usages consistent. 2019-02-17 15:09:01 +04:00
John Preston
7c1704e68b Fix crash in EditCaptionBox. 2019-02-17 13:51:53 +04:00
John Preston
771a51224e Support errors in rpl::event_stream. 2019-02-17 10:55:29 +04:00
John Preston
cf275b152a Fix crash in layers closing.
Sometimes AbstractBox::setClosing invoked Ui::hideLayers that
destroyed LayerStackWidget and all its children, including the
closing AbstractBox. After that a unique_ptr stored on stack
and owning that box was destroyed and it lead to a crash.

Now LayerStackWidget always owns several closing boxes.
2019-02-17 10:55:28 +04:00
John Preston
98cb85df66 Polymorphic classes without virtual dtor warning. 2019-02-15 15:55:34 +04:00
John Preston
032694ad9e Move files to media/audio and media/clip. 2019-02-13 15:41:33 +03:00
John Preston
5437215677 Use premultiplied format for GIF frames. 2019-02-13 15:19:05 +03:00
John Preston
5ec80238a0 Fix permissions dependencies. 2019-02-13 15:19:05 +03:00
John Preston
ae6c152988 Version 1.5.15: Fix macOS media viewer overlay.
Regression was introduced in c1a0dad2b7.
2019-02-12 19:55:35 +03:00
John Preston
7d15cca1ee Version 1.5.15.
- Crash fix.
2019-02-12 19:02:08 +03:00
John Preston
83c5a67af5 Fix another crash in last message checking.
Regression was introduced in 83bc6fb39c.
2019-02-12 19:01:30 +03:00
John Preston
c9ad2cd1aa Version 1.5.14.
- Crash fix.
2019-02-12 16:56:23 +03:00
John Preston
fe1f198d99 Fix crash in last message checking.
Fixes #5683.
2019-02-12 16:53:46 +03:00
John Preston
818662c2e6 Version 1.5.13: Don't automatically load executable files. 2019-02-12 14:28:33 +03:00
John Preston
05d0d2a6d6 Version 1.5.13.
- Bug fixes and other minor improvements.
2019-02-12 14:03:34 +03:00
John Preston
c1a0dad2b7 Use QOpenGLWidget for macOS media viewer overlay.
Also move mediaview to media/view/media_view_overlay_widget.
2019-02-12 14:00:47 +03:00
John Preston
4caf26d069 Fix build for Xcode. 2019-02-11 15:56:25 +03:00
John Preston
83bc6fb39c Fix changelog dialogs list appearance.
Fixes #5678, fixes #5674.
2019-02-11 15:52:36 +03:00
John Preston
dbb7568b92 Fix changelogs blog link previews. 2019-02-11 15:52:36 +03:00
John Preston
45fda44924 Fix crash on bad sticker.
DocumentData::getStickerLarge and DocumentData::loaded go to a loop.
2019-02-11 15:52:36 +03:00
John Preston
26f1ade5ba Optimize connecting widget. 2019-02-10 21:35:44 +03:00
John Preston
9dd93a77a0 Always keep inline thumbnail images loaded. 2019-02-10 11:19:27 +03:00
John Preston
331d1baad6 Fix videos without thumbnails in MediaView.
Fixes #5668.
2019-02-10 11:18:54 +03:00
John Preston
d3159d86da Version 1.5.12: Fix manual loading GIFs to cache. 2019-02-09 18:00:48 +03:00
John Preston
f9e1513491 Version 1.5.12.
- Apply blur effects to backgrounds.
- Use the backgrounds you set in Telegram Desktop
in all other Telegram apps.
2019-02-09 16:46:43 +03:00
John Preston
b6e37b7730 Allow removing cloud wallpapers. 2019-02-09 16:36:07 +03:00
John Preston
f9d56eb4c1 Send installWallPaper requests. 2019-02-08 19:47:02 +03:00
John Preston
95565c39ed Upload wallpapers to the cloud. 2019-02-08 19:20:08 +03:00
John Preston
890aacaeee Allow to blur wallpapers from file. 2019-02-08 16:55:02 +03:00
John Preston
e2f0886950 Add option to blur chat background. 2019-02-07 19:36:30 +03:00
John Preston
fe21b5a502 Support blurred backgrounds. 2019-02-06 17:38:37 +03:00
John Preston
e7043c4d63 Show patterns with colors in galery. 2019-02-05 12:32:54 +03:00
John Preston
aae2101131 Sort backgrounds in the gallery. 2019-02-04 21:37:40 +03:00
John Preston
64afed0fb2 Fix crash for videos without thumbnails. 2019-02-04 19:04:36 +03:00
John Preston
4d9464ed87 Remove flags checking for backgrounds.
Also limit image size to 2960px.

Fixes #5641.
2019-02-04 18:53:00 +03:00
John Preston
b43191506a Fix preview of color-only backgrounds.
Regression was introduced in f506a5ea6c.
2019-02-04 18:03:31 +03:00
John Preston
c47781c25a Version 1.5.11.
- Bug fixes and other minor improvements.
2019-02-01 15:51:46 +03:00
John Preston
f0c4868b3e Ignore default banned rights for channel admins.
Fixes #5640.
2019-02-01 15:50:57 +03:00
John Preston
35e5c2329b Fix wall paper preview on Retina. 2019-02-01 15:41:43 +03:00
John Preston
74fc5524ab Fix dock and menu hiding on macOS.
Regression was introduced in 0681d10c51.
2019-02-01 15:41:43 +03:00
John Preston
2d4c99a6f7 Fix build for old OS X versions. 2019-02-01 13:23:35 +03:00
John Preston
69c73d0a2c Version 1.5.10.
- Bug fixes and other minor improvements.
2019-02-01 12:51:02 +03:00
John Preston
58510e0208 Improve chat list bot icon layout. 2019-02-01 12:50:30 +03:00
Jiachen YANG
0681d10c51 fixing mediaview fullscreen on X11 2019-02-01 12:38:32 +03:00
John Zimmermann
add2356c8a Generalize Unity Integration to not depend on libunity 2019-02-01 12:34:55 +03:00
John Preston
c66b2b2291 Fix setting offline on quit. 2019-02-01 12:23:37 +03:00
23rd
769923c6cc Fixed a keeping online status after application quit.
Fixes https://github.com/telegramdesktop/tdesktop/issues/5528.
2019-02-01 11:52:25 +03:00
23rd
27528d084f Added shortcuts to skip months in CalendarBox. 2019-02-01 11:49:14 +03:00
23rd
299aa69058 Added an icon for bots in the dialog list.
Fixes https://github.com/telegramdesktop/tdesktop/issues/1894 .
2019-02-01 11:48:45 +03:00
John Preston
d1cc09f40e Destroy layers in reverse order. 2019-02-01 11:47:30 +03:00
John Preston
a133b43eed Fix crash in dual background box show. 2019-02-01 11:32:34 +03:00
John Preston
9b57725b8c Fix bad function call in data export cancel. 2019-02-01 11:17:23 +03:00
John Preston
34b0f6f014 Fix crash in group migration. 2019-02-01 11:09:14 +03:00
John Preston
f5cc93ec64 Decouple MTP::Instance from Core::App. 2019-02-01 10:48:31 +03:00
John Preston
4f3263d979 Fix crash in MediaView with thumbless GIFs. 2019-02-01 10:28:04 +03:00
John Preston
b28e374e06 Fix Media::Audio::Instance destruction. 2019-02-01 10:09:55 +03:00
John Preston
918d58ef0a Better check unique results in support mode. 2019-02-01 09:53:15 +03:00
John Preston
5a388d9dde Improve Poland number formatting. 2019-02-01 09:18:31 +03:00
John Preston
0f4909621b Version 1.5.9.
- Bug fixes and other minor improvements.
2019-01-31 20:34:19 +03:00
John Preston
55d3d8adc3 Allow to delete users from exceptions. 2019-01-31 20:31:44 +03:00
John Preston
d2d6a6daa4 Fix proxy sponsor messages search display. 2019-01-31 15:56:57 +03:00
John Preston
a7f4ac2797 Search by hashtag inside groups. 2019-01-31 15:51:19 +03:00
John Preston
25b5027dc7 Only creator can restrict in old groups. 2019-01-31 15:20:15 +03:00
John Preston
93a967dc74 Add random_padding to dns requests. 2019-01-31 13:48:10 +03:00
John Preston
3cfc3dcecf Mark even more extensions as executables. 2019-01-30 17:59:55 +03:00
John Preston
e09510ea9f Fix crash in update checker destruction. 2019-01-30 17:58:23 +03:00
John Preston
4c289fc8fb Fix add members button in channels. 2019-01-30 13:49:36 +03:00
John Preston
58cf0fa2b1 Display date in background preview. 2019-01-29 20:03:51 +03:00
John Preston
5ca12a73c3 Use new HistoryWallPaper media type for wallpaper. 2019-01-29 19:26:19 +03:00
John Preston
fd8e9dad92 Fix pattern wallpapers with themes. 2019-01-29 14:52:33 +03:00
John Preston
df0fe0a460 Closed alpha version 1.5.8.2. 2019-01-29 14:52:33 +03:00
John Preston
646d15b257 Add LSFileQuarantineEnabled to the .plist 2019-01-29 14:52:33 +03:00
John Preston
2eb6848eb8 Fix background preview on retina screens. 2019-01-29 14:52:33 +03:00
John Preston
9b3c103f16 Backport patch for Mojave accessibility access request. 2019-01-29 14:52:33 +03:00
John Preston
6a2a13d346 Closed alpha version 1.5.8.1. 2019-01-29 14:52:33 +03:00
John Preston
b6edf4561d Add support for pattern wallpapers. 2019-01-29 14:52:33 +03:00
John Preston
c2744700c0 Mark more extensions as executables. 2019-01-29 14:52:33 +03:00
John Preston
f506a5ea6c Save wallpaper settings locally. 2019-01-29 14:52:33 +03:00
John Preston
2f702148e3 Fix manage channel actions visibility.
Fixes #5601.
2019-01-29 14:52:33 +03:00
John Preston
e10c928207 Update API scheme to layer 95. 2019-01-29 14:52:33 +03:00
John Preston
a1baa23a52 Use both thumbnails in photos and documents.
Fixes #5602.
2019-01-28 13:10:45 +03:00
John Preston
a70e72f75d Application->Sandbox, Messenger->Application. 2019-01-23 12:51:58 +04:00
John Preston
4111da1dd0 Move some calls from App namespace. 2019-01-22 17:10:01 +04:00
John Preston
e7804d014d Share background from preview. 2019-01-22 17:10:00 +04:00
John Preston
bf87de3706 Fix removing chats from dialogs. 2019-01-22 17:05:06 +04:00
John Preston
ebc2043055 Improve empty group display. 2019-01-22 11:50:21 +04:00
John Preston
69b1f6c4e1 Version 1.5.8.
- Global permissions for groups. Restrict all members in any group
from posting certain types of content.
- Unified group settings. Make groups public,
set admins with granular permissions and toggle persistent history
in just a few clicks in any group.
- Choose the emoji set you would like to use in Chat Settings.
- Choose input and output devices for Telegram Calls
in Settings > Advanced > Call Settings.
- Support for automatically downloading files and music.
2019-01-21 21:28:45 +04:00
John Preston
2708777167 Closed alpha version 1.5.7.2. 2019-01-21 18:06:20 +04:00
John Preston
6e0d62bb65 Re-apply document thumb only for stickers. 2019-01-21 17:43:24 +04:00
John Preston
6d706fd222 Improve unacessible permissions design. 2019-01-21 17:43:24 +04:00
John Preston
6066265717 Fix emoji suggestions in monospace. 2019-01-21 11:02:20 +04:00
John Preston
805e4d01e7 Allow re-downloading failed media. 2019-01-21 10:49:44 +04:00
John Preston
e209299af4 Fix invite link block visibility. 2019-01-21 10:40:25 +04:00
John Preston
b3f0a3c9f5 Make audio device selection box wider. 2019-01-21 10:37:31 +04:00
John Preston
1da8841ac7 fixup use Text 2019-01-21 10:37:20 +04:00
John Preston
7df5df6351 Improve phrases for removed users. 2019-01-21 10:26:19 +04:00
John Preston
bf85b0c109 Closed alpha version 1.5.7.1. 2019-01-18 16:41:08 +04:00
John Preston
314e30272b Replace SingleTimer with base::Timer. 2019-01-18 16:41:08 +04:00
John Preston
61b9a32504 Add 'Contact joined' notifications setting. 2019-01-18 16:41:08 +04:00
John Preston
01b7d4ffba Use Text to display empty group state. 2019-01-18 16:41:07 +04:00
John Preston
8643972f8c Send thumbs only for big files. 2019-01-18 16:41:07 +04:00
John Preston
1894b8fcf7 Handle t.me/bg links with wallpapers / colors. 2019-01-18 16:41:07 +04:00
John Preston
e59a68cd68 Refresh wallpaper file references. 2019-01-17 12:21:31 +04:00
John Preston
466c6da5e3 Save wallpaper information. 2019-01-17 12:21:31 +04:00
John Preston
b8cb792831 Read background image async. 2019-01-17 12:21:31 +04:00
John Preston
0f9c2a62fe Load fullres images of new wallpapers. 2019-01-17 12:21:31 +04:00
John Preston
04350af96f Use one place for saving restrictions. 2019-01-17 12:21:31 +04:00
John Preston
287b3509ab Optimize getPeerDialog requests. 2019-01-17 12:21:31 +04:00
John Preston
2a5bcd3eec Support empty group placeholder for creators. 2019-01-17 12:21:31 +04:00
John Preston
2a0b9a44dd Remove supergroup migrate messages. 2019-01-17 12:21:31 +04:00
John Preston
c552db04d7 Use 'exception' and 'remove user' phrases. 2019-01-17 12:21:30 +04:00
John Preston
22f1ffc72b Use different phrases for default restrictions. 2019-01-17 12:21:30 +04:00
John Preston
4f33be20d4 Add user to group on appointing of admin. 2019-01-17 12:21:30 +04:00
John Preston
9728ddeaf9 Handle migration to supergroups in boxes. 2019-01-17 12:21:30 +04:00
John Preston
3c44bdb6b7 Support auto-migrate to supergroups. 2019-01-17 12:21:30 +04:00
John Preston
b236844c94 Fix crash in admin log events. 2019-01-17 12:21:30 +04:00
John Preston
67d12fa6d2 Improve update handling for legacy chats. 2019-01-17 12:21:30 +04:00
John Preston
215856adc3 Improve AddSpecial box for legacy groups. 2019-01-17 12:21:30 +04:00
John Preston
07e010dfb5 Save admins in legacy groups. 2019-01-17 12:21:30 +04:00
John Preston
dba9ca2084 Replace TLHelp helpers with .match() 2019-01-17 12:21:30 +04:00
John Preston
9a60e744d3 Unify permissions checks in participants boxes. 2019-01-17 12:21:30 +04:00
John Preston
e1a2ab0d7e Log only source base name in assertions. 2019-01-17 12:21:30 +04:00
John Preston
a605c110a8 Support legacy groups in participant boxes. 2019-01-17 12:21:29 +04:00
John Preston
18c6be0d3b Unify legacy and megagroups information edit. 2019-01-17 12:21:29 +04:00
John Preston
ff728e2fc1 Add default permissions changes to admin log. 2019-01-17 12:21:29 +04:00
John Preston
eff90395b6 Add EditPeerPermissionsBox. 2019-01-17 12:21:29 +04:00
John Preston
f4d52b82b4 Allow reusing permissions edit controls. 2019-01-17 12:21:29 +04:00
John Preston
61419b57c8 Prepare legacy group restrictions checking. 2019-01-17 12:21:29 +04:00
John Preston
441989a8e1 Remove EditChannelBox. 2019-01-17 12:21:29 +04:00
John Preston
c5a41e1f55 Divide data/data_peer and remove from PCH. 2019-01-17 12:21:29 +04:00
John Preston
0ce4d66601 Rename restrictionReason to unavailableReason. 2019-01-17 12:21:28 +04:00
John Preston
d2d6b319b6 Update API scheme to layer 93. Broken. 2019-01-17 12:21:28 +04:00
John Preston
47edb71a68 Update API scheme to layer 92. 2019-01-17 12:21:28 +04:00
John Preston
1f8626b383 Move App::histories to Data::Session. 2019-01-17 12:21:28 +04:00
John Preston
0d6a36e187 Fix volume widget position.
Fixes #5467.
2019-01-17 12:20:50 +04:00
John Preston
548a0c8517 Fix MTP logging. 2019-01-17 12:20:50 +04:00
John Preston
09d85e25c1 Fix possible crash in SendFilesBox. 2019-01-17 12:20:50 +04:00
John Preston
51b5b14dea Beta version 1.5.7.
- Choose the emoji set you would like to use
in Settings > Chat Settings.
- Choose input and output devices for Telegram Calls
in Settings > Adavanced > Call Settings.
2019-01-11 17:31:36 +04:00
John Preston
0d290a2c28 Fix emoji icon in theme preview.
Fixes #5561.
2019-01-11 17:30:57 +04:00
John Preston
c1b3d589c7 Fix elision in document extension in MediaView.
Fixes #5555.
2019-01-11 17:30:57 +04:00
John Preston
65430d92ea Refactor calls settings panel. 2019-01-11 17:30:57 +04:00
John Preston
8711830f66 Move calls settings to Settings > Advanced.
Also add calls settings button to the calls list box.
2019-01-11 17:30:57 +04:00
John Preston
c4d919d46b Improve emoji quality while creating cache. 2019-01-11 17:30:57 +04:00
John Preston
3e7a688811 Fix tray icon counter on Linux.
Fixes #5525.
2019-01-11 17:30:57 +04:00
John Preston
2773a675d0 Improve sticker set download phrase. 2019-01-11 17:30:57 +04:00
John Preston
9bbdccc111 Postpone sticker send from StickerSetBox.
Fixes #5539.
2019-01-11 17:30:57 +04:00
John Preston
bb8defeb42 Improve change emoji set box design. 2019-01-11 17:30:57 +04:00
John Preston
545dbd0791 Return sticker-related context menu actions.
Regression was introduced in 3e22ada889.
2019-01-11 17:30:57 +04:00
John Preston
c7469075ab Closed beta version 1.5.6.1: Fix build in GCC. 2019-01-11 17:30:57 +04:00
John Preston
54fa974789 Closed beta version 1.5.6.1. 2019-01-11 17:30:57 +04:00
John Preston
2cd3cec478 Go through open history in support mode. 2019-01-11 17:30:00 +04:00
John Preston
c11b977f1d Fix lagging chat list update in support. 2019-01-11 17:30:00 +04:00
John Preston
30e8f17b37 [all] / [one from chat] in support search results. 2019-01-11 17:30:00 +04:00
John Preston
2c3190ce2a Hide LoadMore button in search mode. 2019-01-11 17:30:00 +04:00
John Preston
ea7796dccc Ctrl+[1-5] jump to the relevant pinned chat. 2019-01-11 17:30:00 +04:00
John Preston
a11ca58f36 Fix Ctrl+Insert in hashtag search results. 2019-01-11 17:30:00 +04:00
John Preston
496d711684 Improve support shortcuts handling. 2019-01-11 17:30:00 +04:00
John Preston
219b824338 Refresh filtered results on more dialogs. 2019-01-11 17:30:00 +04:00
John Preston
df389a365c Display emoji set loading radial animation. 2019-01-11 17:30:00 +04:00
John Preston
aa2c52c1f8 Unpack and prepare emoji asynchronously. 2019-01-11 17:30:00 +04:00
John Preston
f48ae29f22 Load emoji sets from the cloud. 2019-01-11 17:30:00 +04:00
John Preston
de00e0e15c Add simple switch emoji set box. 2019-01-11 17:30:00 +04:00
John Preston
79fea49272 Add updating emoji on the run. 2019-01-11 17:30:00 +04:00
John Preston
8190b10680 Support custom emoji sets loading. 2019-01-11 17:30:00 +04:00
Omkar Nath Singh
1ebd9562a2 Update copyright year (#5559) 2019-01-07 11:36:54 +04:00
John Preston
ebaf63393f Fix build for old OS X and MacAppStore. 2019-01-06 15:22:18 +04:00
John Preston
7c168740d9 Update instructions for Xcode 10.1. 2019-01-05 16:34:34 +04:00
Gregory K
11b991cddc Add call settings (#5540) 2019-01-05 15:08:02 +04:00
John Preston
8306e58b75 Fix build in Xcode / GCC. 2018-12-28 19:41:06 +04:00
John Preston
4002739682 Suggest adding bots to channels as admins. 2018-12-28 15:42:58 +04:00
John Preston
c259921269 Use qualified names for App::main and App::wnd. 2018-12-28 11:14:00 +04:00
John Preston
2eb3041c1f Beta version 1.5.6.
- Fix crash on macOS.
2018-12-27 19:55:36 +04:00
John Preston
d539d9b5d2 Fix postponed calls from crl::on_main() on macOS.
In libdispatch crl::on_main() implementation we bypass Application::notify() frame.
So we handle event loop nesting control manually by wrapping all invokations done
through crl::on_main() with the same methods we do from Application::notify().
2018-12-27 13:34:12 +04:00
John Preston
d17c985bcb Beta version 1.5.5.
- Support for auto-download of files and music.
- Improved auto-download settings.
2018-12-27 09:26:19 +04:00
John Preston
e2668e7cfa Default auto-download 8 MB files. 2018-12-27 09:24:46 +04:00
Omkar Nath Singh
18c2c61bee Update Ubuntu support version (#5372) 2018-12-26 15:09:20 +03:00
23rd
be0b0c1984 Fixed an editing of unsupported messages. 2018-12-26 15:10:56 +04:00
John Preston
b00ca217b3 Don't autoread mentions with voice/video messages.
Voice/video message unread flag is the same that mention unread flag.
If we mark such mentions as read together with all others we mark
media as watched/listened instantly when they appear on the screen.

So now we mark as read only simple mentions, without "unread" media.
2018-12-26 14:30:55 +04:00
John Preston
874d76b16b Ignore activations from ~PopupMenu in file dialog event loops. 2018-12-26 13:54:49 +04:00
John Preston
cfac261516 Create Application before ConcurrentTimerEnvironment.
Fixes #5498.
2018-12-26 13:02:43 +04:00
John Preston
7b5e5c2587 Move caption to the next album item on cancel.
After #4869 albums are sent with captions in the first media.
In case we cancel the first media leaving the rest of the album
the caption will be lost unless we move it to the new "first" media.
2018-12-26 11:24:12 +04:00
John Preston
db064381d9 Re-update libtgvoip.
The submodule was rolled back in 0b87db8b45.
2018-12-26 11:20:01 +04:00
John Preston
096c310e0e Display consistent caption/comment placeholder.
After latest PRs regarding sticker sending with comment (#5500)
and album sending with caption (#4869) the input field placeholder
in SendFilesBox was inconsistent with the sending behaviour. Fix it.
2018-12-26 10:53:21 +04:00
udf
0b87db8b45 Ignore only empty drafts while sending with clear_draft (#5424) 2018-12-26 10:52:48 +04:00
John Preston
71cf4a4885 Change default autodownload settings. 2018-12-26 09:58:27 +04:00
John Preston
a0c6104fae Redesign auto download box. 2018-12-25 22:15:22 +04:00
John Preston
8e54ac4dcf Rename autolock_box module to auto_lock_box. 2018-12-25 22:15:22 +04:00
John Preston
97b0288c7d Add automatic loading of videos/files. 2018-12-25 22:15:22 +04:00
John Preston
e3cc8652e4 New structs for media autodownload settings. 2018-12-25 22:15:22 +04:00
John Preston
8708a001c7 Always display nice percent values.
Sum of percent values should never exceed 100%. If any two answers
received same amount of votes, they should show same percent values.
This way sum could be less than 100% (three answers, one vote each),
but this looks better than giving extra vote to some random answer.
2018-12-25 22:12:35 +04:00
John Preston
6fc4facddf Improve updates sending script. 2018-12-25 19:42:02 +04:00
John Preston
e5536880fb Improve mouse/keyboard selection interactions.
Fixes #5458.
2018-12-25 16:41:40 +04:00
John Preston
44ff8f92ac Fix crash with invalid custom langpacks. 2018-12-25 15:22:25 +04:00
John Preston
95208267de Fix applying langpacks from file. 2018-12-25 15:22:01 +04:00
John Preston
9c579e0d5b Fix crash in wrong confirm email button. 2018-12-25 14:53:47 +04:00
John Preston
d1be4c6d96 Fix crash with event loop nesting. 2018-12-25 14:11:10 +04:00
John Preston
a65afdac95 Fix crash in RevokePublicLinkBox. 2018-12-25 12:48:12 +04:00
John Preston
22b47925d4 Fix assertion violation in calls. 2018-12-25 12:21:00 +04:00
John Preston
f291e365e5 Add slide animations in CreatePollBox. 2018-12-25 11:41:22 +04:00
John Preston
6f176803d4 Reload poll data each 30 seconds without update. 2018-12-24 21:03:53 +04:00
John Preston
b6a3bb4080 Allow closing CreatePollBox by escape. 2018-12-24 17:13:44 +04:00
23rd
c7c1deab81 Add caption to first item of album istead of sending separated message. 2018-12-24 17:12:18 +04:00
RMPR
2ded5870b5 Update supported Fedora version (#5502) 2018-12-24 17:03:40 +04:00
John Preston
57f2ae098f Show exact option votes count in a tooltip.
Fixes #5505.
2018-12-24 14:24:16 +04:00
John Preston
76c06923d5 Add ripple animation to poll voting. 2018-12-24 14:03:13 +04:00
John Preston
fb7ac874f0 Show poll question in pinned bar. 2018-12-24 13:25:02 +04:00
John Preston
12905f0dcb Version 1.5.4: Fix build in Xcode. 2018-12-24 12:16:05 +04:00
John Preston
68a313a58f Version 1.5.4.
- Bug fixes and other minor improvements.
2018-12-23 21:37:26 +04:00
John Preston
152115bf2e Disable multiline poll options. 2018-12-23 21:28:12 +04:00
John Preston
8bd3051224 Fix crop photo box title. 2018-12-23 21:23:36 +04:00
John Preston
aa94ca6619 Fix stuck inline mode.
Regression was introduced in 017ec87d60.

Fixes #5503.
2018-12-23 20:57:34 +04:00
John Preston
e397f72eb2 Lock poll creating.
Fixes #5504.
2018-12-23 20:47:00 +04:00
John Preston
4d495b8d7c Fix votes count in RTL languages. 2018-12-23 20:42:32 +04:00
John Preston
a142a2717c Fix no votes label. 2018-12-23 20:37:32 +04:00
John Preston
de4a477686 Mark event loop nesting more carefully.
Fixes #5506. I hope fixes #5508.
2018-12-23 16:08:48 +04:00
John Preston
4e692e2c1e Version 1.5.3: Fix build for GCC. 2018-12-23 01:31:12 +04:00
John Preston
8237e6f7a3 Version 1.5.3.
- Create polls in groups and channels - right from the chat menu.
2018-12-23 00:30:55 +04:00
23rd
d1a9f1feac Fixed caption when sending single WEBP as file. 2018-12-23 00:27:36 +04:00
John Preston
ef1d38462f Simplest polls data export. 2018-12-23 00:23:19 +04:00
John Preston
93c8e9aa1f Add poll vote sending animation. 2018-12-22 23:32:04 +04:00
John Preston
ac2dce4bb1 Fix polls percent display. 2018-12-22 22:48:25 +04:00
John Preston
f2e1d90c74 Add send vote / retract vote animation. 2018-12-22 22:36:00 +04:00
John Preston
8e28a229f2 Improve polls design. 2018-12-22 14:23:22 +04:00
John Preston
363f6cb329 Add question / options length warnings. 2018-12-22 10:29:03 +04:00
John Preston
b6f7832745 Add create poll box from groups three-dot menu. 2018-12-22 10:29:03 +04:00
John Preston
74c1db740d Implement polls voting and actions. 2018-12-21 17:09:33 +04:00
John Preston
4bb5dcf50c Simplest poll layout. 2018-12-21 17:09:32 +04:00
John Preston
b0d01389c6 Add .terminal extension as executable on macOS. 2018-12-21 17:09:32 +04:00
John Preston
3e22ada889 Remove HistoryMediaType type-tag. 2018-12-21 17:09:32 +04:00
John Preston
6d08394adc Divide history_media_types to several modules. 2018-12-21 17:09:31 +04:00
John Preston
47bdeeef9a Poll data and updates handling added. 2018-12-21 17:09:31 +04:00
John Preston
099440d008 Add test poll sending code. 2018-12-21 17:09:30 +04:00
John Preston
eb7201a55b Strictly match message / media types. 2018-12-21 17:09:30 +04:00
John Preston
6d9f40db30 Update API scheme to layer 91. 2018-12-21 17:09:30 +04:00
John Preston
7960706e60 Update API scheme to layer 90. 2018-12-17 11:01:30 +04:00
John Preston
8b0e54a95c Fix macOS main menu items. 2018-12-17 10:45:48 +04:00
John Preston
89e8f0ccc3 Fix pt-br FAQ link. 2018-12-17 10:12:44 +04:00
John Preston
0f67f75bed Version 1.5.2: Fix unread mentions in workmode. 2018-12-13 16:31:03 +04:00
John Preston
4836173fe6 Version 1.5.2: Fix video message duration. 2018-12-13 15:33:38 +04:00
John Preston
7378ad00b0 Version 1.5.2.
- Bug fixes and other minor improvements.
2018-12-13 12:59:48 +04:00
John Preston
e876c9b6a6 Disable support shortcuts when not support mode.
Fixes #5453.
2018-12-13 12:48:31 +04:00
John Preston
980d20473a Fix building Qt and openal-soft for OS X 10.6/7. 2018-12-12 21:44:49 +04:00
John Preston
22511270dd Fix building openal-soft on Xcode. 2018-12-12 17:59:26 +04:00
John Preston
89cf733d24 Add Ui::PostponeCall() on return to event loop. 2018-12-12 14:14:28 +04:00
John Preston
a167a8587b Fix crash in main menu right button click.
Fixes #5462.
2018-12-12 09:47:24 +04:00
John Preston
ffbd488e93 Clone nimf plugin in Travis Qt build. 2018-12-11 17:39:24 +04:00
John Preston
fa3117e41e Version 1.5.1: Fix build for Xcode. 2018-12-11 17:21:47 +04:00
John Preston
4be335b8ac Version 1.5.1.
- Bug fixes and other minor improvements.
2018-12-11 17:13:47 +04:00
John Preston
3904a9f9a0 Add guard in layers destruction. 2018-12-11 17:12:35 +04:00
John Preston
b683d84df1 Report memory usage in MB. 2018-12-11 16:26:33 +04:00
John Preston
3ad29f6eb7 Fix crash in media preview. 2018-12-11 16:22:27 +04:00
John Preston
cf227490d7 Fix using of base langpack for custom languages. 2018-12-11 16:00:24 +04:00
John Preston
ffd6f7b326 Fix some more missing emoji display.
Fixes #5388.
2018-12-11 15:59:45 +04:00
John Preston
ec2a1b3ddb Fix some missing emoji display. 2018-12-11 11:17:19 +04:00
John Preston
60711471fc Return VB script for UWP version preparing. 2018-12-10 21:41:44 +04:00
John Preston
92738b378c Version 1.5: Fix calls. 2018-12-10 19:37:52 +04:00
John Preston
c5e9c03de9 Version 1.5.
- Support for custom languages. Crowdsource a cloud-based
language pack for Telegram in any language using our
Translations platform - then apply it in real time.
- Interface scaling for large screens, up to 300%
(up to 150% for macOS retina screens).
- 'Count unread messages' setting for the Badge counter
in Settings > Notifications. Disable to show number of unread chats.
- Video messages displayed in shared media (under voice messages).
- Updated emoji. Farewell to question marks!

Also in this update:
- Listen to voice and video messages in 2X mode if you're in a hurry.
- Add a comment when sharing posts from channels.
- View all photos and videos in Twitter and Instagram link previews.
- Add emoji to media captions.
2018-12-10 17:32:24 +04:00
John Preston
6637e5b8e3 Revert "Disable custom languages for now."
This reverts commit 679347309e.
2018-12-07 20:25:18 +04:00
John Preston
b75442a10e No warning from verified peers. 2018-12-07 20:19:47 +04:00
John Preston
811bef41b8 Add caption limit check to updates posting. 2018-12-07 20:19:47 +04:00
John Preston
65242a503b Remove test code for other emoji font. 2018-12-07 20:19:47 +04:00
John Preston
77058b84cd Fix scroll style in local storage box. 2018-12-06 12:56:13 +04:00
5HARK
673962d6a1 Add nimf inputcontext plugin for linux version (#5050) 2018-12-06 11:30:08 +04:00
John Preston
c207f68fd9 Build nimf input method plugin with Qt. 2018-12-06 11:28:24 +04:00
Anton Skorochod
4416dab6c1 Allow UnityCounters for KDE5 resolves #4554 2018-12-06 10:57:07 +04:00
John Preston
f59e824ec1 Possibly fix a crash in image loader. 2018-12-05 15:50:41 +04:00
John Preston
310c68a744 Disable DemiBold fallback for Semibold.
This reverts changes from commit 089c4ceb30.

There were complaints that Persian font becomes unreadable :(
2018-12-05 14:51:47 +04:00
John Preston
2d1971123a Always add 'Saved messages' to index. 2018-12-05 14:41:54 +04:00
John Preston
efe3dfad5c Fix crash in radiobutton destruction.
It crashed if the button was destroyed from group _changedCallback.
2018-12-05 13:55:59 +04:00
John Preston
b10ccce44a Warn before running executable files. 2018-12-05 12:30:05 +04:00
John Preston
edadc51e05 Fix possible crash in dialogs saved peers. 2018-12-05 12:30:05 +04:00
John Preston
0e38671224 Log Qt fatal message to crash report. 2018-12-05 12:30:05 +04:00
John Preston
910b2f2b74 Use upstream range-v3 in Appveyor build.
It still fails because it uses 15.8 toolchain. Will be fixed on 15.9.
2018-12-05 12:29:16 +04:00
John Preston
57387903fd Beta version 1.4.8.
- Add emoji to media captions.
- Switch off the 'Count unread messages' option
in Settings > Notifications if you want to see
the unread chats count in the badge instead.
2018-12-04 20:15:54 +04:00
23rd
8b1ac9fa6e Fixed skipping message with MediaWebPage on KeyUp. 2018-12-04 20:01:17 +04:00
23rd
ad8c0737d6 Refactored key handler in mediaview.cpp.
Refactored key handler in mediaview.cpp.
2018-12-04 19:23:08 +04:00
Jonathan de Jong
87d4d46ce7 Add IDs to JSON exports (#5426)
* Added IDs to various JSON objects.

Including an `_id` addition inside chat message, which get appended to `actor` or `from` entries.
2018-12-04 19:22:17 +04:00
John Preston
61add763ae Restart instead of Unblock for bots. 2018-12-04 15:46:07 +04:00
John Preston
6562a1f6af Add 'Count unread messages' option. 2018-12-04 14:32:48 +04:00
John Preston
71efd10c83 Fix crash on layer -> section migration. 2018-12-04 14:32:47 +04:00
John Preston
679347309e Disable custom languages for now. 2018-12-04 14:32:47 +04:00
John Preston
c8a05137f4 Fix mime type usage for some MP3 files.
They had "audio/mpeg3" instead of "audio/mp3". Fixes #5392.
2018-12-04 14:32:47 +04:00
John Preston
f56d80236e Ignore inline bot with overlapping markdown. 2018-12-04 14:32:47 +04:00
John Preston
1b19e870c0 Fix crash in channel setup box. 2018-12-04 14:32:46 +04:00
John Preston
684ce09bb5 Add some automation for updates posting. 2018-12-04 14:32:46 +04:00
John Preston
9f08faf263 Closed alpha version 1.4.7.6. 2018-12-03 19:33:35 +04:00
John Preston
3bd0efa91e Use 1.7x instead of 2x in voice messages. 2018-12-03 19:33:34 +04:00
John Preston
679330c1c0 Update download icons. 2018-12-03 19:33:34 +04:00
John Preston
47d5e54c48 Fix t.me/username links with upper-case letters. 2018-11-30 13:25:08 +04:00
John Preston
03b0c0cff4 Fix crash in forwarding box. 2018-11-30 09:45:22 +04:00
John Preston
776dd8b928 Closed alpha 1.4.7.5: Fix build on Xcode. 2018-11-29 16:53:54 +04:00
John Preston
c2a2f8dabd Closed alpha version 1.4.7.5. 2018-11-29 16:33:40 +04:00
John Preston
393244d44b Update libopus to 1.3. 2018-11-29 16:33:01 +04:00
John Preston
e6b9caac61 Update libtgvoip. 2018-11-29 16:15:22 +04:00
John Preston
81c4166389 Use CodeBlocks+Makefiles in cmake on Linux.
It gives the files layout in the Qt Creator.
2018-11-29 15:43:31 +04:00
John Preston
0b619e50ba HistoryHider moved to Window namespace. 2018-11-28 15:48:35 +04:00
John Preston
59ecf375b0 Move tg:// handlers to a separate module.
Also move joinGroupByHash and stickerSetBox from MainWidget.
2018-11-26 17:31:13 +04:00
John Preston
338129faea Destroy boxes in Ui::hideLayer(). 2018-11-26 15:00:31 +04:00
John Preston
151a64f817 Close mediaview on confirm link box.
Fixes #5420.
2018-11-26 11:41:27 +04:00
John Preston
3461f3dfc7 Destroy file loaders not delayed. 2018-11-26 11:33:29 +04:00
John Preston
23dc9ef494 Destroy layers not delayed. 2018-11-26 11:33:29 +04:00
John Preston
2fc5b69465 Fix auto word wrap in intro description. 2018-11-26 11:32:53 +04:00
John Preston
f8fc554f78 Closed alpha version 1.4.7.4. 2018-11-23 19:04:14 +04:00
John Preston
3f58c930e3 Use separate download folder for support. 2018-11-22 17:15:52 +04:00
John Preston
7705999e57 Don't occupy bot chats in support mode. 2018-11-22 17:00:14 +04:00
John Preston
0a754b8982 Adding emoji in SendFilesBox and EditCaptionBox. 2018-11-22 16:48:50 +04:00
John Preston
8d3f5820ca Allow TabbedSelector with only emoji. 2018-11-22 14:30:48 +04:00
John Preston
ef4f0168f8 Remove Qt MOC dependency for tabbed selector. 2018-11-22 10:50:41 +04:00
John Preston
9f5b09c263 Add emoji autocomplete to all fields. 2018-11-21 14:09:46 +04:00
John Preston
a1c61daea6 Add contact opens chat in support mode. 2018-11-21 10:51:49 +04:00
John Preston
90c1c21646 Fix switching between hashtag results. 2018-11-21 10:43:49 +04:00
John Preston
bf9069524a Allow long support user information. 2018-11-21 10:43:35 +04:00
John Preston
905376de1d By default load messages for the last week. 2018-11-21 10:43:07 +04:00
John Preston
6fa556e8ea Closed alpha version 1.4.7.3. 2018-11-20 19:50:36 +04:00
John Preston
9a8ab84ecb Add edit / view of user information for support. 2018-11-20 19:50:36 +04:00
John Preston
5e1b8212b2 Show tsfname in occupied chats. 2018-11-20 19:50:36 +04:00
John Preston
7ca821f38c Leave chats search query in support mode. 2018-11-20 19:50:36 +04:00
John Preston
5c718c7c9a Improve support template ordering. 2018-11-20 19:50:36 +04:00
John Preston
7e104805c0 Handle AUTH_KEY_UNREGISTERED on password submit. 2018-11-20 19:50:36 +04:00
John Preston
21fab77c4b Add support for incomplete login attempts. 2018-11-20 19:50:36 +04:00
John Preston
770f4a78aa Allow '-' character in code inputs. 2018-11-20 19:38:40 +04:00
John Preston
c522e047c6 Fix crash in support switches. 2018-11-20 19:38:40 +04:00
John Preston
92f6949ecc Closed alpha version 1.4.7.2. 2018-11-20 19:38:40 +04:00
John Preston
478eeea73e Add custom Qt message handler for crashes. 2018-11-20 19:38:40 +04:00
John Preston
163ee73719 Fix switch to prev/next in Support. 2018-11-20 19:38:40 +04:00
John Preston
479a6d9ad2 Add some more shortcuts for Support. 2018-11-20 19:38:40 +04:00
John Preston
b3ffbeb63e Improve code for Shortcuts handling. 2018-11-20 19:38:40 +04:00
John Preston
8a3615281c Support structured bindings in base::flat_map. 2018-11-20 19:38:40 +04:00
John Preston
d6b4448d3c Show reload toast inside Support::Templates. 2018-11-20 19:38:40 +04:00
John Preston
123523ef62 Separate some lang phrases. 2018-11-20 19:38:39 +04:00
John Preston
4960e08a24 Display occupied chats using drafts for support. 2018-11-20 19:38:39 +04:00
John Preston
60103f7ad6 Use upstream range-v3 on MSVC.
The build works using MSVS 15.9 and latest range-v3 code.
2018-11-20 19:38:39 +04:00
John Preston
d3a261de89 Scroll to cursor after template replacement. 2018-11-20 19:38:39 +04:00
John Preston
ecce1edded Unify version format in MainMenu / About. 2018-11-20 19:38:39 +04:00
John Preston
fb8eafab81 Fix migrating from legacy lang storage. 2018-11-20 19:38:39 +04:00
John Preston
a6de296703 Closed alpha version 1.4.7.1. 2018-11-20 19:38:39 +04:00
John Preston
be3e43e6cb Confirm 2sv recovery email by code. 2018-11-20 19:38:39 +04:00
John Preston
93678a07a8 Use API-provided translations link. 2018-11-20 19:38:39 +04:00
John Preston
155b8f1c45 Update API scheme to layer 89. 2018-11-20 19:38:39 +04:00
John Preston
e737fa59b3 Submit local Peer2PeerNobody setting to the cloud. 2018-11-16 20:17:58 +04:00
John Preston
8d27d8efcf Use cloud-based settings for p2p in calls. 2018-11-16 20:17:58 +04:00
John Preston
5174c002cf Update API scheme to layer 88. 2018-11-16 20:17:58 +04:00
John Preston
26b8515cb5 Improve languages box and language local storing.
Use current language native name instead of lng_language_name value.
2018-11-16 20:17:58 +04:00
John Preston
cf5bd31203 Suggest switch to even empty language. 2018-11-16 20:17:58 +04:00
John Preston
d485287a59 Close languages box by Escape key. 2018-11-16 20:17:58 +04:00
John Preston
d0e48a02a1 Apply lang pack versions from config. 2018-11-16 20:17:58 +04:00
John Preston
36b702702b Support [inputN|n]otifyBroadcasts setting. 2018-11-16 20:17:58 +04:00
John Preston
75db59a8bb Fix user and chat flags handling. 2018-11-16 20:17:58 +04:00
John Preston
48548e9303 Improve phrases for custom langpacks. 2018-11-16 20:17:58 +04:00
John Preston
5163905954 Add a Delete/Share menu for unofficial languages. 2018-11-16 20:17:58 +04:00
John Preston
27d58e1e2a Fix lang_auto boundaries check. (thanks Randl) 2018-11-16 20:17:58 +04:00
John Preston
78da810114 Extend pinned messages support.
Support them in saved messages and normal groups.
2018-11-16 20:17:58 +04:00
John Preston
6d65cf2382 Redesign languages box with a search filter. 2018-11-16 20:17:58 +04:00
John Preston
162da089ec Handle t.me/setlanguage links.
Also support custom langpacks with base langpacks.
2018-11-16 20:17:58 +04:00
John Preston
228fb2f80d Update API scheme to layer 87. 2018-11-16 20:17:58 +04:00
John Preston
8ed600bf3f Add some debug logs. 2018-11-16 20:17:58 +04:00
John Preston
e3b6e1325e Use AL_DIRECT_CHANNELS_SOFT for audio playback.
See https://github.com/telegramdesktop/tdesktop/issues/2580.
2018-11-16 20:17:58 +04:00
John Preston
9101d64b20 Show unavailable admin options as unchecked. 2018-11-16 20:17:58 +04:00
John Preston
089c4ceb30 Use DemiBold fallback for Open Sans Semibold. 2018-11-16 20:17:58 +04:00
23rd
dc8abc74ed Fixed editing of the last message on KeyUp.
Skip stickers, video-messages, call-messages and edit following message.
2018-11-16 20:10:19 +04:00
Vitaly Zaitsev
31e3a426a6 Refactored FallbackFontConfig() to use native Qt methods.
Signed-off-by: Vitaly Zaitsev <vitaly@easycoding.org>
2018-11-16 20:09:33 +04:00
23rd
00969df06f Made isAudioFile() check more strictly.
Thanks John Preston.
2018-11-15 09:43:39 +04:00
23rd
c482ccfd4e Show all audio in "Files" category with FILE layout. 2018-11-15 09:43:39 +04:00
Nicholas Guriev
b6432e7d13 Switch to Ayatana Indicators 2018-11-13 10:30:54 +04:00
Omkar Nath Singh
35a3cb35d5 OpenAL soft license link update (#5379) 2018-11-12 22:42:37 +03:00
John Preston
2cadabd60c Added fc-custom.conf to git. 2018-11-12 17:36:24 +04:00
John Preston
997d1fbc80 Move custom fonts.conf to resources. 2018-11-12 17:34:47 +04:00
John Preston
8ee958bfa0 Force custom bundled fonts.conf if fontconfig is new.
If system fontconfig version is 2.13 or above use custom FONTCONFIG_FILE.
Fixes #4493, fixes #4240.
2018-11-12 15:26:36 +04:00
John Preston
8b64c96381 Separate some lang keys.
Fixes #5146.
2018-11-12 14:39:22 +04:00
John Preston
aba6cc2c64 Don't force WEBP format for stickers.
Fixes #5374.
2018-11-12 14:39:21 +04:00
John Preston
0718520f36 Disable default fallback to Segoe UI.
Fixes #5368.
2018-11-12 14:39:21 +04:00
John Preston
93b7a797d2 Allow non-lower template keys replacements. 2018-11-12 14:39:21 +04:00
John Preston
4ab0e693c1 Write memory usage to crashdump on Windows. 2018-11-12 14:39:21 +04:00
John Preston
af5f85a288 Fix crash with dangling DocumentData pointers. 2018-11-12 14:39:20 +04:00
John Preston
0a69f3c7fd Beta version 1.4.7.
- Crash fix.
2018-11-10 12:16:40 +04:00
John Preston
48889ce56e Better fix for a crash on quit. 2018-11-10 12:16:29 +04:00
John Preston
4532e59933 Beta version 1.4.6: Fix crash on quit. 2018-11-10 10:10:47 +04:00
John Preston
91d784f9bd Beta version 1.4.6: Fix libtgvoip for Linux. 2018-11-09 21:29:40 +04:00
John Preston
6f56097c53 Beta version 1.4.6.
- Bug fixes and other minor improvements.
2018-11-09 20:13:59 +04:00
John Preston
5b0ad0508a Update libtgvoip. 2018-11-09 20:13:59 +04:00
John Preston
f1c06d6743 Store StickerData::image in unique_ptr. 2018-11-09 19:16:47 +04:00
John Preston
e5949dbb86 Restore player delegate non-delayed (crashfix). 2018-11-09 19:16:27 +04:00
John Preston
2b95b96fa3 Store replyPreview in unique_ptr<Image>. 2018-11-09 19:14:31 +04:00
John Preston
147079ce2a Fix crash in unloaded userpic handling. 2018-11-09 18:01:54 +04:00
John Preston
e992702783 Load chats in chunks in support mode. 2018-11-09 17:54:34 +04:00
John Preston
2d05281ba9 Add configuration for OpenAL effects usage. 2018-11-09 16:28:15 +04:00
John Preston
9a1069c1ae Fix resuming audio on call end. 2018-11-09 11:27:12 +04:00
John Preston
561d3e0670 Beta version 1.4.5: Fix build script. 2018-11-08 22:00:08 +04:00
John Preston
d7a41ce8f7 Beta version 1.4.5.
- Listen to voice and video messages in 2X mode if you're in a hurry.
- Find video messages in the shared voice messages section.
- Add a comment when you share posts from channels.
- View all photos and videos in Twitter and Instagram link previews.
- Bug fixes and other minor improvements.
2018-11-08 17:29:29 +04:00
John Preston
784b0a2248 Revert "Show invite link owner in service message."
This reverts commit 27103889a4.
2018-11-08 17:17:00 +04:00
John Preston
346cb4e203 Fix some bugs in double playback speed.
- Apply double speed for all voice tracks, not only for the current.
- Use dedicated atomic in Mixer for the voice speed (fix race).
- Store the playback speed in user settings, not in global settings.
- Use float64 for setting (just consistency, no float-s right now).
2018-11-08 17:06:22 +04:00
Magnus Groß
de8518a112 Implement double playback speed
This adds double playback speed for both voice messages and round video
messages.
The 2x playback speed setting is global and is saved in local storage.

Fixes #4907
2018-11-08 17:05:34 +04:00
John Preston
8ef67c393b Fix build after openal-soft update.
Regression was introduced in 91c85ec86b.
2018-11-08 15:27:06 +04:00
Kirill Romanov
496c361bdc Gnome notification fix (#5215)
* Set notification desktop entry hint

* Set X-GNOME-UsesNotifications flag
2018-11-08 14:58:04 +04:00
John Preston
3646301ce4 Fix build for old OS X versions. 2018-11-08 14:48:15 +04:00
Magnus Groß
9042109d04 Travis: Fix failing to remove OpenAL Cache
rm: cannot remove ‘include/AL/al.h’: Permission denied

See https://travis-ci.org/telegramdesktop/tdesktop/jobs/452071589 for
more info
2018-11-08 10:50:53 +04:00
Magnus Groß
91c85ec86b Update OpenAL-Soft
Update to version 1.19.1
2018-11-08 10:50:53 +04:00
John Preston
7d3919e3f7 Correctly parse version in the snap. 2018-11-08 10:50:26 +04:00
John Preston
3a928aac9f Update version by a python script. 2018-11-08 10:35:48 +04:00
John Preston
8b6e24e83d Build alphas only for official targets. 2018-11-08 10:33:44 +04:00
John Preston
ef38572d5a Detect and send supports_streaming bit for videos. 2018-11-07 18:10:00 +04:00
John Preston
a2b04c9d71 Improve checks for a hidden webpage url. 2018-11-07 14:55:38 +04:00
23rd
c20ab0b93e Removed unused variables in input_fields.cpp. 2018-11-07 14:53:21 +04:00
John Preston
c496a34f57 Fix single accented letter suggestion in hashtags.
Fixes #5335.
2018-11-07 14:28:35 +04:00
John Preston
27103889a4 Show invite link owner in service message. 2018-11-07 14:28:35 +04:00
Marco Trevisan (Treviño)
e781b29d57 snap: use own app_id and api_hash 2018-11-07 14:28:22 +04:00
John Preston
751506d5b5 Better adjust shared media count. 2018-11-06 13:50:31 +04:00
John Preston
2061248224 Push stable / beta commits to launchpad on release. 2018-11-06 13:49:48 +04:00
Marco Trevisan (Treviño)
dcb748c544 destkop: add keywords stanza
They are used by mayor desktops to search through apps.

Remove this modification from snapcraft
2018-11-06 09:50:59 +04:00
Marco Trevisan (Treviño)
ec37867d72 snap: copy .desktop file and icon from part source path 2018-11-06 09:50:59 +04:00
Marco Trevisan (Treviño)
20c1b58307 snap: use content interfaces for themes icons and sounds
Reduce the space used and support proper theming
2018-11-06 09:50:59 +04:00
John Preston
e482f041a8 Allow disabling even system proxy settings.
Fixes #4944.
2018-11-05 18:52:01 +04:00
John Preston
ef64d9c188 Show round videos in Info layer. 2018-11-05 17:18:54 +04:00
John Preston
466444e17d Extract float player controller. 2018-11-05 15:16:09 +04:00
John Preston
b420f5b41b Fix crash in round video playback. 2018-11-05 14:00:53 +04:00
John Preston
53a719e1b1 Display round videos in shared voice messages. 2018-11-05 12:22:09 +04:00
John Preston
5f665b8ecb Add a comment field to ShareBox. 2018-11-04 15:58:32 +04:00
John Preston
65b2db2160 Don't provide 'api_id' and 'api_hash' by default.
We ask the developer to obtain his own api credentials, because
the bundled 'api_id' / 'api_hash' are strictly limited by the server.

The old credentials still could be used for test purposes,
but the developer will need to explicitly opt-in to use them.
2018-11-04 15:57:50 +04:00
John Preston
617d21129f Show confirmation on hidden webpage url. 2018-11-04 15:51:40 +04:00
John Preston
2d1fdc4485 Seek video to start if position is small. 2018-11-04 15:51:40 +04:00
John Preston
5aa2e66d02 Show large photos in web pages with IV. 2018-11-04 15:51:40 +04:00
John Preston
8850d974a2 Pass correct FileOrigin for userpics. 2018-11-04 15:51:40 +04:00
John Preston
e6c4c48261 Animate check in album sending. 2018-11-04 15:51:39 +04:00
John Preston
8eb0f3b60a Remove some unneeded Q_OBJECTs. 2018-11-04 15:51:39 +04:00
John Preston
5192049194 Resume audio when call ends. 2018-11-04 15:51:39 +04:00
John Preston
fabf830132 Allow up to 128 MB of cached images. 2018-11-04 15:51:39 +04:00
John Preston
c9159e2191 Clear memory on MediaView closing. 2018-11-04 15:51:39 +04:00
John Preston
f2348fc749 Fix document unloading. 2018-11-04 15:51:39 +04:00
John Preston
264ab285a7 Fix ImageSource unloading. 2018-11-04 15:51:39 +04:00
John Preston
f28a92be1d Fix another crash in DocumentData destructor. 2018-11-04 15:51:39 +04:00
John Preston
d38a6e5047 Closed alpha version 1.4.4.2. 2018-11-04 15:51:39 +04:00
John Preston
3447aac940 Prefix client-side lang_code-s with #. 2018-11-04 15:51:39 +04:00
John Preston
711b8cfa36 Fix auto interface scale by primary screen dpi. 2018-11-04 15:51:39 +04:00
John Preston
91a6af71a0 Limit video messages size. 2018-11-04 15:51:39 +04:00
John Preston
885e7f0471 Fix pen reset in TextPainter of empty text. 2018-11-04 15:51:39 +04:00
John Preston
8c1e546123 Fix crash in DocumentData destructor.
~DocumentData sometimes calls ~Image that calls RemoteSource::unload.
It tries to schedule delayed loaded deletion and accesses Auth().
But ~DocumentData is called from ~Session, so Auth() is unaccessible.
2018-11-04 15:51:39 +04:00
John Preston
fd4dedcbdf Use good video thumbnail in albums. 2018-11-04 15:51:39 +04:00
John Preston
88a82eecf3 Fix crash in unloaded null Image. 2018-11-04 15:51:39 +04:00
John Preston
906122a334 Insert Segoe UI and San Francisco font substitutions.
Fixes #1791, fixes #3354, fixes #4454.
2018-11-04 15:51:39 +04:00
John Preston
6f1529d730 Backport Qt fix for font weights on macOS Mojave. 2018-11-04 15:51:39 +04:00
John Preston
46162ed3c4 Fix grouped media corner in one layout. 2018-11-04 15:51:39 +04:00
John Preston
3b911f19f6 Fix collage/slideshow extracting in GCC.
It was depending on argument evaluation order before that fix.
2018-11-04 15:51:39 +04:00
John Preston
4e6f55e176 Closed alpha version 1.4.4.1: Fix build for macOS. 2018-11-04 15:51:38 +04:00
John Preston
14cae1b59a Closed alpha version 1.4.4.1. 2018-11-04 15:51:38 +04:00
John Preston
9aa23dac80 Fix ripple glitch on theme switching. 2018-11-04 15:51:38 +04:00
John Preston
eb099c70e6 Fix removing members from search results.
Fixes #5236.
2018-11-04 15:51:38 +04:00
John Preston
4837117719 Use photo as video thumbnail in WebPageData. 2018-11-04 15:51:38 +04:00
John Preston
550b67236e Reactive main window only if app is active.
Otherwise when we choose "Show in Folder" app looses focus,
then destroys PopupMenu and instantly regains focus back.
2018-11-04 15:51:38 +04:00
John Preston
8000ff2cd7 Generate high quality thumbnail on sending video. 2018-11-04 15:51:38 +04:00
John Preston
da358615e0 Generate high quality video thumbnail when loaded. 2018-11-04 15:51:38 +04:00
John Preston
8f387891e2 Show group / channel in ConfirmInviteBox. 2018-11-04 15:51:38 +04:00
John Preston
a961615076 Clear unused emoji cache with DB. 2018-11-04 15:51:38 +04:00
John Preston
bf31722931 Show collage/slideshow as an album in MediaView. 2018-11-04 15:51:38 +04:00
John Preston
251f51ca1b Show collage/slideshow as an album in web page. 2018-11-04 15:51:38 +04:00
John Preston
e8722e1cb2 Separate (c), (r), (tm) and emoji.
Fixes #3300.
2018-11-04 15:51:38 +04:00
John Preston
6db4972208 Fix blurry App Switcher icon on macOS.
Fixes #5267.
2018-11-04 15:51:38 +04:00
John Preston
f0e18ac619 Add better unloading for ImageSource. 2018-11-04 15:51:38 +04:00
John Preston
8e7117fa22 Don't unload all media on switching between chats. 2018-11-04 15:51:38 +04:00
John Preston
959859f57c Forget least used documents gradually. 2018-11-04 15:51:37 +04:00
John Preston
f8eef7c9a6 Forget least used images gradually. 2018-11-04 15:51:37 +04:00
John Preston
595134cab5 Move image-related modules to ui/image/. 2018-11-04 15:51:37 +04:00
John Preston
8b76428c7e Create ImagePtr-s using a factory method. 2018-11-04 15:51:37 +04:00
John Preston
591fbf0ec6 Replace image source after photo sending. 2018-11-04 15:51:37 +04:00
John Preston
4b5b79e415 Use final Image with different Images::Source-s. 2018-11-04 15:51:37 +04:00
John Preston
5a50248055 Remove Image::toDelayedStorageImage downcaster. 2018-11-04 15:51:36 +04:00
John Preston
113f665295 Move Image and derived to ui/image. 2018-11-04 15:51:36 +04:00
John Preston
d56a3d015b Add more plural rules support. 2018-11-04 15:51:36 +04:00
John Preston
85c59762a4 Fix broken emoji. 2018-11-04 15:51:36 +04:00
John Preston
01b4e1946a Show reset scale button if window doesn't fit. 2018-11-04 15:51:36 +04:00
Viktor Oreshkin
17cde3426a Update CONTRIBUTING.md
Add translations (see #5273)
2018-11-04 15:49:14 +04:00
836 changed files with 69554 additions and 38878 deletions

View File

@@ -27,7 +27,7 @@ GOTO:EOF
call:logInfo "Clone dependencies repository"
git clone -q --depth 1 --branch=master https://github.com/telegramdesktop/dependencies_windows.git %LIB_DIR%
cd %LIB_DIR%
git clone https://github.com/Microsoft/Range-V3-VS2015 range-v3
git clone https://github.com/ericniebler/range-v3
if exist prepare.bat (
call prepare.bat
) else (
@@ -48,7 +48,7 @@ GOTO:EOF
git submodule init
git submodule update
cd %SRC_DIR%\Telegram
call gyp\refresh.bat
call gyp\refresh.bat --api-id 17349 --api-hash 344583e45741c457fe1862106095a5eb
GOTO:EOF
:configureBuild
@@ -72,10 +72,6 @@ GOTO:EOF
set TDESKTOP_BUILD_DEFINES=%TDESKTOP_BUILD_DEFINES%,TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION
)
echo %BUILD_VERSION% | findstr /C:"disable_unity_integration">nul && (
set TDESKTOP_BUILD_DEFINES=%TDESKTOP_BUILD_DEFINES%,TDESKTOP_DISABLE_UNITY_INTEGRATION
)
echo %BUILD_VERSION% | findstr /C:"disable_gtk_integration">nul && (
set TDESKTOP_BUILD_DEFINES=%TDESKTOP_BUILD_DEFINES%,TDESKTOP_DISABLE_GTK_INTEGRATION
)

View File

@@ -24,6 +24,8 @@ If we find issues with your pull request, we may suggest some changes and improv
Unfortunately we **do not merge** any pull requests that have new feature implementations, translations to new languages and those which introduce any new user interface elements.
If you have a translations-related contribution, check out [Translations platform][translate].
Telegram Desktop is not a standalone application but a part of [Telegram project][telegram], so all the decisions about the features, languages, user experience, user interface and the design are made inside Telegram team, often according to some roadmap which is not public.
## Build instructions
@@ -113,3 +115,4 @@ Before you submit a pull request, please test your changes. Verify that Telegram
[pr]: https://github.com/telegramdesktop/tdesktop/compare
[build_instructions]: https://github.com/telegramdesktop/tdesktop/blob/master/README.md#build-instructions
[closing-issues-via-commit-messages]: https://help.github.com/articles/closing-issues-via-commit-messages/
[translate]: https://translations.telegram.org

View File

@@ -14,7 +14,6 @@ env:
- BUILD_VERSION="disable_crash_reports"
- BUILD_VERSION="disable_network_proxy"
- BUILD_VERSION="disable_desktop_file_generation"
- BUILD_VERSION="disable_unity_integration"
- BUILD_VERSION="disable_gtk_integration"
matrix:
@@ -45,7 +44,7 @@ addons:
- libopus-dev
- libpulse-dev
- libssl-dev
- libunity-dev
- libdee-dev
- libva-dev
- libvdpau-dev
- libxcb-xkb-dev

View File

@@ -17,7 +17,7 @@ XKB_PATH="$BUILD/libxkbcommon"
XKB_CACHE_VERSION="3"
QT_PATH="$BUILD/qt"
QT_CACHE_VERSION="3"
QT_CACHE_VERSION="4"
QT_PATCH="$UPSTREAM/Telegram/Patches/qtbase_${QT_VERSION//\./_}.diff"
BREAKPAD_PATH="$BUILD/breakpad"
@@ -40,7 +40,7 @@ FFMPEG_PATH="$BUILD/ffmpeg"
FFMPEG_CACHE_VERSION="3"
OPENAL_PATH="$BUILD/openal-soft"
OPENAL_CACHE_VERSION="3"
OPENAL_CACHE_VERSION="4"
GYP_DEFINES=""
@@ -116,10 +116,6 @@ build() {
GYP_DEFINES+=",TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION"
fi
if [[ $BUILD_VERSION == *"disable_unity_integration"* ]]; then
GYP_DEFINES+=",TDESKTOP_DISABLE_UNITY_INTEGRATION"
fi
if [[ $BUILD_VERSION == *"disable_gtk_integration"* ]]; then
GYP_DEFINES+=",TDESKTOP_DISABLE_GTK_INTEGRATION"
fi
@@ -318,6 +314,7 @@ buildVdpau() {
git clone git://anongit.freedesktop.org/vdpau/libvdpau
cd "$EXTERNAL/libvdpau"
git checkout libvdpau-1.2
./autogen.sh --prefix=$VDPAU_PATH --enable-static
make $MAKE_ARGS
sudo make install
@@ -472,10 +469,12 @@ buildOpenAL() {
rm -rf "$EXTERNAL/openal-soft"
fi
cd $OPENAL_PATH
rm -rf *
sudo rm -rf *
cd "$EXTERNAL"
git clone https://github.com/kcat/openal-soft.git
cd openal-soft
git checkout openal-soft-1.19.1
cd "$EXTERNAL/openal-soft/build"
cmake \
@@ -602,6 +601,7 @@ buildCustomQt() {
cd "$EXTERNAL/qt${QT_VERSION}/qtbase/src/plugins/platforminputcontexts"
git clone https://github.com/telegramdesktop/fcitx.git
git clone https://github.com/telegramdesktop/hime.git
git clone https://github.com/telegramdesktop/nimf.git
cd ../../../..
./configure -prefix $QT_PATH -release -opensource -confirm-license -qt-zlib \
@@ -673,6 +673,8 @@ buildTelegram() {
cd "$UPSTREAM/Telegram/gyp"
"$GYP_PATH/gyp" \
-Dapi_id=17349 \
-Dapi_hash=344583e45741c457fe1862106095a5eb \
-Dbuild_defines=${GYP_DEFINES:1} \
-Dlinux_path_xkbcommon=$XKB_PATH \
-Dlinux_path_va=$VA_PATH \

2
LEGAL
View File

@@ -1,7 +1,7 @@
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
Copyright (c) 2014-2018 John Preston, https://desktop.telegram.org
Copyright (c) 2014-2019 John Preston, https://desktop.telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -15,8 +15,8 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
* Windows XP - Windows 10 (**not** RT)
* Mac OS X 10.8 - Mac OS X 10.11
* Mac OS X 10.6 - Mac OS X 10.7 (separate build)
* Ubuntu 12.04 - Ubuntu 18.04
* Fedora 22 - Fedora 28
* Ubuntu 12.04 - Ubuntu 18.10
* Fedora 22 - Fedora 29
* [Snappy](https://snapcraft.io/telegram-desktop)
## Third-party
@@ -31,7 +31,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
* Google Crashpad ([Apache License 2.0](https://chromium.googlesource.com/crashpad/crashpad/+/master/LICENSE))
* GYP ([BSD License](https://github.com/bnoordhuis/gyp/blob/master/LICENSE))
* Ninja ([Apache License 2.0](https://github.com/ninja-build/ninja/blob/master/COPYING))
* OpenAL Soft ([LGPL](http://kcat.strangesoft.net/openal.html))
* OpenAL Soft ([LGPL](https://github.com/kcat/openal-soft/blob/master/COPYING))
* Opus codec ([BSD License](http://www.opus-codec.org/license/))
* FFmpeg ([LGPL](https://www.ffmpeg.org/legal.html))
* Guideline Support Library ([MIT License](https://github.com/Microsoft/GSL/blob/master/LICENSE))
@@ -45,7 +45,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
## Build instructions
* [Visual Studio 2017][msvc]
* [Xcode 9][xcode]
* [Xcode 10][xcode]
* [GYP/CMake on GNU/Linux][cmake]
[//]: # (LINKS)

View File

@@ -1,5 +1,5 @@
diff --git a/src/build/common.gypi b/src/build/common.gypi
index 29990c6..53e99d4 100644
index 29990c65..53e99d44 100644
--- a/src/build/common.gypi
+++ b/src/build/common.gypi
@@ -330,6 +330,7 @@
@@ -11,7 +11,7 @@ index 29990c6..53e99d4 100644
},
}],
diff --git a/src/client/mac/Breakpad.xcodeproj/project.pbxproj b/src/client/mac/Breakpad.xcodeproj/project.pbxproj
index 1a93ce6..1c1d643 100644
index 1a93ce6d..b5986e33 100644
--- a/src/client/mac/Breakpad.xcodeproj/project.pbxproj
+++ b/src/client/mac/Breakpad.xcodeproj/project.pbxproj
@@ -35,6 +35,19 @@
@@ -34,7 +34,15 @@ index 1a93ce6..1c1d643 100644
162F64F2161C577500CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F0161C577500CD68D5 /* arch_utilities.cc */; };
162F64F3161C577500CD68D5 /* arch_utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 162F64F1161C577500CD68D5 /* arch_utilities.h */; };
162F64F4161C579B00CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F0161C577500CD68D5 /* arch_utilities.cc */; };
@@ -170,11 +183,8 @@
@@ -67,6 +80,7 @@
4DBE49A7134A4F280072546A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBE4769134A4F080072546A /* CoreServices.framework */; };
4DBE49A8134A4F380072546A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBE4769134A4F080072546A /* CoreServices.framework */; };
4DBE49A9134A4F460072546A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DBE4769134A4F080072546A /* CoreServices.framework */; };
+ 5A8B220921E0C5740045F83C /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; };
8B3101C611F0CD9F00FCF3E4 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D6A5FE840307C02AAC07 /* AppKit.framework */; };
8B3101C711F0CD9F00FCF3E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; };
8B3101CA11F0CDB000FCF3E4 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D6A5FE840307C02AAC07 /* AppKit.framework */; };
@@ -170,11 +184,8 @@
F92C564A0ECD10CA009BE4BA /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53850ECCE6AD009BE4BA /* string_conversion.cc */; };
F92C564C0ECD10DD009BE4BA /* breakpadUtilities.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F92C563C0ECD10B3009BE4BA /* breakpadUtilities.dylib */; };
F92C56570ECD113E009BE4BA /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F92C554A0ECCF530009BE4BA /* Carbon.framework */; };
@@ -46,7 +54,7 @@ index 1a93ce6..1c1d643 100644
F92C56A90ECE04C5009BE4BA /* crash_report_sender.m in Sources */ = {isa = PBXBuildFile; fileRef = F92C56A80ECE04C5009BE4BA /* crash_report_sender.m */; };
F93803CD0F8083B7004D428B /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536B0ECCE3FD009BE4BA /* dynamic_images.cc */; };
F93803CE0F8083B7004D428B /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536D0ECCE3FD009BE4BA /* exception_handler.cc */; };
@@ -213,7 +223,6 @@
@@ -213,7 +224,6 @@
F9C44DBD0EF072A0003AEBAA /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F9C44DBA0EF072A0003AEBAA /* MainMenu.xib */; };
F9C44E000EF077CD003AEBAA /* Breakpad.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Breakpad.framework */; };
F9C44E3C0EF08B12003AEBAA /* Breakpad.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Breakpad.framework */; };
@@ -54,7 +62,7 @@ index 1a93ce6..1c1d643 100644
F9C44EA20EF09F93003AEBAA /* HTTPMultipartUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = F92C53770ECCE635009BE4BA /* HTTPMultipartUpload.m */; };
F9C44EE50EF0A006003AEBAA /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9C44EE40EF0A006003AEBAA /* SystemConfiguration.framework */; };
F9C44EE90EF0A3C1003AEBAA /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C44EE80EF0A3C1003AEBAA /* GTMLogger.m */; };
@@ -410,20 +419,6 @@
@@ -410,20 +420,6 @@
remoteGlobalIDString = F92C563B0ECD10B3009BE4BA;
remoteInfo = breakpadUtilities;
};
@@ -75,7 +83,7 @@ index 1a93ce6..1c1d643 100644
F93DE2FB0F82C3C600608B94 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
@@ -536,13 +531,6 @@
@@ -536,13 +532,6 @@
remoteGlobalIDString = 8DC2EF4F0486A6940098B216;
remoteInfo = Breakpad;
};
@@ -89,7 +97,7 @@ index 1a93ce6..1c1d643 100644
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -714,7 +702,6 @@
@@ -714,7 +703,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -97,7 +105,7 @@ index 1a93ce6..1c1d643 100644
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1181,18 +1168,13 @@
@@ -1181,18 +1169,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "Breakpad" */;
buildPhases = (
@@ -116,7 +124,7 @@ index 1a93ce6..1c1d643 100644
);
name = Breakpad;
productInstallPath = "$(HOME)/Library/Frameworks";
@@ -1399,6 +1381,8 @@
@@ -1399,6 +1382,8 @@
/* Begin PBXProject section */
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
@@ -125,7 +133,7 @@ index 1a93ce6..1c1d643 100644
buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "Breakpad" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
@@ -1583,16 +1567,6 @@
@@ -1583,16 +1568,6 @@
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
@@ -142,7 +150,7 @@ index 1a93ce6..1c1d643 100644
F92C569C0ECE04A7009BE4BA /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -1640,20 +1614,6 @@
@@ -1640,20 +1615,6 @@
shellPath = /bin/sh;
shellScript = "install_name_tool -id \"@executable_path/../Resources/breakpadUtilities.dylib\" \"${BUILT_PRODUCTS_DIR}/breakpadUtilities.dylib\"\n";
};
@@ -163,10 +171,11 @@ index 1a93ce6..1c1d643 100644
F9C77DD80F7DD5CF0045F7DB /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -1674,6 +1634,19 @@
@@ -1674,6 +1635,20 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 5A8B220921E0C5740045F83C /* breakpad_nlist_64.cc in Sources */,
+ 0748C0501C63C52D004489BF /* bootstrap_compat.cc in Sources */,
+ 0748C04F1C63C523004489BF /* macho_walker.cc in Sources */,
+ 0748C04E1C63C51C004489BF /* md5.cc in Sources */,
@@ -183,7 +192,7 @@ index 1a93ce6..1c1d643 100644
F92C565F0ECD116B009BE4BA /* protected_memory_allocator.cc in Sources */,
F92C56630ECD1179009BE4BA /* exception_handler.cc in Sources */,
F92C55D10ECD0064009BE4BA /* Breakpad.mm in Sources */,
@@ -1955,16 +1928,6 @@
@@ -1955,16 +1930,6 @@
target = F92C563B0ECD10B3009BE4BA /* breakpadUtilities */;
targetProxy = F92C564D0ECD10E5009BE4BA /* PBXContainerItemProxy */;
};
@@ -200,7 +209,7 @@ index 1a93ce6..1c1d643 100644
F93DE2FC0F82C3C600608B94 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = F93803BD0F80820F004D428B /* generator_test */;
@@ -2025,11 +1988,6 @@
@@ -2025,11 +1990,6 @@
target = 8DC2EF4F0486A6940098B216 /* Breakpad */;
targetProxy = F9C44E190EF0790F003AEBAA /* PBXContainerItemProxy */;
};
@@ -212,7 +221,7 @@ index 1a93ce6..1c1d643 100644
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@@ -2126,8 +2084,12 @@
@@ -2126,8 +2086,12 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 8B31027711F0D3AF00FCF3E4 /* BreakpadDebug.xcconfig */;
buildSettings = {
@@ -226,7 +235,7 @@ index 1a93ce6..1c1d643 100644
};
name = Debug;
};
@@ -2135,7 +2097,12 @@
@@ -2135,7 +2099,12 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 8B31027811F0D3AF00FCF3E4 /* BreakpadRelease.xcconfig */;
buildSettings = {
@@ -239,7 +248,7 @@ index 1a93ce6..1c1d643 100644
};
name = Release;
};
@@ -2454,7 +2421,12 @@
@@ -2454,7 +2423,12 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 8B31027711F0D3AF00FCF3E4 /* BreakpadDebug.xcconfig */;
buildSettings = {
@@ -253,7 +262,7 @@ index 1a93ce6..1c1d643 100644
name = "Debug With Code Coverage";
};
diff --git a/src/client/mac/Framework/Breakpad.mm b/src/client/mac/Framework/Breakpad.mm
index 1d2e519..943310f 100644
index 1d2e519b..943310fa 100644
--- a/src/client/mac/Framework/Breakpad.mm
+++ b/src/client/mac/Framework/Breakpad.mm
@@ -355,10 +355,10 @@ bool Breakpad::Initialize(NSDictionary *parameters) {
@@ -480,7 +489,7 @@ index 1d2e519..943310f 100644
}
diff --git a/src/common/language.cc b/src/common/language.cc
index 978fb85..a95ae5f 100644
index 978fb855..a95ae5f7 100644
--- a/src/common/language.cc
+++ b/src/common/language.cc
@@ -46,8 +46,27 @@
@@ -552,7 +561,7 @@ index 978fb85..a95ae5f 100644
#endif
}
diff --git a/src/common/linux/elf_symbols_to_module.cc b/src/common/linux/elf_symbols_to_module.cc
index 562875e..4367851 100644
index 562875e1..43678510 100644
--- a/src/common/linux/elf_symbols_to_module.cc
+++ b/src/common/linux/elf_symbols_to_module.cc
@@ -39,6 +39,29 @@
@@ -615,7 +624,7 @@ index 562875e..4367851 100644
module->AddExtern(ext);
}
diff --git a/src/tools/linux/tools_linux.gypi b/src/tools/linux/tools_linux.gypi
index 1c15992..020e4c1 100644
index 1c15992e..020e4c1c 100644
--- a/src/tools/linux/tools_linux.gypi
+++ b/src/tools/linux/tools_linux.gypi
@@ -58,7 +58,7 @@
@@ -627,3 +636,16 @@ index 1c15992..020e4c1 100644
],
'dependencies': [
'../common/common.gyp:common',
diff --git a/src/tools/mac/dump_syms/macho_dump.cc b/src/tools/mac/dump_syms/macho_dump.cc
index d882bbe8..3432bb45 100644
--- a/src/tools/mac/dump_syms/macho_dump.cc
+++ b/src/tools/mac/dump_syms/macho_dump.cc
@@ -140,7 +140,7 @@ void DumpFile(const char *filename) {
size_t object_files_size;
const SuperFatArch* super_fat_object_files =
fat_reader.object_files(&object_files_size);
- struct fat_arch *object_files;
+ struct fat_arch *object_files = 0;
if (!super_fat_object_files->ConvertToFatArch(object_files)) {
exit(1);
}

View File

@@ -12,7 +12,108 @@ pacman --noconfirm -S pkg-config
PKG_CONFIG_PATH="/mingw64/lib/pkgconfig:$PKG_CONFIG_PATH"
./configure --toolchain=msvc --disable-programs --disable-doc --disable-everything --enable-protocol=file --enable-libopus --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=aasc --enable-decoder=flac --enable-decoder=gif --enable-decoder=h264 --enable-decoder=mp1 --enable-decoder=mp1float --enable-decoder=mp2 --enable-decoder=mp2float --enable-decoder=mp3 --enable-decoder=mp3adu --enable-decoder=mp3adufloat --enable-decoder=mp3float --enable-decoder=mp3on4 --enable-decoder=mp3on4float --enable-decoder=mpeg4 --enable-decoder=msmpeg4v2 --enable-decoder=msmpeg4v3 --enable-decoder=wavpack --enable-decoder=opus --enable-decoder=pcm_alaw --enable-decoder=pcm_alaw_at --enable-decoder=pcm_f32be --enable-decoder=pcm_f32le --enable-decoder=pcm_f64be --enable-decoder=pcm_f64le --enable-decoder=pcm_lxf --enable-decoder=pcm_mulaw --enable-decoder=pcm_mulaw_at --enable-decoder=pcm_s16be --enable-decoder=pcm_s16be_planar --enable-decoder=pcm_s16le --enable-decoder=pcm_s16le_planar --enable-decoder=pcm_s24be --enable-decoder=pcm_s24daud --enable-decoder=pcm_s24le --enable-decoder=pcm_s24le_planar --enable-decoder=pcm_s32be --enable-decoder=pcm_s32le --enable-decoder=pcm_s32le_planar --enable-decoder=pcm_s64be --enable-decoder=pcm_s64le --enable-decoder=pcm_s8 --enable-decoder=pcm_s8_planar --enable-decoder=pcm_u16be --enable-decoder=pcm_u16le --enable-decoder=pcm_u24be --enable-decoder=pcm_u24le --enable-decoder=pcm_u32be --enable-decoder=pcm_u32le --enable-decoder=pcm_u8 --enable-decoder=pcm_zork --enable-decoder=vorbis --enable-decoder=wmalossless --enable-decoder=wmapro --enable-decoder=wmav1 --enable-decoder=wmav2 --enable-decoder=wmavoice --enable-encoder=libopus --enable-hwaccel=h264_d3d11va --enable-hwaccel=h264_dxva2 --enable-parser=aac --enable-parser=aac_latm --enable-parser=flac --enable-parser=h264 --enable-parser=mpeg4video --enable-parser=mpegaudio --enable-parser=opus --enable-parser=vorbis --enable-demuxer=aac --enable-demuxer=flac --enable-demuxer=gif --enable-demuxer=h264 --enable-demuxer=mov --enable-demuxer=mp3 --enable-demuxer=ogg --enable-demuxer=wav --enable-muxer=ogg --enable-muxer=opus --extra-ldflags="-libpath:$FullExecPath/../opus/win32/VS2015/Win32/Release"
./configure --toolchain=msvc \
--extra-ldflags="-libpath:$FullExecPath/../opus/win32/VS2015/Win32/Release" \
--disable-programs \
--disable-doc \
--disable-network \
--disable-everything \
--enable-hwaccel=h264_d3d11va \
--enable-hwaccel=h264_d3d11va2 \
--enable-hwaccel=h264_dxva2 \
--enable-hwaccel=hevc_d3d11va \
--enable-hwaccel=hevc_d3d11va2 \
--enable-hwaccel=hevc_dxva2 \
--enable-hwaccel=mpeg2_d3d11va \
--enable-hwaccel=mpeg2_d3d11va2 \
--enable-hwaccel=mpeg2_dxva2 \
--enable-protocol=file --enable-libopus \
--enable-decoder=aac \
--enable-decoder=aac_at \
--enable-decoder=aac_fixed \
--enable-decoder=aac_latm \
--enable-decoder=aasc \
--enable-decoder=alac \
--enable-decoder=alac_at \
--enable-decoder=flac \
--enable-decoder=gif \
--enable-decoder=h264 \
--enable-decoder=hevc \
--enable-decoder=mp1 \
--enable-decoder=mp1float \
--enable-decoder=mp2 \
--enable-decoder=mp2float \
--enable-decoder=mp3 \
--enable-decoder=mp3adu \
--enable-decoder=mp3adufloat \
--enable-decoder=mp3float \
--enable-decoder=mp3on4 \
--enable-decoder=mp3on4float \
--enable-decoder=mpeg4 \
--enable-decoder=msmpeg4v2 \
--enable-decoder=msmpeg4v3 \
--enable-decoder=opus \
--enable-decoder=pcm_alaw \
--enable-decoder=pcm_alaw_at \
--enable-decoder=pcm_f32be \
--enable-decoder=pcm_f32le \
--enable-decoder=pcm_f64be \
--enable-decoder=pcm_f64le \
--enable-decoder=pcm_lxf \
--enable-decoder=pcm_mulaw \
--enable-decoder=pcm_mulaw_at \
--enable-decoder=pcm_s16be \
--enable-decoder=pcm_s16be_planar \
--enable-decoder=pcm_s16le \
--enable-decoder=pcm_s16le_planar \
--enable-decoder=pcm_s24be \
--enable-decoder=pcm_s24daud \
--enable-decoder=pcm_s24le \
--enable-decoder=pcm_s24le_planar \
--enable-decoder=pcm_s32be \
--enable-decoder=pcm_s32le \
--enable-decoder=pcm_s32le_planar \
--enable-decoder=pcm_s64be \
--enable-decoder=pcm_s64le \
--enable-decoder=pcm_s8 \
--enable-decoder=pcm_s8_planar \
--enable-decoder=pcm_u16be \
--enable-decoder=pcm_u16le \
--enable-decoder=pcm_u24be \
--enable-decoder=pcm_u24le \
--enable-decoder=pcm_u32be \
--enable-decoder=pcm_u32le \
--enable-decoder=pcm_u8 \
--enable-decoder=pcm_zork \
--enable-decoder=vorbis \
--enable-decoder=wavpack \
--enable-decoder=wmalossless \
--enable-decoder=wmapro \
--enable-decoder=wmav1 \
--enable-decoder=wmav2 \
--enable-decoder=wmavoice \
--enable-encoder=libopus \
--enable-parser=aac \
--enable-parser=aac_latm \
--enable-parser=flac \
--enable-parser=h264 \
--enable-parser=hevc \
--enable-parser=mpeg4video \
--enable-parser=mpegaudio \
--enable-parser=opus \
--enable-parser=vorbis \
--enable-demuxer=aac \
--enable-demuxer=flac \
--enable-demuxer=gif \
--enable-demuxer=h264 \
--enable-demuxer=hevc \
--enable-demuxer=m4v \
--enable-demuxer=mov \
--enable-demuxer=mp3 \
--enable-demuxer=ogg \
--enable-demuxer=wav \
--enable-muxer=ogg \
--enable-muxer=opus
make -j4
make -j4 install

View File

@@ -1,8 +1,8 @@
diff --git a/build/common.gypi b/build/common.gypi
index 1affc70..c0d2f6a 100644
index 1affc70..0677e4b 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -66,6 +66,11 @@
@@ -66,6 +66,13 @@
'conditions': [
['clang!=0', {
'CLANG_CXX_LANGUAGE_STANDARD': 'c++11', # -std=c++11
@@ -10,11 +10,13 @@ index 1affc70..c0d2f6a 100644
+ 'OTHER_LDFLAGS': [
+ '/usr/local/macold/lib/libc++.a',
+ '/usr/local/macold/lib/libc++abi.a',
+ '-isysroot/',
+ '-L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/',
+ ],
# Don't link in libarclite_macosx.a, see http://crbug.com/156530.
'CLANG_LINK_OBJC_RUNTIME': 'NO', # -fno-objc-link-runtime
@@ -116,6 +121,9 @@
@@ -116,6 +123,9 @@
],
},

View File

@@ -1,5 +1,5 @@
diff --git a/configure b/configure
index cb8d78fd3cb..cadb3f0a880 100755
index cb8d78fd3c..cadb3f0a88 100755
--- a/configure
+++ b/configure
@@ -511,7 +511,8 @@ if [ "$BUILD_ON_MAC" = "yes" ]; then
@@ -13,7 +13,7 @@ index cb8d78fd3cb..cadb3f0a880 100755
echo " Xcode not set up properly. You may need to confirm the license" >&2
echo " agreement by running /usr/bin/xcodebuild without arguments." >&2
diff --git a/mkspecs/common/g++-macx.conf b/mkspecs/common/g++-macx.conf
index 086510dd963..c485967863d 100644
index 086510dd96..078a5ed1dd 100644
--- a/mkspecs/common/g++-macx.conf
+++ b/mkspecs/common/g++-macx.conf
@@ -14,7 +14,13 @@ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -gdwarf-2
@@ -27,12 +27,12 @@ index 086510dd963..c485967863d 100644
+# Patch: Use C++14 with custom libc++ build.
+QMAKE_CXXFLAGS_CXX11 = -std=c++1y
+QMAKE_CXXFLAGS += -nostdinc++ -I/usr/local/macold/include/c++/v1
+QMAKE_LFLAGS += /usr/local/macold/lib/libc++.a /usr/local/macold/lib/libc++abi.a
+QMAKE_LFLAGS += /usr/local/macold/lib/libc++.a /usr/local/macold/lib/libc++abi.a -isysroot /
QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvmgcc42
diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf
index 0cc8cd6dfdd..ca9725b7791 100644
index 0cc8cd6dfd..ca9725b779 100644
--- a/mkspecs/features/mac/default_pre.prf
+++ b/mkspecs/features/mac/default_pre.prf
@@ -12,7 +12,9 @@ isEmpty(QMAKE_XCODE_DEVELOPER_PATH) {
@@ -47,7 +47,7 @@ index 0cc8cd6dfdd..ca9725b7791 100644
}
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index bb79a139b3c..5d595bc3b34 100644
index bb79a139b3..5d595bc3b3 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -220,6 +220,10 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
@@ -74,7 +74,7 @@ index bb79a139b3c..5d595bc3b34 100644
if (ncols > 0) { // read color table
uchar rgb[4];
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
index ebff9509ab2..4300ca4c0f0 100644
index ebff9509ab..4300ca4c0f 100644
--- a/src/gui/painting/qpaintengine_p.h
+++ b/src/gui/painting/qpaintengine_p.h
@@ -87,8 +87,18 @@ public:
@@ -98,7 +98,7 @@ index ebff9509ab2..4300ca4c0f0 100644
// Make sure we're inside the viewport.
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 4879ae51d7d..56cdcbaf01c 100644
index 4879ae51d7..56cdcbaf01 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -654,6 +654,9 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
@@ -175,7 +175,7 @@ index 4879ae51d7d..56cdcbaf01c 100644
inline void resetRightBearing()
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index cbe42c38444..b273db7e78c 100644
index cbe42c3844..b273db7e78 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -194,6 +194,9 @@ private:
@@ -189,7 +189,7 @@ index cbe42c38444..b273db7e78c 100644
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 360f9722c70..f28f289ef6a 100644
index 360f9722c7..f28f289ef6 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -118,6 +118,8 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
@@ -202,7 +202,7 @@ index 360f9722c70..f28f289ef6a 100644
delete channels[i].socket;
}
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index ca7afb7d1b9..25ae50008db 100644
index ca7afb7d1b..25ae50008d 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -256,6 +256,13 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
@@ -220,7 +220,7 @@ index ca7afb7d1b9..25ae50008db 100644
fd->weight = QFont::Normal;
fd->style = QFont::StyleNormal;
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 6e2c8a2a9af..3cace8abcbc 100644
index 6e2c8a2a9a..3cace8abcb 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -717,7 +717,8 @@ void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metric
@@ -234,7 +234,7 @@ index 6e2c8a2a9af..3cace8abcbc 100644
QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 92358ecc745..694fee73507 100644
index 92358ecc74..694fee7350 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -213,7 +213,8 @@ static void cleanupCocoaApplicationDelegate()
@@ -271,7 +271,7 @@ index 92358ecc745..694fee73507 100644
- (void)appleEventQuit:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index b81b9a0b1c2..4e59e833b1d 100644
index b81b9a0b1c..4e59e833b1 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -81,7 +81,7 @@ void QCocoaCursor::setPos(const QPoint &position)
@@ -284,7 +284,7 @@ index b81b9a0b1c2..4e59e833b1d 100644
CFRelease(e);
}
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 9850f83dea8..b2e1d3dfda7 100644
index 9850f83dea..b2e1d3dfda 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -649,9 +649,10 @@ OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGIm
@@ -317,7 +317,7 @@ index 9850f83dea8..b2e1d3dfda7 100644
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 9fd05a65ee9..dea60720e78 100644
index 9fd05a65ee..dea60720e7 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -402,14 +402,24 @@ void QCocoaIntegration::updateScreens()
@@ -348,7 +348,7 @@ index 9fd05a65ee9..dea60720e78 100644
QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
index e46eaff6be3..c62db534a2d 100644
index e46eaff6be..c62db534a2 100644
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
@@ -382,6 +382,12 @@ bool QCocoaKeyMapper::updateKeyboard()
@@ -375,7 +375,7 @@ index e46eaff6be3..c62db534a2d 100644
}
return ret;
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 83c960d9317..03ae9696afe 100755
index 83c960d931..03ae9696af 100755
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -102,7 +102,10 @@ QT_USE_NAMESPACE
@@ -543,7 +543,7 @@ index 83c960d9317..03ae9696afe 100755
}
@end
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 4d0458a4aa2..3357a5ef817 100644
index 4d0458a4aa..3357a5ef81 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -167,7 +167,8 @@ static bool isMouseEvent(NSEvent *ev)
@@ -606,7 +606,7 @@ index 4d0458a4aa2..3357a5ef817 100644
[iconButton setImage:image];
[image release];
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index a18ee7ff71d..1f91feb0ae8 100644
index a18ee7ff71..1f91feb0ae 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -393,7 +393,9 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
@@ -675,7 +675,7 @@ index a18ee7ff71d..1f91feb0ae8 100644
}
return [super performKeyEquivalent:nsevent];
diff --git a/src/tools/qlalr/lalr.cpp b/src/tools/qlalr/lalr.cpp
index c68076477f3..e2a7aafa586 100644
index c68076477f..e2a7aafa58 100644
--- a/src/tools/qlalr/lalr.cpp
+++ b/src/tools/qlalr/lalr.cpp
@@ -246,11 +246,13 @@ void Grammar::buildExtendedGrammar ()
@@ -715,7 +715,7 @@ index c68076477f3..e2a7aafa586 100644
continue;
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 7396808442e..7178aecf800 100644
index 7396808442..7178aecf80 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -4722,6 +4722,17 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
@@ -768,7 +768,7 @@ index 7396808442e..7178aecf800 100644
|| (k->key() == Qt::Key_Tab && (k->modifiers() & Qt::ShiftModifier)))
res = focusNextPrevChild(false);
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 0845a5eb02f..5735cb6b396 100644
index 0845a5eb02..5735cb6b39 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -3667,9 +3667,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
@@ -786,7 +786,7 @@ index 0845a5eb02f..5735cb6b396 100644
}
diff --git a/src/widgets/util/qsystemtrayicon_qpa.cpp b/src/widgets/util/qsystemtrayicon_qpa.cpp
index f98aeaf6782..00c0734129e 100644
index f98aeaf678..00c0734129 100644
--- a/src/widgets/util/qsystemtrayicon_qpa.cpp
+++ b/src/widgets/util/qsystemtrayicon_qpa.cpp
@@ -99,13 +99,18 @@ void QSystemTrayIconPrivate::updateIcon_sys()
@@ -815,7 +815,7 @@ index f98aeaf6782..00c0734129e 100644
}
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 75f30599be4..980f2be1e93 100644
index 75f30599be..980f2be1e9 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -1867,7 +1867,8 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
@@ -829,7 +829,7 @@ index 75f30599be4..980f2be1e93 100644
#ifndef QT_NO_COMPLETER
complete(event->key());
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 96438a0bdf7..b0b72064056 100644
index 96438a0bdf..b0b7206405 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -1342,7 +1342,8 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)

View File

@@ -450,7 +450,7 @@ index 8ebabf3419..7bb8abd0d0 100644
}
populateFromPattern(pattern);
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 566abf2126..5b9c714ffa 100644
index 566abf2126..5c5fde9813 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -265,6 +265,13 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
@@ -467,6 +467,20 @@ index 566abf2126..5b9c714ffa 100644
fd->styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
fd->weight = QFont::Normal;
fd->style = QFont::StyleNormal;
@@ -300,9 +307,10 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
if (styles) {
if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
- float normalizedWeight;
- if (CFNumberGetValue(weightValue, kCFNumberFloatType, &normalizedWeight))
- fd->weight = QCoreTextFontEngine::qtWeightFromCFWeight(normalizedWeight);
+ // Patch: backport bugfix from 'b64ea4a3ab' commit.
+ double normalizedWeight;
+ if (CFNumberGetValue(weightValue, kCFNumberFloat64Type, &normalizedWeight))
+ fd->weight = QCoreTextFontEngine::qtWeightFromCFWeight(float(normalizedWeight));
}
if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
double d;
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 7b459584ea..2ed2fd9b3b 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -513,7 +527,7 @@ index d1bea9af23..36a15a6473 100644
event.setCommitString(QChar(character));
QCoreApplication::sendEvent(m_focusObject, &event);
diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro
index faea54b874..0f9650996e 100644
index faea54b874..fe4a837511 100644
--- a/src/plugins/platforminputcontexts/platforminputcontexts.pro
+++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro
@@ -1,7 +1,8 @@
@@ -521,8 +535,8 @@ index faea54b874..0f9650996e 100644
qtHaveModule(dbus) {
-!mac:!win32:SUBDIRS += ibus
+# Patch: Adding fcitx/hime input context plugin to our static build.
+!mac:!win32:SUBDIRS += ibus fcitx hime
+# Patch: Adding fcitx/hime/nimf input context plugin to our static build.
+!mac:!win32:SUBDIRS += ibus fcitx hime nimf
}
contains(QT_CONFIG, xcb-plugin): SUBDIRS += compose
@@ -869,7 +883,7 @@ index c0d5904367..f3c2047196 100644
[iconButton setImage:image];
[image release];
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index c67bcfd23b..2616f420cb 100644
index c67bcfd23b..6a60670aee 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -647,6 +647,12 @@ QT_WARNING_POP
@@ -943,6 +957,17 @@ index c67bcfd23b..2616f420cb 100644
- (void)cancelOperation:(id)sender
{
Q_UNUSED(sender);
@@ -1981,6 +2006,10 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
// change the cursor
[nativeCursor set];
+ // Patch: Backport a fix from cd08753d3e. Starting with macOS Mojave this requires accessibility access.
+ if (QSysInfo::macVersion() >= Q_MV_OSX(10, 14))
+ return;
+
// Make sure the cursor is updated correctly if the mouse does not move and window is under cursor
// by creating a fake move event
if (m_updatingDrag)
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 94bb71e429..16ab51e166 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp

View File

@@ -92,7 +92,7 @@ msgServiceFont: semiboldFont;
msgServiceNameFont: semiboldFont;
msgServicePhotoWidth: 100px;
msgDateFont: font(13px);
msgMinWidth: 190px;
msgMinWidth: 160px;
msgPhotoSize: 33px;
msgPhotoSkip: 40px;
msgPadding: margins(13px, 7px, 13px, 8px);
@@ -243,12 +243,6 @@ dragPadding: margins(20px, 10px, 20px, 10px);
dragHeight: 72px;
minPhotoSize: 100px;
maxMediaSize: 430px;
maxStickerSize: 256px;
maxGifSize: 320px;
maxSignatureSize: 144px;
radialSize: size(50px, 50px);
radialLine: 3px;
radialDuration: 350;
@@ -264,19 +258,6 @@ videoIcon: icon {
};
locationSize: size(320px, 240px);
webPageLeft: 10px;
webPageBar: 2px;
webPageTitleFont: semiboldFont;
webPageTitleStyle: semiboldTextStyle;
webPageTitleOutFg: historyTextOutFg;
webPageTitleInFg: historyTextInFg;
webPageDescriptionOutFg: historyTextOutFg;
webPageDescriptionInFg: historyTextInFg;
webPageDescriptionFont: normalFont;
webPageDescriptionStyle: defaultTextStyle;
webPagePhotoSize: 100px;
webPagePhotoDelta: 8px;
mediaPlayerSuppressDuration: 150;
botDescSkip: 8px;

View File

@@ -0,0 +1,14 @@
// This is a list of your own shortcuts for Telegram Desktop
// You can see full list of commands in the 'shortcuts-default.json' file
// Place a null value instead of a command string to switch the shortcut off
[
// {
// "command": "close_telegram",
// "keys": "ctrl+f4"
// },
// {
// "command": "quit_telegram",
// "keys": "ctrl+q"
// }
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -311,7 +311,8 @@ div.selected {
background-position: 12px 12px;
background-size: 24px 24px;
}
.default .media .title {
.default .media .title,
.default .media_poll .question {
padding-top: 4px;
font-size: 14px;
}

View File

@@ -0,0 +1,57 @@
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<dir>/usr/share/fonts</dir>
<dir>/usr/local/share/fonts</dir>
<dir>~/.fonts</dir>
<dir>~/.local/share/fonts</dir>
<dir>/usr/X11R6/lib/X11/fonts</dir>
<dir prefix="xdg">fonts</dir>
<match target="pattern">
<test qual="any" name="family">
<string>mono</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>monospace</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>sans serif</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>sans-serif</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>sans</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>sans-serif</string>
</edit>
</match>
<cachedir>/var/cache/fontconfig_11</cachedir>
<cachedir prefix="xdg">fontconfig_11</cachedir>
<cachedir>~/.fontconfig_11</cachedir>
<match target="font">
<edit mode="assign" name="antialias">
<bool>true</bool>
</edit>
<edit mode="assign" name="embeddedbitmap">
<bool>false</bool>
</edit>
<edit mode="assign" name="hinting">
<bool>true</bool>
</edit>
<edit mode="assign" name="hintstyle">
<const>hintslight</const>
</edit>
<edit mode="assign" name="lcdfilter">
<const>lcddefault</const>
</edit>
<edit mode="assign" name="rgba">
<const>rgb</const>
</edit>
</match>
</fontconfig>

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 419 B

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

After

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -128,6 +128,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gif_error" = "An error has occurred while reading GIF animation :(";
"lng_edit_error" = "You cannot edit this message";
"lng_join_channel_error" = "Sorry, you have joined too many channels and supergroups. Please leave some before joining this one.";
"lng_migrate_error" = "This action will convert the group to a supergroup. Unfortunately, you are a member of too many supergroups and channels. Please leave some of the channels or groups you don't need before proceeding.";
"lng_error_phone_flood" = "Sorry, you have deleted and re-created your account too many times recently. Please wait for a few days before signing up again.";
"lng_error_start_minimized_passcoded" = "You have set a local passcode, so Telegram Desktop can't be launched minimised; it will ask you to enter your passcode before it can start working.";
"lng_error_pinned_max#one" = "Sorry, you can pin no more than {count} chat to the top.";
@@ -142,9 +143,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_error_admin_limit_channel" = "Sorry, you've reached the maximum number of admins for this channel.";
"lng_sure_add_admin_invite" = "This user is not a member of this group. Add them to the group and promote them to admin?";
"lng_sure_add_admin_invite_channel" = "This user is not a subscriber of this channel. Add them to the channel and promote them to admin?";
"lng_sure_add_admin_unban" = "This user is currently restricted or banned. Are you sure you want to unban and promote them?";
"lng_sure_add_admin_unremove" = "This user is currently restricted or removed. Are you sure you want to promote them?";
"lng_sure_ban_admin" = "This user is an admin. Are you sure you want to go ahead and restrict them?";
"lng_sure_ban_user_group" = "Ban {user} in the group?";
"lng_sure_enable_socks" = "Are you sure you want to enable this proxy?\n\nServer: {server}\nPort: {port}\n\nYou can change your proxy server later in the Settings (Connection Type).";
"lng_sure_enable" = "Enable";
@@ -155,6 +155,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_deleted" = "Deleted Account";
"lng_deleted_message" = "Deleted message";
"lng_pinned_message" = "Pinned message";
"lng_pinned_poll" = "Pinned poll";
"lng_pinned_unpin_sure" = "Would you like to unpin this message?";
"lng_pinned_pin_sure" = "Would you like to pin this message?";
"lng_pinned_pin" = "Pin";
@@ -273,15 +274,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_empty_bio" = "None";
"lng_settings_section_notify" = "Notifications";
"lng_settings_notify_title" = "Notifications for chats";
"lng_settings_desktop_notify" = "Desktop notifications";
"lng_settings_show_name" = "Show sender's name";
"lng_settings_show_preview" = "Show message preview";
"lng_settings_native_title" = "Native notifications";
"lng_settings_use_windows" = "Use Windows notifications";
"lng_settings_use_native_notifications" = "Use native notifications";
"lng_settings_notifications_position" = "Location on the screen";
"lng_settings_notifications_count" = "Notifications count";
"lng_settings_sound_notify" = "Play sound";
"lng_settings_badge_title" = "Badge counter";
"lng_settings_include_muted" = "Include muted chats in unread count";
"lng_settings_count_unread" = "Count unread messages";
"lng_settings_events_title" = "Events";
"lng_settings_events_joined" = "Contact joined Telegram";
"lng_notification_preview" = "You have a new message";
"lng_notification_reply" = "Reply";
@@ -328,6 +335,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_bg_tile" = "Tile background";
"lng_settings_adaptive_wide" = "Adaptive layout for wide screens";
"lng_settings_section_call_settings" = "Calls Settings";
"lng_settings_call_section_output" = "Speakers and headphones";
"lng_settings_call_section_input" = "Microphone";
"lng_settings_call_input_device" = "Input device";
"lng_settings_call_output_device" = "Output device";
"lng_settings_call_input_volume" = "Input volume: {percent}%";
"lng_settings_call_output_volume" = "Output volume: {percent}%";
"lng_settings_call_test_mic" = "Test microphone";
"lng_settings_call_stop_mic_test" = "Stop test";
"lng_settings_call_section_other" = "Other settings";
"lng_settings_call_open_system_prefs" = "Open system sound preferences";
"lng_settings_call_device_default" = "Default";
"lng_settings_call_audio_ducking" = "Mute other sounds during calls";
"lng_settings_language" = "Language";
"lng_settings_default_scale" = "Default interface scale";
"lng_settings_connection_type" = "Connection type";
@@ -335,18 +356,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_privacy_title" = "Privacy";
"lng_settings_last_seen" = "Last seen";
"lng_settings_calls" = "Voice calls";
"lng_settings_calls_peer_to_peer" = "Peer-to-peer in calls";
"lng_settings_groups_invite" = "Groups";
"lng_settings_group_privacy_about" = "Change who can add you to groups and channels.";
"lng_settings_forwards_privacy" = "Forwarded messages";
"lng_settings_profile_photo_privacy" = "Profile photo";
"lng_settings_sessions_about" = "Control your sessions on other devices.";
"lng_settings_passcode_disable" = "Disable passcode";
"lng_settings_password_disable" = "Disable cloud password";
"lng_settings_password_abort" = "Abort two-step verification setup";
"lng_settings_password_reenter_email" = "Re-enter recovery email";
"lng_settings_about_bio" = "Any details such as age, occupation or city.\nExample: 23 y.o. designer from San Francisco";
"lng_settings_name_label" = "Name";
"lng_settings_username_label" = "Username";
"lng_settings_phone_label" = "Phone number";
"lng_settings_username_add" = "Add username";
"lng_settings_close_sure" = "Are you sure you want to close this page? You didn't save your changes.";
"lng_settings_peer_to_peer" = "Peer-to-Peer";
//"lng_settings_peer_to_peer" = "Peer-to-Peer";
"lng_settings_peer_to_peer_about" = "Disabling peer-to-peer will relay all calls through Telegram servers to avoid revealing your IP address, but may slightly decrease audio quality.";
"lng_settings_advanced" = "Advanced";
"lng_settings_stickers_emoji" = "Stickers and emoji";
@@ -371,6 +397,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_theme_reverting#other" = "Reverting to the old theme in {count} seconds.";
"lng_theme_keep_changes" = "Keep changes";
"lng_theme_revert" = "Revert";
"lng_background_header" = "Background preview";
"lng_background_text1" = "Ah, you kids today with techno music! You should enjoy the classics, like Hasselhoff!";
"lng_background_text2" = "I can't even take you seriously right now.";
"lng_background_bad_link" = "This background link appears to be invalid.";
"lng_background_apply" = "Apply";
"lng_background_share" = "Share";
"lng_background_link_copied" = "Link copied to clipboard";
"lng_background_blur" = "Blurred";
"lng_background_sure_delete" = "Are you sure you want to delete this background?";
"lng_download_path_ask" = "Ask download path for each file";
"lng_download_path" = "Download path";
@@ -403,7 +438,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_local_storage_round#other" = "{count} video messages";
"lng_local_storage_animation#one" = "{count} animation";
"lng_local_storage_animation#other" = "{count} animations";
"lng_local_storage_media" = "Media cache";
"lng_local_storage_size_limit" = "Total size limit: {size}";
"lng_local_storage_media_limit" = "Media cache limit: {size}";
"lng_local_storage_time_limit" = "Clear files older than: {limit}";
"lng_local_storage_limit_weeks#one" = "{count} week";
"lng_local_storage_limit_weeks#other" = "{count} weeks";
@@ -447,7 +484,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_passcode_logout" = "Log out";
"lng_passcode_need_unblock" = "You need to unlock me first.";
"lng_cloud_password_waiting" = "Confirmation link sent to {email}...";
"lng_cloud_password_waiting_code" = "Confirmation code sent to {email}...";
"lng_cloud_password_confirm" = "Confirm recovery email";
"lng_cloud_password_change" = "Change cloud password";
"lng_cloud_password_create" = "Cloud password";
"lng_cloud_password_remove" = "Remove cloud password";
@@ -473,6 +511,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_cloud_password_wrong" = "Wrong cloud password";
"lng_cloud_password_is_same" = "Password was not changed";
"lng_cloud_password_passport_losing" = "Warning! All data saved in your Telegram Passport will be lost!";
"lng_cloud_password_resend" = "Resend code";
"lng_cloud_password_resent" = "Code was resent.";
"lng_connection_auto_connecting" = "Default (connecting...)";
"lng_connection_auto" = "Default ({transport} used)";
@@ -491,7 +531,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_connection_save" = "Save";
"lng_proxy_settings" = "Proxy settings";
"lng_proxy_use" = "Use proxy";
"lng_proxy_disable" = "Disable proxy";
"lng_proxy_use_system_settings" = "Use system proxy settings";
"lng_proxy_use_custom" = "Use custom proxy";
"lng_proxy_use_for_calls" = "Use proxy for calls";
"lng_proxy_about" = "Proxy servers may be helpful in accessing Telegram if there is no connection in a specific region.";
"lng_proxy_add" = "Add proxy";
@@ -540,10 +582,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_sessions_other_header" = "Active sessions";
"lng_sessions_other_desc" = "You can log in to Telegram from other mobile, tablet and desktop devices, using the same phone number. All your data will be instantly synchronized.";
"lng_sessions_terminate_all" = "Terminate all other sessions";
"lng_sessions_terminate_all_about" = "Logs out all devices except for this one.";
"lng_sessions_incomplete" = "Incomplete login attempts";
"lng_sessions_incomplete_about" = "The devices above have no access to your messages. The code was entered correctly, but no correct password was given.";
"lng_blocked_list_title" = "Blocked users";
"lng_blocked_list_unknown_phone" = "unknown phone number";
"lng_blocked_list_unblock" = "Unblock";
"lng_blocked_list_restart" = "Restart";
"lng_blocked_list_add" = "Block user";
"lng_blocked_list_add_title" = "Select user to block";
"lng_blocked_list_already_blocked" = "blocked already";
@@ -555,14 +601,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_privacy_nobody" = "Nobody";
"lng_edit_privacy_exceptions" = "Add exceptions";
"lng_edit_privacy_exceptions_count#one" = "{count} user";
"lng_edit_privacy_exceptions_count#other" = "{count} users";
"lng_edit_privacy_exceptions_add" = "Add users";
"lng_edit_privacy_lastseen_title" = "Last seen privacy";
"lng_edit_privacy_lastseen_header" = "Who can see your last seen time";
"lng_edit_privacy_lastseen_warning" = "Important: you won't be able to see Last Seen times for people with whom you don't share your Last Seen time. Approximate last seen will be shown instead (recently, within a week, within a month).";
"lng_edit_privacy_lastseen_always_empty" = "Always share with";
"lng_edit_privacy_lastseen_never_empty" = "Never share with";
"lng_edit_privacy_exceptions_count#one" = "{count} user";
"lng_edit_privacy_exceptions_count#other" = "{count} users";
"lng_edit_privacy_exceptions_add" = "Add users";
"lng_edit_privacy_lastseen_exceptions" = "These settings will override the values above.";
"lng_edit_privacy_lastseen_always_title" = "Always share with";
"lng_edit_privacy_lastseen_never_title" = "Never share with";
@@ -583,6 +630,39 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_privacy_calls_always_title" = "Always allow";
"lng_edit_privacy_calls_never_title" = "Never allow";
"lng_edit_privacy_calls_p2p_title" = "Peer-to-peer in calls";
"lng_edit_privacy_calls_p2p_header" = "With who peer-to-peer is enabled?";
"lng_edit_privacy_calls_p2p_always_empty" = "Always allow";
"lng_edit_privacy_calls_p2p_never_empty" = "Never allow";
"lng_edit_privacy_calls_p2p_exceptions" = "Peer-to-peer in calls will or will not be used with these users regardless of the settings above.";
"lng_edit_privacy_calls_p2p_always_title" = "Always allow";
"lng_edit_privacy_calls_p2p_never_title" = "Never allow";
"lng_edit_privacy_calls_p2p_everyone" = "Everybody";
"lng_edit_privacy_calls_p2p_contacts" = "My contacts";
"lng_edit_privacy_calls_p2p_nobody" = "Nobody";
"lng_edit_privacy_forwards_title" = "Forwarded messages privacy";
"lng_edit_privacy_forwards_header" = "Who can add link to my account when forwarding my messages";
"lng_edit_privacy_forwards_warning" = "When forwarded to other chats, messages you send will not link back to your account.";
"lng_edit_privacy_forwards_always_empty" = "Always allow";
"lng_edit_privacy_forwards_never_empty" = "Never allow";
"lng_edit_privacy_forwards_exceptions" = "These settings will override the values above.";
"lng_edit_privacy_forwards_always_title" = "Always allow";
"lng_edit_privacy_forwards_never_title" = "Never allow";
"lng_edit_privacy_forwards_sample_message" = "Reinhardt, we need to find you some new tunes 🎶";
"lng_edit_privacy_forwards_sample_everyone" = "Link to your account.";
"lng_edit_privacy_forwards_sample_contacts" = "Link if allowed by settings below.";
"lng_edit_privacy_forwards_sample_nobody" = "Not a link to your account.";
"lng_edit_privacy_profile_photo_title" = "Profile photo privacy";
"lng_edit_privacy_profile_photo_header" = "Who can see my profile photo";
"lng_edit_privacy_profile_photo_always_empty" = "Always allow";
"lng_edit_privacy_profile_photo_never_empty" = "Never allow";
"lng_edit_privacy_profile_photo_exceptions" = "These settings will override the values above.";
"lng_edit_privacy_profile_photo_always_title" = "Always allow";
"lng_edit_privacy_profile_photo_never_title" = "Never allow";
"lng_self_destruct_title" = "Account self-destruction";
"lng_self_destruct_description" = "If you don't come online at least once within this period, your account will be deleted along with all groups, messages and contacts.";
"lng_self_destruct_months#one" = "{count} month";
@@ -604,6 +684,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_mute_duration_hours#one" = "For {count} hour";
"lng_mute_duration_hours#other" = "For {count} hours";
"lng_mute_duration_days#one" = "For {count} day";
"lng_mute_duration_days#other" = "For {count} days";
"lng_mute_duration_forever" = "Forever";
"lng_mute_box_tip" = "Choose for how long you would like to turn off notifications for the following chat";
"lng_preview_loading" = "Getting Link Info...";
@@ -617,10 +700,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_create_public_link" = "Create public link";
"lng_profile_edit_public_link" = "Edit public link";
"lng_profile_search_members" = "Search members";
"lng_profile_manage_admins" = "Manage administrators";
"lng_profile_manage_blocklist" = "Manage banned users";
"lng_profile_manage_restrictedlist" = "Manage restricted users";
"lng_profile_recent_actions" = "Recent actions";
"lng_profile_common_groups#one" = "{count} group in common";
"lng_profile_common_groups#other" = "{count} groups in common";
"lng_profile_participants_section" = "Members";
@@ -638,7 +717,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_report" = "Report";
"lng_profile_search_messages" = "Search for messages";
"lng_profile_block_bot" = "Stop and block bot";
"lng_profile_unblock_bot" = "Unblock bot";
"lng_profile_restart_bot" = "Restart bot";
"lng_profile_invite_to_group" = "Add to Group";
"lng_profile_delete_contact" = "Delete";
"lng_profile_set_group_photo" = "Set Photo";
@@ -648,6 +727,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_join_group" = "Join Group";
"lng_profile_delete_and_exit" = "Leave";
"lng_profile_kick" = "Remove";
"lng_profile_delete_removed" = "Delete";
"lng_profile_sure_kick" = "Remove {user} from the group?";
"lng_profile_sure_kick_channel" = "Remove {user} from the channel?";
"lng_profile_sure_remove_admin" = "Remove {user} from admins?";
@@ -743,13 +823,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_manage_peer_recent_actions" = "Recent Actions";
"lng_manage_peer_members" = "Members";
"lng_manage_peer_administrators" = "Administrators";
"lng_manage_peer_banned_users" = "Banned users";
"lng_manage_peer_restricted_users" = "Restricted users";
"lng_manage_peer_exceptions" = "Exceptions";
"lng_manage_peer_removed_users" = "Removed users";
"lng_manage_peer_permissions" = "Permissions";
"lng_manage_peer_group_type" = "Group type";
"lng_manage_peer_channel_type" = "Channel type";
"lng_manage_private_peer_title" = "Private";
"lng_manage_public_peer_title" = "Public";
"lng_manage_history_visibility_title" = "Chat history for new members";
"lng_manage_history_visibility_shown" = "Visible";
"lng_manage_history_visibility_shown_about" = "New members will see messages that were sent before they joined.";
"lng_manage_history_visibility_hidden" = "Hidden";
"lng_manage_history_visibility_hidden_about" = "New members won't see earlier messages.";
"lng_manage_history_visibility_hidden_legacy" = "New members won't see more than 100 previous messages.";
"lng_report_title" = "Report channel";
"lng_report_group_title" = "Report group";
@@ -764,17 +852,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_report_thanks" = "Thank you! Your report will be reviewed by our team very soon.";
"lng_channel_add_members" = "Add members";
"lng_channel_add_banned" = "Ban user";
"lng_channel_add_restricted" = "Restrict user";
"lng_channel_add_users" = "Add users";
"lng_channel_add_removed" = "Remove user";
"lng_channel_add_exception" = "Add exception";
"lng_channel_admins" = "Administrators";
"lng_channel_add_admin" = "Add Administrator";
"lng_channel_admin_status_creator" = "Creator";
"lng_channel_admin_status_promoted_by" = "Promoted by {user}";
"lng_channel_admin_status_not_admin" = "Not administrator";
"lng_channel_banned_status_restricted_by" = "Restricted by {user}";
"lng_channel_banned_status_removed_by" = "Removed by {user}";
"lng_group_blocked_list_about" = "Banned users are removed from the group and can only come back if invited by an admin.\nInvite links don't work for them.";
"lng_channel_blocked_list_about" = "Banned users are removed from the channel.\nInvite links don't work for them.";
"lng_channel_removed_list_about" = "Users removed from the channel by admins cannot rejoin it via invite links.";
"lng_group_removed_list_about" = "Users removed from the group by admins cannot rejoin it via invite links.";
"lng_chat_all_members_admins" = "All Members Are Admins";
"lng_chat_about_all_admins" = "Group members can add new members, edit name and photo of the group.";
@@ -799,6 +889,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_create_private_group_about" = "People can only join if they were invited or have an invite link";
"lng_create_group_skip" = "Skip";
"lng_create_channel_link_about" = "You can use a-z, 0-9 and underscores.\nMinimum length is 5 characters.";
"lng_create_channel_link_invalid" = "This link is invalid";
"lng_create_channel_link_occupied" = "Sorry, this link is already occupied";
"lng_create_channel_link_too_short" = "Sorry, this link is too short";
@@ -854,7 +946,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_changed_title_channel" = "Channel name was changed to «{title}»";
"lng_action_created_chat" = "{from} created group «{title}»";
"lng_action_created_channel" = "Channel created";
"lng_action_group_migrate" = "The group was upgraded to a supergroup";
"lng_action_pinned_message" = "{from} pinned «{text}»";
"lng_action_pinned_media" = "{from} pinned {media}";
"lng_action_pinned_media_photo" = "a photo";
@@ -909,8 +1000,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_convert_feature4" = "— Creator can set a public link for the group";
"lng_profile_convert_warning" = "{bold_start}Note:{bold_end} This action can not be undone";
"lng_profile_convert_confirm" = "Convert";
"lng_profile_add_more_after_upgrade#one" = "You will be able to add up to {count} member after you upgrade your group to a supergroup.";
"lng_profile_add_more_after_upgrade#other" = "You will be able to add up to {count} members after you upgrade your group to a supergroup.";
"lng_profile_add_more_after_create" = "You will be able to add more members after you create the group.";
"lng_channel_not_accessible" = "Sorry, this channel is not accessible.";
"lng_group_not_accessible" = "Sorry, this group is not accessible.";
@@ -943,6 +1033,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_forwarded_via" = "Forwarded from {user} via {inline_bot}";
"lng_forwarded_channel_via" = "Forwarded from {channel} via {inline_bot}";
"lng_forwarded_signed" = "{channel} ({user})";
"lng_forwarded_hidden" = "The account was hidden by the user.";
"lng_signed_author" = "Author: {user}";
"lng_in_reply_to" = "In reply to";
"lng_edited" = "edited";
"lng_edited_date" = "Edited: {date}";
@@ -967,13 +1059,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_media_audio" = "Voice message";
"lng_media_auto_settings" = "Automatic media download";
"lng_media_auto_in_private" = "In private chats";
"lng_media_auto_in_groups" = "In groups";
"lng_media_auto_in_channels" = "In channels";
"lng_media_auto_title" = "Automatically download";
"lng_media_photo_title" = "Photos";
"lng_media_video_title" = "Video files";
"lng_media_audio_title" = "Voice messages";
"lng_media_gif_title" = "GIFs and animations";
"lng_media_auto_private_chats" = "Private chats";
"lng_media_auto_groups" = "Groups and channels";
"lng_media_auto_play" = "Autoplay";
"lng_media_video_messages_title" = "Round video messages";
"lng_media_file_title" = "Files";
"lng_media_music_title" = "Music";
"lng_media_animation_title" = "Animated GIFs";
"lng_media_size_limit" = "Limit by size";
"lng_media_size_up_to" = "up to {size}";
"lng_media_chat_background" = "Chat background";
"lng_emoji_category1" = "People";
"lng_emoji_category2" = "Nature";
@@ -983,6 +1082,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_emoji_category6" = "Objects";
"lng_emoji_category7" = "Symbols & Flags";
"lng_emoji_hide_panel" = "Click here to hide the emoji sidebar";
"lng_emoji_manage_sets" = "Choose emoji set";
"lng_emoji_set_ready" = "Downloaded";
"lng_emoji_set_active" = "Current set";
"lng_emoji_set_download" = "Download {size}";
"lng_emoji_set_loading" = "{percent}, {progress}";
"lng_recent_stickers" = "Frequently used";
"lng_faved_stickers_add" = "Add to Favorites";
@@ -991,6 +1095,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_group_stickers_description" = "You can choose a sticker set which will be available for every member while in the group chat.";
"lng_group_stickers_add" = "Choose sticker set";
"lng_group_about_header" = "You have created a group.";
"lng_group_about_text" = "Groups can have:";
"lng_group_about1" = "Up to 100,000 members";
"lng_group_about2" = "Persistent chat history";
"lng_group_about3" = "Public links such as t.me/title";
"lng_group_about4" = "Admins with different rights";
"lng_switch_stickers" = "Stickers";
"lng_switch_emoji" = "Emoji";
"lng_switch_gifs" = "GIFs";
@@ -1018,6 +1129,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_stickers_count#one" = "{count} sticker";
"lng_stickers_count#other" = "{count} stickers";
"lng_stickers_masks_pack" = "This is a pack of mask stickers. You can use them in the photo editor on our mobile apps.";
"lng_stickers_attached_sets" = "Sets of attached stickers";
"lng_stickers_group_set" = "Group sticker set";
"lng_stickers_remove_group_set" = "Remove group sticker set?";
"lng_stickers_group_from_your" = "Choose from your stickers";
@@ -1036,6 +1148,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_in_dlg_file" = "File";
"lng_in_dlg_sticker" = "Sticker";
"lng_in_dlg_sticker_emoji" = "{emoji} Sticker";
"lng_in_dlg_poll" = "Poll";
"lng_ban_user" = "Ban User";
"lng_delete_all_from" = "Delete all from this user";
@@ -1052,7 +1165,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_cant_invite_banned" = "Sorry, only admin can add this user.";
"lng_cant_invite_privacy" = "Sorry, you cannot add this user to groups because of their privacy settings.";
"lng_cant_invite_privacy_channel" = "Sorry, you cannot add this user to channels because of their privacy settings.";
"lng_cant_invite_bot_to_channel" = "Sorry, bots can only be added to channels as administrators.";
"lng_cant_do_this" = "Sorry, this action is unavailable.";
"lng_cant_invite_offer_admin" = "Bots can only be added as administrators.";
"lng_cant_invite_make_admin" = "Make admin";
"lng_send_button" = "Send";
"lng_message_ph" = "Write a message...";
@@ -1066,6 +1182,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_from_draft" = "Draft";
"lng_bot_description" = "What can this bot do?";
"lng_unblock_button" = "Unblock";
"lng_restart_button" = "Restart";
"lng_channel_mute" = "Mute";
"lng_channel_unmute" = "Unmute";
"lng_saved_messages" = "Saved Messages";
@@ -1153,6 +1270,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_edit_permissions" = "Edit permissions";
"lng_context_restrict_user" = "Restrict user";
"lng_context_remove_from_group" = "Remove from group";
"lng_context_add_to_group" = "Add to group";
"lng_context_copy_link" = "Copy Link";
"lng_context_copy_post_link" = "Copy Post Link";
@@ -1173,6 +1291,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_copy_text" = "Copy Text";
"lng_context_open_gif" = "Open GIF";
"lng_context_save_gif" = "Save GIF";
"lng_context_attached_stickers" = "Attached Stickers";
"lng_context_to_msg" = "Go To Message";
"lng_context_reply_msg" = "Reply";
"lng_context_edit_msg" = "Edit";
@@ -1236,9 +1355,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_contact_title" = "Edit contact name";
"lng_edit_channel_title" = "Edit channel";
"lng_edit_sign_messages" = "Sign messages";
"lng_edit_group_who_invites" = "Who can add members";
"lng_edit_group_invites_everybody" = "All members";
"lng_edit_group_invites_only_admins" = "Only admins";
"lng_edit_group" = "Edit group";
"lng_edit_self_title" = "Edit your name";
"lng_confirm_contact_data" = "New Contact";
@@ -1274,8 +1390,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_delete_for_me_chat_hint#other" = "This will delete them just for you, not for other participants of the chat.";
"lng_delete_for_me_hint#one" = "This will delete it just for you.";
"lng_delete_for_me_hint#other" = "This will delete them just for you.";
"lng_selected_unsend_about_user_one" = "You can also delete the message you sent from {user}'s inbox by checking \"Unsend my messages\".";
"lng_selected_unsend_about_user#one" = "You can also delete the {count} message you sent from {user}'s inbox by checking \"Unsend my messages\".";
"lng_selected_unsend_about_user#other" = "You can also delete the {count} messages you sent from {user}'s inbox by checking \"Unsend my messages\".";
"lng_selected_unsend_about_group_one" = "You can also delete the message you sent from the inboxes of other group members by checking \"Unsend my messages\".";
"lng_selected_unsend_about_group#one" = "You can also delete the {count} message you sent from the inboxes of other group members by checking \"Unsend my messages\".";
"lng_selected_unsend_about_group#other" = "You can also delete the {count} messages you sent from the inboxes of other group members by checking \"Unsend my messages\".";
"lng_delete_for_everyone_check" = "Delete for everyone";
"lng_delete_for_other_check" = "Delete for {user}";
"lng_delete_for_other_check" = "Also delete for {user}";
"lng_delete_for_other_my" = "Unsend my messages";
"lng_box_delete" = "Delete";
"lng_box_leave" = "Leave";
@@ -1330,7 +1453,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_menu_formatting_link_edit" = "Edit link";
"lng_menu_formatting_clear" = "Plain text";
"lng_formatting_link_create_title" = "Create link";
"lng_formatting_link_edit_title" = "Create link";
"lng_formatting_link_edit_title" = "Edit link";
"lng_formatting_link_text" = "Text";
"lng_formatting_link_url" = "URL";
"lng_formatting_link_create" = "Create";
@@ -1408,14 +1531,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_player_message_today" = "Today at {time}";
"lng_player_message_yesterday" = "Yesterday at {time}";
"lng_player_message_date" = "{date} at {time}";
//"lng_player_cant_stream" = "This file can't be played before it is fully downloaded.\n\nWould you like to download it?";
"lng_player_download" = "Download";
"lng_rights_edit_admin" = "Manage permissions";
"lng_rights_edit_admin_header" = "What can this admin do?";
"lng_rights_about_add_admins_yes" = "This admin will be able to add new admins with the same (or more limited) permissions.";
"lng_rights_about_add_admins_no" = "This admin will not be able to add new admins.";
"lng_rights_about_admin_cant_edit" = "You cannot edit rights of this admin.";
"lng_rights_about_admin_cant_edit" = "You are not allowed to edit the rights of this admin.";
"lng_rights_about_restriction_cant_edit" = "You cannot change the restrictions for this user.";
"lng_rights_restriction_for_all" = "This option is disabled for all members in Group Permissions. You can either enable the permission for everyone or make this user an admin.";
"lng_rights_permission_for_all" = "This option is enabled for all members in Group Permissions.";
"lng_rights_permission_unavailable" = "This permission is not available in public groups.";
"lng_rights_permission_cant_edit" = "You cannot edit this permission.";
"lng_rights_user_restrictions" = "User restrictions";
"lng_rights_user_restrictions_header" = "What can this user do?";
"lng_rights_user_restrictions_header" = "What can this member do?";
"lng_rights_default_restrictions_header" = "What can members of this group do?";
"lng_rights_channel_info" = "Change channel info";
"lng_rights_channel_post" = "Post messages";
@@ -1433,6 +1565,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_rights_chat_send_media" = "Send media";
"lng_rights_chat_send_stickers" = "Send stickers & GIFs";
"lng_rights_chat_send_links" = "Embed links";
"lng_rights_chat_send_polls" = "Send polls";
"lng_rights_chat_add_members" = "Add members";
"lng_rights_chat_banned_until_header" = "Restricted until";
"lng_rights_chat_banned_forever" = "Forever";
"lng_rights_chat_banned_day#one" = "For {count} day";
@@ -1447,9 +1581,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_restricted_send_stickers" = "The admins of this group restricted you from posting stickers here.";
"lng_restricted_send_gifs" = "The admins of this group restricted you from posting GIFs here.";
"lng_restricted_send_inline" = "The admins of this group restricted you from posting inline content here.";
"lng_restricted_send_polls" = "The admins of this group restricted you from posting polls here.";
"lng_restricted_list_title" = "Restricted users";
"lng_banned_list_title" = "Banned users";
"lng_restricted_send_message_all" = "Writing messages isn't allowed in this group.";
"lng_restricted_send_media_all" = "Posting media content isn't allowed in this group.";
"lng_restricted_send_stickers_all" = "Posting stickers isn't allowed in this group.";
"lng_restricted_send_gifs_all" = "Posting GIFs isn't allowed in this group.";
"lng_restricted_send_inline_all" = "Posting inline content isn't allowed in this group.";
"lng_restricted_send_polls_all" = "Posting polls isn't allowed in this group.";
"lng_exceptions_list_title" = "Exceptions";
"lng_removed_list_title" = "Removed users";
"lng_admin_log_title_all" = "All actions";
"lng_admin_log_title_selected" = "Selected actions";
@@ -1509,10 +1651,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_admin_log_participant_joined_channel" = "{from} joined the channel";
"lng_admin_log_participant_left" = "{from} left the group";
"lng_admin_log_participant_left_channel" = "{from} left the channel";
"lng_admin_log_stopped_poll" = "{from} stopped poll:";
"lng_admin_log_invited" = "invited {user}";
"lng_admin_log_banned" = "banned {user}";
"lng_admin_log_restricted" = "changed restrictions for {user} {until}";
"lng_admin_log_promoted" = "changed privileges for {user}";
"lng_admin_log_changed_default_permissions" = "changed default permissions";
"lng_admin_log_changed_stickers_group" = "{from} changed the group's {sticker_set}";
"lng_admin_log_changed_stickers_set" = "sticker set";
"lng_admin_log_removed_stickers_group" = "{from} removed the group's sticker set";
@@ -1524,12 +1668,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_admin_log_banned_send_media" = "Send media";
"lng_admin_log_banned_send_stickers" = "Send stickers & GIFs";
"lng_admin_log_banned_embed_links" = "Embed links";
"lng_admin_log_banned_send_polls" = "Send polls";
"lng_admin_log_admin_change_info" = "Change info";
"lng_admin_log_admin_post_messages" = "Post messages";
"lng_admin_log_admin_edit_messages" = "Edit messages";
"lng_admin_log_admin_delete_messages" = "Delete messages";
"lng_admin_log_admin_ban_users" = "Ban users";
"lng_admin_log_admin_invite_users" = "Add users";
"lng_admin_log_admin_invite_users" = "Add members";
"lng_admin_log_admin_invite_link" = "Invite users via link";
"lng_admin_log_admin_pin_messages" = "Pin messages";
"lng_admin_log_admin_add_admins" = "Add new admins";
@@ -1586,7 +1731,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_passport_create_password" = "Please create a password which will be used\nto encrypt your personal data.";
"lng_passport_about_password" = "This password will also be required whenever\nyou log in to a new device.";
"lng_passport_password_create" = "Create a password";
"lng_passport_link_sent" = "A confirmation link was sent to your email\n{email}";
"lng_passport_email_validate" = "Validate";
"lng_passport_code_sent" = "A confirmation code was sent to\n{email}";
"lng_passport_stop_password_sure" = "Are you sure you want to cancel setting up your password?";
"lng_passport_password_placeholder" = "Your password";
"lng_passport_next" = "Next";
@@ -1782,6 +1928,41 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_export_about_chats" = "This page lists all chats from this export and where to look for their data.";
"lng_export_about_left_chats" = "Below are the supergroups and channels from this export that you've left or where you were banned.\n\nNote that when you leave a channel or supergroup you've created, you have the option to either delete it, or simply leave (in case you want to rejoin later, or keep the community alive despite not being a member).";
"lng_language_switch_title" = "Change language?";
"lng_language_switch_about_official" = "You are about to apply a language pack {lang_name} that is {percent}% complete.\n\nThis will translate the entire interface. You can suggest corrections in the {link}.\n\nYou can change your language back at any time in Settings.";
"lng_language_switch_about_unofficial" = "You are about to apply a custom language pack {lang_name} that is {percent}% complete.\n\nThis will translate the entire interface. You can suggest corrections in the {link}.\n\nYou can change your language back at any time in Settings.";
"lng_language_switch_link" = "translation panel";
"lng_language_switch_apply" = "Change";
"lng_language_not_found" = "Sorry, this language pack doesn't exist.";
"lng_language_already" = "You're already using this language pack. You can change your language back in Settings.";
"lng_language_not_ready_title" = "Insufficient data";
"lng_language_not_ready_about" = "Unfortunately, this custom language pack ({lang_name}) doesn't contain data for Telegram Desktop. You can contribute to this language pack using the {link}.";
"lng_language_not_ready_link" = "translations platform";
"lng_launch_exe_warning" = "This file has a {extension} extension.\nAre you sure you want to run it?";
"lng_launch_exe_sure" = "Run";
"lng_launch_exe_dont_ask" = "Don't ask me again";
"lng_polls_anonymous" = "Anonymous Poll";
"lng_polls_closed" = "Final results";
"lng_polls_votes_count#one" = "{count} vote";
"lng_polls_votes_count#other" = "{count} votes";
"lng_polls_votes_none" = "No votes";
"lng_polls_retract" = "Retract vote";
"lng_polls_stop" = "Stop poll";
"lng_polls_stop_warning" = "If you stop this poll now, nobody will be able to vote in it anymore. This action cannot be undone.";
"lng_polls_stop_sure" = "Stop";
"lng_polls_create" = "Create poll";
"lng_polls_create_title" = "New poll";
"lng_polls_create_question" = "Question";
"lng_polls_create_question_placeholder" = "Ask a question";
"lng_polls_create_options" = "Poll options";
"lng_polls_create_option_add" = "Add an option...";
"lng_polls_create_limit#one" = "You can add {count} more option.";
"lng_polls_create_limit#other" = "You can add {count} more options.";
"lng_polls_create_maximum" = "You have added the maximum number of options.";
"lng_polls_create_button" = "Create";
// Wnd specific
"lng_wnd_choose_program_menu" = "Choose Default Program...";
@@ -1794,6 +1975,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_linux_menu_undo" = "Undo";
"lng_linux_menu_redo" = "Redo";
"lng_linux_no_audio_prefs" = "You don't have any audio configuration applications installed.";
// Mac specific
"lng_mac_choose_program_menu" = "Other...";

View File

@@ -207,7 +207,7 @@
52;MX;Mexico;
51;PE;Peru;51 XXX XXX XXX;11;
49;DE;Germany;49 XXX XXXXXXXX;13;
48;PL;Poland;48 XX XXX XXXX;11;
48;PL;Poland;48 XXX XXX XXX;11;
47;NO;Norway;47 XXXX XXXX;10;
46;SE;Sweden;46 XX XXX XXXX;11;
45;DK;Denmark;45 XXXX XXXX;10;

View File

@@ -65,6 +65,9 @@
<qresource prefix="/qt-project.org">
<file>qmime/freedesktop.org.xml</file>
</qresource>
<qresource prefix="/misc">
<file alias="default_shortcuts-custom.json">../default_shortcuts-custom.json</file>
</qresource>
<qresource prefix="/langs">
<file alias="lang_it.strings">../langs/lang_it.strings</file>
<file alias="lang_es.strings">../langs/lang_es.strings</file>

View File

@@ -0,0 +1,8 @@
<RCC>
<qresource prefix="/gui">
<file alias="emoji/set0_preview.webp">../emoji/set0_preview.webp</file>
<file alias="emoji/set1_preview.webp">../emoji/set1_preview.webp</file>
<file alias="emoji/set2_preview.webp">../emoji/set2_preview.webp</file>
<file alias="emoji/set3_preview.webp">../emoji/set3_preview.webp</file>
</qresource>
</RCC>

View File

@@ -2,4 +2,7 @@
<qresource prefix="/qt">
<file alias="etc/qt.conf">../etc/qt_linux.conf</file>
</qresource>
<qresource prefix="/fc">
<file alias="fc-custom.conf">../fc-custom.conf</file>
</qresource>
</RCC>

View File

@@ -176,7 +176,8 @@ inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = In
inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaGame#d33f43f3 id:InputGame = InputMedia;
inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;
inputMediaGeoLive#7b1a118f geo_point:InputGeoPoint period:int = InputMedia;
inputMediaGeoLive#ce4e82fd flags:# stopped:flags.0?true geo_point:InputGeoPoint period:flags.1?int = InputMedia;
inputMediaPoll#6b3765b poll:Poll = InputMedia;
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
inputChatUploadedPhoto#927c55b4 file:InputFile = InputChatPhoto;
@@ -194,8 +195,6 @@ inputDocumentFileLocation#196683d9 id:long access_hash:long file_reference:bytes
inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
inputTakeoutFileLocation#29be5899 = InputFileLocation;
inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent;
peerUser#9db1bc6d user_id:int = Peer;
peerChat#bad0e5bb chat_id:int = Peer;
peerChannel#bddde532 channel_id:int = Peer;
@@ -215,7 +214,7 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL
fileLocation#91d11eb dc_id:int volume_id:long local_id:int secret:long file_reference:bytes = FileLocation;
userEmpty#200250ba id:int = User;
user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
@@ -228,13 +227,13 @@ userStatusLastWeek#7bf09fc = UserStatus;
userStatusLastMonth#77ebc742 = UserStatus;
chatEmpty#9ba2d800 id:int = Chat;
chat#d91cdd54 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true admins_enabled:flags.3?true admin:flags.4?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel = Chat;
chat#3bda1bde flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
chatForbidden#7328bdb id:int title:string = Chat;
channel#c88974ac flags:# creator:flags.0?true left:flags.2?true editor:flags.3?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true democracy:flags.10?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChannelAdminRights banned_rights:flags.15?ChannelBannedRights participants_count:flags.17?int = Chat;
channel#4df30834 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat;
chatFull#2e02a614 id:int participants:ChatParticipants chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> = ChatFull;
channelFull#76af5481 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;
chatFull#22a235da flags:# can_set_username:flags.7?true id:int about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int = ChatFull;
channelFull#1c87a71a flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_view_stats:flags.12?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
chatParticipantCreator#da13538a user_id:int = ChatParticipant;
@@ -247,7 +246,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
messageEmpty#83e5de54 id:int = Message;
message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;
message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;
messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
@@ -261,6 +260,7 @@ messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:str
messageMediaGame#fdb19008 game:Game = MessageMedia;
messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
messageMediaGeoLive#7c3c2609 geo:GeoPoint period:int = MessageMedia;
messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
@@ -284,6 +284,7 @@ messageActionCustomAction#fae69f56 message:string = MessageAction;
messageActionBotAllowed#abe9affe domain:string = MessageAction;
messageActionSecureValuesSentMe#1b287353 values:Vector<SecureValue> credentials:SecureCredentialsEncrypted = MessageAction;
messageActionSecureValuesSent#d95c6154 types:Vector<SecureValueType> = MessageAction;
messageActionContactSignUp#f3f25f76 = MessageAction;
dialog#e4def5db flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
@@ -293,6 +294,7 @@ photo#9c477dd8 flags:# has_stickers:flags.0?true id:long access_hash:long file_r
photoSizeEmpty#e17e23c type:string = PhotoSize;
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize;
geoPointEmpty#1117dd5f = GeoPoint;
geoPoint#296f104 long:double lat:double access_hash:long = GeoPoint;
@@ -308,6 +310,7 @@ auth.exportedAuthorization#df969c2d id:int bytes:bytes = auth.ExportedAuthorizat
inputNotifyPeer#b8bc5b0c peer:InputPeer = InputNotifyPeer;
inputNotifyUsers#193b4417 = InputNotifyPeer;
inputNotifyChats#4a95e84e = InputNotifyPeer;
inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer;
inputPeerNotifySettings#9c3d198e flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = InputPeerNotifySettings;
@@ -315,16 +318,16 @@ peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bo
peerSettings#818426cd flags:# report_spam:flags.0?true = PeerSettings;
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
inputReportReasonSpam#58dbcab8 = ReportReason;
inputReportReasonViolence#1e22c78d = ReportReason;
inputReportReasonPornography#2e59d922 = ReportReason;
inputReportReasonChildAbuse#adf44ee3 = ReportReason;
inputReportReasonOther#e1746d0a text:string = ReportReason;
inputReportReasonCopyright#9b89f93a = ReportReason;
userFull#f220f3f flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo common_chats_count:int = UserFull;
userFull#8ea4a881 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int = UserFull;
contact#f911c994 user_id:int mutual:Bool = Contact;
@@ -349,8 +352,8 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
messages.dialogsNotModified#f0e3e596 count:int = messages.Dialogs;
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.channelMessages#99262e37 flags:# pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesSlice#a6c47aaa flags:# inexact:flags.1?true count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.channelMessages#99262e37 flags:# inexact:flags.1?true pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messagesNotModified#74535f21 count:int = messages.Messages;
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
@@ -386,7 +389,6 @@ updateChatParticipants#7761198 participants:ChatParticipants = Update;
updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
updateUserName#a7332b73 user_id:int first_name:string last_name:string username:string = Update;
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
updateContactLink#9d2e67c5 user_id:int my_link:ContactLink foreign_link:ContactLink = Update;
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
updateEncryptedChatTyping#1710f156 chat_id:int = Update;
@@ -410,7 +412,6 @@ updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update;
updateReadChannelInbox#4214f37f channel_id:int max_id:int = Update;
updateDeleteChannelMessages#c37521c9 channel_id:int messages:Vector<int> pts:int pts_count:int = Update;
updateChannelMessageViews#98a12b4b channel_id:int id:int views:int = Update;
updateChatAdmins#6e947941 chat_id:int enabled:Bool version:int = Update;
updateChatParticipantAdmin#b6901959 chat_id:int user_id:int is_admin:Bool version:int = Update;
updateNewStickerSet#688a30aa stickerset:messages.StickerSet = Update;
updateStickerSetsOrder#bb2d201 flags:# masks:flags.0?true order:Vector<long> = Update;
@@ -437,13 +438,17 @@ updateBotWebhookJSONQuery#9b9240a6 query_id:long data:DataJSON timeout:int = Upd
updateBotShippingQuery#e0cdc940 query_id:long user_id:int payload:bytes shipping_address:PostAddress = Update;
updateBotPrecheckoutQuery#5d2f3aa9 flags:# query_id:long user_id:int payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string currency:string total_amount:long = Update;
updatePhoneCall#ab0f6b1e phone_call:PhoneCall = Update;
updateLangPackTooLong#10c2404b = Update;
updateLangPackTooLong#46560264 lang_code:string = Update;
updateLangPack#56022f4d difference:LangPackDifference = Update;
updateFavedStickers#e511996d = Update;
updateChannelReadMessagesContents#89893b45 channel_id:int messages:Vector<int> = Update;
updateContactsReset#7084a7be = Update;
updateChannelAvailableMessages#70db6837 channel_id:int available_min_id:int = Update;
updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
updateUserPinnedMessage#4c43da18 user_id:int id:int = Update;
updateChatPinnedMessage#e10db349 chat_id:int id:int version:int = Update;
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@@ -470,7 +475,7 @@ upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
config#3213dbba flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int = Config;
config#e6ca25f6 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config;
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
@@ -508,13 +513,14 @@ inputDocumentEmpty#72f0eaae = InputDocument;
inputDocument#1abfb575 id:long access_hash:long file_reference:bytes = InputDocument;
documentEmpty#36f8c871 id:long = Document;
document#59534e4c id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumb:PhotoSize dc_id:int attributes:Vector<DocumentAttribute> = Document;
document#9ba29cc1 flags:# id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumbs:flags.0?Vector<PhotoSize> dc_id:int attributes:Vector<DocumentAttribute> = Document;
help.support#17c6b5f6 phone_number:string user:User = help.Support;
notifyPeer#9fd40bd8 peer:Peer = NotifyPeer;
notifyUsers#b4c83b4c = NotifyPeer;
notifyChats#c007cec3 = NotifyPeer;
notifyBroadcasts#d612e8ef = NotifyPeer;
sendMessageTypingAction#16bf744e = SendMessageAction;
sendMessageCancelAction#fd5ec8f5 = SendMessageAction;
@@ -535,10 +541,16 @@ contacts.found#b3134d9d my_results:Vector<Peer> results:Vector<Peer> chats:Vecto
inputPrivacyKeyStatusTimestamp#4f96cb18 = InputPrivacyKey;
inputPrivacyKeyChatInvite#bdfb0426 = InputPrivacyKey;
inputPrivacyKeyPhoneCall#fabadc5f = InputPrivacyKey;
inputPrivacyKeyPhoneP2P#db9e70d2 = InputPrivacyKey;
inputPrivacyKeyForwards#a4dd4c08 = InputPrivacyKey;
inputPrivacyKeyProfilePhoto#5719bacc = InputPrivacyKey;
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
privacyKeyChatInvite#500e6dfa = PrivacyKey;
privacyKeyPhoneCall#3d662b7b = PrivacyKey;
privacyKeyPhoneP2P#39491cc8 = PrivacyKey;
privacyKeyForwards#69ec56a3 = PrivacyKey;
privacyKeyProfilePhoto#96151fed = PrivacyKey;
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
@@ -586,7 +598,7 @@ webPagePending#c586da1c id:long date:int = WebPage;
webPage#5f07b4bc flags:# id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page = WebPage;
webPageNotModified#85849473 = WebPage;
authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations;
@@ -610,7 +622,7 @@ inputStickerSetEmpty#ffb62b95 = InputStickerSet;
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
stickerSet#5585a139 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet;
stickerSet#6a90bcb7 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize count:int hash:int = StickerSet;
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
@@ -667,8 +679,8 @@ channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:
channelParticipant#15ebac1d user_id:int date:int = ChannelParticipant;
channelParticipantSelf#a3289a6d user_id:int inviter_id:int date:int = ChannelParticipant;
channelParticipantCreator#e3e2e1f9 user_id:int = ChannelParticipant;
channelParticipantAdmin#a82fa898 flags:# can_edit:flags.0?true user_id:int inviter_id:int promoted_by:int date:int admin_rights:ChannelAdminRights = ChannelParticipant;
channelParticipantBanned#222c1886 flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChannelBannedRights = ChannelParticipant;
channelParticipantAdmin#5daa6e23 flags:# can_edit:flags.0?true self:flags.1?true user_id:int inviter_id:flags.1?int promoted_by:int date:int admin_rights:ChatAdminRights = ChannelParticipant;
channelParticipantBanned#1c0facaf flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant;
channelParticipantsRecent#de3f3c79 = ChannelParticipantsFilter;
channelParticipantsAdmins#b4608969 = ChannelParticipantsFilter;
@@ -676,6 +688,7 @@ channelParticipantsKicked#a3b54985 q:string = ChannelParticipantsFilter;
channelParticipantsBots#b0d1865b = ChannelParticipantsFilter;
channelParticipantsBanned#1427a5e1 q:string = ChannelParticipantsFilter;
channelParticipantsSearch#656ac4b q:string = ChannelParticipantsFilter;
channelParticipantsContacts#bb6ae88d q:string = ChannelParticipantsFilter;
channels.channelParticipants#f56ee2a8 count:int participants:Vector<ChannelParticipant> users:Vector<User> = channels.ChannelParticipants;
channels.channelParticipantsNotModified#f0173fe9 = channels.ChannelParticipants;
@@ -717,7 +730,7 @@ messages.botResults#947ca848 flags:# gallery:flags.0?true query_id:long next_off
exportedMessageLink#5dab1af4 link:string html:string = ExportedMessageLink;
messageFwdHeader#559ebe6d flags:# from_id:flags.0?int date:int channel_id:flags.1?int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int = MessageFwdHeader;
messageFwdHeader#ec338270 flags:# from_id:flags.0?int from_name:flags.5?string date:int channel_id:flags.1?int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int = MessageFwdHeader;
auth.codeTypeSms#72a3158c = auth.CodeType;
auth.codeTypeCall#741cd3e3 = auth.CodeType;
@@ -794,6 +807,12 @@ textFixed#6c3f19b9 text:RichText = RichText;
textUrl#3c2884c1 text:RichText url:string webpage_id:long = RichText;
textEmail#de5a0dd6 text:RichText email:string = RichText;
textConcat#7e6260d7 texts:Vector<RichText> = RichText;
textSubscript#ed6a8504 text:RichText = RichText;
textSuperscript#c7fb5e01 text:RichText = RichText;
textMarked#34b8621 text:RichText = RichText;
textPhone#1ccb966a text:RichText phone:string = RichText;
textImage#81ccf4f document_id:long w:int h:int = RichText;
textAnchor#35553762 text:RichText name:string = RichText;
pageBlockUnsupported#13567e8a = PageBlock;
pageBlockTitle#70abc3fd text:RichText = PageBlock;
@@ -806,21 +825,24 @@ pageBlockPreformatted#c070d93e text:RichText language:string = PageBlock;
pageBlockFooter#48870999 text:RichText = PageBlock;
pageBlockDivider#db20b188 = PageBlock;
pageBlockAnchor#ce0d37b0 name:string = PageBlock;
pageBlockList#3a58c7f4 ordered:Bool items:Vector<RichText> = PageBlock;
pageBlockList#e4e88011 items:Vector<PageListItem> = PageBlock;
pageBlockBlockquote#263d7c26 text:RichText caption:RichText = PageBlock;
pageBlockPullquote#4f4456d3 text:RichText caption:RichText = PageBlock;
pageBlockPhoto#e9c69982 photo_id:long caption:RichText = PageBlock;
pageBlockVideo#d9d71866 flags:# autoplay:flags.0?true loop:flags.1?true video_id:long caption:RichText = PageBlock;
pageBlockPhoto#1759c560 flags:# photo_id:long caption:PageCaption url:flags.0?string webpage_id:flags.0?long = PageBlock;
pageBlockVideo#7c8fe7b6 flags:# autoplay:flags.0?true loop:flags.1?true video_id:long caption:PageCaption = PageBlock;
pageBlockCover#39f23300 cover:PageBlock = PageBlock;
pageBlockEmbed#cde200d1 flags:# full_width:flags.0?true allow_scrolling:flags.3?true url:flags.1?string html:flags.2?string poster_photo_id:flags.4?long w:int h:int caption:RichText = PageBlock;
pageBlockEmbedPost#292c7be9 url:string webpage_id:long author_photo_id:long author:string date:int blocks:Vector<PageBlock> caption:RichText = PageBlock;
pageBlockCollage#8b31c4f items:Vector<PageBlock> caption:RichText = PageBlock;
pageBlockSlideshow#130c8963 items:Vector<PageBlock> caption:RichText = PageBlock;
pageBlockEmbed#a8718dc5 flags:# full_width:flags.0?true allow_scrolling:flags.3?true url:flags.1?string html:flags.2?string poster_photo_id:flags.4?long w:flags.5?int h:flags.5?int caption:PageCaption = PageBlock;
pageBlockEmbedPost#f259a80b url:string webpage_id:long author_photo_id:long author:string date:int blocks:Vector<PageBlock> caption:PageCaption = PageBlock;
pageBlockCollage#65a0fa4d items:Vector<PageBlock> caption:PageCaption = PageBlock;
pageBlockSlideshow#31f9590 items:Vector<PageBlock> caption:PageCaption = PageBlock;
pageBlockChannel#ef1751b5 channel:Chat = PageBlock;
pageBlockAudio#31b81a7f audio_id:long caption:RichText = PageBlock;
pagePart#8e3f9ebe blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> = Page;
pageFull#556ec7aa blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> = Page;
pageBlockAudio#804361ea audio_id:long caption:PageCaption = PageBlock;
pageBlockKicker#1e148390 text:RichText = PageBlock;
pageBlockTable#bf4dea82 flags:# bordered:flags.0?true striped:flags.1?true title:RichText rows:Vector<PageTableRow> = PageBlock;
pageBlockOrderedList#9a8ae1e1 items:Vector<PageListOrderedItem> = PageBlock;
pageBlockDetails#76768bed flags:# open:flags.0?true blocks:Vector<PageBlock> title:RichText = PageBlock;
pageBlockRelatedArticles#16115a96 title:RichText articles:Vector<PageRelatedArticle> = PageBlock;
pageBlockMap#a44f3ef6 geo:GeoPoint zoom:int w:int h:int caption:PageCaption = PageBlock;
phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason;
phoneCallDiscardReasonDisconnect#e095c1a0 = PhoneCallDiscardReason;
@@ -879,7 +901,7 @@ phoneCallEmpty#5366c915 id:long = PhoneCall;
phoneCallWaiting#1b8f4ad1 flags:# id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
phoneCallRequested#83761ce4 id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall;
phoneCallAccepted#6d003d3f id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall;
phoneCall#ffe6ab67 id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector<PhoneConnection> start_date:int = PhoneCall;
phoneCall#e6f9ddf3 flags:# p2p_allowed:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector<PhoneConnection> start_date:int = PhoneCall;
phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
phoneConnection#9d4c17c0 id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection;
@@ -901,11 +923,7 @@ langPackStringDeleted#2979eeb2 key:string = LangPackString;
langPackDifference#f385c1f6 lang_code:string from_version:int version:int strings:Vector<LangPackString> = LangPackDifference;
langPackLanguage#117698f1 name:string native_name:string lang_code:string = LangPackLanguage;
channelAdminRights#5d7ceba5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true invite_link:flags.6?true pin_messages:flags.7?true add_admins:flags.9?true manage_call:flags.10?true = ChannelAdminRights;
channelBannedRights#58cf4249 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true until_date:int = ChannelBannedRights;
langPackLanguage#eeca5ce3 flags:# official:flags.0?true rtl:flags.2?true beta:flags.3?true name:string native_name:string lang_code:string base_lang_code:flags.1?string plural_code:string strings_count:int translated_count:int translations_url:string = LangPackLanguage;
channelAdminLogEventActionChangeTitle#e6dfb825 prev_value:string new_value:string = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeAbout#55188a2e prev_value:string new_value:string = ChannelAdminLogEventAction;
@@ -923,6 +941,8 @@ channelAdminLogEventActionParticipantToggleBan#e6d83d7e prev_participant:Channel
channelAdminLogEventActionParticipantToggleAdmin#d5676710 prev_participant:ChannelParticipant new_participant:ChannelParticipant = ChannelAdminLogEventAction;
channelAdminLogEventActionChangeStickerSet#b1c3caa7 prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = ChannelAdminLogEventAction;
channelAdminLogEventActionTogglePreHistoryHidden#5f5c95f1 new_value:Bool = ChannelAdminLogEventAction;
channelAdminLogEventActionDefaultBannedRights#2df5fc0a prev_banned_rights:ChatBannedRights new_banned_rights:ChatBannedRights = ChannelAdminLogEventAction;
channelAdminLogEventActionStopPoll#8f079643 message:Message = ChannelAdminLogEventAction;
channelAdminLogEvent#3b5a3e40 id:long date:int user_id:int action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
@@ -1042,6 +1062,75 @@ secureRequiredTypeOneOf#27477b4 types:Vector<SecureRequiredType> = SecureRequire
help.passportConfigNotModified#bfb9f457 = help.PassportConfig;
help.passportConfig#a098d6af hash:int countries_langs:DataJSON = help.PassportConfig;
inputAppEvent#1d1b1245 time:double type:string peer:long data:JSONValue = InputAppEvent;
jsonObjectValue#c0de1bd9 key:string value:JSONValue = JSONObjectValue;
jsonNull#3f6d7b68 = JSONValue;
jsonBool#c7345e6a value:Bool = JSONValue;
jsonNumber#2be0dfa4 value:double = JSONValue;
jsonString#b71e767a value:string = JSONValue;
jsonArray#f7444763 value:Vector<JSONValue> = JSONValue;
jsonObject#99c1d49d value:Vector<JSONObjectValue> = JSONValue;
pageTableCell#34566b6a flags:# header:flags.0?true align_center:flags.3?true align_right:flags.4?true valign_middle:flags.5?true valign_bottom:flags.6?true text:flags.7?RichText colspan:flags.1?int rowspan:flags.2?int = PageTableCell;
pageTableRow#e0c0c5e5 cells:Vector<PageTableCell> = PageTableRow;
pageCaption#6f747657 text:RichText credit:RichText = PageCaption;
pageListItemText#b92fb6cd text:RichText = PageListItem;
pageListItemBlocks#25e073fc blocks:Vector<PageBlock> = PageListItem;
pageListOrderedItemText#5e068047 num:string text:RichText = PageListOrderedItem;
pageListOrderedItemBlocks#98dd8936 num:string blocks:Vector<PageBlock> = PageListOrderedItem;
pageRelatedArticle#b390dc08 flags:# url:string webpage_id:long title:flags.0?string description:flags.1?string photo_id:flags.2?long author:flags.3?string published_date:flags.4?int = PageRelatedArticle;
page#ae891bec flags:# part:flags.0?true rtl:flags.1?true v2:flags.2?true url:string blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> = Page;
help.supportName#8c05f1c9 name:string = help.SupportName;
help.userInfoEmpty#f3ae2eed = help.UserInfo;
help.userInfo#1eb3758 message:string entities:Vector<MessageEntity> author:string date:int = help.UserInfo;
pollAnswer#6ca9c2e9 text:string option:bytes = PollAnswer;
poll#d5529d06 id:long flags:# closed:flags.0?true question:string answers:Vector<PollAnswer> = Poll;
pollAnswerVoters#3b6ddad2 flags:# chosen:flags.0?true option:bytes voters:int = PollAnswerVoters;
pollResults#5755785a flags:# min:flags.0?true results:flags.1?Vector<PollAnswerVoters> total_voters:flags.2?int = PollResults;
chatOnlines#f041e250 onlines:int = ChatOnlines;
statsURL#47a971e0 url:string = StatsURL;
chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true = ChatAdminRights;
chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true until_date:int = ChatBannedRights;
inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper;
inputWallPaperSlug#72091c80 slug:string = InputWallPaper;
account.wallPapersNotModified#1c199183 = account.WallPapers;
account.wallPapers#702b65a9 hash:int wallpapers:Vector<WallPaper> = account.WallPapers;
codeSettings#302f59f3 flags:# allow_flashcall:flags.0?true current_number:flags.1?true app_hash_persistent:flags.2?true app_hash:flags.3?string = CodeSettings;
wallPaperSettings#a12f40b8 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int intensity:flags.3?int = WallPaperSettings;
autoDownloadSettings#d246fd47 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true photo_size_max:int video_size_max:int file_size_max:int = AutoDownloadSettings;
account.autoDownloadSettings#63cacf26 low:AutoDownloadSettings medium:AutoDownloadSettings high:AutoDownloadSettings = account.AutoDownloadSettings;
emojiKeyword#d5b3b9f9 keyword:string emoticons:Vector<string> = EmojiKeyword;
emojiKeywordDeleted#236df622 keyword:string emoticons:Vector<string> = EmojiKeyword;
emojiKeywordsDifference#5cc761bd lang_code:string from_version:int version:int keywords:Vector<EmojiKeyword> = EmojiKeywordsDifference;
emojiURL#a575739d url:string = EmojiURL;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@@ -1052,7 +1141,7 @@ invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X;
invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X;
invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
auth.sendCode#86aef0ec flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool api_id:int api_hash:string = auth.SentCode;
auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
auth.signUp#1b067634 phone_number:string phone_code_hash:string phone_code:string first_name:string last_name:string = auth.Authorization;
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
auth.logOut#5717da40 = Bool;
@@ -1075,7 +1164,7 @@ account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
account.resetNotifySettings#db7e1747 = Bool;
account.updateProfile#78515775 flags:# first_name:flags.0?string last_name:flags.1?string about:flags.2?string = User;
account.updateStatus#6628562c offline:Bool = Bool;
account.getWallPapers#c04cfac2 = Vector<WallPaper>;
account.getWallPapers#aabb1763 hash:int = account.WallPapers;
account.reportPeer#ae189d5f peer:InputPeer reason:ReportReason = Bool;
account.checkUsername#2714d86c username:string = Bool;
account.updateUsername#3e0bdd7c username:string = User;
@@ -1084,7 +1173,7 @@ account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> =
account.deleteAccount#418d4e0b reason:string = Bool;
account.getAccountTTL#8fc711d = AccountDaysTTL;
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
account.sendChangePhoneCode#8e57deb flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode;
account.sendChangePhoneCode#82574ae5 phone_number:string settings:CodeSettings = auth.SentCode;
account.changePhone#70c32edb phone_number:string phone_code_hash:string phone_code:string = User;
account.updateDeviceLocked#38df3532 period:int = Bool;
account.getAuthorizations#e320c158 = account.Authorizations;
@@ -1092,7 +1181,7 @@ account.resetAuthorization#df77f3bc hash:long = Bool;
account.getPassword#548a30f5 = account.Password;
account.getPasswordSettings#9cd4eaf9 password:InputCheckPasswordSRP = account.PasswordSettings;
account.updatePasswordSettings#a59b102f password:InputCheckPasswordSRP new_settings:account.PasswordInputSettings = Bool;
account.sendConfirmPhoneCode#1516d7bd flags:# allow_flashcall:flags.0?true hash:string current_number:flags.0?Bool = auth.SentCode;
account.sendConfirmPhoneCode#1b3faa88 hash:string settings:CodeSettings = auth.SentCode;
account.confirmPhone#5f2178c3 phone_code_hash:string phone_code:string = Bool;
account.getTmpPassword#449e0b51 password:InputCheckPasswordSRP period:int = account.TmpPassword;
account.getWebAuthorizations#182e6d6f = account.WebAuthorizations;
@@ -1104,27 +1193,40 @@ account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long =
account.deleteSecureValue#b880bc4b types:Vector<SecureValueType> = Bool;
account.getAuthorizationForm#b86ba8e1 bot_id:int scope:string public_key:string = account.AuthorizationForm;
account.acceptAuthorization#e7027c94 bot_id:int scope:string public_key:string value_hashes:Vector<SecureValueHash> credentials:SecureCredentialsEncrypted = Bool;
account.sendVerifyPhoneCode#823380b4 flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode;
account.sendVerifyPhoneCode#a5a356f9 phone_number:string settings:CodeSettings = auth.SentCode;
account.verifyPhone#4dd3a7f6 phone_number:string phone_code_hash:string phone_code:string = Bool;
account.sendVerifyEmailCode#7011509f email:string = account.SentEmailCode;
account.verifyEmail#ecba39db email:string code:string = Bool;
account.initTakeoutSession#f05b4804 flags:# contacts:flags.0?true message_users:flags.1?true message_chats:flags.2?true message_megagroups:flags.3?true message_channels:flags.4?true files:flags.5?true file_max_size:flags.5?int = account.Takeout;
account.finishTakeoutSession#1d2652ee flags:# success:flags.0?true = Bool;
account.confirmPasswordEmail#8fdf1920 code:string = Bool;
account.resendPasswordEmail#7a7f2a15 = Bool;
account.cancelPasswordEmail#c1cbd5b6 = Bool;
account.getContactSignUpNotification#9f07c728 = Bool;
account.setContactSignUpNotification#cff43f61 silent:Bool = Bool;
account.getNotifyExceptions#53577479 flags:# compare_sound:flags.1?true peer:flags.0?InputNotifyPeer = Updates;
account.getWallPaper#fc8ddbea wallpaper:InputWallPaper = WallPaper;
account.uploadWallPaper#dd853661 file:InputFile mime_type:string settings:WallPaperSettings = WallPaper;
account.saveWallPaper#6c5a5b37 wallpaper:InputWallPaper unsave:Bool settings:WallPaperSettings = Bool;
account.installWallPaper#feed5769 wallpaper:InputWallPaper settings:WallPaperSettings = Bool;
account.resetWallPapers#bb3b9804 = Bool;
account.getAutoDownloadSettings#56da0b3f = account.AutoDownloadSettings;
account.saveAutoDownloadSettings#76f36233 flags:# low:flags.0?true high:flags.1?true settings:AutoDownloadSettings = Bool;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector<SecureValueError> = Bool;
contacts.getContactIDs#2caa4a42 hash:int = Vector<int>;
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
contacts.getContacts#c023849f hash:int = contacts.Contacts;
contacts.importContacts#2c800be5 contacts:Vector<InputContact> = contacts.ImportedContacts;
contacts.deleteContact#8e953744 id:InputUser = contacts.Link;
contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool;
contacts.deleteByPhones#1013fd9e phones:Vector<string> = Bool;
contacts.block#332b49fc id:InputUser = Bool;
contacts.unblock#e54100bd id:InputUser = Bool;
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
contacts.exportCard#84e53737 = Vector<int>;
contacts.importCard#4fe196fe export_card:Vector<int> = User;
contacts.search#11f812d8 q:string limit:int = contacts.Found;
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers;
@@ -1138,7 +1240,7 @@ messages.getDialogs#b098aee6 flags:# exclude_pinned:flags.0?true offset_date:int
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
messages.search#8614ef68 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true peer:InputPeer max_id:int = messages.AffectedHistory;
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int = messages.AffectedHistory;
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
@@ -1171,7 +1273,7 @@ messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages
messages.getStickers#43d4f2c emoticon:string hash:int = messages.Stickers;
messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
messages.exportChatInvite#df7534c peer:InputPeer = ExportedChatInvite;
messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
messages.importChatInvite#6c50051c hash:string = Updates;
messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet;
@@ -1179,7 +1281,6 @@ messages.installStickerSet#c78fe460 stickerset:InputStickerSet archived:Bool = m
messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
messages.startBot#e6df7378 bot:InputUser peer:InputPeer random_id:long start_param:string = Updates;
messages.getMessagesViews#c4c8a55d peer:InputPeer id:Vector<int> increment:Bool = Vector<int>;
messages.toggleChatAdmins#ec8bd9e1 chat_id:int enabled:Bool = Updates;
messages.editChatAdmin#a9e69f2e chat_id:int user_id:InputUser is_admin:Bool = Bool;
messages.migrateChat#15a3b8e3 chat_id:int = Updates;
messages.searchGlobal#9e3cacb0 q:string offset_date:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
@@ -1190,10 +1291,10 @@ messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs;
messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
messages.setInlineBotResults#eb5ea206 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM = Bool;
messages.sendInlineBotResult#b16e06fe flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
messages.sendInlineBotResult#b16e06fe flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string = Updates;
messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
messages.editMessage#c000e4c8 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Updates;
messages.editInlineBotMessage#adc3e828 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Bool;
messages.editMessage#d116f31e flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Bool;
messages.getBotCallbackAnswer#810a9fec flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes = messages.BotCallbackAnswer;
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
@@ -1233,6 +1334,16 @@ messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
messages.markDialogUnread#c286d98f flags:# unread:flags.0?true peer:InputDialogPeer = Bool;
messages.getDialogUnreadMarks#22e24e22 = Vector<DialogPeer>;
messages.clearAllDrafts#7e58ee9c = Bool;
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true peer:InputPeer id:int = Updates;
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
messages.getPollResults#73bb643b peer:InputPeer msg_id:int = Updates;
messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines;
messages.getStatsURL#812c2ae6 flags:# dark:flags.0?true peer:InputPeer params:string = StatsURL;
messages.editChatAbout#def60797 peer:InputPeer about:string = Bool;
messages.editChatDefaultBannedRights#a5866b41 peer:InputPeer banned_rights:ChatBannedRights = Updates;
messages.getEmojiKeywords#35a0e062 lang_code:string = EmojiKeywordsDifference;
messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference;
messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL;
updates.getState#edd4882a = updates.State;
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
@@ -1255,7 +1366,6 @@ upload.getFileHashes#c7025931 location:InputFileLocation offset:int = Vector<Fil
help.getConfig#c4f9186b = Config;
help.getNearestDc#1fb33026 = NearestDc;
help.getAppUpdate#522d5a7d source:string = help.AppUpdate;
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
help.getInviteText#4d392343 = help.InviteText;
help.getSupport#9cdf08cd = help.Support;
help.getAppChangelog#9010ef6f prev_app_version:string = Updates;
@@ -1266,7 +1376,12 @@ help.getProxyData#3d7758e1 = help.ProxyData;
help.getTermsOfServiceUpdate#2ca51fd1 = help.TermsOfServiceUpdate;
help.acceptTermsOfService#ee72f79a id:DataJSON = Bool;
help.getDeepLinkInfo#3fedc75f path:string = help.DeepLinkInfo;
help.getAppConfig#98914110 = JSONValue;
help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
help.getPassportConfig#c661ad08 hash:int = help.PassportConfig;
help.getSupportName#d360e72c = help.SupportName;
help.getUserInfo#38a08d3 user_id:InputUser = help.UserInfo;
help.editUserInfo#66b91b70 user_id:InputUser message:string entities:Vector<MessageEntity> = help.UserInfo;
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
@@ -1278,8 +1393,7 @@ channels.getParticipant#546dd7a6 channel:InputChannel user_id:InputUser = channe
channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;
channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull;
channels.createChannel#f4893d7f flags:# broadcast:flags.0?true megagroup:flags.1?true title:string about:string = Updates;
channels.editAbout#13e27f1e channel:InputChannel about:string = Bool;
channels.editAdmin#20b88214 channel:InputChannel user_id:InputUser admin_rights:ChannelAdminRights = Updates;
channels.editAdmin#70f893ba channel:InputChannel user_id:InputUser admin_rights:ChatAdminRights = Updates;
channels.editTitle#566decd0 channel:InputChannel title:string = Updates;
channels.editPhoto#f12e57c9 channel:InputChannel photo:InputChatPhoto = Updates;
channels.checkUsername#10e6bd2c channel:InputChannel username:string = Bool;
@@ -1287,14 +1401,11 @@ channels.updateUsername#3514b3de channel:InputChannel username:string = Bool;
channels.joinChannel#24b524c5 channel:InputChannel = Updates;
channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite;
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
channels.toggleInvites#49609307 channel:InputChannel enabled:Bool = Updates;
channels.exportMessageLink#ceb77163 channel:InputChannel id:int grouped:Bool = ExportedMessageLink;
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
channels.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
channels.getAdminedPublicChannels#8d8d82d7 = messages.Chats;
channels.editBanned#bfd915cd channel:InputChannel user_id:InputUser banned_rights:ChannelBannedRights = Updates;
channels.editBanned#72796912 channel:InputChannel user_id:InputUser banned_rights:ChatBannedRights = Updates;
channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector<InputUser> max_id:long min_id:long limit:int = channels.AdminLogResults;
channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet = Bool;
channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool;
@@ -1323,12 +1434,13 @@ phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtoc
phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall;
phone.receivedCall#17d54f61 peer:InputPhoneCall = Bool;
phone.discardCall#78d413a6 peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates;
phone.setCallRating#1c536a34 peer:InputPhoneCall rating:int comment:string = Updates;
phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhoneCall rating:int comment:string = Updates;
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference;
langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector<string> = Vector<LangPackString>;
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
langpack.getDifference#cd984aa5 lang_pack:string lang_code:string from_version:int = LangPackDifference;
langpack.getLanguages#42c6978f lang_pack:string = Vector<LangPackLanguage>;
langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLanguage;
// LAYER 86
// LAYER 97

View File

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

View File

@@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,4,0
PRODUCTVERSION 1,4,4,0
FILEVERSION 1,6,2,0
PRODUCTVERSION 1,6,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -52,10 +52,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileDescription", "Telegram Desktop"
VALUE "FileVersion", "1.4.4.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2018"
VALUE "FileVersion", "1.6.2.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2019"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "1.4.4.0"
VALUE "ProductVersion", "1.6.2.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,4,0
PRODUCTVERSION 1,4,4,0
FILEVERSION 1,6,2,0
PRODUCTVERSION 1,6,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -43,10 +43,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileDescription", "Telegram Desktop Updater"
VALUE "FileVersion", "1.4.4.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2018"
VALUE "FileVersion", "1.6.2.0"
VALUE "LegalCopyright", "Copyright (C) 2014-2019"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "1.4.4.0"
VALUE "ProductVersion", "1.6.2.0"
END
END
BLOCK "VarFileInfo"

View File

@@ -7,9 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <windows.h>
#include <string>
#include <windows.h>
#ifdef small
#undef small
#endif // small
#pragma warning(push)
#pragma warning(disable:4091)
#include <DbgHelp.h>

View File

@@ -6,6 +6,7 @@ For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#import <Cocoa/Cocoa.h>
#include <sys/xattr.h>
NSString *appName = @"Telegram.app";
NSString *appDir = nil;
@@ -44,6 +45,20 @@ void writeLog(NSString *msg) {
[_logFile synchronizeFile];
}
void RemoveQuarantineAttribute(NSString *path) {
const char *kQuarantineAttribute = "com.apple.quarantine";
writeLog([@"Removing quarantine: " stringByAppendingString:path]);
removexattr([path fileSystemRepresentation], kQuarantineAttribute, 0);
}
void RemoveQuarantineFromBundle(NSString *path) {
RemoveQuarantineAttribute(path);
RemoveQuarantineAttribute([path stringByAppendingString:@"/Contents/MacOS/Telegram"]);
RemoveQuarantineAttribute([path stringByAppendingString:@"/Contents/Helpers/crashpad_handler"]);
RemoveQuarantineAttribute([path stringByAppendingString:@"/Contents/Frameworks/Updater"]);
}
void delFolder() {
writeLog([@"Fully clearing old path: " stringByAppendingString:[workDir stringByAppendingString:@"tupdates/ready"]]);
if (![[NSFileManager defaultManager] removeItemAtPath:[workDir stringByAppendingString:@"tupdates/ready"] error:nil]) {
@@ -232,6 +247,9 @@ int main(int argc, const char * argv[]) {
}
NSString *appPath = [[NSArray arrayWithObjects:appDir, appRealName, nil] componentsJoinedByString:@""];
RemoveQuarantineFromBundle(appPath);
NSMutableArray *args = [[NSMutableArray alloc] initWithObjects: @"-noupdate", nil];
if (toSettings) [args addObject:@"-tosettings"];
if (_debug) [args addObject:@"-debug"];
@@ -248,18 +266,24 @@ int main(int argc, const char * argv[]) {
[args addObject:workDir];
}
writeLog([[NSArray arrayWithObjects:@"Running application '", appPath, @"' with args '", [args componentsJoinedByString:@"' '"], @"'..", nil] componentsJoinedByString:@""]);
NSError *error = nil;
NSRunningApplication *result = [[NSWorkspace sharedWorkspace]
for (int i = 0; i < 5; ++i) {
NSError *error = nil;
NSRunningApplication *result = [[NSWorkspace sharedWorkspace]
launchApplicationAtURL:[NSURL fileURLWithPath:appPath]
options:NSWorkspaceLaunchDefault
configuration:[NSDictionary
dictionaryWithObject:args
forKey:NSWorkspaceLaunchConfigurationArguments]
error:&error];
if (!result) {
if (result) {
closeLog();
return 0;
}
writeLog([[NSString stringWithFormat:@"Could not run application, error %ld: ", (long)[error code]] stringByAppendingString: error ? [error localizedDescription] : @"(nil)"]);
usleep(200000);
}
closeLog();
return result ? 0 : -1;
return -1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/timer.h"
#include "base/flat_map.h"
#include "base/flat_set.h"
#include "core/single_timer.h"
#include "mtproto/sender.h"
#include "chat_helpers/stickers.h"
#include "data/data_messages.h"
@@ -24,6 +23,11 @@ enum class SendMediaType;
struct FileLoadTo;
class mtpFileLoader;
namespace Data {
struct UpdatedFileReferences;
class WallPaper;
} // namespace Data
namespace InlineBots {
class Result;
} // namespace InlineBots
@@ -43,14 +47,6 @@ struct CloudPasswordState;
namespace Api {
inline const MTPVector<MTPChat> *getChatsFromMessagesChats(const MTPmessages_Chats &chats) {
switch (chats.type()) {
case mtpc_messages_chats: return &chats.c_messages_chats().vchats;
case mtpc_messages_chatsSlice: return &chats.c_messages_chatsSlice().vchats;
}
return nullptr;
}
template <typename IntRange>
inline int32 CountHash(IntRange &&range) {
uint32 acc = 0;
@@ -62,7 +58,7 @@ inline int32 CountHash(IntRange &&range) {
} // namespace Api
class ApiWrap : private MTP::Sender, private base::Subscriber {
class ApiWrap : public MTP::Sender, private base::Subscriber {
public:
ApiWrap(not_null<AuthSession*> session);
@@ -87,16 +83,22 @@ public:
void requestDialogEntry(
not_null<History*> history,
Fn<void()> callback = nullptr);
void requestDialogEntries(std::vector<not_null<History*>> histories);
void dialogEntryApplied(not_null<History*> history);
//void applyFeedSources(const MTPDchannels_feedSources &data); // #feed
//void setFeedChannels(
// not_null<Data::Feed*> feed,
// const std::vector<not_null<ChannelData*>> &channels);
void changeDialogUnreadMark(not_null<History*> history, bool unread);
//void changeDialogUnreadMark(not_null<Data::Feed*> feed, bool unread); // #feed
void requestFakeChatListMessage(not_null<History*> history);
void requestFullPeer(PeerData *peer);
void requestPeer(PeerData *peer);
void requestWallPaper(
const QString &slug,
Fn<void(const Data::WallPaper &)> done,
Fn<void(const RPCError &)> fail);
void requestFullPeer(not_null<PeerData*> peer);
void requestPeer(not_null<PeerData*> peer);
void requestPeers(const QList<PeerData*> &peers);
void requestLastParticipants(not_null<ChannelData*> channel);
void requestBots(not_null<ChannelData*> channel);
@@ -125,32 +127,52 @@ public:
void requestTermsUpdate();
void acceptTerms(bytes::const_span termsId);
void checkChatInvite(
const QString &hash,
FnMut<void(const MTPChatInvite &)> done,
FnMut<void(const RPCError &)> fail);
void importChatInvite(const QString &hash);
void requestChannelMembersForAdd(
not_null<ChannelData*> channel,
Fn<void(const MTPchannels_ChannelParticipants&)> callback);
void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result);
void processFullPeer(UserData *user, const MTPUserFull &result);
void processFullPeer(
not_null<PeerData*> peer,
const MTPmessages_ChatFull &result);
void processFullPeer(
not_null<UserData*> user,
const MTPUserFull &result);
void migrateChat(
not_null<ChatData*> chat,
FnMut<void(not_null<ChannelData*>)> done,
FnMut<void(const RPCError &)> fail = nullptr);
void markMediaRead(const base::flat_set<not_null<HistoryItem*>> &items);
void markMediaRead(not_null<HistoryItem*> item);
void requestSelfParticipant(ChannelData *channel);
void requestSelfParticipant(not_null<ChannelData*> channel);
void kickParticipant(not_null<ChatData*> chat, not_null<UserData*> user);
void kickParticipant(
not_null<ChannelData*> channel,
not_null<UserData*> user,
const MTPChannelBannedRights &currentRights);
const MTPChatBannedRights &currentRights);
void unblockParticipant(
not_null<ChannelData*> channel,
not_null<UserData*> user);
void deleteAllFromUser(
not_null<ChannelData*> channel,
not_null<UserData*> from);
void saveDefaultRestrictions(
not_null<PeerData*> peer,
const MTPChatBannedRights &rights,
Fn<void(bool)> callback = nullptr);
void requestWebPageDelayed(WebPageData *page);
void clearWebPageRequest(WebPageData *page);
void clearWebPageRequests();
void requestAttachedStickerSets(not_null<PhotoData*> photo);
void scheduleStickerSetRequest(uint64 setId, uint64 access);
void requestStickerSets();
void saveStickerSets(
@@ -189,7 +211,12 @@ public:
const MTPUserStatus &status,
int currentOnlineTill);
void clearHistory(not_null<PeerData*> peer);
void clearHistory(not_null<PeerData*> peer, bool revoke);
void deleteConversation(not_null<PeerData*> peer, bool revoke);
void deleteMessages(
not_null<PeerData*> peer,
const QVector<MTPint> &ids,
bool revoke);
base::Observable<PeerData*> &fullPeerUpdated() {
return _fullPeerUpdated;
@@ -203,12 +230,9 @@ public:
void jumpToDate(Dialogs::Key chat, const QDate &date);
void preloadEnoughUnreadMentions(not_null<History*> history);
void checkForUnreadMentions(const base::flat_set<MsgId> &possiblyReadMentions, ChannelData *channel = nullptr);
void editChatAdmins(
not_null<ChatData*> chat,
bool adminsEnabled,
base::flat_set<not_null<UserData*>> &&admins);
void checkForUnreadMentions(
const base::flat_set<MsgId> &possiblyReadMentions,
ChannelData *channel = nullptr);
using SliceType = Data::LoadDirection;
void requestSharedMedia(
@@ -254,6 +278,9 @@ public:
int availableCount,
const QVector<MTPChannelParticipant> &list)> callbackList,
Fn<void()> callbackNotModified = nullptr);
void addChatParticipants(
not_null<PeerData*> peer,
const std::vector<not_null<UserData*>> &users);
struct SendOptions {
SendOptions(not_null<History*> history);
@@ -323,6 +350,7 @@ public:
bool handleSupportSwitch = false;
};
void sendMessage(MessageToSend &&message);
void sendBotStart(not_null<UserData*> bot, PeerData *chat = nullptr);
void sendInlineResult(
not_null<UserData*> bot,
not_null<InlineBots::Result*> data,
@@ -343,6 +371,11 @@ public:
rpl::producer<Core::CloudPasswordState> passwordState() const;
std::optional<Core::CloudPasswordState> passwordStateCurrent() const;
void reloadContactSignupSilent();
rpl::producer<bool> contactSignupSilent() const;
std::optional<bool> contactSignupSilentCurrent() const;
void saveContactSignupSilent(bool silent);
void saveSelfBio(const QString &text, FnMut<void()> done);
struct Privacy {
@@ -350,6 +383,9 @@ public:
LastSeen,
Calls,
Invites,
CallsPeer2Peer,
Forwards,
ProfilePhoto,
};
enum class Option {
Everyone,
@@ -369,6 +405,17 @@ public:
rpl::producer<int> selfDestructValue() const;
void saveSelfDestruct(int days);
void createPoll(
const PollData &data,
const SendOptions &options,
FnMut<void()> done,
FnMut<void(const RPCError &error)> fail);
void sendPollVotes(
FullMsgId itemId,
const std::vector<QByteArray> &options);
void closePoll(FullMsgId itemId);
void reloadPollResults(not_null<HistoryItem*> item);
~ApiWrap();
private:
@@ -383,13 +430,9 @@ private:
struct StickersByEmoji {
std::vector<not_null<DocumentData*>> list;
int32 hash = 0;
TimeMs received = 0;
crl::time received = 0;
};
using SimpleFileLocationId = Data::SimpleFileLocationId;
using DocumentFileLocationId = Data::DocumentFileLocationId;
using FileLocationId = Data::FileLocationId;
void updatesReceived(const MTPUpdates &updates);
void checkQuitPreventFinished();
@@ -404,13 +447,18 @@ private:
QVector<MTPInputMessage> collectMessageIds(const MessageDataRequests &requests);
MessageDataRequests *messageDataRequests(ChannelData *channel, bool onlyExisting = false);
void applyPeerDialogs(const MTPmessages_PeerDialogs &dialogs);
void historyDialogEntryApplied(not_null<History*> history);
void applyFeedDialogs(
not_null<Data::Feed*> feed,
const MTPmessages_Dialogs &dialogs);
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req);
void gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req);
void gotChatFull(
not_null<PeerData*> peer,
const MTPmessages_ChatFull &result,
mtpRequestId req);
void gotUserFull(
not_null<UserData*> user,
const MTPUserFull &result,
mtpRequestId req);
void applyLastParticipantsList(
not_null<ChannelData*> channel,
int availableCount,
@@ -454,9 +502,6 @@ private:
void requestSavedGifs(TimeId now);
void readFeaturedSets();
void cancelEditChatAdmins(not_null<ChatData*> chat);
void saveChatAdmins(not_null<ChatData*> chat);
void sendSaveChatAdminsRequests(not_null<ChatData*> chat);
void refreshChannelAdmins(
not_null<ChannelData*> channel,
const QVector<MTPChannelParticipant> &participants);
@@ -500,6 +545,10 @@ private:
UserId userId,
const SendOptions &options);
void deleteHistory(
not_null<PeerData*> peer,
bool justClear,
bool revoke);
void sendReadRequest(not_null<PeerData*> peer, MsgId upTo);
int applyAffectedHistory(
not_null<PeerData*> peer,
@@ -560,6 +609,13 @@ private:
void setSelfDestructDays(int days);
void migrateDone(
not_null<PeerData*> peer,
not_null<ChannelData*> channel);
void migrateFail(not_null<PeerData*> peer, const RPCError &error);
void sendDialogRequests();
not_null<AuthSession*> _session;
MessageDataRequests _messageDataRequests;
@@ -588,7 +644,11 @@ private:
not_null<UserData*>>;
base::flat_map<KickRequest, mtpRequestId> _kickRequests;
QMap<ChannelData*, mtpRequestId> _selfParticipantRequests;
base::flat_map<
not_null<PeerData*>,
mtpRequestId> _defaultRestrictionsRequests;
base::flat_set<not_null<ChannelData*>> _selfParticipantRequests;
base::flat_map<
not_null<ChannelData*>,
@@ -630,19 +690,13 @@ private:
base::flat_map<
not_null<History*>,
std::vector<Fn<void()>>> _dialogRequests;
base::flat_map<
not_null<History*>,
std::vector<Fn<void()>>> _dialogRequestsPending;
base::flat_set<not_null<History*>> _fakeChatListRequests;
base::flat_map<not_null<History*>, mtpRequestId> _unreadMentionsRequests;
base::flat_map<
not_null<ChatData*>,
mtpRequestId> _chatAdminsEnabledRequests;
base::flat_map<
not_null<ChatData*>,
base::flat_set<not_null<UserData*>>> _chatAdminsToSave;
base::flat_map<
not_null<ChatData*>,
base::flat_set<mtpRequestId>> _chatAdminsSaveRequests;
base::flat_map<std::tuple<
not_null<PeerData*>,
SharedMediaType,
@@ -686,7 +740,7 @@ private:
rpl::event_stream<uint64> _stickerSetInstalled;
base::flat_map<not_null<Data::Feed*>, TimeMs> _feedReadsDelayed;
base::flat_map<not_null<Data::Feed*>, crl::time> _feedReadsDelayed;
base::flat_map<not_null<Data::Feed*>, mtpRequestId> _feedReadRequests;
base::Timer _feedReadTimer;
@@ -704,9 +758,21 @@ private:
mtpRequestId _deepLinkInfoRequestId = 0;
TimeMs _termsUpdateSendAt = 0;
crl::time _termsUpdateSendAt = 0;
mtpRequestId _termsUpdateRequestId = 0;
mtpRequestId _checkInviteRequestId = 0;
FnMut<void(const MTPChatInvite &result)> _checkInviteDone;
FnMut<void(const RPCError &error)> _checkInviteFail;
struct MigrateCallbacks {
FnMut<void(not_null<ChannelData*>)> done;
FnMut<void(const RPCError&)> fail;
};
base::flat_map<
not_null<PeerData*>,
std::vector<MigrateCallbacks>> _migrateCallbacks;
std::vector<FnMut<void(const MTPUser &)>> _supportContactCallbacks;
base::flat_map<FullMsgId, not_null<PeerData*>> _peerPhotoUploads;
@@ -727,4 +793,19 @@ private:
std::optional<int> _selfDestructDays;
rpl::event_stream<int> _selfDestructChanges;
base::flat_map<FullMsgId, mtpRequestId> _pollVotesRequestIds;
base::flat_map<FullMsgId, mtpRequestId> _pollCloseRequestIds;
base::flat_map<FullMsgId, mtpRequestId> _pollReloadRequestIds;
mtpRequestId _wallPaperRequestId = 0;
QString _wallPaperSlug;
Fn<void(const Data::WallPaper &)> _wallPaperDone;
Fn<void(const RPCError &)> _wallPaperFail;
mtpRequestId _contactSignupSilentRequestId = 0;
std::optional<bool> _contactSignupSilent;
rpl::event_stream<bool> _contactSignupSilentChanges;
mtpRequestId _attachedStickerSetsRequestId = 0;
};

File diff suppressed because it is too large Load Diff

View File

@@ -8,17 +8,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "data/data_types.h"
#include "data/data_peer.h"
enum NewMessageType : char;
class Messenger;
enum class ImageRoundRadius;
class MainWindow;
class MainWidget;
class LocationCoords;
struct LocationData;
class HistoryItem;
class History;
class Histories;
namespace HistoryView {
class Element;
} // namespace HistoryView
@@ -39,6 +35,8 @@ enum RoundCorners {
SelectedOverlayLargeCorners,
DateCorners,
DateSelectedCorners,
OverviewVideoCorners,
OverviewVideoSelectedCorners,
ForwardCorners,
MediaviewSaveCorners,
EmojiHoverCorners,
@@ -68,16 +66,6 @@ namespace App {
QString formatPhone(QString phone);
UserData *feedUser(const MTPUser &user);
UserData *feedUsers(const MTPVector<MTPUser> &users); // returns last user
PeerData *feedChat(const MTPChat &chat);
PeerData *feedChats(const MTPVector<MTPChat> &chats); // returns last chat
void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos);
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d);
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d);
void feedChatAdmins(const MTPDupdateChatAdmins &d);
void feedParticipantAdmin(const MTPDupdateChatParticipantAdmin &d);
bool checkEntitiesAndViewsUpdate(const MTPDmessage &m); // returns true if item found and it is not detached
void updateEditedMessage(const MTPMessage &m);
void addSavedGif(DocumentData *doc);
@@ -91,71 +79,13 @@ namespace App {
ImagePtr image(const MTPPhotoSize &size);
PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded);
inline UserData *user(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
return asUser(peer(id, restriction));
}
inline ChatData *chat(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
return asChat(peer(id, restriction));
}
inline ChannelData *channel(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
return asChannel(peer(id, restriction));
}
inline UserData *user(UserId userId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
return asUser(peer(peerFromUser(userId), restriction));
}
inline ChatData *chat(ChatId chatId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
return asChat(peer(peerFromChat(chatId), restriction));
}
inline ChannelData *channel(ChannelId channelId, PeerData::LoadedStatus restriction = PeerData::NotLoaded) {
return asChannel(peer(peerFromChannel(channelId), restriction));
}
inline PeerData *peerLoaded(const PeerId &id) {
return peer(id, PeerData::FullLoaded);
}
inline UserData *userLoaded(const PeerId &id) {
return user(id, PeerData::FullLoaded);
}
inline ChatData *chatLoaded(const PeerId &id) {
return chat(id, PeerData::FullLoaded);
}
inline ChannelData *channelLoaded(const PeerId &id) {
return channel(id, PeerData::FullLoaded);
}
inline UserData *userLoaded(UserId userId) {
return user(userId, PeerData::FullLoaded);
}
inline ChatData *chatLoaded(ChatId chatId) {
return chat(chatId, PeerData::FullLoaded);
}
inline ChannelData *channelLoaded(ChannelId channelId) {
return channel(channelId, PeerData::FullLoaded);
}
void enumerateUsers(Fn<void(not_null<UserData*>)> action);
void enumerateChatsChannels(
Fn<void(not_null<PeerData*>)> action);
[[nodiscard]] QString peerName(const PeerData *peer, bool forDialogs = false);
PeerData *peerByName(const QString &username);
QString peerName(const PeerData *peer, bool forDialogs = false);
LocationData *location(const LocationCoords &coords);
void forgetMedia();
Histories &histories();
not_null<History*> history(const PeerId &peer);
History *historyLoaded(const PeerId &peer);
HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
inline not_null<History*> history(const PeerData *peer) {
Assert(peer != nullptr);
return history(peer->id);
}
inline History *historyLoaded(const PeerData *peer) {
return peer ? historyLoaded(peer->id) : nullptr;
}
inline HistoryItem *histItemById(const ChannelData *channel, MsgId itemId) {
return histItemById(channel ? peerToChannel(channel->id) : 0, itemId);
}
inline HistoryItem *histItemById(const FullMsgId &msgId) {
[[nodiscard]] HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
[[nodiscard]] HistoryItem *histItemById(
const ChannelData *channel,
MsgId itemId);
[[nodiscard]] inline HistoryItem *histItemById(const FullMsgId &msgId) {
return histItemById(msgId.channel, msgId.msg);
}
void historyRegItem(not_null<HistoryItem*> item);
@@ -187,13 +117,9 @@ namespace App {
const style::font &monofont();
void clearHistories();
void initMedia();
void deinitMedia();
void checkImageCacheSize();
enum LaunchState {
Launched = 0,
QuitRequested = 1,
@@ -228,14 +154,4 @@ namespace App {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
}
struct WallPaper {
WallPaper(int32 id, ImagePtr thumb, ImagePtr full) : id(id), thumb(thumb), full(full) {
}
int32 id;
ImagePtr thumb;
ImagePtr full;
};
typedef QList<WallPaper> WallPapers;
DeclareSetting(WallPapers, ServerBackgrounds);
};

View File

@@ -1,501 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "application.h"
#include "platform/platform_specific.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "storage/localstorage.h"
#include "window/notifications_manager.h"
#include "core/crash_reports.h"
#include "messenger.h"
#include "base/timer.h"
#include "base/concurrent_timer.h"
#include "base/qthelp_url.h"
#include "base/qthelp_regex.h"
#include "core/update_checker.h"
#include "core/crash_report_window.h"
namespace {
constexpr auto kEmptyPidForCommandResponse = 0ULL;
QChar _toHex(ushort v) {
v = v & 0x000F;
return QChar::fromLatin1((v >= 10) ? ('a' + (v - 10)) : ('0' + v));
}
ushort _fromHex(QChar c) {
return ((c.unicode() >= uchar('a')) ? (c.unicode() - uchar('a') + 10) : (c.unicode() - uchar('0'))) & 0x000F;
}
QString _escapeTo7bit(const QString &str) {
QString result;
result.reserve(str.size() * 2);
for (int i = 0, l = str.size(); i != l; ++i) {
QChar ch(str.at(i));
ushort uch(ch.unicode());
if (uch < 32 || uch > 127 || uch == ushort(uchar('%'))) {
result.append('%').append(_toHex(uch >> 12)).append(_toHex(uch >> 8)).append(_toHex(uch >> 4)).append(_toHex(uch));
} else {
result.append(ch);
}
}
return result;
}
QString _escapeFrom7bit(const QString &str) {
QString result;
result.reserve(str.size());
for (int i = 0, l = str.size(); i != l; ++i) {
QChar ch(str.at(i));
if (ch == QChar::fromLatin1('%') && i + 4 < l) {
result.append(QChar(ushort((_fromHex(str.at(i + 1)) << 12) | (_fromHex(str.at(i + 2)) << 8) | (_fromHex(str.at(i + 3)) << 4) | _fromHex(str.at(i + 4)))));
i += 4;
} else {
result.append(ch);
}
}
return result;
}
} // namespace
bool InternalPassportLink(const QString &url) {
const auto urlTrimmed = url.trimmed();
if (!urlTrimmed.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
return false;
}
const auto command = urlTrimmed.midRef(qstr("tg://").size());
using namespace qthelp;
const auto matchOptions = RegExOption::CaseInsensitive;
const auto authMatch = regex_match(
qsl("^passport/?\\?(.+)(#|$)"),
command,
matchOptions);
const auto usernameMatch = regex_match(
qsl("^resolve/?\\?(.+)(#|$)"),
command,
matchOptions);
const auto usernameValue = usernameMatch->hasMatch()
? url_parse_params(
usernameMatch->captured(1),
UrlParamNameTransform::ToLower).value(qsl("domain"))
: QString();
const auto authLegacy = (usernameValue == qstr("telegrampassport"));
return authMatch->hasMatch() || authLegacy;
}
bool StartUrlRequiresActivate(const QString &url) {
return Messenger::Instance().locked()
? true
: !InternalPassportLink(url);
}
Application::Application(
not_null<Core::Launcher*> launcher,
int &argc,
char **argv)
: QApplication(argc, argv)
, _launcher(launcher)
, _updateChecker(Core::UpdaterDisabled()
? nullptr
: std::make_unique<Core::UpdateChecker>()) {
const auto d = QFile::encodeName(QDir(cWorkingDir()).absolutePath());
char h[33] = { 0 };
hashMd5Hex(d.constData(), d.size(), h);
#ifndef OS_MAC_STORE
_localServerName = psServerPrefix() + h + '-' + cGUIDStr();
#else // OS_MAC_STORE
h[4] = 0; // use only first 4 chars
_localServerName = psServerPrefix() + h;
#endif // OS_MAC_STORE
connect(&_localSocket, SIGNAL(connected()), this, SLOT(socketConnected()));
connect(&_localSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
connect(&_localSocket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(socketError(QLocalSocket::LocalSocketError)));
connect(&_localSocket, SIGNAL(bytesWritten(qint64)), this, SLOT(socketWritten(qint64)));
connect(&_localSocket, SIGNAL(readyRead()), this, SLOT(socketReading()));
connect(&_localServer, SIGNAL(newConnection()), this, SLOT(newInstanceConnected()));
QTimer::singleShot(0, this, SLOT(startApplication()));
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication()));
if (cManyInstance()) {
LOG(("Many instance allowed, starting..."));
singleInstanceChecked();
} else {
LOG(("Connecting local socket to %1...").arg(_localServerName));
_localSocket.connectToServer(_localServerName);
}
}
Application::~Application() = default;
bool Application::event(QEvent *e) {
if (e->type() == QEvent::Close) {
App::quit();
}
return QApplication::event(e);
}
void Application::socketConnected() {
LOG(("Socket connected, this is not the first application instance, sending show command..."));
_secondInstance = true;
QString commands;
const QStringList &lst(cSendPaths());
for (QStringList::const_iterator i = lst.cbegin(), e = lst.cend(); i != e; ++i) {
commands += qsl("SEND:") + _escapeTo7bit(*i) + ';';
}
if (!cStartUrl().isEmpty()) {
commands += qsl("OPEN:") + _escapeTo7bit(cStartUrl()) + ';';
} else {
commands += qsl("CMD:show;");
}
DEBUG_LOG(("Application Info: writing commands %1").arg(commands));
_localSocket.write(commands.toLatin1());
}
void Application::socketWritten(qint64/* bytes*/) {
if (_localSocket.state() != QLocalSocket::ConnectedState) {
LOG(("Socket is not connected %1").arg(_localSocket.state()));
return;
}
if (_localSocket.bytesToWrite()) {
return;
}
LOG(("Show command written, waiting response..."));
}
void Application::socketReading() {
if (_localSocket.state() != QLocalSocket::ConnectedState) {
LOG(("Socket is not connected %1").arg(_localSocket.state()));
return;
}
_localSocketReadData.append(_localSocket.readAll());
if (QRegularExpression("RES:(\\d+);").match(_localSocketReadData).hasMatch()) {
uint64 pid = _localSocketReadData.mid(4, _localSocketReadData.length() - 5).toULongLong();
if (pid != kEmptyPidForCommandResponse) {
psActivateProcess(pid);
}
LOG(("Show command response received, pid = %1, activating and quitting...").arg(pid));
return App::quit();
}
}
void Application::socketError(QLocalSocket::LocalSocketError e) {
if (App::quitting()) return;
if (_secondInstance) {
LOG(("Could not write show command, error %1, quitting...").arg(e));
return App::quit();
}
if (e == QLocalSocket::ServerNotFoundError) {
LOG(("This is the only instance of Telegram, starting server and app..."));
} else {
LOG(("Socket connect error %1, starting server and app...").arg(e));
}
_localSocket.close();
// Local server does not work in WinRT build.
#ifndef Q_OS_WINRT
psCheckLocalSocket(_localServerName);
if (!_localServer.listen(_localServerName)) {
LOG(("Failed to start listening to %1 server, error %2").arg(_localServerName).arg(int(_localServer.serverError())));
return App::quit();
}
#endif // !Q_OS_WINRT
if (!Core::UpdaterDisabled()
&& !cNoStartUpdate()
&& Core::checkReadyUpdate()) {
cSetRestartingUpdate(true);
DEBUG_LOG(("Application Info: installing update instead of starting app..."));
return App::quit();
}
singleInstanceChecked();
}
void Application::singleInstanceChecked() {
if (cManyInstance()) {
Logs::multipleInstances();
}
Sandbox::start();
refreshGlobalProxy();
if (!Logs::started() || (!cManyInstance() && !Logs::instanceChecked())) {
new NotStartedWindow();
} else {
const auto status = CrashReports::Start();
if (status == CrashReports::CantOpen) {
new NotStartedWindow();
} else if (status == CrashReports::LastCrashed) {
if (Sandbox::LastCrashDump().isEmpty()) { // don't handle bad closing for now
if (CrashReports::Restart() == CrashReports::CantOpen) {
new NotStartedWindow();
} else {
Sandbox::launch();
}
} else {
new LastCrashedWindow();
}
} else {
Sandbox::launch();
}
}
}
void Application::socketDisconnected() {
if (_secondInstance) {
DEBUG_LOG(("Application Error: socket disconnected before command response received, quitting..."));
return App::quit();
}
}
void Application::newInstanceConnected() {
DEBUG_LOG(("Application Info: new local socket connected"));
for (QLocalSocket *client = _localServer.nextPendingConnection(); client; client = _localServer.nextPendingConnection()) {
_localClients.push_back(LocalClient(client, QByteArray()));
connect(client, SIGNAL(readyRead()), this, SLOT(readClients()));
connect(client, SIGNAL(disconnected()), this, SLOT(removeClients()));
}
}
void Application::readClients() {
// This method can be called before Messenger is constructed.
QString startUrl;
QStringList toSend;
for (LocalClients::iterator i = _localClients.begin(), e = _localClients.end(); i != e; ++i) {
i->second.append(i->first->readAll());
if (i->second.size()) {
QString cmds(QString::fromLatin1(i->second));
int32 from = 0, l = cmds.length();
for (int32 to = cmds.indexOf(QChar(';'), from); to >= from; to = (from < l) ? cmds.indexOf(QChar(';'), from) : -1) {
QStringRef cmd(&cmds, from, to - from);
if (cmd.startsWith(qsl("CMD:"))) {
Sandbox::execExternal(cmds.mid(from + 4, to - from - 4));
const auto response = qsl("RES:%1;").arg(QCoreApplication::applicationPid()).toLatin1();
i->first->write(response.data(), response.size());
} else if (cmd.startsWith(qsl("SEND:"))) {
if (cSendPaths().isEmpty()) {
toSend.append(_escapeFrom7bit(cmds.mid(from + 5, to - from - 5)));
}
} else if (cmd.startsWith(qsl("OPEN:"))) {
auto activateRequired = true;
if (cStartUrl().isEmpty()) {
startUrl = _escapeFrom7bit(cmds.mid(from + 5, to - from - 5)).mid(0, 8192);
activateRequired = StartUrlRequiresActivate(startUrl);
}
if (activateRequired) {
Sandbox::execExternal("show");
}
const auto responsePid = activateRequired
? QCoreApplication::applicationPid()
: kEmptyPidForCommandResponse;
const auto response = qsl("RES:%1;").arg(responsePid).toLatin1();
i->first->write(response.data(), response.size());
} else {
LOG(("Application Error: unknown command %1 passed in local socket").arg(QString(cmd.constData(), cmd.length())));
}
from = to + 1;
}
if (from > 0) {
i->second = i->second.mid(from);
}
}
}
if (!toSend.isEmpty()) {
QStringList paths(cSendPaths());
paths.append(toSend);
cSetSendPaths(paths);
}
if (!cSendPaths().isEmpty()) {
if (App::wnd()) {
App::wnd()->sendPaths();
}
}
if (!startUrl.isEmpty()) {
cSetStartUrl(startUrl);
}
if (auto messenger = Messenger::InstancePointer()) {
messenger->checkStartUrl();
}
}
void Application::removeClients() {
DEBUG_LOG(("Application Info: remove clients slot called, clients %1").arg(_localClients.size()));
for (LocalClients::iterator i = _localClients.begin(), e = _localClients.end(); i != e;) {
if (i->first->state() != QLocalSocket::ConnectedState) {
DEBUG_LOG(("Application Info: removing client"));
i = _localClients.erase(i);
e = _localClients.end();
} else {
++i;
}
}
}
void Application::startApplication() {
if (App::quitting()) {
quit();
}
}
void Application::createMessenger() {
Expects(!App::quitting());
_messengerInstance = std::make_unique<Messenger>(_launcher);
}
void Application::refreshGlobalProxy() {
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
const auto proxy = [&] {
if (Global::started()) {
return Global::UseProxy()
? Global::SelectedProxy()
: ProxyData();
}
return Sandbox::PreLaunchProxy();
}();
if (proxy.type == ProxyData::Type::Socks5
|| proxy.type == ProxyData::Type::Http) {
QNetworkProxy::setApplicationProxy(
ToNetworkProxy(ToDirectIpProxy(proxy)));
} else {
QNetworkProxyFactory::setUseSystemConfiguration(true);
}
#endif // TDESKTOP_DISABLE_NETWORK_PROXY
}
void Application::closeApplication() {
if (App::launchState() == App::QuitProcessed) return;
App::setLaunchState(App::QuitProcessed);
_messengerInstance.reset();
Sandbox::finish();
_localServer.close();
for (LocalClients::iterator i = _localClients.begin(), e = _localClients.end(); i != e; ++i) {
disconnect(i->first, SIGNAL(disconnected()), this, SLOT(removeClients()));
i->first->close();
}
_localClients.clear();
_localSocket.close();
_updateChecker = nullptr;
}
inline Application *application() {
return qobject_cast<Application*>(QApplication::instance());
}
namespace Sandbox {
QRect availableGeometry() {
if (auto a = application()) {
return a->desktop()->availableGeometry();
}
return QDesktopWidget().availableGeometry();
}
QRect screenGeometry(const QPoint &p) {
if (auto a = application()) {
return a->desktop()->screenGeometry(p);
}
return QDesktopWidget().screenGeometry(p);
}
void setActiveWindow(QWidget *window) {
if (auto a = application()) {
a->setActiveWindow(window);
}
}
bool isSavingSession() {
if (auto a = application()) {
return a->isSavingSession();
}
return false;
}
void execExternal(const QString &cmd) {
DEBUG_LOG(("Application Info: executing external command '%1'").arg(cmd));
if (cmd == "show") {
if (App::wnd()) {
App::wnd()->activate();
} else if (PreLaunchWindow::instance()) {
PreLaunchWindow::instance()->activate();
}
}
}
void adjustSingleTimers() {
if (auto a = application()) {
a->adjustSingleTimers();
}
base::Timer::Adjust();
base::ConcurrentTimerEnvironment::Adjust();
}
void connect(const char *signal, QObject *object, const char *method) {
if (auto a = application()) {
a->connect(a, signal, object, method);
}
}
void launch() {
Assert(application() != 0);
const auto dpi = Application::primaryScreen()->logicalDotsPerInch();
LOG(("Primary screen DPI: %1").arg(dpi));
if (dpi <= 108) {
cSetScreenScale(100); // 100%: 96 DPI (0-108)
} else if (dpi <= 132) {
cSetScreenScale(125); // 125%: 120 DPI (108-132)
} else if (dpi <= 168) {
cSetScreenScale(150); // 150%: 144 DPI (132-168)
} else if (dpi <= 216) {
cSetScreenScale(200); // 200%: 192 DPI (168-216)
} else if (dpi <= 264) {
cSetScreenScale(250); // 250%: 240 DPI (216-264)
} else {
cSetScreenScale(300); // 300%: 288 DPI (264-inf)
}
auto devicePixelRatio = application()->devicePixelRatio();
if (devicePixelRatio > 1.) {
if ((cPlatform() != dbipMac && cPlatform() != dbipMacOld) || (devicePixelRatio != 2.)) {
LOG(("Found non-trivial Device Pixel Ratio: %1").arg(devicePixelRatio));
LOG(("Environmental variables: QT_DEVICE_PIXEL_RATIO='%1'").arg(QString::fromLatin1(qgetenv("QT_DEVICE_PIXEL_RATIO"))));
LOG(("Environmental variables: QT_SCALE_FACTOR='%1'").arg(QString::fromLatin1(qgetenv("QT_SCALE_FACTOR"))));
LOG(("Environmental variables: QT_AUTO_SCREEN_SCALE_FACTOR='%1'").arg(QString::fromLatin1(qgetenv("QT_AUTO_SCREEN_SCALE_FACTOR"))));
LOG(("Environmental variables: QT_SCREEN_SCALE_FACTORS='%1'").arg(QString::fromLatin1(qgetenv("QT_SCREEN_SCALE_FACTORS"))));
}
cSetRetinaFactor(devicePixelRatio);
cSetIntRetinaFactor(int32(cRetinaFactor()));
cSetScreenScale(kInterfaceScaleDefault);
}
application()->createMessenger();
}
void refreshGlobalProxy() {
if (const auto instance = application()) {
instance->refreshGlobalProxy();
}
}
} // namespace Sandbox

View File

@@ -1,86 +0,0 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Core {
class Launcher;
class UpdateChecker;
} // namespace Core
bool InternalPassportLink(const QString &url);
bool StartUrlRequiresActivate(const QString &url);
class Application : public QApplication {
Q_OBJECT
public:
Application(not_null<Core::Launcher*> launcher, int &argc, char **argv);
bool event(QEvent *e) override;
void createMessenger();
void refreshGlobalProxy();
~Application();
signals:
void adjustSingleTimers();
// Single instance application
public slots:
void socketConnected();
void socketError(QLocalSocket::LocalSocketError e);
void socketDisconnected();
void socketWritten(qint64 bytes);
void socketReading();
void newInstanceConnected();
void readClients();
void removeClients();
void startApplication(); // will be done in exec()
void closeApplication(); // will be done in aboutToQuit()
private:
typedef QPair<QLocalSocket*, QByteArray> LocalClient;
typedef QList<LocalClient> LocalClients;
not_null<Core::Launcher*> _launcher;
std::unique_ptr<Messenger> _messengerInstance;
QString _localServerName, _localSocketReadData;
QLocalServer _localServer;
QLocalSocket _localSocket;
LocalClients _localClients;
bool _secondInstance = false;
void singleInstanceChecked();
private:
std::unique_ptr<Core::UpdateChecker> _updateChecker;
};
namespace Sandbox {
QRect availableGeometry();
QRect screenGeometry(const QPoint &p);
void setActiveWindow(QWidget *window);
bool isSavingSession();
void execExternal(const QString &cmd);
void adjustSingleTimers();
void refreshGlobalProxy();
void connect(const char *signal, QObject *object, const char *method);
void launch();
} // namespace Sandbox

View File

@@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "auth_session.h"
#include "apiwrap.h"
#include "messenger.h"
#include "core/application.h"
#include "core/changelogs.h"
#include "storage/file_download.h"
#include "storage/file_upload.h"
@@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_facade.h"
#include "storage/serialize_common.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "window/notifications_manager.h"
#include "window/themes/window_theme.h"
#include "platform/platform_specific.h"
@@ -25,12 +26,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/send_files_box.h"
#include "ui/widgets/input_fields.h"
#include "support/support_common.h"
#include "support/support_templates.h"
#include "support/support_helper.h"
#include "observer_peer.h"
namespace {
constexpr auto kAutoLockTimeoutLateMs = TimeMs(3000);
constexpr auto kAutoLockTimeoutLateMs = crl::time(3000);
constexpr auto kLegacyCallsPeerToPeerNobody = 4;
} // namespace
@@ -44,11 +46,13 @@ AuthSessionSettings::Variables::Variables()
}
QByteArray AuthSessionSettings::serialize() const {
auto size = sizeof(qint32) * 10;
const auto autoDownload = _variables.autoDownload.serialize();
auto size = sizeof(qint32) * 23;
for (auto i = _variables.soundOverrides.cbegin(), e = _variables.soundOverrides.cend(); i != e; ++i) {
size += Serialize::stringSize(i.key()) + Serialize::stringSize(i.value());
}
size += _variables.groupStickersSectionHidden.size() * sizeof(quint64);
size += Serialize::bytearraySize(autoDownload);
auto result = QByteArray();
result.reserve(size);
@@ -78,11 +82,17 @@ QByteArray AuthSessionSettings::serialize() const {
stream << qint32(_variables.thirdColumnWidth.current());
stream << qint32(_variables.thirdSectionExtendedBy);
stream << qint32(_variables.sendFilesWay);
stream << qint32(_variables.callsPeerToPeer.current());
stream << qint32(0);// LEGACY _variables.callsPeerToPeer.current());
stream << qint32(_variables.sendSubmitWay);
stream << qint32(_variables.supportSwitch);
stream << qint32(_variables.supportFixChatsOrder ? 1 : 0);
stream << qint32(_variables.supportTemplatesAutocomplete ? 1 : 0);
stream << qint32(_variables.supportChatsTimeSlice.current());
stream << qint32(_variables.includeMutedCounter ? 1 : 0);
stream << qint32(_variables.countUnreadMessages ? 1 : 0);
stream << qint32(_variables.exeLaunchWarning ? 1 : 0);
stream << autoDownload;
stream << qint32(_variables.supportAllSearchResults.current() ? 1 : 0);
}
return result;
}
@@ -108,11 +118,17 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
int thirdColumnWidth = _variables.thirdColumnWidth.current();
int thirdSectionExtendedBy = _variables.thirdSectionExtendedBy;
qint32 sendFilesWay = static_cast<qint32>(_variables.sendFilesWay);
qint32 callsPeerToPeer = qint32(_variables.callsPeerToPeer.current());
qint32 legacyCallsPeerToPeer = qint32(0);
qint32 sendSubmitWay = static_cast<qint32>(_variables.sendSubmitWay);
qint32 supportSwitch = static_cast<qint32>(_variables.supportSwitch);
qint32 supportFixChatsOrder = _variables.supportFixChatsOrder ? 1 : 0;
qint32 supportTemplatesAutocomplete = _variables.supportTemplatesAutocomplete ? 1 : 0;
qint32 supportChatsTimeSlice = _variables.supportChatsTimeSlice.current();
qint32 includeMutedCounter = _variables.includeMutedCounter ? 1 : 0;
qint32 countUnreadMessages = _variables.countUnreadMessages ? 1 : 0;
qint32 exeLaunchWarning = _variables.exeLaunchWarning ? 1 : 0;
QByteArray autoDownload;
qint32 supportAllSearchResults = _variables.supportAllSearchResults.current() ? 1 : 0;
stream >> selectorTab;
stream >> lastSeenWarningSeen;
@@ -166,7 +182,7 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
stream >> sendFilesWay;
}
if (!stream.atEnd()) {
stream >> callsPeerToPeer;
stream >> legacyCallsPeerToPeer;
}
if (!stream.atEnd()) {
stream >> sendSubmitWay;
@@ -176,11 +192,31 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
if (!stream.atEnd()) {
stream >> supportTemplatesAutocomplete;
}
if (!stream.atEnd()) {
stream >> supportChatsTimeSlice;
}
if (!stream.atEnd()) {
stream >> includeMutedCounter;
stream >> countUnreadMessages;
}
if (!stream.atEnd()) {
stream >> exeLaunchWarning;
}
if (!stream.atEnd()) {
stream >> autoDownload;
}
if (!stream.atEnd()) {
stream >> supportAllSearchResults;
}
if (stream.status() != QDataStream::Ok) {
LOG(("App Error: "
"Bad data for AuthSessionSettings::constructFromSerialized()"));
return;
}
if (!autoDownload.isEmpty()
&& !_variables.autoDownload.setFromSerialized(autoDownload)) {
return;
}
auto uncheckedTab = static_cast<ChatHelpers::SelectorTab>(selectorTab);
switch (uncheckedTab) {
@@ -220,14 +256,6 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
case SendFilesWay::Photos:
case SendFilesWay::Files: _variables.sendFilesWay = uncheckedSendFilesWay; break;
}
auto uncheckedCallsPeerToPeer = static_cast<Calls::PeerToPeer>(callsPeerToPeer);
switch (uncheckedCallsPeerToPeer) {
case Calls::PeerToPeer::DefaultContacts:
case Calls::PeerToPeer::DefaultEveryone:
case Calls::PeerToPeer::Everyone:
case Calls::PeerToPeer::Contacts:
case Calls::PeerToPeer::Nobody: _variables.callsPeerToPeer = uncheckedCallsPeerToPeer; break;
}
auto uncheckedSendSubmitWay = static_cast<Ui::InputSubmitSettings>(
sendSubmitWay);
switch (uncheckedSendSubmitWay) {
@@ -243,6 +271,36 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
}
_variables.supportFixChatsOrder = (supportFixChatsOrder == 1);
_variables.supportTemplatesAutocomplete = (supportTemplatesAutocomplete == 1);
_variables.supportChatsTimeSlice = supportChatsTimeSlice;
_variables.hadLegacyCallsPeerToPeerNobody = (legacyCallsPeerToPeer == kLegacyCallsPeerToPeerNobody);
_variables.includeMutedCounter = (includeMutedCounter == 1);
_variables.countUnreadMessages = (countUnreadMessages == 1);
_variables.exeLaunchWarning = (exeLaunchWarning == 1);
_variables.supportAllSearchResults = (supportAllSearchResults == 1);
}
void AuthSessionSettings::setSupportChatsTimeSlice(int slice) {
_variables.supportChatsTimeSlice = slice;
}
int AuthSessionSettings::supportChatsTimeSlice() const {
return _variables.supportChatsTimeSlice.current();
}
rpl::producer<int> AuthSessionSettings::supportChatsTimeSliceValue() const {
return _variables.supportChatsTimeSlice.value();
}
void AuthSessionSettings::setSupportAllSearchResults(bool all) {
_variables.supportAllSearchResults = all;
}
bool AuthSessionSettings::supportAllSearchResults() const {
return _variables.supportAllSearchResults.current();
}
rpl::producer<bool> AuthSessionSettings::supportAllSearchResultsValue() const {
return _variables.supportAllSearchResults.value();
}
void AuthSessionSettings::setTabbedSelectorSectionEnabled(bool enabled) {
@@ -314,14 +372,13 @@ rpl::producer<int> AuthSessionSettings::thirdColumnWidthChanges() const {
}
AuthSession &Auth() {
auto result = Messenger::Instance().authSession();
auto result = Core::App().authSession();
Assert(result != nullptr);
return *result;
}
AuthSession::AuthSession(const MTPUser &user)
: _user(App::user(user.match([](const auto &data) { return data.vid.v; })))
, _autoLockTimer([this] { checkAutoLock(); })
: _autoLockTimer([this] { checkAutoLock(); })
, _api(std::make_unique<ApiWrap>(this))
, _calls(std::make_unique<Calls::Instance>())
, _downloader(std::make_unique<Storage::Downloader>())
@@ -329,21 +386,17 @@ AuthSession::AuthSession(const MTPUser &user)
, _storage(std::make_unique<Storage::Facade>())
, _notifications(std::make_unique<Window::Notifications::System>(this))
, _data(std::make_unique<Data::Session>(this))
, _user(_data->processUser(user))
, _changelogs(Core::Changelogs::Create(this))
, _supportTemplates(
(Support::ValidateAccount(user)
? std::make_unique<Support::Templates>(this)
: nullptr)) {
App::feedUser(user);
, _supportHelper(Support::Helper::Create(this)) {
_saveDataTimer.setCallback([=] {
Local::writeUserSettings();
});
Messenger::Instance().passcodeLockChanges(
Core::App().passcodeLockChanges(
) | rpl::start_with_next([=] {
_shouldLockAt = 0;
}, _lifetime);
Messenger::Instance().lockChanges(
Core::App().lockChanges(
) | rpl::start_with_next([=] {
notifications().updateAll();
}, _lifetime);
@@ -376,55 +429,80 @@ AuthSession::AuthSession(const MTPUser &user)
}
bool AuthSession::Exists() {
if (const auto messenger = Messenger::InstancePointer()) {
return (messenger->authSession() != nullptr);
}
return false;
return Core::IsAppLaunched() && (Core::App().authSession() != nullptr);
}
base::Observable<void> &AuthSession::downloaderTaskFinished() {
return downloader().taskFinished();
}
UserId AuthSession::userId() const {
return _user->bareId();
}
PeerId AuthSession::userPeerId() const {
return _user->id;
}
bool AuthSession::validateSelf(const MTPUser &user) {
if (user.type() != mtpc_user || !user.c_user().is_self()) {
LOG(("API Error: bad self user received."));
return false;
} else if (user.c_user().vid.v != userId()) {
LOG(("Auth Error: wrong self user received."));
crl::on_main(this, [] { Messenger::Instance().logOut(); });
crl::on_main(this, [] { Core::App().logOut(); });
return false;
}
return true;
}
void AuthSession::saveSettingsDelayed(TimeMs delay) {
void AuthSession::moveSettingsFrom(AuthSessionSettings &&other) {
_settings.moveFrom(std::move(other));
if (_settings.hadLegacyCallsPeerToPeerNobody()) {
api().savePrivacy(
MTP_inputPrivacyKeyPhoneP2P(),
QVector<MTPInputPrivacyRule>(
1,
MTP_inputPrivacyValueDisallowAll()));
saveSettingsDelayed();
}
}
void AuthSession::saveSettingsDelayed(crl::time delay) {
Expects(this == &Auth());
_saveDataTimer.callOnce(delay);
}
void AuthSession::localPasscodeChanged() {
_shouldLockAt = 0;
_autoLockTimer.cancel();
checkAutoLock();
}
void AuthSession::checkAutoLock() {
if (!Global::LocalPasscode()
|| Messenger::Instance().passcodeLocked()) {
|| Core::App().passcodeLocked()) {
_shouldLockAt = 0;
_autoLockTimer.cancel();
return;
}
Messenger::Instance().checkLocalTime();
auto now = getms(true);
auto shouldLockInMs = Global::AutoLock() * 1000LL;
auto idleForMs = psIdleTime();
auto notPlayingVideoForMs = now - settings().lastTimeVideoPlayedAt();
auto checkTimeMs = qMin(idleForMs, notPlayingVideoForMs);
Core::App().checkLocalTime();
const auto now = crl::now();
const auto shouldLockInMs = Global::AutoLock() * 1000LL;
const auto checkTimeMs = now - Core::App().lastNonIdleTime();
if (checkTimeMs >= shouldLockInMs || (_shouldLockAt > 0 && now > _shouldLockAt + kAutoLockTimeoutLateMs)) {
Messenger::Instance().lockByPasscode();
_shouldLockAt = 0;
_autoLockTimer.cancel();
Core::App().lockByPasscode();
} else {
_shouldLockAt = now + (shouldLockInMs - checkTimeMs);
_autoLockTimer.callOnce(shouldLockInMs - checkTimeMs);
}
}
void AuthSession::checkAutoLockIn(TimeMs time) {
void AuthSession::checkAutoLockIn(crl::time time) {
if (_autoLockTimer.isActive()) {
auto remain = _autoLockTimer.remainingTime();
if (remain > 0 && remain <= time) return;
@@ -433,13 +511,20 @@ void AuthSession::checkAutoLockIn(TimeMs time) {
}
bool AuthSession::supportMode() const {
return (_supportTemplates != nullptr);
return (_supportHelper != nullptr);
}
not_null<Support::Templates*> AuthSession::supportTemplates() const {
Support::Helper &AuthSession::supportHelper() const {
Expects(supportMode());
return _supportTemplates.get();
return *_supportHelper;
}
AuthSession::~AuthSession() = default;
Support::Templates& AuthSession::supportTemplates() const {
return supportHelper().templates();
}
AuthSession::~AuthSession() {
ClickHandler::clearActive();
ClickHandler::unpressed();
}

View File

@@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <rpl/filter.h>
#include <rpl/variable.h>
#include "base/timer.h"
#include "data/data_auto_download.h"
class ApiWrap;
enum class SendFilesWay;
@@ -21,6 +22,7 @@ enum class InputSubmitSettings;
namespace Support {
enum class SwitchSettings;
class Helper;
class Templates;
} // namespace Support
@@ -28,10 +30,6 @@ namespace Data {
class Session;
} // namespace Data
namespace Calls {
enum class PeerToPeer;
} // namespace Calls
namespace Storage {
class Downloader;
class Uploader;
@@ -102,6 +100,12 @@ public:
bool supportTemplatesAutocomplete() const {
return _variables.supportTemplatesAutocomplete;
}
void setSupportChatsTimeSlice(int slice);
int supportChatsTimeSlice() const;
rpl::producer<int> supportChatsTimeSliceValue() const;
void setSupportAllSearchResults(bool all);
bool supportAllSearchResults() const;
rpl::producer<bool> supportAllSearchResultsValue() const;
ChatHelpers::SelectorTab selectorTab() const {
return _variables.selectorTab;
@@ -135,12 +139,6 @@ public:
bool smallDialogsList() const {
return _variables.smallDialogsList;
}
void setLastTimeVideoPlayedAt(TimeMs time) {
_lastTimeVideoPlayedAt = time;
}
TimeMs lastTimeVideoPlayedAt() const {
return _lastTimeVideoPlayedAt;
}
void setSoundOverride(const QString &key, const QString &path) {
_variables.soundOverrides.insert(key, path);
}
@@ -183,14 +181,34 @@ public:
_variables.groupStickersSectionHidden.remove(peerId);
}
rpl::producer<Calls::PeerToPeer> callsPeerToPeerValue() const {
return _variables.callsPeerToPeer.value();
Data::AutoDownload::Full &autoDownload() {
return _variables.autoDownload;
}
Calls::PeerToPeer callsPeerToPeer() const {
return _variables.callsPeerToPeer.current();
const Data::AutoDownload::Full &autoDownload() const {
return _variables.autoDownload;
}
void setCallsPeerToPeer(Calls::PeerToPeer value) {
_variables.callsPeerToPeer = value;
bool hadLegacyCallsPeerToPeerNobody() const {
return _variables.hadLegacyCallsPeerToPeerNobody;
}
bool includeMutedCounter() const {
return _variables.includeMutedCounter;
}
void setIncludeMutedCounter(bool value) {
_variables.includeMutedCounter = value;
}
bool countUnreadMessages() const {
return _variables.countUnreadMessages;
}
void setCountUnreadMessages(bool value) {
_variables.countUnreadMessages = value;
}
bool exeLaunchWarning() const {
return _variables.exeLaunchWarning;
}
void setExeLaunchWarning(bool warning) {
_variables.exeLaunchWarning = warning;
}
private:
@@ -216,13 +234,22 @@ private:
= kDefaultDialogsWidthRatio; // per-window
rpl::variable<int> thirdColumnWidth
= kDefaultThirdColumnWidth; // per-window
rpl::variable<Calls::PeerToPeer> callsPeerToPeer
= Calls::PeerToPeer();
Ui::InputSubmitSettings sendSubmitWay;
bool hadLegacyCallsPeerToPeerNobody = false;
bool includeMutedCounter = true;
bool countUnreadMessages = true;
bool exeLaunchWarning = true;
Data::AutoDownload::Full autoDownload;
static constexpr auto kDefaultSupportChatsLimitSlice
= 7 * 24 * 60 * 60;
Support::SwitchSettings supportSwitch;
bool supportFixChatsOrder = true;
bool supportTemplatesAutocomplete = true;
rpl::variable<int> supportChatsTimeSlice
= kDefaultSupportChatsLimitSlice;
rpl::variable<bool> supportAllSearchResults = false;
};
rpl::event_stream<bool> _thirdSectionInfoEnabledValue;
@@ -230,11 +257,9 @@ private:
rpl::event_stream<bool> _tabbedReplacedWithInfoValue;
Variables _variables;
TimeMs _lastTimeVideoPlayedAt = 0;
};
// One per Messenger.
class AuthSession;
AuthSession &Auth();
@@ -249,12 +274,8 @@ public:
static bool Exists();
UserId userId() const {
return _user->bareId();
}
PeerId userPeerId() const {
return _user->id;
}
UserId userId() const;
PeerId userPeerId() const;
not_null<UserData*> user() const {
return _user;
}
@@ -282,7 +303,8 @@ public:
AuthSessionSettings &settings() {
return _settings;
}
void saveSettingsDelayed(TimeMs delay = kDefaultSaveDelay);
void moveSettingsFrom(AuthSessionSettings &&other);
void saveSettingsDelayed(crl::time delay = kDefaultSaveDelay);
ApiWrap &api() {
return *_api;
@@ -293,7 +315,8 @@ public:
}
void checkAutoLock();
void checkAutoLockIn(TimeMs time);
void checkAutoLockIn(crl::time time);
void localPasscodeChanged();
rpl::lifetime &lifetime() {
return _lifetime;
@@ -303,18 +326,18 @@ public:
base::Observable<std::pair<not_null<HistoryItem*>, MsgId>> messageIdChanging;
bool supportMode() const;
not_null<Support::Templates*> supportTemplates() const;
Support::Helper &supportHelper() const;
Support::Templates &supportTemplates() const;
~AuthSession();
private:
static constexpr auto kDefaultSaveDelay = TimeMs(1000);
static constexpr auto kDefaultSaveDelay = crl::time(1000);
const not_null<UserData*> _user;
AuthSessionSettings _settings;
base::Timer _saveDataTimer;
TimeMs _shouldLockAt = 0;
crl::time _shouldLockAt = 0;
base::Timer _autoLockTimer;
const std::unique_ptr<ApiWrap> _api;
@@ -324,13 +347,14 @@ private:
const std::unique_ptr<Storage::Facade> _storage;
const std::unique_ptr<Window::Notifications::System> _notifications;
// _data depends on _downloader / _uploader, including destructor.
// _data depends on _downloader / _uploader / _notifications.
const std::unique_ptr<Data::Session> _data;
const not_null<UserData*> _user;
// _changelogs depends on _data, subscribes on chats loading event.
const std::unique_ptr<Core::Changelogs> _changelogs;
const std::unique_ptr<Support::Templates> _supportTemplates;
const std::unique_ptr<Support::Helper> _supportHelper;
rpl::lifetime _lifetime;

View File

@@ -24,6 +24,12 @@ inline constexpr size_t array_size(const Type(&)[Size]) {
return Size;
}
template <typename Container, typename T>
inline bool contains(const Container &container, const T &value) {
const auto end = std::end(container);
return std::find(std::begin(container), end, value) != end;
}
} // namespace base
template <typename T>

View File

@@ -19,7 +19,10 @@ void log(const char *message, const char *file, int line);
inline constexpr void noop() {
}
[[noreturn]] inline void fail(const char *message, const char *file, int line) {
[[noreturn]] inline void fail(
const char *message,
const char *file,
int line) {
log(message, file, line);
// Crash with access violation and generate crash report.
@@ -30,24 +33,36 @@ inline constexpr void noop() {
std::abort();
}
#ifndef GSL_UNLIKELY
#define DEFINED_GSL_UNLIKELY_
#define GSL_UNLIKELY(expression) (expression)
#endif // GSL_UNLIKELY
inline constexpr void validate(bool condition, const char *message, const char *file, int line) {
(GSL_UNLIKELY(!(condition))) ? fail(message, file, line) : noop();
constexpr const char* extract_basename(const char* path, size_t size) {
while (size != 0 && path[size - 1] != '/' && path[size - 1] != '\\') {
--size;
}
return path + size;
}
#ifdef DEFINED_GSL_UNLIKELY_
#undef GSL_UNLIKELY
#undef DEFINED_GSL_UNLIKELY_
#endif // DEFINED_GSL_UNLIKELY_
} // namespace assertion
} // namespace base
#define AssertCustom(condition, message) (::base::assertion::validate(condition, message, __FILE__, __LINE__))
#if defined(__clang__) || defined(__GNUC__)
#define AssertUnlikelyHelper(x) __builtin_expect(!!(x), 0)
#else
#define AssertUnlikelyHelper(x) (!!(x))
#endif
#define AssertValidationCondition(condition, message, file, line)\
((AssertUnlikelyHelper(!(condition)))\
? ::base::assertion::fail(message, file, line)\
: ::base::assertion::noop())
#define SOURCE_FILE_BASENAME (::base::assertion::extract_basename(\
__FILE__,\
sizeof(__FILE__)))
#define AssertCustom(condition, message) (AssertValidationCondition(\
condition,\
message,\
SOURCE_FILE_BASENAME,\
__LINE__))
#define Assert(condition) AssertCustom(condition, "\"" #condition "\"")
// Define our own versions of Expects() and Ensures().
@@ -55,17 +70,28 @@ inline constexpr void validate(bool condition, const char *message, const char *
#ifdef Expects
#undef Expects
#endif // Expects
#define Expects(condition) (::base::assertion::validate(condition, "\"" #condition "\"", __FILE__, __LINE__))
#define Expects(condition) (AssertValidationCondition(\
condition,\
"\"" #condition "\"",\
SOURCE_FILE_BASENAME,\
__LINE__))
#ifdef Ensures
#undef Ensures
#endif // Ensures
#define Ensures(condition) (::base::assertion::validate(condition, "\"" #condition "\"", __FILE__, __LINE__))
#define Ensures(condition) (AssertValidationCondition(\
condition,\
"\"" #condition "\"",\
SOURCE_FILE_BASENAME,\
__LINE__))
#ifdef Unexpected
#undef Unexpected
#endif // Unexpected
#define Unexpected(message) (::base::assertion::fail("Unexpected: " message, __FILE__, __LINE__))
#define Unexpected(message) (::base::assertion::fail(\
"Unexpected: " message,\
SOURCE_FILE_BASENAME,\
__LINE__))
#ifdef _DEBUG
#define AssertIsDebug(...)

View File

@@ -22,9 +22,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <set>
#include <range/v3/all.hpp>
#ifdef Q_OS_WIN
#include "platform/win/windows_range_v3_helpers.h"
#endif // Q_OS_WIN
#include "base/flat_map.h"
#include "base/flat_set.h"

View File

@@ -46,7 +46,6 @@ using uint64 = quint64;
using float32 = float;
using float64 = double;
using TimeMs = int64;
using TimeId = int32;
// Define specializations for QByteArray for Qt 5.3.2, because

View File

@@ -21,7 +21,9 @@ public:
~binary_guard();
bool alive() const;
void kill();
binary_guard &operator=(std::nullptr_t);
explicit operator bool() const;
private:
void destroy();
@@ -44,15 +46,20 @@ inline binary_guard &binary_guard::operator=(binary_guard &&other) {
return *this;
}
inline binary_guard::~binary_guard() {
inline binary_guard &binary_guard::operator=(std::nullptr_t) {
destroy();
return *this;
}
inline binary_guard::operator bool() const {
return alive();
}
inline bool binary_guard::alive() const {
return _bothAlive && _bothAlive->load();
}
inline void binary_guard::kill() {
inline binary_guard::~binary_guard() {
destroy();
}
@@ -74,3 +81,21 @@ inline std::pair<binary_guard, binary_guard> make_binary_guard() {
}
} // namespace base
namespace crl {
template <typename T, typename Enable>
struct guard_traits;
template <>
struct guard_traits<base::binary_guard, void> {
static base::binary_guard create(base::binary_guard value) {
return value;
}
static bool check(const base::binary_guard &guard) {
return guard.alive();
}
};
} // namespace crl

View File

@@ -26,16 +26,16 @@ QMutex EnvironmentMutex;
class CallDelayedEvent : public QEvent {
public:
CallDelayedEvent(
crl::time_type timeout,
crl::time timeout,
Qt::TimerType type,
FnMut<void()> method);
crl::time_type timeout() const;
crl::time timeout() const;
Qt::TimerType type() const;
FnMut<void()> takeMethod();
private:
crl::time_type _timeout = 0;
crl::time _timeout = 0;
Qt::TimerType _type = Qt::PreciseTimer;
FnMut<void()> _method;
@@ -48,7 +48,7 @@ public:
};
CallDelayedEvent::CallDelayedEvent(
crl::time_type timeout,
crl::time timeout,
Qt::TimerType type,
FnMut<void()> method)
: QEvent(kCallDelayedEvent)
@@ -58,7 +58,7 @@ CallDelayedEvent::CallDelayedEvent(
Expects(_timeout >= 0 && _timeout < std::numeric_limits<int>::max());
}
crl::time_type CallDelayedEvent::timeout() const {
crl::time CallDelayedEvent::timeout() const {
return _timeout;
}
@@ -178,7 +178,7 @@ TimerObjectWrap::~TimerObjectWrap() {
}
void TimerObjectWrap::call(
crl::time_type timeout,
crl::time timeout,
Qt::TimerType type,
FnMut<void()> method) {
sendEvent(std::make_unique<CallDelayedEvent>(
@@ -281,7 +281,7 @@ Fn<void()> ConcurrentTimer::createAdjuster() {
}
void ConcurrentTimer::start(
TimeMs timeout,
crl::time timeout,
Qt::TimerType type,
Repeat repeat) {
_type = type;
@@ -290,7 +290,7 @@ void ConcurrentTimer::start(
setTimeout(timeout);
cancelAndSchedule(_timeout);
_next = crl::time() + _timeout;
_next = crl::now() + _timeout;
}
void ConcurrentTimer::cancelAndSchedule(int timeout) {
@@ -301,11 +301,11 @@ void ConcurrentTimer::cancelAndSchedule(int timeout) {
runner = _runner,
guard = std::move(guards.second)
]() mutable {
if (!guard.alive()) {
if (!guard) {
return;
}
runner([=, guard = std::move(guard)] {
if (!guard.alive()) {
if (!guard) {
return;
}
timerEvent();
@@ -319,7 +319,7 @@ void ConcurrentTimer::timerEvent() {
if (_adjusted) {
start(_timeout, _type, repeat());
} else {
_next = crl::time() + _timeout;
_next = crl::now() + _timeout;
}
} else {
cancel();
@@ -338,12 +338,12 @@ void ConcurrentTimer::cancel() {
}
}
TimeMs ConcurrentTimer::remainingTime() const {
crl::time ConcurrentTimer::remainingTime() const {
if (!isActive()) {
return -1;
}
const auto now = crl::time();
return (_next > now) ? (_next - now) : TimeMs(0);
const auto now = crl::now();
return (_next > now) ? (_next - now) : crl::time(0);
}
void ConcurrentTimer::adjust() {
@@ -354,7 +354,7 @@ void ConcurrentTimer::adjust() {
}
}
void ConcurrentTimer::setTimeout(TimeMs timeout) {
void ConcurrentTimer::setTimeout(crl::time timeout) {
Expects(timeout >= 0 && timeout <= std::numeric_limits<int>::max());
_timeout = static_cast<unsigned int>(timeout);

View File

@@ -23,7 +23,7 @@ public:
~TimerObjectWrap();
void call(
crl::time_type timeout,
crl::time timeout,
Qt::TimerType type,
FnMut<void()> method);
void cancel();
@@ -67,8 +67,8 @@ public:
crl::weak_on_queue<Object> weak,
Fn<void()> callback = nullptr);
static Qt::TimerType DefaultType(TimeMs timeout) {
constexpr auto kThreshold = TimeMs(1000);
static Qt::TimerType DefaultType(crl::time timeout) {
constexpr auto kThreshold = crl::time(1000);
return (timeout > kThreshold) ? Qt::CoarseTimer : Qt::PreciseTimer;
}
@@ -76,19 +76,19 @@ public:
_callback = std::move(callback);
}
void callOnce(TimeMs timeout) {
void callOnce(crl::time timeout) {
callOnce(timeout, DefaultType(timeout));
}
void callEach(TimeMs timeout) {
void callEach(crl::time timeout) {
callEach(timeout, DefaultType(timeout));
}
void callOnce(TimeMs timeout, Qt::TimerType type) {
void callOnce(crl::time timeout, Qt::TimerType type) {
start(timeout, type, Repeat::SingleShot);
}
void callEach(TimeMs timeout, Qt::TimerType type) {
void callEach(crl::time timeout, Qt::TimerType type) {
start(timeout, type, Repeat::Interval);
}
@@ -97,7 +97,7 @@ public:
}
void cancel();
TimeMs remainingTime() const;
crl::time remainingTime() const;
private:
enum class Repeat : unsigned {
@@ -105,12 +105,12 @@ private:
SingleShot = 1,
};
Fn<void()> createAdjuster();
void start(TimeMs timeout, Qt::TimerType type, Repeat repeat);
void start(crl::time timeout, Qt::TimerType type, Repeat repeat);
void adjust();
void cancelAndSchedule(int timeout);
void setTimeout(TimeMs timeout);
void setTimeout(crl::time timeout);
int timeout() const;
void timerEvent();
@@ -127,7 +127,7 @@ private:
details::TimerObjectWrap _object;
Fn<void()> _callback;
base::binary_guard _running;
TimeMs _next = 0;
crl::time _next = 0;
int _timeout = 0;
Qt::TimerType _type : 2;

View File

@@ -76,6 +76,7 @@ struct flat_multi_map_pair_type {
const Key first;
Value second;
};
template <
@@ -316,6 +317,18 @@ public:
}
flat_multi_map &operator=(flat_multi_map &&other) = default;
template <
typename Iterator,
typename = typename std::iterator_traits<Iterator>::iterator_category>
flat_multi_map(Iterator first, Iterator last)
: _data(first, last) {
std::sort(std::begin(impl()), std::end(impl()), compare());
}
flat_multi_map(std::initializer_list<pair_type> iter)
: flat_multi_map(iter.begin(), iter.end()) {
}
size_type size() const {
return impl().size();
}
@@ -614,6 +627,20 @@ public:
using reverse_iterator = typename parent::reverse_iterator;
using const_reverse_iterator = typename parent::const_reverse_iterator;
flat_map() = default;
template <
typename Iterator,
typename = typename std::iterator_traits<Iterator>::iterator_category
>
flat_map(Iterator first, Iterator last) : parent(first, last) {
finalize();
}
flat_map(std::initializer_list<pair_type> iter) : parent(iter.begin(), iter.end()) {
finalize();
}
using parent::parent;
using parent::size;
using parent::empty;
@@ -732,6 +759,74 @@ public:
return std::move(result);
}
private:
void finalize() {
this->impl().erase(
std::unique(
std::begin(this->impl()),
std::end(this->impl()),
[&](auto &&a, auto &&b) {
return !this->compare()(a, b);
}
),
std::end(this->impl()));
}
};
} // namespace base
// Structured bindings support.
namespace std {
template <typename Key, typename Value>
class tuple_size<base::flat_multi_map_pair_type<Key, Value>>
: public integral_constant<size_t, 2> {
};
template <typename Key, typename Value>
class tuple_element<0, base::flat_multi_map_pair_type<Key, Value>> {
public:
using type = const Key;
};
template <typename Key, typename Value>
class tuple_element<1, base::flat_multi_map_pair_type<Key, Value>> {
public:
using type = Value;
};
} // namespace std
// Structured bindings support.
namespace base {
namespace details {
template <std::size_t N, typename Key, typename Value>
using flat_multi_map_pair_element = std::tuple_element_t<
N,
flat_multi_map_pair_type<Key, Value>>;
} // namespace details
template <std::size_t N, typename Key, typename Value>
auto get(base::flat_multi_map_pair_type<Key, Value> &value)
-> details::flat_multi_map_pair_element<N, Key, Value> & {
if constexpr (N == 0) {
return value.first;
} else {
return value.second;
}
}
template <std::size_t N, typename Key, typename Value>
auto get(const base::flat_multi_map_pair_type<Key, Value> &value)
-> const details::flat_multi_map_pair_element<N, Key, Value> & {
if constexpr (N == 0) {
return value.first;
} else {
return value.second;
}
}
} // namespace base

View File

@@ -91,3 +91,31 @@ TEST_CASE("flat_maps custom comparator", "[flat_map]") {
checkSorted();
}
}
TEST_CASE("flat_maps structured bindings", "[flat_map]") {
base::flat_map<int, std::unique_ptr<double>> v;
v.emplace(0, std::make_unique<double>(0.));
v.emplace(1, std::make_unique<double>(1.));
SECTION("structred binded range-based for loop") {
for (const auto &[key, value] : v) {
REQUIRE(key == int(std::round(*value)));
}
}
SECTION("non-const structured binded range-based for loop") {
base::flat_map<int, int> second = {
{ 1, 1 },
{ 2, 2 },
{ 2, 3 },
{ 3, 3 },
};
REQUIRE(second.size() == 3);
//for (auto [a, b] : second) { // #MSVC Bug, reported
// REQUIRE(a == b);
//}
for (const auto [a, b] : second) {
REQUIRE(a == b);
}
}
}

View File

@@ -602,36 +602,38 @@ public:
using parent::contains;
using parent::erase;
iterator insert(const Type &value) {
std::pair<iterator, bool> insert(const Type &value) {
if (this->empty() || this->compare()(value, this->front())) {
this->impl().push_front(value);
return this->begin();
return std::make_pair(this->begin(), true);
} else if (this->compare()(this->back(), value)) {
this->impl().push_back(value);
return (this->end() - 1);
return std::make_pair(this->end() - 1, true);
}
auto where = this->getLowerBound(value);
if (this->compare()(value, *where)) {
return this->impl().insert(where, value);
return std::make_pair(this->impl().insert(where, value), true);
}
return this->end();
return std::make_pair(where, false);
}
iterator insert(Type &&value) {
std::pair<iterator, bool> insert(Type &&value) {
if (this->empty() || this->compare()(value, this->front())) {
this->impl().push_front(std::move(value));
return this->begin();
return std::make_pair(this->begin(), true);
} else if (this->compare()(this->back(), value)) {
this->impl().push_back(std::move(value));
return (this->end() - 1);
return std::make_pair(this->end() - 1, true);
}
auto where = this->getLowerBound(value);
if (this->compare()(value, *where)) {
return this->impl().insert(where, std::move(value));
return std::make_pair(
this->impl().insert(where, std::move(value)),
true);
}
return this->end();
return std::make_pair(where, false);
}
template <typename... Args>
iterator emplace(Args&&... args) {
std::pair<iterator, bool> emplace(Args&&... args) {
return this->insert(Type(std::forward<Args>(args)...));
}

View File

@@ -18,12 +18,20 @@ public:
using value_type = typename Container::value_type;
using difference_type = typename Container::difference_type;
using pointer = typename Container::pointer;
using reference = typename Container::reference;
using pointer = std::conditional_t<
std::is_const_v<Container>,
typename Container::const_pointer,
typename Container::pointer>;
using reference = std::conditional_t<
std::is_const_v<Container>,
typename Container::const_reference,
typename Container::reference>;
using base_type = std::conditional_t<
std::is_const_v<Container>,
typename Container::const_iterator,
typename Container::iterator>;
index_based_iterator(
Container *container,
typename Container::iterator impl)
index_based_iterator(Container *container, base_type impl)
: _container(container)
, _index(impl - _container->begin()) {
}
@@ -99,7 +107,7 @@ public:
return !(*this < other);
}
typename Container::iterator base() const {
base_type base() const {
return _container->begin() + _index;
}

View File

@@ -0,0 +1,69 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <list>
#include <unordered_map>
namespace base {
template <typename Entry>
class last_used_cache {
public:
void up(Entry entry);
void remove(Entry entry);
void clear();
Entry take_lowest();
private:
std::list<Entry> _queue;
std::unordered_map<Entry, typename std::list<Entry>::iterator> _map;
};
template <typename Entry>
void last_used_cache<Entry>::up(Entry entry) {
if (!_queue.empty() && _queue.back() == entry) {
return;
}
const auto i = _map.find(entry);
if (i != end(_map)) {
_queue.splice(end(_queue), _queue, i->second);
} else {
_map.emplace(entry, _queue.insert(end(_queue), entry));
}
}
template <typename Entry>
void last_used_cache<Entry>::remove(Entry entry) {
const auto i = _map.find(entry);
if (i != end(_map)) {
_queue.erase(i->second);
_map.erase(i);
}
}
template <typename Entry>
void last_used_cache<Entry>::clear() {
_queue.clear();
_map.clear();
}
template <typename Entry>
Entry last_used_cache<Entry>::take_lowest() {
if (_queue.empty()) {
return Entry();
}
auto result = std::move(_queue.front());
_queue.erase(begin(_queue));
_map.erase(result);
return result;
}
} // namespace base

View File

@@ -21,6 +21,10 @@ extern "C" {
#include <openssl/evp.h>
} // extern "C"
#ifdef small
#undef small
#endif // small
namespace openssl {
class Context {

View File

@@ -35,9 +35,12 @@ public:
const QRegularExpressionMatch *operator->() const {
return &data_;
}
explicit operator bool() const {
bool valid() const {
return data_.hasMatch();
}
explicit operator bool() const {
return valid();
}
private:
QRegularExpressionMatch data_;

View File

@@ -40,7 +40,7 @@ Timer::Timer(Fn<void()> callback)
Qt::QueuedConnection);
}
void Timer::start(TimeMs timeout, Qt::TimerType type, Repeat repeat) {
void Timer::start(crl::time timeout, Qt::TimerType type, Repeat repeat) {
cancel();
_type = type;
@@ -49,7 +49,7 @@ void Timer::start(TimeMs timeout, Qt::TimerType type, Repeat repeat) {
setTimeout(timeout);
_timerId = startTimer(_timeout, _type);
if (_timerId) {
_next = crl::time() + _timeout;
_next = crl::now() + _timeout;
} else {
_next = 0;
}
@@ -61,12 +61,12 @@ void Timer::cancel() {
}
}
TimeMs Timer::remainingTime() const {
crl::time Timer::remainingTime() const {
if (!isActive()) {
return -1;
}
auto now = crl::time();
return (_next > now) ? (_next - now) : TimeMs(0);
const auto now = crl::now();
return (_next > now) ? (_next - now) : crl::time(0);
}
void Timer::Adjust() {
@@ -87,7 +87,7 @@ void Timer::adjust() {
}
}
void Timer::setTimeout(TimeMs timeout) {
void Timer::setTimeout(crl::time timeout) {
Expects(timeout >= 0 && timeout <= std::numeric_limits<int>::max());
_timeout = static_cast<unsigned int>(timeout);
@@ -102,7 +102,7 @@ void Timer::timerEvent(QTimerEvent *e) {
if (_adjusted) {
start(_timeout, _type, repeat());
} else {
_next = crl::time() + _timeout;
_next = crl::now() + _timeout;
}
} else {
cancel();
@@ -114,7 +114,7 @@ void Timer::timerEvent(QTimerEvent *e) {
}
int DelayedCallTimer::call(
TimeMs timeout,
crl::time timeout,
FnMut<void()> callback,
Qt::TimerType type) {
Expects(timeout >= 0);

View File

@@ -21,8 +21,8 @@ public:
Fn<void()> callback = nullptr);
explicit Timer(Fn<void()> callback = nullptr);
static Qt::TimerType DefaultType(TimeMs timeout) {
constexpr auto kThreshold = TimeMs(1000);
static Qt::TimerType DefaultType(crl::time timeout) {
constexpr auto kThreshold = crl::time(1000);
return (timeout > kThreshold) ? Qt::CoarseTimer : Qt::PreciseTimer;
}
@@ -30,19 +30,19 @@ public:
_callback = std::move(callback);
}
void callOnce(TimeMs timeout) {
void callOnce(crl::time timeout) {
callOnce(timeout, DefaultType(timeout));
}
void callEach(TimeMs timeout) {
void callEach(crl::time timeout) {
callEach(timeout, DefaultType(timeout));
}
void callOnce(TimeMs timeout, Qt::TimerType type) {
void callOnce(crl::time timeout, Qt::TimerType type) {
start(timeout, type, Repeat::SingleShot);
}
void callEach(TimeMs timeout, Qt::TimerType type) {
void callEach(crl::time timeout, Qt::TimerType type) {
start(timeout, type, Repeat::Interval);
}
@@ -51,7 +51,7 @@ public:
}
void cancel();
TimeMs remainingTime() const;
crl::time remainingTime() const;
static void Adjust();
@@ -63,10 +63,10 @@ private:
Interval = 0,
SingleShot = 1,
};
void start(TimeMs timeout, Qt::TimerType type, Repeat repeat);
void start(crl::time timeout, Qt::TimerType type, Repeat repeat);
void adjust();
void setTimeout(TimeMs timeout);
void setTimeout(crl::time timeout);
int timeout() const;
void setRepeat(Repeat repeat) {
@@ -77,7 +77,7 @@ private:
}
Fn<void()> _callback;
TimeMs _next = 0;
crl::time _next = 0;
int _timeout = 0;
int _timerId = 0;
@@ -89,7 +89,7 @@ private:
class DelayedCallTimer final : private QObject {
public:
int call(TimeMs timeout, FnMut<void()> callback) {
int call(crl::time timeout, FnMut<void()> callback) {
return call(
timeout,
std::move(callback),
@@ -97,7 +97,7 @@ public:
}
int call(
TimeMs timeout,
crl::time timeout,
FnMut<void()> callback,
Qt::TimerType type);
void cancel(int callId);

View File

@@ -57,12 +57,21 @@ public:
}
~has_weak_ptr() {
if (auto alive = _alive.load()) {
if (const auto alive = _alive.load()) {
alive->value.store(nullptr);
details::decrement(alive);
}
}
friend inline void invalidate_weak_ptrs(has_weak_ptr *object) {
if (auto alive = object->_alive.load()) {
if (object->_alive.compare_exchange_strong(alive, nullptr)) {
alive->value.store(nullptr);
details::decrement(alive);
}
}
}
private:
template <typename Child>
friend class weak_ptr;

View File

@@ -13,6 +13,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "zip.h"
#include "unzip.h"
#ifdef small
#undef small
#endif // small
namespace zlib {
namespace internal {
@@ -172,15 +176,28 @@ public:
return error();
}
int goToFirstFile() {
if (error() == UNZ_OK) {
_error = _handle ? unzGoToFirstFile(_handle) : -1;
}
return error();
}
int goToNextFile() {
if (error() == UNZ_OK) {
_error = _handle ? unzGoToNextFile(_handle) : -1;
}
return error();
}
int getCurrentFileInfo(
unz_file_info *pfile_info,
char *szFileName,
uLong fileNameBufferSize,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
uLong commentBufferSize
) {
unz_file_info *pfile_info,
char *szFileName,
uLong fileNameBufferSize,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
uLong commentBufferSize) {
if (error() == UNZ_OK) {
_error = _handle ? unzGetCurrentFileInfo(
_handle,
@@ -196,6 +213,21 @@ public:
return error();
}
QString getCurrentFileName() {
unz_file_info info = { 0 };
constexpr auto kMaxName = 128;
char name[kMaxName + 1] = { 0 };
const auto result = getCurrentFileInfo(
&info,
name,
kMaxName,
nullptr,
0,
nullptr,
0);
return (result == UNZ_OK) ? QString::fromUtf8(name) : QString();
}
int openCurrentFile() {
if (error() == UNZ_OK) {
_error = _handle ? unzOpenCurrentFile(_handle) : -1;

View File

@@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwidget.h"
#include "mainwindow.h"
#include "boxes/confirm_box.h"
#include "application.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
#include "styles/style_boxes.h"
@@ -20,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/update_checker.h"
AboutBox::AboutBox(QWidget *parent)
: _version(this, lng_about_version(lt_version, QString::fromLatin1(AppVersionStr.c_str()) + (cAlphaVersion() ? qsl(" alpha %1").arg(cAlphaVersion()) : (AppBetaVersion ? " beta" : ""))), st::aboutVersionLink)
: _version(this, lng_about_version(lt_version, currentVersionText()), st::aboutVersionLink)
, _text1(this, lang(lng_about_text_1), Ui::FlatLabel::InitType::Rich, st::aboutLabel)
, _text2(this, lang(lng_about_text_2), Ui::FlatLabel::InitType::Rich, st::aboutLabel)
, _text3(this, st::aboutLabel) {
@@ -70,7 +69,7 @@ void AboutBox::showVersionHistory() {
}
url = url.arg(qsl("talpha%1_%2").arg(cRealAlphaVersion()).arg(Core::countAlphaVersionSignature(cRealAlphaVersion())));
Application::clipboard()->setText(url);
QApplication::clipboard()->setText(url);
Ui::show(Box<InformBox>("The link to the current private alpha version of Telegram Desktop was copied to the clipboard."));
} else {
@@ -87,18 +86,24 @@ void AboutBox::keyPressEvent(QKeyEvent *e) {
}
QString telegramFaqLink() {
auto result = qsl("https://telegram.org/faq");
auto language = Lang::Current().id();
for (auto faqLanguage : { "de", "es", "it", "ko", "br" }) {
if (language.startsWith(QLatin1String(faqLanguage))) {
result.append('/').append(faqLanguage);
const auto result = qsl("https://telegram.org/faq");
const auto langpacked = [&](const char *language) {
return result + '/' + language;
};
const auto current = Lang::Current().id();
for (const auto language : { "de", "es", "it", "ko" }) {
if (current.startsWith(QLatin1String(language))) {
return langpacked(language);
}
}
if (current.startsWith(qstr("pt-br"))) {
return langpacked("br");
}
return result;
}
QString currentVersionText() {
auto result = QString::fromLatin1(AppVersionStr.c_str());
auto result = QString::fromLatin1(AppVersionStr);
if (cAlphaVersion()) {
result += qsl(" alpha %1").arg(cAlphaVersion() % 1000);
} else if (AppBetaVersion) {

View File

@@ -77,7 +77,9 @@ void BoxContent::finishPrepare() {
void BoxContent::finishScrollCreate() {
Expects(_scroll != nullptr);
_scroll->show();
if (!_scroll->isHidden()) {
_scroll->show();
}
updateScrollAreaGeometry();
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
connect(_scroll, SIGNAL(innerResized()), this, SLOT(onInnerResize()));
@@ -143,6 +145,16 @@ void BoxContent::onInnerResize() {
updateShadowsVisibility();
}
void BoxContent::setDimensionsToContent(
int newWidth,
not_null<Ui::RpWidget*> content) {
content->resizeToWidth(newWidth);
content->heightValue(
) | rpl::start_with_next([=](int height) {
setDimensions(newWidth, height);
}, content->lifetime());
}
void BoxContent::setInnerTopSkip(int innerTopSkip, bool scrollBottomFixed) {
if (_innerTopSkip != innerTopSkip) {
auto delta = innerTopSkip - _innerTopSkip;
@@ -366,11 +378,18 @@ void AbstractBox::updateButtonsPositions() {
if (_leftButton) {
_leftButton->moveToLeft(right, top);
}
for_const (auto &button, _buttons) {
for (const auto &button : _buttons) {
button->moveToRight(right, top);
right += button->width() + padding.left();
}
}
if (_topButton) {
_topButton->moveToRight(0, 0);
}
}
QPointer<QWidget> AbstractBox::outerContainer() {
return parentWidget();
}
void AbstractBox::updateTitlePosition() {
@@ -387,6 +406,7 @@ void AbstractBox::clearButtons() {
button.destroy();
}
_leftButton.destroy();
_topButton = nullptr;
}
QPointer<Ui::RoundButton> AbstractBox::addButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) {
@@ -407,6 +427,15 @@ QPointer<Ui::RoundButton> AbstractBox::addLeftButton(Fn<QString()> textFactory,
return result;
}
QPointer<Ui::IconButton> AbstractBox::addTopButton(const style::IconButton &st, Fn<void()> clickCallback) {
_topButton = base::make_unique_q<Ui::IconButton>(this, st);
auto result = QPointer<Ui::IconButton>(_topButton.get());
result->setClickedCallback(std::move(clickCallback));
result->show();
updateButtonsPositions();
return result;
}
void AbstractBox::setDimensions(int newWidth, int maxHeight) {
_maxContentHeight = maxHeight;

View File

@@ -8,10 +8,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "window/layer_widget.h"
#include "base/unique_qptr.h"
#include "ui/rp_widget.h"
namespace style {
struct RoundButton;
struct IconButton;
struct ScrollArea;
} // namespace style
@@ -35,6 +37,7 @@ public:
virtual void clearButtons() = 0;
virtual QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) = 0;
virtual QPointer<Ui::RoundButton> addLeftButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) = 0;
virtual QPointer<Ui::IconButton> addTopButton(const style::IconButton &st, Fn<void()> clickCallback) = 0;
virtual void updateButtonsPositions() = 0;
virtual void showBox(
@@ -56,6 +59,8 @@ public:
return result;
}
virtual QPointer<QWidget> outerContainer() = 0;
};
class BoxContent : public Ui::RpWidget, protected base::Subscriber {
@@ -98,8 +103,14 @@ public:
void clearButtons() {
getDelegate()->clearButtons();
}
QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, Fn<void()> clickCallback);
QPointer<Ui::RoundButton> addLeftButton(Fn<QString()> textFactory, Fn<void()> clickCallback);
QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, Fn<void()> clickCallback = nullptr);
QPointer<Ui::RoundButton> addLeftButton(Fn<QString()> textFactory, Fn<void()> clickCallback = nullptr);
QPointer<Ui::IconButton> addTopButton(const style::IconButton &st, Fn<void()> clickCallback = nullptr) {
return getDelegate()->addTopButton(st, std::move(clickCallback));
}
QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, const style::RoundButton &st) {
return getDelegate()->addButton(std::move(textFactory), nullptr, st);
}
QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) {
return getDelegate()->addButton(std::move(textFactory), std::move(clickCallback), st);
}
@@ -118,12 +129,15 @@ public:
_boxClosingStream.fire({});
}
void setDelegate(BoxContentDelegate *newDelegate) {
void setDelegate(not_null<BoxContentDelegate*> newDelegate) {
_delegate = newDelegate;
_preparing = true;
prepare();
finishPrepare();
}
not_null<BoxContentDelegate*> getDelegate() const {
return _delegate;
}
public slots:
void onScrollToY(int top, int bottom = -1);
@@ -147,6 +161,9 @@ protected:
void setDimensions(int newWidth, int maxHeight) {
getDelegate()->setDimensions(newWidth, maxHeight);
}
void setDimensionsToContent(
int newWidth,
not_null<Ui::RpWidget*> content);
void setInnerTopSkip(int topSkip, bool scrollBottomFixed = false);
void setInnerBottomSkip(int bottomSkip);
@@ -187,10 +204,6 @@ protected:
void paintEvent(QPaintEvent *e) override;
void keyPressEvent(QKeyEvent *e) override;
not_null<BoxContentDelegate*> getDelegate() const {
return _delegate;
}
private slots:
void onScroll();
void onInnerResize();
@@ -247,7 +260,9 @@ public:
void clearButtons() override;
QPointer<Ui::RoundButton> addButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) override;
QPointer<Ui::RoundButton> addLeftButton(Fn<QString()> textFactory, Fn<void()> clickCallback, const style::RoundButton &st) override;
QPointer<Ui::IconButton> addTopButton(const style::IconButton &st, Fn<void()> clickCallback) override;
void updateButtonsPositions() override;
QPointer<QWidget> outerContainer() override;
void setDimensions(int newWidth, int maxHeight) override;
@@ -314,6 +329,7 @@ private:
std::vector<object_ptr<Ui::RoundButton>> _buttons;
object_ptr<Ui::RoundButton> _leftButton = { nullptr };
base::unique_qptr<Ui::IconButton> _topButton = { nullptr };
};
@@ -332,3 +348,45 @@ enum CreatingGroupType {
CreatingGroupGroup,
CreatingGroupChannel,
};
class BoxPointer {
public:
BoxPointer() = default;
BoxPointer(const BoxPointer &other) = default;
BoxPointer(BoxPointer &&other) : _value(base::take(other._value)) {
}
BoxPointer &operator=(const BoxPointer &other) {
if (_value != other._value) {
destroy();
_value = other._value;
}
return *this;
}
BoxPointer &operator=(BoxPointer &&other) {
if (_value != other._value) {
destroy();
_value = base::take(other._value);
}
return *this;
}
BoxPointer &operator=(BoxContent *other) {
if (_value != other) {
destroy();
_value = other;
}
return *this;
}
~BoxPointer() {
destroy();
}
private:
void destroy() {
if (const auto value = base::take(_value)) {
value->closeBox();
}
}
QPointer<BoxContent> _value;
};

View File

@@ -10,13 +10,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_boxes.h"
#include "styles/style_dialogs.h"
#include "lang/lang_keys.h"
#include "messenger.h"
#include "mtproto/sender.h"
#include "base/flat_set.h"
#include "boxes/confirm_box.h"
#include "boxes/photo_crop_box.h"
#include "boxes/peer_list_controllers.h"
#include "boxes/peers/add_participants_box.h"
#include "boxes/peers/edit_participant_box.h"
#include "boxes/peers/edit_participants_box.h"
#include "core/file_utilities.h"
#include "core/application.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
@@ -24,6 +28,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/toast/toast.h"
#include "ui/special_buttons.h"
#include "ui/text_options.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_user.h"
#include "data/data_session.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "apiwrap.h"
@@ -58,7 +66,7 @@ style::InputField CreateBioFieldStyle() {
QString PeerFloodErrorText(PeerFloodType type) {
auto link = textcmdLink(
Messenger::Instance().createInternalLinkFull(qsl("spambot")),
Core::App().createInternalLinkFull(qsl("spambot")),
lang(lng_cant_more_info));
if (type == PeerFloodType::InviteGroup) {
return lng_cant_invite_not_contact(lt_more_info, link);
@@ -66,6 +74,77 @@ QString PeerFloodErrorText(PeerFloodType type) {
return lng_cant_send_to_not_contact(lt_more_info, link);
}
void ShowAddParticipantsError(
const QString &error,
not_null<PeerData*> chat,
const std::vector<not_null<UserData*>> &users) {
if (error == qstr("USER_BOT")) {
const auto channel = chat->asChannel();
if ((users.size() == 1)
&& (users.front()->botInfo != nullptr)
&& channel
&& !channel->isMegagroup()
&& channel->canAddAdmins()) {
const auto makeAdmin = [=] {
const auto user = users.front();
const auto weak = std::make_shared<QPointer<EditAdminBox>>();
const auto close = [=](auto&&...) {
if (*weak) {
(*weak)->closeBox();
}
};
const auto saveCallback = SaveAdminCallback(
channel,
user,
close,
close);
auto box = Box<EditAdminBox>(
channel,
user,
MTP_chatAdminRights(MTP_flags(0)));
box->setSaveCallback(saveCallback);
*weak = Ui::show(std::move(box));
};
Ui::show(
Box<ConfirmBox>(
lang(lng_cant_invite_offer_admin),
lang(lng_cant_invite_make_admin),
lang(lng_cancel),
makeAdmin),
LayerOption::KeepOther);
return;
}
}
const auto bot = ranges::find_if(users, [](not_null<UserData*> user) {
return user->botInfo != nullptr;
});
const auto hasBot = (bot != end(users));
const auto text = [&] {
if (error == qstr("USER_BOT")) {
return lang(lng_cant_invite_bot_to_channel);
} else if (error == qstr("USER_LEFT_CHAT")) {
// Trying to return a user who has left.
} else if (error == qstr("USER_KICKED")) {
// Trying to return a user who was kicked by admin.
return lang(lng_cant_invite_banned);
} else if (error == qstr("USER_PRIVACY_RESTRICTED")) {
return lang(lng_cant_invite_privacy);
} else if (error == qstr("USER_NOT_MUTUAL_CONTACT")) {
// Trying to return user who does not have me in contacts.
return lang(lng_failed_add_not_mutual);
} else if (error == qstr("USER_ALREADY_PARTICIPANT") && hasBot) {
return lang(lng_bot_already_in_group);
} else if (error == qstr("PEER_FLOOD")) {
const auto isGroup = (chat->isChat() || chat->isMegagroup());
return PeerFloodErrorText(isGroup
? PeerFloodType::InviteGroup
: PeerFloodType::InviteChannel);
}
return lang(lng_failed_add_participant);
}();
Ui::show(Box<InformBox>(text), LayerOption::KeepOther);
}
class RevokePublicLinkBox::Inner : public TWidget, private MTP::Sender {
public:
Inner(QWidget *parent, Fn<void()> revokeCallback);
@@ -243,8 +322,9 @@ bool AddContactBox::onSaveUserFail(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false;
_addRequest = 0;
QString err(error.type());
QString firstName = _first->getLastText().trimmed(), lastName = _last->getLastText().trimmed();
const auto &err = error.type();
const auto firstName = _first->getLastText().trimmed();
const auto lastName = _last->getLastText().trimmed();
if (err == "CHAT_TITLE_NOT_MODIFIED") {
_user->setName(firstName, lastName, _user->nameOrPhone, _user->username);
closeBox();
@@ -262,20 +342,21 @@ void AddContactBox::onImportDone(const MTPcontacts_ImportedContacts &res) {
if (!isBoxShown() || !App::main()) return;
const auto &d = res.c_contacts_importedContacts();
App::feedUsers(d.vusers);
Auth().data().processUsers(d.vusers);
const auto &v = d.vimported.v;
const auto user = [&]() -> UserData* {
if (!v.isEmpty()) {
auto &c = v.front().c_importedContact();
if (c.vclient_id.v == _contactId) {
return App::userLoaded(c.vuser_id.v);
return Auth().data().userLoaded(c.vuser_id.v);
}
}
return nullptr;
}();
if (user) {
if (user->contactStatus() == UserData::ContactStatus::Contact) {
if (user->contactStatus() == UserData::ContactStatus::Contact
|| user->session().supportMode()) {
Ui::showPeerHistory(user, ShowAtTheEndMsgId);
}
Ui::hideLayer();
@@ -289,7 +370,7 @@ void AddContactBox::onImportDone(const MTPcontacts_ImportedContacts &res) {
void AddContactBox::onSaveUserDone(const MTPcontacts_ImportedContacts &res) {
auto &d = res.c_contacts_importedContacts();
App::feedUsers(d.vusers);
Auth().data().processUsers(d.vusers);
closeBox();
}
@@ -327,9 +408,9 @@ void GroupInfoBox::prepare() {
_photo.create(
this,
(_creating == CreatingGroupChannel)
? peerFromChannel(0)
: peerFromChat(0),
lang((_creating == CreatingGroupChannel)
? lng_create_channel_crop
: lng_create_group_crop),
Ui::UserpicButton::Role::ChangePhoto,
st::defaultUserpicButton);
_title.create(
@@ -341,6 +422,9 @@ void GroupInfoBox::prepare() {
_title->setMaxLength(kMaxGroupChannelTitle);
_title->setInstantReplaces(Ui::InstantReplaces::Default());
_title ->setInstantReplacesEnabled(Global::ReplaceEmojiValue());
Ui::Emoji::SuggestionsController::Init(
getDelegate()->outerContainer(),
_title);
if (_creating == CreatingGroupChannel) {
_description.create(
@@ -357,6 +441,10 @@ void GroupInfoBox::prepare() {
connect(_description, &Ui::InputField::resized, [=] { descriptionResized(); });
connect(_description, &Ui::InputField::submitted, [=] { submit(); });
connect(_description, &Ui::InputField::cancelled, [=] { closeBox(); });
Ui::Emoji::SuggestionsController::Init(
getDelegate()->outerContainer(),
_description);
}
connect(_title, &Ui::InputField::submitted, [=] { submitName(); });
@@ -403,7 +491,10 @@ void GroupInfoBox::submitName() {
}
}
void GroupInfoBox::createGroup(not_null<PeerListBox*> selectUsersBox, const QString &title, const std::vector<not_null<PeerData*>> &users) {
void GroupInfoBox::createGroup(
not_null<PeerListBox*> selectUsersBox,
const QString &title,
const std::vector<not_null<PeerData*>> &users) {
if (_creationRequestId) return;
auto inputs = QVector<MTPInputUser>();
@@ -418,10 +509,14 @@ void GroupInfoBox::createGroup(not_null<PeerListBox*> selectUsersBox, const QStr
if (inputs.empty()) {
return;
}
_creationRequestId = request(MTPmessages_CreateChat(MTP_vector<MTPInputUser>(inputs), MTP_string(title))).done([this](const MTPUpdates &result) {
_creationRequestId = request(MTPmessages_CreateChat(
MTP_vector<MTPInputUser>(inputs),
MTP_string(title)
)).done([=](const MTPUpdates &result) {
auto image = _photo->takeResultImage();
Ui::hideLayer();
App::main()->sentUpdatesReceived(result);
Auth().api().applyUpdates(result);
auto success = base::make_optional(&result)
| [](auto updates) -> std::optional<const QVector<MTPChat>*> {
@@ -431,28 +526,32 @@ void GroupInfoBox::createGroup(not_null<PeerListBox*> selectUsersBox, const QStr
case mtpc_updatesCombined:
return &updates->c_updatesCombined().vchats.v;
}
LOG(("API Error: unexpected update cons %1 (GroupInfoBox::creationDone)").arg(updates->type()));
LOG(("API Error: unexpected update cons %1 "
"(GroupInfoBox::creationDone)").arg(updates->type()));
return std::nullopt;
}
| [](auto chats) {
return (!chats->empty() && chats->front().type() == mtpc_chat)
return (!chats->empty()
&& chats->front().type() == mtpc_chat)
? base::make_optional(chats)
: std::nullopt;
}
| [](auto chats) {
return App::chat(chats->front().c_chat().vid.v);
return Auth().data().chat(chats->front().c_chat().vid.v);
}
| [this](not_null<ChatData*> chat) {
auto image = _photo->takeResultImage();
| [&](not_null<ChatData*> chat) {
if (!image.isNull()) {
Auth().api().uploadPeerPhoto(chat, std::move(image));
chat->session().api().uploadPeerPhoto(
chat,
std::move(image));
}
Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
};
if (!success) {
LOG(("API Error: chat not found in updates (ContactsBox::creationDone)"));
LOG(("API Error: chat not found in updates "
"(ContactsBox::creationDone)"));
}
}).fail([this, selectUsersBox](const RPCError &error) {
}).fail([=](const RPCError &error) {
_creationRequestId = 0;
if (error.type() == qstr("NO_CHAT_TITLE")) {
auto weak = make_weak(this);
@@ -513,8 +612,7 @@ void GroupInfoBox::submit() {
};
Ui::show(
Box<PeerListBox>(
std::make_unique<AddParticipantsBoxController>(
nullptr),
std::make_unique<AddParticipantsBoxController>(),
std::move(initBox)),
LayerOption::KeepOther);
}
@@ -523,8 +621,12 @@ void GroupInfoBox::submit() {
void GroupInfoBox::createChannel(const QString &title, const QString &description) {
bool mega = false;
auto flags = mega ? MTPchannels_CreateChannel::Flag::f_megagroup : MTPchannels_CreateChannel::Flag::f_broadcast;
_creationRequestId = request(MTPchannels_CreateChannel(MTP_flags(flags), MTP_string(title), MTP_string(description))).done([this](const MTPUpdates &result) {
App::main()->sentUpdatesReceived(result);
_creationRequestId = request(MTPchannels_CreateChannel(
MTP_flags(flags),
MTP_string(title),
MTP_string(description)
)).done([=](const MTPUpdates &result) {
Auth().api().applyUpdates(result);
auto success = base::make_optional(&result)
| [](auto updates) -> std::optional<const QVector<MTPChat>*> {
@@ -543,17 +645,19 @@ void GroupInfoBox::createChannel(const QString &title, const QString &descriptio
: std::nullopt;
}
| [](auto chats) {
return App::channel(chats->front().c_channel().vid.v);
return Auth().data().channel(chats->front().c_channel().vid.v);
}
| [this](not_null<ChannelData*> channel) {
| [&](not_null<ChannelData*> channel) {
auto image = _photo->takeResultImage();
if (!image.isNull()) {
Auth().api().uploadPeerPhoto(channel, std::move(image));
channel->session().api().uploadPeerPhoto(
channel,
std::move(image));
}
_createdChannel = channel;
_creationRequestId = request(
MTPchannels_ExportInvite(_createdChannel->inputChannel)
).done([this](const MTPExportedChatInvite &result) {
_creationRequestId = request(MTPmessages_ExportChatInvite(
_createdChannel->input
)).done([=](const MTPExportedChatInvite &result) {
_creationRequestId = 0;
if (result.type() == mtpc_chatInviteExported) {
auto link = qs(result.c_chatInviteExported().vlink);
@@ -731,7 +835,7 @@ void SetupChannelBox::mouseMoveEvent(QMouseEvent *e) {
void SetupChannelBox::mousePressEvent(QMouseEvent *e) {
if (_linkOver) {
if (_channel->inviteLink().isEmpty()) {
Auth().api().exportInviteLink(_channel);
_channel->session().api().exportInviteLink(_channel);
} else {
QGuiApplication::clipboard()->setText(_channel->inviteLink());
Ui::Toast::Show(lang(lng_create_channel_link_copied));
@@ -755,26 +859,25 @@ void SetupChannelBox::updateSelected(const QPoint &cursorGlobalPosition) {
}
void SetupChannelBox::save() {
if (_privacyGroup->value() == Privacy::Private) {
if (_saveRequestId) {
return;
} else if (_privacyGroup->value() == Privacy::Private) {
if (_existing) {
_sentUsername = QString();
_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
} else {
closeBox();
}
} else {
const auto link = _link->text().trimmed();
if (link.isEmpty()) {
_link->setFocus();
_link->showError();
return;
}
_sentUsername = link;
_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
}
if (_saveRequestId) return;
QString link = _link->text().trimmed();
if (link.isEmpty()) {
_link->setFocus();
_link->showError();
return;
}
_sentUsername = link;
_saveRequestId = MTP::send(MTPchannels_UpdateUsername(_channel->inputChannel, MTP_string(_sentUsername)), rpcDone(&SetupChannelBox::onUpdateDone), rpcFail(&SetupChannelBox::onUpdateFail));
}
void SetupChannelBox::handleChange() {
@@ -1052,7 +1155,7 @@ void EditNameBox::save() {
}
void EditNameBox::saveSelfDone(const MTPUser &user) {
App::feedUsers(MTP_vector<MTPUser>(1, user));
_user->owner().processUsers(MTP_vector<MTPUser>(1, user));
closeBox();
}
@@ -1079,331 +1182,6 @@ bool EditNameBox::saveSelfFail(const RPCError &error) {
return true;
}
EditBioBox::EditBioBox(QWidget*, not_null<UserData*> self) : BoxContent()
, _dynamicFieldStyle(CreateBioFieldStyle())
, _self(self)
, _bio(
this,
_dynamicFieldStyle,
Ui::InputField::Mode::MultiLine,
langFactory(lng_bio_placeholder),
_self->about())
, _countdown(this, QString(), Ui::FlatLabel::InitType::Simple, st::editBioCountdownLabel)
, _about(this, lang(lng_bio_about), Ui::FlatLabel::InitType::Simple, st::aboutRevokePublicLabel) {
}
void EditBioBox::prepare() {
setTitle(langFactory(lng_bio_title));
addButton(langFactory(lng_settings_save), [this] { save(); });
addButton(langFactory(lng_cancel), [this] { closeBox(); });
_bio->setMaxLength(kMaxBioLength);
_bio->setSubmitSettings(Ui::InputField::SubmitSettings::Both);
auto cursor = _bio->textCursor();
cursor.setPosition(_bio->getLastText().size());
_bio->setTextCursor(cursor);
connect(_bio, &Ui::InputField::submitted, [=] { save(); });
connect(_bio, &Ui::InputField::resized, [=] { updateMaxHeight(); });
connect(_bio, &Ui::InputField::changed, [=] { handleBioUpdated(); });
_bio->setInstantReplaces(Ui::InstantReplaces::Default());
_bio->setInstantReplacesEnabled(Global::ReplaceEmojiValue());
handleBioUpdated();
updateMaxHeight();
}
void EditBioBox::updateMaxHeight() {
auto newHeight = st::contactPadding.top() + _bio->height() + st::boxLittleSkip + _about->height() + st::boxPadding.bottom() + st::contactPadding.bottom();
setDimensions(st::boxWideWidth, newHeight);
}
void EditBioBox::handleBioUpdated() {
auto text = _bio->getLastText();
if (text.indexOf('\n') >= 0) {
auto position = _bio->textCursor().position();
_bio->setText(text.replace('\n', ' '));
auto cursor = _bio->textCursor();
cursor.setPosition(position);
_bio->setTextCursor(cursor);
}
auto countLeft = qMax(kMaxBioLength - text.size(), 0);
_countdown->setText(QString::number(countLeft));
}
void EditBioBox::setInnerFocus() {
_bio->setFocusFast();
}
void EditBioBox::resizeEvent(QResizeEvent *e) {
BoxContent::resizeEvent(e);
_bio->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _bio->height());
_bio->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), st::contactPadding.top());
_countdown->moveToRight(st::boxPadding.right(), _bio->y() + _dynamicFieldStyle.textMargins.top());
_about->moveToLeft(st::boxPadding.left(), _bio->y() + _bio->height() + st::boxLittleSkip);
}
void EditBioBox::save() {
if (_requestId) return;
auto text = TextUtilities::PrepareForSending(_bio->getLastText());
_sentBio = text;
auto flags = MTPaccount_UpdateProfile::Flag::f_about;
_requestId = request(MTPaccount_UpdateProfile(MTP_flags(flags), MTPstring(), MTPstring(), MTP_string(text))).done([this](const MTPUser &result) {
App::feedUsers(MTP_vector<MTPUser>(1, result));
_self->setAbout(_sentBio);
closeBox();
}).send();
}
EditChannelBox::EditChannelBox(QWidget*, not_null<ChannelData*> channel)
: _channel(channel)
, _title(this, st::defaultInputField, langFactory(_channel->isMegagroup() ? lng_dlg_new_group_name : lng_dlg_new_channel_name), _channel->name)
, _description(
this,
st::newGroupDescription,
Ui::InputField::Mode::MultiLine,
langFactory(lng_create_group_description),
_channel->about())
, _sign(this, lang(lng_edit_sign_messages), channel->addsSignature(), st::defaultBoxCheckbox)
, _inviteGroup(std::make_shared<Ui::RadioenumGroup<Invites>>(channel->anyoneCanAddMembers() ? Invites::Everybody : Invites::OnlyAdmins))
, _inviteEverybody(this, _inviteGroup, Invites::Everybody, lang(lng_edit_group_invites_everybody))
, _inviteOnlyAdmins(this, _inviteGroup, Invites::OnlyAdmins, lang(lng_edit_group_invites_only_admins))
, _publicLink(this, lang(channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link), st::boxLinkButton) {
}
void EditChannelBox::prepare() {
setTitle(langFactory(_channel->isMegagroup() ? lng_edit_group : lng_edit_channel_title));
addButton(langFactory(lng_settings_save), [this] { save(); });
addButton(langFactory(lng_cancel), [this] { closeBox(); });
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::NameChanged, [this](const Notify::PeerUpdate &update) {
if (update.peer == _channel) {
handleChannelNameChange();
}
}));
setMouseTracking(true);
_title->setMaxLength(kMaxGroupChannelTitle);
_title->setInstantReplaces(Ui::InstantReplaces::Default());
_title->setInstantReplacesEnabled(Global::ReplaceEmojiValue());
_description->setMaxLength(kMaxChannelDescription);
_description->setInstantReplaces(Ui::InstantReplaces::Default());
_description->setInstantReplacesEnabled(Global::ReplaceEmojiValue());
connect(_description, &Ui::InputField::resized, [=] { descriptionResized(); });
connect(_description, &Ui::InputField::submitted, [=] { save(); });
connect(_description, &Ui::InputField::cancelled, [=] { closeBox(); });
_publicLink->addClickHandler([=] { setupPublicLink(); });
_publicLink->setVisible(_channel->canEditUsername());
_sign->setVisible(canEditSignatures());
_inviteEverybody->setVisible(canEditInvites());
_inviteOnlyAdmins->setVisible(canEditInvites());
updateMaxHeight();
}
void EditChannelBox::setInnerFocus() {
_title->setFocusFast();
}
void EditChannelBox::keyPressEvent(QKeyEvent *e) {
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
if (_title->hasFocus()) {
save();
}
} else {
BoxContent::keyPressEvent(e);
}
}
void EditChannelBox::handleChannelNameChange() {
_publicLink->setText(lang(_channel->isPublic() ? lng_profile_edit_public_link : lng_profile_create_public_link));
_sign->setChecked(_channel->addsSignature());
}
void EditChannelBox::descriptionResized() {
updateMaxHeight();
update();
}
bool EditChannelBox::canEditSignatures() const {
return _channel->canEditInformation() && !_channel->isMegagroup();
}
bool EditChannelBox::canEditInvites() const {
return _channel->canEditInformation() && _channel->isMegagroup();
}
void EditChannelBox::updateMaxHeight() {
auto newHeight = st::newGroupInfoPadding.top() + _title->height();
newHeight += st::newGroupDescriptionPadding.top() + _description->height() + st::newGroupDescriptionPadding.bottom();
if (canEditSignatures()) {
newHeight += st::newGroupPublicLinkPadding.top() + _sign->heightNoMargins() + st::newGroupPublicLinkPadding.bottom();
}
if (canEditInvites()) {
newHeight += st::boxTitleHeight + _inviteEverybody->heightNoMargins();
newHeight += st::boxLittleSkip + _inviteOnlyAdmins->heightNoMargins();
}
if (_channel->canEditUsername()) {
newHeight += st::newGroupPublicLinkPadding.top() + _publicLink->height() + st::newGroupPublicLinkPadding.bottom();
}
newHeight += st::boxPadding.bottom() + st::newGroupInfoPadding.bottom();
setDimensions(st::boxWideWidth, newHeight);
}
void EditChannelBox::resizeEvent(QResizeEvent *e) {
BoxContent::resizeEvent(e);
_title->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _title->height());
_title->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), st::newGroupInfoPadding.top() + st::newGroupNamePosition.y());
_description->resize(width() - st::boxPadding.left() - st::newGroupInfoPadding.left() - st::boxPadding.right(), _description->height());
_description->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _title->y() + _title->height() + st::newGroupDescriptionPadding.top());
_sign->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description->y() + _description->height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
_inviteEverybody->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description->y() + _description->height() + st::boxTitleHeight);
_inviteOnlyAdmins->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _inviteEverybody->bottomNoMargins() + st::boxLittleSkip);
if (canEditSignatures()) {
_publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _sign->bottomNoMargins() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
} else if (canEditInvites()) {
_publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _inviteOnlyAdmins->bottomNoMargins() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
} else {
_publicLink->moveToLeft(st::boxPadding.left() + st::newGroupInfoPadding.left(), _description->y() + _description->height() + st::newGroupDescriptionPadding.bottom() + st::newGroupPublicLinkPadding.top());
}
}
void EditChannelBox::paintEvent(QPaintEvent *e) {
BoxContent::paintEvent(e);
if (canEditInvites()) {
Painter p(this);
p.setPen(st::boxTitleFg);
p.setFont(st::autoDownloadTitleFont);
p.drawTextLeft(st::boxTitlePosition.x(), _description->y() + _description->height() + st::boxTitlePosition.y(), width(), lang(lng_edit_group_who_invites));
}
}
void EditChannelBox::save() {
if (_saveTitleRequestId || _saveDescriptionRequestId || _saveSignRequestId || _saveInvitesRequestId) return;
auto title = TextUtilities::PrepareForSending(_title->getLastText());
auto description = TextUtilities::PrepareForSending(_description->getLastText(), TextUtilities::PrepareTextOption::CheckLinks);
if (title.isEmpty()) {
_title->setFocus();
_title->showError();
return;
}
_sentTitle = title;
_sentDescription = description;
if (_sentTitle == _channel->name) {
saveDescription();
} else {
_saveTitleRequestId = MTP::send(MTPchannels_EditTitle(_channel->inputChannel, MTP_string(_sentTitle)), rpcDone(&EditChannelBox::onSaveTitleDone), rpcFail(&EditChannelBox::onSaveFail));
}
}
void EditChannelBox::setupPublicLink() {
Ui::show(
Box<SetupChannelBox>(_channel, true),
LayerOption::KeepOther);
}
void EditChannelBox::saveDescription() {
if (_sentDescription == _channel->about()) {
saveSign();
} else {
_saveDescriptionRequestId = MTP::send(MTPchannels_EditAbout(_channel->inputChannel, MTP_string(_sentDescription)), rpcDone(&EditChannelBox::onSaveDescriptionDone), rpcFail(&EditChannelBox::onSaveFail));
}
}
void EditChannelBox::saveSign() {
if (!canEditSignatures() || _channel->addsSignature() == _sign->checked()) {
saveInvites();
} else {
_saveSignRequestId = MTP::send(MTPchannels_ToggleSignatures(_channel->inputChannel, MTP_bool(_sign->checked())), rpcDone(&EditChannelBox::onSaveSignDone), rpcFail(&EditChannelBox::onSaveFail));
}
}
void EditChannelBox::saveInvites() {
if (!canEditInvites() || _channel->anyoneCanAddMembers() == (_inviteGroup->value() == Invites::Everybody)) {
closeBox();
} else {
_saveInvitesRequestId = MTP::send(MTPchannels_ToggleInvites(_channel->inputChannel, MTP_bool(_inviteGroup->value() == Invites::Everybody)), rpcDone(&EditChannelBox::onSaveInvitesDone), rpcFail(&EditChannelBox::onSaveFail));
}
}
bool EditChannelBox::onSaveFail(const RPCError &error, mtpRequestId req) {
if (MTP::isDefaultHandledError(error)) return false;
QString err(error.type());
if (req == _saveTitleRequestId) {
_saveTitleRequestId = 0;
if (err == qstr("CHAT_NOT_MODIFIED") || err == qstr("CHAT_TITLE_NOT_MODIFIED")) {
_channel->setName(_sentTitle, _channel->username);
saveDescription();
return true;
} else if (err == qstr("NO_CHAT_TITLE")) {
_title->setFocus();
_title->showError();
return true;
} else {
_title->setFocus();
}
} else if (req == _saveDescriptionRequestId) {
_saveDescriptionRequestId = 0;
if (err == qstr("CHAT_ABOUT_NOT_MODIFIED")) {
_channel->setAbout(_sentDescription);
saveSign();
return true;
} else {
_description->setFocus();
}
} else if (req == _saveSignRequestId) {
_saveSignRequestId = 0;
if (err == qstr("CHAT_NOT_MODIFIED")) {
saveInvites();
return true;
}
} else if (req == _saveInvitesRequestId) {
_saveInvitesRequestId = 0;
if (err == qstr("CHAT_NOT_MODIFIED")) {
closeBox();
return true;
}
}
return true;
}
void EditChannelBox::onSaveTitleDone(const MTPUpdates &result) {
_saveTitleRequestId = 0;
Auth().api().applyUpdates(result);
saveDescription();
}
void EditChannelBox::onSaveDescriptionDone(const MTPBool &result) {
_saveDescriptionRequestId = 0;
_channel->setAbout(_sentDescription);
saveSign();
}
void EditChannelBox::onSaveSignDone(const MTPUpdates &result) {
_saveSignRequestId = 0;
Auth().api().applyUpdates(result);
saveInvites();
}
void EditChannelBox::onSaveInvitesDone(const MTPUpdates &result) {
_saveSignRequestId = 0;
Auth().api().applyUpdates(result);
closeBox();
}
RevokePublicLinkBox::Inner::Inner(QWidget *parent, Fn<void()> revokeCallback) : TWidget(parent)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _revokeWidth(st::normalFont->width(lang(lng_channels_too_much_public_revoke)))
@@ -1412,27 +1190,29 @@ RevokePublicLinkBox::Inner::Inner(QWidget *parent, Fn<void()> revokeCallback) :
resize(width(), 5 * _rowHeight);
request(MTPchannels_GetAdminedPublicChannels()).done([this](const MTPmessages_Chats &result) {
if (auto chats = Api::getChatsFromMessagesChats(result)) {
for_const (auto &chat, chats->v) {
if (auto peer = App::feedChat(chat)) {
if (!peer->isChannel() || peer->userName().isEmpty()) {
continue;
}
auto row = ChatRow(peer);
row.peer = peer;
row.name.setText(
st::contactsNameStyle,
peer->name,
Ui::NameTextOptions());
row.status.setText(
st::defaultTextStyle,
Messenger::Instance().createInternalLink(
textcmdLink(1, peer->userName())),
Ui::DialogTextOptions());
_rows.push_back(std::move(row));
request(MTPchannels_GetAdminedPublicChannels(
)).done([=](const MTPmessages_Chats &result) {
const auto &chats = result.match([](const auto &data) {
return data.vchats.v;
});
for (const auto &chat : chats) {
if (const auto peer = Auth().data().processChat(chat)) {
if (!peer->isChannel() || peer->userName().isEmpty()) {
continue;
}
auto row = ChatRow(peer);
row.peer = peer;
row.name.setText(
st::contactsNameStyle,
peer->name,
Ui::NameTextOptions());
row.status.setText(
st::defaultTextStyle,
Core::App().createInternalLink(
textcmdLink(1, peer->userName())),
Ui::DialogTextOptions());
_rows.push_back(std::move(row));
}
}
resize(width(), _rows.size() * _rowHeight);
@@ -1440,23 +1220,30 @@ RevokePublicLinkBox::Inner::Inner(QWidget *parent, Fn<void()> revokeCallback) :
}).send();
}
RevokePublicLinkBox::RevokePublicLinkBox(QWidget*, Fn<void()> revokeCallback)
: _aboutRevoke(this, lang(lng_channels_too_much_public_about), Ui::FlatLabel::InitType::Simple, st::aboutRevokePublicLabel)
RevokePublicLinkBox::RevokePublicLinkBox(
QWidget*,
Fn<void()> revokeCallback)
: _aboutRevoke(
this,
lang(lng_channels_too_much_public_about),
Ui::FlatLabel::InitType::Simple,
st::aboutRevokePublicLabel)
, _revokeCallback(std::move(revokeCallback)) {
}
void RevokePublicLinkBox::prepare() {
_innerTop = st::boxPadding.top() + _aboutRevoke->height() + st::boxPadding.top();
_inner = setInnerWidget(object_ptr<Inner>(this, [this] {
_inner = setInnerWidget(object_ptr<Inner>(this, [=] {
const auto callback = _revokeCallback;
closeBox();
if (_revokeCallback) {
_revokeCallback();
if (callback) {
callback();
}
}), st::boxLayerScroll, _innerTop);
addButton(langFactory(lng_cancel), [this] { closeBox(); });
addButton(langFactory(lng_cancel), [=] { closeBox(); });
subscribe(Auth().downloaderTaskFinished(), [this] { update(); });
subscribe(Auth().downloaderTaskFinished(), [=] { update(); });
_inner->resizeToWidth(st::boxWideWidth);
setDimensions(st::boxWideWidth, _innerTop + _inner->height());
@@ -1497,16 +1284,20 @@ void RevokePublicLinkBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
setCursor((_selected || _pressed) ? style::cur_pointer : style::cur_default);
if (pressed && pressed == _selected) {
auto text_method = pressed->isMegagroup() ? lng_channels_too_much_public_revoke_confirm_group : lng_channels_too_much_public_revoke_confirm_channel;
auto text = text_method(lt_link, Messenger::Instance().createInternalLink(pressed->userName()), lt_group, pressed->name);
auto text = text_method(lt_link, Core::App().createInternalLink(pressed->userName()), lt_group, pressed->name);
auto confirmText = lang(lng_channels_too_much_public_revoke);
_weakRevokeConfirmBox = Ui::show(Box<ConfirmBox>(text, confirmText, crl::guard(this, [this, pressed]() {
if (_revokeRequestId) return;
_revokeRequestId = request(MTPchannels_UpdateUsername(pressed->asChannel()->inputChannel, MTP_string(""))).done([this](const MTPBool &result) {
_revokeRequestId = request(MTPchannels_UpdateUsername(
pressed->asChannel()->inputChannel,
MTP_string("")
)).done([=](const MTPBool &result) {
const auto callback = _revokeCallback;
if (_weakRevokeConfirmBox) {
_weakRevokeConfirmBox->closeBox();
}
if (_revokeCallback) {
_revokeCallback();
if (callback) {
callback();
}
}).send();
})), LayerOption::KeepOther);

View File

@@ -38,6 +38,10 @@ enum class PeerFloodType {
InviteChannel,
};
QString PeerFloodErrorText(PeerFloodType type);
void ShowAddParticipantsError(
const QString &error,
not_null<PeerData*> chat,
const std::vector<not_null<UserData*>> &users);
class AddContactBox : public BoxContent, public RPCSender {
public:
@@ -96,7 +100,6 @@ private:
void descriptionResized();
void updateMaxHeight();
void updateSelected(const QPoint &cursorGlobalPosition);
CreatingGroupType _creating;
bool _fromTypeChoose = false;
@@ -134,7 +137,6 @@ private:
};
void privacyChanged(Privacy value);
void updateSelected(const QPoint &cursorGlobalPosition);
void showAddContactsToChannelBox() const;
void handleChange();
void check();
void save();
@@ -201,88 +203,6 @@ private:
};
class EditBioBox : public BoxContent, private MTP::Sender {
public:
EditBioBox(QWidget*, not_null<UserData*> self);
protected:
void setInnerFocus() override;
void prepare() override;
void resizeEvent(QResizeEvent *e) override;
private:
void updateMaxHeight();
void handleBioUpdated();
void save();
style::InputField _dynamicFieldStyle;
not_null<UserData*> _self;
object_ptr<Ui::InputField> _bio;
object_ptr<Ui::FlatLabel> _countdown;
object_ptr<Ui::FlatLabel> _about;
mtpRequestId _requestId = 0;
QString _sentBio;
};
class EditChannelBox : public BoxContent, public RPCSender {
public:
EditChannelBox(QWidget*, not_null<ChannelData*> channel);
protected:
void prepare() override;
void setInnerFocus() override;
void keyPressEvent(QKeyEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void paintEvent(QPaintEvent *e) override;
private:
void updateMaxHeight();
bool canEditSignatures() const;
bool canEditInvites() const;
void handleChannelNameChange();
void descriptionResized();
void setupPublicLink();
void save();
void onSaveTitleDone(const MTPUpdates &result);
void onSaveDescriptionDone(const MTPBool &result);
void onSaveSignDone(const MTPUpdates &result);
void onSaveInvitesDone(const MTPUpdates &result);
bool onSaveFail(const RPCError &error, mtpRequestId req);
void saveDescription();
void saveSign();
void saveInvites();
not_null<ChannelData*> _channel;
object_ptr<Ui::InputField> _title;
object_ptr<Ui::InputField> _description;
object_ptr<Ui::Checkbox> _sign;
enum class Invites {
Everybody,
OnlyAdmins,
};
std::shared_ptr<Ui::RadioenumGroup<Invites>> _inviteGroup;
object_ptr<Ui::Radioenum<Invites>> _inviteEverybody;
object_ptr<Ui::Radioenum<Invites>> _inviteOnlyAdmins;
object_ptr<Ui::LinkButton> _publicLink;
mtpRequestId _saveTitleRequestId = 0;
mtpRequestId _saveDescriptionRequestId = 0;
mtpRequestId _saveSignRequestId = 0;
mtpRequestId _saveInvitesRequestId = 0;
QString _sentTitle, _sentDescription;
};
class RevokePublicLinkBox : public BoxContent, public RPCSender {
public:
RevokePublicLinkBox(QWidget*, Fn<void()> revokeCallback);

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