diff --git a/Telegram/Resources/icons/chat/input_forward.png b/Telegram/Resources/icons/chat/input_forward.png
index c04e20ceb3..2d9c783354 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 c500804d00..26e435458b 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 9df3f2369c..488f8e1e10 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 0000000000..bd01d4ad19
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 0000000000..0eb12d2033
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 0000000000..851858fafd
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 f20b997732..0000000000
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 e44f5f79eb..0000000000
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 97688789f3..0000000000
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 0000000000..0f0ade5dcd
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 0000000000..c7bcb7d8eb
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 0000000000..f1bc500a1f
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 0000000000..9b67e535c2
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 0000000000..2a4aef116e
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 0000000000..e2f131d6aa
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 0c1422ba9a..3f6b892110 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 87d43e6034..b206163a2d 100644
--- a/Telegram/Resources/uwp/AppX/AppxManifest.xml
+++ b/Telegram/Resources/uwp/AppX/AppxManifest.xml
@@ -10,7 +10,7 @@
+ Version="4.11.7.0" />
Telegram Desktop
Telegram Messenger LLP
diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc
index 53ffeebbe0..0bbf19b2fc 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 22190fb9dd..f9e4d3cfdc 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 383d0973cf..1f5c093a6e 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 api)
-: _api(&api->instance()) {
+Statistics::Statistics(not_null channel)
+: StatisticsRequestSender(channel) {
}
-rpl::producer Statistics::request(
- not_null peer) {
+StatisticsRequestSender::StatisticsRequestSender(not_null 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
+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)
+ ).toDC(
+ dcId ? MTP::ShiftDcId(dcId, MTP::kStatsDcShift) : 0
+ ).overrideId(id));
+}
+
+rpl::producer 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 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 Statistics::request(
}
Statistics::GraphResult Statistics::requestZoom(
- not_null 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 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 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;
_requestId = 0;
@@ -402,10 +423,9 @@ void PublicForwards::request(
MessageStatistics::MessageStatistics(
not_null 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 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 done) {
const auto requestPrivateForwards = [=](
const Data::StatisticalGraph &messageGraph) {
- _api.request(MTPchannels_GetMessages(
- _channel->inputChannel,
+ api().request(MTPchannels_GetMessages(
+ channel()->inputChannel,
MTP_vector(
1,
MTP_inputMessageID(MTP_int(_fullId.msg))))
@@ -475,9 +494,9 @@ void MessageStatistics::request(Fn 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 done) {
}).fail([=](const MTP::Error &error) {
requestPrivateForwards({});
}).send();
-
}
Boosts::Boosts(not_null peer)
diff --git a/Telegram/SourceFiles/api/api_statistics.h b/Telegram/SourceFiles/api/api_statistics.h
index 460c9df9d4..dddf3654c2 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 api);
+class StatisticsRequestSender {
+protected:
+ explicit StatisticsRequestSender(not_null channel);
+ ~StatisticsRequestSender();
- [[nodiscard]] rpl::producer request(
- not_null peer);
+ template <
+ typename Request,
+ typename = std::enable_if_t>,
+ typename = typename Request::Unboxed>
+ [[nodiscard]] auto makeRequest(Request &&request);
+
+ [[nodiscard]] MTP::Sender &api() {
+ return _api;
+ }
+ [[nodiscard]] not_null channel() {
+ return _channel;
+ }
+
+private:
+ void checkRequests();
+
+ const not_null _channel;
+ MTP::Sender _api;
+ base::Timer _timer;
+ base::flat_map> _requests;
+
+};
+
+class Statistics final : public StatisticsRequestSender {
+public:
+ explicit Statistics(not_null channel);
+
+ [[nodiscard]] rpl::producer request();
using GraphResult = rpl::producer;
[[nodiscard]] GraphResult requestZoom(
- not_null peer,
const QString &token,
float64 x);
- [[nodiscard]] GraphResult requestMessage(
- not_null 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> _zoomDeque;
};
-class PublicForwards final {
+class PublicForwards final : public StatisticsRequestSender {
public:
- explicit PublicForwards(not_null channel, FullMsgId fullId);
+ PublicForwards(not_null channel, FullMsgId fullId);
void request(
const Data::PublicForwardsSlice::OffsetToken &token,
Fn done);
private:
- const not_null _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 channel,
@@ -74,13 +93,11 @@ public:
private:
PublicForwards _publicForwards;
- const not_null _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 c0d7a5bc27..2270743c25 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 session)
, _fileLoader(std::make_unique(kFileLoaderQueueStopTimeout))
, _topPromotionTimer([=] { refreshTopPromotion(); })
, _updateNotifyTimer([=] { sendNotifySettingsUpdates(); })
+, _statsSessionKillTimer([=] { checkStatsSessions(); })
, _authorizations(std::make_unique(this))
, _attachedStickers(std::make_unique(this))
, _blockedPeers(std::make_unique(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 f61eb0957e..ecb0f968aa 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 channel);
void migrateFail(not_null peer, const QString &error);
+ void checkStatsSessions();
+
const not_null _session;
base::flat_map _modifyRequests;
@@ -683,6 +688,9 @@ private:
QString requestedText;
} _bio;
+ base::flat_map> _statsRequests;
+ base::Timer _statsSessionKillTimer;
+
const std::unique_ptr _authorizations;
const std::unique_ptr _attachedStickers;
const std::unique_ptr _blockedPeers;
diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style
index d100850ee2..3739ef7e39 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 b44f257cab..b325424287 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 3b26c1eb96..5daff7e176 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 8590e1fa61..85aa659f82 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 channel) {
+ const auto it = _channelStatsDcIds.find(channel);
+ return (it == end(_channelStatsDcIds)) ? MTP::DcId(0) : it->second;
+}
+
+void Session::applyStatsDcId(
+ not_null 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 c470e3a8b3..df6dc5019a 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>;
+ void applyStatsDcId(not_null, MTP::DcId);
+ [[nodiscard]] MTP::DcId statsDcId(not_null);
+
void clearLocalStorage();
private:
@@ -1014,6 +1017,8 @@ private:
base::flat_map, TimeId> _watchingForOffline;
base::Timer _watchForOfflineTimer;
+ base::flat_map, MTP::DcId> _channelStatsDcIds;
+
rpl::event_stream _webViewResultSent;
rpl::event_stream> _peerDecorationsUpdated;
diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp
index e71c3cefd3..5299b648c9 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 cdd0811ddd..f8f5b9ba7d 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()) {
+ 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 3c1ad01e61..7049d94d13 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 87b7edde9b..10a54c8581 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 540d4ca5ff..8b9ac3393a 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 _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(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 850ecfe6b6..6812cb2733 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 9b5334a5c9..1270494163 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 fad3d0e56d..2abe667eae 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,
+ 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,
+ not_null 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 5322d5c092..4b30a842d6 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,
+ PeerData *peer);
+ [[nodiscard]] static TextWithEntities ComposePreviewName(
+ not_null history,
+ not_null 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 19704c7797..694c67fb5f 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(&_peer->session().api()),
+ lifetime().make_state(_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(&_peer->session().api()),
+ lifetime().make_state(_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 0437644be2..75287cebae 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 2a3bc3d4e3..7dc5be49bf 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
diff --git a/Telegram/SourceFiles/mtproto/sender.h b/Telegram/SourceFiles/mtproto/sender.h
index 632f817f4c..5330a0559c 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() const noexcept {
+ [[nodiscard]] not_null 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 dc9301a89f..7914cd9184 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
#include
#include
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
#include
+#endif // Qt < 6.6.0
#include
#include
@@ -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 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 9846438711..de1f1d1ecd 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()
#include
#endif // __has_include()
+#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
#include
+#endif // Qt < 6.6.0
#include
#include
#include
@@ -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 b51184e1d1..5e559b69a6 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
-#include
#include
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 92d6c2b7d1..4f69019ebd 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
+
namespace Platform {
namespace AppUserModelId {
diff --git a/Telegram/SourceFiles/platform/win/windows_dlls.h b/Telegram/SourceFiles/platform/win/windows_dlls.h
index eef6e9bc70..d97eeab92d 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
#include
#include
#include
diff --git a/Telegram/SourceFiles/statistics/view/linear_chart_view.cpp b/Telegram/SourceFiles/statistics/view/linear_chart_view.cpp
index e89be9177c..23fb14d3c1 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 83bd4fa378..0be48632ca 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 c2e718049c..e286ab6614 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 447ef2247e..065ee5c809 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 bb5e7fafd7..fe4f0a72d2 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 f5fe3afcf5..aab27269ff 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 245ef9c1ef..c7e56597b0 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 78098ede77..c373a0a014 160000
--- a/cmake
+++ b/cmake
@@ -1 +1 @@
-Subproject commit 78098ede77a09e41da6233d765d02b43a60e7138
+Subproject commit c373a0a0141bbe146a9507f02b8515183748eb51