diff --git a/Telegram/Resources/icons/chat/input_forward.png b/Telegram/Resources/icons/chat/input_forward.png index c04e20ceb..2d9c78335 100644 Binary files a/Telegram/Resources/icons/chat/input_forward.png and b/Telegram/Resources/icons/chat/input_forward.png differ diff --git a/Telegram/Resources/icons/chat/input_forward@2x.png b/Telegram/Resources/icons/chat/input_forward@2x.png index c500804d0..26e435458 100644 Binary files a/Telegram/Resources/icons/chat/input_forward@2x.png and b/Telegram/Resources/icons/chat/input_forward@2x.png differ diff --git a/Telegram/Resources/icons/chat/input_forward@3x.png b/Telegram/Resources/icons/chat/input_forward@3x.png index 9df3f2369..488f8e1e1 100644 Binary files a/Telegram/Resources/icons/chat/input_forward@3x.png and b/Telegram/Resources/icons/chat/input_forward@3x.png differ diff --git a/Telegram/Resources/icons/chat/input_link_settings.png b/Telegram/Resources/icons/chat/input_link_settings.png new file mode 100644 index 000000000..bd01d4ad1 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_link_settings.png differ diff --git a/Telegram/Resources/icons/chat/input_link_settings@2x.png b/Telegram/Resources/icons/chat/input_link_settings@2x.png new file mode 100644 index 000000000..0eb12d203 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_link_settings@2x.png differ diff --git a/Telegram/Resources/icons/chat/input_link_settings@3x.png b/Telegram/Resources/icons/chat/input_link_settings@3x.png new file mode 100644 index 000000000..851858faf Binary files /dev/null and b/Telegram/Resources/icons/chat/input_link_settings@3x.png differ diff --git a/Telegram/Resources/icons/chat/input_reply.png b/Telegram/Resources/icons/chat/input_reply.png deleted file mode 100644 index f20b99773..000000000 Binary files a/Telegram/Resources/icons/chat/input_reply.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_reply@2x.png b/Telegram/Resources/icons/chat/input_reply@2x.png deleted file mode 100644 index e44f5f79e..000000000 Binary files a/Telegram/Resources/icons/chat/input_reply@2x.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_reply@3x.png b/Telegram/Resources/icons/chat/input_reply@3x.png deleted file mode 100644 index 97688789f..000000000 Binary files a/Telegram/Resources/icons/chat/input_reply@3x.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_reply_quote.png b/Telegram/Resources/icons/chat/input_reply_quote.png new file mode 100644 index 000000000..0f0ade5dc Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_quote.png differ diff --git a/Telegram/Resources/icons/chat/input_reply_quote@2x.png b/Telegram/Resources/icons/chat/input_reply_quote@2x.png new file mode 100644 index 000000000..c7bcb7d8e Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_quote@2x.png differ diff --git a/Telegram/Resources/icons/chat/input_reply_quote@3x.png b/Telegram/Resources/icons/chat/input_reply_quote@3x.png new file mode 100644 index 000000000..f1bc500a1 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_quote@3x.png differ diff --git a/Telegram/Resources/icons/chat/input_reply_settings.png b/Telegram/Resources/icons/chat/input_reply_settings.png new file mode 100644 index 000000000..9b67e535c Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_settings.png differ diff --git a/Telegram/Resources/icons/chat/input_reply_settings@2x.png b/Telegram/Resources/icons/chat/input_reply_settings@2x.png new file mode 100644 index 000000000..2a4aef116 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_settings@2x.png differ diff --git a/Telegram/Resources/icons/chat/input_reply_settings@3x.png b/Telegram/Resources/icons/chat/input_reply_settings@3x.png new file mode 100644 index 000000000..e2f131d6a Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_settings@3x.png differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 0c1422ba9..3f6b89211 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2714,6 +2714,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_forwarding_from_two" = "{user} and {second_user}"; "lng_inline_switch_choose" = "Choose conversation..."; "lng_inline_switch_cant" = "Sorry, no way to write here :("; +"lng_preview_reply_to" = "Reply to {name}"; +"lng_preview_reply_to_quote" = "Reply to quote by {name}"; "lng_reply_in_another_title" = "Reply in..."; "lng_reply_in_another_chat" = "Reply in Another Chat"; diff --git a/Telegram/Resources/uwp/AppX/AppxManifest.xml b/Telegram/Resources/uwp/AppX/AppxManifest.xml index 87d43e603..b206163a2 100644 --- a/Telegram/Resources/uwp/AppX/AppxManifest.xml +++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml @@ -10,7 +10,7 @@ <Identity Name="TelegramMessengerLLP.TelegramDesktop" ProcessorArchitecture="ARCHITECTURE" Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A" - Version="4.11.6.0" /> + Version="4.11.7.0" /> <Properties> <DisplayName>Telegram Desktop</DisplayName> <PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName> diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 53ffeebbe..0bbf19b2f 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,11,6,0 - PRODUCTVERSION 4,11,6,0 + FILEVERSION 4,11,7,0 + PRODUCTVERSION 4,11,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -62,10 +62,10 @@ BEGIN BEGIN VALUE "CompanyName", "Radolyn Labs" VALUE "FileDescription", "AyuGram Desktop" - VALUE "FileVersion", "4.11.6.0" + VALUE "FileVersion", "4.11.7.0" VALUE "LegalCopyright", "Copyright (C) 2014-2023" VALUE "ProductName", "AyuGram Desktop" - VALUE "ProductVersion", "4.11.6.0" + VALUE "ProductVersion", "4.11.7.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 22190fb9d..f9e4d3cfd 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,11,6,0 - PRODUCTVERSION 4,11,6,0 + FILEVERSION 4,11,7,0 + PRODUCTVERSION 4,11,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -53,10 +53,10 @@ BEGIN BEGIN VALUE "CompanyName", "Radolyn Labs" VALUE "FileDescription", "AyuGram Desktop Updater" - VALUE "FileVersion", "4.11.6.0" + VALUE "FileVersion", "4.11.7.0" VALUE "LegalCopyright", "Copyright (C) 2014-2023" VALUE "ProductName", "AyuGram Desktop" - VALUE "ProductVersion", "4.11.6.0" + VALUE "ProductVersion", "4.11.7.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/api/api_statistics.cpp b/Telegram/SourceFiles/api/api_statistics.cpp index 383d0973c..1f5c093a6 100644 --- a/Telegram/SourceFiles/api/api_statistics.cpp +++ b/Telegram/SourceFiles/api/api_statistics.cpp @@ -18,6 +18,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Api { namespace { +constexpr auto kCheckRequestsTimer = 10 * crl::time(1000); + [[nodiscard]] Data::StatisticalGraph StatisticalGraphFromTL( const MTPStatsGraph &tl) { return tl.match([&](const MTPDstatsGraph &d) { @@ -187,23 +189,73 @@ namespace { } // namespace -Statistics::Statistics(not_null<ApiWrap*> api) -: _api(&api->instance()) { +Statistics::Statistics(not_null<ChannelData*> channel) +: StatisticsRequestSender(channel) { } -rpl::producer<rpl::no_value, QString> Statistics::request( - not_null<PeerData*> peer) { +StatisticsRequestSender::StatisticsRequestSender(not_null<ChannelData *> channel) +: _channel(channel) +, _api(&_channel->session().api().instance()) +, _timer([=] { checkRequests(); }) { +} + +StatisticsRequestSender::~StatisticsRequestSender() { + for (const auto &[dcId, ids] : _requests) { + for (const auto id : ids) { + _channel->session().api().unregisterStatsRequest(dcId, id); + } + } +} + +void StatisticsRequestSender::checkRequests() { + for (auto i = begin(_requests); i != end(_requests);) { + for (auto j = begin(i->second); j != end(i->second);) { + if (_api.pending(*j)) { + ++j; + } else { + _channel->session().api().unregisterStatsRequest( + i->first, + *j); + j = i->second.erase(j); + } + } + if (i->second.empty()) { + i = _requests.erase(i); + } else { + ++i; + } + } + if (_requests.empty()) { + _timer.cancel(); + } +} + +template <typename Request, typename, typename> +auto StatisticsRequestSender::makeRequest(Request &&request) { + const auto id = _api.allocateRequestId(); + const auto dcId = _channel->owner().statsDcId(_channel); + if (dcId) { + _channel->session().api().registerStatsRequest(dcId, id); + _requests[dcId].emplace(id); + if (!_timer.isActive()) { + _timer.callEach(kCheckRequestsTimer); + } + } + return std::move(_api.request( + std::forward<Request>(request) + ).toDC( + dcId ? MTP::ShiftDcId(dcId, MTP::kStatsDcShift) : 0 + ).overrideId(id)); +} + +rpl::producer<rpl::no_value, QString> Statistics::request() { return [=](auto consumer) { auto lifetime = rpl::lifetime(); - const auto channel = peer->asChannel(); - if (!channel) { - return lifetime; - } - if (!channel->isMegagroup()) { - _api.request(MTPstats_GetBroadcastStats( + if (!channel()->isMegagroup()) { + makeRequest(MTPstats_GetBroadcastStats( MTP_flags(MTPstats_GetBroadcastStats::Flags(0)), - channel->inputChannel + channel()->inputChannel )).done([=](const MTPstats_BroadcastStats &result) { _channelStats = ChannelStatisticsFromTL(result.data()); consumer.put_done(); @@ -211,12 +263,13 @@ rpl::producer<rpl::no_value, QString> Statistics::request( consumer.put_error_copy(error.type()); }).send(); } else { - _api.request(MTPstats_GetMegagroupStats( + makeRequest(MTPstats_GetMegagroupStats( MTP_flags(MTPstats_GetMegagroupStats::Flags(0)), - channel->inputChannel + channel()->inputChannel )).done([=](const MTPstats_MegagroupStats &result) { - _supergroupStats = SupergroupStatisticsFromTL(result.data()); - peer->owner().processUsers(result.data().vusers()); + const auto &data = result.data(); + _supergroupStats = SupergroupStatisticsFromTL(data); + channel()->owner().processUsers(data.vusers()); consumer.put_done(); }).fail([=](const MTP::Error &error) { consumer.put_error_copy(error.type()); @@ -228,18 +281,13 @@ rpl::producer<rpl::no_value, QString> Statistics::request( } Statistics::GraphResult Statistics::requestZoom( - not_null<PeerData*> peer, const QString &token, float64 x) { return [=](auto consumer) { auto lifetime = rpl::lifetime(); - const auto channel = peer->asChannel(); - if (!channel) { - return lifetime; - } const auto wasEmpty = _zoomDeque.empty(); _zoomDeque.push_back([=] { - _api.request(MTPstats_LoadAsyncGraph( + makeRequest(MTPstats_LoadAsyncGraph( MTP_flags(x ? MTPstats_LoadAsyncGraph::Flag::f_x : MTPstats_LoadAsyncGraph::Flag(0)), @@ -266,32 +314,6 @@ Statistics::GraphResult Statistics::requestZoom( }; } -Statistics::GraphResult Statistics::requestMessage( - not_null<PeerData*> peer, - MsgId msgId) { - return [=](auto consumer) { - auto lifetime = rpl::lifetime(); - const auto channel = peer->asChannel(); - if (!channel) { - return lifetime; - } - - _api.request(MTPstats_GetMessageStats( - MTP_flags(MTPstats_GetMessageStats::Flags(0)), - channel->inputChannel, - MTP_int(msgId.bare) - )).done([=](const MTPstats_MessageStats &result) { - consumer.put_next( - StatisticalGraphFromTL(result.data().vviews_graph())); - consumer.put_done(); - }).fail([=](const MTP::Error &error) { - consumer.put_error_copy(error.type()); - }).send(); - - return lifetime; - }; -} - Data::ChannelStatistics Statistics::channelStats() const { return _channelStats; } @@ -303,9 +325,8 @@ Data::SupergroupStatistics Statistics::supergroupStats() const { PublicForwards::PublicForwards( not_null<ChannelData*> channel, FullMsgId fullId) -: _channel(channel) -, _fullId(fullId) -, _api(&channel->session().api().instance()) { +: StatisticsRequestSender(channel) +, _fullId(fullId) { } void PublicForwards::request( @@ -314,19 +335,19 @@ void PublicForwards::request( if (_requestId) { return; } - const auto offsetPeer = _channel->owner().peer(token.fullId.peer); + const auto offsetPeer = channel()->owner().peer(token.fullId.peer); const auto tlOffsetPeer = offsetPeer ? offsetPeer->input : MTP_inputPeerEmpty(); constexpr auto kLimit = tl::make_int(100); - _requestId = _api.request(MTPstats_GetMessagePublicForwards( - _channel->inputChannel, + _requestId = makeRequest(MTPstats_GetMessagePublicForwards( + channel()->inputChannel, MTP_int(_fullId.msg), MTP_int(token.rate), tlOffsetPeer, MTP_int(token.fullId.msg), kLimit - )).done([=, channel = _channel](const MTPmessages_Messages &result) { + )).done([=, channel = channel()](const MTPmessages_Messages &result) { using Messages = QVector<FullMsgId>; _requestId = 0; @@ -402,10 +423,9 @@ void PublicForwards::request( MessageStatistics::MessageStatistics( not_null<ChannelData*> channel, FullMsgId fullId) -: _publicForwards(channel, fullId) -, _channel(channel) -, _fullId(fullId) -, _api(&channel->session().api().instance()) { +: StatisticsRequestSender(channel) +, _publicForwards(channel, fullId) +, _fullId(fullId) { } Data::PublicForwardsSlice MessageStatistics::firstSlice() const { @@ -413,10 +433,9 @@ Data::PublicForwardsSlice MessageStatistics::firstSlice() const { } void MessageStatistics::request(Fn<void(Data::MessageStatistics)> done) { - if (_channel->isMegagroup()) { + if (channel()->isMegagroup()) { return; } - const auto requestFirstPublicForwards = [=]( const Data::StatisticalGraph &messageGraph, const Data::StatisticsMessageInteractionInfo &info) { @@ -434,8 +453,8 @@ void MessageStatistics::request(Fn<void(Data::MessageStatistics)> done) { const auto requestPrivateForwards = [=]( const Data::StatisticalGraph &messageGraph) { - _api.request(MTPchannels_GetMessages( - _channel->inputChannel, + api().request(MTPchannels_GetMessages( + channel()->inputChannel, MTP_vector<MTPInputMessage>( 1, MTP_inputMessageID(MTP_int(_fullId.msg)))) @@ -475,9 +494,9 @@ void MessageStatistics::request(Fn<void(Data::MessageStatistics)> done) { }).send(); }; - _api.request(MTPstats_GetMessageStats( + makeRequest(MTPstats_GetMessageStats( MTP_flags(MTPstats_GetMessageStats::Flags(0)), - _channel->inputChannel, + channel()->inputChannel, MTP_int(_fullId.msg.bare) )).done([=](const MTPstats_MessageStats &result) { requestPrivateForwards( @@ -485,7 +504,6 @@ void MessageStatistics::request(Fn<void(Data::MessageStatistics)> done) { }).fail([=](const MTP::Error &error) { requestPrivateForwards({}); }).send(); - } Boosts::Boosts(not_null<PeerData*> peer) diff --git a/Telegram/SourceFiles/api/api_statistics.h b/Telegram/SourceFiles/api/api_statistics.h index 460c9df9d..dddf3654c 100644 --- a/Telegram/SourceFiles/api/api_statistics.h +++ b/Telegram/SourceFiles/api/api_statistics.h @@ -7,30 +7,53 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +#include "base/timer.h" #include "data/data_boosts.h" #include "data/data_statistics.h" #include "mtproto/sender.h" -class ApiWrap; class ChannelData; class PeerData; namespace Api { -class Statistics final { -public: - explicit Statistics(not_null<ApiWrap*> api); +class StatisticsRequestSender { +protected: + explicit StatisticsRequestSender(not_null<ChannelData*> channel); + ~StatisticsRequestSender(); - [[nodiscard]] rpl::producer<rpl::no_value, QString> request( - not_null<PeerData*> peer); + template < + typename Request, + typename = std::enable_if_t<!std::is_reference_v<Request>>, + typename = typename Request::Unboxed> + [[nodiscard]] auto makeRequest(Request &&request); + + [[nodiscard]] MTP::Sender &api() { + return _api; + } + [[nodiscard]] not_null<ChannelData*> channel() { + return _channel; + } + +private: + void checkRequests(); + + const not_null<ChannelData*> _channel; + MTP::Sender _api; + base::Timer _timer; + base::flat_map<MTP::DcId, base::flat_set<mtpRequestId>> _requests; + +}; + +class Statistics final : public StatisticsRequestSender { +public: + explicit Statistics(not_null<ChannelData*> channel); + + [[nodiscard]] rpl::producer<rpl::no_value, QString> request(); using GraphResult = rpl::producer<Data::StatisticalGraph, QString>; [[nodiscard]] GraphResult requestZoom( - not_null<PeerData*> peer, const QString &token, float64 x); - [[nodiscard]] GraphResult requestMessage( - not_null<PeerData*> peer, - MsgId msgId); [[nodiscard]] Data::ChannelStatistics channelStats() const; [[nodiscard]] Data::SupergroupStatistics supergroupStats() const; @@ -38,31 +61,27 @@ public: private: Data::ChannelStatistics _channelStats; Data::SupergroupStatistics _supergroupStats; - MTP::Sender _api; std::deque<Fn<void()>> _zoomDeque; }; -class PublicForwards final { +class PublicForwards final : public StatisticsRequestSender { public: - explicit PublicForwards(not_null<ChannelData*> channel, FullMsgId fullId); + PublicForwards(not_null<ChannelData*> channel, FullMsgId fullId); void request( const Data::PublicForwardsSlice::OffsetToken &token, Fn<void(Data::PublicForwardsSlice)> done); private: - const not_null<ChannelData*> _channel; const FullMsgId _fullId; mtpRequestId _requestId = 0; int _lastTotal = 0; - MTP::Sender _api; - }; -class MessageStatistics final { +class MessageStatistics final : public StatisticsRequestSender { public: explicit MessageStatistics( not_null<ChannelData*> channel, @@ -74,13 +93,11 @@ public: private: PublicForwards _publicForwards; - const not_null<ChannelData*> _channel; const FullMsgId _fullId; Data::PublicForwardsSlice _firstSlice; mtpRequestId _requestId = 0; - MTP::Sender _api; }; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index c0d7a5bc2..2270743c2 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -118,6 +118,7 @@ constexpr auto kStickersByEmojiInvalidateTimeout = crl::time(6 * 1000); constexpr auto kNotifySettingSaveTimeout = crl::time(1000); constexpr auto kDialogsFirstLoad = 20; constexpr auto kDialogsPerPage = 500; +constexpr auto kStatsSessionKillTimeout = 10 * crl::time(1000); using PhotoFileLocationId = Data::PhotoFileLocationId; using DocumentFileLocationId = Data::DocumentFileLocationId; @@ -163,6 +164,7 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session) , _fileLoader(std::make_unique<TaskQueue>(kFileLoaderQueueStopTimeout)) , _topPromotionTimer([=] { refreshTopPromotion(); }) , _updateNotifyTimer([=] { sendNotifySettingsUpdates(); }) +, _statsSessionKillTimer([=] { checkStatsSessions(); }) , _authorizations(std::make_unique<Api::Authorizations>(this)) , _attachedStickers(std::make_unique<Api::AttachedStickers>(this)) , _blockedPeers(std::make_unique<Api::BlockedPeers>(this)) @@ -3614,11 +3616,12 @@ void ApiWrap::sendMessage(MessageToSend &&message) { sendAction(action); const auto clearCloudDraft = action.clearDraft; + const auto draftTopicRootId = action.replyTo.topicRootId; const auto replyTo = action.replyTo.messageId ? peer->owner().message(action.replyTo.messageId) : nullptr; - const auto topicRootId = action.replyTo.topicRootId - ? action.replyTo.topicRootId + const auto topicRootId = draftTopicRootId + ? draftTopicRootId : replyTo ? replyTo->topicRootId() : Data::ForumTopic::kGeneralId; @@ -3658,7 +3661,10 @@ void ApiWrap::sendMessage(MessageToSend &&message) { TextUtilities::Trim(sending); _session->data().registerMessageRandomId(randomId, newId); - _session->data().registerMessageSentData(randomId, peer->id, sending.text); + _session->data().registerMessageSentData( + randomId, + peer->id, + sending.text); MTPstring msgText(MTP_string(sending.text)); auto flags = NewMessageFlags(peer); @@ -3720,8 +3726,8 @@ void ApiWrap::sendMessage(MessageToSend &&message) { if (clearCloudDraft) { sendFlags |= MTPmessages_SendMessage::Flag::f_clear_draft; mediaFlags |= MTPmessages_SendMedia::Flag::f_clear_draft; - history->clearCloudDraft(topicRootId); - history->startSavingCloudDraft(topicRootId); + history->clearCloudDraft(draftTopicRootId); + history->startSavingCloudDraft(draftTopicRootId); } const auto sendAs = action.options.sendAs; const auto messageFromId = sendAs @@ -3758,7 +3764,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) { const MTP::Response &response) { if (clearCloudDraft) { history->finishSavingCloudDraft( - topicRootId, + draftTopicRootId, UnixtimeFromMsgId(response.outerMsgId)); } }; @@ -3772,7 +3778,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) { } if (clearCloudDraft) { history->finishSavingCloudDraft( - topicRootId, + draftTopicRootId, UnixtimeFromMsgId(response.outerMsgId)); } }; @@ -4340,6 +4346,32 @@ void ApiWrap::saveSelfBio(const QString &text) { }).send(); } +void ApiWrap::registerStatsRequest(MTP::DcId dcId, mtpRequestId id) { + _statsRequests[dcId].emplace(id); +} + +void ApiWrap::unregisterStatsRequest(MTP::DcId dcId, mtpRequestId id) { + const auto i = _statsRequests.find(dcId); + Assert(i != end(_statsRequests)); + const auto removed = i->second.remove(id); + Assert(removed); + if (i->second.empty()) { + _statsSessionKillTimer.callOnce(kStatsSessionKillTimeout); + } +} + +void ApiWrap::checkStatsSessions() { + for (auto i = begin(_statsRequests); i != end(_statsRequests);) { + if (i->second.empty()) { + instance().killSession( + MTP::ShiftDcId(i->first, MTP::kStatsDcShift)); + i = _statsRequests.erase(i); + } else { + ++i; + } + } +} + Api::Authorizations &ApiWrap::authorizations() { return *_authorizations; } diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index f61eb0957..ecb0f968a 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -369,6 +369,9 @@ public: void saveSelfBio(const QString &text); + void registerStatsRequest(MTP::DcId dcId, mtpRequestId id); + void unregisterStatsRequest(MTP::DcId dcId, mtpRequestId id); + [[nodiscard]] Api::Authorizations &authorizations(); [[nodiscard]] Api::AttachedStickers &attachedStickers(); [[nodiscard]] Api::BlockedPeers &blockedPeers(); @@ -547,6 +550,8 @@ private: not_null<ChannelData*> channel); void migrateFail(not_null<PeerData*> peer, const QString &error); + void checkStatsSessions(); + const not_null<Main::Session*> _session; base::flat_map<QString, int> _modifyRequests; @@ -683,6 +688,9 @@ private: QString requestedText; } _bio; + base::flat_map<MTP::DcId, base::flat_set<mtpRequestId>> _statsRequests; + base::Timer _statsSessionKillTimer; + const std::unique_ptr<Api::Authorizations> _authorizations; const std::unique_ptr<Api::AttachedStickers> _attachedStickers; const std::unique_ptr<Api::BlockedPeers> _blockedPeers; diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index d100850ee..3739ef7e3 100644 --- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style +++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style @@ -827,11 +827,13 @@ historyEmojiStatusInfoLabel: FlatLabel(historyContactStatusLabel) { } historyContactStatusMinSkip: 16px; -historyReplySkip: 51px; +historyReplySkip: 53px; historyReplyNameFg: windowActiveTextFg; historyReplyHeight: 49px; -historyReplyIconPosition: point(5px, 5px); -historyReplyIcon: icon {{ "chat/input_reply", historyReplyIconFg }}; +historyReplyIconPosition: point(7px, 7px); +historyReplyIcon: icon {{ "chat/input_reply_settings", historyReplyIconFg }}; +historyLinkIcon: icon {{ "chat/input_link_settings", historyReplyIconFg }}; +historyQuoteIcon: icon {{ "chat/input_reply_quote", historyReplyIconFg }}; historyForwardIcon: icon {{ "chat/input_forward", historyReplyIconFg }}; historyEditIcon: icon {{ "chat/input_edit", historyReplyIconFg }}; historyReplyCancel: IconButton { diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index b44f257ca..b32542428 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D666}"_cs; constexpr auto AppNameOld = "AyuGram for Windows"_cs; constexpr auto AppName = "AyuGram Desktop"_cs; constexpr auto AppFile = "AyuGram"_cs; -constexpr auto AppVersion = 4011006; -constexpr auto AppVersionStr = "4.11.6"; +constexpr auto AppVersion = 4011007; +constexpr auto AppVersionStr = "4.11.7"; constexpr auto AppBetaVersion = false; constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION; diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 3b26c1eb9..5daff7e17 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -1120,6 +1120,10 @@ void ApplyChannelUpdate( channel, update.vnotify_settings()); + if (update.vstats_dc()) { + channel->owner().applyStatsDcId(channel, update.vstats_dc()->v); + } + if (const auto sendAs = update.vdefault_send_as()) { session->sendAsPeers().setChosen(channel, peerFromMTP(*sendAs)); } else { diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 8590e1fa6..85aa659f8 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -4567,6 +4567,19 @@ uint64 Session::wallpapersHash() const { return _wallpapersHash; } +MTP::DcId Session::statsDcId(not_null<ChannelData*> channel) { + const auto it = _channelStatsDcIds.find(channel); + return (it == end(_channelStatsDcIds)) ? MTP::DcId(0) : it->second; +} + +void Session::applyStatsDcId( + not_null<ChannelData*> channel, + MTP::DcId dcId) { + if (dcId != channel->session().mainDcId()) { + _channelStatsDcIds[channel] = dcId; + } +} + void Session::webViewResultSent(WebViewResultSent &&sent) { return _webViewResultSent.fire(std::move(sent)); } diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index c470e3a8b..df6dc5019 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -730,6 +730,9 @@ public: [[nodiscard]] auto peerDecorationsUpdated() const -> rpl::producer<not_null<PeerData*>>; + void applyStatsDcId(not_null<ChannelData*>, MTP::DcId); + [[nodiscard]] MTP::DcId statsDcId(not_null<ChannelData*>); + void clearLocalStorage(); private: @@ -1014,6 +1017,8 @@ private: base::flat_map<not_null<UserData*>, TimeId> _watchingForOffline; base::Timer _watchForOfflineTimer; + base::flat_map<not_null<ChannelData*>, MTP::DcId> _channelStatsDcIds; + rpl::event_stream<WebViewResultSent> _webViewResultSent; rpl::event_stream<not_null<PeerData*>> _peerDecorationsUpdated; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index e71c3cefd..5299b648c 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -879,7 +879,7 @@ void RowPainter::Paint( } return nullptr; }(); - const auto previewOptions = [&]() -> HistoryView::ToPreviewOptions { + auto previewOptions = [&]() -> HistoryView::ToPreviewOptions { if (topic) { return {}; } else if (const auto searchChat = row->searchInChat()) { @@ -891,6 +891,7 @@ void RowPainter::Paint( } return {}; }(); + previewOptions.ignoreGroup = true; const auto badgesState = context.displayUnreadInfo ? entry->chatListBadgesState() diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index cdd0811dd..f8f5b9ba7 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -2956,11 +2956,22 @@ FullStoryId HistoryItem::replyToStory() const { } FullReplyTo HistoryItem::replyTo() const { - return { - .messageId = replyToFullId(), - .storyId = replyToStory(), + auto result = FullReplyTo{ .topicRootId = topicRootId(), }; + if (const auto reply = Get<HistoryMessageReply>()) { + const auto &fields = reply->fields(); + const auto peer = fields.externalPeerId; + const auto replyToPeer = peer ? peer : _history->peer->id; + if (const auto id = fields.messageId) { + result.messageId = { replyToPeer, id }; + result.quote = fields.quote; + } + if (const auto id = fields.storyId) { + result.storyId = { replyToPeer, id }; + } + } + return result; } void HistoryItem::setText(const TextWithEntities &textWithEntities) { diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 3c1ad01e6..7049d94d1 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -101,6 +101,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_pinned_bar.h" #include "history/view/history_view_group_call_bar.h" #include "history/view/history_view_item_preview.h" +#include "history/view/history_view_reply.h" #include "history/view/history_view_requests_bar.h" #include "history/view/history_view_sticker_toast.h" #include "history/view/history_view_translate_bar.h" @@ -4395,11 +4396,10 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) { void HistoryWidget::updateOverStates(QPoint pos) { const auto isReadyToForward = readyToForward(); - const auto skip = isReadyToForward ? 0 : st::historyReplySkip; const auto detailsRect = QRect( - skip, + 0, _field->y() - st::historySendPadding - st::historyReplyHeight, - width() - skip - _fieldBarCancel->width(), + width() - _fieldBarCancel->width(), st::historyReplyHeight); const auto hasWebPage = !!_previewDrawPreview; const auto inDetails = detailsRect.contains(pos) @@ -4439,10 +4439,6 @@ void HistoryWidget::leaveToChildEvent(QEvent *e, QWidget *child) { // e -- from } void HistoryWidget::mouseReleaseEvent(QMouseEvent *e) { - if (_replyForwardPressed) { - _replyForwardPressed = false; - update(0, _field->y() - st::historySendPadding - st::historyReplyHeight, width(), st::historyReplyHeight); - } } void HistoryWidget::sendBotCommand(const Bot::SendCommandRequest &request) { @@ -6264,20 +6260,7 @@ bool HistoryWidget::cornerButtonsHas(HistoryView::CornerButtonType type) { void HistoryWidget::mousePressEvent(QMouseEvent *e) { const auto isReadyToForward = readyToForward(); - const auto hasSecondLayer = (_editMsgId - || _replyTo - || isReadyToForward - || _kbReplyTo); - _replyForwardPressed = hasSecondLayer && QRect( - 0, - _field->y() - st::historySendPadding - st::historyReplyHeight, - st::historyReplySkip, - st::historyReplyHeight).contains(e->pos()); - if (_replyForwardPressed - && !_fieldBarCancel->isHidden() - && !isReadyToForward) { - updateField(); - } else if (_inPhotoEdit && _photoEditMedia) { + if (_inPhotoEdit && _photoEditMedia) { EditCaptionBox::StartPhotoEdit( controller(), _photoEditMedia, @@ -7507,7 +7490,6 @@ void HistoryWidget::cancelEdit() { void HistoryWidget::cancelFieldAreaState() { controller()->hideLayer(); - _replyForwardPressed = false; if (_previewDrawPreview) { _preview->apply({ .removed = true }); } else if (_editMsgId) { @@ -7839,25 +7821,23 @@ void HistoryWidget::updateForwarding() { } void HistoryWidget::updateReplyToName() { - if (_editMsgId) { + if (!_history || _editMsgId) { return; } else if (!_replyEditMsg && (_replyTo || !_kbReplyTo)) { return; } - const auto from = [&] { - const auto item = _replyEditMsg ? _replyEditMsg : _kbReplyTo; - if (const auto from = item->displayFrom()) { - return from; - } - return item->author().get(); - }(); - _replyToName.setText( - st::msgNameStyle, - from->name(), - Ui::NameTextOptions()); - _replyToNameVersion = (_replyEditMsg - ? _replyEditMsg - : _kbReplyTo)->author()->nameVersion(); + const auto context = Core::MarkedTextContext{ + .session = &_history->session(), + .customEmojiRepaint = [] {}, + .customEmojiLoopLimit = 1, + }; + const auto to = _replyEditMsg ? _replyEditMsg : _kbReplyTo; + const auto replyToQuote = _replyTo && !_replyTo.quote.empty(); + _replyToName.setMarkedText( + st::fwdTextStyle, + HistoryView::Reply::ComposePreviewName(_history, to, replyToQuote), + Ui::NameTextOptions(), + context); } void HistoryWidget::updateField() { @@ -7877,12 +7857,6 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) { auto hasForward = readyToForward(); auto drawMsgText = (_editMsgId || _replyTo) ? _replyEditMsg : _kbReplyTo; if (_editMsgId || _replyTo || (!hasForward && _kbReplyTo)) { - if (!_editMsgId - && drawMsgText - && (_replyToNameVersion - < drawMsgText->author()->nameVersion())) { - updateReplyToName(); - } backy -= st::historyReplyHeight; backh += st::historyReplyHeight; } else if (hasForward) { @@ -7892,12 +7866,11 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) { backy -= st::historyReplyHeight; backh += st::historyReplyHeight; } - auto drawWebPagePreview = _previewDrawPreview && !_replyForwardPressed; p.setInactive( controller()->isGifPausedAtLeastFor(Window::GifPauseReason::Any)); p.fillRect(myrtlrect(0, backy, width(), backh), st::historyReplyBg); - const auto media = (!drawWebPagePreview && drawMsgText) + const auto media = (!_previewDrawPreview && drawMsgText) ? drawMsgText->media() : nullptr; const auto hasPreview = media && media->hasReplyPreview(); @@ -7911,86 +7884,11 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) { }); } - if (_editMsgId || _replyTo || (!hasForward && _kbReplyTo)) { - const auto now = crl::now(); - const auto paused = p.inactive(); - const auto pausedSpoiler = paused || On(PowerSaving::kChatSpoiler); - auto replyLeft = st::historyReplySkip; - (_editMsgId ? st::historyEditIcon : st::historyReplyIcon).paint(p, st::historyReplyIconPosition + QPoint(0, backy), width()); - if (!drawWebPagePreview) { - if (drawMsgText) { - if (hasPreview) { - if (preview) { - const auto overEdit = _photoEditMedia - ? _inPhotoEditOver.value(_inPhotoEdit ? 1. : 0.) - : 0.; - auto to = QRect( - replyLeft, - backy + (st::historyReplyHeight - st::historyReplyPreview) / 2, - st::historyReplyPreview, - st::historyReplyPreview); - p.drawPixmap(to.x(), to.y(), preview->pixSingle( - preview->size() / style::DevicePixelRatio(), - { - .options = Images::Option::RoundSmall, - .outer = to.size(), - })); - if (_replySpoiler) { - if (overEdit > 0.) { - p.setOpacity(1. - overEdit); - } - Ui::FillSpoilerRect( - p, - to, - Ui::DefaultImageSpoiler().frame( - _replySpoiler->index(now, pausedSpoiler))); - } - if (overEdit > 0.) { - p.setOpacity(overEdit); - p.fillRect(to, st::historyEditMediaBg); - st::historyEditMedia.paintInCenter(p, to); - p.setOpacity(1.); - } - } - replyLeft += st::historyReplyPreview + st::msgReplyBarSkip; - } - p.setPen(st::historyReplyNameFg); - if (_editMsgId) { - paintEditHeader(p, rect, replyLeft, backy); - } else { - _replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); - } - p.setPen(st::historyComposeAreaFg); - _replyEditMsgText.draw(p, { - .position = QPoint( - replyLeft, - backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height), - .availableWidth = width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right(), - .palette = &st::historyComposeAreaPalette, - .spoiler = Ui::Text::DefaultSpoilerCache(), - .now = now, - .pausedEmoji = paused || On(PowerSaving::kEmojiChat), - .pausedSpoiler = pausedSpoiler, - .elisionLines = 1, - }); - } else { - p.setFont(st::msgDateFont); - p.setPen(st::historyComposeAreaFgService); - p.drawText(replyLeft, backy + (st::historyReplyHeight - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(tr::lng_profile_loading(tr::now), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right())); - } - } - } else if (hasForward) { - st::historyForwardIcon.paint(p, st::historyReplyIconPosition + QPoint(0, backy), width()); - if (!drawWebPagePreview) { - const auto x = st::historyReplySkip; - const auto available = width() - - x - - _fieldBarCancel->width() - - st::msgReplyPadding.right(); - _forwardPanel->paint(p, x, backy, available, width()); - } - } - if (drawWebPagePreview) { + if (_previewDrawPreview) { + st::historyLinkIcon.paint( + p, + st::historyReplyIconPosition + QPoint(0, backy), + width()); const auto textTop = backy + st::msgReplyPadding.top(); auto previewLeft = st::historyReplySkip; @@ -8019,6 +7917,87 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) { previewLeft, textTop + st::msgServiceNameFont->height, elidedWidth); + } else if (_editMsgId || _replyTo || (!hasForward && _kbReplyTo)) { + const auto now = crl::now(); + const auto paused = p.inactive(); + const auto pausedSpoiler = paused || On(PowerSaving::kChatSpoiler); + auto replyLeft = st::historyReplySkip; + (_editMsgId + ? st::historyEditIcon + : (_replyTo && !_replyTo.quote.empty()) + ? st::historyQuoteIcon + : st::historyReplyIcon).paint( + p, + st::historyReplyIconPosition + QPoint(0, backy), + width()); + if (drawMsgText) { + if (hasPreview) { + if (preview) { + const auto overEdit = _photoEditMedia + ? _inPhotoEditOver.value(_inPhotoEdit ? 1. : 0.) + : 0.; + auto to = QRect( + replyLeft, + backy + (st::historyReplyHeight - st::historyReplyPreview) / 2, + st::historyReplyPreview, + st::historyReplyPreview); + p.drawPixmap(to.x(), to.y(), preview->pixSingle( + preview->size() / style::DevicePixelRatio(), + { + .options = Images::Option::RoundSmall, + .outer = to.size(), + })); + if (_replySpoiler) { + if (overEdit > 0.) { + p.setOpacity(1. - overEdit); + } + Ui::FillSpoilerRect( + p, + to, + Ui::DefaultImageSpoiler().frame( + _replySpoiler->index(now, pausedSpoiler))); + } + if (overEdit > 0.) { + p.setOpacity(overEdit); + p.fillRect(to, st::historyEditMediaBg); + st::historyEditMedia.paintInCenter(p, to); + p.setOpacity(1.); + } + } + replyLeft += st::historyReplyPreview + st::msgReplyBarSkip; + } + p.setPen(st::historyReplyNameFg); + if (_editMsgId) { + paintEditHeader(p, rect, replyLeft, backy); + } else { + _replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); + } + p.setPen(st::historyComposeAreaFg); + _replyEditMsgText.draw(p, { + .position = QPoint( + replyLeft, + backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height), + .availableWidth = width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right(), + .palette = &st::historyComposeAreaPalette, + .spoiler = Ui::Text::DefaultSpoilerCache(), + .now = now, + .pausedEmoji = paused || On(PowerSaving::kEmojiChat), + .pausedSpoiler = pausedSpoiler, + .elisionLines = 1, + }); + } else { + p.setFont(st::msgDateFont); + p.setPen(st::historyComposeAreaFgService); + p.drawText(replyLeft, backy + (st::historyReplyHeight - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(tr::lng_profile_loading(tr::now), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right())); + } + } else if (hasForward) { + st::historyForwardIcon.paint(p, st::historyReplyIconPosition + QPoint(0, backy), width()); + const auto x = st::historyReplySkip; + const auto available = width() + - x + - _fieldBarCancel->width() + - st::msgReplyPadding.right(); + _forwardPanel->paint(p, x, backy, available, width()); } } diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 87b7edde9..10a54c858 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -647,7 +647,6 @@ private: MTP::Sender _api; FullReplyTo _replyTo; Ui::Text::String _replyToName; - int _replyToNameVersion = 0; FullReplyTo _processingReplyTo; HistoryItem *_processingReplyItem = nullptr; @@ -688,8 +687,6 @@ private: Ui::Text::String _previewTitle; Ui::Text::String _previewDescription; - bool _replyForwardPressed = false; - PeerData *_peer = nullptr; bool _canSendMessages = false; diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index 540d4ca5f..8b9ac3393 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -51,6 +51,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/controls/history_view_voice_record_bar.h" #include "history/view/controls/history_view_ttl_button.h" #include "history/view/controls/history_view_webpage_processor.h" +#include "history/view/history_view_reply.h" #include "history/view/history_view_webpage_preview.h" #include "inline_bots/bot_attach_web_view.h" #include "inline_bots/inline_results_widget.h" @@ -192,7 +193,6 @@ private: Ui::Text::String _shownMessageText; std::unique_ptr<Ui::SpoilerAnimation> _shownPreviewSpoiler; Ui::Animations::Simple _inPhotoEditOver; - int _shownMessageNameVersion = -1; bool _shownMessageHasPreview : 1 = false; bool _inPhotoEdit : 1 = false; bool _photoEditAllowed : 1 = false; @@ -245,7 +245,6 @@ void FieldHeader::init() { updateVisible(); }, lifetime()); - const auto leftIconPressed = lifetime().make_state<bool>(false); paintRequest( ) | rpl::start_with_next([=] { Painter p(this); @@ -253,21 +252,29 @@ void FieldHeader::init() { p.fillRect(rect(), st::historyComposeAreaBg); const auto position = st::historyReplyIconPosition; - if (isEditingMessage()) { + if (_preview.parsed) { + st::historyLinkIcon.paint(p, position, width()); + } else if (isEditingMessage()) { st::historyEditIcon.paint(p, position, width()); } else if (readyToForward()) { st::historyForwardIcon.paint(p, position, width()); - } else if (replyingToMessage()) { - st::historyReplyIcon.paint(p, position, width()); + } else if (const auto reply = replyingToMessage()) { + if (!reply.quote.empty()) { + st::historyQuoteIcon.paint(p, position, width()); + } else { + st::historyReplyIcon.paint(p, position, width()); + } } - (_preview.parsed && !*leftIconPressed) - ? paintWebPage( + if (_preview.parsed) { + paintWebPage( p, - _history ? _history->peer : _data->session().user()) - : (isEditingMessage() || !readyToForward()) - ? paintEditOrReplyToMessage(p) - : paintForwardInfo(p); + _history ? _history->peer : _data->session().user()); + } else if (isEditingMessage() || !readyToForward()) { + paintEditOrReplyToMessage(p); + } else { + paintForwardInfo(p); + } }, lifetime()); _editMsgId.value( @@ -359,13 +366,9 @@ void FieldHeader::init() { updateOver(inPreviewRect, inPhotoEdit); return; } - const auto isLeftIcon = (pos.x() < st::historyReplySkip); const auto isLeftButton = (e->button() == Qt::LeftButton); if (type == QEvent::MouseButtonPress) { - if (isLeftButton && isLeftIcon && !inPreviewRect) { - *leftIconPressed = true; - update(); - } else if (isLeftButton && inPhotoEdit) { + if (isLeftButton && inPhotoEdit) { _editPhotoRequests.fire({}); } else if (isLeftButton && inPreviewRect) { const auto reply = replyingToMessage(); @@ -384,11 +387,6 @@ void FieldHeader::init() { _editOptionsRequests.fire({}); } } - } else if (type == QEvent::MouseButtonRelease) { - if (isLeftButton && *leftIconPressed) { - *leftIconPressed = false; - update(); - } } }, lifetime()); } @@ -431,9 +429,21 @@ void FieldHeader::setShownMessage(HistoryItem *item) { st::msgNameStyle, tr::lng_edit_message(tr::now), Ui::NameTextOptions()); + } else if (item) { + const auto context = Core::MarkedTextContext{ + .session = &_history->session(), + .customEmojiRepaint = [] {}, + .customEmojiLoopLimit = 1, + }; + const auto replyTo = _replyTo.current(); + const auto quote = replyTo && !replyTo.quote.empty(); + _shownMessageName.setMarkedText( + st::fwdTextStyle, + HistoryView::Reply::ComposePreviewName(_history, item, quote), + Ui::NameTextOptions(), + context); } else { _shownMessageName.clear(); - _shownMessageNameVersion = -1; } updateVisible(); update(); @@ -545,19 +555,6 @@ void FieldHeader::paintEditOrReplyToMessage(Painter &p) { return; } - if (!isEditingMessage()) { - const auto user = _shownMessage->displayFrom() - ? _shownMessage->displayFrom() - : _shownMessage->author().get(); - if (_shownMessageNameVersion < user->nameVersion()) { - _shownMessageName.setText( - st::msgNameStyle, - user->name(), - Ui::NameTextOptions()); - _shownMessageNameVersion = user->nameVersion(); - } - } - const auto media = _shownMessage->media(); _shownMessageHasPreview = media && media->hasReplyPreview(); const auto preview = _shownMessageHasPreview @@ -691,13 +688,11 @@ FullReplyTo FieldHeader::getDraftReply() const { } void FieldHeader::updateControlsGeometry(QSize size) { - const auto isReadyToForward = readyToForward(); - const auto skip = isReadyToForward ? 0 : st::historyReplySkip; _cancel->moveToRight(0, 0); _clickableRect = QRect( - skip, 0, - width() - skip - _cancel->width(), + 0, + width() - _cancel->width(), height()); _shownMessagePreviewRect = QRect( st::historyReplySkip, diff --git a/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp b/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp index 850ecfe6b..6812cb273 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp @@ -642,6 +642,8 @@ void DraftOptionsBox( if (const auto current = state->quote.current()) { result.messageId = current.item->fullId(); result.quote = current.text; + } else { + result.quote = {}; } return result; }; diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 9b5334a5c..127049416 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -1676,21 +1676,27 @@ TextSelection Element::FindSelectionFromQuote( } offset = i + 1; } - //for (const auto &modification : text.modifications()) { - // if (modification.position >= selection.to) { - // break; - // } else if (modification.position <= selection.from) { - // modified.from += modification.skipped; - // if (modification.added - // && modification.position < selection.from) { - // --modified.from; - // } - // } - // modified.to += modification.skipped; - // if (modification.added && modified.to > modified.from) { - // --modified.to; - // } - //} + for (const auto &modification : text.modifications()) { + if (modification.position >= result.to) { + break; + } + if (modification.added) { + ++result.to; + } + const auto shiftTo = std::min( + int(modification.skipped), + result.to - modification.position); + result.to -= shiftTo; + if (modification.position <= result.from) { + if (modification.added) { + ++result.from; + } + const auto shiftFrom = std::min( + int(modification.skipped), + result.from - modification.position); + result.from -= shiftFrom; + } + } return result; } diff --git a/Telegram/SourceFiles/history/view/history_view_reply.cpp b/Telegram/SourceFiles/history/view/history_view_reply.cpp index fad3d0e56..2abe667ea 100644 --- a/Telegram/SourceFiles/history/view/history_view_reply.cpp +++ b/Telegram/SourceFiles/history/view/history_view_reply.cpp @@ -398,10 +398,11 @@ void Reply::updateName( viaBotUsername = bot->username(); } } + const auto history = view->history(); const auto &fields = data->fields(); const auto sender = resolvedSender.value_or(this->sender(view, data)); const auto externalPeer = fields.externalPeerId - ? view->history()->owner().peer(fields.externalPeerId).get() + ? history->owner().peer(fields.externalPeerId).get() : nullptr; const auto displayAsExternal = data->displayAsExternal(view->data()); const auto groupNameAdded = displayAsExternal @@ -419,38 +420,20 @@ void Reply::updateName( + st::historyReplyPreviewMargin.right() - st::historyReplyPadding.left()) : 0; - const auto peerIcon = [](PeerData *peer) { - using namespace std; - return !peer - ? pair(&st::historyReplyUser, st::historyReplyUserPadding) - : peer->isBroadcast() - ? pair(&st::historyReplyChannel, st::historyReplyChannelPadding) - : (peer->isChannel() || peer->isChat()) - ? pair(&st::historyReplyGroup, st::historyReplyGroupPadding) - : pair(&st::historyReplyUser, st::historyReplyUserPadding); - }; - const auto peerEmoji = [&](PeerData *peer) { - const auto owner = &view->history()->owner(); - const auto icon = peerIcon(peer); - return Ui::Text::SingleCustomEmoji( - owner->customEmojiManager().registerInternalEmoji( - *icon.first, - icon.second)); - }; auto nameFull = TextWithEntities(); if (displayAsExternal && !groupNameAdded && !fields.storyId) { - nameFull.append(peerEmoji(sender)); + nameFull.append(PeerEmoji(history, sender)); } nameFull.append(name); if (groupNameAdded) { - nameFull.append(' ').append(peerEmoji(externalPeer)); + nameFull.append(' ').append(PeerEmoji(history, externalPeer)); nameFull.append(externalPeer->name()); } if (!viaBotUsername.isEmpty()) { nameFull.append(u" @"_q).append(viaBotUsername); } const auto context = Core::MarkedTextContext{ - .session = &view->history()->session(), + .session = &history->session(), .customEmojiRepaint = [] {}, .customEmojiLoopLimit = 1, }; @@ -819,6 +802,61 @@ void Reply::stopLastRipple() { } } +TextWithEntities Reply::PeerEmoji( + not_null<History*> history, + PeerData *peer) { + using namespace std; + const auto icon = !peer + ? pair(&st::historyReplyUser, st::historyReplyUserPadding) + : peer->isBroadcast() + ? pair(&st::historyReplyChannel, st::historyReplyChannelPadding) + : (peer->isChannel() || peer->isChat()) + ? pair(&st::historyReplyGroup, st::historyReplyGroupPadding) + : pair(&st::historyReplyUser, st::historyReplyUserPadding); + const auto owner = &history->owner(); + return Ui::Text::SingleCustomEmoji( + owner->customEmojiManager().registerInternalEmoji( + *icon.first, + icon.second)); +} + +TextWithEntities Reply::ComposePreviewName( + not_null<History*> history, + not_null<HistoryItem*> to, + bool quote) { + const auto sender = [&] { + if (const auto from = to->displayFrom()) { + return not_null(from); + } + return to->author(); + }(); + const auto toPeer = to->history()->peer; + const auto displayAsExternal = (to->history() != history); + const auto groupNameAdded = displayAsExternal + && (toPeer != sender) + && (toPeer->isChat() || toPeer->isMegagroup()); + const auto shorten = groupNameAdded || quote; + + auto nameFull = TextWithEntities(); + using namespace HistoryView; + if (displayAsExternal && !groupNameAdded) { + nameFull.append(Reply::PeerEmoji(history, sender)); + } + nameFull.append(shorten ? sender->shortName() : sender->name()); + if (groupNameAdded) { + nameFull.append(' ').append(Reply::PeerEmoji(history, toPeer)); + nameFull.append(toPeer->name()); + } + return (quote + ? tr::lng_preview_reply_to_quote + : tr::lng_preview_reply_to)( + tr::now, + lt_name, + nameFull, + Ui::Text::WithEntities); + +} + void Reply::unloadPersistentAnimation() { _text.unloadPersistentAnimation(); } diff --git a/Telegram/SourceFiles/history/view/history_view_reply.h b/Telegram/SourceFiles/history/view/history_view_reply.h index 5322d5c09..4b30a842d 100644 --- a/Telegram/SourceFiles/history/view/history_view_reply.h +++ b/Telegram/SourceFiles/history/view/history_view_reply.h @@ -63,6 +63,14 @@ public: return _link; } + [[nodiscard]] static TextWithEntities PeerEmoji( + not_null<History*> history, + PeerData *peer); + [[nodiscard]] static TextWithEntities ComposePreviewName( + not_null<History*> history, + not_null<HistoryItem*> to, + bool quote); + private: [[nodiscard]] Ui::Text::GeometryDescriptor textGeometry( int available, diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp index 19704c779..694c67fb5 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_inner_widget.cpp @@ -91,7 +91,6 @@ void ProcessZoom( widget->zoomRequests( ) | rpl::start_with_next([=](float64 x) { d.api->requestZoom( - d.peer, zoomToken, x ) | rpl::start_with_next_error_done([=]( @@ -144,7 +143,6 @@ void FillStatistic( m); descriptor.api->requestZoom( - descriptor.peer, graphData.zoomToken, 0 ) | rpl::start_with_next_error_done([=, graphPtr = &graphData]( @@ -524,7 +522,7 @@ void InnerWidget::load() { const auto descriptor = Descriptor{ _peer, - lifetime().make_state<Api::Statistics>(&_peer->session().api()), + lifetime().make_state<Api::Statistics>(_peer->asChannel()), _controller->uiShow()->toastParent(), }; @@ -543,7 +541,6 @@ void InnerWidget::load() { ) | rpl::take(1) | rpl::start_with_next([=] { if (!_contextId) { descriptor.api->request( - descriptor.peer ) | rpl::start_with_done([=] { _state.stats = Data::AnyStatistics{ descriptor.api->channelStats(), @@ -575,7 +572,7 @@ void InnerWidget::fill() { const auto inner = this; const auto descriptor = Descriptor{ _peer, - lifetime().make_state<Api::Statistics>(&_peer->session().api()), + lifetime().make_state<Api::Statistics>(_peer->asChannel()), _controller->uiShow()->toastParent(), }; if (_state.stats.message) { @@ -705,8 +702,9 @@ void InnerWidget::fillRecentPosts() { container, tr::lng_stories_show_more()))); - constexpr auto kPerPage = int(10); - const auto max = stats.recentMessageInteractions.size(); + constexpr auto kFirstPage = int(10); + constexpr auto kPerPage = int(30); + const auto max = int(stats.recentMessageInteractions.size()); if (_state.recentPostsExpanded) { _state.recentPostsExpanded = std::max( _state.recentPostsExpanded - kPerPage, @@ -715,8 +713,10 @@ void InnerWidget::fillRecentPosts() { const auto showMore = [=] { const auto from = _state.recentPostsExpanded; _state.recentPostsExpanded = std::min( - int(max), - _state.recentPostsExpanded + kPerPage); + max, + _state.recentPostsExpanded + ? (_state.recentPostsExpanded + kPerPage) + : kFirstPage); if (_state.recentPostsExpanded == max) { buttonWrap->toggle(false, anim::type::instant); } diff --git a/Telegram/SourceFiles/mtproto/core_types.h b/Telegram/SourceFiles/mtproto/core_types.h index 0437644be..75287ceba 100644 --- a/Telegram/SourceFiles/mtproto/core_types.h +++ b/Telegram/SourceFiles/mtproto/core_types.h @@ -47,6 +47,7 @@ constexpr auto kUpdaterDcShift = 0x03; constexpr auto kExportDcShift = 0x04; constexpr auto kExportMediaDcShift = 0x05; constexpr auto kGroupCallStreamDcShift = 0x06; +constexpr auto kStatsDcShift = 0x07; constexpr auto kMaxMediaDcCount = 0x10; constexpr auto kBaseDownloadDcShift = 0x10; constexpr auto kBaseUploadDcShift = 0x20; diff --git a/Telegram/SourceFiles/mtproto/mtp_instance.h b/Telegram/SourceFiles/mtproto/mtp_instance.h index 2a3bc3d4e..7dc5be49b 100644 --- a/Telegram/SourceFiles/mtproto/mtp_instance.h +++ b/Telegram/SourceFiles/mtproto/mtp_instance.h @@ -150,8 +150,11 @@ public: ResponseHandler &&callbacks = {}, ShiftedDcId shiftedDcId = 0, crl::time msCanWait = 0, - mtpRequestId afterRequestId = 0) { - const auto requestId = details::GetNextRequestId(); + mtpRequestId afterRequestId = 0, + mtpRequestId overrideRequestId = 0) { + const auto requestId = overrideRequestId + ? overrideRequestId + : details::GetNextRequestId(); sendSerialized( requestId, details::SerializedRequest::Serialize(request), @@ -169,13 +172,15 @@ public: FailHandler &&onFail = nullptr, ShiftedDcId shiftedDcId = 0, crl::time msCanWait = 0, - mtpRequestId afterRequestId = 0) { + mtpRequestId afterRequestId = 0, + mtpRequestId overrideRequestId = 0) { return send( request, ResponseHandler{ std::move(onDone), std::move(onFail) }, shiftedDcId, msCanWait, - afterRequestId); + afterRequestId, + overrideRequestId); } template <typename Request> diff --git a/Telegram/SourceFiles/mtproto/sender.h b/Telegram/SourceFiles/mtproto/sender.h index 632f817f4..5330a0559 100644 --- a/Telegram/SourceFiles/mtproto/sender.h +++ b/Telegram/SourceFiles/mtproto/sender.h @@ -130,6 +130,9 @@ class Sender { void setToDC(ShiftedDcId dcId) noexcept { _dcId = dcId; } + void setOverrideRequestId(mtpRequestId id) noexcept { + _overrideRequestId = id; + } void setCanWait(crl::time ms) noexcept { _canWait = ms; } @@ -147,16 +150,16 @@ class Sender { _afterRequestId = requestId; } - ShiftedDcId takeDcId() const noexcept { + [[nodiscard]] ShiftedDcId takeDcId() const noexcept { return _dcId; } - crl::time takeCanWait() const noexcept { + [[nodiscard]] crl::time takeCanWait() const noexcept { return _canWait; } - DoneHandler takeOnDone() noexcept { + [[nodiscard]] DoneHandler takeOnDone() noexcept { return std::move(_done); } - FailHandler takeOnFail() { + [[nodiscard]] FailHandler takeOnFail() { return v::match(_fail, [&](auto &value) { return MakeFailHandler( _sender, @@ -164,11 +167,14 @@ class Sender { _failSkipPolicy); }); } - mtpRequestId takeAfter() const noexcept { + [[nodiscard]] mtpRequestId takeAfter() const noexcept { return _afterRequestId; } + [[nodiscard]] mtpRequestId takeOverrideRequestId() const noexcept { + return _overrideRequestId; + } - not_null<Sender*> sender() const noexcept { + [[nodiscard]] not_null<Sender*> sender() const noexcept { return _sender; } void registerRequest(mtpRequestId requestId) { @@ -187,6 +193,7 @@ class Sender { FailFullHandler> _fail; FailSkipPolicy _failSkipPolicy = FailSkipPolicy::Simple; mtpRequestId _afterRequestId = 0; + mtpRequestId _overrideRequestId = 0; }; @@ -207,9 +214,10 @@ public: : RequestBuilder(sender) , _request(std::move(request)) { } - SpecificRequestBuilder(SpecificRequestBuilder &&other) = default; public: + SpecificRequestBuilder(SpecificRequestBuilder &&other) = default; + [[nodiscard]] SpecificRequestBuilder &toDC(ShiftedDcId dcId) noexcept { setToDC(dcId); return *this; @@ -218,6 +226,10 @@ public: setCanWait(ms); return *this; } + [[nodiscard]] SpecificRequestBuilder &overrideId(mtpRequestId id) noexcept { + setOverrideRequestId(id); + return *this; + } using Result = typename Request::ResponseType; [[nodiscard]] SpecificRequestBuilder &done( @@ -295,7 +307,8 @@ public: takeOnFail(), takeDcId(), takeCanWait(), - takeAfter()); + takeAfter(), + takeOverrideRequestId()); registerRequest(id); return id; } @@ -347,6 +360,13 @@ public: } } + [[nodiscard]] mtpRequestId allocateRequestId() noexcept { + return details::GetNextRequestId(); + } + [[nodiscard]] bool pending(mtpRequestId requestId) noexcept { + return _requests.contains(requestId); + } + private: class RequestWrap { public: diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index dc9301a89..7914cd918 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -40,7 +40,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include <QtWidgets/QLineEdit> #include <QtWidgets/QTextEdit> #include <QtGui/QClipboard> + +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) #include <qpa/qwindowsysteminterface.h> +#endif // Qt < 6.6.0 #include <Cocoa/Cocoa.h> #include <CoreFoundation/CFURL.h> @@ -52,7 +55,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL - (id) init:(MainWindow::Private*)window; - (void) activeSpaceDidChange:(NSNotification *)aNotification; +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) - (void) darkModeChanged:(NSNotification *)aNotification; +#endif // Qt < 6.6.0 - (void) screenIsLocked:(NSNotification *)aNotification; - (void) screenIsUnlocked:(NSNotification *)aNotification; @@ -113,6 +118,7 @@ private: - (void) activeSpaceDidChange:(NSNotification *)aNotification { } +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) - (void) darkModeChanged:(NSNotification *)aNotification { Core::Sandbox::Instance().customEnterFromEventLoop([&] { #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) @@ -122,6 +128,7 @@ private: #endif // Qt < 6.5.0 }); } +#endif // Qt < 6.6.0 - (void) screenIsLocked:(NSNotification *)aNotification { Core::App().setScreenIsLocked(true); @@ -156,10 +163,12 @@ void ForceDisabled(QAction *action, bool disabled) { } } +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) QString strNotificationAboutThemeChange() { const uint32 letters[] = { 0x75E86256, 0xD03E11B1, 0x4D92201D, 0xA2144987, 0x99D5B34F, 0x037589C3, 0x38ED2A7C, 0xD2371ABC, 0xDC98BB02, 0x27964E1B, 0x01748AED, 0xE06679F8, 0x761C9580, 0x4F2595BF, 0x6B5FCBF4, 0xE4D9C24E, 0xBA2F6AB5, 0xE6E3FA71, 0xF2CFC255, 0x56A50C19, 0x43AE1239, 0x77CA4254, 0x7D189A89, 0xEA7663EE, 0x84CEB554, 0xA0ADF236, 0x886512D4, 0x7D3FBDAF, 0x85C4BE4F, 0x12C8255E, 0x9AD8BD41, 0xAC154683, 0xB117598B, 0xDFD9F947, 0x63F06C7B, 0x6340DCD6, 0x3AAE6B3E, 0x26CB125A }; return Platform::MakeFromLetters(letters); } +#endif // Qt < 6.6.0 QString strNotificationAboutScreenLocked() { const uint32 letters[] = { 0x34B47F28, 0x47E95179, 0x73D05C42, 0xB4E2A933, 0x924F22D1, 0x4265D8EA, 0x9E4D2CC2, 0x02E8157B, 0x35BF7525, 0x75901A41, 0xB0400FCC, 0xE801169D, 0x4E04B589, 0xC1CEF054, 0xAB2A7EB0, 0x5C67C4F6, 0xA4E2B954, 0xB35E12D2, 0xD598B22B, 0x4E3B8AAB, 0xBEA5E439, 0xFDA8AA3C, 0x1632DBA8, 0x88FE8965 }; @@ -181,7 +190,9 @@ MainWindow::Private::Private(not_null<MainWindow*> window) @autoreleasepool { [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:_observer selector:@selector(activeSpaceDidChange:) name:NSWorkspaceActiveSpaceDidChangeNotification object:nil]; +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) [[NSDistributedNotificationCenter defaultCenter] addObserver:_observer selector:@selector(darkModeChanged:) name:Q2NSString(strNotificationAboutThemeChange()) object:nil]; +#endif // Qt < 6.6.0 [[NSDistributedNotificationCenter defaultCenter] addObserver:_observer selector:@selector(screenIsLocked:) name:Q2NSString(strNotificationAboutScreenLocked()) object:nil]; [[NSDistributedNotificationCenter defaultCenter] addObserver:_observer selector:@selector(screenIsUnlocked:) name:Q2NSString(strNotificationAboutScreenUnlocked()) object:nil]; diff --git a/Telegram/SourceFiles/platform/mac/specific_mac_p.mm b/Telegram/SourceFiles/platform/mac/specific_mac_p.mm index 984643871..de1f1d1ec 100644 --- a/Telegram/SourceFiles/platform/mac/specific_mac_p.mm +++ b/Telegram/SourceFiles/platform/mac/specific_mac_p.mm @@ -30,7 +30,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #if __has_include(<QtCore/QOperatingSystemVersion>) #include <QtCore/QOperatingSystemVersion> #endif // __has_include(<QtCore/QOperatingSystemVersion>) +#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) #include <qpa/qwindowsysteminterface.h> +#endif // Qt < 6.6.0 #include <Cocoa/Cocoa.h> #include <CoreFoundation/CFURL.h> #include <IOKit/IOKitLib.h> @@ -201,11 +203,11 @@ ApplicationDelegate *_sharedDelegate = nil; "-receiveWakeNote: received, scheduling detach from audio device")); Media::Audio::ScheduleDetachFromDeviceSafe(); -#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) - QWindowSystemInterface::handleThemeChange(); -#else // Qt >= 6.5.0 +#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0) Core::App().settings().setSystemDarkMode(Platform::IsDarkMode()); -#endif // Qt < 6.5.0 +#elif QT_VERSION < QT_VERSION_CHECK(6, 6, 0) // Qt < 6.5.0 + QWindowSystemInterface::handleThemeChange(); +#endif // Qt < 6.6.0 }); } diff --git a/Telegram/SourceFiles/platform/win/integration_win.h b/Telegram/SourceFiles/platform/win/integration_win.h index b51184e1d..5e559b69a 100644 --- a/Telegram/SourceFiles/platform/win/integration_win.h +++ b/Telegram/SourceFiles/platform/win/integration_win.h @@ -7,11 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +#include "base/platform/win/base_windows_winrt.h" #include "platform/platform_integration.h" #include <QAbstractNativeEventFilter> -#include <winrt/base.h> #include <ShlObj.h> namespace Platform { diff --git a/Telegram/SourceFiles/platform/win/windows_app_user_model_id.h b/Telegram/SourceFiles/platform/win/windows_app_user_model_id.h index 92d6c2b7d..4f69019eb 100644 --- a/Telegram/SourceFiles/platform/win/windows_app_user_model_id.h +++ b/Telegram/SourceFiles/platform/win/windows_app_user_model_id.h @@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/platform/win/base_windows_h.h" +#include <wtypes.h> + namespace Platform { namespace AppUserModelId { diff --git a/Telegram/SourceFiles/platform/win/windows_dlls.h b/Telegram/SourceFiles/platform/win/windows_dlls.h index eef6e9bc7..d97eeab92 100644 --- a/Telegram/SourceFiles/platform/win/windows_dlls.h +++ b/Telegram/SourceFiles/platform/win/windows_dlls.h @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/platform/win/base_windows_h.h" +#include <shellapi.h> #include <shlobj.h> #include <dwmapi.h> #include <RestartManager.h> diff --git a/Telegram/SourceFiles/statistics/view/linear_chart_view.cpp b/Telegram/SourceFiles/statistics/view/linear_chart_view.cpp index e89be9177..23fb14d3c 100644 --- a/Telegram/SourceFiles/statistics/view/linear_chart_view.cpp +++ b/Telegram/SourceFiles/statistics/view/linear_chart_view.cpp @@ -163,7 +163,7 @@ void LinearChartView::paintSelectedXIndex( + c.rect.topLeft(); } - if (!linePainted) { + if (!linePainted && lineAlpha) { [[maybe_unused]] const auto o = ScopedPainterOpacity( p, p.opacity() * progress * kRulerLineAlpha); diff --git a/Telegram/SourceFiles/ui/boxes/boost_box.cpp b/Telegram/SourceFiles/ui/boxes/boost_box.cpp index 83bd4fa37..0be48632c 100644 --- a/Telegram/SourceFiles/ui/boxes/boost_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/boost_box.cpp @@ -98,11 +98,7 @@ namespace { auto hq = PainterHighQualityEnabler(p); const auto radius = std::min(badge->width(), badge->height()) / 2; p.setPen(Qt::NoPen); - auto brush = QLinearGradient( - QPointF(badge->width(), badge->height()), - QPointF()); - brush.setStops(Ui::Premium::ButtonGradientStops()); - p.setBrush(brush); + p.setBrush(st::premiumButtonBg2); p.drawRoundedRect(badge->rect(), radius, radius); }, badge->lifetime()); diff --git a/Telegram/ThirdParty/libtgvoip b/Telegram/ThirdParty/libtgvoip index c2e718049..e286ab661 160000 --- a/Telegram/ThirdParty/libtgvoip +++ b/Telegram/ThirdParty/libtgvoip @@ -1 +1 @@ -Subproject commit c2e718049cf11bbbe7b6d78b78b2d21f0e0affa0 +Subproject commit e286ab66141a2f986803177e4cbb7b14002664cb diff --git a/Telegram/build/version b/Telegram/build/version index 447ef2247..065ee5c80 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,7 +1,7 @@ -AppVersion 4011006 +AppVersion 4011007 AppVersionStrMajor 4.11 -AppVersionStrSmall 4.11.6 -AppVersionStr 4.11.6 +AppVersionStrSmall 4.11.7 +AppVersionStr 4.11.7 BetaChannel 0 AlphaVersion 0 -AppVersionOriginal 4.11.6 +AppVersionOriginal 4.11.7 diff --git a/Telegram/lib_base b/Telegram/lib_base index bb5e7fafd..fe4f0a72d 160000 --- a/Telegram/lib_base +++ b/Telegram/lib_base @@ -1 +1 @@ -Subproject commit bb5e7fafd7aca5808217baeeb9ee3af8c3be6b1b +Subproject commit fe4f0a72d2041a860c67a81a70f2e4b6f845d9fb diff --git a/Telegram/lib_webview b/Telegram/lib_webview index f5fe3afcf..aab27269f 160000 --- a/Telegram/lib_webview +++ b/Telegram/lib_webview @@ -1 +1 @@ -Subproject commit f5fe3afcf5bc5edf07a78ad18b9e8d33c3fbfdb2 +Subproject commit aab27269ff8aad5dfaf7372db10bff700fdb5fe9 diff --git a/changelog.txt b/changelog.txt index 245ef9c1e..c7e56597b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,11 @@ +4.11.7 (13.11.23) + +- Fix sending media files with quote replies. +- Fix quoted text highlighting in some cases. +- Fix loading statistics for some channels. +- Fix Ctrl+Shift+. shortcut on X11. +- Fix a crash in statistics. + 4.11.6 (09.11.23) - Support multiple boosts and reassignment. diff --git a/cmake b/cmake index 78098ede7..c373a0a01 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 78098ede77a09e41da6233d765d02b43a60e7138 +Subproject commit c373a0a0141bbe146a9507f02b8515183748eb51