Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ede4c0f781 | ||
|
|
75337ad1c2 | ||
|
|
e05b2f3b38 | ||
|
|
0f15adb208 | ||
|
|
a7e552ccab | ||
|
|
797433ebe9 | ||
|
|
633532b88d | ||
|
|
a0dcade9d8 | ||
|
|
2a0babe5ab | ||
|
|
dd92f7fb9d | ||
|
|
7ad08b3ef8 | ||
|
|
73917e8a4b | ||
|
|
dc7aef3f86 | ||
|
|
d89597bf64 | ||
|
|
c2b2d0a92a | ||
|
|
b341dddbb9 | ||
|
|
999e4264c5 | ||
|
|
aee11469c4 | ||
|
|
651cfe5b7e | ||
|
|
a34b2a5472 | ||
|
|
5e7e7eaa83 | ||
|
|
a8f05a01ed | ||
|
|
fedd21b0a6 | ||
|
|
7ff7473db6 | ||
|
|
d89aab08bf | ||
|
|
b2fb5424ed | ||
|
|
e7e34d50ba | ||
|
|
19320cc5d8 | ||
|
|
107a87c7ce | ||
|
|
2cb1d2c0bc | ||
|
|
48ab88a9ca | ||
|
|
33b7ac209e | ||
|
|
4a0ffdc9f5 | ||
|
|
1ec2c16d27 |
6
.github/workflows/linux.yml
vendored
@@ -107,7 +107,7 @@ jobs:
|
||||
|
||||
- name: Check.
|
||||
run: |
|
||||
filePath="$REPO_NAME/out/Debug/bin/Telegram"
|
||||
filePath="$REPO_NAME/out/Debug/Telegram"
|
||||
if test -f "$filePath"; then
|
||||
echo "Build successfully done! :)"
|
||||
|
||||
@@ -121,7 +121,7 @@ jobs:
|
||||
- name: Move artifact.
|
||||
if: env.UPLOAD_ARTIFACT == 'true'
|
||||
run: |
|
||||
cd $REPO_NAME/out/Debug/bin
|
||||
cd $REPO_NAME/out/Debug
|
||||
mkdir artifact
|
||||
mv Telegram artifact/
|
||||
- uses: actions/upload-artifact@master
|
||||
@@ -129,4 +129,4 @@ jobs:
|
||||
name: Upload artifact.
|
||||
with:
|
||||
name: ${{ env.ARTIFACT_NAME }}
|
||||
path: ${{ env.REPO_NAME }}/out/Debug/bin/artifact/
|
||||
path: ${{ env.REPO_NAME }}/out/Debug/artifact/
|
||||
|
||||
6
.gitmodules
vendored
@@ -94,3 +94,9 @@
|
||||
[submodule "Telegram/ThirdParty/jemalloc"]
|
||||
path = Telegram/ThirdParty/jemalloc
|
||||
url = https://github.com/jemalloc/jemalloc
|
||||
[submodule "Telegram/ThirdParty/kwayland"]
|
||||
path = Telegram/ThirdParty/kwayland
|
||||
url = https://github.com/KDE/kwayland.git
|
||||
[submodule "Telegram/ThirdParty/dispatch"]
|
||||
path = Telegram/ThirdParty/dispatch
|
||||
url = https://github.com/apple/swift-corelibs-libdispatch
|
||||
|
||||
@@ -1407,7 +1407,7 @@ PRIVATE
|
||||
G_LOG_DOMAIN="Telegram"
|
||||
)
|
||||
|
||||
if ("${CMAKE_GENERATOR}" STREQUAL "Xcode"
|
||||
if (APPLE
|
||||
OR "${CMAKE_GENERATOR}" STREQUAL "Ninja Multi-Config"
|
||||
OR NOT CMAKE_EXECUTABLE_SUFFIX STREQUAL ""
|
||||
OR NOT "${output_name}" STREQUAL "Telegram")
|
||||
|
||||
|
Before Width: | Height: | Size: 107 B |
|
Before Width: | Height: | Size: 126 B |
|
Before Width: | Height: | Size: 174 B |
BIN
Telegram/Resources/icons/contacts_alphabet.png
Normal file
|
After Width: | Height: | Size: 448 B |
BIN
Telegram/Resources/icons/contacts_alphabet@2x.png
Normal file
|
After Width: | Height: | Size: 784 B |
BIN
Telegram/Resources/icons/contacts_alphabet@3x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/contacts_online.png
Normal file
|
After Width: | Height: | Size: 385 B |
BIN
Telegram/Resources/icons/contacts_online@2x.png
Normal file
|
After Width: | Height: | Size: 649 B |
BIN
Telegram/Resources/icons/contacts_online@3x.png
Normal file
|
After Width: | Height: | Size: 1014 B |
@@ -83,9 +83,6 @@
|
||||
<file alias="settings/devices/device_web_firefox.lottie">../../icons/settings/devices/device_web_firefox.lottie</file>
|
||||
<file alias="settings/devices/device_web_safari.lottie">../../icons/settings/devices/device_web_safari.lottie</file>
|
||||
</qresource>
|
||||
<qresource prefix="/qt-project.org">
|
||||
<file>../qmime/freedesktop.org.xml</file>
|
||||
</qresource>
|
||||
<qresource prefix="/misc">
|
||||
<file alias="default_shortcuts-custom.json">../../default_shortcuts-custom.json</file>
|
||||
<file alias="telegramdesktop.desktop">../../../../lib/xdg/telegramdesktop.desktop</file>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<Identity Name="TelegramMessengerLLP.TelegramDesktop"
|
||||
ProcessorArchitecture="ARCHITECTURE"
|
||||
Publisher="CN=536BC709-8EE1-4478-AF22-F0F0F26FF64A"
|
||||
Version="3.3.0.0" />
|
||||
Version="3.3.1.0" />
|
||||
<Properties>
|
||||
<DisplayName>Telegram Desktop</DisplayName>
|
||||
<PublisherDisplayName>Telegram Messenger LLP</PublisherDisplayName>
|
||||
|
||||
@@ -44,8 +44,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,3,0,0
|
||||
PRODUCTVERSION 3,3,0,0
|
||||
FILEVERSION 3,3,1,0
|
||||
PRODUCTVERSION 3,3,1,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -62,10 +62,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||
VALUE "FileDescription", "Telegram Desktop"
|
||||
VALUE "FileVersion", "3.3.0.0"
|
||||
VALUE "FileVersion", "3.3.1.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "3.3.0.0"
|
||||
VALUE "ProductVersion", "3.3.1.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -35,8 +35,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,3,0,0
|
||||
PRODUCTVERSION 3,3,0,0
|
||||
FILEVERSION 3,3,1,0
|
||||
PRODUCTVERSION 3,3,1,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -53,10 +53,10 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Telegram FZ-LLC"
|
||||
VALUE "FileDescription", "Telegram Desktop Updater"
|
||||
VALUE "FileVersion", "3.3.0.0"
|
||||
VALUE "FileVersion", "3.3.1.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2014-2021"
|
||||
VALUE "ProductName", "Telegram Desktop"
|
||||
VALUE "ProductVersion", "3.3.0.0"
|
||||
VALUE "ProductVersion", "3.3.1.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -118,7 +118,7 @@ void PeerPhoto::upload(not_null<PeerData*> peer, QImage &&image) {
|
||||
std::move(image));
|
||||
|
||||
const auto fakeId = FullMsgId(
|
||||
peerToChannel(peer->id),
|
||||
peer->id,
|
||||
_session->data().nextLocalMessageId());
|
||||
const auto already = ranges::find(
|
||||
_uploads,
|
||||
|
||||
@@ -74,7 +74,7 @@ void SendExistingMedia(
|
||||
api->sendAction(message.action);
|
||||
|
||||
const auto newId = FullMsgId(
|
||||
peerToChannel(peer->id),
|
||||
peer->id,
|
||||
session->data().nextLocalMessageId());
|
||||
const auto randomId = base::RandomValue<uint64>();
|
||||
|
||||
@@ -255,7 +255,7 @@ bool SendDice(MessageToSend &message) {
|
||||
api->sendAction(message.action);
|
||||
|
||||
const auto newId = FullMsgId(
|
||||
peerToChannel(peer->id),
|
||||
peer->id,
|
||||
session->data().nextLocalMessageId());
|
||||
const auto randomId = base::RandomValue<uint64>();
|
||||
|
||||
@@ -346,10 +346,8 @@ void SendConfirmedFile(
|
||||
const std::shared_ptr<FileLoadResult> &file) {
|
||||
const auto isEditing = (file->type != SendMediaType::Audio)
|
||||
&& (file->to.replaceMediaOf != 0);
|
||||
const auto channelId = peerToChannel(file->to.peer);
|
||||
|
||||
const auto newId = FullMsgId(
|
||||
channelId,
|
||||
file->to.peer,
|
||||
isEditing
|
||||
? file->to.replaceMediaOf
|
||||
: session->data().nextLocalMessageId());
|
||||
|
||||
@@ -87,7 +87,7 @@ std::optional<HistoryItem*> SingleMessageSearch::performLookupByChannel(
|
||||
Expects(!_requestKey.empty());
|
||||
|
||||
const auto postId = _requestKey.postId;
|
||||
if (const auto item = _session->data().message(channel, postId)) {
|
||||
if (const auto item = _session->data().message(channel->id, postId)) {
|
||||
_cache.emplace(_requestKey, item->fullId());
|
||||
return item;
|
||||
} else if (!ready) {
|
||||
@@ -112,7 +112,7 @@ std::optional<HistoryItem*> SingleMessageSearch::performLookupByChannel(
|
||||
&& received.messageIds.front() == postId) {
|
||||
_cache.emplace(
|
||||
_requestKey,
|
||||
FullMsgId(peerToChannel(channel->id), postId));
|
||||
FullMsgId(channel->id, postId));
|
||||
ready();
|
||||
} else {
|
||||
fail();
|
||||
|
||||
@@ -730,7 +730,7 @@ void Updates::addActiveChat(rpl::producer<PeerData*> chat) {
|
||||
}
|
||||
|
||||
void Updates::requestChannelRangeDifference(not_null<History*> history) {
|
||||
Expects(history->isChannel());
|
||||
Expects(history->peer->isChannel());
|
||||
|
||||
const auto channel = history->peer->asChannel();
|
||||
if (const auto requestId = _rangeDifferenceRequests.take(channel)) {
|
||||
@@ -1181,7 +1181,7 @@ void Updates::applyUpdateNoPtsCheck(const MTPUpdate &update) {
|
||||
const auto &d = update.c_updateReadMessagesContents();
|
||||
auto possiblyReadMentions = base::flat_set<MsgId>();
|
||||
for (const auto &msgId : d.vmessages().v) {
|
||||
if (const auto item = _session->data().message(NoChannel, msgId.v)) {
|
||||
if (const auto item = _session->data().nonChannelMessage(msgId.v)) {
|
||||
if (item->isUnreadMedia() || item->isUnreadMention()) {
|
||||
item->markMediaRead();
|
||||
_session->data().requestItemRepaint(item);
|
||||
@@ -1249,7 +1249,7 @@ void Updates::applyUpdateNoPtsCheck(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updateDeleteMessages: {
|
||||
auto &d = update.c_updateDeleteMessages();
|
||||
_session->data().processMessagesDeleted(NoChannel, d.vmessages().v);
|
||||
_session->data().processNonChannelMessagesDeleted(d.vmessages().v);
|
||||
} break;
|
||||
|
||||
case mtpc_updateNewChannelMessage: {
|
||||
@@ -1278,9 +1278,9 @@ void Updates::applyUpdateNoPtsCheck(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updatePinnedChannelMessages: {
|
||||
const auto &d = update.c_updatePinnedChannelMessages();
|
||||
const auto channelId = d.vchannel_id().v;
|
||||
const auto peerId = peerFromChannel(d.vchannel_id());
|
||||
for (const auto &msgId : d.vmessages().v) {
|
||||
const auto item = session().data().message(channelId, msgId.v);
|
||||
const auto item = session().data().message(peerId, msgId.v);
|
||||
if (item) {
|
||||
item->setIsPinned(d.is_pinned());
|
||||
}
|
||||
@@ -1299,13 +1299,16 @@ void Updates::applyUpdateNoPtsCheck(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updateDeleteChannelMessages: {
|
||||
auto &d = update.c_updateDeleteChannelMessages();
|
||||
_session->data().processMessagesDeleted(d.vchannel_id().v, d.vmessages().v);
|
||||
_session->data().processMessagesDeleted(
|
||||
peerFromChannel(d.vchannel_id().v),
|
||||
d.vmessages().v);
|
||||
} break;
|
||||
|
||||
case mtpc_updatePinnedMessages: {
|
||||
const auto &d = update.c_updatePinnedMessages();
|
||||
const auto peerId = peerFromMTP(d.vpeer());
|
||||
for (const auto &msgId : d.vmessages().v) {
|
||||
const auto item = session().data().message(0, msgId.v);
|
||||
const auto item = session().data().message(peerId, msgId.v);
|
||||
if (item) {
|
||||
item->setIsPinned(d.is_pinned());
|
||||
}
|
||||
@@ -1424,7 +1427,7 @@ void Updates::applyUpdates(
|
||||
const auto sent = owner.messageSentData(randomId);
|
||||
const auto lookupMessage = [&] {
|
||||
return sent.peerId
|
||||
? owner.message(peerToChannel(sent.peerId), d.vid().v)
|
||||
? owner.message(sent.peerId, d.vid().v)
|
||||
: nullptr;
|
||||
};
|
||||
if (const auto id = owner.messageIdByRandomId(randomId)) {
|
||||
@@ -1439,9 +1442,9 @@ void Updates::applyUpdates(
|
||||
const auto list = d.ventities();
|
||||
if (list && !MentionUsersLoaded(&session(), *list)) {
|
||||
session().api().requestMessageData(
|
||||
item->history()->peer->asChannel(),
|
||||
item->history()->peer,
|
||||
item->id,
|
||||
ApiWrap::RequestMessageDataCallback());
|
||||
nullptr);
|
||||
}
|
||||
item->applySentMessage(sent.text, d, wasAlready);
|
||||
}
|
||||
@@ -1527,9 +1530,8 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
if (local->isScheduled()) {
|
||||
session().data().scheduledMessages().apply(d, local);
|
||||
} else {
|
||||
const auto channel = id.channel;
|
||||
const auto existing = session().data().message(
|
||||
channel,
|
||||
id.peer,
|
||||
newId);
|
||||
if (existing && !local->mainView()) {
|
||||
const auto history = local->history();
|
||||
@@ -1566,7 +1568,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
}
|
||||
auto possiblyReadMentions = base::flat_set<MsgId>();
|
||||
for (const auto &msgId : d.vmessages().v) {
|
||||
if (auto item = session().data().message(channel, msgId.v)) {
|
||||
if (auto item = session().data().message(channel->id, msgId.v)) {
|
||||
if (item->isUnreadMedia() || item->isUnreadMention()) {
|
||||
item->markMediaRead();
|
||||
session().data().requestItemRepaint(item);
|
||||
@@ -2146,24 +2148,26 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updateChannelMessageViews: {
|
||||
const auto &d = update.c_updateChannelMessageViews();
|
||||
if (const auto item = session().data().message(d.vchannel_id().v, d.vid().v)) {
|
||||
const auto peerId = peerFromChannel(d.vchannel_id());
|
||||
if (const auto item = session().data().message(peerId, d.vid().v)) {
|
||||
item->setViewsCount(d.vviews().v);
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateChannelMessageForwards: {
|
||||
const auto &d = update.c_updateChannelMessageForwards();
|
||||
if (const auto item = session().data().message(d.vchannel_id().v, d.vid().v)) {
|
||||
const auto peerId = peerFromChannel(d.vchannel_id());
|
||||
if (const auto item = session().data().message(peerId, d.vid().v)) {
|
||||
item->setForwardsCount(d.vforwards().v);
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateReadChannelDiscussionInbox: {
|
||||
const auto &d = update.c_updateReadChannelDiscussionInbox();
|
||||
const auto channelId = d.vchannel_id().v;
|
||||
const auto peerId = peerFromChannel(d.vchannel_id());
|
||||
const auto msgId = d.vtop_msg_id().v;
|
||||
const auto readTillId = d.vread_max_id().v;
|
||||
const auto item = session().data().message(channelId, msgId);
|
||||
const auto item = session().data().message(peerId, msgId);
|
||||
const auto unreadCount = item
|
||||
? session().data().countUnreadRepliesLocally(item, readTillId)
|
||||
: std::nullopt;
|
||||
@@ -2175,7 +2179,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
}
|
||||
if (const auto broadcastId = d.vbroadcast_id()) {
|
||||
if (const auto post = session().data().message(
|
||||
broadcastId->v,
|
||||
peerFromChannel(*broadcastId),
|
||||
d.vbroadcast_post()->v)) {
|
||||
post->setRepliesInboxReadTill(readTillId, unreadCount);
|
||||
}
|
||||
@@ -2184,10 +2188,10 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updateReadChannelDiscussionOutbox: {
|
||||
const auto &d = update.c_updateReadChannelDiscussionOutbox();
|
||||
const auto channelId = d.vchannel_id().v;
|
||||
const auto peerId = peerFromChannel(d.vchannel_id());
|
||||
const auto msgId = d.vtop_msg_id().v;
|
||||
const auto readTillId = d.vread_max_id().v;
|
||||
const auto item = session().data().message(channelId, msgId);
|
||||
const auto item = session().data().message(peerId, msgId);
|
||||
if (item) {
|
||||
item->setRepliesOutboxReadTill(readTillId);
|
||||
if (const auto post = item->lookupDiscussionPostOriginal()) {
|
||||
|
||||
@@ -95,9 +95,8 @@ void ViewsManager::done(
|
||||
if (id != requestId) {
|
||||
continue;
|
||||
}
|
||||
const auto channel = peerToChannel(peer->id);
|
||||
for (auto j = 0, l = int(ids.size()); j < l; ++j) {
|
||||
if (const auto item = owner.message(channel, ids[j].v)) {
|
||||
if (const auto item = owner.message(peer->id, ids[j].v)) {
|
||||
v[j].match([&](const MTPDmessageViews &data) {
|
||||
if (const auto views = data.vviews()) {
|
||||
item->setViewsCount(views->v);
|
||||
|
||||
@@ -510,14 +510,14 @@ void ApiWrap::sendMessageFail(
|
||||
}
|
||||
|
||||
void ApiWrap::requestMessageData(
|
||||
ChannelData *channel,
|
||||
PeerData *peer,
|
||||
MsgId msgId,
|
||||
RequestMessageDataCallback callback) {
|
||||
auto &requests = channel
|
||||
? _channelMessageDataRequests[channel][msgId]
|
||||
Fn<void()> done) {
|
||||
auto &requests = (peer && peer->isChannel())
|
||||
? _channelMessageDataRequests[peer->asChannel()][msgId]
|
||||
: _messageDataRequests[msgId];
|
||||
if (callback) {
|
||||
requests.callbacks.push_back(callback);
|
||||
if (done) {
|
||||
requests.callbacks.push_back(std::move(done));
|
||||
}
|
||||
if (!requests.requestId) {
|
||||
_messageDataResolveDelayed.call();
|
||||
@@ -539,19 +539,19 @@ QVector<MTPInputMessage> ApiWrap::collectMessageIds(
|
||||
|
||||
auto ApiWrap::messageDataRequests(ChannelData *channel, bool onlyExisting)
|
||||
-> MessageDataRequests* {
|
||||
if (channel) {
|
||||
auto i = _channelMessageDataRequests.find(channel);
|
||||
if (i == end(_channelMessageDataRequests)) {
|
||||
if (onlyExisting) {
|
||||
return nullptr;
|
||||
}
|
||||
i = _channelMessageDataRequests.emplace(
|
||||
channel,
|
||||
MessageDataRequests()).first;
|
||||
}
|
||||
return &i->second;
|
||||
if (!channel) {
|
||||
return &_messageDataRequests;
|
||||
}
|
||||
return &_messageDataRequests;
|
||||
const auto i = _channelMessageDataRequests.find(channel);
|
||||
if (i != end(_channelMessageDataRequests)) {
|
||||
return &i->second;
|
||||
} else if (onlyExisting) {
|
||||
return nullptr;
|
||||
}
|
||||
return &_channelMessageDataRequests.emplace(
|
||||
channel,
|
||||
MessageDataRequests()
|
||||
).first->second;
|
||||
}
|
||||
|
||||
void ApiWrap::resolveMessageDatas() {
|
||||
@@ -614,20 +614,31 @@ void ApiWrap::finalizeMessageDataRequest(
|
||||
ChannelData *channel,
|
||||
mtpRequestId requestId) {
|
||||
auto requests = messageDataRequests(channel, true);
|
||||
if (requests) {
|
||||
for (auto i = requests->begin(); i != requests->cend();) {
|
||||
if (i->second.requestId == requestId) {
|
||||
for (const auto &callback : i->second.callbacks) {
|
||||
callback(channel, i->first);
|
||||
}
|
||||
i = requests->erase(i);
|
||||
if (!requests) {
|
||||
return;
|
||||
}
|
||||
auto callbacks = std::vector<Fn<void()>>();
|
||||
for (auto i = requests->begin(); i != requests->cend();) {
|
||||
if (i->second.requestId == requestId) {
|
||||
auto &list = i->second.callbacks;
|
||||
if (callbacks.empty()) {
|
||||
callbacks = std::move(list);
|
||||
} else {
|
||||
++i;
|
||||
callbacks.insert(
|
||||
end(callbacks),
|
||||
std::make_move_iterator(begin(list)),
|
||||
std::make_move_iterator(end(list)));
|
||||
}
|
||||
i = requests->erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
if (channel && requests->empty()) {
|
||||
_channelMessageDataRequests.remove(channel);
|
||||
}
|
||||
}
|
||||
if (channel && requests->empty()) {
|
||||
_channelMessageDataRequests.remove(channel);
|
||||
}
|
||||
for (const auto &callback : callbacks) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,7 +657,7 @@ QString ApiWrap::exportDirectMessageLink(
|
||||
if (inRepliesContext) {
|
||||
if (const auto rootId = item->replyToTop()) {
|
||||
const auto root = item->history()->owner().message(
|
||||
peerToChannel(channel->id),
|
||||
channel->id,
|
||||
rootId);
|
||||
const auto sender = root
|
||||
? root->discussionPostOriginalSender()
|
||||
@@ -1388,9 +1399,8 @@ void ApiWrap::deleteAllFromParticipant(
|
||||
const auto ids = history
|
||||
? history->collectMessagesFromParticipantToDelete(from)
|
||||
: std::vector<MsgId>();
|
||||
const auto channelId = peerToChannel(channel->id);
|
||||
for (const auto &msgId : ids) {
|
||||
if (const auto item = _session->data().message(channelId, msgId)) {
|
||||
if (const auto item = _session->data().message(channel->id, msgId)) {
|
||||
item->destroy();
|
||||
}
|
||||
}
|
||||
@@ -2225,11 +2235,7 @@ void ApiWrap::resolveWebPages() {
|
||||
if (i.key()->pendingTill <= t) {
|
||||
const auto item = _session->data().findWebPageItem(i.key());
|
||||
if (item) {
|
||||
if (item->channelId() == NoChannel) {
|
||||
ids.push_back(MTP_inputMessageID(MTP_int(item->id)));
|
||||
i.value() = -1;
|
||||
} else {
|
||||
auto channel = item->history()->peer->asChannel();
|
||||
if (const auto channel = item->history()->peer->asChannel()) {
|
||||
auto channelMap = idsByChannel.find(channel);
|
||||
if (channelMap == idsByChannel.cend()) {
|
||||
channelMap = idsByChannel.emplace(
|
||||
@@ -2244,6 +2250,9 @@ void ApiWrap::resolveWebPages() {
|
||||
MTP_inputMessageID(MTP_int(item->id)));
|
||||
}
|
||||
i.value() = -channelMap->second.first - 2;
|
||||
} else {
|
||||
ids.push_back(MTP_inputMessageID(MTP_int(item->id)));
|
||||
i.value() = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -2927,14 +2936,13 @@ void ApiWrap::preloadEnoughUnreadMentions(not_null<History*> history) {
|
||||
void ApiWrap::checkForUnreadMentions(
|
||||
const base::flat_set<MsgId> &possiblyReadMentions,
|
||||
ChannelData *channel) {
|
||||
for (auto msgId : possiblyReadMentions) {
|
||||
requestMessageData(channel, msgId, [=](
|
||||
ChannelData *channel,
|
||||
MsgId msgId) {
|
||||
if (const auto item = _session->data().message(channel, msgId)) {
|
||||
if (item->mentionsMe()) {
|
||||
item->markMediaRead();
|
||||
}
|
||||
for (const auto msgId : possiblyReadMentions) {
|
||||
requestMessageData(channel, msgId, [=] {
|
||||
const auto item = channel
|
||||
? _session->data().message(channel->id, msgId)
|
||||
: _session->data().nonChannelMessage(msgId);
|
||||
if (item && item->mentionsMe()) {
|
||||
item->markMediaRead();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -3206,7 +3214,7 @@ void ApiWrap::forwardMessages(
|
||||
const auto randomId = base::RandomValue<uint64>();
|
||||
if (genClientSideMessage) {
|
||||
const auto newId = FullMsgId(
|
||||
peerToChannel(peer->id),
|
||||
peer->id,
|
||||
_session->data().nextLocalMessageId());
|
||||
const auto self = _session->user();
|
||||
const auto messageFromId = sendAs
|
||||
@@ -3279,7 +3287,7 @@ void ApiWrap::sendSharedContact(
|
||||
const auto peer = history->peer;
|
||||
|
||||
const auto newId = FullMsgId(
|
||||
history->channelId(),
|
||||
peer->id,
|
||||
_session->data().nextLocalMessageId());
|
||||
const auto anonymousPost = peer->amAnonymous();
|
||||
|
||||
@@ -3505,7 +3513,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
|
||||
while (TextUtilities::CutPart(sending, left, MaxMessageSize)) {
|
||||
auto newId = FullMsgId(
|
||||
peerToChannel(peer->id),
|
||||
peer->id,
|
||||
_session->data().nextLocalMessageId());
|
||||
auto randomId = base::RandomValue<uint64>();
|
||||
|
||||
@@ -3663,7 +3671,7 @@ void ApiWrap::sendInlineResult(
|
||||
const auto history = action.history;
|
||||
const auto peer = history->peer;
|
||||
const auto newId = FullMsgId(
|
||||
peerToChannel(peer->id),
|
||||
peer->id,
|
||||
_session->data().nextLocalMessageId());
|
||||
const auto randomId = base::RandomValue<uint64>();
|
||||
|
||||
|
||||
@@ -147,11 +147,7 @@ public:
|
||||
bool archived,
|
||||
Fn<void()> callback);
|
||||
|
||||
using RequestMessageDataCallback = Fn<void(ChannelData*, MsgId)>;
|
||||
void requestMessageData(
|
||||
ChannelData *channel,
|
||||
MsgId msgId,
|
||||
RequestMessageDataCallback callback);
|
||||
void requestMessageData(PeerData *peer, MsgId msgId, Fn<void()> done);
|
||||
QString exportDirectMessageLink(
|
||||
not_null<HistoryItem*> item,
|
||||
bool inRepliesContext);
|
||||
@@ -365,7 +361,7 @@ public:
|
||||
|
||||
private:
|
||||
struct MessageDataRequest {
|
||||
using Callbacks = std::vector<RequestMessageDataCallback>;
|
||||
using Callbacks = std::vector<Fn<void()>>;
|
||||
|
||||
mtpRequestId requestId = 0;
|
||||
Callbacks callbacks;
|
||||
@@ -520,7 +516,7 @@ private:
|
||||
|
||||
MessageDataRequests _messageDataRequests;
|
||||
base::flat_map<
|
||||
ChannelData*,
|
||||
not_null<ChannelData*>,
|
||||
MessageDataRequests> _channelMessageDataRequests;
|
||||
SingleQueuedInvokation _messageDataResolveDelayed;
|
||||
|
||||
|
||||
@@ -80,9 +80,15 @@ void AboutBox::prepare() {
|
||||
void AboutBox::resizeEvent(QResizeEvent *e) {
|
||||
BoxContent::resizeEvent(e);
|
||||
|
||||
const auto available = width()
|
||||
- st::boxPadding.left()
|
||||
- st::boxPadding.right();
|
||||
_version->moveToLeft(st::boxPadding.left(), st::aboutVersionTop);
|
||||
_text1->resizeToWidth(available);
|
||||
_text1->moveToLeft(st::boxPadding.left(), st::aboutTextTop);
|
||||
_text2->resizeToWidth(available);
|
||||
_text2->moveToLeft(st::boxPadding.left(), _text1->y() + _text1->height() + st::aboutSkip);
|
||||
_text3->resizeToWidth(available);
|
||||
_text3->moveToLeft(st::boxPadding.left(), _text2->y() + _text2->height() + st::aboutSkip);
|
||||
}
|
||||
|
||||
|
||||
@@ -418,32 +418,34 @@ void AddContactBox::save() {
|
||||
MTP_string(lastName)))
|
||||
)).done(crl::guard(this, [=](
|
||||
const MTPcontacts_ImportedContacts &result) {
|
||||
result.match([&](const MTPDcontacts_importedContacts &data) {
|
||||
_session->data().processUsers(data.vusers());
|
||||
|
||||
const auto extractUser = [&](const MTPImportedContact &data) {
|
||||
return data.match([&](const MTPDimportedContact &data) {
|
||||
return (data.vclient_id().v == _contactId)
|
||||
? _session->data().userLoaded(data.vuser_id())
|
||||
: nullptr;
|
||||
});
|
||||
};
|
||||
const auto &list = data.vimported().v;
|
||||
const auto user = list.isEmpty()
|
||||
? nullptr
|
||||
: extractUser(list.front());
|
||||
if (user) {
|
||||
if (user->isContact() || user->session().supportMode()) {
|
||||
Ui::showPeerHistory(user, ShowAtTheEndMsgId);
|
||||
}
|
||||
Ui::hideLayer();
|
||||
} else if (isBoxShown()) {
|
||||
hideChildren();
|
||||
_retrying = true;
|
||||
updateButtons();
|
||||
update();
|
||||
}
|
||||
const auto &data = result.match([](
|
||||
const auto &data) -> const MTPDcontacts_importedContacts& {
|
||||
return data;
|
||||
});
|
||||
_session->data().processUsers(data.vusers());
|
||||
|
||||
const auto extractUser = [&](const MTPImportedContact &data) {
|
||||
return data.match([&](const MTPDimportedContact &data) {
|
||||
return (data.vclient_id().v == _contactId)
|
||||
? _session->data().userLoaded(data.vuser_id())
|
||||
: nullptr;
|
||||
});
|
||||
};
|
||||
const auto &list = data.vimported().v;
|
||||
const auto user = list.isEmpty()
|
||||
? nullptr
|
||||
: extractUser(list.front());
|
||||
if (user) {
|
||||
if (user->isContact() || user->session().supportMode()) {
|
||||
Ui::showPeerHistory(user, ShowAtTheEndMsgId);
|
||||
}
|
||||
Ui::hideLayer();
|
||||
} else if (isBoxShown()) {
|
||||
hideChildren();
|
||||
_retrying = true;
|
||||
updateButtons();
|
||||
update();
|
||||
}
|
||||
})).send();
|
||||
}
|
||||
|
||||
|
||||
@@ -160,6 +160,21 @@ contactsAboutFg: windowSubTextFgOver;
|
||||
contactsAboutTop: 60px;
|
||||
contactsAboutBottom: 19px;
|
||||
|
||||
contactsSortButton: IconButton(defaultIconButton) {
|
||||
width: 48px;
|
||||
height: 54px;
|
||||
icon: icon{{ "contacts_alphabet", boxTitleCloseFg }};
|
||||
iconOver: icon{{ "contacts_alphabet", boxTitleCloseFgOver }};
|
||||
iconPosition: point(10px, -1px);
|
||||
rippleAreaPosition: point(1px, 6px);
|
||||
rippleAreaSize: 42px;
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: windowBgOver;
|
||||
}
|
||||
}
|
||||
contactsSortOnlineIcon: icon{{ "contacts_online", boxTitleCloseFg }};
|
||||
contactsSortOnlineIconOver: icon{{ "contacts_online", boxTitleCloseFgOver }};
|
||||
|
||||
contactsMarginTop: 4px;
|
||||
contactsMarginBottom: 4px;
|
||||
membersMarginTop: 10px;
|
||||
|
||||
@@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "apiwrap.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
@@ -26,12 +27,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history.h"
|
||||
#include "dialogs/dialogs_main_list.h"
|
||||
#include "window/window_session_controller.h" // showAddContact()
|
||||
#include "base/unixtime.h"
|
||||
#include "facades.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_profile.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kSortByOnlineThrottle = 3 * crl::time(1000);
|
||||
|
||||
void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
||||
const auto history = chat->owner().history(chat);
|
||||
auto &histories = history->owner().histories();
|
||||
@@ -110,17 +114,31 @@ void AddBotToGroup(not_null<UserData*> bot, not_null<PeerData*> chat) {
|
||||
|
||||
object_ptr<Ui::BoxContent> PrepareContactsBox(
|
||||
not_null<Window::SessionController*> sessionController) {
|
||||
const auto controller = sessionController;
|
||||
auto delegate = [=](not_null<PeerListBox*> box) {
|
||||
using Mode = ContactsBoxController::SortMode;
|
||||
auto controller = std::make_unique<ContactsBoxController>(
|
||||
&sessionController->session());
|
||||
const auto raw = controller.get();
|
||||
auto init = [=](not_null<PeerListBox*> box) {
|
||||
struct State {
|
||||
QPointer<Ui::IconButton> toggleSort;
|
||||
Mode mode = ContactsBoxController::SortMode::Online;
|
||||
};
|
||||
const auto state = box->lifetime().make_state<State>();
|
||||
box->addButton(tr::lng_close(), [=] { box->closeBox(); });
|
||||
box->addLeftButton(
|
||||
tr::lng_profile_add_contact(),
|
||||
[=] { controller->showAddContact(); });
|
||||
[=] { sessionController->showAddContact(); });
|
||||
state->toggleSort = box->addTopButton(st::contactsSortButton, [=] {
|
||||
const auto online = (state->mode == Mode::Online);
|
||||
state->mode = online ? Mode::Alphabet : Mode::Online;
|
||||
raw->setSortMode(state->mode);
|
||||
state->toggleSort->setIconOverride(
|
||||
online ? &st::contactsSortOnlineIcon : nullptr,
|
||||
online ? &st::contactsSortOnlineIconOver : nullptr);
|
||||
});
|
||||
raw->setSortMode(Mode::Online);
|
||||
};
|
||||
return Box<PeerListBox>(
|
||||
std::make_unique<ContactsBoxController>(
|
||||
&sessionController->session()),
|
||||
std::move(delegate));
|
||||
return Box<PeerListBox>(std::move(controller), std::move(init));
|
||||
}
|
||||
|
||||
void PeerListRowWithLink::setActionLink(const QString &action) {
|
||||
@@ -368,7 +386,8 @@ ContactsBoxController::ContactsBoxController(
|
||||
not_null<Main::Session*> session,
|
||||
std::unique_ptr<PeerListSearchController> searchController)
|
||||
: PeerListController(std::move(searchController))
|
||||
, _session(session) {
|
||||
, _session(session)
|
||||
, _sortByOnlineTimer([=] { sort(); }) {
|
||||
}
|
||||
|
||||
Main::Session &ContactsBoxController::session() const {
|
||||
@@ -404,6 +423,7 @@ void ContactsBoxController::rebuildRows() {
|
||||
};
|
||||
appendList(session().data().contactsList());
|
||||
checkForEmptyRows();
|
||||
sort();
|
||||
delegate()->peerListRefreshRows();
|
||||
}
|
||||
|
||||
@@ -427,6 +447,66 @@ void ContactsBoxController::rowClicked(not_null<PeerListRow*> row) {
|
||||
Ui::showPeerHistory(row->peer(), ShowAtUnreadMsgId);
|
||||
}
|
||||
|
||||
void ContactsBoxController::setSortMode(SortMode mode) {
|
||||
if (_sortMode == mode) {
|
||||
return;
|
||||
}
|
||||
_sortMode = mode;
|
||||
sort();
|
||||
if (_sortMode == SortMode::Online) {
|
||||
session().changes().peerUpdates(
|
||||
Data::PeerUpdate::Flag::OnlineStatus
|
||||
) | rpl::filter([=](const Data::PeerUpdate &update) {
|
||||
return !_sortByOnlineTimer.isActive()
|
||||
&& delegate()->peerListFindRow(update.peer->id.value);
|
||||
}) | rpl::start_with_next([=] {
|
||||
_sortByOnlineTimer.callOnce(kSortByOnlineThrottle);
|
||||
}, _sortByOnlineLifetime);
|
||||
} else {
|
||||
_sortByOnlineTimer.cancel();
|
||||
_sortByOnlineLifetime.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsBoxController::sort() {
|
||||
switch (_sortMode) {
|
||||
case SortMode::Alphabet: sortByName(); break;
|
||||
case SortMode::Online: sortByOnline(); break;
|
||||
default: Unexpected("SortMode in ContactsBoxController.");
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsBoxController::sortByName() {
|
||||
auto keys = base::flat_map<PeerListRowId, QString>();
|
||||
keys.reserve(delegate()->peerListFullRowsCount());
|
||||
const auto key = [&](const PeerListRow &row) {
|
||||
const auto id = row.id();
|
||||
const auto i = keys.find(id);
|
||||
if (i != end(keys)) {
|
||||
return i->second;
|
||||
}
|
||||
const auto peer = row.peer();
|
||||
const auto history = peer->owner().history(peer);
|
||||
return keys.emplace(id, history->chatListNameSortKey()).first->second;
|
||||
};
|
||||
const auto predicate = [&](const PeerListRow &a, const PeerListRow &b) {
|
||||
return (key(a).compare(key(b)) < 0);
|
||||
};
|
||||
delegate()->peerListSortRows(predicate);
|
||||
}
|
||||
|
||||
void ContactsBoxController::sortByOnline() {
|
||||
const auto now = base::unixtime::now();
|
||||
const auto key = [&](const PeerListRow &row) {
|
||||
const auto user = row.peer()->asUser();
|
||||
return user ? (std::min(user->onlineTill, now) + 1) : TimeId();
|
||||
};
|
||||
const auto predicate = [&](const PeerListRow &a, const PeerListRow &b) {
|
||||
return key(a) > key(b);
|
||||
};
|
||||
delegate()->peerListSortRows(predicate);
|
||||
}
|
||||
|
||||
bool ContactsBoxController::appendRow(not_null<UserData*> user) {
|
||||
if (auto row = delegate()->peerListFindRow(user->id.value)) {
|
||||
updateRowHook(row);
|
||||
|
||||
@@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/peer_list_box.h"
|
||||
#include "base/flat_set.h"
|
||||
#include "base/weak_ptr.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
// Not used for now.
|
||||
//
|
||||
@@ -136,6 +137,12 @@ public:
|
||||
not_null<PeerData*> peer) override final;
|
||||
void rowClicked(not_null<PeerListRow*> row) override;
|
||||
|
||||
enum class SortMode {
|
||||
Alphabet,
|
||||
Online,
|
||||
};
|
||||
void setSortMode(SortMode mode);
|
||||
|
||||
protected:
|
||||
virtual std::unique_ptr<PeerListRow> createRow(not_null<UserData*> user);
|
||||
virtual void prepareViewHook() {
|
||||
@@ -144,11 +151,17 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
void sort();
|
||||
void sortByName();
|
||||
void sortByOnline();
|
||||
void rebuildRows();
|
||||
void checkForEmptyRows();
|
||||
bool appendRow(not_null<UserData*> user);
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
SortMode _sortMode = SortMode::Alphabet;
|
||||
base::Timer _sortByOnlineTimer;
|
||||
rpl::lifetime _sortByOnlineLifetime;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ namespace {
|
||||
if (!top) {
|
||||
return false;
|
||||
} else if (peer == migrated) {
|
||||
return top.channel || (id < top.msg);
|
||||
return peerIsChannel(top.peer) || (id < top.msg);
|
||||
} else if (migrated) {
|
||||
return top.channel && (id < top.msg);
|
||||
return peerIsChannel(top.peer) && (id < top.msg);
|
||||
} else {
|
||||
return (id < top.msg);
|
||||
}
|
||||
|
||||
@@ -1105,12 +1105,14 @@ QString AppendShareGameScoreUrl(
|
||||
const FullMsgId &fullId) {
|
||||
auto shareHashData = QByteArray(0x20, Qt::Uninitialized);
|
||||
auto shareHashDataInts = reinterpret_cast<uint64*>(shareHashData.data());
|
||||
auto channel = fullId.channel
|
||||
? session->data().channelLoaded(fullId.channel)
|
||||
: static_cast<ChannelData*>(nullptr);
|
||||
auto channelAccessHash = uint64(channel ? channel->access : 0);
|
||||
const auto peer = fullId.peer
|
||||
? session->data().peerLoaded(fullId.peer)
|
||||
: static_cast<PeerData*>(nullptr);
|
||||
const auto channelAccessHash = uint64((peer && peer->isChannel())
|
||||
? peer->asChannel()->access
|
||||
: 0);
|
||||
shareHashDataInts[0] = session->userId().bare;
|
||||
shareHashDataInts[1] = fullId.channel.bare;
|
||||
shareHashDataInts[1] = fullId.peer.value;
|
||||
shareHashDataInts[2] = uint64(fullId.msg.bare);
|
||||
shareHashDataInts[3] = channelAccessHash;
|
||||
|
||||
@@ -1190,31 +1192,22 @@ void ShareGameScoreByHash(
|
||||
return;
|
||||
}
|
||||
|
||||
// Check first 32 bits of channel access hash.
|
||||
auto channelAccessHash = hashDataInts[3];
|
||||
//auto channelAccessHashInts = reinterpret_cast<int32*>(&channelAccessHash);
|
||||
//if (channelAccessHashInts[0] != hashDataInts[3]) {
|
||||
// Ui::show(Box<Ui::InformBox>(tr::lng_share_wrong_user(tr::now)));
|
||||
// return;
|
||||
//}
|
||||
|
||||
if (((hashDataInts[1] >> 40) != 0)
|
||||
|| (!hashDataInts[1] && channelAccessHash)) {
|
||||
const auto peerId = PeerId(hashDataInts[1]);
|
||||
const auto channelAccessHash = hashDataInts[3];
|
||||
if (!peerIsChannel(peerId) && channelAccessHash) {
|
||||
// If there is no channel id, there should be no channel access_hash.
|
||||
Ui::show(Box<Ui::InformBox>(tr::lng_share_wrong_user(tr::now)));
|
||||
return;
|
||||
}
|
||||
|
||||
auto channelId = ChannelId(hashDataInts[1]);
|
||||
auto msgId = MsgId(int64(hashDataInts[2]));
|
||||
if (const auto item = session->data().message(channelId, msgId)) {
|
||||
const auto msgId = MsgId(int64(hashDataInts[2]));
|
||||
if (const auto item = session->data().message(peerId, msgId)) {
|
||||
FastShareMessage(item);
|
||||
} else {
|
||||
auto resolveMessageAndShareScore = [=](ChannelData *channel) {
|
||||
session->api().requestMessageData(channel, msgId, [=](
|
||||
ChannelData *channel,
|
||||
MsgId msgId) {
|
||||
if (const auto item = session->data().message(channel, msgId)) {
|
||||
auto resolveMessageAndShareScore = [=](PeerData *peer) {
|
||||
session->api().requestMessageData(peer, msgId, [=] {
|
||||
const auto item = session->data().message(peerId, msgId);
|
||||
if (item) {
|
||||
FastShareMessage(item);
|
||||
} else {
|
||||
Ui::show(Box<Ui::InformBox>(
|
||||
@@ -1223,24 +1216,24 @@ void ShareGameScoreByHash(
|
||||
});
|
||||
};
|
||||
|
||||
const auto channel = channelId
|
||||
? session->data().channelLoaded(channelId)
|
||||
const auto peer = peerIsChannel(peerId)
|
||||
? session->data().peerLoaded(peerId)
|
||||
: nullptr;
|
||||
if (channel || !channelId) {
|
||||
resolveMessageAndShareScore(channel);
|
||||
if (peer || !peerIsChannel(peerId)) {
|
||||
resolveMessageAndShareScore(peer);
|
||||
} else {
|
||||
session->api().request(MTPchannels_GetChannels(
|
||||
MTP_vector<MTPInputChannel>(
|
||||
1,
|
||||
MTP_inputChannel(
|
||||
MTP_long(channelId.bare),
|
||||
MTP_long(peerToChannel(peerId).bare),
|
||||
MTP_long(channelAccessHash)))
|
||||
)).done([=](const MTPmessages_Chats &result) {
|
||||
result.match([&](const auto &data) {
|
||||
session->data().processChats(data.vchats());
|
||||
});
|
||||
if (const auto channel = session->data().channelLoaded(channelId)) {
|
||||
resolveMessageAndShareScore(channel);
|
||||
if (const auto peer = session->data().peerLoaded(peerId)) {
|
||||
resolveMessageAndShareScore(peer);
|
||||
}
|
||||
}).send();
|
||||
}
|
||||
|
||||
@@ -245,11 +245,12 @@ bool BotKeyboard::updateMarkup(HistoryItem *to, bool force) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_wasForMsgId == FullMsgId(to->channelId(), to->id) && !force) {
|
||||
const auto peerId = to->history()->peer->id;
|
||||
if (_wasForMsgId == FullMsgId(peerId, to->id) && !force) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_wasForMsgId = FullMsgId(to->channelId(), to->id);
|
||||
_wasForMsgId = FullMsgId(peerId, to->id);
|
||||
|
||||
auto markupFlags = to->replyKeyboardFlags();
|
||||
_forceReply = markupFlags & ReplyMarkupFlag::ForceReply;
|
||||
|
||||
@@ -164,7 +164,7 @@ void EmojiInteractions::startIncoming(
|
||||
if (!peer->isUser() || bunch.interactions.empty()) {
|
||||
return;
|
||||
}
|
||||
const auto item = _session->data().message(nullptr, messageId);
|
||||
const auto item = _session->data().message(peer->id, messageId);
|
||||
if (!item || !item->isRegular()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22,109 +22,6 @@ namespace {
|
||||
|
||||
std::map<int, const char*> BetaLogs() {
|
||||
return {
|
||||
{
|
||||
2009004,
|
||||
"- Choose one from dozens of new gorgeous animated backgrounds"
|
||||
" in Chat Settings > Chat background.\n"
|
||||
},
|
||||
{
|
||||
2009005,
|
||||
"- Tile chat background patterns horizontally.\n"
|
||||
|
||||
"- Fix a rare crash in spellchecker on Windows.\n"
|
||||
|
||||
"- Fix animated chat backgrounds in Saved Messages.\n"
|
||||
|
||||
"- Fix \"Sorry, group is inaccessible\" message "
|
||||
"in scheduled voice chats.\n",
|
||||
},
|
||||
{
|
||||
2009013,
|
||||
"- See unread comments count when scrolling discussions in channels."
|
||||
},
|
||||
{
|
||||
3000002,
|
||||
"- Check who've seen your message in small groups "
|
||||
"from the context menu.\n"
|
||||
|
||||
"- Enable recording with video in live streams and video chats."
|
||||
},
|
||||
{
|
||||
3000004,
|
||||
"- Fix a crash when joining video chat or live broadcast.\n"
|
||||
|
||||
"- Add a \"Close to Taskbar\" option when tray icon is disabled "
|
||||
"(Windows and Linux)."
|
||||
},
|
||||
{
|
||||
3000005,
|
||||
"- Add support for Emoji 13.1."
|
||||
},
|
||||
{
|
||||
3001002,
|
||||
"- Control video in fullscreen mode using arrows and numbers.\n"
|
||||
|
||||
"- Open locations in browser if default Bing Maps is not installed.\n"
|
||||
|
||||
"- Reconnect without timeout when network availability changes.\n"
|
||||
|
||||
"- Crash fixes."
|
||||
},
|
||||
{
|
||||
3001005,
|
||||
"- Choose one of 8 new preset themes for any individual private chat.\n"
|
||||
|
||||
"- Click on '...' menu > 'Change Colors' to pick a theme.\n"
|
||||
|
||||
"- Both chat participants will see the same theme in that chat "
|
||||
"– on all their devices.\n"
|
||||
|
||||
"- Each new theme features colorful gradient message bubbles, "
|
||||
"beautifully animated backgrounds and unique background patterns.\n"
|
||||
|
||||
"- All chat themes have day and night versions and will follow "
|
||||
"your overall dark mode settings.\n"
|
||||
|
||||
"- Implement main window rounded corners on Windows 11.\n"
|
||||
|
||||
"- Fix audio capture from AirPods on macOS.\n"
|
||||
},
|
||||
{
|
||||
3001006,
|
||||
"- Show small media previews in chats list.\n"
|
||||
|
||||
"- Show media album previews and caption text in chats list.\n"
|
||||
|
||||
"- Add \"Quick Reply\" and \"Mark as Read\" "
|
||||
"to native Windows notifications.\n"
|
||||
},
|
||||
{
|
||||
3001012,
|
||||
"- Create special invite links that require admins "
|
||||
"to approve users before they become members.\n"
|
||||
|
||||
"- Admins can view the applicants' profiles and bios "
|
||||
"by tapping the Join Requests bar at the top of the chat.\n"
|
||||
|
||||
"- Add internal labels to your chat's Invite Links "
|
||||
"to keep them organized.\n"
|
||||
|
||||
"- Run natively on Apple Silicon (macOS only).\n"
|
||||
},
|
||||
{
|
||||
3001013,
|
||||
"- Fix requests to groups / channels processing.\n"
|
||||
|
||||
"- Fix internal link previews with View Content button layout.\n"
|
||||
|
||||
"- Fix crash in messages search with imported messages results.\n"
|
||||
|
||||
"- Don't use fractional system UI scaling on Linux.\n"
|
||||
|
||||
"- Fix invite link icons on macOS.\n"
|
||||
|
||||
"- Several crash fixes.\n"
|
||||
},
|
||||
{
|
||||
3002006,
|
||||
"- Try out the new audio player with playlist shuffle and repeat.\n"
|
||||
@@ -141,6 +38,24 @@ std::map<int, const char*> BetaLogs() {
|
||||
"- Fix a crash in archived stickers loading.\n"
|
||||
|
||||
"- Fix a crash in calls to old Telegram versions.\n"
|
||||
},
|
||||
{
|
||||
3003001,
|
||||
"- Switch between contacts list sorting modes.\n"
|
||||
|
||||
"- Sort contacts list by last seen time by default.\n"
|
||||
|
||||
"- Fix disappearing Send As Channel button after message editing.\n"
|
||||
|
||||
"- Fix file upload cancelling.\n"
|
||||
|
||||
"- Fix crash in video capture on macOS.\n"
|
||||
|
||||
"- Fix labels in the About box.\n"
|
||||
|
||||
"- Use Qt 6.2.2 for macOS and Linux builds.\n"
|
||||
|
||||
"- Allow installing x64 Windows version on Windows ARM.\n"
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -43,9 +43,7 @@ PreLaunchWindow::PreLaunchWindow(QString title) {
|
||||
p.setColor(QPalette::Window, QColor(255, 255, 255));
|
||||
setPalette(p);
|
||||
|
||||
QLabel tmp(this);
|
||||
tmp.setText(qsl("Tmp"));
|
||||
_size = tmp.sizeHint().height();
|
||||
_size = QFontMetrics(QGuiApplication::font()).height();
|
||||
|
||||
int paddingVertical = (_size / 2);
|
||||
int paddingHorizontal = _size;
|
||||
|
||||
@@ -460,7 +460,6 @@ void Launcher::processArguments() {
|
||||
auto parseMap = std::map<QByteArray, KeyFormat> {
|
||||
{ "-debug" , KeyFormat::NoValues },
|
||||
{ "-freetype" , KeyFormat::NoValues },
|
||||
{ "-many" , KeyFormat::NoValues },
|
||||
{ "-key" , KeyFormat::OneValue },
|
||||
{ "-autostart" , KeyFormat::NoValues },
|
||||
{ "-fixprevious" , KeyFormat::NoValues },
|
||||
@@ -499,7 +498,6 @@ void Launcher::processArguments() {
|
||||
|
||||
gUseFreeType = parseResult.contains("-freetype");
|
||||
gDebugMode = parseResult.contains("-debug");
|
||||
gManyInstance = parseResult.contains("-many");
|
||||
gKeyFile = parseResult.value("-key", {}).join(QString()).toLower();
|
||||
gKeyFile = gKeyFile.replace(QRegularExpression("[^a-z0-9\\-_]"), {});
|
||||
gLaunchMode = parseResult.contains("-autostart") ? LaunchModeAutoStart
|
||||
|
||||
@@ -439,8 +439,8 @@ bool OpenMediaTimestamp(
|
||||
const auto parts = base.mid(3).split('_');
|
||||
const auto documentId = parts.value(0).toULongLong();
|
||||
const auto itemId = FullMsgId(
|
||||
parts.value(1).toInt(),
|
||||
parts.value(2).toInt());
|
||||
PeerId(parts.value(1).toULongLong()),
|
||||
MsgId(parts.value(2).toLongLong()));
|
||||
const auto session = &controller->session();
|
||||
const auto document = session->data().document(documentId);
|
||||
session->settings().setMediaLastPlaybackPosition(
|
||||
|
||||
@@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/effects/animations.h"
|
||||
#include "app.h"
|
||||
|
||||
#include <QtCore/QLockFile>
|
||||
#include <QtGui/QSessionManager>
|
||||
#include <QtGui/QScreen>
|
||||
#include <qpa/qplatformscreen.h>
|
||||
@@ -99,10 +100,35 @@ int Sandbox::start() {
|
||||
if (!Core::UpdaterDisabled()) {
|
||||
_updateChecker = std::make_unique<Core::UpdateChecker>();
|
||||
}
|
||||
const auto d = QFile::encodeName(QDir(cWorkingDir()).absolutePath());
|
||||
char h[33] = { 0 };
|
||||
hashMd5Hex(d.constData(), d.size(), h);
|
||||
_localServerName = Platform::SingleInstanceLocalServerName(h);
|
||||
|
||||
{
|
||||
const auto d = QFile::encodeName(QDir(cWorkingDir()).absolutePath());
|
||||
char h[33] = { 0 };
|
||||
hashMd5Hex(d.constData(), d.size(), h);
|
||||
_localServerName = Platform::SingleInstanceLocalServerName(h);
|
||||
}
|
||||
|
||||
{
|
||||
const auto d = QFile::encodeName(cExeDir() + cExeName());
|
||||
QByteArray h;
|
||||
h.resize(32);
|
||||
hashMd5Hex(d.constData(), d.size(), h.data());
|
||||
_lockFile = std::make_unique<QLockFile>(QDir::tempPath() + '/' + h + '-' + cGUIDStr());
|
||||
_lockFile->setStaleLockTime(0);
|
||||
if (!_lockFile->tryLock() && _launcher->customWorkingDir()) {
|
||||
// On Windows, QLockFile has problems detecting a stale lock
|
||||
// if the machine's hostname contains characters outside the US-ASCII character set.
|
||||
if constexpr (Platform::IsWindows()) {
|
||||
// QLockFile::removeStaleLockFile returns false on Windows,
|
||||
// when the application owning the lock is still running.
|
||||
if (!_lockFile->removeStaleLockFile()) {
|
||||
gManyInstance = true;
|
||||
}
|
||||
} else {
|
||||
gManyInstance = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connect(
|
||||
&_localSocket,
|
||||
@@ -149,13 +175,8 @@ int Sandbox::start() {
|
||||
restartHint,
|
||||
Qt::DirectConnection);
|
||||
|
||||
if (cManyInstance()) {
|
||||
LOG(("Many instance allowed, starting..."));
|
||||
singleInstanceChecked();
|
||||
} else {
|
||||
LOG(("Connecting local socket to %1...").arg(_localServerName));
|
||||
_localSocket.connectToServer(_localServerName);
|
||||
}
|
||||
LOG(("Connecting local socket to %1...").arg(_localServerName));
|
||||
_localSocket.connectToServer(_localServerName);
|
||||
|
||||
if (QuitOnStartRequested) {
|
||||
closeApplication();
|
||||
@@ -339,12 +360,12 @@ void Sandbox::socketError(QLocalSocket::LocalSocketError e) {
|
||||
|
||||
void Sandbox::singleInstanceChecked() {
|
||||
if (cManyInstance()) {
|
||||
Logs::multipleInstances();
|
||||
LOG(("App Info: Detected another instance"));
|
||||
}
|
||||
|
||||
Ui::DisableCustomScaling();
|
||||
refreshGlobalProxy();
|
||||
if (!Logs::started() || (!cManyInstance() && !Logs::instanceChecked())) {
|
||||
if (!Logs::started() || !Logs::instanceChecked()) {
|
||||
new NotStartedWindow();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <QtCore/QAbstractNativeEventFilter>
|
||||
|
||||
class QLockFile;
|
||||
|
||||
namespace Core {
|
||||
|
||||
class Launcher;
|
||||
@@ -119,6 +121,7 @@ private:
|
||||
QLocalServer _localServer;
|
||||
QLocalSocket _localSocket;
|
||||
LocalClients _localClients;
|
||||
std::unique_ptr<QLockFile> _lockFile;
|
||||
bool _secondInstance = false;
|
||||
bool _started = false;
|
||||
static bool QuitOnStartRequested;
|
||||
|
||||
@@ -30,8 +30,6 @@ extern "C" {
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include <QtNetwork/QSslSocket>
|
||||
|
||||
uint64 _SharedMemoryLocation[4] = { 0x00, 0x01, 0x02, 0x03 };
|
||||
|
||||
// Base types compile-time check
|
||||
@@ -56,15 +54,6 @@ static_assert(sizeof(int) >= 4, "Basic types size check failed");
|
||||
|
||||
// Precise timing functions / rand init
|
||||
|
||||
struct CRYPTO_dynlock_value {
|
||||
QMutex mutex;
|
||||
};
|
||||
|
||||
namespace {
|
||||
bool _sslInited = false;
|
||||
QMutex *_sslLocks = nullptr;
|
||||
}
|
||||
|
||||
namespace ThirdParty {
|
||||
|
||||
void start() {
|
||||
@@ -94,45 +83,15 @@ namespace ThirdParty {
|
||||
LOG(("MTP Error: Could not init OpenSSL rand, RAND_status() is 0..."));
|
||||
}
|
||||
}
|
||||
|
||||
// Force OpenSSL loading if it is linked in Qt,
|
||||
// so that we won't mess with our OpenSSL locking with Qt OpenSSL locking.
|
||||
auto sslSupported = QSslSocket::supportsSsl();
|
||||
if (!sslSupported) {
|
||||
LOG(("Error: current Qt build doesn't support SSL requests."));
|
||||
}
|
||||
if (!CRYPTO_get_locking_callback()) {
|
||||
// Qt didn't initialize OpenSSL, so we will.
|
||||
auto numLocks = CRYPTO_num_locks();
|
||||
if (numLocks) {
|
||||
_sslLocks = new QMutex[numLocks];
|
||||
CRYPTO_set_locking_callback(_sslLockingCallback);
|
||||
} else {
|
||||
LOG(("MTP Error: Could not init OpenSSL threads, CRYPTO_num_locks() returned zero!"));
|
||||
}
|
||||
}
|
||||
if (!CRYPTO_get_dynlock_create_callback()) {
|
||||
CRYPTO_set_dynlock_create_callback(_sslCreateFunction);
|
||||
CRYPTO_set_dynlock_lock_callback(_sslLockFunction);
|
||||
CRYPTO_set_dynlock_destroy_callback(_sslDestroyFunction);
|
||||
} else if (!CRYPTO_get_dynlock_lock_callback()) {
|
||||
LOG(("MTP Error: dynlock_create callback is set without dynlock_lock callback!"));
|
||||
}
|
||||
|
||||
_sslInited = true;
|
||||
}
|
||||
|
||||
void finish() {
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
#ifndef LIBRESSL_VERSION_NUMBER
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
EVP_default_properties_enable_fips(nullptr, 0);
|
||||
#else
|
||||
FIPS_mode_set(0);
|
||||
#endif
|
||||
ENGINE_cleanup();
|
||||
CONF_modules_unload(1);
|
||||
ERR_free_strings();
|
||||
EVP_cleanup();
|
||||
|
||||
delete[] base::take(_sslLocks);
|
||||
|
||||
Platform::ThirdParty::finish();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ constexpr auto AppId = "{53F49750-6209-4FBF-9CA8-7A333C87D1ED}"_cs;
|
||||
constexpr auto AppNameOld = "Telegram Win (Unofficial)"_cs;
|
||||
constexpr auto AppName = "Telegram Desktop"_cs;
|
||||
constexpr auto AppFile = "Telegram"_cs;
|
||||
constexpr auto AppVersion = 3003000;
|
||||
constexpr auto AppVersionStr = "3.3";
|
||||
constexpr auto AppBetaVersion = false;
|
||||
constexpr auto AppVersion = 3003001;
|
||||
constexpr auto AppVersionStr = "3.3.1";
|
||||
constexpr auto AppBetaVersion = true;
|
||||
constexpr auto AppAlphaVersion = TDESKTOP_ALPHA_VERSION;
|
||||
|
||||
@@ -1221,7 +1221,10 @@ bool DocumentData::hasWebLocation() const {
|
||||
}
|
||||
|
||||
bool DocumentData::isNull() const {
|
||||
return !hasRemoteLocation() && !hasWebLocation() && _url.isEmpty();
|
||||
return !hasRemoteLocation()
|
||||
&& !hasWebLocation()
|
||||
&& _url.isEmpty()
|
||||
&& !uploading();
|
||||
}
|
||||
|
||||
MTPInputDocument DocumentData::mtpInput() const {
|
||||
|
||||
@@ -300,9 +300,7 @@ void Folder::applyDialog(const MTPDdialogFolder &data) {
|
||||
_chatsList.updateCloudUnread(data);
|
||||
if (const auto peerId = peerFromMTP(data.vpeer())) {
|
||||
const auto history = owner().history(peerId);
|
||||
const auto fullId = FullMsgId(
|
||||
peerToChannel(peerId),
|
||||
data.vtop_message().v);
|
||||
const auto fullId = FullMsgId(peerId, data.vtop_message().v);
|
||||
history->setFolder(this, owner().message(fullId));
|
||||
} else {
|
||||
_chatsList.clear();
|
||||
|
||||
@@ -469,7 +469,7 @@ void Histories::requestGroupAround(not_null<HistoryItem*> item) {
|
||||
result);
|
||||
_chatListGroupRequests.remove(history);
|
||||
history->migrateToOrMe()->applyChatListGroup(
|
||||
history->channelId(),
|
||||
history->peer->id,
|
||||
result);
|
||||
finish();
|
||||
}).fail([=] {
|
||||
|
||||
@@ -157,26 +157,6 @@ void MessagesList::removeOne(MessagePosition messageId) {
|
||||
}
|
||||
}
|
||||
|
||||
void MessagesList::removeAll(ChannelId channelId) {
|
||||
auto removed = 0;
|
||||
for (auto i = begin(_slices); i != end(_slices); ++i) {
|
||||
_slices.modify(i, [&](Slice &slice) {
|
||||
auto &messages = slice.messages;
|
||||
for (auto j = begin(messages); j != end(messages);) {
|
||||
if (j->fullId.channel == channelId) {
|
||||
j = messages.erase(j);
|
||||
++removed;
|
||||
} else {
|
||||
++j;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (removed && _count) {
|
||||
*_count -= removed;
|
||||
}
|
||||
}
|
||||
|
||||
void MessagesList::removeLessThan(MessagePosition messageId) {
|
||||
auto removed = 0;
|
||||
for (auto i = begin(_slices); i != end(_slices);) {
|
||||
@@ -390,22 +370,6 @@ bool MessagesSliceBuilder::removeAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MessagesSliceBuilder::removeFromChannel(ChannelId channelId) {
|
||||
for (auto i = _ids.begin(); i != _ids.end();) {
|
||||
if ((*i).fullId.channel == channelId) {
|
||||
i = _ids.erase(i);
|
||||
if (_fullCount) {
|
||||
--*_fullCount;
|
||||
}
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
_skippedBefore = _skippedAfter = std::nullopt;
|
||||
checkInsufficient();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MessagesSliceBuilder::invalidated() {
|
||||
_fullCount = _skippedBefore = _skippedAfter = std::nullopt;
|
||||
_ids.clear();
|
||||
|
||||
@@ -65,11 +65,11 @@ struct MessagesRange {
|
||||
constexpr auto MinDate = TimeId(0);
|
||||
constexpr auto MaxDate = std::numeric_limits<TimeId>::max();
|
||||
constexpr auto MinMessagePosition = MessagePosition{
|
||||
.fullId = FullMsgId(NoChannel, 1),
|
||||
.fullId = FullMsgId(PeerId(), 1),
|
||||
.date = MinDate,
|
||||
};
|
||||
constexpr auto MaxMessagePosition = MessagePosition{
|
||||
.fullId = FullMsgId(NoChannel, ServerMaxMsgId - 1),
|
||||
.fullId = FullMsgId(PeerId(), ServerMaxMsgId - 1),
|
||||
.date = MaxDate,
|
||||
};
|
||||
constexpr auto FullMessagesRange = MessagesRange{
|
||||
@@ -77,7 +77,7 @@ constexpr auto FullMessagesRange = MessagesRange{
|
||||
.till = MaxMessagePosition,
|
||||
};
|
||||
constexpr auto UnreadMessagePosition = MessagePosition{
|
||||
.fullId = FullMsgId(NoChannel, ShowAtUnreadMsgId),
|
||||
.fullId = FullMsgId(PeerId(), ShowAtUnreadMsgId),
|
||||
.date = MinDate,
|
||||
};
|
||||
|
||||
@@ -117,7 +117,6 @@ public:
|
||||
MessagesRange noSkipRange,
|
||||
std::optional<int> count);
|
||||
void removeOne(MessagePosition messageId);
|
||||
void removeAll(ChannelId channelId);
|
||||
void removeLessThan(MessagePosition messageId);
|
||||
void invalidate();
|
||||
void invalidateBottom();
|
||||
@@ -191,7 +190,6 @@ public:
|
||||
bool applyInitial(const MessagesResult &result);
|
||||
bool applyUpdate(const MessagesSliceUpdate &update);
|
||||
bool removeOne(MessagePosition messageId);
|
||||
bool removeFromChannel(ChannelId channelId);
|
||||
bool removeAll();
|
||||
bool invalidated();
|
||||
bool bottomInvalidated();
|
||||
|
||||
@@ -122,9 +122,10 @@ struct MsgRange {
|
||||
|
||||
struct FullMsgId {
|
||||
constexpr FullMsgId() noexcept = default;
|
||||
constexpr FullMsgId(ChannelId channel, MsgId msg) noexcept
|
||||
: channel(channel), msg(msg) {
|
||||
constexpr FullMsgId(PeerId peer, MsgId msg) noexcept
|
||||
: peer(peer), msg(msg) {
|
||||
}
|
||||
FullMsgId(ChannelId channelId, MsgId msgId) = delete;
|
||||
|
||||
constexpr explicit operator bool() const noexcept {
|
||||
return msg != 0;
|
||||
@@ -133,16 +134,16 @@ struct FullMsgId {
|
||||
return msg == 0;
|
||||
}
|
||||
|
||||
ChannelId channel = NoChannel;
|
||||
PeerId peer = 0;
|
||||
MsgId msg = 0;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline constexpr bool operator<(
|
||||
const FullMsgId &a,
|
||||
const FullMsgId &b) noexcept {
|
||||
if (a.channel < b.channel) {
|
||||
if (a.peer < b.peer) {
|
||||
return true;
|
||||
} else if (a.channel > b.channel) {
|
||||
} else if (a.peer > b.peer) {
|
||||
return false;
|
||||
}
|
||||
return a.msg < b.msg;
|
||||
@@ -169,7 +170,7 @@ struct FullMsgId {
|
||||
[[nodiscard]] inline constexpr bool operator==(
|
||||
const FullMsgId &a,
|
||||
const FullMsgId &b) noexcept {
|
||||
return (a.channel == b.channel) && (a.msg == b.msg);
|
||||
return (a.peer == b.peer) && (a.msg == b.msg);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline constexpr bool operator!=(
|
||||
|
||||
@@ -1193,11 +1193,11 @@ FullMsgId ResolveTopPinnedId(
|
||||
.skippedAfter = 0,
|
||||
};
|
||||
if (!slice.messageIds.empty()) {
|
||||
return FullMsgId(peerToChannel(peer->id), slice.messageIds.back());
|
||||
return FullMsgId(peer->id, slice.messageIds.back());
|
||||
} else if (!migrated || slice.count != 0 || old.messageIds.empty()) {
|
||||
return FullMsgId();
|
||||
} else {
|
||||
return FullMsgId(0, old.messageIds.back());
|
||||
return FullMsgId(migrated->id, old.messageIds.back());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1227,9 +1227,9 @@ FullMsgId ResolveMinPinnedId(
|
||||
.skippedAfter = 0,
|
||||
};
|
||||
if (!old.messageIds.empty()) {
|
||||
return FullMsgId(0, old.messageIds.front());
|
||||
return FullMsgId(migrated->id, old.messageIds.front());
|
||||
} else if (old.count == 0 && !slice.messageIds.empty()) {
|
||||
return FullMsgId(peerToChannel(peer->id), slice.messageIds.front());
|
||||
return FullMsgId(peer->id, slice.messageIds.front());
|
||||
} else {
|
||||
return FullMsgId();
|
||||
}
|
||||
|
||||
@@ -136,8 +136,6 @@ using ChatId = ChatIdType<1>;
|
||||
using ChannelId = ChatIdType<2>;
|
||||
using FakeChatId = ChatIdType<0x7F>;
|
||||
|
||||
inline constexpr auto NoChannel = ChannelId(0);
|
||||
|
||||
struct PeerIdHelper {
|
||||
BareId value = 0;
|
||||
constexpr PeerIdHelper(BareId value) noexcept : value(value) {
|
||||
|
||||
@@ -193,10 +193,10 @@ std::optional<int> RepliesList::fullUnreadCountAfter(
|
||||
|| (fullLoaded && _list.empty());
|
||||
const auto countIncoming = [&](auto from, auto till) {
|
||||
auto &owner = _history->owner();
|
||||
const auto channelId = _history->channelId();
|
||||
const auto peerId = _history->peer->id;
|
||||
auto count = 0;
|
||||
for (auto i = from; i != till; ++i) {
|
||||
if (!owner.message(channelId, *i)->out()) {
|
||||
if (!owner.message(peerId, *i)->out()) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
@@ -336,7 +336,7 @@ bool RepliesList::buildFromData(not_null<Viewer*> viewer) {
|
||||
= (*_skippedAfter + (availableAfter - useAfter));
|
||||
}
|
||||
|
||||
const auto channelId = _history->channelId();
|
||||
const auto peerId = _history->peer->id;
|
||||
slice->ids.clear();
|
||||
auto nearestToAround = std::optional<MsgId>();
|
||||
slice->ids.reserve(useAfter + useBefore);
|
||||
@@ -346,10 +346,10 @@ bool RepliesList::buildFromData(not_null<Viewer*> viewer) {
|
||||
? *j
|
||||
: *(j - 1);
|
||||
}
|
||||
slice->ids.emplace_back(channelId, *j);
|
||||
slice->ids.emplace_back(peerId, *j);
|
||||
}
|
||||
slice->nearestToAround = FullMsgId(
|
||||
channelId,
|
||||
peerId,
|
||||
nearestToAround.value_or(
|
||||
slice->ids.empty() ? 0 : slice->ids.back().msg));
|
||||
slice->fullCount = _fullCount.current();
|
||||
@@ -418,7 +418,7 @@ Histories &RepliesList::histories() {
|
||||
}
|
||||
|
||||
HistoryItem *RepliesList::lookupRoot() {
|
||||
return _history->owner().message(_history->channelId(), _rootId);
|
||||
return _history->owner().message(_history->peer->id, _rootId);
|
||||
}
|
||||
|
||||
void RepliesList::loadAround(MsgId id) {
|
||||
|
||||
@@ -145,7 +145,7 @@ HistoryItem *ScheduledMessages::lookupItem(PeerId peer, MsgId msg) const {
|
||||
}
|
||||
|
||||
HistoryItem *ScheduledMessages::lookupItem(FullMsgId itemId) const {
|
||||
return lookupItem(peerFromChannel(itemId.channel), itemId.msg);
|
||||
return lookupItem(itemId.peer, itemId.msg);
|
||||
}
|
||||
|
||||
int ScheduledMessages::count(not_null<History*> history) const {
|
||||
|
||||
@@ -285,7 +285,7 @@ void Session::clear() {
|
||||
_sponsoredMessages = nullptr;
|
||||
_dependentMessages.clear();
|
||||
base::take(_messages);
|
||||
base::take(_channelMessages);
|
||||
base::take(_nonChannelMessages);
|
||||
_messageByRandomId.clear();
|
||||
_sentMessagesData.clear();
|
||||
cSetRecentInlineBots(RecentInlineBots());
|
||||
@@ -1334,20 +1334,31 @@ rpl::producer<not_null<HistoryItem*>> Session::newItemAdded() const {
|
||||
return _newItemAdded.events();
|
||||
}
|
||||
|
||||
void Session::changeMessageId(ChannelId channel, MsgId wasId, MsgId nowId) {
|
||||
const auto list = messagesListForInsert(channel);
|
||||
void Session::changeMessageId(PeerId peerId, MsgId wasId, MsgId nowId) {
|
||||
const auto list = messagesListForInsert(peerId);
|
||||
auto i = list->find(wasId);
|
||||
Assert(i != list->end());
|
||||
auto owned = std::move(i->second);
|
||||
const auto item = i->second;
|
||||
list->erase(i);
|
||||
const auto [j, ok] = list->emplace(nowId, std::move(owned));
|
||||
const auto [j, ok] = list->emplace(nowId, item);
|
||||
|
||||
if (!peerIsChannel(peerId)) {
|
||||
if (IsServerMsgId(wasId)) {
|
||||
const auto k = _nonChannelMessages.find(wasId);
|
||||
Assert(k != end(_nonChannelMessages));
|
||||
_nonChannelMessages.erase(k);
|
||||
}
|
||||
if (IsServerMsgId(nowId)) {
|
||||
_nonChannelMessages.emplace(nowId, item);
|
||||
}
|
||||
}
|
||||
|
||||
Ensures(ok);
|
||||
}
|
||||
|
||||
void Session::notifyItemIdChange(IdChange event) {
|
||||
const auto item = event.item;
|
||||
changeMessageId(item->history()->channelId(), event.oldId, item->id);
|
||||
changeMessageId(item->history()->peer->id, event.oldId, item->id);
|
||||
|
||||
_itemIdChanges.fire_copy(event);
|
||||
|
||||
@@ -1797,7 +1808,7 @@ void Session::reorderTwoPinnedChats(
|
||||
|
||||
bool Session::checkEntitiesAndViewsUpdate(const MTPDmessage &data) {
|
||||
const auto peer = peerFromMTP(data.vpeer_id());
|
||||
const auto existing = message(peerToChannel(peer), data.vid().v);
|
||||
const auto existing = message(peer, data.vid().v);
|
||||
if (!existing) {
|
||||
return false;
|
||||
}
|
||||
@@ -1817,8 +1828,7 @@ void Session::updateEditedMessage(const MTPMessage &data) {
|
||||
-> HistoryItem* {
|
||||
return nullptr;
|
||||
}, [&](const auto &data) {
|
||||
const auto peer = peerFromMTP(data.vpeer_id());
|
||||
return message(peerToChannel(peer), data.vid().v);
|
||||
return message(peerFromMTP(data.vpeer_id()), data.vid().v);
|
||||
});
|
||||
if (!existing) {
|
||||
return;
|
||||
@@ -1885,23 +1895,19 @@ void Session::processExistingMessages(
|
||||
});
|
||||
}
|
||||
|
||||
const Session::Messages *Session::messagesList(ChannelId channelId) const {
|
||||
if (channelId == NoChannel) {
|
||||
return &_messages;
|
||||
}
|
||||
const auto i = _channelMessages.find(channelId);
|
||||
return (i != end(_channelMessages)) ? &i->second : nullptr;
|
||||
const Session::Messages *Session::messagesList(PeerId peerId) const {
|
||||
const auto i = _messages.find(peerId);
|
||||
return (i != end(_messages)) ? &i->second : nullptr;
|
||||
}
|
||||
|
||||
auto Session::messagesListForInsert(ChannelId channelId)
|
||||
auto Session::messagesListForInsert(PeerId peerId)
|
||||
-> not_null<Messages*> {
|
||||
return (channelId == NoChannel)
|
||||
? &_messages
|
||||
: &_channelMessages[channelId];
|
||||
return &_messages[peerId];
|
||||
}
|
||||
|
||||
void Session::registerMessage(not_null<HistoryItem*> item) {
|
||||
const auto list = messagesListForInsert(item->channelId());
|
||||
const auto peerId = item->history()->peer->id;
|
||||
const auto list = messagesListForInsert(peerId);
|
||||
const auto itemId = item->id;
|
||||
const auto i = list->find(itemId);
|
||||
if (i != list->end()) {
|
||||
@@ -1909,6 +1915,10 @@ void Session::registerMessage(not_null<HistoryItem*> item) {
|
||||
i->second->destroy();
|
||||
}
|
||||
list->emplace(itemId, item);
|
||||
|
||||
if (!peerIsChannel(peerId) && IsServerMsgId(itemId)) {
|
||||
_nonChannelMessages.emplace(itemId, item);
|
||||
}
|
||||
}
|
||||
|
||||
void Session::registerMessageTTL(TimeId when, not_null<HistoryItem*> item) {
|
||||
@@ -1963,12 +1973,10 @@ void Session::checkTTLs() {
|
||||
}
|
||||
|
||||
void Session::processMessagesDeleted(
|
||||
ChannelId channelId,
|
||||
PeerId peerId,
|
||||
const QVector<MTPint> &data) {
|
||||
const auto list = messagesList(channelId);
|
||||
const auto affected = (channelId != NoChannel)
|
||||
? historyLoaded(peerFromChannel(channelId))
|
||||
: nullptr;
|
||||
const auto list = messagesList(peerId);
|
||||
const auto affected = historyLoaded(peerId);
|
||||
if (!list && !affected) {
|
||||
return;
|
||||
}
|
||||
@@ -1991,6 +1999,22 @@ void Session::processMessagesDeleted(
|
||||
}
|
||||
}
|
||||
|
||||
void Session::processNonChannelMessagesDeleted(const QVector<MTPint> &data) {
|
||||
auto historiesToCheck = base::flat_set<not_null<History*>>();
|
||||
for (const auto &messageId : data) {
|
||||
if (const auto item = nonChannelMessage(messageId.v)) {
|
||||
const auto history = item->history();
|
||||
item->destroy();
|
||||
if (!history->chatListMessageKnown()) {
|
||||
historiesToCheck.emplace(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto &history : historiesToCheck) {
|
||||
history->requestChatListMessage();
|
||||
}
|
||||
}
|
||||
|
||||
void Session::removeDependencyMessage(not_null<HistoryItem*> item) {
|
||||
const auto i = _dependentMessages.find(item);
|
||||
if (i == end(_dependentMessages)) {
|
||||
@@ -2006,13 +2030,18 @@ void Session::removeDependencyMessage(not_null<HistoryItem*> item) {
|
||||
|
||||
void Session::unregisterMessage(not_null<HistoryItem*> item) {
|
||||
const auto peerId = item->history()->peer->id;
|
||||
const auto itemId = item->id;
|
||||
_itemRemoved.fire_copy(item);
|
||||
session().changes().messageUpdated(
|
||||
item,
|
||||
Data::MessageUpdate::Flag::Destroyed);
|
||||
groups().unregisterMessage(item);
|
||||
removeDependencyMessage(item);
|
||||
messagesListForInsert(peerToChannel(peerId))->erase(item->id);
|
||||
messagesListForInsert(peerId)->erase(itemId);
|
||||
|
||||
if (!peerIsChannel(peerId) && IsServerMsgId(itemId)) {
|
||||
_nonChannelMessages.erase(itemId);
|
||||
}
|
||||
}
|
||||
|
||||
MsgId Session::nextLocalMessageId() {
|
||||
@@ -2035,12 +2064,12 @@ bool Session::suggestToGigagroup(not_null<ChannelData*> group) const {
|
||||
return _suggestToGigagroup.contains(group);
|
||||
}
|
||||
|
||||
HistoryItem *Session::message(ChannelId channelId, MsgId itemId) const {
|
||||
HistoryItem *Session::message(PeerId peerId, MsgId itemId) const {
|
||||
if (!itemId) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto data = messagesList(channelId);
|
||||
const auto data = messagesList(peerId);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2050,13 +2079,21 @@ HistoryItem *Session::message(ChannelId channelId, MsgId itemId) const {
|
||||
}
|
||||
|
||||
HistoryItem *Session::message(
|
||||
const ChannelData *channel,
|
||||
not_null<const PeerData*> peer,
|
||||
MsgId itemId) const {
|
||||
return message(channel ? peerToChannel(channel->id) : 0, itemId);
|
||||
return message(peer->id, itemId);
|
||||
}
|
||||
|
||||
HistoryItem *Session::message(FullMsgId itemId) const {
|
||||
return message(itemId.channel, itemId.msg);
|
||||
return message(itemId.peer, itemId.msg);
|
||||
}
|
||||
|
||||
HistoryItem *Session::nonChannelMessage(MsgId itemId) const {
|
||||
if (!IsServerMsgId(itemId)) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto i = _nonChannelMessages.find(itemId);
|
||||
return (i != end(_nonChannelMessages)) ? i->second.get() : nullptr;
|
||||
}
|
||||
|
||||
void Session::updateDependentMessages(not_null<HistoryItem*> item) {
|
||||
|
||||
@@ -348,19 +348,22 @@ public:
|
||||
void processExistingMessages(
|
||||
ChannelData *channel,
|
||||
const MTPmessages_Messages &data);
|
||||
void processNonChannelMessagesDeleted(const QVector<MTPint> &data);
|
||||
void processMessagesDeleted(
|
||||
ChannelId channelId,
|
||||
PeerId peerId,
|
||||
const QVector<MTPint> &data);
|
||||
|
||||
[[nodiscard]] MsgId nextLocalMessageId();
|
||||
[[nodiscard]] HistoryItem *message(
|
||||
ChannelId channelId,
|
||||
PeerId peerId,
|
||||
MsgId itemId) const;
|
||||
[[nodiscard]] HistoryItem *message(
|
||||
const ChannelData *channel,
|
||||
not_null<const PeerData*> peer,
|
||||
MsgId itemId) const;
|
||||
[[nodiscard]] HistoryItem *message(FullMsgId itemId) const;
|
||||
|
||||
[[nodiscard]] HistoryItem *nonChannelMessage(MsgId itemId) const;
|
||||
|
||||
void updateDependentMessages(not_null<HistoryItem*> item);
|
||||
void registerDependentMessage(
|
||||
not_null<HistoryItem*> dependent,
|
||||
@@ -698,11 +701,11 @@ private:
|
||||
Data::Folder *requestFolder,
|
||||
const MTPDdialogFolder &data);
|
||||
|
||||
const Messages *messagesList(ChannelId channelId) const;
|
||||
not_null<Messages*> messagesListForInsert(ChannelId channelId);
|
||||
const Messages *messagesList(PeerId peerId) const;
|
||||
not_null<Messages*> messagesListForInsert(PeerId peerId);
|
||||
not_null<HistoryItem*> registerMessage(
|
||||
std::unique_ptr<HistoryItem> item);
|
||||
void changeMessageId(ChannelId channel, MsgId wasId, MsgId nowId);
|
||||
void changeMessageId(PeerId peerId, MsgId wasId, MsgId nowId);
|
||||
void removeDependencyMessage(not_null<HistoryItem*> item);
|
||||
|
||||
void photoApplyFields(
|
||||
@@ -848,14 +851,15 @@ private:
|
||||
Dialogs::IndexedList _contactsNoChatsList;
|
||||
|
||||
MsgId _localMessageIdCounter = StartClientMsgId;
|
||||
Messages _messages;
|
||||
std::map<ChannelId, Messages> _channelMessages;
|
||||
std::unordered_map<PeerId, Messages> _messages;
|
||||
std::map<
|
||||
not_null<HistoryItem*>,
|
||||
base::flat_set<not_null<HistoryItem*>>> _dependentMessages;
|
||||
std::map<TimeId, base::flat_set<not_null<HistoryItem*>>> _ttlMessages;
|
||||
base::Timer _ttlCheckTimer;
|
||||
|
||||
std::unordered_map<MsgId, not_null<HistoryItem*>> _nonChannelMessages;
|
||||
|
||||
base::flat_map<uint64, FullMsgId> _messageByRandomId;
|
||||
base::flat_map<uint64, SentData> _sentMessagesData;
|
||||
|
||||
|
||||
@@ -365,7 +365,7 @@ std::optional<int> SharedMediaWithLastSlice::indexOf(Value value) const {
|
||||
? QString::number(*_ending->skippedAfter())
|
||||
: QString("-"));
|
||||
if (const auto msgId = std::get_if<FullMsgId>(&value)) {
|
||||
info.push_back("value:" + QString::number(msgId->channel.bare));
|
||||
info.push_back("value:" + QString::number(msgId->peer.value));
|
||||
info.push_back(QString::number(msgId->msg.bare));
|
||||
const auto index = _slice.indexOf(*std::get_if<FullMsgId>(&value));
|
||||
info.push_back("index:" + (index
|
||||
|
||||
@@ -164,7 +164,7 @@ private:
|
||||
return (a && b) ? base::make_optional(*a + *b) : std::nullopt;
|
||||
}
|
||||
static Value ComputeId(PeerId peerId, MsgId msgId) {
|
||||
return FullMsgId(peerToChannel(peerId), msgId);
|
||||
return FullMsgId(peerId, msgId);
|
||||
}
|
||||
static Value ComputeId(const Key &key) {
|
||||
if (const auto messageId = std::get_if<MessageId>(&key.universalId)) {
|
||||
|
||||
@@ -100,12 +100,10 @@ private:
|
||||
}
|
||||
|
||||
static bool IsFromSlice(PeerId peerId, FullMsgId fullId) {
|
||||
return peerIsChannel(peerId)
|
||||
? (peerId == peerFromChannel(fullId.channel))
|
||||
: !fullId.channel;
|
||||
return (peerId == fullId.peer);
|
||||
}
|
||||
static FullMsgId ComputeId(PeerId peerId, MsgId msgId) {
|
||||
return FullMsgId(peerToChannel(peerId), msgId);
|
||||
return FullMsgId(peerId, msgId);
|
||||
}
|
||||
static FullMsgId ComputeId(const Key &key) {
|
||||
return (key.universalId >= 0)
|
||||
|
||||
@@ -72,7 +72,7 @@ bool SponsoredMessages::append(not_null<History*> history) {
|
||||
}
|
||||
|
||||
const auto flags = MessageFlags(0)
|
||||
| (history->isChannel() ? MessageFlag::Post : MessageFlags(0))
|
||||
| (history->peer->isChannel() ? MessageFlag::Post : MessageFlags(0))
|
||||
| MessageFlag::HasFromId
|
||||
| MessageFlag::IsSponsored
|
||||
| MessageFlag::Local;
|
||||
@@ -93,7 +93,7 @@ bool SponsoredMessages::append(not_null<History*> history) {
|
||||
}
|
||||
|
||||
bool SponsoredMessages::canHaveFor(not_null<History*> history) const {
|
||||
return history->isChannel();
|
||||
return history->peer->isChannel();
|
||||
}
|
||||
|
||||
void SponsoredMessages::request(not_null<History*> history) {
|
||||
@@ -189,11 +189,10 @@ void SponsoredMessages::clearItems(not_null<History*> history) {
|
||||
|
||||
const SponsoredMessages::Entry *SponsoredMessages::find(
|
||||
const FullMsgId &fullId) const {
|
||||
if (!fullId.channel) {
|
||||
if (!peerIsChannel(fullId.peer)) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto history = _session->data().history(
|
||||
peerFromChannel(fullId.channel));
|
||||
const auto history = _session->data().history(fullId.peer);
|
||||
const auto it = _data.find(history);
|
||||
if (it == end(_data)) {
|
||||
return nullptr;
|
||||
|
||||
@@ -695,7 +695,7 @@ bool InnerWidget::isSearchResultActive(
|
||||
const auto peer = item->history()->peer;
|
||||
return (item->fullId() == entry.fullId)
|
||||
|| (peer->migrateTo()
|
||||
&& (peerToChannel(peer->migrateTo()->id) == entry.fullId.channel)
|
||||
&& (peer->migrateTo()->id == entry.fullId.peer)
|
||||
&& (item->id == -entry.fullId.msg))
|
||||
|| (uniqueSearchResults() && peer == entry.key.peer());
|
||||
}
|
||||
@@ -1552,7 +1552,7 @@ void InnerWidget::updateDialogRow(
|
||||
if (const auto migrated = from->owner().historyLoaded(from)) {
|
||||
row = RowDescriptor(
|
||||
migrated,
|
||||
FullMsgId(0, -row.fullId.msg));
|
||||
FullMsgId(from->id, -row.fullId.msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2712,7 +2712,7 @@ RowDescriptor InnerWidget::chatListEntryBefore(
|
||||
if (i != list->cbegin()) {
|
||||
return RowDescriptor(
|
||||
(*(i - 1))->key(),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
}
|
||||
}
|
||||
return RowDescriptor();
|
||||
@@ -2738,11 +2738,11 @@ RowDescriptor InnerWidget::chatListEntryBefore(
|
||||
}
|
||||
return RowDescriptor(
|
||||
_filterResults.back()->key(),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
}
|
||||
return RowDescriptor(
|
||||
session().data().history(_peerSearchResults.back()->peer),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
}
|
||||
}
|
||||
if (!_peerSearchResults.empty()
|
||||
@@ -2752,14 +2752,14 @@ RowDescriptor InnerWidget::chatListEntryBefore(
|
||||
}
|
||||
return RowDescriptor(
|
||||
_filterResults.back()->key(),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
}
|
||||
if (!_peerSearchResults.empty()) {
|
||||
for (auto b = _peerSearchResults.cbegin(), i = b + 1, e = _peerSearchResults.cend(); i != e; ++i) {
|
||||
if ((*i)->peer == whichHistory->peer) {
|
||||
return RowDescriptor(
|
||||
session().data().history((*(i - 1))->peer),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2771,7 +2771,7 @@ RowDescriptor InnerWidget::chatListEntryBefore(
|
||||
if ((*i)->key() == which.key) {
|
||||
return RowDescriptor(
|
||||
(*(i - 1))->key(),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
}
|
||||
}
|
||||
return RowDescriptor();
|
||||
@@ -2789,7 +2789,7 @@ RowDescriptor InnerWidget::chatListEntryAfter(
|
||||
if (i != list->cend()) {
|
||||
return RowDescriptor(
|
||||
(*i)->key(),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
}
|
||||
}
|
||||
return RowDescriptor();
|
||||
@@ -2815,7 +2815,7 @@ RowDescriptor InnerWidget::chatListEntryAfter(
|
||||
if (i != e) {
|
||||
return RowDescriptor(
|
||||
session().data().history((*i)->peer),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
} else if (!_searchResults.empty()) {
|
||||
return RowDescriptor(
|
||||
_searchResults.front()->item()->history(),
|
||||
@@ -2830,11 +2830,11 @@ RowDescriptor InnerWidget::chatListEntryAfter(
|
||||
if (i != e) {
|
||||
return RowDescriptor(
|
||||
(*i)->key(),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
} else if (!_peerSearchResults.empty()) {
|
||||
return RowDescriptor(
|
||||
session().data().history(_peerSearchResults.front()->peer),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
} else if (!_searchResults.empty()) {
|
||||
return RowDescriptor(
|
||||
_searchResults.front()->item()->history(),
|
||||
@@ -2853,17 +2853,17 @@ RowDescriptor InnerWidget::chatListEntryFirst() const {
|
||||
if (i != list->cend()) {
|
||||
return RowDescriptor(
|
||||
(*i)->key(),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
}
|
||||
return RowDescriptor();
|
||||
} else if (!_filterResults.empty()) {
|
||||
return RowDescriptor(
|
||||
_filterResults.front()->key(),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
} else if (!_peerSearchResults.empty()) {
|
||||
return RowDescriptor(
|
||||
session().data().history(_peerSearchResults.front()->peer),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
} else if (!_searchResults.empty()) {
|
||||
return RowDescriptor(
|
||||
_searchResults.front()->item()->history(),
|
||||
@@ -2879,7 +2879,7 @@ RowDescriptor InnerWidget::chatListEntryLast() const {
|
||||
if (i != list->cbegin()) {
|
||||
return RowDescriptor(
|
||||
(*(i - 1))->key(),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
}
|
||||
return RowDescriptor();
|
||||
} else if (!_searchResults.empty()) {
|
||||
@@ -2889,11 +2889,11 @@ RowDescriptor InnerWidget::chatListEntryLast() const {
|
||||
} else if (!_peerSearchResults.empty()) {
|
||||
return RowDescriptor(
|
||||
session().data().history(_peerSearchResults.back()->peer),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
} else if (!_filterResults.empty()) {
|
||||
return RowDescriptor(
|
||||
_filterResults.back()->key(),
|
||||
FullMsgId(NoChannel, ShowAtUnreadMsgId));
|
||||
FullMsgId(PeerId(), ShowAtUnreadMsgId));
|
||||
}
|
||||
return RowDescriptor();
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ not_null<ChannelData*> Widget::channel() const {
|
||||
Dialogs::RowDescriptor Widget::activeChat() const {
|
||||
return {
|
||||
channel()->owner().history(channel()),
|
||||
FullMsgId(peerToChannel(channel()->id), ShowAtUnreadMsgId)
|
||||
FullMsgId(channel()->id, ShowAtUnreadMsgId)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -366,7 +366,7 @@ not_null<HistoryItem*> History::createItem(
|
||||
const MTPMessage &message,
|
||||
MessageFlags localFlags,
|
||||
bool detachExistingItem) {
|
||||
if (const auto result = owner().message(channelId(), id)) {
|
||||
if (const auto result = owner().message(peer, id)) {
|
||||
if (detachExistingItem) {
|
||||
result->removeMainView();
|
||||
}
|
||||
@@ -2174,7 +2174,7 @@ bool History::isReadyFor(MsgId msgId) {
|
||||
}
|
||||
return loadedAtBottom();
|
||||
}
|
||||
const auto item = owner().message(channelId(), msgId);
|
||||
const auto item = owner().message(peer, msgId);
|
||||
return item && (item->history() == this) && item->mainView();
|
||||
}
|
||||
|
||||
@@ -2446,15 +2446,15 @@ void History::setFakeChatListMessageFrom(const MTPmessages_Messages &data) {
|
||||
}
|
||||
|
||||
void History::applyChatListGroup(
|
||||
ChannelId channelId,
|
||||
PeerId dataPeerId,
|
||||
const MTPmessages_Messages &data) {
|
||||
if (!isEmpty()
|
||||
|| !_chatListMessage
|
||||
|| !*_chatListMessage
|
||||
|| (*_chatListMessage)->history()->channelId() != channelId
|
||||
|| (*_chatListMessage)->history() != this
|
||||
|| !_lastMessage
|
||||
|| !*_lastMessage) {
|
||||
|| !*_lastMessage
|
||||
|| dataPeerId != peer->id) {
|
||||
return;
|
||||
}
|
||||
// Apply loaded album as a last slice.
|
||||
@@ -2463,7 +2463,7 @@ void History::applyChatListGroup(
|
||||
items.reserve(messages.v.size());
|
||||
for (const auto &message : messages.v) {
|
||||
const auto id = IdFromMessage(message);
|
||||
if (const auto message = owner().message(channelId, id)) {
|
||||
if (const auto message = owner().message(dataPeerId, id)) {
|
||||
items.push_back(message);
|
||||
}
|
||||
}
|
||||
@@ -2584,7 +2584,7 @@ void History::applyDialog(
|
||||
}
|
||||
if (!channel->amCreator()) {
|
||||
const auto topMessageId = FullMsgId(
|
||||
peerToChannel(channel->id),
|
||||
channel->id,
|
||||
data.vtop_message().v);
|
||||
if (const auto item = owner().message(topMessageId)) {
|
||||
if (item->date() <= channel->date) {
|
||||
@@ -2719,9 +2719,7 @@ void History::applyDialogFields(
|
||||
|
||||
void History::applyDialogTopMessage(MsgId topMessageId) {
|
||||
if (topMessageId) {
|
||||
const auto itemId = FullMsgId(
|
||||
channelId(),
|
||||
topMessageId);
|
||||
const auto itemId = FullMsgId(peer->id, topMessageId);
|
||||
if (const auto item = owner().message(itemId)) {
|
||||
setLastServerMessage(item);
|
||||
} else {
|
||||
@@ -2826,18 +2824,6 @@ void History::forceFullResize() {
|
||||
_flags |= Flag::f_has_pending_resized_items;
|
||||
}
|
||||
|
||||
ChannelId History::channelId() const {
|
||||
return peerToChannel(peer->id);
|
||||
}
|
||||
|
||||
bool History::isChannel() const {
|
||||
return peerIsChannel(peer->id);
|
||||
}
|
||||
|
||||
bool History::isMegagroup() const {
|
||||
return peer->isMegagroup();
|
||||
}
|
||||
|
||||
not_null<History*> History::migrateToOrMe() const {
|
||||
if (const auto to = peer->migrateTo()) {
|
||||
return owner().history(to);
|
||||
@@ -2964,7 +2950,7 @@ void History::checkLocalMessages() {
|
||||
insertMessageToBlocks(item);
|
||||
}
|
||||
}
|
||||
if (isChannel()
|
||||
if (peer->isChannel()
|
||||
&& !_joinedMessage
|
||||
&& peer->asChannel()->inviter
|
||||
&& goodDate(peer->asChannel()->inviteDate)) {
|
||||
|
||||
@@ -83,16 +83,12 @@ public:
|
||||
History &operator=(const History &) = delete;
|
||||
~History();
|
||||
|
||||
ChannelId channelId() const;
|
||||
bool isChannel() const;
|
||||
bool isMegagroup() const;
|
||||
not_null<History*> migrateToOrMe() const;
|
||||
History *migrateFrom() const;
|
||||
MsgRange rangeForDifferenceRequest() const;
|
||||
void checkLocalMessages();
|
||||
void removeJoinedMessage();
|
||||
|
||||
|
||||
bool isEmpty() const;
|
||||
bool isDisplayedEmpty() const;
|
||||
Element *findFirstNonEmpty() const;
|
||||
@@ -411,7 +407,7 @@ public:
|
||||
void checkChatListMessageRemoved(not_null<HistoryItem*> item);
|
||||
|
||||
void applyChatListGroup(
|
||||
ChannelId channelId,
|
||||
PeerId dataPeerId,
|
||||
const MTPmessages_Messages &data);
|
||||
|
||||
void forgetScrollState() {
|
||||
|
||||
@@ -2892,7 +2892,9 @@ MessageIdsList HistoryInner::getSelectedItems() const {
|
||||
}) | to_vector;
|
||||
|
||||
result |= actions::sort(less{}, [](const FullMsgId &msgId) {
|
||||
return msgId.channel ? msgId.msg : (msgId.msg - ServerMaxMsgId);
|
||||
return peerIsChannel(msgId.peer)
|
||||
? msgId.msg
|
||||
: (msgId.msg - ServerMaxMsgId);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ HistoryItem *HistoryItem::lookupDiscussionPostOriginal() const {
|
||||
return nullptr;
|
||||
}
|
||||
return _history->owner().message(
|
||||
forwarded->savedFromPeer->asChannel(),
|
||||
forwarded->savedFromPeer->id,
|
||||
forwarded->savedFromMsgId);
|
||||
}
|
||||
|
||||
@@ -745,8 +745,8 @@ bool HistoryItem::hasDirectLink() const {
|
||||
return isRegular() && _history->peer->isChannel();
|
||||
}
|
||||
|
||||
ChannelId HistoryItem::channelId() const {
|
||||
return _history->channelId();
|
||||
FullMsgId HistoryItem::fullId() const {
|
||||
return FullMsgId(_history->peer->id, id);
|
||||
}
|
||||
|
||||
Data::MessagePosition HistoryItem::position() const {
|
||||
|
||||
@@ -391,10 +391,7 @@ public:
|
||||
|
||||
[[nodiscard]] bool hasDirectLink() const;
|
||||
|
||||
[[nodiscard]] ChannelId channelId() const;
|
||||
[[nodiscard]] FullMsgId fullId() const {
|
||||
return FullMsgId(channelId(), id);
|
||||
}
|
||||
[[nodiscard]] FullMsgId fullId() const;
|
||||
[[nodiscard]] Data::MessagePosition position() const;
|
||||
[[nodiscard]] TimeId date() const;
|
||||
|
||||
|
||||
@@ -236,8 +236,8 @@ bool HistoryMessageReply::updateData(
|
||||
if (!replyToMsg) {
|
||||
replyToMsg = holder->history()->owner().message(
|
||||
(replyToPeerId
|
||||
? peerToChannel(replyToPeerId)
|
||||
: holder->channelId()),
|
||||
? replyToPeerId
|
||||
: holder->history()->peer->id),
|
||||
replyToMsgId);
|
||||
if (replyToMsg) {
|
||||
if (replyToMsg->isEmpty()) {
|
||||
|
||||
@@ -356,16 +356,15 @@ void RequestDependentMessageData(
|
||||
const auto fullId = item->fullId();
|
||||
const auto history = item->history();
|
||||
const auto session = &history->session();
|
||||
const auto done = [=] {
|
||||
if (const auto item = session->data().message(fullId)) {
|
||||
item->updateDependencyItem();
|
||||
}
|
||||
};
|
||||
history->session().api().requestMessageData(
|
||||
(peerIsChannel(peerId)
|
||||
? history->owner().channel(peerToChannel(peerId)).get()
|
||||
: history->peer->asChannel()),
|
||||
(peerId ? history->owner().peer(peerId) : history->peer),
|
||||
msgId,
|
||||
[=](ChannelData *channel, MsgId msgId) {
|
||||
if (const auto item = session->data().message(fullId)) {
|
||||
item->updateDependencyItem();
|
||||
}
|
||||
});
|
||||
done);
|
||||
}
|
||||
|
||||
MessageFlags NewMessageFlags(not_null<PeerData*> peer) {
|
||||
@@ -384,7 +383,7 @@ bool ShouldSendSilent(
|
||||
|
||||
MsgId LookupReplyToTop(not_null<History*> history, MsgId replyToId) {
|
||||
const auto &owner = history->owner();
|
||||
if (const auto item = owner.message(history->channelId(), replyToId)) {
|
||||
if (const auto item = owner.message(history->peer, replyToId)) {
|
||||
return item->replyToTop();
|
||||
}
|
||||
return 0;
|
||||
@@ -977,25 +976,28 @@ bool HistoryMessage::areRepliesUnread() const {
|
||||
|
||||
FullMsgId HistoryMessage::commentsItemId() const {
|
||||
if (const auto views = Get<HistoryMessageViews>()) {
|
||||
return FullMsgId(views->commentsMegagroupId, views->commentsRootId);
|
||||
return FullMsgId(
|
||||
PeerId(views->commentsMegagroupId),
|
||||
views->commentsRootId);
|
||||
}
|
||||
return FullMsgId();
|
||||
}
|
||||
|
||||
void HistoryMessage::setCommentsItemId(FullMsgId id) {
|
||||
if (id.channel == _history->channelId()) {
|
||||
if (id.peer == _history->peer->id) {
|
||||
if (id.msg != this->id) {
|
||||
if (const auto reply = Get<HistoryMessageReply>()) {
|
||||
reply->replyToMsgTop = id.msg;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else if (const auto views = Get<HistoryMessageViews>()) {
|
||||
if (views->commentsMegagroupId != id.channel) {
|
||||
views->commentsMegagroupId = id.channel;
|
||||
history()->owner().requestItemResize(this);
|
||||
if (const auto channelId = peerToChannel(id.peer)) {
|
||||
if (views->commentsMegagroupId != channelId) {
|
||||
views->commentsMegagroupId = channelId;
|
||||
history()->owner().requestItemResize(this);
|
||||
}
|
||||
views->commentsRootId = id.msg;
|
||||
}
|
||||
views->commentsRootId = id.msg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1966,13 +1968,11 @@ void HistoryMessage::changeReplyToTopCounter(
|
||||
if (!isRegular() || !reply->replyToTop()) {
|
||||
return;
|
||||
}
|
||||
const auto channelId = history()->channelId();
|
||||
if (!channelId) {
|
||||
const auto peerId = _history->peer->id;
|
||||
if (!peerIsChannel(peerId)) {
|
||||
return;
|
||||
}
|
||||
const auto top = history()->owner().message(
|
||||
channelId,
|
||||
reply->replyToTop());
|
||||
const auto top = _history->owner().message(peerId, reply->replyToTop());
|
||||
if (!top) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -605,8 +605,8 @@ bool HistoryService::updateDependent(bool force) {
|
||||
if (!dependent->msg) {
|
||||
dependent->msg = history()->owner().message(
|
||||
(dependent->peerId
|
||||
? peerToChannel(dependent->peerId)
|
||||
: channelId()),
|
||||
? dependent->peerId
|
||||
: _history->peer->id),
|
||||
dependent->msgId);
|
||||
if (dependent->msg) {
|
||||
if (dependent->msg->isEmpty()) {
|
||||
@@ -1245,14 +1245,14 @@ HistoryService::PreparedText GenerateJoinedText(
|
||||
if (inviter->id != history->session().userPeerId()) {
|
||||
auto result = HistoryService::PreparedText{};
|
||||
result.links.push_back(inviter->createOpenLink());
|
||||
result.text = (history->isMegagroup()
|
||||
result.text = (history->peer->isMegagroup()
|
||||
? tr::lng_action_add_you_group
|
||||
: tr::lng_action_add_you)(
|
||||
tr::now,
|
||||
lt_from,
|
||||
textcmdLink(1, inviter->name));
|
||||
return result;
|
||||
} else if (history->isMegagroup()) {
|
||||
} else if (history->peer->isMegagroup()) {
|
||||
if (viaRequest) {
|
||||
return { tr::lng_action_you_joined_by_request(tr::now) };
|
||||
}
|
||||
|
||||
@@ -777,7 +777,7 @@ HistoryWidget::HistoryWidget(
|
||||
return (action.history == _history);
|
||||
}) | rpl::start_with_next([=](const Api::SendAction &action) {
|
||||
const auto lastKeyboardUsed = lastForceReplyReplied(FullMsgId(
|
||||
action.history->channelId(),
|
||||
action.history->peer->id,
|
||||
action.replyTo));
|
||||
if (action.options.scheduled) {
|
||||
cancelReply(lastKeyboardUsed);
|
||||
@@ -1088,7 +1088,7 @@ void HistoryWidget::animatedScrollToItem(MsgId msgId) {
|
||||
updateListSize();
|
||||
}
|
||||
|
||||
auto to = session().data().message(_channel, msgId);
|
||||
auto to = session().data().message(_history->peer, msgId);
|
||||
if (_list->itemTop(to) < 0) {
|
||||
return;
|
||||
}
|
||||
@@ -1767,18 +1767,22 @@ void HistoryWidget::setReplyReturns(PeerId peer, const QList<MsgId> &replyReturn
|
||||
if (_replyReturns.isEmpty()) {
|
||||
_replyReturn = nullptr;
|
||||
} else if (_replyReturns.back() < 0 && -_replyReturns.back() < ServerMaxMsgId) {
|
||||
_replyReturn = session().data().message(0, -_replyReturns.back());
|
||||
_replyReturn = _migrated
|
||||
? session().data().message(_migrated->peer, -_replyReturns.back())
|
||||
: nullptr;
|
||||
} else {
|
||||
_replyReturn = session().data().message(_channel, _replyReturns.back());
|
||||
_replyReturn = session().data().message(peer, _replyReturns.back());
|
||||
}
|
||||
while (!_replyReturns.isEmpty() && !_replyReturn) {
|
||||
_replyReturns.pop_back();
|
||||
if (_replyReturns.isEmpty()) {
|
||||
_replyReturn = nullptr;
|
||||
} else if (_replyReturns.back() < 0 && -_replyReturns.back() < ServerMaxMsgId) {
|
||||
_replyReturn = session().data().message(0, -_replyReturns.back());
|
||||
_replyReturn = _migrated
|
||||
? session().data().message(_migrated->peer, -_replyReturns.back())
|
||||
: nullptr;
|
||||
} else {
|
||||
_replyReturn = session().data().message(_channel, _replyReturns.back());
|
||||
_replyReturn = session().data().message(peer, _replyReturns.back());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1790,9 +1794,13 @@ void HistoryWidget::calcNextReplyReturn() {
|
||||
if (_replyReturns.isEmpty()) {
|
||||
_replyReturn = nullptr;
|
||||
} else if (_replyReturns.back() < 0 && -_replyReturns.back() < ServerMaxMsgId) {
|
||||
_replyReturn = session().data().message(0, -_replyReturns.back());
|
||||
_replyReturn = _migrated
|
||||
? session().data().message(_migrated->peer, -_replyReturns.back())
|
||||
: nullptr;
|
||||
} else {
|
||||
_replyReturn = session().data().message(_channel, _replyReturns.back());
|
||||
_replyReturn = _peer
|
||||
? session().data().message(_peer, _replyReturns.back())
|
||||
: nullptr;
|
||||
}
|
||||
}
|
||||
if (!_replyReturn) {
|
||||
@@ -2026,7 +2034,6 @@ void HistoryWidget::showHistory(
|
||||
setHistory(nullptr);
|
||||
_list = nullptr;
|
||||
_peer = nullptr;
|
||||
_channel = NoChannel;
|
||||
_canSendMessages = false;
|
||||
_silent.destroy();
|
||||
updateBotKeyboard();
|
||||
@@ -2057,7 +2064,6 @@ void HistoryWidget::showHistory(
|
||||
|
||||
if (peerId) {
|
||||
_peer = session().data().peer(peerId);
|
||||
_channel = peerToChannel(_peer->id);
|
||||
_canSendMessages = _peer->canWrite();
|
||||
_contactStatus = std::make_unique<HistoryView::ContactStatus>(
|
||||
controller(),
|
||||
@@ -2110,7 +2116,7 @@ void HistoryWidget::showHistory(
|
||||
refreshTopBarActiveChat();
|
||||
updateTopBarSelection();
|
||||
|
||||
if (_channel) {
|
||||
if (_peer->isChannel()) {
|
||||
updateNotifyControls();
|
||||
session().data().requestNotifySettings(_peer);
|
||||
refreshSilentToggle();
|
||||
@@ -2215,7 +2221,7 @@ void HistoryWidget::showHistory(
|
||||
if (_history) {
|
||||
controller()->setActiveChatEntry({
|
||||
_history,
|
||||
FullMsgId(_history->channelId(), _showAtMsgId) });
|
||||
FullMsgId(_history->peer->id, _showAtMsgId) });
|
||||
}
|
||||
update();
|
||||
controller()->floatPlayerAreaUpdated();
|
||||
@@ -2949,7 +2955,7 @@ void HistoryWidget::firstLoadMessages() {
|
||||
_history->getReadyFor(_showAtMsgId);
|
||||
offset = -loadCount / 2;
|
||||
offsetId = _showAtMsgId;
|
||||
} else if (_showAtMsgId < 0 && _history->isChannel()) {
|
||||
} else if (_showAtMsgId < 0 && _history->peer->isChannel()) {
|
||||
if (_showAtMsgId < 0 && -_showAtMsgId < ServerMaxMsgId && _migrated) {
|
||||
_history->getReadyFor(_showAtMsgId);
|
||||
from = _migrated;
|
||||
@@ -3120,7 +3126,7 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
|
||||
} else if (_delayedShowAtMsgId > 0) {
|
||||
offset = -loadCount / 2;
|
||||
offsetId = _delayedShowAtMsgId;
|
||||
} else if (_delayedShowAtMsgId < 0 && _history->isChannel()) {
|
||||
} else if (_delayedShowAtMsgId < 0 && _history->peer->isChannel()) {
|
||||
if (_delayedShowAtMsgId < 0 && -_delayedShowAtMsgId < ServerMaxMsgId && _migrated) {
|
||||
from = _migrated;
|
||||
offset = -loadCount / 2;
|
||||
@@ -3307,7 +3313,7 @@ void HistoryWidget::showNextUnreadMention() {
|
||||
// See https://github.com/telegramdesktop/tdesktop/issues/5623
|
||||
if (msgId && already) {
|
||||
const auto item = _history->owner().message(
|
||||
_history->channelId(),
|
||||
_history->peer->id,
|
||||
msgId);
|
||||
if (const auto media = item ? item->media() : nullptr) {
|
||||
if (const auto document = media->document()) {
|
||||
@@ -3329,7 +3335,7 @@ void HistoryWidget::saveEditMsg() {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto item = session().data().message(_channel, _editMsgId);
|
||||
const auto item = session().data().message(_history->peer, _editMsgId);
|
||||
if (!item) {
|
||||
cancelEdit();
|
||||
return;
|
||||
@@ -3643,7 +3649,7 @@ void HistoryWidget::setMsgId(MsgId showAtMsgId) {
|
||||
if (_history) {
|
||||
controller()->setActiveChatEntry({
|
||||
_history,
|
||||
FullMsgId(_history->channelId(), _showAtMsgId) });
|
||||
FullMsgId(_history->peer->id, _showAtMsgId) });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3894,8 +3900,8 @@ void HistoryWidget::sendBotCommand(const Bot::SendCommandRequest &request) {
|
||||
}
|
||||
|
||||
const auto lastKeyboardUsed = (_keyboard->forMsgId()
|
||||
== FullMsgId(_channel, _history->lastKeyboardId))
|
||||
&& (_keyboard->forMsgId() == FullMsgId(_channel, request.replyTo));
|
||||
== FullMsgId(_peer->id, _history->lastKeyboardId))
|
||||
&& (_keyboard->forMsgId() == FullMsgId(_peer->id, request.replyTo));
|
||||
|
||||
// 'bot' may be nullptr in case of sending from FieldAutocomplete.
|
||||
const auto toSend = (request.replyTo/* || !bot*/)
|
||||
@@ -3927,7 +3933,8 @@ void HistoryWidget::sendBotCommand(const Bot::SendCommandRequest &request) {
|
||||
void HistoryWidget::hideSingleUseKeyboard(PeerData *peer, MsgId replyTo) {
|
||||
if (!_peer || _peer != peer) return;
|
||||
|
||||
bool lastKeyboardUsed = (_keyboard->forMsgId() == FullMsgId(_channel, _history->lastKeyboardId)) && (_keyboard->forMsgId() == FullMsgId(_channel, replyTo));
|
||||
bool lastKeyboardUsed = (_keyboard->forMsgId() == FullMsgId(_peer->id, _history->lastKeyboardId))
|
||||
&& (_keyboard->forMsgId() == FullMsgId(_peer->id, replyTo));
|
||||
if (replyTo) {
|
||||
if (_replyToId == replyTo) {
|
||||
cancelReply();
|
||||
@@ -4181,7 +4188,11 @@ bool HistoryWidget::updateCmdStartShown() {
|
||||
}
|
||||
|
||||
bool HistoryWidget::kbWasHidden() const {
|
||||
return _history && (_keyboard->forMsgId() == FullMsgId(_history->channelId(), _history->lastKeyboardHiddenId));
|
||||
return _history
|
||||
&& (_keyboard->forMsgId()
|
||||
== FullMsgId(
|
||||
_history->peer->id,
|
||||
_history->lastKeyboardHiddenId));
|
||||
}
|
||||
|
||||
void HistoryWidget::toggleKeyboard(bool manual) {
|
||||
@@ -5308,7 +5319,9 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
|
||||
changed = _keyboard->updateMarkup(_replyEditMsg, force);
|
||||
} else {
|
||||
const auto keyboardItem = _history->lastKeyboardId
|
||||
? session().data().message(_channel, _history->lastKeyboardId)
|
||||
? session().data().message(
|
||||
_history->peer,
|
||||
_history->lastKeyboardId)
|
||||
: nullptr;
|
||||
changed = _keyboard->updateMarkup(keyboardItem, force);
|
||||
}
|
||||
@@ -5319,7 +5332,11 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
|
||||
|
||||
bool hasMarkup = _keyboard->hasMarkup(), forceReply = _keyboard->forceReply() && (!_replyToId || !_replyEditMsg);
|
||||
if (hasMarkup || forceReply) {
|
||||
if (_keyboard->singleUse() && _keyboard->hasMarkup() && _keyboard->forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) {
|
||||
if (_keyboard->singleUse()
|
||||
&& _keyboard->hasMarkup()
|
||||
&& (_keyboard->forMsgId()
|
||||
== FullMsgId(_history->peer->id, _history->lastKeyboardId))
|
||||
&& _history->lastKeyboardUsed) {
|
||||
_history->lastKeyboardHiddenId = _history->lastKeyboardId;
|
||||
}
|
||||
if (!isBotStart() && !isBlocked() && _canSendMessages && (wasVisible || (_replyToId && _replyEditMsg) || (!HasSendText(_field) && !kbWasHidden()))) {
|
||||
@@ -5391,8 +5408,8 @@ void HistoryWidget::botCallbackSent(not_null<HistoryItem*> item) {
|
||||
}
|
||||
|
||||
const auto keyId = _keyboard->forMsgId();
|
||||
const auto lastKeyboardUsed = (keyId == FullMsgId(_channel, item->id))
|
||||
&& (keyId == FullMsgId(_channel, _history->lastKeyboardId));
|
||||
const auto lastKeyboardUsed = (keyId == FullMsgId(_peer->id, item->id))
|
||||
&& (keyId == FullMsgId(_peer->id, _history->lastKeyboardId));
|
||||
|
||||
session().data().requestItemRepaint(item);
|
||||
|
||||
@@ -5706,9 +5723,7 @@ bool HistoryWidget::replyToPreviousMessage() {
|
||||
if (!_history || _editMsgId) {
|
||||
return false;
|
||||
}
|
||||
const auto fullId = FullMsgId(
|
||||
_history->channelId(),
|
||||
_replyToId);
|
||||
const auto fullId = FullMsgId(_history->peer->id, _replyToId);
|
||||
if (const auto item = session().data().message(fullId)) {
|
||||
if (const auto view = item->mainView()) {
|
||||
if (const auto previousView = view->previousDisplayedInBlocks()) {
|
||||
@@ -5731,9 +5746,7 @@ bool HistoryWidget::replyToNextMessage() {
|
||||
if (!_history || _editMsgId) {
|
||||
return false;
|
||||
}
|
||||
const auto fullId = FullMsgId(
|
||||
_history->channelId(),
|
||||
_replyToId);
|
||||
const auto fullId = FullMsgId(_history->peer->id, _replyToId);
|
||||
if (const auto item = session().data().message(fullId)) {
|
||||
if (const auto view = item->mainView()) {
|
||||
if (const auto nextView = view->nextDisplayedInBlocks()) {
|
||||
@@ -5841,7 +5854,7 @@ void HistoryWidget::updatePinnedViewer() {
|
||||
: (view->data()->id + (offset > 0 ? 1 : 0));
|
||||
const auto lastClickedId = !_pinnedClickedId
|
||||
? (ServerMaxMsgId - 1)
|
||||
: (!_migrated || _pinnedClickedId.channel)
|
||||
: (!_migrated || peerIsChannel(_pinnedClickedId.peer))
|
||||
? _pinnedClickedId.msg
|
||||
: (_pinnedClickedId.msg - ServerMaxMsgId);
|
||||
if (_pinnedClickedId
|
||||
@@ -5899,7 +5912,7 @@ void HistoryWidget::checkPinnedBarState() {
|
||||
_migrated ? _migrated->peer.get() : nullptr);
|
||||
const auto universalPinnedId = !currentPinnedId
|
||||
? int32(0)
|
||||
: (_migrated && !currentPinnedId.channel)
|
||||
: (_migrated && !peerIsChannel(currentPinnedId.peer))
|
||||
? (currentPinnedId.msg - ServerMaxMsgId)
|
||||
: currentPinnedId.msg;
|
||||
if (universalPinnedId == hiddenId) {
|
||||
@@ -6046,7 +6059,7 @@ void HistoryWidget::refreshPinnedBarButton(bool many) {
|
||||
controller()->showSection(
|
||||
std::make_shared<HistoryView::PinnedMemento>(
|
||||
_history,
|
||||
((!_migrated || id.message.channel)
|
||||
((!_migrated || peerIsChannel(id.message.peer))
|
||||
? id.message.msg
|
||||
: (id.message.msg - ServerMaxMsgId))));
|
||||
}
|
||||
@@ -6154,13 +6167,14 @@ void HistoryWidget::setupRequestsBar() {
|
||||
}
|
||||
|
||||
void HistoryWidget::requestMessageData(MsgId msgId) {
|
||||
const auto callback = [=](ChannelData *channel, MsgId msgId) {
|
||||
messageDataReceived(channel, msgId);
|
||||
};
|
||||
session().api().requestMessageData(
|
||||
_peer->asChannel(),
|
||||
msgId,
|
||||
crl::guard(this, callback));
|
||||
if (!_peer) {
|
||||
return;
|
||||
}
|
||||
const auto peer = _peer;
|
||||
const auto callback = crl::guard(this, [=] {
|
||||
messageDataReceived(peer, msgId);
|
||||
});
|
||||
session().api().requestMessageData(_peer, msgId, callback);
|
||||
}
|
||||
|
||||
bool HistoryWidget::sendExistingDocument(
|
||||
@@ -6437,17 +6451,17 @@ void HistoryWidget::hidePinnedMessage() {
|
||||
}
|
||||
|
||||
bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const {
|
||||
if (replyTo.channel != _channel) {
|
||||
return false;
|
||||
}
|
||||
return _keyboard->forceReply()
|
||||
&& _keyboard->forMsgId() == FullMsgId(_channel, _history->lastKeyboardId)
|
||||
return _peer
|
||||
&& (replyTo.peer == _peer->id)
|
||||
&& _keyboard->forceReply()
|
||||
&& _keyboard->forMsgId() == FullMsgId(_peer->id, _history->lastKeyboardId)
|
||||
&& _keyboard->forMsgId().msg == replyTo.msg;
|
||||
}
|
||||
|
||||
bool HistoryWidget::lastForceReplyReplied() const {
|
||||
return _keyboard->forceReply()
|
||||
&& _keyboard->forMsgId() == FullMsgId(_channel, _history->lastKeyboardId)
|
||||
return _peer
|
||||
&& _keyboard->forceReply()
|
||||
&& _keyboard->forMsgId() == FullMsgId(_peer->id, _history->lastKeyboardId)
|
||||
&& _keyboard->forMsgId().msg == replyToId();
|
||||
}
|
||||
|
||||
@@ -6536,9 +6550,7 @@ void HistoryWidget::cancelEdit() {
|
||||
fieldChanged();
|
||||
_textUpdateEvents = old;
|
||||
|
||||
if (!canWriteMessage()) {
|
||||
updateControlsVisibility();
|
||||
}
|
||||
updateControlsVisibility();
|
||||
updateBotKeyboard();
|
||||
updateFieldPlaceholder();
|
||||
|
||||
@@ -6840,10 +6852,11 @@ void HistoryWidget::clearSelected() {
|
||||
}
|
||||
|
||||
HistoryItem *HistoryWidget::getItemFromHistoryOrMigrated(MsgId genericMsgId) const {
|
||||
if (genericMsgId < 0 && -genericMsgId < ServerMaxMsgId && _migrated) {
|
||||
return session().data().message(_migrated->channelId(), -genericMsgId);
|
||||
}
|
||||
return session().data().message(_channel, genericMsgId);
|
||||
return (genericMsgId < 0 && -genericMsgId < ServerMaxMsgId && _migrated)
|
||||
? session().data().message(_migrated->peer, -genericMsgId)
|
||||
: _peer
|
||||
? session().data().message(_peer, genericMsgId)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
MessageIdsList HistoryWidget::getSelectedItems() const {
|
||||
@@ -6906,11 +6919,12 @@ void HistoryWidget::updateTopBarSelection() {
|
||||
update();
|
||||
}
|
||||
|
||||
void HistoryWidget::messageDataReceived(ChannelData *channel, MsgId msgId) {
|
||||
if (!_peer || _peer->asChannel() != channel || !msgId) {
|
||||
void HistoryWidget::messageDataReceived(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId msgId) {
|
||||
if (!_peer || _peer != peer || !msgId) {
|
||||
return;
|
||||
}
|
||||
if (_editMsgId == msgId || _replyToId == msgId) {
|
||||
} else if (_editMsgId == msgId || _replyToId == msgId) {
|
||||
updateReplyEditTexts(true);
|
||||
}
|
||||
}
|
||||
@@ -6932,8 +6946,10 @@ void HistoryWidget::updateReplyEditTexts(bool force) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!_replyEditMsg) {
|
||||
_replyEditMsg = session().data().message(_channel, _editMsgId ? _editMsgId : _replyToId);
|
||||
if (!_replyEditMsg && _peer) {
|
||||
_replyEditMsg = session().data().message(
|
||||
_peer->id,
|
||||
_editMsgId ? _editMsgId : _replyToId);
|
||||
}
|
||||
if (_replyEditMsg) {
|
||||
updateReplyEditText(_replyEditMsg);
|
||||
|
||||
@@ -369,7 +369,7 @@ private:
|
||||
void refreshTopBarActiveChat();
|
||||
|
||||
void requestMessageData(MsgId msgId);
|
||||
void messageDataReceived(ChannelData *channel, MsgId msgId);
|
||||
void messageDataReceived(not_null<PeerData*> peer, MsgId msgId);
|
||||
|
||||
[[nodiscard]] Api::SendAction prepareSendAction(
|
||||
Api::SendOptions options) const;
|
||||
@@ -666,7 +666,6 @@ private:
|
||||
|
||||
PeerData *_peer = nullptr;
|
||||
|
||||
ChannelId _channel = NoChannel;
|
||||
bool _canSendMessages = false;
|
||||
MsgId _showAtMsgId = ShowAtUnreadMsgId;
|
||||
|
||||
|
||||
@@ -368,15 +368,14 @@ void FieldHeader::resolveMessageData() {
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
const auto channel = id.channel
|
||||
? _data->channel(id.channel).get()
|
||||
: nullptr;
|
||||
const auto callback = [=](ChannelData *channel, MsgId msgId) {
|
||||
const auto peer = _data->peer(id.peer);
|
||||
const auto itemId = id.msg;
|
||||
const auto callback = crl::guard(this, [=] {
|
||||
const auto now = (isEditingMessage()
|
||||
? _editMsgId
|
||||
: _replyToId).current();
|
||||
if (now == id && !_shownMessage) {
|
||||
if (const auto message = _data->message(channel, msgId)) {
|
||||
if (const auto message = _data->message(peer, itemId)) {
|
||||
setShownMessage(message);
|
||||
} else if (isEditingMessage()) {
|
||||
_editCancelled.fire({});
|
||||
@@ -384,11 +383,8 @@ void FieldHeader::resolveMessageData() {
|
||||
_replyCancelled.fire({});
|
||||
}
|
||||
}
|
||||
};
|
||||
_data->session().api().requestMessageData(
|
||||
channel,
|
||||
id.msg,
|
||||
crl::guard(this, callback));
|
||||
});
|
||||
_data->session().api().requestMessageData(peer, itemId, callback);
|
||||
}
|
||||
|
||||
void FieldHeader::previewRequested(
|
||||
@@ -1537,10 +1533,10 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||
_previewSetState(draft->previewState);
|
||||
|
||||
if (draft == editDraft) {
|
||||
_header->editMessage({ _history->channelId(), draft->msgId });
|
||||
_header->editMessage({ _history->peer->id, draft->msgId });
|
||||
_header->replyToMessage({});
|
||||
} else {
|
||||
_header->replyToMessage({ _history->channelId(), draft->msgId });
|
||||
_header->replyToMessage({ _history->peer->id, draft->msgId });
|
||||
_header->editMessage({});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -986,7 +986,7 @@ void CopyPostLink(
|
||||
Assert(channel != nullptr);
|
||||
if (const auto rootId = item->replyToTop()) {
|
||||
const auto root = item->history()->owner().message(
|
||||
peerToChannel(channel->id),
|
||||
channel->id,
|
||||
rootId);
|
||||
const auto sender = root
|
||||
? root->discussionPostOriginalSender()
|
||||
|
||||
@@ -2318,7 +2318,9 @@ ClickHandlerPtr Message::rightActionLink() const {
|
||||
const auto owner = &data()->history()->owner();
|
||||
const auto itemId = data()->fullId();
|
||||
const auto forwarded = data()->Get<HistoryMessageForwarded>();
|
||||
const auto savedFromPeer = forwarded ? forwarded->savedFromPeer : nullptr;
|
||||
const auto savedFromPeer = forwarded
|
||||
? forwarded->savedFromPeer
|
||||
: nullptr;
|
||||
const auto savedFromMsgId = forwarded ? forwarded->savedFromMsgId : 0;
|
||||
|
||||
using Callback = FnMut<void(not_null<Window::SessionController*>)>;
|
||||
@@ -2328,7 +2330,7 @@ ClickHandlerPtr Message::rightActionLink() const {
|
||||
*showByThread = [=, requested = 0](
|
||||
not_null<Window::SessionController*> controller) mutable {
|
||||
const auto original = savedFromPeer->owner().message(
|
||||
savedFromPeer->asChannel(),
|
||||
savedFromPeer,
|
||||
savedFromMsgId);
|
||||
if (original && original->replyToTop()) {
|
||||
controller->showRepliesForMessage(
|
||||
@@ -2337,14 +2339,12 @@ ClickHandlerPtr Message::rightActionLink() const {
|
||||
original->id,
|
||||
Window::SectionShow::Way::Forward);
|
||||
} else if (!requested) {
|
||||
const auto channel = savedFromPeer->asChannel();
|
||||
const auto prequested = &requested;
|
||||
requested = 1;
|
||||
channel->session().api().requestMessageData(
|
||||
channel,
|
||||
savedFromPeer->session().api().requestMessageData(
|
||||
savedFromPeer,
|
||||
savedFromMsgId,
|
||||
[=, weak = base::make_weak(controller.get())](
|
||||
ChannelData *gotChannel, MsgId gotId) {
|
||||
[=, weak = base::make_weak(controller.get())] {
|
||||
if (const auto strong = showByThreadWeak.lock()) {
|
||||
if (const auto strongController = weak.get()) {
|
||||
*prequested = 2;
|
||||
|
||||
@@ -101,13 +101,9 @@ namespace {
|
||||
consumer.put_next(Ui::MessageBarContent{
|
||||
.text = { tr::lng_contacts_loading(tr::now) },
|
||||
});
|
||||
const auto channel = id.channel
|
||||
? session->data().channel(id.channel).get()
|
||||
: nullptr;
|
||||
const auto callback = [=](ChannelData *channel, MsgId id) {
|
||||
consumer.put_done();
|
||||
};
|
||||
session->api().requestMessageData(channel, id.msg, callback);
|
||||
const auto peer = session->data().peer(id.peer);
|
||||
const auto callback = [=] { consumer.put_done(); };
|
||||
session->api().requestMessageData(peer, id.msg, callback);
|
||||
return rpl::lifetime();
|
||||
});
|
||||
return std::move(
|
||||
|
||||
@@ -64,9 +64,7 @@ PinnedMemento::PinnedMemento(
|
||||
: _history(history)
|
||||
, _highlightId(highlightId) {
|
||||
_list.setAroundPosition({
|
||||
.fullId = FullMsgId(
|
||||
history->channelId(),
|
||||
highlightId),
|
||||
.fullId = FullMsgId(history->peer->id, highlightId),
|
||||
.date = TimeId(0),
|
||||
});
|
||||
}
|
||||
@@ -332,7 +330,7 @@ not_null<History*> PinnedWidget::history() const {
|
||||
Dialogs::RowDescriptor PinnedWidget::activeChat() const {
|
||||
return {
|
||||
_history,
|
||||
FullMsgId(_history->channelId(), ShowAtUnreadMsgId)
|
||||
FullMsgId(_history->peer->id, ShowAtUnreadMsgId)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -391,8 +389,8 @@ void PinnedWidget::restoreState(not_null<PinnedMemento*> memento) {
|
||||
if (const auto highlight = memento->getHighlightId()) {
|
||||
const auto position = Data::MessagePosition{
|
||||
.fullId = ((highlight > 0 || !_migratedPeer)
|
||||
? FullMsgId(_history->channelId(), highlight)
|
||||
: FullMsgId(0, -highlight)),
|
||||
? FullMsgId(_history->peer->id, highlight)
|
||||
: FullMsgId(_migratedPeer->id, -highlight)),
|
||||
.date = TimeId(0),
|
||||
};
|
||||
_inner->showAroundPosition(position, [=] {
|
||||
|
||||
@@ -110,7 +110,7 @@ void PinnedTracker::refreshViewer() {
|
||||
|
||||
void PinnedTracker::refreshCurrentFromSlice() {
|
||||
const auto proj1 = [](FullMsgId id) {
|
||||
return id.channel ? id.msg : (id.msg - ServerMaxMsgId);
|
||||
return peerIsChannel(id.peer) ? id.msg : (id.msg - ServerMaxMsgId);
|
||||
};
|
||||
const auto proj2 = [](FullMsgId id) {
|
||||
return id.msg;
|
||||
|
||||
@@ -90,11 +90,9 @@ rpl::producer<Ui::MessageBarContent> RootViewContent(
|
||||
MsgId rootId) {
|
||||
return MessageBarContentByItemId(
|
||||
&history->session(),
|
||||
FullMsgId{ history->channelId(), rootId }
|
||||
FullMsgId(history->peer->id, rootId)
|
||||
) | rpl::map([=](Ui::MessageBarContent &&content) {
|
||||
const auto item = history->owner().message(
|
||||
history->channelId(),
|
||||
rootId);
|
||||
const auto item = history->owner().message(history->peer, rootId);
|
||||
if (!item) {
|
||||
content.text = Ui::Text::Link(tr::lng_deleted_message(tr::now));
|
||||
}
|
||||
@@ -115,7 +113,7 @@ RepliesMemento::RepliesMemento(
|
||||
if (commentId) {
|
||||
_list.setAroundPosition({
|
||||
.fullId = FullMsgId(
|
||||
commentsItem->history()->channelId(),
|
||||
commentsItem->history()->peer->id,
|
||||
commentId),
|
||||
.date = TimeId(0),
|
||||
});
|
||||
@@ -361,8 +359,7 @@ void RepliesWidget::sendReadTillRequest() {
|
||||
|
||||
void RepliesWidget::setupRoot() {
|
||||
if (!_root) {
|
||||
const auto channel = _history->peer->asChannel();
|
||||
const auto done = crl::guard(this, [=](ChannelData*, MsgId) {
|
||||
const auto done = crl::guard(this, [=] {
|
||||
_root = lookupRoot();
|
||||
if (_root) {
|
||||
_areComments = computeAreComments();
|
||||
@@ -374,7 +371,10 @@ void RepliesWidget::setupRoot() {
|
||||
}
|
||||
updatePinnedVisibility();
|
||||
});
|
||||
_history->session().api().requestMessageData(channel, _rootId, done);
|
||||
_history->session().api().requestMessageData(
|
||||
_history->peer,
|
||||
_rootId,
|
||||
done);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,7 +413,7 @@ void RepliesWidget::setupRootView() {
|
||||
}
|
||||
|
||||
HistoryItem *RepliesWidget::lookupRoot() const {
|
||||
return _history->owner().message(_history->channelId(), _rootId);
|
||||
return _history->owner().message(_history->peer, _rootId);
|
||||
}
|
||||
|
||||
bool RepliesWidget::computeAreComments() const {
|
||||
@@ -831,9 +831,7 @@ void RepliesWidget::restoreReplyReturns(const std::vector<MsgId> &list) {
|
||||
void RepliesWidget::computeCurrentReplyReturn() {
|
||||
_replyReturn = _replyReturns.empty()
|
||||
? nullptr
|
||||
: _history->owner().message(
|
||||
_history->channelId(),
|
||||
_replyReturns.back());
|
||||
: _history->owner().message(_history->peer, _replyReturns.back());
|
||||
}
|
||||
|
||||
void RepliesWidget::calculateNextReplyReturn() {
|
||||
@@ -1408,7 +1406,7 @@ not_null<History*> RepliesWidget::history() const {
|
||||
Dialogs::RowDescriptor RepliesWidget::activeChat() const {
|
||||
return {
|
||||
_history,
|
||||
FullMsgId(_history->channelId(), ShowAtUnreadMsgId)
|
||||
FullMsgId(_history->peer->id, ShowAtUnreadMsgId)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1478,10 +1476,7 @@ bool RepliesWidget::showMessage(
|
||||
if (peerId != _history->peer->id) {
|
||||
return false;
|
||||
}
|
||||
const auto id = FullMsgId{
|
||||
_history->channelId(),
|
||||
messageId
|
||||
};
|
||||
const auto id = FullMsgId(_history->peer->id, messageId);
|
||||
const auto message = _history->owner().message(id);
|
||||
if (!message || message->replyToTop() != _rootId) {
|
||||
return false;
|
||||
@@ -1558,7 +1553,7 @@ void RepliesWidget::restoreState(not_null<RepliesMemento*> memento) {
|
||||
_inner->restoreState(memento->list());
|
||||
if (const auto highlight = memento->getHighlightId()) {
|
||||
const auto position = Data::MessagePosition{
|
||||
.fullId = FullMsgId(_history->channelId(), highlight),
|
||||
.fullId = FullMsgId(_history->peer->id, highlight),
|
||||
.date = TimeId(0),
|
||||
};
|
||||
_inner->showAroundPosition(position, [=] {
|
||||
|
||||
@@ -905,7 +905,7 @@ not_null<History*> ScheduledWidget::history() const {
|
||||
Dialogs::RowDescriptor ScheduledWidget::activeChat() const {
|
||||
return {
|
||||
_history,
|
||||
FullMsgId(_history->channelId(), ShowAtUnreadMsgId)
|
||||
FullMsgId(_history->peer->id, ShowAtUnreadMsgId)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ QString TimestampLinkBase(
|
||||
FullMsgId context) {
|
||||
return QString(
|
||||
"media_timestamp?base=doc%1_%2_%3&t="
|
||||
).arg(document->id).arg(context.channel.bare).arg(context.msg.bare);
|
||||
).arg(document->id).arg(context.peer.value).arg(context.msg.bare);
|
||||
}
|
||||
|
||||
TimeId DurationForTimestampLinks(not_null<WebPageData*> webpage) {
|
||||
|
||||
@@ -71,8 +71,8 @@ rpl::producer<SparseIdsMergedSlice> AbstractController::mediaSource(
|
||||
Expects(peer() != nullptr);
|
||||
|
||||
const auto isScheduled = [&] {
|
||||
const auto channelId = peerToChannel(peer()->id);
|
||||
if (const auto item = session().data().message(channelId, aroundId)) {
|
||||
const auto peerId = peer()->id;
|
||||
if (const auto item = session().data().message(peerId, aroundId)) {
|
||||
return item->isScheduled();
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -61,7 +61,7 @@ constexpr auto kPreloadedScreensCountFull
|
||||
constexpr auto kMediaCountForSearch = 10;
|
||||
|
||||
UniversalMsgId GetUniversalId(FullMsgId itemId) {
|
||||
return (itemId.channel != 0)
|
||||
return peerIsChannel(itemId.peer)
|
||||
? UniversalMsgId(itemId.msg)
|
||||
: UniversalMsgId(itemId.msg - ServerMaxMsgId);
|
||||
}
|
||||
@@ -855,8 +855,10 @@ FullMsgId ListWidget::computeFullId(
|
||||
Expects(universalId != 0);
|
||||
|
||||
return (universalId > 0)
|
||||
? FullMsgId(peerToChannel(_peer->id), universalId)
|
||||
: FullMsgId(NoChannel, ServerMaxMsgId + universalId);
|
||||
? FullMsgId(_peer->id, universalId)
|
||||
: FullMsgId(
|
||||
(_migrated ? _migrated : _peer.get())->id,
|
||||
ServerMaxMsgId + universalId);
|
||||
}
|
||||
|
||||
auto ListWidget::collectSelectedItems() const -> SelectedItems {
|
||||
@@ -964,9 +966,8 @@ bool ListWidget::isMyItem(not_null<const HistoryItem*> item) const {
|
||||
}
|
||||
|
||||
bool ListWidget::isPossiblyMyId(FullMsgId fullId) const {
|
||||
return fullId.channel
|
||||
? (_peer->isChannel() && peerToChannel(_peer->id) == fullId.channel)
|
||||
: (!_peer->isChannel() || _migrated);
|
||||
return (fullId.peer == _peer->id)
|
||||
|| (_migrated && fullId.peer == _migrated->id);
|
||||
}
|
||||
|
||||
bool ListWidget::isItemLayout(
|
||||
|
||||
@@ -1429,7 +1429,7 @@ void MainWidget::ui_showPeerHistory(
|
||||
if (const auto history = _history->history()) {
|
||||
_dialogs->scrollToEntry(Dialogs::RowDescriptor(
|
||||
history,
|
||||
FullMsgId(history->channelId(), showAtMsgId)));
|
||||
FullMsgId(history->peer->id, showAtMsgId)));
|
||||
}
|
||||
}
|
||||
_dialogs->update();
|
||||
|
||||
@@ -386,7 +386,7 @@ auto Instance::playlistKey(not_null<const Data*> data) const
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto universalId = (contextId.channel == history->channelId())
|
||||
const auto universalId = (contextId.peer == history->peer->id)
|
||||
? contextId.msg
|
||||
: (contextId.msg - ServerMaxMsgId);
|
||||
return SliceKey(
|
||||
@@ -506,9 +506,9 @@ bool Instance::moveInPlaylist(
|
||||
}
|
||||
const auto universal = computeCurrentUniversalId(data);
|
||||
const auto byUniversal = [&](ShuffleData::UniversalMsgId id) {
|
||||
return (id < 0)
|
||||
? jumpById({ ChannelId(), id + ServerMaxMsgId })
|
||||
: jumpById({ raw->history->channelId(), id });
|
||||
return (id < 0 && raw->migrated)
|
||||
? jumpById({ raw->migrated->peer->id, id + ServerMaxMsgId })
|
||||
: jumpById({ raw->history->peer->id, id });
|
||||
};
|
||||
if (universal && raw->indexInPlayedIds == raw->playedIds.size()) {
|
||||
raw->playedIds.push_back(universal);
|
||||
@@ -906,12 +906,12 @@ void Instance::validateShuffleData(not_null<Data*> data) {
|
||||
raw->nextSliceLifetime.destroy();
|
||||
|
||||
const auto size = update.size();
|
||||
const auto channel = raw->history->channelId();
|
||||
const auto peer = raw->history->peer->id;
|
||||
raw->playlist.reserve(raw->playlist.size() + size);
|
||||
raw->nonPlayedIds.reserve(raw->nonPlayedIds.size() + size);
|
||||
for (auto i = size; i != 0;) {
|
||||
const auto fullId = update[--i];
|
||||
const auto universal = (fullId.channel == channel)
|
||||
const auto universal = (fullId.peer == peer)
|
||||
? fullId.msg
|
||||
: (fullId.msg - ServerMaxMsgId);
|
||||
if (raw->playlist.empty() || raw->playlist.back() > universal) {
|
||||
|
||||
@@ -4742,7 +4742,7 @@ void OverlayWidget::updateHeader() {
|
||||
_headerText = tr::lng_mediaview_single_photo(tr::now);
|
||||
} else if (_user) {
|
||||
_headerText = tr::lng_mediaview_profile_photo(tr::now);
|
||||
} else if ((_history && _history->channelId() && !_history->isMegagroup())
|
||||
} else if ((_history && _history->peer->isBroadcast())
|
||||
|| (_peer && _peer->isChannel() && !_peer->isMegagroup())) {
|
||||
_headerText = tr::lng_mediaview_channel_photo(tr::now);
|
||||
} else if (_peer) {
|
||||
|
||||
@@ -11,42 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
namespace MTP::details {
|
||||
namespace {
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
|
||||
|
||||
// This is a key setter for compatibility with OpenSSL 1.0
|
||||
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) {
|
||||
if ((r->n == nullptr && n == nullptr) || (r->e == nullptr && e == nullptr)) {
|
||||
return 0;
|
||||
}
|
||||
if (n != nullptr) {
|
||||
BN_free(r->n);
|
||||
r->n = n;
|
||||
}
|
||||
if (e != nullptr) {
|
||||
BN_free(r->e);
|
||||
r->e = e;
|
||||
}
|
||||
if (d != nullptr) {
|
||||
BN_free(r->d);
|
||||
r->d = d;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// This is a key getter for compatibility with OpenSSL 1.0
|
||||
void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) {
|
||||
if (n != nullptr) {
|
||||
*n = r->n;
|
||||
}
|
||||
if (e != nullptr) {
|
||||
*e = r->e;
|
||||
}
|
||||
if (d != nullptr) {
|
||||
*d = r->d;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
enum class Format {
|
||||
RSAPublicKey,
|
||||
@@ -168,7 +132,7 @@ bytes::vector RSAPublicKey::Private::encrypt(bytes::const_span data) const {
|
||||
auto result = bytes::vector(kEncryptSize, gsl::byte{});
|
||||
auto res = RSA_public_encrypt(kEncryptSize, reinterpret_cast<const unsigned char*>(data.data()), reinterpret_cast<unsigned char*>(result.data()), _rsa, RSA_NO_PADDING);
|
||||
if (res < 0 || res > kEncryptSize) {
|
||||
ERR_load_crypto_strings();
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nullptr);
|
||||
LOG(("RSA Error: RSA_public_encrypt failed, key fp: %1, result: %2, error: %3").arg(fingerprint()).arg(res).arg(ERR_error_string(ERR_get_error(), 0)));
|
||||
return {};
|
||||
} else if (auto zeroBytes = kEncryptSize - res) {
|
||||
@@ -186,7 +150,7 @@ bytes::vector RSAPublicKey::Private::decrypt(bytes::const_span data) const {
|
||||
auto result = bytes::vector(kDecryptSize, gsl::byte{});
|
||||
auto res = RSA_public_decrypt(kDecryptSize, reinterpret_cast<const unsigned char*>(data.data()), reinterpret_cast<unsigned char*>(result.data()), _rsa, RSA_NO_PADDING);
|
||||
if (res < 0 || res > kDecryptSize) {
|
||||
ERR_load_crypto_strings();
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nullptr);
|
||||
LOG(("RSA Error: RSA_public_encrypt failed, key fp: %1, result: %2, error: %3").arg(fingerprint()).arg(res).arg(ERR_error_string(ERR_get_error(), 0)));
|
||||
return {};
|
||||
} else if (auto zeroBytes = kDecryptSize - res) {
|
||||
@@ -209,7 +173,7 @@ bytes::vector RSAPublicKey::Private::encryptOAEPpadding(bytes::const_span data)
|
||||
_rsa,
|
||||
RSA_PKCS1_OAEP_PADDING);
|
||||
if (encryptedSize != resultSize) {
|
||||
ERR_load_crypto_strings();
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nullptr);
|
||||
LOG(("RSA Error: RSA_public_encrypt failed, "
|
||||
"key fp: %1, result: %2, error: %3"
|
||||
).arg(fingerprint()
|
||||
|
||||
@@ -1592,7 +1592,7 @@ void FormController::uploadEncryptedFile(
|
||||
prepared->filemd5 = file.uploadData->md5checksum;
|
||||
|
||||
file.uploadData->fullId = FullMsgId(
|
||||
0,
|
||||
session().userPeerId(),
|
||||
session().data().nextLocalMessageId());
|
||||
file.uploadData->status.set(LoadStatus::Status::InProgress, 0);
|
||||
session().uploader().upload(
|
||||
|
||||
@@ -69,7 +69,7 @@ void CheckoutProcess::Start(
|
||||
return;
|
||||
}
|
||||
const auto id = (invoice && invoice->receiptMsgId)
|
||||
? FullMsgId(item->history()->channelId(), invoice->receiptMsgId)
|
||||
? FullMsgId(item->history()->peer->id, invoice->receiptMsgId)
|
||||
: item->fullId();
|
||||
if (invoice) {
|
||||
mode = invoice->receiptMsgId ? Mode::Receipt : Mode::Payment;
|
||||
|
||||
@@ -147,7 +147,7 @@ Form::Form(not_null<PeerData*> peer, MsgId itemId, bool receipt)
|
||||
Form::~Form() = default;
|
||||
|
||||
void Form::fillInvoiceFromMessage() {
|
||||
const auto id = FullMsgId(peerToChannel(_peer->id), _msgId);
|
||||
const auto id = FullMsgId(_peer->id, _msgId);
|
||||
if (const auto item = _session->data().message(id)) {
|
||||
const auto media = [&] {
|
||||
if (const auto payment = item->Get<HistoryServicePayment>()) {
|
||||
@@ -194,9 +194,7 @@ void Form::loadThumbnail(not_null<PhotoData*> photo) {
|
||||
_invoice.cover.thumbnail = prepareEmptyThumbnail();
|
||||
}
|
||||
_thumbnailLoadProcess->view = std::move(view);
|
||||
photo->load(
|
||||
Data::PhotoSize::Thumbnail,
|
||||
FullMsgId(peerToChannel(_peer->id), _msgId));
|
||||
photo->load(Data::PhotoSize::Thumbnail, FullMsgId(_peer->id, _msgId));
|
||||
_session->downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto &view = _thumbnailLoadProcess->view;
|
||||
|
||||
@@ -94,7 +94,7 @@ void XCBSkipTaskbar(QWindow *window, bool skip) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto root = base::Platform::XCB::GetRootWindowFromQt();
|
||||
const auto root = base::Platform::XCB::GetRootWindow(connection);
|
||||
if (!root.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QScreen>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
|
||||
#include <Shobjidl.h>
|
||||
#include <shellapi.h>
|
||||
@@ -429,11 +428,7 @@ void MainWindow::updateIconCounters() {
|
||||
}
|
||||
|
||||
void MainWindow::initHook() {
|
||||
if (const auto native = QGuiApplication::platformNativeInterface()) {
|
||||
ps_hWnd = static_cast<HWND>(native->nativeResourceForWindow(
|
||||
QByteArrayLiteral("handle"),
|
||||
windowHandle()));
|
||||
}
|
||||
ps_hWnd = reinterpret_cast<HWND>(winId());
|
||||
if (!ps_hWnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <QtWidgets/QDesktopWidget>
|
||||
#include <QtGui/QDesktopServices>
|
||||
#include <QtGui/QWindow>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
|
||||
#include <Shobjidl.h>
|
||||
#include <ShObjIdl_core.h>
|
||||
|
||||
@@ -964,7 +964,9 @@ int MainWindow::tryToExtendWidthBy(int addToWidth) {
|
||||
void MainWindow::launchDrag(
|
||||
std::unique_ptr<QMimeData> data,
|
||||
Fn<void()> &&callback) {
|
||||
auto drag = std::make_unique<QDrag>(this);
|
||||
// Qt destroys this QDrag automatically after the drag is finished
|
||||
// We must not delete this at the end of this function, as this breaks DnD on Linux
|
||||
auto drag = new QDrag(this);
|
||||
drag->setMimeData(data.release());
|
||||
drag->exec(Qt::CopyAction);
|
||||
|
||||
|
||||
@@ -296,9 +296,7 @@ void System::checkDelayed() {
|
||||
}
|
||||
}
|
||||
if (loaded) {
|
||||
const auto fullId = FullMsgId(
|
||||
history->channelId(),
|
||||
i->second.msg);
|
||||
const auto fullId = FullMsgId(history->peer->id, i->second.msg);
|
||||
if (const auto item = peer->owner().message(fullId)) {
|
||||
if (!item->notificationReady()) {
|
||||
loaded = false;
|
||||
@@ -677,9 +675,7 @@ void Manager::openNotificationMessage(
|
||||
if (history->peer->isUser() || history->peer->isChannel()) {
|
||||
return false;
|
||||
}
|
||||
const auto item = history->owner().message(
|
||||
history->channelId(),
|
||||
messageId);
|
||||
const auto item = history->owner().message(history->peer, messageId);
|
||||
if (!item || !item->isRegular() || !item->mentionsMe()) {
|
||||
return false;
|
||||
}
|
||||
@@ -714,9 +710,7 @@ void Manager::notificationReplied(
|
||||
message.action.clearDraft = false;
|
||||
history->session().api().sendMessage(std::move(message));
|
||||
|
||||
const auto item = history->owner().message(
|
||||
history->channelId(),
|
||||
id.msgId);
|
||||
const auto item = history->owner().message(history->peer, id.msgId);
|
||||
if (item && item->isUnreadMention() && !item->isUnreadMedia()) {
|
||||
history->session().api().markMediaRead(item);
|
||||
}
|
||||
|
||||
@@ -602,7 +602,9 @@ void ChatBackground::checkUploadWallPaper() {
|
||||
|
||||
const auto ready = PrepareWallPaper(_session->mainDcId(), _original);
|
||||
const auto documentId = ready.id;
|
||||
_wallPaperUploadId = FullMsgId(0, _session->data().nextLocalMessageId());
|
||||
_wallPaperUploadId = FullMsgId(
|
||||
_session->userPeerId(),
|
||||
_session->data().nextLocalMessageId());
|
||||
_session->uploader().uploadMedia(_wallPaperUploadId, ready);
|
||||
if (_wallPaperUploadLifetime) {
|
||||
return;
|
||||
|
||||
@@ -479,7 +479,7 @@ Fn<void()> SavePreparedTheme(
|
||||
const auto api = &session->api();
|
||||
const auto state = std::make_shared<State>();
|
||||
state->id = FullMsgId(
|
||||
0,
|
||||
session->userPeerId(),
|
||||
session->data().nextLocalMessageId());
|
||||
|
||||
const auto creating = !fields.id
|
||||
|
||||
@@ -1153,8 +1153,8 @@ void HidePinnedBar(
|
||||
const auto migrated = peer->migrateFrom();
|
||||
const auto top = Data::ResolveTopPinnedId(peer, migrated);
|
||||
const auto universal = !top
|
||||
? int32(0)
|
||||
: (migrated && !top.channel)
|
||||
? MsgId(0)
|
||||
: (migrated && !peerIsChannel(top.peer))
|
||||
? (top.msg - ServerMaxMsgId)
|
||||
: top.msg;
|
||||
if (universal) {
|
||||
|
||||
@@ -376,8 +376,8 @@ void SessionNavigation::showRepliesForMessage(
|
||||
}
|
||||
_session->api().request(base::take(_showingRepliesRequestId)).cancel();
|
||||
|
||||
const auto channelId = history->channelId();
|
||||
//const auto item = _session->data().message(channelId, rootId);
|
||||
const auto postPeer = history->peer;
|
||||
//const auto item = _session->data().message(postPeer, rootId);
|
||||
//if (!commentId && (!item || !item->repliesAreComments())) {
|
||||
// showSection(std::make_shared<HistoryView::RepliesMemento>(history, rootId));
|
||||
// return;
|
||||
@@ -411,9 +411,7 @@ void SessionNavigation::showRepliesForMessage(
|
||||
if (!peer || !id) {
|
||||
return;
|
||||
}
|
||||
auto item = _session->data().message(
|
||||
peerToChannel(peer),
|
||||
id);
|
||||
auto item = _session->data().message(peer, id);
|
||||
if (const auto group = _session->data().groups().find(item)) {
|
||||
item = group->items.front();
|
||||
}
|
||||
@@ -426,8 +424,8 @@ void SessionNavigation::showRepliesForMessage(
|
||||
data.vunread_count().v);
|
||||
item->setRepliesOutboxReadTill(
|
||||
data.vread_outbox_max_id().value_or_empty());
|
||||
const auto post = _session->data().message(channelId, rootId);
|
||||
if (post && item->history()->channelId() != channelId) {
|
||||
const auto post = _session->data().message(postPeer, rootId);
|
||||
if (post && item->history()->peer != postPeer) {
|
||||
post->setCommentsItemId(item->fullId());
|
||||
if (const auto maxId = data.vmax_id()) {
|
||||
post->setRepliesMaxId(maxId->v);
|
||||
|
||||
1
Telegram/ThirdParty/dispatch
vendored
Submodule
1
Telegram/ThirdParty/kwayland
vendored
Submodule
2
Telegram/ThirdParty/tgcalls
vendored
@@ -9,9 +9,9 @@ ENV QT5_VER 5_15_2
|
||||
ENV QT5_TAG v5.15.2
|
||||
ENV QT5_PREFIX /usr/local/desktop-app/Qt-5.15.2
|
||||
ENV Qt5_DIR ${QT5_PREFIX}
|
||||
ENV QT6_VER 6_2_0
|
||||
ENV QT6_TAG v6.2.0
|
||||
ENV QT6_PREFIX /usr/local/desktop-app/Qt-6.2.0
|
||||
ENV QT6_VER 6_2_2
|
||||
ENV QT6_TAG v6.2.2
|
||||
ENV QT6_PREFIX /usr/local/desktop-app/Qt-6.2.2
|
||||
ENV Qt6_DIR ${QT6_PREFIX}
|
||||
ENV OPENSSL_VER 1_1_1
|
||||
ENV OPENSSL_PREFIX /usr/local/desktop-app/openssl-1.1.1
|
||||
@@ -19,12 +19,14 @@ ENV OPENSSL_ROOT_DIR ${OPENSSL_PREFIX}
|
||||
ENV CMAKE_VER 3.21.3
|
||||
ENV CMAKE_FILE cmake-$CMAKE_VER-Linux-x86_64.sh
|
||||
ENV PATH ${PATH}:${QT5_PREFIX}/bin:${QT6_PREFIX}/bin
|
||||
ENV HFLAGS_DEBUG "-fstack-protector-all -fstack-clash-protection -fPIC"
|
||||
ENV HFLAGS "$HFLAGS_DEBUG -D_FORTIFY_SOURCE=2"
|
||||
|
||||
RUN yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm && yum clean all
|
||||
RUN yum -y install https://packages.endpoint.com/rhel/7/os/x86_64/endpoint-repo-1.7-1.x86_64.rpm && yum clean all
|
||||
RUN yum -y install centos-release-scl && yum clean all
|
||||
|
||||
RUN yum -y install git meson ninja-build autoconf automake libtool \
|
||||
RUN yum -y install git meson ninja-build autoconf automake libtool patch \
|
||||
fontconfig-devel freetype-devel libX11-devel at-spi2-core-devel alsa-lib-devel \
|
||||
pulseaudio-libs-devel mesa-libGL-devel mesa-libEGL-devel gtk3-devel \
|
||||
perl-XML-Parser pkgconfig bison yasm file which xorg-x11-util-macros \
|
||||
@@ -32,11 +34,12 @@ RUN yum -y install git meson ninja-build autoconf automake libtool \
|
||||
devtoolset-10-binutils llvm-toolset-7.0 llvm-toolset-7.0-clang-devel \
|
||||
llvm-toolset-7.0-llvm-devel && yum clean all
|
||||
|
||||
# Fix a bug with argument naming in CentOS 7 glibc
|
||||
RUN sed -i 's/char \*__block/char */' /usr/include/unistd.h
|
||||
|
||||
SHELL [ "bash", "-c", ". /opt/rh/devtoolset-10/enable; exec bash -c \"$@\"", "-s"]
|
||||
|
||||
ENV LibrariesPath /usr/src/Libraries
|
||||
ENV HFLAGS_DEBUG "-fstack-protector-all -fstack-clash-protection -fPIC"
|
||||
ENV HFLAGS "$HFLAGS_DEBUG -D_FORTIFY_SOURCE=2"
|
||||
WORKDIR $LibrariesPath
|
||||
|
||||
RUN mkdir /opt/cmake
|
||||
@@ -46,7 +49,7 @@ RUN ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
|
||||
RUN rm $CMAKE_FILE
|
||||
|
||||
FROM builder AS patches
|
||||
RUN git clone $GIT/desktop-app/patches.git && cd patches && git checkout b6c29e99da
|
||||
RUN git clone $GIT/desktop-app/patches.git && cd patches && git checkout 5368789dc7
|
||||
|
||||
FROM builder AS extra-cmake-modules
|
||||
|
||||
@@ -766,38 +769,6 @@ RUN [ -z "${QT6}" ] || DESTDIR="$LibrariesPath/qt-cache" cmake --install .
|
||||
WORKDIR ..
|
||||
RUN [ -z "${QT6}" ] || rm -rf qt_${QT6_VER}
|
||||
|
||||
FROM patches AS kwayland
|
||||
ARG QT6
|
||||
|
||||
COPY --from=extra-cmake-modules ${LibrariesPath}/extra-cmake-modules-cache /
|
||||
COPY --from=libffi ${LibrariesPath}/libffi-cache /
|
||||
COPY --from=zlib ${LibrariesPath}/zlib-cache /
|
||||
COPY --from=libproxy ${LibrariesPath}/libproxy-cache /
|
||||
COPY --from=mozjpeg ${LibrariesPath}/mozjpeg-cache /
|
||||
COPY --from=xcb ${LibrariesPath}/xcb-cache /
|
||||
COPY --from=xcb-wm ${LibrariesPath}/xcb-wm-cache /
|
||||
COPY --from=xcb-util ${LibrariesPath}/xcb-util-cache /
|
||||
COPY --from=xcb-image ${LibrariesPath}/xcb-image-cache /
|
||||
COPY --from=xcb-keysyms ${LibrariesPath}/xcb-keysyms-cache /
|
||||
COPY --from=xcb-render-util ${LibrariesPath}/xcb-render-util-cache /
|
||||
COPY --from=wayland ${LibrariesPath}/wayland-cache /
|
||||
COPY --from=wayland-protocols ${LibrariesPath}/wayland-protocols-cache /
|
||||
COPY --from=plasma-wayland-protocols ${LibrariesPath}/plasma-wayland-protocols-cache /
|
||||
COPY --from=openssl ${LibrariesPath}/openssl-cache /
|
||||
COPY --from=xkbcommon ${LibrariesPath}/xkbcommon-cache /
|
||||
COPY --from=qt ${LibrariesPath}/qt-cache /
|
||||
|
||||
RUN git clone -b v5.87.0 --depth=1 $GIT/KDE/kwayland.git
|
||||
|
||||
WORKDIR kwayland
|
||||
RUN [ -z "${QT6}" ] || git apply ../patches/kwayland-qt6.patch
|
||||
RUN cmake -GNinja -B build . -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTING=OFF
|
||||
RUN cmake --build build --target KF5WaylandClient --parallel
|
||||
RUN DESTDIR="$LibrariesPath/kwayland-cache" cmake --install build/src/client
|
||||
|
||||
WORKDIR ..
|
||||
RUN rm -rf kwayland
|
||||
|
||||
FROM patches AS breakpad
|
||||
RUN git clone https://chromium.googlesource.com/breakpad/breakpad.git
|
||||
|
||||
@@ -880,6 +851,8 @@ COPY --from=libXrender ${LibrariesPath}/libXrender-cache /
|
||||
COPY --from=libXdamage ${LibrariesPath}/libXdamage-cache /
|
||||
COPY --from=libXcomposite ${LibrariesPath}/libXcomposite-cache /
|
||||
COPY --from=wayland ${LibrariesPath}/wayland-cache /
|
||||
COPY --from=wayland-protocols ${LibrariesPath}/wayland-protocols-cache /
|
||||
COPY --from=plasma-wayland-protocols ${LibrariesPath}/plasma-wayland-protocols-cache /
|
||||
COPY --from=libpciaccess ${LibrariesPath}/libpciaccess-cache /
|
||||
COPY --from=drm ${LibrariesPath}/drm-cache /
|
||||
COPY --from=libva ${LibrariesPath}/libva-cache /
|
||||
@@ -892,7 +865,6 @@ COPY --from=xkbcommon ${LibrariesPath}/xkbcommon-cache /
|
||||
COPY --from=libsigcplusplus ${LibrariesPath}/libsigcplusplus-cache /
|
||||
COPY --from=glibmm ${LibrariesPath}/glibmm-cache /
|
||||
COPY --from=qt ${LibrariesPath}/qt-cache /
|
||||
COPY --from=kwayland ${LibrariesPath}/kwayland-cache /
|
||||
COPY --from=breakpad ${LibrariesPath}/breakpad breakpad
|
||||
COPY --from=breakpad ${LibrariesPath}/breakpad-cache /
|
||||
COPY --from=webrtc ${LibrariesPath}/tg_owt tg_owt
|
||||
|
||||