Compare commits

...

74 Commits

Author SHA1 Message Date
John Preston
78c8d0562b Version 4.16.8: Fix build on Linux. 2024-04-16 23:23:11 +04:00
John Preston
bb0280f096 Revert "Replace mozjpeg with jpegli in snap"
This reverts commit f57e2edf2a.
2024-04-16 23:22:55 +04:00
John Preston
566b53ce9f Revert "Clean remainings of mozjpeg in snapcraft.yml"
This reverts commit da1909cc1d.
2024-04-16 23:22:43 +04:00
John Preston
ec95db0945 Revert "Replace mozjpeg with jpegli in Docker"
This reverts commit a1e2e3d011.
2024-04-16 23:00:08 +04:00
John Preston
a0d7d07543 Version 4.16.8.
- Fix in-app playing of some video and audio files.
- Fix crash on Linux opening chats with custom backgrounds.
- Fix crash on quit after using scheduled messages.
2024-04-16 20:15:32 +04:00
John Preston
fe73bf9053 Fix ripples in channel comments buttons. 2024-04-16 20:14:04 +04:00
John Preston
49c9e08b6c Enforce video/audio extension by mime type. 2024-04-16 20:14:01 +04:00
John Preston
abcf55c498 Check chat background read result. 2024-04-16 20:13:55 +04:00
John Preston
849ce310c4 Jump by keyboard between time input fields. 2024-04-16 20:13:02 +04:00
John Preston
a3e593b747 Fix crash in scheduled messages tear-down. 2024-04-16 20:12:03 +04:00
23rd
5433f95eda Simplified creation of label with custom emoji. 2024-04-16 03:44:00 +03:00
23rd
0459196982 Moved out level meter widget to td_ui. 2024-04-16 03:43:39 +03:00
23rd
6f1457d30d Fixed phrase of placeholder for message edition mode. 2024-04-15 23:56:37 +03:00
23rd
ce596e29c4 Fixed opening message from media player widget in corresponding window. 2024-04-15 23:41:00 +03:00
23rd
86b9d16747 Added additional note for macOS keys to json of custom shortcuts. 2024-04-15 23:30:57 +03:00
John Preston
06911ae42a Version 4.16.7.
- Reimplement file open confirmations.
2024-04-15 17:56:45 +04:00
John Preston
af2cb9b757 Fix possible unhandled exception in highlighting. 2024-04-15 17:56:45 +04:00
John Preston
6a28cd1a35 Reimplement file open confirmations. 2024-04-15 12:07:27 +04:00
23rd
f4a09a9ca0 Fixed display of growth rate in statistics info for huge values. 2024-04-15 11:20:30 +04:00
23rd
a35f020f56 Moved out ScheduledMessages module to components submodule. 2024-04-15 11:20:30 +04:00
23rd
3d48111368 Moved out SponsoredMessages module to components submodule. 2024-04-15 11:20:30 +04:00
23rd
39ed7d7f4c Increased clickable area for each item in EditPeerHistoryVisibilityBox. 2024-04-15 11:20:30 +04:00
23rd
abe83ccb8f Moved inaccessible groups in box for user's own groups to sub-list.
Fixed #27729.
2024-04-15 11:20:30 +04:00
23rd
d1be7c1ff7 Simplified management of PasscodeBox within customCheckCallback. 2024-04-15 11:20:30 +04:00
23rd
1c223e570a Slightly improved code style for long equality expressions. 2024-04-15 11:20:30 +04:00
23rd
a37cbd7d05 Initially refactored statistics module to simplify value types changing. 2024-04-15 11:20:30 +04:00
23rd
7ffa9844e2 Fixed currency formatting for channel earn info section. 2024-04-15 11:20:30 +04:00
23rd
bdf5872f04 Fixed opening channel earn info section for admins. 2024-04-15 11:20:30 +04:00
Ilya Fedin
da1909cc1d Clean remainings of mozjpeg in snapcraft.yml 2024-04-15 10:11:54 +04:00
Ilya Fedin
a503197352 Remove XCBSetDesktopFileName
This is done by Qt nowadays
2024-04-15 10:11:30 +04:00
Nyan
d9d9a8f49d Update data_document_resolver.cpp
Added the LEXE and WLUA extensions to the IsExecutableName function for Windows. Those are registered by default on Windows devices with LUA installed
2024-04-13 23:45:03 +04:00
Ilya Fedin
f57e2edf2a Replace mozjpeg with jpegli in snap 2024-04-11 12:35:47 +04:00
Ilya Fedin
a1e2e3d011 Replace mozjpeg with jpegli in Docker 2024-04-11 12:35:47 +04:00
Ilya Fedin
5e546d1198 Update libjxl in Docker & snap 2024-04-11 12:35:47 +04:00
Ilya Fedin
90405f3ebc Install protobuf in Docker 2024-04-11 12:15:55 +04:00
Nyan
11b57ff7d3 Update data_document_resolver.cpp
The correct python zipapp extension on windows is pyzw, this typo could lead to executing code in the client device without proper warning
2024-04-11 11:24:15 +04:00
Ilya Fedin
fe06cd63ac Lock event loop 2024-04-09 20:48:47 +04:00
John Preston
6c9d5e1499 Improve clipboard QR code image logo quality. 2024-04-09 19:05:02 +04:00
John Preston
6ed910de9f Version 4.16.6.
- Show custom emoji preview on long press.
- Fix resume chat bot button disappearance.
- Fix GIF files playback. (regression in 4.16.3.beta)
2024-04-09 15:20:16 +04:00
John Preston
a506b8b25c Support t.me/username?text=.. links. 2024-04-09 15:20:10 +04:00
John Preston
170ebb57c6 Preview custom emoji on long press from the panel. 2024-04-09 12:11:07 +04:00
John Preston
29dd574e22 Fix toggling chatbot replying, fix saving. 2024-04-09 11:55:52 +04:00
John Preston
72770aa76d Add GIF parser to FFmpeg build.
Fixes #27722.
2024-04-09 11:29:19 +04:00
John Preston
7f1c319aee Add interactive mode to prepare script. 2024-04-09 11:29:16 +04:00
John Preston
60805bd916 Version 4.16.5.
- Fix editing privacy for groups and channels invitations.
- Possible fix for the network unresponsiveness after sleep.
- Possible fix for wide range of memory allocator crashes on Linux.
2024-04-08 22:31:07 +04:00
Ilya Fedin
10272ee0cf Revert "Replace jemalloc with scudo"
This reverts commit 960761ef37.
2024-04-08 21:57:25 +04:00
John Preston
7c44cda76e Fix premium users deselection in multi-select field. 2024-04-08 21:56:56 +04:00
John Preston
0152d2c48e Fix possible temp auth key bind freeze. 2024-04-08 21:56:56 +04:00
23rd
c5febce548 Moved out some functions for main menu to separated files. 2024-04-08 17:34:58 +03:00
23rd
129b07c2c0 Improved style of box for all of user's own groups and channels. 2024-04-08 17:02:52 +03:00
23rd
47bf099b88 Fixed updating of field placeholder in compose controls while editing. 2024-04-08 06:55:44 +03:00
23rd
94f1d23788 Fixed behavior to open section with scheduled messages at top. 2024-04-08 04:12:14 +03:00
Ilya Fedin
84ce72ec7a Fix a crash due to half-hidden media viewer 2024-04-07 14:28:51 +04:00
Ilya Fedin
3da8351522 Let Wayland to use QGuiApplication::screenAt (forgotten place) 2024-04-07 14:08:40 +04:00
Ilya Fedin
542153d950 Use nasm from repository 2024-04-07 11:20:46 +04:00
Ilya Fedin
090fdfb458 Add asan libraries to Docker image 2024-04-07 11:20:46 +04:00
John Preston
77835a43a5 Version 4.16.4: Update patches on Linux. 2024-04-07 11:19:23 +04:00
John Preston
1a2a1f1c17 Version 4.16.4.
- Bug fixes and other minor improvements.
2024-04-06 22:59:03 +04:00
John Preston
eaaa704fa4 Check the URL in IV like in attach bots. 2024-04-06 22:59:03 +04:00
John Preston
7803f8e670 Simplify escaping when parsing IV. 2024-04-06 22:59:03 +04:00
Sergey A. Osokin
f36e3c213e Fix build on FreeBSD 13.3 / llvm 17.0.6 / qt 5.15.13 2024-04-06 20:30:08 +04:00
John Preston
6fb1e23ed5 Fix file dialog filter for videos from attach menu. 2024-04-06 13:05:12 +04:00
John Preston
86d0c49e44 Add "Boost Group/Channel" button to chat menu. 2024-04-06 13:05:12 +04:00
John Preston
9251e6faba Use better title in boost box. 2024-04-06 13:05:12 +04:00
John Preston
8f8725e1af Beta version 4.16.3: Fix dav1d in FFmpeg on macOS. 2024-04-05 21:25:20 +04:00
John Preston
0ce6a4cbdb Beta version 4.16.3: Re-enable system proxy (Linux).
This reverts commit 1e6fb202f0.
2024-04-05 20:48:06 +04:00
John Preston
ad3f705f50 Beta version 4.16.3.
- Improve media upload speed.
- Update FFmpeg to 6.1.1.
2024-04-05 15:35:01 +04:00
John Preston
c5847caa91 Update FFmpeg to 6.1.1: Fix AV1 videos. 2024-04-05 14:42:29 +04:00
John Preston
8df6d9db7e Don't update server-time too frequently. 2024-04-05 09:51:20 +04:00
John Preston
a9c1970f41 Send up to 1MB of parts to a single session. 2024-04-05 09:51:20 +04:00
John Preston
c3f0d2ef31 Adaptive upload up to 8 sessions. 2024-04-05 09:51:20 +04:00
John Preston
0dcc439dda Allow upload requests for several files at once. 2024-04-05 09:51:20 +04:00
John Preston
5b0cac47ad Reapply "Use plain vector for prepared upload parts."
This reverts commit f6f8eefaa0.
2024-04-05 09:51:20 +04:00
John Preston
b39e78a4a9 Reapply "Remove SendMediaReady legacy helper."
This reverts commit 09f07a7a9d.
2024-04-05 09:51:20 +04:00
286 changed files with 2623 additions and 21781 deletions

3
.gitmodules vendored
View File

@@ -76,6 +76,9 @@
[submodule "Telegram/lib_webview"]
path = Telegram/lib_webview
url = https://github.com/desktop-app/lib_webview.git
[submodule "Telegram/ThirdParty/jemalloc"]
path = Telegram/ThirdParty/jemalloc
url = https://github.com/jemalloc/jemalloc
[submodule "Telegram/ThirdParty/dispatch"]
path = Telegram/ThirdParty/dispatch
url = https://github.com/apple/swift-corelibs-libdispatch

View File

@@ -460,6 +460,10 @@ PRIVATE
data/business/data_business_info.h
data/business/data_shortcut_messages.cpp
data/business/data_shortcut_messages.h
data/components/scheduled_messages.cpp
data/components/scheduled_messages.h
data/components/sponsored_messages.cpp
data/components/sponsored_messages.h
data/notify/data_notify_settings.cpp
data/notify/data_notify_settings.h
data/notify/data_peer_notify_settings.cpp
@@ -577,14 +581,10 @@ PRIVATE
data/data_send_action.h
data/data_session.cpp
data/data_session.h
data/data_scheduled_messages.cpp
data/data_scheduled_messages.h
data/data_shared_media.cpp
data/data_shared_media.h
data/data_sparse_ids.cpp
data/data_sparse_ids.h
data/data_sponsored_messages.cpp
data/data_sponsored_messages.h
data/data_statistics.h
data/data_stories.cpp
data/data_stories.h
@@ -1459,8 +1459,6 @@ PRIVATE
ui/image/image_location.h
ui/image/image_location_factory.cpp
ui/image/image_location_factory.h
ui/widgets/level_meter.cpp
ui/widgets/level_meter.h
ui/countryinput.cpp
ui/countryinput.h
ui/dynamic_thumbnails.cpp
@@ -1476,6 +1474,8 @@ PRIVATE
ui/search_field_controller.h
ui/text/format_song_document_name.cpp
ui/text/format_song_document_name.h
ui/widgets/label_with_custom_emoji.cpp
ui/widgets/label_with_custom_emoji.h
ui/unread_badge.cpp
ui/unread_badge.h
window/main_window.cpp
@@ -1503,6 +1503,8 @@ PRIVATE
window/window_lock_widgets.h
window/window_main_menu.cpp
window/window_main_menu.h
window/window_main_menu_helpers.cpp
window/window_main_menu_helpers.h
window/window_media_preview.cpp
window/window_media_preview.h
window/window_peer_menu.cpp

View File

@@ -309,7 +309,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_edit_limit_reached#one" = "You've reached the message text limit. Please make the text shorter by {count} character.";
"lng_edit_limit_reached#other" = "You've reached the message text limit. Please make the text shorter by {count} characters.";
"lng_edit_message" = "Edit message";
"lng_edit_message_text" = "New message text...";
"lng_edit_message_text" = "Caption";
"lng_deleted" = "Deleted Account";
"lng_deleted_message" = "Deleted message";
"lng_deleted_story" = "Deleted story";
@@ -734,6 +734,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_sensitive_disable_filtering" = "Disable filtering";
"lng_settings_sensitive_about" = "Display sensitive media in public channels on all your Telegram devices.";
"lng_settings_security_bots" = "Bots and websites";
"lng_settings_file_confirmations" = "File open confirmations";
"lng_settings_edit_extensions" = "Extensions whitelist";
"lng_settings_edit_extensions_about" = "Open files with the following extensions without additional confirmation.";
"lng_settings_edit_ip_confirm" = "IP reveal warning";
"lng_settings_edit_ip_confirm_about" = "Show confirmation when opening files that may reveal your IP address.";
"lng_settings_clear_payment_info" = "Clear Payment and Shipping Info";
"lng_settings_logged_in" = "Connected websites";
"lng_settings_logged_in_title" = "Logged in with Telegram";
@@ -4480,10 +4485,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_translate_settings_about" = "The 'Translate' button will appear when you open a context menu on a text message.";
"lng_translate_settings_one" = "Please choose at least one language so that it can be used as the \"Translate to\" language.";
"lng_launch_exe_warning" = "This file has a {extension} extension.\nAre you sure you want to run it?";
"lng_launch_exe_warning" = "This file has {extension} extension.\nAre you sure you want to run it?";
"lng_launch_other_warning" = "This file has {extension} extension.\nAre you sure you want to open it?";
"lng_launch_svg_warning" = "Opening this file can potentially expose your IP address to its sender. Continue?";
"lng_launch_exe_sure" = "Run";
"lng_launch_other_sure" = "Open";
"lng_launch_exe_dont_ask" = "Don't ask me again";
"lng_launch_dont_ask" = "Remember for this file type";
"lng_launch_dont_ask_settings" = "You can later edit trusted file types in Settings > Privacy and Security > File open confirmations.";
"lng_polls_anonymous" = "Anonymous Poll";
"lng_polls_public" = "Poll";

View File

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

View File

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

View File

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

View File

@@ -236,14 +236,14 @@ void SendBotCallbackDataWithPassword(
} else {
return;
}
const auto box = std::make_shared<QPointer<PasscodeBox>>();
auto fields = PasscodeBox::CloudFields::From(state);
fields.customTitle = tr::lng_bots_password_confirm_title();
fields.customDescription
= tr::lng_bots_password_confirm_description(tr::now);
fields.customSubmitButton = tr::lng_passcode_submit();
fields.customCheckCallback = [=](
const Core::CloudPasswordResult &result) {
const Core::CloudPasswordResult &result,
QPointer<PasscodeBox> box) {
if (const auto button = getButton()) {
if (button->requestId) {
return;
@@ -257,18 +257,17 @@ void SendBotCallbackDataWithPassword(
return;
}
SendBotCallbackData(strongController, item, row, column, result, [=] {
if (*box) {
(*box)->closeBox();
if (box) {
box->closeBox();
}
}, [=](const QString &error) {
if (*box) {
(*box)->handleCustomCheckError(error);
if (box) {
box->handleCustomCheckError(error);
}
});
}
};
auto object = Box<PasscodeBox>(session, fields);
*box = Ui::MakeWeak(object.data());
show->showBox(std::move(object), Ui::LayerOption::CloseOther);
}, *lifetime);
}

View File

@@ -112,8 +112,8 @@ void ApplyLastList(
channel->mgInfo->lastAdmins.clear();
channel->mgInfo->lastRestricted.clear();
channel->mgInfo->lastParticipants.clear();
channel->mgInfo->lastParticipantsStatus =
MegagroupInfo::LastParticipantsUpToDate
channel->mgInfo->lastParticipantsStatus
= MegagroupInfo::LastParticipantsUpToDate
| MegagroupInfo::LastParticipantsOnceReceived;
auto botStatus = channel->mgInfo->botStatus;

View File

@@ -58,25 +58,33 @@ void HandleWithdrawalButton(
state->loading = false;
auto fields = PasscodeBox::CloudFields::From(pass);
fields.customTitle =
tr::lng_channel_earn_balance_password_title();
fields.customDescription =
tr::lng_channel_earn_balance_password_description(tr::now);
fields.customTitle
= tr::lng_channel_earn_balance_password_title();
fields.customDescription
= tr::lng_channel_earn_balance_password_description(tr::now);
fields.customSubmitButton = tr::lng_passcode_submit();
fields.customCheckCallback = crl::guard(button, [=](
const Core::CloudPasswordResult &result) {
const Core::CloudPasswordResult &result,
QPointer<PasscodeBox> box) {
const auto done = [=](const QString &result) {
if (!result.isEmpty()) {
UrlClickHandler::Open(result);
if (box) {
box->closeBox();
}
}
};
const auto fail = [=](const QString &error) {
show->showToast(error);
};
session->api().request(
MTPstats_GetBroadcastRevenueWithdrawalUrl(
channel->inputChannel,
result.result
)).done([=](const MTPstats_BroadcastRevenueWithdrawalUrl &r) {
const auto url = qs(r.data().vurl());
if (!url.isEmpty()) {
UrlClickHandler::Open(url);
}
done(qs(r.data().vurl()));
}).fail([=](const MTP::Error &error) {
show->showToast(error.type());
fail(error.type());
}).send();
});
show->show(Box<PasscodeBox>(session, fields));

View File

@@ -12,12 +12,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_text_entities.h"
#include "ui/boxes/confirm_box.h"
#include "data/business/data_shortcut_messages.h"
#include "data/components/scheduled_messages.h"
#include "data/data_histories.h"
#include "data/data_scheduled_messages.h"
#include "data/data_session.h"
#include "data/data_web_page.h"
#include "history/history.h"
#include "history/history_item.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "mtproto/mtproto_response.h"
@@ -29,20 +28,20 @@ namespace {
using namespace rpl::details;
template <typename T>
constexpr auto WithId =
is_callable_plain_v<T, Fn<void()>, mtpRequestId>;
constexpr auto WithId
= is_callable_plain_v<T, Fn<void()>, mtpRequestId>;
template <typename T>
constexpr auto WithoutId =
is_callable_plain_v<T, Fn<void()>>;
constexpr auto WithoutId
= is_callable_plain_v<T, Fn<void()>>;
template <typename T>
constexpr auto WithoutCallback =
is_callable_plain_v<T>;
constexpr auto WithoutCallback
= is_callable_plain_v<T>;
template <typename T>
constexpr auto ErrorWithId =
is_callable_plain_v<T, QString, mtpRequestId>;
constexpr auto ErrorWithId
= is_callable_plain_v<T, QString, mtpRequestId>;
template <typename T>
constexpr auto ErrorWithoutId =
is_callable_plain_v<T, QString>;
constexpr auto ErrorWithoutId
= is_callable_plain_v<T, QString>;
template <typename DoneCallback, typename FailCallback>
mtpRequestId EditMessage(
@@ -95,7 +94,7 @@ mtpRequestId EditMessage(
: emptyFlag);
const auto id = item->isScheduled()
? session->data().scheduledMessages().lookupId(item)
? session->scheduledMessages().lookupId(item)
: item->isBusinessShortcut()
? session->data().shortcutMessages().lookupId(item)
: item->id;

View File

@@ -34,7 +34,7 @@ namespace {
constexpr auto kSharedMediaLimit = 100;
[[nodiscard]] SendMediaReady PreparePeerPhoto(
[[nodiscard]] std::shared_ptr<FilePrepareResult> PreparePeerPhoto(
MTP::DcId dcId,
PeerId peerId,
QImage &&image) {
@@ -80,24 +80,17 @@ constexpr auto kSharedMediaLimit = 100;
MTPVector<MTPVideoSize>(),
MTP_int(dcId));
QString file, filename;
int64 filesize = 0;
QByteArray data;
return SendMediaReady(
SendMediaType::Photo,
file,
filename,
filesize,
data,
id,
id,
u"jpg"_q,
peerId,
photo,
photoThumbs,
MTP_documentEmpty(MTP_long(0)),
jpeg);
auto result = MakePreparedFile({
.id = id,
.type = SendMediaType::Photo,
});
result->type = SendMediaType::Photo;
result->setFileData(jpeg);
result->thumbId = id;
result->thumbname = "thumb.jpg";
result->photo = photo;
result->photoThumbs = photoThumbs;
return result;
}
[[nodiscard]] std::optional<MTPVideoSize> PrepareMtpMarkup(
@@ -239,7 +232,7 @@ void PeerPhoto::upload(
_api.instance().mainDcId(),
peer->id,
base::take(photo.image));
_session->uploader().uploadMedia(fakeId, ready);
_session->uploader().upload(fakeId, ready);
}
}

View File

@@ -24,16 +24,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Api {
namespace {
SendMediaReady PrepareRingtoneDocument(
std::shared_ptr<FilePrepareResult> PrepareRingtoneDocument(
MTP::DcId dcId,
const QString &filename,
const QString &filemime,
const QByteArray &content) {
const auto id = base::RandomValue<DocumentId>();
auto attributes = QVector<MTPDocumentAttribute>(
1,
MTP_documentAttributeFilename(MTP_string(filename)));
const auto id = base::RandomValue<DocumentId>();
const auto document = MTP_document(
auto result = MakePreparedFile({
.id = id,
.type = SendMediaType::File,
});
result->filename = filename;
result->content = content;
result->filesize = content.size();
result->setFileData(content);
result->document = MTP_document(
MTP_flags(0),
MTP_long(id),
MTP_long(0),
@@ -45,21 +54,7 @@ SendMediaReady PrepareRingtoneDocument(
MTPVector<MTPVideoSize>(),
MTP_int(dcId),
MTP_vector<MTPDocumentAttribute>(std::move(attributes)));
return SendMediaReady(
SendMediaType::File,
QString(), // filepath
filename,
content.size(),
content,
id,
0,
QString(),
PeerId(),
MTP_photoEmpty(MTP_long(0)),
PreparedPhotoThumbs(),
document,
QByteArray());
return result;
}
} // namespace
@@ -102,7 +97,7 @@ void Ringtones::upload(
_uploads.erase(already);
}
_uploads.emplace(fakeId, uploadedData);
_session->uploader().uploadMedia(fakeId, ready);
_session->uploader().upload(fakeId, ready);
}
void Ringtones::ready(const FullMsgId &msgId, const MTPInputFile &file) {

View File

@@ -353,7 +353,7 @@ void FillMessagePostFlags(
void SendConfirmedFile(
not_null<Main::Session*> session,
const std::shared_ptr<FileLoadResult> &file) {
const std::shared_ptr<FilePrepareResult> &file) {
const auto isEditing = (file->type != SendMediaType::Audio)
&& (file->to.replaceMediaOf != 0);
const auto newId = FullMsgId(

View File

@@ -14,7 +14,7 @@ class Session;
class History;
class PhotoData;
class DocumentData;
struct FileLoadResult;
struct FilePrepareResult;
namespace Api {
@@ -40,6 +40,6 @@ void FillMessagePostFlags(
void SendConfirmedFile(
not_null<Main::Session*> session,
const std::shared_ptr<FileLoadResult> &file);
const std::shared_ptr<FilePrepareResult> &file);
} // namespace Api

View File

@@ -860,6 +860,7 @@ void EarnStatistics::requestHistory(
.token = Data::EarnHistorySlice::OffsetToken(nextToken),
});
}).fail([=] {
done({});
_requestId = 0;
}).send();
}

View File

@@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/mtproto_config.h"
#include "mtproto/mtproto_dc_options.h"
#include "data/business/data_shortcut_messages.h"
#include "data/components/scheduled_messages.h"
#include "data/notify/data_notify_settings.h"
#include "data/stickers/data_stickers.h"
#include "data/data_saved_messages.h"
@@ -37,7 +38,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_histories.h"
#include "data/data_folder.h"
#include "data/data_forum.h"
#include "data/data_scheduled_messages.h"
#include "data/data_send_action.h"
#include "data/data_stories.h"
#include "data/data_message_reactions.h"
@@ -94,7 +94,7 @@ void ProcessScheduledMessageWithElapsedTime(
// Note that when a message is scheduled until online
// while the recipient is already online, the server sends
// an ordinary new message with skipped "from_scheduled" flag.
session->data().scheduledMessages().checkEntitiesAndUpdate(data);
session->scheduledMessages().checkEntitiesAndUpdate(data);
}
}
@@ -1464,7 +1464,9 @@ void Updates::applyUpdates(
if (const auto id = owner.messageIdByRandomId(randomId)) {
const auto local = owner.message(id);
if (local && local->isScheduled()) {
owner.scheduledMessages().sendNowSimpleMessage(d, local);
session().scheduledMessages().sendNowSimpleMessage(
d,
local);
}
}
const auto wasAlready = (lookupMessage() != nullptr);
@@ -1561,7 +1563,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
auto &owner = session().data();
if (const auto local = owner.message(id)) {
if (local->isScheduled()) {
session().data().scheduledMessages().apply(d, local);
session().scheduledMessages().apply(d, local);
} else if (local->isBusinessShortcut()) {
session().data().shortcutMessages().apply(d, local);
} else {
@@ -1771,12 +1773,12 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateNewScheduledMessage: {
const auto &d = update.c_updateNewScheduledMessage();
session().data().scheduledMessages().apply(d);
session().scheduledMessages().apply(d);
} break;
case mtpc_updateDeleteScheduledMessages: {
const auto &d = update.c_updateDeleteScheduledMessages();
session().data().scheduledMessages().apply(d);
session().scheduledMessages().apply(d);
} break;
case mtpc_updateQuickReplies: {

View File

@@ -307,8 +307,8 @@ void UserPrivacy::reload(Key key) {
}
void UserPrivacy::pushPrivacy(Key key, const TLRules &rules) {
const auto &saved = (_privacyValues[key] =
TLToRules(rules, _session->data()));
const auto &saved
= (_privacyValues[key] = TLToRules(rules, _session->data()));
const auto i = _privacyChanges.find(key);
if (i != end(_privacyChanges)) {
i->second.fire_copy(saved);

View File

@@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_user_names.h"
#include "api/api_websites.h"
#include "data/business/data_shortcut_messages.h"
#include "data/components/scheduled_messages.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_changes.h"
#include "data/data_web_page.h"
@@ -43,7 +44,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_forum.h"
#include "data/data_saved_sublist.h"
#include "data/data_search_controller.h"
#include "data/data_scheduled_messages.h"
#include "data/data_session.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
@@ -542,7 +542,7 @@ void ApiWrap::sendMessageFail(
}
}
} else if (error == u"SCHEDULE_STATUS_PRIVATE"_q) {
auto &scheduled = _session->data().scheduledMessages();
auto &scheduled = _session->scheduledMessages();
Assert(peer->isUser());
if (const auto item = scheduled.lookupItem(peer->id, itemId.msg)) {
scheduled.removeSending(item);
@@ -1544,8 +1544,8 @@ void ApiWrap::saveStickerSets(
writeRecent = true;
}
const auto isAttached =
(removedSetId == Data::Stickers::CloudRecentAttachedSetId);
const auto isAttached
= (removedSetId == Data::Stickers::CloudRecentAttachedSetId);
const auto flags = isAttached
? MTPmessages_ClearRecentStickers::Flag::f_attached
: MTPmessages_ClearRecentStickers::Flags(0);
@@ -2447,8 +2447,8 @@ void ApiWrap::refreshFileReference(
_session->data().peer(storyId.peer)->input,
MTP_vector<MTPint>(1, MTP_int(storyId.story))));
} else if (item->isScheduled()) {
const auto &scheduled = _session->data().scheduledMessages();
const auto realId = scheduled.lookupId(item);
const auto realId = _session->scheduledMessages().lookupId(
item);
request(MTPmessages_GetScheduledMessages(
item->history()->peer->input,
MTP_vector<MTPint>(1, MTP_int(realId))));
@@ -2494,8 +2494,8 @@ void ApiWrap::refreshFileReference(
}, [&](Data::FileOriginPeerPhoto data) {
fail();
}, [&](Data::FileOriginStickerSet data) {
const auto isRecentAttached =
(data.setId == Data::Stickers::CloudRecentAttachedSetId);
const auto isRecentAttached
= (data.setId == Data::Stickers::CloudRecentAttachedSetId);
if (data.setId == Data::Stickers::CloudRecentSetId
|| data.setId == Data::Stickers::RecentSetId
|| isRecentAttached) {

View File

@@ -605,8 +605,8 @@ void GroupInfoBox::prepare() {
_navigation->session().api().selfDestruct().reload();
const auto top = addTopButton(st::infoTopBarMenu);
const auto menu =
top->lifetime().make_state<base::unique_qptr<Ui::PopupMenu>>();
const auto menu
= top->lifetime().make_state<base::unique_qptr<Ui::PopupMenu>>();
top->setClickedCallback([=] {
*menu = base::make_unique_q<Ui::PopupMenu>(
top,
@@ -1306,8 +1306,8 @@ void SetupChannelBox::handleChange() {
&& (ch < 'a' || ch > 'z')
&& (ch < '0' || ch > '9')
&& ch != '_') {
const auto badSymbols =
tr::lng_create_channel_link_bad_symbols(tr::now);
const auto badSymbols
= tr::lng_create_channel_link_bad_symbols(tr::now);
if (_errorText != badSymbols) {
_errorText = badSymbols;
update();
@@ -1317,8 +1317,8 @@ void SetupChannelBox::handleChange() {
}
}
if (name.size() < Ui::EditPeer::kMinUsernameLength) {
const auto tooShort =
tr::lng_create_channel_link_too_short(tr::now);
const auto tooShort
= tr::lng_create_channel_link_too_short(tr::now);
if (_errorText != tooShort) {
_errorText = tooShort;
update();

View File

@@ -593,11 +593,11 @@ void BackgroundPreviewBox::uploadForPeer(bool both) {
const auto ready = Window::Theme::PrepareWallPaper(
session->mainDcId(),
_paper.localThumbnail()->original());
const auto documentId = ready.id;
const auto documentId = ready->id;
_uploadId = FullMsgId(
session->userPeerId(),
session->data().nextLocalMessageId());
session->uploader().uploadMedia(_uploadId, ready);
session->uploader().upload(_uploadId, ready);
if (_uploadLifetime) {
return;
}

View File

@@ -232,8 +232,8 @@ void DeleteMessagesBox::prepare() {
if (hasScheduledMessages()) {
} else if (auto revoke = revokeText(peer)) {
const auto &settings = Core::App().settings();
const auto revokeByDefault =
!settings.rememberedDeleteMessageOnlyForYou();
const auto revokeByDefault
= !settings.rememberedDeleteMessageOnlyForYou();
_revoke.create(
this,
revoke->checkbox,

View File

@@ -159,10 +159,7 @@ public:
-> rpl::producer<RowSelectionChange>;
private:
[[nodiscard]] std::unique_ptr<PeerListRow> createRow() const;
const not_null<Main::Session*> _session;
bool _premiums = false;
rpl::event_stream<> _selectionChanged;
rpl::event_stream<RowSelectionChange> _rowSelectionChanges;
@@ -209,8 +206,7 @@ bool PremiumsRow::useForumLikeUserpic() const {
TypesController::TypesController(
not_null<Main::Session*> session,
bool premiums)
: _session(session)
, _premiums(premiums) {
: _session(session) {
}
Main::Session &TypesController::session() const {
@@ -331,6 +327,9 @@ auto PrivacyExceptionsBoxController::preparePremiumsRowList()
_deselectOption = [=](PeerListRowId itemId) {
if (const auto row = _typesDelegate->peerListFindRow(itemId)) {
if (itemId == kPremiumsRowId) {
_selected.premiums = false;
}
_typesDelegate->peerListSetRowChecked(row, false);
}
};

View File

@@ -16,7 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/peers/prepare_short_info_box.h"
#include "boxes/peers/replace_boost_box.h" // BoostsForGift.
#include "boxes/premium_preview_box.h" // ShowPremiumPreviewBox.
#include "core/ui_integration.h" // Core::MarkedTextContext.
#include "data/data_boosts.h"
#include "data/data_changes.h"
#include "data/data_channel.h"
@@ -48,6 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/toast/toast.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/gradient_round_button.h"
#include "ui/widgets/label_with_custom_emoji.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/wrap/table_layout.h"
@@ -319,21 +319,20 @@ void GiftBox(
std::move(titleLabel)),
st::premiumGiftTitlePadding);
auto textLabel = object_ptr<Ui::FlatLabel>(box, st::premiumPreviewAbout);
tr::lng_premium_gift_about(
lt_user,
user->session().changes().peerFlagsValue(
user,
Data::PeerUpdate::Flag::Name
) | rpl::map([=] { return TextWithEntities{ user->firstName }; }),
Ui::Text::RichLangValue
) | rpl::map(
BoostsForGiftText({ user })
) | rpl::start_with_next([
raw = textLabel.data(),
session = &user->session()](const TextWithEntities &t) {
raw->setMarkedText(t, Core::MarkedTextContext{ .session = session });
}, textLabel->lifetime());
auto textLabel = Ui::CreateLabelWithCustomEmoji(
box,
tr::lng_premium_gift_about(
lt_user,
user->session().changes().peerFlagsValue(
user,
Data::PeerUpdate::Flag::Name
) | rpl::map([=] { return TextWithEntities{ user->firstName }; }),
Ui::Text::RichLangValue
) | rpl::map(
BoostsForGiftText({ user })
),
{ .session = &user->session() },
st::premiumPreviewAbout);
textLabel->setTextColorOverride(stTitle.textFg->c);
textLabel->resizeToWidth(available);
box->addRow(
@@ -536,14 +535,12 @@ void GiftsBox(
const auto label = box->addRow(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
box,
object_ptr<Ui::FlatLabel>(box, st::premiumPreviewAbout)),
Ui::CreateLabelWithCustomEmoji(
box,
std::move(text),
{ .session = session },
st::premiumPreviewAbout)),
padding)->entity();
std::move(
text
) | rpl::start_with_next([=](const TextWithEntities &t) {
using namespace Core;
label->setMarkedText(t, MarkedTextContext{ .session = session });
}, label->lifetime());
label->setTextColorOverride(stTitle.textFg->c);
label->resizeToWidth(available);
}

View File

@@ -740,7 +740,7 @@ void PasscodeBox::submitOnlyCheckCloudPassword(const QString &oldPassword) {
void PasscodeBox::sendOnlyCheckCloudPassword(const QString &oldPassword) {
checkPassword(oldPassword, [=](const Core::CloudPasswordResult &check) {
if (const auto onstack = _cloudFields.customCheckCallback) {
onstack(check);
onstack(check, Ui::MakeWeak(this));
} else {
Assert(_cloudFields.turningOff);
sendClearCloudPassword(check);

View File

@@ -51,7 +51,10 @@ public:
TimeId pendingResetDate = 0;
// Check cloud password for some action.
Fn<void(const Core::CloudPasswordResult &)> customCheckCallback;
using CustomCheck = Fn<void(
const Core::CloudPasswordResult &,
QPointer<PasscodeBox>)>;
CustomCheck customCheckCallback;
rpl::producer<QString> customTitle;
std::optional<QString> customDescription;
rpl::producer<QString> customSubmitButton;

View File

@@ -1039,11 +1039,9 @@ void PeerListContent::changeCheckState(
not_null<PeerListRow*> row,
bool checked,
anim::type animated) {
row->setChecked(
checked,
_st.item.checkbox,
animated,
[=] { updateRow(row); });
row->setChecked(checked, _st.item.checkbox, animated, [=] {
updateRow(row);
});
}
void PeerListContent::setRowHidden(not_null<PeerListRow*> row, bool hidden) {

View File

@@ -598,19 +598,17 @@ void EditAdminBox::requestTransferPassword(not_null<ChannelData*> channel) {
) | rpl::take(
1
) | rpl::start_with_next([=](const Core::CloudPasswordState &state) {
const auto box = std::make_shared<QPointer<PasscodeBox>>();
auto fields = PasscodeBox::CloudFields::From(state);
fields.customTitle = tr::lng_rights_transfer_password_title();
fields.customDescription
= tr::lng_rights_transfer_password_description(tr::now);
fields.customSubmitButton = tr::lng_passcode_submit();
fields.customCheckCallback = crl::guard(this, [=](
const Core::CloudPasswordResult &result) {
sendTransferRequestFrom(*box, channel, result);
const Core::CloudPasswordResult &result,
QPointer<PasscodeBox> box) {
sendTransferRequestFrom(box, channel, result);
});
*box = getDelegate()->show(Box<PasscodeBox>(
&channel->session(),
fields));
getDelegate()->show(Box<PasscodeBox>(&channel->session(), fields));
}, lifetime());
}

View File

@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "ui/layers/generic_box.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/labels.h"
#include "styles/style_layers.h"
@@ -23,6 +24,17 @@ void EditPeerHistoryVisibilityBox(
Ui::RadioenumGroup<HistoryVisibility>
>(historyVisibilitySavedValue);
const auto addButton = [=](
not_null<Ui::RpWidget*> inner,
HistoryVisibility v) {
const auto button = Ui::CreateChild<Ui::AbstractButton>(inner.get());
inner->sizeValue(
) | rpl::start_with_next([=](const QSize &s) {
button->resize(s);
}, button->lifetime());
button->setClickedCallback([=] { historyVisibility->setValue(v); });
};
box->setTitle(tr::lng_manage_history_visibility_title());
box->addButton(tr::lng_settings_save(), [=] {
savedCallback(historyVisibility->current());
@@ -31,32 +43,36 @@ void EditPeerHistoryVisibilityBox(
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
box->addSkip(st::editPeerHistoryVisibilityTopSkip);
box->addRow(object_ptr<Ui::Radioenum<HistoryVisibility>>(
const auto visible = box->addRow(object_ptr<Ui::VerticalLayout>(box));
visible->add(object_ptr<Ui::Radioenum<HistoryVisibility>>(
box,
historyVisibility,
HistoryVisibility::Visible,
tr::lng_manage_history_visibility_shown(tr::now),
st::defaultBoxCheckbox));
box->addRow(
visible->add(
object_ptr<Ui::FlatLabel>(
box,
tr::lng_manage_history_visibility_shown_about(),
st::editPeerPrivacyLabel),
st::editPeerPreHistoryLabelMargins + st::boxRowPadding);
st::editPeerPreHistoryLabelMargins);
addButton(visible, HistoryVisibility::Visible);
box->addSkip(st::editPeerHistoryVisibilityTopSkip);
box->addRow(object_ptr<Ui::Radioenum<HistoryVisibility>>(
const auto hidden = box->addRow(object_ptr<Ui::VerticalLayout>(box));
hidden->add(object_ptr<Ui::Radioenum<HistoryVisibility>>(
box,
historyVisibility,
HistoryVisibility::Hidden,
tr::lng_manage_history_visibility_hidden(tr::now),
st::defaultBoxCheckbox));
box->addRow(
hidden->add(
object_ptr<Ui::FlatLabel>(
box,
(isLegacy
? tr::lng_manage_history_visibility_hidden_legacy
: tr::lng_manage_history_visibility_hidden_about)(),
st::editPeerPrivacyLabel),
st::editPeerPreHistoryLabelMargins + st::boxRowPadding);
st::editPeerPreHistoryLabelMargins);
addButton(hidden, HistoryVisibility::Hidden);
}

View File

@@ -983,8 +983,8 @@ void Controller::fillHistoryVisibilityButton() {
: HistoryVisibility::Visible;
_channelHasLocationOriginalValue = channel && channel->hasLocation();
const auto updateHistoryVisibility =
std::make_shared<rpl::event_stream<HistoryVisibility>>();
const auto updateHistoryVisibility
= std::make_shared<rpl::event_stream<HistoryVisibility>>();
const auto boxCallback = crl::guard(this, [=](HistoryVisibility checked) {
updateHistoryVisibility->fire(std::move(checked));
@@ -1698,8 +1698,8 @@ void Controller::saveUsernamesOrder() {
channel->setUsernames(ranges::views::all(
newUsernames
) | ranges::views::transform([&](QString username) {
const auto editable =
(channel->editableUsername() == username);
const auto editable
= (channel->editableUsername() == username);
return Data::Username{
.username = std::move(username),
.active = true,

View File

@@ -227,9 +227,9 @@ QImage QrExact(const Qr::Data &data, int pixel, QColor color) {
p.drawImage(
skip,
skip,
Intro::details::TelegramLogoImage().scaled(
logoSize * style::DevicePixelRatio(),
logoSize * style::DevicePixelRatio(),
Window::LogoNoMargin().scaled(
logoSize,
logoSize,
Qt::IgnoreAspectRatio,
Qt::SmoothTransformation));
}

View File

@@ -1240,8 +1240,8 @@ void DecorateListPromoBox(
box->setStyle(st::premiumPreviewDoubledLimitsBox);
box->widthValue(
) | rpl::start_with_next([=](int width) {
const auto &padding =
st::premiumPreviewDoubledLimitsBox.buttonPadding;
const auto &padding
= st::premiumPreviewDoubledLimitsBox.buttonPadding;
button->resizeToWidth(width
- padding.left()
- padding.right());

View File

@@ -90,7 +90,7 @@ QString ExtractRingtoneName(not_null<DocumentData*> document) {
}
const auto name = document->filename();
if (!name.isEmpty()) {
const auto extension = Data::FileExtension(name);
const auto extension = Core::FileExtension(name);
if (extension.isEmpty()) {
return name;
} else if (name.size() > extension.size() + 1) {

View File

@@ -569,8 +569,8 @@ void StickerSetBox::updateButtons() {
if (!_inner->shortName().isEmpty()) {
const auto top = addTopButton(st::infoTopBarMenu);
const auto menu =
std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
const auto menu
= std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
top->setClickedCallback([=] {
*menu = base::make_unique_q<Ui::PopupMenu>(
top,
@@ -613,8 +613,8 @@ void StickerSetBox::updateButtons() {
_show->showBox(std::move(box));
}
};
const auto menu =
std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
const auto menu
= std::make_shared<base::unique_qptr<Ui::PopupMenu>>();
top->setClickedCallback([=] {
*menu = base::make_unique_q<Ui::PopupMenu>(
top,

View File

@@ -945,8 +945,8 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
tgcalls::Descriptor descriptor = {
.version = versionString,
.config = tgcalls::Config{
.initializationTimeout =
serverConfig.callConnectTimeoutMs / 1000.,
.initializationTimeout
= serverConfig.callConnectTimeoutMs / 1000.,
.receiveTimeout = serverConfig.callPacketTimeoutMs / 1000.,
.dataSaving = tgcalls::DataSaving::Never,
.enableP2P = call.is_p2p_allowed(),

View File

@@ -277,11 +277,11 @@ private:
MTP::Sender _api;
Type _type = Type::Outgoing;
rpl::variable<State> _state = State::Starting;
rpl::variable<RemoteAudioState> _remoteAudioState =
RemoteAudioState::Active;
rpl::variable<RemoteAudioState> _remoteAudioState
= RemoteAudioState::Active;
rpl::variable<Webrtc::VideoState> _remoteVideoState;
rpl::variable<RemoteBatteryState> _remoteBatteryState =
RemoteBatteryState::Normal;
rpl::variable<RemoteBatteryState> _remoteBatteryState
= RemoteBatteryState::Normal;
rpl::event_stream<Error> _errors;
FinishType _finishAfterRequestingCall = FinishType::None;
bool _answerAfterDhConfigReceived = false;

View File

@@ -162,8 +162,8 @@ private:
object_ptr<Ui::FlatLabel> _status;
object_ptr<Ui::RpWidget> _fingerprint = { nullptr };
object_ptr<Ui::PaddingWrap<Ui::FlatLabel>> _remoteAudioMute = { nullptr };
object_ptr<Ui::PaddingWrap<Ui::FlatLabel>> _remoteLowBattery =
{ nullptr };
object_ptr<Ui::PaddingWrap<Ui::FlatLabel>> _remoteLowBattery
= { nullptr };
std::unique_ptr<Userpic> _userpic;
std::unique_ptr<VideoBubble> _outgoingVideoBubble;
QPixmap _bottomShadow;

View File

@@ -25,8 +25,8 @@ const auto kSpeakerThreshold = std::vector<float>{
50.0f / kMaxVolumePercent,
150.0f / kMaxVolumePercent };
constexpr auto kVolumeStickedValues =
std::array<std::pair<float64, float64>, 7>{{
constexpr auto kVolumeStickedValues
= std::array<std::pair<float64, float64>, 7>{{
{ 25. / kMaxVolumePercent, 2. / kMaxVolumePercent },
{ 50. / kMaxVolumePercent, 2. / kMaxVolumePercent },
{ 75. / kMaxVolumePercent, 2. / kMaxVolumePercent },
@@ -93,8 +93,8 @@ MenuVolumeItem::MenuVolumeItem(
const auto volume = _localMuted
? 0
: base::SafeRound(_slider->value() * kMaxVolumePercent);
const auto muteProgress =
_crossLineAnimation.value((!volume) ? 1. : 0.);
const auto muteProgress
= _crossLineAnimation.value((!volume) ? 1. : 0.);
const auto selected = isSelected();
p.fillRect(clip, selected ? st.itemBgOver : st.itemBg);
@@ -174,8 +174,8 @@ MenuVolumeItem::MenuVolumeItem(
return;
}
if (_waitingForUpdateVolume) {
const auto localVolume =
base::SafeRound(_slider->value() * _maxVolume);
const auto localVolume
= base::SafeRound(_slider->value() * _maxVolume);
if ((localVolume != newVolume)
&& (_cloudVolume == newVolume)) {
_changeVolumeRequests.fire(int(localVolume));

View File

@@ -587,11 +587,9 @@ void ChooseSourceProcess::setupGeometryWithParent(
not_null<QWidget*> parent) {
_window->createWinId();
const auto parentScreen = [&] {
if (!::Platform::IsWayland()) {
if (const auto screen = QGuiApplication::screenAt(
if (const auto screen = QGuiApplication::screenAt(
parent->geometry().center())) {
return screen;
}
return screen;
}
return parent->screen();
}();

View File

@@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_changes.h"
#include "data/data_channel.h"
#include "data/data_document.h"
#include "data/data_file_origin.h"
#include "data/data_peer_values.h"
#include "data/stickers/data_stickers.h"
#include "data/stickers/data_custom_emoji.h"
@@ -51,12 +52,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_chat_helpers.h"
#include "styles/style_menu_icons.h"
#include <QtWidgets/QApplication>
namespace ChatHelpers {
namespace {
constexpr auto kCollapsedRows = 3;
constexpr auto kAppearDuration = 0.3;
constexpr auto kCustomSearchLimit = 256;
constexpr auto kColorPickerDelay = crl::time(500);
using Core::RecentEmojiId;
using Core::RecentEmojiDocument;
@@ -477,7 +481,8 @@ EmojiListWidget::EmojiListWidget(
, _overBg(st::emojiPanRadius, st().overBg)
, _collapsedBg(st::emojiPanExpand.height / 2, st().headerFg)
, _picker(this, st())
, _showPickerTimer([=] { showPicker(); }) {
, _showPickerTimer([=] { showPicker(); })
, _previewTimer([=] { showPreview(); }) {
setMouseTracking(true);
if (st().bg->c.alpha() > 0) {
setAttribute(Qt::WA_OpaquePaintEvent);
@@ -624,6 +629,15 @@ void EmojiListWidget::applyNextSearchQuery() {
}
}
void EmojiListWidget::showPreview() {
if (const auto over = std::get_if<OverEmoji>(&_pressed)) {
if (const auto custom = lookupCustomEmoji(over)) {
_show->showMediaPreview(custom->stickerSetOrigin(), custom);
_previewShown = true;
}
}
}
std::vector<EmojiPtr> EmojiListWidget::collectPlainSearchResults() {
return SearchEmoji(_searchQuery, _searchEmoji);
}
@@ -1119,7 +1133,7 @@ void EmojiListWidget::fillRecentMenu(
const auto addAction = Ui::Menu::CreateAddActionCallback(menu);
const auto over = OverEmoji{ section, index };
const auto emoji = lookupOverEmoji(&over);
const auto custom = lookupCustomEmoji(index, section);
const auto custom = lookupCustomEmoji(&over);
if (custom && custom->sticker()) {
const auto sticker = custom->sticker();
const auto emoji = sticker->alt;
@@ -1492,6 +1506,11 @@ bool EmojiListWidget::checkPickerHide() {
return false;
}
DocumentData *EmojiListWidget::lookupCustomEmoji(
const OverEmoji *over) const {
return over ? lookupCustomEmoji(over->index, over->section) : nullptr;
}
DocumentData *EmojiListWidget::lookupCustomEmoji(
int index,
int section) const {
@@ -1594,13 +1613,19 @@ void EmojiListWidget::mousePressEvent(QMouseEvent *e) {
if (!Core::App().settings().hasChosenEmojiVariant(emoji)) {
showPicker();
} else {
_showPickerTimer.callOnce(500);
_previewTimer.cancel();
_showPickerTimer.callOnce(kColorPickerDelay);
}
} else if (lookupCustomEmoji(over)) {
_showPickerTimer.cancel();
_previewTimer.callOnce(QApplication::startDragTime());
}
}
}
void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
_previewTimer.cancel();
auto pressed = _pressed;
setPressed(v::null);
_lastMousePos = e->globalPos();
@@ -1625,7 +1650,10 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
_picker->hide();
}
if (v::is_null(_selected) || _selected != pressed) {
if (_previewShown) {
_previewShown = false;
return;
} else if (v::is_null(_selected) || _selected != pressed) {
return;
}
@@ -1644,7 +1672,7 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
return;
}
selectEmoji(lookupChosen(emoji, over));
} else if (const auto custom = lookupCustomEmoji(index, section)) {
} else if (const auto custom = lookupCustomEmoji(over)) {
selectCustom(lookupChosen(custom, over));
}
} else if (const auto set = std::get_if<OverSet>(&pressed)) {
@@ -2478,7 +2506,9 @@ bool EmojiListWidget::eventHook(QEvent *e) {
void EmojiListWidget::updateSelected() {
if (!v::is_null(_pressed) || !v::is_null(_pickerSelected)) {
return;
if (!_previewShown) {
return;
}
}
auto newSelected = OverState{ v::null };
@@ -2537,6 +2567,13 @@ void EmojiListWidget::setSelected(OverState newSelected) {
} else {
_picker->showAnimated();
}
} else if (_previewShown && _pressed != _selected) {
if (const auto over = std::get_if<OverEmoji>(&_selected)) {
if (const auto custom = lookupCustomEmoji(over)) {
_pressed = _selected;
_show->showMediaPreview(custom->stickerSetOrigin(), custom);
}
}
}
}

View File

@@ -287,6 +287,8 @@ private:
int index);
[[nodiscard]] EmojiPtr lookupOverEmoji(const OverEmoji *over) const;
[[nodiscard]] DocumentData *lookupCustomEmoji(
const OverEmoji *over) const;
[[nodiscard]] DocumentData *lookupCustomEmoji(
int index,
int section) const;
@@ -371,6 +373,8 @@ private:
DocumentId documentId,
uint64 setId);
void showPreview();
void applyNextSearchQuery();
const std::shared_ptr<Show> _show;
@@ -440,6 +444,8 @@ private:
object_ptr<EmojiColorPicker> _picker;
base::Timer _showPickerTimer;
base::Timer _previewTimer;
bool _previewShown = false;
rpl::event_stream<EmojiChosen> _chosen;
rpl::event_stream<FileChosen> _customChosen;

View File

@@ -437,8 +437,8 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
auto filterNotPassedByUsername = [this](UserData *user) -> bool {
if (PrimaryUsername(user).startsWith(_filter, Qt::CaseInsensitive)) {
const auto exactUsername =
(PrimaryUsername(user).size() == _filter.size());
const auto exactUsername
= (PrimaryUsername(user).size() == _filter.size());
return exactUsername;
}
return true;
@@ -446,8 +446,9 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
auto filterNotPassedByName = [&](UserData *user) -> bool {
for (const auto &nameWord : user->nameWords()) {
if (nameWord.startsWith(_filter, Qt::CaseInsensitive)) {
const auto exactUsername =
(PrimaryUsername(user).compare(_filter, Qt::CaseInsensitive) == 0);
const auto exactUsername = PrimaryUsername(user).compare(
_filter,
Qt::CaseInsensitive) == 0;
return exactUsername;
}
}

View File

@@ -933,8 +933,8 @@ void Application::handleAppDeactivated() {
}
rpl::producer<bool> Application::appDeactivatedValue() const {
const auto &app =
static_cast<QGuiApplication*>(QCoreApplication::instance());
const auto &app
= static_cast<QGuiApplication*>(QCoreApplication::instance());
return rpl::single(
app->applicationState()
) | rpl::then(

View File

@@ -313,8 +313,8 @@ CloudPasswordState ParseCloudPasswordState(
ParseCloudPasswordAlgo(data.vnew_algo()));
result.mtp.newSecureSecret = ValidateNewSecureSecretAlgo(
ParseSecureSecretAlgo(data.vnew_secure_algo()));
result.unconfirmedPattern =
qs(data.vemail_unconfirmed_pattern().value_or_empty());
result.unconfirmedPattern = qs(
data.vemail_unconfirmed_pattern().value_or_empty());
result.pendingResetDate = data.vpending_reset_date().value_or_empty();
result.outdatedClient = [&] {

View File

@@ -156,6 +156,10 @@ QByteArray Settings::serialize() const {
const auto &recentEmojiPreloadData = _recentEmojiPreload.empty()
? recentEmojiPreloadGenerated
: _recentEmojiPreload;
const auto noWarningExtensions = QStringList(
begin(_noWarningExtensions),
end(_noWarningExtensions)
).join(' ');
auto size = Serialize::bytearraySize(themesAccentColors)
+ sizeof(qint32) * 5
@@ -212,7 +216,8 @@ QByteArray Settings::serialize() const {
+ Serialize::stringSize(_captureDeviceId.current())
+ Serialize::stringSize(_callPlaybackDeviceId.current())
+ Serialize::stringSize(_callCaptureDeviceId.current())
+ Serialize::bytearraySize(ivPosition);
+ Serialize::bytearraySize(ivPosition)
+ Serialize::stringSize(noWarningExtensions);
auto result = QByteArray();
result.reserve(size);
@@ -252,7 +257,7 @@ QByteArray Settings::serialize() const {
<< qint32(_sendSubmitWay)
<< qint32(_includeMutedCounter ? 1 : 0)
<< qint32(_countUnreadMessages ? 1 : 0)
<< qint32(_exeLaunchWarning ? 1 : 0)
<< qint32(1) // legacy exe launch warning
<< qint32(_notifyAboutPinned.current() ? 1 : 0)
<< qint32(_loopAnimatedStickers ? 1 : 0)
<< qint32(_largeEmoji.current() ? 1 : 0)
@@ -357,7 +362,8 @@ QByteArray Settings::serialize() const {
<< _captureDeviceId.current()
<< _callPlaybackDeviceId.current()
<< _callCaptureDeviceId.current()
<< ivPosition;
<< ivPosition
<< noWarningExtensions;
}
Ensures(result.size() == size);
@@ -406,7 +412,8 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
qint32 sendSubmitWay = static_cast<qint32>(_sendSubmitWay);
qint32 includeMutedCounter = _includeMutedCounter ? 1 : 0;
qint32 countUnreadMessages = _countUnreadMessages ? 1 : 0;
qint32 exeLaunchWarning = _exeLaunchWarning ? 1 : 0;
std::optional<QString> noWarningExtensions;
qint32 legacyExeLaunchWarning = 1;
qint32 notifyAboutPinned = _notifyAboutPinned.current() ? 1 : 0;
qint32 loopAnimatedStickers = _loopAnimatedStickers ? 1 : 0;
qint32 largeEmoji = _largeEmoji.current() ? 1 : 0;
@@ -513,7 +520,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
>> sendSubmitWay
>> includeMutedCounter
>> countUnreadMessages
>> exeLaunchWarning
>> legacyExeLaunchWarning
>> notifyAboutPinned
>> loopAnimatedStickers
>> largeEmoji
@@ -755,6 +762,10 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
if (!stream.atEnd()) {
stream >> ivPosition;
}
if (!stream.atEnd()) {
noWarningExtensions = QString();
stream >> *noWarningExtensions;
}
if (stream.status() != QDataStream::Ok) {
LOG(("App Error: "
"Bad data for Core::Settings::constructFromSerialized()"));
@@ -817,7 +828,12 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
}
_includeMutedCounter = (includeMutedCounter == 1);
_countUnreadMessages = (countUnreadMessages == 1);
_exeLaunchWarning = (exeLaunchWarning == 1);
if (noWarningExtensions) {
const auto list = noWarningExtensions->mid(0, 10240)
.split(' ', Qt::SkipEmptyParts)
.mid(0, 1024);
_noWarningExtensions = base::flat_set<QString>(list.begin(), list.end());
}
_ipRevealWarning = (ipRevealWarning == 1);
_notifyAboutPinned = (notifyAboutPinned == 1);
_loopAnimatedStickers = (loopAnimatedStickers == 1);
@@ -1283,7 +1299,7 @@ void Settings::resetOnLastLogout() {
//_sendSubmitWay = Ui::InputSubmitSettings::Enter;
_soundOverrides = {};
_exeLaunchWarning = true;
_noWarningExtensions.clear();
_ipRevealWarning = true;
_loopAnimatedStickers = true;
_largeEmoji = true;

View File

@@ -398,11 +398,12 @@ public:
}
[[nodiscard]] QString getSoundPath(const QString &key) const;
[[nodiscard]] bool exeLaunchWarning() const {
return _exeLaunchWarning;
[[nodiscard]] auto noWarningExtensions() const
-> const base::flat_set<QString> & {
return _noWarningExtensions;
}
void setExeLaunchWarning(bool warning) {
_exeLaunchWarning = warning;
void setNoWarningExtensions(base::flat_set<QString> extensions) {
_noWarningExtensions = std::move(extensions);
}
[[nodiscard]] bool ipRevealWarning() const {
return _ipRevealWarning;
@@ -933,7 +934,7 @@ private:
Ui::SendFilesWay _sendFilesWay = Ui::SendFilesWay();
Ui::InputSubmitSettings _sendSubmitWay = Ui::InputSubmitSettings();
base::flat_map<QString, QString> _soundOverrides;
bool _exeLaunchWarning = true;
base::flat_set<QString> _noWarningExtensions;
bool _ipRevealWarning = true;
bool _loopAnimatedStickers = true;
rpl::variable<bool> _largeEmoji = true;
@@ -984,8 +985,8 @@ private:
#else // Q_OS_MAC
bool _hardwareAcceleratedVideo = false;
#endif // Q_OS_MAC
HistoryView::DoubleClickQuickAction _chatQuickAction =
HistoryView::DoubleClickQuickAction();
HistoryView::DoubleClickQuickAction _chatQuickAction
= HistoryView::DoubleClickQuickAction();
bool _translateButtonEnabled = false;
rpl::variable<bool> _translateChatEnabled = true;
rpl::variable<int> _translateToRaw = 0;

View File

@@ -159,7 +159,7 @@ void Launch(const QString &filepath) {
void ShowInFolder(const QString &filepath) {
crl::on_main([=] {
Ui::PreventDelayedActivation();
if (Platform::IsLinux()) {
if (Platform::IsX11()) {
// Hide mediaview to make other apps visible.
Core::App().hideMediaView();
}

View File

@@ -563,6 +563,7 @@ bool ResolveUsernameOrPhone(
.phone = phone,
.messageId = post,
.storyId = storyId,
.text = params.value(u"text"_q),
.repliesInfo = commentId
? Window::RepliesByLinkInfo{
Window::CommentId{ commentId }

View File

@@ -37,6 +37,12 @@ namespace {
&& data->hasImage();
}
[[nodiscard]] base::flat_set<QString> SplitExtensions(
const QString &joined) {
const auto list = joined.split(' ');
return base::flat_set<QString>(list.begin(), list.end());
}
} // namespace
MimeType::MimeType(const QMimeType &type) : _typeStruct(type) {
@@ -162,22 +168,9 @@ bool IsMimeAcceptedForPhotoVideoAlbum(const QString &mime) {
}
bool FileIsImage(const QString &name, const QString &mime) {
QString lowermime = mime.toLower(), namelower = name.toLower();
if (lowermime.startsWith(u"image/"_q)) {
return true;
} else if (namelower.endsWith(u".bmp"_q)
|| namelower.endsWith(u".jpg"_q)
|| namelower.endsWith(u".jpeg"_q)
|| namelower.endsWith(u".gif"_q)
|| namelower.endsWith(u".webp"_q)
|| namelower.endsWith(u".tga"_q)
|| namelower.endsWith(u".tiff"_q)
|| namelower.endsWith(u".tif"_q)
|| namelower.endsWith(u".psd"_q)
|| namelower.endsWith(u".png"_q)) {
return true;
}
return false;
return name.isEmpty()
? mime.toLower().startsWith(u"image/"_q)
: (DetectNameType(name) == NameType::Image);
}
std::shared_ptr<QMimeData> ShareMimeMediaData(
@@ -194,10 +187,10 @@ std::shared_ptr<QMimeData> ShareMimeMediaData(
result->setData(u"application/x-td-use-jpeg"_q, "1");
result->setData(u"image/jpeg"_q, original->data(u"image/jpeg"_q));
}
if (auto list = Core::ReadMimeUrls(original); !list.isEmpty()) {
if (auto list = ReadMimeUrls(original); !list.isEmpty()) {
result->setUrls(std::move(list));
}
result->setText(Core::ReadMimeText(original));
result->setText(ReadMimeText(original));
return result;
}
@@ -240,4 +233,116 @@ bool CanSendFiles(not_null<const QMimeData*> data) {
return false;
}
QString FileExtension(const QString &filepath) {
const auto reversed = ranges::views::reverse(filepath);
const auto last = ranges::find_first_of(reversed, ".\\/");
if (last == reversed.end() || *last != '.') {
return QString();
}
return QString(last.base(), last - reversed.begin());
}
NameType DetectNameType(const QString &filepath) {
static const auto kImage = SplitExtensions(u"\
afdesign ai avif bmp dng gif heic icns ico jfif jpeg jpg jpg-large nef png \
png-large psd raw sketch svg tga tif tiff webp"_q);
static const auto kVideo = SplitExtensions(u"\
3g2 3gp 3gpp aep avi flv h264 m4s m4v mkv mov mp4 mpeg mpg ogv srt tgs tgv \
vob webm wmv"_q);
static const auto kAudio = SplitExtensions(u"\
aac ac3 aif amr caf cda cue flac m4a m4b mid midi mp3 ogg opus wav wma"_q);
static const auto kDocument = SplitExtensions(u"\
pdf doc docx ppt pptx pps ppsx xls xlsx txt rtf odt ods odp csv text log tl \
tex xspf xml djvu diag ps ost kml pub epub mobi cbr cbz fb2 prc ris pem p7b \
m3u m3u8 wpd wpl htm html xhtml key"_q);
static const auto kArchive = SplitExtensions(u"\
7z arj bz2 gz rar tar xz z zip zst"_q);
static const auto kThemeFile = SplitExtensions(u"\
tdesktop-theme tdesktop-palette tgios-theme attheme"_q);
static const auto kOtherBenign = SplitExtensions(u"\
c cc cpp cxx h m mm swift cs ts class java css ninja cmake patch diff plist \
gyp gitignore strings asoundrc torrent csr json xaml md keylayout sql \
sln xib mk \
\
dmg img iso vcd \
\
pdb eot ics ips ipa core mem pcap ovpn part pcapng dmp pkpass dat zxp crash \
file bak gbr plain dlc fon fnt otf ttc ttf gpx db rss cur \
\
tdesktop-endpoints"_q);
static const auto kExecutable = SplitExtensions(
#ifdef Q_OS_WIN
u"\
ad ade adp ahk app application appref-ms asp aspx asx bas bat bin cab cdxml \
cer cfg cgi chi chm cmd cnt com conf cpl crt csh der diagcab dll drv eml \
exe fon fxp gadget grp hlp hpj hta htt inf ini ins inx isp isu its jar jnlp \
job js jse jsp key ksh lexe library-ms lnk local lua mad maf mag mam \
manifest maq mar mas mat mau mav maw mcf mda mdb mde mdt mdw mdz mht mhtml \
mjs mmc mof msc msg msh msh1 msh2 msh1xml msh2xml mshxml msi msp mst ops \
osd paf pcd phar php php3 php4 php5 php7 phps php-s pht phtml pif pl plg pm \
pod prf prg ps1 ps2 ps1xml ps2xml psc1 psc2 psd1 psm1 pssc pst py py3 pyc \
pyd pyi pyo pyw pyzw pyz rb reg rgs scf scr sct search-ms settingcontent-ms \
sh shb shs slk sys swf t tmp u3p url vb vbe vbp vbs vbscript vdx vsmacros \
vsd vsdm vsdx vss vssm vssx vst vstm vstx vsw vsx vtx website wlua ws wsc \
wsf wsh xbap xll xlsm xnk xs"_q
#elif defined Q_OS_MAC // Q_OS_MAC
u"\
applescript action app bin command csh osx workflow terminal url caction \
mpkg pkg scpt scptd xhtm xhtml webarchive"_q
#else // Q_OS_WIN || Q_OS_MAC
u"bin csh deb desktop ksh out pet pkg pup rpm run sh shar slp zsh"_q
#endif // !Q_OS_WIN && !Q_OS_MAC
);
const auto extension = FileExtension(filepath).toLower();
if (kExecutable.contains(extension)) {
return NameType::Executable;
} else if (kImage.contains(extension)) {
return NameType::Image;
} else if (kVideo.contains(extension)) {
return NameType::Video;
} else if (kAudio.contains(extension)) {
return NameType::Audio;
} else if (kDocument.contains(extension)) {
return NameType::Document;
} else if (kArchive.contains(extension)) {
return NameType::Archive;
} else if (kThemeFile.contains(extension)) {
return NameType::ThemeFile;
} else if (kOtherBenign.contains(extension)) {
return NameType::OtherBenign;
}
return NameType::Unknown;
}
bool NameTypeAllowsThumbnail(NameType type) {
return type == NameType::Image
|| type == NameType::Video
|| type == NameType::Audio
|| type == NameType::Document
|| type == NameType::ThemeFile;
}
bool IsIpRevealingPath(const QString &filepath) {
static const auto kExtensions = [] {
const auto joined = u"htm html svg m4v m3u8 xhtml"_q;
const auto list = joined.split(' ');
return base::flat_set<QString>(list.begin(), list.end());
}();
static const auto kMimeTypes = [] {
const auto joined = u"text/html image/svg+xml"_q;
const auto list = joined.split(' ');
return base::flat_set<QString>(list.begin(), list.end());
}();
return ranges::binary_search(
kExtensions,
FileExtension(filepath).toLower()
) || ranges::binary_search(
kMimeTypes,
QMimeDatabase().mimeTypeForFile(QFileInfo(filepath)).name()
);
}
} // namespace Core

View File

@@ -69,4 +69,21 @@ struct MimeImageData {
[[nodiscard]] QList<QUrl> ReadMimeUrls(not_null<const QMimeData*> data);
[[nodiscard]] bool CanSendFiles(not_null<const QMimeData*> data);
enum class NameType : uchar {
Unknown,
Executable,
Image,
Video,
Audio,
Document,
Archive,
ThemeFile,
OtherBenign,
};
[[nodiscard]] QString FileExtension(const QString &filepath);
[[nodiscard]] NameType DetectNameType(const QString &filepath);
[[nodiscard]] bool NameTypeAllowsThumbnail(NameType type);
[[nodiscard]] bool IsIpRevealingPath(const QString &filepath);
} // namespace Core

View File

@@ -33,7 +33,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtGui/QSessionManager>
#include <QtGui/QScreen>
#include <QtGui/qpa/qplatformscreen.h>
#include <ksandbox.h>
namespace Core {
namespace {
@@ -83,7 +82,6 @@ bool Sandbox::QuitOnStartRequested = false;
Sandbox::Sandbox(int &argc, char **argv)
: QApplication(argc, argv)
, _mainThreadId(QThread::currentThreadId()) {
setQuitOnLastWindowClosed(false);
}
int Sandbox::start() {
@@ -518,10 +516,8 @@ void Sandbox::refreshGlobalProxy() {
|| proxy.type == MTP::ProxyData::Type::Http) {
QNetworkProxy::setApplicationProxy(
MTP::ToNetworkProxy(MTP::ToDirectIpProxy(proxy)));
} else if ((!Core::IsAppLaunched()
|| Core::App().settings().proxy().isSystem())
// this works stable only in sandboxed environment where it works through portal
&& (!Platform::IsLinux() || KSandbox::isInside() || cDebugMode())) {
} else if (!Core::IsAppLaunched()
|| Core::App().settings().proxy().isSystem()) {
QNetworkProxyFactory::setUseSystemConfiguration(true);
} else {
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);

View File

@@ -107,6 +107,7 @@ private:
void readClients();
void removeClients();
QEventLoopLocker _eventLoopLocker;
const Qt::HANDLE _mainThreadId = nullptr;
int _eventNestingLevel = 0;
int _loopNestingLevel = 0;

View File

@@ -230,8 +230,24 @@ void WriteDefaultCustomFile() {
const auto path = CustomFilePath();
auto input = QFile(":/misc/default_shortcuts-custom.json");
auto output = QFile(path);
if (input.open(QIODevice::ReadOnly) && output.open(QIODevice::WriteOnly)) {
if (input.open(QIODevice::ReadOnly)
&& output.open(QIODevice::WriteOnly)) {
#ifdef Q_OS_MAC
auto text = qs(input.readAll());
const auto note = R"(
// Note:
// On Apple platforms, reference to "ctrl" corresponds to the Command keys )"
+ QByteArray()
+ R"(on the Macintosh keyboard.
// On Apple platforms, reference to "meta" corresponds to the Control keys.
[
)";
text.replace(u"\n\n["_q, QString(note));
output.write(text.toUtf8());
#else
output.write(input.readAll());
#endif // !Q_OS_MAC
}
}

View File

@@ -13,9 +13,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/application.h"
#include "core/sandbox.h"
#include "core/click_handler_types.h"
#include "data/components/sponsored_messages.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/data_session.h"
#include "data/data_sponsored_messages.h"
#include "iv/iv_instance.h"
#include "ui/text/text_custom_emoji.h"
#include "ui/basic_click_handlers.h"
@@ -295,7 +295,7 @@ bool UiIntegration::allowClickHandlerActivation(
const ClickContext &context) {
const auto my = context.other.value<ClickHandlerContext>();
if (const auto window = my.sessionWindow.get()) {
window->session().data().sponsoredMessages().clicked(my.itemId);
window->session().sponsoredMessages().clicked(my.itemId);
}
return true;
}

View File

@@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs;
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
constexpr auto AppName = "Telegram Desktop"_cs;
constexpr auto AppFile = "Telegram"_cs;
constexpr auto AppVersion = 4016002;
constexpr auto AppVersionStr = "4.16.2";
constexpr auto AppVersion = 4016008;
constexpr auto AppVersionStr = "4.16.8";
constexpr auto AppBetaVersion = false;
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;

View File

@@ -125,8 +125,10 @@ void Chatbots::togglePaused(not_null<PeerData*> peer, bool paused) {
return;
} else if (const auto settings = peer->barSettings()) {
peer->setBarSettings(paused
? (*settings | PeerBarSetting::BusinessBotPaused)
: (*settings & ~PeerBarSetting::BusinessBotPaused));
? ((*settings | PeerBarSetting::BusinessBotPaused)
& ~PeerBarSetting::BusinessBotCanReply)
: ((*settings & ~PeerBarSetting::BusinessBotPaused)
| PeerBarSetting::BusinessBotCanReply));
} else {
api->requestPeerSettings(peer);
}

View File

@@ -71,6 +71,13 @@ auto RecipientsFlags(const BusinessRecipients &data) {
} // namespace
BusinessRecipients BusinessRecipients::MakeValid(BusinessRecipients value) {
if (value.included.empty()) {
value.allButExcluded = true;
}
return value;
}
MTPInputBusinessRecipients ForMessagesToMTP(const BusinessRecipients &data) {
using Flag = MTPDinputBusinessRecipients::Flag;
const auto &chats = data.allButExcluded ? data.excluded : data.included;

View File

@@ -44,6 +44,9 @@ struct BusinessRecipients {
BusinessChats excluded;
bool allButExcluded = false;
[[nodiscard]] static BusinessRecipients MakeValid(
BusinessRecipients value);
friend inline bool operator==(
const BusinessRecipients &a,
const BusinessRecipients &b) = default;

View File

@@ -5,7 +5,7 @@ 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 "data/data_scheduled_messages.h"
#include "data/components/scheduled_messages.h"
#include "base/unixtime.h"
#include "data/data_forum_topic.h"
@@ -101,10 +101,10 @@ bool IsScheduledMsgId(MsgId id) {
return (id > ServerMaxMsgId) && (id < ScheduledMaxMsgId);
}
ScheduledMessages::ScheduledMessages(not_null<Session*> owner)
: _session(&owner->session())
ScheduledMessages::ScheduledMessages(not_null<Main::Session*> session)
: _session(session)
, _clearTimer([=] { clearOldRequests(); }) {
owner->itemRemoved(
_session->data().itemRemoved(
) | rpl::filter([](not_null<const HistoryItem*> item) {
return item->isScheduled();
}) | rpl::start_with_next([=](not_null<const HistoryItem*> item) {
@@ -113,9 +113,16 @@ ScheduledMessages::ScheduledMessages(not_null<Session*> owner)
}
ScheduledMessages::~ScheduledMessages() {
for (const auto &request : _requests) {
Expects(_data.empty());
Expects(_requests.empty());
}
void ScheduledMessages::clear() {
_lifetime.destroy();
for (const auto &request : base::take(_requests)) {
_session->api().request(request.second.requestId).cancel();
}
base::take(_data);
}
void ScheduledMessages::clearOldRequests() {

View File

@@ -18,14 +18,13 @@ class Session;
namespace Data {
class Session;
struct MessagesSlice;
[[nodiscard]] bool IsScheduledMsgId(MsgId id);
class ScheduledMessages final {
public:
explicit ScheduledMessages(not_null<Session*> owner);
explicit ScheduledMessages(not_null<Main::Session*> session);
ScheduledMessages(const ScheduledMessages &other) = delete;
ScheduledMessages &operator=(const ScheduledMessages &other) = delete;
~ScheduledMessages();
@@ -56,6 +55,8 @@ public:
[[nodiscard]] Data::MessagesSlice list(
not_null<const Data::ForumTopic*> topic) const;
void clear();
private:
using OwnedItem = std::unique_ptr<HistoryItem, HistoryItem::Destroyer>;
struct List {

View File

@@ -5,7 +5,7 @@ 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 "data/data_sponsored_messages.h"
#include "data/components/sponsored_messages.h"
#include "api/api_text_entities.h"
#include "apiwrap.h"
@@ -30,8 +30,8 @@ constexpr auto kRequestTimeLimit = 5 * 60 * crl::time(1000);
} // namespace
SponsoredMessages::SponsoredMessages(not_null<Session*> owner)
: _session(&owner->session())
SponsoredMessages::SponsoredMessages(not_null<Main::Session*> session)
: _session(session)
, _clearTimer([=] { clearOldRequests(); }) {
}

View File

@@ -20,8 +20,6 @@ class Session;
namespace Data {
class Session;
struct SponsoredReportResult final {
using Id = QByteArray;
struct Option final {
@@ -89,7 +87,7 @@ public:
bool canReport = false;
};
using RandomId = QByteArray;
explicit SponsoredMessages(not_null<Session*> owner);
explicit SponsoredMessages(not_null<Main::Session*> session);
SponsoredMessages(const SponsoredMessages &other) = delete;
SponsoredMessages &operator=(const SponsoredMessages &other) = delete;
~SponsoredMessages();

View File

@@ -22,6 +22,14 @@ CloudFile::~CloudFile() {
base::take(loader);
}
void CloudFile::clear() {
location = {};
base::take(loader);
byteSize = 0;
progressivePartSize = 0;
flags = {};
}
CloudImage::CloudImage() = default;
CloudImage::CloudImage(

View File

@@ -37,6 +37,8 @@ struct CloudFile final {
~CloudFile();
void clear();
ImageLocation location;
std::unique_ptr<FileLoader> loader;
int byteSize = 0;

View File

@@ -478,6 +478,31 @@ void DocumentData::setattributes(
_additional = nullptr;
}
if (!_filename.isEmpty()) {
using Type = Core::NameType;
if (type == VideoDocument
|| type == AnimatedDocument
|| type == RoundVideoDocument
|| isAnimation()) {
if (!enforceNameType(Type::Video)) {
type = FileDocument;
_additional = nullptr;
}
}
if (type == SongDocument || type == VoiceDocument || isAudioFile()) {
if (!enforceNameType(Type::Audio)) {
type = FileDocument;
_additional = nullptr;
}
}
if (!Core::NameTypeAllowsThumbnail(_nameType)) {
_inlineThumbnailBytes = {};
_flags &= ~Flag::InlineThumbnailIsPath;
_thumbnail.clear();
_videoThumbnail.clear();
}
}
if (isAudioFile()
|| isAnimation()
|| isVoiceMessage()
@@ -530,6 +555,10 @@ void DocumentData::updateThumbnails(
const ImageWithLocation &thumbnail,
const ImageWithLocation &videoThumbnail,
bool isPremiumSticker) {
if (!_filename.isEmpty()
&& !Core::NameTypeAllowsThumbnail(Core::DetectNameType(_filename))) {
return;
}
if (!inlineThumbnail.bytes.isEmpty()
&& _inlineThumbnailBytes.isEmpty()) {
_inlineThumbnailBytes = inlineThumbnail.bytes;
@@ -919,6 +948,25 @@ void DocumentData::setFileName(const QString &remoteFileName) {
for (const auto &ch : controls) {
_filename = std::move(_filename).replace(ch, "_");
}
_nameType = Core::DetectNameType(_filename);
}
bool DocumentData::enforceNameType(Core::NameType nameType) {
if (_nameType == nameType) {
return true;
}
const auto base = _filename.isEmpty() ? u"file"_q : _filename;
const auto mime = Core::MimeTypeForName(mimeString());
const auto patterns = mime.globPatterns();
for (const auto &pattern : mime.globPatterns()) {
const auto now = base + QString(pattern).replace('*', QString());
if (Core::DetectNameType(now) == nameType) {
_filename = now;
_nameType = nameType;
return true;
}
}
return false;
}
void DocumentData::setLoadedInMediaCacheLocation() {
@@ -1460,6 +1508,10 @@ QString DocumentData::filename() const {
return _filename;
}
Core::NameType DocumentData::nameType() const {
return _nameType;
}
QString DocumentData::mimeString() const {
return _mimeString;
}
@@ -1527,7 +1579,10 @@ bool DocumentData::isVideoMessage() const {
bool DocumentData::isAnimation() const {
return (type == AnimatedDocument)
|| isVideoMessage()
|| (hasMimeType(u"image/gif"_q)
|| ((_filename.isEmpty()
|| _nameType == Core::NameType::Image
|| _nameType == Core::NameType::Video)
&& hasMimeType(u"image/gif"_q)
&& !(_flags & Flag::StreamingPlaybackFailed));
}
@@ -1537,9 +1592,11 @@ bool DocumentData::isGifv() const {
}
bool DocumentData::isTheme() const {
return hasMimeType(u"application/x-tgtheme-tdesktop"_q)
|| _filename.endsWith(u".tdesktop-theme"_q, Qt::CaseInsensitive)
|| _filename.endsWith(u".tdesktop-palette"_q, Qt::CaseInsensitive);
return _filename.endsWith(u".tdesktop-theme"_q, Qt::CaseInsensitive)
|| _filename.endsWith(u".tdesktop-palette"_q, Qt::CaseInsensitive)
|| (hasMimeType(u"application/x-tgtheme-tdesktop"_q)
&& (_filename.isEmpty()
|| _nameType == Core::NameType::ThemeFile));
}
bool DocumentData::isSong() const {
@@ -1562,6 +1619,10 @@ bool DocumentData::isAudioFile() const {
return true;
}
return false;
} else if (!_filename.isEmpty()
&& _nameType != Core::NameType::Audio
&& _nameType != Core::NameType::Video) {
return false;
}
const auto left = _mimeString.mid(prefix.size());
const auto types = { u"x-wav"_q, u"wav"_q, u"mp4"_q };

View File

@@ -20,6 +20,10 @@ namespace Images {
class Source;
} // namespace Images
namespace Core {
enum class NameType : uchar;
} // namespace Core
namespace Storage {
namespace Cache {
struct Key;
@@ -255,6 +259,7 @@ public:
void collectLocalData(not_null<DocumentData*> local);
[[nodiscard]] QString filename() const;
[[nodiscard]] Core::NameType nameType() const;
[[nodiscard]] QString mimeString() const;
[[nodiscard]] bool hasMimeType(const QString &mime) const;
void setMimeString(const QString &mime);
@@ -336,6 +341,7 @@ private:
void setMaybeSupportsStreaming(bool supports);
void setLoadedInMediaCacheLocation();
void setFileName(const QString &remoteFileName);
bool enforceNameType(Core::NameType nameType);
void finishLoad();
void handleLoaderUpdates();
@@ -369,6 +375,7 @@ private:
std::unique_ptr<DocumentAdditionalData> _additional;
mutable Flags _flags = kStreamingSupportedUnknown;
GoodThumbnailState _goodThumbnailState = GoodThumbnailState();
Core::NameType _nameType = Core::NameType();
std::unique_ptr<FileLoader> _loader;
};

View File

@@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/themes/window_theme_preview.h"
#include "core/core_settings.h"
#include "core/application.h"
#include "core/mime_type.h"
#include "storage/file_download.h"
#include "ui/chat/attach/attach_prepare.h"
@@ -295,10 +296,12 @@ void DocumentMedia::automaticLoad(
// No automatic download in this case.
return;
}
const auto indata = _owner->filename();
const auto filename = toCache
? QString()
: DocumentFileNameForSave(_owner);
const auto shouldLoadFromCloud = !Data::IsExecutableName(filename)
const auto shouldLoadFromCloud = (indata.isEmpty()
|| Core::DetectNameType(indata) != Core::NameType::Executable)
&& (item
? Data::AutoDownload::Should(
_owner->session().settings().autoDownload(),

View File

@@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/chat/chat_theme.h"
#include "ui/text/text_utilities.h"
#include "ui/widgets/checkbox.h"
#include "ui/wrap/slide_wrap.h"
#include "window/window_session_controller.h"
#include "styles/style_layers.h"
@@ -46,11 +47,12 @@ base::options::toggle OptionExternalVideoPlayer({
void ConfirmDontWarnBox(
not_null<Ui::GenericBox*> box,
rpl::producer<TextWithEntities> &&text,
rpl::producer<QString> &&check,
rpl::producer<QString> &&confirm,
Fn<void(bool)> callback) {
auto checkbox = object_ptr<Ui::Checkbox>(
box.get(),
tr::lng_launch_exe_dont_ask(),
std::move(check),
false,
st::defaultBoxCheckbox);
const auto weak = Ui::MakeWeak(checkbox.data());
@@ -67,29 +69,43 @@ void ConfirmDontWarnBox(
auto padding = st::boxPadding;
padding.setTop(padding.bottom());
box->addRow(std::move(checkbox), std::move(padding));
box->addRow(object_ptr<Ui::SlideWrap<Ui::FlatLabel>>(
box,
object_ptr<Ui::FlatLabel>(
box,
tr::lng_launch_dont_ask_settings(),
st::boxLabel)
))->toggleOn(weak->checkedValue());
}
void LaunchWithWarning(
// not_null<Window::Controller*> controller,
const QString &name,
HistoryItem *item) {
const auto isExecutable = Data::IsExecutableName(name);
const auto isIpReveal = Data::IsIpRevealingName(name);
const auto nameType = Core::DetectNameType(name);
const auto isIpReveal = (nameType != Core::NameType::Executable)
&& Core::IsIpRevealingPath(name);
const auto extension = Core::FileExtension(name).toLower();
auto &app = Core::App();
auto &settings = app.settings();
const auto warn = [&] {
if (item && item->history()->peer->isVerified()) {
return false;
}
return (isExecutable && app.settings().exeLaunchWarning())
|| (isIpReveal && app.settings().ipRevealWarning());
return (isIpReveal && settings.ipRevealWarning())
|| ((nameType == Core::NameType::Executable
|| nameType == Core::NameType::Unknown)
&& !settings.noWarningExtensions().contains(extension));
}();
const auto extension = '.' + Data::FileExtension(name);
if (Platform::IsWindows() && extension == u"."_q) {
if (extension.isEmpty()) {
// If you launch a file without extension, like "test", in case
// there is an executable file with the same name in this folder,
// like "test.bat", the executable file will be launched.
//
// Now we always force an Open With dialog box for such files.
//
// Let's force it for all platforms for files without extension.
crl::on_main([=] {
Platform::File::UnsafeShowOpenWith(name);
});
@@ -98,27 +114,38 @@ void LaunchWithWarning(
File::Launch(name);
return;
}
const auto callback = [=, &app](bool checked) {
const auto callback = [=, &app, &settings](bool checked) {
if (checked) {
if (isExecutable) {
app.settings().setExeLaunchWarning(false);
} else if (isIpReveal) {
app.settings().setIpRevealWarning(false);
if (isIpReveal) {
settings.setIpRevealWarning(false);
} else {
auto copy = settings.noWarningExtensions();
copy.emplace(extension);
settings.setNoWarningExtensions(std::move(copy));
}
app.saveSettingsDelayed();
}
File::Launch(name);
};
auto text = isExecutable
? tr::lng_launch_exe_warning(
lt_extension,
rpl::single(Ui::Text::Bold(extension)),
Ui::Text::WithEntities)
: tr::lng_launch_svg_warning(Ui::Text::WithEntities);
auto text = isIpReveal
? tr::lng_launch_svg_warning(Ui::Text::WithEntities)
: ((nameType == Core::NameType::Executable)
? tr::lng_launch_exe_warning
: tr::lng_launch_other_warning)(
lt_extension,
rpl::single(Ui::Text::Bold('.' + extension)),
Ui::Text::WithEntities);
auto check = (isIpReveal
? tr::lng_launch_exe_dont_ask
: tr::lng_launch_dont_ask)();
auto confirm = ((nameType == Core::NameType::Executable)
? tr::lng_launch_exe_sure
: tr::lng_launch_other_sure)();
Ui::show(Box(
ConfirmDontWarnBox,
std::move(text),
(isExecutable ? tr::lng_launch_exe_sure : tr::lng_continue)(),
std::move(check),
std::move(confirm),
callback));
}
@@ -126,91 +153,6 @@ void LaunchWithWarning(
const char kOptionExternalVideoPlayer[] = "external-video-player";
QString FileExtension(const QString &filepath) {
const auto reversed = ranges::views::reverse(filepath);
const auto last = ranges::find_first_of(reversed, ".\\/");
if (last == reversed.end() || *last != '.') {
return QString();
}
return QString(last.base(), last - reversed.begin());
}
#if 0
bool IsValidMediaFile(const QString &filepath) {
static const auto kExtensions = [] {
const auto list = qsl("\
16svx 2sf 3g2 3gp 8svx aac aaf aif aifc aiff amr amv ape asf ast au aup \
avchd avi brstm bwf cam cdda cust dat divx drc dsh dsf dts dtshd dtsma \
dvr-ms dwd evo f4a f4b f4p f4v fla flac flr flv gif gifv gsf gsm gym iff \
ifo it jam la ly m1v m2p m2ts m2v m4a m4p m4v mcf mid mk3d mka mks mkv mng \
mov mp1 mp2 mp3 mp4 minipsf mod mpc mpe mpeg mpg mpv mscz mt2 mus mxf mxl \
niff nsf nsv off ofr ofs ogg ogv opus ots pac ps psf psf2 psflib ptb qsf \
qt ra raw rka rm rmj rmvb roq s3m shn sib sid smi smp sol spc spx ssf svi \
swa swf tak ts tta txm usf vgm vob voc vox vqf wav webm wma wmv wrap wtv \
wv xm xml ym yuv").split(' ');
return base::flat_set<QString>(list.begin(), list.end());
}();
return ranges::binary_search(
kExtensions,
FileExtension(filepath).toLower());
}
#endif
bool IsExecutableName(const QString &filepath) {
static const auto kExtensions = [] {
const auto joined =
#ifdef Q_OS_WIN
u"\
ad ade adp app application appref-ms asp asx bas bat bin cab cdxml cer cfg \
chi chm cmd cnt com cpl crt csh der diagcab dll drv eml exe fon fxp gadget \
grp hlp hpj hta htt inf ini ins inx isp isu its jar jnlp job js jse key ksh \
lnk local lua mad maf mag mam manifest maq mar mas mat mau mav maw mcf mda \
mdb mde mdt mdw mdz mht mhtml mjs mmc mof msc msg msh msh1 msh2 msh1xml \
msh2xml mshxml msi msp mst ops osd paf pcd phar php php3 php4 php5 php7 phps \
php-s pht phtml pif pl plg pm pod prf prg ps1 ps2 ps1xml ps2xml psc1 psc2 \
psd1 psm1 pssc pst py py3 pyc pyd pyi pyo pyw pywz pyz rb reg rgs scf scr \
sct search-ms settingcontent-ms sh shb shs slk sys t tmp u3p url vb vbe vbp \
vbs vbscript vdx vsmacros vsd vsdm vsdx vss vssm vssx vst vstm vstx vsw vsx \
vtx website ws wsc wsf wsh xbap xll xnk xs"_q;
#elif defined Q_OS_MAC // Q_OS_MAC
u"\
applescript action app bin command csh osx workflow terminal url caction \
mpkg pkg scpt scptd xhtm webarchive"_q;
#else // Q_OS_WIN || Q_OS_MAC
u"bin csh deb desktop ksh out pet pkg pup rpm run sh shar \
slp zsh"_q;
#endif // !Q_OS_WIN && !Q_OS_MAC
const auto list = joined.split(' ');
return base::flat_set<QString>(list.begin(), list.end());
}();
return ranges::binary_search(
kExtensions,
FileExtension(filepath).toLower());
}
bool IsIpRevealingName(const QString &filepath) {
static const auto kExtensions = [] {
const auto joined = u"htm html svg m4v m3u8"_q;
const auto list = joined.split(' ');
return base::flat_set<QString>(list.begin(), list.end());
}();
static const auto kMimeTypes = [] {
const auto joined = u"text/html image/svg+xml"_q;
const auto list = joined.split(' ');
return base::flat_set<QString>(list.begin(), list.end());
}();
return ranges::binary_search(
kExtensions,
FileExtension(filepath).toLower()
) || ranges::binary_search(
kMimeTypes,
QMimeDatabase().mimeTypeForFile(QFileInfo(filepath)).name()
);
}
base::binary_guard ReadBackgroundImageAsync(
not_null<Data::DocumentMedia*> media,
FnMut<QImage(QImage)> postprocess,

View File

@@ -22,10 +22,6 @@ class DocumentMedia;
extern const char kOptionExternalVideoPlayer[];
[[nodiscard]] QString FileExtension(const QString &filepath);
// [[nodiscard]] bool IsValidMediaFile(const QString &filepath);
[[nodiscard]] bool IsExecutableName(const QString &filepath);
[[nodiscard]] bool IsIpRevealingName(const QString &filepath);
base::binary_guard ReadBackgroundImageAsync(
not_null<Data::DocumentMedia*> media,
FnMut<QImage(QImage)> postprocess,

View File

@@ -9,13 +9,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_text_entities.h"
#include "data/business/data_shortcut_messages.h"
#include "data/components/scheduled_messages.h"
#include "data/data_session.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_folder.h"
#include "data/data_forum.h"
#include "data/data_forum_topic.h"
#include "data/data_scheduled_messages.h"
#include "data/data_user.h"
#include "base/unixtime.h"
#include "base/random.h"
@@ -830,11 +830,12 @@ void Histories::deleteMessages(const MessageIdsList &ids, bool revoke) {
if (item->isScheduled()) {
const auto wasOnServer = !item->isSending()
&& !item->hasFailed();
auto &scheduled = _owner->session().scheduledMessages();
if (wasOnServer) {
scheduledIdsByPeer[history->peer].push_back(MTP_int(
_owner->scheduledMessages().lookupId(item)));
scheduledIdsByPeer[history->peer].push_back(
MTP_int(scheduled.lookupId(item)));
} else {
_owner->scheduledMessages().removeSending(item);
scheduled.removeSending(item);
}
continue;
} else if (item->isBusinessShortcut()) {

View File

@@ -121,8 +121,8 @@ bool PollData::applyResults(const MTPPollResults &results) {
return results.match([&](const MTPDpollResults &results) {
_lastResultsUpdate = crl::now();
const auto newTotalVoters =
results.vtotal_voters().value_or(totalVoters);
const auto newTotalVoters
= results.vtotal_voters().value_or(totalVoters);
auto changed = (newTotalVoters != totalVoters);
if (const auto list = results.vresults()) {
for (const auto &result : list->v) {

View File

@@ -40,6 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/business/data_business_chatbots.h"
#include "data/business/data_business_info.h"
#include "data/business/data_shortcut_messages.h"
#include "data/components/scheduled_messages.h"
#include "data/stickers/data_stickers.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_bot_app.h"
@@ -56,9 +57,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_poll.h"
#include "data/data_replies_list.h"
#include "data/data_chat_filters.h"
#include "data/data_scheduled_messages.h"
#include "data/data_send_action.h"
#include "data/data_sponsored_messages.h"
#include "data/data_message_reactions.h"
#include "data/data_emoji_statuses.h"
#include "data/data_forum_icons.h"
@@ -272,9 +271,7 @@ Session::Session(not_null<Main::Session*> session)
, _savedMessages(std::make_unique<SavedMessages>(this))
, _chatbots(std::make_unique<Chatbots>(this))
, _businessInfo(std::make_unique<BusinessInfo>(this))
, _scheduledMessages(std::make_unique<ScheduledMessages>(this))
, _shortcutMessages(std::make_unique<ShortcutMessages>(this))
, _sponsoredMessages(std::make_unique<SponsoredMessages>(this)) {
, _shortcutMessages(std::make_unique<ShortcutMessages>(this)) {
_cache->open(_session->local().cacheKey());
_bigFileCache->open(_session->local().cacheBigFileKey());
@@ -397,9 +394,8 @@ void Session::clear() {
_sendActionManager->clear();
_histories->unloadAll();
_scheduledMessages = nullptr;
_shortcutMessages = nullptr;
_sponsoredMessages = nullptr;
_session->scheduledMessages().clear();
_dependentMessages.clear();
base::take(_messages);
base::take(_nonChannelMessages);

View File

@@ -47,10 +47,8 @@ namespace Data {
class Folder;
class LocationPoint;
class WallPaper;
class ScheduledMessages;
class ShortcutMessages;
class SendActionManager;
class SponsoredMessages;
class Reactions;
class EmojiStatuses;
class ForumIcons;
@@ -104,9 +102,6 @@ public:
[[nodiscard]] ChatFilters &chatsFilters() const {
return *_chatsFilters;
}
[[nodiscard]] ScheduledMessages &scheduledMessages() const {
return *_scheduledMessages;
}
[[nodiscard]] ShortcutMessages &shortcutMessages() const {
return *_shortcutMessages;
}
@@ -128,9 +123,6 @@ public:
[[nodiscard]] Stickers &stickers() const {
return *_stickers;
}
[[nodiscard]] SponsoredMessages &sponsoredMessages() const {
return *_sponsoredMessages;
}
[[nodiscard]] Reactions &reactions() const {
return *_reactions;
}
@@ -1084,9 +1076,7 @@ private:
const std::unique_ptr<SavedMessages> _savedMessages;
const std::unique_ptr<Chatbots> _chatbots;
const std::unique_ptr<BusinessInfo> _businessInfo;
std::unique_ptr<ScheduledMessages> _scheduledMessages;
std::unique_ptr<ShortcutMessages> _shortcutMessages;
std::unique_ptr<SponsoredMessages> _sponsoredMessages;
MsgId _nonHistoryEntryId = ShortcutMaxMsgId;

View File

@@ -13,10 +13,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_facade.h"
#include "history/history.h"
#include "history/history_item.h"
#include "data/components/scheduled_messages.h"
#include "data/data_document.h"
#include "data/data_media_types.h"
#include "data/data_photo.h"
#include "data/data_scheduled_messages.h"
#include "data/data_session.h"
#include "core/crash_reports.h"
@@ -193,9 +193,9 @@ rpl::producer<SparseIdsMergedSlice> SharedScheduledMediaViewer(
const auto history = session->data().history(key.mergedKey.peerId);
return rpl::single(rpl::empty) | rpl::then(
session->data().scheduledMessages().updates(history)
session->scheduledMessages().updates(history)
) | rpl::map([=] {
const auto list = session->data().scheduledMessages().list(history);
const auto list = session->scheduledMessages().list(history);
auto items = ranges::views::all(
list.ids

View File

@@ -30,14 +30,15 @@ struct StatisticalChart {
[[nodiscard]] int findIndex(int left, int right, float64 v) const;
struct Line final {
std::vector<int> y;
std::vector<Statistic::ChartValue> y;
Statistic::SegmentTree segmentTree;
int id = 0;
QString idString;
QString name;
int maxValue = 0;
int minValue = std::numeric_limits<int>::max();
Statistic::ChartValue maxValue = 0;
Statistic::ChartValue minValue
= std::numeric_limits<Statistic::ChartValue>::max();
QString colorKey;
QColor color;
QColor colorDark;
@@ -55,8 +56,9 @@ struct StatisticalChart {
float64 max = 0.;
} defaultZoomXIndex;
int maxValue = 0;
int minValue = std::numeric_limits<int>::max();
Statistic::ChartValue maxValue = 0;
Statistic::ChartValue minValue
= std::numeric_limits<Statistic::ChartValue>::max();
float64 oneDayPercentage = 0.;

View File

@@ -770,8 +770,8 @@ void Widget::updateScrollUpPosition() {
_scrollToTop->moveToRight(
st::historyToDownPosition.x(),
_scroll->height() - top);
const auto shouldBeHidden =
!_scrollToTopIsShown && !_scrollToTopShown.animating();
const auto shouldBeHidden
= !_scrollToTopIsShown && !_scrollToTopShown.animating();
if (shouldBeHidden != _scrollToTop->isHidden()) {
_scrollToTop->setVisible(!shouldBeHidden);
}

View File

@@ -48,8 +48,8 @@ PhotoEditorContent::PhotoEditorContent(
return;
}
const auto imageSizeF = [&] {
const auto rotatedSize =
FlipSizeByRotation(size, mods.angle);
const auto rotatedSize
= FlipSizeByRotation(size, mods.angle);
const auto m = _crop->cropMargins();
const auto sizeForCrop = rotatedSize
- QSize(m.left() + m.right(), m.top() + m.bottom());

View File

@@ -541,8 +541,8 @@ void ApiWrap::requestDialogsCount() {
Expects(_startProcess != nullptr);
if (_settings->onlySinglePeer()) {
_startProcess->info.dialogsCount =
(_settings->singlePeer.type() == mtpc_inputPeerChannel
_startProcess->info.dialogsCount
= (_settings->singlePeer.type() == mtpc_inputPeerChannel
? 1
: _splits.size());
sendNextStartRequest();

View File

@@ -738,8 +738,8 @@ void GenerateItems(
using LogPromote = MTPDchannelAdminLogEventActionParticipantToggleAdmin;
using LogSticker = MTPDchannelAdminLogEventActionChangeStickerSet;
using LogEmoji = MTPDchannelAdminLogEventActionChangeEmojiStickerSet;
using LogPreHistory =
MTPDchannelAdminLogEventActionTogglePreHistoryHidden;
using LogPreHistory
= MTPDchannelAdminLogEventActionTogglePreHistoryHidden;
using LogPermissions = MTPDchannelAdminLogEventActionDefaultBannedRights;
using LogPoll = MTPDchannelAdminLogEventActionStopPoll;
using LogDiscussion = MTPDchannelAdminLogEventActionChangeLinkedChat;
@@ -749,19 +749,19 @@ void GenerateItems(
using LogDiscardCall = MTPDchannelAdminLogEventActionDiscardGroupCall;
using LogMute = MTPDchannelAdminLogEventActionParticipantMute;
using LogUnmute = MTPDchannelAdminLogEventActionParticipantUnmute;
using LogCallSetting =
MTPDchannelAdminLogEventActionToggleGroupCallSetting;
using LogJoinByInvite =
MTPDchannelAdminLogEventActionParticipantJoinByInvite;
using LogInviteDelete =
MTPDchannelAdminLogEventActionExportedInviteDelete;
using LogInviteRevoke =
MTPDchannelAdminLogEventActionExportedInviteRevoke;
using LogCallSetting
= MTPDchannelAdminLogEventActionToggleGroupCallSetting;
using LogJoinByInvite
= MTPDchannelAdminLogEventActionParticipantJoinByInvite;
using LogInviteDelete
= MTPDchannelAdminLogEventActionExportedInviteDelete;
using LogInviteRevoke
= MTPDchannelAdminLogEventActionExportedInviteRevoke;
using LogInviteEdit = MTPDchannelAdminLogEventActionExportedInviteEdit;
using LogVolume = MTPDchannelAdminLogEventActionParticipantVolume;
using LogTTL = MTPDchannelAdminLogEventActionChangeHistoryTTL;
using LogJoinByRequest =
MTPDchannelAdminLogEventActionParticipantJoinByRequest;
using LogJoinByRequest
= MTPDchannelAdminLogEventActionParticipantJoinByRequest;
using LogNoForwards = MTPDchannelAdminLogEventActionToggleNoForwards;
using LogSendMessage = MTPDchannelAdminLogEventActionSendMessage;
using LogChangeAvailableReactions = MTPDchannelAdminLogEventActionChangeAvailableReactions;

View File

@@ -19,6 +19,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_unread_things.h"
#include "dialogs/ui/dialogs_layout.h"
#include "data/business/data_shortcut_messages.h"
#include "data/components/scheduled_messages.h"
#include "data/components/sponsored_messages.h"
#include "data/notify/data_notify_settings.h"
#include "data/stickers/data_stickers.h"
#include "data/data_drafts.h"
@@ -28,8 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel_admins.h"
#include "data/data_changes.h"
#include "data/data_chat_filters.h"
#include "data/data_scheduled_messages.h"
#include "data/data_sponsored_messages.h"
#include "data/data_send_action.h"
#include "data/data_folder.h"
#include "data/data_forum.h"
@@ -590,7 +590,7 @@ not_null<HistoryItem*> History::addNewItem(
not_null<HistoryItem*> item,
bool unread) {
if (item->isScheduled()) {
owner().scheduledMessages().appendSending(item);
session().scheduledMessages().appendSending(item);
return item;
} else if (item->isBusinessShortcut()) {
owner().shortcutMessages().appendSending(item);

View File

@@ -25,10 +25,6 @@ struct HistoryMessageMarkupData;
class HistoryMainElementDelegateMixin;
struct LanguageId;
namespace Main {
class Session;
} // namespace Main
namespace Data {
struct Draft;
class Session;

View File

@@ -52,8 +52,8 @@ DragArea::Areas DragArea::SetupDragAreaToContainer(
auto &lifetime = container->lifetime();
container->setAcceptDrops(true);
const auto attachDragDocument =
Ui::CreateChild<DragArea>(container.get());
const auto attachDragDocument
= Ui::CreateChild<DragArea>(container.get());
const auto attachDragPhoto = Ui::CreateChild<DragArea>(container.get());
attachDragDocument->hide();
@@ -62,8 +62,8 @@ DragArea::Areas DragArea::SetupDragAreaToContainer(
attachDragDocument->raise();
attachDragPhoto->raise();
const auto attachDragState =
lifetime.make_state<DragState>(DragState::None);
const auto attachDragState
= lifetime.make_state<DragState>(DragState::None);
const auto width = [=] {
return container->width();

View File

@@ -23,8 +23,8 @@ public:
DragArea *photo;
};
using CallbackComputeState =
Fn<Storage::MimeDataState(const QMimeData *data)>;
using CallbackComputeState
= Fn<Storage::MimeDataState(const QMimeData *data)>;
static Areas SetupDragAreaToContainer(
not_null<Ui::RpWidget*> container,

View File

@@ -68,6 +68,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_who_reacted.h"
#include "api/api_views.h"
#include "lang/lang_keys.h"
#include "data/components/sponsored_messages.h"
#include "data/data_session.h"
#include "data/data_document.h"
#include "data/data_channel.h"
@@ -79,7 +80,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_file_click_handler.h"
#include "data/data_histories.h"
#include "data/data_changes.h"
#include "data/data_sponsored_messages.h"
#include "dialogs/ui/dialogs_video_userpic.h"
#include "styles/style_chat.h"
#include "styles/style_menu_icons.h"
@@ -118,7 +118,7 @@ void FillSponsoredMessagesMenu(
not_null<Window::SessionController*> controller,
FullMsgId itemId,
not_null<Ui::PopupMenu*> menu) {
const auto &data = controller->session().data().sponsoredMessages();
const auto &data = controller->session().sponsoredMessages();
const auto info = data.lookupDetails(itemId).info;
const auto show = controller->uiShow();
if (!info.empty()) {
@@ -979,7 +979,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
: yShown(top + height / 2);
if (markShown) {
if (isSponsored) {
session().data().sponsoredMessages().view(item->fullId());
session().sponsoredMessages().view(item->fullId());
} else if (isUnread) {
readTill = item;
}

View File

@@ -40,11 +40,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/timer_rpl.h"
#include "api/api_text_entities.h"
#include "api/api_updates.h"
#include "data/components/scheduled_messages.h"
#include "data/components/sponsored_messages.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_bot_app.h"
#include "data/data_saved_messages.h"
#include "data/data_saved_sublist.h"
#include "data/data_scheduled_messages.h"
#include "data/data_changes.h"
#include "data/data_session.h"
#include "data/data_message_reactions.h"
@@ -57,7 +58,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h"
#include "data/data_group_call.h" // Data::GroupCall::id().
#include "data/data_poll.h" // PollData::publicVotes.
#include "data/data_sponsored_messages.h"
#include "data/data_stories.h"
#include "data/data_web_page.h"
#include "chat_helpers/stickers_gift_box_pack.h"

View File

@@ -33,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/audio/media_audio.h"
#include "media/player/media_player_instance.h"
#include "data/business/data_shortcut_messages.h"
#include "data/components/scheduled_messages.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/data_channel.h"
#include "data/data_media_types.h"
@@ -42,7 +43,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document.h"
#include "data/data_web_page.h"
#include "data/data_file_click_handler.h"
#include "data/data_scheduled_messages.h"
#include "data/data_session.h"
#include "data/data_stories.h"
#include "main/main_session.h"
@@ -301,7 +301,7 @@ ReplyFields ReplyFieldsFromMTP(
const auto owner = &item->history()->owner();
if (const auto id = data.vreply_to_msg_id().value_or_empty()) {
result.messageId = data.is_reply_to_scheduled()
? owner->scheduledMessages().localMessageId(id)
? owner->session().scheduledMessages().localMessageId(id)
: item->shortcutId()
? owner->shortcutMessages().localMessageId(id)
: id;

View File

@@ -54,6 +54,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unixtime.h"
#include "base/call_delayed.h"
#include "data/business/data_shortcut_messages.h"
#include "data/components/scheduled_messages.h"
#include "data/components/sponsored_messages.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_changes.h"
#include "data/data_drafts.h"
@@ -68,8 +70,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_forum_topic.h"
#include "data/data_user.h"
#include "data/data_chat_filters.h"
#include "data/data_scheduled_messages.h"
#include "data/data_sponsored_messages.h"
#include "data/data_file_origin.h"
#include "data/data_histories.h"
#include "data/data_group_call.h"
@@ -311,7 +311,7 @@ HistoryWidget::HistoryWidget(
) | rpl::start_with_next([=] {
if (_history
&& _history->loadedAtBottom()
&& session().data().sponsoredMessages().append(_history)) {
&& session().sponsoredMessages().append(_history)) {
_scroll->contentAdded();
}
}, lifetime());
@@ -2216,7 +2216,7 @@ void HistoryWidget::showHistory(
return;
} else {
_sponsoredMessagesStateKnown = false;
session().data().sponsoredMessages().clearItems(_history);
session().sponsoredMessages().clearItems(_history);
session().data().hideShownSpoilers();
_composeSearch = nullptr;
}
@@ -2466,20 +2466,18 @@ void HistoryWidget::showHistory(
if (history != _history) {
return;
}
auto &sponsored = session().data().sponsoredMessages();
using State = Data::SponsoredMessages::State;
const auto state = sponsored.state(_history);
const auto state = session().sponsoredMessages().state(
_history);
_sponsoredMessagesStateKnown = (state != State::None);
if (state == State::AppendToEnd) {
_scroll->setTrackingContent(
sponsored.canHaveFor(_history));
session().sponsoredMessages().canHaveFor(_history));
} else if (state == State::InjectToMiddle) {
injectSponsoredMessages();
}
});
session().data().sponsoredMessages().request(
_history,
checkState);
session().sponsoredMessages().request(_history, checkState);
checkState();
}
} else {
@@ -2583,7 +2581,7 @@ void HistoryWidget::setupPreview() {
}
void HistoryWidget::injectSponsoredMessages() const {
session().data().sponsoredMessages().inject(
session().sponsoredMessages().inject(
_history,
_showAtMsgId,
_scroll->height() * 2,
@@ -2774,9 +2772,9 @@ void HistoryWidget::setupScheduledToggle() {
controller()->activeChatValue(
) | rpl::map([=](Dialogs::Key key) -> rpl::producer<> {
if (const auto history = key.history()) {
return session().data().scheduledMessages().updates(history);
return session().scheduledMessages().updates(history);
} else if (const auto topic = key.topic()) {
return session().data().scheduledMessages().updates(
return session().scheduledMessages().updates(
topic->owningHistory());
}
return rpl::never<rpl::empty_value>();
@@ -2791,7 +2789,7 @@ void HistoryWidget::setupScheduledToggle() {
void HistoryWidget::refreshScheduledToggle() {
const auto has = _history
&& _canSendMessages
&& (session().data().scheduledMessages().count(_history) > 0);
&& (session().scheduledMessages().count(_history) > 0);
if (!_scheduled && has) {
_scheduled.create(this, st::historyScheduledToggle);
_scheduled->show();
@@ -3631,7 +3629,7 @@ void HistoryWidget::loadMessagesDown() {
auto from = loadMigrated ? _migrated : _history;
if (from->loadedAtBottom()) {
if (_sponsoredMessagesStateKnown) {
session().data().sponsoredMessages().request(_history, nullptr);
session().sponsoredMessages().request(_history, nullptr);
}
return;
}
@@ -4496,7 +4494,7 @@ void HistoryWidget::chooseAttach(
}
const auto filter = (overrideSendImagesAsPhotos == true)
? FileDialog::ImagesOrAllFilter()
? FileDialog::PhotoVideoFilesFilter()
: FileDialog::AllOrImagesFilter();
FileDialog::GetOpenPaths(this, tr::lng_choose_files(tr::now), filter, crl::guard(this, [=](

View File

@@ -18,7 +18,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/fields/input_field.h"
#include "mtproto/sender.h"
struct FileLoadResult;
enum class SendMediaType;
class MessageLinksParser;
struct InlineBotQuery;

View File

@@ -1973,6 +1973,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
const auto guard = gsl::finally([&] {
updateSendButtonType();
updateReplaceMediaButton();
updateFieldPlaceholder();
updateControlsVisibility();
updateControlsGeometry(_wrap->size());
});

View File

@@ -372,8 +372,8 @@ TTLButton::TTLButton(
return (r.left() + r.width() > parentWidget()->width());
}) | rpl::distinct_until_changed(
) | rpl::start_with_next([=](bool toHide) {
const auto isFirstTooltip =
!Core::App().settings().ttlVoiceClickTooltipHidden();
const auto isFirstTooltip
= !Core::App().settings().ttlVoiceClickTooltipHidden();
if (isFirstTooltip || (!isFirstTooltip && toHide)) {
_tooltip->toggleAnimated(!toHide);
}

View File

@@ -902,15 +902,15 @@ void BusinessBotStatus::Bar::showState(State state) {
_userpic->setAttribute(Qt::WA_TransparentForMouseEvents);
_userpic->show();
_name->setText(state.bot->name());
_status->setText(!state.canReply
? tr::lng_chatbot_status_views(tr::now)
: state.paused
_status->setText(state.paused
? tr::lng_chatbot_status_paused(tr::now)
: tr::lng_chatbot_status_can_reply(tr::now));
: state.canReply
? tr::lng_chatbot_status_can_reply(tr::now)
: tr::lng_chatbot_status_views(tr::now));
_togglePaused->setText(state.paused
? tr::lng_chatbot_button_resume()
: tr::lng_chatbot_button_pause());
_togglePaused->setVisible(state.canReply);
_togglePaused->setVisible(state.canReply || state.paused);
_paused = state.paused;
resizeToWidth(width());
}

View File

@@ -39,10 +39,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text_utilities.h"
#include "ui/item_text_options.h"
#include "ui/painter.h"
#include "data/components/sponsored_messages.h"
#include "data/data_session.h"
#include "data/data_forum.h"
#include "data/data_forum_topic.h"
#include "data/data_sponsored_messages.h"
#include "data/data_message_reactions.h"
#include "data/data_user.h"
#include "lang/lang_keys.h"
@@ -1108,7 +1108,7 @@ ClickHandlerPtr Element::fromLink() const {
}
const auto my = context.other.value<ClickHandlerContext>();
if (const auto window = ContextOrSessionWindow(my, session)) {
auto &sponsored = session->data().sponsoredMessages();
auto &sponsored = session->sponsoredMessages();
const auto itemId = my.itemId ? my.itemId : item->fullId();
const auto details = sponsored.lookupDetails(itemId);
if (!details.externalLink.isEmpty()) {

View File

@@ -56,8 +56,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/premium_preview_box.h"
#include "boxes/peers/edit_participant_box.h"
#include "core/crash_reports.h"
#include "data/components/sponsored_messages.h"
#include "data/data_session.h"
#include "data/data_sponsored_messages.h"
#include "data/data_changes.h"
#include "data/data_folder.h"
#include "data/data_media_types.h"
@@ -2138,8 +2138,7 @@ void ListWidget::paintEvent(QPaintEvent *e) {
: yShown(top + height / 2);
if (markShown) {
if (isSponsored) {
session->data().sponsoredMessages().view(
item->fullId());
session->sponsoredMessages().view(item->fullId());
} else if (isUnread) {
readTill = item;
}
@@ -3898,8 +3897,8 @@ bool ListWidget::lastMessageEditRequestNotify() const {
if (it == end(list)) {
return false;
} else {
const auto item =
session().data().groups().findItemToEdit((*it)->data()).get();
const auto item
= session().data().groups().findItemToEdit((*it)->data()).get();
editMessageRequestNotify(item->fullId());
return true;
}

View File

@@ -27,12 +27,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/round_rect.h"
#include "ui/text/text_utilities.h"
#include "ui/power_saving.h"
#include "data/components/sponsored_messages.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "data/data_channel.h"
#include "data/data_forum_topic.h"
#include "data/data_message_reactions.h"
#include "data/data_sponsored_messages.h"
#include "lang/lang_keys.h"
#include "mainwidget.h"
#include "main/main_session.h"
@@ -435,8 +435,9 @@ Message::Message(
}
}
if (data->isSponsored()) {
const auto &messages = data->history()->owner().sponsoredMessages();
const auto details = messages.lookupDetails(data->fullId());
const auto &session = data->history()->session();
const auto details = session.sponsoredMessages().lookupDetails(
data->fullId());
if (details.canReport) {
_rightAction = std::make_unique<RightAction>();
_rightAction->second = std::make_unique<SecondRightAction>();
@@ -1842,27 +1843,27 @@ void Message::clickHandlerPressedChanged(
Element::clickHandlerPressedChanged(handler, pressed);
if (!handler) {
return;
} else if (_rightAction) {
if (_rightAction->second && (handler == _rightAction->second->link)) {
const auto rightSize = rightActionSize();
Assert(rightSize != std::nullopt);
if (pressed) {
if (!_rightAction->second->ripple) {
// Create a ripple.
_rightAction->second->ripple =
std::make_unique<Ui::RippleAnimation>(
st::defaultRippleAnimation,
Ui::RippleAnimation::RoundRectMask(
Size(rightSize->width()),
rightSize->width() / 2),
[=] { repaint(); });
}
_rightAction->second->ripple->add(_rightAction->lastPoint);
} else if (_rightAction->second->ripple) {
_rightAction->second->ripple->lastStop();
} else if (_rightAction && (handler == _rightAction->link)) {
toggleRightActionRipple(pressed);
} else if (_rightAction
&& _rightAction->second
&& (handler == _rightAction->second->link)) {
const auto rightSize = rightActionSize();
Assert(rightSize != std::nullopt);
if (pressed) {
if (!_rightAction->second->ripple) {
// Create a ripple.
_rightAction->second->ripple
= std::make_unique<Ui::RippleAnimation>(
st::defaultRippleAnimation,
Ui::RippleAnimation::RoundRectMask(
Size(rightSize->width()),
rightSize->width() / 2),
[=] { repaint(); });
}
} else if (handler == _rightAction->link) {
toggleRightActionRipple(pressed);
_rightAction->second->ripple->add(_rightAction->lastPoint);
} else if (_rightAction->second->ripple) {
_rightAction->second->ripple->lastStop();
}
} else if (_comments && (handler == _comments->link)) {
toggleCommentsButtonRipple(pressed);

View File

@@ -52,6 +52,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/mime_type.h"
#include "main/main_session.h"
#include "main/main_session_settings.h"
#include "data/components/scheduled_messages.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "data/data_chat.h"
@@ -63,7 +64,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_changes.h"
#include "data/data_shared_media.h"
#include "data/data_send_action.h"
#include "data/data_scheduled_messages.h"
#include "data/data_premium_limits.h"
#include "storage/storage_media_prepare.h"
#include "storage/storage_account.h"
@@ -230,10 +230,9 @@ RepliesWidget::RepliesWidget(
.stickerOrEmojiChosen = controller->stickerOrEmojiChosen(),
.scheduledToggleValue = _topic
? rpl::single(rpl::empty_value()) | rpl::then(
session().data().scheduledMessages().updates(
_topic->owningHistory())
session().scheduledMessages().updates(_topic->owningHistory())
) | rpl::map([=] {
return session().data().scheduledMessages().hasFor(_topic);
return session().scheduledMessages().hasFor(_topic);
}) | rpl::type_erased()
: rpl::single(false),
}))
@@ -867,7 +866,7 @@ void RepliesWidget::chooseAttach(
}
const auto filter = (overrideSendImagesAsPhotos == true)
? FileDialog::ImagesOrAllFilter()
? FileDialog::PhotoVideoFilesFilter()
: FileDialog::AllOrImagesFilter();
FileDialog::GetOpenPaths(this, tr::lng_choose_files(tr::now), filter, crl::guard(this, [=](
FileDialog::OpenResult &&result) {

View File

@@ -33,11 +33,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/mime_type.h"
#include "chat_helpers/tabbed_selector.h"
#include "main/main_session.h"
#include "data/components/scheduled_messages.h"
#include "data/data_forum.h"
#include "data/data_forum_topic.h"
#include "data/data_session.h"
#include "data/data_changes.h"
#include "data/data_scheduled_messages.h"
#include "data/data_user.h"
#include "data/data_message_reactions.h"
#include "data/data_peer_values.h"
@@ -58,11 +58,20 @@ namespace HistoryView {
ScheduledMemento::ScheduledMemento(not_null<History*> history)
: _history(history)
, _forumTopic(nullptr) {
const auto list = _history->session().scheduledMessages().list(_history);
if (!list.ids.empty()) {
_list.setScrollTopState({ .item = { .fullId = list.ids.front() } });
}
}
ScheduledMemento::ScheduledMemento(not_null<Data::ForumTopic*> forumTopic)
: _history(forumTopic->owningHistory())
, _forumTopic(forumTopic) {
const auto list = _history->session().scheduledMessages().list(
_forumTopic);
if (!list.ids.empty()) {
_list.setScrollTopState({ .item = { .fullId = list.ids.front() } });
}
}
object_ptr<Window::SectionWidget> ScheduledMemento::createWidget(
@@ -1154,9 +1163,7 @@ Context ScheduledWidget::listContext() {
}
bool ScheduledWidget::listScrollTo(int top, bool syntetic) {
top = (top == ScrollMax && syntetic)
? 0
: std::clamp(top, 0, _scroll->scrollTopMax());
top = std::clamp(top, 0, _scroll->scrollTopMax());
if (_scroll->scrollTop() == top) {
updateInnerVisibleArea();
return false;
@@ -1187,13 +1194,13 @@ rpl::producer<Data::MessagesSlice> ScheduledWidget::listSource(
Data::MessagePosition aroundId,
int limitBefore,
int limitAfter) {
const auto data = &controller()->session().data();
const auto session = &controller()->session();
return rpl::single(rpl::empty) | rpl::then(
data->scheduledMessages().updates(_history)
session->scheduledMessages().updates(_history)
) | rpl::map([=] {
return _forumTopic
? data->scheduledMessages().list(_forumTopic)
: data->scheduledMessages().list(_history);
? session->scheduledMessages().list(_forumTopic)
: session->scheduledMessages().list(_history);
}) | rpl::after_next([=](const Data::MessagesSlice &slice) {
highlightSingleNewMessage(slice);
});

View File

@@ -280,7 +280,7 @@ private:
};
class ScheduledMemento : public Window::SectionMemento {
class ScheduledMemento final : public Window::SectionMemento {
public:
ScheduledMemento(not_null<History*> history);
ScheduledMemento(not_null<Data::ForumTopic*> forumTopic);

View File

@@ -150,8 +150,8 @@ bool SendActionPainter::paint(
const auto extraAnimationWidth = _animationLeft
? animationWidth * 2
: 0;
const auto left =
(availableWidth < _animationLeft + extraAnimationWidth)
const auto left
= (availableWidth < _animationLeft + extraAnimationWidth)
? 0
: _animationLeft;
_sendActionAnimation.paint(

View File

@@ -10,8 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_chat_invite.h"
#include "core/click_handler_types.h"
#include "core/file_utilities.h"
#include "data/components/sponsored_messages.h"
#include "data/data_session.h"
#include "data/data_sponsored_messages.h"
#include "main/main_session.h"
#include "window/window_session_controller.h"
@@ -37,8 +37,8 @@ ClickHandlerPtr SponsoredLink(const QString &externalLink) {
if (!controller) {
return;
}
const auto &data = controller->session().data();
const auto details = data.sponsoredMessages().lookupDetails(
const auto &session = controller->session();
const auto details = session.sponsoredMessages().lookupDetails(
my.itemId);
if (!details.externalLink.isEmpty()) {
File::OpenUrl(details.externalLink);

View File

@@ -380,12 +380,9 @@ void Document::createComponents(bool caption) {
mask |= HistoryDocumentVoice::Bit();
} else {
mask |= HistoryDocumentNamed::Bit();
if (_data->hasThumbnail()) {
if (!_data->isSong()
&& !Data::IsExecutableName(_data->filename())) {
_data->loadThumbnail(_realParent->fullId());
mask |= HistoryDocumentThumbed::Bit();
}
if (_data->hasThumbnail() && !_data->isSong()) {
_data->loadThumbnail(_realParent->fullId());
mask |= HistoryDocumentThumbed::Bit();
}
}
if (caption) {

View File

@@ -13,11 +13,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "iv/iv_instance.h"
#include "core/click_handler_types.h"
#include "core/ui_integration.h"
#include "data/components/sponsored_messages.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/data_file_click_handler.h"
#include "data/data_photo_media.h"
#include "data/data_session.h"
#include "data/data_sponsored_messages.h"
#include "data/data_web_page.h"
#include "history/history.h"
#include "history/history_item_components.h"
@@ -227,8 +227,8 @@ WebPage::WebPage(
if (!(flags & MediaWebPageFlag::Sponsored)) {
return std::nullopt;
}
const auto &data = _parent->data()->history()->owner();
const auto details = data.sponsoredMessages().lookupDetails(
const auto &session = _parent->data()->history()->session();
const auto details = session.sponsoredMessages().lookupDetails(
_parent->data()->fullId());
auto result = std::make_optional<SponsoredData>();
result->buttonText = details.buttonText;
@@ -496,8 +496,8 @@ QSize WebPage::countOptimalSize() {
minHeight = resizeGetHeight(maxWidth);
}
if (_sponsoredData && _sponsoredData->canReport) {
_sponsoredData->widthBeforeHint =
st::webPageTitleStyle.font->width(siteName);
_sponsoredData->widthBeforeHint
= st::webPageTitleStyle.font->width(siteName);
const auto &font = st::webPageSponsoredHintFont;
_sponsoredData->hintSize = QSize(
font->width(tr::lng_sponsored_message_revenue_button(tr::now))

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