Merge tag 'v4.16.0' into dev

# Conflicts:
#	README.md
#	Telegram/Resources/winrc/Telegram.rc
#	Telegram/Resources/winrc/Updater.rc
#	Telegram/SourceFiles/calls/calls_call.cpp
#	Telegram/SourceFiles/core/local_url_handlers.cpp
#	Telegram/SourceFiles/core/version.h
#	Telegram/SourceFiles/history/view/media/history_view_giveaway.cpp
#	Telegram/SourceFiles/history/view/media/history_view_sticker.cpp
#	Telegram/lib_ui
#	snap/snapcraft.yaml
This commit is contained in:
AlexeyZavar
2024-04-01 23:56:12 +03:00
511 changed files with 21299 additions and 4877 deletions
+70 -7
View File
@@ -9,7 +9,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "main/main_session_settings.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
#include "apiwrap.h"
#include "mainwidget.h"
@@ -36,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/audio/media_audio.h"
#include "boxes/abstract_box.h"
#include "passport/passport_form_controller.h"
#include "iv/iv_data.h"
#include "lang/lang_keys.h" // tr::lng_deleted(tr::now) in user name
#include "data/business/data_business_chatbots.h"
#include "data/business/data_business_info.h"
@@ -247,7 +247,7 @@ Session::Session(not_null<Main::Session*> session)
, _bigFileCache(Core::App().databases().get(
_session->local().cacheBigFilePath(),
_session->local().cacheBigFileSettings()))
, _groupFreeTranscribeLevel(session->account().appConfig().value(
, _groupFreeTranscribeLevel(session->appConfig().value(
) | rpl::map([limits = Data::LevelLimits(session)] {
return limits.groupTranscribeLevelMin();
}))
@@ -731,6 +731,7 @@ not_null<UserData*> Session::processUser(const MTPUser &data) {
result->botInfo->inlinePlaceholder = QString();
}
result->botInfo->supportsAttachMenu = data.is_bot_attach_menu();
result->botInfo->supportsBusiness = data.is_bot_business();
result->botInfo->canEditInformation = data.is_bot_can_edit();
} else {
result->setBotInfoVersion(-1);
@@ -1688,6 +1689,20 @@ bool Session::queryItemVisibility(not_null<HistoryItem*> item) const {
return result;
}
bool Session::queryDocumentVisibility(
not_null<DocumentData*> document) const {
const auto i = _documentItems.find(document);
if (i != end(_documentItems)) {
for (const auto &item : i->second) {
if (queryItemVisibility(item)) {
return true;
}
}
}
return false;
}
[[nodiscard]] auto Session::itemVisibilityQueries() const
-> rpl::producer<Session::ItemVisibilityQuery> {
return _itemVisibilityQueries.events();
@@ -2199,7 +2214,7 @@ rpl::producer<int> Session::maxPinnedChatsLimitValue(
// We always use premium limit in the MainList limit producer,
// because it slices the list to that limit. We don't want to slice
// premium-ly added chats from the pinned list because of sync issues.
return _session->account().appConfig().value(
return _session->appConfig().value(
) | rpl::map([folder, limits = Data::PremiumLimits(_session)] {
return folder
? limits.dialogsFolderPinnedPremium()
@@ -2213,7 +2228,7 @@ rpl::producer<int> Session::maxPinnedChatsLimitValue(
// We always use premium limit in the MainList limit producer,
// because it slices the list to that limit. We don't want to slice
// premium-ly added chats from the pinned list because of sync issues.
return _session->account().appConfig().value(
return _session->appConfig().value(
) | rpl::map([limits = Data::PremiumLimits(_session)] {
return limits.dialogFiltersChatsPremium();
});
@@ -2221,7 +2236,7 @@ rpl::producer<int> Session::maxPinnedChatsLimitValue(
rpl::producer<int> Session::maxPinnedChatsLimitValue(
not_null<Data::Forum*> forum) const {
return _session->account().appConfig().value(
return _session->appConfig().value(
) | rpl::map([limits = Data::PremiumLimits(_session)] {
return limits.topicsPinnedCurrent();
});
@@ -2233,7 +2248,7 @@ rpl::producer<int> Session::maxPinnedChatsLimitValue(
// We always use premium limit in the MainList limit producer,
// because it slices the list to that limit. We don't want to slice
// premium-ly added chats from the pinned list because of sync issues.
return _session->account().appConfig().value(
return _session->appConfig().value(
) | rpl::map([limits = Data::PremiumLimits(_session)] {
return limits.savedSublistsPinnedPremium();
});
@@ -3431,6 +3446,7 @@ not_null<WebPageData*> Session::processWebpage(
nullptr,
nullptr,
WebPageCollage(),
nullptr,
0,
QString(),
false,
@@ -3455,6 +3471,7 @@ not_null<WebPageData*> Session::webpage(
nullptr,
nullptr,
WebPageCollage(),
nullptr,
0,
QString(),
false,
@@ -3472,6 +3489,7 @@ not_null<WebPageData*> Session::webpage(
PhotoData *photo,
DocumentData *document,
WebPageCollage &&collage,
std::unique_ptr<Iv::Data> iv,
int duration,
const QString &author,
bool hasLargeMedia,
@@ -3489,6 +3507,7 @@ not_null<WebPageData*> Session::webpage(
photo,
document,
std::move(collage),
std::move(iv),
duration,
author,
hasLargeMedia,
@@ -3569,9 +3588,49 @@ void Session::webpageApplyFields(
}, [](const auto &) {});
}
}
if (const auto page = data.vcached_page()) {
for (const auto &photo : page->data().vphotos().v) {
processPhoto(photo);
}
for (const auto &document : page->data().vdocuments().v) {
processDocument(document);
}
const auto process = [&](
const MTPPageBlock &block,
const auto &self) -> void {
block.match([&](const MTPDpageBlockChannel &data) {
processChat(data.vchannel());
}, [&](const MTPDpageBlockCover &data) {
self(data.vcover(), self);
}, [&](const MTPDpageBlockEmbedPost &data) {
for (const auto &block : data.vblocks().v) {
self(block, self);
}
}, [&](const MTPDpageBlockCollage &data) {
for (const auto &block : data.vitems().v) {
self(block, self);
}
}, [&](const MTPDpageBlockSlideshow &data) {
for (const auto &block : data.vitems().v) {
self(block, self);
}
}, [&](const MTPDpageBlockDetails &data) {
for (const auto &block : data.vblocks().v) {
self(block, self);
}
}, [](const auto &) {});
};
for (const auto &block : page->data().vblocks().v) {
process(block, process);
}
}
const auto type = story ? WebPageType::Story : ParseWebPageType(data);
auto iv = (data.vcached_page() && !IgnoreIv(type))
? std::make_unique<Iv::Data>(data, *data.vcached_page())
: nullptr;
webpageApplyFields(
page,
(story ? WebPageType::Story : ParseWebPageType(data)),
type,
qs(data.vurl()),
qs(data.vdisplay_url()),
siteName,
@@ -3589,6 +3648,7 @@ void Session::webpageApplyFields(
? processDocument(*document).get()
: lookupThemeDocument()),
WebPageCollage(this, data),
std::move(iv),
data.vduration().value_or_empty(),
qs(data.vauthor().value_or_empty()),
data.is_has_large_media(),
@@ -3607,6 +3667,7 @@ void Session::webpageApplyFields(
PhotoData *photo,
DocumentData *document,
WebPageCollage &&collage,
std::unique_ptr<Iv::Data> iv,
int duration,
const QString &author,
bool hasLargeMedia,
@@ -3623,6 +3684,7 @@ void Session::webpageApplyFields(
photo,
document,
std::move(collage),
std::move(iv),
duration,
author,
hasLargeMedia,
@@ -4530,6 +4592,7 @@ void Session::insertCheckedServiceNotification(
MTPPeer(), // saved_peer_id
MTPMessageFwdHeader(),
MTPlong(), // via_bot_id
MTPlong(), // via_business_bot_id
MTPMessageReplyHeader(),
MTP_int(date),
MTP_string(sending.text),